From 42fde9c99d5c8c8e51f4175d1069179efdf5154c Mon Sep 17 00:00:00 2001 From: Michael Jennings Date: Fri, 11 Feb 2000 00:25:07 +0000 Subject: [PATCH] Thu Feb 10 15:10:01 PST 2000 Michael Jennings This is the first public availability of the work thus far on Eterm 0.9.1. There's quite a bit of new stuff here. * Added scrollbar thumb support. * Completely redid the terminfo/termcap stuff. The terminfo file is now compiled (by tic) and installed by default (unless you specify --without-terminfo). The config files still say xterm, though, because some programs (like SLang and GNU mc) use the silly algorithm of "Is $TERM set to xterm?" to detect mouse reporting support in a terminal. =P But if you don't ever use xterm, you can use Eterm's termcap and just name it "xterm" instead. Thanks to Marius Gedminas for his patch that started this whole revamp. * Added the kEsetroot script for KDE users from Dax Games . * You can now configure the Home and End emulation via --with-home= and --with-end= options to configure. The --with-terminfo option is also new, and --enable-xim is now the default. * Added a new image state, disabled, for when Eterm loses focus. This is supported by all widgets (well, all those that could possibly be on screen when Eterm lost focus), even the background image. So you could actually have all your images darken on focus out and restore to normal on focus in. * Widget colors formerly dealt with as colors (menu text color, scrollbar color, etc.) are now handled by the imageclasses. Each image state can have a foreground and background color defined. The current exception is the background image; I hope to add that later. The foreground is the text color and the background is the object color (for solid color mode). So menu text color is set by the menu imageclass. And again, for unfocused colors, use the disabled state of the imageclass. * Proportionally-spaced fonts are now handled much better. They are still forced into evenly-spaced columns (it's a terminal for crying out loud!) but at least you don't end up with Eterm's wider than your screen. :-) * Home on refresh is gone, as is home on echo. It's now much simpler. There are two options: home on output, and home on input, the former being a combination of echo and refresh. Also, keypresses that don't necessarily have corresonding output can trigger a home on input, like Ctrl-End or whatever...ones that don't have special meaning. Credit to Darren Stuart Embry for pointing out this issue and the one with "m-" in font names. * I finally got around to re-merging the new parser stuff from my work on the Not Game. Closed up some old potential behavior quirks with theme parsing. * Added a new escape sequence to fork-and-exec a program. Also added a scrollback search capability to highlight all occurances of a string in your scrollback buffer. Use the new "Etsearch" utility to access it. "Etsearch string" to search for a string, then "Etsearch" by itself to reset the highlighting. * And of course, the biggie. Eterm now supports a completely- customizeable buttonbar. Not a menubar, a buttonbar. It can have an arbitrary number of buttons, and each button can perform an action, just like a menuitem. So a button could bring up a menu (like a menubar) or launch a program (like a launchbar) or perform an operation (like a toolbar). Each button can have an icon, text, or both. And you can have buttons left- or right-justified in the buttonbar. You will eventually be able to have an arbitrary number of buttonbars, but I'm still working on that. As with any change this big, things could very easily be broken. So beware. :-) I have tested this myself, and everything seems to work, but I can't test every possibility. Let me know if you find anything that's broken, and enjoy! SVN revision: 2048 --- ChangeLog | 77 +++ acconfig.h | 2 + configure.in | 112 ++- doc/Eterm.tcap | 172 +++-- doc/Eterm.ti | 240 +++---- doc/Makefile.am | 5 +- libmej/mem.h | 8 +- libmej/strings.c | 2 +- pix/Makefile.am | 3 +- pix/exit.png | Bin 0 -> 5844 bytes pix/help.png | Bin 0 -> 3188 bytes pix/thumb_1.png | Bin 0 -> 209 bytes pix/thumb_2.png | Bin 0 -> 209 bytes src/Makefile.am | 15 +- src/buttons.c | 781 +++++++++++++++++++++ src/buttons.h | 129 ++++ src/command.c | 65 +- src/command.h | 7 +- src/debug.h | 45 +- src/e.c | 16 +- src/events.c | 88 ++- src/events.h | 2 + src/feature.h | 2 +- src/font.c | 22 +- src/menus.c | 191 +++--- src/menus.h | 8 +- src/misc.c | 8 +- src/options.c | 1295 +++++++++++++++++++++-------------- src/options.h | 245 ++++--- src/pixmap.c | 849 +++++++++++++++-------- src/pixmap.h | 36 +- src/screen.c | 166 ++++- src/screen.h | 7 +- src/scrollbar.c | 98 ++- src/scrollbar.h | 2 +- src/startup.c | 32 +- src/startup.h | 116 ++-- src/system.c | 10 +- src/term.c | 225 +++--- src/term.h | 8 +- src/windows.c | 359 +++++----- src/windows.h | 4 + themes/Eterm/menus.cfg | 61 +- themes/Eterm/theme.cfg.in | 95 ++- themes/auto/menus.cfg | 6 +- themes/auto/theme.cfg.in | 95 ++- themes/cEterm/menus.cfg | 61 +- themes/cEterm/theme.cfg.in | 95 ++- themes/chooser/menus.cfg | 19 +- themes/chooser/theme.cfg.in | 96 ++- themes/emacs/menus.cfg | 27 +- themes/emacs/theme.cfg.in | 97 ++- themes/irc/menus.cfg | 61 +- themes/irc/theme.cfg.in | 97 ++- themes/mutt/menus.cfg | 15 +- themes/mutt/theme.cfg.in | 141 +++- themes/trans/menus.cfg | 61 +- themes/trans/theme.cfg.in | 95 ++- utils/.cvsignore | 1 + utils/Etsearch | 30 + utils/Makefile.am | 5 +- utils/kEsetroot.in | 107 +++ 62 files changed, 4733 insertions(+), 1984 deletions(-) create mode 100644 pix/exit.png create mode 100644 pix/help.png create mode 100644 pix/thumb_1.png create mode 100644 pix/thumb_2.png create mode 100644 src/buttons.c create mode 100644 src/buttons.h create mode 100755 utils/Etsearch create mode 100755 utils/kEsetroot.in diff --git a/ChangeLog b/ChangeLog index c4979a0..f9cb98c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3084,3 +3084,80 @@ Fri Jan 21 18:40:13 PST 2000 Michael Jennings updated it. ------------------------------------------------------------------------------- +Thu Feb 10 15:10:01 PST 2000 Michael Jennings + + This is the first public availability of the work thus far on Eterm + 0.9.1. There's quite a bit of new stuff here. + + * Added scrollbar thumb support. + + * Completely redid the terminfo/termcap stuff. The terminfo file is + now compiled (by tic) and installed by default (unless you specify + --without-terminfo). The config files still say xterm, though, + because some programs (like SLang and GNU mc) use the silly algorithm + of "Is $TERM set to xterm?" to detect mouse reporting support in a + terminal. =P But if you don't ever use xterm, you can use Eterm's + termcap and just name it "xterm" instead. Thanks to Marius Gedminas + for his patch that started this whole revamp. + + * Added the kEsetroot script for KDE users from Dax Games + . + + * You can now configure the Home and End emulation via --with-home= + and --with-end= options to configure. The --with-terminfo option is + also new, and --enable-xim is now the default. + + * Added a new image state, disabled, for when Eterm loses focus. This + is supported by all widgets (well, all those that could possibly be + on screen when Eterm lost focus), even the background image. So you + could actually have all your images darken on focus out and restore + to normal on focus in. + + * Widget colors formerly dealt with as colors (menu text color, + scrollbar color, etc.) are now handled by the imageclasses. Each + image state can have a foreground and background color defined. The + current exception is the background image; I hope to add that later. + The foreground is the text color and the background is the object + color (for solid color mode). So menu text color is set by the menu + imageclass. And again, for unfocused colors, use the disabled state + of the imageclass. + + * Proportionally-spaced fonts are now handled much better. They are + still forced into evenly-spaced columns (it's a terminal for crying + out loud!) but at least you don't end up with Eterm's wider than your + screen. :-) + + * Home on refresh is gone, as is home on echo. It's now much simpler. + There are two options: home on output, and home on input, the former + being a combination of echo and refresh. Also, keypresses that don't + necessarily have corresonding output can trigger a home on input, + like Ctrl-End or whatever...ones that don't have special meaning. + Credit to Darren Stuart Embry for pointing out + this issue and the one with "m-" in font names. + + * I finally got around to re-merging the new parser stuff from my + work on the Not Game. Closed up some old potential behavior quirks + with theme parsing. + + * Added a new escape sequence to fork-and-exec a program. Also added + a scrollback search capability to highlight all occurances of a string + in your scrollback buffer. Use the new "Etsearch" utility to access + it. "Etsearch string" to search for a string, then "Etsearch" by + itself to reset the highlighting. + + * And of course, the biggie. Eterm now supports a completely- + customizeable buttonbar. Not a menubar, a buttonbar. It can have an + arbitrary number of buttons, and each button can perform an action, + just like a menuitem. So a button could bring up a menu (like a + menubar) or launch a program (like a launchbar) or perform an + operation (like a toolbar). Each button can have an icon, text, or + both. And you can have buttons left- or right-justified in the + buttonbar. You will eventually be able to have an arbitrary number + of buttonbars, but I'm still working on that. + + As with any change this big, things could very easily be broken. So + beware. :-) I have tested this myself, and everything seems to work, + but I can't test every possibility. Let me know if you find anything + that's broken, and enjoy! + +------------------------------------------------------------------------------- diff --git a/acconfig.h b/acconfig.h index e63c671..6200c18 100644 --- a/acconfig.h +++ b/acconfig.h @@ -326,6 +326,8 @@ #undef HAVE_UTEMPTER #undef PTY_GRP_NAME #undef ENABLE_PROFILE +#undef KS_HOME +#undef KS_END /* Leave that blank line there!! Autoheader needs it. diff --git a/configure.in b/configure.in index f1a0163..48a96bc 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ dnl# $Id$ AC_INIT(src/feature.h) -AM_INIT_AUTOMAKE(Eterm, 0.9) +AM_INIT_AUTOMAKE(Eterm, 0.9.1) dnl# Set some basic variables DATE="`date '+%d %B %Y'`" @@ -104,10 +104,15 @@ AC_CHECK_PROG(MKDIR, mkdir, mkdir, false) AC_CHECK_PROG(CTAGS, ctags, ctags, true) AC_CHECK_PROG(AR, ar, ar, false) AC_CHECK_PROG(MV, mv, mv, true) +AC_CHECK_PROG(TIC, tic, tic, true) AC_LN_S +AC_PATH_PROG(PERL, perl, /usr/bin/perl, $PATH:/usr/bin:/bin:/usr/local/bin:/usr/ccs/bin:/usr/contrib/bin) +AC_PATH_PROG(AWK, awk, /usr/bin/awk, $PATH:/usr/bin:/bin:/usr/local/bin:/usr/ccs/bin:/usr/contrib/bin) +export PERL AWK AC_CHECK_SIZEOF(int, 4) AC_CHECK_SIZEOF(long, 4) +AC_CHECK_SIZEOF(void *, 4) AC_CHECK_SIZEOF(long long, 8) dnl AC_C_BIGENDIAN @@ -355,6 +360,36 @@ AC_ARG_WITH(delete, fi, AC_MSG_RESULT(default) AC_DEFINE_UNQUOTED(KS_DELETE, "\177") ) +XTERM_HOME="\033\133H" +LINUX_HOME="\033\1331~" +AC_MSG_CHECKING(for home key configuration) +AC_ARG_WITH(home, +[ --with-home=SEQUENCE specify which sequence to use for the Home key ("xterm", "linux", or "vt102")], + if test "$withval" = "xterm"; then + AC_MSG_RESULT(emulate xterm) + AC_DEFINE_UNQUOTED(KS_HOME, "$XTERM_HOME") + elif test "$withval" = "linux"; then + AC_MSG_RESULT(emulate linux console/vt220) + AC_DEFINE_UNQUOTED(KS_HOME, "$LINUX_HOME") + else + AC_MSG_RESULT(default vt102) + fi, AC_MSG_RESULT(default) +) +XTERM_END="\033\133F" +LINUX_END="\033\1334~" +AC_MSG_CHECKING(for end key configuration) +AC_ARG_WITH(end, +[ --with-end=SEQUENCE specify which sequence to use for the End key ("xterm", "linux", or "vt102")], + if test "$withval" = "xterm"; then + AC_MSG_RESULT(emulate xterm) + AC_DEFINE_UNQUOTED(KS_END, "$XTERM_END") + elif test "$withval" = "linux"; then + AC_MSG_RESULT(emulate linux console/vt220) + AC_DEFINE_UNQUOTED(KS_END, "$LINUX_END") + else + AC_MSG_RESULT(default vt102) + fi, AC_MSG_RESULT(default) +) MULTICHAR_ENCODING="" AC_MSG_CHECKING(for multi-charset support) AC_ARG_ENABLE(multi-charset, @@ -441,6 +476,7 @@ AC_SUBST(FONT1) AC_SUBST(FONT2) AC_SUBST(FONT3) AC_SUBST(FONT4) +export FONT0 FONT1 FONT2 FONT3 FONT4 DEF_FONT_IDX AC_DEFINE_UNQUOTED(MULTICHAR_ENCODING, "$MULTICHAR_ENCODING") AC_DEFINE_UNQUOTED(MFONT0, "$MFONT0") @@ -454,18 +490,21 @@ AC_SUBST(MFONT1) AC_SUBST(MFONT2) AC_SUBST(MFONT3) AC_SUBST(MFONT4) +export MFONT0 MFONT1 MFONT2 MFONT3 MFONT4 MULTICHAR_ENCODING AC_MSG_CHECKING(for XIM support) AC_ARG_ENABLE(xim, -[ --enable-xim compile with XIM support], - if test "$enableval" = "yes"; then +[ --enable-xim compile with XIM support (default)], + if test "$enableval" = "no"; then + AC_MSG_RESULT(no) + XIM="FALSE" + else AC_MSG_RESULT(yes) AC_DEFINE(USE_XIM) XIM="TRUE" - else - AC_MSG_RESULT(no) - XIM="FALSE" - fi, AC_MSG_RESULT(no) + fi, AC_MSG_RESULT(yes) + AC_DEFINE(USE_XIM) + XIM="TRUE" ) AC_MSG_CHECKING(for Greek keyboard support) AC_ARG_ENABLE(greek, @@ -477,6 +516,13 @@ AC_ARG_ENABLE(greek, AC_MSG_RESULT(no) fi, AC_MSG_RESULT(no) ) +AC_ARG_WITH(terminfo, +[ --without-terminfo do not compile the Eterm terminfo file], + if test "$withval" = "yes"; then + : + else + TIC=true + fi) AC_ARG_WITH(theme-update, [ --with-theme-update existing themes will be forceably removed and new ones installed], if test "$withval" = "yes"; then @@ -595,9 +641,6 @@ if test "$prefix" = "NONE"; then prefix=$ac_default_prefix fi -PKGDATADIR=`eval echo "${datadir}/$PACKAGE"` -AC_SUBST(PKGDATADIR) - dnl Stack Tracing toys AC_ARG_ENABLE(stack-trace, [ --disable-stack-trace disable stack trace on abnormal termination], if test "$enableval" = "no"; then @@ -668,24 +711,37 @@ basedir=. AM_CONFIG_HEADER(config.h) -AC_OUTPUT(Makefile \ -bg/Makefile \ -doc/Makefile \ -utils/Makefile \ -libmej/Makefile \ -pix/Makefile \ -src/Makefile \ -themes/Makefile \ -Eterm.spec \ -themes/Eterm/theme.cfg -themes/auto/theme.cfg -themes/cEterm/theme.cfg -themes/chooser/theme.cfg -themes/emacs/theme.cfg -themes/irc/theme.cfg -themes/mutt/theme.cfg -themes/trans/theme.cfg -) +AC_OUTPUT(Makefile bg/Makefile doc/Makefile utils/Makefile libmej/Makefile + pix/Makefile src/Makefile themes/Makefile Eterm.spec) + +# Do replacements on theme files and such. All variables to be replaced +# by this routine MUST be exported before the awk script runs. +if test "X$PKGDATADIR" = "X" ; then + PKGDATADIR=`eval eval eval eval echo "$datadir/$PACKAGE"` +fi +export PKGDATADIR +# Mega evals to make sure all the relative variables get resolved. +BINDIR=`eval eval eval eval echo ${bindir}` +export BINDIR bindir prefix exec_prefix datadir PACKAGE + +changequote(%&, &%)dnl +%& +for i in utils/kEsetroot themes/Eterm/theme.cfg themes/auto/theme.cfg themes/cEterm/theme.cfg \ + themes/chooser/theme.cfg themes/emacs/theme.cfg themes/irc/theme.cfg themes/mutt/theme.cfg \ + themes/trans/theme.cfg ; do + echo creating $i + $AWK '{if (match($0,/@[A-Za-z0-9_]*@/)) { + i=ENVIRON[substr($0,RSTART+1,RLENGTH-2)]; + outp=$0; + gsub(/@[A-Za-z0-9_]*@/,i,outp); + print outp; + } else { + print $0; + } + }' $i.in > $i +done +&% +changequote([, ])dnl dnl If we're not building with Imlib support, don't build Esetroot if test -z "$GRLIBS"; then diff --git a/doc/Eterm.tcap b/doc/Eterm.tcap index df5fb60..35ac4ce 100644 --- a/doc/Eterm.tcap +++ b/doc/Eterm.tcap @@ -1,44 +1,130 @@ -# termcap for rxvt (and xterm) -- (modified from the Midnight Commander) -# -# From: Jakub Jelinek 1 Sep 1995 -# This is a checked termcap entry for the xterm terminal emulator. -# It is compatible with the enclosed terminfo entry. -# Install this by cutting off the old xterm entry from /etc/termcap -# and replacing that place it with this file. -# Heavily based on xterm from: -# Eric S. Raymond 30 Mar 1995 -# Note: If you use the line-drawing character set, the disable afterwards -# will leave you in US-ASCII. If you live somewhere that wants a pound sign -# at 2/3, change rmacs to "\E(A". Further note: cuf and cub don't seem -# to be reliable under my xterm, so they're commented out. -#------------------------------------------------------------------------- - -xterm|vs100|xterm terminal emulator (X11R6 Window System):\ - :am:bs:km:mi:ms:pt:xn:xo:co#80:li#24:it#8:\ - :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:\ - :IC=\E[%d@:LE=\E[%dD:UP=\E[%dA:\ - :ac=++\054\054..00II--``aaffgghhjjkkllmmnnooqqssttuuvvwwxx~~:\ - :ae=\E(B:al=\E[L:as=\E(0:bl=^G:cd=\E[J:ce=\E[K:\ - :cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\ - :ct=\E[3k:dc=\E[P:dl=\E[M:ei=\E[4l:ho=\E[H:\ - :ic=\E[@:im=\E[4h:\ +# termcap for Eterm. Needs to be downsized to fit in < 1023 bytes. +# Generated by infocmp -C -r -sc -T +Eterm-base|Eterm basic terminal capabilities:\ + :5i:am:bw:eo:km:mi:ms:ut:xn:xo:\ + :co#80:it#8:li#24:\ + :#2=\E[7$:#4=\E[d:%1=\E[28~:%c=\E[6$:%e=\E[5$:%i=\E[c:\ + :*4=\E[3$:*6=\E[4~:*7=\E[8$:@0=\E[1~:@1=\EOu:@7=\E[8~:\ + :@8=\EOM:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:\ + :F1=\E[23~:F2=\E[24~:F3=\E[25~:F4=\E[26~:F5=\E[28~:\ + :F6=\E[29~:F7=\E[31~:F8=\E[32~:F9=\E[33~:FA=\E[34~:\ + :IC=\E[%d@:K1=\E[7~:K2=\EOu:K3=\E[5~:K4=\E[8~:K5=\E[6~:\ + :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:\ + :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ + :ae=^O:al=\E[L:as=^N:bl=^G:cb=\E[1K:cd=\E[J:ce=\E[K:\ + :ch=\E[%i%dG:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ + :cs=\E[%i%d;%dr:ct=\E[3g:cv=\E[%i%dd:dc=\E[P:dl=\E[M:\ + :do=\E[B:eA=\E)0:ec=\E[%dX:ei=\E[4l:ho=\E[H:\ + :i1=\E[?47l\E>\E[?1l:ic=\E[@:im=\E[4h:\ :is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l:\ - :k0=\E[21~:\ - :k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:\ - :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:\ - :F1=\E[23~:F2=\E[24~:F3=\E[25~:F4=\E[26~:\ - :F5=\E[28~:F6=\E[29~:F7=\E[31~:F8=\E[32~:F9=\E[33~:FA=\E[34~:\ - :*0=\E[1~:kI=\E[2~:kD=\E[3~:*6=\E[4~:kP=\E[5~:kN=\E[6~:\ - :kh=\E[7~:@7=\E[8~:kB=\E[Z:\ - :ke=\E>:ks=\E=:\ - :ku=\E[A:kd=\E[B:kr=\E[C:kl=\E[D:\ - :K1=\EOw:K3=\EOy:K2=\EOu:K4=\EOq:K5=\EOs:\ - :kb=^H:up=\E[A:do=^J:nd=\E[C:le=^H:\ - :md=\E[1m:me=\E[m:mr=\E[7m:\ - :r2=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l\E<:\ - :rc=\E8:sc=\E7:se=\E[m:sf=^J:so=\E[7m:sr=\EM:ta=^I:\ - :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:u6=\E[%d;%dR:\ - :u7=\E[6n:u8=\E[?1;2c:u9=\E[c:ue=\E[m:\ - :us=\E[4m: -xterm-color|color-xterm|xterm with color support:\ - :tc=xterm:tc=ansi-pc-color: + :k0=\E[21~:k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:\ + :k5=\E[15~:k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:\ + :k;=\E[21~:kB=\E[Z:kD=\E[3~:\ + :kE=\E[8\014rs1=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H:\ + :kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=^H:kd=\E[B:ke=:kh=\E[7~:\ + :kl=\E[D:kr=\E[C:ks=:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:\ + :mr=\E[7m:nd=\E[C:pf=\E[4i:po=\E[5i:\ + :r2=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l\E>:\ + :rc=\E8:sc=\E7:se=\E[27m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ + :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:u7=\E[6n:u8=\E[?1;2c:\ + :u9=\E[c:ue=\E[24m:up=\E[A:us=\E[4m:vb=\E[?5h\E[?5l:\ + :ve=\E[?25h:vi=\E[?25l:vs=\E[?25h: + +Eterm-ansi|Eterm with ANSI color (X Window System):\ + :5i:am:bw:eo:km:mi:ms:ut:xn:xo:\ + :co#80:it#8:li#24:\ + :#2=\E[7$:#4=\E[d:%1=\E[28~:%c=\E[6$:%e=\E[5$:%i=\E[c:\ + :*4=\E[3$:*6=\E[4~:*7=\E[8$:@0=\E[1~:@1=\EOu:@7=\E[8~:\ + :@8=\EOM:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:\ + :F1=\E[23~:F2=\E[24~:F3=\E[25~:F4=\E[26~:F5=\E[28~:\ + :F6=\E[29~:F7=\E[31~:F8=\E[32~:F9=\E[33~:FA=\E[34~:\ + :IC=\E[%d@:K1=\E[7~:K2=\EOu:K3=\E[5~:K4=\E[8~:K5=\E[6~:\ + :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:\ + :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ + :ae=^O:al=\E[L:as=^N:bl=^G:cb=\E[1K:cd=\E[J:ce=\E[K:\ + :ch=\E[%i%dG:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ + :cs=\E[%i%d;%dr:ct=\E[3g:cv=\E[%i%dd:dc=\E[P:dl=\E[M:\ + :do=\E[B:eA=\E)0:ec=\E[%dX:ei=\E[4l:ho=\E[H:\ + :i1=\E[?47l\E>\E[?1l:ic=\E[@:im=\E[4h:\ + :is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l:\ + :k0=\E[21~:k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:\ + :k5=\E[15~:k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:\ + :k;=\E[21~:kB=\E[Z:kD=\E[3~:\ + :kE=\E[8\014rs1=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H:\ + :kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=^H:kd=\E[B:ke=:kh=\E[7~:\ + :kl=\E[D:kr=\E[C:ks=:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:\ + :me=\E[m\017:mr=\E[7m:nd=\E[C:pf=\E[4i:po=\E[5i:\ + :r2=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l\E>:\ + :rc=\E8:\ + :..sa=\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t\016%e\017%;:\ + :sc=\E7:se=\E[27m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ + :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:u7=\E[6n:u8=\E[?1;2c:\ + :u9=\E[c:ue=\E[24m:up=\E[A:us=\E[4m:vb=\E[?5h\E[?5l:\ + :ve=\E[?25h:vi=\E[?25l:vs=\E[?25h: + +Eterm-mouse|Eterm with X11 mouse reporting:\ + :5i:am:bw:eo:km:mi:ms:ut:xn:xo:\ + :co#80:it#8:li#24:\ + :#2=\E[7$:#4=\E[d:%1=\E[28~:%c=\E[6$:%e=\E[5$:%i=\E[c:\ + :*4=\E[3$:*6=\E[4~:*7=\E[8$:@0=\E[1~:@1=\EOu:@7=\E[8~:\ + :@8=\EOM:AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:\ + :F1=\E[23~:F2=\E[24~:F3=\E[25~:F4=\E[26~:F5=\E[28~:\ + :F6=\E[29~:F7=\E[31~:F8=\E[32~:F9=\E[33~:FA=\E[34~:\ + :IC=\E[%d@:K1=\E[7~:K2=\EOu:K3=\E[5~:K4=\E[8~:K5=\E[6~:\ + :Km=\E[M:LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:\ + :UP=\E[%dA:\ + :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ + :ae=^O:al=\E[L:as=^N:bl=^G:cb=\E[1K:cd=\E[J:ce=\E[K:\ + :ch=\E[%i%dG:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ + :cs=\E[%i%d;%dr:ct=\E[3g:cv=\E[%i%dd:dc=\E[P:dl=\E[M:\ + :do=\E[B:eA=\E)0:ec=\E[%dX:ei=\E[4l:ho=\E[H:\ + :i1=\E[?47l\E>\E[?1l:ic=\E[@:im=\E[4h:\ + :is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l:\ + :k0=\E[21~:k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:\ + :k5=\E[15~:k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:\ + :k;=\E[21~:kB=\E[Z:kD=\E[3~:\ + :kE=\E[8\014rs1=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H:\ + :kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=^H:kd=\E[B:ke=:kh=\E[7~:\ + :kl=\E[D:kr=\E[C:ks=:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:\ + :me=\E[m\017:mr=\E[7m:nd=\E[C:pf=\E[4i:po=\E[5i:\ + :r2=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l\E>:\ + :rc=\E8:\ + :..sa=\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t\016%e\017%;:\ + :sc=\E7:se=\E[27m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ + :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:u7=\E[6n:u8=\E[?1;2c:\ + :u9=\E[c:ue=\E[24m:up=\E[A:us=\E[4m:vb=\E[?5h\E[?5l:\ + :ve=\E[?25h:vi=\E[?25l:vs=\E[?25h: + +Eterm|Eterm-color|eterm|Eterm with xterm-style color support (X Window System):\ + :5i:am:bw:eo:km:mi:ms:ut:xn:xo:\ + :Co#8:co#80:it#8:li#24:pa#64:\ + :#2=\E[7$:#4=\E[d:%1=\E[28~:%c=\E[6$:%e=\E[5$:%i=\E[c:\ + :*4=\E[3$:*6=\E[4~:*7=\E[8$:@0=\E[1~:@1=\EOu:@7=\E[8~:\ + :@8=\EOM:AB=\E[%p1%{40}%+%dm:AF=\E[%p1%{30}%+%dm:\ + :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:F1=\E[23~:\ + :F2=\E[24~:F3=\E[25~:F4=\E[26~:F5=\E[28~:F6=\E[29~:\ + :F7=\E[31~:F8=\E[32~:F9=\E[33~:FA=\E[34~:IC=\E[%d@:\ + :K1=\E[7~:K2=\EOu:K3=\E[5~:K4=\E[8~:K5=\E[6~:Km=\E[M:\ + :LE=\E[%dD:RA=\E[?7l:RI=\E[%dC:SA=\E[?7h:UP=\E[%dA:\ + :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~:\ + :ae=^O:al=\E[L:as=^N:bl=^G:cb=\E[1K:cd=\E[J:ce=\E[K:\ + :ch=\E[%i%dG:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cr=^M:\ + :cs=\E[%i%d;%dr:ct=\E[3g:cv=\E[%i%dd:dc=\E[P:dl=\E[M:\ + :do=\E[B:eA=\E)0:ec=\E[%dX:ei=\E[4l:ho=\E[H:\ + :i1=\E[?47l\E>\E[?1l:ic=\E[@:im=\E[4h:\ + :is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l:\ + :k0=\E[21~:k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:\ + :k5=\E[15~:k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:\ + :k;=\E[21~:kB=\E[Z:kD=\E[3~:\ + :kE=\E[8\014rs1=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H:\ + :kI=\E[2~:kN=\E[6~:kP=\E[5~:kb=^H:kd=\E[B:ke=:kh=\E[7~:\ + :kl=\E[D:kr=\E[C:ks=:ku=\E[A:le=^H:mb=\E[5m:md=\E[1m:\ + :me=\E[m\017:mr=\E[7m:nd=\E[C:op=\E[39;49m:pf=\E[4i:\ + :po=\E[5i:\ + :r2=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l\E>:\ + :rc=\E8:\ + :..sa=\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t\016%e\017%;:\ + :sc=\E7:se=\E[27m:sf=^J:so=\E[7m:sr=\EM:st=\EH:ta=^I:\ + :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:u7=\E[6n:u8=\E[?1;2c:\ + :u9=\E[c:ue=\E[24m:up=\E[A:us=\E[4m:vb=\E[?5h\E[?5l:\ + :ve=\E[?25h:vi=\E[?25l:vs=\E[?25h: diff --git a/doc/Eterm.ti b/doc/Eterm.ti index 336aa7f..62faa21 100644 --- a/doc/Eterm.ti +++ b/doc/Eterm.ti @@ -1,147 +1,153 @@ -#------------------------------------------------------------------------- -# terminfo for Eterm (and xterm) -- [modified from the Midnight Commander] -# -# Install using `tic Eterm.ti', to be used with the enclosed termcap -#------------------------------------------------------------------------- +# Eterm terminfo file -xterm-basic|xterm terminal base (X Window System), - am, km, mir, msgr, xenl, xon, cols#80, lines#24, it#8, -# Not sure about eo (Erase overstrike with a blank) - eo, +Eterm-base|Eterm basic terminal capabilities, +# FIXME: xterm does not specify bce, bw, eo, or xon. Should we? + am, bw, bce, km, mir, msgr, xenl, xon, eo, mc5i, + cols#80, lines#24, it#8, lm#0, btns#5, cr=\r, bel=^G, -# Scroll text up, down - ind=\n, ri=\EM, +# Scroll text down/up one line + ind=\n, ri=\eM, -# Clear Screen, EOS, EOL, BOL - clear=\E[H\E[2J, ed=\E[J, el=\E[K, el1=\E[1K, +# Clear entire screen (home, then clear to EOS), EOS, EOL, BOL + clear=\e[H\e[2J, ed=\e[J, el=\e[K, el1=\e[1K, -# Change Scroll Region - csr=\E[%i%p1%d;%p2%dr, +# Change scrolling region to lines $1+1 to $2+1 +# %i means add one to params 1 and 2; convert from 0-based to +# 1-based counting. + csr=\e[%i%p1%d;%p2%dr, -# Cursor Position - cup=\E[%i%p1%d;%p2%dH, +# Move cursor to row $1+1, column $2+1. Can end with H or f + cup=\e[%i%p1%d;%p2%dH, +# Move cursor to column n, same row; or row n, same column + hpa=\e[%i%p1%dG, vpa=\e[%i%p1%dd, +# Move cursor up/down/forward/back by n chars + cuu=\e[%p1%dA, cud=\e[%p1%dB, cuf=\e[%p1%dC, cub=\e[%p1%dD, +# Move cursor up/down/forward/back by 1 char + cuu1=\e[A, cud1=\e[B, cuf1=\e[C, cub1=\b, +# Home cursor (row 1, col 1). Was \e[1;1H but 1's are redundant + home=\e[H, -# Horizontal & Vertical Position Absolute - hpa=\E[%i%p1%dG, vpa=\E[%i%p1%dd, - -# Cursor Up/Down/Forward/Backward: any, 1 char - cuu=\E[%p1%dA, cud=\E[%p1%dB, cuf=\E[%p1%dC, cub=\E[%p1%dD, - cuu1=\E[A, cud1=\E[B, cuf1=\E[C, cub1=\b, - -# Misc cursor motion - home=\E[1;1H, - -# Enter insert mode, leave insert mode - smir=\E[4h, rmir=\E[4l, +# Enter/leave insert mode + smir=\e[4h, rmir=\e[4l, # Set tab stops, clear tab stops, tab character - hts=\EH, tbc=\E[3g, ht=\t, + hts=\eH, tbc=\e[3g, ht=\t, -# Make cursor invisible, normal, bold - civis=\E[?25l, cnorm=\E[?25h, cvvis=\E[?25h, +# Turn on/off auto margins + smam=\e[?7h, rmam=\e[?7l, +# Make cursor invisible, normal, bold (not supported) + civis=\e[?25l, cnorm=\e[?25h, cvvis=\e[?25h, +# Save/restore cursor position + sc=\e7, rc=\e8, -# Save/Restore Cursor position - sc=\E7, rc=\E8, - -# Alternate Char Set (line drawing), enable/enter/exit ACS +# Alternate character set (line drawing), enable/enter/exit ACS acsc=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, - enacs=\E(B\E)0, smacs=\E(B\E)U^N, rmacs=\E(B\E)0^O, + enacs=\e)0, smacs=^N, rmacs=^O, -#-- begin AIX 3.2.5 hack -# acsc (box2 is the standard AIX form, box1 has been changed to work!) -# box1=llqqkkxxjjmmwwuuvvttnn, -# box2=lqkxjmwuvtn, -# font0=\E(B, font1=\E(0, -# position occupied by kend -# colf7=\E[8~, -#-- end AIX 3.2.5 hack +# Delete/insert n chars, 1 char + dch=\e[%p1%dP, ich=\e[%p1%d@, dch1=\e[P, ich1=\e[@, +# Delete/insert n lines, 1 line + dl=\e[%p1%dM, il=\e[%p1%dL, dl1=\e[M, il1=\e[L, +# Erase next n chars + ech=\e[%p1%dX, -# Delete/Insert: Chars, Lines, 1-char, 1-line - dch=\E[%p1%dP, dl=\E[%p1%dM, - ich=\E[%p1%d@, il=\E[%p1%dL, - dch1=\E[P, dl1=\E[M, - ich1=\E[@, il1=\E[L, +# Activate SGR mode: bold, reverse video, blink (bright bg color) + bold=\e[1m, rev=\e[7m, blink=\e[5m, +# Start/stop underline, standout (reverse video) + smul=\e[4m, rmul=\e[24m, smso=\e[7m, rmso=\e[27m, +# Flash the screen (sets and resets reverse video for the whole screen) + flash=\e[?5h\e[?5l, -# Erase Chars - ech=\E[%p1%dX, +# Enter/leave application keypad mode. We always send the ANSI values +# because that seems to be the most portable solution. The valid escape +# sequences are here but are commented out for this reason. The 1st set +# is for keypad cursor keys, the second is for application cursor key +# mode. The third is what gets sent by default. +## smkx=\e=, rmkx=\e>, + smkx=, rmkx=, +## kcuu1=\e[Ox, kcud1=\e[Or, kcuf1=\e[Ov, kcub1=\e[Ot, +## kcuu1=\eOA, kcud1=\eOB, kcuf1=\eOC, kcub1=\eOD, + kcuu1=\e[A, kcud1=\e[B, kcuf1=\e[C, kcub1=\e[D, -# Enter/Leave Fonts: Bold, Reverse, Blink, Underline -# standout (enter/leave), Define attribs 1-9 - bold=\E[1m, rev=\E[7m, blink=\E[5m, - smul=\E[4m, rmul=\E[24m, smso=\E[7m, rmso=\E[m, - -# visual bell - flash=\E[?5h\E[?5l, - -# Enter/leave keypad transmit, Cursor keys (sent by terminal). Don't touch -# cursor keys! use ANSI cursor keys rather than application cursor keys to -# avoid starting in application cursor mode when `$xterm&' is used and to -# enable the Eterm Shift/Ctrl cursor extensions. - smkx=\E=, rmkx=\E>, - kcuu1=\E[A, kcud1=\E[B, kcuf1=\E[C, kcub1=\E[D, - -# Other nice keys - ka1=\EOw, ka3=\EOy, kb2=\EOu, kc1=\EOq, kc3=\EOs +# Keypad 7, 9, 5, 1, and 3. The 1st set are the appl. keypad mode +# sequences. The 2nd set are the values for Home/End/PgUp/PgDn. +# The 5 key is the same either way. +## ka1=\eOw, ka3=\eOy, kb2=\eOu, kc1=\eOq, kc3=\eOs, + ka1=\e[7~, ka3=\e[5~, kb2=\eOu, kc1=\e[8~, kc3=\e[6~, # Function keys - kf0=\E[21~, - kf1=\E[11~, kf2=\E[12~, kf3=\E[13~, kf4=\E[14~, kf5=\E[15~, - kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, kf10=\E[21~, - kf11=\E[23~, kf12=\E[24~, kf13=\E[25~, kf14=\E[26~, - kf15=\E[28~, kf16=\E[29~, kf17=\E[31~, - kf18=\E[32~, kf19=\E[33~, kf20=\E[34~, + kf1=\e[11~, kf2=\e[12~, kf3=\e[13~, kf4=\e[14~, kf5=\e[15~, + kf6=\e[17~, kf7=\e[18~, kf8=\e[19~, kf9=\e[20~, kf10=\e[21~, + kf11=\e[23~, kf12=\e[24~, kf13=\e[25~, kf14=\e[26~, kf15=\e[28~, + kf16=\e[29~, kf17=\e[31~, kf18=\e[32~, kf19=\e[33~, kf20=\e[34~, +# F0, same as F10 + kf0=\e[21~, -# Find, Insert, Delete, Select, Prior, Next - kfnd=\E[1~, kich1=\E[2~, kdch1=\E[3~, kslt=\E[4~, kpp=\E[5~, knp=\E[6~, -# Home (vt100 may use khome=\E[H), End, Backspace, Enter, Backtab - khome=\E[7~, kend=\E[8~, kbs=\177, kent=\EOM, kcbt=\E[Z, +# Find, Insert, Delete, Select, Prior (PgUp), Next (PgDn). The first set of +# sequences are accurate. The second set lets Find/Select act like Home/End. + kfnd=\e[1~, kich1=\e[2~, kdch1=\e[3~, kslt=\e[4~, kpp=\e[5~, knp=\e[6~, +## kfnd=\e[7~, kich1=\e[2~, kdch1=\e[3~, kslt=\e[8~, kpp=\e[5~, knp=\e[6~, -# Shifted Right, Left, Delete, Prior, Next, Home, End, Ctrl-End - kRIT=\E[c, kLFT=\E[d, - kDC=\E[3$, kPRV=\E[5$, kNXT=\E[6$, - kHOM=\E[7$, kEND=\E[8$, kel=\E[8^, +# Home (vt100 may use khome=\e[H), End, Backspace, Keypad Enter, Shift-Tab +# The 1st set is the default. The 2nd set is based on Linux console/vt220 +# settings for Home/End and Backspace sending Delete (^?). The 3rd set gives +# xterm's settings for Home/End. + khome=\e[7~, kend=\e[8~, kbs=\010, kent=\eOM, kcbt=\e[Z, +## khome=\e[1~, kend=\e[4~, kbs=\177, kent=\eOM, kcbt=\e[Z, +## khome=\e[H, kend=\e[F, kbs=\010, kent=\eOM, kcbt=\e[Z, + +# Help and Begin keys + khlp=\e[28~, kbeg=\eOu, +# "Shifted" right and left (actually Ctrl, not Shift) + kRIT=\e[c, kLFT=\e[d, +# Shift-Prior/Next (PgUp/PgDn). Usually, these key combos scroll. + kPRV=\e[5$, kNXT=\e[6$, +# Shift-Delete/Home/End and Ctrl-End. It's a $ instead of a ~ for +# Shift-, a ^ for Ctrl-, and @ for Ctrl-Shift-. + kDC=\e[3$, kHOM=\e[7$, kEND=\e[8$, kel=\e[8^, # Reset terminal, turn off all attributes - rs1=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H, - rs2=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l\E>, -# dec.ti -# rs2=@, - + rs1=\e>\e[1;3;4;5;6l\e[?7h\e[m\e[r\e[2J\e[H, + rs2=\e[r\e[m\e[2J\e[H\e[?7h\e[?1;3;4;6l\e[4l\e>, # Init terminal - is1=\E[?47l\E=\E[?1l, - is2=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l, + is1=\e[?47l\e>\e[?1l, + is2=\e[r\e[m\e[2J\e[H\e[?7h\e[?1;3;4;6l\e[4l, -# Leave/Enter CA-Mode. - smcup=\E7\E[?47h, rmcup=\E[?47l\E8, -# dec.ti -# smcup=\E[?7h\E[?1l\E(B\E=, rmcup=\E[?7h, +# Enter/leave cursor address mode. The 1st set uses the +# secondary screen. The 2nd one doesn't. + smcup=\e7\e[?47h, rmcup=\e[2J\e[?47l\e8, +## smcup=\e7, rmcup=\e8, -# turn on/off the printer -# mc5=\E[5i, mc4=\E[4i, - mc4=\E[4i, +# Start/stop redirection to the printpipe + mc4=\e[4i, mc5=\e[5i, -# -# XTerm with color support. -# -xterm|vs100|xterm terminal emulator (X Window System), - use=xterm-basic, -# sgr=\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t^N%e^O%;, - sgr=\E[%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p6%t;1%;m, - sgr0=\E[m^O, -# from dec.ti -# sgr0=\E[m\E(B, -# sgr0=\E[m, -# sgr=\E[%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p6%t;1%;m%?%p9%t\E(0%e\E(B%;, +# User-defined string capabilities +# Report current screen position + u7=\e[6n, +# vt100 answerback + u8=\e[?1;2c, +# Request identity (replies with u8) + u9=\e[c, -xterm-color|color-xterm|Eterm|eterm|color xterm terminal emulator (X Window System), - use=xterm, colors#8, pairs#64, +###### Add ANSI color support +Eterm-ansi|Eterm with ANSI color (X Window System), + use=Eterm-base, + sgr=\e[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t^N%e^O%;, +## sgr=\e[%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p6%t;1%;m, + sgr0=\e[m^O, -# Set all color pairs to the original ones -# op=\E[0m, - op=\E[39;49m, +###### Add mouse reporting +Eterm-mouse|Eterm with X11 mouse reporting, + use=Eterm-ansi, +# Mouse info packet introducer + kmous=\e[M, +###### Add xterm-style color sequences. +Eterm|Eterm-color|eterm|Eterm with xterm-style color support (X Window System), + use=Eterm-mouse, colors#8, pairs#64, + +# Revert to the original foreground/background pair + op=\e[39;49m, # Set foreground color, background color - setf=\E[%p1%{30}%+%dm, setb=\E[%p1%{40}%+%dm, - -#--------------------------------------------------------------------- eof + setaf=\e[%p1%{30}%+%dm, setab=\e[%p1%{40}%+%dm, diff --git a/doc/Makefile.am b/doc/Makefile.am index b6833dc..02a5c0c 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -2,7 +2,7 @@ man_MANS = Eterm.1 -all: Makefile Eterm.1.html +all: Makefile Eterm.1.html terminfo Eterm.1: $(top_srcdir)/doc/Eterm.1.in $(SED) -e 's%@''VERSION''@%$(VERSION)%g' -e 's%@''DATE''@%$(DATE)%g' -e 's%@THEMEDIR@%$(pkgdatadir)/themes%g' $(top_srcdir)/doc/$@.in > $@ @@ -10,5 +10,8 @@ Eterm.1: $(top_srcdir)/doc/Eterm.1.in Eterm.1.html: Eterm.1 -nroff -man $< | man2html -title Eterm > $@ +terminfo: Eterm.ti + -$(TIC) Eterm.ti + EXTRA_DIST = Eterm.1.in Eterm_reference.html Eterm.tcap Eterm.ti Makefile.am Makefile.in diff --git a/libmej/mem.h b/libmej/mem.h index b3ad013..6e826d9 100644 --- a/libmej/mem.h +++ b/libmej/mem.h @@ -42,12 +42,12 @@ typedef struct memrec_struct { # define MALLOC(sz) malloc(sz) # define CALLOC(type,n) calloc((n),(sizeof(type))) # define REALLOC(mem,sz) realloc((mem), (sz)) -# define FREE(ptr) do { free(ptr); ptr = NULL; } while (0) +# define FREE(ptr) do { free(ptr); (ptr) = NULL; } while (0) #elif (DEBUG >= DEBUG_MALLOC) -# define MALLOC(sz) Malloc(__FILE__, __LINE__, sz) +# define MALLOC(sz) Malloc(__FILE__, __LINE__, (sz)) # define CALLOC(type,n) Calloc(__FILE__, __LINE__, (n),(sizeof(type))) # define REALLOC(mem,sz) Realloc(#mem, __FILE__, __LINE__, (mem),(sz)) -# define FREE(ptr) do { Free(#ptr, __FILE__, __LINE__, ptr); ptr = NULL; } while (0) +# define FREE(ptr) do { Free(#ptr, __FILE__, __LINE__, (ptr)); (ptr) = NULL; } while (0) # define MALLOC_MOD 25 # define REALLOC_MOD 25 # define CALLOC_MOD 25 @@ -56,7 +56,7 @@ typedef struct memrec_struct { # define MALLOC(sz) malloc(sz) # define CALLOC(type,n) calloc((n),(sizeof(type))) # define REALLOC(mem,sz) ((sz) ? ((mem) ? (realloc((mem), (sz))) : (malloc(sz))) : ((mem) ? (free(mem)) : (NULL))) -# define FREE(ptr) do { free(ptr); ptr = NULL; } while (0) +# define FREE(ptr) do { free(ptr); (ptr) = NULL; } while (0) #endif extern char *SafeStr(char *, unsigned short); diff --git a/libmej/strings.c b/libmej/strings.c index 3f6ff5e..7aaaad3 100644 --- a/libmej/strings.c +++ b/libmej/strings.c @@ -83,7 +83,7 @@ usleep(unsigned long usec) /***** Not needed ****** #ifndef HAVE_NANOSLEEP -inline void +__inline__ void nanosleep(unsigned long nsec) { usleep(nsec / 1000); } diff --git a/pix/Makefile.am b/pix/Makefile.am index b5d748e..289c23f 100644 --- a/pix/Makefile.am +++ b/pix/Makefile.am @@ -2,7 +2,8 @@ EXTRA_DIST = bar_horizontal_1.png bar_horizontal_2.png bar_horizontal_3.png bar_vertical_1.png bar_vertical_2.png \ bar_vertical_3.png button_arrow_down_1.png button_arrow_down_2.png button_arrow_down_3.png \ - button_arrow_up_1.png button_arrow_up_2.png button_arrow_up_3.png menu1.png menu2.png menu3.png + button_arrow_up_1.png button_arrow_up_2.png button_arrow_up_3.png menu1.png menu2.png menu3.png \ + thumb_1.png thumb_2.png help.png exit.png pixmapdir = $(pkgdatadir)/pix diff --git a/pix/exit.png b/pix/exit.png new file mode 100644 index 0000000000000000000000000000000000000000..0baf10973a75106ec75c9c3391c7c13da9c1feef GIT binary patch literal 5844 zcmWky2{=@36uy`klZQz{whZbYl6_BNvNa-2b|x|Qk}YFr(kN6~EM?6$mXQ&%XUSf& zP8v02&E%hiCPv2c-~T?(ckgrOdFFiQocn(7IpdCfKL-}X+wFz zyNv0*XW#?kYhn%lSo`?!uE!zpoj=&pISc>}3;(~kCT8My0YEh3qN#~pWM1!A*PCtw zQGDwMA6q`^$1tunPm|tYymQ=A>qsx2T{P=JD%r`KKorcl^~@LVe^zlR{9(lzD>lBO zH+X?Fb~vv%&eGP{Oj0CJ31V^=!Yj~-$I>%%n=6%^Gn$uF8pM8uwlvi_9YZL#Y-cK z-Fe_v;-=Em7$|W60u)i`FJWh&L}8AFOE(6VI8-5?4;4976}hRbMM;N0W{V8f8R<$1 z9yHUK)&jgd>0y-Uf^sP0dd?|EUXYJQb^_0O_dj1hoRt@EcXDw-wYZ%EkN~f&pfOJu zmjKrky{4}vjNw&IefR0pCku<$fgH!C#>V~YVPTrgR*Hs{;IUb@KOC|icOq@kFOT&G zzL3X=IzJY^H}u}CuJa(UBOznxJDeau;3mieY221Pa3BDnaBl|zB$|7|jEV?sLTi|F zZA}I;%TBO{KGhbuAcnF9postq8ay)JsuDZvcy3gZ6?b4~kiQ>aLyOTDeSoF2KmR%+ zrh4rXuq{AvhXg~LVo<`y5CR&C$e6H3uehR;I}az$4fM>9MPS(-G`nB%xcK<}$DXxL zaxX`zPRcp~T8XmFi=*tge>q0!n6%^fLQv2mwf^|s_gd0`tm?J572J_hT~GaWZ=OSRwtQ8TCzdq+$F_h?E6Y>*lRnzoO=2qEX7CnnKbBrr?5%=&QJQ zJgjo8@r;YZ;@hxJS!U+QyYC2=iao$`Sc{a1nLn{-el0$1^bg>#`x&@WR{gPp9Avy7bKWnGF}OYs?HF5YMKRB}dBryaU-@O$W1cX#)Cchce7?Cj%MTKGbgOzf?U*8|wWC8uQh*o6kTQXHH3m-jX?3HL z2e{sPi}!~KoxLGt7`c9RCJG>g1FRMvS$e z%pZ+uFSx0bYlM3RlO1HRkeTS1Z;XQ8$c5gN%T;6-FmQ8aQTd1JemT5o#iEQlTVyH3 zWGq zK$6D7;~-;33Hz}(qoWO^9`q%XzwO&#X=V*B$1>5R5&Z+U?rbdUL^yU}vdZziMEAnN z0uz;7u1NCle-R+gdy+`NptY<^$Yjt7)6$G%^hWEEmR}sBOpK@G-N=G+enh`Gj_ca>;AdZtKRQtY+)6qG1PI}l&qgPG9QgL2SFlV^T&DB-% z4Slt#dw$(2r%Zo7Sp2!F`@SF4;<3!8z5O1=+nI$*4nbE^{3Wi~XI7BWx3T3pW$M;c z5%fwbBdV1V1=0zxNw5&H%>QxlNM~S98QTM}va&LzZPw^YJYwVyFP8?=Z|V{#OcSNd zy2mo-zQ!zP`xa|zYSwOSgb2fujG=cJQB%{?z5o78c2#*^^QCc*(HQ7{Ma1lD<0JNL z!a)f_>U@0OPRCj$c}F$NJO2sB=QysF!aNJlDZ7HDWtaJ9sBd*JTh#|bPN#Z`*%KgkO((L^P64i52lv~fd$*L=hs{ei z+^QyXrp`ecxe_m(!X10ix0S8w+wbG++q1a1*sC?1FEh4s+g9cIjHK=@<%qVK8oe}D zJGLoOjd%otSn7160j zl4OsiJ-1-{>Ezav$sKjIwHsd?s6D z$Ui^Et5;>+@94 z8T$UqGBMwVkA!*ejK#KpTe-deF(j|ERj6wp0i1pRJEk%4?NfJ3D`y znu_dZ?+IZOV#T|!eQywYwEB}13Wp?|AsO<@=Gc^1dWiRGS!);>QLds{blC1oS*Q%p zlYjATA1Y)JM1UYouvF--|8jF}sum~7VzH9IFn;(+K!OJh=K3E=R?XaE|K*F?YG1em zCrBsHRyb760>P*&8GahscDJ#7xQC@we^?iE!Gic?5ztu0yUy=!QL^CN)>L?k>D!w+ zZT8BdZU5Nh4PLgkUVR0*Lyx)B26QwGXl-|GbV0iUp=MV)oT?pE6;ppJDtaqqq7~_F zm!H{`Yb$!o07Q5YKcYYwRca2;z$ggw8>y?;g7$8JFu7k|R_1y1=+THjgjIzf6bdDN zY!&YwF2xAiDq20eVG9MWJ3E}{5<8vw;UuEBoCtq<>C}beI1tMJ=OSc;mA2T`xOxCt zFD*vm8Us($+ur>ud2ICcMSlJ{LtS05&KQZGo6*SUL;ruk$@$>z;{zdE?G>CcXxC-L zt(n&Fi_i@{ghBzDRNE<8+Uof8F!%b^cM7EgXmgS1cAQBf!hSRJOYRl;jSUl#>!n z*!+-r+KN`=E=0m88fa^qfgK6h6%->y0MOcb=d4LxfszX3hp>n0Xy~0qy&r5&#biKp z{9fx%e4FcD{6R5%;pjQqlp_Ri!eaNLOUA|5ZX2Y+6E9u5GzT*Bix)4}&*qPa0uYn+ zIuCIG7-i|WRA(K9C21+1th7^#Tx)0B*3d}BNM(sf1;-^NIn=%Qk(t^W=&%oK(xn<- zbgiZwEc2&`#!d93jER@o+5UZt8yKWWj;=N9IRK|OR`txUN4H-)D5S1@)X5zlYq&x4 zD;Xy+qB7J)trUcPxndbh@6+8|qgcyvL(4)(IrqQ~-2=5G!~z;z@M_`}d93k%{=4tG zHVuO`Wgd@88^!8nUOJ_XfavJzYJ#-42x1#e!fbr_{(A#W5(ZO9#H6k+c2;Eko~8$N z?)BIr|B!<9rs*}lGJPGgTDimLk8?R?HPlN^8#T>sM8>M=>+7qZJC|=5x|A&Z$ovR| z3sWhgDX?fVh3@w}jwxu; z5f^wyVW!Qr)1Zm63dG0^%nlpaI<|ldD#Tl~UrVU`a&zCI{n|?q#5+*qD!{rckx z)`ERZ6W+1HNMS2NOg}ZCVFz9RWp^{WJsxDaRU@${Pc4Zj^nwdJo12lMqN2h{D3eF# zCARkAw{7pncM6TN%)M`W=A6c)58N1vOZ^`E%69N3x^`inSgT* zjc1g#R3Tc6CCj%`>Vx%O1>`h>`4OQvK9Yt0LQaBhVd%(F;*(J_+2B+7p2c}xB8hYo zrMTx(H5m;8k->NOPKRWdmi5z7#{CBm9_YpG+0pgysq@fNnOqUWGR_6CW^9reUx6Czb)T5OWTa8d9ZE9h2qEPJ=49G=X-GbSNlQ4 zKI7Tv(*gzgchodB<)!sQm+n_pRZ%n1-;VRH&*c+4%m69<9@1^`FF?@r+V}q?d(rJR7WYoOa||HRFKL0 z<&y#a1q}cB2@vJeYL(1Z1H_UV!poBSW)v^d{qyImKYe2EuX*?ccS{|r+TB&2UtPt= zSOGX3?*D$mv(hfrT<(Z1`a+QiH}W}}biR?kD%7)!bzkfVr1PQR9#tx@U|`E^O^q%d z|54&ofAP%F1QGs;Wk|FiU%9P-Alg9R!%>1aa<*2O#*vja%`t41nBDD=-NC2wC%&`( z22rZ3S8D@ZzkNC;2nKz%GDBNk-Nf9&0tdz{agVEiikIM~Ld(w0Jq^~VYqJ8f4{zQ7 zVF9*L=QraLF@xTUp2XqQcn~^7O zgXLIP1o-^t&!0xGEr(3FTYGfot5>i795PwAskEyD87Irz*$~PtcM(&;g90Wt76%?( zIwhZEB|8lXYsqVR{n}O~6W!UQ%;Zz$9LcxwO;X>=_I3_xqtI1{>Lvo`gOp+R_Q(32 zP}DaAW&WwZY@vrQgKXfDQ)X8~YoKt|N3VT57vtsSwWwd?%5U(w+@?ct?hGwl5m?|D ziQ{rl8|UQZecIu0bo1tit*(1`6uBvjCV11gPS0|;?Ip8;-4XU)x(WP`prD`zmc~!Y z==D@D#Z-zDnvUZRniCG<8S62k<+P|dF3ElS4!kJX{-SZ!b~Kf+Q^n|kOqcVY0_w|0kw zgwD%~eLeSGPp^u}f|D?e+4IyFkm4@%h_mLs=dle=CW@@T`e8= zlg%B*gCj#2cLK$`R-4-bzi zEgTe?^hTCpgOkk7#}N}p;izU*@?|Vdx;C)waTrB0RW3a4axqy+pa-vg=vts_<{&GQCuZHH)>_5iHeEs_4W1b{Qmu$0UB!y>OS^W z=_Y+Yq`@T+9OmM>^e_A8^uu~&AF8YM8!H~d38WUQ(ZWG4KgP?)mka830u=Yo{fW1( zDJ0{p?_}kngVnV4lXYKyB8KWJn5`9dO8KZF+tbg75~k3+o%8F;Lp$3OB&*Ke9U_MY z#PW5$UgNYWT+|T9&E+}5dYb8UI%f^rhOf>)8=;bHDyM3_)7{@(SC?2>smN7$5n2hn zXpiG;{f#wRQ#o@+`$69Vb#ii22;{D%;oZ>#NiN`$we=yV&N&a>OJ}idIkmoGc95N1WWP#jg22FUHYq9R$i_MxHSix*qllqzd@t4gJS4sM%1-w z*4qT`ZMx0Zg_`4%js#HsyHp!LU&6%P}!9Vhk6r6hi3U&7a cekX08NaYf+ms2ORKwTQRXl7$dL0wP$50N7~yZ`_I literal 0 HcmV?d00001 diff --git a/pix/help.png b/pix/help.png new file mode 100644 index 0000000000000000000000000000000000000000..512f8a4de2306481cf5c5748647f8ac88d5a7b16 GIT binary patch literal 3188 zcmV-)42$!LP)0DAsqcq->YjVfErKEF z^5x4v2Ec?6ObB6e&ht?erNS^w#c`}rN+}^kDvIKVVVDv^Xo{kQsZ^?wOeWU|A)l_S zto&#g-jt&ZR;^awlv1XGAUGLCQ7#Aq!}tBP=XnX&b=4pUs1SkyfTAdpQYwWIL4=AO5DPw`_ z18-W@YV}pldA{H8Ki_ONpJ}yPMaOYS9LHdcA(2R+P$+~WBO`%jS#haUVueCMu`Ej& z9UWz*Qi-UlN*u?5ZQEL}*W;~LOB9Pme(&BrIT#FR6h+MQJfiEmu4&pBV{HB?V1dU- z=}VU`{iWkL&(!PnXIib6;kqu_-+(fij4YK(?)3C@G&eV=RVo#2baYfPO_OA^S)|ix zD2f6h1mZY`loC-C!Eqea>vg%YvB5ph6JZ!K+qS6?f}~QZ$oKs(UDy5T_3PKae^}rH zr}W8_C;z(`X`*AlYnI8ioPOvgpLb1WP89=_rbf>FMdSw{G29 zISlZDQ#uF&tJmvg2ZI6GFEgoBN|s6`_tdFV-P5N}n+ppI$;rt{l1`@)h9P>r9vsI3 z=Nz1K3|x7&Ig$AmEkDJ2q#1jfh5!-a)~!NS5qadB}mIX*s4;yA|U=BBLGYP{8Id7VzD z8^`g0bB-vA0?xV37)$1Ixv}Z#>3pS9(HUcm5JI9TB5@o`DWwE}QmF(0N!zxkUwP$~ z_uqg2{a20!7yze~4wA{Fd{8=&OeRq-mz5`;c%rbdu%L{Ok3&%uY;A4H)z#I0tycTb zx88c|*-BnsQc4(O((^p2swy!}lbEKNs@LnO z$AvvGux;BvN+c4$TPl_OY&NScEiI9ekr4n676;yo12^7_V)JAu3o+R z-Ty1z%F4={)oOLR-ERNDaU7#wuNy*$l<)f_l}bs|G~-+@M=7O5(=_P1u24!7#|CU! z*7t=FzeuH03*~Y-y|}ojOifK82mH0={z z*RzZ*#rF2LySux4>+0337r$v-DWx6+fo!+isMTtSq6ocSk5Wnp z#bS{R27`=Y7*G_2Fvijc$NX;{c$dC$V=1FLTak27|$ZZQHZ0R;z5= zwi3rN6h(oq>ycp?TB%gZ?RI~! z-EPl!yWK<(1PH?rLWqZFYs<3YN~NM+xNt$QR4O!)NWivjbi3Uk2!hsOybK-qkyRb{ zJny+~w|l1DZjW}mT{R5D{qJ=@jk#r6;o{;VdG^_7_4)aEn$2e6c^-Clc6g)FXukXI zyT5-JKSKq6FM@5CTopU>HV}&1N0bG`-o`+4RMW7c=M1 zoum1D9)rOETU%RleSO{D+uQr=!+IL}3deDL(skYEJDtwCcDtSH_xp4oHknMKP$+mK zBO}dnxg3p+jhSc9p3N*SF0xXo1R(@ktrk{SSDn{if4z7Veuf5ItyW)^Qs#W$e`+7r z^E?Uwx~@albrcGP!PwYXb8c=LA;oZA;|Kq59 z3U!4!=OeD`p6+xyrfu6)Q50meS!tT4UnmrU$;nB-QmI%A3k#`Ar9$%gJc1xVx7$Un zRugM$YwlNHef9He*RFl%s5}Z4SO}qoVVHU_fCnK2*=*LEnwo0Q%*%jF=1K)qhaojZ5L#>Pg!R;&Hgah!j-apT4hhhb>gzyf&K41iJ!RaI#& zmt%%u5K1X*+s4}3TKxIvpYJrA&7TE9@aFRJ@;?sC(6CdQNhv7+vJb7Qs*=m)XeN^Z zr4+8~VtaerX*3%DeEs_MKOCkXVE8Lcg%EVV#d~mkR1Cv-c-7+jK78Nzj{_DMGB6>8 zQ%X4iDWxQwa{!=*VL;b)aL&>1_l4(qhw6Y1B0ALIl-h|z!qzlR5<(u{8fG#X=(>(D z4AJRy_#1D$F*8gb|HIQzgHzheWHLL3VMMB`f)D~J<-;qMPN#$2-Cci}9{#t6n$nE1 zRyv*jH_NgnqA03FQAFc7#_H-S!Z5_`+qZ+;w{Ncs)59-$8dl)-_4Uu@=jWfMlMe5-Hut%j$aogK2XvvVYW5gkNBd*S|g zCk(^IPN#FFUa!wOj>Ciyuq+Gb&Yk1sa=Gg`&f42=zx^w37l)yt)?vek4F*i4dR4N6|IVzP3jpNt?ustj(|C{EIOTzt?T-su1^l4q3+Tjee}^UKK=C5=SD_G>ZMYt z%NPsA*FB<$<(J_npL}vlQIuorhmWlsL{XHYl>Qcg?@>ypIOm&;v3~&Y6GF(b a0sj|z+Y43qdoS|<0000>=hH3wq-?6+C{j2hKIim*S@;HGwqs<>S?_~xFT$I1) zCm|uh@LB4!`V;Oa>WtRb*8gQ?Wf^2-WEj}l*%{uvdBecu@X28l3kwTafSa3}!SuQ5 rCT5TsAT3XMo~ox-CnCjfmb&o~Z@(Ep`x!i4{an^LB{Ts57-2uj literal 0 HcmV?d00001 diff --git a/pix/thumb_2.png b/pix/thumb_2.png new file mode 100644 index 0000000000000000000000000000000000000000..c20fdff0c497740766c433a3914d7c40cf810a12 GIT binary patch literal 209 zcmeAS@N?&q;$mQ6;PUiv2?ElrAk4uABzyDKo&qVBbVpxD28NCO+>=hH3v9Pl@%^elVHRB+K=W;laI648r#->lpX>DEv20 zaAn{SyumdKI;Vst0IzLC A7ytkO literal 0 HcmV?d00001 diff --git a/src/Makefile.am b/src/Makefile.am index dcae805..d935604 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,13 +2,14 @@ lib_LTLIBRARIES = libEterm.la -libEterm_la_SOURCES = actions.c actions.h command.c command.h debug.h draw.c \ - draw.h e.c e.h eterm_utmp.h events.c events.h feature.h \ - font.c font.h grkelot.c grkelot.h icon.h menus.c menus.h \ - misc.c misc.h netdisp.c options.c options.h pixmap.c \ - pixmap.h profile.h screen.c screen.h scrollbar.c \ - scrollbar.h startup.c startup.h system.c system.h term.c \ - term.h timer.c timer.h utmp.c windows.c windows.h +libEterm_la_SOURCES = actions.c actions.h buttons.c buttons.h command.c \ + command.h debug.h draw.c draw.h e.c e.h eterm_utmp.h \ + events.c events.h feature.h font.c font.h grkelot.c \ + grkelot.h icon.h menus.c menus.h misc.c misc.h netdisp.c \ + options.c options.h pixmap.c pixmap.h profile.h screen.c \ + screen.h scrollbar.c scrollbar.h startup.c startup.h \ + system.c system.h term.c term.h timer.c timer.h utmp.c \ + windows.c windows.h libEterm_la_DEPENDENCIES = $(top_builddir)/libmej/libmej.la feature.h libEterm_la_LDFLAGS = -release $(VERSION) diff --git a/src/buttons.c b/src/buttons.c new file mode 100644 index 0000000..b8b8830 --- /dev/null +++ b/src/buttons.c @@ -0,0 +1,781 @@ +/* + * Copyright (C) 1997-2000, Michael Jennings + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies of the Software, its documentation and marketing & publicity + * materials, and acknowledgment shall be given in the documentation, materials + * and software packages that this Software was used. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +static const char cvs_ident[] = "$Id$"; + +#include "config.h" +#include "feature.h" + +#include + +#include "../libmej/debug.h" +#include "../libmej/mem.h" +#include "../libmej/strings.h" +#include "buttons.h" +#include "command.h" +#include "draw.h" +#include "e.h" +#include "events.h" +#include "font.h" +#include "startup.h" +#include "menus.h" +#include "misc.h" +#include "options.h" +#include "pixmap.h" +#include "screen.h" +#include "term.h" +#include "windows.h" + +static __inline__ void draw_string(buttonbar_t *, Drawable, GC, int, int, char *, size_t); + +buttonbar_t *buttonbar = NULL; +long bbar_total_h = -1; + +static __inline__ void +draw_string(buttonbar_t *bbar, Drawable d, GC gc, int x, int y, char *str, size_t len) +{ + + D_BBAR(("Writing string \"%s\" (length %lu) onto drawable 0x%08x at %d, %d\n", str, len, d, x, y)); + +#ifdef MULTI_CHARSET + if (bbar->fontset) + XmbDrawString(Xdisplay, d, bbar->fontset, gc, x, y, str, len); + else +#endif + XDrawString(Xdisplay, d, gc, x, y, str, len); + return; + bbar = NULL; +} + +buttonbar_t * +bbar_create(void) +{ + buttonbar_t *bbar; + Cursor cursor; + long mask; + XGCValues gcvalue; + XSetWindowAttributes xattr; + + bbar = (buttonbar_t *) MALLOC(sizeof(buttonbar_t)); + MEMSET(bbar, 0, sizeof(buttonbar_t)); + + xattr.border_pixel = BlackPixel(Xdisplay, Xscreen); + xattr.save_under = FALSE; + xattr.backing_store = NotUseful; + xattr.override_redirect = TRUE; + xattr.colormap = cmap; + + cursor = XCreateFontCursor(Xdisplay, XC_left_ptr); + mask = EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; + gcvalue.foreground = xattr.border_pixel; + + bbar->font = load_font(etfonts[def_font_idx], "fixed", FONT_TYPE_X); + bbar->fwidth = bbar->font->max_bounds.width; + bbar->fheight = bbar->font->ascent + bbar->font->descent + rs_line_space; + bbar->h = 1; + bbar->w = 1; + gcvalue.font = bbar->font->fid; + + bbar->win = XCreateWindow(Xdisplay, Xroot, bbar->x, bbar->y, bbar->w, bbar->h, 0, Xdepth, InputOutput, CopyFromParent, + CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWBorderPixel | CWColormap, &xattr); + XDefineCursor(Xdisplay, bbar->win, cursor); + XSelectInput(Xdisplay, bbar->win, mask); + XStoreName(Xdisplay, bbar->win, "Eterm Button Bar"); + + bbar->gc = XCreateGC(Xdisplay, bbar->win, GCForeground | GCFont, &gcvalue); + bbar_set_docked(bbar, BBAR_DOCKED_TOP); + + return bbar; +} + +void +bbar_init(buttonbar_t *bbar, int width) +{ + event_register_dispatcher(bbar_dispatch_event, bbar_event_init_dispatcher); + XSetForeground(Xdisplay, bbar->gc, images[image_bbar].norm->fg); + bbar_resize(bbar, width); + bbar_reset_total_height(); + bbar_calc_total_height(); +} + +void +bbar_event_init_dispatcher(void) +{ + /* FIXME: The event subsystem needs to be able to pass a pointer to the event data structure. */ + EVENT_DATA_ADD_HANDLER(buttonbar->event_data, EnterNotify, bbar_handle_enter_notify); + EVENT_DATA_ADD_HANDLER(buttonbar->event_data, LeaveNotify, bbar_handle_leave_notify); + EVENT_DATA_ADD_HANDLER(buttonbar->event_data, ButtonPress, bbar_handle_button_press); + EVENT_DATA_ADD_HANDLER(buttonbar->event_data, ButtonRelease, bbar_handle_button_release); + EVENT_DATA_ADD_HANDLER(buttonbar->event_data, MotionNotify, bbar_handle_motion_notify); + + event_data_add_mywin(&buttonbar->event_data, buttonbar->win); +} + +unsigned char +bbar_handle_enter_notify(event_t * ev) +{ + button_t *b; + Window unused_root, unused_child; + int unused_root_x, unused_root_y; + unsigned int unused_mask; + + D_EVENTS(("bbar_handle_enter_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &buttonbar->event_data), 0); + + bbar_draw(buttonbar, IMAGE_STATE_SELECTED, 0); + XQueryPointer(Xdisplay, buttonbar->win, &unused_root, &unused_child, &unused_root_x, &unused_root_y, &(ev->xbutton.x), &(ev->xbutton.y), &unused_mask); + b = find_button_by_coords(buttonbar, ev->xbutton.x, ev->xbutton.y); + if (b) { + bbar_select_button(buttonbar, b); + } + return 1; +} + +unsigned char +bbar_handle_leave_notify(event_t * ev) +{ + D_EVENTS(("bbar_handle_leave_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &buttonbar->event_data), 0); + + bbar_draw(buttonbar, IMAGE_STATE_NORMAL, 0); + if (buttonbar->current) { + bbar_deselect_button(buttonbar, buttonbar->current); + } + return 1; +} + +unsigned char +bbar_handle_button_press(event_t * ev) +{ + + D_EVENTS(("bbar_handle_button_press(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &buttonbar->event_data), 0); + + if (buttonbar->current) { + bbar_click_button(buttonbar, buttonbar->current); + button_check_action(buttonbar, buttonbar->current, 1, ev->xbutton.time); + } + return 1; +} + +unsigned char +bbar_handle_button_release(event_t * ev) +{ + button_t *b; + Window unused_root, unused_child; + int unused_root_x, unused_root_y; + unsigned int unused_mask; + + D_EVENTS(("bbar_handle_button_release(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &buttonbar->event_data), 0); + + XQueryPointer(Xdisplay, buttonbar->win, &unused_root, &unused_child, &unused_root_x, &unused_root_y, &(ev->xbutton.x), &(ev->xbutton.y), &unused_mask); + + b = find_button_by_coords(buttonbar, ev->xbutton.x, ev->xbutton.y); + if (b) { + if (buttonbar->current && (b != buttonbar->current)) { + bbar_deselect_button(buttonbar, buttonbar->current); + } else { + bbar_select_button(buttonbar, b); + button_check_action(buttonbar, b, 0, ev->xbutton.time); + } + } + + return 1; +} + +unsigned char +bbar_handle_motion_notify(event_t * ev) +{ + button_t *b; + Window unused_root, unused_child; + int unused_root_x, unused_root_y; + unsigned int mask; + + D_EVENTS(("bbar_handle_motion_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &buttonbar->event_data), 0); + + while (XCheckTypedWindowEvent(Xdisplay, ev->xany.window, MotionNotify, ev)); + XQueryPointer(Xdisplay, buttonbar->win, &unused_root, &unused_child, &unused_root_x, &unused_root_y, &(ev->xbutton.x), &(ev->xbutton.y), &mask); + D_BBAR((" -> Pointer is at %d, %d with mask 0x%08x\n", ev->xbutton.x, ev->xbutton.y, mask)); + + b = find_button_by_coords(buttonbar, ev->xbutton.x, ev->xbutton.y); + if (b != buttonbar->current) { + if (buttonbar->current) { + bbar_deselect_button(buttonbar, buttonbar->current); + } + if (b) { + if (mask & (Button1Mask | Button2Mask | Button3Mask)) { + bbar_click_button(buttonbar, b); + } else { + bbar_select_button(buttonbar, b); + } + } + } + + return 1; +} + +unsigned char +bbar_dispatch_event(event_t * ev) +{ + if (buttonbar->event_data.handlers[ev->type] != NULL) { + return ((buttonbar->event_data.handlers[ev->type]) (ev)); + } + return (0); +} + +void +bbar_add(buttonbar_t *bbar) +{ + if (buttonbar) { + buttonbar_t *bb; + + for (bb = buttonbar; bb->next; bb = bb->next); + bb->next = bbar; + } else { + buttonbar = bbar; + } + bbar->next = NULL; + bbar_reset_total_height(); + bbar_calc_total_height(); +} + +unsigned short +bbar_calc_height(buttonbar_t *bbar) +{ + button_t *b; + ImlibBorder *bbord = images[image_bbar].norm->iml->border, *bord = images[image_button].norm->iml->border; + + D_BBAR(("bbar_calc_height(%8p): fascent == %d, fdescent == %d, h == %d\n", bbar, bbar->fascent, bbar->fdescent, bbar->h)); + + bbar->h = bbar->fascent + bbar->fdescent + 1; + if (bord) { + bbar->h += bord->top + bord->bottom; + } + for (b = bbar->buttons; b; b = b->next) { + if (b->h != bbar->h) { + b->h = bbar->h; + button_calc_size(bbar, b); + } + } + for (b = bbar->rbuttons; b; b = b->next) { + if (b->h != bbar->h) { + b->h = bbar->h; + button_calc_size(bbar, b); + } + } + if (bbord) { + bbar->h += bbord->top + bbord->bottom; + } + D_BBAR(("Final height is %d\n", bbar->h)); + return bbar->h; +} + +void +bbar_calc_sizes(buttonbar_t *bbar) +{ + button_t *b; + + D_BBAR(("bbar == %8p\n", bbar)); + + for (b = bbar->buttons; b; b = b->next) { + button_calc_size(bbar, b); + } + for (b = bbar->rbuttons; b; b = b->next) { + button_calc_size(bbar, b); + } +} + +void +bbar_calc_positions(buttonbar_t *bbar) +{ + button_t *b; + unsigned short x, y; + ImlibBorder *border = images[image_bbar].norm->iml->border; + + D_BBAR(("bbar == %8p\n", bbar)); + + y = ((border) ? (border->top) : 0); + if (bbar->buttons) { + x = ((border) ? (border->left) : 0) + MENU_HGAP; + for (b = bbar->buttons; b; b = b->next) { + b->x = x; + b->y = y; + D_BBAR(("Set button \"%s\" (%8p, width %d) to coordinates %d, %d\n", b->text, b, b->w, x, y)); + x += b->w + MENU_HGAP; + button_calc_rel_coords(bbar, b); + } + } + if (bbar->rbuttons) { + x = bbar->w - ((border) ? (border->right) : 0); + for (b = bbar->rbuttons; b; b = b->next) { + x -= b->w + MENU_HGAP; + b->x = x; + b->y = y; + button_calc_rel_coords(bbar, b); + D_BBAR(("Set button \"%s\" (%8p, width %d) to coordinates %d, %d\n", b->text, b, b->w, x, y)); + } + } +} + +void +button_calc_size(buttonbar_t *bbar, button_t *button) +{ + ImlibBorder *bord = images[image_button].norm->iml->border; + int ascent, descent, direction; + XCharStruct chars; + + D_BBAR(("button_calc_size(%8p, %8p): XTextExtents(%8p, %s, %d, ...)\n", bbar, button, bbar->font, button->text, button->len)); + + button->w = 0; + if (button->len) { + XTextExtents(bbar->font, button->text, button->len, &direction, &ascent, &descent, &chars); + LOWER_BOUND(bbar->fascent, chars.ascent); + LOWER_BOUND(bbar->fdescent, chars.descent); + button->w += chars.width; + } + if (bord) { + button->w += bord->left + bord->right; + } + if (button->h == 0) { + button->h = bbar->fascent + bbar->fdescent + 1; + if (bord) { + button->h += bord->top + bord->bottom; + } + } + if (button->icon) { + unsigned short b = 0; + + if (bord) { + b = button->h - bord->top - bord->bottom; + } + button->icon_w = button->icon->iml->im->rgb_width; + button->icon_h = button->icon->iml->im->rgb_height; + D_BBAR((" -> Initial icon dimensions are %hux%hu\n", button->icon_w, button->icon_h)); + if (button->icon_h > b) { + button->icon_w = (unsigned short) ((float) button->icon_w / button->icon_h * b); + button->icon_h = b; + } + button->w += button->icon_w; + if (button->len) { + button->w += MENU_HGAP; + } + D_BBAR((" -> Final icon dimensions are %hux%hu\n", button->icon_w, button->icon_h)); + } + D_BBAR((" -> Set button to %dx%d at %d, %d and icon to %dx%d\n", button->w, button->h, button->x, button->y, button->icon_w, button->icon_h)); +} + +void +button_calc_rel_coords(buttonbar_t *bbar, button_t *button) +{ + ImlibBorder *bord = images[image_button].norm->iml->border; + + D_BBAR(("bbar == %8p, button == %8p\n", bbar, button)); + + if (button->icon) { + unsigned short b = 0; + + if (bord) { + b = button->h - bord->top - bord->bottom - 2; + } + if (button->icon_h == button->h) { + button->icon_y = button->y + ((bord) ? (bord->top) : 0); + } else { + button->icon_y = button->y + ((b - button->icon_h) / 2) + ((bord) ? (bord->top) : 0); + } + button->icon_x = button->x + ((bord) ? (bord->left) : 0); + } + if (button->len) { + button->text_x = button->x + ((button->icon_w) ? (button->icon_w + MENU_HGAP) : 0) + ((bord) ? (bord->left) : (0)); + button->text_y = button->y + button->h - ((bord) ? (bord->bottom) : (0)) - bbar->fdescent; + } + D_BBAR((" -> Text is at %d, %d and icon is at %d, %d\n", button->text_x, button->text_y, button->icon_x, button->icon_y)); +} + +void +bbar_add_button(buttonbar_t *bbar, button_t *button) +{ + button_t *b; + + D_BBAR(("bbar_add_button(%8p, %8p): Adding button \"%s\".\n", bbar, button, button->text)); + + if (bbar->buttons) { + for (b = bbar->buttons; b->next; b = b->next); + b->next = button; + } else { + bbar->buttons = button; + } + button->next = NULL; +} + +void +bbar_add_rbutton(buttonbar_t *bbar, button_t *button) +{ + button_t *b; + + D_BBAR(("bbar_add_rbutton(%8p, %8p): Adding button \"%s\".\n", bbar, button, button->text)); + + b = ((bbar->rbuttons) ? (bbar->rbuttons) : NULL); + bbar->rbuttons = button; + button->next = b; +} + +unsigned char +bbar_set_font(buttonbar_t *bbar, const char *fontname) +{ + XFontStruct *font; + + ASSERT_RVAL(fontname != NULL, 0); + + D_BBAR(("bbar_set_font(%8p, \"%s\"): Current font is %8p, dimensions %d/%d/%d\n", bbar, fontname, bbar->font, bbar->fwidth, bbar->fheight, bbar->h)); + if (bbar->font) { + free_font(bbar->font); + } +#ifdef MULTI_CHARSET + if (bbar->fontset) { + XFreeFontSet(Xdisplay, bbar->fontset); + } +#endif + + font = (XFontStruct *) load_font(fontname, "fixed", FONT_TYPE_X); +#ifdef MULTI_CHARSET + bbar->fontset = create_fontset(fontname, etmfonts[def_font_idx]); +#endif + + bbar->font = font; + bbar->fwidth = font->max_bounds.width; + bbar->fheight = font->ascent + font->descent + rs_line_space; + XSetFont(Xdisplay, bbar->gc, font->fid); + bbar_reset_total_height(); + D_BBAR(("New dimensions are %d/%d/%d\n", bbar->fwidth, bbar->fheight, bbar->h)); + + return 1; +} + +button_t * +find_button_by_text(buttonbar_t *bbar, char *text) +{ + register button_t *b; + + REQUIRE_RVAL(text != NULL, NULL); + + for (b = bbar->buttons; b; b = b->next) { + if (!strcasecmp(b->text, text)) { + return (b); + } + } + for (b = bbar->rbuttons; b; b = b->next) { + if (!strcasecmp(b->text, text)) { + return (b); + } + } + return NULL; +} + +button_t * +find_button_by_coords(buttonbar_t *bbar, int x, int y) +{ + register button_t *b; + + ASSERT_RVAL(bbar != NULL, NULL); + + for (b = bbar->buttons; b; b = b->next) { + if ((x >= b->x) && (y >= b->y) && (x < b->x + b->w) && (y < b->y + b->h)) { + return (b); + } + } + for (b = bbar->rbuttons; b; b = b->next) { + if ((x >= b->x) && (y >= b->y) && (x < b->x + b->w) && (y < b->y + b->h)) { + return (b); + } + } + return NULL; +} + +button_t * +button_create(char *text) +{ + button_t *button; + + button = (button_t *) MALLOC(sizeof(button_t)); + MEMSET(button, 0, sizeof(button_t)); + + if (text) { + button->text = StrDup(text); + button->len = strlen(text); + } else { + button->text = ""; + button->len = 0; + } + return button; +} + +unsigned char +button_set_icon(button_t *button, simage_t * icon) +{ + ASSERT_RVAL(button != NULL, 0); + ASSERT_RVAL(icon != NULL, 0); + + button->icon = icon; + return 1; +} + +unsigned char +button_set_action(button_t *button, action_type_t type, char *action) +{ + ASSERT_RVAL(button != NULL, 0); + + button->type = type; + switch (type) { + case ACTION_MENU: + button->action.menu = find_menu_by_title(menu_list, action); + break; + case ACTION_STRING: + case ACTION_ECHO: + button->action.string = (char *) MALLOC(strlen(action) + 2); + strcpy(button->action.string, action); + parse_escaped_string(button->action.string); + break; + default: + break; + } + return 1; +} + +void +bbar_select_button(buttonbar_t *bbar, button_t *button) +{ + bbar->current = button; + if (image_mode_is(image_button, MODE_MASK)) { + paste_simage(images[image_button].selected, image_button, bbar->win, button->x, button->y, button->w, button->h); + } else { + draw_shadow_from_colors(bbar->win, PixColors[menuTopShadowColor], PixColors[menuBottomShadowColor], button->x, button->y, button->w, button->h, 2); + } + if (image_mode_is(image_button, MODE_AUTO)) { + enl_ipc_sync(); + } + if (button->icon) { + paste_simage(button->icon, image_max, bbar->win, button->icon_x, button->icon_y, button->icon_w, button->icon_h); + } + if (button->len) { + XSetForeground(Xdisplay, bbar->gc, images[image_bbar].selected->fg); + draw_string(bbar, bbar->win, bbar->gc, button->text_x, button->text_y, button->text, button->len); + XSetForeground(Xdisplay, bbar->gc, images[image_bbar].norm->fg); + } +} + +void +bbar_deselect_button(buttonbar_t *bbar, button_t *button) +{ + XClearArea(Xdisplay, bbar->win, button->x, button->y, button->w, button->h, False); + bbar->current = NULL; +} + +void +bbar_click_button(buttonbar_t *bbar, button_t *button) +{ + bbar->current = button; + if (image_mode_is(image_button, MODE_MASK)) { + paste_simage(images[image_button].clicked, image_button, bbar->win, button->x, button->y, button->w, button->h); + } else { + draw_shadow_from_colors(bbar->win, PixColors[menuBottomShadowColor], PixColors[menuTopShadowColor], button->x, button->y, button->w, button->h, 2); + } + if (image_mode_is(image_button, MODE_AUTO)) { + enl_ipc_sync(); + } + if (button->icon) { + paste_simage(button->icon, image_max, bbar->win, button->icon_x, button->icon_y, button->icon_w, button->icon_h); + } + if (button->len) { + XSetForeground(Xdisplay, bbar->gc, images[image_bbar].clicked->fg); + draw_string(bbar, bbar->win, bbar->gc, button->text_x, button->text_y, button->text, button->len); + XSetForeground(Xdisplay, bbar->gc, images[image_bbar].norm->fg); + } +} + +void +button_check_action(buttonbar_t *bbar, button_t *button, unsigned char press, Time t) +{ + switch (button->type) { + case ACTION_MENU: + if (press) { + menu_invoke(button->x, button->y + button->h, bbar->win, button->action.menu, t); + } + break; + case ACTION_STRING: + if (!press) { + cmd_write((unsigned char *) button->action.string, strlen(button->action.string)); + } + break; + case ACTION_ECHO: + if (!press) { + tt_write((unsigned char *) button->action.string, strlen(button->action.string)); + } + break; + default: + break; + } +} + +unsigned char +bbar_show(buttonbar_t *bbar, unsigned char visible) +{ + unsigned char changed = 0; + + D_BBAR(("bbar_show(%8p, %d) called.\n", bbar, visible)); + if (visible && !bbar_is_visible(bbar)) { + D_BBAR((" -> Making bbar visible.\n")); + XMapWindow(Xdisplay, bbar->win); + bbar_set_visible(bbar, 1); + changed = 1; + } else if (!visible && bbar_is_visible(bbar)) { + D_BBAR((" -> Making bbar invisible.\n")); + XUnmapWindow(Xdisplay, bbar->win); + bbar_set_visible(bbar, 0); + changed = 1; + } + return changed; +} + +void +bbar_resize(buttonbar_t *bbar, int w) +{ + D_BBAR(("bbar_resize(%8p, %d) called.\n", bbar, w)); + if (w == -1) { + bbar_calc_sizes(bbar); + bbar_calc_height(bbar); + bbar_reset_total_height(); + } else if (bbar->w != w) { + bbar->w = w; + bbar_calc_positions(bbar); + D_BBAR(("Resizing window 0x%08x to %dx%d\n", bbar->win, bbar->w, bbar->h)); + XResizeWindow(Xdisplay, bbar->win, bbar->w, bbar->h); + bbar_draw(bbar, IMAGE_STATE_CURRENT, MODE_MASK); + } +} + +void +bbar_resize_all(int width) +{ + buttonbar_t *bbar; + + for (bbar = buttonbar; bbar; bbar = bbar->next) { + bbar_resize(bbar, width); + } + bbar_calc_total_height(); +} + +void +bbar_draw(buttonbar_t *bbar, unsigned char image_state, unsigned char force_modes) +{ + button_t *button; + + ASSERT(bbar != NULL); + + D_BBAR(("bbar_draw(%8p, 0x%02x, 0x%02x) called.\n", bbar, image_state, force_modes)); + if (image_state != IMAGE_STATE_CURRENT) { + if ((image_state == IMAGE_STATE_NORMAL) && (images[image_bbar].current != images[image_bbar].norm)) { + images[image_bbar].current = images[image_bbar].norm; + force_modes = MODE_MASK; + } else if ((image_state == IMAGE_STATE_SELECTED) && (images[image_bbar].current != images[image_bbar].selected)) { + images[image_bbar].current = images[image_bbar].selected; + force_modes = MODE_MASK; + } else if ((image_state == IMAGE_STATE_CLICKED) && (images[image_bbar].current != images[image_bbar].clicked)) { + images[image_bbar].current = images[image_bbar].clicked; + force_modes = MODE_MASK; + } else if ((image_state == IMAGE_STATE_DISABLED) && (images[image_bbar].current != images[image_bbar].disabled)) { + images[image_bbar].current = images[image_bbar].disabled; + force_modes = MODE_MASK; + } + } + if (image_mode_is(image_bbar, MODE_MASK) && !((images[image_bbar].mode & MODE_MASK) & (force_modes))) { + return; + } else { + render_simage(images[image_bbar].current, bbar->win, bbar->w, bbar->h, image_bbar, RENDER_FORCE_PIXMAP); + bbar->bg = images[image_bbar].current->pmap->pixmap; + } + XSetForeground(Xdisplay, bbar->gc, images[image_bbar].current->fg); + for (button = bbar->buttons; button; button = button->next) { + if (button->icon) { + paste_simage(button->icon, image_max, bbar->bg, button->icon_x, button->icon_y, button->icon_w, button->icon_h); + } + if (button->len) { + draw_string(bbar, bbar->bg, bbar->gc, button->text_x, button->text_y, button->text, button->len); + } + } + for (button = bbar->rbuttons; button; button = button->next) { + if (button->icon) { + paste_simage(button->icon, image_max, bbar->bg, button->icon_x, button->icon_y, button->icon_w, button->icon_h); + } + if (button->len) { + draw_string(bbar, bbar->bg, bbar->gc, button->text_x, button->text_y, button->text, button->len); + } + } + XSetWindowBackgroundPixmap(Xdisplay, bbar->win, bbar->bg); + XClearWindow(Xdisplay, bbar->win); + XSetForeground(Xdisplay, bbar->gc, images[image_bbar].norm->fg); +} + +void +bbar_draw_all(unsigned char image_state, unsigned char force_modes) +{ + buttonbar_t *bbar; + + for (bbar = buttonbar; bbar; bbar = bbar->next) { + bbar_draw(bbar, image_state, force_modes); + } +} + +void +bbar_dock(buttonbar_t *bbar, unsigned char dock) +{ + D_BBAR(("bbar_dock(%8p, %d) called.\n", bbar, dock)); + bbar_set_docked(bbar, dock); + if (dock == BBAR_DOCKED_TOP) { + bbar->x = 0; + bbar->y = 0; + XReparentWindow(Xdisplay, bbar->win, TermWin.parent, bbar->x, bbar->y); + XMoveResizeWindow(Xdisplay, bbar->win, bbar->x, bbar->y, bbar->w, bbar->h); + } +} + +unsigned long +bbar_calc_total_height(void) +{ + buttonbar_t *bbar; + + bbar_total_h = 0; + for (bbar = buttonbar; bbar; bbar = bbar->next) { + if (bbar_is_docked(bbar)) { + bbar_total_h += bbar->h; + } + } + D_BBAR(("Returning %d\n", bbar_total_h)); + return bbar_total_h; +} diff --git a/src/buttons.h b/src/buttons.h new file mode 100644 index 0000000..868ead6 --- /dev/null +++ b/src/buttons.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 1997-2000, Michael Jennings + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies of the Software, its documentation and marketing & publicity + * materials, and acknowledgment shall be given in the documentation, materials + * and software packages that this Software was used. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _BUTTONS_H +# define _BUTTONS_H + +# include +# include "actions.h" +# include "events.h" +# include "menus.h" + +/************ Macros and Definitions ************/ +#define BBAR_DOCKED_TOP (1 << 0) +#define BBAR_DOCKED_BOTTOM (1 << 1) +#define BBAR_DOCKED (BBAR_DOCKED_TOP | BBAR_DOCKED_BOTTOM) +#define BBAR_VISIBLE (1 << 2) + +#define bbar_is_docked(bbar) (bbar->state & BBAR_DOCKED) +#define bbar_set_docked(bbar, d) do {bbar->state &= ~BBAR_DOCKED; bbar->state |= (d);} while (0) +#define bbar_is_visible(bbar) (bbar->state & BBAR_VISIBLE) +#define bbar_set_visible(bbar, v) ((v) ? (bbar->state |= BBAR_VISIBLE) : (bbar->state &= ~BBAR_VISIBLE)) +#define bbar_get_width(bbar) (bbar->w) +#define bbar_get_height(bbar) (bbar->h) +#ifdef __GNUC__ +# define bbar_total_height() __extension__ ({__typeof__(bbar_total_h) bth = (bbar_total_h != -1) ? (bbar_total_h) : (bbar_calc_total_height()); \ + D_BBAR(("bbar_total_height() returning %d\n", bth)); bth;}) +# define bbar_reset_total_height() __extension__ ({D_BBAR(("bbar_reset_total_height()\n")); bbar_total_h = -1; bbar_total_h;}) +#else +# define bbar_total_height() ((bbar_total_h != -1) ? (bbar_total_h) : (bbar_calc_total_height())) +# define bbar_reset_total_height() (bbar_total_h = -1) +#endif + +/************ Structures ************/ +typedef struct button_struct { + simage_t *icon; + action_type_t type; + union { + menu_t *menu; + char *string; + } action; + char *text; + unsigned short len; + unsigned short x, y, w, h; + unsigned short text_x, text_y; + unsigned short icon_x, icon_y, icon_w, icon_h; + struct button_struct *next; +} button_t; + +typedef struct buttonbar_struct { + Window win; + Pixmap bg; + unsigned short x, y, w, h; + GC gc; + unsigned char state; + XFontStruct *font; +#ifdef MULTI_CHARSET + XFontSet fontset; +#endif + unsigned short fwidth, fheight, fascent, fdescent; + event_dispatcher_data_t event_data; + button_t *buttons, *rbuttons, *current; + struct buttonbar_struct *next; +} buttonbar_t; + +/************ Variables ************/ +extern buttonbar_t *buttonbar; +extern long bbar_total_h; + +/************ Function Prototypes ************/ +_XFUNCPROTOBEGIN + +extern buttonbar_t *bbar_create(void); +extern void bbar_init(buttonbar_t *, int); +extern void bbar_event_init_dispatcher(void); +extern unsigned char bbar_handle_enter_notify(event_t *); +extern unsigned char bbar_handle_leave_notify(event_t *); +extern unsigned char bbar_handle_button_press(event_t *); +extern unsigned char bbar_handle_button_release(event_t *); +extern unsigned char bbar_handle_motion_notify(event_t *); +extern unsigned char bbar_dispatch_event(event_t *); +extern void bbar_add(buttonbar_t *bbar); +extern unsigned short bbar_calc_height(buttonbar_t *bbar); +extern void bbar_calc_sizes(buttonbar_t *bbar); +extern void bbar_calc_positions(buttonbar_t *bbar); +extern void button_calc_size(buttonbar_t *bbar, button_t *button); +extern void button_calc_rel_coords(buttonbar_t *bbar, button_t *button); +extern void bbar_add_button(buttonbar_t *bbar, button_t *button); +extern void bbar_add_rbutton(buttonbar_t *bbar, button_t *button); +extern unsigned char bbar_set_font(buttonbar_t *bbar, const char *fontname); +extern button_t *find_button_by_text(buttonbar_t *bbar, char *text); +extern button_t *find_button_by_coords(buttonbar_t *bbar, int x, int y); +extern button_t *button_create(char *text); +extern unsigned char button_set_icon(button_t *button, simage_t * icon); +extern unsigned char button_set_action(button_t *button, action_type_t type, char *action); +extern void bbar_select_button(buttonbar_t *bbar, button_t *button); +extern void bbar_deselect_button(buttonbar_t *bbar, button_t *button); +extern void bbar_click_button(buttonbar_t *bbar, button_t *button); +extern void button_check_action(buttonbar_t *bbar, button_t *button, unsigned char press, Time t); +extern unsigned char bbar_show(buttonbar_t *bbar, unsigned char visible); +extern void bbar_resize(buttonbar_t *bbar, int w); +extern void bbar_resize_all(int width); +extern void bbar_dock(buttonbar_t *bbar, unsigned char dock); +extern void bbar_draw(buttonbar_t *bbar, unsigned char image_state, unsigned char force_modes); +extern void bbar_draw_all(unsigned char image_state, unsigned char force_modes); +extern unsigned long bbar_calc_total_height(void); + +_XFUNCPROTOEND + +#endif /* _BUTTONS_H */ diff --git a/src/command.c b/src/command.c index bcdee90..65048d9 100644 --- a/src/command.c +++ b/src/command.c @@ -1064,7 +1064,7 @@ Exit_signal(int sig) privileges(REVERT); #endif - D_CMD(("Exit_signal(): exit(%s)\n", sig_to_str(sig))); + D_CMD(("exit(%s)\n", sig_to_str(sig))); exit(sig); SIG_RETURN(0); } @@ -1129,9 +1129,9 @@ clean_exit(void) */ #ifdef __sgi -inline int sgi_get_pty(void); +__inline__ int sgi_get_pty(void); -inline int +__inline__ int sgi_get_pty(void) { @@ -1144,9 +1144,9 @@ sgi_get_pty(void) #endif #ifdef HAVE_DEV_PTC -inline int aix_get_pty(void); +__inline__ int aix_get_pty(void); -inline int +__inline__ int aix_get_pty(void) { @@ -1161,9 +1161,9 @@ aix_get_pty(void) #endif #ifdef HAVE_SCO_PTYS -inline int sco_get_pty(void); +__inline__ int sco_get_pty(void); -inline int +__inline__ int sco_get_pty(void) { @@ -1195,9 +1195,9 @@ sco_get_pty(void) #endif #ifdef HAVE_DEV_PTMX -inline int svr_get_pty(void); +__inline__ int svr_get_pty(void); -inline int +__inline__ int svr_get_pty(void) { @@ -1228,9 +1228,9 @@ svr_get_pty(void) #define PTYCHAR1 "pqrstuvwxyz" #define PTYCHAR2 "0123456789abcdefghijklmnopqrstuvwxyz" -inline int gen_get_pty(void); +__inline__ int gen_get_pty(void); -inline int +__inline__ int gen_get_pty(void) { @@ -1297,7 +1297,6 @@ get_tty(void) int fd; pid_t pid; - D_TTY(("get_tty() called.\n")); /* * setsid() [or setpgrp] must be before open of the terminal, * otherwise there is no controlling terminal (Solaris 2.4, HP-UX 9) @@ -1367,7 +1366,7 @@ get_tty(void) { unsigned short i; - D_TTY(("get_tty() closing file descriptors 0-%d.\n", num_fds)); + D_TTY(("Closing file descriptors 0-%d.\n", num_fds)); for (i = 0; i < num_fds; i++) { if (i != fd) close(i); @@ -1423,7 +1422,7 @@ get_tty(void) privileges(REVERT); - D_TTY(("get_tty() done, fd is %d\n", fd)); + D_TTY(("Returning fd == %d\n", fd)); return (fd); } @@ -2083,7 +2082,7 @@ run_command(char *argv[]) /* need to trap SIGURG for SVR4 (Unixware) rlogin */ /* signal (SIGURG, SIG_DFL); */ - D_CMD(("run_command(): forking\n")); + D_CMD(("Forking\n")); cmd_pid = fork(); D_CMD(("After fork(), cmd_pid == %d\n", cmd_pid)); if (cmd_pid < 0) { @@ -2200,7 +2199,7 @@ run_command(char *argv[]) privileges(IGNORE); #endif - D_CMD(("run_command() returning\n")); + D_CMD(("Returning ptyfd == %d\n", ptyfd)); return (ptyfd); } @@ -2393,7 +2392,7 @@ cmd_getc(void) refresh_limit++; refresh_count = 0; refreshed = 1; - D_CMD(("cmd_getc(): scr_refresh() #1\n")); + D_CMD(("scr_refresh() #1\n")); #ifdef PROFILE P_CALL(scr_refresh(refresh_type), "cmd_getc()->scr_refresh()"); #else @@ -2490,7 +2489,7 @@ cmd_getc(void) refresh_limit = 1; if (!refreshed) { refreshed = 1; - D_CMD(("cmd_getc(): select() timed out, time to update the screen.\n")); + D_CMD(("select() timed out, time to update the screen.\n")); scr_refresh(refresh_type); if (scrollbar_is_visible()) { scrollbar_anchor_update_position(1); @@ -2501,8 +2500,6 @@ cmd_getc(void) } } } - - D_CMD(("cmd_getc() returning\n")); return (0); } @@ -2551,7 +2548,7 @@ main_loop(void) /* int ch; */ register int ch; - D_CMD(("[%d] main_loop() called\n", getpid())); + D_CMD(("PID %d\n", getpid())); #ifdef BACKGROUND_CYCLING_SUPPORT if (rs_anim_delay) { @@ -2597,26 +2594,26 @@ main_loop(void) case 005: break; # else - case 005: + case 005: /* ^E (ENQ) terminal status enquiry */ tt_printf(VT100_ANS); - break; /* terminal Status */ + break; # endif - case 007: + case 007: /* ^G (BEL) */ scr_bell(); - break; /* bell */ + break; case '\b': scr_backspace(); - break; /* backspace */ - case 013: - case 014: + break; + case 013: /* ^K (VT) */ + case 014: /* ^L (FF) */ scr_index(UP); - break; /* vertical tab, form feed */ - case 016: + break; + case 016: /* ^N (SO) shift out (enter ACS mode) */ scr_charset_choose(1); - break; /* shift out - acs */ - case 017: + break; + case 017: /* ^O (SI) shift in (leave ACS mode) */ scr_charset_choose(0); - break; /* shift in - acs */ + break; case 033: process_escape_seq(); break; @@ -2718,7 +2715,7 @@ v_writeBig(int f, char *d, int len) if (written < 0) { written = 0; } - D_TTY(("v_writeBig(): Wrote %d characters\n", written)); + D_TTY(("Wrote %d characters\n", written)); v_bufstr += written; if (v_bufstr >= v_bufptr) /* we wrote it all */ v_bufstr = v_bufptr = v_buffer; diff --git a/src/command.h b/src/command.h index e8a8ca5..d06adf5 100644 --- a/src/command.h +++ b/src/command.h @@ -226,11 +226,10 @@ if (test) PrivateModes |= (bit); else PrivateModes &= ~(bit);} while (0) #define CONSOLE "/dev/console" /* console device */ /* key-strings: if only these keys were standardized */ -#ifdef LINUX_KEYS -# define KS_HOME "\033[1~" /* Home == Find */ -# define KS_END "\033[4~" /* End == Select */ -#else +#ifndef KS_HOME # define KS_HOME "\033[7~" /* Home */ +#endif +#ifndef KS_END # define KS_END "\033[8~" /* End */ #endif #ifdef NO_DELETE_KEY diff --git a/src/debug.h b/src/debug.h index 9aa3e05..5962667 100644 --- a/src/debug.h +++ b/src/debug.h @@ -33,26 +33,41 @@ extern unsigned int debug_level; # define NOP ((void)0) #if defined(__FILE__) && defined(__LINE__) -# ifdef __FUNCTION__ -# define __DEBUG() fprintf(stderr, "[%lu] %12s | %4d | %30s: ", (unsigned long) time(NULL), __FILE__, __LINE__, __FUNCTION__) +# ifdef __GNUC__ +# define __DEBUG() fprintf(stderr, "[%lu] %12s | %4d: %s(): ", (unsigned long) time(NULL), __FILE__, __LINE__, __FUNCTION__) # else # define __DEBUG() fprintf(stderr, "[%lu] %12s | %4d: ", (unsigned long) time(NULL), __FILE__, __LINE__) # endif #endif #if defined(__FILE__) && defined(__LINE__) -# define ASSERT(x) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \ - else {print_warning("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);}}} while (0) -# define ASSERT_RVAL(x, val) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \ - else {print_warning("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \ - return (val);}} while (0) -# define ASSERT_NOTREACHED() do {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \ - else {print_warning("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \ - } while (0) -# define ASSERT_NOTREACHED_RVAL(val) do {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \ - else {print_warning("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \ - return (val);} while (0) -# define ABORT() fatal_error("Aborting at %s:%d.", __FILE__, __LINE__) +# ifdef __GNUC__ +# define ASSERT(x) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed in %s() at %s:%d: %s", __FUNCTION__, __FILE__, __LINE__, #x);} \ + else {print_warning("ASSERT failed in %s() at %s:%d: %s", __FUNCTION__, __FILE__, __LINE__, #x);}}} while (0) +# define ASSERT_RVAL(x, val) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed in %s() at %s:%d: %s", __FUNCTION__, __FILE__, __LINE__, #x);} \ + else {print_warning("ASSERT failed in %s() at %s:%d: %s", __FUNCTION__, __FILE__, __LINE__, #x);} \ + return (val);}} while (0) +# define ASSERT_NOTREACHED() do {if (debug_level>=1) {fatal_error("ASSERT failed in %s() at %s:%d: This code should not be reached.", __FUNCTION__, __FILE__, __LINE__);} \ + else {print_warning("ASSERT failed in %s() at %s:%d: This code should not be reached.", __FUNCTION__, __FILE__, __LINE__);} \ + } while (0) +# define ASSERT_NOTREACHED_RVAL(val) do {if (debug_level>=1) {fatal_error("ASSERT failed in %s() at %s:%d: This code should not be reached.", __FUNCTION__, __FILE__, __LINE__);} \ + else {print_warning("ASSERT failed in %s() at %s:%d: This code should not be reached.", __FUNCTION__, __FILE__, __LINE__);} \ + return (val);} while (0) +# define ABORT() fatal_error("Aborting in %s() at %s:%d.", __FUNCTION__, __FILE__, __LINE__) +# else +# define ASSERT(x) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \ + else {print_warning("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);}}} while (0) +# define ASSERT_RVAL(x, val) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \ + else {print_warning("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \ + return (val);}} while (0) +# define ASSERT_NOTREACHED() do {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \ + else {print_warning("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \ + } while (0) +# define ASSERT_NOTREACHED_RVAL(val) do {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \ + else {print_warning("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \ + return (val);} while (0) +# define ABORT() fatal_error("Aborting at %s:%d.", __FILE__, __LINE__) +# endif #else # define ASSERT(x) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed: %s", #x);} \ else {print_warning("ASSERT failed: %s", #x);}}} while (0) @@ -124,6 +139,8 @@ extern unsigned int debug_level; # define D_ENL(x) DPRINTF2(x) # define DEBUG_SCROLLBAR 2 # define D_SCROLLBAR(x) DPRINTF2(x) +# define DEBUG_BBAR 2 +# define D_BBAR(x) DPRINTF2(x) # define DEBUG_TIMER 2 # define D_TIMER(x) DPRINTF2(x) diff --git a/src/e.c b/src/e.c index f13d90e..3604290 100644 --- a/src/e.c +++ b/src/e.c @@ -78,7 +78,7 @@ enl_ipc_get_win(void) int dummy_int; unsigned int dummy_uint; - D_ENL(("enl_ipc_get_win(): Searching for IPC window.\n")); + D_ENL(("Searching for IPC window.\n")); prop = XInternAtom(Xdisplay, "ENLIGHTENMENT_COMMS", True); if (prop == None) { @@ -135,25 +135,25 @@ enl_ipc_send(char *str) if (str == NULL) { ASSERT(last_msg != NULL); str = last_msg; - D_ENL(("enl_ipc_send(): Resending last message \"%s\" to Enlightenment.\n", str)); + D_ENL(("Resending last message \"%s\" to Enlightenment.\n", str)); } else { if (last_msg != NULL) { FREE(last_msg); } last_msg = StrDup(str); - D_ENL(("enl_ipc_send(): Sending \"%s\" to Enlightenment.\n", str)); + D_ENL(("Sending \"%s\" to Enlightenment.\n", str)); } if (ipc_win == None) { if ((ipc_win = enl_ipc_get_win()) == None) { - D_ENL(("enl_ipc_send(): ...or perhaps not, since Enlightenment doesn't seem to be running. No IPC window, no IPC. Sorry....\n")); + D_ENL(("...or perhaps not, since Enlightenment doesn't seem to be running. No IPC window, no IPC. Sorry....\n")); return; } } len = strlen(str); ipc_atom = XInternAtom(Xdisplay, "ENL_MSG", False); if (ipc_atom == None) { - D_ENL(("enl_ipc_send(): IPC error: Unable to find/create ENL_MSG atom.\n")); + D_ENL(("IPC error: Unable to find/create ENL_MSG atom.\n")); return; } for (; XCheckTypedWindowEvent(Xdisplay, my_ipc_win, ClientMessage, &ev);); /* Discard any out-of-sync messages */ @@ -178,7 +178,7 @@ enl_ipc_send(char *str) } XSendEvent(Xdisplay, ipc_win, False, 0, (XEvent *) & ev); } - D_ENL(("enl_ipc_send(): Message sent to IPC window 0x%08x.\n", ipc_win)); + D_ENL(("Message sent to IPC window 0x%08x.\n", ipc_win)); } static RETSIGTYPE @@ -239,7 +239,7 @@ enl_ipc_get(const char *msg_data) if (blen < 12) { ret_msg = message; message = NULL; - D_ENL(("enl_ipc_get(): Received complete reply: \"%s\"\n", ret_msg)); + D_ENL(("Received complete reply: \"%s\"\n", ret_msg)); } return (ret_msg); } @@ -264,7 +264,7 @@ enl_send_and_wait(char *msg) for (; !(reply = enl_ipc_get(enl_wait_for_reply()));); if (reply == IPC_TIMEOUT) { /* We timed out. The IPC window must be AWOL. Reset and resend message. */ - D_ENL(("enl_wait_for_reply(): IPC timed out. IPC window 0x%08x has gone AWOL. Clearing ipc_win.\n", ipc_win)); + D_ENL(("IPC timed out. IPC window 0x%08x has gone AWOL. Clearing ipc_win.\n", ipc_win)); XSelectInput(Xdisplay, ipc_win, None); ipc_win = None; check_image_ipc(1); diff --git a/src/events.c b/src/events.c index c689811..6cc6620 100644 --- a/src/events.c +++ b/src/events.c @@ -38,6 +38,7 @@ static const char cvs_ident[] = "$Id$"; #include "mem.h" #include "strings.h" #include "actions.h" +#include "buttons.h" #include "command.h" #include "e.h" #include "events.h" @@ -141,6 +142,8 @@ event_init_primary_dispatcher(void) EVENT_DATA_ADD_HANDLER(primary_data, ClientMessage, handle_client_message); EVENT_DATA_ADD_HANDLER(primary_data, MappingNotify, handle_mapping_notify); EVENT_DATA_ADD_HANDLER(primary_data, VisibilityNotify, handle_visibility_notify); + EVENT_DATA_ADD_HANDLER(primary_data, EnterNotify, handle_enter_notify); + EVENT_DATA_ADD_HANDLER(primary_data, LeaveNotify, handle_leave_notify); EVENT_DATA_ADD_HANDLER(primary_data, FocusIn, handle_focus_in); EVENT_DATA_ADD_HANDLER(primary_data, FocusOut, handle_focus_out); EVENT_DATA_ADD_HANDLER(primary_data, ConfigureNotify, handle_configure_notify); @@ -155,12 +158,6 @@ event_init_primary_dispatcher(void) event_data_add_mywin(&primary_data, TermWin.parent); event_data_add_mywin(&primary_data, TermWin.vt); -#if 0 - event_data_add_mywin(&primary_data, scrollbar_get_win()); - event_data_add_mywin(&primary_data, scrollbar_get_uparrow_win()); - event_data_add_mywin(&primary_data, scrollbar_get_downarrow_win()); - event_data_add_mywin(&primary_data, scrollbar_get_anchor_win()); -#endif if (desktop_window != None) { event_data_add_parent(&primary_data, desktop_window); @@ -233,7 +230,7 @@ handle_property_notify(event_t * ev) if (background_is_trans()) { if ((ev->xany.window == TermWin.parent) || (ev->xany.window == Xroot)) { prop = XInternAtom(Xdisplay, "_WIN_WORKSPACE", True); - D_EVENTS(("handle_property_notify(): On %s. prop (_WIN_WORKSPACE) == 0x%08x, ev->xproperty.atom == 0x%08x\n", ((ev->xany.window == Xroot) ? "the root window" : "TermWin.parent"), + D_EVENTS(("On %s. prop (_WIN_WORKSPACE) == 0x%08x, ev->xproperty.atom == 0x%08x\n", ((ev->xany.window == Xroot) ? "the root window" : "TermWin.parent"), (int) prop, (int) ev->xproperty.atom)); if (ev->xproperty.atom == prop) { win = get_desktop_window(); @@ -258,7 +255,7 @@ handle_property_notify(event_t * ev) } if (ev->xany.window == desktop_window) { prop = XInternAtom(Xdisplay, "_XROOTPMAP_ID", True); - D_EVENTS(("handle_property_notify(): On desktop_window [0x%08x]. prop (_XROOTPMAP_ID) == 0x%08x, ev->xproperty.atom == 0x%08x\n", (int) desktop_window, (int) prop, (int) ev->xproperty.atom)); + D_EVENTS(("On desktop_window [0x%08x]. prop (_XROOTPMAP_ID) == 0x%08x, ev->xproperty.atom == 0x%08x\n", (int) desktop_window, (int) prop, (int) ev->xproperty.atom)); if (ev->xproperty.atom == prop) { pmap = get_desktop_pixmap(); if (pmap == (Pixmap) 1) { @@ -272,7 +269,7 @@ handle_property_notify(event_t * ev) } if ((ev->xany.window == Xroot) && (image_mode_any(MODE_AUTO))) { prop = XInternAtom(Xdisplay, "ENLIGHTENMENT_COMMS", True); - D_EVENTS(("handle_property_notify(): On the root window. prop (ENLIGHTENMENT_COMMS) == 0x%08x, ev->xproperty.atom == 0x%08x\n", (int) prop, (int) ev->xproperty.atom)); + D_EVENTS(("On the root window. prop (ENLIGHTENMENT_COMMS) == 0x%08x, ev->xproperty.atom == 0x%08x\n", (int) prop, (int) ev->xproperty.atom)); if ((prop != None) && (ev->xproperty.atom == prop)) { if ((enl_ipc_get_win()) != None) { redraw_images_by_mode(MODE_AUTO); @@ -315,7 +312,7 @@ handle_client_message(event_t * ev) buff[i] = ev->xclient.data.b[i + 8]; } buff[12] = 0; - D_ENL(("handle_client_message(): Discarding unexpected Enlightenment IPC message: \"%s\"\n", buff)); + D_ENL(("Discarding unexpected Enlightenment IPC message: \"%s\"\n", buff)); return 1; } #ifdef OFFIX_DND @@ -358,21 +355,57 @@ handle_visibility_notify(event_t * ev) REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); switch (ev->xvisibility.state) { case VisibilityUnobscured: - D_X11(("handle_visibility_notify(): Window completely visible\n")); + D_X11(("Window completely visible. Using FAST_REFRESH.\n")); refresh_type = FAST_REFRESH; break; case VisibilityPartiallyObscured: - D_X11(("handle_visibility_notify(): Window partially hidden\n")); + D_X11(("Window partially hidden. Using SLOW_REFRESH.\n")); refresh_type = SLOW_REFRESH; break; default: - D_X11(("handle_visibility_notify(): Window completely hidden\n")); + D_X11(("Window completely hidden. Using NO_REFRESH.\n")); refresh_type = NO_REFRESH; break; } return 1; } +unsigned char +handle_enter_notify(event_t * ev) +{ + + D_EVENTS(("handle_enter_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + + if (ev->xany.window == TermWin.vt) { + if (images[image_bg].norm != images[image_bg].selected) { + images[image_bg].current = images[image_bg].selected; + redraw_image(image_bg); + } + return 1; + } + return 0; +} + +unsigned char +handle_leave_notify(event_t * ev) +{ + + D_EVENTS(("handle_leave_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + + if (ev->xany.window == TermWin.vt) { + if (images[image_bg].norm != images[image_bg].selected) { + images[image_bg].current = images[image_bg].norm; + redraw_image(image_bg); + } + return 1; + } + return 0; +} + unsigned char handle_focus_in(event_t * ev) { @@ -380,18 +413,32 @@ handle_focus_in(event_t * ev) D_EVENTS(("handle_focus_in(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + if (!TermWin.focus) { + Window unused_root, child; + int unused_root_x, unused_root_y; + unsigned int unused_mask; + TermWin.focus = 1; - if (images[image_bg].norm != images[image_bg].selected) { - images[image_bg].current = images[image_bg].selected; - redraw_image(image_bg); + XQueryPointer(Xdisplay, TermWin.parent, &unused_root, &child, &unused_root_x, &unused_root_y, &(ev->xbutton.x), &(ev->xbutton.y), &unused_mask); + if (child == TermWin.vt) { + if (images[image_bg].current != images[image_bg].selected) { + images[image_bg].current = images[image_bg].selected; + redraw_image(image_bg); + } + } else { + if (images[image_bg].current != images[image_bg].norm) { + images[image_bg].current = images[image_bg].norm; + redraw_image(image_bg); + } } if (Options & Opt_scrollbar_popup) { map_scrollbar(Options & Opt_scrollbar); } else { scrollbar_set_focus(TermWin.focus); - scrollbar_draw(MODE_SOLID); + scrollbar_draw(IMAGE_STATE_NORMAL, MODE_SOLID); } + bbar_draw_all(IMAGE_STATE_NORMAL, MODE_SOLID); #ifdef USE_XIM if (xim_input_context != NULL) XSetICFocus(xim_input_context); @@ -409,16 +456,17 @@ handle_focus_out(event_t * ev) REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); if (TermWin.focus) { TermWin.focus = 0; - if (images[image_bg].norm != images[image_bg].selected) { - images[image_bg].current = images[image_bg].norm; + if (images[image_bg].current != images[image_bg].disabled) { + images[image_bg].current = images[image_bg].disabled; redraw_image(image_bg); } if (Options & Opt_scrollbar_popup) { map_scrollbar(0); } else { scrollbar_set_focus(TermWin.focus); - scrollbar_draw(MODE_SOLID); + scrollbar_draw(IMAGE_STATE_DISABLED, MODE_SOLID); } + bbar_draw_all(IMAGE_STATE_DISABLED, MODE_SOLID); #ifdef USE_XIM if (xim_input_context != NULL) XUnsetICFocus(xim_input_context); diff --git a/src/events.h b/src/events.h index f1f613f..9669a3d 100644 --- a/src/events.h +++ b/src/events.h @@ -103,6 +103,8 @@ extern unsigned char handle_client_message(event_t *); extern unsigned char handle_mapping_notify(event_t *); extern unsigned char handle_leave_notify(event_t *); extern unsigned char handle_visibility_notify(event_t *); +extern unsigned char handle_enter_notify(event_t *); +extern unsigned char handle_leave_notify(event_t *); extern unsigned char handle_focus_in(event_t *); extern unsigned char handle_focus_out(event_t *); extern unsigned char handle_configure_notify(event_t *); diff --git a/src/feature.h b/src/feature.h index 6873e69..3f6780f 100644 --- a/src/feature.h +++ b/src/feature.h @@ -118,7 +118,7 @@ /* This will force clearing of characters before writing new ones on top of * them. This is experimental - added in order to try and fix pixel dropping * problems some people have had. See also NO_BOLDOVERSTRIKE. */ -# define FORCE_CLEAR_CHARS +/*# define FORCE_CLEAR_CHARS*/ /* The command through which to pipe print-screen requests */ #define PRINTPIPE "lp" diff --git a/src/font.c b/src/font.c index 2d0748e..18f70da 100644 --- a/src/font.c +++ b/src/font.c @@ -222,7 +222,7 @@ font_cache_find(const char *name, unsigned char type) { return (current); } } - D_FONT(("font_cache_find(): No matches found. =(\n")); + D_FONT(("No matches found. =(\n")); return ((cachefont_t *) NULL); } @@ -247,7 +247,7 @@ font_cache_find_info(const char *name, unsigned char type) { } } } - D_FONT(("font_cache_find_info(): No matches found. =(\n")); + D_FONT(("No matches found. =(\n")); return (NULL); } @@ -327,8 +327,6 @@ change_font(int init, const char *fontname) #endif short idx = 0, old_idx = font_idx; int fh, fw = 0; - register unsigned long i; - register int cw; D_FONT(("change_font(%d, \"%s\"): def_font_idx == %u, font_idx == %u\n", init, NONULL(fontname), (unsigned int) def_font_idx, (unsigned int) font_idx)); @@ -436,11 +434,8 @@ change_font(int init, const char *fontname) TermWin.fprop = 0; /* Mono-spaced (fixed width) font */ else TermWin.fprop = 1; /* Proportional font */ - if (TermWin.fprop == 1 && TermWin.font->per_char) - for (i = TermWin.font->min_char_or_byte2; i <= TermWin.font->max_char_or_byte2; i++) { - cw = TermWin.font->per_char[i].width; - MAX_IT(fw, cw); - } + LOWER_BOUND(fw, TermWin.font->max_bounds.width); + /* not the first time thru and sizes haven't changed */ if (fw == TermWin.fwidth && fh == TermWin.fheight) return; /* TODO: not return; check MULTI_CHARSET if needed */ @@ -459,14 +454,7 @@ change_font(int init, const char *fontname) if (fw != boldFont->max_bounds.width) fw = -1; } else { - if (boldFont->per_char) { - for (i = 0; i < 256; i++) { - if (!isprint(i)) - continue; - cw = boldFont->per_char[i].width; - MAX_IT(fw, cw); - } - } + LOWER_BOUND(fw, boldFont->max_bounds.width); } if (fw == TermWin.fwidth && fh == TermWin.fheight) { diff --git a/src/menus.c b/src/menus.c index 97a95d0..756cb72 100644 --- a/src/menus.c +++ b/src/menus.c @@ -45,24 +45,25 @@ static const char cvs_ident[] = "$Id$"; #include "term.h" #include "windows.h" -event_dispatcher_data_t menu_event_data; menulist_t *menu_list = NULL; +static event_dispatcher_data_t menu_event_data; static GC topShadowGC, botShadowGC; static Time button_press_time; +static int button_press_x = 0, button_press_y = 0; static menu_t *current_menu; -static inline void grab_pointer(Window win); -static inline void ungrab_pointer(void); -static inline void draw_string(Drawable d, GC gc, int x, int y, char *str, size_t len); -static inline unsigned short center_coords(register unsigned short c1, register unsigned short c2); +static __inline__ void grab_pointer(Window win); +static __inline__ void ungrab_pointer(void); +static __inline__ void draw_string(Drawable d, GC gc, int x, int y, char *str, size_t len); +static __inline__ unsigned short center_coords(register unsigned short c1, register unsigned short c2); -static inline void +static __inline__ void grab_pointer(Window win) { int success; - D_EVENTS(("grab_pointer(): Grabbing control of pointer for window 0x%08x.\n", win)); + D_EVENTS(("Grabbing control of pointer for window 0x%08x.\n", win)); success = XGrabPointer(Xdisplay, win, False, EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | Button2MotionMask | Button3MotionMask, @@ -87,19 +88,19 @@ grab_pointer(Window win) } } -static inline void +static __inline__ void ungrab_pointer(void) { - D_EVENTS(("ungrab_pointer(): Releasing pointer grab.\n")); + D_EVENTS(("Releasing pointer grab.\n")); XUngrabPointer(Xdisplay, CurrentTime); } -static inline void +static __inline__ void draw_string(Drawable d, GC gc, int x, int y, char *str, size_t len) { - D_MENU(("draw_string(): Writing string \"%s\" (length %lu) onto drawable 0x%08x at %d, %d\n", str, len, d, x, y)); + D_MENU(("Writing string \"%s\" (length %lu) onto drawable 0x%08x at %d, %d\n", str, len, d, x, y)); #ifdef MULTI_CHARSET if (current_menu && current_menu->fontset) @@ -109,7 +110,7 @@ draw_string(Drawable d, GC gc, int x, int y, char *str, size_t len) XDrawString(Xdisplay, d, gc, x, y, str, len); } -static inline unsigned short +static __inline__ unsigned short center_coords(register unsigned short c1, register unsigned short c2) { @@ -138,8 +139,6 @@ menu_event_init_dispatcher(void) { register unsigned char i; - MEMSET(&menu_event_data, 0, sizeof(event_dispatcher_data_t)); - EVENT_DATA_ADD_HANDLER(menu_event_data, EnterNotify, menu_handle_enter_notify); EVENT_DATA_ADD_HANDLER(menu_event_data, LeaveNotify, menu_handle_leave_notify); #if 0 @@ -247,8 +246,29 @@ menu_handle_button_press(event_t * ev) D_EVENTS(("ButtonPress at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); - button_press_time = ev->xbutton.time; + if (!current_menu || (ev->xbutton.x < 0) || (ev->xbutton.y < 0) || (ev->xbutton.x >= current_menu->w) || (ev->xbutton.y >= current_menu->h)) { + Window unused_win, child_win; + /* Click outside the current menu, or there is no current menu. Reset. */ + ungrab_pointer(); + menu_reset_all(menu_list); + current_menu = NULL; + XTranslateCoordinates(Xdisplay, ev->xany.window, Xroot, ev->xbutton.x, ev->xbutton.y, &(ev->xbutton.x), &(ev->xbutton.y), &unused_win); + child_win = find_window_by_coords(Xroot, 0, 0, ev->xbutton.x, ev->xbutton.y); + if (child_win != None) { + XTranslateCoordinates(Xdisplay, Xroot, child_win, ev->xbutton.x, ev->xbutton.y, &(ev->xbutton.x), &(ev->xbutton.y), &unused_win); + ev->xany.window = child_win; + D_EVENTS(("Sending synthetic event on to window 0x%08x at %d, %d\n", child_win, ev->xbutton.x, ev->xbutton.y)); + XSendEvent(Xdisplay, child_win, False, 0, ev); + } + } else { + button_press_time = ev->xbutton.time; + button_press_x = ev->xbutton.x; + button_press_y = ev->xbutton.y; + if (current_menu && (current_menu->state & MENU_STATE_IS_DRAGGING)) { + current_menu->state &= ~MENU_STATE_IS_DRAGGING; + } + } return 1; } @@ -266,30 +286,30 @@ menu_handle_button_release(event_t * ev) if (current_menu && (current_menu->state & MENU_STATE_IS_DRAGGING)) { /* Dragging-and-release mode */ - D_MENU(("Drag-and-release mode, detected release.\n")); + D_MENU(("Drag-and-release mode, detected release. Button press time is %lu, release time is %lu\n", button_press_time, ev->xbutton.time)); ungrab_pointer(); if (button_press_time && (ev->xbutton.time - button_press_time > MENU_CLICK_TIME)) { /* Take action here based on the current menu item */ - if (current_menu) { - if ((item = menuitem_get_current(current_menu)) != NULL) { - if (item->type == MENUITEM_SUBMENU) { - menu_display_submenu(current_menu, item); - } else { - menu_action(item); - menuitem_deselect(current_menu); - } + if ((item = menuitem_get_current(current_menu)) != NULL) { + if (item->type == MENUITEM_SUBMENU) { + menu_display_submenu(current_menu, item); + } else { + menu_action(item); + menuitem_deselect(current_menu); } } + /* Reset the state of the menu system. */ + menu_reset_all(menu_list); + current_menu = NULL; + } else { + current_menu->state &= ~MENU_STATE_IS_DRAGGING; /* Click, brief drag, release == single click */ } - /* Reset the state of the menu system. */ - menu_reset_all(menu_list); - current_menu = NULL; } else { /* Single-click mode */ - D_MENU(("Single click mode, detected click.\n")); + D_MENU(("Single click mode, detected click. Button press time is %lu, release time is %lu\n", button_press_time, ev->xbutton.time)); if ((ev->xbutton.x >= 0) && (ev->xbutton.y >= 0) && (ev->xbutton.x < current_menu->w) && (ev->xbutton.y < current_menu->h)) { /* Click inside the menu window. Activate the current item. */ if (current_menu) { @@ -303,7 +323,8 @@ menu_handle_button_release(event_t * ev) } } } - } else { + } else if (!(button_press_time && (ev->xbutton.time - button_press_time < MENU_CLICK_TIME)) || (button_press_x && button_press_y)) { + /* Single click which lasted too long, or the second click occured outside the menu */ ungrab_pointer(); /* Reset the state of the menu system. */ menu_reset_all(menu_list); @@ -311,6 +332,7 @@ menu_handle_button_release(event_t * ev) } } button_press_time = 0; + button_press_x = button_press_y = 0; return 1; } @@ -330,11 +352,12 @@ menu_handle_motion_notify(event_t * ev) return 1; } - if (button_press_time) { - current_menu->state |= MENU_STATE_IS_DRAGGING; - } + D_MENU(("Mouse is in motion. Button press time is %lu, motion time is %lu\n", button_press_time, ev->xbutton.time)); if ((ev->xbutton.x >= 0) && (ev->xbutton.y >= 0) && (ev->xbutton.x < current_menu->w) && (ev->xbutton.y < current_menu->h)) { /* Motion within the current menu */ + if (button_press_time) { + current_menu->state |= MENU_STATE_IS_DRAGGING; + } item = find_item_by_coords(current_menu, ev->xbutton.x, ev->xbutton.y); menuitem_change_current(item); } else { @@ -355,6 +378,7 @@ menu_handle_motion_notify(event_t * ev) menu_reset_tree(current_menu); } current_menu = menu; + current_menu->state |= MENU_STATE_IS_DRAGGING; XTranslateCoordinates(Xdisplay, ev->xany.window, child, ev->xbutton.x, ev->xbutton.y, &dest_x, &dest_y, &child); item = find_item_by_coords(menu, dest_x, dest_y); if (!item || item != menuitem_get_current(current_menu)) { @@ -404,8 +428,6 @@ menu_create(char *title) static XGCValues gcvalue; static XSetWindowAttributes xattr; - ASSERT_RVAL(title != NULL, NULL); - if (!mask) { xattr.border_pixel = BlackPixel(Xdisplay, Xscreen); xattr.save_under = TRUE; @@ -414,13 +436,12 @@ menu_create(char *title) xattr.colormap = cmap; cursor = XCreateFontCursor(Xdisplay, XC_left_ptr); - mask = EnterNotify | LeaveNotify | PointerMotionMask | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask - | Button1MotionMask | Button2MotionMask | Button3MotionMask; - gcvalue.foreground = PixColors[menuTextColor]; + mask = PointerMotionMask | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | Button2MotionMask | Button3MotionMask; + gcvalue.foreground = images[image_menu].norm->fg; } menu = (menu_t *) MALLOC(sizeof(menu_t)); MEMSET(menu, 0, sizeof(menu_t)); - menu->title = StrDup(title); + menu->title = StrDup(title ? title : ""); menu->win = XCreateWindow(Xdisplay, Xroot, 0, 0, 1, 1, 0, Xdepth, InputOutput, CopyFromParent, CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWBorderPixel | CWColormap, &xattr); @@ -437,6 +458,18 @@ menu_create(char *title) return menu; } +unsigned char +menu_set_title(menu_t *menu, const char *title) +{ + ASSERT_RVAL(menu != NULL, 0); + REQUIRE_RVAL(title != NULL, 0); + + FREE(menu->title); + menu->title = StrDup(title); + XStoreName(Xdisplay, menu->win, menu->title); + return 1; +} + unsigned char menu_set_font(menu_t * menu, const char *fontname) { @@ -445,7 +478,7 @@ menu_set_font(menu_t * menu, const char *fontname) XGCValues gcvalue; ASSERT_RVAL(menu != NULL, 0); - ASSERT_RVAL(fontname != NULL, 0); + REQUIRE_RVAL(fontname != NULL, 0); font = (XFontStruct *) load_font(fontname, "fixed", FONT_TYPE_X); #ifdef MULTI_CHARSET @@ -582,7 +615,7 @@ menuitem_change_current(menuitem_t *item) current = menuitem_get_current(current_menu); if (current != item) { - D_MENU(("menuitem_change_current(): Changing current item in menu \"%s\" from \"%s\" to \"%s\"\n", current_menu->title, (current ? current->text : "(NULL)"), (item ? item->text : "(NULL)"))); + D_MENU(("Changing current item in menu \"%s\" from \"%s\" to \"%s\"\n", current_menu->title, (current ? current->text : "(NULL)"), (item ? item->text : "(NULL)"))); if (current) { /* Reset the current item */ menuitem_deselect(current_menu); @@ -608,7 +641,7 @@ menuitem_change_current(menuitem_t *item) menuitem_clear_current(current_menu); } } else { - D_MENU(("menuitem_change_current(): Current item in menu \"%s\" does not require changing.\n", current_menu->title)); + D_MENU(("Current item in menu \"%s\" does not require changing.\n", current_menu->title)); } } @@ -629,7 +662,21 @@ menuitem_create(char *text) } unsigned char -menuitem_set_icon(menuitem_t * item, image_t * icon) +menuitem_set_text(menuitem_t * item, const char *text) +{ + ASSERT_RVAL(item != NULL, 0); + REQUIRE_RVAL(text != NULL, 0); + + if (item->text) { + FREE(item->text); + } + item->text = StrDup(text); + item->len = strlen(text); + return 1; +} + +unsigned char +menuitem_set_icon(menuitem_t * item, simage_t * icon) { ASSERT_RVAL(item != NULL, 0); @@ -680,7 +727,7 @@ menu_reset(menu_t * menu) ASSERT(menu != NULL); - D_MENU(("menu_reset() called for menu \"%s\" (window 0x%08x)\n", menu->title, menu->win)); + D_MENU(("menu_reset(menu %8p \"%s\"), window 0x%08x\n", menu, menu->title, menu->win)); if (!(menu->state & MENU_STATE_IS_MAPPED)) { return; } @@ -693,7 +740,6 @@ menu_reset(menu_t * menu) void menu_reset_all(menulist_t * list) { - register unsigned short i; ASSERT(list != NULL); @@ -701,7 +747,7 @@ menu_reset_all(menulist_t * list) if (list->nummenus == 0) return; - D_MENU(("menu_reset_all() called\n")); + D_MENU(("menu_reset_all(%8p) called\n", list)); if (menuitem_get_current(current_menu) != NULL) { menuitem_deselect(current_menu); } @@ -720,7 +766,7 @@ menu_reset_tree(menu_t * menu) ASSERT(menu != NULL); - D_MENU(("menu_reset_tree() called for menu \"%s\" (window 0x%08x)\n", menu->title, menu->win)); + D_MENU(("menu_reset_tree(menu %8p \"%s\"), window 0x%08x\n", menu, menu->title, menu->win)); if (!(menu->state & MENU_STATE_IS_MAPPED)) { return; } @@ -742,7 +788,7 @@ menu_reset_submenus(menu_t * menu) ASSERT(menu != NULL); - D_MENU(("menu_reset_submenus() called for menu \"%s\" (window 0x%08x)\n", menu->title, menu->win)); + D_MENU(("menu_reset_submenus(menu %8p \"%s\"), window 0x%08x\n", menu, menu->title, menu->win)); for (i = 0; i < menu->numitems; i++) { item = menu->items[i]; if (item->type == MENUITEM_SUBMENU && item->action.submenu != NULL) { @@ -760,8 +806,7 @@ menuitem_select(menu_t * menu) item = menuitem_get_current(menu); REQUIRE(item != NULL); - D_MENU(("menuitem_select(): Selecting new current item \"%s\" within menu \"%s\" (window 0x%08x, selection window 0x%08x)\n", - item->text, menu->title, menu->win, menu->swin)); + D_MENU(("Selecting new current item \"%s\" within menu \"%s\" (window 0x%08x, selection window 0x%08x)\n", item->text, menu->title, menu->win, menu->swin)); item->state |= MENU_STATE_IS_CURRENT; XMoveWindow(Xdisplay, menu->swin, item->x, item->y); XMapWindow(Xdisplay, menu->swin); @@ -788,10 +833,12 @@ menuitem_select(menu_t * menu) enl_ipc_sync(); } } + XSetForeground(Xdisplay, menu->gc, images[image_menu].selected->fg); draw_string(menu->swin, menu->gc, MENU_HGAP, item->h - MENU_VGAP, item->text, item->len); if (item->rtext) { draw_string(menu->swin, menu->gc, item->w - XTextWidth(menu->font, item->rtext, item->rlen) - 2 * MENU_HGAP, item->h - MENU_VGAP, item->rtext, item->rlen); } + XSetForeground(Xdisplay, menu->gc, images[image_menu].norm->fg); } void @@ -803,7 +850,7 @@ menuitem_deselect(menu_t * menu) item = menuitem_get_current(menu); REQUIRE(item != NULL); - D_MENU(("menuitem_deselect(): Deselecting item \"%s\"\n", item->text)); + D_MENU(("Deselecting item \"%s\"\n", item->text)); item->state &= ~(MENU_STATE_IS_CURRENT); XUnmapWindow(Xdisplay, menu->swin); } @@ -818,7 +865,7 @@ menu_display_submenu(menu_t * menu, menuitem_t * item) REQUIRE(item->action.submenu != NULL); submenu = item->action.submenu; - D_MENU(("menu_display_submenu(): Displaying submenu \"%s\" (window 0x%08x) of menu \"%s\" (window 0x%08x)\n", submenu->title, submenu->win, menu->title, menu->win)); + D_MENU(("Displaying submenu \"%s\" (window 0x%08x) of menu \"%s\" (window 0x%08x)\n", submenu->title, submenu->win, menu->title, menu->win)); menu_invoke(item->x + item->w, item->y, menu->win, submenu, CurrentTime); /* Invoking the submenu makes it current. Undo that behavior. */ @@ -834,7 +881,7 @@ menu_move(menu_t *menu, unsigned short x, unsigned short y) { ASSERT(menu != NULL); - D_MENU(("menu_move(): Moving menu \"%s\" to %hu, %hu\n", menu->title, x, y)); + D_MENU(("Moving menu \"%s\" to %hu, %hu\n", menu->title, x, y)); menu->x = x; menu->y = y; XMoveWindow(Xdisplay, menu->win, menu->x, menu->y); @@ -864,7 +911,7 @@ menu_draw(menu_t * menu) if (!menu->font) { menu_set_font(menu, etfonts[def_font_idx]); } - gcvalue.foreground = PixColors[menuTextColor]; + gcvalue.foreground = images[image_menu].norm->fg; gcvalue.graphics_exposures = False; XChangeGC(Xdisplay, menu->gc, GCForeground | GCGraphicsExposures, &gcvalue); @@ -935,34 +982,12 @@ menu_draw(menu_t * menu) XUnmapWindow(Xdisplay, menu->swin); /* Draw menu background */ - if (image_mode_is(image_menu, MODE_AUTO)) { - pixmap_t *pmap = images[image_menu].norm->pmap; - - if (pmap->pixmap != None) { - XFreePixmap(Xdisplay, pmap->pixmap); - } - pmap->pixmap = XCreatePixmap(Xdisplay, menu->win, menu->w, menu->h, Xdepth); - paste_simage(images[image_menu].norm, image_menu, pmap->pixmap, 0, 0, menu->w, menu->h); - enl_ipc_sync(); - } else { - render_simage(images[image_menu].norm, menu->win, menu->w, menu->h, image_menu, 0); - } - if (!image_mode_is(image_menu, MODE_MASK)) { - GC gc; - pixmap_t *pmap = images[image_menu].norm->pmap; - - if (pmap->pixmap != None) { - XFreePixmap(Xdisplay, pmap->pixmap); - } - pmap->pixmap = XCreatePixmap(Xdisplay, menu->win, menu->w, menu->h, Xdepth); - gcvalue.foreground = PixColors[menuColor]; - gc = XCreateGC(Xdisplay, menu->win, GCForeground, &gcvalue); - XFillRectangle(Xdisplay, pmap->pixmap, gc, 0, 0, menu->w, menu->h); - XFreeGC(Xdisplay, gc); - draw_shadow_from_colors(pmap->pixmap, PixColors[menuTopShadowColor], PixColors[menuBottomShadowColor], 0, 0, menu->w, menu->h, 2); - } + render_simage(images[image_menu].norm, menu->win, menu->w, menu->h, image_menu, RENDER_FORCE_PIXMAP); menu->bg = images[image_menu].norm->pmap->pixmap; - D_MENU(("menu_draw(): Menu background is 0x%08x\n", menu->bg)); + if (!image_mode_is(image_menu, MODE_MASK)) { + draw_shadow_from_colors(menu->bg, PixColors[menuTopShadowColor], PixColors[menuBottomShadowColor], 0, 0, menu->w, menu->h, 2); + } + D_MENU(("Menu background is 0x%08x\n", menu->bg)); XMapWindow(Xdisplay, menu->win); XRaiseWindow(Xdisplay, menu->win); @@ -989,8 +1014,7 @@ menu_draw(menu_t * menu) item->y = str_y - 2 * MENU_VGAP; item->w = menu->w - MENU_HGAP; item->h = 2 * MENU_VGAP; - D_MENU(("menu_draw(): Hot Area at %hu, %hu to %hu, %hu (width %hu, height %hu)\n", item->x, item->y, item->x + item->w, item->y + item->h, - item->w, item->h)); + D_MENU(("Hot Area at %hu, %hu to %hu, %hu (width %hu, height %hu)\n", item->x, item->y, item->x + item->w, item->y + item->h, item->w, item->h)); } draw_shadow(menu->bg, botShadowGC, topShadowGC, str_x, str_y - MENU_VGAP - MENU_VGAP / 2, menu->w - 4 * MENU_HGAP, MENU_VGAP, 2); @@ -1001,8 +1025,7 @@ menu_draw(menu_t * menu) item->y = str_y - menu->fheight - MENU_VGAP / 2; item->w = menu->w - MENU_HGAP; item->h = menu->fheight + MENU_VGAP; - D_MENU(("menu_draw(): Hot Area at %hu, %hu to %hu, %hu (width %hu, height %hu)\n", item->x, item->y, item->x + item->w, item->y + item->h, - item->w, item->h)); + D_MENU(("Hot Area at %hu, %hu to %hu, %hu (width %hu, height %hu)\n", item->x, item->y, item->x + item->w, item->y + item->h, item->w, item->h)); } switch (item->type) { case MENUITEM_SUBMENU: diff --git a/src/menus.h b/src/menus.h index a4ce891..b9933f9 100644 --- a/src/menus.h +++ b/src/menus.h @@ -44,7 +44,7 @@ /* Constants */ #define MENU_HGAP 4 #define MENU_VGAP 4 -#define MENU_CLICK_TIME 20 +#define MENU_CLICK_TIME 200 #define NO_CURRENT_ITEM ((unsigned short) -1) #define menu_is_pixmapped() ((images[image_menu].current->iml->im) && (images[image_menu].mode & MODE_MASK)) @@ -57,7 +57,7 @@ typedef struct menu_t_struct menu_t; typedef struct { - image_t *icon; + simage_t *icon; unsigned char type, state; union { menu_t *submenu; @@ -108,6 +108,7 @@ extern unsigned char menu_handle_motion_notify(event_t *); extern unsigned char menu_dispatch_event(event_t *); extern menulist_t *menulist_add_menu(menulist_t *, menu_t *); extern menu_t *menu_create(char *); +extern unsigned char menu_set_title(menu_t *, const char *); extern unsigned char menu_set_font(menu_t *, const char *); extern unsigned char menu_add_item(menu_t *, menuitem_t *); extern unsigned char menu_is_child(menu_t *, menu_t *); @@ -117,7 +118,8 @@ extern menuitem_t *find_item_by_coords(menu_t *, int, int); extern unsigned short find_item_in_menu(menu_t *, menuitem_t *); extern void menuitem_change_current(menuitem_t *); extern menuitem_t *menuitem_create(char *); -extern unsigned char menuitem_set_icon(menuitem_t *, image_t *); +extern unsigned char menuitem_set_text(menuitem_t *, const char *); +extern unsigned char menuitem_set_icon(menuitem_t *, simage_t *); extern unsigned char menuitem_set_action(menuitem_t *, unsigned char, char *); extern unsigned char menuitem_set_rtext(menuitem_t *, char *); diff --git a/src/misc.c b/src/misc.c index c61d06d..186385a 100644 --- a/src/misc.c +++ b/src/misc.c @@ -172,14 +172,18 @@ int parse_escaped_string(char *str) { - register char *pold, *pnew; + register char *pold = str, *pnew; unsigned char i; D_STRINGS(("parse_escaped_string(\"%s\")\n", str)); + if (!BEG_STRCASECMP(pold, "m-")) { + *pold = '\\'; + *(pold + 1) = 'e'; + } for (pold = pnew = str; *pold; pold++, pnew++) { D_STRINGS(("Looking at \"%s\"\n", pold)); - if (!BEG_STRCASECMP(pold, "m-")) { + if (!BEG_STRCASECMP(pold, "m-") && (isspace(*(pold - 1)) || !isprint(*(pold -1)))) { *pold = '\\'; *(pold + 1) = 'e'; } else if (!BEG_STRCASECMP(pold, "c-")) { diff --git a/src/options.c b/src/options.c index d89faca..f1201cd 100644 --- a/src/options.c +++ b/src/options.c @@ -43,6 +43,7 @@ static const char cvs_ident[] = "$Id$"; #include "../libmej/strings.h" #include "debug.h" #include "actions.h" +#include "buttons.h" #include "command.h" #include "events.h" #include "font.h" @@ -57,132 +58,48 @@ static const char cvs_ident[] = "$Id$"; #include "term.h" #include "windows.h" -/* local functions referenced */ -char *chomp(char *); -void parse_main(char *); -void parse_color(char *); -void parse_attributes(char *); -void parse_toggles(char *); -void parse_keyboard(char *); -void parse_misc(char *); -void parse_imageclasses(char *); -void parse_image(char *); -void parse_actions(char *); -void parse_menu(char *); -void parse_menuitem(char *); -void parse_xim(char *); -void parse_multichar(char *); -void parse_undef(char *); -char *builtin_random(char *); -char *builtin_exec(char *); -char *builtin_version(char *); -char *builtin_appname(char *); +static void *parse_color(char *, void *); +static void *parse_attributes(char *, void *); +static void *parse_toggles(char *, void *); +static void *parse_keyboard(char *, void *); +static void *parse_misc(char *, void *); +static void *parse_imageclasses(char *, void *); +static void *parse_image(char *, void *); +static void *parse_actions(char *, void *); +static void *parse_menu(char *, void *); +static void *parse_menuitem(char *, void *); +static void *parse_bbar(char *, void *); +static void *parse_xim(char *, void *); +static void *parse_multichar(char *, void *); +static char *builtin_random(char *); +static char *builtin_exec(char *); +static char *builtin_version(char *); +static char *builtin_appname(char *); +static void *parse_null(char *, void *); + +static ctx_t *context; +static ctx_state_t *ctx_state; +static eterm_func_t *builtins; +static unsigned char ctx_cnt, ctx_idx, ctx_state_idx, ctx_state_cnt, fstate_cnt, builtin_cnt, builtin_idx; +#if defined (HOTKEY_CTRL) || defined (HOTKEY_META) +static char *rs_bigfont_key = NULL; +static char *rs_smallfont_key = NULL; +#endif +#ifdef MULTI_CHARSET +static char *rs_multichar_encoding = NULL; +#endif +#ifdef GREEK_SUPPORT +static char *rs_greek_keyboard = NULL; +#endif const char *true_vals[] = {"1", "on", "true", "yes"}; const char *false_vals[] = {"0", "off", "false", "no"}; -/* This structure defines a context and its attributes */ -struct context_struct { - const unsigned char id; - const char *description; - void (*ctx_handler) (char *); - const unsigned char valid_sub_contexts[CTX_MAX]; -} contexts[] = { - { - CTX_NULL, "none", NULL, { - CTX_MAIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_MAIN, "main", parse_main, { - CTX_COLOR, CTX_ATTRIBUTES, CTX_TOGGLES, CTX_KEYBOARD, - CTX_MISC, CTX_IMAGECLASSES, CTX_ACTIONS, - CTX_MENU, CTX_XIM, CTX_MULTI_CHARSET, 0, 0, 0 - } - }, - { - CTX_COLOR, "color", parse_color, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_ATTRIBUTES, "attributes", parse_attributes, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_TOGGLES, "toggles", parse_toggles, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_KEYBOARD, "keyboard", parse_keyboard, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_MISC, "misc", parse_misc, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_IMAGECLASSES, "imageclasses", parse_imageclasses, { - CTX_IMAGE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_IMAGE, "image", parse_image, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_ACTIONS, "actions", parse_actions, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_MENU, "menu", parse_menu, { - CTX_MENUITEM, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_MENUITEM, "menuitem", parse_menuitem, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_XIM, "xim", parse_xim, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_MULTI_CHARSET, "multichar", parse_multichar, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_UNDEF, NULL, parse_undef, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - } - -}; -unsigned char id_stack[MAX_CTX_DEPTH]; -unsigned short cur_ctx = 0; -file_state file_stack[MAX_FILE_DEPTH]; -short cur_file = -1; -eterm_func builtins[] = -{ - {"random", builtin_random, -1}, - {"exec", builtin_exec, -1}, - {"version", builtin_version, 0}, - {"appname", builtin_appname, 0}, - {(char *) NULL, (eterm_function_ptr) NULL, 0} -}; +fstate_t *fstate; +unsigned char fstate_idx; unsigned long Options = (Opt_scrollbar), image_toggles = 0; -static menu_t *curmenu; char *theme_dir = NULL, *user_dir = NULL; char **rs_execArgs = NULL; /* Args to exec (-e or --exec) */ char *rs_title = NULL; /* Window title */ @@ -207,19 +124,9 @@ unsigned short rs_min_anchor_size = 0; char *rs_scrollbar_type = NULL; unsigned long rs_scrollbar_width = 0; char *rs_term_name = NULL; -#if defined (HOTKEY_CTRL) || defined (HOTKEY_META) -static char *rs_bigfont_key = NULL; -static char *rs_smallfont_key = NULL; -#endif -#ifdef MULTI_CHARSET -static char *rs_multichar_encoding = NULL; -#endif -#ifdef GREEK_SUPPORT -static char *rs_greek_keyboard = NULL; -#endif #ifdef PIXMAP_SUPPORT char *rs_pixmapScale = NULL; -const char *rs_backing_store = NULL; +char *rs_backing_store = NULL; char *rs_icon = NULL; char *rs_cmod_image = NULL; char *rs_cmod_red = NULL; @@ -375,9 +282,8 @@ static const struct { OPT_BOOL('s', "scrollbar", "display scrollbar", &Options, Opt_scrollbar), OPT_BOOL('u', "utmp-logging", "make a utmp entry", &Options, Opt_utmpLogging), OPT_BOOL('v', "visual-bell", "visual bell", &Options, Opt_visualBell), - OPT_BOOL('H', "home-on-echo", "jump to bottom on output", &Options, Opt_homeOnEcho), - OPT_BLONG("home-on-input", "jump to bottom on input", &Options, Opt_homeOnInput), - OPT_BOOL('E', "home-on-refresh", "jump to bottom on refresh (^L)", &Options, Opt_homeOnRefresh), + OPT_BOOL('H', "home-on-echo", "jump to bottom on output", &Options, Opt_home_on_output), + OPT_BLONG("home-on-input", "jump to bottom on input", &Options, Opt_home_on_input), OPT_BLONG("scrollbar-right", "display the scrollbar on the right", &Options, Opt_scrollbar_right), OPT_BLONG("scrollbar-floating", "display the scrollbar with no trough", &Options, Opt_scrollbar_floating), OPT_BLONG("scrollbar-popup", "popup the scrollbar only when focused", &Options, Opt_scrollbar_popup), @@ -1149,6 +1055,8 @@ get_initial_options(int argc, char *argv[]) j = 3; } else if (!BEG_STRCASECMP(opt, "install")) { j = 4; + } else if (!BEG_STRCASECMP(opt, "exec") && (*(opt+4) != '=')) { + break; } else continue; @@ -1208,6 +1116,8 @@ get_initial_options(int argc, char *argv[]) j = 1; } else if (opt[pos] == 'd') { j = 2; + } else if (opt[pos] == 'e') { + break; } else continue; @@ -1235,7 +1145,118 @@ get_initial_options(int argc, char *argv[]) } /***** The Config File Section *****/ -char * +/* This function must be called before any other conf_*() function. + Otherwise you will be bitten by dragons. That's life. */ +void +conf_init_subsystem(void) { + + /* Initialize the context list and establish a catch-all "null" context */ + ctx_cnt = 20; + ctx_idx = 0; + context = (ctx_t *) malloc(sizeof(ctx_t) * ctx_cnt); + MEMSET(context, 0, sizeof(ctx_t) * ctx_cnt); + context[0].name = "null"; + context[0].handler = parse_null; + + /* Initialize the context state stack and set the current context to "null" */ + ctx_state_cnt = 20; + ctx_state_idx = 0; + ctx_state = (ctx_state_t *) malloc(sizeof(ctx_state_t) * ctx_state_cnt); + MEMSET(ctx_state, 0, sizeof(ctx_state_t) * ctx_state_cnt); + + /* Initialize the file state stack */ + fstate_cnt = 10; + fstate_idx = 0; + fstate = (fstate_t *) malloc(sizeof(fstate_t) * fstate_cnt); + MEMSET(fstate, 0, sizeof(fstate_t) * fstate_cnt); + + /* Initialize the builtin function table */ + builtin_cnt = 10; + builtin_idx = 0; + builtins = (eterm_func_t *) malloc(sizeof(eterm_func_t) * builtin_cnt); + MEMSET(builtins, 0, sizeof(eterm_func_t) * builtin_cnt); + + /* Register the omni-present builtin functions */ + conf_register_builtin("appname", builtin_appname); + conf_register_builtin("version", builtin_version); + conf_register_builtin("exec", builtin_exec); + conf_register_builtin("random", builtin_random); + + /* For expediency, Eterm registers its contexts here. If you want to use + this parser in another program, remove these lines. */ + conf_register_context("color", parse_color); + conf_register_context("attributes", parse_attributes); + conf_register_context("toggles", parse_toggles); + conf_register_context("keyboard", parse_keyboard); + conf_register_context("misc", parse_misc); + conf_register_context("imageclasses", parse_imageclasses); + conf_register_context("image", parse_image); + conf_register_context("actions", parse_actions); + conf_register_context("menu", parse_menu); + conf_register_context("menuitem", parse_menuitem); + conf_register_context("button_bar", parse_bbar); + conf_register_context("xim", parse_xim); + conf_register_context("multichar", parse_multichar); +} + +/* Register a new config file context */ +unsigned char +conf_register_context(char *name, ctx_handler_t handler) { + + if (++ctx_idx == ctx_cnt) { + ctx_cnt *= 2; + context = (ctx_t *) realloc(context, sizeof(ctx_t) * ctx_cnt); + } + context[ctx_idx].name = strdup(name); + context[ctx_idx].handler = handler; + D_OPTIONS(("conf_register_context(): Added context \"%s\" with ID %d and handler 0x%08x\n", + context[ctx_idx].name, ctx_idx, context[ctx_idx].handler)); + return (ctx_idx); +} + +/* Register a new file state structure */ +unsigned char +conf_register_fstate(FILE *fp, char *path, char *outfile, unsigned long line, unsigned char flags) { + + if (++fstate_idx == fstate_cnt) { + fstate_cnt *= 2; + fstate = (fstate_t *) realloc(fstate, sizeof(fstate_t) * fstate_cnt); + } + fstate[fstate_idx].fp = fp; + fstate[fstate_idx].path = path; + fstate[fstate_idx].outfile = outfile; + fstate[fstate_idx].line = line; + fstate[fstate_idx].flags = flags; + return (fstate_idx); +} + +/* Register a new builtin function */ +unsigned char +conf_register_builtin(char *name, eterm_func_ptr_t ptr) { + + builtins[builtin_idx].name = strdup(name); + builtins[builtin_idx].ptr = ptr; + if (++builtin_idx == builtin_cnt) { + builtin_cnt *= 2; + builtins = (eterm_func_t *) realloc(builtins, sizeof(eterm_func_t) * builtin_cnt); + } + return (builtin_idx - 1); +} + +/* Register a new config file context */ +unsigned char +conf_register_context_state(unsigned char ctx_id) { + + if (++ctx_state_idx == ctx_state_cnt) { + ctx_state_cnt *= 2; + ctx_state = (ctx_state_t *) realloc(ctx_state, sizeof(ctx_state_t) * ctx_state_cnt); + } + ctx_state[ctx_state_idx].ctx_id = ctx_id; + ctx_state[ctx_state_idx].state = NULL; + return (ctx_state_idx); +} + +static char * builtin_random(char *param) { @@ -1255,7 +1276,7 @@ builtin_random(char *param) return (Word(index, param)); } -char * +static char * builtin_exec(char *param) { @@ -1299,7 +1320,7 @@ builtin_exec(char *param) return (Output); } -char * +static char * builtin_version(char *param) { @@ -1310,7 +1331,7 @@ builtin_version(char *param) return (StrDup(VERSION)); } -char * +static char * builtin_appname(char *param) { @@ -1391,7 +1412,7 @@ shell_expand(char *s) new[j] = '\t'; break; case 'b': - j -= 2; + new[j] = '\b'; break; case 'f': new[j] = '\f'; @@ -1575,24 +1596,12 @@ shell_expand(char *s) } /* The config file parsers. Each function handles a given context. */ - -void -parse_main(char *buff) +static void * +parse_color(char *buff, void *state) { - - ASSERT(buff != NULL); - - print_error("Parse error in file %s, line %lu: Attribute " - "\"%s\" is not valid within context main\n", - file_peek_path(), file_peek_line(), buff); -} - -void -parse_color(char *buff) -{ - - ASSERT(buff != NULL); - + if ((*buff == CONF_BEGIN_CHAR) || (*buff == CONF_END_CHAR)) { + return NULL; + } if (!BEG_STRCASECMP(buff, "foreground ")) { RESET_AND_ASSIGN(rs_color[fgColor], Word(2, buff)); } else if (!BEG_STRCASECMP(buff, "background ")) { @@ -1650,7 +1659,7 @@ parse_color(char *buff) if (n < 3) { print_error("Parse error in file %s, line %lu: Invalid parameter list \"%s\" for " "attribute color", file_peek_path(), file_peek_line(), NONULL(tmp)); - return; + return NULL; } tmp = PWord(2, buff); r1 = PWord(3, buff); @@ -1663,7 +1672,7 @@ parse_color(char *buff) index = minBright + n - 8; } RESET_AND_ASSIGN(rs_color[index], Word(1, r1)); - return; + return NULL; } else { if (!BEG_STRCASECMP(tmp, "bd ")) { #ifndef NO_BOLDUNDERLINE @@ -1671,14 +1680,14 @@ parse_color(char *buff) #else print_warning("Support for the color bd attribute was not compiled in, ignoring"); #endif - return; + return NULL; } else if (!BEG_STRCASECMP(tmp, "ul ")) { #ifndef NO_BOLDUNDERLINE RESET_AND_ASSIGN(rs_color[colorUL], Word(1, r1)); #else print_warning("Support for the color ul attribute was not compiled in, ignoring"); #endif - return; + return NULL; } else { tmp = Word(1, tmp); print_error("Parse error in file %s, line %lu: Invalid color index \"%s\"", @@ -1690,7 +1699,7 @@ parse_color(char *buff) if (n != 5) { print_error("Parse error in file %s, line %lu: Invalid parameter list \"%s\" for " "attribute color", file_peek_path(), file_peek_line(), NONULL(tmp)); - return; + return NULL; } g1 = PWord(4, buff); b1 = PWord(5, buff); @@ -1744,14 +1753,15 @@ parse_color(char *buff) print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " "within context color", file_peek_path(), file_peek_line(), buff); } + return state; } -void -parse_attributes(char *buff) +static void * +parse_attributes(char *buff, void *state) { - - ASSERT(buff != NULL); - + if ((*buff == CONF_BEGIN_CHAR) || (*buff == CONF_END_CHAR)) { + return NULL; + } if (!BEG_STRCASECMP(buff, "geometry ")) { RESET_AND_ASSIGN(rs_geometry, Word(2, buff)); @@ -1781,7 +1791,7 @@ parse_attributes(char *buff) if (NumWords(buff) != 3) { print_error("Parse error in file %s, line %lu: Invalid parameter list \"%s\" for " "attribute font", file_peek_path(), file_peek_line(), NONULL(tmp)); - return; + return NULL; } if (isdigit(*tmp)) { n = (unsigned char) strtoul(tmp, (char **) NULL, 0); @@ -1812,20 +1822,21 @@ parse_attributes(char *buff) print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " "within context attributes", file_peek_path(), file_peek_line(), (buff ? buff : "")); } + return state; } -void -parse_toggles(char *buff) +static void * +parse_toggles(char *buff, void *state) { - - char *tmp = PWord(2, buff); + char *tmp; unsigned char bool_val; - ASSERT(buff != NULL); - - if (!tmp) { + if ((*buff == CONF_BEGIN_CHAR) || (*buff == CONF_END_CHAR)) { + return NULL; + } + if (!(tmp = PWord(2, buff))) { print_error("Parse error in file %s, line %lu: Missing boolean value in context toggles", file_peek_path(), file_peek_line()); - return; + return NULL; } if (BOOL_OPT_ISTRUE(tmp)) { bool_val = 1; @@ -1834,7 +1845,7 @@ parse_toggles(char *buff) } else { print_error("Parse error in file %s, line %lu: Invalid boolean value \"%s\" in context toggles", file_peek_path(), file_peek_line(), tmp); - return; + return NULL; } if (!BEG_STRCASECMP(buff, "map_alert ")) { @@ -1896,25 +1907,18 @@ parse_toggles(char *buff) Options &= ~(Opt_iconic); } - } else if (!BEG_STRCASECMP(buff, "home_on_echo ")) { + } else if (!BEG_STRCASECMP(buff, "home_on_output ")) { if (bool_val) { - Options |= Opt_homeOnEcho; + Options |= Opt_home_on_output; } else { - Options &= ~(Opt_homeOnEcho); + Options &= ~(Opt_home_on_output); } } else if (!BEG_STRCASECMP(buff, "home_on_input ")) { if (bool_val) { - Options |= Opt_homeOnInput; + Options |= Opt_home_on_input; } else { - Options &= ~(Opt_homeOnInput); - } - - } else if (!BEG_STRCASECMP(buff, "home_on_refresh ")) { - if (bool_val) { - Options |= Opt_homeOnRefresh; - } else { - Options &= ~(Opt_homeOnRefresh); + Options &= ~(Opt_home_on_input); } } else if (!BEG_STRCASECMP(buff, "scrollbar_floating ")) { @@ -2001,14 +2005,15 @@ parse_toggles(char *buff) } else { print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid within context toggles", file_peek_path(), file_peek_line(), buff); } + return state; } -void -parse_keyboard(char *buff) +static void * +parse_keyboard(char *buff, void *state) { - - ASSERT(buff != NULL); - + if ((*buff == CONF_BEGIN_CHAR) || (*buff == CONF_END_CHAR)) { + return NULL; + } if (!BEG_STRCASECMP(buff, "smallfont_key ")) { #if defined (HOTKEY_CTRL) || defined (HOTKEY_META) RESET_AND_ASSIGN(rs_smallfont_key, Word(2, buff)); @@ -2039,7 +2044,7 @@ parse_keyboard(char *buff) if (sym < 0 || sym > 0xff) { print_error("Parse error in file %s, line %lu: Keysym 0x%x out of range 0xff00-0xffff", file_peek_path(), file_peek_line(), sym + 0xff00); - return; + return NULL; } s = Word(3, buff); str = (char *) MALLOC(strlen(s) + 2); @@ -2068,7 +2073,7 @@ parse_keyboard(char *buff) if (!tmp) { print_error("Parse error in file %s, line %lu: Missing modifier value for attribute meta_mod", file_peek_path(), file_peek_line()); - return; + return NULL; } rs_meta_mod = (unsigned int) strtoul(tmp, (char **) NULL, 0); @@ -2078,7 +2083,7 @@ parse_keyboard(char *buff) if (!tmp) { print_error("Parse error in file %s, line %lu: Missing modifier value for attribute alt_mod", file_peek_path(), file_peek_line()); - return; + return NULL; } rs_alt_mod = (unsigned int) strtoul(tmp, (char **) NULL, 0); @@ -2088,7 +2093,7 @@ parse_keyboard(char *buff) if (!tmp) { print_error("Parse error in file %s, line %lu: Missing modifier value for attribute numlock_mod", file_peek_path(), file_peek_line()); - return; + return NULL; } rs_numlock_mod = (unsigned int) strtoul(tmp, (char **) NULL, 0); @@ -2100,7 +2105,7 @@ parse_keyboard(char *buff) if (!tmp) { print_error("Parse error in file %s, line %lu: Missing boolean value for attribute greek", file_peek_path(), file_peek_line()); - return; + return NULL; } if (BOOL_OPT_ISTRUE(tmp)) { RESET_AND_ASSIGN(rs_greek_keyboard, Word(3, buff)); @@ -2117,7 +2122,7 @@ parse_keyboard(char *buff) } else { print_error("Parse error in file %s, line %lu: Invalid boolean value \"%s\" for attribute %s", file_peek_path(), file_peek_line(), tmp, buff); - return; + return NULL; } #else print_warning("Support for the greek attribute was not compiled in, ignoring"); @@ -2130,7 +2135,7 @@ parse_keyboard(char *buff) if (!tmp) { print_error("Parse error in file %s, line %lu: Missing boolean value for attribute app_keypad", file_peek_path(), file_peek_line()); - return; + return NULL; } if (BOOL_OPT_ISTRUE(tmp)) { PrivateModes |= PrivMode_aplKP; @@ -2139,7 +2144,7 @@ parse_keyboard(char *buff) } else { print_error("Parse error in file %s, line %lu: Invalid boolean value \"%s\" for " "attribute app_keypad", file_peek_path(), file_peek_line(), tmp); - return; + return NULL; } } else if (!BEG_STRCASECMP(buff, "app_cursor ")) { @@ -2149,7 +2154,7 @@ parse_keyboard(char *buff) if (!tmp) { print_error("Parse error in file %s, line %lu: Missing boolean value for attribute app_cursor", file_peek_path(), file_peek_line()); - return; + return NULL; } if (BOOL_OPT_ISTRUE(tmp)) { PrivateModes |= PrivMode_aplCUR; @@ -2158,21 +2163,22 @@ parse_keyboard(char *buff) } else { print_error("Parse error in file %s, line %lu: Invalid boolean value \"%s\" for " "attribute app_cursor", file_peek_path(), file_peek_line(), tmp); - return; + return NULL; } } else { print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " "within context keyboard", file_peek_path(), file_peek_line(), buff); } + return state; } -void -parse_misc(char *buff) +static void * +parse_misc(char *buff, void *state) { - - ASSERT(buff != NULL); - + if ((*buff == CONF_BEGIN_CHAR) || (*buff == CONF_END_CHAR)) { + return NULL; + } if (!BEG_STRCASECMP(buff, "print_pipe ")) { #ifdef PRINTPIPE RESET_AND_ASSIGN(rs_print_pipe, StrDup(PWord(2, buff))); @@ -2229,15 +2235,17 @@ parse_misc(char *buff) print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " "within context misc", file_peek_path(), file_peek_line(), buff); } + return state; } -void -parse_imageclasses(char *buff) +static void * +parse_imageclasses(char *buff, void *state) { + if ((*buff == CONF_BEGIN_CHAR) || (*buff == CONF_END_CHAR)) { + return NULL; + } #ifdef PIXMAP_SUPPORT - ASSERT(buff != NULL); - if (!BEG_STRCASECMP(buff, "icon ")) { RESET_AND_ASSIGN(rs_icon, Word(2, buff)); @@ -2265,22 +2273,36 @@ parse_imageclasses(char *buff) print_warning("Pixmap support was not compiled in, ignoring entire context"); file_poke_skip(1); #endif + return state; } -void -parse_image(char *buff) +static void * +parse_image(char *buff, void *state) { - static short idx = -1; + int idx; #ifdef PIXMAP_SUPPORT - ASSERT(buff != NULL); + if (*buff == CONF_BEGIN_CHAR) { + int *tmp; + tmp = (int *) MALLOC(sizeof(int)); + return ((void *) tmp); + } + ASSERT_RVAL(state != NULL, (file_skip_to_end(), NULL)); + if (*buff == CONF_END_CHAR) { + int *tmp; + + tmp = (int *) state; + FREE(tmp); + return NULL; + } + idx = *((int *) state); if (!BEG_STRCASECMP(buff, "type ")) { char *type = PWord(2, buff); if (!type) { print_error("Parse error in file %s, line %lu: Missing image type", file_peek_path(), file_peek_line()); - return; + return NULL; } if (!strcasecmp(type, "background")) { idx = image_bg; @@ -2288,6 +2310,8 @@ parse_image(char *buff) idx = image_sb; } else if (!strcasecmp(type, "anchor")) { idx = image_sa; + } else if (!strcasecmp(type, "thumb")) { + idx = image_st; } else if (!strcasecmp(type, "up_arrow")) { idx = image_up; } else if (!strcasecmp(type, "down_arrow")) { @@ -2298,12 +2322,23 @@ parse_image(char *buff) idx = image_right; } else if (!strcasecmp(type, "menu")) { idx = image_menu; + } else if (!strcasecmp(type, "menuitem")) { + idx = image_menuitem; } else if (!strcasecmp(type, "submenu")) { idx = image_submenu; + } else if (!strcasecmp(type, "button")) { + idx = image_button; + } else if (!strcasecmp(type, "button_bar") || !strcasecmp(type, "buttonbar")) { + idx = image_bbar; + } else if (!strcasecmp(type, "grab_bar")) { + idx = image_gbar; + } else if (!strcasecmp(type, "dialog_box")) { + idx = image_dialog; } else { print_error("Parse error in file %s, line %lu: Invalid image type \"%s\"", file_peek_path(), file_peek_line(), type); - return; + return NULL; } + *((int *) state) = idx; } else if (!BEG_STRCASECMP(buff, "mode ")) { char *mode = PWord(2, buff); @@ -2311,11 +2346,11 @@ parse_image(char *buff) if (idx < 0) { print_error("Parse error in file %s, line %lu: Encountered \"mode\" with no image type defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (!mode) { print_error("Parse error in file %s, line %lu: Missing parameters for mode line", file_peek_path(), file_peek_line()); - return; + return NULL; } if (!BEG_STRCASECMP(mode, "image")) { images[idx].mode = (MODE_IMAGE | ALLOW_IMAGE); @@ -2353,11 +2388,11 @@ parse_image(char *buff) if (!state) { print_error("Parse error in file %s, line %lu: Missing state", file_peek_path(), file_peek_line()); - return; + return NULL; } if (idx < 0) { print_error("Parse error in file %s, line %lu: Encountered \"state\" with no image type defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (!strcasecmp(state, "normal")) { if (images[idx].norm == NULL) { @@ -2377,47 +2412,82 @@ parse_image(char *buff) new = 1; } images[idx].current = images[idx].clicked; + } else if (!strcasecmp(state, "disabled")) { + if (images[idx].disabled == NULL) { + images[idx].disabled = (simage_t *) MALLOC(sizeof(simage_t)); + new = 1; + } + images[idx].current = images[idx].disabled; } else { print_error("Parse error in file %s, line %lu: Invalid state \"%s\"", file_peek_path(), file_peek_line(), state); - return; + return NULL; } if (new) { + MEMSET(images[idx].current, 0, sizeof(simage_t)); images[idx].current->pmap = (pixmap_t *) MALLOC(sizeof(pixmap_t)); images[idx].current->iml = (imlib_t *) MALLOC(sizeof(imlib_t)); MEMSET(images[idx].current->pmap, 0, sizeof(pixmap_t)); MEMSET(images[idx].current->iml, 0, sizeof(imlib_t)); } + } else if (!BEG_STRCASECMP(buff, "color ")) { + char *fg = Word(2, buff), *bg = Word(3, buff); + + if (idx < 0) { + print_error("Parse error in file %s, line %lu: Encountered \"color\" with no image type defined", file_peek_path(), file_peek_line()); + return NULL; + } + if (images[idx].current == NULL) { + print_error("Parse error in file %s, line %lu: Encountered \"color\" with no image state defined", file_peek_path(), file_peek_line()); + return NULL; + } + if (!fg || !bg) { + print_error("Parse error in file %s, line %lu: Foreground and background colors must be specified with \"color\"", file_peek_path(), file_peek_line()); + return NULL; + } + if (!BEG_STRCASECMP(fg, "0x")) { + images[idx].current->fg = get_color_by_pixel((Pixel) strtoul(fg, (char **) NULL, 0), WhitePixel(Xdisplay, Xscreen)); + } else { + images[idx].current->fg = get_color_by_name(fg, "white"); + } + if (!BEG_STRCASECMP(bg, "0x")) { + images[idx].current->bg = get_color_by_pixel((Pixel) strtoul(bg, (char **) NULL, 0), BlackPixel(Xdisplay, Xscreen)); + } else { + images[idx].current->bg = get_color_by_name(bg, "black"); + } + FREE(fg); + FREE(bg); + } else if (!BEG_STRCASECMP(buff, "file ")) { char *filename = PWord(2, buff); if (idx < 0) { print_error("Parse error in file %s, line %lu: Encountered \"file\" with no image type defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (images[idx].current == NULL) { print_error("Parse error in file %s, line %lu: Encountered \"file\" with no image state defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (!filename) { print_error("Parse error in file %s, line %lu: Missing filename", file_peek_path(), file_peek_line()); - return; + return NULL; } - load_image(filename, idx); + load_image(filename, images[idx].current); } else if (!BEG_STRCASECMP(buff, "geom ")) { char *geom = PWord(2, buff); if (idx < 0) { print_error("Parse error in file %s, line %lu: Encountered \"geom\" with no image type defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (images[idx].current == NULL) { print_error("Parse error in file %s, line %lu: Encountered \"geom\" with no image state defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (!geom) { print_error("Parse error in file %s, line %lu: Missing geometry string", file_peek_path(), file_peek_line()); - return; + return NULL; } set_pixmap_scale(geom, images[idx].current->pmap); @@ -2429,19 +2499,19 @@ parse_image(char *buff) if (idx < 0) { print_error("Parse error in file %s, line %lu: Encountered color modifier with no image type defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (images[idx].current == NULL) { print_error("Parse error in file %s, line %lu: Encountered color modifier with no image state defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (!color) { print_error("Parse error in file %s, line %lu: Missing color name", file_peek_path(), file_peek_line()); - return; + return NULL; } if (!mods) { print_error("Parse error in file %s, line %lu: Missing modifier(s)", file_peek_path(), file_peek_line()); - return; + return NULL; } n = NumWords(mods); @@ -2487,17 +2557,17 @@ parse_image(char *buff) } } else { print_error("Parse error in file %s, line %lu: Color must be either \"image\", \"red\", \"green\", or \"blue\"", file_peek_path(), file_peek_line()); - return; + return NULL; } } else if (!BEG_STRCASECMP(buff, "border ")) { if (idx < 0) { print_error("Parse error in file %s, line %lu: Encountered \"border\" with no image type defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (NumWords(buff + 7) < 4) { print_error("Parse error in file %s, line %lu: Invalid parameter list for attribute \"border\"", file_peek_path(), file_peek_line()); - return; + return NULL; } RESET_AND_ASSIGN(images[idx].current->iml->border, (ImlibBorder *) MALLOC(sizeof(ImlibBorder))); @@ -2514,15 +2584,15 @@ parse_image(char *buff) } else if (!BEG_STRCASECMP(buff, "bevel ")) { if (idx < 0) { print_error("Parse error in file %s, line %lu: Encountered \"bevel\" with no image type defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (images[idx].current == NULL) { print_error("Parse error in file %s, line %lu: Encountered \"bevel\" with no image state defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (NumWords(buff + 6) < 5) { print_error("Parse error in file %s, line %lu: Invalid parameter list for attribute \"bevel\"", file_peek_path(), file_peek_line()); - return; + return NULL; } if (images[idx].current->iml->bevel != NULL) { FREE(images[idx].current->iml->bevel->edges); @@ -2551,15 +2621,15 @@ parse_image(char *buff) } else if (!BEG_STRCASECMP(buff, "padding ")) { if (idx < 0) { print_error("Parse error in file %s, line %lu: Encountered \"padding\" with no image type defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (images[idx].current == NULL) { print_error("Parse error in file %s, line %lu: Encountered \"padding\" with no image state defined", file_peek_path(), file_peek_line()); - return; + return NULL; } if (NumWords(buff + 8) < 4) { print_error("Parse error in file %s, line %lu: Invalid parameter list for attribute \"padding\"", file_peek_path(), file_peek_line()); - return; + return NULL; } RESET_AND_ASSIGN(images[idx].current->iml->pad, (ImlibBorder *) MALLOC(sizeof(ImlibBorder))); @@ -2577,14 +2647,16 @@ parse_image(char *buff) print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " "within context image", file_peek_path(), file_peek_line(), buff); } + return ((void *) state); #else print_warning("Pixmap support was not compiled in, ignoring entire context"); file_poke_skip(1); + return NULL; #endif } -void -parse_actions(char *buff) +static void * +parse_actions(char *buff, void *state) { unsigned short mod = MOD_NONE; unsigned char button = BUTTON_NONE; @@ -2592,7 +2664,9 @@ parse_actions(char *buff) char *str; unsigned short i; - ASSERT(buff != NULL); + if ((*buff == CONF_BEGIN_CHAR) || (*buff == CONF_END_CHAR)) { + return NULL; + } if (!BEG_STRCASECMP(buff, "bind ")) { for (i = 2; (str = Word(i, buff)) && strcasecmp(str, "to"); i++) { @@ -2636,12 +2710,12 @@ parse_actions(char *buff) } if (!str) { print_error("Parse error in file %s, line %lu: Syntax error (\"to\" not found)", file_peek_path(), file_peek_line()); - return; + return NULL; } FREE(str); if ((button == BUTTON_NONE) && (keysym == 0)) { print_error("Parse error in file %s, line %lu: No valid button/keysym found for action", file_peek_path(), file_peek_line()); - return; + return NULL; } i++; str = PWord(i, buff); @@ -2662,73 +2736,109 @@ parse_actions(char *buff) FREE(str); } else { print_error("Parse error in file %s, line %lu: Syntax error (\"to\" not found)", file_peek_path(), file_peek_line()); - return; + return NULL; } } else { print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " "within context action", file_peek_path(), file_peek_line(), buff); } + return state; } -void -parse_menu(char *buff) +static void * +parse_menu(char *buff, void *state) { + menu_t *menu; - ASSERT(buff != NULL); + if (*buff == CONF_BEGIN_CHAR) { + char *title = PWord(2, buff + 6); + menu = menu_create(title); + return ((void *) menu); + } + ASSERT_RVAL(state != NULL, (file_skip_to_end(), NULL)); + menu = (menu_t *) state; + if (*buff == CONF_END_CHAR) { + if (!(*(menu->title))) { + char tmp[20]; + + sprintf(tmp, "Eterm_Menu_%u", menu_list->nummenus); + menu_set_title(menu, tmp); + print_error("Parse error in file %s, line %lu: Menu context ended without giving a title. Defaulted to \"%s\".", file_peek_path(), file_peek_line(), tmp); + } + menu_list = menulist_add_menu(menu_list, menu); + return NULL; + } if (!BEG_STRCASECMP(buff, "title ")) { char *title = Word(2, buff); - curmenu = menu_create(title); - menu_list = menulist_add_menu(menu_list, curmenu); + menu_set_title(menu, title); FREE(title); } else if (!BEG_STRCASECMP(buff, "font ")) { char *name = Word(2, buff); - if (!curmenu) { - print_error("Parse error in file %s, line %lu: You must set the menu title before choosing a font.", file_peek_path(), file_peek_line()); - return; - } if (!name) { print_error("Parse error in file %s, line %lu: Missing font name.", file_peek_path(), file_peek_line()); - return; + return ((void *) menu); } - menu_set_font(curmenu, name); + menu_set_font(menu, name); FREE(name); } else if (!BEG_STRCASECMP(buff, "sep") || !BEG_STRCASECMP(buff, "-")) { menuitem_t *item; item = menuitem_create((char *) NULL); - menu_add_item(curmenu, item); + menu_add_item(menu, item); menuitem_set_action(item, MENUITEM_SEP, (char *) NULL); } else { - print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " - "within context menu", file_peek_path(), file_peek_line(), buff); + print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid within context menu", file_peek_path(), file_peek_line(), buff); } + return ((void *) menu); } -void -parse_menuitem(char *buff) +static void * +parse_menuitem(char *buff, void *state) { + static menu_t *menu; + menuitem_t *curitem; - static menuitem_t *curitem; - - ASSERT(buff != NULL); - + ASSERT_RVAL(state != NULL, (file_skip_to_end(), NULL)); + if (*buff == CONF_BEGIN_CHAR) { + menu = (menu_t *) state; + curitem = menuitem_create(NULL); + return ((void *) curitem); + } + curitem = (menuitem_t *) state; + ASSERT_RVAL(menu != NULL, state); + if (*buff == CONF_END_CHAR) { + if (!(curitem->text)) { + print_error("Parse error in file %s, line %lu: Menuitem context ended with no text given. Discarding this entry.", file_peek_path(), file_peek_line()); + FREE(curitem); + } else { + menu_add_item(menu, curitem); + } + return ((void *) menu); + } if (!BEG_STRCASECMP(buff, "text ")) { char *text = Word(2, buff); - curitem = menuitem_create(text); - menu_add_item(curmenu, curitem); + if (!text) { + print_error("Parse error in file %s, line %lu: Missing menuitem text.", file_peek_path(), file_peek_line()); + return ((void *) curitem); + } + menuitem_set_text(curitem, text); FREE(text); } else if (!BEG_STRCASECMP(buff, "rtext ")) { char *rtext = Word(2, buff); + if (!rtext) { + print_error("Parse error in file %s, line %lu: Missing menuitem right-justified text.", file_peek_path(), file_peek_line()); + return ((void *) curitem); + } menuitem_set_rtext(curitem, rtext); FREE(rtext); @@ -2751,23 +2861,107 @@ parse_menuitem(char *buff) menuitem_set_action(curitem, MENUITEM_SEP, action); } else { - print_error("Parse error in file %s, line %lu: Invalid menu item action \"%s\"", file_peek_path(), file_peek_line(), type); + print_error("Parse error in file %s, line %lu: Invalid menu item action \"%s\"", file_peek_path(), file_peek_line(), NONULL(type)); } FREE(action); + } else { + print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid within context menu", file_peek_path(), file_peek_line(), buff); + } + return ((void *) curitem); +} + +static void * +parse_bbar(char *buff, void *state) +{ + buttonbar_t *bbar; + + if (*buff == CONF_BEGIN_CHAR) { + bbar = bbar_create(); + return ((void *) bbar); + } + ASSERT_RVAL(state != NULL, (file_skip_to_end(), NULL)); + bbar = (buttonbar_t *) state; + if (*buff == CONF_END_CHAR) { + bbar_add(bbar); + return NULL; + } + if (!BEG_STRCASECMP(buff, "font ")) { + char *font = Word(2, buff); + + bbar_set_font(bbar, font); + FREE(font); + + } else if (!BEG_STRCASECMP(buff, "button ") || !BEG_STRCASECMP(buff, "rbutton ")) { + char *text = PWord(2, buff); + char *icon = StrCaseStr(buff, "icon "); + char *action = StrCaseStr(buff, "action "); + button_t *button; + + if (text == icon) { + text = NULL; + } else { + text = Word(1, text); + } + if (!text && !icon) { + print_error("Parse error in file %s, line %lu: Missing button specifications", file_peek_path(), file_peek_line()); + return ((void *) bbar); + } + + button = button_create(text); + if (icon) { + simage_t *simg; + + icon = Word(2, icon); + simg = create_simage(); + if (load_image(icon, simg)) { + button_set_icon(button, simg); + } else { + free_simage(simg); + } + FREE(icon); + } + if (action) { + char *type = PWord(2, action); + + action = Word(2, type); + if (!BEG_STRCASECMP(type, "menu ")) { + button_set_action(button, ACTION_MENU, action); + } else if (!BEG_STRCASECMP(type, "string ")) { + button_set_action(button, ACTION_STRING, action); + } else if (!BEG_STRCASECMP(type, "echo ")) { + button_set_action(button, ACTION_ECHO, action); + } else { + print_error("Parse error in file %s, line %lu: Invalid button action \"%s\"", file_peek_path(), file_peek_line(), type); + FREE(action); + FREE(button); + return ((void *) bbar); + } + FREE(action); + } else { + print_error("Parse error in file %s, line %lu: Missing button action", file_peek_path(), file_peek_line()); + FREE(button); + return ((void *) bbar); + } + if (tolower(*buff) == 'r') { + bbar_add_rbutton(bbar, button); + } else { + bbar_add_button(bbar, button); + } } else { print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " "within context menu", file_peek_path(), file_peek_line(), buff); } + return ((void *) bbar); } -void -parse_xim(char *buff) +static void * +parse_xim(char *buff, void *state) { - - ASSERT(buff != NULL); - #ifdef USE_XIM + if ((*buff == CONF_BEGIN_CHAR) || (*buff == CONF_END_CHAR)) { + return NULL; + } if (!BEG_STRCASECMP(buff, "input_method ")) { RESET_AND_ASSIGN(rs_input_method, Word(2, buff)); } else if (!BEG_STRCASECMP(buff, "preedit_type ")) { @@ -2780,15 +2974,17 @@ parse_xim(char *buff) print_warning("XIM support was not compiled in, ignoring entire context"); file_poke_skip(1); #endif + return state; + buff = NULL; } -void -parse_multichar(char *buff) +static void * +parse_multichar(char *buff, void *state) { - - ASSERT(buff != NULL); - #ifdef MULTI_CHARSET + if ((*buff == CONF_BEGIN_CHAR) || (*buff == CONF_END_CHAR)) { + return NULL; + } if (!BEG_STRCASECMP(buff, "encoding ")) { RESET_AND_ASSIGN(rs_multichar_encoding, Word(2, buff)); if (rs_multichar_encoding != NULL) { @@ -2797,7 +2993,7 @@ parse_multichar(char *buff) && BEG_STRCASECMP(rs_multichar_encoding, "euckr")) { print_error("Parse error in file %s, line %lu: Invalid multichar encoding mode \"%s\"", file_peek_path(), file_peek_line(), rs_multichar_encoding); - return; + return NULL; } set_multichar_encoding(rs_multichar_encoding); } else { @@ -2812,7 +3008,7 @@ parse_multichar(char *buff) if (NumWords(buff) != 3) { print_error("Parse error in file %s, line %lu: Invalid parameter list \"%s\" for " "attribute font", file_peek_path(), file_peek_line(), NONULL(tmp)); - return; + return NULL; } if (isdigit(*tmp)) { n = (unsigned char) strtoul(tmp, (char **) NULL, 0); @@ -2836,180 +3032,136 @@ parse_multichar(char *buff) print_warning("Multichar support was not compiled in, ignoring entire context"); file_poke_skip(1); #endif + return state; + buff = NULL; } -void -parse_undef(char *buff) -{ - - ASSERT(buff != NULL); - - print_error("Parse error in file %s, line %lu: Undefined subcontext \"%s\" within context %s", - file_peek_path(), file_peek_line(), PWord(2, buff), - ctx_id_to_name(ctx_peek_last())); - file_poke_skip(1); - -} - -/* The config file reader. This looks for the config file by searching CONFIG_SEARCH_PATH and PATH_ENV. +/* The config file reader. This looks for the config file by searching CONFIG_SEARCH_PATH. If it can't find a config file, it displays a warning but continues. -- mej */ char * -find_theme(char *path, char *theme_name, char *conf_name) -{ +conf_find_file(const char *file, const char *dir, const char *pathlist) { - register char *search_path; - register char *cur_path; - char working_path[PATH_MAX + 1]; - char *theme_dir = NULL; + static char name[PATH_MAX], full_path[PATH_MAX]; + const char *path; + char *p; + short maxpathlen; + unsigned short len; struct stat fst; - unsigned long len; - ASSERT(path != NULL && conf_name != NULL); + REQUIRE_RVAL(file != NULL, NULL); - search_path = StrDup(path); - if (theme_name) { - D_OPTIONS(("Searching for config file %s in theme %s\n", conf_name, theme_name)); + getcwd(name, PATH_MAX); + D_OPTIONS(("conf_find_file(\"%s\", \"%s\", \"%s\") called from directory \"%s\".\n", file, NONULL(dir), NONULL(pathlist), name)); + + if (dir) { + strcpy(name, dir); + strcat(name, "/"); + strcat(name, file); } else { - D_OPTIONS(("Searching for config file %s (no theme)\n", conf_name)); + strcpy(name, file); + } + len = strlen(name); + D_OPTIONS(("conf_find_file(): Checking for file \"%s\"\n", name)); + if ((!access(name, R_OK)) && (!stat(name, &fst)) && (!S_ISDIR(fst.st_mode))) { + return ((char *) name); } - for (cur_path = strtok(search_path, ":"); cur_path; cur_path = strtok((char *) NULL, ":")) { + /* maxpathlen is the longest possible path we can stuff into name[]. The - 2 saves room for + an additional / and the trailing null. */ + if ((maxpathlen = sizeof(name) - len - 2) <= 0) { + return ((char *) NULL); + } - if (!BEG_STRCASECMP(cur_path, "~/")) { - snprintf(working_path, PATH_MAX, "%s/%s/%s%s%s", getenv("HOME"), cur_path + 2, (theme_name ? theme_name : ""), (theme_name ? "/" : ""), conf_name); + for (path = pathlist; path != NULL && *path != '\0'; path = p) { + short n; + + /* Calculate the length of the next directory in the path */ + if ((p = strchr(path, ':')) != NULL) { + n = p++ - path; } else { - snprintf(working_path, PATH_MAX, "%s/%s%s%s", cur_path, (theme_name ? theme_name : ""), (theme_name ? "/" : ""), conf_name); + n = strlen(path); } - D_OPTIONS(("Checking for a valid config file at \"%s\"\n", working_path)); - if (!access(working_path, R_OK)) { - stat(working_path, &fst); - if (!S_ISDIR(fst.st_mode)) { - if (open_config_file(working_path)) { - len = strlen(working_path) - strlen(conf_name); - theme_dir = (char *) MALLOC(len); - snprintf(theme_dir, len, "%s", working_path); - if (theme_name) { - D_OPTIONS(("Found config file %s in theme %s at %s\n", conf_name, theme_name, theme_dir)); - } else { - D_OPTIONS(("Found config file %s at %s\n", conf_name, theme_dir)); - } - break; - } else { - D_OPTIONS((" -> Not a valid config file.\n")); - } - } else { - D_OPTIONS((" -> That is a directory.\n")); + /* Don't try if it's too long */ + if (n > 0 && n <= maxpathlen) { + /* Compose the /path/file combo */ + strncpy(full_path, path, n); + if (full_path[n - 1] != '/') { + full_path[n++] = '/'; + } + full_path[n] = '\0'; + strcat(full_path, name); + + D_OPTIONS(("conf_find_file(): Checking for file \"%s\"\n", full_path)); + if ((!access(full_path, R_OK)) && (!stat(full_path, &fst)) && (!S_ISDIR(fst.st_mode))) { + return ((char *) full_path); } - } else { - D_OPTIONS((" -> Read access forbidden -- %s\n", strerror(errno))); } } - FREE(search_path); - return (theme_dir); + D_OPTIONS(("conf_find_file(): File \"%s\" not found in path.\n", name)); + return ((char *) NULL); } -unsigned char +FILE * open_config_file(char *name) { FILE *fp; int ver; - char buff[256], *end_ptr; + char buff[256], *begin_ptr, *end_ptr; ASSERT(name != NULL); fp = fopen(name, "rt"); if (fp != NULL) { fgets(buff, 256, fp); - D_OPTIONS(("Magic line \"%s\" [%s] VERSION == \"%s\" size == %lu\n", buff, buff + 7, VERSION, sizeof(VERSION) - 1)); - if (BEG_STRCASECMP(buff, "')) != NULL) { *end_ptr = 0; } - if ((ver = BEG_STRCASECMP(buff + 7, VERSION)) > 0) { - print_warning("Config file is designed for a newer version of Eterm"); -#ifdef WARN_OLDER - } else if (ver < 0) { - print_warning("Config file is designed for an older version of Eterm"); -#endif + if ((ver = BEG_STRCASECMP(begin_ptr, VERSION)) > 0) { + print_warning("Config file is designed for a newer version of " PACKAGE); } } } - file_poke_fp(fp); - return ((unsigned char) (fp == NULL ? 0 : 1)); + return (fp); } -void -read_config(char *conf_name) -{ +char * +conf_parse(char *conf_name, const char *dir, const char *path) { - register char *search_path; - char *path_env, *desc, *outfile; - char buff[CONFIG_BUFF]; - char *root = NULL; + FILE *fp; + char *name = NULL, *outfile, *p; + char buff[CONFIG_BUFF], orig_dir[PATH_MAX]; register unsigned long i = 0; - static char first_time = 1; - unsigned char id = CTX_UNDEF; - file_state fs = - {NULL, NULL, NULL, 1, 0}; + unsigned char id = 0; + void *state = NULL; - D_OPTIONS(("read_config(conf_name [%s]) called.\n", conf_name)); - path_env = getenv(PATH_ENV); - if (path_env) - i += strlen(path_env); - i += sizeof(CONFIG_SEARCH_PATH) + 3; - search_path = (char *) MALLOC(i); - snprintf(search_path, i, "%s%s%s", CONFIG_SEARCH_PATH, (path_env ? ":" : ""), (path_env ? path_env : "")); - file_push(fs); + REQUIRE_RVAL(conf_name != NULL, 0); - if (rs_theme) { - root = find_theme(search_path, rs_theme, conf_name); - } - if (root == NULL) { - root = find_theme(search_path, "Eterm", conf_name); - if (root == NULL) { - root = find_theme(search_path, "DEFAULT", conf_name); - if (root == NULL) { - root = find_theme(search_path, (char *) NULL, conf_name); - if (rs_theme != NULL) { - FREE(rs_theme); - rs_theme = NULL; - } + *orig_dir = 0; + if (path) { + if ((name = conf_find_file(conf_name, dir, path)) != NULL) { + if ((p = strrchr(name, '/')) != NULL) { + getcwd(orig_dir, PATH_MAX); + *p = 0; + chdir(name); } + } else { + return NULL; } } - FREE(search_path); - if (root == NULL) { - D_OPTIONS((" -> Config file search failed.\n")); - if (first_time) { - print_error("Unable to find/open config file %s. Continuing with defaults.", conf_name); - } - return; + if ((fp = open_config_file(conf_name)) == NULL) { + return NULL; } - D_OPTIONS((" -> Config file search succeeded with root == %s\n", root)); - if (first_time) { - theme_dir = root; - root = (char *) MALLOC(strlen(theme_dir) + 17 + 1); - sprintf(root, "ETERM_THEME_ROOT=%s", theme_dir); - putenv(root); - chdir(theme_dir); - } else { - user_dir = root; - root = (char *) MALLOC(strlen(theme_dir) + 16 + 1); - sprintf(root, "ETERM_USER_ROOT=%s", theme_dir); - putenv(root); - chdir(user_dir); - } - first_time = 0; + file_push(fp, conf_name, NULL, 1, 0); /* Line count starts at 1 because open_config_file() parses the first line */ - file_poke_path(conf_name); - ctx_poke(0); - for (; cur_file >= 0;) { + for (; fstate_idx > 0;) { for (; fgets(buff, CONFIG_BUFF, file_peek_fp());) { file_inc_line(); if (!strchr(buff, '\n')) { @@ -3028,18 +3180,17 @@ read_config(char *conf_name) case '%': D_OPTIONS(("read_config(): Parsing line #%lu of file %s\n", file_peek_line(), file_peek_path())); if (!BEG_STRCASECMP(PWord(1, buff + 1), "include ")) { + char *path; + FILE *fp; + shell_expand(buff); - fs.path = Word(2, buff + 1); - fs.outfile = (char *) NULL; - fs.line = 1; - fs.flags = 0; - file_push(fs); - if (!open_config_file(fs.path)) { - print_error("Error in file %s, line %lu: Unable to locate %%included config file %s " - "(%s), continuing", file_peek_path(), file_peek_line(), fs.path, - strerror(errno)); - file_pop(); - } + path = Word(2, buff + 1); + if ((fp = open_config_file(path)) == NULL) { + print_error("Error in file %s, line %lu: Unable to locate %%included config file %s (%s), continuing", file_peek_path(), file_peek_line(), + path, strerror(errno)); + } else { + file_push(fp, path, NULL, 1, 0); + } } else if (!BEG_STRCASECMP(PWord(1, buff + 1), "preproc ")) { char cmd[PATH_MAX]; FILE *fp; @@ -3063,60 +3214,45 @@ read_config(char *conf_name) break; case 'b': D_OPTIONS(("read_config(): Parsing line #%lu of file %s\n", file_peek_line(), file_peek_path())); - if (file_peek_skip()) + if (file_peek_skip()) { continue; + } if (!BEG_STRCASECMP(buff, "begin ")) { - desc = PWord(2, buff); - ctx_name_to_id(id, desc, i); - if (id == CTX_UNDEF) { - ctx_push(id); - parse_undef(buff); - } else { - if (ctx_peek()) { - for (i = 0; i <= CTX_MAX; i++) { - if (contexts[ctx_peek()].valid_sub_contexts[i]) { - if (contexts[ctx_peek()].valid_sub_contexts[i] == id) { - ctx_push(id); - break; - } - } else { - print_error("Parse error in file %s, line %lu: subcontext %s is not valid " - "within context %s", file_peek_path(), file_peek_line(), - contexts[id].description, contexts[ctx_peek()].description); - break; - } - } - } else if (id != CTX_MAIN) { - print_error("Parse error in file %s, line %lu: subcontext %s is not valid " - "outside context main", file_peek_path(), file_peek_line(), - contexts[id].description); - break; - } else { - ctx_push(id); - } - } - break; - } + name = PWord(2, buff); + ctx_name_to_id(id, name, i); + ctx_push(id); + *buff = CONF_BEGIN_CHAR; + state = (*ctx_id_to_func(id))(buff, ctx_peek_last_state()); + ctx_poke_state(state); + break; + } + /* Intentional pass-through */ case 'e': - D_OPTIONS(("read_config(): Parsing line #%lu of file %s\n", file_peek_line(), file_peek_path())); + if (*buff != 'b') { + D_OPTIONS(("read_config(): Parsing line #%lu of file %s\n", file_peek_line(), file_peek_path())); + } if (!BEG_STRCASECMP(buff, "end ") || !strcasecmp(buff, "end")) { if (ctx_get_depth()) { - (void) ctx_pop(); + *buff = CONF_END_CHAR; + state = (*ctx_id_to_func(id))(buff, ctx_peek_state()); + ctx_poke_state(NULL); + ctx_pop(); + id = ctx_peek_id(); + ctx_poke_state(state); file_poke_skip(0); } break; } + /* Intentional pass-through */ default: - D_OPTIONS(("read_config(): Parsing line #%lu of file %s\n", file_peek_line(), file_peek_path())); - if (file_peek_skip()) + if (*buff != 'b' && *buff != 'e') { + D_OPTIONS(("read_config(): Parsing line #%lu of file %s\n", file_peek_line(), file_peek_path())); + } + if (file_peek_skip()) { continue; - if ((id = ctx_peek())) { - shell_expand(buff); - (*ctx_id_to_func(id)) (buff); - } else { - print_error("Parse error in file %s, line %lu: No established context to parse \"%s\"", - file_peek_path(), file_peek_line(), buff); - } + } + shell_expand(buff); + ctx_poke_state((*ctx_id_to_func(id))(buff, ctx_peek_state())); } } fclose(file_peek_fp()); @@ -3125,6 +3261,53 @@ read_config(char *conf_name) } file_pop(); } + if (*orig_dir) { + chdir(orig_dir); + } + return (StrDup(name)); +} + +char * +conf_parse_theme(char *theme, char *conf_name, unsigned char fallback) +{ + static char path[CONFIG_BUFF]; + char *ret = NULL; + + if (!(*path)) { + char *path_env; + + path_env = getenv(PATH_ENV); + if (path_env) { + strcpy(path, CONFIG_SEARCH_PATH ":"); + strcat(path, path_env); + } else { + strcpy(path, CONFIG_SEARCH_PATH); + } + shell_expand(path); + } + if (!theme || (ret = conf_parse(conf_name, rs_theme, path)) == NULL) { + if (fallback) { + RESET_AND_ASSIGN(rs_theme, StrDup(PACKAGE)); + if ((ret = conf_parse(conf_name, rs_theme, path)) == NULL) { + RESET_AND_ASSIGN(rs_theme, NULL); + ret = conf_parse(conf_name, rs_theme, path); + } + } + } + return ret; +} + +static void * +parse_null(char *buff, void *state) { + + if (*buff == CONF_BEGIN_CHAR) { + return (NULL); + } else if (*buff == CONF_END_CHAR) { + return (NULL); + } else { + print_error("Parse error in file %s, line %lu: Not allowed in \"null\" context: \"%s\"", file_peek_path(), file_peek_line(), buff); + return (state); + } } /* Initialize the default values for everything */ @@ -3262,28 +3445,82 @@ post_parse(void) /* Clean up image stuff */ for (i = 0; i < image_max; i++) { - if (!(images[i].norm)) { + if (images[i].norm) { + /* If we have a bevel but no border, use the bevel as a border. */ + if (images[i].norm->iml->bevel && !(images[i].norm->iml->border)) { + images[i].norm->iml->border = images[i].norm->iml->bevel->edges; + } + images[i].userdef = 1; + } else { images[i].norm = (simage_t *) MALLOC(sizeof(simage_t)); images[i].norm->pmap = (pixmap_t *) MALLOC(sizeof(pixmap_t)); images[i].norm->iml = (imlib_t *) MALLOC(sizeof(imlib_t)); + images[i].norm->fg = WhitePixel(Xdisplay, Xscreen); + images[i].norm->bg = BlackPixel(Xdisplay, Xscreen); MEMSET(images[i].norm->pmap, 0, sizeof(pixmap_t)); MEMSET(images[i].norm->iml, 0, sizeof(imlib_t)); images[i].mode = MODE_IMAGE & ALLOW_IMAGE; } images[i].current = images[i].norm; if (rs_pixmaps[i]) { - reset_simage(images[i].norm, RESET_ALL); - load_image(rs_pixmaps[i], i); + reset_simage(images[i].norm, RESET_ALL_SIMG); + load_image(rs_pixmaps[i], images[i].norm); FREE(rs_pixmaps[i]); /* These are created by StrDup() */ } - if (!(images[i].selected)) { - D_PIXMAP(("post_parse(): No \"selected\" state for image %s. Setting fallback to the normal state.\n", get_image_type(i))); + if (images[i].selected) { + /* If we have a bevel but no border, use the bevel as a border. */ + if (images[i].selected->iml->bevel && !(images[i].selected->iml->border)) { + images[i].selected->iml->border = images[i].selected->iml->bevel->edges; + } + /* If normal has an image but we don't, copy it. */ + if (!(images[i].selected->iml->im) && (images[i].norm->iml->im)) { + images[i].selected->iml->im = images[i].norm->iml->im; + *(images[i].selected->pmap) = *(images[i].norm->pmap); + } + if (images[i].selected->fg == 0 && images[i].selected->bg == 0) { + images[i].selected->fg = images[i].norm->fg; + images[i].selected->bg = images[i].norm->bg; + } + } else { + D_PIXMAP(("No \"selected\" state for image %s. Setting fallback to the normal state.\n", get_image_type(i))); images[i].selected = images[i].norm; } - if (!(images[i].clicked)) { - D_PIXMAP(("post_parse(): No \"clicked\" state for image %s. Setting fallback to the normal state.\n", get_image_type(i))); + if (images[i].clicked) { + /* If we have a bevel but no border, use the bevel as a border. */ + if (images[i].clicked->iml->bevel && !(images[i].clicked->iml->border)) { + images[i].clicked->iml->border = images[i].clicked->iml->bevel->edges; + } + /* If normal has an image but we don't, copy it. */ + if (!(images[i].clicked->iml->im) && (images[i].norm->iml->im)) { + images[i].clicked->iml->im = images[i].norm->iml->im; + *(images[i].clicked->pmap) = *(images[i].norm->pmap); + } + if (images[i].clicked->fg == 0 && images[i].clicked->bg == 0) { + images[i].clicked->fg = images[i].norm->fg; + images[i].clicked->bg = images[i].norm->bg; + } + } else { + D_PIXMAP(("No \"clicked\" state for image %s. Setting fallback to the selected state.\n", get_image_type(i))); images[i].clicked = images[i].selected; } + if (images[i].disabled) { + /* If we have a bevel but no border, use the bevel as a border. */ + if (images[i].disabled->iml->bevel && !(images[i].disabled->iml->border)) { + images[i].disabled->iml->border = images[i].disabled->iml->bevel->edges; + } + /* If normal has an image but we don't, copy it. */ + if (!(images[i].disabled->iml->im) && (images[i].norm->iml->im)) { + images[i].disabled->iml->im = images[i].norm->iml->im; + *(images[i].disabled->pmap) = *(images[i].norm->pmap); + } + if (images[i].disabled->fg == 0 && images[i].disabled->bg == 0) { + images[i].disabled->fg = images[i].norm->fg; + images[i].disabled->bg = images[i].norm->bg; + } + } else { + D_PIXMAP(("No \"disabled\" state for image %s. Setting fallback to the normal state.\n", get_image_type(i))); + images[i].disabled = images[i].norm; + } if ((image_toggles & IMOPT_TRANS) && (image_mode_is(i, ALLOW_TRANS))) { D_PIXMAP(("Detected transparency option. Enabling transparency on image %s\n", get_image_type(i))); image_set_mode(i, MODE_TRANS); @@ -3292,6 +3529,14 @@ post_parse(void) image_set_mode(i, MODE_VIEWPORT); } } + if (images[image_bg].norm->fg || images[image_bg].norm->bg) { + /* They specified their colors here, so copy them to the right place. */ + PixColors[fgColor] = images[image_bg].norm->fg; + PixColors[bgColor] = images[image_bg].norm->bg; + } + + /* Update buttonbar sizes based on new imageclass info. */ + bbar_resize_all(-1); if (rs_cmod_image) { unsigned char n = NumWords(rs_cmod_image); @@ -3354,23 +3599,6 @@ post_parse(void) FREE(rs_cmod_blue); } -#ifdef XTERM_REVERSE_VIDEO - /* this is how xterm implements reverseVideo */ - if (Options & Opt_reverseVideo) { - if (!rs_color[fgColor]) - rs_color[fgColor] = def_colorName[bgColor]; - if (!rs_color[bgColor]) - rs_color[bgColor] = def_colorName[fgColor]; - } -#endif - - for (i = 0; i < NRS_COLORS; i++) { - if (!rs_color[i]) - rs_color[i] = def_colorName[i]; - } - -#ifndef XTERM_REVERSE_VIDEO - /* this is how we implement reverseVideo */ if (Options & Opt_reverseVideo) { char *tmp; @@ -3384,21 +3612,6 @@ post_parse(void) def_colorName[fgColor] = def_colorName[bgColor]; def_colorName[bgColor] = tmp; } -#endif - - /* convenient aliases for setting fg/bg to colors */ - color_aliases(fgColor); - color_aliases(bgColor); -#ifndef NO_CURSORCOLOR - color_aliases(cursorColor); - color_aliases(cursorColor2); -#endif /* NO_CURSORCOLOR */ -#ifndef NO_BOLDUNDERLINE - color_aliases(colorBD); - color_aliases(colorUL); -#endif /* NO_BOLDUNDERLINE */ - color_aliases(pointerColor); - color_aliases(borderColor); if (rs_meta_mod) { MetaMask = modmasks[rs_meta_mod - 1]; @@ -3570,15 +3783,21 @@ save_config(char *path) for (i = 0; i < image_max; i++) { fprintf(fp, " begin image\n"); switch (i) { - case image_bg: fprintf(fp, " type background\n"); break; - case image_sb: fprintf(fp, " type trough\n"); break; - case image_sa: fprintf(fp, " type anchor\n"); break; - case image_up: fprintf(fp, " type up_arrow\n"); break; - case image_down: fprintf(fp, " type down_arrow\n"); break; - case image_left: fprintf(fp, " type left_arrow\n"); break; - case image_right: fprintf(fp, " type right_arrow\n"); break; - case image_menu: fprintf(fp, " type menu\n"); break; - case image_submenu: fprintf(fp, " type submenu\n"); break; + case image_bg: fprintf(fp, " type background\n"); break; + case image_sb: fprintf(fp, " type trough\n"); break; + case image_sa: fprintf(fp, " type anchor\n"); break; + case image_st: fprintf(fp, " type thumb\n"); break; + case image_up: fprintf(fp, " type up_arrow\n"); break; + case image_down: fprintf(fp, " type down_arrow\n"); break; + case image_left: fprintf(fp, " type left_arrow\n"); break; + case image_right: fprintf(fp, " type right_arrow\n"); break; + case image_menu: fprintf(fp, " type menu\n"); break; + case image_menuitem: fprintf(fp, " type menuitem\n"); break; + case image_submenu: fprintf(fp, " type submenu\n"); break; + case image_button: fprintf(fp, " type button\n"); break; + case image_bbar: fprintf(fp, " type button_bar\n"); break; + case image_gbar: fprintf(fp, " type grab_bar\n"); break; + case image_dialog: fprintf(fp, " type dialog\n"); break; } fprintf(fp, " mode "); switch (images[i].mode & MODE_MASK) { @@ -3608,6 +3827,9 @@ save_config(char *path) /* Now save each state. */ simg = images[i].norm; fprintf(fp, " state normal\n"); + if (simg->fg || simg->bg) { + fprintf(fp, " color 0x%08x 0x%08x\n", (unsigned int) simg->fg, (unsigned int) simg->bg); + } if (simg->iml->im) { fprintf(fp, " file %s\n", NONULL(simg->iml->im->filename)); } @@ -3652,6 +3874,9 @@ save_config(char *path) if (images[i].selected != images[i].norm) { simg = images[i].selected; fprintf(fp, " state selected\n"); + if (simg->fg || simg->bg) { + fprintf(fp, " color 0x%08x 0x%08x\n", (unsigned int) simg->fg, (unsigned int) simg->bg); + } if (simg->iml->im) { fprintf(fp, " file %s\n", NONULL(simg->iml->im->filename)); } @@ -3697,6 +3922,57 @@ save_config(char *path) if (images[i].clicked != images[i].norm) { simg = images[i].clicked; fprintf(fp, " state clicked\n"); + if (simg->fg || simg->bg) { + fprintf(fp, " color 0x%08x 0x%08x\n", (unsigned int) simg->fg, (unsigned int) simg->bg); + } + if (simg->iml->im) { + fprintf(fp, " file %s\n", NONULL(simg->iml->im->filename)); + } + fprintf(fp, " geom %hdx%hd+%hd+%hd", simg->pmap->w, simg->pmap->h, simg->pmap->x, simg->pmap->y); + if (simg->pmap->op & OP_TILE) { + fprintf(fp, ":tiled"); + } + if ((simg->pmap->op & OP_SCALE) || ((simg->pmap->op & OP_HSCALE) && (simg->pmap->op & OP_VSCALE))) { + fprintf(fp, ":scaled"); + } else if (simg->pmap->op & OP_HSCALE) { + fprintf(fp, ":hscaled"); + } else if (simg->pmap->op & OP_VSCALE) { + fprintf(fp, ":vscaled"); + } + if (simg->pmap->op & OP_PROPSCALE) { + fprintf(fp, ":propscaled"); + } + fprintf(fp, "\n"); + if (simg->iml->mod) { + fprintf(fp, " colormod image 0x%02x 0x%02x 0x%02x\n", simg->iml->mod->brightness, simg->iml->mod->contrast, simg->iml->mod->gamma); + } + if (simg->iml->rmod) { + fprintf(fp, " colormod red 0x%02x 0x%02x 0x%02x\n", simg->iml->rmod->brightness, simg->iml->rmod->contrast, simg->iml->rmod->gamma); + } + if (simg->iml->gmod) { + fprintf(fp, " colormod green 0x%02x 0x%02x 0x%02x\n", simg->iml->gmod->brightness, simg->iml->gmod->contrast, simg->iml->gmod->gamma); + } + if (simg->iml->bmod) { + fprintf(fp, " colormod blue 0x%02x 0x%02x 0x%02x\n", simg->iml->bmod->brightness, simg->iml->bmod->contrast, simg->iml->bmod->gamma); + } + if (simg->iml->border) { + fprintf(fp, " border %hu %hu %hu %hu\n", simg->iml->border->left, simg->iml->border->right, simg->iml->border->top, simg->iml->border->bottom); + } + if (simg->iml->bevel) { + fprintf(fp, " bevel %s %hu %hu %hu %hu\n", ((simg->iml->bevel->up) ? "up" : "down"), simg->iml->bevel->edges->left, simg->iml->bevel->edges->right, simg->iml->bevel->edges->top, simg->iml->bevel->edges->bottom); + } + if (simg->iml->pad) { + fprintf(fp, " padding %hu %hu %hu %hu\n", simg->iml->pad->left, simg->iml->pad->right, simg->iml->pad->top, simg->iml->pad->bottom); + } + } + + /* Disabled state */ + if (images[i].disabled != images[i].norm) { + simg = images[i].disabled; + fprintf(fp, " state disabled\n"); + if (simg->fg || simg->bg) { + fprintf(fp, " color 0x%08x 0x%08x\n", (unsigned int) simg->fg, (unsigned int) simg->bg); + } if (simg->iml->im) { fprintf(fp, " file %s\n", NONULL(simg->iml->im->filename)); } @@ -3877,9 +4153,8 @@ save_config(char *path) fprintf(fp, " utmp_logging %d\n", (Options & Opt_utmpLogging ? 1 : 0)); fprintf(fp, " meta8 %d\n", (Options & Opt_meta8 ? 1 : 0)); fprintf(fp, " iconic %d\n", (Options & Opt_iconic ? 1 : 0)); - fprintf(fp, " home_on_echo %d\n", (Options & Opt_homeOnEcho ? 1 : 0)); - fprintf(fp, " home_on_input %d\n", (Options & Opt_homeOnInput ? 1 : 0)); - fprintf(fp, " home_on_refresh %d\n", (Options & Opt_homeOnRefresh ? 1 : 0)); + fprintf(fp, " home_on_output %d\n", (Options & Opt_home_on_output ? 1 : 0)); + fprintf(fp, " home_on_input %d\n", (Options & Opt_home_on_input ? 1 : 0)); fprintf(fp, " scrollbar_floating %d\n", (Options & Opt_scrollbar_floating ? 1 : 0)); fprintf(fp, " scrollbar_right %d\n", (Options & Opt_scrollbar_right ? 1 : 0)); fprintf(fp, " scrollbar_popup %d\n", (Options & Opt_scrollbar_popup ? 1 : 0)); diff --git a/src/options.h b/src/options.h index 46328c9..5174914 100644 --- a/src/options.h +++ b/src/options.h @@ -28,51 +28,55 @@ #include /* Xlib, Xutil, Xresource, Xfuncproto */ /************ Macros and Definitions ************/ -#define OPT_BOOLEAN 0x0001 -#define OPT_INTEGER 0x0002 -#define OPT_STRING 0x0004 -#define OPT_ARGUMENT 0x0008 - -#define OPT_STR(s, l, d, p) { s, l, "(str) " d, OPT_STRING, (const char **) p, 0, 0 } -#define OPT_INT(s, l, d, p) { s, l, "(int) " d, OPT_INTEGER, (const int *) p, 0, 0 } -#define OPT_BOOL(s, l, d, v, m) { s, l, "(bool) " d, OPT_BOOLEAN, NULL, v, m } -#define OPT_LONG(l, d, p) { 0, l, "(str) " d, OPT_STRING, (const char **) p, 0, 0 } -#define OPT_ARGS(s, l, d, p) { s, l, "(str) " d, OPT_ARGUMENT, (const char ***) p, 0, 0 } -#define OPT_BLONG(l, d, v, m) { 0, l, "(bool) " d, OPT_BOOLEAN, NULL, v, m } -#define OPT_ILONG(l, d, p) { 0, l, "(int) " d, OPT_INTEGER, (const int *) p, 0, 0 } -#define optList_numoptions() (sizeof(optList)/sizeof(optList[0])) - -#if PATH_MAX < 1024 +#if defined(PATH_MAX) && (PATH_MAX < 255) # undef PATH_MAX -# define PATH_MAX 1024 +#endif +#ifndef PATH_MAX +# define PATH_MAX 255 #endif -# define Opt_console (1LU << 0) -# define Opt_loginShell (1LU << 1) -# define Opt_iconic (1LU << 2) -# define Opt_visualBell (1LU << 3) -# define Opt_mapAlert (1LU << 4) -# define Opt_reverseVideo (1LU << 5) -# define Opt_utmpLogging (1LU << 6) -# define Opt_scrollbar (1LU << 7) -# define Opt_meta8 (1LU << 8) -# define Opt_exec (1LU << 9) -# define Opt_homeOnEcho (1LU << 10) -# define Opt_homeOnRefresh (1LU << 11) -# define Opt_scrollbar_right (1LU << 12) -# define Opt_borderless (1LU << 13) -# define Opt_backing_store (1LU << 14) -# define Opt_noCursor (1LU << 15) -# define Opt_pause (1LU << 16) -# define Opt_homeOnInput (1LU << 17) -# define Opt_report_as_keysyms (1LU << 18) -# define Opt_xterm_select (1LU << 19) -# define Opt_select_whole_line (1LU << 20) -# define Opt_scrollbar_popup (1LU << 21) -# define Opt_select_trailing_spaces (1LU << 22) -# define Opt_install (1LU << 23) -# define Opt_scrollbar_floating (1LU << 24) -# define Opt_double_buffer (1LU << 25) +#define CONF_BEGIN_CHAR ((char) 1) +#define CONF_END_CHAR ((char) 2) + +#define OPT_BOOLEAN 0x0001 +#define OPT_INTEGER 0x0002 +#define OPT_STRING 0x0004 +#define OPT_ARGUMENT 0x0008 + +#define OPT_STR(s, l, d, p) { s, l, "(str) " d, OPT_STRING, (const char **) p, 0, 0 } +#define OPT_INT(s, l, d, p) { s, l, "(int) " d, OPT_INTEGER, (const int *) p, 0, 0 } +#define OPT_BOOL(s, l, d, v, m) { s, l, "(bool) " d, OPT_BOOLEAN, NULL, v, m } +#define OPT_LONG(l, d, p) { 0, l, "(str) " d, OPT_STRING, (const char **) p, 0, 0 } +#define OPT_ARGS(s, l, d, p) { s, l, "(str) " d, OPT_ARGUMENT, (const char ***) p, 0, 0 } +#define OPT_BLONG(l, d, v, m) { 0, l, "(bool) " d, OPT_BOOLEAN, NULL, v, m } +#define OPT_ILONG(l, d, p) { 0, l, "(int) " d, OPT_INTEGER, (const int *) p, 0, 0 } +#define optList_numoptions() (sizeof(optList)/sizeof(optList[0])) + +# define Opt_console (1LU << 0) +# define Opt_loginShell (1LU << 1) +# define Opt_iconic (1LU << 2) +# define Opt_visualBell (1LU << 3) +# define Opt_mapAlert (1LU << 4) +# define Opt_reverseVideo (1LU << 5) +# define Opt_utmpLogging (1LU << 6) +# define Opt_scrollbar (1LU << 7) +# define Opt_meta8 (1LU << 8) +# define Opt_exec (1LU << 9) +# define Opt_home_on_output (1LU << 10) +# define Opt_scrollbar_right (1LU << 11) +# define Opt_borderless (1LU << 12) +# define Opt_backing_store (1LU << 13) +# define Opt_noCursor (1LU << 14) +# define Opt_pause (1LU << 15) +# define Opt_home_on_input (1LU << 16) +# define Opt_report_as_keysyms (1LU << 17) +# define Opt_xterm_select (1LU << 18) +# define Opt_select_whole_line (1LU << 19) +# define Opt_scrollbar_popup (1LU << 20) +# define Opt_select_trailing_spaces (1LU << 21) +# define Opt_install (1LU << 22) +# define Opt_scrollbar_floating (1LU << 23) +# define Opt_double_buffer (1LU << 24) # define IMOPT_TRANS (1U << 0) # define IMOPT_VIEWPORT (1U << 1) @@ -87,96 +91,63 @@ #define BAD_THRESHOLD 3 #define CHECK_BAD() do { \ if (++bad_opts >= BAD_THRESHOLD) { \ - print_error("error threshold exceeded, giving up"); \ + print_error("Error threshold exceeded, giving up."); \ usage(); \ } else { \ - print_error("attempting to continue, but performance may be unpredictable"); \ + print_error("Attempting to continue, but strange things may happen."); \ } \ } while(0) /* Max length of a line in the config file */ #define CONFIG_BUFF 20480 -/* The context identifier. This tells us what section of the config file - we're in, for syntax checking purposes and the like. -- mej */ - -enum { - CTX_NULL, - CTX_MAIN, - CTX_COLOR, - CTX_ATTRIBUTES, - CTX_TOGGLES, - CTX_KEYBOARD, - CTX_MISC, - CTX_IMAGECLASSES, - CTX_IMAGE, - CTX_ACTIONS, - CTX_MENU, - CTX_MENUITEM, - CTX_XIM, - CTX_MULTI_CHARSET, - CTX_MAX = CTX_MULTI_CHARSET, - CTX_UNDEF -}; - +/* The context table */ #define ctx_name_to_id(the_id, n, i) do { \ - for ((i)=0; (i) <= CTX_MAX; (i)++) { \ - if (!strcasecmp((n), contexts[(i)].description)) { \ - (the_id) = contexts[(i)].id; \ + for ((i)=0; (i) <= ctx_idx; (i)++) { \ + if (!strcasecmp((n), context[(i)].name)) { \ + (the_id) = (i); \ break; \ } \ } \ - if ((i) > CTX_MAX) (the_id) = CTX_UNDEF; \ + if ((i) > ctx_idx) (the_id) = 0; \ } while (0) +#define ctx_id_to_name(id) (context[(id)].name) +#define ctx_id_to_func(id) (context[(id)].handler) -#define ctx_id_to_name(id) (contexts[(id)].description) -#define ctx_id_to_func(id) (contexts[(id)].ctx_handler) +/* The context state stack. This keeps track of the current context and each previous one. */ +#define ctx_push(ctx) conf_register_context_state(ctx) +#define ctx_pop() (ctx_state_idx--) +#define ctx_peek() (ctx_state[ctx_state_idx]) +#define ctx_peek_id() (ctx_state[ctx_state_idx].ctx_id) +#define ctx_peek_state() (ctx_state[ctx_state_idx].state) +#define ctx_peek_last_id() (ctx_state[(ctx_state_idx?ctx_state_idx-1:0)].ctx_id) +#define ctx_peek_last_state() (ctx_state[(ctx_state_idx?ctx_state_idx-1:0)].state) +#define ctx_poke_state(q) ((ctx_state[ctx_state_idx].state) = (q)) +#define ctx_get_depth() (ctx_state_idx) -/* The context stack. This keeps track of the current context and each - previous one. You MUST define MAX_CTX_DEPTH to the absolute maximum - number of context levels deep your contexts go, or the results can be - Very Bad. I recommend erring on the side of caution. -- mej */ +/* The file state stack */ +#define FILE_SKIP_TO_END (0x01) +#define FILE_PREPROC (0x02) +#define file_push(f, p, o, l, fl) conf_register_fstate(f, p, o, l, fl) +#define file_pop() (fstate_idx--) +#define file_peek() (fstate[fstate_idx]) +#define file_peek_fp() (fstate[fstate_idx].fp) +#define file_peek_path() (fstate[fstate_idx].path) +#define file_peek_outfile() (fstate[fstate_idx].outfile) +#define file_peek_line() (fstate[fstate_idx].line) +#define file_peek_skip() (fstate[fstate_idx].flags & FILE_SKIP_TO_END) +#define file_peek_preproc() (fstate[fstate_idx].flags & FILE_PREPROC) -#define MAX_CTX_DEPTH 10 -#define ctx_push(ctx) id_stack[++cur_ctx] = (ctx) -#define ctx_pop() (id_stack[cur_ctx--]) -#define ctx_peek() (id_stack[cur_ctx]) -#define ctx_poke(c) (id_stack[cur_ctx] = (c)) -#define ctx_peek_last() (id_stack[(cur_ctx?cur_ctx-1:0)]) -#define ctx_get_depth() (cur_ctx) -#define MAX_FILE_DEPTH 10 -#define FILE_SKIP_TO_END (0x01) -#define FILE_PREPROC (0x02) -#define file_push(fs) do { \ - cur_file++; \ - file_stack[cur_file].fp = (fs).fp; \ - file_stack[cur_file].path = (fs).path; \ - file_stack[cur_file].line = (fs).line; \ - file_stack[cur_file].flags = (fs).flags; \ - } while (0) +#define file_poke_fp(f) ((fstate[fstate_idx].fp) = (f)) +#define file_poke_path(p) ((fstate[fstate_idx].path) = (p)) +#define file_poke_outfile(o) ((fstate[fstate_idx].outfile) = (o)) +#define file_poke_line(l) ((fstate[fstate_idx].line) = (l)) +#define file_skip_to_end() ((fstate[fstate_idx].flags) |= (FILE_SKIP_TO_END)) +#define file_poke_skip(s) do {if (s) {fstate[fstate_idx].flags |= FILE_SKIP_TO_END;} else {fstate[fstate_idx].flags &= ~(FILE_SKIP_TO_END);} } while (0) +#define file_poke_preproc(s) do {if (s) {fstate[fstate_idx].flags |= FILE_PREPROC;} else {fstate[fstate_idx].flags &= ~(FILE_PREPROC);} } while (0) +#define file_poke(f, p, o, l, fl) do {file_poke_fp(f); file_poke_path(p); file_poke_outfile(o); file_poke_line(l); fstate[fstate_idx].flags = (fl);} while (0) -#define file_pop() (cur_file--) -#define file_peek(fs) do { \ - (fs).fp = file_stack[cur_file].fp; \ - (fs).path = file_stack[cur_file].path; \ - (fs).line = file_stack[cur_file].line; \ - (fs).flags = file_stack[cur_file].flags; \ - } while (0) -#define file_peek_fp() (file_stack[cur_file].fp) -#define file_peek_path() (file_stack[cur_file].path) -#define file_peek_outfile() (file_stack[cur_file].outfile) -#define file_peek_line() (file_stack[cur_file].line) -#define file_peek_skip() (file_stack[cur_file].flags & FILE_SKIP_TO_END) -#define file_peek_preproc() (file_stack[cur_file].flags & FILE_PREPROC) - -#define file_poke_fp(f) ((file_stack[cur_file].fp) = (f)) -#define file_poke_path(p) ((file_stack[cur_file].path) = (p)) -#define file_poke_outfile(p) ((file_stack[cur_file].outfile) = (p)) -#define file_poke_line(l) ((file_stack[cur_file].line) = (l)) -#define file_poke_skip(s) do {if (s) {file_stack[cur_file].flags |= FILE_SKIP_TO_END;} else {file_stack[cur_file].flags &= ~(FILE_SKIP_TO_END);} } while (0) -#define file_poke_preproc(s) do {if (s) {file_stack[cur_file].flags |= FILE_PREPROC;} else {file_stack[cur_file].flags &= ~(FILE_PREPROC);} } while (0) - -#define file_inc_line() (file_stack[cur_file].line++) +#define file_inc_line() (fstate[fstate_idx].line++) #define to_keysym(p,s) do { KeySym sym; \ if (s && ((sym = XStringToKeysym(s)) != 0)) *p = sym; \ @@ -185,24 +156,35 @@ enum { #define RESET_AND_ASSIGN(var, val) do {if ((var) != NULL) FREE(var); (var) = (val);} while (0) /************ Structures ************/ -/* The file state stack. This keeps track of the file currently being - parsed. This allows for %include directives. -- mej */ +/* Contexts */ +typedef void * (*ctx_handler_t)(char *, void *); +typedef struct context_struct { + char *name; + ctx_handler_t handler; +} ctx_t; +typedef struct ctx_state_struct { + unsigned char ctx_id; + void *state; +} ctx_state_t; + +/* Parser states */ typedef struct file_state_struct { FILE *fp; char *path, *outfile; unsigned long line; unsigned char flags; -} file_state; -typedef char *(*eterm_function_ptr) (char *); -typedef struct eterm_function_struct { +} fstate_t; +/* Built-in functions */ +typedef char * (*eterm_func_ptr_t) (char *); +typedef struct eterm_func_struct { char *name; - eterm_function_ptr ptr; - int params; - -} eterm_func; + eterm_func_ptr_t ptr; +} eterm_func_t; /************ Variables ************/ +extern fstate_t *fstate; +extern unsigned char fstate_idx; extern unsigned long Options, image_toggles; extern char *theme_dir, *user_dir; extern char **rs_execArgs; /* Args to exec (-e or --exec) */ @@ -213,8 +195,6 @@ extern int rs_desktop; /* Startup desktop */ extern int rs_saveLines; /* Lines in the scrollback buffer */ extern unsigned short rs_min_anchor_size; /* Minimum size, in pixels, of the scrollbar anchor */ extern char *rs_term_name; -extern const char *rs_menubar; -extern const char *rs_menu; extern char *rs_icon; extern char *rs_scrollbar_type; extern unsigned long rs_scrollbar_width; @@ -229,6 +209,7 @@ extern char *rs_input_method; extern char *rs_preedit_type; #endif extern char *rs_name; +extern char *rs_theme; extern char *rs_config_file; extern unsigned int rs_line_space; #ifndef NO_BOLDFONT @@ -257,11 +238,17 @@ _XFUNCPROTOBEGIN unsigned long NumWords(const char *str); extern void get_initial_options(int, char **); extern void get_options(int, char **); +extern void conf_init_subsystem(void); +extern unsigned char conf_register_context(char *name, ctx_handler_t handler); +extern unsigned char conf_register_fstate(FILE *fp, char *path, char *outfile, unsigned long line, unsigned char flags); +extern unsigned char conf_register_builtin(char *name, eterm_func_ptr_t ptr); +extern unsigned char conf_register_context_state(unsigned char ctx_id); extern char *chomp(char *); extern char *shell_expand(char *); -extern char *find_theme(char *, char *, char *); -extern unsigned char open_config_file(char *); -extern void read_config(char *); +extern char *conf_find_file(const char *file, const char *dir, const char *pathlist); +extern FILE *open_config_file(char *name); +extern char *conf_parse(char *conf_name, const char *dir, const char *path); +extern char *conf_parse_theme(char *theme, char *conf_name, unsigned char fallback); extern void init_defaults(void); extern void post_parse(void); unsigned char save_config(char *); diff --git a/src/pixmap.c b/src/pixmap.c index 16fc8cb..c29e959 100644 --- a/src/pixmap.c +++ b/src/pixmap.c @@ -47,6 +47,9 @@ static const char cvs_ident[] = "$Id$"; #include "term.h" #ifdef PIXMAP_SUPPORT +static ImlibBorder bord_none = { 0, 0, 0, 0 }; +static ImlibColorModifier cmod_none = { 256, 256, 256 }; + Pixmap desktop_pixmap = None, viewport_pixmap = None; Pixmap buffer_pixmap = None; Window desktop_window = None; @@ -54,15 +57,20 @@ unsigned char desktop_pixmap_is_mine = 0; ImlibData *imlib_id = NULL; image_t images[image_max] = { - {None, 0, NULL, NULL, NULL, NULL}, - {None, 0, NULL, NULL, NULL, NULL}, - {None, 0, NULL, NULL, NULL, NULL}, - {None, 0, NULL, NULL, NULL, NULL}, - {None, 0, NULL, NULL, NULL, NULL}, - {None, 0, NULL, NULL, NULL, NULL}, - {None, 0, NULL, NULL, NULL, NULL}, - {None, 0, NULL, NULL, NULL, NULL}, - {None, 0, NULL, NULL, NULL, NULL} + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL}, + {None, 0, 0, NULL, NULL, NULL, NULL, NULL} }; #endif @@ -97,20 +105,38 @@ get_image_type(unsigned short type) case image_sa: return "image_sa"; break; + case image_st: + return "image_st"; + break; case image_menu: return "image_menu"; break; + case image_menuitem: + return "image_menuitem"; + break; case image_submenu: return "image_submenu"; break; + case image_button: + return "image_button"; + break; + case image_bbar: + return "image_bbar"; + break; + case image_gbar: + return "image_gbar"; + break; + case image_dialog: + return "image_dialog"; + break; case image_max: return "image_max"; break; default: - return ""; + ASSERT_NOTREACHED_RVAL(""); break; } - return (""); + ASSERT_NOTREACHED_RVAL(""); } unsigned char @@ -257,11 +283,94 @@ set_pixmap_scale(const char *geom, pixmap_t *pmap) pmap->op = op; changed++; } - D_PIXMAP(("scale_pixmap() returning %hu, *pmap == { op [%hu], w [%hd], h [%hd], x [%hd], y [%hd] }\n", - changed, pmap->op, pmap->w, pmap->h, pmap->x, pmap->y)); + D_PIXMAP(("Returning %hu, *pmap == { op [%hu], w [%hd], h [%hd], x [%hd], y [%hd] }\n", changed, pmap->op, pmap->w, pmap->h, pmap->x, pmap->y)); return changed; } +image_t * +create_eterm_image(void) +{ + image_t *i; + + i = (image_t *) MALLOC(sizeof(image_t)); + MEMSET(i, 0, sizeof(image_t)); + return (i); +} + +void +reset_eterm_image(image_t *img, unsigned long mask) +{ + ASSERT(img != NULL); + + D_PIXMAP(("reset_image(%8p, 0x%08x)\n", img, mask)); + + if ((mask & RESET_NORM) && img->norm) { + reset_simage(img->norm, mask); + } + if ((mask & RESET_SELECTED) && img->selected) { + reset_simage(img->selected, mask); + } + if ((mask & RESET_CLICKED) && img->clicked) { + reset_simage(img->clicked, mask); + } + if ((mask & RESET_DISABLED) && img->disabled) { + reset_simage(img->disabled, mask); + } + if (mask & RESET_MODE) { + img->mode = 0; + } + if (mask & RESET_ALL) { + img->userdef = 0; + img->win = None; + img->current = img->norm; + } +} + +void +free_eterm_image(image_t *img) +{ + if (img->selected == img->norm) { + img->selected = NULL; + } + if (img->clicked == img->norm) { + img->clicked = NULL; + } + if (img->disabled == img->norm) { + img->disabled = NULL; + } + free_simage(img->norm); + if (img->clicked == img->selected) { + img->clicked = NULL; + } + if (img->disabled == img->selected || img->disabled == img->clicked) { + img->disabled = NULL; + } + if (img->selected) { + free_simage(img->selected); + } + if (img->clicked) { + free_simage(img->clicked); + } + if (img->disabled) { + free_simage(img->disabled); + } + FREE(img); +} + +simage_t * +create_simage(void) +{ + simage_t *s; + + s = (simage_t *) MALLOC(sizeof(simage_t)); + MEMSET(s, 0, sizeof(simage_t)); + s->pmap = (pixmap_t *) MALLOC(sizeof(pixmap_t)); + s->iml = (imlib_t *) MALLOC(sizeof(imlib_t)); + MEMSET(s->pmap, 0, sizeof(pixmap_t)); + MEMSET(s->iml, 0, sizeof(imlib_t)); + return s; +} + void reset_simage(simage_t * simg, unsigned long mask) { @@ -311,6 +420,13 @@ reset_simage(simage_t * simg, unsigned long mask) } } +void +free_simage(simage_t *s) +{ + reset_simage(s, RESET_ALL_SIMG); + FREE(s); +} + static const char * get_iclass_name(unsigned char which) { @@ -322,8 +438,14 @@ get_iclass_name(unsigned char which) case image_right: return "ETERM_ARROW_RIGHT"; break; case image_sb: return "ETERM_TROUGH"; break; case image_sa: return "ETERM_ANCHOR"; break; - case image_menu: return "ETERM_MENU_ITEM"; break; + case image_st: return "ETERM_THUMB"; break; + case image_menu: return "ETERM_MENU_ITEM"; break; /* FIXME: This should be ETERM_MENU_BOX */ + case image_menuitem: return "ETERM_MENU_ITEM"; break; case image_submenu: return "ETERM_MENU_SUBMENU"; break; + case image_button: return "ETERM_MENU_ITEM"; break; /* FIXME: These four should */ + case image_bbar: return "ETERM_MENU_BOX"; break; /* have their own image classes */ + case image_gbar: return "ETERM_ANCHOR"; break; + case image_dialog: return "ETERM_MENU_BOX"; break; default: ASSERT_NOTREACHED_RVAL(NULL); break; @@ -368,6 +490,147 @@ check_image_ipc(unsigned char reset) return 1; } +Pixmap +create_trans_pixmap(simage_t *simg, unsigned char which, Drawable d, int x, int y, unsigned short width, unsigned short height) +{ + int pw, ph; + Window dummy; + Screen *scr; + Pixmap p = None; + GC gc; + + D_PIXMAP(("create_trans_pixmap(%8p, 0x%08x, %u, %d, %d, %hu, %hu) called.\n", simg, d, which, x, y, width, height)); + scr = ScreenOfDisplay(Xdisplay, Xscreen); + if (!scr) + return None; + + if (!update_desktop_info(&pw, &ph)) { + D_PIXMAP(("update_desktop_info() failed.\n")); + return None; + } + XTranslateCoordinates(Xdisplay, d, desktop_window, x, y, &x, &y, &dummy); + p = XCreatePixmap(Xdisplay, d, width, height, Xdepth); + gc = XCreateGC(Xdisplay, d, 0, NULL); + D_PIXMAP(("Created p [0x%08x] as a %hux%hu pixmap at %d, %d relative to window 0x%08x\n", p, width, height, x, y, desktop_window)); + if (p != None) { + if (pw < scr->width || ph < scr->height) { + D_PIXMAP(("Tiling %ux%u desktop pixmap 0x%08x onto p.\n", pw, ph, desktop_pixmap)); + XSetTile(Xdisplay, gc, desktop_pixmap); + XSetTSOrigin(Xdisplay, gc, pw - (x % pw), ph - (y % ph)); + XSetFillStyle(Xdisplay, gc, FillTiled); + XFillRectangle(Xdisplay, p, gc, 0, 0, width, height); + } else { + D_PIXMAP(("Copying %hux%hu rectangle at %d, %d from %ux%u desktop pixmap 0x%08x onto p.\n", width, height, x, y, pw, ph, desktop_pixmap)); + XCopyArea(Xdisplay, desktop_pixmap, p, gc, x, y, width, height, 0, 0); + } + if (which != image_bg && need_colormod(simg->iml)) { + colormod_trans(p, simg->iml, gc, width, height); + } + if (simg->iml->bevel != NULL) { + D_PIXMAP(("Beveling pixmap 0x%08x with edges %d, %d, %d, %d\n", p, simg->iml->bevel->edges->left, simg->iml->bevel->edges->top, + simg->iml->bevel->edges->right, simg->iml->bevel->edges->bottom)); + Imlib_bevel_pixmap(imlib_id, p, width, height, simg->iml->bevel->edges, simg->iml->bevel->up); + } + } + XFreeGC(Xdisplay, gc); + return p; +} + +Pixmap +create_viewport_pixmap(simage_t *simg, Drawable d, int x, int y, unsigned short width, unsigned short height) +{ + short xsize, ysize; + Window dummy; + unsigned int pw, ph, pb, pd; + int px, py; + Pixmap p = None; + GC gc; + Screen *scr; + + D_PIXMAP(("create_viewport_pixmap(%8p, 0x%08x, %d, %d, %hu, %hu) called.\n", simg, d, x, y, width, height)); + scr = ScreenOfDisplay(Xdisplay, Xscreen); + if (!scr) + return None; + + if (desktop_window == None) { + get_desktop_window(); + if (desktop_window == None) { + D_PIXMAP(("No desktop window found.\n")); + return None; + } + } + if (viewport_pixmap == None) { + imlib_t *tmp_iml = images[image_bg].current->iml; + + xsize = tmp_iml->im->rgb_width; + ysize = tmp_iml->im->rgb_height; + if (tmp_iml->border) { + Imlib_set_image_border(imlib_id, tmp_iml->im, tmp_iml->border); + } else { + Imlib_set_image_border(imlib_id, tmp_iml->im, &bord_none); + } + if (tmp_iml->mod) { + Imlib_set_image_modifier(imlib_id, tmp_iml->im, tmp_iml->mod); + } else { + Imlib_set_image_modifier(imlib_id, tmp_iml->im, &cmod_none); + } + if (tmp_iml->rmod) { + Imlib_set_image_red_modifier(imlib_id, tmp_iml->im, tmp_iml->rmod); + } else { + Imlib_set_image_red_modifier(imlib_id, tmp_iml->im, &cmod_none); + } + if (tmp_iml->gmod) { + Imlib_set_image_green_modifier(imlib_id, tmp_iml->im, tmp_iml->gmod); + } else { + Imlib_set_image_green_modifier(imlib_id, tmp_iml->im, &cmod_none); + } + if (tmp_iml->bmod) { + Imlib_set_image_blue_modifier(imlib_id, tmp_iml->im, tmp_iml->bmod); + } else { + Imlib_set_image_blue_modifier(imlib_id, tmp_iml->im, &cmod_none); + } + if ((images[image_bg].current->pmap->w > 0) || (images[image_bg].current->pmap->op & OP_SCALE)) { + D_PIXMAP(("Scaling image to %dx%d\n", scr->width, scr->height)); + Imlib_render(imlib_id, tmp_iml->im, scr->width, scr->height); + } else { + D_PIXMAP(("Tiling image at %dx%d\n", xsize, ysize)); + Imlib_render(imlib_id, tmp_iml->im, xsize, ysize); + } + viewport_pixmap = Imlib_copy_image(imlib_id, tmp_iml->im); + D_PIXMAP(("Created viewport_pixmap == 0x%08x\n", viewport_pixmap)); + } else { + XGetGeometry(Xdisplay, viewport_pixmap, &dummy, &px, &py, &pw, &ph, &pb, &pd); + xsize = (short) pw; + ysize = (short) ph; + } + if (simg->pmap->pixmap != None) { + XGetGeometry(Xdisplay, simg->pmap->pixmap, &dummy, &px, &py, &pw, &ph, &pb, &pd); + if (pw != width || ph != height) { + Imlib_free_pixmap(imlib_id, simg->pmap->pixmap); + simg->pmap->pixmap = None; + } else { + p = simg->pmap->pixmap; + } + } + if (p == None) { + p = XCreatePixmap(Xdisplay, d, width, height, Xdepth); + D_PIXMAP(("Created p == 0x%08x\n", p)); + } + gc = XCreateGC(Xdisplay, d, 0, NULL); + XTranslateCoordinates(Xdisplay, d, desktop_window, x, y, &x, &y, &dummy); + D_PIXMAP(("Translated coords are %d, %d\n", x, y)); + if ((images[image_bg].current->pmap->w > 0) || (images[image_bg].current->pmap->op & OP_SCALE)) { + XCopyArea(Xdisplay, viewport_pixmap, p, gc, x, y, width, height, 0, 0); + } else { + XSetTile(Xdisplay, gc, viewport_pixmap); + XSetTSOrigin(Xdisplay, gc, xsize - (x % xsize), ysize - (y % ysize)); + XSetFillStyle(Xdisplay, gc, FillTiled); + XFillRectangle(Xdisplay, p, gc, 0, 0, width, height); + } + XFreeGC(Xdisplay, gc); + return p; +} + void paste_simage(simage_t *simg, unsigned char which, Drawable d, unsigned short x, unsigned short y, unsigned short w, unsigned short h) { @@ -377,74 +640,109 @@ paste_simage(simage_t *simg, unsigned char which, Drawable d, unsigned short x, D_PIXMAP(("paste_simage(%8p, %s, 0x%08x, %hd, %hd, %hd, %hd) called.\n", simg, get_image_type(which), (int) d, x, y, w, h)); - if ((images[which].mode & MODE_AUTO) && (images[which].mode & ALLOW_AUTO)) { - char buff[255], *reply; - const char *iclass, *state; - Pixmap pmap, mask; + if (which != image_max) { + if (image_mode_is(which, MODE_AUTO) && image_mode_is(which, ALLOW_AUTO)) { + char buff[255], *reply; + const char *iclass, *state; + Pixmap pmap, mask; - check_image_ipc(0); - if (image_mode_is(which, MODE_AUTO)) { - iclass = get_iclass_name(which); - if (simg == images[which].selected) { - state = "hilited"; - } else if (simg == images[which].clicked) { - state = "clicked"; - } else { - state = "normal"; - } - D_PIXMAP((" -> iclass == \"%s\", state == \"%s\"\n", NONULL(iclass), NONULL(state))); - - if (iclass) { - snprintf(buff, sizeof(buff), "imageclass %s apply_copy 0x%x %s %hd %hd", iclass, (int) d, state, w, h); - reply = enl_send_and_wait(buff); - if (strstr(reply, "Error")) { - print_error("Enlightenment didn't seem to like something about my syntax. Disallowing \"auto\" mode for this image.\n"); - image_mode_fallback(which); - FREE(reply); + check_image_ipc(0); + if (image_mode_is(which, MODE_AUTO)) { + iclass = get_iclass_name(which); + if (simg == images[which].selected) { + state = "hilited"; + } else if (simg == images[which].clicked) { + state = "clicked"; } else { - GC gc; - XGCValues gcvalues; + state = "normal"; + } + D_PIXMAP((" -> iclass == \"%s\", state == \"%s\"\n", NONULL(iclass), NONULL(state))); - gc = XCreateGC(Xdisplay, d, 0, &gcvalues); - pmap = (Pixmap) strtoul(reply, (char **) NULL, 0); - mask = (Pixmap) strtoul(PWord(2, reply), (char **) NULL, 0); - FREE(reply); - enl_ipc_sync(); - if (pmap) { - if (mask) { - shaped_window_apply_mask(pmap, mask); - } - XSetClipMask(Xdisplay, gc, mask); - XSetClipOrigin(Xdisplay, gc, x, y); - XCopyArea(Xdisplay, pmap, d, gc, 0, 0, w, h, x, y); - snprintf(buff, sizeof(buff), "imageclass %s free_pixmap 0x%08x", iclass, (int) pmap); - enl_ipc_send(buff); - XFreeGC(Xdisplay, gc); - return; - } else { - print_error("Enlightenment returned a null pixmap, which I can't use. Disallowing \"auto\" mode for this image.\n"); - FREE(reply); + if (iclass) { + snprintf(buff, sizeof(buff), "imageclass %s apply_copy 0x%x %s %hd %hd", iclass, (int) d, state, w, h); + reply = enl_send_and_wait(buff); + if (strstr(reply, "Error")) { + print_error("Enlightenment didn't seem to like something about my syntax. Disallowing \"auto\" mode for this image.\n"); image_mode_fallback(which); + FREE(reply); + } else { + GC gc; + XGCValues gcvalues; + + gc = XCreateGC(Xdisplay, d, 0, &gcvalues); + pmap = (Pixmap) strtoul(reply, (char **) NULL, 0); + mask = (Pixmap) strtoul(PWord(2, reply), (char **) NULL, 0); + FREE(reply); + enl_ipc_sync(); + if (pmap) { + if (mask) { + shaped_window_apply_mask(pmap, mask); + } + XSetClipMask(Xdisplay, gc, mask); + XSetClipOrigin(Xdisplay, gc, x, y); + XCopyArea(Xdisplay, pmap, d, gc, 0, 0, w, h, x, y); + snprintf(buff, sizeof(buff), "imageclass %s free_pixmap 0x%08x", iclass, (int) pmap); + enl_ipc_send(buff); + XFreeGC(Xdisplay, gc); + return; + } else { + print_error("Enlightenment returned a null pixmap, which I can't use. Disallowing \"auto\" mode for this image.\n"); + FREE(reply); + image_mode_fallback(which); + } } } } + } else if (image_mode_is(which, MODE_TRANS) && image_mode_is(which, ALLOW_TRANS)) { + Pixmap p; + GC gc; + + gc = XCreateGC(Xdisplay, d, 0, NULL); + p = create_trans_pixmap(simg, which, d, x, y, w, h); + if (simg->iml->bevel != NULL) { + Imlib_bevel_pixmap(imlib_id, p, w, h, simg->iml->bevel->edges, simg->iml->bevel->up); + } + XCopyArea(Xdisplay, p, d, gc, 0, 0, w, h, x, y); + XFreePixmap(Xdisplay, p); + } else if (image_mode_is(which, MODE_VIEWPORT) && image_mode_is(which, ALLOW_VIEWPORT)) { + Pixmap p; + GC gc; + + gc = XCreateGC(Xdisplay, d, 0, NULL); + p = create_viewport_pixmap(simg, d, x, y, w, h); + if (simg->iml->bevel != NULL) { + Imlib_bevel_pixmap(imlib_id, p, w, h, simg->iml->bevel->edges, simg->iml->bevel->up); + } + XCopyArea(Xdisplay, p, d, gc, 0, 0, w, h, x, y); + XFreePixmap(Xdisplay, p); } } - if (image_mode_is(which, MODE_IMAGE) && image_mode_is(which, ALLOW_IMAGE)) { + + if ((which == image_max) || (image_mode_is(which, MODE_IMAGE) && image_mode_is(which, ALLOW_IMAGE))) { if (simg->iml->border) { Imlib_set_image_border(imlib_id, simg->iml->im, simg->iml->border); + } else { + Imlib_set_image_border(imlib_id, simg->iml->im, &bord_none); } if (simg->iml->mod) { Imlib_set_image_modifier(imlib_id, simg->iml->im, simg->iml->mod); + } else { + Imlib_set_image_modifier(imlib_id, simg->iml->im, &cmod_none); } if (simg->iml->rmod) { Imlib_set_image_red_modifier(imlib_id, simg->iml->im, simg->iml->rmod); + } else { + Imlib_set_image_red_modifier(imlib_id, simg->iml->im, &cmod_none); } if (simg->iml->gmod) { Imlib_set_image_green_modifier(imlib_id, simg->iml->im, simg->iml->gmod); + } else { + Imlib_set_image_green_modifier(imlib_id, simg->iml->im, &cmod_none); } if (simg->iml->bmod) { Imlib_set_image_blue_modifier(imlib_id, simg->iml->im, simg->iml->bmod); + } else { + Imlib_set_image_blue_modifier(imlib_id, simg->iml->im, &cmod_none); } Imlib_paste_image(imlib_id, simg->iml->im, (Window) d, x, y, w, h); } @@ -468,10 +766,17 @@ redraw_image(unsigned char which) { scrollbar_draw_trough(IMAGE_STATE_CURRENT, MODE_MASK); break; case image_sa: + case image_st: scrollbar_draw_anchor(IMAGE_STATE_CURRENT, MODE_MASK); break; + case image_button: + break; + case image_bbar: + break; + case image_gbar: + break; default: - D_PIXMAP(("redraw_image(): Bad value %u\n", which)); + D_PIXMAP(("Bad value %u\n", which)); break; } } @@ -486,7 +791,7 @@ redraw_images_by_mode(unsigned char mode) { render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 0); scr_touch(); } - scrollbar_draw(mode); + scrollbar_draw(IMAGE_STATE_CURRENT, mode); } } @@ -529,14 +834,7 @@ render_simage(simage_t * simg, Window win, unsigned short width, unsigned short Pixmap pixmap = None; unsigned short rendered = 0; unsigned short xscaled = 0, yscaled = 0; -# ifdef PIXMAP_OFFSET - static unsigned int last_x = 0, last_y = 0; - int x, y; - int px, py; - unsigned int pw, ph, pb, pd; - Window w, dummy; Screen *scr; -# endif /* PIXMAP_OFFSET */ scr = ScreenOfDisplay(Xdisplay, Xscreen); if (!scr) @@ -546,8 +844,8 @@ render_simage(simage_t * simg, Window win, unsigned short width, unsigned short ASSERT(simg->iml != NULL); ASSERT(simg->pmap != NULL); - D_PIXMAP(("render_simage(): Rendering simg->iml->im %8p (%s) at %hux%hu onto window 0x%08x\n", simg->iml->im, get_image_type(which), width, height, win)); - D_PIXMAP(("render_simage(): Image mode is 0x%02x\n", images[which].mode)); + D_PIXMAP(("Rendering simg->iml->im %8p (%s) at %hux%hu onto window 0x%08x\n", simg->iml->im, get_image_type(which), width, height, win)); + D_PIXMAP(("Image mode is 0x%02x\n", images[which].mode)); if ((which == image_bg) && image_mode_is(image_bg, MODE_VIEWPORT)) { width = scr->width; @@ -580,157 +878,91 @@ render_simage(simage_t * simg, Window win, unsigned short width, unsigned short state = "normal"; } if (iclass) { - snprintf(buff, sizeof(buff), "imageclass %s apply 0x%x %s", iclass, (int) win, state); - enl_ipc_send(buff); - return; + if (renderop & RENDER_FORCE_PIXMAP) { + char *reply; + + snprintf(buff, sizeof(buff), "imageclass %s apply_copy 0x%x %s %hd %hd", iclass, (int) win, state, width, height); + reply = enl_send_and_wait(buff); + if (strstr(reply, "Error")) { + print_error("Enlightenment didn't seem to like something about my syntax. Disallowing \"auto\" mode for this image.\n"); + image_mode_fallback(which); + FREE(reply); + } else { + Pixmap pmap, mask; + + pmap = (Pixmap) strtoul(reply, (char **) NULL, 0); + mask = (Pixmap) strtoul(PWord(2, reply), (char **) NULL, 0); + FREE(reply); + enl_ipc_sync(); + if (pmap) { + if (mask) { + shaped_window_apply_mask(pmap, mask); + XSetClipMask(Xdisplay, gc, mask); + XSetClipOrigin(Xdisplay, gc, 0, 0); + } + if (simg->pmap->pixmap) { + XFreePixmap(Xdisplay, simg->pmap->pixmap); + } + simg->pmap->pixmap = XCreatePixmap(Xdisplay, win, width, height, Xdepth); + XCopyArea(Xdisplay, pmap, simg->pmap->pixmap, gc, 0, 0, width, height, 0, 0); + XSetWindowBackgroundPixmap(Xdisplay, win, simg->pmap->pixmap); + snprintf(buff, sizeof(buff), "imageclass %s free_pixmap 0x%08x", iclass, (int) pmap); + enl_ipc_send(buff); + } else { + print_error("Enlightenment returned a null pixmap, which I can't use. Disallowing \"auto\" mode for this image.\n"); + FREE(reply); + image_mode_fallback(which); + } + } + } else { + snprintf(buff, sizeof(buff), "imageclass %s apply 0x%x %s", iclass, (int) win, state); + enl_ipc_send(buff); + XFreeGC(Xdisplay, gc); + return; + } } } } # ifdef PIXMAP_OFFSET if (image_mode_is(which, MODE_TRANS) && image_mode_is(which, ALLOW_TRANS)) { - if (desktop_window == None) { - get_desktop_window(); + if (simg->pmap->pixmap != None) { + XFreePixmap(Xdisplay, simg->pmap->pixmap); } - if (desktop_window == None) { - print_error("Unable to locate desktop window. If you are running Enlightenment, please\n" - "restart. If not, please set your background image with Esetroot, then try again."); - FOREACH_IMAGE(if (image_mode_is(idx, MODE_TRANS)) {image_set_mode(idx, MODE_IMAGE); image_allow_mode(idx, ALLOW_IMAGE);}); - render_simage(simg, win, width, height, which, renderop); - return; - } - if (desktop_pixmap == None) { - get_desktop_pixmap(); - last_x = last_y = -1; - } - if (desktop_pixmap != None) { - XTranslateCoordinates(Xdisplay, win, desktop_window, 0, 0, &x, &y, &w); - if (simg->pmap->pixmap != None) { - XFreePixmap(Xdisplay, simg->pmap->pixmap); - } - simg->pmap->pixmap = XCreatePixmap(Xdisplay, win, width, height, Xdepth); - D_PIXMAP(("desktop_pixmap == 0x%08x, simg->pmap->pixmap == 0x%08x\n", desktop_pixmap, simg->pmap->pixmap)); - if (simg->pmap->pixmap != None) { - XGetGeometry(Xdisplay, desktop_pixmap, &w, &px, &py, &pw, &ph, &pb, &pd); - if ((pw <= 0) || (ph <= 0)) { - /* Reset and try again. */ - get_desktop_window(); - get_desktop_pixmap(); - XGetGeometry(Xdisplay, desktop_pixmap, &w, &px, &py, &pw, &ph, &pb, &pd); - } - if ((pw <= 0) || (ph <= 0)) { - print_error("Value of desktop pixmap property is invalid. Please restart your " - "window manager or use Esetroot to set a new one."); - desktop_pixmap = None; - D_PIXMAP(("Setting background of window 0x%08x to the background color\n", win)); - if ((which == image_bg) && (Options & Opt_double_buffer)) { - copy_buffer_pixmap(MODE_SOLID, (unsigned long) PixColors[bgColor], width, height); - XSetWindowBackgroundPixmap(Xdisplay, win, buffer_pixmap); - } else { - XSetWindowBackground(Xdisplay, win, PixColors[bgColor]); - } - } else { - if (pw < (unsigned int) scr->width || ph < (unsigned int) scr->height) { - XFreeGC(Xdisplay, gc); - gc = XCreateGC(Xdisplay, desktop_pixmap, 0, &gcvalue); - XSetTile(Xdisplay, gc, desktop_pixmap); - XSetTSOrigin(Xdisplay, gc, pw - (x % pw), ph - (y % ph)); - XSetFillStyle(Xdisplay, gc, FillTiled); - XFillRectangle(Xdisplay, simg->pmap->pixmap, gc, 0, 0, scr->width, scr->height); - } else { - XCopyArea(Xdisplay, desktop_pixmap, simg->pmap->pixmap, gc, x, y, width, height, 0, 0); - } - if (which != image_bg && need_colormod(simg->iml)) { - colormod_trans(simg->pmap->pixmap, simg->iml, gc, width, height); - } - if (simg->iml->bevel != NULL) { - Imlib_bevel_pixmap(imlib_id, simg->pmap->pixmap, width, height, simg->iml->bevel->edges, simg->iml->bevel->up); - } - D_PIXMAP(("Setting background of window 0x%08x to 0x%08x\n", win, simg->pmap->pixmap)); - if ((which == image_bg) && (Options & Opt_double_buffer)) { - copy_buffer_pixmap(MODE_TRANS, (unsigned long) simg->pmap->pixmap, width, height); - XSetWindowBackgroundPixmap(Xdisplay, win, buffer_pixmap); - } else { - XSetWindowBackgroundPixmap(Xdisplay, win, simg->pmap->pixmap); - } - } - } - } else { - D_PIXMAP(("Setting background of window 0x%08x to the background color\n", win)); + simg->pmap->pixmap = create_trans_pixmap(simg, which, win, 0, 0, width, height); + if (simg->pmap->pixmap != None) { if ((which == image_bg) && (Options & Opt_double_buffer)) { - copy_buffer_pixmap(MODE_SOLID, (unsigned long) PixColors[bgColor], width, height); + copy_buffer_pixmap(MODE_TRANS, (unsigned long) simg->pmap->pixmap, width, height); XSetWindowBackgroundPixmap(Xdisplay, win, buffer_pixmap); } else { - XSetWindowBackground(Xdisplay, win, PixColors[bgColor]); + XSetWindowBackgroundPixmap(Xdisplay, win, simg->pmap->pixmap); } + } else { + image_mode_fallback(which); } } else if (image_mode_is(which, MODE_VIEWPORT) && image_mode_is(which, ALLOW_VIEWPORT)) { - D_PIXMAP(("Viewport mode enabled. viewport_pixmap == 0x%08x and simg->pmap->pixmap == 0x%08x\n", viewport_pixmap, simg->pmap->pixmap)); - if (viewport_pixmap == None) { - imlib_t *tmp_iml = images[image_bg].current->iml; + Pixmap p; - xsize = tmp_iml->im->rgb_width; - ysize = tmp_iml->im->rgb_height; - if (tmp_iml->border) { - Imlib_set_image_border(imlib_id, tmp_iml->im, tmp_iml->border); + D_PIXMAP(("Viewport mode enabled. viewport_pixmap == 0x%08x and simg->pmap->pixmap == 0x%08x\n", viewport_pixmap, simg->pmap->pixmap)); + p = create_viewport_pixmap(simg, win, 0, 0, width, height); + if (p && (p != simg->pmap->pixmap)) { + if (simg->pmap->pixmap != None) { + XFreePixmap(Xdisplay, simg->pmap->pixmap); } - if (tmp_iml->mod) { - Imlib_set_image_modifier(imlib_id, tmp_iml->im, tmp_iml->mod); - } - if (tmp_iml->rmod) { - Imlib_set_image_red_modifier(imlib_id, tmp_iml->im, tmp_iml->rmod); - } - if (tmp_iml->gmod) { - Imlib_set_image_green_modifier(imlib_id, tmp_iml->im, tmp_iml->gmod); - } - if (tmp_iml->bmod) { - Imlib_set_image_blue_modifier(imlib_id, tmp_iml->im, tmp_iml->bmod); - } - if ((images[image_bg].current->pmap->w > 0) || (images[image_bg].current->pmap->op & OP_SCALE)) { - D_PIXMAP(("Scaling image to %dx%d\n", scr->width, scr->height)); - Imlib_render(imlib_id, tmp_iml->im, scr->width, scr->height); - } else { - D_PIXMAP(("Tiling image at %dx%d\n", xsize, ysize)); - Imlib_render(imlib_id, tmp_iml->im, xsize, ysize); - } - viewport_pixmap = Imlib_copy_image(imlib_id, tmp_iml->im); - D_PIXMAP(("Created viewport_pixmap == 0x%08x\n", viewport_pixmap)); - } else { - XGetGeometry(Xdisplay, viewport_pixmap, &dummy, &px, &py, &pw, &ph, &pb, &pd); - xsize = (short) pw; - ysize = (short) ph; + simg->pmap->pixmap = p; } if (simg->pmap->pixmap != None) { - XGetGeometry(Xdisplay, simg->pmap->pixmap, &dummy, &px, &py, &pw, &ph, &pb, &pd); - if (pw != width || ph != height) { - Imlib_free_pixmap(imlib_id, simg->pmap->pixmap); - simg->pmap->pixmap = None; + D_PIXMAP(("Setting background of window 0x%08x to 0x%08x\n", win, simg->pmap->pixmap)); + if ((which == image_bg) && (Options & Opt_double_buffer)) { + copy_buffer_pixmap(MODE_VIEWPORT, (unsigned long) simg->pmap->pixmap, width, height); + XSetWindowBackgroundPixmap(Xdisplay, win, buffer_pixmap); + } else { + XSetWindowBackgroundPixmap(Xdisplay, win, simg->pmap->pixmap); } - } - if (simg->pmap->pixmap == None) { - simg->pmap->pixmap = XCreatePixmap(Xdisplay, win, width, height, Xdepth); - D_PIXMAP(("Created simg->pmap->pixmap == 0x%08x\n", simg->pmap->pixmap)); - } - XTranslateCoordinates(Xdisplay, win, Xroot, 0, 0, &x, &y, &dummy); - D_PIXMAP(("Translated coords are %d, %d\n", x, y)); - if ((images[image_bg].current->pmap->w > 0) || (images[image_bg].current->pmap->op & OP_SCALE)) { - XCopyArea(Xdisplay, viewport_pixmap, simg->pmap->pixmap, gc, x, y, width, height, 0, 0); } else { - XFreeGC(Xdisplay, gc); - gc = XCreateGC(Xdisplay, viewport_pixmap, 0, &gcvalue); - XSetTile(Xdisplay, gc, viewport_pixmap); - XSetTSOrigin(Xdisplay, gc, xsize - (x % xsize), ysize - (y % ysize)); - XSetFillStyle(Xdisplay, gc, FillTiled); - XFillRectangle(Xdisplay, simg->pmap->pixmap, gc, 0, 0, width, height); + image_mode_fallback(which); } - D_PIXMAP(("Setting background of window 0x%08x to 0x%08x\n", win, simg->pmap->pixmap)); - if ((which == image_bg) && (Options & Opt_double_buffer)) { - copy_buffer_pixmap(MODE_VIEWPORT, (unsigned long) simg->pmap->pixmap, width, height); - XSetWindowBackgroundPixmap(Xdisplay, win, buffer_pixmap); - } else { - XSetWindowBackgroundPixmap(Xdisplay, win, simg->pmap->pixmap); - } - } else + } # endif if (image_mode_is(which, MODE_IMAGE) && image_mode_is(which, ALLOW_IMAGE)) { if (simg->iml->im) { @@ -741,7 +973,7 @@ render_simage(simage_t * simg, Window win, unsigned short width, unsigned short xsize = simg->iml->im->rgb_width; ysize = simg->iml->im->rgb_height; - D_PIXMAP(("render_simage(): w == %d, h == %d, x == %d, y == %d, xsize == %d, ysize == %d\n", w, h, x, y, xsize, ysize)); + D_PIXMAP(("w == %d, h == %d, x == %d, y == %d, xsize == %d, ysize == %d\n", w, h, x, y, xsize, ysize)); if ((simg->pmap->op & OP_PROPSCALE)) { double x_ratio, y_ratio; @@ -776,7 +1008,7 @@ render_simage(simage_t * simg, Window win, unsigned short width, unsigned short xpos = (short) ((width - xscaled) * ((float) x / 100.0)); ypos = (short) ((height - yscaled) * ((float) y / 100.0)); - D_PIXMAP(("render_simage(): Calculated scaled size as %hux%hu with origin at (%hd, %hd)\n", xscaled, yscaled, xpos, ypos)); + D_PIXMAP(("Calculated scaled size as %hux%hu with origin at (%hd, %hd)\n", xscaled, yscaled, xpos, ypos)); if (simg->iml->last_w != xscaled || simg->iml->last_h != yscaled || 1) { @@ -784,31 +1016,41 @@ render_simage(simage_t * simg, Window win, unsigned short width, unsigned short simg->iml->last_h = yscaled; if (simg->iml->border) { - D_PIXMAP(("render_simage(): Setting image border: { left [%d], right [%d], top [%d], bottom [%d] }\n", + D_PIXMAP(("Setting image border: { left [%d], right [%d], top [%d], bottom [%d] }\n", simg->iml->border->left, simg->iml->border->right, simg->iml->border->top, simg->iml->border->bottom)); Imlib_set_image_border(imlib_id, simg->iml->im, simg->iml->border); - } + } else { + Imlib_set_image_border(imlib_id, simg->iml->im, &bord_none); + } if (simg->iml->mod) { - D_PIXMAP(("render_simage(): Setting image modifier: { gamma [0x%08x], brightness [0x%08x], contrast [0x%08x] }\n", + D_PIXMAP(("Setting image modifier: { gamma [0x%08x], brightness [0x%08x], contrast [0x%08x] }\n", simg->iml->mod->gamma, simg->iml->mod->brightness, simg->iml->mod->contrast)); Imlib_set_image_modifier(imlib_id, simg->iml->im, simg->iml->mod); - } + } else { + Imlib_set_image_modifier(imlib_id, simg->iml->im, &cmod_none); + } if (simg->iml->rmod) { - D_PIXMAP(("render_simage(): Setting image red modifier: { gamma [0x%08x], brightness [0x%08x], contrast [0x%08x] }\n", + D_PIXMAP(("Setting image red modifier: { gamma [0x%08x], brightness [0x%08x], contrast [0x%08x] }\n", simg->iml->rmod->gamma, simg->iml->rmod->brightness, simg->iml->rmod->contrast)); Imlib_set_image_red_modifier(imlib_id, simg->iml->im, simg->iml->rmod); - } + } else { + Imlib_set_image_red_modifier(imlib_id, simg->iml->im, &cmod_none); + } if (simg->iml->gmod) { - D_PIXMAP(("render_simage(): Setting image green modifier: { gamma [0x%08x], brightness [0x%08x], contrast [0x%08x] }\n", + D_PIXMAP(("Setting image green modifier: { gamma [0x%08x], brightness [0x%08x], contrast [0x%08x] }\n", simg->iml->gmod->gamma, simg->iml->gmod->brightness, simg->iml->gmod->contrast)); Imlib_set_image_green_modifier(imlib_id, simg->iml->im, simg->iml->gmod); - } + } else { + Imlib_set_image_green_modifier(imlib_id, simg->iml->im, &cmod_none); + } if (simg->iml->bmod) { - D_PIXMAP(("render_simage(): Setting image blue modifier: { gamma [0x%08x], brightness [0x%08x], contrast [0x%08x] }\n", + D_PIXMAP(("Setting image blue modifier: { gamma [0x%08x], brightness [0x%08x], contrast [0x%08x] }\n", simg->iml->bmod->gamma, simg->iml->bmod->brightness, simg->iml->bmod->contrast)); Imlib_set_image_blue_modifier(imlib_id, simg->iml->im, simg->iml->bmod); - } - D_PIXMAP(("render_simage(): Rendering image simg->iml->im [%8p] to %hdx%hd pixmap\n", simg->iml->im, xscaled, yscaled)); + } else { + Imlib_set_image_blue_modifier(imlib_id, simg->iml->im, &cmod_none); + } + D_PIXMAP(("Rendering image simg->iml->im [%8p] to %hdx%hd pixmap\n", simg->iml->im, xscaled, yscaled)); Imlib_render(imlib_id, simg->iml->im, xscaled, yscaled); rendered = 1; } @@ -818,13 +1060,8 @@ render_simage(simage_t * simg, Window win, unsigned short width, unsigned short shaped_window_apply_mask(win, simg->pmap->mask); } } else { - if ((which == image_bg) && (Options & Opt_double_buffer)) { - copy_buffer_pixmap(MODE_SOLID, (unsigned long) PixColors[bgColor], width, height); - XSetWindowBackgroundPixmap(Xdisplay, win, buffer_pixmap); - } else { - XSetWindowBackground(Xdisplay, win, PixColors[bgColor]); - } - reset_simage(simg, RESET_ALL); + image_set_mode(which, MODE_SOLID); + reset_simage(simg, RESET_ALL_SIMG); } if (simg->pmap->pixmap != None) { if (pixmap != None) { @@ -860,38 +1097,33 @@ render_simage(simage_t * simg, Window win, unsigned short width, unsigned short XSetWindowBackgroundPixmap(Xdisplay, win, simg->pmap->pixmap); } } - } else { - unsigned short cidx; + } - switch (which) { - case image_up: - case image_down: - case image_left: - case image_right: - case image_sb: - case image_sa: - cidx = (TermWin.focus ? scrollColor : unfocusedScrollColor); - break; - case image_menu: - case image_submenu: - cidx = (TermWin.focus ? menuColor : unfocusedMenuColor); - break; - default: - cidx = bgColor; - break; - } - + /* Fall back to solid mode if all else fails. */ + if (!image_mode_is(which, MODE_MASK)) { if ((which == image_bg) && (Options & Opt_double_buffer)) { copy_buffer_pixmap(MODE_SOLID, (unsigned long) PixColors[bgColor], width, height); XSetWindowBackgroundPixmap(Xdisplay, win, buffer_pixmap); } else { - XSetWindowBackground(Xdisplay, win, PixColors[cidx]); + if (renderop & RENDER_FORCE_PIXMAP) { + if (simg->pmap->pixmap) { + XFreePixmap(Xdisplay, simg->pmap->pixmap); + } + simg->pmap->pixmap = XCreatePixmap(Xdisplay, win, width, height, Xdepth); + XSetForeground(Xdisplay, gc, ((which == image_bg) ? (PixColors[bgColor]) : (simg->bg))); + XFillRectangle(Xdisplay, simg->pmap->pixmap, gc, 0, 0, width, height); + if (simg->iml->bevel != NULL) { + Imlib_bevel_pixmap(imlib_id, simg->pmap->pixmap, width, height, simg->iml->bevel->edges, simg->iml->bevel->up); + } + XSetWindowBackgroundPixmap(Xdisplay, win, simg->pmap->pixmap); + } else { + XSetWindowBackground(Xdisplay, win, ((which == image_bg) ? (PixColors[bgColor]) : (simg->bg))); + } } - image_set_mode(which, MODE_SOLID); } XClearWindow(Xdisplay, win); XFreeGC(Xdisplay, gc); - XSync(Xdisplay, False); + return; } const char * @@ -911,7 +1143,7 @@ search_path(const char *pathlist, const char *file, const char *ext) } getcwd(name, PATH_MAX); D_OPTIONS(("search_path(\"%s\", \"%s\", \"%s\") called from \"%s\".\n", pathlist, file, ext, name)); - D_OPTIONS(("search_path(): Checking for file \"%s\"\n", file)); + D_OPTIONS(("Checking for file \"%s\"\n", file)); if (!access(file, R_OK)) { if (stat(file, &fst)) { D_OPTIONS(("Unable to stat %s -- %s\n", file, strerror(errno))); @@ -944,7 +1176,7 @@ search_path(const char *pathlist, const char *file, const char *ext) strncpy(name, file, len); name[len] = '\0'; - D_OPTIONS(("search_path(): Checking for file \"%s\"\n", name)); + D_OPTIONS(("Checking for file \"%s\"\n", name)); if (!access(name, R_OK)) { stat(name, &fst); if (!S_ISDIR(fst.st_mode)) @@ -952,7 +1184,7 @@ search_path(const char *pathlist, const char *file, const char *ext) } if (ext) { strcat(name, ext); - D_OPTIONS(("search_path(): Checking for file \"%s\"\n", name)); + D_OPTIONS(("Checking for file \"%s\"\n", name)); if (!access(name, R_OK)) { stat(name, &fst); if (!S_ISDIR(fst.st_mode)) @@ -979,7 +1211,7 @@ search_path(const char *pathlist, const char *file, const char *ext) name[n] = '\0'; strncat(name, file, len); - D_OPTIONS(("search_path(): Checking for file \"%s\"\n", name)); + D_OPTIONS(("Checking for file \"%s\"\n", name)); if (!access(name, R_OK)) { stat(name, &fst); if (!S_ISDIR(fst.st_mode)) @@ -987,7 +1219,7 @@ search_path(const char *pathlist, const char *file, const char *ext) } if (ext) { strcat(name, ext); - D_OPTIONS(("search_path(): Checking for file \"%s\"\n", name)); + D_OPTIONS(("Checking for file \"%s\"\n", name)); if (!access(name, R_OK)) { stat(name, &fst); if (!S_ISDIR(fst.st_mode)) @@ -996,49 +1228,48 @@ search_path(const char *pathlist, const char *file, const char *ext) } } } - D_OPTIONS(("search_path(): File \"%s\" not found in path.\n", file)); + D_OPTIONS(("File \"%s\" not found in path.\n", file)); return ((const char *) NULL); } -unsigned short -load_image(const char *file, short type) +unsigned char +load_image(const char *file, simage_t *simg) { const char *f; - imlib_t img; + ImlibImage *im; char *geom; ASSERT_RVAL(file != NULL, 0); - ASSERT_RVAL(type >= 0 && type < image_max, 0); + ASSERT_RVAL(simg != NULL, 0); - D_PIXMAP(("load_image(%s, %d)\n", file, type)); + D_PIXMAP(("load_image(%s, %8p)\n", file, simg)); if (*file != '\0') { - if ((geom = strchr(file, '@')) != NULL) { *geom++ = 0; } else if ((geom = strchr(file, ';')) != NULL) { *geom++ = 0; } if (geom != NULL) { - set_pixmap_scale(geom, images[type].current->pmap); + set_pixmap_scale(geom, simg->pmap); } if ((f = search_path(rs_path, file, PIXMAP_EXT)) == NULL) { f = search_path(getenv(PATH_ENV), file, PIXMAP_EXT); } if (f != NULL) { - img.im = Imlib_load_image(imlib_id, (char *) f); - if (img.im == NULL) { + im = Imlib_load_image(imlib_id, (char *) f); + if (im == NULL) { print_error("Unable to load image file \"%s\"", file); return 0; } else { - reset_simage(images[type].current, (RESET_IMLIB_IM | RESET_PMAP_PIXMAP | RESET_PMAP_MASK)); - images[type].current->iml->im = img.im; + reset_simage(simg, (RESET_IMLIB_IM | RESET_PMAP_PIXMAP | RESET_PMAP_MASK)); + simg->iml->im = im; } - D_PIXMAP(("load_image() exiting. images[%s].current->iml->im == %8p\n", get_image_type(type), images[type].current->iml->im)); + D_PIXMAP(("Found image %8p.\n", im)); return 1; } } - reset_simage(images[type].current, RESET_ALL); + reset_simage(simg, RESET_ALL_SIMG); return 0; } @@ -1127,8 +1358,7 @@ colormod_trans(Pixmap p, imlib_t *iml, GC gc, unsigned short w, unsigned short h } ximg = XGetImage(Xdisplay, p, 0, 0, w, h, -1, ZPixmap); if (ximg == NULL) { - print_warning("colormod_trans: XGetImage(Xdisplay, 0x%08x, 0, 0, %d, %d, -1, ZPixmap) returned NULL.", - p, w, h); + print_warning("XGetImage(Xdisplay, 0x%08x, 0, 0, %d, %d, -1, ZPixmap) returned NULL.", p, w, h); return; } D_PIXMAP(("XGetImage(Xdisplay, 0x%08x, 0, 0, %d, %d, -1, ZPixmap) returned %8p.\n", p, w, h, ximg)); @@ -1168,7 +1398,7 @@ colormod_trans(Pixmap p, imlib_t *iml, GC gc, unsigned short w, unsigned short h mr = mg = mb = 0xff; break; default: - print_warning("colormod_trans: Bit depth of %d is unsupported for tinting/shading.", real_depth); + print_warning("Bit depth of %d is unsupported for tinting/shading.", real_depth); return; } @@ -1193,6 +1423,55 @@ colormod_trans(Pixmap p, imlib_t *iml, GC gc, unsigned short w, unsigned short h XDestroyImage(ximg); } +unsigned char +update_desktop_info(int *w, int *h) +{ + unsigned int pw, ph, pb, pd; + int px, py; + Window dummy; + + if (w) { + *w = 0; + } + if (h) { + *h = 0; + } + if (desktop_window == None) { + get_desktop_window(); + } + if (desktop_window == None) { + print_error("Unable to locate desktop window. If you are running Enlightenment, please\n" + "restart. If not, please set your background image with Esetroot, then try again."); + return 0; + } + if (desktop_pixmap == None) { + get_desktop_pixmap(); + } + if (desktop_pixmap == None) { + return 0; + } + XGetGeometry(Xdisplay, desktop_pixmap, &dummy, &px, &py, &pw, &ph, &pb, &pd); + if ((pw <= 0) || (ph <= 0)) { + /* Reset and try again. */ + get_desktop_window(); + get_desktop_pixmap(); + XGetGeometry(Xdisplay, desktop_pixmap, &dummy, &px, &py, &pw, &ph, &pb, &pd); + } + if ((pw <= 0) || (ph <= 0)) { + print_error("Value of desktop pixmap property is invalid. Please restart your " + "window manager or use Esetroot to set a new one."); + desktop_pixmap = None; + return 0; + } + if (w) { + *w = pw; + } + if (h) { + *h = ph; + } + return 1; +} + Window get_desktop_window(void) { @@ -1204,12 +1483,12 @@ get_desktop_window(void) unsigned int nchildren; Window w, root, *children, parent; - D_PIXMAP(("get_desktop_window() called. Current desktop window is 0x%08x\n", (unsigned int) desktop_window)); + D_PIXMAP(("Current desktop window is 0x%08x\n", (unsigned int) desktop_window)); if ((prop = XInternAtom(Xdisplay, "_XROOTPMAP_ID", True)) == None) { - D_PIXMAP(("get_desktop_window(): No _XROOTPMAP_ID found.\n")); + D_PIXMAP(("No _XROOTPMAP_ID found.\n")); } if ((prop2 = XInternAtom(Xdisplay, "_XROOTCOLOR_PIXEL", True)) == None) { - D_PIXMAP(("get_desktop_window(): No _XROOTCOLOR_PIXEL found.\n")); + D_PIXMAP(("No _XROOTCOLOR_PIXEL found.\n")); } if (prop == None && prop2 == None) { return None; @@ -1240,7 +1519,7 @@ get_desktop_window(void) continue; } if (type != None) { - D_PIXMAP(("get_desktop_window(): Found desktop as window 0x%08x\n", w)); + D_PIXMAP(("Found desktop as window 0x%08x\n", w)); if (w != Xroot) { XSelectInput(Xdisplay, w, PropertyChangeMask); } @@ -1254,7 +1533,7 @@ get_desktop_window(void) } } - D_PIXMAP(("get_desktop_window(): No suitable parent found.\n")); + D_PIXMAP(("No suitable parent found.\n")); return (desktop_window = None); } @@ -1270,12 +1549,12 @@ get_desktop_pixmap(void) unsigned long length, after; unsigned char *data; - D_PIXMAP(("get_desktop_pixmap() called. Current desktop pixmap is 0x%08x\n", (unsigned int) desktop_pixmap)); + D_PIXMAP(("Current desktop pixmap is 0x%08x\n", (unsigned int) desktop_pixmap)); if (desktop_pixmap == None) { orig_desktop_pixmap = None; /* Forced re-read. */ } if (desktop_window == None) { - D_PIXMAP(("get_desktop_pixmap(): No desktop window. Aborting.\n")); + D_PIXMAP(("No desktop window. Aborting.\n")); free_desktop_pixmap(); return (desktop_pixmap = None); } @@ -1288,7 +1567,7 @@ get_desktop_pixmap(void) return (desktop_pixmap = None); } if (color_pixmap != None) { - D_PIXMAP(("get_desktop_pixmap(): Removing old solid color pixmap 0x%08x.\n", color_pixmap)); + D_PIXMAP(("Removing old solid color pixmap 0x%08x.\n", color_pixmap)); XFreePixmap(Xdisplay, color_pixmap); color_pixmap = None; } @@ -1299,10 +1578,10 @@ get_desktop_pixmap(void) if (p != None) { D_PIXMAP((" Found pixmap 0x%08x\n", p)); if (orig_desktop_pixmap == p) { - D_PIXMAP(("get_desktop_pixmap(): Desktop pixmap is unchanged.\n")); + D_PIXMAP(("Desktop pixmap is unchanged.\n")); return ((Pixmap) 1); } else { - D_PIXMAP(("get_desktop_pixmap(): Desktop pixmap has changed. Updating desktop_pixmap\n")); + D_PIXMAP(("Desktop pixmap has changed. Updating desktop_pixmap\n")); free_desktop_pixmap(); orig_desktop_pixmap = p; if (need_colormod(images[image_bg].current->iml)) { @@ -1316,7 +1595,7 @@ get_desktop_pixmap(void) gcvalue.foreground = gcvalue.background = PixColors[bgColor]; gc = XCreateGC(Xdisplay, TermWin.vt, GCForeground | GCBackground, &gcvalue); XGetGeometry(Xdisplay, p, &w, &px, &py, &pw, &ph, &pb, &pd); - D_PIXMAP(("get_desktop_pixmap(): XGetGeometry() returned w = 0x%08x, pw == %u, ph == %u\n", w, pw, ph)); + D_PIXMAP(("XGetGeometry() returned w = 0x%08x, pw == %u, ph == %u\n", w, pw, ph)); if (pw < (unsigned int) scr->width || ph < (unsigned int) scr->height) { desktop_pixmap = XCreatePixmap(Xdisplay, TermWin.parent, pw, ph, Xdepth); XCopyArea(Xdisplay, p, desktop_pixmap, gc, 0, 0, pw, ph, 0, 0); @@ -1328,11 +1607,11 @@ get_desktop_pixmap(void) } XFreeGC(Xdisplay, gc); desktop_pixmap_is_mine = 1; - D_PIXMAP(("get_desktop_pixmap() returning 0x%08x\n", (unsigned int) desktop_pixmap)); + D_PIXMAP(("Returning 0x%08x\n", (unsigned int) desktop_pixmap)); return (desktop_pixmap); } else { desktop_pixmap_is_mine = 0; - D_PIXMAP(("get_desktop_pixmap() returning 0x%08x\n", (unsigned int) p)); + D_PIXMAP(("Returning 0x%08x\n", (unsigned int) p)); return (desktop_pixmap = p); } } @@ -1356,12 +1635,12 @@ get_desktop_pixmap(void) color_pixmap = XCreatePixmap(Xdisplay, TermWin.vt, 16, 16, Xdepth); XFillRectangle(Xdisplay, color_pixmap, gc, 0, 0, 16, 16); - D_PIXMAP(("get_desktop_pixmap(): Created solid color pixmap 0x%08x for desktop_pixmap.\n", color_pixmap)); + D_PIXMAP(("Created solid color pixmap 0x%08x for desktop_pixmap.\n", color_pixmap)); XFreeGC(Xdisplay, gc); return (desktop_pixmap = color_pixmap); } } - D_PIXMAP(("get_desktop_pixmap(): No suitable attribute found.\n")); + D_PIXMAP(("No suitable attribute found.\n")); free_desktop_pixmap(); return (desktop_pixmap = None); @@ -1394,7 +1673,7 @@ shaped_window_apply_mask(Drawable d, Pixmap mask) if (have_shape == -1) { /* Don't know yet. */ int unused; - D_PIXMAP(("shaped_window_apply_mask(): Looking for shape extension.\n")); + D_PIXMAP(("Looking for shape extension.\n")); if (XQueryExtension(Xdisplay, "SHAPE", &unused, &unused, &unused)) { have_shape = 1; } else { @@ -1402,14 +1681,14 @@ shaped_window_apply_mask(Drawable d, Pixmap mask) } } if (have_shape == 1) { - D_PIXMAP(("shaped_window_apply_mask(): Shape extension available, applying mask.\n")); + D_PIXMAP(("Shape extension available, applying mask.\n")); XShapeCombineMask(Xdisplay, d, ShapeBounding, 0, 0, mask, ShapeSet); } else if (have_shape == 0) { - D_PIXMAP(("shaped_window_apply_mask(): Shape extension not available.\n")); + D_PIXMAP(("Shape extension not available.\n")); return; } # else - D_PIXMAP(("shaped_window_apply_mask(): Shape support disabled.\n")); + D_PIXMAP(("Shape support disabled.\n")); # endif } diff --git a/src/pixmap.h b/src/pixmap.h index 50d2423..1a1fcc7 100644 --- a/src/pixmap.h +++ b/src/pixmap.h @@ -62,8 +62,14 @@ enum { image_right, image_sb, image_sa, + image_st, image_menu, + image_menuitem, image_submenu, + image_button, + image_bbar, + image_gbar, + image_dialog, image_max }; @@ -94,6 +100,11 @@ enum { #define IMAGE_STATE_NORMAL (1) #define IMAGE_STATE_SELECTED (2) #define IMAGE_STATE_CLICKED (3) +#define IMAGE_STATE_DISABLED (4) + +/* Render options */ +#define RENDER_NORMAL (0) +#define RENDER_FORCE_PIXMAP (1 << 0) /* Helper macros */ #define FOREACH_IMAGE(x) do {unsigned char idx; for (idx = 0; idx < image_max; idx++) { x } } while (0) @@ -103,7 +114,7 @@ enum { #define image_mode_is(which, bit) (images[which].mode & (bit)) #define image_mode_fallback(which) do {if (image_mode_is((which), ALLOW_IMAGE)) {image_set_mode((which), MODE_IMAGE);} else {image_set_mode((which), MODE_SOLID);}} while (0) #define redraw_all_images() do {render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 0); \ - scr_touch(); scrollbar_draw(MODE_MASK); if (image_mode_any(MODE_AUTO)) enl_ipc_sync();} while (0) + scr_touch(); scrollbar_draw(IMAGE_STATE_CURRENT, MODE_MASK); if (image_mode_any(MODE_AUTO)) enl_ipc_sync();} while (0) /* Elements of an simage to be reset */ #define RESET_NONE (0UL) @@ -120,7 +131,13 @@ enum { #define RESET_PMAP_PIXMAP (1UL << 7) #define RESET_PMAP_MASK (1UL << 8) #define RESET_ALL_PMAP (RESET_PMAP_GEOM | RESET_PMAP_PIXMAP | RESET_PMAP_MASK) -#define RESET_ALL (RESET_ALL_IMLIB | RESET_ALL_PMAP) +#define RESET_ALL_SIMG (RESET_ALL_IMLIB | RESET_ALL_PMAP) +#define RESET_NORM (1UL << 9) +#define RESET_SELECTED (1UL << 10) +#define RESET_CLICKED (1UL << 11) +#define RESET_DISABLED (1UL << 12) +#define RESET_MODE (1UL << 13) +#define RESET_ALL (RESET_NORM | RESET_SELECTED | RESET_CLICKED | RESET_DISABLED | RESET_MODE) /************ Structures ************/ typedef struct { @@ -143,11 +160,12 @@ typedef struct { typedef struct { pixmap_t *pmap; imlib_t *iml; + Pixel fg, bg; } simage_t; typedef struct { Window win; - unsigned char mode; - simage_t *norm, *selected, *clicked, *current; + unsigned char mode, userdef; + simage_t *norm, *selected, *clicked, *disabled, *current; } image_t; typedef short renderop_t; @@ -165,17 +183,25 @@ extern unsigned char image_mode_any(unsigned char); extern unsigned short parse_pixmap_ops(char *); extern unsigned short set_pixmap_scale(const char *, pixmap_t *); extern unsigned char check_image_ipc(unsigned char); +extern image_t *create_eterm_image(void); +extern void reset_eterm_image(image_t *, unsigned long); +extern void free_eterm_image(image_t *); +extern simage_t *create_simage(void); extern void reset_simage(simage_t *, unsigned long); +extern void free_simage(simage_t *); +extern Pixmap create_trans_pixmap(simage_t *, unsigned char, Drawable, int, int, unsigned short, unsigned short); +extern Pixmap create_viewport_pixmap(simage_t *, Drawable, int, int, unsigned short, unsigned short); extern void paste_simage(simage_t *, unsigned char, Drawable, unsigned short, unsigned short, unsigned short, unsigned short); extern void redraw_image(unsigned char); extern void redraw_images_by_mode(unsigned char); extern void render_simage(simage_t *, Window, unsigned short, unsigned short, unsigned char, renderop_t); extern const char *search_path(const char *, const char *, const char *); -extern unsigned short load_image(const char *, short); +extern unsigned char load_image(const char *, simage_t *); extern void free_desktop_pixmap(void); #ifdef PIXMAP_OFFSET extern unsigned char need_colormod(imlib_t *); extern void colormod_trans(Pixmap, imlib_t *, GC, unsigned short, unsigned short); +extern unsigned char update_desktop_info(int *, int *); extern Window get_desktop_window(void); extern Pixmap get_desktop_pixmap(void); #endif diff --git a/src/screen.c b/src/screen.c index 26ab899..8284ff0 100644 --- a/src/screen.c +++ b/src/screen.c @@ -23,10 +23,11 @@ static const char cvs_ident[] = "$Id$"; #include /* CARD32 */ #include "../libmej/debug.h" +#include "../libmej/mem.h" +#include "../libmej/strings.h" #include "command.h" #include "debug.h" #include "startup.h" -#include "mem.h" #include "screen.h" #include "scrollbar.h" #include "options.h" @@ -100,9 +101,9 @@ unsigned char refresh_all = 0; * SCREEN `COMMON' ROUTINES * * ------------------------------------------------------------------------- */ /* Fill part/all of a drawn line with blanks. */ -inline void blank_line(text_t *, rend_t *, int, rend_t); +__inline__ void blank_line(text_t *, rend_t *, int, rend_t); -inline void +__inline__ void blank_line(text_t * et, rend_t * er, int width, rend_t efs) { /* int i = width; */ @@ -114,9 +115,9 @@ blank_line(text_t * et, rend_t * er, int width, rend_t efs) *r++ = fs; } -inline void blank_screen_mem(text_t **, rend_t **, int, rend_t); +__inline__ void blank_screen_mem(text_t **, rend_t **, int, rend_t); -inline void +__inline__ void blank_screen_mem(text_t **tp, rend_t **rp, int row, rend_t efs) { register unsigned int i = TermWin.ncol; @@ -206,18 +207,18 @@ scr_reset(void) for (i = TermWin.nrow; i < prev_nrow; i++) { j = i + TermWin.saveLines; - if (screen.text[j]) + if (screen.text[j]) { FREE(screen.text[j]); - if (screen.rend[j]) FREE(screen.rend[j]); - if (swap.text[i]) + } + if (swap.text[i]) { FREE(swap.text[i]); - if (swap.rend[i]) FREE(swap.rend[i]); - if (drawn_text[i]) + } + if (drawn_text[i]) { FREE(drawn_text[i]); - if (drawn_rend[i]) FREE(drawn_rend[i]); + } } screen.text = REALLOC(screen.text, total_rows * sizeof(text_t*)); buf_text = REALLOC(buf_text , total_rows * sizeof(text_t*)); @@ -666,7 +667,7 @@ scroll_text(int row1, int row2, int count, int spec) } else if (count < 0) { /* B: scroll down */ - count = min(-count, row2 - row1 + 1); + count = MIN(-count, row2 - row1 + 1); /* B1: Copy and blank out lines that will get clobbered by the rotation */ for (i = 0, j = row2; i < count; i++, j--) { buf_text[i] = screen.text[j]; @@ -1602,15 +1603,14 @@ scr_move_to(int y, int len) int scr_page(int direction, int nlines) { - int start, dirn; + int start; D_SCREEN(("scr_page(%s, %d) view_start:%d\n", ((direction == UP) ? "UP" : "DN"), nlines, TermWin.view_start)); - dirn = (direction == UP) ? 1 : -1; start = TermWin.view_start; MAX_IT(nlines, 1); MIN_IT(nlines, TermWin.nrow); - TermWin.view_start += (nlines * dirn); + TermWin.view_start += ((direction == UP) ? nlines : (-nlines)); MAX_IT(TermWin.view_start, 0); MIN_IT(TermWin.view_start, TermWin.nscrolled); @@ -2104,7 +2104,7 @@ scr_refresh(int type) if (type == SLOW_REFRESH) { XSync(Xdisplay, False); } - D_SCREEN(("scr_refresh() exiting.\n")); + D_SCREEN(("Exiting.\n")); #ifdef PROFILE_SCREEN P_SETTIMEVAL(cnt.stop); @@ -2113,7 +2113,127 @@ scr_refresh(int type) ++call_cnt, P_CMPTIMEVALS_USEC(cnt.start, cnt.stop), total_time); #endif } -/* TermWin term_win screen scr foobar */ + +int +scr_strmatch(unsigned long row, unsigned long col, const char *str) +{ + unsigned char c; + const char *s; + + for (c = screen.text[row][col], s = str; s; s++) { + if (c != *s) { + return (0); + } + } + return 1; +} + +/* Find and highlight all occurances of "str" in the scrollback. */ +void +scr_search_scrollback(char *str) +{ + unsigned char *c; + char *s; + static char *last_str = NULL; + unsigned int *i; + unsigned long row, lrow, col, rows, cols, len, k; + + if (str == NULL) { + if ((str = last_str) == NULL) { + return; + } + } else { + last_str = StrDup(str); + } + lrow = rows = TermWin.nrow + TermWin.saveLines; + cols = TermWin.ncol; + len = strlen(str); + + D_SCREEN(("%d, %d\n", rows, cols)); + for (row = 0; row < rows; row++) { + if (screen.text[row]) { + c = screen.text[row]; + for (s = strstr(c, str); s; s = strstr(++s, str)) { + unsigned long j; + + col = (int) s - (int) c; + for (i = screen.rend[row] + col, j = 0; j < len; i++, j++) { + if (*i & RS_RVid) { + *i &= ~RS_RVid; + } else { + *i |= RS_RVid; + } + } + if ((long) row <= TermWin.saveLines) { + lrow = row; + } + } + for (s = screen.text[row] + cols - len + 1, k = len - 1; k; s++, k--) { + unsigned long j; + + if ((row < rows - 1) && !strncasecmp(s, str, k) && screen.text[row + 1] && !strncasecmp(screen.text[row + 1], str + k, len - k)) { + col = (int) s - (int) c; + for (i = &(screen.rend[row][cols - k]), j = 0; j < k; i++, j++) { + (*i & RS_RVid) ? (*i &= ~RS_RVid) : (*i |= RS_RVid); + } + for (i = screen.rend[row + 1], j = 0, k = len - k; j < k; i++, j++) { + (*i & RS_RVid) ? (*i &= ~RS_RVid) : (*i |= RS_RVid); + } + if ((long) row <= TermWin.saveLines) { + lrow = row; + } + break; + } + } + } + } + if (last_str == str) { + FREE(last_str); + } else { + if (lrow != rows) { + TermWin.view_start = rows - lrow - TermWin.nrow; + LOWER_BOUND(TermWin.view_start, 0); + UPPER_BOUND(TermWin.view_start, TermWin.nscrolled); + D_SCREEN(("New view start is %d\n", TermWin.view_start)); + } + } + scr_refresh(refresh_type); +} + +/* Dump the entire contents of the scrollback buffer to stderr in hex and ASCII */ +void +scr_dump(void) +{ + unsigned char *c; + unsigned int *i; + unsigned long row, col, rows, cols; + + rows = TermWin.nrow + TermWin.saveLines; + cols = TermWin.ncol; + + D_SCREEN(("%d, %d\n", rows, cols)); + for (row = 0; row < rows; row++) { + fprintf(stderr, "%lu: ", row); + if (screen.text[row]) { + for (col = 0, c = screen.text[row]; col < cols; c++, col++) { + fprintf(stderr, "%02x ", *c); + } + fprintf(stderr, "\""); + for (col = 0, c = screen.text[row]; col < cols; c++, col++) { + fprintf(stderr, "%c", ((isprint(*c)) ? (*c) : '.')); + } + fprintf(stderr, "\""); + for (col = 0, i = screen.rend[row]; col < cols; i++, col++) { + fprintf(stderr, " %08x", *i); + } + } else { + fprintf(stderr, "NULL"); + } + fprintf(stderr, "\n"); + fflush(stderr); + } +} + /* ------------------------------------------------------------------------- * * CHARACTER SELECTION * @@ -2269,7 +2389,7 @@ selection_reset(void) i = (current_screen == PRIMARY) ? 0 : TermWin.saveLines; for (; i < lrow; i++) { - if (screen.text[i]) { /* not everything may be malloc()d yet */ + if (screen.text[i]) { for (j = 0; j < lcol; j++) { screen.rend[i][j] &= ~RS_Select; } @@ -2401,7 +2521,7 @@ selection_make(Time tm) char *str; text_t *t; - D_SELECT(("selection_make(): selection.op=%d, selection.clicks=%d\n", selection.op, selection.clicks)); + D_SELECT(("selection.op=%d, selection.clicks=%d\n", selection.op, selection.clicks)); switch (selection.op) { case SELECTION_CONT: break; @@ -2430,7 +2550,7 @@ selection_make(Time tm) str = MALLOC(i * sizeof(char)); new_selection_text = (unsigned char *) str; - col = max(selection.beg.col, 0); + col = MAX(selection.beg.col, 0); row = selection.beg.row + TermWin.saveLines; end_row = selection.end.row + TermWin.saveLines; /* @@ -2486,7 +2606,7 @@ selection_make(Time tm) print_error("can't get primary selection"); XChangeProperty(Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8, PropModeReplace, selection.text, selection.len); - D_SELECT(("selection_make(): selection.len=%d\n", selection.len)); + D_SELECT(("selection.len=%d\n", selection.len)); } /* ------------------------------------------------------------------------- */ @@ -2736,7 +2856,7 @@ selection_extend(int x, int y, int flag) selection.beg.row = selection.end.row = selection.mark.row; selection.beg.col = selection.end.col = selection.mark.col; selection.clicks = 4; - D_SELECT(("selection_extend() selection.clicks = 4\n")); + D_SELECT(("selection.clicks = 4\n")); return; } if (selection.clicks == 4) @@ -2934,7 +3054,7 @@ selection_extend_colrow(int col, int row, int flag, int cont) } selection.end.col = TermWin.ncol - 1; } - D_SELECT(("selection_extend_colrow(): (c:%d,r:%d)-(c:%d,r:%d) old (c:%d,r:%d)-(c:%d,r:%d)\n", selection.beg.col, selection.beg.row, + D_SELECT(("(c:%d,r:%d)-(c:%d,r:%d) old (c:%d,r:%d)-(c:%d,r:%d)\n", selection.beg.col, selection.beg.row, selection.end.col, selection.end.row, old_beg.col, old_beg.row, old_end.col, old_end.row)); /* diff --git a/src/screen.h b/src/screen.h index 160aa70..3016ac0 100644 --- a/src/screen.h +++ b/src/screen.h @@ -23,11 +23,11 @@ #define ZERO_SCROLLBACK do { \ D_SCREEN(("ZERO_SCROLLBACK()\n")); \ - if (Options & Opt_homeOnEcho) TermWin.view_start = 0; \ + if (Options & Opt_home_on_output) TermWin.view_start = 0; \ } while (0) #define REFRESH_ZERO_SCROLLBACK do { \ D_SCREEN(("REFRESH_ZERO_SCROLLBACK()\n")); \ - if (Options & Opt_homeOnRefresh) TermWin.view_start = 0; \ + if (Options & Opt_home_on_output) TermWin.view_start = 0; \ } while (0) #define CHECK_SELECTION do { \ if (selection.op) selection_check(); \ @@ -261,6 +261,9 @@ extern int scr_page(int, int); extern void scr_bell(void); extern void scr_printscreen(int); extern void scr_refresh(int); +extern int scr_strmatch(unsigned long, unsigned long, const char *); +extern void scr_search_scrollback(char *); +extern void scr_dump(void); extern void selection_check(void); extern void PasteIt(unsigned char *, unsigned int); extern void selection_paste(Window, unsigned, int); diff --git a/src/scrollbar.c b/src/scrollbar.c index fb40849..4370deb 100644 --- a/src/scrollbar.c +++ b/src/scrollbar.c @@ -30,6 +30,8 @@ static const char cvs_ident[] = "$Id$"; #include "../libmej/debug.h" #include "../libmej/mem.h" +#include "debug.h" +#include "buttons.h" #include "command.h" #include "draw.h" #include "e.h" @@ -374,6 +376,9 @@ scrollbar_draw_uparrow(unsigned char image_state, unsigned char force_modes) { } else if ((image_state == IMAGE_STATE_CLICKED) && (images[image_up].current != images[image_up].clicked)) { images[image_up].current = images[image_up].clicked; force_modes = MODE_MASK; + } else if ((image_state == IMAGE_STATE_DISABLED) && (images[image_up].current != images[image_up].disabled)) { + images[image_up].current = images[image_up].disabled; + force_modes = MODE_MASK; } } if (!image_mode_is(image_up, MODE_MASK)) { @@ -436,6 +441,9 @@ scrollbar_draw_downarrow(unsigned char image_state, unsigned char force_modes) { } else if ((image_state == IMAGE_STATE_CLICKED) && (images[image_down].current != images[image_down].clicked)) { images[image_down].current = images[image_down].clicked; force_modes = MODE_MASK; + } else if ((image_state == IMAGE_STATE_DISABLED) && (images[image_down].current != images[image_down].disabled)) { + images[image_down].current = images[image_down].disabled; + force_modes = MODE_MASK; } } if (!image_mode_is(image_down, MODE_MASK)) { @@ -498,6 +506,22 @@ scrollbar_draw_anchor(unsigned char image_state, unsigned char force_modes) { } else if ((image_state == IMAGE_STATE_CLICKED) && (images[image_sa].current != images[image_sa].clicked)) { images[image_sa].current = images[image_sa].clicked; force_modes = MODE_MASK; + } else if ((image_state == IMAGE_STATE_DISABLED) && (images[image_sa].current != images[image_sa].disabled)) { + images[image_sa].current = images[image_sa].disabled; + force_modes = MODE_MASK; + } + if ((image_state == IMAGE_STATE_NORMAL) && (images[image_st].current != images[image_st].norm)) { + images[image_st].current = images[image_st].norm; + force_modes = MODE_MASK; + } else if ((image_state == IMAGE_STATE_SELECTED) && (images[image_st].current != images[image_st].selected)) { + images[image_st].current = images[image_st].selected; + force_modes = MODE_MASK; + } else if ((image_state == IMAGE_STATE_CLICKED) && (images[image_st].current != images[image_st].clicked)) { + images[image_st].current = images[image_st].clicked; + force_modes = MODE_MASK; + } else if ((image_state == IMAGE_STATE_DISABLED) && (images[image_st].current != images[image_st].disabled)) { + images[image_st].current = images[image_st].disabled; + force_modes = MODE_MASK; } } if (!image_mode_is(image_sa, MODE_MASK)) { @@ -532,6 +556,34 @@ scrollbar_draw_anchor(unsigned char image_state, unsigned char force_modes) { } if (scrollbar_anchor_height() > 1) { render_simage(images[image_sa].current, scrollbar.sa_win, scrollbar_anchor_width(), scrollbar_anchor_height(), image_sa, 0); + + /* Draw the thumb if there is one. */ + if (images[image_st].current->iml) { + unsigned short tw = 0, th = 0; + imlib_t *iml = images[image_st].current->iml, *siml = images[image_sa].current->iml; + + if (image_mode_is(image_st, MODE_IMAGE) && iml->im) { + tw = iml->im->rgb_width; + th = iml->im->rgb_height; + } else if (siml->bevel) { + tw = scrollbar_anchor_width() - (siml->bevel->edges->left + siml->bevel->edges->right); + th = scrollbar_anchor_width() - (siml->bevel->edges->top + siml->bevel->edges->bottom); + } else if (siml->border) { + tw = scrollbar_anchor_width() - (siml->border->left + siml->border->right); + th = scrollbar_anchor_width() - (siml->border->top + siml->border->bottom); + } else if (iml->bevel) { + tw = iml->bevel->edges->left + iml->bevel->edges->right + 4; + th = iml->bevel->edges->top + iml->bevel->edges->bottom + 4; + } + UPPER_BOUND(tw, scrollbar_anchor_width()); + UPPER_BOUND(th, scrollbar_anchor_height() >> 1); + D_SCROLLBAR(("Thumb width/height has been calculated at %hux%hu.\n", tw, th)); + if ((tw > 0) && (th > 0)) { + paste_simage(images[image_st].current, image_st, images[image_sa].current->pmap->pixmap, (scrollbar_anchor_width() - tw) >> 1, (scrollbar_anchor_height() - th) >> 1, tw, th); + XSetWindowBackgroundPixmap(Xdisplay, scrollbar.sa_win, images[image_sa].current->pmap->pixmap); + XClearWindow(Xdisplay, scrollbar.sa_win); + } + } } } @@ -540,7 +592,7 @@ scrollbar_move_anchor(void) { static int last_x = -1, last_y = -1, last_w = -1, last_h = -1; int x, y, w, h; - D_SCROLLBAR(("scrollbar_move_anchor()\n")); + D_SCROLLBAR(("Last values: %d, %d, %d, %d\n", last_x, last_y, last_w, last_h)); x = scrollbar_get_shadow(); y = scrollbar.anchor_top; w = scrollbar_anchor_width(); @@ -572,6 +624,9 @@ scrollbar_draw_trough(unsigned char image_state, unsigned char force_modes) { } else if ((image_state == IMAGE_STATE_CLICKED) && (images[image_sb].current != images[image_sb].clicked)) { images[image_sb].current = images[image_sb].clicked; force_modes = MODE_MASK; + } else if ((image_state == IMAGE_STATE_DISABLED) && (images[image_sb].current != images[image_sb].disabled)) { + images[image_sb].current = images[image_sb].disabled; + force_modes = MODE_MASK; } } if (!image_mode_is(image_sb, MODE_MASK)) { @@ -598,10 +653,10 @@ scrollbar_init(int width, int height) Cursor cursor; long mask; - D_SCROLLBAR(("scrollbar_init(): Initializing all scrollbar elements.\n")); + D_SCROLLBAR(("Initializing all scrollbar elements.\n")); - Attributes.background_pixel = PixColors[scrollColor]; - Attributes.border_pixel = PixColors[bgColor]; + Attributes.background_pixel = images[image_sb].norm->bg; + Attributes.border_pixel = images[image_sb].norm->bg; Attributes.override_redirect = TRUE; Attributes.save_under = TRUE; cursor = XCreateFontCursor(Xdisplay, XC_left_ptr); @@ -612,30 +667,30 @@ scrollbar_init(int width, int height) scrollbar.anchor_bottom = scrollbar.scrollarea_end; /* Create the scrollbar trough window. It will be the parent to the other windows. */ - scrollbar.win = XCreateWindow(Xdisplay, TermWin.parent, ((Options & Opt_scrollbar_right) ? (width - scrollbar_trough_width()) : (0)), 0, scrollbar_trough_width(), height, + scrollbar.win = XCreateWindow(Xdisplay, TermWin.parent, ((Options & Opt_scrollbar_right) ? (width - scrollbar_trough_width()) : (0)), bbar_total_height(), scrollbar_trough_width(), height, 0, Xdepth, InputOutput, CopyFromParent, CWOverrideRedirect | CWBackingStore | CWBackPixel | CWBorderPixel | CWColormap, &Attributes); XDefineCursor(Xdisplay, scrollbar.win, cursor); XSelectInput(Xdisplay, scrollbar.win, mask); - D_SCROLLBAR(("scrollbar_init(): Created scrollbar window 0x%08x\n", scrollbar.win)); + D_SCROLLBAR(("Created scrollbar window 0x%08x\n", scrollbar.win)); /* Now the up arrow window. */ scrollbar.up_win = XCreateWindow(Xdisplay, scrollbar.win, scrollbar_get_shadow(), scrollbar_up_loc(), scrollbar_arrow_width(), scrollbar_arrow_height(), 0, Xdepth, InputOutput, CopyFromParent, CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWColormap, &Attributes); XSelectInput(Xdisplay, scrollbar.up_win, mask); - D_SCROLLBAR(("scrollbar_init(): Created scrollbar up arrow window 0x%08x\n", scrollbar.up_win)); + D_SCROLLBAR(("Created scrollbar up arrow window 0x%08x\n", scrollbar.up_win)); /* The down arrow window */ scrollbar.dn_win = XCreateWindow(Xdisplay, scrollbar.win, scrollbar_get_shadow(), scrollbar_dn_loc(), scrollbar_arrow_width(), scrollbar_arrow_height(), 0, Xdepth, InputOutput, CopyFromParent, CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWColormap, &Attributes); XSelectInput(Xdisplay, scrollbar.dn_win, mask); - D_SCROLLBAR(("scrollbar_init(): Created scrollbar down arrow window 0x%08x\n", scrollbar.dn_win)); + D_SCROLLBAR(("Created scrollbar down arrow window 0x%08x\n", scrollbar.dn_win)); /* The anchor window */ scrollbar.sa_win = XCreateWindow(Xdisplay, scrollbar.win, scrollbar_get_shadow(), scrollbar.anchor_top, scrollbar_anchor_width(), scrollbar_anchor_height(), 0, Xdepth, InputOutput, CopyFromParent, CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWColormap, &Attributes); XSelectInput(Xdisplay, scrollbar.sa_win, mask); XMapWindow(Xdisplay, scrollbar.sa_win); - D_SCROLLBAR(("scrollbar_init(): Created scrollbar anchor window 0x%08x\n", scrollbar.sa_win)); + D_SCROLLBAR(("Created scrollbar anchor window 0x%08x\n", scrollbar.sa_win)); if (scrollbar_get_type() != SCROLLBAR_XTERM) { scrollbar_map_arrows(); @@ -643,7 +698,7 @@ scrollbar_init(int width, int height) event_register_dispatcher(scrollbar_dispatch_event, scrollbar_event_init_dispatcher); scrollbar_drawing_init(); - scrollbar_draw(MODE_MASK); + scrollbar_draw(IMAGE_STATE_CURRENT, MODE_MASK); } unsigned char @@ -720,8 +775,9 @@ scrollbar_resize(int width, int height) D_SCROLLBAR(("scrollbar_resize(%d, %d)\n", width, height)); scrollbar_calc_size(width, height); - D_SCROLLBAR((" -> XMoveResizeWindow(Xdisplay, 0x%08x, %d, %d, %d, %d)\n", scrollbar.win, ((Options & Opt_scrollbar_right) ? (width - scrollbar_trough_width()) : (0)), 0, scrollbar_trough_width(), height)); - XMoveResizeWindow(Xdisplay, scrollbar.win, ((Options & Opt_scrollbar_right) ? (width - scrollbar_trough_width()) : (0)), 0, scrollbar_trough_width(), height); + D_SCROLLBAR((" -> XMoveResizeWindow(Xdisplay, 0x%08x, %d, %d, %d, %d)\n", scrollbar.win, ((Options & Opt_scrollbar_right) ? (width - scrollbar_trough_width()) : (0)), + bbar_total_height(), scrollbar_trough_width(), height)); + XMoveResizeWindow(Xdisplay, scrollbar.win, ((Options & Opt_scrollbar_right) ? (width - scrollbar_trough_width()) : (0)), bbar_total_height(), scrollbar_trough_width(), height); scrollbar_draw_trough(IMAGE_STATE_CURRENT, MODE_MASK); scrollbar_reposition_and_draw(MODE_MASK); scrollbar.init = 0; @@ -802,7 +858,7 @@ scrollbar_drawing_init(void) { XGCValues gcvalue; - D_SCROLLBAR(("scrollbar_drawing_init()\n")); + D_SCROLLBAR(("Called.\n")); #ifdef XTERM_SCROLLBAR gcvalue.stipple = XCreateBitmapFromData(Xdisplay, scrollbar.win, (char *) xterm_sb_bits, 12, 2); if (!gcvalue.stipple) { @@ -821,7 +877,7 @@ scrollbar_drawing_init(void) { #endif /* XTERM_SCROLLBAR */ #if defined(MOTIF_SCROLLBAR) || defined(NEXT_SCROLLBAR) - gcvalue.foreground = PixColors[scrollColor]; + gcvalue.foreground = images[image_sb].norm->bg; gc_scrollbar = XCreateGC(Xdisplay, scrollbar.win, GCForeground, &gcvalue); gcvalue.foreground = PixColors[topShadowColor]; gc_top = XCreateGC(Xdisplay, scrollbar.win, GCForeground, &gcvalue); @@ -839,7 +895,7 @@ scrollbar_set_focus(short has_focus) { D_SCROLLBAR(("scrollbar_set_focus(%hd): focus == %hd\n", has_focus, focus)); if (focus != has_focus) { focus = has_focus; - gcvalue.foreground = PixColors[focus ? scrollColor : unfocusedScrollColor]; + gcvalue.foreground = (focus ? (images[image_sb].norm->bg) : (images[image_sb].disabled->bg)); XChangeGC(Xdisplay, gc_scrollbar, GCForeground, &gcvalue); gcvalue.foreground = PixColors[focus ? topShadowColor : unfocusedTopShadowColor]; XChangeGC(Xdisplay, gc_top, GCForeground, &gcvalue); @@ -895,13 +951,13 @@ scrollbar_anchor_update_position(short mouseoffset) { } void -scrollbar_draw(unsigned char force_modes) +scrollbar_draw(unsigned char image_state, unsigned char force_modes) { - D_SCROLLBAR(("scrollbar_draw(0x%02x)\n", force_modes)); - scrollbar_draw_trough(IMAGE_STATE_CURRENT, force_modes); - scrollbar_draw_anchor(IMAGE_STATE_CURRENT, force_modes); - scrollbar_draw_uparrow(IMAGE_STATE_CURRENT, force_modes); - scrollbar_draw_downarrow(IMAGE_STATE_CURRENT, force_modes); + D_SCROLLBAR(("scrollbar_draw(%d, 0x%02x)\n", image_state, force_modes)); + scrollbar_draw_trough(image_state, force_modes); + scrollbar_draw_anchor(image_state, force_modes); + scrollbar_draw_uparrow(image_state, force_modes); + scrollbar_draw_downarrow(image_state, force_modes); scrollbar.init = 1; } diff --git a/src/scrollbar.h b/src/scrollbar.h index 78aaa11..272957f 100644 --- a/src/scrollbar.h +++ b/src/scrollbar.h @@ -148,7 +148,7 @@ extern void scrollbar_change_width(unsigned short); extern void scrollbar_drawing_init(void); extern unsigned char scrollbar_set_focus(short has_focus); extern unsigned char scrollbar_anchor_update_position(short mouseoffset); -extern void scrollbar_draw(unsigned char force_modes); +extern void scrollbar_draw(unsigned char image_state, unsigned char force_modes); extern void scrollbar_reposition_and_draw(unsigned char force_modes); extern void scrollbar_reposition_and_always_draw(void); extern unsigned char scrollbar_show(short); diff --git a/src/startup.c b/src/startup.c index 3ddf6ad..12b19a1 100644 --- a/src/startup.c +++ b/src/startup.c @@ -44,11 +44,12 @@ static const char cvs_ident[] = "$Id$"; #include #include "../libmej/debug.h" /* from libmej */ -#include "debug.h" #include "../libmej/mem.h" #include "../libmej/strings.h" +#include "debug.h" #include "startup.h" #include "actions.h" +#include "buttons.h" #include "command.h" #include "eterm_utmp.h" #include "events.h" @@ -154,8 +155,23 @@ eterm_bootstrap(int argc, char *argv[]) get_modifiers(); /* Set up modifier masks before parsing config files. */ - read_config(THEME_CFG); - read_config((rs_config_file ? rs_config_file : USER_CFG)); + /* Initialize the parser */ + conf_init_subsystem(); + + if ((theme_dir = conf_parse_theme(rs_theme, THEME_CFG, 1)) != NULL) { + char *tmp; + + tmp = (char *) MALLOC(strlen(theme_dir) + sizeof("ETERM_THEME_ROOT=\0")); + sprintf(tmp, "ETERM_THEME_ROOT=%s", theme_dir); + putenv(tmp); + } + if ((user_dir = conf_parse_theme(rs_theme, (rs_config_file ? rs_config_file : USER_CFG), 0)) != NULL) { + char *tmp; + + tmp = (char *) MALLOC(strlen(user_dir) + sizeof("ETERM_USER_ROOT=\0")); + sprintf(tmp, "ETERM_USER_ROOT=%s", user_dir); + putenv(tmp); + } #if defined(PIXMAP_SUPPORT) if (rs_path || theme_dir || user_dir) { @@ -206,16 +222,24 @@ eterm_bootstrap(int argc, char *argv[]) } #endif + process_colors(); + Create_Windows(argc, argv); scr_reset(); /* initialize screen */ /* Initialize the scrollbar */ - scrollbar_init(szHint.width, szHint.height); + scrollbar_init(szHint.width, szHint.height - bbar_total_height()); scrollbar_mapping(Options & Opt_scrollbar); /* Initialize the menu subsystem. */ menu_init(); + if (buttonbar) { + bbar_init(buttonbar, szHint.width); + bbar_dock(buttonbar, BBAR_DOCKED_TOP); + bbar_show(buttonbar, 1); + } + #if DEBUG >= DEBUG_X if (debug_level >= DEBUG_X) { XSynchronize(Xdisplay, True); diff --git a/src/startup.h b/src/startup.h index fc32554..398e23c 100644 --- a/src/startup.h +++ b/src/startup.h @@ -24,40 +24,49 @@ */ #ifndef _STARTUP_H -# define _STARTUP_H -# include -# include /* Xlib, Xutil, Xresource, Xfuncproto */ -# include -# include -# include -# include -# include -# include "misc.h" +#define _STARTUP_H +#include +#include /* Xlib, Xutil, Xresource, Xfuncproto */ +#include +#include +#include +#include +#include +#include "misc.h" /************ Macros and Definitions ************/ -# ifndef EXIT_SUCCESS /* missing from */ -# define EXIT_SUCCESS 0 /* exit function success */ -# define EXIT_FAILURE 1 /* exit function failure */ -# endif +#ifndef EXIT_SUCCESS /* missing from */ +# define EXIT_SUCCESS 0 /* exit function success */ +# define EXIT_FAILURE 1 /* exit function failure */ +#endif -# define THEME_CFG "theme.cfg" -# define USER_CFG "user.cfg" +#define THEME_CFG "theme.cfg" +#define USER_CFG "user.cfg" -# define MAX_COLS 200 -# define MAX_ROWS 128 +#define MAX_COLS 200 +#define MAX_ROWS 128 -# ifndef min -# define min(a,b) (((a) < (b)) ? (a) : (b)) -# endif -# ifndef max -# define max(a,b) (((a) > (b)) ? (a) : (b)) -# endif -# ifndef MIN -# define MIN(a,b) (((a) < (b)) ? (a) : (b)) -# endif -# ifndef MAX -# define MAX(a,b) (((a) > (b)) ? (a) : (b)) -# endif +#ifdef MIN +# undef MIN +#endif +#ifdef MAX +# undef MAX +#endif +#ifdef __GNUC__ +# define MIN(a,b) __extension__ ({__typeof__(a) aa = (a); __typeof__(b) bb = (b); (aa < bb) ? (aa) : (bb);}) +# define MAX(a,b) __extension__ ({__typeof__(a) aa = (a); __typeof__(b) bb = (b); (aa > bb) ? (aa) : (bb);}) +# define LOWER_BOUND(current, other) __extension__ ({__typeof__(other) o = (other); ((current) < o) ? ((current) = o) : (current);}) +# define AT_LEAST(current, other) LOWER_BOUND(current, other) +# define MAX_IT(current, other) LOWER_BOUND(current, other) +# define UPPER_BOUND(current, other) __extension__ ({__typeof__(other) o = (other); ((current) > o) ? ((current) = o) : (current);}) +# define AT_MOST(current, other) UPPER_BOUND(current, other) +# define MIN_IT(current, other) UPPER_BOUND(current, other) +# define BOUND(val, min, max) __extension__ ({__typeof__(min) m1 = (min); __typeof__(max) m2 = (max); ((val) < m1) ? ((val) = m1) : (((val) > m2) ? ((val) = m2) : (val));}) +# define CONTAIN(val, min, max) BOUND(val, min, max) +# define SWAP_IT(one, two, tmp) do {(tmp) = (one); (one) = (two); (two) = (tmp);} while (0) +#else +# define MIN(a,b) (((a) < (b)) ? (a) : (b)) +# define MAX(a,b) (((a) > (b)) ? (a) : (b)) # define LOWER_BOUND(current, other) (((current) < (other)) ? ((current) = (other)) : (current)) # define AT_LEAST(current, other) LOWER_BOUND(current, other) # define MAX_IT(current, other) LOWER_BOUND(current, other) @@ -67,32 +76,33 @@ # define BOUND(val, min, max) (((val) < (min)) ? ((val) = (min)) : (((val) > (max)) ? ((val) = (max)) : (val))) # define CONTAIN(val, min, max) BOUND(val, min, max) # define SWAP_IT(one, two, tmp) do {(tmp) = (one); (one) = (two); (two) = (tmp);} while (0) +#endif /* width of scrollbar, menuBar shadow ... don't change! */ -# define SHADOW 2 +#define SHADOW 2 /* convert pixel dimensions to row/column values */ -# define Pixel2Width(x) ((x) / TermWin.fwidth) -# define Pixel2Height(y) ((y) / TermWin.fheight) -# define Pixel2Col(x) Pixel2Width((x) - TermWin.internalBorder) -# define Pixel2Row(y) Pixel2Height((y) - TermWin.internalBorder) -# define Width2Pixel(n) ((n) * TermWin.fwidth) -# define Height2Pixel(n) ((n) * TermWin.fheight) -# define Col2Pixel(col) (Width2Pixel(col) + TermWin.internalBorder) -# define Row2Pixel(row) (Height2Pixel(row) + TermWin.internalBorder) +#define Pixel2Width(x) ((x) / TermWin.fwidth) +#define Pixel2Height(y) ((y) / TermWin.fheight) +#define Pixel2Col(x) Pixel2Width((x) - TermWin.internalBorder) +#define Pixel2Row(y) Pixel2Height((y) - TermWin.internalBorder) +#define Width2Pixel(n) ((n) * TermWin.fwidth) +#define Height2Pixel(n) ((n) * TermWin.fheight) +#define Col2Pixel(col) (Width2Pixel(col) + TermWin.internalBorder) +#define Row2Pixel(row) (Height2Pixel(row) + TermWin.internalBorder) -# define TermWin_TotalWidth() (TermWin.width + 2 * TermWin.internalBorder) -# define TermWin_TotalHeight() (TermWin.height + 2 * TermWin.internalBorder) +#define TermWin_TotalWidth() (TermWin.width + 2 * TermWin.internalBorder) +#define TermWin_TotalHeight() (TermWin.height + 2 * TermWin.internalBorder) -# define Xscreen DefaultScreen(Xdisplay) -# define Xcmap DefaultColormap(Xdisplay,Xscreen) -# define Xdepth DefaultDepth(Xdisplay,Xscreen) -# define Xroot DefaultRootWindow(Xdisplay) -# define Xvisual DefaultVisual(Xdisplay, Xscreen) -# ifdef DEBUG_DEPTH -# undef Xdepth -# define Xdepth DEBUG_DEPTH -# endif +#define Xscreen DefaultScreen(Xdisplay) +#define Xcmap DefaultColormap(Xdisplay,Xscreen) +#define Xdepth DefaultDepth(Xdisplay,Xscreen) +#define Xroot DefaultRootWindow(Xdisplay) +#define Xvisual DefaultVisual(Xdisplay, Xscreen) +#ifdef DEBUG_DEPTH +# undef Xdepth +# define Xdepth DEBUG_DEPTH +#endif /************ Structures ************/ typedef struct { @@ -110,12 +120,12 @@ typedef struct { GC gc; /* GC for drawing text */ XFontStruct * font; /* main font structure */ XFontSet fontset; -# ifndef NO_BOLDFONT +#ifndef NO_BOLDFONT XFontStruct * boldFont; /* bold font */ -# endif -# ifdef MULTI_CHARSET +#endif +#ifdef MULTI_CHARSET XFontStruct * mfont; /* multibyte font structure */ -# endif +#endif } TermWin_t; /************ Variables ************/ diff --git a/src/system.c b/src/system.c index b1b15b1..68316ea 100644 --- a/src/system.c +++ b/src/system.c @@ -57,14 +57,14 @@ wait_for_chld(int system_pid) /* If the child that exited is the command we spawned, or if the child exited before fork() returned in the parent, it must be our immediate child that exited. We exit gracefully. */ - D_OPTIONS(("wait_for_chld(): %ld exited.\n", pid)); + D_OPTIONS(("%ld exited.\n", pid)); if (pid == system_pid || system_pid == -1) { if (WIFEXITED(status)) { code = WEXITSTATUS(status); - D_OPTIONS(("wait_for_chld(): Child process exited with return code %lu\n", code)); + D_OPTIONS(("Child process exited with return code %lu\n", code)); } else if (WIFSIGNALED(status)) { code = WTERMSIG(status); - D_OPTIONS(("wait_for_chld(): Child process was terminated by unhandled signal %lu\n", code)); + D_OPTIONS(("Child process was terminated by unhandled signal %lu\n", code)); } else { code = 0; } @@ -89,7 +89,7 @@ system_wait(char *command) setreuid(my_ruid, my_ruid); setregid(my_rgid, my_rgid); execl("/bin/sh", "sh", "-c", command, (char *) NULL); - print_error("system_wait(): execl(%s) failed -- %s", command, strerror(errno)); + print_error("execl(%s) failed -- %s", command, strerror(errno)); exit(EXIT_FAILURE); } else { D_OPTIONS(("%d: fork() returned %d\n", getpid(), pid)); @@ -109,7 +109,7 @@ system_no_wait(char *command) setreuid(my_ruid, my_ruid); setregid(my_rgid, my_rgid); execl("/bin/sh", "sh", "-c", command, (char *) NULL); - print_error("system_no_wait(): execl(%s) failed -- %s", command, strerror(errno)); + print_error("execl(%s) failed -- %s", command, strerror(errno)); exit(EXIT_FAILURE); } return (0); diff --git a/src/term.c b/src/term.c index 8785314..673c2dc 100644 --- a/src/term.c +++ b/src/term.c @@ -122,16 +122,16 @@ get_modifiers(void) switch (XKeycodeToKeysym(Xdisplay, kc[k], 0)) { case XK_Meta_L: case XK_Meta_R: - D_X11(("get_modifiers() found Meta key as mod %d\n", l + 1)); + D_X11(("Found Meta key as mod %d\n", l + 1)); match = MetaMask = modmasks[l]; break; case XK_Alt_L: case XK_Alt_R: - D_X11(("get_modifiers() found Alt key as mod %d\n", l + 1)); + D_X11(("Found Alt key as mod %d\n", l + 1)); match = AltMask = modmasks[l]; break; case XK_Num_Lock: - D_X11(("get_modifiers() found NumLock key as mod %d\n", l + 1)); + D_X11(("Found NumLock key as mod %d\n", l + 1)); match = NumLockMask = modmasks[l]; break; default: @@ -145,15 +145,15 @@ get_modifiers(void) XFreeModifiermap(modmap); if (MetaMask == 0) { if (AltMask != 0) { - D_X11(("get_modifiers() defaulted Meta key to match Alt mask\n")); + D_X11(("Defaulted Meta key to match Alt mask\n")); MetaMask = AltMask; } else { - D_X11(("get_modifiers() defaulted Meta key to mod 1\n")); + D_X11(("Defaulted Meta key to mod 1\n")); MetaMask = Mod1Mask; } } if (AltMask == 0) { - D_X11(("get_modifiers() defaulted Alt key to match Meta mask\n")); + D_X11(("Defaulted Alt key to match Meta mask\n")); AltMask = MetaMask; /* MetaMask will always be defined at this point. */ } } @@ -180,9 +180,6 @@ lookup_key(XEvent * ev) #else static unsigned char kbuf[KBUFSZ]; #endif -#if DEBUG >= DEBUG_CMD - static int debug_key = 1; /* accessible by a debugger only */ -#endif #ifdef GREEK_SUPPORT static short greek_mode = 0; #endif @@ -236,13 +233,9 @@ lookup_key(XEvent * ev) if (action_dispatch(ev, keysym)) { LK_RET(); - } - if (len) { - if (keypress_exit) { + } + if (len && keypress_exit) { exit(0); - } else if (Options & Opt_homeOnInput) { - TermWin.view_start = 0; - } } if ((Options & Opt_report_as_keysyms) && (keysym >= 0xff00)) { @@ -357,6 +350,11 @@ lookup_key(XEvent * ev) break; } + /* If we get this far, the keypress had no special meaning to us. */ + if (Options & Opt_home_on_input) { + TermWin.view_start = 0; + } + if (keysym >= 0xFF00 && keysym <= 0xFFFF) { #ifdef KEYSYM_ATTRIBUTE if (!(shft | ctrl) && KeySym_map[keysym - 0xFF00] != NULL) { @@ -571,22 +569,22 @@ lookup_key(XEvent * ev) kbuf[2] += (keysym - XK_KP_F1); break; - case XK_KP_Multiply: /* "\033Oj" : "*" */ - case XK_KP_Add: /* "\033Ok" : "+" */ - case XK_KP_Separator: /* "\033Ol" : "," */ - case XK_KP_Subtract: /* "\033Om" : "-" */ - case XK_KP_Decimal: /* "\033On" : "." */ - case XK_KP_Divide: /* "\033Oo" : "/" */ - case XK_KP_0: /* "\033Op" : "0" */ - case XK_KP_1: /* "\033Oq" : "1" */ - case XK_KP_2: /* "\033Or" : "2" */ - case XK_KP_3: /* "\033Os" : "3" */ - case XK_KP_4: /* "\033Ot" : "4" */ - case XK_KP_5: /* "\033Ou" : "5" */ - case XK_KP_6: /* "\033Ov" : "6" */ - case XK_KP_7: /* "\033Ow" : "7" */ - case XK_KP_8: /* "\033Ox" : "8" */ - case XK_KP_9: /* "\033Oy" : "9" */ + case XK_KP_Multiply: /* "\033Oj" : "*" */ + case XK_KP_Add: /* "\033Ok" : "+" */ + case XK_KP_Separator: /* "\033Ol" : "," */ + case XK_KP_Subtract: /* "\033Om" : "-" */ + case XK_KP_Decimal: /* "\033On" : "." */ + case XK_KP_Divide: /* "\033Oo" : "/" */ + case XK_KP_0: /* "\033Op" : "0" */ + case XK_KP_1: /* "\033Oq" : "1" */ + case XK_KP_2: /* "\033Or" : "2" */ + case XK_KP_3: /* "\033Os" : "3" */ + case XK_KP_4: /* "\033Ot" : "4" */ + case XK_KP_5: /* "\033Ou" : "5" */ + case XK_KP_6: /* "\033Ov" : "6" */ + case XK_KP_7: /* "\033Ow" : "7" */ + case XK_KP_8: /* "\033Ox" : "8" */ + case XK_KP_9: /* "\033Oy" : "9" */ /* allow shift to override */ if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { len = 3; @@ -603,55 +601,55 @@ len = 5; \ sprintf((char *) kbuf,"\033[%02d~", (int)((n) + (keysym - fkey))); \ } while (0); - case XK_F1: /* "\033[11~" */ - case XK_F2: /* "\033[12~" */ - case XK_F3: /* "\033[13~" */ - case XK_F4: /* "\033[14~" */ - case XK_F5: /* "\033[15~" */ - FKEY(11, XK_F1); - break; + case XK_F1: /* "\033[11~" */ + case XK_F2: /* "\033[12~" */ + case XK_F3: /* "\033[13~" */ + case XK_F4: /* "\033[14~" */ + case XK_F5: /* "\033[15~" */ + FKEY(11, XK_F1); + break; - case XK_F6: /* "\033[17~" */ - case XK_F7: /* "\033[18~" */ - case XK_F8: /* "\033[19~" */ - case XK_F9: /* "\033[20~" */ - case XK_F10: /* "\033[21~" */ - FKEY(17, XK_F6); - break; + case XK_F6: /* "\033[17~" */ + case XK_F7: /* "\033[18~" */ + case XK_F8: /* "\033[19~" */ + case XK_F9: /* "\033[20~" */ + case XK_F10: /* "\033[21~" */ + FKEY(17, XK_F6); + break; - case XK_F11: /* "\033[23~" */ - case XK_F12: /* "\033[24~" */ - case XK_F13: /* "\033[25~" */ - case XK_F14: /* "\033[26~" */ - FKEY(23, XK_F11); - break; + case XK_F11: /* "\033[23~" */ + case XK_F12: /* "\033[24~" */ + case XK_F13: /* "\033[25~" */ + case XK_F14: /* "\033[26~" */ + FKEY(23, XK_F11); + break; - case XK_F15: /* "\033[28~" */ - case XK_F16: /* "\033[29~" */ - FKEY(28, XK_F15); - break; + case XK_F15: /* "\033[28~" */ + case XK_F16: /* "\033[29~" */ + FKEY(28, XK_F15); + break; - case XK_F17: /* "\033[31~" */ - case XK_F18: /* "\033[32~" */ - case XK_F19: /* "\033[33~" */ - case XK_F20: /* "\033[34~" */ - case XK_F21: /* "\033[35~" */ - case XK_F22: /* "\033[36~" */ - case XK_F23: /* "\033[37~" */ - case XK_F24: /* "\033[38~" */ - case XK_F25: /* "\033[39~" */ - case XK_F26: /* "\033[40~" */ - case XK_F27: /* "\033[41~" */ - case XK_F28: /* "\033[42~" */ - case XK_F29: /* "\033[43~" */ - case XK_F30: /* "\033[44~" */ - case XK_F31: /* "\033[45~" */ - case XK_F32: /* "\033[46~" */ - case XK_F33: /* "\033[47~" */ - case XK_F34: /* "\033[48~" */ - case XK_F35: /* "\033[49~" */ - FKEY(31, XK_F17); - break; + case XK_F17: /* "\033[31~" */ + case XK_F18: /* "\033[32~" */ + case XK_F19: /* "\033[33~" */ + case XK_F20: /* "\033[34~" */ + case XK_F21: /* "\033[35~" */ + case XK_F22: /* "\033[36~" */ + case XK_F23: /* "\033[37~" */ + case XK_F24: /* "\033[38~" */ + case XK_F25: /* "\033[39~" */ + case XK_F26: /* "\033[40~" */ + case XK_F27: /* "\033[41~" */ + case XK_F28: /* "\033[42~" */ + case XK_F29: /* "\033[43~" */ + case XK_F30: /* "\033[44~" */ + case XK_F31: /* "\033[45~" */ + case XK_F32: /* "\033[46~" */ + case XK_F33: /* "\033[47~" */ + case XK_F34: /* "\033[48~" */ + case XK_F35: /* "\033[49~" */ + FKEY(31, XK_F17); + break; #undef FKEY } @@ -685,8 +683,9 @@ sprintf((char *) kbuf,"\033[%02d~", (int)((n) + (keysym - fkey))); \ } #endif - if (len <= 0) - LK_RET(); /* not mapped */ + if (len <= 0) { + LK_RET(); + } /* * these modifications only affect the static keybuffer @@ -694,12 +693,13 @@ sprintf((char *) kbuf,"\033[%02d~", (int)((n) + (keysym - fkey))); \ * * eg, * Prior = "ESC[5~" - * Shift+Prior = "ESC[5~" + * Shift+Prior = "ESC[5$" * Ctrl+Prior = "ESC[5^" * Ctrl+Shift+Prior = "ESC[5@" */ - if (kbuf[0] == '\033' && kbuf[1] == '[' && kbuf[len - 1] == '~') + if (kbuf[0] == '\033' && kbuf[1] == '[' && kbuf[len - 1] == '~') { kbuf[len - 1] = (shft ? (ctrl ? '@' : '$') : (ctrl ? '^' : '~')); + } /* escape prefix */ if (meta @@ -713,8 +713,7 @@ sprintf((char *) kbuf,"\033[%02d~", (int)((n) + (keysym - fkey))); \ tt_write(&ch, 1); } #if DEBUG >= DEBUG_CMD - if (debug_level >= DEBUG_CMD && debug_key) { /* Display keyboard buffer contents */ - + if (debug_level >= DEBUG_CMD) { char *p; int i; @@ -1417,22 +1416,16 @@ process_terminal_mode(int mode, int priv, unsigned int nargs, int arg[]) break; /* X11 mouse highlighting */ #endif case 1010: /* Scroll to bottom on TTY output */ - if (Options & Opt_homeOnEcho) - Options &= ~Opt_homeOnEcho; + if (Options & Opt_home_on_output) + Options &= ~Opt_home_on_output; else - Options |= Opt_homeOnEcho; - break; - case 1011: /* scroll to bottom on refresh */ - if (Options & Opt_homeOnRefresh) - Options &= ~Opt_homeOnRefresh; - else - Options |= Opt_homeOnRefresh; + Options |= Opt_home_on_output; break; case 1012: /* Scroll to bottom on TTY input */ - if (Options & Opt_homeOnInput) - Options &= ~Opt_homeOnInput; + if (Options & Opt_home_on_input) + Options &= ~Opt_home_on_input; else - Options |= Opt_homeOnInput; + Options |= Opt_home_on_input; break; } break; @@ -1509,27 +1502,6 @@ process_sgr_mode(unsigned int nargs, int arg[]) } } -/* color aliases, fg/bg bright-bold */ -void -color_aliases(int idx) -{ - - if (rs_color[idx] && isdigit(*rs_color[idx])) { - - int i = atoi(rs_color[idx]); - - if (i >= 8 && i <= 15) { /* bright colors */ - i -= 8; -#ifndef NO_BRIGHTCOLOR - rs_color[idx] = rs_color[minBright + i]; - return; -#endif - } - if (i >= 0 && i <= 7) /* normal colors */ - rs_color[idx] = rs_color[minColor + i]; - } -} - /* find if fg/bg matches any of the normal (low-intensity) colors */ #ifndef NO_BRIGHTCOLOR void @@ -1604,7 +1576,7 @@ set_title(const char *str) if (name != NULL) { FREE(name); } - D_X11(("set_title(): Setting window title to \"%s\"\n", str)); + D_X11(("Setting window title to \"%s\"\n", str)); XStoreName(Xdisplay, TermWin.parent, str); name = StrDup(str); } @@ -1620,7 +1592,7 @@ set_icon_name(const char *str) if (name != NULL) { FREE(name); } - D_X11(("set_icon_name(): Setting window icon name to \"%s\"\n", str)); + D_X11(("Setting window icon name to \"%s\"\n", str)); XSetIconName(Xdisplay, TermWin.parent, str); name = StrDup(str); } @@ -1708,6 +1680,7 @@ xterm_seq(int op, const char *str) 50 Move window to another desktop 70 Exit Eterm 71 Save current configuration to a file + 72 Search scrollback for a string and is an optional argument, depending on the particular sequence being used. It (along with its preceeding semicolon) may or @@ -2022,6 +1995,22 @@ xterm_seq(int op, const char *str) save_config(NULL); } break; + case 72: + /* Search scrollback buffer for a string. NULL to clear. */ + nstr = (char *) strsep(&tnstr, ";"); + if (nstr && *nstr) { + scr_search_scrollback(nstr); + } else { + scr_search_scrollback(NULL); + } + break; + case 73: + /* Spawn a subprogram */ + nstr = (char *) strsep(&tnstr, ";"); + if (nstr && *nstr) { + system_no_wait(nstr); + } + break; case 80: /* Set debugging level */ nstr = (char *) strsep(&tnstr, ";"); @@ -2047,7 +2036,7 @@ xterm_seq(int op, const char *str) if (*nstr) { set_pixmap_scale("", images[image_bg].current->pmap); bg_needs_update = 1; - load_image(nstr, image_bg); + load_image(nstr, images[image_bg].current); } while ((nstr = (char *) strsep(&tnstr, ";")) && *nstr) { changed += set_pixmap_scale(nstr, images[image_bg].current->pmap); diff --git a/src/term.h b/src/term.h index 02f5459..bbcfb16 100644 --- a/src/term.h +++ b/src/term.h @@ -91,7 +91,10 @@ enum color_list { Magenta3Color, Cyan3Color, maxColor, /* minColor + 7 */ -# ifndef NO_BRIGHTCOLOR +# ifdef NO_BRIGHTCOLOR + WhiteColor = maxColor, + maxBright = maxColor, +# else AntiqueWhiteColor = maxColor, minBright, /* maxColor + 1 */ Grey25Color = minBright, @@ -103,8 +106,6 @@ enum color_list { CyanColor, maxBright, /* minBright + 7 */ WhiteColor = maxBright, -# else - WhiteColor = maxColor, # endif # ifndef NO_CURSORCOLOR cursorColor, @@ -176,7 +177,6 @@ extern void process_xterm_seq(void); extern void process_window_mode(unsigned int, int []); extern void process_terminal_mode(int, int, unsigned int, int []); extern void process_sgr_mode(unsigned int, int []); -extern void color_aliases(int); #ifndef NO_BRIGHTCOLOR extern void set_colorfgbg(void); #else diff --git a/src/windows.c b/src/windows.c index a282e5c..ac9a669 100644 --- a/src/windows.c +++ b/src/windows.c @@ -38,6 +38,7 @@ static const char cvs_ident[] = "$Id$"; #include "../libmej/mem.h" #include "../libmej/strings.h" #include "debug.h" +#include "buttons.h" #include "command.h" #include "e.h" #include "events.h" @@ -135,13 +136,13 @@ get_top_shadow_color(Pixel norm_color, const char *type) xcol.pixel = norm_color; XQueryColor(Xdisplay, cmap, &xcol); - xcol.red = max((white.red / 5), xcol.red); - xcol.green = max((white.green / 5), xcol.green); - xcol.blue = max((white.blue / 5), xcol.blue); + xcol.red = MAX((white.red / 5), xcol.red); + xcol.green = MAX((white.green / 5), xcol.green); + xcol.blue = MAX((white.blue / 5), xcol.blue); - xcol.red = min(white.red, (xcol.red * 7) / 5); - xcol.green = min(white.green, (xcol.green * 7) / 5); - xcol.blue = min(white.blue, (xcol.blue * 7) / 5); + xcol.red = MIN(white.red, (xcol.red * 7) / 5); + xcol.green = MIN(white.green, (xcol.green * 7) / 5); + xcol.blue = MIN(white.blue, (xcol.blue * 7) / 5); r = xcol.red; g = xcol.green; b = xcol.blue; @@ -154,6 +155,142 @@ get_top_shadow_color(Pixel norm_color, const char *type) return (xcol.pixel); } +Pixel +get_color_by_name(const char *name, const char *fallback) +{ + XColor xcol; + + if (!XParseColor(Xdisplay, cmap, name, &xcol)) { + print_warning("Unable to resolve \"%s\" as a color name. Falling back on \"%s\".", name, NONULL(fallback)); + name = fallback; + if (name) { + if (!XParseColor(Xdisplay, cmap, name, &xcol)) { + print_warning("Unable to resolve \"%s\" as a color name. This should never fail. Please repair/restore your RGB database.", name); + return ((Pixel) -1); + } + } else { + return ((Pixel) -1); + } + } + if (Xdepth < 24) { + int r, g, b; + + r = xcol.red; + g = xcol.green; + b = xcol.blue; + xcol.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); + xcol.red = r; + xcol.green = g; + xcol.blue = b; + } + if (!XAllocColor(Xdisplay, cmap, &xcol)) { + print_warning("Unable to allocate \"%s\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map. Falling back on \"%s\".", + name, xcol.pixel, xcol.red, xcol.green, xcol.blue, NONULL(fallback)); + name = fallback; + if (name) { + if (!XAllocColor(Xdisplay, cmap, &xcol)) { + print_warning("Unable to allocate \"%s\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map.", name, xcol.pixel, xcol.red, xcol.green, xcol.blue); + return ((Pixel) -1); + } + } else { + return ((Pixel) -1); + } + } + return (xcol.pixel); +} + +Pixel +get_color_by_pixel(Pixel pixel, Pixel fallback) +{ + XColor xcol; + + xcol.pixel = pixel; + if (!XQueryColor(Xdisplay, cmap, &xcol)) { + print_warning("Unable to convert pixel value 0x%08x to an XColor structure. Falling back on 0x%08x.", pixel, fallback); + xcol.pixel = fallback; + if (!XQueryColor(Xdisplay, cmap, &xcol)) { + print_warning("Unable to convert pixel value 0x%08x to an XColor structure.", xcol.pixel); + return ((Pixel) 0); + } + } + if (Xdepth < 24) { + int r, g, b; + + r = xcol.red; + g = xcol.green; + b = xcol.blue; + xcol.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); + xcol.red = r; + xcol.green = g; + xcol.blue = b; + } + if (!XAllocColor(Xdisplay, cmap, &xcol)) { + print_warning("Unable to allocate 0x%08x (0x%04x, 0x%04x, 0x%04x) in the color map. Falling back on 0x%08x.", xcol.pixel, xcol.red, xcol.green, xcol.blue, fallback); + xcol.pixel = fallback; + if (!XAllocColor(Xdisplay, cmap, &xcol)) { + print_warning("Unable to allocate 0x%08x (0x%04x, 0x%04x, 0x%04x) in the color map.", xcol.pixel, xcol.red, xcol.green, xcol.blue); + return ((Pixel) 0); + } + } + return (xcol.pixel); +} + +void +process_colors(void) +{ + int i; + Pixel pixel; + + for (i = 0; i < NRS_COLORS; i++) { + if ((Xdepth <= 2) || (!rs_color[i]) || ((pixel = get_color_by_name(rs_color[i], def_colorName[i])) == (Pixel) -1)) { + switch (i) { + case fgColor: + pixel = WhitePixel(Xdisplay, Xscreen); + break; + case bgColor: + pixel = BlackPixel(Xdisplay, Xscreen); + break; +#ifndef NO_CURSORCOLOR + case cursorColor: pixel = PixColors[bgColor]; break; + case cursorColor2: pixel = PixColors[fgColor]; break; +#endif /* NO_CURSORCOLOR */ + case pointerColor: pixel = PixColors[fgColor]; break; + case borderColor: pixel = PixColors[bgColor]; break; +#ifndef NO_BOLDUNDERLINE + case colorBD: pixel = PixColors[fgColor]; break; + case colorUL: pixel = PixColors[fgColor]; break; +#endif + default: + pixel = PixColors[fgColor]; /* None */ + break; + } + } + PixColors[i] = pixel; + } + + if (Xdepth <= 2) { /* Monochrome */ + PixColors[topShadowColor] = PixColors[fgColor]; + PixColors[bottomShadowColor] = PixColors[fgColor]; + PixColors[unfocusedTopShadowColor] = PixColors[fgColor]; + PixColors[unfocusedBottomShadowColor] = PixColors[fgColor]; + + PixColors[menuTopShadowColor] = PixColors[fgColor]; + PixColors[menuBottomShadowColor] = PixColors[fgColor]; + PixColors[unfocusedMenuTopShadowColor] = PixColors[fgColor]; + PixColors[unfocusedMenuBottomShadowColor] = PixColors[fgColor]; + } else { + PixColors[bottomShadowColor] = get_bottom_shadow_color(images[image_sb].norm->bg, "bottomShadowColor"); + PixColors[unfocusedBottomShadowColor] = get_bottom_shadow_color(images[image_sb].disabled->bg, "unfocusedBottomShadowColor"); + PixColors[topShadowColor] = get_top_shadow_color(images[image_sb].norm->bg, "topShadowColor"); + PixColors[unfocusedTopShadowColor] = get_top_shadow_color(images[image_sb].disabled->bg, "unfocusedTopShadowColor"); + + PixColors[menuBottomShadowColor] = get_bottom_shadow_color(images[image_menu].norm->bg, "menuBottomShadowColor"); + PixColors[unfocusedMenuBottomShadowColor] = get_bottom_shadow_color(images[image_menu].disabled->bg, "unfocusedMenuBottomShadowColor"); + PixColors[menuTopShadowColor] = get_top_shadow_color(images[image_menu].norm->bg, "menuTopShadowColor"); + PixColors[unfocusedMenuTopShadowColor] = get_top_shadow_color(images[image_menu].disabled->bg, "unfocusedMenuTopShadowColor"); + } +} + /* Create_Windows() - Open and map the window */ void Create_Windows(int argc, char *argv[]) @@ -164,9 +301,8 @@ Create_Windows(int argc, char *argv[]) XWMHints wmHint; Atom prop = None; CARD32 val; - int i, x = 0, y = 0, flags; + int x = 0, y = 0, flags; unsigned int width = 0, height = 0; - int r, g, b; MWMHints mwmhints; if (Options & Opt_borderless) { @@ -185,140 +321,8 @@ Create_Windows(int argc, char *argv[]) Attributes.backing_store = WhenMapped; Attributes.colormap = cmap; - /* - * grab colors before netscape does - */ - for (i = 0; i < (Xdepth <= 2 ? 2 : NRS_COLORS); i++) { - - XColor xcol; - unsigned char found_color = 0; - - if (rs_color[i]) { - if (!XParseColor(Xdisplay, cmap, rs_color[i], &xcol)) { - print_warning("Unable to resolve \"%s\" as a color name. Falling back on \"%s\".", - rs_color[i], def_colorName[i] ? def_colorName[i] : "(nil)"); - rs_color[i] = def_colorName[i]; - if (rs_color[i]) { - if (!XParseColor(Xdisplay, cmap, rs_color[i], &xcol)) { - print_warning("Unable to resolve \"%s\" as a color name. This should never fail. Please repair/restore your RGB database.", rs_color[i]); - found_color = 0; - } else { - found_color = 1; - } - } - } else { - found_color = 1; - } - if (found_color) { - r = xcol.red; - g = xcol.green; - b = xcol.blue; - xcol.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); - if (!XAllocColor(Xdisplay, cmap, &xcol)) { - print_warning("Unable to allocate \"%s\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map. " - "Falling back on \"%s\".", - rs_color[i], xcol.pixel, r, g, b, def_colorName[i] ? def_colorName[i] : "(nil)"); - rs_color[i] = def_colorName[i]; - if (rs_color[i]) { - if (!XAllocColor(Xdisplay, cmap, &xcol)) { - print_warning("Unable to allocate \"%s\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map.", - rs_color[i], xcol.pixel, r, g, b); - found_color = 0; - } else { - found_color = 1; - } - } - } else { - found_color = 1; - } - } - } else { - found_color = 0; - } - if (!found_color) { - switch (i) { - case fgColor: - case bgColor: - /* fatal: need bg/fg color */ - fatal_error("Unable to get foreground/background colors!"); - break; -#ifndef NO_CURSORCOLOR - case cursorColor: - xcol.pixel = PixColors[bgColor]; - break; - case cursorColor2: - xcol.pixel = PixColors[fgColor]; - break; -#endif /* NO_CURSORCOLOR */ - case unfocusedMenuColor: - xcol.pixel = PixColors[menuColor]; - break; - case unfocusedScrollColor: - case menuColor: - xcol.pixel = PixColors[scrollColor]; - break; - default: - xcol.pixel = PixColors[bgColor]; /* None */ - break; - } - } - PixColors[i] = xcol.pixel; - } - -#ifndef NO_CURSORCOLOR - if (Xdepth <= 2 || !rs_color[cursorColor]) - PixColors[cursorColor] = PixColors[bgColor]; - if (Xdepth <= 2 || !rs_color[cursorColor2]) - PixColors[cursorColor2] = PixColors[fgColor]; -#endif /* NO_CURSORCOLOR */ - if (Xdepth <= 2 || !rs_color[pointerColor]) - PixColors[pointerColor] = PixColors[fgColor]; - if (Xdepth <= 2 || !rs_color[borderColor]) - PixColors[borderColor] = PixColors[bgColor]; - -#ifndef NO_BOLDUNDERLINE - if (Xdepth <= 2 || !rs_color[colorBD]) - PixColors[colorBD] = PixColors[fgColor]; - if (Xdepth <= 2 || !rs_color[colorUL]) - PixColors[colorUL] = PixColors[fgColor]; -#endif /* NO_BOLDUNDERLINE */ - - /* - * get scrollbar/menu shadow colors - * - * The calculations of topShadow/bottomShadow values are adapted - * from the fvwm window manager. - */ - if (Xdepth <= 2) { /* Monochrome */ - PixColors[scrollColor] = PixColors[bgColor]; - PixColors[topShadowColor] = PixColors[fgColor]; - PixColors[bottomShadowColor] = PixColors[fgColor]; - - PixColors[unfocusedScrollColor] = PixColors[bgColor]; - PixColors[unfocusedTopShadowColor] = PixColors[fgColor]; - PixColors[unfocusedBottomShadowColor] = PixColors[fgColor]; - - PixColors[menuColor] = PixColors[bgColor]; - PixColors[menuTopShadowColor] = PixColors[fgColor]; - PixColors[menuBottomShadowColor] = PixColors[fgColor]; - - PixColors[unfocusedMenuColor] = PixColors[bgColor]; - PixColors[unfocusedMenuTopShadowColor] = PixColors[fgColor]; - PixColors[unfocusedMenuBottomShadowColor] = PixColors[fgColor]; - } else { - PixColors[bottomShadowColor] = get_bottom_shadow_color(PixColors[scrollColor], "bottomShadowColor"); - PixColors[unfocusedBottomShadowColor] = get_bottom_shadow_color(PixColors[unfocusedScrollColor], "unfocusedBottomShadowColor"); - PixColors[topShadowColor] = get_top_shadow_color(PixColors[scrollColor], "topShadowColor"); - PixColors[unfocusedTopShadowColor] = get_top_shadow_color(PixColors[unfocusedScrollColor], "unfocusedTopShadowColor"); - - PixColors[menuBottomShadowColor] = get_bottom_shadow_color(PixColors[menuColor], "menuBottomShadowColor"); - PixColors[unfocusedMenuBottomShadowColor] = get_bottom_shadow_color(PixColors[unfocusedMenuColor], "unfocusedMenuBottomShadowColor"); - PixColors[menuTopShadowColor] = get_top_shadow_color(PixColors[menuColor], "menuTopShadowColor"); - PixColors[unfocusedMenuTopShadowColor] = get_top_shadow_color(PixColors[unfocusedMenuColor], "unfocusedMenuTopShadowColor"); - } - szHint.base_width = (2 * TermWin.internalBorder + ((Options & Opt_scrollbar) ? (scrollbar_get_width() + (2 * scrollbar_get_shadow())) : 0)); - szHint.base_height = (2 * TermWin.internalBorder); + szHint.base_height = (2 * TermWin.internalBorder) + bbar_total_height(); flags = (rs_geometry ? XParseGeometry(rs_geometry, &x, &y, &width, &height) : 0); D_X11(("XParseGeometry(geom, %d, %d, %d, %d)\n", x, y, width, height)); @@ -359,6 +363,7 @@ Create_Windows(int argc, char *argv[]) Attributes.background_pixel = PixColors[bgColor]; Attributes.border_pixel = PixColors[bgColor]; + D_X11(("szHint == { %d, %d, %d, %d }\n", szHint.x, szHint.y, szHint.width, szHint.height)); TermWin.parent = XCreateWindow(Xdisplay, Xroot, szHint.x, szHint.y, szHint.width, szHint.height, 0, Xdepth, InputOutput, #ifdef PREFER_24BIT Xvisual, @@ -404,7 +409,7 @@ Create_Windows(int argc, char *argv[]) /* the vt window */ TermWin.x = (((Options & Opt_scrollbar) && !(Options & Opt_scrollbar_right)) ? (scrollbar_get_width() + (2 * scrollbar_get_shadow())) : 0); - TermWin.y = 0; + TermWin.y = bbar_total_height(); if ((!(Options & Opt_borderless)) && (Options & Opt_backing_store)) { D_X11(("Creating term window with save_under = TRUE\n")); TermWin.vt = XCreateWindow(Xdisplay, TermWin.parent, TermWin.x, TermWin.y, szHint.width, szHint.height, 0, Xdepth, InputOutput, CopyFromParent, @@ -419,7 +424,7 @@ Create_Windows(int argc, char *argv[]) XClearWindow(Xdisplay, TermWin.vt); } XDefineCursor(Xdisplay, TermWin.vt, TermWin_cursor); - XSelectInput(Xdisplay, TermWin.vt, (ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | Button3MotionMask)); + XSelectInput(Xdisplay, TermWin.vt, (EnterWindowMask | LeaveWindowMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | Button3MotionMask)); /* If the user wants a specific desktop, tell the WM that */ if (rs_desktop != -1) { @@ -474,9 +479,9 @@ set_width(unsigned short width) void update_size_hints(void) { - D_X11(("update_size_hints() called.\n")); + D_X11(("Called.\n")); szHint.base_width = (2 * TermWin.internalBorder); - szHint.base_height = (2 * TermWin.internalBorder); + szHint.base_height = (2 * TermWin.internalBorder) + bbar_total_height(); szHint.base_width += ((scrollbar_is_visible()) ? (scrollbar_trough_width()) : (0)); szHint.width_inc = TermWin.fwidth; @@ -503,8 +508,9 @@ term_resize(int width, int height) TermWin.width = TermWin.ncol * TermWin.fwidth; TermWin.height = TermWin.nrow * TermWin.fheight; D_X11((" -> New TermWin width/height == %lux%lu\n", TermWin.width, TermWin.height)); - XMoveResizeWindow(Xdisplay, TermWin.vt, ((Options & Opt_scrollbar_right) ? (0) : ((scrollbar_is_visible()) ? (scrollbar_trough_width()) : (0))), 0, width, height + 1); - render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 1); + XMoveResizeWindow(Xdisplay, TermWin.vt, ((Options & Opt_scrollbar_right) ? (0) : ((scrollbar_is_visible()) ? (scrollbar_trough_width()) : (0))), bbar_total_height(), + width, height - bbar_total_height()); + render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 0); if (image_mode_is(image_bg, MODE_AUTO)) { enl_ipc_sync(); } @@ -514,12 +520,13 @@ term_resize(int width, int height) void parent_resize(void) { - D_X11(("parent_resize() called.\n")); + D_X11(("Called.\n")); update_size_hints(); XResizeWindow(Xdisplay, TermWin.parent, szHint.width, szHint.height); D_X11((" -> New parent width/height == %lux%lu\n", szHint.width, szHint.height)); term_resize(szHint.width, szHint.height); - scrollbar_resize(szHint.width, szHint.height); + scrollbar_resize(szHint.width, szHint.height + bbar_total_height()); + bbar_resize_all(szHint.width); if (buffer_pixmap != None) { scr_touch(); } @@ -548,7 +555,8 @@ handle_resize(unsigned int width, unsigned int height) szHint.width = szHint.base_width + TermWin.width; szHint.height = szHint.base_height + TermWin.height; D_X11((" -> New szHint.width/height == %lux%lu\n", szHint.width, szHint.height)); - scrollbar_resize(width, height); + scrollbar_resize(width, szHint.height - bbar_total_height()); + bbar_resize_all(szHint.width); scr_reset(); if (buffer_pixmap != None) { scr_touch(); @@ -559,13 +567,6 @@ handle_resize(unsigned int width, unsigned int height) } first_time = 0; } -#if 0 - else if (image_mode_is(image_bg, MODE_TRANS) || image_mode_is(image_bg, MODE_VIEWPORT)) { - term_resize(width, height); - scrollbar_resize(width, height); - scr_touch(); - } -#endif } void @@ -649,3 +650,47 @@ set_window_color(int idx, const char *color) # define set_window_color(idx,color) ((void)0) #endif /* XTERM_COLOR_CHANGE */ +Window +find_window_by_coords(Window win, int win_x, int win_y, int rel_x, int rel_y) +{ + Window *children = NULL; + XWindowAttributes attr; + Window child = 0, parent_win = 0, root_win = 0; + int i; + unsigned int ww, wh, num; + int wx, wy; + + D_X11(("win 0x%08x at %d, %d. Coords are %d, %d.\n", win, win_x, win_y, rel_x, rel_y)); + + /* Bad or invisible window. */ + if ((!XGetWindowAttributes(Xdisplay, win, &attr)) || (attr.map_state != IsViewable)) { + return None; + } + wx = attr.x + win_x; + wy = attr.y + win_y; + ww = attr.width; + wh = attr.height; + + if (!((rel_x >= wx) && (rel_y >= wy) && (rel_x < (int)(wx + ww)) && (rel_y < (int)(wy + wh)))) { + return None; + } + + if (!XQueryTree(Xdisplay, win, &root_win, &parent_win, &children, &num)) { + return win; + } + if (children) { + D_X11(("%d children.\n", num)); + for (i = num - 1; i >= 0; i--) { + D_X11(("Trying children[%d] (0x%08x)\n", i, children[i])); + if ((child = find_window_by_coords(children[i], wx, wy, rel_x, rel_y)) != None) { + D_X11(("Match!\n")); + XFree(children); + return child; + } + } + D_X11(("XFree(children)\n")); + XFree(children); + } + D_X11(("Returning 0x%08x\n", win)); + return win; +} diff --git a/src/windows.h b/src/windows.h index dbacc0e..cfe8fd2 100644 --- a/src/windows.h +++ b/src/windows.h @@ -45,6 +45,9 @@ _XFUNCPROTOBEGIN extern void set_text_property(Window, char *, char *); extern Pixel get_bottom_shadow_color(Pixel, const char *); extern Pixel get_top_shadow_color(Pixel, const char *); +extern Pixel get_color_by_name(const char *, const char *); +extern Pixel get_color_by_pixel(Pixel, Pixel); +extern void process_colors(void); extern void Create_Windows(int, char * []); extern void set_width(unsigned short); extern void update_size_hints(void); @@ -57,6 +60,7 @@ extern void set_window_color(int, const char *); #else # define set_window_color(idx,color) ((void)0) #endif /* XTERM_COLOR_CHANGE */ +extern Window find_window_by_coords(Window, int, int, int, int); _XFUNCPROTOEND diff --git a/themes/Eterm/menus.cfg b/themes/Eterm/menus.cfg index 3235f55..c826a14 100644 --- a/themes/Eterm/menus.cfg +++ b/themes/Eterm/menus.cfg @@ -39,13 +39,9 @@ begin menu action string "\e[?25t" end begin menuitem - text "Home on Echo" + text "Home on Output" action string "\e[?1010t" end - begin menuitem - text "Home on Refresh" - action string "\e[?1011t" - end begin menuitem text "Home on Input" action string "\e[?1012t" @@ -870,22 +866,47 @@ begin menu end end -# This is the menu that gets called by Ctrl-Button3 begin menu - title Eterm - begin menuitem - text "Font" - action submenu Font - end - begin menuitem - text "Background" - action submenu Background - end - begin menuitem - text "Terminal" - action submenu Terminal - end - - + title "Eterm Operations" + begin menuitem + text "Version" + action string "\e[8n" + end + begin menuitem + text "Status" + action string "\e[9n" + end + separator + begin menuitem + text "Save Settings..." + action string "\e]6;71\a" + end + begin menuitem + text "Exit" + action string "\e]6;70\a" + end +end + +# This is the menu that gets called by Ctrl-Button3 +begin menu + title Eterm + begin menuitem + text "Font" + action submenu Font + end + begin menuitem + text "Background" + action submenu Background + end + begin menuitem + text "Terminal" + action submenu Terminal + end + - + begin menuitem + text "New Window..." + action string "\e]6;73;Eterm\a" + end begin menuitem text "Version" action string "\e[8n" diff --git a/themes/Eterm/theme.cfg.in b/themes/Eterm/theme.cfg.in index 05aa36f..aa35581 100644 --- a/themes/Eterm/theme.cfg.in +++ b/themes/Eterm/theme.cfg.in @@ -23,11 +23,6 @@ begin main background black cursor #ffff00 cursor_text #880000 - scrollbar #3f1c00 - unfocused_scrollbar #777777 - menu #777777 - unfocused_menu #777777 - menu_text black pointer white # video attribute can either be "normal" or "reverse" @@ -149,27 +144,43 @@ begin main type trough mode image allow image trans viewport auto state normal + color black #666666 file bar_vertical_3.png # Here is how you specify the geometry string separately. See the man page for its syntax. geom :scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type anchor mode image allow image auto state normal + color black #666666 file bar_vertical_1.png geom :scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_vertical_2.png geom :scale - border 3 3 2 2 + border 2 2 2 2 + end image + begin image + type thumb + mode image allow image auto + state normal + color black #666666 + file thumb_1.png + geom :scale + border 3 3 3 3 + state selected + file thumb_2.png + geom :scale + border 3 3 3 3 end image begin image type up_arrow mode image allow image auto state normal + color black #666666 file button_arrow_up_1.png geom :scale border 2 2 2 2 @@ -186,6 +197,7 @@ begin main type down_arrow mode image allow image auto state normal + color black #666666 file button_arrow_down_1.png geom :scale border 2 2 2 2 @@ -202,18 +214,20 @@ begin main type menu mode image allow image auto state normal + color black #999999 file bar_horizontal_1.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_horizontal_2.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type submenu mode image allow image auto state normal + color black #999999 file menu1.png geom 100x100+0+0:scale border 3 15 3 3 @@ -229,6 +243,36 @@ begin main border 3 15 3 3 padding 3 15 3 3 end image + begin image + type button_bar + mode image allow image auto + state normal + color black #999999 + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state disabled + color white #333333 + cmod image 0xc0 + border 2 2 2 2 + end image + begin image + type button + mode image allow image auto + state normal + color black #cccccc + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state selected + file bar_horizontal_2.png + geom 100x100+0+0:scale + border 2 2 2 2 + state clicked + file bar_horizontal_3.png + geom 100x100+0+0:scale + border 2 2 2 2 + end image end %include "menus.cfg" @@ -242,9 +286,27 @@ begin main bind ctrl button1 to string "\e]5;\a" bind ctrl button2 to string "\e[?30t" bind ctrl button3 to menu Eterm - bind anymod 0xffbe to menu Eterm end actions +# This section must also come after the menus if you want any buttons +# to launch menus. (If not, it can go anywhere.) + begin button_bar + +# Specify a font. The default buttonbar font is the default terminal +# font as defined in the attributes section above. + font "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1" + +# Add a button. The syntax is: +# button [ icon ] action { string | echo | menu } +# + button Eterm action menu "Eterm Operations" + button Font action menu Font + button Background action menu Background + button Terminal action menu Terminal + rbutton icon help.png action string "\e]6;73;Eterm -e man Eterm\a" + rbutton icon exit.png action string "\e]6;70\a" + end button_bar + # The XIM support options. # input_method: set the name of your favorate input method program # preedit_type: OverTheSpot or OffTheSpot or Root @@ -285,13 +347,12 @@ begin main # If true, Eterm will start iconified. iconic false -# If true, Eterm will jump to the bottom of the window when something is echoed -# to the terminal, either by program output or user input. - home_on_echo 1 +# If true, Eterm will jump to the bottom of the window when something is output +# to the terminal. + home_on_output 1 -# If true, Eterm will jump to the bottom of the window when you refresh the -# screen (^L). - home_on_refresh 1 +# If true, Eterm will jump to the bottom of the window when a key is pressed. + home_on_input 1 # If true, Eterm will put the scrollbar on the right of the window (default is left). scrollbar_right true diff --git a/themes/auto/menus.cfg b/themes/auto/menus.cfg index 3235f55..d39cabd 100644 --- a/themes/auto/menus.cfg +++ b/themes/auto/menus.cfg @@ -39,13 +39,9 @@ begin menu action string "\e[?25t" end begin menuitem - text "Home on Echo" + text "Home on Output" action string "\e[?1010t" end - begin menuitem - text "Home on Refresh" - action string "\e[?1011t" - end begin menuitem text "Home on Input" action string "\e[?1012t" diff --git a/themes/auto/theme.cfg.in b/themes/auto/theme.cfg.in index c453794..bce1260 100644 --- a/themes/auto/theme.cfg.in +++ b/themes/auto/theme.cfg.in @@ -23,11 +23,6 @@ begin main background black cursor #ffff00 cursor_text #880000 - scrollbar #3f1c00 - unfocused_scrollbar #777777 - menu #777777 - unfocused_menu #777777 - menu_text black pointer white # video attribute can either be "normal" or "reverse" @@ -149,27 +144,43 @@ begin main type trough mode auto allow image trans viewport auto state normal + color black #666666 file bar_vertical_3.png # Here is how you specify the geometry string separately. See the man page for its syntax. geom :scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type anchor mode auto allow image auto state normal + color black #666666 file bar_vertical_1.png geom :scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_vertical_2.png geom :scale - border 3 3 2 2 + border 2 2 2 2 + end image + begin image + type thumb + mode auto allow image auto + state normal + color black #666666 + file thumb_1.png + geom :scale + border 3 3 3 3 + state selected + file thumb_2.png + geom :scale + border 3 3 3 3 end image begin image type up_arrow mode auto allow image auto state normal + color black #666666 file button_arrow_up_1.png geom :scale border 2 2 2 2 @@ -186,6 +197,7 @@ begin main type down_arrow mode auto allow image auto state normal + color black #666666 file button_arrow_down_1.png geom :scale border 2 2 2 2 @@ -202,18 +214,20 @@ begin main type menu mode auto allow image auto state normal + color black #999999 file bar_horizontal_1.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_horizontal_2.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type submenu mode auto allow image auto state normal + color black #999999 file menu1.png geom 100x100+0+0:scale border 3 15 3 3 @@ -229,6 +243,36 @@ begin main border 3 15 3 3 padding 3 15 3 3 end image + begin image + type button_bar + mode auto allow image auto + state normal + color black #999999 + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state disabled + color white #333333 + cmod image 0xc0 + border 2 2 2 2 + end image + begin image + type button + mode auto allow image auto + state normal + color black #cccccc + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state selected + file bar_horizontal_2.png + geom 100x100+0+0:scale + border 2 2 2 2 + state clicked + file bar_horizontal_3.png + geom 100x100+0+0:scale + border 2 2 2 2 + end image end %include "menus.cfg" @@ -242,9 +286,27 @@ begin main bind ctrl button1 to string "\e]5;\a" bind ctrl button2 to string "\e[?30t" bind ctrl button3 to menu Eterm - bind anymod 0xffbe to menu Eterm end actions +# This section must also come after the menus if you want any buttons +# to launch menus. (If not, it can go anywhere.) + begin button_bar + +# Specify a font. The default buttonbar font is the default terminal +# font as defined in the attributes section above. + font "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1" + +# Add a button. The syntax is: +# button [ icon ] action { string | echo | menu } +# + button Eterm action menu "Eterm Operations" + button Font action menu Font + button Background action menu Background + button Terminal action menu Terminal + rbutton icon help.png action string "\e]6;73;Eterm -e man Eterm\a" + rbutton icon exit.png action string "\e]6;70\a" + end button_bar + # The XIM support options. # input_method: set the name of your favorate input method program # preedit_type: OverTheSpot or OffTheSpot or Root @@ -285,13 +347,12 @@ begin main # If true, Eterm will start iconified. iconic false -# If true, Eterm will jump to the bottom of the window when something is echoed -# to the terminal, either by program output or user input. - home_on_echo 1 +# If true, Eterm will jump to the bottom of the window when something is output +# to the terminal. + home_on_output 1 -# If true, Eterm will jump to the bottom of the window when you refresh the -# screen (^L). - home_on_refresh 1 +# If true, Eterm will jump to the bottom of the window when a key is pressed. + home_on_input 1 # If true, Eterm will put the scrollbar on the right of the window (default is left). scrollbar_right true diff --git a/themes/cEterm/menus.cfg b/themes/cEterm/menus.cfg index 3235f55..c826a14 100644 --- a/themes/cEterm/menus.cfg +++ b/themes/cEterm/menus.cfg @@ -39,13 +39,9 @@ begin menu action string "\e[?25t" end begin menuitem - text "Home on Echo" + text "Home on Output" action string "\e[?1010t" end - begin menuitem - text "Home on Refresh" - action string "\e[?1011t" - end begin menuitem text "Home on Input" action string "\e[?1012t" @@ -870,22 +866,47 @@ begin menu end end -# This is the menu that gets called by Ctrl-Button3 begin menu - title Eterm - begin menuitem - text "Font" - action submenu Font - end - begin menuitem - text "Background" - action submenu Background - end - begin menuitem - text "Terminal" - action submenu Terminal - end - - + title "Eterm Operations" + begin menuitem + text "Version" + action string "\e[8n" + end + begin menuitem + text "Status" + action string "\e[9n" + end + separator + begin menuitem + text "Save Settings..." + action string "\e]6;71\a" + end + begin menuitem + text "Exit" + action string "\e]6;70\a" + end +end + +# This is the menu that gets called by Ctrl-Button3 +begin menu + title Eterm + begin menuitem + text "Font" + action submenu Font + end + begin menuitem + text "Background" + action submenu Background + end + begin menuitem + text "Terminal" + action submenu Terminal + end + - + begin menuitem + text "New Window..." + action string "\e]6;73;Eterm\a" + end begin menuitem text "Version" action string "\e[8n" diff --git a/themes/cEterm/theme.cfg.in b/themes/cEterm/theme.cfg.in index 9fd4bad..321cc22 100644 --- a/themes/cEterm/theme.cfg.in +++ b/themes/cEterm/theme.cfg.in @@ -23,11 +23,6 @@ begin main background black cursor #ffff00 cursor_text #880000 - scrollbar #3f1c00 - unfocused_scrollbar #777777 - menu #777777 - unfocused_menu #777777 - menu_text black pointer white # video attribute can either be "normal" or "reverse" @@ -148,27 +143,43 @@ begin main type trough mode image allow image trans viewport auto state normal + color black #666666 file bar_vertical_3.png # Here is how you specify the geometry string separately. See the man page for its syntax. geom :scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type anchor mode image allow image auto state normal + color black #666666 file bar_vertical_1.png geom :scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_vertical_2.png geom :scale - border 3 3 2 2 + border 2 2 2 2 + end image + begin image + type thumb + mode image allow image auto + state normal + color black #666666 + file thumb_1.png + geom :scale + border 3 3 3 3 + state selected + file thumb_2.png + geom :scale + border 3 3 3 3 end image begin image type up_arrow mode image allow image auto state normal + color black #666666 file button_arrow_up_1.png geom :scale border 2 2 2 2 @@ -185,6 +196,7 @@ begin main type down_arrow mode image allow image auto state normal + color black #666666 file button_arrow_down_1.png geom :scale border 2 2 2 2 @@ -201,18 +213,20 @@ begin main type menu mode image allow image auto state normal + color black #999999 file bar_horizontal_1.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_horizontal_2.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type submenu mode image allow image auto state normal + color black #999999 file menu1.png geom 100x100+0+0:scale border 3 15 3 3 @@ -228,6 +242,36 @@ begin main border 3 15 3 3 padding 3 15 3 3 end image + begin image + type button_bar + mode image allow image auto + state normal + color black #999999 + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state disabled + color white #333333 + cmod image 0xc0 + border 2 2 2 2 + end image + begin image + type button + mode image allow image auto + state normal + color black #cccccc + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state selected + file bar_horizontal_2.png + geom 100x100+0+0:scale + border 2 2 2 2 + state clicked + file bar_horizontal_3.png + geom 100x100+0+0:scale + border 2 2 2 2 + end image end %include "menus.cfg" @@ -241,9 +285,27 @@ begin main bind ctrl button1 to string "\e]5;\a" bind ctrl button2 to string "\e[?30t" bind ctrl button3 to menu Eterm - bind anymod 0xffbe to menu Eterm end actions +# This section must also come after the menus if you want any buttons +# to launch menus. (If not, it can go anywhere.) + begin button_bar + +# Specify a font. The default buttonbar font is the default terminal +# font as defined in the attributes section above. + font "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1" + +# Add a button. The syntax is: +# button [ icon ] action { string | echo | menu } +# + button Eterm action menu "Eterm Operations" + button Font action menu Font + button Background action menu Background + button Terminal action menu Terminal + rbutton icon help.png action string "\e]6;73;Eterm -e man Eterm\a" + rbutton icon exit.png action string "\e]6;70\a" + end button_bar + # The XIM support options. # input_method: set the name of your favorate input method program # preedit_type: OverTheSpot or OffTheSpot or Root @@ -279,13 +341,12 @@ begin main # If true, Eterm will start iconified. iconic false -# If true, Eterm will jump to the bottom of the window when something is echoed -# to the terminal, either by program output or user input. - home_on_echo 1 +# If true, Eterm will jump to the bottom of the window when something is output +# to the terminal. + home_on_output 1 -# If true, Eterm will jump to the bottom of the window when you refresh the -# screen (^L). - home_on_refresh 1 +# If true, Eterm will jump to the bottom of the window when a key is pressed. + home_on_input 1 # If true, Eterm will put the scrollbar on the right of the window (default is left). scrollbar_right true diff --git a/themes/chooser/menus.cfg b/themes/chooser/menus.cfg index 94b447c..9f332cf 100644 --- a/themes/chooser/menus.cfg +++ b/themes/chooser/menus.cfg @@ -35,13 +35,9 @@ begin menu action string "\e[?25t" end begin menuitem - text "Home on Echo" + text "Home on Output" action string "\e[?1010t" end - begin menuitem - text "Home on Refresh" - action string "\e[?1011t" - end begin menuitem text "Home on Input" action string "\e[?1012t" @@ -976,25 +972,14 @@ DO_PROTOCOL(rlogin) DO_PROTOCOL(telnet) DO_PROTOCOL(ftp) -begin menu - title Chooser - ECHO_ITEM(`New Eterm Window', `Eterm &\r') - - - SUBMENU_ITEM(`ssh') - SUBMENU_ITEM(`rlogin') - SUBMENU_ITEM(`telnet') - SUBMENU_ITEM(`ftp') -end - # This is the menu that gets called by Ctrl-Button3 begin menu title Eterm - SUBMENU_ITEM(Chooser) - - SUBMENU_ITEM(Font) SUBMENU_ITEM(Background) SUBMENU_ITEM(Terminal) - + STRING_ITEM(`New Eterm Window', `\e]6;73;Eterm\a') STRING_ITEM(`Version', `\e[8n') STRING_ITEM(`Status', `\e[9n') separator diff --git a/themes/chooser/theme.cfg.in b/themes/chooser/theme.cfg.in index e9510a9..45ab856 100644 --- a/themes/chooser/theme.cfg.in +++ b/themes/chooser/theme.cfg.in @@ -23,11 +23,6 @@ begin main background black cursor #ffff00 cursor_text #880000 - scrollbar #3f1c00 - unfocused_scrollbar #777777 - menu #777777 - unfocused_menu #777777 - menu_text black pointer white # video attribute can either be "normal" or "reverse" @@ -149,27 +144,43 @@ begin main type trough mode image allow image trans viewport auto state normal + color black #666666 file bar_vertical_3.png # Here is how you specify the geometry string separately. See the man page for its syntax. geom :scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type anchor mode image allow image auto state normal + color black #666666 file bar_vertical_1.png geom :scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_vertical_2.png geom :scale - border 3 3 2 2 + border 2 2 2 2 + end image + begin image + type thumb + mode image allow image auto + state normal + color black #666666 + file thumb_1.png + geom :scale + border 3 3 3 3 + state selected + file thumb_2.png + geom :scale + border 3 3 3 3 end image begin image type up_arrow mode image allow image auto state normal + color black #666666 file button_arrow_up_1.png geom :scale border 2 2 2 2 @@ -186,6 +197,7 @@ begin main type down_arrow mode image allow image auto state normal + color black #666666 file button_arrow_down_1.png geom :scale border 2 2 2 2 @@ -202,18 +214,20 @@ begin main type menu mode image allow image auto state normal + color black #999999 file bar_horizontal_1.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_horizontal_2.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type submenu mode image allow image auto state normal + color black #999999 file menu1.png geom 100x100+0+0:scale border 3 15 3 3 @@ -229,6 +243,36 @@ begin main border 3 15 3 3 padding 3 15 3 3 end image + begin image + type button_bar + mode image allow image auto + state normal + color black #999999 + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state disabled + color white #333333 + cmod image 0xc0 + border 2 2 2 2 + end image + begin image + type button + mode image allow image auto + state normal + color black #cccccc + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state selected + file bar_horizontal_2.png + geom 100x100+0+0:scale + border 2 2 2 2 + state clicked + file bar_horizontal_3.png + geom 100x100+0+0:scale + border 2 2 2 2 + end image end %include "menus.cfg" @@ -242,9 +286,28 @@ begin main bind ctrl button1 to string "\e]5;\a" bind ctrl button2 to string "\e[?30t" bind ctrl button3 to menu Eterm - bind anymod 0xffbe to menu Eterm end actions +# This section must also come after the menus if you want any buttons +# to launch menus. (If not, it can go anywhere.) + begin button_bar + +# Specify a font. The default buttonbar font is the default terminal +# font as defined in the attributes section above. + font "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1" + +# Add a button. The syntax is: +# button [ icon ] action { string | echo | menu } +# + button Eterm action menu Eterm + button ssh action menu ssh + button rlogin action menu rlogin + button telnet action menu telnet + button ftp action menu ftp + rbutton icon help.png action string "\e]6;73;Eterm -e man Eterm\a" + rbutton icon exit.png action string "\e]6;70\a" + end button_bar + # The XIM support options. # input_method: set the name of your favorate input method program # preedit_type: OverTheSpot or OffTheSpot or Root @@ -280,13 +343,12 @@ begin main # If true, Eterm will start iconified. iconic false -# If true, Eterm will jump to the bottom of the window when something is echoed -# to the terminal, either by program output or user input. - home_on_echo 1 +# If true, Eterm will jump to the bottom of the window when something is output +# to the terminal. + home_on_output 1 -# If true, Eterm will jump to the bottom of the window when you refresh the -# screen (^L). - home_on_refresh 1 +# If true, Eterm will jump to the bottom of the window when a key is pressed. + home_on_input 1 # If true, Eterm will put the scrollbar on the right of the window (default is left). scrollbar_right true diff --git a/themes/emacs/menus.cfg b/themes/emacs/menus.cfg index 2d71044..7b09fdd 100644 --- a/themes/emacs/menus.cfg +++ b/themes/emacs/menus.cfg @@ -39,13 +39,9 @@ begin menu action string "\e[?25t" end begin menuitem - text "Home on Echo" + text "Home on Output" action string "\e[?1010t" end - begin menuitem - text "Home on Refresh" - action string "\e[?1011t" - end begin menuitem text "Home on Input" action string "\e[?1012t" @@ -1108,27 +1104,6 @@ end # This is the menu that gets called by Ctrl-Button3 begin menu title Eterm - begin menuitem - text "Buffers" - action submenu Buffers - end - begin menuitem - text "Files" - action submenu Files - end - begin menuitem - text "Edit" - action submenu Edit - end - begin menuitem - text "Search" - action submenu Search - end - begin menuitem - text "Help" - action submenu Help - end - - begin menuitem text "Font" action submenu Font diff --git a/themes/emacs/theme.cfg.in b/themes/emacs/theme.cfg.in index a2d6407..504a4ae 100644 --- a/themes/emacs/theme.cfg.in +++ b/themes/emacs/theme.cfg.in @@ -23,11 +23,6 @@ begin main background black cursor #ffff00 cursor_text #880000 - scrollbar #3f1c00 - unfocused_scrollbar #777777 - menu #777777 - unfocused_menu #777777 - menu_text black pointer white # video attribute can either be "normal" or "reverse" @@ -149,27 +144,43 @@ begin main type trough mode image allow image trans viewport auto state normal + color black #666666 file bar_vertical_3.png # Here is how you specify the geometry string separately. See the man page for its syntax. geom :scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type anchor mode image allow image auto state normal + color black #666666 file bar_vertical_1.png geom :scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_vertical_2.png geom :scale - border 3 3 2 2 + border 2 2 2 2 + end image + begin image + type thumb + mode image allow image auto + state normal + color black #666666 + file thumb_1.png + geom :scale + border 3 3 3 3 + state selected + file thumb_2.png + geom :scale + border 3 3 3 3 end image begin image type up_arrow mode image allow image auto state normal + color black #666666 file button_arrow_up_1.png geom :scale border 2 2 2 2 @@ -186,6 +197,7 @@ begin main type down_arrow mode image allow image auto state normal + color black #666666 file button_arrow_down_1.png geom :scale border 2 2 2 2 @@ -202,18 +214,20 @@ begin main type menu mode image allow image auto state normal + color black #999999 file bar_horizontal_1.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_horizontal_2.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type submenu mode image allow image auto state normal + color black #999999 file menu1.png geom 100x100+0+0:scale border 3 15 3 3 @@ -229,6 +243,36 @@ begin main border 3 15 3 3 padding 3 15 3 3 end image + begin image + type button_bar + mode image allow image auto + state normal + color black #999999 + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state disabled + color white #333333 + cmod image 0xc0 + border 2 2 2 2 + end image + begin image + type button + mode image allow image auto + state normal + color black #cccccc + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state selected + file bar_horizontal_2.png + geom 100x100+0+0:scale + border 2 2 2 2 + state clicked + file bar_horizontal_3.png + geom 100x100+0+0:scale + border 2 2 2 2 + end image end %include "menus.cfg" @@ -242,9 +286,29 @@ begin main bind ctrl button1 to string "\e]5;\a" bind ctrl button2 to string "\e[?30t" bind ctrl button3 to menu Eterm - bind anymod 0xffbe to menu Eterm end actions +# This section must also come after the menus if you want any buttons +# to launch menus. (If not, it can go anywhere.) + begin button_bar + +# Specify a font. The default buttonbar font is the default terminal +# font as defined in the attributes section above. + font "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1" + +# Add a button. The syntax is: +# button [ icon ] action { string | echo | menu } +# + button Eterm action menu Eterm + button Buffers action menu Buffers + button Files action menu Files + button Edit action menu Edit + button Search action menu Search + button Help action menu Help + rbutton icon help.png action string "\e]6;73;Eterm -e man Eterm\a" + rbutton icon exit.png action string "\e]6;70\a" + end button_bar + # The XIM support options. # input_method: set the name of your favorate input method program # preedit_type: OverTheSpot or OffTheSpot or Root @@ -280,13 +344,12 @@ begin main # If true, Eterm will start iconified. iconic false -# If true, Eterm will jump to the bottom of the window when something is echoed -# to the terminal, either by program output or user input. - home_on_echo 0 +# If true, Eterm will jump to the bottom of the window when something is output +# to the terminal. + home_on_output 1 -# If true, Eterm will jump to the bottom of the window when you refresh the -# screen (^L). - home_on_refresh 0 +# If true, Eterm will jump to the bottom of the window when a key is pressed. + home_on_input 1 # If true, Eterm will put the scrollbar on the right of the window (default is left). scrollbar_right true diff --git a/themes/irc/menus.cfg b/themes/irc/menus.cfg index 3235f55..c826a14 100644 --- a/themes/irc/menus.cfg +++ b/themes/irc/menus.cfg @@ -39,13 +39,9 @@ begin menu action string "\e[?25t" end begin menuitem - text "Home on Echo" + text "Home on Output" action string "\e[?1010t" end - begin menuitem - text "Home on Refresh" - action string "\e[?1011t" - end begin menuitem text "Home on Input" action string "\e[?1012t" @@ -870,22 +866,47 @@ begin menu end end -# This is the menu that gets called by Ctrl-Button3 begin menu - title Eterm - begin menuitem - text "Font" - action submenu Font - end - begin menuitem - text "Background" - action submenu Background - end - begin menuitem - text "Terminal" - action submenu Terminal - end - - + title "Eterm Operations" + begin menuitem + text "Version" + action string "\e[8n" + end + begin menuitem + text "Status" + action string "\e[9n" + end + separator + begin menuitem + text "Save Settings..." + action string "\e]6;71\a" + end + begin menuitem + text "Exit" + action string "\e]6;70\a" + end +end + +# This is the menu that gets called by Ctrl-Button3 +begin menu + title Eterm + begin menuitem + text "Font" + action submenu Font + end + begin menuitem + text "Background" + action submenu Background + end + begin menuitem + text "Terminal" + action submenu Terminal + end + - + begin menuitem + text "New Window..." + action string "\e]6;73;Eterm\a" + end begin menuitem text "Version" action string "\e[8n" diff --git a/themes/irc/theme.cfg.in b/themes/irc/theme.cfg.in index a8566d2..1564e3e 100644 --- a/themes/irc/theme.cfg.in +++ b/themes/irc/theme.cfg.in @@ -23,11 +23,6 @@ begin main background black cursor #ffff00 cursor_text #880000 - scrollbar #3f1c00 - unfocused_scrollbar #777777 - menu #777777 - unfocused_menu #777777 - menu_text black pointer white # video attribute can either be "normal" or "reverse" @@ -84,7 +79,7 @@ begin main font default @DEF_FONT_IDX@ font 0 @FONT0@ font 1 @FONT1@ - font 2 @FONT2@ + font 2 shine font 3 @FONT3@ font 4 @FONT4@ font 5 8x13 @@ -151,27 +146,43 @@ begin main type trough mode image allow image trans viewport auto state normal + color black #666666 file bar_vertical_3.png # Here is how you specify the geometry string separately. See the man page for its syntax. geom :scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type anchor mode image allow image auto state normal + color black #666666 file bar_vertical_1.png geom :scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_vertical_2.png geom :scale - border 3 3 2 2 + border 2 2 2 2 + end image + begin image + type thumb + mode image allow image auto + state normal + color black #666666 + file thumb_1.png + geom :scale + border 3 3 3 3 + state selected + file thumb_2.png + geom :scale + border 3 3 3 3 end image begin image type up_arrow mode image allow image auto state normal + color black #666666 file button_arrow_up_1.png geom :scale border 2 2 2 2 @@ -188,6 +199,7 @@ begin main type down_arrow mode image allow image auto state normal + color black #666666 file button_arrow_down_1.png geom :scale border 2 2 2 2 @@ -204,18 +216,20 @@ begin main type menu mode image allow image auto state normal + color black #999999 file bar_horizontal_1.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_horizontal_2.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type submenu mode image allow image auto state normal + color black #999999 file menu1.png geom 100x100+0+0:scale border 3 15 3 3 @@ -231,6 +245,36 @@ begin main border 3 15 3 3 padding 3 15 3 3 end image + begin image + type button_bar + mode image allow image auto + state normal + color black #999999 + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state disabled + color white #333333 + cmod image 0xc0 + border 2 2 2 2 + end image + begin image + type button + mode image allow image auto + state normal + color black #cccccc + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state selected + file bar_horizontal_2.png + geom 100x100+0+0:scale + border 2 2 2 2 + state clicked + file bar_horizontal_3.png + geom 100x100+0+0:scale + border 2 2 2 2 + end image end %include "menus.cfg" @@ -244,9 +288,27 @@ begin main bind ctrl button1 to string "\e]5;\a" bind ctrl button2 to string "\e[?30t" bind ctrl button3 to menu Eterm - bind anymod 0xffbe to menu Eterm end actions +# This section must also come after the menus if you want any buttons +# to launch menus. (If not, it can go anywhere.) + begin button_bar + +# Specify a font. The default buttonbar font is the default terminal +# font as defined in the attributes section above. + font "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1" + +# Add a button. The syntax is: +# button [ icon ] action { string | echo | menu } +# + button Eterm action menu "Eterm Operations" + button Font action menu Font + button Background action menu Background + button Terminal action menu Terminal + rbutton icon help.png action string "\e]6;73;Eterm -e man Eterm\a" + rbutton icon exit.png action string "\e]6;70\a" + end button_bar + # The XIM support options. # input_method: set the name of your favorate input method program # preedit_type: OverTheSpot or OffTheSpot or Root @@ -282,13 +344,12 @@ begin main # If true, Eterm will start iconified. iconic false -# If true, Eterm will jump to the bottom of the window when something is echoed -# to the terminal, either by program output or user input. - home_on_echo 0 +# If true, Eterm will jump to the bottom of the window when something is output +# to the terminal. + home_on_output 1 -# If true, Eterm will jump to the bottom of the window when you refresh the -# screen (^L). - home_on_refresh 0 +# If true, Eterm will jump to the bottom of the window when a key is pressed. + home_on_input 1 # If true, Eterm will put the scrollbar on the right of the window (default is left). scrollbar_right true diff --git a/themes/mutt/menus.cfg b/themes/mutt/menus.cfg index da62961..c512f3e 100644 --- a/themes/mutt/menus.cfg +++ b/themes/mutt/menus.cfg @@ -39,13 +39,9 @@ begin menu action string "\e[?25t" end begin menuitem - text "Home on Echo" + text "Home on Output" action string "\e[?1010t" end - begin menuitem - text "Home on Refresh" - action string "\e[?1011t" - end begin menuitem text "Home on Input" action string "\e[?1012t" @@ -1042,15 +1038,6 @@ end # This is the menu that gets called by Ctrl-Button3 begin menu title Eterm - begin menuitem - text "Messages" - action submenu Messages - end - begin menuitem - text "Mailbox" - action submenu Mailbox - end - - begin menuitem text "Font" action submenu Font diff --git a/themes/mutt/theme.cfg.in b/themes/mutt/theme.cfg.in index 16a4210..0865b9c 100644 --- a/themes/mutt/theme.cfg.in +++ b/themes/mutt/theme.cfg.in @@ -23,11 +23,6 @@ begin main background black cursor #ffff00 cursor_text #880000 - scrollbar #3f1c00 - unfocused_scrollbar #777777 - menu #777777 - unfocused_menu #777777 - menu_text black pointer white # video attribute can either be "normal" or "reverse" @@ -144,22 +139,94 @@ begin main # Th-th-th-th-that's all folks. end image + begin image + type trough + mode image allow image trans viewport auto + state normal + color black #666666 + file bar_vertical_3.png +# Here is how you specify the geometry string separately. See the man page for its syntax. + geom :scale + border 2 2 2 2 + end image + begin image + type anchor + mode image allow image auto + state normal + color black #666666 + file bar_vertical_1.png + geom :scale + border 2 2 2 2 + state selected + file bar_vertical_2.png + geom :scale + border 2 2 2 2 + end image + begin image + type thumb + mode image allow image auto + state normal + color black #666666 + file thumb_1.png + geom :scale + border 3 3 3 3 + state selected + file thumb_2.png + geom :scale + border 3 3 3 3 + end image + begin image + type up_arrow + mode image allow image auto + state normal + color black #666666 + file button_arrow_up_1.png + geom :scale + border 2 2 2 2 + state selected + file button_arrow_up_2.png + geom :scale + border 2 2 2 2 + state clicked + file button_arrow_up_3.png + geom :scale + border 2 2 2 2 + end image + begin image + type down_arrow + mode image allow image auto + state normal + color black #666666 + file button_arrow_down_1.png + geom :scale + border 2 2 2 2 + state selected + file button_arrow_down_2.png + geom :scale + border 2 2 2 2 + state clicked + file button_arrow_down_3.png + geom :scale + border 2 2 2 2 + end image begin image type menu mode image allow image auto state normal + color black #999999 file bar_horizontal_1.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_horizontal_2.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type submenu mode image allow image auto state normal + color black #999999 file menu1.png geom 100x100+0+0:scale border 3 15 3 3 @@ -175,6 +242,36 @@ begin main border 3 15 3 3 padding 3 15 3 3 end image + begin image + type button_bar + mode image allow image auto + state normal + color black #999999 + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state disabled + color white #333333 + cmod image 0xc0 + border 2 2 2 2 + end image + begin image + type button + mode image allow image auto + state normal + color black #cccccc + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state selected + file bar_horizontal_2.png + geom 100x100+0+0:scale + border 2 2 2 2 + state clicked + file bar_horizontal_3.png + geom 100x100+0+0:scale + border 2 2 2 2 + end image end %include "menus.cfg" @@ -188,9 +285,26 @@ begin main bind ctrl button1 to string "\e]5;\a" bind ctrl button2 to string "\e[?30t" bind ctrl button3 to menu Eterm - bind anymod 0xffbe to menu Eterm end actions +# This section must also come after the menus if you want any buttons +# to launch menus. (If not, it can go anywhere.) + begin button_bar + +# Specify a font. The default buttonbar font is the default terminal +# font as defined in the attributes section above. + font "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1" + +# Add a button. The syntax is: +# button [ icon ] action { string | echo | menu } +# + button Eterm action menu Eterm + button Messages action menu Messages + button Mailbox action menu Mailbox + rbutton icon help.png action string "\e]6;73;Eterm -e man Eterm\a" + rbutton icon exit.png action string "\e]6;70\a" + end button_bar + # The XIM support options. # input_method: set the name of your favorate input method program # preedit_type: OverTheSpot or OffTheSpot or Root @@ -226,13 +340,12 @@ begin main # If true, Eterm will start iconified. iconic false -# If true, Eterm will jump to the bottom of the window when something is echoed -# to the terminal, either by program output or user input. - home_on_echo 1 +# If true, Eterm will jump to the bottom of the window when something is output +# to the terminal. + home_on_output 1 -# If true, Eterm will jump to the bottom of the window when you refresh the -# screen (^L). - home_on_refresh 1 +# If true, Eterm will jump to the bottom of the window when a key is pressed. + home_on_input 1 # If true, Eterm will put the scrollbar on the right of the window (default is left). scrollbar_right true diff --git a/themes/trans/menus.cfg b/themes/trans/menus.cfg index 3235f55..c826a14 100644 --- a/themes/trans/menus.cfg +++ b/themes/trans/menus.cfg @@ -39,13 +39,9 @@ begin menu action string "\e[?25t" end begin menuitem - text "Home on Echo" + text "Home on Output" action string "\e[?1010t" end - begin menuitem - text "Home on Refresh" - action string "\e[?1011t" - end begin menuitem text "Home on Input" action string "\e[?1012t" @@ -870,22 +866,47 @@ begin menu end end -# This is the menu that gets called by Ctrl-Button3 begin menu - title Eterm - begin menuitem - text "Font" - action submenu Font - end - begin menuitem - text "Background" - action submenu Background - end - begin menuitem - text "Terminal" - action submenu Terminal - end - - + title "Eterm Operations" + begin menuitem + text "Version" + action string "\e[8n" + end + begin menuitem + text "Status" + action string "\e[9n" + end + separator + begin menuitem + text "Save Settings..." + action string "\e]6;71\a" + end + begin menuitem + text "Exit" + action string "\e]6;70\a" + end +end + +# This is the menu that gets called by Ctrl-Button3 +begin menu + title Eterm + begin menuitem + text "Font" + action submenu Font + end + begin menuitem + text "Background" + action submenu Background + end + begin menuitem + text "Terminal" + action submenu Terminal + end + - + begin menuitem + text "New Window..." + action string "\e]6;73;Eterm\a" + end begin menuitem text "Version" action string "\e[8n" diff --git a/themes/trans/theme.cfg.in b/themes/trans/theme.cfg.in index 62bc939..21a4597 100644 --- a/themes/trans/theme.cfg.in +++ b/themes/trans/theme.cfg.in @@ -23,11 +23,6 @@ begin main background black cursor #ffff00 cursor_text #880000 - scrollbar #3f1c00 - unfocused_scrollbar #777777 - menu #777777 - unfocused_menu #777777 - menu_text black pointer white # video attribute can either be "normal" or "reverse" @@ -149,27 +144,43 @@ begin main type trough mode trans allow image trans viewport auto state normal + color black #666666 file bar_vertical_3.png # Here is how you specify the geometry string separately. See the man page for its syntax. geom :scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type anchor mode image allow image auto state normal + color black #666666 file bar_vertical_1.png geom :scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_vertical_2.png geom :scale - border 3 3 2 2 + border 2 2 2 2 + end image + begin image + type thumb + mode image allow image auto + state normal + color black #666666 + file thumb_1.png + geom :scale + border 3 3 3 3 + state selected + file thumb_2.png + geom :scale + border 3 3 3 3 end image begin image type up_arrow mode image allow image auto state normal + color black #666666 file button_arrow_up_1.png geom :scale border 2 2 2 2 @@ -186,6 +197,7 @@ begin main type down_arrow mode image allow image auto state normal + color black #666666 file button_arrow_down_1.png geom :scale border 2 2 2 2 @@ -202,18 +214,20 @@ begin main type menu mode image allow image auto state normal + color black #999999 file bar_horizontal_1.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 state selected file bar_horizontal_2.png geom 100x100+0+0:scale - border 3 3 2 2 + border 2 2 2 2 end image begin image type submenu mode image allow image auto state normal + color black #999999 file menu1.png geom 100x100+0+0:scale border 3 15 3 3 @@ -229,6 +243,36 @@ begin main border 3 15 3 3 padding 3 15 3 3 end image + begin image + type button_bar + mode image allow image auto + state normal + color black #999999 + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state disabled + color white #333333 + cmod image 0xc0 + border 2 2 2 2 + end image + begin image + type button + mode image allow image auto + state normal + color black #cccccc + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 2 2 2 2 + state selected + file bar_horizontal_2.png + geom 100x100+0+0:scale + border 2 2 2 2 + state clicked + file bar_horizontal_3.png + geom 100x100+0+0:scale + border 2 2 2 2 + end image end %include "menus.cfg" @@ -242,9 +286,27 @@ begin main bind ctrl button1 to string "\e]5;\a" bind ctrl button2 to string "\e[?30t" bind ctrl button3 to menu Eterm - bind anymod 0xffbe to menu Eterm end actions +# This section must also come after the menus if you want any buttons +# to launch menus. (If not, it can go anywhere.) + begin button_bar + +# Specify a font. The default buttonbar font is the default terminal +# font as defined in the attributes section above. + font "-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1" + +# Add a button. The syntax is: +# button [ icon ] action { string | echo | menu } +# + button Eterm action menu "Eterm Operations" + button Font action menu Font + button Background action menu Background + button Terminal action menu Terminal + rbutton icon help.png action string "\e]6;73;Eterm -e man Eterm\a" + rbutton icon exit.png action string "\e]6;70\a" + end button_bar + # The XIM support options. # input_method: set the name of your favorate input method program # preedit_type: OverTheSpot or OffTheSpot or Root @@ -280,13 +342,12 @@ begin main # If true, Eterm will start iconified. iconic false -# If true, Eterm will jump to the bottom of the window when something is echoed -# to the terminal, either by program output or user input. - home_on_echo 1 +# If true, Eterm will jump to the bottom of the window when something is output +# to the terminal. + home_on_output 1 -# If true, Eterm will jump to the bottom of the window when you refresh the -# screen (^L). - home_on_refresh 1 +# If true, Eterm will jump to the bottom of the window when a key is pressed. + home_on_input 1 # If true, Eterm will put the scrollbar on the right of the window (default is left). scrollbar_right true diff --git a/utils/.cvsignore b/utils/.cvsignore index f22683f..6658c90 100644 --- a/utils/.cvsignore +++ b/utils/.cvsignore @@ -5,3 +5,4 @@ Makefile.in Esetroot Etbg Ettable +kEsetroot diff --git a/utils/Etsearch b/utils/Etsearch new file mode 100755 index 0000000..7d45b99 --- /dev/null +++ b/utils/Etsearch @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Eterm Search Utility +# +# $Id$ + +if [ $# -gt 1 -o "X$1" = "X-h" -o "X$1" = "X--help" ]; then + echo "Syntax: Etsearch [string]" + echo " (To clear the highlighting from a previous search," + echo " do not specify a string.)" + echo + exit 0 +fi + +# Code to figure out if we need 'echo -n' or 'echo "\c"', stolen from configure +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' + else + ac_n=-n ac_c= + fi +else + ac_n= ac_c='\c' +fi + +STR="$1" + +echo $ac_n "]6;72;${STR}$ac_c" diff --git a/utils/Makefile.am b/utils/Makefile.am index c081028..0400905 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -3,7 +3,7 @@ INCLUDES = -I. -I../libmej -I.. -I$(includedir) -I$(prefix)/include $(X_CFLAGS) bin_PROGRAMS = Esetroot Etbg Ettable -bin_SCRIPTS = Etcolors Etwinop +bin_SCRIPTS = Etcolors Etwinop Etsearch kEsetroot Esetroot_SOURCES = Esetroot.c Esetroot_LDFLAGS = -rpath $(libdir):$(pkglibdir) @@ -12,5 +12,6 @@ Esetroot_LDADD = -L$(DIST_ROOT)/libmej -L$(libdir) -L$(prefix)/lib $(LIBS) $(GRL Etbg_SOURCES = Etbg.c Ettable_SOURCES = Ettable.c -EXTRA_DIST = Etbg.c Esetroot.c Ettable.c Makefile.am Makefile.in Etcolors Etwinop +EXTRA_DIST = Etbg.c Esetroot.c Ettable.c Makefile.am Makefile.in Etcolors Etwinop Etsearch \ + kEsetroot.in diff --git a/utils/kEsetroot.in b/utils/kEsetroot.in new file mode 100755 index 0000000..906d30e --- /dev/null +++ b/utils/kEsetroot.in @@ -0,0 +1,107 @@ +#!@PERL@ +#======================================================================= +# kEsetroot - KDE Esetroot integration for Eterm +# +# Copyright (C) 1999 - 2000 Dax T. Games +# (dgames@isoc.net) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#======================================================================= +# Written by Dax Games +# Sets root pixmap for Eterm transparency. + +$HOME = $ENV{'HOME'}; +$KDEDIR = $ENV{'KDEDIR'}; +open (in,"$HOME/.kde/share/config/desktop0rc"); + +while () { + if ($_ =~ /^Wallpaper=(.*)/i) { + if (-e $1) { + $PixMap = $1 + #system("/usr/bin/Esetroot -display :0 $1"); + } + elsif (-e "$KDEDIR/share/wallpapers/$1") { + $PixMap = "$KDEDIR/share/wallpapers/$1" + #system("/usr/bin/Esetroot -display :0 $KDEDIR/share/wallpapers/$1"); + } + else { + exit(1); + } + } + elsif ($_ =~ /^WallpaperMode=(.*)/i) { + $WallpaperMode = uc($1); + if ($WallpaperMode eq "TILED") { + $PixMapMode = "" + } + elsif ($WallpaperMode eq "CENTRED") { + $PixMapMode = "-center "; + } + elsif ($WallpaperMode eq "SCALED") { + $PixMapMode = "-scale "; + } + } + +} +close (in); + +system("@BINDIR@/Esetroot $PixMapMode-display :0 $PixMap"); + +if (!-e "$HOME/Desktop/Autostart/kEsetroot.kdelnk") { + print "Do you want to start kEsetroot when KDE starts? y/n [y] "; + $AutostartYORN = (<>); + chomp $AutostartYORN; + + if ($AutostartYORN = "" or $AutostartYORN = "Y") { + open (out, ">$HOME/Desktop/Autostart/kEsetroot.kdelnk"); + print out "\# KDE Config File\n"; + print out "[KDE Desktop Entry]\n"; + print out "Name[fi]=Sovellus\n"; + print out "Comment[C]=Set root pixmap for Eterm transparency\n"; + print out "SwallowTitle=\n"; + print out "SwallowExec=\n"; + print out "Name[ru]=ðÒÉÌÏÖÅÎÉÅ\n"; + print out "BinaryPattern=\n"; + print out "Name[hr]=Program\n"; + print out "Name[sl]=Uporabni¹ki program\n"; + print out "Name[pl]=Aplikacja\n"; + print out "Name=Application\n"; + print out "Name[ca]=Aplicacions\n"; + print out "Name[it]=Applicazione\n"; + print out "Name[da]=Anvendelse\n"; + print out "Name[C]=KDE Esetroot\n"; + print out "MimeType=\n"; + print out "Name[de]=Anwendung\n"; + print out "Name[ja]=¥¢¥×¥ê¥±¡¼¥·¥ç¥ó\n"; + print out "Exec=kEsetroot\n"; + print out "Name[cs]=Aplikace\n"; + print out "Name[sv]=Program\n"; + print out "Icon=kwm.xpm\n"; + print out "TerminalOptions=\n"; + print out "Name[sk]=Aplikácia\n"; + print out "Path=\n"; + print out "Name[pt_BR]=Aplicativo\n"; + print out "Type=Application\n"; + print out "Name[es]=Aplicaciones\n"; + print out "Name[is]=Forrit\n"; + print out "Name[pt]=Aplicação\n"; + print out "Terminal=0\n"; + print out "Name[no]=Applikasjon\n"; + print out "Name[hu]=Applikáció\n"; + print out "Name[ro]=Aplicaþie\n"; + close(out); + } +} + +