From f72ceed5dbbe14bb38e6b07adf7759e2f4c7dbe8 Mon Sep 17 00:00:00 2001 From: Branden Robinson Date: Sun, 6 Nov 2005 00:35:41 +0000 Subject: [PATCH] Import vtwm_5.4.7.orig.tar.gz [dgit import orig vtwm_5.4.7.orig.tar.gz] --- INSTALL | 1 + Imakefile | 197 + Makefile.QNX | 223 + add_window.c | 2558 ++++++++ add_window.h | 62 + applets.c | 209 + contrib/nexpm/Imakefile | 5 + contrib/nexpm/README | 55 + contrib/nexpm/nexpm.c | 516 ++ contrib/nexpm/patchlevel.h | 1 + contrib/nexpm/xpm.COPYRIGHT | 33 + contrib/support/sysrc_add_apps.sh | 206 + contrib/vtwmrc/images/byzantine.xpm | 22 + contrib/vtwmrc/images/djhjr.xpm | 70 + contrib/vtwmrc/images/dot1x3.xbm | 4 + contrib/vtwmrc/images/eyesline.xpm | 23 + contrib/vtwmrc/images/nestedsqu.xbm | 35 + contrib/vtwmrc/images/photon_close.xpm | 47 + contrib/vtwmrc/images/photon_help.xpm | 47 + contrib/vtwmrc/images/photon_maximize.xpm | 47 + contrib/vtwmrc/images/photon_menu.xpm | 47 + contrib/vtwmrc/images/photon_minimize.xpm | 47 + contrib/vtwmrc/images/photon_rarrow.xpm | 19 + contrib/vtwmrc/images/vtwm.gif | Bin 0 -> 85816 bytes contrib/vtwmrc/images/win95_close.xpm | 26 + contrib/vtwmrc/images/win95_menu.xpm | 26 + contrib/vtwmrc/images/win95_minimize.xpm | 26 + contrib/vtwmrc/images/win95_rarrow.xpm | 19 + contrib/vtwmrc/images/win95_unzoom.xpm | 26 + contrib/vtwmrc/images/win95_zoom.xpm | 26 + contrib/vtwmrc/sounds/applause1.au | Bin 0 -> 40112 bytes contrib/vtwmrc/sounds/applause2.au | Bin 0 -> 73761 bytes contrib/vtwmrc/sounds/bleebloo.au | Bin 0 -> 6005 bytes contrib/vtwmrc/sounds/boing1.au | Bin 0 -> 8615 bytes contrib/vtwmrc/sounds/boing2.au | Bin 0 -> 7257 bytes contrib/vtwmrc/sounds/boing3.au | Bin 0 -> 5691 bytes contrib/vtwmrc/sounds/boip.au | Bin 0 -> 938 bytes contrib/vtwmrc/sounds/break1.au | Bin 0 -> 4700 bytes contrib/vtwmrc/sounds/break2.au | Bin 0 -> 52787 bytes contrib/vtwmrc/sounds/cardshuffle.au | Bin 0 -> 26169 bytes contrib/vtwmrc/sounds/cashregister.au | Bin 0 -> 7946 bytes contrib/vtwmrc/sounds/chime1.au | Bin 0 -> 5529 bytes contrib/vtwmrc/sounds/chime2.au | Bin 0 -> 20503 bytes contrib/vtwmrc/sounds/chime3.au | Bin 0 -> 5469 bytes contrib/vtwmrc/sounds/chime4.au | Bin 0 -> 4180 bytes contrib/vtwmrc/sounds/chime5.au | Bin 0 -> 3641 bytes contrib/vtwmrc/sounds/coinslot.au | Bin 0 -> 96367 bytes contrib/vtwmrc/sounds/ddl.au | Bin 0 -> 12162 bytes contrib/vtwmrc/sounds/ddloo.au | Bin 0 -> 1892 bytes contrib/vtwmrc/sounds/dedoo.au | Bin 0 -> 3920 bytes contrib/vtwmrc/sounds/doh1.au | Bin 0 -> 3600 bytes contrib/vtwmrc/sounds/doh2.au | Bin 0 -> 3824 bytes contrib/vtwmrc/sounds/doh3.au | Bin 0 -> 4927 bytes contrib/vtwmrc/sounds/doh4.au | Bin 0 -> 4672 bytes contrib/vtwmrc/sounds/highhat.wav | Bin 0 -> 29646 bytes contrib/vtwmrc/sounds/hithere.au | Bin 0 -> 7186 bytes contrib/vtwmrc/sounds/ping.au | Bin 0 -> 14271 bytes contrib/vtwmrc/sounds/pop1.wav | Bin 0 -> 4758 bytes contrib/vtwmrc/sounds/pop2.wav | Bin 0 -> 1419 bytes contrib/vtwmrc/sounds/pop3.au | Bin 0 -> 759 bytes contrib/vtwmrc/sounds/shutdown.wav | Bin 0 -> 42830 bytes contrib/vtwmrc/sounds/splat1.wav | Bin 0 -> 3734 bytes contrib/vtwmrc/sounds/splat2.wav | Bin 0 -> 21308 bytes contrib/vtwmrc/sounds/squeezetoy.au | Bin 0 -> 2829 bytes contrib/vtwmrc/sounds/startup.wav | Bin 0 -> 41075 bytes contrib/vtwmrc/sounds/touch1.au | Bin 0 -> 1945 bytes contrib/vtwmrc/sounds/touch2.au | Bin 0 -> 6247 bytes contrib/vtwmrc/sounds/touch3.au | Bin 0 -> 7825 bytes contrib/vtwmrc/sounds/touch4.au | Bin 0 -> 11839 bytes contrib/vtwmrc/sounds/touch5.au | Bin 0 -> 15381 bytes contrib/vtwmrc/sounds/tshhh.wav | Bin 0 -> 36056 bytes contrib/vtwmrc/sounds/warp1.au | Bin 0 -> 3930 bytes contrib/vtwmrc/sounds/warp2.au | Bin 0 -> 20942 bytes contrib/vtwmrc/sounds/warp3.au | Bin 0 -> 7979 bytes contrib/vtwmrc/sounds/whoosh1.wav | Bin 0 -> 14526 bytes contrib/vtwmrc/sounds/whoosh2.wav | Bin 0 -> 25756 bytes contrib/vtwmrc/sounds/whoosh3.wav | Bin 0 -> 49646 bytes contrib/vtwmrc/sounds/whoosh4.au | Bin 0 -> 2993 bytes contrib/vtwmrc/sounds/whoosh5.au | Bin 0 -> 3973 bytes contrib/vtwmrc/vtwmrc-95ish | 274 + contrib/vtwmrc/vtwmrc-MWMish | 237 + contrib/vtwmrc/vtwmrc-NoBorder | 272 + contrib/vtwmrc/vtwmrc-PWMish | 263 + contrib/vtwmrc/vtwmrc-TWM3d | 270 + contrib/vtwmrc/vtwmrc-TWMish | 232 + contrib/vtwmrc/vtwmrc-binds | 120 + contrib/vtwmrc/vtwmrc-bools | 53 + contrib/vtwmrc/vtwmrc-lists | 197 + contrib/vtwmrc/vtwmrc-menus | 266 + contrib/vtwmrc/vtwmrc-parms | 66 + contrib/vtwmrc/vtwmrc-sound | 90 + cursor.c | 179 + desktop.c | 1562 +++++ desktop.h | 61 + doc/.vtwmrc-marcel | 754 +++ doc/1.README | 45 + doc/2.1.ANNOUNCE | 74 + doc/2.1.README | 95 + doc/2.2.README | 15 + doc/2.README | 120 + doc/3.FUTURE | 9 + doc/3.README | 102 + doc/4.4.ANNOUNCE | 30 + doc/4.4.FUTURE | 23 + doc/4.4.README | 9 + doc/4.5.ANNOUNCE | 27 + doc/4.5.README | 9 + doc/4.6.ANNOUNCE | 40 + doc/4.6.README | 5 + doc/4.7.README | 25 + doc/4.ANNOUNCE | 44 + doc/4.FUTURE | 18 + doc/4.README | 321 + doc/BUGS | 80 + doc/CHANGELOG | 1375 +++++ doc/DEVELOPERS | 33 + doc/HISTORY | 530 ++ doc/INSTALL | 199 + doc/SOUND | 94 + doc/WISHLIST | 59 + doc/vtwm.man | 2668 ++++++++ doors.c | 458 ++ doors.h | 62 + events.c | 4171 +++++++++++++ events.h | 96 + gc.c | 129 + gc.h | 44 + gram.y | 1248 ++++ iconmgr.c | 1098 ++++ iconmgr.h | 97 + icons.c | 970 +++ lex.l | 111 + list.c | 704 +++ list.h | 72 + menus.c | 6773 +++++++++++++++++++++ menus.h | 220 + parse.c | 2325 +++++++ parse.h | 192 + regions.c | 258 + regions.h | 76 + resize.c | 1906 ++++++ resize.h | 65 + screen.h | 808 +++ sound.c | 330 + sound.h | 48 + system.vtwmrc.2D | 250 + system.vtwmrc.3D | 271 + twm.c | 1586 +++++ twm.h | 580 ++ util.c | 3419 +++++++++++ util.h | 108 + version.c | 71 + version.h | 46 + 153 files changed, 44160 insertions(+) create mode 120000 INSTALL create mode 100644 Imakefile create mode 100644 Makefile.QNX create mode 100644 add_window.c create mode 100644 add_window.h create mode 100644 applets.c create mode 100644 contrib/nexpm/Imakefile create mode 100644 contrib/nexpm/README create mode 100644 contrib/nexpm/nexpm.c create mode 100644 contrib/nexpm/patchlevel.h create mode 100644 contrib/nexpm/xpm.COPYRIGHT create mode 100644 contrib/support/sysrc_add_apps.sh create mode 100644 contrib/vtwmrc/images/byzantine.xpm create mode 100644 contrib/vtwmrc/images/djhjr.xpm create mode 100644 contrib/vtwmrc/images/dot1x3.xbm create mode 100644 contrib/vtwmrc/images/eyesline.xpm create mode 100644 contrib/vtwmrc/images/nestedsqu.xbm create mode 100644 contrib/vtwmrc/images/photon_close.xpm create mode 100644 contrib/vtwmrc/images/photon_help.xpm create mode 100644 contrib/vtwmrc/images/photon_maximize.xpm create mode 100644 contrib/vtwmrc/images/photon_menu.xpm create mode 100644 contrib/vtwmrc/images/photon_minimize.xpm create mode 100644 contrib/vtwmrc/images/photon_rarrow.xpm create mode 100644 contrib/vtwmrc/images/vtwm.gif create mode 100644 contrib/vtwmrc/images/win95_close.xpm create mode 100644 contrib/vtwmrc/images/win95_menu.xpm create mode 100644 contrib/vtwmrc/images/win95_minimize.xpm create mode 100644 contrib/vtwmrc/images/win95_rarrow.xpm create mode 100644 contrib/vtwmrc/images/win95_unzoom.xpm create mode 100644 contrib/vtwmrc/images/win95_zoom.xpm create mode 100644 contrib/vtwmrc/sounds/applause1.au create mode 100644 contrib/vtwmrc/sounds/applause2.au create mode 100644 contrib/vtwmrc/sounds/bleebloo.au create mode 100644 contrib/vtwmrc/sounds/boing1.au create mode 100644 contrib/vtwmrc/sounds/boing2.au create mode 100644 contrib/vtwmrc/sounds/boing3.au create mode 100644 contrib/vtwmrc/sounds/boip.au create mode 100644 contrib/vtwmrc/sounds/break1.au create mode 100644 contrib/vtwmrc/sounds/break2.au create mode 100644 contrib/vtwmrc/sounds/cardshuffle.au create mode 100644 contrib/vtwmrc/sounds/cashregister.au create mode 100644 contrib/vtwmrc/sounds/chime1.au create mode 100644 contrib/vtwmrc/sounds/chime2.au create mode 100644 contrib/vtwmrc/sounds/chime3.au create mode 100644 contrib/vtwmrc/sounds/chime4.au create mode 100644 contrib/vtwmrc/sounds/chime5.au create mode 100644 contrib/vtwmrc/sounds/coinslot.au create mode 100644 contrib/vtwmrc/sounds/ddl.au create mode 100644 contrib/vtwmrc/sounds/ddloo.au create mode 100644 contrib/vtwmrc/sounds/dedoo.au create mode 100644 contrib/vtwmrc/sounds/doh1.au create mode 100644 contrib/vtwmrc/sounds/doh2.au create mode 100644 contrib/vtwmrc/sounds/doh3.au create mode 100644 contrib/vtwmrc/sounds/doh4.au create mode 100644 contrib/vtwmrc/sounds/highhat.wav create mode 100644 contrib/vtwmrc/sounds/hithere.au create mode 100644 contrib/vtwmrc/sounds/ping.au create mode 100644 contrib/vtwmrc/sounds/pop1.wav create mode 100644 contrib/vtwmrc/sounds/pop2.wav create mode 100644 contrib/vtwmrc/sounds/pop3.au create mode 100644 contrib/vtwmrc/sounds/shutdown.wav create mode 100644 contrib/vtwmrc/sounds/splat1.wav create mode 100644 contrib/vtwmrc/sounds/splat2.wav create mode 100644 contrib/vtwmrc/sounds/squeezetoy.au create mode 100644 contrib/vtwmrc/sounds/startup.wav create mode 100644 contrib/vtwmrc/sounds/touch1.au create mode 100644 contrib/vtwmrc/sounds/touch2.au create mode 100644 contrib/vtwmrc/sounds/touch3.au create mode 100644 contrib/vtwmrc/sounds/touch4.au create mode 100644 contrib/vtwmrc/sounds/touch5.au create mode 100644 contrib/vtwmrc/sounds/tshhh.wav create mode 100644 contrib/vtwmrc/sounds/warp1.au create mode 100644 contrib/vtwmrc/sounds/warp2.au create mode 100644 contrib/vtwmrc/sounds/warp3.au create mode 100644 contrib/vtwmrc/sounds/whoosh1.wav create mode 100644 contrib/vtwmrc/sounds/whoosh2.wav create mode 100644 contrib/vtwmrc/sounds/whoosh3.wav create mode 100644 contrib/vtwmrc/sounds/whoosh4.au create mode 100644 contrib/vtwmrc/sounds/whoosh5.au create mode 100644 contrib/vtwmrc/vtwmrc-95ish create mode 100644 contrib/vtwmrc/vtwmrc-MWMish create mode 100644 contrib/vtwmrc/vtwmrc-NoBorder create mode 100644 contrib/vtwmrc/vtwmrc-PWMish create mode 100644 contrib/vtwmrc/vtwmrc-TWM3d create mode 100644 contrib/vtwmrc/vtwmrc-TWMish create mode 100644 contrib/vtwmrc/vtwmrc-binds create mode 100644 contrib/vtwmrc/vtwmrc-bools create mode 100644 contrib/vtwmrc/vtwmrc-lists create mode 100644 contrib/vtwmrc/vtwmrc-menus create mode 100644 contrib/vtwmrc/vtwmrc-parms create mode 100644 contrib/vtwmrc/vtwmrc-sound create mode 100644 cursor.c create mode 100644 desktop.c create mode 100644 desktop.h create mode 100644 doc/.vtwmrc-marcel create mode 100644 doc/1.README create mode 100644 doc/2.1.ANNOUNCE create mode 100644 doc/2.1.README create mode 100644 doc/2.2.README create mode 100644 doc/2.README create mode 100644 doc/3.FUTURE create mode 100644 doc/3.README create mode 100644 doc/4.4.ANNOUNCE create mode 100644 doc/4.4.FUTURE create mode 100644 doc/4.4.README create mode 100644 doc/4.5.ANNOUNCE create mode 100644 doc/4.5.README create mode 100644 doc/4.6.ANNOUNCE create mode 100644 doc/4.6.README create mode 100644 doc/4.7.README create mode 100644 doc/4.ANNOUNCE create mode 100644 doc/4.FUTURE create mode 100644 doc/4.README create mode 100644 doc/BUGS create mode 100644 doc/CHANGELOG create mode 100644 doc/DEVELOPERS create mode 100644 doc/HISTORY create mode 100644 doc/INSTALL create mode 100644 doc/SOUND create mode 100644 doc/WISHLIST create mode 100644 doc/vtwm.man create mode 100644 doors.c create mode 100644 doors.h create mode 100644 events.c create mode 100644 events.h create mode 100644 gc.c create mode 100644 gc.h create mode 100644 gram.y create mode 100644 iconmgr.c create mode 100644 iconmgr.h create mode 100644 icons.c create mode 100644 lex.l create mode 100644 list.c create mode 100644 list.h create mode 100644 menus.c create mode 100644 menus.h create mode 100644 parse.c create mode 100644 parse.h create mode 100644 regions.c create mode 100644 regions.h create mode 100644 resize.c create mode 100644 resize.h create mode 100644 screen.h create mode 100644 sound.c create mode 100644 sound.h create mode 100644 system.vtwmrc.2D create mode 100644 system.vtwmrc.3D create mode 100644 twm.c create mode 100644 twm.h create mode 100644 util.c create mode 100644 util.h create mode 100644 version.c create mode 100644 version.h diff --git a/INSTALL b/INSTALL new file mode 120000 index 0000000..1f38889 --- /dev/null +++ b/INSTALL @@ -0,0 +1 @@ +doc/INSTALL \ No newline at end of file diff --git a/Imakefile b/Imakefile new file mode 100644 index 0000000..72db51e --- /dev/null +++ b/Imakefile @@ -0,0 +1,197 @@ +#ifndef XCOMM +#define XCOMM # +#endif + +XCOMM $XConsortium: Imakefile,v 1.33 91/07/17 00:48:06 gildea Exp $ +XCOMM +XCOMM Here is an Imakefile for VTWM. +XCOMM I like to use Imakefiles for everything, and I am sure other +XCOMM people do also, so perhaps you could do us all a favor and +XCOMM distribute this one. + +XCOMM =============== Start of common editables ===================== + +XCOMM To omit XPM image support, uncomment this +XCOMM NO_XPM_SUPPORT = -DNO_XPM_SUPPORT +XCOMM and comment these + XPMLIB = -lXpm + XPMINC = +XCOMM (version 3.4h of the XPM library is the earliest supported I know of) + +XCOMM To omit regular expressions ("RE"s) support, uncomment this +XCOMM NO_REGEX_SUPPORT = -DNO_REGEX_SUPPORT +XCOMM and comment these + REGEXLIB = + REGEXINC = +XCOMM (the library must conform to the POSIX 1003.2 specification) + +XCOMM To omit sound support, uncomment this +XCOMM NO_SOUND_SUPPORT = -DNO_SOUND_SUPPORT +XCOMM and comment these +SOUNDLIB = -L/usr/local/lib -lrplay +SOUNDINC = -I/usr/local/include +XCOMM (sound is supported only by way of the rplay library) + +XCOMM To omit Internationalization support, uncomment this +XCOMM NO_I18N_SUPPORT = -DNO_I18N_SUPPORT + +XCOMM To omit m4 pre-processing of resource files, uncomment this +XCOMM NO_M4_SUPPORT = -DNO_M4_SUPPORT + +XCOMM To omit platform and build info in the version window, uncomment this +XCOMM NO_BUILD_INFO = -DNO_BUILD_INFO + +XCOMM For lexers that don't track line numbers, uncomment this +XCOMM NEED_YYLINENO_V = -DNEED_YYLINENO_V + +XCOMM For those systems that don't have putenv(), uncomment this +XCOMM NEED_PUTENV_F = -DNEED_PUTENV_F + +XCOMM For those systems that require sys/select.h, uncomment this +XCOMM NEED_SELECT_H = -DNEED_SELECT_H + +XCOMM For those systems that require process.h, uncomment this +XCOMM NEED_PROCESS_H = -DNEED_PROCESS_H + +XCOMM Installation path for the binary + VTWMBINDIR = $(BINDIR) + +XCOMM Installation path for the system resource file + VTWMLIBDIR = $(LIBDIR)/twm + +XCOMM Installation path for the man page + VTWMMANDIR = $(MANDIR) + +XCOMM For the traditional look of TWM as the system fallback, +XCOMM change this to "2D" + SYS_VTWMRC_LOOK = 3D + +XCOMM ================ End of common editables ====================== + +XCOMM ============= Start of less common editables ================== + +XCOMM Handy for developers to check man page editions +XCOMM (see the end of this file) + DEROFF = deroff + DW = dw + SPELL = spell + +XCOMM Required to generate HTML or Postscript versions of the man page +XCOMM (see the end of this file) + MAN2HTML = man2html + MAN2PS = man2ps + +XCOMM ============== End of less common editables =================== + +XCOMM ========= Editing below here should not be necessary ========== + + YFLAGS = -d + DEPLIBS = $(DEPXMULIB) $(DEPEXTENSIONLIB) $(DEPXLIB) + LOCAL_LIBRARIES = $(LEXLIB) $(XPMLIB) $(REGEXLIB) $(SOUNDLIB) \ + $(XMULIB) $(EXTENSIONLIB) $(XLIB) + LINTLIBS = $(LINTXMU) $(LINTEXTENSIONLIB) $(LINTXLIB) + EXTRA_INCLUDES = $(XPMINC) $(REGEXINC) $(SOUNDINC) + DEFINES = $(SIGNAL_DEFINES) $(NO_XPM_SUPPORT) $(NO_REGEX_SUPPORT) \ + $(NO_SOUND_SUPPORT) $(NO_I18N_SUPPORT) $(NO_M4_SUPPORT) + + SRCS = gram.c lex.c deftwmrc.c add_window.c gc.c list.c \ + twm.c sound.c parse.c menus.c events.c resize.c util.c \ + version.c iconmgr.c cursor.c regions.c applets.c \ + icons.c desktop.c doors.c lastmake.c + + OBJS = gram.o lex.o deftwmrc.o add_window.o gc.o list.o \ + twm.o sound.o parse.o menus.o events.o resize.o util.o \ + version.o iconmgr.o cursor.o regions.o applets.o \ + icons.o desktop.o doors.o lastmake.o + +AllTarget(vtwm) + +SpecialObjectRule(menus.o,gram.h,$(NO_BUILD_INFO) $(NEED_PROCESS_H)) + +SpecialObjectRule(util.o,gram.h,$(NEED_PUTENV_F)) + +SpecialObjectRule(events.o,gram.h,$(NEED_SELECT_H)) + +SpecialObjectRule(parse.o,gram.h,$(NEED_YYLINENO_V) \ +'-DSYSTEM_VTWMRC="'$(VTWMLIBDIR)'/system.vtwmrc"' \ +'-DSYSTEM_TWMRC="'$(VTWMLIBDIR)'/system.twmrc"') + +SpecialObjectRule(add_window.o applets.o icons.o \ +list.o regions.o sound.o twm.o,gram.h,NullParameter) + +NormalProgramTarget(vtwm,$(OBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),NullParameter) + +InstallProgram(vtwm,$(VTWMBINDIR)) +InstallManPage(vtwm,$(VTWMMANDIR)) +InstallNonExecFile(system.vtwmrc,$(VTWMLIBDIR)) + +depend:: lex.c gram.c deftwmrc.c lastmake.c vtwm.man + +all:: + $(RM) deftwmrc.* lastmake.* + +install:: + $(RM) deftwmrc.* lastmake.* + $(MAKE) install.man + +clean:: + $(RM) y.tab.h y.tab.c lex.yy.c gram.h gram.c lex.c deftwmrc.c \ + lastmake.c system.vtwmrc vtwm.dw vtwm.ser vtwm.html vtwm.ps vtwm.man + +gram.h gram.c: gram.y + $(YACC) $(YFLAGS) gram.y + $(MV) y.tab.c gram.c + $(MV) y.tab.h gram.h + +deftwmrc.c: system.vtwmrc + $(RM) $@ + echo '/* ' >>$@ + echo ' * This file is generated automatically from the default' >>$@ + echo ' * VTWM bindings file system.vtwmrc.'$(SYS_VTWMRC_LOOK)' by the VTWM Makefile.' >>$@ + echo ' */' >>$@ + echo '' >>$@ + echo 'char *defTwmrc[] = {' >>deftwmrc.c + sed -e '/^$$/d' -e '/^#/d' -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/",/' -e 's/[ ]\{1,\}/ /g' -e 's/^" /"/' system.vtwmrc >>$@ + echo '(char *)0 };' >>$@ + +lastmake.c: + $(RM) $@ + echo '/* ' >>$@ + echo ' * This file is generated automatically by the VTWM Makefile.' >>$@ + echo ' */' >>$@ + echo '' >>$@ + echo 'char *lastmake[] = {' >>lastmake.c + echo ' "Platform: '`uname -r -s`'",' >>$@ + echo ' "Build: '`date`'",' >>$@ + echo ' "" };' >>$@ + +system.vtwmrc: + $(RM) $@ + $(CP) $@.$(SYS_VTWMRC_LOOK) $@ + +vtwm.man: + $(RM) $@ + $(LN) doc/$@ $@ + +XCOMM Handy for developers to check the man page +dw vtwm.dw: vtwm.man + $(DEROFF) vtwm.man | $(DW) >vtwm.dw + @if test -s vtwm.dw ; \ + then \ + echo Doubled words in vtwm.man ... ; \ + cat vtwm.dw ; \ + fi +spell vtwm.ser: vtwm.man vtwm.sok + $(DEROFF) vtwm.man | $(SPELL) +vtwm.sok >vtwm.ser + @if test -s vtwm.ser ; \ + then \ + echo Spelling exceptions in vtwm.man ... ; \ + cat vtwm.ser ; \ + fi + +XCOMM If you wish to generate HTML or Postscript versions of the man page, +XCOMM enter 'make vtwm.html' or 'make vtwm.ps' +vtwm.html: vtwm.man + $(MAN2HTML) vtwm.man +vtwm.ps: vtwm.man + $(MAN2PS) < $< >$@ diff --git a/Makefile.QNX b/Makefile.QNX new file mode 100644 index 0000000..f0ff874 --- /dev/null +++ b/Makefile.QNX @@ -0,0 +1,223 @@ + +# Here is a makefile for VTWM. +# +# It's a hand-tweaked version of the makefile made with xmkmf, +# it may prove useful as a template for those who don't have xmkmf. +# +# This makefile guarantees that the build info is absolutely current. +# +# djhjr + +# =============== Start of common editables ===================== + +# To omit XPM image support, uncomment this +#XPM_DEFINE = -DNO_XPM_SUPPORT +# and comment these +XPMLIB = -lXpm +XPMINC = +# (version 3.4h of the XPM library is the earliest supported I know of) + +# To omit regular expressions ("RE"s) support, uncomment this +#REGEX_DEFINE = -DNO_REGEX_SUPPORT +# and comment these +REGEXLIB = +REGEXINC = +# (the library must conform to the POSIX 1003.2 specification) + +# To omit sound support. uncomment this +SOUND_DEFINE = -DNO_SOUND_SUPPORT +# and comment these +#SOUNDLIB = -L/usr/local/lib -lrplay +#SOUNDINC = -I/usr/local/include +# (sound is supported only by way of the rplay library) + +# To omit Internationalization support, uncomment this +I18N_DEFINE = -DNO_I18N_SUPPORT + +# To omit m4 pre-processing of resource files, uncomment this +#M4_DEFINE = -DNO_M4_SUPPORT + +# To omit platform and build info in the version window, uncomment this +#INFO_DEFINE = -DNO_BUILD_INFO + +# For lexers that don't track line numbers, uncomment this +YYLINENO_DEFINE = -DNEED_YYLINENO_V + +# For those systems that don't have putenv(), uncomment this +PUTENV_DEFINE = -DNEED_PUTENV_F + +# For those systems that require sys/select.h, uncomment this +SELECT_DEFINE = -DNEED_SELECT_H + +# For those systems that require process.h, uncomment this +PROCESS_DEFINE = -DNEED_PROCESS_H + +# Installation path for the binary +VTWMBINDIR = /usr/bin/X11 + +# Installation path for the system resource file +VTWMLIBDIR = /usr/lib/X11/twm + +# Installation path for the man page +VTWMMANDIR = /usr/man/mann + +# For the traditional look of TWM as the system fallback, +# change this to "2D" +SYS_VTWMRC_LOOK = 3D + +CDEBUGFLAGS = -w4 -M +CCOPTIONS = -Otx -zp1 -mf -b -j -Wc,-s -N32k + +# ================ End of common editables ====================== + +# ============= Start of less common editables ================== + +CP = cp -f +MV = mv -f +RM = rm -f +LN = ln -fs +CC = cc +LEX = lex +YACC = yacc + +YFLAGS = -d + +USRLIBDIR = /usr/lib/X11 + +# Handy for developers to check man page editions +# (see the end of this file) +DEROFF = deroff +DW = dw +SPELL = spell + +# Required to generate HTML or Postscript versions of the man page +# (see the end of this file) +MAN2HTML = man2html +MAN2PS = man2ps + +# ============== End of less common editables =================== + +# ========= Editing below here should not be necessary ========== + +XMULIB = -lXmu +XTOOLLIB = +EXTENSIONLIB = -lXext +XLIB = $(EXTENSIONLIB) -lX11_s + +LOCAL_LIBRARIES = $(XMULIB) $(XTOOLLIB) $(XLIB) \ + $(XPMLIB) $(REGEXLIB) $(SOUNDLIB) +EXTRA_LIBRARIES = -lXqnx -lsocket +LDLIBS = $(LOCAL_LIBRARIES) $(EXTRA_LIBRARIES) + +INCLUDES = +EXTRA_INCLUDES = $(XPMINC) $(REGEXINC) $(SOUNDINC) +STD_INCLUDES = + +ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(STD_INCLUDES) + +STD_DEFINES = -D__QNX__ -DMetroLink -DSTRINGS_ALIGNED -DNO_REGEX \ + -DBOGUS_MB_MAX +EXTRA_DEFINES = $(XPM_DEFINE) $(SOUND_DEFINE) $(REGEX_DEFINE) \ + $(I18N_DEFINE) $(M4_DEFINE) $(INFO_DEFINE) \ + $(YYLINENO_DEFINE) $(PUTENV_DEFINE) $(SELECT_DEFINE) \ + $(PROCESS_DEFINE) +PROTO_DEFINES = + +ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) + +CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES) -L$(USRLIBDIR) + +SRCS = gram.c lex.c deftwmrc.c add_window.c gc.c list.c twm.c sound.c \ + parse.c menus.c events.c resize.c util.c version.c iconmgr.c \ + cursor.c regions.c applets.c icons.c desktop.c doors.c lastmake.c + +OBJS = gram.o lex.o deftwmrc.o add_window.o gc.o list.o twm.o sound.o \ + parse.o menus.o events.o resize.o util.o version.o iconmgr.o \ + cursor.o regions.o applets.o icons.o desktop.o doors.o lastmake.o + +PROGRAM = vtwm + +all: vtwm + +depend: lex.c gram.c deftwmrc.c lastmake.c + +install: + $(CP) $(PROGRAM) $(VTWMBINDIR) + $(CP) system.vtwmrc $(VTWMLIBDIR) + $(CP) doc/vtwm.man $(VTWMMANDIR) + +clean: + $(RM) $(PROGRAM) *.o *.b *.err *.map y.tab.h y.tab.c lex.yy.c \ + gram.h gram.c lex.c deftwmrc.c lastmake.c system.vtwmrc \ + vtwm.dw vtwm.ser vtwm.html vtwm.ps + +vtwm: $(OBJS) + $(RM) $@ + $(CC) -o $@ $(OBJS) $(CFLAGS) $(LDLIBS) + $(RM) deftwmrc.* lastmake.* + +parse.o: gram.h + $(RM) $@ + $(CC) -c $(CFLAGS) '-DSYSTEM_VTWMRC="'$(VTWMLIBDIR)'/system.vtwmrc"' \ + '-DSYSTEM_TWMRC="'$(VTWMLIBDIR)'/system.twmrc"' parse.c + +add_window.o applets.o events.o icons.o list.o menus.o \ +regions.o sound.o twm.o util.o: gram.h + $(RM) $@ + $(CC) -c $(CFLAGS) $*.c + +lex.o: gram.h + +gram.h gram.c: gram.y + $(YACC) $(YFLAGS) gram.y + $(MV) y.tab.c gram.c + $(MV) y.tab.h gram.h + +deftwmrc.c: system.vtwmrc + $(RM) $@ + echo '/* ' >>$@ + echo ' * This file is generated automatically from the default' >>$@ + echo ' * VTWM bindings file system.vtwmrc.'$(SYS_VTWMRC_LOOK)' by the VTWM Makefile.' >>$@ + echo ' */' >>$@ + echo '' >>$@ + echo 'char *defTwmrc[] = {' >>deftwmrc.c + sed -e '/^$$/d' -e '/^#/d' -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/",/' -e 's/[ ]\{1,\}/ /g' -e 's/^" /"/' system.vtwmrc >>$@ + echo '(char *)0 };' >>$@ + +lastmake.c: + $(RM) $@ + echo '/* ' >>$@ + echo ' * This file is generated automatically by the VTWM Makefile.' >>$@ + echo ' */' >>$@ + echo '' >>$@ + echo 'char *lastmake[] = {' >>lastmake.c + echo ' "Platform: '`uname -r -s`'",' >>$@ + echo ' "Build: '`date`'",' >>$@ + echo ' "" };' >>$@ + +system.vtwmrc: + $(RM) $@ + $(CP) $@.$(SYS_VTWMRC_LOOK) $@ + +# Handy for developers to check the man page +dw vtwm.dw: doc/vtwm.man + $(DEROFF) doc/vtwm.man | $(DW) >vtwm.dw + @if test -s vtwm.dw ; \ + then \ + echo Doubled words in vtwm.man ... ; \ + cat vtwm.dw ; \ + fi +spell vtwm.ser: doc/vtwm.man vtwm.sok + $(DEROFF) doc/vtwm.man | $(SPELL) +vtwm.sok >vtwm.ser + @if test -s vtwm.ser ; \ + then \ + echo Spelling exceptions in vtwm.man ... ; \ + cat vtwm.ser ; \ + fi + +# If you wish to generate HTML or Postscript versions of the man page, +# enter 'make vtwm.html' or 'make vtwm.ps' +vtwm.html: doc/vtwm.man + $(MAN2HTML) doc/vtwm.man +vtwm.ps: doc/vtwm.man + $(MAN2PS) < $< >$@ diff --git a/add_window.c b/add_window.c new file mode 100644 index 0000000..1141cfe --- /dev/null +++ b/add_window.c @@ -0,0 +1,2558 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/********************************************************************** + * + * $XConsortium: add_window.c,v 1.153 91/07/10 13:17:26 dave Exp $ + * + * Add a new window, put the titlbar and other stuff around + * the window + * + * 31-Mar-88 Tom LaStrange Initial Version. + * + **********************************************************************/ + +#include +#include +#include "twm.h" +#include +#ifndef NO_XPM_SUPPORT +#include +#endif + +#include "add_window.h" +#include "util.h" +#include "resize.h" +#include "parse.h" + +/* djhjr - 4/19/96 */ +#include "gram.h" + +#include "list.h" +#include "events.h" +#include "menus.h" +#include "screen.h" +#include "iconmgr.h" +#include "desktop.h" + +/* random placement coordinates */ +#define PLACEMENT_START 50 +#define PLACEMENT_INCR 30 + +/* 4/26/99 - djhjr */ +extern int PlaceApplet(); + +#define gray_width 2 +#define gray_height 2 +static char gray_bits[] = { + 0x02, 0x01}; + +/* djhjr - 4/19/96 */ +static unsigned char black_bits[] = { + 0xFF, 0xFF}; + +int AddingX; +int AddingY; +int AddingW; +int AddingH; + +static void CreateWindowTitlebarButtons(); +void SetHighlightPixmap(); + +/* djhjr - 4/14/98 */ +static void AddMoveAndResize(); + +char NoName[] = "Untitled"; /* name if no name is specified */ + + +/************************************************************************ + * + * Procedure: + * GetGravityOffsets - map gravity to (x,y) offset signs for adding + * to x and y when window is mapped to get proper placement. + * + ************************************************************************ + */ + +void GetGravityOffsets (tmp, xp, yp) + TwmWindow *tmp; /* window from which to get gravity */ + int *xp, *yp; /* return values */ +{ + static struct _gravity_offset { + int x, y; + } gravity_offsets[11] = { + { 0, 0 }, /* ForgetGravity */ + { -1, -1 }, /* NorthWestGravity */ + { 0, -1 }, /* NorthGravity */ + { 1, -1 }, /* NorthEastGravity */ + { -1, 0 }, /* WestGravity */ + { 0, 0 }, /* CenterGravity */ + { 1, 0 }, /* EastGravity */ + { -1, 1 }, /* SouthWestGravity */ + { 0, 1 }, /* SouthGravity */ + { 1, 1 }, /* SouthEastGravity */ + { 0, 0 }, /* StaticGravity */ + }; + register int g = ((tmp->hints.flags & PWinGravity) + ? tmp->hints.win_gravity : NorthWestGravity); + + if (g < ForgetGravity || g > StaticGravity) { + *xp = *yp = 0; + } else { + *xp = gravity_offsets[g].x; + *yp = gravity_offsets[g].y; + } +} + + +/*********************************************************************** + * + * Procedure: + * AddWindow - add a new window to the twm list + * + * Returned Value: + * (TwmWindow *) - pointer to the TwmWindow structure + * + * Inputs: + * w - the window id of the window to add + * iconm - flag to tell if this is an icon manager window + * iconp - pointer to icon manager struct + * + *********************************************************************** + */ + +TwmWindow * +AddWindow(w, iconm, iconp) +Window w; +int iconm; +IconMgr *iconp; +{ + TwmWindow *tmp_win; /* new twm window structure */ + unsigned long valuemask; /* mask for create windows */ + XSetWindowAttributes attributes; /* attributes for create windows */ +#ifdef NO_I18N_SUPPORT + XTextProperty text_property; +#endif + Atom actual_type; + int actual_format; + unsigned long nitems, bytesafter; + int ask_user; /* don't know where to put the window */ + int *ppos_ptr, ppos_on; /* djhjr - 9/24/02 */ + int gravx, gravy; /* gravity signs for positioning */ + int namelen; + int bw2; + char *icon_name; /* djhjr - 2/20/99 */ +#ifndef NO_I18N_SUPPORT + char *name; +#endif + /* next two submitted by Jonathan Paisley - 11/8/02 */ + Atom motifhints = XInternAtom( dpy, "_MOTIF_WM_HINTS", 0); + MotifWmHints *mwmhints; + +#ifdef DEBUG + fprintf(stderr, "AddWindow: w = 0x%x\n", w); +#endif + + /* allocate space for the twm window */ + tmp_win = (TwmWindow *)calloc(1, sizeof(TwmWindow)); + if (tmp_win == 0) + { + fprintf (stderr, "%s: Unable to allocate memory to manage window ID %lx.\n", + ProgramName, w); + return NULL; + } + tmp_win->w = w; + tmp_win->zoomed = ZOOM_NONE; + tmp_win->iconmgr = iconm; + tmp_win->iconmgrp = iconp; + tmp_win->cmaps.number_cwins = 0; + + XSelectInput(dpy, tmp_win->w, PropertyChangeMask); + XGetWindowAttributes(dpy, tmp_win->w, &tmp_win->attr); + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + if (I18N_FetchName(dpy, tmp_win->w, &name)) + { + tmp_win->name = strdup(name); + free(name); + } +#else + /* + * Ask the window manager for a name with "newer" R4 function - + * it was 'XFetchName()', which apparently failed more often. + * Submitted by Nicholas Jacobs + */ + if (XGetWMName(dpy, tmp_win->w, &text_property) != 0) + { + tmp_win->name = (char *)strdup(text_property.value); + XFree(text_property.value); + } +#endif + else + tmp_win->name = NoName; + + tmp_win->class = NoClass; + XGetClassHint(dpy, tmp_win->w, &tmp_win->class); + FetchWmProtocols (tmp_win); + FetchWmColormapWindows (tmp_win); + + /* + * do initial clip; should look at window gravity + */ + if (tmp_win->attr.width > Scr->MaxWindowWidth) + tmp_win->attr.width = Scr->MaxWindowWidth; + if (tmp_win->attr.height > Scr->MaxWindowHeight) + tmp_win->attr.height = Scr->MaxWindowHeight; + + tmp_win->wmhints = XGetWMHints(dpy, tmp_win->w); + if (tmp_win->wmhints && (tmp_win->wmhints->flags & WindowGroupHint)) + tmp_win->group = tmp_win->wmhints->window_group; + else + tmp_win->group = tmp_win->w/* NULL */; + + /* submitted by Jonathan Paisley - 11/8/02 */ + tmp_win->mwmhints.flags = 0; + if (motifhints != None) + { + if (XGetWindowProperty(dpy, tmp_win->w, motifhints, + 0L, sizeof(MotifWmHints), False, + motifhints, &actual_type, &actual_format, + &nitems, &bytesafter, + (unsigned char**)&mwmhints) == Success && actual_type != None) + { + if (mwmhints) + { + tmp_win->mwmhints = *mwmhints; + XFree(mwmhints); + } + } + } + + /* + * The July 27, 1988 draft of the ICCCM ignores the size and position + * fields in the WM_NORMAL_HINTS property. + */ + + tmp_win->transient = Transient(tmp_win->w, &tmp_win->transientfor); + + if (tmp_win->class.res_name == NULL) + tmp_win->class.res_name = NoName; + if (tmp_win->class.res_class == NULL) + tmp_win->class.res_class = NoName; + + tmp_win->full_name = tmp_win->name; + namelen = strlen (tmp_win->name); + + tmp_win->highlight = Scr->Highlight && +/* djhjr - 4/22/98 + (!(short)(int) LookInList(Scr->NoHighlight, tmp_win->full_name, + &tmp_win->class)); +*/ + (LookInList(Scr->NoHighlight, tmp_win->full_name, + &tmp_win->class) == (char *)NULL); + + tmp_win->stackmode = Scr->StackMode && +/* djhjr - 4/22/98 + (!(short)(int) LookInList(Scr->NoStackModeL, tmp_win->full_name, + &tmp_win->class)); +*/ + (LookInList(Scr->NoStackModeL, tmp_win->full_name, + &tmp_win->class) == (char *)NULL); + + tmp_win->titlehighlight = Scr->TitleHighlight && +/* djhjr - 4/22/98 + (!(short)(int) LookInList(Scr->NoTitleHighlight, tmp_win->full_name, + &tmp_win->class)); +*/ + (LookInList(Scr->NoTitleHighlight, tmp_win->full_name, + &tmp_win->class) == (char *)NULL); + + tmp_win->auto_raise = Scr->AutoRaiseDefault || /* RAISEDELAY */ +/* djhjr - 4/22/98 + (short)(int) LookInList(Scr->AutoRaise, tmp_win->full_name, + &tmp_win->class); +*/ + (LookInList(Scr->AutoRaise, tmp_win->full_name, + &tmp_win->class) != (char *)NULL); + if (tmp_win->auto_raise) Scr->NumAutoRaises++; + + tmp_win->iconify_by_unmapping = Scr->IconifyByUnmapping; + if (Scr->IconifyByUnmapping) + { +/* djhjr - 9/21/99 + tmp_win->iconify_by_unmapping = iconm ? FALSE : +*/ + tmp_win->iconify_by_unmapping = +/* djhjr - 4/22/98 + !(short)(int) LookInList(Scr->DontIconify, tmp_win->full_name, + &tmp_win->class); +*/ + (LookInList(Scr->DontIconify, tmp_win->full_name, + &tmp_win->class) == (char *)NULL); + } + tmp_win->iconify_by_unmapping |= +/* djhjr - 4/22/98 + (short)(int) LookInList(Scr->IconifyByUn, tmp_win->full_name, + &tmp_win->class); +*/ + (LookInList(Scr->IconifyByUn, tmp_win->full_name, + &tmp_win->class) != (char *)NULL); + + /* Scr->NoWindowRingL submitted by Jonathan Paisley - 10/27/02 */ + if ((Scr->UseWindowRing || + LookInList(Scr->WindowRingL, tmp_win->full_name, + &tmp_win->class)) && + LookInList(Scr->NoWindowRingL, tmp_win->full_name, + &tmp_win->class) == (char *)NULL) + { + /* in menus.c now - djhjr - 10/27/02 */ + AddWindowToRing(tmp_win); + } + else + tmp_win->ring.next = tmp_win->ring.prev = NULL; +#ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */ + tmp_win->ring.cursor_valid = False; +#endif + + if (LookInList(Scr->NailedDown, tmp_win->full_name, &tmp_win->class)) + tmp_win->nailed = TRUE; + else + tmp_win->nailed = FALSE; + + if (LookInList(Scr->DontShowInDisplay, tmp_win->full_name, &tmp_win->class)) + tmp_win->showindesktopdisplay = FALSE; + else + tmp_win->showindesktopdisplay = TRUE; + + tmp_win->squeeze_info = NULL; + /* + * get the squeeze information; note that this does not have to be freed + * since it is coming from the screen list + */ + if (HasShape) { + if (!LookInList (Scr->DontSqueezeTitleL, tmp_win->full_name, + &tmp_win->class)) { + tmp_win->squeeze_info = (SqueezeInfo *) + LookInList (Scr->SqueezeTitleL, tmp_win->full_name, + &tmp_win->class); + if (!tmp_win->squeeze_info) { + static SqueezeInfo default_squeeze = { J_LEFT, 0, 0 }; + if (Scr->SqueezeTitle) + tmp_win->squeeze_info = &default_squeeze; + } + } + } + + tmp_win->old_bw = tmp_win->attr.border_width; + +#ifdef NEVER /* see the next '#ifdef NEVER's '#else' - C. F. Jalali */ + /* djhjr - 4/19/96 */ + /* was 'Scr->ThreeDBorderWidth' - djhjr - 8/11/98 */ + tmp_win->frame_bw3D = Scr->BorderWidth; +#endif + /* added 'Scr->NoBorders' test - djhjr - 8/23/02 */ + if (Scr->NoBorders || LookInList(Scr->NoBorder, tmp_win->full_name, &tmp_win->class)) + { + tmp_win->frame_bw = 0; + tmp_win->frame_bw3D = 0; + } + else +#ifdef NEVER + if (tmp_win->frame_bw3D != 0) + { + tmp_win->frame_bw = 0; + Scr->ClientBorderWidth = FALSE; + } + else + if (Scr->ClientBorderWidth) + tmp_win->frame_bw = tmp_win->old_bw; + else + tmp_win->frame_bw = Scr->BorderWidth; +#else + /* + * Submitted by Caveh Frank Jalali - 8/25/98 + */ + { + if (Scr->BorderBevelWidth > 0) + { + tmp_win->frame_bw3D = Scr->BorderWidth; + tmp_win->frame_bw = 0; + Scr->ClientBorderWidth = FALSE; + } + else + { + tmp_win->frame_bw3D = 0; + if (Scr->ClientBorderWidth) + tmp_win->frame_bw = tmp_win->old_bw; + else + tmp_win->frame_bw = Scr->BorderWidth; + } + } +#endif + + /* submitted by Jonathan Paisley - 11/8/02 */ + if (tmp_win->mwmhints.flags & MWM_HINTS_DECORATIONS) + { + if (tmp_win->mwmhints.decorations & MWM_DECOR_ALL) + tmp_win->mwmhints.decorations |= (MWM_DECOR_BORDER | + MWM_DECOR_RESIZEH | MWM_DECOR_TITLE | + MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | + MWM_DECOR_MAXIMIZE); + + if (!(tmp_win->mwmhints.decorations & MWM_DECOR_BORDER)) + tmp_win->frame_bw = tmp_win->frame_bw3D = 0; + } + if (tmp_win->mwmhints.flags & MWM_HINTS_FUNCTIONS) + if (tmp_win->mwmhints.functions & MWM_FUNC_ALL) + tmp_win->mwmhints.functions |= (MWM_FUNC_RESIZE | + MWM_FUNC_MOVE | MWM_FUNC_MINIMIZE | + MWM_FUNC_MAXIMIZE | MWM_FUNC_CLOSE); + + bw2 = tmp_win->frame_bw * 2; + + /* moved MakeTitle under NoTitle - djhjr - 10/20/01 */ + tmp_win->title_height = Scr->TitleHeight + tmp_win->frame_bw; + + /* submitted by Jonathan Paisley 11/8/02 */ + if (tmp_win->mwmhints.flags & MWM_HINTS_DECORATIONS && + !(tmp_win->mwmhints.decorations & MWM_DECOR_TITLE)) + tmp_win->title_height = 0; + + if (Scr->NoTitlebar) + tmp_win->title_height = 0; + if (LookInList(Scr->NoTitle, tmp_win->full_name, &tmp_win->class)) + tmp_win->title_height = 0; + if (LookInList(Scr->MakeTitle, tmp_win->full_name, &tmp_win->class)) + tmp_win->title_height = Scr->TitleHeight + tmp_win->frame_bw; + + /* djhjr - 4/7/98 */ + if (LookInList(Scr->OpaqueMoveL, tmp_win->full_name, &tmp_win->class)) + tmp_win->opaque_move = TRUE; + else + tmp_win->opaque_move = Scr->OpaqueMove && +/* djhjr - 4/22/98 + !(short)(int)LookInList(Scr->NoOpaqueMoveL, tmp_win->full_name, &tmp_win->class); +*/ + (LookInList(Scr->NoOpaqueMoveL, tmp_win->full_name, + &tmp_win->class) == (char *)NULL); + + /* djhjr - 9/21/99 */ + if (tmp_win->opaque_move) tmp_win->attr.save_under = True; + + /* djhjr - 4/7/98 */ + if (LookInList(Scr->OpaqueResizeL, tmp_win->full_name, &tmp_win->class)) + tmp_win->opaque_resize = TRUE; + else + tmp_win->opaque_resize = Scr->OpaqueResize && +/* djhjr - 4/22/98 + !(short)(int)LookInList(Scr->NoOpaqueResizeL, tmp_win->full_name, &tmp_win->class); +*/ + (LookInList(Scr->NoOpaqueResizeL, tmp_win->full_name, + &tmp_win->class) == (char *)NULL); + + /* djhjr - 9/21/99 */ + if (tmp_win->opaque_resize) tmp_win->attr.save_under = True; + + /* if it is a transient window, don't put a title on it */ + if (tmp_win->transient && !Scr->DecorateTransients) + tmp_win->title_height = 0; + + if (LookInList(Scr->StartIconified, tmp_win->full_name, &tmp_win->class)) + { + if (!tmp_win->wmhints) + { + tmp_win->wmhints = (XWMHints *)malloc(sizeof(XWMHints)); + tmp_win->wmhints->flags = 0; + } + tmp_win->wmhints->initial_state = IconicState; + tmp_win->wmhints->flags |= StateHint; + } + + GetWindowSizeHints (tmp_win); + GetGravityOffsets (tmp_win, &gravx, &gravy); + + /* + * Don't bother user if: + * + * o the window is a transient, or + * + * o a USPosition was requested, or + * + * o a PPosition was requested and UsePPosition is ON or + * NON_ZERO if the window is at other than (0,0) + */ + + /* djhjr - 9/24/02 */ + if ((ppos_ptr = (int *)LookInList(Scr->UsePPositionL, + tmp_win->full_name, &tmp_win->class))) + ppos_on = *ppos_ptr; + else + ppos_on = Scr->UsePPosition; + if (ppos_on == PPOS_NON_ZERO && + (tmp_win->attr.x != 0 || tmp_win->attr.y != 0)) + ppos_on = PPOS_ON; + + ask_user = TRUE; + if (tmp_win->transient || + (tmp_win->hints.flags & USPosition) || + ((tmp_win->hints.flags & PPosition) && ppos_on == PPOS_ON)) + ask_user = FALSE; + + /* check for applet regions - djhjr - 4/26/99 */ + if (PlaceApplet(tmp_win, tmp_win->attr.x, tmp_win->attr.y, + &tmp_win->attr.x, &tmp_win->attr.y)) + ask_user = FALSE; + + if (LookInList(Scr->NailedDown, tmp_win->full_name, &tmp_win->class)) + tmp_win->nailed = TRUE; + else + tmp_win->nailed = FALSE; + + /* + * 25/09/90 - Nailed windows should always be on the real screen, + * regardless of PPosition or UPosition. If we are dealing with + * PPosition, then offset by the current real screen offset on the vd. + */ + if (tmp_win->nailed || + ((tmp_win->hints.flags & PPosition) && (ask_user == FALSE))) { + tmp_win->attr.x = R_TO_V_X(tmp_win->attr.x); + tmp_win->attr.y = R_TO_V_Y(tmp_win->attr.y); + } + +/* moved to after window prep and creation - djhjr - 4/14/98 + AddMoveAndResize(tmp_win, ask_user); +*/ + + if (!Scr->ClientBorderWidth) { /* need to adjust for twm borders */ + +/* djhjr - 4/19/96 + int delta = tmp_win->attr.border_width - tmp_win->frame_bw; +*/ +/* submitted by Jonathan Paisley - 11/8/02 + int delta = tmp_win->attr.border_width - tmp_win->frame_bw - tmp_win->frame_bw3D; +*/ + int delta = -(tmp_win->frame_bw + tmp_win->frame_bw3D); + + tmp_win->attr.x += gravx * delta; + tmp_win->attr.y += gravy * delta; + } + + /* + * For windows with specified non-northwest gravities. + * Submitted by Jonathan Paisley - 11/8/02 + */ + if (tmp_win->old_bw) { + if (!Scr->ClientBorderWidth) { + JunkX = gravx + 1; + JunkY = gravy + 1; + } else + JunkX = JunkY = 1; + + tmp_win->attr.x += JunkX * tmp_win->old_bw; + tmp_win->attr.y += JunkY * tmp_win->old_bw; + } + + tmp_win->title_width = tmp_win->attr.width; + + if (tmp_win->old_bw) XSetWindowBorderWidth (dpy, tmp_win->w, 0); + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + tmp_win->name_width = MyFont_TextWidth(&Scr->TitleBarFont, +#else + tmp_win->name_width = XTextWidth(Scr->TitleBarFont.font, +#endif + tmp_win->name, namelen); + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + if (!I18N_GetIconName(dpy, tmp_win->w, &icon_name)) +#else + /* used to be a simple boolean test for success - djhjr - 1/10/98 */ + if (XGetWindowProperty (dpy, tmp_win->w, XA_WM_ICON_NAME, 0L, 200L, False, + XA_STRING, &actual_type, &actual_format, &nitems, &bytesafter, + +/* see that the icon name is it's own memory - djhjr - 2/20/99 + (unsigned char **)&tmp_win->icon_name) != Success || actual_type == None) + tmp_win->icon_name = tmp_win->name; +*/ + (unsigned char **)&icon_name) != Success || actual_type == None) +#endif + tmp_win->icon_name = strdup(tmp_win->name); + else + { + tmp_win->icon_name = strdup(icon_name); +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + free(icon_name); +#else + XFree(icon_name); +#endif + } + +/* redundant? - djhjr - 1/10/98 + if (tmp_win->icon_name == NULL) + tmp_win->icon_name = tmp_win->name; +*/ + + tmp_win->iconified = FALSE; + tmp_win->icon = FALSE; + tmp_win->icon_on = FALSE; + + XGrabServer(dpy); + + /* + * Make sure the client window still exists. We don't want to leave an + * orphan frame window if it doesn't. Since we now have the server + * grabbed, the window can't disappear later without having been + * reparented, so we'll get a DestroyNotify for it. We won't have + * gotten one for anything up to here, however. + */ + if (XGetGeometry(dpy, tmp_win->w, &JunkRoot, &JunkX, &JunkY, + &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0) + { + free((char *)tmp_win); + XUngrabServer(dpy); + return(NULL); + } + + /* add the window into the twm list */ + tmp_win->next = Scr->TwmRoot.next; + if (Scr->TwmRoot.next != NULL) + Scr->TwmRoot.next->prev = tmp_win; + tmp_win->prev = &Scr->TwmRoot; + Scr->TwmRoot.next = tmp_win; + + /* get all the colors for the window */ + +/* djhjr - 4/25/96 + tmp_win->border = Scr->BorderColor; +*/ + tmp_win->border.back = Scr->BorderColor; + + tmp_win->icon_border = Scr->IconBorderColor; + tmp_win->border_tile.fore = Scr->BorderTileC.fore; + tmp_win->border_tile.back = Scr->BorderTileC.back; + tmp_win->title.fore = Scr->TitleC.fore; + tmp_win->title.back = Scr->TitleC.back; + tmp_win->iconc.fore = Scr->IconC.fore; + tmp_win->iconc.back = Scr->IconC.back; + tmp_win->virtual.fore = Scr->VirtualDesktopDisplayC.fore; + tmp_win->virtual.back = Scr->VirtualDesktopDisplayC.back; + +/* djhjr - 4/25/96 + GetColorFromList(Scr->BorderColorL, tmp_win->full_name, &tmp_win->class, + &tmp_win->border); +*/ + GetColorFromList(Scr->BorderColorL, tmp_win->full_name, &tmp_win->class, + &tmp_win->border.back); + + GetColorFromList(Scr->IconBorderColorL, tmp_win->full_name, &tmp_win->class, + &tmp_win->icon_border); + GetColorFromList(Scr->BorderTileForegroundL, tmp_win->full_name, + &tmp_win->class, &tmp_win->border_tile.fore); + GetColorFromList(Scr->BorderTileBackgroundL, tmp_win->full_name, + &tmp_win->class, &tmp_win->border_tile.back); + GetColorFromList(Scr->TitleForegroundL, tmp_win->full_name, &tmp_win->class, + &tmp_win->title.fore); + GetColorFromList(Scr->TitleBackgroundL, tmp_win->full_name, &tmp_win->class, + &tmp_win->title.back); + GetColorFromList(Scr->IconForegroundL, tmp_win->full_name, &tmp_win->class, + &tmp_win->iconc.fore); + GetColorFromList(Scr->IconBackgroundL, tmp_win->full_name, &tmp_win->class, + &tmp_win->iconc.back); + +/* fixed transposed fallback fore and back color lists - djhjr - 9/25/01 */ + if (!GetColorFromList(Scr->VirtualDesktopColorFL, tmp_win->full_name, + &tmp_win->class, &tmp_win->virtual.fore)) + GetColorFromList(Scr->TitleForegroundL, tmp_win->full_name, + &tmp_win->class, &tmp_win->virtual.fore); + if (!GetColorFromList(Scr->VirtualDesktopColorBL, tmp_win->full_name, + &tmp_win->class, &tmp_win->virtual.back)) + GetColorFromList(Scr->TitleBackgroundL, tmp_win->full_name, + &tmp_win->class, &tmp_win->virtual.back); + + /* djhjr - 4/19/96 */ + /* loosened up for titlebar-colored 3D buttons - djhjr - 4/1/98 + if (Scr->use3Dtitles && !Scr->BeNiceToColormap) + */ + if (!Scr->BeNiceToColormap) + GetShadeColors (&tmp_win->title); + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + /* rearranged the parenthesis - djhjr - 10/30/02 */ + if ((Scr->ButtonColorIsFrame || Scr->BorderBevelWidth > 0) && !Scr->BeNiceToColormap) + { + GetShadeColors (&tmp_win->border); + GetShadeColors (&tmp_win->border_tile); + } + + /* create windows */ + +/* djhjr - 4/19/96 + tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->frame_bw; + tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height + + tmp_win->old_bw - tmp_win->frame_bw; + tmp_win->frame_width = tmp_win->attr.width; + tmp_win->frame_height = tmp_win->attr.height + tmp_win->title_height; +*/ +/* done in AddMoveAndResize() - djhjr - 4/14/98 + tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->frame_bw + - tmp_win->frame_bw3D; + tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height + + tmp_win->old_bw - tmp_win->frame_bw - tmp_win->frame_bw3D; +*/ + tmp_win->frame_width = tmp_win->attr.width + 2 * tmp_win->frame_bw3D; + tmp_win->frame_height = tmp_win->attr.height + tmp_win->title_height + + 2 * tmp_win->frame_bw3D; +/* done in AddMoveAndResize() - djhjr - 4/14/98 + ConstrainSize (tmp_win, &tmp_win->frame_width, &tmp_win->frame_height); + + tmp_win->virtual_frame_x = R_TO_V_X(tmp_win->frame_x); + tmp_win->virtual_frame_y = R_TO_V_Y(tmp_win->frame_y); +*/ + +/* djhjr - 4/19/96 + valuemask = CWBackPixmap | CWBorderPixel | CWCursor | CWEventMask; + attributes.background_pixmap = None; + attributes.border_pixel = tmp_win->border; + attributes.cursor = Scr->FrameCursor; + attributes.event_mask = (SubstructureRedirectMask | + ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask); + if (tmp_win->attr.save_under) { + attributes.save_under = True; + valuemask |= CWSaveUnder; + } +*/ +/* djhjr - 9/14/96 + valuemask = CWBackPixmap | CWBorderPixel | CWCursor | CWEventMask | CWBackPixel; + attributes.background_pixmap = None; +*/ + valuemask = CWBorderPixel | CWCursor | CWEventMask | CWBackPixel; + + attributes.background_pixel = tmp_win->border.back; + attributes.border_pixel = tmp_win->border.back; + attributes.cursor = Scr->FrameCursor; + attributes.event_mask = (SubstructureRedirectMask | + ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask | ExposureMask); + if (tmp_win->attr.save_under) { + attributes.save_under = True; + valuemask |= CWSaveUnder; + } + + /* djhjr - 9/17/96 - slows down iconify/delete/destroy too much... + if (Scr->BackingStore) + { + attributes.backing_store = WhenMapped; + valuemask |= CWBackingStore; + } + */ + + if (tmp_win->hints.flags & PWinGravity) { + attributes.win_gravity = tmp_win->hints.win_gravity; + valuemask |= CWWinGravity; + } + + tmp_win->frame = XCreateWindow (dpy, Scr->Root, tmp_win->frame_x, + tmp_win->frame_y, + (unsigned int) tmp_win->frame_width, + (unsigned int) tmp_win->frame_height, + (unsigned int) tmp_win->frame_bw, + Scr->d_depth, + (unsigned int) CopyFromParent, + Scr->d_visual, valuemask, &attributes); + + if (tmp_win->title_height) + { + valuemask = (CWEventMask | CWBorderPixel | CWBackPixel); + attributes.event_mask = (KeyPressMask | ButtonPressMask | + ButtonReleaseMask | ExposureMask); +/* djhjr - 4/19/96 + attributes.border_pixel = tmp_win->border; +*/ + attributes.border_pixel = tmp_win->title.back; + attributes.background_pixel = tmp_win->title.back; + + /* djhjr - 9/17/96 */ + if (Scr->BackingStore) + { + attributes.backing_store = WhenMapped; + valuemask |= CWBackingStore; + } + + tmp_win->title_w = XCreateWindow (dpy, tmp_win->frame, +/* djhjr - 4/19/96 + -tmp_win->frame_bw, + -tmp_win->frame_bw, +*/ + tmp_win->frame_bw3D - tmp_win->frame_bw, + tmp_win->frame_bw3D - tmp_win->frame_bw, + + (unsigned int) tmp_win->attr.width, + (unsigned int) Scr->TitleHeight, + (unsigned int) tmp_win->frame_bw, + Scr->d_depth, + (unsigned int) CopyFromParent, + Scr->d_visual, valuemask, + &attributes); + } + else { + tmp_win->title_w = 0; + tmp_win->squeeze_info = NULL; + } + + if (tmp_win->highlight) + { + + /* djhjr - 4/19/96 */ + /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */ + if (Scr->TitleBevelWidth > 0 && (Scr->Monochrome != COLOR)) + tmp_win->gray = XCreatePixmapFromBitmapData(dpy, Scr->Root, + (char *)black_bits, gray_width, gray_height, + tmp_win->border_tile.fore, tmp_win->border_tile.back, + Scr->d_depth); + else + + tmp_win->gray = XCreatePixmapFromBitmapData(dpy, Scr->Root, + gray_bits, gray_width, gray_height, + tmp_win->border_tile.fore, tmp_win->border_tile.back, + Scr->d_depth); + + SetBorder (tmp_win, False); + } + else + tmp_win->gray = None; + + if (tmp_win->title_w) { + CreateWindowTitlebarButtons (tmp_win); + ComputeTitleLocation (tmp_win); + XMoveWindow (dpy, tmp_win->title_w, + tmp_win->title_x, tmp_win->title_y); + XDefineCursor(dpy, tmp_win->title_w, Scr->TitleCursor); + } + + /* djhjr - 4/19/96 */ + else { + tmp_win->title_x = tmp_win->frame_bw3D - tmp_win->frame_bw; + tmp_win->title_y = tmp_win->frame_bw3D - tmp_win->frame_bw; + } + + valuemask = (CWEventMask | CWDontPropagate); + attributes.event_mask = (StructureNotifyMask | PropertyChangeMask | + ColormapChangeMask | VisibilityChangeMask | + EnterWindowMask | LeaveWindowMask); + attributes.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask; + XChangeWindowAttributes (dpy, tmp_win->w, valuemask, &attributes); + + if (HasShape) + XShapeSelectInput (dpy, tmp_win->w, ShapeNotifyMask); + + if (tmp_win->title_w) { + XMapWindow (dpy, tmp_win->title_w); + } + + if (HasShape) { + int xws, yws, xbs, ybs; + unsigned wws, hws, wbs, hbs; + int boundingShaped, clipShaped; + + XShapeSelectInput (dpy, tmp_win->w, ShapeNotifyMask); + XShapeQueryExtents (dpy, tmp_win->w, + &boundingShaped, &xws, &yws, &wws, &hws, + &clipShaped, &xbs, &ybs, &wbs, &hbs); + tmp_win->wShaped = boundingShaped; + } + + if (!tmp_win->iconmgr) + XAddToSaveSet(dpy, tmp_win->w); + +/* djhjr - 4/19/96 + XReparentWindow(dpy, tmp_win->w, tmp_win->frame, 0, tmp_win->title_height); +*/ + XReparentWindow(dpy, tmp_win->w, tmp_win->frame, tmp_win->frame_bw3D, + tmp_win->title_height + tmp_win->frame_bw3D); + + /* + * Reparenting generates an UnmapNotify event, followed by a MapNotify. + * Set the map state to FALSE to prevent a transition back to + * WithdrawnState in HandleUnmapNotify. Map state gets set correctly + * again in HandleMapNotify. + */ + tmp_win->mapped = FALSE; + + /* + * NOW do the move and resize - windows needed to be created + * first to accomodate the opaque resources - djhjr - 4/14/98 + */ + AddMoveAndResize(tmp_win, ask_user); + + SetupFrame (tmp_win, tmp_win->frame_x, tmp_win->frame_y, + tmp_win->frame_width, tmp_win->frame_height, -1, True); + + /* wait until the window is iconified and the icon window is mapped + * before creating the icon window + */ + tmp_win->icon_w = None; + + if (!tmp_win->iconmgr) + { + GrabButtons(tmp_win); + GrabKeys(tmp_win); + } + + (void) AddIconManager(tmp_win); + UpdateDesktop(tmp_win); + + XSaveContext(dpy, tmp_win->w, TwmContext, (caddr_t) tmp_win); + XSaveContext(dpy, tmp_win->w, ScreenContext, (caddr_t) Scr); + XSaveContext(dpy, tmp_win->frame, TwmContext, (caddr_t) tmp_win); + XSaveContext(dpy, tmp_win->frame, ScreenContext, (caddr_t) Scr); + if (tmp_win->title_height) + { + int i; + int nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; + + XSaveContext(dpy, tmp_win->title_w, TwmContext, (caddr_t) tmp_win); + XSaveContext(dpy, tmp_win->title_w, ScreenContext, (caddr_t) Scr); + for (i = 0; i < nb; i++) { + XSaveContext(dpy, tmp_win->titlebuttons[i].window, TwmContext, + (caddr_t) tmp_win); + XSaveContext(dpy, tmp_win->titlebuttons[i].window, ScreenContext, + (caddr_t) Scr); + } + if (tmp_win->hilite_w) + { + XSaveContext(dpy, tmp_win->hilite_w, TwmContext, (caddr_t)tmp_win); + XSaveContext(dpy, tmp_win->hilite_w, ScreenContext, (caddr_t)Scr); + } + } + + XUngrabServer(dpy); + + /* if we were in the middle of a menu activated function, regrab + * the pointer + */ + if (RootFunction != F_NOFUNCTION) + ReGrab(); + + Scr->Newest = tmp_win; /* PF */ + if (tmp_win->transient && Scr->WarpToTransients) /* PF */ + WarpToWindow(tmp_win); /* PF,DSE */ + + return (tmp_win); +} + + +/* + * AddPaintRealWindows() + * + * a little helper for AddMoveAndResize() - djhjr - 4/15/98 + */ +static void +AddPaintRealWindows(tmp_win, x, y) +TwmWindow *tmp_win; +int x, y; +{ +/* handled in add_window() now - djhjr - 9/21/99 + XSetWindowAttributes attr; + + attr.save_under = True; + XChangeWindowAttributes(dpy, tmp_win->frame, CWSaveUnder, &attr); +*/ + + /* don't need to send a configure notify event */ + SetupWindow(tmp_win, tmp_win->frame_x, tmp_win->frame_y, + tmp_win->frame_width, tmp_win->frame_height, -1); + + XMoveWindow(dpy, tmp_win->frame, x, y); + + XMapWindow(dpy, tmp_win->frame); + XMapSubwindows(dpy, tmp_win->frame); + XMapSubwindows(dpy, tmp_win->title_w); + + PaintBorderAndTitlebar(tmp_win); + + /* djhjr - 4/15/98 */ + if (!Scr->NoGrabServer) + { + /* these allow the application window to be drawn */ + XUngrabServer(dpy); XSync(dpy, 0); XGrabServer(dpy); + } +} + + +/* + * AddMoveAndResize() + * + * was inline in AddWindow() at first call to this function, + * now handles the opaque move and resize resources - djhjr - 4/14/98 + */ +static void +AddMoveAndResize(tmp_win, ask_user) +TwmWindow *tmp_win; +int ask_user; +{ + static int PlaceX = PLACEMENT_START; + static int PlaceY = PLACEMENT_START; + XEvent event; + int stat, gravx, gravy; + int bw2 = tmp_win->frame_bw * 2; + int wd = tmp_win->attr.width + bw2; + int ht = tmp_win->attr.height + tmp_win->title_height + bw2; + + /* + * do any prompting for position + */ + if (HandlingEvents && ask_user) { + if (Scr->RandomPlacement) { /* just stick it somewhere */ + if (PlaceX + wd > Scr->MyDisplayWidth) { + /* submitted by Seth Robertson - 8/25/02 */ + if (PLACEMENT_START + wd < Scr->MyDisplayWidth) + PlaceX = PLACEMENT_START; + else { + PlaceX = tmp_win->frame_bw; + if (wd < Scr->MyDisplayWidth) + PlaceX += (Scr->MyDisplayWidth - wd) / 2; + } + } + if (PlaceY + ht > Scr->MyDisplayHeight) { + /* submitted by Seth Robertson - 8/25/02 */ + if (PLACEMENT_START + ht < Scr->MyDisplayHeight) + PlaceY = PLACEMENT_START; + else { + PlaceY = tmp_win->title_height + tmp_win->frame_bw; + if (ht < Scr->MyDisplayHeight) + PlaceY += (Scr->MyDisplayHeight - ht) / 2; + } + } + + tmp_win->attr.x = PlaceX; + tmp_win->attr.y = PlaceY; + PlaceX += PLACEMENT_INCR; + PlaceY += PLACEMENT_INCR; + } else if (Scr->PointerPlacement) { + /* find pointer */ + if (!XQueryPointer (dpy, Scr->Root, &JunkRoot, + &JunkChild, &JunkX, &JunkY, + &AddingX, &AddingY, &JunkMask)) + JunkMask = 0; + /* fit window onto screen */ + if (Scr->WarpSnug) { + if (JunkX + wd > Scr->MyDisplayWidth) + JunkX -= (JunkX + wd - Scr->MyDisplayWidth); + if (JunkY + tmp_win->attr.height > Scr->MyDisplayHeight) + JunkY -= (JunkY + tmp_win->attr.height - Scr->MyDisplayHeight); + } + tmp_win->attr.x = JunkX; + tmp_win->attr.y = JunkY; + } else { /* else prompt */ + if (!(tmp_win->wmhints && tmp_win->wmhints->flags & StateHint && + tmp_win->wmhints->initial_state == IconicState)) + { + Bool firsttime = True; + + /* djhjr - 11/15/01 */ + Bool doorismapped = False; + TwmDoor *door = NULL; + XFindContext(dpy, tmp_win->w, DoorContext, (caddr_t *)&door); + + /* better wait until all the mouse buttons have been + * released. + */ + while (TRUE) + { + XUngrabServer(dpy); + XSync(dpy, 0); + XGrabServer(dpy); + + JunkMask = 0; + if (!XQueryPointer (dpy, Scr->Root, &JunkRoot, + &JunkChild, &JunkX, &JunkY, + &AddingX, &AddingY, &JunkMask)) + JunkMask = 0; + + JunkMask &= (Button1Mask | Button2Mask | Button3Mask | + Button4Mask | Button5Mask); + + /* + * watch out for changing screens + */ + if (firsttime) { + if (JunkRoot != Scr->Root) { + register int scrnum; + + for (scrnum = 0; scrnum < NumScreens; scrnum++) { + if (JunkRoot == RootWindow (dpy, scrnum)) break; + } + + if (scrnum != NumScreens) PreviousScreen = scrnum; + } + firsttime = False; + } + + /* + * wait for buttons to come up; yuck + */ + if (JunkMask != 0) continue; + + /* + * this will cause a warp to the indicated root + */ + stat = XGrabPointer(dpy, Scr->Root, False, + ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | PointerMotionHintMask, + GrabModeAsync, GrabModeAsync, + Scr->Root, UpperLeftCursor, CurrentTime); + + if (stat == GrabSuccess) + break; + } + + /* djhjr - 4/15/98 */ + if (Scr->NoGrabServer) XUngrabServer(dpy); + +/* use initialized size... djhjr - 5/9/96 +* djhjr - 9/14/03 * +#ifndef NO_I18N_SUPPORT + width = (SIZE_HINDENT + MyFont_TextWidth (&Scr->SizeFont, +#else + width = (SIZE_HINDENT + XTextWidth (Scr->SizeFont.font, +#endif + tmp_win->name, namelen)); + height = Scr->SizeFont.height + SIZE_VINDENT * 2; + +* djhjr - 4/27/96 + XResizeWindow (dpy, Scr->SizeWindow, width + SIZE_HINDENT, height); +* + XResizeWindow (dpy, Scr->SizeWindow, Scr->SizeStringOffset + + Scr->SizeStringWidth, height); +*/ + + XMapRaised(dpy, Scr->SizeWindow); + InstallRootColormap(); + +/* DisplayPosition overwrites it anyway... djhjr - 5/9/96 + * font was font.font->fid - djhjr - 9/14/03 * + FBF(Scr->DefaultC.fore, Scr->DefaultC.back, Scr->SizeFont); +* djhjr - 9/14/03 * +#ifndef NO_I18N_SUPPORT + MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont, +#else + XDrawImageString (dpy, Scr->SizeWindow, +#endif + Scr->NormalGC, SIZE_HINDENT, +* djhjr - 9/14/03 + SIZE_VINDENT + Scr->SizeFont.font->ascent, +* + SIZE_VINDENT + Scr->SizeFont.ascent, + tmp_win->name, namelen); +*/ + +/* djhjr - 4/19/96 + AddingW = tmp_win->attr.width + bw2; + AddingH = tmp_win->attr.height + tmp_win->title_height + bw2; + + MoveOutline(Scr->Root, AddingX, AddingY, AddingW, AddingH, + tmp_win->frame_bw, tmp_win->title_height); +*/ + AddingW = tmp_win->attr.width + bw2 + 2 * tmp_win->frame_bw3D; + AddingH = tmp_win->attr.height + tmp_win->title_height + + bw2 + 2 * tmp_win->frame_bw3D; + + /* added this 'if ... else' - djhjr - 4/14/98 */ + if (tmp_win->opaque_move) + { + AddPaintRealWindows(tmp_win, AddingX, AddingY); + + /* djhjr - 11/15/01 */ + if (door && !doorismapped) + { + XMapWindow(dpy, door->w); + RedoDoorName(tmp_win, door); + doorismapped = True; + } + } + else + MoveOutline(Scr->Root, AddingX, AddingY, AddingW, AddingH, + tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); + + /* djhjr - 4/17/98 */ + if (Scr->VirtualReceivesMotionEvents) + { + tmp_win->virtual_frame_x = R_TO_V_X(AddingX); + tmp_win->virtual_frame_y = R_TO_V_Y(AddingY); + UpdateDesktop(tmp_win); + } + +/* DisplayPosition() overwrites it anyway... djhjr - 5/9/96 +* djhjr - 9/14/03 * +#ifndef NO_I18N_SUPPORT + MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont, +#else + * djhjr - 4/27/96 * + XDrawImageString (dpy, Scr->SizeWindow, +#endif + Scr->NormalGC, width, +* djhjr - 9/14/03 + SIZE_VINDENT + Scr->SizeFont.font->ascent, ": ", 2); +* + SIZE_VINDENT + Scr->SizeFont.ascent, ": ", 2); +*/ + + /* djhjr - 4/27/96 */ + DisplayPosition (AddingX, AddingY); + + while (TRUE) + { + XMaskEvent(dpy, ButtonPressMask | PointerMotionMask, &event); + + if (Event.type == MotionNotify) { + /* discard any extra motion events before a release */ + while(XCheckMaskEvent(dpy, + ButtonMotionMask | ButtonPressMask, &Event)) + if (Event.type == ButtonPress) + break; + } + + if (event.type == ButtonPress) { + AddingX = event.xbutton.x_root; + AddingY = event.xbutton.y_root; + + /* DontMoveOff prohibits user form off-screen placement */ + if (Scr->DontMoveOff) + { + int AddingR, AddingB; + + AddingR = AddingX + AddingW; + AddingB = AddingY + AddingH; + + if (AddingX < 0) + AddingX = 0; + if (AddingR > Scr->MyDisplayWidth) + AddingX = Scr->MyDisplayWidth - AddingW; + + if (AddingY < 0) + AddingY = 0; + if (AddingB > Scr->MyDisplayHeight) + AddingY = Scr->MyDisplayHeight - AddingH; + + } + break; + } + + if (event.type != MotionNotify) { + continue; + } + + XQueryPointer(dpy, Scr->Root, &JunkRoot, &JunkChild, + &JunkX, &JunkY, &AddingX, &AddingY, &JunkMask); + + if (Scr->DontMoveOff) + { + int AddingR, AddingB; + + AddingR = AddingX + AddingW; + AddingB = AddingY + AddingH; + + if (AddingX < 0) + AddingX = 0; + if (AddingR > Scr->MyDisplayWidth) + AddingX = Scr->MyDisplayWidth - AddingW; + + if (AddingY < 0) + AddingY = 0; + if (AddingB > Scr->MyDisplayHeight) + AddingY = Scr->MyDisplayHeight - AddingH; + } + +/* djhjr - 4/19/96 + MoveOutline(Scr->Root, AddingX, AddingY, AddingW, AddingH, + tmp_win->frame_bw, tmp_win->title_height); +*/ + /* added this 'if ... else' - djhjr - 4/14/98 */ + if (tmp_win->opaque_move) + { + XMoveWindow(dpy, tmp_win->frame, AddingX, AddingY); + PaintBorderAndTitlebar(tmp_win); + + /* djhjr - 4/15/98 */ + if (!Scr->NoGrabServer) + { + /* these allow the application window to be drawn */ + XUngrabServer(dpy); XSync(dpy, 0); XGrabServer(dpy); + } + } + else + MoveOutline(Scr->Root, AddingX, AddingY, AddingW, AddingH, + tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); + + /* djhjr - 4/17/98 */ + if (Scr->VirtualReceivesMotionEvents) + { + tmp_win->virtual_frame_x = R_TO_V_X(AddingX); + tmp_win->virtual_frame_y = R_TO_V_Y(AddingY); + MoveResizeDesktop(tmp_win, Scr->NoRaiseResize); + } + + /* djhjr - 4/27/96 */ + DisplayPosition (AddingX, AddingY); + + } + + if (event.xbutton.button == Button2) { + int lastx, lasty; + +/* AddStartResize() overwrites it anyway... djhjr - 5/9/96 + Scr->SizeStringOffset = width + +* djhjr - 9/14/03 * +#ifndef NO_I18N_SUPPORT + MyFont_TextWidth(&Scr->SizeFont, ": ", 2); +#else + XTextWidth(Scr->SizeFont.font, ": ", 2); +#endif + XResizeWindow (dpy, Scr->SizeWindow, Scr->SizeStringOffset + + Scr->SizeStringWidth, height); +* djhjr - 9/14/03 * +#ifndef NO_I18N_SUPPORT + MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont, +#else + XDrawImageString (dpy, Scr->SizeWindow, +#endif + Scr->NormalGC, width, +* djhjr - 9/14/03 + SIZE_VINDENT + Scr->SizeFont.font->ascent, +* + SIZE_VINDENT + Scr->SizeFont.ascent, + ": ", 2); +*/ + + /* djhjr - 4/15/98 */ + if (!tmp_win->opaque_move && tmp_win->opaque_resize) + { + /* erase the move outline */ + MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); + + AddPaintRealWindows(tmp_win, AddingX, AddingY); + + /* djhjr - 11/15/01 */ + if (door && !doorismapped) + { + XMapWindow(dpy, door->w); + RedoDoorName(tmp_win, door); + doorismapped = True; + } + } + +#if 0 + if (0/*Scr->AutoRelativeResize*/) +My R5 vtvwm came with this commented out, always 0. +Why? +#endif + if (Scr->AutoRelativeResize) + { + int dx = (tmp_win->attr.width / 4); + int dy = (tmp_win->attr.height / 4); + +#define HALF_AVE_CURSOR_SIZE 8 /* so that it is visible */ + if (dx < HALF_AVE_CURSOR_SIZE) dx = HALF_AVE_CURSOR_SIZE; + if (dy < HALF_AVE_CURSOR_SIZE) dy = HALF_AVE_CURSOR_SIZE; +#undef HALF_AVE_CURSOR_SIZE + dx += (tmp_win->frame_bw + 1); + dy += (bw2 + tmp_win->title_height + 1); + if (AddingX + dx >= Scr->MyDisplayWidth) + dx = Scr->MyDisplayWidth - AddingX - 1; + if (AddingY + dy >= Scr->MyDisplayHeight) + dy = Scr->MyDisplayHeight - AddingY - 1; + if (dx > 0 && dy > 0) + XWarpPointer (dpy, None, None, 0, 0, 0, 0, dx, dy); + } else { + XWarpPointer (dpy, None, Scr->Root, 0, 0, 0, 0, + AddingX + AddingW/2, AddingY + AddingH/2); + } + AddStartResize(tmp_win, AddingX, AddingY, AddingW, AddingH); + + lastx = -10000; + lasty = -10000; + while (TRUE) + { + XMaskEvent(dpy, + ButtonReleaseMask | ButtonMotionMask, &event); + + if (Event.type == MotionNotify) { + /* discard any extra motion events before a release */ + while(XCheckMaskEvent(dpy, + ButtonMotionMask | ButtonReleaseMask, &Event)) + if (Event.type == ButtonRelease) + break; + } + + if (event.type == ButtonRelease) + { + AddEndResize(tmp_win); + + /* don't need to send a configure notify event - djhjr - 4/15/98 */ + if (tmp_win->opaque_move && !tmp_win->opaque_resize) + SetupWindow(tmp_win, AddingX, AddingY, AddingW, AddingH, -1); + + /* djhjr - 11/15/01 */ + if (!tmp_win->opaque_resize && door && doorismapped) + RedoDoorName(tmp_win, door); + + break; + } + + if (event.type != MotionNotify) { + continue; + } + + /* + * XXX - if we are going to do a loop, we ought to consider + * using multiple GXxor lines so that we don't need to + * grab the server. + */ + XQueryPointer(dpy, Scr->Root, &JunkRoot, &JunkChild, + &JunkX, &JunkY, &AddingX, &AddingY, &JunkMask); + + if (lastx != AddingX || lasty != AddingY) + { + DoResize(AddingX, AddingY, tmp_win); + + lastx = AddingX; + lasty = AddingY; + } + + } + } /* if (event.xbutton.button == Button2) */ + else if (event.xbutton.button == Button3) + { + int maxw = Scr->MyDisplayWidth - AddingX - bw2; + int maxh = Scr->MyDisplayHeight - AddingY - bw2; + + /* + * Make window go to bottom of screen, and clip to right edge. + * This is useful when popping up large windows and fixed + * column text windows. + */ + if (AddingW > maxw) AddingW = maxw; + AddingH = maxh; + + ConstrainSize (tmp_win, &AddingW, &AddingH); /* w/o borders */ + AddingW += bw2; + AddingH += bw2; + + /* don't need to send a configure notify event - djhjr - 4/15/98 */ + SetupWindow(tmp_win, AddingX, AddingY, AddingW, AddingH, -1); + + /* djhjr - 11/15/01 */ + if (!tmp_win->opaque_resize && door && doorismapped) + RedoDoorName(tmp_win, door); + + } + else + { + XMaskEvent(dpy, ButtonReleaseMask, &event); + } + + /* erase the move outline */ + MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); + + XUnmapWindow(dpy, Scr->SizeWindow); + UninstallRootColormap(); + XUngrabPointer(dpy, CurrentTime); + +/* djhjr - 4/15/98 + tmp_win->attr.x = AddingX; + tmp_win->attr.y = AddingY + tmp_win->title_height; +*/ + tmp_win->attr.x = AddingX + tmp_win->frame_bw + tmp_win->frame_bw3D; + tmp_win->attr.y = AddingY + tmp_win->title_height + + tmp_win->frame_bw + tmp_win->frame_bw3D; + +/* djhjr - 4/19/96 + tmp_win->attr.width = AddingW - bw2; + tmp_win->attr.height = AddingH - tmp_win->title_height - bw2; +*/ + tmp_win->attr.width = AddingW - bw2 - 2 * tmp_win->frame_bw3D; + tmp_win->attr.height = AddingH - tmp_win->title_height - + bw2 - 2 * tmp_win->frame_bw3D; + +/* un-grabbed in the caller AddWindow() on return - djhjr - 4/15/98 + XUngrabServer(dpy); +*/ + } + } + + /* djhjr - 6/4/98 */ + if (Scr->VirtualReceivesMotionEvents && !tmp_win->opaque_move) + { + XUnmapWindow(dpy, Scr->VirtualDesktopDisplay); + XMapWindow(dpy, Scr->VirtualDesktopDisplay); + } + } else { /* put it where asked, mod title bar */ + /* interpret the position specified as a virtual one if asked */ + +/* added 'FixManagedVirtualGeometries' - djhjr - 1/6/98 */ +/* added test for 'PPosition' - submitted by Michael Dales */ + if (Scr->GeometriesAreVirtual || + (!Scr->GeometriesAreVirtual && + (tmp_win->nailed || + ( ( (Scr->FixManagedVirtualGeometries && + !tmp_win->transient) || + (Scr->FixTransientVirtualGeometries && + tmp_win->transient) + ) && (tmp_win->hints.flags & PPosition) + ) + ) + ) + ) + /* + * If virtual geometries is set, or virtual geometries + * isn't set and (nailed or (fix virtual geometries and + * preferred position)). This is a bug workaround -- DSE + */ + { + tmp_win->attr.x = V_TO_R_X(tmp_win->attr.x); + tmp_win->attr.y = V_TO_R_Y(tmp_win->attr.y); + } + + GetGravityOffsets (tmp_win, &gravx, &gravy); + + /* if the gravity is towards the top, move it by the title height */ + if (gravy < 0) tmp_win->attr.y -= gravy * tmp_win->title_height; + } + +/* should never have been - djhjr - 9/21/99 + if (tmp_win->opaque_move) + { + XSetWindowAttributes attr; + + attr.save_under = False; + XChangeWindowAttributes(dpy, tmp_win->frame, CWSaveUnder, &attr); + } +*/ + +/* + * consider client borderwidths based on the ClientBorderWidth and + * RandomPlacement resources, PPosition with the UsePPosition resource, + * and the USPosition spec - djhjr - 6/3/98 + * + tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->frame_bw + - tmp_win->frame_bw3D; + tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height + + tmp_win->old_bw - tmp_win->frame_bw - tmp_win->frame_bw3D; +*/ + tmp_win->frame_x = tmp_win->attr.x - + tmp_win->frame_bw - tmp_win->frame_bw3D; + tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height - + tmp_win->frame_bw - tmp_win->frame_bw3D; +/* Not needed? - submitted by Jonathan Paisley - 11/8/02 + if (Scr->ClientBorderWidth || !ask_user) + { + tmp_win->frame_x += tmp_win->old_bw; + tmp_win->frame_y += tmp_win->old_bw; + } +*/ + + tmp_win->frame_width = tmp_win->attr.width + 2 * tmp_win->frame_bw3D; + tmp_win->frame_height = tmp_win->attr.height + tmp_win->title_height + + 2 * tmp_win->frame_bw3D; + ConstrainSize (tmp_win, &tmp_win->frame_width, &tmp_win->frame_height); + + tmp_win->virtual_frame_x = R_TO_V_X(tmp_win->frame_x); + tmp_win->virtual_frame_y = R_TO_V_Y(tmp_win->frame_y); + +#ifdef DEBUG + fprintf(stderr, " position window %d, %d %dx%d\n", + tmp_win->attr.x, + tmp_win->attr.y, + tmp_win->attr.width, + tmp_win->attr.height); +#endif +} + + +/*********************************************************************** + * + * Procedure: + * MappedNotOverride - checks to see if we should really + * put a twm frame on the window + * + * Returned Value: + * TRUE - go ahead and frame the window + * FALSE - don't frame the window + * + * Inputs: + * w - the window to check + * + *********************************************************************** + */ + +int +MappedNotOverride(w) + Window w; +{ + XWindowAttributes wa; + + XGetWindowAttributes(dpy, w, &wa); + return ((wa.map_state != IsUnmapped) && (wa.override_redirect != True)); +} + + +/*********************************************************************** + * + * Procedure: + * AddDefaultBindings - attach default bindings so that naive users + * don't get messed up if they provide a minimal twmrc. + */ +static void do_add_binding (button, context, modifier, func) + int button, context, modifier; + int func; +{ + MouseButton *mb = &Scr->Mouse[button][context][modifier]; + + if (mb->func) return; /* already defined */ + + mb->func = func; + mb->item = NULL; +} + +void AddDefaultBindings () +{ + /* + * The bindings are stored in Scr->Mouse, indexed by + * Mouse[button_number][C_context][modifier]. + */ + +#define NoModifierMask 0 + + do_add_binding (Button1, C_TITLE, NoModifierMask, F_MOVE); + do_add_binding (Button1, C_ICON, NoModifierMask, F_ICONIFY); + do_add_binding (Button1, C_ICONMGR, NoModifierMask, F_ICONIFY); + do_add_binding (Button1, C_VIRTUAL, NoModifierMask, F_MOVESCREEN); + do_add_binding (Button1, C_VIRTUAL_WIN, NoModifierMask, F_MOVESCREEN); + + do_add_binding (Button2, C_TITLE, NoModifierMask, F_RAISELOWER); + do_add_binding (Button2, C_ICON, NoModifierMask, F_ICONIFY); + do_add_binding (Button2, C_ICONMGR, NoModifierMask, F_ICONIFY); + do_add_binding (Button2, C_VIRTUAL, NoModifierMask, F_MOVESCREEN); + do_add_binding (Button2, C_VIRTUAL_WIN, NoModifierMask, F_MOVESCREEN); + +#undef NoModifierMask +} + + + + +/*********************************************************************** + * + * Procedure: + * GrabButtons - grab needed buttons for the window + * + * Inputs: + * tmp_win - the twm window structure to use + * + *********************************************************************** + */ + +void +GrabButtons(tmp_win) +TwmWindow *tmp_win; +{ + int i, j; + + for (i = 0; i < MAX_BUTTONS+1; i++) + { + for (j = 0; j < MOD_SIZE; j++) + { + if (Scr->Mouse[i][C_WINDOW][j].func != F_NOFUNCTION) + { + /* twm used to do this grab on the application main window, + * tmp_win->w . This was not ICCCM complient and was changed. + */ + XGrabButton(dpy, i, j, tmp_win->frame, + True, ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, None, + Scr->FrameCursor); + } + } + } +} + +/*********************************************************************** + * + * Procedure: + * GrabKeys - grab needed keys for the window + * + * Inputs: + * tmp_win - the twm window structure to use + * + *********************************************************************** + */ + +/* djhjr - 9/10/03 */ +void +GrabModKeys(w, k) +Window w; +FuncKey *k; +{ + int i; + + XGrabKey(dpy, k->keycode, k->mods, w, True, GrabModeAsync, GrabModeAsync); + + for (i = 1; i <= Scr->IgnoreModifiers; i++) + if ((Scr->IgnoreModifiers & i) == i) + XGrabKey(dpy, k->keycode, k->mods | i, w, True, + GrabModeAsync, GrabModeAsync); +} + +/* djhjr - 9/10/03 */ +void +UngrabModKeys(w, k) +Window w; +FuncKey *k; +{ + int i; + + XUngrabKey(dpy, k->keycode, k->mods, w); + + for (i = 1; i <= Scr->IgnoreModifiers; i++) + if ((Scr->IgnoreModifiers & i) == i) + XUngrabKey(dpy, k->keycode, k->mods | i, w); +} + +void +GrabKeys(tmp_win) +TwmWindow *tmp_win; +{ + FuncKey *tmp; + IconMgr *p; + + for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next) + { + switch (tmp->cont) + { + case C_WINDOW: +/* djhjr - 9/10/03 + XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->w, True, + GrabModeAsync, GrabModeAsync); +*/ + GrabModKeys(tmp_win->w, tmp); + break; + + case C_ICON: + if (tmp_win->icon_w) +/* djhjr - 9/10/03 + XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->icon_w, True, + GrabModeAsync, GrabModeAsync); +*/ + GrabModKeys(tmp_win->icon_w, tmp); + + case C_TITLE: + if (tmp_win->title_w) +/* djhjr - 9/10/03 + XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->title_w, True, + GrabModeAsync, GrabModeAsync); +*/ + GrabModKeys(tmp_win->title_w, tmp); + break; + + case C_NAME: +/* djhjr - 9/10/03 + XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->w, True, + GrabModeAsync, GrabModeAsync); +*/ + GrabModKeys(tmp_win->w, tmp); + if (tmp_win->icon_w) +/* djhjr - 9/10/03 + XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->icon_w, True, + GrabModeAsync, GrabModeAsync); +*/ + GrabModKeys(tmp_win->icon_w, tmp); + if (tmp_win->title_w) +/* djhjr - 9/10/03 + XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->title_w, True, + GrabModeAsync, GrabModeAsync); +*/ + GrabModKeys(tmp_win->title_w, tmp); + break; + + /* + case C_ROOT: +* djhjr - 9/10/03 + XGrabKey(dpy, tmp->keycode, tmp->mods, Scr->Root, True, + GrabModeAsync, GrabModeAsync); +* + GrabModKeys(Scr->Root, tmp); + break; + */ + } + } + for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next) + { + if (tmp->cont == C_ICONMGR && !Scr->NoIconManagers) + { + for (p = &Scr->iconmgr; p != NULL; p = p->next) + { +/* djhjr - 9/10/03 + XUngrabKey(dpy, tmp->keycode, tmp->mods, p->twm_win->w); +*/ + UngrabModKeys(p->twm_win->w, tmp); + } + } + } +} + +static Window CreateHighlightWindow (tmp_win) + TwmWindow *tmp_win; +{ + XSetWindowAttributes attributes; /* attributes for create windows */ + Pixmap pm = None; + GC gc; + XGCValues gcv; + unsigned long valuemask; + unsigned int pm_numcolors; + /* added '- 2' - djhjr - 10/18/02 */ + int h = (Scr->TitleHeight - 2 * Scr->FramePadding) - 2; + Window w; + +/* djhjr - 9/14/03 +#ifndef NO_I18N_SUPPORT + int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1); +#else + * djhjr - 4/1/98 * + int en = XTextWidth(Scr->TitleBarFont.font, "n", 1); +#endif +*/ +/* djhjr - 10/18/02 + int width = Scr->TBInfo.titlex + tmp_win->name_width + 2 * en; +*/ + + /* + * If a special highlight pixmap was given, use that. Otherwise, + * use a nice, even gray pattern. The old horizontal lines look really + * awful on interlaced monitors (as well as resembling other looks a + * little bit too closely), but can be used by putting + * + * Pixmaps { TitleHighlight "hline2" } + * + * (or whatever the horizontal line bitmap is named) in the startup + * file. If all else fails, use the foreground color to look like a + * solid line. + */ + +/* + * re-written to use an Image structure for XPM support + * + * djhjr - 5/17/98 + */ +#ifdef ORIGINAL_PIXMAPS + if (!Scr->hilitePm) { + + /* djhjr - 4/20/96 */ + /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */ + if (Scr->TitleBevelWidth > 0 && (Scr->Monochrome != COLOR)) + Scr->hilitePm = XCreateBitmapFromData (dpy, tmp_win->title_w, + (char *)black_bits, gray_width, gray_height); + else + Scr->hilitePm = XCreateBitmapFromData (dpy, tmp_win->title_w, + gray_bits, gray_width, gray_height); + + Scr->hilite_pm_width = gray_width; + Scr->hilite_pm_height = gray_height; + } + if (Scr->hilitePm) { + pm = XCreatePixmap (dpy, tmp_win->title_w, + Scr->hilite_pm_width, Scr->hilite_pm_height, + Scr->d_depth); + gcv.foreground = tmp_win->title.fore; + gcv.background = tmp_win->title.back; + gcv.graphics_exposures = False; + gc = XCreateGC (dpy, pm, + (GCForeground|GCBackground|GCGraphicsExposures), + &gcv); + if (gc) { + XCopyPlane (dpy, Scr->hilitePm, pm, gc, 0, 0, + Scr->hilite_pm_width, Scr->hilite_pm_height, + 0, 0, 1); + XFreeGC (dpy, gc); + } else { + XFreePixmap (dpy, pm); + pm = None; + } + } + if (pm) { + valuemask = CWBackPixmap; + attributes.background_pixmap = pm; + } else { + valuemask = CWBackPixel; + attributes.background_pixel = tmp_win->title.fore; + } +#else /* ORIGINAL_PIXMAPS */ + if (!Scr->hilitePm) + { + Scr->hilitePm = (Image *)malloc(sizeof(Image)); + if (Scr->hilitePm) + { + Scr->hilitePm->width = gray_width; + Scr->hilitePm->height = gray_height; + Scr->hilitePm->mask = None; + + /* djhjr - 4/20/96 */ + /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */ + if (Scr->TitleBevelWidth > 0 && (Scr->Monochrome != COLOR)) + Scr->hilitePm->pixmap = XCreateBitmapFromData (dpy, + tmp_win->title_w, (char *)black_bits, + Scr->hilitePm->width, Scr->hilitePm->height); + else + Scr->hilitePm->pixmap = XCreateBitmapFromData (dpy, + tmp_win->title_w, gray_bits, + Scr->hilitePm->width, Scr->hilitePm->height); + } + } + + pm_numcolors = 0; + +/* djhjr - 5/23/98 9/2/98 */ +#ifndef NO_XPM_SUPPORT +/* removed this for non-transparent pixmaps - djhjr - 5/26/98 + if (Scr->hilitePm->mask != None) +*/ + pm_numcolors = SetPixmapsBackground(Scr->hilitePm, Scr->Root, + tmp_win->title.back); +#endif + + /* + * Modified to handle non-transparent pixmaps - Jason Gloudon + */ + if (Scr->hilitePm->pixmap) + { + if (pm_numcolors > 2) /* not a bitmap */ + { + valuemask = CWBackPixmap; + attributes.background_pixmap = Scr->hilitePm->pixmap; + } + else + { + pm = XCreatePixmap (dpy, tmp_win->title_w, + Scr->hilitePm->width, Scr->hilitePm->height, + Scr->d_depth); + + gcv.foreground = tmp_win->title.fore; + gcv.background = tmp_win->title.back; + gcv.graphics_exposures = False; + + gc = XCreateGC (dpy, pm, + (GCForeground | GCBackground | GCGraphicsExposures), + &gcv); + + if (gc) + { + /* the copy plane works on color ! */ + XCopyPlane (dpy, Scr->hilitePm->pixmap, pm, gc, 0, 0, + Scr->hilitePm->width, Scr->hilitePm->height, + 0, 0, 1); + + XFreeGC(dpy, gc); + + valuemask = CWBackPixmap; + attributes.background_pixmap = pm; + } + else + { + valuemask = CWBackPixel; + attributes.background_pixel = tmp_win->title.fore; + } + } + } + else + { + valuemask = CWBackPixel; + attributes.background_pixel = tmp_win->title.fore; + } +#endif /* ORIGINAL_PIXMAPS */ + +/* djhjr - 10/18/02 */ +#if 0 + /* djhjr - 4/19/96 */ + /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */ + if (Scr->TitleBevelWidth > 0) +/* djhjr - 4/25/96 + w = XCreateWindow (dpy, tmp_win->title_w, 0, Scr->FramePadding + 2, + (unsigned int) Scr->TBInfo.width, (unsigned int) (h - 4), +*/ +/* djhjr - 4/1/98 + w = XCreateWindow (dpy, tmp_win->title_w, 0, Scr->FramePadding + 3, + (unsigned int) Scr->TBInfo.width, (unsigned int) (h - 6), +*/ + w = XCreateWindow (dpy, tmp_win->title_w, width, Scr->FramePadding + 4, + ComputeHighlightWindowWidth(tmp_win), (unsigned int) (h - 8), + + (unsigned int) 0, + Scr->d_depth, (unsigned int) CopyFromParent, + Scr->d_visual, valuemask, &attributes); + + else +/* djhjr - 4/1/98 + w = XCreateWindow (dpy, tmp_win->title_w, 0, Scr->FramePadding, + (unsigned int) Scr->TBInfo.width, (unsigned int) h, +*/ + w = XCreateWindow (dpy, tmp_win->title_w, width, Scr->FramePadding + 2, + ComputeHighlightWindowWidth(tmp_win), (unsigned int) (h - 4), + (unsigned int) 0, + Scr->d_depth, (unsigned int) CopyFromParent, + Scr->d_visual, valuemask, &attributes); +#else + w = XCreateWindow (dpy, tmp_win->title_w, + tmp_win->highlightx, Scr->FramePadding + 1, + ComputeHighlightWindowWidth(tmp_win), (unsigned int) h, + (unsigned int) 0, + Scr->d_depth, (unsigned int) CopyFromParent, + Scr->d_visual, valuemask, &attributes); +#endif + + if (pm) XFreePixmap (dpy, pm); + + return w; +} + + +void ComputeCommonTitleOffsets () +{ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1); +#else + /* djhjr - 10/18/02 */ + int en = XTextWidth(Scr->TitleBarFont.font, "n", 1); +#endif + + int buttonwidth = (Scr->TBInfo.width + Scr->TBInfo.pad); + + Scr->TBInfo.leftx = Scr->TBInfo.rightoff = Scr->FramePadding; + + if (Scr->TBInfo.nleft > 0) + Scr->TBInfo.leftx += Scr->ButtonIndent; + + /* 'en' was 'Scr->TitlePadding' - djhjr - 10/18/02 */ + Scr->TBInfo.titlex = (Scr->TBInfo.leftx + + (Scr->TBInfo.nleft * buttonwidth) - Scr->TBInfo.pad + + en); + + if (Scr->TBInfo.nright > 0) + Scr->TBInfo.rightoff += (Scr->ButtonIndent + + ((Scr->TBInfo.nright * buttonwidth) - + Scr->TBInfo.pad)); + return; +} + +void ComputeWindowTitleOffsets (tmp_win, width, squeeze) + TwmWindow *tmp_win; + int width; + Bool squeeze; +{ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1); +#else + /* djhjr - 10/18/02 */ + int en = XTextWidth(Scr->TitleBarFont.font, "n", 1); +#endif + + /* added 'en' - djhjr - 10/18/02 */ + tmp_win->highlightx = Scr->TBInfo.titlex + tmp_win->name_width + en; + +/* djhjr - 10/18/02 + * djhjr - 4/1/98 * + * was 'Scr->use3Dtitles' - djhjr - 8/11/98 * + if (Scr->TitleBevelWidth > 0) + { +* djhjr - 9/14/03 * +#ifndef NO_I18N_SUPPORT + int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1); +#else + int en = XTextWidth(Scr->TitleBarFont.font, "n", 1); +#endif + tmp_win->highlightx += en; + + * rem'd out - djhjr - 4/19/96 * + * reinstated - djhjr - 4/1/98 * + tmp_win->highlightx += 6; + } + + if (tmp_win->hilite_w || Scr->TBInfo.nright > 0) + tmp_win->highlightx += Scr->TitlePadding; +*/ + + tmp_win->rightx = width - Scr->TBInfo.rightoff; + + if (squeeze && tmp_win->squeeze_info) + { + /* djhjr - 3/13/97 8/11/98 */ + /* this used to care about title bevels - djhjr - 10/18/02 */ + int rx = tmp_win->highlightx + + ((tmp_win->titlehighlight) ? Scr->TitleHeight * 2 : 0); + + if (rx < tmp_win->rightx) tmp_win->rightx = rx; + } + + return; +} + + +/* + * ComputeTitleLocation - calculate the position of the title window. + * + * substantially re-written - djhjr - 1/8/98 + */ +void ComputeTitleLocation (tmp) + TwmWindow *tmp; +{ + tmp->title_x = tmp->frame_bw3D - tmp->frame_bw; + tmp->title_y = tmp->frame_bw3D - tmp->frame_bw; + + if (tmp->squeeze_info) + { + SqueezeInfo *si = tmp->squeeze_info; + int basex; + int fw = tmp->frame_bw + tmp->frame_bw3D; + + if (si->denom != 0 && si->num != 0) + basex = ((tmp->frame_width - tmp->title_width) / si->denom) * si->num + fw; + else + if (si->denom == 0 && si->num != 0) + basex = si->num + fw; + else + switch (si->justify) + { + case J_LEFT: + basex = tmp->title_x + fw; + break; + case J_CENTER: + basex = tmp->frame_width / 2 - (tmp->title_width / 2 - fw); + break; + case J_RIGHT: + basex = tmp->frame_width - tmp->title_width; + break; + } + + if (basex > tmp->frame_width - tmp->title_width) + basex = tmp->frame_width - tmp->title_width; + if (basex < 0) + basex = tmp->title_x + fw; + + tmp->title_x = basex - fw; + } +} + + +static void CreateWindowTitlebarButtons (tmp_win) + TwmWindow *tmp_win; +{ + unsigned long valuemask; /* mask for create windows */ + XSetWindowAttributes attributes; /* attributes for create windows */ + TitleButton *tb; + TBWindow *tbw; + int boxwidth = Scr->TBInfo.width + Scr->TBInfo.pad; + unsigned int h = Scr->TBInfo.width - Scr->TBInfo.border * 2; + int x, y = Scr->FramePadding + Scr->ButtonIndent; /* init - djhjr - 10/18/02 */ + int nb, leftx, rightx; + + if (tmp_win->title_height == 0) + { + tmp_win->hilite_w = 0; + return; + } + + /* + * create the title bar windows; let the event handler deal with painting + * so that we don't have to spend two pixmaps (or deal with hashing) + */ + ComputeWindowTitleOffsets (tmp_win, tmp_win->attr.width, False); + +/* djhjr - 10/18/02 + leftx = y = Scr->TBInfo.leftx; +*/ + leftx = Scr->TBInfo.leftx; + rightx = tmp_win->rightx; + + attributes.background_pixel = tmp_win->title.back; + attributes.border_pixel = tmp_win->title.fore; + attributes.event_mask = (ButtonPressMask | ButtonReleaseMask | ExposureMask); + attributes.cursor = Scr->ButtonCursor; + + valuemask = (CWWinGravity | CWBackPixel | CWBorderPixel | CWEventMask | CWCursor); + + tmp_win->titlebuttons = NULL; + nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; + if (nb > 0) { + tmp_win->titlebuttons = (TBWindow *) malloc (nb * sizeof(TBWindow)); + if (!tmp_win->titlebuttons) { + fprintf (stderr, "%s: unable to allocate %d titlebuttons\n", + ProgramName, nb); + } else { + for (tb = Scr->TBInfo.head, tbw = tmp_win->titlebuttons; tb; + tb = tb->next, tbw++) { + if (tb->rightside) { + x = rightx; + rightx += boxwidth; + attributes.win_gravity = NorthEastGravity; + } else { + x = leftx; + leftx += boxwidth; + attributes.win_gravity = NorthWestGravity; + } + + tbw->window = XCreateWindow (dpy, tmp_win->title_w, x, y, h, h, + (unsigned int) Scr->TBInfo.border, + 0, (unsigned int) CopyFromParent, + (Visual *) CopyFromParent, + valuemask, &attributes); + + tbw->info = tb; + } /* end for(...) */ + } + } + +/* djhjr - 4/5/98 + tmp_win->hilite_w = (tmp_win->titlehighlight + ? CreateHighlightWindow (tmp_win) : None); + + XMapSubwindows(dpy, tmp_win->title_w); + +* djhjr - 4/25/96 + if (tmp_win->hilite_w) + XUnmapWindow(dpy, tmp_win->hilite_w); +* + PaintTitleHighlight(tmp_win, off); +*/ + /* was '!Scr->SunkFocusWindowTitle' - djhjr - 10/25/02 */ + tmp_win->hilite_w = + (tmp_win->titlehighlight && !Scr->hiliteName) ? + CreateHighlightWindow(tmp_win) : None; + + return; +} + + +/* + * re-written to use an Image structure for XPM support + * + * djhjr - 5/17/98 + */ +#ifdef ORIGINAL_PIXMAPS +void SetHighlightPixmap (filename) + char *filename; +{ + Pixmap pm = GetBitmap (filename); + + if (pm) { + if (Scr->hilitePm) { + XFreePixmap (dpy, Scr->hilitePm); + } + Scr->hilitePm = pm; + Scr->hilite_pm_width = JunkWidth; + Scr->hilite_pm_height = JunkHeight; + } +} +#else /* ORIGINAL_PIXMAPS */ +void SetHighlightPixmap (filename) + char *filename; +{ + /* added this 'if (...) else' - djhjr - 10/25/02 */ + if (filename[0] == ':') + Scr->hiliteName = filename; + else + + if (!Scr->hilitePm) Scr->hilitePm = SetPixmapsPixmap(filename); +} +#endif /* ORIGINAL_PIXMAPS */ + + +void FetchWmProtocols (tmp) + TwmWindow *tmp; +{ + unsigned long flags = 0L; + Atom *protocols = NULL; + int n; + + if (XGetWMProtocols (dpy, tmp->w, &protocols, &n)) { + register int i; + register Atom *ap; + + for (i = 0, ap = protocols; i < n; i++, ap++) { + if (*ap == _XA_WM_TAKE_FOCUS) flags |= DoesWmTakeFocus; + if (*ap == _XA_WM_SAVE_YOURSELF) flags |= DoesWmSaveYourself; + if (*ap == _XA_WM_DELETE_WINDOW) flags |= DoesWmDeleteWindow; + } + if (protocols) XFree ((char *) protocols); + } + tmp->protocols = flags; +} + +TwmColormap * +CreateTwmColormap(c) + Colormap c; +{ + TwmColormap *cmap; + cmap = (TwmColormap *) malloc(sizeof(TwmColormap)); + if (!cmap || + XSaveContext(dpy, c, ColormapContext, (caddr_t) cmap)) { + if (cmap) free((char *) cmap); + return (NULL); + } + cmap->c = c; + cmap->state = 0; + cmap->install_req = 0; + cmap->w = None; + cmap->refcnt = 1; + return (cmap); +} + +ColormapWindow * +CreateColormapWindow(w, creating_parent, property_window) + Window w; + Bool creating_parent; + Bool property_window; +{ + ColormapWindow *cwin; + TwmColormap *cmap; + XWindowAttributes attributes; + + cwin = (ColormapWindow *) malloc(sizeof(ColormapWindow)); + if (cwin) { + if (!XGetWindowAttributes(dpy, w, &attributes) || + XSaveContext(dpy, w, ColormapContext, (caddr_t) cwin)) { + free((char *) cwin); + return (NULL); + } + + if (XFindContext(dpy, attributes.colormap, ColormapContext, + (caddr_t *)&cwin->colormap) == XCNOENT) { + cwin->colormap = cmap = CreateTwmColormap(attributes.colormap); + if (!cmap) { + XDeleteContext(dpy, w, ColormapContext); + free((char *) cwin); + return (NULL); + } + } else { + cwin->colormap->refcnt++; + } + + cwin->w = w; + /* + * Assume that windows in colormap list are + * obscured if we are creating the parent window. + * Otherwise, we assume they are unobscured. + */ + cwin->visibility = creating_parent ? + VisibilityPartiallyObscured : VisibilityUnobscured; + cwin->refcnt = 1; + + /* + * If this is a ColormapWindow property window and we + * are not monitoring ColormapNotify or VisibilityNotify + * events, we need to. + */ + if (property_window && + (attributes.your_event_mask & + (ColormapChangeMask|VisibilityChangeMask)) != + (ColormapChangeMask|VisibilityChangeMask)) { + XSelectInput(dpy, w, attributes.your_event_mask | + (ColormapChangeMask|VisibilityChangeMask)); + } + } + + return (cwin); +} + +void FetchWmColormapWindows (tmp) + TwmWindow *tmp; +{ + register int i, j; + Window *cmap_windows = NULL; + Bool can_free_cmap_windows = False; + int number_cmap_windows = 0; + ColormapWindow **cwins = NULL; + int previously_installed; + extern void free_cwins(); + + number_cmap_windows = 0; + + if ((previously_installed = + (Scr->cmapInfo.cmaps == &tmp->cmaps) && tmp->cmaps.number_cwins)) { + cwins = tmp->cmaps.cwins; + for (i = 0; i < tmp->cmaps.number_cwins; i++) + cwins[i]->colormap->state = 0; + } + + if (XGetWMColormapWindows (dpy, tmp->w, &cmap_windows, + &number_cmap_windows) && + number_cmap_windows > 0) { + + can_free_cmap_windows = False; + /* + * check if the top level is in the list, add to front if not + */ + for (i = 0; i < number_cmap_windows; i++) { + if (cmap_windows[i] == tmp->w) break; + } + if (i == number_cmap_windows) { /* not in list */ + Window *new_cmap_windows = + (Window *) malloc (sizeof(Window) * (number_cmap_windows + 1)); + + if (!new_cmap_windows) { + fprintf (stderr, + "%s: unable to allocate %d element colormap window array\n", + ProgramName, number_cmap_windows+1); + goto done; + } + new_cmap_windows[0] = tmp->w; /* add to front */ + for (i = 0; i < number_cmap_windows; i++) { /* append rest */ + new_cmap_windows[i+1] = cmap_windows[i]; + } + XFree ((char *) cmap_windows); + can_free_cmap_windows = True; /* do not use XFree any more */ + cmap_windows = new_cmap_windows; + number_cmap_windows++; + } + + cwins = (ColormapWindow **) malloc(sizeof(ColormapWindow *) * + number_cmap_windows); + if (cwins) { + for (i = 0; i < number_cmap_windows; i++) { + + /* + * Copy any existing entries into new list. + */ + for (j = 0; j < tmp->cmaps.number_cwins; j++) { + if (tmp->cmaps.cwins[j]->w == cmap_windows[i]) { + cwins[i] = tmp->cmaps.cwins[j]; + cwins[i]->refcnt++; + break; + } + } + + /* + * If the colormap window is not being pointed by + * some other applications colormap window list, + * create a new entry. + */ + if (j == tmp->cmaps.number_cwins) { + if (XFindContext(dpy, cmap_windows[i], ColormapContext, + (caddr_t *)&cwins[i]) == XCNOENT) { + if ((cwins[i] = CreateColormapWindow(cmap_windows[i], + (Bool) tmp->cmaps.number_cwins == 0, + True)) == NULL) { + int k; + for (k = i + 1; k < number_cmap_windows; k++) + cmap_windows[k-1] = cmap_windows[k]; + i--; + number_cmap_windows--; + } + } else + cwins[i]->refcnt++; + } + } + } + } + + /* No else here, in case we bailed out of clause above. + */ + if (number_cmap_windows == 0) { + + number_cmap_windows = 1; + + cwins = (ColormapWindow **) malloc(sizeof(ColormapWindow *)); + if (XFindContext(dpy, tmp->w, ColormapContext, (caddr_t *)&cwins[0]) == + XCNOENT) + cwins[0] = CreateColormapWindow(tmp->w, + (Bool) tmp->cmaps.number_cwins == 0, False); + else + cwins[0]->refcnt++; + } + + if (tmp->cmaps.number_cwins) + free_cwins(tmp); + + tmp->cmaps.cwins = cwins; + tmp->cmaps.number_cwins = number_cmap_windows; + if (number_cmap_windows > 1) + tmp->cmaps.scoreboard = + (char *) calloc(1, ColormapsScoreboardLength(&tmp->cmaps)); + + if (previously_installed) + InstallWindowColormaps(PropertyNotify, (TwmWindow *) NULL); + + done: + if (cmap_windows) { + if (can_free_cmap_windows) + free ((char *) cmap_windows); + else + XFree ((char *) cmap_windows); + } + + return; +} + + +void GetWindowSizeHints (tmp) + TwmWindow *tmp; +{ + long supplied = 0; + + if (!XGetWMNormalHints (dpy, tmp->w, &tmp->hints, &supplied)) + tmp->hints.flags = 0; + + if (tmp->hints.flags & PResizeInc) { + if (tmp->hints.width_inc == 0) tmp->hints.width_inc = 1; + if (tmp->hints.height_inc == 0) tmp->hints.height_inc = 1; + } + + if (!(supplied & PWinGravity) && (tmp->hints.flags & USPosition)) { + static int gravs[] = { SouthEastGravity, SouthWestGravity, + NorthEastGravity, NorthWestGravity }; + int right = tmp->attr.x + tmp->attr.width + 2 * tmp->old_bw; + int bottom = tmp->attr.y + tmp->attr.height + 2 * tmp->old_bw; + +/* djhjr - 4/19/96 + tmp->hints.win_gravity = + gravs[((Scr->MyDisplayHeight - bottom < tmp->title_height) ? 0 : 2) | + ((Scr->MyDisplayWidth - right < tmp->title_height) ? 0 : 1)]; +*/ + tmp->hints.win_gravity = + gravs[((Scr->MyDisplayHeight - bottom < + tmp->title_height + 2 * tmp->frame_bw3D) ? 0 : 2) | + ((Scr->MyDisplayWidth - right < + tmp->title_height + 2 * tmp->frame_bw3D) ? 0 : 1)]; + + tmp->hints.flags |= PWinGravity; + } +} + diff --git a/add_window.h b/add_window.h new file mode 100644 index 0000000..768b56a --- /dev/null +++ b/add_window.h @@ -0,0 +1,62 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/********************************************************************** + * + * $XConsortium: add_window.h,v 1.7 90/04/17 14:04:33 jim Exp $ + * + * AddWindow include file + * + * 31-Mar-88 Tom LaStrange Initial Version. + * + **********************************************************************/ + +#ifndef _ADD_WINDOW_ +#define _ADD_WINDOW_ + +extern char NoName[]; + +extern TwmWindow *AddWindow(); +extern int MappedNotOverride(); +extern void GrabButtons(); +extern void GrabKeys(); +extern void GrabModKeys(); +extern void UngrabModKeys(); +extern void GetWindowSizeHints(); +extern void FetchWmProtocols(); +extern void FetchWmColormapWindows(); +extern void GetGravityOffsets(); +extern void AddDefaultBindings(); + +extern int AddingX; +extern int AddingY; +extern int AddingW; +extern int AddingH; + +#endif /* _ADD_WINDOW_ */ + diff --git a/applets.c b/applets.c new file mode 100644 index 0000000..165a25b --- /dev/null +++ b/applets.c @@ -0,0 +1,209 @@ +/* + * Copyright 1989 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/********************************************************************** + * + * applets.c + * + * Applet region related routines + * + * 4/26/99 D. J. Hawkey Jr. + * + **********************************************************************/ + +#include +#include +#include "twm.h" +#include "screen.h" +#include "regions.h" +#include "gram.h" +#include "parse.h" +#include "util.h" + +extern void twmrc_error_prefix(); +extern int MatchName(); + +extern void splitRegionEntry(); +extern int roundEntryUp(); +extern RegionEntry *prevRegionEntry(); +extern void mergeRegionEntries(); +extern void downRegionEntry(); +extern RootRegion *AddRegion(); + +int appletWidth(tmp_win) +TwmWindow *tmp_win; +{ + /* submitted by Tim Wiess - 8/23/02 */ + if (Scr->NoBorders || LookInList(Scr->NoBorder, tmp_win->full_name, &tmp_win->class)) + return tmp_win->attr.width; + else + return Scr->BorderWidth * 2 + tmp_win->attr.width; +} + +int appletHeight(tmp_win) +TwmWindow *tmp_win; +{ + /* submitted by Tim Wiess - 8/23/02 */ + /* added 'tmp_win->title_height +' - djhjr - 11/11/03 */ + if (Scr->NoBorders || LookInList(Scr->NoBorder, tmp_win->full_name, &tmp_win->class)) + return tmp_win->title_height + tmp_win->attr.height; + else + return Scr->BorderWidth * 2 + tmp_win->title_height + tmp_win->attr.height; +} + +int PlaceApplet(tmp_win, def_x, def_y, final_x, final_y) +TwmWindow *tmp_win; +int def_x, def_y; +int *final_x, *final_y; +{ + RootRegion *rr; + RegionEntry *re; + int matched, w, h; + + for (rr = Scr->FirstAppletRegion; rr; rr = rr->next) + { + matched = 0; + w = roundEntryUp (appletWidth (tmp_win), rr->stepx); + h = roundEntryUp (appletHeight (tmp_win), rr->stepy); + + for (re = rr->entries; re; re = re->next) + { + if (!matched) + { + /* these were 'match()' - djhjr - 10/20/01 */ + if (MatchName(tmp_win->full_name, re->u.name, &re->re, re->type)) + if (MatchName(tmp_win->class.res_name, re->u.name, &re->re, re->type)) + if (MatchName(tmp_win->class.res_class, re->u.name, &re->re, re->type)) + continue; + + matched = 1; + } + + if (re->usedby) continue; +/* don't include grid spacing - djhjr - 5/22/99 + if (re->w < w || re->h < h) continue; +*/ + if (re->w < appletWidth(tmp_win) || re->h < appletHeight(tmp_win)) + continue; + + splitRegionEntry (re, rr->grav1, rr->grav2, w, h); + re->usedby = USEDBY_TWIN; + re->u.twm_win = tmp_win; + +/* evenly spaced applet placement - djhjr - 4/24/99 + *final_x = re->x + (re->w - appletWidth (tmp_win)) / 2; + *final_y = re->y + (re->h - appletHeight (tmp_win)) / 2; +*/ + *final_x = re->x; + *final_y = re->y; + + /* adjust for region gravity - djhjr 4/26/99 */ + if (rr->grav2 == D_EAST) + *final_x += re->w - appletWidth(tmp_win); + if (rr->grav1 == D_SOUTH) + *final_y += re->h - appletHeight(tmp_win); + + return 1; + } + } + + *final_x = def_x; + *final_y = def_y; + + return 0; +} + +static RegionEntry * +FindAppletEntry (tmp_win, rrp) + TwmWindow *tmp_win; + RootRegion **rrp; +{ + RootRegion *rr; + RegionEntry *re; + + for (rr = Scr->FirstAppletRegion; rr; rr = rr->next) { + for (re = rr->entries; re; re=re->next) + if (re->u.twm_win == tmp_win) { + if (rrp) + *rrp = rr; + return re; + } + } + return 0; +} + +void +AppletDown (tmp_win) + TwmWindow *tmp_win; +{ + RegionEntry *re; + RootRegion *rr; + + re = FindAppletEntry (tmp_win, &rr); + if (re) + downRegionEntry(rr, re); +} + +RootRegion * +AddAppletRegion(geom, grav1, grav2, stepx, stepy) +char *geom; +int grav1, grav2, stepx, stepy; +{ + RootRegion *rr; + + rr = AddRegion(geom, grav1, grav2, stepx, stepy); + + if (Scr->LastAppletRegion) + Scr->LastAppletRegion->next = rr; + Scr->LastAppletRegion = rr; + if (!Scr->FirstAppletRegion) + Scr->FirstAppletRegion = rr; + + return rr; +} + +void +AddToAppletList(list_head, name, type) +RootRegion *list_head; +char *name; +short type; +{ + RegionEntry *nptr; + + if (!list_head) return; /* ignore empty inserts */ + + nptr = (RegionEntry *)malloc(sizeof(RegionEntry)); + if (nptr == NULL) + { + twmrc_error_prefix(); + fprintf (stderr, "unable to allocate %d bytes for RegionEntry\n", + sizeof(RegionEntry)); + Done(); + } + + nptr->next = list_head->entries; + /* djhjr - 10/20/01 */ + nptr->type = type; + nptr->usedby = USEDBY_NAME; + nptr->u.name = (char*)strdup(name); + list_head->entries = nptr; +} + diff --git a/contrib/nexpm/Imakefile b/contrib/nexpm/Imakefile new file mode 100644 index 0000000..94c720d --- /dev/null +++ b/contrib/nexpm/Imakefile @@ -0,0 +1,5 @@ +USRLIBDIR = /usr/lib/X11 +LOCAL_LIBRARIES = -lXpm $(XMULIB) $(XTOOLLIB) $(XLIB) + DEPLIBS = $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB) + +SimpleProgramTarget(nexpm) diff --git a/contrib/nexpm/README b/contrib/nexpm/README new file mode 100644 index 0000000..2805222 --- /dev/null +++ b/contrib/nexpm/README @@ -0,0 +1,55 @@ +INTRODUCTION + +If you use vtwm, perhaps you would like to set or change the +background of the "Virtual Desktop" panner window... + +This posting provides a simple program, based on sxpm, xMoveIt, +and xsetroot, that draws a pixmap in *any* existing window. + +Instead of drawing a pixmap, you can make it set a solid background +color for the window -- which is useful to cancel the effects of a +previous nexpm invocation! + +There is a special parameter for operating on the vtwm panner +window; otherwise, the target window is specified either by name, by +numeric ID, or by using the mouse pointer. + +It is possible that the Compensate() routine, which is the only +original code here, is vtwm-specific. + +There is probably no use for this technology except when applied to +the panner window. Putting a pixmap in the background of an xterm +window may be hazardous to your mental health. + +INSTALLATION + +xmkmf +make + +COMPATIBILITY + +My version of xpm is, from README, "3.0 (91/10/03)"; +older xpm libraries will not understand the built-in default +"plaid" pixmap. + +OTHER USES + +The same hack could be applied to xmartin, xv, xloadimage, xneko, or +anything else, if you have source for them, to make them capable of +displaying in other windows. + +FILES + +Imakefile +README +nexpm.c this is what it's all about +patchlevel.h required +xpm.COPYRIGHT came with sxpm... + +DISCLAIMER + +I'm not responsible. This is free stuff, and I wrote very little of +it. Enjoy! + +--Ralph Betza + gnohmon@ssiny.com diff --git a/contrib/nexpm/nexpm.c b/contrib/nexpm/nexpm.c new file mode 100644 index 0000000..6ffccce --- /dev/null +++ b/contrib/nexpm/nexpm.c @@ -0,0 +1,516 @@ +/**********************************************************/ +/* */ +/* pxpm.c: this is sxpm.c hacked by Ralph Betza so that */ +/* it can be used to set a background picture for the */ +/* vtwm panner window, */ +/* */ +/* Works for vtwm, not for tvtwm. */ +/* */ +/* And then also changed to set backgrounds for */ +/* *any* window. */ +/* Ralph Betza, June 1993 gnohmon@ssiny.com */ +/**********************************************************/ + +/* Copyright 1990,91 GROUPE BULL -- See licence conditions in file COPYRIGHT */ +/* Since most of the code is from sxpm.c, the above copyright should +** still apply. +*/ + +/*****************************************************************************\ +* sxpm.c: * +* * +* Show XPM File program * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#include + +#ifdef VMS +#include "decw$include:Xlib.h" +#include "decw$include:Intrinsic.h" +#include "decw$include:Shell.h" +#include "decw$include:shape.h" +#else +#include +#include +#include +#include +#include +#endif + +#include + +Window window_by_name(); +Window point_to_window(); + +/* XPM */ +/* plaid pixmap */ +static char *plaid[] = +{ +/* width height ncolors chars_per_pixel */ + "22 22 4 2", +/* colors */ + " c red m white s light_color", + "Y c green m black s lines_in_mix", + "+ c yellow m white s lines_in_dark", + "x m black s dark_color", +/* pixels */ + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + "Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + "x x x x x x x x x x x x x x x x x x x x x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x " +}; + +/* #define win XtWindow(topw) */ +Window win; +Window Compensate(); +#define dpy XtDisplay(topw) +#define screen XtScreen(topw) +#define colormap XDefaultColormapOfScreen(screen) +#define root XRootWindowOfScreen(screen) +#define xrdb XtDatabase(dpy) + +int sDoByName; +int sDoByNumber; +char * pTargetWindowName; + +void Usage(); +void ErrorMessage(); +void Punt(); + +#define IWIDTH 50 +#define IHEIGHT 50 + +typedef struct _XpmIcon { + Pixmap pixmap; + Pixmap mask; + XpmAttributes attributes; +} XpmIcon; + +static char **command; +static Widget topw; +static XpmIcon view; + +char *point_txt[] = { +" ====> Please select the window", +" ====> whose background you wish to", +" ====> change by clicking the", +" ====> pointer in that window.", +0}; + +XColor NameToXColor(); +unsigned long NameToPixel(); + +main(argc, argv) + unsigned int argc; + char **argv; +{ + int ErrorStatus; + unsigned int stdinf = 0; + unsigned int sSolid = 0; + unsigned int w_rtn; + unsigned int h_rtn; + char *input = NULL; + unsigned int numsymbols = 0; + XpmColorSymbol symbols[10]; + char *stype; + XrmValue val; + unsigned long valuemask = 0; + int n; + char *solid_color = NULL; + Arg args[3]; + + topw = XtInitialize(argv[0], "Nexpm", + (void*)0, 0, &argc, argv); + + if (!topw) { + fprintf(stderr, "Nexpm Error... [ Undefined DISPLAY ]\n"); + exit(1); + } + + /* + * arguments parsing + */ + + command = argv; + if (argc < 2) + Usage(); + for (n = 1; n < argc; n++) { + + if ( ! strcmp( argv[ n ], "-target" )) + { sDoByName = 1; + pTargetWindowName = argv[++n]; + continue; + } + if ( ! strcmp( argv[ n ], "-vtwm" )) + { sDoByName = 1; + pTargetWindowName = "VTWM Desktop"; + continue; + } + if ( ! strcmp( argv[ n ], "-id" )) + { sDoByNumber = 1; + pTargetWindowName = argv[++n]; + continue; + } + + if (!strcmp("-solid", argv[n])) { + solid_color = argv[++n]; + sSolid = 1; + continue; + } + if (strncmp(argv[n], "-plaid", 3) == 0) { + continue; + } + if (strncmp(argv[n], "-in", 3) == 0) { + input = argv[++n]; + continue; + } + if (strncmp(argv[n], "-stdin", 5) == 0) { + stdinf = 1; + continue; + } + if (strncmp(argv[n], "-s", 2) == 0) { + if (n < argc - 2) { + valuemask |= XpmColorSymbols; + symbols[numsymbols].name = argv[++n]; + symbols[numsymbols++].value = argv[++n]; + continue; + } + } + if (strncmp(argv[n], "-p", 2) == 0) { + if (n < argc - 2) { + valuemask |= XpmColorSymbols; + symbols[numsymbols].name = argv[++n]; + symbols[numsymbols].value = NULL; + symbols[numsymbols++].pixel = atol(argv[++n]); + continue; + } + } + if (strncmp(argv[n], "-rgb", 3) == 0) { + if (n < argc - 1) { + valuemask |= XpmRgbFilename; + view.attributes.rgb_fname = argv[++n]; + continue; + } + } + Usage(); + } + + n = 0; + XtSetArg(args[n], XtNwidth, 1); + n++; + XtSetArg(args[n], XtNheight, 1); + n++; + XtSetArg(args[n], XtNmappedWhenManaged, False); + n++; + XtSetValues(topw, args, n); + XtRealizeWidget(topw); + + view.attributes.colorsymbols = symbols; + view.attributes.numsymbols = numsymbols; + view.attributes.valuemask = valuemask; + + if ( sDoByName ) + { win = window_by_name( root, pTargetWindowName ); + win = Compensate( win ); + } + else if ( sDoByNumber ) + { + win = strtol( pTargetWindowName, (void *)0, 0 ); + } + else + { char ** ptr; + for (ptr = point_txt; *ptr; ptr++) + printf("%s\n",*ptr); + + win = point_to_window(); /* use pointer to get window */ + win = Compensate( win ); + } + + if ( ! sSolid ) + { + if (input || stdinf) { + view.attributes.valuemask |= XpmReturnInfos; + view.attributes.valuemask |= XpmReturnPixels; + ErrorStatus = XpmReadFileToPixmap(dpy, win, input, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "Read"); + } else { + + ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "Plaid"); + } +/* Now we are ready to display it... */ + XSetWindowBackgroundPixmap(dpy, win, view.pixmap); + } + else + { + XSetWindowBackground(dpy, win, NameToPixel( solid_color, + 0L )); + } + + XClearWindow(dpy, win); + XFlush( dpy ); + Punt(0); +} + +void +Usage() +{ + fprintf(stderr, "\nUsage: %s [options...]\n", command[0]); + fprintf(stderr, "%s\n", "Where options are:"); + fprintf(stderr, "%s\n", + "[-vtwm] Target is the vtwm panner."); + fprintf(stderr, "%s\n", + "[-id window_id target Window's numeric ID."); + fprintf(stderr, "%s\n", + "[-target window_name] target Window's name."); + fprintf(stderr, "%s\n", + " (if none of the above specified, target is selected by mouse)"); + fprintf(stderr, "%s\n", +"[-solid color_name] Ignore all pixmap parameters, set\ + background color."); + fprintf(stderr, "%s\n", + "[-d host:display] Display to connect to."); + fprintf(stderr, "%s\n", + "[-s symbol_name color_name] Overwrite color defaults."); + fprintf(stderr, "%s\n", + "[-p symbol_name pixel_value] Overwrite color defaults."); + fprintf(stderr, "%s\n", + "[-plaid] Read the included plaid pixmap."); + fprintf(stderr, "%s\n", + "[-in filename] Read input from file `filename`."); + fprintf(stderr, "%s\n", + "[-stdin] Read input from stdin."); + fprintf(stderr, "%s\n\n", + "[-rgb filename] Search color names in the \ +rgb text file `filename`."); + exit(0); +} + + +void +ErrorMessage(ErrorStatus, tag) + int ErrorStatus; + char *tag; +{ + char *error = NULL; + char *warning = NULL; + + switch (ErrorStatus) { + case XpmSuccess: + return; + case XpmColorError: + warning = "Could not parse or alloc requested color"; + break; + case XpmOpenFailed: + error = "Cannot open file"; + break; + case XpmFileInvalid: + error = "invalid XPM file"; + break; + case XpmNoMemory: + error = "Not enough memory"; + break; + case XpmColorFailed: + error = "Color not found"; + break; + } + + if (warning) + printf("%s Xpm Warning: %s.\n", tag, warning); + + if (error) { + printf("%s Xpm Error: %s.\n", tag, error); + Punt(1); + } +} + +void +Punt(i) + int i; +{ + if (view.pixmap) { + XFreePixmap(dpy, view.pixmap); + if (view.mask) + XFreePixmap(dpy, view.mask); + + XFreeColors(dpy, colormap, + view.attributes.pixels, view.attributes.npixels, 0); + + XpmFreeAttributes(&view.attributes); + } + exit(i); +} + +Window window_by_name(wdw,name) +Window wdw; +char *name; +{ +/**********************************************************/ +/* */ +/* Copied from xcursor.c, who copied it from xwininfo. */ +/* */ +/**********************************************************/ + + Window *offspring; /* Any children */ + Window junk; /* Just that */ + Window w = 0; /* Found window */ + int count; /* Number of kids */ + int loop; /* Loop counter */ + char *wdw_name; /* Returnewd name */ + if (XFetchName(dpy,wdw,&wdw_name) && !strcmp(wdw_name,name)) + return(wdw); + if (!XQueryTree(dpy,wdw,&junk,&junk,&offspring,&count)) + return(0); + for (loop = 0; loop < count; loop++) + { + w = window_by_name(offspring[loop],name); + if (w) + break; + } + if (offspring) + XFree(offspring); + /* fprintf( stderr, "w=%x\n", w ); */ + return(w); +} + +Window point_to_window() +{ /* from xcursor.c, also from blast.c */ + int status; + Cursor cursor; + XEvent event; + Window target_win = None; + int buttons = 0; + + /* Make the target cursor */ + cursor = XCreateFontCursor(dpy, XC_crosshair); + + /* Grab the pointer using target cursor, letting it room all over */ + status = XGrabPointer(dpy, root, False, + ButtonPressMask|ButtonReleaseMask, GrabModeSync, + GrabModeAsync, None, cursor, CurrentTime); + if (status != GrabSuccess) + { + fprintf(stderr,"Can't grab the mouse."); + exit(4); + } + + /* Let the user select a window... */ + while ((target_win == None) || (buttons != 0)) /* allow one more event */ + { + XAllowEvents(dpy, SyncPointer, CurrentTime); + XWindowEvent(dpy, root, + ButtonPressMask|ButtonReleaseMask, &event); + switch (event.type) + { + case ButtonPress: + if (target_win == None) + { + /* window selected */ + target_win = event.xbutton.subwindow; + if (target_win == None) + target_win = root; + } + buttons++; + break; + + /* there may have been some down before we started */ + case ButtonRelease: + if (buttons > 0) + buttons--; + break; + } + } + + XUngrabPointer(dpy, CurrentTime); /* Done with pointer */ + + target_win = XmuClientWindow( dpy, target_win ); +/* XmuClientWindow() is suggested by blast.c, but ifdeffed out. +** What happens is that blast gets the ID of the frame window, +** created by the window manager, not the ID of the window you +** really pointed to; but for blast it's OK: the shape *should* be +** given to the frame. +*/ + + return(target_win); +} + +Window +Compensate( win ) +Window win; +{ + Window dummy; + Window dummy2; + Window * children; + unsigned int n; + + if ( XQueryTree( dpy, win, &dummy, &dummy2, &children, &n )) + { + /* Test for children submitted by Steve Ratcliffe */ + if (children) + { + win = *children; + XFree( children ); + } + } +/**********************************************************/ +/* */ +/* It is possible that Compensate() is vtwm-specific. */ +/* */ +/* In any case, xlswins() reveals that the window ID we */ +/* get from the pointer or from the name is always the */ +/* *parent* of the window we really want, and since it */ +/* is always at the bottom of the stacking order we */ +/* know that it is the first window returned by */ +/* XQueryTree. */ +/* */ +/**********************************************************/ + return win; +} + + +unsigned long NameToPixel(name, pixel) + char *name; + unsigned long pixel; +{ + XColor ecolor; + + if (!name || !*name) + return pixel; + if (!XParseColor(dpy,colormap,name,&ecolor)) { + fprintf(stderr,"nexpm: unknown color \"%s\"\n",name); + exit(1); + /*NOTREACHED*/ + } + if (!XAllocColor(dpy, colormap,&ecolor)) + { + fprintf(stderr, "nexpm: unable to allocate color for \"%s\"\n", + name); + exit(1); + /*NOTREACHED*/ + } + return(ecolor.pixel); +} diff --git a/contrib/nexpm/patchlevel.h b/contrib/nexpm/patchlevel.h new file mode 100644 index 0000000..ba66466 --- /dev/null +++ b/contrib/nexpm/patchlevel.h @@ -0,0 +1 @@ +0.0 diff --git a/contrib/nexpm/xpm.COPYRIGHT b/contrib/nexpm/xpm.COPYRIGHT new file mode 100644 index 0000000..09aa185 --- /dev/null +++ b/contrib/nexpm/xpm.COPYRIGHT @@ -0,0 +1,33 @@ +The following still applies to the parts of sxpm.c that were used to +create nexpm.c: + +/* + * Copyright 1990, 1991 GROUPE BULL + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of GROUPE BULL not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. GROUPE BULL makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * GROUPE BULL disclaims all warranties with regard to this software, + * including all implied warranties of merchantability and fitness, + * in no event shall GROUPE BULL be liable for any special, + * indirect or consequential damages or any damages + * whatsoever resulting from loss of use, data or profits, + * whether in an action of contract, negligence or other tortious + * action, arising out of or in connection with the use + * or performance of this software. + * + */ + +Arnaud LE HORS BULL Research FRANCE -- Koala Project + (XPM - X PixMap format version 2 & 3) + Internet: lehors@sophia.inria.fr +Surface Mail: Arnaud LE HORS, INRIA - Sophia Antipolis, + 2004, route des Lucioles, 06565 Valbonne Cedex -- FRANCE + Voice phone: (33) 93.65.77.71, Fax: (33) 93 65 77 66, Telex: 97 00 50 F diff --git a/contrib/support/sysrc_add_apps.sh b/contrib/support/sysrc_add_apps.sh new file mode 100644 index 0000000..e0c665d --- /dev/null +++ b/contrib/support/sysrc_add_apps.sh @@ -0,0 +1,206 @@ +#!/bin/sh +# +# Adds installed applications to the box-stock system.vtwmrc file. + +syntax () +{ + # could be a "here-doc", but it'd break at least one shell + echo + echo "Usage: ${0##*/} [-i in_file] [-o out_file] [-m menu_decl] \\" + echo " [-a app_list | -A app_file] [-f] [-h]" + echo + echo "Default in_file: $DEF_INPUT" + echo "Default out_file: $DEF_OUTPUT" + echo "Default menu_decl: $DEF_MENU_DECL" + echo "Default app_list: $DEF_LIST" + echo + echo "app_file is a list, each line containing one application specification" + echo "(or the keywords \"SEPARATOR\" or \"TITLE::string\"). The specification is" + echo "of the form \"name::string\", where \"name\" is the menu entry and \"string\"" + echo "is the command to execute. Whitespace in either part is indicated with" + echo "a single colon." + echo + + exit +} + +check_replace () +{ + CWD=$PWD + cd `dirname "$INPUT"` && INDIR=$PWD && INNAME=`basename "$INPUT"` + cd `dirname "$OUTPUT"` && OUTDIR=$PWD && OUTNAME=`basename "$OUTPUT"` + cd $CWD + if [ "$INDIR" = "$OUTDIR" -a "$INNAME" = "$OUTNAME" ]; then + if [ $NO_PROMPT -eq 1 ]; then + echo "Replacing in_file with out_file." + else + echo -n "Replace in_file with out_file (y/n)? " + read ANS + [ "$ANS" != "y" -a "$ANS" != "Y" ] && \ + echo "Exiting." && exit + fi + + OUTPUT=$TMPOUT + fi +} + +check_X_path () +{ + ANS=`which xterm 2>/dev/null` + if [ -z "$ANS" ]; then + if [ $NO_PROMPT -eq 1 ]; then + echo "No path to X applications (xterm)." + else + echo "The path to X applications (xterm) isn't set." + while true; do + echo -n "Enter full X path: " + read ANS + [ -z "$ANS" ] && echo "Exiting." && exit + [ -d "$ANS" -a -f "$ANS/xterm" -a \ + -x "$ANS/xterm" ] && break + done + PATH=$PATH:$ANS + fi + fi +} + +check_proceed () +{ + echo + echo "in_file: $INPUT" + if [ "$OUTPUT" = "$TMPOUT" ]; then + echo "out_file: $INPUT" + else + echo "out_file: $OUTPUT" + fi + echo "menu_decl: $MENU_DECL" + echo "app_list: $APP_LIST" + echo "app_file: $APP_FILE" + echo "Search path: $PATH" + echo + if [ $NO_PROMPT -eq 1 ]; then + echo "Proceeding..." + else + echo -n "Proceed (y/n)? " + read ANS + [ "$ANS" != "y" -a "$ANS" != "Y" ] && echo "Exiting." && exit + fi +} + +check_app () +{ + if [ "$1" = "SEPARATOR" ]; then + printf "\t\"\"\t\tf.separator\n" >>$2 + else + CMD=${1%%::*} + STR=${1##*::} + + if [ "$CMD" = "TITLE" ]; then + printf "\t\" %s \"\t\tf.title\n" $STR \ + |sed -e 's/:/ /g' >>$2 + else + [ -z "`which $CMD 2>/dev/null`" ] && return + printf "\t\"%s\"\t\tf.exec \"%s &\"\n" $CMD $STR \ + |sed -e 's/:/ /g' >>$2 + fi + fi +} + +DEF_INPUT=./system.vtwmrc +DEF_OUTPUT=./custom.vtwmrc + +DEF_LIST="TITLE::Shells emu eterm mxterm rxvt xterm xvt" +DEF_LIST="$DEF_LIST midc::xterm:-e:midc top::xterm:-e:top" +DEF_LIST="$DEF_LIST TITLE::Editors nedit xcoral xvile" +DEF_LIST="$DEF_LIST vi::xterm:-e:vi vile::xterm:-e:vile vim::xterm:-e:vim" +DEF_LIST="$DEF_LIST SEPARATOR gimp xfig xpaint xv xbmbrowser bitmap pixmap" +DEF_LIST="$DEF_LIST TITLE::Desktop applix soffice abiword lyx ted::Ted" +DEF_LIST="$DEF_LIST gnumeric ghostview gv xcal xcalendar" +DEF_LIST="$DEF_LIST SEPARATOR tkman xman" +DEF_LIST="$DEF_LIST SEPARATOR gmplayer xine xmcd xmmix xmms" +DEF_LIST="$DEF_LIST SEPARATOR hexcalc xcalc editres" +DEF_LIST="$DEF_LIST xbiff xcb xev xeyes xload xmag" +DEF_LIST="$DEF_LIST SEPARATOR moonclock mouseclock oclock" +DEF_LIST="$DEF_LIST rclock sunclock t3d xarclock xclock xdaliclock" +DEF_LIST="$DEF_LIST TITLE::Network chimera ie mozilla netscape opera" +DEF_LIST="$DEF_LIST links::xterm:-e:links lynx::xterm:-e:lynx" +DEF_LIST="$DEF_LIST SEPARATOR exmh knews xdir" +DEF_LIST="$DEF_LIST ftp::xterm:-e:ftp telnet::xterm:-e:telnet" +DEF_LIST="$DEF_LIST elm::xterm:-e:elm mutt::xterm:-e:mutt" +DEF_LIST="$DEF_LIST pine::xterm:-e:pine tin::xterm:-e:tin" + +DEF_MENU_DECL="menu \"apps\"" + +NO_PROMPT=0 + +TMPOUT=out.$$ +LISTOUT=list.$$ + +while getopts "i:o:m:a:A:fh" OPT; do + case $OPT in + i) INPUT=$OPTARG;; + o) OUTPUT=$OPTARG;; + m) MENU_DECL=$OPTARG;; + a) APP_LIST=$OPTARG;; + A) APP_FILE=$OPTARG;; + f) NO_PROMPT=1;; + *) syntax;; + esac +done + +[ -z "$INPUT" ] && INPUT=$DEF_INPUT +[ -z "$OUTPUT" ] && OUTPUT=$DEF_OUTPUT +[ -z "$APP_LIST" ] && APP_LIST=$DEF_LIST +[ -n "$APP_FILE" ] && APP_LIST= +[ -z "$MENU_DECL" ] && MENU_DECL=$DEF_MENU_DECL + +[ ! -f "$INPUT" ] && echo "$INPUT: File not found" && syntax + +check_replace +check_X_path +check_proceed + +if [ -n "$APP_LIST" ]; then + for APP in $APP_LIST; do + check_app $APP $LISTOUT + done +else + if [ -f "$APP_FILE" ]; then + while read APP; do + check_app $APP $LISTOUT + done <"$APP_FILE" + else + echo "$APP_FILE: File not found" + exit + fi +fi + +[ ! -s $LISTOUT ] && echo "No applications added." && exit + +uniq $LISTOUT $$.$$ +mv $$.$$ $LISTOUT + +cat "$INPUT" \ + |awk -v list="$LISTOUT" -v menu="$MENU_DECL" \ + 'BEGIN { \ + split(menu, menu); \ + } { \ + if ($1 == menu[1] && $2 == menu[2]) { \ + print $0; \ + do { \ + if ($1 == "{") print "{"; \ + a = getline; \ + } while (a && $1 != "}"); \ + if (a && $1 == "}") { \ + while (getline app "$OUTPUT" + +[ -s $TMPOUT ] && mv $TMPOUT "$INPUT" +rm -f *.$$ +echo "Done." diff --git a/contrib/vtwmrc/images/byzantine.xpm b/contrib/vtwmrc/images/byzantine.xpm new file mode 100644 index 0000000..36b4934 --- /dev/null +++ b/contrib/vtwmrc/images/byzantine.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static char *byzantine[] = { +/* width height num_colors chars_per_pixel */ +"32 13 3 1", +/* colors */ +" s None c None", +". c grey75", +"X c grey35", +/* pixels */ +" ..............X ..............X", +" .XXXXXXXXXXXX.X .XXXXXXXXXXXX.X", +" .X .X .X .X", +" .X ........X .X .X ........X .X", +" .X .XXXXXX.X .X .X .XXXXXX.X .X", +" .X .X .X .X .X .X .X .X", +" .X .....X .X .X .X .X .....X .X", +" .X XXXX.X .X .X .X .X .XXXXX .X", +" .X .X .X .X .X .X .X .X", +" ........X .X .X .X .X ........X", +" XXXXXXXXX .X .X .X .X XXXXXXXXX", +" .X .X .X .X ", +"............X ....X ............"}; diff --git a/contrib/vtwmrc/images/djhjr.xpm b/contrib/vtwmrc/images/djhjr.xpm new file mode 100644 index 0000000..3b5cbe0 --- /dev/null +++ b/contrib/vtwmrc/images/djhjr.xpm @@ -0,0 +1,70 @@ +/* XPM */ +static char *djhjr[] = { +/* width height num_colors chars_per_pixel */ +" 320 48 15 1", +/* colors */ +". c #595959", +"# c #656565", +"a c #6d6d6d", +"b c #757575", +"c c #797979", +"d c #828282", +"e c #8a8a8a", +"f c #999999", +"g c #a2a2a2", +"h c #a6a6a6", +"i c #b2b2b2", +"j c #bababa", +"k c #c3c3c3", +"l c #c7c7c7", +"m c #d3d3d3", +/* pixels */ +"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeefeffffffffffffffffffffffffffffffffffffffefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeefefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffedcbcdefffffffffffffffffffffffffffffffffffedccdeffffffffffffffffffffffffffffffffffffffffffffffffffffffffecbbdfghgfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedcddeffffffffffffffffffffffffffedbaabdfffffffffffffffffffffffffeeeffffffffdcbcdffgffffffffffffffffffffffffffffffffffffffffffffffffffffffebbbefhigfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +"ffffffffffffffffffffffffffedddeefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdcccdffgffffffffffffffffffffffffdcba#ceffgfffffffffffffffffffffddddefffffffdcbcefhhgffffffffffffffffffffffffffffffffffffffffffffffffffffedbbbfhjihfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +"ffffffffffffffffffeeeeeeddccbbcdeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbbcdfhhffffffffffffffffffffffffdbabbefgggggffffffffffffffffffedcccefffffffdbbcfgiigffffffffffffffffffffffffffffffffffffffffffffffffffffdcabdgijihfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +"fffffffffffffefeeedccbbbbbbabbcdeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbbdfghigfffffffffffffffffffffffdbbcdfghgghgffffffffffffffffffecbbdffhgfffedbbdgijigffffffffffffffffffffffffffffffffffffffffffffffffffffdbacehijigfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +"fffffffffeeccbbbbbaaabbbbbbcdeefffffffffffffffffffffffffffffffffffffffffffffffffffeeeffffffffffffffffffffffffdccefhiigfffffffffffffffffffffffdbbdffghgfhhgfffffffffffffffffebbcefihhfffecabehijigffffffffffffffffffffffffffffffffffffffffffffffffffffdbbdfhjjhffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +"ffeddcccccbbbabbbbbcddeefffggffffghhgfffffffffffffffffffffffffffffffffffffffffffeddddefffffffffffffffffffffffedcefghigfffffffffffffffffffffffdbbdfffgfgiihfffffffffffffffffdbbcfhjihfffcbbcfhjjhgffffffffffffffffffffffffffffffffffffffffffffffffffffdbbdfiijgffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +"ffdcbbbbbbbbccdeeefffgghhiiihgfffhihhgffffffffffffffffffffffffffffffffffffffffffecccdffgffffffffffffffffffffffecdffgigfffffffffffffffffffffffdbbeffffffiiigfffffffffffffffedabdfijihffecbbdfjjigfffffffffffffffffffffffffffffffffffffffffffffffffffffcbbefiijgffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +"ffdcbccddddeffffghhijiiijjjigfdegijihgffffffffffffffffffffffffffffffffffffffffffecbcdfgggfffffffffffffffffffffedcdfgihhffffffffffffffffffffffdbbdfffffgiiiffffffffffffffffdcabegijigfffcbbefjiigffffffffffffffffffffffffffffffffffffffffffffffffffffecbbegijigfffffffffffffffffffffffffffffffffffffffffffefeffffffffffffffffffff", +"ffdddefffgggghhijjjjjjiiiihgeccdfijihfffffffffffffffffffffffffffffffffffffffffffecccefhhgfffffffffffffffffffffeccdegiihffffffffffffffffffffffdbbdfffffgiiigfffffffffffffffdbacfhjjhgffecbcegjjhffffffffffffffffffffffffffffffffffffffffffffffffffffedbacfhjiigfffffffffffffffffffffffffffffffffffffffffeddcdeeffffffffffffffffff", +"fffffghiijhhhghiijiihgfffffdbbcfhjjigffffffffffffffffffffffffffffeedddefffffffffedddffhhgffffffffffffffffffffffcccffiihffffffffffffffffffffffdbbdeffffgijiffffffffffffffffcbbdfiijgffffbbcffjjiffffffffffffffffffffffffffffffffffffffffffffffffffffecbbdfijihfffffffffffffffffffffffffffffffffffffffffedcbccefffffffffffffffffff", +"ffffghiiiihfeffghhgfgfffffecbbcfijihffffffffffffffffffffffffffffedcccdeffffffffffeddefghhgfffffffffffffffffffffddcefhihffffffffffffffffffffffdbbceeffghjiiffffffffffffffffcbbdfiiigfffecbcegijhgfffffffffffffffffffffffffffffffffffffffffffffffffffebbbegijigffffffffffffffffffffffffffffffffffffffffeeccbdeggggffffffffffffffff", +"ffffgggghgedcdegghffffffffdcabehijigfffffffffffffffffffffffffffedcbcdfffgfffffffffdddffhhhfffffffffffffffffffffedcefghhgfffffffffffffffffffffdbbcdeffhijihgfffffffffffffffccbefijifffffbbcegjjhffffffffffffffffffffffffffffffffffffffffffffffffffffebbcegiihfffffffffffffffffffffffffffffffffffffffffeedddfghihgffffffffffffffff", +"ffffffffffccbdfhhiffffffffcbacfhiihffffffffffffffffffffffffffffeddcdfghhhgffffffffeddefhihffffffffffffffffffffffecdefghhgffffffffffffffffffffdbbbcefhiijigffffffffffffffffccbefijiffffecbcegijiffffffffefffffffffffffffffffffffffffffffffffffffffffebbcfgjjhffffffffffffffffffffffffffffffffffffffffffeeffgijihgffffffffffffffff", +"ffffffffffedcefghiffffffedbbbfhihfdcccdddefffffffffffffffffffffffffhiiihggfffffffffecdefhhhgffffffffffffffffffffedddfghhgffffffffffffffffffffba#abfhljjigfffffffffffffffffccbegiiiffffecbcegijifffffedcccccddeeffffffffffffffffffffffffffffffffffffebbcfgjjhffffffffffffffffffffffffffffffffffffffffffffffffgffeddeeffffffffffff", +"fffffffffffdceffhhhfffffecbbcfiigfdcddddddddeeefffffffffffffffffffgghhggfffffffffffeddefghhgfffffffffffffffffffffeddefghhgffffffffffffffeeddca..adhjlkihgfffffffffffffffffccbefijigffffcccffiihgffffedccdddddddddeeefffffffffffffffffffffffffffffffebccfgjjhfffffffffffffffffffffffffffffffffffffffffffeeddeedcccceeffffffffffff", +"fffffffffffeddefghhgffffdbacehiigfeefeeedddddddeffffffffffffffffffffgfffffffffffffffdddffihgffffffffffffffffffffffdddffhhhfffffefefffffedccbb#.#cfilmjihffffffffffffffffffccbegiiifffffdcceghihfffffeeeeeefeedddddddfefffffffffffffffffffffffffffffebbcfgjjhfffffffffffffffffffffffffffffffffffffffffffdcbbbcccbcdffgfffffffffff", +"fffffffffffedddffihgfffedbbcfijihffffgffffdddcdddeffffffffffffffffffffffffffffffffffeddffghhffffffffffffffffffffffdddefhhhgfffddcddeffeccbabbaacfhklligfffffffffffffffffffccbefiiiffffeddcefghhffffffffffffffffddcdddeefffffffffffffffffffffffeedeeebbcfgjjhffffffffffffffffffffffffffffffffffffffffffeca#aacddcefghhhgfffffffff", +"ffffffffffffdddffhhhfffecabehijigfgghhigffdccdeefffffffffffffffffffffffffffffffffffffedeffgggfffffffffffffffffffffedcefghiffeddbbcdfffecaabcfeefgikkkhffedcbbcceefffffffffccbegiihfdcbbba#acdffffffffffgghihhfedcddefffffffffffffffffffffffffeedddedbbcfgjjhffffffffffffffffffffffffffffffffffffffffffdb#.abeffghijiigffffffffff", +"fffffffffffffdceffhhgfecbbcfijjhgfffffefeedeeffgghhggffffffffffffffffffffffffffffffffeedefggggfffffffffffffffffffffeceefhhhfecbabdfggffcccefhgffgijjjgfdcbbbbbccddddefffffcbacefgfcbabbba#abdeffeeefffffffefeeedeeffgghggfffffffffffffffffffffdccddeccdfgijhffffeedcdddefffffffffffffffffffffffffffffdca.#behijijjiihggfffffffff", +"fffffffffffffeddefhihfdbbbegjjigfedccccccdefghiiiihffeddddddddddddeeffffffffffffffffffeddffghgfffffffffffffffffffffeddefghhfdbbbdfhihgfdddffigfffgiiifdcbbbcddeedddddddddda##bdfffcbccddcbbcefgffefeffedcbcccddefghijiigffedddddddeeefffffffffeccceedddfgjjhffeedcbbbccdddedeeffffffffffffeedeeeffffedcaabegikkjiihggfffffffffff", +"fffffffffffffeddefghifcabcfijigfdcbbabbcdefghjijihffccbbbbbbccbcbbccdeeeeeefffffffffffedddfgihgfffffffffffffffffffffdddffhifcbbcfijjigffeeffhgffffhhgecbccefffgffeedddcccb#..bdfffeefffgfeeffhihgffffecbbabbcdffghjjjigfeccbccbcbbcceeeeffffffecccfefeefgiihfeeccbbbccdddccccddeeeeeeeeeedccbccdefffedccddfhjkjjhgffffffffffffff", +"fffffffffffffedceffhiecacehjjhfdcbbbcdefgghhhgffffdccbbcccccccccccccdcccbbcddefffffffffdddffhhhfffffffffffffffffffffdddffhhfcbbegjjjggffeddefffffffffcbcefhijihhfffffeedcb##aceghihiiijihgfghjjjhhggfdcbbcdffgghhggfffedccbbccccccccdccdddeffeebcdfgffffghihfdcbbbdefffffddcccccccbbbbbbbbaabbcdefffeeeffffhhijhgfffffffffffffff", +"ffffffffffffffeddefghfcbdfiiifdbbbcefghgggffffeedcccdeeffffffffffffffedccbccdccccceefffddcefhhhffffffffffffffffffffffdceffhgeccefghgffffdccefhigfffffeefgiijjiihihhhgffffeedefhjkkjjjjjiigfghiikihgfedcdefghgggfffeeedcccdeefffffffffeddcdcdccbabdghigfffhhfdcbbdfghihhgffffffeedcbbbbbbbbbcdeeffffffffgffffghiigfffffffffffffff", +"fffffffffffffffccdffgedcegiihebbbdffggffffeeedeeefffghhhhhhhhhhhhhhgfffefeeeeedccccddddddceffhigfffffffffffffffffffffdddefhgfedfffgfddccbacehijigfffffghiiihhgggghhhhhhhhhgffhijkkjihhggffeeffhiigfeeeeffgfgfffeedeeeffffghhhhhhhhhgffffeeddccbcdfhjigffffffdccefhijjiihhhhhhgfffeeeeeeeefffgggffffffffgfedefhiigfffffffffffffff", +"ffffffffffffffeccdffgfddfhjifdbbdefffffeeeeefffgghiijjijjjjjjjjjjiihhhgggggfffeededdddddccdefhhhgffffffffffffffffffffedcefghgfeffffedccbbbdfijiigfffhhijiihgfffffggghhhiijihgggiijihgfffffdddffigfdcdefffffeeeeeefffgghiijijjjjjjiihhhgfgffeedeffhjiiffefffeedeghjiihhhhhhiiihhggggggggghhiijihgffffgggffddefghigfffffffffffffff", +"fffffffffffffffdddfgffeefjjhfdbcdffffeeeeffghiijjjjjjiihihihihihihihhhiiiiiihgfgffffeededccdfghhgfffeefefffffffffffffeeceffhhgffffffeedcdeghjjigfffghijiiggffffffffffgghhihgffffghhgffffffdddefhgfcccefffeeeeeffhhijijjjjiiihihihihihhhhhggfggghjjiihffeeffffggiiihggffffghhhhhhiiiijjijijjjjihfeeffhhgffdddffghgfffffffffffffff", +"fffffffffffffffeefggffffhjjhfddeffffeffghijjjjjjiiihhgfffffffffffffffghhiiiiiiiiihhgffffecccefgigfddcbbcdeefffffffffffeddefgihgfgggffffgghjjjihgfffgghhhgfffffffffffffffffffcddfghhgffffffedcefggfeeeffffeffhhjjjjjjjiiihhgffffffffffghhihiiiijjjjhhgffefffhiijjihgfffffffffffgghiiiiijiiiihhgfdddfghhhfffdddfghhhffffffffffffff", +"ffffffffffffffffffffeeffijihfeeffghhhiijjjjjihhgffgfffffffffffffffffffffffffgghhiiihhhhgfeccefghhfdcbbbcccdcdccddefffffdddffihhfggghhhiiijjiigffffffffffffffffffffffffffffffdddffhigfffffffedeffggffffghhhiijjjjiihhggfffffffffffffffffffgghiiiiihgfffffffhijjihhgfffffffffffffffffgfgffffgffffedcffhhhfffccdegiihffffffffffffff", +"fffffffffffffffffffdddfhijigffffghiijjjiiihhggfffffffffffffffffffffffffffffffffggggghhhhgfeefgijhfecccdeeeddccbccddddddcccffhhhfffgghiiijiihgfffffffffffffffffffffffffffffffeddefgghffffffffdeefghggfghijjjjiihhhggfffffffffffffffffffffffffgggggffffffffgghiihhgffffffffffffffffffffffffffffffeecefghhgffcccefiiiffffffffffffff", +"fffffffffffffffffdcbbegijigfffffggghggfffffffffffffffffffffffffffffffffffffffffffffffffffgfgijkkihffgghihgffffffffeedccccbdfghihgfffffffffffffffffffffffffffffffffffffffffffffeefghhigfffffffffghihiggghgggfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeccdfhiigfdccefhihgfffffffffffff", +"ffffffffffffffffedbbbfhjiiffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffggiijiihfgghiiihiiiiiihgffffffeeffiiihgffffffffffffffffffffffffffffffffffffffffffffffefghiigfffffffffgghiggfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdcbdfhiigfedcefghiffffffffffffff", +"ffffffffffffffffecbbdfijihffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffgghhgffffgfgfgghiiiihihhhhggffhijjihgffffffffffffffffffffffffffffffffffffffffffffffffghhiggfffffffffggggffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebbdfhjjgffecdffghhgffffffffffff", +"ffffffffffffffffdbacehjjhgfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffggggggghhiiihhhiijiigffffffffffffffffffffffffffffffffffffffffffffffffffhhggffffffffffffffgfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebbdfhjigffecddfgihgffffffffffff", +"fffffffffffffffecbbdfijihfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffgghhhhhiiiihggfffffffffffffffffffffffffffffffffffffffffffffffffffgfgffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdcbdfhjjgffeccdfgiigffffffffffff", +"fffffffffffffffdcabehijigfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffgghhhgffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebbdfhjihffebbcfgjihffffffffffff", +"ffffffffffffffecbbcfijjhgfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebbdfhjjgffebbcfgjjhffffffffffff", +"ffffffffffffffecbbdfjjigffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdcbdfhjigffebbcfgjjhffffffffffff", +"fffffffffffffedbbbfhjjhgffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbbdfhjihffebbcfhjihffffffffffff", +"fffffffffffffecbbcgijihffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedbbdgijigfedbbdfhjihffffffffffff", +"fffffffffffffdbacehikigffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecabehijihfecabdgijjhffffffffffff", +"fffffffffffffdccefijjhfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcbacfijjhgfdccdfhjjhgffffffffffff", +"fffffffffffffeddfgijigffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecbbdgijigffeddfgijihfffffffffffff", +"fffffffffffffeeffiiiifffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbbcfhjiigffeeffhiiigfffffffffffff", +"ffffffffffffffffghhhhgffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdcdegijihffffffghihgffffffffffffff", +"fffffffffffffffffgggfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeedefhjjhgffffffggggfffffffffffffff" +}; diff --git a/contrib/vtwmrc/images/dot1x3.xbm b/contrib/vtwmrc/images/dot1x3.xbm new file mode 100644 index 0000000..3cd0c9f --- /dev/null +++ b/contrib/vtwmrc/images/dot1x3.xbm @@ -0,0 +1,4 @@ +#define dot1x3_width 1 +#define dot1x3_height 3 +static unsigned char dot1x3_bits[] = { + 0x01, 0x00, 0x00}; diff --git a/contrib/vtwmrc/images/eyesline.xpm b/contrib/vtwmrc/images/eyesline.xpm new file mode 100644 index 0000000..673b5cb --- /dev/null +++ b/contrib/vtwmrc/images/eyesline.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char *eyesline[] = { +/* width height num_colors chars_per_pixel */ +" 1024 13 3 1", +/* colors */ +". s None c None", +"# c black", +"a c gray90", +/* pixels */ +"................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"........####.........####.......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +".......###.............###......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"...........###.....###..........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"..........###a#...###a#.........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +".........###aaa#.###aaa#........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"....#....##aaaa#.##aaaa#...#..#.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"##.###...##a##a#.##a##a#..##.###................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"#######..##a###..##a###..#######################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################", +"aaaaaaaa..####....####...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", +"...........##......##...........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................", +"................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................" +}; diff --git a/contrib/vtwmrc/images/nestedsqu.xbm b/contrib/vtwmrc/images/nestedsqu.xbm new file mode 100644 index 0000000..d6e6166 --- /dev/null +++ b/contrib/vtwmrc/images/nestedsqu.xbm @@ -0,0 +1,35 @@ +#define realscr_width 64 +#define realscr_height 48 +static char realscr_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x63, 0xc6, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x63, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x63, + 0xc6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x63, 0xc6, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x63, 0xc6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x63, + 0xc6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x63, 0xc6, 0xe1, 0xff, 0xff, + 0xff, 0xff, 0x87, 0x63, 0xc6, 0xe1, 0xff, 0xff, 0xff, 0xff, 0x87, 0x63, + 0xc6, 0xe1, 0xff, 0xff, 0xff, 0xff, 0x87, 0x63, 0xc6, 0xe1, 0xff, 0xff, + 0xff, 0xff, 0x87, 0x63, 0xc6, 0xe1, 0x01, 0x00, 0x00, 0x80, 0x87, 0x63, + 0xc6, 0xe1, 0x01, 0x00, 0x00, 0x80, 0x87, 0x63, 0xc6, 0xe1, 0x01, 0x00, + 0x00, 0x80, 0x87, 0x63, 0xc6, 0xe1, 0x01, 0x00, 0x00, 0x80, 0x87, 0x63, + 0xc6, 0xe1, 0x01, 0x00, 0x00, 0x80, 0x87, 0x63, 0xc6, 0xe1, 0xc1, 0xff, + 0xff, 0x83, 0x87, 0x63, 0xc6, 0xe1, 0xc1, 0xff, 0xff, 0x83, 0x87, 0x63, + 0xc6, 0xe1, 0xc1, 0xff, 0xff, 0x83, 0x87, 0x63, 0xc6, 0xe1, 0xc1, 0xff, + 0xff, 0x83, 0x87, 0x63, 0xc6, 0xe1, 0x01, 0x00, 0x00, 0x80, 0x87, 0x63, + 0xc6, 0xe1, 0x01, 0x00, 0x00, 0x80, 0x87, 0x63, 0xc6, 0xe1, 0x01, 0x00, + 0x00, 0x80, 0x87, 0x63, 0xc6, 0xe1, 0x01, 0x00, 0x00, 0x80, 0x87, 0x63, + 0xc6, 0xe1, 0x01, 0x00, 0x00, 0x80, 0x87, 0x63, 0xc6, 0xe1, 0xff, 0xff, + 0xff, 0xff, 0x87, 0x63, 0xc6, 0xe1, 0xff, 0xff, 0xff, 0xff, 0x87, 0x63, + 0xc6, 0xe1, 0xff, 0xff, 0xff, 0xff, 0x87, 0x63, 0xc6, 0xe1, 0xff, 0xff, + 0xff, 0xff, 0x87, 0x63, 0xc6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x63, + 0xc6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x63, 0xc6, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x63, 0xc6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x63, + 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x63, 0xc6, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x63, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x63, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/contrib/vtwmrc/images/photon_close.xpm b/contrib/vtwmrc/images/photon_close.xpm new file mode 100644 index 0000000..482ea41 --- /dev/null +++ b/contrib/vtwmrc/images/photon_close.xpm @@ -0,0 +1,47 @@ +/* XPM */ +static char *photon_close[] = { +/* width height num_colors chars_per_pixel */ +" 18 18 22 1", +/* colors */ +". c #000084", +"# c #c6c3c6", +"a c #636163", +"b c #949294", +"c s None c None", +"d c #a5a2a5", +"e c #cecfce", +"f c #b5b2b5", +"g c #9c9a9c", +"h c #e7e3e7", +"i c #ffffff", +"j c #f7f3f7", +"k c #d6d3d6", +"l c #848284", +"m c #737173", +"n c #424142", +"o c #313031", +"p c #42494a", +"q c #000000", +"r c #525152", +"s c #101010", +"t c #212021", +/* pixels */ +"cccccd#e#fdccccccc", +"cccchijhke#fdlcccc", +"ccgiiihke#fffdmccc", +"cgiiihke##ffggbacc", +"chiihe#ffffddgbbpc", +"giih#fffdfddgbblar", +"#ihefsqadlsqmbllmn", +"kjk#flqqpsqpbbllmo", +"kk#ffdaqqqtdbblmmo", +"#e#fddrqqqtgbllmmt", +"f##fdlqqaqqpblmmao", +"cfffgsqrdlsqalmaro", +"cdfdddgddgbblmaaon", +"cldggggbbbblmmaroc", +"cclgbbbbbllmaarooc", +"cccllblllmmaaroocc", +"cccccammmmaroooccc", +"cccccccpoooonccccc" +}; diff --git a/contrib/vtwmrc/images/photon_help.xpm b/contrib/vtwmrc/images/photon_help.xpm new file mode 100644 index 0000000..cde77c1 --- /dev/null +++ b/contrib/vtwmrc/images/photon_help.xpm @@ -0,0 +1,47 @@ +/* XPM */ +static char *photon_help[] = { +/* width height num_colors chars_per_pixel */ +" 18 18 22 1", +/* colors */ +". c #000084", +"# c #c6c3c6", +"a c #636163", +"b c #949294", +"c s None c None", +"d c #a5a2a5", +"e c #cecfce", +"f c #b5b2b5", +"g c #9c9a9c", +"h c #e7e3e7", +"i c #ffffff", +"j c #f7f3f7", +"k c #d6d3d6", +"l c #848284", +"m c #737173", +"n c #424142", +"o c #313031", +"p c #42494a", +"q c #000000", +"r c #525152", +"s c #101010", +"t c #212021", +/* pixels */ +"cccccd#e#fdccccccc", +"cccchijhke#fdlcccc", +"ccgiiihke#fffdmccc", +"cgiiihke##ffggbacc", +"chiihelnopbddgbbpc", +"giiheaqqqqqlgbblar", +"#ihefsqolsqrgbllmn", +"kjk#fblbaqqlbbllmo", +"kk#ffddrqqmgbblmmo", +"#e#fdddqqmddbllmmt", +"f##ffdgllgdgblmmao", +"cfffdddqqmdgblmaro", +"cdfddddqqlbblmaaon", +"cldggbgbbbllmaaroc", +"cclgbbbbbllmaarooc", +"cccllblllmmaaroocc", +"cccccammmmaroooccc", +"ccccccapoooonccccc" +}; diff --git a/contrib/vtwmrc/images/photon_maximize.xpm b/contrib/vtwmrc/images/photon_maximize.xpm new file mode 100644 index 0000000..af26377 --- /dev/null +++ b/contrib/vtwmrc/images/photon_maximize.xpm @@ -0,0 +1,47 @@ +/* XPM */ +static char *photon_maximize[] = { +/* width height num_colors chars_per_pixel */ +" 18 18 22 1", +/* colors */ +". c #000084", +"# c #c6c3c6", +"a c #636163", +"b c #949294", +"c s None c None", +"d c #a5a2a5", +"e c #cecfce", +"f c #b5b2b5", +"g c #9c9a9c", +"h c #e7e3e7", +"i c #ffffff", +"j c #f7f3f7", +"k c #d6d3d6", +"l c #848284", +"m c #737173", +"n c #424142", +"o c #313031", +"p c #42494a", +"q c #000000", +"r c #525152", +"s c #101010", +"t c #212021", +/* pixels */ +"cccccd#e#ffccccccc", +"cccchijhh##fdlcccc", +"ccgiiihke#fffdmccc", +"cgiiihk###ffggbacc", +"chiiqqqqqqqqqgbbpc", +"giihqqqqqqqqqbblar", +"#iheqqdddddqqbllmn", +"kjk#qqdddddqqbllmo", +"kk##qqdddddqqblmmo", +"#e#fqqdddddqqllmmt", +"f##fqqdddddqqlmmao", +"cfffqqqqqqqqqlmaro", +"cdfdototottttmaaon", +"cldgggbbbbblmmaroc", +"cclgbbbbbllmaarooc", +"cccllblllmmaaroocc", +"ccccmammmmaroooccc", +"ccccccapoooonccccc" +}; diff --git a/contrib/vtwmrc/images/photon_menu.xpm b/contrib/vtwmrc/images/photon_menu.xpm new file mode 100644 index 0000000..0d2c48c --- /dev/null +++ b/contrib/vtwmrc/images/photon_menu.xpm @@ -0,0 +1,47 @@ +/* XPM */ +static char *photon_menu[] = { +/* width height num_colors chars_per_pixel */ +" 18 18 22 1", +/* colors */ +". c #000084", +"# c #c6c3c6", +"a c #636163", +"b c #949294", +"c s None c None", +"d c #a5a2a5", +"e c #cecfce", +"f c #b5b2b5", +"g c #9c9a9c", +"h c #e7e3e7", +"i c #ffffff", +"j c #f7f3f7", +"k c #d6d3d6", +"l c #848284", +"m c #737173", +"n c #424142", +"o c #313031", +"p c #42494a", +"q c #000000", +"r c #525152", +"s c #101010", +"t c #212021", +/* pixels */ +"cccccd#e#fdccccccc", +"cccchijhke#fdlcccc", +"ccgiiihke##ffdmccc", +"cgiiihke##ffggbacc", +"chiihe#ffffddgbbpc", +"giihaarrrrrrrbblac", +"#iheaqqqqqqqtbllmn", +"kjk#gsqqqqqqlbllmo", +"kk##daqqqqqpbblmmo", +"#e#ffdtqqqqgbllmmt", +"f##fddlqqqmgblmmao", +"cfffdddnqtgbblmaro", +"cdfdddgbqmgblmaaon", +"cldggggbmbllmaaroc", +"cclgbbbbbllmaarooc", +"cccllblllmmaaroocc", +"ccccmammmmaroooccc", +"ccccccapoooonccccc" +}; diff --git a/contrib/vtwmrc/images/photon_minimize.xpm b/contrib/vtwmrc/images/photon_minimize.xpm new file mode 100644 index 0000000..81d92f5 --- /dev/null +++ b/contrib/vtwmrc/images/photon_minimize.xpm @@ -0,0 +1,47 @@ +/* XPM */ +static char *photon_minimize[] = { +/* width height num_colors chars_per_pixel */ +" 18 18 22 1", +/* colors */ +". c #000084", +"# c #c6c3c6", +"a c #636163", +"b c #949294", +"c s None c None", +"d c #a5a2a5", +"e c #cecfce", +"f c #b5b2b5", +"g c #9c9a9c", +"h c #e7e3e7", +"i c #ffffff", +"j c #f7f3f7", +"k c #d6d3d6", +"l c #848284", +"m c #737173", +"n c #424142", +"o c #313031", +"p c #42494a", +"q c #000000", +"r c #525152", +"s c #101010", +"t c #212021", +/* pixels */ +"cccccg#e#fdccccccc", +"cccchijhke#fdlcccc", +"ccgiiihke##ffdmccc", +"cgiiihke##ffggbacc", +"chiihe#ffffddgbbpc", +"giih#ffdfdddgbblac", +"#iheffddddddgbllmn", +"kjk#fdddddddgbllmo", +"kk#ffdddddddbblmmo", +"#e#fddddddddbllmmt", +"f##ffqqqoqqqblmmao", +"cfffdotoptotblmaro", +"cdfddgdgggbblmaaon", +"cldgggggbbblmmaroc", +"cclgbbblbllmaarooc", +"cccllblllmmaaroocc", +"ccccmammmmaroooccc", +"ccccccapoooonccccc" +}; diff --git a/contrib/vtwmrc/images/photon_rarrow.xpm b/contrib/vtwmrc/images/photon_rarrow.xpm new file mode 100644 index 0000000..abce6f2 --- /dev/null +++ b/contrib/vtwmrc/images/photon_rarrow.xpm @@ -0,0 +1,19 @@ +/* XPM */ +static char *photon_rarrow[] = { +"14 14 2 1", +" s None c None", +". c #000000000000", +" ", +" ", +" .. ", +" .... ", +" ..... ", +" ....... ", +" ........ ", +" ....... ", +" ..... ", +" .... ", +" .. ", +" ", +" ", +" "}; diff --git a/contrib/vtwmrc/images/vtwm.gif b/contrib/vtwmrc/images/vtwm.gif new file mode 100644 index 0000000000000000000000000000000000000000..aefaa10870cdd3ac9f32e06b468450751736df79 GIT binary patch literal 85816 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/images/win95_close.xpm b/contrib/vtwmrc/images/win95_close.xpm new file mode 100644 index 0000000..4b05d76 --- /dev/null +++ b/contrib/vtwmrc/images/win95_close.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char *win95_close[] = { +/* width height num_colors chars_per_pixel */ +" 15 15 4 1", +/* colors */ +", c None s None", +". c #000000", +"a c #acacac", +"b c #ebebeb", +/* pixels */ +",,,,,,,,,,,,,,,", +"bbbbbbbbbbbbbb.", +"baaaaaaaaaaaaa.", +"baaaaaaaaaaaaa.", +"baa..aaaaa..aa.", +"baaa..aaa..aaa.", +"baaaa..a..aaaa.", +"baaaaa...aaaaa.", +"baaaa..a..aaaa.", +"baaa..aaa..aaa.", +"baa..aaaaa..aa.", +"baaaaaaaaaaaaa.", +"baaaaaaaaaaaaa.", +"...............", +",,,,,,,,,,,,,,," +}; diff --git a/contrib/vtwmrc/images/win95_menu.xpm b/contrib/vtwmrc/images/win95_menu.xpm new file mode 100644 index 0000000..40d8efe --- /dev/null +++ b/contrib/vtwmrc/images/win95_menu.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char *win95_menu[] = { +/* width height num_colors chars_per_pixel */ +" 15 15 4 1", +/* colors */ +", c None s None", +". c #ebebeb", +"# c #000000", +"a c #acacac", +/* pixels */ +",,,,,,,,,,,,,,,", +"..............#", +".aaaaaaaaaaaaa#", +".aaaaaaaaaaaaa#", +".aaaaaaaaaaaaa#", +".aa#########aa#", +".aaa#######aaa#", +".aaaa#####aaaa#", +".aaaaa###aaaaa#", +".aaaaaa#aaaaaa#", +".aaaaaaaaaaaaa#", +".aaaaaaaaaaaaa#", +".aaaaaaaaaaaaa#", +"###############", +",,,,,,,,,,,,,,," +}; diff --git a/contrib/vtwmrc/images/win95_minimize.xpm b/contrib/vtwmrc/images/win95_minimize.xpm new file mode 100644 index 0000000..2c52ca5 --- /dev/null +++ b/contrib/vtwmrc/images/win95_minimize.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char *win95_minimize[] = { +/* width height num_colors chars_per_pixel */ +" 15 15 4 1", +/* colors */ +", c None s None", +". c #000000", +"a c #acacac", +"b c #ebebeb", +/* pixels */ +",,,,,,,,,,,,,,,", +"bbbbbbbbbbbbbb.", +"baaaaaaaaaaaaa.", +"baaaaaaaaaaaaa.", +"baaaaaaaaaaaaa.", +"baaaaaaaaaaaaa.", +"baaaaaaaaaaaaa.", +"baaaaaaaaaaaaa.", +"baaaaaaaaaaaaa.", +"baaaaaaaaaaaaa.", +"baaa.......aaa.", +"baaa.......aaa.", +"baaaaaaaaaaaaa.", +"...............", +",,,,,,,,,,,,,,,," +}; diff --git a/contrib/vtwmrc/images/win95_rarrow.xpm b/contrib/vtwmrc/images/win95_rarrow.xpm new file mode 100644 index 0000000..9c88f85 --- /dev/null +++ b/contrib/vtwmrc/images/win95_rarrow.xpm @@ -0,0 +1,19 @@ +/* XPM */ +static char *win95_rarrow[] = { +"14 14 2 1", +" s None c None", +". c #000000000000", +" ", +" ", +" . ", +" .. ", +" ... ", +" .... ", +" ..... ", +" .... ", +" ... ", +" .. ", +" . ", +" ", +" ", +" "}; diff --git a/contrib/vtwmrc/images/win95_unzoom.xpm b/contrib/vtwmrc/images/win95_unzoom.xpm new file mode 100644 index 0000000..22ac6ac --- /dev/null +++ b/contrib/vtwmrc/images/win95_unzoom.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char *win95_unzoom[] = { +/* width height num_colors chars_per_pixel */ +" 15 15 4 1", +/* colors */ +", c None s None", +". c #000000", +"a c #acacac", +"b c #ebebeb", +/* pixels */ +",,,,,,,,,,,,,,,", +"bbbbbbbbbbbbbb.", +"baaaaaaaaaaaaa.", +"baaaa......aaa.", +"baaaa......aaa.", +"baaaa.aaaa.aaa.", +"baa......a.aaa.", +"baa......a.aaa.", +"baa.aaaa...aaa.", +"baa.aaaa.aaaaa.", +"baa.aaaa.aaaaa.", +"baa......aaaaa.", +"baaaaaaaaaaaaa.", +"...............", +",,,,,,,,,,,,,,," +}; diff --git a/contrib/vtwmrc/images/win95_zoom.xpm b/contrib/vtwmrc/images/win95_zoom.xpm new file mode 100644 index 0000000..afd9c97 --- /dev/null +++ b/contrib/vtwmrc/images/win95_zoom.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char *win95_zoom[] = { +/* width height num_colors chars_per_pixel */ +" 15 15 4 1", +/* colors */ +", c None s None", +". c #000000", +"a c #acacac", +"b c #ebebeb", +/* pixels */ +",,,,,,,,,,,,,,,", +"bbbbbbbbbbbbbb.", +"baaaaaaaaaaaaa.", +"baa.........aa.", +"baa.........aa.", +"baa.aaaaaaa.aa.", +"baa.aaaaaaa.aa.", +"baa.aaaaaaa.aa.", +"baa.aaaaaaa.aa.", +"baa.aaaaaaa.aa.", +"baa.aaaaaaa.aa.", +"baa.........aa.", +"baaaaaaaaaaaaa.", +"...............", +",,,,,,,,,,,,,,," +}; diff --git a/contrib/vtwmrc/sounds/applause1.au b/contrib/vtwmrc/sounds/applause1.au new file mode 100644 index 0000000000000000000000000000000000000000..8727229bc5a1b9d53455c1cc30acb32cf4ae65e7 GIT binary patch literal 40112 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≠+T1lBCg=?s-@tCerSRbXtLC)YuC;W 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/applause2.au b/contrib/vtwmrc/sounds/applause2.au new file mode 100644 index 0000000000000000000000000000000000000000..d1e3ff58bc3478e1294995eef1e401a679ac8330 GIT binary patch literal 73761 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/boing1.au b/contrib/vtwmrc/sounds/boing1.au new file mode 100644 index 0000000000000000000000000000000000000000..f736fec2e01342abb555e4d06bb3ade96b71e1e3 GIT binary patch literal 8615 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 I|HuOW1AdnUR{#J2 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/boing2.au b/contrib/vtwmrc/sounds/boing2.au new file mode 100644 index 0000000000000000000000000000000000000000..bd73296ff42d9326bf953bb9f79b8dd9d38fca8a GIT binary patch literal 7257 zcmd^@JBzH|n#T8hkAVtycU9L#Ekr~_WDE=pj0}xt7?4TM1Oqc4r-Qy#*HuIc5fKaw z42%r@0Dg=$zh(FSpMChB1C!69+1=Z!rSIi=p7&X*|Mi!D|MBC;&mTYj+2r>>{rIu? z7y0|&{_{WnlIZIH{Of=J5Wm*M67nbXhpMQBshj@PjcuQ%d1GnI2gRLkZ@1@{LGJKO z?P0NXMEdgl{Ct`$bzu*}S2jCuO7rva`FV8qKX=Q;a^UaxVsy0Wa?P8v+AS78ZIOh+ zQ_ViT9z|&E4X@*`x5M*uIvVP3XNN&s2;o0177wQ0_aCq6ICrjFG-tENnmGUK>wbKHgc^%X^(((jw1? zDYnn=UJ7P zb&+NteC_3YZ-k{h?sluk%}zJ0DB6c zbR{Y7*IPb?jwrG;Z$(!XV-z~J=u6@7K+VmMA9WOjp6b-6bJ~UCau@mM`*RgJwr}p$ zsjf>A7^-IIL0=`pUmLPZk-zo&F)y30yk|vQlwEqd3p*(bYwu6@_iK@kzU{lN8-{D$ zb1fr^L*Em#gm_V5FUsaAV)rwN04BBCrh2ZF@89>;8UxKIBD}SbM{F`m(glXsXgE z>ift|Y{ea`d=PLNHb1=NQ_~DXT@+Pzy=BnW zv7)}ScB`M7;YFcshLKBrZC&LBwUKblZkMzfCRZ||=!YqCoG2D;QFJ2Wk7??=cASKz zYQczF^<$eC3D4x32wh88cblCy$K6e|^Yn4N-rJJ8q(#+(tFA4(u^&C~Z$7GSG}dF} z?e~^HmTeLS3SAoOMzqu3juFS(=c$^Kq`N&oUrR{liHV?+2!{Gz7=^x{q<3LjF0|}J zXRoSz)Ah+o43h{0QIusv4}z#q56^EOuSbfPSDi=%Xr%fOQjsX$J3(M7W+Y@oYSTsM3aMtE^&!qXgU}_eo?d;yEbw4eZV6VOWCazBOIs1vyHv$xse!( zJVi*#rpd17Pk?+(Xc0k%ZHz9n<|VFm+9&C?d{{z#ERxI zW3n8T$r@6j1k`~YKoK05!nEmRk(OY1>Z-D?2e7_dtbkSArq}dNVst9K7G<87MSA%> zUdqHV_NK*biA1C>AJ%3#mGvMTMGeQk>ANbgo1)IrtdC<6IlhcumRE{b*EOKCE-MtU z8Im~id|O$s_m<~aPDq#hPz+sDHo{a*k)2;(KR$2eI7qnl)G>1HXlPpU@U_Ly{gCAq zoO3iINsq6e*EX_rMK?X*8QO}XZ1k{6k=WZUr4{ejvH@%KKzUj|Y$8;9icG^W0#G&v zsu8v2{r36#SqtBGgCR{DAZTbhCe=a0|hIW79GN#8!xif<;4wp;Iff~UE@_V}=ki?_G)`2rbxD$`DpXQ)mX1!!5~ zNtU%peAfU4S-KunL{Ro}xn`XReaBF@tFKTTr;>{J78pPu$x4n-_Pd5^ z1&J8yeiE_oL|t7~Gcem6J#U-?d#Yh=#f>?p4zc!t^Ro zM`Lzj+&&*j!6L#YP3wel3o7(TgihEMMZ+FO&d{}z7ez+cd>0lCkej<$cHC7J2BvFk zW@}Sb)vP`!l&xAZ${cJ9=mDaBz#o<3`2aP|gs6 z7_0PpyFNn^Zcbb;M zHffdTIi|W^J^Wm0#2f@+gjU_}Rog=l+LdKRRpj>qkztiUK0*B{y0+V?Dl$9cmjEYn zsPKnbUKID7Tri%8&(rPRhc zmRUu@V z78A26?xcUcoIVdn{3qEkOi?>WQ#MaePdw&vxwS&ZEVGx519EveA3u*L#7Zt)xVhIU zo9{V>Zc%pNg#$E9`BxN2VLX&Yb~#9^^maJka;9zKVhZ-A11=0*mp_*6A|ic1jN>$P zH69q#LSOT`8%G8!o%9^JpmP#BkifKT9tjmN3KPJ&9Ny+f98-o8kcp5tb^G-A_@rny zyF}u_iDZ(L>6!+7lL!bnr+4@>ku%2$(m>R33wu0^=`sbq06No-zOC;mN_oEBF6Zkl zEl1&6F1L;By}H|O71L$%qhH$I2tjn))!FU(`EfYOv395ZFfW0=xFJOcEbG;iYR+&3 zR%nv^8WdyN^bnglGV3TJ2^+E0=)-Qi+Z!f2MeCZo92KlAXMWugEomKOXMJP$09Af& zEbKIlDAMzRBhlM2Eoxk*4nS3uFP_jsa4F&0P63*++bVlqM=z-+mn9Q17E%vztu@@1 zx5vpSyWJLGJnihbL=eG^q%8EC5Fbo~%n8N-!_)O%i@;?H?=}$X;YnqH@d<%*d-|JZ zB{=qStVu;gQdo!-V#z3z zMdQ3c=$_7IDz40Y3lQxaSbuwYc|TtAF?2Mj^t8nz4Q*Y*Qs#X{t|GMdavPH2Cqtc{ zrBakk5thUW!+;5gz79PXC7Tl1PGGXnMa!^}BFtHFwh|RSse#=6n7GznQ4ERVvCDz% z>+8$Q>-#BfWZzbg4-XGZY^q^<5Ealdj>?9}P-oOQ@+IG4hg2*U2q^o=ksBW$<#BSc z+8S|Jf>X%${PIR?Dj02SSC4A|I&Yu4?EL;p{%ObP#tCxr**-ojw|h?%*VE@|)()AI zbc*=jXrkf;W9Z}U6#}R5ms6&)WpOTDEH~II;3(sfNZ?#32WKp&h6Hkr&6F@Lhs0Lr z9Y5C^s^6kK@)No3db`)O(kB#!(dBb&@Vp=%cqr{WV5iM=4=k7=%L(qjzPZ0 zxt`g8y&bCb2-f9#ht~}W&TM#Ct#`U3dyI92{+uMgoEqIE)L5|bd_2o?GC^GjND<0r zv(>D4VkTWqRHg2a4ko}519RJi2M92B2Sv<*V#jTn5MXjnpX8-1pH63aVA40TRII11 zgan@D@G7Hx<5R#!x>A^<4NgS2qltdO~z<&!DkkU59O%wT#YU7crqbJgk&q-5X2! zc81gV@y06-!Zehp)ste_u|)bEwUHE);}qp(@djpuRx)iMfLL^>5F;HDZMQo`lLnfz z9F#tOp0Q(744U`ao>-8QxJQJTAt;yZ}L?f36h^{NT!^Gn1l-5+~kVW&{8ra3Db~K_6M%`^4L?XO=%~_q-0l z8Y5+&c=sD`oe*Z`1IKJa88`=>FWm5sXpl7^lD-Mi$EQmRT+G>L_m*>}Me-Xwi|Hqv zpU#Jm59t-@9LFzod%eYuO;^CqGsnCZMOXtH_be zTzU{*-@y`E4n;TyNxLfxO)2ww3gml--EIzp7Z0)`3`#sV6rC-b=LZ2^2O~NQIX0RE zI5uH$IS!O)bfLe8m4ej$ox zexv-Yyc@5fW*5xS!ZL9)PAKgwCLCEq^l>D<>$vz4Y2$c{Neh_QL?K5BaE5do(Rpbm z2ZhwLS%G*G;u%Qr$VC`(Tw*}jCpTdw9NV@XY)*_lLv6vRt5K|f_;m^75G=9t81l#kq{PnN|5>T(f_99mV!l;lJ*`>KR4AUE;^E@LNa z46rY|*5j`+VL0r0K~*xIvxIl+Pz z_Q}i!xl5kZ*e3UVRdc>Bo5$yKSHB;^D4g^8Q_W}C@g;)zl6r|VjL&aNKH#_i653qH z?@Pb_o}Y-b=Q5ooAbB{F<)1H6blISxCci3ovu51MTg=s9kL3IBYr->sZ~ngB zuR_7JuZ_PR|NFMT{yj%OgF#YLuKC&DyQNNigPic?lfLiy>jv{hS)f0E^y@2s{GOjO zKkw_(_y7O+{BQpFdeC39l^vwLzY6sSS-1)0_;vaBTYOjj*Cj%y>GS$6hp+g*v!eGv z=j)kYb(w4U_2;kqeEt58{cp4W?TPXczt>9MWA5nRi}d$f|9aT3-@kt*Ni5gzH~zZv a5B~kSiTw8;eBn=*|Ic6i)6V}F7ycKpzgYMH literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/boing3.au b/contrib/vtwmrc/sounds/boing3.au new file mode 100644 index 0000000000000000000000000000000000000000..551557f702527f109b8a2553fcb10f98e782f2c0 GIT binary patch literal 5691 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/break1.au b/contrib/vtwmrc/sounds/break1.au new file mode 100644 index 0000000000000000000000000000000000000000..28a4bfda848cddeddb9c3b621d2473f574945e32 GIT binary patch literal 4700 zcmbtXOK%*xcJ?@)v1N}XKgO0U%MvVG)>~a^G#W~yP)IFmQ46lPQt_D6?) ziid8z9yz||)~0TMfBbU(M)m5i+xLoB>-qP=%`h0+-}?E{;m%rmYx&j8d3z|h`}@r& zlXq`#{-t+q{O-tuYsv1-{`$|mlQ%c^hJJ8Y*KU8mxoOw`XKZwC=*_x0emj|6efQz| zq*{MBa>KnDo+U5;a(KVLGo0>??H=8~O4ojz?(NQG?*eibp5;eJx1Wwbyz^mpWj(pt z*&QCfxt)z4?9Ys{PcI*Sd~*1=hvT)4jrPXOl-g$C2lYLY2o$R)3MEs z-NyRj7+?SUEAzvxlim4i?$-79Ten7knL3xn@WbIwYiQ)~$Ll{%y!?IWyL_#@`snvp zuUCUR!=3&xd%JFjAB?Z1J9Fp1zT5eE{SJR8-fTzL$9`M;b$e-kY=SjzKOW6{_vEd= z&W+!AVAppyYb!&mhkHBU&Hc^(@WbimUq@@_k1BR!W_a|s?EdYe=IF@PQ8xMmJ)KpTEFi-a>s`srw-22*4(b>6~}Mhk?n4?&&=cKL)ju-dDIroq}^&9 zxbsTCU3tQevbme|B2QPwSMrHxU+$mGu&3?%%=1UJ)e)CfMrIZo_ot?7il?&;S5F?e ziC~2-jU~0^MseqKD-BmV!Az&&CeDJ&dABIyyzDQ}=Y7$#@3*?<{kyg}{}fEyqgMX5 z=|#mDRqS=i!Kei&E@H~94Bw) zp72kk5|}U@{UViaFNo82eI;micxs!K=~{ET8fdlrNodlZ{hB{GTT0tOuM8EF0ehia zR7qjBq$l~HDm%JS2=eJ(CknI~r~m)4!0&lGJ{)Hi4N#{AolkK5s1nr{Y; z-D>I7#T)x#`6z3bL_8BaWWE*jvZ%7RQ*YYU!}9ffnLd7T^5FRMVLGKJsQYP&PPc0OqSw)od#dYe!Wm`={cKS4wgUcZBOTlKANmfhvVa9 ze{u4ud;j%W@#4#TrIR@R#GZa0t@D!?Q9V4$({}PXl3xzXIDNZ!+DUh}>r3M8*5q<+ z?YCgMQ*3366K@a5*Z%qL#8i8yHec-I!NhL27=QHX?0Kl)ci8-L+pSE*EmE7CJ>^ks zRZy|3EpX2DEIExOb6>S=%xapr@WVx|O`9y}tCE-^JnZR?ICVV{l#PY%$;HyM7q$J; z_N(>K9H%P_i@7M~D#dI)jxnYXCB_g*3d^;V zaikc}qSJnthprUHlx0iEPaQ=?zjtyWzI2@uou+K(?X$KJw$o{gj$@s6shBOOzG&s8 zBBJj!@AtVgwq!JR8L7l9PD2V`RwM0fu}agr3nSJ@8)3Cp&@iY)Y3iy83!~6FO9EmU zXN2gs)nXO48(A967@2iTmy4V^C0&&DOCfvbUFpt>=GQi@RjoMN?_@=uo4#^=YYSTn zsK}*g>Qmn6ODdiFs3vP)T3u65#6p-d({GbnStDSC?q$y>z6c%9G)kU4n{(}~k(>u4 zc1zs4bSYM(9#NI23$@hokY}9N>W-_hYACO#S<(K?Ni`9rig}w+s~l${X%%7aRO`G0 zjyp?P`y_)CnahmpJ7aWH_*lv!Z%D&)V+@t*yjd8>ly*)Tn{_24DNlox>)i4Nl_iI7 z(j{7pFs5l32Z&NoV=jtZoN(loJI1MtBg%r55htW^Hf3%#0uLkNIE^iS9Ce~-7{|G^ zh3hNKFv=8ly-d3#N-ax!h181Wn%1o{Ov$dcNvfoFTx!fLSc20L z6$5GJG?Xv`twLEsU^J!Pa=dYvMgai@1(1h!SjS-sak{h&hvGv@EI}LybP#hELGc+@ zoWW~9f#5^HtB?+{QiDlsR>HsePg#PEgAc4*!EkD)A}#fNhugFbBUf|8)d^-aeh?$c zu%+iult>{{krlQ}xg;Xt1;bpA8o~sTmX$G-v{IMQoa)jQtK8B&aycvFMAD4#w&|y7 z&O{uejMF4*xRkZHWwhye1v+cjLEL#iWHuIYDovTVLiMQ2P*{khe6>*~AVJ0v_a4mW z*krgOsqs!&D4<9wCq|S!)x-hv$T>p<5}*;jgNu~IbCDBMoj*RTAc~m_Wv^yww-LEA zV3`bBjx<`l&@}AFoMu!@6i>YU6!&vIN=4r1TxB3=*0eTwtTf_jD z0^EmQFATbZ$qpD}E=LGJm(*D0Yl0_J3JKr?#S!Qb{!HlcFeV0uaA-o%z!VCeQV(=z z^Gq|&L1XW<(^|t^)Lldk!l?8fThNJ3&Sc1lFHDT*$V(bA&`iP!FAehusEH;=D1~B< za^T8Bs^ZdB$3m!w5+FmCh>ZierEnz0Ixvh(dlyhUfevpm*Ci5(fXc!0pmO2Dvfu!s zizlE2F=M=xHvu;LP$P~5F9(wfvRE_77$CsC0QC7eXS}0`wO8b2AmH_RHhF*l7&wTs zLENDEkE5_O$RnN_k@E8Xzt{9_qdx(2-YBo!+Xj;QH;l^}ydb;CGOidLjUTLt0TEz7 z2UNUG-dDc|>IQbhp3Bd{DqaVl124bLL+lZkwMPHhy~z)Mgt#4n;1IKbBIO{mwVx8 zkwvylNH!?vMKZJ9h?*qovH)EP3LbSO{>Z?MY$emH%9s#M2m@%sLgSv`fNF}Oh1jAR zc`MPA+Ds=odK+{?RA3p`HYy$(2!mV1psPi#8PLR0@P>2GTF-xU&P+0oGTdV@7gvoZ z7eLFYKzPtAc`PHL##%18zYAn&nISj=USh@1Srco9;*M&DC%>c$GU{vuGZ_8=LN5ey z&k`gImc)o2)~ue{2%!)*xdjC literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/break2.au b/contrib/vtwmrc/sounds/break2.au new file mode 100644 index 0000000000000000000000000000000000000000..dc6ec982e69723c9c7ec63fcab2e8a31b6dd359f GIT binary patch literal 52787 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/cardshuffle.au b/contrib/vtwmrc/sounds/cardshuffle.au new file mode 100644 index 0000000000000000000000000000000000000000..ccd7b7e76af05bb29dcfe2be46e2046eb3c9fbbc GIT binary patch literal 26169 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/cashregister.au b/contrib/vtwmrc/sounds/cashregister.au new file mode 100644 index 0000000000000000000000000000000000000000..5e310abbad410484f1792d1325c1dafd5ffaa33a GIT binary patch literal 7946 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 JpM;6X{{kAIJ!}8~ literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/chime1.au b/contrib/vtwmrc/sounds/chime1.au new file mode 100644 index 0000000000000000000000000000000000000000..ddda79b0ab8ec7ebe332841fc07d1711ad980395 GIT binary patch literal 5529 zcmeH}y^ia;5yv+VkvhOhPVPPD?yeofFbu&EqC$lVRVq~lNuZ=ingBPCv%ucFyZ$y| z2!cQm0$8w6!HOjxfR8cx54C5{CP|K0aDQi|tYPkELXbbNex*!Ib%WkLG%crs+U{3YX^>LHW84p5$?B@nMF zQM#hGvtEnNmg^OX!)~_|^{0<>((UuNw;T^73*DcOPeNu;%!Dq~!K)quaq=p0;5=Tj#Y`^0GV8>`tB}ZL)gQ zmh}1AEoTC9ozJN zBSkMei9FTS*ur+(jd^8_Cmgan(()dfYwGqQEbrI)D2UYaQD=F@=Zxo_sFo{ou0J0- zoZVotBysE^-kE$8+Lwb$SCzC?X3obk-&9fvs;v-X6;%YQrJ*b*Bd;$=-=?UcBcKdS zxh6AEHSQjtR5DxANMv@;qMFZBr?ltoV>d34lWFYbi-MI;I!0 zm@gY^WGjTMm$TAo@7mqLvbWB8b^1}z-7F0u*!FTVoB1ZV5cK8LQIS=MHZE36S!s>+ zV=FpJvLJekQ+moaq=j_&z;YU7uZ%|NB)D!Z%BDAU%6?m`uUASD4sETv9J^{cZ)6XB z*LKX;nODkMlu*DOBR`s97zrLaYf;3eDamNt)S>TOfeX>YTU0NlDWS{*U;YxQ?XOZ> zhX^4wX6TUc6uEL*bwaobH%a5Bm>vmOWq#1k_CnYK&X~alXDn4!6WDw^;!bgD&7fJE zwbnz;KqU&dcUUnavr;3c`(Y7B1tGj1uad zmbf2{Q`m}gLKU~Lh$E!JBL!>&?l+3Ub3ABNgKuhY9HOMIy+;SM9+jyP5LnCGQ7DFE zP?ZRt!!I4`vUW%bSt&zNpb+>S5@j7UbcfM6SdR1fEXX+aJs1<9UK(Q|+WSmD8+PG?9KFkdbdMd}l>XE7%XYnb}&D-(eQGfVicSlx&pZEu9 z#~RzkCh@1|gajKcL#9}q<*>`b+ZZY67};EuE6m`0!rZ{Iz~$E-RtMGr`&ckW0slrV zfgN}aw>R(>Cd3Lr3xofY30Ogx9IJ|^L%HG9@acHGiRMoKu^|-%In*At0;AX^NU(C$ z_armf&mKp+@Xusi{BkUZR)eDDh;Z~YOGjg)1JRL5cBFWLbexYYPS zDYFP3Zah=Gkp_e;Rse?`g8U8#5nSv=j8Grc43V!h@bz>#9NK2JPD8uhPkcom=p$c! z^6h8vb^rKqh)Pt}v_IL2ujcZ+LxTo&C% zRewJ9+761qRJ357o#4OG+)14W(Xjv3V*&LQ#@1va#1^~Tq#$g_#Bon6c#Uym;@ z*NLw#@^x{0SLxQ;%a7pe9IeNz?y|emjKJ4&lc5^~(z|E-`D3EM*S767Z8jubRSj=^ zHQjD6Hy9FV;_D{CNMY8AdYSl2)rQn@OhHc}!B-?};%j3&n)n*@d3&V$d+Kx@z}ISd zU+AMEx?l>(@|tTQ@)ZLT_sgbX%Wd$kbYp6H4E3bS_B401NgG=Y>#Mk{XEbdb7E^3eRn$IF% z&)XAf08y|LU$c_=+FgX1_}T<NRp6@xUpX9+ucr>-ZKSe(xVG@H^lGrS2Va3t?vumd-uT)X1fThe zQKko9gX+f+B(6Z3dU-{mGG7ZaEk;Ui2$8R`+)|j2xfhPRY@LJc;A`8u4187Ejku?g zufrQ(xg$lsqNkufjC#jc3BHo;ltWRXm*&;PS2WqWY4vA19KsflbATe?vVKg<3H(VHBbl^YioMsI~fv#oJ22M?001KPNBco_pk^oqlQyz(@KoM0V6MesR6aTekwY=(kq ztibLOw<$&u?=b`Tj(cDed}3>OpkjSE8lFZSocbwpY#k3K*uaAE!l3N%@G{RGUu!L{ zdcHPskt-=4!kXfwGKCV?C_0Fm;=1AkaUP!dh7S$_a*IFNEjWuq*f4C0bs1-u$vlqb zq=G~6>UMOPb>NAW$aRY1oC|0@C1AWhJx`h1O5eKz23`T#U?xm~&A~y$46ke7AVdVIWHMZ$b%b{07}%mM&>To(WDcyU)d8W%budp` z1-l|kkrrCM)&s0X-oO$q5oRJj;L!$XOOQ4J=tI;DSc>)s1?ms2Ke7XjfN|;#&?vBH zlj_klBnO$TrK!0f7o7{gt7&j2nvS$p_p4WtJ!l@Bpa#Rs=yk-X_EAMN3H<}hs|`UH zGzauj_1af76M<^Jnue^wTEituA2=4fj{H%+D*31ldkbqS7+iuaM>ea7dI!CUwb0U( z?qDKz2{e$OYMb#27^$eTf@I;--~<`h%J3poRAS|=Xd-?C#>zF|J6u8avR(O&wZh)0 zm*qK#o(KaIrRl0dEWx8>moyG-Kz4_(#LHSs;&1GfJXAW27LduXi!>9|BwHho#4MS| zMWUZ_PpXX8qFR97LM7!JsS+C{Nf5CFx;bpdN2(jB1-K}kkZ8OiHBOat&o23dh{P%Q*h1SL~hOCbfh$Zn}c3q-oftvY3emyd2))N2s?=x{vAp<0`G3p+DJ{j+C%Kf1C=m(0~ z-l6C|3xhZCEayt}{S4!UMxG;hf9q(Z*!f0iWHjhWKF;T*W?2?!Q(XI$6Q;XVORtH2 zY8Y&(%q#ZO$iv`i#1Q*qU$*Ir1@htcfhZc3iRtWT`QqTGA@hXk@N_|N@eXZ>Y>KWJ zq0_&$tSB%$8cE;l`9XhQa)A=>g9+Poksl>)Smkm-qfV^WlvL^H{KI< zqx{b^qaTldx8X@)zspq`_RMULzPMf1?eOla8*B$~Y($OT_q0V}jSh1ckJyL4*qpj< z!0s-G#(cRl`hAz9#NLxt8-`375kIbO$#3z^4t`Ywx8uj?@r$PpsFmFpKfUv*`=2XU z-gbSLted!hi2i%E+?i|JZ)q)TR6EaZ_}9}qCn{P_A3S#D&WUGTI$rC!bJ*}sgy{LpFLViVQIJN~}&c>2Bj*9J7%TW&^=mR+%*OZ~QV^lDAxJAd_I z=Q=JkFqNAgUi&Qj)s*MMTR*DQtof-X_V>L?zuZXtFCn(7A-dD}U>XJfv8t@I%}zWMhSEgdhA<9CO=oQI9@DQz6Jn%k}fcg{+B z`%m_?pRT$CD^G5mRyU^LvcvbJ-Lty}939XwsNp8%XwZqf{!hCdr+z(Xbi2ZcsxPWc z{H^n(e<{v3hMfh;)s9t;cB%R~FAU!_Evq;>d0os%^M$w#pSQBE;!gRWDxyqg?3;v* z1zS-vJMvp=-DOvD&7^We^=xQ^FH;<~O171)jy8urj9n6a(o@yT=hptY8NZ^gjNcPk zM9nw%|CQ;k!s6~;k)zD}2pvhLqv+oekfqGNCCsaf3!_9PGIuTgWb$*$jtvrys=pHdO>Fx|8 zJQ5XdIXi${fp#+_85YUM;7j*W?=={#HncQ1=8?-7#?zl0%bxM&7@892EX|CSg&j&! z>3eq?T%bM*y=6g}nN*JBvuBz2v~Rj4!PwXOS5Sm|qPVu8eaSbH({{x)43+Wwx^{(e zj_3aBo(ExX%%3gxkg(!l4*t6G=ce%?99|KN>ZSCh!oH`J%n~OFzbbHHi_AMrOY+M( zx|IA?To!(r{u0?VewhSm=zNrprmNmwWCz zuL)mr3kcOIjH=itw5hI>q3X|}r4?Pe(!AKw<_6J2B1St#31@%o`*WXMg^aE6Z#fmt zqtx6Nzstnl&T8eW$JB_d5cjAc&OP*Jh3}h9AE{v#CRf}fq^h~!E__-eJ!6sh7Kx0t zPxQXL&-T!QYk$s0HMe}K6kfi!Zya0e)B7*Y)L~GU^f}?Zt-E1HUX$GEMW^hOB9}!k zj5`rEz_X(G)kjxODx{fzleSa~(>>Eq`0?oL6o2iKa~0P`Zwe_WpY{8dyU~v}ISq}S zh=vt=Cf!lO>8$SsIk(kwo;Hc+EA+Hhj5ziETVd?)6}iJAGYtDG-i({-87o`9tp2{7 z>?`BdI>yx^j@e4zafO|Vatqs+zhGMzi$!ObEcdU;x%bCtzC>0?T9PnXTdhC(wRL`k zKg1au`#$8FbwudoyszG(U+&VMAxABJ;z9h3z^df_x;)>Ah=Qx~yXb-XdWIHX4*m`) zV(jtdPehDJSYM&CD}f#IHShZxsubB=DYDWf^`>$3`xE(ReDzBoCan*97CSBGa_MjX zoZseO)2%N+d|Y@;p>G>4ey*Fp0RsE^#DfvI5iRHbE_2(<4i;XDIY;j+H@w2@A_4jS zE&BU4U4)CPJ}qj${(h+SOBcJN1TB3TGa)>z!awDMTu(eZzE#R;Nu;V3s(5302G}ls zyI^nN{#;fR*CEIqIXbdiK`LALW8BYo243q_acXRwX=Cnb_-!h$ywmuPCs}^^t)1(YYSJ#3e{C!Xs*XF$u6ll#4HNbU&$e`ngdySV zKE6k;Ts%T+4p+tcLS3dU`u+~gIe>5Asvp|d_`uRU0`X1|e9qZ_9@9<5OdAqbMJ+Sb zEragO@;*Tc8WvX7Iyz_x-@ut)oK-@DYxK~F(V?mIbCD@2`E!i5DZwEr(cMEuTax#o zqqs1lxEtPHeU~DmUG4b)_KGJTr_C5p~jXGMXs?v zqU3$SA9@h=Abe1TD$t9)ExDTaTE60^f-jWsWq29f%i;P{-TmNa729OX&2n2RW-9x{ z_QiF76sT>0$<`>*N?kGKc?SPz#DSl;jZ_3@Ew1)c&JeqBS=ljE0UTkxofsoOXNJ38 zevi{GmpwG*$9BT)-25H9y;e0 zzjY1zbI5o+sAu@&gwrCS`U*^6_lPg~%+Nm-^9`o(sqP1*9mU{3y+S|P^g;FF$GZ~M z%#!gxp3n{WS0VnWC1O&@@q(J3+DetOpXJicY1XXR4$gk?K=H3XY5G(dFF!hbfjUdq zBJX)Yf%?qut@taX)N(HF#qT#7RWSb78|zOgI3l^+EZ<0DY2lHA-_%-%p?pf%IxM3C z_v@zc$UpGgm)IfxKS9@Hnit@vsd-fkep%|cuEiaSJSr|Mw<1?^A;6dyp74^&FpVnT zF*jBA%@V-vw8{UbSt+4#!tW zvS_rfN>1Xpmx8TmYTTG`A#6fuaarx+b_EObptY?fGVWWI8tNyQ^|R5ZVM3y(AhJ)K zFE}IQsOMwJaC>GkWqM%S5$%mmfk*up3ibuoi6+v%u*qQ~nYa3HMVNE3TC^YjE>~Dr>WegvY7(*0*bCoSgybuZ+%iMx8r#A0OC$VZu+;ebw4!9LH|$o< z9bRI5t6N@#79Vntb^aAGKj?l`$A~CbCXfD_Q&^80j{S-G6IP%^qm{m|DNEou5thGf z8*064GydKzc}g03M~7qh{&|+W#@=?kub{`4 z*rILvpCa-quefYY$ZNJwVpz}!u200KoWa6B*zA&Wi5=w)%q_#`@8dCl@lxOHu-`)0 zkYYnZNq4=HKR`sxW4TF{`w=Gi$N;h%OPY6uYfgoU>Z#zr^<7JcYEMgSuEW+xLQ#~% za*Qi)+4bwAkCr}_?Fk)%JN137(A5gm_O|lguziu!LM|J&bCdL;Mg90rNHu$A_!Q|X zKFIjtPb+#)8P9#TzTj4dzt`1}78)~(JIKReA74q>8?>BGPY0EpmP%d8o@cgSFfJUm zwdTh&hN6D%rr1r_zoFTB0X2tSuv?XHQtQ$_*3Gb@NjBB+G zme?{%nD5`~iZ^vcwpnUgOZX^inDeOT9oCQcSeqHnA-9<~_NiT)=6?Da<#b|CIDyM4sE>aXmg(n&R+dwA z-`sTyKdSditLk1_vb9f`MzW@eEF|CWnNBn)-FV zZYA~PBc=5WnEAYJPmI;qkbCd_T9C$MAO*Ixup{bp?W=Rt?>cahf03n2#492?WVq{? zGs{=Lu(e)KQ^us2XfX$V@HWV+igXZqo6f|flZ-W&9Z{Snj{eh8H<}qmo5C-0Y2rK2 z_ChcA4K6cnh+L`JncD6b#kE1C8?k7%`(#k?IH%n+%QGpzgW(eB5mqN^BwR(bFL_g7 z7yt7{+D3#vVbGBIWnr#NN6w#lCWN>b;*Z%O87bV^pr9LG+xgL^x4wYyf+mz&yg--QS>du?OM{m6c}sM}|%QaXiy<3`J3 zEJwl7(BSZH+$uW$&#dAxQi^kOXtwE+(Hgw4Y=i*qp3+jw5AFDXpi~?-xDJsk%^R887DsVyA9~P5%l1WMUB)oB-)$q7TDFc-bml|&?oSI$b5RYD^vOOXP$Q@aZk;T z*+H+QaHMWQH?E!Yqu9jyf?OIjff?@wB9{N%a}B%(#ZengwWx#S%(7&53K#FMY@Lr) zGtI*Ly5Gy*lKaxXxQMW(Dmcf#QJa>ckn{F zivWd$(o)zD{YpIuUPa!=N|ic}Y`(FVfM4i}WO*ZtWGY2+o8sVih@Nu_t;Cs_ma%ofd0WFYOl6OsMgF-_DpgvU&Gkt1qbG|P8g4TJZ& zXY_70R{2DZ^sYn`)xb592Hz;-wG1Y=W z+X)QY#W@@-B6oaiLioa_u#-dcWZjFNj zJ7phtQ~wZD#!_`}JwEgbm*P*>o#k2?XVaPTH1m4aEH6V+oU51|Re)X1g94;V6~uFw z80EQwoTt)+`IgB6Qq%CU{_VPOS*J<*I5wM_p&~v={q&r}L$KMxMg2h`U)zpGaLtG- z=)%C5?fe$7Lr(V|#T_C+CK@U!Wu|WYI;AFhH`XUxH>zxb-nNn0l_P_kLtdo=?s(>koLT!JF!a2fj@%BbDSZA zzw3_2qMT!NYjhvM&TyK$iMl{#dyeickD^x$o&Cu)$+cqt(3$@J=JixFd71vObCvQ; z6?n!x2Iyw~kpZ47>@6xyJ#3k5nTt)M{`PNoosxCFefl^9Ma?je@j>yNLlim~OEy$O9Hws638kid#goA0sj*bF zUNO}q+9+Pu>Z<5(sjzga#ccA?Tjh)XMb1p_Z_tcNw>~z$2#~t%{peWa`J`Bhk>-#3 zH-`FhPbuDelJ&x5?5AP6F^T+)+~d0Y@AFk859uJB)LZPO=n!-H-AV&03e7VOLElM- zKxRpI*j35_0KrQt!Imj|sGgE(aKV7HbX5T*J zlmIEac?{Qx@563)q~pBgqyda0hG7Z9MDU62sdd&)Vy~DK@-tDYZBaUL!<5R}P^>9E z2(N|X@VS(#G?gZUwdge3NtkIp(pudLQBFjU1+v}ai7ryTz)aer>;$!-iyTDiH8Zx8 z`zfcw&1#r&3OSXslY_WM+Ff?L6pr`Sn&|6dSJ0O55T7M1R>HL$@|%8VfYd@x65U)r zdn-WdyP<=A7%ZT|{LPd^7%T)xfzEggJ%`t!PHBQzhZ-WMpl|TuewJLtYuaJ*lsaCY zg*5{N{>R@9&Q)_IhoPC;mOKQG`p3ZxZk;lO<}|Z@2C+wJNZ(*nwLDmjA4I=aJ)jxW zm(K`fi$rw`9i;Uks(^U4EnFHP^@}uUDa0`OM1WK>+mn2#og`N?DTG^;bWD` zdL7mjcj2`p3O*MmC{5v8uoi1TJGG0nUaO>T1sW$}U)4K!FQQAp7Dj;e%FaNf>eAMe zdawc8iKok{*g-W+ZAVU(SCWI^3+*n_SPBQZS`*{|b_IC{4dRNgA1j z5Q=W`BzsFahI~iY>W87_s4(TalBm=YqOl#IGck&ugRDZG@*c5{)=EwxOYz}UC32O@ zXotn&>Uf~Tnqk}VKX3+|E8UeGfoexvY%e&9R}NH*<|;$9u)sa6Ozfcy^bPEQmZu^7 zAh<&HU=x|X;2FvBFVrpK8m$lh6vP`&z@>Oi_)Dy+rN~$06L=a(rst3kk+bA#sfMCQ zJ_C_kWvDqDr%MVmw~2Dz`k-T@m??v`KG%G z)}!sU<~~ka&us%6$h&yDt|E3&dakx(_sT1gJov(L7HLd;2f1DYa=^bHd8hk^oG~rc z2Fe1u*A+t=<=qgP4vHsfhjJ`nE!VQe0a8bm>n2*MrMjIem=E|w3=mqlWG{k!nWwj?;$+EokV>tmH2 zkTMVzumd(hL%>qFqKv^N@>9UG;6?lk+a_@h`w#xqVKAJa$Kf?YQ^l%qjeMoFH=d^c zN6!h#M9vZgQjL<{$Vbm`V^7;KkR95}H;(Tv%`Mr_#N$EKlZgJ}Ir^iNQd)to=#uo8 zEwVNts1dhP=m+Cmi0&pj6m4&9=;P2VZky{Sc{fm}sc6fWp6ddnd~1+nhf4D$hbTN595|n-*B^a!aH=&SH-_P+b}j7H@%AK3=UX zlFjq)68GDZsMXf4#0$Q@Ksg{^ji^BMvI(YGu#~u7#&EUxDg3bDMWo)gNgu=h1A03Q z{0MrSk{p^!Zh>pa)Y9J4zv_SdhmcGxktkpWm-GhrJ;Nm_KQre3X}?QiH&|pK1vN54p&x$3h4??CL&bD!LwzKgWqj+pDb-T1d3?5f zB3jqZn&Ddu>iMrYPn)`l)h!lFjK8~KN67d_ak8fyg_&T9AXy!{&?o-59l+|4qCwKM*KWB43StNc3_xHpNou#P#5L zTrD_@A69mp)JsqGF;+Y1O}*wvxEm_T-ZkVF<5)7)woUq1T+e?f+lM7$eVM^w8n{pN zkfgFP;EeZQ=7PB~kz$?6cjkr)6HEIMAMr%$RA>)rKc3ERaFhax?{0+F+4v1}y#F)X zRZMrz(nnI~jc+YYq*}sMkFW3+5v|5qGa_q&dZy~m)AsdZ^|E1>7~OHhjxY;9Ppio; zC}Oc3)uFE)u@h-de-XPCnm|}tzAn`=4BZ?y+Si@G>pxgLG(c*YzI9j)sWzFwt}gpQ z0)GqJIco^A-J&>0`Rx4ul5C3;duzQHT*}=C=_PVmSLB^KF~|{K4V$m$+*nyh{JN~zg;1|;CU--h$-Bl8WgM&T zYugq!S6r`lDce`H3hOKU2-B=*i5^UcvN7()-hX|y&5eyg)|o-N0I3_L{YrxHL@+J1 zNBCJhomt>0bxh;Cvu&)ijcv^F#yqyGA3A5*H&f@)gO(@cz<+ua6xt6U8(wTuSo zOnO;YcD*{$Cx=&~{Cdv(S6N4Su{)xyt7VgTEtItE0S(o@s)MrPOYqGwt^H|tis3eP=xn4HPe1@6r3Ek@QH{Relh9%;Pg(##_Q=mLz))(vA;y zl~`Jctt^Yo>-g^aZtf=D!^C7aW7|)<5y~{(p-I8w4EsHkLz~GQwsvHf;h(&D?j9t` zRW;8y*kEMfn%fA2l&kjj0aAUKbX!$+J=WhR+Y!p|8EO8@kSZ^>J}&FZ|0`ZAt!vo} z3w5t-(|vmUm}i1p&-528R>AmL>B|JU%&rHpwtbp)3DJZ4Y#r{JtSxaKbA?fzwIr+2 z@=$9->0DmVLFE8D!!%7FNglD}cwfoa{R#Hj%wEM}9Brv0$e)uO#y1R$eiL2^-X0T~30@vJ97z8ia*Sq|nk5Iu@)z|>*uXo!KzKdt1 z*JMb=GOdqId-#7rW@%kdb6BWcvrRWA;>U34);kr!;_YqxtUJvFS=+fDC^ziWTw{qI z8fhJF_^vI%_q)RUvX&(Fw>+eeQ93%!b5PjA&hSR*Beflt9A>0^9hqyN?QkQ6x~{GMAN7p2lucC#b*L+b(bUuA0b|twsjhOc*NrR{J_6P_QS4@>_&Gd> zw6=%q2BX#S)*-bd6c3Xk9sAJ^{;$+yV=|nef50dCli?j#9NirALdM#F9gOdlI{3;0 zq;4^t^_v8ve!nkU*ot=Ww$s-_qmkzNQ~r){pIphal)j>c;+iFkdro-RN1j|T)gQ{# zWKhIwn#bRTUDdx>l<5c`5*d24_zkFHYflKil$)VzW$2~G8$Y_ni`~Tc0UOvKTdzN; zTPq^)vGvdx_ zgpYiIaiY@EOpzUVj{|uFdh%1X9P(7li+UG$v{WLUwbG2*1Qanmw*sFm{Uv-0ka~mtrhY3dv0Dz3 zt7Db;^SZZ~g4NKM=L@t7N=MINvZMG9Wzij0HtK*-TPOtMeO>7p_&W3-<5>wsCn`U< zE@Yl^m|D$Tme!E#`6GNoEekwI)t$5FMlGKu+NgZN0p zD8b=Vm)20H*d}XmlU6~ZFTc>t(YH%8zK0GR}WMA2W z4fU8yrncTrayNE~H%w=NVTSp}O2TV&l2`SZ$Wy$>Cg?}Pi~7UGXXI4B%pNemMEV$2 zrWtz^{^zd3pQP<-NswPhtHVjw?&M!-H`#W!i@?qdXF}btQN3pzznl7_d@;G1wsJ?R zx3`Z>5Tp2c)~Co0WIMgsu?pGBFXawdW{MNcE@Ga)1O3eLQ2UL?iQR0C13J_=;$Yb( zcv0LdRJNMHzsBXd1zZZYB4A$}M2Qe(-Gzr~r>TVww=!LR&MD?4;4syXA-swBdTzF` z&G1=@F+HIE@PBkQoL}V6NEOyzGU2OKy+2k&PyXk{{`V#*`JzOncb^{H%KiypHEuDbe=O-b( zxE-2GR8eA>6<~lm1C{-y0ZnfUC0n-|b^;ZMtKMx`FR{Gzk=ZUTVS0dP98bPr_hY}w zwaR6q4kp4Jye)SG>94WkP`bAC2ziZ*{BEKskRz;w-4>>hn~>}9B-2FhjJ<)=1P$9S zJp(KeqWmB^uuUo=VtpkjfEVPGx`y&T{0w*@H9)7y4V2EqMu?MPE9D<7i`s%zqZS0RU}^GrL5B|wtdcdTIOQmgim7sYWU;!Rjv|g= z{jft~j<`ggA}qmYVN=OSs<*sWUFsjtvoHgVq5Zl)co3Q)xw%d9J83J{n0$z@p-WV= zdR;cMCy-qAJ!#jiMP?IeVn4p4a!c5O5o9WwO!rbINp@M{KVl#8dek@FG*|^$B6j5( z1}bVv51H;D$B5qloN22kVV#q*RaLp zeEARBN-Ysz;04lmEP=Qs^`}0I^VIvO%DKtm+FSJleOd&VgnW^vGV|m$=n$d_{~u8z zx04?czxZ_OKC(kxZ`+%@|K{|n~mbdyB;vV%m`9wcjGZHO?YJO4^xWm*OG7p=gTPN36 z;*@y54PS|zBO(mPlmXZc;f-$<(uL#54EhE5X=o-LQl@Ax*>dE2P#3SObIB4iPCCTa zLjRF^5*qzq;J2IbQ^cJ}9WGPXh-ih)GobtrD2nyjd&CN588uwDMwN-0VsfC0vY$Up zkE1>441F$FEUy=Sd7lIn?xU$r#$ZLk_V5ST`N(&%8}qNOBic#VUq}>oDt&y{sqSb7 z;nI(huEQ+8KYI%qqfMtv4Ke5}B2O5~S(FL<7b=W$6OWk7;wveJAK>eQ4+qusn=JcL z1H8e%D%+;U^G)a)#t+15LsQ{CSAny76VN2;wXTPCHacJZhwJ9*sn*hdG5=ZmVPELF z{z~5K;#*%6y`C)6O)y%;mGUp|YE}<=;2F9W=JjwrGTeL2m95qnwwtY{QTpaar(fZY zdtSIrbam{YCEx5;yTYbU#aUj9lg61tOeI7E{cDeopUx%v=IRTHDyA0ZRB49x-nGQt z0F)@btS5}?iRR>Zm*gwt)A(~nQlFw{4Zr=3g)--M4~~-vZuw>&j#R`ey0>_jDv-Zt z=5$ka<8@crU;gvngU+60C3Ld!qs=Mj5~Qn=2i2Byf0^g&X3(7s_1V_4%q6lB^r1ja z{i435_yrAOfB5PXm&7PbW9A;b#klRH!tj&0mI3{KMLkaya|7W!?@ZwC53AX~FN0@eBhLWa2(G7uR+wRYD* z`U#o5WU@%ZjYsecTsF1b{TDP~Yo+$)U4j0XR`^Tj8hA@uBX%)u2j}$bX+M7gg}w(u zbHXULG!xij?JGIjy+h#xHSVs)CSWz$hWdxCj^*(=;u#$$NrrvoT``!x>=~>~1JM80 zOlh-mJ$cRh8szg1v8JvroU5BfefAe&ubnrAd~}2`)V37eju%roo`Fa+?wB-Jm!cij zyYXj=4fJDE`P#6lct8*E|4@p~_AP@}v9-{OSq*cT8}tID0&$C*CsjtGxy95iv>$w@ znIiGW6aFc+2Va3)r~3$k`bZthCsOx712TqbC1-I6W8XMz<7_cv)KJ&%?J7@2GzI!_WqEr8NFXz>~A!m#G2pHgZ^;Axs6Q zB`19!8;m*w)u>4U|1M3who!;AWOJ;w%79#9zFG;a04u50_(kj)@=<)HU~+ii4($YY z=tXE#Wwo-0Gf0*|2TdZmfm#H9;GM+*@(8$4nn0b!EZ9w|hG>Kzg!R&Wbh%cMx`-S@ zQb2WSpVn793+?y?q(A6`Y~;tn8R7%24t`$CqECQFFcgUproq|p2MDD*BIk)cu%pyj zp2lUU8G&rYNnL$(B)kJjR@A!66A^_jz?zVDWT9{qiRCpIkB?IRp@TtZ^)tGL5By7z zqV}X+a4aZ?e`fcg@1!d7LAt!OfGPs#g+9a+t~b_&*r3+ZTVV&7haD00NJSVerIM_? z8Ci=r6uuK^z{AMIs)##@Ey#3umHMopSYxZw2<&ofoRuOQRai)e)08^$A5wB^JuRDwsoF@;!o1(kXxzq(E2~?1)2_~>hy-nze5Hugzrf!gCz+q|%R+StL zG_toG9GF)zVq5GA9FLD6DYX(dN*be}fjX~9e#IZ4?=hqFMp~vMi0RlPw3w(&CM%89 z-@H+*10N#KsclRhY%1DWz9kUK961fWOt4 z3?+k@1TY;OmTmkB)vKlARcSjOf~TtzKU{Y4+Yk)<2memL11CTwS>@|!LzKl>2=xt_ zNzzJBvAx!gUxX(F@+VDn=_-xJ%6=ggZ6U8G&ta26G=_>%N<)p5*W!PnRgfXXOSuME zs_v3!5gXOj#3KBcI+Pe9C8<^5BJmH=1ZJUbVy3blDbkurPw`m!0(u&MCpRVcO3Sn; zbfqwy7z%+_jcPBI!v-Ro zK26mXJsOSf7Y9;>U>8_J*Avd6W3=6T40T;J;1n(ho2eM#hHAoU^RK8w$U9Jh*(i(; z*aK1MOFmW7h`LmQREKyeq)Q*r8~hrk4l)?|MBfl6pyQQ9VIAsMmY{n{my$)C2s{%W zB!^#zYj{U6MR!991Mk(JTxGnD9E2aH)~cJSa4AcC1)uR@_!TS#Ij&;@3ZC{#dp;RY z&=QD?%!a^S92bbcUcrh&MY1LF2>nHWkR|1z@`TF{*sU>mJKavjjg=E6|3)NKm`og@ zhJrh~7V;t$*ECK~WPobeDkf1mj#QTyanWdNxfwxF1J$kMAK{a91VM!6^cH*^TC6jO zwV)*R=62$T)F84N{aWjR_mjE?>dVUnm7=HxsFAS?W0ba%fpy}oL2oi#=T_%qh#+&R z$R=q#U5(y{l+vffsp3n;>Ay{uL)+kfW{tcfQ2l?z?F`J+Yt#%~dDMg#i%0mYDk>%u zcJdhhE)dncmqUdo{=cxZAb~k${DEY^M`EJWtsWBoCO_%dn@l>L}_l(~zd=V|WFHAp%)n)Ru6zN&y zTa66_Urn^(74Txye3jTo>Qb@1u_Jw%PN$2wEPfoDYqW;} zeOMlSg)G!n=9((${2MNUssabmznCG?FXT3N*Pn{tmf9K@(~C+_E}&`KtIva;0Ua`BQe>t z3_g};OVbRYU=y>0nk-t-h5j$%c05@cZ-(;nzz2SdVWxHq8%S*STfrT%hct+u3AfPa$i@5#tdi%l6om-l zMRPB-0&XFf`*IOVXeLjfXKCM=e2i1FKznYOa08}F8B8SRM=nym{AXb!X`;A~`UUf8 zhQgJXc%~35R|RE4961_s!f*6xsR0ahqjKj0Gq*hcnp!LMC4TUQ;sgS&`C^oqI}+z?-=r@$mI zkxapIuvlcd^jpc0S>+-z3G5I2(pNQ3P3B+7QQAY`BgT-`K?b&7TA|c}JLIus4|FwV zA;yZISjuDcmUKXsfU<8c#)oqp$@i z690vp;cpN`zDI`P`(c{gO=%$v)}oO-WDq?b;oyI;Hs{dx2dwpRswaAmxPmm4P+%AT zf}I0uolfLQ&`fK9h6sMJ4pdWLPy^vI5Qa(IQM9LAM;T529mrrU1slby_&vdZX5gFE zD@-^{g9WH0&H*miRvu1dC~HvR~Uc?h#P^<^odAHK-0BAvnkiGGOa)M1*xfpBR7@murpw_|L|>r+|@p` zS3rkm)nqyh3YMI577X;C92Ajx=Q&dEyHlQ65D}0)C=fid4h5ep|t_TUhEgz z4P7ihlvgTWr4LvTIt;Hz7!|wLPPi(~gs+g8>k`+}+ zo1p9s^eA@Jmf}yS76^jflK+wr^`7(_4G#Ev%ZXd+dS$uVSQ?2QNBL#hOnUq9qRrHa%M-G|P=ebn?o*Zopi6+^W?+68Ph)duU0z0d{;vT|9h z2tHsK=BKKIRUlTmBV=pm)dX}oISQ$X7psW0R@)~AVZ+d^=rQ_&x*NHrWQZ@2Ps%W2 z0{R?;qtgR^nNu6B48wLK50NN5LkR(C8m)B4m#Zp18{^dP_#nBJdJXQ9b$E055*>w4 zR+Ev9+IIONHb7Z~R>De@IAXB8UYm{T#kcq%n5?ZNisc6AO{A4lhn%Z;kwe&aX$(#) zPt|fbD)k^bB9wNL=q9!Sm$mD17TGiqyVWJeN}sXb@&V;N_C(IY?Px_s!|%ye)vM@Y zu~A^Qdckix^#8PT=Fe4?XB>at?c5u7GJ_hDh!9FZz=p+82v{v!u?iSN8w5f`Adwi$ zGJ=pYEG-a$u$d}m1_o$JA}X@TR7lwZD9Hq37>2hii`STmrE1WmS6@fg#2Kq>Ok(ghVWc4 zOl7lQa3PhbR0(zqeMe3SdXa_DIdVugkiXfr@{Cwy zL|Uue*x&q0w$SOeH;uy?e=09B*L7#IRQBRAY(BgcEi?7#HXj|fWizm&b|~oNBBDYc zSI*ak=U6p;m!wDI%v2IJKD^E{-7;Pr`NVz9iqwIy*pHQEq75&l>5)fGrJZJHgj-lU z@)(;FEwqJnx$fTbHZ;kvd7-!i??#84DR#3@X;Hicy3>o1Y&!X) ztP|zKaDF3NV?&y!CWX(CpX;T;rr;J?9sHmUYHkZ#j__NgmKmJK=lVMJ)9|-&2YvB6 znnX(3J=G*9*!R>bjxHmdx0mR8(@ynoS%$9SMX~ET)T4hSStUbzEj)6PV5e?3xeoaTMbXkW7uc= z(QS(iid4|Y*zNF|9H{E$3L$vkzy#-QXcx&rVKpR@DM4CvGt`h;IjW`EoX~j!f~|Z{ zP--&GI8_nep^lUW=OYZWH!5XG_^D&IQYbNxV#!06=nMKOvmJY1DM5wkYTvX!giBRC z4DrR0SH&J0L$1mK8JbjmQq=M#qFyxVGp?g-D@Tw*UlYs@QhfvYSng2o`!42kaEVW4 z&&2|<$?Sny;T0J|oNbEC6CcohJVEx=ZtG=M_z2DNvx6U_ZQx0kt=h}$?lO8o z-()RpG*{{cOI5M_J6jA!90MO+TL_%rNN`K|8ax~k=TExkdP1k24zKhvhjkFdJ3jgP{+nxADESRWYS z%hV};7|(?3_!e{UO$_BnSOozJj&(RWu3r;Yqj0K83!5KhtjXm|Y9hjC?W9?7<%Ea9?A0qYHW^G~ijo_`UXqi=_|yYFa}FyCyQgeCytT$>{fffph{~ z`~9e$$wh`sEOkphxz2f#n<7k(F=;5V@(*x){cB9rDP`VBsyA#@{& zP-)-BsGRvegLd@yX;18Ht$^3;2px%Dv4p7uN8_kI~o{Z9tZc#8=-KHb-ma}Y}= zL#``Rs`r-O^vTp@reGiDox%8=o@4|>I$SB^;~2&>H=gi>I9?&wMP~p62}LSU!xv_3_$%eQ(S2UK`VnIa%YAmR+VU39;mOzZg z77Rh7M#VxC5mAsL0>Z*B>`tHgPkjF8K0CX^x_kG$=Pl>jdHLem2%%7feEY#Ofl$gI zc*bVM&R;aAN9R>DzD3$?O{e0DO&%y+kjz3oAMWkhbfIym%iWMwUr^u0nd+S59OPW= z%&2c(FE!kAy>Fb-bi~`5XN5c|Q@O8I;~``sUBvK)C8p=r0rrDF5B%7GPXfPdu{U^g z>nWk_!ydQ&rd@sq-|+q)MRx4g$=qpUXMN`{I#2FAzBAqFQKxYofBxucczK5l?dP_m z+UyK{+q%9L)6yK|2)O09(br)=ZjCbiV~Auj=@^p6j%yZb0J^JaJr`9J?kFy_de|+?@_$2;mtE}GHBXiR8 z7UY`?A`90Ql@*^XO{m!U?%I2YbD-;56UT>2gVnKETOxz*#w6;0G0rfhT1?hn))%$} zn`mEYKj{c?OmZx9WcV0-7W-WAMZP_KvzrAsTiEP@Ux;6vUxwcsf197`-`4M6zpZ|w zn&mf(^1bHk@EPHF;Gpe^wuiQE)(w_D=2~-mQ*UFWAxVFL&0v1lCDFskN@5OnTHCD5 z6U+HMUaIknhH7Wq_gkt>l@}|*N?(*@y}ntLR#^6ee!k(^oxB~nqjGv=FVD))+LRTM zbw1maotLvG_fVcU|4PB_!iHB{OInq+d8@CAe!tv#%H{D)=dVcVY6ccZwxIuI%?67x z$2{G#);iY4+HTr?>@)1C_Id~I=nVC3bv*a6`%LmF_FdJigCFv{>c2UleSoWZa$v8( ze}f`|;)B)&9SQn1Xkri+_+6m6`F8;Y0sj8Mety2$K8x*{HlwATu}WXSB-4F~`&fuN zRocrJdWzjjgQd2ry7XPQip8bnCCgq16?H9)F8KZVr}@2~P0CxHXUtufyD&E)_jsN$ zZ}+ol`4P`s7tDEa@ujKg_UqLp;iY}bw^!<_ZoZ%DjCRd#I?J=tGF8H-Q6+3EV~l0J zeVy+ZzjFcm17m{nTQs%gf=>lITUmnt4E`pVX!&D{svsp$ZC(^`)qkj8U*B?{V~#|7 zi1mdf&wSU^XjF|83}f^c*gAF`^A}^&9oIFZ|DogPj#M>un~EVd@;9GC(5N-|1jmV}pBOXip4zWKg% zZCPyju8O;r0q+v3O*K1fEp_MWyEI&Nk7=y%Y~ot-uf=K7J7uqCM(KDUafu3{cj>(B zT>V{xVj5zeY8h>{TmP_GZQX1WY?EyRtd-VG>t>5$`Oy+)eqB!vg?c@E zm0iaC&IIa$sY|2{ABEPc!zDpTU2^@r+WMMbs$wgrR4gbfEj{#Rc1dE1srY>H z_2Qh89wiNLE|*>|yItY?Hu)V}b){xs?HuRKhGh56rZO%@xGVQm6Hz)rQT=p5>@Wjm z+-vS`NwVIyZMQGB=i4<0Yxml7?5pj=?Y(W~wi-~&Gg~1%t9Fw;*#5bFtbK=lsr@)y zSK2$+8f?dHEv<2uljZ``BjYi{SNirWt9wYFqmGf2iJACT>^M57Wocd1Maq4pw>&{Q zEdC~(=aad3Z?mS2jlEo(8w}3q+WPmKs=2D`?-D9!yj@t4S`k{FT0XP9SNW*&W#zRM zBi?@WwyCnR%2M49>ao^{byen_Q}nM5(s5kG^I z*m3NC=ndMAmZRocwU(yEX`w2o=BZa^1d6r@3bdzctX#AhybA1=K72~h#O%J1%kSB-?qAh*^_rtbeJ&}wqqaV;bGz*scNjARQQrq$hW20Jg+FKvi*9dMs+P-?@0FP;AC3n)AP)udHZ`0bDg>Ce1fo4JSm-3 zFm;VqgpI|YlV4C*bw*|yyF|a(Fvv(6_ZlmVlF@C9H1~rnHotBC5Ga| zu~_scLfU4nhx%OeRaGrQTc%~9PtjV8!Q!!UJO)o8!ijanagru`lSfG&xcD{oHf zQ7@=d)NIO5eoxwnHTX3=1RIH_YEkMy#VD1DXN3iPIM>EYcyvv}KxMn#-CSv|7*`t? z=`y&?@al}K$o-`|w{cpdyJ@GVFVvOC9p)Dakz$zC74#LaW}@a;68@T;MR|4ctX;ps zXfaJP7g(NK-L@M0Zbz77h@+RoWdGZ4v<7>2#e8pc$P`j)DYVE;a z(zLf)k#Nl2<-S}aJET5he_=KF$ZM{b_b2aEufxlD$9uo^dbusUmFI*<;vQ+2 zycRk?N*j&FW4$m1e^2~OPNi__0zH6!1Gz#oiOhS@@_P0*`#^8jH`jmt|Eo32v8R}N z<}=+DI*lqLdD4dn#!Xlx8mz5R&nQ(&h&)F&N-ID?qv4kn2RzE>A$8_<62FusF02yPWm_oW40IWwF&$h>6om^kKBT`KLNyHRaO zJ)Vi3MFUhxxgrmeItVZMOWfZa<{jy|;E91=)-^SG%%0Ys15oo1z`{~KS?DfkV!0&9 zqDpHW(Ew})K8;8q*HT~89ii59%tYodHh}#Me5)(NGdpyOZVseS5fwrX2N&#!{{>8R zV@cQ?>~ky%9>cIDSS)zpZR`c+#=GI+_yl|u-VR6bm+!DBfMNI^j74 zs^YyPz5j5L+!?+%xO_Uy8Utjj;;;76rUP=Xh<@Z`>VYnpSq@1kIiTc z`c#uOH`2ihgZI)g1GW$+@%6Y0N}o*LqQ+DA=r(i=eS$tj|3LQzr5nhxL@NFSD@X6( zvv#$GGFCn!RZ4xq!NY)qn}K;$iTM5N;{=g#VKN2l$^S&Xo`#7b;&<=BQT93_I?}B5@kOL#!kFKvmyT zZaSL2NUOR?UA!(ycTkrA&*Ahl`V4R%rdW!BDfSbhmRLjd!zKI%-WNFcJN6ZFp%W-f zy9?9CM&Q!|`JFsUDv`dHT8bs&V^}V!2PBwNUMF)(qN1rcv?%Qn8iP(^By?;A@VOIG z(0;8}o2{lOwMw8IBmE(f;u7H{pk?N-@cZ~_{4#z!R1zv|5NYwW6bpG+4pYWPZ5|qm zYOtsH0b&rrkpm-Q#~Kj^;(?^wcQ!h9ME6&Z+Pybz|m zE!s**mqhurboakKAzS7N-T4asUw#)q4$vFLFM?MO`9{H4_*6(2>cLl%MM>H$TfsdB zDLLvawMvVD1M&vs!oI>@fEq6n!Nga@DdH~CKr{kk`NR<-ff!2oL$0ldEO2AjLC?Xc z26#6H>9p@OvwBJGt~3IAocyz#Acsruq$i-u65x6_dAWiCa$ZQvNyvh-VXg|qbBM)6 zEjgaNPcc*<$epg_OEMACW+L#g9_xjcYsX;v8>O67g5_OuPw9cQOWG-|f@DsYkvvn* zRyrwrK@W+V4xAwi4L~Q66Z`l>vJJ=2;S$lC*bHZuT1dA(`5egX{ zf*nM~=%WukD^>={ha>^!76}xp7tRYy!D+h-7@&p$YU_l3LKRE^%f&1yR(c>$kPAV- z^-#~3S}odu1!DJLqALW1u8{r7lcb9pNnNEXKd5XweSl7ZlgA>+1|5|}#Zdv|d2%`+ zyOF^0nb_Z0TQpC*00}f4T$z)jr5ve;_!>IdU+@5f@*vfU!GlMNM?nD_WJ>-)>8;#X zXZ`0Lpz&4cAMn)`*jX$EzAFX1H3~gO(OQA_r7D3_(8@stlQZPg@>ZC@cF70icaVV# zlv`?Nc()WPNCThPj#;o7&{YNh7+-{^K%(^^<^g`GL?5uf?}>^u8|J}o zP=`hNUXefp2Iyb`>JK_ppo2@WKd>CE9=GDX@KyNF_>Xud&H*DkfeeGZ@@X^C_Jjw zCQwc*t+zG~Ts#>ZBn{3j0y3j!s0HeY^e|hvwFa#WmJGWQ@XmjZycQ+FiJ%;&uufP9 ztSg40JaiN-{Gg+L>K%0mOaTcB11QdvTS`Une^bY#@1z4z!)?%PxV%w*rA$Zp8f(|O(2#L;|O2q-3mMq zIMWPWgc>(!0g$M;vKRI~2Pek&Fb8h{42MY_r4XqrbPcp8dE{vMSA|jHl`6=hOR5CP zdb%vXOP-^fN3%CZ+ie@T_Dqk0cxWG)t&I^yMS9Q zaCs<-hI7(9I4S-27zuZMQF}ns0?UEA!5(8E88<-6oklz`wkz;{FDU*ntZl&Gwt(ej zG#xPCrwxX);x08zc?BFB3qHpv6wK?45~y?s^bQ06S#>Npex~LNe!fjh)th-bl$tKjo5Kd@m2`0qlfB?+DzR32VRUg z^|^QNmcUHc+0nhAH9MAT-#g{f6z0Br`)D&|I6FSrNe^4U=7)@2 zowvtaWCyD}*q#%4INj2fS}*Ft(_#ma~1R@=Wth#$-8Qtu!9*%f+jAwduM)m)y+q*#Oa0+`p)r4*>B(Uipyh~_%k%bD zh{Mq;4Yrq9VqOJc&c&LYt_uGxsFlfBtb#YcSWVeAx^Btn) zsm{QD!r- zxg9UL&Q0OU``1F@xwZ4~gLETslJ)ejiNViB9ABjyx5$GPp!on)7CJKZi(JF0?v2MwPypD>(JCc*9FZ6<%Yk2`jCB+@44gM6-!* zQL_<6100iD69lbJZqLdPg$;V%qS{)CFhCfVSQgiI9)`KI5oM!(gb6ZMD-*|IR2#CW zIr-y}JK9RN>*pgunj{%GeMFVDUa7c@q719j+G^rQjCDn|nk>$0OHp)O#!2m{%El>@ zq{JF%RT}3c$f%PfL#C?gC{5BvS5*^dNm?7KV&FW{=%gV-n=uK zVmKAlz=onbO`29yn((ZQh33*uyg6Qmisf$IX& zObS3U!5gF+@;g9cP*GGghL$DPs4Ob5Hf&M@W5cj;RhD36fOT0ylZFXFWsM!vv~gWS zx3=xzrmmq$+r~gO*dd^4npQ)fXmvxvzslCFk}ok7mxt9muOv^J>INZVaBgwv0#x9kS!4Enrw5|T%HYujyy>!$>oG7v=5x;2rW`f^=< zzks&d`%YU!8bi*j18p%n958JSx)P_e{`(Cf`QKdZJS5}y4f`(BbT;SG}rB?N)Of>dcRR zJlk%?ZU6bwdG3~<_@Cp`MOg1v@{{~?ztd${=4Y+)!$msD4@>Bw@jwsX4olDFhq>E3 zRGmNXTc&qts;Bpj?p^-*YyPS5IB4G=dc)k^0NtH2?`v2e+!cB%*Do%*XSb!?AQwK? zZz&SFX}x$`N`_!@@5;CIpnp&dPwy7a!$H!_-Bj(vzPvcOsXScgdi!6)!*I~N$>Ep% z>wf3D$Wg9a?O*2~#9nwj?;c;DHXipL!t#}a)_X6t!c{>H_QEsou6Tp?dVA-+!fn#( z?=79&RS7@r#r5J=mxhTH#*z z@%-9BtBm;in|j?3&)xgt9XjakpNEC}xZU4hIJuh=>h7;wr#ENeO|E-z)I02tE^hPY z>EL!)zd2Ag|D!U#&3B_*?{xiKxG%e5uGc@i>ySn6wRwDZ629fairXvxAcx`C>hp1! zIxmMyFMofI!o$cdKa>aSqcC55IvUREKfbAczB_Gn^Gbbttj)TG$GGrRj^B!54fl_p zhvgqGT^tQNXT7t*sL*er{&}Ai`i17}=|DNdZ!2;fR=j>;P3n);adO-*mIo)ZRrC2= z4Nsnzt)~+uORvrKbLllX8#ctWK4_7*;&58)Bep($cPstMXm&Pq@u)Ut=fjdSslFKW zUXED#wTVaP32VPK7ot3>HpZ1z>LkO9X>u`f)Uq{k*`)HmYz{Gt zstep0HRj9e1k+h_#xAB+Z&n`}Jimzf#i)&^7b$nfowcY<8|_&wO590H%`PUMJHAk| zIrGG%K1&+!o?3O@J@#H(tlAU8quPqtNprEP%?Mqzm%Kh}pk;Gv@UoHE`m}@R_0+oW zPAu!Qwli<0sXKGjqA^46d&7wK0?GI0B5lo(iJS%I^X4jYW|YUxi1Jxyy>2cjU3S*I zHE-cnXKu*4liJqYCCipDXz3-gwQ$^JTL{>gReOoiqHTn;B4*KErOu*lV`oj+vJ*w_ zlCh+daK7;3sJ&)*<;AMAa%9wAO0q)Iwj+dAo{-+!QxZ7PvSWl75x#WR%v(BCbW&~? zD2_Wxn?`75*t#v#&O+G;DMn(Hf>PlG;O>gbwG&CSMpn3Mj+YKMUc^;GBI1e;i`mj} z)ln4UlCfhjiAfZbwM&F6C0}8cxRD?c!0?)j$Q2gFEEO!qOu2DtBg3p~7+G7HB7tc_ zBSjLA3M36nh%`8&u(6g!RzOG|iD@jDL`q26;adzvE>3w!4ks^QHm#A z8K5!32u>`a!lsg0$}AJoNXi&hMo6nDRn$l>EmssG2aBObS;@Es4>PicQw|!tuY4v(Qx=P@Uzo^?x*~1$vimM zR_nk9@T+0Dlc2FXjRlR(EO2UO0a_KnWq}#uv2dh@BQ?kXEXKf!2R}7TaVY~07PiY8 zoTN5ziHu6CWnd_^a1~Z&(rUAXV0{RC3kmw#x7%Q=DM)R>qI`%$fR}H5UvRMn52mTm zTo7uB&{|MKiDU*IFYp!F>Oc@*6UZcGR%2;FDvLGNX#kI@F(jT^v&Gud)Jg>woU%0a zw}fi4F)YQtz1(P>V&h+?)NFjo$QBF5Hkjy3AWq-~FNMz&U)f8EbwU$`C4wtTxD^P} zNUV}bVem{+4CM!9Z)t*jgA!vlm)b`g-zH>Bu|TQvV}un_+QzNj+&u48)$qHYRa;nPMo|*pk?z8l>GI<$E!)G2TMNDAmw(M0%gZTQB`dEP$8* zvGA;7K)ms`K+OLl#wlU)GPZsU*o-(uih2pL3El=|dnthU(uV{Mhln8q0(}Q}EZ{0g zq6zesW=R0BttJWA3T?A&6M<7dkaz?41KGlrSb-J0+z^`*8BmG0#@`SsFQM!2jGOLXd|+TUUzP6L2RLsMuBBB=$7^abOJ2zXI=c#>KxeH{=1jq5AUB)k(9K7-eX zE~W+uX&~SLDyb1rOjJU-1=|2%%CIfBnnJm6sf3;lU?VNtQmtuLkW_ODoi0HMMXsT^ zS)hT_f+w_ez@Zjx0B{Kf87O8=AURyL1__nUbY_9pf!597;Gtn-VFP^yFa;Z~gUk}} zObM@_bzT6S2+av_6(|lzLl^I0nI{kj8cqpxhJ;*TQp}jlqM=2zcrqmr?=~ReYmiL< z+ify9cmOddp+$D?*~S1O+rR<4Q+9;A&5r961{VGomj&f-V*b-(cgiO*e3^DfXT%(W z%!uKulEFTSA+`Vrb>{v_yfea-eZzKXfCNMa<0b&@Cwv!qh5$3DGWW~~a+d};eZnB8 z44zG&@XQln*@2%UGyhcnlo{dY*ae%p|Mti%**^Q~{#xxK|BV6le~-*L8^7dVt6!R5 N^3(7C^Z(2Z{0HT``~?62 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/coinslot.au b/contrib/vtwmrc/sounds/coinslot.au new file mode 100644 index 0000000000000000000000000000000000000000..0d92362a9f117f8d7feb8692448230c04e004317 GIT binary patch literal 96367 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/ddl.au b/contrib/vtwmrc/sounds/ddl.au new file mode 100644 index 0000000000000000000000000000000000000000..fea63707ad9aee72fbd6e51abc6e7de62caa92ff GIT binary patch literal 12162 zcmeI%)pJy7(*W>u#@$^qlZkss2oi$3E*2J8+}(l%f-ml}$l|&{U>6I%SPTLQanDR< zCgT}*Kkrt3|G{@nUvxiL&&98*tGc>V^VTc^06+`?X$$_VZ~&Ml`LBYD7OhI%GJo@b z&;J4e2!J^7E^;)Mjr)ixg~tZAIMXbJmI!->Cp$=kdIJZ+@$dr7eo8iHv2ZGX5@mI$ zSx0IttvXRZOLGyd7c5R0nYuwV3z=`&+2U#$t$&R^5-aPsB4>DPIUsHBcoXwa-#4b_ zm!TKprM+I~RQ7xv{g}}Y^BA53bOdMFM#$cMegA6s^SLGKv~J$O@x^&hca^U?*nd-a z-bd+~DZ70qZoC+(%i~_oc{BFG$YEJV@jOx#OcN^iKX7&%i0vz?psy>cy=o0g5-%Bi zW(;fqJrW(zx1IiS{_B~JB>w?UR3bXz5?koo*MZ`9=EcWK<%L$vMg=WVOX6F)ty z{8d9ndL;NB+tNNp41w1f2Df#!5A9AwypA}LCQfIH^O11PydT_>)fKRg@$L>vb=3JJ zed1inI?f()D|Qlme1KuTESpsIviNEVt4?8C$_Wo*{notjk10>m_~Caynjapzn)z2+ z@p^qM`9%t{pEd{ELn3xil!)}eBsIX}sQqP$W2eV~hCxqt1xu(K*0Q z3r6)+<+r>7Bk6raWs+q)3O2*3>>{?@Y2nG$RutHmvWbroQ^Xm9FKh&P3G$<_vfClm z)csTCs{5v#>~CTJo3UajG;%?9i}(}7l2(_#f3xcS$Lj0)c4W11VscD+Rq~9;gY;X- z?OvJrtVXVc$@g}N3=7-EoPl;GMJrL8*AQpq9Q2b=oI1tx$92Rs~1B!gSV$N3}B-OC}{YCC`tU!}J2{ zb=rotU##VCYR_xd10Q%VQy=!((ra5nC9?{OH5_aI*ihd@lBIV8J_TkDW0T;n7!i@f zzC;uQdmI71M|D9>@BYo@hs`2xV60;nQUSC%l;Ws1?>0Yk4hbDaD=AAE@96i5^WgKn zFjKp>hkA!T)pjQ|4HwJ&EObN?B2t(Im~`(x{b=d-=KHM^l)G%jh!L!U==aI7NokP~ zZ85aoSRu7GK5YD@qrMvmx=DWFs+dEuDA6SPD8ys;w(eNf0%ffx!*tp60QR29Wg<9! z4vY$+4S^=>Sv^C0*!Z_67jcJD$q{g}C~XL?>y3e+x~&yk--M44_OeQNB^)FLK&}r= zaD24fGViyHwHh5P_sqa+cnfJNH!E^nREl6bG0G!XG}NYk?^}09g9M)P*QRQ+8dEs~0%`&TjC@vBmI#2lj1y^Fe0yQ&zuXtCVm3^#TIKnU zbLw@0OxB9zwya;17EqHdl$yd%B*sRO4TpHLdIG=CmhUPN1i7{}J!t?Z@BpyDd%TYR^{`gLZ(mj&wZuNSoaB zx~{8};gxarWnLU~CVR4k4fX6eR%-f~TUn^RjCvvJNctYXfjbs?({;rB#=b4I5}Qe$ zgqK5$%xC4N+ubUfX9oFgbZx3VF@k+RRIfhYJh$1cc@g@?SPoua5_pSGI zKJa(mmt-()MwEeQbFmb^x5A}x!yLZ~9U_j!4TlZ&H~7*aC2_7`eQaX%Q)X4LS10&o z<@+0Dm9nisizL*KJ>*uO0G|8@WQlp= z>jaMda=WHlRFf^+=hWc;<=+-#IaRm_|0`Rz?N;C!p1^TLD7bvgaNF?q(?3rCa7q!* zv!wk|6I1piZ57=kj{-8?HyqDgOFXTfKDHOSE1m8RZ`ViHG}6Bb+xwpzmYK~H`ysJ( zd#V22isHpho2)HZDSw@$Ju;m)koJhEA$%w9C0s=*0z^Yq+pg+Y)$wgFtoe9))Uu4m ztPM$1IZI&<+gxo(``i?E_YPbROmH1C73cu{erGIdFW;NW@1@8nkx((+CRMY%5~!p$ z&Cs0m+(Z_TX3^}--JE5Dw~=e2?uiWaCg`|k+7I0OwQs`Z@Xm8Uw}jk}KjQe1PZ?q! z7mPN3mc!b`?ZM77UB7E--9zov5Q{Kd_&KFlFGkOzI5V~0^NZ|dmGSH4YN717%?dYB z{$Q~ zih{yu?i6}}fCH-R@4FhCC)d2HyCE&IrlZn%l?m(9Qj>Ox$5Tb1%Js%fHeA+s8fXTl z0qka3Xr2M^OSH}6M~S~Dt77M|YY~~2noe9}R((-xlX{{f5;%na%t+;-gx^JlqGbL| z`f${HccU6=epZ(pkHXFeX5kU)NB)asa{k?*+KL?w97oo>9WzOJ|?mv)`g%N*OFi-d1nx+Eud zM)Y`rn9PL^Su?u6c1&z5ky*6Q98(}I{t0uI02Hw!R`IyBO_+YcvsSYPlFyfoRSePD zo#|j4v5J!v@m~B)7-VM?55h)!025LDK=EGDpbnTmd6VEZWC~}HFeF+dn8_T1uLci! zR+?vP6P3HSjA$>GAonxk9k=Nas+V~D!^T+l!U84Uf*&g+{ z$MaqvdJKyE7guaO(1I$D_;93zTR+-31$#H9wBPg*y@vJ3Iw^o4j$&oSzIU~6zm%`( zSmDiMCZ_bs$r<>#_t+RJq294XdZT*#_u;hzIv+T)&_!HwG%B_!@+eb*s`S(uvosU5 zSW~HYH)0NH9s{JyNFZG11x?E}YRw{Jo|lO-GT%iqVtG;NoH^*#j??n8dR*1s+RvS9 zoI?onqf&bc`u)`hop6)p_V$u3{kHwnub)HJz0_xbM!vkqmHzGlMVXDFlSp~@>n6n4 zkL77U@;eLNiNr0D+?3Vn>k?6X3wEx1tmc4}*uF%u#56R>#BF2_=S}0ZQum`~`v+Ph z4C@SkSa6z=uOq%R)tXcVfjau~*wTzqnck#t{2M5# z?TNf+<3IJXws*Q6ek%SQS0Aa7Ea3k`z6z2YWAww-cy{b~gr^KPW!hN1#%;r{j;ML8*hHHc$@) z)SA~#lB!idrnP)FJOv)GHpDge*wf=~d@g$zY`1A^M}A#Vt-95#=LaLnDG~eQa^jlB zhv_`nUi)zMqt2AhcI{Bd0kDP?;`HKQ0i$Xl29OEeYk2qpd z8~Dj_S9?W1zw^C@Y99t#sj7&tG2dcF2zjKpL2LH_Y5&H?raPVYESa!jOi45`8K1OU zQa~$)))+@hNe%xtsHLlnN1;sW1M$T8-1s5l(X>=RZSg6;w0CxFQT4V>28`s-yb@8l z(8R34&J0X8f7VRxs?Z*>J_^yWHpV92NM0lZkDV3Fvqoz(yY6XbnOg(1u{q2=!hF#L zUOu@MJY_$ncFHzM->E3pF_53^5`>~>MsE`irLdrL7M$X1+n%<^%CVMeU>6k`L5smh zpA$5b*Fuq&Y^AZ|p7fG>tNjFwO;Pb}kyz0HHVHQ(aNj&YRi_xI`o$#neM6t5AK=Fb z+BnllSHMc=BLiBMpqgmd#7t5@|Egl>+SFbLJenWgj*ELu@P@Wf7*&P^@KNheGCbA zI7dO}V*7^H*+&_AYr^{J)^CBg=yKXLE}r)rvxBe%GT6hqWy+n(+d9a(9`=&r67-iO zM$Y5P2!T+F>3|}#t)MNSykhYI`>5=Q{jq&xKZ?=xh49h#YBizbXj@sQ%J9+0!$dJr z!c`)lU@rrOSr<&P-7>t^?dk?>BYn?cBe1DN7I7o)9P$_>4~V>Hyqy6(P=ONTrV`+| zS;*NTrE8NJuRo%nZRUH%z*kX5@caGOEhhz+DX)O9mYed8O*!@PEfUpP_h#HPVPTRy z<5v0~F*e3-DAy3z^5O@xQczD(+;B;7TtR2zi1fIW(x_I(8rUMMRq1QH(V~@})6R5? z!JWjO%!Axh++oalpSIQzg63g# z?|M43|EWqx!U}1%VtBHT~NJ!Jg{ly!A%k(E3_bAn} zEZI7x)G*dDId}`1Oc+JI%%rkjvMw<`QHA*Xh&@4!z1z^YE2nd0XTEB+nHX4wYv2K~ zOH*E^j)+^&twJZ*r^@bC@A`7>>%F=!s%wE2^n&>I-r521Y;y7yb}Q6ZQ(1SV%w618 z@mDL^JR51|E0UjN)%6mls3X+)b}v?Qu}#pB-Z-%1q%PlGj3iQrbCnTM5de=z--pkK zM+dgKXx1U7i0+%+Z%xasFI{(o4EQ7b5BdS_GhvKC%~?*ahU?q|bhT1N^VVj9G)X_k z_k)lv{4>$sqbJT*YTQ&!KoK&CLOElnZGC13Q*v?p7N zYo6CEZ@!><@5)2TSiK_q#BPhZA{xYK#7qc$wEFck)JN3kbT;!-*XIx)uEt&@YA7#h zB&wUTp12K5gU<}!cI_~~*DuuMX^IUc_8Gx1m=}x%!uF`&qHag@r{6{naOG%{+io;G zX}l<1-<=q|O~#6TO{_>;lss92rlmm3jn&c(_4TzIn=UEG+4B)InW)Ix_^Jf9#LB*d z9pWEk0=l-y|yY;r^Mm0ZMBZF&bGaA&h+*R z<-n=feqK0MbOZF-{qtSC_)((!GtLLImZ%z9y=xGds4djnxF z^ryXEH%jqDPUVms5o}j-rya=`lRfyX~Tu7=WO~QXf_Xack1x}*b zXG}9rww!fc3*AC3C!J(GVZUUtIqkEvUr$gc5cy{`4h6&&_ zL~m392E=^8{DZDTWx+KdF4X3~CFj1J3Xa#B_A`yH8O$E5iq;{v0>1>= z-py{5E7^_mt_^}fBq9O51$z)j!opBj;iI8HgCgI2PpM~%ce8(AXef{a3nODtt5Gjd zc*I56O<-eqN$^?VZ~zrZ4yZzu@P2>{9)y*_|3a`3Sol8JS@0J~72X``85|R63Alnc zLS@hZpb0h|ei+dQF$VrG>=qaU?G3qtZ-elFF1S3jE?fr!Am?X z#!_{JQm%1WRbeHG%^wmqH9Au`fV?|&sXL{kcSB4gyEDh?L!IF@C2USxnY2A(CqCJA zTAA30sA+53r)uz)ky6B$lY6F~iOXichL1N7=+M_0>t?i%?Un;qnCUT-Q|>0OkMvXW z0!OtMTT1Gp8d-9mVn!#&zcW5Q86W$R zy8u;eFISvtdf#xUeUV-kG*ixrixcUIS0qDd760w821qj+*EXG$Pqr2!5?N)@7ZXe4 zkpeTm$vZ`}u2tVSv-PP4^t{CL1o3eb5(h@lV_6U%ZC4a~n!h#WORJ5;!d29x;>+D&JeeSi#8H z-1r3&IO7ydYQ3ts*kW(VllL^A0S?lpi+_pR8@pM!l#~;UF{osemg#L8b*c-47PE_@ zCdD0z+Q;FcpSWJDyW7vVbjl_gN&{Dkxq?A4gJQRc9@0jF5tcGVLt9o`f%1&?D=dN* z5=mnj(bM@@LWKXdAx~D+YLara2R(SqJhn};J*GBt81oyl%6U(%>bTtYT7KDt3e6$) z640Yb(R+l`|C<31SeVMJ_A?zvRBF2tev+Oq8WVj=(v$NRC-kj1Bz10WKi4@{U+pzv zw{nn?hoUheB>e<};CQcrOaJY-u2fhu!U2+n|4C9T*~6!hfH1{;Qu#)TlwH#%Ipv6U zdR4@EiBC*nZNp@HCmFEvS<(rL?M8(E32r6ZDc&OKA^1*R23uthXhzCBvXklv+c01Q zdG~+w{#@~PPCWq;{A5n=njAZ(Kzu$-bL~Zz-phb`A0rReo#Bf(H|@)8+b(`ZNxg(9b8P{oXM+-md7f8bRYKq zjs_T@phk3o|CQDQ(c(U2=&jr)*Qx8RX`vtZ7WSeDbi`uL8scK;lFh8`qbO4TuFrSz zU@l5BHyH7oU@>DqW|9AtNv*~xYE){|HGed^g|6a%7S?eKDJk&jE}7v#*Ar!#)@~O= z34|#ujo@#=Ce|eUk?=CxO>I|KhH78;DR(OzqKxLo3O?~>(6*pTe9uf?4W{dm#%sA6 zxQjVLzsdVk0Av3_8VCklGYxK4NcF&gb$Ec;g!`;f{2bmM#vp7}XohXO?r+s+&3@BG zZvmoWp&+!?$C=0UWg=d3DJ+Cc)b;Av% zX1lu(7=^8&4rlTh2g!e<&xM@MFDAdiWz4lz`ZM9Bg#ENTj8@u9!ea#9f5kr8Xz1Q+ zp6AqtUZR|&H}u5}7-bW72k?jIqIHpRv+=sM)*BD9uw|6_^y9QU#5PoBXo3^6AdG*S zvmGY_8xeyDQPeGT38e-Pz)b!zcA2@CX|#2Sdsp}|nnyxVgS2$gWefn7d9K+8n*8Q% z_UpdG;AiX~{*th)=AEp{_n8i*g>Qbl<_1ZE)QN8T<>bO&9{VX z7Wa?PDa03CfFvc~B*vgEAkWWs=Gt)9PDh7t7LbYZ5{8gGq@#Eqa(4Knm*E&?OR&ed zfq)VA7v?*WLApldV-&FZV2*pE{i*G>l{|ksh|-i$MnR1C+P6G=w+ZcnB?iB87Tz~x^f6p7oO@hF zK5VE0=0fklt-+^aFQKsDfZ#wc!F9xy?TPmrpy!C)m|t-#ag#7KL?X1--|Cs?dhPD* z{TM6-mm}X}nsE$lFVs5N%uubb%tLhd_N?+R4ey6(Q1>ul>;|+MQ4Tx^ZuTKOWVhd2 z79;@?h)DE6OataL>Hs_zN(jvNUhvHEIQ?0nyWjyN1-&1$5WNRU1Fwdp{`1}~9*d6| zD1-#C=g1f6o#+>+$?#i1-(ZcOjIYaw^W6)a z2`>hBBZi~IsDF?x@EQ;vCIt5R9KQShC&3!%G;B8FFQgUeM|_1{g3O`ufnolE{xyNJ zkQX=x3nI#pN071bXW(uKAFK`x_rDKJ2sT3?I2HaI;vT|-7zn!$91G74o(${=%nxRV znjtx;g6}{~Lkx#c28*CCA!G1xKpl(-MTP(U@5jFIrSLZRZrB24*Dy literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/ddloo.au b/contrib/vtwmrc/sounds/ddloo.au new file mode 100644 index 0000000000000000000000000000000000000000..489c88b95c99d916e3a6ec2bc9df5b586221fb99 GIT binary patch literal 1892 zcmb7_O>YuW6o&Da=r2$#3UvmsL|Z7dHl`sBF=EgXM*CzwBKrrzcs#zmynIK{Vc!B1 zB0bBRk`F`@O}xw^r<%8a2~^d9|HvY6_adC)ryKdyBzyT^3WPP;{)|OHpNV)nFi(x3 zRVnqlXz|6sjiGW()77Jbd`0jSQ%&)>igHy!mTL>j=nG8`h%-tPZ`3A@np1gVPxbi* zheLIUmPW;%nnbHEB|x1Nx}+3dDb*M2sfAy)>-mLbRgBivvRV+EDsXk+o;Y-=7p)ri zMkVUN?Y^h!uBus-&F!jDA1Wiks!wA z^ycR1XsKY3y@ppsxN0)B{jn5JE)8U=MeIvZ1g80fV8<4Ue!SY}=Ofw%ZNc-oZVh9Qf=Gv|6@3Tf|M%L0n%@D(&C}Pl;hzCBVb3SuW$;GuGDD zLZOg(U9MCr8n4ta-+abjw{G$WbER4h>qkwLEp|ebg~~5#)wg6oD>m8?^weypSddr@ z!{0a;n*lg4g&6n8FGfyCCL!of+2#R@rr8_}40%B``c}X?qtQ=tk#&)kE(9*t>Ev>J z1DeA_9NFOHN=Rb)yi!QdTpY)l6@*tLKSRKAY!YshD+#!y=W~5HnM|hn?CI&5 zFr97-I6kIR2F}i;jPnR&^bns++z-g-2ZI5>>W!W#mgOBEBkMqplx&v6dRlmY3cmsA CZp(52 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/dedoo.au b/contrib/vtwmrc/sounds/dedoo.au new file mode 100644 index 0000000000000000000000000000000000000000..aef41081b91944e44cb515de5b5794e93b7572b6 GIT binary patch literal 3920 zcmeHJv97B|5OuyFpAac+t}#Lgp%p@*pm0Iuk}A@Tw#zG?l>F0^ZB_^&gb)%1g$pXm z{eb<9$(eyTB+IjMJ&d&Sga8&A4sPiOtu7fKb3sszpLebWB9e3vv zjI%lyq#eg~w~m&@Nx{xd2!y*OlE^QP9nCw(bGMl$Iu`0!OQW5gzjKX|r=vO_i8O6J z*WtZ&g*ri*-0>XWV0Kc)K!!}@?gH3`ic=3fX@48C0-}Ih((F8G{p8Pf7pGPlgHyO$ zJ?G~yMt(7*!7^_-gJmScbVe*Dh!+_bWk@g(US&rdGKT|ORz0Y(aJaKJ^@Wi(+4JDQ zB5KX>J>YPu(mG7)`!O6;S_e_$2OcLjs#YyidtvAqO-5CfXJIMfx} zUDbw397S;~n!0P6wrflTN1Q~|bY0tat$`88NrLCp_4tfNCMkd5=+QqT=``K%)6~%1 zUoPWl^t{gwSw{I`o@RSdF7ur4X__Z(3@WyYp*-g)3KfJR^gTZZf@oGsRaIRoRZqDD zKzJ4qprCpJ!i)+vLJgFfK!KY3zRxH3y--gx7H9!LNvcv+7pBMsGXN0;kzt0uEU^R- zN{yBx!zLDhFqaAEsek|g9MvE}k%X3kIRwpk3J9!#a^VZ- z1FsSa?wk(vjlBUNiEjZ%gnev6YHSnH#tI&=21U9=BZv^W)|Vx^jNL@U5yX}uMQKLF z+IG1c03@FHA~Bj_Pr5^x0ampm9bzkJ3zme8Mk_4B6MSE?CB)GriBp=;I@~Yl7^tSF z1Z{(ejYCO2a)c394McI0rYSH9bP^}BZ*4yz+z#Z6nV*omj z`wvQL1jYq1jAP#o86sK6i2a@w0e}u2AS0w72!0miqh&En2mpa$f?O`MJmgYx_o9Dg ze#p7`AoFZiSsVGP%ys%P`>4Q21wJb9eJg+$41VtL{|7$?d}(cP;a>zBlE=kitb^CK zKe^giI77(dVXr9`0Ro%Pz9ogVHP~j()nR@35odzc1qHxjzKjbV*2=LGTo+*q%_IQu zuCNI1HGNH5t$(AKiRC5pg=z6(ym!1FU`61K{)*)Zzu|8k_Kkn-nJ{; zF0uf=$+$Z10ob5*z3$>3z^%fctK817-tRM8SBH9w?-lU|;5Ggh#k+u)qB8LDBLAJ@ xhT;7+9wTlk-bXw-$X5&xDZWDdGX+=eF=F{1Aow=GmK@m+5f7b@mik}#{szp(+I|24 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/doh1.au b/contrib/vtwmrc/sounds/doh1.au new file mode 100644 index 0000000000000000000000000000000000000000..f63b6fc7a96b99df10b0972c2644299d3b1425d4 GIT binary patch literal 3600 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 F{|mbJlj8sY literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/doh3.au b/contrib/vtwmrc/sounds/doh3.au new file mode 100644 index 0000000000000000000000000000000000000000..399580f17f2b7838327de9084268435b405d2bf6 GIT binary patch literal 4927 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/doh4.au b/contrib/vtwmrc/sounds/doh4.au new file mode 100644 index 0000000000000000000000000000000000000000..45acccbfc2d979913fd7aa04cbfbd148201b71ed GIT binary patch literal 4672 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 G?f(Pk`%{7d literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/highhat.wav b/contrib/vtwmrc/sounds/highhat.wav new file mode 100644 index 0000000000000000000000000000000000000000..0c8240fbd284c87b00c79d6ee8ed971d2156dae4 GIT binary patch literal 29646 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
xc7Gx`jQ=Mu5aBOJZJ$Py^AbOa|j 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 o_{@f@%TjOXb* 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/pop1.wav b/contrib/vtwmrc/sounds/pop1.wav new file mode 100644 index 0000000000000000000000000000000000000000..6740d3fe4e5be1449441b63c44399c42b8220eaa GIT binary patch literal 4758 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/pop2.wav b/contrib/vtwmrc/sounds/pop2.wav new file mode 100644 index 0000000000000000000000000000000000000000..1b69cd1d82ff109d189924bd127e3b4648cf6fb4 GIT binary patch literal 1419 zcmZ9MJ8L6X6vwqiAYB6c0UU6V!i5VLE>uin6r&hp7Go3>grfz&Vq0Fzdd_I(KIg3& zT|KgvNL&~pgjvL5j1gur1{W$+xKOc$i!HX;50Gz=bH^b?&M?EBdmjJaIaj0gpO=^U zSFzYHKc;@#%@)4!nB)xqPZoASa;(il8W&yNzbbD7ro^GHw3CiKDN>9VpmH?u;9AE#&8cl_nS zNiWVM$<^b7*k4{uOQr7JbY!Lz%4+4}VLIt%mlqb&;b?jbib@|M6+u$}Z0@Zn5EApC7IyGOYJueAlU@l==8pa6Orf{DZZ)a?~C@PH(JC zazWV(-aU-ONosZ1?!Uho*7EDh(vE#T=)3vtjdUrv81~ORTr6`T>gGv0mD<gev zW;S<9Omy3pcD$SCqH|u?4l}xhA( zg{xHzEJFA|11;Ka;B)X2%kk@V$K;GVpemgzVS%tj_lCW3T%tW1`c7@&kSRg+{e(dR!ASpvdz2?m>>uc@k9)nTOA07=k< zh^nSRgyb@0EGYcXD4ZI!2wqGWh(Uv3lyOP>91GRCDf#6_)S;Xz>;g(OUh;1sgi9#^ zq){lGB8CKH=!T>Ld&ZIr9r}^1a&3S+qW#Y;Un9e^M&yiyrRK8(6rNWA#{l&osUEvT literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/pop3.au b/contrib/vtwmrc/sounds/pop3.au new file mode 100644 index 0000000000000000000000000000000000000000..5093e9165d9530fe7ae71f1440d94068beec5c57 GIT binary patch literal 759 zcmVxskdmK991;^8N1>FFnY$$x6B#k8 zmXesUDHs$QGOCx8o4q9$6&_8Ym6oDK9TpiYvYM5g#3UFPCBvPToVq9(879M>n4QEX z8XGONoSCFd9~vJ@rkb6(D;ym!vYni)I367a(C?GAxq@uSoA}3I*qOL?HCO)yGtXC-~JGQ2*TPi3%wWqI3Dl1H|skuBVFWIfE z&@wDOyR5fHEi&J)ui-Nv_dwu(Tc>eu+{r7%*{r-G@{(FD@etrD?ef|A? ze*JuW{(XJ_{(k=be*XS_e|~;`etrJ^e*gb{e*S%ae|~>{egA*|{``Oc{{MY^dV76+ pe|~@c{r&y@|Nj1deSLlZ{{Mgf|9^dce}8^{e*b^}{{H{}|9+qSfb9SP literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/shutdown.wav b/contrib/vtwmrc/sounds/shutdown.wav new file mode 100644 index 0000000000000000000000000000000000000000..f74629f369f4df09ee937070301d4673cf13ca1e GIT binary patch literal 42830 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/splat1.wav b/contrib/vtwmrc/sounds/splat1.wav new file mode 100644 index 0000000000000000000000000000000000000000..fd15ace716a60b612b7d5b66b12a945772aa6078 GIT binary patch literal 3734 zcmW+%X>eQDbynE^Xwqps_S9}ViDXA!>B})1OYB0!Bu7?idrmLq%3P`RNJygk)@`MJFzoKXWC3Nb$(!`&z`s3J9q9q z_nhy1=R0TXj~@^HaLbmCBki?=ko%?Qwrtt*J>_}!jV<4O-`nzc%F3Wx>;7A1R4F@k zYPb5^k;Y)0Vr0@qNCDnUpiU1MiEthvXf?E$t%#T%cNONzGiF?6>+1&(b>DOrcTH5-1 zOawqsf5guPGTHIc=H}u;+NWtf*3j$bBgv7p6e(mG5+LU8Qzwqsb@r=)m(EO22cqNS zGudQz!V59HcL2ibcK0Cz7MjEYq2crtZzm?=W_*6s3i&4)oeyM|r$(o;agHRMMzcZP z)!(P;R~tQEj~5~20L2C<$bv#zH;MC!%-H1kL8N@MdEE}fs9otv5nSb95EHq_M8G!y|%M^BpMND*ofQiCY%X6MC%W~(xqsV^rXgcj!vH(8n4iA(FC|Rgx;KSd9B6bo zZ>f1_ZyR4azZ%Eg#xDIJNT$7wyWcrv7BAisyIcCfg|EtYYo9;iSpVjm>Bh=`dWpIE z@Y={w;~)UQ-P_u(HcPn?$)WEtQl+J**P(r{?l|C_yZ7mmpsMam|LVpHP_^`0<;gH* z(y4v<3oAKWXM+}u%+b~P_YJ};XTDacZVx=uo=*_Md@%a)XL4+Hxb??PhYp^t{&jf{ zmd5IS(qlag1s3kjUHkaR{{`8`5 z+o5rKC;opERfUbMf8+n};GRtR%e|UEU3&gmJF*l0b@_4U_ibZ!4OmkRvrP0dldG3X zt5+{xO;}DIs@bvA(yk4LOk`o>!DshpUF4ixry}eB@#Ry{@Y3!3(LoR*$Jf`Qrn)2b zH75s%kz9W9((K&A#Fz}micD|i_A_{Gqm+ym3k(>Uy|j^XscLt>Re8jeT`iK*)bhp2 z$(S3)^^jc1rQ`0NW=KrV%#84|1Yn~N(lz%OEK*Awio_N#Tr9Mmv{+T)yB~k}fq9Qt z-)f9cMoEs9etQW&_i(cSbhWQ;uY)nCJ8^CzKRLfpkS(<@z0QBO zVXW?xI0xbzatx;dG57S}vL}CDO|G1So2rgdPyWaFee0i}yz_jie7(-a{OmdA4_6w0 zfn5z$*RB2a{3*5AxxW+4(a?j($DTWE1jSqb`TM!9Lk$`tB+(q)d%6RRMNAE9Ru<&K zjeB{wgH2~6!B`Mc)mGJEi_7DqqWVykIy8S}UFbZcCn94@*XM|Vel-+XoKF*7M{6}= z%FhG@m(7K9@gy;*cQWz9>Pl3SShs1=N{6E%+GN7HDC4mENID#6h9h1pN(qTX1Q@!E zAb)##@Xg(>4}P0FzP%E?_~`Mxwz|o`esgSK_qIdQtw*KaeP_Y>#}C9KuN`nM-e0sI z-P;k}ycJc~9O&R?XIOo|MVjBd8de{#A4*)fobhP-oXMGprM+E8kC&p*fF2ai1zeh5 zvo!U=CUf+#ZSv-9f8|k2az0^dZMVeEO(b~4%SmE@Lz!qi#33#!5D7Xvb>vhIwWwNj zRAlYZcyC?3J(JIJc28i#9Tq1iij`9_h&dDhr>(hEIErdaTr9^!W`bs9R*Z?(0ef(|Kn+^z~;RmYQCyWUs7~r!{j=uNd|m0`D!-O>Y_>Jailz%EYAr=O!j* ziGGJXEC$>iJ!C2c3`20L7_gY!I*?|hXvR2D{7vU8vt_!X;#|4>^NMHBm&+$AwmmAZ zKU>lIpjs%9_1lJ+ToTqf!dWoT zkA;I29ZM)F0W3eiLTac{{nnS!`(IA9=$GC{D-R+wd1v>~aE`OWi9(2xLyXHoa<~@* zivJShH2Wl(bYKk21ws2T*d;td*!VarE;dCvi!{}&usp= z?z!Ys$LqGWz$xSWyjLTR;#yyX@qm?{vPgaKoS zRfGbuQu!2Z7AHYB6q@^&(XHEVl;Mhfn}0a}>MJYvY^Fp8YI2Qoh#Uh(H^-sAP>v>O zw+mx<07RY@fXxw)p`omYMmszUC3A1;*0ez_#9TdQAqX%a5_T*U5=91psP%N_j&Z+t zDW|n9O&w`o%be1rLQvw0s0C5j6_CA@L?RS{0Xa_E0f71W(ym>X^G$&{WN0`_;4J61 zvO(M}W*D9SU%9u$V5Q^32?rXC(b`U*#LyIsx!A|iH;G_dXko}PopzCtQJ>c8!$5#H zIYx4X6M}>^!{m4^8Ad(0bNY9>AF;zH!W%CAa#qKs%}|2Uak32`M#wN>Wk#|zPQ(%5D8Q3)#D|33 z7J1mI_I*XYw)9>FT&~$W+hpEMhOQhihA|E8ak9Wdi8xR^F4bNCYq~5CZ2Sahy|_&2lWw z5sK#1JVTO9I&)YUZ3UmC-;LWfA0kH=#lA`27^5r^U=IOD0CUT*5)eF)>Gl{&B;8EV!41157Ady*irPqgXoQ6QxWc71 z*qqy2i0)p;%u{A0WtSy4M|fy2OraD-C|C&s&C{I7FdW0tEKAcgN3kry(iF=u3=NbB z6crY6iu!gc0w9x=vaE0gC=v*GL6L9{09pYQaDG4lh7?zzh6rFdQjlm=IR$XQbF^1U zFsIm4==QC`lYkbK@CKQ%pJgQFIwhd*%uw{Vu_;rERmfr2g=4_WOAJCNYf5jR>EQ@z zIh)Np38ldRlAviHuI$DL#k7(cfQtZEQbhY07MDe(npm1p?*Gmt4H(5|l%sG)L}@`VZ^B(DM;glM=& z2t$O5KD|cu+S5*mnQEfGs(0$udZmunM|DH-x9%c3h`GWPzVd{~EqlrG@{7nR$4i?b zj9-ls#(iUqkt%Zo9N-XpFX5ks7-2v>aLcn5$d3-qk5?T)mQzc@~iF2t|ur{eN^+*Gxb0TQCR<_ zD~fdegQzTeixT3lXev9%lVY6+mSw~)(M(2*hum?pI4*|BM{=wDTV`RbLB?Ps)K~60UIjGtU2EHCD-+=K zTNqqF@Njtc0@sSyFQiL!D88-GuIS&hWRdsX#lHGKD|@Zj>C^i={5}5f2D@_Zs<_*` z_x!%7fGq%jCUtl2aLDA zF+qdER!4Trbs=AuLRpH|FYYM0yp*eSK-rsR%azMp?sC~DWqOnuS*A&ufHE^nuP!yD zWYH3Lixnt3s_>M8zWGPx5z*HoGr}u}Z4G%AR3TubZzG=)wiB|a&??Q z^VahEd5?HTdMbE=JPX|Y+=boIZa=rzwaER-J;zhpyVM(PUN@&$m#p=whu)+g=*{{& z(OA?G(c+eVsjusK>=w7KCQgexqPyHLJu+VU8L{$!oGOdUKgDysN?%diR5kUlHQ739 z&9xR;rqxS*$F+)z=c2#7$jUb{Y8jJ^S;lbVrV(Sr8^V@ogxex*H;g_;7o)IoSgw>! zWx6;a&Wnv=iWngVitS>OC?~?$W#5Q{v-%I+Lyu%cLE?gTh^IPOye2yO>*czeZlgQ! zr@3CNZ|i?`N3P>9+sN+nUwMa!cq8)|(MAp9mAorE%b~KmyeGbi>*6R8^`7UdN<*v`D==XF$^68{sG+2c+4o!YXr z%pvP>@8L2)#){u%W$EC`P2^Kzwxt*<7Ko-|wCFF6iCf}|SRrnRGvc;5BL3n@HjD0} ztgsV}!Q!4iuJ`HQdLa@1y*@ysp5SjkVdMAv39oJ=@`+PAPWKf(#YoomNA6Tv4wJu0 zU!%NH-&kPeW_`OF!{i*fP7Y$Wn#v5ZLBxwkVzpQ<%8QTsn2r?p`MWgHAI^0wVSqOO zimj~pCSEJWDq_E}NY?N5c0EZiV*U1lX-$Qt>xmZN(Q$q{QY>ODFZE>INBcA4xq6I# zt;Xu^x|dGTuR)lFV98GLCo^uBpF|edY~SsBXmW5QVmvBR4sLe>%F&jTEAE|tmak)YlSt~ z%B%9I(rUEopiZhCDqa1=Sl+2Jda5d^H|VhHsm?shE7gab zG>z5UrMKu1eOt96_q!3Md#CRcz011rlbld!zndaT~`g*nOAih>ljSr<(Id_N;26e zF;mW!1LPICSY8mbiR>(LF!`yGEGqA_)AooLL0%duO`3qV6iMs;)<< z6g8bFoTZ~!|J}NSc%Zg38?RLe&wD_9X4bUoq}S-e`kCs=E*Yi|k%zm1wl?-vbJ3od zIL!ZQ>jCPhYO5OQBD#w{s3+=uDu9_e!Bbz>pY(KnkgqPWl7_y+D*wR;?TPlIj&Mh`Z!h0`j+MU4{oeb%4zLH! z3ObafW){ET^TGXs*Jmk|rB~?VtlvVzv%9kA&hcB0Ly^U!?q$1@ZF<;4`^Ky?vRAH# zLCwPtWVeSD4%le6N-Ftr^t(zgq8>(F`T1DK-PJc=-x#wwWc%}7)AuYn-1bDvv!Bmj z|7XwD5;wNp@q762S;;r)@2ACmP0Lj^=@bLtkcJ7kxTk<-(VW z`Ifv@s!{2|Www=lU9L}skc!b2SCp?&u56iorDm7xUt($TBE?)qIv0LXa6p04`4;C1 z$~7~`-H5R8pR;xi$&=-Az&t;@qlLY^aYT4@6}7NwiaIe!_+q~t? zZzg*mc&G5{>s{gf%lpK;)co5_HiugCtSeS^m{X#vqf6_qx{9vFPN}T3=$q`{C2FWD zLiGKu#;8F3JJGp~-MCLpQ;St)BH@q~Y<)ES%*)={-X-4ey(7Kryk*Q-v$1us)o90 z&9=H(3#|`klvUi?Zj}H@9w|S)5;W!-!RX5h(hKu3{`` zyi?2|5B^Qed=@bxKxU4nFL@!q7(=W_gYPCdd;}bhBm(?JE-)YrM$un~>p=LzEk?3l z{jAEVXw`_Po3kE)UuL_ifiQ~#`AkbC||b|@{b z>!MC>1A%B66NJ>-t9qLE18_iAv3 znYsc|`AAjMp}H@b=SS`lrL*$f1&Ow2%*<+j)?Wwda=h=WvVotOab8Fl&;h*rz49kc zOEBi|;UE3TIey}t&MN-VWkA2_WXvrhi5!s*V~2giID~u)L)j%7iWI$$Xr0ZKt7)g2 z2=nftB2|Pc4kEs^Dym!VE_~HQ3>HCRu`UE+&ShP+N+Kf!!W2UFT5{t^^50E0n$a$0jb_48iZdSzMLwAm zUNTSyg4;7>B^cFi@vpcn)-VI*WFs+5EMc$iV0Au-HZqLSy%&377-gl4yLJ`7kg0aT zpdK-A5uyvb<6q`BJNfCe`cZGyzw*p;`Cdsl@^yWS_YTo5nV0G8AGZ?vK3TbkE()qQ z&`a3Klla+Ay?_Wx5jN(gl`KKd36y!{1o<61B%GYHP>zJ7{=gooK{ktp-^9Qlnh;f8 z$*dvbs;(;*!0tS(Q!}!_WEgujSjQ>$S6!IbN_O8joun(Vw}zAT8WAzI^%F+(RvjWP z&Z|%u;Rw*^HW?~ZOlLNW&&m&SnXDnd%4GQKQaM3%fSLX# zH#1*;a*nPezSFlXOF48q)lYZUWkK6?y-BptlSC`0bov&wY{l4GRWNVEfT~>5B z-?>cF(Y12tDjn3%+@8=Zw)3mu*Aos_S~qra_up47tiRH+DQ;( z_=!?$%g(DXr1JMw?^k)iNK7KP|jB zf5|-cqt8dxjChzWG4x25wgIV*Rkq0@LJc&FdzW~cdHg+>-Pzn(T$7zS)7zv5r!-7% zn)F>#SwcZ`+tzrIShFjUJGM2}@WoEZRt!3s^ zbFSIi>}$T}r~Ayq)&Q7BUNKvAm0JFa>(I)`WqgsNQ7OY=eEZNz<5hWe%DQD0gmI45 zg++eiZnNA+B&M?hZNzW-f;wPrG-JG}DAOeO7WZ0rkSB-df1XL?xRI7GdubpMv;mI& z9r)5UlN%AUBV_^O4KE*CPTMKtx^calvsPECW;hN^vV+$q-gp!#+^jaXG*Cx98J&?cL~fPZ9pqm5D1Xp4Hwi59A8 z{9t(5i}Trir9>?IsJ0jdO4MezUX#1!1Nj+u<21@GR4x$@$zOxiZ7WkX+_b(~B~^ws znd~0J?mVmukQILu0ivKNLo^#AKl-5xapDk{b+~BD+}sn*iIW6r7>ng}xMzDA4?3R^ z^T{)J)Btte>S^V%u9}ssAy!i>3_s?UTBj3rH1VGy`pJnhtI^-+Wt1`eQJ^&$(@Nra z5bQWNn2{lN>JZe_XQDJy5#1v;eurh&B=QsVbNv|38X;c6&&!gVDu^E999-8)Mmq|6 zZPI7J_HFQ(hGe?e%vd&1`nmXlxt}RV$%@QK%}l2TM9YGPEhw^aza?bJHh2UT^bIh2 z28!aUI!vCAhEx2-PcP|mqB;0hoOf4b581^ZplP)Dj?v{5cVYGe$xTf}dwCQczsaa= z&V3C{mq zy;iCG#tHQ=+9?m%s8uhr%8y|CAkaKT=OcI6q>pUCekjEKIvQtqsu?JQta2Wn)DlsP zQBM_L#1Qd{U6UZj$(BX~5n+VDgEp{ZBTzLH)qZP+b=kUU-L)dDLDn2AS~XGMk&72I z7d3g$1=WRYK8ZM4f(G13?wth(>8U%x35IZ$EhwZTti(McCmzkQOeE?H%=;e3xtLj9 z3R+i2yNtmjIFAp|4@F{U*5|{SzTa*2CHCH+C@tUESE~xuxsp{nSn>q{rNgS^j zc7Vakr?T$lMPbndExJT+QC0C&s*rJa>d)HJc64h|lt#Lmiq}(wD;9>kC89*@!6P4- zg+YtO)=*VY=h6A~d0j#H2@MAvfJ5|DZxcDh3^K_z?yy~77RU7*@w+H0%YX_CWFPq# zJfs@xYKC|%T8TsW8aeTxQo#1nWU|lNsSlHvr@{yJ$zMetBEl|%L{|9+d%&MeGY?&L1=&iZs_%6RwF}PNR%t5|J=p>;GbelbKG|=Rt}6e`bbV|ajZwC_ zwo10@_G|W6KL6TZ+j9E6u{(Y8I<7bzj!lmKj^p;SzAe;sQA@eKAIv1TsV>D&5bH|q z%I_>(zGOh@AB+B0pkdf9{XD((*MlGY-d%lO<9^8-S^r5mWj_&d*6+fqt7Y%rc+}`g zwr3ZgR(aCsahYd7zZ~)A`}bu(&X3I(mot7_k~?*8MrH3fl`LA?>iOLAy&CX7cuKYz zktL#Q=b4aiZGqN>HWuzvJ1;o9WjJ_O1@|TQP|rKhYHv|g#F_eqQSOMq#6~58|k7F&|)=xhmKJ%*^)_AM0^@o*Ytwz`0 zROR$&_F)=M)mC^^BRv;&zRD_qLd$9{Lsf0^9`$bZ{$j2-UFHSr4Bqn&*y{$JfRj>B zjDd0dP9)VJ3ckZFwq!%YZtKcA_OPumrlWS}$va{(xb4<=*c~bCal!7H$^PE~f32;r zS|4y7_NYwqU;^$L8g-(*Kn;Vl04X?W>ju3b#D z7Y$J#SFMq%7*0|h)W=2T%hNo81$QEzm*GMA;=1S44x%c~O0%-6FO~xjq7oWtC3?On zF};&LUK-|hQa{51ss#hP4hLUJBn`zCiU*yG6B*6G^3!-{ZE#4Z!q3Lzp1tPDa*A5u zou3}5E?N;P$qL|4Pke^uD7f`p^Kac)RA9 zTfo3s#Qy+&kJmPxjK;VM7EJ-c%i$kY<9->s6YhQ~e7qH8o#oUPdXUvR5p^MOfHOEj zm-zj+=#W>8{0>p6^&jNC3_Y2(9!%!=MfX-yl#?v^&{|{p^VJc{gTt1B({{-kq)xLU zht)7t#ui-zQ2+tL}@i@nVfBl(VA4XnOY$oDQh&ZsT0u11@e#kucQ2(>G zT8FG@R)6aUYpQhtzbrw`fbUi%dp8$L`29bb=Y7ogLi9jcshO7r;wqlxDP0}ct|ZyM zE}FJ9xv4j^FdSd;CfvBE_?h|N!7j{X#~*b~Ff3W5vM+O?Q8t5><-{y896xuGr~=R3 z1`BS8vMPbHc>=3B0yDp6WnuIez^q651ZuiFYZ)SzlH+5=IOZ`*6xW+^t2(PFb;T-a z6{8Ap*jv)v>-Boid4Kcf_WGDjyxF`TJk`8QJ>S8lnwsOxIaY04_yRf%wlf^BZLw$x zQ=V$PGZq`0jI}b4?Sj$IxNLO7iFX=R?C0$d?Mr=veG2+K_37_8Y~SWn(dUHYmXGwA zV{dDFWRLV2FME((%|oAn09iq3q#d*|O%$ zGCJ_K&v;vgZg2I@NJ*a=f8|T=53S!uzxwUvtyk;b{2sIHeV&hZKfe1^^i#`Ei(|)p ziHNKGH8{R>!i&UJ$!5x;^aB|~+}Auk%@tN@9V^m|_x7f~2mH?lj>u9wWK(GIu({b* zgs;h7I%0c-6;UR#LS$;h<%pjmN=D>}Xc|!@qEf{6?D63>!qGn>eIpQG``8TxCXJf8mVy8Th>6Ui6yM5roTDQ+sT{Hd&85@o7a276Xeb5^?Jg+ z)4U_R3EuAD-gR@bl^<`S2wD2A{tN!}2|b@I&XRANB+>{o)-w*thq9P) zmukc*>V-Ar8IYq3Xl2Lw$VOFV3m7<$$X=^9<8jo589DG5dcnHuvUet;4?7b7x!`1n zgjW=lzoMfr%34MhW1#Unb%ImIG2;l;8%vfl7RpufI{xWw^y^`2Ecs!c_sG_tM37v8 zlJ($w)F7k#lKH2=I5xovud6evCk_L80c_ljzZ?V)y~ntg!h8P{>?Kz8{8WU^4$>;#ME?R{}w!Y1NYd&&tu?j|LR!K^G7_SE;<-29mJC;ZNigJ zqMJ+Ui_C3VwZi(->I>R8z!m<2n>`SvoEMy2AQW?YOf14Py(%K*HPJ)*$@+2(JbxE# zwYe_iqhzZU7rKU_LW+Yf!v=W_5tLF9`;$(%l&AZf%!U#YOyI zKNza7{tHGwL*>Kq$xH3^dp%H;)aTS|ovse((zp>-WRmP6=Ne1JPsVgv+Nf;IvwgFl zu;sTcW9F4SC1T_vT%T;r<9?WJpq}DA;4MqVaH97gkB|GQ+vBd}zVANiak&5IZsY3g ze3Wu3y+r!Pw8V@p-gQAYvyRSrEL*WWt8=f(u{W#JKS1R69`dYm_DMb%=l6c_tK}~S zyy*F&=j-H{da>2MjZKP9JDN5k{d#J)Z@e30kCH$EfmozT*xij4ppz9h5 z_Wh1XzYYF916O9L61qF=eRzY2u8}gTP1LZcAERth!y*?)OvpYv{CT#;*^Xzkg*Ojh z8-9*I`NCUg8=19qNSB}s{xy7i+GiPi#XYsq8gAzBu5th6+K{o|Il%cgeMkDG^iS!+ z+1}aQ+02>S`8j=B`sDOS=?k6roqib?GWxoXxi-67c*=Ui%rNT_*`y#D=OlHfG`RUz zs?~eJ{iRea&Jzb$s2RMlvOwxoNVTf5`jBRr=(Q^0PU zS$$lcB|4rO z#U`@+2O{BDDtJ#&f^B&wrQE30*(mm->HwUl7!Knultq4c)<-nfRJ~3O@ zS*@)6R)+bP)sf7aV3i?T&!rBL4L`KJ{)u{N5H8_JbYg#;y2`KylS);8;;}f9KY*WC zBJ;Ju*8-`)jy1^rIw;2 zIe850+7PYK15~RiX2W3~>%sU{f-2KISVk!NrK8?UKKvK1Se)5<&3NkKS$0z|;7d`c z^#$C~hZ$U8{bMy!)4_rzcv|uBvH;L%FPx){Jdgf-Cfp#)A`l@&ULuy4!wU+E4lvhu z`l6nIo-NPlhU3=-lWCgJ!(f1e@pMLXM-`tT{~YB?_uvj~;6nd`f|bb(;e0&-m%bgk zHJBN!pwrZGyxIX^e*hlEL@Hy+)VcnLUaXFH9>$%rp^sZoJ^cynt1M&Ke-q(7PsJp9 zC#uRh;NUFQO@W^kak1BexVQCA*wYx;S{(Z)5mnX|Z5v7FNC{gN`~U1Y>>FfR(Nul$ zMtJHvpMU#4KIi8f@wL+5s8`-dzbAq13UA6YC->1pg^CO*crwRtA$#@GwDAdMY*cK% znAF$tPa|G*fAv15^rv!hmlB7hH*x>r-R$Y>xs<*?<;VC5pKHGF7*pfz&u@Q;S@>?% zhncZAzII9)kRI%LWBJOBwy}=B{_letW<3?|8#OCulU(g`Z^~UOPu4s&@^sDpC|68$ z)97l^>!b7Lx}B?J?)Z_F06q(vO^-^kBT8s3a&P5sTG9ujtJi*>- z<_B|tCD6xrsqHSo?Gs?J~t`9q_2ItEqf5eYGDV?%{G1n+&6g7$%x8(&? zK_xkgtaJ!QP#gZX5x?q`s7L+&0o^a5ysw6_8)qjC$9cH+!2kPMBmUza7C7ba{pgwO z9p+8;wl#BF0oF__RK-}GR2DUh3eh)}m;5MM@oq%_6gh;Bf)2Jkwm91g+b_0HwqJR* zx0yyI+jJwuhylMEv+vT$TmNW3xtI*JkNxRKjmOYC&>M%Wf7x07<{9&ecf2{(Th;7u zc7Z4V#7^s{4iROMcv1s+lFTZ7AS!+#QB)I7ABsLpqyEuTWdTD%;FrZ^F*+W~%Z+6J zaQyQN)P&aH4|{R&R)Hts)Gsd*t&4Rr{DaT%qZdTaa2X}1(e=TlnSIy|HS;&ylf3H>zMnkuDD>Ku%ic7E%N9=l}>du z8LuQt`or6|f(D7&R|Zq(vGg=F&k4N)Uoe#F?P8F1365SDX*W&^f8znG_e2&p@@9?) zC-av088@%3oGhyvLx|iNxYaF13u%|WVjsTp1)YcsQUc|@l#+M$0jLl=jCZt#9Jukhs1UtJA9h9TCY9 zyCU6@=OTR~%SW8b-Yk1m_6phiWdC3Gr0i!R?nUg5$QDsJJR+=R$dsTz{jd3M_PKAH zWt5adbtkpXZ05bA$8oOz)p|DXo3l`m`NslhXs8J)9k#`<&}D zzGj5EcDri2SCEAddlq=#duLD)eQD)J@kgWhhoXX9RJ8Kx^<Po037y#X)TF*m6XZJ~-X676tHY?5820*!Zo)pJpn9vI0$v~y9>6F(pq zRi65|d~3)+O{sDv5`C|A0(kJ%`k!f7+s!IwHZ#ur(=22au}<=I7p;Tjw3RptPS|`O zRg{Rmul^=OcI6stMY;&2DqP<%(S!MH0Y*7vt9;F$Kj}t#O?LPM%7rm^emvn5=At7r zI+Ci}|4<~ET|%416Y|PO(NK1xru&>qlRq_@WSDUkYB#^(Sud6I(ZpxTf}_-Dyo$j@ z)_H23(MC`CkCzh+lYgr{WsqU6Yw4GCS6FQ%<_4)xjN zm=)j-t`pHKqFMO#Y%#%A11|Wz6?Sig^L6r{-)?+9@S*AZnK8*R^WN|IJpF6K#4*Wt zQ=`)|Qg@{sOL`x_<=f7JSA6*?ZqB#DiB(dXr;l;X^d48W#eh=0(x5_RRzIH5i1)L2ek z;SPFko8dNou;sPCv;XQ7>Zt0N>=@+e=BVxX;xpLii@l9K*;d6i!{`fFTtIyyl3nYh zZ)*^JW;WvhHOymR=NSD5`eqmVv#vG4JZ1JVe>QuYYs|f7fYryGa!>o4E4bu)Z?m(y9HDj>tn5~{Y z&|brCxBq3^V*A1N#%Rhjtdvtw!^^2Qoe;%9;`uTd#xfR$d{3SLq07iCbQe5Bb^Qrj z`d)pbH>idR#+wd;G4&!oU#WO}$9+`5zo@V34UDoEeNXMdf#IqtubI>WmcitgvI4_! z*vEr68RVP^=|Qsg{_B z%&lf4=4uOFSq}OcdJyq0tGOD-h|j7&Vekv^CXZ27p1~_!PrwC#g`aRu9s>y<$eZ9w z30WAuFrJLNiadCn=PM0%trcJC5!pjNTOz-()5gPMN8{qnq%yS}@6QG*@1=s;3)G3l zb+e&uey5HbjjOc}?{X<9)=yo+=S;-KT};ho3o}%jD%(5NoNC7_wE0cChMoHFSHQCGtx>%+l%YQM~p>#LX(R9ojX&pu{t%AGX z#Jhfp#+`(3b_+*nEqnY0Yx;!y#p%U#1oi!|o4GQcRxzWY5pGnY2lh4Gu(@1K&B{fG z$6)koqN+mg%VkvP1(fN1qRj6qQz&d9hAb!*60MpFM^yO`t*R!q6XoG4}HM5>Id_$joUCEr(q14evS;0 zKjDm7j5G=)tf&$!x3vg<{{V#bg%4GxS~8V;?7`VCsM=V?z4P3)+^HGk(%w5aXMA>@ zBs)Gx_E(neL_}!r#Zku#d?|XXU_?|}NJT%lTAO}5e$1Ejk8$tv#Z-HD?){_BMH2#2 z=eu8sE57l8Z-YCBEDvrP^v!p>Z6Q|0p!6Nd`w}|D-}t8Dzf0NGvPd)2By*>Ng7hR)V3o??N+ni&Z)12d+L!E7%t(-_i3YvZK7?s?FEW1#^$z#+DDQB>(b>gnw*m9Mx7*&e3Z%Z6P!#K7pQ?& zN8cU5QN74ICejyJ+&X2ZcrST(@#^EfO?9B4*}=SG&chFiwf0!qRdrZsH{6X&^Z*(3 zn*N3+Y>cmULszA*XB;(=>qNs*T(4x;DWV;J-=>D$n?A4h zFkF+WRy>_VhpCVZW6!sxUp|k~%(%?^JMiA-^aN}sFV$ne_NAZg26;R;xKI<$(Sb2m z6D1-94FH8gBhzHa1szn|lX& zdwJh5Uq`&h%rfNN>1MiF6V|eyo{_RtBK_4mBZj{i!Oz&N^_ zb1;JLWcCZ32zbJ5)s-IH{~0nbUinOP?oKlDHcl1P!=X7i*GnH_L7mb;Z(*0xZ6~DlzNzjYtWefgbirxVW4#n@HC9CYRj%-hP*+9C-GYm zsN}+Qam`Xs=qq_|y);L7o73MK=~?a`=$Yp1lKj8e3miPMrkr+iDV?3(QP%Y0(}p@PvnLv$-qUam4`QIB`o*Z8=7 zF8R##ne6kUPd)xU?NiF})N$6=<>wy|5O^stA#iWt_JFzm)%*@PqJ5mUSH>^KLt-SC zlyWmO&;`_uf`5dv;|}6TzNgEwg-WxctRypwHQF3+ZUV7$(EonHs*dj#fX7w}-0!K2 zfToS<9(xQ^bX#AnW<=2>Rfyd4*1Anp?XcRB4X!I6>PqpriMXC{&Z$&0BUr2RmZI~+ z4q7_s7d%2|W0<@xs~a5+ZIrilp@-?Dk%r&!nJ$_T>f{^fw}_@|Fh6U%1BFx(l~{yG z{|j~doKq>S|En|3z&&gPv-?P`;8)=iy-~$0LhZ_Dr$*Ks1D|$Ya`imvcor86Ro_~E%PZ+Ta)gTEmme{J zhg79Q?Isg!YpYRN=glfS82 z-=f}A7bRMc`muoa#y34tY8gwA6Lu+em1;1s$7h>2$H^`6G$){_H!RM&o zRI1jE@n%MVcBlE-Ybqbbz z2ktZkZD8>Phv;JRkPoXw7vD>6UQG_L%L8!#C=}TP zuFwJ(!makw!T&dY!e)H2TXcKokjrpr`^c5>;_2LbJs$Q%u;Bzzeh3Vk0~%y@er_a7 z9|PF}>BamWlnA5t(35@Fo?Y4wcAm)Ti1KPR%%p#$HS&& zubK5q@gwE`s&J`Hg)(^yzs%{IwWh6=^YNEOuTMX|b$7y@LU%7bob+<#2c6j2d&B-R z=w-H%Q46DUMn~qz8=jn{nj={4cfLsa{OwTO`?#*(_9S#oo}0EbRuTHC7UpV8b($>P;?ptm}j8hO3vWxvQ+Jt!pTM+PenwXENWL;F{u^?^?{? z$*%tH*Y5qEJKhX4$qJ<(C5*i7K#hMhdfT?aqu1KLx4DgfjPH!+%w95`a~sjvSy+Vy z=&{kpBTjLCF%tQA51PA#5n=SFS9Ucgzt+JeHlxKhlAm9|*)#k6uE5*-8j(gKyS6>p zTRAhQlK+;1K*98WErekor`LA^+;bAy>1Q&Lma*u=V?@LOYSo2>5B&_2d5xz}cpd#P z$()?4MJGdfSio`eQhs*yBC0YE=-8=hJu&~nIrs%;aT&aPMNiHHbC227e9jq#p;R0H z=kfD8yq7#t^e3G2{%B4%Ygnbw-2dqAI7dxosytxSvemRru>EH1Y&!&(Eswv~hgnLM z&5W0HU_G%-us^j2_?+>%>$BBomCqKRkM;)k9kv}P>FV+Xb1???FcIFyb1(6%UQ(I)(Lk0S9(AS<1PM8W~l+nl%OK=fH`UaS3Ql+{y^Se zWX?BFn)^+E>yufLNVx}&45Bs_PWGIe5#ex92S2GuTs46!dU9Y~G<1deeW`nHpC$Jof7F?t>@^7hLQ(eeAbU0aK|u zH3ap#qSa=DYOVO*Dm4ceQ>(r>YKzHStEil1x{o>VS}xK@@IASE47*}B&t8ODP+i6` zl|R++=k|d$gUKsSR0t582PDlJr4FyIV9MPjq9yA7BUX1a0TjRZtGS(-X({4VAT!<>}qBFUYdCaU!kK+&U+!x+A)F#(4`itgy zPy37)sXY@f$4&k)@x`pCeZPJPpvNW4FHv*z_bZye%=G{>Z@KK|qMU1#0| z-`JG5bKcaAiT(KL+ov=?wa_On=vmmhh^xSI18L zJSOhv_|&9>X^mWiyeF)m$neYQVDE3sWv^%NZhvm~bHsDD>L*7xpKA7M@cFj3yS5v4 z?c;T%`mXb9?7!51t-r%R!8fnNM*VG$eqddoIejXOG|C(6`Q(Z5T=iI<^7N;S^@e)q zc=CJBx`(@)yGy%2xE{EI+)h_f_h~B2ZM=)AG4!Wuc?>o^4sN=EQw~X>bXhntH0G)k@CltfcGd1iIo5YY_u~cta-Whg&t4(-L`5EE7;239`8{&-iHA zY(Lw!+pZI%NBHWZkr$>uP~OHtDvSzQ1bfu%iu35e<{(KII)~5D`_Y1HG$t;>=*4`9 z`*0Y)e4v%j%3))(diJnzckV zMLX4}CRml&KPt3ng%4Ss^MGS%D2&Fum=|{k(_@T1h@w?Y{ql1Acs4s z?WW>HB&u2_|aa4xID4LYd4IGuy}T~jweFP)*=;1{qn z5*_)Hv1Oi)n)F}pPoXm)4R_?U&W&<708^5@=OQPCy5R~8$D0YmW%xxu1G%dHS6}`e z7PE}*;}5W_itvd6WVc8;8kRbXZo;=XAS-Z(j!-e13@fWch46uxPJHLYr##AiM^Foo z)F2^lMGQ5RzIdUh&1dwR?y+n*pf#z{kHR&MM_aeSNs6})(#uzaeX(5G@hqCaMQ1V6 zYcQ{Tc$PWX>l5fbJx?UGh5P%7SyX$*qpe24oc2*=Swn5)SNx!PAj?9=^a(!M4@UV2 zbd3bP4zmJ((8nAHGo3_M*-KTX7AJ~NaD|+(>1Qy%tmMo$_*193$_c#?Y;1_{9HN$4 zeK_&g#rhHcHNlhu*LLd^GaY7XPggr|ddneBqkK=ai{ap-Sno zg$EW`p7Wp3Gd^29>k`|=4tqE2?dzBkA0ofRC6#q=6pwt~26YVkJ9}c}t;j;zt&m>= z4%+Hi{uyJE>wX*e`S_>k*k+%X$8Ct0$+q+`_YBil-xghr*7o~8uN)nHxA+e6yX=21 z;BCNP0qOo3ekJ`|nFBcOjoQFxu15 zPj^3%c95m%5+1yLuXU+n8Og zyj1$ez*@%=A!G0?N*k?>MfmoWjZk=vrYGznED@a+_SwQN8h~zkO#X_+ z-CoGfo%P?T@DX??Pk60h*N@;XO+l(;v`JH{4uf$Yf41gZhpp3`t9)-2<$KNX;Etgi z$D#;sl6yykGN-AfWrH0I#_g^T2D#yN1Igcun1MpDvfRdxR1zLjchqpe?Wov9Dngm( z^4#pwazu9!e(5dx$$p0eUY9TA4@RI7PlaI+C!U==K@+-24}uUg+1-_R?^=4%3WGkk z>52OWL$RTNP7`ktVgwpy6G(NzT0qp*C2M-uM74RH(mzdiFfi|XTJ z*kNvv;T&$tVvx8zn)U|Ye+$!{2rD}-GSB*TgCVs>O?1N3zl9&N2aKuC3VctUVK6i8 z!a?Z?4z`0mbrnU?I0{Uf#)y|w4Nk({nT0<+5v+R-Ysowv{{*Dp$CI?6$2vvrg(;<2 zZU4&)Yv_9_%TLpE9J^`l(i2{>j8Ag7C3C@~+pv$cv5SglB_oS*0?n6C zo&?cin33zaF;QsLN9dX_I8;|*RORUTTE#e`^jWG^+o-%$!SDQ$lPl|(u{C^W188=W zY_|ukS&@;=0R>V()^f1H%5*~Kq|^B_*&rLw6a;JAg(AxQG>n$yV2_egk8G4jfO&H;tu_TFO5oluh(QT7XA!7cH>>e7Wgk{x@G z-1>%U_+m8fU{rcO8ABgMOZ=RQZMg4nvgb&4dSTGF z2J4#}#2yG^yd*q8xV|T!*xLBCa)kLl^zG$0 z(XWZ0^qcBi)c3KYpQ8>Z=8HS(I+{9~IPyC>`<%5uN1=3;$MpX!k9V@Cp8F41J6CO2 zMOPWuudcsc@vaGO=_%rw>Y41x?RoAV;LhrP%6IdCnsKg2uFJ01u37Ga9$#;qH_lwi z$+R0PD_ve;VB>WWh+}vQmvbKxwv9|Z3Zy&6Nr?m){C3VW6r&S%AwS)Mi+YBg^_8z4 z@UE`p!IB_bN4_2lBV0segt3loSk2L_t^f~RoO_)GnhYWu^AVlxacUaE1BS83f^k8{ z%EO$g$V)$BUtbV^+gaOEe>_V`edHk2%~NO$Bc-e|CdH)2uk_7kJ+^ zDu{P^rty3Z%4~LbaXNxFb2`nd_v5+Xfa3WcVGhQ?KK$h*KJUecY*Cv}F!{pRtII9S zLL&WdZfchsQ9d^~6ZVo?&Io=hhIl=T(kMyHJmR!(3wnb)!6E0tIa;HUhEX>zOgui< z1wq!!y!Q$Ws3@O2(@Adu;eS#E@W4OQdvV`Nr?Oog#g-4Y)8+E0~C_h<|)@E~{S<+1K z8uW|hGkciln4dAIG$-El9`aE^+{*dXf^X3~Q<1n@$vEG`hOROvzW5AZ@ZY^)-9C2H zChixBcX)&`F5tC_-j@T!>RnzQPCIl4o%gekGCy0OJ3de<$U9W$rdN9@XIl!Qz~bpm zD}{$Rius(0u0BN9YctezVRFf8DzT;D_C@GE-9^`W4(4$txM`#ESeu#YjM{92A752V zeS@)221oDUn-1dMt=Xkp#XpQWn=HWDiJ@{9b?P;^c8$m=`OpxbaZL83b@PiIl*+6zeO?psG zvWGtkzZ`7)A)~m>Z0yE&JI2@f**lq-U61IP!i?;N3CELT4uN&+sf(N-D!0NikH9}> zk)>O}9kw#U*X-AG%=Iy%Xd)vD66fInnP+g$u|_w@1R<Q)ais zeE#eNi62sLxxo9b^Z84e^`?J`pFW(q4&|)-J8JKHH(-(~hTrmz#f{pT^>rGJpGvnOITzt=y)`W8vM$={D{2R{Dq@rBSuXQz(>Kod z_67?_6BnK76-&dZ&P^}L6wZk?Gg^RgPi1!F2s68aTw6$*Wa|9%Q550TS5}~R(??z< z|IQ|gACdV2QN82o*3FIc+nKfPr(2*sBJlD5VPE}#=kb&(gFkiBNOcbk>`fQRFYv>& zblp6#22e#k3J#6uN$LNHN4=czF2cKA zPxNh_^`nN8fS)AuGXOQ`T|)YoruL%)vt)*_)`($bV& z=!aS6a$VBMX+Psr7?p6{w}j|uOp|=E?afu zET3RgRW-M^f>E96es9ZXmHp#RbXW9D_iXXp^*r<(_bl+V@pRxbR5p47yyf|1vV5Gg zDS~tO&Rc~(wtMDb^R0OwZzm631KL_nA6sKsNnutjmeVq`sXHv9Gc*UEnb3|HxG0+% z6{v$J;Ox8kY=9T+^j$FPGVr7Vbfi|Ig4m6I+w0`RrtFR%h^=4wH}g})hJ(OU;lYjh z&L8}*6>%5z-MY!%oj%E8Fv211(Cui~j&$v2h3)-9c7bg&y8m&ur4Sz6IozHbRHXKj zH-Dm9_%o`=;@QU&^G7&u=Lb)i%SoQg1Aimq3%+iL> z@Mu6UQ33jVop`p1^fS&xPyNf;z{=EZ@1XxT;cUeHmrHUJby>gz8_rK4=gWt|Wk--d zkAjwQoXE5DxfR*zNt0wc8@_md)ci4`asi{RK%L2pZ%~O$^aHappDvMDT%ZEfnrqU} z;^F+>Hxx-zK1bpiwWmLEQL>YZzoLlRQ&m1qH-27X{ug|p_GI2f>VGR#ePvqntN}!M zTU@PS)+$!7@PC>y0e7?rIj=rrHt9l(QESnsCvamv^2$*4alKlhu{JP{NpOe5BCLYvn(C=m~hXB5A?i|rCUy~8N`if=^ zzHbx3cZ&U7JYV^0)vD#|Juct>|I>C2{rGA5YGtdItyWDmY}UTb|NC4_AzCzSG-BxB L!F`5~`BnTM3HIV0 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/squeezetoy.au b/contrib/vtwmrc/sounds/squeezetoy.au new file mode 100644 index 0000000000000000000000000000000000000000..8efc4d0a9cbb86381312d5d779ec7afa61bd1b45 GIT binary patch literal 2829 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/startup.wav b/contrib/vtwmrc/sounds/startup.wav new file mode 100644 index 0000000000000000000000000000000000000000..225d5b5b23e516a641ed156c77afd9d340e99fc1 GIT binary patch literal 41075 zcmaI9*M1{OlJ42(ZZG!{_P1}c7iVU=yL47+!Avr#K@eJm4j>{B(2|-=ot0IUrK`JV zcAswlp9jFqsx!Mz5`>6wb2m3PH}SdStH1u+zwN*H%U^E)U$_3})vntk-|r9ly);pY+JWa-%|@e9uT?AMVxdr= z+H#4?i^USvS1NkNzgoS{RgI=)Igaa5e13ygn-Ys2gnB(FP*Rmn+UbZwhr+)&;=)!K z_@3)Hj%`~M$kwT~UZ)GST2+Oh@$^1T9BffD^lvD zx@bCRdM1kSaanj?p_u;CV{w(i^Zbypi|LL=3p%6mcruyJW^|Fcru;OkB(1HPtVTI&(AOTJ3Bi& zJ%QFdBh*VfaU>~$e}5P&q!G~+8Au#Za@imB3dItn8kX()A%wcU!3a7>C#UBZmsii8 zJ*PZ-c6E7qE=nRaqC@IW=zB{lNPbxzS=FAS?3=QuvcC_tyy!s2@eCDuGhG~=oLyW# zd;a3(D^p&+c>e6_;{5F7XfcCtuq~l8^u=^#MWjF%X#f8H-rnx+?#`<0?m{S+KP;9j z^``9xExJNaW{cy~^UJH}FJ8TR{rU~%^()9g<@9(ln|>hTxwe(fVNG6GwITwA?GI&V zXLm10U(^+dw3C#Mh{gpZUP9sRHH|!A z_YOuGK0)AUZpK1=kW|qJ&5x`HnOI3`C0DD0E-x_F%n{o&gH0F2B{SIc;d-zoQm4ld zSTP9#2-K2C*DMl`RQCAM?|x1lD3+KSnKWr$FfHJb1eWUGQr^6Jm2oJm-?ZPQ`868P zeE694A4C-)(g+y-FvgA_MoG87lGW7+sCI-EG0NC8=ux{?8&$65OoPe4wch# z$&MJWmTPFu$Qt>)yg)n|*=6NwdI_$m;XB(~o10HnHYobP35A_K8eWp%|CuRpTs2cS zOjoaFBM|E#J**W{J-#HkGbZo>11;H#Ro6ws-drn6{a`UpHC;zpVM2w<~F6 zMqM}AHcf^bd%H9^Ypg0(q1mc;FUMT1HH~6RdxNo*=W-?)Au%fF8Oq>jE?vMR5}U;d z+6x~xpKh3jKF*41@aERe-hQ5Hkq!;uU^Ja)^OFIjRvMe>7#KXC4Ew1>gRxVkrm0Ui zo;+S#dt}PPhmRhuJ$|yj@swI~hox%M(b^n$Xsl*^rXSyY|LZ^h^^f0w|Lx}=zJK@n z>U1{jwA^N`bg;X%@p$dwgZuaI-Mf4H*3Db1a{KQ6M^Bz^?;RA%Ufdl_=8}Quuit+A z{rm5~|L(i@Km73i`)|K_{rvJwP3*?LWkx@@x4lW@Xx$pM-n)B;A8NjH=l-L|>zli| z0%Gd~9o2VocKQ6(n{U4Tj{4qd@V|NU@|mfv*J=B9t%y?C-`#q;uD-54Qh)E?zkBcg zgNOI;KUiC*yQmMOQluU|{?Jb!k1YNRuXLbq8(G7t85vf3U!eDHv_ z(W*PN@6Nr4Pd2xAa>a^T)}PEzF0Nj@di(9S-+lM}ci+BaEM7goIzK_h^wTKxta|wn zWo7vGh??%-yL0FEt*>v~_?o|4cVXJr-eJ}9+r9DP?CRy~x9{Hn{L4>2P`>~6?duoM zF3yf;2#UJcsFs*5yE{*xJbFYuu<6##o2I6(Z```~m@ei@b=!~nlcV$J%#iPX{Q0LJ zfBf;M_wei03nt02W*;@VR*gpGa=V-BYc%QJy*syWQmE>y8#nL5tLQ|t zr7HU6=bwK1@uwf?;M4d$CzcgqO62#pG>EDSp}2L6zI}ZYHf?O}F@Kw3XE>&! z7q8#E`~JNO?Rop=#l`6f^{8usYd0z~=MHwH1)i9isOt7De(pbEUgZvv13wv{Th3WD z-h2zA-@JYEl2JQ5nvPLe$h>RStK}jl)8XEhREZ?Pa2y$U@Z>3Tvrx6YR?-_z78fsG zzI^reyLazUQEy+re0DAiV3hV24FvPi!}|~JiP?AW-b0$6Z0_zADq1I# z!Q$xr3LW?M{SQC>_`{Ds(5u(4#GJ{1c}+dlB0N6W-`4DV_~0QG-Dk{hBHRz3tZ(lj zjdd?(C7GUGy+E|zzWWyT(yJGjQk0`!CkhZB#vD&&Z)+Xhwf^`qe15_oGx+J|=KdkN zh9xf^Ocy82HyFe8c>n(UZ(hHA`TXK!KJF**rBNvy$aL9!!o+=WpPr~8cVWw;HR{>Q z714xVJL*qQFD@^U2R_E7(;<@zvC@X-qZNaT(F&I{fs5cGT$%r;GVwaej&U{G8>RMyL{$ z17>rGooO*Rhlj-?>SjOBT#_AwxnH;V$e7`HX*h&kV{u>!Pv(m`j>~W`V2x&xmaA&4 z06CS|Nj3Zl%q$--FW^>|WGrWvxSj-UIvtN^vk8t62G9U!B#lu~w8BBTK($gRRx0?c zI5stP!ET`AT0w{}72_Xa;Pw)Nn%@Jx7+r^{vZjX(a|7? z`h8aU(R>hfqJ&wWq=VFN_4;kc>vSW$z9_<5bV6TlnTvtsc{Y_{LZJ03jllB)uV#l{ zr4po3wc764hxPuvRV|0JzU%e}?RGy7x+fE>HJc?gcHR%8-gp>U!K5EGoqpGLB0qE* zu4}dIN_%AOmzgyB=OvABG4va)(X`eabdsRetWKXh8->|LaCm4fW(WDsATH*u@gTR| z><>%#569`@PTg$=)&0YYpVT)>gS2u`Wl8c2?Y{3vr=9ZApc$Rb!@*Z$PZA@&26~xVY8dx?#>R^%JF&ij+=B! zn}cDPv*vDCsxP8}YY%;Y&}#{>$~p2tJwRSz4k%5>JF-Vji_x`{P?ijby{)HZ@K** zOgcV~3xl%>j`Qdw@f+QvMLh^B(?yk_$7%n-8thlbj^`hiBClJ`2Y%jZmrM1YU8q|n zcTmrlwv(~KA&5e~820N{BkTlT=uFyS*YbMfld#qvz8vS;vtE4F+iH#bQ@5I=jX|s8 z4qdxdua9PX``u=6QeLPpdyW_9OGjzm?bX{8 zYd3f~s_$OCsyV^%bZVEUubjfs>$n;A$3wdk3@*IG#E+at6pfl|g~e(8se@$iZN~j> zbG>|$?9}2?em2_QZ^Ut~JPsbThs}PmZl}{qDQc=L0=xHxqOM_s2g?2HGE z+01Hn=L@UmTpU&RC*wW)jkn|Z-HG$0JRe2nooahF*xzc;JDat%9)@ngKK3f*!~SW0 z-x~~Sd*QQowB0y48tfG&?`Kxd`SEqLTz&ShR>8S=GcO&SzdCO3w8qbmb5F)E7UhTS z+0|g1CZ+ANUG|T=rM1q)X*-+sSyFQkn@3*t&>I!3FljiE-HGj}^9o1jnvz34*Um=c0H{=Eu~4-D{NYE%XwTpvCF&eypgM(9v|+Or&ohY#Y<*a z;qLHR(4NHcY2OachV5RpJB<6sh27qGVjVPxUdvxEPgoG17LusBUGbWgyj!e!#d1_C zRJOwSpxke6G=`0`wKpE`l+u#(i~sNLv#8yyN5fu}ZkK=W?G(o6JtueY`f{VzJV>YY z{d{;_dF<>R%)*^Vhwh;K=)Tp>+qo}xPP<#T@7jZ4<5tDf^0HOvH8%^jM(A$kdx<3n zr8lnb)=!Ri_FDe@s=8JRhezq%+_)V#wjU49YPUCMlgEF{%_fDr>y=_T+*tFH-G@%$ z>(1bdLu-9Atv|}UPVMmC&hTXCfz@ufQNGfMPwc&o)_0Sgz4-JvzuzDF_Mq!mc9Y{q zspWbNXLs*tk-POUISsb&=e%L`_+Gvh*S4S3PTf!Lx99!cPq(H?t+ulfK8qf&H+thi z<#F?5)C{6@6qfDzd9T`x$K7@^Z*9fjTDy((*vVPwpvqyz8q7;y>@Rx3!Oi?x>tM6u zG`jVz+PJo{(?2Oc*^By?*Qynh(xBFAi4eMu@PP20|PZxvT`Tuj$$o1bo4|DeH zBEmT6Orp|efACF#~Kiyb7>v<(7?RUyWXF4iwJM*-BV7aNc)9N^0$?p3l8u%FS+E^R2KK zT6y$|_q2J^@3@c3FV4JO=j>z{H7Z9xT!eQ2^3_o_d3QeO4`-93;|W$t+v_hz&EB`k zmOo3KPS0*M$EVirUh;a8dsOS347b)N&rubF^K>s5jAm^=9Zveg;rL_{4_;pkMuYU^ z)w~uxe|eNx;ry)cSL4OZDa6B0t=#Fb&iR$rsJ!k@`=#A{n%ebx+ij&Sr=DI7t!OwJ zjORy#XmEMfpC#e>W!jmX&Fb~u(N$~1y*zjK58~5NZMzn=tbDEA33j)dJ%2ABM$O$r z&ke@OL9st{+T*A-Kk9n@W6ZL_upg(R@hEL~r#+`>kFJ74ruQVtm0DhTzmc>W#r=}w z6}NL`JF;>+Rj-k+Bo-?l%X+`-Iz5b|Zo@xDOV~%#q~|p{lTNkZ^+N(_L1Y)omea@| zI8K=WW~I2dYk7xxOj>NVQq^~BWe209-3jfm)9!m%+*P2tz*WEg+TENAA+>U~V8@4)a%f+Jduv@Don}+18 z^=k33(k$cd5X(5+&zH)D+&;0~a^+yJQZFhhV_UUS&BfZqNANAT9paBVu8ot3ZC5H) zsG#1g;Zzc}$R8An2l?FQR;hBZyPL}$7IJ$g=2dOfO{}(Q`HmArLA~L%TliXd9`vSB zE0+pYyp()}`}PjY<^0}m?r?9nP$}+jZ|`E$=8KgQCT`WTYE9Rv*FC}$GEWIjW0lqF zg!pKvqLgKPq6!Tu;HnpL+dDWuDtKdr!U@<^ide=?$F-XBz!V;I2`IK<3(LACtF>B% zA;k*81v->3nm}|8{@~IPVk;;jEJGLm%1U*)9V@jJQm~e(j;0X%CC)=p>=&{$K%w#i zaj=4%)G{r_%EnYxKE=m`Z7bk{QLAbQo5}LD@P!yFg)WsXAh|^AON0=4L8EAb?3OBy zKbpIH(s7oeYp+F~ukw5O{G0O^3hf9b}$sjzIv`2uB$iI>>9cql*J}Z~+m<$X( zswt+fifX)|qB=oKK2&On>-eQ9A!c}64T|tU+TyRe1dqu(@hV{KA}UsbM%gW8PUNL1 zvqjp6%V@mG`p`?In93!BJ4)5Kzv)6CmzWd?#fBoaPUw`}k*Pnm>@%`&(Bq`2} zk4R=N4m~6U3Ub1flOa8)tV`PKr!5Z|Y*Y*T+eA$suHC+S>*1pZx9;3~!W2YMo%Z0E zFw5DiAAb4ew}1Th)B9ik^S^%mmPo_v%hU7I*?7>2;xmq6H^uWu2eyYra2y;pMFfJpl(A(?M}{l_oA{r)d{@%ul1A+GZB z+4IWot!w+^a~?WFVL`SJ6&-x1IH<+p$S>$jhN{{5G4O;Gs^cNUMn8~GS$K0?<{+EKUP zANTslr=!t==+N|NG46Cn{kCh{&0_vAxAj<2klQyO-n;$v?e*>T&0O)Y8u-!lY&Jc8 z`P2J%zx?{kkMIBWpa1yb{SQQAp1(XlnGQz1ZZE}a^&u3*y>`^=jHdlDuKeui>|}Oy zJfF^3Fb0Z4H7a$xuue>2^U>Y4NB17we@f)#;a;tLP;AJQ8I4HUz53?+pT2$j1Hr!U z-+%Y&o3}5XpP$X=lj*RVB)wkjMWoddqO#qzH$6HYQ~TM4(uikABnLW4KgJBMH)^%R z{oF3$XToo55ALpQ5QN>_+CQlKmKP?Y8M()+H?Q9*kV07K$M4_1eg6E#i)TlqLXXGo zluXf}<09uhYV3E%lhN#GHX~wjeleNQwc|n3V<97I>Y%g^4vX7F)i&3kJi4R!?AF%$ z&VI38ZQ$&8XVc^Jlj9c(8vXq9+jsBYzkm0FSkfuh(2Vr%fT=?KpdBzlItcNwm-LTL z#ytY$N29@PPK3EP>H00EjBhDzUfABwZLe+bu5Ubew6T|ey1uoOMZ0`29uqh`y*zzR zUTnia7GjbIBlJ7cQB{N(<1`vN0Z5nAI;ZZ?1XK%QAdRrin~wucAjoO zU4xmA?r-HtcI@nySs-mM8Vq`h=3P8{_2&6Y@(^!cJtOJ*>|{DTIUR=as7tmrY==^l zaSsvcV3!U1eF!Zu>t>|W3DA(xM~OP9>S`gE-`n0LTK4n_@jm*u`Q*_~ZhQZ*SgBXS zsMW!eW00PopIp3p^YZoc^Q&hU7qi91lpxQz6SljFYq?Rbt?L2<6we=J!AzDewWq)VyU_W22xPcv@@W;f*7qe$C z&n}*yU3_~nJbQk!7!SweVYllCqn71Fot9@=L;%`xnDz-ejTZfQ*zF%py2{t!^~Q;d zpkVwS?(G~Da+^=KwuwtVe)M>2{o&e^jh#K@1)G7SNdT+T*j}Xq-5Nn5?oB$9{uoQ5Xk7rx&&R{dhW$2I!Ibh?EPFGS82bW~FJdpp$JoINV-e z+sbc0eE4){ckSU8c{hT82M3jAt)W0z8g-6NW~1@x6{()%^UJddG1~bkjni?b=|tVw ztym;DL)U5dJ3+h4uyvF1@j^HSqT+)wZVs3NY34?u?iKb94$HaiT`~zu>E#diHgfd} zHc|nTux`6eR@HQvw%a2_Z;W=G05~{4op$?^(PYfBM2w6TgnU!nwv%z%^3(CS*Xd7T zJ7ak?8+Hdr1H}mmZ^eGo^XjEq9jgVqsZh>sZXZ?-cM0cX@*Y$Q`9h^q_ZxKtI$@2Nd|4O!KDsc#1fde`+@q0^4A1v)ImJrv*+-F!4245sr*(ix^< zluA8gQ@R!Cl@2gM_X-6pxZ-}URz1w+Yvp`Fc$OMwr|UA+T3%Ze7#KZ5zZf290Ajxw&sdoa!t-_82|_doAErY>v)$f^Tm=7=iE5G7 zYC5vkiE@*V!pPa$+I+mejTU;00fc5p3vE2zClpPN1M?Khgv;8USOyu!ngZ6?%sydZ ztjB6uwxqxXN**}yI&62aO0efJ8$b)O5HsnWXmSCOI4Rbd!a1ePaWbD|5U_+1}6XZEf!5 zOQcoM#bhn8bU>X^XaYk^mvN1dc%&X<6?}sx0H(Gl#>jd$CUk-gY7AQe8BBU5%X~vf ziF$YqJwuV4i?Y;PXpr3FxyF}GIt`W}3_z0}x zf|;~JAt(?)+#`~c27>@$*0Zeej$jEpJDc0Gsu_#jgTs=1y$U{?Tn`Peiku#KGxAn& zZ)Ev5ux{~j$a>2!z;*y2!&eV*tmMn5Pw> zEHs873Tz`=2rPy>e8hYa0+0G|C^FwhDG`kZHa$jn!j$VF(Q>dPTnGd`&`dJe5OT6R z!no}75?`9Kk53`$J0dK|(_z6txHP^979*!#Fn;n$;5R*9&Ze4V3t*J|C^VOGjJQ^y zvFuU-N(^2M78-dZ_JCtsC>DzHloUT7rIDKuT4tp1c(Zh)&GsTa9c_Z{!2X0G)$Q_5<;82v8 zWo%I+QeI$0G?9#W?GrMP$ zEV@;l6|M%sf|Y{jAYKw$(rd&A5K-wtf%lM?dWD1=@?Rq)fve<(aTknNic5+))2Gli zjWvKQ`Pj@NO zU(7tNHtJ3YM@>Ui6Mnv89-43TSMN4#HO~W(Lb$+WC|598CKba*%S}vyp%=byhIH*XNiinNhzli7T6EHozg$TQNp$JfBcB|uX1L3+mYoQVO)2pkm-HMu2j zvIdArVN0t=Q3_ColN2cYHKAXd(n# z2pyP8$1<=a!YzatBAy2d#MA*fQBm~ACNVG2Y!Bm}8dTpIP*2FxW2OrJvqC3ED}r`q zc)_2NKR-Pqmw#bkp#oaqXZJPRmZ&aNhXPw9t04t%71pZO${KM?0W1SF>cK+HQP>CB z<0AuUr3X;eOrgKXF7iDPjF$imT!GEU$ET-;CtPU)FKO(jmI4*^dKvlATt>+?Sa*ce zB`}Eq6S2~RV94m$NNcLJyy8%O5V|-R#)LvGFq!qJ|I24gZc{Xk1X4DIdX~RZ-=;bP zJEp}ncXhLFr3127M2<_L&0}`U3aD)QCvqx~(jB6e5zCsad$?D(n+hNaJq1uik0J|j z)o`jX8qW|FRoyF^YUr|=a8|ui-_6B}DVZjUhGx8$E*3A9Wt0C%5n`GL=v>1qwVL** z&7z|sf?_i?^@$p*;F2j^_JLkT4J|IBDj7|4JGUA!Fr6Hl$E?}eXi$k6NYOLJjE;KA zjXaoQuDRy_k{aX;K@3+z@S3J!5(<;wO#W8?^j_YFqIXZWsOCzgT9w1PgsPtsoMjkL9i#ql*GE>kEVzN`o#*?6v^g?B53rb11N-0 zkrAKB2m;s1XlP-ffUBlYdTs90o2D;XPjwAz5tbLz9IFT2XLbdkX*D6SJb8b~b6H2? zfQU=#7#mCo72!7cGaCtHSS)2?IoYzg$9>#DXR~`CX6{<9Y>K|i+%utLDPRJ~TJmJ4 z&|bW!Yn32RN|iA<>X+$G)+PyYCiiFxikWe2$dHg5V@=i-D>aITj06ii=23=-JN2qDIrqGY>DLOpKn!=|)#B*eD>(J|Z#@s0Vp6^HKjY`IfFh2g-_2myG!-LmxsI zdN^+DPYCJ|*%2@dvkzAS6^<##s<;r)QESCDW}9UhmJ3^C48n+zoVqlfvvx|eD^gCd z0K1_k`v=(KlQpUru#d<%NH5@u2YFyxVVtrD;ppT-+W}YyfewQ<(@ZdSIkqCJx!I4Q zRE@j_Elsk;ggXM;W^4_zH3vXI3EMn)aQE)5TZFD3Jb3hYV`m=#BJtcV@ko%Q&tANG zDQq4RZV1;0cXeE&cgHfd^VJ5g3#Y!iCD4%tLF5Cv2cw0Y$CgOh44edXG z#xXH+Etf!)jU9+Bgt)O*%2vc)hF7>COoXLtD##dk6`1)Br~;;ElL>~Bgq4hq#LyT?gb$3b zrJ0-Ugkcgx1N#)r96<%#J-pg=(kl-hs`dvoox#PuEh(}Sw%L?1!8Dvhfw9FUSna|Q zgTw=r9}_~!I?Sz1PssK+FmGH+ab=CFY4yWLL>7sg?9y_aNTuykqYpof^5Fx)U*z7t&6sG_rt z!&sr7Wf9-`Gi*|T$0#7<9U1Re-kMN}CL#vXTQ)HaKQY^dG@>#hQLIEAG@fdqHbd~M zZ9>`R6r2uumb4d79?+wr2xgNFsc-{1)KW&mLbeV#Y}Iev2smIY zUyR;^oc0$OrHQ+>Drz$>rgknczwsiqcOlbOnIuYCkv!^tj|N7Y2_ja@Bhva|IK1SzQo(dUV!5IN39_OJ zT``df8n772ij(<=+baXiC=RV-%c{-pFI6phP_{YaMo#-pl<`Culqy#IMR{CSY|~g) zSy>X8FtT4L*E+-K4H*SmCRwSoBY&uvzA>Q?nxkzpc3N9k%bt^8fBPAa(9 zSy9atqf(YtV<#9x#u&d#3swuIS*~GoX1vN~k?|oeEGIc@MrH_z;f4$1u-P`KC`o30 zENjgq!mt!8QeLk3%%6G8xV)rb8qc(}8Ww&sa~wy9)hSz`GOkejs@2!Vk{LQxN-@+# zhs7%s5t_Yhccz_|OvqSZEG5};SVSf!m#uvoE@SAf8lTl@EHT4pW4kE^WXymSi(UsN9crpHbs1qbZ8Vjw zgw(WhIXE9T(bSkV_CrIL6&t&ls!VfD$IX1AiLz-Cd07#E=(}OSM?5gEWxbj?{86>E zd0F5H4bAE_Rhs#qRV3#9xkzqBQzi_BTVz4gq|7ciPt-iqz^sjGB-w1q5?U*p`&4Us zt?D6Tm`d#1Obb;H0Zr`ds;O6#JCjiJIm~1%meQoy*Gg2EEnand)kZNbYn}WcUKuWm zjVkJk@wU}JI%xjs+4YlUk4>Ahpy*zwW z;f{s)GCn376sX}wqmem4WJW7{<9gW6&4Dr-mqZVU$gRL zyNnF<)&v=%en(}&u&^?(`i{jkOVbg8uq+?!1aenJ}ufz^&7>iPpWZCPD<0}KxIQ8QH#y%K=m z_N!6cY=C`iHyo=~AtF&}(f|)Ur3+jLh(~icb>v$){-_ycWa4D>axu`WG9VU+s?b4e2IitkQhBLDz$b~c*d$-D>S@9F5I`g{fgu7 z*P~o3+KGUzdP%J{w7h;`jcIpcA-q+f8g>-b*_V(KV)i=uX56R;_4;I&PP<8?=%lq8 zJHfg;%_J9qb#9fs-FngTH-WA=rGoE(N(kIq49iG-`$@Mr9B)rjCxPK(;s~FfNc)iyz)i-C=&1xS*w9(1sY!BzJT*tVshJG8M zWv>x+TlTQ!#G^tyXczl&vlr%j{p}>KdhK?x(Q1`!{+HPFFvOw^<3=?+>^b?MaWFnO z3~hY+t;%q}(%rKCic_)tY66OU(0w#o>|t|? zxSsCUk2lD$w@NPiF2Z6ZtyZGLYEml}Mmx2jUbMXfC)`SE%~I?aLnkZ+J*(bHY`93|B(yF>_ zjym)llCI54RIJ%SvFugDV#}_!tXfcY6X&3dWYyAUtIr(iG@LG3*U+1ltMjlxL}IuH z?xh|C2f#SMs0Vw^db@13a`m)XsbzZuI;Eg*7p;E8Sow!7uihw)8*7t# z!z~p@jlC$`Z@KxhH`;x&zy_}uLceA=Tg-y06IaW=(?eofp;cur)1)?llfZ5{m85&< z#`U1v zFf6-mtI$fy1^2A5(eKo&wN88hFljRx78|M8u0)Bww@8X^pB*o)as-euF4U)hhKudA zVK=%qxOAE(vG5D^ez+5~>sB)Ov z4w~)e!dY7^p86>7q}Unf>b*{(H1~6E6jU1#F|NRy$6-+n!d--Ow6T>pgT&+N!gjRHD=hYH_Do9kLOs;dTH8xoxirhOLsPp+d{+ z1WnJ6!b+G_qOgiwx@3a>g@05eobtB8|kYPmud0yhVM7Z6!Ww#=q z{dq}?57-LZYWOHAJD`J|wBq!=I-3$L*5H~Qg$*yXh>m+UYXMu6eBA$l2vnohZ8{0L zOq4y9x7?)du!R@XAc%ujY==oA6q)u)c7nixU<({uLU_#w?nxz}v|<;4J`e_`D{-+< z3!SV1-iz^V!O$qypRg*0#4G#`Z^l4`SorveP@o=sXb22J1=t)i^3AWYFJKsE2sO$i zHfHt8R{G>gzUG6Tw(kH(V3zt*qXCR@VPqG~exQdSsu@Q|6LioF{JS!t#i`l?OUsFl|btM``wMMd?l?#iBg z^k~|~6{bD9+Ek_LObx1=vZ~&EZrV(vSJi%0+ec4DQ}z9+T+_+kH`S<#tCDrm@NwCF z^L+V+xytnDPt{((G@bo(ePWv`Ua>DDW;(#7*Z2PUiTTKUtY`ZD|L-!@F007+DHi^@ z&W~Q3%T1M8#mmRli;u2cJ=H*%p;?ZO85RxCe^XY?{ck?X-ZG=A2C7Ok*rvIrHZ$aZ zy7Rhoe|mrQ5@DVkPa~#y8V3$pc&05zCXb34`a)naCs7zel4#OlDT_}4v#~!(qVO)C zw!qkHH$clvuv?P|?4pek8`({^Fb6hp@+N8^4IP*5%x>N5jMA`XrGqZpfADKka02aK zL>j>FcCj4VgS1&e!3;Vjt3%~%LIw-z)`(XUJZm{YH*yO8B5f4BPTDWmBWE-$fK6<% z&1v3gEhecOFBWI5{wSUhm91mz2TrkKwZPj}g9zB1<8y`t0D!i`-l-V;KUiE+E3T)I zC|g_D+~VNAphP|P-PG%7Q47F^r#&yq9s+$NMiUUGMjJ;aFh=5mj|J(&NhBt&NBl); zH(}ZMkKWXtZ{Ehv#?O<3hlixAWH>2;l(~C>{^1j{jYH@$g$dbh40&vKJVFM8;Xv)8 ztkK>fczpyw`8n=UM1RF$G8YG?D-yMT(L_hH+MF+H_1Si zwSy>0glPc6a=PHSD?s=YqQ-sg*%z{d?GnR2n04jorn3`J7#vkGosf@A;tu??8e}vN z$<+aNTVGqdedm@r$U{eY+`LataJ$4N)h_#3zIpxT9S26ed86}5CV*}cDmqRQi!tjC zhx5~u%a<=X=IIqVy{q&2$(#*;-4y534=|{Ji4pAv5v!ETll!;teErqupZxu=fBp2+ zFK^v?u$yz!#rcajFTeZc+n?UQ=B$^O=L=3+0FuQnGtyLeTZG2(K4%x~7WwAoo2#p5 zmzTg<=AdGu6dsdkf>KC=0OU)t-Yk?jA72^KbwD@1Okj(;IglZx-Cn z>GN0bzW@HGAHRG1=HmI~XqI}-lF)}+Kw9c`yWI?M3?~4+zxk0vBuGxeyxEj(Gn`Oh zBRg)V6^FeRV#98*x=nhZu)DSX;NG2^H@^7t%P&9q?C+m``qkZs>xEi0dVcl#ySK03 zzkU7U5&#Zc7#h{X18ry1LWnal5Qk*vIb^X82&KmX*jFTS{O z@8R0cW}zPSrdOA5Uw`xV+2t{NG&}5>2pqOU)XNRWjnd&@G$(5`8cch`)A>wrqn=KO z>GeB;a}f<;uEnTIw5{|`1-xGg+#%_r^?Ucf`s(kW{QYl#|KiS#`;Rvs=W0$gyL$He zdo~GO9&?fk)-n1GP+y_I@s8k>fp07p>~w--gW(a#{OM%Qp6xy(2Lf@%u1_?&kNV;t zktULBH2`3ok5SwQwfyMr&09Bb+_}l=G!O4Q-C5rTFy^+?+4;rs+4&J$BD%5_Wnq>* zyh%4e(@rJ>He3Ph@5Co#2e?_2^o01jo+aYMBq%RR^b2=P~jVEYxlpt`T6HxeD>E*Z+(9I_S){w zCTZ+2ViUug*U!n6Cw>bYc?C6z@-0~$u#t90!x^~$x%L>j&P9^L=?tIt0B;?o;9?mPe+zOkL(FWByAa&*O^MJKZ{ zhlSwDac9$S95NOz-J1;O$KVNit*{3uo-GdJDKmk16->wnmepEI^*MKSFc{4%x5Y7CTSej9>Q~^N8E^Q z1pxVu=Hy=^a-86Az%Y!!@c=&TkzO9LNhGD)R#UtLP6C`(NpCRLJ5QdXRc_t*g0r4( z-(TO@0;XChuXg7M9TX19#%`}~un9~DC*6JU=)vQSjqN>v6n4~`pIw0SJf5&! z0S^N}H5Lri94|`y>|zpd05B7S1qj#dR$_W~Om2HJ0TBx=t;B-78srJUSS4(?x1Kz_ zd+Y0)H}9FlzqSF3HTi$YS6$n;VZG-e<}I5qZQ;iCqCfIc^9!KpCE}a}IsP<~tU| z%(eiBrTlq@)2bU1Vc{fHKJ!Am!Ssc3rr7(^pI0$%wQt`Ux}tMZea)O zn;;Ez%fNR)MQ|qAZ4e#cYaT!4%(GG>h=+?KgYguIlC5(xCKz!H7ec+Lc)+Ej>0}0a z2yU{|hutMhc%MmJ%Yl?(V3M;OXT_FmP)JYL#X$~jV;?6QvpBJdNHM3|EQDkQcR|7) z+e3Rrj8&!-Hp7x3N`(m*cvhQf$?1b^MqJu5s0?minMuOt;-A>ZA#o4k-`#r;*48%I z?ZMelPTZdv#DOXT3d<>QOdxoO`HID)gf^I{>Cp*@C4o(aa}{nCO2V4JYi&Cb1Y0-? zjZ+3j*rHdQ00rg)G)%r&<#-)-HBGUSPR>q&lbi@nBJe9?pwUqDU*~j!R+S{`GT^j2 z6B6WxXvIKPh2&DcUt|p6{Q&R-pnC0jHL!Ou8rYAV5Y>|igKY-HMPVL+z(EKMu2kSn zY&V040G`b69K8<&1=Xkn%T@pp4lM(0Vsic>2i#mcB$PY`Fv5ZM|ku6MtsSIH@kj4i@ESOWwdJHYJ277U2NQ0UO zG%s_XcaTsFdd`*-V%{JvM3G+<9`!M2=&?CtikICKKLkQ-dK4jc+H)l~J`NV=O(iWh zdSRi<1ql_GlF{vuY`_^KT_A%21DzX0j`_zwxdZaf=ptY|cqWpp!+L@!k`-ZkOEBfu z(MHx}F$T8*H$-VKxhKoSHgD=Pvv|wvWDOU;^-s@uO+-X>iCZGDBnbQP9hL=dL4=D% zgftYc5=0m*p&m?%NEA__(4sbaCYMBYo2P0X{%4kL%chbB4EdulTpBBs6?2u!jaEgp z4S>aL;4sG$5U&@)!VHjL?!pvkEF@6Mcq!*)xP(`NxrzN};Pt}u$rcn1Mnj$(_PZty zIy*!2Xuk&P8ki7A1{lPRLG3efm??lMc@R$DfR%+CVwTJenrfxpm@h~+)eBJtU`_J{ z+|=ggQ@~k|)*e1anF(Ua_MWPZb)e%SfuZY=M>evYUvRJ^NFmKsgZ?sjN6mY5gFGo& zmw0lZsxr-tU1GKkJ$?FgLloB8=?vzJ?VZ9_daXW4eCb1T$SLQ-aU?DtnV@&tv_b+; z+Bw?}AkInmBkfWupb@E?O=u`AszozuGZtElfN6wX!ALRFbb_Y@oY-~;*xivJqGv+# z1CKKYd`fu;duWz^v@Tv5kS{hKY3?8|=+N=q=9b6Yy|@9lUF6IyCg@(;YUgv2TpshMW|@E@18EnZk|5e4#^{ zdBsAjXIfw}lEe@Lvt#ArP|dtBWTs#}psw>cQHOa}_dS&NK7GjRKoYZsMtgzKtJ*Wc z8pkkUmK*S%x*!}PWTdYJ|55>>VjLw+vmr!B{lSME+naDgIE8|#DP$H7 zik2~yv37p5+Od?WR@x0Gpr)B<)-pvYfOZPoD5sj=e4foF0N&Wv187LtG_(24V1S7P z&``}Z0M6j_RHUYKm^#h_=lZGLEZs;k3dAu+nnc3D$h4uA$zIV04{h@@TRRMrPJ_j= zq&~yWZ0nV#1C51KW>&Mv!(9QJD}r2VpBD?FWXoVM5iyozKEyww%{l^5x?6i+vU$uz zmT+hc4Hb={1Vpxx(MdAbR6iOcv-5yWYo{c87GW|10@6|#QJ{3RiD`_GWra5C9Z9tM z&nmxcx|9VrjBo=iI%0-kfvk20s%Nlo25!e&G+TNP#Rpc@U@nbWs^K%MxjC*lQ-Ybk zrdo|1inak)D5zAh&%*#N6(2|y%o~4NfOBsA= z1NDwEqXR0YU$W<9Q)P`cU4f_kKopC^TqPRI0(o_lV(vp>sbjL*joTx6lc>Q>$uQ=c zjKIv$Fn1cON3`f39~t9A2_@4Ywa9c$y@XEIG_K7?4mw8AGON>2GPI=TGO((VR=QZR;%8j!4Lh^{XXB#Dv{Tgs8)_q9-%z8OYJ?9D5U zxrRY($!f~#fMV9Wj9q#(ua_-Z{gWZHn$VeOEEy;xS|rRkn?W~%bzK{@R*f}JrA0G} zrfQ=pR;;@=q*p>h=Ov4jYpxsN%-&lG@KUB$Vr-h9Rk`Y1_SSWqvM1NKT|ZfI`@j8v zebpbIWOZHBG*A9OXn8s8`(Mg`M@Is^yijUjSq$&Z+kdFryjWiSF@e=xtJ}rK56?e5 z`_LlZ`|#rW*-{FT8Q#hWe7O0;v*mDnJWL86fp?ZdkzJM5cir^=^~oOzs5iO=(K78e1SHeaccw_9Ga_8TmE7>BD$L8(&@Y90 z^^(t41Xh|SYxzgD(|*m!rPIfPXFN-@OdD%M6KA=knkmba&!~tx>EfV6ASMXDN4(87L)#t8N@xnF2i1f}@IA*2GfQY~#hsutFd5FFPkr8U@|R zHRfW%)M_lToydrgshQqq6=F0f3+Yk26p$U-4d8PP4pio=1IpL~Xx*AuD>rd+l&d3K zN#+tDh(|zxV;9|+)0Vnki<~PkKp=J;T9`z3==K6D^`m+(Y_u)lB_3#@FyH`Zx5#;h zWq^l8zj;{WAS2AuV&IkQuE(JQU_{ytpfY^B0h`9Slc+#M+&zk22H0zLeJ|yl*QizJ z^vBe#kv6SWx;3v6)S3ZDUDyq~#_3LMO0wAm=;z5}f|q0;U6?p-H?n$eoOoSOJG9>I zbsTFH*9KPKb;#v7apDkbb7K;`UNa&?*5*81^1N+Mslb|Rb3i7@w8%Md$9uIXaLQ?; z)1ot)Kf?Zo{W@UyxL zrpIZgt`qe7MN`ET`YEhoivjMGerYanN%)H7Iq5oR3=z8Zbh>0WcQk#>HISD$hl4ZAAZo_Gl(cqv4D`=*ErSG-MlTKmSaY$d2pB%?F=lz7< zIH{aCX&P`)a;M*NM@fKNOil5QccGV&fI8sQxa2D#c|U~5S>~6Ea)ZO#v=8?33xaVgB(EB7^FdEG~I6< z)e6UPtv(OxoXyo3`Az3pwKyJBo5#rJD6+>KkEe7~)SZ#|pQnBt&qGdsbve_#>7Q`0 z7sz9x95kB~KY;K8;Ud9Fx(Ixg6O8gv-?2ine9VWWRUUQhj@RMRHsAlzZX6|z*07V- z$0I8mqz+fiB9{}NQm@w<0B-Iw_rh_*AK8tgQV5d5>cM4;uyM$jEbJw{u$qJp`Pk|( z0%V~xxO!2Y^P%?#eXBl;E0eH3>^B>W7Ds>qO>Vm*PO=Xd#U%ECrcKI0r{3}ENvG%! zs{k~;$SU+&99A5s6{ccb?gj{R*s7%ceEm46VD?WcjYYM1Sv?rrNl=g7xZ3psr_+eM zPCWtCIFC3KI4lg}ovBwQ+1Rk=m7SyRAvRH*Y;{KKU66Y{@?JqwpeJ$3?byTJ#=_lC z`#YWfZj#p8_0nm)VU0bX)5OSIg-I3QVTB`T-DbJdsy4b-X+&PC(U_NWW1B!}(+&dW zNz(^t*lKfRdD#sbl_Wl_9NBp%IqcS(KEdoUyL{?87ts7oE|H`lWWN6(Lr2J7H@8*emw!FgRjqCX$z>QD%9Gn z`ebSAiDLcoPFa7mm0PcQLyl2qJ7tett|#1(nI`696T;7I9V`dg@iHdl&gwe4CIdwQ zbYpXHOmAj6VLagyQv*$>Jv@OvSwiEF$vDt?L4s1MO7Lc^ZbOW2ce zq$DCryE@b5+x7s|B}v{pV!CKC0^CNpPq!D5{krGwlKNHISJ zYH{b*ojZ4K-Mvk&l8o;`zS;;|-Qj}0`5ZF(!_U9{{@X7qKmG9C+ZXJi=j=t$DcFO` zD#8-FDc_0^Ffm{guZ3T36Z8#P*C!9Y{_=~j$nlcry>)kOQ^zcE#N3dt7<&2oo9}=5 z=fD2zzy8TLMR9WNj~t9k&W`L9z%~sqF>i%2vuu)yFzXmzjTF-)e`yYS($3Or1pZ^H~&c@~2mY!dokZtWmOp+|P&Td}0*?@LQ6Ded$2v_x^L#m~N zeQ+Q*zPdsC|Mux8e}zd8@2_ofP$KwhGWh4u-+cGeFTelx>+iqwRa(Ek|Audedw#wk z_D-;f4F*K7Oyms$V1Ui>B7CVFsSZWkShV%MQ9B$Ud-IFWKmGKRPyhbO-#+>Di(6!f zIoGn`CWFz@$@!~qfBf~=Uw-}VH#+dk5AWW*(3e;NcL94xVv_|hVyt*K zgMd(p0_d5|C--iB`T6IcfBM;feD?1!2_ag0x`PO{0Ch}Hp1=NvF9Z7Vr=NfO<>&VT zbuk8{+7)OUO1e|6*L?FWyZava7%l`kLR_}|&t<%?IZm|)-PORUWC(7-Qr z?3GgUC>T@F01Dm!{WSS6VyW5*rvxgK8XO;FHc8&xf510p-MV$}4s-6o+Eb+V5W^n3 z0o2VAPz#ROees%uTS*RGp7Wi0GqOP()*=T<3Q~@ow57E0byNit z1Ui!37P(P*%W@h4NU}1b0d0pZ3njk%mIE(2Fo1(Hw%FWHW`^uhu5ef?DHO<}B&I9a z3=WZu30Zn_84Lk{3j*zA2+*+XG}4#(u)-MCtX0OWa#{>%0*AY}?0EtC1H_UuX)CoV z-!O#aaJU%fLxMlDs-S{2*jm&1%T_}zR{>ue04&Nxw!mO==mKmcD-p&lcMKf8)arvN zP2vN&XVGR=Zvtf1Vj)%oKA|yqkW!uKf1e!&BsE;O&RtCwSC2F3ojO@#j2c-7Tn#MJ z!D!$%!Cn{^Y9i(zur>>I!ySIjbWLj#OSx;QdhTHAIW0~Kv!JPK72HKx;XshG!?2NCcEETcMnVhjTz zVzt5xBLb2Z(PAeZR)q&FI27VXE3H75{8v3}QLsS%`d-^}ab_eDob=5>-P{UEtVA-0 z*j1PgaD(gk1zsxxy1&JIXEO*7IM{f?bfVR6qS%Zrq8$-tmB+CmTcHVM7JnpM2br_T zGvmn6+bv9N%njKs4nk^T2h4fADqW)G9Yn8|V)}we^R7CD0i^E`kU)c~jN8Iy1H)w< zLrB;SDSN}d7@z*adKoV#^SySa@eL(PYn=|6|zLr$}ucL{&k zf%wcbOdp1YZe|-lbahAo10iQl@zoLJ_c86VeIZN&*oPq?V}KEWBW^4s3*P8Wb&R!; zXa@tW5r(Hog^>)1pw|#2BoDSjk`0l>SGW(8k-!D>Hez=b5)-g523Q3ZAT}_MfnsRj z4~l?yKq0AG8Jf_x*b^lY1xm}dR*uUK5im0)A&-Ppi`qi?LiixwfH_dvC&{h8wKcJNlXM6~h$G&q zyaGsPKbNauopUBMW&zkkokHR`%AV947~7meiEt%!Q}{O;iZU`yC0Zn7Rv3Epg6(lW zH9Cg_e$D#hI-$;$L8eJoa|-mJp8&pN+h&Dtqo{I5tN@LOBm!%wa!`U_aHt?N zRVg{rnS|PCwklOLpZCBsN(L$?i6S`1}Q|e2ZsSJjnEnIqq zeg)`}WyW-yGIP8ZY(DGB@-E{ItQJ>Dn4^KT5QqY;Rn_{{<;%t~wB~(tjow3kjK3pm zQnhQ!Xdrb})*|je2DyrXUfpXhl@p`F=UmQZx{gV=WP|EfO{OLCF1XoTm0fABGWVN0 zvW7uazK#|bbFukoS+gpZvQv0h>#S*|KBF5Z+-jPqR&&2u{kiJHMW%5OWqh+P(lT92 zlhop6ud}{FN2{_7cV$IH5w&Lu`XZ|{V~;8jz2$wTQ>HblPelw-!=0|^Wx-n0 z_o>U$F}|jZOC3`t0yNV&U81Av1yI6pHm8PW=anweBf@4Fq>G>*bW3bDd={4puG2Sl zE`v|tvH?@XjuT!<-K?>vJ)-{$$&Wt0|cB>kq5ED%TSGeaKA7+4PM7o0O}zX%tPoLow%)|x%rxO^r;SQ z2FwIS4lV^xYR(h`LL|q>fRVIVpnZ@`ec3kOLv?(9@%#lFMZW#++i&?kSbc*p-yq z2$M3|#B<3=zB3x5R^bVw~`M#6T2^oI`^NGsi8T5casd zFlXXIRTpYBg;C7Z(NaSrRwy5%53rFkjSqkkERVj9iQ};d0HE3!aXFqk>z6ZUg_aUZ zKGOt7n<de|s7REQ=S@(=!rL+3acdQYdo z;XrYuV-RG$6I4b}cEV5W|HHO0+DkT;%q8T)c$I7iGVm)QAEiiy*pZA$Z=>hvkkND5 zdMxmS0WcZt)&9OtUjv5>0*x82ue0Jrcr1pN!Z)Zur2r)-2AXbkpNT4J0f9X9!Sn#% zRDn%u=2Fp`Zc0~5gD;0!0AxX@%ooh(fhG(7#^B|aw7qV6LBZ2N z@?<<=(r4qc8XCrj_5p4)Wx2MSpxP21V=Nvfp|NYU#9fz_?Q#8|PZ$;C^G}zUDQxtP z$6wr*&HT|XKB~C~WE$zA$U$|I` zF%#3}8XPj&H9Sg%o-{^ ztYA2|Nl#^>V#ZW}Bq<81imcEC1qH7ML7GpB+yv+iQo+CpGy8|NpC&OErHXXsv0;f6 zMHYdRVaJ~=0P|15Q7J7W<5C(+c1TXdkPl5TZP3KSy)bf#7>E^yyW)k2epC!+u34f1 zQ}>y&kT^S3pJV=L`jGdk!kL8}yVVA#;E-4@g68+F{rX0n-jM=vgZ=aEp1q zYzxm<*JVvHZ7|HpxUphKww%gIG|Sq@4N)VOzEw6XM&=N@j31_c(_1~5j;?yUBDQKT zpJq*7U0@m_5nat%xh-lq%yP=u08NqA3&R%Ej_U`#X|(fl)-H7i^{QmT#@rBPGgTREFo!lWz;q5MH)tY z$R@3(?XtxmH9KpvvB``(nLU{1ulTc?H$*|QBGV;nq;Y7Mthrv}v}_o!WO#_uN zEE_7bDzDZS-IA>}Qg+u9X2lh;B_o>2%W@hScA;{YpP9uLmSl<&5nXzbxJ_~&BrHZ# zE(PTevh74jRqbPJ^b!JjwCdTz^4Z?Cg7E`WOs?=Gg*v+ItGSOkCEF}e|s2ELV z#$h!WAL%Ppg%Jod;$|N3`g(Yn6Dwg+&kcDEgq$~tLpJDtUd0duBMaBEt68yXfSEkY z1{k|b^#4>=Z(WbblJ|zRnWro2W-2UsyBbUe^h4WLy3Me}C?|=6S>|*dC7VE|%Na8i zS`s@l`PVct5+U;{(-E>~sKdyVv2B)=G5RQaLCG4W%XHzNXABptNK0FPRQ|YtEX}rT z1v62kyv_v zLET|$j4M}H0Lf5_AZ5LwALO0c62j&_(&?-_#P1;&5y{w&z@kXrV;!4YuziPZ&r%iddM$@`PG4`i+JGoo67 zxx%!_VAHl3CAyN14joZJF4wiT;Qh3P;iwxBVW!9Lfo6pqJo2|qz0Qdg0bRujnS)E6flqg6_J_5+ll_AR5IB5bW1Y1=CWJcczWlNdy?i@0<*T1 ze)QR_!EZ+I6VNjD&`%arq9|qT02IZ5uTu~p`5x?@E@IOpLBFsp-N>NKQPURy1u(R& zsE-RNc06Yt1-je8*D^koO&zSq3L0Mn>I_xZZT|_W%ZPgF)SMgB6XF`$izp&I1%s#= zljhrtHWLXGpo%L7q}^(0eF$yp3e`TVIImTH_T7QwYoIcCHgv^QS~z5u3X^VQRA_Uk zY6-qWG-^=`v5ba2bk28M8L%GU=dpgw{{Q@3@X z1T_vkKgzvZ5I<6JWeeQ_MQv<{O|%`e(V^|OHK54k5lURKhMBk3UCFlHD&(hrsd$R& zwBgc-6r$r1m{r)_$GtwnPpFO&1Lr(-crY-jmTtJMzVJ#-Fgs8vjJaeC;?Y7i+nky& zmF5*ZArQ#U?_*KZ!JsUgVn5^q%`I8C=l|~0V?sRg0PV)%Q=cw$OXyI8!X9bZ>=cQ> zLxrc-^8qpLd+hvgsiyPn{Q!VYzgB#r6sEVYqq5h6m+hvbRt*v|xpQIn<=Ilvw+D|g z>-fc<RNzA97VxDcm*qARv%g2A#o3!Tl>ePk5F`s433w~t?vFnTh zdj580|8C1~iNkVdb)BWC`$}dWPXt%6wA+~myp+dQ=CX0(^73K7l0To`Tyw;HyF**0 zi{rD@=N_0-hJIWS2Y1unh-1&uj27d(3=ZYCeb6tzUWoSpu9FWA(Cz4eD(C9rXA!=0q%7;L@=xx+x3HV*^5uI{+shwAIoVNv!6v*w;P@{byv5^LqEm)501$q8^LMr7 z*T#RX|K^@UV8Kz&aM8c1+HaKLpV(h>wg>KTwDetgtCPZc%rw0-3FFxf>k=>?4@1~@ zpP$ocUl#+964Ar>vgzid--Dx?wx0je@M+xbc;RZjTzpMtBeF>4yrVy!-hQo=44&P- zCF0tLcE*lbpE78jG7~x1CRJMxao-@ zYsY1MRr7OJ>Ce=qA8?z{UozY%(W)5ac&>9i2a2AS4A~9q{xXMjjL=p})EAC@{6Ot| zwsD)4-9h_alJXLG5un?6QomIzN3KJG}R;iWbk^6~xwP=@;U{nc^C16?iHr2b;BQZPLi8Z|;JJs&i9jl^2tXk?hH$(&qDx+Q z*wx|MdWqGD7AU~pT3-2ucQo&8zOM%zfgyqEG!Rvd8g46r4AfLYD^Hj}1OuaVQy}u# ze}Z9zz>mNY8Z=K>o;$UHsAjI~nFu;|m~c<{1PAdVm~hZ!%HxuD=8cNY0iOf@UB1i1 zM>UvhB=B3r<4w5esI(0M7k5JACJ(_{Q(3)J1S^C{gbx@eJd|G7(Z%2crAjl7iUuzS z_bxxe6g1OsZALLsw^Je<8dS$E05Hq7TbhqYn;@33#_@fUwkOp}j@CfK!G;U}*z3j<&0DP71i8?|2u5Y!seP!7N6hu?moc(QgnHY-e(0fp=m1(9 z8OEl%PED8e!@EX22e{bqQ?fLuE5212SWR$s8}uWv+eTG5wfJRU^QYycowLYBT2++l z6^Io-!^vSQ+};|dv8rHiKd^s2THNN1(^O$J_Os3AqfO?c3%YK6{9hMr)3CGWQ{Z5M zT`Ylc9r_bAbkyF~b)Q%%>7b6_*3d8-!N-J-!9R#8 zwgz1cmQI%cD7d=q0iI#Ur|edTo4u(6WOt>aez0DsJMMi$mGBM%HVX%s=ANVI80_~7 zUWIR!7|8=peT(Uz9OaVqRHizKs|%rJ!nK`6619gJdBm+83_9$TP%8IGkryj9bK=Jf-qOSvheg_J$Kg zikFMM6Y}f8If!*+Rl`gr^9%<_)l}v+Oi9uJOlHh&vS8#yJfzYfek-4lganH@ITOb* z-SY4IBea)=*xSt|0lTnZWZvL2{GW(r2`IN%U@#n EKSTQ44FCWD literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/touch1.au b/contrib/vtwmrc/sounds/touch1.au new file mode 100644 index 0000000000000000000000000000000000000000..31301bc59e552370c9e2de7353ed77fcc4df9588 GIT binary patch literal 1945 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 WuEA(zHvA>*M;eesctYSb-26ZBx`WjK literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/touch3.au b/contrib/vtwmrc/sounds/touch3.au new file mode 100644 index 0000000000000000000000000000000000000000..a9c02e7bf4219be93f61585c5220cf39ea7ff5a8 GIT binary patch literal 7825 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/touch4.au b/contrib/vtwmrc/sounds/touch4.au new file mode 100644 index 0000000000000000000000000000000000000000..638e76ef405b763d72b080d8dc7766bba0384da4 GIT binary patch literal 11839 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 G?DKzAq6S|8 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/tshhh.wav b/contrib/vtwmrc/sounds/tshhh.wav new file mode 100644 index 0000000000000000000000000000000000000000..253d568afde55a1fa51db2c91c78cbef23d29872 GIT binary patch literal 36056 zcmW(-bC_Jo*FIHsZ}-e(Vr^{Owryi$+fFvdhQHXhZF^$d8%{jvzNPQY_v|0LPj)ih zeXGtnuTD3tQMKx=e~Fq^Xj-L9??LGk5D~*amA4a3ZO({O0_xO$Q2Xup8HZx+4f>0F z&NwF*{pH=(#qDGg`gPRSu!?SNl_EMyRSbLQ|CiQ$>l@W6taidUZv9_rennEBu!bRf zJ@mD#!2c(bN6^#n0g{9N7OgiMk%wgl?BB zemSH=Cx{#}N1(nbj%)H5)`o}&LuxUaB{@r({LBb*$*l>BPc)L<_ELgz9SR-IK5%H;cC zZ$@9&qvP%m85RBF+fZ{b{@d`jGVRx$!4=_I9a=CSF`7yBC9`vDoqsK>|46!%!n zv5#li)x=@$li#@lJ@u>56}U%Be~%8%@qLNg)@cy6@B1l}Jbst>ljWu#VZU5o#f1O* ziw9o+IutzWqzE4unm9J&*GViQ&b*LE=KJpjQM>%J5^khKKi0>r^*0NjVtMde>~pH? zYveDg4@WQ3IYZv?jHU~<)GdNHb*IqeZeP12us3?HlQCXpzA@%ROe>bz-_?0+B7doTNH;=lDK)w&bCWex7qKKDE&6w$Vm>>S(D*U5iTezhl59zNW()Fpi*cwW^db|NM7Uv`?% z@0dd|cYV#{ln@DHJ4KzP6Cr&Mq$7Ud^(S-qbB5O?UO zw>D5hy!SU`71VX_m+UB>`}>H>I^(a({JZawD6BsQe)2giEj?i+^)ItqOqQSJR9Eu! ze5{vJZc!sb|L30_$Q%2Y{VVjPKRh`3R|MM^zSZA2dS_G}>LGH)Dd4{z82ock;9#8i z316EGkpp8+gbYfgoX=l#|LQ=W5^alHJUZe_Cz&QbkC)Wg@AYH*yU)X8LW)IQ`Ymkg zI1}9ms(kQ}uD}*MhuoiDlh`cmxKE36Mg$^*r~FIf^q1qKUdx&O%b|I+i9T;1y8T#l zeMna|L-}C$yq*=jZqo=Y9P`?w@e-STp@V!;vB_g6v5vlVVx-v<=w=d#3?V=Dhv+kO z-YF$|+m>>p^qlE5iQS^Srn%SM&h`y-4y*eyt!zobaX~jCRK`_QUW{3 zN^`^1WM6y%^Dw4~oD;Iu|F_pFHW@DyQiR$BuLiaI*zM`0i2WT?j*W}6P`H6U-f$}H z3unD;e$`gS_s?{u%4eRIF}_ImFMZNm?lp5e`_A&-F56Jgl6KkjW(QA91&m|fveW#QDy-M?C|YJ}*?+`Y zd)s?tj=6C-1^38#?reV#6&9OWoDpwnq)end=cr(;YH+Bm<=@3u>p@;uTgkc2m)cwM zv`)p8Gu!r+dvrJV8->aSw3*(roa_vh4?gqWhD>pc3IvnWbTPMv6T=QTC)otA zz3R#KvM9ELRWzTx4R(Xr%*X5d@*$mbThO9lc6q>UACf`MjFBczXazAjxJy1_S)2mg z_15CrY+xmr=k@k3_$E0?)F3n3B(f!azgUmh7hX2sJj~cEUUoTHxAXtyPZ-SLRj|2z zC;0|b#HPcMXr9_=^6;Ye9o4dD<$E5_*-A<^ zk-bcNQONb|n?P~Qew-6qV;1QdECH)+hOtGwj?AKNP#*srv03_K8fXf?96BOU=|>xy z9v;{K%9|dwSvLqh;qT|&jj5&%$9eCM4J3>HW(tJP_9fHHV>WmP+^3HVwHojf$WqVM(*UZLXYde(u{0{4D7b@2- z;KRAF*GySGQ(y8eWYhFBwO740q5e$H0{zKrhlw0NG@3F64ti1IjvHlcFqKIf^4-=A zzR)1{SK_?wOEzs$gKS9^l)> z%c+K@22ad8$-1f;U+>>Zt|x;7X`)|=k#c6>BlY%wqo^QLH^g0kar->>PVj&HVQ58H z2Hfb?qFc#d`?rXR!TfuhZ^ z#ir&7SO~qA59}EJH@j&Idkl*Tv?T%Bg!XkAWnq->-L(CHUsEcf>HuEXYN?yX6*SNBG*>?ZKeT?W^J}*R$nzGf2eet;{T-tjEq7+Nt^&ht9G6HUbRfKKW%MdLUlX zO`z zVW|U$0ylX~NMi9OFe7k=#c_-JuBgyJMP1qd)_o|;1nZl5zTy0tN^Hv7E;N;=rt>-t z`(&%D;q(d>n8D6bvG$q$&Y#mfoK8HGfNgQI@VLR_-rw$Mw;q0So33W3@^MtnmSLA{ zSKNmLY=m7wJ#bfZieF}_?riU|7c9Php%tsjo0t(g8M`4`+Z(}(^h=E6n@urwRkxsB zzRqlLu%B0--3Zy^RW`Emym^-Veiv6so(@s{KB{nzpS6keI^UCw}bd74$cuS^*>BJ?!X}@~;&0{B0+z5uLk35l6hvw?Is5VC|qgASn zs>tsG%O_VS)M%VnXQ6dDb<*DCNmwZruvd8kTac|o4=QNi+tz%q_@t)G@#w16Y(v%A z27K2jdvKE4;(X(&Z9(hW66T<-$|o^qx6A1!!q-n!4mObaSwi;&&!3dOGK!%&1(_7V{U}>C0}@_ z*lb@r+80=2^83E=%yN$`K#}5aVBJEo!me<4y6H^KU@x^(EcQL+OJWno?sRvCwY4W= z$H_TB2Q!%srcn*W5qA%L4*un3!L)noq78L4u~W@0WcXP20yrnQYkzmRm=eo&W8KX!`sV=vV!eTtg%fqZ~!AfK`1 z?g`3^DILyEJMZa}S6&x~g3ywkFh$i7bQ!->o_CX}f(Ka@Uq=2~rZ8J+vT4gx^1Wt{ zzNstYo@`nZWh%LT2R3qlB{N^8viuovmxLs>` z6TV0L^37_rc;Wu?N;J?vse&@cP=50}%oXKuO z+s2EQv-w_k1Y4?Rdn;&|Q-Yf6vUV+%aKEb?!Htx|c`G{U3tlGNk%gkBTCIDr^ZX@U zQVYFJU05-T^}|GWl5< zHjF(r6>K`&-lXOe*hUIh-*tYml1JNP@|a1%KJs2*bL)d&nRe&-3I#9zKES8MiR(O% z=@z?>J7M{F(qIyG)8=xP@eFFZ8NoKNPzpD>F@2x%^Y%6P&N|kH4w>S1E?uz?><0Uo z@=-aPlpdL^w2^l~N1n?ou)1cPEkXxv4fe=;#B3grC*+8Uz~cB zL{ISi{IP#5YaDnV=*Sv{ZFDAhRbvaPx&B1pW!qyXC@Yfs*He+;#$Xj^vcJ3C;+2qp z@tOX4cD>vz^YDDmeLSPFs-U>bXHixAZ?sW1pL3wl-DcXYtd&bskLFvV5G)rl08y zsG)i`C@-1e=#f&L)24~ie+c1*aw^4WL4*R2C>dOC(=J~%6plgYqQCV)i>NFPzAqXPL*{U zxZ$>%H%L9?L1zf7Aqzr@TkkyQt5lfjXoP%tlNv6;1v2@b;%7$p+C9x5{KH{Z(5G;$yoXe4Bq#P)h@%?Tsz9_gtZenTu zZ)_9U2gvfU$iX|SbKWTQqslZ#mDV|ceYe<9JKFr#moO2ps{-;hs-iP{5PT@p^L*^=J=$^IjWKgc425xS4M{QCgDGN`{Kht!1T)p5+owp{bENaK2 zSEMnAz}Nl*_ceOHSq%NDvCS;Et6A<%CpGx}9v#<7`7^syeT540!F^`idnI)w9dombm0q}4hqgHL#9egq^7<}sjB{+E z)>9WzlvnY($%O7EUp$o=47#<`LL8$SUNP0s8Rg`oy}^Sj!dWLCYC>00z;bPA1MA2( z>c73GbjlsdN9n{ezd0<{p_^?CELO9fr=ma4E_-^vDAZq)Pw=?BVJ7*8`|rxkF>iEv zeWRC(N{vTmG!_ZR{uY)0f%5Nc&@|>5={g?pE_xpoShT{JzHM z>?6G7)Zd*Wrq~|AdU`8Q;2fj1`m??S#cDH;hyIaWJ*7148Eb1(+TG?PFi{M9O_63C z?oL8p&&grashRp1AHgtrY%%qPO=4Z`czxRrz%$RPcC%_cKilKAQt{n)zA^e_;BR$C ztOzkSNnoDWLW}@s^@Ba`;Qv6Q<-y6pc20(nJ7!ieH+XYtXAo;)#s>$RSH9VNuCA~4 zo7e1t=tiwnMPTbCZdvpkZWi&5tdgy63PU6Jsi~$lUrR}BL(`J~WHa>ub)7BYWAq+q z7mG|rdSfrseK4=4_OS_=wwR6W)fhV;wXj%RLWSLy$=N}uH3z+V!4|aIx61u5xGf;; z2VazX#Ec2t3(j;>hUTPJ!Ajmbb{qP{CogVbgT3c|avnhIN}@uY4o($Jf|B~GDaqqH zcl9#4$#xV4_$N~u%xMtIEt-(e{B72l6x5ctPc%LR0k-(<7(c=?iQ zx}Ry3j<2&C!*=i$^bx(H9^JN*rqcu)uHJ)ttzpwuT;0|7!EDoC*in`SH$J(kgV`{GHT4Rsi9nmzc_%YQPEm2F zuRob11IN8k-qrb=6){XLhnC4jE6ObM>9=fykLY$_3o2lTuby5Nyv{?=QTLl@JC5#C zL;FVi%ypo)JT`}p)vugy6s8`b|4b3->3@2;en*+9D7(WN+L5Y=*~Z3-i?l%{H+ShL z+r)m$a;7rR!3(l|x;LK15|I!nGNa7KDmcm6eVGf>c@x}^bhn*`w47V+HUa1nnV7fB2w-Ne5Np; zBr=WUZ=J+fMnveF-d2;#$sj72o^qBs&m%=W+g%?qx9w~j#n!Nix|80<{^GzwW{gct zr^v7#=vonWx;vQms|t8x`Xk%H})YPBo^z1 zYOJXwnmRkx2>q8X$nyKv()3_@)a*8=hOHsznG-aVWx%JpC?}hLfC1z3*>|E2)YHx}Qs;t((pqN&tE$FxnlCCLRj}=xT70FvA^&5`ol7>4eyi%U zuPhRZ_)GOSw1X?`9!qHQ8%InvmGxS>$1bpTn1svJAXdxQhCK~__bjjMj^bav#&BkC z`xZJ+yq-{D;-C z*kk6TucIiZnyN-%o;g`fns4Tq9QF%~%eh&tM?)9AZku6xkH1^TG-&I_lIX)UwZgt&RJU=GswwWi{jgvDgN z;8OvgiiHO|dv$nkUuu3B75{{FbTU(1Ia`yvmvy$obTfDcmBazwOhGZSUEI{}a(x~g zuCo&*=Gii+f(N#w6YXSGi-H-A>ucwB(f`D5q}xs&XP>ScTt>Y_NzB31dLfI$D}k*C z%x)%l7%FzN-UgiVO&r7A4M!~uu|?G$JwWsm<@Ie~)Jp6m*z9YQ3rf%>GuGte-FbDh zQ?7xc{F&C->1MZj#3s`q7DbNANOPzxSkZ8E&m1!=r~q$h|23uUFB2|El-6Ip2{uHG zcRJdF(1VoC#W&I-ULPzi1x2w4`@+VtpQ%4xHvMg9Tb>8(WxduOpb*sCO8XbES0+1; zg|qo8mmSQTv%b{L%rgHPPM5?pn;QC26ETH71kZ>kIy*OQa#>w{5oho`YI~(jYUi*o zLOZc%Om1j`Y1n1C%Znv)oAJTstZb?qIJ@{zpybNB1I2OX@^0#lOlRsjbKLoc2cN05 zZd$jetscy4HUrWBk5T}abMSUapUh&oqMY)IQzTSdorR5ed(ktmt{F(X*?1_x%k@S* zlNDv9X^pwA3-Ma~f~ln&+W0(#YS`)&idoXb?54rgl)chN^iO`92b3RL%o?GgzjrYg z><(bPPv)H2NN=eKoigpMXOH3cSEO}d|5w-`k%vyG5Olnklou+HHB(Jm$_d@!0G)t$ zy#cp67trQOo}OZLay1MUyPGb{Nh%>v<<7NbWkNkvj1^z)Qndi{rhw~+PhNj{pBA}~ z!3in_hUgalZ{i2A(?0t^d}6cIPyK^>vWJu(%F%YJNK5SiTY=@V+s$D+g&l*Ya9!83 z)5QaGU+<$$VC*+_MNH4T^bAw=5$@g%>S#yOahnmJCkfBXZt4Q&B9QYF`$erWPem=> z1#GSao?RL-TVMB%vM-_?cuFd@%?=R`ou@InvdILuBQ9Mqc};n0MYmW5wnF7KMfiLh zVF$3Kwvc&ll&#Ej@gcgROlQlweVu~pVGvBxH`q<&eGF`~v2Fo3g*h2WW$KE6xJtL- z)RbZIoMQAxy=+A3c}|6EA%wmW5EmJ{#vQI^KyI4IoiQrhl`7(2< zGv+}uU`M8U;oc?{L7hZBq&ciTdd^+yZttL573c44TKcJ9n|Z7=i!@ci(O%L+-WVQw z0CTu79El{l9@w`n>9k!!Wjy(m# zE{?N$fI6#YJ5eUvfoiiVmeWj~#FmBTlph-EMbuDBs7x^?Gwr4*>OfiX^z+bu_7lBs zGHzpIR?gH13W-kxDM~%EpZNv*)FjlAIs#a~xNaej=nzrMNoHTDXNs{G&QP;V6}9Ks z5IEY~QMuQl`IUl>))m<11~ikW`iY%kL)a*&qq+2Iy`GTKfD*dJ{<$v&D487q_2wKS zGaTsk5$e#`nt1>9%{!{dr7n!0ykTy#W|Wj7buqJ-ZH8LbQH5I<6FDDGZ+d%$?Qds* zxN63D`PC&+#hF9bRRuN3Ugr6DCrYGZ;o>EB*MJ>Wvzb^g5owwOjfI(waHDVAL&0Wn zm}l}{CJE5gO?DN`IY{@ARmcWzU0m-}&v0(9>_q**G@-VXh`lzYfFRz|DBD(FvB_9M z-i0oxa==wraU-Uw^7zcv#Tb53|B!XfWgdY~oKKc8M|dwW$Be{#zW`S-Efvzub#`__ z)MU5iQvI58vq)Z8mr(zsI!;$8DYf+fp!RR%iA_+Rx3l1b%%zoDsh#vgEJiJ61a>@X zPqCfmp32Bqp$qRf&-5p@oz~i+rW4XCp?su?2bRANl|2<&=scEzz0f0R0Z#tUDSfhM z=sA2v@GP3mkLn$84dOv93D~kW>Q7ftHCb^-u!MTGd};EzWqB#J8-2HusHT_dv(yW& zTNAV2i)Y6Ljn6Wvm_q9Nib<P z%`Lg#I}B|(pYu|ciA6>yGy~XWS^2|sa56dnnrP$$nu)An(|ZEdytg9KpPgL{d=JzY z4?~kuyFj=%0qKDvR5hr)sl1_YFmLG65h{Y=cHY!e`;Yr(lIdfuJ)`>h2B&|C^#JvI);_zJ58ki zY>v=q;KL(Y;wh}QJ0-w9NoNf3KROX7CSUko}|zs*SY7{lLD-`kr9b-O=oVY9|}AXU-dYN)6PB zSU4PtyZS#?9(Cta>sU|xdjh6mC1~h>vL>B)Uw&M@Ro$qblYp&|70qEblNYxS{>*o< zrZCf0ZvitJ#r}aSepmjqBSi`kP$B9tv?gSyD2WQnFKoM5$hxXH`Y~V0UaQNf`km~g zoovQpdR}qf@we(wpfoZ)(?u;kDxmdBe*)*e+~F-Uuf+xtVf`|#UId>hH=C#SLnm2@ z&Y1=?kdS%GD2AH8a)}uTHEEcRXI7b3Yyy;$X3#n2v3ZQK7&AmCL~d>;8&8YveO<&H zwFTgGA2emWpx(?kIZbG(9_2kSBf+=MsmU_RtYPuso@dm1^epX+!Zqv3BI z15ewEY|au>R%SPgovfme{w%N9`eH1wXejPNG1HB|6|YT%TBP@~f-DW=(B}@S9W0N# zfbIns$TG;utz!XisO$z5SBhoSlT=w6$Gh++s+93jA?|}7x0zP5GvKx3=qld*0Wjip z=&4)H61qdb^+rleO)(itVM3<|(%nc6MH#p#S>Twyr^&d*z?fz%xWX^f1!%83C;Z%b z%E0=VNRyY10h(>gKiKbH6sj{!jKR!ZtS9n8PIAhIC)1NFk(!dqn&tpM!LLIx%Siu- zy(Wn&1jgy|lXj;p1Quw)eVfRHrW((VoXdW6+NZeHm(3lP8p`7pH5%vLpPzt()ZJ?O z2@P{8^t)5E*6Aj`df9_Xg>u^Qd){Q+ly71QKdSx-_NDFaQpf&rnMs816~zP90`>UO zkdC5(Y##Gd$A-4`50>YmuIsuX$^5-_g1}Wd0vgy)JHhK@D!`|@!xrgr+J#E-mMwvU zlF`6}7WKhYsYG^V zn{Fls+5(pja+>gba+r4+ta=GAEf+w)t1G4p*Ut1(>T=?o+Xmg@1r)~??n#yes?I;G zl$(@FsC#fnFTmGGX=lSPe8@)uJ2U~WOJjDhUT{ih=$A-yJYmDlKV~rXVbj=pT|sSO zLq#H>(Y$J+X~chtwRm<7%>ZZ+^F@E1S`M@E;C;0RcL}$vpw_jtKXo#jl@jwiRMVVN z+3B@d$8salVZ{+{jcXsnK|4gmtFXN4x9lMnxEG-yRyU)Zw!E3Spr(TP>;_(_OvUYg zYJ@Ea-zkOJjc#|6jb<&VzdmNZv)t^1NsA7$nt!s3@y;92KzRNM)C|3kFBZR1eUqhP zK{q=~gM?~RxVt5wr~MDTcqV_!$LX*5Jo80aKEYN{1@wEKA0Au@Ip0`52%WRG>1&_U zeR^tgQd|4YBoqgMT7Cf$6}PojS>#zJ@8wVEtTx=8$7V852iI_vT}>zLXqE^* zQXcBbSFx<{_6nHE)C8%ZHSpQD*?g3OB}R@fmwjhHn1ake-`}Zng8ThsBjAjM>S3&* z$ikliC&f3=|KNx2f4|L67J|N!WARXQNT4L273m8fP2O z0Pv#s@RRn!{|mL_sX2>pKEQYFMJZ{&Ek)abF9yP0W$ZpLkGYeC&16q0V7lwcW*JaI zZu474nhK(Y7>{g9N@_!;DGA)fDLRPfl+g`3j_e?_!08d}v~8*un3m2I*2%b-V&8dk z(cJpfWU~_e`Y1c7R;W(Mq#dJE@{!4cxwp}rF^LJ7nJNN5E}(`$dE?>4JvLj-RG!Wm zW$Sy_)j(&0NNMA#_O>+NW9QkPxSj3IKFTT@=y~QF5?f2rZ;UF-cZ*ZzAST}vR$r{9 zTwVp$&{x|nCX0K8*>`6i`%4#)S)jSSw^QW~eVQK@r)^<<586#h$5M6Rc zgi}I5DOTL{#C&aMS8LDgvHj@|i>9x7x5-7<@rs==mtx`Umtb>Daa~f6;}x8>mgzIl z>oncxe)t4C%{V&EesW%l4Md(QV#)YDPHZs-n`gwG5D61W9^IT^mxJ+_wa>I`;0eB1SONS~79 zcn^2KNhnts4IgL$HC53vFH7aFrbK$JEXuAp4Ov`d(;=DW59#Mf^u1+$*d+sn z-(I9u(73MHT6Ur-OBp%m6HQ_DK}{Et?soIj%WOLE#dy{I@IF$*r|Apz;(@o$WN}U) zW12?}0^?Qakf~)-jGWIHt0Mm!AeM@dA!) zpDCq0wLzSBw%M0zmD+EA^O;T;-O`(3eWH?+m}Ywq)NG_;DzWKum)yW+I)+UEj*2n2 zFj;ESdifaI)-17s^;0|LTUHa5@C=x*4-$}x!NY#g3BH+jAU6vYluf5S;6i!qboy>f z+I`4fG=gWh(fqWF=rI+BW0&9Vp`2{BUSY;LK4eihsUK#TBl$|5ReiM;fgf+chrLQ2 z%?c9<#iqaYpjiC`lUc;q>gpTf32oe!rOc80!hbK-OxgEdZtdNUPD%1DzRm3oTBfhITywc-Z? zsbbsFMcRaP2vZwGGlakFyTI|ICE4wGhOs#;ik4307kovx3ldrbq??y$OF8TZ>$8{Ph$J2 zrFtn#4JAKRXHwA=M5=_)qg=k$IZHKUH8qp1bgp5V{tK0)4f4ZrC^uY>!ub1D`2y1q ziLa;p3mb{qIhMVKD*MtbGtDSq$FkvkDKcg`xF?F*yRx)RA*w;gED1+yHwzOZp~>EMpBTwd3gd3ooQ=>!a)M*Kuy z0HV>~fH=+xPBnBFAp2OTrp#(x3<~@&C>HPaV;TXc{w17@K}fQ$V#8&G_lk{nNAUkt zK`$=dbn1!}st~GtgcHMtsYrPc{^tt%pdye4p30w_VH)1TA4ZML>1axe^izBDM)xog z;*#*|!7`hD<22$|;0?q<6$&7YtNJ1Q24v684xD94_&)!rZYq`7B68UUm|j7iQ4EHE zdkV^KBBaSK$}Xm+IL0w$WfE20-_CzXj*sc2hxzXM=bPuTQ)O=VlwX<;u^&_t=e?7f z4}yaog%ckRFXTe-8a6k|JA+LvZ?U>1*0?S4v@)Am{)mB@nTfQDr3TXluHr}d9q_03 zG}e7cYh_B@kQw0hNmY7GseN#gg}Uk8v|aqSSPOLuDUTZ>C$bA?!K?GKdgyBx;Mjk$ z-)%D_<4S-oQX~bTN?O0ALe}s_!;SL;yK@i6wq}z0j+s&8vsVS$%^m{_MN`2 zEA#eZfSIg&nO9I>TSB9X#7zxhXRS4r>~T8+b0HQE^GzsJ2}A*K!f5NkLv(>TjGgTi z6J6DI*@lFZjTvZq*Qh-d(Hqdje0aZ#l}3;K<1RPheb^Lb)F=2l>ETAcvSC0`{n6Kl zLHWH7ymD1Hp<7Uck5F6afus0ndapM_r=E?v-mkK-;&41upqg7?hL$F+OJSN_f}b;2 zS2r8rie7;_+|jh-$@oGWj+}TDZcjy^v1{OVXaDeaT8AuLMQX;s+XcwK7NI{LYC6-$ zjHChZxT+un@q%UMRqRQ9(1x=R_AfG~7xgqYidUwRx{n&ii#n}sJAFy5=Wl^bDwq;x z3;5(>Bs7PcM{GJjPlfeMC2Sq%Jd)s*p)l_Ro0x~h!W12!Rs%^esDv9#a*D%?^S_Z# zSZ&k7Ph4YGA}Ma@}nQ% zi5xL)X^WV^YD4K5Pk#fmyuc~^w)uE-UK4$>upY>3i+46!mQh8Wug+6**K4O&^Jlc4#b_D+CCzAsAb-ca{J-$0M4{lQGtMrL| z#~mIB-XWpv&em;pU-0j8$l4ar+vNuH6e)%VI&DxRrMB4}rWeWny1hu?thT*9aBQct zxTVI)UvyBo@PMc2RwOyj&`d}F-^b7LJ|?*$WMKNS)4CmQOaxmD_dKHsGhO%)DAH25 z1CKtBXZ2C9W93*THo=TFTl7jis~zxj58GSd$VbtGJ-Zc}%mVy|E#O&M&4oY8g)Jhh zW83B`ylSnV%Oc2BZ-UOV5!sq*Krab^iMyh@KZE)1x9#D0jIul6Umn-j#ChcRS0Y^! zDNggIb|QG;HEx_mCN9*swY(5dP9BnLnQ<1sZ3DSLmk>?h#ZFV@%nVitPd2TtgGqRn zA4Cdzge{Jnxlum_4?Dx&L-hgXThyO$Wz$f<0n> znXhndE+a!+()MEWZ7<4UbAo#uMYiao&PoNHYOJwZBrijSj)OewdfCj3ce^{`Dh$fN zH}||#Oid0JwT0Z{PD$O+^O-WDwyy;(4P5Z@IJf+z*!n<+U}8}_q#s-CB@RyHYkci^ zVU;ehhyM13xv5mWz^_kd9)gVv1K0cLNf zFF^C_$nKbFdO1ra5}OxLd*>i;aN0gnuaI?DVk$+-1ZtAF=zwjgGUf_PCuZ9!n1nsC z->{QT>d~qNa=+_XYaNDE!f^K>BR$89q}`ZoON^FtEmBZWj#q=_ZKM)ZkH(>AZ3Wjn zL50!Vm+D1&HJs+Q&~IlVtJ#41+B;x?ANgD)uNLTUycL+jIGIV!#~$Jmo>hjZS#a-O z@%APwYAXe@iKjKQOYliX*~7q01?U}6Vq3~X6_8e+$3C!w<`p{W7IqMG`-M$_&Ab!X zV(5e!c?@XfA9Tp>;Mh%dQ9BLnayd30qRe!>(+S{vf9Z>QGXD;@{h_>R&#-S4Vb@_w zzp#bvB=G3VRLM4hD&mL27fYeQfT!S&7BXw?6}+EeHV-h)Y1CEGi(W9lPUJB9ZlQm7E&fpsXjYz>w?pard+las(UK_G!C9r8k>;1 z04L6Y6PTID0&Ar}mS+oc(c|nJBpmkGhuC*GgqsnKg!up#q4vombU`%W@pT@Z5<1&; zeisSvU(}W5Lx=8e`FCB%f>3q|lV-4T;mCe=uX!7Z$dJDe82Kub17JcR33KraJV zjO87``QbV99W1CjV;-i%hSJ z>48jLEdN0q9zk7pnBBH(%qTsY-3FHqQ6qtFBC&f=7}<^kcoygFWs?Nlp(wnVdO-ER zbsPMa@$mE(!8@!h!r3lld?fUk4>rQy#_i}qUy;_F3$0@sdfgHHj#BW~FCv+|%YM{v z;UcfIcWE|!!FE9I>ug?VQ?FP*lM=V)3pBSVoK`$j1E+S-j=)dE;v@?p4c!TU-W6_h z3(*OF-F8`lb#PWAH@^T%ZW`tw9gKXN{fqy(0~OG>oAak8BTiri)RoG}MGnzl>}_x? zpmOk)IQaRa$Q6yJVLCnh@qu8D)AS>x;9DV|83wNWH=BZI_&=QqIr9>1EV$25@`>z7 z8dir+T9&^-pXo)$o`AF7lFa}vTW2Eh35w&6&x8Xu90AjPx-w{ID4@dhxx zY3wVWIf2E0L!HfsVz!mnvafVgwHR7M7|W#3N*^V5_hA2W3zDJr+{rwXj;H3C-#jbk zerf$(H)jg!RWC!h9oUAl=gs1@5|vEcv*^$wiGjZj{8Qk1xi3A_bUp$^j2Zesh|r!<7+ zHg8oD)(KwRD)iJsG=u$R6T@Td38c0Fw>dtAf|Ea#y-X-_424;GAhn6~0uISKucak- zGcTr+%DL1YJLbcHU(Z23ybmR!wLZ#v^HDY{QpHE;3_jx+{nm67>*=8SV7h`?PDhTj zxs40%ksMn%b#w>?xyLl7zy^B|GhM08vafCF>=hZ{bO?JI3T$?TJP-R1U2K5rfh_(( zyxV4~Bb@Hy;Jp*g6Y%K7yt6&37NUFRXE}gM<3ckH*kxcDbK$dJLw#*gQit+w*ta>X zPU=y}$uwp2%rCVC$)EqhzZ-2{QzNjd8u~mC^(__$_jtH!MVTCz?^O%YF*@*W{9mMD z%CV$k1r*XQa0+_zg!Edi*Js#h(Fl8{cT`orPLu-nXn-DF8!5h^E`~%|9;d1pYbwij zdW)FkEVdT=vadxtC}vF6LmKBNKZczT4#rv*TJJ42UcaYZ*k3OId^Dba=B4cowFlGc zfo;xeuwte!_~k-W@-aCX`#Mpg3v{pLdL|U>LfHSxq%yGhP{u33^WR6GkT2<`LTz3s zl7*9HkY7=4?!JlG~G;fBr>ks5jq|+8aFVRcAM1LHj0P-2USxirLk~e zQbBoGhLl}To{>V(6R&~;M3DsQgf7W1VXL4pR0s?Hvs0aedvO5$uaD`B4COFZ(njiG z;O+g`Q*^#~U@Sj?J_aKt@}J3M6QOqcVmq>sS&E!?J*WW1%v!yJxz2LCS;9@A7$MjT zIB?_aBxf!6>)a}XZ3Zp(x;m==sJElp7^u4$F&7K6j>w|Cx06IqTL?GoFz(wq_MQft z8^9W^`F-R&Td0q88yY3S(Y*@AYBE@PIcWMfZ3z*NRX0k_gEDmqKEV!cY!N;W>e^t_ zj%EP?{h8VoX%KS#AFw}mmEr&cOr~snF#O>~x-$LE`lI(7ctuBeDp5y&S9i=xJ^(w* zA-KtRP+Oazat%Zd@H}>QpJ^f=HNx!8WnUvTTNGUCjGCpo^Lg$$6DohHLL!lKk=A&3 zvC9|bZZ`2e3m3ErZw8L!m`*et@BO_t`Z^GE19<-&jzJ-cGFLE-M`3SekuCvbbP}2S z>1G4!<}TlW4!RqgN;8n%7>9{l1wMKnB*Px-{iY(=(qpKFA8cOqrx`XqA4qNBWEMr1 zH$4&Dr-PVFsexL$qmPtFZf6v4h#9vB>G>vf7P$Q~PO`l@1w?t1cc4w+%jw|Uw?Kwz zyDG? z`mpnQCHTp9q?NE^CJ)=G;ytfp=Xn)%EhndlftE+~7&p+Sigr1%2v~SnnjVYrHy0(kw(L$%s9{Aa9BM%pFx&`B){SnT{Ym(wuF@ z_C!vKi?q~BY+ZI{3(R6Y0N!haO`x7?WcK+yE0IL21vPdCQm99;LwN-Z{~3D@jsP^w zpJS5T*JtfKmJ@e-9-e=H%-JaTzTM1GaO277`t?nGJ)APb6>b6~e3y12X*>d{khbt@ zhk`wG~S1y(v<1`QZ+1WAF7t-GFwm8-I`}vV<$3Oa0+hX>5ArN>gB0zcF}L zLE8`C^soT#LR-FdVuG+2%lsiP;d+QFK^M0BMELI@<_?)5Rg|B2FAnqYria z|I^BhR}9CVZ*|^h>dq1fxfz8Q`VyF2V z-!wAQ@wq)rHt#X?zyac<=E(UXyDQS00bUWL_P+elp7CGnpjf?zzS{z7?mK=D>4jVJ zGkWeuz6>3ztnSB-aRua83#S(i#UTR8nO5iv1?^sy6#41Z=uLBNC}l;5u8!>F9w=gC z=^eDIbLKzHtf>Oqk?K9vyqi1)OA6+(7CwPu(@is#AIu{;*bU+Hy=8Z8W)sBrLVErW z`;%Gz2iv6EY&AU*{>LV4c3rYF@qG-j`V9KKhMUkqr$imqW#7^58-a)Xk5_}sJstkz zMp}qeL?djs_klb59r|K^Bp{3OI@DJWFbmlanqxMb&+vN-AlKOq@3t!4)P7qRIfcDA z^|?6Vj=-#2z&cag1?C1&zoxsk7w&R0I4k#cIpnB6BV}<}L-Bz-|B#00VVI;7F##JQ ziTF$>5bd~U)*%tojDKJq=%}uuGtx*=6Z?7-P@Q8%Iry)M)Nq;$7bmX%1dP;(FN4On zO=W?j+Cm&g<=4S(;df^PX6Z&#i3NEUHW^%@I{isXcGc6cXO+ciz^mvo*vUyOQqXr* z(2io2kUBgAWmJJd8M_dPy-D!p#!V%|GT0Z zn&9|01*2+#3|v*DIa^`}vK17D0#uCtfghKJB?p`Rfh_AhxEA?=!i&Q9pK4y3%Ghz( zgyi8ogFRYiRDWHcX|S?;>V-N%JK*~4MJA_?ttr-G_wg6}pEe>2+T8&7RtLaaTbOqG zsP%wz3+R90fWPC}fE`;S`&Jmc%2(jM9Td^@OyyL|S&Z0DrPKp;2OgWjc1}&`IDrBJyTPrQ=FLMwt|QK_A+U2YCnr>#H!=mj*D8Y5H!oEh^PDfo zX2g408VRlhtPQ-kZpfS5M8!P9_d6hQ%jaMsjl^EYJ1FbhY#r=qT&2l07uw2qq#DK} zi`W#~*`d50^ysgc@zZ$(_V4GI7wEigu$?&_E?!A+)ccqcFX@L0& zq!u)h_`EWosbl3pxRP0zMdytIORWrMByg+Cv7DkT5ONrDsK=3GuBJEZ!YmK;vng<) z2O(M7AKG>aWF`iKm9%FM?4M-oLL@5k!n2#t;FX!zsLKcJFp`h;O)Bg;30@5Sup&Bf z3H&+st;|yFaAb#b))go92n=WrJfC`~i40IFE0~sG1M8t6T+};kH)v*IVB!1OJUbj- zMI;gn?d&-Chn62fn*D!B0hZ?1C_gskEIPm=_~LbtqRN2&GYF__i1>hSNJ^;d;K{bZ zdtZr+Ru%Y;uaMV^gw7krlG)^D2ON>&a5RqSa3HUh@X;$kQyLG1P|^x?7tVLGyE>t1 zg{jsbIIR&d%P*=)`zRsuG3zna_5mL!g$jECnS`4_&Dp>i>ftwkMnPt##E*`CU+slB45ytrw)gPQug5Vuj{(HoMZ73Fa^ z7Uqihs>Ab%F9L1Ywgo7lyB{#U87jpN7Reo(3RRAM)L~&Y;N!O<@zXd()VOq zW_HUGZ_~|oo4Q3h>Yi>2%e??CM!*h_!7?k-Q(1sZGa2jbs7mxgTrX8kqOYOvP<6?i&+Cmtjt{jJ*D{HQH2J<~qg@>Kui zPqeHLDcnx(tN7iJp3e{1S3tw$CLl6HDDD=WXKd`u=eH&qc`6Stu` ze@u-|{h;D^2Ccu!m?xt~$^T%v|I=OMY_ZIn@USnVI&pKO{Vn~1&g=JJQMFi-cXhQd zgy}e^13I(--dI2Fe6Y-$aR;3*)#7(Dr$oaKlJ{6gQlj5zpggc=lAqiSfnLiV^mDR8 zeTdFXh}IIQ;on%9x{#OER%-Wy;b*mxQYSE&YwDj6gqr$$FHSyULoZe2jKwF=Whe7^2ketus zR8jlQeW`9oz#Cq}$N&&o1QS&|0n?a9K*vy&D%yWk&tWc>rhNwe6`*6{P1 zYOW_T*V_m4aC#Fwyp{~&Y?ZqH_Qre=Ukd}71ckZXY@6$yeuifm4#nN3ll4h9Yb$T` z0}u6lW~tt!(XgpI_3TwkB_wpY`hI^MBwdpwl?O6Y(kJ!m{-{^KH2q@qH}Ui}Y+{*c zD=+C14Td8=CP#W%e{L814IWBOS1WJB3;c^sd`3Uo4nE~MGQTRRhT>J#$A>0;VXzl@ z_6rpM3wyd3hX&DxhjiLi#4Dn6aC;~#eZ30vKp0N3zS#rv>#lIdnYyVui!zR9wkLB_ zm3D@G3RV2QSg8rwD~dLyE7XrZfuMfx+6VFEq#0~xL@G|^>*{O7PF`Q|on(5q>ZuaF;)49F3x!`sxMmW_m<7q~3=u{gZDW zil$>!l)lyl-(K!LRGmY2yZxu9tG#YY_R^PL@lpE3ib8nS!b`s8nV*BZ*xk*(H%RZ# zd|5d#*{GhH)=@J~N74|riYwwAd$Ilt@f)Cq^F6&Bl{C&g5Py_z>deEJD&CVT4q#_< zGy9TNdb;=Xkf*`<5AzMbh~JE#vww0q{j7<1$JGrU*7bb9Om9#0ygt_FWL*<*Yp&YG zT3O?p`Yp!8rN57h;nJ7t7HtNtOjUWrevV<4t5rwy^%``L&%KyjJNtx`AWNNuGL^;fA4_BLIX%u4M@-5xE;lvmE7S>HzE;#8(C_tz^G`D)MZ~9D^|@-um39}FL%_w)$yQO;r}l4EQ9=Jjsv|pbR&p+cYrGh% z(8-)VU}WbQeYZ0_&Vkmy5ii%fGcf%>-FQpo3BSwfoVvswjkd|qoTlj)^(UQ!a{n}v zJVF=fYw3pe_3Vd?T$+AQ3^g&c)&AJuK_*{~i`7`mqBq5(e~LG&2F!(kpA&x#B|bAJ zUysHc6&J(@?SrlvHxlW-8x2n1Wp_n}6@QLLZli*Ci>x?_pQd|9vvFY*y#oIzmb3gX zbEL9sYEQZo?^zxnc9z6g`Ve;E92D`ifaBGJkRP$%>t^=g(NxXoI(@j??XDP#N?(h! ze&op)#J5B>Wq{+8aV%3+I9rB(U#!#ibv4;@*_K<$b~pR&W~J(g$e)8(R839b6PC#_ zFHd@tu-8e%*vzTqIy-}&j$@R%FkMrxOiATMaZmkwg-K=QuF8t2L6xaaQ=QKz*U$@c zMtr<-s@l^;k?Z@FLy{&r8({oz;Lf9b-N$xRe(6-Jzw(=ZvsIr$^0jdc>S<<^R%S59P&}9 zU3>Mj^HRUUn`dG0`Mm81?C?@N{7xM685H0KCpea7K8#p z@YcHj+vz~sFVF2uR_>JdmWwz>lZxGJ$3NvRe^K2Xr?xgNRVM2AAnpc(I4nXr1-ac~ z1$9VySDE!&qWhZAhdYe3$N24_Q&mamgCgA0WV7C}GoX>xqO!~zaeZ+_kvM7&toI2! z>&LK>@5fGEOErRlpGvM`Kj+&cJJc@Rh1p#r8{!Yu`NBS-$3$n>K$joTnKz2g_fK^v z-@ivOXFIFC|2lcd-sRrW3dmG`rh{JUYk2eCW;r%GS4LGI+E@+xG89hLR7Jdpoq5X> zn?jNo<5GCv^Ze~GG;9Zj|DzovZK5jB#+vGbRY_~4npyxwtZ5I;8+2$Q?{=}u_wQ0K ziX&?33g7FlG(Fo0PkvD)cbfU$?WsrXExuXgsE!PE(Wz&}DPi_kpu3Oo~S(64hp>$L&K zm1qCO()ik(OLOkji~M5TF6YIZpX@t3p7|l&vP$pxHZP(BwAqy`a7A2 zG9Q`$PWj$tN#dj<0W-^h@qin|y`L-z$RJsV@2tdG2pj=Z1^F zCc~0%gE88ft;gck)LdBOa23tAJn)Bc34Z6nO3RH}J$loXE8NpghsWu9R~Ew)?-PyP z%Yx+T-hM=V4^k!h4OF0l)PJT^?mQVtf1C^vZy_Xmq<+;=Y{Vwf|97ym3_Nd6 zyj)**COQGByF30~Mpxv_sH=1tUk?xbG}DuO?~o3){KaA!10B*Z6(~@<|wO6fzRecuL{DcbsWtrD~I;_iUWTszgmK^^O z>wA7m1vS}`>CKb;*D4;+?=?b{u}Wq9Q`Mi(MUA`k>*|6^LEGXdU|fyR(Rnp&(epZ6 zs*4|IT5oqTYhTgj1uCj*Sg#om%6T&BEbnX} zd&^0nM|kp-zK@c)s+!yPJW4k{Y?S)m-67Ye&5@XSB2V&=UYC2JTy<#EHDbmyWP^2e z_bf2OsSvqEEaz}us3p(v5Z>+3n|~$yc!4tke)dcQy6~FF_AZ%p4|nyG6ZG*pbPQfe z(nqkPXR%Q2)gG4W^eGjeyh+1X%NBZCO*>f6r80qg5_oj{mA%1rSxx=2?tI9K>dMOw zt51$Wli^7u3txe*omF!FE{gfw{O)vy!U`*y=Dw{-Ws+;GNw|L-IlLHR`vX55iE^9B zdaKOWibpd)auvki@nlruBAGP z#-%>gP2+r|)Tg@tJ7(U84VH^_f3nZ$r_^u7ZZB1SA72U&J6o?xNn9dMd!H?wDU&m8?ich@fo_EL-lD9>fObc-3wVS zk4M5My75xa#TUw<=I}Tf)#7sbTe&(!L#vxke^2A#o@NdEll*>h=tVnBJ15EY2I;r^ zfrpsJm%i-(R--%9xME39iDH+ z^D_5B?53tai~n4?AwCw)e9{9vR6VLAT%u`wBdbsbJ1mYLl`l6=4^%zE2{FQliUV_MHz-mZV;ex`~rc!96d<(Pp$_sWTb=<-5Ajk0<0-&%|TtVLK}; zrip`+o&LNp%4-IN>q}BwlJH$|8y=y%Or{G9yv`lPD*1hJZ#G+4lk}cQKG12%vO}`_ zsAR?@f4k9|dPfZ_IgOS!cmCaicxfz3b!ua4QT>(VwKsb(+DI#PTRsOf8wdyaxbkDG z9i)Tyd$IjnQ3D?J=D20%OclBBQUf6JW0Mlk+Pj^3OQ%LJdl>GGOH)14tJHRKlBK$J zyTrrf$9-k1f0C6qSHI}2&b2&KE{{H{Gvg|;!`b@C#=vZ=vn;wn?O}N>QytztCMt%3 z?^oMAOCQ!tY7kee)9#gh-U|8sA-vcctcQl?J7wAe_o?IliD1?W;0FmqmZTX%qk4vh=Rmjk?V zPJ_R4qTs(oRF~+XUch&x#3Mxz)1|!Mt7_Nl`1mX2y3%9i-;V3Z@SBkS6yM*}sEhcTzI1V(zUyYFl@>8=;-w!-Zc&$+$;x*|%{lt(K7v(t zgGGI9-&iJdsl5Ly^~s&k;_u|D&h>&5=Av&`-oJX(9M|XYDL;uNU(ye=04|e@)^G9s zU&jyyCxV>h3FfHS-D{mU+Qam$481kVe8CcQXT2`dv2ZN2K+ad6gZe#wVlxsZ*l6tCR7tuLXY7#lpCToq1hY zy3W~(`*)DbJXNf>Y5nc^be4UcJw>M5Rhr+2L1r@lmR~KBnT?A#I88Cn9>W{u#EsK; zN1tS54|+P^he2jCwW15toAf`O8@JGZ6h-IBJw_zI(!Kvyyq`TOlZ742Tm&hsqPDZh zs%wZWda9AuQ)ylTH!k+%D?DpOe3l4rtcYPPkFZ!JVzr7-H+lDyR#-qoZljM?&Gb+4 zpTu?*p80{6S7GDo+3)*v{D3@gmfFK6E2}RzT*zlz>+$;mvEMFg97elm ziZ|<}4)K-+Jljot%rp3271n(}5A=ve|wHJwe0oYdc7r|;OkcbS~=ZJFCx8utSUemy?qJjZ9~=Ra7V4kF$KY}P83uW>x} zdt$8b)w1fy^QO|2E@HK|sTWiT%3*JV*|rNw)NmhLGsQKG-QFA zTN9q*KGE!axnFy6b0KRm+uvh#cwE9`3}zcDd4L)u?~C|AvRNEmB0{`WJiAQH^dM>L zh1NI8POo=&C%deg%EfOm!qaSReYNV1@Rt|FeQm@gZBzLyPj}YndfoH`t*t8k+AOC% zPjq!RjJLnobt?KCV}H+vKff)i{Z2HsT1GGrU+#b&R9I6lmisq6>-p?O2R6BNszU$C zT>N>Br@t|t$|JoauU>`UJyU(7c5%7N&G|CT(XPF$53dx}^3;`vieNv?jH90o((CLo zYRh8e^MdcNKJ8hWL9E$OtGES*^NkaxMtbkjs6nE}B+gn-BKz6hTgYQhR4?w63?OrB z^iJKOFXlWowSH{SSxy=l3YDrEt(67#WIGSp9VQo$@f{+$*F&gNd`3#$dT2Z>o1vA6 z^k3k)W~SCB7tq8{qBU}oPt+;Cj*h@xZq-lpqdts-B9c5^*Z1lx2vNi6=nhc^6aZ(w zg=@}HJ#!L0i!@3^{dn?N)B;X2H;d&jre9l=TwHG)J(9(l&QD6@3BAbI*}T-v(IgSZ z77<|$anyO%dIcLgjz<|qItRc3tFulG;WIko&9(+FbE9g`fAMJmkGYZ7bTsyxwDcan zWew?0^D-rIby^79!j&E>30v8{yGY(^YD1Gr+5~pJw)xzXT*y}sX06APm7$`zC!DVP zj;QJ=tMD0(eTFooRjPJo2J<(~ohWc9bDsKG*s)$Gu899_<);~?2G80mSv-GhG_w)!*&CNPC2zR<_2?s3W{w!LscScr+G+86G4Aa+^$kq?w$y1!yZA7xchYkO zH2!-%D!;bNJ*i5AHnG`V`L}P`keB(s3SRoBcuU+R%+!HkR;@+&n6tT#KMqW)bKW16W zjPWb9Y7o6_rN4xMb+h^rEYbmXCEp0*1a|05*;p^OY^o^jQP|B__&kknbRd@n{Mv)= zRW}no-9aLH!_PXSWKHNm1F`%0va~D6*p=3@POR2Ij@1!D@fDQo8;F8#PMO`+Y+`#c z*mCqPWv4C_=}Z>cKI^?1XkZ}(>LniODbd~QY-k!ya=q(G>+54xC8VdDXrYsJR1t3# z$eYij5zmnG8{lTA@N)&5J1R?)d1#c+_BLk0R*Iu#rq-Hk=G%FggRIO!RLJGMUg59j zCL5d__eJmvI6jsP%n>WRtNVBkX`*GUV;xe{jEp@Y#y%|jYVKO+l(%FCCO@jt57ejS zd(pIRa62-ef?DQ5P_N|Q0!}$y^qRxtT$o%#r@N-^g>vmUz>!vqRnAJy_O539 z$}K$0q{KNEtW$S2=MUqBdj1MgdKepDisy%TjUIBsBdp&%(!0!e#q{8a>T(LM5v`PxmWlJhnjI!cGa)nbZIt#kmKIiC#(yGJj# zBf5R6nXc;Jiokx6%5`>jK7{*5NY8t;?ME7TI(bP)qt#y?HHTx#QXX;$?$0NQ`{=}c zl31Xdxr`*v;In4)Wi9c48kx8lACIHY4CrhX>uPDo&aEuKR`R=!EgddbIDsO^>v7T(0va-J1?~_=e>>8wIXlIl{>ur|3r?5_U1ZFINpHWl3tew>gjUn)jSe*1NG+ zo1ia^*rQj)2OY&t(@6X4=J^pRev;?CFZp}iNi;KGHq&2*TaCo!qWKWI7Ip-7X74t^ z0h@>n^3m@;cB~CsungxH`FxSs$MvdkuUec?T+w#eZ1bb*-8eReX%!<_2!1&F-E>v%bOPAT0qDAHaFu>v8%lg z582AM*ZFt6c()DxI*T7I_jElmQV-A6w%Q?9Rx^5DhW|Nve}+_T#-mmc{dbLi8Opb@ zCt-zrYaRWXDvtRx8ow9)TP@|O_#lcEiuF#1jJ+@KYH1}!P7Q1$f;}pJs+*dpwlsou zeolw@S=Q2pADF-j>?DErqxye&uowBAmC)OkZ1KDJbT*8jR`fwO;wzSUHxQMKu;#ib zxzNAcNl0Vd?q~%kym=MddziFuGvX0(#KmY^EXLR?rkO5oIFY4Xkk?7fuB+aL7^TeMe#u(}TJI$e$E3de- zRo175?4ds2U7bB%PSZ-*fJxSRfw>IHMuK%wdY}lp7EE>;smK>gJFOJYn$U$=aP6@u z`7#gpSM`BS^6{xM%%9~;SEVMyT`%U3U$)AhSnlA3OYn9WTCT`?-34g80z!T>UHK8J z^a0z~85I`b=aZ!LeD5h^724CUGyQo5l^1&EGP3yrn|Y5&r%>K`(z-KHiQX*LWO96j z{i;IaNAXd2dwWl-&O`m3WUd&!CZNrFl2VIhbTYfQ1^nYo{_R=zuM>*2p=;~WZ4K*J zn@!4RX@;?uwNPp>tqyuJkG>V4RZ|*&o1HQP#Fd?SlvhbzYj0?W8Y6MdsiW*lElA5& zGWI>Ly(jv4i=5i&VIJ*Z`-9Q_B(3O=k5y>J6n15u&tc9F(jyos`#FnlT!$LNv%1>O z9)uzi9QHK-DpgNxf0W&NOH6bjytIpK-PxHk%dxz{9+7ARw*C|IFOU1t<;JLfh%Wc% z>z@}O?p+U)Q%jh)El zOHM*s`nhWl>oJJFegPK>yIjZ6T>Xb;H^u4(@s>Br-p(Xv513P^FB~V!CFnMv{MN|w z=28C-ry5)>!Y`!-Yy9gs5*cfpwd^&@tSm=Du6Gj;+}oH_NzD!`+H4kU%(@$DhU&mP zwnQ}R#|id=@8*+=r%_etSXD!GgBZ81xG04+8dXQOrQB|C@7&SY0^ zXZwel`ypDmjfQTaUkl9U1if%hFMX^^Q(C!d|=QZXKlH)<(r=CiOnP;VZuRu9!4#q}F;q(3?h76Y`V z|1DU-6?A=^)jq~23?nyt=-Bnvu{WNF+I@NQl6V5GypeQXX%5HP?T9}ZVFhjYq`~xH z3t4O*T?}KYDvoI>r>%%rW^<;0veIM37dh^_j@(RV$p`bMQ&nR2Lqz6Sb0ePj1Rmc4 z+wZ{ZKgA}sHQP4cS*nUQkU!}oqH<~(+px#;C(Lpgif?3#V^nQx#T~6}k&$+KPhD1T z1o};L=QAXt1O2VfYc5t3n`zaz^W0t0p&I!;fnt+THf=47QGXfU!(PbNK=wQ~$}DnH zDLV+YqI`C%HtO7g-Yr#K){9s!cI_oJz81CDn`=uE%_wv)@Js}B7RPfKa*2TWCMb9zaT&9=#9(703F@?YwsRS(z}zI zDJbw7?zUuCYLWReBepfmhB&;(swVrxAF{43y}dWijmLrGVu*%vlHk+lWqn1iHE-re znwfdPuI96?J&k=4D>zZUbcCgsMkyqM%KqJwGHYYKTg zm5mbYhj!nsuJy%}a2CS}Iyc!*k)Il9wIpkM_Mq1q-s2Gc+~T{cWWPUq(2<4Qo<)+o zs~e2)wu9o_%|@6_mrnA+L-6P%X)MB@@LN0lmIyi!YP1dAHxOlYv*Dx)1wO7a$H3vW ztVAEYe2uj{gEm|R$JvY`520ho>lc%Y9k^J=-p#j~BK%&+Lm%Q18nawCpxwj#{UGCR zG+qm_!)@N$Se)=EUhVU<$35GvX^oYxx1x+u%-@ivz{FT%58pEg<3MwH&k z*6byzvqVoV>BM-mt}Ywt%%b!%`bcXERjxXCJc?W#N9TQXa~|uZ4#mPv7wNP&pMbQ6 z7-fZjS9$jdt6W4YhO;TPP-KRu*ORKcJZ?*KP?g~8nxkPmqaR|~hqFq()n|09lX1P+ z#@>qBHDnAEJYDLUBl4T^c+ritT!^N}XmS3TesZ;rpdJT||a^n&Cw>cLu#L^tqVbpM)kQq6${hIHY8s>SEnRm%*{UDs|W~CEc+s3wDhj!n^ zBUKhYWZS>+>0$nH8$CJ?Cs$kT=W!3Uj6pQz*L1g(Wve1j3`k-wwtm%+lD*ySfv<+CVGE6-upH*t4m9loB082C@0&Ka5h9%3($8JZLQ0m zJ%|GJ@GE%VEwr)R-It+4d$L+Un?rWr()WRyn^9sT3h$AL1S=7K=Si-ZVY0|^DxY~h z>vJ_~b}`BdQn8$D*(2<`d0GA4!~Nvm}|Xdp0^jE$wn(JLCbvWJYY53ysOa2 zYw)SiDwm;3pidfS$GN-Q-3vV(VvSXv-IAqU0jsva`)YY^u_xA`aWz(aq|xfjgcn+W zq45up{t4b3&UWZ;#kI)S5T9-oRZbRd?ZLsiY+f^W3}(fy^jvpqyUlvjq_Lc4jxnEx zY-F%kr_g0D-Uhtl0;orKvfmAN4|q#w>kH9-$XRn)vod-($~()w#fjdmeFv5>;1@ML zvDKR9qIiMz6|uzQdF(+@w6;cSDnpp<6AXjy=+3GA$bzo&jSmAM2>VR2>H-|_wk7RE3Y>44j;_^YO zT!V_6aHi6@6G?VWb}v+Gruwc0PE0k*5#ukzwIhD!ld;{t+wS@{98=dYw~)1uK&Qqc zl38Rv+)?!ZWw=__2W|C^b>4LtRSQvPx$jG@X1h_g;Y09ik*7m^yMk;TcE@y5)|8Gv zNTTZb_W+3+ZuC>GhPYr8u2#3}d5HUZ<7OW`EJgRw8+4B~-pwj>cdZ0Z@~wRad8>mC z%dDcrO6Q_X5o=V0GE=-GmlSRxBXe=5iEjs)-zij>=G$%78)EW7_}#@AL)=wnp8ppU zY_+CU=3QwGQ^?6yekPY5_Q&b!I2|z25bZDLV`j2LR~a)zEx>^(S$WuL z7Smm=DQa5e&Lutt*`GjqPLZWUWNNMFoQmVg6Ru2gtu8yW5bpxEaRi+wqJC{uv5&x= z!2$;xRAhua<7_iRp=Y<5(R!5JPR2_8z17?H`FjVtulE_QPa+CEHv>QYRvq-7;`4D{ zUr&H9khv@lCcQ+)3)3a}`Z}onUyS40g z_bF04&CHLJuu{(tw}y+%CsY?hB_rU4NLR zfbKJ&ddZ9Iu!!f0ZUVmYL%bHRyRp!hTX8!`?MiYt&aAtj&23iDz_o2+q=~p*kG&Z0 zy*pXcNEY_ESvFx|W};0o4KAZi!&%N2-a8Q|f|o3?nyqGY1dUhFt>ZX4+bZ+vLO=p% z`BY2>R?*3g)>V^)hW-A*;|6L3E4!C2uf)?r^GeG53>l66Cj~AR_l$z)=jg>0%{Zr`$2g{Z-96)VVj&!4O;M3B`fK*0>Oz4|?+!-{~K>!hjl=n#n@fwwuis zbJ~PMdQIJzM+X9$6wcV%hgWM+YaQ!alAUYtW=DKG)03sXTW$tBJQ04kr=2C{8Ek&+ z+I(ZJ^~?$LScDpTT;FFto4uisRBT~M1L|6zUAxb7_1L;4c)JWWYPuHs#B1;|YrHGp z)5nat-bg!*xZ5aev$9lfF2U*t`*w&F=aIl%G#_h4b;!t6PapIt{D!X)o^8Q@EyVL> zWU8w8e+=IFT?o9xaP)6OM;DNXB`icu5y)6$)?zCr8>N(f?8D3DX3~^|Ie`Kn(yT`4 zBM-PwhzU-ZPskW|`gdQJvH|(o=5vt#d{#|C#PDvXY>SLI1X+V~~`eGzl~%RR_?5R9Bv|r)L6KGwyN z(HoPXE$qWAl2OaG8SXuTW(D{cveY8)SYtjB4;1>MgXaIA4?9GLc4t>x;EBU1u-NQ_ ze;Dg?$WaPt^?bZ)NUHmrXMGa9h@|fkj~qeW8MsX!7ge4*KVK9=_$JyeUvY zK&eneNJB`|FzBFzJz&^jZ%^*zuI#Km*=@R4KaaJn|MQ>!{^y^6zUf97`+xoO&zk@L zb|V`h>l#7oX`LYfm0<{-NP^U*x+1|!Cn;sAE~(rvus(Y&wHwt|t;MnIE8nLu(&vqb(1`DF z{}8qBx!@os^1>U}?e%&e{E(mU)A>SH09Y{~y;|zBBCD$Lk$Rd+#_?n_iDz&^XBLvo z^ZaCyi82I%Ef|dUCqrQXmXq{=9!;99xtvI#$=HXGgki`DS)qNKH{5L(O65*vnrC0? zZNA-2dIG+X*lXu2MK+hOwG|ab+~ysV6*_RCNp;a>3q`ir;+tLRi&50riQ55fTedbG zh|?W9J59WITlvRqu29J5YYe9(^k7iaaAr9TQE|j;-!(&y1J{KY2A%HH_4UKuzT0+~f6AF<+=Pfu8WY zoCnap)eb>U_j#D%E~qCTfJo#AI9txJnEsR@*>>PcCb&j27X1Ir-IL}v<)<7qJ02uh?bzgDESkY}{G z6el0z9Gh}lTx`q`tgg5N??MO_zI=Aj4o9LbGVxaKX7n=aPfZCo zauGlXe`wjCF6zx%Nu|)B>)3vA5ITNW`Esqn6`ACP$L%SpSgm8qY>y8UY^<3P```@{f>>lf$8@(K~+oeWz^jWKYjU<_fW6UB+9EGhm2nxiQcD>pdj#-vnO&K+nA(u-m z>V+Vy!%YIVR^leDTC*d6sRSbdSvfm%L6F@Y7i9x=lO9)ko6Y3pSQmkq3VHS%yL)Gs z>EeKDqV`jlDeCgf7_kx>*U1(~^%fHQHme$liP{|wUm!&F1TuMf zF`CGv+^khf`8>zUh{L>P`ghX=IZ>jQ`-|FN_k{+7>~4Ht`?j&=!lhFF@hSV1%@&0B zbO?4@%qG*88H$L7-@krd-4q92^XB^ZP1|WFcXxgLSZ8e8>+9R@S^eSRsZdkx=Jj2V zTq``iNI|nu0?Or_9JhHp38j21xbL2r8UDJ*!B#4%yiDRt+he-DBWX=OQyc4+xi zVcD1bM-K_^nGd#o?)s>iUk$=<0$UqNs2)R{kj;?0Ll^7?__;o;mfDq%Rb1%xc@lA1odIbvl@|O`Y_ji+5=|4!w0GCM zbMjs-6@*xHFl@iR%CtKYI(FH%tvtVW=`*n47TaO>^?ppSp=utwbKHfj%>unIUnZK>=And&XncjuLlx>?{y1DvO zJ+^La2BktaKl0m8_~E7RGdW4j&qw$O_e&!X#}>;AhSC%wr2q}+D<-WZNrq0-G?tF9 z(hR}q8cESOp!AHQYX&QTDg!~A$hry`-1w8^OxILKm6xPQNPuBTU5f!_rWhwFdKCo; zM){iP3o?quQ?udlOEp+eWZ21^A$%vN(x5*Rr6iir#O8Fy(C`^5^8=tWkyC8`-WV!E z3O(}a6XGJ3_NS#;!JDu&Z%<0$xmp+brhX2baF9k z4HgtTSzP#SUjK*MNw8Y&qjSQliZ5uh*kj9?z%|N+=TZMP4O_O?ckIEp;_a_rf1ZJD zb8YPh1nM_ezq6eqtJ$<=$M|}s{G2V6v3gMHid+obzn!WyAI)OHJv34%| zak=Z7G|EEca4IwUctlbd57f*GCxK!pKLCuXN#vALNu8nzoFXWU(imc8B!*%#e-mX; zSCfGZR8=Qd8crrw%u1Td;)-D|lO!!m;%H9l(WA?hFcKzdzc(V(+oKhF99gtlGdkco z)4BTOlFzv5=C9fLnRb6`RU|6*>j&v8*1DT8C?w z#k6e?fOZV`^PkD_`+Kv0?6A2$yImN;^oad9}D zMPpo(<6;K~QNYJRs>Md_sd4oMvF%6LN*_o<-yrGXD>rl6l=?&IEH!8_K9ebMwwQB; zKR;iHoo|~~XS{lMbyp?fon4C)NxePX-4{BT5Bk2g8_!?;DGXfOKQ_IMn_orW?v}q< zDqOlkJmZ_m3I@-opGToq0$*S%4OW!20)|NHz*w4Yw77uQRyv?{nxQC+CaERRXT;d3 zH8IC2ijkF>s_63-DKG>^l1W|eiOeEMMs+dDDcvQK@+L*TJ&7QmM5oF1QeHI0H9v$) z7aSP&`#tRBgkT#j9``uCfR`2*f%8?X+!#`@#}#HylYTTjE@lhdrG3|m$O*pX7m`wU zUY;l@6!!8c>IU^_Xm~D)wLa*8kBaVGv==tLqBf)DoNo!ssHZT8E# zv9@ONPjWx6e&)lLtsmP5N8|Eei>iLP{$2aFH@g4%tLihana;bnH#OXBa#H1o3bkuV zbaK4infj1ZaiamoH5sSLzmBugHN~i|qA83b=>SlGFnW7KnwG1@(hwj@BbElV4S!Z- zu%uNWugDoGE|*hX0COrbjei1Vf=}XrjB;vwiX{Tk(Xb~Z(6ji+@D{?K!iU`nf9X38 zPG<9YG>C&X$92h56jd~kLE+13qs+2GGU7S)d;JG+y!VjJ)^)$t?v5U$KIIN(j3(81 z`Upl{$Z<%WwmLnwQ4>%Hd=$5%I$Is^y*fKhIibBwG#HcFYNIc3LkhL*MlTpfpR~(` zmY7V@PBU~UG&^5&uK3)PP|WADnP8>zLP?eTZ0GP)!;sC5eW_S{dAk0SKi*pVzOx(U zZm+KMUx*E|+77(E!qZc(*v2etYv$$S-BZhF-ZV!`H@|A|_S*h?;o&ui2(PKBNO|mg zp}7~YPQ`AW>-EC+J&Vl&W8G(Ch$xS}Ti@2U&)DqsU7>sGus{fUp>c)Brvi^!*3GAb z`#;$>vh~B9c=>%@ikM9YdL>^Xov`>)qu}^L#yzKJt9HH4cIFrn_Q1|PFW$=D-{l5~ zG5tV+*XM`F;-}AMG3JwLr(VuChXlO4zUiD~Z+_(&*XFvDF5DIb`xfMHJ>*%`f=cy| zu**f%a89{@ThcqmoqNtI)L2hxlqqNW-A$Z`v-K=dAP|5j*TBy=K1cf?YEljYAaig cyWv&u{lW>@_jo+YNCsPITB8k5)HNgi7w21A9{>OV literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/warp2.au b/contrib/vtwmrc/sounds/warp2.au new file mode 100644 index 0000000000000000000000000000000000000000..c03b69d09631b120326bc0c8e0791f4b42b9a379 GIT binary patch literal 20942 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 CSQbS9 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/warp3.au b/contrib/vtwmrc/sounds/warp3.au new file mode 100644 index 0000000000000000000000000000000000000000..f2db0351eb3101b25880f58c45559bd7d6a3d1de GIT binary patch literal 7979 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/whoosh2.wav b/contrib/vtwmrc/sounds/whoosh2.wav new file mode 100644 index 0000000000000000000000000000000000000000..1f6d278f0bc000a846e8b9d636c6b3cece2cb898 GIT binary patch literal 25756 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%0Dnu*SFE(_F}sr1|I8%YDU~ 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 U4F4L`tTnLjpuPk9j_XPP2QqAzeEbDS zqu(F=y2C##qjXE6l(t*Dl$5gFDNYhZ;4}O*a8bqUS`kbPMR64S0itjWYsH&}HIkq> zOpMeDMNxt&!idN!%}XW)<5Hv0wq2q@ozw&yCA5^9GMz+JOJP7Lp|YvCu^r55LL?VP zhqjBs7?dDG5aD%I!(v?UvS<`WiEDc?c26wVRArH8dC^G51dS3{h#0o1DQIs%l4?DI zg%fIoQCv%w)^(|CnYdv@%3MXUDQf0=s%(;xqnZs(sMu7<-DJzaj`N#x)aN;`Mm?{( zAtzyi%7?XQh1#&ZQOvTcyI}W#e>@xaeY0ltSemL%cYE&H&)ui-hnu5a+pKKuZE`xv z?B2eIvOZOQ%0UVyZnHj-@bRAR|^{5tPkaV=~`p|;bJ8yk@emA+&$ho!0BY3 z*kfDQiy|0x_J=lBW2d{*F%OsbN#}@Po?SOsEI(f56gOhk;Ls!|2Rq-}^71C`p5#Bj zKR?=W*O%9%v;FOXe_b3s*}Ho4Dc;!&-@m*Hp6=ZL_*!glN6RT1KiezU=)?|-D+VFY zZa>^Hdg}R|=k@}8-aB?ryWMA_i;o}Ay}|Ng6Zg=={l!Cg(6KuSMGi$?Sxu*nMlwDB zWqtg7f45strnmmnzdqi_i`i0na(QtZy4}(2?W;G%H-G$#c>VG{J>358`(7OQFZS`( z>$jJkuePTD{pTzG;>mY=qi}Pbb+)$lr>nzn56<5#pKpoR|NbRwo`x`^}e6>UW=ZzW(F4>vu1ISndA#>(iI- z)^jT?t;zlF!Q*9q&9gl!ve)l^`RV-U%dPD_H9Nb`zOP<=x2^v$_*00YqrJ#E=&QTx z>ink^(l5-*9ri zmM?mK6@H+lT;^)Fm^C%hLXx_y8tjI+T+o14o1zwxH8@RBOon~GA0mO-?d@e6`j*|b z(d=SH`X{zKSHa#;eAp&fzhYWE5}ack71b zck7CktF#g-@Nstm@)y8m`^Vz_hK=xDH@}a zF@oLLS5gQj8|Y|B(C_p*-jD=X*AJ{(-_LRm?b9Q%PHBSp>R~d=p?lGa60(?QI5i5f^tE}8-&#oKIH;O@b+?(++^-RBRH35CtX3+48KDGsR|T_% zAsunAsn(Q*z9D`_lph5{LRW!^Ocl_<=4z3nbT*mQi+P>}PIPMZ;<8fRBPR&y5EnEn zHg%;NRZe(GV*|N~r5c|MM#tTQKyEn8=66?jt5wNhE_tJ&GqOAns-E*YPs===!#Gk2 ziQFWL+`-sDBq%mKub2@C3xZ=Jn}&v75W>j76#Q&7Q)OBTq$PHS!+|wCIUOKL8*Q+Q zo6Ry!v-$L4k--Flk>wuuj(WD8cnC2W6HT?+%qI^I=`wF9f?0>H{>Y6IXK*rf0*r}h zYF0L7nH9xX@)&D+QI$xFQV3WI_yv0UQxktyb%_X>{n>USv!X zdgIWwPfiBI*ffn0MLK_&&I=Rt4v$U-?l=g8gspO}n$>JNORKuvz{KT-gl=FtzVD7~ z7@M4nA}@`A`NcKzT*q-82sDmitV#}ne9v>nR)1i*5g}~{$nqT8UtKT(0}tQ|rZkC@7CZZ0SG}5C6Vt~;~>UBcVi=kQmk$S)dI}IA(jo-7|BLT(t;qZ;SI+K69Nv32G9@_ z3K9Ys36P0tlWoG#@d7^#JlBWH7XX`dt5Het10WP3Msjeh6{z7m0Y^D7$%+9Q(kKF_ zd@oL*PT-;f@ZuccOH+XlTEWK{L350ufy7}900$%hb^;kCkzgJ?X$k6}u|ipa9(WW6 z(xaDc(0Wy<@B+vjs8CVT}0NWsI z4Tly7p0wBy(i#LojG_=C)51fr12PE8TYEGDffOO5;0@3jZ+9VurWm40+vou}1O8T0 ztF=u&q(XyP070pNXhRm05UTIQsDMPZ;c6K_ lbNxmHDjaV8Y8QwHb?pv+`ZKQrf$bZF3|QNGZAlRF{{t_>ZVLba literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/sounds/whoosh5.au b/contrib/vtwmrc/sounds/whoosh5.au new file mode 100644 index 0000000000000000000000000000000000000000..6c2d9d81a8d732e8115646296657ff34472a81cf GIT binary patch literal 3973 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 literal 0 HcmV?d00001 diff --git a/contrib/vtwmrc/vtwmrc-95ish b/contrib/vtwmrc/vtwmrc-95ish new file mode 100644 index 0000000..23c2356 --- /dev/null +++ b/contrib/vtwmrc/vtwmrc-95ish @@ -0,0 +1,274 @@ + +# +# DESCRIPTION FILE FOR vtwm - $(HOME)/vtwm/vtwmrc-95ish +# +# PRE-PROCESSED BY vtwm-5.4.6 USING m4 +# + +# +# m4 Variables +# + +define(WMname, `95ish') + +# Border width, autopan border width, desktop and door bevel widths... +define(WMborder, 5) define(WMpanborder, 5) +define(WMdesktopbevel, 1) define(WMdoorbevel, 1) +# Title heights (must be set manually for VTWM windows and applets)... +define(WMdesktoptitle, 0) define(WMdoortitle, 0) +define(WMiconmgrtitle, 0) define(WMapplettitle, 0) + +# +# Boolean Variables +# + +# Read in the variables file... +include(HOME/vtwm/vtwmrc-bools) + +ShallowReliefWindowButton + +NoBorderDecorations + +# +# Parametered Variables +# + +# Read in the variables file... +include(HOME/vtwm/vtwmrc-parms) + +# See also 'Lists' below... +IconManagerGeometry "+5+5" 1 + +RealScreenBorderWidth 0 + +# Gap between frame and titlebar font (titlebar changes) +FramePadding 2 +# Gap between FramePadding and buttons (buttons change) +ButtonIndent 0 +# Gap between titlebar elements +TitlePadding 2 +# Button border width (TitleForeground color) +TitleButtonBorderWidth 0 + +ClearBevelContrast 60 +DarkBevelContrast 60 + +BorderBevelWidth 1 +ButtonBevelWidth 0 +DoorBevelWidth WMdoorbevel +IconBevelWidth 1 +IconManagerBevelWidth 1 +InfoBevelWidth 1 +MenuBevelWidth 1 +TitleBevelWidth 0 +VirtualDesktopBevelWidth WMdesktopbevel + +UnknownIcon "xlogo32" + +TitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +ResizeFont "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" +MenuFont "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" +MenuTitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +IconFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +InfoFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +IconManagerFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +DoorFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +#VirtualDesktopFont "-adobe-helvetica-medium-r-normal--*-75-*-*-*-*-*-*" + +# +# Functions and Bindings +# + +# Read in the bindings file... +include(HOME/vtwm/vtwmrc-binds) + +LeftTitleButton "win95_menu.xpm" = f.menu "ArrangeMenu" +RightTitleButton "win95_minimize.xpm" = f.iconify +RightTitleButton "win95_zoom.xpm" = f.fullzoom +RightTitleButton "win95_unzoom.xpm" = f.resize +#RightTitleButton "win95_close.xpm" = f.menu "CloseMenu" + +Function "decorate-virtual" +{ + f.exec "nexpm -vtwm -in HOME/vtwm/images/djhjr.xpm &" +} + +Function "clear-virtual" +{ + f.exec "nexpm -vtwm -solid gray67 &" +} + +# +# Lists +# + +# Read in the sound file... +include(ifelse(SOUND, `Yes', `HOME/vtwm/vtwmrc-sound')) + +# Read in the lists file... +include(HOME/vtwm/vtwmrc-lists) + +# Check 'BorderColor', as that's the highlight color... +NoHighlight + +#NoTitleHighlight + +#SqueezeTitle +#DontSqueezeTitle {} + +Pixmaps +{ + TitleHighlight "eyesline.xpm" +# TitleHighlight "byzantine.xpm" +# VirtualBackgroundPixmap "djhjr.xpm" + MenuIconPixmap "win95_rarrow.xpm" +} + +# Box-stock Background is, of course, "maroon" +# Box-stock Foreground and IconBorderColor is "gray85" +# Box-stock MenuTitleBackground and BorderColor is "gray70" +Color +{ + DefaultBackground "gray67" + DefaultForeground "black" + MenuBackground "gray67" + MenuForeground "black" + MenuTitleBackground "gray67" + MenuTitleForeground "black" + RealScreenBackground "gray57" + RealScreenForeground "black" + VirtualBackground "gray67" + VirtualForeground "black" + BorderColor "gray67" + BorderTileBackground "gray67" + BorderTileForeground "gray67" + TitleBackground "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + TitleForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } + IconBackground "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + IconForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } + IconBorderColor "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + IconManagerBackground "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + IconManagerForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } + IconManagerHighlight "gray90" + DoorBackground "gray67" + DoorForeground "black" + DesktopDisplayBackground "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + DesktopDisplayForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } +} + +# +# Menus +# + +# Read in the menus file... +include(HOME/vtwm/vtwmrc-menus) + +menu "CloseMenu" +{ + " Close " f.title + "Delete" f.delete + "Destroy" f.destroy +} + diff --git a/contrib/vtwmrc/vtwmrc-MWMish b/contrib/vtwmrc/vtwmrc-MWMish new file mode 100644 index 0000000..aacb17c --- /dev/null +++ b/contrib/vtwmrc/vtwmrc-MWMish @@ -0,0 +1,237 @@ + +# +# DESCRIPTION FILE FOR vtwm - $(HOME)/vtwm/vtwmrc-MWMish +# +# PRE-PROCESSED BY vtwm-5.4.6 USING m4 +# + +# +# m4 Variables +# + +define(WMname, `MWMish') + +# Border width, autopan border width, desktop and door bevel widths... +define(WMborder, 5) define(WMpanborder, 5) +define(WMdesktopbevel, 1) define(WMdoorbevel, 1) +# Title heights (must be set manually for VTWM windows and applets)... +define(WMdesktoptitle, 0) define(WMdoortitle, 0) +define(WMiconmgrtitle, 0) define(WMapplettitle, 0) + +# +# Boolean Variables +# + +# Read in the variables file... +include(HOME/vtwm/vtwmrc-bools) + +ShallowReliefWindowButton + +ButtonColorIsFrame + +# +# Parametered Variables +# + +# Read in the variables file... +include(HOME/vtwm/vtwmrc-parms) + +# See also 'Lists' below... +IconManagerGeometry "+5+5" 1 + +RealScreenBorderWidth 0 + +# Gap between frame and titlebar font (titlebar changes) +FramePadding 2 +# Gap between FramePadding and buttons (buttons change) +ButtonIndent -2 +# Gap between titlebar elements +TitlePadding 0 +# Button border width (TitleForeground color) +TitleButtonBorderWidth 0 + +ClearBevelContrast 40 +DarkBevelContrast 40 + +BorderBevelWidth 2 +ButtonBevelWidth 1 +DoorBevelWidth WMdoorbevel +IconBevelWidth 2 +IconManagerBevelWidth 1 +InfoBevelWidth 2 +MenuBevelWidth 2 +TitleBevelWidth 1 +VirtualDesktopBevelWidth WMdesktopbevel + +UnknownIcon "xlogo32" + +TitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +ResizeFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +MenuFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +MenuTitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +IconFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +InfoFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +IconManagerFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +DoorFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +#VirtualDesktopFont "-adobe-helvetica-medium-r-normal--*-75-*-*-*-*-*-*" + +# +# Functions and Bindings +# + +# Read in the bindings file... +include(HOME/vtwm/vtwmrc-binds) + +# These are nice built-in 3D buttons... +LeftTitleButton ":xpm:darrow" = f.menu "ArrangeMenu" +RightTitleButton ":xpm:dot" = f.iconify +RightTitleButton ":xpm:resize" = f.resize + +Function "decorate-virtual" +{ + f.exec "nexpm -vtwm -in HOME/vtwm/images/djhjr.xpm &" +} + +Function "clear-virtual" +{ + f.exec "nexpm -vtwm -solid gray60 &" +} + +# +# Lists +# + +# Read in the sound file... +include(ifelse(SOUND, `Yes', `HOME/vtwm/vtwmrc-sound')) + +# Read in the lists file... +include(HOME/vtwm/vtwmrc-lists) + +# Check 'BorderColor', as that's the highlight color... +NoHighlight + +#NoTitleHighlight + +SqueezeTitle +#DontSqueezeTitle {} + +Pixmaps +{ +# TitleHighlight "eyesline.xpm" +# TitleHighlight "byzantine.xpm" + TitleHighlight ":xpm:sunkenlines" +# VirtualBackgroundPixmap "djhjr.xpm" + MenuIconPixmap ":xpm:rarrow" + IconManagerPixmap ":xpm:zoom" +} + +# Box-stock Background is, of course, "maroon" +# Box-stock Foreground and IconBorderColor is "gray85" +# Box-stock MenuTitleBackground and BorderColor is "gray70" +Color +{ + DefaultBackground "gray60" + DefaultForeground "gray90" + MenuBackground "gray60" + MenuForeground "gray90" + MenuTitleBackground "gray60" + MenuTitleForeground "gray90" + RealScreenBackground "gray50" + RealScreenForeground "black" + VirtualBackground "gray60" + VirtualForeground "black" + BorderColor "gray75" + BorderTileBackground "gray60" + BorderTileForeground "gray60" + TitleBackground "DeepSkyBlue4" + { + "VTWM*" "gray60" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray60" + "xcb" "gray60" + "*clock" "gray60" + "xload" "gray60" + "as*" "gray60" + } + TitleForeground "gray90" + IconBackground "DeepSkyBlue4" + { + "VTWM*" "gray60" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray60" + "xcb" "gray60" + "*clock" "gray60" + "xload" "gray60" + "as*" "gray60" + } + IconForeground "gray90" + IconBorderColor "gray75" +# IconBorderColor "DeepSkyBlue4" +# { +# "VTWM*" "gray60" +# "XTerm" "SeaGreen" +# "Xqsh" "maroon" +# "ssh:*" "maroon" +# "telnet:*" "maroon" +# "rlogin:*" "maroon" +# "*ftp:*" "maroon" +# "xbiff*" "gray60" +# "xcb" "gray60" +# "*clock" "gray60" +# "xload" "gray60" +# "as*" "gray60" +# } + IconManagerBackground "DeepSkyBlue4" + { + "VTWM*" "gray60" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray60" + "xcb" "gray60" + "*clock" "gray60" + "xload" "gray60" + "as*" "gray60" + } + IconManagerForeground "gray90" + IconManagerHighlight "gray90" + DoorBackground "gray60" + DoorForeground "gray90" + DesktopDisplayBackground "DeepSkyBlue4" + { + "VTWM*" "gray60" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray60" + "xcb" "gray60" + "*clock" "gray60" + "xload" "gray60" + "as*" "gray60" + } + DesktopDisplayForeground "gray90" +} + +# +# Menus +# + +# Read in the menus file... +include(HOME/vtwm/vtwmrc-menus) + diff --git a/contrib/vtwmrc/vtwmrc-NoBorder b/contrib/vtwmrc/vtwmrc-NoBorder new file mode 100644 index 0000000..b1a424b --- /dev/null +++ b/contrib/vtwmrc/vtwmrc-NoBorder @@ -0,0 +1,272 @@ + +# +# DESCRIPTION FILE FOR vtwm - $(HOME)/vtwm/vtwmrc-NoBorder +# +# PRE-PROCESSED BY vtwm-5.4.6 USING m4 +# + +# +# m4 Variables +# + +define(WMname, `NoBorder') + +# Border width, autopan border width, desktop and door bevel widths... +define(WMborder, 0) define(WMpanborder, 5) +define(WMdesktopbevel, 1) define(WMdoorbevel, 1) +# Title heights (must be set manually for VTWM windows and applets)... +define(WMdesktoptitle, 0) define(WMdoortitle, 0) +define(WMiconmgrtitle, 0) define(WMapplettitle, 0) + +# +# Boolean Variables +# + +# Read in the variables file... +include(HOME/vtwm/vtwmrc-bools) + +DecorateTransients + +NoIconManagerHighlight + +ShallowReliefWindowButton + +ButtonColorIsFrame + +# +# Parametered Variables +# + +# Read in the variables file... +include(HOME/vtwm/vtwmrc-parms) + +# See also 'Lists' below... +IconManagerGeometry "+5+5" 1 + +RealScreenBorderWidth 0 + +# Gap between frame and titlebar titlebar font (titlebar changes) +FramePadding 3 +# Gap between FramePadding and buttons (buttons change) +ButtonIndent -1 +# Gap between titlebar elements +TitlePadding 2 +# Button border width (TitleForeground color) +TitleButtonBorderWidth 0 + +ClearBevelContrast 50 +DarkBevelContrast 60 + +BorderBevelWidth 0 +ButtonBevelWidth 1 +DoorBevelWidth WMdoorbevel +IconBevelWidth 1 +IconManagerBevelWidth 1 +InfoBevelWidth 1 +MenuBevelWidth 1 +TitleBevelWidth 1 +VirtualDesktopBevelWidth WMdesktopbevel + +UnknownIcon "xlogo32" + +TitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +ResizeFont "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" +MenuFont "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" +MenuTitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +IconFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +InfoFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +IconManagerFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +DoorFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +#VirtualDesktopFont "-adobe-helvetica-medium-r-normal--*-75-*-*-*-*-*-*" + +# +# Functions and Bindings +# + +# Read in the bindings file... +include(HOME/vtwm/vtwmrc-binds) + +# These are nice built-in 3D buttons... +LeftTitleButton ":xpm:darrow" = f.menu "ArrangeMenu" +RightTitleButton ":xpm:dot" = f.iconify +RightTitleButton ":xpm:resize" = f.resize + +Function "decorate-virtual" +{ + f.exec "nexpm -vtwm -in HOME/vtwm/images/djhjr.xpm &" +} + +Function "clear-virtual" +{ + f.exec "nexpm -vtwm -solid gray67 &" +} + +# +# Lists +# + +# Read in the sound file... +include(ifelse(SOUND, `Yes', `HOME/vtwm/vtwmrc-sound')) + +# Read in the lists file... +include(HOME/vtwm/vtwmrc-lists) + +# Check 'BorderColor', as that's the highlight color... +NoHighlight + +#NoTitleHighlight + +#SqueezeTitle +#DontSqueezeTitle {} + +Pixmaps +{ +# TitleHighlight "eyesline.xpm" +# TitleHighlight "byzantine.xpm" + TitleHighlight ":xpm:raisedlines" +# VirtualBackgroundPixmap "djhjr.xpm" + MenuIconPixmap ":xpm:rarrow" + IconManagerPixmap ":xpm:zoom" +} + +# Box-stock Background is, of course, "maroon" +# Box-stock Foreground and IconBorderColor is "gray85" +# Box-stock MenuTitleBackground and BorderColor is "gray70" +Color +{ + DefaultBackground "gray73" + DefaultForeground "black" + MenuBackground "gray73" + MenuForeground "black" + MenuTitleBackground "gray73" + MenuTitleForeground "black" + RealScreenBackground "gray57" + RealScreenForeground "black" + VirtualBackground "gray67" + VirtualForeground "black" + BorderColor "gray73" + BorderTileBackground "gray67" + BorderTileForeground "gray67" + TitleBackground "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + TitleForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } + IconBackground "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + IconForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } + IconBorderColor "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + IconManagerBackground "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + IconManagerForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } + IconManagerHighlight "gray90" + DoorBackground "gray67" + DoorForeground "black" + DesktopDisplayBackground "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + DesktopDisplayForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } +} + +# +# Menus +# + +# Read in the menus file... +include(HOME/vtwm/vtwmrc-menus) + diff --git a/contrib/vtwmrc/vtwmrc-PWMish b/contrib/vtwmrc/vtwmrc-PWMish new file mode 100644 index 0000000..7d2c8f7 --- /dev/null +++ b/contrib/vtwmrc/vtwmrc-PWMish @@ -0,0 +1,263 @@ + +# +# DESCRIPTION FILE FOR vtwm - $(HOME)/vtwm/vtwmrc-PWMish +# +# PRE-PROCESSED BY vtwm-5.4.6 USING m4 +# + +# +# m4 Variables +# + +define(WMname, `PWMish') + +# Border width, autopan border width, desktop and door bevel widths... +define(WMborder, 5) define(WMpanborder, 5) +define(WMdesktopbevel, 1) define(WMdoorbevel, 1) +# Title heights (must be set manually for VTWM windows and applets)... +define(WMdesktoptitle, 0) define(WMdoortitle, 0) +define(WMiconmgrtitle, 0) define(WMapplettitle, 0) + +# +# Boolean Variables +# + +# Read in the variables file... +include(HOME/vtwm/vtwmrc-bools) + +NoBorderDecorations + +# +# Parametered Variables +# + +# Read in the variables file... +include(HOME/vtwm/vtwmrc-parms) + +# See also 'Lists' below... +IconManagerGeometry "+5+5" 1 + +RealScreenBorderWidth 0 + +# Gap between frame and titlebar font (titlebar changes) +FramePadding 4 +# Gap between FramePadding and buttons (buttons change) +ButtonIndent -2 +# Gap between titlebar elements +TitlePadding 3 +# Button border width (TitleForeground color) +TitleButtonBorderWidth 0 + +ClearBevelContrast 40 +DarkBevelContrast 40 + +BorderBevelWidth 1 +ButtonBevelWidth 0 +DoorBevelWidth WMdoorbevel +IconBevelWidth 1 +IconManagerBevelWidth 1 +InfoBevelWidth 1 +MenuBevelWidth 1 +TitleBevelWidth 1 +VirtualDesktopBevelWidth WMdesktopbevel + +UnknownIcon "xlogo32" + +TitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +ResizeFont "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" +MenuFont "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" +MenuTitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +IconFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +InfoFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +IconManagerFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +DoorFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +#VirtualDesktopFont "-adobe-helvetica-medium-r-normal--*-75-*-*-*-*-*-*" + +# +# Functions and Bindings +# + +# Read in the bindings file... +include(HOME/vtwm/vtwmrc-binds) + +LeftTitleButton "photon_menu.xpm" = f.menu "ArrangeMenu" +RightTitleButton "photon_minimize.xpm" = f.iconify +RightTitleButton "photon_maximize.xpm" = f.fullzoom + +Function "decorate-virtual" +{ + f.exec "nexpm -vtwm -in HOME/vtwm/images/djhjr.xpm &" +} + +Function "clear-virtual" +{ + f.exec "nexpm -vtwm -solid gray75 &" +} + +# +# Lists +# + +# Read in the sound file... +include(ifelse(SOUND, `Yes', `HOME/vtwm/vtwmrc-sound')) + +# Read in the lists file... +include(HOME/vtwm/vtwmrc-lists) + +# Check 'BorderColor', as that's the highlight color... +#NoHighlight + +NoTitleHighlight + +#SqueezeTitle +DontSqueezeTitle {} + +Pixmaps +{ +# TitleHighlight "eyesline.xpm" +# TitleHighlight "byzantine.xpm" +# VirtualBackgroundPixmap "djhjr.xpm" + MenuIconPixmap "photon_rarrow.xpm" +} + +# Box-stock Background is, of course, "maroon" +# Box-stock Foreground and IconBorderColor is "gray85" +# Box-stock MenuTitleBackground and BorderColor is "gray70" +Color +{ + DefaultBackground "gray75" + DefaultForeground "black" + MenuBackground "gray75" + MenuForeground "black" + MenuTitleBackground "gray75" + MenuTitleForeground "black" + RealScreenBackground "gray65" + RealScreenForeground "black" + VirtualBackground "gray75" + VirtualForeground "black" + BorderColor "gray75" + BorderTileBackground "gray60" + BorderTileForeground "gray60" + TitleBackground "DeepSkyBlue4" + { + "VTWM*" "gray75" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray75" + "xcb" "gray75" + "*clock" "gray75" + "xload" "gray75" + "as*" "gray75" + } + TitleForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } + IconBackground "DeepSkyBlue4" + { + "VTWM*" "gray75" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray75" + "xcb" "gray75" + "*clock" "gray75" + "xload" "gray75" + "as*" "gray75" + } + IconForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } + IconBorderColor "DeepSkyBlue4" + { + "VTWM*" "gray75" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray75" + "xcb" "gray75" + "*clock" "gray75" + "xload" "gray75" + "as*" "gray75" + } + IconManagerBackground "DeepSkyBlue4" + { + "VTWM*" "gray75" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray75" + "xcb" "gray75" + "*clock" "gray75" + "xload" "gray75" + "as*" "gray75" + } + IconManagerForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } + IconManagerHighlight "gray90" + DoorBackground "gray75" + DoorForeground "black" + DesktopDisplayBackground "DeepSkyBlue4" + { + "VTWM*" "gray75" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray75" + "xcb" "gray75" + "*clock" "gray75" + "xload" "gray75" + "as*" "gray75" + } + DesktopDisplayForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } +} + +# +# Menus +# + +# Read in the menus file... +include(HOME/vtwm/vtwmrc-menus) + diff --git a/contrib/vtwmrc/vtwmrc-TWM3d b/contrib/vtwmrc/vtwmrc-TWM3d new file mode 100644 index 0000000..c25fc23 --- /dev/null +++ b/contrib/vtwmrc/vtwmrc-TWM3d @@ -0,0 +1,270 @@ + +# +# DESCRIPTION FILE FOR vtwm - $(HOME)/vtwm/vtwmrc-TWM3d +# +# PRE-PROCESSED BY vtwm-5.4.6 USING m4 +# + +# +# m4 Variables +# + +define(WMname, `TWM3d') + +# Border width, autopan border width, desktop and door bevel widths... +define(WMborder, 4) define(WMpanborder, 5) +define(WMdesktopbevel, 1) define(WMdoorbevel, 1) +# Title heights (must be set manually for VTWM windows and applets)... +define(WMdesktoptitle, 0) define(WMdoortitle, 0) +define(WMiconmgrtitle, 0) define(WMapplettitle, 0) + +# +# Boolean Variables +# + +# Read in the variables file... +include(HOME/vtwm/vtwmrc-bools) + +NoBorderDecorations + +ShallowReliefWindowButton + +ButtonColorIsFrame + +# +# Parametered Variables +# + +# Read in the variables file... +include(HOME/vtwm/vtwmrc-parms) + +# See also 'Lists' below... +IconManagerGeometry "+5+5" 1 + +RealScreenBorderWidth 0 + +# Gap between frame and titlebar titlebar font (titlebar changes) +FramePadding 2 +# Gap between FramePadding and buttons (buttons change) +ButtonIndent -1 +# Gap between titlebar elements +TitlePadding 2 +# Button border width (TitleForeground color) +TitleButtonBorderWidth 0 + +ClearBevelContrast 50 +DarkBevelContrast 60 + +BorderBevelWidth 1 +ButtonBevelWidth 1 +DoorBevelWidth WMdoorbevel +IconBevelWidth 1 +IconManagerBevelWidth 1 +InfoBevelWidth 1 +MenuBevelWidth 1 +TitleBevelWidth 0 +VirtualDesktopBevelWidth WMdesktopbevel + +UnknownIcon "xlogo32" + +TitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +ResizeFont "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" +MenuFont "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" +MenuTitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +IconFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +InfoFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +IconManagerFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +DoorFont "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" +#VirtualDesktopFont "-adobe-helvetica-medium-r-normal--*-75-*-*-*-*-*-*" + +# +# Functions and Bindings +# + +# Read in the bindings file... +include(HOME/vtwm/vtwmrc-binds) + +# These are nice built-in 3D buttons... +LeftTitleButton ":xpm:bar" = f.menu "ArrangeMenu" +RightTitleButton ":xpm:dot" = f.iconify +RightTitleButton ":xpm:resize" = f.resize + +Function "decorate-virtual" +{ + f.exec "nexpm -vtwm -in HOME/vtwm/images/djhjr.xpm &" +} + +Function "clear-virtual" +{ + f.exec "nexpm -vtwm -solid gray67 &" +} + +# +# Lists +# + +# Read in the sound file... +include(ifelse(SOUND, `Yes', `HOME/vtwm/vtwmrc-sound')) + +# Read in the lists file... +include(HOME/vtwm/vtwmrc-lists) + +# Check 'BorderColor', as that's the highlight color... +NoHighlight + +#NoTitleHighlight + +SqueezeTitle +#DontSqueezeTitle {} + +Pixmaps +{ +# TitleHighlight "eyesline.xpm" +# TitleHighlight "byzantine.xpm" + TitleHighlight ":xpm:raisedlines" +# VirtualBackgroundPixmap "djhjr.xpm" + MenuIconPixmap ":xpm:bar" + IconManagerPixmap ":xpm:zoom" +} + +# Box-stock Background is, of course, "maroon" +# Box-stock Foreground and IconBorderColor is "gray85" +# Box-stock MenuTitleBackground and BorderColor is "gray70" +Color +{ + DefaultBackground "gray73" + DefaultForeground "black" + MenuBackground "gray73" + MenuForeground "black" + MenuTitleBackground "gray73" + MenuTitleForeground "black" + RealScreenBackground "gray57" + RealScreenForeground "black" + VirtualBackground "gray67" + VirtualForeground "black" + BorderColor "gray73" + BorderTileBackground "gray67" + BorderTileForeground "gray67" + TitleBackground "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + TitleForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } + IconBackground "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + IconForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } + IconBorderColor "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + IconManagerBackground "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + IconManagerForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } + IconManagerHighlight "gray90" + DoorBackground "gray67" + DoorForeground "black" + DesktopDisplayBackground "DeepSkyBlue4" + { + "VTWM*" "gray67" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray67" + "xcb" "gray67" + "*clock" "gray67" + "xload" "gray67" + "as*" "gray67" + } + DesktopDisplayForeground "gray90" + { + "VTWM*" "black" + "xbiff*" "black" + "xcb" "black" + "*clock" "black" + "xload" "black" + "as*" "black" + } +} + +# +# Menus +# + +# Read in the menus file... +include(HOME/vtwm/vtwmrc-menus) + diff --git a/contrib/vtwmrc/vtwmrc-TWMish b/contrib/vtwmrc/vtwmrc-TWMish new file mode 100644 index 0000000..b7eaf0e --- /dev/null +++ b/contrib/vtwmrc/vtwmrc-TWMish @@ -0,0 +1,232 @@ + +# +# DESCRIPTION FILE FOR vtwm - $(HOME)/vtwm/vtwmrc-TWMish +# +# PRE-PROCESSED BY vtwm-5.4.6 USING m4 +# + +# +# m4 Variables +# + +define(WMname, `TWMish') + +# Border width, autopan border width, desktop and door bevel widths... +define(WMborder, 2) define(WMpanborder, 5) +define(WMdesktopbevel, 0) define(WMdoorbevel, 0) +# Title heights (must be set manually for VTWM windows and applets)... +define(WMdesktoptitle, 0) define(WMdoortitle, 0) +define(WMiconmgrtitle, 0) define(WMapplettitle, 0) + +# +# Boolean Variables +# + +# Read in the variables file... +include(HOME/vtwm/vtwmrc-bools) + +DecorateTransients + +# +# Parametered Variables +# + +# Read in the variables file... +include(HOME/vtwm/vtwmrc-parms) + +# See also 'Lists' below... +IconManagerGeometry "+5+5" 1 + +RealScreenBorderWidth 0 + +# Gap between frame and titlebar font (titlebar changes) +FramePadding 2 +# Gap between FramePadding and buttons (buttons change) +ButtonIndent 0 +# Gap between titlebar elements +TitlePadding 5 +# Button border width (TitleForeground color) +TitleButtonBorderWidth 1 + +ClearBevelContrast 40 +DarkBevelContrast 40 + +BorderBevelWidth 0 +ButtonBevelWidth 0 +DoorBevelWidth WMdoorbevel +IconBevelWidth 0 +IconManagerBevelWidth 0 +InfoBevelWidth 0 +MenuBevelWidth 0 +TitleBevelWidth 0 +VirtualDesktopBevelWidth WMdesktopbevel + +UnknownIcon "xlogo32" + +TitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +ResizeFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +MenuFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +MenuTitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +IconFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +InfoFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +IconManagerFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +DoorFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +#VirtualDesktopFont "-adobe-helvetica-medium-r-normal--*-75-*-*-*-*-*-*" + +# +# Functions and Bindings +# + +# Read in the bindings file... +include(HOME/vtwm/vtwmrc-binds) + +# These are the box-stock flat buttons... +LeftTitleButton ":darrow" = f.menu "ArrangeMenu" +RightTitleButton ":dot" = f.iconify +RightTitleButton ":resize" = f.resize + +Function "decorate-virtual" +{ + f.exec "nexpm -vtwm -in HOME/vtwm/images/djhjr.xpm &" +} + +Function "clear-virtual" +{ + f.exec "nexpm -vtwm -solid gray60 &" +} + +# +# Lists +# + +# Read in the sound file... +include(ifelse(SOUND, `Yes', `HOME/vtwm/vtwmrc-sound')) + +# Read in the lists file... +include(HOME/vtwm/vtwmrc-lists) + +# Check 'BorderColor', as that's the highlight color... +#NoHighlight + +#NoTitleHighlight + +SqueezeTitle +#DontSqueezeTitle {} + +Pixmaps +{ +# TitleHighlight "dot1x3.xbm" + TitleHighlight "hlines3" + MenuIconPixmap ":rarrow" +} + +# Box-stock Background is, of course, "maroon" +# Box-stock Foreground and IconBorderColor is "gray85" +# Box-stock MenuTitleBackground and BorderColor is "gray70" +Color +{ + DefaultBackground "gray60" + DefaultForeground "gray90" + MenuBackground "gray60" + MenuForeground "gray90" + MenuTitleBackground "gray60" + MenuTitleForeground "gray90" + RealScreenBackground "gray50" + RealScreenForeground "black" + VirtualBackground "gray60" + VirtualForeground "black" + BorderColor "gray75" + BorderTileBackground "gray60" + BorderTileForeground "gray60" + TitleBackground "DeepSkyBlue4" + { + "VTWM*" "gray60" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray60" + "xcb" "gray60" + "*clock" "gray60" + "xload" "gray60" + "as*" "gray60" + } + TitleForeground "gray90" + IconBackground "DeepSkyBlue4" + { + "VTWM*" "gray60" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray60" + "xcb" "gray60" + "*clock" "gray60" + "xload" "gray60" + "as*" "gray60" + } + IconForeground "gray90" + IconBorderColor "gray75" +# IconBorderColor "DeepSkyBlue4" +# { +# "VTWM*" "gray60" +# "XTerm" "SeaGreen" +# "Xqsh" "maroon" +# "ssh:*" "maroon" +# "telnet:*" "maroon" +# "rlogin:*" "maroon" +# "*ftp:*" "maroon" +# "xbiff*" "gray60" +# "xcb" "gray60" +# "*clock" "gray60" +# "xload" "gray60" +# "as*" "gray60" +# } + IconManagerBackground "DeepSkyBlue4" + { + "VTWM*" "gray60" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray60" + "xcb" "gray60" + "*clock" "gray60" + "xload" "gray60" + "as*" "gray60" + } + IconManagerForeground "gray90" + IconManagerHighlight "gray75" + DoorBackground "gray60" + DoorForeground "gray90" + DesktopDisplayBackground "DeepSkyBlue4" + { + "VTWM*" "gray60" + "XTerm" "SeaGreen" + "Xqsh" "maroon" + "ssh:*" "maroon" + "telnet:*" "maroon" + "rlogin:*" "maroon" + "*ftp:*" "maroon" + "xbiff*" "gray60" + "xcb" "gray60" + "*clock" "gray60" + "xload" "gray60" + "as*" "gray60" + } + DesktopDisplayForeground "gray90" +} + +# +# Menus +# + +# Read in the menus file... +include(HOME/vtwm/vtwmrc-menus) + diff --git a/contrib/vtwmrc/vtwmrc-binds b/contrib/vtwmrc/vtwmrc-binds new file mode 100644 index 0000000..95bb955 --- /dev/null +++ b/contrib/vtwmrc/vtwmrc-binds @@ -0,0 +1,120 @@ + +# +# DESCRIPTION FILE FOR vtwm - $(HOME)/vtwm/vtwmrc-binds +# +# PRE-PROCESSED BY vtwm-5.4.6 USING m4 +# + +# +# Functions and Bindings +# + +# See $(HOME)/.xinitrc... +#Function "VTWM Profile" +#{ +# f.exec "startxclients &" +#} + +Function "move-or-raise" +{ + f.move +# These two set up a click-to-type focus policy +# (omitting the first allows it to be "togglable")... +# f.unfocus +# f.focus + f.deltastop + f.raise +} + +Function "move-or-iconify" +{ + f.move + f.deltastop + f.iconify +} + +# This is for warping from the icon manager... +Function "deiconify-and-warp" +{ + f.deiconify + f.warp +} + +# This is for warping from the virtual desktop... +Function "move-or-warp" +{ + f.playsound "HOME/vtwm/sounds/whoosh4.au" + f.move + f.deltastop + f.warp +} + +# This is for warping from the virtual desktop... +Function "resize-or-warp" +{ + f.playsound "HOME/vtwm/sounds/whoosh4.au" + f.resize + f.deltastop + f.warp +} + +Button1 = : root : f.version +Button3 = : root : f.menu "XWindowsMenu" + +Button1 = : title : f.function "move-or-raise" +Button2 = : title : f.resize +Button3 = : title : f.raiselower + +Button1 = : frame : f.function "move-or-raise" +Button2 = : frame : f.resize +Button3 = : frame : f.iconify + +Button1 = : icon : f.function "move-or-iconify" +Button3 = : icon : f.menu "ArrangeMenu" + +Button1 = : iconmgr : f.iconify +Button3 = : iconmgr : f.function "deiconify-and-warp" + +Button1 = : door : f.enterdoor +Button2 = : door : f.namedoor +Button3 = : door : f.deletedoor + +Button1 = : virtual | desktop : f.movescreen +Button2 = : desktop : f.function "move-or-warp" +Button3 = : desktop : f.function "resize-or-warp" +# If you've got nothing better to do with 'em... +#Button2 = : virtual | desktop : f.function "decorate-virtual" +#Button3 = : virtual | desktop : f.function "clear-virtual" + +"Up" = : iconmgr : f.backiconmgr +"Down" = : iconmgr : f.forwiconmgr +"Return" = : iconmgr : f.function "deiconify-and-warp" +"BackSpace" = : iconmgr : f.iconify + +"Return" = : door : f.enterdoor + +"Up" = : virtual | desktop : f.panup "100" +"Down" = : virtual | desktop : f.pandown "100" +"Left" = : virtual | desktop : f.panleft "100" +"Right" = : virtual | desktop : f.panright "100" + +"Meta_L" = c : all : f.warpring "prev" +"Control_R" = m : all : f.warpring "prev" +"Control_L" = m : all : f.warpring "next" +"Meta_R" = c : all : f.warpring "next" + +"Meta_L" = c : root : f.warpto "*Icon Manager" +"Control_R" = m : root : f.warpto "*Icon Manager" +"Control_L" = m : root : f.warpto "*Icon Manager" +"Meta_R" = c : root : f.warpto "*Icon Manager" + +"Shift_L" = c : all : f.warpclassprev "" +"Shift_R" = c : all : f.warpclassprev "" +"Control_L" = s : all : f.warpclassnext "" +"Control_R" = s : all : f.warpclassnext "" + +"Shift_L" = m : all : f.warptoiconmgr "" +"Shift_R" = m : all : f.warptoiconmgr "" +"Meta_L" = s : all : f.warptoiconmgr "" +"Meta_R" = s : all : f.warptoiconmgr "" + diff --git a/contrib/vtwmrc/vtwmrc-bools b/contrib/vtwmrc/vtwmrc-bools new file mode 100644 index 0000000..da15068 --- /dev/null +++ b/contrib/vtwmrc/vtwmrc-bools @@ -0,0 +1,53 @@ + +# +# DESCRIPTION FILE FOR vtwm - $(HOME)/vtwm/vtwmrc-bools +# +# PRE-PROCESSED BY vtwm-5.4.6 USING m4 +# + +# +# Boolean Variables +# + +RestartPreviousState +NoGrabServer + +RandomPlacement +#DeiconifyToScreen +StaticIconPositions +#WarpSnug +#WarpVisible +#WarpWindows +DontDeiconifyTransients + +# Left unset so class and ring warps ignore the iconified - +# see 'Functions and Bindings' below... +#WarpUnmapped + +NoCaseSensitive +NoIconManagerFocus +ShowIconManager +SortIconManager + +# see Zoom in 'Parametered'... +#PrettyZoom + +RightHandSidePulldownMenus +OldFashionedVtwmWindowsMenu +#StayUpOptionalMenus +#StayUpMenus + +SnapRealScreen +NaturalAutoPanBehavior +NotVirtualGeometries +FixManagedVirtualGeometries +FixTransientVirtualGeometries +VirtualReceivesMotionEvents +VirtualSendsMotionEvents + +# See 'Functions and Bindings' below... +#NoDefaultTitleButtons +#NoDefaultMouseOrKeyboardBindings +# Covers both of the above... +NoDefaults + diff --git a/contrib/vtwmrc/vtwmrc-lists b/contrib/vtwmrc/vtwmrc-lists new file mode 100644 index 0000000..365d640 --- /dev/null +++ b/contrib/vtwmrc/vtwmrc-lists @@ -0,0 +1,197 @@ + +# +# DESCRIPTION FILE FOR vtwm - $(HOME)/vtwm/vtwmrc-lists +# +# PRE-PROCESSED BY vtwm-5.4.6 USING m4 +# + +# +# Lists +# + +WindowRing +NoWindowRing +{ + "VTWM*" + "as*" +} + +IconifyByUnmapping + +WarpCursor + +#OpaqueMove +#NoOpaqueMove {} + +#OpaqueResize +#NoOpaqueResize {} + +UsePPosition "off" +{ + "MPlayer" "on" +} + +Cursors +{ + Button "arrow" +# Frame "arrow" + IconMgr "arrow" + Menu "arrow" + Title "arrow" +} + +# In addition to the default icon manager... +IconManagers +{ + "Xcoral*" "+5+405" 1 + "xv *" "+5+605" 1 +} + +NailedDown +{ + "VTWM*" + "xbiff*" + "xcb" + "*clock" + "xeyes" + "xload" + "xpostit" + "as*" +} + +IconManagerDontShow +{ + "VTWM*" +# "xbiff*" +# "xcb" +# "*clock" +# "xeyes" +# "xload" +# "xpostit" + "as*" +} + +DontShowInDisplay +{ + "VTWM*" + "xbiff*" + "xcb" + "*clock" + "xeyes" + "xload" + "xpostit" + "as*" +} + +NoTitle +{ +ifelse(WMdesktoptitle, 0, `"VTWM Desktop"') +ifelse(WMdoortitle, 0, `"VTWM Door"') +ifelse(WMiconmgrtitle, 0, `"VTWM Icon Manager"') +ifelse(WMname, `95ish', `"MPlayer"', WMname, `MWMish', `"MPlayer"') +ifelse(WMname, `PWMish', `"MPlayer"', WMname, `TWM3d', `"MPlayer"') +ifelse(WMname, `TWMish', `"MPlayer"') +ifelse(WMname, `95ish', `"xbiff*"', WMname, `MWMish', `"xbiff*"') +ifelse(WMname, `PWMish', `"xbiff*"', WMname, `TWM3d', `"xbiff*"') +ifelse(WMname, `TWMish', `"xbiff*"') +ifelse(WMname, `95ish', `"xcb"', WMname, `MWMish', `"xcb"') +ifelse(WMname, `PWMish', `"xcb"', WMname, `TWM3d', `"xcb"') +ifelse(WMname, `TWMish', `"xcb"') +ifelse(WMname, `95ish', `"*clock"', WMname, `MWMish', `"*clock"') +ifelse(WMname, `PWMish', `"*clock"', WMname, `TWM3d', `"*clock"') +ifelse(WMname, `TWMish', `"*clock"') + "xeyes" +ifelse(WMname, `95ish', `"xload"', WMname, `MWMish', `"xload"') +ifelse(WMname, `PWMish', `"xload"', WMname, `TWM3d', `"xload"') +ifelse(WMname, `TWMish', `"xload"') +ifelse(WMname, `95ish', `"xpostit"', WMname, `MWMish', `"xpostit"') +ifelse(WMname, `PWMish', `"xpostit"', WMname, `TWM3d', `"xpostit"') +ifelse(WMname, `TWMish', `"xpostit"') +ifelse(WMapplettitle, 0, `"as*"') +} + +# Confusing if click-to-type focus is enabled... +AutoRaise +{ + "VTWM*" + "XTerm" + "Xqsh" + "xbiff*" + "xcb" + "*clock" + "xeyes" + "xload" + "xpostit" + "as*" + "XVroot" + "XVschnauze" +} + +# These are dependant on the virtual desktop size... +# Set the window dimensions... +define(Dwidth, 20) define(Dheight, 19) +# Translate to an X geometry string... +define(Dgeometry, translit(Dwidth*Dheight, *, x)) +#Doors +#{ +# "1" "Dgeometry" "+eval(WIDTH * 0)+0" +# "2" "Dgeometry" "+eval(WIDTH * 1)+0" +# "3" "Dgeometry" "+eval(WIDTH * 2)+0" +# "4" "Dgeometry" "+eval(WIDTH * 3)+0" +# "5" "Dgeometry" "+eval(WIDTH * 4)+0" +#} + +# Calculate the region dimensions... +define(R0width, eval(WIDTH - VDwidth - 50)) +define(R0height, eval(Dheight + 2 * WMborder + WMdoortitle)) +# Calculate the region coordinates... +define(R0x, WMpanborder) +define(R0y, eval(HEIGHT - (R0height + WMpanborder))) +# Translate to an X geometry string... +define(R0geometry, translit(R0width*R0height+R0x+R0y, *, x)) +# Calculate the grids... +define(R0gridx, eval(2 * WMborder + 5)) +define(R0gridy, 0) +# Set the resource... +AppletRegion "R0geometry" South East R0gridx R0gridy +{ + "VTWM Door" +} + +# Calculate the region dimensions... +define(R1width, eval(WIDTH - 200)) +define(R1height, eval(64 + 2 * WMborder + WMapplettitle)) +# Translate to an X geometry string... +define(R1geometry, translit(R1width*R1height-WMpanborder+WMpanborder, *, x)) +# Calculate the grids... +define(R1gridx, eval(2 * WMborder + 2)) +define(R1gridy, 0) +# Set the resource... +AppletRegion "R1geometry" North East R1gridx R1gridy +{ + "as*" +} + +# Calculate the region coordinates... +define(R2x, WMpanborder) define(R2y, eval(R1height + 20)) +# Calculate the region dimensions... +define(R2width, eval(100 + 2 * WMborder)) +define(R2height, eval(HEIGHT - R2y - (VDheight + WMdesktoptitle))) +# Translate to an X geometry string... +define(R2geometry, translit(R2width*R2height-R2x+R2y, *, x)) +# Calculate the grids... +define(R2gridx, 0) +define(R2gridy, eval(2 * WMborder + 4)) +# Set the resource... +AppletRegion "R2geometry" North East R2gridx R2gridy +{ + "xbiff*" + "xcb" + "xload" + "oclock" + "xarclock" + "xclock" + "xdaliclock" + "xpostit" +} + diff --git a/contrib/vtwmrc/vtwmrc-menus b/contrib/vtwmrc/vtwmrc-menus new file mode 100644 index 0000000..7dc0934 --- /dev/null +++ b/contrib/vtwmrc/vtwmrc-menus @@ -0,0 +1,266 @@ + +# +# DESCRIPTION FILE FOR vtwm - $(HOME)/vtwm/vtwmrc-menus +# +# PRE-PROCESSED BY vtwm-5.4.6 USING m4 +# + +# +# Menus +# + +menu "XWindowsMenu" +{ + `"'SERVERHOST`"' f.title + "Shells" f.menu "ShellsMenu" + "Editors" f.menu "EditorsMenu" + "" f.separator + "Desktop" f.menu "DesktopMenu" + "Network" f.menu "NetworkMenu" + "Toybox" f.menu "ToyboxMenu" + "Wallpaper" f.menu "WallpaperMenu" + "" f.separator + "Arrange" f.menu "ArrangeMenu" + "" f.separator + "VTWM" f.menu "VTWMMenu" +} + +menu "ShellsMenu" +{ + " Shells " f.title + "mc" f.exec "HOME/bin/startxterm -g 80x43 -title 'mc' -name 'mc' -e mc &" + "rxvt" f.exec "HOME/bin/startrxvt &" + "xterm" f.exec "HOME/bin/startxterm &" +} + +menu "EditorsMenu" +{ + " Editors " f.title + "nedit" f.exec "nedit &" + "ted" f.exec "Ted 2>/dev/null &" + "tkhtml" f.exec "tkHTML &" + "vi" f.exec "HOME/bin/startxterm -title 'vi' -name 'vi' -e vi &" + "vile" f.exec "HOME/bin/startxterm -title 'vile' -name 'vile' -e vile &" + "xcoral" f.exec "xcoral &" + "xvile" f.exec "xvile &" + "" f.separator + "bitmap" f.exec "bitmap &" + "editres" f.exec "editres &" + "gimp" f.exec "gimp &" + "pixmap" f.exec "pixmap &" + "xfig" f.exec "xfig 2>/dev/null &" + "xpaint" f.exec "xpaint 2>/dev/null &" + "xv" f.exec "xv &" +# "xv +vsp" f.exec "xv +vsp &" +} + +menu "DesktopMenu" +{ + " Desktop " f.title + "asbutton" f.exec "asbutton -n 4 &" + "ghostview" f.exec "ghostview &" + "gv" f.exec "gv &" + "hexcalc" f.exec "hexcalc &" + "jpilot" f.exec "jpilot &" + "meltdown" f.exec "meltdown -s &" + "tkman" f.exec "tkman &" + "xbmbrowser" f.exec "xbmbrowser &" + "xcb" f.exec "xcb &" + "xcalc" f.exec "xcalc &" + "xcalendar" f.exec "xcalendar &" + "xload" f.exec "xload -jumpscroll 20 -update 3 -g 96x93 &" + "xlock" f.exec "xscreensaver-command -lock &" + "xmcd" f.exec "xmcd &" + "xmmix" f.exec "xmmix 2>/dev/null &" + "xpostit" f.exec "xpostit -g 96x40 &" + "xtplaygizmo" f.exec "xtplaygizmo &" + "" f.separator + "asclock" f.exec "asclock -exe xcalendar -led grey85 &" + "oclock" f.exec "oclock -g 96x93 -bd SeaGreen -fg SeaGreen -transparent &" + "mouseclock" f.exec "mouseclock &" + "rclock" f.exec "rclock &" + "sunclock" f.exec "sunclock &" + "t3d" f.exec "t3d -nice 2 &" + "xarclock" f.exec "xarclock -g 97x93 -arabic -fg white -bg black -fn -adobe-helvetica-medium-r-normal--*-80-*-*-p-*-iso8859-* &" + "xclock" f.exec "xclock &" +# "xdaliclock" f.exec "xdaliclock -fg SeaGreen -transparent -fn -adobe-utopia-medium-i-normal-*-*-260-*-*-p-*-iso8859-* &" + "xdaliclock" f.exec "xdaliclock -fg SeaGreen -transparent -fn -adobe-times-bold-i-normal-*-*-260-*-*-p-*-iso8859-* &" +} + +menu "NetworkMenu" +{ + " Network " f.title + "asmail" f.exec "asmail &" + "chimera" f.exec "chimera &" + "knews" f.exec "knews &" +# "mosaic" f.exec "Mosaic &" + "mozilla" f.exec "mozilla &" + "mutt" f.exec "HOME/bin/startxterm -title mutt -name mutt -e mutt &" + "netscape" f.exec "netscape &" + "xarchie" f.exec "xarchie &" + "xbiff++" f.exec "xbiff++ -update 60 -g 96x93 &" + "xdir" f.exec "xdir &" + "xgopher" f.exec "xgopher &" + "" f.separator + "FTP" f.menu "FTPMenu" + "Login" f.menu "LoginMenu" + "SSH" f.menu "SSHMenu" + "Telnet" f.menu "TelnetMenu" +} + +menu "FTPMenu" +{ + " FTP " f.title + "host1" f.exec "HOME/bin/startxterm -title 'ftp:host1' -name 'ftp:host1' -e ftp host1 &" + "" f.separator +# "host2" f.exec "HOME/bin/startxterm -title 'ftp:host2' -name 'ftp:host2' -e ftp host2 &" + "host3" f.exec "HOME/bin/startxterm -title 'ftp:host3' -name 'ftp:host3' -e ftp host3 &" +# "host4" f.exec "HOME/bin/startxterm -title 'ftp:host4' -name 'ftp:host4' -e ftp host4 &" + "" f.separator + "host5" f.exec "HOME/bin/startxterm -title 'ftp:host5' -name 'ftp:host5' -e ftp host5 &" +} + +menu "LoginMenu" +{ + " Remote Login " f.title +# "host1" f.exec "HOME/bin/startxterm -title 'rlogin:host1' -name 'rlogin:host1' -e rlogin host1 &" +# "" f.separator +# "host2" f.exec "HOME/bin/startxterm -title 'rlogin:host2' -name 'rlogin:host2' -e rlogin host2 &" + "host3" f.exec "HOME/bin/startxterm -title 'rlogin:host3' -name 'rlogin:host3' -e rlogin host3 &" +# "host4" f.exec "HOME/bin/startxterm -title 'rlogin:host4' -name 'rlogin:host4' -e rlogin host4 &" + "" f.separator + "host5" f.exec "HOME/bin/startxterm -title 'rlogin:host5' -name 'rlogin:host5' -e rlogin host5 &" +} + +menu "SSHMenu" +{ + " SSH " f.title + "host1" f.exec "HOME/bin/startxterm -title 'ssh:host1' -name 'ssh:host1' -e ssh -l username host1 &" + "" f.separator +# "host2" f.exec "HOME/bin/startxterm -title 'ssh:host2' -name 'ssh:host2' -e ssh -l username host2 &" +# "host3" f.exec "HOME/bin/startxterm -title 'ssh:host3' -name 'ssh:host3' -e ssh -l username host3 &" +# "host4" f.exec "HOME/bin/startxterm -title 'ssh:host4' -name 'ssh:host4' -e ssh -l username -p 27 host4 &" +# "" f.separator +# "host5" f.exec "HOME/bin/startxterm -title 'ssh:host5' -name 'ssh:host5' -e ssh host5 &" + "host6" f.exec "HOME/bin/startxterm -title 'ssh:host6' -name 'ssh:host6' -e ssh host6 &" +# "host7" f.exec "HOME/bin/startxterm -title 'ssh:host7' -name 'ssh:host7' -e ssh host7 &" +} + +menu "TelnetMenu" +{ + " Telnet " f.title + "host1" f.exec "HOME/bin/startxterm -tn $TELTERM -title 'telnet:host1' -name 'telnet:host1' -e telnet host1 &" +# "host2" f.exec "HOME/bin/startxterm -tn $TELTERM -title 'telnet:host2' -name 'telnet:host2' -e telnet -8 host2 &" + "" f.separator +# "host3" f.exec "HOME/bin/startxterm -tn $TELTERM -title 'telnet:host3' -name 'telnet:host3' -e telnet host3 &" + "host4" f.exec "HOME/bin/startxterm -tn $TELTERM -title 'telnet:host4' -name 'telnet:host4' -e telnet host4 &" +# "host5" f.exec "HOME/bin/startxterm -tn $TELTERM -title 'telnet:host5' -name 'telnet:host5' -e telnet host5 &" + "" f.separator + "host6" f.exec "HOME/bin/startxterm -title 'telnet:host6' -name 'telnet:host6' -e telnet -8 host6 &" +} + +menu "ToyboxMenu" +{ + " Toybox " f.title + "blast" f.exec "blast &" + "xbl" f.exec "xbl -draw 2 -keyboard 4 -buffer 2 -buttonheight 4 &" + "xboing" f.exec "xboing -sound &" + "xeyes" f.exec "xeyes &" + "xmine" f.exec "xmine &" + "xneko" f.exec "xneko -t 0.07 &" + "xoids" f.exec "xoids &" + "xtetris" f.exec "xtetris &" +} + +menu "WallpaperMenu" +{ + " Wallpaper " f.title + "ico" f.exec "HOME/bin/stopxroot; nice -2 ico -softdbl -faces -colors green blue yellow red white -delta +10+10 -r &" + "pyro" f.exec "HOME/bin/stopxroot; pyro -root &" + "xcursor" f.exec "xcursor &" + "xearth" f.exec "HOME/bin/stopxroot; xearth &" + "xfishtank" f.exec "HOME/bin/stopxroot; xfishtank -m 25 -C 25 -c black -r 0.08 -i 0.04 -b 20 &" + "xneko" f.exec "HOME/bin/stopxroot; xneko -t 0.07 -r &" + "xroach" f.exec "HOME/bin/stopxroot; xroach -rc grey -speed 8 &" + "" f.separator + "logo" f.exec "xsetbg -grey -border black -center /home/hawkeyd/vtwm/vtwm.gif &" + "none" f.exec "HOME/bin/stopxroot &" +} + +menu "ArrangeMenu" +{ + " Arrange " f.title + "Auto Raise" f.autoraise + "Raise" f.raise + "Lower" f.lower +# I just never use this... +# "Raise Lower" f.raiselower + "Nail" f.nail + "Ring" f.ring + "" f.separator + "Focus" f.focus + "Unfocus" f.unfocus + "" f.separator + "Move" f.move + "Size" f.resize + "Iconify" f.iconify + "" f.separator + "Full Zoom" f.fullzoom + "Horiz Zoom" f.horizoom + "Vert Zoom" f.zoom + "" f.separator + "Left Title" f.squeezeleft + "Center Title" f.squeezecenter + "Right Title" f.squeezeright + "" f.separator + "Bind Buttons" f.bindbuttons + "Unbind Buttons" f.unbindbuttons + "Bind Keys" f.bindkeys + "Unbind Keys" f.unbindkeys + "" f.separator + "Identify" f.identify + "" f.separator + "Delete" f.delete + "Destroy" f.destroy +} + +menu "VTWMMenu" +{ + " VTWM " f.title +# These are dependant on the virtual screen counts... +# "Virtual 1" f.setrealscreen "+eval(WIDTH * 0)+0" +# "Virtual 2" f.setrealscreen "+eval(WIDTH * 1)+0" +# "Virtual 3" f.setrealscreen "+eval(WIDTH * 2)+0" +# "Virtual 4" f.setrealscreen "+eval(WIDTH * 3)+0" +# "Virtual 5" f.setrealscreen "+eval(WIDTH * 4)+0" +# "" f.separator + "Auto Pan" f.autopan + "New Door" f.newdoor + "Snap Screen" f.snaprealscreen +ifelse(SOUND, `Yes', `"Sounds" f.sounds') + "Static Icons" f.staticiconpositions + "Strict Icon Mgr" f.stricticonmgr + "Warp Snug" f.warpsnug + "Warp Visible" f.warpvisible + "" f.separator + "Icon Mgr" f.showiconmgr + "Virtual Mgr" f.showdesktopdisplay + "" f.separator +# "VTWM Windows" f.menu "VTWM Windows" +# "" f.separator + "Refresh" f.refresh + "Restart 95ish" f.startwm "vtwm -d :0.0 -s -m -p -f vtwm/vtwmrc-95ish" + "Restart MWMish" f.startwm "vtwm -d :0.0 -s -m -p -f vtwm/vtwmrc-MWMish" + "Restart PWMish" f.startwm "vtwm -d :0.0 -s -m -p -f vtwm/vtwmrc-PWMish" + "Restart TWMish" f.startwm "vtwm -d :0.0 -s -m -p -f vtwm/vtwmrc-TWMish" + "Restart TWM3d" f.startwm "vtwm -d :0.0 -s -m -p -f vtwm/vtwmrc-TWM3d" + "Restart borderless" f.startwm "vtwm -d :0.0 -s -m -p -f vtwm/vtwmrc-NoBorder" + "Start MWM" f.startwm "mwm -display :0.0" + "Start TVTWM" f.startwm "tvtwm -display :0.0" + "Start TWM" f.startwm "twm -display :0.0" + "" f.separator +changequote(%, %) + "Exit" f.exec "HOME/bin/stopxroot; kill `cat HOME/vtwm.pid`" +changequote(,) +} + diff --git a/contrib/vtwmrc/vtwmrc-parms b/contrib/vtwmrc/vtwmrc-parms new file mode 100644 index 0000000..7a9dbe8 --- /dev/null +++ b/contrib/vtwmrc/vtwmrc-parms @@ -0,0 +1,66 @@ + +# +# DESCRIPTION FILE FOR vtwm - $(HOME)/vtwm/vtwmrc-parms +# +# PRE-PROCESSED BY vtwm-5.4.6 USING m4 +# + +# +# Parametered Variables +# + +WarpCentered "off" + +# Lower this if PrettyZoom used (see 'Booleans')... +#Zoom 150 + +# This spec works when (count * scale < phys_size) in each dimension. +# The size is then (phys_size * count / scale + bevel * 2) in each dimension. +# -- It's best if the window sizes work out to exact whole numbers -- +# +# This window is (1024 * 5 / 16 + 1 * 2) x (768 * 1 / 16 + 1 * 2) = 322 x 50. +# +# Use one of these (LLC or LRC) if you want it titled... +#VirtualDesktop "5x1+5-30" 16 +#VirtualDesktop "5x1+690+685" 16 +# Use one of these (LLC or LRC) if not... +#VirtualDesktop "5x1+5-10" 16 +#VirtualDesktop "5x1+690+705" 16 +# +# Using m4, calculate coordinates for most common phys_size dimensions. +# +# Horizontal and vertical screen counts, desktop scale... +define(VDhoriz, 5) define(VDvert, 1) define(VDscale, 16) +# Calculate the window dimensions... +define(VDwidth, eval(WIDTH * VDhoriz / VDscale + (WMdesktopbevel * 2 + WMborder * 2))) +define(VDheight, eval(HEIGHT * VDvert / VDscale + (WMdesktopbevel * 2 + WMborder * 2 + WMdesktoptitle))) +# Calculate the window coordinates (this is for LRC)... +define(VDx, eval(WIDTH - (VDwidth + WMpanborder))) +define(VDy, eval(HEIGHT - (VDheight + WMpanborder))) +# Translate to an X geometry string (set VDx to WMpanborder for LLC)... +define(VDgeometry, translit(VDhoriz*VDvert+VDx+VDy, *, x)) +# Set the resource... +VirtualDesktop "VDgeometry" VDscale + +PanDistanceX 100 +PanDistanceY 100 +PanResistance 750 +AutoPan 100 +# Nice if 'NaturalAutoPanBehavior' is not used... +#AutoPanExtraWarp 30 + +MoveDelta 10 + +BorderWidth WMborder +AutoPanBorderWidth WMpanborder + +# Windows are snappier if 'NoBackingStore' is not used when this is... +RaiseDelay 80 + +XorValue 65535 + +ResizeRegion "NorthEast" + +# Ignore the Caps, Num, and Scroll lock states... +IgnoreModifiers l | m2 | m5 + diff --git a/contrib/vtwmrc/vtwmrc-sound b/contrib/vtwmrc/vtwmrc-sound new file mode 100644 index 0000000..ef93777 --- /dev/null +++ b/contrib/vtwmrc/vtwmrc-sound @@ -0,0 +1,90 @@ + +# +# DESCRIPTION FILE FOR vtwm - $(HOME)/vtwm/vtwmrc-sound +# +# PRE-PROCESSED BY vtwm-5.4.6 USING m4 +# + +PauseOnExit 3 +PauseOnQuit 3 + +Sounds +{ + "(vtwm start)" "HOME/vtwm/sounds/startup.wav" + "(vtwm stop)" "HOME/vtwm/sounds/shutdown.wav" + +# "f.exec" "HOME/vtwm/sounds/ping.au" + "f.newdoor" "HOME/vtwm/sounds/ping.au" + "(client map)" "HOME/vtwm/sounds/ping.au" + + "f.delete" "HOME/vtwm/sounds/doh2.au" + "f.deletedoor" "HOME/vtwm/sounds/doh1.au" + "f.destroy" "HOME/vtwm/sounds/doh3.au" + "(client unmap)" "HOME/vtwm/sounds/ping.au" + + "f.bottomzoom" "HOME/vtwm/sounds/bleebloo.au" 50 + "f.fullzoom" "HOME/vtwm/sounds/bleebloo.au" 50 + "f.horizoom" "HOME/vtwm/sounds/bleebloo.au" 50 + "f.leftzoom" "HOME/vtwm/sounds/bleebloo.au" 50 + "f.rightzoom" "HOME/vtwm/sounds/bleebloo.au" 50 + "f.topzoom" "HOME/vtwm/sounds/bleebloo.au" 50 + "f.zoom" "HOME/vtwm/sounds/bleebloo.au" 50 + + "f.squeezeleft" "HOME/vtwm/sounds/tshhh.wav" 50 + "f.squeezecenter" "HOME/vtwm/sounds/tshhh.wav" 50 + "f.squeezeright" "HOME/vtwm/sounds/tshhh.wav" 50 + + "f.iconify" "HOME/vtwm/sounds/dedoo.au" 30 + "f.hidedesktopdisplay" "HOME/vtwm/sounds/dedoo.au" 30 + "f.hideiconmgr" "HOME/vtwm/sounds/dedoo.au" 30 + "f.showdesktopdisplay" "HOME/vtwm/sounds/dedoo.au" 30 + "f.showiconmgr" "HOME/vtwm/sounds/dedoo.au" 30 + "f.stricticonmgr" "HOME/vtwm/sounds/bleebloo.au" 50 + + "f.resize" "HOME/vtwm/sounds/chime5.au" + "f.movescreen" "HOME/vtwm/sounds/chime5.au" + "f.move" "HOME/vtwm/sounds/chime5.au" + "f.forcemove" "HOME/vtwm/sounds/chime5.au" + + "f.deiconify" "HOME/vtwm/sounds/whoosh4.au" 50 +# "f.warp" "HOME/vtwm/sounds/whoosh4.au" 50 + "f.warpclassnext" "HOME/vtwm/sounds/whoosh4.au" 50 + "f.warpclassprev" "HOME/vtwm/sounds/whoosh4.au" 50 + "f.warpring" "HOME/vtwm/sounds/whoosh4.au" 50 + "f.warpto" "HOME/vtwm/sounds/whoosh4.au" 50 + "f.warptoiconmgr" "HOME/vtwm/sounds/whoosh4.au" 50 + "f.warptonewest" "HOME/vtwm/sounds/whoosh4.au" 50 + + "f.panup" "HOME/vtwm/sounds/whoosh1.wav" + "f.pandown" "HOME/vtwm/sounds/whoosh1.wav" + "f.panleft" "HOME/vtwm/sounds/whoosh1.wav" + "f.panright" "HOME/vtwm/sounds/whoosh1.wav" + "f.enterdoor" "HOME/vtwm/sounds/whoosh1.wav" + "(autopan event)" "HOME/vtwm/sounds/whoosh1.wav" + + "f.autopan" "HOME/vtwm/sounds/pop1.wav" 30 + "f.snaprealscreen" "HOME/vtwm/sounds/pop1.wav" 30 + "f.staticiconpositions" "HOME/vtwm/sounds/pop1.wav" 30 + "f.nail" "HOME/vtwm/sounds/pop1.wav" 30 + "f.ring" "HOME/vtwm/sounds/pop1.wav" 30 + "f.warpsnug" "HOME/vtwm/sounds/pop1.wav" 30 + "f.warpvisible" "HOME/vtwm/sounds/pop1.wav" 30 + + "f.autoraise" "HOME/vtwm/sounds/pop1.wav" 30 +# "f.raise" "HOME/vtwm/sounds/pop1.wav" 30 +# "f.lower" "HOME/vtwm/sounds/pop1.wav" 30 + "f.focus" "HOME/vtwm/sounds/pop1.wav" 30 + "f.unfocus" "HOME/vtwm/sounds/pop1.wav" 30 + "f.bindbuttons" "HOME/vtwm/sounds/pop1.wav" 30 + "f.unbindbuttons" "HOME/vtwm/sounds/pop1.wav" 30 + "f.bindkeys" "HOME/vtwm/sounds/pop1.wav" 30 + "f.unbindkeys" "HOME/vtwm/sounds/pop1.wav" 30 + + "(menu map)" "HOME/vtwm/sounds/chime3.au" +# "(menu unmap)" "HOME/vtwm/sounds/chime3.au" + "f.identify" "HOME/vtwm/sounds/chime4.au" +# "(info unmap)" "HOME/vtwm/sounds/chime4.au" + + "(bell event)" "HOME/vtwm/sounds/chime1.au" +} + diff --git a/cursor.c b/cursor.c new file mode 100644 index 0000000..a04fe27 --- /dev/null +++ b/cursor.c @@ -0,0 +1,179 @@ +/* + * Copyright 1989 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*********************************************************************** + * + * $XConsortium: cursor.c,v 1.10 89/12/14 14:52:23 jim Exp $ + * + * cursor creation code + * + * 05-Apr-89 Thomas E. LaStrange File created + * + ***********************************************************************/ + +#include +#include "twm.h" +#include +#include "screen.h" +#include "util.h" + +void NewBitmapCursor(); + +static struct _CursorName { + char *name; + unsigned int shape; + Cursor cursor; +} cursor_names[] = { + +{"X_cursor", XC_X_cursor, None}, +{"arrow", XC_arrow, None}, +{"based_arrow_down", XC_based_arrow_down, None}, +{"based_arrow_up", XC_based_arrow_up, None}, +{"boat", XC_boat, None}, +{"bogosity", XC_bogosity, None}, +{"bottom_left_corner", XC_bottom_left_corner, None}, +{"bottom_right_corner", XC_bottom_right_corner, None}, +{"bottom_side", XC_bottom_side, None}, +{"bottom_tee", XC_bottom_tee, None}, +{"box_spiral", XC_box_spiral, None}, +{"center_ptr", XC_center_ptr, None}, +{"circle", XC_circle, None}, +{"clock", XC_clock, None}, +{"coffee_mug", XC_coffee_mug, None}, +{"cross", XC_cross, None}, +{"cross_reverse", XC_cross_reverse, None}, +{"crosshair", XC_crosshair, None}, +{"diamond_cross", XC_diamond_cross, None}, +{"dot", XC_dot, None}, +{"dotbox", XC_dotbox, None}, +{"double_arrow", XC_double_arrow, None}, +{"draft_large", XC_draft_large, None}, +{"draft_small", XC_draft_small, None}, +{"draped_box", XC_draped_box, None}, +{"exchange", XC_exchange, None}, +{"fleur", XC_fleur, None}, +{"gobbler", XC_gobbler, None}, +{"gumby", XC_gumby, None}, +{"hand1", XC_hand1, None}, +{"hand2", XC_hand2, None}, +{"heart", XC_heart, None}, +{"icon", XC_icon, None}, +{"iron_cross", XC_iron_cross, None}, +{"left_ptr", XC_left_ptr, None}, +{"left_side", XC_left_side, None}, +{"left_tee", XC_left_tee, None}, +{"leftbutton", XC_leftbutton, None}, +{"ll_angle", XC_ll_angle, None}, +{"lr_angle", XC_lr_angle, None}, +{"man", XC_man, None}, +{"middlebutton", XC_middlebutton, None}, +{"mouse", XC_mouse, None}, +{"pencil", XC_pencil, None}, +{"pirate", XC_pirate, None}, +{"plus", XC_plus, None}, +{"question_arrow", XC_question_arrow, None}, +{"right_ptr", XC_right_ptr, None}, +{"right_side", XC_right_side, None}, +{"right_tee", XC_right_tee, None}, +{"rightbutton", XC_rightbutton, None}, +{"rtl_logo", XC_rtl_logo, None}, +{"sailboat", XC_sailboat, None}, +{"sb_down_arrow", XC_sb_down_arrow, None}, +{"sb_h_double_arrow", XC_sb_h_double_arrow, None}, +{"sb_left_arrow", XC_sb_left_arrow, None}, +{"sb_right_arrow", XC_sb_right_arrow, None}, +{"sb_up_arrow", XC_sb_up_arrow, None}, +{"sb_v_double_arrow", XC_sb_v_double_arrow, None}, +{"shuttle", XC_shuttle, None}, +{"sizing", XC_sizing, None}, +{"spider", XC_spider, None}, +{"spraycan", XC_spraycan, None}, +{"star", XC_star, None}, +{"target", XC_target, None}, +{"tcross", XC_tcross, None}, +{"top_left_arrow", XC_top_left_arrow, None}, +{"top_left_corner", XC_top_left_corner, None}, +{"top_right_corner", XC_top_right_corner, None}, +{"top_side", XC_top_side, None}, +{"top_tee", XC_top_tee, None}, +{"trek", XC_trek, None}, +{"ul_angle", XC_ul_angle, None}, +{"umbrella", XC_umbrella, None}, +{"ur_angle", XC_ur_angle, None}, +{"watch", XC_watch, None}, +{"xterm", XC_xterm, None}, +}; + +void NewFontCursor (cp, str) + Cursor *cp; + char *str; +{ + int i; + + for (i = 0; i < sizeof(cursor_names)/sizeof(struct _CursorName); i++) + { + if (strcmp(str, cursor_names[i].name) == 0) + { + if (cursor_names[i].cursor == None) + cursor_names[i].cursor = XCreateFontCursor(dpy, + cursor_names[i].shape); + *cp = cursor_names[i].cursor; + return; + } + } + fprintf (stderr, "%s: unable to find font cursor \"%s\"\n", + ProgramName, str); +} + +void NewBitmapCursor(cp, source, mask) +Cursor *cp; +char *source, *mask; +{ + XColor fore, back; + int hotx, hoty; + int sx, sy, mx, my; + unsigned int sw, sh, mw, mh; + Pixmap spm, mpm; + Colormap cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c; + + fore.pixel = Scr->Black; + XQueryColor(dpy, cmap, &fore); + back.pixel = Scr->White; + XQueryColor(dpy, cmap, &back); + + spm = GetBitmap(source); + if ((hotx = HotX) < 0) hotx = 0; + if ((hoty = HotY) < 0) hoty = 0; + mpm = GetBitmap(mask); + + /* make sure they are the same size */ + + XGetGeometry(dpy, spm, &JunkRoot, &sx, &sy, &sw, &sh, &JunkBW,&JunkDepth); + XGetGeometry(dpy, mpm, &JunkRoot, &mx, &my, &mw, &mh, &JunkBW,&JunkDepth); + if (sw != mw || sh != mh) + { + fprintf (stderr, + "%s: cursor bitmaps \"%s\" and \"%s\" not the same size\n", + ProgramName, source, mask); + return; + } + *cp = XCreatePixmapCursor(dpy, spm, mpm, &fore, &back, hotx,hoty); +} diff --git a/desktop.c b/desktop.c new file mode 100644 index 0000000..b9f8140 --- /dev/null +++ b/desktop.c @@ -0,0 +1,1562 @@ +/* + * $Id: desktop.c,v 3.0 90/11/20 16:13:09 dme Exp Locker: dme $ + * + * Copyright (c) 1990 Dave Edmondson. + * Copyright (c) 1990 Imperial College of Science, Technoology & Medicine + * All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Dave Edmondson or Imperial College + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Dave Edmondson and + * Imperial College make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#include +#include "twm.h" +#include "screen.h" +#include "add_window.h" +#include "menus.h" +#include "parse.h" +#include "events.h" +#include "desktop.h" + +#define strdup Strdup /* avoid conflict with system header files */ +extern char *strdup(char *); + +extern void SetRealScreenInternal(); +extern void SetRealScreen(); +extern void SnapRealScreen(); +extern void SetMapStateProp(); +extern void twmrc_error_prefix(); + +void SetVirtualPixmap(); +void SetRealScreenPixmap(); + +/* djhjr - 4/27/98 */ +static int starting_x, starting_y; + +/* djhjr - 11/3/03 */ +static int original_x, original_y; + +static void GetDesktopWindowCoordinates(tmp_win, x, y, w, h) +TwmWindow *tmp_win; +int *x, *y, *w, *h; +{ + /* djhjr - 4/27/98 */ + int border = tmp_win->frame_bw + tmp_win->frame_bw3D; + + /* Stig Ostholm */ + if (tmp_win->nailed) + { if (x) + *x = tmp_win->frame_x / Scr->VirtualDesktopDScale; + if (y) +/* *y = tmp_win->virtual_frame_y / Scr->VirtualDesktopDScale; */ + *y = tmp_win->frame_y / Scr->VirtualDesktopDScale; /* DSE */ + /* RFB 4/92 no SCALE_D */ + /* *x = SCALE_D(tmp_win->virtual_frame_x); */ + /* *y = SCALE_D(tmp_win->virtual_frame_y); */ + } else { + if (x) + *x = tmp_win->virtual_frame_x / Scr->VirtualDesktopDScale; + if (y) + *y = tmp_win->virtual_frame_y / Scr->VirtualDesktopDScale; + /* RFB 4/92 no SCALE_D */ + /* *x = SCALE_D(tmp_win->virtual_frame_x); */ + /* *y = SCALE_D(tmp_win->virtual_frame_y); */ + } + + if (w) + { *w = SCALE_D( + tmp_win->frame_width + Scr->VirtualDesktopDScale / 2 + +/* djhjr - 4/27/98 + + tmp_win->frame_bw + tmp_win->frame_bw ) +*/ + + (2 * border) ) + + - 2; + if ( *w <= 0 ) *w = 1; /* 4/92 RFB */ + } + + if (h) + { *h = SCALE_D( + tmp_win->frame_height + Scr->VirtualDesktopDScale / 2 +/* #ifdef SHAPE */ + /* + tmp_win->title_height */ +/* #ifdef SHAPE */ + +/* djhjr - 4/27/98 + + tmp_win->frame_bw + tmp_win->frame_bw ) - 2; +*/ + + (2 * border) ) - 2; + +/* 4/92 RFB -- subtract borderwidth from windowwidth... */ + if ( *h <= 0 ) *h = 1; /* 4/92 RFB */ + } +} /* Stig Ostholm */ + + +/* + * create the virtual desktop display and store the window in the screen structure + */ +void CreateDesktopDisplay() +{ + int width, height; + int border; + +/* djhjr - 5/17/98 */ +#ifndef ORIGINAL_PIXMAPS + Pixmap pm = None; + GC gc; + XGCValues gcv; + XSetWindowAttributes attributes; /* attributes for create windows */ + unsigned long valuemask; + unsigned int pm_numcolors; +#endif + + if (!Scr->Virtual) + return; + + width = Scr->VirtualDesktopWidth / Scr->VirtualDesktopDScale; + height = Scr->VirtualDesktopHeight / Scr->VirtualDesktopDScale; + +/* done in SetVirtualDesktop() - djhjr - 9/26/01 + * we have some checking for negative (x,y) to do * + if (Scr->VirtualDesktopDX < 0) { + Scr->VirtualDesktopDX = Scr->MyDisplayWidth - width - + (2 * Scr->BorderWidth) + Scr->VirtualDesktopDX; + } + if (Scr->VirtualDesktopDY < 0) { + Scr->VirtualDesktopDY = Scr->MyDisplayHeight - height - + (2 * Scr->BorderWidth) + Scr->VirtualDesktopDY; + } +*/ + + Scr->VirtualDesktopDisplayOuter = + XCreateSimpleWindow(dpy, Scr->Root, + Scr->VirtualDesktopDX, Scr->VirtualDesktopDY, + +/* djhjr - 2/7/99 + width, height, +*/ + width + (Scr->VirtualDesktopBevelWidth * 2), + height + (Scr->VirtualDesktopBevelWidth * 2), + +/* was 'Scr->BorderWidth' - submitted by Rolf Neugebauer */ + 0, + + Scr->Black, Scr->VirtualDesktopDisplayC.back); + + /* djhjr - 2/7/99 */ + { + XSetWindowAttributes attr; + + attr.backing_store = True; + XChangeWindowAttributes(dpy, Scr->VirtualDesktopDisplayOuter, + CWBackingStore, &attr); + } + + if ( width != Scr->VirtualDesktopMaxWidth ) + Scr->VirtualDesktopMaxWidth = width; + if ( height != Scr->VirtualDesktopMaxHeight ) + Scr->VirtualDesktopMaxHeight = height; +/* vtwm 5.2: RFB growable but not unreasonable interior window! */ + +/* + * re-written to use an Image structure for XPM support + * + * djhjr - 5/17/98 + */ +#ifdef ORIGINAL_PIXMAPS + Scr->VirtualDesktopDisplay = + XCreateSimpleWindow(dpy, Scr->VirtualDesktopDisplayOuter, + +/* djhjr - 2/7/99 + 0, 0, +*/ + Scr->VirtualDesktopBevelWidth, + Scr->VirtualDesktopBevelWidth, + + Scr->VirtualDesktopMaxWidth, + Scr->VirtualDesktopMaxHeight, + 0, + Scr->VirtualDesktopDisplayBorder, + Scr->VirtualC.back);/*RFB VCOLOR*/ + + XDefineCursor( dpy, Scr->VirtualDesktopDisplay, + Scr->VirtualCursor ); /*RFBCURSOR*/ + + if ( Scr->virtualPm ) /*RFB PIXMAP*/ + { /* Background pixmap, copied from tvtwm */ + Pixmap pm = None; + GC gc; + XGCValues gcv; + + pm = XCreatePixmap( dpy, Scr->VirtualDesktopDisplay, + Scr->virtual_pm_width, Scr->virtual_pm_height, + Scr->d_depth); + gcv.foreground = Scr->VirtualC.fore; + gcv.background = Scr->VirtualC.back; + gcv.graphics_exposures = False; + gc = XCreateGC (dpy, Scr->Root, + (GCForeground|GCBackground|GCGraphicsExposures), + &gcv); + if (gc) + { + XCopyPlane (dpy, Scr->virtualPm, pm, gc, 0, 0, + Scr->virtual_pm_width, Scr->virtual_pm_height, + 0, 0, 1); + XFreeGC (dpy, gc); + XSetWindowBackgroundPixmap( dpy, Scr->VirtualDesktopDisplay, + pm ); + XClearWindow( dpy, Scr->VirtualDesktopDisplay ); + } + XFreePixmap (dpy, pm); + } +#else /* ORIGINAL_PIXMAPS */ + pm_numcolors = 0; + +/* djhjr - 5/23/98 9/2/98 */ +#ifndef NO_XPM_SUPPORT + if (Scr->virtualPm) + pm_numcolors = SetPixmapsBackground(Scr->virtualPm, Scr->Root, + Scr->VirtualC.back); +#endif + + if (pm_numcolors > 2) /* not a bitmap */ + { + valuemask = CWBackPixmap; + attributes.background_pixmap = Scr->virtualPm->pixmap; + + Scr->VirtualDesktopDisplay = XCreateWindow(dpy, + Scr->VirtualDesktopDisplayOuter, + +/* djhjr - 2/7/99 + 0, 0, +*/ + Scr->VirtualDesktopBevelWidth, + Scr->VirtualDesktopBevelWidth, + + Scr->VirtualDesktopMaxWidth, + Scr->VirtualDesktopMaxHeight, + 0, + Scr->d_depth, (unsigned int) CopyFromParent, + Scr->d_visual, valuemask, &attributes); + } + else + { + Scr->VirtualDesktopDisplay = XCreateSimpleWindow(dpy, + Scr->VirtualDesktopDisplayOuter, + +/* djhjr - 2/7/99 + 0, 0, +*/ + Scr->VirtualDesktopBevelWidth, + Scr->VirtualDesktopBevelWidth, + + Scr->VirtualDesktopMaxWidth, + Scr->VirtualDesktopMaxHeight, + 0, + Scr->VirtualDesktopDisplayBorder, + Scr->VirtualC.back); /*RFB VCOLOR*/ + + if (Scr->virtualPm) + { + pm = XCreatePixmap( dpy, Scr->VirtualDesktopDisplay, + Scr->virtualPm->width, Scr->virtualPm->height, + Scr->d_depth); + + gcv.foreground = Scr->VirtualC.fore; + gcv.background = Scr->VirtualC.back; + gcv.graphics_exposures = False; + + gc = XCreateGC(dpy, Scr->Root, + (GCForeground | GCBackground | GCGraphicsExposures), + &gcv); + + if (gc) + { + XCopyPlane(dpy, Scr->virtualPm->pixmap, pm, gc, 0, 0, + Scr->virtualPm->width, Scr->virtualPm->height, + 0, 0, 1); + + XFreeGC (dpy, gc); + + XSetWindowBackgroundPixmap(dpy, Scr->VirtualDesktopDisplay, pm); + + XClearWindow(dpy, Scr->VirtualDesktopDisplay); + } + + XFreePixmap(dpy, pm); + } + } + + XDefineCursor(dpy, Scr->VirtualDesktopDisplay, Scr->VirtualCursor); /*RFB CURSOR */ +#endif /* ORIGINAL_PIXMAPS */ + + XSetStandardProperties(dpy, Scr->VirtualDesktopDisplayOuter, + +/* djhjr - 4/27/96 + "Virtual Desktop", "Virtual Desktop", +*/ +/* djhjr - 5/19/98 + "VTWM Desktop", "VTWM Desktop", +*/ + VTWM_DESKTOP_CLASS, VTWM_DESKTOP_CLASS, + + None, NULL, 0, NULL); + +/* Stig Ostholm moved a few lines away from here */ + +/* djhjr - 2/15/99 + border = 0; + if ( Scr->UseRealScreenBorder ) + { + * border = 2; * + border = Scr->RealScreenBorderWidth; * DSE * + } +*/ + border = Scr->RealScreenBorderWidth; + +/* + * re-written to use an Image structure for XPM support + * + * djhjr - 5/17/98 + */ +#ifdef ORIGINAL_PIXMAPS + /* create the real screen display */ + Scr->VirtualDesktopDScreen = + XCreateSimpleWindow(dpy, Scr->VirtualDesktopDisplay, + 0, 0, + +/* djhjr - 2/15/99 + SCALE_D(Scr->MyDisplayWidth - 2 * border), + SCALE_D(Scr->MyDisplayHeight - 2 * border), +*/ + SCALE_D(Scr->MyDisplayWidth) - 2 * border, + SCALE_D(Scr->MyDisplayHeight) - 2 * border, + + border, /* make it distinctive */ +/* RFB 4/92: make borderwidth 0 instead of 2 */ +/* RFB 5.2: some people need the border... */ + Scr->VirtualDesktopDisplayBorder, + Scr->RealScreenC.back ); /* RFB 4/92 */ + + if ( Scr->RealScreenPm ) /*RFB PIXMAP*/ + { /* Background pixmap */ + Pixmap pm = None; + GC gc; + XGCValues gcv; + + pm = XCreatePixmap( dpy, Scr->VirtualDesktopDScreen, + Scr->RealScreen_pm_width, Scr->RealScreen_pm_height, + Scr->d_depth); + gcv.foreground = Scr->RealScreenC.fore; + gcv.background = Scr->RealScreenC.back; + gcv.graphics_exposures = False; + gc = XCreateGC (dpy, Scr->Root, + (GCForeground|GCBackground|GCGraphicsExposures), + &gcv); + if (gc) + { + XCopyPlane (dpy, Scr->RealScreenPm, pm, gc, 0, 0, + Scr->RealScreen_pm_width, Scr->RealScreen_pm_height, + 0, 0, 1); + XFreeGC (dpy, gc); + XSetWindowBackgroundPixmap( dpy, Scr->VirtualDesktopDScreen, + pm ); + XClearWindow( dpy, Scr->VirtualDesktopDScreen ); + } + XFreePixmap (dpy, pm); + } +#else /* ORIGINAL_PIXMAPS */ + pm_numcolors = 0; + +/* djhjr - 5/23/98 9/2/98 */ +#ifndef NO_XPM_SUPPORT + if (Scr->realscreenPm) + pm_numcolors = SetPixmapsBackground(Scr->realscreenPm, + Scr->Root, Scr->RealScreenC.back); +#endif + + if (pm_numcolors > 2) /* not a bitmap */ + { + valuemask = CWBackPixmap | CWBorderPixel; + attributes.background_pixmap = Scr->realscreenPm->pixmap; + attributes.border_pixel = Scr->VirtualDesktopDisplayBorder; + + Scr->VirtualDesktopDScreen = XCreateWindow(dpy, + Scr->VirtualDesktopDisplay, + 0, 0, + +/* djhjr - 2/15/99 + SCALE_D(Scr->MyDisplayWidth - 2 * border), + SCALE_D(Scr->MyDisplayHeight - 2 * border), +*/ + SCALE_D(Scr->MyDisplayWidth) - 2 * border, + SCALE_D(Scr->MyDisplayHeight) - 2 * border, + + border, + Scr->d_depth, (unsigned int) CopyFromParent, + Scr->d_visual, valuemask, &attributes); + } + else + { + Scr->VirtualDesktopDScreen = XCreateSimpleWindow(dpy, + Scr->VirtualDesktopDisplay, + 0, 0, + +/* djhjr - 2/15/99 + SCALE_D(Scr->MyDisplayWidth - 2 * border), + SCALE_D(Scr->MyDisplayHeight - 2 * border), +*/ + SCALE_D(Scr->MyDisplayWidth) - 2 * border, + SCALE_D(Scr->MyDisplayHeight) - 2 * border, + + border, /* make it distinctive */ +/* RFB 4/92: make borderwidth 0 instead of 2 */ +/* RFB 5.2: some people need the border... */ + Scr->VirtualDesktopDisplayBorder, + Scr->RealScreenC.back ); /* RFB 4/92 */ + + if (Scr->realscreenPm) + { + pm = XCreatePixmap(dpy, Scr->VirtualDesktopDScreen, + Scr->realscreenPm->width, Scr->realscreenPm->height, + Scr->d_depth); + + gcv.foreground = Scr->RealScreenC.fore; + gcv.background = Scr->RealScreenC.back; + gcv.graphics_exposures = False; + + gc = XCreateGC(dpy, Scr->Root, + (GCForeground | GCBackground | GCGraphicsExposures), + &gcv); + + if (gc) + { + XCopyPlane(dpy, Scr->realscreenPm->pixmap, pm, gc, 0, 0, + Scr->realscreenPm->width, Scr->realscreenPm->height, + 0, 0, 1); + + XFreeGC(dpy, gc); + + XSetWindowBackgroundPixmap(dpy, Scr->VirtualDesktopDScreen, pm); + + XClearWindow(dpy, Scr->VirtualDesktopDScreen); + } + + XFreePixmap(dpy, pm); + } + } +#endif /* ORIGINAL_PIXMAPS */ + + /* declare our interest */ + XSelectInput(dpy, Scr->VirtualDesktopDisplay, ButtonPressMask | ButtonReleaseMask | + KeyPressMask | KeyReleaseMask | ExposureMask); + +/* Stig Ostholm moved some lines to here: */ + Scr->VirtualDesktopDisplayTwin = + AddWindow(Scr->VirtualDesktopDisplayOuter, FALSE, NULL); + + /* djhjr - 5/19/98 */ + Scr->VirtualDesktopDisplayTwin->class.res_name = strdup(VTWM_DESKTOP_CLASS); + Scr->VirtualDesktopDisplayTwin->class.res_class = strdup(VTWM_DESKTOP_CLASS); + XSetClassHint(dpy, Scr->VirtualDesktopDisplayOuter, &Scr->VirtualDesktopDisplayTwin->class); + + /* limit the minimum size of the virtual desktop - djhjr - 2/23/99 */ + Scr->VirtualDesktopDisplayTwin->hints.flags |= PMinSize; + Scr->VirtualDesktopDisplayTwin->hints.min_width = + SCALE_D(Scr->MyDisplayWidth) + (Scr->VirtualDesktopBevelWidth * 2); + Scr->VirtualDesktopDisplayTwin->hints.min_height = + SCALE_D(Scr->MyDisplayHeight) + (Scr->VirtualDesktopBevelWidth * 2); + +#ifdef GROSS_HACK + /* this is a gross hack, but people wanted it */ + Scr->VirtualDesktopDisplayTwin->nailed = TRUE; +#endif /* GROSS_HACK */ + + SetMapStateProp(Scr->VirtualDesktopDisplayTwin, NormalState); +/* :ereh ot senil emos devom mlohtsO gitS */ + + /* position the representation */ + DisplayScreenOnDesktop(); + + /* map them all */ + XMapWindow(dpy, Scr->VirtualDesktopDScreen); + XMapWindow(dpy, Scr->VirtualDesktopDisplay); + XMapWindow(dpy, Scr->VirtualDesktopDisplayOuter); + + /* create the autopan windows if we are doing this */ + if (Scr->AutoPanX > 0) { + short l; + + /* left */ + Scr->VirtualDesktopAutoPan[0] = XCreateWindow(dpy, Scr->Root, + 0, + 0, + AP_SIZE, + Scr->MyDisplayHeight, + 0, + CopyFromParent, + InputOnly, + CopyFromParent, + 0, NULL); + /* right */ + Scr->VirtualDesktopAutoPan[1] = XCreateWindow(dpy, Scr->Root, + Scr->MyDisplayWidth - AP_SIZE, + 0, + AP_SIZE, + Scr->MyDisplayHeight, + 0, + CopyFromParent, + InputOnly, + CopyFromParent, + 0, NULL); + /* top */ + Scr->VirtualDesktopAutoPan[2] = XCreateWindow(dpy, Scr->Root, + 0, + 0, + Scr->MyDisplayWidth, + AP_SIZE, + 0, + CopyFromParent, + InputOnly, + CopyFromParent, + 0, NULL); + /* bottom */ + Scr->VirtualDesktopAutoPan[3] = XCreateWindow(dpy, Scr->Root, + 0, + Scr->MyDisplayHeight - AP_SIZE, + Scr->MyDisplayWidth, + AP_SIZE, + 0, + CopyFromParent, + InputOnly, + CopyFromParent, + 0, NULL); + + /* set the event masks on the windows */ + for(l = 0; l <= 3; l++) { + XSetStandardProperties(dpy, Scr->VirtualDesktopAutoPan[l], + "Automatic Pan", "Automatic Pan", + None, NULL, 0, NULL); + + /* + * Added the leave event for pan resistance - + * see events.c:HandleEnterNotify(). + * + * djhjr - 11/16/98 + */ + XSelectInput(dpy, Scr->VirtualDesktopAutoPan[l], + EnterWindowMask | LeaveWindowMask); + + XMapWindow(dpy, Scr->VirtualDesktopAutoPan[l]); + } /* end for l */ + + } /* end if Scr->AutoPan */ +} + +/* + * re-written to use an Image structure for XPM support + * + * djhjr - 5/17/98 + */ +#ifdef ORIGINAL_PIXMAPS +void SetVirtualPixmap (filename) +char *filename; +{/*RFB PIXMAP*/ + Pixmap pm = GetBitmap (filename); + + if (pm) { + if (Scr->virtualPm) { + XFreePixmap (dpy, Scr->virtualPm); + } + Scr->virtualPm = pm; + Scr->virtual_pm_width = JunkWidth; + Scr->virtual_pm_height = JunkHeight; + } +} +#else /* ORIGINAL_PIXMAPS */ +void SetVirtualPixmap (filename) +char *filename; +{ + if (!Scr->virtualPm) Scr->virtualPm = SetPixmapsPixmap(filename); +} +#endif /* ORIGINAL_PIXMAPS */ + +/* + * re-written to use an Image structure for XPM support + * + * djhjr - 5/17/98 + */ +#ifdef ORIGINAL_PIXMAPS +void SetRealScreenPixmap (filename) +char *filename; +{/*RFB PIXMAP*/ + Pixmap pm = GetBitmap (filename); + + if (pm) { + if (Scr->RealScreenPm) { + XFreePixmap (dpy, Scr->RealScreenPm); + } + Scr->RealScreenPm = pm; + Scr->RealScreen_pm_width = JunkWidth; + Scr->RealScreen_pm_height = JunkHeight; + } +} +#else /* ORIGINAL_PIXMAPS */ +void SetRealScreenPixmap (filename) +char *filename; +{ + if (!Scr->realscreenPm) Scr->realscreenPm = SetPixmapsPixmap(filename); +} +#endif /* ORIGINAL_PIXMAPS */ + +/* + * add this window to the virtual desktop - aka nail it + */ +void UpdateDesktop(tmp_win) +TwmWindow *tmp_win; +{ + int x, y, width, height; + Window dwindow; + + if (!Scr->Virtual) + return; + + if (!tmp_win->showindesktopdisplay) + return; + + if (tmp_win->icon) { + XUnmapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow); + return; + } + + GetDesktopWindowCoordinates(tmp_win, &x, &y, &width, &height); +/* Stig Ostholm these 3 lines */ + dwindow = (tmp_win->nailed) + ? Scr->VirtualDesktopDScreen : Scr->VirtualDesktopDisplay; + + /* if it already has a vd display window, just move it to the right place + and map it, else actually create the window */ + if (!tmp_win->VirtualDesktopDisplayWindow) { + Pixel background, border; + +#ifdef notdef + if (!GetColorFromList(Scr->VirtualDesktopColorBL, tmp_win->full_name, + &tmp_win->class, &background) && + !GetColorFromList(Scr->TitleBackgroundL, tmp_win->full_name, + &tmp_win->class, &background)) + background = Scr->VirtualDesktopDisplayC.back; +#endif /* notdef */ + background = tmp_win->virtual.back; + + /* 7/10/90 - uses border list not foreground */ + if(!GetColorFromList(Scr->VirtualDesktopColorBoL, tmp_win->full_name, + &tmp_win->class, &border) && + !GetColorFromList(Scr->TitleForegroundL, tmp_win->full_name, + &tmp_win->class, &border)) + border = Scr->VirtualDesktopDisplayBorder; + + /* the position and size don't matter */ + tmp_win->VirtualDesktopDisplayWindow = + XCreateSimpleWindow(dpy, + dwindow, x, y, width, height, /* Stig */ + 1, border, background); + +/*RFBCURSOR*/XDefineCursor( dpy, tmp_win->VirtualDesktopDisplayWindow, +/*RFBCURSOR*/Scr->DesktopCursor ); + + /* listen for expose events to redraw the name */ + if (Scr->NamesInVirtualDesktop) + XSelectInput(dpy, tmp_win->VirtualDesktopDisplayWindow, + ExposureMask); + + /* save the twm window on the window */ + XSaveContext(dpy, tmp_win->VirtualDesktopDisplayWindow, + VirtualContext, (caddr_t) tmp_win); + XSaveContext(dpy, tmp_win->VirtualDesktopDisplayWindow, + TwmContext, (caddr_t) tmp_win); + + +#if 0 +0 /* Stig Ostholm */ +0 /* comment out this section */ +0 } else +0 /* unmap whilst we reconfigure it */ +0 XUnmapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow); +0 +0 if (tmp_win->nailed) { +0 x = tmp_win->frame_x / Scr->VirtualDesktopDScale; +0 y = tmp_win->frame_y / Scr->VirtualDesktopDScale; +0/* RFB 4/92 no SCALE_D */ +0 /* x = SCALE_D(tmp_win->frame_x); */ +0 /* y = SCALE_D(tmp_win->frame_y); */ +0 +0 /* reparent this window into the little screen representation */ +0 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow, +0 Scr->VirtualDesktopDScreen, x, y); +0 } else { +0 x = tmp_win->virtual_frame_x / Scr->VirtualDesktopDScale; +0 y = tmp_win->virtual_frame_y / Scr->VirtualDesktopDScale; +0/* RFB 4/92 no SCALE_D */ +0 /* x = SCALE_D(tmp_win->virtual_frame_x); */ +0 /* y = SCALE_D(tmp_win->virtual_frame_y); */ +0 +0 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow, +0 Scr->VirtualDesktopDisplay, x, y); +0 } +0 +0 /* calculate the sizes and position */ +0 width = SCALE_D( +0 tmp_win->frame_width + Scr->VirtualDesktopDScale / 2 +0 + tmp_win->frame_bw + tmp_win->frame_bw ) +0 - 2; +0 height = SCALE_D( +0 tmp_win->frame_height + Scr->VirtualDesktopDScale / 2 +0/* #ifdef SHAPE */ +0 /* + tmp_win->title_height */ +0/* #endif */ +0 + tmp_win->frame_bw + tmp_win->frame_bw ) - 2; +0/* 4/92 RFB -- subtract borderwidth from windowwidth... */ +0 if ( width <= 0 ) width = 1; /* 4/92 RFB */ +0 if ( height <= 0 ) height = 1; /* 4/92 RFB */ +0 +0#ifdef DEBUG +0 fprintf(stderr, "%d*%d+%d+%d\n", x, y, width, height); +0#endif /* DEBUG */ +0 +0 /* move and size it */ +0 XMoveWindow(dpy, tmp_win->VirtualDesktopDisplayWindow, +0 x, y); +0 XResizeWindow(dpy, tmp_win->VirtualDesktopDisplayWindow, +0 width, height); +#else /* 0, Stig */ + } else { /* Unmapping is fixed by XReparentWindow */ + XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow, + dwindow, x, y); + XResizeWindow(dpy, tmp_win->VirtualDesktopDisplayWindow, + width, height); + } +#endif + XMapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow); +} + +#if 0 /* Stig */ +0/* Stig Ostholm */ +0/* +0 * remove a window from the desktop display - aka unnail it +0 */ +0void RemoveFromDesktop(tmp_win) +0TwmWindow *tmp_win; +0{ +0 int x, y; +0 +0 if (!Scr->Virtual) +0 return; +0 +0 /* +0 if (tmp_win->VirtualDesktopDisplayWindow) +0 XUnmapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow); +0 */ +0 /* reparent its representation out of the real screen window */ +0 x = tmp_win->virtual_frame_x /Scr->VirtualDesktopDScale; +0 y = tmp_win->virtual_frame_y / Scr->VirtualDesktopDScale; +0/* RFB 4/92 no SCALE_D */ +0 /* x = SCALE_D(tmp_win->virtual_frame_x); */ +0 /* y = SCALE_D(tmp_win->virtual_frame_y); */ +0 +0 XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow, +0 Scr->VirtualDesktopDisplay, x, y); +0} +#endif /* 0, Stig */ + +/* Stig Ostholm + * Nail/unnail a window on the desktop display. + */ +void NailDesktop(tmp_win) +TwmWindow *tmp_win; +{ + int x, y; + + if (!tmp_win->VirtualDesktopDisplayWindow + || !Scr->Virtual + || tmp_win->icon) + return; + + GetDesktopWindowCoordinates(tmp_win, &x, &y, (int *) 0, (int *) 0); + XReparentWindow(dpy, tmp_win->VirtualDesktopDisplayWindow, + (tmp_win->nailed) + ? Scr->VirtualDesktopDScreen + : Scr->VirtualDesktopDisplay, + x, y); + XMapWindow(dpy, tmp_win->VirtualDesktopDisplayWindow); +} + +/* + * state during the move + */ +static unsigned int moving_x, moving_y, moving_w, moving_h, moving_bw; +static unsigned int moving_off_x, moving_off_y; +Window moving_window; +TwmWindow *moving_twindow; + +/**********************************************************/ +/* */ +/* RFB 7/16/93 -- moved these static variables up to */ +/* this part of the file so that I could use moving_bw */ +/* in DisplayScreenOnDesktop(). */ +/* */ +/* Note that moving_bw is set to 0 if you clicked *in* */ +/* the window; therefore it can only have a non-zero */ +/* value if you clicked at a random location in the */ +/* panner, making the RealScreen jump to the pointer, */ +/* AND you also had RealScreenBorderWidth set. */ +/* */ +/* This is almost the final step in getting the panner */ +/* to behave pefectly! It still jitters a bit at the */ +/* edges... */ +/* */ +/**********************************************************/ + +/* + * correctly position the real screen representation on the virtual desktop display + */ +void DisplayScreenOnDesktop() +{ + int border; + + if (!Scr->Virtual) + return; + +/* djhjr - 2/15/99 + border = ( Scr->UseRealScreenBorder ) ? moving_bw : 0; + moving_bw = 0; +*/ + border = moving_bw = 0; + + /* the -3 is to account for the 2 pixel border and the 1 pixel + * offset added by SCALE_D.... */ + XMoveWindow(dpy, Scr->VirtualDesktopDScreen, + Scr->VirtualDesktopX / Scr->VirtualDesktopDScale - border, + Scr->VirtualDesktopY / Scr->VirtualDesktopDScale - border + /* SCALE_D(Scr->VirtualDesktopX), */ /* - RFB changed 3 to 1 */ + /* SCALE_D(Scr->VirtualDesktopY) */ /* - RFB changed 3 to 1 */ + ); +/* 4/92 RFB -- simply use SCALE_D; well, no... +** the problem is that SCALE_D adds 1 if the result is 0, but +** just gives the right result otherwise. +*/ + + /* Way back, somebody wrote: */ + /* I've convinced myself that this is not necessary */ + /* XLowerWindow(dpy, Scr->VirtualDesktopDScreen); */ +} + +void ResizeDesktopDisplay(w, h) +int w, h; +{ + int bw, x, y, np; + + if (!Scr->Virtual) + return; + + + /* added compensation for the titlebar - djhjr - 2/23/99 */ + h -= Scr->VirtualDesktopDisplayTwin->title_height; + + /* added compensation for frame and bevel widths - djhjr - 2/7/99 */ + bw = Scr->VirtualDesktopBevelWidth * 2; + if (Scr->BorderBevelWidth) bw += Scr->BorderWidth * 2; + + np = 0; + if ( w - bw != Scr->VirtualDesktopMaxWidth ) + { Scr->VirtualDesktopMaxWidth = w - bw; + np = 1; + } + if ( h - bw != Scr->VirtualDesktopMaxHeight ) + { Scr->VirtualDesktopMaxHeight = h - bw; + np = 1; + } + if ( np ) + { XResizeWindow( dpy, Scr->VirtualDesktopDisplay, + Scr->VirtualDesktopMaxWidth, + Scr->VirtualDesktopMaxHeight ); + } + + /* calculate the new vd size */ + Scr->VirtualDesktopWidth = SCALE_U(w - bw); + Scr->VirtualDesktopHeight = SCALE_U(h - bw); + + x = SCALE_D(Scr->VirtualDesktopX); + y = SCALE_D(Scr->VirtualDesktopY); + + /* redraw it so that the real screen representation ends up on the display */ + np = SCALE_D(Scr->VirtualDesktopWidth) - SCALE_D(Scr->MyDisplayWidth); + if (x > np) + x = np; + + np = SCALE_D(Scr->VirtualDesktopHeight) - SCALE_D(Scr->MyDisplayHeight); + if (y > np) + y = np; + +#ifdef FUDGING + /* this is a bit of a fudge factor to account for the borderwidth */ + x -= 2; + y -= 2; +#endif /* FUDGING */ + + SetRealScreen(SCALE_U(x), SCALE_U(y)); + + /* done in setrealscreen now */ +#ifdef notdef + /* move the display window */ + XMoveWindow(dpy, Scr->VirtualDesktopDScreen, x - 1, y - 1); +#endif /* notdef */ +} + + +/* + * F_MOVESCREEN function + * move a window in the desktop display - possible including the `real' screen + */ +void StartMoveWindowInDesktop(ev) +XMotionEvent ev; +{ + int xoff, yoff; +#ifdef notdef + TwmWindow *Tmp_win; +#endif /* notdef */ + + if (!Scr->Virtual) + return; + + moving_window = ev.subwindow; + + if (!moving_window) + moving_window = Scr->VirtualDesktopDScreen; + + XGrabPointer(dpy, Scr->VirtualDesktopDisplayOuter, True, + ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, + GrabModeAsync, GrabModeAsync, + Scr->VirtualDesktopDisplay, Scr->NoCursor, CurrentTime); + + moving_x = ev.x; + moving_y = ev.y; + + /* djhjr - 4/27/98 */ + starting_x = ev.x; + starting_y = ev.y; + + /* find the window by looking at the context on the little window */ + if ((moving_window != Scr->VirtualDesktopDScreen) && + (XFindContext(dpy, moving_window, VirtualContext, + (caddr_t *) &moving_twindow) == XCNOENT)) { + /* i don't think that this should _ever_ happen */ + moving_window = None; + moving_twindow = NULL; + return; + } + + /* use Junk globals - djhjr - 4/28/98 */ + XGetGeometry(dpy, moving_window, &JunkChild, &xoff, &yoff, + &moving_w, &moving_h, &moving_bw, &JunkMask); + + moving_off_x = moving_off_y = 0; + if ( xoff <= moving_x && moving_x <= ( xoff + moving_w ) + && yoff <= moving_y && moving_y <= ( yoff + moving_h )) + { /* The pointer is IN the window. + ** don't start by moving the window so its upper-left is at + ** the cursor! RFB + */ + moving_off_x = xoff - moving_x; + moving_off_y = yoff - moving_y; + moving_bw = 0; + } + + /* djhjr - 4/28/98 */ + XMapRaised(dpy, Scr->SizeWindow); + InstallRootColormap(); + if (moving_window == Scr->VirtualDesktopDScreen) + JunkX = JunkY = 0; + else + { + XGetGeometry(dpy, moving_twindow->frame, &JunkChild, &JunkX, &JunkY, + &JunkWidth, &JunkHeight, &JunkBW, &JunkMask); + + /* djhjr - 9/28/99 */ + { + int hilite = moving_twindow->highlight; + + moving_twindow->highlight = True; + SetBorder(moving_twindow, (hilite) ? True : False); + moving_twindow->highlight = hilite; + + Scr->Focus = moving_twindow; /* evil */ + + EventHandler[EnterNotify] = HandleUnknown; + EventHandler[LeaveNotify] = HandleUnknown; + } + + /* djhjr - 10/2/02 */ + if (Scr->VirtualSendsMotionEvents && + (moving_window != Scr->VirtualDesktopDScreen && !moving_twindow->opaque_move)) + MoveOutline(Scr->Root, + JunkX, JunkY, + moving_twindow->frame_width, + moving_twindow->frame_height, + moving_twindow->frame_bw, + moving_twindow->title_height + moving_twindow->frame_bw3D); + + } + + /* added 'original_? = ' - djhjr - 11/3/03 */ + original_x = JunkX + Scr->VirtualDesktopX; + original_y = JunkY + Scr->VirtualDesktopY; + DisplayPosition(original_x, original_y); + + /* get things going */ + DoMoveWindowOnDesktop(ev.x, ev.y); +} + +void DoMoveWindowOnDesktop(x, y) +int x, y; +{ + if (!Scr->Virtual) + return; + + /* + * cancel the effects of scaling errors by skipping the code + * if nothing is actually moved - djhjr - 4/27/98 + */ + if (x == starting_x && y == starting_y) + return; + + /* djhjr - 2/7/99 */ + x -= Scr->VirtualDesktopBevelWidth; + y -= Scr->VirtualDesktopBevelWidth; + + x += moving_off_x; + y += moving_off_y; + /* check that we are legit */ + if (x < 0) + x = 0; + else { + + /* added real screen's border!? - djhjr - 2/15/99 */ + int np = ( Scr->VirtualDesktopWidth / + Scr->VirtualDesktopDScale ) - moving_w - + Scr->RealScreenBorderWidth * 2; + +/* RFB 4/92 no SCALE_D */ + if (x > np) + x = np; + } + if (y < 0) + y = 0; + else { + + /* added real screen's border!? - djhjr - 2/15/99 */ + int np = ( Scr->VirtualDesktopHeight / + Scr->VirtualDesktopDScale ) - moving_h - + Scr->RealScreenBorderWidth * 2; + +/* RFB 4/92 no SCALE_D */ + if (y > np) + y = np; + } + + moving_x = x; + moving_y = y; + + /* move the display window */ + /* removed '- moving_bw' - djhjr - 2/15/99 */ + XMoveWindow(dpy, moving_window, x/* - moving_bw*/, y/* - moving_bw*/); + + /* djhjr - 4/28/98 */ + DisplayPosition(SCALE_U(x), SCALE_U(y)); + +/* nah... it's pretty easy! - djhjr - 4/17/98 + * move the real window * + * this is very difficult on anything not very powerful * + * XMoveWindow(dpy, moving_twindow->frame, SCALE_U(x), SCALE_U(y)); * +*/ + if (Scr->VirtualSendsMotionEvents) + if (moving_window != Scr->VirtualDesktopDScreen) + { + if (moving_twindow->opaque_move) + XMoveWindow(dpy, moving_twindow->frame, + SCALE_U(x) - Scr->VirtualDesktopX, + SCALE_U(y) - Scr->VirtualDesktopY); + else + MoveOutline(Scr->Root, + SCALE_U(x) - Scr->VirtualDesktopX, + SCALE_U(y) - Scr->VirtualDesktopY, + moving_twindow->frame_width, + moving_twindow->frame_height, + moving_twindow->frame_bw, + moving_twindow->title_height + moving_twindow->frame_bw3D); + + /* djhjr - 9/28/99 */ + Scr->Focus = moving_twindow; /* evil */ + } +} + +void EndMoveWindowOnDesktop() +{ + if (!Scr->Virtual) + return; + + /* djhjr - 4/28/98 */ + XUnmapWindow(dpy, Scr->SizeWindow); + UninstallRootColormap(); + + if (moving_window == Scr->VirtualDesktopDScreen) { + /* added '(Cancel) ? ... :' - djhjr - 11/3/03 */ + SetRealScreen((Cancel) ? original_x : SCALE_U(moving_x),/* - moving_bw,*/ + (Cancel) ? original_y : SCALE_U(moving_y) /*- moving_bw*/ ); + } else { + /* djhjr - 4/17/98 10/2/02 */ + if (Scr->VirtualSendsMotionEvents && + (moving_window != Scr->VirtualDesktopDScreen && !moving_twindow->opaque_move)) + /* erase the move outline */ + MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); + + /* same little check as at the top of DoMoveWindowOnDesktop() - djhjr - 4/27/98 */ + if (moving_x != starting_x || moving_y != starting_y) + { + /* move the window in virtual space */ + /* added '(Cancel) ? ... :' - djhjr - 11/3/03 */ + moving_twindow->virtual_frame_x = + (Cancel) ? original_x : SCALE_U(moving_x); + moving_twindow->virtual_frame_y = + (Cancel) ? original_y : SCALE_U(moving_y); + + /* move it in real space */ + moving_twindow->frame_x = V_TO_R_X(moving_twindow->virtual_frame_x); + moving_twindow->frame_y = V_TO_R_Y(moving_twindow->virtual_frame_y); + + /* djhjr - 11/3/03 */ + if (Cancel) + XMoveWindow(dpy, moving_window, + SCALE_D(original_x), SCALE_D(original_y)); + + XMoveWindow(dpy, moving_twindow->frame, + moving_twindow->frame_x, moving_twindow->frame_y); + + /* notify the window */ + SendConfigureNotify(moving_twindow, + moving_twindow->frame_x, moving_twindow->frame_y); + } + + /* djhjr - 9/28/99 */ + { + int hilite = moving_twindow->highlight; + + moving_twindow->highlight = True; + SetBorder(moving_twindow, False); + moving_twindow->highlight = hilite; + + Scr->Focus = NULL; /* evil */ + + EventHandler[EnterNotify] = HandleEnterNotify; + EventHandler[LeaveNotify] = HandleLeaveNotify; + } + + /* added '!Cancel &&' - djhjr - 11/3/03 */ + if (!Cancel && !Scr->NoRaiseMove) { + XRaiseWindow(dpy, moving_twindow->frame); + XRaiseWindow(dpy, moving_twindow->VirtualDesktopDisplayWindow); + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + } + + /* djhjr - 6/4/98 */ + if (Scr->VirtualSendsMotionEvents && !moving_twindow->opaque_move) + { + XUnmapWindow(dpy, Scr->VirtualDesktopDisplay); + XMapWindow(dpy, Scr->VirtualDesktopDisplay); + } + + moving_window = None; + + return; + } + moving_window = None; + moving_twindow = NULL; +} + +/* Stig Ostholm + * move and resize a window on the desktop. + */ +void MoveResizeDesktop(tmp_win, noraise) +TwmWindow *tmp_win; +int noraise; +{ + int x, y, w, h; + + if (!tmp_win->VirtualDesktopDisplayWindow + || !Scr->Virtual + || tmp_win->icon) + return; + + GetDesktopWindowCoordinates(tmp_win, &x, &y, &w, &h); + /* Resize the desktop representation window */ + XMoveResizeWindow(dpy, tmp_win->VirtualDesktopDisplayWindow, + x, y, w, h); + if (!noraise) + XRaiseWindow(dpy, tmp_win->VirtualDesktopDisplayWindow); +} + +void SetVirtualDesktop(geom, scale) +char *geom; +int scale; +{ + + if (Scr->Virtual) { + twmrc_error_prefix(); + fprintf(stderr, "VirtualDesktop already defined -- ignored.\n"); + return; + } + + if (scale < 0) { + twmrc_error_prefix(); + fprintf(stderr, + "VirtualDesktop scale must be positive, not %d\n", scale); + return; + } + Scr->VirtualDesktopDScale = scale; + + JunkMask = XParseGeometry (geom, &JunkX, &JunkY, &JunkWidth, &JunkHeight); + + if ((JunkMask & (WidthValue | HeightValue)) != + (WidthValue | HeightValue)) { + twmrc_error_prefix(); + fprintf (stderr, "bad VirtualDesktop \"%s\"\n", geom); + return; + } + if (JunkWidth <= 0 || JunkHeight <= 0) { + twmrc_error_prefix(); + fprintf (stderr, "VirtualDesktop \"%s\" must be positive\n", geom); + return; + } + + /* + * More flexible way of selecting size of virtual desktop (ala tvtwm) + * M.J.E. Mol marcel@duteca.et.tudelft.nl + */ + if (JunkWidth > Scr->MyDisplayWidth) + /* specified as total pixels */ + JunkWidth /= Scr->VirtualDesktopDScale; + else if (JunkWidth*Scr->VirtualDesktopDScale < Scr->MyDisplayWidth) { + /* specified as number of physical screens */ + JunkWidth *= Scr->MyDisplayWidth; + JunkWidth /= Scr->VirtualDesktopDScale; + } + /* else specified as size of panner window */ + + if (JunkHeight > Scr->MyDisplayHeight) + /* specified as total pixels */ + JunkHeight /= Scr->VirtualDesktopDScale; + else if (JunkHeight*Scr->VirtualDesktopDScale < Scr->MyDisplayHeight) { + /* specified as number of physical screens */ + JunkHeight *= Scr->MyDisplayHeight; + JunkHeight /= Scr->VirtualDesktopDScale; + } + /* else specified as size of panner window */ + + /* tar@math.ksu.edu: fix handling of -0 X and Y geometry */ +/* account for VirtualDesktopBevelWidth - djhjr - 9/26/01 */ + if (JunkMask & XValue) { + if (JunkMask & XNegative) { + Scr->VirtualDesktopDX = Scr->MyDisplayWidth + - JunkWidth - (2 * Scr->BorderWidth) + - (2 * Scr->VirtualDesktopBevelWidth) + JunkX; + } + else Scr->VirtualDesktopDX = JunkX; + } + if (JunkMask & YValue) { + if (JunkMask & YNegative) { + Scr->VirtualDesktopDY = Scr->MyDisplayHeight + - JunkHeight - (2 * Scr->BorderWidth) + - (2 * Scr->VirtualDesktopBevelWidth) + JunkY; + } + else Scr->VirtualDesktopDY = JunkY; + } + + JunkWidth *= Scr->VirtualDesktopDScale; + JunkHeight *= Scr->VirtualDesktopDScale; + + /* check that the vd is at least as big as the screen */ +/* handled above, M.J.E. Mol +** if ((JunkWidth < Scr->MyDisplayWidth) +** || (JunkHeight < Scr->MyDisplayHeight)) +** { +** twmrc_error_prefix(); +** fprintf(stderr, +** "VirtualDesktop must be larger than screen (%dx%d)\n", +** Scr->MyDisplayWidth, Scr->MyDisplayHeight); +** return; +** } +*/ + Scr->VirtualDesktopWidth = JunkWidth; + Scr->VirtualDesktopHeight = JunkHeight; + + /* all of the values looked reasonable */ + Scr->Virtual = TRUE; +} + +void VirtualMoveWindow(t, x, y) +TwmWindow *t; +int x, y; +{ + if (!Scr->Virtual) + return; + + /* move window in virtual space */ + t->virtual_frame_x = x; + t->virtual_frame_y = y; + + /* move it in real space */ + t->frame_x = V_TO_R_X(x); + t->frame_y = V_TO_R_Y(y); + + XMoveWindow(dpy, t->frame, + t->frame_x, t->frame_y); + + /* update the display */ + /* UpdateDesktop(t); Stig */ + MoveResizeDesktop(t, FALSE); /* Stig */ + + if (!Scr->NoRaiseMove) { + XRaiseWindow(dpy, t->frame); + /* XRaiseWindow(dpy, t->VirtualDesktopDisplayWindow); Stig */ + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + } +} + +/* + * F_SNAP function + * for Kevin Twidle + * this snaps the real screen to a grid defined by the pandistance values. + */ +void SnapRealScreen() +{ + int newx, newy; + int mod, div; + + mod = Scr->VirtualDesktopX % Scr->VirtualDesktopPanDistanceX; + div = Scr->VirtualDesktopX / Scr->VirtualDesktopPanDistanceX; + + if (mod > (Scr->VirtualDesktopPanDistanceX / 2)) + newx = Scr->VirtualDesktopPanDistanceX * (div + 1); + else + newx = Scr->VirtualDesktopPanDistanceX * div; + + mod = Scr->VirtualDesktopY % Scr->VirtualDesktopPanDistanceY; + div = Scr->VirtualDesktopY / Scr->VirtualDesktopPanDistanceY; + + if (mod > (Scr->VirtualDesktopPanDistanceY / 2)) + newy = Scr->VirtualDesktopPanDistanceY * (div + 1); + else + newy = Scr->VirtualDesktopPanDistanceY * div; + + SetRealScreenInternal(newx, newy, FALSE, NULL, NULL); /* DSE */ +} + + +void SetRealScreen(x, y) +int x, y; +{ + if (Scr->snapRealScreen) + SetRealScreenInternal(x, y, TRUE, NULL, NULL); /* DSE */ + else + SetRealScreenInternal(x, y, FALSE, NULL, NULL); /* DSE */ +} + +/* + * handles the possibility of snapping + */ +void SetRealScreenInternal(x, y, dosnap, dx, dy) +int x, y; +int *dx, *dy; /* a pointer to an integer that contains the value + (AutoPanBorderWidth + AutoPanExtraWarp) is passed in to + both dx and dy when autopanning, or NULL is passed. On + return, the value is modified to store how much the pointer + should actually be warped, in case + AutoPanWarpWithRespectToRealScreen is nonzero. -- DSE */ +short dosnap; +{ + int xdiff, ydiff; + TwmWindow *Tmp_win; + + /* check bounds */ + if (x < 0) x = 0; + if (y < 0) y = 0; + if (x > (Scr->VirtualDesktopWidth - Scr->MyDisplayWidth)) + x = Scr->VirtualDesktopWidth - Scr->MyDisplayWidth; + if (y > (Scr->VirtualDesktopHeight - Scr->MyDisplayHeight)) + y = Scr->VirtualDesktopHeight - Scr->MyDisplayHeight; + + /* if ( Scr->RealScreenBorderWidth ) */ + /* { x -= 2; */ + /* y -= 2; */ + /* } */ + + /* how big a move is this ? */ + xdiff = Scr->VirtualDesktopX - x; + ydiff = Scr->VirtualDesktopY - y; + + { + /* calculate how much we might warp the pointer */ + int x_warp = ((xdiff<0) ? -1 : 1) * + ((50 + abs(xdiff) * Scr->AutoPanWarpWithRespectToRealScreen) / 100); + int y_warp = ((ydiff<0) ? -1 : 1) * + ((50 + abs(ydiff) * Scr->AutoPanWarpWithRespectToRealScreen) / 100); + + /* make sure the pointer warps enought with respect to the real screen + so that it can get out of the autopan windows. */ + if (dx) + if ( abs (*dx) < abs(x_warp) ) *dx = x_warp; + if (dy) + if ( abs (*dx) < abs(y_warp) ) *dy = y_warp; + } + + /* make sure it isn't warped too much in case ``AutoPan 100'' and + ``AutoPanWarpWithRespectToRealScreen 100'' (also known as + ``NaturalAutopanBehavior'') are set. -- DSE */ + { + int max_x_warp = ((xdiff<0) ? -1 : 1) * + (Scr->MyDisplayWidth - 2 * Scr->AutoPanBorderWidth); + int max_y_warp = ((ydiff<0) ? -1 : 1) * + (Scr->MyDisplayHeight - 2 * Scr->AutoPanBorderWidth); + if (dx) + if ( abs(*dx) > abs(max_x_warp) ) *dx = max_x_warp; + if (dy) + if ( abs(*dy) > abs(max_y_warp) ) *dy = max_y_warp; + } + + /* move all of the windows by walking the twm list */ + for (Tmp_win = Scr->TwmRoot.next; Tmp_win != NULL; Tmp_win = Tmp_win->next) + { + if (Scr->StaticIconPositions && Tmp_win->icon && Tmp_win->icon_w) + { + /* + * Make icons "stay put" on the virtual desktop when + * not otherwise nailed - djhjr - 12/14/98 + */ + XGetGeometry(dpy, Tmp_win->icon_w, &JunkRoot, &JunkX, &JunkY, + &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth); + + XMoveWindow(dpy, Tmp_win->icon_w, + JunkX + xdiff, JunkY + ydiff); + } + + if (Tmp_win->nailed || (Scr->DeIconifyToScreen && Tmp_win->icon)) + { + /* + * The window is nailed or... + * The window is currently an icon, we are trying to + * keep things on the screen, so move it around the + * virtual desktop so that it stays on the real screen + */ + Tmp_win->virtual_frame_x -= xdiff; + Tmp_win->virtual_frame_y -= ydiff; + } + else + { + /* + * move the window + */ + Tmp_win->frame_x += xdiff; + Tmp_win->frame_y += ydiff; + + if (!dosnap) + { + XMoveWindow(dpy, Tmp_win->frame, + Tmp_win->frame_x, Tmp_win->frame_y); + SendConfigureNotify(Tmp_win, + Tmp_win->frame_x, Tmp_win->frame_y); + } + } + } + + Scr->VirtualDesktopX = x; + Scr->VirtualDesktopY = y; + + if (dosnap) + SnapRealScreen(); + else + DisplayScreenOnDesktop(); +} + +/* + * pan the real screen on the virtual desktop by (xoff, yoff) + */ +void PanRealScreen(xoff, yoff, dx, dy) +int xoff, yoff; +int *dx, *dy; /* DSE */ +{ + /* panning the screen can never mean that you need to snap */ + SetRealScreenInternal(Scr->VirtualDesktopX + xoff, Scr->VirtualDesktopY + yoff, +/* why not? - djhjr - 1/24/98 + FALSE, dx, dy); +*/ + Scr->snapRealScreen, dx, dy); + /* DSE */ +} + +/* + * raise the auto-pan windows if needed + */ + +void RaiseAutoPan() +{ + int i; + if (Scr->AutoPanX > 0) + for (i = 0; i <= 3; i++) + XRaiseWindow(dpy, Scr->VirtualDesktopAutoPan[i]); +} + +/* + * Raise sticky windows if StickyAbove is set. -- DSE + */ + +void RaiseStickyAbove () { + if (Scr->StickyAbove) { + TwmWindow *Tmp_win; + for (Tmp_win = Scr->TwmRoot.next; Tmp_win != NULL; + Tmp_win = Tmp_win->next) + if (Tmp_win->nailed) { + XRaiseWindow(dpy,Tmp_win->w); + XRaiseWindow(dpy,Tmp_win->VirtualDesktopDisplayWindow); + XRaiseWindow(dpy,Tmp_win->frame); + } + } +} + +/* + * Lower sticky windows. -- DSE + */ + +void LowerSticky () { + TwmWindow *Tmp_win; + for (Tmp_win = Scr->TwmRoot.next; Tmp_win != NULL; + Tmp_win = Tmp_win->next) + if (Tmp_win->nailed) { + XLowerWindow(dpy,Tmp_win->w); + XLowerWindow(dpy,Tmp_win->VirtualDesktopDisplayWindow); + XLowerWindow(dpy,Tmp_win->frame); + } +} + diff --git a/desktop.h b/desktop.h new file mode 100644 index 0000000..5e61487 --- /dev/null +++ b/desktop.h @@ -0,0 +1,61 @@ +/* + * $Id: desktop.h,v 3.0 90/11/20 16:13:13 dme Exp Locker: dme $ + * + * Copyright (c) 1990 Dave Edmondson. + * Copyright (c) 1990 Imperial College of Science, Technoology & Medicine + * All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Dave Edmondson or Imperial College + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Dave Edmondson and + * Imperial College make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +extern Window moving_window; /* indicates that we are doing a move in the vd display */ + +extern void CreateDesktopDisplay(); +extern void UpdateDesktop(); +/* extern void RemoveFromDesktop(); */ +extern void MoveResizeDesktop(); +extern void NailDesktop(); + +extern void DisplayScreenOnDesktop(); +extern void StartMoveWindowInDesktop(); +extern void StartMoveWindowOnDesktop(); +extern void EndMoveWindowOnDesktop(); +extern void DoMoveWindowOnDesktop(); +extern void ResizeDesktopDisplay(); +extern void VirtualMoveWindow(); +extern void SnapRealScreen(); +extern void SetRealScreen(); +extern void PanRealScreen(); +extern void RaiseStickyAbove(); /* DSE */ +extern void LowerSticky(); /* DSE */ +extern void RaiseAutoPan(); + +/* convert real space to virtual space */ +#define R_TO_V_X(x) ((x) + Scr->VirtualDesktopX) +#define R_TO_V_Y(y) ((y) + Scr->VirtualDesktopY) + +/* convert virtual space to real space */ +#define V_TO_R_X(x) (-(Scr->VirtualDesktopX - (x))) +#define V_TO_R_Y(y) (-(Scr->VirtualDesktopY - (y))) + +/* scale up and down from desktop display to real sizes */ +/* #define SCALE_D(x) (((x)/Scr->VirtualDesktopDScale)+1) */ +/* don't pass me something like `x++' - please */ +#define SCALE_D(x) ((((x)/Scr->VirtualDesktopDScale) < 1) ? 1 : (x)/Scr->VirtualDesktopDScale) +#define SCALE_U(x) ((x)*Scr->VirtualDesktopDScale) + +/* how wide/high the autopan windows are */ +#define AP_SIZE (Scr->AutoPanBorderWidth) /* DSE */ + +/* djhjr - 5/19/98 */ +#define VTWM_DESKTOP_CLASS "VTWM Desktop" + diff --git a/doc/.vtwmrc-marcel b/doc/.vtwmrc-marcel new file mode 100644 index 0000000..01e457b --- /dev/null +++ b/doc/.vtwmrc-marcel @@ -0,0 +1,754 @@ +############################################################ +## ## +## Fri Jul 30 14:37:25 EDT 1993 ## +## ## +## I am including this vtwmrc in the distribution ## +## because it is so incredibly well organized and shows ## +## the differences between twm, vtwm, and tvtwm. ## +## ## +## As an example of what you can learn from this, the ## +## vtwm VirtualDesktopFont and the tvtwm VirtualFont ## +## both mean the same thing and *ought* to have the ## +## same name! ## +## ## +############################################################ + + + +#============================================================================= +# File: ~/.?twmrc V1.00 93/07/08 M.J.E. Mol +# marcel@duteca.et.tudelft.nl +# +# This file is read by the twm, vtwm or tvtwm Xwindow managers. +# + + +############################################################################ +# Font Section +############################################################################ +# +# TWM Fonts +# +# ResizeFont "fixed" # resize dimension indicator # "9x15" +ResizeFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +# IconManagerFont "6x12" #"variable" # "6x10" +IconManagerFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*" +# MenuFont "variable" # "6x10" "-*-helvetica-bold-r-normal--*-140-*-*-*-*-iso8859-1" +MenuFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +# TitleFont "variable" # "6x13" "6x10" +TitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +# +# VTWM Fonts +# +# DoorFont "6x10" # Needed to allow doors +DoorFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*" +VirtualDesktopFont "variable" +# +# TVTWM Fonts +# +#VirtualFont "variable" # 5x8 +#MenuTitleFont "-adobe-helvetica-bold-r-normal--*-140-*-*-*-*-*-*" + + +############################################################################ +# Variables Section +############################################################################ +# +# TWM Boolean Variables +# +AutoRelativeResize # Allow resize from any point within the window +ClientBorderWidth # Take border width from initial border width of window +DecorateTransients # Transient windows should have titlebars +DontMoveOff # Do not allow windows to be moved of the screen +# ForceIcons # Force use of "Icons" list instead of client-supplied one +# InterpolateMenuColors # Gradually changing menu colors +# NoBackingStore # Backing store for twm's menus +NoCaseSensitive # For sorting icon names in icon manager +# NoDefaults # Needed when building own title buttons and bindings +NoGrabServer # When popping up menus or moving opaque windows +# NoIconManagers # Don't create icon managers +# NoMenuShadows # Don't draw drop shadows behind menus +# NoRaiseOnDeiconify # Don't automatically raise windows on de-iconify +# NoRaiseOnMove # Don't automatically raise when windows are moved +# NoRaiseOnResize # Don't automatically raise when windows are resized +# NoRaiseOnWarp # Don't automatically raise window when f.warpto +# NoSaveUnders # Repaint instead of save-under for menu selection +# NoTitleFocus # Don't set input focus when window is entered +# OpaqueMove # F.move window instead of just an outline +# RandomPlacement # Don't give ouline-drag for no-geometry windows +RestartPreviousState # 'Remember' previous state when window manager is restarted +ShowIconManager # Show icon manager on startup +# SortIconManager # Sort icons alphabetically in iconmanager +WarpUnmapped # Allow f.warpto to de-iconify windows + +# +# VTWM Boolean Variables +# +# DeiconifyToScreen # De-iconifying puts window on physical screen instead of old position +#NotVirtualGeometries # Geometries relative to screen, not over whole desktop +# SnapRealScreen # Snap to grid defined in PanDistanceX and PanDistanceY +# WarpWindows # move window to real screen instead of moveing real screen + +# +# TVTWM Boolean Variables +# +#PannerOpaqueScroll # Only useful when StickyAbove is set +#ShowVirtualNames # Give virtual desktop windows a name using VirtualFont +#StayUpMenus # Only select menuitems when they are pushed +#StickyAbove # Sticky windows will always be on top + +# +# TWM Numeric Variables +# +BorderWidth 2 # Frame border width in pixels +ButtonIndent 1 # 0, Title button indentation in pixels +ConstrainedMoveTime 400 # Time (msec) in which double click allows only move in hor or vert direction +FramePadding 2 # Pixelwidth between titlebar decorations and the window frame +IconBorderWidth 2 # Border of icons in pixels +MoveDelta 3 # Number of pixels to move before f.move starts working (also f.deltastop) +TitleButtonBorderWidth 1 # 0, Distance between title buttons +TitlePadding 8 # 16, Distance between title buttons, text and highlight area +# XorValue 1 # Outline color setter for move and resize +Zoom 16 # Iconify/de-iconfy outline show count + +# +# VTWM Numeric Variables +# +# AutoPan 5 # Pan when mouse is with % range of edge of screen +# AutoRaiseDelay 30000 # == RaiseDelay ? +# PanDistanceX 3? # Grid of screens for f.snap +# PanDistanceY 3? # Move real screan to closest grid location +RaiseDelay 3000 # Milliseconds to delay before AutoRaise/f.autoraise + +# +# TVTWM Numeric Variables +# +#PannerScale 20 # Scale of deskto panner to real screen +#ScrollDistanceX 100 # % scroll when scrolling in virtual desktop +#ScrollDistanceY 100 # % scroll when scrolling in virtual desktop +#TitleFontPadding 5 # pixels above window titles + +# +# TWM String Variables +# +# Path to look for bitmaps if they cannot be found in "bitmapFilePath" resource +# IconDirectory "/usr/include/X11/bitmaps" +# IconDirectory "/usr/include/X11/bitmaps:/usr/local/bitmaps/local" +# IconDirectory "/usr/local/X11/bitmaps" +IconDirectory "/usr/X386/lib/X11/xdtm/icons/small" +MaxWindowSize "30000x30000" +UnknownIcon "icon" # icon bitmap to use when no other found +UsePPosition "on" # program requested location, "on" "off" "nonzero" +# +# VTWM String Variables +# +# RealScreenPixmap "realscr.bm" # decorate virt. desktop realscreen (panner) +# VirtualBackgroundPixmap "something" # decoration for virtual desktop +# +# TVTWM String Variables +# +#PannerBackgroundPixmap "realscr.bm" # decoration of panner +#PannerGeometry "=100x250-0+0" +#PannerState "normal" # normal, iconic, withdrawn +#VirtualDesktop "3x2" +#VirtualDesktopBackgroundPixmap "something" # decoration for virtual desktop + +# +# TWM Complex Variables +# +IconManagerGeometry "=100x250-0+0" 1 # 1 column +# Define regions to put icons (multiple lines allowed) +# IconRegion geomstring # define geometry) +# vgrav # North or South fill direction +# hgrav # East for West fill direction +# gridwidth # grid dimensions to put icons in +# gridheight +IconRegion "=300x300+200-0" North East 30 30 + +# +# VTWM Complex Variables +# +#VirtualDesktop "150x100-0-0" 20 # Panner geometry and scale +VirtualDesktop "3x2-0-0" 20 # Panner geometry and scale + +# +# TWM List Variables +# + +Color { + # TWM Simple Color + DefaultBackground "white" # "maroon" Sizing and information windows + DefaultForeground "black" # "gray85" + MenuBackground "maroon" + MenuForeground "black" # "gray85" + MenuShadowColor "blue" + MenuTitleBackground "gray70" # "red" # f.title color + MenuTitleForeground "maroon" # "black" + + # TWM Complex Color + BorderColor "LightGoldenRod" { #"slategrey" + "xterm" "red" + "seyon" "orange" + } + BorderTileBackground "white" { } # Unhighlighted window borders + BorderTileForeground "black" { } + IconBackground "maroon" { } # "white" black + IconBorderColor "black" { } # "gray85"white + IconForeground "black" { } # "gray85" white + IconManagerBackground "white" { } # "maroon" + IconManagerForeground "black" { } # "gray85" + IconManagerHighlight "blue" {"xterm" "red" "seyon" "orange"} + TitleBackground "sea green" {"xterm" "steelblue" "seyon" "brown"} + TitleForeground "white" { } # "gray85" + + # VTWM Simple Color + RealScreenBackground "orange" # virtual desktop realscreen indicator + RealScreenForeground "yellow" # needs RealScreenPixmap + VirtualBackground "green" + VirtualForeground "red" + + # VTWM Complex Color + DesktopDisplayBackground "pink" { } # color of windows in virtual desktop windows and in iconmanager + DesktopDisplayBorder "green" { } # border color of windows in virtual desktop window + DesktopDisplayForeground "white" { } # color of text in windows in virtual desktop window and iconmanager, needs VirtualDesktopFont + DoorBackGround "orange" { } + DoorForeGround "blue" { } + + # TVTWM Simple Color + #PannerBackground "yellow" + #PannerForeground "blue" + #VirtualDesktopBackground "steelblue" # Whole screen, + #VirtualDesktopForeground "black" # use with VirtualBackgroundPixm + + # TVTWM Complex Color + #VirtualBackground "orange" { } + #VirtualForeground "green" { } +} + +Monochrome { + # TWM Simple Color + DefaultBackground "white" + DefaultForeground "black" + MenuBackground "white" + MenuForeground "black" + MenuShadowColor "black" + MenuTitleBackground "white" # black, f.title color + MenuTitleForeground "black" # white + + # TWM Complex Color + BorderColor "black" { } + BorderTileBackground "white" { } + BorderTileForeground "black" { } + IconBackground "white" { } # black + IconBorderColor "black" { } # white + IconForeground "black" { } # white + IconManagerBackground "white" { } + IconManagerForeground "black" { } + IconManagerHighlight "black" { } + TitleBackground "black" { } + TitleForeground "white" { } + + # VTWM Simple Color + RealScreenBackground "black" # virtual desktop realscreen indicator + RealScreenForeground "white" # needs RealScreenPixmap + VirtualBackground "white" + VirtualForeground "black" + + # VTWM Complex Color + DesktopDisplayBackground "black" { } # color of windows in virtual desktop windows and in iconmanager + DesktopDisplayBorder "white" { } # border color of windows in virtual desktop window + DesktopDisplayForeground "white" { } # color of text in windows in virtual desktop window and iconmanager, needs VirtualDesktopFont + DoorBackGround "white" { } + DoorForeGround "black" { } + + # TVTWM Simple Color + #PannerBackground "black" + #PannerForeground "white" + #VirtualDesktopBackground "white" # Whole screen, + #VirtualDesktopForeground "black" # use with VirtualBackgroundPixm + + + # TVTWM Complex Color + #VirtualBackground "white" { } + #VirtualForeground "black" { } +} + +AutoRaise { # Auto raise windows + "XTerm" + "x" + "XV" + "Seyon" + "Post" + "emacs" + "Ghost" + "gv" + "gs" + # TVTWM VTWM + "Virtual Desktop" + "VTWM Icon Manager" + "TWM Icon Manager" + "Twm Door" +} + +Cursors { + # cursorname "string" for names in include/X11/cursorfont.h + # cursoname "image" "mask" for cursors taken from bitmap files + Frame "top_left_arrow" # "spider" + Title "top_left_arrow" + Icon "top_left_arrow" + IconMgr "top_left_arrow" + Move "fleur" + Resize "fleur" + Menu "sb_left_arrow" + Button "hand2" + Wait "watch" + Select "dot" + Destroy "pirate" + + # VTWM + Door "exchange" + Virtual "rtl_logo" + Desktop "dotbox" +} + +# DontIconifyByUnmapping { } # Iconify to icons instead of to icon manager +# IconifyByUnmapping { } # Don't try to map any icons. Remap through iconmanager, f.warpto or TwmWindows menu + +IconManagerDontShow { + "xclock" + "xload" + "xbiff" + "xmeter" + "xcb" + "Virtual Desktop" + "VTWM Icon Manager" + "TWM Icon Manager" + "Twm Door" +} + +IconManagers { # Definition of iconmanagers... + # "winname" ["iconname"] "geometry" columns + # "XTerm" "=300x5+800+5" 5 +} + +# IconManagerShow { } + +Icons { + # "XTerm" "xterm.icon" + "XTerm" "pixmap.xpm" + # "Seyon" "seyon.icon" +} + +# MakeTitle { } # Create title bars even when NoTitle has been specified + +NoHighLight { # i.e. not drawing borders in bordercolor +# "xclock" +# "xload" +# "xeyes" +# "xbiff" +# "xbehold" +# "xmeter" +# "oclock" +# "xcb" + "Virtual Desktop" + "VTWM Icon Manager" + "TWM Icon Manager" + "Twm Door" +} + +NoStackMode { } # ignore stacking request for these windows + +NoTitle { # don't show a titlebar for these windows + "XClock" +# "xclock" +# "xload" +# "xeyes" + "xbiff" +# "xbehold" +# "xmeter" +# "oclock" +# "xcb" + "Virtual Desktop" + "VTWM Icon Manager" + "TWM Icon Manager" + "Twm Door" +} + +NoTitleHighlight { } # don't highlight titlebar when focused in window + +Pixmaps { # "bitmapfile" + # TitleHighlight "gray1" + # VTWM + # RealScreenPixmap "something" + # VirtualBackgroundPixmap "something else" +} + +# SaveColor { } + +# titlebar is only as large as is needed for decorations +# { "name" left|center|right nominator denominator } +# SqueezeTitle { } + +DontSqueezeTitle { } # Don't make title bar as short a possible + +StartIconified { + "console" +} + +WarpCursor { # warp cursor in window when de-iconified + "xterm" + "seyon" + "nn" +} + +WindowRing { # windows to cycle through by f.warpring + "xterm" + "seyon" + "nn" +} + +# +# VTWM List Variables +# + +DontShowInDisplay { # Don't show in virtual desktop window + "xclock" + "XBiff" + # TVTWM VTWM + "TWM Windows" + "Virtual Desktop" + "VTWM Icon Manager" + "TWM Icon Manager" + "Twm Door" +} + +Doors { # remember to set DoorFont + # "winname" "location" "jumpTo" + "Home" "60x15+650+1" "+0+0" + "Screen 1" "60x15+710+1" "+1024+0" + "Screen 2" "60x15+770+1" "+2048+0" + "Screen 3" "60x15+650+16" "+0+1024" + "Screen 4" "60x15+710+16" "+1024+1024" + "Screen 5" "60x15+770+16" "+2048+1024" +} + +# NailedDown { # Keep on physical screen, see Sticky +Sticky { # synomym for naileddown + "xclock" + "xcb" + "Virtual Desktop" + "VTWM Icon Manager" + "TWM Icon Manager" + "Twm Door" +} + +# +# TVTWM List Variables +# +#IconTitle { } # Give titles to icons, even when NoIconTitle is set +#NoIconTitle { } # Give titles to icons, even when NoIconTitle is set + +# +# Put these two in at end of variable section, before bindings section +# +DefaultFunction f.beep # for non-bound keys or buttons +# WindowFunction f.deiconify # function to perform when window is selected from "TwmWindows" menu + + +###################################################################### +# End of Variable Section +###################################################################### + + +# Functions ... +# f.circledown +# f.circleup + +# f.deiconify + + +# f.saveyourself FKEYWORD F_SAVEYOURSELF +# f.setrealscreen FSKEYWORD F_SETREALSCREEN +# f.snap FKEYWORD F_SNAP +# f.snugdesktop FKEYWORD F_SNUGDESKTOP +# f.snugwindow FKEYWORD F_SNUGWINDOW + +# f.nexticonmgr FKEYWORD F_NEXTICONMGR +# f.previconmgr FKEYWORD F_PREVICONMGR + +# f.warptoiconmgr FSKEYWORD F_WARPTOICONMGR +# f.warptoscreen FSKEYWORD F_WARPTOSCREEN + + + +###################################################################### +# Titlebuttons +###################################################################### +# bitmaps are stored in /usr/include/X11/bitmaps +# ":bitmap" uses internal bitmap +# (:dot, :xlogo, :iconify, :resize, :question, :delete, :menu) +#--------------------------------------------------------------------- +RightTitleButton ":menu" = f.menu "WindowSettings" +RightTitleButton ":iconify" = f.iconify +RightTitleButton "jpzoom" = f.zoom +LeftTitleButton ":xlogo" = f.menu "XSettings" + +###################################################################### +# Button/key bindings +###################################################################### +# Button = KEYS : CONTEXT : FUNCTION +# Keys can be m (meta) s (shift) c (control) l (lock) m1-5 (meta1-meta5) +# Context can be window, title, icon, root, frame, virtual, desktop, door, +# iconmgr, all +#--------------------------------------------------------------------- +Button1 = : root : f.menu "Applications" +Button2 = : root : f.menu "WindowManager" +Button3 = : root : f.menu "Rlogins" +Button1 = : door : f.enterdoor +Button1 = : title|icon|iconmgr : f.function "move-or-raise" #f.raise +Button2 = : title : f.move +Button2 = : icon | iconmgr : f.iconify +Button3 = : title|icon|iconmgr : f.function "focus_and_raise" +Button1 = c : door : f.deletedoor +Button1 = s : all : f.menu "Applications" +Button2 = s : title | window : f.move +# Don't want to define next: idraw uses that button... +#Button3 = s : all : f.menu "Applications" +Button1 = m : all : f.menu "WindowSettings" +Button2 = m : title | window : f.forcemove +Button3 = m : title | icon | iconmgr : f.lower +#Button1 = m : window | icon : f.function "move-or-lower" +#Button2 = m : window | icon : f.iconify +#Button3 = m : window | icon : f.function "move-or-raise" +#Button2 = : title : f.raiselower +#Button1 = : icon : f.function "move-or-iconify" + +#"F1" = : all : f.iconify +"F2" = : all : f.function "xvi" +#"F2" = : all : f.raiselower +#"F3" = : all : f.warpring "next" +#"F4" = : all : f.warpto "xmh" +#"F5" = : all : f.warpto "emacs" +"F6" = : title | window : f.iconify +#"F6" = : all : f.colormap "next" +#"F7" = : all : f.colormap "default" +"F9" = : all : f.warpto "idraw" +"F10" = : all : f.warpring "next" +"F11" = : all : f.warpring "prev" +"F14" = : all : f.function "xlock" +#"F20" = : all : f.warptoscreen "next" + +"Delete" = m c : title | window : f.destroy + +"Left" = : iconmgr : f.lefticonmgr # f.backiconmgr +"Right" = : iconmgr : f.righticonmgr # f.forwiconmgr +"Down" = : iconmgr : f.downiconmgr +"Up" = : iconmgr : f.upiconmgr +"Left" = m : all : f.backiconmgr +"Right" = m : all : f.forwiconmgr +"Up" = m : all : f.upiconmgr +"Down" = m : all : f.downiconmgr +# +# VTWM Desktop Scroll +# +"Left" = : root : f.panleft "100" +"Right" = : root : f.panright "100" +"Up" = : root : f.panup "100" +"Down" = : root : f.pandown "100" +"Left" = s : all : f.panleft "100" +"Right" = s : all : f.panright "100" +"Up" = s : all : f.panup "100" +"Down" = s : all : f.pandown "100" +# +# TVTWM Desktop Scroll +# +#"Left" = : root : f.scrolleft +#"Right" = : root : f.scrollright +#"Up" = : root : f.scrollup +#"Down" = : root : f.scrolldown +#"Left" = s : all : f.scrolleft +#"Right" = s : all : f.scrollright +#"Up" = s : all : f.scrollup +#"Down" = s : all : f.scrolldown + + +# +# Fuctions defined for Buttons +#--------------------------------------------------------------------- +Function "focus_and_raise" { f.focus f.raise } +Function "xlock" { !"xlock -mode swarm -font '8x13' &" } +Function "xvi" { !"xvi &" } +Function "move-or-lower" { f.move f.deltastop f.lower } +Function "move-or-raise" { f.move f.deltastop f.raise } +Function "move-or-iconify" { f.move f.deltastop f.iconify } +Function "restore-colormap" { f.colormap "default" f.lower } + + +###################################################################### +# Menus +###################################################################### +# (default font and geometry for "xterm" are defined in ~/.Xdefaults) +#--------------------------------------------------------------------- + +menu "Applications" { + "Applications" ("black":"yellow") f.title + "Lock" f.function "xlock" + "Xterm" !"xterm -geometry =80x24 &" + "nn" ("black":"yellow") !"xnn &" + "" f.nop + "Misc. Appl." f.menu "MiscAppl" + "Window Manager" f.menu "WindowManager" + "XSettings" f.menu "XSettings" + "WindowSettings" ("black":"cyan") f.menu "WindowSettings" + "TWM Windows" f.menu "TWM Windows" + "TwmWindows" f.menu "TwmWindows" + "Rlogins" f.menu "Rlogins" + "Colors" f.menu "Colors" + "Xterms" ("white":"green") f.menu "Xterms" + "File" f.file "/vtwm.file" +} + +menu "WindowManager" { + "Window Manager" f.title + "Refresh" f.refresh + "Refresh Desktop" f.resetdesktop + "Hide Icon Manager" f.hideiconmgr + "Show Icon Manager" f.showiconmgr + "Sort Icon Manager" f.sorticonmgr + "Hide Virtual Desktop" f.hidedesktopdisplay + "Show Virtual Desktop" f.showdesktopdisplay + "Toggle Virtual Geometries" f.virtualgeometries + "Create Door" f.newdoor + "Delete Door" f.deletedoor + "Focus on Root" f.unfocus + "Toggle Autopan" f.autopan + "Restart Twm" f.twmrc # f.restart + "TWM keys" !"xtwmkeys &" + "Backdrops" !"xsetbg `xfiles /usr/local/X11/local/bitmaps`&" + "Version" f.version + "Exit Twm" f.quit +} + +menu "WindowSettings" { + "Window Settings" ("black":"cyan") f.title + "Refresh" f.winrefresh + "AutoRaise" f.autoraise + "Raise" f.raise + "Lower" f.lower + "Focus" f.focus # f.unfocus + "Focus&Raise" f.function "focus_and_raise" + "Move" f.move + "ForceMove" f.forcemove + "Resize" f.resize + "Identify" f.identify + "Iconify" f.iconify + "Zoom" f.menu "Zoom" + "Toggle in WarpRing" f.ring + "Toggle Nail" f.nail + "Squeeze Title Center" f.squeezecenter + "Squeeze Title Left" f.squeezeleft + "Squeeze Title Right" f.squeezeright + "Quit" f.delete + "Destroy" f.destroy +} + +menu "Zoom" { + "FullZoom" f.fullzoom + "LeftZoom" f.leftzoom # f.vlzoom + "RightZoom" f.rightzoom # f.vrzoom + "TopZoom" f.topzoom # f.htzoom + "BottomZoom" f.bottomzoom # f.hbzoom + "VerticalZoom" f.zoom + "HorizontalZoom" f.horizoom # f.hzoom +} + +menu "MiscAppl" { + "Misc. Appl." f.title + "" f.nop +# "nn" ("black":"yellow") !"xnn &" +# "idraw" !"idraw &" + "calc" !"xcalc -rv &" +# "news" !"xrn &" + "man" !"xman &" + "fonts" !"xfbrows &" +# "archie" !"xarchie &" + "bricks" !"xsetroot -bitmap /usr/local/X11/local/bitmaps/wall.xbm&" +# "swarm" !"xswarm &" + "clock" !"xclock &" + "biff" !"xbiff &" + "load" !"xload &" +# "vi" f.function "xvi" +} + +menu "XSettings" { + "XSettings" f.title + "" f.nop + "Bell Loud" !"xset b 100&" + " Normal" !"xset b 50&" + " Off" !"xset b off&" + " High" !"xset b 50 880&" + " Medium" !"xset b 50 440&" + " Low" !"xset b 50 220&" + "Click Loud" !"xset c 80&" + " Normal" !"xset c 40&" + " Off" !"xset c off&" + "Lock On" !"xset l on&" + " Off" !"xset l off&" + "Mouse Fast" !"xset m 4 2&" + " Normal" !"xset m 2 5&" + " Slow" !"xset m 1 1&" +} + +menu "Colors" { + "Colors" f.title + "Next" f.colormap "next" + "Previous" f.colormap "prev" + "Default" f.colormap "default" +} + +# xterm-options: +# The "-name" specifies the name that applies to resources in ~/.Xdefaults +# The "-n" specifies the name that appears in the icon +# The "-title" or "-T" specifies the name that appears in the titlebar +# icon-name and title are default set to the name of the executable (i.e. +# "xterm") or set to the name of the executable after the "-e" option or +# set to the name after the "-name" option + +menu "Xterms" { + "Xterms" f.title + "" f.nop + "xterm -fn 6x13" !"xterm -fn 6x13 -geometry =80x24 &" + "xterm -fn 8x13" !"xterm -fn 8x13 -geometry =80x24 &" + "xterm -fn 9x15" !"xterm -fn 9x15 -geometry =80x24 &" +} + +menu "Rlogins" { + "Rlogins" f.title + "Local" !"xterm -T `hostname` &" + "" f.nop + "baldrick" ("black":"green") !"xterm -T baldrick -e rlogin baldrick &" + "bean" ("black":"green") !"xterm -T bean -e rlogin bean &" + "percy" ("black":"green") !"xterm -T percy -e rlogin percy &" + "" f.nop + "SUN4s" f.menu "SUN4s" + "SUN3s" f.menu "SUN3s" + "" f.nop + "Telnet" ("black":"yellow") !"xterm -name telnet -e telnet &" +} + +menu "SUN4s" { + "SUN4s" f.title + "" f.nop + "baldrick" ("black":"green") !"xterm -T baldrick -e rlogin baldrick &" + "bean" ("black":"green") !"xterm -T bean -e rlogin bean &" +} + +menu "SUN3s" { + "SUN3s" f.title + "" f.nop + "percy" ("black":"green") !"xterm -T percy -e rlogin percy &" + "darling" ("black":"green") !"xterm -T darling -e rlogin darling &" + "bob" ("black":"green") !"xterm -T bob -e rlogin bob &" +} + + diff --git a/doc/1.README b/doc/1.README new file mode 100644 index 0000000..a0c1a7f --- /dev/null +++ b/doc/1.README @@ -0,0 +1,45 @@ +This is based on vtwm-5.0.tar.Z, with the addition of all the +patches I know of except for the "dwim" patch. +The patch authors' names were added to the manual entry. + +It also includes my own enhancements, of course. + +Although many files are unchanged from vtwm-5.0.tar.Z, +I mean for this to supplant that version, so the next +person to take a swing at vtwm will start with my changes! + +There is no excuse for not including raisedelay and +dynamic squeezed titles and dynamic warpring in every +version of twm, including twm, vtwm, tvtwm, and ctwm. +These are essential features. + +RealScreen colors and bitmap are useful. +A sample realscreen.bm file is included. + +Colored entries in the TWM-Windows menu are nice to have. +Being able to turn autopan off and on at will is also handy. + +I rarely use the "snug" functions. + +Panner foreground and bitmap are superseded by my "nexpm" +program: see the nexpm directory for details. + +============================================================ +== == +== TWO EXTRAS INCLUDED == +== == +============================================================ + +The nexpm directory contains a program that decorates +your panner window. + +The vtwmrc directory contains a makefile and scripts that help +maintain the colorlists in your .vtwmrc + +======== + +vtwm has no maintainer, as far as I know. + +Now I am finished with vtwm; somebody else can take a turn next. + +Fri Jun 25 12:20:38 EDT 1993 diff --git a/doc/2.1.ANNOUNCE b/doc/2.1.ANNOUNCE new file mode 100644 index 0000000..7d48412 --- /dev/null +++ b/doc/2.1.ANNOUNCE @@ -0,0 +1,74 @@ +From comp.windows.x Sat Oct 9 17:02:14 1993 +Xref: netnews.louisville.edu comp.windows.x.announce:212 comp.windows.x:53876 +Newsgroups: comp.windows.x.announce,comp.windows.x +Path: netnews.louisville.edu!starbase.spd.louisville.edu!dsembr01 +From: Darren S. Embry +Subject: ANNOUNCING the release of vtwm 5.2.1 +Originator: dsembr01@terra.spd.louisville.edu +Sender: news@netnews.louisville.edu (Netnews) +Message-ID: +Date: Wed, 6 Oct 1993 20:46:34 GMT +Reply-To: dsembr01@starbase.spd.louisville.edu +Nntp-Posting-Host: terra.spd.louisville.edu +Organization: University of Louisville Speed Scientific School + +I am announcing the (unofficial) release of vtwm version 5.2.1. It's +available at: + + ftp.x.org:/contrib/vtwm-5.2.1.tar.gz + +As far as changes from version 5.2 to version 5.2.1 go, they are mostly a few +aesthetic and look-and-feel hacks and a couple of bug fixes. + +I would really like input as to how you like the changes I made. + +-- Darren S. Embry, dsembr01@starbase.spd.louisville.edu + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + MINOR NEW FEATURE (I can't say it's a big deal) + ----------------------------------------------- + Natural Autopan Behavior + + By default, when autopanning, the pointer is warped by only + (AutoPanBorderWidth + AutoPanExtraWarp) pixels on the real + screen. With this option turned on, the pointer is warped by as + many pixels as the screen is scrolled, or by the above number of + pixels, whichever is greater. Thus, the pointer will not + actually move very much (only by AutoPanExtraWarp) in relation to + the virtual desktop. This works very well on faster X terminals, + although I can't say the same thing for slower ones (but setting + AutoPanWarpWithRespectToRealScreen may do a good job). + + NEW VARIABLES to play around with + --------------------------------- + AutoPanBorderWidth + AutoPanExtraWarp + AutoPanWarpWithRespectToRealScreen + EnhancedExecResources + LessRandomZoomZoom + NaturalAutopanBehavior + # synonymous with ``AutoPanWarpWithRespectToRealScreen 100'' + PrettyZoom + RealScreenBorderWidth + RightHandSidePulldownMenus + + OTHER HACKS AND BUG FIXES + ------------------------- + Supports negative and `0,0' door geometries. [ bug fix ] + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +DISCLAIMER: I am not the official maintainer or central programmer of vtwm, +but there isn't one anyway; I just made a few bug fixes, played with the code +to make it a little bit more `configurable' in certain areas, and decided to +see what *you* think of the changes I made. I also don't know much about X +programming, but the changes I made to vtwm haven't caused any major damage +so far. + +-- + letitflowletyourselfgos[ darren s. embry ]lowandlowthatisthetempo + [ dsembr01@starbase ] +beingashamedbecauseyouredif[ .spd.louisville.edu ]ferentisthesickestkindoflie + + diff --git a/doc/2.1.README b/doc/2.1.README new file mode 100644 index 0000000..aede518 --- /dev/null +++ b/doc/2.1.README @@ -0,0 +1,95 @@ +As far as changes from version 5.2 to version 5.2.1 go, they are mostly a few +aesthetic and look-and-feel hacks and a couple of bug fixes. + +I would really like input as to how you like the changes I made. + +-- Darren S. Embry, dsembr01@starbase.spd.louisville.edu + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + MINOR NEW FEATURE (I can't say it's a big deal) + ----------------------------------------------- + Natural Autopan Behavior + + By default, when autopanning, the pointer is warped by only + (AutoPanBorderWidth + AutoPanExtraWarp) pixels on the real + screen. With this option turned on, the pointer is warped by as + many pixels as the screen is scrolled, or by the above number of + pixels, whichever is greater. Thus, the pointer will not + actually move very much (only by AutoPanExtraWarp) in relation to + the virtual desktop. This works very well on faster X terminals, + although I can't say the same thing for slower ones (but setting + AutoPanWarpWithRespectToRealScreen may do a good job). + + NEW VARIABLES to play around with + --------------------------------- + AutoPanBorderWidth + AutoPanExtraWarp + AutoPanWarpWithRespectToRealScreen + EnhancedExecResources + LessRandomZoomZoom + NaturalAutopanBehavior + # synonymous with ``AutoPanWarpWithRespectToRealScreen 100'' + PrettyZoom + RealScreenBorderWidth + RightHandSidePulldownMenus + + OTHER HACKS AND BUG FIXES + ------------------------- + Supports negative and `0,0' door geometries. [ bug fix ] + +CHANGES BY SOURCE FILE +====================== + +Any lines, code or data structures in the code denoted by "/* DSE */" are +changes I made. + + desktop.c: + ---------- + Supports the RealScreenBorderWidth variable now. + + Added dx,dy parameters to SetRealScreenInternal and PanRealScreen so + that they pass information on how much to warp the mouse pointer, + to support my AutoPanWarpWithRespectToRealScreen hack. + + desktop.h: + ---------- + Define AP_SIZE to Scr->AutoPanBorderWidth instead of just 5. + + doors.c + ------- + Supports negative door geometries now (like "120x120-0-0"). + [ bug fix ] + + Also fixes bug that wouldn't allow "+0+0" to be a valid door + position. [ bug fix ] + + events.c + -------- + In HandleEnterNotify(), initial setting of xwarp and ywarp uses + AutopanExtraWarp instead of just 2. + + menus.c + ------- + The RightHandSidePulldownMenus, EnhancedExecResources, and PrettyZoom + hacks are done here. + + parse.c, screen.h + ----------------- + Of course, the new variables were inserted here. + + util.c + ------ + The LessRandomZoomZoom hack was done here. + +DISCLAIMER: I am not the official maintainer or central programmer of vtwm, +but there isn't one anyway; I just made a few fixes, played with the code to +make it a little bit more `configurable' in certain areas, and decided to see +what *you* think of the changes I made. I also don't know much about X +programming, but the changes I made to vtwm haven't caused any major damage +so far. + +-- + letitflowletyourselfgos[ darren s. embry ]lowandlowthatisthetempo + [ dsembr01@starbase ] +beingashamedbecauseyouredif[ .spd.louisville.edu ]ferentisthesickestkindoflie diff --git a/doc/2.2.README b/doc/2.2.README new file mode 100644 index 0000000..b9d7645 --- /dev/null +++ b/doc/2.2.README @@ -0,0 +1,15 @@ +Actually only one change from 5.2.1 to 5.2.2: A bug in my workaround from +5.2.1 regarding supporting negative door geometries has been fixed. I found +this bug by trying to use a +0+0 geometry; it didn't exactly work. + +DISCLAIMER: I am not the official maintainer or central programmer of vtwm, +but there isn't one anyway; I just made a few fixes, played with the code to +make it a little bit more `configurable' in certain areas, and decided to see +what *you* think of the changes I made. I also don't know much about X +programming, but the changes I made to vtwm haven't caused any major damage +so far. + +-- + letitflowletyourselfgos[ darren s. embry ]lowandlowthatisthetempo + [ dsembr01@starbase ] +beingashamedbecauseyouredif[ .spd.louisville.edu ]ferentisthesickestkindoflie diff --git a/doc/2.README b/doc/2.README new file mode 100644 index 0000000..945ff2e --- /dev/null +++ b/doc/2.README @@ -0,0 +1,120 @@ +Version 5.2 of vtwm is a community effort. My name is on it, +but I did less than half the work. There were contributors +from all around the world, every one of whom managed to +figure out how some piece of this program works and do a creditable +job of hacking it. A large number of people have touched this code, +and except for the part of the code that moves windows around, it's +still easily understandable and in terrific shape; this says a lot +about the X style of programming, and the kind of job done by Tom +LaStrange and Dave Edmondson. + +I'm not aware of any program, nor any release of a program, that so +fully embodies the ideal of community software. Perhaps that says a +lot about my ignorance, but ignorance is bliss, so don't enlighten +me. + +The only reason I published 5.1 was because I had a number of +changes that I wanted to see in the "official" vtwm, and had no +better way of getting them in there. + +After I did so, I heard from a number of people who seemed +to be in the same boat; because I needed to fix rescaling the +desktop and to add the UseRealScreenBorder and +OldFashionedTwmWindowsMenu variables ( some folks didn't like the +changes I made and wanted the old-style behavior to be at least +available to them :-( ), + +I agreed to collect patches and come out with a vtwm-5.2! + +Because I was playing with the code in any case, I added f.zoomzoom +and StayUpMenus, and made a big improvement in moving the windows +around in the panner. + + When you click on a window in the panner, it used to jump so + that its top-left corner would be at the pointer position. + Now, when you click inside the little windows, they don't jump; + they also don't jump when you release!, and moving them around + has become much more natural. + + I really like stayup menus, *but* it's kinda confusing to use, + because xterm, xpostit, and the like don't have this feature! + +Perhaps there will be a vtwm-5.3, but I do not plan to be involved, +at least not as the central figure. + +Here is a short list of the changes: + + New variables + StayUpMenus + OldFashionedTwmWindowsMenu + UseRealScreenBorder + + Modified Variables + WindowRing (window list optional) + VirtualDesktop (expanded syntax) + + New functions + f.zoomzoom + f.snaprealscreen + f.virtualgeometries + f.deletedoor + + Modified functions + f.move (can be bound to a keypress) + + Miscellaneous + smoother movement in panner + Allow #rrggbb colors in X11R4 + restored the ability to rescale the desktop + bug fixes + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!! !! +!! And here is the known bug: !! +!! !! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +If you invoke resize from a stayup menu or from a titlebar menu, it +moves the window and gets the wrong size. :-( + +This bug was also present in vtwm-5.0.tar.Z, but there was no such +bug in the X11R4 vtvwm.shar.Z + +As I found from putting in StayUpMenus, the movement and resize code +is quite messy; since I didn't create this bug, I will take the +coward's path, and decline to deal with it. (Actually, I wasted a +few hours looking through the code to try to find a clue, and *then* +I gave up.) + +Resizing by dragging the side of the window works quite well, +as does resizing from a non-stayup non-titlebar menu. + +=============================================== + +Supplementary files: + +marcel.vtwmrc is a remarkably-well organized vtwmrc, and it shows +exactly the differences between tvtwm and vtwm. I think it would be +nice if .tvtwmrc and .vtwmrc could be more similar, so perhaps some +of the variables and functions from tvtwm should be added (as +synonyms) to vtwm. + +nexpm is still there; the next release of xpm will presumably +include nexpm, however, and after that there will be no need to +package nexpm along with vtwm. + +============================================== + +Final note: + +Enjoy! + +-- +Ralph Betza (FM), +uunet!ssiny!gnohmon gnohmon@ssiny.com + +"The question of whether a computer can swim is more interesting + than the question of whether a submarine can think" - Lenny Dykstra + + + diff --git a/doc/3.FUTURE b/doc/3.FUTURE new file mode 100644 index 0000000..1061347 --- /dev/null +++ b/doc/3.FUTURE @@ -0,0 +1,9 @@ +NOW IT'S *YOUR* TURN! +===================== + + With this version I'm gonna quit for a while as the semester is just + about to start and I *probably* won't have enough time to fool with vtwm + anymore. If you're willing to work on the next version, just send me + email and I'll forward any mail I get concerning vtwm to you. I had + some real fun working with this thing. --- DSE + diff --git a/doc/3.README b/doc/3.README new file mode 100644 index 0000000..d9676ab --- /dev/null +++ b/doc/3.README @@ -0,0 +1,102 @@ +ANNOUNCEMENT +============ + +vtwm 5.3 is available now via anonymous ftp at: + + ftp.x.org:/contrib/vtwm-5.3.tar.gz + +A SUMMARY OF CHANGES FROM VTWM-5.2.2 TO VTWM-5.3 +================================================ + + The file `CHANGELOG' in the vtwm-5.3 archive contains more detailed info + concerning changes made since version 5.0. + + New Variables: + -------------- + DontInterpolateTitles (from tvtwm) + FixTransientVirtualGeometries (BUG WORKAROUND!!) + MenuTitleFont (from tvtwm) + NailedAbove (aliased to StickyAbove) + NoDefaultMouseAndKeyboardBindings + NoDefaultTitleButtons + NoIconifyIconManagers (from Paul Falstad) + StayUpOptionalMenus (from Paul Falstad) + StickyAbove (like the same feature in tvtwm) + WarpSnug + WarpToTransients (from Paul Falstad) + + New Functions: + -------------- + f.nail (aliased to f.stick) + f.stickyabove (or f.nailedabove) + f.warp (from Paul Falstad) + f.warpclassnext (from Paul Falstad) + f.warpclassprev (from Paul Falstad) + f.warptonewest (from Paul Falstad) + + Other New Features: + ------------------- + The window manager will now execute a special function called + "VTWM Profile" upon the initial startup or restarting of the window + manager. This may prove useful in certain situations. For example, + say you want AutoPan to have a value but you want autopanning + turned off initially: + + AutoPan 25 + . + . + + function "VTWM Profile" { + . + . + + f.autopan # turns it off (you can turn it back on later) + . + . + } + + The feature was created for this very specific purpose in mind, but + the possibilities are endless. + + Other fixes: + ------------ + autopanning (wouldn't work when mouse was over a window on the edge + of the screen sometimes) + nailed windows will *always* go on the real screen, wherever the real + screen is on the virtual desktop. + small fix of an obvious bug in the source regarding nailed windows' + representations on the virtual desktop + patches to Imakefile + + Undocumented functions now documented (please use these at your own risk): + -------------------------------------------------------------------------- + f.cut + f.cutfile + f.file + f.movescreen + f.twmrc [same thing as f.restart anyway] + f.version + +WHAT IS VTWM? +============= + + vtwm (which stands for `Virtual Tab Window Manager') is based upon the + twm window manager, but adds extra functionality in the form of a + VIRTUAL DESKTOP. The virtual desktop is an area larger than the + physical screen, where windows can be placed. On the real screen, a + portion of the virtual desktop the size of the real screen can be seen. + The `virtual desktop window', of course, facilitates navigation around + the desktop and manipulation of windows in the desktop. + +ACKNOWLEDGEMENTS +================ + + * Paul Falstad for f.warp, one of the things I + really wanted to see, among other related things. + * kudos to Chris P. Ross for letting me use some of + his code from tvtwm (MenuTitleFont and DontInterpolateTitles). + * Marty Leisner , small patches to Imakefile. + * Kaur for pointing out f.movescreen to me, and + inspiring me to look for other undocumented stuff and take a stab at + documenting it. + diff --git a/doc/4.4.ANNOUNCE b/doc/4.4.ANNOUNCE new file mode 100644 index 0000000..ab15873 --- /dev/null +++ b/doc/4.4.ANNOUNCE @@ -0,0 +1,30 @@ + +This is the announcement of VTWM 5.4.4, an upgrade of the recently released +VTWM 5.4. The web page, http://www.visi.com/~hawkeyd/vtwm.html, has been +updated, and the archive may be found via a link there, or directly via FTP +at ftp://ftp.visi.com in the /users/hawkeyd/X directory, and ftp://ftp.x.org +in the /contrib/window_managers directory (if and when they move it there +from the /incoming directory). + +The major changes, in a nutshell: + - Squashed two big bugs, involving pan distances and monochrome GCs, that + would crash VTWM. Many other nuisances exterminated, too. + - The border drawing code [finally] renders the top segment of the border + when using 3D squeezed titles, and now correctly renders small windows. + - Enabled a resource to go easy on colormap allocations. + - Added a resource for highlighting icon manager entries, independant of + the border highlighting resource. + - Simplified parameter enterpretation for SqueezeTitle list entries. + - The startup sequence now searches for user and system .vtwmrc files, + then user and system .twmrc files, in this order. + - Color image (XPM) support for icons. + - An up-to-date man page, and support for HTML and Postscript conversions. + - Many additions and fixes to improve portability and operability. + +For those that may not know, VTWM 5.4 is an update of the venerable window +manager that features a fully configurable 3D interface, as well as many +other bells, whistles, and, of course, bug fixes. + +D. J. Hawkey Jr. (hawkeyd@visi.com) +January 27, 1998 + diff --git a/doc/4.4.FUTURE b/doc/4.4.FUTURE new file mode 100644 index 0000000..c9861e8 --- /dev/null +++ b/doc/4.4.FUTURE @@ -0,0 +1,23 @@ + +I have written + "I do not want to be the maintainer of VTWM. I don't even think of myself + as an "X programmer", though I like it, and *I*am*learning*. I will + entertain comments, bug reports, etc., especially to my work, and will + try to respond in kind. I am not planning on further effort, as it now + fills my needs." +and + "It looks like, for the time being anyway, due to incoming mail, I am the + maintainer of VTWM." + +Well, most of the former has been proven false (though I still don't feel +I'm an "X programmer", I am indeed learning), and the latter seems to be +holding true. Whether I want to be the ersatz maintainer doesn't matter, +really, as I'm having a jolly good time doing so! + +I think I can say VTWM definitely has a future. I'll likely continue to +play a part, at least until a few more points in the WISHLIST file are +knocked off. + +D. J. Hawkey Jr. (hawkeyd@visi.com) +January 18, 1998 + diff --git a/doc/4.4.README b/doc/4.4.README new file mode 100644 index 0000000..8e438d7 --- /dev/null +++ b/doc/4.4.README @@ -0,0 +1,9 @@ + +I'm not going to reiterate all the changes from 5.4.3 to 5.4.4 here. + +The 4.4.ANNOUNCE file has an overview, and the CHANGELOG file lists +everything in more detail. Check those out. + +D. J. Hawkey Jr. (hawkeyd@visi.com) +January 18, 1998 + diff --git a/doc/4.5.ANNOUNCE b/doc/4.5.ANNOUNCE new file mode 100644 index 0000000..93f8c6a --- /dev/null +++ b/doc/4.5.ANNOUNCE @@ -0,0 +1,27 @@ + +This is the announcement of VTWM 5.4.5, an upgrade of the three-year +old 5.4 release of the window manager for the X Window System. + +The web page, www.visi.com/~hawkeyd/vtwm.html, has been updated, and +the archive may be found via a link there, or directly via FTP at +ftp.visi.com/users/hawkeyd/X/ and ftp.x.org/contrib/window_managers/ +(if and when they move it there from incoming/). + +Some of the major changes, in a nutshell: + - All the 3D features are now fully configurable. + - Complete color (XPM) image support. + - Improved and consistant warp functionality. + - Many new variables and functions. + - Better keyboarding support. + - Many more bug fixes. + - Better portability. + +And a newly-discovered capability: + - A subset of regex wildcarding for list resources. + +Visit the above web page for screen captures, installation notes, and +complete histories of VTWM since version 5.1. + +D. J. Hawkey Jr. (hawkeyd@visi.com) +September 19, 1998 + diff --git a/doc/4.5.README b/doc/4.5.README new file mode 100644 index 0000000..8e522c3 --- /dev/null +++ b/doc/4.5.README @@ -0,0 +1,9 @@ + +When VTWM 5.4.5 was released on or about Sep 19 1998, this file contained a +list of new or changed features for that version. + +I've since created and maintain a HISTORY file that lists the features added +or changed for all releases of VTWM 5.4. + +--- djhjr + diff --git a/doc/4.6.ANNOUNCE b/doc/4.6.ANNOUNCE new file mode 100644 index 0000000..71ee12c --- /dev/null +++ b/doc/4.6.ANNOUNCE @@ -0,0 +1,40 @@ + +This is the announcement of VTWM 5.4.6, an upgrade of the five-year +old 5.4 release of the window manager for the X Window System. + +Highlighting the major changes from release 5.4.5a: + - m4 preprocessing of the resource file. VTWM can now share a + common .twmrc with TWM and other TWM derivatives, and support + by-user, by-group, and by-feature configurations. + - Regular expressions ("RE"s) support for resource file window + lists. Much more sophisticated than VTWM's own wildcarding. + - Sound effects, by way of the rplay library and daemon. What's + wrong with a little chrome? + - Applet regions, for all those little tools we have up all the + time. + - Scrolling menus, for those with more entries than the display + can handle. + - 3D doors and the virtual desktop. All 3D features are rendered + on opaque resizes (well, except for one case). + - Windows can be resized or moved from the virtual desktop, icon + managers, and menus not of the root or window in question. + - Better (dare I say it, "complete"?) support for multi-headed + systems. +And, of course, many more bug fixes, tweaks, additions, and changes. + +VTWM continues to be 100% backward-compatable with TWM. It can still +build and run under X11R4, and lose no self-supported functionality. +Release 5.4.6 supports the many features expected of "modern" window +managers, is highly configurable, yet it keeps a small footprint and +quick response. VTWM is quite portable; it has been built on over a +dozen different OSes, across nine platforms. + +The web page, www.visi.com/~hawkeyd/vtwm.html, has been updated, and +the archive may be found via a link there, or directly via FTP at +ftp.visi.com/users/hawkeyd/X/ and ftp.x.org/contrib/window_managers/ +(if and when they move it there from contrib/INCOMING/). Visit the +above web page for installation notes, complete histories, and more. + +David J. Hawkey Jr. (hawkeyd@visi.com) +November 3, 2001 + diff --git a/doc/4.6.README b/doc/4.6.README new file mode 100644 index 0000000..dfc6ff7 --- /dev/null +++ b/doc/4.6.README @@ -0,0 +1,5 @@ + +See the HISTORY and CHANGELOG files for version and chronological changes. + +--- djhjr + diff --git a/doc/4.7.README b/doc/4.7.README new file mode 100644 index 0000000..9ffb7cf --- /dev/null +++ b/doc/4.7.README @@ -0,0 +1,25 @@ +This is release 5.4.7 of VTWM the Virtual Tab Window Manager for the X +Window System. See the CHANGELOG and HISTORY files in the doc subdirectory +for further information on changes since the last release. + +This release is dedicated to the memory of David J Hawkey Jr, the previous +maintainer of vtwm, who sadly passed away as this release was being +prepared. The VTWM community acknowledges the countless hours he dedicated +to this project and are proud to carry on this project as his legacy. + +This will also be the first release to be publically available in a +source code repository. + +Callum Gibson 29th May, 2005 +callumgibson@optusnet.com.au + + +---------------------------------------------------------------------- +David John Hawkey Jr. + +Hawkey, David John Jr., age 47, of Mpls., on 10/17/04. Survived by son, +John David; mother, Alicia; father, David Sr.; sister, Lisa; brother, +Chris; and Gayle Hawkey. A farewell party will be planned at a later +date. Cremation Society of MN 612-825-2435 + +Published in the Star Tribune on 10/24/2004. diff --git a/doc/4.ANNOUNCE b/doc/4.ANNOUNCE new file mode 100644 index 0000000..ae21489 --- /dev/null +++ b/doc/4.ANNOUNCE @@ -0,0 +1,44 @@ + + +This is the announcement of VTWM Version 5.4, the first upgrade (by all +accounts contained herein) in over two years. I'm un-officially bumping the +minor number because VTWM-5.3 is the latest I've seen in distribution, and +this is a significant change, both in end-user impression and in code. + +This all started because I wanted an esthetically pleasing alternative to +the Motif window manager, a good workout, and leaner system requirements. +Enhanced and extended functionality is way cool. + +It has taken me about one hobby-month to apply a 3D appearance to VTWM-5.3. +I did it by borrowing (stealing?) code from CTWM-3.1 and plugging it in. +I also added 3D borders to the size, position(!), and info windows. Then I +wanted variable info window fonts. Then resize/position window locations. +And a bunch of other tweaks. + +I have read that VTWM-5.2b has some or all of these enhancements, but I +could not find a package to evaluate (I tried with Xarchie using around 15 +different hosts). CTWM-3.1 is pretty, lean, and fast, but I don't like it's +virtual desktop implementation. I found, made, and tried a version of FVWM, +but it didn't port right (or was way buggy), and I didn't/don't think I +could have overcome that/those bug/s before becoming thoroughly frustrated. + +This is not bug-free code. I "inherited" two documented flaws, and others +may exist. By fixing one, I seem to have introduced another, but it is +easily worked around. + +I do not want to be the maintainer of VTWM. I don't even think of myself as +an "X programmer", though I like it, and *I*am*learning*. I will entertain +comments, bug reports, etc., especially to my work, and will try to respond +in kind. I am not planning on further effort, as it now fills my needs. + +D. J. Hawkey Jr. (hawkeyd@visi.com) +May 15, 1996 + + + +It looks like, for the time being anyway, due to incoming mail, I am the +maintainer of VTWM. + +D. J. Hawkey Jr. (hawkeyd@visi.com) +November 17, 1997 + diff --git a/doc/4.FUTURE b/doc/4.FUTURE new file mode 100644 index 0000000..0acda92 --- /dev/null +++ b/doc/4.FUTURE @@ -0,0 +1,18 @@ + + +I do not want to be the maintainer of VTWM. I don't even think of myself as +an "X programmer", though I like it, and *I*am*learning*. I will entertain +comments, bug reports, etc., especially to my work, and will try to respond +in kind. I am not planning on further effort, as it now fills my needs. + +D. J. Hawkey Jr. (hawkeyd@visi.com) +May 15, 1996 + + + +It looks like, for the time being anyway, due to incoming mail, I am the +maintainer of VTWM. + +D. J. Hawkey Jr. (hawkeyd@visi.com) +November 17, 1997 + diff --git a/doc/4.README b/doc/4.README new file mode 100644 index 0000000..de2e07d --- /dev/null +++ b/doc/4.README @@ -0,0 +1,321 @@ + +---------------------------------------------------------------------------- + +`grep -n 3D *.[ch] > 3Ddiffs.lst` of CTWM-3.1. +This is where VTWM-5.4 began. The exclamation marks denote what I ported. +This is not inclusive or exhaustive. RTSL for the signature 'djhjr'. + +! add_window.c:276: tmp_win->frame_bw3D = Scr->ThreeDBorderWidth; +! add_window.c:279: tmp_win->frame_bw3D = 0; +! add_window.c:282: if (tmp_win->frame_bw3D != 0) { +! add_window.c:446: AddingW = tmp_win->attr.width + bw2 + 2 * tmp_win->frame_bw3D; +! add_window.c:448: bw2 + 2 * tmp_win->frame_bw3D; +! add_window.c:451: tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); +! add_window.c:521: tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); +! add_window.c:634: tmp_win->attr.width = AddingW - bw2 - 2 * tmp_win->frame_bw3D; +! add_window.c:636: bw2 - 2 * tmp_win->frame_bw3D; +! add_window.c:655: int delta = tmp_win->attr.border_width - tmp_win->frame_bw - tmp_win->frame_bw3D; +! add_window.c:725: if (Scr->use3Dtitles && !Scr->BeNiceToColormap) GetShadeColors (&tmp_win->title); +! add_window.c:726: if (Scr->use3Dborders && !Scr->BeNiceToColormap) { +! add_window.c:733: - tmp_win->frame_bw3D; +! add_window.c:735: tmp_win->old_bw - tmp_win->frame_bw - tmp_win->frame_bw3D; +! add_window.c:736: tmp_win->frame_width = tmp_win->attr.width + 2 * tmp_win->frame_bw3D; +! add_window.c:738: 2 * tmp_win->frame_bw3D; +! add_window.c:776: tmp_win->frame_bw3D - tmp_win->frame_bw, +! add_window.c:777: tmp_win->frame_bw3D - tmp_win->frame_bw, +! add_window.c:793: if (Scr->use3Dtitles && (Scr->Monochrome != COLOR)) +! add_window.c:818: tmp_win->title_x = tmp_win->frame_bw3D - tmp_win->frame_bw; +! add_window.c:819: tmp_win->title_y = tmp_win->frame_bw3D - tmp_win->frame_bw; +! add_window.c:851: XReparentWindow(dpy, tmp_win->w, tmp_win->frame, tmp_win->frame_bw3D, +! add_window.c:852: tmp_win->title_height + tmp_win->frame_bw3D); +! add_window.c:1103: if (Scr->use3Dtitles && (Scr->Monochrome != COLOR)) +! add_window.c:1138: if (Scr->use3Dtitles) +! add_window.c:1177: if (Scr->use3Dtitles) tmp_win->highlightx += 6; +! add_window.c:1201: tmp->title_x = tmp->frame_bw3D - tmp->frame_bw; +! add_window.c:1202: tmp->title_y = tmp->frame_bw3D - tmp->frame_bw; +! add_window.c:1244: tmp->title_x = basex - tmp->frame_bw + tmp->frame_bw3D; +! add_window.c:1589: tmp->title_height + 2 * tmp->frame_bw3D) ? 0 : 2) | +! add_window.c:1591: tmp->title_height + 2 * tmp->frame_bw3D) ? 0 : 1)]; + +! ctwm.c:423: Scr->TBInfo.border = -100; /* trick to have different default value if ThreeDTitles +! ctwm.c:499: if (Scr->use3Dtitles) { +! ctwm.c:512: if (Scr->use3Dtitles && !Scr->BeNiceToColormap) GetShadeColors (&Scr->TitleC); +! ctwm.c:513: if (Scr->use3Dmenus && !Scr->BeNiceToColormap) GetShadeColors (&Scr->MenuC); +! ctwm.c:514: if (Scr->use3Dmenus && !Scr->BeNiceToColormap) GetShadeColors (&Scr->MenuTitleC); +! ctwm.c:515: if (Scr->use3Dborders && !Scr->BeNiceToColormap) GetShadeColors (&Scr->BorderColorC); +! ctwm.c:516: if (! Scr->use3Dborders) Scr->ThreeDBorderWidth = 0; +! ctwm.c:526: if (Scr->use3Dtitles) Scr->TitleHeight += 4; +! ctwm.c:732: Scr->FramePadding = -100; /* trick to have different default value if ThreeDTitles +! ctwm.c:737: Scr->ThreeDBorderWidth = 6; +! ctwm.c:797: Scr->use3Diconmanagers = FALSE; +! ctwm.c:798: Scr->use3Dmenus = FALSE; +! ctwm.c:799: Scr->use3Dtitles = FALSE; +! ctwm.c:800: Scr->use3Dborders = FALSE; +! ctwm.c:854: xwc.x += gravx * tmp->frame_bw3D; +! ctwm.c:855: xwc.y += gravy * tmp->frame_bw3D; + +! events.c:1367: if (Scr->use3Dborders && (Event.xany.window == Tmp_win->frame)) { +! events.c:1415: if (Scr->use3Diconmanagers && (Scr->Monochrome != COLOR)) +! events.c:1428: if (Scr->use3Diconmanagers && Tmp_win->list->iconifypm) { +! events.c:2172: Event.xbutton.x = JunkX - Tmp_win->frame_bw3D; +! events.c:2173: Event.xbutton.y = JunkY - Tmp_win->title_height - Tmp_win->frame_bw3D; +! events.c:2202: Event.xbutton.x -= Tmp_win->frame_bw3D; +! events.c:2203: Event.xbutton.y -= (Tmp_win->title_height + Tmp_win->frame_bw3D); +! events.c:2533: if (Scr->use3Dtitles && Scr->SunkFocusWindowTitle && +! events.c:2535: Draw3DBorder (Tmp_win->title_w, Scr->TBInfo.titlex, 0, +! events.c:2557: if (Scr->use3Dtitles && Scr->SunkFocusWindowTitle && +! events.c:2559: Draw3DBorder (Tmp_win->title_w, Scr->TBInfo.titlex, 0, +! events.c:2748: if (Scr->use3Dtitles && Scr->SunkFocusWindowTitle && +! events.c:2750: Draw3DBorder (Tmp_win->title_w, Scr->TBInfo.titlex, 0, +! events.c:2882: x -= ((gravx < 0) ? 0 : Tmp_win->frame_bw3D); +! events.c:2886: y -= ((gravy < 0) ? 0 : Tmp_win->frame_bw3D); +! events.c:2890: width = cre->width + 2 * Tmp_win->frame_bw3D; +! events.c:2893: height = cre->height + Tmp_win->title_height + 2 * Tmp_win->frame_bw3D; + +! iconmgr.c:101: (2 * (Scr->ThreeDBorderWidth ? Scr->ThreeDBorderWidth : Scr->BorderWidth)); +! iconmgr.c:105: (2 * (Scr->ThreeDBorderWidth ? Scr->ThreeDBorderWidth : Scr->BorderWidth)); +! iconmgr.c:475: if (Scr->use3Diconmanagers) { +! iconmgr.c:477: tmp->iconifypm = Create3DIconManagerIcon (tmp->cp); +! iconmgr.c:712: if (Scr->use3Diconmanagers) { +! iconmgr.c:717: Draw3DBorder (tmp->w, 0, 0, tmp->width, tmp->height, shadow_width, +! iconmgr.c:720: Draw3DBorder (tmp->w, 0, 0, tmp->width, tmp->height, shadow_width, +! iconmgr.c:857: bw = ip->twm_win->frame_bw3D ? ip->twm_win->frame_bw3D : ip->twm_win->frame_bw; +! iconmgr.c:869: newwidth + 2 * ip->twm_win->frame_bw3D, +! iconmgr.c:870: ip->height + ip->twm_win->title_height + 2 * ip->twm_win->frame_bw3D, -1); + +! icons.c:405: if (Scr->use3Diconmanagers && !Scr->BeNiceToColormap) GetShadeColors (&icon->iconc); + +! menus.c:344: if (Scr->use3Dtitles) +! menus.c:358: if (Scr->use3Dtitles) { +! menus.c:359: if (!CreateTitleButton (TBPM_3DDOT, F_ICONIFY, "", (MenuRoot *) NULL, +! menus.c:363: if (!CreateTitleButton (TBPM_3DRESIZE, F_RESIZE, "", (MenuRoot *) NULL, +! menus.c:422: if (Scr->use3Dmenus) { +! menus.c:423: Paint3DEntry (mr, mi, exposure); +! menus.c:428:void Paint3DEntry(mr, mi, exposure) +! menus.c:444: Draw3DBorder (mr->w, 2, y_offset, mr->width - 4, Scr->EntryHeight, 1, +! menus.c:476: Scr->pullPm = Create3DMenuIcon (Scr->MenuFont.height, &Scr->pullW, +! menus.c:486: Draw3DBorder (mr->w, 2, y_offset, mr->width - 4, Scr->EntryHeight, 1, +! menus.c:594: if (Scr->use3Dmenus) { +! menus.c:595: Draw3DBorder (mr->w, 0, 0, mr->width, mr->height, 2, Scr->MenuC, off, False, False); +! menus.c:890: if (Scr->use3Dmenus && !Scr->BeNiceToColormap) GetShadeColors (&tmp->normal); +! menus.c:956: if (Scr->use3Dmenus) mr->height += 4; +! menus.c:1004: borderwidth = Scr->use3Dmenus ? 0 : 1; +! menus.c:1018: if (Scr->use3Dmenus && (Scr->Monochrome == COLOR) && (mr->highlight.back == UNUSED_PIXEL)) { +! menus.c:1033: if (Scr->use3Dmenus && (Scr->Monochrome == COLOR) && (mr->highlight.fore == UNUSED_PIXEL)) { +! menus.c:1047: if (Scr->use3Dmenus && !Scr->BeNiceToColormap) GetShadeColors (&mr->highlight); +! menus.c:1072: if (Scr->use3Dmenus && !Scr->BeNiceToColormap) { +! menus.c:1447: AddingW = tmp_win->attr.width + bw2 + 2 * tmp_win->frame_bw3D; +! menus.c:1448: AddingH = tmp_win->attr.height + tmp_win->title_height + bw2 + 2 * tmp_win->frame_bw3D; +! menus.c:1476: tmp_win->title_height + tmp_win->frame_bw3D); +! menus.c:2006: moving_icon ? 0 : tmp_win->title_height + tmp_win->frame_bw3D); +! menus.c:2182: moving_icon ? 0 : tmp_win->title_height + tmp_win->frame_bw3D); +! menus.c:2224: moving_icon ? 0 : tmp_win->title_height + tmp_win->frame_bw3D); +! menus.c:3368: if (Scr->use3Dborders) PaintBorders (tmp, onoroff); + +! parse.c:467:#define kw0_Use3DMenus 33 +! parse.c:468:#define kw0_Use3DTitles 34 +! parse.c:469:#define kw0_Use3DIconManagers 35 +! parse.c:470:#define kw0_Use3DBorders 36 +! parse.c:512:#define kwn_ThreeDBorderWidth 21 +! parse.c:772: { "threedborderwidth", NKEYWORD, kwn_ThreeDBorderWidth }, +! parse.c:784: { "usethreedborders", KEYWORD, kw0_Use3DBorders }, +! parse.c:785: { "usethreediconmanagers", KEYWORD, kw0_Use3DIconManagers }, +! parse.c:786: { "usethreedmenus", KEYWORD, kw0_Use3DMenus }, +! parse.c:787: { "usethreedtitles", KEYWORD, kw0_Use3DTitles }, +! parse.c:948: case kw0_Use3DBorders: +! parse.c:949: Scr->use3Dborders = TRUE; +! parse.c:952: case kw0_Use3DIconManagers: +! parse.c:953: Scr->use3Diconmanagers = TRUE; +! parse.c:956: case kw0_Use3DMenus: +! parse.c:957: Scr->use3Dmenus = TRUE; +! parse.c:960: case kw0_Use3DTitles: +! parse.c:961: Scr->use3Dtitles = TRUE; +! parse.c:1131: case kwn_ThreeDBorderWidth: +! parse.c:1132: if (Scr->FirstTime) Scr->ThreeDBorderWidth = num; + +! resize.c:179: tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); +! resize.c:214: tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); +! resize.c:361: tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); +! resize.c:488: tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); +! resize.c:523: dheight = height - tmp_win->title_height - 2 * tmp_win->frame_bw3D; +! resize.c:524: dwidth = width - 2 * tmp_win->frame_bw3D; +! resize.c:592: tmp_win->iconmgrp->width = (int) (((dragWidth - 2 * tmp_win->frame_bw3D) * +! resize.c:669: dwidth -= 2 * tmp_win->frame_bw3D; +! resize.c:670: dheight -= (tmp_win->title_height + 2 * tmp_win->frame_bw3D); +! resize.c:777: *widthp = dwidth + 2 * tmp_win->frame_bw3D; +! resize.c:778: *heightp = dheight + tmp_win->title_height + 2 * tmp_win->frame_bw3D; +! resize.c:840: tmp_win->iconmgrp->width = w - (2 * tmp_win->frame_bw3D); +! resize.c:841: h = tmp_win->iconmgrp->height + tmp_win->title_height + (2 * tmp_win->frame_bw3D); +! resize.c:855: title_width = xwc.width = w - (2 * tmp_win->frame_bw3D); +! resize.c:885: tmp_win->title_x = xwc.x = tmp_win->frame_bw3D - bw; +! resize.c:886: tmp_win->title_y = xwc.y = tmp_win->frame_bw3D - bw; +! resize.c:893: tmp_win->attr.width = w - (2 * tmp_win->frame_bw3D); +! resize.c:894: tmp_win->attr.height = h - tmp_win->title_height - (2 * tmp_win->frame_bw3D); +! resize.c:911: XMoveResizeWindow (dpy, tmp_win->w, tmp_win->frame_bw3D, +! resize.c:912: tmp_win->title_height + tmp_win->frame_bw3D, +! resize.c:922: if (Scr->use3Dtitles) xwc.width -= 4; +! resize.c:937: WMapSetupWindow (tmp_win, x + tmp_win->frame_bw3D, +! resize.c:938: y + tmp_win->title_height + tmp_win->frame_bw3D, +! resize.c:948: + tmp_win->frame_bw3D); +! resize.c:951: + tmp_win->frame_bw3D); +! resize.c:1100: tmp->frame_bw3D, tmp->title_height + tmp->frame_bw3D, tmp->w, +! resize.c:1126: newBounding[0].x = tmp->title_x - tmp->frame_bw3D; +! resize.c:1127: newBounding[0].y = tmp->title_y - tmp->frame_bw3D; +! resize.c:1128: newBounding[0].width = tmp->title_width + fbw2 + 2 * tmp->frame_bw3D; +! resize.c:1129: newBounding[0].height = tmp->title_height + tmp->frame_bw3D; +! resize.c:1131: newBounding[1].y = Scr->TitleHeight + tmp->frame_bw3D; +! resize.c:1132: newBounding[1].width = tmp->attr.width + fbw2 + 2 * tmp->frame_bw3D; +! resize.c:1133: newBounding[1].height = tmp->attr.height + fbw2 + tmp->frame_bw3D; +! resize.c:1137: newClip[0].x = tmp->title_x + tmp->frame_bw - tmp->frame_bw3D; +! resize.c:1139: newClip[0].width = tmp->title_width + 2 * tmp->frame_bw3D; +! resize.c:1140: newClip[0].height = Scr->TitleHeight + tmp->frame_bw3D; +! resize.c:1142: newClip[1].y = tmp->title_height + tmp->frame_bw3D; +! resize.c:1143: newClip[1].width = tmp->attr.width + 2 * tmp->frame_bw3D; +! resize.c:1144: newClip[1].height = tmp->attr.height + tmp->frame_bw3D; + +! util.c:91:static Image *Create3DMenuImage (); +! util.c:92:static Image *Create3DDotImage (); +! util.c:93:static Image *Create3DResizeImage (); +! util.c:94:static Image *Create3DZoomImage (); +! util.c:95:static Image *Create3DBarImage (); + util.c:96:static Image *Create3DResizeAnimation (); +! util.c:1341:static Image *Create3DDotImage (cp) +! util.c:1355: Draw3DBorder (image->pixmap, 0, 0, h, h, 2, cp, off, True, False); +! util.c:1356: Draw3DBorder (image->pixmap, (h / 2) - 2, (h / 2) - 2, 5, 5, 2, cp, off, True, False); +! util.c:1364:static Image *Create3DBarImage (cp) +! util.c:1378: Draw3DBorder (image->pixmap, 0, 0, h, h, 2, cp, off, True, False); +! util.c:1379: Draw3DBorder (image->pixmap, 4, (h / 2) - 2, h - 8, 5, 2, cp, off, True, False); +! util.c:1387:static Image *Create3DMenuImage (cp) +! util.c:1401: Draw3DBorder (image->pixmap, 0, 0, h, h, 2, cp, off, True, False); +! util.c:1403: Draw3DBorder (image->pixmap, 4, i, h - 8, 4, 2, cp, off, True, False); +! util.c:1412:static Image *Create3DResizeImage (cp) +! util.c:1426: Draw3DBorder (image->pixmap, 0, 0, h, h, 2, cp, off, True, False); +! util.c:1427: Draw3DBorder (image->pixmap, 0, h / 4, ((3 * h) / 4) + 1, ((3 * h) / 4) + 1, 2, +! util.c:1429: Draw3DBorder (image->pixmap, 0, h / 2, (h / 2) + 1, (h / 2) + 1, 2, cp, off, True, False); +! util.c:1437:static Image *Create3DZoomImage (cp) +! util.c:1451: Draw3DBorder (image->pixmap, 0, 0, h, h, 2, cp, off, True, False); +! util.c:1452: Draw3DBorder (image->pixmap, h / 4, h / 4, (h / 2) + 2, (h / 2) + 2, 2, cp, off, True, False); +! util.c:1466:Pixmap Create3DMenuIcon (height, widthp, heightp, cp) +! util.c:1493: Draw3DBorder (col->pix, 0, 0, w, h, 1, cp, off, True, False); +! util.c:1495: Draw3DBorder (col->pix, 4, i, w - 8, 3, 1, Scr->MenuC, off, True, False); +! util.c:1502:Pixmap Create3DIconManagerIcon (cp) +! util.c:1519: Draw3DBorder (col->pix, 0, 0, w, h, 4, cp, off, True, False); + util.c:1526:static Image *Create3DResizeAnimation (cp) + util.c:1539: Draw3DBorder (im->pixmap, 0, 0, h, h, 2, cp, off, True, False); + util.c:1540: Draw3DBorder (im->pixmap, i, i, h - (2 * i), h - (2 * i), 2, cp, off, True, False); +! util.c:1663:void Draw3DBorder (w, x, y, width, height, bw, cp, state, fill, forcebw) +! util.c:1775:void Draw3DCorner (w, x, y, width, height, thick, bw, cp, type) +! util.c:1781: Draw3DBorder (w, x, y, width, height, bw, cp, off, True, False); +! util.c:1784: Draw3DBorder (w, x + thick - bw, y + thick - bw, +! util.c:1789: Draw3DBorder (w, x - bw, y + thick - bw, +! util.c:1794: Draw3DBorder (w, x - bw, y - bw, +! util.c:1799: Draw3DBorder (w, x + thick - bw, y - bw, + util.c:1813: if (tmp_win->frame_bw3D) +! util.c:1839: Draw3DBorder (tmp_win->frame, +! util.c:1845: Draw3DBorder (tmp_win->frame, +! util.c:1846: tmp_win->frame_bw3D - 2, +! util.c:1847: tmp_win->frame_bw3D - 2, +! util.c:1848: tmp_win->frame_width - 2 * tmp_win->frame_bw3D + 4, +! util.c:1849: tmp_win->frame_height - 2 * tmp_win->frame_bw3D + 4, +! util.c:1853: Draw3DBorder (tmp_win->frame, +! util.c:1857: tmp_win->frame_bw3D, +! util.c:1859: Draw3DBorder (tmp_win->frame, +! util.c:1860: tmp_win->frame_bw3D + Scr->TitleHeight, +! util.c:1861: tmp_win->frame_height - tmp_win->frame_bw3D, +! util.c:1862: tmp_win->frame_width - 2 * (Scr->TitleHeight + tmp_win->frame_bw3D), +! util.c:1863: tmp_win->frame_bw3D, +! util.c:1865: Draw3DBorder (tmp_win->frame, +! util.c:1867: Scr->TitleHeight + tmp_win->frame_bw3D, +! util.c:1868: tmp_win->frame_bw3D, +! util.c:1869: tmp_win->frame_height - 2 * (Scr->TitleHeight + tmp_win->frame_bw3D), +! util.c:1871: Draw3DBorder (tmp_win->frame, +! util.c:1872: tmp_win->frame_width - tmp_win->frame_bw3D, +! util.c:1873: Scr->TitleHeight + tmp_win->frame_bw3D, +! util.c:1874: tmp_win->frame_bw3D, +! util.c:1875: tmp_win->frame_height - 2 * (Scr->TitleHeight + tmp_win->frame_bw3D), +! util.c:1877: Draw3DCorner (tmp_win->frame, +! util.c:1878: tmp_win->title_x - tmp_win->frame_bw3D, +! util.c:1880: Scr->TitleHeight + tmp_win->frame_bw3D, +! util.c:1881: Scr->TitleHeight + tmp_win->frame_bw3D, +! util.c:1882: tmp_win->frame_bw3D, 2, cp, 0); +! util.c:1883: Draw3DCorner (tmp_win->frame, +! util.c:1886: Scr->TitleHeight + tmp_win->frame_bw3D, +! util.c:1887: Scr->TitleHeight + tmp_win->frame_bw3D, +! util.c:1888: tmp_win->frame_bw3D, 2, cp, 1); +! util.c:1889: Draw3DCorner (tmp_win->frame, +! util.c:1890: tmp_win->frame_width - (Scr->TitleHeight + tmp_win->frame_bw3D), +! util.c:1891: tmp_win->frame_height - (Scr->TitleHeight + tmp_win->frame_bw3D), +! util.c:1892: Scr->TitleHeight + tmp_win->frame_bw3D, +! util.c:1893: Scr->TitleHeight + tmp_win->frame_bw3D, +! util.c:1894: tmp_win->frame_bw3D, 2, cp, 2); +! util.c:1895: Draw3DCorner (tmp_win->frame, +! util.c:1897: tmp_win->frame_height - (Scr->TitleHeight + tmp_win->frame_bw3D), +! util.c:1898: Scr->TitleHeight + tmp_win->frame_bw3D, +! util.c:1899: Scr->TitleHeight + tmp_win->frame_bw3D, +! util.c:1900: tmp_win->frame_bw3D, 2, cp, 3); +! util.c:1906: if (Scr->use3Dtitles) +! util.c:1909: Draw3DBorder (tmp_win->title_w, Scr->TBInfo.titlex, 0, +! util.c:1914: Draw3DBorder (tmp_win->title_w, Scr->TBInfo.titlex, 0, +! util.c:1922: if (Scr->use3Dtitles) { +! util.c:1942: if (Scr->use3Diconmanagers) { +! util.c:1943: Draw3DBorder (tmp_win->icon->w, 0, tmp_win->icon->height, +! util.c:2095: { TBPM_3DDOT, Create3DDotImage }, +! util.c:2096: { TBPM_3DRESIZE, Create3DResizeImage }, +! util.c:2097: { TBPM_3DMENU, Create3DMenuImage }, +! util.c:2098: { TBPM_3DZOOM, Create3DZoomImage }, +! util.c:2099: { TBPM_3DBAR, Create3DBarImage }, + util.c:2123: { "%xpm:resize", Create3DResizeAnimation } + util.c:2128: if ((image = Create3DResizeAnimation (cp)) != None) { + + workmgr.c:1137: Draw3DBorder (Scr->workSpaceMgr.workspaceWindow.w, 0, 0, width, height, 2, + workmgr.c:1294: Draw3DBorder (Scr->workSpaceMgr.occupyWindow.w, 0, 0, width, height, 2, + workmgr.c:1347: Draw3DBorder (w, 0, 0, bwidth, bheight, Scr->WMgrButtonShadowDepth, + workmgr.c:1353: Draw3DBorder (w, 0, 0, bwidth, bheight, Scr->WMgrButtonShadowDepth, + +! screen.h:167: short use3Dmenus; +! screen.h:168: short use3Dtitles; +! screen.h:169: short use3Diconmanagers; +! screen.h:170: short use3Dborders; +! screen.h:236: int ThreeDBorderWidth; /* 3D border width of twm windows */ + +! twm.h:250: int frame_bw3D; /* 3D borderwidth of frame */ +! twm.h:323:#define TBPM_3DDOT ":xpm:dot" /* name of titlebar pixmap for dot */ +! twm.h:324:#define TBPM_3DRESIZE ":xpm:resize" /* name of titlebar pixmap for resize button */ +! twm.h:325:#define TBPM_3DMENU ":xpm:menu" /* name of titlebar pixmap for menus */ +! twm.h:326:#define TBPM_3DZOOM ":xpm:zoom" +! twm.h:327:#define TBPM_3DBAR ":xpm:bar" +! twm.h:381:extern Pixmap Create3DMenuIcon(); + +! util.h:65:void Draw3DBorder (); +! util.h:66:void Draw3DCorner (); + +! protos:137:extern void Paint3DEntry(struct MenuRoot *,struct MenuItem *,int ); +! ...in menus.c +! protos:232:extern unsigned long Create3DMenuIcon(unsigned int ,unsigned int *,unsigned int *,struct ColorPair ); +! ...in twm.h +! protos:234:extern unsigned long Create3DIconManagerIcon(struct ColorPair ); +! ...in twm.h +! protos:237:extern void Draw3DBorder(unsigned long ,int ,int ,int ,int ,int ,struct ColorPair ,int ,int ,int ); +! ...in twm.h +! protos:239:extern void Draw3DCorner(unsigned long ,int ,int ,int ,int ,int ,int ,struct ColorPair ,int ); +! ...in util.c + +---------------------------------------------------------------------------- + +`grep -in separator *.[chy] > separator.lst` of CTWM-3.1. +This is what it took for menu separators. The exclamation marks denote +what I ported. RTSL for the signature 'djhjr'. + +! gram.y:741: if ($2 == F_SEPARATOR) { +! gram.y:751: if ($7 == F_SEPARATOR) { +! parse.c:633: { "f.separator", FKEYWORD, F_SEPARATOR }, +! parse.h:105:#define F_SEPARATOR 58 + +---------------------------------------------------------------------------- + +See the files 4.ANNOUNCE, BUGS and CHANGELOG for a summary of these and +other changes - djhjr - + +---------------------------------------------------------------------------- + + diff --git a/doc/BUGS b/doc/BUGS new file mode 100644 index 0000000..e9bd262 --- /dev/null +++ b/doc/BUGS @@ -0,0 +1,80 @@ + +A LISTING OF BUGS +================= + +This is the bug list as distributed with VTWM 5.3. + + * Behavior of transients on the virtual desktop, when the real screen is + not at (0,0), is almost unpredictable. Hence the + FixTransientVirtualGeometries variable, new to 5.3, which is not + guaranteed to work in every case. --- DSE + + * When the Zoom count is a largish number and PrettyZoom is set, some + artifacts may be left on formerly obscured windows. Decrease the count + value. --- djhjr + + * Not a bug, but the IconRegion variable should take a list. --- DSE + + * Not a bug, but the resource manager should have been used instead of + all of the window lists. --- DSE + +Bugs created as a result of my hacking VTWM 5.4. --- djhjr + + * Icon borders will not do 3D, and I don't want to to mess with it. + The icons themselves are 3D when IconBevelWidth is non-zero, however, + and the IconBorderWidth variable is automatically set to 0. + + * The code to vertically center a door name in the window is correct. + It just won't appear so, due to the window and font heights. Play with + the door geometry. + + * Behavior of managed windows when used as transients on the virtual + desktop, when the real screen is not at (0,0), is sometimes flawed. + Hence the FixManagedVirtualGeometries variable, new to 5.4.4, which + is also guaranteed to not work in every case. + + * Only titlebar buttons, and therefore the titlebar itself, can adjust + to the height of external images. + + * All images should either tile or center as required. + + * VTWM recognizes two-color pixmaps, but incorrectly uses them as + bitmaps. + + * When 3D bevel widths reach double digits, things start going weird, + and I don't know why. Hence an imposed limit of nine pixels. + + * The region resources don't like 0 or 1 for a horizontal grid space. + A kludge is in that fixes it (I think). + + * The f.warpto function doesn't recognize a regular expression. + + * It is possible to place a window sufficiently off-screen as to defeat + warp functions (ex: The visible part wholly within AutoPanBorderWidth + pixels of screen edge). + + * When warping the screen to a window during a move or resize operation, + any number of exposed clients may not get drawn. + + * Menus can become unresponsive. I don't know what triggers this, though + submenu selections seem to be involved. + + * At least one application seems to foul up the window ring. At present, + restarting VTWM is the only cure. + +Bugs encountered and not fixed while hacking VTWM 5.4. --- djhjr + + * Opaque resizing of windows with squeezed titlebars can kill the X + server. A hack prevents this by raising the window before the resize. + + * If there is an order of precedence regarding contexts, it's broken. + + * There are precious few safeguards against binding functions to objects + inappropriately, particularly where the virtual desktop is concerned. + + * Redefining a bound function doesn't behave as one would expect; really + strange things occur. + + * Not a bug, but the sample resource file .vtwmrc-marcel is quite out + of date regarding various VTWM features. + diff --git a/doc/CHANGELOG b/doc/CHANGELOG new file mode 100644 index 0000000..79b83c2 --- /dev/null +++ b/doc/CHANGELOG @@ -0,0 +1,1375 @@ + +============================================================ +A COMPLETE LISTING OF CHANGES MADE TO VTWM SINCE VERSION 5.0 +IN CHRONOLOGICAL ORDER FROM MOST RECENT CHANGES TO EARLIEST. +============================================================ + +============ vtwm-5.4.N.tar.gz ============= +hawkeyd@visi.com (D. J. Hawkey Jr. aka djhjr) + + May 2005 + VTWM 5.4.7 release + [add_window.c] [iconmgr.c] [parse.c] [screen.h] [twm.c] + Added PointerPlacement + [menus.c] + Fix no-sound support + + October 1, 2004 + VTWM 5.4.6b (bugfix release) released for public consumption. + vtwm-5.4.6a-to-5.4.6b.udiff patch file released. + + March 9, 2004 + [events.c] [menus.c] + Added checks for the number of rodent buttons and VTWM + Windows entries. Fixed a bug causing sporadic restarts + when realizing unmanaged windows. + + From Jennifer Elaan , Seth Robertson + , and Callum Gibson : + Patches for the above. + + November 2 - 11, 2003 + [applets.c] [desktop.c] [events.c] [menus.c] [parse.c] [resize.c] + [twm.c] [screen.h] + Fixed a vertical placement error in applet regions. The + f.movescreen function supports sound and honors cancels now + (moved functionality from event handlers to the function + itself). Fixed "raise window regardless of MoveDelta" bugs + introduced on May 23 - 27. Optionally preserve the previous + move and resize raise behaviour. Some shaping optimizations. + Depreciated the motion event handler. Reduced server grabs. + + Added the following variable: + RaiseOnStart + + September 21 & 22, 2003 + Tweaked stuff all over the place for a cleaner compile. + + [add_window.c] [events.c] [menus.c] + Fixed an UsePPosition bug, a restart bug, a sound bug, and + an instance of unfreed memory. + + September 18, 2003 + [*akefile*] [parse.c] + Let lexers track line numbers by default. + + September 14 - 17, 2003 + Moved the nexpm/ directory into contrib/. Moved the sample + resource files and directories in the contrib/ directory into + contrib/vtwmrc/. + + [*akefile*] [add_window.c] [doors.c] [events.c] [gc.c] [icons.c] + [menus.c] [parse.c] [resize.c] [twm.c] [util.c] [twm.h] [util.h] + Added internationalization (I18N) support. Woo-woo! + Better handling of missing or empty string resources. + + September 10, 2003 + [add_window.c] [gram.y] [menus.c] [parse.c] [twm.c] [add_window.h] + [screen.h] [twm.h] + Added code to ignore "shift states" for bindings. + + Added the following variable: + IgnoreModifiers k + + June 3, 2003 + [menus.c] + Better sound handling in the (de)iconify and warp functions. + + May 27, 2003 + [iconmgr.c] [events.c] [menus.c] [resize.c] + Fixed a bug when removing icon manager entries. Almost fixed + stacking order bugs when resizing windows (the raise still + occurs before the movement when opaque resizes are done on + windows with squeezed titlebars). Cancelled resizes now work + correctly, except for the above case. + + May 23 & 24, 2003 + [menus.c] + Fixed stacking order bugs when moving windows (the raise + now occurs after the movement). Cancelled moves now work + correctly. + + November 15, 2002 + [menus.c] [parse.c] [sound.c] [parse.h] [sound.h] + Allow sounds to be played "ad hoc". + + Added the following function: + f.playsound s + + November 8 & 11, 2002 + [add_window.c] [events.c] [ parse.c] [twm.h] + Support for MWM hints (currently, honor "noborder" and + "notitle" hints). Fixed some off-by-clientborderwidth + window placement bugs, an off-by-one malloc(), a null + pointer reference, and a ConfigureNotify propogation bug. + + From Jonathan Paisley : + Patches for the above. + + November 6 & 7, 2002 + [*akefile*] [twm.c] [vtwm.man] + Reduced the size of the compiled-in system.vtwmrc array. + The command line can specify that no startup file be used. + Updated the man page to reflect the compiled-in defaults. + + October 30 & 31, 2002 + [system.vtwmrc*] [add_window.c] [events.c] [icons.c] [gram.y] + [iconmgr.c] [menus.c] [parse.c] [twm.c] [util.c] [iconmgr.h] + [menus.h] [screen.h] [twm.h] + Opened up icon managers and menus to user-specified images. + The interfaces to all the built-in pixmap drawing functions + have been made uniform. + + Added the following keywords: + IconManagerPixmap s + MenuIconPixmap s + Changed the following variable: + ShallowReliefWindowButton + + October 27, 2002 + [add_window.c] [gram.y] [events.c] [menus.c] [parse.c] [twm.c] + [menus.h] [screen.h] + The f.warpto function accepts VTWM-style wildcards now. + The f.warpring function has been fixed. Again. + Prohibit windows from being added to the WindowRing list. + + From Jonathan Paisley : + Patches for NoWindowRing. + + Added the following variable: + NoWindowRing l + + October 25 & 26, 2002 + [add_window.c] [events.c] [parse.c] [resize.c] [twm.c] [util.c] + [screen.h] [twm.h] + Obsoleted the SunkFocusHighlightWindow variable with new + built-in highlight pixmaps, :xpm:raisedbox, :xpm:sunkenbox, + :xpm:raisedlines, and :xpm:sunkenlines. Fixed some titlebar + highlight exposure bugs. + + Changed the following keyword: + TitleHighlight s + Removed the following variable: + SunkFocusHighlightWindow + + October 20, 2002 + [parse.c] [twm.c] [util.c] [screen.h] + Chmod 0600 $(HOME)/vtwm.pid. + Allow the 3D borders of titled windows to be unadorned. + Fixed the 3D borders of titled windows when BeNiceToColormap + is set. + + Added the following variable: + NoBorderDecorations + + October 17 & 18, 2002 + [system.vtwmrc*] [add_window.c] [gram.y] [menus.c] [twm.c] + [util.c] + Refinements to the titlebar: The title bevel can now frame + the entire titlebar when built-in 3D buttons are not full + height. Buttons can now "extend into" the title bevel and + frame padding. The highlight area (or absence of) is handled + correctly now. The built-in 3D highlight is now available + with or without a title bevel. Enabled signed-integer data + handling in the resource file parser. + + Changed the following variables: + ButtonIndent n + FramePadding n + TitleBevelWidth n + TitlePadding n + + October 16, 2002 + [gram.y] [menus.c] [parse.c] [twm.c] [screen.h] + Allow warp functions to position the pointer at the center + of windows. + + Added the following variable: + WarpCentered s + + September 30, October 2 - 6, 2002 + [desktop.c] [events.c] [menus.c] [resize.c] [events.h] [menus.h] + [resize.h] + Refinements to the f.resize and f.move functions: Both are + now single rodent button operations from any context, and both + warp the pointer back to the virtual desktop when started from + there. The wireframe is drawn immediately, ignoring MoveDelta. + MoveDelta is otherwise used consistantly now. Fixed some icon + move and resize bugs. Large chunks of relevant code changed, + moving operations from event handlers to the function itself + and merging/removing redundant code. + + Changed the following functions: + f.move + f.resize + + September 26, 2002 + [menus.c] + Removed the limitations of the f.startwm argument. + + Changed the following function: + f.startwm s + + September 24, 2002 + [add_window.c] [gram.y] [parse.c] [twm.c] [screen.h] + The UsePPosition variable accepts a list now. + + Changed the following variable: + UsePPosition s l + + September 17, 2002 + [menus.c] + Fixed a race condition when f.squeeze* functions are invoked + from a window menu while Opaque* variables are set. + Prevent f.squeeze* functions when DontSqueezeTitle is set. + + September 13, 2002 + [resize.c] + Adjust the pointer back to the window at the end of window + resizes as required. + Constrain virtual desktop resizes to multiples of PanDistance + when SnapRealScreen is set. + + September 9, 2002 + [menus.c] [parse.c] [parse.h] + Fixed warp bugs when windows are borderless or shaped. + + From Seth Robertson : + Patches for passing raw key and rodent button events + to windows. + + Added the following functions: + f.bindbuttons + f.bindkeys + f.unbindbuttons + f.unbindkeys + + September 1, 2002 + VTWM 5.4.6a released for public consumption. + vtwm-5.4.6-to-5.4.6a.udiff patch file released. + + August 25, 2002 + [add_window.c] + Better random placement of large windows. + + From Seth Robertson : + Patch for the above. + + August 23, 2002 + [add_window.c] [applets.c] [gram.y] [parse.c] [twm.c] [screen.h] + Support for borderless windows. + + From Tim Wiess : + Patches for the above. + + Added the following variable: + NoBorder l + + April 28, 2002 + Improved the list parser in contrib/support/sysrc_add_apps.sh. + + April 9, 2002 + [events.c] + Fixed a focus problem with transient windows. + + December 2, 2001 + [menus.c] [twm.c] + Added "-p" command line switch for a runtime PID file, + $HOME/vtwm.pid. + + November 20, 2001 + [add_window.c] + MakeTitle now overrides NoTitle like it's supposed to. + + November 15, 2001 + [add_window.c] [doors.c] [menus.c] + Doors are drawn during opaque interactive creation now. + + November 8, 2001 + [events.c] [menus.c] [version.c] + Fixed bugs I introduced regarding icon managers and warp + rings. This should end f.warpring problems. + + November 3, 2001 + VTWM 5.4.6 released for public consumption. + + October 20 & 21, 2001 + [*akefile*] [applets.c] [gram.y] [icons.c] [lex.l] [list.c] + [menus.c] [parse.c] [regions.c] [util.c] [list.h] [regions.h] + Added support for POSIX 1003.2 regular expressions ("RE"s) + in resource file window lists. + + October 11, 2001 + [menus.c] [parse.c] [resize.c] [twm.c] [util.c] [screen.h] + Fixed window resizing via icon managers and the virtual + desktop and window moves (f.move) via the virtual desktop. + Improved virtual desktop updates after window resizes and + moves. Zooms are aware of icon managers now. Random zooms + during deiconification are controlled by a variable now. + + Added the following variable: + ZoomZoom + + October 2 & 3, 2001 + [events.c] [iconmgr.c] [menus.c] [parse.c] [twm.c] [parse.h] + [screen.h] + A new feature to make icon managers function strictly as + icon managers, listing only iconified windows. + + Added the following variable: + StrictIconManager + Added the following function: + f.stricticonmgr + + September 24 - 28, 2001 + A new script in the contrib/support directory can add installed + applications to the system default resource file. + + [*akefile*] [system.vtwmrc*] [add_window.c] [desktop.c] + [iconmgr.c] + Ensure the compiled-in resources and build info are current. + Made the system default resource files a bit more useful + and appealing. Fixed transposed default desktop foreground + and background colors. + + From Michael Dales : + Work on the bug where windows may be mapped in desktop + (0,0) regardless of the desktop's virtual location. + + From Rolf Neugebauer : + Fixed positioning errors for the icon manager and + virtual desktop windows. + + August 16, 2001 + [gram.y] [parse.c] [sound.c] + Added micro-manageable volume control. + + Changed the following variable: + Sounds l + + August 3, 2001 + Added another build hint to the INSTALL file. + + June 22 & 23, 2001 + Updated the doc and contrib directories. + + [*akefile*] [events.c] [gram.y] [iconmgr.c] [menus.c] [parse.c] + [sound.c] [twm.c] [menus.h] [parse.h] [screen.h] [sound.h] [twm.h] + Sound effects are now supported, by way of the rplay library + and daemon. + + Added the following variables: + PauseOnExit n + PauseOnQuit n + SoundHost s + Sounds l + SoundVolume n + Added the following function: + f.sounds + + October 24 & 31, 2000 + [doors.c] [menus.c] + Sanity checks on door renames. Fixed two menu repaint bugs. + + August 23, 2000 + [menus.c] + Fixed a menu scroll bug. + + June 14 & 21, 2000 + [menus.c] + Plugged holes where executing f.warptoiconmgr when thene + is no icon manager to warp to, and f.warpclass* when there + is no class, window, or focus, blew VTWM out of the water. + + June 4, 2000 + [twm.c] [util.c] [screen.h] [twm.h] + Added four new built-in window button images: ":darrow", + ":rarrow", ":xpm:darrow", and ":xpm:rarrow". + + May 28 - 31, 2000 + Added two more build hints to the INSTALL file. + + [iconmgr.c] [menus.c] [parse.c] [twm.c] [menus.h] [parse.h] + [screen.h] + When the pointer would end up in an AutoPan border on warps, + it is adjusted out, preventing unwanted screen pans. All the + f.*iconmgr warp functions honor the WarpSnug and WarpWindows + variables now (or absence of). The WarpSnug state can now be + toggled. + + From Ugen Antsilevitch : + Support for warping only to visible windows. + + Added the following variable: + WarpVisible + Added the following functions: + f.warpsnug + f.warpvisible + + May 22 - 24, 2000 + [menus.c] [parse.c] [twm.c] [menus.h] [screen.h] + Added "scrollability" to menus that would be taller than the + display (inspired by the neXtaw SimpleMenu widget). + + Added the following variables: + MenuScrollBorderWidth n + MenuScrollJump n + + April 1, 2000 + Added another build hint to the INSTALL file. + + [menus.c] + Made the pointer warp to the titlebar on a squeeze operation + if WarpCursor is set on, a la zoom operations. + + September 28, 1999 + [desktop.c] [icons.c] [util.c] + When moving an application window in the virtual desktop, the + border of the corresponding real screen window now highlights + as required. Streamlined the handling of transparent pixmaps + for window buttons, improving exposure response to pointer- + driven focus changes. + + September 21, 1999 + [add_window.c] [iconmgr.c] [menus.c] + Icon managers now honor the IconifyByUnmapping resource. + Fixed a bug where removing the last entry in an iconified + icon manager didn't unmap that icon, and it contained an + empty entry when deiconified. Fixed the f.hideiconmgr and + f.showiconmgr functions so that they now work against icon + managers that are defined with the IconManagers resource. + More work on the "Don't iconify if can't deiconify" logic. + + September 14 & 15, 1999 + [*akefile*] [events.c] [menus.c] + Fixed the notorious "Can't resize or move from icon managers + and menus not of the root or window in question" bug. Woo-woo! + + From Mehul N. Sanghvi : + Additional tweaks to the *akefile*s for more flexible + installations. + + September 10 & 11, 1999 + Moved the man page into the doc directory. On request, renamed + the lnf directory to contrib. + + [*akefile*] [events.c] [menus.c] [resize.c] + Changed the *akefile*s to accomodate the above, as the man + page is now included in 'make install'. Reverted the setting + of the context of a door's frame to that prior to the change + on May 13 (it wasn't needed after all). Added code to prevent + iconifying windows that don't have provision to deiconify or + otherwise restore them. Fixed f.destroy and f.delete so that + they can be safely used on doors, icon managers, and the + virtual desktop. Fixed the zooming of doors, icon managers + and the virtual desktop so that their contents adjust to the + new size. + + June 18 & 22, 1999 + [menus.c] [parse.c] [twm.c] [util.c] [screen.h] + Fixed a bug, noted by "digs", where the truncation of long + titles messed up in titlebars that don't have any left-side + buttons. Added a new variable to see that iconified transient + windows of an iconified parent window aren't deiconified when + that parent is. + + Added the following variable: + DontDeiconifyTransients + + May 22, 1999 + [applets.c] [icons.c] + The same small tweak in both to have the region layout + logic disregard grid spacing in determining whether a + window will fit (clarified the man page accordingly). + + May 10 & 13, 1999 + [doors.c] [events.c] [menus.c] [util.c] + Relaxed the door geometry parser, allowing omission of + the position. Fixed a bug where rodent button events on a + door's frame didn't correctly set the context, and added + a kludge to "fix" not getting the rodent button up event. + Applied the XPM library's color closeness attribute to + external pixmap images. Updated the resource files in lnf + to demonstrate some of m4's capabilities. + + April 26 & 27, 1999 + [*akefile*] [add_window.c] [applets.c] [doors.c] [events.c] + [gram.y] [icons.c] [menus.c] [parse.c] [regions.c] [twm.c] + [regions.h] [screen.h] + By cleverly re-using the code for icon regions, a new window + management scheme, applet regions, is born! Moved the generic + functions of icons.c into a new regions.c, renamed icons.h + to regions.h, copied and modified the remaining icons.c to + create applets.c, and made all this known to the rest of the + modules above. Setting up all those little tool applications + is now just a matter of dropping them into a list resource! + + Added the following variable: + AppletRegion g s s n n l + + February 28 & March 1, 1999 + [doors.c] [events.c] [iconmgr.c] [menus.c] [resize.c] [events.h] + Doors, icon managers, and the virtual desktop now get redrawn + during opaque resizes (I have yet to figure out how to redraw + doors during interactive creation). The first two also have + minimum sizes imposed on them now. Fixed the icon manager's + class assignment; it's visible to resource list entries now. + Skip re-mapping of the virtual desktop to clean up outline + droppings if the window moved or resized is itself. + + February 22 & 23, 1999 + [desktop.c] [menus.c] [resize.c] + Added a trap to prevent resizing windows via the virtual + desktop (it's horribly broken). Imposed a minimum size on + the virtual desktop, that of the scaled real screen. + + February 20, 1999 + [add_window.c] [events.c] [parse.c] [twm.c] + The window's icon name now has it's own memory space; this + to keep some apps from blowing VTWM out of the water when + they change it. Added support for user-defined m4 parameters + passed from the command line. + + February 15 & 16, 1999 + [desktop.c] [icons.c] [parse.c] [twm.c] [screen.h] + If the RealScreenBorderWidth resource is defined, is there any + reason why the UseRealScreenBorder resource wouldn't be? More + fixes for the virtual desktop; these to properly accomodate the + real screen's border. + + From Caveh Frank Jalali : + A last tweak for icon images on multiple screens. + + Removed the following variable: + UseRealScreenBorder + + February 10 & 13, 1999 + [events.c] [resize.c] [util.c] + Hacked in code to see that the virtual desktop's bevel gets + redrawn after being resized. Ick. + + From Caveh Frank Jalali : + Tweaks to correct the painting of external images on + multiple screens. + + February 5 - 9, 1999 + [system.vtwmrc*] [desktop.c] [doors.c] [events.c] [parse.c] + [twm.c] [util.c] [screen.h] [twm.h] + Doors and the virtual desktop can now be rendered in 3D. + Doors now override real screen snapping on entry. Fixed a + few bugs regarding the virtual desktop when it's resized; + these may have been responsible for the problems noted in + previous releases, because they don't happen anymore! + Added a resource to override title truncation when in short + titlebars and icon managers. + + Added the following variables: + DoorBevelWidth n + VirtualDesktopBevelWidth n + NoPrettyTitles + + January 30, 1999 + [*akefile*] [menus.c] [parse.c] [twm.c] [version.c] + Added compiled-in options to the build info in the version + window. + + From Jason Gloudon : + Added m4 pre-processing of resource files. Woo-woo! + + January 10 & 14, 1999 + [add_window.c] [doors.c] [menus.c] [parse.c] + Added proper tests for success of XGetWindowProperty() calls + to fix getting icon names, window states, and pixel atoms from + the X server. Fixed a bug in the display of a renamed door. + + December 26 & 28, 1998 + [icons.c] [twm.c] [util.c] [screen.h] + Fixed a bug where icon bitmaps were rendered with the wrong + color. The X database resource "*bitmapFilePath" is now + searched for pixmap image files, like that for bitmap image + files. + + December 10 & 14, 1998 + [desktop.c] [menus.c] [parse.c] [twm.c] [menus.h] [parse.h] + [screen.h] + Non-nailed icons can now stay put at their locations on the + virtual desktop. The titlebar height now adjusts to external + button images. Added a few button image files to lnf. + + Added the following variable: + StaticIconPositions + Added the following function: + f.staticiconpositions + + November 15 - 16, 1998 + [Imakefile] [desktop.c] [events.c] [menus.c] + Fixed the PanResistance resource's not recognizing when the + pointer has left the autopan windows. Fixed the "orphaning" + of intermediate parent menu(s) when skipping them for some + superior parent menu. + + From Steve Ratcliffe : + Moved $(NO_XPM_SUPPORT) into DEFINES for global + visibility, and removed several SpecialObjectRule()s. + + From Michel Eyckmans : + Fixed deferred execution on keyboard events when the + root window has focus. + + September 27, 1998 + [menus.c] [resize.c] [version.c] + + From Goran Larsson : + Fixed text display bug in the size and position windows. + + VTWM 5.4.5a released for public consumption. + vtwm-5.4.5-to-5.4.5a.txt patch file released. + + September 14, 1998 + Established a directory, doc, for all the documentation + that has accumulated through time. The HINTS file is now + called INSTALL, and is more comprehensive. + + [util.c] + The menu, resize and X logo built-in bitmaps now account + for the ButtonBevelWidth variable. + + VTWM 5.4.5 released for public consumption. + + September 8 - 10, 1998 + [events.c] [iconmgr.c] [parse.c] [twm.c] [screen.h] + Fixed a bug with icon manager geometries that would blow + VTWM out of the water. Added code to make it a little + harder to accidentally pan to an adjacent virtual screen. + + Added the following variable: + PanResistance n + + September 4 - 5, 1998 + [events.c] [menus.c] [resize.c] [resize.h] + Fixed another pixmap oversight, this one for icons, + noted by C. F. Jalali. Applied the MoveDelta variable + to window resizing and initial menu highlighting. + + From Steve Ratcliffe : + Fixed a bug for the AutoPan variable, when the pan + windows are obscured by a newly-raised window. + + September 2, 1998 + [add_window.c] [desktop.c] [util.c] [util.h] + Plugged a memory leak, as noted by Jason Gloudon, where + transparent pixmap resources weren't freed before re-use. + + August 23 - 27, 1998 + [add_window] [events.c] [icons.c] [menus.c] [parse.c] [twm.c] + [util.c] + Fixed a bug where the titlebar highlight wasn't + erased when focus was unset and the BeNiceToColormap + and SunkFocusWindowTitle variables were used. + + From Steve Ratcliffe : + Tweaks to suppress menu highlighting on mapping, + relieve CPU consumption on menus bound to rodent + buttons, and allow a second rodent button press to + cancel menus. A safer approach to the RaiseDelay + variable's timeout. + + From Jason Gloudon : + Tweaks to streamline icon bitmap handling, and + fixed the painting of non-transparent titlebar + highlight pixmaps. + + From Caveh Frank Jalali : + Fixed a bug I introduced where non-3D borders were + always rendered as highlighted! Tweaks to correct + the painting of built-in images on multiple screens. + Fixed some bugs in colormap management. Tweaks for + application-defined icon border widths. + + August 10 - 14, 1998 + All references to and mention of the shadow contrast and + shadow width variables have been changed to *BevelContrast + and *BevelWidth. + + [add_window.c] [doors.c] [events.c] [iconmgr.c] [icons.c] + [menus.c] [parse.c] [resize.c] [twm.c] [util.c] [version.c] + [screen.h] + Fixed an oversight, color (XPM) image support for the + UnknownIcon variable and application-specified icons. + Window buttons are now beveled when external images are + used. The *BevelWidth variables render the UseThreeD* + variables obsolete. The ThreeDBorderWidth variable is + superfluous, too, no? + + Removed the following variables: + UseThreeDBorders + UseThreeDIcons + UseThreeDIconManagers + UseThreeDMenus + UseThreeDTitles + ThreeDBorderWidth n + Added the following variables: + ButtonBevelWidth n + IconBevelWidth n + Changed the following variable: + UnknownIcon s + + July 31 & August 3, 1998 + Discovered that VTWM supports a subset of regex wildcards for + list variables! It's in the man page now. + + [events.c] [menus.c] [twm.c] [twm.h] + Another tweak to the f.warpclass* functions, to properly + handle multiple icon managers. Added a signal handler for + external restarts (adapted from TVTWM pl11). + + July 15 - 17, 1998 + [desktop.c] [menus.c] [parse.c] [resize.c] [parse.h] + Added code to restart using a specified window manager. + A few changes to grab the server during non-opaque moves + and resizes, regardless of the NoGrabServer variable. + + Added the following function: + f.startwm s + + July 2 & 14, 1998 + [events.c] + Made the borders of windows without titlebars forward key + events to the application, like titlebars do. I think the + various warps from icon managers are sorted out now. + + June 25, 1998 + [gram.y] [menus.c] [parse.c] [twm.c] [screen.h] + Aliased a new variable, OldFashionedVtwmWindowsMenu, to the + OldFashionedTwmWindowsMenu variable, just for consistancy. + + From Erik Agsjo : + Added code to support two new variable(s). + + Added the following variables: + DontShowInTwmWindows l + DontShowInVtwmWindows l + OldFashionedVtwmWindowsMenu + + June 10 - 15, 1998 + [events.c] [iconmgr.c] [menus.c] + Had to make an exception for icon managers regarding warps, + that their window border isn't the destination, because I + can't figure out how to make the appropriate entry active + when one isn't without screwing up something else. BAH! Added + a few "prevents" when there isn't an icon manager mapped. The + f.warpclass* functions now behave correctly when an empty + string is used on windows without titlebars or on VTWM-specific + windows. + + June 3 - 6, 1998 + [add_window.c] [desktop.c] [events.c] [menus.c] [resize.c] + Made initial window placement adjust to client borderwidths, + depending on related variables. The virtual desktop is now + re-mapped after non-opaque moves and resizes to clean up any + outline droppings left on it when the Virtual*MotionEvents + variables are set. The window border of the virtual desktop + now honors key bindings to "virtual". Doors and their borders + are now sensitive to key bindings, too. + + May 27, 1998 + [events.c] [parse.c] [twm.c] [screen.h] + Added code to not set focus from icon manager entries to + the corresponding application windows, for binding keys that + otherwise would get forwarded. + + Added the following variable: + NoIconManagerFocus + + May 24, 1998 + Established a directory, lnf (look n' feel), for the previously + included sample resource and image files, and added a couple + more to it. Renamed some files: marcel.vtwm to .vtwmrc-marcel, + djhjr.vtwmrc to .vtwmrc-95ish, djhjr.vtwmpm to djhjr.xpm, + realscr.bm to nestedsqu.xbm, and siconify.bm to siconify.xbm. + + [iconmgr.c] [util.c] + Changed to handle the above. + + May 17 - 23, 1998 + [add_window.c] [desktop.c] [iconmgr.c] [menus.c] [twm.c] [util.c] + [screen.h] [util.h] + Found and plugged the hole in the original menu handler that + would blow VTWM out of the water when the pointer scrolled + down past the last entry. Gave the icon manager and virtual + desktop resource classes. The f.warpclass* functions will now + exhibit reasonable behavior when an empty string is used on + windows without titlebars or on VTWM-specific windows. The + three entries of the Pixmaps variable now fully support color + (XPM) images - this does render the nexpm utility obsolete in + regard to VTWM, but it's still included in the distribution. + The external image support for window buttons is better, but + still not perfect (see BUGS). + + Changed the following variable: + Pixmaps l + + May 11 - 13, 1998 + [add_window.c] [events.c] [menus.c] [twm.h] + The f.warpclassprev and f.warpclassnext functions now accept + an empty string, meaning the class of the window with focus, + and the first actually goes backwards now! Tweaks made to those + and the f.warpring function so its destination is a titlebar or + border like the other warp functions, and it now remembers the + window to warp to when invoked from the root window, unless the + target window was unmapped (leaving the pointer on the root + window), in which case it will no longer skip the first window + in the ring. All warping functions now honor the WarpUnmapped + variable a la the f.warpto function. + + Changed the following functions: + f.warpclassprev s + f.warpclassnext s + f.warpnewest + f.warpring s + f.warptoiconmgr s + + April 26 - May 5, 1998 + [add_window.c] [desktop.c] [events.c] [gram.y] [iconmgr.c] + [icons.c] [menus.c] [parse.c] [resize.c] [twm.c] [util.c] + [menus.h] [screen.h] [twm.h] + The 3D rendition of icons is now governed by its own variable. + The 3D bevel widths are configurable now, and related elements + are sized and positioned accordingly. Virtual window geometries + now account for 3D borders. Virtual-to-real window scaling and + positioning errors have been reduced. The position window now + reports during moves in the virtual desktop. Re-instated the + effects of the RightHandSidePulldownMenus variable! Changed the + foreground color for the built-in "TwmWindows" menu to that of + the global variable, and aliased it's name to "VTWM Windows", + just for consistancy's sake. + + Added the following variables: + UseThreeDIcons + BorderBevelWidth n + IconManagerBevelWidth n + InfoBevelWidth n + MenuBevelWidth n + TitleBevelWidth n + + From Nelson H. F. Beebe : + Even more tweaks for portability, most notably, restoring + X11R4 compatability by not including the X11R5,6 headers + Xosdefs.h and Xfuncs.h! X11R5,6 don't seem to mind. + + April 20 - 23, 1998 + [nexpm/nexpm.c] + + From Steve Ratcliffe : + Added a test for the child window of the selected window. + + [*akefile*] [add_window.c] [desktop.c] [doors.c] [events.c] + [lex.l] [menus.c] [parse.c] [twm.c] [util.c] [doors.h] [parse.h] + Purged GNU-specific syntax from this new Imakefile, and changed + the NO_PUTENV definition to NEED_PUTENV_F, for consistancy. + Added code to support pasting a name into a door (adapted from + VTWM 5.2b). + + Added the following function: + f.namedoor + + From Steve Ratcliffe : + Many tweaks made in the name of Portability. The snug + variables now take border width into account. + + From Nelson H. F. Beebe : + Many more tweaks for portability's sake. + + April 14 - 17, 1998 + [add_window.c] [desktop.c] [menus.c] [parse.c] [resize.c] + [twm.c] [resize.h] [screen.h] + When windows are created, they now honor the opaque variables + when the RandomPlacement variable is not set. While moving and + resizing windows on the real screen, the virtual desktop now + responds in kind, and visa-versa. The NoGrabServer variable now + sees to it the server is actually not grabbed! The position + window now reports during constrained moves. + + Added the following variables: + VirtualReceivesMotionEvents + VirtualSendsMotionEvents + + April 1 - 8, 1998 + [*akefile*] [system.vtwmrc*] [add_window.c] [gram.y] [menus.c] + [parse.c] [resize.c] [twm.c] [util.c] [screen.h] [twm.h] [util.h] + Added a define supporting a 2D or 3D system default resource + file, and made that file a bit more useful. Added code for + opaque resizing, and all opaque variables now support lists. + Many tweaks to make titlebar-related variables consistant with + respect to each other and 3D rendition of the various elements. + + Added the following variables: + OpaqueResize [l] + NoOpaqueResize [l] + NoOpaqueMove [l] + Changed the following variable: + OpaqueMove [l] + + March 29 - 30, 1998 + [Imakefile] [events.c] [util.c] + Added the system Imake.tmpl macro for flex's library (should + be absent or an empty string on systems with lex). Added code + to properly truncate, then add ellipses to, titles that are + longer than the space they're drawn on. + + March 23 - 24, 1998 + [gram.y] [util.c] + Fixed the rendition of a squeezed titlebar's right-side 3D + border (a silly gunkulation error). + + From Jason Gloudon : + Support for bison. + + March 20 - 22, 1998 + [add_window.c] [util.c] [version.c] + Added color image (XPM) support for window buttons. Jason's + code for color icon images made it a breeze, but it's not + perfect (see BUGS). + + VTWM 5.4.4c released for public consumption. + vtwm-5.4.4b-to-5.4.4c.txt patch file released. + + March 14 - 15, 1998 + [events.c] [menus.c] [version.c] + Fixed a bug where the window buttons would get painted with + the border color when the background color should have been + used. + + From Steve Ratcliffe : + Fixed warping to titlebars not flush left. + + VTWM 5.4.4b released for public consumption. + vtwm-5.4.4a-to-5.4.4b.txt patch file released. + + February 5, 1998 + [*akefile*] [events.c] [menus.c] [util.c] [version.c] + Tweaks to accomodate the following made to the *akefile*s. + + From Takeharu Kato : + Fixed a fault causing a SIGSEGV in the info window, + and the use of a depreciated constant in the XPM library. + + VTWM 5.4.4a released for public consumption. + vtwm-5.4.4-to-5.4.4a.txt patch file released. + + February 2, 1998 + VTWM 5.4.4 released for public consumption. + + January 27, 1998 + [add_window.c] [iconmgr.c] [parse.c] [twm.c] [screen.h] [gram.y] + Added a variable to tell the icon manager whether or not to + highlight its entries as an indication of pointer location, + regardless of the NoHighlight variable. + + Added the following variable: + NoIconManagerHighlight + + From Nicholas Jacobs : + A better effort at getting a name for the window. + + January 24, 1998 + [desktop.c] [menus.c] + Allow screen warps to honor the SnapRealScreen variable. + Added a kludge to "fix" screen warps to deiconifying windows + not on the real screen (high degree of confidence it's not + the source of the problem). + + January 21, 1998 + Added the HINTS file to the distribution. Moved and added many + function declarations into header files (quieter builds!). Other + miscellaneous tweaks. + + December 28, 1997, January 1 - 19, 1998 + [nexpm/nexpm.c] + Changed the window name sought by `nexpm -vtwm ...` to match + the virtual desktop's name. It's a wonder nobody's noticed! + + [*akefile*] [add_window.c] [cursor.c] [desktop.c] [doors.c] + [events.c] [gc.c] [icons.c] [list.c] [menus.c] [parse.c] [resize.c] + [twm.c] [util.c] [util.h] [version.c] [screen.h] [gram.y] + Rewrote most of the 3D border code, adding, among other things, + drawing the top border segment when 3D borders are used with + squeezed titlebars! Simplified the meaning of the SqueezeTitle + variable list parameters. Fixed a bug causing SIGFPEs when pan + distances are set to zero. Added a bug workaround to try to + make managed windows used as transients behave, a la the + FixTransientVirtualGeometries variable (seldom needed, just as + bad, but mostly works). Fixed an oversight of mine, not + initializing monochrome GCs! Enabled a variable to go easy on + the colormap (doesn't render perfectly yet). Use the system + Imake.tmpl macro for yacc and removed all escaped characters + from the lastmake.c rule in the *akefile*s. Clarified the pan + distance variable descriptions in the man page. + + Added the following variables: + BeNiceToColormap + FixManagedVirtualGeometries + + From Nelson H. F. Beebe : + On startup, VTWM now searches for user and system .vtwmrc + files, then user and system .twmrc files, in this order. + Fixed and added many declarations and definitions. Updated + the man page. Support for HTML and Postscript versions of + the man page added to the *akefile*s. + + From Jason Gloudon : + Color image (XPM) support for icons. + + Added a pixmap (djhjr.vtwmpm) referenced in my resource file + (djhjr.vtwmrc) for an example of the nexpm utility. + + Pruned the R4 Imakefile from the tree. + + Pruned the vtwmrc/ directory from the distribution tree. No offense + to Mr. Betza, but it made little sense (to me), was five years old, + was very esoteric, and anyone who wants it probably already has it. + + November 17, 1997 + VTWM 5.4.3 released for public consumption. + + November 17 - 19, 1997 + [events.c] [menus.c] [util.c] [util.h] [version.c] + Fixed a bug where the wrong variable was being used to + highlight the window border that has focus. Fixed an omission + where the window buttons would not follow the border color + when highlighted and the ButtonColorIsFrame variable is true. + Added a hack to trap corrupted/invalid window button names. + + October 27, 1997 + VTWM 5.4.2 released for public consumption. + + March 12 - 14, 1997 + [add_window.c] [menus.c] [twm.c] [util.c] + Added code to properly paint the window buttons in the same + color as their titlebar on a restart operation. Woo-woo! + Numerous changes to accomodate added buttons and squeezed + titlebars - I had previously overlooked these. Made a few + variables un-alterable when 3D appearances are used. Now + closes the display before spawning the new WM on a restart + operation - free alloc'd memory in the X server? + + September 25 - 26, 1996 + [menus.c] + Changed code to properly scale menus to the fonts used. + + September 14 - 21, 1996 + [*akefile*] [add_window.c] [iconmgr.c] [menus.c] [resize.c] + [twm.h] [util.c] [version.h] [*akefil*] [vtwm.man] + Fixed a bug in zooms that I introduced! Applied the backing + store and NoBackingStore variables to the Icon Manager and + titlebars (defeats effects of RaiseDelay). Made the pointer + warp to the titlebar on a zoom operation if WarpCursor is + set on. The function f.showdesktopdisplay now deiconifies as + required. Working on code to make the window buttons stay the + same color as their titlebar on a restart operation (obviously + wasn't thought about much before). Added build info to the + version window by having the *akefile*s create a temporary C + module. + + Added the following variable: + ButtonColorIsFrame + + September 10 - 12, 1996 + [events.c] [menus.c] + Added code preventing the virtual desktop window and Door + windows from doing harm. Fixed a bug when trying to move the + virtual desktop window with the pointer; see the notes in + djhjr.vtwmrc pertaining to the virtual desktop, it's related, + and the BUGS file. + + June 26, 1996 + [screen.h] [parse.c] [twm.c] [util.c] [vtwm.man] + Tweaked the 3D menu icons to look a little more like menus. + Made the 3D Icon Manager iconified indicators "shallow" to + match the 3D menu icons. Added code for Motif-ish "shallow" + relief in 3D titlebars and buttons to matches the others. + + Added the following variable: + ShallowReliefWindowButton + + June 11, 1996 + [icons.c] [events.c] + Tweaked the hard-coded geometries for a better 3D appearance + on icons (looks best with IconBorderWidth set to 0). + + April 18 - May 19, 1996 + [add_window.c] [desktop.c] [doors.c] [doors.h] [events.c] + [gram.y] [iconmgr.c] [iconmgr.h] [icons.c] [menus.c] [menus.h] + [parse.c] [resize.c] [screen.h] [twm.c] [twm.h] [util.c] [util.h] + [version.c] + Modifications and/or additions to the above modules for + a 3D appearance, menu separators, a position window, info + window fonts, resize/position window locations, and other + minor tweaks (listed below). All should be initialled and + dated. Changed as many as convenient boolean shorts to bits in + a Slim-Fast effort (the only executable code changed was due + to renaming the variable SnapRealScreen to snapRealScreen; the + shorts maybe reinstated with '#define ORIGINAL_SHORTS'). + Changed "Twm Door" to "VTWM Door", in the name of Consistancy. + Changed "Virtual Desktop" to "VTWM Desktop". Ditto. Changed the + code to center Door names in their windows. It *is* correct, + but only looks more correct. Took liberties with the + SunkFocusWindowTitle function. I think it more pleasing. Took + liberties with other code too, look for '#ifdef ORIGINAL_'. + A couple of changes for a cleaner compile (what were 'int' + functions are now 'void', etc.). Rem'd out code no longer + valid due to these changes. + + Added the following variables: + SunkFocusWindowTitle + UseThreeDIconManagers + UseThreeDMenus + UseThreeDTitles + UseThreeDBorders + ThreeDBorderWidth n + ClearBevelContrast n + DarkBevelContrast n + InfoFont s + ResizeRegion s + Added the following function: + f.separator + + Updated the man page. + Included my .vtwmrc (djhjr.vtwmrc) in this distribution. + + See also the files 4.ANNOUNCE, 4.README, and BUGS. + +============ vtwm-5.3.tar.gz ============= +dsembr01@starbase.spd.louisville.edu (Darren S. Embry) + + Tuesday, 1994 January 4, 16:43:32 EST + [menus.c] Autopanned windows are now raised when Autopan is + turned back on via f.autopan. + + Monday, 1994 January 3, 20:49:22 EST + f.stickyabove (or f.nailedabove) + + Monday, 1994 January 3, 19:29:07 EST / dsembr01 + [twm.c] The "VTWM Profile" function is now executed after + starting/restarting the window manager. + + Friday, 1993 November 26, 15:37:01 EST / dsembr01 + [vtwm.man] Some previously undocumented functions have now + been documented. Please use them at your own risk: + + f.cut + f.cutfile + f.file + f.movescreen + f.twmrc [same as f.restart anyway] + f.version + + Saturday, 1993 November 6, 19:03:28 EST / dsembr01 + [desktop.c] Small bug fix regarding representations of + nailed windows on the virtual desktop; it was obvious and + obviously unintentional. + + Tue Nov 2 20:05:44 EST 1993 dsembr01 + WarpSnug + + Wed Oct 27 12:29:38 EDT 1993 dsembr01 + MenuTitleFont (this code also came from tvtwm) + + Tue Oct 26 19:41:04 EDT 1993 pf@z-code.z-code.com (Paul Falstad) + NoIconifyIconManagers + StayUpOptionalMenus + WarpToTransients + f.warp + f.warpclassnext + f.warpclassprev + f.warptonewest + + Mon Oct 25 21:08:40 EDT 1993 dsembr01 + If StickyAbove is set, f.nail will raise all sticky windows + to make sure nailed windows stay above. + + Mon Oct 25 19:48:33 EDT 1993 dsembr01 + FixTransientVirtualGeometries, a BUG WORKAROUND!! + (Any better ideas, folks? -- DSE) + + Mon Oct 25 17:13:00 EDT 1993 dsembr01 + DontInterpolateTitles, from tvtwm -- thanks to + cross@eng.umd.edu (Chris P. Ross) for letting me use his + code. + + Sun Oct 24 16:16:52 EDT 1993 dsembr01 + f.lower now won't lower the window if it is nailed down and + StickyAbove is set. + + Tue Oct 19 18:03:35 EDT 1993 dsembr01 + StickyAbove (I didn't take any of the code for this from + tvtwm; just the idea.) + + Mon Oct 18 21:14:04 EDT 1993 dsembr01 + Fixed autopanning bug that would *sometimes* not allow + AutoPan to work if the focus was on a window, since + the autopan windows (on the edges of the real screen) + weren't raised. + + Sat Oct 16 18:23:43 EDT 1993 dsembr01 + Nailed windows now *always* go on the real screen, wherever + the real screen is. + + Wed Oct 13 12:21:54 EDT 1993 dsembr01 + Aliased "f.stick" to "f.nail", for greater compatibility + (or less incompatibility) between .vtwmrc and .tvtwmrc, + just for the hell of it. + + Mon Oct 11 21:06:09 EDT 1993 dsembr01 + Fixed a bug that would make the window manager mess up if + "AutoPan 100" and "AutoPanWarpWithRespectToRealScreen 100" + (a.k.a. "NaturalAutoPanBehavior") were set. I wanted to + set my window manager to behave like fvwm (in the + autopanning sense of the word) when I discovered this. + + Mon Oct 11 09:14:58 PDT 1993 leisner@eso.mc.xerox.com (Marty Leisner) + Included small patches to Imakefile from Marty Leisner. + + Mon Oct 11 17:04:35 EDT 1993 dsembr01 + NoDefaultTitleButtons + NoDefaultMouseAndKeyboardBindings + so someone could use either the default title or + keyboard bindings, but not necessarily both. + +============ vtwm-5.2.2.tar.gz ============= + + dsembr01@starbase.spd.louisville.edu (Darren S. Embry) + Used another bug workaround to support negative door + geometries; the old one I did messed up with positive door + geometries, especially "+0+0". + +============ vtwm-5.2.1.tar.gz ============= + + dsembr01@starbase.spd.louisville.edu (Darren S. Embry) + AutoPanBorderWidth + AutoPanExtraWarp + AutoPanWarpWithRespectToRealScreen + EnhancedExecResources + LessRandomZoomZoom + NaturalAutopanBehavior + PrettyZoom + RealScreenBorderWidth + RightHandSidePulldownMenus + + Support for negative and "0,0" door geometries. + +============ vtwm-5.2.tar.Z ============= + +Various contributions: + + gnohmon@ssiny.com (Ralph Betza) + f.zoomzoom + StayUpMenus from tvtwm code + OldFashionedTwmWindowsMenu + UseRealScreenBorder + f.snaprealscreen + + Improved window movement in the panner + Restored the ability to rescale the desktop + + futzi@uni-paderborn.de (Michael Kutzner) + Class-name was compared twice in menus.c + (applies also to vtwm-5.0) + + Stig Ostholm + Problem when windows are resized without vtwm interaction + cleaning up of the desktop code to minimize vtwm - server + interaction. + Imakefile patch allows vtwm to be installed in another + location + (applies also to vtwm-5.0) + + eyckmans@imec.be (M. Eyckmans) + Allow #rrggbb colors in X11R4 + + Tony Brannigan + AutoPanX, AutoPanY + + dana@thumper.bellcore.com (Dana A. Chee) + Added fix which allows key presses to move a window (menus.c, + events.c) + + Alec Wolman + WindowRing can now specify "all windows" by leaving off the + Window List + + Can specify x or y = 0 in door location now + +Tue Jul 20 15:22:49 EDT 1993 + Thu Oct 1 17:47:37 1992 Dana A. Chee (dana@dino) + * Added fix which allows key presses to move a window (menus.c, + events.c) + Fri May 29 14:20:53 1992 Dana A. Chee (dana@dino) + * Fixed bug in do_single_keyword (break should be return), sent in + by George Ross (parse.c) +[Editor's note: a very popular bug to send in the fix for!] + * Autoraise can now specify "all windows" by leaving off the + Window List, sent in by Alec Wolman +[Editor's note: this was previously done by the RaiseDelay patch] + * WindowRing can now specify "all windows" by leaving off the + Window List, sent in by Alec Wolman + (add_window.c, gram.y, screen.h, twm.c, vtwm.man) + * Initial Placement of virtual desktop fixed, sent in by Alec Wolman +[Editor's note: this was previously done] + * Can specify x or y = 0 in door location now, sent in by Alec + Wolman (doors.c) + * Update man page to mention NoVirtualGeometries variable + (vtwm.man) + * Updated patchlevel (patchlevel.h) +[Editor's note: we don't have one! ] + Thu Mar 26 12:31:09 1992 Dana A. Chee (dana@dino) + * F_LOWER now lowers the window in the virtual desktop as well + +Thu Jul 15 14:03:01 DST 1993 Marcel Mol (marcel@duteca.et.tudelft.nl) + * Includes F_WARPTO patch from futzi@uni-paderborn.de (Michael Kutzner) + Patched this patch to check for name, class and classname in a + single for loop. + * Changed syntax of 'VirtualDesktop' variable. Now can set desktop + as number of screens, as size of virtual desktop window or as + size of whole desktop. + * Fixed unharmful bug when NotVirtualGeometries was set. + (vtwm comlains about "unknown singleton keyword") + * Added f.virtualgeometries function to toggle virtual geometries + settings. + * Added f.deletedoor function to delete a door. Don't know if I + correctly released all memory allocated to the door. Any X-Wizard??? + * Updated man page + +========= vtwm-5.1.tar.Z ============== + +Thu Jun 24 15:24:36 EDT 1993 Ralph Betza (gnohmon@ssiny.com) + + * Includes RaiseDelay patch from + Warren Jessop, University of Washington, whj@cs.washington.edu + + * Includes snug patch from thoth@reef.cis.ufl.edu (Gilligan) + + * Includes patch vtwm.5.1.ptch from tar@math.ksu.edu (Tim Ramsey) + + * Includes panner background pixmap, panner foreground color, + dynamic warpring, dynamic squeezetitle, TWM-Window menu + colors, RealScreen foreground, background, and colors, + corrections to placement of the little windows in the + panner, additional cursors, and maybe a few other things I + forgot to mention, from me, + Ralph Betza (gnohmon@ssiny.com) + +Tue Mar 24 13:15:11 1992 Dana A. Chee (dana@dino) + + * fixed problem with key presses in virtual desktop not working + (had an if test wrong in events.c) + * released to export. + +Wed Feb 19 13:37:57 1992 Dana A. Chee (dana at dino) + + * Converted vtwm to use the source of twm from R5 (my base was + vtwm 4.0 gamma). Released it to export.lcs.mit.edu + * Cut and paste missed resize grabs, added them back in + * Botched ask_user stuff in add_window, fixed that up. + * Removed broken copy from export. + diff --git a/doc/DEVELOPERS b/doc/DEVELOPERS new file mode 100644 index 0000000..8eef831 --- /dev/null +++ b/doc/DEVELOPERS @@ -0,0 +1,33 @@ + +A FEW THOUGHTS TO FUTURE MAINTAINERS/DEVELOPERS/HACKERS +======================================================= + + - If you feel compelled to add more compile-time options (i.e., Java + support, etc.), please follow the "NO_" and "NEED_" conventions in the + make files. Also, add code as appropriate to menus.c:Identify() and + parse.c:make_m4_cmdline(). + + - Likewise, please follow what few coding conventions are in place. Don't + use C++'s double-slash comments, keep up with the K&R style functions, + etc. + + - Keep VTWM portable. There are only two "#ifdef __PLATFORM__"s in this + code, yet it runs on platforms I've never seen. GNU isn't everywhere. + Neither is POSIX or ANSI. Seek out variety through beta-testers in the + X-related newsgroups. Finally, remember that it's X11R4 compliant. + + - Just because you can't live without such-and-such doesn't mean everyone + can't. It's a window manager, not an environment. Help keep VTWM lean. + + - Add no memory leaks! I haven't read every line of this code, but have + had to fix very few, and have seen that none have been introduced. + 'Nuff said 'bout that. + + - Document! The code is a long commentary on VTWM's evolution, and though + it does get hard to read, I've come to think it a Good Thing. Keep the + files in the in the doc directory current. + +Sorry if this reads a little belligerent. I'm just tired of fighting all +sorts of platform-specific implementations and lazy coding practices while +porting stuff. I'm sure you are too. VTWM should never be such. --- djhjr + diff --git a/doc/HISTORY b/doc/HISTORY new file mode 100644 index 0000000..4bcfd0d --- /dev/null +++ b/doc/HISTORY @@ -0,0 +1,530 @@ + +VERSION HISTORY OF VTWM 5.4 +=========================== + +VTWM 5.4.7 + + New Features + - Added internationalization (I18N) support. + - Support ignoring "shift states" when determining if a key + or rodent button event is bound (added the IgnoreModifiers + variable). + - Support passing raw key and rodent button events to windows + (added the f.bindbuttons, f.bindkeys, f.unbindbuttons and + f.unbindkeys functions). + - Allow warp functions to position the pointer at the center + of windows (added the WarpCentered variable). + - Allow the 3D borders of titled windows to be unadorned (added + the NoBorderDecorations variable). + - Prohibit windows from being added to the WindowRing list + (added the NoWindowRing variable). + - Opened up icon managers and menus to user-specified images + (added the MenuIconPixmap and IconManagerPixmap keywords). + This gives the ShallowReliefWindowButton variable wider scope. + - Two new 3D built-in pixmaps, :xpm:box and :xpm:lines. + - Four new 3D built-in pixmaps for the titlebar highlight, + :xpm:raisedbox, :xpm:sunkenbox, :xpm:raisedlines, and + :xpm:sunkenlines. These obsolete the SunkFocusHighlightWindow + variable. + - The command line can specify that no startup file be used + (primarily for testing compiled-in defaults). + - Added support for Motif window manager hints (currently, honor + "noborder" and "notitle" hints). + - Allow sounds to be played "ad hoc" (added the f.playsound + function). + - Added PointerPlacement keyword. + Changed Features + - The UsePPosition variable accepts a list now. + - The f.warpto function accepts VTWM-style wildcards now. + - Refinements to the f.resize and f.move functions: Both are + now single rodent button operations from any context, and both + warp the pointer back to the virtual desktop when started from + there. The wireframe is drawn immediately, ignoring MoveDelta. + MoveDelta is otherwise used consistantly now. Constrain virtual + desktop resizes to multiples of PanDistance when SnapRealScreen + is set. + - Refinements to the titlebar: The title bevel can now frame the + entire titlebar when built-in 3D buttons are not full height. + Buttons can now "extend into" the title bevel and frame padding. + The highlight area (or absence of) is handled correctly now. + The built-in 3D highlight is now available with or without a + title bevel. The ButtonIndent, FramePadding, TitleBevelWidth, + and TitlePadding variables are changed. + - The TitleHighlight keyword accepts built-in pixmaps now, like + the LeftTitleButton and RightTitleButton bindings. + - The raise for moved and resized windows now occurs after the + movement (added the RaiseOnStart variable). + - Some shaping optimizations. + - Depreciated the motion event handler. + - Chmod 0600 $(HOME)/vtwm.pid. + - Let lexers track line numbers by default. + - Reduced the compiled-in defaults footprint. + Bug Fixes + - Fixed warp bugs when windows are borderless or shaped. + - Fixed some icon move and resize bugs. + - Fixed a vertical placement error in applet regions. + - Fixed most stacking order bugs when moving and resizing windows. + - Cancelled moves and resizes now work correctly, except one case. + - The pointer is adjusted back to the window as needed on resizes. + - Fixed some titlebar highlight exposure bugs. + - Fixed some off-by-clientborderwidth window placement bugs. + - Fixed an off-by-one malloc() and a null pointer reference. + - Checks for the number of rodent buttons and VTWM Windows entries. + - The f.warpring function has been fixed. Again. + - Fixed a race condition when f.squeeze* functions are invoked + from a window menu while Opaque* variables are set. + - Prevent f.squeeze* functions when the DontSqueezeTitle variable + is set. + - Removed the limitations of the f.startwm argument. + - Fixed the 3D borders of titled windows when the BeNiceToColormap + variable is set. + - Reduced server grabs. + - Better handling of missing or empty string resources. + - sound function referenced outside of ifdef. + Misc. + - Updated the man page, and the BUGS, INSTALL, SOUND, and WISHLIST + files. + - Updated the system and sample resource files. + - Updated contrib/support/sysrc_add_apps.sh. + +VTWM 5.4.6b (bugfix release) + + Fixed a bug causing sporadic restarts when realizing unmanaged + windows. + +VTWM 5.4.6a + + Support for borderless windows (added the NoBorder variable). + Better random placement of large windows. + Fixed bugs regarding icon managers and warp rings. + Doors are drawn during opaque interactive creation now. + MakeTitle now overrides NoTitle like it's supposed to. + Added creating and deleting a pid file. + Fixed a focus problem with transient windows. + Improved the list parser in contrib/support/sysrc_add_apps.sh. + +VTWM 5.4.6 + + New Features + - Added pre-processing of the resource file with m4. Parameters + can be passed on the command-line, too. + - Added support for regular expressions ("RE"s) in resource file + window lists. VTWM's own wildcarding is still honored. + - Sound effects are now supported, by way of the rplay library + and daemon (added the PauseOnExit, PauseOnQuit, SoundHost, + Sounds, SoundVolume, and f.sounds resources). + - Added applet regions. For all those handy little utilities we + use every day. + - Added "scrollability" to menus that would be taller than the + display (added the MenuScrollBorderWidth and MenuScrollJump + variables). + - Doors and the virtual desktop can now be rendered in 3D + (added the DoorBevelWidth and VirtualDesktopBevelWidth + variables). + - Non-nailed icons can now stay put at their locations on the + virtual desktop (added the StaticIconPositions and + f.staticiconpositions resources). + - Iconified transient windows of an iconified parent window can + now have their state preserved when that parent is + deiconified (added the DontDeiconifyTransients variable). + - Iconification of windows is now prevented when there is no + provision to deiconify or otherwise restore them. + - Icon managers can now list only iconified windows (added the + StrictIconManager and f.stricticonmgr resources). + - Added support for warping only to visible windows (added the + WarpVisible and f.warpvisible resources). + - Improved response to exposure events of transparent pixmaps + used for window buttons on pointer-driven focus changes. + - Added four built-in button images, two each of down and right + arrows. + Changed Features + - A small tweak in icon and applet regions to have the region + layout logic disregard grid spacing in determining whether a + window will fit. + - Relaxed the door geometry parser, allowing omission of the + position. + - Applied the XPM library's color closeness attribute to + external pixmap images. + - Doors, icon managers, and the virtual desktop have minimum + sizes imposed on them now. + - Doors now override real screen snapping on entry. + - Icon managers now honor the IconifyByUnmapping resource. + - Removed the UseRealScreenBorder variable. If it's non-zero, + why wouldn't you want to use it? + - Added compiled-in options to the build info in the version + window. + - The X database resource "*bitmapFilePath" is now searched for + pixmap image files. + - Random zooms during deiconification are controlled by a + resource now (added the ZoomZoom variable). + - The cursor stays with the titlebar on a squeeze operation, + like it does with zooms. + - All the f.*iconmgr warp functions honor the WarpSnug and + WarpWindows variables now (or absence of). The WarpSnug state + can now be toggled. + Bug Fixes + - Doors, icon managers, and the virtual desktop now respond to + zoom operations properly. + - Doors, icon managers, and the virtual desktop now get redrawn + during opaque resizes (redrawing doors during interactive + creation is still a problem). + - Fixed transposed virtual desktop default foreground and + background colors. + - Work on the bug where windows may be mapped in desktop (0,0) + regardless of the desktop's location in the virtual display. + - Fixed positioning errors for the icon manager and virtual + desktop windows. + - The virtual desktop's bevel and a door's text and bevel now + get redrawn after being resized. + - The virtual desktop now properly accomodates the real + screen's border. + - Skip re-mapping of the virtual desktop to clean up outline + droppings if the window moved or resized is itself. + - When moving an application window in the virtual desktop, the + border of the corresponding real screen window now highlights + as required. + - Windows can now be resized and moved from icon managers and + menus not of the root or window in question. + - Fixed window resizing via the virtual desktop and icon + managers. Fixed window moves (f.move) via the virtual desktop. + - Zooms know about icon managers now. + - Iconified icon managers now behave as one would expect when + removing the last entry in them. + - The f.delete and f.destroy functions now work properly on + doors, icon managers, and the virtual desktop. + - The f.hideiconmgr and f.showiconmgr functions now work + against icon managers defined with the IconManagers resource. + - Fixed bugs in getting icon names, window states, and pixel + atoms from the X server. + - Fixed where truncation of long titles messed up in titlebars + that don't have any left-side buttons. + - The titlebar height now adjusts to external button images. + - Sanity checks on door renames. Fixed two menu repaint bugs. + - Fixed a bug in the display of a renamed door. + - Tweaks to correct the painting of external images on multiple + screens. + - Fixed a bug where icon bitmaps were rendered with the wrong + color. + - Fixed the PanResistance resource's not recognizing when the + pointer has left the autopan windows. + - The icon manager's class is visible to resource list entries + now. + - The window's icon name now has it's own memory space. + Occasionally, VTWM would crash if an app changed it. + - Added a kludge to "fix" not getting the rodent button up + event when deleting doors. + - Fixed the "orphaning" of intermediate parent menu(s) when + skipping them for some superior parent menu. + - Fixed deferred execution on keyboard events when the root + window has focus. + Misc. + - Added support for the rplay library to the make files. + - Added support for regular expressions to the make files. + - Ensure the built-in resources and build info are current + (tweaks in the make files). + - The man page is now included on 'make install'. + - Also in the make files, moved the $(NO_XPM_SUPPORT) and + $(NO_M4_SUPPORT) defines into $(DEFINES), and removed some + SpecialObjectRule()s. Two new definitions and a different + directive make for more flexible installs. + - Renamed the lnf directory to contrib. Created subdirectories + therein for images, sounds, and misc. support stuff. Removed + the leading '.' from the resource file names. + - The system resource files are a bit more useful and appealing. + - A new script in contrib/support can add installed applications + to the system default resource file. + - Updated the sample resource files to demonstrate some of m4's + capabilities. + - Added some sample button image and sound files. + - Updated the BUGS, INSTALL, and WISHLIST files, and added the + HISTORY and SOUND files. + - Moved the man page into doc. + +VTWM 5.4.5a + + Fixed text display bug in the size and position windows. + +VTWM 5.4.5 + + New Features + - Added code to make it a little harder to accidentally pan to + an adjacent virtual screen (added the PanResistance + variable). + - Discovered that VTWM supports a subset of regex wildcards for + list variables! It's in the man page now. + - Added a signal handler for external restarts. + - Added code to restart using a specified window manager (added + the f.startwm function). + - Made the borders of windows without titlebars forward key + events events to the application, like titlebars do. + - Added and aliased the OldFashionedVtwmWindowsMenu variable to + OldFashionedTwmWindowsMenu. + - Added code to suppress entries in th VTWM Windows menu (added + the DontShowInVtwmWindows and DontShowInTwmWindows + variables). + - The window border of the virtual desktop now honors key + bindings to "virtual". + - Doors and their borders are now sensitive to key bindings. + - Added code to inhibit forwarding focus from icon manager + entries to the corresponding application windows (added the + NoIconManagerFocus variable). + - Established a directory, doc, for all the documentation that + has accumulated through time. + - Established a directory, lnf (look n' feel), for the + previously included sample resource and image files, added a + couple more, renamed some. + - Gave the icon manager and virtual desktop resource classes. + - The f.warpclassprev and f.warpclassnext functions now accept + an empty string, meaning the class of the window with focus. + - Added color (XPM) image support for the UnknownIcon variable + and application-specified icons (changed the UnknownIcon + variable). + - The three entries of the Pixmaps variable now fully support + color (XPM) images (changed the Pixmaps variable). + - The 3D rendition of icons is now governed by its own variable + (added the IconBevelWidth variable). + - The position window now reports during moves in the virtual + desktop. + - The position window now reports during constrained moves. + - Added code to support pasting a name into a door (added the + f.namedoor function). + - When windows are created, they now honor the opaque variables + when the RandomPlacement variable is not set. + - While moving and resizing windows on the real screen, the + virtual desktop now responds in kind, and visa-versa (added + the VirtualReceivesMotionEvents and VirtualSendsMotionEvents + variables). + - Added code for opaque resizing (added the OpaqueResize and + NoOpaqueResize variables). + - All opaque variables now support lists (added the + NoOpaqueMove variable, and changed the OpaqueMove variable). + - Added code to properly truncate, then add ellipses to, titles + that are longer than the space they're drawn on. + Changed Features + - Applied the MoveDelta variable to window resizing and initial + menu highlighting. + - Tweaks to suppress menu highlighting on mapping, relieve CPU + consumption on menus bound to rodent buttons, and allow a + second rodent button press to cancel menus. + - Tweaks for application-defined icon border widths. + - All references to and mention of the shadow contrast + variables have been changed to *BevelContrast (changed the + DarkShadowContrast variable to DarkBevelContrast, and the + LightShadowContrast variable to LightBevelContrast). + - All references to and mention of the shadow width variables + have been changed to *BevelWidth, and they are configurable + now (added the BorderBevelWidth, IconManagerBevelWidth, + InfoBevelWidth, MenuBevelWidth, TitleBevelWidth, and + ButtonBevelWidth variables; removed the UseThreeDBorders, + UseThreeDIcons, UseThreeDIconManagers, UseThreeDMenus, + UseThreeDTitles, and ThreeDBorderWidth variables). + - A few changes to grab the server during non-opaque moves and + resizes, regardless of the NoGrabServer variable. + - Changed the foreground color for the built-in "TwmWindows" + menu to that of the global variable (added and aliased "VTWM + Windows" to "TwmWindows"). + - Another tweak to the f.warpclass* functions, to properly + handle multiple icon managers. + - Had to make an exception for icon managers regarding warps, + that their window border isn't the destination. + - The f.warpclass* functions will now exhibit reasonable + behavior when an empty string is used on windows without + titlebars or on VTWM-specific windows. + - Tweaks made to the f.warpclass* variables and the f.warpring + function so the destination is a titlebar or border like the + other warp functions, and the latter now remembers the window + to warp to when invoked from the root window. + - All warping functions now honor the WarpUnmapped variable a + la the f.warpto function (changed the f.warpclassprev, + f.warpclassnext, f.warpnewest, f.warpring, and + f.warptoiconmgr functions). + Bug Fixes + - Fixed a bug with icon manager geometries that would blow VTWM + out of the water. + - Fixed a bug for the AutoPan variable, when the pan windows + are obscured by a newly-raised window. + - Plugged a memory leak, where transparent pixmap resources + weren't freed before re-use. + - Tweaks to streamline icon bitmap handling, and fixed the + painting of non-transparent titlebar highlight pixmaps. + - Tweaks to correct the painting of built-in images on multiple + screens. + - Window buttons can now be beveled when external images are + used. + - Fixed a bug where the titlebar highlight wasn't erased when + focus was unset and the BeNiceToColormap and + SunkFocusWindowTitle variables were used. + - A safer approach to the RaiseDelay variable's timeout. + - Fixed a bug I introduced where non-3D borders were always + rendered as highlighted! + - Fixed some bugs in colormap management. + - Added a few "prevents" when there isn't an icon manager + mapped. + - Made initial window placement adjust to client borderwidths, + depending on related variables. + - The virtual desktop is now re-mapped after non-opaque moves + and resizes to clean up any outline droppings left on it when + the Virtual*MotionEvents variables are set. + - Found and plugged the hole in the original menu handler that + would blow VTWM out of the water when the pointer scrolled + down past the last entry. + - Virtual window geometries now account for 3D borders. + - Virtual-to-real window scaling and positioning errors have + been reduced. + - Re-instated the effects of the RightHandSidePulldownMenus + variable! + - The snug variables now take border width into account. + - Fixed the rendition of a squeezed titlebar's right-side 3D + border (a silly gunkulation error). + - The NoGrabServer variable now sees to it the server is + actually not grabbed! + - The f.warpclassprev function actually goes backwards now! + - Many tweaks to make titlebar-related variables consistant + with respect to each other and 3D rendition of the various + elements. + Misc. + - Even more tweaks for portability, most notably, restoring + X11R4 compatability by not including the X11R5,6 headers + Xosdefs.h and Xfuncs.h! X11R5,6 don't seem to mind. + - Purged GNU-specific syntax from this new Imakefile, and + changed the NO_PUTENV definition to NEED_PUTENV_F, for + consistancy. + - Support for bison. + - Added a define supporting a 2D or 3D system default resource + file. + - Added the system Imake.tmpl macro for flex's library (should + be absent or an empty string on systems with lex). + - Renamed the HINTS file to INSTALL, and it's more + comprehensive now. + +VTWM 5.4.4c + + Added color image (XPM) support for window buttons. + +VTWM 5.4.4b + + Fixed a bug where the window buttons would get painted with the + border color when the background color should have been used. + Fixed warping to titlebars not flush left. + +VTWM 5.4.4a + + Fixed a fault causing a SIGSEGV in the info window. + Purged the use of a depreciated constant in the XPM library. + +VTWM 5.4.4 + + New Features + - Added a variable to tell the icon manager whether or not to + highlight its entries as an indication of pointer location, + regardless of the NoHighlight variable (added the + NoIconManagerHighlight variable). + - Enabled a variable to go easy on the colormap; it doesn't + render perfectly yet (added the BeNiceToColormap variable). + - Color image (XPM) support for icons. + - Added a bug workaround to try to make managed windows used as + transients behave (added the FixManagedVirtualGeometries + variable). + Changed Features + - Allow screen warps to honor the SnapRealScreen variable. + - Simplified the meaning of the SqueezeTitle variable list + parameters. + Bug Fixes + - A better effort at getting a name for the window. + - Added a kludge to "fix" screen warps to de-iconifying windows + not on the real screen (high degree of confidence it's not + the source of the problem). + - Rewrote most of the 3D border code, adding, among other + things, drawing the top border segment when 3D borders are + used with squeezed titles! + - Fixed a bug causing SIGFPEs when pan distances are set to + zero. + - Fixed an oversight where monochrome GCs weren't getting + intialized! + Misc. + - Added the HINTS file to the distribution. + - Moved and added many function declarations into header files + for quieter builds. + - Use the system Imake.tmpl macro for yacc and removed all + escaped characters from the lastmake.c rule in the + *akefile*s. + - On startup, VTWM now searches for user and system .vtwmrc + files, then user and system .twmrc files, in this order. + - Fixed and added many declarations and definitions. + - Updated the man page. + - Support for HTML and Postscript versions of the man page + added to the *akefile*s. + - Pruned the R4 Imakefile from the tree. + - Pruned the vtwmrc/ directory from the distribution tree. + +VTWM 5.4.3 + + Bug Fixes + - Fixed a bug where the wrong variable was being used to + highlight the window border that has focus. + - Fixed an omission where the window buttons would not follow + the border color when highlighted and the ButtonColorIsFrame + variable is true. + - Added a hack to trap corrupted/invalid window button names. + +VTWM 5.4.2 + + New Features + - Modifications for a 3D appearance, menu separators, a + position window, info window fonts, and resize/position + window locations (added the SunkFocusWindowTitle, + UseThreeDIconManagers, UseThreeDMenus, UseThreeDTitles, + UseThreeDBorders, ThreeDBorderWidth, ClearBevelContrast, + DarkBevelContrast, InfoFont, and ResizeRegion variables; + added the f.separator function). + - Added code to properly paint the window buttons in the same + color as their titlebar (added the ButtonColorIsFrame + variable). + - Now closes the display before spawning the new WM on a + restart operation - free alloc'd memory in the X server? + - Applied the backing store and NoBackingStore variables to the + Icon Manager and titlebars (defeats effects of RaiseDelay). + - Added code for Motif-ish "shallow" relief in 3D titlebars and + buttons to matches the others (added the + ShallowReliefWindowButton variable). + Changed Features + - Made a few variables un-alterable when 3D appearances are + used. + - Made the cursor warp to the titlebar on a zoom operation if + WarpCursor is set on. + - The function f.showdesktopdisplay now deiconifies as + required. + - Added build info to the version window by having the + *makefil*s create a temporary C module. + - Tweaked the 3D menu icons to look a little more like menus. + - Made the 3D Icon Manager iconified indicators "shallow" to + match the 3D menu icons. + - Tweaked the hard-coded geometries for a better 3D appearance + on icons (looks best with IconBorderWidth set to 0). + - Changed "Twm Door" to "VTWM Door", in the name of + Consistancy. + - Changed "Virtual Desktop" to "VTWM Desktop". + - Changed the code to center door window names in their + windows. + - Took liberties with the SunkFocusWindowTitle function. + - Changed as many as convenient boolean shorts to bits in a + Slim-Fast effort. + Bug Fixes + - Numerous changes to accomodate added buttons and squeezed + titlebars - I had previously overlooked these. + - Changed code to properly scale menus to the fonts used. + - Fixed a bug in zooms that I introduced! + - Added code preventing the virtual desktop window and door + windows from doing harm. + - Fixed a bug when trying to move the virtual desktop window + with the pointer. + Misc. + - A couple of changes for a cleaner compile (what were 'int' + functions are now 'void', etc.). + - Updated the man page. + +VTWM 5.4.0 - 5.4.1 + + No public release was made of versions before 5.4.2. + + diff --git a/doc/INSTALL b/doc/INSTALL new file mode 100644 index 0000000..bcdc103 --- /dev/null +++ b/doc/INSTALL @@ -0,0 +1,199 @@ + +BUILDING VTWM 5.4 +================= + + - Unpack the distribution. You've likely done that already, no? + + - Determine if you have the XPM library installed: + - The library is usually found in /usr/X11R6/lib, /usr/local/lib, + or some such directory. It's usually called "libxpm.a". + - The header file is usually found in /usr/X11R6/include, + /usr/local/include, or some such directory. It's "xpm.h". + + - Determine if you have regular expressions ("RE"s) support: + - On many systems, the routines are built into the standard + C library. If not, the library might be in /usr/local/lib, + /usr/lib, or some such directory, and would be called + something like "libregex.a". + - The header file is usually found in /usr/local/include, + /usr/include, or some such directory. It's "regex.h". + - Note that the routines must conform to the POSIX 1003.2 + specification. Older systems may have regex support that + predates this POSIX spec, and will not suffice. + + - Determine if you have the rplay library installed: + - The library is usually found in /usr/local/lib, /usr/lib, + or some such directory. It's usually called "librplay.a". + - The header file is usually found in /usr/local/include, + /usr/include, or some such directory. It's "rplay.h". + + - Determine if your system supports internationalization (I18N): + - On many systems, header files "locale.h" and "Xlocale.h" + are found in /usr/include and /usr/X11R6/include/X11, + respectively. + + - Determine if you have the m4 macro processor installed: + - Issuing 'whence m4' or 'which m4' ought to do it. + + - Look over Imakefile, and edit to taste. If you use a VNC client, or + Cygwin under MS-Windows, you may want to make changes as described + further down in this file. Or particular interest to some people + will be the installation path which can be changed by editing + VTWMBINDIR. See also VTWMLIBDIR and VTWMMANDIR. This will allow + installation to other than the system X11 directories where you don't + have root access. + + - Issue 'xmkmf'. If that doesn't work (you'll know it), you'll have + to copy Makefile.QNX to Makefile, and edit the latter to taste. + + - Issue 'make'. This shouldn't take very long at all; VTWM is small. + Should the build break, check further down in this file. If it still + breaks, ask a friend. If it _still_ breaks, you can write me. + + - The sysrc_add_apps.sh script in contrib/support/ may be of help in + customizing the default system resource file. It automagically adds + selected applications found on your system to system.vtwmrc. Issue + 'sh contrib/support/sysrc_add_apps.sh -h' for a brief help message. + + +INSTALLING VTWM 5.4 +=================== + +1) Installation. + If you haven't modified VTWMBINDIR, et al, to point to a non-system + area in which you have write access, you will need to perform the + following install steps as root. + - If you trust whoever set up your build environment: + - issue 'make install'. + If you don't: + - Issue 'make -n install' to see what it'll do, without actually + doing it. + - If you want (or have) to set it up manually: + - Copy vtwm to /usr/X11R6/bin, or to wherever other X + window managers and binaries are. + - Copy system.vtwmrc to wherever it's spec'd in the + Makefile (this path is built into the VTWM binary). + - Copy vtwm.man to wherever other X window manager + man pages are (usually /usr/X11R6/man/mann). + +2) Configuration. + - Set up user resource files: + - Copy system.vtwmrc to your home directory as .vtwmrc, and edit + it to suit your immediate needs (you'll be editing it a lot more, + I'm sure). + - If VTWM supports m4, you can copy the contrib/vtwmrc/ directory + into your home directory as vtwm/ or some such. Then, create a + symlink $(HOME)/.vtwmrc to one of the vtwmrc-*ish files in that + subdirectory, or specify one of those files on VTWM's invocation + (either will give you much more to work with). + - The sysrc_add_apps.sh script in contrib/support/ may also be + useful in customizing user resource files by playing with its + command-line switches. + + - Edit the script that starts your current X window manager to start + VTWM instead (mine is 'vtwm -d :0.0 -f vtwm/vtwmrc-MWMish -s -m -p' + in $(HOME)/.xinitrc). + + - Exit X, and restart it. + + +BUILD HINTS +=========== + + - If, during the build, you get complaints of an undefined "yylineno", + uncomment the "NEED_YYLINENO_V" definition in Imakefile (or the + Makefile) and try the build again. If it is still undefined, also + remove the "extern" keyword from its declaration in gram.y. Likewise, + if "yywrap" turns up as undefined, add a line "yywrap() {return(1)};" + to lex.l. Finally, if "yylex" turns up undefined, it can be fixed by + adding a line "#define YY_DECL int yylex YY_PROTO((void))" to lex.l. + These are all expected to be in the lexer's skeleton file, but there + are some without. + + - If, during the build, you get complaints of undefined data types and + functions "FontSet" and "Xmb" whatall, it's because you've built VTWM + with internationalization (I18N) support, and your system doesn't + support it. Read the comments in Imakefile and/or Makefile.QNX. + + - If, during the build, you get complaints of undefined data types and + functions "Xpm" whatall, it's because you've built VTWM with XPM image + support, and either you don't have the XPM library available, or it's + not a recent enough version (3.4h is the earliest I know of). Read the + comments in Imakefile and/or Makefile.QNX. + + - If, during the build, you get complaints of an undefined data type + "regex_t" or functions "reg" whatall, it's because you've built VTWM + with regular expressions ("RE"s) support, and either you don't have + regex support, or it's not POSIX 1003.2 compliant. Read the comments + in Imakefile and/or Makefile.QNX. + + - If, during the build, you get complaints of an undefined data type + "RPLAY" or functions "rplay" whatall, it's because you've built VTWM + with sound support and you don't have the rplay library available. + Read the comments in Imakefile and/or Makefile.QNX. + + - If, during the build, you get complaints of an unknown data type + "Pixel", add "EXTRA_DEFINES=-DNEED_PIXEL_T" to the make command. + + - If you expected HTML or Postscript man pages on build completion, + or VTWM doesn't fall back on system resource files on startup, read + the comments in Imakefile and/or Makefile.QNX. + + - VNC users: If you regularly use a remote X desktop, you may want to + add "EXTRA_DEFINES=-DORIGINAL_DRAWIT" to the make command. It seems + that VTWM's diagonal resize/move lines are more expensive than TWM's + horizontal and vertical lines. YMMV. + + - Windows users: VTWM is known to build and run under Cygwin with DLL + version 1.3.2. The Makefile may need a line "vtwm: vtwm.exe" added + beneath the "all:: vtwm" line for a successful build. The INSTALL + file and the /usr/X11R6/lib/X11/twm directory may have to be "moved + out of the way" for a successful installation. + + +RUNTIME HINTS +============= + + - Prior to version 5.4.7, key and button bindings were dependent on + various "shift states". Version 5.4.7 can ignore these; check out + the IgnoreModifiers variable. + + - As of version 5.4.7, all window moves and resizes initiated at the + virtual desktop will end there (previous behavior was to leave the + pointer at the window). Bind a function like + Function "move-or-warp" { f.move f.deltastop f.warp } + to a button and the desktop context with something like + Button2 = : desktop : f.function "move-or-warp" + to approximate previous behavior. + + - As of version 5.4.7, the raise that normally accompanies moves and + resizes occurs at operation end, to preserve window stacking order + on cancellation. Set the RaiseOnStart variable for previous behavior. + + - The SunkFocusHighlightWindow variable was depreciated in version + 5.4.7. Set the TitleHighlight argument of the Pixmaps variable to + an appropriate built-in pixmap. + + - If, on startup, things are coming up weird (if at all!), check the + resource file for m4 macros, and if found, see that VTWM is version + 5.4.6 or later, that it was built with m4 support, that "-m" is in + the line that starts VTWM, and that m4 is in $(PATH). + + - The UseRealScreenBorder variable was depreciated in version 5.4.6. + If the RealScreenBorderWidth variable is non-zero, why wouldn't you + want to use it? + + - As of version 5.4.6, random zooms during deiconification won't occur + unless the ZoomZoom variable is set. + + - If you use any of the 3D resources from versions before 5.4.5, you + will find that they generate errors on startup. They no longer exist! + See the man page or the CHANGELOG file for the new resources (look + for the word "Bevel"). + + - If you use a SqueezeTitle list from versions before 5.4.4, you may + want to check the man page to see if the new enterpretation of the + resource's list parameters fouls your setup. + + - See also the man page, and the SOUND and BUGS files in doc/. + diff --git a/doc/SOUND b/doc/SOUND new file mode 100644 index 0000000..eb0cfc3 --- /dev/null +++ b/doc/SOUND @@ -0,0 +1,94 @@ + +NOTES ON SOUND SUPPORT +====================== + +As of version 5.4.6, VTWM can be built to support sound effects, by way of +the rplay library and daemon. The following chart lists the identifiers for +the sounds resource, loosely organized into categories. Those in parentheses +are best described as "event identifiers" - cues that also trigger a sound. + +See the man page and sample resource file for usage and syntax. + + +CREATE DESKTOP START STOP + m ! m f.autopan m f.twmrc + m f.exec m f.panup m f.quit + m f.newdoor m f.pandown m f.restart + e (client map) m f.panleft m f.startwm + m (menu map) m f.panright t (vtwm start) + m f.movescreen t (vtwm stop) + m f.setrealscreen +BUFFER m f.resetdesktop + m ^ m f.enterdoor NAVIGATE + m f.cut m f.snap m f.backiconmgr + m f.cutfile m f.snugdesktop m f.downiconmgr + m f.file m f.snugwindow m f.forwiconmgr + e (autopan event) m f.lefticonmgr + m f.nexticonmgr +ARRANGE m f.previconmgr + m f.autoraise ZOOM RESIZE m f.upiconmgr + m f.circledown m f.bottomzoom m f.righticonmgr + m f.circleup m f.fullzoom m f.warp + m f.lower m f.hbzoom m f.warpclassnext + m f.raise m f.horizoom m f.warpclassprev + m f.raiselower m f.htzoom m f.warpring + m f.deiconify m f.hzoom m f.warpto + m f.iconify m f.leftzoom m f.warptoiconmgr + m f.hidedesktopdisplay m f.rightzoom m f.warptonewest + m f.hideiconmgr m f.topzoom m f.warptoscreen + m f.showdesktopdisplay m f.vlzoom + m f.showiconmgr m f.vrzoom + m f.forcemove m f.zoom MISC + m f.move m f.resize m f.beep + m f.nail m f.colormap + m f.stick m f.deltastop + m f.squeezecenter DELETE DESTROY m f.version + m f.squeezeleft m f.delete m f.identify + m f.squeezeright m f.deletedoor m f.menu + m f.namedoor m f.destroy m f.nailedabove + m f.sorticonmgr e (client unmap) m f.nop + m f.stricticonmgr e (info unmap) m f.saveyourself + m (menu unmap) f.separator + m f.stickyabove + m f.refresh + m f.winrefresh + m f.focus + m f.unfocus + m f.bindbuttons + m f.bindkeys + m f.unbindbuttons + m f.unbindkeys + m f.function + m f.ring + m f.snaprealscreen + m f.staticiconpositions + m f.stricticonmgr + m f.title + m f.virtualgeometries + m f.warpsnug + m f.warpvisible + m f.zoomzoom + f.playsound + f.sounds + m (bell event) + + +LEGEND: + m = handled in menus.c + e = handled in events.c + t = handled in twm.c + = no sound support + +NOTES: + - Where function identifiers overlap event identifiers, the function takes + precedence when both would otherwise play. These identifiers are: + f.beep > (bell event) f.exec > (client map) + f.delete > (client unmap) f.menu > (menu map) + f.deletedoor > (client unmap) f.quit > (vtwm stop) + f.destroy > (client unmap) f.version = f.identify + - f.exec will never know if the program is an X client, nor if it maps a + window if it is, so (client map) might be preferred. + - None should play if the function or event isn't possible, but they will. + - Two variables, PauseOnExit and PauseOnQuit, allow time for exit sounds + to play. + diff --git a/doc/WISHLIST b/doc/WISHLIST new file mode 100644 index 0000000..35fa1f8 --- /dev/null +++ b/doc/WISHLIST @@ -0,0 +1,59 @@ + +WISHES FOR THE FUTURE OF VTWM +============================= + + From vtwm-5.1 spawned two independent versions, vtwm-5.2 and vtwm-5.2b. + The features added to 5.2b are different from the ones added to 5.2, and + I based my version(s) on 5.2 rather than 5.2b since in 5.2 the features + were, in my humble opinion, more useful, while in 5.2b the new stuff was + mostly `chrome' (e.g., XPM support, etc.). I was seriously considering + adding the features from 5.2b into 5.3, but I didn't have enough time. + + I would like to see most of the features from 5.2b merged into the next + version, especially the color XPM support and m4 pre-processing of the + *twmrc file. See below for more info. --- DSE + + [From the CHANGES-5.2 file in the vtwm-5.2b archive] + ---------------------------------------------------------------- begin file + Summary feature list for version 5.2: + + * Added m4 pre-processing of the *twmrc file. courtesy of Dave Edmondson. + DONE - jg + * Added :random color specification, which generates colors on the fly. + * Color XPM support for icons. DONE - jg, djhjr + * Color XPM support for buttons. DONE (the titlebar highlight, the + virtual desktop and it's real screen window, too!) - djhjr + * 3D appearance on menus, titles, icons. DONE (the window's borders, the + virtual desktop, info windows, doors, and icon managers, too!) - djhjr + * Moving in and out of desktop. + * Opaque resizing available. DONE - djhjr + * Both OpaqueResize and OpaqueMove may specify lists of windows as + opposed to being "global". DONE - djhjr + * Can direct focus through desktop at real windows. When enabled, the + desktop windows also indicate the focus highlight by using the border. + * regexps can be used for lists in the vtwmrc. DONE - djhjr + * Size information is displayed during both move and resize. DONE - djhjr + * Size information can be centered in the screen. DONE (any of the + screen corners, too!) - djhjr + * Desktop size may be specified in multiples of real screen. IT'S THERE + (see contrib/vtwmrc-parms) - djhjr + * Can "paste" a new name into a door. DONE - djhjr + * Places property on root window giving virtual coordinates, in case + other programs want to use this info. (e.g. xpostit). + * Now uses a blank/icon startup screen while initialising. + * Many bugfixes, especially to do with desktop stacking order and + iconification/deiconification of the desktop windows. ALMOST ALL + DONE - djhjr + ------------------------------------------------------------------ end file + + * A better way of implementing StickyAbove and "VTWM Profile". + + Here's the list of stuff I would like to see added to VTWM. --- djhjr + + * Support for user-defined icons in menus and the icon manager. MOSTLY + DONE - djhjr + * More coherent/uniform handling of XPM images, particularly where + transparency is concerned. + * I18n support. This will break X11R4 compatability if not done right. + DONE - djhjr + diff --git a/doc/vtwm.man b/doc/vtwm.man new file mode 100644 index 0000000..c6a26b7 --- /dev/null +++ b/doc/vtwm.man @@ -0,0 +1,2668 @@ +.\" twm +.\" .de EX \"Begin example +.\" .ne 5 +.\" .if n .sp 1 +.\" .if t .sp .5 +.\" .nf +.\" .in +.5i +.\" .. +.\" .de EE +.\" .fi +.\" .in -.5i +.\" .if n .sp 1 +.\" .if t .sp .5 +.\" .. +.\" .ta .3i .6i .9i 1.2i 1.5i 1.8i +.TH VTWM 1 "Release 5.4.7" "X11R4-6" +.\"********************************************************************* +.\" Important note: At the time 5.4.4 was released, this manual page +.\" conformed to Sun's guidelines for manual page markup, passed +.\" checknr, had been spell checked and doubled-word checked, and was +.\" automatically translatable to HTML with man2html. Please be careful +.\" in subsequent edits to preserve these important invariants! +.\"********************************************************************* +.\"===================================================================== +.SH NAME +.PP +vtwm - Virtual Tab Window Manager for the X Window System +.PP +.\"===================================================================== +.SH SYNTAX +.PP +\&\fBvtwm\fP [\fB-d\fP \fIdisplay\fP] [\fB-f\fP [\fIinitfile\fP]] +[\fB-m\fP [\fIoptions\fP]] [\fB-p\fP] [\fB-s\fP] [\fB-v\fP] +.PP +.\"===================================================================== +.SH DESCRIPTION +.PP +\&\fBvtwm\fP is a window manager for the X Window System. It provides +titlebars, shaped windows, several forms of icon management, user-defined +macro functions, click-to-type and pointer-driven keyboard focus, and +user-specified key and pointer button bindings. +.PP +This program is usually started by the user's session manager or +startup script. When used from \fBxdm\fP(1) or \fBxinit\fP(1) without +a session manager, \fBvtwm\fP is frequently executed in the foreground +as the last client. When run this way, exiting \fBvtwm\fP causes the +session to be terminated (i.e., logged out). +.PP +By default, application windows are surrounded by a border with a +titlebar at the top. The titlebar contains the window's name, a rectangular +area that indicates when the window is receiving keyboard input, and three +function boxes known as "titlebar buttons". Pressing pointer Button1 (usually +the left-most button unless it has been changed with \fBxmodmap\fP(1)) on any +of these titlebar features will invoke the function associated with them. +.PP +With the default interface, windows are iconified by clicking (pressing and +then immediately releasing) the titlebar button that looks like a dot. +Conversely, windows are deiconified by clicking in the associated icon or +entry in the icon manager (see the descriptions of the variable +\&\fBShowIconManager\fP and the function \fBf.showiconmgr\fP in the +.B BINDINGS +section). +.PP +Windows are resized by pressing the titlebar button that resembles a group +of nested squares, dragging the pointer over the edge that is to be moved, +and releasing the pointer when the window is the desired size. +Similarly, windows are moved by pressing in the title or highlight area, +dragging it to the new location, and then releasing when the window is in +the desired position. Just clicking in the title or highlight area +raises the window without moving it. +.PP +Pressing the titlebar button with the down arrow in it brings up a menu +with many other functions that may be applied to the window. +.PP +When new windows are created, \fBvtwm\fP will honor any size and location +information requested by the user (usually through \fB\-geometry\fP +command line argument or X11 resources for the individual applications). +With the default configuration, Clicking pointer Button1 will position the +window at the current position and give it the default size. Pressing +pointer Button2 (usually the middle pointer button) and dragging the window +will give the window its current position but allow the sides to be resized +as described above. Clicking pointer Button3 (usually the right pointer +button) will give the window its current position but attempt to make it +long enough to touch the bottom of the screen. +.PP +The default behavior during these operations is to represent the window with +an outline of the client window and its titlebar, lines crossing within the +client window. Alternatively, \fBvtwm\fP may be configured to draw the +window completely, but it is not recommended unless yours is a fast system. +.\"===================================================================== +.SH THE VIRTUAL DESKTOP +\&\fBvtwm\fP is based upon the \fBtwm\fP(1) window manager, but adds extra +functionality in the form of a virtual desktop. The virtual desktop is an +area larger than the physical screen. The real screen is considered to be a +window onto portions of the virtual desktop showing whatever windows are +present in that area of the desktop. To help navigate around the desktop, +\&\fBvtwm\fP creates a new window, of the name \fIVTWM Desktop\fP, which shows +the entire desktop using a small scale. In the Virtual Desktop window, all +windows that exist are displayed and various options are provided to recognize +the identity of the different windows (see the descriptions of the variables +\&\fBDesktopDisplayBackground\fP, +\&\fBDesktopDisplayForeground\fP, \fBDesktopDisplayBorder\fP and +\&\fBVirtualDesktopFont\fP). +.PP +To provide a consistent workspace, the option is provided of \fInail\fPing +windows onto the real screen. When a window is nailed, it is considered +stuck to the real screen no matter what part of the desktop is currently +being displayed. +.PP +Normally, a few standard utilities are nailed down: the icon manager, +the desktop view, a load average chart, a clock, and a mail notifier. +The \fBf.nail\fP (or its alias, \fBf.stick\fP) function can be used to +change the nailed status of any window; see the +.B BINDINGS +section for details. +.PP +The root window of the display is unchanged by this program and utilities +such as \fBxsetroot\fP(1) will continue to work unmodified. +.\"===================================================================== +.SH OPTIONS +\&\fBvtwm\fP accepts the following command line options: +.PP +.TP 15 +.B \-d \fIdisplay\fP +This option specifies the X server to use. +.TP 15 +.B \-f \fP[\fIinitfile\fP] +This option specifies the name of the startup file to use. By default, +\&\fBvtwm\fP will look in the user's home directory for files named +\&\fI.vtwmrc.N\fP, \fI.vtwmrc\fP, \fI.twmrc.N\fP, or \fI.twmrc\fP (where +\&'\fIN\fP' is a screen number). It also looks for system-wide default +files; see the +.B CUSTOMIZATION +section below for details. If \fIinitfile\fP is not provided, this specifies +that \fBvtwm\fP should disregard any startup files it finds, and use only the +defaults that are compiled in (intended for testing compiled-in defaults). +.TP 15 +.B \-m \fP[\fIoptions\fP] +This option causes \fBvtwm\fP to preprocess the startup file using the +\&\fBm4\fP(1) macro processor. The \fIoptions\fP will be passed verbatim to +\&\fBm4\fP along with those symbols that \fBvtwm\fP declares. Note that +\&\fIoptions\fP itself should be quoted, to prevent unwanted processing that +may occur by the shell, etc. +.TP 15 +.B \-p +This option indicates that \fBvtwm\fP should attempt to write it's PID to +\&\fI$HOME/vtwm.pid\fP on startup, and delete that file on shutdown. +This file may be useful as a lock file, or for determining the correct +\&\fBvtwm\fP process for a particular user. If the file cannot be written +on startup, a bell will sound, but \fBvtwm\fP will continue. +.TP 15 +.B \-s +This option indicates that only the default screen (as specified by the +\&\fB\-d\fP option or by the \fBDISPLAY\fP environment variable) should be +managed. By default, \fBvtwm\fP will attempt to manage all screens on the +display. +.TP 15 +.B \-v +This option indicates that \fBvtwm\fP should print messages to the stderr +device when an unexpected event occurs. This can be be useful for debugging +applications, but may be distracting in regular use. +.\"===================================================================== +.SH CUSTOMIZATION +.PP +Much of \fBvtwm\fP's appearance and behavior can be controlled by providing +a startup file in one of the following locations (searched in order for +each screen being managed when \fBvtwm\fP begins): +.TP 8 +.I "$HOME/.vtwmrc.\fIscreennumber\fP" +The \fIscreennumber\fP is a small positive number (e.g., 0, 1, etc.) +representing the screen number (e.g., the last number in the DISPLAY environment +variable \fIhost:displaynum.screennum\fP) that would be used to contact that +screen of the display. This is intended for displays with multiple screens of +differing visual types. +.TP 8 +.I "$HOME/.vtwmrc" +This is the usual name for an individual user's startup file. +.TP 8 +.I "$VTWMDIR/twm/system.vtwmrc" +If neither of the preceding files are found, \fBvtwm\fP will look in this +file for a default configuration. +Note that the variable is defined \fIonly in the Makefile\fP, and is often +set and tailored by the site administrator to +provide convenient menus or familiar bindings for novice users. +.TP +.I "$HOME/.twmrc.\fIscreennumber\fP" +.TP +.I "$HOME/.twmrc" +.TP +.I "$VTWMDIR/twm/system.twmrc" +When none of the +.I .vtwmrc +files can be found, +.B vtwm +reverts to acting like +.BR twm (1), +and searches for these three +.I .twmrc +variants. +Note that the variable is defined \fIonly in the Makefile\fP. +.PP +This search algorithm allows both +.BR twm (1) +and +.B vtwm +to coexist peacefully at an installation. Since +.B vtwm +is a superset of +.BR twm (1), +it can even used to replace the latter, and users who have only a +.IR .twmrc -style +file should not notice much difference. +.PP +If no startup files are found, or if \fBvtwm\fP is told to ignore them, +\&\fBvtwm\fP will use built-in defaults as described in the +.B DESCRIPTION +section above, though the \fIsystem.vtwmrc\fP file, if re-configured before +the build, may intervene. The only X11 resource used by \fBvtwm\fP is +\&\fIbitmapFilePath\fP for a colon-separated list of directories to search +when looking for bitmap and pixmap files (for more information, see the +\&\fIAthena Widgets\fP manual and \fBxrdb\fP(1)). +.PP +\&\fBvtwm\fP startup files are logically broken up into three types of +specifications: \fIVariables\fP, \fIBindings\fP, \fIMenus\fP. +.PP +The \&\fIVariables\fP section must come first and is used to describe +the fonts, colors, cursors, border widths, icon and window placement, +highlighting, autoraising, layout of titles, warping, and use of the +icon manager. +.PP +The \fIBindings\fP section usually comes second and is used to specify +the functions that should be to be invoked when keyboard and pointer +buttons are pressed in windows, icons, titles, and frames. +.PP +The \fIMenus\fP section gives any user-defined menus (containing +functions to be invoked or commands to be executed). +.PP +Variable names and keywords are case-insensitive. Strings must be surrounded +by double quote characters (e.g., \fI"blue"\fP) and are case-sensitive. +A sharp sign ('#') outside +of a string causes the remainder of the line in which the character appears to +be treated as a comment. +.\"===================================================================== +.SH M4 PREPROCESSING +.PP +A powerful feature of \fBvtwm\fP as of version 5.4.6 is that it can use +\&\fBm4\fP(1) to pre-process it's startup files. When \fBvtwm\fP is started +with \fB\-m\fP, it will open a file for input as described above, but will +process that file through \fBm4\fP before parsing it. So, you can use +\&\fBm4\fP macros to perform operations at runtime. This makes it very easy +to work when you use many different displays, etc. For example, if you want +to set the lower right section of the screen to be your \fBIconRegion\fP, +you can use \fBm4\fP directives and pre-defined symbols to calculate the +region you want: +.RS 4 +.nf +define(IRegion, translit(eval(WIDTH/3)*eval(HEIGHT/2)+eval(WIDTH-WIDTH/3)-0, *, x)) +IconRegion "IRegion" SOUTH EAST 75 25 +.fi +.RE +will define the lower half, and right-hand third of the screen. The symbols +\&\fIWIDTH\fP and \fIHEIGHT\fP are calculated by \fBvtwm\fP for \fBm4\fP to +use. The following symbols are pre-defined by \fBvtwm\fP: +.TP 15 +.B "SERVERHOST" +This variable is set to the name of the machine that is running the X +server. +.TP 15 +.B "CLIENTHOST" +The machine that is running the X clients (i.e., "vtwm", "xterm", etc.). +.TP 15 +.B "HOSTNAME" +The canonical hostname running the clients (i.e., a fully-qualified +version of \fBCLIENTHOST\fP). +.TP 15 +.B "USER" +The name of the user running the program. Gotten from the environment. +.TP 15 +.B "HOME" +The user's home directory. Gotten from the environment. +.TP 15 +.B "VERSION" +The X major protocol version. As seen by ProtocolVersion(). +.TP 15 +.B "REVISION" +The X minor protocol revision. As seen by ProtocolRevision(). +.TP 15 +.B "VENDOR" +The vendor of your X server (i.e., "MIT X Consortium"). +.TP 15 +.B "RELEASE" +The release number of your X server. For MIT X11R5, this is "5". +.TP 15 +.B "WIDTH" +The width of your display in pixels. +.TP 15 +.B "HEIGHT" +The height of your display in pixels. +.TP 15 +.B "X_RESOLUTION" +The X resolution of your display in pixels per meter. +.TP 15 +.B "Y_RESOLUTION" +The Y resolution of your display in pixels per meter. +.TP 15 +.B "PLANES" +The number of bit planes your display supports in the default root window. +.TP 15 +.B "BITS_PER_RGB" +The number of significant bits in an RGB color. (log base 2 of the number +of distinct colors that can be created. This is often different from the +number of colors that can be displayed at once.) +.TP 15 +.B "TWM_TYPE" +Tells which \fBtwm\fP derivative is running. It will always be set to "vtwm" +in this program. This is useful for protecting parts of your startup file +that \fBtwm\fP proper won't understand (like \fBVirtualDesktop\fP) so that it +is still usable with other \fBtwm\fP-based programs. +.TP 15 +.B "CLASS" +Your visual class. Will return one of "StaticGray", "GrayScale", +"StaticColor", "PseudoColor", "TrueColor", "DirectColor", or, if it cannot +determine what you have, "NonStandard". +.TP 15 +.B "COLOR" +This will be either "Yes" or "No". This is just a wrapper around the above +definition. Returns "Yes" on "*Color", and "No" on "StaticGray" and "GrayScale". +.TP 15 +.B "I18N" +This will be either "Yes" or "No" depending on whether support for +internationalization has been compiled in. +.TP 15 +.B "XPM" +This will be either "Yes" or "No" depending on whether support for pixmap +image files has been compiled in. +.TP 15 +.B "SOUND" +This will be either "Yes" or "No" depending on whether support for sound has +been compiled in. +.TP 15 +.B "REGEX" +This will be either "Yes" or "No" depending on whether support for regular +expressions ("RE"s) has been compiled in. +.PP +Note that any symbols passed to \fBm4\fP on the command line that conflict +with these will not be anticipated or dealt with by \fBvtwm\fP; you will be +at the mercy of your particular \fBm4\fP. +.PP +Note also that if \fBvtwm\fP's preparation for executing \fBm4\fP fails, the +startup file will be processed normally, and will choke on the first \fBm4\fP +macro encountered. +.PP +Finally, be aware that \fBm4\fP preprocessing can cause things often found in +startup files to break. For example, quotes and backquotes in shell commands +will be badly messed up by \fBm4\fP's own internal quoting mechanism. This +particular problem can be worked around by placing \fIchangequote(,)\fP at +the top of your startup file. +.PP +Invoking \fBvtwm\fP with both the \fB-m\fP and \fB-v\fP options will print +the \fBm4\fP command with all symbols expanded. +.\"===================================================================== +.SH VARIABLES +.PP +Many of the aspects of \fBvtwm\fP's user interface are controlled by variables +that may be set in the user's startup file. Some of the options are +enabled or disabled simply by the presence of a particular keyword. Other +options require keywords, numbers, strings, or lists of all of these. +.PP +Lists are surrounded by braces and are usually separated by +whitespace or a newline. For example: +.RS 4 +.nf +\&\fBAutoRaise\fP { "emacs" "VTWM*" "x*clock" "Xmh" "XTerm" } +.fi +.RE +or +.RS 4 +.nf +\&\fBAutoRaise\fP +{ + "emacs" + "VTWM*" + "x*clock" + "Xmh" + "XTerm" +} +.fi +.RE +.PP +When a variable containing a list of strings representing windows is searched +(e.g., to determine whether or not to enable autoraise as shown above), a +string must be a case-sensitive match to the window's name (given by the +WM_NAME window property), or the class name or class class (both given by the +WM_CLASS window property). The preceding example would enable autoraise on +windows named "emacs", all \fBvtwm\fP-specific windows, any clocks installed +whose name starts with an 'x' (\fBasclock\fP will not autoraise), and all +\&\fBxmh\fP and \fBxterm\fP windows (which are of class "XTerm" and "Xmh", +respectively). See the +.B WILDCARDS +section for details on what the asterisks ('*') mean. +.PP +String arguments that are interpreted as filenames (see the \fBPixmaps\fP, +\&\fBCursors\fP, and \fBIconDirectory\fP variables below) will +prepend the user's directory +(specified by the \fIHOME\fP environment variable) if the first character is +a tilde ('~'). If, instead, the first character is a colon (':'), the name is +assumed to refer to one of the internal bitmaps that are used to +create 2D titlebar buttons, the 2D icon manager button, and the 2D menu +pull-right icon. Finally, if the first five characters are ":xpm:", the name +is assumed to refer to one of the built-in pixmaps that can used to create 3D +titlebar buttons, the 3D icon manager button, and the 3D menu pull-right icon. +See the +.B IMAGE AND AUDIO FORMATS +section for further details. +.PP +The following variables may be specified in the \fBvtwm\fP startup file. +Lists of window names are indicated by \fIwin-list\fP, and optional arguments +are shown in square brackets. Any default values are based on the distributed +\fIsystem.vtwmrc\fP files, and if none is mentioned, the default setting is +"off", "disabled", or "none". +.PP +.IP "\fBAppletRegion\fP \fIgeomstr\fP \fIvgrav hgrav hgrid vgrid\fP { \fIwin-list\fP }" +This variable specifies an area on the root window in which the windows +listed in \fIwin-list\fP are placed. The \fIgeomstr\fP is a quoted string +containing a standard geometry specification for the region size and location. +If more than one \fBAppletRegion\fP is specified, windows will be put into +succeeding regions that have the window listed when the first is full. The +\&\fIvgrav\fP argument should be either \fBNorth\fP or \fBSouth\fP and is used +to control whether windows are first filled in from the top or bottom of the +region. Similarly, the \fIhgrav\fP argument should be either \fBEast\fP or +\&\fBWest\fP and is used to control whether windows should be filled in from +the left or right. Windows are laid out in a grid with cells \fIhgrid\fP +pixels wide and \fIvgrid\fP pixels high. Note that the smallest dimension of +the region must be at least the size of the largest window in it, including +frame and titlebar, in the same direction. This variable is intended to +simplify management of all those little tool applications like \fBxcb\fP(1), +\&\fBxbiff\fP(1), \fBxload\fP(1), etc. that are used regularly. +.IP "\fBAutoPan\fP \fIN\fP" 8 +This variable allows the screen to automatically pan by \fIN%\fP of a real +screen when the pointer approaches the edge of the screen. The pan will be in +the direction of the edge approached. The default is \fI100\fP, effectively +"paging" across the virtual desktop. +.IP "\fBAutoPanBorderWidth\fP \fIpixels\fP" 8 +If \fBAutoPan\fP is turned on, when the pointer goes within the specified +number of \fIpixels\fP of the real screen's border, the screen is panned. +The default value is \fI5\fP. +.IP "\fBAutoPanExtraWarp\fP \fIpixels\fP" 8 +If \fBAutoPan\fP is turned on and \fBNaturalAutopanBehavior\fP turned off, +this variable specifies how far, in pixels, you want the pointer to move away +from the inner edge of the autopan border +when autopanning. The default value is \fI2\fP pixels. +.IP "\fBAutoPanWarpWithRespectToRealScreen\fP \fIN\fP" 8 +With this option turned on, the pointer is warped by \fIN%\fP as many pixels +on the real screen as the screen is scrolled, or by +.RS 12 +.nf +(\fBAutoPanBorderWidth\fP + \fBAutoPanExtraWarp\fP) +.fi +.RE +.RS +pixels, whichever is greater. See \fBNaturalAutopanBehavior\fP for a more thorough +discussion of this and some recommended settings. +.RE +.IP "\fBAutoRaise\fP [{ \fIwin-list\fP }]" 8 +This variable specifies a list of windows (all windows if \fIwin-list\fP is +omitted) to be automatically raised whenever the pointer has come to rest in +a window for the amount of time specified by the \fBRaiseDelay\fP variable. +This action can be interactively enabled or disabled on individual windows +using the function \fBf.autoraise\fP. +.IP "\fBAutoRaiseDelay\fP \fImilliseconds\fP" 8 +A synonym for \fBRaiseDelay\fP. +.IP "\fBAutoRelativeResize\fP" 8 +This variable indicates that dragging out a window size (either when +initially sizing the window with pointer Button2 or when resizing it) +should not wait until the pointer has crossed the window edges. +Instead, moving +the pointer automatically causes the nearest edge or edges to move by the +same amount. This allows the resizing windows that extend off +the edge of the screen. +If the pointer is +in the center of the window, or if the resize is begun by pressing a +titlebar button, \fBvtwm\fP will still wait for the pointer to cross a window +edge (to prevent accidents). This option is +particularly useful for people who like the press-drag-release method of +sweeping out window sizes. +.IP "\fBBeNiceToColormap\fP" 8 +This variable specifies that stippled lines be used for the bevel colors +when any of the 3D variables are set, to conserve on colormap allocations. +.IP "\fBBorderBevelWidth\fP \fIpixels\fP" 8 +Tells \fBvtwm\fP to use 3D-looking window borders, and specifies the width in +pixels of the bevel. The color of the 3D border is \fBBorderTileBackground\fP, +and if \fBNoHighlight\fP is not selected, the border of the Focus window is +\&\fBBorderColor\fP. The default is \fI0\fP if \fBvtwm\fP is built with +2D features, or \fI2\fP when \fBvtwm\fP is built with 3D features. +.IP "\fBBorderColor\fP \fIstring\fP [{ \fIwincolorlist\fP }]" 8 +This variable specifies the default color of the border to be placed around +all +non-iconified windows, and may only be given within a \fBColor\fP or +\&\fBMonochrome\fP list. The optional \fIwincolorlist\fP specifies a list +of window and color name pairs for specifying particular border colors for +different types of windows. For example: +.RS 12 +.nf +\&\fBBorderColor\fP "gray50" +{ + "XTerm" "red" + "xmh" "green" +} +.fi +.RE +.IP +The default is \fI"gray70"\fP. +.IP "\fBBorderTileBackground\fP \fIstring\fP [{ \fIwincolorlist\fP }]" 8 +This variable specifies the default background color in the gray pattern +used in unhighlighted borders (only if \fBNoHighlight\fP hasn't been set), +and may only be given within a \fBColor\fP or \fBMonochrome\fP list. The +optional \fIwincolorlist\fP allows per-window colors to be specified. +The default is \fI"gray60"\fP. +.IP "\fBBorderTileForeground\fP \fIstring\fP [{ \fIwincolorlist\fP }]" 8 +This variable specifies the default foreground color in the gray pattern +used in unhighlighted borders (only +if \fBNoHighlight\fP hasn't been set), and may only be given within a +\&\fBColor\fP or \fBMonochrome\fP list. The optional \fIwincolorlist\fP allows +per-window colors to be specified. The default is \fI"gray60"\fP. +.IP "\fBBorderWidth\fP \fIpixels\fP" 8 +This variable specifies the width in pixels of the border surrounding +all client window frames if \fBClientBorderWidth\fP has not been specified. +This value is also used to set the border size of windows created by \fBvtwm\fP +(such as the icon manager). The default is \fI2\fP if \fBvtwm\fP is built +with 2D features, or \fI6\fP when \fBvtwm\fP is built with 3D features. +.IP "\fBButtonBevelWidth\fP \fIpixels\fP" 8 +Tells \fBvtwm\fP to use 3D-looking window buttons. It specifies the width +in pixels of the bevel. The default is \fI0\fP if \fBvtwm\fP is built with +2D features, or \fI1\fP when \fBvtwm\fP is built with 3D features. +.IP "\fBButtonIndent\fP \fIpixels\fP" 8 +This variable specifies the size of titlebar buttons, expressed as a difference +from the titlebar font height, and normally means that titlebar buttons will +shrink (built-in images) or be cropped (external images) accordingly. +A negative value is accepted, however, indicating that titlebar buttons should +be larger than the titlebar font. Setting this to a negated \fBFramePadding\fP +value, with \fBTitleButtonBorderWidth\fP set to 0, makes titlebar buttons as +tall and wide as possible. The default is \fI0\fP if \fBvtwm\fP is built with +with 2D features, or \fI-2\fP when \fBvtwm\fP is built with 3D features. +.IP "\fBButtonColorIsFrame\fP" +This variable specifies that the titlebar buttons will be the same color +as the window frame. It is set by default if \fBvtwm\fP is built with 3D +features. +.IP "\fBClearBevelContrast\fP \fIcontrast\fP" 8 +Indicates to \fBvtwm\fP how to calculate the clear bevel color for 3D items. +The value is a compressed to the range 0 and 100. The formula used is: +.RS 12 +.nf +clear.{RGB} = (65535 - color.{RGB}) * (contrast / 100) +.fi +.RE +.IP +The default is \fI40\fP if \fBvtwm\fP is built with 3D features. +.IP "\fBClientBorderWidth\fP" 8 +This variable indicates that width of a window's frame should be set to +the border width as specified by the client, rather than to the value of +\&\fBBorderWidth\fP. If \fBBorderBevelWidth\fP is non-zero, however, this +variable is ignored. +.IP "\fBColor\fP { \fIcolors-list\fP }" 8 +This variable specifies a list of color assignments to be made if the default +display is capable of displaying more than simple black and white. The +\&\fIcolors-list\fP is made up of the following color variables and their values: +\&\fBDefaultBackground\fP, +\&\fBDefaultForeground\fP, +\&\fBMenuBackground\fP, +\&\fBMenuForeground\fP, +\&\fBMenuTitleBackground\fP, +\&\fBMenuTitleForeground\fP, and +\&\fBMenuShadowColor\fP. +The following +color variables may also be given a list of window and color name pairs to +allow per-window colors to be specified (see \fBBorderColor\fP for details): +\&\fBBorderColor\fP, +\&\fBDesktopDisplayForeground\fP, +\&\fBDesktopDisplayBackground\fP, +\&\fBRealScreenForeground\fP, +\&\fBRealScreenBackground\fP, +\&\fBVirtualForeground\fP, +\&\fBVirtualBackground\fP, +\&\fBDekstopDisplayBorder\fP, +\&\fBIconManagerHighlight\fP, +\&\fBBorderTitleBackground\fP, +\&\fBBorderTitleForeground\fP, +\&\fBTitleBackground\fP, +\&\fBTitleForeground\fP, +\&\fBIconBackground\fP, +\&\fBIconForeground\fP, +\&\fBIconBorderColor\fP, +\&\fBIconManagerBackground\fP, and +\&\fBIconManagerForeground\fP. +For example: +.RS 12 +.nf +\&\fBColor\fP +{ + \fBMenuBackground\fP "gray50" + \fBMenuForeground\fP "blue" + \fBBorderColor\fP "red" + { + "XTerm" "yellow" + } + \fBTitleForeground\fP "yellow" + \fBTitleBackground\fP "blue" +} +.fi +.RE +.IP +All of these color variables may also be specified for the \fBMonochrome\fP +variable, allowing the same initialization file to be used on both color and +monochrome displays. +.IP "\fBConstrainedMoveTime\fP \fImilliseconds\fP" 8 +This variable specifies the length of time between button clicks needed to +begin a constrained move operation. Double clicking within this amount +of time when invoking \fBf.move\fP will cause the window only to be moved +in a horizontal or vertical direction. Setting this value to 0 will disable +constrained moves. The default is \fI400\fP milliseconds. +.IP "\fBCursors\fP { \fIcursor-list\fP }" 8 +This variable specifies the glyphs that \fBvtwm\fP should use for various +pointer cursors. Each cursor +may be defined either from the \fBcursor\fP font or from two bitmap files. +Shapes from the \fBcursor\fP font may be specified directly as: +.RS 12 +.nf +\&\fIcursorname\fP "\fIstring\fP" +.fi +.RE +.RS +where \fIcursorname\fP is one of the cursor names listed below, and +\&\fIstring\fP is the name of a glyph as found in the file +/usr/include/X11/cursorfont.h (without the "XC_" prefix). +If the cursor is to be defined +from bitmap files, the following syntax is used instead: +.RE +.RS 12 +.nf +\&\fIcursorname\fP "\fIimage\fP" "\fImask\fP" +.fi +.RE +.RS +where \fIimage\fP and \fImask\fP specify the names of files containing +the glyph image and mask in \fIbitmap\fP(1) form. +The bitmap files are located in the same manner as icon bitmap files. +The following example shows the default cursor definitions: +.RE +.RS 12 +.nf +\&\fBCursors\fP +{ + Frame "top_left_arrow" + Title "top_left_arrow" + Icon "top_left_arrow" + IconMgr "top_left_arrow" + Move "fleur" + Resize "fleur" + Menu "sb_left_arrow" + Button "hand2" + Wait "watch" + Select "dot" + Destroy "pirate" + Door "exchange" + Virtual "rtl_logo" + Desktop "dotbox" +} +.fi +.RE +.IP "\fBDarkBevelContrast\fP \fIcontrast\fP" 8 +Indicates to \fBvtwm\fP has to calculate the dark bevel color for 3D items. +The value is a comprised between 0 and 100. The formula used is: +.RS 12 +.nf +dark.{RGB} = color.{RGB} * ((100 - contrast) / 100) +.fi +.RE +.IP +The default is \fI40\fP if \fBvtwm\fP is built with 3D features. +.IP "\fBDecorateTransients\fP" 8 +This variable indicates that transient windows (those containing a +WM_TRANSIENT_FOR property) should have titlebars. By default, transients +are not reparented. +.IP "\fBDefaultBackground\fP \fIstring\fP" 8 +This variable specifies the background color to be used for sizing and +information windows. The default is \fI"maroon"\fP for color displays or +\fI"gray50"\fP for monochrome displays. +.IP "\fBDefaultForeground\fP \fIstring\fP" 8 +This variable specifies the foreground color to be used for sizing and +information windows. The default is \fI"gray85"\fP. +.IP "\fBDeiconifyToScreen\fP" 8 +When deiconifying a window, by default, the window will be placed +at its previous geometry in the virtual desktop. With this variable +set, +.B vtwm +ensures that the window will be placed somewhere on the real +screen. +.IP "\fBDesktopDisplayBackground\fP \fIcolor\fP [{ \fIwin-list\fP }]" 8 +This variable sets the backgrounds of the little windows inside the +Virtual Desktop window, +AND it sets the backgrounds of menu entries in the \fBVTWM Windows\fP +menu -- unless you specify \fBOldFashionedVtwmWindowsMenu\fP. +The default \fIcolor\fP is used for the default background of +windows not named in the list. The optional +\&\fIwin-list\fP is a list of window names and colors, for example: +.RS 12 +.nf +\&\fBDesktopDisplayBackground\fP "purple" +{ + "zwgc" "green" +} +.fi +.RE +.IP +The default is \fI"gray60"\fP. +.IP "\fBDesktopDisplayBorder\fP \fIcolor\fP [{ \fIwin-list\fP }]" 8 +This variable sets the border color in the +virtual desktop representation window to \fIcolor\fP. +The \fIwin-list\fP is in the same format as \fBTitleForeground\fP and other +similar variables. +.RS 12 +.nf +\&\fBDesktopDisplayBorder\fP "black" +{ + "zwgc" "green" +} +.fi +.RE +.IP +The default is \fI"black"\fP. +.IP "\fBDesktopDisplayForeground\fP \fIcolor\fP [{ \fIwin-list\fP }]" 8 +If both this and the \fBVirtualDesktopFont\fP variable are set, +then the names of the windows will be +written in the window representations shown in the desktop. +This entry also sets foreground colors for entries in the +\&\fBVTWM Windows\fP menu. +The format of this variable is +the same as that used for \fBDesktopDisplayBackground\fP. +The default is \fI"gray85"\fP. +.IP "\fBDontDeiconifyTransients\fP" 8 +This variable sees that iconified transient windows of an iconified parent +window aren't deiconified when that parent is, thus preserving their state. +Default behavior is to deiconify all transient subwindows of the ancestor +window when it is deiconified. +.IP "\fBDontIconifyByUnmapping\fP { \fIwin-list\fP }" 8 +This variable specifies a list of windows that should not be iconified by +simply unmapping the window (as would be the case if \fBIconifyByUnmapping\fP +had been set). This is frequently used to force some windows to be treated +as icons while other windows are handled by the icon manager. +.IP "\fBDontInterpolateTitles\fP" 8 +This variable specifies a modification to the \fBInterpolateMenuColors\fP +behavior. It will cause \fBvtwm\fP to not apply color interpolation to any +titles in the middle of the menu. So, \fBf.title\fP strings that appear in +the middle of the menu (ie, without a specific color defined for them) will +inherit the default MenuTitle foreground and background colors. +.IP "\fBDontMoveOff\fP" 8 +This variable indicates that windows should not be allowed to be moved off the +screen. It can be overridden by the \fBf.forcemove\fP function. +.IP "\fBDontShowInDisplay\fP { \fIlist\fP }" 8 +This variable specifies a list of clients that should not appear in +the desktop display. The default is: +.RS 12 +.nf +\&\fBDontShowInDisplay\fP +{ + "VTWM *" + "xclock" + "xload" +} +.fi +.RE +.IP "\fBDontShowInTwmWindows\fP { \fIlist\fP }" 8 +.IP "\fBDontShowInVtwmWindows\fP { \fIlist\fP }" 8 +These variables specify a list of clients that should not appear in +the \fBVTWM Windows\fP menu. +.IP "\fBDontSqueezeTitle\fP [{ \fIwin-list\fP }] " 8 +This variable indicates that titlebars should not be squeezed to their +minimum size as described under \fBSqueezeTitle\fP below. +If the optional window list is supplied, only those windows will be +prevented from being squeezed. +.IP "\fBDoorBackground\fP \fIcolor\fP [{ \fIdoor-list\fP }]" 8 +Specifies background colors of doors. The default is \fI"maroon"\fP for +color displays or \fI"gray50"\fP for monochrome displays. +.IP "\fBDoorBevelWidth\fP \fIpixels\fP" 8 +Tells \fBvtwm\fP to use 3D-looking doors, and specifies the width in pixels +of the bevel. The default is \fI0\fP if \fBvtwm\fP is built with 2D features, +or \fI1\fP when \fBvtwm\fP is built with 3D features. +.IP "\fBDoorFont\fP \fIstring\fP" +This variable specifies the font to be used for text in doors. This must +be set in order to see the doors. +The default is \fI"-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*"\fP. +.IP "\fBDoorForeground\fP \fIcolor\fP [{ \fIdoor-list\fP }]" 8 +Specifies foreground colors of doors. The default is \fI"gray85"\fP. +.IP "\fBDoors\fP { \fIdoor-list\fP }" 8 +This variable is used to create doors, which are teleports. Each item +in the door-list has the following format: +.RS 12 +.nf +"\fIwinname\fP" "\fIlocation\fP" "\fIjumpTo\fP" +.fi +.RE +.IP +Windows with the name \fIwinname\fP appear with geometry and position +as defined in \fIlocation\fP, and warp the user to \fIjumpTo\fP when +\&\fBf.enterdoor\fP is executed inside them. Doors have a class of "VTWM Door". +.IP "\fBEnhancedExecResources\fP" 8 +By default, \fBf.exec\fP variables behaved as they always did in \fBvtwm\fP. You +would have to append " &" to all of your variables in order to execute them +without blocking the window manager. With this option turned on, you don't +have to; \fBvtwm\fP will automatically append " &" to the \fBf.exec\fP variable +.I unless +the last non-space character is either '&' or (in case you still want a +command to block the window manager) ';'. For example, in a variable such as: +.RS 12 +.nf +f.exec "foo; bar; baz" +.fi +.RE +.RS +the window manager will be blocked so that "foo" and "bar" can be executed; +"baz" is the only command which will NOT block the window manager. If you +want all these commands to be backgrounded, try the following: +.RE +.RS 12 +.nf +f.exec "{ foo; bar; baz }" # note that "{" and "}" + # are shell keywords; they + # MUST be separated by + # spaces. +.fi +.RE +.IP +If you still want a command to block the window manager, you would use: +.RS 12 +.nf +f.exec "xset fp rehash;" # vtwm will not append " &" + # because ';' is the last + # non-space character. +.fi +.RE +.IP +This behavior was inspired by that of \fBvuewm\fP(1), Hewlett-Packard's +workspace implementation of \fBmwm\fP(1). +.IP "\fBFixManagedVirtualGeometries\fP" 8 +.IP "\fBFixTransientVirtualGeometries\fP" 8 +These are bug workarounds that *should* fix the way most windows' +virtual geometries are handled, i.e., they should be on the real screen if +the parent windows are on the real screen, no matter where the virtual +desktop is (\fBxv\fP(1) is one example of how these \fIdon't\fP work). +They are both set by default. +.IP "\fBForceIcons\fP" 8 +This variable indicates that icon image files specified in the \fBIcons\fP +variable should override any client-supplied images. +.IP "\fBFramePadding\fP \fIpixels\fP" 8 +This variable specifies the distance between the titlebar font or the +titlebar button height, whichever is greater, and the window frame, enlarging +the titlebar as required. See also \fBButtonIndent\fP, for how it influences +the titlebar. The default is \fI2\fP pixels. +.IP "\fBIconBackground\fP \fIstring\fP [{ \fIwin-list\fP }]" 8 +This variable specifies the background color of icons, and may +only be specified inside of a \fBColor\fP or \fBMonochrome\fP list. +The optional \fIwin-list\fP is a list of window names and colors so that +per-window colors may be specified. See the \fBBorderColor\fP +variable for a complete description of the \fIwin-list\fP. +The default is \fI"maroon"\fP for color displays or \fI"gray50"\fP for +monochrome displays. +.IP "\fBIconBevelWidth\fP \fIpixels\fP" 8 +Tells \fBvtwm\fP to use 3D-looking icons, and specifies the width in pixels +of the bevel. The default is \fI0\fP if \fBvtwm\fP is built with 2D features, +or \fI2\fP when \fBvtwm\fP is built with 3D features. +.IP "\fBIconBorderColor\fP \fIstring\fP [{ \fIwin-list\fP }]" 8 +This variable specifies the color of the border used for icon windows, and +may only be specified inside of a \fBColor\fP or \fBMonochrome\fP list. +The optional \fIwin-list\fP is a list of window names and colors so that +per-window colors may be specified. See the \fBBorderColor\fP +variable for a complete description of the \fIwin-list\fP. +The default is \fI"gray85"\fP. +.IP "\fBIconBorderWidth\fP \fIpixels\fP" 8 +This variable specifies the width in pixels of the border surrounding icon +windows. The default is \fI2\fP if \fBvtwm\fP is built with 2D features, or +\fI0\fP when \fBvtwm\fP is built with 3D features. +.IP "\fBIconDirectory\fP \fIstring\fP" 8 +This variable specifies the directory that should be searched if +an image file cannot be found in any of the directories +in the \fBbitmapFilePath\fP variable. +.IP "\fBIconFont\fP \fIstring\fP" 8 +This variable specifies the font to be used to display icon names within +icons. +The default is \fI"-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*"\fP. +.IP "\fBIconForeground\fP \fIstring\fP [{ \fIwin-list\fP }]" 8 +This variable specifies the foreground color to be used when displaying icons, +and may only be specified inside of a +\&\fBColor\fP or \fBMonochrome\fP list. +The optional \fIwin-list\fP is a list of window names and colors so that +per-window colors may be specified. See the \fBBorderColor\fP +variable for a complete description of the \fIwin-list\fP. +The default is \fI"gray85"\fP. +.IP "\fBIconifyByUnmapping\fP [{ \fIwin-list\fP }]" 8 +This variable indicates that windows should be iconified by being unmapped +without trying to map any icons. If the optional \fIwin-list\fP is provided, +only those windows will be iconified by simply unmapping. Windows that have +both this and the \fBIconManagerDontShow\fP options set may not be accessible +unless the user has provided bindings to the warp functions (\fBf.warp\fP and +the like) while \fBWarpUnmapped\fP is set, or by the \fBVTWM Windows\fP menu. +It is set by default. +.IP "\fBIconManagerBackground\fP \fIstring\fP [{ \fIwin-list\fP }]" 8 +This variable specifies the background color to use for icon manager entries, +and may only be specified inside of a +\&\fBColor\fP or \fBMonochrome\fP list. +The optional \fIwin-list\fP is a list of window names and colors so that +per-window colors may be specified. See the \fBBorderColor\fP +variable for a complete description of the \fIwin-list\fP. +The default is \fI"maroon"\fP for color displays or \fI"gray50"\fP for +monochrome displays. +.IP "\fBIconManagerBevelWidth\fP \fIpixels\fP" 8 +Tells \fBvtwm\fP to use 3D-looking icon manager entries, and specifies the +width in pixels of their bevels. The default is \fI0\fP if \fBvtwm\fP is +built with 2D features, or \fI1\fP when \fBvtwm\fP is built with 3D features. +.IP "\fBIconManagerDontShow\fP [{ \fIwin-list\fP }]" 8 +This variable indicates that the icon manager should not display any +windows. If the optional \fIwin-list\fP is given, only those windows will +not be displayed. This variable is used to prevent windows that are rarely +iconified (such as \fIxclock\fP or \fIxload\fP) from taking up space in +the icon manager. The default is: +.RS 12 +.nf +\&\fBIconManagerDontShow\fP +{ + "VTWM *" + "xclock" + "xload" +} +.fi +.RE +.IP "\fBIconManagerFont\fP \fIstring\fP" 8 +This variable specifies the font to be used when displaying icon manager +entries. +The default is \fI"-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*"\fP. +.IP "\fBIconManagerForeground\fP \fIstring\fP [{ \fIwin-list\fP }]" 8 +This variable specifies the foreground color to be used when displaying +icon manager entries, and may only be specified inside of a +\&\fBColor\fP or \fBMonochrome\fP list. +The optional \fIwin-list\fP is a list of window names and colors so that +per-window colors may be specified. See the \fBBorderColor\fP +variable for a complete description of the \fIwin-list\fP. +The default is \fI"gray85"\fP. +.IP "\fBIconManagerGeometry\fP \fIstring\fP [ \fIcolumns\fP ]" 8 +This variable indicates that a default icon manager is to be created, with +the geometry specified with \fIstring\fP. The \fIstring\fP argument should +be a standard X geometry specification, specifying the initial size and/or +location. The icon manager window is then broken into \fIcolumns\fP pieces +and scaled according to the number of entries in the icon manager. Extra +entries are wrapped to form additional rows. +The default \fIstring\fP is \fI"+0+0"\fP, and the default \fIcolumns\fP +is \fI1\fP. +.IP "\fBIconManagerHighlight\fP \fIstring\fP [{ \fIwin-list\fP }]" 8 +This variable specifies the border color to be used when highlighting +the icon manager entry that currently has the focus, +and can only be specified inside of a +\&\fBColor\fP or \fBMonochrome\fP list. +The optional \fIwin-list\fP is a list of window names and colors so that +per-window colors may be specified. See the \fBBorderColor\fP +variable for a complete description of the \fIwin-list\fP. +The default is \fI"black"\fP. +.IP "\fBIconManagers\fP { \fIiconmgr-list\fP }" 8 +This variable specifies a list of icon managers to create, in addition to +the default icon manager if \fBIconManagerGeometry\fP is used. Each item +in the \fIiconmgr-list\fP has the following format: +.RS 12 +.nf +"\fIwinname\fP" ["\fIiconname\fP"] "\fIgeometry\fP" \fIcolumns\fP +.fi +.RE +.RS +where \fIwinname\fP is the name of the windows that should be put into this +icon manager, \fIiconname\fP is the name of that icon manager window's icon, +\&\fIgeometry\fP is a standard geometry specification, and \fIcolumns\fP is +the number of columns in this icon manager as described in +\&\fBIconManagerGeometry\fP. For example: +.RE +.RS 12 +.nf +\&\fBIconManagers\fP +{ + "XTerm" "300x5+800+5" 5 + "myhost" "400x5+100+5" 2 +} +.fi +.RE +.IP +Clients whose name or class is "XTerm" will have an entry created +in the "XTerm" icon manager. Clients whose name was "myhost" would +be put into the "myhost" icon manager. +.IP "\fBIconManagerShow\fP { \fIwin-list\fP }" 8 +This variable specifies a list of windows that should appear in the icon +manager. When used in conjunction with the \fBIconManagerDontShow\fP +variable, only the windows in this list will be shown in the icon manager. +By default, all windows are shown except those in \fBIconManagerDontShow\fP. +.IP "\fBIconRegion\fP \fIgeomstr\fP \fIvgrav hgrav hgrid vgrid\fP" +This variable specifies an area on the root window in which icons are placed +if no specific icon location is provided by the client. The \fIgeomstr\fP +is a quoted string containing a standard geometry specification for the +region size and location. If more than one \fBIconRegion\fP line is given, +icons will be put into the succeeding regions when the first is full. The +\&\fIvgrav\fP argument should be either \fBNorth\fP or \fBSouth\fP and is used +to control whether icons are first filled in from the top or bottom of the +region. Similarly, the \fIhgrav\fP argument should be either \fBEast\fP or +\&\fBWest\fP and is used to control whether icons should be filled in from the +left or right. Icons are laid out in a grid with cells \fIhgrid\fP pixels +wide and \fIvgrid\fP pixels high. Note that the smallest dimension of the +region must be at least the size of the largest icon in it in the same +direction. Note also that many applications change their icon name as they +run, and no provision is made to reformat the icon regions if any icon +changes size accordingly. +.IP "\fBIcons\fP { \fIwin-list\fP }" 8 +This variable specifies a list of window names and the image filenames that +should be used as their icons. For example: +.RS 12 +.nf +\&\fBIcons\fP +{ + "XTerm" "xterm.icon" + "xfd" "xfd_icon" +} +.fi +.RE +.IP +Windows that match "XTerm" and would not be iconified by unmapping, and +would try to use +the icon image in the file "xterm.icon". If \fBForceIcons\fP is +specified, this image will be used even if the client has requested its +own icon image. +.IP "\fBIgnoreModifiers\fP \fImodlist\fP" 8 +This variable specifies the "shift states" to ignore when determining if +an event is bound by \fBvtwm\fP. In this example: +.RS 12 +.nf +\&\fBIgnoreModifiers\fP l | m2 +.fi +.RE +.RS +the CapsLock and NumLock states will be ignored. Note that the use of +this variable can generate quite a bit of X protocol network traffic; +\&\fImodlist\fP should be kept as small as possible. See also the +.B BINDINGS +section. +.RE +.IP "\fBInfoBevelWidth\fP \fIpixels\fP" 8 +Tells \fBvtwm\fP to use 3D-looking identify, move and resize windows, and +specifies the width in pixels of the bevel. The default is \fI0\fP if +\&\fBvtwm\fP is built with 2D features, or \fI2\fP when \fBvtwm\fP is built +with 3D features. +.IP "\fBInfoFont\fP \fIstring\fP" 8 +This variable specifies the font to be used for in the identify window. +The default is \fI"-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*"\fP. +.IP "\fBInterpolateMenuColors\fP" 8 +This variable indicates that menu entry colors should be interpolated between +entry specified colors. In this example: +.RS 12 +.nf +\&\fBMenu\fP "mymenu" +{ + "Title" ("black":"red") f.title + "entry1" f.nop + "entry2" f.nop + "entry3" ("white":"green") f.nop + "entry4" f.nop + "entry5" ("red":"white") f.nop +} +.fi +.RE +.RS +the foreground colors for "entry1" and "entry2" will be interpolated +between black and white, and the background colors between red and green. +Similarly, the foreground for "entry4" will be half-way between white and +red, and the background will be half-way between green and white. +.RE +.IP "\fBLessRandomZoomZoom\fP" 8 +With this option turned on, this makes random zooms a bit less "random" and +a bit more visible. This might make a better visual bell, depending on your +personal taste. +.IP "\fBMakeTitle\fP { \fIwin-list\fP }" 8 +This variable specifies a list of windows on which a titlebar should be placed +and is used to request titles on specific windows when \fBNoTitle\fP has been +set. +.IP "\fBMaxWindowSize\fP \fIstring\fP" 8 +This variable specifies a geometry in which the width and height +give the maximum size for a given window. This is typically used to +restrict windows to the size of the screen. The default is \fI"30000x30000"\fP. +.IP "\fBMenuBackground\fP \fIstring\fP" 8 +This variable specifies the background color used for menus, +and can only be specified inside of a \fBColor\fP or \fBMonochrome\fP list. +The default is \fI"maroon"\fP for color displays or \fI"gray50"\fP for +monochrome displays. +.IP "\fBMenuBevelWidth\fP \fIpixels\fP" 8 +Tells \fBvtwm\fP to use 3D-looking menus, and specifies the width in +pixels of the bevel. The default is \fI0\fP if \fBvtwm\fP is built with 2D +features, or \fI2\fP when \fBvtwm\fP is built with 3D features. +.IP "\fBMenuFont\fP \fIstring\fP" 8 +This variable specifies the font to use when displaying menus. +The default is \fI"-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*"\fP. +.IP "\fBMenuForeground\fP \fIstring\fP" 8 +This variable specifies the foreground color used for menus, and can only be +specified inside of a \fBColor\fP or \fBMonochrome\fP list. The default is +\&\fI"gray85"\fP. +.IP "\fBMenuScrollBorderWidth\fP \fIpixels\fP" 8 +When the contents of a menu would make it taller than the display, moving +the pointer within \fIpixels\fP of the top or bottom of the menu causes it +to scroll the entries. The default value is \fI2\fP. +.IP "\fBMenuScrollJump\fP \fIentries\fP" 8 +This variable specifies the number of entries to scroll when the pointer +is moved within the area defined by \fBMenuScrollBorderWidth\fP. The +default is \fI3\fP entries. +.IP "\fBMenuShadowColor\fP \fIstring\fP" 8 +This variable specifies the color of the shadow behind pull-down menus +and can only be specified inside of a +\&\fBColor\fP or \fBMonochrome\fP list. The default is \fI"black"\fP. +.IP "\fBMenuTitleBackground\fP \fIstring\fP" 8 +This variable specifies the background color for \fBf.title\fP entries in +menus, and can only be specified inside of a \fBColor\fP or \fBMonochrome\fP +list. The default is \fI"gray70"\fP. +.IP "\fBMenuTitleFont\fP \fIstring\fP" 8 +This variable specifies the font to be used in menu titles. +The default is \fI"-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*"\fP. +.IP "\fBMenuTitleForeground\fP \fIstring\fP" 8 +This variable specifies the foreground color for \fBf.title\fP entries in +menus and can only be specified inside of a \fBColor\fP or \fBMonochrome\fP +list. The default is \fI"maroon"\fP for color displays or \fI"gray50"\fP for +monochrome displays. +.IP "\fBMonochrome\fP { \fIcolors\fP }" 8 +This variable specifies a list of color assignments that should be made if +the screen has a depth of 1. See the description of \fBColors\fP. +.IP "\fBMoveDelta\fP \fIpixels\fP" 8 +This variable specifies the number of pixels the pointer must move before +the \fBf.move\fP and \fBf.resize\fP functions and initial menu highlighting +starts working. See also the \fBf.deltastop\fP function. +The default is \fI3\fP pixels. +.IP "\fBNailedAbove\fP" 8 +This variable causes nailed windows to be physically above non-nailed +windows. The \fBf.nailedabove\fP function can be used to toggle this setting. +.IP "\fBNailedDown\fP { \fIlist\fP }" 8 +This variable gives a \fIlist\fP of clients that are nailed initially. +The default is: +.RS 12 +.nf +\&\fBNailedDown\fP +{ + "VTWM *" + "xclock" + "xload" +} +.fi +.RE +.IP "\fBNaturalAutopanBehavior\fP" 8 +By default, when autopanning, the pointer is warped by only +.RS 12 +.nf +(\fBAutoPanBorderWidth\fP + \fBAutoPanExtraWarp\fP) +.fi +.RE +.RS +pixels on the real screen. With this option turned on, the pointer is warped +on the real screen by as many pixels as the screen is scrolled, or the above +value, whichever is greater. Thus, the pointer does not normally move very +much (only by \fBAutoPanExtraWarp\fP) in relation to the virtual desktop. +.RE +.IP +This works really well on faster X terminals and workstations, although for +slower ones, you may want to use the following: +.RS 12 +.nf +\&\fBAutoPanWarpWithRespectToRealScreen\fP 50 +.fi +.RE +.RS +to achieve a similar effect. +Setting \fBNaturalAutopanBehavior\fP has the exact same effect as using the +variable +.RE +.RS 12 +.nf +\&\fBAutoPanWarpWithRespectToRealScreen\fP 100 +.fi +.RE +.IP "\fBNoBackingStore\fP" 8 +This variable indicates that \fBvtwm\fP's windows should not request backing +store to minimize repainting. This is typically +used with servers that can repaint faster than they can handle backing store. +.IP "\fBNoBorder\fP [{ \fIwin-list\fP }] " 8 +This variable indicates that windows should not have borders. If the +optional \fIwin-list\fP is given, only those windows will not have borders. +.IP "\fBNoBorderDecorations\fP" 8 +This variable indicates that the 3D borders of titled windows should not have +the little divots adorning the corners. +.IP "\fBNoCaseSensitive\fP" 8 +This variable indicates that case should be ignored when sorting icon names +in an icon manager. This option is typically used with applications that +capitalize the first letter of their icon name. +.IP "\fBNoDefaultMouseOrKeyboardBindings\fP" 8 +This variable indicates that \fBvtwm\fP should not supply the default pointer +and keyboard bindings. This option should only be used if the startup file +contains a completely new set of pointer and keyboard bindings and definitions. +See also \fBNoDefaults\fP. +.IP "\fBNoDefaults\fP" 8 +This variable indicates that \fBvtwm\fP should not supply the default +titlebar buttons and bindings. This option should only be used if the startup +file contains a completely new set of bindings and definitions. This +function has the effect of setting both \fBNoDefaultMouseOrKeyboardBindings\fP +and \fBNoDefaultTitleButtons\fP. +.IP "\fBNoDefaultTitleButtons\fP" 8 +This variable indicates that \fBvtwm\fP should not supply the default +titlebar buttons. This option should only be used if the startup file +contains a completely new set of titlebar button definitions. See also +\&\fBNoDefaults\fP. +.IP "\fBNoGrabServer\fP" 8 +This variable indicates that \fBvtwm\fP should minimize server grabs when +popping up menus and moving or resizing windows. +.IP "\fBNoHighlight\fP [{ \fIwin-list\fP }]" 8 +This variable indicates that borders should not be highlighted to track the +location of the pointer. If the optional \fIwin-list\fP is given, highlighting +will only be disabled for those windows. When the border is highlighted, it +will be drawn in the current \fBBorderColor\fP. When the border is not +highlighted, it will be stippled with an gray pattern using the +current \fBBorderTileForeground\fP and \fBBorderTileBackground\fP colors. +It is set by default if \fBvtwm\fP is built with 3D features. +.IP "\fBNoIconManagerFocus\fP" 8 +This variable indicates that \fBvtwm\fP should not set focus to windows +corresponding to their entries in an icon manager. Normally, \fBvtwm\fP +sets the focus so that events from an icon manager are delivered to the +application. Typically, this is set to facilitate icon manager bindings +that would otherwise be delivered to the application. +.IP "\fBNoIconManagerHighlight\fP" 8 +This variable indicates that icon manager entries will not be highlighted +to track the location of the pointer. This is independant of the +\&\fBNoHighlight\fP variable. +.IP "\fBNoIconManagers\fP" 8 +This variable indicates that no icon manager should be created. +.IP "\fBNoIconifyIconManagers\fP" 8 +This variable indicates that no icon manager should be iconified. +.IP "\fBNoMenuShadows\fP" 8 +This variable indicates that menus should not have drop shadows drawn behind +them. This is typically used with slower servers since it speeds up menu +drawing at the expense of making the menu slightly harder to read. +.IP "\fBNoOpaqueMove\fP [{ \fIwin-list\fP }]" 8 +.IP "\fBNoOpaqueResize\fP [{ \fIwin-list\fP }]" 8 +These variables indicate that the \fBf.move\fP and \fBf.resize\fP functions +should change just a window's outline. If the optional \fIwin-list\fP is +given, only those windows will be affected. These are usually used to narrow +the scope of "global" \fBOpaqueMove\fP and \fBOpaqueResize\fP variables. +.IP "\fBNoPrettyTitles\fP" 8 +If you don't mind long titles butting up against the right edge of short +titlebars and icon managers. Disables the default behavior of using ellipses +to indicate a truncated title. +.IP "\fBNoRaiseOnDeiconify\fP" 8 +.IP "\fBNoRaiseOnMove\fP" 8 +.IP "\fBNoRaiseOnResize\fP" 8 +.IP "\fBNoRaiseOnWarp\fP" 8 +These variables indicate that windows should not be raised after a deiconify, +move, resize, or warp operation, and are typically used to preserve the window +stacking order. Note that the pointer may end up in an occluding window when +these variables are used. +.IP "\fBNoSaveUnders\fP" 8 +This variable indicates that menus should not request save-unders to minimize +window repainting following menu selection. It is typically used with displays +that can repaint faster than they can handle save-unders. +.IP "\fBNoStackMode\fP [{ \fIwin-list\fP }]" 8 +This variable indicates that client window requests to change stacking order +should be ignored. If the optional \fIwin-list\fP is given, only requests on +those windows will be ignored. This is typically used to prevent applications +from relentlessly popping themselves to the front of the window stack. +.IP "\fBNoTitle\fP [{ \fIwin-list\fP }] " 8 +This variable indicates that windows should not have titlebars. If the +optional \fIwin-list\fP is given, only those windows will not have titlebars. +\&\fBMakeTitle\fP may be used with this option to force titlebars to be put +on specific windows. The default is: +.RS 12 +.nf +\&\fBNoTitle\fP +{ + "VTWM *" + "xclock" + "xload" +} +.fi +.RE +.IP "\fBNoTitleFocus\fP" 8 +This variable indicates that \fBvtwm\fP should not set keyboard input focus to +each window as it is entered. Normally, \fBvtwm\fP sets the focus +so that focus and key events from the titlebar and +icon managers are delivered to the application. If the pointer is moved +quickly and \fBvtwm\fP is slow to respond, input can be directed to the old +window instead of the new. This option is typically +used to prevent this "input lag" and to +work around bugs in older applications that have problems with focus events. +.IP "\fBNoTitleHighlight\fP [{ \fIwin-list\fP }]" 8 +This variable indicates that the highlight area of the titlebar, which is +used to indicate the window that currently has the input focus, should not +be displayed. If the optional \fIwin-list\fP is given, only those windows +will not have highlight areas. This and the \fBSqueezeTitle\fP options +can be set to substantially reduce the amount of screen space required by +titlebars. +.IP "\fBNotVirtualGeometries\fP" 8 +This variable indicates that \fBvtwm\fP should assume that user geometries +should be relative to the current virtual window, as opposed to absolute. +If you set this, then "xterm -geometry +20+20" specifies a position in the +current view; otherwise, it would specify a position in the top-left view. +It is set by default. +.IP "\fBNoWindowRing\fP { \fIwin-list\fP }" 8 +This variable specifies a list of windows that will not be added to the +list along which the \fBf.warpring\fP function cycles. +See also \fBWindowRing\fP. +.IP "\fBOldFashionedTwmWindowsMenu\fP" 8 +.IP "\fBOldFashionedVtwmWindowsMenu\fP" 8 +By default, the \fBVTWM Windows\fP menu will use the same colors +that you see in the panner. This variable disables that behavior. +.IP "\fBOpaqueMove\fP [{ \fIwin-list\fP }]" 8 +.IP "\fBOpaqueResize\fP [{ \fIwin-list\fP }]" 8 +These variables indicate that the \fBf.move\fP and \fBf.resize\fP functions +should actually change the window instead of just an outline so that the user +can immediately see what the window will look like. If the optional +\&\fIwin-list\fP is given, only those windows will be affected "opaquely". +These options are typically used on fast systems (particularly when +\&\fBNoGrabServer\fP is set). +.IP "\fBPanDistanceX\fP \fIN\fP" 8 +.IP "\fBPanDistanceY\fP \fIN\fP" 8 +These variables define a grid of screens for the virtual desktop, expressed +as \fIN%\fP of a real screen. When the \fBf.snap\fP function is called, the +real screen will be moved to the closest grid location. The (mis)naming of +these variables is for historical reasons. The default value is \fI100\fP, +effectively setting up "pages" in the virtual desktop. +.IP "\fBPanResistance\fP \fImilliseconds\fP" 8 +This variable indicates how hard it should be to pan to an adjacent virtual +screen. It specifies how long the pointer must be within \fBAutoPanBorderWidth\fP +pixels of the real screen's edge. Values equal to \fI0\fP or greater than +\&\fI10000\fP disables this feature. The default is \fI750\fP milliseconds. +.IP "\fBPauseOnExit\fP \fIN\fP" 8 +.IP "\fBPauseOnQuit\fP \fIN\fP" 8 +These variables define a delay on exit, expressed in seconds. They allow the +\&\fB(vtwm stop)\fP and \fBf.quit\fP sounds time to play before the connection +to \fBrplayd\fP(8) is closed. +.IP "\fBPixmaps\fP { \fIpixmaps\fP }" 8 +This variable specifies a list of images that define the appearance +of various windows. Each entry is a keyword indicating the window to set, +followed by a string giving the name of the image. Built-in and external +images may be freely mixed, given the constraints described in the +.B IMAGE AND AUDIO FORMATS +section. +The following windows may be specified thus: +.RS 12 +.nf +\&\fBPixmaps\fP +{ + TitleHighlight ":xpm:sunkenbox" + RealScreenPixmap "scaledbackground.xpm" + VirtualBackgroundPixmap "gray1" + MenuIconPixmap ":xpm:rarrow" + IconManagerPixmap ":xpm:zoom" +} +.fi +.RE +.IP +By default, the \fBTitleHighlight\fP is an even, stippled pattern if \fBvtwm\fP +is built with 2D features, or "sunken" lines when \fBvtwm\fP is built with 3D +features. The \fBMenuIconPixmap\fP is a right arrow by default (rendered 3D as +appropriate), and the default \fBIconManagerPixmap\fP is either the X logo or +a "raised" box, for 2D or 3D features, respectively. +.IP "\fBPointerPlacement\fP" 8 +This variable indicates that windows with no specified geometry should +be placed with the window origin at the location of the mouse pointer or, +if \fBWarpSnug\fP is specified, as close as possible to that location such +that the window fits onto the real screen. If \fBRandomPlacement\fP is also +set then it takes precedence. +.IP "\fBPrettyZoom\fP" 8 +If \fBZoom\fP is turned on, this makes the associated animation look just a little +nicer, depending on your personal taste. This makes the zoom slower, +however, so you may have to decrease the value of the \fBZoom\fP variable. +.IP "\fBRaiseDelay\fP \fImilliseconds\fP" 8 +For windows that are to be automatically raised when the pointer enters +(see the \fBAutoRaise\fP variable and the \fBf.autoraise\fP function) +this variable specifies the length of time the pointer should rest in +the window before it is raised. The default is \fI0\fP milliseconds. +.IP "\fBRaiseOnStart\fP" 8 +This variable specifies that the raise which would normally occur at the end +of a move or resize operation (subject to \fBMoveDelta\fP, \fBNoRaiseOnMove\fP, +and \fBNoRaiseOnResize\fP) will occur at the start of the operation. This may +be useful when \fBOpaqueMove\fP and/or \fBOpaqueResize\fP are specified. Note +that cancelling a move or resize operation with this variable set will not +preserve the window stacking order. +.IP "\fBRandomPlacement\fP" 8 +This variable indicates that windows with no specified geometry should +be placed in a pseudo-random location instead of having the user drag an +outline (or the window itself if the \fBOpaqueMove\fP variable is set) to +the preferred location. +.IP "\fBRealScreenBackground\fP \fIstring\fP" 8 +See \fBRealScreenForeground\fP. +.IP "\fBRealScreenBorderWidth\fP \fIpixels\fP" 8 +This value specifies the border width of the \fBRealScreen\fP window +(see \fBRealScreenForeground\fP). The default value is \fI0\fP pixels. +.IP "\fBRealScreenForeground\fP \fIstring\fP" 8 +Inside what \fBvtwm\fP calls the virtual desktop window, but which we might +call the "panner", is a little window that shows where the physical screen +is located in virtual space. The \fBvtwm\fP source code calls this little +window the RealScreen. By default, it has no border, and can be distinguished +from the normal backdrop of the panner only by its color or image. +Its foreground color has no meaning unless you give it an image. +(It can be given a border with \fBRealScreenBorderWidth\fP.) +.IP "\fBRealScreenPixmap\fP \fIstring\fP" 8 +Names an image file used to decorate the RealScreen window. +A sample is provided, \fInestedsqu.xbm\fP, but your mileage may vary as the +size of your screen varies! +It is easy to find out the size of this window and to create any image file +of type \fBbitmap\fP(1) or \fBpixmap\fP(1) for it; that is the recommended +procedure. +.IP "\fBResizeFont\fP \fIstring\fP" 8 +This variable specifies the font to be used for in the dimensions window when +resizing windows. +The default is \fI"-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*"\fP. +.IP "\fBResizeRegion\fP \fIlocation\fP" 8 +This variable specifies the area on the screen to display the resize window. +The \fIlocation\fP should be one of \fBNorthWest\fP, \fBNorthEast\fP, +\&\fBSouthWest\fP, \fBSouthEast\fP, or \fBCentered\fP. +.IP "\fBRestartPreviousState\fP" 8 +This variable indicates that +\&\fBvtwm\fP should attempt to use the WM_STATE property on client windows +to tell which windows should be iconified and which should be left visible. +This is typically used to try to regenerate the state that the screen +was in before the previous window manager was shutdown. It is set by default. +.IP "\fBRightHandSidePulldownMenus\fP" 8 +Pull-down menus can appear when the pointer is to the right of the center of +their parent menu, or they can appear when the pointer is closer to the right +edge of their parent menu. This option enables the latter behavior, and is +the default. +.IP "\fBSaveColor\fP { \fIcolors-list\fP }" 8 +This variable indicates a list of color assignments to be stored as pixel +values in the root window property _MIT_PRIORITY_COLORS. Clients may elect +to preserve these values when installing their own colormap. Note that +use of this mechanism is a way an for application to avoid the "technicolor" +problem, whereby useful screen objects such as window borders and titlebars +disappear when a programs custom colors are installed by the window +manager. +For example: +.RS 12 +.nf +\&\fBSaveColor\fP +{ + BorderColor + TitleBackground + TitleForeground + "red" + "green" + "blue" +} +.fi +.RE +.IP +This would place on the root window 3 pixel values for borders and titlebars, +as well as the three color strings, all taken from the default colormap. +.IP "\fBShallowReliefWindowButton\fP" 8 +This indicates that the features of built-in 3D titlebar buttons, the 3D +icon manager button the 3D menu pull-right icon, and the 3D titlebar highlight +area should be rendered with a "flatter" appearance. It is set by default if +\&\fBvtwm\fP is built with 3D features. +.IP "\fBShowIconManager\fP" 8 +This variable indicates that the icon manager window should be displayed when +\&\fBvtwm\fP is started. It can always be brought up using the +\&\fBf.showiconmgr\fP function. +.IP "\fBSnapRealScreen\fP" 8 +This variable causes the real screen to snap to a grid defined in +\&\fBPanDistanceX\fP and \fBPanDistanceY\fP increments whenever the representation +moves. The \fBf.snaprealscreen\fP function can be used to toggle this setting. +.IP "\fBSortIconManager\fP" 8 +This variable indicates that entries in the icon manager should be +sorted alphabetically rather than by simply appending new windows to +the end. It is set by default. +.IP "\fBSoundHost\fP \fIstring\fP" 8 +This variable specifies what machine (by its \fITCP/IP hostname\fP) is +running the \fBrplayd\fP(8) daemon. If not specified, the local machine +is tried. If \fBrplayd\fP(8) cannot be accessed, sound will be toggled off. +.IP "\fBSounds\fP { \fIsound-list\fP }" 8 +This variable is a list of identifiers and associated sound files. It +contains entries of the form: +.RS 12 +.nf +"\fIidentifier\fP" "\fIsoundfile\fP" [\fIvolume\fP] +.fi +.RE +.RS +where \fIidentifier\fP is any function described in the +.B BINDINGS +section except \fBf.playsound\fP, \fBf.sounds\fP, and \fBf.separator\fP, +as well as these event identifiers: \fB(vtwm start)\fP, \fB(vtwm stop)\fP, +\&\fB(client map)\fP, \fB(client unmap)\fP, \fB(menu map)\fP, +\&\fB(menu unmap)\fP, \fB(info unmap)\fP, \fB(autopan event)\fP, +and \fB(bell event)\fP. The \fIsoundfile\fP is the full pathname of +the sound file to play for the associated \fIidentifier\fP, and +\&\fIvolume\fP sets the volume for which to play that sound (see also +\&\fBSoundVolume\fP). Note that the list entries must be quoted: +.RE +.RS 12 +.nf +\&\fBSounds\fP +{ + "(vtwm start)" "/usr/share/sounds/wowee.wav" + "(vtwm stop)" "/usr/share/sounds/seeya.wav" + "f.exec" "/usr/share/sounds/click.au" 50 + "(client map)" "/usr/share/sounds/ping.au" 50 + "f.delete" "/usr/share/sounds/doh1.wav" + "f.deletedoor" "/usr/share/sounds/doh2.wav" + "f.destroy" "/usr/share/sounds/doh3.wav" + "(client unmap)" "/usr/share/sounds/ping.au" +} +.fi +.RE +.IP +This example points out that some \fIidentifier\fPs "overlap": +.RS 12 +.nf +f.beep > (bell event) f.exec > (client map) +f.delete > (client unmap) f.menu > (menu map) +f.deletedoor > (client unmap) f.quit > (vtwm stop) +f.destroy > (client unmap) f.version = f.identify +.fi +.RE +.IP +In these cases, the function takes precedence over the event when both +would otherwise play. +.IP "\fBSoundVolume\fP \fIN\fP" 8 +This variable sets the overall volume for which to play sounds, expressed +as \fIN%\fP of maximum. Default is \fI25\fP (1/4 attenuation). +.IP "\fBSqueezeTitle\fP [{ \fIsqueeze-list\fP }] " 8 +This variable indicates that \fBvtwm\fP should attempt to use the SHAPE +extension to make titlebars occupy only as much screen space as they need, +rather than extending all the way across the top of the window. +The optional \fIsqueeze-list\fP +may be used to control the location of the squeezed titlebar along the +top of the window. It contains entries of the form: +.RS 12 +.nf +"\fIname\fP" \fIjustification\fP \fInum\fP \fIdenom\fP +.fi +.RE +.RS +where \fIname\fP is a window name, \fIjustification\fP is either +\&\fBleft\fP, \&\fBcenter\fP, or \fBright\fP, and \fInum\fP and +\&\fIdenom\fP are numbers specifying a ratio for the relative position +about which the titlebar is located, measured from left to right. +A ratio of 0/0 indicates that the \fIjustification\fP is absolute, +A non-zero numerator with a zero denominator indicates a pixel count, +and the \fIjustification\fP is ignored entirely for any other ratio. +For example: +.RE +.RS 12 +.nf +\&\fBSqueezeTitle\fP +{ + "XTerm" left 0 0 + "xterm1" left 1 3 + "xterm2" right 2 3 + "oclock" center 0 0 + "emacs" right 0 0 +} +.fi +.RE +.IP +The \fBDontSqueezeTitle\fP list can be used to turn off squeezing on +certain titles. It is set by default. +.IP "\fBStartIconified\fP [{ \fIwin-list\fP }] " 8 +This variable indicates that client windows should initially be left as +icons until explicitly deiconified by the user. If the optional \fIwin-list\fP +is given, only those windows will be started iconic. This is useful for +programs that do not support an \fI-iconic\fP command line option or +resource. +.IP "\fBStaticIconPositions\fP" 8 +This variable alters icon placement such that they will maintain their +positions on the virtual desktop when not nailed and \fBDeiconifyToScreen\fP +is not used. This is most applicable when \fBSnapRealScreen\fP and +\&\fBAutoPan\fP is used with \fBPanDistanceX\fP and \fBPanDistanceY\fP values +to simulate \fBctwm\fP(1) workspaces. +.IP "\fBStayUpMenus\fP" 8 +This variable alters menu interaction. By default, a menu item is selected +when a pointer button is released over it. This variable causes menu items to +be selected on the next button press event. +.IP "\fBStayUpOptionalMenus\fP" 8 +This variable is similar to \fBStayUpMenus\fP, except that if any menu items +are selected, the menu interaction reverts to the old behavior. For example, +suppose you have the right pointer button bound to bring up a menu with a title +bar. Clicking the right button and releasing it (over the title bar) will +bring up the menu and have it stay up until you click on a menu item. +Clicking the right button, moving the pointer to a menu item, and releasing +the right button will activate that menu item and dismiss the menu. +.IP "\fBSticky\fP { \fIlist\fP }" 8 +A synonym for \fBNailedDown\fP. +.IP "\fBStickyAbove\fP" 8 +A synonym for \fBNailedAbove\fP. +.IP "\fBStrictIconManager\fP" 8 +This variable causes icon managers to list only those windows that are in +an iconified state. +.IP "\fBTitleBackground\fP \fIstring\fP [{ \fIwin-list\fP }]" 8 +This variable specifies the background color used in titlebars, and may only +be specified inside of a \fBColor\fP or \fBMonochrome\fP list. The optional +\&\fIwin-list\fP is a list of window names and colors so that per-window +colors may be specified. The default is \fI"maroon"\fP for color displays +or \fI"gray50"\fP for monochrome displays. +.IP "\fBTitleBevelWidth\fP \fIpixels\fP" 8 +Tells \fBvtwm\fP to use 3D-looking titlebars, and specifies the width in +pixels of the bevel that surrounds the titlebar. If the value of +\&\fBButtonIndent\fP added to \fBFramePadding\fP equals zero, the bevel +will be bound to the text and highlight area. The default is \fI0\fP +if \fBvtwm\fP is built with 2D features, or \fI1\fP when \fBvtwm\fP is +built with 3D features.. +.IP "\fBTitleButtonBorderWidth\fP \fIpixels\fP" 8 +This variable specifies the width in pixels of the border surrounding +titlebar buttons, drawn in the \fBTitleForeground\fP color. The default is +\fI1\fP if \fBvtwm\fP is built with 2D bitmaps, or \fI0\fP when \fBvtwm\fP +is built with 3D pixmaps. +.IP "\fBTitleFont\fP \fIstring\fP" 8 +This variable specifies the font to used for displaying window names in +titlebars. +The default is \fI"-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*"\fP. +.IP "\fBTitleForeground\fP \fIstring\fP [{ \fIwin-list\fP }]" 8 +This variable specifies the foreground color used in titlebars, and +may only be specified inside of a \fBColor\fP or \fBMonochrome\fP list. +The optional \fIwin-list\fP is a list of window names and colors so that +per-window colors may be specified. The default is \fI"maroon"\fP for color +displays or \fI"gray50"\fP for monochrome displays. +.IP "\fBTitlePadding\fP \fIpixels\fP" 8 +This variable specifies the distance between titlebar buttons in the titlebar. +Note that distances between buttons and the title, the title and the highlight +area, and the highlight area and buttons, are all set to a hard-coded value. +The default is \fI5\fP if \fBvtwm\fP is built with 2D features, or \fI0\fP +when \fBvtwm\fP is built with 3D features. +.IP "\fBUnknownIcon\fP \fIstring\fP" 8 +This variable specifies the filename of an image file to be +used as the default icon. This image will be used as the icon of all +clients which do not provide an icon image and are not listed +in the \fBIcons\fP list. +.IP "\fBUsePPosition\fP \fIstring\fP [{ \fIwin-list\fP }]" 8 +This variable specifies whether or not \fBvtwm\fP should honor +program-requested locations (given by the \fBPPosition\fP flag in the +WM_NORMAL_HINTS property), in the absence of a user-specified position. +The argument \fIstring\fP may have one of three values: \fI"off"\fP +(the default) indicating that \fBvtwm\fP should ignore the program-supplied +position, \fI"on"\fP indicating that the position should be used, and +\&\fI"non-zero"\fP indicating that the position should used if it is other +than (0,0) (for working around a bug in older toolkits). +The optional \fIwin-list\fP is a list of window names and arguments that +will override the global \fIstring\fP argument. For example: +.RS 12 +.nf +\&\fBUsePPosition\fP "off" +{ + "MPlayer" "on" +} +.fi +.RE +.IP "\fBVirtualBackground\fP \fIstring\fP" 8 +This is the background color for the panner, a.k.a. the Virtual Desktop +window. The default is \fI"maroon"\fP for color displays or \fI"gray50"\fP +for monochrome displays. +.IP "\fBVirtualBackgroundPixmap\fP \fIstring\fP" 8 +Names an image file to decorate the panner. +.IP "\fBVirtualForeground\fP \fIstring\fP" 8 +Foreground for the panner; has no use unless you specify a panner +image of type \fBbitmap\fP(1). +.IP "\fBVirtualDesktop\fP \fIgeometry\fP \fIscale\fP" 8 +This variable must be set to enable the virtual desktop features of +\&\fBvtwm\fP. If this variable is not set, \fBvtwm\fP will behave in +the same manner as \fBtwm\fP. This variable specifies where to place +the virtual desktop window and its size. The \fIgeometry\fP is a +standard X geometry specification and defines the size and location +of the window containing the desktop representation. +.IP +The \fIscale\fP parameter specifies the scaling of the virtual +desktop window compared to the desktop. The size specification can +be given in three ways: If size is larger than the screen size, it +represents the size of the whole desktop, and the virtual window desktop +size will then be size divided by \fIscale\fP. When size times +\&\fIscale\fP is smaller than the screen size, size represents the +number of screens that should fit in the desktop. Otherwise size +represents the size of the virtual desktop window, and the currently +accessible virtual desktop is then \fIscale\fP times the size of the +desktop window. Using the default as an example: +.RS 12 +.nf +\&\fBVirtualDesktop\fP "5x2-0-0" 16 +.fi +.RE +.RS +With \&\fIscale\fP set to \fI16\fP, and a physical screen size of 1024x768, +the desktop area is 1/16 the size of the screen times the number of screens +specified: +.RE +.RS 12 +.nf +(5 * (1024 / 16)) x (2 * (768 / 16)) = 320 x 96 +.fi +.RE +.IP +The size of the desktop can be changed dynamically, by simply resizing the +virtual desktop window. +.IP "\fBVirtualDesktopBevelWidth\fP \fIpixels\fP" 8 +Tells \fBvtwm\fP to use a 3D-looking virtual desktop, and specifies the width +in pixels of the bevel. The default is \fI0\fP if \fBvtwm\fP is built with 2D +features, or \fI1\fP when \fBvtwm\fP is built with 3D features. +.IP "\fBVirtualDesktopFont\fP \fIfont\fP" 8 +This variable causes \fIfont\fP to be used when displaying the names +of windows in the virtual desktop display. If this variable is not +set, then names will not be displayed. The \fBDesktopDisplayForeground\fP +should also be set for this feature to be useful. +The default is \fI"-adobe-helvetica-medium-r-normal--*-75-*-*-*-*-*-*"\fP. +.IP "\fBVirtualReceivesMotionEvents\fP" 8 +.IP "\fBVirtualSendsMotionEvents\fP" 8 +These variables indicate that changes to the position and dimension of +windows on the real screen will be reflected in the virtual desktop as +they occur, and visa-versa. +.IP "\fBWarpCentered\fP \fIstring\fP" 8 +By default, on warps to windows, the pointer goes to either the center of +the titlebar, or in the absence of, the center of the top border member. +This variable specifies that the pointer should warp to the center of the +window depending on the \fIstring\fP argument: \fI"on"\fP indicates all +windows, \fI"titled"\fP indicates titled windows only, \fI"untitled"\fP +indicates untitled windows only, and \fI"off"\fP (the default) indicating +the default behavior. Note that warps to icon managers are exceptional: +The pointer always goes to either the active entry, or in the absence of, +the top entry. +.IP "\fBWarpCursor\fP [{ \fIwin-list\fP }]" 8 +This variable indicates that the pointer should be warped into windows when +they are deiconified. If the optional \fIwin-list\fP is given, the pointer +will only be warped when those windows are deiconified. It is set by default. +.IP "\fBWarpSnug\fP" 8 +With this variable set, the warp functions (\fBf.warp\fP and the like) will +fit the entire window on the screen, i.e., they'll be snugged on the real +screen. +.IP "\fBWarpToTransients\fP" 8 +This variable indicates that the pointer should be warped into transient +windows when they are created. +.IP "\fBWarpUnmapped\fP" 8 +This variable indicates that the warp functions (\fBf.warp\fP and the like) +should deiconify any iconified windows they encounter. This is typically +used to make a key binding that will pop a particular window (such as +\&\fIxmh\fP), no matter where it is. The default is for the functions to +ignore iconified windows. +.IP "\fBWarpVisible\fP" 8 +This variable indicates that the warp functions \fBf.warpclassnext\fP, +\&\fBf.warpclassprev\fP, \fBf.warpring\fP, and \fBf.warpto\fP should restrict +themselves to windows that are on the screen. The default is for the +functions to traverse the entire virtual desktop. +.IP "\fBWarpWindows\fP" 8 +When warping to a window, by default the real screen will be moved +to find the window on the virtual desktop. With this set, the window +itself will be warped to the real screen, moving the window in the virtual +desktop. +.IP "\fBWindowRing\fP [{ \fIwin-list\fP }]" 8 +This variable specifies that when windows are created, they should be added +to the list that the \fBf.warpring\fP function operates on. If the optional +\&\fIwin-list\fP is given, then only those windows will be included in the +window ring. See also \fBNoWindowRing\fP and \fBf.ring\fP. +.IP "\fBXorValue\fP \fInumber\fP" 8 +This variable specifies the value to use when drawing window outlines for +moving and resizing. This should be set to a value that will result in a +variety +of distinguishable colors when exclusive-or'ed with the contents of the +user's typical screen. Setting this variable to 1 often gives nice results +if adjacent colors in the default colormap are distinct. By default, +\&\fBvtwm\fP will attempt to cause temporary lines to appear at the opposite +end of the colormap from the graphics. +.IP "\fBZoom\fP [ \fIcount\fP ]" 8 +This variable indicates that outlines suggesting movement of a window +to and from its iconified state should be displayed whenever a window is +iconified or deiconified. The optional \fIcount\fP argument specifies the +number of outlines to be drawn. The default count is \fI8\fP. +.IP "\fBZoomZoom\fP" 8 +This variable modifies zooms such that a random place will be used for the +source or destination when there isn't an appropriate window (e.g., an icon, +icon manager entry, or client window). Default behavior inhibits zooms when +there aren't appropriate windows, except for the \fBf.zoomzoom\fP function. +.\"===================================================================== +.SH SPECIAL VARIABLES +.PP +The following variables must be set after the fonts have been +assigned, so it is usually best to put them at the end of the variables +or beginning of the bindings sections: +.IP "\fBDefaultFunction\fP \fIfunction\fP" 8 +This variable specifies the function to be executed when a key or button +event is received for which no binding is provided. This is typically +bound to \fBf.nop\fP, \fBf.beep\fP, or a menu containing window operations. +.IP "\fBWindowFunction\fP \fIfunction\fP" 8 +This variable specifies the function to execute when a window is selected +from the \fBVTWM Windows\fP menu. If this variable is not set (default), +the window will be deiconified and raised. It is strongly recommended that +if this is set, the function includes provision for deiconifying windows. +.\"===================================================================== +.SH BINDINGS +.PP +After the desired variables have been set, functions may be attached +titlebar buttons and key and pointer buttons. Titlebar buttons may be added +from the left or right side and appear in the titlebar from left-to-right +according to the +order in which they are specified. Key and pointer button +bindings may be given in any order. +.PP +Titlebuttons specifications must include the name of the image to use in +the button box and the function to be invoked when a pointer button is +pressed within them: +.RS 4 +.nf +\&\fBLeftTitleButton\fP "\fIimage\fP" = \fIfunction\fP +.fi +.RE +or +.RS 4 +.nf +\&\fBRightTitleButton\fP "\fIimage\fP" = \fIfunction\fP +.fi +.RE +.PP +See the \fBButtonIndent\fP and \fBFramePadding\fP variables and the +.B IMAGE AND AUDIO FORMATS +section for details on the \fIimage\fP specification. +.PP +Key and pointer button specifications must give the modifiers that must +be pressed, over which parts of the screen the pointer must be, and what +function is to be invoked. Keys are given as strings containing the +appropriate +keysym name; buttons are given as the keywords \fBButton1\fP-\fBButton5\fP: +.RS 4 +.nf +"FP1" = \fImodlist\fP : \fIcontext\fP : \fIfunction\fP +\&\fBButton1\fP = \fImodlist\fP : \fIcontext\fP : \fIfunction\fP +.fi +.RE +.PP +The \fImodlist\fP is any combination of the modifier names \fBshift\fP, +\&\fBcontrol\fP, \fBlock\fP, \fBmeta\fP, \fBmod1\fP, \fBmod2\fP, \fBmod3\fP, +\&\fBmod4\fP, or \fBmod5\fP (which may be abbreviated as +\&\fBs\fP, \fBc\fP, \fBl\fP, \fBm\fP, \fBm1\fP, \fBm2\fP, \fBm3\fP, \fBm4\fP, +\&\fBm5\fP, respectively) separated by a vertical bar (\(or). +Similarly, the \fIcontext\fP is any combination of +\&\fBwindow\fP, +\&\fBtitle\fP, +\&\fBicon\fP, +\&\fBroot\fP, +\&\fBframe\fP, +\&\fBvirtual\fP, +\&\fBdesktop\fP, +\&\fBdoor\fP, +\&\fBiconmgr\fP, their first letters (\fBiconmgr\fP abbreviation is +\&\fBm\fP, \fBdoor\fP has no abbreviation), +or \fBall\fP, separated by a vertical bar. It is rumored that window class +names will also work. The \fIfunction\fP is any of the \fBf.\fP keywords +described below. For example, the default startup file contains the following +bindings: +.RS 4 +.nf +Button1 = : root : f.menu "VTWM Windows" +Button1 = m : window | icon : f.function "move-or-lower" +Button2 = m : window | icon : f.iconify +Button3 = m : window | icon : f.move +Button1 = : title : f.move +Button2 = : title : f.raiselower +Button1 = : icon : f.function "move-or-iconify" +Button2 = : icon : f.iconify +Button1 = : iconmgr : f.iconify +Button2 = : iconmgr : f.iconify +.fi +.RE +.PP +A user who wanted to be able to manipulate windows from the keyboard could +use the following bindings: +.RS 4 +.nf +"F1" = : all : f.iconify +"F2" = : all : f.raiselower +"F3" = : all : f.warpring "next" +"F4" = : all : f.warpto "xmh" +"F5" = : all : f.warpto "emacs" +"F6" = : all : f.colormap "next" +"F7" = : all : f.colormap "default" +"F20" = : all : f.warptoscreen "next" +"Left" = m : all : f.backiconmgr +"Right" = m | s : all : f.forwiconmgr +"Up" = m : all : f.upiconmgr +"Down" = m | s : all : f.downiconmgr +.fi +.RE +.PP +Note, however, that using \fIall\fP for button or key bindings is +almost always a bad idea, since it prevents all applications from +receiving those events; this can cripple text and graphics editors +that otherwise expect to see those buttons or keys (see also the +\&\fBIgnoreModifiers\fP variable, and the \fBf.bindbuttons\fP, +\&\fBf.bindkeys\fP, \fBf.unbindbuttons\fP, and \fBf.unbindkeys\fP +functions). +.PP +\&\fBvtwm\fP provides many more window manipulation primitives than can be +conveniently stored in a titlebar, menu, or set of key bindings. Although +a small set of defaults are supplied (unless either \fBNoDefaults\fP, +\&\fBNoDefaultMouseOrKeyboardBindings\fP, or \fBNoDefaultTitleButtons\fP is +specified), most users will want to have their most common operations +bound to key and button strokes. To do this, \fBvtwm\fP associates names +with each of the primitives and provides \fIuser-defined functions\fP for +building higher level primitives and \fImenus\fP for interactively selecting +among groups of functions. +.PP +User-defined functions contain the name by which they are referenced in +calls to \fBf.function\fP and a list of other functions to execute. For +example: +.RS 4 +.nf +Function "move-or-lower" { f.move f.deltastop f.lower } +Function "move-or-iconify" { f.move f.deltastop f.iconify } +Function "restore-colormap" { f.colormap "default" f.lower } +.fi +.RE +.PP +The function name must be used in \fBf.function\fP exactly as it appears in +the function specification. +.PP +\&\fBVTWM PROFILE\fP. If a function called "VTWM Profile" +is defined within the startup file, that function will be executed +upon startup or restarting of the window manager. For example: +.RS 4 +.nf +AutoPan 25 +Function "VTWM Profile" +{ + f.autopan +} +.fi +.RE +gives \fBAutoPan\fP a value but turns autopanning off initially (it won't +have a value unless \fBAutoPan\fP is set in the startup file; see +\&\fBf.autopan\fP below), in case you want to turn it on sometime later. +.PP +In the descriptions below, if the function is said to operate on the selected +window, but is invoked from a root menu, the cursor will be changed to +the \fBSelect\fP cursor and the next window to receive a button press will +be chosen: +.IP "\fB!\fP \fIstring\fP" 8 +This is an abbreviation for \fBf.exec\fP \fIstring\fP. +.IP "\fB^\fP \fIstring\fP (OBSOLETE --- use a clipboard client)" 8 +This is an abbreviation for \fBf.cut\fP \fIstring\fP. +.IP "\fBf.autopan\fP" 8 +If autopan wasn't configured in your .vtwmrc file, this does +nothing. If, however, it was configured, this toggles the current +autopan state. The reason for this command is that autopan is +sometimes nice to have, but it interferes with using sticky windows +that are near the edge of the screen. With this command, you get the +best of both worlds. +.IP "\fBf.autoraise\fP" 8 +This function toggles whether or not the selected window is raised whenever +entered by the pointer. See the description of the variable \fBAutoRaise\fP. +.IP "\fBf.backiconmgr\fP" 8 +This function warps the pointer to the previous column in the +current icon manager, wrapping back to the previous row if necessary. +.IP "\fBf.beep\fP" 8 +This function sounds the keyboard bell. +.IP "\fBf.bindbuttons\fP" 8 +.IP "\fBf.bindkeys\fP" 8 +These functions enable \fBvtwm\fP's pointer or keyboard bindings for the +selected window. These are only needed if the bindings have been disabled +with the \fBf.unbindbuttons\fP or \fBf.unbindkeys\fP functions. Be careful +what you bind these functions to; \fBf.bindkeys\fP bound to a window context +key will not be accessable after \fBf.unbindkeys\fP is invoked for the window! +.IP "\fBf.bottomzoom\fP" 8 +This function is similar to the \fBf.fullzoom\fP function, but +resizes the window to fill only the bottom half of the screen. +.IP "\fBf.circledown\fP" 8 +This function lowers the top-most window that occludes another window. +.IP "\fBf.circleup\fP" 8 +This function raises the bottom-most window that is occluded by another window. +.IP "\fBf.colormap\fP \fIstring\fP" 8 +This function rotates the colormaps (obtained from the WM_COLORMAP_WINDOWS +property on the window) that \fBvtwm\fP will display when the pointer +is in this window. The argument \fIstring\fP may have one of the following +values: \fI"next"\fP, \fI"prev"\fP, and \fI"default"\fP. It should be noted +here that in general, the installed colormap is determined by keyboard focus. +A pointer driven keyboard focus will install a private colormap upon entry +of the window owning the colormap. Using the click to type model, private +colormaps will not be installed until the user presses a pointer button on +the target window. +.IP "\fBf.cut\fP \fIstring\fP (OBSOLETE --- use a clipboard client)" 8 +This function places the specified \fIstring\fP (followed by a newline +character) into the root window property CUT_BUFFER0. +.IP "\fBf.cutfile\fP (OBSOLETE --- use a clipboard client)" 8 +This function reads the file indicated by the contents of the CUT_BUFFER0 +window property and replaces the cut buffer. +.IP "\fBf.deiconify\fP" 8 +This function deiconifies the selected window. If the window is not an icon, +this function does nothing. +.IP "\fBf.delete\fP" 8 +This function sends the WM_DELETE_WINDOW message to the selected window if +the client application has requested it through the WM_PROTOCOLS window +property. The application is supposed to respond to the message by removing +the window. If the window has not requested +WM_DELETE_WINDOW messages, the keyboard bell will be rung indicating that +the user should choose an alternative method. Note this is very different +from \fBf.destroy\fP. The intent here is to delete a single window, not +necessarily the entire application. +.IP "\fBf.deletedoor\fP" 8 +This function deletes a door. +.IP "\fBf.deltastop\fP" 8 +This function allows a user-defined function to be aborted if the pointer has +been moved more than \fPMoveDelta\fP pixels. See the example definition +given for \fBFunction "move-or-lower"\fP at the beginning of the section. +.IP "\fBf.destroy\fP" 8 +This function instructs the X server to close the display connection of the +client that created the selected window. This should only be used as a last +resort for shutting down runaway clients. See also \fBf.delete\fP. +.IP +This action sometimes leaves a runaway process that consumes CPU +cycles; you should always try to use the applications own quit +function, rather than this one. +.IP "\fBf.downiconmgr\fP" 8 +This function warps the pointer to the next row in the current icon manger, +wrapping to the beginning of the next column if necessary. +.IP "\fBf.enterdoor\fP" 8 +This function activates this door. Typically one binds: +.RS 12 +.nf +Button1 = : door : f.enterdoor +Button2 = : door : f.enterdoor +Button3 = : door : f.enterdoor +.fi +.RE +.IP "\fBf.exec\fP \fIstring\fP" 8 +This function passes the argument \fIstring\fP to /bin/sh for execution. +In multiscreen mode, if \fIstring\fP starts a new X client without +giving a display argument, the client will appear on the screen from +which this function was invoked. +.IP "\fBf.file\fP \fIstring\fP (OBSOLETE --- use a clipboard client)" 8 +This function assumes \fIstring\fP is a file name. This file is read into +the window server's cut buffer. +.IP "\fBf.focus\fP" 8 +This function toggles the keyboard focus of the server to the +selected window, changing the focus rule from pointer-driven if necessary. +If the selected window already was focused, this function executes an +\&\fBf.unfocus\fP. +.IP "\fBf.forcemove\fP" 8 +This function is like \fBf.move\fP except that it ignores the \fBDontMoveOff\fP +variable. +.IP "\fBf.forwiconmgr\fP" 8 +This function warps the pointer to the next column in the current icon +manager, wrapping to the beginning of the next row if necessary. +.IP "\fBf.fullzoom\fP" 8 +This function resizes the selected window to the full size of the display or +else restores the original size if the window was already zoomed. +.IP "\fBf.function\fP \fIstring\fP" 8 +This function executes the user-defined function whose name is specified +by the argument \fIstring\fP. +.IP "\fBf.hbzoom\fP" 8 +This function is a synonym for \fBf.bottomzoom\fP. +.IP "\fBf.hidedesktopdisplay\fP" 8 +This function unmaps the desktop display. +.IP "\fBf.hideiconmgr\fP" 8 +This function unmaps the current icon manager when selected from a client +window, and unmaps all icon managers when selected from the root window. +.IP "\fBf.horizoom\fP" 8 +This variable is similar to the \fBf.zoom\fP function except that the +selected window is resized to the full width of the display. +.IP "\fBf.htzoom\fP" 8 +This function is a synonym for \fBf.topzoom\fP. +.IP "\fBf.hzoom\fP" 8 +This function is a synonym for \fBf.horizoom\fP. +.IP "\fBf.iconify\fP" 8 +This function iconifies or deiconifies the selected window or icon, +respectively. +.IP "\fBf.identify\fP" 8 +This function displays a summary of the name and geometry of the +selected window. Clicking the pointer or pressing a key in the window +will dismiss it. If the function is invoked on a desktop representation of +a window, the real window which is represented will be identified. +.IP "\fBf.lefticonmgr\fP" 8 +This function similar to \fBf.backiconmgr\fP except that wrapping does not +change rows. +.IP "\fBf.leftzoom\fP" 8 +This variable is similar to the \fBf.bottomzoom\fP function but causes +the selected window is only resized to the left half of the display. +.IP "\fBf.lower\fP" 8 +This function lowers the selected window. +.IP "\fBf.menu\fP \fIstring\fP" 8 +This function invokes the menu specified by the argument \fIstring\fP. +Cascaded menus may be built by nesting calls to \fBf.menu\fP. +.IP "\fBf.move\fP" 8 +This function drags an outline of the selected window (or the window itself +if the \fBOpaqueMove\fP variable is set) until the invoking pointer button +is released, at which time the window is raised (subject to +\&\fBRaiseOnStart\fP, \fBMoveDelta\fP, and \fBNoRaiseOnMove\fP). Double +clicking within the number of milliseconds given by \fBConstrainedMoveTime\fP +warps the pointer to the center of the window and constrains the move +horizontally or vertically, depending on pointer movement. To abort the move, +press another button before releasing the invoking button. +.IP "\fBf.movescreen\fP" 8 +Moves a window (or possibly the real screen) inside the desktop display. To +abort the move, press another button before releasing the invoking button. +By default, the bindings using the \fBdesktop\fP context are defined as: +.RS 12 +.nf +Button1 = : desktop : f.movescreen +Button2 = : desktop : f.movescreen +.fi +.RE +.IP +This is useful if you want to reset the default keyboard and pointer bindings +via \fBNoDefaultMouseOrKeyboardBindings\fP and use some of your own for the +virtual desktop, e.g.: +.RS 12 +.nf +NoDefaultMouseOrKeyboardBindings +Button1 = : desktop : f.movescreen +Button2 = : desktop : f.warp +Button3 = : desktop : f.iconify +.fi +.RE +.IP +This function is not useful under any context other than "desktop". +.IP "\fBf.nail\fP" 8 +This function nails or unnails the selected window onto the real screen; the +current value of this property is toggled on the window. +.IP "\fBf.nailedabove\fP" 8 +This function toggles the setting of the \fBNailedAbove\fP variable. +.IP "\fBf.namedoor\fP" 8 +This function, bound to the door context, pastes a name from CUT_BUFFER0 +into the selected door (see the +.B BINDINGS +section for details). +.IP "\fBf.newdoor\fP" 8 +This function creates a new door with it's destination and name set to the real +screen's current position in the virtual desktop. +.IP "\fBf.nexticonmgr\fP" 8 +This function warps the pointer to the next icon manager containing any windows +on the current or any succeeding screen. +.IP "\fBf.nop\fP" 8 +This function does nothing and is typically used with the \fBDefaultFunction\fP +or \fBWindowFunction\fP variables or to introduce blank lines in menus. +.IP "\fBf.panup\fP \fIN\fP" 8 +.IP "\fBf.pandown\fP \fIN\fP" 8 +.IP "\fBf.panleft\fP \fIN\fP" 8 +.IP "\fBf.panright\fP \fIN\fP" 8 +These functions move the real screen by \fIN%\fP of the screen dimension in the +indicated direction. These are ideally bound to the cursor keys: +.RS 12 +.nf +"Up" = : root : f.panup "100" +"Down" = : root : f.pandown "100" +"Left" = : root : f.panleft "100" +"Right" = : root : f.panright "100" +.fi +.RE +.IP "\fBf.playsound\fP \fIsoundfile\fP" 8 +This function plays the specified sound at \fBSoundVolume\fP volume. The +\&\fIsoundfile\fP must be the full pathname of the sound file. This is a +rather "expensive" function compared to that provided by the \fBSounds\fP +variable, and should be avoided. +.IP "\fBf.previconmgr\fP" 8 +This function warps the pointer to the previous icon manager containing any +windows on the current or preceding screens. +.IP "\fBf.quit\fP" 8 +This function causes \fBvtwm\fP to restore the window's borders and exit. If +\&\fBvtwm\fP is the last client invoked from \fIxdm\fP, this will result in a +server reset, and the user's session will be logged out. +.IP +Users who stay logged in for long periods (days or weeks), or who like +to change window managers, or experiment with them, may find it +desirable to use a relatively simple application, such as +.BR xbiff (1), +as the last application in their +.IR .xinitrc +or +.IR .xsession +file, letting the window manager start earlier, and run in the +background. This allows changing window managers without logging out, +and also makes it much less likely that a session will be abruptly +terminated by a bug in a complex program like a window manager. The +one drawback to this approach is that \fBf.quit\fP then no longer +terminates the session: you need to use \fBf.delete\fP or \fBf.destroy\fP +on that last application to logout. +.IP "\fBf.raise\fP" 8 +This function raises the selected window. +.IP "\fBf.raiselower\fP" 8 +This function raises the selected window to the top of the stacking order if +it is occluded by any windows, otherwise the window will be lowered. +.IP "\fBf.refresh\fP" 8 +This function causes all windows to be refreshed. +.IP "\fBf.resetdesktop\fP" 8 +This function moves the real display to (0,0) +.IP "\fBf.resize\fP" 8 +This function drags an outline of the selected window (or the window itself +if the \fBOpaqueResize\fP variable is set) after crossing a border (or by +setting \fBAutoRelativeResize\fP) until the invoking pointer button is +released, at which time the window is raised (subject to +\&\fBRaiseOnStart\fP, \fBMoveDelta\fP, and \fBNoRaiseOnResize\fP). To abort +the resize, press another button before releasing the invoking button. +.IP "\fBf.restart\fP" 8 +This function kills and restarts \fBvtwm\fP. See also \fBf.startwm\fP. +.IP "\fBf.righticonmgr\fP" 8 +This function is similar to \fBf.nexticonmgr\fP except that wrapping does +not change rows. +.IP "\fBf.rightzoom\fP" 8 +This variable is similar to the \fBf.bottomzoom\fP function except that +the selected window is only resized to the right half of the display. +.IP "\fBf.ring\fP" 8 +Selects a window and adds it to the \fBWindowRing\fP list, or removes it if +it was already in the ring. This command makes \fBf.warpring\fP much more +useful, by making its configuration dynamic. +.IP "\fBf.saveyourself\fP" 8 +This function sends a WM_SAVEYOURSELF message to the selected window if it +has requested the message in its WM_PROTOCOLS window property. Clients that +accept this message are supposed to checkpoint all state associated with the +window and update the WM_COMMAND property as specified in the ICCCM. If +the window has not requested this message, the keyboard bell will be rung. +.IP "\fBf.separator\fP" 8 +Valid only in menus. The effect is to add a line separator between the +previous and the following entry. The name selector part in the menu is not +used (but must be present). +.IP "\fBf.setrealscreen\fP \fIgeomstr\fP" 8 +This function sets the real screen to the virtual coordinates specified. +The \fIgeomstr\fP is a quoted string containing a standard geometry +specification. +.IP "\fBf.showdesktopdisplay\fP" 8 +This function maps the desktop display. +.IP "\fBf.showiconmgr\fP" 8 +This function maps the current icon manager when selected from a client +window, and maps all icon managers when selected from the root window. +.IP "\fBf.snap\fP" 8 +This function snaps the real screen to a grid defined on virtual space with +\&\fBPanDistanceX\fP and \fBPanDistanceY\fP increments. +.IP "\fBf.snaprealscreen\fP" 8 +This function toggles the setting of \fBSnapRealScreen\fP. +.IP "\fBf.snugdesktop\fP" 8 +moves the display to try to fit all partially visible windows +completely on the screen. +.IP "\fBf.snugwindow\fP" 8 +moves the display to try to fit the selected window completely +on the screen +.IP "\fBf.sorticonmgr\fP" 8 +This function sorts the entries in the current icon manager alphabetically. +See the variable \fBSortIconManager\fP. +.IP "\fBf.sounds\fP" 8 +This function toggles the playing of sounds. It's a "mute" function. +.\".IP "\fBf.source\fP \fIstring\fP (DOES NOT WORK!!!)" 8 +.\"This function assumes \fIstring\fP is a file name. The file is read +.\"and parsed as a \fBvtwm\fP startup file. +.\"This function is intended to be used only to re-build pull-down menus. None +.\"of the \fBvtwm\fP variables are changed. +.IP "\fBf.squeezecenter\fP" 8 +.IP "\fBf.squeezeleft\fP" 8 +.IP "\fBf.squeezeright\fP" 8 +Selects a window and makes its title appear as though you had +configured it as +.RS 12 +.nf +\&\fBSqueezeTitle\fP center 0 0 +.fi +.RE +.RS +or +.RE +.RS 12 +.nf +\&\fBSqueezeTitle\fP left 0 0 +.fi +.RE +.RS +or +.RE +.RS 12 +.nf +\&\fBSqueezeTitle\fP right 0 0 +.fi +.RE +.RS +respectively. These make squeezed titles much more useful because their +configuration is dynamic. +.RE +.IP "\fBf.startwm\fP \fIcommandline\fP" 8 +This function kills \fBvtwm\fP, and starts up the window manager as specified +by \fIcommandline\fP. A trailing ampersand and/or environment variables should +not be used. See also \fBf.restart\fP. +.IP "\fBf.staticiconpositions\fP" 8 +This function toggles the setting of \fBStaticIconPositions\fP. +.IP "\fBf.stick\fP" 8 +This function is a synonym for \fBf.nail\fP. +.IP "\fBf.stickyabove\fP" 8 +This function is synonymous with the \fBf.nailedabove\fP function. +.IP "\fBf.stricticonmgr\fP" 8 +This function toggles the setting of \fBStrictIconManager\fP. +.IP "\fBf.title\fP" 8 +This function provides a centered, unselectable item in a menu definition. It +should not be used in any other context. +.IP "\fBf.topzoom\fP" 8 +This variable is similar to the \fBf.bottomzoom\fP function except that +the selected window is only resized to the top half of the display. +.IP "\fBf.twmrc\fP" 8 +Synonymous with \fBf.restart\fP. Historically, this function was intended +to cause the startup customization file to be re-read. +.IP "\fBf.unbindbuttons\fP" 8 +.IP "\fBf.unbindkeys\fP" 8 +These functions disable \fBvtwm\fP's pointer or keyboard bindings for the +selected window, allowing events to pass directly to the application. These +are useful, for example, when running another window manager within \fBXnest\fP +or \fBXvnc\fP. +.IP "\fBf.unfocus\fP" 8 +This function resets the focus back to pointer-driven. This should be used +when a focused window is no longer desired. +.IP "\fBf.upiconmgr\fP" 8 +This function warps the pointer to the previous row in the current icon +manager, wrapping to the last row in the same column if necessary. +.IP "\fBf.version\fP" 8 +This function causes the \fBvtwm\fP version window to be displayed. This +window will be displayed until a pointer button is pressed or the +pointer is moved from one window to another. +.IP "\fBf.virtualgeometries\fP" 8 +This function toggles the setting of \fBNotVirtualGeometries\fP. +.IP "\fBf.vlzoom\fP" 8 +This function is a synonym for \fBf.leftzoom\fP. +.IP "\fBf.vrzoom\fP" 8 +This function is a synonym for \fBf.rightzoom\fP. +.IP "\fBf.warp\fP" 8 +Warp the cursor to the selected window. This is only useful if the window +is selected via the icon manager. +.IP "\fBf.warpclassnext\fP \fIstring\fP" 8 +.IP "\fBf.warpclassprev\fP \fIstring\fP" 8 +These functions warp the pointer to the next or previous window in the +specified class indicated by the argument \fIstring\fP. If \fIstring\fP is +\&\fI"VTWM"\fP, only icon managers, doors, and the Virtual Desktop window are +considered. If \fIstring\fP empty (i.e., \fI""\fP), the class of the window +with focus is used. If the window is iconified, it will be deiconified if +the variable \fBWarpUnmapped\fP is set or else ignored. +.IP "\fBf.warpring\fP \fIstring\fP" 8 +This function warps the pointer to the next or previous window (as indicated +by the argument \fIstring\fP, which may be \fI"next"\fP or \fI"prev"\fP) +specified in the \fBWindowRing\fP variable. If the window is iconified, it +will be deiconified if the variable \fBWarpUnmapped\fP is set or else ignored. +.IP "\fBf.warpsnug\fP" 8 +This function toggles the setting of \fBWarpSnug\fP. +.IP "\fBf.warpto\fP \fIstring\fP" 8 +This function warps the pointer to the window which has a name or class +that matches \fIstring\fP. The \fIstring\fP may be a VTWM-style wildcard, but +not a \fIregular expression\fP (see the +.B WILDCARDS +section for details). +If the window is iconified, it will be deiconified if the \fBWarpUnmapped\fP +variable is set, or else ignored. +.IP "\fBf.warptoiconmgr\fP \fIstring\fP" 8 +This function warps the pointer to the icon manager entry associated with +the window containing the pointer in the icon manager specified by the +argument \fIstring\fP. If \fIstring\fP is empty (i.e., \fI""\fP), the +current icon manager is chosen. If the window is iconified, it will be +deiconified if the variable \fBWarpUnmapped\fP is set or else ignored. +.IP "\fBf.warptonewest\fP" 8 +This function warps the pointer to the most recently created window. +If the window is iconified, it will be deiconified if the variable +\&\fBWarpUnmapped\fP is set or else ignored. +.IP "\fBf.warptoscreen\fP \fIstring\fP" 8 +This function warps the pointer to the screen specified by the +argument \fIstring\fP. \fIString\fP may be a number (e.g., \fI"0"\fP or +\&\fI"1"\fP), the word \fI"next"\fP (indicating the current screen plus 1, +skipping over any unmanaged screens), +the word \fI"back"\fP (indicating the current screen minus 1, skipping over +any unmanaged screens), or the word +\&\fI"prev"\fP (indicating the last screen visited. +.IP "\fBf.warpvisible\fP" 8 +This function toggles the setting of \fBWarpVisible\fP. +.IP "\fBf.winrefresh\fP" 8 +This function is similar to the \fBf.refresh\fP function except that only the +selected window is refreshed. +.IP "\fBf.zoom\fP" 8 +This function is similar to the \fBf.fullzoom\fP function, except that +the only the height of the selected window is changed. +.IP "\fBf.zoomzoom\fP" 8 +This function makes a zoom outline from a random place to another random +place (see the \fBZoom\fP and \fBZoomZoom\fP variables). It's silly, but +can be used as a visual bell in place of \fBf.beep\fP. See also the +\&\fBLessRandomZoomZoom\fP variable. +.\"===================================================================== +.SH MENUS +.PP +Functions may be grouped and interactively selected using pop-up +(when bound to a pointer button) or pull-down (when associated +with a titlebar button) menus. Each menu specification contains the name of +the menu as it will be referred to by \fBf.menu\fP, optional default +foreground and background colors, the list of item names and the functions +they should invoke, and optional foreground and background colors for +individual items: +.RS 4 +.nf +\&\fBMenu\fP "\fImenuname\fP" [ ("\fIdeffore\fP":"\fIdefback\fP") ] +{ + \fIstring1\fP [ ("\fIfore1\fP":"\fIback1\fP")] \fIfunction1\fP + \fIstring2\fP [ ("\fIfore2\fP":"\fIback2\fP")] \fIfunction2\fP + ... + \fIstringN\fP [ ("\fIforeN\fP":"\fIbackN\fP")] \fIfunctionN\fP +} +.fi +.RE +.PP +The \fImenuname\fP is case-sensitive. +The optional \fIdeffore\fP and \fIdefback\fP arguments specify the foreground +and background colors used on a color display +to highlight menu entries. +The \fIstring\fP portion +of each menu entry will be the text which will appear in the menu. +The optional \fIfore\fP and \fIback\fP arguments specify the foreground +and background colors of the menu entry when the pointer is not in +the entry. These colors will only be used on a color display. The +default is to use the colors specified by the +\&\fBMenuForeground\fP and \fBMenuBackground\fP variables. +The \fIfunction\fP portion of the menu entry is one of the functions, +including any user-defined functions, or additional menus. +.PP +There is a special menu named \fBVTWM Windows\fP which contains the names of +all of the client and \fBvtwm\fP-supplied windows. Selecting an entry will +cause the \fBWindowFunction\fP to be executed on that window. +If \fBWindowFunction\fP hasn't been set, the window will be deiconified and +raised. This menu uses the same colors as the little windows in the panner. +This feature still honors the traditional \fBTwmWindows\fP menu name of yore. +.\"===================================================================== +.SH ICONS +\&\fBvtwm\fP supports several different ways of manipulating iconified windows. +The common image-and-text style may be laid out by hand or automatically +arranged as described by the \fBIconRegion\fP variable. In addition, a +terse grid of icon names, called an icon manager, provides a more efficient +use of screen space as well as the ability to navigate among windows from +the keyboard. +.PP +An icon manager is a window that contains names of selected or all +windows currently on the display. In addition to the window name, +a small button using the default iconify symbol will be displayed to the +left of the name when the window is iconified. By default, clicking on an +entry in the icon manager performs \fBf.iconify\fP. +To change the actions taken in the icon manager, use +the \fBiconmgr\fP context when specifying button and keyboard bindings. +.PP +Moving the pointer into the icon manager also directs keyboard focus to +the indicated window when \fBNoIconManagerFocus\fP is not set (setting the +focus explicitly or else sending synthetic events if \fBNoTitleFocus\fP is +set). +Using the \fBf.upiconmgr\fP, \fBf.downiconmgr\fP +\&\fBf.lefticonmgr\fP, and +\&\fBf.righticonmgr\fP functions, +the input focus can be changed between windows directly from the keyboard. +.\"===================================================================== +.SH IMAGE AND AUDIO FORMATS +\&\fBvtwm\fP supports many images on its own (referred to as "internal" or +"built-in" in this document), divided into two types, \fIbitmaps\fP and +\&\fIpixmaps\fP. They are differentiated from file images by either a colon +(':') or the string ":xpm:" as the first character(s) of the name, +respectively: +.RS 4 +.nf +\&\fB:darrow\fP scaled in any, n/a for highlight +\&\fB:delete\fP / \fB:xlogo\fP centered in any drawable +\&\fB:dot\fP / \fB:iconify\fP centered in any drawable +\&\fB:menu\fP scaled in any drawable +\&\fB:rarrow\fP scaled in any, n/a for highlight +\&\fB:resize\fP scaled in any drawable +.fi +.RE +.PP +.RS 4 +.nf +\&\fB:xpm:bar\fP scaled in any drawable +\&\fB:xpm:box\fP scaled in any drawable +\&\fB:xpm:darrow\fP scaled in any, n/a for highlight +\&\fB:xpm:dot\fP centered in any drawable +\&\fB:xpm:lines\fP scaled in any drawable +\&\fB:xpm:menu\fP scaled in any drawable +\&\fB:xpm:raisedbox\fP scaled, for highlight only +\&\fB:xpm:raisedlines\fP scaled, for highlight only +\&\fB:xpm:rarrow\fP scaled in any, n/a for highlight +\&\fB:xpm:resize\fP scaled in any drawable +\&\fB:xpm:sunkenbox\fP scaled, for highlight only +\&\fB:xpm:sunkenlines\fP scaled, for highlight only +\&\fB:xpm:zoom\fP scaled in any drawable +.fi +.RE +.PP +\&\fBvtwm\fP also supports a single image file format by default, the X Window +System bitmap (files typically carrying an extension of \fI".xbm"\fP), for +two-color images. However, when built with the XPM library, \fBvtwm\fP will +also support the X Window System pixmap (files typically carrying an extension +of \fI".xpm"\fP), for full-color images. +.PP +All image types and sources can be freely mixed within the variables that use +them, given the behavior listed above, and with the following additional +exceptions: The \fBIcons\fP and \fBUnknownIcon\fP variables don't recognize +the built-in images, the \fBRealScreenPixmap\fP, \fBTitleHighlight\fP, and +\&\fBVirtualBackgroundPixmap\fP entries of the \fBPixmaps\fP variable don't +recognize the built-in images, only titlebar buttons can accomodate external +images that would be larger than the default space allocated for them (in any +other case, the image will be cropped to fit), and only the \fBRealScreenPixmap\fP, +\&\fBTitleHighlight\fP, and \fBVirtualBackgroundPixmap\fP entries of the +\&\fBPixmaps\fP variable will tile small images into the space allocated for +them. +.PP +The icon manager drawable is hard-coded to 11x11 pixels, the menu drawable +is \fBMenuFont\fP pixels square, and titlebar buttons are +.RS 4 +.nf +(\fBTitleFont\fP - (2 * \fBButtonIndent\fP)) +.fi +.RE +pixels square. The titlebar highlight area is +.RS 4 +.nf +(\fItitlebar height\fP - (2 * \fBFramePadding\fP) - 2) +.fi +.RE +pixels high, where \fItitlebar height\fP is determined by \fBTitleFont\fP +or the titlebar button height, whichever is greater, and \fBFramePadding\fP. +.PP +The root window can be decorated with whatever image files that are +supported by X Window System utilities and applications (\fBxloadimage\fP(1), +\&\fBxsetroot\fP(1), \fBxv\fP(1), etc.). +.PP +If \fBvtwm\fP is built with sound support, several audio file formats +are supported, not by \fBvtwm\fP per se, but by the \fBrplayd\fP(8) daemon. +Currently, the AU, AIFF, WAV, and VOC formats are natively supported, but +see also \fBrplay.helpers\fP(5). +.\"===================================================================== +.SH WILDCARDS +\&\fBvtwm\fP supports "wildcarding" when matching windows against a +variable's \fIwin-list\fP. By default, the question mark ('?') represents +any single character, the asterisk ('*') represents any zero or more +characters, and brackets ('[' and ']') represent any characters listed +within them. The backslash ('\\') "escapes" any one character, allowing +these reserved characters to be used literally. +.PP +\&\fBvtwm\fP can support a richer method of character substitution, called +\&\fIregular expressions\fP, or \fI"RE"\fPs. If \fBvtwm\fP is built with REs, +many more "wildcard" rules are added. A description of REs is beyond the +scope of this document; see the \fBre_format\fP(7) or \fBegrep\fP(1) man +pages. +.PP +\&\fBvtwm\fP distinguishes REs from strings by enclosing them in forward +slashes ('/'). The two may be freely mixed; changing the example in the +.B VARIABLES +section to: +.RS 4 +.nf +\&\fBAutoRaise\fP +{ + "emacs" + "VTWM*" + /x.*clock/ # was "x*clock" + "Xmh" + "XTerm" +} +.fi +.RE +accomplishes the same thing. This is but a simple example of RE usage, +and as such doesn't demonstrate or leverage their capabilities. +.\"===================================================================== +.SH SIGNALS +It is possible to issue a \fBf.restart\fP via a UNIX signal, to ease +debugging of \fBvtwm\fP resource files. To do this, send a SIGUSR1 to the +\&\fBvtwm\fP process ID (written to \fI$HOME/vtwm.pid\fP). +See \fBkill\fP(1) or \fBslay\fP(1). +.\"===================================================================== +.SH BUGS +There are precious few safeguards against binding functions to objects +inappropriately, especially where the virtual desktop is concerned. +.PP +Double clicking very fast to get the constrained move function will sometimes +cause the window to move, even though the pointer is not moved. +.PP +It is possible to "lose" windows in the virtual desktop by placing them +in a large desktop area, then shrinking the desktop so as to remove them +from view. They are still there, of course, but are unreachable until the +desktop is grown sufficiently large again. +.PP +See the \fIBUGS\fP file in the distribution for others. +.\"===================================================================== +.SH FILES +.PP +Searched for in the order shown: +.RS 4 +.nf +\&\fI$HOME/.vtwmrc.\fP +\&\fI$HOME/.vtwmrc\fP +\&\fI$VTWMDIR/twm/system.vtwmrc\fP +\&\fI$HOME/.twmrc.\fP +\&\fI$HOME/.twmrc\fP +\&\fI$VTWMDIR/twm/system.twmrc\fP +.fi +.RE +.PP +.nf +\&\fI$HOME/vtwm.pid\fP +.fi +.\"===================================================================== +.SH "ENVIRONMENT VARIABLES" +.IP "\fBDISPLAY\fP" 8 +This variable is used to determine which X server to use. It is also set +during \fBf.exec\fP so that programs come up on the proper screen. +.IP "\fBHOME\fP" 8 +This variable is used as the prefix for files that begin with a tilde and +for locating the \fBvtwm\fP startup file. +.\"===================================================================== +.SH "SEE ALSO" +\&\fBbitmap\fP(5), +\&\fBctwm\fP(1), +\&\fBm4\fP(1), +\&\fBmwm\fP(1), +\&\fBpixmap\fP(5), +\&\fBre_format\fP(7) or \fBegrep\fP(1), +\&\fBrplayd\fP(8) and \fBrplay.helpers\fP(5), +\&\fBtvtwm\fP(1), +\&\fBtwm\fP(1), +\&\fBvuewm\fP(1), +\&\fBX\fP(1), +\&\fBxdm\fP(1), +\&\fBxinit\fP(1), +\&\fBxmodmap\fP(1), +\&\fBxrdb\fP(1), +\&\fBXserver\fP(1) +.\"===================================================================== +.SH COPYRIGHT +Portions copyright 1988 Evans & Sutherland Computer Corporation; portions +copyright 1989 Hewlett-Packard Company and the Massachusetts Institute of +Technology; portions copyright 2001 D. J. Hawkey Jr.. +.PP +See \fBX\fP(1) for a full statement of rights and permissions. +.\"===================================================================== +.SH AUTHORS AND CONTRIBUTORS +Tom LaStrange, Solbourne Computer; Jim Fulton, MIT X Consortium; +Steve Pitschke, Stardent Computer; Keith Packard, MIT X Consortium; +Dave Payne, Apple Computer; Nick Williams ; +Dave Edmondson, Santa Cruz Operation, ; +Dana Chee, Bellcore (R5 conversion), ; +Warren Jessop, University of Washington, ; +Gilligan ; +Tim Ramsey ; +Ralph Betza ; +Michael Kutzner ; +Stig Ostholm ; +M. Eyckmans ; +Tony Brannigan ; +Alec Wolman ; +; +Marcel Mol ; +Darren S. Embry ; +Chris P. Ross ; +Paul Falstad ; +D. J. Hawkey Jr., (version 5.4), , +with +Erik Agsjo , +Ugen Antsilevitch , +Nelson H. F. Beebe , +Michael Dales , +Jennifer Elaan , +Michel Eyckmans , +Callum Gibson , +Jason Gloudon , +Nicholas Jacobs , +Caveh Frank Jalali +Takeharu Kato , +Goran Larsson , +Rolf Neugebauer , +Jonathan Paisley , +Steve Ratcliffe , +Seth Robertson , +Mehul N. Sanghvi , +Tim Wiess , +acknowledging +Claude Lecommandeur, (ctwm), +.\"==============================[The End]============================== diff --git a/doors.c b/doors.c new file mode 100644 index 0000000..79f1d73 --- /dev/null +++ b/doors.c @@ -0,0 +1,458 @@ +/* + * $Id: doors.c,v 3.0 90/11/20 16:13:17 dme Exp Locker: dme $ + * + * Copyright (c) 1990 Dave Edmondson. + * Copyright (c) 1990 Imperial College of Science, Technoology & Medicine + * All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Dave Edmondson or Imperial College + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Dave Edmondson and + * Imperial College make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#include +#include +#include "doors.h" +#include "screen.h" +#include "desktop.h" +#include "add_window.h" + +#define strdup Strdup /* avoid conflict with system header files */ +char *strdup(s1) +char * s1; +{ + char *s2; + + s2 = malloc((unsigned) strlen(s1)+1); + return (s2 == NULL ? NULL : strcpy(s2,s1)); +} + +extern void SetMapStateProp(); +extern TwmDoor *door_add_internal(); +extern void twmrc_error_prefix(); + +/* djhjr - 4/20/98 */ +extern void HandleExpose(); +extern void SetupWindow(); + +/* djhjr - 4/27/99 */ +extern void AppletDown(); + +TwmDoor *door_add(name, position, destination) +char *name, *position, *destination; +{ + int px, py, pw, ph, dx, dy; + + /* djhjr - 4/26/96 */ +/* djhjr - 8/11/98 + * was 'Scr->use3Dborders' - djhjr - 8/11/98 * + int bw = (Scr->BorderBevelWidth > 0) ? Scr->ThreeDBorderWidth : Scr->BorderWidth; +*/ + int bw = Scr->BorderWidth; + + JunkMask = XParseGeometry (position, &JunkX, &JunkY, + &JunkWidth, &JunkHeight); + + /* we have some checking for negative (x,y) to do + sorta taken from desktop.c by DSE */ + if ((JunkMask & XNegative) == XNegative) { + JunkX += Scr->MyDisplayWidth - JunkWidth - (2 * bw); + } + if ((JunkMask & YNegative) == YNegative) { + JunkY += Scr->MyDisplayHeight - JunkHeight - (2 * bw); + } + +/* allow position to be omitted - djhjr - 5/10/99 + if ((JunkMask & (XValue | YValue)) != + (XValue | YValue)) { + twmrc_error_prefix(); + fprintf (stderr, "bad Door position \"%s\"\n", position); + return NULL; + } +*/ + + /* added this 'if (...) else' - djhjr - 5/10/99 */ + if ((JunkMask & (XValue | YValue)) != (XValue | YValue)) + { + /* allow AddWindow() to position it - djhjr - 5/10/99 */ + JunkX = JunkY = -1; + } + else + { +/* if (JunkX <= 0 || JunkY <= 0) { */ + if (JunkX < 0 || JunkY < 0) { /* 0,0 accepted now -- DSE */ + twmrc_error_prefix(); + fprintf (stderr, "silly Door position \"%s\"\n", position); + return NULL; + } + } + + /* they seemed ok */ + px = JunkX; + py = JunkY; + + if (JunkMask & WidthValue) + pw = JunkWidth; + else + /* means figure it out when you create the window */ + pw = -1; + if (JunkMask & HeightValue) + ph = JunkHeight; + else + ph = -1; + + JunkMask = XParseGeometry (destination, &JunkX, &JunkY, + &JunkWidth, &JunkHeight); + if ((JunkMask & (XValue | YValue)) != + (XValue | YValue)) { + twmrc_error_prefix(); + fprintf (stderr, "bad Door destination \"%s\"\n", destination); + return NULL; + } + if (JunkX < 0 || JunkY < 0) { + twmrc_error_prefix(); + fprintf (stderr, "silly Door destination \"%s\"\n", + destination); + return NULL; + } + dx = JunkX; + dy = JunkY; + + return (door_add_internal(name, px, py, pw, ph, dx, dy)); +} + +TwmDoor *door_add_internal(name, px, py, pw, ph, dx, dy) +char *name; +int px, py, pw, ph, dx, dy; +{ + TwmDoor *new; + + new = (TwmDoor *)malloc(sizeof(TwmDoor)); + new->name = strdup(name); + + /* this for getting colors */ + new->class = XAllocClassHint(); + new->class->res_name = new->name; + new->class->res_class = strdup(VTWM_DOOR_CLASS); + + new->x = px; + new->y = py; + new->width = pw; + new->height = ph; + new->goto_x = dx; + new->goto_y = dy; + + /* link into the list */ + new->prev = NULL; + new->next = Scr->Doors; + if (Scr->Doors) + Scr->Doors->prev = new; + Scr->Doors = new; + + return (new); +} + +void door_open(tmp_door) +TwmDoor *tmp_door; +{ + Window w; + + /* djhjr - 4/26/96 */ +/* djhjr - 8/11/98 + * was 'Scr->use3Dborders' - djhjr - 8/11/98 * + int bw = (Scr->BorderBevelWidth > 0) ? Scr->ThreeDBorderWidth : Scr->BorderWidth; +*/ + int bw = Scr->BorderWidth; + + /* look up colours */ + if (!GetColorFromList(Scr->DoorForegroundL, + tmp_door->name, + tmp_door->class, &tmp_door->colors.fore)) + tmp_door->colors.fore = Scr->DoorC.fore; + if (!GetColorFromList(Scr->DoorBackgroundL, + tmp_door->name, + tmp_door->class, &tmp_door->colors.back)) + tmp_door->colors.back = Scr->DoorC.back; + + if (tmp_door->width < 0) +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + tmp_door->width = MyFont_TextWidth(&Scr->DoorFont, +#else + tmp_door->width = XTextWidth(Scr->DoorFont.font, +#endif + tmp_door->name, + strlen(tmp_door->name)) + + /* djhjr - 2/7/99 */ + + (Scr->DoorBevelWidth * 2) + + + SIZE_HINDENT; + + if (tmp_door->height < 0) + tmp_door->height = Scr->DoorFont.height + + /* djhjr - 2/7/99 */ + + (Scr->DoorBevelWidth * 2) + + + SIZE_VINDENT; + + /* create the window */ + w = XCreateSimpleWindow(dpy, Scr->Root, + tmp_door->x, tmp_door->y, + tmp_door->width, tmp_door->height, + bw, + tmp_door->colors.fore, + tmp_door->colors.back); + tmp_door->w = XCreateSimpleWindow(dpy, w, + 0, 0, + tmp_door->width, tmp_door->height, + 0, + tmp_door->colors.fore, + tmp_door->colors.back); + +/* reworked to limit the minimum size of a door - djhjr - 3/1/99 + if ((tmp_door->x < 0) || (tmp_door->y < 0)) { + XSizeHints *hints = NULL; + long ret; + + * + * set the wmhints so that add_window() will allow + * the user to place the window + * + if (XGetWMNormalHints(dpy, w, hints, &ret) > 0) { + hints->flags = hints->flags & + (!USPosition & !PPosition); + XSetStandardProperties(dpy, w, + tmp_door->class->res_name, + tmp_door->class->res_name, + None, NULL, 0, hints); + } + } else { + XSetStandardProperties(dpy, w, + tmp_door->class->res_name, + tmp_door->class->res_name, + None, NULL, 0, NULL); + } +*/ + { + XSizeHints *hints = NULL; + + if (tmp_door->x < 0 || tmp_door->y < 0) + { + long ret; + + /* + * set the wmhints so that add_window() will allow + * the user to place the window + */ + if (XGetWMNormalHints(dpy, w, hints, &ret) != 0) + hints->flags &= (!USPosition & !PPosition); + } + + if (!hints) hints = XAllocSizeHints(); + + hints->flags |= PMinSize; + hints->min_width = tmp_door->width; + hints->min_height = tmp_door->height; + + XSetStandardProperties(dpy, w, + tmp_door->class->res_name, + tmp_door->class->res_name, + None, NULL, 0, hints); + } + + XSetClassHint(dpy, w, tmp_door->class); + + /* set the name on both */ + XStoreName(dpy, tmp_door->w, tmp_door->name); + XStoreName(dpy, w, tmp_door->name); + + XDefineCursor( dpy, w, Scr->FrameCursor );/*RFB*/ + XDefineCursor( dpy, tmp_door->w, Scr->DoorCursor );/*RFBCURSOR*/ + + /* moved these 'cuz AddWindow() will need 'em - djhjr - 11/15/01 */ + /* store the address of the door on the window */ + XSaveContext(dpy, + tmp_door->w, DoorContext, (caddr_t) tmp_door); + XSaveContext(dpy, + w, DoorContext, (caddr_t) tmp_door); + + /* give to twm */ + tmp_door->twin = AddWindow(w, FALSE, NULL); + + SetMapStateProp(tmp_door->twin, NormalState); + + /* interested in... */ + XSelectInput(dpy, tmp_door->w, ExposureMask | + ButtonPressMask | ButtonReleaseMask); + + /* store the address of the door on the window */ + XSaveContext(dpy, + tmp_door->w, + TwmContext, (caddr_t) tmp_door->twin); + + /* map it */ + XMapWindow(dpy, tmp_door->w); + XMapWindow(dpy, w); +} + +void door_open_all() +{ + TwmDoor *tmp_door; + + for (tmp_door = Scr->Doors; tmp_door; tmp_door = tmp_door->next) + door_open(tmp_door); +} + +/* + * go into a door + */ +void door_enter(w, d) +Window w; +TwmDoor *d; +{ + int snapon; /* doors override real screen snapping - djhjr - 2/5/99 */ + + if (!d) + /* find the door */ + if (XFindContext(dpy, w, DoorContext, (caddr_t *)&d) + == XCNOENT) + /* not a door ! */ + return; + + /* go to it */ + snapon = (int)Scr->snapRealScreen; + Scr->snapRealScreen = FALSE; + SetRealScreen(d->goto_x, d->goto_y); + Scr->snapRealScreen = (snapon) ? TRUE : FALSE; +} + +/* + * delete a door + */ +void door_delete(w, d) +Window w; +TwmDoor *d; +{ /*marcel@duteca.et.tudelft.nl*/ + if (!d) + /* find the door */ + if (XFindContext(dpy, w, DoorContext, (caddr_t *)&d) + == XCNOENT) + /* not a door ! */ + return; + + /* unlink it: */ + if (Scr->Doors == d) + Scr->Doors = d->next; + if (d->prev != NULL) + d->prev->next = d->next; + if (d->next != NULL) + d->next->prev = d->prev; + + /* djhjr - 4/27/99 */ + AppletDown(d->twin); + +/* + * Must this be done here ? Is it do by XDestroyWindow(), + * or by HandleDestroyNotify() in events.c, or should it + * it be done there ? M.J.E. Mol. + * + * It looks as though the contexts, at least, should be + * deleted here, maybe more, I dunno. - djhjr 2/25/99 + */ + XDeleteContext(dpy, d->w, DoorContext); + XDeleteContext(dpy, d->w, TwmContext); + XDeleteContext(dpy, d->twin->w, DoorContext); /* ??? */ + XUnmapWindow(dpy, d->w); + XUnmapWindow(dpy, w); + XDestroyWindow(dpy, w); + free(d->class->res_class); /* djhjr - 2/25/99 */ + XFree(d->class); + free(d->name); /* djhjr - 2/25/99 */ + free(d); +} + +/* + * create a new door on the fly + */ +void door_new() +{ + TwmDoor *d; + char name[256]; + + sprintf(name, "+%d+%d", Scr->VirtualDesktopX, Scr->VirtualDesktopY); + + d = door_add_internal(name, -1, -1, -1, -1, + Scr->VirtualDesktopX, Scr->VirtualDesktopY); + + door_open(d); +} + +/* + * rename a door from cut buffer 0 + * + * adapted from VTWM-5.2b - djhjr - 4/20/98 + */ +void +door_paste_name(w, d) +Window w; +TwmDoor* d; +{ + int width, height, count; + char *ptr; +/* djhjr - 8/11/98 + * was 'Scr->use3Dborders' - djhjr - 8/11/98 * + int bw = (Scr->BorderBevelWidth > 0) ? Scr->ThreeDBorderWidth : Scr->BorderWidth; +*/ + /* added initialization and test - djhjr - 3/1/99 */ + int bw = 0; + if (Scr->BorderBevelWidth) bw = Scr->BorderWidth; + + if (!d) + if (XFindContext(dpy, w, DoorContext, (caddr_t *)&d) == XCNOENT) + return; + + /* sanity check - djhjr - 10/31/00 */ + if (!(ptr = XFetchBytes(dpy, &count)) || count == 0) return; + if (count > 128) count = 128; + + if (d->name) + d->name = realloc(d->name, count + 1); + else + d->name = malloc(count + 1); + + sprintf(d->name, "%*s", count, ptr); + XFree(ptr); + + /* djhjr - 1/14/99 */ + XClearWindow(dpy, d->w); + + /* added 'Scr->DoorBevelWidth * 2' - djhjr - 2/7/99 */ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + width = MyFont_TextWidth(&Scr->DoorFont, d->name, count) + +#else + width = XTextWidth(Scr->DoorFont.font, d->name, count) + +#endif + SIZE_HINDENT + (Scr->DoorBevelWidth * 2); + height = Scr->DoorFont.height + SIZE_VINDENT + (Scr->DoorBevelWidth * 2); + + /* limit the size of a door - djhjr - 3/1/99 */ + d->twin->hints.flags |= PMinSize; + d->twin->hints.min_width = width; + d->twin->hints.min_height = height; + + SetupWindow(d->twin, d->twin->frame_x, d->twin->frame_y, + width + 2 * bw, height + d->twin->title_height + 2 * bw, -1); + + HandleExpose(); +} + diff --git a/doors.h b/doors.h new file mode 100644 index 0000000..63c53fe --- /dev/null +++ b/doors.h @@ -0,0 +1,62 @@ +/* + * $Id: doors.h,v 3.0 90/11/20 16:13:19 dme Exp Locker: dme $ + * + * Copyright (c) 1990 Dave Edmondson. + * Copyright (c) 1990 Imperial College of Science, Technoology & Medicine + * All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Dave Edmondson or Imperial College + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Dave Edmondson and + * Imperial College make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#ifndef DOORS_H_INCLUDED +#define DOORS_H_INCLUDED + +#include "twm.h" + +/* the class of twm doors */ +/* djhjr - 4/27/96 +#define TWM_DOOR_CLASS "Twm Door" +*/ +#define VTWM_DOOR_CLASS "VTWM Door" + +/* + * the door structure + */ +typedef struct TwmDoor { + struct TwmDoor *next; /* next in the linked list */ + struct TwmDoor *prev; /* prev in the linked list */ + + char *name; /* name of this door */ + int x, y; /* position */ + int width, height; /* size */ + + int goto_x, goto_y; /* destination */ + + XClassHint *class; /* name and class of this door */ + + ColorPair colors; /* fore and back */ + + Window w; /* the x window for this */ + TwmWindow *twin; /* the twmwindow for this */ +} TwmDoor; + +extern TwmDoor *door_add(); +extern void door_open(); +extern void door_open_all(); +extern void door_enter(); +extern void door_new(); +extern void door_delete(); + +/* djhjr - 4/20/98 */ +extern void door_paste_name(); + +#endif /* DOORS_H_INCLUDED */ diff --git a/events.c b/events.c new file mode 100644 index 0000000..28e1e29 --- /dev/null +++ b/events.c @@ -0,0 +1,4171 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/*********************************************************************** + * + * $XConsortium: events.c,v 1.182 91/07/17 13:59:14 dave Exp $ + * + * twm event handling + * + * 17-Nov-87 Thomas E. LaStrange File created + * + ***********************************************************************/ + +#include +#include +#include "twm.h" +#include +#include "add_window.h" +#include "menus.h" +#include "events.h" +#include "resize.h" +#include "parse.h" +#include "gram.h" +#include "util.h" +#include "screen.h" +#include "iconmgr.h" +#include "version.h" +#include "desktop.h" +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT +#include "sound.h" +#endif +/* Submitted by Takeharu Kato */ +#ifdef NEED_SELECT_H +#include /* RAISEDELAY */ +#else +#include /* RAISEDELAY */ +#include /* RAISEDELAY */ +#include +#endif + +extern void IconDown(); +/* djhjr - 4/26/99 */ +extern void AppletDown(); + +static void do_menu (); +void RedoIconName(); + +extern int iconifybox_width, iconifybox_height; +extern unsigned int mods_used; +extern int menuFromFrameOrWindowOrTitlebar; +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT +extern int createSoundFromFunction; +extern int destroySoundFromFunction; +#endif + +#define MAX_X_EVENT 256 +event_proc EventHandler[MAX_X_EVENT]; /* event handler jump table */ +char *Action; +int Context = C_NO_CONTEXT; /* current button press context */ +TwmWindow *ButtonWindow; /* button press window structure */ +XEvent ButtonEvent; /* button press event */ +XEvent Event; /* the current event */ +TwmWindow *Tmp_win; /* the current twm window */ + +/* Used in HandleEnterNotify to remove border highlight from a window + * that has not recieved a LeaveNotify event because of a pointer grab + */ +TwmWindow *UnHighLight_win = NULL; + +Window DragWindow; /* variables used in moving windows */ +int origDragX; +int origDragY; +int DragX; +int DragY; +int DragWidth; +int DragHeight; +int CurrentDragX; +int CurrentDragY; + +/* Vars to tell if the resize has moved. */ +extern int ResizeOrigX; +extern int ResizeOrigY; + +static int enter_flag; +static int ColortableThrashing; +static TwmWindow *enter_win, *raise_win; + +ScreenInfo *FindScreenInfo(); +int ButtonPressed = -1; +int Cancel = FALSE; +int GlobalFirstTime = True; +int GlobalMenuButton = False; + +void HandleCreateNotify(); + +void HandleShapeNotify (); +extern int ShapeEventBase, ShapeErrorBase; + +void AutoRaiseWindow (tmp) + TwmWindow *tmp; +{ + XRaiseWindow (dpy, tmp->frame); + XRaiseWindow (dpy, tmp->VirtualDesktopDisplayWindow); + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + + XSync (dpy, 0); + enter_win = NULL; + enter_flag = TRUE; + raise_win = tmp; +} + +void SetRaiseWindow (tmp) + TwmWindow *tmp; +{ + enter_flag = TRUE; + enter_win = NULL; + raise_win = tmp; + XSync (dpy, 0); +} + + + +/*********************************************************************** + * + * Procedure: + * InitEvents - initialize the event jump table + * + *********************************************************************** + */ + +void +InitEvents() +{ + int i; + + + ResizeWindow = 0; + DragWindow = 0; + enter_flag = FALSE; + enter_win = raise_win = NULL; + + for (i = 0; i < MAX_X_EVENT; i++) + EventHandler[i] = HandleUnknown; + + EventHandler[Expose] = HandleExpose; + EventHandler[CreateNotify] = HandleCreateNotify; + EventHandler[DestroyNotify] = HandleDestroyNotify; + EventHandler[MapRequest] = HandleMapRequest; + EventHandler[MapNotify] = HandleMapNotify; + EventHandler[UnmapNotify] = HandleUnmapNotify; +#if 0 /* functionality moved to menus.c:ExecuteFunction() - djhjr - 11/7/03 */ + EventHandler[MotionNotify] = HandleMotionNotify; +#endif + EventHandler[ButtonRelease] = HandleButtonRelease; + EventHandler[ButtonPress] = HandleButtonPress; + EventHandler[EnterNotify] = HandleEnterNotify; + EventHandler[LeaveNotify] = HandleLeaveNotify; + EventHandler[ConfigureRequest] = HandleConfigureRequest; + EventHandler[ClientMessage] = HandleClientMessage; + EventHandler[PropertyNotify] = HandlePropertyNotify; + EventHandler[KeyPress] = HandleKeyPress; + EventHandler[ColormapNotify] = HandleColormapNotify; + EventHandler[VisibilityNotify] = HandleVisibilityNotify; + if (HasShape) + EventHandler[ShapeEventBase+ShapeNotify] = HandleShapeNotify; +} + + + + +Time lastTimestamp = CurrentTime; /* until Xlib does this for us */ + +Bool StashEventTime (ev) + register XEvent *ev; +{ + switch (ev->type) { + case KeyPress: + case KeyRelease: + lastTimestamp = ev->xkey.time; + return True; + case ButtonPress: + case ButtonRelease: + lastTimestamp = ev->xbutton.time; + return True; + case MotionNotify: + lastTimestamp = ev->xmotion.time; + return True; + case EnterNotify: + case LeaveNotify: + lastTimestamp = ev->xcrossing.time; + return True; + case PropertyNotify: + lastTimestamp = ev->xproperty.time; + return True; + case SelectionClear: + lastTimestamp = ev->xselectionclear.time; + return True; + case SelectionRequest: + lastTimestamp = ev->xselectionrequest.time; + return True; + case SelectionNotify: + lastTimestamp = ev->xselection.time; + return True; + } + return False; +} + + + +/* + * WindowOfEvent - return the window about which this event is concerned; this + * window may not be the same as XEvent.xany.window (the first window listed + * in the structure). + */ +Window WindowOfEvent (e) + XEvent *e; +{ + /* + * Each window subfield is marked with whether or not it is the same as + * XEvent.xany.window or is different (which is the case for some of the + * notify events). + */ + switch (e->type) { + case KeyPress: + case KeyRelease: return e->xkey.window; /* same */ + case ButtonPress: + case ButtonRelease: return e->xbutton.window; /* same */ + case MotionNotify: return e->xmotion.window; /* same */ + case EnterNotify: + case LeaveNotify: return e->xcrossing.window; /* same */ + case FocusIn: + case FocusOut: return e->xfocus.window; /* same */ + case KeymapNotify: return e->xkeymap.window; /* same */ + case Expose: return e->xexpose.window; /* same */ + case GraphicsExpose: return e->xgraphicsexpose.drawable; /* same */ + case NoExpose: return e->xnoexpose.drawable; /* same */ + case VisibilityNotify: return e->xvisibility.window; /* same */ + case CreateNotify: return e->xcreatewindow.window; /* DIFF */ + case DestroyNotify: return e->xdestroywindow.window; /* DIFF */ + case UnmapNotify: return e->xunmap.window; /* DIFF */ + case MapNotify: return e->xmap.window; /* DIFF */ + case MapRequest: return e->xmaprequest.window; /* DIFF */ + case ReparentNotify: return e->xreparent.window; /* DIFF */ + case ConfigureNotify: return e->xconfigure.window; /* DIFF */ + case ConfigureRequest: return e->xconfigurerequest.window; /* DIFF */ + case GravityNotify: return e->xgravity.window; /* DIFF */ + case ResizeRequest: return e->xresizerequest.window; /* same */ + case CirculateNotify: return e->xcirculate.window; /* DIFF */ + case CirculateRequest: return e->xcirculaterequest.window; /* DIFF */ + case PropertyNotify: return e->xproperty.window; /* same */ + case SelectionClear: return e->xselectionclear.window; /* same */ + case SelectionRequest: return e->xselectionrequest.requestor; /* DIFF */ + case SelectionNotify: return e->xselection.requestor; /* same */ + case ColormapNotify: return e->xcolormap.window; /* same */ + case ClientMessage: return e->xclient.window; /* same */ + case MappingNotify: return None; + } + return None; +} + + + +/*********************************************************************** + * + * Procedure: + * DispatchEvent2 - + * handle a single X event stored in global var Event + * this routine for is for a call during an f.move + * + **********************************************************************/ +/* + * Merged into DispatchEvent() + * djhjr - 10/6/02 + */ +#if 0 +Bool DispatchEvent2 () +{ + Window w = Event.xany.window; + StashEventTime (&Event); + + if (XFindContext (dpy, w, TwmContext, (caddr_t *) &Tmp_win) == XCNOENT) + Tmp_win = NULL; + + if (XFindContext (dpy, w, ScreenContext, (caddr_t *)&Scr) == XCNOENT) { + Scr = FindScreenInfo (WindowOfEvent (&Event)); + } + + if (!Scr) return False; + + if (menuFromFrameOrWindowOrTitlebar && Event.type == Expose) + HandleExpose(); + + if (!menuFromFrameOrWindowOrTitlebar && Event.type>= 0 && Event.type < MAX_X_EVENT) { + (*EventHandler[Event.type])(); + } + + return True; +} +#endif + +/*********************************************************************** + * + * Procedure: + * DispatchEvent - handle a single X event stored in global var Event + * + *********************************************************************** + */ +Bool DispatchEvent () +{ + Window w = Event.xany.window; + StashEventTime (&Event); + + if (XFindContext (dpy, w, TwmContext, (caddr_t *) &Tmp_win) == XCNOENT) + Tmp_win = NULL; + + if (XFindContext (dpy, w, ScreenContext, (caddr_t *)&Scr) == XCNOENT) + Scr = FindScreenInfo (WindowOfEvent (&Event)); + + if (!Scr) return False; + + if (MoveFunction != F_NOFUNCTION && menuFromFrameOrWindowOrTitlebar) + { + if (Event.type == Expose) + HandleExpose(); + } + else if (Event.type >= 0 && Event.type < MAX_X_EVENT) + (*EventHandler[Event.type])(); + + return True; +} + + + +/*********************************************************************** + * + * Procedure: + * HandleEvents - handle X events + * + *********************************************************************** + */ + +void +HandleEvents() +{ + while (TRUE) + { + if (enter_flag && !QLength(dpy)) { + if (enter_win && enter_win != raise_win) { + AutoRaiseWindow (enter_win); /* sets enter_flag T */ + } else { + enter_flag = FALSE; + } + } + if (ColortableThrashing && !QLength(dpy) && Scr) { + InstallWindowColormaps(ColormapNotify, (TwmWindow *) NULL); + } + WindowMoved = FALSE; + XNextEvent(dpy, &Event); + (void) DispatchEvent (); + } +} + + + +/*********************************************************************** + * + * Procedure: + * HandleColormapNotify - colormap notify event handler + * + * This procedure handles both a client changing its own colormap, and + * a client explicitly installing its colormap itself (only the window + * manager should do that, so we must set it correctly). + * + *********************************************************************** + */ + +void +HandleColormapNotify() +{ + XColormapEvent *cevent = (XColormapEvent *) &Event; + ColormapWindow *cwin, **cwins; + TwmColormap *cmap; + int lost, won, n, number_cwins; + extern TwmColormap *CreateTwmColormap(); + + if (XFindContext(dpy, cevent->window, ColormapContext, (caddr_t *)&cwin) == XCNOENT) + return; + cmap = cwin->colormap; + + if (cevent->new) + { + if (XFindContext(dpy, cevent->colormap, ColormapContext, + (caddr_t *)&cwin->colormap) == XCNOENT) + cwin->colormap = CreateTwmColormap(cevent->colormap); + else + cwin->colormap->refcnt++; + + cmap->refcnt--; + + if (cevent->state == ColormapUninstalled) + cmap->state &= ~CM_INSTALLED; + else + cmap->state |= CM_INSTALLED; + + if (cmap->state & CM_INSTALLABLE) + InstallWindowColormaps(ColormapNotify, (TwmWindow *) NULL); + + if (cmap->refcnt == 0) + { + XDeleteContext(dpy, cmap->c, ColormapContext); + free((char *) cmap); + } + + return; + } + + if (cevent->state == ColormapUninstalled && + (cmap->state & CM_INSTALLABLE)) + { + if (!(cmap->state & CM_INSTALLED)) + return; + cmap->state &= ~CM_INSTALLED; + + if (!ColortableThrashing) + { + ColortableThrashing = TRUE; + XSync(dpy, 0); + } + + if (cevent->serial >= Scr->cmapInfo.first_req) + { + number_cwins = Scr->cmapInfo.cmaps->number_cwins; + + /* + * Find out which colortables collided. + */ + + cwins = Scr->cmapInfo.cmaps->cwins; + for (lost = won = -1, n = 0; + (lost == -1 || won == -1) && n < number_cwins; + n++) + { + if (lost == -1 && cwins[n] == cwin) + { + lost = n; /* This is the window which lost its colormap */ + continue; + } + + if (won == -1 && + cwins[n]->colormap->install_req == cevent->serial) + { + won = n; /* This is the window whose colormap caused */ + continue; /* the de-install of the previous colormap */ + } + } + + /* + ** Cases are: + ** Both the request and the window were found: + ** One of the installs made honoring the WM_COLORMAP + ** property caused another of the colormaps to be + ** de-installed, just mark the scoreboard. + ** + ** Only the request was found: + ** One of the installs made honoring the WM_COLORMAP + ** property caused a window not in the WM_COLORMAP + ** list to lose its map. This happens when the map + ** it is losing is one which is trying to be installed, + ** but is getting getting de-installed by another map + ** in this case, we'll get a scoreable event later, + ** this one is meaningless. + ** + ** Neither the request nor the window was found: + ** Somebody called installcolormap, but it doesn't + ** affect the WM_COLORMAP windows. This case will + ** probably never occur. + ** + ** Only the window was found: + ** One of the WM_COLORMAP windows lost its colormap + ** but it wasn't one of the requests known. This is + ** probably because someone did an "InstallColormap". + ** The colormap policy is "enforced" by re-installing + ** the colormaps which are believed to be correct. + */ + + if (won != -1) + if (lost != -1) + { + /* lower diagonal index calculation */ + if (lost > won) + n = lost*(lost-1)/2 + won; + else + n = won*(won-1)/2 + lost; + Scr->cmapInfo.cmaps->scoreboard[n] = 1; + } else + { + /* + ** One of the cwin installs caused one of the cwin + ** colormaps to be de-installed, so I'm sure to get an + ** UninstallNotify for the cwin I know about later. + ** I haven't got it yet, or the test of CM_INSTALLED + ** above would have failed. Turning the CM_INSTALLED + ** bit back on makes sure we get back here to score + ** the collision. + */ + cmap->state |= CM_INSTALLED; + } + else if (lost != -1) + InstallWindowColormaps(ColormapNotify, (TwmWindow *) NULL); + } + } + + else if (cevent->state == ColormapUninstalled) + cmap->state &= ~CM_INSTALLED; + + else if (cevent->state == ColormapInstalled) + cmap->state |= CM_INSTALLED; +} + + + +/*********************************************************************** + * + * Procedure: + * HandleVisibilityNotify - visibility notify event handler + * + * This routine keeps track of visibility events so that colormap + * installation can keep the maximum number of useful colormaps + * installed at one time. + * + *********************************************************************** + */ + +void +HandleVisibilityNotify() +{ + XVisibilityEvent *vevent = (XVisibilityEvent *) &Event; + ColormapWindow *cwin; + TwmColormap *cmap; + + if (XFindContext(dpy, vevent->window, ColormapContext, (caddr_t *)&cwin) == XCNOENT) + return; + + /* + * when Saber complains about retreiving an from an + * just type "touch vevent->state" and "cont" + */ + cmap = cwin->colormap; + if ((cmap->state & CM_INSTALLABLE) && + vevent->state != cwin->visibility && + (vevent->state == VisibilityFullyObscured || + cwin->visibility == VisibilityFullyObscured) && + cmap->w == cwin->w) { + cwin->visibility = vevent->state; + InstallWindowColormaps(VisibilityNotify, (TwmWindow *) NULL); + } else + cwin->visibility = vevent->state; +} + + + +/*********************************************************************** + * + * Procedure: + * HandleKeyPress - key press event handler + * + *********************************************************************** + */ + +int MovedFromKeyPress = False; + +void +HandleKeyPress() +{ + FuncKey *key; + int len; + unsigned int modifier; + TwmWindow *tmp_win; + + /* djhjr - 6/5/98 */ + int have_ScrFocus = 0; + +#if 0 + if (InfoLines) + { XUnmapWindow(dpy, Scr->InfoWindow); +RFB july 28 1993 this code was wrong anyway because +InfoLines should have been set to 0. +Simply remove it... + } +#endif + Context = C_NO_CONTEXT; + + if (Event.xany.window == Scr->Root) + Context = C_ROOT; + if ((Event.xany.window == Scr->VirtualDesktopDisplay) || + (Event.xany.window == Scr->VirtualDesktopDisplayOuter)) + { + if (Event.xkey.subwindow && + (XFindContext(dpy, Event.xkey.subwindow, VirtualContext, (caddr_t *) &tmp_win) + != XCNOENT)) { + Tmp_win = tmp_win; + Context = C_VIRTUAL_WIN; + } else { + Context = C_VIRTUAL; + Tmp_win = Scr->VirtualDesktopDisplayTwin; + } + } + if (Tmp_win) + { + if (Event.xany.window == Tmp_win->title_w) + Context = C_TITLE; + if (Event.xany.window == Tmp_win->w) + Context = C_WINDOW; + if (Event.xany.window == Tmp_win->icon_w) + Context = C_ICON; + if (Event.xany.window == Tmp_win->frame) + Context = C_FRAME; + if (Tmp_win->list && Event.xany.window == Tmp_win->list->w) + Context = C_ICONMGR; + if (Tmp_win->list && Event.xany.window == Tmp_win->list->icon) + Context = C_ICONMGR; + } + + /* + * Now HERE'S a fine little kludge: Make an icon manager's frame or + * the virtual desktop's frame or a door and it's frame context- + * sensitive to key bindings, and make the frames of windows without + * titlebars forward key events. + * + * djhjr - 6/5/98 7/2/98 7/14/98 + */ + if (Scr->Focus && (Context == C_NO_CONTEXT || Context == C_ROOT)) + { + /* ugly, but it works! see also iconmgr.c:RemoveIconManager() */ + if (Scr->Focus->iconmgr) + { +#ifdef NEVER /* warps to icon managers uniquely handled in menus.c:WarpToWindow() */ + if (!Scr->Focus->iconmgrp->active) + { + ActiveIconManager(Scr->Focus->iconmgrp->last); + Tmp_win = Scr->Focus; + } + else + Tmp_win = Scr->Focus->iconmgrp->active->twm; +#endif + + have_ScrFocus = 1; + } + else if (Scr->VirtualDesktopDisplayTwin == Scr->Focus) + { + Tmp_win = Scr->Focus; + Context = C_VIRTUAL; + } + /* XFindContext() doesn't seem to work here!?! */ + else if (Scr->Doors) + { + TwmDoor *door_win; + + for (door_win = Scr->Doors; door_win != NULL; + door_win = door_win->next) + if (door_win->twin == Scr->Focus) + { + Tmp_win = Scr->Focus; + Context = C_DOOR; + + break; + } + } + else if (Scr->Focus->frame && !Scr->Focus->title_w) + { + Tmp_win = Scr->Focus; + Event.xany.window = Tmp_win->frame; + Context = C_FRAME; + } + } + + modifier = (Event.xkey.state & mods_used); + for (key = Scr->FuncKeyRoot.next; key != NULL; key = key->next) + { + if (key->keycode == Event.xkey.keycode && + key->mods == modifier && + (key->cont == Context || key->cont == C_NAME)) + { + /* it doesn't make sense to resize from a key press? */ + if (key->func == F_RESIZE) + return; + + /* + * Exceptions for warps from icon managers (see the above kludge) + * + * djhjr - 6/5/98 7/2/98 7/14/98 + */ + switch (key->func) + { + case F_WARP: + if (have_ScrFocus && Context == C_ROOT) + return; + + break; + case F_WARPCLASSNEXT: + case F_WARPCLASSPREV: + case F_WARPRING: + if (Context == C_ICONMGR) + Scr->Focus = Tmp_win = Tmp_win->list->iconmgr->twm_win; + + if (have_ScrFocus) + { + Tmp_win = Scr->Focus; + Context = C_ICONMGR; + } + + break; +/* case F_WARPTO:*/ +/* case F_WARPTOICONMGR:*/ +/* case F_WARPTONEWEST:*/ + default: + break; + } + + /* special case for moves */ + if (key->func == F_MOVE || key->func == F_FORCEMOVE) + MovedFromKeyPress = True; + + if (key->cont != C_NAME) + { + ExecuteFunction(key->func, key->action, Event.xany.window, + Tmp_win, &Event, Context, FALSE); + + /* + * Added this 'if ()' for deferred keyboard events (see also menus.c) + * Submitted by Michel Eyckmans + */ + if (!(Context = C_ROOT && RootFunction != F_NOFUNCTION)) + XUngrabPointer(dpy, CurrentTime); + + return; + } + else + { + int matched = FALSE; + len = strlen(key->win_name); + + /* try and match the name first */ + for (Tmp_win = Scr->TwmRoot.next; Tmp_win != NULL; + Tmp_win = Tmp_win->next) + { + if (!strncmp(key->win_name, Tmp_win->name, len)) + { + matched = TRUE; + ExecuteFunction(key->func, key->action, Tmp_win->frame, + Tmp_win, &Event, C_FRAME, FALSE); + XUngrabPointer(dpy, CurrentTime); + } + } + + /* now try the res_name */ + if (!matched) + for (Tmp_win = Scr->TwmRoot.next; Tmp_win != NULL; + Tmp_win = Tmp_win->next) + { + if (!strncmp(key->win_name, Tmp_win->class.res_name, len)) + { + matched = TRUE; + ExecuteFunction(key->func, key->action, Tmp_win->frame, + Tmp_win, &Event, C_FRAME, FALSE); + XUngrabPointer(dpy, CurrentTime); + } + } + + /* now try the res_class */ + if (!matched) + for (Tmp_win = Scr->TwmRoot.next; Tmp_win != NULL; + Tmp_win = Tmp_win->next) + { + if (!strncmp(key->win_name, Tmp_win->class.res_class, len)) + { + matched = TRUE; + ExecuteFunction(key->func, key->action, Tmp_win->frame, + Tmp_win, &Event, C_FRAME, FALSE); + XUngrabPointer(dpy, CurrentTime); + } + } + if (matched) + return; + } + } + } + + /* + * If we get here, no function was bound to the key. Send it + * to the client if it was in a window we know about. + */ + if (Tmp_win) + { + if (Event.xany.window == Tmp_win->icon_w || + Event.xany.window == Tmp_win->frame || + Event.xany.window == Tmp_win->title_w || + (Tmp_win->list && (Event.xany.window == Tmp_win->list->w))) + { + Event.xkey.window = Tmp_win->w; + XSendEvent(dpy, Tmp_win->w, False, KeyPressMask, &Event); + } + } + +} + + + +static void free_window_names (tmp, nukefull, nukename, nukeicon) + TwmWindow *tmp; + Bool nukefull, nukename, nukeicon; +{ + /* the other two "free()"s were "XFree()"s - djhjr - 9/14/03 */ +/* + + * XXX - are we sure that nobody ever sets these to another constant (check + * twm windows)? + */ + if (tmp->name == tmp->full_name) nukefull = False; + +/* this test is never true anymore... - djhjr - 2/20/99 + if (tmp->name == tmp->icon_name) nukename = False; +*/ + +#define isokay(v) ((v) && (v) != NoName) + + if (nukefull && isokay(tmp->full_name)) free (tmp->full_name); + if (nukename && isokay(tmp->name)) free (tmp->name); + +/* ...because the icon name is now alloc()'d locally - djhjr - 2/20/99 + if (nukeicon && isokay(tmp->icon_name)) XFree (tmp->icon_name); +*/ + if (nukeicon && tmp->icon_name) free(tmp->icon_name); + +#undef isokay + return; +} + + + +void free_cwins (tmp) + TwmWindow *tmp; +{ + int i; + TwmColormap *cmap; + + if (tmp->cmaps.number_cwins) { + for (i = 0; i < tmp->cmaps.number_cwins; i++) { + if (--tmp->cmaps.cwins[i]->refcnt == 0) { + cmap = tmp->cmaps.cwins[i]->colormap; + if (--cmap->refcnt == 0) { + XDeleteContext(dpy, cmap->c, ColormapContext); + free((char *) cmap); + } + XDeleteContext(dpy, tmp->cmaps.cwins[i]->w, ColormapContext); + free((char *) tmp->cmaps.cwins[i]); + } + } + free((char *) tmp->cmaps.cwins); + if (tmp->cmaps.number_cwins > 1) { + free(tmp->cmaps.scoreboard); + tmp->cmaps.scoreboard = NULL; + } + tmp->cmaps.number_cwins = 0; + } +} + + + +/*********************************************************************** + * + * Procedure: + * HandlePropertyNotify - property notify event handler + * + *********************************************************************** + */ + +void +HandlePropertyNotify() +{ + char *prop = NULL; +#ifdef NO_I18N_SUPPORT + Atom actual = None; + int actual_format; + unsigned long nitems, bytesafter; +#endif + unsigned long valuemask; /* mask for create windows */ + XSetWindowAttributes attributes; /* attributes for create windows */ + Pixmap pm; + + /* watch for standard colormap changes */ + if (Event.xproperty.window == Scr->Root) { + XStandardColormap *maps = NULL; + int nmaps; + + switch (Event.xproperty.state) { + case PropertyNewValue: + if (XGetRGBColormaps (dpy, Scr->Root, &maps, &nmaps, + Event.xproperty.atom)) { + /* if got one, then replace any existing entry */ + InsertRGBColormap (Event.xproperty.atom, maps, nmaps, True); + } + return; + + case PropertyDelete: + RemoveRGBColormap (Event.xproperty.atom); + return; + } + } + + if (!Tmp_win) return; /* unknown window */ + +#define MAX_NAME_LEN 200L /* truncate to this many */ +#define MAX_ICON_NAME_LEN 200L /* ditto */ + + switch (Event.xproperty.atom) { + case XA_WM_NAME: +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + if (!I18N_FetchName(dpy, Tmp_win->w, &prop)) +#else + if (XGetWindowProperty (dpy, Tmp_win->w, Event.xproperty.atom, 0L, + MAX_NAME_LEN, False, XA_STRING, &actual, + &actual_format, &nitems, &bytesafter, + (unsigned char **) &prop) != Success || actual == None) +#endif + return; + + free_window_names (Tmp_win, True, True, False); + Tmp_win->full_name = (prop) ? strdup(prop) : NoName; + Tmp_win->name = (prop) ? strdup(prop) : NoName; +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + if (prop) free(prop); +#else + if (prop) XFree(prop); +#endif + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + Tmp_win->name_width = MyFont_TextWidth (&Scr->TitleBarFont, +#else + Tmp_win->name_width = XTextWidth (Scr->TitleBarFont.font, +#endif + Tmp_win->name, + strlen (Tmp_win->name)); + + SetupWindow (Tmp_win, Tmp_win->frame_x, Tmp_win->frame_y, + Tmp_win->frame_width, Tmp_win->frame_height, -1); + + if (Tmp_win->title_w) XClearArea(dpy, Tmp_win->title_w, 0,0,0,0, True); + + /* + * if the icon name is NoName, set the name of the icon to be + * the same as the window + */ +/* see that the icon name is it's own memory - djhjr - 2/20/99 + if (Tmp_win->icon_name == NoName) { + Tmp_win->icon_name = Tmp_win->name; +*/ + if (!strcmp(Tmp_win->icon_name, NoName)) { + free(Tmp_win->icon_name); + Tmp_win->icon_name = strdup(Tmp_win->name); + + RedoIconName(); + } + break; + + case XA_WM_ICON_NAME: +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + if (!I18N_GetIconName(dpy, Tmp_win->w, &prop)) +#else + if (XGetWindowProperty (dpy, Tmp_win->w, Event.xproperty.atom, 0, + MAX_ICON_NAME_LEN, False, XA_STRING, &actual, + &actual_format, &nitems, &bytesafter, + (unsigned char **) &prop) != Success || actual == None) +#endif + return; + +/* see that the icon name is it's own memory - djhjr - 2/20/99 + if (!prop) prop = NoName; + free_window_names (Tmp_win, False, False, True); + Tmp_win->icon_name = prop; +*/ + free_window_names (Tmp_win, False, False, True); + Tmp_win->icon_name = (prop) ? strdup(prop) : NoName; +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + if (prop) free(prop); +#else + if (prop) XFree(prop); +#endif + + RedoIconName(); + + break; + + case XA_WM_HINTS: + if (Tmp_win->wmhints) XFree ((char *) Tmp_win->wmhints); + Tmp_win->wmhints = XGetWMHints(dpy, Event.xany.window); + + if (Tmp_win->wmhints && (Tmp_win->wmhints->flags & WindowGroupHint)) + Tmp_win->group = Tmp_win->wmhints->window_group; + + if (!Tmp_win->forced && Tmp_win->wmhints && + Tmp_win->wmhints->flags & IconWindowHint) { + if (Tmp_win->icon_w) { + int icon_x, icon_y; + + /* + * There's already an icon window. + * Try to find out where it is; if we succeed, move the new + * window to where the old one is. + */ + if (XGetGeometry (dpy, Tmp_win->icon_w, &JunkRoot, &icon_x, + &icon_y, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth)) { + /* + * Move the new icon window to where the old one was. + */ + XMoveWindow(dpy, Tmp_win->wmhints->icon_window, icon_x, + icon_y); + } + + /* + * If the window is iconic, map the new icon window. + */ + if (Tmp_win->icon) + XMapWindow(dpy, Tmp_win->wmhints->icon_window); + + /* + * Now, if the old window isn't ours, unmap it, otherwise + * just get rid of it completely. + */ + if (Tmp_win->icon_not_ours) { + if (Tmp_win->icon_w != Tmp_win->wmhints->icon_window) + XUnmapWindow(dpy, Tmp_win->icon_w); + } else + XDestroyWindow(dpy, Tmp_win->icon_w); + + /* + * The new icon window isn't our window, so note that fact + * so that we don't treat it as ours. + */ + Tmp_win->icon_not_ours = TRUE; + + /* + * Now make the new window the icon window for this window, + * and set it up to work as such (select for key presses + * and button presses/releases, set up the contexts for it, + * and define the cursor for it). + */ + Tmp_win->icon_w = Tmp_win->wmhints->icon_window; + XSelectInput (dpy, Tmp_win->icon_w, + KeyPressMask | ButtonPressMask | ButtonReleaseMask); + XSaveContext(dpy, Tmp_win->icon_w, TwmContext, (caddr_t)Tmp_win); + XSaveContext(dpy, Tmp_win->icon_w, ScreenContext, (caddr_t)Scr); + XDefineCursor(dpy, Tmp_win->icon_w, Scr->IconCursor); + } + } + + if (Tmp_win->icon_w && !Tmp_win->forced && Tmp_win->wmhints && + (Tmp_win->wmhints->flags & IconPixmapHint)) { + if (!XGetGeometry (dpy, Tmp_win->wmhints->icon_pixmap, &JunkRoot, + &JunkX, &JunkY, (unsigned int *)&Tmp_win->icon_width, + (unsigned int *)&Tmp_win->icon_height, &JunkBW, &JunkDepth)) { + return; + } + + pm = XCreatePixmap (dpy, Scr->Root, Tmp_win->icon_width, + Tmp_win->icon_height, Scr->d_depth); + if (!pm) return; + + FB(Tmp_win->iconc.fore, Tmp_win->iconc.back); + +/* + * adapted from CTWM-3.5 - djhjr - 9/4/98 + */ +#ifdef ORIGINAL_PIXMAPS + XCopyPlane(dpy, Tmp_win->wmhints->icon_pixmap, pm, + Scr->NormalGC, + 0,0, Tmp_win->icon_width, Tmp_win->icon_height, 0, 0, 1 ); +#else + if (JunkDepth == Scr->d_depth) + XCopyArea (dpy, Tmp_win->wmhints->icon_pixmap, pm, Scr->NormalGC, + 0,0, Tmp_win->icon_width, Tmp_win->icon_height, 0, 0); + else + XCopyPlane(dpy, Tmp_win->wmhints->icon_pixmap, pm, Scr->NormalGC, + 0,0, Tmp_win->icon_width, Tmp_win->icon_height, 0, 0, 1 ); +#endif + + valuemask = CWBackPixmap; + attributes.background_pixmap = pm; + + if (Tmp_win->icon_bm_w) + XDestroyWindow(dpy, Tmp_win->icon_bm_w); + + Tmp_win->icon_bm_w = + XCreateWindow (dpy, Tmp_win->icon_w, 0, 0, + (unsigned int) Tmp_win->icon_width, + (unsigned int) Tmp_win->icon_height, + (unsigned int) 0, Scr->d_depth, + (unsigned int) CopyFromParent, Scr->d_visual, + valuemask, &attributes); + +/* + * adapted from CTWM-3.5 - djhjr - 9/4/98 + */ +#ifndef ORIGINAL_PIXMAPS + if (! (Tmp_win->wmhints->flags & IconMaskHint)) { + XRectangle rect; + + rect.x = rect.y = 0; + rect.width = Tmp_win->icon_width; + rect.height = Tmp_win->icon_height; + XShapeCombineRectangles (dpy, Tmp_win->icon_w, ShapeBounding, + 0, 0, &rect, 1, ShapeUnion, 0); + } +#endif + + XFreePixmap (dpy, pm); + RedoIconName(); + } + +/* + * adapted from CTWM-3.5 - djhjr - 9/4/98 + */ +#ifndef ORIGINAL_PIXMAPS + if (Tmp_win->icon_w && !Tmp_win->forced && Tmp_win->wmhints && + (Tmp_win->wmhints->flags & IconMaskHint)) { + GC gc; + + if (!XGetGeometry (dpy, Tmp_win->wmhints->icon_mask, &JunkRoot, + &JunkX, &JunkY, &JunkWidth, &JunkHeight, &JunkBW, + &JunkDepth)) { + return; + } + if (JunkDepth != 1) return; + + pm = XCreatePixmap (dpy, Scr->Root, JunkWidth, JunkHeight, 1); + if (!pm) return; + + gc = XCreateGC (dpy, pm, 0, NULL); + if (!gc) return; + + XCopyArea (dpy, Tmp_win->wmhints->icon_mask, pm, gc, + 0, 0, JunkWidth, JunkHeight, 0, 0); + XFreeGC (dpy, gc); + + XFreePixmap (dpy, pm); + RedoIconName(); + } +#endif + + break; + + case XA_WM_NORMAL_HINTS: + GetWindowSizeHints (Tmp_win); + break; + + default: + if (Event.xproperty.atom == _XA_WM_COLORMAP_WINDOWS) { + FetchWmColormapWindows (Tmp_win); /* frees old data */ + break; + } else if (Event.xproperty.atom == _XA_WM_PROTOCOLS) { + FetchWmProtocols (Tmp_win); + break; + } + break; + } +} + + + +/*********************************************************************** + * + * Procedure: + * RedoIconName - procedure to re-position the icon window and name + * + *********************************************************************** + */ + +void RedoIconName() +{ + int x, y; + + if (Tmp_win->list) + { + /* let the expose event cause the repaint */ + XClearArea(dpy, Tmp_win->list->w, 0,0,0,0, True); + + if (Scr->SortIconMgr) + SortIconManager(Tmp_win->list->iconmgr); + } + + if (Scr->Virtual && + Scr->NamesInVirtualDesktop && + Tmp_win->VirtualDesktopDisplayWindow) + XClearArea(dpy, Tmp_win->VirtualDesktopDisplayWindow, + 0, 0, 0, 0, True); + + if ( ! Tmp_win->icon_w ) return; + + if (Tmp_win->icon_not_ours) + return; + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + Tmp_win->icon_w_width = MyFont_TextWidth(&Scr->IconFont, +#else + Tmp_win->icon_w_width = XTextWidth(Scr->IconFont.font, +#endif + Tmp_win->icon_name, strlen(Tmp_win->icon_name)); + +/* djhjr - 6/11/96 + Tmp_win->icon_w_width += 6; + if (Tmp_win->icon_w_width < Tmp_win->icon_width) + { + Tmp_win->icon_x = (Tmp_win->icon_width - Tmp_win->icon_w_width)/2; + Tmp_win->icon_x += 3; + Tmp_win->icon_w_width = Tmp_win->icon_width; + } + else + { + Tmp_win->icon_x = 3; + } +*/ + Tmp_win->icon_w_width += 8; + if (Tmp_win->icon_w_width < Tmp_win->icon_width + 8) + { + Tmp_win->icon_x = (((Tmp_win->icon_width + 8) - Tmp_win->icon_w_width)/2) + 4; + Tmp_win->icon_w_width = Tmp_win->icon_width + 8; + } + else + Tmp_win->icon_x = 4; + + if (Tmp_win->icon_w_width == Tmp_win->icon_width) + x = 0; + else + x = (Tmp_win->icon_w_width - Tmp_win->icon_width)/2; + +/* djhjr - 6/11/96 + y = 0; +*/ + y = 4; + +/* djhjr - 6/11/96 + Tmp_win->icon_w_height = Tmp_win->icon_height + Scr->IconFont.height + 4; + Tmp_win->icon_y = Tmp_win->icon_height + Scr->IconFont.height; +*/ + Tmp_win->icon_w_height = Tmp_win->icon_height + Scr->IconFont.height + 8; + Tmp_win->icon_y = Tmp_win->icon_height + Scr->IconFont.height + 2; + + XResizeWindow(dpy, Tmp_win->icon_w, Tmp_win->icon_w_width, + Tmp_win->icon_w_height); + if (Tmp_win->icon_bm_w) + { + XMoveWindow(dpy, Tmp_win->icon_bm_w, x, y); + XMapWindow(dpy, Tmp_win->icon_bm_w); + } + if (Tmp_win->icon) + { + XClearArea(dpy, Tmp_win->icon_w, 0, 0, 0, 0, True); + } +} + +/* + * RedoDoorName - Redraw the contents of a door's window + * + * djhjr - 2/10/99 2/28/99 + */ +void +RedoDoorName(twin, door) +TwmWindow *twin; +TwmDoor *door; +{ + TwmWindow *tmp_win; + + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF(door->colors.fore, door->colors.back, Scr->DoorFont); + + /* find it's twm window to get the current width, etc. */ +/* + * The TWM window is passed from Do*Resize(), + * as it may be undeterminable in HandleExpose()!? + * + * djhjr - 2/28/99 + * + if (XFindContext(dpy, Event.xany.window, TwmContext, + (caddr_t *)&tmp_win) != XCNOENT) +*/ + if (twin) + tmp_win = twin; + else + XFindContext(dpy, Event.xany.window, TwmContext, (caddr_t *)&tmp_win); + + if (tmp_win) + { + int tw, bw; + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + tw = MyFont_TextWidth(&Scr->DoorFont, +#else + tw = XTextWidth(Scr->DoorFont.font, +#endif + door->name, strlen(door->name)); + + /* djhjr - 4/26/96 */ +/* djhjr - 8/11/98 + * was 'Scr->use3Dborders' - djhjr - 8/11/98 * + bw = (Scr->BorderBevelWidth > 0) ? Scr->ThreeDBorderWidth : 0; +*/ + bw = (Scr->BorderBevelWidth > 0) ? Scr->BorderWidth : 0; + + /* change the little internal one to fit the external */ + XResizeWindow(dpy, door->w, + tmp_win->frame_width, + tmp_win->frame_height); + + /* draw the text in the right place */ +/* And it IS the right place. +** If your font has its characters starting 20 pixels +** over to the right, it just looks wrong! +** For example grog-9 from ISC's X11R3 distribution. +*/ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawString(dpy, door->w, &Scr->DoorFont, +#else + XDrawString(dpy, door->w, +#endif + Scr->NormalGC, +/* gets 'SIZE_VINDENT' out of here... djhjr - 5/14/96 + (tmp_win->frame_width - tw)/2, + tmp_win->frame_height - SIZE_VINDENT - + (tmp_win->frame_height - Scr->DoorFont.height)/2, +** ...and NOW it's in the right place! */ + (tmp_win->frame_width - tw - 2 * bw) / 2, + (tmp_win->frame_height - tmp_win->title_height - + Scr->DoorFont.height - 2 * bw) / 2 + +/* djhjr - 9/14/03 + Scr->DoorFont.font->ascent, +*/ + Scr->DoorFont.ascent, + door->name, strlen(door->name)); + + /* djhjr - 2/7/99 */ + if (Scr->DoorBevelWidth > 0) + Draw3DBorder(door->w, 0, 0, tmp_win->frame_width - (bw * 2), + tmp_win->frame_height - (bw * 2), + Scr->DoorBevelWidth, Scr->DoorC, off, False, False); + } else { +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawString(dpy, door->w, &Scr->DoorFont, +#else + XDrawString(dpy, door->w, +#endif + Scr->NormalGC, + SIZE_HINDENT/2, 0/*Scr->DoorFont.height*/, + door->name, strlen(door->name)); + } +} + +/* + * RedoListWindow - Redraw the contents of an icon manager's entry + * + * djhjr - 3/1/99 + */ +void +RedoListWindow(twin) +TwmWindow *twin; +{ +/* djhjr - 4/19/96 + * font was font.font->fid - djhjr - 9/14/03 * + FBF(twin->list->fore, twin->list->back, Scr->IconManagerFont); +* djhjr - 9/14/03 * +#ifndef NO_I18N_SUPPORT + MyFont_DrawString (dpy, Event.xany.window, &Scr->IconManagerFont, +#else + XDrawString (dpy, Event.xany.window, +#endif + Scr->NormalGC, + iconmgr_textx, Scr->IconManagerFont.y+4, + twin->icon_name, strlen(twin->icon_name)); + DrawIconManagerBorder(twin->list); +*/ + /* made static - djhjr - 6/18/99 */ + static int en = 0, dots = 0; + + /* djhjr - 3/29/98 */ + int i, j, slen = strlen(twin->icon_name); + char *a = NULL; + + /* djhjr - 10/2/01 */ + if (!twin->list) return; + + /* + * clip the title a couple of characters less than the width of the + * icon window plus padding, and tack on ellipses - this is a little + * different than the titlebar's... + * + * djhjr - 3/29/98 + */ + if (Scr->NoPrettyTitles == FALSE) /* for rader - djhjr - 2/9/99 */ + { +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + i = MyFont_TextWidth(&Scr->IconManagerFont, +#else + i = XTextWidth(Scr->IconManagerFont.font, +#endif + twin->icon_name, slen); + +/* DUH! - djhjr - 6/18/99 + j = twin->list->width - iconmgr_textx - en; +*/ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + if (!en) en = MyFont_TextWidth(&Scr->IconManagerFont, "n", 1); + if (!dots) dots = MyFont_TextWidth(&Scr->IconManagerFont, "...", 3); +#else + if (!en) en = XTextWidth(Scr->IconManagerFont.font, "n", 1); + if (!dots) dots = XTextWidth(Scr->IconManagerFont.font, "...", 3); +#endif + j = twin->list->width - iconmgr_textx - dots; + + /* djhjr - 5/5/98 */ + /* was 'Scr->use3Diconmanagers' - djhjr - 8/11/98 */ + if (Scr->IconMgrBevelWidth > 0) + j -= Scr->IconMgrBevelWidth; + else + j -= Scr->BorderWidth; + +/* djhjr - 6/18/99 + if (2 * en >= j) +*/ + if (en >= j) + slen = 0; + else if (i >= j) + { + for (i = slen; i >= 0; i--) + +/* djhjr - 6/18/99 + if (XTextWidth(Scr->IconManagerFont.font, twin->icon_name, i) + 2 * en < j) +*/ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + if (MyFont_TextWidth(&Scr->IconManagerFont, +#else + if (XTextWidth(Scr->IconManagerFont.font, +#endif + twin->icon_name, i) + en < j) + { + slen = i; + break; + } + + a = (char *)malloc(slen + 4); + memcpy(a, twin->icon_name, slen); + strcpy(a + slen, "..."); + slen += 3; + } + } + + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF(twin->list->cp.fore, twin->list->cp.back, Scr->IconManagerFont); + +/* what's the point of this? - djhjr - 5/2/98 + if (Scr->use3Diconmanagers && (Scr->Monochrome != COLOR)) +* djhjr - 9/14/03 * +#ifndef NO_I18N_SUPPORT + MyFont_DrawImageString (dpy, twin->list->w, + &Scr->IconManagerFont, +#else + XDrawImageString (dpy, twin->list->w, +#endif + Scr->NormalGC, iconmgr_textx, + +* djhjr - 5/2/98 + Scr->IconManagerFont.y+4, +* + (twin->list->height - Scr->IconManagerFont.height) / 2 + + Scr->IconManagerFont.y, + + (a) ? a : twin->icon_name, slen); + else +*/ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawString (dpy, twin->list->w, + &Scr->IconManagerFont, +#else + XDrawString (dpy, twin->list->w, +#endif + Scr->NormalGC, iconmgr_textx, + +/* djhjr - 5/2/98 + Scr->IconManagerFont.y+4, +*/ + (twin->list->height - Scr->IconManagerFont.height) / 2 + + Scr->IconManagerFont.y, + + (a) ? a : twin->icon_name, slen); + + /* free the clipped title - djhjr - 3/29/98 */ + if (a) free(a); + + DrawIconManagerBorder(twin->list, False); +} + + +/*********************************************************************** + * + * Procedure: + * HandleClientMessage - client message event handler + * + *********************************************************************** + */ + +void +HandleClientMessage() +{ + extern void RestartVtwm(); + + if (Event.xclient.message_type == _XA_WM_CHANGE_STATE) + { + if (Tmp_win != NULL) + { + if (Event.xclient.data.l[0] == IconicState && !Tmp_win->icon) + { + XEvent button; + + XQueryPointer( dpy, Scr->Root, &JunkRoot, &JunkChild, + &(button.xmotion.x_root), + &(button.xmotion.y_root), + &JunkX, &JunkY, &JunkMask); + + ExecuteFunction(F_ICONIFY, NULLSTR, Event.xany.window, + Tmp_win, &button, FRAME, FALSE); + XUngrabPointer(dpy, CurrentTime); + } + } + } + /* djhjr - 7/31/98 */ + else if (Event.xclient.message_type == _XA_TWM_RESTART) + RestartVtwm(CurrentTime); +} + + + +/*********************************************************************** + * + * Procedure: + * HandleExpose - expose event handler + * + *********************************************************************** + */ + +static void flush_expose(); + +void +HandleExpose() +{ + MenuRoot *tmp; + TwmDoor *door = NULL; + int j; + + if (XFindContext(dpy, Event.xany.window, MenuContext, (caddr_t *)&tmp) == 0) + { + PaintMenu(tmp, &Event); + return; + } + + if (XFindContext(dpy, Event.xany.window, DoorContext, (caddr_t *)&door) != XCNOENT) + { + /* see also resize.c - djhjr - 2/28/99 */ + RedoDoorName(NULL, door); + flush_expose(Event.xany.window); + return; + } + + if (Event.xexpose.count != 0) + return; + + if (Event.xany.window == Scr->InfoWindow && InfoLines) + { + int i, k; + int height; + + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF(Scr->DefaultC.fore, Scr->DefaultC.back, Scr->InfoFont); + + /* djhjr - 5/10/96 */ + XGetGeometry (dpy, Scr->InfoWindow, &JunkRoot, &JunkX, &JunkY, + &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth); + + height = Scr->InfoFont.height+2; + for (i = 0; i < InfoLines; i++) + { + /* djhjr - 5/10/96 */ + j = strlen(Info[i]); + + /* djhjr - 4/29/98 */ + k = 5; + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (!i && Scr->BorderBevelWidth > 0) k += Scr->InfoBevelWidth; + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawString(dpy, Scr->InfoWindow, &Scr->InfoFont, +#else + XDrawString(dpy, Scr->InfoWindow, +#endif + Scr->NormalGC, +/* centers the lines... djhjr - 5/10/96 + 10, +*/ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + (JunkWidth - MyFont_TextWidth(&Scr->InfoFont, Info[i], j)) / 2, +#else + (JunkWidth - XTextWidth(Scr->InfoFont.font, Info[i], j)) / 2, +#endif + + /* 'k' was a hard-coded '5' - djhjr - 4/29/98 */ + (i*height) + Scr->InfoFont.y + k, Info[i], j); + } + + /* djhjr - 5/9/96 */ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (Scr->InfoBevelWidth > 0) + Draw3DBorder(Scr->InfoWindow, 0, 0, JunkWidth, JunkHeight, +/* djhjr - 4/29/98 + BW, Scr->DefaultC, off, False, False); +*/ + Scr->InfoBevelWidth, Scr->DefaultC, off, False, False); + + flush_expose (Event.xany.window); + } + + /* see that the desktop's bevel gets redrawn - djhjr - 2/10/99 */ + else if (Event.xany.window == Scr->VirtualDesktopDisplay) + { + Draw3DBorder(Scr->VirtualDesktopDisplayOuter, 0, 0, + Scr->VirtualDesktopMaxWidth + (Scr->VirtualDesktopBevelWidth * 2), + Scr->VirtualDesktopMaxHeight + (Scr->VirtualDesktopBevelWidth * 2), + Scr->VirtualDesktopBevelWidth, Scr->VirtualC, off, False, False); + flush_expose (Event.xany.window); + return; + } + + else if (Tmp_win != NULL) + { + /* djhjr - 4/20/96 */ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (Scr->BorderBevelWidth > 0 && (Event.xany.window == Tmp_win->frame)) { + PaintBorders (Tmp_win, ((Tmp_win == Scr->Focus) ? True : False)); + flush_expose (Event.xany.window); + return; + } + else + + if (Event.xany.window == Tmp_win->title_w) + { +/* djhjr - 4/20/96 + * font was font.font->fid - djhjr - 9/14/03 * + FBF(Tmp_win->title.fore, Tmp_win->title.back, Scr->TitleBarFont); + +* djhjr - 9/14/03 * +#ifndef NO_I18N_SUPPORT + MyFont_DrawString (dpy, Tmp_win->title_w, &Scr->TitleBarFont, +#else + XDrawString (dpy, Tmp_win->title_w, +#endif + Scr->NormalGC, + Scr->TBInfo.titlex, Scr->TitleBarFont.y, + Tmp_win->name, strlen(Tmp_win->name)); +*/ + PaintTitle (Tmp_win); + + /* djhjr - 10/25/02 */ + PaintTitleHighlight(Tmp_win, (Tmp_win == Scr->Focus) ? on : off); + + flush_expose (Event.xany.window); + return; + } + else if (Event.xany.window == Tmp_win->icon_w) + { + +/* djhjr - 4/21/96 + * font was font.font->fid - djhjr - 9/14/03 * + FBF(Tmp_win->iconc.fore, Tmp_win->iconc.back, Scr->IconFont); + +* djhjr - 9/14/03 * +#ifndef NO_I18N_SUPPORT + MyFont_DrawString (dpy, Tmp_win->icon_w, &Scr->IconManagerFont, +#else + XDrawString (dpy, Tmp_win->icon_w, +#endif + Scr->NormalGC, + Tmp_win->icon_x, Tmp_win->icon_y, + Tmp_win->icon_name, strlen(Tmp_win->icon_name)); +*/ + PaintIcon(Tmp_win); + + flush_expose (Event.xany.window); + return; + } else if (Tmp_win->titlebuttons) { + int i; + Window w = Event.xany.window; + TBWindow *tbw; + int nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; + + for (i = 0, tbw = Tmp_win->titlebuttons; i < nb; i++, tbw++) { + if (w == tbw->window) { +/* djhjr - 4/19/96 + register TitleButton *tb = tbw->info; + + FB(Tmp_win->title.fore, Tmp_win->title.back); + XCopyPlane (dpy, tb->bitmap, w, Scr->NormalGC, + tb->srcx, tb->srcy, tb->width, tb->height, + tb->dstx, tb->dsty, 1); +*/ + /* djhjr - 11/17/97 8/10/98 */ + /* added the test for window highlighting - djhjr - 3/14/98 */ + /* collapsed two functions - djhjr - 8/10/98 */ + if (Scr->ButtonColorIsFrame && Tmp_win->highlight) + PaintTitleButton(Tmp_win, tbw, (Scr->Focus == Tmp_win) ? 2 : 1); + else + PaintTitleButton(Tmp_win, tbw, 0); + + flush_expose (w); + return; + } + } + } + if (Tmp_win->list) { + if (Event.xany.window == Tmp_win->list->w) + { + /* see also resize.c - djhjr - 3/1/99 */ + RedoListWindow(Tmp_win); + flush_expose (Event.xany.window); + return; + } + if (Event.xany.window == Tmp_win->list->icon) + { +/* djhjr - 4/19/96 + FB(Tmp_win->list->fore, Tmp_win->list->back); + XCopyPlane(dpy, Scr->siconifyPm, Tmp_win->list->icon, + Scr->NormalGC, + 0,0, iconifybox_width, iconifybox_height, 0, 0, 1); +*/ +/* djhjr - 10/30/02 + * was 'Scr->use3Diconmanagers' - djhjr - 8/11/98 * + if (Scr->IconMgrBevelWidth > 0 && Tmp_win->list->iconifypm) + XCopyArea (dpy, Tmp_win->list->iconifypm, Tmp_win->list->icon, + Scr->NormalGC, 0, 0, + iconifybox_width, iconifybox_height, 0, 0); + else { + FB(Tmp_win->list->cp.fore, Tmp_win->list->cp.back); + XCopyPlane(dpy, Scr->siconifyPm->pixmap, Tmp_win->list->icon, Scr->NormalGC, + 0,0, iconifybox_width, iconifybox_height, 0, 0, 1); + } +*/ + XCopyArea(dpy, Tmp_win->list->iconifypm->pixmap, + Tmp_win->list->icon, Scr->NormalGC, 0, 0, + iconifybox_width, iconifybox_height, 0, 0); + + flush_expose (Event.xany.window); + return; + } + } + } + + /* update the virtual desktop display names */ + if (Scr->Virtual && Scr->NamesInVirtualDesktop) { + TwmWindow *tmp_win; + char *name = NULL; + + if (XFindContext(dpy, Event.xany.window, VirtualContext, + (caddr_t *)&tmp_win) != XCNOENT) { + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF(tmp_win->virtual.fore, tmp_win->virtual.back, + Scr->VirtualFont); + if (tmp_win->icon_name) + name = tmp_win->icon_name; + else if (tmp_win->name) + name = tmp_win->name; + if (name) +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawImageString(dpy, Event.xany.window, + &Scr->VirtualFont, +#else + XDrawImageString(dpy, Event.xany.window, +#endif + Scr->NormalGC, + 0, Scr->VirtualFont.height, + name, strlen(name)); + } + } +} + + + +/*********************************************************************** + * + * Procedure: + * HandleDestroyNotify - DestroyNotify event handler + * + *********************************************************************** + */ + +void +HandleDestroyNotify() +{ + int i; + + /* + * Warning, this is also called by HandleUnmapNotify; if it ever needs to + * look at the event, HandleUnmapNotify will have to mash the UnmapNotify + * into a DestroyNotify. + */ + + if (Tmp_win == NULL) + return; + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + if (destroySoundFromFunction == FALSE) + PlaySound(S_CUNMAP); + else + destroySoundFromFunction = FALSE; +#endif + + if (Tmp_win == Scr->Focus) + { + FocusOnRoot(); + } + + if (Tmp_win == Scr->Newest) /* PF */ + Scr->Newest = NULL; /* PF */ + + /* djhjr - 5/16/98 */ + if (Tmp_win == UnHighLight_win) UnHighLight_win = NULL; + + XDeleteContext(dpy, Tmp_win->w, TwmContext); + XDeleteContext(dpy, Tmp_win->w, ScreenContext); + XDeleteContext(dpy, Tmp_win->frame, TwmContext); + XDeleteContext(dpy, Tmp_win->frame, ScreenContext); + XDeleteContext(dpy, Tmp_win->VirtualDesktopDisplayWindow, VirtualContext); + if (Tmp_win->icon_w) + { + XDeleteContext(dpy, Tmp_win->icon_w, TwmContext); + XDeleteContext(dpy, Tmp_win->icon_w, ScreenContext); + } + if (Tmp_win->title_height) + { + int nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; + XDeleteContext(dpy, Tmp_win->title_w, TwmContext); + XDeleteContext(dpy, Tmp_win->title_w, ScreenContext); + if (Tmp_win->hilite_w) + { + XDeleteContext(dpy, Tmp_win->hilite_w, TwmContext); + XDeleteContext(dpy, Tmp_win->hilite_w, ScreenContext); + } + if (Tmp_win->titlebuttons) { + for (i = 0; i < nb; i++) { + XDeleteContext (dpy, Tmp_win->titlebuttons[i].window, + TwmContext); + XDeleteContext (dpy, Tmp_win->titlebuttons[i].window, + ScreenContext); + } + } + } + + if (Scr->cmapInfo.cmaps == &Tmp_win->cmaps) + InstallWindowColormaps(DestroyNotify, &Scr->TwmRoot); + + /* + * TwmWindows contain the following pointers + * + * 1. full_name + * 2. name + * 3. icon_name + * 4. wmhints + * 5. class.res_name + * 6. class.res_class + * 7. list + * 8. iconmgrp + * 9. cwins + * 10. titlebuttons + * 11. window ring + * 12. virtual desktop display window + */ + if (Tmp_win->gray) XFreePixmap (dpy, Tmp_win->gray); + + /* djhjr - 4/26/99 */ + AppletDown(Tmp_win); + + XDestroyWindow(dpy, Tmp_win->frame); + if (Tmp_win->icon_w && !Tmp_win->icon_not_ours) { + XDestroyWindow(dpy, Tmp_win->icon_w); + IconDown (Tmp_win); + } + XDestroyWindow(dpy, Tmp_win->VirtualDesktopDisplayWindow); /* 12 */ + RemoveIconManager(Tmp_win); /* 7 */ + Tmp_win->prev->next = Tmp_win->next; + if (Tmp_win->next != NULL) + Tmp_win->next->prev = Tmp_win->prev; + if (Tmp_win->auto_raise) Scr->NumAutoRaises--; + + free_window_names (Tmp_win, True, True, True); /* 1, 2, 3 */ + if (Tmp_win->wmhints) /* 4 */ + XFree ((char *)Tmp_win->wmhints); + if (Tmp_win->class.res_name && Tmp_win->class.res_name != NoName) /* 5 */ + XFree ((char *)Tmp_win->class.res_name); + if (Tmp_win->class.res_class && Tmp_win->class.res_class != NoName) /* 6 */ + XFree ((char *)Tmp_win->class.res_class); + free_cwins (Tmp_win); /* 9 */ + if (Tmp_win->titlebuttons) /* 10 */ + free ((char *) Tmp_win->titlebuttons); + /* + * 11a through 11c was handled in a local function, but + * is now broken out (11a & 11b), and uses a public function + * in menus.c (11c) - djhjr - 10/27/02 + */ + if (enter_win == Tmp_win) { /* 11a */ + enter_flag = FALSE; + enter_win = NULL; + } + if (raise_win == Tmp_win) raise_win = NULL; /* 11b */ + RemoveWindowFromRing(Tmp_win); /* 11c */ + + free((char *)Tmp_win); +} + + + +void +HandleCreateNotify() +{ +#ifdef DEBUG_EVENTS + fprintf(stderr, "CreateNotify w = 0x%x\n", Event.xcreatewindow.window); + fflush(stderr); + XBell(dpy, 0); + XSync(dpy, 0); +#endif +} + + + +/*********************************************************************** + * + * Procedure: + * HandleMapRequest - MapRequest event handler + * + *********************************************************************** + */ + +void +HandleMapRequest() +{ + + int stat; + int zoom_save; + + Event.xany.window = Event.xmaprequest.window; + stat = XFindContext(dpy, Event.xany.window, TwmContext, (caddr_t *)&Tmp_win); + if (stat == XCNOENT) + Tmp_win = NULL; + + /* If the window has never been mapped before ... */ + if (Tmp_win == NULL) + { + /* Add decorations. */ + Tmp_win = AddWindow(Event.xany.window, FALSE, (IconMgr *) NULL); + if (Tmp_win == NULL) + return; + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + if (createSoundFromFunction == FALSE) + PlaySound(S_CMAP); + else + createSoundFromFunction = FALSE; +#endif + + } + else + { + /* + * If the window has been unmapped by the client, it won't be listed + * in the icon manager. Add it again, if requested. + */ + if (Tmp_win->list == NULL) + (void) AddIconManager (Tmp_win); + } + + /* If it's not merely iconified, and we have hints, use them. */ + if ((! Tmp_win->icon) && + Tmp_win->wmhints && (Tmp_win->wmhints->flags & StateHint)) + { + int state; + Window icon; + + /* use WM_STATE if enabled */ + if (!(RestartPreviousState && GetWMState(Tmp_win->w, &state, &icon) && + (state == NormalState || state == IconicState))) + state = Tmp_win->wmhints->initial_state; + + switch (state) + { + case DontCareState: + case NormalState: + case ZoomState: + case InactiveState: + XMapWindow(dpy, Tmp_win->w); + XMapWindow(dpy, Tmp_win->frame); + SetMapStateProp(Tmp_win, NormalState); + SetRaiseWindow (Tmp_win); + + /* djhjr - 10/2/01 */ + if (Scr->StrictIconManager) + if (Tmp_win->list) + RemoveIconManager(Tmp_win); + + break; + + case IconicState: + zoom_save = Scr->DoZoom; + Scr->DoZoom = FALSE; + Iconify(Tmp_win, 0, 0); + Scr->DoZoom = zoom_save; + break; + } + } + /* If no hints, or currently an icon, just "deiconify" */ + else + { + DeIconify(Tmp_win); + SetRaiseWindow (Tmp_win); + } + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); /* DSE */ + +} + + + +void SimulateMapRequest (w) + Window w; +{ + Event.xmaprequest.window = w; + HandleMapRequest (); +} + + + +/*********************************************************************** + * + * Procedure: + * HandleMapNotify - MapNotify event handler + * + *********************************************************************** + */ + +void +HandleMapNotify() +{ + if (Tmp_win == NULL) + return; + + /* + * Need to do the grab to avoid race condition of having server send + * MapNotify to client before the frame gets mapped; this is bad because + * the client would think that the window has a chance of being viewable + * when it really isn't. + */ + XGrabServer (dpy); + if (Tmp_win->icon_w) + XUnmapWindow(dpy, Tmp_win->icon_w); + if (Tmp_win->title_w) + XMapSubwindows(dpy, Tmp_win->title_w); + XMapSubwindows(dpy, Tmp_win->frame); + +/* djhjr - 4/25/96 + if (Scr->Focus != Tmp_win && Tmp_win->hilite_w) + XUnmapWindow(dpy, Tmp_win->hilite_w); +*/ + if (Scr->Focus != Tmp_win) + PaintTitleHighlight(Tmp_win, off); + + XMapWindow(dpy, Tmp_win->frame); + XUngrabServer (dpy); + XFlush (dpy); + Tmp_win->mapped = TRUE; + Tmp_win->icon = FALSE; + Tmp_win->icon_on = FALSE; + + /* Race condition if in menus.c:DeIconify() - djhjr - 10/2/01 */ + if (Scr->StrictIconManager) + if (Tmp_win->list) + RemoveIconManager(Tmp_win); +} + + + +/*********************************************************************** + * + * Procedure: + * HandleUnmapNotify - UnmapNotify event handler + * + *********************************************************************** + */ + +void +HandleUnmapNotify() +{ + int dstx, dsty; + Window dumwin; + + /* + * The July 27, 1988 ICCCM spec states that a client wishing to switch + * to WithdrawnState should send a synthetic UnmapNotify with the + * event field set to (pseudo-)root, in case the window is already + * unmapped (which is the case for twm for IconicState). Unfortunately, + * we looked for the TwmContext using that field, so try the window + * field also. + */ + if (Tmp_win == NULL) + { + Event.xany.window = Event.xunmap.window; + if (XFindContext(dpy, Event.xany.window, + TwmContext, (caddr_t *)&Tmp_win) == XCNOENT) + Tmp_win = NULL; + } + + if (Tmp_win == NULL || (!Tmp_win->mapped && !Tmp_win->icon)) + return; + + /* + * The program may have unmapped the client window, from either + * NormalState or IconicState. Handle the transition to WithdrawnState. + * + * We need to reparent the window back to the root (so that twm exiting + * won't cause it to get mapped) and then throw away all state (pretend + * that we've received a DestroyNotify). + */ + + XGrabServer (dpy); + if (XTranslateCoordinates (dpy, Event.xunmap.window, Tmp_win->attr.root, + 0, 0, &dstx, &dsty, &dumwin)) { + XEvent ev; + Bool reparented = XCheckTypedWindowEvent (dpy, Event.xunmap.window, + ReparentNotify, &ev); + SetMapStateProp (Tmp_win, WithdrawnState); + if (reparented) { + if (Tmp_win->old_bw) XSetWindowBorderWidth (dpy, + Event.xunmap.window, + Tmp_win->old_bw); + if (Tmp_win->wmhints && (Tmp_win->wmhints->flags & IconWindowHint)) + XUnmapWindow (dpy, Tmp_win->wmhints->icon_window); + } else { + XReparentWindow (dpy, Event.xunmap.window, Tmp_win->attr.root, + dstx, dsty); + RestoreWithdrawnLocation (Tmp_win); + } + XRemoveFromSaveSet (dpy, Event.xunmap.window); + XSelectInput (dpy, Event.xunmap.window, NoEventMask); + HandleDestroyNotify (); /* do not need to mash event before */ + } /* else window no longer exists and we'll get a destroy notify */ + XUngrabServer (dpy); + XFlush (dpy); +} + + + +/*********************************************************************** + * + * Procedure: + * HandleMotionNotify - MotionNotify event handler + * + *********************************************************************** + */ + +#if 0 /* functionality moved to menus.c:ExecuteFunction() - djhjr - 11/7/03 */ +void +HandleMotionNotify() +{ +#if 0 /* done in menus.c:ExecuteFunction() now - djhjr - 11/4/03 */ + if (moving_window) { + DoMoveWindowOnDesktop(Event.xmotion.x, Event.xmotion.y); + } +#endif + +#if 0 /* done in menus.c:ExecuteFunction() now - djhjr - 5/27/03 */ + if ( ResizeWindow ) + { + XQueryPointer( dpy, Event.xany.window, + &(Event.xmotion.root), &JunkChild, + &(Event.xmotion.x_root), &(Event.xmotion.y_root), + &(Event.xmotion.x), &(Event.xmotion.y), + &JunkMask); + + /* Set WindowMoved appropriately so that f.deltastop will + work with resize as well as move. */ + if (abs (Event.xmotion.x - ResizeOrigX) >= Scr->MoveDelta + || abs (Event.xmotion.y - ResizeOrigY) >= Scr->MoveDelta) + { + /* djhjr - 9/5/98 */ + resizing_window = 1; + + WindowMoved = TRUE; + } + + /* added this 'if ()' for applying MoveDelta - djhjr - 9/5/98 */ + if (resizing_window) + { + XFindContext(dpy, ResizeWindow, TwmContext, (caddr_t *)&Tmp_win); + DoResize(Event.xmotion.x_root, Event.xmotion.y_root, Tmp_win); + } + } +#endif +} +#endif + + + +/*********************************************************************** + * + * Procedure: + * HandleButtonRelease - ButtonRelease event handler + * + *********************************************************************** + */ +void +HandleButtonRelease() +{ +/* djhjr - 10/6/02 + int xl, xr, yt, yb, w, h; +*/ + unsigned mask; + + if (Scr->StayUpMenus) + { + if (GlobalFirstTime == True && GlobalMenuButton == True ) + { + ButtonPressed = -1; + GlobalFirstTime = False; + return; + } /* end if */ + + GlobalFirstTime = True; + } /* end if */ + +#if 0 +0 For StayUpMenus, delete infobox after buttonpress! +0 if (InfoLines) /* delete info box on 2nd button release */ +0 /* if (Context == C_IDENTIFY) */ +0 /* This would force you to click on the box itself */ +0 { +0fprintf( stderr, "Kill info B\n" ); +0 XUnmapWindow(dpy, Scr->InfoWindow); +0 InfoLines = 0; +0 Context = C_NO_CONTEXT; +0 } +#endif + +#if 0 /* done in menus.c:ExecuteFunction() now - djhjr - 11/4/03 */ + if (moving_window) + { EndMoveWindowOnDesktop(); + } +#endif + + if (DragWindow != None) + { +/* + * Most all of this is redundant (see menus.c:ExecuteFunction()), + * and I don't see why. Everything except local functionality is + * '#if 0'd out, with just a few lines moved (copied) to menus.c. + * djhjr - 10/6/02 + */ +#if 0 + MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); + + XFindContext(dpy, DragWindow, TwmContext, (caddr_t *)&Tmp_win); + if (DragWindow == Tmp_win->frame) + { + xl = Event.xbutton.x_root - DragX - Tmp_win->frame_bw; + yt = Event.xbutton.y_root - DragY - Tmp_win->frame_bw; + w = DragWidth + 2 * Tmp_win->frame_bw; + h = DragHeight + 2 * Tmp_win->frame_bw; + } + else + { +/* + * Deskset/Openwin apps change the icon's border width attribute. + * Submitted by Caveh Frank Jalali + * + xl = Event.xbutton.x_root - DragX - Scr->IconBorderWidth; + yt = Event.xbutton.y_root - DragY - Scr->IconBorderWidth; + w = DragWidth + 2 * Scr->IconBorderWidth; + h = DragHeight + 2 * Scr->IconBorderWidth; +*/ + XWindowAttributes wat; + + XGetWindowAttributes(dpy, DragWindow, &wat); + xl = Event.xbutton.x_root - DragX - wat.border_width; + yt = Event.xbutton.y_root - DragY - wat.border_width; + w = DragWidth + 2 * wat.border_width; + h = DragHeight + 2 * wat.border_width; + } + + if (ConstMove) + { + if (ConstMoveDir == MOVE_HORIZ) + yt = ConstMoveY; + + if (ConstMoveDir == MOVE_VERT) + xl = ConstMoveX; + + if (ConstMoveDir == MOVE_NONE) + { + yt = ConstMoveY; + xl = ConstMoveX; + } + } + + if (Scr->DontMoveOff && MoveFunction != F_FORCEMOVE) + { + xr = xl + w; + yb = yt + h; + + if (xl < 0) + xl = 0; + if (xr > Scr->MyDisplayWidth) + xl = Scr->MyDisplayWidth - w; + + if (yt < 0) + yt = 0; + if (yb > Scr->MyDisplayHeight) + yt = Scr->MyDisplayHeight - h; + } + + CurrentDragX = xl; + CurrentDragY = yt; + if (DragWindow == Tmp_win->frame) + SetupWindow (Tmp_win, xl, yt, + Tmp_win->frame_width, Tmp_win->frame_height, -1); + else + XMoveWindow (dpy, DragWindow, xl, yt); + +/* djhjr - 4/7/98 + if (!Scr->NoRaiseMove && !Scr->OpaqueMove) * opaque already did * + XRaiseWindow(dpy, DragWindow); +*/ + if (!Scr->NoRaiseMove) + /* opaque already did, so test the individual window, methinks */ + if (DragWindow == Tmp_win->frame) + { + if (!Tmp_win->opaque_move) + XRaiseWindow(dpy, DragWindow); + } + else if (!Scr->OpaqueMove) + XRaiseWindow(dpy, DragWindow); + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + + if (!Scr->OpaqueMove) + UninstallRootColormap(); + else + XSync(dpy, 0); + + if (Scr->NumAutoRaises) { + enter_flag = TRUE; + enter_win = NULL; + raise_win = ((DragWindow == Tmp_win->frame && !Scr->NoRaiseMove) + ? Tmp_win : NULL); + } +#endif + + DragWindow = None; + ConstMove = FALSE; + } + +#ifdef NEVER /* djhjr - 5/27/03 */ + if ( ResizeWindow ) + { + EndResize(); + } +#endif + + if ( ActiveMenu && RootFunction == F_NOFUNCTION ) + { + if ( ActiveItem ) + { + int func = ActiveItem->func; + Action = ActiveItem->action; + switch (func) + { case F_MOVE: + case F_FORCEMOVE: + ButtonPressed = -1; + break; +#if (0) +0 case F_IDENTIFY: +0 case F_CIRCLEUP: +0 case F_CIRCLEDOWN: +0 case F_REFRESH: +0 case F_WARPTOSCREEN: +0 case F_AUTOPAN: /*RFB */ +0 case F_SNAPREALSCREEN:/*RFB*/ +0 PopDownMenu(); +0 break; +#endif + default: + break; + } + ExecuteFunction(func, Action, + ButtonWindow ? ButtonWindow->frame : None, + ButtonWindow, &Event/*&ButtonEvent*/, Context, TRUE); + Context = C_NO_CONTEXT; + ButtonWindow = NULL; + +/* djhjr - 9/15/99 + * if we are not executing a defered command, then take down the + * menu + * + if (RootFunction == F_NOFUNCTION) + { + PopDownMenu(); + } +*/ + } +/* djhjr - 9/15/99 + else +*/ + PopDownMenu(); + } + + mask = (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask); + switch (Event.xbutton.button) + { + case Button1: mask &= ~Button1Mask; break; + case Button2: mask &= ~Button2Mask; break; + case Button3: mask &= ~Button3Mask; break; + case Button4: mask &= ~Button4Mask; break; + case Button5: mask &= ~Button5Mask; break; + } + + if (RootFunction != F_NOFUNCTION || + ResizeWindow != None || + moving_window != None || + DragWindow != None) + { ButtonPressed = -1; + } + + if (RootFunction == F_NOFUNCTION && + (Event.xbutton.state & mask) == 0 && + DragWindow == None && + moving_window == None && + ResizeWindow == None) + { + XUngrabPointer(dpy, CurrentTime); + XUngrabServer(dpy); + XFlush(dpy); + EventHandler[EnterNotify] = HandleEnterNotify; + EventHandler[LeaveNotify] = HandleLeaveNotify; + menuFromFrameOrWindowOrTitlebar = FALSE; + ButtonPressed = -1; + if (DownIconManager) + { + DownIconManager->down = FALSE; + +/* djhjr - 4/19/96 + if (Scr->Highlight) DrawIconManagerBorder(DownIconManager); +*/ + if (Scr->Highlight) DrawIconManagerBorder(DownIconManager, False); + + DownIconManager = NULL; + } + Cancel = FALSE; + } +} + + + +static void do_menu (menu, wnd) + MenuRoot *menu; /* menu to pop up */ + Window wnd; /* invoking window or None */ +{ + int x = Event.xbutton.x_root; + int y = Event.xbutton.y_root; + Bool center = True; + + if (Scr->StayUpMenus) + { GlobalMenuButton = True; + } + + if (!Scr->NoGrabServer) + XGrabServer(dpy); + if (wnd) { + Window child; + /* djhjr - 1/20/98 */ + int w = Scr->TBInfo.width / 2; +/* djhjr - 1/20/98 + int h = Scr->TBInfo.width - Scr->TBInfo.border; +*/ + int h = Scr->TBInfo.width; + +/* djhjr - 1/20/98 + (void) XTranslateCoordinates (dpy, w, Scr->Root, 0, h, &x, &y, &child); +*/ + (void) XTranslateCoordinates (dpy, wnd, Scr->Root, w, h, &x, &y, &child); + +/* djhjr - 1/20/98 + * djhjr - 3/12/97 * + y -= Scr->TitleHeight; +*/ + y -= Scr->TitleHeight / 2; + +/* djhjr - 1/20/98 + center = False; +*/ + } + if (PopUpMenu (menu, x, y, center)) { + UpdateMenu(); + } else { + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + } +} + + + +/*********************************************************************** + * + * Procedure: + * HandleButtonPress - ButtonPress event handler + * + *********************************************************************** + */ +void +HandleButtonPress() +{ + unsigned int modifier; + Cursor cur; + TwmDoor *door = NULL; + + /* Submitted by Jennifer Elaan */ + if (Event.xbutton.button > MAX_BUTTONS) + return; + + if (Scr->StayUpMenus) + { + /* added '&& ButtonPressed == -1' - Submitted by Steve Ratcliffe */ + if (GlobalFirstTime == False && GlobalMenuButton == True + && ButtonPressed == -1) + { + return; + } + } + else + { /* pop down the menu, if any */ + if (ActiveMenu != NULL) PopDownMenu(); + } + + if ( InfoLines ) /* StayUpMenus */ + { +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + PlaySound(S_IUNMAP); +#endif + + XUnmapWindow(dpy, Scr->InfoWindow); + InfoLines = 0; + } + + XSync(dpy, 0); /* XXX - remove? */ + + if (ButtonPressed != -1 + && !InfoLines /* want menus if we have info box */ + ) + { /* we got another butt press in addition to one still held + * down, we need to cancel the operation we were doing + */ + Cancel = TRUE; + if (DragWindow != None) + { + CurrentDragX = origDragX; + CurrentDragY = origDragY; + if (!menuFromFrameOrWindowOrTitlebar) + { + /* added this 'if ... else' - djhjr - 4/7/98 */ + if (Tmp_win && DragWindow == Tmp_win->frame && Tmp_win->opaque_move) + XMoveWindow (dpy, DragWindow, origDragX, origDragY); + else + if (Scr->OpaqueMove && DragWindow != None) + XMoveWindow (dpy, DragWindow, origDragX, origDragY); + else + MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); + } + if (!Scr->OpaqueMove) UninstallRootColormap(); + } + +#if 0 /* done in menus.c:ExecuteFunction() now - djhjr - 11/4/03 */ + /* this 'else if ...' - djhjr - 11/3/03 */ + else if (moving_window) + EndMoveWindowOnDesktop(); +#endif + + XUnmapWindow(dpy, Scr->SizeWindow); + ResizeWindow = None; + DragWindow = None; + cur = LeftButt; + if (Event.xbutton.button == Button2) cur = MiddleButt; + else if (Event.xbutton.button >= Button3) cur = RightButt; + + XGrabPointer(dpy, Scr->Root, True, + ButtonReleaseMask | ButtonPressMask, + GrabModeAsync, GrabModeAsync, + Scr->Root, cur, CurrentTime); + return; + } + else + { ButtonPressed = Event.xbutton.button; + } + + if ( ResizeWindow != None + || DragWindow != None + || moving_window != None + /* ||ActiveMenu != NULL ** tvtwm StayUpMenus */ + ) + { + return; + } + + if ( ButtonPressed == Button1 && Tmp_win && Tmp_win->title_height && Tmp_win->titlebuttons ) + { /* check the title bar buttons */ + register int i; + register TBWindow *tbw; + int nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; + + for (i = 0, tbw = Tmp_win->titlebuttons; i < nb; i++, tbw++) + { + if (Event.xany.window == tbw->window) + { + if (tbw->info->func == F_MENU) + { + Context = C_TITLE; + ButtonEvent = Event; + ButtonWindow = Tmp_win; + do_menu (tbw->info->menuroot, tbw->window); + } + else + { + /* djhjr - 9/15/99 */ + Context = C_TITLE; + + ExecuteFunction (tbw->info->func, tbw->info->action, + Event.xany.window, Tmp_win, &Event, C_TITLE, FALSE); + + /* + * For some reason, we don't get the button up event. + * Submitted by Caveh Frank Jalali + */ + ButtonPressed = -1; + } + + return; + } + } + } + + Context = C_NO_CONTEXT; + if ( Event.xany.window == Scr->InfoWindow ) Context = C_IDENTIFY; + if ( Event.xany.window == Scr->Root ) Context = C_ROOT; + +/* djhjr - 9/12/96 - moved to the bottom of this context decision chain... + if + ( Context == C_NO_CONTEXT + && + ( Tmp_win == Scr->VirtualDesktopDisplayTwin + || + Event.xany.window == Scr->VirtualDesktopDisplayOuter + || + Event.xany.window == Scr->VirtualDesktopDisplay + ) + ) + { TwmWindow *tmp_win; + + if ( Event.xbutton.subwindow + && XFindContext( dpy, Event.xbutton.subwindow, VirtualContext, + (caddr_t *) &tmp_win ) + != XCNOENT + ) + { * Click in a little window in the panner. * + Tmp_win = tmp_win; + Context = C_VIRTUAL_WIN; + } + else + { * Click in the panner. * + Tmp_win = Scr->VirtualDesktopDisplayTwin; + Context = C_VIRTUAL; + } + } +*/ + + if (XFindContext(dpy, Event.xany.window, + DoorContext, (caddr_t *)&door) != XCNOENT) + Context = C_DOOR; + + if ( Tmp_win && Context == C_NO_CONTEXT ) + { +/* have I really determined that this isn't needed? - djhjr - 9/15/99 + if + ( Tmp_win->list + && + RootFunction != F_NOFUNCTION + && + ( Event.xany.window == Tmp_win->list->w + || + Event.xany.window == Tmp_win->list->icon + ) + ) + { + Tmp_win = Tmp_win->list->iconmgr->twm_win; + XTranslateCoordinates(dpy, Event.xany.window, Tmp_win->w, + Event.xbutton.x, Event.xbutton.y, + &JunkX, &JunkY, &JunkChild); + +* djhjr - 4/21/96 + Event.xbutton.x = JunkX; + Event.xbutton.y = JunkY - Tmp_win->title_height; +* + Event.xbutton.x = JunkX - Tmp_win->frame_bw3D; + Event.xbutton.y = JunkY - Tmp_win->title_height - Tmp_win->frame_bw3D; + + Event.xany.window = Tmp_win->w; + Context = C_WINDOW; + } + else +*/ + if ( Event.xany.window == Tmp_win->title_w ) + { + Context = C_TITLE; + } + else if (Event.xany.window == Tmp_win->w) + { + printf("ERROR! ERROR! ERROR! YOU SHOULD NOT BE HERE!!!\n"); + Context = C_WINDOW; + } + else if (Event.xany.window == Tmp_win->icon_w) + { + Context = C_ICON; + } + else if (Event.xany.window == Tmp_win->frame) + { /* since we now place a button grab on the frame instead + * of the window, (see GrabButtons() in add_window.c), we + * need to figure out where the pointer exactly is before + * assigning Context. If the pointer is on the application + * window we will change the event structure to look as if + * it came from the application window. + */ + if (Event.xbutton.subwindow == Tmp_win->w) + { Event.xbutton.window = Tmp_win->w; + +/* djhjr - 4/21/96 + Event.xbutton.y -= Tmp_win->title_height; +*/ + Event.xbutton.x -= Tmp_win->frame_bw3D; + Event.xbutton.y -= (Tmp_win->title_height + Tmp_win->frame_bw3D); + + /***** + Event.xbutton.x -= Tmp_win->frame_bw; + *****/ + Context = C_WINDOW; + } + +/* not needed after all - djhjr - 9/10/99 + * djhjr - 5/13/99 * + else if (Scr->Doors) + { + for (door = Scr->Doors; door != NULL; door = door->next) + if (door->twin->frame == Tmp_win->frame) + { + Context = C_DOOR; + + break; + } + + if (!door) Context = C_FRAME; + } +*/ + + else Context = C_FRAME; + } + else if + ( Tmp_win->list + && + ( Event.xany.window == Tmp_win->list->w + || + Event.xany.window == Tmp_win->list->icon + ) + ) + { + Tmp_win->list->down = TRUE; + +/* djhjr - 4/19/96 + if (Scr->Highlight) DrawIconManagerBorder(Tmp_win->list); +*/ + if (Scr->Highlight) DrawIconManagerBorder(Tmp_win->list, False); + + DownIconManager = Tmp_win->list; + Context = C_ICONMGR; + } + } + +/* djhjr - 9/12/96 - moved from the top of this context decision chain...*/ + if + ( Context == C_NO_CONTEXT + && + ( Tmp_win == Scr->VirtualDesktopDisplayTwin + || + Event.xany.window == Scr->VirtualDesktopDisplayOuter + || + Event.xany.window == Scr->VirtualDesktopDisplay + ) + ) + { TwmWindow *tmp_win; + + if ( Event.xbutton.subwindow + && XFindContext( dpy, Event.xbutton.subwindow, VirtualContext, + (caddr_t *) &tmp_win ) + != XCNOENT + ) + { /* Click in a little window in the panner. */ + Tmp_win = tmp_win; + Context = C_VIRTUAL_WIN; + } + else + { /* Click in the panner. */ + Tmp_win = Scr->VirtualDesktopDisplayTwin; + Context = C_VIRTUAL; + } + } + + /* this section of code checks to see if we were in the middle of + * a command executed from a menu + */ + if (RootFunction != F_NOFUNCTION) + { + if (Event.xany.window == Scr->Root) + { + /* if the window was the Root, we don't know for sure it + * it was the root. We must check to see if it happened to be + * inside of a client that was getting button press events. + */ + XTranslateCoordinates(dpy, Scr->Root, Scr->Root, + Event.xbutton.x, + Event.xbutton.y, + &JunkX, &JunkY, &Event.xany.window); + + if (Event.xany.window == 0 || + XFindContext(dpy, Event.xany.window, TwmContext, + (caddr_t *)&Tmp_win) == XCNOENT) + { + RootFunction = F_NOFUNCTION; + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + + /* + * If stay up menus is set, then the menu may still be active + * and should be popped down - Submitted by Steve Ratcliffe + */ + if (ActiveMenu != NULL) + PopDownMenu(); + + return; + } + + XTranslateCoordinates(dpy, Scr->Root, Event.xany.window, + Event.xbutton.x, + Event.xbutton.y, + &JunkX, &JunkY, &JunkChild); + + Event.xbutton.x = JunkX; + Event.xbutton.y = JunkY; + Context = C_WINDOW; + } + + /* make sure we are not trying to move an identify window */ + if (Scr->InfoWindow && Event.xany.window != Scr->InfoWindow) + { + ExecuteFunction(RootFunction, Action, Event.xany.window, + Tmp_win, &Event, Context, FALSE); + if (Scr->StayUpMenus) + { /* pop down the menu, if any */ + if (ActiveMenu != NULL) PopDownMenu(); + } + } + + RootFunction = F_NOFUNCTION; + return; + } + + ButtonEvent = Event; + ButtonWindow = Tmp_win; + + /* if we get to here, we have to execute a function or pop up a + * menu + */ + modifier = (Event.xbutton.state & mods_used); + + if (Context == C_NO_CONTEXT) return; + + RootFunction = F_NOFUNCTION; + if (Scr->Mouse[Event.xbutton.button][Context][modifier].func == F_MENU) + { + do_menu (Scr->Mouse[Event.xbutton.button][Context][modifier].menu, + (Window) None); + if (Scr->StayUpMenus) + { + GlobalMenuButton = False; + } + } + else if (Scr->Mouse[Event.xbutton.button][Context][modifier].func != F_NOFUNCTION) + { + Action = Scr->Mouse + [Event.xbutton.button][Context][modifier].item + ? Scr->Mouse + [Event.xbutton.button][Context][modifier] + .item->action + : NULL; + ExecuteFunction( Scr->Mouse + [Event.xbutton.button][Context][modifier].func, + Action, Event.xany.window, Tmp_win, &Event, Context, FALSE); + } + else if (Scr->DefaultFunction.func != F_NOFUNCTION) + { + if (Scr->DefaultFunction.func == F_MENU) + { + do_menu (Scr->DefaultFunction.menu, (Window) None); + } + else + { + Action = Scr->DefaultFunction.item + ? Scr->DefaultFunction.item->action + : NULL; + ExecuteFunction(Scr->DefaultFunction.func, Action, + Event.xany.window, Tmp_win, &Event, Context, FALSE); + } + } +} + + + +/*********************************************************************** + * + * Procedure: + * HENQueueScanner - EnterNotify event q scanner + * + * Looks at the queued events and determines if any matching + * LeaveNotify events or EnterEvents deriving from the + * termination of a grab are behind this event to allow + * skipping of unnecessary processing. + * + *********************************************************************** + */ + +typedef struct HENScanArgs { + Window w; /* Window we are currently entering */ + Bool leaves; /* Any LeaveNotifies found for this window */ + Bool inferior; /* Was NotifyInferior the mode for LeaveNotify */ + Bool enters; /* Any EnterNotify events with NotifyUngrab */ +} HENScanArgs; + +/* ARGSUSED*/ +static Bool +HENQueueScanner(dpy, ev, args) + Display *dpy; + XEvent *ev; + char *args; +{ + if (ev->type == LeaveNotify) { + if (ev->xcrossing.window == ((HENScanArgs *) args)->w && + ev->xcrossing.mode == NotifyNormal) { + ((HENScanArgs *) args)->leaves = True; + /* + * Only the last event found matters for the Inferior field. + */ + ((HENScanArgs *) args)->inferior = + (ev->xcrossing.detail == NotifyInferior); + } + } else if (ev->type == EnterNotify) { + if (ev->xcrossing.mode == NotifyUngrab) + ((HENScanArgs *) args)->enters = True; + } + + return (False); +} + + + +/*********************************************************************** + * + * Procedure: + * HandleEnterNotify - EnterNotify event handler + * + *********************************************************************** + */ + +void +HandleEnterNotify() +{ + MenuRoot *mr; + XEnterWindowEvent *ewp = &Event.xcrossing; + HENScanArgs scanArgs; + XEvent dummy; + short l; + extern int RaiseDelay;/*RAISEDELAY*/ + + /* + * Save the id of the window entered. This will be used to remove + * border highlight on entering the next application window. + */ + if (UnHighLight_win && ewp->window != UnHighLight_win->w) { + SetBorder (UnHighLight_win, False); /* application window */ + if (UnHighLight_win->list) /* in the icon box */ + NotActiveIconManager(UnHighLight_win->list); + } + if (ewp->window == Scr->Root) + UnHighLight_win = NULL; + else if (Tmp_win) + UnHighLight_win = Tmp_win; + + /* + * if we aren't in the middle of menu processing + */ + if (!ActiveMenu) { + /* + * We're not interested in pseudo Enter/Leave events generated + * from grab initiations. + */ + if (ewp->mode == NotifyGrab) + return; + + /* + * Scan for Leave and Enter Notify events to see if we can avoid some + * unnecessary processing. + */ + scanArgs.w = ewp->window; + scanArgs.leaves = scanArgs.enters = False; + (void) XCheckIfEvent(dpy, &dummy, HENQueueScanner, (char *) &scanArgs); + + /* + * if it is one of the autopan windows, do the pan + */ + if ( Scr->AutoPanX )/*RFB F_AUTOPAN*/ + for (l = 0; l <= 3; l++) + if (ewp->window == Scr->VirtualDesktopAutoPan[l]) + { + int xdiff, ydiff, xwarp, ywarp; + + /* + * Code from FVWM-1.23b, modified to reflect "real time" + * values of the resource. + * + * djhjr - 9/8/98 + */ + if (Scr->VirtualDesktopPanResistance > 0 && + Scr->VirtualDesktopPanResistance < 10000) + { + int x, y, i; + static struct timeval timeoutval = {0, 12500}; + struct timeval timeout; + + /* The granularity of PanResistance is about 25 ms. + * The timeout variable is set to 12.5 ms since we + * pass this way twice each time an autopan window + * is entered. + */ + for (i = 25; i < Scr->VirtualDesktopPanResistance; i += 25) + { + timeout = timeoutval; + select(0, 0, 0, 0, &timeout); + + scanArgs.w = ewp->window; + scanArgs.leaves = scanArgs.enters = False; + (void)XCheckIfEvent(dpy, &dummy, HENQueueScanner, + (char *)&scanArgs); + + if (scanArgs.leaves) + return; + } + + XQueryPointer(dpy, Scr->Root, &JunkRoot, &JunkChild, + &x, &y, &JunkX, &JunkY, &JunkMask); + + if (x < Scr->AutoPanBorderWidth) + l = 0; + else if (x >= Scr->MyDisplayWidth - Scr->AutoPanBorderWidth) + l = 1; + else if (y < Scr->AutoPanBorderWidth) + l = 2; + else if (y >= Scr->MyDisplayHeight - Scr->AutoPanBorderWidth) + l = 3; + else + l = 4; /* oops */ + } + + /* figure out which one it is */ + switch (l) + { + case 0: /* left */ + xdiff = -(Scr->AutoPanX); + ydiff = 0; + /* xwarp = AP_SIZE + 2; */ + xwarp = AP_SIZE + Scr->AutoPanExtraWarp; /* DSE */ + ywarp = 0; + break; + case 1: /* right */ + xdiff = Scr->AutoPanX; + ydiff = 0; + /* xwarp = -(AP_SIZE + 2); */ + xwarp = -(AP_SIZE + Scr->AutoPanExtraWarp); /* DSE */ + ywarp = 0; + break; + case 2: /* up */ + xdiff = 0; + ydiff = -(Scr->AutoPanY); + xwarp = 0; + /* ywarp = AP_SIZE + 2; */ + ywarp = AP_SIZE + Scr->AutoPanExtraWarp; /* DSE */ + break; + case 3: /* down */ + xdiff = 0; + ydiff = Scr->AutoPanY; + xwarp = 0; + /* ywarp = -(AP_SIZE + 2); */ + ywarp = -(AP_SIZE + Scr->AutoPanExtraWarp); /* DSE */ + break; + default: /* oops */ + /* this is to stop the compiler complaining */ + xdiff = ydiff = xwarp = ywarp = 0; +/* not with the PanResistance resource! - djhjr - 9/8/98 + fprintf(stderr, "vtwm: major problems with autopan\n"); +*/ + } + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + PlaySound(S_APAN); +#endif + + /* do the pan */ + PanRealScreen(xdiff, ydiff, &xwarp, &ywarp); /* DSE */ + + /* + * warp the pointer out of the window so that they can keep + * moving the mouse + */ + XWarpPointer(dpy, None, None, 0, 0, 0, 0, xwarp, ywarp); + + return; + } /* end if ewp->window = autopan */ + + /* + * if entering root window, restore twm default colormap so that + * titlebars are legible + */ + if (ewp->window == Scr->Root) { + if (!scanArgs.leaves && !scanArgs.enters) + InstallWindowColormaps(EnterNotify, &Scr->TwmRoot); + return; + } + +/*RAISEDELAY*/ /* Handle RaiseDelay, if any..... */ +/*RAISEDELAY*/ if (RaiseDelay > 0) { +/*RAISEDELAY*/ if (Tmp_win && Tmp_win->auto_raise +/*RAISEDELAY*/ && (!Tmp_win->list || Tmp_win->list->w != ewp->window)) { +/*RAISEDELAY*/ ColormapWindow *cwin; + +#ifdef NEVER +/*RAISEDELAY*/ static struct timeval timeout = {0,12500}; +#else +/* + * Submitted by Steve Ratcliffe + */ +/*RAISEDELAY*/ static struct timeval timeoutval = {0,12500}; +/*RAISEDELAY*/ struct timeval timeout; +#endif + +/*RAISEDELAY*/ +/*RAISEDELAY*/ if (XFindContext(dpy, Tmp_win->w, ColormapContext, +/*RAISEDELAY*/ (caddr_t *)&cwin) == XCNOENT) { +/*RAISEDELAY*/ cwin = (ColormapWindow *)NULL; +/*RAISEDELAY*/ } +/*RAISEDELAY*/ +/*RAISEDELAY*/ if ((ewp->detail != NotifyInferior +/*RAISEDELAY*/ || Tmp_win->frame == ewp->window) +/*RAISEDELAY*/ && (!cwin || cwin->visibility != VisibilityUnobscured)) { +/*RAISEDELAY*/ int x, y, px, py, d, i; +/*RAISEDELAY*/ Window w; +/*RAISEDELAY*/ +/*RAISEDELAY*/ XQueryPointer(dpy, Scr->Root, &w, &w, &px, &py, +/*RAISEDELAY*/ &d, &d, (unsigned int *)&d); +/*RAISEDELAY*/ +/*RAISEDELAY*/ /* The granularity of RaiseDelay is about 25 ms. + * The timeout variable is set to 12.5 ms since we + * pass this way twice each time a twm window is + * entered. + */ +/*RAISEDELAY*/ for (i = 25; i < RaiseDelay; i += 25) { + +/* + * Submitted by Steve Ratcliffe + */ +/*RAISEDELAY*/ /* The timeout needs initialising each time on Linux */ +/*RAISEDELAY*/ timeout = timeoutval; + +/*RAISEDELAY*/ select(0, 0, 0, 0, &timeout); +/*RAISEDELAY*/ /* Did we leave this window already? */ +/*RAISEDELAY*/ scanArgs.w = ewp->window; +/*RAISEDELAY*/ scanArgs.leaves = scanArgs.enters = False; +/*RAISEDELAY*/ (void) XCheckIfEvent(dpy, &dummy, HENQueueScanner, +/*RAISEDELAY*/ (char *) &scanArgs); +/*RAISEDELAY*/ if (scanArgs.leaves && !scanArgs.inferior) return; +/*RAISEDELAY*/ +/*RAISEDELAY*/ XQueryPointer(dpy, Scr->Root, &w, &w, &x, &y, +/*RAISEDELAY*/ &d, &d, (unsigned int *)&d); +/*RAISEDELAY*/ +/*RAISEDELAY*/ /* Has the pointer moved? If so reset the loop cnt. + * We want the pointer to be still for RaiseDelay + * milliseconds before terminating the loop + */ +/*RAISEDELAY*/ if (x != px || y != py) { +/*RAISEDELAY*/ i = 0; px = x; py = y; +/*RAISEDELAY*/ } +/*RAISEDELAY*/ } +/*RAISEDELAY*/ } +/*RAISEDELAY*/ } +/*RAISEDELAY*/ +/*RAISEDELAY*/ /* + * Scan for Leave and Enter Notify events to see if we can avoid some + * unnecessary processing. + */ +/*RAISEDELAY*/ scanArgs.w = ewp->window; +/*RAISEDELAY*/ scanArgs.leaves = scanArgs.enters = False; +/*RAISEDELAY*/ (void) XCheckIfEvent(dpy, &dummy, HENQueueScanner, (char *) &scanArgs); +/*RAISEDELAY*/ +/*RAISEDELAY*/ /* + * if entering root window, restore twm default colormap so that + * titlebars are legible + */ +/*RAISEDELAY*/ if (ewp->window == Scr->Root) { +/*RAISEDELAY*/ if (!scanArgs.leaves && !scanArgs.enters) +/*RAISEDELAY*/ InstallWindowColormaps(EnterNotify, &Scr->TwmRoot); +/*RAISEDELAY*/ return; +/*RAISEDELAY*/ } +/*RAISEDELAY*/ } +/*RAISEDELAY*/ /* End of RaiseDelay modification. */ + + /* + * if we have an event for a specific one of our windows + */ + if (Tmp_win) { + /* + * If currently in PointerRoot mode (indicated by FocusRoot), then + * focus on this window + */ + if (Scr->FocusRoot && (!scanArgs.leaves || scanArgs.inferior)) { + if (Tmp_win->list) ActiveIconManager(Tmp_win->list); + + if (Tmp_win->mapped) { + /* + * unhighlight old focus window + */ + +/* djhjr - 4/25/96 + if (Scr->Focus && Scr->Focus != Tmp_win && Tmp_win->hilite_w) + XUnmapWindow(dpy, Scr->Focus->hilite_w); +*/ + if (Scr->Focus && Scr->Focus != Tmp_win) + PaintTitleHighlight(Scr->Focus, off); + + /* + * If entering the frame or the icon manager, then do + * "window activation things": + * + * 1. turn on highlight window (if any) + * 2. install frame colormap + * 3. set frame and highlight window (if any) border + * 3a. set titlebutton highlight (if button color is frame) + * if IconManagerFocus is set or not in icon mgr + * 4. focus on client window to forward typing + * 4a. same as 4 but for icon mgr and/or NoTitlebar set + * 5. send WM_TAKE_FOCUS if requested + */ + if (ewp->window == Tmp_win->frame || + (Tmp_win->list && ewp->window == Tmp_win->list->w)) { + +/* djhjr - 4/25/96 + if (Tmp_win->hilite_w) * 1 * + XMapWindow (dpy, Tmp_win->hilite_w); +*/ + PaintTitleHighlight(Tmp_win, on); /* 1 */ + + if (!scanArgs.leaves && !scanArgs.enters) /* 2 */ + InstallWindowColormaps (EnterNotify, + &Scr->TwmRoot); + SetBorder (Tmp_win, True); /* 3, 3a */ + + /* added this 'if()' - djhjr - 5/27/98 */ + /* added hack for StrictIconManager - djhjr - 10/2/01 */ + /* added test for transients - djhjr - 4/9/02 */ + if (Scr->IconManagerFocus || + (Scr->FocusRoot && + Scr->StrictIconManager && + !Tmp_win->list) || + (Tmp_win->list && Tmp_win->list->w && + Tmp_win->list->w != ewp->window) || + Tmp_win->transient) + { + /* added test for transients - djhjr - 4/9/02 */ + if ((((Tmp_win->title_w || Scr->NoTitlebar) && /* 4, 4a */ + Scr->TitleFocus) || + Tmp_win->transient) && + Tmp_win->wmhints && + Tmp_win->wmhints->input) + SetFocus (Tmp_win, ewp->time); + } + + if (Tmp_win->protocols & DoesWmTakeFocus) /* 5 */ + SendTakeFocusMessage (Tmp_win, ewp->time); + Scr->Focus = Tmp_win; + } else if (ewp->window == Tmp_win->w) { + /* + * If we are entering the application window, install + * its colormap(s). + */ + if (!scanArgs.leaves || scanArgs.inferior) + InstallWindowColormaps(EnterNotify, Tmp_win); + } + } /* end if Tmp_win->mapped */ + if (Tmp_win->wmhints != NULL && + ewp->window == Tmp_win->wmhints->icon_window && + (!scanArgs.leaves || scanArgs.inferior)) + InstallWindowColormaps(EnterNotify, Tmp_win); + } /* end if FocusRoot */ + /* + * If this window is to be autoraised, mark it so + */ + if (Tmp_win->auto_raise) { + enter_win = Tmp_win; + if (enter_flag == FALSE) AutoRaiseWindow (Tmp_win); + } else if (enter_flag && raise_win == Tmp_win) + enter_win = Tmp_win; + /* + * set ring leader + */ + if (Tmp_win->ring.next && (!enter_flag || raise_win == enter_win)) + { + /* + * If this window is an icon manager window, make + * the ring leader the icon manager - djhjr - 11/8/01 + * + * Is the icon manager in the ring? - djhjr - 10/27/02 + */ + if (Tmp_win->list && ewp->window == Tmp_win->list->w && + Tmp_win->list->iconmgr->twm_win->ring.next) + { + Scr->RingLeader = Tmp_win->list->iconmgr->twm_win; + } + else + Scr->RingLeader = Tmp_win; + } + XSync (dpy, 0); + return; + } /* end if Tmp_win */ + } /* end if !ActiveMenu */ + + /* + * Find the menu that we are dealing with now; punt if unknown + */ + if (XFindContext (dpy, ewp->window, MenuContext, (caddr_t *)&mr) != XCSUCCESS) return; + + mr->entered = TRUE; +/* djhjr - 4/23/96 + if (ActiveMenu && mr == ActiveMenu->prev && RootFunction == F_NOFUNCTION) { + if (Scr->Shadow) XUnmapWindow (dpy, ActiveMenu->shadow); + XUnmapWindow (dpy, ActiveMenu->w); + ActiveMenu->mapped = UNMAPPED; + UninstallRootColormap (); + if (ActiveItem) { + ActiveItem->state = 0; + PaintEntry (ActiveMenu, ActiveItem, False); + } + ActiveItem = NULL; + ActiveMenu = mr; + MenuDepth--; + } +*/ + if (RootFunction == F_NOFUNCTION) { + MenuRoot *tmp; + for (tmp = ActiveMenu; tmp; tmp = tmp->prev) { + if (tmp == mr) break; + } + if (! tmp) return; + for (tmp = ActiveMenu; tmp != mr; tmp = tmp->prev) { + /* all 'tmp' were 'ActiveMenu'... DUH! - djhjr - 11/16/98 */ + if (Scr->Shadow) XUnmapWindow (dpy, tmp->shadow); + XUnmapWindow (dpy, tmp->w); + tmp->mapped = UNMAPPED; + MenuDepth--; + } + UninstallRootColormap (); + if (ActiveItem) { + ActiveItem->state = 0; + PaintEntry (ActiveMenu, ActiveItem, False); + } + ActiveItem = NULL; + ActiveMenu = mr; + } + + return; +} + + + +/*********************************************************************** + * + * Procedure: + * HLNQueueScanner - LeaveNotify event q scanner + * + * Looks at the queued events and determines if any + * EnterNotify events are behind this event to allow + * skipping of unnecessary processing. + * + *********************************************************************** + */ + +typedef struct HLNScanArgs { + Window w; /* The window getting the LeaveNotify */ + Bool enters; /* Any EnterNotify event at all */ + Bool matches; /* Any matching EnterNotify events */ +} HLNScanArgs; + +/* ARGSUSED*/ +static Bool +HLNQueueScanner(dpy, ev, args) + Display *dpy; + XEvent *ev; + char *args; +{ + if (ev->type == EnterNotify && ev->xcrossing.mode != NotifyGrab) { + ((HLNScanArgs *) args)->enters = True; + if (ev->xcrossing.window == ((HLNScanArgs *) args)->w) + ((HLNScanArgs *) args)->matches = True; + } + + return (False); +} + + + +/*********************************************************************** + * + * Procedure: + * HandleLeaveNotify - LeaveNotify event handler + * + *********************************************************************** + */ + +void +HandleLeaveNotify() +{ + HLNScanArgs scanArgs; + XEvent dummy; + + if (Tmp_win != NULL) + { + Bool inicon; + + /* + * We're not interested in pseudo Enter/Leave events generated + * from grab initiations and terminations. + */ + if (Event.xcrossing.mode != NotifyNormal) + return; + + inicon = (Tmp_win->list && + Tmp_win->list->w == Event.xcrossing.window); + +/* + * rem'ing this allows the window crossed out of onto the root window + * to be remembered, so an f.warpring event occuring on the root window + * will return to that window (see WarpAlongRing() in menus.c). + * + * no, I don't fully understand... djhjr - 5/11/98 + * + if (Scr->RingLeader && Scr->RingLeader == Tmp_win && + (Event.xcrossing.detail != NotifyInferior && + Event.xcrossing.window != Tmp_win->w)) { + +#ifdef ORIGINAL_WARPRINGCOORDINATES * djhjr - 5/11/98 * + if (!inicon) { + if (Tmp_win->mapped) { + Tmp_win->ring.cursor_valid = False; + } else { + Tmp_win->ring.cursor_valid = True; + Tmp_win->ring.curs_x = (Event.xcrossing.x_root - + Tmp_win->frame_x); + Tmp_win->ring.curs_y = (Event.xcrossing.y_root - + Tmp_win->frame_y); + } + } +#endif + + Scr->RingLeader = (TwmWindow *) NULL; + } +*/ + + if (Scr->FocusRoot) { + + if (Event.xcrossing.detail != NotifyInferior) { + + /* + * Scan for EnterNotify events to see if we can avoid some + * unnecessary processing. + */ + scanArgs.w = Event.xcrossing.window; + scanArgs.enters = scanArgs.matches = False; + (void) XCheckIfEvent(dpy, &dummy, HLNQueueScanner, + (char *) &scanArgs); + + if ((Event.xcrossing.window == Tmp_win->frame && + !scanArgs.matches) || inicon) { + if (Tmp_win->list) NotActiveIconManager(Tmp_win->list); + +/* djhjr - 4/25/96 + if (Tmp_win->hilite_w) + XUnmapWindow (dpy, Tmp_win->hilite_w); +*/ + PaintTitleHighlight(Tmp_win, off); + + SetBorder (Tmp_win, False); + if (Scr->TitleFocus || + Tmp_win->protocols & DoesWmTakeFocus) + SetFocus ((TwmWindow *) NULL, Event.xcrossing.time); + Scr->Focus = NULL; + } else if (Event.xcrossing.window == Tmp_win->w && + !scanArgs.enters) { + InstallWindowColormaps (LeaveNotify, &Scr->TwmRoot); + } + } + } + XSync (dpy, 0); + return; + } +} + + + +/*********************************************************************** + * + * Procedure: + * HandleConfigureRequest - ConfigureRequest event handler + * + *********************************************************************** + */ + +void +HandleConfigureRequest() +{ + XWindowChanges xwc; + unsigned long xwcm; + int x, y, width, height, bw; + int gravx, gravy; + XConfigureRequestEvent *cre = &Event.xconfigurerequest; + +#ifdef DEBUG_EVENTS + fprintf(stderr, "ConfigureRequest\n"); + if (cre->value_mask & CWX) + fprintf(stderr, " x = %d\n", cre->x); + if (cre->value_mask & CWY) + fprintf(stderr, " y = %d\n", cre->y); + if (cre->value_mask & CWWidth) + fprintf(stderr, " width = %d\n", cre->width); + if (cre->value_mask & CWHeight) + fprintf(stderr, " height = %d\n", cre->height); + if (cre->value_mask & CWSibling) + fprintf(stderr, " above = 0x%x\n", cre->above); + if (cre->value_mask & CWStackMode) + fprintf(stderr, " stack = %d\n", cre->detail); +#endif + + /* + * Event.xany.window is Event.xconfigurerequest.parent, so Tmp_win will + * be wrong + */ + Event.xany.window = cre->window; /* mash parent field */ + if (XFindContext (dpy, cre->window, TwmContext, (caddr_t *) &Tmp_win) == + XCNOENT) + Tmp_win = NULL; + + + /* + * According to the July 27, 1988 ICCCM draft, we should ignore size and + * position fields in the WM_NORMAL_HINTS property when we map a window. + * Instead, we'll read the current geometry. Therefore, we should respond + * to configuration requests for windows which have never been mapped. + */ + if (!Tmp_win || Tmp_win->icon_w == cre->window) { + xwcm = cre->value_mask & + (CWX | CWY | CWWidth | CWHeight | CWBorderWidth); + xwc.x = cre->x; + xwc.y = cre->y; + xwc.width = cre->width; + xwc.height = cre->height; + xwc.border_width = cre->border_width; + XConfigureWindow(dpy, Event.xany.window, xwcm, &xwc); + return; + } + + if ((cre->value_mask & CWStackMode) && Tmp_win->stackmode) { + TwmWindow *otherwin; + + xwc.sibling = (((cre->value_mask & CWSibling) && + (XFindContext (dpy, cre->above, TwmContext, + (caddr_t *) &otherwin) == XCSUCCESS)) + ? otherwin->frame : cre->above); + xwc.stack_mode = cre->detail; + XConfigureWindow (dpy, Tmp_win->frame, + cre->value_mask & (CWSibling | CWStackMode), &xwc); + } + + + /* Don't modify frame_XXX fields before calling SetupWindow! */ + x = Tmp_win->frame_x; + y = Tmp_win->frame_y; + width = Tmp_win->frame_width; + height = Tmp_win->frame_height; + bw = Tmp_win->frame_bw; + + /* + * Section 4.1.5 of the ICCCM states that the (x,y) coordinates in the + * configure request are for the upper-left outer corner of the window. + * This means that we need to adjust for the additional title height as + * well as for any border width changes that we decide to allow. The + * current window gravity is to be used in computing the adjustments, just + * as when initially locating the window. Note that if we do decide to + * allow border width changes, we will need to send the synthetic + * ConfigureNotify event. + */ + GetGravityOffsets (Tmp_win, &gravx, &gravy); + + if (cre->value_mask & CWBorderWidth) { + int bwdelta = cre->border_width - Tmp_win->old_bw; /* posit growth */ + if (bwdelta && Scr->ClientBorderWidth) { /* if change allowed */ + x += gravx * bwdelta; /* change default values only */ + y += gravy * bwdelta; /* ditto */ + bw = cre->border_width; + if (Tmp_win->title_height) height += bwdelta; + x += (gravx < 0) ? bwdelta : -bwdelta; + y += (gravy < 0) ? bwdelta : -bwdelta; + } + Tmp_win->old_bw = cre->border_width; /* for restoring */ + } + + if (cre->value_mask & CWX) { /* override even if border change */ + x = cre->x - bw; + + /* djhjr - 4/21/96 */ + x -= ((gravx < 0) ? 0 : Tmp_win->frame_bw3D); + + } + if (cre->value_mask & CWY) { + y = cre->y - ((gravy < 0) ? 0 : Tmp_win->title_height) - bw; + + /* djhjr - 4/21/96 */ + y -= ((gravy < 0) ? 0 : Tmp_win->frame_bw3D); + + } + + if (cre->value_mask & CWWidth) { + +/* djhjr - 4/21/96 + width = cre->width; +*/ + width = cre->width + 2 * Tmp_win->frame_bw3D; + + } + if (cre->value_mask & CWHeight) { + +/* djhjr - 4/21/96 + height = cre->height + Tmp_win->title_height; +*/ + height = cre->height + Tmp_win->title_height + 2 * Tmp_win->frame_bw3D; + + } + + if (width != Tmp_win->frame_width || height != Tmp_win->frame_height) + Tmp_win->zoomed = ZOOM_NONE; + + /* + * SetupWindow (x,y) are the location of the upper-left outer corner and + * are passed directly to XMoveResizeWindow (frame). The (width,height) + * are the inner size of the frame. The inner width is the same as the + * requested client window width; the inner height is the same as the + * requested client window height plus any title bar slop. + */ +/* propogate ConfigureNotify events - submitted by Jonathan Paisley - 11/11/02 + SetupWindow (Tmp_win, x, y, width, height, bw); +*/ + SetupFrame(Tmp_win, x, y, width, height, bw, True); + + /* Change the size of the desktop representation */ + MoveResizeDesktop (Tmp_win, TRUE); + + /* + * Raise the autopan windows in case the current window covers them. + * Submitted by Steve Ratcliffe + */ + RaiseAutoPan(); +} + + + +/*********************************************************************** + * + * Procedure: + * HandleShapeNotify - shape notification event handler + * + *********************************************************************** + */ +void +HandleShapeNotify () +{ + XShapeEvent *sev = (XShapeEvent *) &Event; + + if (Tmp_win == NULL) + return; + if (sev->kind != ShapeBounding) + return; + if (!Tmp_win->wShaped && sev->shaped) { + XShapeCombineMask (dpy, Tmp_win->frame, ShapeClip, 0, 0, None, + ShapeSet); + } + Tmp_win->wShaped = sev->shaped; + SetFrameShape (Tmp_win); +} + + + +/*********************************************************************** + * + * Procedure: + * HandleUnknown - unknown event handler + * + *********************************************************************** + */ + +void +HandleUnknown() +{ +#ifdef DEBUG_EVENTS + fprintf(stderr, "type = %d\n", Event.type); +#endif +} + + + +/*********************************************************************** + * + * Procedure: + * Transient - checks to see if the window is a transient + * + * Returned Value: + * TRUE - window is a transient + * FALSE - window is not a transient + * + * Inputs: + * w - the window to check + * + *********************************************************************** + */ + +int +Transient(w, propw) + Window w, *propw; +{ + return (XGetTransientForHint(dpy, w, propw)); +} + + + +/*********************************************************************** + * + * Procedure: + * FindScreenInfo - get ScreenInfo struct associated with a given window + * + * Returned Value: + * ScreenInfo struct + * + * Inputs: + * w - the window + * + *********************************************************************** + */ + +ScreenInfo * +FindScreenInfo(w) + Window w; +{ + XWindowAttributes attr; + int scrnum; + + attr.screen = NULL; + if (XGetWindowAttributes(dpy, w, &attr)) { + for (scrnum = 0; scrnum < NumScreens; scrnum++) { + if (ScreenList[scrnum] != NULL && + (ScreenOfDisplay(dpy, ScreenList[scrnum]->screen) == + attr.screen)) + return ScreenList[scrnum]; + } + } + + return NULL; +} + + + +static void flush_expose (w) + Window w; +{ + XEvent dummy; + + /* SUPPRESS 530 */ + while (XCheckTypedWindowEvent (dpy, w, Expose, &dummy)) ; +} + + + +/*********************************************************************** + * + * Procedure: + * InstallWindowColormaps - install the colormaps for one twm window + * + * Inputs: + * type - type of event that caused the installation + * tmp - for a subset of event types, the address of the + * window structure, whose colormaps are to be installed. + * + *********************************************************************** + */ + +void InstallWindowColormaps (type, tmp) + int type; + TwmWindow *tmp; +{ + int i, j, n, number_cwins, state; + ColormapWindow **cwins, *cwin, **maxcwin = NULL; + TwmColormap *cmap; + char *row, *scoreboard; + + switch (type) { + case EnterNotify: + case LeaveNotify: + case DestroyNotify: + default: + /* Save the colormap to be loaded for when force loading of + * root colormap(s) ends. + */ + Scr->cmapInfo.pushed_window = tmp; + /* Don't load any new colormap if root colormap(s) has been + * force loaded. + */ + if (Scr->cmapInfo.root_pushes) + return; + /* Don't reload the currend window colormap list. + */ + if (Scr->cmapInfo.cmaps == &tmp->cmaps) + return; + if (Scr->cmapInfo.cmaps) + for (i = Scr->cmapInfo.cmaps->number_cwins, + cwins = Scr->cmapInfo.cmaps->cwins; i-- > 0; cwins++) + (*cwins)->colormap->state &= ~CM_INSTALLABLE; + Scr->cmapInfo.cmaps = &tmp->cmaps; + break; + + case PropertyNotify: + case VisibilityNotify: + case ColormapNotify: + break; + } + + number_cwins = Scr->cmapInfo.cmaps->number_cwins; + cwins = Scr->cmapInfo.cmaps->cwins; + scoreboard = Scr->cmapInfo.cmaps->scoreboard; + + ColortableThrashing = FALSE; /* in case installation aborted */ + + state = CM_INSTALLED; + +/* + * Submitted by Caveh Frank Jalali + * + for (i = n = 0; i < number_cwins + && n < Scr->cmapInfo.maxCmaps +*/ + for (i = 0; i < number_cwins + + /* comp.windows.x + ** Article <21sn92INNbiv@sirius.isi.com> Mon 18:06 + ** Path: ..!news.isi.com!not-for-mail (Mark Kent @ + ** Integrated Systems, Inc.) + */ + ; i++) { + cwin = cwins[i]; + cmap = cwin->colormap; + cmap->state |= CM_INSTALLABLE; + cmap->state &= ~CM_INSTALL; + cmap->w = cwin->w; + } + for (i = n = 0; i < number_cwins; i++) { + cwin = cwins[i]; + cmap = cwin->colormap; + if (cwin->visibility != VisibilityFullyObscured + /* && n < Scr->cmapInfo.maxCmaps + ** <21sn92INNbiv@sirius.isi.com> + */ + ) { + row = scoreboard + (i*(i-1)/2); + for (j = 0; j < i; j++) + if (row[j] && (cwins[j]->colormap->state & CM_INSTALL)) + break; + if (j != i) + continue; + n++; + maxcwin = &cwins[i]; + state &= (cmap->state & CM_INSTALLED); + cmap->state |= CM_INSTALL; + } + } + + Scr->cmapInfo.first_req = NextRequest(dpy); + +/* + * Submitted by Caveh Frank Jalali + * + for ( ; n > 0; maxcwin--) { +*/ + for ( ; n > 0; n--, maxcwin--) { + + cmap = (*maxcwin)->colormap; + if (cmap->state & CM_INSTALL) { + cmap->state &= ~CM_INSTALL; + if (!(state & CM_INSTALLED)) { + cmap->install_req = NextRequest(dpy); + XInstallColormap(dpy, cmap->c); + } + cmap->state |= CM_INSTALLED; +/* see above 'for (...)' + n--; +*/ + } + } +} + + + +/*********************************************************************** + * + * Procedures: + * nstallRootColormap - Force (un)loads root colormap(s) + * + * These matching routines provide a mechanism to insure that + * the root colormap(s) is installed during operations like + * rubber banding or menu display that require colors from + * that colormap. Calls may be nested arbitrarily deeply, + * as long as there is one UninstallRootColormap call per + * InstallRootColormap call. + * + * The final UninstallRootColormap will cause the colormap list + * which would otherwise have be loaded to be loaded, unless + * Enter or Leave Notify events are queued, indicating some + * other colormap list would potentially be loaded anyway. + *********************************************************************** + */ + +void InstallRootColormap() +{ + TwmWindow *tmp; + if (Scr->cmapInfo.root_pushes == 0) { + /* + * The saving and restoring of cmapInfo.pushed_window here + * is a slimy way to remember the actual pushed list and + * not that of the root window. + */ + tmp = Scr->cmapInfo.pushed_window; + InstallWindowColormaps(0, &Scr->TwmRoot); + Scr->cmapInfo.pushed_window = tmp; + } + Scr->cmapInfo.root_pushes++; +} + + + +/* ARGSUSED*/ +static Bool +UninstallRootColormapQScanner(dpy, ev, args) + Display *dpy; + XEvent *ev; + char *args; +{ + if (!*args) + { + if (ev->type == EnterNotify) { + if (ev->xcrossing.mode != NotifyGrab) + *args = 1; + } else if (ev->type == LeaveNotify) { + if (ev->xcrossing.mode == NotifyNormal) + *args = 1; + } + } + + return (False); +} + + + +void UninstallRootColormap() +{ + char args; + XEvent dummy; + + if (Scr->cmapInfo.root_pushes) + Scr->cmapInfo.root_pushes--; + + if (!Scr->cmapInfo.root_pushes) { + /* + * If we have subsequent Enter or Leave Notify events, + * we can skip the reload of pushed colormaps. + */ + XSync (dpy, 0); + args = 0; + (void) XCheckIfEvent(dpy, &dummy, UninstallRootColormapQScanner, &args); + + if (!args) + InstallWindowColormaps(0, Scr->cmapInfo.pushed_window); + } +} + +void SendConfigureNotify(tmp_win, x, y) +TwmWindow *tmp_win; +int x, y; +{ + XEvent client_event; + + client_event.type = ConfigureNotify; + client_event.xconfigure.display = dpy; + client_event.xconfigure.event = tmp_win->w; + client_event.xconfigure.window = tmp_win->w; + +/* djhjr - 4/24/96 + client_event.xconfigure.x = (x + tmp_win->frame_bw - tmp_win->old_bw); + client_event.xconfigure.y = (y + tmp_win->frame_bw + + tmp_win->title_height - tmp_win->old_bw); + client_event.xconfigure.width = tmp_win->frame_width; + client_event.xconfigure.height = tmp_win->frame_height - + tmp_win->title_height; +*/ + client_event.xconfigure.x = (x + tmp_win->frame_bw - tmp_win->old_bw + + tmp_win->frame_bw3D); + client_event.xconfigure.y = (y + tmp_win->frame_bw + + tmp_win->title_height - tmp_win->old_bw + + tmp_win->frame_bw3D); + client_event.xconfigure.width = tmp_win->attr.width; + client_event.xconfigure.height = tmp_win->attr.height; + + client_event.xconfigure.border_width = tmp_win->old_bw; + /* Real ConfigureNotify events say we're above title window, so ... */ + /* what if we don't have a title ????? */ + client_event.xconfigure.above = tmp_win->frame; + client_event.xconfigure.override_redirect = False; + + XSendEvent(dpy, tmp_win->w, False, StructureNotifyMask, &client_event); +} + +#ifdef TRACE +dumpevent (e) + XEvent *e; +{ + char *name = NULL; + + switch (e->type) { + case KeyPress: name = "KeyPress"; break; + case KeyRelease: name = "KeyRelease"; break; + case ButtonPress: name = "ButtonPress"; break; + case ButtonRelease: name = "ButtonRelease"; break; + case MotionNotify: name = "MotionNotify"; break; + case EnterNotify: name = "EnterNotify"; break; + case LeaveNotify: name = "LeaveNotify"; break; + case FocusIn: name = "FocusIn"; break; + case FocusOut: name = "FocusOut"; break; + case KeymapNotify: name = "KeymapNotify"; break; + case Expose: name = "Expose"; break; + case GraphicsExpose: name = "GraphicsExpose"; break; + case NoExpose: name = "NoExpose"; break; + case VisibilityNotify: name = "VisibilityNotify"; break; + case CreateNotify: name = "CreateNotify"; break; + case DestroyNotify: name = "DestroyNotify"; break; + case UnmapNotify: name = "UnmapNotify"; break; + case MapNotify: name = "MapNotify"; break; + case MapRequest: name = "MapRequest"; break; + case ReparentNotify: name = "ReparentNotify"; break; + case ConfigureNotify: name = "ConfigureNotify"; break; + case ConfigureRequest: name = "ConfigureRequest"; break; + case GravityNotify: name = "GravityNotify"; break; + case ResizeRequest: name = "ResizeRequest"; break; + case CirculateNotify: name = "CirculateNotify"; break; + case CirculateRequest: name = "CirculateRequest"; break; + case PropertyNotify: name = "PropertyNotify"; break; + case SelectionClear: name = "SelectionClear"; break; + case SelectionRequest: name = "SelectionRequest"; break; + case SelectionNotify: name = "SelectionNotify"; break; + case ColormapNotify: name = "ColormapNotify"; break; + case ClientMessage: name = "ClientMessage"; break; + case MappingNotify: name = "MappingNotify"; break; + } + + if (name) { + printf ("event: %s, %d remaining\n", name, QLength(dpy)); + } else { + printf ("unknown event %d, %d remaining\n", e->type, QLength(dpy)); + } +} +#endif /* TRACE */ + diff --git a/events.h b/events.h new file mode 100644 index 0000000..8d42304 --- /dev/null +++ b/events.h @@ -0,0 +1,96 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/*********************************************************************** + * + * $XConsortium: events.h,v 1.14 91/05/10 17:53:58 dave Exp $ + * + * twm event handler include file + * + * 17-Nov-87 Thomas E. LaStrange File created + * + ***********************************************************************/ + +#ifndef _EVENTS_ +#define _EVENTS_ + +typedef void (*event_proc)(); + +extern void InitEvents(); +extern Bool StashEventTime(); +extern Time lastTimestamp; +extern void SimulateMapRequest(); +extern void AutoRaiseWindow(); +#define LastTimestamp() lastTimestamp +extern Bool DispatchEvent(); +/* depreciated - djhjr - 10/6/02 +extern Bool DispatchEvent2(); +*/ +extern void HandleEvents(); +extern void HandleExpose(); +extern void HandleDestroyNotify(); +extern void HandleMapRequest(); +extern void HandleMapNotify(); +extern void HandleUnmapNotify(); +extern void HandleMotionNotify(); +extern void HandleButtonRelease(); +extern void HandleButtonPress(); +extern void HandleEnterNotify(); +extern void HandleLeaveNotify(); +extern void HandleConfigureRequest(); +extern void HandleClientMessage(); +extern void HandlePropertyNotify(); +extern void HandleKeyPress(); +extern void HandleColormapNotify(); +extern void HandleVisibilityNotify(); +extern void HandleUnknown(); +extern void SendConfigureNotify(); +extern void InstallRootColormap(); +extern int Transient(); +extern void UninstallRootColormap(); +extern void InstallWindowColormaps(); +extern void RedoDoorName(); /* djhjr - 2/28/99 */ +extern void RedoListWindow(); /* djhjr - 3/1/99 */ + +extern event_proc EventHandler[]; +extern Window DragWindow; +extern int origDragX; +extern int origDragY; +extern int DragX; +extern int DragY; +extern int DragWidth; +extern int DragHeight; +extern int CurrentDragX; +extern int CurrentDragY; + +extern int ButtonPressed; +extern int Cancel; + +extern XEvent Event; + +#endif /* _EVENTS_ */ diff --git a/gc.c b/gc.c new file mode 100644 index 0000000..4363b78 --- /dev/null +++ b/gc.c @@ -0,0 +1,129 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/********************************************************************** + * + * $XConsortium: gc.c,v 1.22 91/01/09 17:13:12 rws Exp $ + * + * Open the fonts and create the GCs + * + * 31-Mar-88 Tom LaStrange Initial Version. + * + * Do the necessary modification to be integrated in ctwm. + * Can no longer be used for the standard twm. + * + * 22-April-92 Claude Lecommandeur. + * + * + **********************************************************************/ + +#include +#include "twm.h" +#include "util.h" +#include "screen.h" + +/*********************************************************************** + * + * Procedure: + * CreateGCs - open fonts and create all the needed GC's. I only + * want to do this once, hence the first_time flag. + * + *********************************************************************** + */ + +void +CreateGCs() +{ + static ScreenInfo *prevScr = NULL; + XGCValues gcv; + unsigned long gcm; + static unsigned char greypattern [] = {0x0f, 0x05, 0x0f, 0x0a}; + Pixmap greypixmap; + static char dashlist [2] = {1, 1}; + + if (!Scr->FirstTime || prevScr == Scr) + return; + + prevScr = Scr; + + /* create GC's */ + + gcm = 0; + gcm |= GCFunction; gcv.function = GXxor; + gcm |= GCLineWidth; gcv.line_width = 0; + gcm |= GCForeground; gcv.foreground = Scr->XORvalue; + gcm |= GCSubwindowMode; gcv.subwindow_mode = IncludeInferiors; + + Scr->DrawGC = XCreateGC(dpy, Scr->Root, gcm, &gcv); + + gcm = 0; + gcm |= GCForeground; gcv.foreground = Scr->MenuC.fore; + gcm |= GCBackground; gcv.background = Scr->MenuC.back; +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + if (!use_fontset) + { + gcm |= GCFont; gcv.font = Scr->MenuFont.font->fid; + } +#else + gcm |= GCFont; gcv.font = Scr->MenuFont.font->fid; +#endif + + Scr->MenuGC = XCreateGC(dpy, Scr->Root, gcm, &gcv); + + gcm = 0; + gcm |= GCPlaneMask; gcv.plane_mask = AllPlanes; + /* + * Prevent GraphicsExpose and NoExpose events. We'd only get NoExpose + * events anyway; they cause BadWindow errors from XGetWindowAttributes + * call in FindScreenInfo (events.c) (since drawable is a pixmap). + */ + gcm |= GCGraphicsExposures; gcv.graphics_exposures = False; + gcm |= GCLineWidth; gcv.line_width = 0; + + Scr->NormalGC = XCreateGC(dpy, Scr->Root, gcm, &gcv); + + greypixmap = XCreatePixmapFromBitmapData(dpy, Scr->Root, + (char *) greypattern, 4, 4, 1, 0, 1); + + gcm = 0; + gcm |= GCStipple; gcv.stipple = greypixmap; + gcm |= GCFillStyle; gcv.fill_style = FillOpaqueStippled; + gcm |= GCForeground; gcv.foreground = Scr->Black; + gcm |= GCBackground; gcv.background = Scr->White; + Scr->GreyGC = XCreateGC (dpy, Scr->Root, gcm, &gcv); + XSetDashes (dpy, Scr->GreyGC, 1, dashlist, 2); + + if (Scr->BeNiceToColormap) { + gcm = 0; + gcm |= GCLineStyle; + gcv.line_style = LineDoubleDash; + Scr->ShadGC = XCreateGC (dpy, Scr->Root, gcm, &gcv); + XSetDashes (dpy, Scr->ShadGC, 0, dashlist, 2); + } +} diff --git a/gc.h b/gc.h new file mode 100644 index 0000000..f603201 --- /dev/null +++ b/gc.h @@ -0,0 +1,44 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/********************************************************************** + * + * $XConsortium: gc.h,v 1.5 89/10/27 14:01:17 jim Exp $ + * + * GC related externs + * + * 8-Apr-88 Tom LaStrange Initial Version. + * + **********************************************************************/ + +#ifndef _GC_ +#define _GC_ + +extern void CreateGCs(); + +#endif /* _GC_ */ diff --git a/gram.y b/gram.y new file mode 100644 index 0000000..ac41412 --- /dev/null +++ b/gram.y @@ -0,0 +1,1248 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/*********************************************************************** + * + * $XConsortium: gram.y,v 1.91 91/02/08 18:21:56 dave Exp $ + * + * .twmrc command grammer + * + * 07-Jan-86 Thomas E. LaStrange File created + * 11-Nov-90 Dave Sternlicht Adding SaveColors + * 10-Oct-90 David M. Sternlicht Storing saved colors on root + * + ***********************************************************************/ + +%{ +#include +#include +#include +#include "twm.h" +#include "menus.h" +#include "list.h" +#include "util.h" +#include "screen.h" +#include "parse.h" +#include "doors.h" +/* djhjr - 10/30/02 */ +#include "iconmgr.h" +/* djhjr - 4/26/99 */ +#include "regions.h" +#include +#include + +/* Submitted by Nelson H. F. Beebe */ +#ifdef __NeXT__ +#undef isascii +#define isascii(c) ((0 <= (int)(c)) && ((int)(c) <= 127)) +#endif + +static char *Action = ""; +static char *Name = ""; +static MenuRoot *root, *pull = NULL; + +static MenuRoot *GetRoot(); +/* was type 'void' - djhjr - 10/20/01 */ +static char *RemoveDQuote(); +/* djhjr - 10/20/01 */ +static char *RemoveRESlash(); +/* djhjr - 10/16/02 */ +static int ParseWarpCentered(); +/* djhjr - 9/24/02 */ +static int ParseUsePPosition(); +void twmrc_error_prefix(); + +/* djhjr - 4/30/96 */ +static MenuItem *lastmenuitem = (MenuItem*) 0; + +static Bool CheckWarpScreenArg(), CheckWarpRingArg(); +static Bool CheckColormapArg(); +static void GotButton(), GotKey(), GotTitleButton(); +static void yyerror(); +static name_list **list; +/* djhjr - 4/26/99 */ +static RootRegion *ARlist; +static int cont = 0; +static int color; +int mods = 0; +unsigned int mods_used = (ShiftMask | ControlMask | Mod1Mask); +/* djhjr - 9/24/02 */ +static int ppos; +/* djhjr - 10/16/02 */ +static int warpc; + +extern void SetHighlightPixmap(); +extern void SetVirtualPixmap(), SetVirtualDesktop(), SetRealScreenPixmap(); +extern void NewBitmapCursor(); +extern void AddIconRegion(); +/* next two - djhjr - 4/26/99 */ +extern RootRegion *AddAppletRegion(); +extern int AddToAppletList(); +extern int do_single_keyword(), do_string_keyword(), do_number_keyword(); +extern name_list **do_colorlist_keyword(); +extern int do_color_keyword(); +extern void do_string_savecolor(), do_var_savecolor(), do_squeeze_entry(); +/* djhjr - 6/22/01 */ +extern int SetSound(); + +/* + * this used to be the definition - now making the assumption it's + * defined in lex's skeleton file (submitted by Nelson H. F. Beebe) + * + * djhjr - 1/16/98 + */ +extern int yylineno; + +%} + +%union +{ + int num; + char *ptr; + /* djhjr - 10/20/01 */ + struct + { + short ltype; + char *lval; + } match; +}; + +%token LP RP MENUS MENU BUTTON DEFAULT_FUNCTION PLUS MINUS +%token ALL OR CURSORS PIXMAPS ICONS COLOR MONOCHROME FUNCTION +%token ICONMGR_SHOW ICONMGR WINDOW_FUNCTION ZOOM ICONMGRS +%token ICONMGR_GEOMETRY ICONMGR_NOSHOW MAKE_TITLE +%token ICONIFY_BY_UNMAPPING DONT_ICONIFY_BY_UNMAPPING +%token NO_TITLE AUTO_RAISE NO_HILITE NO_ICONMGR_HILITE ICON_REGION +/* djhjr - 10/16/02 */ +%token WARP_CENTERED +/* djhjr - 9/24/02 */ +%token USE_PPOSITION +/* submitted by Tim Wiess - 8/23/02 */ +%token NO_BORDER +/* djhjr - 4/26/99 */ +%token APPLET_REGION +%token META SHIFT LOCK CONTROL WINDOW TITLE ICON ROOT FRAME VIRTUAL VIRTUAL_WIN +/* TILDE - djhjr - 10/20/01 */ +%token COLON EQUALS TILDE SQUEEZE_TITLE DONT_SQUEEZE_TITLE +/* opaque stuff - djhjr - 4/7/98 */ +%token OPAQUE_MOVE NO_OPAQUE_MOVE OPAQUE_RESIZE NO_OPAQUE_RESIZE +%token START_ICONIFIED NO_TITLE_HILITE TITLE_HILITE +%token MOVE RESIZE WAIT SELECT KILL LEFT_TITLEBUTTON RIGHT_TITLEBUTTON +/* MKEYWORD - djhjr - 10/20/01 */ +%token NUMBER KEYWORD MKEYWORD NKEYWORD CKEYWORD CLKEYWORD FKEYWORD FSKEYWORD +/* SNKEYWORD - djhjr - 10/18/02 */ +/* NO_WINDOW_RING submitted by Jonathan Paisley - 10/27/02 */ +%token SNKEYWORD SKEYWORD DKEYWORD JKEYWORD WINDOW_RING NO_WINDOW_RING WARP_CURSOR +%token ERRORTOKEN NO_STACKMODE NAILEDDOWN VIRTUALDESKTOP NO_SHOW_IN_DISPLAY +/* Submitted by Erik Agsjo */ +%token NO_SHOW_IN_TWMWINDOWS +%token DOORS DOOR +/*RFB PIXMAP:*/ +%token VIRTUALMAP +%token REALSCREENMAP +/* two pixmaps - djhjr - 10/30/02 */ +%token ICONMGRICONMAP +%token MENUICONMAP +/* STRING REGEXP +/* djhjr - 9/10/03 */ +%token IGNORE_MODS +%token SAVECOLOR +%token LB +%token RB + +/* regex stuff - djhjr - 10/20/01 */ +%type matcher +%type string regexp +%type action button number signed_number full fullkey + +%start twmrc + +%% +twmrc : stmts + ; + +stmts : /* Empty */ + | stmts stmt + ; + +stmt : error + | noarg + | sarg + | narg + | snarg + | squeeze + | doors + | ICON_REGION string DKEYWORD DKEYWORD number number + { AddIconRegion($2, $3, $4, $5, $6); } + | APPLET_REGION string DKEYWORD DKEYWORD number number + { ARlist = AddAppletRegion($2, $3, $4, $5, $6); } + applet_list + | ICONMGR_GEOMETRY string number { if (Scr->FirstTime) + { + Scr->iconmgr.geometry=$2; + Scr->iconmgr.columns=$3; + } + } + | ICONMGR_GEOMETRY string { if (Scr->FirstTime) + Scr->iconmgr.geometry = $2; + } + | ZOOM number { if (Scr->FirstTime) + { + Scr->DoZoom = TRUE; + Scr->ZoomCount = $2; + } + } + | ZOOM { if (Scr->FirstTime) + Scr->DoZoom = TRUE; } + | PIXMAPS pixmap_list {} + | CURSORS cursor_list {} + | ICONIFY_BY_UNMAPPING { list = &Scr->IconifyByUn; } + win_list + | ICONIFY_BY_UNMAPPING { if (Scr->FirstTime) + Scr->IconifyByUnmapping = TRUE; } + + | OPAQUE_MOVE { list = &Scr->OpaqueMoveL; } + win_list + | OPAQUE_MOVE { if (Scr->FirstTime) Scr->OpaqueMove = TRUE; } + | NO_OPAQUE_MOVE { list = &Scr->NoOpaqueMoveL; } + win_list + | NO_OPAQUE_MOVE { if (Scr->FirstTime) Scr->OpaqueMove = FALSE; } + | OPAQUE_RESIZE { list = &Scr->OpaqueResizeL; } + win_list + | OPAQUE_RESIZE { if (Scr->FirstTime) Scr->OpaqueResize = TRUE; } + | NO_OPAQUE_RESIZE { list = &Scr->NoOpaqueResizeL; } + win_list + | NO_OPAQUE_RESIZE { if (Scr->FirstTime) Scr->OpaqueResize = FALSE; } + + | LEFT_TITLEBUTTON string EQUALS action { + GotTitleButton ($2, $4, False); + } + | RIGHT_TITLEBUTTON string EQUALS action { + GotTitleButton ($2, $4, True); + } + | button string { root = GetRoot($2, NULLSTR, NULLSTR); + Scr->Mouse[$1][C_ROOT][0].func = F_MENU; + Scr->Mouse[$1][C_ROOT][0].menu = root; + } + | button action { Scr->Mouse[$1][C_ROOT][0].func = $2; + if ($2 == F_MENU) + { + pull->prev = NULL; + Scr->Mouse[$1][C_ROOT][0].menu = pull; + } + else + { + root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR); + Scr->Mouse[$1][C_ROOT][0].item = + AddToMenu(root,"x",Action, + NULLSTR,$2,NULLSTR,NULLSTR); + } + Action = ""; + pull = NULL; + } + | string fullkey { GotKey($1, $2); } + | button full { GotButton($1, $2); } + | IGNORE_MODS keys { Scr->IgnoreModifiers = mods; + mods = 0; + } + | DONT_ICONIFY_BY_UNMAPPING { list = &Scr->DontIconify; } + win_list + | ICONMGR_NOSHOW { list = &Scr->IconMgrNoShow; } + win_list + | ICONMGR_NOSHOW { Scr->IconManagerDontShow = TRUE; } + | ICONMGRS { list = &Scr->IconMgrs; } + iconm_list + | ICONMGR_SHOW { list = &Scr->IconMgrShow; } + win_list + | NO_TITLE_HILITE { list = &Scr->NoTitleHighlight; } + win_list + | NO_TITLE_HILITE { if (Scr->FirstTime) + Scr->TitleHighlight = FALSE; } + | NO_ICONMGR_HILITE { Scr->IconMgrHighlight = FALSE; } + | NO_HILITE { list = &Scr->NoHighlight; } + win_list + | NO_HILITE { if (Scr->FirstTime) + Scr->Highlight = FALSE; } + | NO_STACKMODE { list = &Scr->NoStackModeL; } + win_list + | NO_STACKMODE { if (Scr->FirstTime) + Scr->StackMode = FALSE; } + | NO_TITLE { list = &Scr->NoTitle; } + win_list + | NO_TITLE { if (Scr->FirstTime) + Scr->NoTitlebar = TRUE; } + | NO_BORDER { list = &Scr->NoBorder; } + win_list + | NO_BORDER { if (Scr->FirstTime) + Scr->NoBorders = TRUE; } + | MAKE_TITLE { list = &Scr->MakeTitle; } + win_list + | START_ICONIFIED { list = &Scr->StartIconified; } + win_list + | AUTO_RAISE { list = &Scr->AutoRaise; } + win_list + | AUTO_RAISE { Scr->AutoRaiseDefault = TRUE; } + | WARP_CENTERED string { if (Scr->FirstTime) { + if ((warpc = ParseWarpCentered($2)) != -1) + Scr->WarpCentered = warpc; + } + } + | USE_PPOSITION string { if (Scr->FirstTime) { + if ((ppos = ParseUsePPosition($2)) != -1) + Scr->UsePPosition = ppos; + } + } + | USE_PPOSITION { list = &Scr->UsePPositionL; } + ppos_list + | USE_PPOSITION string { if (Scr->FirstTime) { + if ((ppos = ParseUsePPosition($2)) != -1) + Scr->UsePPosition = ppos; + } + list = &Scr->UsePPositionL; + } + ppos_list + | MENU string LP string COLON string RP { + root = GetRoot($2, $4, $6); } + menu { root->real_menu = TRUE;} + | MENU string { root = GetRoot($2, NULLSTR, NULLSTR); } + menu { root->real_menu = TRUE; } + | FUNCTION string { root = GetRoot($2, NULLSTR, NULLSTR); } + function + | ICONS { list = &Scr->IconNames; } + icon_list + | SOUNDS + sound_list + | COLOR { color = COLOR; } + color_list + | SAVECOLOR + save_color_list + | MONOCHROME { color = MONOCHROME; } + color_list + | DEFAULT_FUNCTION action { Scr->DefaultFunction.func = $2; + if ($2 == F_MENU) + { + pull->prev = NULL; + Scr->DefaultFunction.menu = pull; + } + else + { + root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR); + Scr->DefaultFunction.item = + AddToMenu(root,"x",Action, + NULLSTR,$2, NULLSTR, NULLSTR); + } + Action = ""; + pull = NULL; + } + | WINDOW_FUNCTION action { Scr->WindowFunction.func = $2; + root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR); + Scr->WindowFunction.item = + AddToMenu(root,"x",Action, + NULLSTR,$2, NULLSTR, NULLSTR); + Action = ""; + pull = NULL; + } + | WARP_CURSOR { list = &Scr->WarpCursorL; } + win_list + | WARP_CURSOR { if (Scr->FirstTime) + Scr->WarpCursor = TRUE; } + | WINDOW_RING { list = &Scr->WindowRingL; } + win_list + | WINDOW_RING { if (Scr->FirstTime) + Scr->UseWindowRing = TRUE; } + | NO_WINDOW_RING { list = &Scr->NoWindowRingL; } + win_list + | NAILEDDOWN { list = &Scr->NailedDown; } + win_list + | VIRTUALDESKTOP string number + { SetVirtualDesktop($2, $3); } + | NO_SHOW_IN_DISPLAY { list = &Scr->DontShowInDisplay; } + win_list + | NO_SHOW_IN_TWMWINDOWS { list = &Scr->DontShowInTWMWindows; } + win_list + ; + + +noarg : KEYWORD { if (!do_single_keyword ($1)) { + twmrc_error_prefix(); + fprintf (stderr, + "unknown singleton keyword %d\n", + $1); + ParseError = 1; + } + } + ; + +sarg : SKEYWORD string { if (!do_string_keyword ($1, $2)) { + twmrc_error_prefix(); + fprintf (stderr, + "unknown string keyword %d (value \"%s\")\n", + $1, $2); + ParseError = 1; + } + } + ; + +narg : NKEYWORD number { if (!do_number_keyword ($1, $2)) { + twmrc_error_prefix(); + fprintf (stderr, + "unknown numeric keyword %d (value %d)\n", + $1, $2); + ParseError = 1; + } + } + ; + +/* djhjr - 10/18/02 */ +snarg : SNKEYWORD signed_number { if (!do_number_keyword ($1, $2)) { + twmrc_error_prefix(); + fprintf (stderr, + "unknown signed keyword %d (value %d)\n", + $1, $2); + ParseError = 1; + } + } + ; + + + +full : EQUALS keys COLON contexts COLON action { $$ = $6; } + ; + +fullkey : EQUALS keys COLON contextkeys COLON action { $$ = $6; } + ; + +keys : /* Empty */ + | keys key + ; + +key : META { mods |= Mod1Mask; } + | SHIFT { mods |= ShiftMask; } + | LOCK { mods |= LockMask; } + | CONTROL { mods |= ControlMask; } + | META number { if ($2 < 1 || $2 > 5) { + twmrc_error_prefix(); + fprintf (stderr, + "bad modifier number (%d), must be 1-5\n", + $2); + ParseError = 1; + } else { + mods |= (Mod1Mask << ($2 - 1)); + } + } + | OR { } + ; + +contexts : /* Empty */ + | contexts context + ; + +context : WINDOW { cont |= C_WINDOW_BIT; } + | TITLE { cont |= C_TITLE_BIT; } + | ICON { cont |= C_ICON_BIT; } + | ROOT { cont |= C_ROOT_BIT; } + | FRAME { cont |= C_FRAME_BIT; } + | ICONMGR { cont |= C_ICONMGR_BIT; } + | META { cont |= C_ICONMGR_BIT; } + | VIRTUAL { cont |= C_VIRTUAL_BIT; } + | VIRTUAL_WIN { cont |= C_VIRTUAL_WIN_BIT; } + | DOOR { cont |= C_DOOR_BIT; } + | ALL { cont |= C_ALL_BITS; } + | OR { } + ; + +contextkeys : /* Empty */ + | contextkeys contextkey + ; + +contextkey : WINDOW { cont |= C_WINDOW_BIT; } + | TITLE { cont |= C_TITLE_BIT; } + | ICON { cont |= C_ICON_BIT; } + | ROOT { cont |= C_ROOT_BIT; } + | FRAME { cont |= C_FRAME_BIT; } + | ICONMGR { cont |= C_ICONMGR_BIT; } + | META { cont |= C_ICONMGR_BIT; } + | VIRTUAL { cont |= C_VIRTUAL_BIT; } + | VIRTUAL_WIN { cont |= C_VIRTUAL_WIN_BIT; } + | DOOR { cont |= C_DOOR_BIT; } + | ALL { cont |= C_ALL_BITS; } + | OR { } + | string { Name = $1; cont |= C_NAME_BIT; } + ; + + +pixmap_list : LB pixmap_entries RB + ; + +pixmap_entries : /* Empty */ + | pixmap_entries pixmap_entry + ; + +pixmap_entry : TITLE_HILITE string { SetHighlightPixmap ($2); } + | VIRTUALMAP string { SetVirtualPixmap ($2); }/*RFB PIXMAP*/ + | REALSCREENMAP string { SetRealScreenPixmap ($2); }/*RFB PIXMAP*/ + | ICONMGRICONMAP string { SetIconMgrPixmap($2); } /* djhjr - 10/30/02 */ + | MENUICONMAP string { SetMenuIconPixmap($2); } /* djhjr - 10/30/02 */ + ; + + +cursor_list : LB cursor_entries RB + ; + +cursor_entries : /* Empty */ + | cursor_entries cursor_entry + ; + +cursor_entry : FRAME string string { + NewBitmapCursor(&Scr->FrameCursor, $2, $3); } + | FRAME string { + NewFontCursor(&Scr->FrameCursor, $2); } + | TITLE string string { + NewBitmapCursor(&Scr->TitleCursor, $2, $3); } + | TITLE string { + NewFontCursor(&Scr->TitleCursor, $2); } + | ICON string string { + NewBitmapCursor(&Scr->IconCursor, $2, $3); } + | ICON string { + NewFontCursor(&Scr->IconCursor, $2); } + | ICONMGR string string { + NewBitmapCursor(&Scr->IconMgrCursor, $2, $3); } + | ICONMGR string { + NewFontCursor(&Scr->IconMgrCursor, $2); } + | BUTTON string string { + NewBitmapCursor(&Scr->ButtonCursor, $2, $3); } + | BUTTON string { + NewFontCursor(&Scr->ButtonCursor, $2); } + | MOVE string string { + NewBitmapCursor(&Scr->MoveCursor, $2, $3); } + | MOVE string { + NewFontCursor(&Scr->MoveCursor, $2); } + | RESIZE string string { + NewBitmapCursor(&Scr->ResizeCursor, $2, $3); } + | RESIZE string { + NewFontCursor(&Scr->ResizeCursor, $2); } + | WAIT string string { + NewBitmapCursor(&Scr->WaitCursor, $2, $3); } + | WAIT string { + NewFontCursor(&Scr->WaitCursor, $2); } + | MENU string string { + NewBitmapCursor(&Scr->MenuCursor, $2, $3); } + | MENU string { + NewFontCursor(&Scr->MenuCursor, $2); } + | SELECT string string { + NewBitmapCursor(&Scr->SelectCursor, $2, $3); } + | SELECT string { + NewFontCursor(&Scr->SelectCursor, $2); } + | KILL string string { + NewBitmapCursor(&Scr->DestroyCursor, $2, $3); } + | KILL string { + NewFontCursor(&Scr->DestroyCursor, $2); } + | DOOR string string {/*RFBCURSOR*/ + NewBitmapCursor(&Scr->DoorCursor, $2, $3); }/*RFBCURSOR*/ + | DOOR string {/*RFBCURSOR*/ + NewFontCursor(&Scr->DoorCursor, $2); }/*RFBCURSOR*/ + | VIRTUAL string string {/*RFBCURSOR*/ + NewBitmapCursor(&Scr->VirtualCursor, $2, $3); }/*RFBCURSOR*/ + | VIRTUAL string {/*RFBCURSOR*/ + NewFontCursor(&Scr->VirtualCursor, $2); }/*RFBCURSOR*/ + | VIRTUAL_WIN string string {/*RFBCURSOR*/ + NewBitmapCursor(&Scr->DesktopCursor, $2, $3); }/*RFBCURSOR*/ + | VIRTUAL_WIN string {/*RFBCURSOR*/ + NewFontCursor(&Scr->DesktopCursor, $2); }/*RFBCURSOR*/ + ; + +color_list : LB color_entries RB + ; + + +color_entries : /* Empty */ + | color_entries color_entry + ; + +color_entry : CLKEYWORD string { if (!do_colorlist_keyword ($1, color, + $2)) { + twmrc_error_prefix(); + fprintf (stderr, + "unhandled list color keyword %d (string \"%s\")\n", + $1, $2); + ParseError = 1; + } + } + | CLKEYWORD string { list = do_colorlist_keyword($1,color, + $2); + if (!list) { + twmrc_error_prefix(); + fprintf (stderr, + "unhandled color list keyword %d (string \"%s\")\n", + $1, $2); + ParseError = 1; + } + } + win_color_list + | CKEYWORD string { if (!do_color_keyword ($1, color, + $2)) { + twmrc_error_prefix(); + fprintf (stderr, + "unhandled color keyword %d (string \"%s\")\n", + $1, $2); + ParseError = 1; + } + } + ; + +save_color_list : LB s_color_entries RB + ; + +s_color_entries : /* Empty */ + | s_color_entries s_color_entry + ; + +s_color_entry : string { do_string_savecolor(color, $1); } + | CLKEYWORD { do_var_savecolor($1); } + ; + +win_color_list : LB win_color_entries RB + ; + +win_color_entries : /* Empty */ + | win_color_entries win_color_entry + ; + +/* 'matcher', mods to 'AddToList()' - djhjr - 10/20/01 */ +win_color_entry : matcher string { if (Scr->FirstTime && + color == Scr->Monochrome) + AddToList(list, $1.lval, $1.ltype, + $2); } + ; + +squeeze : SQUEEZE_TITLE { + if (HasShape) Scr->SqueezeTitle = TRUE; + } + | SQUEEZE_TITLE { list = &Scr->SqueezeTitleL; + if (HasShape && Scr->SqueezeTitle == -1) + Scr->SqueezeTitle = TRUE; + } + LB win_sqz_entries RB + | DONT_SQUEEZE_TITLE { Scr->SqueezeTitle = FALSE; } + | DONT_SQUEEZE_TITLE { list = &Scr->DontSqueezeTitleL; } + win_list + ; + +/* 'matcher', mods to 'do_sqeeze_entry()' - djhjr - 10/20/01 */ +win_sqz_entries : /* Empty */ + | win_sqz_entries matcher JKEYWORD signed_number signed_number { + if (Scr->FirstTime) { + do_squeeze_entry (list, $2.lval, $2.ltype, + $3, $4, $5); + } + } + ; + +doors : DOORS LB door_list RB + ; + +door_list : /* Empty */ + | door_list door_entry + ; + +door_entry : string string string + { + (void) door_add($1, $2, $3); + } + ; + +iconm_list : LB iconm_entries RB + ; + +iconm_entries : /* Empty */ + | iconm_entries iconm_entry + ; + +/* 'matcher', mods to 'AddToList()', 'AllocateIconManager()' - djhjr - 10/20/01 */ +iconm_entry : matcher string number { if (Scr->FirstTime) + AddToList(list, $1.lval, $1.ltype, (char *) + AllocateIconManager($1.lval, + NULLSTR, $2, $3)); + } + | matcher string string number + { if (Scr->FirstTime) + AddToList(list, $1.lval, $1.ltype, (char *) + AllocateIconManager($1.lval, + $2, $3, $4)); + } + ; + +win_list : LB win_entries RB + ; + +win_entries : /* Empty */ + | win_entries win_entry + ; + +/* 'matcher', mods to 'AddToList()' - djhjr - 10/20/01 */ +win_entry : matcher { if (Scr->FirstTime) + AddToList(list, $1.lval, $1.ltype, 0); + } + ; + +icon_list : LB icon_entries RB + ; + +icon_entries : /* Empty */ + | icon_entries icon_entry + ; + +/* 'matcher', mods to 'AddToList()' - djhjr - 10/20/01 */ +icon_entry : matcher string { if (Scr->FirstTime) + AddToList(list, $1.lval, $1.ltype, $2); + } + ; + +/* djhjr - 9/24/02 */ +ppos_list : LB ppos_entries RB + ; + +ppos_entries : /* Empty */ + | ppos_entries ppos_entry + ; + +/* 'matcher', mods to 'AddToList()' - djhjr - 10/20/01 */ +ppos_entry : matcher string { if (Scr->FirstTime) { + if ((ppos = ParseUsePPosition($2)) != -1) + AddToList(list, $1.lval, $1.ltype, (char *)&ppos); + } + } + ; + +/* djhjr - 6/22/01 */ +sound_list : LB sound_entries RB + ; + +/* djhjr - 6/22/01 */ +sound_entries : /* Empty */ + | sound_entries sound_entry + ; + +/* djhjr - 8/16/01 */ +sound_entry : string string { if (Scr->FirstTime) SetSound($1, $2, -1); } + | string string number { if (Scr->FirstTime) SetSound($1, $2, $3); } + ; + +/* djhjr - 4/26/99 */ +applet_list : LB applet_entries RB + ; + +/* djhjr - 4/26/99 */ +applet_entries : /* Empty */ + | applet_entries applet_entry + ; + +/* djhjr - 4/26/99 */ +/* 'matcher', mods to 'AddToAppletList()' - djhjr - 10/20/01 */ +applet_entry : matcher { if (Scr->FirstTime) + AddToAppletList(ARlist, + $1.lval, $1.ltype); + } + ; + +function : LB function_entries RB + ; + +function_entries: /* Empty */ + | function_entries function_entry + ; + +function_entry : action { AddToMenu(root, "", Action, NULLSTR, $1, + NULLSTR, NULLSTR); + Action = ""; + } + ; + +/* djhjr - 4/30/96 +menu : LB menu_entries RB +*/ +menu : LB menu_entries RB {lastmenuitem = (MenuItem*) 0;} + ; + +menu_entries : /* Empty */ + | menu_entries menu_entry + ; + +/* djhjr - 4/30/96 +menu_entry : string action { AddToMenu(root, $1, Action, pull, $2, + NULLSTR, NULLSTR); + Action = ""; + pull = NULL; + } + | string LP string COLON string RP action { + AddToMenu(root, $1, Action, pull, $7, + $3, $5); + Action = ""; + pull = NULL; + } + ; +*/ +menu_entry : string action { + if ($2 == F_SEPARATOR) { + if (lastmenuitem) lastmenuitem->separated = 1; + } + else { + lastmenuitem = AddToMenu(root, $1, Action, pull, $2, NULLSTR, NULLSTR); + Action = ""; + pull = NULL; + } + } + | string LP string COLON string RP action { + if ($7 == F_SEPARATOR) { + if (lastmenuitem) lastmenuitem->separated = 1; + } + else { + lastmenuitem = AddToMenu(root, $1, Action, pull, $7, $3, $5); + Action = ""; + pull = NULL; + } + } + ; + +action : FKEYWORD { $$ = $1; } + | FSKEYWORD string { + $$ = $1; + Action = $2; + switch ($1) { + case F_MENU: + pull = GetRoot ($2, NULLSTR,NULLSTR); + pull->prev = root; + break; + case F_WARPRING: + if (!CheckWarpRingArg (Action)) { + twmrc_error_prefix(); + fprintf (stderr, + "ignoring invalid f.warptoring argument \"%s\"\n", + Action); + $$ = F_NOP; + } + case F_WARPTOSCREEN: + if (!CheckWarpScreenArg (Action)) { + twmrc_error_prefix(); + fprintf (stderr, + "ignoring invalid f.warptoscreen argument \"%s\"\n", + Action); + $$ = F_NOP; + } + break; + case F_COLORMAP: + if (CheckColormapArg (Action)) { + $$ = F_COLORMAP; + } else { + twmrc_error_prefix(); + fprintf (stderr, + "ignoring invalid f.colormap argument \"%s\"\n", + Action); + $$ = F_NOP; + } + break; + } /* end switch */ + } + ; + + +button : BUTTON number { $$ = $2; + if ($2 == 0) + yyerror("bad button 0"); + + if ($2 > MAX_BUTTONS) + { + $$ = 0; + yyerror("button number too large"); + } + } + ; + +/* djhjr - 10/20/01 */ +matcher : string { $$.ltype = LTYPE_ANY_STRING; + $$.lval = $1; + } + | regexp { $$.ltype = LTYPE_ANY_REGEXP; + $$.lval = $1; + } + | MKEYWORD EQUALS string { $$.ltype = $1 | LTYPE_STRING; + $$.lval = $3; + } + | MKEYWORD TILDE regexp { $$.ltype = $1 | LTYPE_REGEXP; + $$.lval = $3; + } + ; + +string : STRING { $$ = RemoveDQuote($1); } + ; + +/* djhjr - 10/20/01 */ +regexp : REGEXP { $$ = RemoveRESlash($1); } + ; + +signed_number : number { $$ = $1; } + | PLUS number { $$ = $2; } + | MINUS number { $$ = -($2); } + ; + +number : NUMBER { $$ = $1; } + ; + +%% +static void +yyerror(s) char *s; +{ + twmrc_error_prefix(); + fprintf (stderr, "error in input file: %s\n", s ? s : ""); + ParseError = 1; +} + +/* do manipulations in place, then copy it - djhjr - 10/20/01 */ +static char *RemoveDQuote(str) +char *str; +{ + register char *i, *o; + register int n, count; + int length = 0; + char *ptr = ""; + + for (i = str + 1, o = str; *i && *i != '\"'; o++) + { + if (*i == '\\') + { + switch (*++i) + { + case 'n': + *o = '\n'; + i++; + break; + case 'b': + *o = '\b'; + i++; + break; + case 'r': + *o = '\r'; + i++; + break; + case 't': + *o = '\t'; + i++; + break; + case 'f': + *o = '\f'; + i++; + break; + case '0': + if (*++i == 'x') + goto hex; + else + --i; + case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + n = 0; + count = 0; + while (*i >= '0' && *i <= '7' && count < 3) + { + n = (n << 3) + (*i++ - '0'); + count++; + } + *o = n; + break; + hex: + case 'x': + n = 0; + count = 0; + while (i++, count++ < 2) + { + if (*i >= '0' && *i <= '9') + n = (n << 4) + (*i - '0'); + else if (*i >= 'a' && *i <= 'f') + n = (n << 4) + (*i - 'a') + 10; + else if (*i >= 'A' && *i <= 'F') + n = (n << 4) + (*i - 'A') + 10; + else + { + length--; /* account for length++ at loop end */ + break; + } + } + *o = n; + break; + case '\n': + i++; /* punt */ + o--; /* to account for o++ at end of loop */ + length--; /* account for length++ at loop end */ + break; + case '\"': + case '\'': + case '\\': + default: + *o = *i++; + break; + } + } + else + *o = *i++; + + length++; + } + *o = '\0'; + + if (length > 0) + { + ptr = (char *)malloc(length + 1); + memcpy(ptr, str, length); + ptr[length] = '\0'; + +#ifdef DEBUG + fprintf(stderr, "RemoveDQuote(): '"); + for (n = 0; n < length; n++) + fprintf(stderr, "%c", ptr[n]); + fprintf(stderr, "'\n", ptr); +#endif + } + + return (ptr); +} + +/* djhjr - 10/20/01 */ +static char *RemoveRESlash(str) +char *str; +{ + char *ptr = ""; +#ifndef NO_REGEX_SUPPORT + int length = strlen(str); + + if (length > 2) + { + ptr = (char *)malloc(length - 1); + memcpy(ptr, str + 1, length - 2); + ptr[length - 2] = '\0'; + +#ifdef DEBUG + fprintf(stderr, "RemoveRESlash(): '%s'\n", ptr); +#endif + } +#else + twmrc_error_prefix(); + fprintf(stderr, "no regex support for %s\n", str); + ParseError = 1; +#endif + + return (ptr); +} + +/* was in parse.c - djhjr - 9/24/02 */ +static int ParseUsePPosition(s) +char *s; +{ + XmuCopyISOLatin1Lowered (s, s); + + if (strcmp(s, "off") == 0) + return PPOS_OFF; + else if (strcmp(s, "on") == 0) + return PPOS_ON; + else if (strcmp(s, "non-zero") == 0 || strcmp(s, "nonzero") == 0) + return PPOS_NON_ZERO; + + twmrc_error_prefix(); + fprintf(stderr, "ignoring invalid UsePPosition argument \"%s\"\n", s); + return -1; +} + +/* djhjr - 10/16/02 */ +static int ParseWarpCentered(s) +char *s; +{ + XmuCopyISOLatin1Lowered (s, s); + + if (strcmp(s, "off") == 0) + return WARPC_OFF; + else if (strcmp(s, "on") == 0) + return WARPC_ON; + else if (strcmp(s, "titled") == 0) + return WARPC_TITLED; + else if (strcmp(s, "untitled") == 0) + return WARPC_UNTITLED; + + twmrc_error_prefix(); + fprintf(stderr, "ignoring invalid WarpCentered argument \"%s\"\n", s); + return -1; +} + +static MenuRoot *GetRoot(name, fore, back) +char *name; +char *fore, *back; +{ + MenuRoot *tmp; + + tmp = FindMenuRoot(name); + if (tmp == NULL) + tmp = NewMenuRoot(name); + + if (fore) + { + int save; + + save = Scr->FirstTime; + Scr->FirstTime = TRUE; + +/* djhjr - 4/22/96 + GetColor(COLOR, &tmp->hi_fore, fore); + GetColor(COLOR, &tmp->hi_back, back); +*/ + GetColor(COLOR, &tmp->highlight.fore, fore); + GetColor(COLOR, &tmp->highlight.back, back); + + Scr->FirstTime = save; + } + + return tmp; +} + +static void GotButton(butt, func) +int butt, func; +{ + int i; + + for (i = 0; i < NUM_CONTEXTS; i++) + { + if ((cont & (1 << i)) == 0) + continue; + + Scr->Mouse[butt][i][mods].func = func; + + if (func == F_MENU) + { + pull->prev = NULL; + + Scr->Mouse[butt][i][mods].menu = pull; + } + else + { + root = GetRoot(TWM_ROOT, NULLSTR, NULLSTR); + + Scr->Mouse[butt][i][mods].item = AddToMenu(root,"x",Action, + NULLSTR, func, NULLSTR, NULLSTR); + + } + } + Action = ""; + pull = NULL; + cont = 0; + mods_used |= mods; + mods = 0; +} + +static void GotKey(key, func) +char *key; +int func; +{ + int i; + + for (i = 0; i < NUM_CONTEXTS; i++) + { + if ((cont & (1 << i)) == 0) + continue; + if (!AddFuncKey(key, i, mods, func, Name, Action)) + break; + } + + Action = ""; + pull = NULL; + cont = 0; + mods_used |= mods; + mods = 0; +} + + +static void GotTitleButton (bitmapname, func, rightside) + char *bitmapname; + int func; + Bool rightside; +{ + if (!CreateTitleButton (bitmapname, func, Action, pull, rightside, True)) { + twmrc_error_prefix(); + fprintf (stderr, + "unable to create %s titlebutton \"%s\"\n", + rightside ? "right" : "left", bitmapname); + } + Action = ""; + pull = NULL; +} + +static Bool CheckWarpScreenArg (s) + register char *s; +{ + XmuCopyISOLatin1Lowered (s, s); + + if (strcmp (s, WARPSCREEN_NEXT) == 0 || + strcmp (s, WARPSCREEN_PREV) == 0 || + strcmp (s, WARPSCREEN_BACK) == 0) + return True; + + for (; *s && isascii(*s) && isdigit(*s); s++) ; /* SUPPRESS 530 */ + return (*s ? False : True); +} + + +static Bool CheckWarpRingArg (s) + register char *s; +{ + XmuCopyISOLatin1Lowered (s, s); + + if (strcmp (s, WARPSCREEN_NEXT) == 0 || + strcmp (s, WARPSCREEN_PREV) == 0) + return True; + + return False; +} + + +static Bool CheckColormapArg (s) + register char *s; +{ + XmuCopyISOLatin1Lowered (s, s); + + if (strcmp (s, COLORMAP_NEXT) == 0 || + strcmp (s, COLORMAP_PREV) == 0 || + strcmp (s, COLORMAP_DEFAULT) == 0) + return True; + + return False; +} + + +void twmrc_error_prefix () +{ + fprintf (stderr, "%s: line %d: ", ProgramName, yylineno); +} diff --git a/iconmgr.c b/iconmgr.c new file mode 100644 index 0000000..55f1abb --- /dev/null +++ b/iconmgr.c @@ -0,0 +1,1098 @@ +/* + * Copyright 1989 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*********************************************************************** + * + * $XConsortium: iconmgr.c,v 1.48 91/09/10 15:27:07 dave Exp $ + * + * Icon Manager routines + * + * 09-Mar-89 Tom LaStrange File Created + * + ***********************************************************************/ + +#include +#include "twm.h" +#include "util.h" +#include "menus.h" +#include "desktop.h" +#include "parse.h" +#include "screen.h" +#include "resize.h" +#include "add_window.h" +#include +#include + +#ifdef macII +int strcmp(); /* missing from string.h in AUX 2.0 */ +#endif + +#define strdup Strdup /* avoid conflict with system header files */ +extern char *strdup(char *); + +/* djhjr - 5/2/98 */ +static int ComputeIconMgrWindowHeight(); + +/* see AddIconManager() - djhjr - 5/5/98 +int iconmgr_textx = siconify_width+11; +*/ +int iconmgr_iconx = 0, iconmgr_textx = 0; + +WList *Active = NULL; +WList *DownIconManager = NULL; + +/* was an external file - djhjr - 10/30/02 */ +#define siconify_width 11 +#define siconify_height 11 +/* +static unsigned char siconify_bits[] = { + 0xff, 0x07, 0x01, 0x04, 0x0d, 0x05, 0x9d, 0x05, 0xb9, 0x04, 0x51, 0x04, + 0xe9, 0x04, 0xcd, 0x05, 0x85, 0x05, 0x01, 0x04, 0xff, 0x07}; +*/ + +int iconifybox_width = siconify_width; +int iconifybox_height = siconify_height; + +/* djhjr - 10/30/02 */ +void SetIconMgrPixmap(filename) +char *filename; +{ + Scr->iconMgrIconName = filename; +} + +/*********************************************************************** + * + * Procedure: + * CreateIconManagers - creat all the icon manager windows + * for this screen. + * + * Returned Value: + * none + * + * Inputs: + * none + * + *********************************************************************** + */ + +struct Colori { + Pixel color; + Pixmap pix; + struct Colori *next; +}; + +#if 0 +Pixmap Create3DIconManagerIcon (cp) +ColorPair cp; +{ + unsigned int w, h; + struct Colori *col; + static struct Colori *colori = NULL; + + w = (unsigned int) siconify_width; + h = (unsigned int) siconify_height; + + for (col = colori; col; col = col->next) { + if (col->color == cp.back) break; + } + if (col != NULL) return (col->pix); + col = (struct Colori*) malloc (sizeof (struct Colori)); + col->color = cp.back; + col->pix = XCreatePixmap (dpy, Scr->Root, w, h, Scr->d_depth); +#ifdef ORIGINAL_ICONMGRPIXMAP + Draw3DBorder (col->pix, 0, 0, w, h, 4, cp, off, True, False); +#else + Draw3DBorder (col->pix, 0, 0, w, h, 1, cp, off, True, False); +#ifdef DO_DOT + Draw3DBorder (col->pix, (w / 2) - 1, (h / 2) - 1, 3, 3, 1, cp, off, True, False); +#endif +#endif + col->next = colori; + colori = col; + + return (colori->pix); +} +#endif + +void CreateIconManagers() +{ + XClassHint *class; /* djhjr - 2/28/99 */ + IconMgr *p; + int mask; + char str[100]; + char str1[100]; + Pixel background; + char *icon_name; + + if (Scr->NoIconManagers) + return; + +/* djhjr - 10/30/02 + if (Scr->siconifyPm == None) + { + Scr->siconifyPm->pixmap = XCreatePixmapFromBitmapData(dpy, Scr->Root, + (char *)siconify_bits, siconify_width, siconify_height, 1, 0, 1); + } +*/ + + for (p = &Scr->iconmgr; p != NULL; p = p->next) + { + mask = XParseGeometry(p->geometry, &JunkX, &JunkY, + (unsigned int *) &p->width, (unsigned int *)&p->height); + + /* djhjr - 3/1/99 */ + if (p->width > Scr->MyDisplayWidth) p->width = Scr->MyDisplayWidth; + + if (mask & XNegative) +/* djhjr - 4/19/96 + JunkX = Scr->MyDisplayWidth - p->width - + (2 * Scr->BorderWidth) + JunkX; +*/ +/* djhjr - 8/11/98 + JunkX += Scr->MyDisplayWidth - p->width - + (2 * (Scr->ThreeDBorderWidth ? Scr->ThreeDBorderWidth : Scr->BorderWidth)); +*/ + JunkX += Scr->MyDisplayWidth - p->width - + (2 * Scr->BorderWidth); + + if (mask & YNegative) +/* djhjr - 4/19/96 + JunkY = Scr->MyDisplayHeight - p->height - + (2 * Scr->BorderWidth) + JunkY; +*/ +/* djhjr - 8/11/98 + JunkY += Scr->MyDisplayHeight - p->height - + (2 * (Scr->ThreeDBorderWidth ? Scr->ThreeDBorderWidth : Scr->BorderWidth)); +*/ + JunkY += Scr->MyDisplayHeight - p->height - + (2 * Scr->BorderWidth); + + /* djhjr - 9/10/98 */ + if (p->width < 1) p->width = 1; + if (p->height < 1) p->height = 1; + + background = Scr->IconManagerC.back; + GetColorFromList(Scr->IconManagerBL, p->name, (XClassHint *)NULL, + &background); + + p->w = XCreateSimpleWindow(dpy, Scr->Root, + JunkX, JunkY, p->width, p->height, + + 0, /* was '1' - submitted by Rolf Neugebauer */ + + Scr->Black, background); + + sprintf(str, "%s Icon Manager", p->name); + sprintf(str1, "%s Icons", p->name); + if (p->icon_name) + icon_name = p->icon_name; + else + icon_name = str1; + + /* djhjr - 5/19/98 */ + /* was setting for the TwmWindow after AddWindow() - djhjr - 2/28/99 */ + class = XAllocClassHint(); + class->res_name = strdup(str); + class->res_class = strdup(VTWM_ICONMGR_CLASS); + XSetClassHint(dpy, p->w, class); + + XSetStandardProperties(dpy, p->w, str, icon_name, None, NULL, 0, NULL); + + p->twm_win = AddWindow(p->w, TRUE, p); + + SetMapStateProp (p->twm_win, WithdrawnState); + } + for (p = &Scr->iconmgr; p != NULL; p = p->next) + { + GrabButtons(p->twm_win); + GrabKeys(p->twm_win); + } +} + +/*********************************************************************** + * + * Procedure: + * AllocateIconManager - allocate a new icon manager + * + * Inputs: + * name - the name of this icon manager + * icon_name - the name of the associated icon + * geom - a geometry string to eventually parse + * columns - the number of columns this icon manager has + * + *********************************************************************** + */ + +IconMgr *AllocateIconManager(name, icon_name, geom, columns) + char *name; + char *geom; + char *icon_name; + int columns; +{ + IconMgr *p; + +#ifdef DEBUG_ICONMGR + fprintf(stderr, "AllocateIconManager\n"); + fprintf(stderr, " name=\"%s\" icon_name=\"%s\", geom=\"%s\", col=%d\n", + name, icon_name, geom, columns); +#endif + + if (Scr->NoIconManagers) + return NULL; + + p = (IconMgr *)malloc(sizeof(IconMgr)); + p->name = name; + p->icon_name = icon_name; + p->geometry = geom; + p->columns = columns; + p->first = NULL; + p->last = NULL; + p->active = NULL; + p->scr = Scr; + p->count = 0; + p->x = 0; + p->y = 0; + p->width = 150; + p->height = 10; + + Scr->iconmgr.lasti->next = p; + p->prev = Scr->iconmgr.lasti; + Scr->iconmgr.lasti = p; + p->next = NULL; + + return(p); +} + +/*********************************************************************** + * + * Procedure: + * MoveIconManager - move the pointer around in an icon manager + * + * Inputs: + * dir - one of the following: + * F_FORWICONMGR - forward in the window list + * F_BACKICONMGR - backward in the window list + * F_UPICONMGR - up one row + * F_DOWNICONMGR - down one row + * F_LEFTICONMGR - left one column + * F_RIGHTICONMGR - right one column + * + * Special Considerations: + * none + * + *********************************************************************** + */ + +void MoveIconManager(dir) + int dir; +{ + IconMgr *ip; + WList *tmp = NULL; + int cur_row, cur_col, new_row, new_col; + int row_inc, col_inc; + int got_it; + + if (!Active) return; + + cur_row = Active->row; + cur_col = Active->col; + ip = Active->iconmgr; + + row_inc = 0; + col_inc = 0; + got_it = FALSE; + + switch (dir) + { + case F_FORWICONMGR: + if ((tmp = Active->next) == NULL) + tmp = ip->first; + got_it = TRUE; + break; + + case F_BACKICONMGR: + if ((tmp = Active->prev) == NULL) + tmp = ip->last; + got_it = TRUE; + break; + + case F_UPICONMGR: + row_inc = -1; + break; + + case F_DOWNICONMGR: + row_inc = 1; + break; + + case F_LEFTICONMGR: + col_inc = -1; + break; + + case F_RIGHTICONMGR: + col_inc = 1; + break; + } + + /* If got_it is FALSE ast this point then we got a left, right, + * up, or down, command. We will enter this loop until we find + * a window to warp to. + */ + new_row = cur_row; + new_col = cur_col; + + while (!got_it) + { + new_row += row_inc; + new_col += col_inc; + if (new_row < 0) + new_row = ip->cur_rows - 1; + if (new_col < 0) + new_col = ip->cur_columns - 1; + if (new_row >= ip->cur_rows) + new_row = 0; + if (new_col >= ip->cur_columns) + new_col = 0; + + /* Now let's go through the list to see if there is an entry with this + * new position + */ + for (tmp = ip->first; tmp != NULL; tmp = tmp->next) + { + if (tmp->row == new_row && tmp->col == new_col) + { + got_it = TRUE; + break; + } + } + } + + if (!got_it) + { + fprintf (stderr, + "%s: unable to find window (%d, %d) in icon manager\n", + ProgramName, new_row, new_col); + return; + } + + if (tmp == NULL) + return; + + /* raise the frame so the icon manager is visible */ + if (ip->twm_win->mapped) { + XRaiseWindow(dpy, ip->twm_win->frame); + +/* djhjr - 5/30/00 + RaiseStickyAbove(); + RaiseAutoPan(); + + XWarpPointer(dpy, None, tmp->icon, 0,0,0,0, 5, 5); +*/ + WarpInIconMgr(tmp, ip->twm_win); + } else { +/* djhjr - 5/30/00 + if (tmp->twm->title_height) { + int tbx = Scr->TBInfo.titlex; + int x = tmp->twm->highlightx; + XWarpPointer (dpy, None, tmp->twm->title_w, 0, 0, 0, 0, + tbx + (x - tbx) / 2, + Scr->TitleHeight / 4); + } else { + XWarpPointer (dpy, None, tmp->twm->w, 0, 0, 0, 0, 5, 5); + } +*/ + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + + WarpToWindow(tmp->twm); + } +} + +/*********************************************************************** + * + * Procedure: + * JumpIconManager - jump from one icon manager to another, + * possibly even on another screen + * + * Inputs: + * dir - one of the following: + * F_NEXTICONMGR - go to the next icon manager + * F_PREVICONMGR - go to the previous one + * + *********************************************************************** + */ + +void JumpIconManager(dir) + register int dir; +{ + IconMgr *ip, *tmp_ip = NULL; + int got_it = FALSE; + ScreenInfo *sp; + int screen; + + if (!Active) return; + + +#define ITER(i) (dir == F_NEXTICONMGR ? (i)->next : (i)->prev) +#define IPOFSP(sp) (dir == F_NEXTICONMGR ? &(sp->iconmgr) : sp->iconmgr.lasti) +#define TEST(ip) if ((ip)->count != 0 && (ip)->twm_win->mapped) \ + { got_it = TRUE; break; } + + ip = Active->iconmgr; + for (tmp_ip = ITER(ip); tmp_ip; tmp_ip = ITER(tmp_ip)) { + TEST (tmp_ip); + } + + if (!got_it) { + int origscreen = ip->scr->screen; + int inc = (dir == F_NEXTICONMGR ? 1 : -1); + + for (screen = origscreen + inc; ; screen += inc) { + if (screen >= NumScreens) + screen = 0; + else if (screen < 0) + screen = NumScreens - 1; + + sp = ScreenList[screen]; + if (sp) { + for (tmp_ip = IPOFSP (sp); tmp_ip; tmp_ip = ITER(tmp_ip)) { + TEST (tmp_ip); + } + } + if (got_it || screen == origscreen) break; + } + } + +#undef ITER +#undef IPOFSP +#undef TEST + + if (!got_it) { + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + return; + } + + /* raise the frame so it is visible */ + XRaiseWindow(dpy, tmp_ip->twm_win->frame); + +/* djhjr - 5/30/00 + RaiseStickyAbove(); * DSE * + RaiseAutoPan(); +*/ + + if (tmp_ip->active) +/* djhjr - 5/30/00 + XWarpPointer(dpy, None, tmp_ip->active->icon, 0,0,0,0, 5, 5); +*/ + WarpInIconMgr(tmp_ip->active, tmp_ip->twm_win); + else +/* djhjr - 5/30/00 + XWarpPointer(dpy, None, tmp_ip->w, 0,0,0,0, 5, 5); +*/ + { + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + + WarpToWindow(tmp_ip->twm_win); + } +} + +/*********************************************************************** + * + * Procedure: + * AddIconManager - add a window to an icon manager + * + * Inputs: + * tmp_win - the TwmWindow structure + * + *********************************************************************** + */ + +WList *AddIconManager(tmp_win) + TwmWindow *tmp_win; +{ + WList *tmp; + int h; + unsigned long valuemask; /* mask for create windows */ + XSetWindowAttributes attributes; /* attributes for create windows */ + IconMgr *ip; + + tmp_win->list = NULL; + + /* djhjr - 10/2/01 */ + if (Scr->StrictIconManager) + { + if (tmp_win->icon || (!tmp_win->iconified && + (tmp_win->wmhints && + (tmp_win->wmhints->flags & StateHint) && + tmp_win->wmhints->initial_state == IconicState))) + ; + else + return NULL; + } + + if (tmp_win->iconmgr || tmp_win->transient || Scr->NoIconManagers) + return NULL; + + if (LookInList(Scr->IconMgrNoShow, tmp_win->full_name, &tmp_win->class)) + return NULL; + if (Scr->IconManagerDontShow && + !LookInList(Scr->IconMgrShow, tmp_win->full_name, &tmp_win->class)) + return NULL; + if ((ip = (IconMgr *)LookInList(Scr->IconMgrs, tmp_win->full_name, + &tmp_win->class)) == NULL) + ip = &Scr->iconmgr; + + tmp = (WList *) malloc(sizeof(WList)); + tmp->iconmgr = ip; + tmp->next = NULL; + tmp->active = FALSE; + tmp->down = FALSE; + + InsertInIconManager(ip, tmp, tmp_win); + + tmp->twm = tmp_win; + +/* djhjr - 4/19/96 + tmp->fore = Scr->IconManagerC.fore; + tmp->back = Scr->IconManagerC.back; +*/ + tmp->cp.fore = Scr->IconManagerC.fore; + tmp->cp.back = Scr->IconManagerC.back; + + tmp->highlight = Scr->IconManagerHighlight; + +/* djhjr - 4/19/96 + GetColorFromList(Scr->IconManagerFL, tmp_win->full_name, &tmp_win->class, + &tmp->fore); + GetColorFromList(Scr->IconManagerBL, tmp_win->full_name, &tmp_win->class, + &tmp->back); +*/ + GetColorFromList(Scr->IconManagerFL, tmp_win->full_name, &tmp_win->class, + &tmp->cp.fore); + GetColorFromList(Scr->IconManagerBL, tmp_win->full_name, &tmp_win->class, + &tmp->cp.back); + + GetColorFromList(Scr->IconManagerHighlightL, tmp_win->full_name, + &tmp_win->class, &tmp->highlight); + + /* djhjr - 4/19/96 */ + /* was 'Scr->use3Diconmanagers' - djhjr - 8/11/98 */ +/* djhjr - 10/30/02 + if (Scr->IconMgrBevelWidth > 0) +*/ + { + if (!Scr->BeNiceToColormap) GetShadeColors (&tmp->cp); +/* djhjr - 10/30/02 + tmp->iconifypm = Create3DIconManagerIcon (tmp->cp); +*/ + tmp->iconifypm = GetImage(Scr->iconMgrIconName, + iconifybox_width, iconifybox_height, + 0, tmp->cp); + } + + /* djhjr - 5/2/98 */ + h = ComputeIconMgrWindowHeight(); + + ip->height = h * ip->count; + tmp->me = ip->count; + tmp->x = -1; + tmp->y = -1; + + valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor); + +/* djhjr - 4/19/96 + attributes.background_pixel = tmp->back; + attributes.border_pixel = tmp->back; +*/ + attributes.background_pixel = tmp->cp.back; + attributes.border_pixel = tmp->cp.back; + + attributes.event_mask = (KeyPressMask | ButtonPressMask | + ButtonReleaseMask | ExposureMask | + EnterWindowMask | LeaveWindowMask); + attributes.cursor = Scr->IconMgrCursor; + + /* djhjr - 9/17/96 */ + if (Scr->BackingStore) + { + attributes.backing_store = WhenMapped; + valuemask |= CWBackingStore; + } + + tmp->w = XCreateWindow (dpy, ip->w, 0, 0, (unsigned int) 1, + (unsigned int) h, (unsigned int) 0, + CopyFromParent, (unsigned int) CopyFromParent, + (Visual *) CopyFromParent, valuemask, &attributes); + + + valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor); + +/* djhjr - 4/19/96 + attributes.background_pixel = tmp->back; +*/ + attributes.background_pixel = tmp->cp.back; + + attributes.border_pixel = Scr->Black; + attributes.event_mask = (ButtonReleaseMask| ButtonPressMask | + ExposureMask); + attributes.cursor = Scr->ButtonCursor; + + /* djhjr - 5/5/98 */ + if (!iconmgr_iconx) + { + /* was 'Scr->use3Diconmanagers' - djhjr - 8/11/98 */ + if (Scr->IconMgrBevelWidth > 0) + iconmgr_iconx = Scr->IconMgrBevelWidth + 5; + else + iconmgr_iconx = Scr->BorderWidth + 5; + iconmgr_textx = iconmgr_iconx + siconify_width + 5; + } + + /* 'iconmgr_iconx' was '5' - djhjr - 5/5/98 */ + tmp->icon = XCreateWindow (dpy, tmp->w, iconmgr_iconx, (int) (h - siconify_height)/2, + (unsigned int) siconify_width, + (unsigned int) siconify_height, + (unsigned int) 0, CopyFromParent, + (unsigned int) CopyFromParent, + (Visual *) CopyFromParent, + valuemask, &attributes); + + ip->count += 1; + PackIconManager(ip); + XMapWindow(dpy, tmp->w); + + XSaveContext(dpy, tmp->w, IconManagerContext, (caddr_t) tmp); + XSaveContext(dpy, tmp->w, TwmContext, (caddr_t) tmp_win); + XSaveContext(dpy, tmp->w, ScreenContext, (caddr_t) Scr); + XSaveContext(dpy, tmp->icon, TwmContext, (caddr_t) tmp_win); + XSaveContext(dpy, tmp->icon, ScreenContext, (caddr_t) Scr); + tmp_win->list = tmp; + + if (!ip->twm_win->icon) + { + XMapWindow(dpy, ip->w); + XMapWindow(dpy, ip->twm_win->frame); + } + + /* djhjr - 9/21/99 */ + else + XMapWindow(dpy, ip->twm_win->icon_w); + + return (tmp); +} + +/*********************************************************************** + * + * Procedure: + * InsertInIconManager - put an allocated entry into an icon + * manager + * + * Inputs: + * ip - the icon manager pointer + * tmp - the entry to insert + * + *********************************************************************** + */ + +void InsertInIconManager(ip, tmp, tmp_win) + IconMgr *ip; + WList *tmp; + TwmWindow *tmp_win; +{ + WList *tmp1; + int added; + int (*compar)() = (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1); + + added = FALSE; + if (ip->first == NULL) + { + ip->first = tmp; + tmp->prev = NULL; + ip->last = tmp; + added = TRUE; + } + else if (Scr->SortIconMgr) + { + for (tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next) + { + if ((*compar)(tmp_win->icon_name, tmp1->twm->icon_name) < 0) + { + tmp->next = tmp1; + tmp->prev = tmp1->prev; + tmp1->prev = tmp; + if (tmp->prev == NULL) + ip->first = tmp; + else + tmp->prev->next = tmp; + added = TRUE; + break; + } + } + } + + if (!added) + { + ip->last->next = tmp; + tmp->prev = ip->last; + ip->last = tmp; + } +} + +void RemoveFromIconManager(ip, tmp) + IconMgr *ip; + WList *tmp; +{ + if (tmp->prev == NULL) + ip->first = tmp->next; + else + tmp->prev->next = tmp->next; + + if (tmp->next == NULL) + ip->last = tmp->prev; + else + tmp->next->prev = tmp->prev; +} + +/*********************************************************************** + * + * Procedure: + * RemoveIconManager - remove a window from the icon manager + * + * Inputs: + * tmp_win - the TwmWindow structure + * + *********************************************************************** + */ + +void RemoveIconManager(tmp_win) + TwmWindow *tmp_win; +{ + IconMgr *ip; + WList *tmp; + + if (tmp_win->list == NULL) + return; + + tmp = tmp_win->list; + + /* submitted by Jonathan Paisley - 11/11/02 */ + if (Active == tmp) + Active = NULL; + + /* + * Believe it or not, the kludge in events.c:HandleKeyPress() needs + * this, or a window that's been destroyed still registers there, + * even though the whole mess gets freed in just a few microseconds! + * + * djhjr - 6/5/98 + */ + /* + * Somehwere alone the line, whatever it was got fixed, and this is + * needed again - djhjr - 5/27/03 + */ +/*#ifdef NEVER*/ /* warps to icon managers uniquely handled in menus.c:WarpToWindow() */ + tmp->active = FALSE; + tmp->iconmgr->active = NULL; +/*#endif*/ + + tmp_win->list = NULL; + ip = tmp->iconmgr; + + RemoveFromIconManager(ip, tmp); + + XDeleteContext(dpy, tmp->icon, TwmContext); + XDeleteContext(dpy, tmp->icon, ScreenContext); + XDestroyWindow(dpy, tmp->icon); + XDeleteContext(dpy, tmp->w, IconManagerContext); + XDeleteContext(dpy, tmp->w, TwmContext); + XDeleteContext(dpy, tmp->w, ScreenContext); + XDestroyWindow(dpy, tmp->w); + ip->count -= 1; + +#ifdef NEVER /* can't do this, else we lose the button entirely! */ + /* about damn time I did this! - djhjr - 6/5/98 */ + XFreePixmap(dpy, tmp->iconifypm); +#endif + + free((char *) tmp); + + PackIconManager(ip); + + if (ip->count == 0) + { + /* djhjr - 9/21/99 */ + if (ip->twm_win->icon) + XUnmapWindow(dpy, ip->twm_win->icon_w); + else + + XUnmapWindow(dpy, ip->twm_win->frame); + } + +} + +void ActiveIconManager(active) + WList *active; +{ + active->active = TRUE; + Active = active; + Active->iconmgr->active = active; + +/* djhjr - 4/19/96 + DrawIconManagerBorder(active); +*/ + DrawIconManagerBorder(active, False); +} + +void NotActiveIconManager(active) + WList *active; +{ + active->active = FALSE; + +/* djhjr - 4/19/96 + DrawIconManagerBorder(active); +*/ + DrawIconManagerBorder(active, False); +} + +/* djhjr - 4/19/96 +void DrawIconManagerBorder(tmp) + WList *tmp; +*/ +void DrawIconManagerBorder(tmp, fill) + WList *tmp; + int fill; +{ + /* was 'Scr->use3Diconmanagers' - djhjr - 8/11/98 */ + if (Scr->IconMgrBevelWidth > 0) { + int shadow_width; + +/* djhjr - 4/28/98 + shadow_width = 2; +*/ + shadow_width = Scr->IconMgrBevelWidth; + +/* djhjr - 1/27/98 + if (tmp->active && Scr->Highlight) +*/ + if (tmp->active && Scr->IconMgrHighlight) + Draw3DBorder (tmp->w, 0, 0, tmp->width, tmp->height, shadow_width, + tmp->cp, on, fill, False); + else + Draw3DBorder (tmp->w, 0, 0, tmp->width, tmp->height, shadow_width, + tmp->cp, off, fill, False); + } + else { +/* + XSetForeground(dpy, Scr->NormalGC, tmp->fore); +*/ + XSetForeground(dpy, Scr->NormalGC, tmp->cp.fore); + XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 2, 2, + tmp->width-5, tmp->height-5); + +/* djhjr - 1/27/98 + if (tmp->active && Scr->Highlight) +*/ + if (tmp->active && Scr->IconMgrHighlight) + XSetForeground(dpy, Scr->NormalGC, tmp->highlight); + else +/* + XSetForeground(dpy, Scr->NormalGC, tmp->back); +*/ + XSetForeground(dpy, Scr->NormalGC, tmp->cp.back); + + XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 0, 0, + tmp->width-1, tmp->height-1); + XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 1, 1, + tmp->width-3, tmp->height-3); + } +} + +/*********************************************************************** + * + * Procedure: + * SortIconManager - sort the dude + * + * Inputs: + * ip - a pointer to the icon manager struture + * + *********************************************************************** + */ + +void SortIconManager(ip) + IconMgr *ip; +{ + WList *tmp1, *tmp2; + int done; + int (*compar)() = (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1); + + if (ip == NULL) + ip = Active->iconmgr; + + done = FALSE; + do + { + for (tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next) + { + if ((tmp2 = tmp1->next) == NULL) + { + done = TRUE; + break; + } + if ((*compar)(tmp1->twm->icon_name, tmp2->twm->icon_name) > 0) + { + /* take it out and put it back in */ + RemoveFromIconManager(ip, tmp2); + InsertInIconManager(ip, tmp2, tmp2->twm); + break; + } + } + } + while (!done); + PackIconManager(ip); +} + +/*********************************************************************** + * + * Procedure: + * PackIconManager - pack the icon manager windows following + * an addition or deletion + * + * Inputs: + * ip - a pointer to the icon manager struture + * + *********************************************************************** + */ + +void PackIconManager(ip) + IconMgr *ip; +{ + int newwidth, i, row, col, maxcol, colinc, rowinc, wheight, wwidth; + int new_x, new_y; + int savewidth; + WList *tmp; + + /* djhjr - 5/2/98 */ + wheight = ComputeIconMgrWindowHeight(); + + wwidth = ip->width / ip->columns; + + rowinc = wheight; + colinc = wwidth; + + row = 0; + col = ip->columns; + maxcol = 0; + for (i = 0, tmp = ip->first; tmp != NULL; i++, tmp = tmp->next) + { + tmp->me = i; + if (++col >= ip->columns) + { + col = 0; + row += 1; + } + if (col > maxcol) + maxcol = col; + + new_x = col * colinc; + new_y = (row-1) * rowinc; + + /* if the position or size has not changed, don't touch it */ + if (tmp->x != new_x || tmp->y != new_y || + tmp->width != wwidth || tmp->height != wheight) + { + XMoveResizeWindow(dpy, tmp->w, new_x, new_y, wwidth, wheight); + + tmp->row = row-1; + tmp->col = col; + tmp->x = new_x; + tmp->y = new_y; + tmp->width = wwidth; + tmp->height = wheight; + } + } + maxcol += 1; + + ip->cur_rows = row; + ip->cur_columns = maxcol; + ip->height = row * rowinc; + if (ip->height == 0) + ip->height = rowinc; + newwidth = maxcol * colinc; + if (newwidth == 0) + newwidth = colinc; + + XResizeWindow(dpy, ip->w, newwidth, ip->height); + + savewidth = ip->width; + if (ip->twm_win) + { + + /* limit the min and max sizes of an icon manager - djhjr - 3/1/99 */ + ip->twm_win->hints.flags |= (PMinSize | PMaxSize); + ip->twm_win->hints.min_width = maxcol * (2 * iconmgr_iconx + siconify_width); + ip->twm_win->hints.min_height = ip->height; + ip->twm_win->hints.max_width = Scr->MyDisplayWidth; + ip->twm_win->hints.max_height = ip->height; + +/* djhjr - 4/19/96 + SetupWindow (ip->twm_win, + ip->twm_win->frame_x, ip->twm_win->frame_y, + newwidth, ip->height + ip->twm_win->title_height, -1); +*/ + SetupWindow (ip->twm_win, + ip->twm_win->frame_x, ip->twm_win->frame_y, + newwidth + 2 * ip->twm_win->frame_bw3D, + ip->height + ip->twm_win->title_height + 2 * ip->twm_win->frame_bw3D, -1); + } + + ip->width = savewidth; +} + +/* + * ComputeIconMgrWindowHeight() + * scale the icon manager window height to the font used + * + * djhjr - 5/2/98 + */ +static int ComputeIconMgrWindowHeight() +{ + int h; + + /* was 'Scr->use3Diconmanagers' - djhjr - 8/11/98 */ + if (Scr->IconMgrBevelWidth > 0) + { + h = Scr->IconManagerFont.height + 2 * Scr->IconMgrBevelWidth + 4; + if (h < (siconify_height + 2 * Scr->IconMgrBevelWidth + 4)) + h = siconify_height + 2 * Scr->IconMgrBevelWidth + 4; + } + else + { + h = Scr->IconManagerFont.height + 10; + if (h < (siconify_height + 4)) + h = siconify_height + 4; + } + + /* make height be odd so buttons look nice and centered */ + if (!(h & 1)) h++; + + return (h); +} + diff --git a/iconmgr.h b/iconmgr.h new file mode 100644 index 0000000..227e810 --- /dev/null +++ b/iconmgr.h @@ -0,0 +1,97 @@ +/* + * Copyright 1989 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*********************************************************************** + * + * $XConsortium: iconmgr.h,v 1.11 89/12/10 17:47:02 jim Exp $ + * + * Icon Manager includes + * + * 09-Mar-89 Tom LaStrange File Created + * + ***********************************************************************/ + +#ifndef _ICONMGR_ +#define _ICONMGR_ + +typedef struct WList +{ + struct WList *next; + struct WList *prev; + struct TwmWindow *twm; + struct IconMgr *iconmgr; + Window w; + Window icon; + int x, y, width, height; + int row, col; + int me; + + /* djhjr - 4/19/96 */ + ColorPair cp; + /* was Pixmap - djhjr - 10/30/02 */ + Image *iconifypm; + + Pixel fore, back, highlight; + unsigned top, bottom; + short active; + short down; +} WList; + +typedef struct IconMgr +{ + struct IconMgr *next; /* pointer to the next icon manager */ + struct IconMgr *prev; /* pointer to the previous icon mgr */ + struct IconMgr *lasti; /* pointer to the last icon mgr */ + struct WList *first; /* first window in the list */ + struct WList *last; /* last window in the list */ + struct WList *active; /* the active entry */ + TwmWindow *twm_win; /* back pointer to the new parent */ + struct ScreenInfo *scr; /* the screen this thing is on */ + Window w; /* this icon manager window */ + char *geometry; /* geometry string */ + char *name; + char *icon_name; + int x, y, width, height; + int columns, cur_rows, cur_columns; + int count; +} IconMgr; + +extern int iconmgr_textx; +extern WList *DownIconManager; +extern void SetIconMgrPixmap(); +extern void CreateIconManagers(); +extern IconMgr *AllocateIconManager(); +extern void MoveIconManager(); +extern void JumpIconManager(); +extern WList *AddIconManager(); +extern void InsertInIconManager(); +extern void RemoveFromIconManager(); +extern void RemoveIconManager(); +extern void ActiveIconManager(); +extern void NotActiveIconManager(); +extern void DrawIconManagerBorder(); +extern void SortIconManager(); +extern void PackIconManager(); + +/* djhjr - 5/19/98 */ +#define VTWM_ICONMGR_CLASS "VTWM Icon Manager" + +#endif /* _ICONMGR_ */ diff --git a/icons.c b/icons.c new file mode 100644 index 0000000..4ea526e --- /dev/null +++ b/icons.c @@ -0,0 +1,970 @@ +/* + * Copyright 1989 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/********************************************************************** + * + * $XConsortium: icons.c,v 1.22 91/07/12 09:58:38 dave Exp $ + * + * Icon releated routines + * + * 10-Apr-89 Tom LaStrange Initial Version. + * + **********************************************************************/ + +#include +#include +#include "twm.h" +#include "screen.h" +#include "regions.h" +#include "list.h" +#include "gram.h" +#include "parse.h" +#include "util.h" + +extern void splitRegionEntry(); +extern int roundEntryUp(); +extern RegionEntry *prevRegionEntry(); +extern void mergeRegionEntries(); +extern void downRegionEntry(); +extern RootRegion *AddRegion(); + +#define iconWidth(w) (Scr->IconBorderWidth * 2 + w->icon_w_width) +#define iconHeight(w) (Scr->IconBorderWidth * 2 + w->icon_w_height) + +void PlaceIcon(tmp_win, def_x, def_y, final_x, final_y) +TwmWindow *tmp_win; +int def_x, def_y; +int *final_x, *final_y; +{ + RootRegion *rr; + RegionEntry *re; + int w, h; + + re = 0; + for (rr = Scr->FirstIconRegion; rr; rr = rr->next) { + w = roundEntryUp (iconWidth (tmp_win), rr->stepx); + h = roundEntryUp (iconHeight (tmp_win), rr->stepy); + for (re = rr->entries; re; re=re->next) { + if (re->usedby) + continue; +/* don't include grid spacing - djhjr - 5/22/99 + if (re->w >= w && re->h >= h) +*/ + if (re->w >= iconWidth(tmp_win) && re->h >= iconHeight(tmp_win)) + break; + } + if (re) + break; + } + if (re) { + splitRegionEntry (re, rr->grav1, rr->grav2, w, h); + re->usedby = USEDBY_TWIN; + re->u.twm_win = tmp_win; + +/* evenly spaced icon placement - djhjr - 4/24/99 + *final_x = re->x + (re->w - iconWidth (tmp_win)) / 2; + *final_y = re->y + (re->h - iconHeight (tmp_win)) / 2; +*/ + *final_x = re->x; + *final_y = re->y; + + /* adjust for region gravity - djhjr 4/26/99 */ + if (rr->grav2 == D_EAST) + *final_x += re->w - iconWidth(tmp_win); + if (rr->grav1 == D_SOUTH) + *final_y += re->h - iconHeight(tmp_win); + + } else { + *final_x = def_x; + *final_y = def_y; + } + return; +} + +static RegionEntry * +FindIconEntry (tmp_win, rrp) + TwmWindow *tmp_win; + RootRegion **rrp; +{ + RootRegion *rr; + RegionEntry *re; + + for (rr = Scr->FirstIconRegion; rr; rr = rr->next) { + for (re = rr->entries; re; re=re->next) + if (re->u.twm_win == tmp_win) { + if (rrp) + *rrp = rr; + return re; + } + } + return 0; +} + +void IconUp (tmp_win) + TwmWindow *tmp_win; +{ + int x, y; + int defx, defy; + struct RootRegion *rr; + + /* + * If the client specified a particular location, let's use it (this might + * want to be an option at some point). Otherwise, try to fit within the + * icon region. + */ + if (tmp_win->wmhints && (tmp_win->wmhints->flags & IconPositionHint)) + return; + + if (tmp_win->icon_moved) { + if (!XGetGeometry (dpy, tmp_win->icon_w, &JunkRoot, &defx, &defy, + &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth)) + return; + +/* evenly spaced icon placement - djhjr - 4/24/99 + x = defx + ((int) JunkWidth) / 2; + y = defy + ((int) JunkHeight) / 2; +*/ + x = defx; + y = defy; + + for (rr = Scr->FirstIconRegion; rr; rr = rr->next) { + if (x >= rr->x && x < (rr->x + rr->w) && + y >= rr->y && y < (rr->y + rr->h)) + break; + } + if (!rr) return; /* outside icon regions, leave alone */ + } + + defx = -100; + defy = -100; + PlaceIcon(tmp_win, defx, defy, &x, &y); + if (x != defx || y != defy) { + XMoveWindow (dpy, tmp_win->icon_w, x, y); + tmp_win->icon_moved = FALSE; /* since we've restored it */ + } +} + +void +IconDown (tmp_win) + TwmWindow *tmp_win; +{ + RegionEntry *re; + RootRegion *rr; + + re = FindIconEntry (tmp_win, &rr); + if (re) + downRegionEntry(rr, re); +} + +void +AddIconRegion(geom, grav1, grav2, stepx, stepy) +char *geom; +int grav1, grav2, stepx, stepy; +{ + RootRegion *rr; + + rr = AddRegion(geom, grav1, grav2, stepx, stepy); + + if (Scr->LastIconRegion) + Scr->LastIconRegion->next = rr; + Scr->LastIconRegion = rr; + if (!Scr->FirstIconRegion) + Scr->FirstIconRegion = rr; +} + +#ifdef ORIGINAL_PIXMAPS +void CreateIconWindow(tmp_win, def_x, def_y) +TwmWindow *tmp_win; +int def_x, def_y; +{ + unsigned long event_mask; + unsigned long valuemask; /* mask for create windows */ + XSetWindowAttributes attributes; /* attributes for create windows */ + Pixmap pm = None; /* tmp pixmap variable */ + int final_x, final_y; + int x; + + /* djhjr - 4/27/96 */ + GetColorFromList(Scr->IconBorderColorL, tmp_win->full_name, &tmp_win->class, + &tmp_win->icon_border); + GetColorFromList(Scr->IconForegroundL, tmp_win->full_name, &tmp_win->class, + &tmp_win->iconc.fore); + GetColorFromList(Scr->IconBackgroundL, tmp_win->full_name, &tmp_win->class, + &tmp_win->iconc.back); + +/* djhjr - 5/5/98 + if (Scr->use3Diconmanagers && !Scr->BeNiceToColormap) GetShadeColors(&tmp_win->iconc); +*/ + /* was 'Scr->use3Dicons' - djhjr - 8/11/98 */ + if (Scr->IconBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors(&tmp_win->iconc); + + FB(tmp_win->iconc.fore, tmp_win->iconc.back); + + tmp_win->forced = FALSE; + tmp_win->icon_not_ours = FALSE; + + /* now go through the steps to get an icon window, if ForceIcon is + * set, then no matter what else is defined, the bitmap from the + * .twmrc file is used + */ + if (Scr->ForceIcon) + { + char *icon_name; + Pixmap bm; + + icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name); + if (icon_name == NULL) + icon_name = LookInList(Scr->IconNames, tmp_win->full_name, + &tmp_win->class); + + bm = None; + if (icon_name != NULL) + { + if ((bm = (Pixmap)LookInNameList(Scr->Icons, icon_name)) == None) + { + if ((bm = GetBitmap (icon_name)) != None) + /* added 'type' argument - djhjr - 10/20/01 */ + AddToList(&Scr->Icons, icon_name, LTYPE_EXACT_NAME, + (char *)bm); + } + } + + if (bm != None) + { + XGetGeometry(dpy, bm, &JunkRoot, &JunkX, &JunkY, + (unsigned int *) &tmp_win->icon_width, (unsigned int *)&tmp_win->icon_height, + &JunkBW, &JunkDepth); + + pm = XCreatePixmap(dpy, Scr->Root, tmp_win->icon_width, + tmp_win->icon_height, Scr->d_depth); + + /* the copy plane works on color ! */ + XCopyPlane(dpy, bm, pm, Scr->NormalGC, + 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 ); + + tmp_win->forced = TRUE; + } + } + + /* if the pixmap is still NULL, we didn't get one from the above code, + * that could mean that ForceIcon was not set, or that the window + * was not in the Icons list, now check the WM hints for an icon + */ + if (pm == None && tmp_win->wmhints && + tmp_win->wmhints->flags & IconPixmapHint) + { + + XGetGeometry(dpy, tmp_win->wmhints->icon_pixmap, + &JunkRoot, &JunkX, &JunkY, + (unsigned int *)&tmp_win->icon_width, (unsigned int *)&tmp_win->icon_height, &JunkBW, &JunkDepth); + + pm = XCreatePixmap(dpy, Scr->Root, + tmp_win->icon_width, tmp_win->icon_height, + Scr->d_depth); + + XCopyPlane(dpy, tmp_win->wmhints->icon_pixmap, pm, Scr->NormalGC, + 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 ); + } + + /* if we still haven't got an icon, let's look in the Icon list + * if ForceIcon is not set + */ + if (pm == None && !Scr->ForceIcon) + { + char *icon_name; + Pixmap bm; + + icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name); + if (icon_name == NULL) + icon_name = LookInList(Scr->IconNames, tmp_win->full_name, + &tmp_win->class); + + bm = None; + if (icon_name != NULL) + { + if ((bm = (Pixmap)LookInNameList(Scr->Icons, icon_name)) == None) + { + if ((bm = GetBitmap (icon_name)) != None) + /* added 'type' argument - djhjr - 10/20/01 */ + AddToList(&Scr->Icons, icon_name, LTYPE_EXACT_NAME, + (char *)bm); + } + } + + if (bm != None) + { + XGetGeometry(dpy, bm, &JunkRoot, &JunkX, &JunkY, + (unsigned int *)&tmp_win->icon_width, (unsigned int *)&tmp_win->icon_height, + &JunkBW, &JunkDepth); + + pm = XCreatePixmap(dpy, Scr->Root, tmp_win->icon_width, + tmp_win->icon_height, Scr->d_depth); + + /* the copy plane works on color ! */ + XCopyPlane(dpy, bm, pm, Scr->NormalGC, + 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 ); + } + } + + /* if we still don't have an icon, assign the UnknownIcon */ + + if (pm == None && Scr->UnknownPm != None) + { + tmp_win->icon_width = Scr->UnknownWidth; + tmp_win->icon_height = Scr->UnknownHeight; + + pm = XCreatePixmap(dpy, Scr->Root, tmp_win->icon_width, + tmp_win->icon_height, Scr->d_depth); + + /* the copy plane works on color ! */ + XCopyPlane(dpy, Scr->UnknownPm, pm, Scr->NormalGC, + 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 ); + } + + if (pm == None) + { + tmp_win->icon_height = 0; + tmp_win->icon_width = 0; + valuemask = 0; + } + else + { + /* added pixel specs - djhjr - 12/28/98 */ + valuemask = CWBackPixmap | CWBackPixel; + attributes.background_pixmap = pm; + attributes.background_pixel = tmp_win->iconc.fore; + } + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + tmp_win->icon_w_width = MyFont_TextWidth(&Scr->IconFont, +#else + tmp_win->icon_w_width = XTextWidth(Scr->IconFont.font, +#endif + tmp_win->icon_name, strlen(tmp_win->icon_name)); + +/* djhjr - 6/11/96 + tmp_win->icon_w_width += 6; + if (tmp_win->icon_w_width < tmp_win->icon_width) + { + tmp_win->icon_x = (tmp_win->icon_width - tmp_win->icon_w_width)/2; + tmp_win->icon_x += 3; + tmp_win->icon_w_width = tmp_win->icon_width; + } + else + { + tmp_win->icon_x = 3; + } +*/ + tmp_win->icon_w_width += 8; + if (tmp_win->icon_w_width < tmp_win->icon_width + 8) + { + tmp_win->icon_x = (((tmp_win->icon_width + 8) - tmp_win->icon_w_width)/2) + 4; + tmp_win->icon_w_width = tmp_win->icon_width + 8; + } + else + tmp_win->icon_x = 4; + +/* djhjr - 6/11/96 + tmp_win->icon_y = tmp_win->icon_height + Scr->IconFont.height; +*/ + tmp_win->icon_y = tmp_win->icon_height + Scr->IconFont.height + 2; + +/* djhjr - 4/27/96 + tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 4; +*/ +/* djhjr - 6/11/96 + tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 6; +*/ + tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 8; + + event_mask = 0; + if (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint) + { + tmp_win->icon_w = tmp_win->wmhints->icon_window; + if (tmp_win->forced || + XGetGeometry(dpy, tmp_win->icon_w, &JunkRoot, &JunkX, &JunkY, + (unsigned int *)&tmp_win->icon_w_width, (unsigned int *)&tmp_win->icon_w_height, + &JunkBW, &JunkDepth) == 0) + { + tmp_win->icon_w = None; + tmp_win->wmhints->flags &= ~IconWindowHint; + } + else + { + tmp_win->icon_not_ours = TRUE; + event_mask = EnterWindowMask | LeaveWindowMask; + } + } + else + { + tmp_win->icon_w = None; + } + + /* djhjr - 5/5/98 */ + /* was 'Scr->use3Dicons' and 'Scr->BorderBevelWidth' - djhjr - 8/11/98 */ + if (Scr->IconBevelWidth > 0) + { + tmp_win->icon_w_width += 2 * Scr->IconBevelWidth; + tmp_win->icon_w_height += 2 * Scr->IconBevelWidth; + + tmp_win->icon_x += Scr->IconBevelWidth; + tmp_win->icon_y += Scr->IconBevelWidth; + } + + if (tmp_win->icon_w == None) + { + tmp_win->icon_w = XCreateSimpleWindow(dpy, Scr->Root, + 0,0, + tmp_win->icon_w_width, tmp_win->icon_w_height, + Scr->IconBorderWidth, tmp_win->icon_border, tmp_win->iconc.back); + event_mask = ExposureMask; + } + + XSelectInput (dpy, tmp_win->icon_w, + KeyPressMask | ButtonPressMask | ButtonReleaseMask | + event_mask); + + tmp_win->icon_bm_w = None; + if (pm != None && + (! (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint))) + { + int y; + +/* djhjr - 6/11/96 + y = 0; +*/ + y = 4; + + if (tmp_win->icon_w_width == tmp_win->icon_width) + x = 0; + else + x = (tmp_win->icon_w_width - tmp_win->icon_width)/2; + + /* djhjr - 5/5/98 */ + /* was 'Scr->use3Dicons' and 'Scr->BorderBevelWidth' - djhjr - 8/11/98 */ + if (Scr->IconBevelWidth > 0) + y += Scr->IconBevelWidth; + + tmp_win->icon_bm_w = XCreateWindow (dpy, tmp_win->icon_w, x, y, + (unsigned int)tmp_win->icon_width, + (unsigned int)tmp_win->icon_height, + (unsigned int) 0, Scr->d_depth, + (unsigned int) CopyFromParent, + Scr->d_visual, valuemask, + &attributes); + } + + /* I need to figure out where to put the icon window now, because + * getting here means that I am going to make the icon visible + */ + if (tmp_win->wmhints && + tmp_win->wmhints->flags & IconPositionHint) + { + final_x = tmp_win->wmhints->icon_x; + final_y = tmp_win->wmhints->icon_y; + } + else + { + PlaceIcon(tmp_win, def_x, def_y, &final_x, &final_y); + } + + if (final_x > Scr->MyDisplayWidth) + final_x = Scr->MyDisplayWidth - tmp_win->icon_w_width - + (2 * Scr->IconBorderWidth); + + if (final_y > Scr->MyDisplayHeight) + final_y = Scr->MyDisplayHeight - tmp_win->icon_height - + Scr->IconFont.height - 4 - (2 * Scr->IconBorderWidth); + + XMoveWindow(dpy, tmp_win->icon_w, final_x, final_y); + tmp_win->iconified = TRUE; + + XMapSubwindows(dpy, tmp_win->icon_w); + XSaveContext(dpy, tmp_win->icon_w, TwmContext, (caddr_t)tmp_win); + XSaveContext(dpy, tmp_win->icon_w, ScreenContext, (caddr_t)Scr); + XDefineCursor(dpy, tmp_win->icon_w, Scr->IconCursor); + if (pm) XFreePixmap (dpy, pm); + return; +} +#else /* ORIGINAL_PIXMAPS */ +/* + * to help clean up CreateIconWindow() below - djhjr - 8/13/98 + * added background color and XPM indicator - djhjr - 12/28/98 + */ +Image * +GetIconImage(name, background, numcolors) +char *name; +Pixel background; +unsigned int *numcolors; +{ + Image *iconimage; + GC gc; + Pixmap bm; + int bitmap_height, bitmap_width; + + iconimage = (Image *)LookInNameList(Scr->Icons, name); + if (iconimage == NULL) + { + bm = FindBitmap(name, &bitmap_width, &bitmap_height); + if (bm != None) + { + iconimage = (Image *)malloc(sizeof(Image)); + iconimage->mask = None; + iconimage->height = bitmap_height; + iconimage->width = bitmap_width; + iconimage->pixmap = XCreatePixmap(dpy, Scr->Root, bitmap_width, + bitmap_height, Scr->d_depth); + + XGetGeometry(dpy, bm, + &JunkRoot, &JunkX, &JunkY, + &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth); + + /* + * XCopyArea() seems to be necessary for some apps that change + * their icons - djhjr - rem'd 8/23/98, re-instated 11/15/98 + */ + if (JunkDepth == Scr->d_depth) + XCopyArea(dpy, bm, iconimage->pixmap, + Scr->NormalGC, 0, 0, iconimage->width, iconimage->height, + 0, 0); + else + XCopyPlane(dpy, bm, iconimage->pixmap, + Scr->NormalGC, 0, 0, iconimage->width, iconimage->height, + 0, 0, 1); + + iconimage->mask = XCreatePixmap(dpy, Scr->Root, + iconimage->width, iconimage->height, 1); + if (iconimage->mask) + { + gc = XCreateGC(dpy, iconimage->mask, 0, NULL); + if (gc) + { + XCopyArea(dpy, bm, iconimage->mask, + gc, 0, 0, iconimage->width, iconimage->height, 0, 0); + XFreeGC (dpy, gc); + } + } + + XFreePixmap(dpy, bm); + } +#ifndef NO_XPM_SUPPORT + else + { + /* added color argument - djhjr - 9/28/99 */ + iconimage = FindImage(name, background); + } +#endif + + if (iconimage != NULL) + /* added 'type' argument - djhjr - 10/20/01 */ + AddToList(&Scr->Icons, name, LTYPE_EXACT_NAME, + (char *)iconimage); + } + + /* djhjr - 12/28/98 */ + *numcolors = 0; +#ifndef NO_XPM_SUPPORT + if (iconimage != NULL) + *numcolors = SetPixmapsBackground(iconimage, Scr->Root, background); +#endif + + return (iconimage); +} + +/* + * Submitted by Jason Gloudon + */ +void +CreateIconWindow(tmp_win, def_x, def_y) +TwmWindow *tmp_win; +int def_x, def_y; +{ + unsigned long event_mask; + unsigned long valuemask; /* mask for create windows */ + XSetWindowAttributes attributes; /* attributes for create windows */ + Pixmap pm; /* tmp pixmap variable */ + Image *iconimage; + char *icon_name; + int x, final_x, final_y; + unsigned int pm_numcolors = 0; /* djhjr - 12/28/98 */ + + /* djhjr - 4/27/96 */ + GetColorFromList(Scr->IconBorderColorL, tmp_win->full_name, &tmp_win->class, + &tmp_win->icon_border); + GetColorFromList(Scr->IconForegroundL, tmp_win->full_name, &tmp_win->class, + &tmp_win->iconc.fore); + GetColorFromList(Scr->IconBackgroundL, tmp_win->full_name, &tmp_win->class, + &tmp_win->iconc.back); + +/* djhjr - 5/5/98 + if (Scr->use3Diconmanagers && !Scr->BeNiceToColormap) GetShadeColors(&tmp_win->iconc); +*/ + /* was 'Scr->use3Dicons' - djhjr - 8/11/98 */ + if (Scr->IconBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors(&tmp_win->iconc); + + FB(tmp_win->iconc.fore, tmp_win->iconc.back); + + tmp_win->forced = FALSE; + tmp_win->icon_not_ours = FALSE; + iconimage = NULL; + pm = None; + + /* + * now go through the steps to get an icon window, if ForceIcon is + * set, then no matter what else is defined, the bitmap from the + * .vtwmrc file is used + */ + if (Scr->ForceIcon) + { + icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name); + if (icon_name == NULL) + icon_name = LookInList(Scr->IconNames, tmp_win->full_name, + &tmp_win->class); + + if (icon_name != NULL) + /* added background and XPM indicator - djhjr - 12/28/98 */ + iconimage = GetIconImage(icon_name, tmp_win->iconc.back, + &pm_numcolors); + + if (iconimage != NULL) + { + tmp_win->icon_width = iconimage->width; + tmp_win->icon_height = iconimage->height; + + pm = iconimage->pixmap; + tmp_win->forced = TRUE; + } + } + + /* + * if the pixmap is still NULL, we didn't get one from the above code, + * that could mean that ForceIcon was not set, or that the window + * was not in the Icons list, now check the WM hints for an icon + */ + if (pm == None && tmp_win->wmhints && + tmp_win->wmhints->flags & IconPixmapHint) + { +/* djhjr - 8/14/98 + XGetGeometry(dpy, tmp_win->wmhints->icon_pixmap, + &JunkRoot, &JunkX, &JunkY, + (unsigned int *)&tmp_win->icon_width, + (unsigned int *)&tmp_win->icon_height, &JunkBW, &JunkDepth); + + pm = XCreatePixmap(dpy, Scr->Root, + tmp_win->icon_width, tmp_win->icon_height, + Scr->d_depth); + + XCopyPlane(dpy, tmp_win->wmhints->icon_pixmap, pm, Scr->NormalGC, + 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 ); + + XFreePixmap(dpy, pm); +*/ + XGetGeometry(dpy, tmp_win->wmhints->icon_pixmap, + &JunkRoot, &JunkX, &JunkY, + &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth); + + pm_numcolors = 3; /* Submitted by Caveh Frank Jalali */ + + iconimage = (Image*)malloc(sizeof(Image)); + iconimage->mask = None; + iconimage->width = JunkWidth; + iconimage->height = JunkHeight; + iconimage->pixmap = XCreatePixmap(dpy, Scr->Root, iconimage->width, + iconimage->height, Scr->d_depth); + + if (JunkDepth == Scr->d_depth) + XCopyArea(dpy, tmp_win->wmhints->icon_pixmap, iconimage->pixmap, + Scr->NormalGC, 0, 0, iconimage->width, iconimage->height, + 0, 0); + else + XCopyPlane(dpy, tmp_win->wmhints->icon_pixmap, iconimage->pixmap, + Scr->NormalGC, 0, 0, iconimage->width, iconimage->height, + 0, 0, 1); + + if ((tmp_win->wmhints->flags & IconMaskHint) && + XGetGeometry(dpy, tmp_win->wmhints->icon_mask, + &JunkRoot, &JunkX, &JunkY, &JunkWidth, &JunkHeight, + &JunkBW, &JunkDepth) && + JunkDepth == 1) + { + GC gc; + + iconimage->mask = XCreatePixmap(dpy, Scr->Root, + JunkWidth, JunkHeight, 1); + if (iconimage->mask) + { + gc = XCreateGC(dpy, iconimage->mask, 0, NULL); + if (gc) + { + XCopyArea(dpy, tmp_win->wmhints->icon_mask, iconimage->mask, + gc, 0, 0, JunkWidth, JunkHeight, 0, 0); + XFreeGC (dpy, gc); + } + } + } + + if (iconimage != NULL) + { + tmp_win->icon_width = iconimage->width; + tmp_win->icon_height = iconimage->height; + + pm = iconimage->pixmap; + } + } + + /* + * if we still haven't got an icon, let's look in the Icon list + * if ForceIcon is not set + */ + if (pm == None && !Scr->ForceIcon) + { + icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name); + if (icon_name == NULL) + icon_name = LookInList(Scr->IconNames, tmp_win->full_name, + &tmp_win->class); + + if (icon_name != NULL) + /* added background and XPM indicator - djhjr - 12/28/98 */ + iconimage = GetIconImage(icon_name, tmp_win->iconc.back, + &pm_numcolors); + + if (iconimage != NULL) + { + tmp_win->icon_width = iconimage->width; + tmp_win->icon_height = iconimage->height; + + pm = iconimage->pixmap; + } + } + + /* + * if we still don't have an icon, assign the UnknownIcon + */ +/* djhjr - 8/13/98 + if (pm == None && Scr->UnknownPm != None) + { + tmp_win->icon_width = Scr->UnknownWidth; + tmp_win->icon_height = Scr->UnknownHeight; + + pm = XCreatePixmap(dpy, Scr->Root, tmp_win->icon_width, + tmp_win->icon_height, Scr->d_depth); + + * the copy plane works on color ! * + XCopyPlane(dpy, Scr->UnknownPm, pm, Scr->NormalGC, + 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 ); + + XFreePixmap(dpy, pm); + } +*/ + if (pm == None && Scr->unknownName != NULL) + { + /* added background and XPM indicator - djhjr - 12/28/98 */ + iconimage = GetIconImage(Scr->unknownName, tmp_win->iconc.back, + &pm_numcolors); + + if (iconimage != NULL) + { + tmp_win->icon_width = iconimage->width; + tmp_win->icon_height = iconimage->height; + + pm = iconimage->pixmap; + } + } + + if (pm == None) + { + tmp_win->icon_height = 0; + tmp_win->icon_width = 0; + valuemask = 0; + } + else + { + valuemask = CWBackPixmap; + attributes.background_pixmap = pm; + + /* djhjr - 12/28/98 */ + if (pm_numcolors <= 2) /* not a pixmap */ + { + valuemask |= CWBackPixel; + attributes.background_pixel = tmp_win->iconc.fore; + } + } + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + tmp_win->icon_w_width = MyFont_TextWidth(&Scr->IconFont, +#else + tmp_win->icon_w_width = XTextWidth(Scr->IconFont.font, +#endif + tmp_win->icon_name, strlen(tmp_win->icon_name)); + +/* djhjr - 6/11/96 + tmp_win->icon_w_width += 6; + if (tmp_win->icon_w_width < tmp_win->icon_width) + { + tmp_win->icon_x = (tmp_win->icon_width - tmp_win->icon_w_width)/2; + tmp_win->icon_x += 3; + tmp_win->icon_w_width = tmp_win->icon_width; + } + else + { + tmp_win->icon_x = 3; + } +*/ + tmp_win->icon_w_width += 8; + if (tmp_win->icon_w_width < tmp_win->icon_width + 8) + { + tmp_win->icon_x = (((tmp_win->icon_width + 8) - tmp_win->icon_w_width)/2) + 4; + tmp_win->icon_w_width = tmp_win->icon_width + 8; + } + else + tmp_win->icon_x = 4; + +/* djhjr - 6/11/96 + tmp_win->icon_y = tmp_win->icon_height + Scr->IconFont.height; +*/ + tmp_win->icon_y = tmp_win->icon_height + Scr->IconFont.height + 2; + +/* djhjr - 4/27/96 + tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 4; +*/ +/* djhjr - 6/11/96 + tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 6; +*/ + tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 8; + + event_mask = 0; + if (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint) + { + tmp_win->icon_w = tmp_win->wmhints->icon_window; + if (tmp_win->forced || + XGetGeometry(dpy, tmp_win->icon_w, &JunkRoot, &JunkX, &JunkY, + (unsigned int *)&tmp_win->icon_w_width, (unsigned int *)&tmp_win->icon_w_height, + &JunkBW, &JunkDepth) == 0) + { + tmp_win->icon_w = None; + tmp_win->wmhints->flags &= ~IconWindowHint; + } + else + { + tmp_win->icon_not_ours = TRUE; + event_mask = EnterWindowMask | LeaveWindowMask; + } + } + else + { + tmp_win->icon_w = None; + } + + /* djhjr - 5/5/98 */ + /* was 'Scr->use3Dicons' and 'Scr->BorderBevelWidth' - djhjr - 8/11/98 */ + if (Scr->IconBevelWidth > 0) + { + tmp_win->icon_w_width += 2 * Scr->IconBevelWidth; + tmp_win->icon_w_height += 2 * Scr->IconBevelWidth; + + tmp_win->icon_x += Scr->IconBevelWidth; + tmp_win->icon_y += Scr->IconBevelWidth; + } + + if (tmp_win->icon_w == None) + { + tmp_win->icon_w = XCreateSimpleWindow(dpy, Scr->Root, + 0,0, + tmp_win->icon_w_width, tmp_win->icon_w_height, + Scr->IconBorderWidth, tmp_win->icon_border, tmp_win->iconc.back); + event_mask = ExposureMask; + } + + XSelectInput (dpy, tmp_win->icon_w, + KeyPressMask | ButtonPressMask | ButtonReleaseMask | + event_mask); + + tmp_win->icon_bm_w = None; + if (pm != None && + (! (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint))) + { + int y; + +/* djhjr - 6/11/96 + y = 0; +*/ + y = 4; + + if (tmp_win->icon_w_width == tmp_win->icon_width) + x = 0; + else + x = (tmp_win->icon_w_width - tmp_win->icon_width)/2; + + /* djhjr - 5/5/98 */ + /* was 'Scr->use3Dicons' and 'Scr->BorderBevelWidth' - djhjr - 8/11/98 */ + if (Scr->IconBevelWidth > 0) + y += Scr->IconBevelWidth; + + tmp_win->icon_bm_w = XCreateWindow (dpy, tmp_win->icon_w, x, y, + (unsigned int)tmp_win->icon_width, + (unsigned int)tmp_win->icon_height, + (unsigned int) 0, Scr->d_depth, + (unsigned int) CopyFromParent, + Scr->d_visual, valuemask, + &attributes); + + if (HasShape) + if (iconimage != NULL && iconimage->mask != None) + XShapeCombineMask(dpy,tmp_win->icon_bm_w , ShapeBounding, 0, 0, + iconimage->mask, ShapeSet); + } + + /* I need to figure out where to put the icon window now, because + * getting here means that I am going to make the icon visible + */ + if (tmp_win->wmhints && + tmp_win->wmhints->flags & IconPositionHint) + { + final_x = tmp_win->wmhints->icon_x; + final_y = tmp_win->wmhints->icon_y; + } + else + { + PlaceIcon(tmp_win, def_x, def_y, &final_x, &final_y); + } + + if (final_x > Scr->MyDisplayWidth) + final_x = Scr->MyDisplayWidth - tmp_win->icon_w_width - + (2 * Scr->IconBorderWidth); + + if (final_y > Scr->MyDisplayHeight) + final_y = Scr->MyDisplayHeight - tmp_win->icon_height - + Scr->IconFont.height - 4 - (2 * Scr->IconBorderWidth); + + XMoveWindow(dpy, tmp_win->icon_w, final_x, final_y); + tmp_win->iconified = TRUE; + + XMapSubwindows(dpy, tmp_win->icon_w); + XSaveContext(dpy, tmp_win->icon_w, TwmContext, (caddr_t)tmp_win); + XSaveContext(dpy, tmp_win->icon_w, ScreenContext, (caddr_t)Scr); + XDefineCursor(dpy, tmp_win->icon_w, Scr->IconCursor); + + return; +} +#endif /* ORIGINAL_PIXMAPS */ + diff --git a/lex.l b/lex.l new file mode 100644 index 0000000..f7e9c70 --- /dev/null +++ b/lex.l @@ -0,0 +1,111 @@ +%{ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + +/*********************************************************************** + * + * $XConsortium: lex.l,v 1.62 89/12/10 17:46:33 jim Exp $ + * + * .twmrc lex file + * + * 12-Nov-87 Thomas E. LaStrange File created + * + ***********************************************************************/ + +/* #include */ /* lex already includes stdio.h */ +#include "gram.h" +#include "parse.h" + +extern int parse_keyword(); +extern void twmrc_error_prefix(); + +extern char *ProgramName; +extern int ParseError; + +#ifdef FLEX_SCANNER +#undef YY_INPUT +#define YY_INPUT(b,r,s) r = ((b[0] = (*twmInputFunc)()) != 0) +#endif +%} + +string \"([^"]|\\.)*\" +regexp \/([^/]|\\.)*\/ +number [0-9]+ +%% +"{" { return (LB); } +"}" { return (RB); } +"(" { return (LP); } +")" { return (RP); } +"=" { return (EQUALS); } +"~" { return (TILDE); } +":" { return (COLON); } +"+" { return PLUS; } +"-" { return MINUS; } +"|" { return OR; } + +[a-zA-Z\.]+ { int token = parse_keyword (yytext, + &yylval.num); + if (token == ERRORTOKEN) { + twmrc_error_prefix(); + fprintf (stderr, + "ignoring unknown keyword: %s\n", + yytext); + ParseError = 1; + } else + return token; + } + +"!" { yylval.num = F_EXEC; return FSKEYWORD; } +"^" { yylval.num = F_CUT; return FSKEYWORD; } + +{string} { yylval.ptr = (char *)yytext; return STRING; } +{regexp} { yylval.ptr = (char *)yytext; return REGEXP; } +{number} { (void)sscanf((char *)&yytext[0], "%d", &yylval.num); + return (NUMBER); + } +\#[^\n]*\n {;} +[\n\t ] {;} +. { + twmrc_error_prefix(); + fprintf (stderr, + "ignoring character \"%s\"\n", + yytext); + ParseError = 1; + } +%% +#ifndef FLEX_SCANNER +yywrap() { return(1);} + +#undef input +#undef feof +#define feof() (1) +#define input() (*twmInputFunc)() +#endif +#undef output +#define output(c) TwmOutput(c) +#undef unput +#define unput(c) twmUnput(c) diff --git a/list.c b/list.c new file mode 100644 index 0000000..e91a69a --- /dev/null +++ b/list.c @@ -0,0 +1,704 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/********************************************************************** + * + * $XConsortium: list.c,v 1.20 91/01/09 17:13:30 rws Exp $ + * + * TWM code to deal with the name lists for the NoTitle list and + * the AutoRaise list + * + * 11-Apr-88 Tom LaStrange Initial Version. + * + **********************************************************************/ + +/* + * Stolen from TVTWM pl11, updated it to conform to the POSIX 1003.2 + * regex spec, backported VTWM 5.3's internal wildcarding code, and + * made it work without regex support. + * + * D. J. Hawkey Jr. - 10/20/01 + */ + +#include +#include + +#ifndef NO_REGEX_SUPPORT +#include +#include +#endif + +#include "twm.h" +#include "screen.h" +#include "list.h" +#include "gram.h" + +#define REGCOMP_FLAGS (REG_EXTENDED | REG_NOSUB) + +#define strdup Strdup /* avoid conflict with system header files */ +extern char *strdup(char *); + +struct name_list_struct +{ + name_list *next; /* pointer to the next name */ + char *name; /* the name of the window */ +#ifndef NO_REGEX_SUPPORT + regex_t re; /* compile only once */ +#else + char re; /* not used */ +#endif + short type; /* what type of match */ + Atom property; /* if (type == property) */ + char *ptr; /* list dependent data */ +}; + +#ifndef NO_REGEX_SUPPORT +static char buffer[256]; +#endif + +int match(); + +/*********************************************************************** + * + * Wrappers to allow code to step through a list + * + ***********************************************************************/ + +name_list * +next_entry(list) +name_list *list; +{ + return (list->next); +} + +char * +contents_of_entry(list) +name_list *list; +{ + return (list->ptr); +} + +/**********************************************************************/ + +#ifdef DEBUG +static void +printNameList(name, nptr) +char *name; +name_list *nptr; +{ + printf("printNameList(): %s=[", name); + + while (nptr) + { + printf(" '%s':%d", nptr->name, nptr->type); + nptr = nptr->next; + } + + printf(" ]\n"); +} +#endif + +/*********************************************************************** + * + * Procedure: + * AddToList - add a window name to the appropriate list + * + * Inputs: + * list - the address of the pointer to the head of a list + * name - a pointer to the name of the window + * type - a bitmask of what to match against + * property- a window propery to match against + * ptr - pointer to list dependent data + * + * Special Considerations + * If the list does not use the ptr value, a non-null value + * should be placed in it. LookInList returns this ptr value + * and procedures calling LookInList will check for a non-null + * return value as an indication of success. + * + *********************************************************************** + */ + +void +AddToList(list_head, name, type, /*property, */ptr) +name_list **list_head; +char *name; +short type; +/* Atom property; */ +char *ptr; +{ + Atom property = None; + name_list *nptr; + + if (!list_head) return; /* ignore empty inserts */ + + nptr = (name_list *)malloc(sizeof(name_list)); + if (nptr == NULL) + { + fprintf (stderr, "%s: unable to allocate %d bytes for name_list\n", + ProgramName, sizeof(name_list)); + Done(); + } + +#if 0 + while (*list_head) + list_head = &((*list_head)->next); + + nptr->next = NULL; +#else + nptr->next = *list_head; +#endif + + nptr->name = (char *)strdup(name); + if (type & LTYPE_HOST) + { + nptr->type = (type & ~LTYPE_HOST) | LTYPE_PROPERTY; + nptr->property = XA_WM_CLIENT_MACHINE; + } + else + { + nptr->type = type; + nptr->property = property; + } + nptr->ptr = (ptr == NULL) ? (char *)TRUE : ptr; + + *list_head = nptr; +} + + /********************************************************************\ + * * + * New LookInList code by RJC. * + * * + * Since we want to be able to look for multiple matches (eg, to * + * check which relevant icon regions are on the screen), the basic * + * procedure is now MultiLookInList and uses a (pseudo-)continuation * + * to keep track of where it is. * + * * + * LookInList is a trivial specialisation of that. * + * * + * Also, we now allow regular expressions in lists, so here we use * + * Henry Spencer's regular expression code. It is possible that we * + * should pre-compile all the regular expressions for maximum * + * speed. * + * * + \********************************************************************/ + +int +MatchName(name, pattern, compiled, type) +char *name; +char *pattern; +#ifndef NO_REGEX_SUPPORT +regex_t *compiled; +#else +char *compiled; +#endif +short type; +{ +#ifdef DEBUG + fprintf(stderr, "MatchName(): compare '%s' with '%s'\n", name, pattern); +#endif + + if (type & LTYPE_ANYTHING) + return (0); + + if (type & LTYPE_REGEXP) + { +#ifndef NO_REGEX_SUPPORT + regex_t re; + int result; + + if ((result = regcomp(&re, pattern, REGCOMP_FLAGS)) != 0) + { + regerror(result, &re, buffer, sizeof(buffer)); + regfree(&re); + + fprintf(stderr, "%s: (1) regcomp(\"%s\") error: %s\n", + ProgramName, pattern, buffer); + return (result); + } + + result = regexec(&re, name, 0, NULL, 0); + regfree(&re); + + return (result); +#else + fprintf(stderr, "%s: (1) no support for regcomp(\"%s\")\n", + ProgramName, pattern); + return (1); +#endif + } + + if (type & LTYPE_C_REGEXP) + { +#ifndef NO_REGEX_SUPPORT + return (regexec(compiled, name, 0, NULL, 0)); +#else + fprintf(stderr, "%s: no support for regexec(\"%s\")\n", + ProgramName, name); + return (1); +#endif + } + + if (type & LTYPE_STRING) + return (match(pattern, name)); + + fprintf(stderr, "%s: bad list type (%d) comparing \"%s\" with \"%s\"\n", + ProgramName, type, name, pattern); + return (1); +} + +static char * +MultiLookInList(list_head, name, class, /*win, */continuation) +name_list *list_head; +char *name; +XClassHint *class; +/* Window win; */ +name_list **continuation; +{ + name_list *nptr; +#if 0 + Window win = None; +#endif + +#ifdef DEBUG + fprintf(stderr, "MultiLookInList(): looking for '%s'\n", name); +#endif + + for (nptr = list_head ; nptr ; nptr = nptr->next) + { + /* pre-compile and cache the regex_t */ + if (nptr->type & LTYPE_REGEXP) + { +#ifndef NO_REGEX_SUPPORT + int result; + + if ((result = regcomp(&nptr->re, nptr->name, REGCOMP_FLAGS)) != 0) + { + regerror(result, &nptr->re, buffer, sizeof(buffer)); + regfree(&nptr->re); + + fprintf(stderr, "%s: (2) regcomp(\"%s\") error: %s\n", + ProgramName, nptr->name, buffer); + + nptr->type |= LTYPE_NOTHING; + } + else + nptr->type |= LTYPE_C_REGEXP; +#else + fprintf(stderr, "%s: (2) no support for regcomp(\"%s\")\n", + ProgramName, nptr->name); + + nptr->type |= LTYPE_NOTHING; +#endif + + nptr->type &= ~LTYPE_REGEXP; + } + + if (nptr->type & LTYPE_NOTHING) + continue; /* skip illegal entry */ + + if (nptr->type & LTYPE_ANYTHING) + { + *continuation = nptr->next; + return (nptr->ptr); + } + + if (nptr->type & LTYPE_NAME) + if (MatchName(name, nptr->name, &nptr->re, nptr->type) == 0) + { + *continuation = nptr->next; + return (nptr->ptr); + } + + if (class) + { + if (nptr->type & LTYPE_RES_NAME) + if (MatchName(class->res_name, nptr->name, &nptr->re, + nptr->type) == 0) + { + *continuation = nptr->next; + return (nptr->ptr); + } + + if (nptr->type & LTYPE_RES_CLASS) + if (MatchName(class->res_class, nptr->name, &nptr->re, + nptr->type) == 0) + { + *continuation = nptr->next; + return (nptr->ptr); + } + } + +#if 0 + if (win && (nptr->type & LTYPE_PROPERTY)) + { + char *s = GetPropertyString(win, nptr->property); + + if (s && MatchName(s, nptr->name, &nptr->re, nptr->type) == 0) + { + free(s); + + *continuation = nptr->next; + return (nptr->ptr); + } + + if (s) free(s); + } +#endif + } + + *continuation = NULL; + return (NULL); +} + +char * +LookInList(list_head, name, class/*, win*/) +name_list *list_head; +char *name; +XClassHint *class; +/* Window win; */ +{ +#if 0 + name_list *nptr; +#endif + name_list *rest; + char *return_name = MultiLookInList(list_head, name, class, /*win, */&rest); + +#if 0 + if ((Scr->ListRings == TRUE) && (return_name != NULL) + && (list_head->next != NULL)) + { + /* To implement a ring on the linked list where we cant change the */ + /* list_head, use a simple unlink/link-at-end alg. unless you need */ + /* to move the first link. In that case swap the contents of the */ + /* first link with the contents of the second then proceed as */ + /* normal. */ + name_list *tmp_namelist; + + if (list_head->ptr == return_name) + { + char *tmp_name; + short tmp_type; + char *tmp_ptr; + + tmp_name = list_head->name; + tmp_type = list_head->type; + tmp_ptr = list_head->ptr; + + list_head->name = list_head->next->name; + list_head->type = list_head->next->type; + list_head->ptr = list_head->next->ptr; + + list_head->next->name = tmp_name; + list_head->next->type = tmp_type; + list_head->next->ptr = tmp_ptr; + } + + for (nptr = list_head; nptr->next != NULL; nptr = nptr->next) + { + if (nptr->next->ptr == return_name) + break; + } + + if (nptr->next->next != NULL) + { + tmp_namelist = nptr->next; + nptr->next = nptr->next->next; + + for (nptr = nptr->next; nptr->next != NULL; nptr = nptr->next); + nptr->next = tmp_namelist; + nptr->next->next = NULL; + } + } +#endif + + return (return_name); +} + +#if 0 +static char * +MultiLookInNameList(list_head, name, continuation) +name_list *list_head; +char *name; +name_list **continuation; +{ + return (MultiLookInList(list_head, name, NULL, /*None, */continuation)); +} +#endif + +char * +LookInNameList(list_head, name) +name_list *list_head; +char *name; +{ + return (MultiLookInList(list_head, name, NULL, /*None, */&list_head)); +} + +/*********************************************************************** + * + * Procedure: + * GetColorFromList - look through a list for a window name, or class + * + * Returned Value: + * TRUE if the name was found + * FALSE if the name was not found + * + * Inputs: + * list - a pointer to the head of a list + * name - a pointer to the name to look for + * class - a pointer to the class to look for + * + * Outputs: + * ptr - fill in the list value if the name was found + * + *********************************************************************** + */ + +int GetColorFromList(list_head, name, class, /*win, */ptr) +name_list *list_head; +char *name; +XClassHint *class; +/* Window win; */ +Pixel *ptr; +{ + int save; + char *val = LookInList(list_head, name, class/*, win*/); + + if (val) + { + save = Scr->FirstTime; + Scr->FirstTime = TRUE; + GetColor(Scr->Monochrome, ptr, val); + Scr->FirstTime = save; + + return (TRUE); + } + + return (FALSE); +} + +/*********************************************************************** + * + * Procedure: + * FreeList - free up a list + * + *********************************************************************** + */ + +void FreeList(list) +name_list **list; +{ + name_list *nptr; + name_list *tmp; + + for (nptr = *list; nptr != NULL; ) + { + tmp = nptr->next; + +#ifndef NO_REGEX_SUPPORT + if (nptr->type & LTYPE_C_REGEXP) + regfree(&nptr->re); +#endif + free(nptr->name); + free((char *) nptr); + + nptr = tmp; + } + + *list = NULL; +} + +/*********************************************************************** + * + * MSDOS-ish, Unix-ish, VTWM 5.3 wildcard support + * + **********************************************************************/ + +#if 0 +static int is_pattern(p) +char *p; +{ + while (*p) + { + switch (*p++) + { + case '?': + case '*': + case '[': + return (TRUE); + case '\\': + if (!*p++) return (FALSE); + } + } + + return (FALSE); +} +#endif + +#define ABORT 2 + +static int regex_match(); + +static int regex_match_after_star(p, t) +char *p, *t; +{ + register int match; + register int nextp; + + while ((*p == '?') || (*p == '*')) + { + if (*p == '?') + if (!*t++) return (ABORT); + + p++; + } + if (!*p) return (TRUE); + + nextp = *p; + if (nextp == '\\') nextp = p[1]; + + match = FALSE; + while (match == FALSE) + { + if (nextp == *t || nextp == '[') + match = regex_match(p, t); + + if (!*t++) match = ABORT; + } + + return (match); +} + +static int regex_match(p, t) +char *p, *t; +{ + register char range_start, range_end; + int invert; + int member_match; + int loop; + + for (; *p; p++, t++) + { + if (!*t) return ((*p == '*' && *++p == '\0') ? TRUE : ABORT); + + switch (*p) + { + case '?': + break; + case '*': + return (regex_match_after_star(p, t)); + case '[': + { + p++; + invert = FALSE; + if (*p == '!' || *p == '^') + { + invert = TRUE; + p++; + } + + if (*p == ']') return (ABORT); + + member_match = FALSE; + loop = TRUE; + while (loop) + { + if (*p == ']') + { + loop = FALSE; + continue; + } + + if (*p == '\\') + range_start = range_end = *++p; + else + range_start = range_end = *p; + if (!range_start) return (ABORT); + + if (*++p == '-') + { + range_end = *++p; + if (range_end == '\0' || range_end == ']') + return (ABORT); + + if (range_end == '\\') + range_end = *++p; + p++; + } + + if (range_start < range_end) + { + if (*t >= range_start && *t <= range_end) + { + member_match = TRUE; + loop = FALSE; + } + } + else + { + if (*t >= range_end && *t <= range_start) + { + member_match = TRUE; + loop = FALSE; + } + } + } + + if ((invert && member_match) || !(invert || member_match)) + return (FALSE); + + if (member_match) + { + while (*p != ']') + { + if (!*p) return (ABORT); + + if (*p == '\\') p++; + p++; + } + } + break; + } + case '\\': + p++; + + default: + if (*p != *t) return (FALSE); + } + } + + return (!*t); +} + +int match(p, t) +char *p, *t; +{ + if ((p == NULL) || (t == NULL)) return (TRUE); + + return ((regex_match(p, t) == TRUE) ? FALSE : TRUE); +} diff --git a/list.h b/list.h new file mode 100644 index 0000000..0971d8c --- /dev/null +++ b/list.h @@ -0,0 +1,72 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/********************************************************************** + * + * $XConsortium: list.h,v 1.12 90/09/14 14:54:42 converse Exp $ + * + * TWM list handling external definitions + * + * 11-Apr-88 Tom LaStrange Initial Version. + * + **********************************************************************/ + +#ifndef _LIST_ +#define _LIST_ + +#define LTYPE_NAME (1<<0) /* match against window name */ +#define LTYPE_RES_NAME (1<<1) /* match against resource name */ +#define LTYPE_RES_CLASS (1<<2) /* match against resource class */ +#define LTYPE_PROPERTY (1<<3) /* match against a window property */ +#define LTYPE_HOST (1<<4) /* match against a host name */ + +#define LTYPE_REGEXP (1<<8) /* match as a regular expression */ +#define LTYPE_C_REGEXP (1<<9) /* match as a compiled regexp */ +#define LTYPE_STRING (1<<10) /* match as an exact string */ +#define LTYPE_ANYTHING (1<<11) /* match anything */ +#define LTYPE_NOTHING (1<<12) /* match nothing */ + +#define LTYPE_ANY_STRING (LTYPE_NAME | LTYPE_RES_NAME | \ + LTYPE_RES_CLASS | LTYPE_STRING) +#define LTYPE_ANY_REGEXP (LTYPE_NAME | LTYPE_RES_NAME | \ + LTYPE_RES_CLASS | LTYPE_REGEXP) +#define LTYPE_EXACT_NAME (LTYPE_NAME | LTYPE_STRING) + +typedef struct name_list_struct name_list; + +extern void AddToList(); +extern char *LookInList(); +extern char *LookInNameList(); +extern int GetColorFromList(); +extern void FreeList(); + +extern name_list *next_entry(); +extern char *contents_of_entry(); + +#endif /* _LIST_ */ + diff --git a/menus.c b/menus.c new file mode 100644 index 0000000..63072a8 --- /dev/null +++ b/menus.c @@ -0,0 +1,6773 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + +/*********************************************************************** + * + * $XConsortium: menus.c,v 1.186 91/07/17 13:58:00 dave Exp $ + * + * twm menu code + * + * 17-Nov-87 Thomas E. LaStrange File created + * + ***********************************************************************/ + +#include +#include +/* djhjr - 10/27/02 */ +#ifndef NO_REGEX_SUPPORT +#include +#include +#endif +#include +#include +#include +#include +#include +#ifdef NEED_PROCESS_H +#include +#endif +#include /* DSE */ +#include "twm.h" +#include "gc.h" +#include "menus.h" +#include "resize.h" +#include "events.h" +#include "util.h" +#include "parse.h" +#include "gram.h" +#include "screen.h" +#include "doors.h" +#include "desktop.h" +#include "add_window.h" +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT +#include "sound.h" +#endif +#include "version.h" + +#define strdup Strdup /* avoid conflict with system header files */ +extern char *strdup(char *); + +extern void IconUp(), IconDown(), CreateIconWindow(); + +/* djhjr - 4/26/99 */ +extern void AppletDown(); + +/* djhjr - 12/2/01 */ +extern void delete_pidfile(); + +/* djhjr - 10/27/02 */ +extern int MatchName(); + +extern void ResizeTwmWindowContents(); +extern void SetRaiseWindow(); + +extern char *Action; +extern int Context; +extern int ConstrainedMoveTime; +extern TwmWindow *ButtonWindow, *Tmp_win; +extern XEvent Event, ButtonEvent; +extern char *InitFile; + +int RootFunction = F_NOFUNCTION; +MenuRoot *ActiveMenu = NULL; /* the active menu */ +MenuItem *ActiveItem = NULL; /* the active menu item */ +int MoveFunction = F_NOFUNCTION; /* or F_MOVE or F_FORCEMOVE */ +int WindowMoved = FALSE; +int menuFromFrameOrWindowOrTitlebar = FALSE; +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT +int createSoundFromFunction = FALSE; +int destroySoundFromFunction = FALSE; +#endif + +void BumpWindowColormap(); +void DestroyMenu(); +void HideIconManager(); +void MakeMenu(); +void SendDeleteWindowMessage(); +void SendSaveYourselfMessage(); +void WarpClass(); +void WarpToScreen(); +void WarpScreenToWindow(); +Cursor NeedToDefer(); /* was an 'int' - Submitted by Michel Eyckmans */ + +int ConstMove = FALSE; /* constrained move variables */ + +/* for comparison against MoveDelta - djhjr - 9/5/98 */ +static int MenuOrigX, MenuOrigY; + +/* Globals used to keep track of whether the mouse has moved during + a resize function. */ +int ResizeOrigX; +int ResizeOrigY; + +extern int origx, origy, origWidth, origHeight; + +int MenuDepth = 0; /* number of menus up */ +static struct { + int x; + int y; +} MenuOrigins[MAXMENUDEPTH]; +static Cursor LastCursor; + +static char *actionHack = ""; /* Submitted by Michel Eyckmans */ + +/* + * context bitmaps for TwmWindows menu, f.showdesktop and f.showiconmgr + * djhjr - 9/10/99 + */ +static int have_twmwindows = -1; +static int have_showdesktop = -1; +static int have_showlist = -1; + +void WarpAlongRing(); + +/* djhjr - 4/18/96 */ +void Paint3DEntry(); + +static void Identify(); +void PaintNormalEntry(); + +/* djhjr - 5/13/98 */ +static TwmWindow *next_by_class(); +static int warp_if_warpunmapped(); + +/* djhjr - 7/31/98 */ +static void setup_restart(); +void RestartVtwm(); + +/* djhjr - 9/21/99 */ +int FindMenuOrFuncInBindings(); +int FindMenuOrFuncInWindows(); +int FindMenuInMenus(); +int FindFuncInMenus(); + +/* djhjr - 9/21/99 */ +void HideIconMgr(); +void ShowIconMgr(); + +/* djhjr - 9/17/02 */ +static int do_squeezetitle(); + +/* djhjr */ +#undef MAX +/* DSE */ +#define MAX(x,y) ((x)>(y)?(x):(y)) + +#define SHADOWWIDTH 5 /* in pixels */ + +#define EDGE_OFFSET 5 /* DSE */ + +/* djhjr - 5/5/98 +#define PULLDOWNMENU_OFFSET ((Scr->RightHandSidePulldownMenus)?\ + (ActiveMenu->width - EDGE_OFFSET * 2 - Scr->pullW):\ + (ActiveMenu->width >> 1)) * DSE * +*/ +#define PULLDOWNMENU_OFFSET ((Scr->RightHandSidePulldownMenus)?\ + (JunkWidth - EDGE_OFFSET * 2 - Scr->pullW):\ + (JunkWidth >> 1)) + + + +/*********************************************************************** + * + * Procedure: + * InitMenus - initialize menu roots + * + *********************************************************************** + */ + +void +InitMenus() +{ + int i, j, k; + FuncKey *key, *tmp; + + for (i = 0; i < MAX_BUTTONS+1; i++) + for (j = 0; j < NUM_CONTEXTS; j++) + for (k = 0; k < MOD_SIZE; k++) + { + Scr->Mouse[i][j][k].func = F_NOFUNCTION; + Scr->Mouse[i][j][k].item = NULL; + } + + Scr->DefaultFunction.func = F_NOFUNCTION; + Scr->WindowFunction.func = F_NOFUNCTION; + + if (FirstScreen) + { + for (key = Scr->FuncKeyRoot.next; key != NULL;) + { + free(key->name); + tmp = key; + key = key->next; + free((char *) tmp); + } + Scr->FuncKeyRoot.next = NULL; + } +} + + + +/*********************************************************************** + * + * Procedure: + * AddFuncKey - add a function key to the list + * + * Inputs: + * name - the name of the key + * cont - the context to look for the key press in + * mods - modifier keys that need to be pressed + * func - the function to perform + * win_name- the window name (if any) + * action - the action string associated with the function (if any) + * + *********************************************************************** + */ + +Bool AddFuncKey (name, cont, mods, func, win_name, action) + char *name; + int cont, mods, func; + char *win_name; + char *action; +{ + FuncKey *tmp; + KeySym keysym; + KeyCode keycode; + + /* + * Don't let a 0 keycode go through, since that means AnyKey to the + * XGrabKey call in GrabKeys(). + */ + if ((keysym = XStringToKeysym(name)) == NoSymbol || + (keycode = XKeysymToKeycode(dpy, keysym)) == 0) + { + return False; + } + + /* see if there already is a key defined for this context */ + for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next) + { + if (tmp->keysym == keysym && + tmp->cont == cont && + tmp->mods == mods) + break; + } + + if (tmp == NULL) + { + tmp = (FuncKey *) malloc(sizeof(FuncKey)); + tmp->next = Scr->FuncKeyRoot.next; + Scr->FuncKeyRoot.next = tmp; + } + + tmp->name = name; + tmp->keysym = keysym; + tmp->keycode = keycode; + tmp->cont = cont; + tmp->mods = mods; + tmp->func = func; + tmp->win_name = win_name; + tmp->action = action; + + return True; +} + + + +int CreateTitleButton (name, func, action, menuroot, rightside, append) + char *name; + int func; + char *action; + MenuRoot *menuroot; + Bool rightside; + Bool append; +{ + TitleButton *tb = (TitleButton *) malloc (sizeof(TitleButton)); + + if (!tb) { + fprintf (stderr, + "%s: unable to allocate %d bytes for title button\n", + ProgramName, sizeof(TitleButton)); + return 0; + } + + tb->next = NULL; + tb->name = name; /* note that we are not copying */ + +/* djhjr - 10/30/02 + * djhjr - 4/19/96 * + tb->image = NULL; +*/ + +/* tb->bitmap = None;*/ /* WARNING, values not set yet */ + tb->width = 0; /* see InitTitlebarButtons */ + tb->height = 0; /* ditto */ + tb->func = func; + tb->action = action; + tb->menuroot = menuroot; + tb->rightside = rightside; + if (rightside) { + Scr->TBInfo.nright++; + } else { + Scr->TBInfo.nleft++; + } + + /* + * Cases for list: + * + * 1. empty list, prepend left put at head of list + * 2. append left, prepend right put in between left and right + * 3. append right put at tail of list + * + * Do not refer to widths and heights yet since buttons not created + * (since fonts not loaded and heights not known). + */ + if ((!Scr->TBInfo.head) || ((!append) && (!rightside))) { /* 1 */ + tb->next = Scr->TBInfo.head; + Scr->TBInfo.head = tb; + } else if (append && rightside) { /* 3 */ + register TitleButton *t; + + for (t = Scr->TBInfo.head; t->next; t = t->next) + ; /* SUPPRESS 530 */ + t->next = tb; + tb->next = NULL; + } else { /* 2 */ + register TitleButton *t, *prev = NULL; + + for (t = Scr->TBInfo.head; t && !t->rightside; t = t->next) + prev = t; + if (prev) { + tb->next = prev->next; + prev->next = tb; + } else { + tb->next = Scr->TBInfo.head; + Scr->TBInfo.head = tb; + } + } + + return 1; +} + + + +/* + * InitTitlebarButtons - Do all the necessary stuff to load in a titlebar + * button. If we can't find the button, then put in a question; if we can't + * find the question mark, something is wrong and we are probably going to be + * in trouble later on. + */ +/* was of type 'void', now returns button height - djhjr - 12/10/98 */ +int InitTitlebarButtons () +{ + Image *image; + TitleButton *tb; + int h, height; + + /* + * initialize dimensions + */ + Scr->TBInfo.width = (Scr->TitleHeight - + 2 * (Scr->FramePadding + Scr->ButtonIndent)); + +/* djhjr - 10/18/02 + * djhjr - 4/19/96 * + * was 'Scr->use3Dtitles' - djhjr - 8/11/98 * + if (Scr->TitleBevelWidth > 0) + Scr->TBInfo.pad = ((Scr->TitlePadding > 1) + ? ((Scr->TitlePadding + 1) / 2) : 0); + else + + Scr->TBInfo.pad = ((Scr->TitlePadding > 1) + ? ((Scr->TitlePadding + 1) / 2) : 1); +*/ + Scr->TBInfo.pad = Scr->TitlePadding; + + h = Scr->TBInfo.width - 2 * Scr->TBInfo.border; + /* djhjr - 10/30/02 */ + if (!(h & 1)) h--; + height = h; + + /* + * add in some useful buttons and bindings so that novices can still + * use the system. -- modified by DSE + */ + + if (!Scr->NoDefaultTitleButtons) /* DSE */ + { + /* insert extra buttons */ + + /* djhjr - 4/19/96 */ + /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */ + if (Scr->TitleBevelWidth > 0) { + if (!CreateTitleButton (TBPM_3DDOT, F_ICONIFY, "", (MenuRoot *) NULL, + False, False)) + fprintf (stderr, "%s: unable to add iconify button\n", ProgramName); + if (!CreateTitleButton (TBPM_3DRESIZE, F_RESIZE, "", (MenuRoot *) NULL, + True, True)) + fprintf (stderr, "%s: unable to add resize button\n", ProgramName); + } + else { + + if (!CreateTitleButton (TBPM_ICONIFY, F_ICONIFY, "", (MenuRoot *) NULL, + False, False)) + fprintf(stderr,"%s: unable to add iconify button\n",ProgramName); + if (!CreateTitleButton (TBPM_RESIZE, F_RESIZE, "", (MenuRoot *) NULL, + True, True)) + fprintf(stderr,"%s: unable to add resize button\n",ProgramName); + } + } + if (!Scr->NoDefaultMouseOrKeyboardBindings) /* DSE */ + { + AddDefaultBindings (); + } + + ComputeCommonTitleOffsets (); + +/* djhjr - 6/15/98 - moved it back to here... */ +/* djhjr - 9/14/96 - moved to CreateWindowTitlebarButtons()... */ + /* + * load in images and do appropriate centering + */ + for (tb = Scr->TBInfo.head; tb; tb = tb->next) { + +/* djhjr - 4/19/96 + tb->bitmap = FindBitmap (tb->name, &tb->width, &tb->height); + if (!tb->bitmap) { + tb->bitmap = FindBitmap (TBPM_QUESTION, &tb->width, &tb->height); + if (!tb->bitmap) { * cannot happen (see util.c) * + fprintf (stderr, + "%s: unable to add titlebar button \"%s\"\n", + ProgramName, tb->name); + } + } +*/ +/* djhjr - 9/21/96 + tb->image = GetImage (tb->name, Scr->TitleC); + if (!tb->image) { + tb->image = GetImage (TBPM_QUESTION, Scr->TitleC); + if (!tb->image) { * cannot happen (see util.c) * + fprintf (stderr, "%s: unable to add titlebar button \"%s\"\n", + ProgramName, tb->name); + } + } +*/ + /* added width and height - 10/30/02 */ + image = GetImage (tb->name, h, h, Scr->ButtonBevelWidth * 2, + (Scr->ButtonColorIsFrame) ? Scr->BorderColorC : Scr->TitleC); + + tb->width = image->width; + + /* added 'height = ' - djhjr - 12/10/98 */ + height = tb->height = image->height; + + tb->dstx = (h - tb->width + 1) / 2; + if (tb->dstx < 0) { /* clip to minimize copying */ + tb->srcx = -(tb->dstx); + tb->width = h; + tb->dstx = 0; + } else { + tb->srcx = 0; + } + tb->dsty = (h - tb->height + 1) / 2; + if (tb->dsty < 0) { + tb->srcy = -(tb->dsty); + tb->height = h; + tb->dsty = 0; + } else { + tb->srcy = 0; + } + + } /* for(...) */ + + /* djhjr - 12/10/98 */ + return (height > h) ? height : h; +/* ...end of moved */ +} + + + +/* djhjr - 10/30/02 */ +void SetMenuIconPixmap(filename) + char *filename; +{ + Scr->menuIconName = filename; +} + +void PaintEntry(mr, mi, exposure) +MenuRoot *mr; +MenuItem *mi; +int exposure; +{ + /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */ + if (Scr->MenuBevelWidth > 0) + Paint3DEntry (mr, mi, exposure); + + /* djhjr - 4/22/96 */ + else + + PaintNormalEntry (mr, mi, exposure); +} + +void Paint3DEntry(mr, mi, exposure) +MenuRoot *mr; +MenuItem *mi; +int exposure; +{ + int y_offset; + int text_y; + GC gc; + +/* djhjr - 4/29/98 + y_offset = mi->item_num * Scr->EntryHeight + 2; +*/ +/* djhjr - 5/22/00 + y_offset = mi->item_num * Scr->EntryHeight + Scr->MenuBevelWidth; +*/ + y_offset = (mi->item_num - mr->top) * Scr->EntryHeight + Scr->MenuBevelWidth; + +/* djhjr - 9/25/96 + text_y = y_offset + Scr->MenuFont.y + 2; +*/ + text_y = y_offset + (((Scr->EntryHeight - Scr->MenuFont.height) / 2) + Scr->MenuFont.y); + + if (mi->func != F_TITLE) + { + int x, y; + + if (mi->state) + { + +/* djhjr - 9/25/96 + Draw3DBorder (mr->w, 2, y_offset, mr->width - 4, Scr->EntryHeight, 1, + mi->highlight, off, True, False); +*/ +/* djhjr - 4/29/98 + Draw3DBorder (mr->w, 2, y_offset + 1, mr->width - 4, Scr->EntryHeight - 1, 1, + mi->highlight, off, True, False); +*/ + Draw3DBorder (mr->w, Scr->MenuBevelWidth, y_offset + 1, mr->width - 2 * Scr->MenuBevelWidth, Scr->EntryHeight - 1, 1, + mi->highlight, off, True, False); + + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF(mi->highlight.fore, mi->highlight.back, Scr->MenuFont); + +/* djhjr - 4/29/98 + XDrawImageString(dpy, mr->w, Scr->NormalGC, mi->x + 2, text_y, mi->item, mi->strlen); +*/ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawImageString(dpy, mr->w, &Scr->MenuFont, +#else + XDrawImageString(dpy, mr->w, +#endif + Scr->NormalGC, mi->x + Scr->MenuBevelWidth, text_y, mi->item, mi->strlen); + + gc = Scr->NormalGC; + } + else + { + if (mi->user_colors || !exposure) + { + XSetForeground (dpy, Scr->NormalGC, mi->normal.back); + +/* djhjr - 9/25/96 + XFillRectangle (dpy, mr->w, Scr->NormalGC, 2, y_offset, + mr->width - 4, Scr->EntryHeight); +*/ +/* djhjr - 4/29/98 + XFillRectangle (dpy, mr->w, Scr->NormalGC, 2, y_offset + 1, + mr->width - 4, Scr->EntryHeight - 1); +*/ + XFillRectangle (dpy, mr->w, Scr->NormalGC, Scr->MenuBevelWidth, y_offset + 1, + mr->width - 2 * Scr->MenuBevelWidth, Scr->EntryHeight - 1); + + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF (mi->normal.fore, mi->normal.back, Scr->MenuFont); + + gc = Scr->NormalGC; + } + else + { + gc = Scr->MenuGC; + } + +/* djhjr - 4/29/98 + XDrawImageString (dpy, mr->w, gc, mi->x + 2, text_y, mi->item, mi->strlen); +*/ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawImageString (dpy, mr->w, &Scr->MenuFont, +#else + XDrawImageString (dpy, mr->w, +#endif + gc, mi->x + Scr->MenuBevelWidth, text_y, mi->item, mi->strlen); + + if (mi->separated) + { + /* this 'if (...)' - djhjr - 1/19/98 */ + if (!Scr->BeNiceToColormap) + { + FB (Scr->MenuC.shadd, Scr->MenuC.shadc); + +/* djhjr - 9/25/96 + XDrawLine (dpy, mr->w, Scr->NormalGC, 1, y_offset + Scr->MenuFont.y + 5, + mr->width - 2, y_offset + Scr->MenuFont.y + 5); +*/ +/* djhjr - 4/29/98 + XDrawLine (dpy, mr->w, Scr->NormalGC, 1, y_offset + Scr->EntryHeight - 1, + mr->width - 2, y_offset + Scr->EntryHeight - 1); +*/ + XDrawLine (dpy, mr->w, Scr->NormalGC, Scr->MenuBevelWidth + 1, y_offset + Scr->EntryHeight - 1, + mr->width - Scr->MenuBevelWidth - 3, y_offset + Scr->EntryHeight - 1); + } + + FB (Scr->MenuC.shadc, Scr->MenuC.shadd); + +/* djhjr - 9/25/96 + XDrawLine (dpy, mr->w, Scr->NormalGC, 2, y_offset + Scr->MenuFont.y + 6, + mr->width - 3, y_offset + Scr->MenuFont.y + 6); +*/ +/* djhjr - 4/29/98 + XDrawLine (dpy, mr->w, Scr->NormalGC, 2, y_offset + Scr->EntryHeight, + mr->width - 3, y_offset + Scr->EntryHeight); +*/ + XDrawLine (dpy, mr->w, Scr->NormalGC, Scr->MenuBevelWidth + 2, y_offset + Scr->EntryHeight, + mr->width - Scr->MenuBevelWidth - 2, y_offset + Scr->EntryHeight); + } + } + + if (mi->func == F_MENU) + { +/* djhjr - 10/30/02 + * create the pull right pixmap if needed * + if (Scr->pullPm == None) + { + Scr->pullPm = Create3DMenuIcon (Scr->MenuFont.height, &Scr->pullW, + &Scr->pullH, Scr->MenuC); +*/ + Image *image; + Pixel back; + + back = Scr->MenuC.back; + if (mi->state) + Scr->MenuC.back = mi->highlight.back; + else + Scr->MenuC.back = mi->normal.back; + + Scr->pullW = Scr->pullH = Scr->MenuFont.height; + image = GetImage(Scr->menuIconName, + Scr->pullW, Scr->pullH, + 0, Scr->MenuC); + + Scr->MenuC.back = back; +/* djhjr - 10/30/02 + } +*/ + +/* djhjr - 4/29/98 + x = mr->width - Scr->pullW - 5; +*/ + x = mr->width - Scr->pullW - Scr->MenuBevelWidth - EDGE_OFFSET; + +/* djhjr - 9/25/96 + y = y_offset + ((Scr->MenuFont.height - Scr->pullH) / 2) + 2; +*/ + y = y_offset + ((Scr->EntryHeight - Scr->pullH) / 2) + 1; + + XCopyArea (dpy, image->pixmap, mr->w, gc, 0, 0, Scr->pullW, Scr->pullH, x, y); + } + } + else + { + +/* djhjr - 4/29/96 + Draw3DBorder (mr->w, 2, y_offset, mr->width - 4, Scr->EntryHeight, 1, + mi->normal, off, True, False); +*/ +/* djhjr - 4/29/98 + Draw3DBorder (mr->w, 2, y_offset, mr->width - 4, Scr->EntryHeight + 1, 1, + mi->normal, off, True, False); +*/ + Draw3DBorder (mr->w, Scr->MenuBevelWidth, y_offset, mr->width - 2 * Scr->MenuBevelWidth, Scr->EntryHeight + 1, 1, + mi->normal, off, True, False); + +/* djhjr - 4/29/96 + FBF (mi->normal.fore, mi->normal.back, Scr->MenuFont.font->fid); +*/ + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF (mi->normal.fore, mi->normal.back, Scr->MenuTitleFont); + +/* djhjr - 9/25/96 + XDrawImageString (dpy, mr->w, Scr->NormalGC, mi->x + 2, text_y, mi->item, mi->strlen); +*/ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawImageString (dpy, mr->w, &Scr->MenuTitleFont, +#else + XDrawImageString (dpy, mr->w, +#endif + Scr->NormalGC, mi->x, text_y, mi->item, mi->strlen); + } +} + + + +void PaintNormalEntry(mr, mi, exposure) +MenuRoot *mr; +MenuItem *mi; +int exposure; +{ + int y_offset; + int text_y; + GC gc; + +/* djhjr - 5/22/00 + y_offset = mi->item_num * Scr->EntryHeight; +*/ + y_offset = (mi->item_num - mr->top) * Scr->EntryHeight; + +/* djhjr - 9/26/96 + text_y = y_offset + Scr->MenuFont.y; +*/ + text_y = y_offset + (((Scr->EntryHeight - Scr->MenuFont.height) / 2) + Scr->MenuFont.y); + + if (mi->func != F_TITLE) + { + int x, y; + + if (mi->state) + { + XSetForeground(dpy, Scr->NormalGC, mi->highlight.back); + + XFillRectangle(dpy, mr->w, Scr->NormalGC, 0, y_offset, + mr->width, Scr->EntryHeight); + + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF(mi->highlight.fore, mi->highlight.back, Scr->MenuFont); + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawString(dpy, mr->w, &Scr->MenuFont, +#else + XDrawString(dpy, mr->w, +#endif + Scr->NormalGC, mi->x, + text_y, mi->item, mi->strlen); + + gc = Scr->NormalGC; + } + else + { + if (mi->user_colors || !exposure) + { + XSetForeground(dpy, Scr->NormalGC, mi->normal.back); + + XFillRectangle(dpy, mr->w, Scr->NormalGC, 0, y_offset, + mr->width, Scr->EntryHeight); + + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF(mi->normal.fore, mi->normal.back, Scr->MenuFont); + + gc = Scr->NormalGC; + } + else + { + gc = Scr->MenuGC; + } + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawString(dpy, mr->w, &Scr->MenuFont, +#else + XDrawString(dpy, mr->w, +#endif + gc, mi->x, text_y, mi->item, mi->strlen); + + if (mi->separated) + +/* djhjr - 9/26/96 + XDrawLine (dpy, mr->w, gc, 0, y_offset + Scr->MenuFont.y + 5, + mr->width, y_offset + Scr->MenuFont.y + 5); +*/ + XDrawLine (dpy, mr->w, gc, 0, y_offset + Scr->EntryHeight - 1, + mr->width, y_offset + Scr->EntryHeight - 1); + } + + if (mi->func == F_MENU) + { +/* djhjr - 10/30/02 + * create the pull right pixmap if needed * + if (Scr->pullPm == None) + { + Scr->pullPm = CreateMenuIcon (Scr->MenuFont.height, + &Scr->pullW, &Scr->pullH); +*/ + Image *image; + ColorPair cp; + + cp.back = Scr->MenuC.back; + if (strncmp(Scr->menuIconName, ":xpm:", 5) != 0) + { + cp.fore = Scr->MenuC.fore; + Scr->MenuC.fore = (mi->state) ? mi->highlight.fore : mi->normal.fore; + Scr->MenuC.back = (mi->state) ? mi->highlight.back : mi->normal.back; + } + else + Scr->MenuC.back = (mi->state) ? mi->highlight.back : mi->normal.back; + + Scr->pullW = Scr->pullH = Scr->MenuFont.height; + image = GetImage(Scr->menuIconName, + Scr->pullW, Scr->pullH, + 0, Scr->MenuC); + + Scr->MenuC.back = cp.back; + if (strncmp(Scr->menuIconName, ":xpm:", 5) != 0) + Scr->MenuC.fore = cp.fore; +/* djhjr - 10/30/02 + } +*/ + + x = mr->width - Scr->pullW - EDGE_OFFSET; + +/* djhjr - 9/26/96 + y = y_offset + ((Scr->MenuFont.height - Scr->pullH) / 2); +*/ + y = y_offset + ((Scr->EntryHeight - Scr->pullH) / 2); + +/* djhjr - 10/30/02 + XCopyPlane(dpy, Scr->pullPm->pixmap, mr->w, gc, 0, 0, + Scr->pullW, Scr->pullH, x, y, 1); +*/ + XCopyArea (dpy, image->pixmap, mr->w, gc, 0, 0, + Scr->pullW, Scr->pullH, x, y); + } + } + else + { + int y; + + XSetForeground(dpy, Scr->NormalGC, mi->normal.back); + + /* fill the rectangle with the title background color */ + XFillRectangle(dpy, mr->w, Scr->NormalGC, 0, y_offset, + mr->width, Scr->EntryHeight); + + XSetForeground(dpy, Scr->NormalGC, mi->normal.fore); + + /* now draw the dividing lines */ + if (y_offset) + XDrawLine (dpy, mr->w, Scr->NormalGC, 0, y_offset, + mr->width, y_offset); + + y = ((mi->item_num+1) * Scr->EntryHeight)-1; + XDrawLine(dpy, mr->w, Scr->NormalGC, 0, y, mr->width, y); + +/* djhjr - 4/29/96 + FBF(mi->normal.fore, mi->normal.back, Scr->MenuFont.font->fid); +*/ + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF (mi->normal.fore, mi->normal.back, Scr->MenuTitleFont); + + /* finally render the title */ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawString(dpy, mr->w, &Scr->MenuTitleFont, +#else + XDrawString(dpy, mr->w, +#endif + Scr->NormalGC, mi->x, text_y, mi->item, mi->strlen); + } +} + +void PaintMenu(mr, e) +MenuRoot *mr; +XEvent *e; +{ + MenuItem *mi; + /* djhjr - 5/22/00 */ + int y_offset; + + /* djhjr - 4/22/96 */ + /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */ + if (Scr->MenuBevelWidth > 0) { +/* djhjr - 4/29/98 + Draw3DBorder (mr->w, 0, 0, mr->width, mr->height, 2, Scr->MenuC, off, False, False); +*/ + Draw3DBorder (mr->w, 0, 0, mr->width, mr->height, Scr->MenuBevelWidth, Scr->MenuC, off, False, False); + } + + for (mi = mr->first; mi != NULL; mi = mi->next) + { + /* djhjr - 5/22/00 */ + if (mi->item_num < mr->top) continue; + +/* djhjr - 5/22/00 + int y_offset = mi->item_num * Scr->EntryHeight; +*/ + y_offset = (mi->item_num - mr->top) * Scr->EntryHeight; + + /* djhjr - 5/22/00 */ + if (y_offset + Scr->EntryHeight > mr->height) break; + + /* some servers want the previous entry redrawn - djhjr - 10/24/00 */ + if (Scr->MenuBevelWidth > 0) y_offset += Scr->EntryHeight; + + /* + * Be smart about handling the expose, redraw only the entries + * that we need to. + */ + /* those servers want the next entry redrawn, too - djhjr - 10/24/00 */ + if (e->xexpose.y < (y_offset + Scr->EntryHeight) && + (e->xexpose.y + e->xexpose.height) > y_offset - ((mr->shadow) ? Scr->EntryHeight : 0)) + { + PaintEntry(mr, mi, True); + } + } + XSync(dpy, 0); +} + + + +static Bool fromMenu; + +extern int GlobalFirstTime; /* for StayUpMenus -- PF */ + +void UpdateMenu() +{ + MenuItem *mi; + int i, x, y, x_root, y_root, entry; + int done; + MenuItem *badItem = NULL; + static int firstTime = True; + + fromMenu = TRUE; + + while (TRUE) + { /* block until there is an event */ +#ifdef NEVER /* see the '#else' - Steve Ratcliffe */ +#if 0 + if (!menuFromFrameOrWindowOrTitlebar && ! Scr->StayUpMenus) { + XMaskEvent(dpy, + ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | ExposureMask | + VisibilityChangeMask | LeaveWindowMask | + ButtonMotionMask, &Event); + } + if (Event.type == MotionNotify) { + /* discard any extra motion events before a release */ + while(XCheckMaskEvent(dpy, + ButtonMotionMask | ButtonReleaseMask, &Event)) + if (Event.type == ButtonRelease) + break; + } +#else + while (XCheckMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | ExposureMask, &Event)) + { /* taken from tvtwm */ +#endif /* 0 */ +#else + /* Submitted by Steve Ratcliffe */ + XNextEvent(dpy, &Event); +#endif /* NEVER */ + + if (!DispatchEvent ()) continue; + + if (Event.type == ButtonRelease ) + { if (Scr->StayUpMenus) + { + if (firstTime == True) + { /* it was the first release of the button */ + firstTime = False; + } + else + { /* thats the second we need to return now */ + firstTime = True; + menuFromFrameOrWindowOrTitlebar = FALSE; + fromMenu = FALSE; + return; + } + } + else + { /* not stay-up */ + menuFromFrameOrWindowOrTitlebar = FALSE; + fromMenu = FALSE; + return; + } + } + + if (Cancel) return; + +#ifdef NEVER /* see the above - Steve Ratcliffe */ + } +#endif + + /* re-instated - Steve Ratcliffe */ + if (Event.type != MotionNotify) + continue; + + /* if we haven't received the enter notify yet, wait */ + if (!ActiveMenu || !ActiveMenu->entered) + continue; + + done = FALSE; + XQueryPointer( dpy, ActiveMenu->w, &JunkRoot, &JunkChild, + &x_root, &y_root, &x, &y, &JunkMask); + + /* djhjr - 9/5/98 */ + if (!ActiveItem) + if (abs(x_root - MenuOrigX) < Scr->MoveDelta && + abs(y_root - MenuOrigY) < Scr->MoveDelta) + continue; + +#if 0 + /* if we haven't recieved the enter notify yet, wait */ + if (ActiveMenu && !ActiveMenu->entered) + continue; +#endif + + XFindContext(dpy, ActiveMenu->w, ScreenContext, (caddr_t *)&Scr); + + JunkWidth = ActiveMenu->width; + JunkHeight = ActiveMenu->height; + /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */ + if (Scr->MenuBevelWidth > 0) + { + x -= Scr->MenuBevelWidth; + y -= Scr->MenuBevelWidth; + + JunkWidth -= 2 * Scr->MenuBevelWidth; + JunkHeight -= Scr->MenuBevelWidth; + } + +/* djhjr - 5/22/00 + if (x < 0 || y < 0 || x >= JunkWidth || y >= JunkHeight) +*/ + if ((x < 0 || y < 0 || x >= JunkWidth || y >= JunkHeight) || + (ActiveMenu->too_tall && (y < Scr->MenuScrollBorderWidth || + y > JunkHeight - Scr->MenuScrollBorderWidth))) + { + if (ActiveItem && ActiveItem->func != F_TITLE) + { + ActiveItem->state = 0; + PaintEntry(ActiveMenu, ActiveItem, False); + } + ActiveItem = NULL; + + /* menu scrolling - djhjr - 5/22/00 */ + if (ActiveMenu->too_tall && x >= 0 && x < JunkWidth) + { + short j = ActiveMenu->top; + + if (y < Scr->MenuScrollBorderWidth) + { + if (ActiveMenu->top - Scr->MenuScrollJump < 0) + continue; + else + j -= Scr->MenuScrollJump; + } + else if (y > JunkHeight - Scr->MenuScrollBorderWidth) + { + int k = JunkHeight / Scr->EntryHeight; + + if (ActiveMenu->top + k >= ActiveMenu->items) + continue; + else + j += Scr->MenuScrollJump; + } + + if (ActiveMenu->top != j) + { + ActiveMenu->top = j; + XClearArea(dpy, ActiveMenu->w, 0, 0, 0, 0, True); + } + } + + continue; + } + + /* look for the entry that the mouse is in */ +/* djhjr - 5/22/00 + entry = y / Scr->EntryHeight; +*/ + entry = (y / Scr->EntryHeight) + ActiveMenu->top; + for (i = 0, mi = ActiveMenu->first; mi != NULL; i++, mi=mi->next) + { + if (i == entry) + break; + } + + /* if there is an active item, we might have to turn it off */ + if (ActiveItem) + { + /* is the active item the one we are on ? */ + if (ActiveItem->item_num == entry && ActiveItem->state) + done = TRUE; + + /* if we weren't on the active entry, let's turn the old + * active one off + */ + if (!done && ActiveItem->func != F_TITLE) + { + ActiveItem->state = 0; + PaintEntry(ActiveMenu, ActiveItem, False); + } + } + + /* djhjr - 5/22/00 */ + if (ActiveMenu->too_tall && y + Scr->EntryHeight > JunkHeight) + continue; + + /* if we weren't on the active item, change the active item and turn + * it on + */ + if (!done) + { + ActiveItem = mi; + +/* djhjr - 5/20/98 + if (ActiveItem->func != F_TITLE && !ActiveItem->state) +*/ + if (ActiveItem && ActiveItem->func != F_TITLE && !ActiveItem->state) + { + ActiveItem->state = 1; + PaintEntry(ActiveMenu, ActiveItem, False); + + if (Scr->StayUpOptionalMenus) /* PF */ + GlobalFirstTime = firstTime = False; /* PF */ + + } + } + + /* now check to see if we were over the arrow of a pull right entry */ + +/* djhjr - 5/20/98 + if (ActiveItem->func == F_MENU && +*/ + if (ActiveItem && ActiveItem->func == F_MENU && + +/* ((ActiveMenu->width - x) < (ActiveMenu->width >> 1))) */ + ( x > PULLDOWNMENU_OFFSET )) /* DSE */ + { + MenuRoot *save = ActiveMenu; + int savex = MenuOrigins[MenuDepth - 1].x; + int savey = MenuOrigins[MenuDepth - 1].y; + + if (MenuDepth < MAXMENUDEPTH) { + PopUpMenu (ActiveItem->sub, + (savex + PULLDOWNMENU_OFFSET), /* DSE */ + (savey + ActiveItem->item_num * Scr->EntryHeight) + /*(savey + ActiveItem->item_num * Scr->EntryHeight + + (Scr->EntryHeight >> 1))*/, False); + } else if (!badItem) { + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + badItem = ActiveItem; + } + + /* if the menu did get popped up, unhighlight the active item */ + if (save != ActiveMenu && ActiveItem->state) + { + ActiveItem->state = 0; + PaintEntry(save, ActiveItem, False); + ActiveItem = NULL; + } + } + + if (badItem != ActiveItem) badItem = NULL; + XFlush(dpy); + } +} + + + +/*********************************************************************** + * + * Procedure: + * NewMenuRoot - create a new menu root + * + * Returned Value: + * (MenuRoot *) + * + * Inputs: + * name - the name of the menu root + * + *********************************************************************** + */ + +MenuRoot * +NewMenuRoot(name) + char *name; +{ + MenuRoot *tmp; + +#define UNUSED_PIXEL ((unsigned long) (~0)) /* more than 24 bits */ + + tmp = (MenuRoot *) malloc(sizeof(MenuRoot)); + +/* djhjr - 5/22/96 + tmp->hi_fore = UNUSED_PIXEL; + tmp->hi_back = UNUSED_PIXEL; +*/ + tmp->highlight.fore = UNUSED_PIXEL; + tmp->highlight.back = UNUSED_PIXEL; + + tmp->name = name; + tmp->prev = NULL; + tmp->first = NULL; + tmp->last = NULL; + tmp->items = 0; + tmp->width = 0; + tmp->mapped = NEVER_MAPPED; + tmp->pull = FALSE; + tmp->w = None; + tmp->shadow = None; + tmp->real_menu = FALSE; + + /* djhjr - 5/22/00 */ + tmp->too_tall = 0; + tmp->top = 0; + + if (Scr->MenuList == NULL) + { + Scr->MenuList = tmp; + Scr->MenuList->next = NULL; + } + + if (Scr->LastMenu == NULL) + { + Scr->LastMenu = tmp; + Scr->LastMenu->next = NULL; + } + else + { + Scr->LastMenu->next = tmp; + Scr->LastMenu = tmp; + Scr->LastMenu->next = NULL; + } + +/* djhjr - 5/4/98 + if (strcmp(name, TWM_WINDOWS) == 0) +*/ + if (strcmp(name, TWM_WINDOWS) == 0 || strcmp(name, VTWM_WINDOWS) == 0) + Scr->Windows = tmp; + + return (tmp); +} + + + +/*********************************************************************** + * + * Procedure: + * AddToMenu - add an item to a root menu + * + * Returned Value: + * (MenuItem *) + * + * Inputs: + * menu - pointer to the root menu to add the item + * item - the text to appear in the menu + * action - the string to possibly execute + * sub - the menu root if it is a pull-right entry + * func - the numeric function + * fore - foreground color string + * back - background color string + * + *********************************************************************** + */ + +MenuItem * +AddToMenu(menu, item, action, sub, func, fore, back) + MenuRoot *menu; + char *item, *action; + MenuRoot *sub; + int func; + char *fore, *back; +{ + MenuItem *tmp; + int width; + MyFont *font; /* DSE */ + +#ifdef DEBUG_MENUS + fprintf(stderr, "adding menu item=\"%s\", action=%s, sub=%d, f=%d\n", + item, action, sub, func); +#endif + + tmp = (MenuItem *) malloc(sizeof(MenuItem)); + tmp->root = menu; + + if (menu->first == NULL) + { + menu->first = tmp; + tmp->prev = NULL; + } + else + { + menu->last->next = tmp; + tmp->prev = menu->last; + } + menu->last = tmp; + + tmp->item = item; + tmp->strlen = strlen(item); + tmp->action = action; + tmp->next = NULL; + tmp->sub = NULL; + tmp->state = 0; + tmp->func = func; + + /* djhjr - 4/22/96 */ + tmp->separated = 0; + + if ( func == F_TITLE && (Scr->MenuTitleFont.name != NULL) ) /* DSE */ + font= &(Scr->MenuTitleFont); + else + font= &(Scr->MenuFont); + + if (!Scr->HaveFonts) CreateFonts(); +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + width = MyFont_TextWidth(font, +#else + width = XTextWidth(font->font, +#endif + item, tmp->strlen); + if (width <= 0) + width = 1; + if (width > menu->width) + menu->width = width; + + tmp->user_colors = FALSE; + if (Scr->Monochrome == COLOR && fore != NULL) + { + int save; + + save = Scr->FirstTime; + Scr->FirstTime = TRUE; + +/* djhjr - 4/22/96 + GetColor(COLOR, &tmp->fore, fore); + GetColor(COLOR, &tmp->back, back); +*/ + GetColor(COLOR, &tmp->normal.fore, fore); + GetColor(COLOR, &tmp->normal.back, back); + + /* djhjr - 4/22/96 */ + /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */ + /* rem'd 'Scr->MenuBevelWidth' djhjr - 10/30/02 */ + if (/*Scr->MenuBevelWidth > 0 && */!Scr->BeNiceToColormap) GetShadeColors (&tmp->normal); + + Scr->FirstTime = save; + tmp->user_colors = TRUE; + } + if (sub != NULL) + { + tmp->sub = sub; + menu->pull = TRUE; + } + tmp->item_num = menu->items++; + + return (tmp); +} + + + +void MakeMenus() +{ + MenuRoot *mr; + + for (mr = Scr->MenuList; mr != NULL; mr = mr->next) + { + if (mr->real_menu == FALSE) + continue; + + MakeMenu(mr); + } +} + + + +void MakeMenu(mr) +MenuRoot *mr; +{ + MenuItem *start, *end, *cur, *tmp; + XColor f1, f2, f3; + XColor b1, b2, b3; + XColor save_fore, save_back; + int num, i; + int fred, fgreen, fblue; + int bred, bgreen, bblue; + int width; + + /* djhjr - 4/22/96 */ + int borderwidth; + + unsigned long valuemask; + XSetWindowAttributes attributes; + Colormap cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c; + MyFont *titleFont; + + if ( Scr->MenuTitleFont.name != NULL ) /* DSE */ + { + Scr->EntryHeight = MAX(Scr->MenuFont.height, + Scr->MenuTitleFont.height) + 4; + titleFont = &(Scr->MenuTitleFont); + } + else + { + Scr->EntryHeight = Scr->MenuFont.height + 4; + titleFont= &(Scr->MenuFont); + } + + + /* lets first size the window accordingly */ + if (mr->mapped == NEVER_MAPPED) + { + if (mr->pull == TRUE) + { + mr->width += 16 + 2 * EDGE_OFFSET; /* DSE */ + } + +/* djhjr - 4/29/98 + * djhjr - 9/18/96 * + if (Scr->use3Dmenus) mr->width += 4; +*/ + /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */ + if (Scr->MenuBevelWidth > 0) mr->width += 2 * Scr->MenuBevelWidth; + + width = mr->width + 2 * EDGE_OFFSET; /* DSE */ + + for (cur = mr->first; cur != NULL; cur = cur->next) + { + if (cur->func != F_TITLE) + cur->x = EDGE_OFFSET; /* DSE */ + else + { + cur->x = width - +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_TextWidth(titleFont, +#else + XTextWidth(titleFont->font, +#endif + cur->item, cur->strlen); + cur->x /= 2; + } + } + mr->height = mr->items * Scr->EntryHeight; + +/* djhjr - 4/29/98 + * djhjr - 4/22/96 * + if (Scr->use3Dmenus) mr->height += 4; +*/ + /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */ + if (Scr->MenuBevelWidth > 0) mr->height += 2 * Scr->MenuBevelWidth; + + /* djhjr - 4/22/96 */ + /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */ + borderwidth = (Scr->MenuBevelWidth > 0) ? 0 : 1; + + /* djhjr - 5/22/00 */ + if (mr->height > Scr->MyDisplayHeight) + { + mr->too_tall = 1; + mr->height = Scr->MyDisplayHeight - borderwidth * 2; + } + + /* added this 'if () ... else' - djhjr - 4/29/98 */ + /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */ + if (Scr->MenuBevelWidth > 0) + mr->width += 2 * Scr->MenuBevelWidth + 6; + else + mr->width += 10; + + if (Scr->Shadow) + { + /* + * Make sure that you don't draw into the shadow window or else + * the background bits there will get saved + */ + valuemask = (CWBackPixel | CWBorderPixel); + attributes.background_pixel = Scr->MenuShadowColor; + attributes.border_pixel = Scr->MenuShadowColor; + if (Scr->SaveUnder) { + valuemask |= CWSaveUnder; + attributes.save_under = True; + } + mr->shadow = XCreateWindow (dpy, Scr->Root, 0, 0, + (unsigned int) mr->width, + (unsigned int) mr->height, + (unsigned int)0, + CopyFromParent, + (unsigned int) CopyFromParent, + (Visual *) CopyFromParent, + valuemask, &attributes); + } + + valuemask = (CWBackPixel | CWBorderPixel | CWEventMask); + attributes.background_pixel = Scr->MenuC.back; + attributes.border_pixel = Scr->MenuC.fore; + attributes.event_mask = (ExposureMask | EnterWindowMask); + if (Scr->SaveUnder) { + valuemask |= CWSaveUnder; + attributes.save_under = True; + } + if (Scr->BackingStore) { + valuemask |= CWBackingStore; + attributes.backing_store = Always; + } + + mr->w = XCreateWindow (dpy, Scr->Root, 0, 0, (unsigned int) mr->width, + +/* djhjr - 4/22/96 + (unsigned int) mr->height, (unsigned int) 1, +*/ + (unsigned int) mr->height, (unsigned int) borderwidth, + + CopyFromParent, (unsigned int) CopyFromParent, + (Visual *) CopyFromParent, + valuemask, &attributes); + + + XSaveContext(dpy, mr->w, MenuContext, (caddr_t)mr); + XSaveContext(dpy, mr->w, ScreenContext, (caddr_t)Scr); + + mr->mapped = UNMAPPED; + } + + /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */ + if (Scr->MenuBevelWidth > 0 && (Scr->Monochrome == COLOR) && (mr->highlight.back == UNUSED_PIXEL)) { + XColor xcol; + char colname [32]; + short save; + + xcol.pixel = Scr->MenuC.back; + XQueryColor (dpy, cmap, &xcol); + sprintf (colname, "#%04x%04x%04x", + 5 * (xcol.red / 6), 5 * (xcol.green / 6), 5 * (xcol.blue / 6)); + save = Scr->FirstTime; + Scr->FirstTime = True; + GetColor (Scr->Monochrome, &mr->highlight.back, colname); + Scr->FirstTime = save; + } + + /* djhjr - 4/22/96 */ + /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */ + if (Scr->MenuBevelWidth > 0 && (Scr->Monochrome == COLOR) && (mr->highlight.fore == UNUSED_PIXEL)) { + XColor xcol; + char colname [32]; + short save; + xcol.pixel = Scr->MenuC.fore; + XQueryColor (dpy, cmap, &xcol); + sprintf (colname, "#%04x%04x%04x", + 5 * (xcol.red / 6), 5 * (xcol.green / 6), 5 * (xcol.blue / 6)); + save = Scr->FirstTime; + Scr->FirstTime = True; + GetColor (Scr->Monochrome, &mr->highlight.fore, colname); + Scr->FirstTime = save; + } + /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */ + if (Scr->MenuBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&mr->highlight); + + /* get the default colors into the menus */ + for (tmp = mr->first; tmp != NULL; tmp = tmp->next) + { +/* djhjr - 4/22/96 + if (!tmp->user_colors) { + if (tmp->func != F_TITLE) { + tmp->fore = Scr->MenuC.fore; + tmp->back = Scr->MenuC.back; + } else { + tmp->fore = Scr->MenuTitleC.fore; + tmp->back = Scr->MenuTitleC.back; + } + } + + if (mr->hi_fore != UNUSED_PIXEL) + { + tmp->hi_fore = mr->hi_fore; + tmp->hi_back = mr->hi_back; + } + else + { + tmp->hi_fore = tmp->back; + tmp->hi_back = tmp->fore; + } +*/ + if (!tmp->user_colors) { + if (tmp->func != F_TITLE) { + tmp->normal.fore = Scr->MenuC.fore; + tmp->normal.back = Scr->MenuC.back; + } else { + tmp->normal.fore = Scr->MenuTitleC.fore; + tmp->normal.back = Scr->MenuTitleC.back; + } + } + + if (mr->highlight.fore != UNUSED_PIXEL) + { + tmp->highlight.fore = mr->highlight.fore; + tmp->highlight.back = mr->highlight.back; + } + else + { + tmp->highlight.fore = tmp->normal.back; + tmp->highlight.back = tmp->normal.fore; + } + /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */ + if (Scr->MenuBevelWidth > 0 && !Scr->BeNiceToColormap) { + if (tmp->func != F_TITLE) + GetShadeColors (&tmp->highlight); + else + GetShadeColors (&tmp->normal); + } + + + } /* end for(...) */ + + if (Scr->Monochrome == MONOCHROME || !Scr->InterpolateMenuColors) + return; + + start = mr->first; + while (TRUE) + { + for (; start != NULL; start = start->next) + { + if (start->user_colors) + break; + } + if (start == NULL) + break; + + for (end = start->next; end != NULL; end = end->next) + { + if (end->user_colors) + break; + } + if (end == NULL) + break; + + /* we have a start and end to interpolate between */ + num = end->item_num - start->item_num; + +/* djhjr - 4/22/96 + f1.pixel = start->fore; + XQueryColor(dpy, cmap, &f1); + f2.pixel = end->fore; + XQueryColor(dpy, cmap, &f2); + + b1.pixel = start->back; + XQueryColor(dpy, cmap, &b1); + b2.pixel = end->back; + XQueryColor(dpy, cmap, &b2); +*/ + f1.pixel = start->normal.fore; + XQueryColor(dpy, cmap, &f1); + f2.pixel = end->normal.fore; + XQueryColor(dpy, cmap, &f2); + b1.pixel = start->normal.back; + XQueryColor(dpy, cmap, &b1); + b2.pixel = end->normal.back; + XQueryColor(dpy, cmap, &b2); + + fred = ((int)f2.red - (int)f1.red) / num; + fgreen = ((int)f2.green - (int)f1.green) / num; + fblue = ((int)f2.blue - (int)f1.blue) / num; + + bred = ((int)b2.red - (int)b1.red) / num; + bgreen = ((int)b2.green - (int)b1.green) / num; + bblue = ((int)b2.blue - (int)b1.blue) / num; + + f3 = f1; + f3.flags = DoRed | DoGreen | DoBlue; + + b3 = b1; + b3.flags = DoRed | DoGreen | DoBlue; + + /* djhjr - 4/23/96 */ + start->highlight.back = start->normal.fore; + start->highlight.fore = start->normal.back; + + num -= 1; + for (i = 0, cur = start->next; i < num; i++, cur = cur->next) + { + f3.red += fred; + f3.green += fgreen; + f3.blue += fblue; + save_fore = f3; + + b3.red += bred; + b3.green += bgreen; + b3.blue += bblue; + save_back = b3; + + if (Scr->DontInterpolateTitles && (cur->func == F_TITLE)) + continue; /* DSE -- from tvtwm */ + + XAllocColor(dpy, cmap, &f3); + XAllocColor(dpy, cmap, &b3); + +/* djhjr - 4/22/96 + cur->hi_back = cur->fore = f3.pixel; + cur->hi_fore = cur->back = b3.pixel; +*/ + cur->highlight.back = cur->normal.fore = f3.pixel; + cur->highlight.fore = cur->normal.back = b3.pixel; + cur->user_colors = True; + + f3 = save_fore; + b3 = save_back; + } + start = end; + + /* djhjr - 4/22/96 + start->highlight.back = start->normal.fore; + start->highlight.fore = start->normal.back; + */ + } +} + + + +/*********************************************************************** + * + * Procedure: + * PopUpMenu - pop up a pull down menu + * + * Inputs: + * menu - the root pointer of the menu to pop up + * x, y - location of upper left of menu + * center - whether or not to center horizontally over position + * + *********************************************************************** + */ + +Bool PopUpMenu (menu, x, y, center) + MenuRoot *menu; + int x, y; + Bool center; +{ + int WindowNameOffset, WindowNameCount; + TwmWindow **WindowNames; + TwmWindow *tmp_win2,*tmp_win3; + int mask; + int i; + int (*compar)() = + (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1); + + /* djhjr - 9/5/98 */ + int x_root, y_root; + + if (!menu) return False; + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + if (!PlaySound(F_MENU)) PlaySound(S_MMAP); +#endif + + /* djhjr - 5/22/00 */ + menu->top = 0; + if (menu->w) XClearArea(dpy, menu->w, 0, 0, 0, 0, True); + + InstallRootColormap(); + + if (menu == Scr->Windows) + { + TwmWindow *tmp_win; + + /* this is the twm windows menu, let's go ahead and build it */ + + DestroyMenu (menu); + + menu->first = NULL; + menu->last = NULL; + menu->items = 0; + menu->width = 0; + menu->mapped = NEVER_MAPPED; + +/* djhjr - 5/4/98 + AddToMenu(menu, "TWM Windows", NULLSTR, (MenuRoot *)NULL, F_TITLE,NULLSTR,NULLSTR); +*/ + AddToMenu(menu, "VTWM Windows", NULLSTR, (MenuRoot *)NULL, F_TITLE,NULLSTR,NULLSTR); + + WindowNameOffset=(char *)Scr->TwmRoot.next->name - + (char *)Scr->TwmRoot.next; + for(tmp_win = Scr->TwmRoot.next , WindowNameCount=0; + tmp_win != NULL; + tmp_win = tmp_win->next) + WindowNameCount++; + + if (WindowNameCount != 0) /* Submitted by Jennifer Elaan */ + { + WindowNames = + (TwmWindow **)malloc(sizeof(TwmWindow *)*WindowNameCount); + WindowNames[0] = Scr->TwmRoot.next; + for(tmp_win = Scr->TwmRoot.next->next , WindowNameCount=1; + tmp_win != NULL; + tmp_win = tmp_win->next,WindowNameCount++) + { + /* Submitted by Erik Agsjo */ + if (LookInList(Scr->DontShowInTWMWindows, tmp_win->full_name, &tmp_win->class)) + { + WindowNameCount--; + continue; + } + + tmp_win2 = tmp_win; + for (i=0;iname,WindowNames[i]->name) < 0) + { + tmp_win3 = tmp_win2; + tmp_win2 = WindowNames[i]; + WindowNames[i] = tmp_win3; + } + } + WindowNames[WindowNameCount] = tmp_win2; + } + for (i=0; iname, (char *)WindowNames[i], + (MenuRoot *)NULL, F_POPUP,NULLSTR,NULLSTR); + if (!Scr->OldFashionedTwmWindowsMenu + && Scr->Monochrome == COLOR)/*RFBCOLOR*/ + {/*RFBCOLOR*/ + menu->last->user_colors = TRUE;/*RFBCOLOR*/ + +/* djhjr - 4/22/96 + menu->last->fore = + WindowNames[i]->virtual.fore;*RFBCOLOR* +*/ +/* djhjr - 5/4/98 + menu->last->normal.fore = + WindowNames[i]->virtual.fore;*RFBCOLOR* +*/ + menu->last->normal.fore = Scr->MenuC.fore; + +/* djhjr - 4/22/96 + menu->last->back = + WindowNames[i]->virtual.back;*RFBCOLOR* +*/ + menu->last->normal.back = + WindowNames[i]->virtual.back; + +/**********************************************************/ +/* */ +/* Okay, okay, it's a bit of a kludge. */ +/* */ +/* On the other hand, it's nice to have the VTWM Windows */ +/* menu come up with "the right colors". And the colors */ +/* from the panner are not a bad choice... */ +/* */ +/**********************************************************/ + }/*RFBCOLOR*/ + } + free(WindowNames); + } + MakeMenu(menu); + } + + if (menu->w == None || menu->items == 0) return False; + + /* Prevent recursively bringing up menus. */ + if (menu->mapped == MAPPED) return False; + + /* + * Dynamically set the parent; this allows pull-ups to also be main + * menus, or to be brought up from more than one place. + */ + menu->prev = ActiveMenu; + + /* + * Submitted by Steve Ratcliffe + */ + mask = ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | PointerMotionHintMask; + if (Scr->StayUpMenus) + mask |= PointerMotionMask; + + XGrabPointer(dpy, Scr->Root, True, mask, + GrabModeAsync, GrabModeAsync, + Scr->Root, Scr->MenuCursor, CurrentTime); + + ActiveMenu = menu; + menu->mapped = MAPPED; + menu->entered = FALSE; + + if (center) { + x -= (menu->width / 2); + y -= (Scr->EntryHeight / 2); /* sticky menus would be nice here */ + } + + /* + * clip to screen + */ + /* next line and " - i" to "x = " and "y = " - djhjr - 5/22/00 */ + i = (Scr->MenuBevelWidth > 0) ? 0 : 2; + if (x + menu->width > Scr->MyDisplayWidth) { + x = Scr->MyDisplayWidth - menu->width - i; + } + if (x < 0) x = 0; + if (y + menu->height > Scr->MyDisplayHeight) { + y = Scr->MyDisplayHeight - menu->height - i; + } + if (y < 0) y = 0; + + MenuOrigins[MenuDepth].x = x; + MenuOrigins[MenuDepth].y = y; + MenuDepth++; + + XMoveWindow(dpy, menu->w, x, y); + if (Scr->Shadow) { + XMoveWindow (dpy, menu->shadow, x + SHADOWWIDTH, y + SHADOWWIDTH); + } + if (Scr->Shadow) { + XRaiseWindow (dpy, menu->shadow); + } + XMapRaised(dpy, menu->w); + if (Scr->Shadow) { + XMapWindow (dpy, menu->shadow); + } + XSync(dpy, 0); + + /* djhjr - 9/5/98 */ + XQueryPointer(dpy, menu->w, &JunkRoot, &JunkChild, + &x_root, &y_root, &JunkX, &JunkY, &JunkMask); + MenuOrigX = x_root; + MenuOrigY = y_root; + + return True; +} + + + +/*********************************************************************** + * + * Procedure: + * PopDownMenu - unhighlight the current menu selection and + * take down the menus + * + *********************************************************************** + */ + +void PopDownMenu() +{ + MenuRoot *tmp; + + if (ActiveMenu == NULL) + return; + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + PlaySound(S_MUNMAP); +#endif + + if (ActiveItem) + { + ActiveItem->state = 0; + PaintEntry(ActiveMenu, ActiveItem, False); + } + + for (tmp = ActiveMenu; tmp != NULL; tmp = tmp->prev) + { + if (Scr->Shadow) { + XUnmapWindow (dpy, tmp->shadow); + } + XUnmapWindow(dpy, tmp->w); + tmp->mapped = UNMAPPED; + UninstallRootColormap(); + } + + XFlush(dpy); + ActiveMenu = NULL; + ActiveItem = NULL; + MenuDepth = 0; + if (Context == C_WINDOW || Context == C_FRAME || Context == C_TITLE) + { menuFromFrameOrWindowOrTitlebar = TRUE; + } +} + + + +/*********************************************************************** + * + * Procedure: + * FindMenuRoot - look for a menu root + * + * Returned Value: + * (MenuRoot *) - a pointer to the menu root structure + * + * Inputs: + * name - the name of the menu root + * + *********************************************************************** + */ + +MenuRoot * +FindMenuRoot(name) + char *name; +{ + MenuRoot *tmp; + + for (tmp = Scr->MenuList; tmp != NULL; tmp = tmp->next) + { + if (strcmp(name, tmp->name) == 0) + return (tmp); + } + return NULL; +} + + + +static Bool belongs_to_twm_window (t, w) + register TwmWindow *t; + register Window w; +{ + if (!t) return False; + +#if 0 +StayUpMenus + if (w == t->frame || w == t->title_w || w == t->hilite_w || + w == t->icon_w || w == t->icon_bm_w) return True; +#endif + + if (t && t->titlebuttons) { + register TBWindow *tbw; + register int nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; + for (tbw = t->titlebuttons; nb > 0; tbw++, nb--) { + if (tbw->window == w) return True; + } + } + return False; +} + + + +/* + * Hack^H^H^H^HWrapper to moves for non-menu contexts. + * + * djhjr - 10/11/01 10/4/02 + */ +static void moveFromCenterWrapper(tmp_win) +TwmWindow *tmp_win; +{ + if (!tmp_win->opaque_move) XUngrabServer(dpy); + + WarpScreenToWindow(tmp_win); + + /* now here's a nice little kludge... */ + { + int hilite = tmp_win->highlight; + + tmp_win->highlight = True; + SetBorder(tmp_win, (hilite) ? True : False); + tmp_win->highlight = hilite; + + Scr->Focus = tmp_win; + } + + if (!tmp_win->opaque_move) XGrabServer(dpy); +} + +/* + * Jason P. Venner jason@tfs.com + * This function is used by F_WARPTO to match the action name + * against window names. + * Re-written to use list.c:MatchName(), allowing VTWM-style wilcards. + * djhjr - 10/27/02 + */ +int MatchWinName(action, t) +char *action; +TwmWindow *t; +{ + int matched = 0; +#ifndef NO_REGEX_SUPPORT + regex_t re; +#else + char re; +#endif + + if (MatchName(t->full_name, action, &re, LTYPE_ANY_STRING)) + if (MatchName(t->class.res_name, action, &re, LTYPE_ANY_STRING)) + if (MatchName(t->class.res_class, action, &re, LTYPE_ANY_STRING)) + matched = 1; + + return (matched); +} + + + +/*********************************************************************** + * + * Procedure: + * ExecuteFunction - execute a twm root function + * + * Inputs: + * func - the function to execute + * action - the menu action to execute + * w - the window to execute this function on + * tmp_win - the twm window structure + * event - the event that caused the function + * context - the context in which the button was pressed + * pulldown- flag indicating execution from pull down menu + * + * Returns: + * TRUE if should continue with remaining actions else FALSE to abort + * + *********************************************************************** + */ + +extern int MovedFromKeyPress; + +int +ExecuteFunction(func, action, w, tmp_win, eventp, context, pulldown) + int func; + char *action; + Window w; + TwmWindow *tmp_win; + XEvent *eventp; + int context; + int pulldown; +{ + char tmp[200]; + char *ptr; + char buff[MAX_FILE_SIZE]; + int count, fd; + int do_next_action = TRUE; + + actionHack = action; /* Submitted by Michel Eyckmans */ + RootFunction = F_NOFUNCTION; + if (Cancel) + return TRUE; /* XXX should this be FALSE? */ + + switch (func) + { + case F_UPICONMGR: + case F_LEFTICONMGR: + case F_RIGHTICONMGR: + case F_DOWNICONMGR: + case F_FORWICONMGR: + case F_BACKICONMGR: + case F_NEXTICONMGR: + case F_PREVICONMGR: + case F_NOP: + case F_TITLE: + case F_DELTASTOP: + case F_RAISELOWER: + case F_WARP: /* PF */ + case F_WARPCLASSNEXT: /* PF */ + case F_WARPCLASSPREV: /* PF */ + case F_WARPTOSCREEN: + case F_WARPTO: + case F_WARPRING: + case F_WARPTOICONMGR: + case F_COLORMAP: + + /* djhjr - 4/30/96 */ + case F_SEPARATOR: + + /* djhjr - 12/14/98 */ + case F_STATICICONPOSITIONS: + + /* djhjr - 5/30/00 */ + case F_WARPSNUG: + case F_WARPVISIBLE: + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + case F_SOUNDS: +#endif + + /* djhjr - 10/2/01 */ + case F_STRICTICONMGR: + + /* djhjr - 9/9/02 */ + case F_BINDBUTTONS: + case F_BINDKEYS: + case F_UNBINDBUTTONS: + case F_UNBINDKEYS: + + break; + default: + XGrabPointer(dpy, Scr->Root, True, + ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, + Scr->Root, Scr->WaitCursor, CurrentTime); + break; + } + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + switch (func) + { + case F_BEEP: + case F_SQUEEZECENTER: + case F_SQUEEZELEFT: + case F_SQUEEZERIGHT: + + /* djhjr - 11/4/03 */ + case F_MOVESCREEN: + + case F_FORCEMOVE: + case F_MOVE: + case F_RESIZE: + case F_EXEC: + case F_DELETE: + case F_DELETEDOOR: + case F_DESTROY: + case F_DEICONIFY: + case F_ICONIFY: + case F_IDENTIFY: + case F_VERSION: + case F_QUIT: + case F_WARP: + case F_WARPCLASSNEXT: + case F_WARPCLASSPREV: + case F_WARPRING: + case F_WARPTO: + case F_WARPTOICONMGR: + case F_WARPTONEWEST: + case F_WARPTOSCREEN: + /* handle uniquely */ + break; + case F_POPUP: + /* ignore */ + break; + case F_LOWER: + case F_RAISE: + case F_RAISELOWER: + case F_NAIL: + case F_NAMEDOOR: + case F_BOTTOMZOOM: + case F_FULLZOOM: + case F_HORIZOOM: + case F_LEFTZOOM: + case F_RIGHTZOOM: + case F_TOPZOOM: + case F_ZOOM: + case F_BACKICONMGR: + case F_DOWNICONMGR: + case F_FORWICONMGR: + case F_LEFTICONMGR: + case F_RIGHTICONMGR: + case F_UPICONMGR: + case F_FOCUS: + case F_SAVEYOURSELF: + case F_STICKYABOVE: + case F_RING: + case F_WINREFRESH: + + /* djhjr - 9/9/02 */ + case F_BINDBUTTONS: + case F_BINDKEYS: + case F_UNBINDBUTTONS: + case F_UNBINDKEYS: + + /* ignore if from a root menu */ + if (Context != C_ROOT && Context != C_NO_CONTEXT) + PlaySound(func); + break; + default: + /* unconditional */ + PlaySound(func); + break; + } +#endif + + switch (func) + { + case F_NOP: + case F_TITLE: + break; + + case F_DELTASTOP: + if (WindowMoved) do_next_action = FALSE; + break; + + case F_RESTART: + + /* added this 'case' and 'if () ... else ' - djhjr - 7/15/98 */ + case F_STARTWM: + if (func == F_STARTWM) + { + /* dynamic allocation of (char **)my_argv - djhjr - 9/26/02 */ + + char *p, *delims = " \t"; + char *new_argv = NULL, **my_argv = NULL; + int i = 0, j = 0; + + p = strtok(action, delims); + while (p) + { + if (j >= i) + { + i += 5; + new_argv = (char *)realloc((char *)my_argv, + i * sizeof(char *)); + if (new_argv == NULL) + { + fprintf(stderr, + "%s: unable to allocate %d bytes for execvp()\n", + ProgramName, i * sizeof(char *)); + break; + } + else + my_argv = (char **)new_argv; + } + + my_argv[j++] = strdup(p); + p = strtok(NULL, delims); + } + + if (new_argv != NULL) + { + my_argv[j] = NULL; + + /* djhjr - 7/31/98 */ + setup_restart(eventp->xbutton.time); + + execvp(*my_argv, my_argv); + fprintf(stderr, "%s: unable to start \"%s\"\n", + ProgramName, *my_argv); + new_argv = NULL; + } + + if (new_argv == NULL) + { + i = 0; + while (i < j) + free(my_argv[i++]); + if (j) + free((char *)my_argv); + } + } + else + /* djhjr - 7/31/98 */ + RestartVtwm(eventp->xbutton.time); + + break; + + case F_UPICONMGR: + case F_DOWNICONMGR: + case F_LEFTICONMGR: + case F_RIGHTICONMGR: + case F_FORWICONMGR: + case F_BACKICONMGR: + MoveIconManager(func); + break; + + case F_NEXTICONMGR: + case F_PREVICONMGR: + JumpIconManager(func); + break; + + case F_SHOWLIST: + + /* added this 'if (...) else ...' - djhjr - 9/21/99 */ + if (context == C_ROOT) + { + name_list *list; + + ShowIconMgr(&Scr->iconmgr); + + /* + * New code in list.c necessitates 'next_entry()' and + * 'contents_of_entry()' - djhjr - 10/20/01 + */ + for (list = Scr->IconMgrs; list != NULL; list = next_entry(list)) + ShowIconMgr((IconMgr *)contents_of_entry(list)); + } + else + { + IconMgr *ip; + + if ((ip = (IconMgr *)LookInList(Scr->IconMgrs, tmp_win->full_name, + &tmp_win->class)) == NULL) + ip = &Scr->iconmgr; + + ShowIconMgr(ip); + } + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + + break; + + case F_HIDELIST: + + if (Scr->NoIconManagers) + break; + + /* added argument - djhjr - 9/21/99 */ + HideIconManager((context == C_ROOT) ? NULL : tmp_win); + + break; + + case F_SORTICONMGR: + + /* djhjr - 6/10/98 */ + if (Scr->NoIconManagers || Scr->iconmgr.count == 0) + break; + + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + + { + int save_sort; + + save_sort = Scr->SortIconMgr; + Scr->SortIconMgr = TRUE; + + if (context == C_ICONMGR) + SortIconManager((IconMgr *) NULL); + else if (tmp_win->iconmgr) + SortIconManager(tmp_win->iconmgrp); + else + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + + Scr->SortIconMgr = save_sort; + } + break; + + case F_IDENTIFY: + if (DeferExecution(context, func, Scr->SelectCursor)) + { + return TRUE; + } + + Identify(tmp_win); + break; + + case F_VERSION: + Identify ((TwmWindow *) NULL); + break; + + case F_ZOOMZOOM: /* RFB silly */ + /* added args to iconmgrs - djhjr - 10/11/01 */ + Zoom( None, NULL, None, NULL ); + break; + + case F_AUTOPAN:/*RFB F_AUTOPAN*/ + { /* toggle autopan *//*RFB F_AUTOPAN*/ + static int saved;/*RFB F_AUTOPAN*/ + + if ( Scr->AutoPanX ) + { saved = Scr->AutoPanX;/*RFB F_AUTOPAN*/ + Scr->AutoPanX = 0;/*RFB F_AUTOPAN*/ + } else { /*RFB F_AUTOPAN*/ + Scr->AutoPanX = saved;/*RFB F_AUTOPAN*/ + /* if restart with no autopan, we'll set the + ** variable but we won't pan + */ + RaiseAutoPan(); /* DSE */ + }/*RFB F_AUTOPAN*/ + break;/*RFB F_AUTOPAN*/ + }/*RFB F_AUTOPAN*/ + + case F_STICKYABOVE: /* DSE */ + if (Scr->StickyAbove) { + LowerSticky(); Scr->StickyAbove = FALSE; + /* don't change the order of execution! */ + } else { + Scr->StickyAbove = TRUE; RaiseStickyAbove(); RaiseAutoPan(); + /* don't change the order of execution! */ + } + return TRUE; + /* break; *//* NOT REACHABLE */ + + case F_AUTORAISE: + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + + tmp_win->auto_raise = !tmp_win->auto_raise; + if (tmp_win->auto_raise) ++(Scr->NumAutoRaises); + else --(Scr->NumAutoRaises); + break; + + case F_BEEP: + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + /* sound has priority over bell */ + if (PlaySound(func)) break; +#endif + + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + break; + + case F_POPUP: + tmp_win = (TwmWindow *)action; + if (Scr->WindowFunction.func != F_NOFUNCTION) + { + ExecuteFunction(Scr->WindowFunction.func, + Scr->WindowFunction.item->action, + w, tmp_win, eventp, C_FRAME, FALSE); + } + else + { + DeIconify(tmp_win); + XRaiseWindow (dpy, tmp_win->frame); + XRaiseWindow (dpy, tmp_win->VirtualDesktopDisplayWindow); + + RaiseStickyAbove(); + RaiseAutoPan(); + } + break; + + case F_RESIZE: + { + TwmWindow *focused = NULL; /* djhjr - 5/27/03 */ + Bool fromtitlebar = False; + long releaseEvent; + long movementMask; + int resizefromcenter = 0; /* djhjr - 10/2/02 */ +/* djhjr - 10/6/02 */ +#ifndef NO_SOUND_SUPPORT + int did_playsound = FALSE; +#endif + + if (DeferExecution(context, func, Scr->ResizeCursor)) + return TRUE; + + PopDownMenu(); + + if (pulldown) + XWarpPointer(dpy, None, Scr->Root, 0, 0, 0, 0, + eventp->xbutton.x_root, + eventp->xbutton.y_root); + + EventHandler[EnterNotify] = HandleUnknown; + EventHandler[LeaveNotify] = HandleUnknown; + +/* allow the resizing of doors - djhjr - 2/22/99 + if ((w != tmp_win->icon_w) && (context != C_DOOR)) +*/ + if (context == C_ICON) /* can't resize icons */ + { + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + break; + } + + /* + * Resizing from a titlebar menu was handled uniquely long + * before I got here, and I added virtual windows and icon + * managers on 9/15/99 and 10/11/01, leveraging that code. + * It's all been integrated here. + * djhjr - 10/3/02 + */ + if (Context & (C_FRAME_BIT | C_WINDOW_BIT | C_TITLE_BIT) + && menuFromFrameOrWindowOrTitlebar) + { + XGetGeometry(dpy, w, &JunkRoot, &origDragX, &origDragY, + (unsigned int *)&DragWidth, + (unsigned int *)&DragHeight, + &JunkBW, &JunkDepth); + + resizefromcenter = 2; + } + else if (Context == C_VIRTUAL_WIN) + { + TwmWindow *twin; + + if ((XFindContext(dpy, eventp->xbutton.subwindow, + VirtualContext, (caddr_t *) &twin) == XCNOENT)) + { + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + break; + } + + context = C_WINDOW; + tmp_win = twin; + resizefromcenter = 1; + } + else if (Context == C_ICONMGR && tmp_win->list) + { + /* added the second argument - djhjr - 5/28/00 */ + if (!warp_if_warpunmapped(tmp_win, F_NOFUNCTION)) + { + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + break; + } + + resizefromcenter = 1; + } + + if (resizefromcenter) + { + WarpScreenToWindow(tmp_win); + + XWarpPointer(dpy, None, Scr->Root, 0, 0, 0, 0, + tmp_win->frame_x + tmp_win->frame_width / 2, + tmp_win->frame_y + tmp_win->frame_height / 2); + + /* grr - djhjr - 5/27/03 */ + focused = Scr->Focus; + Scr->Focus = tmp_win; + SetBorder(Scr->Focus, True); + + /* save positions so we can tell if it was moved or not */ + ResizeOrigX = tmp_win->frame_x + tmp_win->frame_width / 2; + ResizeOrigY = tmp_win->frame_y + tmp_win->frame_height / 2; + } + else + { + /* save position so we can tell if it was moved or not */ + ResizeOrigX = eventp->xbutton.x_root; + ResizeOrigY = eventp->xbutton.y_root; + } + + /* see if this is being done from the titlebar */ + fromtitlebar = belongs_to_twm_window(tmp_win, + eventp->xbutton.window); + + if (resizefromcenter == 2) + { + MenuStartResize(tmp_win, origDragX, origDragY, + DragWidth, DragHeight, Context); + + releaseEvent = ButtonPress; + movementMask = PointerMotionMask; + } + else + { + StartResize(eventp, tmp_win, fromtitlebar, context); + + fromtitlebar = False; + releaseEvent = ButtonRelease; + movementMask = ButtonMotionMask; + } + + /* substantially re-worked - djhjr - 5/27/03 */ + while (TRUE) + { + /* added exposure event masks - djhjr - 10/11/01 */ + XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask | + ExposureMask | VisibilityChangeMask | + movementMask, &Event); + +/* + * See down below, after this loop - djhjr - 5/27/03 + */ +#if 0 + /* discard crossing events before a release - djhjr - 10/11/01 */ + if (Event.xany.type == EnterNotify || + Event.xany.type == LeaveNotify) + { + /* this can't be the proper place - djhjr - 10/2/02 */ + SetBorder(tmp_win, True); + + continue; + } +#endif + + /* + * Don't discard exposure events before release + * or window borders and/or their titles in the + * virtual desktop won't get redrawn - djhjr + */ + + /* discard any extra motion events before a release */ + if (Event.type == MotionNotify) + { + /* was 'ButtonMotionMask' - djhjr - 10/11/01 */ + while (XCheckMaskEvent(dpy, releaseEvent | movementMask, + &Event)) + { + if (Event.type == releaseEvent) + break; + } + } + +/* + * See above, before this loop - djhjr - 5/27/03 + */ +#if 0 + if (fromtitlebar && Event.type == ButtonPress) { + fromtitlebar = False; + continue; + } +#endif + + if (Event.type == releaseEvent) + { + if (Cancel) + { + if (tmp_win->opaque_resize) + { + ConstrainSize(tmp_win, &origWidth, &origHeight); + SetupWindow(tmp_win, origx, origy, + origWidth, origHeight, -1); + ResizeTwmWindowContents(tmp_win, + origWidth, origHeight); + } + else + MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); + + ResizeWindow = None; + resizing_window = 0; + do_next_action = FALSE; + } + else + { + if (resizefromcenter == 2) + { + /* added passing of 'Context' - djhjr - 9/30/02 */ + MenuEndResize(tmp_win, Context); + } + else + EndResize(); + + /* DispatchEvent2() is depreciated - djhjr - 10/6/02 */ + DispatchEvent(); + + /* djhjr - 5/27/03 11/2/03 */ + if (!Scr->NoRaiseResize && !Scr->RaiseOnStart && + WindowMoved) + { + XRaiseWindow(dpy, tmp_win->frame); + SetRaiseWindow(tmp_win); + } + } + + break; + } + + /* DispatchEvent2() is depreciated - djhjr - 10/6/02 */ + if (!DispatchEvent()) continue; + + if (Event.type != MotionNotify) continue; + + XQueryPointer(dpy, Scr->Root, + &JunkRoot, &JunkChild, &JunkX, &JunkY, + &AddingX, &AddingY, &JunkMask); + + if (!resizing_window && + (abs(AddingX - ResizeOrigX) < Scr->MoveDelta && + abs(AddingY - ResizeOrigY) < Scr->MoveDelta)) + { + continue; + } + + resizing_window = 1; + WindowMoved = TRUE; + + /* djhjr - 5/27/03 11/3/03 */ + if ((!Scr->NoRaiseResize && Scr->RaiseOnStart) + /* trap a Shape extention bug - djhjr - 5/27/03 */ + || (tmp_win->opaque_resize && + (HasShape && + (tmp_win->wShaped || tmp_win->squeeze_info))) + ) + { + XRaiseWindow(dpy, tmp_win->frame); + SetRaiseWindow(tmp_win); + if (Scr->Virtual && tmp_win->VirtualDesktopDisplayWindow) + XRaiseWindow(dpy, tmp_win->VirtualDesktopDisplayWindow); + } + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + if (did_playsound == FALSE) + { + PlaySound(func); + did_playsound = TRUE; + } +#endif + + /* MenuDoResize() is depreciated - djhjr - 10/6/02 */ + DoResize(AddingX, AddingY, tmp_win); + } + +/* djhjr - 6/4/98 + return TRUE; +*/ + +/* djhjr - 7/17/98 + * djhjr - 4/7/98 * + if (!Scr->NoGrabServer) XUngrabServer(dpy); +*/ + if (!tmp_win->opaque_resize) XUngrabServer(dpy); + + /* + * All this stuff from resize.c:EndResize() - djhjr - 10/6/02 + */ + + if (!tmp_win->opaque_resize) + UninstallRootColormap(); + + /* discard queued enter and leave events - djhjr - 5/27/03 */ + while (XCheckMaskEvent(dpy, EnterWindowMask | LeaveWindowMask, + &Event)) + ; + + if (!Scr->NoRaiseResize) + { + RaiseStickyAbove (); /* DSE */ + RaiseAutoPan(); + } + + /* update virtual coords */ + tmp_win->virtual_frame_x = Scr->VirtualDesktopX + tmp_win->frame_x; + tmp_win->virtual_frame_y = Scr->VirtualDesktopY + tmp_win->frame_y; + + /* UpdateDesktop(tmp_win); Stig */ +/* djhjr - 5/27/03 + MoveResizeDesktop(tmp_win, Scr->NoRaiseResize); * Stig * +*/ + MoveResizeDesktop(tmp_win, Cancel | Scr->NoRaiseResize); /* Stig */ + + /* djhjr - 9/30/02 10/6/02 */ + if (Context == C_VIRTUAL_WIN) + { + /* + * Mask a bug that calls MoveOutline(zeros) after the + * border has been repainted, leaving artifacts. I think + * I know what the bug is, but I can't seem to fix it. + */ + if (Scr->BorderBevelWidth > 0) PaintBorders(tmp_win, False); + + JunkX = tmp_win->virtual_frame_x + tmp_win->frame_width / 2; + JunkY = tmp_win->virtual_frame_y + tmp_win->frame_height / 2; + XWarpPointer(dpy, None, Scr->VirtualDesktopDisplayOuter, + 0, 0, 0, 0, SCALE_D(JunkX), SCALE_D(JunkY)); + + /* grr - djhjr - 5/27/03 */ + SetBorder(Scr->Focus, False); + Scr->Focus = focused; + } + + /* djhjr - 6/4/98 */ + /* don't re-map if the window is the virtual desktop - djhjr - 2/28/99 */ + if (Scr->VirtualReceivesMotionEvents && + /* !tmp_win->opaque_resize && */ + tmp_win->w != Scr->VirtualDesktopDisplayOuter) + { + XUnmapWindow(dpy, Scr->VirtualDesktopDisplay); + XMapWindow(dpy, Scr->VirtualDesktopDisplay); + } + + break; + } + + case F_ZOOM: + case F_HORIZOOM: + case F_FULLZOOM: + case F_LEFTZOOM: + case F_RIGHTZOOM: + case F_TOPZOOM: + case F_BOTTOMZOOM: + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + + /* djhjr - 4/1/00 */ + PopDownMenu(); + + fullzoom(tmp_win, func); + /* UpdateDesktop(tmp_win); Stig */ + MoveResizeDesktop(tmp_win, Scr->NoRaiseMove); /* Stig */ + break; + + case F_MOVE: + case F_FORCEMOVE: + { + static Time last_time = 0; + Window rootw; + Bool fromtitlebar = False; + int moving_icon = FALSE; + int constMoveDir, constMoveX, constMoveY; + int constMoveXL, constMoveXR, constMoveYT, constMoveYB; + int origX, origY; + long releaseEvent; + long movementMask; + int xl, yt, xr, yb; + int movefromcenter = 0; /* djhjr - 10/4/02 */ +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + int did_playsound = FALSE; +#endif + + if (DeferExecution(context, func, Scr->MoveCursor)) + return TRUE; + + PopDownMenu(); + rootw = eventp->xbutton.root; + + if (pulldown) + XWarpPointer(dpy, None, Scr->Root, + 0, 0, 0, 0, eventp->xbutton.x_root, + eventp->xbutton.y_root); + + EventHandler[EnterNotify] = HandleUnknown; + EventHandler[LeaveNotify] = HandleUnknown; + +/* djhjr - 4/7/98 + if (!Scr->NoGrabServer || !Scr->OpaqueMove) XGrabServer(dpy); +*/ +/* djhjr - 7/17/98 + if (!Scr->NoGrabServer) XGrabServer(dpy); +*/ + if (!tmp_win->opaque_move) XGrabServer(dpy); + +/* use initialized size... djhjr - 5/9/96 + * djhjr - 4/27/96 * + Scr->SizeStringOffset = SIZE_HINDENT; + XResizeWindow(dpy, Scr->SizeWindow, + Scr->SizeStringWidth + SIZE_HINDENT * 2, + Scr->SizeFont.height + SIZE_VINDENT * 2); +*/ + + XGrabPointer(dpy, eventp->xbutton.root, True, + ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | PointerMotionMask, + /* PointerMotionHintMask */ + GrabModeAsync, GrabModeAsync, + Scr->Root, Scr->MoveCursor, CurrentTime); + + /* added this 'if (...) else' - djhjr - 10/11/01 */ + if (context == C_VIRTUAL_WIN) + { + TwmWindow *twin; + + if ((XFindContext(dpy, eventp->xbutton.subwindow, + VirtualContext, (caddr_t *) &twin) == XCNOENT)) + { + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + break; + } + + tmp_win = twin; + moveFromCenterWrapper(tmp_win); + /* these two - djhjr - 10/4/02 */ + w = tmp_win->frame; + movefromcenter = 1; + } + else + + /* added this 'if (...) else' - djhjr - 9/15/99 */ + if (context == C_ICONMGR && tmp_win->list) + { + /* added the second argument - djhjr - 5/28/00 */ + if (!warp_if_warpunmapped(tmp_win, F_NOFUNCTION)) + { + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + break; + } + + moveFromCenterWrapper(tmp_win); /* djhjr - 10/11/01 */ + /* these two - djhjr - 10/4/02 */ + w = tmp_win->frame; + movefromcenter = 1; + } + else + + if (context == C_ICON && tmp_win->icon_w) + { + DragX = eventp->xbutton.x; + DragY = eventp->xbutton.y; + + w = tmp_win->icon_w; + moving_icon = TRUE; + } + else if (w != tmp_win->icon_w) + { + XTranslateCoordinates(dpy, w, tmp_win->frame, + eventp->xbutton.x, + eventp->xbutton.y, + &DragX, &DragY, &JunkChild); + + w = tmp_win->frame; + } + + XMapRaised (dpy, Scr->SizeWindow); + + DragWindow = None; + + MoveFunction = func; /* set for DispatchEvent() */ + + XGetGeometry(dpy, w, &JunkRoot, &origDragX, &origDragY, + (unsigned int *)&DragWidth, + (unsigned int *)&DragHeight, + &JunkBW, &JunkDepth); + + /* added this 'if (...) else' - djhjr - 10/4/02 */ + if (menuFromFrameOrWindowOrTitlebar || + movefromcenter || (moving_icon && fromMenu)) + { + origX = DragX = origDragX + DragWidth / 2; + origY = DragY = origDragY + DragHeight / 2; + } + else + { + origX = eventp->xbutton.x_root; + origY = eventp->xbutton.y_root; + } + + CurrentDragX = origDragX; + CurrentDragY = origDragY; + + /* + * Only do the constrained move if timer is set - + * need to check it in case of stupid or wicked fast servers. + */ + if ( ConstrainedMoveTime && + eventp->xbutton.time - last_time < ConstrainedMoveTime) + { + int width, height; + + ConstMove = TRUE; + constMoveDir = MOVE_NONE; + constMoveX = eventp->xbutton.x_root - DragX - JunkBW; + constMoveY = eventp->xbutton.y_root - DragY - JunkBW; + width = DragWidth + 2 * JunkBW; + height = DragHeight + 2 * JunkBW; + constMoveXL = constMoveX + width/3; + constMoveXR = constMoveX + 2*(width/3); + constMoveYT = constMoveY + height/3; + constMoveYB = constMoveY + 2*(height/3); + + XWarpPointer(dpy, None, w, + 0, 0, 0, 0, DragWidth/2, DragHeight/2); + + XQueryPointer(dpy, w, &JunkRoot, &JunkChild, + &JunkX, &JunkY, &DragX, &DragY, &JunkMask); + } + last_time = eventp->xbutton.time; + +/* djhjr - 4/7/98 + if (!Scr->OpaqueMove) +*/ + if (!tmp_win->opaque_move) + { + InstallRootColormap(); + /*if (!Scr->MoveDelta)*/ /* djhjr - 10/2/02 */ + { + /* + * Draw initial outline. This was previously done the + * first time though the outer loop by dropping out of + * the XCheckMaskEvent inner loop down to one of the + * MoveOutline's below. + */ + MoveOutline(rootw, + origDragX - JunkBW, origDragY - JunkBW, + DragWidth + 2 * JunkBW, DragHeight + 2 * JunkBW, + tmp_win->frame_bw, +/* djhjr - 4/22/96 + moving_icon ? 0 : tmp_win->title_height); +*/ + moving_icon ? 0 : tmp_win->title_height + tmp_win->frame_bw3D); + + /* + * This next line causes HandleButtonRelease to call + * XRaiseWindow(). This is solely to preserve the + * previous behaviour that raises a window being moved + * on button release even if you never actually moved + * any distance (unless you move less than MoveDelta or + * NoRaiseMove is set or OpaqueMove is set). + * + * It's set way down below; no need to force it here. + * djhjr - 10/4/02 + * + * The code referred to above is 'if 0'd out now anyway. + * djhjr - 10/6/02 + */ + /*DragWindow = w;*/ + } + } + + /* + * see if this is being done from the titlebar + */ + fromtitlebar = belongs_to_twm_window(tmp_win, + eventp->xbutton.window); + + /* added 'movefromcenter' and 'moving_icon' - djhjr - 10/4/02 */ + if ((menuFromFrameOrWindowOrTitlebar && !fromtitlebar) || + movefromcenter || (moving_icon && fromMenu)) + { + /* warp the pointer to the middle of the window */ + XWarpPointer(dpy, None, Scr->Root, 0, 0, 0, 0, + origDragX + DragWidth / 2, + origDragY + DragHeight / 2); + + SetBorder(tmp_win, True); /* grr */ + + XFlush(dpy); + } + + /* djhjr - 4/27/96 */ + DisplayPosition(CurrentDragX, CurrentDragY); + + if (menuFromFrameOrWindowOrTitlebar) + { + releaseEvent = ButtonPress; + movementMask = PointerMotionMask; + } + else + { + releaseEvent = ButtonRelease; + movementMask = ButtonMotionMask; + } + + while (TRUE) + { + /* block until there is an interesting event */ + XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask | + ExposureMask | VisibilityChangeMask | + movementMask, &Event); + +/* + * See down below, after this loop - djhjr - 5/23/03 + */ +#if 0 + /* throw away enter and leave events until release */ + if (Event.xany.type == EnterNotify || + Event.xany.type == LeaveNotify) + { + continue; + } +#endif + + /* + * Don't discard exposure events before release + * or window borders and/or their titles in the + * virtual desktop won't get redrawn - djhjr + */ + + /* discard any extra motion events before a release */ + if (Event.type == MotionNotify) + { + while (XCheckMaskEvent(dpy, movementMask | releaseEvent, + &Event)) + { + if (Event.type == releaseEvent) + break; + } + } + + /* + * There used to be a couple of routines that handled the + * cancel functionality here, each doing a portion of the + * job, then returning immediately. They became redundant + * to just letting program execution fall through. So now, + * the 'if (Event.type == releaseEvent) if (Cancel)' below + * does just that, clearing a few flags first. + * djhjr - 10/6/02 + */ + + if (fromtitlebar && Event.type == ButtonPress) + { + fromtitlebar = False; + CurrentDragX = origX = Event.xbutton.x_root; + CurrentDragY = origY = Event.xbutton.y_root; + XTranslateCoordinates(dpy, rootw, tmp_win->frame, + origX, origY, + &DragX, &DragY, &JunkChild); + + continue; + } + + /* DispatchEvent2() is depreciated - djhjr - 10/6/02 */ + if (!DispatchEvent()) continue; + + /* re-wrote this stuff - djhjr - 10/4/02 5/24/03 11/2/03 */ + if (Event.type == releaseEvent) + { + MoveOutline(rootw, 0, 0, 0, 0, 0, 0); + + if (Cancel) + { + DragWindow = None; + ConstMove = WindowMoved = do_next_action = FALSE; + } + else if (WindowMoved) + { + if (moving_icon) + { + tmp_win->icon_moved = TRUE; + XMoveWindow(dpy, tmp_win->icon_w, + CurrentDragX, CurrentDragY); + + if (!Scr->NoRaiseMove && !Scr->RaiseOnStart) + { + XRaiseWindow(dpy, tmp_win->icon_w); + SetRaiseWindow(tmp_win->icon_w); + } + } + else + { + if (movefromcenter) + { + tmp_win->frame_x = Event.xbutton.x_root - + DragWidth / 2; + tmp_win->frame_y = Event.xbutton.y_root - + DragHeight / 2; + } + else + { + tmp_win->frame_x = CurrentDragX; + tmp_win->frame_y = CurrentDragY; + } + + XMoveWindow(dpy, tmp_win->frame, + tmp_win->frame_x, tmp_win->frame_y); + SendConfigureNotify(tmp_win, tmp_win->frame_x, + tmp_win->frame_y); + + if (!Scr->NoRaiseMove && !Scr->RaiseOnStart) + { + XRaiseWindow(dpy, tmp_win->frame); + SetRaiseWindow(tmp_win); + } + } + } + + break; + } + + /* something left to do only if the pointer moved */ + if (Event.type != MotionNotify) continue; + + XQueryPointer(dpy, rootw, &(eventp->xmotion.root), &JunkChild, + &(eventp->xmotion.x_root), + &(eventp->xmotion.y_root), + &JunkX, &JunkY, &JunkMask); + + if (DragWindow == None && + abs(eventp->xmotion.x_root - origX) < Scr->MoveDelta && + abs(eventp->xmotion.y_root - origY) < Scr->MoveDelta) + { + continue; + } + + WindowMoved = TRUE; + DragWindow = w; + +/* djhjr - 4/7/98 + if (!Scr->NoRaiseMove && Scr->OpaqueMove) +*/ +/* djhjr - 10/6/02 + if (!Scr->NoRaiseMove && tmp_win->opaque_move) + XRaiseWindow(dpy, DragWindow); +*/ + /* djhjr - 5/24/03 11/3/03 */ + if (!Scr->NoRaiseMove && Scr->RaiseOnStart) + { + if (moving_icon) + { + XRaiseWindow(dpy, tmp_win->icon_w); + SetRaiseWindow(tmp_win->icon_w); + } + else + { + XRaiseWindow(dpy, tmp_win->frame); + SetRaiseWindow(tmp_win); + if (Scr->Virtual && + tmp_win->VirtualDesktopDisplayWindow) + XRaiseWindow(dpy, + tmp_win->VirtualDesktopDisplayWindow); + } + } + + if (ConstMove) + { + switch (constMoveDir) + { + case MOVE_NONE: + if (eventp->xmotion.x_root < constMoveXL || + eventp->xmotion.x_root > constMoveXR) + { + constMoveDir = MOVE_HORIZ; + } + if (eventp->xmotion.y_root < constMoveYT || + eventp->xmotion.y_root > constMoveYB) + { + constMoveDir = MOVE_VERT; + } + XQueryPointer(dpy, DragWindow, &JunkRoot, + &JunkChild, &JunkX, &JunkY, + &DragX, &DragY, &JunkMask); + break; + case MOVE_VERT: + constMoveY = eventp->xmotion.y_root - DragY - + JunkBW; + break; + case MOVE_HORIZ: + constMoveX = eventp->xmotion.x_root - DragX - + JunkBW; + break; + } + + xl = constMoveX; + yt = constMoveY; + } + else if (DragWindow != None) + { + /* added 'movefromcenter' and 'moving_icon' - djhjr - 10/4/02 */ + if (!menuFromFrameOrWindowOrTitlebar && + !movefromcenter && !(moving_icon && fromMenu)) + { + xl = eventp->xmotion.x_root - DragX - JunkBW; + yt = eventp->xmotion.y_root - DragY - JunkBW; + } + else + { + xl = eventp->xmotion.x_root - (DragWidth / 2); + yt = eventp->xmotion.y_root - (DragHeight / 2); + } + } + + if ((ConstMove && constMoveDir != MOVE_NONE) || + DragWindow != None) + { + int width = DragWidth + 2 * JunkBW; + int height = DragHeight + 2 * JunkBW; + + if (Scr->DontMoveOff && MoveFunction != F_FORCEMOVE) + { + xr = xl + width; + yb = yt + height; + + if (xl < 0) xl = 0; + if (xr > Scr->MyDisplayWidth) + xl = Scr->MyDisplayWidth - width; + + if (yt < 0) yt = 0; + if (yb > Scr->MyDisplayHeight) + yt = Scr->MyDisplayHeight - height; + } + + CurrentDragX = xl; + CurrentDragY = yt; + +/* djhjr - 6/22/01 10/6/02 */ +#ifndef NO_SOUND_SUPPORT + if ((!ConstMove || constMoveDir != MOVE_NONE) && + did_playsound == FALSE) + { + PlaySound(func); + did_playsound = TRUE; + } +#endif + +/* djhjr - 4/7/98 + if (Scr->OpaqueMove) +*/ + if (tmp_win->opaque_move) + XMoveWindow(dpy, DragWindow, xl, yt); + else + MoveOutline(eventp->xmotion.root, xl, yt, + width, height, tmp_win->frame_bw, +/* djhjr - 4/22/96 + moving_icon ? 0 : tmp_win->title_height); +*/ + moving_icon ? 0 : tmp_win->title_height + tmp_win->frame_bw3D); + +/* djhjr - 4/17/98 + * move the small representation window + * this knows a bit much about the internals i guess + * XMoveWindow(dpy, tmp_win->VirtualDesktopDisplayWindow, SCALE_D(xl), SCALE_D(yt)); +*/ + if (Scr->VirtualReceivesMotionEvents) + { + tmp_win->virtual_frame_x = R_TO_V_X(xl); + tmp_win->virtual_frame_y = R_TO_V_Y(yt); +/* djhjr - 5/24/03 + MoveResizeDesktop(tmp_win, Scr->NoRaiseMove); +*/ + MoveResizeDesktop(tmp_win, TRUE); + } + + /* djhjr - 4/27/96 */ + DisplayPosition (xl, yt); + } + } + +/* djhjr - 7/17/98 + * djhjr - 4/7/98 * + if (!Scr->NoGrabServer) XUngrabServer(dpy); +*/ + if (!tmp_win->opaque_move) XUngrabServer(dpy); + + /* djhjr - 4/27/96 */ + XUnmapWindow (dpy, Scr->SizeWindow); + + MovedFromKeyPress = False; + + if (!tmp_win->opaque_move) + UninstallRootColormap(); + + /* discard queued enter and leave events - djhjr - 5/23/03 */ + while (XCheckMaskEvent(dpy, EnterWindowMask | LeaveWindowMask, + &Event)) + ; + + /* from events.c:HandleButtonRelease() - djhjr - 10/6/02 */ + if (!Scr->NoRaiseMove) + { + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + } + + /* update virtual coords */ + tmp_win->virtual_frame_x = Scr->VirtualDesktopX + tmp_win->frame_x; + tmp_win->virtual_frame_y = Scr->VirtualDesktopY + tmp_win->frame_y; + + /* UpdateDesktop() hoses the stacking order - djhjr - 10/6/02 */ +/* djhjr - 5/24/03 + MoveResizeDesktop(tmp_win, Scr->NoRaiseMove); +*/ + MoveResizeDesktop(tmp_win, Cancel | Scr->NoRaiseMove); + + /* djhjr - 10/4/02 10/6/02 */ + if (Context == C_VIRTUAL_WIN) + { + /* + * Mask a bug that calls MoveOutline(zeros) after the + * border has been repainted, leaving artifacts. I think + * I know what the bug is, but I can't seem to fix it. + */ + if (Scr->BorderBevelWidth > 0) PaintBorders(tmp_win, False); + + JunkX = tmp_win->virtual_frame_x + tmp_win->frame_width / 2; + JunkY = tmp_win->virtual_frame_y + tmp_win->frame_height / 2; + XWarpPointer(dpy, None, Scr->VirtualDesktopDisplayOuter, + 0, 0, 0, 0, SCALE_D(JunkX), SCALE_D(JunkY)); + } + + /* djhjr - 6/4/98 */ + /* don't re-map if the window is the virtual desktop - djhjr - 2/28/99 */ + if (Scr->VirtualReceivesMotionEvents && + /* !tmp_win->opaque_move && */ + tmp_win->w != Scr->VirtualDesktopDisplayOuter) + { + XUnmapWindow(dpy, Scr->VirtualDesktopDisplay); + XMapWindow(dpy, Scr->VirtualDesktopDisplay); + } + + MoveFunction = F_NOFUNCTION; /* clear for DispatchEvent() */ + + /* sanity check (also in events.c:HandleButtonRelease()) - djhjr - 10/6/02 */ + DragWindow = None; + ConstMove = FALSE; + + break; + } + case F_FUNCTION: + { + MenuRoot *mroot; + MenuItem *mitem; + Cursor cursor; + + if ((mroot = FindMenuRoot(action)) == NULL) + { + fprintf (stderr, "%s: couldn't find function \"%s\"\n", + ProgramName, action); + return TRUE; + } + +/* + * Changed this 'if ()' for deferred keyboard events (see also events.c) + * Submitted by Michel Eyckmans + * + if (NeedToDefer(mroot) && DeferExecution(context, func, Scr->SelectCursor)) + */ + if ((cursor = NeedToDefer(mroot)) != None && DeferExecution(context, func, cursor)) + return TRUE; + else + { + for (mitem = mroot->first; mitem != NULL; mitem = mitem->next) + { + if (!ExecuteFunction (mitem->func, mitem->action, w, + tmp_win, eventp, context, pulldown)) + break; + } + } + } + break; + + case F_DEICONIFY: + case F_ICONIFY: + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + + /* added '|| (...)' - djhjr - 6/3/03 */ + if (tmp_win->icon || + (func == F_DEICONIFY && tmp_win == tmp_win->list->twm)) + { +/* djhjr - 6/3/03 */ +#ifndef NO_SOUND_SUPPORT + PlaySound(func); +#endif + + DeIconify(tmp_win); + + /* + * now HERE's a fine bit of kludge! it's to mask a hole in the + * code I can't find that messes up when trying to warp to the + * de-iconified window not in the real screen when WarpWindows + * isn't used. see also the change in DeIconify(). + * djhjr - 1/24/98 + */ + if (!Scr->WarpWindows && (Scr->WarpCursor || + LookInList(Scr->WarpCursorL, tmp_win->full_name, &tmp_win->class))) + { + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + + WarpToWindow(tmp_win); /* PF */ + } + } + else if (func == F_ICONIFY) + { + /* djhjr - 9/10/99 */ + TwmDoor *d; + TwmWindow *tmgr = NULL, *twin = NULL; + MenuRoot *mr; + + /* sanity check for what's next - djhjr - 9/10/99 */ + if (XFindContext(dpy, tmp_win->w, DoorContext, + (caddr_t *)&d) != XCNOENT) + { + twin = tmp_win; + tmp_win = d->twin; + } + + /* + * don't iconify if there's no way to get it back - not fool-proof + * djhjr - 9/10/99 + */ + if (tmp_win->iconify_by_unmapping) + { + /* iconified by unmapping */ + + if (tmp_win->list) tmgr = tmp_win->list->iconmgr->twm_win; + + if ((tmgr && !tmgr->mapped && tmgr->iconify_by_unmapping) || + ((Scr->IconManagerDontShow || + LookInList(Scr->IconMgrNoShow, tmp_win->full_name, &tmp_win->class)) && + LookInList(Scr->IconMgrShow, tmp_win->full_name, &tmp_win->class) == (char *)NULL)) + { + /* icon manager not mapped or not shown in one */ + + if (have_twmwindows == -1) + { + have_twmwindows = 0; + + /* better than two calls to FindMenuRoot() */ + for (mr = Scr->MenuList; mr != NULL; mr = mr->next) + if (strcmp(mr->name, TWM_WINDOWS) == 0 || + strcmp(mr->name, VTWM_WINDOWS) == 0) + { + /* djhjr - 9/21/99 */ + have_twmwindows = FindMenuOrFuncInBindings(C_ALL_BITS, mr, F_NOFUNCTION); + break; + } + } + /* djhjr - 9/21/99 */ + if (have_showdesktop == -1) + have_showdesktop = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWDESKTOP); + if (have_showlist == -1) + have_showlist = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWLIST); + + /* djhjr - 9/21/99 */ + if (!FindMenuOrFuncInWindows(tmp_win, have_twmwindows, mr, F_NOFUNCTION) || + LookInList(Scr->DontShowInTWMWindows, tmp_win->full_name, &tmp_win->class)) + { + /* no TwmWindows menu or not shown in it */ + + if (tmp_win->w == Scr->VirtualDesktopDisplayOuter && + FindMenuOrFuncInWindows(tmp_win, have_showdesktop, NULL, F_SHOWDESKTOP)) + ; + else if (tmp_win->iconmgr && + FindMenuOrFuncInWindows(tmp_win, have_showlist, NULL, F_SHOWLIST)) + ; + else if (tmgr && + FindMenuOrFuncInWindows(tmgr, have_showlist, NULL, F_SHOWLIST)) + ; + else + { + /* no f.showdesktop or f.showiconmgr */ + + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + + if (twin) tmp_win = twin; + break; + } + } + } + } + + if (twin) tmp_win = twin; + + if (tmp_win->list || !Scr->NoIconifyIconManagers) /* PF */ + { +/* djhjr - 6/3/03 */ +#ifndef NO_SOUND_SUPPORT + PlaySound(func); +#endif + + Iconify (tmp_win, eventp->xbutton.x_root - EDGE_OFFSET, /* DSE */ + eventp->xbutton.y_root - EDGE_OFFSET); /* DSE */ + } + } + break; + + case F_RAISELOWER: + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + + if (!WindowMoved) { + XWindowChanges xwc; + + xwc.stack_mode = Opposite; + if (w != tmp_win->icon_w) + w = tmp_win->frame; + XConfigureWindow (dpy, w, CWStackMode, &xwc); + XConfigureWindow (dpy, tmp_win->VirtualDesktopDisplayWindow, CWStackMode, &xwc); + /* ug */ + XLowerWindow(dpy, Scr->VirtualDesktopDScreen); + } + break; + + case F_RAISE: + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + + /* check to make sure raise is not from the WindowFunction */ + if (w == tmp_win->icon_w && Context != C_ROOT) + XRaiseWindow(dpy, tmp_win->icon_w); + else + { + XRaiseWindow(dpy, tmp_win->frame); + XRaiseWindow(dpy, tmp_win->VirtualDesktopDisplayWindow); + } + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + + break; + + case F_LOWER: + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + + if (!(Scr->StickyAbove && tmp_win->nailed)) { /* DSE */ + if (w == tmp_win->icon_w) + XLowerWindow(dpy, tmp_win->icon_w); + else + { XLowerWindow(dpy, tmp_win->frame); + XLowerWindow(dpy, tmp_win->VirtualDesktopDisplayWindow); + XLowerWindow(dpy, Scr->VirtualDesktopDScreen); + } + } /* DSE */ + + break; + + case F_FOCUS: + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + + if (tmp_win->icon == FALSE) + { + if (!Scr->FocusRoot && Scr->Focus == tmp_win) + { + FocusOnRoot(); + } + else + { + if (Scr->Focus != NULL) { + SetBorder (Scr->Focus, False); + +/* djhjr - 4/25/96 + if (Scr->Focus->hilite_w) + XUnmapWindow (dpy, Scr->Focus->hilite_w); +*/ + PaintTitleHighlight(Scr->Focus, off); + + } + + InstallWindowColormaps (0, tmp_win); + +/* djhjr - 4/25/96 + if (tmp_win->hilite_w) XMapWindow (dpy, tmp_win->hilite_w); +*/ + PaintTitleHighlight(tmp_win, on); + + SetBorder (tmp_win, True); + SetFocus (tmp_win, eventp->xbutton.time); + Scr->FocusRoot = FALSE; + Scr->Focus = tmp_win; + } + } + break; + + case F_DESTROY: + if (DeferExecution(context, func, Scr->DestroyCursor)) + return TRUE; + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + /* flag for the handler */ + if (PlaySound(func)) destroySoundFromFunction = TRUE; +#endif + + /* djhjr - 9/10/96 */ + if (tmp_win == Scr->VirtualDesktopDisplayTwin) + { + /* added this 'if (...) ...' and 'if (...) else' - djhjr - 9/21/99 */ + if (have_showdesktop == -1) + have_showdesktop = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWDESKTOP); + if (FindMenuOrFuncInWindows(tmp_win, have_showdesktop, NULL, F_SHOWDESKTOP)) + XUnmapWindow(dpy, Scr->VirtualDesktopDisplayTwin->frame); + else + + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + break; + } + + { + TwmDoor *d; + + if (XFindContext(dpy, tmp_win->w, DoorContext, + (caddr_t *) &d) != XCNOENT) + { +/* djhjr - 9/10/99 + XBell(dpy, 0); +*/ + /* for some reason, we don't get the button up event - djhjr - 9/10/99 */ + ButtonPressed = -1; + door_delete(tmp_win->w, d); + + break; + } + } + + if (tmp_win->iconmgr) /* don't send ourself a message */ + { + /* added this 'if (...) ...' and 'if (...) else ...' - djhjr - 9/21/99 */ + if (have_showlist == -1) + have_showlist = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWLIST); + if (FindMenuOrFuncInWindows(tmp_win, have_showlist, NULL, F_SHOWLIST)) + + /* added argument - djhjr - 9/21/99 */ + HideIconManager(tmp_win); + + else + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + } + else + { + /* djhjr - 4/26/99 */ + AppletDown(tmp_win); + + XKillClient(dpy, tmp_win->w); + } + break; + + case F_DELETE: + if (DeferExecution(context, func, Scr->DestroyCursor)) + return TRUE; + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + /* flag for the handler */ + if (PlaySound(func)) destroySoundFromFunction = TRUE; +#endif + + /* djhjr - 9/21/99 */ + if (tmp_win == Scr->VirtualDesktopDisplayTwin) + { + if (have_showdesktop == -1) + have_showdesktop = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWDESKTOP); + if (FindMenuOrFuncInWindows(tmp_win, have_showdesktop, NULL, F_SHOWDESKTOP)) + XUnmapWindow(dpy, Scr->VirtualDesktopDisplayTwin->frame); + else + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + + break; + } + + /* djhjr - 9/10/99 */ + { + TwmDoor *d; + + if (XFindContext(dpy, tmp_win->w, DoorContext, + (caddr_t *) &d) != XCNOENT) + { + /* for some reason, we don't get the button up event - djhjr - 9/10/99 */ + ButtonPressed = -1; + door_delete(tmp_win->w, d); + + break; + } + } + + if (tmp_win->iconmgr) /* don't send ourself a message */ + { + /* added this 'if (...) ...' and 'if (...) else ...' - djhjr - 9/21/99 */ + if (have_showlist == -1) + have_showlist = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWLIST); + if (FindMenuOrFuncInWindows(tmp_win, have_showlist, NULL, F_SHOWLIST)) + + /* added argument - djhjr - 9/21/99 */ + HideIconManager(tmp_win); + + else + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + } + else if (tmp_win->protocols & DoesWmDeleteWindow) + { + /* djhjr - 4/26/99 */ + AppletDown(tmp_win); + + SendDeleteWindowMessage (tmp_win, LastTimestamp()); + } + else + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + break; + + case F_SAVEYOURSELF: + if (DeferExecution (context, func, Scr->SelectCursor)) + return TRUE; + + if (tmp_win->protocols & DoesWmSaveYourself) + SendSaveYourselfMessage (tmp_win, LastTimestamp()); + else + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + break; + + case F_CIRCLEUP: + XCirculateSubwindowsUp(dpy, Scr->Root); + break; + + case F_CIRCLEDOWN: + XCirculateSubwindowsDown(dpy, Scr->Root); + break; + + case F_EXEC: + PopDownMenu(); + if (!Scr->NoGrabServer) { + XUngrabServer (dpy); + XSync (dpy, 0); + } + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + /* flag for the handler */ + if (PlaySound(func)) createSoundFromFunction = TRUE; +#endif + + Execute(action); + break; + + case F_UNFOCUS: + FocusOnRoot(); + break; + + case F_CUT: + strcpy(tmp, action); + strcat(tmp, "\n"); + XStoreBytes(dpy, tmp, strlen(tmp)); + break; + + case F_CUTFILE: + ptr = XFetchBytes(dpy, &count); + if (ptr) { + if (sscanf (ptr, "%s", tmp) == 1) { + XFree (ptr); + ptr = ExpandFilename(tmp); + if (ptr) { + fd = open (ptr, 0); + if (fd >= 0) { + count = read (fd, buff, MAX_FILE_SIZE - 1); + if (count > 0) XStoreBytes (dpy, buff, count); + close(fd); + } else { + fprintf (stderr, + "%s: unable to open cut file \"%s\"\n", + ProgramName, tmp); + } + if (ptr != tmp) free (ptr); + } + } else { + XFree(ptr); + } + } else { + fprintf(stderr, "%s: cut buffer is empty\n", ProgramName); + } + break; + + case F_WARPTOSCREEN: + { + if (strcmp (action, WARPSCREEN_NEXT) == 0) { + WarpToScreen (Scr->screen + 1, 1); + } else if (strcmp (action, WARPSCREEN_PREV) == 0) { + WarpToScreen (Scr->screen - 1, -1); + } else if (strcmp (action, WARPSCREEN_BACK) == 0) { + WarpToScreen (PreviousScreen, 0); + } else { + WarpToScreen (atoi (action), 0); + } + } + break; + + case F_COLORMAP: + { + if (strcmp (action, COLORMAP_NEXT) == 0) { + BumpWindowColormap (tmp_win, 1); + } else if (strcmp (action, COLORMAP_PREV) == 0) { + BumpWindowColormap (tmp_win, -1); + } else { + BumpWindowColormap (tmp_win, 0); + } + } + break; + + case F_WARPCLASSNEXT: /* PF */ + case F_WARPCLASSPREV: /* PF */ + WarpClass(func == F_WARPCLASSNEXT, tmp_win, action); + break; + + case F_WARPTONEWEST: /* PF */ + /* added '&& warp_if_warpunmapped()' - djhjr - 5/13/98 */ + /* added the second argument - djhjr - 5/28/00 */ + if (Scr->Newest && warp_if_warpunmapped(Scr->Newest, F_NOFUNCTION)) + { + RaiseStickyAbove(); + RaiseAutoPan(); + +/* djhjr - 6/3/03 */ +#ifndef NO_SOUND_SUPPORT + PlaySound(func); +#endif + + WarpToWindow(Scr->Newest); + } + else + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + break; + + case F_WARPTO: + { + register TwmWindow *t; + /* djhjr - 6/3/03 */ + int did_warpto = FALSE; + + for (t = Scr->TwmRoot.next; t != NULL; t = t->next) + { + /* + * This used to fall through into F_WARP, but the + * warp_if_warpunmapped() meant this loop couldn't + * continue to look for a match in the window list. + * djhjr - 10/27/02 + */ + + /* jason@tfs.com */ + if (MatchWinName(action, t) == 0 && + warp_if_warpunmapped(t, func)) + { + tmp_win = t; /* PF */ + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + + /* djhjr - 6/3/03 */ +#ifndef NO_SOUND_SUPPORT + PlaySound(func); +#endif + did_warpto = TRUE; + + WarpToWindow(tmp_win); /* PF */ + break; + } + } + + /* djhjr - 6/3/03 */ + if (!did_warpto) + DoAudible(); + } + break; + + case F_WARP: /* PF */ + { /* PF */ + /* added '&& warp_if_warpunmapped()' - djhjr - 5/13/98 */ + /* added the second argument - djhjr - 5/28/00 */ + if (tmp_win && warp_if_warpunmapped(tmp_win, F_NOFUNCTION)) /* PF */ + { + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + +/* djhjr - 6/3/03 */ +#ifndef NO_SOUND_SUPPORT + PlaySound(func); +#endif + + WarpToWindow(tmp_win); /* PF */ + } else { + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + } + } /* PF */ + break; + + case F_WARPTOICONMGR: + { + TwmWindow *t; + int len; + +/* djhjr - 5/13/98 + Window raisewin = None, iconwin = None; +*/ +/* + * raisewin now points to the window's icon manager entry, and + * iconwin now points to raisewin's icon manager - djhjr - 5/30/00 + * + TwmWindow *raisewin = None; + Window iconwin = None; +*/ + WList *raisewin = NULL; + TwmWindow *iconwin = None; + + len = strlen(action); + if (len == 0) { + if (tmp_win && tmp_win->list) { +/* djhjr - 5/13/98 + raisewin = tmp_win->list->iconmgr->twm_win->frame; +*/ +/* djhjr - 5/30/00 + raisewin = tmp_win->list->iconmgr->twm_win; + iconwin = tmp_win->list->icon; +*/ + raisewin = tmp_win->list; + } else if (Scr->iconmgr.active) { +/* djhjr - 5/13/98 + raisewin = Scr->iconmgr.twm_win->frame; +*/ +/* djhjr - 5/30/00 + raisewin = Scr->iconmgr.twm_win; + iconwin = Scr->iconmgr.active->w; +*/ + raisewin = Scr->iconmgr.active; + } + } else { + for (t = Scr->TwmRoot.next; t != NULL; t = t->next) { + if (strncmp (action, t->icon_name, len) == 0) { + if (t->list && t->list->iconmgr->twm_win->mapped) { + +/* djhjr - 5/13/98 + raisewin = t->list->iconmgr->twm_win->frame; +*/ +/* djhjr - 5/30/00 + raisewin = t->list->iconmgr->twm_win; + iconwin = t->list->icon; +*/ + raisewin = t->list; + break; + } + } + } + } + + /* djhjr - 6/14/00 */ + if (!raisewin) + { + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + break; + } + + /* djhjr - 5/30/00 */ + iconwin = raisewin->iconmgr->twm_win; + + /* added '&& warp_if_warpunmapped()' - djhjr - 5/13/98 */ + /* added the second argument - djhjr - 5/28/00 */ + /* was 'raisewin' - djhjr - 5/30/00 */ + if (iconwin && warp_if_warpunmapped(iconwin, F_NOFUNCTION)) { +/* djhjr - 6/3/03 */ +#ifndef NO_SOUND_SUPPORT + PlaySound(func); +#endif + +/* djhjr - 5/30/00 + XWarpPointer (dpy, None, iconwin, 0, 0, 0, 0, + EDGE_OFFSET, EDGE_OFFSET); * DSE * +*/ + WarpInIconMgr(raisewin, iconwin); + } else { + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + } + } + break; + + case F_SQUEEZELEFT:/*RFB*/ + { + static SqueezeInfo left_squeeze = { J_LEFT, 0, 0 }; + + /* too much dup'd code - djhjr - 9/17/02 */ + if (do_squeezetitle(context, func, tmp_win, &left_squeeze)) + return TRUE; /* deferred */ + } + break; + + case F_SQUEEZERIGHT:/*RFB*/ + { + static SqueezeInfo right_squeeze = { J_RIGHT, 0, 0 }; + + /* too much dup'd code - djhjr - 9/17/02 */ + if (do_squeezetitle(context, func, tmp_win, &right_squeeze)) + return TRUE; /* deferred */ + } + break; + + case F_SQUEEZECENTER:/*RFB*/ + { + static SqueezeInfo center_squeeze = { J_CENTER, 0, 0 }; + + /* too much dup'd code - djhjr - 9/17/02 */ + if (do_squeezetitle(context, func, tmp_win, ¢er_squeeze)) + return TRUE; /* deferred */ + } + break; + + case F_RING:/*RFB*/ + if (DeferExecution (context, func, Scr->SelectCursor)) + return TRUE; + if ( tmp_win->ring.next || tmp_win->ring.prev ) + RemoveWindowFromRing(tmp_win); + else + AddWindowToRing(tmp_win); +#ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */ + tmp_win->ring.cursor_valid = False; +#endif + break; + + case F_WARPRING: + switch (action[0]) { + case 'n': + WarpAlongRing (&eventp->xbutton, True); + break; + case 'p': + WarpAlongRing (&eventp->xbutton, False); + break; + default: + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + break; + } + break; + + case F_FILE: + action = ExpandFilename(action); + fd = open(action, 0); + if (fd >= 0) + { + count = read(fd, buff, MAX_FILE_SIZE - 1); + if (count > 0) + XStoreBytes(dpy, buff, count); + + close(fd); + } + else + { + fprintf (stderr, "%s: unable to open file \"%s\"\n", + ProgramName, action); + } + break; + + case F_REFRESH: + { + XSetWindowAttributes attributes; + unsigned long valuemask; + + valuemask = (CWBackPixel | CWBackingStore | CWSaveUnder); + attributes.background_pixel = Scr->Black; + attributes.backing_store = NotUseful; + attributes.save_under = False; + w = XCreateWindow (dpy, Scr->Root, 0, 0, + (unsigned int) Scr->MyDisplayWidth, + (unsigned int) Scr->MyDisplayHeight, + (unsigned int) 0, + CopyFromParent, (unsigned int) CopyFromParent, + (Visual *) CopyFromParent, valuemask, + &attributes); + XMapWindow (dpy, w); + XDestroyWindow (dpy, w); + XFlush (dpy); + } + break; + + case F_WINREFRESH: + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + + if (context == C_ICON && tmp_win->icon_w) + w = XCreateSimpleWindow(dpy, tmp_win->icon_w, + 0, 0, 9999, 9999, 0, Scr->Black, Scr->Black); + else + w = XCreateSimpleWindow(dpy, tmp_win->frame, + 0, 0, 9999, 9999, 0, Scr->Black, Scr->Black); + + XMapWindow(dpy, w); + XDestroyWindow(dpy, w); + XFlush(dpy); + break; + + case F_NAIL: + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + + tmp_win->nailed = !tmp_win->nailed; + /* update the vd display */ + /* UpdateDesktop(tmp_win); Stig */ + NailDesktop(tmp_win); /* Stig */ + +#ifdef DEBUG + fprintf(stdout, "%s: nail state of %s is now %s\n", + ProgramName, tmp_win->name, (tmp_win->nailed ? "nailed" : "free")); +#endif /* DEBUG */ + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); /* DSE */ + + break; + + /* + * move a percentage in a particular direction + */ + case F_PANDOWN: + PanRealScreen(0, (atoi(action) * Scr->MyDisplayHeight) / 100 + /* DSE */ ,NULL,NULL); + break; + case F_PANLEFT: + PanRealScreen(-((atoi(action) * Scr->MyDisplayWidth) / 100), 0 + /* DSE */ ,NULL,NULL); + break; + case F_PANRIGHT: + PanRealScreen((atoi(action) * Scr->MyDisplayWidth) / 100, 0 + /* DSE */ ,NULL,NULL); + break; + case F_PANUP: + PanRealScreen(0, -((atoi(action) * Scr->MyDisplayHeight) / 100) + /* DSE */ ,NULL,NULL); + break; + + case F_RESETDESKTOP: + SetRealScreen(0, 0); + break; + +/*SNUG*/ /* Robert Forsman added these two functions */ +/*SNUG*/ { +/*SNUG*/ TwmWindow *scan; +/*SNUG*/ int right, left, up, down; +/*SNUG*/ int inited; +/*SNUG*/ case F_SNUGDESKTOP: +/*SNUG*/ +/*SNUG*/ inited = 0; +/*SNUG*/ for (scan = Scr->TwmRoot.next; scan!=NULL; scan = scan->next) +/*SNUG*/ { +/*SNUG*/ if (scan->nailed) +/*SNUG*/ continue; +/*SNUG*/ if (scan->frame_x > Scr->MyDisplayWidth || +/*SNUG*/ scan->frame_y > Scr->MyDisplayHeight) +/*SNUG*/ continue; +/*SNUG*/ if (scan->frame_x+scan->frame_width < 0 || +/*SNUG*/ scan->frame_y+scan->frame_height < 0) +/*SNUG*/ continue; +/*SNUG*/ if ( inited==0 || scan->frame_xframe_x; +/*SNUG*/ if ( inited==0 || scan->frame_yframe_y; +/*SNUG*/ if ( inited==0 || scan->frame_x+scan->frame_width>left ) +/*SNUG*/ left = scan->frame_x+scan->frame_width; +/*SNUG*/ if ( inited==0 || scan->frame_y+scan->frame_height>down ) +/*SNUG*/ down = scan->frame_y+scan->frame_height; +/*SNUG*/ inited = 1; +/*SNUG*/ } +/*SNUG*/ if (inited) +/*SNUG*/ { +/*SNUG*/ int dx,dy; +/*SNUG*/ if (left-right < Scr->MyDisplayWidth && (right<0 || left>Scr->MyDisplayWidth) ) +/*SNUG*/ dx = right - ( Scr->MyDisplayWidth - (left-right) ) /2; +/*SNUG*/ else +/*SNUG*/ dx = 0; +/*SNUG*/ if (down-up < Scr->MyDisplayHeight && (up<0 || down>Scr->MyDisplayHeight) ) +/*SNUG*/ dy = up - (Scr->MyDisplayHeight - (down-up) ) /2; +/*SNUG*/ else +/*SNUG*/ dy = 0; +/*SNUG*/ if (dx!=0 || dy!=0) +/*SNUG*/ PanRealScreen(dx,dy,NULL,NULL); +/*SNUG*/ /* DSE */ +/*SNUG*/ else +/*SNUG*/ DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ +/*SNUG*/ } +/*SNUG*/ else +/*SNUG*/ DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ +/*SNUG*/ break; +/*SNUG*/ +/*SNUG*/ case F_SNUGWINDOW: +/*SNUG*/ if (DeferExecution(context, func, Scr->SelectCursor)) +/*SNUG*/ return TRUE; +/*SNUG*/ +/*SNUG*/ inited = 0; +/*SNUG*/ right = tmp_win->frame_x; +/*SNUG*/ left = tmp_win->frame_x + tmp_win->frame_width; +/*SNUG*/ up = tmp_win->frame_y; +/*SNUG*/ down = tmp_win->frame_y + tmp_win->frame_height; +/*SNUG*/ inited = 1; +/*SNUG*/ if (inited) +/*SNUG*/ { +/*SNUG*/ int dx,dy; +/*SNUG*/ dx = 0; +/*SNUG*/ if (left-right < Scr->MyDisplayWidth) +/*SNUG*/ { +/*SNUG*/ if (right<0) +/*SNUG*/ dx = right; +/*SNUG*/ else if (left>Scr->MyDisplayWidth) +/*SNUG*/ dx = left - Scr->MyDisplayWidth; +/*SNUG*/ } +/*SNUG*/ +/*SNUG*/ dy = 0; +/*SNUG*/ if (down-up < Scr->MyDisplayHeight) +/*SNUG*/ { +/*SNUG*/ if (up<0) +/*SNUG*/ dy = up; +/*SNUG*/ else if (down>Scr->MyDisplayHeight) +/*SNUG*/ dy = down - Scr->MyDisplayHeight; +/*SNUG*/ } +/*SNUG*/ +/*SNUG*/ if (dx!=0 || dy!=0) +/*SNUG*/ PanRealScreen(dx,dy,NULL,NULL); +/*SNUG*/ /* DSE */ +/*SNUG*/ else +/*SNUG*/ DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ +/*SNUG*/ } +/*SNUG*/ else +/*SNUG*/ DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ +/*SNUG*/ +/*SNUG*/ break; +/*SNUG*/ } + + /* Next four submitted by Seth Robertson - 9/9/02 */ + case F_BINDBUTTONS: + { + int i, j; + + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + for (i = 0; i < MAX_BUTTONS+1; i++) + for (j = 0; j < MOD_SIZE; j++) + if (Scr->Mouse[i][C_WINDOW][j].func != F_NOFUNCTION) + XGrabButton(dpy, i, j, tmp_win->frame, + True, ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, None, + Scr->FrameCursor); + break; + } + case F_BINDKEYS: + { + FuncKey *tmp; + + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next) + if (tmp->cont == C_WINDOW) +/* djhjr - 9/10/03 + XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->w, True, + GrabModeAsync, GrabModeAsync); +*/ + GrabModKeys(tmp_win->w, tmp); + break; + } + case F_UNBINDBUTTONS: + { + int i, j; + + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + for (i = 0; i < MAX_BUTTONS+1; i++) + for (j = 0; j < MOD_SIZE; j++) + if (Scr->Mouse[i][C_WINDOW][j].func != F_NOFUNCTION) + XUngrabButton(dpy, i, j, tmp_win->frame); + break; + } + case F_UNBINDKEYS: + { + FuncKey *tmp; + + if (DeferExecution(context, func, Scr->SelectCursor)) + return TRUE; + for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next) + if (tmp->cont == C_WINDOW) +/* djhjr - 9/10/03 + XUngrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->w); +*/ + UngrabModKeys(tmp_win->w, tmp); + break; + } + + case F_MOVESCREEN: + + /* + * Breaks badly if not called by the default button press. + */ + + { + long releaseEvent = ButtonRelease; + long movementMask = ButtonMotionMask; +#ifndef NO_SOUND_SUPPORT + int did_playsound = FALSE; +#endif + + StartMoveWindowInDesktop(eventp->xmotion); + + while (TRUE) + { + /* added exposure event masks - djhjr - 10/11/01 */ + XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask | + ExposureMask | VisibilityChangeMask | + movementMask, &Event); + + /* + * Don't discard exposure events before release + * or window borders and/or their titles in the + * virtual desktop won't get redrawn - djhjr + */ + + /* discard any extra motion events before a release */ + if (Event.type == MotionNotify) + { + /* was 'ButtonMotionMask' - djhjr - 10/11/01 */ + while (XCheckMaskEvent(dpy, releaseEvent | movementMask, + &Event)) + { + if (Event.type == releaseEvent) + break; + } + } + + if (Event.type == releaseEvent) + { + EndMoveWindowOnDesktop(); + break; + } + + if (!DispatchEvent()) continue; + + if (Event.type != MotionNotify) continue; + +#ifndef NO_SOUND_SUPPORT + if (did_playsound == FALSE) + { + PlaySound(func); + did_playsound = TRUE; + } +#endif + + DoMoveWindowOnDesktop(Event.xmotion.x, Event.xmotion.y); + } + + /* discard queued enter and leave events */ + while (XCheckMaskEvent(dpy, EnterWindowMask | LeaveWindowMask, + &Event)) + ; + + /* will clear the XGrabPointer() in events.c:HandleButtonPress() */ + ButtonPressed = -1; + + break; + } + + case F_SNAP: + SnapRealScreen(); + /* and update the data structures */ + SetRealScreen(Scr->VirtualDesktopX, Scr->VirtualDesktopY); + break; + + case F_SNAPREALSCREEN: + Scr->snapRealScreen = ! Scr->snapRealScreen; + break; + + /* djhjr - 12/14/98 */ + case F_STATICICONPOSITIONS: + Scr->StaticIconPositions = ! Scr->StaticIconPositions; + break; + + /* djhjr - 12/14/98 */ + case F_STRICTICONMGR: + { + TwmWindow *t; + + Scr->StrictIconManager = ! Scr->StrictIconManager; + if (Scr->StrictIconManager) + { + for (t = Scr->TwmRoot.next; t != NULL; t = t->next) + if (!t->icon) + RemoveIconManager(t); + } + else + { + for (t = Scr->TwmRoot.next; t != NULL; t = t->next) + if (!t->list) + AddIconManager(t); + } + + break; + } + + case F_SETREALSCREEN: + { + int newx = Scr->VirtualDesktopX; + int newy = Scr->VirtualDesktopY; + + /* parse the geometry */ + JunkMask = XParseGeometry (action, &JunkX, &JunkY, &JunkWidth, &JunkHeight); + + if (JunkMask & XValue) + newx = JunkX; + if (JunkMask & YValue) + newy = JunkY; + + if (newx < 0) + newx = Scr->VirtualDesktopWidth + newx; + if (newy < 0) + newy = Scr->VirtualDesktopHeight + newy; + + SetRealScreen(newx, newy); + + break; + } + + case F_HIDEDESKTOP: + if (Scr->Virtual) + XUnmapWindow(dpy, Scr->VirtualDesktopDisplayTwin->frame); + break; + + case F_SHOWDESKTOP: + if (Scr->Virtual) { + XMapWindow(dpy, Scr->VirtualDesktopDisplayTwin->frame); + + /* djhjr - 9/14/96 */ + if (Scr->VirtualDesktopDisplayTwin->icon) + DeIconify(Scr->VirtualDesktopDisplayTwin); + } + break; + + case F_ENTERDOOR: + { + TwmDoor *d; + + if (XFindContext(dpy, tmp_win->w, DoorContext, + (caddr_t *) &d) != XCNOENT) + door_enter(tmp_win->w, d); + break; + } + + case F_DELETEDOOR: + { /*marcel@duteca.et.tudelft.nl*/ + TwmDoor *d; + + if (DeferExecution(context, func, Scr->DestroyCursor)) + return TRUE; + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + /* flag for the handler */ + if (PlaySound(func)) destroySoundFromFunction = TRUE; +#endif + + if (XFindContext(dpy, tmp_win->w, DoorContext, + (caddr_t *) &d) != XCNOENT) + { + /* for some reason, we don't get the button up event - djhjr - 5/13/99 */ + ButtonPressed = -1; + + door_delete(tmp_win->w, d); + } + break; + } + + case F_NEWDOOR: + PopDownMenu(); + door_new(); + break; + + /* djhjr - 4/20/98 */ + case F_NAMEDOOR: + { + TwmDoor *d; + + if (XFindContext(dpy, tmp_win->w, DoorContext, + (caddr_t *) &d) != XCNOENT) + door_paste_name(tmp_win->w, d); + break; + } + + case F_QUIT: +/* djhjr - 9/14/96 - it's in Done()... + SetRealScreen(0,0); +*/ + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + if (PlaySound(func)) + { + /* allow time to emit */ + if (Scr->PauseOnQuit) sleep(Scr->PauseOnQuit); + } + else + PlaySoundDone(); +#endif + + Done(); + break; + + case F_VIRTUALGEOMETRIES: + Scr->GeometriesAreVirtual = ! Scr->GeometriesAreVirtual; + break; + + /* submitted by Ugen Antsilevitch - 5/28/00 */ + case F_WARPVISIBLE: + Scr->WarpVisible = ! Scr->WarpVisible; + break; + + /* djhjr - 5/30/00 */ + case F_WARPSNUG: + Scr->WarpSnug = ! Scr->WarpSnug; + break; + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + case F_SOUNDS: + ToggleSounds(); + break; + + /* djhjr - 11/15/02 */ + case F_PLAYSOUND: + PlaySoundAdhoc(action); + break; +#endif + } + + if (ButtonPressed == -1) XUngrabPointer(dpy, CurrentTime); + return do_next_action; +} + + + +/*********************************************************************** + * + * Procedure: + * DeferExecution - defer the execution of a function to the + * next button press if the context is C_ROOT + * + * Inputs: + * context - the context in which the mouse button was pressed + * func - the function to defer + * cursor - the cursor to display while waiting + * + *********************************************************************** + */ + +int +DeferExecution(context, func, cursor) +int context, func; +Cursor cursor; +{ + if (context == C_ROOT) + { + LastCursor = cursor; + XGrabPointer(dpy, Scr->Root, True, + ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, + Scr->Root, cursor, CurrentTime); + + RootFunction = func; + Action = actionHack; /* Submitted by Michel Eyckmans */ + + return (TRUE); + } + + return (FALSE); +} + + + +/*********************************************************************** + * + * Procedure: + * ReGrab - regrab the pointer with the LastCursor; + * + *********************************************************************** + */ + +void ReGrab() +{ + XGrabPointer(dpy, Scr->Root, True, + ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, + Scr->Root, LastCursor, CurrentTime); +} + + + +/*********************************************************************** + * + * Procedure: + * NeedToDefer - checks each function in the list to see if it + * is one that needs to be defered. + * + * Inputs: + * root - the menu root to check + * + *********************************************************************** + */ + +/* was of type 'int' - Submitted by Michel Eyckmans */ +Cursor +NeedToDefer(root) +MenuRoot *root; +{ + MenuItem *mitem; + + for (mitem = root->first; mitem != NULL; mitem = mitem->next) + { + switch (mitem->func) + { + case F_RESIZE: + return Scr->ResizeCursor; /* Submitted by Michel Eyckmans */ + case F_MOVE: + case F_FORCEMOVE: + return Scr->MoveCursor; /* Submitted by Michel Eyckmans */ + /* these next four - Submitted by Michel Eyckmans */ + case F_DELETE: + case F_DELETEDOOR: + case F_DESTROY: + return Scr->DestroyCursor; + case F_IDENTIFY: /* was with 'F_RESIZE' - Submitted by Michel Eyckmans */ + case F_DEICONIFY: + case F_ICONIFY: + case F_RAISELOWER: + case F_RAISE: + case F_LOWER: + case F_FOCUS: + case F_WINREFRESH: + case F_ZOOM: + case F_FULLZOOM: + case F_HORIZOOM: + case F_RIGHTZOOM: + case F_LEFTZOOM: + case F_TOPZOOM: + case F_BOTTOMZOOM: + case F_AUTORAISE: + case F_NAIL: + case F_SNUGWINDOW: + return Scr->SelectCursor; + } + } + return None; +} + + + +void +Execute(s) + char *s; +{ + static char buf[256]; + char *ds = DisplayString (dpy); + char *colon, *dot1; + char oldDisplay[256]; + char *doisplay; + int restorevar = 0; + + char *append_this = " &"; + char *es = (char *)malloc(strlen(s)+strlen(append_this)+1); + sprintf(es,s); + /* a new copy of s, with extra space incase -- DSE */ + + if (Scr->EnhancedExecResources) /* DSE */ + { + /* chop all space characters from the end of the string */ + while ( isspace ( es[strlen(es)-1] ) ) + { + es[strlen(es)-1] = '\0'; + } + switch ( es[strlen(es)-1] ) /* last character */ + { + case ';': + es[strlen(es)-1] = '\0'; /* remove the semicolon */ + break; + case '&': /* already there so do nothing */ + break; + default: + strcat(es,append_this); /* don't block the window manager */ + break; + } + } + + oldDisplay[0] = '\0'; + doisplay=getenv("DISPLAY"); + if (doisplay) + strcpy (oldDisplay, doisplay); + + /* + * Build a display string using the current screen number, so that + * X programs which get fired up from a menu come up on the screen + * that they were invoked from, unless specifically overridden on + * their command line. + */ + colon = rindex (ds, ':'); + if (colon) { /* if host[:]:dpy */ + strcpy (buf, "DISPLAY="); + strcat (buf, ds); + colon = buf + 8 + (colon - ds); /* use version in buf */ + dot1 = index (colon, '.'); /* first period after colon */ + if (!dot1) dot1 = colon + strlen (colon); /* if not there, append */ + (void) sprintf (dot1, ".%d", Scr->screen); + putenv (buf); + restorevar = 1; + } + + (void) system (es); /* DSE */ + free (es); /* DSE */ + + if (restorevar) { /* why bother? */ + (void) sprintf (buf, "DISPLAY=%s", oldDisplay); + putenv (buf); + } +} + + + +/*********************************************************************** + * + * Procedure: + * FocusOnRoot - put input focus on the root window + * + *********************************************************************** + */ + +void +FocusOnRoot() +{ + SetFocus ((TwmWindow *) NULL, LastTimestamp()); + if (Scr->Focus != NULL) + { + SetBorder (Scr->Focus, False); + +/* djhjr - 4/25/96 + if (Scr->Focus->hilite_w) XUnmapWindow (dpy, Scr->Focus->hilite_w); +*/ + PaintTitleHighlight(Scr->Focus, off); + + } + InstallWindowColormaps(0, &Scr->TwmRoot); + Scr->Focus = NULL; + Scr->FocusRoot = TRUE; +} + +void DeIconify(tmp_win) +TwmWindow *tmp_win; +{ + TwmWindow *t; + + /* + * De-iconify the main window first + */ + + /* re-vamped the zoom stuff - djhjr - 10/11/01 */ + if (Scr->DoZoom && Scr->ZoomCount > 0) + { + IconMgr *ipf = NULL; + Window wt = None, wf = None; + + if (tmp_win->icon) + { + if (tmp_win->icon_on) + { + wf = tmp_win->icon_w; wt = tmp_win->frame; + } + else if (tmp_win->list) /* djhjr - 10/11/01 */ + { + wf = tmp_win->list->w; wt = tmp_win->frame; + ipf = tmp_win->list->iconmgr; + } + else if (tmp_win->group != None) + { + for (t = Scr->TwmRoot.next; t != NULL; t = t->next) + if (tmp_win->group == t->w) + { + if (t->icon_on) + wf = t->icon_w; + else if (t->list) /* djhjr - 10/11/01 */ + { + wf = t->list->w; + ipf = t->list->iconmgr; + } + + wt = tmp_win->frame; + break; + } + } + } + + /* added Zoom()s args to iconmgrs - djhjr - 10/11/01 */ + if (Scr->ZoomZoom || (wf != None && wt != None)) + Zoom(wf, ipf, wt, NULL); /* RFBZOOM */ + } + + XMapWindow(dpy, tmp_win->w); + tmp_win->mapped = TRUE; + + if (Scr->NoRaiseDeicon) + XMapWindow(dpy, tmp_win->frame); + else + { + XMapRaised(dpy, tmp_win->frame); + XRaiseWindow(dpy, tmp_win->VirtualDesktopDisplayWindow); + } + SetMapStateProp(tmp_win, NormalState); + + if (tmp_win->icon_w) { + XUnmapWindow(dpy, tmp_win->icon_w); + IconDown (tmp_win); + } + + tmp_win->icon = FALSE; + tmp_win->icon_on = FALSE; + + if (tmp_win->list) + XUnmapWindow(dpy, tmp_win->list->icon); + + /* + * RemoveIconManager() done in events.c:HandleMapNotify() + */ + + UpdateDesktop(tmp_win); + + /* + * Now de-iconify transients + */ + + for (t = Scr->TwmRoot.next; t != NULL; t = t->next) + { + if (t->transient && t->transientfor == tmp_win->w) + { + /* this 'if (...) else' (see also Iconify()) - djhjr - 6/22/99 */ + if (Scr->DontDeiconifyTransients && t->icon_w && + t->icon == TRUE && t->icon_on == FALSE) + { + IconUp(t); + XMapRaised(dpy, t->icon_w); + t->icon_on = TRUE; + } + else + { + /* added Zoom()s args to iconmgrs - djhjr - 10/11/01 */ + if (t->icon_on) + Zoom(t->icon_w, NULL, t->frame, NULL); + else + Zoom(tmp_win->icon_w, NULL, t->frame, NULL); + + XMapWindow(dpy, t->w); + t->mapped = TRUE; + + if (Scr->NoRaiseDeicon) + XMapWindow(dpy, t->frame); + else + { + XMapRaised(dpy, t->frame); + XRaiseWindow(dpy, t->VirtualDesktopDisplayWindow); + } + SetMapStateProp(t, NormalState); + + if (t->icon_w) + { + XUnmapWindow(dpy, t->icon_w); + IconDown (t); + } + + t->icon = FALSE; + t->icon_on = FALSE; + + if (t->list) XUnmapWindow(dpy, t->list->icon); + + /* + * RemoveIconManager() done in events.c:HandleMapNotify() + */ + + UpdateDesktop(t); + } + } + } + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + + /* + * added '&& Scr->WarpWindows'. + * see the kludge in ExecuteFunction(F_ICONIFY, ...). + * djhjr - 1/24/98 + */ + if (((Scr->WarpCursor || + LookInList(Scr->WarpCursorL, tmp_win->full_name, + &tmp_win->class)) && + tmp_win->icon) && Scr->WarpWindows) + WarpToWindow (tmp_win); + + XSync (dpy, 0); +} + + + +void Iconify(tmp_win, def_x, def_y) +TwmWindow *tmp_win; +int def_x, def_y; +{ + TwmWindow *t; + int iconify; + XWindowAttributes winattrs; + unsigned long eventMask; + /* djhjr - 6/22/99 */ + short fake_icon; + + iconify = ((!tmp_win->iconify_by_unmapping) || tmp_win->transient); + if (iconify) + { + if (tmp_win->icon_w == None) + CreateIconWindow(tmp_win, def_x, def_y); + else + IconUp(tmp_win); + + XMapRaised(dpy, tmp_win->icon_w); + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + } + + XGetWindowAttributes(dpy, tmp_win->w, &winattrs); + eventMask = winattrs.your_event_mask; + + /* + * Iconify transients first + */ + + for (t = Scr->TwmRoot.next; t != NULL; t = t->next) + { + if (t->transient && t->transientfor == tmp_win->w) + { + + /* RemoveFromDesktop(t); Stig */ + + /* + * Prevent the receipt of an UnmapNotify, since that would + * cause a transition to the Withdrawn state. + */ + t->mapped = FALSE; + XSelectInput(dpy, t->w, eventMask & ~StructureNotifyMask); + XUnmapWindow(dpy, t->w); + XSelectInput(dpy, t->w, eventMask); + XUnmapWindow(dpy, t->frame); + + /* moved to make zooms more aesthetically pleasing -- DSE */ + if (iconify) + { + /* added Zoom()s args to iconmgrs - djhjr - 10/11/01 */ + if (t->icon_on) + Zoom(t->icon_w, NULL, tmp_win->icon_w, NULL); + else + Zoom(t->frame, NULL, tmp_win->icon_w, NULL); + } + + if (t->icon_w) + XUnmapWindow(dpy, t->icon_w); + SetMapStateProp(t, IconicState); + SetBorder (t, False); + if (t == Scr->Focus) + { + SetFocus ((TwmWindow *) NULL, LastTimestamp()); + Scr->Focus = NULL; + Scr->FocusRoot = TRUE; + } + + /* + * let current status ride, but "fake out" UpdateDesktop() + * (see also DeIconify()) - djhjr - 6/22/99 + */ + fake_icon = t->icon; + + t->icon = TRUE; + t->icon_on = FALSE; + + /* djhjr - 10/2/01 */ + if (Scr->StrictIconManager) + if (!t->list) + AddIconManager(t); + + if (t->list) XMapWindow(dpy, t->list->icon); + + UpdateDesktop(t); + + /* restore icon status - djhjr - 6/22/99 */ + t->icon = fake_icon; + } + } + + /* + * Now iconify the main window + */ + +/* if (iconify) RFBZOOM*/ + + /* RemoveFromDesktop(tmp_win); Stig */ + + /* + * Prevent the receipt of an UnmapNotify, since that would + * cause a transition to the Withdrawn state. + */ + tmp_win->mapped = FALSE; + XSelectInput(dpy, tmp_win->w, eventMask & ~StructureNotifyMask); + XUnmapWindow(dpy, tmp_win->w); + XSelectInput(dpy, tmp_win->w, eventMask); + XUnmapWindow(dpy, tmp_win->frame); + + SetMapStateProp(tmp_win, IconicState); + + SetBorder (tmp_win, False); + if (tmp_win == Scr->Focus) + { + SetFocus ((TwmWindow *) NULL, LastTimestamp()); + Scr->Focus = NULL; + Scr->FocusRoot = TRUE; + } + + tmp_win->icon = TRUE; + if (iconify) + tmp_win->icon_on = TRUE; + else + tmp_win->icon_on = FALSE; + + /* djhjr - 10/2/01 */ + if (Scr->StrictIconManager) + if (!tmp_win->list) + AddIconManager(tmp_win); + + /* moved to make zooms more aesthetically pleasing -- DSE */ + /* moved again to ensure an icon manager entry exists - djhjr - 10/11/01 */ + /* added Zoom()s args to iconmgrs - djhjr - 10/11/01 */ + if (iconify) + Zoom(tmp_win->frame, NULL, tmp_win->icon_w, NULL); + else if (tmp_win->list) /* djhjr - 10/11/01 */ + Zoom(tmp_win->frame, NULL, tmp_win->list->w, tmp_win->list->iconmgr); + + if (tmp_win->list) + XMapWindow(dpy, tmp_win->list->icon); + + UpdateDesktop(tmp_win); + XSync (dpy, 0); +} + + + +static void Identify (t) +TwmWindow *t; +{ + int i, n, twidth, width, height; + int x, y; + unsigned int wwidth, wheight, bw, depth; + Window junk; + int px, py, dummy; + unsigned udummy; + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + PlaySound(F_IDENTIFY); +#endif + + n = 0; + (void) sprintf(Info[n++], "%s", Version); + Info[n++][0] = '\0'; + + if (t) { + XGetGeometry (dpy, t->w, &JunkRoot, &JunkX, &JunkY, + &wwidth, &wheight, &bw, &depth); + (void) XTranslateCoordinates (dpy, t->w, Scr->Root, 0, 0, + &x, &y, &junk); + +/* looks bad with variable fonts... djhjr - 5/10/96 + (void) sprintf(Info[n++], "Name = \"%s\"", t->full_name); + (void) sprintf(Info[n++], "Class.res_name = \"%s\"", t->class.res_name); + (void) sprintf(Info[n++], "Class.res_class = \"%s\"", t->class.res_class); + Info[n++][0] = '\0'; + (void) sprintf(Info[n++], "Geometry/root = %dx%d+%d+%d", wwidth, wheight, x, y); + (void) sprintf(Info[n++], "Border width = %d", bw); + (void) sprintf(Info[n++], "Depth = %d", depth); +*/ + (void) sprintf(Info[n++], "Name: \"%s\"", t->full_name); + (void) sprintf(Info[n++], "Class.res_name: \"%s\"", t->class.res_name); + (void) sprintf(Info[n++], "Class.res_class: \"%s\"", t->class.res_class); + Info[n++][0] = '\0'; + (void) sprintf(Info[n++], "Geometry/root: %dx%d+%d+%d", wwidth, wheight, x, y); + (void) sprintf(Info[n++], "Border width: %d", bw); + (void) sprintf(Info[n++], "Depth: %d", depth); + + Info[n++][0] = '\0'; + } +/* djhjr - 9/19/96 */ +#ifndef NO_BUILD_INFO + else + { + char is_m4, is_xpm; + char is_rplay; /* djhjr - 6/22/01 */ + char is_regex; /* djhjr - 10/20/01 */ + char is_i18n; /* djhjr - 10/20/01 */ + +/* djhjr - 6/22/99 */ +#ifdef WE_REALLY_DO_WANT_TO_SEE_THIS + (void) sprintf(Info[n++], "X Server: %s Version %d.%d Release %d", + ServerVendor(dpy), ProtocolVersion(dpy), ProtocolRevision(dpy), + VendorRelease(dpy)); +#endif + + /* + * Was a 'do ... while()' that accessed unallocated memory. + * This and the change to Imakefile submitted by Takeharu Kato + */ + i = 0; + while (lastmake[i][0] != '\0') + (void) sprintf(Info[n++], "%s", lastmake[i++]); + +/* djhjr - 1/31/99 */ +#ifdef NO_M4_SUPPORT + is_m4 = '-'; +#else + is_m4 = '+'; +#endif +#ifdef NO_XPM_SUPPORT + is_xpm = '-'; +#else + is_xpm = '+'; +#endif +/* djhjr - 6/22/01 */ +#ifdef NO_SOUND_SUPPORT + is_rplay = '-'; +#else + is_rplay = '+'; +#endif +/* djhjr - 6/22/01 */ +#ifdef NO_REGEX_SUPPORT + is_regex = '-'; +#else + is_regex = '+'; +#endif +/* djhjr - 9/14/03 */ +#ifdef NO_I18N_SUPPORT + is_i18n = '-'; +#else + is_i18n = '+'; +#endif + (void) sprintf(Info[n++], + "Options: %ci18n %cm4 %cregex %crplay %cxpm", + is_i18n, is_m4, is_regex, is_rplay, is_xpm); + + Info[n++][0] = '\0'; + } +#endif + + (void) sprintf(Info[n++], "Click to dismiss..."); + + /* figure out the width and height of the info window */ + +/* djhjr - 4/29/98 + height = (n * (Scr->InfoFont.height+2)) + 10; * some padding * +*/ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + i = (Scr->InfoBevelWidth > 0) ? Scr->InfoBevelWidth + 8 : 10; + height = (n * (Scr->InfoFont.height+2)) + i; /* some padding */ + + width = 1; + for (i = 0; i < n; i++) + { +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + twidth = MyFont_TextWidth(&Scr->InfoFont, +#else + twidth = XTextWidth(Scr->InfoFont.font, +#endif + Info[i], strlen(Info[i])); + if (twidth > width) + width = twidth; + } + if (InfoLines) XUnmapWindow(dpy, Scr->InfoWindow); + +/* djhjr - 4/29/98 + width += 20; * some padding * +*/ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + i = (Scr->InfoBevelWidth > 0) ? Scr->InfoBevelWidth + 18 : 20; + width += i; /* some padding */ + + if (XQueryPointer (dpy, Scr->Root, &JunkRoot, &JunkChild, &px, &py, + &dummy, &dummy, &udummy)) { + px -= (width / 2); + py -= (height / 3); + + /* added this 'if ()' - djhjr - 4/29/98 */ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (Scr->InfoBevelWidth > 0) + { + if (px + width + 2 * Scr->InfoBevelWidth >= Scr->MyDisplayWidth) + px = Scr->MyDisplayWidth - width - 2 * Scr->InfoBevelWidth; + if (py + height + 2 * Scr->InfoBevelWidth >= Scr->MyDisplayHeight) + py = Scr->MyDisplayHeight - height - 2 * Scr->InfoBevelWidth; + } + else + { + if (px + width + BW2 >= Scr->MyDisplayWidth) + px = Scr->MyDisplayWidth - width - BW2; + if (py + height + BW2 >= Scr->MyDisplayHeight) + py = Scr->MyDisplayHeight - height - BW2; + } + + if (px < 0) px = 0; + if (py < 0) py = 0; + } else { + px = py = 0; + } + + XMoveResizeWindow(dpy, Scr->InfoWindow, px, py, width, height); + +/* done in HandleExpose() in events.c - djhjr - 4/30/98 */ +#ifdef NEVER + /* djhjr - 5/9/96 */ + if (Scr->use3Dborders > 0) + { + XGetGeometry (dpy, Scr->InfoWindow, &JunkRoot, &JunkX, &JunkY, + &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth); + Draw3DBorder(Scr->InfoWindow, 0, 0, JunkWidth, JunkHeight, +/* djhjr - 4/29/98 + BW, Scr->DefaultC, off, False, False); +*/ + Scr->InfoBevelWidth, Scr->DefaultC, off, False, False); + } +#endif + + XMapRaised(dpy, Scr->InfoWindow); + InfoLines = n; +} + + + +void SetMapStateProp(tmp_win, state) +TwmWindow *tmp_win; +int state; +{ + unsigned long data[2]; /* "suggested" by ICCCM version 1 */ + + data[0] = (unsigned long) state; + data[1] = (unsigned long) (tmp_win->iconify_by_unmapping ? None : + tmp_win->icon_w); + + XChangeProperty (dpy, tmp_win->w, _XA_WM_STATE, _XA_WM_STATE, 32, + PropModeReplace, (unsigned char *) data, 2); +} + + + +Bool GetWMState (w, statep, iwp) + Window w; + int *statep; + Window *iwp; +{ + Atom actual_type; + int actual_format; + unsigned long nitems, bytesafter; + unsigned long *datap = NULL; + Bool retval = False; + + /* used to test for '!datap' - djhjr - 1/10/98 */ + if (XGetWindowProperty (dpy, w, _XA_WM_STATE, 0L, 2L, False, _XA_WM_STATE, + &actual_type, &actual_format, &nitems, &bytesafter, + (unsigned char **) &datap) != Success || + actual_type == None) + return False; + + if (nitems <= 2) { /* "suggested" by ICCCM version 1 */ + *statep = (int) datap[0]; + *iwp = (Window) datap[1]; + retval = True; + } + + XFree ((char *) datap); + return retval; +} + + + +/* + * BumpWindowColormap - rotate our internal copy of WM_COLORMAP_WINDOWS + */ + +void BumpWindowColormap (tmp, inc) + TwmWindow *tmp; + int inc; +{ + int i, j, previously_installed; + ColormapWindow **cwins; + + if (!tmp) return; + + if (inc && tmp->cmaps.number_cwins > 0) { + cwins = (ColormapWindow **) malloc(sizeof(ColormapWindow *)* + tmp->cmaps.number_cwins); + if (cwins) { + if ((previously_installed = + (Scr->cmapInfo.cmaps == &tmp->cmaps) && + tmp->cmaps.number_cwins)) { + for (i = tmp->cmaps.number_cwins; i-- > 0; ) + tmp->cmaps.cwins[i]->colormap->state = 0; + } + + for (i = 0; i < tmp->cmaps.number_cwins; i++) { + j = i - inc; + if (j >= tmp->cmaps.number_cwins) + j -= tmp->cmaps.number_cwins; + else if (j < 0) + j += tmp->cmaps.number_cwins; + cwins[j] = tmp->cmaps.cwins[i]; + } + + free((char *) tmp->cmaps.cwins); + + tmp->cmaps.cwins = cwins; + + if (tmp->cmaps.number_cwins > 1) + memset( tmp->cmaps.scoreboard, 0, + ColormapsScoreboardLength(&tmp->cmaps)); + + if (previously_installed) + InstallWindowColormaps(PropertyNotify, (TwmWindow *) NULL); + } + } else + FetchWmColormapWindows (tmp); +} + + + +void HideIconManager(tmp_win) +TwmWindow *tmp_win; +{ + /* added this 'if (...) else ...' - djhjr - 9/21/99 */ + if (tmp_win == NULL) + { + name_list *list; + + HideIconMgr(&Scr->iconmgr); + + /* + * New code in list.c necessitates 'next_entry()' and + * 'contents_of_entry()' - djhjr - 10/20/01 + */ + for (list = Scr->IconMgrs; list != NULL; list = next_entry(list)) + HideIconMgr((IconMgr *)contents_of_entry(list)); + } + else + { + IconMgr *ip; + + if ((ip = (IconMgr *)LookInList(Scr->IconMgrs, tmp_win->full_name, + &tmp_win->class)) == NULL) + ip = &Scr->iconmgr; + + HideIconMgr(ip); + } +} + +/* djhjr - 9/21/99 */ +void HideIconMgr(ip) +IconMgr *ip; +{ + /* djhjr - 6/10/98 */ + if (ip->count == 0) + return; + + SetMapStateProp (ip->twm_win, WithdrawnState); + XUnmapWindow(dpy, ip->twm_win->frame); + if (ip->twm_win->icon_w) + XUnmapWindow (dpy, ip->twm_win->icon_w); + ip->twm_win->mapped = FALSE; + ip->twm_win->icon = TRUE; +} + +/* djhjr - 9/21/99 */ +void ShowIconMgr(ip) +IconMgr *ip; +{ + /* added the second condition - djhjr - 6/10/98 */ + if (Scr->NoIconManagers || ip->count == 0) + return; + + DeIconify(ip->twm_win); + XRaiseWindow(dpy, ip->twm_win->frame); + XRaiseWindow(dpy, ip->twm_win->VirtualDesktopDisplayWindow); +} + + +void SetBorder (tmp, onoroff) +TwmWindow *tmp; +Bool onoroff; +{ + if (tmp->highlight) + { + /* djhjr - 4/22/96 */ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (Scr->BorderBevelWidth > 0) + PaintBorders (tmp, onoroff); + else + { + if (onoroff) + { +/* djhjr - 4/24/96 + XSetWindowBorder (dpy, tmp->frame, tmp->border); +*/ +/* djhjr - 11/17/97 + XSetWindowBorder (dpy, tmp->frame, tmp->border_tile.back); +*/ + XSetWindowBorder (dpy, tmp->frame, tmp->border.back); + + if (tmp->title_w) +/* djhjr - 4/24/96 + XSetWindowBorder (dpy, tmp->title_w, tmp->border); +*/ +/* djhjr - 11/17/97 + XSetWindowBorder (dpy, tmp->title_w, tmp->border_tile.back); +*/ + XSetWindowBorder (dpy, tmp->title_w, tmp->border.back); + } + else + { + XSetWindowBorderPixmap (dpy, tmp->frame, tmp->gray); + + if (tmp->title_w) + XSetWindowBorderPixmap (dpy, tmp->title_w, tmp->gray); + } + } + + /* djhjr - 11/17/97 */ + /* rem'd out test for button color - djhjr - 9/15/99 */ + if (/*Scr->ButtonColorIsFrame && */tmp->titlebuttons) + { + int i, nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; + TBWindow *tbw; + + /* collapsed two functions - djhjr - 8/10/98 */ + for (i = 0, tbw = tmp->titlebuttons; i < nb; i++, tbw++) + PaintTitleButton(tmp, tbw, (onoroff) ? 2 : 1); + } + } +} + + + +void DestroyMenu (menu) + MenuRoot *menu; +{ + MenuItem *item; + + if (menu->w) { + XDeleteContext (dpy, menu->w, MenuContext); + XDeleteContext (dpy, menu->w, ScreenContext); + if (Scr->Shadow) XDestroyWindow (dpy, menu->shadow); + XDestroyWindow(dpy, menu->w); + } + + for (item = menu->first; item; ) { + MenuItem *tmp = item; + item = item->next; + free ((char *) tmp); + } +} + + + +/* + * warping routines + */ + +/* for moves and resizes from center - djhjr - 10/4/02 */ +void WarpScreenToWindow(t) +TwmWindow *t; +{ + int warpwin = Scr->WarpWindows; + int warpsnug = Scr->WarpSnug; + + Scr->WarpWindows = Scr->WarpSnug = FALSE; + WarpToWindow(t); + Scr->WarpWindows = warpwin; + Scr->WarpSnug = warpsnug; + + /* + * This is an attempt to have windows redraw themselves, but + * it doesn't always work (non-raising windows in particular). + */ + XSync(dpy, 0); +} + +/* was in-lined in WarpToWindow() - djhjr - 5/30/00 */ +void WarpWindowOrScreen(t) +TwmWindow *t; +{ + + /* + * we are either moving the window onto the screen, or the screen to the + * window, the distances remain the same + */ + + if ((t->frame_x < Scr->MyDisplayWidth) + && (t->frame_y < Scr->MyDisplayHeight) + && (t->frame_x + t->frame_width >= 0) + && (t->frame_y + t->frame_height >= 0)) + { + + /* + * window is visible; you can simply + * snug it if WarpSnug or WarpWindows is set -- DSE + */ + + if (Scr->WarpSnug || Scr->WarpWindows) + { + int right,left,up,down,dx,dy; + + /* + * Adjustment for border widths submitted by Steve Ratcliffe + * Note: Do not include the 3D border width! + */ + right = t->frame_x; + left = t->frame_x + t->frame_width + 2 * t->frame_bw; + up = t->frame_y; + down = t->frame_y + t->frame_height + 2 * t->frame_bw; + + dx = 0; + if (left-right < Scr->MyDisplayWidth) + { + if (right<0) + dx = right; + else if (left>Scr->MyDisplayWidth) + dx = left - Scr->MyDisplayWidth; + } + + dy = 0; + if (down-up < Scr->MyDisplayHeight) + { + if (up<0) + dy = up; + else if (down>Scr->MyDisplayHeight) + dy = down - Scr->MyDisplayHeight; + } + + if (dx!=0 || dy!=0) { + /* added 'Scr->WarpSnug ||' - djhjr - 5/30/00 */ + if (Scr->WarpSnug || Scr->WarpWindows) + { + /* move the window */ + VirtualMoveWindow(t, t->virtual_frame_x - dx, + t->virtual_frame_y - dy); + } + else + { + /* move the screen */ + PanRealScreen(dx,dy,NULL,NULL); + } + } + } + } + else + { + + /* + * Window is invisible; we need to move it or the screen. + */ + + int xdiff, ydiff; + + xdiff = ((Scr->MyDisplayWidth - t->frame_width) / 2) - t->frame_x; + ydiff = ((Scr->MyDisplayHeight - t->frame_height) / 2) - t->frame_y; + + /* added 'Scr->WarpSnug ||' - djhjr - 5/30/00 */ + if (Scr->WarpSnug || Scr->WarpWindows) + { + /* move the window */ + VirtualMoveWindow(t, t->virtual_frame_x + xdiff, + t->virtual_frame_y + ydiff); + } + else + { + /* move the screen */ + PanRealScreen(-xdiff, -ydiff,NULL,NULL); /* DSE */ + } + } + + if (t->auto_raise || !Scr->NoRaiseWarp) + AutoRaiseWindow (t); +} + +/* for icon manager management - djhjr - 5/30/00 */ +void WarpInIconMgr(w, t) +WList *w; +TwmWindow *t; +{ + int x, y, pan_margin = 0; + /* djhjr - 9/9/02 */ + int bw = t->frame_bw3D + t->frame_bw; + + RaiseStickyAbove(); + RaiseAutoPan(); + + WarpWindowOrScreen(t); + + /* was 'Scr->BorderWidth' - djhjr - 9/9/02 */ + x = w->x + bw + EDGE_OFFSET + 5; + x += (Scr->IconMgrBevelWidth > 0) ? Scr->IconMgrBevelWidth : bw; + y = w->y + bw + w->height / 2; + y += (Scr->IconMgrBevelWidth > 0) ? Scr->IconMgrBevelWidth : bw; + y += w->iconmgr->twm_win->title_height; + + /* + * adjust the pointer for partially visible windows and the + * AutoPan border width + */ + + if (Scr->AutoPanX) pan_margin = Scr->AutoPanBorderWidth; + + if (x + t->frame_x >= Scr->MyDisplayWidth - pan_margin) + x = Scr->MyDisplayWidth - t->frame_x - pan_margin - 2; + if (x + t->frame_x <= pan_margin) + x = -t->frame_x + pan_margin + 2; + if (y + t->frame_y >= Scr->MyDisplayHeight - pan_margin) + y = Scr->MyDisplayHeight - t->frame_y - pan_margin - 2; + if (y + t->frame_y <= pan_margin) + y = -t->frame_y + pan_margin + 2; + + XWarpPointer(dpy, None, t->frame, 0, 0, 0, 0, x, y); /* DSE */ +} + +/* + * substantially re-written and added passing 'next' to next_by_class() + * + * djhjr - 5/13/98 6/6/98 6/15/98 + */ +#ifdef ORIGINAL_WARPCLASS +void WarpClass (next, t, class) + int next; + TwmWindow *t; + char *class; +{ + int len = strlen(class); + + if (!strncmp(class, t->class.res_class, len)) + t = next_by_class(t, class); + else + t = next_by_class((TwmWindow *)NULL, class); + if (t) { + if (Scr->WarpUnmapped || t->mapped) { + if (!t->mapped) DeIconify (t); + if (!Scr->NoRaiseWarp) + { + XRaiseWindow (dpy, t->frame); + } + XRaiseWindow (dpy, t->VirtualDesktopDisplayWindow); + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + + WarpToWindow (t); + } + } +} +#else /* ORIGINAL_WARPCLASS */ +void WarpClass(next, t, class) + int next; + TwmWindow *t; + char *class; +{ + TwmWindow *tt; + XClassHint ch; + int i; + + /* + * if an empty class string + * if a TwmWindow + * class = the TwmWindow's class + * else if a window with focus + * if it's classed + * class = the focused window's class + * else + * return + * if still an empty class string + * class = "VTWM" + */ + if (!strlen(class)) + { + if (t) + class = t->class.res_class; + else if (Scr->Focus) + { + i = XGetClassHint(dpy, Scr->Focus->w, &ch); + if (i && !strncmp(class, ch.res_class, strlen(class))) + class = ch.res_class; + } + /* djhjr - 6/21/00 */ + else + { + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + return; + } + } + if (!strlen(class) || !strncmp(class, "VTWM", 4)) + class = "VTWM"; + +/* djhjr - 8/3/98 + if (!(tt = next_by_class(next, t, class))) + if (t) tt = t; +*/ + + /* djhjr - 5/28/00 */ + while (1) + { + + tt = NULL; + do + { + if ((tt = next_by_class(next, t, class))) + { + /* multiple icon managers: gotta test for those without entries */ + if (tt->iconmgr && tt->iconmgrp->count == 0) + { + t = tt; + tt = NULL; + } + } + else if (t) + tt = t; + else + break; + } while (!tt); + + /* added the second argument - djhjr - 5/28/00 */ + if (tt && warp_if_warpunmapped(tt, (next) ? F_WARPCLASSNEXT: F_WARPCLASSPREV)) + { + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + +/* djhjr - 6/3/03 */ +#ifndef NO_SOUND_SUPPORT + PlaySound((next) ? F_WARPCLASSNEXT: F_WARPCLASSPREV); +#endif + + WarpToWindow(tt); + + /* djhjr - 5/28/00 */ + break; + } +/* djhjr - 5/28/00 + else + XBell(dpy, 0); +*/ + t = tt; + } /* while (1) */ +} +#endif /* ORIGINAL_WARPCLASS */ + + + +/* moved from add_window.c - djhjr - 10/27/02 */ +void AddWindowToRing(tmp_win) +TwmWindow *tmp_win; +{ + if (Scr->Ring) + { + /* link window in after Scr->Ring */ + tmp_win->ring.prev = Scr->Ring; + tmp_win->ring.next = Scr->Ring->ring.next; + + /* Scr->Ring's next's prev points to this */ + /*if (Scr->Ring->ring.next->ring.prev)*/ + Scr->Ring->ring.next->ring.prev = tmp_win; + + /* Scr->Ring's next points to this */ + Scr->Ring->ring.next = tmp_win; + } + else + tmp_win->ring.next = tmp_win->ring.prev = Scr->Ring = tmp_win; +} + +/* moved from events.c - djhjr - 10/27/02 */ +void RemoveWindowFromRing(tmp_win) +TwmWindow *tmp_win; +{ + /* unlink window */ + if (tmp_win->ring.prev) + tmp_win->ring.prev->ring.next = tmp_win->ring.next; + if (tmp_win->ring.next) + tmp_win->ring.next->ring.prev = tmp_win->ring.prev; + + /* if window was only thing in ring, null out ring */ + if (Scr->Ring == tmp_win) + Scr->Ring = (tmp_win->ring.next != tmp_win) ? + tmp_win->ring.next : (TwmWindow *)NULL; + + /* if window was ring leader, set to next (or null) */ + if (!Scr->Ring || Scr->RingLeader == tmp_win) + Scr->RingLeader = Scr->Ring; + + tmp_win->ring.next = tmp_win->ring.prev = NULL; +} + +void WarpAlongRing (ev, forward) + XButtonEvent *ev; + Bool forward; +{ + TwmWindow *r, *head; + + /* + * Re-vamped much of this to properly handle icon managers, and + * clean up dumb code I added some time back. + * djhjr - 11/8/01 + * Cleaned it up again. I musta been high. Twice. + * djhjr - 10/27/02 + */ + + if (!(head = (Scr->RingLeader) ? Scr->RingLeader : Scr->Ring)) + { + DoAudible(); + return; + } + + if (forward) + r = head->ring.next; + else + r = head->ring.prev; + + while (r && r != head) + { + if (r->mapped || warp_if_warpunmapped(r, F_WARPRING)) + break; + + r = (forward) ? r->ring.next : r->ring.prev; + } + + if (r && r->mapped) + { +#ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */ + TwmWindow *p = Scr->RingLeader, *t; +#endif + +/* done in WarpToWindow - djhjr - 10/27/02 + Scr->RingLeader = r; +*/ + + RaiseStickyAbove(); + RaiseAutoPan(); + +/* djhjr - 6/3/03 */ +#ifndef NO_SOUND_SUPPORT + PlaySound(F_WARPRING); +#endif + + WarpToWindow (r); + +#ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */ + if (p && p->mapped && + XFindContext (dpy, ev->window, TwmContext, (caddr_t *)&t) == XCSUCCESS && + p == t) + { + p->ring.cursor_valid = True; + p->ring.curs_x = ev->x_root - t->frame_x; + p->ring.curs_y = ev->y_root - t->frame_y; + if (p->ring.curs_x < -p->frame_bw || + p->ring.curs_x >= p->frame_width + p->frame_bw || + p->ring.curs_y < -p->frame_bw || + p->ring.curs_y >= p->frame_height + p->frame_bw) + { + /* somehow out of window */ + p->ring.curs_x = p->frame_width / 2; + p->ring.curs_y = p->frame_height / 2; + } + } +#endif + } + else + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ +} + + + +void WarpToScreen (n, inc) + int n, inc; +{ + Window dumwin; + int x, y, dumint; + unsigned int dummask; + ScreenInfo *newscr = NULL; + + while (!newscr) { + /* wrap around */ + if (n < 0) + n = NumScreens - 1; + else if (n >= NumScreens) + n = 0; + + newscr = ScreenList[n]; + if (!newscr) { /* make sure screen is managed */ + if (inc) { /* walk around the list */ + n += inc; + continue; + } + fprintf (stderr, "%s: unable to warp to unmanaged screen %d\n", + ProgramName, n); + DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */ + return; + } + } + + if (Scr->screen == n) return; /* already on that screen */ + + PreviousScreen = Scr->screen; + XQueryPointer (dpy, Scr->Root, &dumwin, &dumwin, &x, &y, + &dumint, &dumint, &dummask); + +/* djhjr - 6/3/03 */ +#ifndef NO_SOUND_SUPPORT + PlaySound(F_WARPTOSCREEN); +#endif + + XWarpPointer (dpy, None, newscr->Root, 0, 0, 0, 0, x, y); + return; +} + + + +void WarpToWindow (t) +TwmWindow *t; +{ + int x, y; + int pan_margin = 0; /* djhjr - 5/28/00 */ + int bw = t->frame_bw3D + t->frame_bw; /* djhjr - 9/9/02 */ + Window w = t->frame; /* djhjr - 5/30/00 */ + + WarpWindowOrScreen(t); /* djhjr - 5/30/00 */ + +#ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */ + if (t->ring.cursor_valid) { + x = t->ring.curs_x; + y = t->ring.curs_y; + } + else { + x = t->frame_width / 2; + y = t->frame_height / 2; + } +#else + /* added this 'if (...) else' - djhjr - 6/10/98 */ + if (t->iconmgr) + { +/* djhjr - 5/30/00 + if (t->iconmgrp->count > 0) + XWarpPointer(dpy, None, t->iconmgrp->first->icon, 0,0,0,0, + EDGE_OFFSET, EDGE_OFFSET); + + return; +*/ + if (t->iconmgrp->count > 0) + { + w = t->iconmgrp->twm_win->frame; + + /* was 'Scr->BorderWidth' - djhjr - 9/9/02 */ + x = t->iconmgrp->x + bw + EDGE_OFFSET + 5; + x += (Scr->IconMgrBevelWidth > 0) ? Scr->IconMgrBevelWidth : bw; + y = t->iconmgrp->y + bw + t->iconmgrp->first->height / 2; + y += (Scr->IconMgrBevelWidth > 0) ? Scr->IconMgrBevelWidth : bw; + y += t->iconmgrp->twm_win->title_height; + } + } + else if (!t->title_w) + { + /* added this 'if (...) else' - djhjr - 10/16/02 */ + if (Scr->WarpCentered & WARPC_UNTITLED) + { + x = t->frame_width / 2; + y = t->frame_height / 2; + } + else + { + x = t->frame_width / 2; + y = (t->wShaped) ? bw : bw / 2; /* djhjr - 9/9/02 */ + } + } + else + { + /* added this 'if (...) else' - djhjr - 10/16/02 */ + if (Scr->WarpCentered & WARPC_TITLED) + { + x = t->frame_width / 2; + y = t->frame_height / 2; + } + else + { + /* + * Added 't->title_x + ' to handle titlebars that + * aren't flush left. + * Submitted by Steve Ratcliffe + * was '(t->frame_bw3D + t->frame_bw)' - djhjr - 9/9/02 + */ + x = t->title_x + t->title_width / 2 + bw; + y = t->title_height / 2 + bw; + } + } + + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (!Scr->BorderBevelWidth > 0) y -= t->frame_bw; +#endif + + /* + * adjust the pointer for partially visible windows and the + * AutoPan border width - djhjr - 5/30/00 + * was '(t->frame_bw3D + t->frame_bw)' - djhjr - 9/9/02 + */ + + if (Scr->AutoPanX) pan_margin = Scr->AutoPanBorderWidth; + + if (x + t->frame_x >= Scr->MyDisplayWidth - pan_margin) + x = Scr->MyDisplayWidth - t->frame_x - pan_margin - 2; + if (x + t->frame_x <= pan_margin) + { + if (t->title_w) + x = t->title_width - (t->frame_x + t->title_width) + + pan_margin + 2; + else + x = -t->frame_x + pan_margin + 2; + } + + /* added test for centered warps - djhjr - 10/16/02 */ + if (t->title_w && !(Scr->WarpCentered & WARPC_TITLED) && + (x < t->title_x || x > t->title_x + t->title_width)) + { + y = t->title_height + bw / 2; + } + if (y + t->frame_y >= Scr->MyDisplayHeight - pan_margin) + { + y = Scr->MyDisplayHeight - t->frame_y - pan_margin - 2; + + /* move centered warp to titlebar - djhjr - 10/16/02 */ + if (y < t->title_y + t->title_height) + x = t->title_x + t->title_width / 2 + bw; + } + if (y + t->frame_y <= pan_margin) + y = -t->frame_y + pan_margin + 2; + + /* was 't->frame' - djhjr - 5/30/00 */ + XWarpPointer (dpy, None, w, 0, 0, 0, 0, x, y); + + /* djhjr - 10/27/02 */ + if (t->ring.next) Scr->RingLeader = t; +} + + + +/* + * substantially re-written and added receiving and using 'next' + * + * djhjr - 5/13/98 5/19/98 6/6/98 6/15/98 + */ +#ifdef ORIGINAL_WARPCLASS +TwmWindow * +next_by_class (t, class) +TwmWindow *t; +char *class; +{ + TwmWindow *tt; + int len = strlen(class); + + if (t) + for (tt = t->next; tt != NULL; tt = tt->next) + if (!strncmp(class, tt->class.res_class, len)) return tt; + for (tt = Scr->TwmRoot.next; tt != NULL; tt = tt->next) + if (!strncmp(class, tt->class.res_class, len)) return tt; + return NULL; +} +#else /* ORIGINAL_WARPCLASS */ +static TwmWindow * +next_by_class (next, t, class) +int next; +TwmWindow *t; +char *class; +{ + static TwmWindow *tp = NULL; + TwmWindow *tt, *tl; + int i, len = strlen(class); + XClassHint ch; + +#ifdef DEBUG_WARPCLASS + fprintf(stderr, "class=\"%s\", next=%d, %s t, ", class, next, (t) ? "have" : "no"); +#endif + + /* forward or backward from current */ + tl = (next) ? ((tp) ? tp->next : Scr->TwmRoot.next) : ((tp) ? tp->prev : Scr->TwmRoot.prev); + for (tt = (next) ? ((t) ? t->next : tl) : ((t) ? t->prev : tl); + tt != NULL; + tt = (next) ? tt->next : tt->prev) + if (Scr->WarpUnmapped || tt->mapped) + { + i = XGetClassHint(dpy, tt->w, &ch); + if (i && !strncmp(class, ch.res_class, len)) + { +#ifdef DEBUG_WARPCLASS + fprintf(stderr, "matched \"%s\" \"%s\"\n", tt->class.res_class, tt->class.res_name); +#endif + tp = tt; + return tp; + } + else + { +#ifdef DEBUG_WARPCLASS + fprintf(stderr, "(1) skipping \"%s\"\n", (i) ? tt->class.res_class : "NO RES_CLASS!"); +#endif + if (i == 0) break; + } + } + + /* no match, wrap and retry */ + tp = tl = NULL; + for (tt = Scr->TwmRoot.next; tt != NULL; tt = tt->next) + if (Scr->WarpUnmapped || tt->mapped) + { + i = XGetClassHint(dpy, tt->w, &ch); + if (i && !strncmp(class, ch.res_class, len)) + { + if (next) + { +#ifdef DEBUG_WARPCLASS + fprintf(stderr, "next wrapped to \"%s\ \"%s\"\n", tt->class.res_class, tt->class.res_name); +#endif + tp = tt; + return tp; + } + else + tl = tt; + } +#ifdef DEBUG_WARPCLASS + else + fprintf(stderr, "(2) skipping \"%s\"\n", (i) ? tt->class.res_class : "NO RES_CLASS!"); +#endif + } + +#ifdef DEBUG_WARPCLASS + i = 0; if (tl) i = XGetClassHint(dpy, tl->w, &ch); + fprintf(stderr, "prev wrapped to \"%s\ \"%s\"\n", (i) ? ch.res_class : "NO RES_CLASS!", (i) ? ch.res_name : "NO RES_CLASS!"); +#endif + tp = tl; + return tp; +} +#endif /* ORIGINAL_WARPCLASS */ + +/* this was inlined in many places, and even more now - djhjr - 5/13/98 */ +/* added the second argument - djhjr - 5/28/00 */ +static int warp_if_warpunmapped(w, func) +TwmWindow *w; +int func; +{ + /* skip empty icon managers - 10/27/02 */ + if (w && (w->iconmgr && w->iconmgrp->count == 0)) + return (0); + + if (Scr->WarpUnmapped || w->mapped) + { + /* submitted by Ugen Antsilevitch - 5/28/00 */ + /* if F_NOFUNCTION, override WarpVisible - djhjr - 5/28/00 */ + if (func != F_NOFUNCTION && Scr->WarpVisible) + { + int pan_margin = 0; + + if (Scr->AutoPanX) pan_margin = Scr->AutoPanBorderWidth; + + if (w->frame_x >= Scr->MyDisplayWidth - pan_margin || + w->frame_y >= Scr->MyDisplayHeight - pan_margin || + w->frame_x + w->frame_width <= pan_margin || + w->frame_y + w->frame_height <= pan_margin) + return 0; + } + + if (!w->mapped) DeIconify(w); + if (!Scr->NoRaiseWarp) XRaiseWindow(dpy, w->frame); + XRaiseWindow(dpy, w->VirtualDesktopDisplayWindow); + + return (1); + } + + return (0); +} + +/* djhjr - 9/17/02 */ +static int +do_squeezetitle(context, func, tmp_win, squeeze) +int context, func; +TwmWindow *tmp_win; +SqueezeInfo *squeeze; +{ + if (DeferExecution (context, func, Scr->SelectCursor)) + return TRUE; + + /* honor "Don't Squeeze" resources - djhjr - 9/17/02 */ + if (Scr->SqueezeTitle && + !LookInList(Scr->DontSqueezeTitleL, tmp_win->full_name, &tmp_win->class)) + { + if ( tmp_win->title_height ) /* Not for untitled windows! */ + { + PopDownMenu(); /* djhjr - 9/17/02 */ + +#ifndef NO_SOUND_SUPPORT + PlaySound(func); +#endif + + tmp_win->squeeze_info = squeeze; + SetFrameShape( tmp_win ); + + /* Can't go in SetFrameShape()... - djhjr - 4/1/00 */ + if (Scr->WarpCursor || + LookInList(Scr->WarpCursorL, tmp_win->full_name, &tmp_win->class)) + WarpToWindow(tmp_win); + } + } + else + DoAudible(); + + return FALSE; +} + +/* + * Two functions to handle a restart from a SIGUSR1 signal + * (see also twm.c:Done() and twm.c:QueueRestartVtwm()) + * + * adapted from TVTWM-pl11 - djhjr - 7/31/98 + */ + +static void setup_restart(time) + Time time; +{ +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + CloseSound(); +#endif + + SetRealScreen(0,0); + XSync (dpy, 0); + Reborder (time); + XSync (dpy, 0); + + /* djhjr - 3/13/97 */ + XCloseDisplay(dpy); + + /* djhjr - 12/2/01 */ + delete_pidfile(); +} + +void RestartVtwm(time) + Time time; +{ + setup_restart(time); + + execvp(*Argv, Argv); + fprintf (stderr, "%s: unable to restart \"%s\"\n", ProgramName, *Argv); +} + + +/* + * ICCCM Client Messages - Section 4.2.8 of the ICCCM dictates that all + * client messages will have the following form: + * + * event type ClientMessage + * message type _XA_WM_PROTOCOLS + * window tmp->w + * format 32 + * data[0] message atom + * data[1] time stamp + */ + +static void send_clientmessage (w, a, timestamp) + Window w; + Atom a; + Time timestamp; +{ + XClientMessageEvent ev; + + ev.type = ClientMessage; + ev.window = w; + ev.message_type = _XA_WM_PROTOCOLS; + ev.format = 32; + ev.data.l[0] = a; + ev.data.l[1] = timestamp; + XSendEvent (dpy, w, False, 0L, (XEvent *) &ev); +} + +void SendDeleteWindowMessage (tmp, timestamp) + TwmWindow *tmp; + Time timestamp; +{ + send_clientmessage (tmp->w, _XA_WM_DELETE_WINDOW, timestamp); +} + +void SendSaveYourselfMessage (tmp, timestamp) + TwmWindow *tmp; + Time timestamp; +{ + send_clientmessage (tmp->w, _XA_WM_SAVE_YOURSELF, timestamp); +} + +void SendTakeFocusMessage (tmp, timestamp) + TwmWindow *tmp; + Time timestamp; +{ + send_clientmessage (tmp->w, _XA_WM_TAKE_FOCUS, timestamp); +} + + +/* djhjr - 4/27/96 */ +void DisplayPosition (x, y) +int x, y; +{ + char str [100]; + int i; + +/* djhjr - 5/10/96 + char signx = '+'; + char signy = '+'; + + if (x < 0) { + x = -x; + signx = '-'; + } + if (y < 0) { + y = -y; + signy = '-'; + } + + i = sprintf (str, " %c%-4d %c%-4d ", signx, x, signy, y); +*/ +/* + * Non-SysV systems - specifically, BSD-derived systems - return a + * pointer to the string, not its length. Submitted by Goran Larsson + i = sprintf (str, "%+6d %-+6d", x, y); + */ + sprintf (str, "%+6d %-+6d", x, y); + i = strlen (str); + + XRaiseWindow (dpy, Scr->SizeWindow); + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF (Scr->DefaultC.fore, Scr->DefaultC.back, Scr->SizeFont); +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont, +#else + XDrawImageString (dpy, Scr->SizeWindow, +#endif + Scr->NormalGC, + +/* djhjr - 5/9/96 + Scr->SizeStringOffset, +*/ + (Scr->SizeStringWidth - +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_TextWidth(&Scr->SizeFont, +#else + XTextWidth(Scr->SizeFont.font, +#endif + str, i)) / 2, + +/* djhjr - 4/29/98 + Scr->SizeFont.font->ascent + SIZE_VINDENT, +*/ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ +/* djhjr - 9/14/03 + Scr->SizeFont.font->ascent + +*/ + Scr->SizeFont.ascent + + SIZE_VINDENT + + ((Scr->InfoBevelWidth > 0) ? Scr->InfoBevelWidth : 0), + + str, i); + + /* I know, I know, but the above code overwrites it... djhjr - 5/9/96 */ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (Scr->InfoBevelWidth > 0) + Draw3DBorder(Scr->SizeWindow, 0, 0, + Scr->SizeStringWidth, + +/* djhjr - 4/29/98 + (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2), + BW, Scr->DefaultC, off, False, False); +*/ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2) + + ((Scr->InfoBevelWidth > 0) ? 2 * Scr->InfoBevelWidth : 0), + Scr->InfoBevelWidth, Scr->DefaultC, off, False, False); +} + +/* djhjr - 9/21/99 */ +int FindMenuOrFuncInBindings(contexts, mr, func) +int contexts; +MenuRoot *mr; +int func; +{ + MenuRoot *start; + FuncKey *key; + int found = 0; /* context bitmap for menu or function */ + int i, j, k, l, fallback = 0; + + if (mr) + { + if (Scr->DefaultFunction.func == F_MENU) + if (FindMenuInMenus(Scr->DefaultFunction.menu, mr)) + fallback = 1; + } + else + { + if (Scr->DefaultFunction.func == func) + fallback = 1; + else if (Scr->DefaultFunction.func == F_MENU) + if (FindFuncInMenus(Scr->DefaultFunction.menu, func)) + fallback = 1; + } + + for (j = 0; j < NUM_CONTEXTS; j++) + { + if ((contexts & (1 << j)) == 0) continue; + + if (fallback) + { + found |= (1 << j); + continue; + } + + for (i = 0; i < MAX_BUTTONS + 1; i++) + { + l = 0; + + for (k = 0; k < MOD_SIZE; k++) + { + if (mr) + { + if (Scr->Mouse[i][j][k].func == F_MENU) + l = FindMenuInMenus(Scr->Mouse[i][j][k].menu, mr); + } + else + { + if (Scr->Mouse[i][j][k].func == func) + l = 1; + else if (Scr->Mouse[i][j][k].func == F_MENU) + l = FindFuncInMenus(Scr->Mouse[i][j][k].menu, func); + } + + if (l) + { + found |= (1 << j); + i = MAX_BUTTONS + 1; + break; + } + } + } + + l = 0; + for (key = Scr->FuncKeyRoot.next; key != NULL; key = key->next) + if (key->cont & (1 << j)) + { + if (mr) + { + if (key->func == F_MENU) + for (start = Scr->MenuList; start != NULL; start = start->next) + if (strcmp(start->name, key->action) == 0) + { + l = FindMenuInMenus(start, mr); + break; + } + } + else + { + if (key->func == func) + l = 1; + else if (key->func == F_MENU) + for (start = Scr->MenuList; start != NULL; start = start->next) + if (strcmp(start->name, key->action) == 0) + { + l = FindFuncInMenus(start, func); + break; + } + } + + if (l) + { + found |= (1 << j); + break; + } + } + } + + return found; +} + +/* djhjr - 9/21/99 */ +int FindMenuOrFuncInWindows(tmp_win, contexts, mr, func) +TwmWindow *tmp_win; +int contexts; +MenuRoot *mr; +int func; +{ + TwmWindow *twin; + TwmDoor *d; + TBWindow *tbw; + int i, nb; + + if (contexts & C_ROOT_BIT) return 1; + + for (twin = Scr->TwmRoot.next; twin != NULL; twin = twin->next) + if (twin != tmp_win) + { + /* + * if this window is an icon manager, + * skip the windows that aren't in it + */ + if (tmp_win->iconmgr && twin->list && + tmp_win != twin->list->iconmgr->twm_win) + continue; + + if (twin->mapped) + { + for (i = 1; i < C_ALL_BITS; i = (1 << i)) + { + if ((contexts & i) == 0) continue; + + switch (i) + { + case C_WINDOW_BIT: + case C_FRAME_BIT: + break; + case C_TITLE_BIT: + if (!twin->title_height) continue; + break; + case C_VIRTUAL_BIT: + if (twin->w != Scr->VirtualDesktopDisplayOuter) + continue; + break; + case C_DOOR_BIT: + if (XFindContext(dpy, twin->w, DoorContext, + (caddr_t *)&d) == XCNOENT) + continue; + break; + default: + continue; + break; + } + + return 1; + } + + if (twin->titlebuttons) + { + nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; + + for (tbw = twin->titlebuttons; nb > 0; tbw++, nb--) + if (mr) + { + if (tbw->info->menuroot) + if (FindMenuInMenus(tbw->info->menuroot, mr)) + return 1; + } + else + { + if (tbw->info->func == func) + return 1; + else if (tbw->info->menuroot) + if (FindFuncInMenus(tbw->info->menuroot, func)) + return 1; + } + } + } + else if (!twin->iconify_by_unmapping) + { + /* not mapped and shows an icon */ + + if (contexts & C_ICON_BIT) return 1; + } + } + + return 0; +} + +/* djhjr - 9/21/99 */ +int FindMenuInMenus(start, sought) +MenuRoot *start, *sought; +{ + MenuItem *mi; + + if (!start) return 0; /* submitted by Jonathan Paisley - 11/11/02 */ + if (start == sought) return 1; + + for (mi = start->first; mi != NULL; mi = mi->next) + if (mi->sub) + if (FindMenuInMenus(mi->sub, sought)) + return 1; + + return 0; +} + +/* djhjr - 9/21/99 */ +int FindFuncInMenus(mr, func) +MenuRoot *mr; +int func; +{ + MenuItem *mi; + + for (mi = mr->first; mi != NULL; mi = mi->next) + if (mi->func == func) + return 1; + else if (mi->sub) + if (FindFuncInMenus(mi->sub, func)) + return 1; + + return 0; +} + +/* djhjr - 6/22/01 */ +void DoAudible() +{ +#ifndef NO_SOUND_SUPPORT + if (PlaySound(S_BELL)) return; +#endif + + XBell(dpy, 0); +} + diff --git a/menus.h b/menus.h new file mode 100644 index 0000000..de8761a --- /dev/null +++ b/menus.h @@ -0,0 +1,220 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/*********************************************************************** + * + * $XConsortium: menus.h,v 1.24 89/12/10 17:46:26 jim Exp $ + * + * twm menus include file + * + * 17-Nov-87 Thomas E. LaStrange File created + * + ***********************************************************************/ + +#ifndef _MENUS_ +#define _MENUS_ + +#define TWM_ROOT "bLoB_GoOp" /* my private root menu */ + +#define TWM_WINDOWS "TwmWindows" /* for f.menu "TwmWindows" */ + +/* djhjr - 5/4/98 */ +#define VTWM_WINDOWS "VTWM Windows" /* for f.menu "VTWM Windows" */ + +#define MAX_FILE_SIZE 4096 /* max chars to read from file for cut */ + +typedef struct MenuItem +{ + struct MenuItem *next; /* next menu item */ + struct MenuItem *prev; /* prev menu item */ + struct MenuRoot *sub; /* MenuRoot of a pull right menu */ + struct MenuRoot *root; /* back pointer to my MenuRoot */ + char *item; /* the character string displayed */ + char *action; /* action to be performed */ + +/* djhjr - 4/22/96 + Pixel fore; * foreground color * + Pixel back; * background color * + Pixel hi_fore; * highlight foreground * + Pixel hi_back; * highlight background * +*/ + ColorPair normal; /* unhiglight colors */ + ColorPair highlight; /* highlight colors */ + + short item_num; /* item number of this menu */ + short x; /* x coordinate for text */ + short func; /* twm built in function */ + short state; /* video state, 0 = normal, 1 = reversed */ + short strlen; /* strlen(item) */ + short user_colors; /* colors were specified */ + + /* djhjr - 4/22/96 */ + short separated; /* separated from the next item */ + +} MenuItem; + +typedef struct MenuRoot +{ + struct MenuItem *first; /* first item in menu */ + struct MenuItem *last; /* last item in menu */ + struct MenuRoot *prev; /* previous root menu if pull right */ + struct MenuRoot *next; /* next in list of root menus */ + char *name; /* name of root */ + Window w; /* the window of the menu */ + Window shadow; /* the shadow window */ + +/* djhjr - 4/22/96 + Pixel hi_fore; * highlight foreground * + Pixel hi_back; * highlight background * +*/ + ColorPair highlight; /* highlight colors */ + + short mapped; /* NEVER_MAPPED, UNMAPPED, or MAPPED */ + short height; /* height of the menu */ + short width; /* width of the menu */ + short items; /* number of items in the menu */ + short pull; /* is there a pull right entry? */ + short entered; /* EnterNotify following pop up */ + short real_menu; /* this is a real menu */ + + /* djhjr - 5/22/00 */ + short too_tall; /* menu taller than display? */ + short top; /* first item displayed */ +} MenuRoot; + +#define NEVER_MAPPED 0 /* constants for mapped field of MenuRoot */ +#define UNMAPPED 1 +#define MAPPED 2 + + +typedef struct MouseButton +{ + int func; /* the function number */ + int mask; /* modifier mask */ + MenuRoot *menu; /* menu if func is F_MENU */ + MenuItem *item; /* action to perform if func != F_MENU */ +} MouseButton; + +typedef struct FuncButton +{ + struct FuncButton *next; /* next in the list of function buttons */ + int num; /* button number */ + int cont; /* context */ + int mods; /* modifiers */ + int func; /* the function number */ + MenuRoot *menu; /* menu if func is F_MENU */ + MenuItem *item; /* action to perform if func != F_MENU */ +} FuncButton; + +typedef struct FuncKey +{ + struct FuncKey *next; /* next in the list of function keys */ + char *name; /* key name */ + KeySym keysym; /* X keysym */ + KeyCode keycode; /* X keycode */ + int cont; /* context */ + int mods; /* modifiers */ + int func; /* function to perform */ + char *win_name; /* window name (if any) */ + char *action; /* action string (if any) */ +} FuncKey; + +extern int RootFunction; +extern MenuRoot *ActiveMenu; +extern MenuItem *ActiveItem; +extern int MoveFunction; +extern int WindowMoved; +extern int ConstMove; +/* private variables now - djhjr - 10/6/02 +extern int ConstMoveDir; +extern int ConstMoveX; +extern int ConstMoveY; +extern int ConstMoveXL; +extern int ConstMoveXR; +extern int ConstMoveYT; +extern int ConstMoveYB; +*/ + +#define MAXMENUDEPTH 10 /* max number of nested menus */ +extern int MenuDepth; + +#define MOVE_NONE 0 /* modes of constrained move */ +#define MOVE_VERT 1 +#define MOVE_HORIZ 2 + +#define WARPSCREEN_NEXT "next" +#define WARPSCREEN_PREV "prev" +#define WARPSCREEN_BACK "back" + +#define COLORMAP_NEXT "next" +#define COLORMAP_PREV "prev" +#define COLORMAP_DEFAULT "default" + +extern int InitTitlebarButtons(); +extern void InitMenus(); +extern MenuRoot *NewMenuRoot(); +extern void SetMenuIconPixmap(); +extern MenuItem *AddToMenu(); +extern Bool PopUpMenu(); +extern MenuRoot *FindMenuRoot(); +extern Bool AddFuncKey(); +extern int ExecuteFunction(); +extern int DeferExecution(); +extern void Execute(); +extern void FocusOnRoot(); +extern void SetBorder(); +extern void ReGrab(); +extern void WarpToWindow(); +extern void PaintEntry(); +extern void DeIconify(); +extern void SetMapStateProp(); +extern void Iconify(); +extern void PopDownMenu(); +extern void UpdateMenu(); +extern void SendTakeFocusMessage(); +extern void PaintEntry(); +extern void SetBorder(); +extern int CreateTitleButton(); +extern void MakeMenus(); +extern void PaintMenu(); + +/* djhjr - 4/27/96 */ +extern void DisplayPosition (); + +/* djhjr - 5/30/00 */ +extern void WarpWindowOrScreen(); +extern void WarpInIconMgr(); + +/* djhjr - 10/27/02 */ +extern void AddWindowToRing(); +extern void RemoveWindowFromRing(); + +/* djhjr - 6/22/01 */ +extern void DoAudible(); + +#endif /* _MENUS_ */ diff --git a/parse.c b/parse.c new file mode 100644 index 0000000..050794a --- /dev/null +++ b/parse.c @@ -0,0 +1,2325 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/*********************************************************************** + * + * $XConsortium: parse.c,v 1.52 91/07/12 09:59:37 dave Exp $ + * + * parse the .twmrc file + * + * 17-Nov-87 Thomas E. LaStrange File created + * 10-Oct-90 David M. Sternlicht Storing saved colors on root + ***********************************************************************/ + +#include +#include +#include +#include +#include +#include "twm.h" +#include "screen.h" +#include "menus.h" +#include "list.h" +#include "util.h" +#include "gram.h" +#include "parse.h" +#include + +/* Submitted by Jason Gloudon */ +#ifndef NO_M4_SUPPORT +#include +#include +#include +#include +#endif + +extern void twmrc_error_prefix(); + +#define BUF_LEN 300 + +static FILE *twmrc; +static int ptr = 0; +static int len = 0; +static char buff[BUF_LEN+1]; +static char overflowbuff[20]; /* really only need one */ +static int overflowlen; +static char **stringListSource, *currentString; +void put_pixel_on_root(); + +int RaiseDelay = 0; /* msec, for AutoRaise *//*RAISEDELAY*/ +extern int yylineno; +extern int mods; + +int ConstrainedMoveTime = 400; /* milliseconds, event times */ + +static int twmFileInput(), twmStringListInput(); +void twmUnput(); +int (*twmInputFunc)(); + +extern char *defTwmrc[]; /* default bindings */ + +/* Submitted by Jason Gloudon */ +#ifndef NO_M4_SUPPORT +#define Resolution(pixels, mm) ((((pixels) * 100000 / (mm)) + 50) / 100) +#define M4_MAXDIGITS 21 /* greater than the number of digits in a long int */ +extern Bool PrintErrorMessages; +char *make_m4_cmdline(); +#endif + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT +extern void SetSoundHost(); +extern void SetSoundVolume(); +#endif + +/*********************************************************************** + * + * Procedure: + * ParseTwmrc - parse the .twmrc file + * + * Inputs: + * filename - the filename to parse. A NULL indicates $HOME/.twmrc + * + *********************************************************************** + */ + +static int doparse (ifunc, srctypename, srcname) + int (*ifunc)(); + char *srctypename; + char *srcname; +{ + mods = 0; + ptr = 0; + len = 0; +/* djhjr - 9/18/03 */ +#ifdef NEED_YYLINENO_V + yylineno = 1; +#endif + ParseError = FALSE; + twmInputFunc = ifunc; + overflowlen = 0; + + yyparse(); + + if (ParseError) { + fprintf (stderr, "%s: errors found in twm %s", + ProgramName, srctypename); + if (srcname) fprintf (stderr, " \"%s\"", srcname); + fprintf (stderr, "\n"); + } + return (ParseError ? 0 : 1); +} + +/* Changes for m4 pre-processing submitted by Jason Gloudon */ +/* added support for user-defined parameters - djhjr - 2/20/99 */ +#ifndef NO_M4_SUPPORT +int ParseTwmrc (filename, display_name, m4_preprocess, m4_option) + char *filename; + char *display_name; + int m4_preprocess; + char *m4_option; /* djhjr - 2/20/99 */ +#else +int ParseTwmrc (filename) + char *filename; +#endif +{ + int i; + char *cp = NULL; + char tmpfilename[257]; +#ifndef NO_M4_SUPPORT + char *m4_cmdline; + int m4_status; +#endif + + /* + * If filename given, try it, else try ~/.vtwmrc.#, else try ~/.vtwmrc, + * else try system.vtwmrc, else try ~/.twmrc.#, else ~/.twmrc, else + * system.twmrc; finally using built-in defaults. + * + * This choice allows user, then system, versions of .vtwmrc, followed + * by user, then system, versions of .twmrc. + * Thus, sites that have both twm and vtwm can allow users without + * private .vtwmrc or .twmrc files to fall back to system-wide + * defaults (very important when there are many users), yet the + * presence of a private .twmrc file for twm will not prevent + * features of a system-wide .vtwmrc file from exploiting the mew + * features of vtwm. Submitted by Nelson H. F. Beebe + */ + for (twmrc = NULL, i = 0; !twmrc && i <= 6; i++) { + switch (i) { + case 0: /* -f filename */ + cp = filename; + break; + + case 1: /* ~/.vtwmrc.screennum */ + if (!filename) { + cp = tmpfilename; + (void) sprintf (tmpfilename, "%s/.vtwmrc.%d", + Home, Scr->screen); + break; + } + continue; + + case 2: /* ~/.vtwmrc */ + if (!filename) { + tmpfilename[HomeLen + 8] = '\0'; + } + break; + + case 3: /* system.vtwmrc */ + cp = SYSTEM_VTWMRC; + break; + + case 4: /* ~/.twmrc.screennum */ + if (!filename) { + cp = tmpfilename; + (void) sprintf (tmpfilename, "%s/.twmrc.%d", + Home, Scr->screen); + break; + } + continue; + + case 5: /* ~/.twmrc */ + if(!filename){ + tmpfilename[HomeLen + 7] = '\0'; + } + break; + + case 6: /* system.twmrc */ + cp = SYSTEM_TWMRC; + break; + } + +#ifndef NO_M4_SUPPORT + if (cp) { + if (m4_preprocess && (access(cp, R_OK) == 0) ) { + if ((m4_cmdline = make_m4_cmdline(display_name, cp, m4_option)) != NULL) { + twmrc = popen(m4_cmdline, "r"); + free(m4_cmdline); + } + else { + m4_preprocess = 0; + twmrc = fopen (cp, "r"); + } + } + else { + twmrc = fopen (cp, "r"); + } + } +#else + if (cp) twmrc = fopen (cp, "r"); +#endif + } + + if (twmrc) { + int status; + + if (filename && cp != filename) { + fprintf (stderr, + "%s: unable to open twmrc file %s, using %s instead\n", + ProgramName, filename, cp); + } + status = doparse (twmFileInput, "file", cp); + +#ifndef NO_M4_SUPPORT + if(m4_preprocess){ + m4_status = pclose (twmrc); + if(!WIFEXITED(m4_status) || + (WIFEXITED(m4_status) && WEXITSTATUS(m4_status)) ){ + fprintf(stderr, + "%s: m4 returned %d\n", + ProgramName, WEXITSTATUS(m4_status)); + exit(-1); + } + } + else { + fclose (twmrc); + } +#else + fclose (twmrc); +#endif + + return status; + } else { + if (filename) { + fprintf (stderr, + "%s: unable to open twmrc file %s, using built-in defaults instead\n", + ProgramName, filename); + } + return ParseStringList (defTwmrc); + } +} + +int ParseStringList (sl) + char **sl; +{ + stringListSource = sl; + currentString = *sl; + return doparse (twmStringListInput, "string list", (char *)NULL); +} + + +/*********************************************************************** + * + * Procedure: + * twmFileInput - redefinition of the lex input routine for file input + * + * Returned Value: + * the next input character + * + *********************************************************************** + */ + +static int twmFileInput() +{ + if (overflowlen) return (int) overflowbuff[--overflowlen]; + + while (ptr == len) + { + if (fgets(buff, BUF_LEN, twmrc) == NULL) + return 0; + +/* djhjr - 9/18/03 */ +#ifdef NEED_YYLINENO_V + yylineno++; +#endif + + ptr = 0; + len = strlen(buff); + } + return ((int)buff[ptr++]); +} + +static int twmStringListInput() +{ + if (overflowlen) return (int) overflowbuff[--overflowlen]; + + /* + * return the character currently pointed to + */ + if (currentString) { + unsigned int c = (unsigned int) *currentString++; + + if (c) return c; /* if non-nul char */ + currentString = *++stringListSource; /* advance to next bol */ + return '\n'; /* but say that we hit last eol */ + } + return 0; /* eof */ +} + + +/*********************************************************************** + * + * Procedure: + * twmUnput - redefinition of the lex unput routine + * + * Inputs: + * c - the character to push back onto the input stream + * + *********************************************************************** + */ + +void twmUnput (c) + int c; +{ + if (overflowlen < sizeof overflowbuff) { + overflowbuff[overflowlen++] = (char) c; + } else { + twmrc_error_prefix (); + fprintf (stderr, "unable to unput character (%d)\n", + c); + } +} + + +/*********************************************************************** + * + * Procedure: + * TwmOutput - redefinition of the lex output routine + * + * Inputs: + * c - the character to print + * + *********************************************************************** + */ + +void +TwmOutput(c) +{ + putchar(c); +} + + +/********************************************************************** + * + * Parsing table and routines + * + ***********************************************************************/ + +typedef struct _TwmKeyword { + char *name; + int value; + int subnum; +} TwmKeyword; + +#define kw0_NoDefaults 1 +#define kw0_AutoRelativeResize 2 +#define kw0_ForceIcons 3 +#define kw0_NoIconManagers 4 +#define kw0_OpaqueMove 5 +#define kw0_InterpolateMenuColors 6 +#define kw0_NoVersion 7 +#define kw0_SortIconManager 8 +#define kw0_NoGrabServer 9 +#define kw0_NoMenuShadows 10 +#define kw0_NoRaiseOnMove 11 +#define kw0_NoRaiseOnResize 12 +#define kw0_NoRaiseOnDeiconify 13 +#define kw0_DontMoveOff 14 +#define kw0_NoBackingStore 15 +#define kw0_NoSaveUnders 16 +#define kw0_RestartPreviousState 17 +#define kw0_ClientBorderWidth 18 +#define kw0_NoTitleFocus 19 +#define kw0_RandomPlacement 20 +#define kw0_DecorateTransients 21 +#define kw0_ShowIconManager 22 +#define kw0_NoCaseSensitive 23 +#define kw0_NoRaiseOnWarp 24 +#define kw0_WarpUnmapped 25 +#define kw0_DeIconifyToScreen 26 +#define kw0_WarpWindows 27 +#define kw0_SnapRealScreen 28 +#define kw0_NotVirtualGeometries 29 +#define kw0_OldFashionedTwmWindowsMenu 30 /* RFB */ + +/* djhjr - 2/15/99 +#define kw0_UseRealScreenBorder 31 * RFB * +*/ + +#define kw0_StayUpMenus 32 +#define kw0_NaturalAutopanBehavior 33 /* DSE */ +#define kw0_EnhancedExecResources 34 /* DSE */ +#define kw0_RightHandSidePulldownMenus 35 /* DSE */ +#define kw0_LessRandomZoomZoom 36 /* DSE */ +#define kw0_PrettyZoom 37 /* DSE */ + +#define kw0_NoDefaultTitleButtons 38 /* DSE */ +#define kw0_NoDefaultMouseOrKeyboardBindings 39 /* DSE */ + +#define kw0_StickyAbove 40 /* DSE */ +#define kw0_DontInterpolateTitles 41 /* DSE */ +#define kw0_FixTransientVirtualGeometries 42 /* DSE */ + +#define kw0_WarpToTransients 43 /* PF */ +#define kw0_NoIconifyIconManagers 44 /* PF */ +#define kw0_StayUpOptionalMenus 45 /* PF */ + +#define kw0_WarpSnug 46 /* DSE */ + +#define kw0_PointerPlacement 47 /* cg */ +/* obsoleted by the *BevelWidth resources - djhjr - 8/11/98 +* djhjr - 4/18/96 * +#define kw0_Use3DMenus 47 +#define kw0_Use3DTitles 48 +#define kw0_Use3DIconManagers 49 +#define kw0_Use3DBorders 50 +*/ + +/* obsoleted by the ":xpm:*" built-in pixmaps - djhjr - 10/26/02 +* djhjr - 4/25/96 * +#define kw0_SunkFocusWindowTitle 51 +*/ + +/* djhjr - 6/25/96 */ +#define kw0_ShallowReliefWindowButton 52 + +/* djhjr - 9/21/96 */ +#define kw0_ButtonColorIsFrame 53 + +/* djhjr - 1/6/98 */ +#define kw0_FixManagedVirtualGeometries 54 + +/* djhjr - 1/19/98 */ +#define kw0_BeNiceToColormap 55 + +/* djhjr - 4/17/98 */ +#define kw0_VirtualReceivesMotionEvents 56 +#define kw0_VirtualSendsMotionEvents 57 + +/* obsoleted by the *BevelWidth resources - djhjr - 8/11/98 +* djhjr - 5/5/98 * +#define kw0_Use3DIcons 58 +*/ + +/* djhjr - 5/27/98 */ +#define kw0_NoIconManagerFocus 59 + +/* djhjr - 12/14/98 */ +#define kw0_StaticIconPositions 60 + +/* for rader - djhjr - 2/9/99 */ +#define kw0_NoPrettyTitles 61 + +/* djhjr - 6/22/99 */ +#define kw0_DontDeiconifyTransients 62 + +/* submitted by Ugen Antsilevitch - 5/28/00 */ +#define kw0_WarpVisible 63 + +/* djhjr - 10/2/01 */ +#define kw0_StrictIconManager 64 + +/* djhjr - 10/11/01 */ +#define kw0_ZoomZoom 65 + +/* djhjr - 10/20/02 */ +#define kw0_NoBorderDecorations 66 + +/* djhjr - 11/3/03 */ +#define kw0_RaiseOnStart 67 + +/* djhjr - 9/24/02 +#define kws_UsePPosition 1 +*/ +#define kws_IconFont 2 +#define kws_ResizeFont 3 +#define kws_MenuFont 4 +#define kws_TitleFont 5 +#define kws_IconManagerFont 6 +#define kws_UnknownIcon 7 +#define kws_IconDirectory 8 +#define kws_MaxWindowSize 9 +#define kws_VirtualFont 10 +#define kws_DoorFont 11 +#define kws_MenuTitleFont 12 /* DSE */ + +/* djhjr - 5/10/96 */ +#define kws_InfoFont 13 + +/* djhjr - 5/15/96 */ +#define kws_ResizeRegion 14 + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT +#define kws_SoundHost 15 +#endif + +#define kwn_ConstrainedMoveTime 1 +#define kwn_MoveDelta 2 +#define kwn_XorValue 3 +#define kwn_FramePadding 4 +#define kwn_TitlePadding 5 +#define kwn_ButtonIndent 6 +#define kwn_BorderWidth 7 +#define kwn_IconBorderWidth 8 +#define kwn_TitleButtonBorderWidth 9 +#define kwn_PanDistanceX 10 +#define kwn_PanDistanceY 11 +#define kwn_AutoPan 12 +#define kwn_RaiseDelay 13 /* RAISEDELAY */ +#define kwn_AutoPanBorderWidth 14 /* DSE */ +#define kwn_AutoPanExtraWarp 15 /* DSE */ +#define kwn_RealScreenBorderWidth 16 /* DSE */ +#define kwn_AutoPanWarpWithRespectToRealScreen 17 /* DSE */ + +/* djhjr - 8/11/98 +* djhjr - 4/18/96 * +#define kwn_ThreeDBorderWidth 18 +*/ + +/* djhjr - 4/18/96 */ +#define kwn_ClearBevelContrast 19 +#define kwn_DarkBevelContrast 20 + +/* djhjr - 5/2/98 */ +#define kwn_BorderBevelWidth 21 +#define kwn_IconManagerBevelWidth 22 +#define kwn_InfoBevelWidth 23 +#define kwn_MenuBevelWidth 24 +#define kwn_TitleBevelWidth 25 + +/* djhjr - 8/11/98 */ +#define kwn_IconBevelWidth 26 +#define kwn_ButtonBevelWidth 27 + +/* djhjr - 2/7/99 */ +#define kwn_DoorBevelWidth 28 +#define kwn_VirtualDesktopBevelWidth 29 + +/* djhjr - 9/8/98 */ +#define kwn_PanResistance 30 + +/* djhjr - 5/22/00 */ +#define kwn_MenuScrollBorderWidth 31 +#define kwn_MenuScrollJump 32 + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT +#define kwn_SoundVolume 33 +#endif +#define kwn_PauseOnExit 34 +#define kwn_PauseOnQuit 35 + +#define kwcl_BorderColor 1 +#define kwcl_IconManagerHighlight 2 +#define kwcl_BorderTileForeground 3 +#define kwcl_BorderTileBackground 4 +#define kwcl_TitleForeground 5 +#define kwcl_TitleBackground 6 +#define kwcl_IconForeground 7 +#define kwcl_IconBackground 8 +#define kwcl_IconBorderColor 9 +#define kwcl_IconManagerForeground 10 +#define kwcl_IconManagerBackground 11 +#define kwcl_VirtualDesktopBackground 12 +#define kwcl_VirtualDesktopForeground 13 +#define kwcl_VirtualDesktopBorder 14 +#define kwcl_DoorForeground 15 +#define kwcl_DoorBackground 16 + +#define kwc_DefaultForeground 1 +#define kwc_DefaultBackground 2 +#define kwc_MenuForeground 3 +#define kwc_MenuBackground 4 +#define kwc_MenuTitleForeground 5 +#define kwc_MenuTitleBackground 6 +#define kwc_MenuShadowColor 7 +#define kwc_VirtualForeground 8 /*RFB VCOLOR*/ +#define kwc_VirtualBackground 9 /*RFB VCOLOR*/ +#define kwc_RealScreenBackground 10 /* RFB 4/92 */ +#define kwc_RealScreenForeground 11 /* RFB 4/92 */ + +/* djhjr - 10/20/01 */ +#define kwm_Name LTYPE_NAME +#define kwm_ResName LTYPE_RES_NAME +#define kwm_ResClass LTYPE_RES_CLASS + +/* + * The following is sorted alphabetically according to name (which must be + * in lowercase and only contain the letters a-z). It is fed to a binary + * search to parse keywords. + */ +static TwmKeyword keytable[] = { + { "all", ALL, 0 }, + + /* djhjr - 4/26/99 */ + { "appletregion", APPLET_REGION, 0 }, + + { "autopan", NKEYWORD, kwn_AutoPan }, + { "autopanborderwidth", NKEYWORD, kwn_AutoPanBorderWidth }, /* DSE */ + { "autopanextrawarp", NKEYWORD, kwn_AutoPanExtraWarp }, /* DSE */ + { "autopanwarpwithrespecttorealscreen", NKEYWORD, + kwn_AutoPanWarpWithRespectToRealScreen }, /* DSE */ + { "autoraise", AUTO_RAISE, 0 }, + { "autoraisedelay", NKEYWORD, kwn_RaiseDelay },/*RAISEDELAY*/ + { "autorelativeresize", KEYWORD, kw0_AutoRelativeResize }, + + /* djhjr - 1/19/98 */ + { "benicetocolormap", KEYWORD, kw0_BeNiceToColormap }, + + /* djhjr - 5/2/98 */ + { "borderbevelwidth", NKEYWORD, kwn_BorderBevelWidth }, + + { "bordercolor", CLKEYWORD, kwcl_BorderColor }, + { "bordertilebackground", CLKEYWORD, kwcl_BorderTileBackground }, + { "bordertileforeground", CLKEYWORD, kwcl_BorderTileForeground }, + { "borderwidth", NKEYWORD, kwn_BorderWidth }, + { "button", BUTTON, 0 }, + + /* djhjr - 8/11/98 */ + { "buttonbevelwidth", NKEYWORD, kwn_ButtonBevelWidth }, + + /* djhjr - 9/21/96 */ + { "buttoncolorisframe", KEYWORD, kw0_ButtonColorIsFrame }, + + { "buttonindent", SNKEYWORD, kwn_ButtonIndent }, + { "c", CONTROL, 0 }, + { "center", JKEYWORD, J_CENTER }, + + /* djhjr - 4/19/96 */ + { "clearbevelcontrast", NKEYWORD, kwn_ClearBevelContrast }, + + { "clientborderwidth", KEYWORD, kw0_ClientBorderWidth }, + { "color", COLOR, 0 }, + { "constrainedmovetime", NKEYWORD, kwn_ConstrainedMoveTime }, + { "control", CONTROL, 0 }, + { "cursors", CURSORS, 0 }, + { "d", VIRTUAL_WIN, 0 }, + + /* djhjr - 4/19/96 */ + { "darkbevelcontrast", NKEYWORD, kwn_DarkBevelContrast }, + + { "decoratetransients", KEYWORD, kw0_DecorateTransients }, + { "defaultbackground", CKEYWORD, kwc_DefaultBackground }, + { "defaultforeground", CKEYWORD, kwc_DefaultForeground }, + { "defaultfunction", DEFAULT_FUNCTION, 0 }, + { "deiconifytoscreen", KEYWORD, kw0_DeIconifyToScreen }, + { "desktop", VIRTUAL_WIN, 0 }, + { "desktopdisplaybackground", + CLKEYWORD, kwcl_VirtualDesktopBackground }, + { "desktopdisplayborder", + CLKEYWORD, kwcl_VirtualDesktopBorder }, + { "desktopdisplayforeground", + CLKEYWORD, kwcl_VirtualDesktopForeground }, + { "destroy", KILL, 0 }, + + /* djhjr - 6/22/99 */ + { "dontdeiconifytransients", KEYWORD, kw0_DontDeiconifyTransients }, + + { "donticonifybyunmapping", DONT_ICONIFY_BY_UNMAPPING, 0 }, + { "dontinterpolatetitles", KEYWORD, kw0_DontInterpolateTitles }, + { "dontmoveoff", KEYWORD, kw0_DontMoveOff }, + { "dontshowindisplay", NO_SHOW_IN_DISPLAY, 0 }, + + /* Submitted by Erik Agsjo */ + { "dontshowintwmwindows", NO_SHOW_IN_TWMWINDOWS, 0 }, + /* djhjr - 6/25/98 */ + { "dontshowinvtwmwindows", NO_SHOW_IN_TWMWINDOWS, 0 }, + + { "dontsqueezetitle", DONT_SQUEEZE_TITLE, 0 }, + { "door", DOOR, 0 }, + { "doorbackground", CLKEYWORD, kwcl_DoorBackground }, + + /* djhjr - 2/7/99 */ + { "doorbevelwidth", NKEYWORD, kwn_DoorBevelWidth }, + + { "doorfont", SKEYWORD, kws_DoorFont }, + { "doorforeground", CLKEYWORD, kwcl_DoorForeground }, + { "doors", DOORS, 0 }, + { "east", DKEYWORD, D_EAST }, + { "enhancedexecresources", KEYWORD, kw0_EnhancedExecResources }, /* DSE */ + { "f", FRAME, 0 }, + { "f.autopan", FKEYWORD, F_AUTOPAN },/*RFB F_AUTOPAN*/ + { "f.autoraise", FKEYWORD, F_AUTORAISE }, + { "f.backiconmgr", FKEYWORD, F_BACKICONMGR }, + { "f.beep", FKEYWORD, F_BEEP }, + + /* Submitted by Seth Robertson - 9/9/02 */ + { "f.bindbuttons", FKEYWORD, F_BINDBUTTONS }, + { "f.bindkeys", FKEYWORD, F_BINDKEYS }, + + { "f.bottomzoom", FKEYWORD, F_BOTTOMZOOM }, + { "f.circledown", FKEYWORD, F_CIRCLEDOWN }, + { "f.circleup", FKEYWORD, F_CIRCLEUP }, + { "f.colormap", FSKEYWORD, F_COLORMAP }, + { "f.cut", FSKEYWORD, F_CUT }, + { "f.cutfile", FKEYWORD, F_CUTFILE }, + { "f.deiconify", FKEYWORD, F_DEICONIFY }, + { "f.delete", FKEYWORD, F_DELETE }, + { "f.deletedoor", FKEYWORD, F_DELETEDOOR }, + { "f.deltastop", FKEYWORD, F_DELTASTOP }, + { "f.destroy", FKEYWORD, F_DESTROY }, + { "f.downiconmgr", FKEYWORD, F_DOWNICONMGR }, + { "f.enterdoor", FKEYWORD, F_ENTERDOOR }, + { "f.exec", FSKEYWORD, F_EXEC }, + { "f.file", FSKEYWORD, F_FILE }, + { "f.focus", FKEYWORD, F_FOCUS }, + { "f.forcemove", FKEYWORD, F_FORCEMOVE }, + { "f.forwiconmgr", FKEYWORD, F_FORWICONMGR }, + { "f.fullzoom", FKEYWORD, F_FULLZOOM }, + { "f.function", FSKEYWORD, F_FUNCTION }, + { "f.hbzoom", FKEYWORD, F_BOTTOMZOOM }, + { "f.hidedesktopdisplay", FKEYWORD, F_HIDEDESKTOP }, + { "f.hideiconmgr", FKEYWORD, F_HIDELIST }, + { "f.horizoom", FKEYWORD, F_HORIZOOM }, + { "f.htzoom", FKEYWORD, F_TOPZOOM }, + { "f.hzoom", FKEYWORD, F_HORIZOOM }, + { "f.iconify", FKEYWORD, F_ICONIFY }, + { "f.identify", FKEYWORD, F_IDENTIFY }, + { "f.lefticonmgr", FKEYWORD, F_LEFTICONMGR }, + { "f.leftzoom", FKEYWORD, F_LEFTZOOM }, + { "f.lower", FKEYWORD, F_LOWER }, + { "f.menu", FSKEYWORD, F_MENU }, + { "f.move", FKEYWORD, F_MOVE }, + { "f.movescreen", FKEYWORD, F_MOVESCREEN }, + { "f.nail", FKEYWORD, F_NAIL }, + { "f.nailedabove", FKEYWORD, F_STICKYABOVE }, /* DSE */ + + /* djhjr - 4/20/98 */ + { "f.namedoor", FKEYWORD, F_NAMEDOOR }, + + { "f.newdoor", FKEYWORD, F_NEWDOOR }, + { "f.nexticonmgr", FKEYWORD, F_NEXTICONMGR }, + { "f.nop", FKEYWORD, F_NOP }, + { "f.pandown", FSKEYWORD, F_PANDOWN }, + { "f.panleft", FSKEYWORD, F_PANLEFT }, + { "f.panright", FSKEYWORD, F_PANRIGHT }, + { "f.panup", FSKEYWORD, F_PANUP }, + + /* djhjr - 11/15/02 */ + { "f.playsound", FSKEYWORD, F_PLAYSOUND }, + + { "f.previconmgr", FKEYWORD, F_PREVICONMGR }, + { "f.quit", FKEYWORD, F_QUIT }, + { "f.raise", FKEYWORD, F_RAISE }, + { "f.raiselower", FKEYWORD, F_RAISELOWER }, + { "f.refresh", FKEYWORD, F_REFRESH }, + { "f.resetdesktop", FKEYWORD, F_RESETDESKTOP }, + { "f.resize", FKEYWORD, F_RESIZE }, + { "f.restart", FKEYWORD, F_RESTART }, + { "f.righticonmgr", FKEYWORD, F_RIGHTICONMGR }, + { "f.rightzoom", FKEYWORD, F_RIGHTZOOM }, + { "f.ring", FKEYWORD, F_RING }, + { "f.saveyourself", FKEYWORD, F_SAVEYOURSELF }, + + /* djhjr - 4/30/96 */ + { "f.separator", FKEYWORD, F_SEPARATOR }, + + { "f.setrealscreen", FSKEYWORD, F_SETREALSCREEN }, + { "f.showdesktopdisplay", FKEYWORD, F_SHOWDESKTOP }, + { "f.showiconmgr", FKEYWORD, F_SHOWLIST }, + { "f.snap", FKEYWORD, F_SNAP }, + { "f.snaprealscreen", FKEYWORD, F_SNAPREALSCREEN }, + { "f.snugdesktop", FKEYWORD, F_SNUGDESKTOP }, + { "f.snugwindow", FKEYWORD, F_SNUGWINDOW }, + { "f.sorticonmgr", FKEYWORD, F_SORTICONMGR }, + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + { "f.sounds", FKEYWORD, F_SOUNDS }, +#endif + + { "f.source", FSKEYWORD, F_BEEP }, /* XXX - don't work */ + { "f.squeezecenter", FKEYWORD, F_SQUEEZECENTER },/*RFB SQUEEZE*/ + { "f.squeezeleft", FKEYWORD, F_SQUEEZELEFT },/*RFB SQUEEZE*/ + { "f.squeezeright", FKEYWORD, F_SQUEEZERIGHT },/*RFB SQUEEZE*/ + + /* djhjr - 7/15/98 */ + { "f.startwm", FSKEYWORD, F_STARTWM }, + + /* djhjr - 12/14/98 */ + { "f.staticiconpositions", FKEYWORD, F_STATICICONPOSITIONS }, + + { "f.stick", FKEYWORD, F_NAIL }, + { "f.stickyabove", FKEYWORD, F_STICKYABOVE }, /* DSE */ + + /* djhjr - 10/2/01 */ + { "f.stricticonmgr", FKEYWORD, F_STRICTICONMGR }, + + { "f.title", FKEYWORD, F_TITLE }, + { "f.topzoom", FKEYWORD, F_TOPZOOM }, + { "f.twmrc", FKEYWORD, F_RESTART }, + + /* Submitted by Seth Robertson - 9/9/02 */ + { "f.unbindbuttons", FKEYWORD, F_UNBINDBUTTONS }, + { "f.unbindkeys", FKEYWORD, F_UNBINDKEYS }, + + { "f.unfocus", FKEYWORD, F_UNFOCUS }, + { "f.upiconmgr", FKEYWORD, F_UPICONMGR }, + { "f.version", FKEYWORD, F_VERSION }, + { "f.virtualgeometries", FKEYWORD, F_VIRTUALGEOMETRIES }, + { "f.vlzoom", FKEYWORD, F_LEFTZOOM }, + { "f.vrzoom", FKEYWORD, F_RIGHTZOOM }, + { "f.warp", FKEYWORD, F_WARP }, /* PF */ + { "f.warpclassnext", FSKEYWORD, F_WARPCLASSNEXT }, /* PF */ + { "f.warpclassprev", FSKEYWORD, F_WARPCLASSPREV }, /* PF */ + { "f.warpring", FSKEYWORD, F_WARPRING }, + + /* djhjr - 5/30/00 */ + { "f.warpsnug", FKEYWORD, F_WARPSNUG }, + + { "f.warpto", FSKEYWORD, F_WARPTO }, + { "f.warptoiconmgr", FSKEYWORD, F_WARPTOICONMGR }, + { "f.warptonewest", FKEYWORD, F_WARPTONEWEST }, /* PF */ + { "f.warptoscreen", FSKEYWORD, F_WARPTOSCREEN }, + + /* submitted by Ugen Antsilevitch - 5/28/00 */ + { "f.warpvisible", FKEYWORD, F_WARPVISIBLE }, + + { "f.winrefresh", FKEYWORD, F_WINREFRESH }, + { "f.zoom", FKEYWORD, F_ZOOM }, + { "f.zoomzoom", FKEYWORD, F_ZOOMZOOM }, + + /* djhjr - 1/6/98 */ + { "fixmanagedvirtualgeometries", KEYWORD, kw0_FixManagedVirtualGeometries }, + + { "fixtransientvirtualgeometries", KEYWORD, + kw0_FixTransientVirtualGeometries }, /* DSE */ + { "forceicons", KEYWORD, kw0_ForceIcons }, + { "frame", FRAME, 0 }, + { "framepadding", NKEYWORD, kwn_FramePadding }, + { "function", FUNCTION, 0 }, + { "i", ICON, 0 }, + { "icon", ICON, 0 }, + { "iconbackground", CLKEYWORD, kwcl_IconBackground }, + + /* djhjr - 8/11/98 */ + { "iconbevelwidth", NKEYWORD, kwn_IconBevelWidth }, + + { "iconbordercolor", CLKEYWORD, kwcl_IconBorderColor }, + { "iconborderwidth", NKEYWORD, kwn_IconBorderWidth }, + { "icondirectory", SKEYWORD, kws_IconDirectory }, + { "iconfont", SKEYWORD, kws_IconFont }, + { "iconforeground", CLKEYWORD, kwcl_IconForeground }, + { "iconifybyunmapping", ICONIFY_BY_UNMAPPING, 0 }, + { "iconmanagerbackground", CLKEYWORD, kwcl_IconManagerBackground }, + + /* djhjr - 5/2/98 */ + { "iconmanagerbevelwidth", NKEYWORD, kwn_IconManagerBevelWidth }, + + { "iconmanagerdontshow", ICONMGR_NOSHOW, 0 }, + { "iconmanagerfont", SKEYWORD, kws_IconManagerFont }, + { "iconmanagerforeground", CLKEYWORD, kwcl_IconManagerForeground }, + { "iconmanagergeometry", ICONMGR_GEOMETRY, 0 }, + { "iconmanagerhighlight", CLKEYWORD, kwcl_IconManagerHighlight }, + + /* djhjr - 10/30/02 */ + { "iconmanagerpixmap", ICONMGRICONMAP, 0 }, + + { "iconmanagers", ICONMGRS, 0 }, + { "iconmanagershow", ICONMGR_SHOW, 0 }, + { "iconmgr", ICONMGR, 0 }, + { "iconregion", ICON_REGION, 0 }, + { "icons", ICONS, 0 }, + + /* djhjr - 9/10/03 */ + { "ignoremodifiers", IGNORE_MODS, 0 }, + + /* djhjr - 5/2/98 */ + { "infobevelwidth", NKEYWORD, kwn_InfoBevelWidth }, + + /* djhjr - 5/10/96 */ + { "infofont", SKEYWORD, kws_InfoFont }, + + { "interpolatemenucolors", KEYWORD, kw0_InterpolateMenuColors }, + { "l", LOCK, 0 }, + { "left", JKEYWORD, J_LEFT }, + { "lefttitlebutton", LEFT_TITLEBUTTON, 0 }, + { "lessrandomzoomzoom", KEYWORD, kw0_LessRandomZoomZoom }, /* DSE */ + { "lock", LOCK, 0 }, + { "m", META, 0 }, + { "maketitle", MAKE_TITLE, 0 }, + { "maxwindowsize", SKEYWORD, kws_MaxWindowSize }, + { "menu", MENU, 0 }, + { "menubackground", CKEYWORD, kwc_MenuBackground }, + + /* djhjr - 5/2/98 */ + { "menubevelwidth", NKEYWORD, kwn_MenuBevelWidth }, + + { "menufont", SKEYWORD, kws_MenuFont }, + { "menuforeground", CKEYWORD, kwc_MenuForeground }, + + /* djhjr - 10/30/02 */ + { "menuiconpixmap", MENUICONMAP, 0 }, + + /* djhjr - 5/22/00 */ + { "menuscrollborderwidth", NKEYWORD, kwn_MenuScrollBorderWidth }, + { "menuscrolljump", NKEYWORD, kwn_MenuScrollJump }, + + { "menushadowcolor", CKEYWORD, kwc_MenuShadowColor }, + { "menutitlebackground", CKEYWORD, kwc_MenuTitleBackground }, + { "menutitlefont", SKEYWORD, kws_MenuTitleFont }, /* DSE */ + { "menutitleforeground", CKEYWORD, kwc_MenuTitleForeground }, + { "meta", META, 0 }, + { "mod", META, 0 }, /* fake it */ + { "monochrome", MONOCHROME, 0 }, + { "move", MOVE, 0 }, + { "movedelta", NKEYWORD, kwn_MoveDelta }, + { "nailedabove", KEYWORD, kw0_StickyAbove }, /* DSE */ + { "naileddown", NAILEDDOWN, 0}, + + /* djhjr - 10/20/01 */ + { "name", MKEYWORD, kwm_Name }, + + { "naturalautopanbehavior", KEYWORD, + kw0_NaturalAutopanBehavior }, /* DSE */ + { "nobackingstore", KEYWORD, kw0_NoBackingStore }, + + /* submitted by Tim Wiess - 8/23/02 */ + { "noborder", NO_BORDER, 0 }, + + /* djhjr - 10/20/02 */ + { "noborderdecorations", KEYWORD, kw0_NoBorderDecorations }, + + { "nocasesensitive", KEYWORD, kw0_NoCaseSensitive }, + { "nodefaultmouseorkeyboardbindings", KEYWORD, + kw0_NoDefaultMouseOrKeyboardBindings }, /* DSE */ + { "nodefaults", KEYWORD, kw0_NoDefaults }, + { "nodefaulttitlebuttons", KEYWORD, kw0_NoDefaultTitleButtons }, /* DSE */ + { "nograbserver", KEYWORD, kw0_NoGrabServer }, + { "nohighlight", NO_HILITE, 0 }, + { "noiconifyiconmanagers", KEYWORD, kw0_NoIconifyIconManagers }, /* PF */ + + /* djhjr - 5/27/98 */ + { "noiconmanagerfocus", KEYWORD, kw0_NoIconManagerFocus }, + + /* djhjr - 1/27/98 */ + { "noiconmanagerhighlight", NO_ICONMGR_HILITE, 0 }, + + { "noiconmanagers", KEYWORD, kw0_NoIconManagers }, + { "nomenushadows", KEYWORD, kw0_NoMenuShadows }, + + /* djhjr - 4/7/98 */ + { "noopaquemove", NO_OPAQUE_MOVE, 0 }, + { "noopaqueresize", NO_OPAQUE_RESIZE, 0 }, + + /* for rader - djhjr - 2/9/99 */ + { "noprettytitles", KEYWORD, kw0_NoPrettyTitles }, + + { "noraiseondeiconify", KEYWORD, kw0_NoRaiseOnDeiconify }, + { "noraiseonmove", KEYWORD, kw0_NoRaiseOnMove }, + { "noraiseonresize", KEYWORD, kw0_NoRaiseOnResize }, + { "noraiseonwarp", KEYWORD, kw0_NoRaiseOnWarp }, + { "north", DKEYWORD, D_NORTH }, + { "nosaveunders", KEYWORD, kw0_NoSaveUnders }, + { "nostackmode", NO_STACKMODE, 0 }, + { "notitle", NO_TITLE, 0 }, + { "notitlefocus", KEYWORD, kw0_NoTitleFocus }, + { "notitlehighlight", NO_TITLE_HILITE, 0 }, + { "notvirtualgeometries", KEYWORD, kw0_NotVirtualGeometries }, + { "noversion", KEYWORD, kw0_NoVersion }, + + /* submitted by Jonathan Paisley - 10/27/02 */ + { "nowindowring", NO_WINDOW_RING, 0 }, + + { "oldfashionedtwmwindowsmenu", KEYWORD, + kw0_OldFashionedTwmWindowsMenu },/*RFB*/ + + /* djhjr - 6/25/98 */ + { "oldfashionedvtwmwindowsmenu", KEYWORD, + kw0_OldFashionedTwmWindowsMenu },/*RFB*/ + +/* djhjr - 4/7/98 + { "opaquemove", KEYWORD, kw0_OpaqueMove }, +*/ + { "opaquemove", OPAQUE_MOVE, 0 }, + + /* djhjr - 4/7/98 */ + { "opaqueresize", OPAQUE_RESIZE, 0 }, + + { "pandistancex", NKEYWORD, kwn_PanDistanceX }, + { "pandistancey", NKEYWORD, kwn_PanDistanceY }, + + /* djhjr - 4/7/98 */ + { "panresistance", NKEYWORD, kwn_PanResistance }, + + /* djhjr - 6/22/01 */ + { "pauseonexit", NKEYWORD, kwn_PauseOnExit }, + { "pauseonquit", NKEYWORD, kwn_PauseOnQuit }, + + { "pixmaps", PIXMAPS, 0 }, + { "pointerplacement", KEYWORD, kw0_PointerPlacement }, + { "prettyzoom", KEYWORD, kw0_PrettyZoom }, /* DSE */ + { "r", ROOT, 0 }, + { "raisedelay", NKEYWORD, kwn_RaiseDelay },/*RAISEDELAY*/ + + /* djhjr - 11/3/03 */ + { "raiseonstart", KEYWORD, kw0_RaiseOnStart }, + + { "randomplacement", KEYWORD, kw0_RandomPlacement }, + { "realscreenbackground", CKEYWORD, kwc_RealScreenBackground },/*RFB 4/92*/ + { "realscreenborderwidth", NKEYWORD, kwn_RealScreenBorderWidth }, /* DSE */ + { "realscreenforeground", CKEYWORD, kwc_RealScreenForeground },/*RFB 4/92*/ + { "realscreenpixmap", REALSCREENMAP, 0 },/*RFB PIXMAP*/ + + /* djhjr - 10/20/01 */ + { "resclass", MKEYWORD, kwm_ResClass }, + + { "resize", RESIZE, 0 }, + { "resizefont", SKEYWORD, kws_ResizeFont }, + + /* djhjr - 5/15/96 */ + { "resizeregion", SKEYWORD, kws_ResizeRegion }, + + /* djhjr - 10/20/01 */ + { "resname", MKEYWORD, kwm_ResName }, + + { "restartpreviousstate", KEYWORD, kw0_RestartPreviousState }, + { "rhspulldownmenus", KEYWORD, kw0_RightHandSidePulldownMenus }, /* DSE */ + { "right", JKEYWORD, J_RIGHT }, + { "righthandsidepulldownmenus", KEYWORD, kw0_RightHandSidePulldownMenus }, /* DSE */ + { "righttitlebutton", RIGHT_TITLEBUTTON, 0 }, + { "root", ROOT, 0 }, + { "s", SHIFT, 0 }, + { "savecolor", SAVECOLOR, 0}, + { "select", SELECT, 0 }, + + /* djhjr - 6/25/96 */ + { "shallowreliefwindowbutton", KEYWORD, kw0_ShallowReliefWindowButton }, + + { "shift", SHIFT, 0 }, + { "showiconmanager", KEYWORD, kw0_ShowIconManager }, + { "snaprealscreen", KEYWORD, kw0_SnapRealScreen }, + { "sorticonmanager", KEYWORD, kw0_SortIconManager }, + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + { "soundhost", SKEYWORD, kws_SoundHost }, + { "sounds", SOUNDS, 0 }, + { "soundvolume", NKEYWORD, kwn_SoundVolume }, +#endif + + { "south", DKEYWORD, D_SOUTH }, + { "squeezetitle", SQUEEZE_TITLE, 0 }, + { "starticonified", START_ICONIFIED, 0 }, + + /* djhjr - 12/14/98 */ + { "staticiconpositions", KEYWORD, kw0_StaticIconPositions }, + + { "stayupmenus", KEYWORD, kw0_StayUpMenus }, + { "stayupoptionalmenus", KEYWORD, kw0_StayUpOptionalMenus }, /* PF */ + { "sticky", NAILEDDOWN, 0 },/*RFB*/ + { "stickyabove", KEYWORD, kw0_StickyAbove }, /* DSE */ + + /* djhjr - 10/2/01 */ + { "stricticonmanager", KEYWORD, kw0_StrictIconManager }, + +/* obsoleted by the ":xpm:*" built-in pixmaps - djhjr - 10/26/02 + * djhjr - 4/25/96 * + { "sunkfocuswindowtitle", KEYWORD, kw0_SunkFocusWindowTitle }, +*/ + + { "t", TITLE, 0 }, + +/* djhjr - 8/11/98 + * djhjr - 4/18/96 * + { "threedborderwidth", NKEYWORD, kwn_ThreeDBorderWidth }, +*/ + + { "title", TITLE, 0 }, + { "titlebackground", CLKEYWORD, kwcl_TitleBackground }, + + /* djhjr - 5/2/98 */ + { "titlebevelwidth", NKEYWORD, kwn_TitleBevelWidth }, + + { "titlebuttonborderwidth", NKEYWORD, kwn_TitleButtonBorderWidth }, + { "titlefont", SKEYWORD, kws_TitleFont }, + { "titleforeground", CLKEYWORD, kwcl_TitleForeground }, + { "titlehighlight", TITLE_HILITE, 0 }, + { "titlepadding", NKEYWORD, kwn_TitlePadding }, + { "unknownicon", SKEYWORD, kws_UnknownIcon }, +/* djhjr - 9/24/02 + { "usepposition", SKEYWORD, kws_UsePPosition }, +*/ + { "usepposition", USE_PPOSITION, 0 }, + +/* djhjr - 2/15/99 - this is dumb - if RealScreenBorderWidth is defined, use it! + { "userealscreenborder", KEYWORD, kw0_UseRealScreenBorder }, *RFB* +*/ + +/* obsoleted by the *BevelWidth resources - djhjr - 8/11/98 + * djhjr - 4/18/96 * + { "usethreedborders", KEYWORD, kw0_Use3DBorders }, + { "usethreediconmanagers", KEYWORD, kw0_Use3DIconManagers }, + + * djhjr - 5/5/98 * + { "usethreedicons", KEYWORD, kw0_Use3DIcons }, + + { "usethreedmenus", KEYWORD, kw0_Use3DMenus }, + { "usethreedtitles", KEYWORD, kw0_Use3DTitles }, +*/ + + { "v", VIRTUAL, 0 }, + { "virtual", VIRTUAL, 0 }, + { "virtualbackground", CKEYWORD, kwc_VirtualBackground },/*RFB VCOLOR*/ + { "virtualbackgroundpixmap", VIRTUALMAP, 0 },/*RFB PIXMAP*/ + { "virtualdesktop", VIRTUALDESKTOP, 0 }, + + /* djhjr - 2/7/99 */ + { "virtualdesktopbevelwidth", NKEYWORD, kwn_VirtualDesktopBevelWidth }, + + { "virtualdesktopfont", SKEYWORD, kws_VirtualFont }, + { "virtualforeground", CKEYWORD, kwc_VirtualForeground },/*RFB VCOLOR*/ + + /* djhjr - 4/17/98 */ + { "virtualreceivesmotionevents", KEYWORD, + kw0_VirtualReceivesMotionEvents }, + { "virtualsendsmotionevents", KEYWORD, + kw0_VirtualSendsMotionEvents }, + + { "w", WINDOW, 0 }, + { "wait", WAIT, 0 }, + + /* djhjr - 10/16/02 */ + { "warpcentered", WARP_CENTERED, 0 }, + + { "warpcursor", WARP_CURSOR, 0 }, + { "warpsnug", KEYWORD, kw0_WarpSnug }, /* DSE */ + { "warptotransients", KEYWORD, kw0_WarpToTransients }, /* PF */ + { "warpunmapped", KEYWORD, kw0_WarpUnmapped }, + + /* submitted by Ugen Antsilevitch - 5/28/00 */ + { "warpvisible", KEYWORD, kw0_WarpVisible }, + + { "warpwindows", KEYWORD, kw0_WarpWindows }, + { "west", DKEYWORD, D_WEST }, + { "window", WINDOW, 0 }, + { "windowfunction", WINDOW_FUNCTION, 0 }, + { "windowring", WINDOW_RING, 0 }, + { "xorvalue", NKEYWORD, kwn_XorValue }, + { "zoom", ZOOM, 0 }, + + /* djhjr - 10/11/01 */ + { "zoomzoom", KEYWORD, kw0_ZoomZoom }, +}; + +static int numkeywords = (sizeof(keytable)/sizeof(keytable[0])); + +int parse_keyword (s, nump) + char *s; + int *nump; +{ + register int lower = 0, upper = numkeywords - 1; + + XmuCopyISOLatin1Lowered (s, s); + while (lower <= upper) { + int middle = (lower + upper) / 2; + TwmKeyword *p = &keytable[middle]; + int res = strcmp (p->name, s); + + if (res < 0) { + lower = middle + 1; + } else if (res == 0) { + *nump = p->subnum; + return p->value; + } else { + upper = middle - 1; + } + } + return ERRORTOKEN; +} + + + +/* + * action routines called by grammar + */ + +int do_single_keyword (keyword) + int keyword; +{ + switch (keyword) { + case kw0_NoDefaults: + Scr->NoDefaultMouseOrKeyboardBindings = TRUE; + Scr->NoDefaultTitleButtons = TRUE; + return 1; + + case kw0_NoDefaultMouseOrKeyboardBindings: /* DSE */ + Scr->NoDefaultMouseOrKeyboardBindings = TRUE; + return 1; + + case kw0_NoDefaultTitleButtons: /* DSE */ + Scr->NoDefaultTitleButtons = TRUE; + return 1; + + case kw0_StayUpMenus: + if (Scr->FirstTime) Scr->StayUpMenus = TRUE; + return 1; + + case kw0_StayUpOptionalMenus: /* PF */ + if (Scr->FirstTime) Scr->StayUpOptionalMenus = Scr->StayUpMenus = TRUE; + return 1; + +/* djhjr - 2/15/99 - this is dumb - if RealScreenBorderWidth is defined, use it! + case kw0_UseRealScreenBorder: *RFB* + Scr->UseRealScreenBorder = TRUE; + return 1; +*/ + + case kw0_OldFashionedTwmWindowsMenu:/*RFB*/ + Scr->OldFashionedTwmWindowsMenu = TRUE; + return 1; + + case kw0_AutoRelativeResize: + Scr->AutoRelativeResize = TRUE; + return 1; + + case kw0_ForceIcons: + if (Scr->FirstTime) Scr->ForceIcon = TRUE; + return 1; + + case kw0_NoIconManagers: + Scr->NoIconManagers = TRUE; + return 1; + + case kw0_NoIconifyIconManagers: /* PF */ + Scr->NoIconifyIconManagers = TRUE; + return 1; + +/* djhjr - 4/7/98 + case kw0_OpaqueMove: + Scr->OpaqueMove = TRUE; + return 1; +*/ + + case kw0_InterpolateMenuColors: + if (Scr->FirstTime) Scr->InterpolateMenuColors = TRUE; + return 1; + + case kw0_NoVersion: + /* obsolete */ + return 1; + + case kw0_SortIconManager: + if (Scr->FirstTime) Scr->SortIconMgr = TRUE; + return 1; + + case kw0_NoGrabServer: + Scr->NoGrabServer = TRUE; + return 1; + + case kw0_NoMenuShadows: + if (Scr->FirstTime) Scr->Shadow = FALSE; + return 1; + + case kw0_NoRaiseOnMove: + if (Scr->FirstTime) Scr->NoRaiseMove = TRUE; + return 1; + + case kw0_NoRaiseOnResize: + if (Scr->FirstTime) Scr->NoRaiseResize = TRUE; + return 1; + + case kw0_NoRaiseOnDeiconify: + if (Scr->FirstTime) Scr->NoRaiseDeicon = TRUE; + return 1; + + case kw0_DontMoveOff: + Scr->DontMoveOff = TRUE; + return 1; + + case kw0_NoBackingStore: + Scr->BackingStore = FALSE; + return 1; + + case kw0_NoSaveUnders: + Scr->SaveUnder = FALSE; + return 1; + + case kw0_RestartPreviousState: + RestartPreviousState = True; + return 1; + + case kw0_ClientBorderWidth: + if (Scr->FirstTime) Scr->ClientBorderWidth = TRUE; + return 1; + + case kw0_NoTitleFocus: + Scr->TitleFocus = FALSE; + return 1; + + case kw0_RandomPlacement: + Scr->RandomPlacement = TRUE; + return 1; + + case kw0_PointerPlacement: + Scr->PointerPlacement = TRUE; + return 1; + + case kw0_DecorateTransients: + Scr->DecorateTransients = TRUE; + return 1; + + case kw0_WarpToTransients: /* PF */ + Scr->WarpToTransients = TRUE; + return 1; + + case kw0_ShowIconManager: + Scr->ShowIconManager = TRUE; + return 1; + + case kw0_NoCaseSensitive: + Scr->CaseSensitive = FALSE; + return 1; + + case kw0_NoRaiseOnWarp: + Scr->NoRaiseWarp = TRUE; + return 1; + + case kw0_WarpUnmapped: + Scr->WarpUnmapped = TRUE; + return 1; + + case kw0_DeIconifyToScreen: + Scr->DeIconifyToScreen = TRUE; + return 1; + + case kw0_WarpWindows: + Scr->WarpWindows = TRUE; + return 1; + + case kw0_SnapRealScreen: + Scr->snapRealScreen = TRUE; + return 1; + + case kw0_NotVirtualGeometries: + Scr->GeometriesAreVirtual = FALSE; + return 1; + + case kw0_NaturalAutopanBehavior: /* DSE */ + Scr->AutoPanWarpWithRespectToRealScreen = 100; + return 1; + case kw0_EnhancedExecResources: /* DSE */ + Scr->EnhancedExecResources = TRUE; + return 1; + case kw0_RightHandSidePulldownMenus: /* DSE */ + Scr->RightHandSidePulldownMenus = TRUE; + return 1; + case kw0_LessRandomZoomZoom: /* DSE */ + Scr->LessRandomZoomZoom = TRUE; + return 1; + case kw0_PrettyZoom: /* DSE */ + Scr->PrettyZoom = TRUE; + return 1; + case kw0_StickyAbove: /* DSE */ + Scr->StickyAbove = TRUE; + return 1; + case kw0_DontInterpolateTitles: /* DSE */ + Scr->DontInterpolateTitles = TRUE; + return 1; + + /* djhjr - 1/6/98 */ + case kw0_FixManagedVirtualGeometries: + Scr->FixManagedVirtualGeometries = TRUE; + return 1; + + case kw0_FixTransientVirtualGeometries: /* DSE */ + Scr->FixTransientVirtualGeometries = TRUE; + return 1; + case kw0_WarpSnug: /* DSE */ + Scr->WarpSnug = TRUE; + return 1; + + /* djhjr - 6/25/96 */ + case kw0_ShallowReliefWindowButton: + Scr->ShallowReliefWindowButton = 1; + return 1; + +/* obsoleted by the *BevelWidth resources - djhjr - 8/11/98 + * djhjr - 4/18/96 * + case kw0_Use3DBorders: + Scr->use3Dborders = TRUE; + return 1; + case kw0_Use3DIconManagers: + Scr->use3Diconmanagers = TRUE; + return 1; + case kw0_Use3DMenus: + Scr->use3Dmenus = TRUE; + return 1; + case kw0_Use3DTitles: + Scr->use3Dtitles = TRUE; + return 1; + + * djhjr - 5/5/98 * + case kw0_Use3DIcons: + Scr->use3Dicons = TRUE; + return 1; +*/ + +/* obsoleted by the ":xpm:*" built-in pixmaps - djhjr - 10/26/02 + * djhjr - 4/25/96 * + case kw0_SunkFocusWindowTitle: + Scr->SunkFocusWindowTitle = TRUE; + return 1; +*/ + + /* djhjr - 9/21/96 */ + case kw0_ButtonColorIsFrame: + Scr->ButtonColorIsFrame = TRUE; + return 1; + + /* djhjr - 1/19/98 */ + case kw0_BeNiceToColormap: + Scr->BeNiceToColormap = TRUE; + return 1; + + /* djhjr - 4/17/98 */ + case kw0_VirtualReceivesMotionEvents: + Scr->VirtualReceivesMotionEvents = TRUE; + return 1; + case kw0_VirtualSendsMotionEvents: + Scr->VirtualSendsMotionEvents = TRUE; + return 1; + + /* djhjr - 5/27/98 */ + case kw0_NoIconManagerFocus: + Scr->IconManagerFocus = FALSE; + return 1; + + /* djhjr - 12/14/98 */ + case kw0_StaticIconPositions: + Scr->StaticIconPositions = TRUE; + return 1; + + /* for rader - djhjr - 2/9/99 */ + case kw0_NoPrettyTitles: + Scr->NoPrettyTitles = TRUE; + return 1; + + /* djhjr - 6/22/99 */ + case kw0_DontDeiconifyTransients: + Scr->DontDeiconifyTransients = TRUE; + return 1; + + /* submitted by Ugen Antsilevitch - 5/28/00 */ + case kw0_WarpVisible: + Scr->WarpVisible = TRUE; + return 1; + + /* djhjr - 10/2/01 */ + case kw0_StrictIconManager: + Scr->StrictIconManager = TRUE; + return 1; + + /* djhjr - 10/11/01 */ + case kw0_ZoomZoom: /* DSE */ + Scr->ZoomZoom = TRUE; + return 1; + + /* djhjr - 10/20/02 */ + case kw0_NoBorderDecorations: /* DSE */ + Scr->NoBorderDecorations = TRUE; + return 1; + + /* djhjr - 11/3/03 */ + case kw0_RaiseOnStart: + Scr->RaiseOnStart = TRUE; + return 1; + } + + return 0; +} + + +int do_string_keyword (keyword, s) + int keyword; + char *s; +{ + /* idea from Seth Robertson - djhjr - 9/17/03 */ + if (s == NULL || s[0] == '\0') + return 0; + + switch (keyword) { +/* now in gram.y - djhjr - 9/24/02 + case kws_UsePPosition: + { + int ppos = ParseUsePPosition (s); + if (ppos < 0) { + twmrc_error_prefix(); + fprintf (stderr, + "ignoring invalid UsePPosition argument \"%s\"\n", s); + } else { + Scr->UsePPosition = ppos; + } + return 1; + } +*/ + + case kws_IconFont: + if (!Scr->HaveFonts) Scr->IconFont.name = s; + return 1; + + case kws_ResizeFont: + if (!Scr->HaveFonts) Scr->SizeFont.name = s; + return 1; + + case kws_MenuFont: + if (!Scr->HaveFonts) Scr->MenuFont.name = s; + return 1; + + case kws_TitleFont: + if (!Scr->HaveFonts) Scr->TitleBarFont.name = s; + return 1; + + case kws_IconManagerFont: + if (!Scr->HaveFonts) Scr->IconManagerFont.name = s; + return 1; + + case kws_MenuTitleFont: /* DSE */ + if (!Scr->HaveFonts) Scr->MenuTitleFont.name = s; + return 1; + + /* djhjr - 5/10/96 */ + case kws_InfoFont: + if (!Scr->HaveFonts) Scr->InfoFont.name = s; + return 1; + + case kws_UnknownIcon: + if (Scr->FirstTime) GetUnknownIcon (s); + return 1; + + case kws_IconDirectory: + if (Scr->FirstTime) Scr->IconDirectory = ExpandFilename (s); + return 1; + + case kws_MaxWindowSize: + JunkMask = XParseGeometry (s, &JunkX, &JunkY, &JunkWidth, &JunkHeight); + if ((JunkMask & (WidthValue | HeightValue)) != + (WidthValue | HeightValue)) { + twmrc_error_prefix(); + fprintf (stderr, "bad MaxWindowSize \"%s\"\n", s); + return 0; + } + if (JunkWidth <= 0 || JunkHeight <= 0) { + twmrc_error_prefix(); + fprintf (stderr, "MaxWindowSize \"%s\" must be positive\n", s); + return 0; + } + Scr->MaxWindowWidth = JunkWidth; + Scr->MaxWindowHeight = JunkHeight; + return 1; + + case kws_VirtualFont: + Scr->NamesInVirtualDesktop = True; + if (!Scr->HaveFonts) Scr->VirtualFont.name = s; + return 1; + + case kws_DoorFont: + if (!Scr->HaveFonts) Scr->DoorFont.name = s; + return 1; + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + case kws_SoundHost: + if (Scr->FirstTime) SetSoundHost(s); + return 1; +#endif + + /* djhjr - 5/15/96 */ + case kws_ResizeRegion: + XmuCopyISOLatin1Lowered (s, s); + if (strcmp (s, "northwest") == 0) + { + Scr->ResizeX = R_NORTHWEST; + return 1; + } + else if (strcmp (s, "northeast") == 0) + { + Scr->ResizeX = R_NORTHEAST; + return 1; + } + if (strcmp (s, "southwest") == 0) + { + Scr->ResizeX = R_SOUTHWEST; + return 1; + } + else if (strcmp (s, "southeast") == 0) + { + Scr->ResizeX = R_SOUTHEAST; + return 1; + } + else if (strcmp (s, "centered") == 0) + { + Scr->ResizeX = R_CENTERED; + return 1; + } + else + { + twmrc_error_prefix(); + fprintf (stderr, "Invalid ResizeRegion \"%s\"\n", s); + return 0; + } + } + + return 0; +} + + +int do_number_keyword (keyword, num) + int keyword; + int num; +{ + switch (keyword) { + case kwn_ConstrainedMoveTime: + ConstrainedMoveTime = num; + return 1; + + case kwn_AutoPanBorderWidth: /* DSE */ + Scr->AutoPanBorderWidth = (num<1)?1:num; + return 1; + + case kwn_AutoPanExtraWarp: /* DSE */ + Scr->AutoPanExtraWarp = (num<0)?0:num; + return 1; + + case kwn_RealScreenBorderWidth: /* DSE */ + Scr->RealScreenBorderWidth = (num < 0) ? 0 : num; + return 1; + + case kwn_MoveDelta: + Scr->MoveDelta = num; + return 1; + + case kwn_XorValue: + if (Scr->FirstTime) Scr->XORvalue = num; + return 1; + + case kwn_FramePadding: + if (Scr->FirstTime) Scr->FramePadding = num; + return 1; + + case kwn_TitlePadding: + if (Scr->FirstTime) Scr->TitlePadding = num; + return 1; + + case kwn_ButtonIndent: + if (Scr->FirstTime) Scr->ButtonIndent = num; + return 1; + + case kwn_BorderWidth: + if (Scr->FirstTime) Scr->BorderWidth = num; + return 1; + + case kwn_IconBorderWidth: + if (Scr->FirstTime) Scr->IconBorderWidth = num; + return 1; + + case kwn_TitleButtonBorderWidth: + if (Scr->FirstTime) Scr->TBInfo.border = num; + return 1; + + case kwn_PanDistanceX: + if (Scr->FirstTime) + { + Scr->VirtualDesktopPanDistanceX = (num * Scr->MyDisplayWidth) / 100; + /* added this - djhjr - 1/4/98 */ + if (Scr->VirtualDesktopPanDistanceX <= 0) Scr->VirtualDesktopPanDistanceX = 1; + } + return 1; + + case kwn_PanDistanceY: + if (Scr->FirstTime) + { + Scr->VirtualDesktopPanDistanceY = (num * Scr->MyDisplayHeight) / 100; + /* added this - djhjr - 1/4/98 */ + if (Scr->VirtualDesktopPanDistanceY <= 0) Scr->VirtualDesktopPanDistanceY = 1; + } + return 1; + + /* djhjr - 9/8/98 */ + case kwn_PanResistance: + if (Scr->FirstTime) Scr->VirtualDesktopPanResistance = num; + if (Scr->VirtualDesktopPanResistance < 0) + Scr->VirtualDesktopPanResistance = 0; + return 1; + + case kwn_RaiseDelay: RaiseDelay = num; return 1;/*RAISEDELAY*/ + + case kwn_AutoPan: + if (Scr->FirstTime) + { + Scr->AutoPanX = (num * Scr->MyDisplayWidth) / 100; + Scr->AutoPanY = (num * Scr->MyDisplayHeight) / 100; + if (Scr->AutoPanX <= 0) Scr->AutoPanX = 1; + if (Scr->AutoPanY <= 0) Scr->AutoPanY = 1; + } + return 1; + + case kwn_AutoPanWarpWithRespectToRealScreen: /* DSE */ + Scr->AutoPanWarpWithRespectToRealScreen = (num<0)?0:(num>100)?100:num; + return 1; + +/* djhjr - 8/11/98 + * djhjr - 4/18/96 * + case kwn_ThreeDBorderWidth: + if (Scr->FirstTime) Scr->ThreeDBorderWidth = num; + return 1; +*/ + + /* djhjr - 4/19/96 */ + case kwn_ClearBevelContrast: + if (Scr->FirstTime) Scr->ClearBevelContrast = num; + if (Scr->ClearBevelContrast < 0) Scr->ClearBevelContrast = 0; + if (Scr->ClearBevelContrast > 100) Scr->ClearBevelContrast = 100; + return 1; + case kwn_DarkBevelContrast: + if (Scr->FirstTime) Scr->DarkBevelContrast = num; + if (Scr->DarkBevelContrast < 0) Scr->DarkBevelContrast = 0; + if (Scr->DarkBevelContrast > 100) Scr->DarkBevelContrast = 100; + return 1; + + /* djhjr - 5/2/98 */ + case kwn_BorderBevelWidth: + if (Scr->FirstTime) Scr->BorderBevelWidth = num; + if (Scr->BorderBevelWidth < 0) Scr->BorderBevelWidth = 0; + if (Scr->BorderBevelWidth > 9) Scr->BorderBevelWidth = 9; + return 1; + case kwn_IconManagerBevelWidth: + if (Scr->FirstTime) Scr->IconMgrBevelWidth = num; + if (Scr->IconMgrBevelWidth < 0) Scr->IconMgrBevelWidth = 0; + if (Scr->IconMgrBevelWidth > 9) Scr->IconMgrBevelWidth = 9; + return 1; + case kwn_InfoBevelWidth: + if (Scr->FirstTime) Scr->InfoBevelWidth = num; + if (Scr->InfoBevelWidth < 0) Scr->InfoBevelWidth = 0; + if (Scr->InfoBevelWidth > 9) Scr->InfoBevelWidth = 9; + return 1; + case kwn_MenuBevelWidth: + if (Scr->FirstTime) Scr->MenuBevelWidth = num; + if (Scr->MenuBevelWidth < 0) Scr->MenuBevelWidth = 0; + if (Scr->MenuBevelWidth > 9) Scr->MenuBevelWidth = 9; + return 1; + case kwn_TitleBevelWidth: + if (Scr->FirstTime) Scr->TitleBevelWidth = num; + if (Scr->TitleBevelWidth < 0) Scr->TitleBevelWidth = 0; + if (Scr->TitleBevelWidth > 9) Scr->TitleBevelWidth = 9; + return 1; + + /* djhjr - 8/11/98 */ + case kwn_ButtonBevelWidth: + if (Scr->FirstTime) Scr->ButtonBevelWidth = num; + if (Scr->ButtonBevelWidth < 0) Scr->ButtonBevelWidth = 0; + if (Scr->ButtonBevelWidth > 9) Scr->ButtonBevelWidth = 9; + return 1; + case kwn_IconBevelWidth: + if (Scr->FirstTime) Scr->IconBevelWidth = num; + if (Scr->IconBevelWidth < 0) Scr->IconBevelWidth = 0; + if (Scr->IconBevelWidth > 9) Scr->IconBevelWidth = 9; + return 1; + + /* djhjr - 2/7/99 */ + case kwn_DoorBevelWidth: + if (Scr->FirstTime) Scr->DoorBevelWidth = num; + if (Scr->DoorBevelWidth < 0) Scr->DoorBevelWidth = 0; + if (Scr->DoorBevelWidth > 9) Scr->DoorBevelWidth = 9; + return 1; + case kwn_VirtualDesktopBevelWidth: + if (Scr->FirstTime) Scr->VirtualDesktopBevelWidth = num; + if (Scr->VirtualDesktopBevelWidth < 0) Scr->VirtualDesktopBevelWidth = 0; + if (Scr->VirtualDesktopBevelWidth > 9) Scr->VirtualDesktopBevelWidth = 9; + return 1; + + /* djhjr - 5/22/00 */ + case kwn_MenuScrollBorderWidth: + if (Scr->FirstTime) Scr->MenuScrollBorderWidth = num; + return 1; + case kwn_MenuScrollJump: + if (Scr->FirstTime) Scr->MenuScrollJump = num; + return 1; + +/* djhjr - 8/16/01 */ +#ifndef NO_SOUND_SUPPORT + case kwn_SoundVolume: + if (Scr->FirstTime) SetSoundVolume(num); + return 1; +#endif + + /* djhjr - 6/22/01 */ + case kwn_PauseOnExit: + if (Scr->FirstTime) Scr->PauseOnExit = num; + return 1; + case kwn_PauseOnQuit: + if (Scr->FirstTime) Scr->PauseOnQuit = num; + return 1; + } + + return 0; +} + +name_list **do_colorlist_keyword (keyword, colormode, s) + int keyword; + int colormode; + char *s; +{ + switch (keyword) { + case kwcl_BorderColor: + GetColor (colormode, &Scr->BorderColor, s); + return &Scr->BorderColorL; + + case kwcl_IconManagerHighlight: + GetColor (colormode, &Scr->IconManagerHighlight, s); + return &Scr->IconManagerHighlightL; + + case kwcl_BorderTileForeground: + GetColor (colormode, &Scr->BorderTileC.fore, s); + return &Scr->BorderTileForegroundL; + + case kwcl_BorderTileBackground: + GetColor (colormode, &Scr->BorderTileC.back, s); + return &Scr->BorderTileBackgroundL; + + case kwcl_TitleForeground: + GetColor (colormode, &Scr->TitleC.fore, s); + return &Scr->TitleForegroundL; + + case kwcl_TitleBackground: + GetColor (colormode, &Scr->TitleC.back, s); + return &Scr->TitleBackgroundL; + + case kwcl_IconForeground: + GetColor (colormode, &Scr->IconC.fore, s); + return &Scr->IconForegroundL; + + case kwcl_IconBackground: + GetColor (colormode, &Scr->IconC.back, s); + return &Scr->IconBackgroundL; + + case kwcl_IconBorderColor: + GetColor (colormode, &Scr->IconBorderColor, s); + return &Scr->IconBorderColorL; + + case kwcl_IconManagerForeground: + GetColor (colormode, &Scr->IconManagerC.fore, s); + return &Scr->IconManagerFL; + + case kwcl_IconManagerBackground: + GetColor (colormode, &Scr->IconManagerC.back, s); + return &Scr->IconManagerBL; + + case kwcl_VirtualDesktopForeground: + GetColor (colormode, &Scr->VirtualDesktopDisplayC.fore, s); + return &Scr->VirtualDesktopColorFL; + + case kwcl_VirtualDesktopBackground: + GetColor (colormode, &Scr->VirtualDesktopDisplayC.back, s); + return &Scr->VirtualDesktopColorBL; + + case kwcl_VirtualDesktopBorder: + GetColor (colormode, &Scr->VirtualDesktopDisplayBorder, s); + return &Scr->VirtualDesktopColorBoL; + + case kwcl_DoorForeground: + GetColor (colormode, &Scr->DoorC.fore, s); + return &Scr->DoorForegroundL; + + case kwcl_DoorBackground: + GetColor (colormode, &Scr->DoorC.back, s); + return &Scr->DoorBackgroundL; + + } + return NULL; +} + +int do_color_keyword (keyword, colormode, s) + int keyword; + int colormode; + char *s; +{ + switch (keyword) { + case kwc_DefaultForeground: + GetColor (colormode, &Scr->DefaultC.fore, s); + return 1; + + case kwc_DefaultBackground: + GetColor (colormode, &Scr->DefaultC.back, s); + return 1; + + case kwc_MenuForeground: + GetColor (colormode, &Scr->MenuC.fore, s); + return 1; + + case kwc_MenuBackground: + GetColor (colormode, &Scr->MenuC.back, s); + return 1; + + case kwc_MenuTitleForeground: + GetColor (colormode, &Scr->MenuTitleC.fore, s); + return 1; + + case kwc_MenuTitleBackground: + GetColor (colormode, &Scr->MenuTitleC.back, s); + return 1; + + case kwc_MenuShadowColor: + GetColor (colormode, &Scr->MenuShadowColor, s); + return 1; + + case kwc_VirtualBackground:/*RFB VCOLOR*/ + GetColor (colormode, &Scr->VirtualC.back, s);/*RFB VCOLOR*/ + return 1;/*RFB VCOLOR*/ + + case kwc_VirtualForeground:/*RFB VCOLOR*/ + GetColor (colormode, &Scr->VirtualC.fore, s);/*RFB VCOLOR*/ + return 1;/*RFB VCOLOR*/ + + case kwc_RealScreenForeground: + GetColor( colormode, &Scr->RealScreenC.fore, s);/*RFB 4/92 */ + return 1; + + case kwc_RealScreenBackground: + GetColor( colormode, &Scr->RealScreenC.back, s);/*RFB 4/92 */ + return 1; + + } + + return 0; +} + +/* + * put_pixel_on_root() Save a pixel value in twm root window color property. + */ +void put_pixel_on_root(pixel) + Pixel pixel; +{ + int i, addPixel = 1; + Atom pixelAtom, retAtom; + int retFormat; + unsigned long nPixels, retAfter; + Pixel *retProp; + + pixelAtom = XInternAtom(dpy, "_MIT_PRIORITY_COLORS", True); + + /* added tests for success - djhjr - 1/10/98 */ + if (XGetWindowProperty(dpy, Scr->Root, pixelAtom, 0, 8192, + False, XA_CARDINAL, &retAtom, + &retFormat, &nPixels, &retAfter, + (unsigned char **)&retProp) != Success || retAtom == None) + return; + + for (i=0; i< nPixels; i++) + if (pixel == retProp[i]) addPixel = 0; + + if (addPixel) + XChangeProperty (dpy, Scr->Root, _XA_MIT_PRIORITY_COLORS, + XA_CARDINAL, 32, PropModeAppend, + (unsigned char *)&pixel, 1); +} + +/* + * do_string_savecolor() save a color from a string in the twmrc file. + */ +void do_string_savecolor(colormode, s) + int colormode; + char *s; +{ + Pixel p = ULONG_MAX; + GetColor(colormode, &p, s); + if (p != ULONG_MAX) + put_pixel_on_root(p); +} + +/* + * do_var_savecolor() save a color from a var in the twmrc file. + */ +typedef struct _cnode {int i; struct _cnode *next;} Cnode, *Cptr; +Cptr chead = NULL; + +void do_var_savecolor(key) +int key; +{ + Cptr cptrav, cpnew; + if (!chead) { + chead = (Cptr)malloc(sizeof(Cnode)); + chead->i = key; chead->next = NULL; + } + else { + cptrav = chead; + while (cptrav->next != NULL) { cptrav = cptrav->next; } + cpnew = (Cptr)malloc(sizeof(Cnode)); + cpnew->i = key; cpnew->next = NULL; cptrav->next = cpnew; + } +} + +/* + * assign_var_savecolor() traverse the var save color list placeing the pixels + * in the root window property. + */ +void assign_var_savecolor() +{ + Cptr cp = chead; + while (cp != NULL) { + switch (cp->i) { + case kwcl_BorderColor: + put_pixel_on_root(Scr->BorderColor); + break; + case kwcl_IconManagerHighlight: + put_pixel_on_root(Scr->IconManagerHighlight); + break; + case kwcl_BorderTileForeground: + put_pixel_on_root(Scr->BorderTileC.fore); + break; + case kwcl_BorderTileBackground: + put_pixel_on_root(Scr->BorderTileC.back); + break; + case kwcl_TitleForeground: + put_pixel_on_root(Scr->TitleC.fore); + break; + case kwcl_TitleBackground: + put_pixel_on_root(Scr->TitleC.back); + break; + case kwcl_IconForeground: + put_pixel_on_root(Scr->IconC.fore); + break; + case kwcl_IconBackground: + put_pixel_on_root(Scr->IconC.back); + break; + case kwcl_IconBorderColor: + put_pixel_on_root(Scr->IconBorderColor); + break; + case kwcl_IconManagerForeground: + put_pixel_on_root(Scr->IconManagerC.fore); + break; + case kwcl_IconManagerBackground: + put_pixel_on_root(Scr->IconManagerC.back); + break; + } + cp = cp->next; + } + if (chead) { + free(chead); + chead = NULL; + } +} + +/* added 'type' argument - djhjr - 10/20/01 */ +void do_squeeze_entry (list, name, type, justify, num, denom) + name_list **list; /* squeeze or dont-squeeze list */ + char *name; /* window name */ + short type; /* match type */ + int justify; /* left, center, right */ + int num; /* signed pixel count or fraction num */ + int denom; /* signed 0 or indicates fraction denom */ +{ + int absnum = (num < 0 ? -num : num); + int absdenom = (denom < 0 ? -denom : denom); + + if (num < 0) { + twmrc_error_prefix(); + fprintf (stderr, "SqueezeTitle numerator %d made positive\n", num); + } + if (denom < 0) { + twmrc_error_prefix(); + fprintf (stderr, "SqueezeTitle denominator %d made positive\n", denom); + } + if (absnum > absdenom && denom != 0) { + twmrc_error_prefix(); + fprintf (stderr, "SqueezeTitle fraction %d/%d outside window\n", + num, denom); + return; + } + if (denom == 1) { + twmrc_error_prefix(); + fprintf (stderr, "useless SqueezeTitle fraction %d/%d, assuming 0/0\n", + num, denom); + absnum = 0; + absdenom = 0; + } + + if (HasShape) { + SqueezeInfo *sinfo; + sinfo = (SqueezeInfo *) malloc (sizeof(SqueezeInfo)); + + if (!sinfo) { + twmrc_error_prefix(); + fprintf (stderr, "unable to allocate %d bytes for squeeze info\n", + sizeof(SqueezeInfo)); + return; + } + sinfo->justify = justify; + sinfo->num = absnum; + sinfo->denom = absdenom; + /* added 'type' argument - djhjr - 10/20/01 */ + AddToList (list, name, type, (char *)sinfo); + } +} + +/* Submitted by Jason Gloudon */ +/* added support for user-defined parameters - djhjr - 2/20/99 */ +/* added support for sound - djhjr - 6/22/01 */ +/* added support for regex - djhjr - 10/20/01 */ +/* added support for i18n - djhjr - 9/14/03 */ +#ifndef NO_M4_SUPPORT +char *make_m4_cmdline(display_name, cp, m4_option) +char *display_name; +char *cp; +char *m4_option; /* djhjr - 2/20/99 */ +{ + char *m4_lines[6] = { + "m4 -DHOME='%s' -DWIDTH='%d' -DHEIGHT='%d' -DSOUND='%s' ", + "-DPLANES='%d' -DBITS_PER_RGB='%d' -DCLASS='%s' -DXPM='%s' ", + "-DI18N='%s' -DCOLOR='%s' -DX_RESOLUTION='%d' -DY_RESOLUTION='%d' ", + "-DREGEX='%s' -DUSER='%s' -DSERVERHOST='%s' -DCLIENTHOST='%s' ", + "-DHOSTNAME='%s' -DTWM_TYPE='vtwm' -DVERSION='%d' ", + "-DREVISION='%d' -DVENDOR='%s' -DRELEASE='%d'" + }; + char *client, *server, *hostname; + char *m4_cmdline, *colon, *vc, *env_username; + char *is_sound, *is_xpm, *is_regex, *is_color, *is_i18n; + int i, client_len, opt_len = 0, cmd_len = 0, server_is_client = 0; + struct hostent *hostname_ent; + + /* djhjr - 2/20/99 */ + if (m4_option) + { + opt_len = strlen(m4_option); + + /* this isn't likely ever needed, but you just never know... */ + if (m4_option[0] == '\'' || m4_option[0] == '"') + { + if (m4_option[opt_len - 1] != '\'' && m4_option[opt_len - 1] != '"') + { + fprintf(stderr,"%s: badly formed user-defined m4 parameter\n", ProgramName); + return (NULL); + } + else + { + m4_option++; + opt_len -= 2; + } + } + } + + /* the sourcing of various hostnames is stolen from tvtwm */ + /* pad for NULL terminator - submitted by Jonathan Paisley - 11/11/02 */ + for(client = NULL, client_len = 256; client_len < 1024; client_len *= 2){ + if((client = malloc(client_len + 1)) == NULL){ + fprintf(stderr,"%s: cannot allocate %d bytes for m4\n", ProgramName, client_len + 1); + return (NULL); + } + + client[client_len] = '\0'; + XmuGetHostname(client, client_len); + + if(client[client_len] == '\0') + break; + + free(client); + client = NULL; + } + + if(client == NULL){ + fprintf(stderr, "%s: cannot get hostname for m4\n", ProgramName); + return (NULL); + } + + if((server = XDisplayName(display_name)) == NULL){ + fprintf(stderr, "%s: cannot get display name for m4\n", ProgramName); + return (NULL); + } + + /* we copy so we can modify it safely */ + server = strdup(server); + + if((colon = index(server, ':')) != NULL){ + *colon = '\0'; + } + + /* connected to :0 or unix:0 ? */ + if((server[0] == '\0') || (!strcmp(server, "unix"))){ + if (colon){ + *colon = ':'; + colon = NULL; + } + free(server); + server = client; + server_is_client = 1; + } + + hostname_ent = gethostbyname(client); + hostname = hostname_ent != NULL ? hostname_ent->h_name : client; + +#ifdef NO_XPM_SUPPORT + is_xpm = "No"; +#else + is_xpm = "Yes"; +#endif +#ifdef NO_SOUND_SUPPORT + is_sound = "No"; +#else + is_sound = "Yes"; +#endif +#ifdef NO_REGEX_SUPPORT + is_regex = "No"; +#else + is_regex = "Yes"; +#endif +#ifdef NO_I18N_SUPPORT + is_i18n = "No"; +#else + is_i18n = "Yes"; +#endif + + /* assume colour visual */ + is_color = "Yes"; + switch(Scr->d_visual->class) + { + case(StaticGray): vc = "StaticGray"; is_color = "No"; break; + case(GrayScale): vc = "GrayScale"; is_color = "No"; break; + case(StaticColor): vc = "StaticColor"; break; + case(PseudoColor): vc = "PseudoColor"; break; + case(TrueColor): vc = "TrueColor"; break; + case(DirectColor): vc = "DirectColor"; break; + default: vc = "NonStandard"; break; + } + + if((env_username = getenv("LOGNAME")) == NULL){ + env_username = ""; + } + + /* + * Start with slightly more than the minimal command line, add space for + * nine numeric fields, ensure we have room for each of the strings, and + * add some breathing room + * + * Then add space for any user-defined parameters - djhjr - 2/20/99 + */ + for (i = 0; i < 6; i++) cmd_len += strlen(m4_lines[i]); + cmd_len += M4_MAXDIGITS * 9 + HomeLen + strlen(vc) + strlen(is_xpm) + + strlen(is_color) + strlen(env_username) + strlen(server) + + strlen(client) + strlen(hostname) + strlen(ServerVendor(dpy)) + + strlen(is_sound) + strlen(is_regex) + strlen(is_i18n) + strlen(cp) + 16; + if (opt_len) cmd_len += opt_len; + + if((m4_cmdline = malloc(cmd_len)) == NULL){ + fprintf(stderr,"%s: cannot allocate %d bytes for m4\n", ProgramName, cmd_len); + return (NULL); + } + + /* + * Non-SysV systems - specifically, BSD-derived systems - return a + * pointer to the string, not its length. + */ + sprintf(m4_cmdline, m4_lines[0], Home, Scr->MyDisplayWidth, + Scr->MyDisplayHeight, is_sound); + cmd_len = strlen(m4_cmdline); + sprintf(m4_cmdline + cmd_len, m4_lines[1], Scr->d_depth, + Scr->d_visual->bits_per_rgb, vc, is_xpm); + cmd_len = strlen(m4_cmdline); + sprintf(m4_cmdline + cmd_len, m4_lines[2], is_i18n, is_color, + Resolution(Scr->MyDisplayWidth, DisplayWidthMM(dpy, Scr->screen)), + Resolution(Scr->MyDisplayHeight, DisplayHeightMM(dpy, Scr->screen))); + cmd_len = strlen(m4_cmdline); + sprintf(m4_cmdline + cmd_len, m4_lines[3], is_regex, env_username, + server, client); + cmd_len = strlen(m4_cmdline); + sprintf(m4_cmdline + cmd_len, m4_lines[4], hostname, ProtocolVersion(dpy)); + cmd_len = strlen(m4_cmdline); + sprintf(m4_cmdline + cmd_len, m4_lines[5], ProtocolRevision(dpy), + ServerVendor(dpy), VendorRelease(dpy)); + + /* djhjr - 2/20/99 */ + cmd_len = strlen(m4_cmdline); + if (opt_len) + { + sprintf(m4_cmdline + cmd_len, " %*.*s", opt_len, opt_len, m4_option); + cmd_len = strlen(m4_cmdline); + } + sprintf(m4_cmdline + cmd_len, " < %s", cp); + + if (PrintErrorMessages) + fprintf(stderr, "\n%s: %s\n", ProgramName, m4_cmdline); + + if (colon) *colon = ':'; + if (!server_is_client) free(server); + free(client); + + return (m4_cmdline); +} +#endif /* NO_M4_SUPPORT */ + diff --git a/parse.h b/parse.h new file mode 100644 index 0000000..4c7d4b2 --- /dev/null +++ b/parse.h @@ -0,0 +1,192 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/********************************************************************** + * + * $XConsortium: parse.h,v 1.14 89/12/14 14:51:25 jim Exp $ + * + * .twmrc parsing externs + * + * 8-Apr-88 Tom LaStrange Initial Version. + * + **********************************************************************/ + +#ifndef _PARSE_ +#define _PARSE_ + +extern int ParseTwmrc(), ParseStringList(); +extern int (*twmInputFunc)(); +extern void twmUnput(); +extern void TwmOutput(); + +/* + * This is private to VTWM, to indicate no or invalid functions. + * + * djhjr - 4/20/98 + */ +#define F_NOFUNCTION 0 + +#define F_NOP 0 +#define F_BEEP 1 +#define F_RESTART 2 +#define F_QUIT 3 +#define F_FOCUS 4 +#define F_REFRESH 5 +#define F_WINREFRESH 6 +#define F_DELTASTOP 7 +#define F_MOVE 8 +#define F_POPUP 9 +#define F_FORCEMOVE 10 +#define F_AUTORAISE 11 +#define F_IDENTIFY 12 +#define F_ICONIFY 13 +#define F_DEICONIFY 14 +#define F_UNFOCUS 15 +#define F_RESIZE 16 +#define F_ZOOM 17 +#define F_LEFTZOOM 18 +#define F_RIGHTZOOM 19 +#define F_TOPZOOM 20 +#define F_BOTTOMZOOM 21 +#define F_HORIZOOM 22 +#define F_FULLZOOM 23 +#define F_RAISE 24 +#define F_RAISELOWER 25 +#define F_LOWER 26 +#define F_DESTROY 27 +#define F_DELETE 28 +#define F_SAVEYOURSELF 29 +#define F_VERSION 30 +#define F_TITLE 31 +#define F_RIGHTICONMGR 32 +#define F_LEFTICONMGR 33 +#define F_UPICONMGR 34 +#define F_DOWNICONMGR 35 +#define F_FORWICONMGR 36 +#define F_BACKICONMGR 37 +#define F_NEXTICONMGR 38 +#define F_PREVICONMGR 39 +#define F_SORTICONMGR 40 +#define F_CIRCLEUP 41 +#define F_CIRCLEDOWN 42 +#define F_CUTFILE 43 +#define F_SHOWLIST 44 +#define F_HIDELIST 45 +#define F_NAIL 46 +#define F_PANDOWN 47 +#define F_PANLEFT 48 +#define F_PANRIGHT 49 +#define F_PANUP 50 +#define F_RESETDESKTOP 51 +#define F_MOVESCREEN 52 +#define F_SNAP 53 +#define F_HIDEDESKTOP 54 +#define F_SHOWDESKTOP 55 +#define F_ENTERDOOR 56 +#define F_NEWDOOR 57 +#define F_SNUGDESKTOP 58 +#define F_SNUGWINDOW 59 +#define F_AUTOPAN 60/*RFB F_AUTOPAN*/ +#define F_RING 61/*RFB F_RING*/ +#define F_SQUEEZELEFT 62/*RFB F_SQUEEZE*/ +#define F_SQUEEZERIGHT 63/*RFB F_SQUEEZE*/ +#define F_SQUEEZECENTER 64/*RFB F_SQUEEZE*/ +#define F_SNAPREALSCREEN 65/*RFB F_SNAPREALSCREEN*/ +#define F_VIRTUALGEOMETRIES 66/*marcel@duteca.et.tudelft.nl*/ +#define F_DELETEDOOR 67/*marcel@duteca.et.tudelft.nl*/ +#define F_ZOOMZOOM 68 /* RFB silly */ +#define F_WARP 69 /* PF */ +#define F_STICKYABOVE 70 /* DSE */ + +#define F_MENU 101 /* string */ +#define F_WARPTO 102 /* string */ +#define F_WARPTOICONMGR 103 /* string */ +#define F_WARPRING 104 /* string */ +#define F_FILE 105 /* string */ +#define F_EXEC 106 /* string */ +#define F_CUT 107 /* string */ +#define F_FUNCTION 108 /* string */ +#define F_WARPTOSCREEN 109 /* string */ +#define F_COLORMAP 110 /* string */ +#define F_SETREALSCREEN 111 /* string */ +#define F_WARPCLASSNEXT 112 /* string -- PF */ +#define F_WARPCLASSPREV 113 /* string -- PF */ +#define F_WARPTONEWEST 114 /* string -- PF */ + +/* djhjr - 4/30/96 */ +#define F_SEPARATOR 115 + +/* djhjr - 4/20/98 */ +#define F_NAMEDOOR 116 + +/* djhjr - 7/15/98 */ +#define F_STARTWM 117 + +/* djhjr - 12/14/98 */ +#define F_STATICICONPOSITIONS 118 + +/* submitted by Ugen Antsilevitch - 5/28/00 */ +#define F_WARPVISIBLE 119 + +/* djhjr - 5/30/00 */ +#define F_WARPSNUG 120 + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT +#define F_SOUNDS 121 +#endif + +/* djhjr - 10/2/01 */ +#define F_STRICTICONMGR 122 + +/* Next four submitted by Seth Robertson - 9/9/02 */ +#define F_BINDBUTTONS 123 +#define F_BINDKEYS 124 +#define F_UNBINDBUTTONS 125 +#define F_UNBINDKEYS 126 + +/* djhjr - 11/15/02 */ +#define F_PLAYSOUND 127 + +#define D_NORTH 1 +#define D_SOUTH 2 +#define D_EAST 3 +#define D_WEST 4 + +/* djhjr - 5/15/96 */ +#define R_NORTH 1 +#define R_NORTHEAST 2 +#define R_EAST 3 +#define R_SOUTHEAST 4 +#define R_SOUTH 5 +#define R_SOUTHWEST 6 +#define R_WEST 7 +#define R_NORTHWEST 8 +#define R_CENTERED 9 + +#endif /* _PARSE_ */ diff --git a/regions.c b/regions.c new file mode 100644 index 0000000..1067f1c --- /dev/null +++ b/regions.c @@ -0,0 +1,258 @@ +/* + * Copyright 1989 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/********************************************************************** + * + * regions.c + * + * Region related routines + * + * 4/26/99 D. J. Hawkey Jr. + * + **********************************************************************/ + +#include +#include +#include "twm.h" +#include "screen.h" +#include "list.h" +#include "regions.h" +#include "gram.h" +#include "parse.h" +#include "util.h" + +void +splitRegionEntry (re, grav1, grav2, w, h) + RegionEntry *re; + int grav1, grav2; + int w, h; +{ + RegionEntry *new; + + switch (grav1) { + case D_NORTH: + case D_SOUTH: + if (w != re->w) + splitRegionEntry (re, grav2, grav1, w, re->h); + if (h != re->h) { + new = (RegionEntry *)malloc (sizeof (RegionEntry)); + new->u.twm_win = 0; + /* djhjr - 10/20/01 */ + new->type = LTYPE_EXACT_NAME; + new->usedby = 0; + new->next = re->next; + re->next = new; + new->x = re->x; + new->h = (re->h - h); + new->w = re->w; + re->h = h; + if (grav1 == D_SOUTH) { + new->y = re->y; + re->y = new->y + new->h; + } else + new->y = re->y + re->h; + } + break; + case D_EAST: + case D_WEST: + if (h != re->h) + splitRegionEntry (re, grav2, grav1, re->w, h); + if (w != re->w) { + new = (RegionEntry *)malloc (sizeof (RegionEntry)); + new->u.twm_win = 0; + /* djhjr - 10/20/01 */ + new->type = LTYPE_EXACT_NAME; + new->usedby = 0; + new->next = re->next; + re->next = new; + new->y = re->y; + new->w = (re->w - w); + new->h = re->h; + re->w = w; + if (grav1 == D_EAST) { + new->x = re->x; + re->x = new->x + new->w; + } else + new->x = re->x + re->w; + } + break; + } +} + +int +roundEntryUp (v, multiple) +{ + return ((v + multiple - 1) / multiple) * multiple; +} + +RegionEntry * +prevRegionEntry (re, rr) + RegionEntry *re; + RootRegion *rr; +{ + RegionEntry *ep; + + if (re == rr->entries) + return 0; + for (ep = rr->entries; ep->next != re; ep=ep->next) + ; + return ep; +} + +/* + * old is being freed; and is adjacent to re. Merge regions together. + */ +void +mergeRegionEntries (old, re) + RegionEntry *old, *re; +{ + if (old->y == re->y) { + re->w = old->w + re->w; + if (old->x < re->x) + re->x = old->x; + } else { + re->h = old->h + re->h; + if (old->y < re->y) + re->y = old->y; + } +} + +void +downRegionEntry(rr, re) +RootRegion *rr; +RegionEntry *re; +{ + RegionEntry *ep, *en; + + re->u.twm_win = 0; + re->usedby = 0; + ep = prevRegionEntry (re, rr); + en = re->next; + for (;;) { + if (ep && ep->usedby == 0 && + ((ep->x == re->x && ep->w == re->w) || + (ep->y == re->y && ep->h == re->h))) + { + ep->next = re->next; + mergeRegionEntries (re, ep); + if (re->usedby == USEDBY_NAME) + free(re->u.name); +/* djhjr - 10/20/01 */ +#ifndef NO_REGEX_SUPPORT + if (re->type & LTYPE_C_REGEXP) + regfree(&re->re); +#endif + free ((char *) re); + re = ep; + ep = prevRegionEntry (ep, rr); + } else if (en && en->usedby == 0 && + ((en->x == re->x && en->w == re->w) || + (en->y == re->y && en->h == re->h))) + { + re->next = en->next; + mergeRegionEntries (en, re); + if (en->usedby == USEDBY_NAME) + free(en->u.name); +/* djhjr - 10/20/01 */ +#ifndef NO_REGEX_SUPPORT + if (en->type & LTYPE_C_REGEXP) + regfree(&en->re); +#endif + free ((char *) en); + en = re->next; + } else + break; + } +} + +RootRegion * +AddRegion(geom, grav1, grav2, stepx, stepy) +char *geom; +int grav1, grav2, stepx, stepy; +{ + RootRegion *rr; + int mask; + + rr = (RootRegion *)malloc(sizeof(RootRegion)); + rr->next = NULL; + rr->grav1 = grav1; + rr->grav2 = grav2; + rr->stepx = (stepx <= 0) ? 2 : stepx; /* hard-coded value was '1' - djhjr - 9/26/99 */ + rr->stepy = (stepy <= 0) ? 1 : stepy; + rr->x = rr->y = rr->w = rr->h = 0; + + mask = XParseGeometry(geom, &rr->x, &rr->y, (unsigned int *)&rr->w, (unsigned int *)&rr->h); + if (mask & XNegative) + rr->x += Scr->MyDisplayWidth - rr->w; + if (mask & YNegative) + rr->y += Scr->MyDisplayHeight - rr->h; + + rr->entries = (RegionEntry *)malloc(sizeof(RegionEntry)); + rr->entries->next = 0; + rr->entries->x = rr->x; + rr->entries->y = rr->y; + rr->entries->w = rr->w; + rr->entries->h = rr->h; + rr->entries->u.twm_win = 0; + /* djhjr - 10/20/01 */ + rr->entries->type = LTYPE_EXACT_NAME; + rr->entries->usedby = 0; + + return rr; +} + +void +FreeRegionEntries (rr) + RootRegion *rr; +{ + RegionEntry *re, *tmp; + + for (re = rr->entries; re; re=tmp) + { + tmp = re->next; + if (re->usedby == USEDBY_NAME) + free(re->u.name); +/* djhjr - 10/20/01 */ +#ifndef NO_REGEX_SUPPORT + if (re->type & LTYPE_C_REGEXP) + regfree(&re->re); +#endif + free ((char *) re); + } +} + +void +FreeRegions (first, last) + RootRegion *first, *last; +{ + RootRegion *rr, *tmp; + + for (rr = first; rr != NULL;) + { + tmp = rr; + FreeRegionEntries (rr); + rr = rr->next; + free((char *) tmp); + } + first = NULL; + last = NULL; +} + diff --git a/regions.h b/regions.h new file mode 100644 index 0000000..bad1631 --- /dev/null +++ b/regions.h @@ -0,0 +1,76 @@ +/* + * Copyright 1989 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/********************************************************************** + * + * regions.h (was icons.h) + * + * Region related definitions + * + * 4/26/99 D. J. Hawkey Jr. + * + **********************************************************************/ + +#ifndef REGIONS_H +#define REGIONS_H + +#define USEDBY_TWIN 1 +#define USEDBY_NAME 2 + +/* djhjr - 10/20/01 */ +#ifndef NO_REGEX_SUPPORT +#include +#include +#endif + +typedef struct RootRegion +{ + struct RootRegion *next; + int x, y, w, h; + int grav1, grav2; + int stepx, stepy; + struct RegionEntry *entries; +} RootRegion; + +typedef struct RegionEntry +{ + struct RegionEntry *next; + int x, y, w, h; + + /* icons use twm_win, applets use both - djhjr - 4/26/99 */ + union + { + TwmWindow *twm_win; + char *name; + } u; + +/* djhjr - 10/20/01 */ +#ifndef NO_REGEX_SUPPORT + regex_t re; +#else + char re; +#endif + short type; + + short usedby; +} RegionEntry; + +#endif /* REGIONS_H */ diff --git a/resize.c b/resize.c new file mode 100644 index 0000000..6c77281 --- /dev/null +++ b/resize.c @@ -0,0 +1,1906 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/*********************************************************************** + * + * $XConsortium: resize.c,v 1.80 91/05/11 17:35:42 dave Exp $ + * + * window resizing borrowed from the "wm" window manager + * + * 11-Dec-87 Thomas E. LaStrange File created + * + ***********************************************************************/ + +#include +#include "twm.h" +#include "parse.h" +#include "util.h" +#include "resize.h" +#include "add_window.h" +#include "screen.h" +#include "desktop.h" +#include "events.h" +#include "menus.h" + +#define MINHEIGHT 0 /* had been 32 */ +#define MINWIDTH 0 /* had been 60 */ + +static int dragx; /* all these variables are used */ +static int dragy; /* in resize operations */ +static int dragWidth; +static int dragHeight; + +int origx; +int origy; +int origWidth; +int origHeight; + +static int clampTop; +static int clampBottom; +static int clampLeft; +static int clampRight; +static int clampDX; +static int clampDY; + +static int last_width; +static int last_height; + +static int resize_context; + +/* set in menus.c:ExecuteFunction(), cleared in *EndResize() - djhjr - 9/5/98 */ +int resizing_window = 0; + +/* djhjr - 4/6/98 */ +void PaintBorderAndTitlebar(); + +/* djhjr - 4/17/98 */ +static void DoVirtualMoveResize(); + +/* djhjr - 9/10/99 */ +void ResizeTwmWindowContents(); + +/* djhjr - 9/13/02 */ +static void SetVirtualDesktopIncrs(); +static void EndResizeAdjPointer(); + +static void do_auto_clamp (tmp_win, evp) + TwmWindow *tmp_win; + XEvent *evp; +{ + Window junkRoot; + int x, y, h, v, junkbw; + unsigned int junkMask; + + switch (evp->type) { + case ButtonPress: + x = evp->xbutton.x_root; + y = evp->xbutton.y_root; + break; + case KeyPress: + x = evp->xkey.x_root; + y = evp->xkey.y_root; + break; + default: + if (!XQueryPointer (dpy, Scr->Root, &junkRoot, &junkRoot, + &x, &y, &junkbw, &junkbw, &junkMask)) + return; + } + + h = ((x - dragx) / (dragWidth < 3 ? 1 : (dragWidth / 3))); + v = ((y - dragy - tmp_win->title_height) / + (dragHeight < 3 ? 1 : (dragHeight / 3))); + + if (h <= 0) { + clampLeft = 1; + clampDX = (x - dragx); + } else if (h >= 2) { + clampRight = 1; + clampDX = (x - dragx - dragWidth); + } + + if (v <= 0) { + clampTop = 1; + clampDY = (y - dragy); + } else if (v >= 2) { + clampBottom = 1; + clampDY = (y - dragy - dragHeight); + } +} + + +/*********************************************************************** + * + * Procedure: + * StartResize - begin a window resize operation + * + * Inputs: + * ev - the event structure (button press) + * tmp_win - the TwmWindow pointer + * fromtitlebar - action invoked from titlebar button + * + *********************************************************************** + */ + +void +StartResize(evp, tmp_win, fromtitlebar, context) +XEvent *evp; +TwmWindow *tmp_win; +Bool fromtitlebar; +int context; +{ + Window junkRoot; + unsigned int junkbw, junkDepth; + + resize_context = context; + + SetVirtualDesktopIncrs(tmp_win); /* djhjr - 9/13/02 */ + + if (context == C_VIRTUAL_WIN) + ResizeWindow = tmp_win->VirtualDesktopDisplayWindow; + else + ResizeWindow = tmp_win->frame; + +/* djhjr - 7/17/98 + * djhjr - 4/15/98 * + if (!Scr->NoGrabServer) +*/ + { + /* added test - djhjr - 4/7/98 */ + if (!tmp_win->opaque_resize) + XGrabServer(dpy); + } + if (context == C_VIRTUAL_WIN) + XGrabPointer(dpy, Scr->VirtualDesktopDisplay, True, + ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | PointerMotionHintMask, + GrabModeAsync, GrabModeAsync, + Scr->Root, Scr->ResizeCursor, CurrentTime); + else + XGrabPointer(dpy, Scr->Root, True, + ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | PointerMotionHintMask, + GrabModeAsync, GrabModeAsync, + Scr->Root, Scr->ResizeCursor, CurrentTime); + + XGetGeometry(dpy, (Drawable) ResizeWindow, &junkRoot, + &dragx, &dragy, (unsigned int *)&dragWidth, (unsigned int *)&dragHeight, &junkbw, + &junkDepth); + + if (context != C_VIRTUAL_WIN) { + dragx += tmp_win->frame_bw; + dragy += tmp_win->frame_bw; + } + origx = dragx; + origy = dragy; + origWidth = dragWidth; + origHeight = dragHeight; + clampTop = clampBottom = clampLeft = clampRight = clampDX = clampDY = 0; + + if (Scr->AutoRelativeResize && !fromtitlebar) + do_auto_clamp (tmp_win, evp); + +/* use initialized size... djhjr - 5/9/96 + Scr->SizeStringOffset = SIZE_HINDENT; + XResizeWindow (dpy, Scr->SizeWindow, + Scr->SizeStringWidth + SIZE_HINDENT * 2, + Scr->SizeFont.height + SIZE_VINDENT * 2); +*/ + + XMapRaised(dpy, Scr->SizeWindow); + if (!tmp_win->opaque_resize) InstallRootColormap(); + last_width = 0; + last_height = 0; + DisplaySize(tmp_win, origWidth, origHeight); + + if (resize_context == C_VIRTUAL_WIN) + MoveOutline (Scr->VirtualDesktopDisplay, dragx, + dragy, dragWidth, + dragHeight, + tmp_win->frame_bw, 0); + else + /* added this 'if ... else' - djhjr - 4/6/98 */ + if (tmp_win->opaque_resize) + { + SetupWindow (tmp_win, + dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw, + dragWidth, dragHeight, -1); + PaintBorderAndTitlebar(tmp_win); + } + else + MoveOutline (Scr->Root, dragx - tmp_win->frame_bw, + dragy - tmp_win->frame_bw, dragWidth + 2 * tmp_win->frame_bw, + dragHeight + 2 * tmp_win->frame_bw, +/* djhjr - 4/24/96 + tmp_win->frame_bw, tmp_win->title_height); +*/ + tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); +} + + + +/* added the passed 'context' - djhjr - 2/22/99 */ +void +MenuStartResize(tmp_win, x, y, w, h, context) +TwmWindow *tmp_win; +int x, y, w, h; +int context; +{ + /* djhjr - 2/22/99 */ + resize_context = context; + + SetVirtualDesktopIncrs(tmp_win); /* djhjr - 9/13/02 */ + +/* djhjr - 7/17/98 + * djhjr - 4/15/98 * + if (!Scr->NoGrabServer) +*/ + { + /* added test - djhjr - 4/7/98 */ + if (!tmp_win->opaque_resize) + XGrabServer(dpy); + } + XGrabPointer(dpy, Scr->Root, True, + ButtonPressMask | ButtonMotionMask | PointerMotionMask, + GrabModeAsync, GrabModeAsync, + Scr->Root, Scr->ResizeCursor, CurrentTime); + dragx = x + tmp_win->frame_bw; + dragy = y + tmp_win->frame_bw; + origx = dragx; + origy = dragy; + dragWidth = origWidth = w; /* - 2 * tmp_win->frame_bw; */ + dragHeight = origHeight = h; /* - 2 * tmp_win->frame_bw; */ + clampTop = clampBottom = clampLeft = clampRight = clampDX = clampDY = 0; + last_width = 0; + last_height = 0; + +/* use initialized size... djhjr - 5/9/96 + Scr->SizeStringOffset = SIZE_HINDENT; + XResizeWindow (dpy, Scr->SizeWindow, + Scr->SizeStringWidth + SIZE_HINDENT * 2, + Scr->SizeFont.height + SIZE_VINDENT * 2); +*/ + + XMapRaised(dpy, Scr->SizeWindow); + if (!tmp_win->opaque_resize) InstallRootColormap(); + DisplaySize(tmp_win, origWidth, origHeight); + + /* added this 'if ... else' - djhjr - 4/6/98 */ + if (tmp_win->opaque_resize) + { + SetupWindow (tmp_win, + dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw, + dragWidth, dragHeight, -1); + PaintBorderAndTitlebar(tmp_win); + } + else + MoveOutline (Scr->Root, dragx - tmp_win->frame_bw, + dragy - tmp_win->frame_bw, + dragWidth + 2 * tmp_win->frame_bw, + dragHeight + 2 * tmp_win->frame_bw, +/* djhjr - 4/23/96 + tmp_win->frame_bw, tmp_win->title_height); +*/ + tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); +} + +/*********************************************************************** + * + * Procedure: + * AddStartResize - begin a windorew resize operation from AddWindow + * + * Inputs: + * tmp_win - the TwmWindow pointer + * + *********************************************************************** + */ + +void +AddStartResize(tmp_win, x, y, w, h) +TwmWindow *tmp_win; +int x, y, w, h; +{ + /* djhjr - 2/22/99 */ + resize_context = C_WINDOW; + + SetVirtualDesktopIncrs(tmp_win); /* djhjr - 9/13/02 */ + +/* djhjr - 7/17/98 + * djhjr - 4/15/98 * + if (!Scr->NoGrabServer) +*/ + { + /* added test - djhjr - 4/7/98 */ + if (!tmp_win->opaque_resize) + XGrabServer(dpy); + } + + XGrabPointer(dpy, Scr->Root, True, + ButtonReleaseMask | ButtonMotionMask | PointerMotionHintMask, + GrabModeAsync, GrabModeAsync, + Scr->Root, Scr->ResizeCursor, CurrentTime); + + dragx = x + tmp_win->frame_bw; + dragy = y + tmp_win->frame_bw; + origx = dragx; + origy = dragy; + dragWidth = origWidth = w - 2 * tmp_win->frame_bw; + dragHeight = origHeight = h - 2 * tmp_win->frame_bw; + clampTop = clampBottom = clampLeft = clampRight = clampDX = clampDY = 0; +/***** + if (Scr->AutoRelativeResize) { + clampRight = clampBottom = 1; + } +*****/ + last_width = 0; + last_height = 0; + DisplaySize(tmp_win, origWidth, origHeight); +} + + + +/* + * Functionally identical with DoResize(), except that this + * handles a virtual window differently, but it isn't used anyway. + * djhjr - 10/6/02 + */ +#if 0 +void +MenuDoResize(x_root, y_root, tmp_win) +int x_root; +int y_root; +TwmWindow *tmp_win; +{ + int action; + + action = 0; + + x_root -= clampDX; + y_root -= clampDY; + + if (clampTop) { + int delta = y_root - dragy; + if (dragHeight - delta < MINHEIGHT) { + delta = dragHeight - MINHEIGHT; + clampTop = 0; + } + dragy += delta; + dragHeight -= delta; + action = 1; + } + else if (y_root <= dragy/* || + y_root == findRootInfo(root)->rooty*/) { + dragy = y_root; + dragHeight = origy + origHeight - + y_root; + clampBottom = 0; + clampTop = 1; + clampDY = 0; + action = 1; + } + if (clampLeft) { + int delta = x_root - dragx; + if (dragWidth - delta < MINWIDTH) { + delta = dragWidth - MINWIDTH; + clampLeft = 0; + } + dragx += delta; + dragWidth -= delta; + action = 1; + } + else if (x_root <= dragx/* || + x_root == findRootInfo(root)->rootx*/) { + dragx = x_root; + dragWidth = origx + origWidth - + x_root; + clampRight = 0; + clampLeft = 1; + clampDX = 0; + action = 1; + } + if (clampBottom) { + int delta = y_root - dragy - dragHeight; + if (dragHeight + delta < MINHEIGHT) { + delta = MINHEIGHT - dragHeight; + clampBottom = 0; + } + dragHeight += delta; + action = 1; + } + else if (y_root >= dragy + dragHeight - 1/* || + y_root == findRootInfo(root)->rooty + + findRootInfo(root)->rootheight - 1*/) { + dragy = origy; + dragHeight = 1 + y_root - dragy; + clampTop = 0; + clampBottom = 1; + clampDY = 0; + action = 1; + } + if (clampRight) { + int delta = x_root - dragx - dragWidth; + if (dragWidth + delta < MINWIDTH) { + delta = MINWIDTH - dragWidth; + clampRight = 0; + } + dragWidth += delta; + action = 1; + } + else if (x_root >= dragx + dragWidth - 1/* || + x_root == findRootInfo(root)->rootx + + findRootInfo(root)->rootwidth - 1*/) { + dragx = origx; + dragWidth = 1 + x_root - origx; + clampLeft = 0; + clampRight = 1; + clampDX = 0; + action = 1; + } + + if (action) { + ConstrainSize (tmp_win, &dragWidth, &dragHeight); + if (clampLeft) + dragx = origx + origWidth - dragWidth; + if (clampTop) + dragy = origy + origHeight - dragHeight; + + if (resize_context == C_VIRTUAL_WIN) + MoveOutline(Scr->VirtualDesktopDisplay, + dragx, + dragy, + dragWidth, + dragHeight, + tmp_win->frame_bw, 0); + else { + /* added this 'if ... else' - djhjr - 4/6/98 */ + if (tmp_win->opaque_resize) + { + SetupWindow (tmp_win, + dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw, + dragWidth, dragHeight, -1); + + /* force the redraw of a door - djhjr - 2/28/99 */ + { + TwmDoor *door; + + if (XFindContext(dpy, tmp_win->w, DoorContext, (caddr_t *)&door) != XCNOENT) + RedoDoorName(tmp_win, door); + } + + /* force the redraw of the desktop - djhjr - 2/28/99 */ + if (!strcmp(tmp_win->class.res_class, VTWM_DESKTOP_CLASS)) + { + ResizeDesktopDisplay(dragWidth, dragHeight); + + Draw3DBorder(Scr->VirtualDesktopDisplayOuter, 0, 0, + Scr->VirtualDesktopMaxWidth + (Scr->VirtualDesktopBevelWidth * 2), + Scr->VirtualDesktopMaxHeight + (Scr->VirtualDesktopBevelWidth * 2), + Scr->VirtualDesktopBevelWidth, Scr->VirtualC, off, False, False); + } + + /* force the redraw of an icon manager - djhjr - 3/1/99 */ + if (tmp_win->iconmgr) + { + struct WList *list; + int ncols = tmp_win->iconmgrp->cur_columns; + if (ncols == 0) ncols = 1; + +/* djhjr - 4/24/96 + tmp_win->iconmgrp->width = (int) ((dragWidth * +*/ + tmp_win->iconmgrp->width = (int) (((dragWidth - 2 * tmp_win->frame_bw3D) * + + (long) tmp_win->iconmgrp->columns) + / ncols); + PackIconManager(tmp_win->iconmgrp); + + list = tmp_win->iconmgrp->first; + while (list) + { + RedoListWindow(list->twm); + list = list->next; + } + } + + PaintBorderAndTitlebar(tmp_win); + + /* djhjr - 4/15/98 */ + /* added '&& !resizing_window' - djhjr - 11/7/03 */ + if (!Scr->NoGrabServer && !resizing_window) + { + /* these let the application window be drawn - djhjr - 4/14/98 */ + XUngrabServer(dpy); XSync(dpy, 0); XGrabServer(dpy); + } + } + else + MoveOutline(Scr->Root, + dragx - tmp_win->frame_bw, + dragy - tmp_win->frame_bw, + dragWidth + 2 * tmp_win->frame_bw, + dragHeight + 2 * tmp_win->frame_bw, +/* djhjr - 4/24/96 + tmp_win->frame_bw, tmp_win->title_height); +*/ + tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); + + /* djhjr - 4/17/98 */ + if (Scr->VirtualReceivesMotionEvents) + DoVirtualMoveResize(tmp_win, dragx, dragy, dragWidth, dragHeight); + } + } + + DisplaySize(tmp_win, dragWidth, dragHeight); +} +#endif + +/*********************************************************************** + * + * Procedure: + * DoResize - move the rubberband around. This is called for + * each motion event when we are resizing + * + * Inputs: + * x_root - the X corrdinate in the root window + * y_root - the Y corrdinate in the root window + * tmp_win - the current twm window + * + *********************************************************************** + */ + +void +DoResize(x_root, y_root, tmp_win) +int x_root; +int y_root; +TwmWindow *tmp_win; +{ + int action; + + action = 0; + + x_root -= clampDX; + y_root -= clampDY; + + if (clampTop) { + int delta = y_root - dragy; + if (dragHeight - delta < MINHEIGHT) { + delta = dragHeight - MINHEIGHT; + clampTop = 0; + } + dragy += delta; + dragHeight -= delta; + action = 1; + } + else if (y_root <= dragy/* || + y_root == findRootInfo(root)->rooty*/) { + dragy = y_root; + dragHeight = origy + origHeight - + y_root; + clampBottom = 0; + clampTop = 1; + clampDY = 0; + action = 1; + } + if (clampLeft) { + int delta = x_root - dragx; + if (dragWidth - delta < MINWIDTH) { + delta = dragWidth - MINWIDTH; + clampLeft = 0; + } + dragx += delta; + dragWidth -= delta; + action = 1; + } + else if (x_root <= dragx/* || + x_root == findRootInfo(root)->rootx*/) { + dragx = x_root; + dragWidth = origx + origWidth - + x_root; + clampRight = 0; + clampLeft = 1; + clampDX = 0; + action = 1; + } + if (clampBottom) { + int delta = y_root - dragy - dragHeight; + if (dragHeight + delta < MINHEIGHT) { + delta = MINHEIGHT - dragHeight; + clampBottom = 0; + } + dragHeight += delta; + action = 1; + } + else if (y_root >= dragy + dragHeight - 1/* || + y_root == findRootInfo(root)->rooty + + findRootInfo(root)->rootheight - 1*/) { + dragy = origy; + dragHeight = 1 + y_root - dragy; + clampTop = 0; + clampBottom = 1; + clampDY = 0; + action = 1; + } + if (clampRight) { + int delta = x_root - dragx - dragWidth; + if (dragWidth + delta < MINWIDTH) { + delta = MINWIDTH - dragWidth; + clampRight = 0; + } + dragWidth += delta; + action = 1; + } + else if (x_root >= dragx + dragWidth - 1/* || + x_root == findRootInfo(root)->rootx + + findRootInfo(root)->rootwidth - 1*/) { + dragx = origx; + dragWidth = 1 + x_root - origx; + clampLeft = 0; + clampRight = 1; + clampDX = 0; + action = 1; + } + + if (action) { + ConstrainSize (tmp_win, &dragWidth, &dragHeight); + if (clampLeft) + dragx = origx + origWidth - dragWidth; + if (clampTop) + dragy = origy + origHeight - dragHeight; + + /* added this 'if() ... else' - djhjr - 4/6/98 */ + if (tmp_win->opaque_resize) + { + SetupWindow(tmp_win, + dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw, + dragWidth, dragHeight, -1); + + /* force the redraw of a door - djhjr - 2/28/99 */ + { + TwmDoor *door; + + if (XFindContext(dpy, tmp_win->w, DoorContext, (caddr_t *)&door) != XCNOENT) + RedoDoorName(tmp_win, door); + } + + /* force the redraw of the desktop - djhjr - 2/28/99 */ + if (!strcmp(tmp_win->class.res_class, VTWM_DESKTOP_CLASS)) + { + ResizeDesktopDisplay(dragWidth, dragHeight); + + Draw3DBorder(Scr->VirtualDesktopDisplayOuter, 0, 0, + Scr->VirtualDesktopMaxWidth + (Scr->VirtualDesktopBevelWidth * 2), + Scr->VirtualDesktopMaxHeight + (Scr->VirtualDesktopBevelWidth * 2), + Scr->VirtualDesktopBevelWidth, Scr->VirtualC, off, False, False); + } + + /* force the redraw of an icon manager - djhjr - 3/1/99 */ + if (tmp_win->iconmgr) + { + struct WList *list; + int ncols = tmp_win->iconmgrp->cur_columns; + if (ncols == 0) ncols = 1; + +/* djhjr - 4/24/96 + tmp_win->iconmgrp->width = (int) ((dragWidth * +*/ + tmp_win->iconmgrp->width = (int) (((dragWidth - 2 * tmp_win->frame_bw3D) * + + (long) tmp_win->iconmgrp->columns) + / ncols); + PackIconManager(tmp_win->iconmgrp); + + list = tmp_win->iconmgrp->first; + while (list) + { + RedoListWindow(list->twm); + list = list->next; + } + } + + PaintBorderAndTitlebar(tmp_win); + + /* djhjr - 4/15/98 */ + /* added '&& !resizing_window' - djhjr - 11/7/03 */ + if (!Scr->NoGrabServer && !resizing_window) + { + /* these let the application window be drawn - djhjr - 4/14/98 */ + XUngrabServer(dpy); XSync(dpy, 0); XGrabServer(dpy); + } + } + else + MoveOutline(Scr->Root, + dragx - tmp_win->frame_bw, + dragy - tmp_win->frame_bw, + dragWidth + 2 * tmp_win->frame_bw, + dragHeight + 2 * tmp_win->frame_bw, +/* djhjr - 4/24/96 + tmp_win->frame_bw, tmp_win->title_height); +*/ + tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); + + /* djhjr - 4/17/98 */ + if (Scr->VirtualReceivesMotionEvents) + DoVirtualMoveResize(tmp_win, dragx, dragy, dragWidth, dragHeight); + } + + DisplaySize(tmp_win, dragWidth, dragHeight); +} + +/* djhjr - 9/13/02 */ +static void +SetVirtualDesktopIncrs(tmp_win) +TwmWindow *tmp_win; +{ + if (strcmp(tmp_win->class.res_class, VTWM_DESKTOP_CLASS) == 0) + { + if (Scr->snapRealScreen) + { + Scr->VirtualDesktopDisplayTwin->hints.flags |= PResizeInc; + Scr->VirtualDesktopDisplayTwin->hints.width_inc = + SCALE_D(Scr->VirtualDesktopPanDistanceX); + Scr->VirtualDesktopDisplayTwin->hints.height_inc = + SCALE_D(Scr->VirtualDesktopPanDistanceY); + } + else + Scr->VirtualDesktopDisplayTwin->hints.flags &= ~PResizeInc; + + XSetWMNormalHints(dpy, tmp_win->w, + &Scr->VirtualDesktopDisplayTwin->hints); + } +} + +/*********************************************************************** + * + * Procedure: + * DisplaySize - display the size in the dimensions window + * + * Inputs: + * tmp_win - the current twm window + * width - the width of the rubber band + * height - the height of the rubber band + * + *********************************************************************** + */ + +void +DisplaySize(tmp_win, width, height) +TwmWindow *tmp_win; +int width; +int height; +{ + char str[100]; + int i, dwidth, dheight; + + if (last_width == width && last_height == height) + return; + + last_width = width; + last_height = height; + + if (resize_context == C_VIRTUAL_WIN) { + dheight = SCALE_U(height) - tmp_win->title_height; + dwidth = SCALE_U(width); + } else { +/* djhjr - 4/24/96 + dheight = height - tmp_win->title_height; + dwidth = width; +*/ + dheight = height - tmp_win->title_height - 2 * tmp_win->frame_bw3D; + dwidth = width - 2 * tmp_win->frame_bw3D; + + } + + /* + * ICCCM says that PMinSize is the default is no PBaseSize is given, + * and vice-versa. + * Don't adjust if window is the virtual desktop - djhjr - 9/13/02 + */ + if (tmp_win->hints.flags&(PMinSize|PBaseSize) && tmp_win->hints.flags & PResizeInc) + { + if (tmp_win->hints.flags & PBaseSize) + { + dwidth -= tmp_win->hints.base_width; + dheight -= tmp_win->hints.base_height; + } else if (strcmp(tmp_win->class.res_class, VTWM_DESKTOP_CLASS) != 0) + { + dwidth -= tmp_win->hints.min_width; + dheight -= tmp_win->hints.min_height; + } + } + + if (tmp_win->hints.flags & PResizeInc) + { + dwidth /= tmp_win->hints.width_inc; + dheight /= tmp_win->hints.height_inc; + } + +/* + * Non-SysV systems - specifically, BSD-derived systems - return a + * pointer to the string, not its length. Submitted by Goran Larsson + i = sprintf (str, "%5d x %-5d", dwidth, dheight); + */ + sprintf (str, "%5d x %-5d", dwidth, dheight); + i = strlen (str); + + XRaiseWindow(dpy, Scr->SizeWindow); + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF(Scr->DefaultC.fore, Scr->DefaultC.back, Scr->SizeFont); +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont, +#else + XDrawImageString (dpy, Scr->SizeWindow, +#endif + Scr->NormalGC, + +/* djhjr - 5/9/96 + Scr->SizeStringOffset, +*/ + (Scr->SizeStringWidth - +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_TextWidth(&Scr->SizeFont, +#else + XTextWidth(Scr->SizeFont.font, +#endif + str, i)) / 2, + +/* djhjr - 4/29/98 + Scr->SizeFont.font->ascent + SIZE_VINDENT, +*/ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ +/* djhjr 9/14/03 + Scr->SizeFont.font->ascent + +*/ + Scr->SizeFont.ascent + + SIZE_VINDENT + + ((Scr->InfoBevelWidth > 0) ? Scr->InfoBevelWidth : 0), + + str, i); + + /* I know, I know, but the above code overwrites it... djhjr - 5/9/96 */ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (Scr->InfoBevelWidth > 0) + Draw3DBorder(Scr->SizeWindow, 0, 0, + Scr->SizeStringWidth, + +/* djhjr - 4/29/98 + (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2), + BW, Scr->DefaultC, off, False, False); +*/ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2) + + ((Scr->InfoBevelWidth > 0) ? 2 * Scr->InfoBevelWidth : 0), + Scr->InfoBevelWidth, Scr->DefaultC, off, False, False); +} + +/*********************************************************************** + * + * Procedure: + * EndResize - finish the resize operation + * + *********************************************************************** + */ + +void +EndResize() +{ + TwmWindow *tmp_win; + +#ifdef DEBUG + fprintf(stderr, "EndResize\n"); +#endif + + if (resize_context == C_VIRTUAL_WIN) + MoveOutline(Scr->VirtualDesktopDisplay, 0, 0, 0, 0, 0, 0); + else + MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); + XUnmapWindow(dpy, Scr->SizeWindow); + + XFindContext(dpy, ResizeWindow, TwmContext, (caddr_t *)&tmp_win); + + if (resize_context == C_VIRTUAL_WIN) { + /* scale up */ + dragWidth = SCALE_U(dragWidth); + dragHeight = SCALE_U(dragHeight); + dragx = SCALE_U(dragx); + dragy = SCALE_U(dragy); + } + + ConstrainSize (tmp_win, &dragWidth, &dragHeight); + + if (dragWidth != tmp_win->frame_width || + dragHeight != tmp_win->frame_height) + tmp_win->zoomed = ZOOM_NONE; + + SetupWindow (tmp_win, dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw, + dragWidth, dragHeight, -1); + + EndResizeAdjPointer(tmp_win); /* djhjr - 9/13/02 */ + + /* added test for opaque resizing - djhjr - 2/28/99, 3/1/99 */ + if (!tmp_win->opaque_resize) + { + /* was inline code - djhjr - 9/10/99 */ + ResizeTwmWindowContents(tmp_win, dragWidth, dragHeight); + } + +#if 0 /* done in menus.c:ExecuteFunction() - djhjr - 10/6/02 */ + if (!Scr->NoRaiseResize) { + XRaiseWindow(dpy, tmp_win->frame); + + RaiseStickyAbove (); /* DSE */ + RaiseAutoPan(); + } + + UninstallRootColormap(); + + /* the resize can have cause the window to move on the screen, hence on the virtual + * desktop - need to fix the virtual coords */ + tmp_win->virtual_frame_x = R_TO_V_X(dragx); + tmp_win->virtual_frame_y = R_TO_V_Y(dragy); + + /* UpdateDesktop(tmp_win); Stig */ + MoveResizeDesktop(tmp_win, Scr->NoRaiseResize); /* Stig */ +#endif + +#if 0 /* done in menus.c:ExecuteFunction() - djhjr - 10/11/01 */ + /* djhjr - 6/4/98 */ + /* don't re-map if the window is the virtual desktop - djhjr - 2/28/99 */ + if (Scr->VirtualReceivesMotionEvents && + /* !tmp_win->opaque_resize && */ + tmp_win->w != Scr->VirtualDesktopDisplayOuter) + { + XUnmapWindow(dpy, Scr->VirtualDesktopDisplay); + XMapWindow(dpy, Scr->VirtualDesktopDisplay); + } +#endif + + ResizeWindow = None; + + /* djhjr - 9/5/98 */ + resizing_window = 0; +} + +/* added the passed 'context' - djhjr - 9/30/02 */ +void +MenuEndResize(tmp_win, context) +TwmWindow *tmp_win; +int context; +{ + /* added this 'if (...) ... else' - djhjr - 2/22/99 */ + if (resize_context == C_VIRTUAL_WIN) + MoveOutline(Scr->VirtualDesktopDisplay, 0, 0, 0, 0, 0, 0); + else + MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); + XUnmapWindow(dpy, Scr->SizeWindow); + + ConstrainSize (tmp_win, &dragWidth, &dragHeight); + + /* djhjr - 9/19/96 */ + if (dragWidth != tmp_win->frame_width || dragHeight != tmp_win->frame_height) + tmp_win->zoomed = ZOOM_NONE; + +/* djhjr - 10/6/02 + AddingX = dragx; + AddingY = dragy; + AddingW = dragWidth + (2 * tmp_win->frame_bw); + AddingH = dragHeight + (2 * tmp_win->frame_bw); + SetupWindow (tmp_win, AddingX, AddingY, AddingW, AddingH, -1); +*/ + SetupWindow (tmp_win, dragx - tmp_win->frame_bw, dragy - tmp_win->frame_bw, + dragWidth, dragHeight, -1); + + /* djhjr - 9/13/02 9/30/02 */ + if (context != C_VIRTUAL_WIN) + EndResizeAdjPointer(tmp_win); + + /* added test for opaque resizing - djhjr - 2/28/99, 3/1/99 */ + if (!tmp_win->opaque_resize) + { + /* was inline code - djhjr - 9/10/99 */ + ResizeTwmWindowContents(tmp_win, dragWidth, dragHeight); + } + +#if 0 /* done in menus.c:ExecuteFunction() - djhjr - 10/11/01 */ + /* djhjr - 6/4/98 */ + /* don't re-map if the window is the virtual desktop - djhjr - 2/28/99 */ + if (Scr->VirtualReceivesMotionEvents && + /* !tmp_win->opaque_resize && */ + tmp_win->w != Scr->VirtualDesktopDisplayOuter) + { + XUnmapWindow(dpy, Scr->VirtualDesktopDisplay); + XMapWindow(dpy, Scr->VirtualDesktopDisplay); + } +#endif + + /* djhjr - 9/5/98 */ + resizing_window = 0; +} + + + +/*********************************************************************** + * + * Procedure: + * AddEndResize - finish the resize operation for AddWindow + * + *********************************************************************** + */ + +void +AddEndResize(tmp_win) +TwmWindow *tmp_win; +{ + +#ifdef DEBUG + fprintf(stderr, "AddEndResize\n"); +#endif + + /* djhjr - 2/22/99 */ + MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); + XUnmapWindow(dpy, Scr->SizeWindow); + + ConstrainSize (tmp_win, &dragWidth, &dragHeight); + AddingX = dragx; + AddingY = dragy; + AddingW = dragWidth + (2 * tmp_win->frame_bw); + AddingH = dragHeight + (2 * tmp_win->frame_bw); + + EndResizeAdjPointer(tmp_win); /* djhjr - 9/13/02 */ + + /* djhjr - 9/19/96 */ + if (dragWidth != tmp_win->frame_width || dragHeight != tmp_win->frame_height) + tmp_win->zoomed = ZOOM_NONE; + +#if 0 /* done in add_window.c:AddMoveAndResize() - djhjr - 10/11/01 */ + /* djhjr - 6/4/98 */ + if (Scr->VirtualReceivesMotionEvents/* && !tmp_win->opaque_resize*/) + { + XUnmapWindow(dpy, Scr->VirtualDesktopDisplay); + XMapWindow(dpy, Scr->VirtualDesktopDisplay); + } +#endif + + /* djhjr - 9/5/98 */ + resizing_window = 0; +} + +/* djhjr - 9/13/02 */ +static void +EndResizeAdjPointer(tmp_win) +TwmWindow *tmp_win; +{ + int x, y, bw = tmp_win->frame_bw + tmp_win->frame_bw3D; + + XQueryPointer(dpy, Scr->Root, &JunkRoot, &JunkChild, + &JunkX, &JunkY, &JunkBW, &JunkBW, &JunkBW); + XTranslateCoordinates(dpy, Scr->Root, tmp_win->frame, + JunkX, JunkY, &x, &y, &JunkChild); + + /* for borderless windows */ + if (bw == 0) bw = 4; + + /* (tmp_win->frame_bw) == no 3D borders */ + + if (x <= 0) + { + if (y < tmp_win->title_height) + x = tmp_win->title_x + ((tmp_win->frame_bw) ? (bw / 2) : -(bw / 2)); + else + x = ((tmp_win->frame_bw) ? -(bw / 2) : (bw / 2)); + } + if (x >= tmp_win->frame_width) + { + if (y < tmp_win->title_height) + x = tmp_win->title_x + tmp_win->title_width + (bw / 2); + else + x = tmp_win->frame_width + ((tmp_win->frame_bw) ? (bw / 2) : -(bw / 2)); + } + + if (y <= tmp_win->title_height) + { + if (x >= tmp_win->title_x - ((tmp_win->frame_bw) ? 0 : bw) && + x < tmp_win->title_x + tmp_win->title_width + bw) + { + if (y <= 0) + y = ((tmp_win->frame_bw) ? -(bw / 2) : (bw / 2)); + } + else + y = tmp_win->title_height + ((tmp_win->frame_bw) ? -(bw / 2) : (bw / 2)); + } + if (y >= tmp_win->frame_height) + y = tmp_win->frame_height + ((tmp_win->frame_bw) ? (bw / 2) : -(bw / 2)); + + XWarpPointer(dpy, None, tmp_win->frame, 0, 0, 0, 0, x, y); +} + +/*********************************************************************** + * + * Procedure: + * ConstrainSize - adjust the given width and height to account for the + * constraints imposed by size hints + * + * The general algorithm, especially the aspect ratio stuff, is + * borrowed from uwm's CheckConsistency routine. + * + ***********************************************************************/ + +void ConstrainSize (tmp_win, widthp, heightp) + TwmWindow *tmp_win; + int *widthp, *heightp; +{ +#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) ) +#define _min(a,b) (((a) < (b)) ? (a) : (b)) + + int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta; + int baseWidth, baseHeight; + int dwidth = *widthp, dheight = *heightp; + + +/* djhjr - 4/24/96 + dheight -= tmp_win->title_height; +*/ + dwidth -= 2 * tmp_win->frame_bw3D; + dheight -= (tmp_win->title_height + 2 * tmp_win->frame_bw3D); + + if (tmp_win->hints.flags & PMinSize) { + minWidth = tmp_win->hints.min_width; + minHeight = tmp_win->hints.min_height; + } else if (tmp_win->hints.flags & PBaseSize) { + minWidth = tmp_win->hints.base_width; + minHeight = tmp_win->hints.base_height; + } else + minWidth = minHeight = 1; + + if (resize_context == C_VIRTUAL_WIN) { + minWidth = SCALE_D(minWidth); + minHeight = SCALE_D(minHeight); + } + + if (tmp_win->hints.flags & PBaseSize) { + baseWidth = tmp_win->hints.base_width; + baseHeight = tmp_win->hints.base_height; + } else if (tmp_win->hints.flags & PMinSize) { + baseWidth = tmp_win->hints.min_width; + baseHeight = tmp_win->hints.min_height; + } else + baseWidth = baseHeight = 0; + + if (resize_context == C_VIRTUAL_WIN) { + baseWidth = SCALE_D(baseWidth); + baseHeight = SCALE_D(baseHeight); + } + + if (tmp_win->hints.flags & PMaxSize) { + maxWidth = _min (Scr->MaxWindowWidth, tmp_win->hints.max_width); + maxHeight = _min (Scr->MaxWindowHeight, tmp_win->hints.max_height); + } else { + maxWidth = Scr->MaxWindowWidth; + maxHeight = Scr->MaxWindowHeight; + } + + if (resize_context == C_VIRTUAL_WIN) { + maxWidth = SCALE_D(maxWidth); + maxHeight = SCALE_D(maxHeight); + } + + if (tmp_win->hints.flags & PResizeInc) { + xinc = tmp_win->hints.width_inc; + yinc = tmp_win->hints.height_inc; + } else + xinc = yinc = 1; + + if (resize_context == C_VIRTUAL_WIN) { + xinc = SCALE_D(xinc); + yinc = SCALE_D(yinc); + } + + /* + * First, clamp to min and max values + */ + if (dwidth < minWidth) dwidth = minWidth; + if (dheight < minHeight) dheight = minHeight; + + if (dwidth > maxWidth) dwidth = maxWidth; + if (dheight > maxHeight) dheight = maxHeight; + + + /* + * Second, fit to base + N * inc + */ + dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth; + dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight; + + + /* + * Third, adjust for aspect ratio + */ +#define maxAspectX tmp_win->hints.max_aspect.x +#define maxAspectY tmp_win->hints.max_aspect.y +#define minAspectX tmp_win->hints.min_aspect.x +#define minAspectY tmp_win->hints.min_aspect.y + /* + * The math looks like this: + * + * minAspectX dwidth maxAspectX + * ---------- <= ------- <= ---------- + * minAspectY dheight maxAspectY + * + * If that is multiplied out, then the width and height are + * invalid in the following situations: + * + * minAspectX * dheight > minAspectY * dwidth + * maxAspectX * dheight < maxAspectY * dwidth + * + */ + + if (tmp_win->hints.flags & PAspect) + { + if (minAspectX * dheight > minAspectY * dwidth) + { + delta = makemult(minAspectX * dheight / minAspectY - dwidth, + xinc); + if (dwidth + delta <= maxWidth) dwidth += delta; + else + { + delta = makemult(dheight - dwidth*minAspectY/minAspectX, + yinc); + if (dheight - delta >= minHeight) dheight -= delta; + } + } + + if (maxAspectX * dheight < maxAspectY * dwidth) + { + delta = makemult(dwidth * maxAspectY / maxAspectX - dheight, + yinc); + if (dheight + delta <= maxHeight) dheight += delta; + else + { + delta = makemult(dwidth - maxAspectX*dheight/maxAspectY, + xinc); + if (dwidth - delta >= minWidth) dwidth -= delta; + } + } + } + + + /* + * Fourth, account for border width and title height + */ +/* djhjr - 4/26/96 + *widthp = dwidth; + *heightp = dheight + tmp_win->title_height; +*/ + *widthp = dwidth + 2 * tmp_win->frame_bw3D; + *heightp = dheight + tmp_win->title_height + 2 * tmp_win->frame_bw3D; + +} + + +/*********************************************************************** + * + * Procedure: + * SetupWindow - set window sizes, this was called from either + * AddWindow, EndResize, or HandleConfigureNotify. + * + * Inputs: + * tmp_win - the TwmWindow pointer + * x - the x coordinate of the upper-left outer corner of the frame + * y - the y coordinate of the upper-left outer corner of the frame + * w - the width of the frame window w/o border + * h - the height of the frame window w/o border + * bw - the border width of the frame window or -1 not to change + * + * Special Considerations: + * This routine will check to make sure the window is not completely + * off the display, if it is, it'll bring some of it back on. + * + * The tmp_win->frame_XXX variables should NOT be updated with the + * values of x,y,w,h prior to calling this routine, since the new + * values are compared against the old to see whether a synthetic + * ConfigureNotify event should be sent. (It should be sent if the + * window was moved but not resized.) + * + *********************************************************************** + */ + +void SetupWindow (tmp_win, x, y, w, h, bw) + TwmWindow *tmp_win; + int x, y, w, h, bw; +{ + SetupFrame (tmp_win, x, y, w, h, bw, False); +} + +void SetupFrame (tmp_win, x, y, w, h, bw, sendEvent) + TwmWindow *tmp_win; + int x, y, w, h, bw; + Bool sendEvent; /* whether or not to force a send */ +{ + XWindowChanges frame_wc, xwc; + unsigned long frame_mask, xwcm; + int title_width, title_height; + int reShape; + +#ifdef DEBUG + fprintf (stderr, "SetupWindow: x=%d, y=%d, w=%d, h=%d, bw=%d\n", + x, y, w, h, bw); +#endif + + if ((tmp_win->virtual_frame_x + tmp_win->frame_width) < 0) + x = 16; /* one "average" cursor width */ + if (x >= Scr->VirtualDesktopWidth) + x = Scr->VirtualDesktopWidth - 16; + if ((tmp_win->virtual_frame_y + tmp_win->frame_height) < 0) + y = 16; /* one "average" cursor width */ + if (y >= Scr->VirtualDesktopHeight) + y = Scr->VirtualDesktopHeight - 16; + + if (bw < 0) + bw = tmp_win->frame_bw; /* -1 means current frame width */ + + if (tmp_win->iconmgr) { +/* djhjr - 4/24/96 + tmp_win->iconmgrp->width = w; + h = tmp_win->iconmgrp->height + tmp_win->title_height; +*/ + tmp_win->iconmgrp->width = w - (2 * tmp_win->frame_bw3D); + h = tmp_win->iconmgrp->height + tmp_win->title_height + (2 * tmp_win->frame_bw3D); + + } + + /* + * According to the July 27, 1988 ICCCM draft, we should send a + * "synthetic" ConfigureNotify event to the client if the window + * was moved but not resized. + */ + if (((x != tmp_win->frame_x || y != tmp_win->frame_y) && + (w == tmp_win->frame_width && h == tmp_win->frame_height)) || + (bw != tmp_win->frame_bw)) + sendEvent = TRUE; + + xwcm = CWWidth; +/* djhjr 8 4/24/96 + title_width = xwc.width = w; +*/ + title_width = xwc.width = w - (2 * tmp_win->frame_bw3D); + title_height = Scr->TitleHeight + bw; + + ComputeWindowTitleOffsets (tmp_win, xwc.width, True); + + reShape = (tmp_win->wShaped ? TRUE : FALSE); + if (tmp_win->squeeze_info) /* check for title shaping */ + { + title_width = tmp_win->rightx + Scr->TBInfo.rightoff; + if (title_width < xwc.width) + { + xwc.width = title_width; + if (tmp_win->frame_height != h || + tmp_win->frame_width != w || + tmp_win->frame_bw != bw || + title_width != tmp_win->title_width) + reShape = TRUE; + } + else + { + if (!tmp_win->wShaped) reShape = TRUE; + title_width = xwc.width; + } + } + + tmp_win->title_width = title_width; + if (tmp_win->title_height) tmp_win->title_height = title_height; + + if (tmp_win->title_w) { + if (bw != tmp_win->frame_bw) { + xwc.border_width = bw; +/* djhjr - 4/24/96 + tmp_win->title_x = xwc.x = -bw; + tmp_win->title_y = xwc.y = -bw; +*/ + tmp_win->title_x = xwc.x = tmp_win->frame_bw3D - bw; + tmp_win->title_y = xwc.y = tmp_win->frame_bw3D - bw; + + xwcm |= (CWX | CWY | CWBorderWidth); + } + + XConfigureWindow(dpy, tmp_win->title_w, xwcm, &xwc); + } + +/* djhjr - 4/24/96 + tmp_win->attr.width = w; + tmp_win->attr.height = h - tmp_win->title_height; +*/ + tmp_win->attr.width = w - (2 * tmp_win->frame_bw3D); + tmp_win->attr.height = h - tmp_win->title_height - (2 * tmp_win->frame_bw3D); + +/* djhjr - 4/25/96 + XMoveResizeWindow (dpy, tmp_win->w, 0, tmp_win->title_height, + w, h - tmp_win->title_height); +*/ + + /* + * fix up frame and assign size/location values in tmp_win + */ + + frame_mask = 0; + if (bw != tmp_win->frame_bw) { + frame_wc.border_width = tmp_win->frame_bw = bw; + frame_mask |= CWBorderWidth; + } + frame_wc.x = tmp_win->frame_x = x; + frame_wc.y = tmp_win->frame_y = y; + frame_wc.width = tmp_win->frame_width = w; + frame_wc.height = tmp_win->frame_height = h; + frame_mask |= (CWX | CWY | CWWidth | CWHeight); + XConfigureWindow (dpy, tmp_win->frame, frame_mask, &frame_wc); + tmp_win->virtual_frame_x = R_TO_V_X(tmp_win->frame_x); + tmp_win->virtual_frame_y = R_TO_V_Y(tmp_win->frame_y); + + /* djhjr - 4/24/96 */ + XMoveResizeWindow (dpy, tmp_win->w, tmp_win->frame_bw3D, + tmp_win->title_height + tmp_win->frame_bw3D, + tmp_win->attr.width, tmp_win->attr.height); + + /* + * fix up highlight window + */ + + if (tmp_win->title_height && tmp_win->hilite_w) + { +/* djhjr - 4/2/98 + xwc.width = (tmp_win->rightx - tmp_win->highlightx); + if (Scr->TBInfo.nright > 0) xwc.width -= Scr->TitlePadding; + + * djhjr - 4/24/96 * + if (Scr->use3Dtitles) xwc.width -= 4; +*/ + xwc.width = ComputeHighlightWindowWidth(tmp_win); + + if (xwc.width <= 0) { + xwc.x = Scr->MyDisplayWidth; /* move offscreen */ + xwc.width = 1; + } else { + xwc.x = tmp_win->highlightx; + } + + xwcm = CWX | CWWidth; + XConfigureWindow(dpy, tmp_win->hilite_w, xwcm, &xwc); + } + + if (HasShape && reShape) { + SetFrameShape (tmp_win); + } + + if (sendEvent) + { + SendConfigureNotify(tmp_win, x, y); + } +} + +/* djhjr - 4/6/98 */ +void +PaintBorderAndTitlebar(tmp_win) +TwmWindow *tmp_win; +{ + if (tmp_win->highlight) + SetBorder(tmp_win, True); + else + { + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (Scr->BorderBevelWidth > 0) PaintBorders(tmp_win, True); + + if (tmp_win->titlebuttons) + { + int i, nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; + TBWindow *tbw; + + for (i = 0, tbw = tmp_win->titlebuttons; i < nb; i++, tbw++) + PaintTitleButton(tmp_win, tbw, 0); + } + } + + PaintTitle(tmp_win); + PaintTitleHighlight(tmp_win, on); /* djhjr - 10/25/02 */ +} + + +/* djhjr - 4/17/98 */ +static void +DoVirtualMoveResize(tmp_win, x, y, w, h) +TwmWindow *tmp_win; +int x, y, w, h; +{ + int fw = tmp_win->frame_width, fh = tmp_win->frame_height; + + tmp_win->virtual_frame_x = R_TO_V_X(x - tmp_win->frame_bw); + tmp_win->virtual_frame_y = R_TO_V_Y(y - tmp_win->frame_bw); + if (!tmp_win->opaque_resize) + { + tmp_win->frame_width = w + 2 * tmp_win->frame_bw; + tmp_win->frame_height = h + 2 * tmp_win->frame_bw; + } + +/* djhjr - 5/27/03 + MoveResizeDesktop(tmp_win, Scr->NoRaiseResize); +*/ + MoveResizeDesktop(tmp_win, TRUE); + + tmp_win->frame_width = fw; tmp_win->frame_height = fh; +} + + +/********************************************************************** + * Rutgers mod #1 - rocky. + * Procedure: + * fullzoom - zooms window to full height of screen or + * to full height and width of screen. (Toggles + * so that it can undo the zoom - even when switching + * between fullzoom and vertical zoom.) + * + * Inputs: + * tmp_win - the TwmWindow pointer + * + * + ********************************************************************** + */ + +void +fullzoom(tmp_win,flag) +TwmWindow *tmp_win; +int flag; +{ + Window junkRoot; + unsigned int junkbw, junkDepth; + int basex, basey; + int frame_bw_times_2; + + XGetGeometry(dpy, (Drawable) tmp_win->frame, &junkRoot, &dragx, &dragy, + (unsigned int *)&dragWidth, (unsigned int *)&dragHeight, &junkbw, + &junkDepth); + + basex = basey = 0; + + if (tmp_win->zoomed == flag) + { + dragHeight = tmp_win->save_frame_height; + dragWidth = tmp_win->save_frame_width; + dragx = tmp_win->save_frame_x; + dragy = tmp_win->save_frame_y; + tmp_win->zoomed = ZOOM_NONE; + } + else + { + if (tmp_win->zoomed == ZOOM_NONE) + { + tmp_win->save_frame_x = dragx; + tmp_win->save_frame_y = dragy; + tmp_win->save_frame_width = dragWidth; + tmp_win->save_frame_height = dragHeight; + } + + tmp_win->zoomed = flag; + + frame_bw_times_2 = 2 * tmp_win->frame_bw; + + switch (flag) + { + case ZOOM_NONE: + break; + case F_ZOOM: + dragx = tmp_win->save_frame_x; + dragy=basey; + dragWidth = tmp_win->save_frame_width; + dragHeight = Scr->MyDisplayHeight - frame_bw_times_2; + break; + case F_HORIZOOM: + dragx = basex; + dragy = tmp_win->save_frame_y; + dragWidth = Scr->MyDisplayWidth - frame_bw_times_2; + dragHeight = tmp_win->save_frame_height; + break; + case F_FULLZOOM: + dragx = basex; + dragy = basey; + dragWidth = Scr->MyDisplayWidth - frame_bw_times_2; + dragHeight = Scr->MyDisplayHeight - frame_bw_times_2; + break; + case F_LEFTZOOM: + dragx = basex; + dragy = basey; + dragWidth = Scr->MyDisplayWidth / 2 - frame_bw_times_2; + dragHeight = Scr->MyDisplayHeight - frame_bw_times_2; + break; + case F_RIGHTZOOM: + dragx = basex + Scr->MyDisplayWidth / 2; + dragy = basey; + dragWidth = Scr->MyDisplayWidth / 2 - frame_bw_times_2; + dragHeight = Scr->MyDisplayHeight - frame_bw_times_2; + break; + case F_TOPZOOM: + dragx = basex; + dragy = basey; + dragWidth = Scr->MyDisplayWidth - frame_bw_times_2; + dragHeight = Scr->MyDisplayHeight / 2 - frame_bw_times_2; + break; + case F_BOTTOMZOOM: + dragx = basex; + dragy = basey + Scr->MyDisplayHeight / 2; + dragWidth = Scr->MyDisplayWidth - frame_bw_times_2; + dragHeight = Scr->MyDisplayHeight / 2 - frame_bw_times_2; + break; + } + } + + if (!Scr->NoRaiseResize) { + XRaiseWindow(dpy, tmp_win->frame); + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); + } + + ConstrainSize(tmp_win, &dragWidth, &dragHeight); + SetupWindow (tmp_win, dragx , dragy , dragWidth, dragHeight, -1); + + /* djhjr - 9/10/99 */ + ResizeTwmWindowContents(tmp_win, dragWidth, dragHeight); + + /* 9/21/96 - djhjr */ + if ((Scr->WarpCursor || LookInList(Scr->WarpCursorL, tmp_win->full_name, &tmp_win->class))) + WarpToWindow (tmp_win); + + XUngrabPointer (dpy, CurrentTime); + XUngrabServer (dpy); +} + +/* + * adjust contents of iconmgrs, doors and the desktop - djhjr - 9/10/99 + */ +void ResizeTwmWindowContents(tmp_win, width, height) + TwmWindow *tmp_win; + int width, height; +{ + TwmDoor *door; + int ncols; + + if (tmp_win->iconmgr) + { + ncols = tmp_win->iconmgrp->cur_columns; + if (ncols == 0) ncols = 1; + +/* djhjr - 4/24/96 + tmp_win->iconmgrp->width = (int) ((width * +*/ + tmp_win->iconmgrp->width = + (int)(((width - 2 * tmp_win->frame_bw3D) * + + (long) tmp_win->iconmgrp->columns) / ncols); + PackIconManager(tmp_win->iconmgrp); + } + else if (tmp_win->w == Scr->VirtualDesktopDisplayOuter) + ResizeDesktopDisplay(width, height); + else if (XFindContext(dpy, tmp_win->w, DoorContext, (caddr_t *)&door) != XCNOENT) + RedoDoorName(tmp_win, door); +} + +void SetFrameShape (tmp) + TwmWindow *tmp; +{ + /* + * see if the titlebar needs to move + */ + if (tmp->title_w) { + int oldx = tmp->title_x, oldy = tmp->title_y; + ComputeTitleLocation (tmp); + if (oldx != tmp->title_x || oldy != tmp->title_y) + XMoveWindow (dpy, tmp->title_w, tmp->title_x, tmp->title_y); + } + + /* + * The frame consists of the shape of the contents window offset by + * title_height or'ed with the shape of title_w (which is always + * rectangular). + */ + if (tmp->wShaped) { + /* + * need to do general case + */ + XShapeCombineShape (dpy, tmp->frame, ShapeBounding, +/* djhjr - 4/24/96 + 0, tmp->title_height, tmp->w, +*/ + tmp->frame_bw3D, tmp->title_height + tmp->frame_bw3D, tmp->w, + + ShapeBounding, ShapeSet); + if (tmp->title_w) { + XShapeCombineShape (dpy, tmp->frame, ShapeBounding, + tmp->title_x + tmp->frame_bw, + tmp->title_y + tmp->frame_bw, + tmp->title_w, ShapeBounding, + ShapeUnion); + } + } else { + /* + * can optimize rectangular contents window + */ + if (tmp->squeeze_info) { + XRectangle newBounding[3]; + XRectangle newClip[3]; + int count = 3, order = YXSorted, fbw2 = 2 * tmp->frame_bw; + int client_width = tmp->attr.width + fbw2 + 2 * tmp->frame_bw3D; + + /* + * Build the border clipping rectangles; one around title, one + * around window. The title_[xy] field already have had frame_bw + * subtracted off them so that they line up properly in the frame. + * + * The frame_width and frame_height do *not* include borders. + */ + /* border */ +/* djhjr - 4/24/96 + newBounding[0].x = tmp->title_x; + newBounding[0].y = tmp->title_y; + newBounding[0].width = tmp->title_width + fbw2; + newBounding[0].height = tmp->title_height; + newBounding[1].x = -tmp->frame_bw; + newBounding[1].y = Scr->TitleHeight; + newBounding[1].width = tmp->attr.width + fbw2; + newBounding[1].height = tmp->attr.height + fbw2; +*/ + newBounding[0].x = tmp->title_x - tmp->frame_bw3D; + newBounding[0].y = tmp->title_y - tmp->frame_bw3D; + newBounding[0].width = tmp->title_width + fbw2 + 2 * tmp->frame_bw3D; + newBounding[0].height = tmp->title_height + tmp->frame_bw3D; + + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (Scr->BorderBevelWidth > 0 && + newBounding[0].width < client_width) + { + /* re-ordered arrays for XYSorted - djhjr - 11/5/03 */ + newBounding[1].x = -tmp->frame_bw3D; + newBounding[1].y = tmp->title_height; + newBounding[1].width = tmp->attr.width + 3 * tmp->frame_bw3D; + newBounding[1].height = tmp->frame_bw3D; + newBounding[2].x = -tmp->frame_bw; + newBounding[2].y = Scr->TitleHeight + tmp->frame_bw3D; + newBounding[2].width = client_width; + newBounding[2].height = tmp->attr.height + fbw2 + tmp->frame_bw3D; + } + else + { + newBounding[1].x = -tmp->frame_bw; + newBounding[1].y = Scr->TitleHeight + tmp->frame_bw3D; + newBounding[1].width = client_width; + newBounding[1].height = tmp->attr.height + fbw2 + tmp->frame_bw3D; + count = 2; + order = YXBanded; + } + + /* insides */ +/* djhjr - 4/24/96 + newClip[0].x = tmp->title_x + tmp->frame_bw; + newClip[0].y = 0; + newClip[0].width = tmp->title_width; + newClip[0].height = Scr->TitleHeight; + newClip[1].x = 0; + newClip[1].y = tmp->title_height; + newClip[1].width = tmp->attr.width; + newClip[1].height = tmp->attr.height; +*/ + newClip[0].x = tmp->title_x + tmp->frame_bw - tmp->frame_bw3D; + newClip[0].y = 0; + newClip[0].width = tmp->title_width + 2 * tmp->frame_bw3D; + newClip[0].height = Scr->TitleHeight + tmp->frame_bw3D; + + if (count == 3) + { + /* re-ordered arrays for XYSorted - djhjr - 11/5/03 */ + newClip[1].x = newBounding[1].x; + newClip[1].y = newBounding[1].y; + newClip[1].width = newBounding[1].width; + newClip[1].height = newBounding[1].height; + newClip[2].x = 0; + newClip[2].y = tmp->title_height + tmp->frame_bw3D; + newClip[2].width = client_width; + newClip[2].height = tmp->attr.height + tmp->frame_bw3D; + } + else + { + newClip[1].x = 0; + newClip[1].y = tmp->title_height + tmp->frame_bw3D; + newClip[1].width = client_width; + newClip[1].height = tmp->attr.height + tmp->frame_bw3D; + } + + XShapeCombineRectangles (dpy, tmp->frame, ShapeBounding, 0, 0, + newBounding, count, ShapeSet, order); + XShapeCombineRectangles (dpy, tmp->frame, ShapeClip, 0, 0, + newClip, count, ShapeSet, order); + } else { + (void) XShapeCombineMask (dpy, tmp->frame, ShapeBounding, 0, 0, + None, ShapeSet); + (void) XShapeCombineMask (dpy, tmp->frame, ShapeClip, 0, 0, + None, ShapeSet); + } + } +} + +/* + * Squeezed Title: + * + * tmp->title_x + * 0 | + * tmp->title_y ........+--------------+......... -+,- tmp->frame_bw + * 0 : ......| +----------+ |....... : -++ + * : : | | | | : : ||-Scr->TitleHeight + * : : | | | | : : || + * +-------+ +----------+ +--------+ -+|-tmp->title_height + * | +---------------------------+ | --+ + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | +---------------------------+ | + * +-------------------------------+ + * + * + * Unsqueezed Title: + * + * tmp->title_x + * | 0 + * tmp->title_y +-------------------------------+ -+,tmp->frame_bw + * 0 | +---------------------------+ | -+' + * | | | | |-Scr->TitleHeight + * | | | | | + * + +---------------------------+ + -+ + * |-+---------------------------+-| + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | +---------------------------+ | + * +-------------------------------+ + * + * + * + * Dimensions and Positions: + * + * frame orgin (0, 0) + * frame upper left border (-tmp->frame_bw, -tmp->frame_bw) + * frame size w/o border tmp->frame_width , tmp->frame_height + * frame/title border width tmp->frame_bw + * extra title height w/o bdr tmp->title_height = TitleHeight + frame_bw + * title window height Scr->TitleHeight + * title origin w/o border (tmp->title_x, tmp->title_y) + * client origin (0, Scr->TitleHeight + tmp->frame_bw) + * client size tmp->attr.width , tmp->attr.height + * + * When shaping, need to remember that the width and height of rectangles + * are really deltax and deltay to lower right handle corner, so they need + * to have -1 subtracted from would normally be the actual extents. + */ diff --git a/resize.h b/resize.h new file mode 100644 index 0000000..4590144 --- /dev/null +++ b/resize.h @@ -0,0 +1,65 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/********************************************************************** + * + * $XConsortium: resize.h,v 1.7 90/03/23 11:42:32 jim Exp $ + * + * resize function externs + * + * 8-Apr-88 Tom LaStrange Initial Version. + * + **********************************************************************/ + +#ifndef _RESIZE_ +#define _RESIZE_ + +extern int resizing_window; + +extern void StartResize(); +extern void AddStartResize(); +extern void DoResize(); +extern void DisplaySize(); +extern void EndResize(); +extern void AddEndResize(); +extern void SetupWindow(); +extern void SetupFrame(); +extern void SetFrameShape(); +extern void ConstrainSize(); +/* depreciated - djhjr - 10/6/02 +extern void MenuDoResize(); +*/ +extern void MenuStartResize(); +extern void MenuEndResize(); + +/* djhjr - 4/6/98 */ +void PaintBorderAndTitlebar(); + +extern void fullzoom(); + +#endif /* _RESIZE_ */ diff --git a/screen.h b/screen.h new file mode 100644 index 0000000..6ba85c2 --- /dev/null +++ b/screen.h @@ -0,0 +1,808 @@ +/* + * Copyright 1989 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*********************************************************************** + * + * $XConsortium: screen.h,v 1.62 91/05/01 17:33:09 keith Exp $ + * + * twm per-screen data include file + * + * 11-3-88 Dave Payne, Apple Computer File created + * + ***********************************************************************/ + +#ifndef _SCREEN_ +#define _SCREEN_ + +#include +#include +#include +#include "list.h" +#include "menus.h" +#include "iconmgr.h" +#include "doors.h" + +/* djhjr - 5/17/98 */ +#ifndef ORIGINAL_PIXMAPS +#include "util.h" /* for Image structure */ +#endif + +typedef struct _StdCmap { + struct _StdCmap *next; /* next link in chain */ + Atom atom; /* property from which this came */ + int nmaps; /* number of maps below */ + XStandardColormap *maps; /* the actual maps */ +} StdCmap; + +#define SIZE_HINDENT 10 + +#ifdef ORIGINAL_SIZEVINDENT +#define SIZE_VINDENT 2 +#else +#define SIZE_VINDENT 5 +#endif + +typedef struct ScreenInfo +{ + int screen; /* the default screen */ + int d_depth; /* copy of DefaultDepth(dpy, screen) */ + Visual *d_visual; /* copy of DefaultVisual(dpy, screen) */ + int Monochrome; /* is the display monochrome ? */ + int MyDisplayWidth; /* my copy of DisplayWidth(dpy, screen) */ + int MyDisplayHeight; /* my copy of DisplayHeight(dpy, screen) */ + int MaxWindowWidth; /* largest window to allow */ + int MaxWindowHeight; /* ditto */ + + /* djhjr - 5/15/96 */ + int ResizeX; /* coordinate of resize/position window */ + int ResizeY; /* ditto */ + + int VirtualDesktopMaxWidth; /* max width of virtual desktop */ + int VirtualDesktopMaxHeight; /* max height of virtual desktop */ + int VirtualDesktopWidth; /* width of virtual desktop */ + int VirtualDesktopHeight; /* height of virtual desktop */ + int VirtualDesktopX; /* top left x of my screen on the desktop */ + int VirtualDesktopY; /* top left y of my screen on the desktop */ + int VirtualDesktopPanDistanceX; /* distance to pan screen */ + int VirtualDesktopPanDistanceY; /* distance to pan screen */ + + /* these are for the little vd display */ + int VirtualDesktopDScale; /* scale of the virtual desktop display */ + int VirtualDesktopDX; /* position of the vd display */ + int VirtualDesktopDY; /* position of the vd display */ + + /* the autopan stuff */ + int AutoPanX; /* how far should autopan travel */ + /* AutoPanX is also "whether autopan configured". */ + int AutoPanY; /* how far should autopan travel */ + Window VirtualDesktopAutoPan[4]; /* the autopan windows */ + /* 0 = left, 1 = right, 2 = top, 3 = bottom */ + + /* djhjr - 9/8/98 */ + int VirtualDesktopPanResistance; /* how much effort it takes to pan */ + + TwmWindow TwmRoot; /* the head of the twm window list */ + + Window Root; /* the root window */ + Window SizeWindow; /* the resize dimensions window */ + Window InfoWindow; /* the information window */ + Window VirtualDesktopDisplayOuter; /* wrapper for display of the virtual desktop */ + Window VirtualDesktopDisplay; /* display of the virtual desktop */ + Window VirtualDesktopDScreen; /* display of the real screen on the vd */ + TwmWindow *VirtualDesktopDisplayTwin; /* twm window for the above */ + + name_list *ImageCache; /* list of pixmaps */ + name_list *Icons; /* list of icon pixmaps */ + + int pullW, pullH; /* size of pull right menu icon */ + +/* djhjr - 5/17/98 */ +/* added the unknowns - djhjr - 8/13/98 */ +#ifdef ORIGINAL_PIXMAPS + Pixmap UnknownPm; /* the unknown icon pixmap */ + int UnknownWidth; /* width of the unknown icon */ + int UnknownHeight; /* height of the unknown icon */ + Pixmap hilitePm; /* focus highlight window background */ + int hilite_pm_width, hilite_pm_height; /* cache the size */ + Pixmap virtualPm; /* panner background pixmap RFB PIXMAP */ + int virtual_pm_width, virtual_pm_height; /* RFB PIXMAP */ + Pixmap RealScreenPm; /* panner background pixmap RFB PIXMAP */ + int RealScreen_pm_width, RealScreen_pm_height; /* RFB PIXMAP */ +#else /* ORIGINAL_PIXMAPS */ + char *unknownName; /* name of unknown icon pixmap */ + + /* djhjr - 10/25/02 */ + char *hiliteName; /* name of built-in focus highlight pixmap */ + /* two more - djhjr - 10/30/02 */ + char *iconMgrIconName; /* name of built-in iconmgr iconify pixmap */ + char *menuIconName; /* name of built-in pull right menu pixmap */ + +/* depreciated - djhjr - 10/30/02 + Image *siconifyPm; * the icon manager iconify pixmap * + Image *pullPm; * pull right menu icon * +*/ + + Image *hilitePm; /* focus highlight window image structure */ + Image *virtualPm; /* panner background window image structure */ + Image *realscreenPm; /* real screen window image structure */ +#endif /* ORIGINAL_PIXMAPS */ + + MenuRoot *MenuList; /* head of the menu list */ + MenuRoot *LastMenu; /* the last menu (mostly unused?) */ + MenuRoot *Windows; /* the TwmWindows menu */ + + TwmWindow *Ring; /* one of the windows in window ring */ + TwmWindow *RingLeader; /* current winodw in ring */ + + MouseButton Mouse[MAX_BUTTONS+1][NUM_CONTEXTS][MOD_SIZE]; + MouseButton DefaultFunction; + MouseButton WindowFunction; + + struct { + Colormaps *cmaps; /* current list of colormap windows */ + int maxCmaps; /* maximum number of installed colormaps */ + unsigned long first_req; /* seq # for first XInstallColormap() req in + pass thru loading a colortable list */ + int root_pushes; /* current push level to install root + colormap windows */ + TwmWindow *pushed_window; /* saved window to install when pushes drops + to zero */ + } cmapInfo; + + struct { + StdCmap *head, *tail; /* list of maps */ + StdCmap *mru; /* most recently used in list */ + int mruindex; /* index of mru in entry */ + } StdCmapInfo; + + struct { + int nleft, nright; /* numbers of buttons in list */ + TitleButton *head; /* start of list */ + int border; /* button border */ + int pad; /* button-padding */ + int width; /* width of single button & border */ + int leftx; /* start of left buttons */ + int titlex; /* start of title string */ + int rightoff; /* offset back from right edge */ + } TBInfo; + ColorPair BorderTileC; /* border tile colors */ + ColorPair TitleC; /* titlebar colors */ + ColorPair MenuC; /* menu colors */ + ColorPair MenuTitleC; /* menu title colors */ + ColorPair IconC; /* icon colors */ + ColorPair IconManagerC; /* icon manager colors */ + ColorPair DefaultC; /* default colors */ + + /* djhjr - 4/19/96 */ + ColorPair BorderColorC; /* color of window borders */ + + ColorPair VirtualDesktopDisplayC; /* desktop display color */ + ColorPair DoorC; /* default door colors */ + ColorPair VirtualC; /* default virtual colors *//*RFB VCOLOR*/ + ColorPair RealScreenC; /* "real screen" in panner RFB 4/92 */ + Pixel VirtualDesktopDisplayBorder; /* desktop display default border */ + Pixel BorderColor; /* color of window borders */ + Pixel MenuShadowColor; /* menu shadow color */ + Pixel IconBorderColor; /* icon border color */ + Pixel IconManagerHighlight; /* icon manager highlight */ + + /* djhjr - 4/19/96 */ + short ClearBevelContrast; /* The contrast of the clear shadow */ + short DarkBevelContrast; /* The contrast of the dark shadow */ + + Cursor TitleCursor; /* title bar cursor */ + Cursor FrameCursor; /* frame cursor */ + Cursor IconCursor; /* icon cursor */ + Cursor IconMgrCursor; /* icon manager cursor */ + Cursor ButtonCursor; /* title bar button cursor */ + Cursor MoveCursor; /* move cursor */ + Cursor ResizeCursor; /* resize cursor */ + Cursor WaitCursor; /* wait a while cursor */ + Cursor MenuCursor; /* menu cursor */ + Cursor SelectCursor; /* dot cursor for f.move, etc. from menus */ + Cursor DestroyCursor; /* skull and cross bones, f.destroy */ + Cursor DoorCursor;/*RFBCURSOR*/ + Cursor VirtualCursor;/*RFBCURSOR*/ + Cursor DesktopCursor;/*RFBCURSOR*/ + Cursor NoCursor; /* a black cursor - used on desktop display */ + + name_list *BorderColorL; + name_list *IconBorderColorL; + name_list *BorderTileForegroundL; + name_list *BorderTileBackgroundL; + name_list *TitleForegroundL; + name_list *TitleBackgroundL; + name_list *IconForegroundL; + name_list *IconBackgroundL; + name_list *IconManagerFL; + name_list *IconManagerBL; + name_list *IconMgrs; + + /* djhjr - 4/19/96 */ + name_list *NoBorder; /* list of window without borders */ + + /* djhjr - 4/7/98 */ + name_list *OpaqueMoveL; /* list of windows moved as a solid */ + name_list *NoOpaqueMoveL; /* list of windows moved as an outline */ + name_list *OpaqueResizeL; /* list of windows resized as a solid */ + name_list *NoOpaqueResizeL; /* list of windows resized as an outline */ + + name_list *NoTitle; /* list of window names with no title bar */ + name_list *MakeTitle; /* list of window names with title bar */ + name_list *AutoRaise; /* list of window names to auto-raise */ + name_list *IconNames; /* list of window names and icon names */ + name_list *NoHighlight; /* list of windows to not highlight */ + name_list *NoStackModeL; /* windows to ignore stack mode requests */ + name_list *NoTitleHighlight;/* list of windows to not highlight the TB*/ + name_list *DontIconify; /* don't iconify by unmapping */ + name_list *IconMgrNoShow; /* don't show in the icon manager */ + name_list *IconMgrShow; /* show in the icon manager */ + name_list *IconifyByUn; /* windows to iconify by unmapping */ + name_list *StartIconified; /* windows to start iconic */ + name_list *IconManagerHighlightL; /* icon manager highlight colors */ + name_list *SqueezeTitleL; /* windows of which to squeeze title */ + name_list *DontSqueezeTitleL; /* windows of which not to squeeze */ + name_list *WindowRingL; /* windows in ring */ + + /* submitted by Jonathan Paisley - 10/27/02 */ + name_list *NoWindowRingL; /* windows not added to ring */ + + name_list *WarpCursorL; /* windows to warp cursor to on deiconify */ + name_list *NailedDown; /* windows that are nailed down */ + name_list *VirtualDesktopColorFL; /* color of representations on the vd display */ + name_list *VirtualDesktopColorBL; /* color of representations on the vd display */ + name_list *VirtualDesktopColorBoL; /* color of representations on the vd display */ + name_list *DontShowInDisplay; /* don't show these in the desktop display */ + + /* Submitted by Erik Agsjo */ + name_list *DontShowInTWMWindows; /* don't show these in the TWMWindows menu */ + + name_list *DoorForegroundL; /* doors foreground */ + name_list *DoorBackgroundL; /* doors background */ + + /* djhjr - 9/24/02 */ + name_list *UsePPositionL; /* windows with UsePPosition set */ + + GC NormalGC; /* normal GC for everything */ + GC MenuGC; /* gc for menus */ + GC DrawGC; /* GC to draw lines for move and resize */ + + /* djhjr - 4/19/96 */ + GC GreyGC; /* for shadowing on monochrome displays */ + GC ShadGC; /* for shadowing on with patterns */ + + unsigned long Black; + unsigned long White; + unsigned long XORvalue; /* number to use when drawing xor'ed */ + MyFont TitleBarFont; /* title bar font structure */ + MyFont MenuFont; /* menu font structure */ + MyFont IconFont; /* icon font structure */ + MyFont SizeFont; /* resize font structure */ + MyFont IconManagerFont; /* window list font structure */ + MyFont VirtualFont; /* virtual display windows */ + MyFont DoorFont; /* for drawing in doors */ + MyFont MenuTitleFont; /* DSE -- for menu titles */ + MyFont InfoFont; /* for the info window */ + MyFont DefaultFont; + IconMgr iconmgr; /* default icon manager */ + struct RootRegion *FirstIconRegion; /* pointer to icon regions */ + struct RootRegion *LastIconRegion; /* pointer to the last icon region */ + char *IconDirectory; /* icon directory to search */ + + /* djhjr - 4/26/99 */ + struct RootRegion *FirstAppletRegion; /* pointer to applet regions */ + struct RootRegion *LastAppletRegion; /* pointer to the last applet region */ + + /* djhjr - 12/26/98 */ + char *BitmapFilePath; /* local copy of the X database resource */ + + int SizeStringOffset; /* x offset in size window for drawing */ + int SizeStringWidth; /* minimum width of size window */ + int BorderWidth; /* border width of twm windows */ + +/* djhjr - 8/11/98 + * djhjr - 4/18/96 * + int ThreeDBorderWidth; * 3D border width of twm windows * +*/ + + /* widths of the various 3D shadows - djhjr - 5/2/98 */ + int BorderBevelWidth; + int TitleBevelWidth; + int MenuBevelWidth; + int IconMgrBevelWidth; + int InfoBevelWidth; + + /* djhjr - 8/11/98 */ + int IconBevelWidth; + int ButtonBevelWidth; + + /* djhjr - 2/7/99 */ + int DoorBevelWidth; + int VirtualDesktopBevelWidth; + + /* djhjr - 5/22/00 */ + int MenuScrollBorderWidth; /* top and bottom margins for menu scrolling */ + int MenuScrollJump; /* number of entries for menu scroll */ + + int IconBorderWidth; /* border width of icon windows */ + int TitleHeight; /* height of the title bar window */ + TwmWindow *Focus; /* the twm window that has focus */ + TwmWindow *Newest; /* the most newly added twm window -- PF */ + int EntryHeight; /* menu entry height */ + int FramePadding; /* distance between decorations and border */ + int TitlePadding; /* distance between items in titlebar */ + int ButtonIndent; /* amount to shrink buttons on each side */ + int NumAutoRaises; /* number of autoraise windows on screen */ + + short SqueezeTitle; /* make title as small as possible */ + short MoveDelta; /* number of pixels before f.move starts */ + short ZoomCount; /* zoom outline count */ + + /* djhjr - 6/22/01 */ + int PauseOnExit; /* delay before shutting down via Done() */ + int PauseOnQuit; /* delay before shuttind down via f.quit */ + +/* djhjr - 5/17/96 */ +#ifdef ORIGINAL_SHORTS + /* short NoDefaults; - DSE */ + short NoDefaultMouseOrKeyboardBindings; /* do not add default UI mouse and keyboard stuff - DSE */ + short NoDefaultTitleButtons; /* do not add default resize and iconify title buttons - DSE */ + short UsePPosition; /* what do with PPosition, see values below */ + short OldFashionedTwmWindowsMenu; + +/* djhjr - 2/15/99 + short UseRealScreenBorder; +*/ + + short AutoRelativeResize; /* start resize relative to position in quad */ + short FocusRoot; /* is the input focus on the root ? */ + + /* djhjr - 10/16/02 */ + short WarpCentered; /* warp to center of windows? */ + + short WarpCursor; /* warp cursor on de-iconify? */ + short ForceIcon; /* force the icon to the user specified */ + short NoGrabServer; /* don't do server grabs */ + short NoRaiseMove; /* don't raise window following move */ + short NoRaiseResize; /* don't raise window following resize */ + short NoRaiseDeicon; /* don't raise window on deiconify */ + short NoRaiseWarp; /* don't raise window on warp */ + short DontMoveOff; /* don't allow windows to be moved off */ + short DoZoom; /* zoom in and out of icons */ + short TitleFocus; /* focus on window in title bar ? */ + + /* djhjr - 5/27/98 */ + short IconManagerFocus; /* focus on window of the icon manager entry? */ + + /* djhjr - 12/14/98 */ + short StaticIconPositions; /* non-nailed icons stay put */ + + /* djhjr - 10/2/01 */ + short StrictIconManager; /* show only the iconified */ + + /* djhjr - 8/23/02 */ + short NoBorders; /* put borders on windows */ + + short NoTitlebar; /* put title bars on windows */ + short DecorateTransients; /* put title bars on transients */ + short IconifyByUnmapping; /* simply unmap windows when iconifying */ + short ShowIconManager; /* display the window list */ + short IconManagerDontShow; /* show nothing in the icon manager */ + short NoIconifyIconManagers; /* don't iconify the icon manager -- PF */ + short BackingStore; /* use backing store for menus */ + short SaveUnder; /* use save under's for menus */ + short RandomPlacement; /* randomly place windows that no give hints */ + short PointerPlacement; /* place near mouse pointer */ + short OpaqueMove; /* move the window rather than outline */ + + /* djhjr - 4/6/98 */ + short OpaqueResize; /* resize the window rather than outline */ + + short Highlight; /* should we highlight the window borders */ + + /* djhjr - 1/27/98 */ + short IconMgrHighlight; /* should we highlight icon manager entries */ + + short StackMode; /* should we honor stack mode requests */ + short TitleHighlight; /* should we highlight the titlebar */ + short SortIconMgr; /* sort entries in the icon manager */ + short Shadow; /* show the menu shadow */ + short InterpolateMenuColors;/* make pretty menus */ + short NoIconManagers; /* Don't create any icon managers */ + short ClientBorderWidth; /* respect client window border width */ + short HaveFonts; /* set if fonts have been loaded */ + short FirstTime; /* first time we've read .twmrc */ + short CaseSensitive; /* be case-sensitive when sorting names */ + short WarpUnmapped; /* allow warping to unmapped windows */ + short DeIconifyToScreen; /* if deiconified, should this goto the screen ? */ + short WarpWindows; /* should windows or the screen be warped ? */ + short snapRealScreen; /* should the real screen snap to a pandistance grid ? */ + short GeometriesAreVirtual; /* should geometries be interpreted as virtual or real ? */ + short Virtual; /* are we virtual ? (like, hey man....) */ + short NamesInVirtualDesktop;/* show names in virtual desktop display ? */ + short AutoRaiseDefault; /* AutoRaise all windows if true *//*RAISEDELAY*/ + short UseWindowRing; /* put all windows in the ring? */ + short StayUpMenus; + short StayUpOptionalMenus; /* PF */ + short WarpToTransients; /* PF */ + short EnhancedExecResources; /* instead of normal behavior - DSE */ + short RightHandSidePulldownMenus; /* instead of left-right center - DSE */ + short LessRandomZoomZoom; /* makes zoomzoom a better visual bell - DSE */ + short PrettyZoom; /* nicer-looking animation - DSE */ + short StickyAbove; /* sticky windows above other windows - DSE */ + short DontInterpolateTitles; /* menu titles are excluded from color interpolation - DSE */ + + /* djhjr - 1/6/98 */ + short FixManagedVirtualGeometries; /* bug workaround */ + + short FixTransientVirtualGeometries; /* bug workaround - DSE */ + short WarpSnug; /* make sure entire window is on screen when warping - DSE */ + + /* djhjr - 6/25/96 */ + short ShallowReliefWindowButton; + +/* obsoleted by the *BevelWidth resources - djhjr - 8/11/98 + * djhjr - 4/18/96 * + short use3Dmenus; + short use3Dtitles; + short use3Diconmanagers; + short use3Dborders; +*/ + + short BeNiceToColormap; + +/* obsoleted by the *BevelWidth resources - djhjr - 8/11/98 + * djhjr - 5/5/98 * + short use3Dicons; +*/ + +/* obsoleted by the ":xpm:*" built-in pixmaps - djhjr - 10/26/02 + * djhjr - 4/25/96 * + short SunkFocusWindowTitle; +*/ + + /* for rader - djhjr - 2/9/99 */ + short NoPrettyTitles; + + /* djhjr - 9/21/96 */ + short ButtonColorIsFrame; + + /* djhjr - 4/17/98 */ + short VirtualReceivesMotionEvents; + short VirtualSendsMotionEvents; + + /* djhjr - 6/22/99 */ + short DontDeiconifyTransients; + + /* submitted by Ugen Antsilevitch - 5/28/00 */ + short WarpVisible; + + /* djhjr - 10/11/01 */ + short ZoomZoom; /* fallback on random zooms on iconify */ + + /* djhjr - 10/20/02 */ + short NoBorderDecorations; + + /* djhjr - 11/3/03 */ + short RaiseOnStart; +#else + struct + { + unsigned int NoDefaultMouseOrKeyboardBindings : 1; + unsigned int NoDefaultTitleButtons : 1; + unsigned int UsePPosition : 2; + unsigned int OldFashionedTwmWindowsMenu : 1; + +/* djhjr - 2/15/99 + unsigned int UseRealScreenBorder : 1; +*/ + + unsigned int AutoRelativeResize : 1; + unsigned int FocusRoot : 1; + + /* djhjr - 10/16/02 */ + unsigned int WarpCentered : 2; + + unsigned int WarpCursor : 1; + unsigned int ForceIcon : 1; + unsigned int NoGrabServer : 1; + unsigned int NoRaiseMove : 1; + unsigned int NoRaiseResize : 1; + unsigned int NoRaiseDeicon : 1; + unsigned int NoRaiseWarp : 1; + unsigned int DontMoveOff : 1; + unsigned int DoZoom : 1; + unsigned int TitleFocus : 1; + + /* djhjr - 5/27/98 */ + unsigned int IconManagerFocus : 1; + + /* djhjr - 12/14/98 */ + unsigned int StaticIconPositions : 1; + + /* djhjr - 10/2/01 */ + unsigned int StrictIconManager : 1; + + /* djhjr - 8/23/02 */ + unsigned int NoBorders : 1; + + unsigned int NoTitlebar : 1; + unsigned int DecorateTransients : 1; + unsigned int IconifyByUnmapping : 1; + unsigned int ShowIconManager : 1; + unsigned int IconManagerDontShow : 1; + unsigned int NoIconifyIconManagers : 1; + unsigned int BackingStore : 1; + unsigned int SaveUnder : 1; + unsigned int RandomPlacement : 1; + unsigned int PointerPlacement : 1; + unsigned int OpaqueMove : 1; + + /* djhjr - 4/6/98 */ + unsigned int OpaqueResize : 1; + + unsigned int Highlight : 1; + + /* djhjr - 1/27/98 */ + unsigned int IconMgrHighlight : 1; + + unsigned int StackMode : 1; + unsigned int TitleHighlight : 1; + unsigned int SortIconMgr : 1; + unsigned int Shadow : 1; + unsigned int InterpolateMenuColors : 1; + unsigned int NoIconManagers : 1; + unsigned int ClientBorderWidth : 1; + unsigned int HaveFonts : 1; + unsigned int FirstTime : 1; + unsigned int CaseSensitive : 1; + unsigned int WarpUnmapped : 1; + unsigned int DeIconifyToScreen : 1; + unsigned int WarpWindows : 1; + unsigned int snapRealScreen : 1; + unsigned int GeometriesAreVirtual : 1; + unsigned int Virtual : 1; + unsigned int NamesInVirtualDesktop : 1; + unsigned int AutoRaiseDefault : 1; + unsigned int UseWindowRing : 1; + unsigned int StayUpMenus : 1; + unsigned int StayUpOptionalMenus : 1; + unsigned int WarpToTransients : 1; + unsigned int EnhancedExecResources : 1; + unsigned int RightHandSidePulldownMenus : 1; + unsigned int LessRandomZoomZoom : 1; + unsigned int PrettyZoom : 1; + unsigned int StickyAbove : 1; + unsigned int DontInterpolateTitles : 1; + + /* djhjr - 1/6/98 */ + unsigned int FixManagedVirtualGeometries : 1; + + unsigned int FixTransientVirtualGeometries : 1; + unsigned int WarpSnug : 1; + unsigned int ShallowReliefWindowButton : 2; + +/* obsoleted by the *BevelWidth resources - djhjr - 8/11/98 + unsigned int use3Dmenus : 1; + unsigned int use3Dtitles : 1; + unsigned int use3Diconmanagers : 1; + unsigned int use3Dborders : 1; + + * djhjr - 5/5/98 * + unsigned int use3Dicons : 1; +*/ + + unsigned int BeNiceToColormap : 1; + +/* obsoleted by the ":xpm:*" built-in pixmaps - djhjr - 10/26/02 + unsigned int SunkFocusWindowTitle : 1; +*/ + + /* for rader - djhjr - 2/9/99 */ + unsigned int NoPrettyTitles : 1; + + unsigned int ButtonColorIsFrame : 1; + + /* djhjr - 4/17/98 */ + unsigned int VirtualReceivesMotionEvents : 1; + unsigned int VirtualSendsMotionEvents : 1; + + /* djhjr - 6/22/99 */ + unsigned int DontDeiconifyTransients : 1; + + /* submitted by Ugen Antsilevitch - 5/28/00 */ + unsigned int WarpVisible : 1; + + /* djhjr - 10/11/01 */ + unsigned int ZoomZoom : 1; + + /* djhjr - 10/20/02 */ + unsigned int NoBorderDecorations : 1; + + /* djhjr - 11/3/03 */ + unsigned int RaiseOnStart : 1; + } userflags; +#define NoDefaultMouseOrKeyboardBindings userflags.NoDefaultMouseOrKeyboardBindings +#define NoDefaultTitleButtons userflags.NoDefaultTitleButtons +#define UsePPosition userflags.UsePPosition +#define OldFashionedTwmWindowsMenu userflags.OldFashionedTwmWindowsMenu + +/* djhjr - 2/15/99 +#define UseRealScreenBorder userflags.UseRealScreenBorder +*/ + +#define AutoRelativeResize userflags.AutoRelativeResize +#define FocusRoot userflags.FocusRoot + +/* djhjr - 10/16/02 */ +#define WarpCentered userflags.WarpCentered + +#define WarpCursor userflags.WarpCursor +#define ForceIcon userflags.ForceIcon +#define NoGrabServer userflags.NoGrabServer +#define NoRaiseMove userflags.NoRaiseMove +#define NoRaiseResize userflags.NoRaiseResize +#define NoRaiseDeicon userflags.NoRaiseDeicon +#define NoRaiseWarp userflags.NoRaiseWarp +#define DontMoveOff userflags.DontMoveOff +#define DoZoom userflags.DoZoom +#define TitleFocus userflags.TitleFocus + +/* djhjr - 5/27/98 */ +#define IconManagerFocus userflags.IconManagerFocus + +/* djhjr - 12/14/98 */ +#define StaticIconPositions userflags.StaticIconPositions + +/* djhjr - 10/2/01 */ +#define StrictIconManager userflags.StrictIconManager + +/* djhjr - 8/23/02 */ +#define NoBorders userflags.NoBorders + +#define NoTitlebar userflags.NoTitlebar +#define DecorateTransients userflags.DecorateTransients +#define IconifyByUnmapping userflags.IconifyByUnmapping +#define ShowIconManager userflags.ShowIconManager +#define IconManagerDontShow userflags.IconManagerDontShow +#define NoIconifyIconManagers userflags.NoIconifyIconManagers +#define BackingStore userflags.BackingStore +#define SaveUnder userflags.SaveUnder +#define RandomPlacement userflags.RandomPlacement +#define PointerPlacement userflags.PointerPlacement +#define OpaqueMove userflags.OpaqueMove + +/* djhjr - 4/6/98 */ +#define OpaqueResize userflags.OpaqueResize + +#define Highlight userflags.Highlight + +/* djhjr - 1/27/98 */ +#define IconMgrHighlight userflags.IconMgrHighlight + +#define StackMode userflags.StackMode +#define TitleHighlight userflags.TitleHighlight +#define SortIconMgr userflags.SortIconMgr +#define Shadow userflags.Shadow +#define InterpolateMenuColors userflags.InterpolateMenuColors +#define NoIconManagers userflags.NoIconManagers +#define ClientBorderWidth userflags.ClientBorderWidth +#define HaveFonts userflags.HaveFonts +#define FirstTime userflags.FirstTime +#define CaseSensitive userflags.CaseSensitive +#define WarpUnmapped userflags.WarpUnmapped +#define DeIconifyToScreen userflags.DeIconifyToScreen +#define WarpWindows userflags.WarpWindows +#define snapRealScreen userflags.snapRealScreen +#define GeometriesAreVirtual userflags.GeometriesAreVirtual +#define Virtual userflags.Virtual +#define NamesInVirtualDesktop userflags.NamesInVirtualDesktop +#define AutoRaiseDefault userflags.AutoRaiseDefault +#define UseWindowRing userflags.UseWindowRing +#define StayUpMenus userflags.StayUpMenus +#define StayUpOptionalMenus userflags.StayUpOptionalMenus +#define WarpToTransients userflags.WarpToTransients +#define EnhancedExecResources userflags.EnhancedExecResources +#define RightHandSidePulldownMenus userflags.RightHandSidePulldownMenus +#define LessRandomZoomZoom userflags.LessRandomZoomZoom +#define PrettyZoom userflags.PrettyZoom +#define StickyAbove userflags.StickyAbove +#define DontInterpolateTitles userflags.DontInterpolateTitles + +/* djhjr - 1/6/98 */ +#define FixManagedVirtualGeometries userflags.FixManagedVirtualGeometries + +#define FixTransientVirtualGeometries userflags.FixTransientVirtualGeometries +#define WarpSnug userflags.WarpSnug +#define ShallowReliefWindowButton userflags.ShallowReliefWindowButton + +/* obsoleted by the *BevelWidth resources - djhjr - 8/11/98 +#define use3Dmenus userflags.use3Dmenus +#define use3Dtitles userflags.use3Dtitles +#define use3Diconmanagers userflags.use3Diconmanagers +#define use3Dborders userflags.use3Dborders + +* djhjr - 5/5/98 * +#define use3Dicons userflags.use3Dicons +*/ + +#define BeNiceToColormap userflags.BeNiceToColormap + +/* obsoleted by the ":xpm:*" built-in pixmaps - djhjr - 10/26/02 +#define SunkFocusWindowTitle userflags.SunkFocusWindowTitle +*/ + +/* for rader - djhjr - 2/9/99 */ +#define NoPrettyTitles userflags.NoPrettyTitles + +#define ButtonColorIsFrame userflags.ButtonColorIsFrame + +/* djhjr - 4/17/98 */ +#define VirtualReceivesMotionEvents userflags.VirtualReceivesMotionEvents +#define VirtualSendsMotionEvents userflags.VirtualSendsMotionEvents + +/* djhjr - 6/22/99 */ +#define DontDeiconifyTransients userflags.DontDeiconifyTransients + +/* submitted by Ugen Antsilevitch - 5/28/00 */ +#define WarpVisible userflags.WarpVisible + +/* djhjr - 10/11/01 */ +#define ZoomZoom userflags.ZoomZoom + +/* djhjr - 10/20/02 */ +#define NoBorderDecorations userflags.NoBorderDecorations + +/* djhjr - 11/3/03 */ +#define RaiseOnStart userflags.RaiseOnStart +#endif + + /* djhjr - 9/10/03 */ + int IgnoreModifiers; /* binding modifiers to ignore */ + + FuncKey FuncKeyRoot; + TwmDoor *Doors; /* a list of doors on this screen */ + + int AutoPanBorderWidth; /* of autopan windows, really - DSE */ + int AutoPanExtraWarp; /* # of extra pixels to warp - DSE */ + int RealScreenBorderWidth; /* in virtual desktop - DSE */ + int AutoPanWarpWithRespectToRealScreen; /* percent - DSE */ +} ScreenInfo; + +extern int MultiScreen; +extern int NumScreens; +extern ScreenInfo **ScreenList; +extern ScreenInfo *Scr; +extern int FirstScreen; + +#define PPOS_OFF 0 +#define PPOS_ON 1 +#define PPOS_NON_ZERO 2 +/* may eventually want an option for having the PPosition be the initial + location for the drag lines */ + +/* djhjr - 10/16/02 */ +#define WARPC_OFF 0 +#define WARPC_TITLED 1 +#define WARPC_UNTITLED 2 +#define WARPC_ON 3 + +#endif /* _SCREEN_ */ diff --git a/sound.c b/sound.c new file mode 100644 index 0000000..4a32a7e --- /dev/null +++ b/sound.c @@ -0,0 +1,330 @@ +/* + * Copyright 2001, 2002 David J. Hawkey Jr. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder or the author not + * be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. The copyright holder + * and the author make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THE COPYRIGHT HOLDER AND THE AUTHOR DISCLAIM ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDER OR THE AUTHOR BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * sound.c + * + * D. J. Hawkey Jr. - 6/22/01 8/16/01 11/15/02 + */ + +#ifdef NO_SOUND_SUPPORT + +/* stub function for gram.y */ +int +SetSound(function, filename, volume) +char *function, *filename; +int volume; +{ + return (1); +} + +#else /* NO_SOUND_SUPPORT */ + +#include +#include +#include +#include +#include "gram.h" +#include "parse.h" +#include "twm.h" +#include "sound.h" + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 256 +#endif + +extern int parse_keyword(); /* in parse.c */ +extern void twmrc_error_prefix(); /* in gram.y */ + +typedef struct sound_keyword +{ + char *name; + int value; +} sound_keyword; + +static sound_keyword sound_keywords[] = +{ + {"(vtwm start)", S_START}, + {"(vtwm stop)", S_STOP}, + {"(client map)", S_CMAP}, + {"(client unmap)", S_CUNMAP}, + {"(menu map)", S_MMAP}, + {"(menu unmap)", S_MUNMAP}, + {"(info unmap)", S_IUNMAP}, + {"(autopan event)", S_APAN}, + {"(bell event)", S_BELL} +}; + +#define MAX_SOUNDKEYWORDS (sizeof(sound_keywords) / sizeof(sound_keyword)) + +typedef struct sound_entry +{ + int func; + RPLAY *rp; +} sound_entry; + +static sound_entry *sound_entries = NULL; +static int sound_count = 0; +static int sound_size = 0; + +static int sound_fd = -1; +static int sound_vol = 63; /* 1/4 attenuation */ +static int sound_state = 0; +static char sound_host[MAXHOSTNAMELEN + 1] = ""; + +/* for qsort() */ +static int +compare(p, q) +void *p, *q; +{ + sound_entry *pp = (sound_entry *) p, *qq = (sound_entry *) q; + + return (pp->func - qq->func); +} + +static int +adjustVolume(volume) +int volume; +{ + float vol; + + if (volume > 100) + volume = 100; + + /* volume for rplay is 1 to 255, not 1 to 100 */ + vol = (float) volume / 100.0; + volume = vol * 255.0; + + return (volume); +} + +int +OpenSound() +{ + if (sound_fd < 0) + { + if (sound_host[0] == '\0') + { + strncpy(sound_host, rplay_default_host(), MAXHOSTNAMELEN); + sound_host[MAXHOSTNAMELEN] = '\0'; + } + + if ((sound_fd = rplay_open(sound_host)) >= 0) + { + qsort((void *) sound_entries, (size_t) sound_count, + (size_t) sizeof(sound_entry), compare); + + sound_state = 1; + } + } + + return (sound_fd); +} + +void +CloseSound() +{ + int i; + + for (i = 0; i < sound_count; i++) + rplay_destroy(sound_entries[i].rp); + + if (sound_entries != NULL) + free((void *) sound_entries); + + if (sound_fd >= 0) + rplay_close(sound_fd); + + sound_entries = NULL; + sound_count = 0; + sound_size = 0; + + sound_fd = -1; + sound_vol = 63; + sound_state = 0; + sound_host[0] = '\0'; +} + +int +SetSound(function, filename, volume) +char *function, *filename; +int volume; +{ + sound_entry *sptr; + int i, func, subfunc; + + func = parse_keyword(function, &subfunc); + if (func != FKEYWORD && func != FSKEYWORD) + { + XmuCopyISOLatin1Lowered(function, function); + + for (i = 0; i < MAX_SOUNDKEYWORDS; i++) + if (strcmp(function, sound_keywords[i].name) == 0) + { + func = FKEYWORD; + subfunc = sound_keywords[i].value; + break; + } + } + + if (func == FKEYWORD || func == FSKEYWORD) + { + if (sound_count >= sound_size) + { + sound_size += 10; + sptr = (sound_entry *) realloc((sound_entry *) sound_entries, + sound_size * sizeof(sound_entry)); + if (sptr == NULL) + { + twmrc_error_prefix(); + fprintf(stderr, + "unable to allocate %d bytes for sound_entries\n", + sound_size * sizeof(sound_entry)); + Done(); + } + else + sound_entries = sptr; + } + + sptr = &sound_entries[sound_count]; + + sptr->func = subfunc; + if ((sptr->rp = rplay_create(RPLAY_PLAY)) == NULL) + { + twmrc_error_prefix(); + fprintf(stderr, "unable to add to sound list\n"); + Done(); + } + + sound_count++; + + if (volume < 0) + volume = sound_vol; + else + volume = adjustVolume(volume); + + if (rplay_set(sptr->rp, RPLAY_INSERT, 0, RPLAY_SOUND, filename, + RPLAY_VOLUME, volume, NULL) < 0) + { + twmrc_error_prefix(); + fprintf(stderr, "unable to set \"%s\" in sound list\n", + filename); + Done(); + } + + return (1); + } + + twmrc_error_prefix(); + fprintf(stderr, "unknown function \"%s\" for sound_entry\n", function); + + return (0); +} + +int +PlaySound(function) +int function; +{ + register int i, low, mid, high; + + if (sound_fd < 0 || sound_state == 0) + return (1); /* pretend success */ + + low = 0; + high = sound_count - 1; + while (low <= high) + { + mid = (low + high) / 2; + i = sound_entries[mid].func - function; + if (i < 0) + low = mid + 1; + else if (i > 0) + high = mid - 1; + else + { + rplay(sound_fd, sound_entries[mid].rp); + return (1); + } + } + + return (0); +} + +int +PlaySoundAdhoc(filename) +char *filename; +{ + RPLAY *rp; + int i; + + if (sound_fd < 0 || sound_state == 0) + return (1); /* pretend success */ + + if ((rp = rplay_create(RPLAY_PLAY)) == NULL) + { + twmrc_error_prefix(); + fprintf(stderr, "unable to create sound \"%s\"\n", filename); + return (0); + } + + if ((i = rplay_set(rp, RPLAY_INSERT, 0, RPLAY_SOUND, filename, + RPLAY_VOLUME, sound_vol, NULL)) >= 0) + rplay(sound_fd, rp); + + rplay_destroy(rp); + + if (i < 0) + { + twmrc_error_prefix(); + fprintf(stderr, "unable to set sound \"%s\"\n", filename); + return (0); + } + + return (1); +} + +void +SetSoundHost(host) +char *host; +{ + strncpy(sound_host, host, MAXHOSTNAMELEN); + sound_host[MAXHOSTNAMELEN] = '\0'; +} + +void +SetSoundVolume(volume) +int volume; +{ + if (volume < 0) + volume = 0; + + sound_vol = adjustVolume(volume); +} + +int +ToggleSounds() +{ + return ((sound_state ^= 1)); +} + +#endif /* NO_SOUND_SUPPORT */ diff --git a/sound.h b/sound.h new file mode 100644 index 0000000..db05b8b --- /dev/null +++ b/sound.h @@ -0,0 +1,48 @@ +/* + * Copyright 2001, 2002 David J. Hawkey Jr. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holder or the author not + * be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. The copyright holder + * and the author make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THE COPYRIGHT HOLDER AND THE AUTHOR DISCLAIM ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDER OR THE AUTHOR BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * sound.h + * + * D. J. Hawkey Jr. - 6/22/01 11/15/02 + */ + +#ifndef _SOUND_ +#define _SOUND_ + +/* must not overlap the function defines */ +#define S_START 900 +#define S_STOP 901 +#define S_CMAP 902 +#define S_CUNMAP 903 +#define S_MMAP 904 +#define S_MUNMAP 905 +#define S_IUNMAP 906 +#define S_APAN 907 +#define S_BELL 908 + +extern int OpenSound(), SetSound(), ToggleSounds(); +extern int PlaySound(), PlaySoundAdhoc(); +extern void CloseSound(), SetSoundHost(), SetSoundVolume(); + +#endif /* _SOUND_ */ diff --git a/system.vtwmrc.2D b/system.vtwmrc.2D new file mode 100644 index 0000000..869e527 --- /dev/null +++ b/system.vtwmrc.2D @@ -0,0 +1,250 @@ +# +# system.vtwmrc.2D +# +# Default VTWM configuration file; should be kept small to conserve string +# space in systems whose compilers don't handle medium-sized strings. +# +# Sites should tailor this file, providing any extra title buttons, menus, +# etc., that may be appropriate for their environment. For example, if most +# of the users were accustomed to uwm, the defaults could be set up not to +# decorate any windows and to use meta-keys. +# + +# +# Variables +# + +NoGrabServer +RestartPreviousState +NoDefaults + +ShowIconManager +SortIconManager +IconifyByUnmapping + +RightHandSidePulldownMenus + +NaturalAutoPanBehavior +NotVirtualGeometries +FixManagedVirtualGeometries +FixTransientVirtualGeometries + +MoveDelta 3 + +ResizeRegion "NorthEast" + +FramePadding 2 +ButtonIndent 0 +TitlePadding 5 +TitleButtonBorderWidth 1 + +VirtualDesktop "5x2-0-0" 16 +PanDistanceX 100 +PanDistanceY 100 +PanResistance 750 +AutoPan 100 + +TitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +ResizeFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +MenuFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +MenuTitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +DoorFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +IconFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +InfoFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +IconManagerFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +VirtualDesktopFont "-adobe-helvetica-medium-r-normal--*-75-*-*-*-*-*-*" + +# +# Lists +# + +SqueezeTitle + +WarpCursor + +NailedDown +{ + "VTWM *" + "xclock" + "xload" +} + +NoTitle +{ + "VTWM *" + "xclock" + "xload" +} + +DontShowInDisplay +{ + "VTWM *" + "xclock" + "xload" +} + +IconManagerDontShow +{ + "VTWM *" + "xclock" + "xload" +} + +Pixmaps +{ + "MenuIconPixmap" ":rarrow" +} + +Color +{ + DefaultBackground "maroon" + DefaultForeground "gray85" + BorderColor "grey70" + BorderTileBackground "gray60" + BorderTileForeground "gray60" + DoorBackground "maroon" + DoorForeground "gray85" + TitleBackground "maroon" + TitleForeground "gray85" + MenuBackground "maroon" + MenuForeground "gray85" + MenuTitleBackground "gray70" + MenuTitleForeground "maroon" + IconBackground "maroon" + IconForeground "gray85" + IconBorderColor "gray85" + IconManagerBackground "maroon" + IconManagerForeground "gray85" + VirtualBackground "maroon" + VirtualForeground "black" + DesktopDisplayBackground "grey60" + DesktopDisplayForeground "grey85" +} + +Monochrome +{ + DefaultBackground "gray50" + DefaultForeground "gray85" + BorderColor "grey70" + BorderTileBackground "gray60" + BorderTileForeground "gray60" + DoorBackground "gray50" + DoorForeground "gray85" + TitleBackground "gray50" + TitleForeground "gray85" + MenuBackground "gray50" + MenuForeground "gray85" + MenuTitleBackground "gray70" + MenuTitleForeground "gray50" + IconBackground "gray50" + IconForeground "gray85" + IconBorderColor "gray85" + IconManagerBackground "gray50" + IconManagerForeground "gray85" + VirtualBackground "gray50" + VirtualForeground "black" + DesktopDisplayBackground "grey60" + DesktopDisplayForeground "grey85" +} + +# +# Functions and Bindings +# + +Function "move-or-iconify" { f.move f.deltastop f.iconify } + +LeftTitleButton ":darrow" = f.menu "arrange" +RightTitleButton ":dot" = f.iconify +RightTitleButton ":resize" = f.resize + +Button1 = : root : f.version +Button3 = : root : f.menu "main" + +Button1 = : title : f.move +Button2 = : title : f.resize +Button3 = : title : f.raiselower + +Button1 = : frame : f.move +Button2 = : frame : f.resize +Button3 = : frame : f.iconify + +Button1 = : door : f.enterdoor +Button2 = : door : f.namedoor +Button3 = : door : f.deletedoor + +Button1 = : icon : f.function "move-or-iconify" +Button3 = : icon : f.menu "arrange" + +Button1 = : iconmgr : f.iconify +Button3 = : iconmgr : f.warp + +Button1 = : virtual | desktop : f.movescreen + +# +# Menus +# + +menu "main" +{ + " VTWM " f.title + "Applications" f.menu "apps" + "" f.separator + "Operations" f.menu "ops" + "Arrange" f.menu "arrange" + "" f.separator + "Restart" f.restart + "Exit" f.quit +} + +menu "apps" +{ + " Applications " f.title + "xclock" f.exec "xclock &" + "xload" f.exec "xload &" + "xterm" f.exec "xterm &" +} + +menu "ops" +{ + " Operations " f.title + "Auto Pan" f.autopan + "New Door" f.newdoor + "Snap Screen" f.snaprealscreen + "Static Icons" f.staticiconpositions + "Warp Snug" f.warpsnug + "Warp Visible" f.warpvisible + "" f.separator + "Show Icon Mgr" f.showiconmgr + "Hide Icon Mgr" f.hideiconmgr + "Show Desktop" f.showdesktopdisplay + "Hide Desktop" f.hidedesktopdisplay + "" f.separator + "Refresh" f.refresh +} + +menu "arrange" +{ + " Arrange " f.title + "Autoraise" f.autoraise + "Raise" f.raise + "Lower" f.lower + "Nail" f.nail + "" f.separator + "Move" f.move + "Size" f.resize + "Iconify" f.iconify + "" f.separator + "Full Zoom" f.fullzoom + "Horiz Zoom" f.horizoom + "Vert Zoom" f.zoom + "" f.separator + "Left Title" f.squeezeleft + "Center Title" f.squeezecenter + "Right Title" f.squeezeright + "" f.separator + "Identify" f.identify + "" f.separator + "Delete" f.delete + "Destroy" f.destroy +} + diff --git a/system.vtwmrc.3D b/system.vtwmrc.3D new file mode 100644 index 0000000..fa9dcc1 --- /dev/null +++ b/system.vtwmrc.3D @@ -0,0 +1,271 @@ +# +# system.vtwmrc.3D +# +# Default VTWM configuration file; should be kept small to conserve string +# space in systems whose compilers don't handle medium-sized strings. +# +# Sites should tailor this file, providing any extra title buttons, menus, +# etc., that may be appropriate for their environment. For example, if most +# of the users were accustomed to uwm, the defaults could be set up not to +# decorate any windows and to use meta-keys. +# + +# +# Variables +# + +NoGrabServer +RestartPreviousState +NoDefaults + +ShowIconManager +SortIconManager +IconifyByUnmapping + +RightHandSidePulldownMenus + +NaturalAutoPanBehavior +NotVirtualGeometries +FixManagedVirtualGeometries +FixTransientVirtualGeometries + +ButtonColorIsFrame +ShallowReliefWindowButton + +MoveDelta 3 + +ResizeRegion "NorthEast" + +FramePadding 2 +ButtonIndent -2 +TitlePadding 0 +TitleButtonBorderWidth 0 + +BorderWidth 6 +BorderBevelWidth 2 +ButtonBevelWidth 1 +DoorBevelWidth 1 +IconBevelWidth 2 +IconManagerBevelWidth 1 +InfoBevelWidth 2 +MenuBevelWidth 2 +TitleBevelWidth 1 +VirtualDesktopBevelWidth 1 + +ClearBevelContrast 40 +DarkBevelContrast 40 + +VirtualDesktop "5x2-0-0" 16 +PanDistanceX 100 +PanDistanceY 100 +PanResistance 750 +AutoPan 100 + +TitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +ResizeFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +MenuFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +MenuTitleFont "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*" +DoorFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +IconFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +InfoFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +IconManagerFont "-adobe-helvetica-bold-r-normal--*-100-*-*-*-*-*-*" +VirtualDesktopFont "-adobe-helvetica-medium-r-normal--*-75-*-*-*-*-*-*" + +# +# Lists +# + +NoHighlight + +SqueezeTitle + +WarpCursor + +NailedDown +{ + "VTWM *" + "xclock" + "xload" +} + +NoTitle +{ + "VTWM *" + "xclock" + "xload" +} + +DontShowInDisplay +{ + "VTWM *" + "xclock" + "xload" +} + +IconManagerDontShow +{ + "VTWM *" + "xclock" + "xload" +} + +Pixmaps +{ + TitleHighlight ":xpm:sunkenlines" + MenuIconPixmap ":xpm:rarrow" + IconManagerPixmap ":xpm:box" +} + +Color +{ + DefaultBackground "maroon" + DefaultForeground "gray85" + BorderColor "grey70" + BorderTileBackground "gray60" + BorderTileForeground "gray60" + DoorBackground "maroon" + DoorForeground "gray85" + TitleBackground "maroon" + TitleForeground "gray85" + MenuBackground "maroon" + MenuForeground "gray85" + MenuTitleBackground "gray70" + MenuTitleForeground "maroon" + IconBackground "maroon" + IconForeground "gray85" + IconBorderColor "gray85" + IconManagerBackground "maroon" + IconManagerForeground "gray85" + VirtualBackground "maroon" + VirtualForeground "black" + DesktopDisplayBackground "grey60" + DesktopDisplayForeground "grey85" +} + +Monochrome +{ + DefaultBackground "gray50" + DefaultForeground "gray85" + BorderColor "grey70" + BorderTileBackground "gray60" + BorderTileForeground "gray60" + DoorBackground "gray50" + DoorForeground "gray85" + TitleBackground "gray50" + TitleForeground "gray85" + MenuBackground "gray50" + MenuForeground "gray85" + MenuTitleBackground "gray70" + MenuTitleForeground "gray50" + IconBackground "gray50" + IconForeground "gray85" + IconBorderColor "gray85" + IconManagerBackground "gray50" + IconManagerForeground "gray85" + VirtualBackground "gray50" + VirtualForeground "black" + DesktopDisplayBackground "grey60" + DesktopDisplayForeground "grey85" +} + +# +# Functions and Bindings +# + +Function "move-or-iconify" { f.move f.deltastop f.iconify } + +LeftTitleButton ":xpm:darrow" = f.menu "arrange" +RightTitleButton ":xpm:dot" = f.iconify +RightTitleButton ":xpm:resize" = f.resize + +Button1 = : root : f.version +Button3 = : root : f.menu "main" + +Button1 = : title : f.move +Button2 = : title : f.resize +Button3 = : title : f.raiselower + +Button1 = : frame : f.move +Button2 = : frame : f.resize +Button3 = : frame : f.iconify + +Button1 = : door : f.enterdoor +Button2 = : door : f.namedoor +Button3 = : door : f.deletedoor + +Button1 = : icon : f.function "move-or-iconify" +Button3 = : icon : f.menu "arrange" + +Button1 = : iconmgr : f.iconify +Button3 = : iconmgr : f.warp + +Button1 = : virtual | desktop : f.movescreen + +# +# Menus +# + +menu "main" +{ + " VTWM " f.title + "Applications" f.menu "apps" + "" f.separator + "Operations" f.menu "ops" + "Arrange" f.menu "arrange" + "" f.separator + "Restart" f.restart + "Exit" f.quit +} + +menu "apps" +{ + " Applications " f.title + "xclock" f.exec "xclock &" + "xload" f.exec "xload &" + "xterm" f.exec "xterm &" +} + +menu "ops" +{ + " Operations " f.title + "Auto Pan" f.autopan + "New Door" f.newdoor + "Snap Screen" f.snaprealscreen + "Static Icons" f.staticiconpositions + "Warp Snug" f.warpsnug + "Warp Visible" f.warpvisible + "" f.separator + "Show Icon Mgr" f.showiconmgr + "Hide Icon Mgr" f.hideiconmgr + "Show Desktop" f.showdesktopdisplay + "Hide Desktop" f.hidedesktopdisplay + "" f.separator + "Refresh" f.refresh +} + +menu "arrange" +{ + " Arrange " f.title + "Autoraise" f.autoraise + "Raise" f.raise + "Lower" f.lower + "Nail" f.nail + "" f.separator + "Move" f.move + "Size" f.resize + "Iconify" f.iconify + "" f.separator + "Full Zoom" f.fullzoom + "Horiz Zoom" f.horizoom + "Vert Zoom" f.zoom + "" f.separator + "Left Title" f.squeezeleft + "Center Title" f.squeezecenter + "Right Title" f.squeezeright + "" f.separator + "Identify" f.identify + "" f.separator + "Delete" f.delete + "Destroy" f.destroy +} + diff --git a/twm.c b/twm.c new file mode 100644 index 0000000..1402eee --- /dev/null +++ b/twm.c @@ -0,0 +1,1586 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/*********************************************************************** + * + * $XConsortium: twm.c,v 1.124 91/05/08 11:01:54 dave Exp $ + * + * twm - "Tom's Window Manager" + * + * 27-Oct-87 Thomas E. LaStrange File created + * 10-Oct-90 David M. Sternlicht Storing saved colors on root + ***********************************************************************/ + +#include +#include +#include +#include /* for sleep() */ +#include +#include +#include "twm.h" +#include "add_window.h" +#include "gc.h" +#include "parse.h" +#include "version.h" +#include "menus.h" +#include "events.h" +#include "util.h" +#include "gram.h" +#include "screen.h" +#include "iconmgr.h" +#include "desktop.h" +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT +#include "sound.h" +#endif +#include +#include +#include +#include +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT +#include +#endif + +Display *dpy; /* which display are we talking to */ +Window ResizeWindow; /* the window we are resizing */ + +int MultiScreen = TRUE; /* try for more than one screen? */ +int NumScreens; /* number of screens in ScreenList */ +int HasShape; /* server supports shape extension? */ +int ShapeEventBase, ShapeErrorBase; +ScreenInfo **ScreenList; /* structures for each screen */ +ScreenInfo *Scr = NULL; /* the cur and prev screens */ +int PreviousScreen; /* last screen that we were on */ +int FirstScreen; /* TRUE ==> first screen of display */ +Bool PrintPID = False; /* controls PID file - djhjr - 12/2/01 */ +Bool PrintErrorMessages = False; /* controls error messages */ +static int RedirectError; /* TRUE ==> another window manager running */ +static int CatchRedirectError(); /* for settting RedirectError */ +static int TwmErrorHandler(); /* for everything else */ +void InitVariables(); +void InternUsefulAtoms(); + +char Info[INFO_LINES][INFO_SIZE]; /* info strings to print */ +int InfoLines; + +char *InitFile = NULL; +int parseInitFile = TRUE; /* djhjr - 10/7/02 */ + +Cursor UpperLeftCursor; /* upper Left corner cursor */ +Cursor RightButt; +Cursor MiddleButt; +Cursor LeftButt; + +XContext TwmContext; /* context for twm windows */ +XContext MenuContext; /* context for all menu windows */ +XContext IconManagerContext; /* context for all window list windows */ +XContext VirtualContext; /* context for all desktop display windows */ +XContext ScreenContext; /* context to get screen data */ +XContext ColormapContext; /* context for colormap operations */ +XContext DoorContext; /* context for doors */ + +XClassHint NoClass; /* for applications with no class */ + +XGCValues Gcv; + +char *Home; /* the HOME environment variable */ +int HomeLen; /* length of Home */ +int ParseError; /* error parsing the .twmrc file */ + +int HandlingEvents = FALSE; /* are we handling events yet? */ + +Window JunkRoot; /* junk window */ +Window JunkChild; /* junk window */ +int JunkX; /* junk variable */ +int JunkY; /* junk variable */ +unsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth, JunkMask; + +char *ProgramName, *PidName = "vtwm.pid"; /* PID file - djhjr - 12/2/01 */ +int Argc; +char **Argv; +char **Environ; + +Bool RestartPreviousState = False; /* try to restart in previous state */ + +unsigned long black, white; + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT +Bool use_fontset; +#endif + +extern void assign_var_savecolor(); + +/* djhjr - 4/26/99 */ +extern void FreeRegions(); + +/*********************************************************************** + * + * Procedure: + * main - start of twm + * + *********************************************************************** + */ + +/* Changes for m4 pre-processing submitted by Jason Gloudon */ +int +main(argc, argv, environ) + int argc; + char **argv; + char **environ; +{ + Window root, parent, *children; + unsigned int nchildren; + int i, j; + char *def, *display_name = NULL; + unsigned long valuemask; /* mask for create windows */ + XSetWindowAttributes attributes; /* attributes for create windows */ + int numManaged, firstscrn, lastscrn, scrnum; + extern ColormapWindow *CreateColormapWindow(); +#ifndef NO_M4_SUPPORT + int m4_preprocess = False; /* filter the *twmrc file through m4 */ + char *m4_option = NULL; /* pass these options to m4 - djhjr - 2/20/98 */ +#endif +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + int sound_state = 0; +#endif + extern char *defTwmrc[]; /* djhjr - 10/7/02 */ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + char *loc; +#endif + + /* djhjr - 7/21/98 */ + SIGNAL_T QueueRestartVtwm(); + + if ((ProgramName = strrchr(argv[0], '/'))) + ProgramName++; + else + ProgramName = argv[0]; + Argc = argc; + Argv = argv; + Environ = environ; + + for (i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + switch (argv[i][1]) { + case 'd': /* -display display */ + if (++i >= argc) goto usage; + display_name = argv[i]; + continue; + case 'f': /* -file [initfile] */ + /* this isn't really right, but hey... - djhjr - 10/7/02 */ + if (i + 1 < argc && + (argv[i + 1][0] != '-' || + (argv[i + 1][0] == '-' && !strchr("dfmpsv", argv[i + 1][1])))) + InitFile = argv[++i]; + else + parseInitFile = FALSE; + continue; +#ifndef NO_M4_SUPPORT + case 'm': /* -m4 [options] */ + m4_preprocess = True; + /* this isn't really right, but hey... - djhjr - 2/20/98 */ + if (i + 1 < argc && + (argv[i + 1][0] != '-' || + (argv[i + 1][0] == '-' && !strchr("dfmpsv", argv[i + 1][1])))) + m4_option = argv[++i]; + continue; +#endif + case 'p': /* -pidfile - djhjr - 12/2/01 */ + PrintPID = True; + continue; + case 's': /* -single */ + MultiScreen = FALSE; + continue; + case 'v': /* -verbose */ + PrintErrorMessages = True; + continue; +#ifdef NEVER /* djhjr - 2/20/99 */ + case 'q': /* -quiet */ + PrintErrorMessages = False; + continue; +#endif + } + } + usage: + fprintf (stderr, +#ifndef NO_M4_SUPPORT + "usage: %s [-d display] [-f [initfile]] [-m [options]] [-p] [-s] [-v]\n", +#else + "usage: %s [-d display] [-f [initfile]] [-p] [-s] [-v]\n", +#endif + ProgramName); + exit (1); + } + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + loc = setlocale(LC_ALL, ""); + if (!loc || !strcmp(loc, "C") || !strcmp(loc, "POSIX") || + !XSupportsLocale()) + use_fontset = False; + else + use_fontset = True; + + if (PrintErrorMessages) + fprintf(stderr, "%s: I18N supported, L10N %sabled\n", + ProgramName, (use_fontset) ? "en" : "dis"); +#endif + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT +#define sounddonehandler(sig) \ + if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, PlaySoundDone) +#else +#define sounddonehandler(sig) \ + if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, Done) +#endif +#define donehandler(sig) \ + if (signal (sig, SIG_IGN) != SIG_IGN) (void) signal (sig, Done) + + sounddonehandler (SIGINT); + sounddonehandler (SIGHUP); + sounddonehandler (SIGQUIT); + sounddonehandler (SIGTERM); + + /* djhjr - 12/2/01 */ + donehandler (SIGABRT); + donehandler (SIGFPE); + donehandler (SIGSEGV); + donehandler (SIGILL); + donehandler (SIGTSTP); + donehandler (SIGPIPE); +#undef sounddonehandler +#undef donehandler + + /* djhjr - 7/31/98 */ + signal (SIGUSR1, QueueRestartVtwm); + + Home = getenv("HOME"); + if (Home == NULL) + Home = "./"; + + HomeLen = strlen(Home); + + NoClass.res_name = NoName; + NoClass.res_class = NoName; + + if (!(dpy = XOpenDisplay(display_name))) { + fprintf (stderr, "%s: unable to open display \"%s\"\n", + ProgramName, XDisplayName(display_name)); + exit (1); + } + + if (fcntl(ConnectionNumber(dpy), F_SETFD, 1) == -1) { + fprintf (stderr, + "%s: unable to mark display connection as close-on-exec\n", + ProgramName); + exit (1); + } + + HasShape = XShapeQueryExtension (dpy, &ShapeEventBase, &ShapeErrorBase); + TwmContext = XUniqueContext(); + MenuContext = XUniqueContext(); + IconManagerContext = XUniqueContext(); + VirtualContext = XUniqueContext(); + ScreenContext = XUniqueContext(); + ColormapContext = XUniqueContext(); + DoorContext = XUniqueContext(); + + InternUsefulAtoms (); + + + /* Set up the per-screen global information. */ + + NumScreens = ScreenCount(dpy); + + if (MultiScreen) + { + firstscrn = 0; + lastscrn = NumScreens - 1; + } + else + { + firstscrn = lastscrn = DefaultScreen(dpy); + } + + InfoLines = 0; + + /* for simplicity, always allocate NumScreens ScreenInfo struct pointers */ + ScreenList = (ScreenInfo **) calloc (NumScreens, sizeof (ScreenInfo *)); + if (ScreenList == NULL) + { + fprintf (stderr, "%s: Unable to allocate memory for screen list, exiting.\n", + ProgramName); + exit (1); + } + numManaged = 0; + PreviousScreen = DefaultScreen(dpy); + FirstScreen = TRUE; + for (scrnum = firstscrn ; scrnum <= lastscrn; scrnum++) + { + /* Make sure property priority colors is empty */ + XChangeProperty (dpy, RootWindow(dpy, scrnum), _XA_MIT_PRIORITY_COLORS, + XA_CARDINAL, 32, PropModeReplace, NULL, 0); + RedirectError = FALSE; + XSetErrorHandler(CatchRedirectError); + XSelectInput(dpy, RootWindow (dpy, scrnum), + ColormapChangeMask | EnterWindowMask | PropertyChangeMask | + SubstructureRedirectMask | KeyPressMask | + ButtonPressMask | ButtonReleaseMask); + XSync(dpy, 0); + XSetErrorHandler(TwmErrorHandler); + + if (RedirectError) + { + fprintf (stderr, "%s: another window manager is already running", + ProgramName); + if (MultiScreen && NumScreens > 0) + fprintf(stderr, " on screen %d?\n", scrnum); + else + fprintf(stderr, "?\n"); + continue; + } + + numManaged ++; + + /* Note: ScreenInfo struct is calloc'ed to initialize to zero. */ + Scr = ScreenList[scrnum] = + (ScreenInfo *) calloc(1, sizeof(ScreenInfo)); + if (Scr == NULL) + { + fprintf (stderr, "%s: unable to allocate memory for ScreenInfo structure for screen %d.\n", + ProgramName, scrnum); + continue; + } + + /* initialize list pointers, remember to put an initialization + * in InitVariables also + */ + Scr->BorderColorL = NULL; + Scr->IconBorderColorL = NULL; + Scr->BorderTileForegroundL = NULL; + Scr->BorderTileBackgroundL = NULL; + Scr->TitleForegroundL = NULL; + Scr->TitleBackgroundL = NULL; + Scr->IconForegroundL = NULL; + Scr->IconBackgroundL = NULL; + Scr->NoTitle = NULL; + Scr->MakeTitle = NULL; + Scr->AutoRaise = NULL; + Scr->IconNames = NULL; + Scr->NoHighlight = NULL; + Scr->NoStackModeL = NULL; + Scr->NoTitleHighlight = NULL; + Scr->DontIconify = NULL; + Scr->IconMgrNoShow = NULL; + Scr->IconMgrShow = NULL; + Scr->IconifyByUn = NULL; + Scr->IconManagerFL = NULL; + Scr->IconManagerBL = NULL; + Scr->IconMgrs = NULL; + Scr->StartIconified = NULL; + Scr->SqueezeTitleL = NULL; + Scr->DontSqueezeTitleL = NULL; + Scr->WindowRingL = NULL; + + /* submitted by Jonathan Paisley - 10/27/02 */ + Scr->NoWindowRingL = NULL; + + Scr->WarpCursorL = NULL; + + /* djhjr - 4/22/96 */ + Scr->ImageCache = NULL; + + /* djhjr - 4/7/98 */ + Scr->OpaqueMoveL = NULL; + Scr->NoOpaqueMoveL = NULL; + Scr->OpaqueResizeL = NULL; + Scr->NoOpaqueResizeL = NULL; + + /* djhjr - 5/2/98 */ + Scr->NoBorder = NULL; + + /* djhjr - 9/24/02 */ + Scr->UsePPositionL = NULL; + + /* remember to put an initialization in InitVariables also + */ + + Scr->screen = scrnum; + Scr->d_depth = DefaultDepth(dpy, scrnum); + Scr->d_visual = DefaultVisual(dpy, scrnum); + Scr->Root = RootWindow(dpy, scrnum); + XSaveContext (dpy, Scr->Root, ScreenContext, (caddr_t) Scr); + + /* djhjr - 1/31/99 */ + if ((def = XGetDefault(dpy, "*", "bitmapFilePath"))) + Scr->BitmapFilePath = strdup(def); + else + Scr->BitmapFilePath = NULL; + + Scr->TwmRoot.cmaps.number_cwins = 1; + Scr->TwmRoot.cmaps.cwins = + (ColormapWindow **) malloc(sizeof(ColormapWindow *)); + Scr->TwmRoot.cmaps.cwins[0] = + CreateColormapWindow(Scr->Root, True, False); + Scr->TwmRoot.cmaps.cwins[0]->visibility = VisibilityPartiallyObscured; + + Scr->cmapInfo.cmaps = NULL; + Scr->cmapInfo.maxCmaps = + MaxCmapsOfScreen(ScreenOfDisplay(dpy, Scr->screen)); + Scr->cmapInfo.root_pushes = 0; + InstallWindowColormaps(0, &Scr->TwmRoot); + + Scr->StdCmapInfo.head = Scr->StdCmapInfo.tail = + Scr->StdCmapInfo.mru = NULL; + Scr->StdCmapInfo.mruindex = 0; + LocateStandardColormaps(); + + Scr->TBInfo.nleft = Scr->TBInfo.nright = 0; + Scr->TBInfo.head = NULL; + +/* djhjr - 4/19/96 + Scr->TBInfo.border = 1; +*/ + Scr->TBInfo.border = -100; + + Scr->TBInfo.width = 0; + Scr->TBInfo.leftx = 0; + Scr->TBInfo.titlex = 0; + + Scr->MyDisplayWidth = DisplayWidth(dpy, scrnum); + Scr->MyDisplayHeight = DisplayHeight(dpy, scrnum); + Scr->MaxWindowWidth = 32767 - Scr->MyDisplayWidth; + Scr->MaxWindowHeight = 32767 - Scr->MyDisplayHeight; + + Scr->XORvalue = (((unsigned long) 1) << Scr->d_depth) - 1; + + if (DisplayCells(dpy, scrnum) < 3) + Scr->Monochrome = MONOCHROME; + else + Scr->Monochrome = COLOR; + + /* setup default colors */ + Scr->FirstTime = TRUE; + GetColor(Scr->Monochrome, &black, "black"); + Scr->Black = black; + GetColor(Scr->Monochrome, &white, "white"); + Scr->White = white; + + if (FirstScreen) + { + SetFocus ((TwmWindow *)NULL, CurrentTime); + + /* define cursors */ + + NewFontCursor(&UpperLeftCursor, "top_left_corner"); + NewFontCursor(&RightButt, "rightbutton"); + NewFontCursor(&LeftButt, "leftbutton"); + NewFontCursor(&MiddleButt, "middlebutton"); + } + + Scr->iconmgr.x = 0; + Scr->iconmgr.y = 0; + Scr->iconmgr.width = 150; + Scr->iconmgr.height = 5; + Scr->iconmgr.next = NULL; + Scr->iconmgr.prev = NULL; + Scr->iconmgr.lasti = &(Scr->iconmgr); + Scr->iconmgr.first = NULL; + Scr->iconmgr.last = NULL; + Scr->iconmgr.active = NULL; + Scr->iconmgr.scr = Scr; + Scr->iconmgr.columns = 1; + Scr->iconmgr.count = 0; + Scr->iconmgr.name = "VTWM"; + Scr->iconmgr.icon_name = "Icons"; + + Scr->IconDirectory = NULL; + + /* djhjr - 10/30/02 */ + Scr->hiliteName = NULL; + Scr->menuIconName = TBPM_MENU; + Scr->iconMgrIconName = TBPM_XLOGO; + +/* djhjr - 10/30/02 + Scr->siconifyPm = NULL; + Scr->pullPm = NULL; +*/ + +/* djhjr - 5/17/98 */ +#ifdef ORIGINAL_PIXMAPS + Scr->hilitePm = None; + Scr->virtualPm = None; /* RFB PIXMAP */ + Scr->RealScreenPm = None; /* RFB PIXMAP */ +#else /* ORIGINAL_PIXMAPS */ + /* djhjr - 10/25/02 */ + Scr->hiliteName = NULL; + + Scr->hilitePm = NULL; + Scr->virtualPm = NULL; + Scr->realscreenPm = NULL; +#endif /* ORIGINAL_PIXMAPS */ + + if ( Scr->FirstTime ) + { /* retain max size on restart. */ + Scr->VirtualDesktopMaxWidth = 0; + Scr->VirtualDesktopMaxHeight = 0; + } + + InitVariables(); + InitMenus(); + + /* added this 'if (...) else' - djhjr - 10/7/02 */ + if (!parseInitFile) + ParseStringList(defTwmrc); + else + { + /* Parse it once for each screen. */ +#ifndef NO_M4_SUPPORT + /* added 'm4_option' - djhjr - 2/20/99 */ + ParseTwmrc(InitFile, display_name, m4_preprocess, m4_option); +#else + ParseTwmrc(InitFile); +#endif + } + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + OpenSound(); + + if (PlaySound(S_START)) + { + /* + * Save setting from resource file, and turn sound off + */ + sound_state = ToggleSounds(); + sound_state ^= 1; + if (sound_state == 0) ToggleSounds(); + } +#endif + + assign_var_savecolor(); /* storeing pixels for twmrc "entities" */ + +/* djhjr - 10/17/02 */ +#if 0 + /* djhjr - 4/19/96 */ + /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */ + if (Scr->TitleBevelWidth > 0) { +/* djhjr - 10/17/02 + if (Scr->TBInfo.border == -100) Scr->TBInfo.border = 0; +*/ + +/* djhjr - 3/12/97 + if (Scr->ButtonIndent == -100) Scr->ButtonIndent = 0; + if (Scr->FramePadding == -100) Scr->FramePadding = 0; + if (Scr->TitlePadding == -100) Scr->TitlePadding = 0; +*/ + Scr->ButtonIndent = 0; + Scr->FramePadding = 0; + Scr->TitlePadding = 0; + +/* djhjr - 4/3/98 + * djhjr - 4/26/96 * + if (Scr->SunkFocusWindowTitle) Scr->TitleHighlight = FALSE; +*/ + } + else { + /* djhjr - 4/5/98 */ + Scr->SunkFocusWindowTitle = FALSE; + } +#endif + + /* was only if Scr->TitleBevelWidth == 0 - djhjr - 10/17/02 */ + if (Scr->FramePadding == -100) Scr->FramePadding = 2; /* values that look */ + if (Scr->TitlePadding == -100) Scr->TitlePadding = 8; /* "nice" on */ + if (Scr->ButtonIndent == -100) Scr->ButtonIndent = 1; /* 75 and 100dpi displays */ + if (Scr->TBInfo.border == -100) Scr->TBInfo.border = 1; + + /* was 'Scr->use3D*' - djhjr - 8/11/98 */ + /* rem'd 'Scr->*BevelWidth > 0' - djhjr - 10/30/02 */ + if (/*Scr->TitleBevelWidth > 0 && */!Scr->BeNiceToColormap) GetShadeColors (&Scr->TitleC); + if (/*Scr->MenuBevelWidth > 0 && */!Scr->BeNiceToColormap) GetShadeColors (&Scr->MenuC); + if (Scr->MenuBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&Scr->MenuTitleC); + if (Scr->BorderBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&Scr->BorderColorC); + + /* djhjr - 2/7/99 */ + if (Scr->DoorBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&Scr->DoorC); + if (Scr->VirtualDesktopBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&Scr->VirtualC); + +/* djhjr - 8/11/98 + * was 'Scr->use3Dborders' - djhjr - 8/11/98 * + if (Scr->BorderBevelWidth == 0) + Scr->ThreeDBorderWidth = 0; + else +*/ + { +/* djhjr - 8/11/98 + * djhjr - 4/29/98 * + if (2 * Scr->BorderBevelWidth > Scr->ThreeDBorderWidth) + Scr->ThreeDBorderWidth = 2 * Scr->BorderBevelWidth; +*/ + if (2 * Scr->BorderBevelWidth > Scr->BorderWidth) + Scr->BorderWidth = 2 * Scr->BorderBevelWidth; + + if (!Scr->BeNiceToColormap) + GetShadeColors(&Scr->DefaultC); + } + + /* djhjr - 5/5/98 */ + /* was 'Scr->use3Dicons' - djhjr - 8/11/98 */ + if (Scr->IconBevelWidth > 0) + Scr->IconBorderWidth = 0; + + if (Scr->SqueezeTitle == -1) Scr->SqueezeTitle = FALSE; + if (!Scr->HaveFonts) CreateFonts(); + CreateGCs(); + MakeMenus(); + +/* djhjr - 10/18/02 */ +#if 0 + /* + * Set titlebar height from font height and padding, + * then adjust to titlebutton height - djhjr - 12/10/98 + */ + Scr->TitleBarFont.y += Scr->FramePadding; + i = Scr->TitleBarFont.height; + do + { + Scr->TitleBarFont.y += (i - Scr->TitleBarFont.height) / 2; + Scr->TitleHeight = i + Scr->FramePadding * 2; + +/* djhjr - 4/29/98 + * djhjr - 4/19/96 * + if (Scr->use3Dtitles) Scr->TitleHeight += 4; +*/ +/* djhjr - 10/18/02 + * was 'Scr->use3Dtitles' - djhjr - 8/11/98 * + if (Scr->TitleBevelWidth > 0) + Scr->TitleHeight += 2 * Scr->TitleBevelWidth + 2; +*/ + + /* make title height be odd so buttons look nice and centered */ + if (!(Scr->TitleHeight & 1)) Scr->TitleHeight++; + } while ((i = InitTitlebarButtons()) > Scr->TitleHeight - Scr->FramePadding * 2); +#else + /* set titlebar height to font height plus frame padding */ + Scr->TitleHeight = Scr->TitleBarFont.height + Scr->FramePadding * 2; + if (!(Scr->TitleHeight & 1)) Scr->TitleHeight++; + + i = InitTitlebarButtons(); /* returns the button height */ + + /* adjust titlebar height to button height */ + if (i > Scr->TitleHeight) Scr->TitleHeight = i + Scr->FramePadding * 2; + if (!(Scr->TitleHeight & 1)) Scr->TitleHeight++; + + /* adjust font baseline */ + Scr->TitleBarFont.y += ((Scr->TitleHeight - Scr->TitleBarFont.height) / 2); +#endif + + XGrabServer(dpy); + XSync(dpy, 0); + + JunkX = 0; + JunkY = 0; + + XQueryTree(dpy, Scr->Root, &root, &parent, &children, &nchildren); + CreateIconManagers(); + if (!Scr->NoIconManagers) + Scr->iconmgr.twm_win->icon = TRUE; + + if (Scr->VirtualDesktopWidth > 0) + CreateDesktopDisplay(); + + /* create all of the door windows */ + door_open_all(); + + /* + * weed out icon windows + */ + for (i = 0; i < nchildren; i++) { + if (children[i]) { + XWMHints *wmhintsp = XGetWMHints (dpy, children[i]); + + if (wmhintsp) { + if (wmhintsp->flags & IconWindowHint) { + for (j = 0; j < nchildren; j++) { + if (children[j] == wmhintsp->icon_window) { + children[j] = None; + break; + } + } + } + XFree ((char *) wmhintsp); + } + } + } + + /* + * map all of the non-override windows + */ + for (i = 0; i < nchildren; i++) + { + if (children[i] && MappedNotOverride(children[i])) + { + XUnmapWindow(dpy, children[i]); + SimulateMapRequest(children[i]); + } + } + + if (Scr->ShowIconManager && !Scr->NoIconManagers) + { + Scr->iconmgr.twm_win->icon = FALSE; + if (Scr->iconmgr.count) + { + SetMapStateProp (Scr->iconmgr.twm_win, NormalState); + XMapWindow(dpy, Scr->iconmgr.w); + XMapWindow(dpy, Scr->iconmgr.twm_win->frame); + } + } + + /* djhjr - 5/9/96 */ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (!Scr->BorderBevelWidth > 0) + attributes.border_pixel = Scr->DefaultC.fore; + + attributes.background_pixel = Scr->DefaultC.back; + attributes.event_mask = (ExposureMask | ButtonPressMask | + KeyPressMask | ButtonReleaseMask); + attributes.backing_store = NotUseful; + +#ifdef ORIGINAL_INFOCURSOR + attributes.cursor = XCreateFontCursor (dpy, Scr->WaitCursor); + + /* djhjr - 5/9/96 */ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (!Scr->BorderBevelWidth > 0) + valuemask = (CWBorderPixel | CWBackPixel | CWEventMask | + CWBackingStore | CWCursor); + else + valuemask = (CWBackPixel | CWEventMask | CWBackingStore | CWCursor); +#else + + /* djhjr - 5/9/96 */ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (!Scr->BorderBevelWidth > 0) + valuemask = (CWBorderPixel | CWBackPixel | CWEventMask | + CWBackingStore); + else + valuemask = (CWBackPixel | CWEventMask | CWBackingStore); +#endif + + Scr->InfoWindow = XCreateWindow (dpy, Scr->Root, 0, 0, + (unsigned int) 5, (unsigned int) 5, + + /* djhjr - 5/9/96 */ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + (unsigned int) (Scr->InfoBevelWidth > 0) ? 0 : BW, 0, + + (unsigned int) CopyFromParent, + (Visual *) CopyFromParent, + valuemask, &attributes); + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + Scr->SizeStringWidth = MyFont_TextWidth (&Scr->SizeFont, +#else + Scr->SizeStringWidth = XTextWidth (Scr->SizeFont.font, +#endif +/* djhjr - 5/9/96 + " 8888 x 8888 ", 13); +*/ +/* djhjr - 4/29/98 + "nnnnnnnnnnnnn", 13); +*/ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + "nnnnnnnnnnnnn", 13) + ((Scr->InfoBevelWidth > 0) ? 2 * Scr->InfoBevelWidth : 0); + + /* djhjr - 5/9/96 */ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + if (!Scr->InfoBevelWidth > 0) + valuemask = (CWBorderPixel | CWBackPixel | CWBitGravity); + else + valuemask = (CWBackPixel | CWBitGravity); + + /* djhjr - 5/15/96 */ + switch (Scr->ResizeX) + { + case R_NORTHWEST: + Scr->ResizeX = 20; + Scr->ResizeY = 20; + break; + case R_NORTHEAST: + Scr->ResizeX = (Scr->MyDisplayWidth - Scr->SizeStringWidth) - 20; + Scr->ResizeY = 20; + break; + case R_SOUTHWEST: + Scr->ResizeX = 20; + Scr->ResizeY = (Scr->MyDisplayHeight - (Scr->SizeFont.height + SIZE_VINDENT*2)) - 20; + break; + case R_SOUTHEAST: + Scr->ResizeX = (Scr->MyDisplayWidth - Scr->SizeStringWidth) - 20; + Scr->ResizeY = (Scr->MyDisplayHeight - (Scr->SizeFont.height + SIZE_VINDENT*2)) - 20; + break; + case R_CENTERED: + Scr->ResizeX = (Scr->MyDisplayWidth - Scr->SizeStringWidth) / 2; + Scr->ResizeY = (Scr->MyDisplayHeight - (Scr->SizeFont.height + SIZE_VINDENT*2)) / 2; + break; + } + + attributes.bit_gravity = NorthWestGravity; + Scr->SizeWindow = XCreateWindow (dpy, Scr->Root, + +/* djhjr - 5/15/96 + 0,0, +*/ + Scr->ResizeX, Scr->ResizeY, + + (unsigned int) Scr->SizeStringWidth, + +/* djhjr - 4/29/98 + (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2), +*/ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2) + + ((Scr->InfoBevelWidth > 0) ? 2 * Scr->InfoBevelWidth : 0), + + /* djhjr - 5/9/96 */ + /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ + (unsigned int) (Scr->InfoBevelWidth > 0) ? 0 : BW, 0, + + (unsigned int) CopyFromParent, + (Visual *) CopyFromParent, + valuemask, &attributes); + + XUngrabServer(dpy); + + FirstScreen = FALSE; + Scr->FirstTime = FALSE; + } /* for */ + + if (numManaged == 0) { + if (MultiScreen && NumScreens > 0) + fprintf (stderr, "%s: unable to find any unmanaged screens\n", + ProgramName); + exit (1); + + } + + RestartPreviousState = False; + HandlingEvents = TRUE; + + RaiseStickyAbove(); /* DSE */ + RaiseAutoPan(); /* autopan windows should have been raised + after [re]starting vtwm -- DSE */ + + InitEvents(); + + /* profile function stuff by DSE */ +#define VTWM_PROFILE "VTWM Profile" + if (FindMenuRoot (VTWM_PROFILE)) { + ExecuteFunction (F_FUNCTION, VTWM_PROFILE, Event.xany.window, + &Scr->TwmRoot, &Event, C_NO_CONTEXT, FALSE); + } + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT + /* restore setting from resource file */ + if (sound_state == 1) ToggleSounds(); +#endif + + + /* write out a PID file - djhjr - 12/2/01 */ + if (PrintPID) + { + int fd, err = 0; + char buf[10], *fn = malloc(HomeLen + strlen(PidName) + 2); + + /* removed group and other permissions - djhjr - 10/20/02 */ + sprintf(fn, "%s/%s", Home, PidName); + if ((fd = open(fn, + O_WRONLY|O_EXCL|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR)) != -1) + { + sprintf(buf, "%d\n", getpid()); + err = write(fd, buf, strlen(buf)); + close(fd); + } + + if (fd == -1 || err == -1) + { + fprintf(stderr, "%s: cannot write to %s\n", ProgramName, fn); + DoAudible(); + } + + free(fn); + } + + HandleEvents(); + + return (0); +} + +/*********************************************************************** + * + * Procedure: + * InitVariables - initialize twm variables + * + *********************************************************************** + */ + +void InitVariables() +{ + FreeList(&Scr->BorderColorL); + FreeList(&Scr->IconBorderColorL); + FreeList(&Scr->BorderTileForegroundL); + FreeList(&Scr->BorderTileBackgroundL); + FreeList(&Scr->TitleForegroundL); + FreeList(&Scr->TitleBackgroundL); + FreeList(&Scr->IconForegroundL); + FreeList(&Scr->IconBackgroundL); + FreeList(&Scr->IconManagerFL); + FreeList(&Scr->IconManagerBL); + FreeList(&Scr->IconMgrs); + FreeList(&Scr->NoTitle); + FreeList(&Scr->MakeTitle); + FreeList(&Scr->AutoRaise); + FreeList(&Scr->IconNames); + FreeList(&Scr->NoHighlight); + FreeList(&Scr->NoStackModeL); + FreeList(&Scr->NoTitleHighlight); + FreeList(&Scr->DontIconify); + FreeList(&Scr->IconMgrNoShow); + FreeList(&Scr->IconMgrShow); + FreeList(&Scr->IconifyByUn); + FreeList(&Scr->StartIconified); + FreeList(&Scr->IconManagerHighlightL); + FreeList(&Scr->SqueezeTitleL); + FreeList(&Scr->DontSqueezeTitleL); + FreeList(&Scr->WindowRingL); + + /* submitted by Jonathan Paisley - 10/27/02 */ + FreeList(&Scr->NoWindowRingL); + + FreeList(&Scr->WarpCursorL); + FreeList(&Scr->NailedDown); + FreeList(&Scr->VirtualDesktopColorFL); + FreeList(&Scr->VirtualDesktopColorBL); + FreeList(&Scr->VirtualDesktopColorBoL); + FreeList(&Scr->DontShowInDisplay); + + /* Submitted by Erik Agsjo */ + FreeList(&Scr->DontShowInTWMWindows); + + FreeList(&Scr->DoorForegroundL); + FreeList(&Scr->DoorBackgroundL); + + /* djhjr - 4/22/96 */ + FreeList(&Scr->ImageCache); + + /* djhjr - 4/7/98 */ + FreeList(&Scr->OpaqueMoveL); + FreeList(&Scr->NoOpaqueMoveL); + FreeList(&Scr->OpaqueResizeL); + FreeList(&Scr->NoOpaqueResizeL); + + /* djhjr - 5/2/98 */ + FreeList(&Scr->NoBorder); + + /* djhjr - 9/24/02 */ + FreeList(&Scr->UsePPositionL); + + NewFontCursor(&Scr->FrameCursor, "top_left_arrow"); + NewFontCursor(&Scr->TitleCursor, "top_left_arrow"); + NewFontCursor(&Scr->IconCursor, "top_left_arrow"); + NewFontCursor(&Scr->IconMgrCursor, "top_left_arrow"); + NewFontCursor(&Scr->MoveCursor, "fleur"); + NewFontCursor(&Scr->ResizeCursor, "fleur"); + NewFontCursor(&Scr->MenuCursor, "sb_left_arrow"); + NewFontCursor(&Scr->ButtonCursor, "hand2"); + NewFontCursor(&Scr->WaitCursor, "watch"); + NewFontCursor(&Scr->SelectCursor, "dot"); + NewFontCursor(&Scr->DestroyCursor, "pirate"); + NewFontCursor(&Scr->DoorCursor, "exchange");/*RFBCURSOR*/ + NewFontCursor(&Scr->VirtualCursor, "rtl_logo");/*RFBCURSOR*/ + NewFontCursor(&Scr->DesktopCursor, "dotbox");/*RFBCURSOR*/ + Scr->NoCursor = NoCursor(); + + Scr->Ring = NULL; + Scr->RingLeader = NULL; + + Scr->DefaultC.fore = black; + Scr->DefaultC.back = white; + Scr->BorderColor = black; + Scr->BorderTileC.fore = black; + Scr->BorderTileC.back = white; + Scr->TitleC.fore = black; + Scr->TitleC.back = white; + Scr->MenuC.fore = black; + Scr->MenuC.back = white; + Scr->MenuTitleC.fore = black; + Scr->MenuTitleC.back = white; + Scr->MenuShadowColor = black; + Scr->IconC.fore = black; + Scr->IconC.back = white; + Scr->IconBorderColor = black; + Scr->IconManagerC.fore = black; + Scr->IconManagerC.back = white; + Scr->IconManagerHighlight = black; + + /* djhjr - 4/19/96 */ + Scr->FramePadding = -100; + Scr->TitlePadding = -100; + Scr->ButtonIndent = -100; + +/* djhjr - 8/11/98 + Scr->ThreeDBorderWidth = 6; +*/ + + /* djhjr - 5/15/96 */ + Scr->ResizeX = Scr->ResizeY = 0; + + Scr->VirtualC.fore = black;/*RFB VCOLOR*/ + Scr->VirtualC.back = white;/*RFB VCOLOR*/ + Scr->RealScreenC.back = black;/*RFB 4/92 */ + Scr->RealScreenC.fore = white;/*RFB 4/92 */ + Scr->VirtualDesktopDisplayC.fore = black; + Scr->VirtualDesktopDisplayC.back = white; + Scr->VirtualDesktopDisplayBorder = black; + Scr->DoorC.fore = black; + Scr->DoorC.back = white; + + Scr->AutoRaiseDefault = FALSE;/*RAISEDELAY*/ + Scr->FramePadding = 2; /* values that look "nice" on */ + Scr->TitlePadding = 8; /* 75 and 100dpi displays */ + Scr->ButtonIndent = 1; + Scr->SizeStringOffset = 0; + Scr->BorderWidth = BW; + Scr->IconBorderWidth = BW; + +/* djhjr - 8/13/98 */ +#ifdef ORIGINAL_PIXMAPS + Scr->UnknownWidth = 0; + Scr->UnknownHeight = 0; +#else + Scr->unknownName = NULL; +#endif + + Scr->NumAutoRaises = 0; +/* Scr->NoDefaults = FALSE; */ + Scr->NoDefaultMouseOrKeyboardBindings = FALSE; /* DSE */ + Scr->NoDefaultTitleButtons = FALSE; /* DSE */ + Scr->UsePPosition = PPOS_OFF; + Scr->FocusRoot = TRUE; + Scr->Newest = NULL; /* PF */ + Scr->Focus = NULL; + + /* djhjr - 9/10/03 */ + Scr->IgnoreModifiers = 0; + + /* djhjr - 10/16/02 */ + Scr->WarpCentered = WARPC_OFF; + + Scr->WarpCursor = FALSE; + Scr->ForceIcon = FALSE; + Scr->NoGrabServer = FALSE; + Scr->NoRaiseMove = FALSE; + Scr->NoRaiseResize = FALSE; + Scr->NoRaiseDeicon = FALSE; + Scr->NoRaiseWarp = FALSE; + Scr->DontMoveOff = FALSE; + Scr->DoZoom = FALSE; + Scr->TitleFocus = TRUE; + + /* djhjr - 5/27/98 */ + Scr->IconManagerFocus = TRUE; + + /* djhjr - 12/14/98 */ + Scr->StaticIconPositions = FALSE; + + /* djhjr - 10/2/01 */ + Scr->StrictIconManager = FALSE; + + /* djhjr - 8/23/02 */ + Scr->NoBorders = FALSE; + + Scr->NoTitlebar = FALSE; + Scr->DecorateTransients = FALSE; + Scr->IconifyByUnmapping = FALSE; + Scr->ShowIconManager = FALSE; + Scr->IconManagerDontShow =FALSE; + Scr->BackingStore = TRUE; + Scr->SaveUnder = TRUE; + Scr->RandomPlacement = FALSE; + Scr->PointerPlacement = FALSE; + Scr->OpaqueMove = FALSE; + + /* djhjr - 4/6/98 */ + Scr->OpaqueResize = FALSE; + + Scr->Highlight = TRUE; + + /* djhjr - 1/27/98 */ + Scr->IconMgrHighlight = TRUE; + + Scr->StackMode = TRUE; + Scr->TitleHighlight = TRUE; + Scr->MoveDelta = 1; /* so that f.deltastop will work */ + Scr->ZoomCount = 8; + Scr->SortIconMgr = FALSE; + Scr->Shadow = TRUE; + Scr->InterpolateMenuColors = FALSE; + Scr->NoIconManagers = FALSE; + Scr->NoIconifyIconManagers = FALSE; /* PF */ + Scr->ClientBorderWidth = FALSE; + Scr->SqueezeTitle = -1; + +/* djhjr - 4/26/99 + Scr->FirstIconRegion = NULL; + Scr->LastIconRegion = NULL; +*/ + FreeRegions(Scr->FirstIconRegion, Scr->LastIconRegion); + + /* djhjr - 4/26/99 */ + FreeRegions(Scr->FirstAppletRegion, Scr->LastAppletRegion); + + Scr->FirstTime = TRUE; + Scr->HaveFonts = FALSE; /* i.e. not loaded yet */ + Scr->CaseSensitive = TRUE; + Scr->WarpUnmapped = FALSE; + Scr->DeIconifyToScreen = FALSE; + Scr->WarpWindows = FALSE; + Scr->WarpToTransients = FALSE; /* PF */ + + /* djhjr - 6/25/96 */ + Scr->ShallowReliefWindowButton = 2; + +/* obsoleted by the *BevelWidth resources - djhjr - 8/11/98 + * djhjr - 4/19/96 * + Scr->use3Diconmanagers = FALSE; + Scr->use3Dmenus = FALSE; + Scr->use3Dtitles = FALSE; + Scr->use3Dborders = FALSE; +*/ + + Scr->ClearBevelContrast = 50; + Scr->DarkBevelContrast = 40; + Scr->BeNiceToColormap = FALSE; + +/* obsoleted by the *BevelWidth resources - djhjr - 8/11/98 + * djhjr - 5/5/98 * + Scr->use3Dicons = FALSE; +*/ + +/* obsoleted by the ":xpm:*" built-in pixmaps - djhjr - 10/26/02 + * djhjr - 4/26/96 * + Scr->SunkFocusWindowTitle = FALSE; +*/ + + /* for rader - djhjr - 2/9/99 */ + Scr->NoPrettyTitles = FALSE; + + /* djhjr - 9/21/96 */ + Scr->ButtonColorIsFrame = FALSE; + + Scr->snapRealScreen = FALSE; + Scr->OldFashionedTwmWindowsMenu = FALSE; + Scr->GeometriesAreVirtual = TRUE; + Scr->UseWindowRing = FALSE; + + /* setup default fonts; overridden by defaults from system.twmrc */ +#define DEFAULT_NICE_FONT "variable" +#define DEFAULT_FAST_FONT "fixed" +#define DEFAULT_SMALL_FONT "5x8" + + Scr->TitleBarFont.font = NULL; + Scr->TitleBarFont.name = DEFAULT_NICE_FONT; + Scr->MenuFont.font = NULL; + Scr->MenuFont.name = DEFAULT_NICE_FONT; + Scr->MenuTitleFont.font = NULL; /* DSE */ + Scr->MenuTitleFont.name = NULL; /* uses MenuFont unless set -- DSE */ + Scr->IconFont.font = NULL; + Scr->IconFont.name = DEFAULT_NICE_FONT; + Scr->SizeFont.font = NULL; + Scr->SizeFont.name = DEFAULT_FAST_FONT; + + /* djhjr - 5/10/96 */ + Scr->InfoFont.font = NULL; + Scr->InfoFont.name = DEFAULT_FAST_FONT; + + Scr->IconManagerFont.font = NULL; + Scr->IconManagerFont.name = DEFAULT_NICE_FONT; + Scr->VirtualFont.font = NULL; + Scr->VirtualFont.name = DEFAULT_SMALL_FONT; + Scr->DoorFont.font = NULL; + Scr->DoorFont.name = DEFAULT_NICE_FONT; + Scr->DefaultFont.font = NULL; + Scr->DefaultFont.name = DEFAULT_FAST_FONT; + + /* no names unless they say so */ + Scr->NamesInVirtualDesktop = FALSE; + + /* by default we emulate the old twm - ie. no virtual desktop */ + Scr->Virtual = FALSE; + + /* this makes some of the algorithms for checking if windows + * are on the screen simpler */ + Scr->VirtualDesktopWidth = Scr->MyDisplayWidth; + Scr->VirtualDesktopHeight = Scr->MyDisplayHeight; + + /* start at the top left of the virtual desktop */ + Scr->VirtualDesktopX = 0; + Scr->VirtualDesktopY = 0; + + /* pan defaults to half screen size */ + Scr->VirtualDesktopPanDistanceX = 50; + Scr->VirtualDesktopPanDistanceY = 50; + + /* djhjr - 9/8/98 */ + Scr->VirtualDesktopPanResistance = 0; + + /* default scale is 1:25 */ + Scr->VirtualDesktopDScale = 25; + + /* and the display should appear at 0, 0 */ + Scr->VirtualDesktopDX = 0; + Scr->VirtualDesktopDY = 0; + + /* by default no autopan */ + Scr->AutoPanX = 0; + Scr->StayUpMenus = FALSE; + Scr->StayUpOptionalMenus = FALSE; /* PF */ + + Scr->AutoPanWarpWithRespectToRealScreen = 0; /* DSE */ + Scr->AutoPanBorderWidth = 5; /* DSE */ + Scr->AutoPanExtraWarp = 2; /* DSE */ + Scr->EnhancedExecResources = FALSE; /* DSE */ + Scr->RightHandSidePulldownMenus = FALSE; /* DSE */ + + /* was '2' for when UseRealScreenBorderWidth existed - djhjr - 2/15/99 */ + Scr->RealScreenBorderWidth = 0; /* DSE */ + + /* djhjr - 10/11/01 */ + Scr->ZoomZoom = FALSE; + + Scr->LessRandomZoomZoom = FALSE; /* DSE */ + Scr->PrettyZoom = FALSE; /* DSE */ + Scr->StickyAbove = FALSE; /* DSE */ + Scr->DontInterpolateTitles = FALSE; /* DSE */ + + /* djhjr - 1/6/98 */ + Scr->FixManagedVirtualGeometries = FALSE; + + Scr->FixTransientVirtualGeometries = FALSE; /* DSE */ + Scr->WarpSnug = FALSE; /* DSE */ + + /* djhjr - 4/17/98 */ + Scr->VirtualReceivesMotionEvents = FALSE; + Scr->VirtualSendsMotionEvents = FALSE; + + /* djhjr - 5/2/98 */ + Scr->BorderBevelWidth = 0; + Scr->TitleBevelWidth = 0; + Scr->MenuBevelWidth = 0; + Scr->IconMgrBevelWidth = 0; + Scr->InfoBevelWidth = 0; + + /* djhjr - 8/11/98 */ + Scr->IconBevelWidth = 0; + Scr->ButtonBevelWidth = 0; + + /* djhjr - 2/7/99 */ + Scr->DoorBevelWidth = 0; + Scr->VirtualDesktopBevelWidth = 0; + + /* djhjr - 5/22/00 */ + Scr->MenuScrollBorderWidth = 2; + Scr->MenuScrollJump = 3; + + /* djhjr - 6/22/99 */ + Scr->DontDeiconifyTransients = FALSE; + + /* submitted by Ugen Antsilevitch - 5/28/00 */ + Scr->WarpVisible = FALSE; + + /* djhjr - 6/22/01 */ + Scr->PauseOnExit = 0; + Scr->PauseOnQuit = 0; + + /* djhjr - 11/3/03 */ + Scr->RaiseOnStart = FALSE; +} + + +void CreateFonts () +{ + GetFont(&Scr->TitleBarFont); + GetFont(&Scr->MenuFont); + GetFont(&Scr->IconFont); + GetFont(&Scr->SizeFont); + + /* djhjr - 5/10/96 */ + GetFont(&Scr->InfoFont); + + GetFont(&Scr->IconManagerFont); + GetFont(&Scr->VirtualFont); + GetFont(&Scr->DoorFont); + GetFont(&Scr->DefaultFont); + GetFont(&Scr->MenuTitleFont); /* DSE */ + Scr->HaveFonts = TRUE; +} + + +void RestoreWithdrawnLocation (tmp) + TwmWindow *tmp; +{ + int gravx, gravy; + unsigned int bw, mask; + XWindowChanges xwc; + + if (XGetGeometry (dpy, tmp->w, &JunkRoot, &xwc.x, &xwc.y, + &JunkWidth, &JunkHeight, &bw, &JunkDepth)) { + + GetGravityOffsets (tmp, &gravx, &gravy); + if (gravy < 0) xwc.y -= tmp->title_height; + + /* djhjr - 4/19/96 */ + xwc.x += gravx * tmp->frame_bw3D; + xwc.y += gravy * tmp->frame_bw3D; + + if (bw != tmp->old_bw) { + int xoff, yoff; + + if (!Scr->ClientBorderWidth) { + xoff = gravx; + yoff = gravy; + } else { + xoff = 0; + yoff = 0; + } + + xwc.x -= (xoff + 1) * tmp->old_bw; + xwc.y -= (yoff + 1) * tmp->old_bw; + } + if (!Scr->ClientBorderWidth) { + xwc.x += gravx * tmp->frame_bw; + xwc.y += gravy * tmp->frame_bw; + } + + mask = (CWX | CWY); + if (bw != tmp->old_bw) { + xwc.border_width = tmp->old_bw; + mask |= CWBorderWidth; + } + + XConfigureWindow (dpy, tmp->w, mask, &xwc); + + if (tmp->wmhints && (tmp->wmhints->flags & IconWindowHint)) { + XUnmapWindow (dpy, tmp->wmhints->icon_window); + } + + } +} + + +void Reborder (time) +Time time; +{ + TwmWindow *tmp; /* temp twm window structure */ + int scrnum; + + /* put a border back around all windows */ + + XGrabServer (dpy); + for (scrnum = 0; scrnum < NumScreens; scrnum++) + { + if ((Scr = ScreenList[scrnum]) == NULL) + continue; + + InstallWindowColormaps (0, &Scr->TwmRoot); /* force reinstall */ + for (tmp = Scr->TwmRoot.next; tmp != NULL; tmp = tmp->next) + { + RestoreWithdrawnLocation (tmp); + XMapWindow (dpy, tmp->w); + } + } + + XUngrabServer (dpy); + SetFocus ((TwmWindow*)NULL, time); +} + +/* delete the PID file - djhjr - 12/2/01 */ +void delete_pidfile() +{ + char *fn; + + if (PrintPID) + { + fn = malloc(HomeLen + strlen(PidName) + 2); + sprintf(fn, "%s/%s", Home, PidName); + unlink(fn); + free(fn); + } +} + + +/* + * Exit handlers. Clean up and exit VTWM. + * + * PlaySoundDone() + * Done() + * QueueRestartVtwm() + */ + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT +SIGNAL_T PlaySoundDone() +{ + if (PlaySound(S_STOP)) + { + /* allow time to emit */ + if (Scr->PauseOnExit) sleep(Scr->PauseOnExit); + } + + Done(); + SIGNAL_RETURN; +} + +void Done() +{ + CloseSound(); + + SetRealScreen(0,0); + Reborder (CurrentTime); + XCloseDisplay(dpy); + + delete_pidfile(); /* djhjr - 12/2/01 */ + + exit(0); +} +#else +SIGNAL_T Done() +{ + SetRealScreen(0,0); + Reborder (CurrentTime); + XCloseDisplay(dpy); + + delete_pidfile(); /* djhjr - 12/2/01 */ + + exit(0); + SIGNAL_RETURN; +} +#endif + +/* djhjr - 7/31/98 */ +SIGNAL_T +QueueRestartVtwm() +{ + XClientMessageEvent ev; + + delete_pidfile(); /* djhjr - 12/2/01 */ + + ev.type = ClientMessage; + ev.window = Scr->Root; + ev.message_type = _XA_TWM_RESTART; + ev.format = 32; + ev.data.b[0] = (char)0; + + XSendEvent (dpy, Scr->VirtualDesktopDisplay, False, 0L, (XEvent *) &ev); + XFlush(dpy); + SIGNAL_RETURN; +} + + +/* + * Error Handlers. If a client dies, we'll get a BadWindow error (except for + * GetGeometry which returns BadDrawable) for most operations that we do before + * manipulating the client's window. + */ + +Bool ErrorOccurred = False; +XErrorEvent LastErrorEvent; + +static int TwmErrorHandler(dpy, event) + Display *dpy; + XErrorEvent *event; +{ + LastErrorEvent = *event; + ErrorOccurred = True; + + if (PrintErrorMessages && /* don't be too obnoxious */ + event->error_code != BadWindow && /* watch for dead puppies */ + (event->request_code != X_GetGeometry && /* of all styles */ + event->error_code != BadDrawable)) + XmuPrintDefaultErrorMessage (dpy, event, stderr); + return 0; +} + + +/* ARGSUSED*/ +static int CatchRedirectError(dpy, event) + Display *dpy; + XErrorEvent *event; +{ + RedirectError = TRUE; + LastErrorEvent = *event; + ErrorOccurred = True; + return 0; +} + +Atom _XA_MIT_PRIORITY_COLORS; +Atom _XA_WM_CHANGE_STATE; +Atom _XA_WM_STATE; +Atom _XA_WM_COLORMAP_WINDOWS; +Atom _XA_WM_PROTOCOLS; +Atom _XA_WM_TAKE_FOCUS; +Atom _XA_WM_SAVE_YOURSELF; +Atom _XA_WM_DELETE_WINDOW; + +/* djhjr - 7/31/98 */ +Atom _XA_TWM_RESTART; + +void InternUsefulAtoms () +{ + /* + * Create priority colors if necessary. + */ + _XA_MIT_PRIORITY_COLORS = XInternAtom(dpy, "_MIT_PRIORITY_COLORS", False); + _XA_WM_CHANGE_STATE = XInternAtom (dpy, "WM_CHANGE_STATE", False); + _XA_WM_STATE = XInternAtom (dpy, "WM_STATE", False); + _XA_WM_COLORMAP_WINDOWS = XInternAtom (dpy, "WM_COLORMAP_WINDOWS", False); + _XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False); + _XA_WM_TAKE_FOCUS = XInternAtom (dpy, "WM_TAKE_FOCUS", False); + _XA_WM_SAVE_YOURSELF = XInternAtom (dpy, "WM_SAVE_YOURSELF", False); + _XA_WM_DELETE_WINDOW = XInternAtom (dpy, "WM_DELETE_WINDOW", False); + + /* djhjr - 7/31/98 */ + _XA_TWM_RESTART = XInternAtom (dpy, "_TWM_RESTART", False); +} diff --git a/twm.h b/twm.h new file mode 100644 index 0000000..4038cba --- /dev/null +++ b/twm.h @@ -0,0 +1,580 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/*********************************************************************** + * + * $XConsortium: twm.h,v 1.74 91/05/31 17:38:30 dave Exp $ + * + * twm include file + * + * 28-Oct-87 Thomas E. LaStrange File created + * 10-Oct-90 David M. Sternlicht Storeing saved colors on root + ***********************************************************************/ + +#ifndef _TWM_ +#define _TWM_ + +#include +#include +#include +#include +#ifdef NEVER /* stay X11R4 compatable; X11R5,6 doesn't seem to mind! */ +#include +#endif + +/* + * This accomodates systems that simply cannot handle the + * duplicate typedef declaration of 'Pixel'. On the other hand, + * if your make halts with complaints of an unknown datatype + * 'Pixel', add "EXTRA_DEFINES=-DNEED_PIXEL_T" to the make + * command. Submitted by Nelson H. F. Beebe + */ +#include +#ifdef NEED_PIXEL_T +typedef unsigned long Pixel; +#endif +#define PIXEL_ALREADY_TYPEDEFED /* for Xmu/Drawing.h */ + +#include "util.h" + +#ifndef WithdrawnState +#define WithdrawnState 0 +#endif + +#ifdef SIGNALRETURNSINT +#define SIGNAL_T int +#define SIGNAL_RETURN return 0 +#else +#define SIGNAL_T void +#define SIGNAL_RETURN return +#endif + +typedef SIGNAL_T (*SigProc)(); /* type of function returned by signal() */ + +#define BW 2 /* border width */ +#define BW2 4 /* border width * 2 */ + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#define NULLSTR ((char *) NULL) + +#define MAX_BUTTONS 5 /* max mouse buttons supported */ + +/* info stings defines */ +#define INFO_LINES 30 +#define INFO_SIZE 200 + +/* contexts for button presses */ +#define C_NO_CONTEXT -1 +#define C_WINDOW 0 +#define C_TITLE 1 +#define C_ICON 2 +#define C_ROOT 3 +#define C_FRAME 4 +#define C_ICONMGR 5 +#define C_NAME 6 +#define C_IDENTIFY 7 +#define C_VIRTUAL 8 +#define C_VIRTUAL_WIN 9 +#define C_DOOR 10 +#define NUM_CONTEXTS 11 + +#define C_WINDOW_BIT (1 << C_WINDOW) +#define C_TITLE_BIT (1 << C_TITLE) +#define C_ICON_BIT (1 << C_ICON) +#define C_ROOT_BIT (1 << C_ROOT) +#define C_FRAME_BIT (1 << C_FRAME) +#define C_ICONMGR_BIT (1 << C_ICONMGR) +#define C_NAME_BIT (1 << C_NAME) +#define C_VIRTUAL_BIT (1 << C_VIRTUAL) +#define C_VIRTUAL_WIN_BIT (1 << C_VIRTUAL_WIN) +#define C_DOOR_BIT (1 << C_DOOR) + +#define C_ALL_BITS (C_WINDOW_BIT | C_TITLE_BIT | C_ICON_BIT |\ + C_ROOT_BIT | C_FRAME_BIT | C_ICONMGR_BIT |\ + C_VIRTUAL_BIT | C_VIRTUAL_WIN_BIT | C_DOOR_BIT) + +/* modifiers for button presses */ +/* added "LockMask" - djhjr - 9/10/03 */ +#define MOD_SIZE ((ShiftMask | LockMask | ControlMask | Mod1Mask \ + | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask) + 1) + +/* definitions from MwmUtil.h - submitted by Jonathan Paisley - 11/8/02 */ +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_INPUT_MODE (1L << 2) +#define MWM_HINTS_STATUS (1L << 3) + +#define MWM_FUNC_ALL (1L << 0) +#define MWM_FUNC_RESIZE (1L << 1) +#define MWM_FUNC_MOVE (1L << 2) +#define MWM_FUNC_MINIMIZE (1L << 3) +#define MWM_FUNC_MAXIMIZE (1L << 4) +#define MWM_FUNC_CLOSE (1L << 5) + +#define MWM_DECOR_ALL (1L << 0) +#define MWM_DECOR_BORDER (1L << 1) +#define MWM_DECOR_RESIZEH (1L << 2) +#define MWM_DECOR_TITLE (1L << 3) +#define MWM_DECOR_MENU (1L << 4) +#define MWM_DECOR_MINIMIZE (1L << 5) +#define MWM_DECOR_MAXIMIZE (1L << 6) + +#define MWM_INPUT_MODELESS 0 +#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 +#define MWM_INPUT_SYSTEM_MODAL 2 +#define MWM_INPUT_FULL_APPLICATION_MODAL 3 +#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL + +#define MWM_TEAROFF_WINDOW (1L<<0) + +/* submitted by Jonathan Paisley - 11/8/02 */ +typedef struct +{ + long flags; + long functions; + long decorations; + long input_mode; + long state; +} MotifWmHints; + +#define TITLE_BAR_SPACE 1 /* 2 pixel space bordering chars */ +#define TITLE_BAR_FONT_HEIGHT 15 /* max of 15 pixel high chars */ +#define TITLE_BAR_HEIGHT (TITLE_BAR_FONT_HEIGHT+(2*TITLE_BAR_SPACE)) + +/* defines for zooming/unzooming */ +#define ZOOM_NONE 0 + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT +#define FBF(fix_fore, fix_back, fix_font)\ + MyFont_ChangeGC(fix_fore, fix_back, &fix_font) +#else +#define FBF(fix_fore, fix_back, fix_font)\ + Gcv.foreground = fix_fore;\ + Gcv.background = fix_back;\ + Gcv.font = fix_font.font->fid;\ + XChangeGC(dpy, Scr->NormalGC, GCFont|GCForeground|GCBackground,&Gcv) +#endif + +#define FB(fix_fore, fix_back)\ + Gcv.foreground = fix_fore;\ + Gcv.background = fix_back;\ + XChangeGC(dpy, Scr->NormalGC, GCForeground|GCBackground,&Gcv) + +typedef enum {on, off} ButtonState; + +typedef struct MyFont +{ + char *name; /* name of the font */ + XFontStruct *font; /* font structure */ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + XFontSet fontset; +#endif + int height; /* height of the font */ + int y; /* Y coordinate to draw characters */ + int ascent; + int descent; +} MyFont; + +typedef struct ColorPair +{ + Pixel fore, back; + + /* djhjr - 4/19/96 */ + Pixel shadc, shadd; +} ColorPair; + +typedef struct _TitleButton { + struct _TitleButton *next; /* next link in chain */ + char *name; /* bitmap name in case of deferal */ + +/* don't need either anymore - djhjr - 10/30/02 + * might not need 'bitmap anymore... djhjr - 4/19/96 * + Image *image; * image to display in button * + *Pixmap bitmap;* * image to display in button * +*/ + + int srcx, srcy; /* from where to start copying */ + unsigned int width, height; /* size of pixmap */ + int dstx, dsty; /* to where to start copying */ + int func; /* function to execute */ + char *action; /* optional action arg */ + struct MenuRoot *menuroot; /* menu to pop on F_MENU */ + Bool rightside; /* t: on right, f: on left */ +} TitleButton; + +typedef struct _TBWindow { + Window window; /* which window in this frame */ + +/* djhjr - 4/19/96 + Image *image; * image to display in button * +*/ + + TitleButton *info; /* description of this window */ +} TBWindow; + +typedef struct _SqueezeInfo { + int justify; /* left, center, right */ + int num; /* signed pixel count or numerator */ + int denom; /* 0 for pix count or denominator */ +} SqueezeInfo; + +#define J_LEFT 1 +#define J_CENTER 2 +#define J_RIGHT 3 + +/* Colormap window entry for each window in WM_COLORMAP_WINDOWS + * ICCCM property. + */ +typedef struct TwmColormap +{ + Colormap c; /* Colormap id */ + int state; /* install(ability) state */ + unsigned long install_req; /* request number which installed it */ + Window w; /* window causing load of color table */ + int refcnt; +} TwmColormap; + +#define CM_INSTALLABLE 1 +#define CM_INSTALLED 2 +#define CM_INSTALL 4 + +typedef struct ColormapWindow +{ + Window w; /* Window id */ + TwmColormap *colormap; /* Colormap for this window */ + int visibility; /* Visibility of this window */ + int refcnt; +} ColormapWindow; + +typedef struct Colormaps +{ + ColormapWindow **cwins; /* current list of colormap windows */ + int number_cwins; /* number of elements in current list */ + char *scoreboard; /* conflicts between installable colortables */ +} Colormaps; + +#define ColormapsScoreboardLength(cm) ((cm)->number_cwins * \ + ((cm)->number_cwins - 1) / 2) + +/* for each window that is on the display, one of these structures + * is allocated and linked into a list + */ +typedef struct TwmWindow +{ + struct TwmWindow *next; /* next twm window */ + struct TwmWindow *prev; /* previous twm window */ + Window w; /* the child window */ + Window VirtualDesktopDisplayWindow; /* the representation of this window in the vd display */ + int old_bw; /* border width before reparenting */ + Window frame; /* the frame window */ + Window title_w; /* the title bar window */ + Window hilite_w; /* the hilite window */ + Pixmap gray; + Window icon_w; /* the icon window */ + Window icon_bm_w; /* the icon bitmap window */ + int frame_x; /* x position of frame */ + int frame_y; /* y position of frame */ + int virtual_frame_x; /* virtual x position of frame */ + int virtual_frame_y; /* virtual y position of frame */ + int frame_width; /* width of frame */ + int frame_height; /* height of frame */ + int frame_bw; /* borderwidth of frame */ + + /* djhjr - 4/18/96 */ + int frame_bw3D; /* 3D borderwidth of frame */ + + int title_x; + int title_y; + int virtual_title_x; /* virtual x position of title */ + int virtual_title_y; /* virtual y position of title */ + int icon_x; /* icon text x coordinate */ + int icon_y; /* icon text y coordiante */ + int virtual_icon_x; /* virtual x position of icon */ + int virtual_icon_y; /* virtual y position of icon */ + int icon_w_width; /* width of the icon window */ + int icon_w_height; /* height of the icon window */ + int icon_width; /* width of the icon bitmap */ + int icon_height; /* height of the icon bitmap */ + int title_height; /* height of the title bar */ + int title_width; /* width of the title bar */ + char *full_name; /* full name of the window */ + char *name; /* name of the window */ + char *icon_name; /* name of the icon */ + int name_width; /* width of name text */ + int highlightx; /* start of highlight window */ + int rightx; /* start of right buttons */ + XWindowAttributes attr; /* the child window attributes */ + XSizeHints hints; /* normal hints */ + XWMHints *wmhints; /* WM hints */ + MotifWmHints mwmhints; /* MWM hints - by Jonathan Paisley - 11/8/02 */ + Window group; /* group ID */ + XClassHint class; + struct WList *list; + /*********************************************************************** + * color definitions per window + **********************************************************************/ + Pixel icon_border; /* border color */ + +/* djhjr - 4/19/96 + Pixel border; * border color * +*/ + ColorPair border; /* border color */ + + ColorPair border_tile; + ColorPair title; + ColorPair iconc; + ColorPair virtual; + + short mapped; /* is the window mapped ? */ + short zoomed; /* is the window zoomed? */ + short highlight; /* should highlight this window */ + short iconmgr; /* this is an icon manager window */ + short icon; /* is the window an icon now ? */ + +/* 5/17/96 - djhjr */ +#ifdef ORIGINAL_SHORTS + short iconified; /* has the window ever been iconified? */ + short icon_on; /* is the icon visible */ + short auto_raise; /* should we auto-raise this window ? */ + short forced; /* has had an icon forced upon it */ + short icon_not_ours; /* icon pixmap or window supplied to us */ + short icon_moved; /* user explicitly moved the icon */ + short stackmode; /* honor stackmode requests */ + short iconify_by_unmapping; /* unmap window to iconify it */ + short transient; /* this is a transient window */ + short titlehighlight; /* should I highlight the title bar */ + short wShaped; /* this window has a bounding shape */ + short nailed; /* is this window nailed ? */ + short showindesktopdisplay; /* should i show this in the desktop display ? */ + + /* djhjr - 4/6/98 */ + short opaque_move; + short opaque_resize; + +#else + struct + { + unsigned int iconified : 1; + unsigned int icon_on : 1; + unsigned int auto_raise : 1; + unsigned int forced : 1; + unsigned int icon_not_ours : 1; + unsigned int icon_moved : 1; + unsigned int stackmode : 1; + unsigned int iconify_by_unmapping : 1; + unsigned int transient : 1; + unsigned int titlehighlight : 1; + unsigned int wShaped : 1; + unsigned int nailed : 1; + unsigned int showindesktopdisplay : 1; + + /* djhjr - 4/6/98 */ + unsigned int opaque_move : 1; + unsigned int opaque_resize : 1; + + } twmflags; +#define iconified twmflags.iconified +#define icon_on twmflags.icon_on +#define auto_raise twmflags.auto_raise +#define forced twmflags.forced +#define icon_not_ours twmflags.icon_not_ours +#define icon_moved twmflags.icon_moved +#define stackmode twmflags.stackmode +#define iconify_by_unmapping twmflags.iconify_by_unmapping +#define transient twmflags.transient +#define titlehighlight twmflags.titlehighlight +#define wShaped twmflags.wShaped +#define nailed twmflags.nailed +#define showindesktopdisplay twmflags.showindesktopdisplay + +/* djhjr - 4/6/98 */ +#define opaque_move twmflags.opaque_move +#define opaque_resize twmflags.opaque_resize + +#endif + + Window transientfor; /* window contained in XA_XM_TRANSIENT_FOR */ + struct IconMgr *iconmgrp; /* pointer to it if this is an icon manager */ + int save_frame_x; /* x position of frame */ + int save_frame_y; /* y position of frame */ + int save_frame_width; /* width of frame */ + int save_frame_height; /* height of frame */ + unsigned long protocols; /* which protocols this window handles */ + Colormaps cmaps; /* colormaps for this application */ + TBWindow *titlebuttons; + SqueezeInfo *squeeze_info; /* should the title be squeezed? */ + struct { + struct TwmWindow *next, *prev; +#ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */ + Bool cursor_valid; + int curs_x, curs_y; +#endif + } ring; +} TwmWindow; + +#define DoesWmTakeFocus (1L << 0) +#define DoesWmSaveYourself (1L << 1) +#define DoesWmDeleteWindow (1L << 2) + +#define TBPM_DOT ":dot" /* name of titlebar pixmap for dot */ +#define TBPM_ICONIFY ":iconify" /* same image as dot */ +#define TBPM_RESIZE ":resize" /* name of titlebar pixmap for resize button */ +#define TBPM_XLOGO ":xlogo" /* name of titlebar pixmap for xlogo */ +#define TBPM_DELETE ":delete" /* same image as xlogo */ +#define TBPM_MENU ":menu" /* name of titlebar pixmap for menus */ +#define TBPM_QUESTION ":question" /* name of unknown titlebar pixmap */ + +/* djhjr - 6/4/00 */ +#define TBPM_RARROW ":rarrow" /* name of right arrow pixmap */ +#define TBPM_DARROW ":darrow" /* name of down arrow pixmap */ + +/* djhjr - 4/18/96 */ +#define TBPM_3DDOT ":xpm:dot" /* name of titlebar pixmap for dot */ +#define TBPM_3DRESIZE ":xpm:resize" /* name of titlebar pixmap for resize button */ +#define TBPM_3DMENU ":xpm:menu" /* name of titlebar pixmap for menus */ +#define TBPM_3DZOOM ":xpm:zoom" +#define TBPM_3DBAR ":xpm:bar" + +/* djhjr - 6/4/00 */ +#define TBPM_3DRARROW ":xpm:rarrow" /* name of right arrow pixmap */ +#define TBPM_3DDARROW ":xpm:darrow" /* name of down arrow pixmap */ + +/* djhjr - 10/25/02 */ +#define TBPM_3DRAISEDBOX ":xpm:raisedbox" /* name of raised box highlight pixmap */ +#define TBPM_3DSUNKENBOX ":xpm:sunkenbox" /* name of sunken box highlight pixmap */ +#define TBPM_3DRAISEDLINES ":xpm:raisedlines" /* name of raised lines highlight pixmap */ +#define TBPM_3DSUNKENLINES ":xpm:sunkenlines" /* name of sunken lines highlight pixmap */ + +/* djhjr - 10/30/02 */ +#define TBPM_3DBOX ":xpm:box" /* name of box pixmap */ +#define TBPM_3DLINES ":xpm:lines" /* name of lines pixmap */ + +#ifdef NEVER /* stay X11R4 compatable; X11R5,6 doesn't seem to mind! */ +#include +#endif +#ifndef X_NOT_STDC_ENV +#include +#else +extern char *malloc(), *calloc(), *realloc(), *getenv(); +extern void free(); +#endif +extern void Reborder(); + +/* djhjr - 6/22/01 */ +#ifndef NO_SOUND_SUPPORT +extern SIGNAL_T PlaySoundDone(); +void Done(); +#else +extern SIGNAL_T Done(); +#endif + +void ComputeCommonTitleOffsets(); +void ComputeWindowTitleOffsets(), ComputeTitleLocation(); + +extern char *ProgramName; +extern Display *dpy; +extern Window ResizeWindow; /* the window we are resizing */ +extern int HasShape; /* this server supports Shape extension */ + +extern int PreviousScreen; + +extern Cursor UpperLeftCursor; +extern Cursor RightButt; +extern Cursor MiddleButt; +extern Cursor LeftButt; + +extern XClassHint NoClass; + +extern XContext TwmContext; +extern XContext MenuContext; +extern XContext IconManagerContext; +extern XContext VirtualContext; +extern XContext ScreenContext; +extern XContext ColormapContext; +extern XContext DoorContext; + +extern char *Home; +extern int HomeLen; +extern int ParseError; + +extern int HandlingEvents; + +extern Window JunkRoot; +extern Window JunkChild; +extern int JunkX; +extern int JunkY; +extern unsigned int JunkWidth, JunkHeight, JunkBW, JunkDepth, JunkMask; +extern XGCValues Gcv; +extern int InfoLines; +extern char Info[][INFO_SIZE]; +extern int Argc; +extern char **Argv; +extern char **Environ; + +extern void NewFontCursor(); +extern Pixmap CreateMenuIcon(); +extern void RestoreWithdrawnLocation(); +extern void CreateFonts(); + +/* djhjr - 4/18/96 */ +extern Pixmap Create3DMenuIcon(); +extern Pixmap Create3DIconManagerIcon(); +extern void Draw3DBorder(); + +extern Bool ErrorOccurred; +extern XErrorEvent LastErrorEvent; + +#define ResetError() (ErrorOccurred = False) + +extern Bool RestartPreviousState; +extern Bool GetWMState(); + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT +extern Bool use_fontset; +#endif + +extern Atom _XA_MIT_PRIORITY_COLORS; +extern Atom _XA_WM_CHANGE_STATE; +extern Atom _XA_WM_STATE; +extern Atom _XA_WM_COLORMAP_WINDOWS; +extern Atom _XA_WM_PROTOCOLS; +extern Atom _XA_WM_TAKE_FOCUS; +extern Atom _XA_WM_SAVE_YOURSELF; +extern Atom _XA_WM_DELETE_WINDOW; + +/* djhjr - 7/31/98 */ +extern Atom _XA_TWM_RESTART; + +#endif /* _TWM_ */ diff --git a/util.c b/util.c new file mode 100644 index 0000000..41947df --- /dev/null +++ b/util.c @@ -0,0 +1,3419 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + +/* + +Portions Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + + +/*********************************************************************** + * + * $XConsortium: util.c,v 1.47 91/07/14 13:40:37 rws Exp $ + * + * utility routines for twm + * + * 28-Oct-87 Thomas E. LaStrange File created + * + ***********************************************************************/ + +#include "twm.h" +#include "util.h" +#include "gram.h" +#include "screen.h" +#include "list.h" +#include +#include +#include +#include +#ifndef NO_XPM_SUPPORT +#include +#endif + +#include +#include + +/* see Zoom() - djhjr - 10/11/01 */ +#ifdef NEED_SELECT_H +#include +#else +#include +#include +#endif +#ifndef ZOOMSLEEP +#define ZOOMSLEEP 50000 /* arbitrary, but pleasing, msec value */ +#endif + +#define strdup Strdup /* avoid conflict with system header files */ +extern char *strdup(char *); + +/* + * All instances of Scr->TitleBevelWidth and Scr->BorderBevelWidth + * were a hard value of 2 - djhjr - 4/29/98 + */ + +/* djhjr - 4/18/96 10/29/02 */ +static void Draw3DMenuImage(); +static void Draw3DDotImage(); +static void Draw3DResizeImage(); +static void Draw3DZoomImage(); +static void Draw3DBarImage(); + +/* djhjr - 6/4/00 10/29/02 */ +static void Draw3DRArrowImage(); +static void Draw3DDArrowImage(); + +/* djhjr - 1/13/98 10/20/02 */ +void setBorderGC(); +#ifdef USE_ORIGINAL_CORNERS +void Draw3DCorner(); +#else +GC setBevelGC(); +void Draw3DBevel(); +void Draw3DNoBevel(); +#endif + +/* djhjr - 4/19/96 */ +static GC rootGC = (GC) 0; + +/* for trying to clean up BeNiceToColormap - djhjr - 10/20/02 */ +static int borderdashoffset; + +int HotX, HotY; + +#define questionmark_width 8 +#define questionmark_height 8 +static unsigned char questionmark_bits[] = { + 0x38, 0x7c, 0x64, 0x30, 0x18, 0x00, 0x18, 0x18}; + +/*********************************************************************** + * + * Procedure: + * MoveOutline - move a window outline + * + * Inputs: + * root - the window we are outlining + * x - upper left x coordinate + * y - upper left y coordinate + * width - the width of the rectangle + * height - the height of the rectangle + * bw - the border width of the frame + * th - title height + * + *********************************************************************** + */ + +/* ARGSUSED */ +void MoveOutline(root, x, y, width, height, bw, th) + Window root; + int x, y, width, height, bw, th; +{ + static int lastx = 0; + static int lasty = 0; + static int lastWidth = 0; + static int lastHeight = 0; + static int lastBW = 0; + static int lastTH = 0; + int xl, xr, yt, yb, xinnerl, xinnerr, yinnert, yinnerb; + int xthird, ythird; + XSegment outline[18]; + register XSegment *r; + + if (x == lastx && y == lasty && width == lastWidth && height == lastHeight + && lastBW == bw && th == lastTH) + return; + + r = outline; + +#ifdef ORIGINAL_DRAWIT +#define DRAWIT() \ + if (lastWidth || lastHeight) \ + { \ + xl = lastx; \ + xr = lastx + lastWidth - 1; \ + yt = lasty; \ + yb = lasty + lastHeight - 1; \ + xinnerl = xl + lastBW; \ + xinnerr = xr - lastBW; \ + yinnert = yt + lastTH + lastBW; \ + yinnerb = yb - lastBW; \ + xthird = (xinnerr - xinnerl) / 3; \ + ythird = (yinnerb - yinnert) / 3; \ + \ + /* frame outline */ \ + r->x1 = xl; \ + r->y1 = yt; \ + r->x2 = xr; \ + r->y2 = yt; \ + r++; \ + \ + r->x1 = xl; \ + r->y1 = yb; \ + r->x2 = xr; \ + r->y2 = yb; \ + r++; \ + \ + r->x1 = xl; \ + r->y1 = yt; \ + r->x2 = xl; \ + r->y2 = yb; \ + r++; \ + \ + r->x1 = xr; \ + r->y1 = yt; \ + r->x2 = xr; \ + r->y2 = yb; \ + r++; \ + \ + /* left vertical */ \ + r->x1 = xinnerl + xthird; \ + r->y1 = yinnert; \ + r->x2 = r->x1; \ + r->y2 = yinnerb; \ + r++; \ + \ + /* right vertical */ \ + r->x1 = xinnerl + (2 * xthird); \ + r->y1 = yinnert; \ + r->x2 = r->x1; \ + r->y2 = yinnerb; \ + r++; \ + \ + /* top horizontal */ \ + r->x1 = xinnerl; \ + r->y1 = yinnert + ythird; \ + r->x2 = xinnerr; \ + r->y2 = r->y1; \ + r++; \ + \ + /* bottom horizontal */ \ + r->x1 = xinnerl; \ + r->y1 = yinnert + (2 * ythird); \ + r->x2 = xinnerr; \ + r->y2 = r->y1; \ + r++; \ + \ + /* title bar */ \ + if (lastTH != 0) { \ + r->x1 = xl; \ + r->y1 = yt + lastTH; \ + r->x2 = xr; \ + r->y2 = r->y1; \ + r++; \ + } \ + } + + /* undraw the old one, if any */ + DRAWIT (); + + lastx = x; + lasty = y; + lastWidth = width; + lastHeight = height; + lastBW = bw; + lastTH = th; + + /* draw the new one, if any */ + DRAWIT (); +#else +#define DRAWIT() \ + if (lastWidth || lastHeight) \ + { \ + xl = lastx; \ + xr = lastx + lastWidth - 1; \ + yt = lasty; \ + yb = lasty + lastHeight - 1; \ + xinnerl = xl + lastBW; \ + xinnerr = xr - lastBW; \ + yinnert = yt + lastTH + lastBW; \ + yinnerb = yb - lastBW; \ + xthird = (xinnerr - xinnerl) / 3; \ + ythird = (yinnerb - yinnert) / 3; \ + \ + /* frame outline */ \ + r->x1 = xl; \ + r->y1 = yt; \ + r->x2 = xr; \ + r->y2 = yt; \ + r++; \ + \ + r->x1 = xl; \ + r->y1 = yb; \ + r->x2 = xr; \ + r->y2 = yb; \ + r++; \ + \ + r->x1 = xl; \ + r->y1 = yt; \ + r->x2 = xl; \ + r->y2 = yb; \ + r++; \ + \ + r->x1 = xr; \ + r->y1 = yt; \ + r->x2 = xr; \ + r->y2 = yb; \ + r++; \ + \ + /* top-left to bottom-right */ \ + r->x1 = xinnerl; \ + r->y1 = yinnert; \ + r->x2 = xinnerr; \ + r->y2 = yinnerb; \ + r++; \ + \ + /* bottom-left to top-right */ \ + r->x1 = xinnerl; \ + r->y1 = yinnerb; \ + r->x2 = xinnerr; \ + r->y2 = yinnert; \ + r++; \ + \ + /* title bar */ \ + if (lastTH != 0) { \ + r->x1 = xl; \ + r->y1 = yt + lastTH; \ + r->x2 = xr; \ + r->y2 = r->y1; \ + r++; \ + } \ + } + + /* undraw the old one, if any */ + DRAWIT (); + + lastx = x; + lasty = y; + lastWidth = width; + lastHeight = height; + lastBW = bw; + lastTH = th; + + /* draw the new one, if any */ + DRAWIT (); +#endif + +#undef DRAWIT + + if (r != outline) + { + XDrawSegments(dpy, root, Scr->DrawGC, outline, r - outline); + } +} + +/*********************************************************************** + * + * Procedure: + * Zoom - zoom in or out of an icon + * + * Inputs: + * wf - window to zoom from + * ipf - icon manager of window to zoom from + * wt - window to zoom to + * ipt - icon manager of window to zoom to + * + * Patched to make sure a "None" window generates coordinates *INSIDE* + * the screen. -- DSE + * + * Added args to icon managers so zooms from and to the window's + * entry use that icon manager's coordinates - djhjr - 10/11/01 + * + *********************************************************************** + */ + +void +Zoom(wf, ipf, wt, ipt) + Window wf, wt; + IconMgr *ipf, *ipt; +{ + int fx, fy, tx, ty; /* from, to */ + unsigned int fw, fh, tw, th; /* from, to */ + long dx, dy, dw, dh; + long z; + int j; + + /* djhjr - 10/11/01 */ + static struct timeval timeoutval = {0, ZOOMSLEEP}; + struct timeval timeout; + + void draw_rect(); /* DSE */ + + if (!Scr->DoZoom || Scr->ZoomCount < 1) return; + +#if (0) + if (wf == None || wt == None) return; + + XGetGeometry (dpy, wf, &JunkRoot, &fx, &fy, &fw, &fh, &JunkBW, &JunkDepth); + XGetGeometry (dpy, wt, &JunkRoot, &tx, &ty, &tw, &th, &JunkBW, &JunkDepth); +#else + + /* if (wf == None && wt == None) return; */ + + if ( wt == None) + { + if (Scr->LessRandomZoomZoom) /* DSE */ + { + int temp,x1,y1,x2,y2; + x1 = ( (int)rand() % (Scr->MyDisplayWidth >> 3) ); + x2 = Scr->MyDisplayWidth - + ( (int)rand() % (Scr->MyDisplayWidth >> 3) ); + y1 = ( (int)rand() % (Scr->MyDisplayHeight >> 3) ); + y2 = Scr->MyDisplayHeight - + ( (int)rand() % (Scr->MyDisplayHeight >> 3) ); + if(x1>x2){temp=x1;x1=x2;x2=temp;} + if(y1>y2){temp=y1;y1=y2;y2=temp;} + tx = x1; ty = y1; + tw = x2 - x1; th = y2 - y1; + } + else + { + /* Zoom from nowhere, RFBZOOM */ + tx = ( (int)rand() % Scr->MyDisplayWidth ); + tw = ( (int)rand() % Scr->MyDisplayWidth ); + ty = ( (int)rand() % Scr->MyDisplayWidth ); + th = ( (int)rand() % Scr->MyDisplayWidth ); + } + } + else + { /* Normal. */ + XGetGeometry (dpy, wt, &JunkRoot, + &tx, &ty, &tw, &th, &JunkBW, &JunkDepth); + + if (ipt) + { + tx += (ipt->twm_win->frame_x + ipt->twm_win->title_x); + ty += (ipt->twm_win->frame_y + ipt->twm_win->title_y + + ipt->twm_win->title_height); + } + } + + if ( wf == None ) + { + if (Scr->LessRandomZoomZoom) /* DSE */ + { + /* zoom from somewhere on the screen, DSE */ + int temp,x1,y1,x2,y2; + do + { + x1 = ( (int)rand() % Scr->MyDisplayWidth ); + x2 = ( (int)rand() % Scr->MyDisplayWidth ); + y1 = ( (int)rand() % Scr->MyDisplayHeight ); + y2 = ( (int)rand() % Scr->MyDisplayHeight ); + if(x1>x2){temp=x1;x1=x2;x2=temp;} + if(y1>y2){temp=y1;y1=y2;y2=temp;} + fx = x1; fy = y1; + fw = x2 - x1; fh = y2 - y1; + } + while ( fw > (Scr->MyDisplayWidth >> 2) || fh > (Scr->MyDisplayHeight >> 2) ); + } + else + { + /* Zoom from nowhere, RFB */ + /* fx = ( rand() & 1 ) * Scr->MyDisplayWidth; */ + fx = ( (int)rand() % Scr->MyDisplayWidth ); + fw = ( (int)rand() % Scr->MyDisplayWidth ); + fy = ( (int)rand() % Scr->MyDisplayWidth ); + fh = ( (int)rand() % Scr->MyDisplayWidth ); + } + } + + else + { /* Normal. */ + XGetGeometry (dpy, wf, &JunkRoot, + &fx, &fy, &fw, &fh, &JunkBW, &JunkDepth); + + if (ipf) + { + fx += (ipf->twm_win->frame_x + ipf->twm_win->title_x); + fy += (ipf->twm_win->frame_y + ipf->twm_win->title_y + + ipf->twm_win->title_height); + } + } +#endif + + dx = ((long) (tx - fx)); /* going from -> to */ + dy = ((long) (ty - fy)); /* going from -> to */ + dw = ((long) (tw - fw)); /* going from -> to */ + dh = ((long) (th - fh)); /* going from -> to */ + z = (long) (Scr->ZoomCount + 1); + + for (j = 0; j < 2; j++) { + long i; + + draw_rect (dpy, Scr->Root, Scr->DrawGC, fx, fy, fw, fh); /* DSE */ + for (i = 1; i < z; i++) + { + int x = fx + (int) ((dx * i) / z); + int y = fy + (int) ((dy * i) / z); + unsigned width = (unsigned) (((long) fw) + (dw * i) / z); + unsigned height = (unsigned) (((long) fh) + (dh * i) / z); + + draw_rect (dpy, Scr->Root, Scr->DrawGC, x, y, width, height); /* DSE */ + } + draw_rect (dpy, Scr->Root, Scr->DrawGC, tx, ty, tw, th); /* DSE */ + + /* djhjr - 10/11/01 */ + timeout = timeoutval; + select(0, 0, 0, 0, &timeout); + } +} + + +/* + * Use any routine to draw your own rectangles here. -- DSE + */ +void draw_rect (display,drawable,gc,x,y,width,height) /* DSE */ + Display *display; + Drawable drawable; + GC gc; + int x,y; + unsigned int width,height; + { + void draw_scaled_rect(); + draw_scaled_rect (display,drawable,gc,x,y,width,height, 20,20); + if (Scr->PrettyZoom) + { + draw_scaled_rect (display,drawable,gc,x,y,width,height, 18,20); + draw_scaled_rect (display,drawable,gc,x,y,width,height, 16,20); + } + } +void draw_scaled_rect (display,drawable,gc,x,y, + width,height,scale,over) /* DSE */ + Display *display; + Drawable drawable; + GC gc; + int x,y; + unsigned int width,height; + unsigned int scale,over; + { + XDrawRectangle(dpy,drawable,gc, + x + ( over + width * (over - scale) ) / (2 * over), + y + ( over + width * (over - scale) ) / (2 * over), + ( (over / 2) + width * scale ) / over, + ( (over / 2) + height * scale ) / over + ); + } + +/*********************************************************************** + * + * Procedure: + * ExpandFilename - expand the tilde character to HOME + * if it is the first character of the filename + * + * Returned Value: + * a pointer to the new name + * + * Inputs: + * name - the filename to expand + * + *********************************************************************** + */ + +char * +ExpandFilename(name) +char *name; +{ + char *newname; + + if (name[0] != '~') return name; + + newname = (char *) malloc (HomeLen + strlen(name) + 2); + if (!newname) { + fprintf (stderr, + "%s: unable to allocate %d bytes to expand filename %s/%s\n", + ProgramName, HomeLen + strlen(name) + 2, Home, &name[1]); + } else { + (void) sprintf (newname, "%s/%s", Home, &name[1]); + } + + return newname; +} + +/*********************************************************************** + * + * Procedure: + * GetUnknownIcon - read in the bitmap file for the unknown icon + * + * Inputs: + * name - the filename to read + * + *********************************************************************** + */ + +void +GetUnknownIcon(name) +char *name; +{ +/* djhjr - 8/13/98 */ +#ifdef ORIGINAL_PIXMAPS + if ((Scr->UnknownPm = GetBitmap(name)) != None) + { + XGetGeometry(dpy, Scr->UnknownPm, &JunkRoot, &JunkX, &JunkY, + (unsigned int *)&Scr->UnknownWidth, (unsigned int *)&Scr->UnknownHeight, &JunkBW, &JunkDepth); + } +#else + Scr->unknownName = name; +#endif +} + +/*********************************************************************** + * + * Procedure: + * FindBitmap - read in a bitmap file and return size + * + * Returned Value: + * the pixmap associated with the bitmap + * widthp - pointer to width of bitmap + * heightp - pointer to height of bitmap + * + * Inputs: + * name - the filename to read + * + *********************************************************************** + */ + +Pixmap FindBitmap (name, widthp, heightp) + char *name; + unsigned int *widthp, *heightp; +{ + char *bigname; + Pixmap pm; + + if (!name) return None; + + /* + * Generate a full pathname if any special prefix characters (such as ~) + * are used. If the bigname is different from name, bigname will need to + * be freed. + */ + bigname = ExpandFilename (name); + if (!bigname) return None; + + /* + * look along bitmapFilePath resource same as toolkit clients + */ + pm = XmuLocateBitmapFile (ScreenOfDisplay(dpy, Scr->screen), bigname, NULL, + 0, (int *)widthp, (int *)heightp, &HotX, &HotY); + if (pm == None && Scr->IconDirectory && bigname[0] != '/') { + if (bigname != name) free (bigname); + /* + * Attempt to find icon in old IconDirectory (now obsolete) + */ + bigname = (char *) malloc (strlen(name) + strlen(Scr->IconDirectory) + + 2); + if (!bigname) { + fprintf (stderr, + "%s: unable to allocate memory for \"%s/%s\"\n", + ProgramName, Scr->IconDirectory, name); + return None; + } + (void) sprintf (bigname, "%s/%s", Scr->IconDirectory, name); + if (XReadBitmapFile (dpy, Scr->Root, bigname, widthp, heightp, &pm, + &HotX, &HotY) != BitmapSuccess) { + pm = None; + } + } + if (bigname != name) free (bigname); + +#ifdef DEBUG + if (pm == None) { + fprintf (stderr, "%s: unable to find bitmap \"%s\"\n", + ProgramName, name); + } +#endif + + return pm; +} + +Pixmap GetBitmap (name) + char *name; +{ + return FindBitmap (name, &JunkWidth, &JunkHeight); +} + +#ifndef NO_XPM_SUPPORT +/* + * Submitted by Jason Gloudon + * added color argument - djhjr - 9/28/99 + */ +Image *FindImage (name, color) + char *name; + Pixel color; +{ + char *bigname; + Pixmap pixmap,mask; + Image *newimage = None; /* added intialization - djhjr - 3/21/98 */ + XpmAttributes attributes; + XpmColorSymbol xpmcolor[1]; /* djhjr - 9/28/99 */ + int ErrorStatus; + + /* + * Generate a full pathname if any special prefix characters (such as ~) + * are used. If the bigname is different from name, bigname will need to + * be freed. + */ + bigname = ExpandFilename (name); + if (!bigname) return None; + + /* was 'XpmReturnAllocPixels' - Submitted by Takeharu Kato */ + attributes.valuemask = XpmReturnPixels; + + /* djhjr - 5/10/99 */ + attributes.valuemask |= XpmCloseness; + attributes.closeness = 32768; + + /* djhjr - 9/28/99 */ + if (color) + { + xpmcolor[0].name = NULL; + xpmcolor[0].value = "none"; + xpmcolor[0].pixel = color; + + attributes.colorsymbols = xpmcolor; + attributes.numsymbols = 1; + attributes.valuemask |= XpmColorSymbols; + } + + /* + * By default, the XPM library assumes screen 0, so we have + * to pass in the real values. Submitted by Caveh Frank Jalali + */ + attributes.valuemask |= XpmVisual | XpmColormap | XpmDepth; + attributes.visual = Scr->d_visual; + attributes.colormap = XDefaultColormap(dpy, Scr->screen); + attributes.depth = Scr->d_depth; + + if( (ErrorStatus = XpmReadFileToPixmap(dpy, Scr->Root, bigname, &pixmap, + &mask, &attributes)) != XpmSuccess){ + pixmap = None; + } + + /* + * Do for pixmaps what XmuLocateBitmapFile() does for bitmaps, + * because, apparently, XmuLocatePixmapFile() doesn't! + * + * djhjr - 12/26/98 + */ + if (pixmap == None && Scr->BitmapFilePath && bigname[0] != '/') + { + char *path = Scr->BitmapFilePath, *term; + + do + { + if ((term = strchr(path, ':'))) *term = 0; + + if (bigname != name) free(bigname); + if (!(bigname = (char *)malloc(strlen(name) + strlen(path) + 2))) + fprintf(stderr, "%s: unable to allocate memory for \"%s/%s\"\n", + ProgramName, path, name); + else + { + (void)sprintf(bigname, "%s/%s", path, name); + +#ifdef NEVER /* once, at the top, is enough? - djhjr - 12/26/98 */ + /* was 'XpmReturnAllocPixels' - Submitted by Takeharu Kato */ + attributes.valuemask = XpmReturnPixels; + + /* djhjr - 5/10/99 */ + attributes.valuemask |= XpmCloseness; + attributes.closeness = 32768; + + /* djhjr - 9/28/99 */ + if (color) + { + xpmcolor[0].name = NULL; + xpmcolor[0].value = "none"; + xpmcolor[0].pixel = color; + + attributes.colorsymbols = xpmcolor; + attributes.numsymbols = 1; + attributes.valuemask |= XpmColorSymbols; + } + + /* + * By default, the XPM library assumes screen 0, so we have + * to pass in the real values. Submitted by Caveh Frank Jalali + */ + attributes.valuemask |= XpmVisual | XpmColormap | XpmDepth; + attributes.visual = Scr->d_visual; + attributes.colormap = XDefaultColormap(dpy, Scr->screen); + attributes.depth = Scr->d_depth; +#endif /* NEVER */ + + ErrorStatus = XpmReadFileToPixmap(dpy, Scr->Root, bigname, + &pixmap, &mask, &attributes); + } + + if (term) + { + *term = ':'; + path = term + 1; + } + else + path = NULL; + + if (ErrorStatus != XpmSuccess) + pixmap = None; + else + break; + + } while (path); + } + + if (pixmap == None && Scr->IconDirectory && bigname[0] != '/') { + if (bigname != name) free (bigname); + /* + * Attempt to find icon pixmap in old IconDirectory (now obsolete) + */ + bigname = (char *) malloc (strlen(name) + strlen(Scr->IconDirectory) + 2); + if (!bigname) { + fprintf (stderr, + "%s: unable to allocate memory for \"%s/%s\"\n", + ProgramName, Scr->IconDirectory, name); + return None; + } + (void) sprintf (bigname, "%s/%s", Scr->IconDirectory, name); + +#ifdef NEVER /* once, at the top, is enough? - djhjr - 12/26/98 */ + /* was 'XpmReturnAllocPixels' - Submitted by Takeharu Kato */ + attributes.valuemask = XpmReturnPixels; + + /* djhjr - 5/10/99 */ + attributes.valuemask |= XpmCloseness; + attributes.closeness = 32768; + + /* + * By default, the XPM library assumes screen 0, so we have + * to pass in the real values. Submitted by Caveh Frank Jalali + */ + attributes.valuemask |= XpmVisual | XpmColormap | XpmDepth; + attributes.visual = Scr->d_visual; + attributes.colormap = XDefaultColormap(dpy, Scr->screen); + attributes.depth = Scr->d_depth; +#endif /* NEVER */ + + ErrorStatus = XpmReadFileToPixmap(dpy, Scr->Root, bigname, &pixmap, + &mask, &attributes); + } + + if(ErrorStatus == XpmSuccess){ + newimage = (Image *)malloc(sizeof(Image)); + newimage->pixmap = pixmap; + newimage->mask = mask; + newimage->height = attributes.height; + newimage->width = attributes.width; + } + else { + fprintf (stderr, "%s: unable to find pixmap \"%s\"\n", + ProgramName, name); + } + + if (bigname != name) free (bigname); + return newimage; +} +#endif /* NO_XPM_SUPPORT */ + +void InsertRGBColormap (a, maps, nmaps, replace) + Atom a; + XStandardColormap *maps; + int nmaps; + Bool replace; +{ + StdCmap *sc = NULL; + + if (replace) { /* locate existing entry */ + for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) { + if (sc->atom == a) break; + } + } + + if (!sc) { /* no existing, allocate new */ + sc = (StdCmap *) malloc (sizeof (StdCmap)); + if (!sc) { + fprintf (stderr, "%s: unable to allocate %d bytes for StdCmap\n", + ProgramName, sizeof (StdCmap)); + return; + } + } + + if (replace) { /* just update contents */ + if (sc->maps) XFree ((char *) maps); + if (sc == Scr->StdCmapInfo.mru) Scr->StdCmapInfo.mru = NULL; + } else { /* else appending */ + sc->next = NULL; + sc->atom = a; + if (Scr->StdCmapInfo.tail) { + Scr->StdCmapInfo.tail->next = sc; + } else { + Scr->StdCmapInfo.head = sc; + } + Scr->StdCmapInfo.tail = sc; + } + sc->nmaps = nmaps; + sc->maps = maps; + + return; +} + +/* + * SetPixmapsPixmap - load the Image structure for the Pixmaps resource images + * + * djhjr - 5/17/98 + */ +Image *SetPixmapsPixmap(filename) +char *filename; +{ + Pixmap bm; + Image *image = NULL; + + bm = FindBitmap(filename, &JunkWidth, &JunkHeight); + if (bm != None) + { + image = (Image *)malloc(sizeof(Image)); + + image->width = JunkWidth; + image->height = JunkHeight; + image->mask = None; + + image->pixmap = bm; + } +#ifndef NO_XPM_SUPPORT + else /* Try to find a pixmap file with this name */ + + /* added color argument - djhjr - 9/28/99 */ + image = FindImage(filename, 0); +#endif + + return image; +} + +/* + * SetPixmapsBackground - set the background for the Pixmaps resource images + * + * djhjr - 5/23/98 + * used to receive (int *)numcolors and return (Image *)image - djhjr - 9/2/98 + */ +#ifndef NO_XPM_SUPPORT +int SetPixmapsBackground(image, drawable, color) +Image *image; +Drawable drawable; +Pixel color; +{ + XpmImage xpmimage; + XpmAttributes xpmattr; + XpmColorSymbol xpmcolor[1]; + unsigned int i; + + /* djhjr - 5/10/99 */ + xpmattr.valuemask = XpmCloseness; + xpmattr.closeness = 32768; + + /* + * By default, the XPM library assumes screen 0, so we have + * to pass in the real values. Submitted by Caveh Frank Jalali + */ + xpmattr.valuemask |= XpmVisual | XpmColormap | XpmDepth; + xpmattr.visual = Scr->d_visual; + xpmattr.colormap = XDefaultColormap(dpy, Scr->screen); + xpmattr.depth = Scr->d_depth; + + if (XpmCreateXpmImageFromPixmap(dpy, image->pixmap, image->mask, + &xpmimage, &xpmattr) != XpmSuccess) + return (0); + + for (i = 0; i < xpmimage.ncolors; i++) + if (!strcmp(xpmimage.colorTable[i].c_color, "None")) + break; + + if (i < xpmimage.ncolors) + { + /* djhjr - 9/2/98 */ + XFreePixmap(dpy, image->pixmap); + XFreePixmap(dpy, image->mask); + + xpmcolor[0].name = NULL; + xpmcolor[0].value = "none"; + xpmcolor[0].pixel = color; + +#ifdef NEVER /* once, at the top, is enough? - djhjr - 2/13/99 */ + xpmattr.colorsymbols = xpmcolor; + xpmattr.numsymbols = 1; + xpmattr.valuemask = XpmColorSymbols; + + /* djhjr - 5/10/99 */ + xpmattr.valuemask |= XpmCloseness; + xpmattr.closeness = 32768; + + /* + * By default, the XPM library assumes screen 0, so we have + * to pass in the real values. Submitted by Caveh Frank Jalali + */ + xpmattr.valuemask |= XpmVisual | XpmColormap | XpmDepth; + xpmattr.visual = Scr->d_visual; + xpmattr.colormap = XDefaultColormap(dpy, Scr->screen); + xpmattr.depth = Scr->d_depth; +#else + xpmattr.colorsymbols = xpmcolor; + xpmattr.numsymbols = 1; + xpmattr.valuemask |= XpmColorSymbols; +#endif /* NEVER */ + + XpmCreatePixmapFromXpmImage(dpy, drawable, &xpmimage, + &image->pixmap, &image->mask, &xpmattr); + } + + i = xpmimage.ncolors; + XpmFreeXpmImage(&xpmimage); + + return (i); +} +#endif /* NO_XPM_SUPPORT */ + +void RemoveRGBColormap (a) + Atom a; +{ + StdCmap *sc, *prev; + + prev = NULL; + for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) { + if (sc->atom == a) break; + prev = sc; + } + if (sc) { /* found one */ + if (sc->maps) XFree ((char *) sc->maps); + if (prev) prev->next = sc->next; + if (Scr->StdCmapInfo.head == sc) Scr->StdCmapInfo.head = sc->next; + if (Scr->StdCmapInfo.tail == sc) Scr->StdCmapInfo.tail = prev; + if (Scr->StdCmapInfo.mru == sc) Scr->StdCmapInfo.mru = NULL; + } + return; +} + +void LocateStandardColormaps() +{ + Atom *atoms; + int natoms; + int i; + + atoms = XListProperties (dpy, Scr->Root, &natoms); + for (i = 0; i < natoms; i++) { + XStandardColormap *maps = NULL; + int nmaps; + + if (XGetRGBColormaps (dpy, Scr->Root, &maps, &nmaps, atoms[i])) { + /* if got one, then append to current list */ + InsertRGBColormap (atoms[i], maps, nmaps, False); + } + } + if (atoms) XFree ((char *) atoms); + return; +} + +void GetColor(kind, what, name) +int kind; +Pixel *what; +char *name; +{ + XColor color, junkcolor; + Status stat = 0; + Colormap cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c; + +#ifndef TOM + if (!Scr->FirstTime) return; +#endif + + if (Scr->Monochrome != kind) return; + +#if ( XlibSpecificationRelease < 5 ) + /* eyckmans@imec.be */ + if ( ! ( ( name[0] == '#') + ? ( (stat = XParseColor (dpy, cmap, name, &color)) + && XAllocColor (dpy, cmap, &color)) + : XAllocNamedColor (dpy, cmap, name, &color, &junkcolor))) +#else + if (!XAllocNamedColor (dpy, cmap, name, &color, &junkcolor)) +#endif + { + /* if we could not allocate the color, let's see if this is a + * standard colormap + */ + XStandardColormap *stdcmap = NULL; + + /* parse the named color */ + if (name[0] != '#') + stat = XParseColor (dpy, cmap, name, &color); + if (!stat) + { + fprintf (stderr, "%s: invalid color name \"%s\"\n", + ProgramName, name); + return; + } + + /* + * look through the list of standard colormaps (check cache first) + */ + if (Scr->StdCmapInfo.mru && Scr->StdCmapInfo.mru->maps && + (Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex].colormap == + cmap)) { + stdcmap = &(Scr->StdCmapInfo.mru->maps[Scr->StdCmapInfo.mruindex]); + } else { + StdCmap *sc; + + for (sc = Scr->StdCmapInfo.head; sc; sc = sc->next) { + int i; + + for (i = 0; i < sc->nmaps; i++) { + if (sc->maps[i].colormap == cmap) { + Scr->StdCmapInfo.mru = sc; + Scr->StdCmapInfo.mruindex = i; + stdcmap = &(sc->maps[i]); + goto gotit; + } + } + } + } + + gotit: + if (stdcmap) { + color.pixel = (stdcmap->base_pixel + + ((Pixel)(((float)color.red / 65535.0) * + stdcmap->red_max + 0.5) * + stdcmap->red_mult) + + ((Pixel)(((float)color.green /65535.0) * + stdcmap->green_max + 0.5) * + stdcmap->green_mult) + + ((Pixel)(((float)color.blue / 65535.0) * + stdcmap->blue_max + 0.5) * + stdcmap->blue_mult)); + } else { + fprintf (stderr, "%s: unable to allocate color \"%s\"\n", + ProgramName, name); + return; + } + } + + *what = color.pixel; +} + +void GetShadeColors (cp) +ColorPair *cp; +{ + XColor xcol; + Colormap cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c; + int save; + float clearfactor; + float darkfactor; + char clearcol [32], darkcol [32]; + + clearfactor = (float) Scr->ClearBevelContrast / 100.0; + darkfactor = (100.0 - (float) Scr->DarkBevelContrast) / 100.0; + xcol.pixel = cp->back; + XQueryColor (dpy, cmap, &xcol); + + sprintf (clearcol, "#%04x%04x%04x", + xcol.red + (unsigned short) ((65535 - xcol.red) * clearfactor), + xcol.green + (unsigned short) ((65535 - xcol.green) * clearfactor), + xcol.blue + (unsigned short) ((65535 - xcol.blue) * clearfactor)); + sprintf (darkcol, "#%04x%04x%04x", + (unsigned short) (xcol.red * darkfactor), + (unsigned short) (xcol.green * darkfactor), + (unsigned short) (xcol.blue * darkfactor)); + + save = Scr->FirstTime; + Scr->FirstTime = True; + GetColor (Scr->Monochrome, &cp->shadc, clearcol); + GetColor (Scr->Monochrome, &cp->shadd, darkcol); + Scr->FirstTime = save; +} + +/* + * The following I18N-oriented functions are adapted from TWM + * as distributed with XFree86 4.2.0 - djhjr - 9/14/03 + */ + +/* + * The following functions are sensible to 'use_fontset'. + * When 'use_fontset' is True, + * - XFontSet-related internationalized functions are used + * so as multibyte languages can be displayed. + * When 'use_fontset' is False, + * - XFontStruct-related conventional functions are used + * so as 8-bit characters can be displayed even when + * locale is not set properly. + */ +void +GetFont(font) +MyFont *font; +{ +#ifndef NO_I18N_SUPPORT + char **missing_charset_list_return; + int missing_charset_count_return; + char *def_string_return; + XFontSetExtents *font_extents; + XFontStruct **xfonts; + char **font_names; + register int i; + int ascent; + int descent; + int fnum; + char *basename2, *basename3 = NULL; + + if (use_fontset) + { + if (font->fontset != NULL) + XFreeFontSet(dpy, font->fontset); + + if (!font->name) + font->name = Scr->DefaultFont.name; + if ((basename2 = (char *)malloc(strlen(font->name) + 3))) + sprintf(basename2, "%s,*", font->name); + else + basename2 = font->name; + if ((font->fontset = XCreateFontSet(dpy, basename2, + &missing_charset_list_return, + &missing_charset_count_return, + &def_string_return)) == NULL) + { + /* idea from Seth Robertson - djhjr - 9/17/03 */ + + if ((basename3 = (char *)realloc(basename2, + strlen(Scr->DefaultFont.name) + 3))) + sprintf(basename3, "%s,*", Scr->DefaultFont.name); + else + { + basename3 = Scr->DefaultFont.name; + if (basename2 != font->name) + free(basename2); + } + if ((font->fontset = XCreateFontSet(dpy, basename3, + &missing_charset_list_return, + &missing_charset_count_return, + &def_string_return)) == NULL) + { + fprintf(stderr, + "%s: unable to open fontsets \"%s\" or \"%s\"\n", + ProgramName, font->name, Scr->DefaultFont.name); + if (basename3 != Scr->DefaultFont.name) + free(basename3); + exit(1); + } + basename2 = basename3; + } + + if (basename2 != ((basename3) ? Scr->DefaultFont.name : font->name)) + free(basename2); + + for (i = 0; i < missing_charset_count_return; i++) + fprintf(stderr, "%s: font for charset %s is lacking\n", + ProgramName, missing_charset_list_return[i]); + + font_extents = XExtentsOfFontSet(font->fontset); + fnum = XFontsOfFontSet(font->fontset, &xfonts, &font_names); + for (i = 0, ascent = 0, descent = 0; iascent) + ascent = (*xfonts)->ascent; + if (descent < (*xfonts)->descent) + descent = (*xfonts)->descent; + xfonts++; + } + + font->height = font_extents->max_logical_extent.height; + font->y = ascent; + font->ascent = ascent; + font->descent = descent; + return; + } +#endif + + if (font->font != NULL) + XFreeFont(dpy, font->font); + + if ((font->font = XLoadQueryFont(dpy, font->name)) == NULL) + if ((font->font = XLoadQueryFont(dpy, Scr->DefaultFont.name)) == NULL) + { + fprintf(stderr, "%s: unable to open fonts \"%s\" or \"%s\"\n", + ProgramName, font->name, Scr->DefaultFont.name); + exit(1); + } + + font->height = font->font->ascent + font->font->descent; + font->y = font->font->ascent; + font->ascent = font->font->ascent; + font->descent = font->font->descent; +} + +#ifndef NO_I18N_SUPPORT +int +MyFont_TextWidth(font, string, len) + MyFont *font; + char *string; + int len; +{ + XRectangle ink_rect; + XRectangle logical_rect; + + if (use_fontset) { + XmbTextExtents(font->fontset, string, len, &ink_rect, &logical_rect); + return logical_rect.width; + } + return XTextWidth(font->font, string, len); +} + +void +MyFont_DrawImageString(dpy, d, font, gc, x, y, string, len) + Display *dpy; + Drawable d; + MyFont *font; + GC gc; + int x,y; + char *string; + int len; +{ + if (use_fontset) { + XmbDrawImageString(dpy, d, font->fontset, gc, x, y, string, len); + return; + } + XDrawImageString (dpy, d, gc, x, y, string, len); +} + +void +MyFont_DrawString(dpy, d, font, gc, x, y, string, len) + Display *dpy; + Drawable d; + MyFont *font; + GC gc; + int x,y; + char *string; + int len; +{ + if (use_fontset) { + XmbDrawString(dpy, d, font->fontset, gc, x, y, string, len); + return; + } + XDrawString (dpy, d, gc, x, y, string, len); +} + +void +MyFont_ChangeGC(fix_fore, fix_back, fix_font) + unsigned long fix_fore, fix_back; + MyFont *fix_font; +{ + Gcv.foreground = fix_fore; + Gcv.background = fix_back; + if (use_fontset) { + XChangeGC(dpy, Scr->NormalGC, GCForeground|GCBackground, &Gcv); + return; + } + Gcv.font = fix_font->font->fid; + XChangeGC(dpy, Scr->NormalGC, GCFont|GCForeground|GCBackground,&Gcv); +} + +/* + * The following functions are internationalized substitutions + * for XFetchName and XGetIconName using XGetWMName and + * XGetWMIconName. + * + * Please note that the third arguments have to be freed using free(), + * not XFree(). + */ +Status +I18N_FetchName(dpy, w, winname) + Display *dpy; + Window w; + char ** winname; +{ + int status; + XTextProperty text_prop; + char **list; + int num; + + status = XGetWMName(dpy, w, &text_prop); + if (!status || !text_prop.value || !text_prop.nitems) { + *winname = NULL; + return 0; + } + *winname = (char *)strdup(text_prop.value); + status = XmbTextPropertyToTextList(dpy, &text_prop, &list, &num); + if (status < Success || !num || !*list) { + *winname = NULL; + return 0; + } + XFree(text_prop.value); + *winname = (char *)strdup(*list); + XFreeStringList(list); + return 1; +} + +Status +I18N_GetIconName(dpy, w, iconname) + Display *dpy; + Window w; + char ** iconname; +{ + int status; + XTextProperty text_prop; + char **list; + int num; + + status = XGetWMIconName(dpy, w, &text_prop); + if (!status || !text_prop.value || !text_prop.nitems) return 0; + *iconname = (char *)strdup(text_prop.value); + status = XmbTextPropertyToTextList(dpy, &text_prop, &list, &num); + if (status < Success || !num || !*list) return 0; + XFree(text_prop.value); + *iconname = (char *)strdup(*list); + XFreeStringList(list); + return 1; +} +#endif + + +/* + * SetFocus - separate routine to set focus to make things more understandable + * and easier to debug + */ +void SetFocus (tmp_win, time) + TwmWindow *tmp_win; + Time time; +{ + Window w = (tmp_win ? tmp_win->w : PointerRoot); + +#ifdef TRACE + if (tmp_win) { + printf ("Focusing on window \"%s\"\n", tmp_win->full_name); + } else { + printf ("Unfocusing; Scr->Focus was \"%s\"\n", + Scr->Focus ? Scr->Focus->full_name : "(nil)"); + } +#endif + + XSetInputFocus (dpy, w, RevertToPointerRoot, time); +} + + +#ifdef NEED_PUTENV_F +/* + * define our own putenv() if the system doesn't have one. + * putenv(s): place s (a string of the form "NAME=value") in + * the environment; replacing any existing NAME. s is placed in + * environment, so if you change s, the environment changes (like + * putenv on a sun). Binding removed if you putenv something else + * called NAME. + */ +int +putenv(s) +/* djhjr - 4/22/98 +char *s; +*/ +const char *s; +{ + char *v; + int varlen, idx; + extern char **environ; + char **newenv; + static int virgin = 1; /* true while "environ" is a virgin */ + + v = index(s, '='); + if(v == 0) + return 0; /* punt if it's not of the right form */ + varlen = (v + 1) - s; + + for (idx = 0; environ[idx] != 0; idx++) { + if (strncmp(environ[idx], s, varlen) == 0) { + if(v[1] != 0) { /* true if there's a value */ + environ[idx] = (char *)s; + return 0; + } else { + do { + environ[idx] = environ[idx+1]; + } while(environ[++idx] != 0); + return 0; + } + } + } + + /* add to environment (unless no value; then just return) */ + if(v[1] == 0) + return 0; + if(virgin) { + register i; + + newenv = (char **) malloc((unsigned) ((idx + 2) * sizeof(char*))); + if(newenv == 0) + return -1; + for(i = idx-1; i >= 0; --i) + newenv[i] = environ[i]; + virgin = 0; /* you're not a virgin anymore, sweety */ + } else { + newenv = (char **) realloc((char *) environ, + (unsigned) ((idx + 2) * sizeof(char*))); + if (newenv == 0) + return -1; + } + + environ = newenv; + environ[idx] = (char *)s; + environ[idx+1] = 0; + + return 0; +} +#endif /* NEED_PUTENV_F */ + + +/* Returns a blank cursor */ +Cursor NoCursor() +{ + static Cursor blank = (Cursor) NULL; + Pixmap nopixmap; + XColor nocolor; + + if (!blank) { + nopixmap = XCreatePixmap(dpy, Scr->Root, 1, 1, 1); + nocolor.red = nocolor.blue = nocolor.green = 0; + blank = XCreatePixmapCursor(dpy, nopixmap, nopixmap, &nocolor, &nocolor, 1, 1); + } + return(blank); +} + +/* djhjr - 10/30/02 */ +static void DrawDotImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + XPoint points[5]; + int wb, hb, ws, hs, lw; + + lw = (w > h) ? h / 16 : w / 16; + if (lw == 1) lw = 0; + XSetForeground(dpy, rootGC, cp.fore); + XSetLineAttributes(dpy, rootGC, lw, LineSolid, CapButt, JoinMiter); + + ws = x + (w / 2) - 2; + hs = y + (h / 2) - 2; + wb = ws + 4; + hb = hs + 4; + + points[0].x = points[3].x = points[4].x = ws; + points[0].y = points[1].y = points[4].y = hs; + points[1].x = points[2].x = wb; + points[2].y = points[3].y = hb; + XDrawLines(dpy, d, rootGC, points, 5, CoordModeOrigin); +} + +/* djhjr - 10/30/02 */ +static void DrawResizeImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + XPoint points[3]; + int wb, hb, ws, hs, lw; + + lw = (w > h) ? h / 16 : w / 16; + if (lw == 1) lw = 0; + XSetForeground(dpy, rootGC, cp.fore); + XSetLineAttributes(dpy, rootGC, lw, LineSolid, CapButt, JoinMiter); + + y--; + wb = w / 4; /* bigger width */ + hb = h / 4; /* bigger width */ + ws = w / 2; /* smaller width */ + hs = h / 2; /* smaller width */ + + points[0].x = x; + points[0].y = points[1].y = y + hb; + points[1].x = points[2].x = x + w - wb - 1; + points[2].y = y + h; + XDrawLines(dpy, d, rootGC, points, 3, CoordModeOrigin); + + points[0].x = x; + points[0].y = points[1].y = y + hs; + points[1].x = points[2].x = x + ws; + points[2].y = y + h; + XDrawLines(dpy, d, rootGC, points, 3, CoordModeOrigin); +} + +/* djhjr - 10/30/02 */ +static void DrawMenuImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + int ih, iw; + int ix, iy; + int mh, mw; + int tw, th; + int lw, lh; + int lx, ly; + int lines, dly; + /*int off;*/ + int bw; + + if (h < 1) h = 1; + if (w < 1) w = 1; + + ix = iy = pad + 1; + ih = h - iy * 2; + iw = w - ix * 2; + /*off = ih / 8;*/ + mh = ih - ih / 8/*off*/; + mw = iw - iw / 8/*off*/; + bw = mh / 16; + if (bw == 0 && mw > 2) bw = 1; + tw = mw - bw * 2; + th = mh - bw * 2; + ix += x; + iy += y; + XSetForeground(dpy, rootGC, cp.fore); + XFillRectangle(dpy, d, rootGC, ix, iy, mw, mh); + XFillRectangle(dpy, d, rootGC, ix + iw - mw, iy + ih - mh, mw, mh); + XSetForeground(dpy, rootGC, cp.back); + XFillRectangle(dpy, d, rootGC, ix + bw, iy + bw, tw, th); + + lw = tw / 2; + if ((tw & 1) ^ (lw & 1)) lw++; + lx = ix + bw + (tw - lw) / 2; + lh = th / 2 - bw; + if ((lh & 1) ^ ((th - bw) & 1)) lh++; + ly = iy + bw + (th - bw - lh) / 2; + lines = 3; + if ((lh & 1) && lh < 6) lines--; + dly = lh / (lines - 1); + XSetForeground(dpy, rootGC, cp.fore); + while (lines--) + { + XFillRectangle(dpy, d, rootGC, lx, ly, lw, bw); + ly += dly; + } +} + +/* djhjr - 10/30/02 */ +static void DrawXLogoImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + GC gcBack; + XGCValues gcvalues; + int lw; + + gcBack = XCreateGC(dpy, Scr->Root, 0, &gcvalues); + gcvalues.background = cp.back; + gcvalues.foreground = cp.fore; + XChangeGC(dpy, gcBack, GCForeground | GCBackground, &gcvalues); + + lw = (w > h) ? h / 16 : w / 16; + if (lw < 3) lw = 3; + XSetLineAttributes(dpy, gcBack, lw, LineSolid, CapButt, JoinMiter); + + /* + * Draw the logo large so that it gets as dense as possible, + * then blank out the edges so that they look crisp. + */ + + x += pad; + y += pad; + w -= pad * 2; + h -= pad * 2; + XSetForeground(dpy, rootGC, cp.fore); + XSetForeground(dpy, gcBack, cp.back); + XmuDrawLogo(dpy, d, rootGC, gcBack, x - 1, y - 1, w + 2, h + 2); + XDrawRectangle(dpy, d, gcBack, x - 1, y - 1, w + 1, h + 1); + + XFreeGC(dpy, gcBack); +} + +/* djhjr - 10/30/02 */ +static void DrawQuestionImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + Pixmap p; + + p = XCreateBitmapFromData(dpy, Scr->Root, questionmark_bits, + questionmark_width, questionmark_height); + + XSetForeground(dpy, rootGC, cp.fore); + XCopyPlane(dpy, p, d, rootGC, 0, 0, + questionmark_width, questionmark_height, + x + (w - questionmark_width) / 2, + y + (h - questionmark_height) / 2, + (unsigned long)1); + + XFreePixmap(dpy, p); +} + +/* djhjr - 10/30/02 */ +static void DrawRArrowImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + XPoint points[4]; + int lw, mw, mh; + + if (!(h & 1)) h--; + if (h < 1) h = 1; + + lw = (w > h) ? h / 16 : w / 16; + if (lw == 1) lw = 0; + XSetForeground(dpy, rootGC, cp.fore); + XSetLineAttributes(dpy, rootGC, lw, LineSolid, CapButt, JoinMiter); + + mw = w / 3; + mh = h / 3; + points[0].x = w - mw; + points[0].y = h / 2; + points[1].x = mw - 1; + points[1].y = mh - 1; + points[2].x = mw - 1; + points[2].y = h - mh; + points[3] = points[0]; + XDrawLines(dpy, d, rootGC, points, 4, CoordModeOrigin); +} + +/* djhjr - 10/30/02 */ +static void DrawDArrowImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + XPoint points[4]; + int lw, mw, mh; + + if (!(h & 1)) h--; + if (h < 1) h = 1; + + lw = (w > h) ? h / 16 : w / 16; + if (lw == 1) lw = 0; + XSetForeground(dpy, rootGC, cp.fore); + XSetLineAttributes(dpy, rootGC, lw, LineSolid, CapButt, JoinMiter); + + mw = h / 3; + mh = h / 3; + points[0].x = w / 2; + points[0].y = h - mh; + points[1].x = w - mw; + points[1].y = mh - 1; + points[2].x = mw - 1; + points[2].y = mh - 1; + points[3] = points[0]; + XDrawLines(dpy, d, rootGC, points, 4, CoordModeOrigin); +} + +/* djhjr - 4/19/96 */ +/* added d, x, y, w, h, state - djhjr - 10/29/02 */ +static void Draw3DDotImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + Draw3DBorder(d, x + (w / 2) - 2, y + (h / 2) - 2, 5, 5, + Scr->ShallowReliefWindowButton, cp, state, True, False); +} + +/* djhjr - 4/19/96 */ +/* added d, x, y, w, h, state - djhjr - 10/29/02 */ +static void Draw3DBarImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + /* was 'Scr->TitleBevelWidth' - djhjr - 8/11/98 */ + Draw3DBorder (d, x + pad + 1, y + (h - 5) / 2, + w - pad * 2 - 2, 5, + Scr->ShallowReliefWindowButton, cp, state, True, False); +} + +/* djhjr - 4/19/96 */ +/* added d, x, y, w, h, state - djhjr - 10/29/02 */ +static void Draw3DMenuImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + int i, lines, width, height; + + height = Scr->ShallowReliefWindowButton * 2; + + /* count the menu lines */ + lines = (h - pad * 2 - 2) / height; + /* center 'em */ + y += (h - lines * height) / 2; + if (!(y & 1)) y += 1; + /* now draw 'em */ + x += pad + 1; + lines = y + lines * height; + width = w - pad * 2 - 2; + for (i = y; i < lines; i += height) + Draw3DBorder(d, x, i, width, height, + Scr->ShallowReliefWindowButton, + cp, state, True, False); +} + +/* djhjr - 4/19/96 */ +/* added d, x, y, w, h, state - djhjr - 10/29/02 */ +static void Draw3DResizeImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + int i, j; + + /* djhjr - 4/29/98 */ + /* was 'Scr->TitleBevelWidth' - djhjr - 8/11/98 */ + i = w - Scr->ButtonBevelWidth * 2; + + /* + * Extend the left and bottom "off-window" by the + * line width for "thick" boxes on "thin" buttons. + */ + + /* was 'Scr->TitleBevelWidth' - djhjr - 8/11/98 */ + j = Scr->ButtonBevelWidth + (i / 4); + Draw3DBorder(d, + x + -Scr->ShallowReliefWindowButton, y + j - 1, + x + w - j + 1 + Scr->ShallowReliefWindowButton, + y + h - j + 1 + Scr->ShallowReliefWindowButton, + Scr->ShallowReliefWindowButton, cp, state, True, False); + + j = Scr->ButtonBevelWidth + (i / 2); + Draw3DBorder(d, + x + -Scr->ShallowReliefWindowButton, y + j, + x + w - j + Scr->ShallowReliefWindowButton, + y + h - j + Scr->ShallowReliefWindowButton, + Scr->ShallowReliefWindowButton, cp, state, True, False); +} + +/* djhjr - 4/19/96 */ +/* added d, x, y, w, h, state - djhjr - 10/29/02 */ +static void Draw3DZoomImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + /* was 'Scr->TitleBevelWidth' - djhjr - 8/11/98 */ + Draw3DBorder (d, + x + pad + 1, y + pad + 1, + w - 2 * pad - 2, + h - 2 * pad - 2, + Scr->ShallowReliefWindowButton, cp, state, True, False); +} + +/* djhjr - 6/4/00 */ +/* added d, x, y, w, h, state - djhjr - 10/29/02 */ +static void Draw3DRArrowImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + int i, mw, mh; + + mw = w / 3; + mh = h / 3; + + if (Scr->Monochrome != COLOR) + { + /* draw highlights */ + setBorderGC(1, Scr->GreyGC, cp, state, False); + for (i = 0; i < Scr->ShallowReliefWindowButton; i++) + { + XDrawLine(dpy, d, Scr->GreyGC, + x + w - mw - i, y + h / 2, + x + mw - 1 + i, y + mh - 1 + i); + XDrawLine (dpy, d, Scr->GreyGC, + x + mw - 1 + i, y + mh - 1 + i, + x + mw - 1 + i, y + h - mh - i); + } + + /* draw shadows */ + setBorderGC(2, Scr->GreyGC, cp, state, False); + for (i = 0; i < Scr->ShallowReliefWindowButton; i++) + XDrawLine (dpy, d, Scr->GreyGC, + x + mw - 1 + i, y + h - mh - i, + x + w - mw - i, y + h / 2); + } + else if (Scr->BeNiceToColormap) + { + int dashoffset = 0; + + setBorderGC(3, Scr->ShadGC, cp, state, False); + + /* draw highlights */ + XSetForeground (dpy, Scr->ShadGC, Scr->White); + for (i = 0; i < Scr->ShallowReliefWindowButton; i++) + { + XDrawLine(dpy, d, Scr->ShadGC, + x + w - mw - i, y + h / 2, + x + mw - 1 + i, y + mh - 1 + i); + XDrawLine (dpy, d, Scr->ShadGC, + x + mw - 1 + i, y + mh - 1 + i, + x + mw - 1 + i, y + h - mh - i); + } + + /* draw shadows */ + XSetForeground (dpy, Scr->ShadGC, Scr->Black); + for (i = 0; i < Scr->ShallowReliefWindowButton; i++) + { + XDrawLine (dpy, d, Scr->ShadGC, + x + mw - 1 + i, y + h - mh - i + dashoffset, + x + w - mw - i, y + h / 2 + dashoffset); + dashoffset = 1 - dashoffset; + } + } + else + { + /* draw highlights */ + if (state) + { FB (cp.shadc, cp.shadd); } + else + { FB (cp.shadd, cp.shadc); } + for (i = 0; i < Scr->ShallowReliefWindowButton; i++) + { + XDrawLine(dpy, d, Scr->NormalGC, + x + w - mw - i, y + h / 2, + x + mw - 1 + i, y + mh - 1 + i); + XDrawLine (dpy, d, Scr->NormalGC, + x + mw - 1 + i, y + mh - 1 + i, + x + mw - 1 + i, y + h - mh - i); + } + + /* draw shadows */ + if (state) + { FB (cp.shadd, cp.shadc); } + else + { FB (cp.shadc, cp.shadd); } + for (i = 0; i < Scr->ShallowReliefWindowButton; i++) + XDrawLine (dpy, d, Scr->NormalGC, + x + mw - 1 + i, y + h - mw - i, + x + w - mw - i, y + h / 2); + } +} + +/* djhjr - 6/4/00 */ +/* added d, x, y, w, h, state - djhjr - 10/29/02 */ +static void Draw3DDArrowImage(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + int i, mw, mh; + + mw = w / 3; + mh = h / 3; + + if (Scr->Monochrome != COLOR) + { + /* draw highlights */ + setBorderGC(1, Scr->GreyGC, cp, state, False); + for (i = 0; i < Scr->ShallowReliefWindowButton; i++) + { + XDrawLine(dpy, d, Scr->GreyGC, + x + w - mw - i, y + mh - 1 + i, + x + mw - 1 + i, y + mh - 1 + i); + XDrawLine (dpy, d, Scr->GreyGC, + x + mw - 1 + i, y + mh - 1 + i, + x + w / 2, y + mh - 1 - i + h / 2); + } + + /* draw shadows */ + setBorderGC(2, Scr->GreyGC, cp, state, False); + for (i = 0; i < Scr->ShallowReliefWindowButton; i++) + XDrawLine (dpy, d, Scr->GreyGC, + x + w / 2, y + mh - 1 - i + h / 2, + x + w - mw - i, y + mh + i); + } + else if (Scr->BeNiceToColormap) + { + int dashoffset = 0; + + setBorderGC(3, Scr->ShadGC, cp, state, False); + + /* draw highlights */ + XSetForeground (dpy, Scr->ShadGC, Scr->White); + for (i = 0; i < Scr->ShallowReliefWindowButton; i++) + { + XDrawLine(dpy, d, Scr->ShadGC, + x + w - mw - i, y + mh - 1 + i, + x + mw - 1 + i, y + mh - 1 + i); + XDrawLine (dpy, d, Scr->ShadGC, + x + mw - 1 + i, y + mh - 1 + i + dashoffset, + x + w / 2, y + mh - 1 - i + h / 2 + dashoffset); + dashoffset = 1 - dashoffset; + } + + /* draw shadows */ + XSetForeground (dpy, Scr->ShadGC, Scr->Black); + for (i = 0; i < Scr->ShallowReliefWindowButton; i++) + XDrawLine (dpy, d, Scr->ShadGC, + x + w / 2, y + mh - 1 - i + h / 2, + x + w - mw - i, y + mh + i); + } + else + { + /* draw highlights */ + if (state) + { FB (cp.shadc, cp.shadd); } + else + { FB (cp.shadd, cp.shadc); } + for (i = 0; i < Scr->ShallowReliefWindowButton; i++) + { + XDrawLine(dpy, d, Scr->NormalGC, + x + w - mw - i, y + mh - 1 + i, + x + mw - 1 + i, y + mh - 1 + i); + XDrawLine (dpy, d, Scr->NormalGC, + x + mw - 1 + i, y + mh - 1 + i, + x + w / 2, y + mh - 1 - i + h / 2); + } + + /* draw shadows */ + if (state) + { FB (cp.shadd, cp.shadc); } + else + { FB (cp.shadc, cp.shadd); } + for (i = 0; i < Scr->ShallowReliefWindowButton; i++) + XDrawLine (dpy, d, Scr->NormalGC, + x + w / 2, y + mh - 1 - i + h / 2, + x + w - mw - i, y + mh + i); + } +} + +/* djhjr - 10/25/02 */ +static void Draw3DBoxHighlight(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + Draw3DBorder(d, x, y, w, h, + Scr->ShallowReliefWindowButton, cp, + state, True, False); +} + +/* djhjr - 10/25/02 */ +static void Draw3DLinesHighlight(d, x, y, w, h, pad, cp, state) +Drawable d; +int x, y, w, h, pad; +ColorPair cp; +int state; +{ + int p; + + p = (Scr->ShallowReliefWindowButton & 1) ? 3 : 2; + p = (h - Scr->ShallowReliefWindowButton * p - 2) / 2; + + y += h / 2 - 1; + y -= (Scr->ShallowReliefWindowButton & 1) ? 0 : 1; + y += (state == on) ? 0 : 1; + + h = Scr->ShallowReliefWindowButton * 2; + + Draw3DBorder(d, x, y - p, w, h, + Scr->ShallowReliefWindowButton, cp, + state, False, False); + + if ((Scr->ShallowReliefWindowButton & 1)) + Draw3DBorder(d, x, y, w, h, + Scr->ShallowReliefWindowButton, cp, + state, False, False); + + Draw3DBorder(d, x, y + p, w, h, + Scr->ShallowReliefWindowButton, cp, + state, False, False); +} + +/* ick - djhjr - 10/30/02 */ +static void DrawBackground(d, x, y, w, h, cp, use_rootGC) +Drawable d; +int x, y, w, h; +ColorPair cp; +int use_rootGC; +{ + XGCValues gcvalues; + + if (use_rootGC) + { + if (rootGC == (GC)0) + rootGC = XCreateGC(dpy, Scr->Root, 0, &gcvalues); + + gcvalues.background = cp.back; + gcvalues.foreground = cp.fore; + XChangeGC(dpy, rootGC, GCForeground | GCBackground, &gcvalues); + + XSetForeground(dpy, rootGC, cp.back); + XFillRectangle(dpy, d, rootGC, x, y, w, h); + } + else + { + FB(cp.back, cp.fore); + XFillRectangle(dpy, d, Scr->NormalGC, x, y, w, h); + } +} + +/* djhjr - 10/25/02 */ +static void DrawTitleHighlight(t, state) +TwmWindow *t; +int state; +{ + static const struct { + char *name; + void (*proc)(); + Bool use_rootGC; + int state; + } pmtab[] = { + /* djhjr - 10/30/02 */ + { TBPM_DOT, DrawDotImage, True, off }, + { TBPM_ICONIFY, DrawDotImage, True, off }, + { TBPM_RESIZE, DrawResizeImage, True, off }, + { TBPM_MENU, DrawMenuImage, True, off }, + { TBPM_XLOGO, DrawXLogoImage, True, off }, + { TBPM_DELETE, DrawXLogoImage, True, off }, + { TBPM_QUESTION, DrawQuestionImage, True, off }, + + { TBPM_3DDOT, Draw3DDotImage, False, off }, + { TBPM_3DRESIZE, Draw3DResizeImage, False, off }, + { TBPM_3DMENU, Draw3DMenuImage, False, off }, + { TBPM_3DZOOM, Draw3DZoomImage, False, off }, + { TBPM_3DBAR, Draw3DBarImage, False, off }, + + /* djhjr - 10/30/02 */ + { TBPM_3DBOX, Draw3DBoxHighlight, False, off }, + { TBPM_3DLINES, Draw3DLinesHighlight, False, off }, + + { TBPM_3DRAISEDBOX, Draw3DBoxHighlight, False, off }, + { TBPM_3DSUNKENBOX, Draw3DBoxHighlight, False, on }, + { TBPM_3DRAISEDLINES, Draw3DLinesHighlight, False, off }, + { TBPM_3DSUNKENLINES, Draw3DLinesHighlight, False, on }, + }; + + XGCValues gcvalues; + ColorPair cp; + register int i; + int h, w; + + cp = t->title; + w = ComputeHighlightWindowWidth(t); + h = Scr->TitleHeight - 2 * Scr->FramePadding - 2; + + for (i = 0; i < sizeof(pmtab) / sizeof(pmtab[0]); i++) + { + if (XmuCompareISOLatin1(pmtab[i].name, Scr->hiliteName) == 0) + { + if (state == off) + { + DrawBackground(t->title_w, + t->highlightx, + Scr->FramePadding + 1, + w, h, cp, + pmtab[i].use_rootGC | (Scr->Monochrome != COLOR)); + } + else + { + /* ick - djhjr - 10/30/02 */ + if (pmtab[i].use_rootGC) + { + if (rootGC == (GC)0) + rootGC = XCreateGC(dpy, + Scr->Root, + 0, + &gcvalues); + + gcvalues.background = cp.back; + gcvalues.foreground = cp.fore; + XChangeGC(dpy, rootGC, + GCForeground | GCBackground, + &gcvalues); + } + + (*pmtab[i].proc)(t->title_w, + t->highlightx, + Scr->FramePadding + 1, + w, h, 0, cp, pmtab[i].state); + } + + break; + } + } +} + +/* djhjr - 1/13/98 */ +void setBorderGC(type, gc, cp, state, forcebw) +int type, state, forcebw; +GC gc; +ColorPair cp; +{ + XGCValues gcv; + unsigned long gcm; + + switch (type) + { + case 0: /* Monochrome main */ + gcm = GCFillStyle; + gcv.fill_style = FillOpaqueStippled; + break; + case 1: /* Monochrome highlight */ + gcm = 0; + gcm |= GCLineStyle; + gcv.line_style = (state == on) ? LineSolid : LineDoubleDash; + gcm |= GCFillStyle; + gcv.fill_style = FillSolid; + break; + case 2: /* Monochrome shadow */ + gcm = 0; + gcm |= GCLineStyle; + gcv.line_style = (state == on) ? LineDoubleDash : LineSolid; + gcm |= GCFillStyle; + gcv.fill_style = FillSolid; + break; + case 3: /* BeNiceToColormap */ + gcm = 0; + gcm |= GCLineStyle; + gcv.line_style = (forcebw) ? LineSolid : LineDoubleDash; + gcm |= GCBackground; + gcv.background = cp.back; + break; + default: + return; + } + + XChangeGC (dpy, gc, gcm, &gcv); +} + +/* djhjr - 4/19/96 */ +void Draw3DBorder (w, x, y, width, height, bw, cp, state, fill, forcebw) +Drawable w; +int x, y, width, height, bw; +ColorPair cp; +int state, fill, forcebw; +{ + int i; + + if (width < 1 || height < 1) return; + + if (Scr->Monochrome != COLOR) + { + /* set main color */ + if (fill) + { + setBorderGC(0, Scr->GreyGC, cp, state, forcebw); + XFillRectangle (dpy, w, Scr->GreyGC, x, y, width, height); + } + + /* draw highlights */ + setBorderGC(1, Scr->GreyGC, cp, state, forcebw); + for (i = 0; i < bw; i++) + { + XDrawLine (dpy, w, Scr->GreyGC, x, y + i, + x + width - i - 1, y + i); + XDrawLine (dpy, w, Scr->GreyGC, x + i, y, + x + i, y + height - i - 1); + } + + /* draw shadows */ + setBorderGC(2, Scr->GreyGC, cp, state, forcebw); + for (i = 0; i < bw; i++) + { + XDrawLine (dpy, w, Scr->GreyGC, x + width - i - 1, y + i, + x + width - i - 1, y + height - 1); + XDrawLine (dpy, w, Scr->GreyGC, x + i, y + height - i - 1, + x + width - 1, y + height - i - 1); + } + + return; + } + + /* set main color */ + if (fill) + { + FB (cp.back, cp.fore); + XFillRectangle (dpy, w, Scr->NormalGC, x, y, width, height); + } + + if (Scr->BeNiceToColormap) + { + setBorderGC(3, Scr->ShadGC, cp, state, forcebw); + + /* draw highlights */ + if (state == on) + XSetForeground (dpy, Scr->ShadGC, Scr->Black); + else + XSetForeground (dpy, Scr->ShadGC, Scr->White); + for (i = 0; i < bw; i++) + { + XDrawLine (dpy, w, Scr->ShadGC, + x + i, y + borderdashoffset, + x + i, y + height - i - 1); + XDrawLine (dpy, w, Scr->ShadGC, + x + borderdashoffset, y + i, + x + width - i - 1, y + i); + borderdashoffset = 1 - borderdashoffset; + } + + /* draw shadows */ + if (state == on) + XSetForeground (dpy, Scr->ShadGC, Scr->White); + else + XSetForeground (dpy, Scr->ShadGC, Scr->Black); + for (i = 0; i < bw; i++) + { + XDrawLine (dpy, w, Scr->ShadGC, x + i, y + height - i - 1, + x + width - 1, y + height - i - 1); + XDrawLine (dpy, w, Scr->ShadGC, x + width - i - 1, y + i, + x + width - i - 1, y + height - 1); + } + + return; + } + + /* draw highlights */ + if (state == on) + { FB (cp.shadd, cp.shadc); } + else + { FB (cp.shadc, cp.shadd); } + for (i = 0; i < bw; i++) + { + XDrawLine (dpy, w, Scr->NormalGC, x, y + i, + x + width - i - 1, y + i); + XDrawLine (dpy, w, Scr->NormalGC, x + i, y, + x + i, y + height - i - 1); + } + + /* draw shadows */ + if (state == on) + { FB (cp.shadc, cp.shadd); } + else + { FB (cp.shadd, cp.shadc); } + for (i = 0; i < bw; i++) + { + XDrawLine (dpy, w, Scr->NormalGC, x + width - i - 1, y + i, + x + width - i - 1, y + height - 1); + XDrawLine (dpy, w, Scr->NormalGC, x + i, y + height - i - 1, + x + width - 1, y + height - i - 1); + } +} + +#ifdef USE_ORIGINAL_CORNERS +/* djhjr - 4/19/96 */ +void Draw3DCorner (w, x, y, width, height, thick, bw, cp, type) +Window w; +int x, y, width, height, thick, bw; +ColorPair cp; +int type; +{ + Draw3DBorder (w, x, y, width, height, bw, cp, off, True, False); + + switch (type) + { + /* upper left */ + case 0 : + Draw3DBorder (w, x + thick - bw, y + thick - bw, + width - thick + 2 * bw, height - thick + 2 * bw, + bw, cp, on, True, False); + break; + /* upper right */ + case 1 : + Draw3DBorder (w, x - bw, y + thick - bw, + width - thick + 2 * bw, height - thick + 2 * bw, + bw, cp, on, True, False); + break; + /* lower right */ + case 2 : + Draw3DBorder (w, x - bw, y - bw, + width - thick + 2 * bw, height - thick + 2 * bw, + bw, cp, on, True, False); + break; + /* lower left */ + case 3 : + Draw3DBorder (w, x + thick - bw, y - bw, + width - thick + 2 * bw, height - thick + 2 * bw, + bw, cp, on, True, False); + break; + } +} +#else /* USE_ORIGINAL_CORNERS */ +/* djhjr - 1/14/98 */ +GC setBevelGC(type, state, cp) +int type, state; +ColorPair cp; +{ + GC gc; + + if (Scr->Monochrome != COLOR) + { + gc = Scr->GreyGC; + setBorderGC(type, gc, cp, state, False); + } + else if (Scr->BeNiceToColormap) + { + gc = Scr->ShadGC; + setBorderGC(3, gc, cp, state, False); + if (state == on) + XSetForeground (dpy, gc, Scr->Black); + else + XSetForeground (dpy, gc, Scr->White); + } + else + { + gc = Scr->NormalGC; + if (state == on) + { FB (cp.shadc, cp.shadd); } + else + { FB (cp.shadd, cp.shadc); } + } + + return (gc); +} + +/* djhjr - 1/12/98 */ +void Draw3DBevel (w, x, y, bw, cp, state, type) +Drawable w; +int x, y, bw; +ColorPair cp; +int state, type; +{ + int i; + GC gc; + + switch (type) + { + /* vertical */ + case 1 : + case 11 : + gc = setBevelGC(1, state, cp); + for (i = 0; i < Scr->BorderBevelWidth; i++) + XDrawLine (dpy, w, gc, x - i - 1, y + i, + x - i - 1, y + bw - 2 * i + i); + if (type == 11) break; + case 111 : + gc = setBevelGC(2, !state, cp); + for (i = 0; i < Scr->BorderBevelWidth; i++) + XDrawLine (dpy, w, gc, x + i, y + i - 1, + x + i, y + bw - 2 * i + i - 1); + break; + /* horizontal */ + case 2 : + case 22 : + gc = setBevelGC(1, state, cp); + for (i = 0; i < Scr->BorderBevelWidth; i++) + XDrawLine (dpy, w, gc, x + i, y - i - 1, + x + bw - 2 * i + i, y - i - 1); + if (type == 22) break; + case 222 : + gc = setBevelGC(2, !state, cp); + for (i = 0; i < Scr->BorderBevelWidth; i++) + XDrawLine (dpy, w, gc, x + i - 1, y + i, + x + bw - 2 * i + i - 1, y + i); + break; + /* ulc to lrc */ + case 3 : + if (Scr->Monochrome != COLOR) + { + gc = Scr->GreyGC; + setBorderGC(0, gc, cp, state, False); + } + else + { + gc = Scr->NormalGC; + FB (cp.back, cp.fore); + } + XFillRectangle (dpy, w, gc, x, y, bw, bw); + gc = setBevelGC(1, (Scr->BeNiceToColormap) ? state : !state, cp); + for (i = 0; i < Scr->BorderBevelWidth; i++) + XDrawLine (dpy, w, gc, x + i, y, + x + i, y + Scr->BorderBevelWidth - 1); + gc = setBevelGC(2, (Scr->BeNiceToColormap) ? !state : state, cp); + for (i = 0; i < Scr->BorderBevelWidth; i++) + XDrawLine (dpy, w, gc, x, y + bw - i - 1, + x + bw - 1, y + bw - i - 1); + for (i = 0; i < Scr->BorderBevelWidth; i++) + XDrawLine (dpy, w, gc, x + bw - i - 1, y, + x + bw - i - 1, y + bw - 1); + break; + /* urc to llc */ + case 4 : + if (Scr->Monochrome != COLOR) + { + gc = Scr->GreyGC; + setBorderGC(0, gc, cp, state, False); + } + else + { + gc = Scr->NormalGC; + FB (cp.back, cp.fore); + } + XFillRectangle (dpy, w, gc, x, y, bw, bw); + gc = setBevelGC(1, (Scr->BeNiceToColormap) ? state : !state, cp); + /* top light */ + for (i = 0; i < Scr->BorderBevelWidth; i++) + XDrawLine (dpy, w, gc, x + i, y, + x + i, y + bw - i); + /* bottom light */ + for (i = 0; i < Scr->BorderBevelWidth; i++) + XDrawLine (dpy, w, gc, x + bw - 1, y + i, + x + bw - i - 1, y + i); + gc = setBevelGC(2, (Scr->BeNiceToColormap) ? !state : state, cp); + /* top dark */ + for (i = 0; i < Scr->BorderBevelWidth - 1; i++) + XDrawLine (dpy, w, gc, x + bw - Scr->BorderBevelWidth, y + i, + x + bw - i - 2, y + i); + /* bottom dark */ + for (i = 0; i < Scr->BorderBevelWidth; i++) + XDrawLine (dpy, w, gc, x + i, y + bw - i - 1, + x + bw + 1, y + bw - i - 1); + break; + } +} + +/* djhjr - 10/20/02 */ +void Draw3DNoBevel(w, x, y, bw, cp, state, forcebw) +Drawable w; +int x, y, bw; +ColorPair cp; +int state, forcebw; +{ + int i, upr, lwr; + + if (bw < 1) return; + + upr = y - 2 * Scr->BorderBevelWidth; + if ((upr & 1)) upr--; + lwr = y + 2 * Scr->BorderBevelWidth; + if ((lwr & 1)) lwr++; + + if (Scr->Monochrome != COLOR) + { + /* set main color */ + setBorderGC(0, Scr->GreyGC, cp, state, forcebw); + XFillRectangle (dpy, w, Scr->GreyGC, + x + Scr->BorderBevelWidth, upr, + (unsigned int)(bw - Scr->BorderBevelWidth * 2), + (unsigned int)(upr * 2)); + + /* draw highlight */ + setBorderGC(1, Scr->GreyGC, cp, state, forcebw); + for (i = 0; i < Scr->BorderBevelWidth; i++) + XDrawLine (dpy, w, Scr->GreyGC, + x + i, upr, x + i, lwr); + + /* draw shadow */ + setBorderGC(2, Scr->GreyGC, cp, state, forcebw); + for (i = bw - Scr->BorderBevelWidth; i < bw; i++) + XDrawLine (dpy, w, Scr->GreyGC, + x + i, upr, x + i, lwr); + + return; + } + + /* set main color */ + FB (cp.back, cp.fore); + XFillRectangle (dpy, w, Scr->NormalGC, + x + Scr->BorderBevelWidth, upr, + (unsigned int)(bw - Scr->BorderBevelWidth * 2), + (unsigned int)(upr * 2)); + + if (Scr->BeNiceToColormap) + { + int dashoffset; + + setBorderGC(3, Scr->ShadGC, cp, state, forcebw); + + /* draw highlight */ + if (state == on) + XSetForeground (dpy, Scr->ShadGC, Scr->Black); + else + XSetForeground (dpy, Scr->ShadGC, Scr->White); + dashoffset = 0; + for (i = 0; i < Scr->BorderBevelWidth; i++) + { + XDrawLine (dpy, w, Scr->ShadGC, + x + i, upr + dashoffset, x + i, lwr); + dashoffset = 1 - dashoffset; + } + + /* draw shadow */ + if (state == on) + XSetForeground (dpy, Scr->ShadGC, Scr->White); + else + XSetForeground (dpy, Scr->ShadGC, Scr->Black); + dashoffset = 0; + for (i = bw - Scr->BorderBevelWidth; i < bw; i++) + { + XDrawLine (dpy, w, Scr->ShadGC, + x + i, upr + dashoffset, x + i, lwr); + dashoffset = 1 - dashoffset; + } + + return; + } + + /* draw highlight */ + if (state == on) + { FB (cp.shadc, cp.shadd); } + else + { FB (cp.shadd, cp.shadc); } + for (i = 0; i < Scr->BorderBevelWidth; i++) + XDrawLine (dpy, w, Scr->NormalGC, + x + i, upr, x + i, lwr); + + /* draw shadow */ + if (state == on) + { FB (cp.shadd, cp.shadc); } + else + { FB (cp.shadc, cp.shadd); } + for (i = bw - Scr->BorderBevelWidth; i < bw; i++) + XDrawLine (dpy, w, Scr->NormalGC, + x + i, upr, x + i, lwr); +} +#endif /* USE_ORIGINAL_CORNERS */ + +/* djhjr - 4/19/96 */ +static Image *LoadBitmapImage (name, cp) +char *name; +ColorPair cp; +{ + Image *image; + Pixmap bm; + int width, height; + XGCValues gcvalues; + + if (rootGC == (GC) 0) rootGC = XCreateGC (dpy, Scr->Root, 0, &gcvalues); + bm = FindBitmap (name, (unsigned int *) &width, (unsigned int *) &height); + if (bm == None) return (None); + + image = (Image*) malloc (sizeof (struct _Image)); + image->pixmap = XCreatePixmap (dpy, Scr->Root, width, height, Scr->d_depth); + gcvalues.background = cp.back; + gcvalues.foreground = cp.fore; + XChangeGC (dpy, rootGC, GCForeground | GCBackground, &gcvalues); + XCopyPlane (dpy, bm, image->pixmap, rootGC, 0, 0, width, height, 0, 0, (unsigned long) 1); + XFreePixmap (dpy, bm); + image->mask = None; + image->width = width; + image->height = height; + image->next = None; + return (image); +} + +/* djhjr - 10/30/02 */ +static Image *CreateImagePixmap(name, w, h, depth) +char *name; +int w, h, depth; +{ + Image *image; + + image = (Image *)malloc(sizeof(struct _Image)); + if (!image) + { + fprintf(stderr, "%s: cannot allocate %d bytes for Image \"%s\"\n", + ProgramName, sizeof(struct _Image), name); + return (None); + } + + image->pixmap = XCreatePixmap(dpy, Scr->Root, w, h, depth); + if (image->pixmap == None) + { + fprintf(stderr, "%s: cannot allocate %d bytes for pixmap \"%s\"\n", + ProgramName, sizeof(image->pixmap), name); + free((void *)image); + return (None); + } + + return (image); +} + +/* djhjr - 4/19/96 10/30/02 */ +static Image *ReallyGetImage(name, w, h, pad, cp) +char *name; +int w, h, pad; +ColorPair cp; +{ + static const struct { + char *name; + void (*proc)(); + Bool use_rootGC; + int state; + } pmtab[] = { + { TBPM_DOT, DrawDotImage, True, off }, + { TBPM_ICONIFY, DrawDotImage, True, off }, + { TBPM_RESIZE, DrawResizeImage, True, off }, + { TBPM_MENU, DrawMenuImage, True, off }, + { TBPM_XLOGO, DrawXLogoImage, True, off }, + { TBPM_DELETE, DrawXLogoImage, True, off }, + { TBPM_QUESTION, DrawQuestionImage, True, off }, + + /* djhjr - 6/4/00 */ + { TBPM_RARROW, DrawRArrowImage, True, off }, + { TBPM_DARROW, DrawDArrowImage, True, off }, + + { TBPM_3DDOT, Draw3DDotImage, False, off }, + { TBPM_3DRESIZE, Draw3DResizeImage, False, off }, + { TBPM_3DMENU, Draw3DMenuImage, False, off }, + { TBPM_3DZOOM, Draw3DZoomImage, False, off }, + { TBPM_3DBAR, Draw3DBarImage, False, off }, + + /* djhjr - 6/4/00 */ + { TBPM_3DRARROW, Draw3DRArrowImage, False, off }, + { TBPM_3DDARROW, Draw3DDArrowImage, False, off }, + + /* djhjr - 10/30/02 */ + { TBPM_3DBOX, Draw3DBoxHighlight, False, off }, + { TBPM_3DLINES, Draw3DLinesHighlight, False, off }, + }; + + Image *image = NULL; + name_list **list; + register int i; + char fullname [256]; + + if (name == NULL) return (NULL); + + list = &Scr->ImageCache; + + if (name[0] == ':') + { + /* probably need '"%d", Scr->screen' - Caveh Frank Jalali */ + sprintf(fullname, "%s.%dx%d.%Xx%X", name, + w, h, (int)cp.fore, (int)cp.back); + if ((image = (Image *)LookInNameList(*list, fullname)) == NULL) + { + for (i = 0; i < sizeof(pmtab) / sizeof(pmtab[0]); i++) + { + if (XmuCompareISOLatin1(pmtab[i].name, name) == 0) + { + if (!(image = CreateImagePixmap(name, w, h, Scr->d_depth))) + return (None); + + DrawBackground(image->pixmap, 0, 0, w, h, cp, + pmtab[i].use_rootGC | (Scr->Monochrome != COLOR)); + + /* added d, x, y, w, h, pad, state - djhjr - 10/29/02 */ + (*pmtab[i].proc)(image->pixmap, 0, 0, w, h, pad, + cp, pmtab[i].state); + + image->mask = None; + image->width = w; + image->height = h; + image->next = None; + break; + } + } + + if (!image) + { + fprintf(stderr, "%s: no such built-in pixmap \"%s\"\n", + ProgramName, name); + return (NULL); + } + } + else + return (image); + } + else + { + /* + * Need screen number in fullname since screens may have different GCs. + * Submitted by Caveh Frank Jalali + */ + sprintf(fullname, "%s.%Xx%X.%d", + name, (int)cp.fore, (int)cp.back, (int)Scr->screen); + if ((image = (Image *)LookInNameList(*list, fullname)) == NULL) + { + if ((image = LoadBitmapImage(name, cp)) == NULL) +#ifndef NO_XPM_SUPPORT + /* djhjr - 3/20/98 */ + /* added color argument - djhjr - 9/28/99 */ + image = FindImage(name, cp.back); +#else + ; +#endif + + if (!image) return (NULL); + } + else + return (image); + } + + /* added 'type' argument - djhjr - 10/20/01 */ + AddToList(list, fullname, LTYPE_EXACT_NAME, (char *)image); + + return (image); +} + +/* + * Wrapper to guarantee something is returned - djhjr - 10/30/02 + */ +Image *GetImage(name, w, h, pad, cp) +char *name; +int w, h, pad; +ColorPair cp; +{ + Image *image = NULL; + + if (!(image = ReallyGetImage(name, w, h, pad, cp))) + image = ReallyGetImage(TBPM_QUESTION, w, h, pad, cp); + + return (image); +} + +/* djhjr - 4/21/96 */ +/* djhjr - 1/12/98 */ +void PaintBorders (tmp_win, focus) +TwmWindow *tmp_win; +Bool focus; +{ + GC gc; + ColorPair cp; + int i, j, cw, ch, cwbw, chbw; +#ifdef USE_ORIGINAL_CORNERS + int THbw, fhbwchbw, fhTHchbw; +#endif + + cp = (focus && tmp_win->highlight) ? tmp_win->border : tmp_win->border_tile; + + /* no titlebar, no corners */ + if (tmp_win->title_height == 0) + { + Draw3DBorder (tmp_win->frame, + 0, + 0, + tmp_win->frame_width, + tmp_win->frame_height, + Scr->BorderBevelWidth, cp, off, True, False); + Draw3DBorder (tmp_win->frame, + tmp_win->frame_bw3D - Scr->BorderBevelWidth, + tmp_win->frame_bw3D - Scr->BorderBevelWidth, + tmp_win->frame_width - 2 * tmp_win->frame_bw3D + 2 * Scr->BorderBevelWidth, + tmp_win->frame_height - 2 * tmp_win->frame_bw3D + 2 * Scr->BorderBevelWidth, + Scr->BorderBevelWidth, cp, on, True, False); + + return; + } + + cw = ch = Scr->TitleHeight; + if (cw * 2 > tmp_win->attr.width) cw = tmp_win->attr.width / 2; + if (ch * 2 > tmp_win->attr.height) ch = tmp_win->attr.height / 2; + cwbw = cw + tmp_win->frame_bw3D; + chbw = ch + tmp_win->frame_bw3D; + +#ifdef USE_ORIGINAL_CORNERS + THbw = Scr->TitleHeight + tmp_win->frame_bw3D; + fhbwchbw = tmp_win->frame_height + tmp_win->frame_bw3D - 3 * chbw; + fhTHchbw = tmp_win->frame_height - (Scr->TitleHeight + ch + 2 * tmp_win->frame_bw3D); + + /* client upper left corner */ + if (tmp_win->squeeze_info && tmp_win->title_x > tmp_win->frame_bw3D) + Draw3DCorner (tmp_win->frame, + 0, + Scr->TitleHeight, + cwbw, + chbw, + tmp_win->frame_bw3D, Scr->BorderBevelWidth, cp, 0); + /* client top bar */ + if (tmp_win->squeeze_info) + Draw3DBorder (tmp_win->frame, + THbw, + tmp_win->title_height, + tmp_win->frame_width - 2 * cwbw, + tmp_win->frame_bw3D, + Scr->BorderBevelWidth, cp, off, True, False); + /* client upper right corner */ + if (tmp_win->squeeze_info && tmp_win->title_x + tmp_win->title_width + tmp_win->frame_bw3D < tmp_win->frame_width) + Draw3DCorner (tmp_win->frame, + tmp_win->frame_width - cwbw, + Scr->TitleHeight, + cwbw, + chbw, + tmp_win->frame_bw3D, Scr->BorderBevelWidth, cp, 1); + /* client left bar */ + if (tmp_win->squeeze_info && tmp_win->title_x > tmp_win->frame_bw3D) + Draw3DBorder (tmp_win->frame, + 0, + THbw + ch, + tmp_win->frame_bw3D, + fhbwchbw, + Scr->BorderBevelWidth, cp, off, True, False); + else + Draw3DBorder (tmp_win->frame, + 0, + THbw, + tmp_win->frame_bw3D, + fhTHchbw, + Scr->BorderBevelWidth, cp, off, True, False); + /* client right bar */ + if (tmp_win->squeeze_info && tmp_win->title_x + tmp_win->title_width + tmp_win->frame_bw3D < tmp_win->frame_width) + Draw3DBorder (tmp_win->frame, + tmp_win->frame_width - tmp_win->frame_bw3D, + THbw + ch, + tmp_win->frame_bw3D, + fhbwchbw, + Scr->BorderBevelWidth, cp, off, True, False); + else + Draw3DBorder (tmp_win->frame, + tmp_win->frame_width - tmp_win->frame_bw3D, + THbw, + tmp_win->frame_bw3D, + fhTHchbw, + Scr->BorderBevelWidth, cp, off, True, False); + /* client lower left corner */ + Draw3DCorner (tmp_win->frame, + 0, + tmp_win->frame_height - chbw, + cwbw, + chbw, + tmp_win->frame_bw3D, Scr->BorderBevelWidth, cp, 3); + /* client bottom bar */ + Draw3DBorder (tmp_win->frame, + THbw, + tmp_win->frame_height - tmp_win->frame_bw3D, + tmp_win->frame_width - 2 * cwbw, + tmp_win->frame_bw3D, + Scr->BorderBevelWidth, cp, off, True, False); + /* client lower right corner */ + Draw3DCorner (tmp_win->frame, + tmp_win->frame_width - cwbw, + tmp_win->frame_height - chbw, + cwbw, + chbw, + tmp_win->frame_bw3D, Scr->BorderBevelWidth, cp, 2); + + /* titlebar upper left corner */ + Draw3DCorner (tmp_win->frame, + tmp_win->title_x - tmp_win->frame_bw3D, + 0, + cwbw, + THbw, + tmp_win->frame_bw3D, Scr->BorderBevelWidth, cp, 0); + /* titlebar top bar */ + Draw3DBorder (tmp_win->frame, + tmp_win->title_x + cw, + 0, + tmp_win->title_width - 2 * cw, + tmp_win->frame_bw3D, + Scr->BorderBevelWidth, cp, off, True, False); + /* titlebar upper right corner */ + Draw3DCorner (tmp_win->frame, + (tmp_win->title_width > 2 * Scr->TitleHeight) + ? tmp_win->title_x + tmp_win->title_width - Scr->TitleHeight + : tmp_win->frame_width - cwbw, + 0, + cwbw, + THbw, + tmp_win->frame_bw3D, Scr->BorderBevelWidth, cp, 1); +#else /* USE_ORIGINAL_CORNERS */ + /* client */ + borderdashoffset = 1; + Draw3DBorder (tmp_win->frame, + 0, + Scr->TitleHeight, + tmp_win->frame_width, + tmp_win->frame_height - Scr->TitleHeight, + Scr->BorderBevelWidth, cp, off, True, False); + borderdashoffset = 1; + Draw3DBorder (tmp_win->frame, + tmp_win->frame_bw3D - Scr->BorderBevelWidth, + Scr->TitleHeight + tmp_win->frame_bw3D - Scr->BorderBevelWidth, + tmp_win->frame_width - 2 * tmp_win->frame_bw3D + 2 * Scr->BorderBevelWidth, + tmp_win->frame_height - 2 * tmp_win->frame_bw3D + 2 * Scr->BorderBevelWidth - Scr->TitleHeight, + Scr->BorderBevelWidth, cp, on, True, False); + if (!Scr->NoBorderDecorations) /* djhjr - 10/20/02 */ + { + /* upper left corner */ + if (tmp_win->title_x == tmp_win->frame_bw3D) + Draw3DBevel (tmp_win->frame, + 0, Scr->TitleHeight + tmp_win->frame_bw3D, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? on : off, 222); + else + { + if (tmp_win->title_x > tmp_win->frame_bw3D + cwbw) + Draw3DBevel (tmp_win->frame, + cwbw, Scr->TitleHeight, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? on : off, 1); + Draw3DBevel (tmp_win->frame, + 0, Scr->TitleHeight + chbw, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? on : off, 2); + } + } + /* upper right corner */ + if ((i = tmp_win->title_x + tmp_win->title_width + tmp_win->frame_bw3D) == tmp_win->frame_width) + Draw3DBevel (tmp_win->frame, + tmp_win->frame_width - tmp_win->frame_bw3D, Scr->TitleHeight + tmp_win->frame_bw3D, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? on : off, 222); + else + { + if (!Scr->NoBorderDecorations) /* djhjr - 10/20/02 */ + { + if (i < tmp_win->frame_width - cwbw) + Draw3DBevel (tmp_win->frame, + tmp_win->frame_width - cwbw, Scr->TitleHeight, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? on : off, 1); + Draw3DBevel (tmp_win->frame, + tmp_win->frame_width - tmp_win->frame_bw3D, + Scr->TitleHeight + chbw, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? on : off, 2); + } + } + if (!Scr->NoBorderDecorations) /* djhjr - 10/20/02 */ + { + /* lower left corner */ + Draw3DBevel (tmp_win->frame, + cwbw, tmp_win->frame_height - tmp_win->frame_bw3D, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? on : off, 1); + Draw3DBevel (tmp_win->frame, + 0, tmp_win->frame_height - chbw, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? on : off, 2); + /* lower right corner */ + Draw3DBevel (tmp_win->frame, + tmp_win->frame_width - cwbw, + tmp_win->frame_height - tmp_win->frame_bw3D, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? on : off, 1); + Draw3DBevel (tmp_win->frame, + tmp_win->frame_width - tmp_win->frame_bw3D, + tmp_win->frame_height - chbw, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? on : off, 2); + } + /* title */ + borderdashoffset = 0; + Draw3DBorder (tmp_win->frame, + tmp_win->title_x - tmp_win->frame_bw3D, + tmp_win->title_y - tmp_win->frame_bw3D, + tmp_win->title_width + 2 * tmp_win->frame_bw3D, + Scr->TitleHeight + tmp_win->frame_bw3D, + Scr->BorderBevelWidth, cp, off, True, False); + borderdashoffset = 0; + Draw3DBorder (tmp_win->frame, + tmp_win->title_x - Scr->BorderBevelWidth, + tmp_win->title_y - Scr->BorderBevelWidth, + tmp_win->title_width + 2 * Scr->BorderBevelWidth, + Scr->TitleHeight, + Scr->BorderBevelWidth, cp, on, True, False); + /* upper left corner */ + if (tmp_win->title_x == tmp_win->frame_bw3D) + { + /* this 'if (...) else' - djhjr - 10/20/02 */ + if (Scr->NoBorderDecorations) + { + Draw3DNoBevel(tmp_win->frame, + tmp_win->title_x - tmp_win->frame_bw3D, + Scr->TitleHeight + tmp_win->frame_bw3D, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? off : on, False); + } + else + { + gc = setBevelGC(2, (Scr->BeNiceToColormap) ? on : off, cp); + +/* djhjr - 4/29/98 + XDrawLine (dpy, tmp_win->frame, gc, + tmp_win->title_x - 2, Scr->TitleHeight + tmp_win->frame_bw3D - 4, + tmp_win->title_x - 2, Scr->TitleHeight + tmp_win->frame_bw3D - 1); + XDrawLine (dpy, tmp_win->frame, gc, + tmp_win->title_x - 1, Scr->TitleHeight + tmp_win->frame_bw3D - 4, + tmp_win->title_x - 1, Scr->TitleHeight + tmp_win->frame_bw3D - 1); +*/ + for (j = 1; j <= Scr->BorderBevelWidth; j++) + XDrawLine (dpy, tmp_win->frame, gc, + tmp_win->title_x - j, + Scr->TitleHeight + tmp_win->frame_bw3D - 2 * Scr->BorderBevelWidth, + tmp_win->title_x - j, + Scr->TitleHeight + tmp_win->frame_bw3D - Scr->BorderBevelWidth - 1); + + Draw3DBevel (tmp_win->frame, + tmp_win->title_x + cw, 0, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? on : off, 1); + } + } + else + { + Draw3DBevel (tmp_win->frame, + tmp_win->title_x - tmp_win->frame_bw3D, Scr->TitleHeight, + tmp_win->frame_bw3D, cp, off, 3); + } + /* upper right corner */ + if (i == tmp_win->frame_width) + { + /* this 'if (...) else' - djhjr - 10/20/02 */ + if (Scr->NoBorderDecorations) + { + Draw3DNoBevel(tmp_win->frame, + tmp_win->frame_width - tmp_win->frame_bw3D, + Scr->TitleHeight + tmp_win->frame_bw3D, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? off : on, False); + } + else + { + gc = setBevelGC(1, (Scr->BeNiceToColormap) ? off : on, cp); + +/* djhjr - 4/29/98 + gc = setBevelGC(1, on, cp); + XDrawLine (dpy, tmp_win->frame, gc, + tmp_win->title_x + tmp_win->title_width, Scr->TitleHeight + tmp_win->frame_bw3D - 2, + tmp_win->title_x + tmp_win->title_width, Scr->TitleHeight + tmp_win->frame_bw3D - 2); +*/ + for (j = 0; j < Scr->BorderBevelWidth; j++) + XDrawLine (dpy, tmp_win->frame, gc, + tmp_win->title_x + tmp_win->title_width - 1, + Scr->TitleHeight + tmp_win->frame_bw3D - Scr->BorderBevelWidth + j - 1, + tmp_win->title_x + tmp_win->title_width + Scr->BorderBevelWidth - j - 1, + Scr->TitleHeight + tmp_win->frame_bw3D - Scr->BorderBevelWidth + j - 1); + + Draw3DBevel (tmp_win->frame, + tmp_win->title_x + tmp_win->title_width - cw, 0, + tmp_win->frame_bw3D, cp, + (Scr->BeNiceToColormap) ? on : off, 1); + } + } + else + { + Draw3DBevel (tmp_win->frame, + tmp_win->title_x + tmp_win->title_width, Scr->TitleHeight, + tmp_win->frame_bw3D, cp, off, 4); + } +#endif /* USE_ORIGINAL_CORNERS */ +} + +/* djhjr - 4/21/96 */ +void PaintIcon (tmp_win) +TwmWindow *tmp_win; +{ +/* djhjr - 5/5/98 + if (Scr->use3Diconmanagers) { +*/ + /* was 'Scr->use3Dicons' - djhjr - 8/11/98 */ + if (Scr->IconBevelWidth > 0) { + +/* + Draw3DBorder (tmp_win->icon_w, 0, tmp_win->icon_height, + tmp_win->icon_w_width, Scr->IconFont.height + 6, + Scr->BorderBevelWidth, tmp_win->iconc, off, False, False); +*/ + /* was 'Scr->BorderBevelWidth' - djhjr - 8/11/98 */ + Draw3DBorder (tmp_win->icon_w, 0, 0, + tmp_win->icon_w_width, tmp_win->icon_w_height, + Scr->IconBevelWidth, tmp_win->iconc, off, False, False); + } + + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF(tmp_win->iconc.fore, tmp_win->iconc.back, Scr->IconFont); + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawString (dpy, tmp_win->icon_w, &Scr->IconFont, +#else + XDrawString (dpy, tmp_win->icon_w, +#endif + Scr->NormalGC, tmp_win->icon_x, tmp_win->icon_y, + tmp_win->icon_name, strlen(tmp_win->icon_name)); +} + +/* djhjr - 4/20/96 */ +void PaintTitle (tmp_win) +TwmWindow *tmp_win; +{ + /* made static - djhjr - 6/18/99 */ + static int en = 0, dots = 0; + + int bwidth = Scr->TBInfo.width + Scr->TBInfo.pad; + int left = (Scr->TBInfo.nleft) ? Scr->TBInfo.leftx + + (Scr->TBInfo.nleft * bwidth) - Scr->TBInfo.pad : + 0; + int right = (Scr->TBInfo.nright) ? + (Scr->TBInfo.nright * bwidth) - Scr->TBInfo.pad : + 0; + + /* djhjr - 3/29/98 */ + int i, j, slen = strlen(tmp_win->name); + char *a = NULL; + +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + if (!en) en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1); +#else + if (!en) en = XTextWidth(Scr->TitleBarFont.font, "n", 1); +#endif + + /* + * clip the title a couple of characters less than the width of + * the titlebar plus padding, and tack on ellipses - this is a + * little different than the icon manager's... + * + * djhjr - 3/29/98 + */ + if (Scr->NoPrettyTitles == FALSE) /* for rader - djhjr - 2/9/99 */ + { +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + i = MyFont_TextWidth(&Scr->TitleBarFont, tmp_win->name, slen); +#else + i = XTextWidth(Scr->TitleBarFont.font, tmp_win->name, slen); +#endif + +/* DUH! - djhjr - 6/18/99 + j = tmp_win->title_width - 2 * Scr->TBInfo.rightoff; +*/ +/* djhjr - 10/18/02 + if (!dots) dots = XTextWidth(Scr->TitleBarFont.font, "...", 3) + en; + j = tmp_win->title_width - Scr->TBInfo.titlex - Scr->TBInfo.rightoff - dots; +*/ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + if (!dots) dots = MyFont_TextWidth(&Scr->TitleBarFont, "...", 3); +#else + if (!dots) dots = XTextWidth(Scr->TitleBarFont.font, "...", 3); +#endif + j = tmp_win->title_width - Scr->TBInfo.titlex - Scr->TBInfo.rightoff - en; + +/* djhjr - 10/18/02 + * djhjr - 5/5/98 * + * was 'Scr->use3Dtitles' - djhjr - 8/11/98 * + if (Scr->TitleBevelWidth > 0) + j -= Scr->TitleBevelWidth; +*/ + /* reworked this stuff - djhjr - 10/18/02 */ + if (dots >= j) + slen = 0; + else if (i > j) + { + while (i >= 0) + { +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + if (MyFont_TextWidth(&Scr->TitleBarFont, +#else + if (XTextWidth(Scr->TitleBarFont.font, +#endif + tmp_win->name, i) + dots < j) + { + slen = i; + break; + } + + i--; + } + + a = (char *)malloc(slen + 4); + memcpy(a, tmp_win->name, slen); + strcpy(a + slen, "..."); + slen += 3; + } + } + + /* font was font.font->fid - djhjr - 9/14/03 */ + FBF(tmp_win->title.fore, tmp_win->title.back, Scr->TitleBarFont); + +/* djhjr - 10/18/02 */ +#if 0 + /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */ + if (Scr->TitleBevelWidth > 0) + { +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawString (dpy, tmp_win->title_w, &Scr->TitleBarFont, +#else + XDrawString (dpy, tmp_win->title_w, +#endif + Scr->NormalGC, +/* djhjr - 4/29/98 + Scr->TBInfo.titlex + en, Scr->TitleBarFont.y + 2, +*/ +/* djhjr - 5/5/98 + Scr->TBInfo.titlex + en, Scr->TitleBarFont.y + Scr->TitleBevelWidth + 1, +*/ + Scr->TBInfo.titlex + Scr->TitleBevelWidth + en, Scr->TitleBarFont.y, + + (a) ? a : tmp_win->name, slen); + } + else +#endif +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + MyFont_DrawString (dpy, tmp_win->title_w, &Scr->TitleBarFont, +#else + XDrawString (dpy, tmp_win->title_w, +#endif + Scr->NormalGC, Scr->TBInfo.titlex, Scr->TitleBarFont.y, + (a) ? a : tmp_win->name, slen); + + /* free the clipped title - djhjr - 3/29/98 */ + if (a) free(a); + + /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */ + if (Scr->TitleBevelWidth > 0) + { +/* + Draw3DBorder (tmp_win->title_w, Scr->TBInfo.titlex, 0, + tmp_win->title_width - Scr->TBInfo.titlex - Scr->TBInfo.rightoff, + Scr->TitleHeight, Scr->TitleBevelWidth, tmp_win->title, off, True, False); +*/ +/* djhjr - 3/12/97 + Draw3DBorder (tmp_win->title_w, Scr->TBInfo.rightoff, Scr->FramePadding, + tmp_win->title_width - 2 * Scr->TBInfo.rightoff, + Scr->TitleHeight - 2 * Scr->FramePadding, Scr->TitleBevelWidth, tmp_win->title, off, True, False); +*/ +/* djhjr - 10/17/02 + Draw3DBorder (tmp_win->title_w, Scr->TBInfo.leftx + left, + Scr->FramePadding, tmp_win->title_width - (left + right), + Scr->TitleHeight - 2 * Scr->FramePadding, Scr->TitleBevelWidth, tmp_win->title, off, False, False); +*/ + if (Scr->FramePadding + Scr->ButtonIndent > 0) + { + Draw3DBorder(tmp_win->title_w, 0, 0, + tmp_win->title_width, Scr->TitleHeight, + Scr->TitleBevelWidth, tmp_win->title, + off, False, False); + } + else + { + Draw3DBorder(tmp_win->title_w, left, 0, + tmp_win->title_width - (left + right), + Scr->TitleHeight, + Scr->TitleBevelWidth, tmp_win->title, + off, False, False); + } + } +} + +/* djhjr - 11/17/97 */ +/* collapsed the two functions PTB() and PTBH() - djhjr - 8/10/98 */ +/* djhjr - 10/30/02 */ +void PaintTitleButton(tmp_win, tbw, onoroff) +TwmWindow *tmp_win; +TBWindow *tbw; +int onoroff; /* 0 = no hilite 1 = hilite off 2 = hilite on */ +{ + Image *image; + TitleButton *tb; + /* djhjr - 5/23/98 8/10/98 */ + ColorPair cp; + + if (!tbw->window) return; + + tb = tbw->info; + + /* djhjr - 5/23/98 8/10/98 */ + if (Scr->ButtonColorIsFrame) + cp = (onoroff == 2) ? tmp_win->border : tmp_win->border_tile; + else + cp = tmp_win->title; + cp.fore = tmp_win->title.fore; + + image = GetImage(tb->name, tb->width, tb->height, + Scr->ButtonBevelWidth * 2, cp); + + XCopyArea(dpy, image->pixmap, tbw->window, Scr->NormalGC, + tb->srcx, tb->srcy, tb->width, tb->height, tb->dstx, tb->dsty); + + /* djhjr - 8/10/98 8/18/98 */ + /* was 'Scr->TitleBevelWidth' - djhjr - 8/11/98 */ + if (Scr->ButtonBevelWidth > 0) + Draw3DBorder(tbw->window, 0, 0, tb->width, tb->height, + Scr->ButtonBevelWidth, cp, off, False, False); +} + +/* djhjr - 4/19/96 */ +/* re-arranged - djhjr - 4/5/98 */ +void PaintTitleHighlight(tmp_win, onoroff) +TwmWindow *tmp_win; +Bool onoroff; +{ + /* djhjr - 4/3/98 */ + if (!tmp_win->titlehighlight) return; + + if (tmp_win->hilite_w) + { + if (onoroff == on) + XMapWindow (dpy, tmp_win->hilite_w); + else + XUnmapWindow (dpy, tmp_win->hilite_w); + } + else if (Scr->hiliteName && tmp_win->title_height != 0) + DrawTitleHighlight(tmp_win, onoroff); /* djhjr - 10/25/02 */ +} + +/* djhjr - 4/2/98 10/18/02 */ +int ComputeHighlightWindowWidth(tmp_win) +TwmWindow *tmp_win; +{ +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT + int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1); +#else + int en = XTextWidth(Scr->TitleBarFont.font, "n", 1); +#endif + + return (tmp_win->rightx - tmp_win->highlightx - en); +} + diff --git a/util.h b/util.h new file mode 100644 index 0000000..21a1a50 --- /dev/null +++ b/util.h @@ -0,0 +1,108 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + + +/*********************************************************************** + * + * $XConsortium: util.h,v 1.10 89/12/10 17:47:04 jim Exp $ + * + * utility routines header file + * + * 28-Oct-87 Thomas E. LaStrange File created + * + ***********************************************************************/ + +#ifndef _UTIL_ +#define _UTIL_ + +typedef struct _Image { + Pixmap pixmap; + Pixmap mask; + int width; + int height; + struct _Image *next; +} Image; + +extern void Zoom(); +extern void MoveOutline(); +extern Pixmap GetBitmap(), FindBitmap(); +#ifndef NO_XPM_SUPPORT +extern Image *FindImage(); +#endif +extern void GetUnknownIcon(); +extern char *ExpandFilename(); +extern void GetColor(); +extern Cursor NoCursor(); + +extern Image *GetImage (); +extern void Draw3DBorder(); +extern void GetShadeColors(); +extern void PaintBorders(); +extern void PaintIcon(); +extern void PaintTitle(); +extern void PaintTitleButton(); +extern void InsertRGBColormap(); +extern void RemoveRGBColormap(); +extern void SetFocus(); +extern void LocateStandardColormaps(); +extern void GetFont(); +/* djhjr - 9/14/03 */ +#ifndef NO_I18N_SUPPORT +extern int MyFont_TextWidth(); +extern void MyFont_DrawImageString(); +extern void MyFont_DrawString(); +extern void MyFont_ChangeGC(); +extern Status I18N_FetchName(); +extern Status I18N_GetIconName(); +#endif + +/* djhjr - 1/13/98 */ +void setBorderGC(); +#ifdef USE_ORIGINAL_CORNERS +void Draw3DCorner(); +#else +GC setBevelGC(); +void Draw3DBevel(); +#endif + +/* djhjr - 4/25/96 */ +void PaintTitleHighlight(); + +/* djhjr - 4/2/98 */ +int ComputeHighlightWindowWidth(); + +/* djhjr - 5/17/98 */ +extern Image *SetPixmapsPixmap(); + +/* djhjr - 5/23/98 */ +#ifndef NO_XPM_SUPPORT +extern int SetPixmapsBackground(); +#endif + +extern int HotX, HotY; + +#endif /* _UTIL_ */ diff --git a/version.c b/version.c new file mode 100644 index 0000000..0f62085 --- /dev/null +++ b/version.c @@ -0,0 +1,71 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + +/* djhjr - 4/23/96 +char *Version = "Virtual Desktop TWM (VTWM) - R5 Release (5.3)"; +*/ +/* djhjr - 9/10/96 +char *Version = "Virtual Desktop TWM (VTWM) - R5 Release 5.4"; +*/ +/* djhjr - 3/12/97 +char *Version = "Virtual Desktop TWM (VTWM) - R5 Release 5.4.1"; +*/ +/* djhjr - 11/17/97 +char *Version = "Virtual Desktop TWM (VTWM) - R5 Release 5.4.2"; +*/ +/* djhjr - 1/1/98 +char *Version = "Virtual Desktop TWM (VTWM) - R5 Release 5.4.3"; +*/ +/* djhjr - 2/5/98 +char *Version = "Virtual Desktop TWM (VTWM) - X11R4-6 Release 5.4.4"; +*/ +/* djhjr - 3/14/98 +char *Version = "Virtual Desktop TWM (VTWM) - X11R4-6 Release 5.4.4a"; +*/ +/* djhjr - 3/20/98 +char *Version = "Virtual Desktop TWM (VTWM) - X11R4-6 Release 5.4.4b"; +*/ +/* djhjr - 8/11/98 +char *Version = "Virtual Desktop TWM (VTWM) - X11R4-6 Release 5.4.4c"; +*/ +/* djhjr - 9/27/98 +char *Version = "Virtual Desktop TWM (VTWM) - X11R4-6 Release 5.4.5"; +*/ +/* djhjr - 1/30/99 +char *Version = "Virtual Desktop TWM (VTWM) - X11R4-6 Release 5.4.5a"; +*/ +/* djhjr - 11/8/01 +char *Version = "Virtual Desktop TWM (VTWM) - X11R4-6 Release 5.4.6"; +*/ +/* djhjr - 10/1/04 +char *Version = "Virtual Desktop TWM (VTWM) - X11R4-6 Release 5.4.6a"; +*/ +/* djhjr - 10/2/04 +char *Version = "Virtual Desktop TWM (VTWM) - X11R4-6 Release 5.4.6b"; +*/ +char *Version = "Virtual Desktop TWM (VTWM) - X11R4-6 Release 5.4.7"; + diff --git a/version.h b/version.h new file mode 100644 index 0000000..012bad9 --- /dev/null +++ b/version.h @@ -0,0 +1,46 @@ +/*****************************************************************************/ +/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ +/** Salt Lake City, Utah **/ +/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ +/** Cambridge, Massachusetts **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ +/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ +/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ +/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ +/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ + +/********************************************************************** + * + * $XConsortium: version.h,v 1.7 89/10/27 14:01:42 jim Exp $ + * + * TWM version externs + * + * 8-Apr-88 Tom LaStrange Initial Version. + * + **********************************************************************/ + +#ifndef _VERSION_ +#define _VERSION_ + +extern char *Version; + +/* djhjr - 9/19/96 */ +extern char *lastmake[]; + +#endif /* _VERSION_ */ -- 2.30.2