diff --git a/ChangeLog b/ChangeLog index 49de670..96f83fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,25 +6,25 @@ basis. Dates are included, as are nicknames/names/initials for the persons making the changes. -Thu Sep 3 17:27:35 CDT 1998 Michael Jennings +Thu Sep 3 17:27:35 CDT 1998 Michael Jennings Removed RELNOTES.Eterm and split it into README and ChangeLog. I also fixed options.c so that keysym definitions are at least accepted. Now I'll have to find a tn3270 to test with. :-) ------------------------------------------------------------------------------- -Thu Sep 3 17:57:38 CDT 1998 Michael Jennings +Thu Sep 3 17:57:38 CDT 1998 Michael Jennings Added the trans theme and fixed doc/Makefile.in to remove Esetroot on "make distclean" ------------------------------------------------------------------------------- -Thu Sep 3 18:36:10 CDT 1998 Michael Jennings +Thu Sep 3 18:36:10 CDT 1998 Michael Jennings Added the --shade option to replace the DARKEN_TRANSPARENCY #define. ------------------------------------------------------------------------------- -Thu Sep 3 20:28:22 CDT 1998 Michael Jennings +Thu Sep 3 20:28:22 CDT 1998 Michael Jennings Fixed problems compiling with MENUBAR_MAX == 0 and without pixmap support and/or transparency support. @@ -35,7 +35,7 @@ Thu Sep 3 20:28:22 CDT 1998 Michael Jennings script to automatically disable menubar support. ------------------------------------------------------------------------------- -Fri Sep 4 11:28:30 CDT 1998 Michael Jennings +Fri Sep 4 11:28:30 CDT 1998 Michael Jennings Added in the Eterm man page Shaleh fixed up for us. Thanks Shaleh! @@ -43,7 +43,7 @@ Fri Sep 4 11:28:30 CDT 1998 Michael Jennings Also updated the doc/FAQ.html file with the latest FAQ from the web. ------------------------------------------------------------------------------- -Fri Sep 4 11:36:33 CDT 1998 Michael Jennings +Fri Sep 4 11:36:33 CDT 1998 Michael Jennings Ripped the RELNOTES.Eterm stuff out of ChangeLog and put it in ReleaseNotes. I decided not to use the name RELNOTES because it does @@ -51,45 +51,45 @@ Fri Sep 4 11:36:33 CDT 1998 Michael Jennings ChangeLog will be the detail and RELNOTES will be the summary. ------------------------------------------------------------------------------- -Fri Sep 4 13:24:49 CDT 1998 Michael Jennings +Fri Sep 4 13:24:49 CDT 1998 Michael Jennings Fixed a bug mandrake pointed out where supplying a pixmap would kill a transparent Eterm. -------------------------------------------------------------------------------- -Fri Sep 4 13:47:32 CDT 1998 Michael Jennings +Fri Sep 4 13:47:32 CDT 1998 Michael Jennings Fixed the bug pointed out by technoir that made transparent Eterms flicker when there were two on the desktop at the same time and one was moving. ------------------------------------------------------------------------------- -Fri Sep 4 15:42:55 CDT 1998 Michael Jennings +Fri Sep 4 15:42:55 CDT 1998 Michael Jennings Fixed scrollbar_floating with transparency so that the root image shows through underneath the scrollbar. The effect is really sweet. :) -------------------------------------------------------------------------------- -Fri Sep 4 16:22:29 CDT 1998 Michael Jennings +Fri Sep 4 16:22:29 CDT 1998 Michael Jennings Fixed scrollbar_floating without transparency so that it shows the background color instead of white. ------------------------------------------------------------------------------- -Fri Sep 4 18:48:08 CDT 1998 Michael Jennings +Fri Sep 4 18:48:08 CDT 1998 Michael Jennings Added the --tint option. Specify a shade of tinting for a pseudo- transparent Eterm. It implies --shade. Choices are red, green, blue, purple, orange, or yellow. ------------------------------------------------------------------------------- -Fri Sep 4 19:31:18 CDT 1998 Michael Jennings +Fri Sep 4 19:31:18 CDT 1998 Michael Jennings Fixed a stupid mistake in doing the tinting. Also enabled "yes" and "no" as valid boolean values. ------------------------------------------------------------------------------- -Fri Sep 4 21:34:09 CDT 1998 Michael Jennings +Fri Sep 4 21:34:09 CDT 1998 Michael Jennings Fixed the color names. Thanks to technoir for assistance with this. Choices are now red, green, blue, cyan, magenta, yellow. @@ -115,14 +115,14 @@ Sat Sep 5 14:28:18 1998 sdh Why does menubar.c use the global Attributes exported by main.c? ------------------------------------------------------------------------------- -Tue Sep 8 13:50:10 CDT 1998 Michael Jennings +Tue Sep 8 13:50:10 CDT 1998 Michael Jennings Updated the menubar files to take advantage of some of the newer background images in the collection. Also removed the pixmap menu from the "trans" theme since it's all ignored anyway. ------------------------------------------------------------------------------- -Tue Sep 8 15:14:00 CDT 1998 Michael Jennings +Tue Sep 8 15:14:00 CDT 1998 Michael Jennings Cleaned up the changes made by "sdh" (whoever that is). :-) If the unfocused color is not defined, it will revert to the scrollbar color, @@ -139,14 +139,14 @@ Tue Sep 8 15:14:00 CDT 1998 Michael Jennings please change the other themes too. ------------------------------------------------------------------------------- -Tue Sep 8 17:16:34 CDT 1998 Michael Jennings +Tue Sep 8 17:16:34 CDT 1998 Michael Jennings Fixed transparency so that it works on any desktop, not just the root. Only works with E, so non-E users are S.O.L. (Sorry, that's life.) Thanks to raster for helping me with this. :-) ------------------------------------------------------------------------------- -Tue Sep 8 20:52:18 CDT 1998 Michael Jennings +Tue Sep 8 20:52:18 CDT 1998 Michael Jennings Added a new feature. This was requested by Nick Vargish . Basically, the new option --watch-bg (or config @@ -161,36 +161,36 @@ Tue Sep 8 20:52:18 CDT 1998 Michael Jennings interest, I will internalize more of it. ------------------------------------------------------------------------------- -Sun Sep 13 13:18:31 CDT 1998 Michael Jennings +Sun Sep 13 13:18:31 CDT 1998 Michael Jennings Fixed the scrollbar_floating option with transparency (again). sdh's changes on 9/5 screwed it up. The pixmap now shows through once again. And there was much rejoicing. ------------------------------------------------------------------------------- -Sun Sep 13 16:08:06 CDT 1998 Michael Jennings +Sun Sep 13 16:08:06 CDT 1998 Michael Jennings Added .cvsignore files. ------------------------------------------------------------------------------- -Mon Sep 14 10:11:41 CDT 1998 Michael Jennings +Mon Sep 14 10:11:41 CDT 1998 Michael Jennings Fixed a bug pointed out by Hans Engren which kept Eterm and Esetroot from working under certain conditions. ------------------------------------------------------------------------------- -Mon Sep 14 11:38:06 CDT 1998 Michael Jennings +Mon Sep 14 11:38:06 CDT 1998 Michael Jennings Final documentation cleanups before the release of 0.8.6. ------------------------------------------------------------------------------- -Mon Sep 14 12:04:43 CDT 1998 Michael Jennings +Mon Sep 14 12:04:43 CDT 1998 Michael Jennings Final compilation cleanups before release of 0.8.6. With this commit, CVS will contain the release version of 0.8.6. ------------------------------------------------------------------------------- -Mon Sep 14 12:58:32 CDT 1998 Michael Jennings +Mon Sep 14 12:58:32 CDT 1998 Michael Jennings Installed 0.8.7 into CVS. This release has some major changes in it. For one, Eterm now uses automake and libtool. The old libmej is now @@ -201,30 +201,30 @@ Mon Sep 14 12:58:32 CDT 1998 Michael Jennings of memory per Eterm. ------------------------------------------------------------------------------- -Tue Sep 15 13:10:20 CDT 1998 Michael Jennings +Tue Sep 15 13:10:20 CDT 1998 Michael Jennings Fixed a bug compiling on Linux. (Damn Linux having dprintf!) ;-P ------------------------------------------------------------------------------- -Tue Sep 15 13:23:00 CDT 1998 Michael Jennings +Tue Sep 15 13:23:00 CDT 1998 Michael Jennings Fixed another bug on Linux, this time with linking Esetroot. ------------------------------------------------------------------------------- -Tue Sep 15 14:10:05 CDT 1998 Michael Jennings +Tue Sep 15 14:10:05 CDT 1998 Michael Jennings Removed MIN_ANCHOR_SIZE and added -a (--min-anchor-size) option. It is 0 by default so ppl won't complain about the scroll-up "bug". ------------------------------------------------------------------------------- -Tue Sep 15 15:03:57 CDT 1998 Michael Jennings +Tue Sep 15 15:03:57 CDT 1998 Michael Jennings Changed the pixmap setting code in Esetroot so it will (hopefully) work better. Geez, if everyone would just use Enlightenment, it would save me so much grief.... ;-) ------------------------------------------------------------------------------- -Tue Sep 15 16:00:26 CDT 1998 Michael Jennings +Tue Sep 15 16:00:26 CDT 1998 Michael Jennings Fixed the scaling problem in Esetroot pointed out by technoir thanks to some code swiped from Enlightenment. I also nuked the code that @@ -232,14 +232,14 @@ Tue Sep 15 16:00:26 CDT 1998 Michael Jennings lame code.) =P ------------------------------------------------------------------------------- -Tue Sep 15 17:25:53 CDT 1998 Michael Jennings +Tue Sep 15 17:25:53 CDT 1998 Michael Jennings Choosing a pixmap in a transparent Eterm now works. I also renamed StrSep() to strsep() and changed configure.in to check for strsep(). That allowed me to remove some really annoying #ifdef's in command.c. ------------------------------------------------------------------------------- -Tue Sep 15 17:59:24 CDT 1998 Michael Jennings +Tue Sep 15 17:59:24 CDT 1998 Michael Jennings Added initial support for an escape code sequence set to mess with the various transparency options. It doesn't work yet, so don't bother @@ -247,42 +247,42 @@ Tue Sep 15 17:59:24 CDT 1998 Michael Jennings I'm going home anyway. :-) ------------------------------------------------------------------------------- -Wed Sep 16 11:42:16 CDT 1998 Michael Jennings +Wed Sep 16 11:42:16 CDT 1998 Michael Jennings Initial work on a patch for CygWin32 support. Also updated autogen.sh to create libtool stuff. ------------------------------------------------------------------------------- -Wed Sep 16 15:25:32 CDT 1998 Michael Jennings +Wed Sep 16 15:25:32 CDT 1998 Michael Jennings Fixed some misc. problems with the new escape sequences. Toggling transparency on and off now works (more or less). At least stuff won't crash. :-) Still some kinks to iron out, as always. ------------------------------------------------------------------------------- -Wed Sep 16 17:21:52 CDT 1998 Michael Jennings +Wed Sep 16 17:21:52 CDT 1998 Michael Jennings Fixed the escape sequence for Pixmap -> None (again). Also made the transparency toggle work for not having a pixmap. ------------------------------------------------------------------------------- -Wed Sep 16 18:20:47 CDT 1998 Michael Jennings +Wed Sep 16 18:20:47 CDT 1998 Michael Jennings Updated the default themes to include the Trans menu. ------------------------------------------------------------------------------- -Thu Sep 17 13:05:30 CDT 1998 Michael Jennings +Thu Sep 17 13:05:30 CDT 1998 Michael Jennings Hack for newer Linux versions in which the real uid must be nonzero to open the display. ------------------------------------------------------------------------------- -Thu Sep 17 13:50:50 CDT 1998 Michael Jennings +Thu Sep 17 13:50:50 CDT 1998 Michael Jennings Moved the #define for the Linux fix into config.h ------------------------------------------------------------------------------- -Thu Sep 17 16:59:17 CDT 1998 Michael Jennings +Thu Sep 17 16:59:17 CDT 1998 Michael Jennings This version has a working CygWin32 port! :-) Some minor hacking may still be required. @@ -290,24 +290,24 @@ Thu Sep 17 16:59:17 CDT 1998 Michael Jennings Also included a test for something with transparency. ------------------------------------------------------------------------------- -Thu Sep 17 17:29:39 CDT 1998 Michael Jennings +Thu Sep 17 17:29:39 CDT 1998 Michael Jennings Changed code to use setres*id() functions if they are there (Linux and HP-UX only AFAIK). This is a vast security improvement for Linux. ------------------------------------------------------------------------------- -Thu Sep 17 17:49:19 CDT 1998 Michael Jennings +Thu Sep 17 17:49:19 CDT 1998 Michael Jennings Hopefully fixed privileges() for systems without setres*id() or saved uids. ------------------------------------------------------------------------------- -Thu Sep 17 17:58:17 CDT 1998 Michael Jennings +Thu Sep 17 17:58:17 CDT 1998 Michael Jennings More .cvsignore entries. ------------------------------------------------------------------------------- -Thu Sep 17 19:03:22 CDT 1998 Michael Jennings +Thu Sep 17 19:03:22 CDT 1998 Michael Jennings Changed the --watch-bg option to --watch-pixmap, which will hopefully make it less tempting for people to think it has something to do with @@ -318,39 +318,39 @@ Thu Sep 17 19:03:22 CDT 1998 Michael Jennings cause flicker like it used to. ------------------------------------------------------------------------------- -Thu Sep 17 19:36:56 CDT 1998 Michael Jennings +Thu Sep 17 19:36:56 CDT 1998 Michael Jennings Some config file parser cleanups and additions to the trans theme. ------------------------------------------------------------------------------- -Thu Sep 17 20:03:57 CDT 1998 Michael Jennings +Thu Sep 17 20:03:57 CDT 1998 Michael Jennings Makefile and theme cleanups. ------------------------------------------------------------------------------- -Thu Sep 17 20:45:03 CDT 1998 Michael Jennings +Thu Sep 17 20:45:03 CDT 1998 Michael Jennings Fixed a major bug which caused Eterm to seg fault in trans theme. ------------------------------------------------------------------------------- -Thu Sep 17 20:56:33 CDT 1998 Michael Jennings +Thu Sep 17 20:56:33 CDT 1998 Michael Jennings Fixed another seg fault bug, this time with changing the pixmap via escape sequence. Doh! ------------------------------------------------------------------------------- -Thu Sep 17 21:03:34 CDT 1998 Michael Jennings +Thu Sep 17 21:03:34 CDT 1998 Michael Jennings Changed the scrollbar_floating attribute back on for the trans theme. Geez, is there no end to the stuff I've screwed up today?? =P ------------------------------------------------------------------------------- -Fri Sep 18 09:33:30 CDT 1998 Michael Jennings +Fri Sep 18 09:33:30 CDT 1998 Michael Jennings Added some checks to autogen.sh ------------------------------------------------------------------------------- -Fri Sep 18 11:18:59 CDT 1998 Michael Jennings +Fri Sep 18 11:18:59 CDT 1998 Michael Jennings Put in the #define IMLIB_TRANS, which will make Eterm use Imlib to do the transparency stuff. There's a problem with it, though, either in @@ -358,7 +358,7 @@ Fri Sep 18 11:18:59 CDT 1998 Michael Jennings obvious reasons, it's off by default. ------------------------------------------------------------------------------- -Fri Sep 18 16:39:15 CDT 1998 Michael Jennings +Fri Sep 18 16:39:15 CDT 1998 Michael Jennings As expected, raster's imlib fix corrected the problem. Imlib transparency rendering now works as expected. It is still off by @@ -372,7 +372,7 @@ Fri Sep 18 16:39:15 CDT 1998 Michael Jennings standardization and nothing more, I'll do it. ------------------------------------------------------------------------------- -Mon Sep 21 15:45:17 CDT 1998 Michael Jennings +Mon Sep 21 15:45:17 CDT 1998 Michael Jennings Fixed the aforementioned memory leak as well as some others. Dangling pointers were cut in half. :) @@ -384,17 +384,17 @@ Mon Sep 21 15:45:17 CDT 1998 Michael Jennings pseudo-transparency. ------------------------------------------------------------------------------- -Mon Sep 21 16:10:46 CDT 1998 Michael Jennings +Mon Sep 21 16:10:46 CDT 1998 Michael Jennings Fixed the transparency toggle. ------------------------------------------------------------------------------- -Mon Sep 21 17:05:31 CDT 1998 Michael Jennings +Mon Sep 21 17:05:31 CDT 1998 Michael Jennings Fixed bug in Imlib transparency code. ------------------------------------------------------------------------------- -Mon Sep 21 19:46:44 CDT 1998 Michael Jennings +Mon Sep 21 19:46:44 CDT 1998 Michael Jennings Looks like Imlib-based transparency is working now. It only reads the desktop image once. After that, it uses the same desktop pixmap @@ -402,14 +402,14 @@ Mon Sep 21 19:46:44 CDT 1998 Michael Jennings run it's much faster. ------------------------------------------------------------------------------- -Mon Sep 21 20:53:44 CDT 1998 Michael Jennings +Mon Sep 21 20:53:44 CDT 1998 Michael Jennings Added --shade-pct. When Imlib-based transparency is enabled, you can specify a percentage by which to shade the background (0 being no shading, 100 being all black, not to mention rather pointless). ------------------------------------------------------------------------------- -Tue Sep 22 10:41:32 CDT 1998 Michael Jennings +Tue Sep 22 10:41:32 CDT 1998 Michael Jennings With Imlib-based transparency, Eterm now takes --tint as a numerical option. You specify a 24-bit RGB mask for colored tinting, such as @@ -417,7 +417,7 @@ Tue Sep 22 10:41:32 CDT 1998 Michael Jennings blue tint. ------------------------------------------------------------------------------- -Tue Sep 22 14:48:03 CDT 1998 Michael Jennings +Tue Sep 22 14:48:03 CDT 1998 Michael Jennings Fixed a bug in non-Imlib-based transparency. I also made preparations for letting non-Imlib-based transparency do shading percentages and @@ -431,31 +431,31 @@ Tue Sep 22 14:48:03 CDT 1998 Michael Jennings now. ------------------------------------------------------------------------------- -Tue Sep 22 18:28:49 CDT 1998 Michael Jennings +Tue Sep 22 18:28:49 CDT 1998 Michael Jennings Fixed the menubar code so that the menus aren't clipped by the window or screen edge. There's still one small problem, but I'll look at that later. :) ------------------------------------------------------------------------------- -Tue Sep 22 21:20:16 CDT 1998 Michael Jennings +Tue Sep 22 21:20:16 CDT 1998 Michael Jennings If root_pixmap() returns None, transparency gets turned off instead of rendering on a null pixmap. ------------------------------------------------------------------------------- -Wed Sep 23 10:26:01 CDT 1998 Michael Jennings +Wed Sep 23 10:26:01 CDT 1998 Michael Jennings Fixed that one last menubar bug. ------------------------------------------------------------------------------- -Wed Sep 23 11:46:44 CDT 1998 Michael Jennings +Wed Sep 23 11:46:44 CDT 1998 Michael Jennings Fixed a segfault in Esetroot. Also fixed --watch-desktop to work again (just for you, Nat). ;-) ------------------------------------------------------------------------------- -Wed Sep 23 19:07:11 CDT 1998 Michael Jennings +Wed Sep 23 19:07:11 CDT 1998 Michael Jennings Some bug fixes pertaining to root_pixmap() failing, transparency and background pixmaps coinciding, etc. @@ -465,7 +465,7 @@ Wed Sep 23 19:07:11 CDT 1998 Michael Jennings the shell behavior, but I prefer it. :) ------------------------------------------------------------------------------- -Thu Sep 24 17:14:29 CDT 1998 Michael Jennings +Thu Sep 24 17:14:29 CDT 1998 Michael Jennings Fixed a bug with tiling pixmaps in transparency code. (Didn't do it the way raster wanted it, but it works for now. I'll make it better @@ -478,12 +478,12 @@ Thu Sep 24 17:14:29 CDT 1998 Michael Jennings The latter two are thanks to Casey Zacek ------------------------------------------------------------------------------- -Fri Sep 25 22:32:30 CDT 1998 Michael Jennings +Fri Sep 25 22:32:30 CDT 1998 Michael Jennings Fixed a bug in Esetroot.c and the CUTCHARS default in src/feature.h.in ------------------------------------------------------------------------------- -Fri Sep 25 22:35:44 CDT 1998 Michael Jennings +Fri Sep 25 22:35:44 CDT 1998 Michael Jennings Missed another typo in Esetroot.c @@ -493,19 +493,19 @@ Sat Sep 26 21:11:48 EDT 1998 mandrake cleaned up a lot of stuff so it compiles a little cleaner. ------------------------------------------------------------------------------- -Tue Sep 29 14:04:39 CDT 1998 Michael Jennings +Tue Sep 29 14:04:39 CDT 1998 Michael Jennings Fixed utmp.c for OpenBSD thanks to Jason Ish ------------------------------------------------------------------------------- -Tue Sep 29 17:14:11 CDT 1998 Michael Jennings +Tue Sep 29 17:14:11 CDT 1998 Michael Jennings Removed the variables mandrake commented out, except for the one that was still needed. I uncommented that one and put it in #ifdef's to fix the compiler warnings. ------------------------------------------------------------------------------- -Thu Oct 8 15:24:10 CDT 1998 Michael Jennings +Thu Oct 8 15:24:10 CDT 1998 Michael Jennings Some transparency speed-ups (I hope). Still trying to figure out why I'm not getting ReparentNotify events. =P Also fixed the bug mandrake @@ -516,12 +516,12 @@ Thu Oct 8 15:24:10 CDT 1998 Michael Jennings number checker. ------------------------------------------------------------------------------- -Thu Oct 8 15:29:01 CDT 1998 Michael Jennings +Thu Oct 8 15:29:01 CDT 1998 Michael Jennings Correct order: Compile FIRST, commit SECOND. Doh!! =P ------------------------------------------------------------------------------- -Fri Oct 9 12:06:10 CDT 1998 Michael Jennings +Fri Oct 9 12:06:10 CDT 1998 Michael Jennings Added --with-debugging[=num] to support debugging levels up through 5. @@ -530,18 +530,18 @@ Fri Oct 9 12:06:10 CDT 1998 Michael Jennings pstack (on Solaris), gdb, dbx. ------------------------------------------------------------------------------- -Fri Oct 9 12:18:32 CDT 1998 Michael Jennings +Fri Oct 9 12:18:32 CDT 1998 Michael Jennings Oops, forgot to add libmej/snprintf.c to the repository. =P ------------------------------------------------------------------------------- -Sun Oct 11 17:35:18 CDT 1998 Michael Jennings +Sun Oct 11 17:35:18 CDT 1998 Michael Jennings Fixed autogen.sh so that VERSION was defined again. Apparently running autoheader before other stuff in autogen.sh is a Bad Thing. ------------------------------------------------------------------------------- -Tue Oct 13 17:38:30 CDT 1998 Michael Jennings +Tue Oct 13 17:38:30 CDT 1998 Michael Jennings If the desktop pixmap goes away (which happens if you're on another desktop for awhile), we'll just use the old one until it comes back. @@ -549,13 +549,13 @@ Tue Oct 13 17:38:30 CDT 1998 Michael Jennings Also added Id strings to all C files. ------------------------------------------------------------------------------- -Tue Oct 13 18:18:03 CDT 1998 Michael Jennings +Tue Oct 13 18:18:03 CDT 1998 Michael Jennings Added Id strings to the Makefile.am files, src/feature.h.in, configure.in, and autogen.sh. Also added an entry to keep CVS quiet. ------------------------------------------------------------------------------- -Wed Oct 14 12:55:13 CDT 1998 Michael Jennings +Wed Oct 14 12:55:13 CDT 1998 Michael Jennings Fixed the bug with dragging a transparent Eterm across E's desktop dragbar. It reparents to the root window for a bit, but once you drop @@ -564,23 +564,23 @@ Wed Oct 14 12:55:13 CDT 1998 Michael Jennings the -W (--watch-desktop) option. ------------------------------------------------------------------------------- -Wed Oct 14 13:02:37 CDT 1998 Michael Jennings +Wed Oct 14 13:02:37 CDT 1998 Michael Jennings Nuked some leftover code from testing. (oops) ------------------------------------------------------------------------------- -Wed Oct 14 14:49:01 CDT 1998 Michael Jennings +Wed Oct 14 14:49:01 CDT 1998 Michael Jennings Added some debugging code to Esetroot.c and added the -x switch to turn on debugging. Hopefully this will help me track down the DISPLAY bug. ------------------------------------------------------------------------------- -Wed Oct 14 14:54:46 CDT 1998 Michael Jennings +Wed Oct 14 14:54:46 CDT 1998 Michael Jennings Blah. Forgot to "if (debug)" out a couple lines. =P ------------------------------------------------------------------------------- -Mon Oct 19 15:33:48 CDT 1998 Michael Jennings +Mon Oct 19 15:33:48 CDT 1998 Michael Jennings Fixed transparency stuff so it wouldn't take up mondo CPU time. Since we're getting events for other windows now, we need to make sure we @@ -589,7 +589,7 @@ Mon Oct 19 15:33:48 CDT 1998 Michael Jennings Also fixed scrollbar coloring in transparent mode. ------------------------------------------------------------------------------- -Mon Oct 19 17:03:47 CDT 1998 Michael Jennings +Mon Oct 19 17:03:47 CDT 1998 Michael Jennings New features courtesy a patch from James Antill as described here: @@ -602,12 +602,12 @@ Mon Oct 19 17:03:47 CDT 1998 Michael Jennings Replaced "strncasecmp(buff, "string ", num)" with macro. ------------------------------------------------------------------------------- -Wed Oct 21 11:11:04 CDT 1998 Michael Jennings +Wed Oct 21 11:11:04 CDT 1998 Michael Jennings Fixed a bug with -W and -x together. ------------------------------------------------------------------------------- -Wed Oct 21 12:26:53 CDT 1998 Michael Jennings +Wed Oct 21 12:26:53 CDT 1998 Michael Jennings Final documentation cleanups for 0.8.7 release tomorrow. Barring bug fixes in the next 24 hours or so, this is 0.8.7 as it will be released @@ -619,13 +619,13 @@ Thu Oct 22 23:38:47 PDT 1998 Manish Singh * strings.c, strings.h: make everything consistent ------------------------------------------------------------------------------- -Mon Oct 26 22:26:47 CST 1998 Michael Jennings +Mon Oct 26 22:26:47 CST 1998 Michael Jennings Major changes to the man page. Hopefully people who actually bother to read the man page will find it easier to mess with the MAIN file. ------------------------------------------------------------------------------- -Mon Nov 2 13:24:21 CST 1998 Michael Jennings +Mon Nov 2 13:24:21 CST 1998 Michael Jennings Lots of changes here. This is the first commit of 0.8.8. The new features are: @@ -659,20 +659,20 @@ Mon Nov 2 13:24:21 CST 1998 Michael Jennings compiler (for those who have pgcc but want to use gcc, etc.). ------------------------------------------------------------------------------- -Mon Nov 2 16:11:37 CST 1998 Michael Jennings +Mon Nov 2 16:11:37 CST 1998 Michael Jennings Feh. Got rid of the warning in command.c. Chalk that one up to laziness on my part. =P ------------------------------------------------------------------------------- -Tue Nov 3 19:56:15 CST 1998 Michael Jennings +Tue Nov 3 19:56:15 CST 1998 Michael Jennings Added an optional boolean parameter to ESC ] 6 ; 0 escape sequence. Also added code to clear the shading/tinting when loading a new pixmap. This will be an option soon, but not tonight. ------------------------------------------------------------------------------- -Thu Nov 5 19:17:58 CST 1998 Michael Jennings +Thu Nov 5 19:17:58 CST 1998 Michael Jennings Added support for the old color strings to the escape sequence handler for tinting. They won't work on the command line, though. @@ -683,17 +683,17 @@ Thu Nov 5 19:17:58 CST 1998 Michael Jennings tracing on abnormal termination. ------------------------------------------------------------------------------- -Fri Nov 6 09:26:38 CST 1998 Michael Jennings +Fri Nov 6 09:26:38 CST 1998 Michael Jennings Shading and tinting were broken for 2 days, and nobody told me. Feh. ------------------------------------------------------------------------------- -Mon Nov 9 15:38:11 CST 1998 Michael Jennings +Mon Nov 9 15:38:11 CST 1998 Michael Jennings No, I said *don't* exit on X errors. And I meant it. Really. ------------------------------------------------------------------------------- -Mon Nov 9 20:00:08 CST 1998 Michael Jennings +Mon Nov 9 20:00:08 CST 1998 Michael Jennings Added src/Eterm.xpm as the default Eterm icon pixmap. @@ -704,7 +704,7 @@ Mon Nov 9 20:00:08 CST 1998 Michael Jennings Note that -I used to be --print-pipe. Not any more. ------------------------------------------------------------------------------- -Tue Nov 10 11:47:42 CST 1998 Michael Jennings +Tue Nov 10 11:47:42 CST 1998 Michael Jennings Fixed a bug when no background image was specified. Dunno how on earth that happened.... @@ -724,7 +724,7 @@ Tue Nov 10 11:47:42 CST 1998 Michael Jennings to you to write. You can thank me later. >:) ------------------------------------------------------------------------------- -Tue Nov 10 20:11:54 CST 1998 Michael Jennings +Tue Nov 10 20:11:54 CST 1998 Michael Jennings Now the hosts in the chooser theme change the title bar instead of the menubar title, thanks to a new extended menubar function called @@ -735,7 +735,7 @@ Tue Nov 10 20:11:54 CST 1998 Michael Jennings thanks to Sung-Hyun Nam . ------------------------------------------------------------------------------- -Wed Nov 11 12:18:00 CST 1998 Michael Jennings +Wed Nov 11 12:18:00 CST 1998 Michael Jennings Wheee. Minor bug fix. Also redid the cvs_ident string declarations to make egcs happy. =P @@ -751,28 +751,28 @@ Thu Nov 12 03:10:50 EST 1998 Gerald Britton Esetroot.c: Fixed an X server memory leak. ------------------------------------------------------------------------------- -Thu Nov 12 08:54:58 CST 1998 Michael Jennings +Thu Nov 12 08:54:58 CST 1998 Michael Jennings Reverted Gerald's change. Been there, done that. It kills E. Sorry, but if the X server doesn't work right, that's not my problem. I'm not going to kill E over it. Tough break. ------------------------------------------------------------------------------- -Mon Nov 16 19:31:29 CST 1998 Michael Jennings +Mon Nov 16 19:31:29 CST 1998 Michael Jennings Finally got around to doing that icon window thing to make mandrake and ICCCM (the next-to-worst acronym in history, second only to i18n) happy. Are we there yet? ------------------------------------------------------------------------------- -Tue Nov 17 11:17:57 CST 1998 Michael Jennings +Tue Nov 17 11:17:57 CST 1998 Michael Jennings Fixes for Digital UNIX from . These were all "Stupid KainX" bugs that I didn't catch because GNU's cpp is more forgiving than most vendors' cpp's. ------------------------------------------------------------------------------- -Tue Nov 24 13:39:34 CST 1998 Michael Jennings +Tue Nov 24 13:39:34 CST 1998 Michael Jennings This is the Correct (tm) fix to the memory leak pointed out by Gerald. He and I had a pow-wow of sorts via e-mail with Nat and @@ -795,21 +795,21 @@ Tue Nov 24 13:39:34 CST 1998 Michael Jennings program set/change ESETROOT_PMAP_ID. ------------------------------------------------------------------------------- -Tue Nov 24 16:26:22 CST 1998 Michael Jennings +Tue Nov 24 16:26:22 CST 1998 Michael Jennings Added -center (-c) option to Esetroot for centering the pixmap. Most of these changes are from a patch submitted by Ralph Giles . ------------------------------------------------------------------------------- -Tue Nov 24 20:05:05 CST 1998 Michael Jennings +Tue Nov 24 20:05:05 CST 1998 Michael Jennings Some fairly useless stuff that I really don't even want to document for fear it might actually get used, and people will expect more out of it than they should. If you really wanna know, diff it. :) ------------------------------------------------------------------------------- -Tue Nov 24 21:48:24 CST 1998 Michael Jennings +Tue Nov 24 21:48:24 CST 1998 Michael Jennings New feature. --pause will make Eterm wait for a keypress when the child process exits. Useful most often in combination with -e. @@ -818,32 +818,32 @@ Tue Nov 24 21:48:24 CST 1998 Michael Jennings (--anim) is much smoother and less bug-prone. ------------------------------------------------------------------------------- -Wed Nov 25 11:47:05 CST 1998 Michael Jennings +Wed Nov 25 11:47:05 CST 1998 Michael Jennings Some bug fixes in the ongoing saga of KainX vs. The Solaris 7 64-Bit Kernel. ------------------------------------------------------------------------------- -Fri Dec 4 16:11:03 CST 1998 Michael Jennings +Fri Dec 4 16:11:03 CST 1998 Michael Jennings Ok, this should make Eterm compliant with the GNU FHS. I also did a LOT of futzing around with configure.in, so if I broke something in doing either of these things, please let me know. ------------------------------------------------------------------------------- -Fri Dec 4 19:45:39 CST 1998 Michael Jennings +Fri Dec 4 19:45:39 CST 1998 Michael Jennings Feh. Thanks Pavlov. :-) ------------------------------------------------------------------------------- -Mon Dec 7 18:04:09 CST 1998 Michael Jennings +Mon Dec 7 18:04:09 CST 1998 Michael Jennings FreeBSD fixes, fixes for building without Imlib support (oops), and fixes for the RPATH problem with Debian and autofs. Thanks to Murray Stokely for continued help on the FreeBSD front. ------------------------------------------------------------------------------- -Tue Dec 8 12:10:55 CST 1998 Michael Jennings +Tue Dec 8 12:10:55 CST 1998 Michael Jennings Another of the Eterm-specific escape sequences. This one is \e]6;3\a which will force Eterm to update the pseudo-transparent background. @@ -851,12 +851,12 @@ Tue Dec 8 12:10:55 CST 1998 Michael Jennings Christmas. :-) ------------------------------------------------------------------------------- -Tue Dec 8 16:55:44 CST 1998 Michael Jennings +Tue Dec 8 16:55:44 CST 1998 Michael Jennings Another oopsie from the December 4th changes. ------------------------------------------------------------------------------- -Fri Dec 18 13:44:04 CST 1998 Michael Jennings +Fri Dec 18 13:44:04 CST 1998 Michael Jennings The long awaited selection options. There are two new options here. The first, --xterm-select, duplicates xterm's treatment of cutchars @@ -867,13 +867,13 @@ Fri Dec 18 13:44:04 CST 1998 Michael Jennings and select_line, both go in the toggles context. ------------------------------------------------------------------------------- -Mon Dec 28 18:20:01 CST 1998 Michael Jennings +Mon Dec 28 18:20:01 CST 1998 Michael Jennings From the Trying-to-Please-All-the-People-All-the-Time department... %random() seeds based on process ID *and* time(NULL) now. Feh. ------------------------------------------------------------------------------- -Tue Dec 29 16:52:34 CST 1998 Michael Jennings +Tue Dec 29 16:52:34 CST 1998 Michael Jennings A new Eterm feature. This one is called "Viewport Mode." It is toggled on by the --viewport-mode parameter or the viewport_mode @@ -894,19 +894,19 @@ Tue Dec 29 16:52:34 CST 1998 Michael Jennings Credit to es9 on IRC for the idea. ------------------------------------------------------------------------------- -Tue Dec 29 17:12:57 CST 1998 Michael Jennings +Tue Dec 29 17:12:57 CST 1998 Michael Jennings And Tynian said, "Let there be Debian Stuff." And there was Debian Stuff. And it was good. ------------------------------------------------------------------------------- -Tue Dec 29 17:51:21 CST 1998 Michael Jennings +Tue Dec 29 17:51:21 CST 1998 Michael Jennings Viewport + shading/tinting escape sequences is fixed. I also fixed a bug with shading/tinting. ------------------------------------------------------------------------------- -Wed Dec 30 12:07:18 CST 1998 Michael Jennings +Wed Dec 30 12:07:18 CST 1998 Michael Jennings Added an Eterm.spec.in file as submitted by techn0ir, with a couple minor changes. I know nothing about this file, so I have no clue how @@ -939,13 +939,13 @@ Wed Dec 30 12:07:18 CST 1998 Michael Jennings continued support and assistance with packaged Eterm distributions. ------------------------------------------------------------------------------- -Thu Dec 31 16:15:09 CST 1998 Michael Jennings +Thu Dec 31 16:15:09 CST 1998 Michael Jennings www.eterm.org is now alive and kicking. All pointers to www.tcserv.com have been changed to point to the new URL. ------------------------------------------------------------------------------- -Mon Jan 4 13:32:32 CST 1999 Michael Jennings +Mon Jan 4 13:32:32 CST 1999 Michael Jennings Hopefully fixed a bug with backquote commands that don't return any output. @@ -960,12 +960,12 @@ Mon Jan 4 13:32:32 CST 1999 Michael Jennings track it down. ------------------------------------------------------------------------------- -Mon Jan 4 14:31:06 CST 1999 Michael Jennings +Mon Jan 4 14:31:06 CST 1999 Michael Jennings Stupid KainX error #13,471.8: Don't use macros you don't have. ------------------------------------------------------------------------------- -Mon Jan 4 16:30:54 CST 1999 Michael Jennings +Mon Jan 4 16:30:54 CST 1999 Michael Jennings Work-around for what is either a bug or unexpected behavior in Enlightenment. Other WM's leave coordinate setting for negative @@ -976,56 +976,56 @@ Mon Jan 4 16:30:54 CST 1999 Michael Jennings I'm curious to know if this is a bug in E or in everybody else. :) ------------------------------------------------------------------------------- -Fri Jan 8 14:40:36 CST 1999 Michael Jennings +Fri Jan 8 14:40:36 CST 1999 Michael Jennings Documentation updates for 0.8.8. Wheeeeee. :) ------------------------------------------------------------------------------- -Mon Jan 11 14:30:02 CST 1999 Michael Jennings +Mon Jan 11 14:30:02 CST 1999 Michael Jennings Use Imlib_best_color_match() for all colors we allocate so that we coexist peacefully with Imlib, E, Netscape, et al. This should make raster's day a little brighter.... =) ------------------------------------------------------------------------------- -Mon Jan 11 16:12:35 CST 1999 Michael Jennings +Mon Jan 11 16:12:35 CST 1999 Michael Jennings Fixed typos in MAIN.in files. ------------------------------------------------------------------------------- -Mon Jan 11 16:34:41 CST 1999 Michael Jennings +Mon Jan 11 16:34:41 CST 1999 Michael Jennings Long-awaited transparency improvement for tiled desktops. Let's hope it doesn't break anything. ------------------------------------------------------------------------------- -Tue Jan 12 13:17:41 CST 1999 Michael Jennings +Tue Jan 12 13:17:41 CST 1999 Michael Jennings Integrate random background functionality into Eterm distribution. ------------------------------------------------------------------------------- -Thu Jan 21 10:49:02 CST 1999 Michael Jennings +Thu Jan 21 10:49:02 CST 1999 Michael Jennings Add some more verbose output when color allocation fails. ------------------------------------------------------------------------------- -Thu Jan 21 10:55:02 CST 1999 Michael Jennings +Thu Jan 21 10:55:02 CST 1999 Michael Jennings Yes, Virginia, there is a 0.8.9. Back to adding features. Ugh. =) ------------------------------------------------------------------------------- -Thu Jan 21 14:17:15 CST 1999 Michael Jennings +Thu Jan 21 14:17:15 CST 1999 Michael Jennings More for 0.8.9.... ------------------------------------------------------------------------------- -Thu Jan 21 15:15:52 CST 1999 Michael Jennings +Thu Jan 21 15:15:52 CST 1999 Michael Jennings Mouse wheel support. Does it work? I dunno, since I don't have a wheeled mouse and can't test it, but it should. ------------------------------------------------------------------------------- -Thu Jan 21 17:59:47 CST 1999 Michael Jennings +Thu Jan 21 17:59:47 CST 1999 Michael Jennings New --version option to display compile-time #define's. Also switched --help output to stdout instead of stderr (people were @@ -1033,7 +1033,7 @@ Thu Jan 21 17:59:47 CST 1999 Michael Jennings "Eterm --help 2>&1 | grep foo" was too much work). ------------------------------------------------------------------------------- -Thu Jan 28 11:58:26 CST 1999 Michael Jennings +Thu Jan 28 11:58:26 CST 1999 Michael Jennings Fixed typos in MAIN files. @@ -1042,18 +1042,18 @@ Thu Jan 28 11:58:26 CST 1999 Michael Jennings and I'm not sure why. =} ------------------------------------------------------------------------------- -Thu Jan 28 12:29:20 CST 1999 Michael Jennings +Thu Jan 28 12:29:20 CST 1999 Michael Jennings An attempt at a fix, or at least to help find the bug. ------------------------------------------------------------------------------- -Tue Feb 2 15:10:43 CST 1999 Michael Jennings +Tue Feb 2 15:10:43 CST 1999 Michael Jennings Tinting and shading speedups (about 30%) thanks to a patch from Michael Pearson . ------------------------------------------------------------------------------- -Tue Feb 2 23:27:20 CST 1999 Michael Jennings +Tue Feb 2 23:27:20 CST 1999 Michael Jennings You want scrollbars? We've got scrollbars. :) @@ -1064,21 +1064,21 @@ Tue Feb 2 23:27:20 CST 1999 Michael Jennings More work on this tomorrow, but I need sleep. ------------------------------------------------------------------------------- -Wed Feb 3 10:43:45 CST 1999 Michael Jennings +Wed Feb 3 10:43:45 CST 1999 Michael Jennings Fixed a bug with tiled desktop pixmaps and shading/tinting. Thanks to t'Sade and Michael Pearson for helping me track this down. ------------------------------------------------------------------------------- -Wed Feb 3 12:26:20 CST 1999 Michael Jennings +Wed Feb 3 12:26:20 CST 1999 Michael Jennings The resize-to-crash bug has *finally* been squashed once and for all, thanks to a patch from Sebastien van Klinkenberg . Thanks Sebastien!! ------------------------------------------------------------------------------- -Wed Feb 3 14:55:26 CST 1999 Michael Jennings +Wed Feb 3 14:55:26 CST 1999 Michael Jennings scrollbar_type now works in the attributes context of the MAIN file. @@ -1091,12 +1091,12 @@ Wed Feb 3 14:55:26 CST 1999 Michael Jennings (reported with Window Maker 0.50.2). ------------------------------------------------------------------------------- -Mon Feb 8 12:16:38 CST 1999 Michael Jennings +Mon Feb 8 12:16:38 CST 1999 Michael Jennings Fix for a tiny hiccup. ------------------------------------------------------------------------------- -Thu Feb 11 19:39:00 CST 1999 Michael Jennings +Thu Feb 11 19:39:00 CST 1999 Michael Jennings Ctrl-Click behavior has changed. Ctrl+Button1 now does the old raise- and-steal-focus thing. Ctrl+Button2 toggles the scrollbar. Ctrl+ @@ -1104,7 +1104,7 @@ Thu Feb 11 19:39:00 CST 1999 Michael Jennings src/feature.h but are on by default. ------------------------------------------------------------------------------- -Thu Feb 11 22:32:15 CST 1999 Michael Jennings +Thu Feb 11 22:32:15 CST 1999 Michael Jennings Added the --menubar boolean option to toggle whether or not the menubar is visible on startup. There's also the "menubar" attribute @@ -1114,7 +1114,7 @@ Thu Feb 11 22:32:15 CST 1999 Michael Jennings sequence or by Ctrl+Button3 on the term window. ------------------------------------------------------------------------------- -Thu Feb 11 23:34:10 CST 1999 Michael Jennings +Thu Feb 11 23:34:10 CST 1999 Michael Jennings Added support for popup scrollbars (i.e., the scrollbar goes away when Eterm loses focus, and comes back when Eterm regains focus). @@ -1125,7 +1125,7 @@ Thu Feb 11 23:34:10 CST 1999 Michael Jennings Also, thanks to OctobrX for the menubar ideas above. ------------------------------------------------------------------------------- -Mon Feb 15 19:38:54 CST 1999 Michael Jennings +Mon Feb 15 19:38:54 CST 1999 Michael Jennings New -D (--desktop) option (and "desktop" attribute in the "attributes" context) to choose what desktop to load on. NOTE: This requires a @@ -1146,14 +1146,14 @@ Mon Feb 15 19:38:54 CST 1999 Michael Jennings the desktop thing. ------------------------------------------------------------------------------- -Mon Feb 15 20:00:59 CST 1999 Michael Jennings +Mon Feb 15 20:00:59 CST 1999 Michael Jennings Work around a nasty Solaris X bug in _XFlushInt(), called by XUnmapWindow(). If we're not unmapped after 3 seconds, call _exit(). If _exit() isn't around, use abort(). ------------------------------------------------------------------------------- -Tue Feb 16 11:21:59 CST 1999 Michael Jennings +Tue Feb 16 11:21:59 CST 1999 Michael Jennings Implemented scrollbar type and width changing via an escape sequence, namely "\e]6;10;;\a". is either "xterm", "next", @@ -1161,7 +1161,7 @@ Tue Feb 16 11:21:59 CST 1999 Michael Jennings or blank. Leaving both values blank does nothing. ------------------------------------------------------------------------------- -Wed Feb 17 18:54:44 CST 1999 Michael Jennings +Wed Feb 17 18:54:44 CST 1999 Michael Jennings Two whole days' worth of work here. I added bunches of escape sequences. You can now set, configure, or toggle just about every @@ -1183,7 +1183,7 @@ Wed Feb 17 18:54:44 CST 1999 Michael Jennings =} ------------------------------------------------------------------------------- -Thu Feb 18 10:26:56 CST 1999 Michael Jennings +Thu Feb 18 10:26:56 CST 1999 Michael Jennings Patch from John Ellson . Render style was not getting properly reset for line wrapping. His patched fixed extra @@ -1195,14 +1195,14 @@ Thu Feb 18 10:26:56 CST 1999 Michael Jennings Thanks guys! ------------------------------------------------------------------------------- -Thu Feb 18 14:06:05 CST 1999 Michael Jennings +Thu Feb 18 14:06:05 CST 1999 Michael Jennings Dammit. I hate stupid bugs, and this is a big one. Re-enable our own system() call, this time one that works. If you setuid Eterm, you NEED this fix ASAP. 'Nuff said. ------------------------------------------------------------------------------- -Tue Mar 2 14:31:03 CST 1999 Michael Jennings +Tue Mar 2 14:31:03 CST 1999 Michael Jennings Applied and corrected patch from Alexander Savelyev for supporting DESTDIR and for utmp on BSDI. @@ -1211,17 +1211,17 @@ Tue Mar 2 14:31:03 CST 1999 Michael Jennings Thanks to Tomas Ogren for the patch. ------------------------------------------------------------------------------- -Tue Mar 2 17:27:22 CST 1999 Michael Jennings +Tue Mar 2 17:27:22 CST 1999 Michael Jennings The -C (--console) switch works again, at least on Solaris and Linux. ------------------------------------------------------------------------------- -Wed Mar 3 09:44:21 CST 1999 Michael Jennings +Wed Mar 3 09:44:21 CST 1999 Michael Jennings Debian info updates from Brian M. Almeida ------------------------------------------------------------------------------- -Wed Mar 3 17:58:55 CST 1999 Michael Jennings +Wed Mar 3 17:58:55 CST 1999 Michael Jennings Reformatted code using new script, aptly-named "reformat-code," which calls indent. Now if only there were a few more indent options, like @@ -1232,23 +1232,23 @@ Wed Mar 3 17:58:55 CST 1999 Michael Jennings on glibc 2.1. ------------------------------------------------------------------------------- -Wed Mar 3 18:04:49 CST 1999 Michael Jennings +Wed Mar 3 18:04:49 CST 1999 Michael Jennings Oops, forgot some Debian files. ------------------------------------------------------------------------------- -Thu Mar 11 14:30:53 CST 1999 Michael Jennings +Thu Mar 11 14:30:53 CST 1999 Michael Jennings Changed the default colors from names to rgb values (failsafe), and modified almost all of them to match colors Netscape uses. ------------------------------------------------------------------------------- -Thu Mar 11 15:51:05 CST 1999 Michael Jennings +Thu Mar 11 15:51:05 CST 1999 Michael Jennings Remove move-themes.in from distribution list. ------------------------------------------------------------------------------- -Sun Mar 14 12:32:36 CST 1999 Michael Jennings +Sun Mar 14 12:32:36 CST 1999 Michael Jennings By popular demand, the bright blue scrollbar/menubar scheme has been nixed in favor of a red/gray scheme that blends with the ShinyMetal @@ -1257,27 +1257,27 @@ Sun Mar 14 12:32:36 CST 1999 Michael Jennings for a change.... =) ------------------------------------------------------------------------------- -Tue Mar 16 09:21:53 CST 1999 Michael Jennings +Tue Mar 16 09:21:53 CST 1999 Michael Jennings Checkpoint commit. We're on our way to making debugging output a dual compile- and run-time option. ------------------------------------------------------------------------------- -Tue Mar 16 17:34:35 CST 1999 Michael Jennings +Tue Mar 16 17:34:35 CST 1999 Michael Jennings . in config search path can cause nasty, hard-to-find weirdness. So I nixed it. I apologize in advance if you used it, but if you did, you probably have bigger problems. ------------------------------------------------------------------------------- -Wed Mar 17 16:59:25 CST 1999 Michael Jennings +Wed Mar 17 16:59:25 CST 1999 Michael Jennings Completely redid all the debugging stuff to facilitate the creation of a run-time option for it. The option isn't there yet; that comes next. ------------------------------------------------------------------------------- -Thu Mar 18 14:24:48 CST 1999 Michael Jennings +Thu Mar 18 14:24:48 CST 1999 Michael Jennings Finally fixed a long-standing font alignment problem in the menubar when using nexus, shine, and similar fonts with 0 descent. I then @@ -1285,21 +1285,21 @@ Thu Mar 18 14:24:48 CST 1999 Michael Jennings ignore it for a bit longer. =) ------------------------------------------------------------------------------- -Thu Mar 18 18:05:30 CST 1999 Michael Jennings +Thu Mar 18 18:05:30 CST 1999 Michael Jennings Fixed another long-standing problem, this time with the placement and appearance of the menubar arrows, especially when --border-width is used. ------------------------------------------------------------------------------- -Fri Mar 19 12:15:35 CST 1999 Michael Jennings +Fri Mar 19 12:15:35 CST 1999 Michael Jennings New --debug option to vary the level of debugging output shown. Valid values are integers 0 through DEBUG, where DEBUG is the value you set when calling ./configure with --with-debugging=N. ------------------------------------------------------------------------------- -Fri Mar 19 17:34:52 CST 1999 Michael Jennings +Fri Mar 19 17:34:52 CST 1999 Michael Jennings Implemented two new escape codes. One is a simple "exit" feature than can be used from the menubar. The other is a feature to save the @@ -1314,7 +1314,7 @@ Fri Mar 19 17:34:52 CST 1999 Michael Jennings the current settings save properly.... =) ------------------------------------------------------------------------------- -Fri Mar 19 18:20:28 CST 1999 Michael Jennings +Fri Mar 19 18:20:28 CST 1999 Michael Jennings After further consideration, added a routine to create a backup of the current MAIN file before overwriting it. The backup is named with a @@ -1322,19 +1322,19 @@ Fri Mar 19 18:20:28 CST 1999 Michael Jennings any other backup files. ------------------------------------------------------------------------------- -Mon Mar 22 10:23:58 CST 1999 Michael Jennings +Mon Mar 22 10:23:58 CST 1999 Michael Jennings Changed configure.in so that the default level of debugging support compiled in is 4 (the maximum level that does not sync X events). The run-time default is still 0, however. ------------------------------------------------------------------------------- -Tue Mar 23 18:16:40 CST 1999 Michael Jennings +Tue Mar 23 18:16:40 CST 1999 Michael Jennings Whoops. Inverted one set of arrows too many. =) ------------------------------------------------------------------------------- -Tue Mar 23 18:50:36 CST 1999 Michael Jennings +Tue Mar 23 18:50:36 CST 1999 Michael Jennings Added support in the options macros for specifying a variable to which the bitmask should be applied. (The variable Options had always been @@ -1342,7 +1342,7 @@ Tue Mar 23 18:50:36 CST 1999 Michael Jennings variables via command-line options with no additional code needed. ------------------------------------------------------------------------------- -Tue Mar 23 19:43:38 CST 1999 Michael Jennings +Tue Mar 23 19:43:38 CST 1999 Michael Jennings Added long-awaited options to set the keypad and cursor key modes on startup. @@ -1356,7 +1356,7 @@ Tue Mar 23 19:43:38 CST 1999 Michael Jennings continues to be normal cursor key mode. ------------------------------------------------------------------------------- -Tue Mar 23 21:28:57 CST 1999 Michael Jennings +Tue Mar 23 21:28:57 CST 1999 Michael Jennings Nuked several bugs relating to printpipe. Also enabled it by default. @@ -1364,55 +1364,55 @@ Tue Mar 23 21:28:57 CST 1999 Michael Jennings debugging is enabled. ------------------------------------------------------------------------------- -Fri Mar 26 17:54:03 CST 1999 Michael Jennings +Fri Mar 26 17:54:03 CST 1999 Michael Jennings Lots of code cleanups here, plus a bugfix for menubars. I might have done other stuff too, I forget.... =) ------------------------------------------------------------------------------- -Fri Mar 26 19:07:15 CST 1999 Michael Jennings +Fri Mar 26 19:07:15 CST 1999 Michael Jennings Added another little helper app. This one is doc/Etbg, written by Brian McFee in a fit of boredom. Thanks keeb! ------------------------------------------------------------------------------- -Fri Mar 26 22:08:45 CST 1999 Michael Jennings +Fri Mar 26 22:08:45 CST 1999 Michael Jennings The rewrite of the Eterm Technical Reference. It's HTML now, and is (at least to me) much more readable. I've still got lots to add, but it's fleshed out enough to replace the old one now. ------------------------------------------------------------------------------- -Mon Mar 29 11:25:24 CST 1999 Michael Jennings +Mon Mar 29 11:25:24 CST 1999 Michael Jennings Oops. Forgot to add the Kanji stuff to main.h. Thanks to Sung-Hyun Nam for catching this. ------------------------------------------------------------------------------- -Mon Mar 29 19:37:38 CST 1999 Michael Jennings +Mon Mar 29 19:37:38 CST 1999 Michael Jennings This is an attempt to fix X locale support, which was broken on Linux (XFree86?). Please (!) let me know if I broke stuff, especially you who use KANJI. ------------------------------------------------------------------------------- -Mon Mar 29 20:19:29 CST 1999 Michael Jennings +Mon Mar 29 20:19:29 CST 1999 Michael Jennings Pre-emptive Kanji fix. ------------------------------------------------------------------------------- -Tue Mar 30 13:07:05 CST 1999 Michael Jennings +Tue Mar 30 13:07:05 CST 1999 Michael Jennings More robust font set for XIC. Should be able to handle any charset. ------------------------------------------------------------------------------- -Tue Mar 30 17:20:50 CST 1999 Michael Jennings +Tue Mar 30 17:20:50 CST 1999 Michael Jennings Technical reference now includes complete documentation for all the Eterm-specific escape sequences. ------------------------------------------------------------------------------- -Wed Mar 31 18:47:18 CST 1999 Michael Jennings +Wed Mar 31 18:47:18 CST 1999 Michael Jennings Added support for the "ESC ] {l|I|L} string ESC \" sequences, a la dtterm. 'l' sets the title, 'I' sets the icon pixmap filename (or the @@ -1423,59 +1423,59 @@ Wed Mar 31 18:47:18 CST 1999 Michael Jennings Look for more dtterm sequence support coming soon. ------------------------------------------------------------------------------- -Wed Mar 31 19:56:07 CST 1999 Michael Jennings +Wed Mar 31 19:56:07 CST 1999 Michael Jennings More work on the Technical Reference. ------------------------------------------------------------------------------- -Thu Apr 1 10:25:35 CST 1999 Michael Jennings +Thu Apr 1 10:25:35 CST 1999 Michael Jennings At this point, the initial revision of the Eterm Technical Reference is complete. I'm looking for comments, suggestions, errata, and so forth. :-) ------------------------------------------------------------------------------- -Thu Apr 1 10:37:57 CST 1999 Michael Jennings +Thu Apr 1 10:37:57 CST 1999 Michael Jennings Some rearranging. Now doc/ just contains documentation. The utility programs have been put in utils/. ------------------------------------------------------------------------------- -Thu Apr 1 12:06:15 CST 1999 Michael Jennings +Thu Apr 1 12:06:15 CST 1999 Michael Jennings New, improved color grid script, Etcolors.sh. ------------------------------------------------------------------------------- -Thu Apr 1 12:40:15 CST 1999 Michael Jennings +Thu Apr 1 12:40:15 CST 1999 Michael Jennings New, improved menu utility, Etmenu.sh. Modified utils/Makefile.am to install these new utilities. ------------------------------------------------------------------------------- -Thu Apr 1 17:48:47 CST 1999 Michael Jennings +Thu Apr 1 17:48:47 CST 1999 Michael Jennings Doh! Man page booboo. Thanks to Jim Niemira for pointing this out to me. ------------------------------------------------------------------------------- -Mon Apr 5 14:18:09 CDT 1999 Michael Jennings +Mon Apr 5 14:18:09 CDT 1999 Michael Jennings Support several dtterm escape sequences for window operations. Documentation is forthcoming. ------------------------------------------------------------------------------- -Mon Apr 5 14:41:11 CDT 1999 Michael Jennings +Mon Apr 5 14:41:11 CDT 1999 Michael Jennings Added a rule to build an HTML-ized man page in doc/. ------------------------------------------------------------------------------- -Mon Apr 5 14:55:41 CDT 1999 Michael Jennings +Mon Apr 5 14:55:41 CDT 1999 Michael Jennings Gah! I'd love to know who the idiot was who decided to put height before width.... >:P ------------------------------------------------------------------------------- -Mon Apr 5 15:15:42 CDT 1999 Michael Jennings +Mon Apr 5 15:15:42 CDT 1999 Michael Jennings Documentation for new window ops sequences: @@ -1497,7 +1497,7 @@ Mon Apr 5 15:15:42 CDT 1999 Michael Jennings n == 21: Report window title ------------------------------------------------------------------------------- -Tue Apr 6 13:33:18 CDT 1999 Michael Jennings +Tue Apr 6 13:33:18 CDT 1999 Michael Jennings Added support for UNIX 98 pty's under glibc 2.1, thanks to a patch from Mikolaj Habryn . @@ -1509,7 +1509,7 @@ Tue Apr 6 13:33:18 CDT 1999 Michael Jennings necessary! :-) ------------------------------------------------------------------------------- -Wed Apr 7 10:14:00 CDT 1999 Michael Jennings +Wed Apr 7 10:14:00 CDT 1999 Michael Jennings Fixed several bugs related to the %include directive and magic number version checking in the config file parser, thanks to a patch from @@ -1521,7 +1521,7 @@ Wed Apr 7 10:14:00 CDT 1999 Michael Jennings Thanks guys! :-) ------------------------------------------------------------------------------- -Thu Apr 8 13:01:02 CDT 1999 Michael Jennings +Thu Apr 8 13:01:02 CDT 1999 Michael Jennings Trying to get pty code in order. There are some problems with glibc 2.1 systems still. I totally rearranged the pty-finding code, so I @@ -1529,30 +1529,30 @@ Thu Apr 8 13:01:02 CDT 1999 Michael Jennings anything. ------------------------------------------------------------------------------- -Thu Apr 8 14:43:42 CDT 1999 Michael Jennings +Thu Apr 8 14:43:42 CDT 1999 Michael Jennings Still trying to get that pty code in order.... :( ------------------------------------------------------------------------------- -Thu Apr 8 15:34:31 CDT 1999 Michael Jennings +Thu Apr 8 15:34:31 CDT 1999 Michael Jennings And again. ------------------------------------------------------------------------------- -Thu Apr 8 16:21:21 CDT 1999 Michael Jennings +Thu Apr 8 16:21:21 CDT 1999 Michael Jennings Now that the pty problems seem to be fixed (at least on Solaris and Linux), let's be a little more robust with failures. ------------------------------------------------------------------------------- -Thu Apr 8 18:11:46 CDT 1999 Michael Jennings +Thu Apr 8 18:11:46 CDT 1999 Michael Jennings Fixed some assorted bugs and problems that occur when pixmaps.list is not present. Also fixed a bug for output files that cannot be created. ------------------------------------------------------------------------------- -Thu Apr 15 16:01:03 CDT 1999 Michael Jennings +Thu Apr 15 16:01:03 CDT 1999 Michael Jennings The borderless Eterm options will now make Eterm set the MWM hints so that the window manager will render it borderless. (If the WM @@ -1561,21 +1561,21 @@ Thu Apr 15 16:01:03 CDT 1999 Michael Jennings Enlightenment, but it should work for other window managers too. ------------------------------------------------------------------------------- -Thu Apr 15 17:42:35 CDT 1999 Michael Jennings +Thu Apr 15 17:42:35 CDT 1999 Michael Jennings Added the type of each variable to the help output, as well as some additional info on how to use the command-line options. You're welcome, llane. :-) ------------------------------------------------------------------------------- -Fri Apr 16 18:03:26 CDT 1999 Michael Jennings +Fri Apr 16 18:03:26 CDT 1999 Michael Jennings Added a -fit option to Esetroot which scales the image to fit the screen while maintaining its true proportion. Thanks to Remo Strotkamp for the idea and some code. ------------------------------------------------------------------------------- -Mon Apr 19 13:55:09 CDT 1999 Michael Jennings +Mon Apr 19 13:55:09 CDT 1999 Michael Jennings Two bugfix patches. One is for compiling on SGI IRIX, thanks to Kimball Thurston . The other was a fix for the @@ -1583,20 +1583,20 @@ Mon Apr 19 13:55:09 CDT 1999 Michael Jennings Sebastien van Klinkenberg . :-) ------------------------------------------------------------------------------- -Mon Apr 19 19:42:54 CDT 1999 Michael Jennings +Mon Apr 19 19:42:54 CDT 1999 Michael Jennings Two more bugfixes. Eterm now installs its X error handler earlier to catch more errors without dying. Also, another patch from Sebastien van Klinkenberg for the segfault bug. ------------------------------------------------------------------------------- -Tue Apr 20 15:20:00 CDT 1999 Michael Jennings +Tue Apr 20 15:20:00 CDT 1999 Michael Jennings I think this fixes all remaining menu flickering problems. I also removed a goto while I was at it, because goto's are evil. ------------------------------------------------------------------------------- -Tue Apr 20 16:05:50 CDT 1999 Michael Jennings +Tue Apr 20 16:05:50 CDT 1999 Michael Jennings Added a new option. --select-trailing-spaces (or the attribute select_trailing_spaces in the toggles context of the config file) @@ -1608,20 +1608,675 @@ Tue Apr 20 16:05:50 CDT 1999 Michael Jennings Also did some options-related cleanups in preparation for release. ------------------------------------------------------------------------------- -Wed Apr 21 09:58:36 CDT 1999 Michael Jennings +Wed Apr 21 09:58:36 CDT 1999 Michael Jennings This should take care of the man page for the release of 0.8.9. ------------------------------------------------------------------------------- -Wed Apr 21 10:20:33 CDT 1999 Michael Jennings +Wed Apr 21 10:20:33 CDT 1999 Michael Jennings Added support, documentation, and .menu file entries for an escape code to toggle the select-trailing-spaces feature. ------------------------------------------------------------------------------- -Fri Apr 23 15:55:18 CDT 1999 Michael Jennings +Fri Apr 23 15:55:18 CDT 1999 Michael Jennings Support the omission of the operator in an xterm escape sequence. Adding support for the dtterm stuff broke this. ------------------------------------------------------------------------------- +Mon Apr 26 13:26:20 CDT 1999 Michael Jennings + + Initial checkin of Eterm 0.8.10. Please note the following WARNING + which has been added to configure.in: + + This version of Eterm is highly experimental. All kinds of things + may be broken; in fact, it may not work at all! DO NOT install + this version of Eterm as your general-use version. Even the + developers aren't doing that! You have been warned! + + If you run this version, you'll notice that the menubar and scrollbar + have become pixmapped. I've still got *lots* of stuff to clean up, + but it's not looking too bad. =) + +------------------------------------------------------------------------------- +Mon Apr 26 16:59:37 CDT 1999 Michael Jennings + + Cleanups of the scrollbar/menubar pixmapping stuff. + +------------------------------------------------------------------------------- +Mon Apr 26 18:51:34 CDT 1999 Michael Jennings + + Removed some pointless compile-time #defines. Added a separate + menubar color and unfocused menubar color, along with options and + attributes to support them (--menubar-color, + --unfocused-menubar-color). + +------------------------------------------------------------------------------- +Tue Apr 27 10:41:15 CDT 1999 Michael Jennings + + Added a pix/ directory for scrollbar/menubar pixmaps. Swiped some + pixmaps from Enlightenment to work with. + +------------------------------------------------------------------------------- +Wed Apr 28 16:43:47 CDT 1999 Michael Jennings + + Scrollbar trough is now pixmappable. Everything seems to work as far + as I can tell. Now on to the scrollbar anchor. + + I also cleaned up a lot of the pixmap handling code. Tiling is + handled the *right* way now. :-) + +------------------------------------------------------------------------------- +Wed Apr 28 17:07:00 CDT 1999 Michael Jennings + + Fixes from Karl Vogel for Digital UNIX. Now back to + breaking stuff! >:-) + +------------------------------------------------------------------------------- +Wed Apr 28 19:03:55 CDT 1999 Michael Jennings + + Pixmappable up- and down-arrows. The scrolling isn't working quite + right just yet, though. + +------------------------------------------------------------------------------- +Thu Apr 29 09:27:17 CDT 1999 Michael Jennings + + Scrolling is fixed. Now it's time to break all kinds of stuff.... + +------------------------------------------------------------------------------- +Fri Apr 30 18:26:31 CDT 1999 Michael Jennings + + I've got everything cleaned up quite a bit now. This one should + compile and run just fine. If it doesn't work for you, please let me + know. + +------------------------------------------------------------------------------- +Mon May 3 14:06:21 CDT 1999 Michael Jennings + + Brand new event handling subsystem. + +------------------------------------------------------------------------------- +Mon May 3 14:23:23 CDT 1999 Michael Jennings + + Fixed a problem with transparency and a floating scrollbar. + +------------------------------------------------------------------------------- +Mon May 3 15:00:37 CDT 1999 Michael Jennings + + Fixed problem resizing scrollbar with pixmapped arrows. + +------------------------------------------------------------------------------- +Mon May 3 17:00:39 CDT 1999 Michael Jennings + + Patch from Norman Stevens for builddir != + srcdir. Also beginnings of pixmappable scrollbar anchor. + +------------------------------------------------------------------------------- +Tue May 4 11:30:12 CDT 1999 Michael Jennings + + The scrollbar is now fully-functional with every element pixmapped. + +------------------------------------------------------------------------------- +Tue May 4 12:12:42 CDT 1999 Michael Jennings + + I cleaned up the code in options.c for reading pixmap configurations. + You can now specify your scrollbar pixmaps in MAIN, like so: + + trough 100 100 bar_vertical_3.png + up_arrow 100 100 button_arrow_up_1.png + down_arrow 100 100 button_arrow_down_1.png + anchor 100 100 bar_vertical_1.png + + These go in the pixmaps context, of course. + +------------------------------------------------------------------------------- +Tue May 4 15:25:33 CDT 1999 Michael Jennings + + Menubar background pixmap is now configurable. In order to have some + variety, I added two more auto-generated pixmap list files, one of the + tiled images, and one of the scaled ones. Here's the new line in my + MAIN file: + + menu_background 0 0 %random(`cat tiled-pixmaps.list`) + +------------------------------------------------------------------------------- +Tue May 4 17:46:20 CDT 1999 Michael Jennings + + Fixed some resizing issues. + +------------------------------------------------------------------------------- +Tue May 4 18:55:34 CDT 1999 Michael Jennings + + Temporary hack to keep background pixmap shading/tinting from + affecting the scrollbar/menubar pixmaps. I will fix this the Right + Way when I redo the pixmap stuff. + +------------------------------------------------------------------------------- +Thu May 6 11:23:48 CDT 1999 Michael Jennings + + Back to breaking things.... I'm in the process of shifting Eterm's + old "pixmap" paradigm to one based on 3-state images. This will allow + Eterm to support different pixmaps for the various elements based on + state (normal, selected, clicked), as well as different shading + levels, different tints, etc. It will also support different image + operations (tiling, scaling, proportional scaling, offsetting, and + various combinations thereof). But in order to do that, I have to + completely redesign the pixmap code and alter parts of the config file + format. + + This checkin is BROKEN. It will not run. But it will give you a bit + of a glimpse at the future (if you look at the code, anyway). :-) + +------------------------------------------------------------------------------- +Thu May 6 14:31:23 CDT 1999 Michael Jennings + + Back in semi-working order (i.e., it runs without crashing). Still + details to iron out, of course. + +------------------------------------------------------------------------------- +Thu May 6 18:08:02 CDT 1999 Michael Jennings + + Almost back to where we were before. A few small things still + broken, but at least it runs without crashing. :-) + +------------------------------------------------------------------------------- +Thu May 6 21:55:26 CDT 1999 Michael Jennings + + All the pixmap manipulation code is working now. There is a LOT more + flexibility with this system. Scaling and tiling are entirely + independent, so for example, you can scale to 50% by 50% and tile, or + scale to 100%, or scale to 90% while maintaining the image's aspect + ratio, or tile the image at its true size.... There are all kinds of + possibilities. And the +X+Y offsets work again as well, so you can + center images, or adjust the origin within the window however you + like. Plus, you can set the shading, tinting, geometry, and border + widths of each image individually. + + The first screenshot at http://www.eterm.org/Screenshots.html shows + two Eterms done this way. The comment explains what I did to each. + If you look at the Emacs window in the background, you can also get + a glimpse of the new config file syntax. + +------------------------------------------------------------------------------- +Fri May 7 13:34:38 CDT 1999 Michael Jennings + + Added image mode support. For each image type, you can specify a + startup mode and a list of allowable modes for that element (image, + trans, or viewport). + +------------------------------------------------------------------------------- +Fri May 7 14:22:27 CDT 1999 Michael Jennings + + Fixed bug with handling undefined contexts. It won't crash on old + themes now. :-) + +------------------------------------------------------------------------------- +Fri May 7 17:01:04 CDT 1999 Michael Jennings + + Updated all the themes with the new format. Read the comments for + details on how they work. + + I also changed the default config file name since E doesn't use MAIN + any longer. The new name is "theme.cfg". This will also create the + possibility of a user-specific preferences file, "user.cfg". + +------------------------------------------------------------------------------- +Mon May 10 12:10:21 CDT 1999 Michael Jennings + + Fixed the "path" statements in the default config files. Also fixed + the setting of the background image to "None." + +------------------------------------------------------------------------------- +Mon May 10 14:14:48 CDT 1999 Michael Jennings + + Tinting and shading from the menu is fixed. So are the image + choices. + +------------------------------------------------------------------------------- +Mon May 10 14:46:00 CDT 1999 Michael Jennings + + Only track pointers if we're debugging. Should help some on speed. + +------------------------------------------------------------------------------- +Mon May 10 16:15:00 CDT 1999 Michael Jennings + + Shading and tinting via the command line work again. + +------------------------------------------------------------------------------- +Tue May 11 14:00:36 CDT 1999 Michael Jennings + + New --install option to use a separate color map. This depends on my + updates to Imlib 1.9.5. + +------------------------------------------------------------------------------- +Tue May 11 15:05:38 CDT 1999 Michael Jennings + + Fixed some assorted bugs with mode lines and with Eterm starting in + the wrong directory. + +------------------------------------------------------------------------------- +Wed May 12 16:00:04 CDT 1999 Michael Jennings + + Fixed problems loading menubar files. Also made theme searching more + efficient. Searching $PATH has also been eliminated since it took a + lot of time for really no good reason. + +------------------------------------------------------------------------------- +Wed May 12 17:23:54 CDT 1999 Michael Jennings + + Duh. Fixed a stupid mistake on my part that broke background image + tinting. + +------------------------------------------------------------------------------- +Wed May 12 19:17:59 CDT 1999 Michael Jennings + + Per a suggestion from namsh, I cleaned up the #including of config.h + since it does not keep itself from being included multiple times. + +------------------------------------------------------------------------------- +Thu May 13 09:00:15 CDT 1999 Michael Jennings + + Removed eterm_imlib.h since Imlib 0.x is no longer supported. Also + fixed the "status" escape sequence. + +------------------------------------------------------------------------------- +Thu May 13 16:40:54 CDT 1999 Michael Jennings + + Fixed some bugs with transparency. Also fixed a scrolling bug. + + The scrollbar event handler is now in place via the event subsystem I + designed awhile back. The scrollbar itself is now more self- + contained, as it handles all its own events. + +------------------------------------------------------------------------------- +Fri May 14 09:02:37 CDT 1999 Michael Jennings + + More work on separating and encompassing the scrollbar. + +------------------------------------------------------------------------------- +Fri May 14 14:51:18 CDT 1999 Michael Jennings + + Command-line options for images are working again. + +------------------------------------------------------------------------------- +Fri May 14 15:44:31 CDT 1999 Michael Jennings + + New escape sequence for setting the level of debugging output on the + fly. + +------------------------------------------------------------------------------- +Wed May 19 12:45:49 CDT 1999 Michael Jennings + + Moved some features to configure.in instead of feature.h. + + Also fixed my e-mail address to one that's more pertinent. + +------------------------------------------------------------------------------- +Thu May 20 15:11:41 CDT 1999 Michael Jennings + + Scrollbar images are now 3-state. + +------------------------------------------------------------------------------- +Wed May 26 12:11:51 CDT 1999 Michael Jennings + + Removed the active tags stuff since it never worked right anyway. We + will do this eventually, but it will be integrated more into the + system. + + Also added the skeleton files for the new popup menu system. Bye bye + evil menubar. + +------------------------------------------------------------------------------- +Thu May 27 11:52:37 CDT 1999 Michael Jennings + + More work on the menu system. + +------------------------------------------------------------------------------- +Tue Jun 1 13:34:33 CDT 1999 Michael Jennings + + The menubar is now gone. Totally and permanently. Good riddance. + + Also in this commit is a fix from Luca Lizzeri for + multi-threaded builds, and I'm going to see how changing the default + for HAVE_SAVED_UIDS goes. + +------------------------------------------------------------------------------- +Wed Jun 2 15:02:29 CDT 1999 Michael Jennings + + The menu can actually draw itself now, but not much else. + +------------------------------------------------------------------------------- +Wed Jun 2 19:54:03 CDT 1999 Michael Jennings + + Further menu drawing refinements. Still not quite there yet, though. + +------------------------------------------------------------------------------- +Thu Jun 3 09:34:05 CDT 1999 Michael Jennings + + Fixed a segfault with themes lacking menus (which, at the moment, + includes all of them but mine). Thanks to Patrick Lenz + for pointing this out. + +------------------------------------------------------------------------------- +Thu Jun 3 16:54:57 CDT 1999 Michael Jennings + + Wow, it's actually starting to look semi-usable now. :-) + +------------------------------------------------------------------------------- +Thu Jun 3 18:03:36 CDT 1999 Michael Jennings + + Both menu navigation styles are now working. + +------------------------------------------------------------------------------- +Fri Jun 4 16:51:26 CDT 1999 Michael Jennings + + Everything works for a 1-tier menu, except for actually performing + the action. Next I'll implement that, and fix the bug with + proportional fonts. + +------------------------------------------------------------------------------- +Mon Jun 7 10:43:29 CDT 1999 Michael Jennings + + Eterm finally has a dedicated module for Enlightenment-specific + feature support. Don't worry, there's lots more to come here soon. :) + +------------------------------------------------------------------------------- +Mon Jun 7 15:33:23 CDT 1999 Michael Jennings + + Flat menus should be working now. Now onto submenus.... + +------------------------------------------------------------------------------- +Tue Jun 8 09:58:10 CDT 1999 Michael Jennings + + Fixes for KANJI support. Thanks to Sung-Hyun Nam + for pointing this out. + +------------------------------------------------------------------------------- +Tue Jun 8 14:24:11 CDT 1999 Michael Jennings + + The submenu code is now in. Navigation is still rather flaky, + however. + +------------------------------------------------------------------------------- +Wed Jun 9 15:24:15 CDT 1999 Michael Jennings + + Navigation is still quite messy, but at least it's possible to get to + all the menu items, and they actually seem to work. So I'll commit + this anyway. + +------------------------------------------------------------------------------- +Thu Jun 10 12:41:20 CDT 1999 Michael Jennings + + Navigation is 99% clean now. I've added the new menu files and such + to CVS now, so you should be able to try everything out now. Let me + know if you have any problems. + +------------------------------------------------------------------------------- +Thu Jun 10 16:24:50 CDT 1999 Michael Jennings + + Eliminate one more stupid configure.in hack. :-) + +------------------------------------------------------------------------------- +Fri Jun 11 11:11:31 CDT 1999 Michael Jennings + + A KANJI fix and a Makefile.am fix from Sung-Hyun Nam + . + +------------------------------------------------------------------------------- +Mon Jun 14 10:16:10 CDT 1999 Michael Jennings + + Several oopses fixed. + +------------------------------------------------------------------------------- +Mon Jun 14 19:21:11 CDT 1999 Michael Jennings + + Initial work on supporting IPC (E IPC and Eterm's own IPC), as well + as some bugfixes with the menu. Also changed the default for refresh + to fast (from smooth). + +------------------------------------------------------------------------------- +Tue Jun 15 10:24:32 CDT 1999 Michael Jennings + + Scrolling speed-ups, bugfix in menus.c for systems without save- + unders, and corrections to menu config files. + +------------------------------------------------------------------------------- +Tue Jun 15 19:13:04 CDT 1999 Michael Jennings + + Added the %preproc directive to allow Eterm config files to be pre- + processed by the utility of your choice (so long as it can read from + stdin and write to stdout). Also modified the chooser-menu.cfg file + to (1) work right, and (2) demonstrate the use of %preproc. + +------------------------------------------------------------------------------- +Wed Jun 16 16:56:13 CDT 1999 Michael Jennings + + Some bugfixes with respect to escape sequence parsing, as well as + improved formatting for debugging output. + +------------------------------------------------------------------------------- +Thu Jun 17 12:14:15 CDT 1999 Michael Jennings + + Added an Eterm IPC interface to Enlightenment's own IPC. The escape + sequence is "\e]7;enl_send:\a". Eterm can now be used in + place of eesh. + + Also added a check to configure.in to make sure the OS's snprintf() + implementation, if it exists, does not ignore the "n" parameter. The + macro for this was written by Duncan Simpson . + +------------------------------------------------------------------------------- +Fri Jun 18 17:47:34 CDT 1999 Michael Jennings + + Added beveling and padding support. I'll take care of updating the + theme files later. + + NOTE: You WILL have to update Imlib from CVS to successfully compile + and run this version. + +------------------------------------------------------------------------------- +Mon Jun 21 10:41:23 CDT 1999 Michael Jennings + + Fixed a bug noticed by Gnea with the menu code + remembering the last selected item. This caused certain toggles (like + transparency) to misbehave when using click-select menu navigation. + (Drag-and-release worked fine.) + +------------------------------------------------------------------------------- +Mon Jun 21 15:39:26 CDT 1999 Michael Jennings + + Added the "winop" IPC command and a little helper script, so Eterm can + assist in minor window manipulation needs. + + Also removed the old menu helper script since it's no longer valid. + And I removed the .sh from the ends of the script names. + +------------------------------------------------------------------------------- +Wed Jun 23 15:53:18 CDT 1999 Michael Jennings + + Hopefully fixed the CONFIG_SEARCH_PATH definition under Linux. + +------------------------------------------------------------------------------- +Thu Jun 24 14:06:01 CDT 1999 Michael Jennings + + Eterm can receive Enlightenment IPC replies now. Added Eterm IPC + command "enl_query" which, unlike enl_send, will wait for a reply to + its IPC command. + + Also added a skeleton function for when mandrake adds the image query + IPC commands to E. + +------------------------------------------------------------------------------- +Thu Jun 24 15:02:38 CDT 1999 Michael Jennings + + This should fix the bug Gnea found (see above). My previous fix was + incomplete. + +------------------------------------------------------------------------------- +Thu Jun 24 17:07:37 CDT 1999 Michael Jennings + + Added some checks to the config file parser which should help fix the + issues between theme.cfg and user.cfg. + +------------------------------------------------------------------------------- +Fri Jun 25 11:52:41 CDT 1999 Michael Jennings + + Added keysym reporting mode from salvador . + This feature is designed for application use and is not recommended + for normal users to try. :-) + +------------------------------------------------------------------------------- +Fri Jun 25 14:44:01 CDT 1999 Michael Jennings + + New utility Ettable. Prints out an ASCII table in the current font. + Useful for showing you what characters your font has as well as their + numeric values in decimal/hex/octal. + +------------------------------------------------------------------------------- +Mon Jun 28 10:21:12 CDT 1999 Michael Jennings + + Fixed the seg fault bug noticed by several people. I guess Solaris is + a bit more forgiving of free()ing memory you didn't malloc(). + +------------------------------------------------------------------------------- +Tue Jun 29 11:48:56 CDT 1999 Michael Jennings + + Fixed a bug with MWM hints thanks to a patch from MOROHOSHI Akihiko + . + + Also fixed the menus to move themselves rather than displaying off + screen when they are opened near the screen edge. + +------------------------------------------------------------------------------- +Tue Jun 29 16:38:25 CDT 1999 Michael Jennings + + Updated the code formatting and added some to Ettable. + +------------------------------------------------------------------------------- +Mon Jul 5 23:18:49 CDT 1999 Michael Jennings + + Moved to new CVS server. Small cosmetic change as a test. + +------------------------------------------------------------------------------- +Thu Jul 15 17:06:07 PDT 1999 Michael Jennings + + Don't copy the desktop pixmap unnecessarily. + +------------------------------------------------------------------------------- +Thu Jul 15 19:39:51 PDT 1999 Michael Jennings + + But don't free it if it isn't ours either. =P + +------------------------------------------------------------------------------- +Fri Jul 16 11:05:34 PDT 1999 Michael Jennings + + Hopefully I found the cause of those weird hangs.... + +------------------------------------------------------------------------------- +Tue Jul 20 17:39:01 PDT 1999 Michael Jennings + + Applied two patches from Sung-Hyun Nam for much- + improved multi-byte font support and internationalization. Many + thanks to him for his efforts, and my apologies for taking so long to + get this patch in CVS. + +------------------------------------------------------------------------------- +Tue Jul 20 18:48:31 PDT 1999 Michael Jennings + + Removed lots of code warnings. + +------------------------------------------------------------------------------- +Mon Jul 26 17:25:00 PDT 1999 Michael Jennings + + Eterm has a whole new concept of image color modifiers...basically, + it's now the same as Enlightenment's. Shading and tinting are + gone completely as they were done before (along with the --shade and + --tint options); they've been replaced by this new mechanism which + gives you control over the contrast and gamma correction in addition + to the brightness (the latter being the only thing shading/tinting + messed with before). + + For the uninitiated...basically, each image has up to 4 color + modifiers which can be applied to it -- one for each color (red, + green, and blue) and one for the image as a whole. Each modifier + has three attributes which can be set: brightness, contrast, and + gamma correction (referred to as simply "gamma"). These modifiers + are applied before rendering to alter the appearance of the image. + This can be used to make images darker or lighter to improve text + readability, or to make image details more visible. + + The old escape sequences \e]6;1 (shade) and \e]6;2 (tint) have been + replaced with a single sequence (\e]6;1) which handles all color + modifier changes. The syntax is "\e]6;1;modifier;attribute;value\a". + See the new menu config files for examples. + + Color modifiers for any image can be set in the config file. The + syntax there is "cmod modifier brightness contrast gamma" (e.g., + "cmod image 0xe0 0xff 0xff"). Trailing elements may be omitted, + but leading ones may not (i.e., you may specify the brightness + only without giving a contrast or a gamma, but you cannot specify + the gamma without also giving the brightness and contrast). If you + prefer, you can use "colormod" instead of "cmod" for clarity. + + You also have the --cmod, --cmod-red, --cmod-green, and --cmod-blue + command line options; these follow the same syntax as the config file. + + Hopefully that's clear enough. :-) + +------------------------------------------------------------------------------- +Thu Jul 29 18:23:53 PDT 1999 Michael Jennings + + Thanks to raster's advice, there is no longer a -W (--watch-desktop) + option. That behavior is now the default and exhibits no slowdown + whatsoever. I also cleaned up some silly repetitive bullshit that + should speed things up as well. + +------------------------------------------------------------------------------- +Tue Aug 3 14:31:53 PDT 1999 Michael Jennings + + Fixed a scrollbar bug raster pointed out and added the skeleton of + action classes. + +------------------------------------------------------------------------------- +Tue Aug 3 14:48:48 PDT 1999 Michael Jennings + + Added 3-state support to the background. Well, actually 2-state. :) + +------------------------------------------------------------------------------- +Tue Aug 3 11:34:56 PDT 1999 The Rasterman + + fixed redraw of multi-state background :) + +------------------------------------------------------------------------------- +Thu Aug 5 19:21:49 PDT 1999 Michael Jennings + + Action bindings are now working. See the new theme.cfg files for + examples of how to use them. I've duplicated the old bindings for + Ctrl+Buttons and added the F1 key to bring up the Eterm menu. I'll + customize the themes to take full advantage of this feature soon. + +------------------------------------------------------------------------------- +Fri Aug 6 12:05:35 PDT 1999 Michael Jennings + + Fixed a problem with actions with no valid button/keysym binding. + Some of the action stuff is still having problems, but at least you + can use the Eterms again. :-) + +------------------------------------------------------------------------------- +Fri Aug 6 12:34:33 PDT 1999 Michael Jennings + + Actions should be all fixed now. Keep in mind, however, that some + keybindings may not work the way you expect if you have your X + mappings configured to send different keysyms when the keys are + modified. Check "xmodmap -pk" and "xmodmap -pm". + + Also applied a small XIM patch from Sung-Hyun Nam . + +------------------------------------------------------------------------------- +Tue Aug 17 18:06:01 PDT 1999 Michael Jennings + + Now that we have a fixed CVS server.... This includes the old 0.8.10 + code, but it's now 0.9. It also includes a timer subsystem. + +------------------------------------------------------------------------------- diff --git a/Eterm.spec.in b/Eterm.spec.in index 8c1f213..8d3167a 100644 --- a/Eterm.spec.in +++ b/Eterm.spec.in @@ -1,79 +1,107 @@ -# Note that this is NOT a relocatable package %define ver @VERSION@ -%define rel SNAP -%define prefix /usr +%define rel 1 +%define prefix @prefix@ -Summary: Eterm Enlightened Terminal Emulator for X Windows +Summary: Enlightened terminal emulator Name: Eterm -Version: %ver -Release: %rel +Version: %{ver} +Release: %{rel} Copyright: GPL -Group: X11/Applications -Source: ftp://ftp.enlightenment.org/pub/Eterm/Eterm-%{ver}.tar.gz -BuildRoot: /tmp/Eterm-root -Packager: technoir -URL: http://e.themes.org/ -Requires: imlib >= 1.8 - -Docdir: %{prefix}/doc +Group: Utilities/Terminal +Source: ../SOURCES/Eterm-%{ver}.tar.gz +BuildRoot: /tmp/Eterm-root/ +URL: http://www.eterm.org/ +Requires: imlib, libjpeg, libtiff, libungif, libpng, zlib, XFree86-libs +Packager: Todd Nemanich +%ifarch i386 %description -Eterm is a color vt102 terminal emulator intended as an xterm replacement for users who want a term program integrated with Enlightenment, or simply want a little more "eye candy". Eterm uses Imlib for advanced graphic abilities. +This is an rpm of Eterm, a highly configurable and asethically pleasing +terminal emulator. + +This rpm was optimized for i486 and was built without support +for libKenny.so. +(Egads! They killed Kenny! You bastards!) +%else +%description +This is an rpm of Eterm, a highly configurable and asethically pleasing +terminal emulator. + +This rpm contains no architecture specific optimizations, and +was built without support for libKenny.so. +(Egads! They killed Kenny! You bastards!) +%endif %changelog +* Sun Jun 6 1999 Todd Nemanich +- Updated rpm to incorporate a few fixes for different architectures, +- specify /usr/local/share/Eterm/themes/* as config files, and +- a fix for the share directory problem. -* Wed Dec 30 1998 mej +* Tue Apr 27 1999 Todd Nemanich +- Updated to version 8.9. Added a check to make sure /usr/local/lib +- is in /etc/ld.so.conf because too many people don't know how +- ld works. +- Also moving, so new email address for me. + +* Sat Jan 23 1999 Todd Nemanich +- Updated to version 8.8 -- Added spec file. Created by techn0ir +* Sat Oct 23 1998 Todd Nemanich +- Updated to version 0.8.7. A minor change in the Makefiles was made by hand, +- due to a linkinkg problem. This should not cause problems to people using the +- source rpm, but the call to configure has been removed. +* Mon Sep 21 1998 Todd Nemanich +- Bad link in /usr/local/bin corrected. THX to Andy Dustman for pointing this out. %prep -%setup +rm -fr $RPM_BUILD_ROOT $RPM_BUILD_DIR/Eterm-%{ver} +mkdir $RPM_BUILD_ROOT +cd $RPM_BUILD_DIR +tar -xzf $RPM_SOURCE_DIR/Eterm-%{ver}.tar.gz %build -# Optimize that damned code all the way -if [ ! -z "`echo -n ${RPM_OPT_FLAGS} | grep pentium`" ]; then - if [ ! -z `which egcs` ]; then - CC="egcs" - else - if [ ! -z `which pgcc` ]; then - CC="pgcc" - fi - fi - CFLAGS="${RPM_OPT_FLAGS}" -else - CFLAGS="${RPM_OPT_FLAGS}" -fi -if [ ! -f configure ]; then - CFLAGS="$RPM_OPT_FLAGS" ./autogen.sh --prefix=%prefix -else - CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix -fi - +cd $RPM_BUILD_DIR/Eterm-%{ver} +./configure --prefix=%{prefix} +%ifarch i386 +make "CFLAGS=-O3 -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2" +%else make +%endif %install -rm -rf $RPM_BUILD_ROOT - +cd $RPM_BUILD_DIR/Eterm-%{ver} make prefix=$RPM_BUILD_ROOT%{prefix} install + + +%postinst +LDPATH=`grep local /etc/ld.so.conf` + +if [ "$LDPATH" = "" ] ; then + NEW='/usr/local/lib' + cat /etc/ld.so.conf >ld.tmp + echo "$NEW">>new.ld + cat ld.tmp new.ld > ld.so.conf + mv ld.so.conf /etc/ld.so.conf + rm -f new.ld ld.tmp +fi + +/sbin/ldconfig + %clean -rm -rf $RPM_BUILD_ROOT - -%post - -%postun +rm -fr $RPM_BUILD_ROOT $RPM_BUILD_DIR/Eterm-%{ver} %files -%defattr(-, root, root) - -%{prefix}/bin/* -%(prefix)/doc/* -%{prefix}/lib/* -%{prefix}/share/* -%{prefix}/man/* - - -%doc COPYING -%doc ChangeLog -%doc README +%defattr(-,root,root) +%doc $RPM_BUILD_DIR/Eterm-%{ver}/README +%doc $RPM_BUILD_DIR/Eterm-%{ver}/COPYING +%doc $RPM_BUILD_DIR/Eterm-%{ver}/ChangeLog +%doc $RPM_BUILD_DIR/Eterm-%{ver}/ReleaseNotes +%doc $RPM_BUILD_DIR/Eterm-%{ver}/CVS-README +%doc $RPM_BUILD_DIR/Eterm-%{ver}/doc/* +%doc %{prefix}/man +%config %{prefix}/share/Eterm/themes/ +%{prefix}/bin +%{prefix}/lib diff --git a/Makefile.am b/Makefile.am index 087c5e5..37595e1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,6 +2,6 @@ AUTOMAKE_OPTIONS = foreign -SUBDIRS = libmej src themes utils doc bg +SUBDIRS = libmej src themes utils doc bg pix EXTRA_DIST = README ReleaseNotes CVS-README COPYING ChangeLog autogen.sh diff --git a/acconfig.h b/acconfig.h index c74de7b..19c5077 100644 --- a/acconfig.h +++ b/acconfig.h @@ -270,6 +270,9 @@ /* Do we need our own nanosleep()? */ #undef HAVE_NANOSLEEP +/* Is our snprintf() implementation buggy? */ +#undef HAVE_SNPRINTF_BUG + /* Debugging level */ #undef DEBUG @@ -286,6 +289,29 @@ /* Do we have the X shape extension? */ #undef HAVE_X_SHAPE_EXT +/* Support for various features */ +#undef USE_ACTIVE_TAGS +#undef USE_POSIX_THREADS +#undef MUTEX_SYNCH +#undef PIXMAP_SUPPORT +#undef PIXMAP_OFFSET +#undef BACKING_STORE +#undef FORCE_BACKSPACE +#undef FORCE_DELETE +#undef IMLIB_TRANS +#undef KS_DELETE +#undef NO_DELETE_KEY +#undef NO_XLOCALE +#undef PIXMAP_MENUBAR +#undef PIXMAP_SCROLLBAR +#undef UTMP_SUPPORT +#undef MULTI_CHARSET +#undef USE_XIM +#undef USE_X11R6_XIM +#undef NO_XLOCALE +#undef GREEK_SUPPORT +#undef CONFIG_SEARCH_PATH + /* Leave that blank line there!! Autoheader needs it. If you're adding to this file, keep in mind: diff --git a/autogen.sh b/autogen.sh index c2583dc..b6e7fe7 100755 --- a/autogen.sh +++ b/autogen.sh @@ -4,6 +4,8 @@ DIE=0 +echo "Generating configuration files for Eterm, please wait...." + (autoconf --version) < /dev/null > /dev/null 2>&1 || { echo echo "You must have autoconf installed to compile Eterm." @@ -32,11 +34,16 @@ if test "$DIE" -eq 1; then exit 1 fi +echo " libtoolize --copy --force" libtoolize --copy --force -aclocal $ACLOCAL_FLAGS -automake --add-missing -autoconf +echo " aclocal -I . $ACLOCAL_FLAGS" +aclocal -I . $ACLOCAL_FLAGS +echo " autoheader" autoheader +echo " automake --add-missing" +automake --add-missing +echo " autoconf" +autoconf if [ -x config.status -a -z "$*" ]; then ./config.status --recheck @@ -50,3 +57,10 @@ else fi ./configure "$@" fi + +if [ -f cvs.motd ]; then + echo "ATTENTION CVS Users!" + echo "" + cat cvs.motd + echo "" +fi diff --git a/bg/Makefile.am b/bg/Makefile.am index 70a50dd..8a42d6c 100644 --- a/bg/Makefile.am +++ b/bg/Makefile.am @@ -8,35 +8,45 @@ pixmapdir = $(pkgdatadir)/pix themedir = $(pkgdatadir)/themes all: Makefile - @echo "*** Generating pixmaps.list file from images in tile/ and scale/..." + @echo "*** Generating pixmap list files from images in tile/ and scale/..." @true > pixmaps.list @cd tile ; \ - for i in `ls -1 | grep -v CVS | grep -v \.cvsignore` ; do \ - echo '" 0 0 '$$i'"' >> ../pixmaps.list ; \ + true > tiled-pixmaps.list ; \ + for i in `ls -1 | grep -v CVS | grep -v \.cvsignore | grep -v pixmaps.list` ; do \ + echo $$i >> tiled-pixmaps.list ; \ + echo '"'$$i'@0x0+0+0:tile"' >> ../pixmaps.list ; \ done ; \ cd .. ; \ cd scale ; \ - for i in `ls -1 | grep -v CVS | grep -v \.cvsignore` ; do \ - echo '"-1 -1 '$$i'"' >> ../pixmaps.list ; \ + true > scaled-pixmaps.list ; \ + for i in `ls -1 | grep -v CVS | grep -v \.cvsignore | grep -v pixmaps.list` ; do \ + echo $$i >> scaled-pixmaps.list ; \ + echo '"'$$i'@100x100"' >> ../pixmaps.list ; \ done install-data-hook: @if test ! -f pixmaps.list ; then $(MAKE) all ; fi $(mkinstalldirs) $(DESTDIR)$(pixmapdir) @for j in $(DIRS) ; do echo "Installing pixmaps in $$j" ; cd $$j ; \ - for i in `ls -1 | grep -v CVS | grep -v \.cvsignore` ; do \ + for i in `ls -1 | grep -v CVS | grep -v \.cvsignore | grep -v pixmaps.list` ; do \ echo $(INSTALL_DATA) $$i $(DESTDIR)${pixmapdir} ; \ $(INSTALL_DATA) $$i $(DESTDIR)${pixmapdir} ; \ done ; cd .. ; \ done - @if test -f $(DESTDIR)${pixmapdir}/pixmaps.list ; then \ - $(CP) -p $(DESTDIR)${pixmapdir}/pixmaps.list $(DESTDIR)${pixmapdir}/pixmaps.list.old ; \ - echo "WARNING: Backup of existing pixmaps.list created." ; \ - fi - $(INSTALL_DATA) pixmaps.list $(DESTDIR)${pixmapdir} - @for i in `ls -1d $(DESTDIR)${themedir}/*` ; do \ - if test $$i != "." -a $$i != ".." -a ! -f $$i/pixmaps.list ; then \ - echo "$(LN_S) ../../pix/pixmaps.list $$i/pixmaps.list" ; \ - $(LN_S) ../../pix/pixmaps.list $$i/pixmaps.list ; \ + @for i in tiled-pixmaps.list scaled-pixmaps.list pixmaps.list ; do \ + if test -f $(DESTDIR)${pixmapdir}/$$i ; then \ + $(CP) -p $(DESTDIR)${pixmapdir}/$$i $(DESTDIR)${pixmapdir}/$$i.old ; \ + echo "WARNING: Backup of existing $$i created." ; \ fi ; \ done + $(INSTALL_DATA) tile/tiled-pixmaps.list $(DESTDIR)${pixmapdir} + $(INSTALL_DATA) scale/scaled-pixmaps.list $(DESTDIR)${pixmapdir} + $(INSTALL_DATA) pixmaps.list $(DESTDIR)${pixmapdir} + @for i in `ls -1d $(DESTDIR)${themedir}/*` ; do \ + for j in tiled-pixmaps.list scaled-pixmaps.list pixmaps.list ; do \ + if test $$i != "." -a $$i != ".." -a ! -f $$i/$$j ; then \ + echo "$(LN_S) ../../pix/$$j $$i/$$j" ; \ + $(LN_S) ../../pix/$$j $$i/$$j ; \ + fi ; \ + done ; \ + done diff --git a/configure.in b/configure.in index dd9a6a8..c019ff0 100644 --- a/configure.in +++ b/configure.in @@ -1,12 +1,12 @@ dnl# $Id$ -AC_INIT(src/feature.h.in) -AM_INIT_AUTOMAKE(Eterm, 0.8.9) +AC_INIT(src/feature.h) +AM_INIT_AUTOMAKE(Eterm, 0.9) dnl# Set some basic variables -DATE="21 January 1999" +DATE="`date '+%d %B %Y'`" AC_SUBST(DATE) -AUTHORS="Tuomo Venalainen (vendu@cc.hut.fi) and Michael Jennings (mej@tcserv.com)" +AUTHORS="Tuomo Venalainen (vendu@cc.hut.fi) and Michael Jennings (mej@eterm.org)" AC_SUBST(AUTHORS) dnl# Supply default CFLAGS, if not specified by `CFLAGS=flags ./configure' @@ -139,6 +139,7 @@ AC_TYPE_UID_T dnl# Checks for library functions. AC_TYPE_SIGNAL AC_CHECK_FUNCS(atexit _exit unsetenv setutent seteuid memmove putenv strsep setresuid setresgid memmem usleep snprintf) +dps_snprintf_oflow() dnl# Check for the need for -lutil on BSD systems AC_CHECK_FUNC(login, @@ -153,14 +154,6 @@ AC_CHECK_FUNC(logout, )) AC_CHECK_FUNC(getpwuid, , AC_CHECK_LIB(sun, getpwuid, LIBS="$LIBS -lsun")) -dnl# Check for POSIX threads library -dnl# Don't comment this back in before multithreading actually works, -dnl# so people don't need thread-safe X libs to be able to run unthreaded -dnl# Eterm :) -vendu -#AC_CHECK_LIB(pthread, pthread_create, CFLAGS="$CFLAGS -D_REENTRANT"; -# THREADLIBS="-lpthread", , -# -D_REENTRANT -L/usr/lib -L/lib -L/usr/local/lib) - dnl# Did they want debugging? AC_MSG_CHECKING(for debugging level) AC_ARG_WITH(debugging, [ --with-debugging[=num] enable debugging output, num is an optional level], @@ -178,34 +171,144 @@ AC_ARG_WITH(debugging, [ --with-debugging[=num] enable debugging output, num i AC_DEFINE_UNQUOTED(DEBUG, 4) ) -dnl# Check for support for menus -AC_MSG_CHECKING(whether or not to enable menubar support) -AC_ARG_ENABLE(menus, [ --disable-menus disable support for menubars (support enabled by default)], - if test "$enableval" != "no"; then - echo "yes" ; MENUSED=""; - else echo "no" ; MENUSED='s/define MENUBAR_MAX .*/define MENUBAR_MAX 0/g'; - fi, echo "yes" ; MENUSED="") - -dnl# Check for graphics libraries. -dnl# Force Imlib flags - see below. -vendu -AC_MSG_CHECKING(whether or not to enable pixmap support) +dnl# +dnl# FEATURES +dnl# +AC_MSG_CHECKING(for pixmap support) AC_ARG_WITH(imlib, -[ --with-imlib[=DIR] compile with Imlib support (Imlib residing in DIR/lib) [default] - --without-imlib compile with pixmap support disabled], +[ --with-imlib[=DIR] compile with Imlib support (Imlib residing in DIR/lib) (default)], if test "$withval" != "no"; then - echo "yes" ; CFLAGS="$CFLAGS -I${withval}/include -L${withval}/lib"; - GRLIBS="-lImlib" ; PIXMAPSED=""; - else echo "no" ; PIXMAPSED='s/define PIXMAP_SUPPORT/undef PIXMAP_SUPPORT/g'; - GRLIBS=""; - fi, echo "yes" ; GRLIBS="-lImlib" ; PIXMAPSED="") + AC_MSG_RESULT(yes) + CFLAGS="$CFLAGS -I${withval}/include -L${withval}/lib" + GRLIBS="-lImlib" + AC_DEFINE(PIXMAP_SUPPORT) + AC_DEFINE(PIXMAP_SCROLLBAR) + AC_DEFINE(PIXMAP_MENUBAR) + AC_DEFINE(BACKING_STORE) + else + AC_MSG_RESULT(no) + GRLIBS="" + fi, AC_MSG_RESULT(yes) + GRLIBS="-lImlib" + AC_DEFINE(PIXMAP_SUPPORT) + AC_DEFINE(PIXMAP_SCROLLBAR) + AC_DEFINE(PIXMAP_MENUBAR) + AC_DEFINE(BACKING_STORE) +) +AC_MSG_CHECKING(for transparency support) +AC_ARG_ENABLE(trans, +[ --enable-trans[=imlib] compile with transparency support ("=imlib" will use Imlib instead of Xlib for transparency)], + if test "$enableval" = "imlib"; then + AC_MSG_RESULT(yes, using Imlib) + AC_DEFINE(PIXMAP_OFFSET) + AC_DEFINE(IMLIB_TRANS) + elif test "$enableval" != "no"; then + AC_MSG_RESULT(yes) + AC_DEFINE(PIXMAP_OFFSET) + else + AC_MSG_RESULT(no) + fi, AC_MSG_RESULT(yes) + AC_DEFINE(PIXMAP_OFFSET) +) +AC_MSG_CHECKING(for utmp support) +AC_ARG_ENABLE(utmp, +[ --enable-utmp compile with utmp support], + if test "$enableval" != "no"; then + AC_MSG_RESULT(yes) + AC_DEFINE(UTMP_SUPPORT) + else + AC_MSG_RESULT(no) + fi, AC_MSG_RESULT(yes) + AC_DEFINE(UTMP_SUPPORT) +) +AC_MSG_CHECKING(for backspace key configuration) +AC_ARG_WITH(backspace, +[ --with-backspace=KEY force backspace to send KEY (KEY is either "bs" for ^H or "del" for ^?)], + if test "$withval" = "bs"; then + AC_MSG_RESULT(forcing Backspace to send Ctrl-H) + AC_DEFINE(FORCE_BACKSPACE) + elif test "$withval" = "del"; then + AC_MSG_RESULT(forcing Backspace to send Ctrl-?) + AC_DEFINE(FORCE_DELETE) + else + AC_MSG_RESULT(default) + fi, AC_MSG_RESULT(default) +) +AC_MSG_CHECKING(for delete key configuration) +AC_ARG_WITH(delete, +[ --with-delete=SETTING force delete to SETTING ("server" to use the X server value always or + a quoted string to use a specific string)], + if test "$withval" = "server"; then + AC_MSG_RESULT(X server value) + AC_DEFINE(NO_DELETE_KEY) + else + AC_MSG_RESULT(forcing Delete to send "$withval") + AC_DEFINE_UNQUOTED(KS_DELETE, "$withval") + fi, AC_MSG_RESULT(default) + AC_DEFINE_UNQUOTED(KS_DELETE, "\177") +) +AC_MSG_CHECKING(for multi-charset support) +AC_ARG_ENABLE(multi-charset, +[ --enable-multi-charset compile with multi-charset support], + if test "$enableval" = "yes"; then + AC_MSG_RESULT(yes) + AC_DEFINE(MULTI_CHARSET) + else + AC_MSG_RESULT(no) + fi, AC_MSG_RESULT(no) +) +AC_MSG_CHECKING(for XIM support) +AC_ARG_ENABLE(xim, +[ --enable-xim compile with XIM support], + if test "$enableval" = "yes"; then + AC_MSG_RESULT(yes) + AC_DEFINE(USE_XIM) + XIM="TRUE" + else + AC_MSG_RESULT(no) + XIM="FALSE" + fi, AC_MSG_RESULT(no) +) +AC_MSG_CHECKING(for Greek keyboard support) +AC_ARG_ENABLE(greek, +[ --enable-greek compile with support for Greek keyboards], + if test "$enableval" = "yes"; then + AC_MSG_RESULT(yes) + AC_DEFINE(GREEK_SUPPORT) + else + AC_MSG_RESULT(no) + fi, AC_MSG_RESULT(no) +) +AC_MSG_CHECKING(which threads library to use) +AC_ARG_WITH(threads, +[ --with-threads[=STYLE] compile with threads support, STYLE is either "posix" or blank + (disabled by default)], + case $withval in + [yes | posix )] + AC_MSG_RESULT(POSIX) + THREADS_LIB=posix + ;; + [* )] + AC_MSG_RESULT(none) + ;; + esac + , AC_MSG_RESULT(none)) +if test "$THREADS_LIB" = "posix"; then + AC_CHECK_LIB(pthread, pthread_create, CFLAGS="$CFLAGS -D_REENTRANT" ; THREADLIBS="-lpthread" + AC_DEFINE(USE_POSIX_THREADS) + AC_DEFINE(MUTEX_SYNCH) + , , -D_REENTRANT -L/usr/lib -L/lib -L/usr/local/lib) +fi +dnl# +dnl# X LIBRARIES +dnl# AC_CHECK_LIB(X11, XOpenDisplay, X_LIBS="$X_LIBS -lX11", [ echo "ERROR: You need libX11 to build Eterm. Verify that you have libX11.a or"; echo " libX11.so installed and that it is located in the X libraries"; echo " directory shown above. If it is in a different directory, try using"; echo " the --x-libraries parameter to configure."; AC_MSG_ERROR([Fatal: libX11 not found.])], $X_LIBS $SUBLIBS) - AC_CHECK_LIB(Xext, XextAddDisplay, X_LIBS="-lXext $X_LIBS", [ echo "ERROR: You need libXext to build Eterm. Verify that you have libXext.a or"; echo " libXext.so installed and that it is located in the X libraries"; @@ -215,6 +318,14 @@ echo " the --x-libraries parameter to configure."; AC_CHECK_LIB(Xext, XShapeQueryExtension, AC_DEFINE(HAVE_X_SHAPE_EXT), , $X_LIBS $SUBLIBS) +# check if we need X_LOCALE definition +AC_CHECK_LIB(X11, _Xsetlocale, , AC_DEFINE(NO_XLOCALE), , $X_LIBS $SUBLIBS) + +# check X11R6 for XIM +if test "$XIM" = "TRUE"; then + AC_CHECK_LIB(X11, XRegisterIMInstantiateCallback, AC_DEFINE(USE_X11R6_XIM), , $X_LIBS $SUBLIBS) +fi + if test -z "$PIXMAPSED"; then AC_CHECK_PROG(IMLIB_CONFIG, imlib-config, imlib-config, no) @@ -325,6 +436,8 @@ AC_CHECK_LIB(Kenny, life_signs, , [ ]) fi +AC_DEFINE_UNQUOTED(CONFIG_SEARCH_PATH, "~/.Eterm/themes:~/.Eterm:${prefix}/share/Eterm/themes:${prefix}/share/Eterm") + CFLAGS=${CFLAGS--O} LDFLAGS=${LDFLAGS--O} @@ -338,12 +451,6 @@ AC_SUBST(THREADLIBS) AC_SUBST(GRLIBS) basedir=. -FEATURE_CMD="$SED -e \"s%@PREFIX@%${prefix}%g\" -e \"s%@DATADIR@%${datadir}%g\" -e \"$PIXMAPSED\" -e \"$MENUSED\" "'${DIST_ROOT}'"/src/feature.h.in > "'${DIST_ROOT}'"/src/feature.h" -AC_SUBST(FEATURE_CMD) - -dnl# common parts of the Makefile -dnl# MCOMMON=./Make.common -dnl# AC_SUBST_FILE(MCOMMON) AM_CONFIG_HEADER(config.h) @@ -352,6 +459,7 @@ bg/Makefile \ doc/Makefile \ utils/Makefile \ libmej/Makefile \ +pix/Makefile \ src/Makefile \ src/graphics/Makefile \ themes/Makefile \ @@ -359,29 +467,24 @@ Eterm.spec \ ) dnl If we're not building with Imlib support, don't build Esetroot -if test -n "$PIXMAPSED"; then +if test -z "$GRLIBS"; then sed -e 's/^bin_PROGRAMS.*$//g' doc/Makefile > doc/Makefile.new mv doc/Makefile.new doc/Makefile fi -echo "creating src/feature.h" -eval ${FEATURE_CMD}.new -if cmp -s ${DIST_ROOT}/src/feature.h.new ${DIST_ROOT}/src/feature.h 2>/dev/null ; then - echo "feature.h is unchanged" - rm -f ${DIST_ROOT}/src/feature.h.new -else - mv ${DIST_ROOT}/src/feature.h.new ${DIST_ROOT}/src/feature.h -fi - echo " +$PACKAGE $VERSION Configuration: +-------------- Source code location: ${srcdir} Compiler: ${CC} ${CFLAGS} Host System Type: ${host} Graphics libraries: ${GRLIBS} - X Windows libs/paths: ${X_LIBS} + X libraries/paths: ${X_LIBS} Install path: ${prefix} - See src/feature.h for further configuration information." -echo + See src/feature.h for further configuration information. + + Now type 'make' to build $PACKAGE $VERSION. +" diff --git a/cvs.motd b/cvs.motd new file mode 100644 index 0000000..e4ee510 --- /dev/null +++ b/cvs.motd @@ -0,0 +1,3 @@ +Yet another change to the Eterm theme files. Shading and tinting as +you remember them no longer exist. Please update your Eterm theme +files, or stuff will not work. See the ChangeLog for details! diff --git a/doc/Eterm.1.in b/doc/Eterm.1.in index e23f892..8d73334 100644 --- a/doc/Eterm.1.in +++ b/doc/Eterm.1.in @@ -1249,7 +1249,7 @@ directive to allow for separation of the configuration information into separate files. .SH AUTHORS -Tuomo Venalainen (vendu@cc.hut.fi) and Michael Jennings (mej@tcserv.com). +Michael Jennings (mej@eterm.org) and Tuomo Venäläinen (vendu@cc.hut.fi). Man page re-written for version 0.8 by Shaleh (shaleh@debian.org). .SH URL(s) diff --git a/doc/FAQ.html b/doc/FAQ.html index 69a635d..b958628 100644 --- a/doc/FAQ.html +++ b/doc/FAQ.html @@ -450,7 +450,7 @@ If you run into problems with Eterm, please go through the steps outlined
  1. Comment out line 41 of src/feature.h where NDEBUG is defined.
  2. Recompile Eterm. -
  3. Run the new copy of Eterm and mail the output to me (mej@tcserv.com). +
  4. Run the new copy of Eterm and mail the output to me (mej@eterm.org).
This is the only way we can get the information we need about where the program is when it runs into problems, or what privileges it has, or diff --git a/libmej/Makefile.am b/libmej/Makefile.am index 2ae3dd2..8ed28ba 100644 --- a/libmej/Makefile.am +++ b/libmej/Makefile.am @@ -6,7 +6,7 @@ libmej_la_SOURCES = debug.c mem.c strings.c snprintf.c INCLUDES = -I. -I.. -I$(includedir) -I$(prefix)/include -libmej_la_LDFLAGS = -version-info 8:9:8 +libmej_la_LDFLAGS = -version-info 9:0:9 EXTRA_DIST = debug.h global.h mem.h strings.h strptime.h strptime.c diff --git a/libmej/debug.c b/libmej/debug.c index 845d34c..947b708 100644 --- a/libmej/debug.c +++ b/libmej/debug.c @@ -4,7 +4,7 @@ * -- 20 December 1996 * *********************************************************/ /* - * This file is original work by Michael Jennings . + * This file is original work by Michael Jennings . * * Copyright (C) 1997, Michael Jennings * @@ -26,6 +26,9 @@ static const char cvs_ident[] = "$Id$"; +#include "config.h" +#include "../src/feature.h" + #include "global.h" #include #include @@ -36,7 +39,6 @@ static const char cvs_ident[] = "$Id$"; #include #include #include -#define DEBUG_C #include "debug.h" int @@ -47,8 +49,7 @@ real_dprintf(const char *format,...) int n; va_start(args, format); - n = fprintf(stderr, "[debug] "); - n += vfprintf(stderr, format, args); + n = vfprintf(stderr, format, args); va_end(args); fflush(stderr); return (n); diff --git a/libmej/debug.h b/libmej/debug.h index d96afdb..9f02901 100644 --- a/libmej/debug.h +++ b/libmej/debug.h @@ -4,7 +4,7 @@ * -- 20 December 1996 * **********************************************************/ /* - * This file is original work by Michael Jennings . + * This file is original work by Michael Jennings . * * Copyright (C) 1997, Michael Jennings * @@ -24,13 +24,11 @@ * */ -#if !defined(DEBUG_C) && !defined(DEBUG_CC) - extern int real_dprintf(const char *, ...); -#endif - #ifndef _LIBMEJ_DEBUG_H # define _LIBMEJ_DEBUG_H +extern int real_dprintf(const char *, ...); + #include "../src/debug.h" #endif /* _LIBMEJ_DEBUG_H */ diff --git a/libmej/global.h b/libmej/global.h index 2a6077b..1d94c86 100644 --- a/libmej/global.h +++ b/libmej/global.h @@ -4,7 +4,7 @@ * -- 16 January 1997 * ***************************************************************/ /* - * This file is original work by Michael Jennings . + * This file is original work by Michael Jennings . * * Copyright (C) 1997, Michael Jennings * @@ -28,9 +28,6 @@ #define _GLOBAL_H_ -#include "config.h" -#include "src/feature.h" - /* Other compile-time defines */ #ifdef LINUX # define _GNU_SOURCE diff --git a/libmej/mem.c b/libmej/mem.c index 97550fc..f44c2fb 100644 --- a/libmej/mem.c +++ b/libmej/mem.c @@ -5,7 +5,7 @@ * -- 07 January 1997 * ***************************************************************/ /* - * This file is original work by Michael Jennings . + * This file is original work by Michael Jennings . * * Copyright (C) 1997, Michael Jennings * @@ -27,6 +27,9 @@ static const char cvs_ident[] = "$Id$"; +#include "config.h" +#include "../src/feature.h" + #include "global.h" #include #include @@ -35,7 +38,7 @@ static const char cvs_ident[] = "$Id$"; #include #include #include -#define MEM_C + #include "debug.h" #include "mem.h" @@ -44,12 +47,11 @@ static const char cvs_ident[] = "$Id$"; * The beginning of each one's respective function. (The ones with capitalized * letters. I'm not sure that they'll be useful outside of gdb. Maybe. */ -#if DEBUG >= DEBUG_MALLOC +#ifdef MALLOC_CALL_DEBUG static int malloc_count = 0; static int calloc_count = 0; static int realloc_count = 0; static int free_count = 0; - #endif MemRec memrec = @@ -240,38 +242,26 @@ void * Malloc(size_t size) { -#if 0 - char *temp = NULL; - -#endif void *temp = NULL; -#if DEBUG >= DEBUG_MALLOC - ++malloc_count; #ifdef MALLOC_CALL_DEBUG + ++malloc_count; if (!(malloc_count % MALLOC_MOD)) { fprintf(stderr, "Calls to malloc(): %d\n", malloc_count); } #endif -#endif - -#if DEBUG >= DEBUG_MALLOC if (!memrec.init) { D_MALLOC(("WARNING: You must call memrec_init() before using the libmej memory management calls.\n")); memrec_init(); } -#endif -#if 0 - temp = (char *) malloc(size); -#endif - temp = malloc(size); + temp = (void *) malloc(size); if (!temp) return NULL; -#if DEBUG >= DEBUG_MALLOC - memrec_add_var(temp, size); -#endif + if (debug_level >= DEBUG_MALLOC) { + memrec_add_var(temp, size); + } return (temp); } @@ -279,33 +269,27 @@ void * Realloc(void *ptr, size_t size) { - char *temp = NULL; + void *temp = NULL; -#if DEBUG >= DEBUG_MALLOC +#ifdef MALLOC_CALL_DEBUG ++realloc_count; -# ifdef MALLOC_CALL_DEBUG if (!(realloc_count % REALLOC_MOD)) { fprintf(stderr, "Calls to realloc(): %d\n", realloc_count); } -# endif #endif -/* - * Redundant. You know the drill :) - * #if DEBUG >= DEBUG_MALLOC - */ + if (!memrec.init) { D_MALLOC(("WARNING: You must call memrec_init() before using the libmej memory management calls.\n")); memrec_init(); } -/* #endif */ if (ptr == NULL) { - temp = (char *) Malloc(size); + temp = (void *) Malloc(size); } else { - temp = (char *) realloc(ptr, size); -#if DEBUG >= DEBUG_MALLOC - memrec_chg_var(ptr, temp, size); -#endif + temp = (void *) realloc(ptr, size); + if (debug_level >= DEBUG_MALLOC) { + memrec_chg_var(ptr, temp, size); + } } if (!temp) return NULL; @@ -318,27 +302,22 @@ Calloc(size_t count, size_t size) char *temp = NULL; -#if DEBUG >= DEBUG_MALLOC - ++calloc_count; #ifdef MALLOC_CALL_DEBUG + ++calloc_count; if (!(calloc_count % CALLOC_MOD)) { fprintf(stderr, "Calls to calloc(): %d\n", calloc_count); } #endif -#endif - -#if DEBUG >= DEBUG_MALLOC if (!memrec.init) { D_MALLOC(("WARNING: You must call memrec_init() before using the libmej memory management calls.\n")); memrec_init(); } -#endif temp = (char *) calloc(count, size); -#if DEBUG >= DEBUG_MALLOC - memrec_add_var(temp, size * count); -#endif + if (debug_level >= DEBUG_MALLOC) { + memrec_add_var(temp, size * count); + } if (!temp) return NULL; return (temp); @@ -348,25 +327,22 @@ void Free(void *ptr) { -#if DEBUG >= DEBUG_MALLOC - ++free_count; #ifdef MALLOC_CALL_DEBUG + ++free_count; if (!(free_count % FREE_MOD)) { fprintf(stderr, "Calls to free(): %d\n", free_count); } #endif -#endif -#if DEBUG >= DEBUG_MALLOC + if (!memrec.init) { D_MALLOC(("WARNING: You must call memrec_init() before using the libmej memory management calls.\n")); memrec_init(); } -#endif if (ptr) { -#if DEBUG >= DEBUG_MALLOC - memrec_rem_var(ptr); -#endif + if (debug_level >= DEBUG_MALLOC) { + memrec_rem_var(ptr); + } free(ptr); } else { D_MALLOC(("Caught attempt to free NULL pointer\n")); @@ -384,12 +360,12 @@ HandleSigSegv(int sig) /* Recursive seg faults are not cool.... */ if (segv_again) { - printf("RECURSIVE SEGMENTATION FAULT DETECTED!\n"); + printf("Recursive segmentation fault detected!\n"); _exit(EXIT_FAILURE); } segv_again = 1; #if DEBUG >= DEBUG_MALLOC - fprintf(stderr, "SEGMENTATION FAULT! DUMPING MEMORY TABLE\n"); + fprintf(stderr, "Fatal memory fault (%d)! Dumping memory table.\n", sig); memrec_dump(); #endif exit(EXIT_FAILURE); diff --git a/libmej/mem.h b/libmej/mem.h index 3ab5226..fa6c3d3 100644 --- a/libmej/mem.h +++ b/libmej/mem.h @@ -4,7 +4,7 @@ * -- 07 January 1997 * ***************************************************************/ /* - * This file is original work by Michael Jennings . + * This file is original work by Michael Jennings . * * Copyright (C) 1997, Michael Jennings * @@ -41,12 +41,12 @@ typedef struct memrec_struct { # define CALLOC(type,n) calloc((n),(sizeof(type))) # define REALLOC(mem,sz) fixed_realloc((mem),(sz)) # define FREE(ptr) free(ptr) -#elif defined(DEBUG) || !defined(NDEBUG) +#elif (DEBUG >= DEBUG_MALLOC) # define MALLOC(sz) Malloc(sz) # define CALLOC(type,n) Calloc((n),(sizeof(type))) # define REALLOC(mem,sz) Realloc((mem),(sz)) /* # define FREE(ptr) Free(ptr) */ -# define FREE(ptr) { Free(ptr); ptr = NULL; } +# define FREE(ptr) do { Free(ptr); ptr = NULL; } while(0) # define MALLOC_MOD 25 # define REALLOC_MOD 25 # define CALLOC_MOD 25 @@ -58,15 +58,13 @@ typedef struct memrec_struct { # define FREE(ptr) free(ptr) #endif -#ifndef MEM_C - extern char *SafeStr(char *, unsigned short); extern MemRec memrec; extern void memrec_init(void); -void memrec_add_var(void *, size_t); -void memrec_rem_var(void *); -void memrec_chg_var(void *, void *, size_t); -void memrec_dump(void); +extern void memrec_add_var(void *, size_t); +extern void memrec_rem_var(void *); +extern void memrec_chg_var(void *, void *, size_t); +extern void memrec_dump(void); extern void *Malloc(size_t); extern void *Realloc(void *, size_t); extern void *Calloc(size_t, size_t); @@ -76,7 +74,6 @@ extern void HandleSigSegv(int); extern char *GarbageCollect(char *, size_t); extern char *FileGarbageCollect(char *, size_t); extern void *fixed_realloc(void *, size_t); -#endif /* MEM_C */ #endif /* _MEM_H_ */ diff --git a/libmej/snprintf.c b/libmej/snprintf.c index 6d351e9..80635ae 100644 --- a/libmej/snprintf.c +++ b/libmej/snprintf.c @@ -1,3 +1,6 @@ +#include "config.h" +#include "../src/feature.h" + #include "global.h" #include @@ -13,7 +16,7 @@ static const char cvs_ident[] = "$Id$"; * junk.... */ -#ifndef HAVE_SNPRINTF +#if !defined(HAVE_SNPRINTF) || (HAVE_SNPRINTF_BUG == 1) #ifdef HAVE_STDARG_H #include diff --git a/libmej/strings.c b/libmej/strings.c index d2b88f8..f712641 100644 --- a/libmej/strings.c +++ b/libmej/strings.c @@ -4,7 +4,7 @@ * -- 08 January 1997 * ***************************************************************/ /* - * This file is original work by Michael Jennings . + * This file is original work by Michael Jennings . * * Copyright (C) 1997, Michael Jennings * @@ -26,6 +26,9 @@ static const char cvs_ident[] = "$Id$"; +#include "config.h" +#include "../src/feature.h" + #include "global.h" #include #include @@ -38,7 +41,6 @@ static const char cvs_ident[] = "$Id$"; #include #include "debug.h" #include "mem.h" -#define STRINGS_C #include "strings.h" #ifndef HAVE_MEMMEM @@ -51,7 +53,7 @@ memmem(void *haystack, register size_t haystacklen, void *needle, register size_ register char *hs = (char *) haystack; register char *n = (char *) needle; register unsigned long i; - register len = haystacklen - needlelen; + register size_t len = haystacklen - needlelen; for (i = 0; i < len; i++) { if (!memcmp(hs + i, n, needlelen)) { @@ -396,6 +398,19 @@ StrRev(register char *str) } +char * +StrDup(register const char *str) +{ + + register char *newstr; + register unsigned long len; + + len = strlen(str) + 1; /* Copy NUL byte also */ + newstr = (char *) MALLOC(len); + memcpy(newstr, str, len); + return (newstr); +} + #if !(HAVE_STRSEP) char * strsep(char **str, register char *sep) @@ -404,7 +419,7 @@ strsep(char **str, register char *sep) register char *s = *str; char *sptr; - D_STRINGS(("StrSep(%s, %s) called.\n", *str, sep)); + D_STRINGS(("strsep(%s, %s) called.\n", *str, sep)); sptr = s; for (; *s && !strchr(sep, *s); s++); if (!*s) { diff --git a/libmej/strings.h b/libmej/strings.h index 342565c..bd97eca 100644 --- a/libmej/strings.h +++ b/libmej/strings.h @@ -4,7 +4,7 @@ * -- 08 January 1997 * ***************************************************************/ /* - * This file is original work by Michael Jennings . + * This file is original work by Michael Jennings . * * Copyright (C) 1997, Michael Jennings * @@ -66,15 +66,15 @@ # include #endif -#ifndef STRINGS_C extern char *LeftStr(const char *, unsigned long); extern char *MidStr(const char *, unsigned long, unsigned long); extern char *RightStr(const char *, unsigned long); #if defined(HAVE_REGEX_H) || defined(IRIX) extern unsigned char Match(const char *, const char *); #endif -extern char *Word(unsigned long index, const char *str); -extern char *PWord(unsigned long index, char *str); +extern char *Word(unsigned long, const char *); +extern char *PWord(unsigned long, char *); +extern unsigned long NumWords(const char *); extern char *StripWhitespace(char *); extern char *LowerStr(char *); extern char *UpStr(char *); @@ -82,6 +82,7 @@ extern char *StrCaseStr(char *, const char *); extern char *StrCaseChr(char *, char); extern char *StrCasePBrk(char *, char *); extern char *StrRev(char *); +extern char *StrDup(const char *); #if !(HAVE_STRSEP) extern char *strsep(char **, char *); #endif @@ -101,6 +102,5 @@ extern void usleep(unsigned long); extern void nanosleep(unsigned long); #endif */ -#endif #endif /* _STRINGS_H_ */ diff --git a/libmej/strptime.c b/libmej/strptime.c index 6440e95..a1dff9e 100644 --- a/libmej/strptime.c +++ b/libmej/strptime.c @@ -5,7 +5,7 @@ * -- 2 April 1997 * ***************************************************************/ /* - * This file is original work by Michael Jennings . + * This file is original work by Michael Jennings . * * Copyright (C) 1997, Michael Jennings * @@ -29,12 +29,14 @@ static const char cvs_ident[] = "$Id$"; #ifdef IRIX +#include "config.h" +#include "../src/feature.h" + #include "global.h" #include #include #include #include -#define STRPTIME_C #include "strptime.h" char * diff --git a/libmej/strptime.h b/libmej/strptime.h index 888dd7c..ab241c1 100644 --- a/libmej/strptime.h +++ b/libmej/strptime.h @@ -4,7 +4,7 @@ * -- 2 April 1997 * ***************************************************************/ /* - * This file is original work by Michael Jennings . + * This file is original work by Michael Jennings . * * Copyright (C) 1997, Michael Jennings * @@ -63,14 +63,6 @@ static DTMap USMap = { "PM" }; -#ifndef STRPTIME_C -# ifdef __cplusplus -extern "C" { -# else -extern { -# endif - extern char *strptime(char *, const char *, struct tm *); -} -#endif +extern char *strptime(char *, const char *, struct tm *); #endif /* _STRPTIME_H_ */ diff --git a/pix/.cvsignore b/pix/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/pix/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/pix/Makefile.am b/pix/Makefile.am new file mode 100644 index 0000000..fb0f226 --- /dev/null +++ b/pix/Makefile.am @@ -0,0 +1,14 @@ +# $Id$ + +EXTRA_DIST = bar_horizontal_1.png bar_horizontal_2.png bar_horizontal_3.png bar_vertical_1.png bar_vertical_2.png \ + bar_vertical_3.png button_arrow_down_1.png button_arrow_down_2.png button_arrow_down_3.png \ + button_arrow_up_1.png button_arrow_up_2.png button_arrow_up_3.png menu1.png menu2.png menu3.png + +pixmapdir = $(pkgdatadir)/pix + +install-data-hook: + $(mkinstalldirs) $(DESTDIR)$(pixmapdir) + @for i in $(EXTRA_DIST) ; do \ + echo $(INSTALL_DATA) $$i $(DESTDIR)${pixmapdir} ; \ + $(INSTALL_DATA) $$i $(DESTDIR)${pixmapdir} ; \ + done diff --git a/pix/bar_horizontal_1.png b/pix/bar_horizontal_1.png new file mode 100644 index 0000000..c607c80 Binary files /dev/null and b/pix/bar_horizontal_1.png differ diff --git a/pix/bar_horizontal_2.png b/pix/bar_horizontal_2.png new file mode 100644 index 0000000..a14618b Binary files /dev/null and b/pix/bar_horizontal_2.png differ diff --git a/pix/bar_horizontal_3.png b/pix/bar_horizontal_3.png new file mode 100644 index 0000000..c03719d Binary files /dev/null and b/pix/bar_horizontal_3.png differ diff --git a/pix/bar_vertical_1.png b/pix/bar_vertical_1.png new file mode 100644 index 0000000..c2e67c5 Binary files /dev/null and b/pix/bar_vertical_1.png differ diff --git a/pix/bar_vertical_2.png b/pix/bar_vertical_2.png new file mode 100644 index 0000000..fa8d29d Binary files /dev/null and b/pix/bar_vertical_2.png differ diff --git a/pix/bar_vertical_3.png b/pix/bar_vertical_3.png new file mode 100644 index 0000000..142e315 Binary files /dev/null and b/pix/bar_vertical_3.png differ diff --git a/pix/button_arrow_down_1.png b/pix/button_arrow_down_1.png new file mode 100644 index 0000000..f463b87 Binary files /dev/null and b/pix/button_arrow_down_1.png differ diff --git a/pix/button_arrow_down_2.png b/pix/button_arrow_down_2.png new file mode 100644 index 0000000..9cdf303 Binary files /dev/null and b/pix/button_arrow_down_2.png differ diff --git a/pix/button_arrow_down_3.png b/pix/button_arrow_down_3.png new file mode 100644 index 0000000..e7fda96 Binary files /dev/null and b/pix/button_arrow_down_3.png differ diff --git a/pix/button_arrow_up_1.png b/pix/button_arrow_up_1.png new file mode 100644 index 0000000..b9d76d6 Binary files /dev/null and b/pix/button_arrow_up_1.png differ diff --git a/pix/button_arrow_up_2.png b/pix/button_arrow_up_2.png new file mode 100644 index 0000000..d76985f Binary files /dev/null and b/pix/button_arrow_up_2.png differ diff --git a/pix/button_arrow_up_3.png b/pix/button_arrow_up_3.png new file mode 100644 index 0000000..016e869 Binary files /dev/null and b/pix/button_arrow_up_3.png differ diff --git a/pix/menu1.png b/pix/menu1.png new file mode 100644 index 0000000..3c75544 Binary files /dev/null and b/pix/menu1.png differ diff --git a/pix/menu2.png b/pix/menu2.png new file mode 100644 index 0000000..d69251e Binary files /dev/null and b/pix/menu2.png differ diff --git a/pix/menu3.png b/pix/menu3.png new file mode 100644 index 0000000..d1a8bd0 Binary files /dev/null and b/pix/menu3.png differ diff --git a/src/Makefile.am b/src/Makefile.am index 429a74b..1d2f4f2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,29 +2,22 @@ lib_LTLIBRARIES = libEterm.la -libEterm_la_SOURCES = activeconfig.c activeeterm.c activetags.c command.c \ - graphics.c grkelot.c menubar.c misc.c netdisp.c options.c \ - pixmap.c screen.c scrollbar.c system.c threads.c utmp.c +libEterm_la_SOURCES = actions.c command.c e.c events.c graphics.c grkelot.c menus.c misc.c netdisp.c \ + options.c pixmap.c screen.c scrollbar.c system.c term.c threads.c timer.c utmp.c windows.c -libEterm_la_LDFLAGS = -version-info 8:9:8 +libEterm_la_LDFLAGS = -version-info 9:0:9 bin_PROGRAMS = Eterm Eterm_SOURCES = main.c -Eterm_DEPENDENCIES = ../libmej/libmej.la feature.h +Eterm_DEPENDENCIES = libEterm.la ../libmej/libmej.la feature.h -INCLUDES = -I. -I../libmej -I.. -I$(includedir) -I$(prefix)/include $(X_CFLAGS) +INCLUDES = -I. -I$(top_srcdir)/libmej -I.. -I$(includedir) -I$(prefix)/include $(X_CFLAGS) Eterm_LDFLAGS = -rpath $(libdir):$(pkglibdir) LDADD = -L$(DIST_ROOT)/src/.libs -lEterm -L$(DIST_ROOT)/libmej/.libs -L$(libdir) -L$(prefix)/lib $(LIBS) -lmej $(GRLIBS) $(X_LIBS) -EXTRA_DIST = activeconfig.h activeeterm.h activetags.h command.h debug.h \ - eterm_imlib.h feature.h.in graphics.h grkelot.h grx.h main.h \ - menubar.h misc.h options.h pixmap.h profile.h screen.h scrollbar.h \ - system.h threads.h graphics/Makefile.am graphics/Makefile.in \ - graphics/README graphics/data graphics/grxlib.c graphics/grxlib.h \ - graphics/qplot.c Eterm.xpm - -feature.h: feature.h.in - $(FEATURE_CMD) +EXTRA_DIST = actions.h command.h debug.h e.h eterm_utmp.h events.h feature.h graphics.h grkelot.h grx.h main.h menus.h misc.h \ + options.h pixmap.h profile.h screen.h scrollbar.h system.h term.h threads.h timer.h windows.h graphics/Makefile.am \ + graphics/Makefile.in graphics/README graphics/data graphics/grxlib.c graphics/grxlib.h graphics/qplot.c Eterm.xpm diff --git a/src/actions.c b/src/actions.c new file mode 100644 index 0000000..091142c --- /dev/null +++ b/src/actions.c @@ -0,0 +1,158 @@ +/* actions.c -- Eterm action class module + * -- 3 August 1999, mej + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1999-1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +static const char cvs_ident[] = "$Id$"; + +#include "config.h" +#include "feature.h" + +#include +#include +#include +#include + +#include "../libmej/debug.h" +#include "../libmej/strings.h" +#include "debug.h" +#include "main.h" +#include "mem.h" +#include "strings.h" +#include "actions.h" +#include "command.h" +#include "e.h" +#include "events.h" +#include "graphics.h" +#include "menus.h" +#include "options.h" +#include "pixmap.h" +#include "screen.h" +#include "scrollbar.h" +#include "term.h" +#include "windows.h" + +action_t *action_list = NULL; + +unsigned char +action_handle_string(event_t *ev, action_t *action) { + REQUIRE_RVAL(action->param.string != NULL, 0); + cmd_write(action->param.string, strlen(action->param.string)); + return 1; +} + +unsigned char +action_handle_echo(event_t *ev, action_t *action) { + REQUIRE_RVAL(action->param.string != NULL, 0); + tt_write(action->param.string, strlen(action->param.string)); + return 1; +} + +unsigned char +action_handle_menu(event_t *ev, action_t *action) { + REQUIRE_RVAL(action->param.menu != NULL, 0); + menu_invoke(ev->xbutton.x, ev->xbutton.y, TermWin.parent, action->param.menu, ev->xbutton.time); + return 1; +} + +unsigned char +action_dispatch(event_t *ev, KeySym keysym) { + + action_t *action; + + ASSERT(ev != NULL); + for (action = action_list; action; action = action->next) { + D_ACTIONS(("Checking action. mod == 0x%08x, button == %d, keysym == 0x%08x\n", action->mod, action->button, action->keysym)); + if (ev->xany.type == ButtonPress) { + if ((action->button == BUTTON_NONE) || ((action->button != BUTTON_ANY) && (action->button != ev->xbutton.button))) { + continue; + } + } else if (action->button != BUTTON_NONE) { + continue; + } + D_ACTIONS(("Button passed.\n")); + if (action->mod != MOD_ANY) { + if (LOGICAL_XOR((action->mod & MOD_SHIFT), (ev->xkey.state & ShiftMask))) { + continue; + } + if (LOGICAL_XOR((action->mod & MOD_CTRL), (ev->xkey.state & ControlMask))) { + continue; + } + if (LOGICAL_XOR((action->mod & MOD_LOCK), (ev->xkey.state & LockMask))) { + continue; + } + if (LOGICAL_XOR((action->mod & MOD_MOD1), (ev->xkey.state & Mod1Mask))) { + continue; + } + if (LOGICAL_XOR((action->mod & MOD_MOD2), (ev->xkey.state & Mod2Mask))) { + continue; + } + if (LOGICAL_XOR((action->mod & MOD_MOD3), (ev->xkey.state & Mod3Mask))) { + continue; + } + if (LOGICAL_XOR((action->mod & MOD_MOD4), (ev->xkey.state & Mod4Mask))) { + continue; + } + if (LOGICAL_XOR((action->mod & MOD_MOD5), (ev->xkey.state & Mod5Mask))) { + continue; + } + } + D_ACTIONS(("Modifiers passed. keysym == 0x%08x, action->keysym == 0x%08x\n", keysym, action->keysym)); + if ((keysym) && (action->keysym) && (keysym != action->keysym)) { + continue; + } + D_ACTIONS(("Match found.\n")); + /* If we've passed all the above tests, it's a match. Dispatch the handler. */ + return ((action->handler)(ev, action)); + } + return (0); + +} + +void +action_add(unsigned short mod, unsigned char button, KeySym keysym, action_type_t type, void *param) { + + static action_t *action; + + if (!action_list) { + action_list = (action_t *) MALLOC(sizeof(action_t)); + action = action_list; + } else { + action->next = (action_t *) MALLOC(sizeof(action_t)); + action = action->next; + } + action->mod = mod; + action->button = button; + action->type = type; + action->keysym = keysym; + switch(type) { + case ACTION_STRING: action->handler = (action_handler_t) action_handle_string; action->param.string = StrDup((char *) param); break; + case ACTION_ECHO: action->handler = (action_handler_t) action_handle_echo; action->param.string = StrDup((char *) param); break; + case ACTION_MENU: action->handler = (action_handler_t) action_handle_menu; action->param.menu = (menu_t *) param; break; + default: break; + } + action->next = NULL; + D_ACTIONS(("Added action. mod == 0x%08x, button == %d, keysym == 0x%08x\n", action->mod, action->button, action->keysym)); +} + diff --git a/src/actions.h b/src/actions.h new file mode 100644 index 0000000..0813a12 --- /dev/null +++ b/src/actions.h @@ -0,0 +1,92 @@ +/* actions.h -- Eterm action class module header file + * -- 3 August 1999, mej + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1999-1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _ACTIONS_H_ +#define _ACTIONS_H_ + +#include +#include /* Xlib, Xutil, Xresource, Xfuncproto */ + +#include "events.h" +#include "menus.h" + +/************ Macros and Definitions ************/ +typedef enum { + ACTION_NONE = 0, + ACTION_STRING, + ACTION_ECHO, + ACTION_MENU +} action_type_t; + +#define KEYSYM_NONE (0UL) + +#define MOD_NONE (0UL) +#define MOD_CTRL (1UL << 0) +#define MOD_SHIFT (1UL << 1) +#define MOD_LOCK (1UL << 2) +#define MOD_MOD1 (1UL << 3) +#define MOD_MOD2 (1UL << 4) +#define MOD_MOD3 (1UL << 5) +#define MOD_MOD4 (1UL << 6) +#define MOD_MOD5 (1UL << 7) +#define MOD_ANY (1UL << 8) + +#define BUTTON_NONE (0) +#define BUTTON_ANY (0xff) + +#define LOGICAL_XOR(a, b) !(((a) && (b)) || (!(a) && !(b))) + +/************ Structures ************/ +typedef struct action_struct action_t; +typedef unsigned char (*action_handler_t) (event_t *, action_t *); +struct action_struct { + unsigned short mod; + unsigned char button; + KeySym keysym; + action_type_t type; + action_handler_t handler; + union { + char *string; + menu_t *menu; + } param; + struct action_struct *next; +}; + +/************ Variables ************/ +extern action_t *action_list; + +/************ Function Prototypes ************/ +_XFUNCPROTOBEGIN + +extern unsigned char action_handle_string(event_t *ev, action_t *action); +extern unsigned char action_handle_echo(event_t *ev, action_t *action); +extern unsigned char action_handle_menu(event_t *ev, action_t *action); +extern unsigned char action_dispatch(event_t *ev, KeySym keysym); +extern void action_add(unsigned short mod, unsigned char button, KeySym keysym, action_type_t type, void *param); + +_XFUNCPROTOEND + +#endif /* _ACTIONS_H_ */ diff --git a/src/activeconfig.c b/src/activeconfig.c deleted file mode 100644 index 902798c..0000000 --- a/src/activeconfig.c +++ /dev/null @@ -1,623 +0,0 @@ -/*--------------------------------*-C-*---------------------------------* - * File: activeconfig.c - * - * Copyright 1997 Nat Friedman, Massachusetts Institute of Technology - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - *----------------------------------------------------------------------*/ - -/* This file contains all the config file parsing functionality */ - -static const char cvs_ident[] = "$Id$"; - -#include "feature.h" -#ifdef USE_ACTIVE_TAGS - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "activeconfig.h" - -/* The basic design of the config file parsing routines revolves around the - dispatch table below. The dispatch table relates file tokens with - their parsing functions. In order to add a new config file token - (for example "Foo=something"), simply define TAG_CONFIG_FOO, write - parse_config_tag_foo, and then add the following line to the dispatch - table: - - {TAG_CONFIG_FOO, parse_config_tag_foo} - - and it will magically work. */ - -/* This is the actual dispatch table. It should be terminated by a struct - config_entry whose parser field is NULL. */ -struct config_entry config_dispatch[] = -{ - {TAG_CONFIG_LOAD, parse_config_load}, - {TAG_CONFIG_DEFAULT_BINDING, parse_config_default_binding}, - {TAG_CONFIG_DEFAULT_HIGHLIGHT, parse_config_default_highlight}, - {TAG_CONFIG_DEFAULT_SEARCH_LINES, parse_config_default_search_lines}, - {TAG_CONFIG_NEW_TAG, parse_config_tag_begin}, - {TAG_CONFIG_END_TAG, parse_config_tag_end}, - {TAG_CONFIG_LATENT, parse_config_tag_latent}, - {TAG_CONFIG_BINDING, parse_config_tag_binding}, - {TAG_CONFIG_HIGHLIGHT, parse_config_tag_highlight}, - {TAG_CONFIG_MODES, parse_config_tag_modes}, - {TAG_CONFIG_REGEXP, parse_config_tag_regexp}, - {TAG_CONFIG_ACTION, parse_config_tag_action}, - {TAG_CONFIG_OUTPUT, parse_config_tag_output}, - {TAG_CONFIG_SEARCH_LINES, parse_config_tag_search_lines}, - {TAG_CONFIG_CLUE, parse_config_tag_clue}, - {TAG_CONFIG_ENV, parse_config_tag_env}, - {"", NULL} -}; - -/* - Dispatch Functions - */ - -int -parse_config_tag_env(char *envlist, struct config_info *config_info) -{ - char *p, *q; - int nenvs = 0; - - p = envlist; - do { - printf("Env...\n"); - if ((q = strchr(p, ',')) == NULL) - q = p + strlen(p); - strncpy(tag[config_info->curr_tag].env[nenvs], p, q - p); - tag[config_info->curr_tag].env[nenvs][q - p] = '\0'; - printf("got env: %s\n", tag[config_info->curr_tag].env[nenvs]); - nenvs++; - if (*q != ',') - p = NULL; - else - p = q + 1; - } while (p != NULL); - tag[config_info->curr_tag].num_envs = nenvs; - - printf("Got envs for tag:\n"); - for (nenvs = 0; nenvs < tag[config_info->curr_tag].num_envs; nenvs++) - printf("Env %d: (%s)\n", nenvs, tag[config_info->curr_tag].env[nenvs]); - return 1; -} - -int -parse_config_load(char *filename, struct config_info *config_info) -{ - struct config_info new_config_info; - - /* Scope on Defaults is per-file */ - set_config_defaults(&new_config_info); - new_config_info.curr_tag = config_info->curr_tag; - - /* If it's a relative file name, make it absolute */ - if (*filename != '/') { - char new_filename[1024]; - char *p, *q; - - if ((p = strrchr(config_info->filename, '/')) == NULL) - configerror(config_info, "Could not determine path to file!"); - q = config_info->filename; - - strcpy(new_filename, q); - new_filename[p - q] = '\0'; - strcat(new_filename, "/"); - strcat(new_filename, filename); - printf("Filename: %s\n", new_filename); - strcpy(filename, new_filename); - } - /* FIXME: This implementation forces pathnames to be absolute. We should - allow relative pathnames somehow. */ - parse_tag_file(filename, &new_config_info); - - config_info->curr_tag = new_config_info.curr_tag; - - return 1; -} - -int -parse_config_default_binding(char *def, - struct config_info *config_info) -{ - config_info->default_binding = string_to_binding_mask(config_info, def); - if (!(config_info->default_binding & (TAG_BINDING_BUTTON1 | TAG_BINDING_BUTTON2 | - TAG_BINDING_BUTTON3))) { - configerror(config_info, "Error reading default binding: binding _must_ " - "include either Button1, Button2, or Button3. Reverting to " - "compiled default."); - config_info->default_binding = TAG_DEFAULT_BINDING_MASK; - } - return 1; -} - -int -parse_config_default_highlight(char *def, - struct config_info *config_info) -{ - string_to_highlight(config_info, &config_info->default_highlight, def); - return 1; -} - -int -parse_config_default_search_lines(char *def, - struct config_info *config_info) -{ - if ((config_info->default_search_lines = atoi(def)) == 0) { - configerror(config_info, "Invalid default number of search lines. " - "Reverting to compiled default.\n"); - config_info->default_search_lines = TAG_DEFAULT_SEARCH_LINES; - } - if (config_info->default_search_lines > MAX_SEARCH_LINES) { - configerror(config_info, "Default number of search lines > maximum. " - "Reverting to compiled default.\n"); - config_info->default_search_lines = TAG_DEFAULT_SEARCH_LINES; - } - return 1; -} - -int -parse_config_tag_begin(char *s, struct config_info *config_info) -{ - fprintf(stderr, "New tag\n"); - if (config_info->in_tag) { - configerror(config_info, "Open brace inside braces"); - disable_tags(); - return -1; - } - if ((config_info->curr_tag + 1) >= MAX_TAGS) { - configerror(config_info, "Too many tags! Increase the maximum number " - "of tags and recompile!\n"); - disable_tags(); - return -1; - } - config_info->in_tag = 1; - - /* Initialize the new tag with all the default values. */ - tag[config_info->curr_tag].binding_mask = config_info->default_binding; - tag[config_info->curr_tag].search_lines = config_info->default_search_lines; - tag[config_info->curr_tag].highlight.attributes = - config_info->default_highlight.attributes; - tag[config_info->curr_tag].highlight.fg_color = - config_info->default_highlight.fg_color; - tag[config_info->curr_tag].highlight.bg_color = - config_info->default_highlight.bg_color; - tag[config_info->curr_tag].num_modes = 0; - tag[config_info->curr_tag].latent = 0; - tag[config_info->curr_tag].output_type = TAG_OUTPUT_NULL; - -#ifdef ACTIVE_TAGS_SPENCER_REGEXP - tag[config_info->curr_tag].rx = NULL; -#endif - - return 1; -} - -int -parse_config_tag_end(char *s, struct config_info *config_info) -{ - if (!config_info->in_tag) { - configerror(config_info, "close brace without open brace"); - disable_tags(); - return -1; - } - /* Make sure that the tag was setup properly before advancing to the next - one in the list */ - - /* FIXME: we need a way of figuring this out if we're using POSIX regex */ -#ifdef ACTIVE_TAGS_SPENCER_REGEXP - if (tag[config_info->curr_tag].rx == NULL) { - configerror("No regular epxression supplied for tag. Tag ignored."); - config_info->curr_tag--; - } -#endif - - config_info->in_tag = 0; - config_info->curr_tag++; - - return 1; -} - -int -parse_config_tag_latent(char *latent, struct config_info *config_info) -{ - if (!strcasecmp(latent, "true")) - tag[config_info->curr_tag].latent = 1; - return 1; -} - -int -parse_config_tag_search_lines(char *sl, struct config_info *config_info) -{ - if (atoi(sl)) - tag[config_info->curr_tag].search_lines = atoi(sl); - - D_TAGS(("==> Setting tag %d's search lines to %d\n", config_info->curr_tag, atoi(sl))); - - return 1; -} - -int -parse_config_tag_binding(char *s, struct config_info *config_info) -{ - tag[config_info->curr_tag].binding_mask = string_to_binding_mask(config_info, s); - return 1; -} - -int -parse_config_tag_highlight(char *s, struct config_info *config_info) -{ - string_to_highlight(config_info, &tag[config_info->curr_tag].highlight, s); - return 1; -} - -int -parse_config_tag_modes(char *s, struct config_info *config_info) -{ - char *mode, *p; - - mode = s; - - while (mode != NULL) { - if ((p = strchr(mode, ',')) != NULL) - *p = '\0'; - strcpy(tag[config_info->curr_tag].mode[tag[config_info->curr_tag].num_modes], mode); - if (p != NULL) - mode = p + 1; - else - mode = NULL; - - tag[config_info->curr_tag].num_modes++; - } - - return 1; -} - -int -parse_config_tag_regexp(char *regexp, struct config_info *config_info) -{ -#ifdef ACTIVE_TAGS_SPENCER_REGEXP - if ((tag[config_info->curr_tag].rx = regcomp(regexp)) == NULL) -#else - if (regcomp(&tag[config_info->curr_tag].rx, regexp, REG_EXTENDED) != 0) -#endif - { - configerror(config_info, "Couldn't compile regular expression"); - return -1; - } - return 1; -} - -int -parse_config_tag_action(char *action, struct config_info *config_info) -{ - strcpy(tag[config_info->curr_tag].action, action); - return 1; -} - -int -parse_config_tag_output(char *output, struct config_info *config_info) -{ - if (!strcasecmp(output, "null")) - tag[config_info->curr_tag].output_type = TAG_OUTPUT_NULL; - else if (!strcasecmp(output, "loop")) - tag[config_info->curr_tag].output_type = TAG_OUTPUT_LOOP; - else if (!strcasecmp(output, "replace")) - tag[config_info->curr_tag].output_type = TAG_OUTPUT_REPL; - else if (!strcasecmp(output, "popup")) - tag[config_info->curr_tag].output_type = TAG_OUTPUT_POPUP; - else { - configerror(config_info, "Unknown output method; defaulting to NULL"); - tag[config_info->curr_tag].output_type = TAG_OUTPUT_NULL; - } - - return 1; -} - -int -parse_config_tag_clue(char *clue, struct config_info *config_info) -{ - strcpy(tag[config_info->curr_tag].clue, clue); - return 1; -} - - - -void -set_config_defaults(struct config_info *config_info) -{ - config_info->default_binding = TAG_DEFAULT_BINDING_MASK; - config_info->default_search_lines = TAG_DEFAULT_SEARCH_LINES; - config_info->default_highlight.bg_color = TAG_DEFAULT_HIGHLIGHT_BG; - config_info->default_highlight.fg_color = TAG_DEFAULT_HIGHLIGHT_FG; - config_info->default_highlight.attributes = TAG_DEFAULT_HIGHLIGHT_ATT; - config_info->curr_tag = 0; - config_info->line_num = 0; - config_info->in_tag = 0; -} - -/* parse_tag_config actually reads the file and calls the dispatch functions - where appropriate */ -void -parse_tag_config(char *tag_config_file) -{ - char file_name[1024]; - struct passwd *user; - - struct config_info config_info; - - /* Set the defaults */ - set_config_defaults(&config_info); - - if (tag_config_file != NULL) - if (!parse_tag_file(tag_config_file, &config_info)) { - fprintf(stderr, "parse_tag_config: Couldn't open tag config" - "file: %s\n", tag_config_file); - tag_config_file = NULL; - } - if (tag_config_file == NULL) { - user = getpwuid(getuid()); - sprintf(file_name, "%s/%s", user->pw_dir, TAG_CONFIG_USER_FILENAME); - if (!parse_tag_file(file_name, &config_info)) { - fprintf(stderr, "parse_tag_config: Couldn't open user tag config " - "file: %s\n", file_name); - fprintf(stderr, "parse_tag_config: Trying system config file\n"); - - /* Try the system-wide config file */ - if (!parse_tag_file(TAG_CONFIG_SYSTEM_FILENAME, &config_info)) { - fprintf(stderr, "parse_tag_config: Error parsing config file: " - "%s\n", TAG_CONFIG_SYSTEM_FILENAME); - disable_tags(); - return; - } - } - } - num_tags = config_info.curr_tag; - printf("Num tags: %d\n", num_tags); - { - int i; - - for (i = 0; i < num_tags; i++) - printf("Tag action(%d): %s\n", i, tag[i].action); - } -} - -int -parse_tag_file(const char *filename, struct config_info *config_info) -{ - FILE *tag_file; - char line[1024]; - int i; - - if ((tag_file = fopen(filename, "r")) == NULL) - return 0; - - strcpy(config_info->filename, filename); - - /* Loop through the config file lines */ - while (!feof(tag_file)) { - fgets(line, sizeof(line), tag_file); - config_info->line_num++; - - if (feof(tag_file)) - break; - - if (line[strlen(line) - 1] != '\n') { - configerror(config_info, "line too long?"); - exit(1); - } - line[strlen(line) - 1] = '\0'; - - /* Loop through the config file lines, calling the appropriate - functions from the dispatch table as we go. If there is no - corresponding function, flag a warning and try to continue. */ - if ((line[0] != '#') && (!isspace(line[0])) && (strlen(line) != 0)) { - for (i = 0; config_dispatch[i].parser != NULL; i++) - if (TAG_CONFIG(config_dispatch[i].token)) { - if ((strchr(line, '=') == NULL) && (*line != '{') && - (*line != '}') && !TAG_CONFIG(TAG_CONFIG_LOAD)) - configerror(config_info, "'=' not found"); - else { - char *p; - - p = line + strlen(config_dispatch[i].token) + 1; - if (strchr(line, '=') != NULL) { - p = strchr(line, '=') + 1; - while (isspace(*p)) - p++; - } - if (!((config_dispatch[i].parser) (p, config_info))) - return 0; - break; - } - } - if (config_dispatch[i].parser == NULL) - configerror(config_info, "Unrecognized token"); - } - } - fclose(tag_file); - - return 1; -} - -/* - Internal Functions - */ - -/* Use this function to display errors encountered while parsing the config - file to keep them looking uniform */ -void -configerror(struct config_info *config_info, char *message) -{ - fprintf(stderr, "active tags: error on line %d of config file %s: %s\n", - config_info->line_num, config_info->filename, message); -} - -void -string_to_color(struct config_info *config_info, tag_highlight_t * highlight, - char *c) -{ -#if 0 - int color; - -#endif - int color = 0; - int bg = 0; - char *p; - - p = c; - - /* Background colors are prefaced by a '*' */ - if (*p == '*') { - bg = 1; - p++; - } - if (!strcasecmp(p, "Black")) - color = TAG_HIGHLIGHT_BLACK; - else if (!strcasecmp(p, "White")) - color = TAG_HIGHLIGHT_WHITE; - else if (!strcasecmp(p, "Red")) - color = TAG_HIGHLIGHT_RED; - else if (!strcasecmp(p, "Green")) - color = TAG_HIGHLIGHT_GREEN; - else if (!strcasecmp(p, "Yellow")) - color = TAG_HIGHLIGHT_YELLOW; - else if (!strcasecmp(p, "Blue")) - color = TAG_HIGHLIGHT_BLUE; - else if (!strcasecmp(p, "Magenta")) - color = TAG_HIGHLIGHT_MAGENTA; - else if (!strcasecmp(p, "Cyan")) - color = TAG_HIGHLIGHT_CYAN; - else if (!strcasecmp(p, "Normal")) - color = TAG_HIGHLIGHT_NORMAL; - else - configerror(config_info, "Unrecognized highlight token"); - - if (bg) - highlight->bg_color = color; - else - highlight->fg_color = color; -} - -void -string_to_highlight(struct config_info *config_info, tag_highlight_t * - highlight, char *s) -{ - char *h_bit; - - /* att_set is 0 if we've set an attribute value and 1 otherwise. We have to - keep track of this because setting an attribute value should override the - default, so we can't blindly OR the new values with whatever was in - highlight->attribute before. So, if we've already overriden the value, - we OR. If we haven't yet overriden it, then we do so and set att_set to - 1. */ - int att_set = 0; - - h_bit = strtok(s, "&"); - - while (h_bit != NULL) { - if (!strcasecmp(h_bit, "Underline")) { - if (att_set) - highlight->attributes |= TAG_HIGHLIGHT_ULINE; - else { - highlight->attributes = TAG_HIGHLIGHT_ULINE; - highlight->fg_color = TAG_HIGHLIGHT_NORMAL; - highlight->bg_color = TAG_HIGHLIGHT_NORMAL; - att_set = 1; - } - } else if (!strcasecmp(h_bit, "Bold")) { - if (att_set) - highlight->attributes |= TAG_HIGHLIGHT_BOLD; - else { - highlight->attributes = TAG_HIGHLIGHT_BOLD; - highlight->fg_color = TAG_HIGHLIGHT_NORMAL; - highlight->bg_color = TAG_HIGHLIGHT_NORMAL; - att_set = 1; - } - } else if (!strcasecmp(h_bit, "RVid")) { - if (att_set) - highlight->attributes |= TAG_HIGHLIGHT_RVID; - else { - highlight->attributes = TAG_HIGHLIGHT_RVID; - highlight->fg_color = TAG_HIGHLIGHT_NORMAL; - highlight->bg_color = TAG_HIGHLIGHT_NORMAL; - att_set = 1; - } - } else if (!strcasecmp(h_bit, "Blink")) { - if (att_set) - highlight->attributes |= TAG_HIGHLIGHT_BLINK; - else { - highlight->attributes = TAG_HIGHLIGHT_BLINK; - highlight->fg_color = TAG_HIGHLIGHT_NORMAL; - highlight->bg_color = TAG_HIGHLIGHT_NORMAL; - att_set = 1; - } - } else { - if (att_set) - string_to_color(config_info, highlight, h_bit); - else { - att_set = 1; - highlight->fg_color = TAG_HIGHLIGHT_NORMAL; - highlight->bg_color = TAG_HIGHLIGHT_NORMAL; - highlight->attributes = 0; - string_to_color(config_info, highlight, h_bit); - } - } - - h_bit = strtok(NULL, "&"); - } -} - -unsigned int -string_to_binding_mask(struct config_info *config_info, char *s) -{ - char *b_bit; - unsigned int mask = 0; - - b_bit = strtok(s, "&"); - while (b_bit != NULL) { - if (!strcasecmp(b_bit, "Button1")) - mask |= TAG_BINDING_BUTTON1; - else if (!strcasecmp(b_bit, "Button2")) - mask |= TAG_BINDING_BUTTON2; - else if (!strcasecmp(b_bit, "Button3")) - mask |= TAG_BINDING_BUTTON3; - else if (!strcasecmp(b_bit, "Shift")) - mask |= TAG_BINDING_SHIFT; - else if (!strcasecmp(b_bit, "Control")) - mask |= TAG_BINDING_CONTROL; - else if (!strcasecmp(b_bit, "Meta")) - mask |= TAG_BINDING_META; - else - configerror(config_info, "Unknown binding token"); - - b_bit = strtok(NULL, "&"); - } - - return mask; -} - -#endif /* USE_ACTIVE_TAGS */ diff --git a/src/activeconfig.h b/src/activeconfig.h deleted file mode 100644 index f5bda86..0000000 --- a/src/activeconfig.h +++ /dev/null @@ -1,106 +0,0 @@ -/*--------------------------------*-C-*---------------------------------* - * File: activeconfig.h - * - * Copyright 1996,1997 Nat Friedman, Massachusetts Institute of Technology - * - * - * You can do what you like with this source code as long as - * you don't try to make money out of it and you include an - * unaltered copy of this message (including the copyright). - * - * The author accepts no responsibility for anything whatsoever, nor does he - * guarantee anything, nor are any guarantees, promises, or covenants implicit - * with the use of this software. - * - * For information regarding this particular module, please see - * README.ActiveTags. - * - *----------------------------------------------------------------------*/ - -#ifdef ACTIVE_TAGS_SPENCER_REGEXP -#include "regexp/regexp.h" -#else -#include -#endif - -#include "activetags.h" - -/* The default locations for the config file */ -#define TAG_CONFIG_USER_FILENAME ".active.tags" -#define TAG_CONFIG_SYSTEM_FILENAME "/etc/active.tags" - -/* Defaults */ -#define TAG_DEFAULT_SEARCH_LINES 1 -#define TAG_DEFAULT_BINDING_MASK TAG_BINDING_BUTTON3 -#define TAG_DEFAULT_HIGHLIGHT_BG TAG_HIGHLIGHT_NORMAL -#define TAG_DEFAULT_HIGHLIGHT_FG TAG_HIGHLIGHT_BLUE -#define TAG_DEFAULT_HIGHLIGHT_ATT 0 - -/* These are the config file tokens. */ -#define TAG_CONFIG_DEFAULT_BINDING "DefaultBinding" -#define TAG_CONFIG_DEFAULT_HIGHLIGHT "DefaultHighlight" -#define TAG_CONFIG_DEFAULT_SEARCH_LINES "DefaultSearchLines" -#define TAG_CONFIG_SEARCH_LINES "SearchLines" -#define TAG_CONFIG_NEW_TAG "{" -#define TAG_CONFIG_END_TAG "}" -#define TAG_CONFIG_OUTPUT "Output" -#define TAG_CONFIG_LATENT "Latent" -#define TAG_CONFIG_BINDING "Binding" -#define TAG_CONFIG_HIGHLIGHT "Highlight" -#define TAG_CONFIG_MODES "Modes" -#define TAG_CONFIG_REGEXP "Regexp" -#define TAG_CONFIG_ACTION "Action" -#define TAG_CONFIG_LOOPACTION "LoopAction" -#define TAG_CONFIG_CLUE "Clue" -#define TAG_CONFIG_LOAD "Load" -#define TAG_CONFIG_ENV "Env" - -/* Macros for parsing the config file */ -#define TAG_CONFIG(x) (!strncmp(line, (x), strlen(x))) - -/* The config_info structure holds all the information that each individual - configuration parsing function needs as it runs */ -struct config_info { - int line_num; - int default_binding; - tag_highlight_t default_highlight; - int default_search_lines; - int in_tag; - int curr_tag; - char filename[1024]; -}; - -/* Each dispatch table entry is of the following form */ -struct config_entry { - char * token; - int (*parser)(char *, struct config_info *); -}; - -/* Configuration dispatch function prototypes */ -int parse_config_default_binding(char *, struct config_info *); -int parse_config_default_highlight(char *, struct config_info *); -int parse_config_default_search_lines(char *, struct config_info *); -int parse_config_tag_begin(char *, struct config_info *); -int parse_config_tag_end(char *, struct config_info *); -int parse_config_tag_latent(char *, struct config_info *); -int parse_config_tag_binding(char *, struct config_info *); -int parse_config_tag_highlight(char *, struct config_info *); -int parse_config_tag_modes(char *, struct config_info *); -int parse_config_tag_regexp(char *, struct config_info *); -int parse_config_tag_action(char *, struct config_info *); -int parse_config_tag_search_lines(char *, struct config_info *); -int parse_config_tag_output(char *, struct config_info *); -int parse_config_tag_clue(char *, struct config_info *); -int parse_config_load(char * filename, struct config_info * config_info); -int parse_config_tag_env(char * envlist, struct config_info * config_info); - -/* Internal helper functin prototypes */ -void configerror(struct config_info * config_info, char * message); -void string_to_color(struct config_info * config_info, tag_highlight_t * - highlight, char * c); -void string_to_highlight(struct config_info * config_info, tag_highlight_t * - highlight, char * s); -unsigned int string_to_binding_mask(struct config_info * config_info, - char * s); -void set_config_defaults(struct config_info * config_info); -int parse_tag_file(const char * filename, struct config_info * config_info); diff --git a/src/activeeterm.c b/src/activeeterm.c deleted file mode 100644 index 3f3d775..0000000 --- a/src/activeeterm.c +++ /dev/null @@ -1,390 +0,0 @@ -/*--------------------------------*-C-*---------------------------------* - * File: activeeterm.c - * - * Copyright 1997 Nat Friedman, Massachusetts Institute of Technology - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - *----------------------------------------------------------------------*/ - -/* This file contains the glue functions to make active tags work in eterm. */ - -/* - In order to dingify a program, this plugin file must define the following - functions with the specified behavior. Note that functions can be defined - as macros just fine. - - The functions are broken up into two groups. The first group of functions - are the wrapper functions which get called by the main program. These - functions call the internal active tags functions. The second group of - functions are the internal functions which are called by the active - tags functions. - - WRAPPER FUNCTIONS - - int tag_click( ... ) - This should call tag_activate after it has properly assembled the - binding mask and determined the row and column properly. tag_click() - is called from inside the main program. - - void tag_pointer_new_position( ... ) - This should call show_tag after it has computed the row and column - properly and done whatever processing it needs to do. - - void tag_scroll( ... ) - void tag_init ( ... ) - void tag_sig_child ( ... ) - void tag_hide ( ... ) - - INTERNAL FUNCTIONS - - void get_tag_mode(char * mode) - This function stores a string containing the current mode in the - mode parameter. This can be very simple (for example - strcpy(mode, "browser") might be sufficient), or somewhat more complex - for those programs which can change modes, such as rxvt. - - int row_width(void) - returns the maximum width of each row. - - const char ** get_rows(void) - returns the comparison region. current_row() and current_col() should - be indexes into this region. - - void set_tag_highlight(int row, int col, tag_highlight_t highlight) - Highlights the specified character with the specified highlighting. - - tag_highlight_t get_tag_highlight(int row, int col) - Returns the current highlighting information for the specified - character. - */ - -static const char cvs_ident[] = "$Id$"; - -#include "feature.h" -#ifdef USE_ACTIVE_TAGS - -#include -#include -#include - -#include "activetags.h" -#include "activeeterm.h" -#include "mem.h" /* From libmej */ - -/* - WRAPPER FUNCTIONS - */ - -void -tag_pointer_new_position(int x, int y) -{ - int row, col; - - if (!active_tags_enabled) - return; - - col = Pixel2Col(x); - row = Pixel2Row(y); - -#ifdef ACTIVE_TAG_CLICK_CLUES - if (show_tag(row, col)) - set_click_clue_timer(); - else { - destroy_click_clue(); - unset_click_clue_timer(); - } -#else - show_tag(row, col); -#endif -} - -void -tag_scroll(int nlines, int row1, int row2) -{ - if (!active_tags_enabled) - return; - -#ifdef ACTIVE_TAG_CLICK_CLUES - if (tag_screen_scroll(nlines, row1, row2)) { - destroy_click_clue(); - unset_click_clue_timer(); - } -#else - (void) tag_screen_scroll(nlines, row1, row2); -#endif -} - -void -tag_init(void) -{ - if (!active_tags_enabled) - return; - - tag_env = "X"; - -#ifdef ACTIVE_TAG_CLICK_CLUES - init_click_clues(); -#endif - - initialize_tags(); -} - -#if 0 -void -#endif -inline void -tag_hide(void) -{ - if (!active_tags_enabled) - return; - - erase_tag_highlighting(); -} - -int -tag_click(int x, int y, unsigned int button, unsigned int keystate) -{ - int binding_mask; - int row, col; - int retval; - - if (!active_tags_enabled) - return 0; - -#ifdef ACTIVE_TAG_CLICK_CLUES - destroy_click_clue(); - unset_click_clue_timer(); -#endif - - /* Build the binding mask. Button3 == 3. We need it to be 4 - (100 binary) to fit in the binding mask properly. */ - if (button == Button3) - button = TAG_BINDING_BUTTON3; - - binding_mask = button; - - if (keystate & ShiftMask) - binding_mask |= TAG_BINDING_SHIFT; - if (keystate & ControlMask) - binding_mask |= TAG_BINDING_CONTROL; - if (keystate & Mod1Mask) - binding_mask |= TAG_BINDING_META; - - row = Pixel2Row(y); - col = Pixel2Col(x); - retval = tag_activate(row, col, binding_mask); - return retval; -} - -/* - INTERNAL FUNCTIONS - */ - -/* This function finds the current tag mode and stores it in the 'mode' - parameter. The current mode is equivalent to argv[0] of the program - currently controlling the eterm's terminal. */ -void -get_tag_mode(char *mode) -{ - char proc_name[1024]; - FILE *f; - pid_t pid; - - if ((pid = tcgetpgrp(cmd_fd)) == -1) { - fprintf(stderr, "Couldn't get tag mode!\n"); - strcpy(mode, ""); - return; - } - sprintf(proc_name, "/proc/%d/cmdline", pid); - if ((f = fopen(proc_name, "r")) == NULL) { - fprintf(stderr, "Couldn't open proc!\n"); - strcpy(mode, ""); - return; - } - fscanf(f, "%s", mode); - fclose(f); -} - -/* These were changed to macros and moved into activeeterm.h. -vendu */ - -#if 0 -int -row_width(void) -{ - return TermWin.ncol; -} - -int -tag_min_row(void) -{ - return 0; -} - -int -tag_max_row(void) -{ - return TermWin.nrow - 1; -} -#endif - -void -tag_get_row(int row_num, char **row) -{ -/* FIXME: I guess this works :) -vendu */ - *row = drawn_text[row_num]; -} - -int -tag_eterm_color(int tag_color) -{ - switch (tag_color) { - case TAG_HIGHLIGHT_BLACK: - return 2; - case TAG_HIGHLIGHT_WHITE: - return 1; - case TAG_HIGHLIGHT_RED: - return 3; - case TAG_HIGHLIGHT_GREEN: - return 4; - case TAG_HIGHLIGHT_YELLOW: - return 5; - case TAG_HIGHLIGHT_BLUE: - return 6; - case TAG_HIGHLIGHT_MAGENTA: - return 7; - case TAG_HIGHLIGHT_CYAN: - return 8; - default: - return -1; - } -} - -int -eterm_tag_color(int eterm_color) -{ - switch (eterm_color) { - case 0: - return TAG_HIGHLIGHT_NORMAL; - case 7: - return TAG_HIGHLIGHT_MAGENTA; - case 1: - return TAG_HIGHLIGHT_WHITE; - case 2: - return TAG_HIGHLIGHT_BLACK; - case 3: - return TAG_HIGHLIGHT_RED; - case 4: - return TAG_HIGHLIGHT_GREEN; - case 5: - return TAG_HIGHLIGHT_YELLOW; - case 6: - return TAG_HIGHLIGHT_BLUE; - case 8: - return TAG_HIGHLIGHT_CYAN; - default: - return TAG_HIGHLIGHT_NORMAL; - } -} - -void -set_tag_highlight(int row, int col, tag_highlight_t highlight) -{ - unsigned int rend_mask = 0; - unsigned int back; - unsigned int fore; - -/* rend_t ** rp = &(screen.rend[row + TermWin.saveLines - TermWin.view_start][col]); */ - - if (highlight.attributes & TAG_HIGHLIGHT_RVID) - rend_mask |= RS_RVid; - if (highlight.attributes & TAG_HIGHLIGHT_ULINE) - rend_mask |= RS_Uline; - if (highlight.attributes & TAG_HIGHLIGHT_BOLD) - rend_mask |= RS_Bold; - - if (highlight.fg_color == TAG_HIGHLIGHT_NORMAL) - fore = SET_FGCOLOR(0, fgColor); - else - fore = SET_FGCOLOR(0, tag_eterm_color(highlight.fg_color)); - - if (highlight.bg_color == TAG_HIGHLIGHT_NORMAL) - back = SET_BGCOLOR(0, bgColor); - else - back = SET_BGCOLOR(0, tag_eterm_color(highlight.bg_color)); - - screen.rend[row + TermWin.saveLines - TermWin.view_start][col] = - rend_mask | fore | back; -} - -void -get_tag_highlight(int row, int col, tag_highlight_t * highlight) -{ - unsigned int rend; - - rend = screen.rend[row + TermWin.saveLines - TermWin.view_start][col]; - - highlight->attributes = 0; - if (rend & RS_RVid) - highlight->attributes |= TAG_HIGHLIGHT_RVID; - if (rend & RS_Uline) - highlight->attributes |= TAG_HIGHLIGHT_ULINE; - if (rend & RS_Bold) - highlight->attributes |= TAG_HIGHLIGHT_BOLD; - if (rend & RS_Blink) - highlight->attributes |= TAG_HIGHLIGHT_BLINK; - - highlight->fg_color = eterm_tag_color(GET_FGCOLOR(rend)); - highlight->bg_color = eterm_tag_color(GET_BGCOLOR(rend)); -} - -/* Set the UID appropriately */ -int -set_tag_uid(void) -{ - return 1; -} - -/* Set stdout for loop actions */ -int -set_tag_stdout(void) -{ - if (close(1) < 0) { - perror("close"); - return 0; - } - if (dup(cmd_fd) < 0) { - perror("dup"); - return 0; - } - return 1; -} - -/* Set the PWD to the pwd of the process eterm is running */ -int -set_tag_pwd(void) -{ - char dir[1024]; - - sprintf(dir, "/proc/%d/cwd", cmd_pid); - if (chdir(dir) < 0) - return 0; - - return 1; -} - -#endif /* USE_ACTIVE_TAGS */ diff --git a/src/activeeterm.h b/src/activeeterm.h deleted file mode 100644 index e01d23a..0000000 --- a/src/activeeterm.h +++ /dev/null @@ -1,48 +0,0 @@ -/*--------------------------------*-C-*---------------------------------* - * File: activeeterm.h - * - * Copyright 1997 Nat Friedman, Massachusetts Institute of Technology - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - *----------------------------------------------------------------------*/ - -#ifndef _ACTIVEETERM_H -# define ACTIVEETERM_H - -# include "screen.h" -# include "command.h" -# include "main.h" /* for TermWin */ -/* #include "rxvtgrx.h" */ - -/* #define MAX_RXVT_ROWS 1024 */ - -int tag_click(int x, int y, unsigned int button, unsigned int keystate); -void tag_pointer_new_position(int x, int y); -void tag_init(void); - -extern int cmd_fd; -extern screen_t screen; - -extern text_t **drawn_text; -extern rend_t **drawn_rend; - -# define row_width() (TermWin.ncol) -# define tag_min_row() (0) -# define tag_max_row() (TermWin.nrow - 1) - -#endif /* ACTIVEETERM_H */ diff --git a/src/activetags.c b/src/activetags.c deleted file mode 100644 index 86ff516..0000000 --- a/src/activetags.c +++ /dev/null @@ -1,524 +0,0 @@ -/*--------------------------------*-C-*---------------------------------* - * File: activetags.c - * - * Copyright 1997 Nat Friedman, Massachusetts Institute of Technology - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * - *----------------------------------------------------------------------*/ - -/* - This file contains all of the basic active tags functionality. These - are the generalized routines which can be plugged into just about anything. - If I've designed everything properly, which I believe I have, you should - not have to change anything in this file in order to plug active tags into - an application. - - See activeeterm.c for the routines which interface these functions with Eterm - */ - -static const char cvs_ident[] = "$Id$"; - -#include "feature.h" -#ifdef USE_ACTIVE_TAGS - -#include -#include -#include -#include -#include -#include - -#include "activetags.h" -#include "activeeterm.h" - -/* ============================ Global Variables =========================== */ - -/* This is for run-time enabling and disabling of tags. It is 1 if tags are - enabled at 0 otherwise. */ -int active_tags_enabled = 1; - -/* This is the global array of tag configurations. Each of the tags in the - configuration file corresponds to a tag in this global array. These are - allocated statically just to reduce the complexity of the code. Increase - MAX_TAGS in activetags.h if you run out. */ -struct active_tag tag[MAX_TAGS]; -int num_tags = 0; - -/* The tag environment (e.g. "X", "console", ... */ -char *tag_env; - -/* The data regarding the last tag highlighted on the screen. NB: this model - limits the number of highlighted tags on the screen to one. */ -int last_h_tag_index = -1, last_h_tag_begin_row = -1, last_h_tag_end_row = -1, last_h_tag_begin_col = -1, last_h_tag_end_col = -1; -tag_highlight_t old_highlighting[MAX_SEARCH_LINES][MAX_SEARCH_COLS]; - -char *tag_config_file = NULL; - -static char *thingy = "ActiveTags 1.0b4 -- Copyright 1997,1998 Nat Friedman -- DINGUS UBER ALLES"; - -/* ============================== Tag Routines ============================= */ - -/* This is the tag intialization routine. It needs to be called upon - startup. */ -void -initialize_tags(void) -{ - /* Parse the config file */ - parse_tag_config(tag_config_file); -} - -void -disable_tags(void) -{ - fprintf(stderr, "Active tags are disabled.\n"); - active_tags_enabled = 0; -} - -/* check_tag_mode returns true if the mode parameter is one of the modes - for which the tag indexed by tag_index is active. Otherwise, it returns - false. */ -int -check_tag_mode(int tag_index, char *mode) -{ - int i; - - /* If no modes are listed for a particular tag, that tag is always active. */ - if (tag[tag_index].num_modes == 0) - return 1; - - for (i = 0; i < tag[tag_index].num_modes; i++) - if (!strcmp(mode, tag[tag_index].mode[i])) - return 1; - - return 0; -} - -int -check_tag_env(int tag_index) -{ - int i; - - if (!tag[tag_index].num_envs) - return 1; - - for (i = 0; i < tag[tag_index].num_envs; i++) - if (!strcasecmp(tag_env, tag[tag_index].env[i])) - return 1; - - return 0; -} - -/* Check the position specified by (row,col) for a tag. If there is - a tag there, set tag_begin and tag_end to the proper offsets into - screen.text and screen.rend, and set tag_index to the index of the - tag that was identified. If no tag is found, return 0. Otherwise, - return 1. If binding_mask is set, then only search tags whose - binding mask matches the binding_mask passed to the function. - Tag searching begins at the specified index, tag_begin_index. */ -int -find_tag(int row, int col, int *tag_begin_row, int *tag_begin_col, - int *tag_end_row, int *tag_end_col, int *tag_index, - unsigned int binding_mask, int tag_begin_index) -{ - char *curr_row; - static char mode[1024]; - static int mode_check_count = 0; - char compare_region[MAX_SEARCH_CHARS]; - int compare_offset, compare_region_pointer_position; - int done; - unsigned int region_size; - unsigned int last_region_size = 0; - - int start_row, end_row, i, dest_offset; - - char *start_match_p, *end_match_p; - -#ifndef ACTIVE_TAGS_SPENCER_REGEXP - regmatch_t regmatch[5]; - -#endif - - D_TAGS(("==> find_tag(row=%d, col=%d, ..., binding=%d, begin=%d)\n", row, col, binding_mask, tag_begin_index)); - if (!mode_check_count) - get_tag_mode(mode); - - mode_check_count++; - if (mode_check_count == MAX_MODE_CHECK_COUNT) - mode_check_count = 0; - for (*tag_index = tag_begin_index; *tag_index < num_tags; (*tag_index)++) { - D_TAGS((" ==> tag: %d (sl=%d)\n", *tag_index, tag[*tag_index].search_lines)); - if (((binding_mask == 0) && (!tag[*tag_index].latent)) || - (binding_mask && (binding_mask == tag[*tag_index].binding_mask))) - if (check_tag_mode(*tag_index, mode) && (check_tag_env(*tag_index))) { - start_row = row - tag[*tag_index].search_lines / 2; - end_row = row + tag[*tag_index].search_lines / 2; - - if (start_row < tag_min_row()) - start_row = tag_min_row(); - - if (end_row > tag_max_row()) - end_row = tag_max_row(); - - compare_region_pointer_position = ((row - start_row) * row_width()) + - col; - - region_size = (row_width()) * (end_row - start_row + 1); - - if (region_size > MAX_SEARCH_CHARS) { - fprintf(stderr, "search region too large: reduce number of " - "search lines.\n"); - fprintf(stderr, "row_width: %d end_row: %d start_row: %d\n", - row_width(), end_row, start_row); - break; - } - if (region_size != last_region_size) { - D_TAGS((" ==> region_size == %d\tlast_region_size == %d\n", region_size, last_region_size)); - i = start_row; - dest_offset = 0; - while (i <= end_row) { - tag_get_row(i, &curr_row); - D_TAGS(("Memcpying row into place...\n")); - memcpy(compare_region + dest_offset, curr_row, row_width()); - D_TAGS(("Done\n")); - dest_offset += row_width(); - i++; - } - compare_region[dest_offset + 1] = '\0'; - } - last_region_size = region_size; - - - done = 0; - compare_offset = 0; - - while (!done) { -#ifdef ACTIVE_TAGS_SPENCER_REGEXP - if (regexec(tag[*tag_index].rx, compare_region + compare_offset)) -#else - if (!regexec(&tag[*tag_index].rx, compare_region + compare_offset, - 4, regmatch, REG_NOTBOL | REG_NOTEOL)) -#endif - - { -#ifdef ACTIVE_TAGS_SPENCER_REGEXP - start_match_p = tag[*tag_index].rx->startp[0]; - end_match_p = tag[*tag_index].rx->endp[0]; -#else - start_match_p = compare_region + compare_offset + - regmatch[0].rm_so; - end_match_p = compare_region + compare_offset + - regmatch[0].rm_eo; -#endif - - if ((start_match_p <= - (compare_region + compare_region_pointer_position)) && - (end_match_p > - (compare_region + compare_region_pointer_position))) { - *tag_begin_row = ((start_match_p - - compare_region) / row_width()) + - start_row; - *tag_begin_col = (start_match_p - - compare_region) - - ((start_match_p - compare_region) / - row_width()) * row_width(); - - *tag_end_row = ((end_match_p - - compare_region) / row_width()) + - start_row; - *tag_end_col = (end_match_p - - compare_region) - - ((end_match_p - compare_region) / - row_width()) * row_width(); - D_TAGS(("Found tag: begin_row: %d begin_col: %d\nend_row : %d end_col : %d\n", *tag_begin_row, *tag_begin_col, - *tag_end_row, *tag_end_col)); - return 1; - - } else - compare_offset = (end_match_p - - compare_region); - } else - done = 1; - } - } - } - - return 0; -} - -/* tag_scroll -- This is to notify the tag functionality that the screen - has scrolled nlines lines (positive means scrolled up, negative means - scrolled down) from start_row to end_row (inclusive) */ -int -tag_screen_scroll(int nlines, int start_row, int end_row) -{ - - D_TAGS(("tag_scroll(%d, %d, %d)\n", nlines, start_row, end_row)); - D_TAGS(("\tlast_brow: %d last_erow: %d\n", last_h_tag_begin_row, last_h_tag_end_row)); - if (!nlines) - return 0; - - if (last_h_tag_index == -1) - return 0; - - /* If the last highlighted tag is not part of the region that scrolled, - we don't need to do anything. */ - if (last_h_tag_begin_row > end_row) - return 0; - - if (last_h_tag_end_row < start_row) - return 0; - - /* Otherwise, update the position of the tag last highlighted */ - last_h_tag_begin_row += nlines; - last_h_tag_end_row += nlines; - - /* Erase the tag */ - (void) show_tag(last_h_tag_begin_row - nlines, last_h_tag_begin_col + 1); - return 1; -} - -/* This function restores the rendering information for the currently - highlighted tag to its status before the tag was highlighted. */ -void -erase_tag_highlighting(void) -{ - int row, col; - int final_highlight_col; - int start_highlight_col; - - if (last_h_tag_index != -1) { - for (row = last_h_tag_begin_row; row <= last_h_tag_end_row; row++) { - final_highlight_col = (row == last_h_tag_end_row) ? - last_h_tag_end_col : row_width(); - start_highlight_col = (row == last_h_tag_begin_row) ? - last_h_tag_begin_col : 0; - for (col = start_highlight_col; col < final_highlight_col; col++) { - set_tag_highlight(row, col, - old_highlighting[row - last_h_tag_begin_row][col]); - } - } - } - /* We don't need to keep erasing now that nothing is highlighted */ - last_h_tag_index = -1; -} - -/* Highlight a tag if one exists at the location specified in pixels. - If no tag exists there and a tag is currently highlighted, we need - to erase that tag's highlighting. */ -int -show_tag(int row, int col) -{ - unsigned int tag_begin_col, tag_end_col, tag_begin_row, tag_end_row, tag_index; - int final_highlight_col; - int start_highlight_col; - tag_highlight_t highlight; - - D_TAGS(("==> show_tag(%d,%d)\n", row, col)); - - /* If there's no tag there and a tag is currently highlighted, we need - to erase its highlighting. */ - if (!find_tag(row, col, &tag_begin_row, &tag_begin_col, &tag_end_row, - &tag_end_col, &tag_index, 0, 0)) { - D_TAGS((" ==> no tag, erasing highlighting and leaving.\n")); - /* Erase the old highlighting */ - tag_hide(); - - return 0; - } - /* If we've come this far, then we are on a tag, and it needs to be - highlighted. */ - - /* If we're on the same tag as last time, there's no need to do - anything. */ - if ((tag_index == last_h_tag_index) && - (tag_begin_row == last_h_tag_begin_row) && - (tag_end_row == last_h_tag_end_row) && - (tag_begin_col == last_h_tag_begin_col) && - (tag_end_col == last_h_tag_end_col)) - return 1; - - /* Erase the old highlighting */ - tag_hide(); - - /* Add the new highlighting */ - for (row = tag_begin_row; row <= tag_end_row; row++) { - final_highlight_col = (row == tag_end_row) ? tag_end_col : - row_width(); - start_highlight_col = (row == tag_begin_row) ? tag_begin_col : 0; - for (col = start_highlight_col; col < final_highlight_col; col++) { - get_tag_highlight(row, col, &highlight); - memcpy((void *) &old_highlighting[row - tag_begin_row][col], - (void *) &highlight, sizeof(tag_highlight_t)); - - set_tag_highlight(row, col, tag[tag_index].highlight); - } - } - - /* Store the old values to erase later */ - last_h_tag_index = tag_index; - last_h_tag_begin_row = tag_begin_row; - last_h_tag_end_row = tag_end_row; - last_h_tag_begin_col = tag_begin_col; - last_h_tag_end_col = tag_end_col; - - return 1; -} - -/* Check to see if there's a tag at the location specified by (x,y) (in - pixels). If so, execute the corresponding action. Return 0 if there's - no tag there, otherwise return 1. */ -int -tag_activate(int row, int col, unsigned int binding_mask) -{ - int tag_begin_row, tag_end_row, tag_index, tag_begin_col, tag_end_col; - - D_TAGS(("tag_activate(row==%d, col==%d, ...)\n", row, col)); - - /* If there is no tag to be activated here, return. */ - if (!find_tag(row, col, &tag_begin_row, &tag_begin_col, &tag_end_row, - &tag_end_col, &tag_index, binding_mask, 0)) - return 0; - - /* Otherwise, activate the tag. */ - execute_tag(tag_begin_row, tag_begin_col, tag_end_row, tag_end_col, - tag_index); - - return 1; -} - -/* Execute the tag specified by tag_index and contained between the - indices specified by tag_begin and tag_end. */ - -void -execute_tag(int tag_begin_row, int tag_begin_col, - int tag_end_row, int tag_end_col, int tag_index) -{ - char tagstr[MAX_SEARCH_CHARS]; - char cmd[MAX_TAG_COMMAND_LENGTH]; - char *p, *q; - pid_t pid; - int dest_offset; - int i, start_column, end_column; - char *curr_row; - - printf("==> Activating tag %d:\n ==> Action: [%s]\n Env: [%s] ==> Output: %s\n", - tag_index, tag[tag_index].action, tag_env, - (tag[tag_index].output_type == TAG_OUTPUT_NULL) ? "NULL" : - ((tag[tag_index].output_type == TAG_OUTPUT_POPUP) ? "POPUP" : - ((tag[tag_index].output_type == TAG_OUTPUT_LOOP) ? "LOOP" : - ((tag[tag_index].output_type == TAG_OUTPUT_REPL) ? "REPL" : - "UNKNOWN")))); - - /* If the tag's action is TAG_ACTION_RELOAD, then we simply - relaod the tag config file. */ - if (!strcmp(tag[tag_index].action, TAG_ACTION_RELOAD)) { - for (i = 0; i < num_tags; i++) -#ifdef ACTIVE_TAGS_SPENCER_REGEXP - regfree(tag[i].rx); -#else - regfree(&tag[i].rx); -#endif - num_tags = 0; - parse_tag_config(tag_config_file); - return; - } - if (!strcmp(tag[tag_index].action, TAG_ACTION_DISABLE)) { - disable_tags(); - return; - } - /* For debugging */ - if (!strcmp(tag[tag_index].action, TAG_ACTION_MODE)) { - char mode[1024]; - - get_tag_mode(mode); - fprintf(stderr, "Mode: %s\n", mode); - return; - } - /* Fork off a separate process to execute the new tag. */ - pid = fork(); - - if (pid == 0) { /* child */ - - D_TAGS(("Child\n")); - - i = tag_begin_row; - dest_offset = 0; - - while (i <= tag_end_row) { - start_column = i == tag_begin_row ? tag_begin_col : 0; - end_column = i == tag_end_row ? tag_end_col : row_width(); - D_TAGS(("row: %d Start col: %d end_col: %d\n", i, start_column, end_column)); - tag_get_row(i, &curr_row); - memcpy(tagstr + dest_offset, - curr_row + start_column, - end_column - start_column); - - dest_offset += end_column - start_column; - i++; - } - - tagstr[dest_offset] = '\0'; - D_TAGS(("\t==> tag string: {%s}\n", tagstr)); - /* Initialize the command string */ - *cmd = '\0'; - - /* Build the command string from the action string by replacing - all occurences of ${} in the action string with the tag string. */ - q = p = tag[tag_index].action; - while ((p = strstr(q, "${}")) != NULL) { - *p = '\0'; - strcat(cmd, q); - - strcat(cmd, tagstr); - - /* Step over the remaining characters of the ${} */ - q = p + 3; - } - - strcat(cmd + strlen(cmd), q); - - if (!set_tag_pwd()) - fprintf(stderr, "Active Tags: couldn't set the pwd!\n"); - - - /* Set the UID appropriately so we don't act as the wrong user */ - if (!set_tag_uid()) { - fprintf(stderr, "Active Tags: tag action: Couldn't set the uid!\n"); - exit(1); - } - /* For a loop action, we connect stdout on the tag process to stdin on - the terminal's executing process */ - if (tag[tag_index].output_type == TAG_OUTPUT_LOOP) - /* I wonder if screwing around with Eterm's stdin is a good idea >:) - * -vendu - */ - if (!set_tag_stdout()) { - fprintf(stderr, "Active Tags: tag action: Couldn't set stdout for " - "a loop action!\n"); - exit(1); - } - system(cmd); -#if 0 - exit(1); /* This might be a bad idea :) Makes Eterm exit, at - * least if run from another Eterm. -vendu */ -#endif - return; - } -} - -#endif /* USE_ACTIVE_TAGS */ diff --git a/src/activetags.h b/src/activetags.h deleted file mode 100644 index 20152e0..0000000 --- a/src/activetags.h +++ /dev/null @@ -1,182 +0,0 @@ -/*--------------------------------*-C-*---------------------------------* - * File: activetags.h - * - * Copyright 1996,1997 Nat Friedman, Massachusetts Institute of Technology - * - * - * You can do what you like with this source code as long as - * you don't try to make money out of it and you include an - * unaltered copy of this message (including the copyright). - * - * The author accepts no responsibility for anything whatsoever, nor does he - * guarantee anything, nor are any guarantees, promises, or covenants implicit - * with the use of this software. - * - * For information regarding this particular module, please see - * README.ActiveTags. - * - *----------------------------------------------------------------------*/ - -#ifndef _ACTIVE_TAGS_H -#define _ACTIVE_TAGS_H - -#ifndef ACTIVE_TAGS -#define ACTIVE_TAGS -#endif - -#ifdef ACTIVE_TAGS_SPENCER_REGEXP -#include "regexp/regexp.h" -#else -#include -#include -#endif - -#include - -#define TAG_ACTION_RELOAD "*reload*" -#define TAG_ACTION_DISABLE "*disable*" - -/* Debugging actions */ -#define TAG_ACTION_MODE "*mode*" - - -#define TAG_DRAG_THRESHHOLD 500 - -/* Maximums */ -#define MAX_TAGS 128 -#define MAX_SEARCH_CHARS 32767 -#define MAX_SEARCH_LINES 25 -#define MAX_SEARCH_COLS 300 -#define MAX_SCREEN_ROWS 128 -#define MAX_TAG_MODES 32 -#define MAX_TAG_MODE_LEN 32 -#define MAX_TAG_COMMAND_LENGTH 2048 -#define MAX_REGEXP_LEN 1024 -#define MAX_ACTION_LEN 1024 -#define MAX_CLUE_LENGTH 1024 -#define MAX_MODE_CHECK_COUNT 25 -#define MAX_TAG_ENVS 8 -#define MAX_TAG_ENV_LEN 16 - -/* Output Types */ -#define TAG_OUTPUT_POPUP 1 -#define TAG_OUTPUT_LOOP 2 -#define TAG_OUTPUT_NULL 3 -#define TAG_OUTPUT_REPL 4 - -/* Binding fields */ -#define TAG_BINDING_BUTTON1 (1<<0) -#define TAG_BINDING_BUTTON2 (1<<1) -#define TAG_BINDING_BUTTON3 (1<<2) -#define TAG_BINDING_SHIFT (1<<3) -#define TAG_BINDING_CONTROL (1<<4) -#define TAG_BINDING_META (1<<5) - -/* Highlight fields */ -#define TAG_HIGHLIGHT_RVID (1L<<0) -#define TAG_HIGHLIGHT_BOLD (1L<<1) -#define TAG_HIGHLIGHT_ULINE (1L<<2) -#define TAG_HIGHLIGHT_BLINK (1L<<3) - -#define TAG_HIGHLIGHT_BLACK (1L<<0) -#define TAG_HIGHLIGHT_WHITE (1L<<1) -#define TAG_HIGHLIGHT_RED (1L<<2) -#define TAG_HIGHLIGHT_GREEN (1L<<3) -#define TAG_HIGHLIGHT_YELLOW (1L<<4) -#define TAG_HIGHLIGHT_BLUE (1L<<5) -#define TAG_HIGHLIGHT_MAGENTA (1L<<6) -#define TAG_HIGHLIGHT_CYAN (1L<<7) -#define TAG_HIGHLIGHT_NORMAL -1 - -typedef struct tag_highlight { - /* Underline, Reverse Video, Bold */ - int attributes; - - /* Highlighting colors */ - int fg_color; - int bg_color; - -} tag_highlight_t; - -struct active_tag { - - /* rx is the compiled regular expression for the tag */ -#ifdef ACTIVE_TAGS_SPENCER_REGEXP - regexp * rx; -#else - regex_t rx; -#endif - - /* The action is a program to be executed. The string ${} in the action - will be replaced with the tag. */ - char action[MAX_ACTION_LEN]; - - tag_highlight_t highlight; - - /* The button/key combo that activates this tag. */ - unsigned int binding_mask; - - /* Number of lines to search for this tag */ - int search_lines; - - char mode[MAX_TAG_MODES][MAX_TAG_MODE_LEN]; - int num_modes; - - char env[MAX_TAG_ENVS][MAX_TAG_ENV_LEN]; - int num_envs; - - /* See TAG_OUTPUT_* */ - int output_type; - - /* Whether or not the tag is latent. */ - int latent; - - char clue[MAX_CLUE_LENGTH]; -}; - - -/* Template prototypes */ -void get_tag_mode(char * mode); -/* int row_width(void); */ -void tag_get_row(int row_num, char ** row); -/* int tag_min_row(void); */ -/* int tag_max_row(void); */ -void set_tag_highlight(int row, int col, tag_highlight_t highlight); -void get_tag_highlight(int row, int col, tag_highlight_t * highlight); -int set_tag_stdout(void); -int set_tag_pwd(void); -int set_tag_uid(void); - -/* Prototypes */ -void parse_tag_config(char * tag_config_file); -int find_tag(int row, int col, int * tag_begin_row, int * tag_begin_col, - int * tag_end_row, int * tag_end_col, - int * tag_index, unsigned int binding_mask, int tag_begin_index); -int show_tag(int x, int y); -int tag_activate(int row, int col, unsigned int binding_mask); -void execute_tag(int tag_begin_row, int tag_begin_col, int tag_end_row, int tag_end_col, int tag_index); -void initialize_tags(void); -int tag_screen_scroll(int nlines, int start_row, int end_row); -void reap_tag_process(pid_t pid); -void erase_tag_highlighting(void); -void disable_tags(void); -void tag_hide(void); - -/* Externs */ -extern int active_tags_enabled; -extern struct active_tag tag[MAX_TAGS]; -extern int num_tags; -extern int last_h_tag_begin_row; -extern int last_h_tag_begin_col; -extern int last_h_tag_index; -extern char * tag_env; - -#endif /* _ACTIVE_TAGS_H */ - - - - - - - - diff --git a/src/command.c b/src/command.c index c01d776..261c0b5 100644 --- a/src/command.c +++ b/src/command.c @@ -37,8 +37,8 @@ static const char cvs_ident[] = "$Id$"; /* includes: */ -#include "feature.h" #include "config.h" +#include "feature.h" /* System Headers */ #include @@ -48,14 +48,6 @@ static const char cvs_ident[] = "$Id$"; #endif #include #include -#include -#if !defined(SIGSYS) -# if defined(SIGUNUSED) -# define SIGSYS SIGUNUSED -# else -# define SIGSYS ((int) 0) -# endif -#endif #ifdef HAVE_UNISTD_H # include #endif @@ -77,20 +69,6 @@ static const char cvs_ident[] = "$Id$"; #include #include #include -#ifdef OFFIX_DND -# define DndFile 2 -# define DndDir 5 -# define DndLink 7 -#endif -#include -#ifndef NO_XLOCALE -# if (XtVersion < 11005) -# define NO_XLOCALE -# include -# else -# include -# endif -#endif /* NO_XLOCALE */ #ifdef USE_GETGRNAME # include #endif @@ -136,527 +114,61 @@ static const char cvs_ident[] = "$Id$"; #endif /* Eterm-specific Headers */ -#ifdef USE_ACTIVE_TAGS -# include "activetags.h" -# include "activeeterm.h" -#endif #include "command.h" #include "main.h" #include "../libmej/debug.h" #include "debug.h" #include "../libmej/mem.h" #include "../libmej/strings.h" -#include "string.h" +#include "events.h" #include "graphics.h" #include "grkelot.h" -#include "scrollbar.h" -#include "menubar.h" -#include "screen.h" #include "options.h" #include "pixmap.h" -#ifdef USE_POSIX_THREADS -# include "threads.h" -#endif #ifdef PROFILE # include "profile.h" #endif - -#ifdef PIXMAP_SCROLLBAR -extern pixmap_t sbPixmap; - -#endif -#ifdef PIXMAP_MENUBAR -extern pixmap_t mbPixmap; - -#endif - - -/* terminal mode defines: */ -/* ways to deal with getting/setting termios structure */ -#ifdef HAVE_TERMIOS_H -typedef struct termios ttymode_t; - -# ifdef TCSANOW /* POSIX */ -# define GET_TERMIOS(fd,tios) tcgetattr (fd, tios) -# define SET_TERMIOS(fd,tios) do {\ -cfsetospeed (tios, BAUDRATE);\ -cfsetispeed (tios, BAUDRATE);\ -tcsetattr (fd, TCSANOW, tios);\ -} while (0) -# else -# ifdef TIOCSETA -# define GET_TERMIOS(fd,tios) ioctl (fd, TIOCGETA, tios) -# define SET_TERMIOS(fd,tios) do {\ -tios->c_cflag |= BAUDRATE;\ -ioctl (fd, TIOCSETA, tios);\ -} while (0) -# else -# define GET_TERMIOS(fd,tios) ioctl (fd, TCGETS, tios) -# define SET_TERMIOS(fd,tios) do {\ -tios->c_cflag |= BAUDRATE;\ -ioctl (fd, TCSETS, tios);\ -} while (0) -# endif -# endif -# define SET_TTYMODE(fd,tios) SET_TERMIOS (fd, tios) -#else -/* sgtty interface */ -typedef struct { - struct sgttyb sg; - struct tchars tc; - struct ltchars lc; - int line; - int local; -} ttymode_t; - -# define SET_TTYMODE(fd,tt) \ -do { \ -tt->sg.sg_ispeed = tt->sg.sg_ospeed = BAUDRATE;\ -ioctl (fd, TIOCSETP, &(tt->sg));\ -ioctl (fd, TIOCSETC, &(tt->tc));\ -ioctl (fd, TIOCSLTC, &(tt->lc));\ -ioctl (fd, TIOCSETD, &(tt->line));\ -ioctl (fd, TIOCLSET, &(tt->local));\ -} while (0) -#endif /* HAVE_TERMIOS_H */ - -/* use the fastest baud-rate */ -#ifdef B38400 -# define BAUDRATE B38400 -#else -# ifdef B19200 -# define BAUDRATE B19200 -# else -# define BAUDRATE B9600 -# endif -#endif - -/* Disable special character functions */ -#ifdef _POSIX_VDISABLE -# define VDISABLE _POSIX_VDISABLE -#else -# define VDISABLE 255 -#endif - -/*----------------------------------------------------------------------* - * system default characters if defined and reasonable - */ -#ifndef CINTR -# define CINTR '\003' /* ^C */ -#endif -#ifndef CQUIT -# define CQUIT '\034' /* ^\ */ -#endif -#ifndef CERASE -# ifdef linux -# define CERASE '\177' /* ^? */ -# else -# define CERASE '\010' /* ^H */ -# endif -#endif -#ifndef CKILL -# define CKILL '\025' /* ^U */ -#endif -#ifndef CEOF -# define CEOF '\004' /* ^D */ -#endif -#ifndef CSTART -# define CSTART '\021' /* ^Q */ -#endif -#ifndef CSTOP -# define CSTOP '\023' /* ^S */ -#endif -#ifndef CSUSP -# define CSUSP '\032' /* ^Z */ -#endif -#ifndef CDSUSP -# define CDSUSP '\031' /* ^Y */ -#endif -#ifndef CRPRNT -# define CRPRNT '\022' /* ^R */ -#endif -#ifndef CFLUSH -# define CFLUSH '\017' /* ^O */ -#endif -#ifndef CWERASE -# define CWERASE '\027' /* ^W */ -#endif -#ifndef CLNEXT -# define CLNEXT '\026' /* ^V */ -#endif - -#ifndef VDISCRD -# ifdef VDISCARD -# define VDISCRD VDISCARD -# endif -#endif - -#ifndef VWERSE -# ifdef VWERASE -# define VWERSE VWERASE -# endif -#endif - -/* defines: */ - -#define KBUFSZ 8 /* size of keyboard mapping buffer */ -#define STRING_MAX 512 /* max string size for process_xterm_seq() */ -#define ESC_ARGS 32 /* max # of args for esc sequences */ - -/* a large REFRESH_PERIOD causes problems with `cat' */ - -#ifndef REFRESH_PERIOD -# define REFRESH_PERIOD 3 -#endif - -#ifndef MULTICLICK_TIME -# define MULTICLICK_TIME 500 -#endif -#ifndef SCROLLBAR_INITIAL_DELAY -# define SCROLLBAR_INITIAL_DELAY 40 -#endif -#ifndef SCROLLBAR_CONTINUOUS_DELAY -# define SCROLLBAR_CONTINUOUS_DELAY 2 -#endif - -/* time factor to slow down a `jumpy' mouse */ -#define MOUSE_THRESHOLD 50 -#define CONSOLE "/dev/console" /* console device */ - -/* - * key-strings: if only these keys were standardized - */ -#ifdef LINUX_KEYS -# define KS_HOME "\033[1~" /* Home == Find */ -# define KS_END "\033[4~" /* End == Select */ -#else -# define KS_HOME "\033[7~" /* Home */ -# define KS_END "\033[8~" /* End */ -#endif - -/* and this one too! */ -#ifdef NO_DELETE_KEY -# undef KS_DELETE /* use X server definition */ -#else -# ifndef KS_DELETE -# define KS_DELETE "\033[3~" /* Delete = Execute */ -# endif -#endif - -/* - * ESC-Z processing: - * - * By stealing a sequence to which other xterms respond, and sending the - * same number of characters, but having a distinguishable sequence, - * we can avoid having a timeout (when not under an Eterm) for every login - * shell to auto-set its DISPLAY. - * - * This particular sequence is even explicitly stated as obsolete since - * about 1985, so only very old software is likely to be confused, a - * confusion which can likely be remedied through termcap or TERM. Frankly, - * I doubt anyone will even notice. We provide a #ifdef just in case they - * don't care about auto-display setting. Just in case the ancient - * software in question is broken enough to be case insensitive to the 'c' - * character in the answerback string, we make the distinguishing - * characteristic be capitalization of that character. The length of the - * two strings should be the same so that identical read(2) calls may be - * used. - */ -#define VT100_ANS "\033[?1;2c" /* vt100 answerback */ -#ifndef ESCZ_ANSWER -# define ESCZ_ANSWER VT100_ANS /* obsolete ANSI ESC[c */ -#endif - -/* Global attributes */ -extern XWindowAttributes attr; -extern XSetWindowAttributes Attributes; -extern char *orig_argv0; - -#ifdef PIXMAP_SUPPORT -extern short bg_needs_update; - -#endif - -/* extern functions referenced */ -extern char *ptsname(); - -#ifdef DISPLAY_IS_IP -extern char *network_display(const char *display); - -#endif - -extern void get_initial_options(int, char **); -extern void menubar_read(const char *filename); - +#include "screen.h" +#include "scrollbar.h" +#include "string.h" +#include "term.h" #ifdef USE_POSIX_THREADS -extern static void **retval; -extern static int join_value; -extern static pthread_t main_loop_thr; -extern static pthread_attr_t main_loop_attr; - -# ifdef MUTEX_SYNCH -extern pthread_mutex_t mutex; - -# endif +# include "threads.h" #endif - -#ifdef PIXMAP_SUPPORT -extern void render_pixmap(Window win, imlib_t image, pixmap_t pmap, - int which, renderop_t renderop); - -# ifdef BACKING_STORE -extern const char *rs_saveUnder; - -# endif - -extern char *rs_noCursor; - -# ifdef USE_IMLIB -extern ImlibData *imlib_id; - -# endif -#endif - -/* extern variables referenced */ -extern int my_ruid, my_rgid, my_euid, my_egid; - -#ifdef PIXMAP_OFFSET -extern unsigned int rs_shadePct; -extern unsigned long rs_tintMask; - -#endif - -#ifdef PIXMAP_OFFSET -extern Pixmap desktop_pixmap, viewport_pixmap; - -#endif - -/* extern variables declared here */ -extern TermWin_t TermWin; -extern Display *Xdisplay; /* display */ - -extern char *rs_color[NRS_COLORS]; -extern Pixel PixColors[NRS_COLORS + NSHADOWCOLORS]; - -extern unsigned long Options; - -extern const char *display_name; -extern char *rs_name; /* client instance (resource name) */ - -#ifndef NO_BOLDFONT -extern const char *rs_boldFont; - -#endif -extern const char *rs_font[NFONTS]; - -#ifdef KANJI -extern const char *rs_kfont[NFONTS]; - -#endif - -#ifdef PRINTPIPE -extern char *rs_print_pipe; - -#endif - -extern char *rs_cutchars; - -/* local variables */ -extern Cursor TermWin_cursor; /* cursor for vt window */ -extern unsigned int colorfgbg; -extern menuBar_t menuBar; -unsigned char keypress_exit = 0; - -extern XSizeHints szHint; - -extern char *def_colorName[]; - -#ifdef KANJI -/* Kanji font names, roman fonts sized to match */ -extern const char *def_kfontName[]; - -#endif /* KANJI */ -extern const char *def_fontName[]; - -/* extern functions referenced */ -#ifdef PIXMAP_SUPPORT -/* the originally loaded pixmap and its scaling */ -extern pixmap_t bgPixmap; -extern void set_bgPixmap(const char * /* file */ ); - -# ifdef USE_IMLIB -extern imlib_t imlib_bg; - -# endif -# ifdef PIXMAP_SCROLLBAR -extern pixmap_t sbPixmap; -extern pixmap_t upPixmap, up_clkPixmap; -extern pixmap_t dnPixmap, dn_clkPixmap; -extern pixmap_t saPixmap, sa_clkPixmap; - -# ifdef USE_IMLIB -extern imlib_t imlib_sb, imlib_sa, imlib_saclk; - -# endif -# endif -# ifdef PIXMAP_MENUBAR -extern pixmap_t mbPixmap, mb_selPixmap; - -# ifdef USE_IMLIB -extern imlib_t imlib_mb, imlib_ms; - -# endif -# endif - -extern int scale_pixmap(const char *geom, pixmap_t * pmap); - -#endif /* PIXMAP_SUPPORT */ - -/* have we changed the font? Needed to avoid race conditions - * while window resizing */ -extern int font_change_count; - -static void resize(void); - -/* extern functions referenced */ #ifdef UTMP_SUPPORT -extern void cleanutent(void); -extern void makeutent(const char *, const char *); - -#else -# define cleanutent() ((void)(0)) -# define makeutent(pty, hostname) ((void)(0)) +# include "eterm_utmp.h" #endif - -/* extern variables referenced */ -extern int my_ruid, my_rgid, my_euid, my_egid; - -/* extern variables declared here */ +#include "windows.h" /* local variables */ -/* static unsigned char segv=0; */ +int my_ruid, my_euid, my_rgid, my_egid; char initial_dir[PATH_MAX + 1]; static char *ptydev = NULL, *ttydev = NULL; /* pty/tty name */ - -#ifdef USE_ACTIVE_TAGS int cmd_fd = -1; /* file descriptor connected to the command */ pid_t cmd_pid = -1; /* process id if child */ - -#else -static int cmd_fd = -1; /* file descriptor connected to the command */ -static pid_t cmd_pid = -1; /* process id if child */ - -#endif -static int Xfd = -1; /* file descriptor of X server connection */ -static unsigned int num_fds = 0; /* number of file descriptors being used */ -static struct stat ttyfd_stat; /* original status of the tty we will use */ - -#ifdef SCROLLBAR_BUTTON_CONTINUAL_SCROLLING -static int scroll_arrow_delay; - -#endif - -#ifdef META8_OPTION -static unsigned char meta_char = 033; /* Alt-key prefix */ - -#endif - -unsigned long PrivateModes = PrivMode_Default; -static unsigned long SavedModes = PrivMode_Default; - -#ifndef USE_POSIX_THREADS -static int refresh_count = 0, refresh_limit = 1; - -#else -int refresh_count = 0, refresh_limit = 1; - -#endif - -/* Why? -vendu */ -/* static int refresh_type = SLOW_REFRESH; */ -static int refresh_type = FAST_REFRESH; - -static Atom wmDeleteWindow; - +int Xfd = -1; /* file descriptor of X server connection */ +unsigned int num_fds = 0; /* number of file descriptors being used */ +struct stat ttyfd_stat; /* original status of the tty we will use */ +int refresh_count = 0, refresh_limit = 1, refresh_type = FAST_REFRESH; +Atom wmDeleteWindow; +unsigned char cmdbuf_base[CMD_BUF_SIZE], *cmdbuf_ptr, *cmdbuf_endp; +/* Addresses pasting large amounts of data + * code pinched from xterm + */ +static char *v_buffer; /* pointer to physical buffer */ +static char *v_bufstr = NULL; /* beginning of area to write */ +static char *v_bufptr; /* end of area to write */ +static char *v_bufend; /* end of physical buffer */ /* OffiX Dnd (drag 'n' drop) support */ #ifdef OFFIX_DND static Atom DndProtocol, DndSelection; - #endif /* OFFIX_DND */ - -#ifndef NO_XLOCALE -static char *rs_inputMethod = ""; /* XtNinputMethod */ -static char *rs_preeditType = NULL; /* XtNpreeditType */ -static XIC Input_Context; /* input context */ - -#endif /* NO_XLOCALE */ - -/* command input buffering */ - -#if defined(linux) && defined(N_TTY_BUF_SIZE) -# define CMD_BUF_SIZE N_TTY_BUF_SIZE -#else -# ifndef CMD_BUF_SIZE -# define CMD_BUF_SIZE 4096 -# endif +#ifdef USE_XIM +XIC Input_Context = NULL; /* input context */ #endif -#ifndef USE_POSIX_THREADS -static unsigned char cmdbuf_base[CMD_BUF_SIZE], *cmdbuf_ptr, *cmdbuf_endp; - -#else -unsigned char cmdbuf_base[CMD_BUF_SIZE], *cmdbuf_ptr, *cmdbuf_endp; - -#endif - -/* local functions referenced */ -void privileges(int mode); - -RETSIGTYPE Child_signal(int); -RETSIGTYPE Exit_signal(int); -int get_pty(void); -int get_tty(void); -int run_command(char * /* argv */ []); -unsigned char cmd_getc(void); - -#if 0 -void lookup_key(XEvent * /* ev */ ); - -#endif -inline void lookup_key(XEvent * /* ev */ ); -void process_x_event(XEvent * /* ev */ ); - -/*static void process_string (int); */ -#ifdef PRINTPIPE -void process_print_pipe(void); - -#endif -void process_escape_seq(void); -void process_csi_seq(void); -void process_xterm_seq(void); -void process_window_mode(unsigned int, int[]); -void process_terminal_mode(int, int, unsigned int, int[]); -void process_sgr_mode(unsigned int, int[]); -void process_graphics(void); - -void tt_winsize(int); - -#ifndef NO_XLOCALE -void init_xlocale(void); - -#else -# define init_xlocale() ((void)0) -#endif - -/*for Big Paste Handling */ -static int v_doPending(void); -static void v_writeBig(int, char *, int); - -/*----------------------------------------------------------------------*/ - /* Substitutes for missing system functions */ -#ifndef _POSIX_VERSION -# if defined (__svr4__) +#if !defined(_POSIX_VERSION) && defined(__svr4__) int getdtablesize(void) { @@ -665,7 +177,6 @@ getdtablesize(void) getrlimit(RLIMIT_NOFILE, &rlim); return rlim.rlim_cur; } -# endif # endif /* Take care of suid/sgid super-user (root) privileges */ @@ -1448,11 +959,6 @@ request_code_to_name(int code) } /* Try to get a stack trace when we croak */ -#ifdef HAVE_U_STACK_TRACE -extern void U_STACK_TRACE(void); - -#endif - void dump_stack_trace(void) { @@ -1488,6 +994,18 @@ dump_stack_trace(void) system(cmd); } +void +hard_exit(void) { + + dump_stack_trace(); +#ifdef HAVE__EXIT + _exit(-1); +#else + abort(); +#endif + +} + /* signal handling, exit handler */ /* * Catch a SIGCHLD signal and exit if the direct child has died @@ -1513,9 +1031,9 @@ Child_signal(int sig) if (Options & Opt_pause) { const char *message = "\r\nPress any key to exit " APL_NAME "...."; - scr_refresh(SMOOTH_REFRESH); + scr_refresh(DEFAULT_REFRESH); scr_add_lines(message, 1, strlen(message)); - scr_refresh(SMOOTH_REFRESH); + scr_refresh(DEFAULT_REFRESH); keypress_exit = 1; return; } @@ -1526,10 +1044,7 @@ Child_signal(int sig) D_CMD(("Child_signal: installing signal handler\n")); signal(SIGCHLD, Child_signal); -#ifdef NEED_EXPLICIT_RETURN - D_CMD(("FUN FUN FUN. Child_signal returned 0 :)\n")); return ((RETSIGTYPE) 0); -#endif } /* Handles signals usually sent by a user, like HUP, TERM, INT. */ @@ -1546,9 +1061,6 @@ Exit_signal(int sig) privileges(REVERT); #endif - /* No! This causes unhandled signal propogation! -- mej */ - /* kill(getpid(), sig); */ - D_CMD(("Exit_signal(): exit(%s)\n", sig_to_str(sig))); exit(sig); } @@ -1607,69 +1119,6 @@ clean_exit(void) D_THREADS(("pthread_exit();\n")); # endif #endif - - /* Work around a nasty Solaris X bug. If we're not unmapped in - 3 seconds, it ain't gonna happen. Die anyway. -- mej */ -#ifdef HAVE__EXIT - signal(SIGALRM, _exit); -#else - signal(SIGALRM, abort); -#endif - alarm(3); - - /* Close the display connection to the X server. Unmap the windows - * first. - */ - D_X11(("XUnmapWindow(Xdisplay, TermWin.parent);\n")); - XUnmapWindow(Xdisplay, TermWin.parent); - D_X11(("XSync(Xdisplay, TRUE) - discarding events\n")); - /* XSync discards all events in the event queue. */ - XSync(Xdisplay, TRUE); - D_X11(("XCloseDisplay(Xdisplay);\n")); - XCloseDisplay(Xdisplay); -} -#if (MENUBAR_MAX) -inline void -map_menuBar(int map) -{ - - if (delay_menu_drawing) { - delay_menu_drawing++; - } else if (menubar_mapping(map)) { - resize(); - } - PrivMode(map, PrivMode_menuBar); -} -#endif /* MENUBAR_MAX */ - -inline void -map_scrollBar(int map) -{ - - if (scrollbar_mapping(map)) { - scr_touch(); - resize(); - } - PrivMode(map, PrivMode_scrollBar); -} - - -/* Returns true if running under E, false otherwise */ -inline unsigned char -check_for_enlightenment(void) -{ - static char have_e = -1; - - if (have_e == -1) { - if (XInternAtom(Xdisplay, "ENLIGHTENMENT_COMMS", True) != None) { - D_X11(("Enlightenment detected.\n")); - have_e = 1; - } else { - D_X11(("Enlightenment not detected.\n")); - have_e = 0; - } - } - return (have_e); } /* Acquire a pseudo-teletype from the system. */ @@ -1688,7 +1137,7 @@ sgi_get_pty(void) int fd = -1; - ptydev = ttydev = _getpty(&fd, O_RDWR | O_NDELAY, 0622, 0); + ptydev = ttydev = _getpty(&fd, O_RDWR | O_NDELAY, 0620, 0); return (ptydev == NULL ? -1 : fd); } @@ -1911,7 +1360,7 @@ get_tty(void) * child processes remain alive upon deletion of the window. */ { - int i; + unsigned short i; for (i = 0; i < num_fds; i++) { if (i != fd) @@ -2195,6 +1644,399 @@ get_ttymode(ttymode_t * tio) #endif /* HAVE_TERMIOS_H */ } +/* Xlocale */ +XFontSet +create_fontset(const char *font1, const char *font2) +{ + XFontSet fontset = 0; + char *fontname, **ml, *ds; + int mc; + const char fs_base[] = ",-misc-fixed-*-r-*-*-*-120-*-*-*-*-*-*"; + + ASSERT(font1 != NULL); + +#ifdef MULTI_CHARSET + if (!font2) { + font2 = "*"; + } + fontname = MALLOC(strlen(font1) + strlen(font2) + sizeof(fs_base) + 2); + if (fontname) { + strcpy(fontname, font1); + strcat(fontname, fs_base); + strcat(fontname, ","); + strcat(fontname, font2); + } +#else + fontname = MALLOC(strlen(font1) + sizeof(fs_base) + 1); + if (fontname) { + strcpy(fontname, font1); + strcat(fontname, fs_base); + } +#endif + if (fontname) { + setlocale(LC_ALL, ""); + fontset = XCreateFontSet(Xdisplay, fontname, &ml, &mc, &ds); + FREE(fontname); + if (mc) { + XFreeStringList(ml); + fontset = 0; + } + } + return fontset; +} + +#if defined(USE_XIM) || defined(MULTI_CHARSET) + +#ifdef USE_XIM +static int xim_real_init(void); +# ifdef USE_X11R6_XIM +static void xim_destroy_cb(XIM xim, XPointer client_data, + XPointer call_data); +static void xim_instantiate_cb(Display *display, XPointer client_data, + XPointer call_data); +# endif +#endif + +void +init_locale(void) +{ + char *locale = NULL; + + locale = setlocale(LC_CTYPE, ""); + TermWin.fontset = (XFontSet) -1; + if (locale == NULL) + print_error("Setting locale failed."); + else { +#ifdef MULTI_CHARSET + TermWin.fontset = create_fontset(rs_font[0], rs_mfont[0]); +#else + TermWin.fontset = create_fontset(rs_font[0], (const char *) NULL); +#endif +#ifdef USE_XIM +# ifdef MULTI_CHARSET + if (strcmp(locale, "C")) +# endif + { + if (xim_real_init() != -1) + return; + +# ifdef USE_X11R6_XIM + XRegisterIMInstantiateCallback(Xdisplay, NULL, NULL, NULL, + xim_instantiate_cb, NULL); +# endif + } +#endif + } +} +#endif /* USE_XIM || MULTI_CHARSET */ + +#ifdef USE_XIM + +static void +xim_set_size(XRectangle * size) +{ + size->x = TermWin.internalBorder; + size->y = TermWin.internalBorder; + size->width = Width2Pixel(TermWin.ncol); + size->height = Height2Pixel(TermWin.nrow); +} + +static void +xim_set_color(unsigned long *fg, unsigned long *bg) +{ + *fg = PixColors[fgColor]; + *bg = PixColors[bgColor]; +} + +static void +xim_send_spot(void) +{ + XPoint spot; + XVaNestedList preedit_attr; + XIMStyle input_style; + + if (Input_Context == NULL) + return; + else { + XGetICValues(Input_Context, XNInputStyle, &input_style, NULL); + if (!(input_style & XIMPreeditPosition)) + return; + } + xim_get_position(&spot); + + preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL); + XSetICValues(Input_Context, XNPreeditAttributes, preedit_attr, NULL); + XFree(preedit_attr); +} + +static void +xim_get_area(XRectangle *preedit_rect, XRectangle *status_rect, + XRectangle *needed_rect) +{ + preedit_rect->x = needed_rect->width + + (scrollbar_visible() && !(Options & Opt_scrollBar_right) + ? (SB_WIDTH) : 0); + preedit_rect->y = Height2Pixel(TermWin.nrow - 1); + + preedit_rect->width = Width2Pixel(TermWin.ncol + 1) - needed_rect->width + + (!(Options & Opt_scrollBar_right) + ? (SB_WIDTH) : 0); + preedit_rect->height = Height2Pixel(1); + + status_rect->x = (scrollbar_visible() && !(Options & Opt_scrollBar_right)) + ? (SB_WIDTH) : 0; + status_rect->y = Height2Pixel(TermWin.nrow - 1); + + status_rect->width = needed_rect->width ? needed_rect->width + : Width2Pixel(TermWin.ncol + 1); + status_rect->height = Height2Pixel(1); +} + +#ifdef USE_X11R6_XIM +static void +xim_destroy_cb(XIM xim, XPointer client_data, XPointer call_data) +{ + Input_Context = NULL; + XRegisterIMInstantiateCallback(Xdisplay, NULL, NULL, NULL, + xim_instantiate_cb, NULL); +} + +static void +xim_instantiate_cb(Display *display, XPointer client_data, + XPointer call_data) +{ + xim_real_init(); + if (Input_Context) + XUnregisterIMInstantiateCallback(Xdisplay, NULL, NULL, NULL, + xim_instantiate_cb, NULL); +} +#endif + +static int +xim_real_init(void) +{ + char *p, *s, buf[64], tmp[1024]; + char *end, *next_s; + XIM xim = NULL; + XIMStyle input_style = 0; + XIMStyles *xim_styles = NULL; + int found; + XPoint spot; + XRectangle rect, status_rect, needed_rect; + unsigned long fg, bg; + XVaNestedList preedit_attr = NULL; + XVaNestedList status_attr = NULL; + + if (Input_Context) + return 0; + + if (rs_inputMethod && *rs_inputMethod) { + strncpy(tmp, rs_inputMethod, sizeof(tmp) - 1); + for (s = tmp; *s; s = next_s + 1) { + for (; *s && isspace(*s); s++) ; + if (!*s) + break; + for (end = s; (*end && (*end != ',')); end++) ; + for (next_s = end--; ((end >= s) && isspace(*end)); end--) ; + *(end + 1) = '\0'; + + if (*s) { + snprintf(buf, sizeof(buf), "@im=%s", s); + if ((p = XSetLocaleModifiers(buf)) != NULL && *p + && (xim = XOpenIM(Xdisplay, NULL, NULL, NULL)) != NULL) + break; + } + if (!*next_s) + break; + } + } + + /* try with XMODIFIERS env. var. */ + if (xim == NULL && (p = XSetLocaleModifiers("")) != NULL && *p) + xim = XOpenIM(Xdisplay, NULL, NULL, NULL); + +#ifndef USE_X11R6_XIM + /* try with no modifiers base */ + if (xim == NULL && (p = XSetLocaleModifiers("@im=none")) != NULL && *p) + xim = XOpenIM(Xdisplay, NULL, NULL, NULL); +#endif + + if (xim == NULL) + xim = XOpenIM(Xdisplay, NULL, NULL, NULL); + + if (xim == NULL) + return -1; + +#ifdef USE_X11R6_XIM + { + XIMCallback destroy_cb; + + destroy_cb.callback = xim_destroy_cb; + destroy_cb.client_data = NULL; + if (XSetIMValues(xim, XNDestroyCallback, &destroy_cb, NULL)) + print_error("Could not set destroy callback to IM"); + } +#endif + + if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) + || !xim_styles) { + print_error("input method doesn't support any style"); + XCloseIM(xim); + return -1; + } + strncpy(tmp, (rs_preeditType ? rs_preeditType + : "OverTheSpot,OffTheSpot,Root"), + sizeof(tmp) - 1); + for (found = 0, s = tmp; *s && !found; s = next_s + 1) { + unsigned short i; + + for (; *s && isspace(*s); s++) ; + if (!*s) + break; + for (end = s; (*end && (*end != ',')); end++) ; + for (next_s = end--; ((end >= s) && isspace(*end)); end--) ; + *(end + 1) = '\0'; + + if (!strcmp(s, "OverTheSpot")) + input_style = (XIMPreeditPosition | XIMStatusNothing); + else if (!strcmp(s, "OffTheSpot")) + input_style = (XIMPreeditArea | XIMStatusArea); + else if (!strcmp(s, "Root")) + input_style = (XIMPreeditNothing | XIMStatusNothing); + + for (i = 0; i < xim_styles->count_styles; i++) { + if (input_style == xim_styles->supported_styles[i]) { + found = 1; + break; + } + } + } + XFree(xim_styles); + + if (found == 0) { + print_error("input method doesn't support my preedit type"); + XCloseIM(xim); + return -1; + } + if ((input_style != (XIMPreeditNothing | XIMStatusNothing)) + && (input_style != (XIMPreeditArea | XIMStatusArea)) + && (input_style != (XIMPreeditPosition | XIMStatusNothing))) { + print_error("This program does not support the preedit type"); + XCloseIM(xim); + return -1; + } + if (input_style & XIMPreeditPosition) { + xim_set_size(&rect); + xim_get_position(&spot); + xim_set_color(&fg, &bg); + + preedit_attr = XVaCreateNestedList(0, XNArea, &rect, + XNSpotLocation, &spot, + XNForeground, fg, + XNBackground, bg, + XNFontSet, TermWin.fontset, + NULL); + } else if (input_style & XIMPreeditArea) { + xim_set_color(&fg, &bg); + + /* + * The necessary width of preedit area is unknown + * until create input context. + */ + needed_rect.width = 0; + + xim_get_area(&rect, &status_rect, &needed_rect); + + preedit_attr = XVaCreateNestedList(0, XNArea, &rect, + XNForeground, fg, + XNBackground, bg, + XNFontSet, TermWin.fontset, + NULL); + status_attr = XVaCreateNestedList(0, XNArea, &status_rect, + XNForeground, fg, + XNBackground, bg, + XNFontSet, TermWin.fontset, + NULL); + } + + Input_Context = XCreateIC(xim, XNInputStyle, input_style, + XNClientWindow, TermWin.parent, + XNFocusWindow, TermWin.parent, + preedit_attr ? XNPreeditAttributes : NULL, + preedit_attr, + status_attr ? XNStatusAttributes : NULL, + status_attr, + NULL); + XFree(preedit_attr); + XFree(status_attr); + if (Input_Context == NULL) { + print_error("Failed to create input context"); + XCloseIM(xim); + return -1; + } + + if (input_style & XIMPreeditArea) + xim_set_status_position(); + return 0; +} + +void +xim_set_status_position(void) +{ + XIMStyle input_style; + XRectangle preedit_rect, status_rect, *needed_rect; + XVaNestedList preedit_attr, status_attr; + + if (Input_Context == NULL) + return; + + XGetICValues(Input_Context, XNInputStyle, &input_style, NULL); + + if (input_style & XIMPreeditArea) { + /* Getting the necessary width of preedit area */ + status_attr = XVaCreateNestedList(0, XNAreaNeeded, &needed_rect, NULL); + XGetICValues(Input_Context, XNStatusAttributes, status_attr, NULL); + XFree(status_attr); + + xim_get_area(&preedit_rect, &status_rect, needed_rect); + + preedit_attr = XVaCreateNestedList(0, XNArea, &preedit_rect, NULL); + status_attr = XVaCreateNestedList(0, XNArea, &status_rect, NULL); + + XSetICValues(Input_Context, + XNPreeditAttributes, preedit_attr, + XNStatusAttributes, status_attr, NULL); + + XFree(preedit_attr); + XFree(status_attr); + } +} + +void xim_set_fontset(void) +{ + XIMStyle input_style; + XVaNestedList preedit_attr; + XVaNestedList status_attr; + + if (Input_Context == NULL) + return; + + XGetICValues(Input_Context, XNInputStyle, &input_style, NULL); + + if (input_style & (XIMPreeditArea | XIMPreeditPosition)) { + preedit_attr = XVaCreateNestedList(0, XNFontSet, TermWin.fontset, NULL); + status_attr = XVaCreateNestedList(0, XNFontSet, TermWin.fontset, NULL); + + XSetICValues(Input_Context, + XNPreeditAttributes, preedit_attr, + XNStatusAttributes, status_attr, NULL); + + XFree(preedit_attr); + XFree(status_attr); + } +} +#endif /* USE_XIM */ + /* run_command() */ /* * Run the command in a subprocess and return a file descriptor for the @@ -2244,10 +2086,6 @@ run_command(char *argv[]) PrivateModes |= PrivMode_scrollBar; SavedModes |= PrivMode_scrollBar; } - if (menubar_visible()) { - PrivateModes |= PrivMode_menuBar; - SavedModes |= PrivMode_menuBar; - } #if DEBUG >= DEBUG_TTYMODE && defined(HAVE_TERMIOS_H) if (debug_level >= DEBUG_TTYMODE) { debug_ttymode(&tio); @@ -2357,7 +2195,9 @@ run_command(char *argv[]) /* command interpreter path */ D_CMD(("[%d] About to spawn shell\n", getpid())); - chdir(initial_dir); + if (chdir(initial_dir)) { + print_warning("Unable to chdir to \"%s\" -- %s\n", initial_dir, strerror(errno)); + } if (argv != NULL) { #if DEBUG >= DEBUG_CMD if (debug_level >= DEBUG_CMD) { @@ -2425,7 +2265,7 @@ init_command(char *argv[]) DndSelection = XInternAtom(Xdisplay, "DndSelection", False); #endif /* OFFIX_DND */ - init_xlocale(); + init_locale(); /* get number of available file descriptors */ #ifdef _POSIX_VERSION @@ -2452,175 +2292,6 @@ init_command(char *argv[]) } } -/* Xlocale */ -#ifndef NO_XLOCALE -inline const char * -get_input_style_flags(XIMStyle style) -{ - - static char style_buff[256]; - - strcpy(style_buff, "("); - if (style & XIMPreeditCallbacks) { - strcat(style_buff, "XIMPreeditCallbacks"); - } else if (style & XIMPreeditPosition) { - strcat(style_buff, "XIMPreeditPosition"); - } else if (style & XIMPreeditArea) { - strcat(style_buff, "XIMPreeditArea"); - } else if (style & XIMPreeditNothing) { - strcat(style_buff, "XIMPreeditNothing"); - } else if (style & XIMPreeditNone) { - strcat(style_buff, "XIMPreeditNone"); - } - strcat(style_buff, " | "); - if (style & XIMStatusCallbacks) { - strcat(style_buff, "XIMStatusCallbacks"); - } else if (style & XIMStatusArea) { - strcat(style_buff, "XIMStatusArea"); - } else if (style & XIMStatusNothing) { - strcat(style_buff, "XIMStatusNothing"); - } else if (style & XIMStatusNone) { - strcat(style_buff, "XIMStatusNone"); - } - strcat(style_buff, ")"); - return style_buff; -} - -void -init_xlocale(void) -{ - - char *p, *s, buf[32], tmp[1024]; - XIM xim = NULL; - XIMStyle input_style; - XIMStyles *xim_styles = NULL; - int found, i, mc; - XFontSet fontset = 0; - char *fontname, **ml, *ds; - XVaNestedList list; - const char fs_base[] = ",-misc-fixed-*-r-*-*-*-120-*-*-*-*-*-*"; - - D_X11(("Initializing X locale and Input Method...\n")); - Input_Context = NULL; - if (rs_inputMethod && strlen(rs_inputMethod) >= sizeof(tmp)) { - print_error("Input Method too long, ignoring."); - rs_inputMethod = NULL; - } -# ifdef KANJI - setlocale(LC_CTYPE, ""); -# else - if (rs_inputMethod && !*rs_inputMethod) { - rs_inputMethod = NULL; - } -# endif - - if (rs_inputMethod == NULL) { - if ((p = XSetLocaleModifiers("@im=none")) != NULL && *p) { - xim = XOpenIM(Xdisplay, NULL, NULL, NULL); - } - } else { - strcpy(tmp, rs_inputMethod); - for (s = tmp; *s; /*nil */ ) { - - char *end, *next_s; - - for (; *s && isspace(*s); s++); - if (!*s) - break; - end = s; - for (; *end && (*end != ','); end++); - next_s = end--; - for (; (end >= s) && isspace(*end); end--); - *(end + 1) = '\0'; - - if (*s) { - snprintf(buf, sizeof(buf), "@im=%s", s); - if ((p = XSetLocaleModifiers(buf)) != NULL && *p && (xim = XOpenIM(Xdisplay, NULL, NULL, NULL)) != NULL) { - break; - } - } - if (!*next_s) - break; - s = (next_s + 1); - } - } - - if (xim == NULL && (p = XSetLocaleModifiers("")) != NULL && *p) { - xim = XOpenIM(Xdisplay, NULL, NULL, NULL); - } - if (xim == NULL) { - D_X11(("Error: Failed to open Input Method\n")); - return; - } else { - D_X11(("Opened X Input Method. xim == 0x%08x\n", xim)); - } - - if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL) || !xim_styles) { - D_X11(("Error: Input Method doesn't support any style\n")); - XCloseIM(xim); - return; - } else { - D_X11((" -> Input Method supports %d styles.\n", xim_styles->count_styles)); - } - - /* We only support the Root preedit type */ - input_style = (XIMPreeditNothing | XIMStatusNothing); - D_X11((" -> input_style == 0x%08x\n", input_style)); - - for (i = 0, found = 0; i < xim_styles->count_styles; i++) { - D_X11((" -> Supported style flags: 0x%08x %s\n", xim_styles->supported_styles[i], get_input_style_flags(xim_styles->supported_styles[i]))); - D_X11((" -> 0x%08x %s\n", xim_styles->supported_styles[i] & input_style, - get_input_style_flags(xim_styles->supported_styles[i] & input_style))); - if ((xim_styles->supported_styles[i] & input_style) == (xim_styles->supported_styles[i])) { - input_style = xim_styles->supported_styles[i]; - found = 1; - break; - } - } - XFree(xim_styles); - - if (!found) { - D_X11(("Error: " APL_NAME " " VERSION " only supports the \"Root\" preedit type, which the Input Method does not support.\n")); - XCloseIM(xim); - return; - } - /* Create Font Set */ - -#ifdef KANJI - fontname = MALLOC(strlen(rs_font[0]) + strlen(rs_kfont[0]) + sizeof(fs_base) + 2); - if (fontname) { - strcpy(fontname, rs_font[0]); - strcat(fontname, fs_base); - strcat(fontname, ","); - strcat(fontname, rs_kfont[0]); - } -#else - fontname = MALLOC(strlen(rs_font[0]) + sizeof(fs_base) + 1); - if (fontname) { - strcpy(fontname, rs_font[0]); - strcat(fontname, fs_base); - } -#endif - if (fontname) { - setlocale(LC_ALL, ""); - fontset = XCreateFontSet(Xdisplay, fontname, &ml, &mc, &ds); - FREE(fontname); - if (mc) { - XFreeStringList(ml); - fontset = 0; - return; - } - } - list = XVaCreateNestedList(0, XNFontSet, fontset, NULL); - Input_Context = XCreateIC(xim, XNInputStyle, input_style, XNClientWindow, TermWin.parent, XNFocusWindow, TermWin.parent, - XNPreeditAttributes, list, XNStatusAttributes, list, NULL); - if (Input_Context == NULL) { - D_X11(("Error: Unable to create Input Context\n")); - XCloseIM(xim); - } -} -#endif /* NO_XLOCALE */ - /* window resizing */ /* * Tell the teletype handler what size the window is. @@ -2649,563 +2320,6 @@ tt_resize(void) tt_winsize(cmd_fd); } -/* Convert the keypress event into a string */ -inline void -lookup_key(XEvent * ev) -{ - - static int numlock_state = 0; - static unsigned char kbuf[KBUFSZ]; - int ctrl, meta, shft, len; - KeySym keysym; - -#ifndef NO_XLOCALE - static Status status_return; - -#endif - -#if DEBUG >= DEBUG_CMD - static int debug_key = 1; /* accessible by a debugger only */ - -#endif -#ifdef GREEK_SUPPORT - static short greek_mode = 0; - -#endif - - /* - * use Num_Lock to toggle Keypad on/off. If Num_Lock is off, allow an - * escape sequence to toggle the Keypad. - * - * Always permit `shift' to override the current setting - */ - shft = (ev->xkey.state & ShiftMask); - ctrl = (ev->xkey.state & ControlMask); - meta = (ev->xkey.state & Mod1Mask); - if (numlock_state || (ev->xkey.state & Mod5Mask)) { - numlock_state = (ev->xkey.state & Mod5Mask); /* numlock toggle */ - PrivMode((!numlock_state), PrivMode_aplKP); - } -#ifndef NO_XLOCALE - if (Input_Context != NULL) { - len = XmbLookupString(Input_Context, &ev->xkey, kbuf, sizeof(kbuf), &keysym, &status_return); - if (status_return == XLookupNone) { - D_X11(("XmbLookupString() returned len == %d, status_return == XLookupNone\n", len)); - len = 0; - } else if (status_return == XBufferOverflow) { - D_X11(("XmbLookupString() returned len == %d, status_return == XBufferOverflow\n", len)); - print_error("XmbLookupString(): Buffer overflow, string too long."); - XmbResetIC(Input_Context); - } else if (status_return == XLookupKeySym) { - D_X11(("XmbLookupString() returned len == %d, status_return == XLookupKeySym\n", len)); - if ((keysym >= 0x0100) && (keysym < 0x0400)) { - len = 1; - kbuf[0] = (keysym & 0xff); - } - } else if (status_return == XLookupBoth) { - D_X11(("XmbLookupString() returned len == %d, status_return == XLookupBoth\n", len)); - if ((keysym >= 0x0100) && (keysym < 0x0400)) { - len = 1; - kbuf[0] = (keysym & 0xff); - } - } else if (status_return == XLookupChars) { - D_X11(("XmbLookupString() returned len == %d, status_return == XLookupChars\n", len)); - /* Nothing */ - } - } else { - len = XLookupString(&ev->xkey, kbuf, sizeof(kbuf), &keysym, NULL); - } -#else /* NO_XLOCALE */ - len = XLookupString(&ev->xkey, kbuf, sizeof(kbuf), &keysym, NULL); - /* - * have unmapped Latin[2-4] entries -> Latin1 - * good for installations with correct fonts, but without XLOCAL - */ - if (!len && (keysym >= 0x0100) && (keysym < 0x0400)) { - len = 1; - kbuf[0] = (keysym & 0xff); - } -#endif /* NO_XLOCALE */ - - if (len && (Options & Opt_homeOnInput)) - TermWin.view_start = 0; - - /* for some backwards compatibility */ -#if defined (HOTKEY_CTRL) || defined (HOTKEY_META) -# ifdef HOTKEY_CTRL -# define HOTKEY ctrl -# else -# ifdef HOTKEY_META -# define HOTKEY meta -# endif -# endif - if (HOTKEY) { - if (keysym == ks_bigfont) { - change_font(0, FONT_UP); - return; - } else if (keysym == ks_smallfont) { - change_font(0, FONT_DN); - return; - } - } -# undef HOTKEY -#endif - - if (shft) { - /* Shift + F1 - F10 generates F11 - F20 */ - if (keysym >= XK_F1 && keysym <= XK_F10) { - keysym += (XK_F11 - XK_F1); - shft = 0; /* turn off Shift */ - } else if (!ctrl && !meta && (PrivateModes & PrivMode_ShiftKeys)) { - - int lnsppg; /* Lines per page to scroll */ - -#ifdef PAGING_CONTEXT_LINES - lnsppg = TermWin.nrow - PAGING_CONTEXT_LINES; -#else - lnsppg = TermWin.nrow * 4 / 5; -#endif - - switch (keysym) { - /* normal XTerm key bindings */ - case XK_Prior: /* Shift+Prior = scroll back */ - if (TermWin.saveLines) { - scr_page(UP, lnsppg); - return; - } - break; - - case XK_Next: /* Shift+Next = scroll forward */ - if (TermWin.saveLines) { - scr_page(DN, lnsppg); - return; - } - break; - - case XK_Insert: /* Shift+Insert = paste mouse selection */ - selection_request(ev->xkey.time, ev->xkey.x, ev->xkey.y); - return; - break; - - /* Eterm extras */ - case XK_KP_Add: /* Shift+KP_Add = bigger font */ - change_font(0, FONT_UP); - return; - break; - - case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */ - change_font(0, FONT_DN); - return; - break; - } - } - } -#ifdef UNSHIFTED_SCROLLKEYS - else if (!ctrl && !meta) { - switch (keysym) { - case XK_Prior: - if (TermWin.saveLines) { - scr_page(UP, TermWin.nrow * 4 / 5); - return; - } - break; - - case XK_Next: - if (TermWin.saveLines) { - scr_page(DN, TermWin.nrow * 4 / 5); - return; - } - break; - } - } -#endif - - switch (keysym) { - case XK_Print: -#if DEBUG >= DEBUG_SELECTION - if (debug_level >= DEBUG_SELECTION) { - debug_selection(); - } -#endif -#ifdef PRINTPIPE - scr_printscreen(ctrl | shft); - return; -#endif - break; - - case XK_Mode_switch: -#ifdef GREEK_SUPPORT - greek_mode = !greek_mode; - if (greek_mode) { - xterm_seq(XTerm_title, (greek_getmode() == GREEK_ELOT928 ? "[Greek: iso]" : "[Greek: ibm]")); - greek_reset(); - } else - xterm_seq(XTerm_title, APL_NAME "-" VERSION); - return; -#endif - break; - } - - if (keysym >= 0xFF00 && keysym <= 0xFFFF) { -#ifdef KEYSYM_ATTRIBUTE - if (!(shft | ctrl) && KeySym_map[keysym - 0xFF00] != NULL) { - - const unsigned char *kbuf; - unsigned int len; - - kbuf = (KeySym_map[keysym - 0xFF00]); - len = *kbuf++; - - /* escape prefix */ - if (meta -# ifdef META8_OPTION - && (meta_char == 033) -# endif - ) { - const unsigned char ch = '\033'; - - tt_write(&ch, 1); - } - tt_write(kbuf, len); - return; - } else -#endif - switch (keysym) { - case XK_BackSpace: - len = 1; -#ifdef FORCE_BACKSPACE - kbuf[0] = (!(shft | ctrl) ? '\b' : '\177'); -#elif defined(FORCE_DELETE) - kbuf[0] = ((shft | ctrl) ? '\b' : '\177'); -#else - kbuf[0] = (((PrivateModes & PrivMode_BackSpace) ? !(shft | ctrl) : (shft | ctrl)) ? '\b' : '\177'); -#endif - break; - - case XK_Tab: - if (shft) { - len = 3; - strcpy(kbuf, "\033[Z"); - } - break; - -#ifdef XK_KP_Home - case XK_KP_Home: - /* allow shift to override */ - if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { - len = 3; - strcpy(kbuf, "\033Ow"); - break; - } - /* -> else FALL THROUGH */ -#endif - - case XK_Home: - len = strlen(strcpy(kbuf, KS_HOME)); - break; - -#ifdef XK_KP_Left - case XK_KP_Left: /* \033Ot or standard */ - case XK_KP_Up: /* \033Ox or standard */ - case XK_KP_Right: /* \033Ov or standard */ - case XK_KP_Down: /* \033Ow or standard */ - if ((PrivateModes && PrivMode_aplKP) ? !shft : shft) { - len = 3; - strcpy(kbuf, "\033OZ"); - kbuf[2] = ("txvw"[keysym - XK_KP_Left]); - break; - } else { - /* translate to std. cursor key */ - keysym = XK_Left + (keysym - XK_KP_Left); - } - /* FALL THROUGH */ -#endif - case XK_Left: /* "\033[D" */ - case XK_Up: /* "\033[A" */ - case XK_Right: /* "\033[C" */ - case XK_Down: /* "\033[B" */ - len = 3; - strcpy(kbuf, "\033[@"); - kbuf[2] = ("DACB"[keysym - XK_Left]); - if (PrivateModes & PrivMode_aplCUR) { - kbuf[1] = 'O'; - } else if (shft) { /* do Shift first */ - kbuf[2] = ("dacb"[keysym - XK_Left]); - } else if (ctrl) { - kbuf[1] = 'O'; - kbuf[2] = ("dacb"[keysym - XK_Left]); - } - break; -#ifndef UNSHIFTED_SCROLLKEYS -# ifdef XK_KP_Prior - case XK_KP_Prior: - /* allow shift to override */ - if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { - len = 3; - strcpy(kbuf, "\033Oy"); - break; - } - /* -> else FALL THROUGH */ -# endif /* XK_KP_Prior */ - case XK_Prior: - len = 4; - strcpy(kbuf, "\033[5~"); - break; -# ifdef XK_KP_Next - case XK_KP_Next: - /* allow shift to override */ - if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { - len = 3; - strcpy(kbuf, "\033Os"); - break; - } - /* -> else FALL THROUGH */ -# endif /* XK_KP_Next */ - case XK_Next: - len = 4; - strcpy(kbuf, "\033[6~"); - break; -#endif /* UNSHIFTED_SCROLLKEYS */ -#ifdef XK_KP_End - case XK_KP_End: - /* allow shift to override */ - if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { - len = 3; - strcpy(kbuf, "\033Oq"); - break; - } - /* -> else FALL THROUGH */ -#endif /* XK_KP_End */ - case XK_End: - len = strlen(strcpy(kbuf, KS_END)); - break; - - case XK_Select: - len = 4; - strcpy(kbuf, "\033[4~"); - break; - -#ifdef DXK_Remove /* support for DEC remove like key */ - case DXK_Remove: /* drop */ -#endif - case XK_Execute: - len = 4; - strcpy(kbuf, "\033[3~"); - break; - case XK_Insert: - len = 4; - strcpy(kbuf, "\033[2~"); - break; - - case XK_Menu: - len = 5; - strcpy(kbuf, "\033[29~"); - break; - case XK_Find: - len = 4; - strcpy(kbuf, "\033[1~"); - break; - case XK_Help: - len = 5; - strcpy(kbuf, "\033[28~"); - break; - - case XK_KP_Enter: - /* allow shift to override */ - if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { - len = 3; - strcpy(kbuf, "\033OM"); - } else { - len = 1; - kbuf[0] = '\r'; - } - break; - -#ifdef XK_KP_Begin - case XK_KP_Begin: - len = 3; - strcpy(kbuf, "\033Ou"); - break; - - case XK_KP_Insert: - len = 3; - strcpy(kbuf, "\033Op"); - break; - - case XK_KP_Delete: - len = 3; - strcpy(kbuf, "\033On"); - break; -#endif /* XK_KP_Begin */ - - case XK_KP_F1: /* "\033OP" */ - case XK_KP_F2: /* "\033OQ" */ - case XK_KP_F3: /* "\033OR" */ - case XK_KP_F4: /* "\033OS" */ - len = 3; - strcpy(kbuf, "\033OP"); - kbuf[2] += (keysym - XK_KP_F1); - break; - - case XK_KP_Multiply: /* "\033Oj" : "*" */ - case XK_KP_Add: /* "\033Ok" : "+" */ - case XK_KP_Separator: /* "\033Ol" : "," */ - case XK_KP_Subtract: /* "\033Om" : "-" */ - case XK_KP_Decimal: /* "\033On" : "." */ - case XK_KP_Divide: /* "\033Oo" : "/" */ - case XK_KP_0: /* "\033Op" : "0" */ - case XK_KP_1: /* "\033Oq" : "1" */ - case XK_KP_2: /* "\033Or" : "2" */ - case XK_KP_3: /* "\033Os" : "3" */ - case XK_KP_4: /* "\033Ot" : "4" */ - case XK_KP_5: /* "\033Ou" : "5" */ - case XK_KP_6: /* "\033Ov" : "6" */ - case XK_KP_7: /* "\033Ow" : "7" */ - case XK_KP_8: /* "\033Ox" : "8" */ - case XK_KP_9: /* "\033Oy" : "9" */ - /* allow shift to override */ - if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { - len = 3; - strcpy(kbuf, "\033Oj"); - kbuf[2] += (keysym - XK_KP_Multiply); - } else { - len = 1; - kbuf[0] = ('*' + (keysym - XK_KP_Multiply)); - } - break; - -#define FKEY(n,fkey) do { \ -len = 5; \ -sprintf(kbuf,"\033[%02d~", (int)((n) + (keysym - fkey))); \ -} while (0); - - case XK_F1: /* "\033[11~" */ - case XK_F2: /* "\033[12~" */ - case XK_F3: /* "\033[13~" */ - case XK_F4: /* "\033[14~" */ - case XK_F5: /* "\033[15~" */ - FKEY(11, XK_F1); - break; - - case XK_F6: /* "\033[17~" */ - case XK_F7: /* "\033[18~" */ - case XK_F8: /* "\033[19~" */ - case XK_F9: /* "\033[20~" */ - case XK_F10: /* "\033[21~" */ - FKEY(17, XK_F6); - break; - - case XK_F11: /* "\033[23~" */ - case XK_F12: /* "\033[24~" */ - case XK_F13: /* "\033[25~" */ - case XK_F14: /* "\033[26~" */ - FKEY(23, XK_F11); - break; - - case XK_F15: /* "\033[28~" */ - case XK_F16: /* "\033[29~" */ - FKEY(28, XK_F15); - break; - - case XK_F17: /* "\033[31~" */ - case XK_F18: /* "\033[32~" */ - case XK_F19: /* "\033[33~" */ - case XK_F20: /* "\033[34~" */ - case XK_F21: /* "\033[35~" */ - case XK_F22: /* "\033[36~" */ - case XK_F23: /* "\033[37~" */ - case XK_F24: /* "\033[38~" */ - case XK_F25: /* "\033[39~" */ - case XK_F26: /* "\033[40~" */ - case XK_F27: /* "\033[41~" */ - case XK_F28: /* "\033[42~" */ - case XK_F29: /* "\033[43~" */ - case XK_F30: /* "\033[44~" */ - case XK_F31: /* "\033[45~" */ - case XK_F32: /* "\033[46~" */ - case XK_F33: /* "\033[47~" */ - case XK_F34: /* "\033[48~" */ - case XK_F35: /* "\033[49~" */ - FKEY(31, XK_F17); - break; -#undef FKEY -#ifdef KS_DELETE - case XK_Delete: - len = strlen(strcpy(kbuf, KS_DELETE)); - break; -#endif - } - -#ifdef META8_OPTION - if (meta && (meta_char == 0x80) && len > 0) { - kbuf[len - 1] |= 0x80; - } -#endif - } else if (ctrl && keysym == XK_minus) { - len = 1; - kbuf[0] = '\037'; /* Ctrl-Minus generates ^_ (31) */ - } else { -#ifdef META8_OPTION - /* set 8-bit on */ - if (meta && (meta_char == 0x80)) { - - unsigned char *ch; - - for (ch = kbuf; ch < kbuf + len; ch++) - *ch |= 0x80; - meta = 0; - } -#endif -#ifdef GREEK_SUPPORT - if (greek_mode) - len = greek_xlat(kbuf, len); -#endif - } - - if (len <= 0) - return; /* not mapped */ - - /* - * these modifications only affect the static keybuffer - * pass Shift/Control indicators for function keys ending with `~' - * - * eg, - * Prior = "ESC[5~" - * Shift+Prior = "ESC[5~" - * Ctrl+Prior = "ESC[5^" - * Ctrl+Shift+Prior = "ESC[5@" - */ - if (kbuf[0] == '\033' && kbuf[1] == '[' && kbuf[len - 1] == '~') - kbuf[len - 1] = (shft ? (ctrl ? '@' : '$') : (ctrl ? '^' : '~')); - - /* escape prefix */ - if (meta -#ifdef META8_OPTION - && (meta_char == 033) -#endif - ) { - - const unsigned char ch = '\033'; - - tt_write(&ch, 1); - } -#if DEBUG >= DEBUG_CMD - if (debug_level >= DEBUG_CMD && debug_key) { /* Display keyboard buffer contents */ - - char *p; - int i; - - fprintf(stderr, "key 0x%04X[%d]: `", (unsigned int) keysym, len); - for (i = 0, p = kbuf; i < len; i++, p++) - fprintf(stderr, (*p >= ' ' && *p < '\177' ? "%c" : "\\%03o"), *p); - fprintf(stderr, "'\n"); - } -#endif /* DEBUG_CMD */ - tt_write(kbuf, len); -} - -#if (MENUBAR_MAX) - /* attempt to `write' COUNT to the input buffer */ unsigned int cmd_write(const unsigned char *str, unsigned int count) @@ -3246,15 +2360,8 @@ cmd_write(const unsigned char *str, unsigned int count) return (0); } -#endif /* MENUBAR_MAX */ #ifdef BACKGROUND_CYCLING_SUPPORT -# if RETSIGTYPE != void -# define CPC_RETURN(x) return ((RETSIGTYPE) x) -# else -# define CPC_RETURN(x) return -# endif - RETSIGTYPE check_pixmap_change(int sig) { @@ -3268,8 +2375,7 @@ check_pixmap_change(int sig) if (in_cpc) CPC_RETURN(0); in_cpc = 1; - D_PIXMAP(("check_pixmap_change(): rs_anim_delay == %lu seconds, last_update == %lu\n", - rs_anim_delay, last_update)); + D_PIXMAP(("check_pixmap_change(%d): rs_anim_delay == %lu seconds, last_update == %lu\n", sig, rs_anim_delay, last_update)); if (!rs_anim_delay) CPC_RETURN(0); if (last_update == 0) { @@ -3283,8 +2389,8 @@ check_pixmap_change(int sig) D_PIXMAP(("now %lu >= %lu (last_update %lu + rs_anim_delay %lu) ?\n", now, last_update + rs_anim_delay, last_update, rs_anim_delay)); if (now >= last_update + rs_anim_delay || 1) { D_PIXMAP(("Time to update pixmap. now == %lu\n", now)); - Imlib_destroy_image(imlib_id, imlib_bg.im); - imlib_bg.im = NULL; + Imlib_destroy_image(imlib_id, images[image_bg].current->iml->im); + images[image_bg].current->iml->im = NULL; xterm_seq(XTerm_Pixmap, rs_anim_pixmaps[image_idx++]); last_update = now; old_handler = signal(SIGALRM, check_pixmap_change); @@ -3307,14 +2413,6 @@ check_pixmap_change(int sig) * Return the next input character after first passing any keyboard input * to the command. */ -#define CHARS_READ() (cmdbuf_ptr < cmdbuf_endp) -#define CHARS_BUFFERED() (count != CMD_BUF_SIZE) -#define RETURN_CHAR() do { refreshed = 0; return (*cmdbuf_ptr++); } while (0) - -#ifdef REFRESH_DELAY -# define REFRESH_DELAY_USEC 1000000/25 -#endif - unsigned char cmd_getc(void) { @@ -3359,14 +2457,12 @@ cmd_getc(void) refreshed = 0; XNextEvent(Xdisplay, &ev); -#ifndef NO_XLOCALE +#ifdef USE_XIM if (!XFilterEvent(&ev, ev.xkey.window)) { - D_X11(("cmd_getc(): process_x_event();\n")); - process_x_event(&ev); + event_dispatch(&ev); } #else - D_X11(("cmd_getc(): process_x_event();\n")); - process_x_event(&ev); + event_dispatch(&ev); #endif /* in case button actions pushed chars to cmdbuf */ @@ -3380,13 +2476,11 @@ cmd_getc(void) if (!scroll_arrow_delay-- && scr_page(UP, 1)) { scroll_arrow_delay = SCROLLBAR_CONTINUOUS_DELAY; refreshed = 0; -/* refresh_type |= SMOOTH_REFRESH; */ } } else if (scrollbar_isDn()) { if (!scroll_arrow_delay-- && scr_page(DN, 1)) { scroll_arrow_delay = SCROLLBAR_CONTINUOUS_DELAY; refreshed = 0; -/* refresh_type |= SMOOTH_REFRESH; */ } } #endif /* SCROLLBAR_BUTTON_CONTINUAL_SCROLLING */ @@ -3444,6 +2538,9 @@ cmd_getc(void) scr_refresh(refresh_type); if (scrollbar_visible()) scrollbar_show(1); +#ifdef USE_XIM + xim_send_spot(); +#endif } } } @@ -3452,738 +2549,6 @@ cmd_getc(void) return (0); } -#if MENUBAR_MAX -# define XEVENT_IS_MYWIN(ev) (((ev)->xany.window == TermWin.parent) \ - || ((ev)->xany.window == TermWin.vt) \ - || ((ev)->xany.window == menuBar.win) \ - || ((ev)->xany.window == scrollBar.win)) -#else -# define XEVENT_IS_MYWIN(ev) (((ev)->xany.window == TermWin.parent) \ - || ((ev)->xany.window == TermWin.vt) \ - || ((ev)->xany.window == scrollBar.win)) -#endif -#define XEVENT_IS_PARENT(ev) (((ev)->xany.window == TermWin.wm_parent) \ - || ((ev)->xany.window == TermWin.wm_grandparent)) -#define XEVENT_REQUIRE(bool_test) do { if (!(bool_test)) return; } while (0) - -void -process_x_event(XEvent * ev) -{ - static Time buttonpress_time, lastbutton_press; - static int clicks = 0; - -#define clickOnce() (clicks <= 1) - static int bypass_keystate = 0; - int reportmode; - static int mouseoffset = 0; /* Mouse pointer offset info scrollbar anchor */ - -#ifdef COUNT_X_EVENTS - static long long event_cnt = 0; - static long long keypress_cnt = 0; - static long long motion_cnt = 0; - static long long expose_cnt = 0; - -#endif -#ifdef PIXMAP_OFFSET - Atom type; - int format; - unsigned long length, after; - unsigned char *data; - -#endif -#ifdef USE_ACTIVE_TAGS - static Time activate_time; - -#endif -#ifdef PROFILE_X_EVENTS - struct timeval expose_start, expose_stop, motion_start, motion_stop, keypress_start, keypress_stop; - static long expose_total = 0; - -#endif -#ifdef WATCH_DESKTOP_OPTION - Window new_desktop_window, last_desktop_window = desktop_window; - -#endif - -#ifdef COUNT_X_EVENTS - event_cnt++; - D_EVENTS(("total number of events: %ld\n", event_cnt)); -#endif - - D_EVENTS(("process_x_event(0x%02x): %s, for window 0x%08x\n", - ev->type, event_type_to_name(ev->type), ev->xany.window)); - - switch (ev->type) { - case KeyPress: - if (keypress_exit) - exit(EXIT_SUCCESS); - D_EVENTS(("process_x_event(%s)\n", "KeyPress")); -#ifdef COUNT_X_EVENTS - keypress_cnt++; - D_EVENTS(("total number of KeyPress events: %ld\n", keypress_cnt)); -#endif -#ifdef PROFILE_X_EVENTS - P_SETTIMEVAL(keypress_start); -#endif - XEVENT_REQUIRE(XEVENT_IS_MYWIN(ev)); - lookup_key(ev); -#ifdef PROFILE_X_EVENTS - P_SETTIMEVAL(keypress_stop); - fprintf(stderr, "KeyPress: %ld microseconds\n", - P_CMPTIMEVALS_USEC(keypress_start, keypress_stop)); -#endif - break; - -#ifdef WATCH_DESKTOP_OPTION - case PropertyNotify: - D_EVENTS(("process_x_event(%s)\n", "PropertyNotify")); - if (Options & Opt_pixmapTrans && Options & Opt_watchDesktop) { - if (desktop_window != None) { - XSelectInput(Xdisplay, desktop_window, 0); - } else { - XSelectInput(Xdisplay, Xroot, 0); - } - XGetWindowProperty(Xdisplay, Xroot, ev->xproperty.atom, 0L, 1L, False, - AnyPropertyType, &type, &format, &length, &after, &data); - if (type == XA_PIXMAP) { - if (desktop_pixmap != None) { - XFreePixmap(Xdisplay, desktop_pixmap); - desktop_pixmap = None; /* Force the re-read */ - } - render_pixmap(TermWin.vt, imlib_bg, bgPixmap, 0, 1); - scr_expose(0, 0, TermWin_TotalWidth(), TermWin_TotalHeight()); - } - if (desktop_window != None) { - XSelectInput(Xdisplay, desktop_window, PropertyChangeMask); - } else { - XSelectInput(Xdisplay, Xroot, PropertyChangeMask); - } - } - break; - - case ReparentNotify: - D_EVENTS(("ReparentNotify: window == 0x%08x, parent == 0x%08x, TermWin.parent == 0x%08x, TermWin.wm_parent == 0x%08x\n", - ev->xreparent.window, ev->xreparent.parent, TermWin.parent, TermWin.wm_parent)); - if (Options & Opt_watchDesktop) { - if (ev->xreparent.window == TermWin.parent) { - D_EVENTS(("It's TermWin.parent. Assigning TermWin.wm_parent to 0x%08x\n", ev->xreparent.parent)); - if (TermWin.wm_parent != None) { - XSelectInput(Xdisplay, TermWin.wm_parent, None); - } - TermWin.wm_parent = ev->xreparent.parent; - XSelectInput(Xdisplay, TermWin.wm_parent, (StructureNotifyMask | SubstructureNotifyMask)); - } else if (ev->xreparent.window == TermWin.wm_parent || ev->xreparent.window == TermWin.wm_grandparent) { - D_EVENTS(("It's my parent! last_desktop_window == 0x%08x, desktop_window == 0x%08x\n", - last_desktop_window, get_desktop_window())); - if (Options & Opt_pixmapTrans && Options & Opt_watchDesktop && get_desktop_window() != last_desktop_window) { - D_EVENTS(("Desktop changed!\n")); - if (desktop_pixmap != None) { - XFreePixmap(Xdisplay, desktop_pixmap); - desktop_pixmap = None; /* Force the re-read */ - } - render_pixmap(TermWin.vt, imlib_bg, bgPixmap, 0, 1); - scr_expose(0, 0, TermWin_TotalWidth(), TermWin_TotalHeight()); - } - } - } - break; -#endif - - case ClientMessage: - XEVENT_REQUIRE(XEVENT_IS_MYWIN(ev)); - D_EVENTS(("process_x_event(%s)\n", "ClientMessage")); - if (ev->xclient.format == 32 && ev->xclient.data.l[0] == wmDeleteWindow) - exit(EXIT_SUCCESS); -#ifdef OFFIX_DND - /* OffiX Dnd (drag 'n' drop) protocol */ - if (ev->xclient.message_type == DndProtocol && - ((ev->xclient.data.l[0] == DndFile) || - (ev->xclient.data.l[0] == DndDir) || - (ev->xclient.data.l[0] == DndLink))) { - /* Get Dnd data */ - Atom ActualType; - int ActualFormat; - unsigned char *data; - unsigned long Size, RemainingBytes; - - XGetWindowProperty(Xdisplay, Xroot, - DndSelection, - 0L, 1000000L, - False, AnyPropertyType, - &ActualType, &ActualFormat, - &Size, &RemainingBytes, - &data); - XChangeProperty(Xdisplay, Xroot, - XA_CUT_BUFFER0, XA_STRING, - 8, PropModeReplace, - data, strlen(data)); - selection_paste(Xroot, XA_CUT_BUFFER0, True); - XSetInputFocus(Xdisplay, Xroot, RevertToNone, CurrentTime); - } -#endif /* OFFIX_DND */ - break; - - case MappingNotify: - D_EVENTS(("process_x_event(%s)\n", "MappingNotify")); - XRefreshKeyboardMapping(&(ev->xmapping)); - break; - -#ifdef USE_ACTIVE_TAGS - case LeaveNotify: - XEVENT_REQUIRE(XEVENT_IS_MYWIN(ev)); - tag_hide(); - break; -#endif - - /* Here's my conclusion: - * If the window is completely unobscured, use bitblt's - * to scroll. Even then, they're only used when doing partial - * screen scrolling. When partially obscured, we have to fill - * in the GraphicsExpose parts, which means that after each refresh, - * we need to wait for the graphics expose or Noexpose events, - * which ought to make things real slow! - */ - case VisibilityNotify: - D_EVENTS(("process_x_event(%s)\n", "VisibilityNotify")); - XEVENT_REQUIRE(XEVENT_IS_MYWIN(ev)); - switch (ev->xvisibility.state) { - case VisibilityUnobscured: -#ifdef USE_SMOOTH_REFRESH - refresh_type = SMOOTH_REFRESH; -#else - refresh_type = FAST_REFRESH; -#endif - break; - - case VisibilityPartiallyObscured: - refresh_type = SLOW_REFRESH; - break; - - default: - refresh_type = NO_REFRESH; - break; - } - break; - - case FocusIn: - D_EVENTS(("process_x_event(%s)\n", "FocusIn")); - XEVENT_REQUIRE(XEVENT_IS_MYWIN(ev)); - if (!TermWin.focus) { - TermWin.focus = 1; -#ifdef CHANGE_SCROLLCOLOR_ON_FOCUS - menubar_expose(); -#endif - if (Options & Opt_scrollbar_popup) { - map_scrollBar(Options & Opt_scrollBar); - } -#ifndef NO_XLOCALE - if (Input_Context != NULL) - XSetICFocus(Input_Context); -#endif - } - break; - - case FocusOut: - D_EVENTS(("process_x_event(%s)\n", "FocusOut")); - XEVENT_REQUIRE(XEVENT_IS_MYWIN(ev)); - if (TermWin.focus) { - TermWin.focus = 0; -#ifdef CHANGE_SCROLLCOLOR_ON_FOCUS - menubar_expose(); -#endif - if (Options & Opt_scrollbar_popup) { - map_scrollBar(0); - } -#ifndef NO_XLOCALE - if (Input_Context != NULL) - XUnsetICFocus(Input_Context); -#endif - } - break; - - case ConfigureNotify: - D_EVENTS(("process_x_event(%s)\n", "ConfigureNotify")); - XEVENT_REQUIRE(XEVENT_IS_MYWIN(ev)); -#ifdef PIXMAP_OFFSET - if (Options & Opt_pixmapTrans || Options & Opt_viewport_mode) { - render_pixmap(TermWin.vt, imlib_bg, bgPixmap, 0, 2); - scr_expose(0, 0, TermWin_TotalWidth(), TermWin_TotalHeight()); - } -#endif - resize_window(); - menubar_expose(); - break; - - case SelectionClear: - D_EVENTS(("process_x_event(%s)\n", "SelectionClear")); - selection_clear(); - break; - - case SelectionNotify: - D_EVENTS(("process_x_event(%s)\n", "SelectionNotify")); - selection_paste(ev->xselection.requestor, ev->xselection.property, True); - break; - - case SelectionRequest: - D_EVENTS(("process_x_event(%s)\n", "SelectionRequest")); - selection_send(&(ev->xselectionrequest)); - break; - - case GraphicsExpose: - D_EVENTS(("process_x_event(%s)\n", "GraphicsExpose")); - case Expose: - D_EVENTS(("process_x_event(%s)\n", "Expose")); -#ifdef PROFILE_X_EVENTS - P_SETTIMEVAL(expose_start); -#endif - XEVENT_REQUIRE(XEVENT_IS_MYWIN(ev)); - if (ev->xany.window == TermWin.vt) { - scr_expose(ev->xexpose.x, ev->xexpose.y, ev->xexpose.width, ev->xexpose.height); - } else { - - XEvent unused_xevent; - - while (XCheckTypedWindowEvent(Xdisplay, ev->xany.window, Expose, &unused_xevent)); - while (XCheckTypedWindowEvent(Xdisplay, ev->xany.window, GraphicsExpose, &unused_xevent)); - if (isScrollbarWindow(ev->xany.window)) { - scrollbar_setNone(); - scrollbar_show(0); - } -#if (MENUBAR_MAX) - if (menubar_visible() && isMenuBarWindow(ev->xany.window)) { - menubar_expose(); - } -#endif /* MENUBAR_MAX */ - Gr_expose(ev->xany.window); - } -#ifdef WATCH_DESKTOP_OPTION - if (Options & Opt_pixmapTrans && Options & Opt_watchDesktop) { - if (desktop_window != None) { - XSelectInput(Xdisplay, desktop_window, PropertyChangeMask); - } else { - XSelectInput(Xdisplay, Xroot, PropertyChangeMask); - } - } -#endif -#ifdef PROFILE_X_EVENTS - P_SETTIMEVAL(expose_stop); - expose_total += P_CMPTIMEVALS_USEC(expose_start, expose_stop); - fprintf(stderr, "Expose: %ld(%ld) microseconds\n", - P_CMPTIMEVALS_USEC(expose_start, expose_stop), - expose_total); -#endif - break; - - case ButtonPress: - D_EVENTS(("process_x_event(%s)\n", "ButtonPress")); - XEVENT_REQUIRE(XEVENT_IS_MYWIN(ev)); - if (Options & Opt_borderless) { - XSetInputFocus(Xdisplay, Xroot, RevertToNone, CurrentTime); - } -#if defined(CTRL_CLICK_RAISE) || defined(CTRL_CLICK_SCROLLBAR) || defined(CTRL_CLICK_MENU) - if ((ev->xbutton.state & ControlMask) && (ev->xany.window == TermWin.vt)) { - D_EVENTS(("Checking for Ctrl+Button\n")); - switch (ev->xbutton.button) { - case Button1: - D_EVENTS(("Ctrl+Button1\n")); -# ifdef CTRL_CLICK_RAISE - XSetInputFocus(Xdisplay, TermWin.parent, RevertToParent, CurrentTime); - XRaiseWindow(Xdisplay, TermWin.parent); - /*XWarpPointer(Xdisplay, None, TermWin.vt, 0, 0, 0, 0, TermWin.width/2, TermWin.height/2); */ -# endif - break; - case Button2: - D_EVENTS(("Ctrl+Button2\n")); -# ifdef CTRL_CLICK_SCROLLBAR - map_scrollBar(scrollbar_visible()? 0 : 1); -# endif - break; - case Button3: - D_EVENTS(("Ctrl+Button3\n")); -# if defined(CTRL_CLICK_MENU) && (MENUBAR_MAX) - map_menuBar(menubar_visible()? 0 : 1); -# endif - break; - default: - break; - } - break; - } -#endif /* CTRL_CLICK_RAISE || CTRL_CLICK_MENU */ - - bypass_keystate = (ev->xbutton.state & (Mod1Mask | ShiftMask)); - reportmode = (bypass_keystate ? 0 : (PrivateModes & PrivMode_mouse_report)); - - if (ev->xany.window == TermWin.vt) { - if (ev->xbutton.subwindow != None) { - Gr_ButtonPress(ev->xbutton.x, ev->xbutton.y); - } else { - if (reportmode) { - if (reportmode & PrivMode_MouseX10) { - /* no state info allowed */ - ev->xbutton.state = 0; - } -#ifdef MOUSE_REPORT_DOUBLECLICK - if (ev->xbutton.button == Button1) { - if (ev->xbutton.time - buttonpress_time < MULTICLICK_TIME) - clicks++; - else - clicks = 1; - } -#else - clicks = 1; -#endif /* MOUSE_REPORT_DOUBLECLICK */ - mouse_report(&(ev->xbutton)); - } else { -#ifdef USE_ACTIVE_TAGS - if (tag_click(ev->xbutton.x, ev->xbutton.y, ev->xbutton.button, ev->xkey.state)) - activate_time = ev->xbutton.time; - else -#endif - switch (ev->xbutton.button) { - case Button1: - if (lastbutton_press == 1 - && (ev->xbutton.time - buttonpress_time < MULTICLICK_TIME)) - clicks++; - else - clicks = 1; - selection_click(clicks, ev->xbutton.x, ev->xbutton.y); - lastbutton_press = 1; - break; - - case Button3: - if (lastbutton_press == 3 - && (ev->xbutton.time - buttonpress_time < MULTICLICK_TIME)) - selection_rotate(ev->xbutton.x, ev->xbutton.y); - else - selection_extend(ev->xbutton.x, ev->xbutton.y, 1); - lastbutton_press = 3; - break; - } - } - buttonpress_time = ev->xbutton.time; - return; - } - } -#ifdef PIXMAP_SCROLLBAR - if ((isScrollbarWindow(ev->xany.window)) - || (scrollbar_upButtonWin(ev->xany.window)) - || (scrollbar_dnButtonWin(ev->xany.window))) -#else - if (isScrollbarWindow(ev->xany.window)) -#endif - { - scrollbar_setNone(); - /* - * Eterm-style scrollbar: - * move up if mouse is above slider - * move dn if mouse is below slider - * - * XTerm-style scrollbar: - * Move display proportional to pointer location - * pointer near top -> scroll one line - * pointer near bot -> scroll full page - */ -#ifndef NO_SCROLLBAR_REPORT - if (reportmode) { - /* - * Mouse report disabled scrollbar: - * arrow buttons - send up/down - * click on scrollbar - send pageup/down - */ -#ifdef PIXMAP_SCROLLBAR - if ((scrollbar_upButtonWin(ev->xany.window)) - || (!(scrollbar_is_pixmapped()) && - (scrollbar_upButton(ev->xbutton.y)))) -#else - if (scrollbar_upButton(ev->xbutton.y)) -#endif - tt_printf("\033[A"); -#ifdef PIXMAP_SCROLLBAR - else if ((scrollbar_dnButtonWin(ev->xany.window)) - || (!(scrollbar_is_pixmapped()) && - (scrollbar_upButton(ev->xbutton.y)))) -#else - else if (scrollbar_dnButton(ev->xbutton.y)) -#endif - tt_printf("\033[B"); - else - switch (ev->xbutton.button) { - case Button2: - tt_printf("\014"); - break; - case Button1: - tt_printf("\033[6~"); - break; - case Button3: - tt_printf("\033[5~"); - break; - } - } else -#endif /* NO_SCROLLBAR_REPORT */ - { -#ifdef PIXMAP_SCROLLBAR - if ((scrollbar_upButtonWin(ev->xany.window)) - || (!(scrollbar_is_pixmapped()) && - (scrollbar_upButton(ev->xbutton.y)))) -#else - if (scrollbar_upButton(ev->xbutton.y)) -#endif - { -#ifdef SCROLLBAR_BUTTON_CONTINUAL_SCROLLING - scroll_arrow_delay = SCROLLBAR_INITIAL_DELAY; -#endif - if (scr_page(UP, 1)) { - scrollbar_setUp(); - } - } else if -#ifdef PIXMAP_SCROLLBAR - ((scrollbar_dnButtonWin(ev->xany.window)) - || (!(scrollbar_is_pixmapped()) - && (scrollbar_dnButton(ev->xbutton.y)))) -#else - (scrollbar_dnButton(ev->xbutton.y)) -#endif - { -#ifdef SCROLLBAR_BUTTON_CONTINUAL_SCROLLING - scroll_arrow_delay = SCROLLBAR_INITIAL_DELAY; -#endif - if (scr_page(DN, 1)) { - scrollbar_setDn(); - } - } - else - switch (ev->xbutton.button) { - case Button2: - mouseoffset = (scrollBar.bot - scrollBar.top) / 2; /* Align to center */ - if (scrollbar_above_slider(ev->xbutton.y) || scrollbar_below_slider(ev->xbutton.y) - || scrollBar.type == SCROLLBAR_XTERM) { - scr_move_to(scrollbar_position(ev->xbutton.y) - mouseoffset, - scrollbar_size()); - } - scrollbar_setMotion(); - break; - - case Button1: - mouseoffset = ev->xbutton.y - scrollBar.top; - MAX_IT(mouseoffset, 1); - /* drop */ - case Button3: -#if defined(MOTIF_SCROLLBAR) || defined(NEXT_SCROLLBAR) - if (scrollBar.type == SCROLLBAR_MOTIF || scrollBar.type == SCROLLBAR_NEXT) { -# ifdef PIXMAP_SCROLLBAR - if (!(ev->xany.window == scrollBar.sa_win) - && (scrollbar_above_slider(ev->xbutton.y))) -# else - if (scrollbar_above_slider(ev->xbutton.y)) -# endif - scr_page(UP, TermWin.nrow - 1); -# ifdef PIXMAP_SCROLLBAR - else if (!(ev->xany.window == scrollBar.sa_win) - && (scrollbar_below_slider(ev->xbutton.y))) -# else - else - if (scrollbar_below_slider(ev->xbutton.y)) -# endif - scr_page(DN, TermWin.nrow - 1); - else - scrollbar_setMotion(); - } -#endif /* MOTIF_SCROLLBAR || NEXT_SCROLLBAR */ - -#ifdef XTERM_SCROLLBAR - if (scrollBar.type == SCROLLBAR_XTERM) { - scr_page((ev->xbutton.button == Button1 ? DN : UP), - (TermWin.nrow * - scrollbar_position(ev->xbutton.y) / - scrollbar_size()) - ); - } -#endif /* XTERM_SCROLLBAR */ - break; - } - } - return; - } -#if (MENUBAR_MAX) - if (isMenuBarWindow(ev->xany.window)) { - menubar_control(&(ev->xbutton)); - return; - } -#endif /* MENUBAR_MAX */ - break; - - case ButtonRelease: - D_EVENTS(("process_x_event(%s)\n", "ButtonRelease")); - XEVENT_REQUIRE(XEVENT_IS_MYWIN(ev)); - mouseoffset = 0; - reportmode = (bypass_keystate ? - 0 : (PrivateModes & PrivMode_mouse_report)); - - if (scrollbar_isUpDn()) { - scrollbar_setNone(); - scrollbar_show(0); -#ifdef SCROLLBAR_BUTTON_CONTINUAL_SCROLLING -/* refresh_type &= ~SMOOTH_REFRESH; */ -#endif - } - if (ev->xany.window == TermWin.vt) { - if (ev->xbutton.subwindow != None) - Gr_ButtonRelease(ev->xbutton.x, ev->xbutton.y); - else { - if (reportmode) { - switch (reportmode & PrivMode_mouse_report) { - case PrivMode_MouseX10: - break; - - case PrivMode_MouseX11: - ev->xbutton.state = bypass_keystate; - ev->xbutton.button = AnyButton; - mouse_report(&(ev->xbutton)); - break; - } - return; - } - /* - * dumb hack to compensate for the failure of click-and-drag - * when overriding mouse reporting - */ - if ((PrivateModes & PrivMode_mouse_report) && - (bypass_keystate) && - (ev->xbutton.button == Button1) && - (clickOnce())) - selection_extend(ev->xbutton.x, ev->xbutton.y, 0); - - switch (ev->xbutton.button) { - case Button1: - case Button3: -#if defined(CTRL_CLICK_RAISE) || defined(CTRL_CLICK_MENU) - if (!(ev->xbutton.state & ControlMask)) -#endif - selection_make(ev->xbutton.time); - break; - - case Button2: -#ifdef CTRL_CLICK_SCROLLBAR - if (!(ev->xbutton.state & ControlMask)) -#endif - selection_request(ev->xbutton.time, ev->xbutton.x, ev->xbutton.y); - break; - case Button4: - scr_page(UP, (ev->xbutton.state & ShiftMask) ? 1 : 5); - break; - case Button5: - scr_page(DN, (ev->xbutton.state & ShiftMask) ? 1 : 5); - break; - } - } - } -#if (MENUBAR_MAX) - else if (isMenuBarWindow(ev->xany.window)) { - menubar_control(&(ev->xbutton)); - } -#endif /* MENUBAR_MAX */ - break; - - case MotionNotify: - D_EVENTS(("process_x_event(%s)\n", "MotionNotify")); -#ifdef COUNT_X_EVENTS - motion_cnt++; - D_EVENTS(("total number of MotionNotify events: %ld\n", motion_cnt)); -#endif -#ifdef PROFILE_X_EVENTS - P_SETTIMEVAL(motion_start); -#endif - XEVENT_REQUIRE(XEVENT_IS_MYWIN(ev)); -#if (MENUBAR_MAX) - if (isMenuBarWindow(ev->xany.window)) { - menubar_control(&(ev->xbutton)); - break; - } -#endif /* MENUBAR_MAX */ - if ((PrivateModes & PrivMode_mouse_report) && !(bypass_keystate)) - break; - - if (ev->xany.window == TermWin.vt) { - if ((ev->xbutton.state & (Button1Mask | Button3Mask)) -#ifdef USE_ACTIVE_TAGS - && ((ev->xmotion.time - activate_time) > TAG_DRAG_THRESHHOLD) -#endif - ) { - Window unused_root, unused_child; - int unused_root_x, unused_root_y; - unsigned int unused_mask; - - while (XCheckTypedWindowEvent(Xdisplay, TermWin.vt, - MotionNotify, ev)); - XQueryPointer(Xdisplay, TermWin.vt, - &unused_root, &unused_child, - &unused_root_x, &unused_root_y, - &(ev->xbutton.x), &(ev->xbutton.y), - &unused_mask); -#ifdef MOUSE_THRESHOLD - /* deal with a `jumpy' mouse */ - if ((ev->xmotion.time - buttonpress_time) > MOUSE_THRESHOLD) -#endif - selection_extend((ev->xbutton.x), (ev->xbutton.y), - (ev->xbutton.state & Button3Mask)); - } -#ifdef USE_ACTIVE_TAGS - else - tag_pointer_new_position(ev->xbutton.x, ev->xbutton.y); -#endif -#ifdef PIXMAP_SCROLLBAR - } else if ((scrollbar_is_pixmapped()) && (ev->xany.window == scrollBar.sa_win) && scrollbar_isMotion()) { - - Window unused_root, unused_child; - int unused_root_x, unused_root_y; - unsigned int unused_mask; - - /* FIXME: I guess pointer or server should be grabbed here - * or something like that :) -vendu - */ - - while (XCheckTypedWindowEvent(Xdisplay, scrollBar.sa_win, - MotionNotify, ev)); - - XQueryPointer(Xdisplay, scrollBar.sa_win, - &unused_root, &unused_child, - &unused_root_x, &unused_root_y, - &(ev->xbutton.x), &(ev->xbutton.y), - &unused_mask); - - scr_move_to(scrollbar_position(ev->xbutton.y) - mouseoffset, - scrollbar_size()); - refresh_count = refresh_limit = 0; - scr_refresh(refresh_type); - scrollbar_show(mouseoffset); -#endif - } else if ((ev->xany.window == scrollBar.win) && scrollbar_isMotion()) { - Window unused_root, unused_child; - int unused_root_x, unused_root_y; - unsigned int unused_mask; - - while (XCheckTypedWindowEvent(Xdisplay, scrollBar.win, MotionNotify, ev)); - XQueryPointer(Xdisplay, scrollBar.win, - &unused_root, &unused_child, - &unused_root_x, &unused_root_y, - &(ev->xbutton.x), &(ev->xbutton.y), - &unused_mask); - scr_move_to(scrollbar_position(ev->xbutton.y) - mouseoffset, - scrollbar_size()); - refresh_count = refresh_limit = 0; - scr_refresh(refresh_type); - scrollbar_show(mouseoffset); - } -#ifdef PROFILE_X_EVENTS - P_SETTIMEVAL(motion_stop); - fprintf(stderr, "MotionNotify: %ld microseconds\n", - P_CMPTIMEVALS_USEC(motion_start, motion_stop)); -#endif - break; - } -} - /* tt_write(), tt_printf() - output to command */ /* * Send count characters directly to the command @@ -4222,852 +2587,6 @@ tt_printf(const unsigned char *fmt,...) tt_write(buf, strlen(buf)); } - -/* print pipe */ -/*----------------------------------------------------------------------*/ -#ifdef PRINTPIPE -/* PROTO */ -FILE * -popen_printer(void) -{ - FILE *stream = popen(rs_print_pipe, "w"); - - if (stream == NULL) - print_error("can't open printer pipe \"%s\" -- %s", rs_print_pipe, strerror(errno)); - return stream; -} - -/* PROTO */ -int -pclose_printer(FILE * stream) -{ - fflush(stream); - /* pclose() reported not to work on SunOS 4.1.3 */ -# if defined (__sun__) - /* pclose works provided SIGCHLD handler uses waitpid */ - return pclose(stream); /* return fclose (stream); */ -# else - return pclose(stream); -# endif -} - -/* - * simulate attached vt100 printer - */ -/* PROTO */ -void -process_print_pipe(void) -{ - const char *const escape_seq = "\033[4i"; - const char *const rev_escape_seq = "i4[\033"; - int index; - FILE *fd; - - if ((fd = popen_printer()) != NULL) { - for (index = 0; index < 4; /* nil */ ) { - unsigned char ch = cmd_getc(); - - if (ch == escape_seq[index]) - index++; - else if (index) - for ( /*nil */ ; index > 0; index--) - fputc(rev_escape_seq[index - 1], fd); - - if (index == 0) - fputc(ch, fd); - } - pclose_printer(fd); - } -} -#endif /* PRINTPIPE */ - -/* process escape sequences */ -/* PROTO */ -void -process_escape_seq(void) -{ - unsigned char ch = cmd_getc(); - - switch (ch) { - /* case 1: do_tek_mode (); break; */ - case '#': - if (cmd_getc() == '8') - scr_E(); - break; - case '(': - scr_charset_set(0, cmd_getc()); - break; - case ')': - scr_charset_set(1, cmd_getc()); - break; - case '*': - scr_charset_set(2, cmd_getc()); - break; - case '+': - scr_charset_set(3, cmd_getc()); - break; -#ifdef KANJI - case '$': - scr_charset_set(-2, cmd_getc()); - break; -#endif - case '7': - scr_cursor(SAVE); - break; - case '8': - scr_cursor(RESTORE); - break; - case '=': - case '>': - PrivMode((ch == '='), PrivMode_aplKP); - break; - case '@': - (void) cmd_getc(); - break; - case 'D': - scr_index(UP); - break; - case 'E': - scr_add_lines("\n\r", 1, 2); - break; - case 'G': - process_graphics(); - break; - case 'H': - scr_set_tab(1); - break; - case 'M': - scr_index(DN); - break; - /*case 'N': scr_single_shift (2); break; */ - /*case 'O': scr_single_shift (3); break; */ - case 'Z': - tt_printf(ESCZ_ANSWER); - break; /* steal obsolete ESC [ c */ - case '[': - process_csi_seq(); - break; - case ']': - process_xterm_seq(); - break; - case 'c': - scr_poweron(); - break; - case 'n': - scr_charset_choose(2); - break; - case 'o': - scr_charset_choose(3); - break; - } -} - -/* process CSI (code sequence introducer) sequences `ESC[' */ -/* PROTO */ -void -process_csi_seq(void) -{ - - unsigned char ch, priv; - unsigned int nargs; - int arg[ESC_ARGS]; - - nargs = 0; - arg[0] = 0; - arg[1] = 0; - - priv = 0; - ch = cmd_getc(); - if (ch >= '<' && ch <= '?') { - priv = ch; - ch = cmd_getc(); - } - /* read any numerical arguments */ - do { - int n; - - for (n = 0; isdigit(ch); ch = cmd_getc()) - n = n * 10 + (ch - '0'); - - if (nargs < ESC_ARGS) - arg[nargs++] = n; - if (ch == '\b') { - scr_backspace(); - } else if (ch == 033) { - process_escape_seq(); - return; - } else if (ch < ' ') { - scr_add_lines(&ch, 0, 1); - return; - } - if (ch < '@') - ch = cmd_getc(); - } - while (ch >= ' ' && ch < '@'); - if (ch == 033) { - process_escape_seq(); - return; - } else if (ch < ' ') - return; - - switch (ch) { -#ifdef PRINTPIPE - case 'i': /* printing */ - switch (arg[0]) { - case 0: - scr_printscreen(0); - break; - case 5: - process_print_pipe(); - break; - } - break; -#endif - case 'A': - case 'e': /* up */ - scr_gotorc((arg[0] ? -arg[0] : -1), 0, RELATIVE); - break; - case 'B': /* down */ - scr_gotorc((arg[0] ? +arg[0] : +1), 0, RELATIVE); - break; - case 'C': - case 'a': /* right */ - scr_gotorc(0, (arg[0] ? +arg[0] : +1), RELATIVE); - break; - case 'D': /* left */ - scr_gotorc(0, (arg[0] ? -arg[0] : -1), RELATIVE); - break; - case 'E': /* down & to first column */ - scr_gotorc((arg[0] ? +arg[0] : +1), 0, R_RELATIVE); - break; - case 'F': /* up & to first column */ - scr_gotorc((arg[0] ? -arg[0] : -1), 0, R_RELATIVE); - break; - case 'G': - case '`': /* move to col */ - scr_gotorc(0, (arg[0] ? arg[0] - 1 : +1), R_RELATIVE); - break; - case 'd': /* move to row */ - scr_gotorc((arg[0] ? arg[0] - 1 : +1), 0, C_RELATIVE); - break; - case 'H': - case 'f': /* position cursor */ - switch (nargs) { - case 0: - scr_gotorc(0, 0, 0); - break; - case 1: - scr_gotorc((arg[0] ? arg[0] - 1 : 0), 0, 0); - break; - default: - scr_gotorc(arg[0] - 1, arg[1] - 1, 0); - break; - } - break; - case 'I': - scr_tab(arg[0] ? +arg[0] : +1); - break; - case 'Z': - scr_tab(arg[0] ? -arg[0] : -1); - break; - case 'J': - scr_erase_screen(arg[0]); - break; - case 'K': - scr_erase_line(arg[0]); - break; - case '@': - scr_insdel_chars((arg[0] ? arg[0] : 1), INSERT); - break; - case 'L': - scr_insdel_lines((arg[0] ? arg[0] : 1), INSERT); - break; - case 'M': - scr_insdel_lines((arg[0] ? arg[0] : 1), DELETE); - break; - case 'X': - scr_insdel_chars((arg[0] ? arg[0] : 1), ERASE); - break; - case 'P': - scr_insdel_chars((arg[0] ? arg[0] : 1), DELETE); - break; - - case 'c': -#ifndef NO_VT100_ANS - tt_printf(VT100_ANS); -#endif - break; - case 'm': - process_sgr_mode(nargs, arg); - break; - case 'n': /* request for information */ - switch (arg[0]) { - case 5: - tt_printf("\033[0n"); - break; /* ready */ - case 6: - scr_report_position(); - break; -#if defined (ENABLE_DISPLAY_ANSWER) - case 7: - tt_printf("%s\n", display_name); - break; -#endif - case 8: - xterm_seq(XTerm_title, APL_NAME "-" VERSION); - break; - case 9: -#ifdef PIXMAP_OFFSET - if (Options & Opt_pixmapTrans) { - char tbuff[70]; - - snprintf(tbuff, sizeof(tbuff), APL_NAME "-" VERSION ": Transparent - %d%% shading - 0x%06x tint mask", - rs_shadePct, rs_tintMask); - xterm_seq(XTerm_title, tbuff); - } else -#endif -#ifdef PIXMAP_SUPPORT - { - char *tbuff; - unsigned short len; - - if (imlib_bg.im) { - len = strlen(imlib_bg.im->filename) + sizeof(APL_NAME) + sizeof(VERSION) + 5; - tbuff = MALLOC(len); - snprintf(tbuff, len, APL_NAME "-" VERSION ": %s", imlib_bg.im->filename); - xterm_seq(XTerm_title, tbuff); - FREE(tbuff); - } else { - xterm_seq(XTerm_title, APL_NAME "-" VERSION ": No Pixmap"); - } - } -#endif /* PIXMAP_SUPPORT */ - break; - } - break; - case 'r': /* set top and bottom margins */ - if (priv != '?') { - if (nargs < 2 || arg[0] >= arg[1]) - scr_scroll_region(0, 10000); - else - scr_scroll_region(arg[0] - 1, arg[1] - 1); - break; - } - /* drop */ - case 't': - if (priv != '?') { - process_window_mode(nargs, arg); - break; - } - /* drop */ - case 's': - case 'h': - case 'l': - process_terminal_mode(ch, priv, nargs, arg); - break; - case 'g': - switch (arg[0]) { - case 0: - scr_set_tab(0); - break; /* delete tab */ - case 3: - scr_set_tab(-1); - break; /* clear all tabs */ - } - break; - case 'W': - switch (arg[0]) { - case 0: - scr_set_tab(1); - break; /* = ESC H */ - case 2: - scr_set_tab(0); - break; /* = ESC [ 0 g */ - case 5: - scr_set_tab(-1); - break; /* = ESC [ 3 g */ - } - break; - } -} - -/* process xterm text parameters sequences `ESC ] Ps ; Pt BEL' */ -/* PROTO */ -void -process_xterm_seq(void) -{ - unsigned char ch, string[STRING_MAX]; - int arg; - - ch = cmd_getc(); - if (isdigit(ch)) { - for (arg = 0; isdigit(ch); ch = cmd_getc()) { - arg = arg * 10 + (ch - '0'); - } - } else if (ch == ';') { - arg = 0; - } else { - arg = ch; - ch = cmd_getc(); - } - if (ch == ';') { - int n = 0; - - while ((ch = cmd_getc()) != 007) { - if (ch) { - if (ch == '\t') - ch = ' '; /* translate '\t' to space */ - else if (ch < ' ') - return; /* control character - exit */ - - if (n < sizeof(string) - 1) - string[n++] = ch; - } - } - string[n] = '\0'; - - /* - * menubar_dispatch() violates the constness of the string, - * so do it here - */ - if (arg == XTerm_Menu) - menubar_dispatch(string); - else - xterm_seq(arg, string); - } else { - int n = 0; - - for (; ch != '\e'; ch = cmd_getc()) { - if (ch) { - if (ch == '\t') - ch = ' '; /* translate '\t' to space */ - else if (ch < ' ') - return; /* control character - exit */ - - if (n < sizeof(string) - 1) - string[n++] = ch; - } - } - string[n] = '\0'; - - if ((ch = cmd_getc()) != '\\') { - return; - } - switch (arg) { - case 'l': - xterm_seq(XTerm_title, string); - break; - case 'L': - xterm_seq(XTerm_iconName, string); - break; - case 'I': - set_icon_pixmap(string, NULL); - break; - default: - break; - } - } -} - -/* Process window manipulations */ -void -process_window_mode(unsigned int nargs, int args[]) -{ - - register unsigned int i; - unsigned int x, y; - Screen *scr; - Window dummy_child; - char buff[128], *name; - - if (!nargs) - return; - scr = ScreenOfDisplay(Xdisplay, Xscreen); - if (!scr) - return; - - for (i = 0; i < nargs; i++) { - if (args[i] == 14) { - int dummy_x, dummy_y; - unsigned int dummy_border, dummy_depth; - - /* Store current width and height in x and y */ - XGetGeometry(Xdisplay, TermWin.parent, &dummy_child, &dummy_x, &dummy_y, &x, &y, &dummy_border, &dummy_depth); - } - switch (args[i]) { - case 1: - XRaiseWindow(Xdisplay, TermWin.parent); - break; - case 2: - XIconifyWindow(Xdisplay, TermWin.parent, Xscreen); - break; - case 3: - if (i + 2 >= nargs) - return; /* Make sure there are 2 args left */ - x = args[++i]; - y = args[++i]; - if (x > scr->width || y > scr->height) - return; /* Don't move off-screen */ - XMoveWindow(Xdisplay, TermWin.parent, x, y); - break; - case 4: - if (i + 2 >= nargs) - return; /* Make sure there are 2 args left */ - y = args[++i]; - x = args[++i]; - XResizeWindow(Xdisplay, TermWin.parent, x, y); - break; - case 5: - XRaiseWindow(Xdisplay, TermWin.parent); - break; - case 6: - XLowerWindow(Xdisplay, TermWin.parent); - break; - case 7: - XClearWindow(Xdisplay, TermWin.vt); - XSync(Xdisplay, False); - scr_touch(); - scr_refresh(SMOOTH_REFRESH); - break; - case 8: - if (i + 2 >= nargs) - return; /* Make sure there are 2 args left */ - y = args[++i]; - x = args[++i]; - XResizeWindow(Xdisplay, TermWin.parent, - Width2Pixel(x) + 2 * TermWin.internalBorder + (scrollbar_visible()? scrollbar_total_width() : 0), - Height2Pixel(y) + 2 * TermWin.internalBorder + (menubar_visible()? menuBar_TotalHeight() : 0)); - break; - case 11: - break; - case 13: - XTranslateCoordinates(Xdisplay, TermWin.parent, Xroot, 0, 0, &x, &y, &dummy_child); - snprintf(buff, sizeof(buff), "\e[3;%d;%dt", x, y); - tt_write(buff, strlen(buff)); - break; - case 14: - snprintf(buff, sizeof(buff), "\e[4;%d;%dt", y, x); - tt_write(buff, strlen(buff)); - break; - case 18: - snprintf(buff, sizeof(buff), "\e[8;%d;%dt", TermWin.nrow, TermWin.ncol); - tt_write(buff, strlen(buff)); - break; - case 20: - XGetIconName(Xdisplay, TermWin.parent, &name); - snprintf(buff, sizeof(buff), "\e]L%s\e\\", name); - tt_write(buff, strlen(buff)); - XFree(name); - break; - case 21: - XFetchName(Xdisplay, TermWin.parent, &name); - snprintf(buff, sizeof(buff), "\e]l%s\e\\", name); - tt_write(buff, strlen(buff)); - XFree(name); - break; - default: - break; - } - } -} - -/* process DEC private mode sequences `ESC [ ? Ps mode' */ -/* - * mode can only have the following values: - * 'l' = low - * 'h' = high - * 's' = save - * 'r' = restore - * 't' = toggle - * so no need for fancy checking - */ -/* PROTO */ -void -process_terminal_mode(int mode, int priv, unsigned int nargs, int arg[]) -{ - unsigned int i; - int state; - - if (nargs == 0) - return; - - /* make lo/hi boolean */ - switch (mode) { - case 'l': - mode = 0; - break; - case 'h': - mode = 1; - break; - } - - switch (priv) { - case 0: - if (mode && mode != 1) - return; /* only do high/low */ - for (i = 0; i < nargs; i++) - switch (arg[i]) { - case 4: - scr_insert_mode(mode); - break; - /* case 38: TEK mode */ - } - break; - -#define PrivCases(bit) \ -if (mode == 't') state = !(PrivateModes & bit); else state = mode;\ -switch (state) {\ -case 's': SavedModes |= (PrivateModes & bit); continue; break;\ -case 'r': state = (SavedModes & bit) ? 1 : 0;/*drop*/\ -default: PrivMode (state, bit); } - - case '?': - for (i = 0; i < nargs; i++) - switch (arg[i]) { - case 1: /* application cursor keys */ - PrivCases(PrivMode_aplCUR); - break; - - /* case 2: - reset charsets to USASCII */ - - case 3: /* 80/132 */ - PrivCases(PrivMode_132); - if (PrivateModes & PrivMode_132OK) - set_width(state ? 132 : 80); - break; - - /* case 4: - smooth scrolling */ - - case 5: /* reverse video */ - PrivCases(PrivMode_rVideo); - scr_rvideo_mode(state); - break; - - case 6: /* relative/absolute origins */ - PrivCases(PrivMode_relOrigin); - scr_relative_origin(state); - break; - - case 7: /* autowrap */ - PrivCases(PrivMode_Autowrap); - scr_autowrap(state); - break; - - /* case 8: - auto repeat, can't do on a per window basis */ - - case 9: /* X10 mouse reporting */ - PrivCases(PrivMode_MouseX10); - /* orthogonal */ - if (PrivateModes & PrivMode_MouseX10) - PrivateModes &= ~(PrivMode_MouseX11); - break; - -#if (MENUBAR_MAX) -# ifdef menuBar_esc - case menuBar_esc: - PrivCases(PrivMode_menuBar); - map_menuBar(state); - break; -# endif -#endif /* MENUBAR_MAX */ - -#ifdef scrollBar_esc - case scrollBar_esc: - PrivCases(PrivMode_scrollBar); - map_scrollBar(state); - break; -#endif - case 25: /* visible/invisible cursor */ - PrivCases(PrivMode_VisibleCursor); - scr_cursor_visible(state); - break; - - case 35: - PrivCases(PrivMode_ShiftKeys); - break; - - case 40: /* 80 <--> 132 mode */ - PrivCases(PrivMode_132OK); - break; - - case 47: /* secondary screen */ - PrivCases(PrivMode_Screen); - scr_change_screen(state); - break; - - case 66: /* application key pad */ - PrivCases(PrivMode_aplKP); - break; - - case 67: - PrivCases(PrivMode_BackSpace); - break; - - case 1000: /* X11 mouse reporting */ - PrivCases(PrivMode_MouseX11); - /* orthogonal */ - if (PrivateModes & PrivMode_MouseX11) - PrivateModes &= ~(PrivMode_MouseX10); - break; - -#if 0 - case 1001: - break; /* X11 mouse highlighting */ -#endif - case 1010: /* Scroll to bottom on TTY output */ - if (Options & Opt_homeOnEcho) - Options &= ~Opt_homeOnEcho; - else - Options |= Opt_homeOnEcho; - break; - case 1011: /* scroll to bottom on refresh */ - if (Options & Opt_homeOnRefresh) - Options &= ~Opt_homeOnRefresh; - else - Options |= Opt_homeOnRefresh; - break; - case 1012: /* Scroll to bottom on TTY input */ - if (Options & Opt_homeOnInput) - Options &= ~Opt_homeOnInput; - else - Options |= Opt_homeOnInput; - break; - } -#undef PrivCases - break; - } -} - -/* process sgr sequences */ -/* PROTO */ -void -process_sgr_mode(unsigned int nargs, int arg[]) -{ - unsigned int i; - - if (nargs == 0) { - scr_rendition(0, ~RS_None); - return; - } - for (i = 0; i < nargs; i++) - switch (arg[i]) { - case 0: - scr_rendition(0, ~RS_None); - break; - case 1: - scr_rendition(1, RS_Bold); - break; - case 4: - scr_rendition(1, RS_Uline); - break; - case 5: - scr_rendition(1, RS_Blink); - break; - case 7: - scr_rendition(1, RS_RVid); - break; - case 22: - scr_rendition(0, RS_Bold); - break; - case 24: - scr_rendition(0, RS_Uline); - break; - case 25: - scr_rendition(0, RS_Blink); - break; - case 27: - scr_rendition(0, RS_RVid); - break; - - case 30: - case 31: /* set fg color */ - case 32: - case 33: - case 34: - case 35: - case 36: - case 37: - scr_color(minColor + (arg[i] - 30), RS_Bold); - break; - case 39: /* default fg */ - scr_color(restoreFG, RS_Bold); - break; - - case 40: - case 41: /* set bg color */ - case 42: - case 43: - case 44: - case 45: - case 46: - case 47: - scr_color(minColor + (arg[i] - 40), RS_Blink); - break; - case 49: /* default bg */ - scr_color(restoreBG, RS_Blink); - break; - } -} - -/* process Rob Nation's own graphics mode sequences */ -/* PROTO */ -void -process_graphics(void) -{ - unsigned char ch, cmd = cmd_getc(); - -#ifndef RXVT_GRAPHICS - if (cmd == 'Q') { /* query graphics */ - tt_printf("\033G0\n"); /* no graphics */ - return; - } - /* swallow other graphics sequences until terminating ':' */ - do - ch = cmd_getc(); - while (ch != ':'); -#else - int nargs; - int args[NGRX_PTS]; - unsigned char *text = NULL; - - if (cmd == 'Q') { /* query graphics */ - tt_printf("\033G1\n"); /* yes, graphics (color) */ - return; - } - for (nargs = 0; nargs < (sizeof(args) / sizeof(args[0])) - 1; /*nil */ ) { - int neg; - - ch = cmd_getc(); - neg = (ch == '-'); - if (neg || ch == '+') - ch = cmd_getc(); - - for (args[nargs] = 0; isdigit(ch); ch = cmd_getc()) - args[nargs] = args[nargs] * 10 + (ch - '0'); - if (neg) - args[nargs] = -args[nargs]; - - nargs++; - args[nargs] = 0; - if (ch != ';') - break; - } - - if ((cmd == 'T') && (nargs >= 5)) { - int i, len = args[4]; - - text = MALLOC((len + 1) * sizeof(char)); - - if (text != NULL) { - for (i = 0; i < len; i++) - text[i] = cmd_getc(); - text[len] = '\0'; - } - } - Gr_do_graphics(cmd, nargs, args, text); -#endif -} - #ifndef USE_POSIX_THREADS /* Read and process output from the application */ @@ -5152,18 +2671,9 @@ main_loop(void) } #endif -/* Addresses pasting large amounts of data - * code pinched from xterm - */ - -static char *v_buffer; /* pointer to physical buffer */ -static char *v_bufstr = NULL; /* beginning of area to write */ -static char *v_bufptr; /* end of area to write */ -static char *v_bufend; /* end of physical buffer */ - /* output a burst of any pending data from a paste... */ -static int -v_doPending() +int +v_doPending(void) { if (v_bufstr >= v_bufptr) @@ -5176,7 +2686,7 @@ v_doPending() * or generated by us in response to a query ESC sequence. * Code stolen from xterm */ -static void +void v_writeBig(int f, char *d, int len) { @@ -5248,30 +2758,6 @@ v_writeBig(int f, char *d, int len) * a little more forgiving.) */ -#if defined(linux) -# ifdef PTY_BUF_SIZE /* From */ -# define MAX_PTY_WRITE PTY_BUF_SIZE -# endif -#endif - -/* NOTE: _POSIX_MAX_INPUT is defined _through_ at least for - * the following systems: HP-UX 10.20, AIX (no idea about the version), - * OSF1/alpha 4.0, Linux (probably any Linux system). - */ -#ifndef MAX_PTY_WRITE -# ifdef _POSIX_VERSION -# ifdef _POSIX_MAX_INPUT -# define MAX_PTY_WRITE _POSIX_MAX_INPUT -# else -# define MAX_PTY_WRITE 255 /* POSIX minimum MAX_INPUT */ -# endif -# endif -#endif - -#ifndef MAX_PTY_WRITE -# define MAX_PTY_WRITE 128 /* 1/2 POSIX minimum MAX_INPUT */ -#endif - if (v_bufptr > v_bufstr) { written = write(f, v_bufstr, v_bufptr - v_bufstr <= MAX_PTY_WRITE ? v_bufptr - v_bufstr : MAX_PTY_WRITE); @@ -5303,1821 +2789,3 @@ v_writeBig(int f, char *d, int len) } } } - -#ifndef MAX -# define MAX(a,b) ((a) > (b) ? (a) : (b)) -#endif - -XErrorHandler -xerror_handler(Display * display, XErrorEvent * event) -{ - - char err_string[2048]; - extern char *XRequest, *XlibMessage; - - strcpy(err_string, ""); - XGetErrorText(Xdisplay, event->error_code, err_string, sizeof(err_string)); - print_error("XError in function %s (request %d.%d): %s (error %d)", request_code_to_name(event->request_code), - event->request_code, event->minor_code, err_string, event->error_code); -#if DEBUG > DEBUG_X11 - if (debug_level >= DEBUG_X11) { - dump_stack_trace(); - } -#endif - print_error("Attempting to continue..."); - return 0; -} - -/* color aliases, fg/bg bright-bold */ -/*static inline void */ -/* inline void */ -void -color_aliases(int idx) -{ - - if (rs_color[idx] && isdigit(*rs_color[idx])) { - - int i = atoi(rs_color[idx]); - - if (i >= 8 && i <= 15) { /* bright colors */ - i -= 8; -#ifndef NO_BRIGHTCOLOR - rs_color[idx] = rs_color[minBright + i]; - return; -#endif - } - if (i >= 0 && i <= 7) /* normal colors */ - rs_color[idx] = rs_color[minColor + i]; - } -} - -/* - * find if fg/bg matches any of the normal (low-intensity) colors - */ -#ifndef NO_BRIGHTCOLOR -static inline void -set_colorfgbg(void) -{ - unsigned int i; - static char *colorfgbg_env = NULL; - char *p; - int fg = -1, bg = -1; - - if (!colorfgbg_env) { - colorfgbg_env = (char *) malloc(30); - strcpy(colorfgbg_env, "COLORFGBG=default;default;bg"); - } - for (i = BlackColor; i <= WhiteColor; i++) { - if (PixColors[fgColor] == PixColors[i]) { - fg = (i - BlackColor); - break; - } - } - for (i = BlackColor; i <= WhiteColor; i++) { - if (PixColors[bgColor] == PixColors[i]) { - bg = (i - BlackColor); - break; - } - } - - p = strchr(colorfgbg_env, '='); - p++; - if (fg >= 0) - sprintf(p, "%d;", fg); - else - strcpy(p, "default;"); - p = strchr(p, '\0'); - if (bg >= 0) - sprintf(p, -# ifdef PIXMAP_SUPPORT - "default;" -# endif - "%d", bg); - else - strcpy(p, "default"); - putenv(colorfgbg_env); - - colorfgbg = DEFAULT_RSTYLE; - for (i = minColor; i <= maxColor; i++) { - if (PixColors[fgColor] == PixColors[i] -# ifndef NO_BOLDUNDERLINE - && PixColors[fgColor] == PixColors[colorBD] -# endif /* NO_BOLDUNDERLINE */ - /* if we wanted boldFont to have precedence */ -# if 0 /* ifndef NO_BOLDFONT */ - && TermWin.boldFont == NULL -# endif /* NO_BOLDFONT */ - ) - colorfgbg = SET_FGCOLOR(colorfgbg, i); - if (PixColors[bgColor] == PixColors[i]) - colorfgbg = SET_BGCOLOR(colorfgbg, i); - } -} -#else /* NO_BRIGHTCOLOR */ -# define set_colorfgbg() ((void)0) -#endif /* NO_BRIGHTCOLOR */ - -/* Create_Windows() - Open and map the window */ -void -Create_Windows(int argc, char *argv[]) -{ - - Cursor cursor; - XClassHint classHint; - XWMHints wmHint; - Atom prop; - CARD32 val; - int i, x, y, flags; - unsigned int width, height; - unsigned int r, g, b; - MWMHints mwmhints; - -/* char *tmp; */ - - if (Options & Opt_borderless) { - prop = XInternAtom(Xdisplay, "_MOTIF_WM_HINTS", True); - if (prop == None) { - print_warning("Window Manager does not support MWM hints. Bypassing window manager control for borderless window."); - Attributes.override_redirect = TRUE; - mwmhints.flags = 0; - } else { - mwmhints.flags = MWM_HINTS_DECORATIONS; - mwmhints.decorations = 0; - } - } - Attributes.save_under = TRUE; - Attributes.backing_store = WhenMapped; - - /* - * grab colors before netscape does - */ - for (i = 0; i < (Xdepth <= 2 ? 2 : NRS_COLORS); i++) { - - XColor xcol; - unsigned char found_color; - - if (!rs_color[i]) - continue; - - if (!XParseColor(Xdisplay, Xcmap, rs_color[i], &xcol)) { - print_warning("Unable to resolve \"%s\" as a color name. Falling back on \"%s\".", - rs_color[i], def_colorName[i] ? def_colorName[i] : "(nil)"); - rs_color[i] = def_colorName[i]; - if (!rs_color[i]) - continue; - if (!XParseColor(Xdisplay, Xcmap, rs_color[i], &xcol)) { - print_warning("Unable to resolve \"%s\" as a color name. This should never fail. Please repair/restore your RGB database.", rs_color[i]); - found_color = 0; - } else { - found_color = 1; - } - } else { - found_color = 1; - } - if (found_color) { - r = xcol.red; - g = xcol.green; - b = xcol.blue; - xcol.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); - if (!XAllocColor(Xdisplay, Xcmap, &xcol)) { - print_warning("Unable to allocate \"%s\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map. " - "Falling back on \"%s\".", - rs_color[i], xcol.pixel, r, g, b, def_colorName[i] ? def_colorName[i] : "(nil)"); - rs_color[i] = def_colorName[i]; - if (!rs_color[i]) - continue; - if (!XAllocColor(Xdisplay, Xcmap, &xcol)) { - print_warning("Unable to allocate \"%s\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map.", - rs_color[i], xcol.pixel, r, g, b); - found_color = 0; - } else { - found_color = 1; - } - } else { - found_color = 1; - } - } - if (!found_color) { - switch (i) { - case fgColor: - case bgColor: - /* fatal: need bg/fg color */ - fatal_error("Unable to get foreground/background colors!"); - break; -#ifndef NO_CURSORCOLOR - case cursorColor: - xcol.pixel = PixColors[bgColor]; - break; - case cursorColor2: - xcol.pixel = PixColors[fgColor]; - break; -#endif /* NO_CURSORCOLOR */ - default: - xcol.pixel = PixColors[bgColor]; /* None */ - break; - } - } - PixColors[i] = xcol.pixel; - } - -#ifndef NO_CURSORCOLOR - if (Xdepth <= 2 || !rs_color[cursorColor]) - PixColors[cursorColor] = PixColors[bgColor]; - if (Xdepth <= 2 || !rs_color[cursorColor2]) - PixColors[cursorColor2] = PixColors[fgColor]; -#endif /* NO_CURSORCOLOR */ - if (Xdepth <= 2 || !rs_color[pointerColor]) - PixColors[pointerColor] = PixColors[fgColor]; - if (Xdepth <= 2 || !rs_color[borderColor]) - PixColors[borderColor] = PixColors[bgColor]; - -#ifndef NO_BOLDUNDERLINE - if (Xdepth <= 2 || !rs_color[colorBD]) - PixColors[colorBD] = PixColors[fgColor]; - if (Xdepth <= 2 || !rs_color[colorUL]) - PixColors[colorUL] = PixColors[fgColor]; -#endif /* NO_BOLDUNDERLINE */ - - /* - * get scrollBar/menuBar shadow colors - * - * The calculations of topShadow/bottomShadow values are adapted - * from the fvwm window manager. - */ -#ifdef KEEP_SCROLLCOLOR - if (Xdepth <= 2) { /* Monochrome */ - PixColors[scrollColor] = PixColors[bgColor]; - PixColors[topShadowColor] = PixColors[fgColor]; - PixColors[bottomShadowColor] = PixColors[fgColor]; - -# ifdef CHANGE_SCROLLCOLOR_ON_FOCUS - PixColors[unfocusedScrollColor] = PixColors[bgColor]; - PixColors[unfocusedTopShadowColor] = PixColors[fgColor]; - PixColors[unfocusedBottomShadowColor] = PixColors[fgColor]; -# endif - - } else { - - XColor xcol, white; - - /* bottomShadowColor */ - xcol.pixel = PixColors[scrollColor]; - XQueryColor(Xdisplay, Xcmap, &xcol); - - xcol.red /= 2; - xcol.green /= 2; - xcol.blue /= 2; - r = xcol.red; - g = xcol.green; - b = xcol.blue; - xcol.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); - - if (!XAllocColor(Xdisplay, Xcmap, &xcol)) { - print_error("Unable to allocate \"bottomShadowColor\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map.", - xcol.pixel, r, g, b); - xcol.pixel = PixColors[minColor]; - } - PixColors[bottomShadowColor] = xcol.pixel; - -#ifdef CHANGE_SCROLLCOLOR_ON_FOCUS - /* unfocusedBottomShadowColor */ - xcol.pixel = PixColors[unfocusedScrollColor]; - XQueryColor(Xdisplay, Xcmap, &xcol); - - xcol.red /= 2; - xcol.green /= 2; - xcol.blue /= 2; - r = xcol.red; - g = xcol.green; - b = xcol.blue; - xcol.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); - - if (!XAllocColor(Xdisplay, Xcmap, &xcol)) { - print_error("Unable to allocate \"unfocusedbottomShadowColor\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map.", - xcol.pixel, r, g, b); - xcol.pixel = PixColors[minColor]; - } - PixColors[unfocusedBottomShadowColor] = xcol.pixel; -#endif - - /* topShadowColor */ -# ifdef PREFER_24BIT - white.red = white.green = white.blue = r = g = b = ~0; - white.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); - XAllocColor(Xdisplay, Xcmap, &white); -# else - white.pixel = WhitePixel(Xdisplay, Xscreen); - XQueryColor(Xdisplay, Xcmap, &white); -# endif - - xcol.pixel = PixColors[scrollColor]; - XQueryColor(Xdisplay, Xcmap, &xcol); - - xcol.red = max((white.red / 5), xcol.red); - xcol.green = max((white.green / 5), xcol.green); - xcol.blue = max((white.blue / 5), xcol.blue); - - xcol.red = min(white.red, (xcol.red * 7) / 5); - xcol.green = min(white.green, (xcol.green * 7) / 5); - xcol.blue = min(white.blue, (xcol.blue * 7) / 5); - r = xcol.red; - g = xcol.green; - b = xcol.blue; - xcol.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); - - if (!XAllocColor(Xdisplay, Xcmap, &xcol)) { - print_error("Unable to allocate \"topShadowColor\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map.", - xcol.pixel, r, g, b); - xcol.pixel = PixColors[WhiteColor]; - } - PixColors[topShadowColor] = xcol.pixel; - -#ifdef CHANGE_SCROLLCOLOR_ON_FOCUS - /* Do same for unfocusedTopShadowColor */ - xcol.pixel = PixColors[unfocusedScrollColor]; - XQueryColor(Xdisplay, Xcmap, &xcol); - - xcol.red = max((white.red / 5), xcol.red); - xcol.green = max((white.green / 5), xcol.green); - xcol.blue = max((white.blue / 5), xcol.blue); - - xcol.red = min(white.red, (xcol.red * 7) / 5); - xcol.green = min(white.green, (xcol.green * 7) / 5); - xcol.blue = min(white.blue, (xcol.blue * 7) / 5); - r = xcol.red; - g = xcol.green; - b = xcol.blue; - xcol.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); - - if (!XAllocColor(Xdisplay, Xcmap, &xcol)) { - print_error("Unable to allocate \"unfocusedtopShadowColor\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map.", - xcol.pixel, r, g, b); - xcol.pixel = PixColors[WhiteColor]; - } - PixColors[unfocusedTopShadowColor] = xcol.pixel; -#endif - - } -#endif /* KEEP_SCROLLCOLOR */ - - szHint.base_width = (2 * TermWin.internalBorder + - (Options & Opt_scrollBar ? scrollbar_total_width() - : 0)); - szHint.base_height = (2 * TermWin.internalBorder); - - flags = (rs_geometry ? XParseGeometry(rs_geometry, &x, &y, &width, &height) : 0); - D_X11(("XParseGeometry(geom, %d, %d, %d, %d)\n", x, y, width, height)); - - if (flags & WidthValue) { - szHint.width = width; - szHint.flags |= USSize; - } - if (flags & HeightValue) { - szHint.height = height; - szHint.flags |= USSize; - } - TermWin.ncol = szHint.width; - TermWin.nrow = szHint.height; - - change_font(1, NULL); -#if (MENUBAR_MAX) - szHint.base_height += (delay_menu_drawing ? menuBar_TotalHeight() : 0); -#endif - if (flags & XValue) { - if (flags & XNegative) { - if (check_for_enlightenment()) { - x += (DisplayWidth(Xdisplay, Xscreen)); - } else { - x += (DisplayWidth(Xdisplay, Xscreen) - (szHint.width + TermWin.internalBorder)); - } - szHint.win_gravity = NorthEastGravity; - } - szHint.x = x; - szHint.flags |= USPosition; - } - if (flags & YValue) { - if (flags & YNegative) { - if (check_for_enlightenment()) { - y += (DisplayHeight(Xdisplay, Xscreen) - (2 * TermWin.internalBorder)); - } else { - y += (DisplayHeight(Xdisplay, Xscreen) - (szHint.height + TermWin.internalBorder)); - } - szHint.win_gravity = (szHint.win_gravity == NorthEastGravity ? - SouthEastGravity : SouthWestGravity); - } - szHint.y = y; - szHint.flags |= USPosition; - } - D_X11(("Geometry values after parsing: %dx%d%+d%+d\n", width, height, x, y)); - - /* parent window - reverse video so we can see placement errors - * sub-window placement & size in resize_subwindows() - */ - - Attributes.background_pixel = PixColors[bgColor]; - Attributes.border_pixel = PixColors[bgColor]; -#ifdef PREFER_24BIT - Attributes.colormap = Xcmap; - TermWin.parent = XCreateWindow(Xdisplay, Xroot, - szHint.x, szHint.y, - szHint.width, szHint.height, - 0, - Xdepth, InputOutput, - Xvisual, - CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect, - &Attributes); -#else - TermWin.parent = XCreateWindow(Xdisplay, Xroot, - szHint.x, szHint.y, - szHint.width, szHint.height, - 0, - Xdepth, - InputOutput, - CopyFromParent, - CWBackPixel | CWBorderPixel | CWOverrideRedirect, - &Attributes); -#endif - - xterm_seq(XTerm_title, rs_title); - xterm_seq(XTerm_iconName, rs_iconName); - classHint.res_name = (char *) rs_name; - classHint.res_class = APL_NAME; - wmHint.window_group = TermWin.parent; - wmHint.input = True; - wmHint.initial_state = (Options & Opt_iconic ? IconicState : NormalState); - wmHint.window_group = TermWin.parent; - wmHint.flags = (InputHint | StateHint | WindowGroupHint); -#ifdef PIXMAP_SUPPORT - set_icon_pixmap(rs_icon, &wmHint); -#endif - - XSetWMProperties(Xdisplay, TermWin.parent, NULL, NULL, argv, argc, &szHint, &wmHint, &classHint); - XSelectInput(Xdisplay, TermWin.parent, (KeyPressMask | FocusChangeMask | StructureNotifyMask | VisibilityChangeMask)); - if (mwmhints.flags) { - XChangeProperty(Xdisplay, TermWin.parent, prop, prop, 32, PropModeReplace, (unsigned char *) &mwmhints, PROP_MWM_HINTS_ELEMENTS); - } - /* vt cursor: Black-on-White is standard, but this is more popular */ - TermWin_cursor = XCreateFontCursor(Xdisplay, XC_xterm); - { - - XColor fg, bg; - - fg.pixel = PixColors[pointerColor]; - XQueryColor(Xdisplay, Xcmap, &fg); - bg.pixel = PixColors[bgColor]; - XQueryColor(Xdisplay, Xcmap, &bg); - XRecolorCursor(Xdisplay, TermWin_cursor, &fg, &bg); - } - - /* cursor (menuBar/scrollBar): Black-on-White */ - cursor = XCreateFontCursor(Xdisplay, XC_left_ptr); - - /* the vt window */ - -#ifdef BACKING_STORE - if ((!(Options & Opt_borderless)) - && (Options & Opt_saveUnder)) { - D_X11(("Creating term window with save_under = TRUE\n")); - TermWin.vt = XCreateWindow(Xdisplay, TermWin.parent, - 0, 0, - szHint.width, szHint.height, - 0, - Xdepth, - InputOutput, - CopyFromParent, - CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWSaveUnder | CWBackingStore, - &Attributes); - if (!(background_is_pixmap()) && !(Options & Opt_borderless)) { - XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); - XClearWindow(Xdisplay, TermWin.vt); - } - } else -#endif - { - D_X11(("Creating term window with no backing store\n")); - TermWin.vt = XCreateWindow(Xdisplay, TermWin.parent, - 0, 0, - szHint.width, szHint.height, - 0, - Xdepth, - InputOutput, - CopyFromParent, - CWBackPixel | CWBorderPixel | CWOverrideRedirect, - &Attributes); - if (!(background_is_pixmap()) && !(Options & Opt_borderless)) { - XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); - XClearWindow(Xdisplay, TermWin.vt); - } - } - - XDefineCursor(Xdisplay, TermWin.vt, TermWin_cursor); -#ifdef USE_ACTIVE_TAGS - XSelectInput(Xdisplay, TermWin.vt, - (ExposureMask | ButtonPressMask | ButtonReleaseMask | - Button1MotionMask | Button3MotionMask | - PointerMotionMask | LeaveWindowMask)); -#else - XSelectInput(Xdisplay, TermWin.vt, - (ExposureMask | ButtonPressMask | ButtonReleaseMask | - Button1MotionMask | Button3MotionMask)); -#endif - - /* If the user wants a specific desktop, tell the WM that */ - if (rs_desktop != -1) { - prop = XInternAtom(Xdisplay, "_WIN_WORKSPACE", False); - val = rs_desktop; - XChangeProperty(Xdisplay, TermWin.parent, prop, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &val, 1); - } - XMapWindow(Xdisplay, TermWin.vt); - XMapWindow(Xdisplay, TermWin.parent); - - /* scrollBar: size doesn't matter */ -#ifdef KEEP_SCROLLCOLOR - Attributes.background_pixel = PixColors[scrollColor]; -#else - Attributes.background_pixel = PixColors[fgColor]; -#endif - Attributes.border_pixel = PixColors[bgColor]; - - scrollBar.win = XCreateWindow(Xdisplay, TermWin.parent, - 0, 0, - 1, 1, - 0, - Xdepth, - InputOutput, - CopyFromParent, - CWOverrideRedirect | CWSaveUnder | CWBackPixel | CWBorderPixel, - &Attributes); - - XDefineCursor(Xdisplay, scrollBar.win, cursor); - XSelectInput(Xdisplay, scrollBar.win, - (ExposureMask | ButtonPressMask | ButtonReleaseMask | - Button1MotionMask | Button2MotionMask | Button3MotionMask) - ); - -#ifdef PIXMAP_SCROLLBAR - if (scrollbar_is_pixmapped()) { - scrollBar.up_win = XCreateWindow(Xdisplay, scrollBar.win, - 0, 0, - scrollbar_total_width(), - scrollbar_arrow_height(), - 0, - Xdepth, - InputOutput, - CopyFromParent, - CWOverrideRedirect | CWSaveUnder, - &Attributes); - - XDefineCursor(Xdisplay, scrollBar.up_win, cursor); - XSelectInput(Xdisplay, scrollBar.up_win, - (ExposureMask | ButtonPressMask | ButtonReleaseMask | - Button1MotionMask | Button2MotionMask | Button3MotionMask) - ); - - scrollBar.dn_win = XCreateWindow(Xdisplay, scrollBar.win, - 0, - scrollbar_arrow_height() - + scrollbar_anchor_max_height(), - scrollbar_total_width(), - scrollbar_arrow_height(), - 0, - Xdepth, - InputOutput, - CopyFromParent, - CWOverrideRedirect | CWSaveUnder, - &Attributes); - - XDefineCursor(Xdisplay, scrollBar.dn_win, cursor); - XSelectInput(Xdisplay, scrollBar.dn_win, - (ExposureMask | ButtonPressMask | ButtonReleaseMask | - Button1MotionMask | Button2MotionMask | Button3MotionMask) - ); - scrollBar.sa_win = XCreateWindow(Xdisplay, scrollBar.win, - 0, - scrollbar_arrow_height(), - scrollbar_total_width(), - scrollbar_anchor_max_height(), - 0, - Xdepth, - InputOutput, - CopyFromParent, - CWOverrideRedirect | CWSaveUnder | CWBackingStore, - &Attributes); - - XDefineCursor(Xdisplay, scrollBar.sa_win, cursor); - XSelectInput(Xdisplay, scrollBar.sa_win, - (ExposureMask | ButtonPressMask | ButtonReleaseMask | - Button1MotionMask | Button2MotionMask | Button3MotionMask) - ); - } -#endif - -#if (MENUBAR_MAX) - /* menuBar: size doesn't matter */ -# ifdef KEEP_SCROLLCOLOR - Attributes.background_pixel = PixColors[scrollColor]; -# else - Attributes.background_pixel = PixColors[fgColor]; -# endif - Attributes.border_pixel = PixColors[bgColor]; - menuBar.win = XCreateWindow(Xdisplay, TermWin.parent, - 0, 0, - 1, 1, - 0, - Xdepth, - InputOutput, - CopyFromParent, - CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWBackPixel | CWBorderPixel, - &Attributes); - - -# ifdef PIXMAP_MENUBAR - if (menubar_is_pixmapped()) { - set_Pixmap(rs_pixmaps[pixmap_mb], mbPixmap.pixmap, pixmap_mb); - XSetWindowBackgroundPixmap(Xdisplay, menuBar.win, - mbPixmap.pixmap); - } else -# endif - { -# ifdef KEEP_SCROLLCOLOR - XSetWindowBackground(Xdisplay, menuBar.win, PixColors[scrollColor]); -# else - XSetWindowBackground(Xdisplay, menuBar.win, PixColors[fgColor]); -# endif - } - - XClearWindow(Xdisplay, menuBar.win); - - XDefineCursor(Xdisplay, menuBar.win, cursor); - XSelectInput(Xdisplay, menuBar.win, - (ExposureMask | ButtonPressMask | ButtonReleaseMask | - Button1MotionMask) - ); -#endif /* MENUBAR_MAX */ - - XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); - XClearWindow(Xdisplay, TermWin.vt); - -#ifdef PIXMAP_SUPPORT - if (rs_pixmaps[pixmap_bg] != NULL) { - - char *p = rs_pixmaps[pixmap_bg]; - - if ((p = strchr(p, '@')) != NULL) { - p++; - scale_pixmap(p, &bgPixmap); - } - D_PIXMAP(("set_bgPixmap() call #1\n")); - set_bgPixmap(rs_pixmaps[pixmap_bg]); - } -# ifdef PIXMAP_SCROLLBAR - if (scrollbar_is_pixmapped()) { - if (rs_pixmaps[pixmap_sb] != NULL) { - - char *p = rs_pixmaps[pixmap_sb]; - - if ((p = strchr(p, '@')) != NULL) { - p++; - scale_pixmap(p, &sbPixmap); - } - fprintf(stderr, "scrollbar sb: %s\n", p); - D_PIXMAP(("set_Pixmap(rs_pixmaps[pixmap_sb], pixmap_sb)\n")); - set_Pixmap(rs_pixmaps[pixmap_sb], sbPixmap.pixmap, pixmap_sb); - } - if (rs_pixmaps[pixmap_up] != NULL) { - - char *p = rs_pixmaps[pixmap_up]; - - if ((p = strchr(p, '@')) != NULL) { - p++; - scale_pixmap(p, &upPixmap); - } - fprintf(stderr, "scrollbar up: %s\n", p); - D_PIXMAP(("set_Pixmap(rs_pixmaps[pixmap_up], pixmap_up)\n")); - set_Pixmap(rs_pixmaps[pixmap_up], upPixmap.pixmap, pixmap_up); - } - if (rs_pixmaps[pixmap_upclk] != NULL) { - - char *p = rs_pixmaps[pixmap_upclk]; - - if ((p = strchr(p, '@')) != NULL) { - p++; - scale_pixmap(p, &up_clkPixmap); - } - fprintf(stderr, "scrollbar upclk: %s\n", p); - D_PIXMAP(("set_Pixmap(rs_pixmaps[pixmap_upclk], pixmap_upclk)\n")); - set_Pixmap(rs_pixmaps[pixmap_upclk], up_clkPixmap.pixmap, pixmap_upclk); - } - if (rs_pixmaps[pixmap_dn] != NULL) { - - char *p = rs_pixmaps[pixmap_dn]; - - if ((p = strchr(p, '@')) != NULL) { - p++; - scale_pixmap(p, &dnPixmap); - } - fprintf(stderr, "scrollbar dn: %s\n", p); - D_PIXMAP(("set_Pixmap(rs_pixmaps[pixmap_dn], pixmap_dn)\n")); - set_Pixmap(rs_pixmaps[pixmap_dn], dnPixmap.pixmap, pixmap_dn); - } - if (rs_pixmaps[pixmap_dnclk] != NULL) { - - char *p = rs_pixmaps[pixmap_dnclk]; - - if ((p = strchr(p, '@')) != NULL) { - p++; - scale_pixmap(p, &dn_clkPixmap); - } - fprintf(stderr, "scrollbar dnclk: %s\n", p); - D_PIXMAP(("set_Pixmap(rs_pixmaps[pixmap_dnclk], pixmap_dnclk)\n")); - set_Pixmap(rs_pixmaps[pixmap_dnclk], dn_clkPixmap.pixmap, pixmap_dnclk); - } - if (rs_pixmaps[pixmap_sa] != NULL) { - - char *p = rs_pixmaps[pixmap_sa]; - - if ((p = strchr(p, '@')) != NULL) { - p++; - scale_pixmap(p, &saPixmap); - } - fprintf(stderr, "scrollbar sa: %s\n", p); - D_PIXMAP(("set_Pixmap(rs_pixmaps[pixmap_sa], pixmap_sa)\n")); - set_Pixmap(rs_pixmaps[pixmap_sa], saPixmap.pixmap, pixmap_sa); - } - if (rs_pixmaps[pixmap_saclk] != NULL) { - - char *p = rs_pixmaps[pixmap_saclk]; - - if ((p = strchr(p, '@')) != NULL) { - p++; - scale_pixmap(p, &sa_clkPixmap); - } - fprintf(stderr, "scrollbar saclk: %s\n", p); - D_PIXMAP(("set_Pixmap(rs_pixmaps[pixmap_saclk], pixmap_saclk)\n")); - set_Pixmap(rs_pixmaps[pixmap_saclk], sa_clkPixmap.pixmap, pixmap_saclk); - } - } -# endif /* PIXMAP_SCROLLBAR */ - -# ifdef PIXMAP_MENUBAR - if (menubar_is_pixmapped()) { - if (rs_pixmaps[pixmap_mb] != NULL) { - - char *p = rs_pixmaps[pixmap_mb]; - - if ((p = strchr(p, '@')) != NULL) { - p++; - scale_pixmap(p, &mbPixmap); - } - fprintf(stderr, "menubar mb: %s\n", p); - set_Pixmap(rs_pixmaps[pixmap_mb], mbPixmap.pixmap, pixmap_mb); - } - if (rs_pixmaps[pixmap_ms] != NULL) { - - char *p = rs_pixmaps[pixmap_ms]; - - if ((p = strchr(p, '@')) != NULL) { - p++; - scale_pixmap(p, &mb_selPixmap); - } - fprintf(stderr, "menubar ms: %s\n", p); - D_PIXMAP(("set_Pixmap(rs_pixmaps[pixmap_ms], pixmap_ms)\n")); - set_Pixmap(rs_pixmaps[pixmap_ms], mb_selPixmap.pixmap, pixmap_ms); - } - } -# endif /* PIXMAP_MENUBAR */ -#else /* PIXMAP_SUPPORT */ - XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); - XClearWindow(Xdisplay, TermWin.vt); -#endif /* PIXMAP_SUPPORT */ - - /* graphics context for the vt window */ - { - - XGCValues gcvalue; - - gcvalue.font = TermWin.font->fid; - gcvalue.foreground = PixColors[fgColor]; - gcvalue.background = PixColors[bgColor]; - gcvalue.graphics_exposures = 0; - TermWin.gc = XCreateGC(Xdisplay, TermWin.vt, - GCForeground | GCBackground | GCFont | GCGraphicsExposures, - &gcvalue); - } - - if (Options & Opt_noCursor) - scr_cursor_visible(0); -} - -/* window resizing - assuming the parent window is the correct size */ -void -resize_subwindows(int width, int height) -{ - - int x = 0, y = 0; - -#ifdef RXVT_GRAPHICS - int old_width = TermWin.width; - int old_height = TermWin.height; - -#endif - - D_SCREEN(("resize_subwindows(%d, %d)\n", width, height)); - TermWin.width = TermWin.ncol * TermWin.fwidth; - TermWin.height = TermWin.nrow * TermWin.fheight; - - /* size and placement */ - if (scrollbar_visible()) { - scrollBar.beg = 0; - scrollBar.end = height; -#ifdef MOTIF_SCROLLBAR - if (scrollBar.type == SCROLLBAR_MOTIF) { - /* arrows are as high as wide - leave 1 pixel gap */ - scrollBar.beg += scrollbar_arrow_height(); - scrollBar.end -= scrollbar_arrow_height(); - } -#endif -#ifdef NEXT_SCROLLBAR - if (scrollBar.type == SCROLLBAR_NEXT) { - scrollBar.beg = sb_shadow; - scrollBar.end -= (scrollBar.width * 2 + (sb_shadow ? sb_shadow : 1) + 2); - } -#endif - width -= scrollbar_total_width(); - XMoveResizeWindow(Xdisplay, scrollBar.win, - ((Options & Opt_scrollBar_right) ? (width) : (x)), - 0, scrollbar_total_width(), height); - - if (!(Options & Opt_scrollBar_right)) { - x = scrollbar_total_width(); - } - } -#if (MENUBAR_MAX) - if (menubar_visible()) { - y = menuBar_TotalHeight(); /* for placement of vt window */ - XMoveResizeWindow(Xdisplay, menuBar.win, x, 0, width, y); - if ((!(menubar_is_pixmapped())) - && ((Options & Opt_borderless) || (Options & Opt_saveUnder))) - XSetWindowBackground(Xdisplay, menuBar.win, PixColors[scrollColor]); - } -#endif /* NO_MENUBAR */ - - XMoveResizeWindow(Xdisplay, TermWin.vt, x, y, width, height + 1); - -#ifdef RXVT_GRAPHICS - if (old_width) - Gr_Resize(old_width, old_height); -#endif - XClearWindow(Xdisplay, TermWin.vt); - if (!(background_is_pixmap())) - XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); - -#ifdef PIXMAP_SUPPORT -# ifdef USE_POSIX_THREADS - - D_PIXMAP(("resize_subwindows(): start_bg_thread()\n")); - pthread_attr_init(&resize_sub_thr_attr); - -# ifdef MUTEX_SYNCH - if (pthread_mutex_trylock(&mutex) == EBUSY) { - D_THREADS(("resize_subwindows(): mutex locked, bbl\n")); - } else { - D_THREADS(("pthread_mutex_trylock(&mutex): ")); - pthread_mutex_unlock(&mutex); - D_THREADS(("pthread_mutex_unlock(&mutex)\n")); - } -# endif - - if (!(pthread_create(&resize_sub_thr, &resize_sub_thr_attr, - (void *) &render_bg_thread, NULL))) { - /* bg_set = 0; */ - D_THREADS(("thread created\n")); - } else { - D_THREADS(("pthread_create() failed!\n")); - } - -# else - D_PIXMAP(("resize_subwindows(): render_pixmap(TermWin.vt)\n")); - render_pixmap(TermWin.vt, imlib_bg, bgPixmap, 0, 1); - XSync(Xdisplay, 0); -# endif -#endif -} - -static void -resize(void) -{ - szHint.base_width = (2 * TermWin.internalBorder); - szHint.base_height = (2 * TermWin.internalBorder); - - szHint.base_width += (scrollbar_visible()? scrollbar_total_width() : 0); -#if (MENUBAR_MAX) - szHint.base_height += (menubar_visible()? menuBar_TotalHeight() : 0); -#endif - - szHint.min_width = szHint.base_width + szHint.width_inc; - szHint.min_height = szHint.base_height + szHint.height_inc; - - szHint.width = szHint.base_width + TermWin.width; - szHint.height = szHint.base_height + TermWin.height; - - szHint.flags = PMinSize | PResizeInc | PBaseSize | PWinGravity; - - XSetWMNormalHints(Xdisplay, TermWin.parent, &szHint); - XResizeWindow(Xdisplay, TermWin.parent, szHint.width, szHint.height); - - resize_subwindows(szHint.width, szHint.height); -} - -/* - * Redraw window after exposure or size change - */ -static void -resize_window1(unsigned int width, unsigned int height) -{ - static short first_time = 1; - int new_ncol = (width - szHint.base_width) / TermWin.fwidth; - int new_nrow = (height - szHint.base_height) / TermWin.fheight; - - if (first_time || - (new_ncol != TermWin.ncol) || - (new_nrow != TermWin.nrow)) { - int curr_screen = -1; - - /* scr_reset only works on the primary screen */ - if (!first_time) { /* this is not the first time thru */ - selection_clear(); - curr_screen = scr_change_screen(PRIMARY); - } - TermWin.ncol = new_ncol; - TermWin.nrow = new_nrow; - - resize_subwindows(width, height); - scr_reset(); - - if (curr_screen >= 0) /* this is not the first time thru */ - scr_change_screen(curr_screen); - first_time = 0; - } else if (Options & Opt_pixmapTrans) { - resize_subwindows(width, height); - scrollbar_show(0); - scr_expose(0, 0, width, height); - } -} - -/* - * good for toggling 80/132 columns - */ -void -set_width(unsigned short width) -{ - unsigned short height = TermWin.nrow; - - if (width != TermWin.ncol) { - width = szHint.base_width + width * TermWin.fwidth; - height = szHint.base_height + height * TermWin.fheight; - - XResizeWindow(Xdisplay, TermWin.parent, width, height); - resize_window1(width, height); - } -} - -/* - * Redraw window after exposure or size change - */ -void -resize_window(void) -{ - Window root; - XEvent dummy; - int x, y; - unsigned int border, depth, width, height; - - while (XCheckTypedWindowEvent(Xdisplay, TermWin.parent, - ConfigureNotify, &dummy)); - - /* do we come from an fontchange? */ - if (font_change_count > 0) { - font_change_count--; - return; - } - XGetGeometry(Xdisplay, TermWin.parent, - &root, &x, &y, &width, &height, &border, &depth); -#if 0 - XGetGeometry(Xdisplay, TermWin.vt, - &root, &x, &y, &width, &height, &border, &depth); -#endif - - /* parent already resized */ - - resize_window1(width, height); -} - -/* xterm sequences - title, iconName, color (exptl) */ -#ifdef SMART_WINDOW_TITLE -static void -set_title(const char *str) -{ - - char *name; - - if (XFetchName(Xdisplay, TermWin.parent, &name)) - name = NULL; - if (name == NULL || strcmp(name, str)) - XStoreName(Xdisplay, TermWin.parent, str); - if (name) - XFree(name); -} -#else -# define set_title(str) XStoreName(Xdisplay, TermWin.parent, str) -#endif - -#ifdef SMART_WINDOW_TITLE -static void -set_iconName(const char *str) -{ - - char *name; - - if (XGetIconName(Xdisplay, TermWin.parent, &name)) - name = NULL; - if (name == NULL || strcmp(name, str)) - XSetIconName(Xdisplay, TermWin.parent, str); - if (name) - XFree(name); -} -#else -# define set_iconName(str) XSetIconName (Xdisplay, TermWin.parent, str) -#endif - -#ifdef XTERM_COLOR_CHANGE -static void -set_window_color(int idx, const char *color) -{ - - XColor xcol; - int i; - unsigned int pixel, r, g, b; - - if (color == NULL || *color == '\0') - return; - - /* handle color aliases */ - if (isdigit(*color)) { - i = atoi(color); - if (i >= 8 && i <= 15) { /* bright colors */ - i -= 8; -# ifndef NO_BRIGHTCOLOR - PixColors[idx] = PixColors[minBright + i]; - goto Done; -# endif - } - if (i >= 0 && i <= 7) { /* normal colors */ - PixColors[idx] = PixColors[minColor + i]; - goto Done; - } - } - if (XParseColor(Xdisplay, Xcmap, color, &xcol)) { - r = xcol.red; - g = xcol.green; - b = xcol.blue; - pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); - xcol.pixel = pixel; - if (!XAllocColor(Xdisplay, Xcmap, &xcol)) { - print_warning("Unable to allocate \"%s\" in the color map.\n", color); - return; - } - } else { - print_warning("Unable to resolve \"%s\" as a color name.\n", color); - return; - } - - /* XStoreColor(Xdisplay, Xcmap, XColor*); */ - - /* - * FIXME: should free colors here, but no idea how to do it so instead, - * so just keep gobbling up the colormap - */ -# if 0 - for (i = BlackColor; i <= WhiteColor; i++) - if (PixColors[idx] == PixColors[i]) - break; - if (i > WhiteColor) { - /* fprintf (stderr, "XFreeColors: PixColors[%d] = %lu\n", idx, PixColors[idx]); */ - XFreeColors(Xdisplay, Xcmap, (PixColors + idx), 1, - DisplayPlanes(Xdisplay, Xscreen)); - } -# endif - - PixColors[idx] = xcol.pixel; - - /* XSetWindowAttributes attr; */ - /* Cursor cursor; */ -Done: - if (idx == bgColor) - XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); - - /* handle colorBD, scrollbar background, etc. */ - - set_colorfgbg(); - { - - XColor fg, bg; - - fg.pixel = PixColors[fgColor]; - XQueryColor(Xdisplay, Xcmap, &fg); - bg.pixel = PixColors[bgColor]; - XQueryColor(Xdisplay, Xcmap, &bg); - - XRecolorCursor(Xdisplay, TermWin_cursor, &fg, &bg); - } - /* the only reasonable way to enforce a clean update */ - scr_poweron(); -} -#else -# define set_window_color(idx,color) ((void)0) -#endif /* XTERM_COLOR_CHANGE */ - -/* Macros to make parsing escape sequences slightly more readable.... */ -#define OPT_SET_OR_TOGGLE(s, mask, bit) do { \ - if (!(s) || !(*(s))) { \ - if ((mask) & (bit)) { \ - (mask) &= ~(bit); \ - } else { \ - (mask) |= (bit); \ - } \ - } else if (BOOL_OPT_ISTRUE(s)) { \ - if ((mask) & (bit)) return; \ - (mask) |= (bit); \ - } else if (BOOL_OPT_ISFALSE(s)) { \ - if (!((mask) & (bit))) return; \ - (mask) &= ~(bit); \ - } \ - } while (0) -/* The macro below forces bit to the opposite state from what we want, so that the - code that follows will set it right. Hackish, but saves space. :) Use this - if you need to do some processing other than just setting the flag right. */ -#define OPT_SET_OR_TOGGLE_NEG(s, mask, bit) do { if (s) { \ - if (BOOL_OPT_ISTRUE(s)) { \ - if ((mask) & (bit)) return; \ - (mask) &= ~(bit); \ - } else if (BOOL_OPT_ISFALSE(s)) { \ - if (!((mask) & (bit))) return; \ - (mask) |= (bit); \ - } \ - } } while (0) - -/* - * XTerm escape sequences: ESC ] Ps;Pt BEL - * 0 = change iconName/title - * 1 = change iconName - * 2 = change title - * 46 = change logfile (not implemented) - * 50 = change font - * - * rxvt/Eterm extensions: - * 5 = Hostile takeover (grab focus and raise) - * 6 = Transparency mode stuff - * 10 = menu - * 20 = bg pixmap - * 39 = change default fg color - * 49 = change default bg color - */ -void -xterm_seq(int op, const char *str) -{ - - XColor xcol; - char *nstr, *tnstr, *orig_tnstr; - unsigned char eterm_seq_op; - -#if MENUBAR_MAX - char *menu_str; - -#endif -#ifdef PIXMAP_SUPPORT - int changed = 0, scaled = 0; - -#endif - - if (!str) - return; - -#if MENUBAR_MAX - menu_str = strdup(str); -#endif -#ifdef PIXMAP_SUPPORT - orig_tnstr = tnstr = strdup(str); -#endif - - switch (op) { - case XTerm_title: - set_title(str); - break; - case XTerm_name: - set_title(str); /* drop */ - case XTerm_iconName: - set_iconName(str); - break; - case XTerm_Takeover: - XSetInputFocus(Xdisplay, TermWin.parent, RevertToParent, CurrentTime); - XRaiseWindow(Xdisplay, TermWin.parent); - break; -#if MENUBAR_MAX - case XTerm_Menu: - menubar_dispatch(menu_str); - free(menu_str); - break; -#endif - - case XTerm_EtermSeq: - - /* Eterm proprietary escape sequences - - Syntax: ESC ] 6 ; ; BEL - - where is: 0 Set/toggle transparency - 1 Set shade percentage - 2 Set tint mask - 3 Force update of pseudo-transparent background - 4 Set/toggle desktop watching - 10 Set scrollbar type/width - 11 Set/toggle right-side scrollbar - 12 Set/toggle floating scrollbar - 13 Set/toggle popup scrollbar - 15 Set/toggle menubar move - 20 Set/toggle visual bell - 21 Set/toggle map alert - 22 Set/toggle xterm selection behavior - 23 Set/toggle triple-click line selection - 24 Set/toggle viewport mode - 25 Set/toggle selection of trailing spaces - 30 Do not use - 40 Do not use - 50 Move window to another desktop - 70 Exit Eterm - 71 Save current configuration to a file - and is an optional argument, depending - on the particular sequence being used. It - (along with its preceeding semicolon) may or - may not be needed. - */ - - D_EVENTS(("Got XTerm_EtermSeq sequence\n")); - nstr = strsep(&tnstr, ";"); - eterm_seq_op = (unsigned char) strtol(nstr, (char **) NULL, 10); - D_EVENTS((" XTerm_EtermSeq operation is %d\n", eterm_seq_op)); - /* Yes, there is order to the numbers for this stuff. And here it is: - 0-9 Transparency Configuration - 10-14 Scrollbar Configuration - 15-19 Menubar Configuration - 20-29 Miscellaneous Toggles - 30-39 Foreground/Text Color Configuration - 40-49 Background Color Configuration - 50-69 Window/Window Manager Configuration/Interaction - 70-79 Internal Eterm Operations - */ - switch (eterm_seq_op) { -#ifdef PIXMAP_OFFSET - case 0: - nstr = strsep(&tnstr, ";"); - OPT_SET_OR_TOGGLE_NEG(nstr, Options, Opt_pixmapTrans); - if (Options & Opt_pixmapTrans) { - Options &= ~(Opt_pixmapTrans); -# ifdef IMLIB_TRANS - if (imlib_id) { - if (imlib_bg.im != NULL) { - Imlib_kill_image(imlib_id, imlib_bg.im); - imlib_bg.im = NULL; - } - } -#endif - set_bgPixmap(rs_pixmaps[pixmap_bg]); - } else { - Options |= Opt_pixmapTrans; - if (imlib_id) { - ImlibFreePixmap(imlib_id, bgPixmap.pixmap); - if (imlib_bg.im != NULL) { - D_IMLIB(("ImlibDestroyImage()\n")); - ImlibDestroyImage(imlib_id, imlib_bg.im); - imlib_bg.im = NULL; - } - bgPixmap.pixmap = None; - } - TermWin.pixmap = None; - } - render_pixmap(TermWin.vt, imlib_bg, bgPixmap, 0, 1); - scr_touch(); - break; - case 1: - nstr = strsep(&tnstr, ";"); - if (!nstr) { - break; - } - rs_shadePct = strtoul(nstr, (char **) NULL, 0); - D_EVENTS((" XTerm_EtermSeq shade percentage is %d%%\n", rs_shadePct)); - if (Options & Opt_pixmapTrans && desktop_pixmap != None) { - XFreePixmap(Xdisplay, desktop_pixmap); - desktop_pixmap = None; /* Force the re-read */ - } - if (Options & Opt_viewport_mode && viewport_pixmap != None) { - XFreePixmap(Xdisplay, viewport_pixmap); - viewport_pixmap = None; /* Force the re-read */ - } - render_pixmap(TermWin.vt, imlib_bg, bgPixmap, 0, 1); - scr_touch(); - break; - case 2: - nstr = strsep(&tnstr, ";"); - if (!nstr) { - break; - } - if (!BEG_STRCASECMP(nstr, "none")) { - rs_tintMask = 0xffffff; - } else if (!BEG_STRCASECMP(nstr, "red")) { - rs_tintMask = 0xff8080; - } else if (!BEG_STRCASECMP(nstr, "green")) { - rs_tintMask = 0x80ff80; - } else if (!BEG_STRCASECMP(nstr, "blue")) { - rs_tintMask = 0x8080ff; - } else if (!BEG_STRCASECMP(nstr, "cyan")) { - rs_tintMask = 0x80ffff; - } else if (!BEG_STRCASECMP(nstr, "magenta")) { - rs_tintMask = 0xff80ff; - } else if (!BEG_STRCASECMP(nstr, "yellow")) { - rs_tintMask = 0xffff80; - } else { - rs_tintMask = strtoul(nstr, (char **) NULL, 0); - } - D_EVENTS((" XTerm_EtermSeq tint mask is 0x%06x\n", rs_tintMask)); - if (Options & Opt_pixmapTrans && desktop_pixmap != None) { - XFreePixmap(Xdisplay, desktop_pixmap); - desktop_pixmap = None; /* Force the re-read */ - } - if (Options & Opt_viewport_mode && viewport_pixmap != None) { - XFreePixmap(Xdisplay, viewport_pixmap); - viewport_pixmap = None; /* Force the re-read */ - } - render_pixmap(TermWin.vt, imlib_bg, bgPixmap, 0, 1); - scr_touch(); - break; - case 3: - if (Options & Opt_pixmapTrans) { - get_desktop_window(); - if (desktop_pixmap != None) { - XFreePixmap(Xdisplay, desktop_pixmap); - desktop_pixmap = None; /* Force the re-read */ - } - render_pixmap(TermWin.vt, imlib_bg, bgPixmap, 0, 1); - scr_expose(0, 0, TermWin_TotalWidth(), TermWin_TotalHeight()); - } - break; - case 4: - nstr = strsep(&tnstr, ";"); - OPT_SET_OR_TOGGLE(nstr, Options, Opt_watchDesktop); - if (Options & Opt_pixmapTrans) { - get_desktop_window(); - } - break; -#endif - case 10: - nstr = strsep(&tnstr, ";"); - if (nstr && *nstr) { - if (!strcasecmp(nstr, "xterm")) { -#ifdef XTERM_SCROLLBAR - scrollBar.type = SCROLLBAR_XTERM; -#else - print_error("Support for xterm scrollbars was not compiled in. Sorry."); -#endif - } else if (!strcasecmp(nstr, "next")) { -#ifdef NEXT_SCROLLBAR - scrollBar.type = SCROLLBAR_NEXT; -#else - print_error("Support for NeXT scrollbars was not compiled in. Sorry."); -#endif - } else if (!strcasecmp(nstr, "motif")) { -#ifdef MOTIF_SCROLLBAR - scrollBar.type = SCROLLBAR_MOTIF; -#else - print_error("Support for motif scrollbars was not compiled in. Sorry."); -#endif - } else { - print_error("Unrecognized scrollbar type \"%s\".", nstr); - } - scrollbar_reset(); - map_scrollBar(0); - map_scrollBar(1); - scrollbar_show(0); - } - nstr = strsep(&tnstr, ";"); - if (nstr && *nstr) { - scrollBar.width = strtoul(nstr, (char **) NULL, 0); - if (scrollBar.width == 0) { - print_error("Invalid scrollbar length \"%s\".", nstr); - scrollBar.width = SB_WIDTH; - } - scrollbar_reset(); - map_scrollBar(0); - map_scrollBar(1); - scrollbar_show(0); - } - break; - case 11: - nstr = strsep(&tnstr, ";"); - OPT_SET_OR_TOGGLE(nstr, Options, Opt_scrollBar_right); - scrollbar_reset(); - map_scrollBar(0); - map_scrollBar(1); - scrollbar_show(0); - break; - case 12: - nstr = strsep(&tnstr, ";"); - OPT_SET_OR_TOGGLE(nstr, Options, Opt_scrollBar_floating); - scrollbar_reset(); - map_scrollBar(0); - map_scrollBar(1); - scrollbar_show(0); - break; - case 13: - nstr = strsep(&tnstr, ";"); - OPT_SET_OR_TOGGLE(nstr, Options, Opt_scrollbar_popup); - break; - case 15: - nstr = strsep(&tnstr, ";"); - OPT_SET_OR_TOGGLE(nstr, Options, Opt_menubar_move); - break; - case 20: - nstr = strsep(&tnstr, ";"); - OPT_SET_OR_TOGGLE(nstr, Options, Opt_visualBell); - break; -#ifdef MAPALERT_OPTION - case 21: - nstr = strsep(&tnstr, ";"); - OPT_SET_OR_TOGGLE(nstr, Options, Opt_mapAlert); - break; -#endif - case 22: - nstr = strsep(&tnstr, ";"); - OPT_SET_OR_TOGGLE(nstr, Options, Opt_xterm_select); - break; - case 23: - nstr = strsep(&tnstr, ";"); - OPT_SET_OR_TOGGLE(nstr, Options, Opt_select_whole_line); - break; - case 24: - nstr = strsep(&tnstr, ";"); - OPT_SET_OR_TOGGLE(nstr, Options, Opt_viewport_mode); - render_pixmap(TermWin.vt, imlib_bg, bgPixmap, 0, 1); - scr_touch(); - break; - case 25: - nstr = strsep(&tnstr, ";"); - OPT_SET_OR_TOGGLE(nstr, Options, Opt_select_trailing_spaces); - break; - case 30: - nstr = strsep(&tnstr, ";"); - if (nstr) { - if (XParseColor(Xdisplay, Xcmap, nstr, &xcol) && XAllocColor(Xdisplay, Xcmap, &xcol)) { - PixColors[fgColor] = xcol.pixel; - scr_refresh(SMOOTH_REFRESH); - } - } - break; - case 40: - nstr = strsep(&tnstr, ";"); - if (nstr) { - if (XParseColor(Xdisplay, Xcmap, nstr, &xcol) && XAllocColor(Xdisplay, Xcmap, &xcol)) { - PixColors[bgColor] = xcol.pixel; - scr_refresh(SMOOTH_REFRESH); - } - } - break; - case 50: - /* Change desktops */ - nstr = strsep(&tnstr, ";"); - if (nstr && *nstr) { - XClientMessageEvent xev; - - rs_desktop = (int) strtol(nstr, (char **) NULL, 0); - xev.type = ClientMessage; - xev.window = TermWin.parent; - xev.message_type = XInternAtom(Xdisplay, "_WIN_WORKSPACE", False); - xev.format = 32; - xev.data.l[0] = rs_desktop; - XChangeProperty(Xdisplay, TermWin.parent, xev.message_type, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &rs_desktop, 1); - XSendEvent(Xdisplay, Xroot, False, SubstructureNotifyMask, (XEvent *) & xev); - } - break; - case 70: - /* Exit Eterm */ - exit(0); - break; - case 71: - /* Save current config */ - nstr = strsep(&tnstr, ";"); - if (nstr && *nstr) { - save_config(nstr); - } else { - save_config(NULL); - } - break; - - default: - break; - } - break; - - case XTerm_Pixmap: -#ifdef PIXMAP_SUPPORT -# ifdef PIXMAP_OFFSET - if (Options & Opt_pixmapTrans) { - Options &= ~(Opt_pixmapTrans); - } -# endif - rs_shadePct = 0; - rs_tintMask = 0xffffff; - if (!strcmp(str, ";")) { - rs_pixmaps[pixmap_bg] = ""; - set_bgPixmap(""); - return; - } - nstr = strsep(&tnstr, ";"); - if (nstr) { - if (*nstr) { - scale_pixmap("", &bgPixmap); - D_PIXMAP(("set_bgPixmap() call #2\n")); - bg_needs_update = 1; - set_bgPixmap(nstr); - } - while ((nstr = strsep(&tnstr, ";")) && *nstr) { - changed += scale_pixmap(nstr, &bgPixmap); - scaled = 1; - } - /* FIXME: This used to be && instead of || to avoid unnecessary - * rendering under some circumstances... I'll try to look - * deeper :) -vendu - */ - if ((changed) || (bg_needs_update)) { - D_PIXMAP(("XTerm_Pixmap sequence: render_pixmap(TermWin.vt)\n")); - render_pixmap(TermWin.vt, imlib_bg, bgPixmap, 0, 1); - scr_touch(); - } - } else { - D_PIXMAP(("set_bgPixmap() call #3\n")); - set_bgPixmap(""); - } -#endif /* PIXMAP_SUPPORT */ - break; - - case XTerm_restoreFG: - set_window_color(fgColor, str); - break; - case XTerm_restoreBG: - set_window_color(bgColor, str); - break; - case XTerm_logfile: - break; - case XTerm_font: - change_font(0, str); - break; -#ifdef ETERM_COMMAND_MODE - case ETerm_command_mode: - fprintf(stderr, "ETerm_command_mode\n"); - break; -#endif - default: - D_CMD(("Unsupported xterm escape sequence operator: 0x%02x\n", op)); - break; - } -#ifdef PIXMAP_SUPPORT - free(orig_tnstr); -#endif -} - -/* change_font() - Switch to a new font */ -/* - * init = 1 - initialize - * - * fontname == FONT_UP - switch to bigger font - * fontname == FONT_DN - switch to smaller font - */ -#define ABORT() do { print_error("aborting"); exit(EXIT_FAILURE); } while (0) -void -change_font(int init, const char *fontname) -{ - const char *const msg = "can't load font \"%s\""; - XFontStruct *xfont; - static char *newfont[NFONTS]; - -#ifndef NO_BOLDFONT - static XFontStruct *boldFont = NULL; - -#endif - static int fnum = FONT0_IDX; /* logical font number */ - int idx = 0; /* index into rs_font[] */ - -#if (FONT0_IDX == 0) -# define IDX2FNUM(i) (i) -# define FNUM2IDX(f) (f) -#else -# define IDX2FNUM(i) (i == 0? FONT0_IDX : (i <= FONT0_IDX? (i-1) : i)) -# define FNUM2IDX(f) (f == FONT0_IDX ? 0 : (f < FONT0_IDX ? (f+1) : f)) -#endif -#define FNUM_RANGE(i) (i <= 0 ? 0 : (i >= NFONTS ? (NFONTS-1) : i)) - - if (!init) { - switch (fontname[0]) { - case '\0': - fnum = FONT0_IDX; - fontname = NULL; - break; - - /* special (internal) prefix for font commands */ - case FONT_CMD: - idx = atoi(fontname + 1); - switch (fontname[1]) { - case '+': /* corresponds to FONT_UP */ - fnum += (idx ? idx : 1); - fnum = FNUM_RANGE(fnum); - break; - - case '-': /* corresponds to FONT_DN */ - fnum += (idx ? idx : -1); - fnum = FNUM_RANGE(fnum); - break; - - default: - if (fontname[1] != '\0' && !isdigit(fontname[1])) - return; - if (idx < 0 || idx >= (NFONTS)) - return; - fnum = IDX2FNUM(idx); - break; - } - fontname = NULL; - break; - - default: - if (fontname != NULL) { - /* search for existing fontname */ - for (idx = 0; idx < NFONTS; idx++) { - if (!strcmp(rs_font[idx], fontname)) { - fnum = IDX2FNUM(idx); - fontname = NULL; - break; - } - } - } else - return; - break; - } - /* re-position around the normal font */ - idx = FNUM2IDX(fnum); - - if (fontname != NULL) { - char *name; - - xfont = XLoadQueryFont(Xdisplay, fontname); - if (!xfont) - return; - - name = MALLOC(strlen(fontname + 1) * sizeof(char)); - - if (name == NULL) { - XFreeFont(Xdisplay, xfont); - return; - } - strcpy(name, fontname); - if (newfont[idx] != NULL) - FREE(newfont[idx]); - newfont[idx] = name; - rs_font[idx] = newfont[idx]; - } - } - if (TermWin.font) - XFreeFont(Xdisplay, TermWin.font); - - /* load font or substitute */ - xfont = XLoadQueryFont(Xdisplay, rs_font[idx]); - if (!xfont) { - print_error(msg, rs_font[idx]); - rs_font[idx] = "fixed"; - xfont = XLoadQueryFont(Xdisplay, rs_font[idx]); - if (!xfont) { - print_error(msg, rs_font[idx]); - ABORT(); - } - } - TermWin.font = xfont; - -#ifndef NO_BOLDFONT - /* fail silently */ - if (init && rs_boldFont != NULL) - boldFont = XLoadQueryFont(Xdisplay, rs_boldFont); -#endif - -#ifdef KANJI - if (TermWin.kanji) - XFreeFont(Xdisplay, TermWin.kanji); - - /* load font or substitute */ - xfont = XLoadQueryFont(Xdisplay, rs_kfont[idx]); - if (!xfont) { - print_error(msg, rs_kfont[idx]); - rs_kfont[idx] = "k14"; - xfont = XLoadQueryFont(Xdisplay, rs_kfont[idx]); - if (!xfont) { - print_error(msg, rs_kfont[idx]); - ABORT(); - } - } - TermWin.kanji = xfont; -#endif /* KANJI */ - - /* alter existing GC */ - if (!init) { - XSetFont(Xdisplay, TermWin.gc, TermWin.font->fid); -#if (MENUBAR_MAX) - menubar_expose(); -#endif /* MENUBAR_MAX */ - } - /* set the sizes */ - { - - int i, cw, fh, fw = 0; - - fw = TermWin.font->min_bounds.width; - fh = TermWin.font->ascent + TermWin.font->descent; - - D_X11(("Font information: Ascent == %hd, Descent == %hd\n", TermWin.font->ascent, TermWin.font->descent)); - if (TermWin.font->min_bounds.width == TermWin.font->max_bounds.width) - TermWin.fprop = 0; /* Mono-spaced (fixed width) font */ - else - TermWin.fprop = 1; /* Proportional font */ - if (TermWin.fprop == 1) - for (i = TermWin.font->min_char_or_byte2; - i <= TermWin.font->max_char_or_byte2; i++) { - cw = TermWin.font->per_char[i].width; - MAX_IT(fw, cw); - } - /* not the first time thru and sizes haven't changed */ - if (fw == TermWin.fwidth && fh == TermWin.fheight) - return; /* TODO: not return; check KANJI if needed */ - - TermWin.fwidth = fw; - TermWin.fheight = fh; - } - - /* check that size of boldFont is okay */ -#ifndef NO_BOLDFONT - TermWin.boldFont = NULL; - if (boldFont != NULL) { - int i, cw, fh, fw = 0; - - fw = boldFont->min_bounds.width; - fh = boldFont->ascent + boldFont->descent; - if (TermWin.fprop == 0) { /* bold font must also be monospaced */ - if (fw != boldFont->max_bounds.width) - fw = -1; - } else { - for (i = 0; i < 256; i++) { - if (!isprint(i)) - continue; - cw = boldFont->per_char[i].width; - MAX_IT(fw, cw); - } - } - - if (fw == TermWin.fwidth && fh == TermWin.fheight) - TermWin.boldFont = boldFont; - } -#endif /* NO_BOLDFONT */ - - set_colorfgbg(); - - TermWin.width = TermWin.ncol * TermWin.fwidth; - TermWin.height = TermWin.nrow * TermWin.fheight; - - szHint.width_inc = TermWin.fwidth; - szHint.height_inc = TermWin.fheight; - - szHint.min_width = szHint.base_width + szHint.width_inc; - szHint.min_height = szHint.base_height + szHint.height_inc; - - szHint.width = szHint.base_width + TermWin.width; - szHint.height = szHint.base_height + TermWin.height; -#if (MENUBAR_MAX) - szHint.height += (delay_menu_drawing ? menuBar_TotalHeight() : 0); -#endif - - szHint.flags = PMinSize | PResizeInc | PBaseSize | PWinGravity; - - if (!init) { - font_change_count++; - resize(); - } - return; -#undef IDX2FNUM -#undef FNUM2IDX -#undef FNUM_RANGE -} diff --git a/src/command.h b/src/command.h index bd5567f..339bb20 100644 --- a/src/command.h +++ b/src/command.h @@ -19,16 +19,40 @@ *----------------------------------------------------------------------*/ #ifndef _COMMAND_H_ # define _COMMAND_H_ +# include +# include # include # include # include -# include -# include +# include -# ifdef USE_ACTIVE_TAGS -# include "activetags.h" +# ifdef NO_XLOCALE +# include +# else +# ifndef X_LOCALE +# define X_LOCALE +# endif +# include # endif +# include "options.h" +# include "system.h" /* For RETSIGTYPE */ + +/************ Macros and Definitions ************/ +#if !defined(SIGSYS) +# if defined(SIGUNUSED) +# define SIGSYS SIGUNUSED +# else +# define SIGSYS ((int) 0) +# endif +#endif + +#ifdef OFFIX_DND +# define DndFile 2 +# define DndDir 5 +# define DndLink 7 +#endif + # define menuBar_esc 10 # define scrollBar_esc 30 @@ -37,7 +61,6 @@ #define MWM_HINTS_DECORATIONS (1L << 1) #define MWM_HINTS_INPUT_MODE (1L << 2) #define MWM_HINTS_STATUS (1L << 3) - /* bit definitions for MwmHints.functions */ #define MWM_FUNC_ALL (1L << 0) #define MWM_FUNC_RESIZE (1L << 1) @@ -45,7 +68,6 @@ #define MWM_FUNC_MINIMIZE (1L << 3) #define MWM_FUNC_MAXIMIZE (1L << 4) #define MWM_FUNC_CLOSE (1L << 5) - /* bit definitions for MwmHints.decorations */ #define MWM_DECOR_ALL (1L << 0) #define MWM_DECOR_BORDER (1L << 1) @@ -54,24 +76,13 @@ #define MWM_DECOR_MENU (1L << 4) #define MWM_DECOR_MINIMIZE (1L << 5) #define MWM_DECOR_MAXIMIZE (1L << 6) - /* bit definitions for MwmHints.inputMode */ #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 PROP_MWM_HINTS_ELEMENTS 5 -/* Motif window hints */ -typedef struct _mwmhints { - CARD32 flags; - CARD32 functions; - CARD32 decorations; - INT32 input_mode; - CARD32 status; -} MWMHints; - /* DEC private modes */ # define PrivMode_132 (1LU<<0) # define PrivMode_132OK (1LU<<1) @@ -97,26 +108,281 @@ if (test) PrivateModes |= (bit); else PrivateModes &= ~(bit);} while (0) #define PrivMode_Default (PrivMode_Autowrap|PrivMode_ShiftKeys|PrivMode_VisibleCursor) +#ifdef HAVE_TERMIOS_H +# ifdef TCSANOW /* POSIX */ +# define GET_TERMIOS(fd,tios) tcgetattr(fd, tios) +# define SET_TERMIOS(fd,tios) do {cfsetospeed(tios, BAUDRATE); cfsetispeed(tios, BAUDRATE); tcsetattr(fd, TCSANOW, tios); } while (0) +# else +# ifdef TIOCSETA +# define GET_TERMIOS(fd,tios) ioctl (fd, TIOCGETA, tios) +# define SET_TERMIOS(fd,tios) do {tios->c_cflag |= BAUDRATE; ioctl(fd, TIOCSETA, tios); } while (0) +# else +# define GET_TERMIOS(fd,tios) ioctl (fd, TCGETS, tios) +# define SET_TERMIOS(fd,tios) do {tios->c_cflag |= BAUDRATE; ioctl(fd, TCSETS, tios); } while (0) +# endif +# endif +# define SET_TTYMODE(fd,tios) SET_TERMIOS(fd, tios) +#else +# define SET_TTYMODE(fd,tt) do {tt->sg.sg_ispeed = tt->sg.sg_ospeed = BAUDRATE; ioctl(fd, TIOCSETP, &(tt->sg)); ioctl(fd, TIOCSETC, &(tt->tc)); \ + ioctl(fd, TIOCSLTC, &(tt->lc)); ioctl(fd, TIOCSETD, &(tt->line)); ioctl(fd, TIOCLSET, &(tt->local)); \ + } while (0) +#endif /* HAVE_TERMIOS_H */ + +#ifdef B38400 +# define BAUDRATE B38400 +#else +# ifdef B19200 +# define BAUDRATE B19200 +# else +# define BAUDRATE B9600 +# endif +#endif + +/* Disable special character functions */ +#ifdef _POSIX_VDISABLE +# define VDISABLE _POSIX_VDISABLE +#else +# define VDISABLE 255 +#endif + +/* system default characters if defined and reasonable */ +#ifndef CINTR +# define CINTR '\003' /* ^C */ +#endif +#ifndef CQUIT +# define CQUIT '\034' /* ^\ */ +#endif +#ifndef CERASE +# ifdef linux +# define CERASE '\177' /* ^? */ +# else +# define CERASE '\010' /* ^H */ +# endif +#endif +#ifndef CKILL +# define CKILL '\025' /* ^U */ +#endif +#ifndef CEOF +# define CEOF '\004' /* ^D */ +#endif +#ifndef CSTART +# define CSTART '\021' /* ^Q */ +#endif +#ifndef CSTOP +# define CSTOP '\023' /* ^S */ +#endif +#ifndef CSUSP +# define CSUSP '\032' /* ^Z */ +#endif +#ifndef CDSUSP +# define CDSUSP '\031' /* ^Y */ +#endif +#ifndef CRPRNT +# define CRPRNT '\022' /* ^R */ +#endif +#ifndef CFLUSH +# define CFLUSH '\017' /* ^O */ +#endif +#ifndef CWERASE +# define CWERASE '\027' /* ^W */ +#endif +#ifndef CLNEXT +# define CLNEXT '\026' /* ^V */ +#endif +#ifndef VDISCRD +# ifdef VDISCARD +# define VDISCRD VDISCARD +# endif +#endif +#ifndef VWERSE +# ifdef VWERASE +# define VWERSE VWERASE +# endif +#endif + +#define KBUFSZ 12 /* size of keyboard mapping buffer */ +#define STRING_MAX 512 /* max string size for process_xterm_seq() */ +#define ESC_ARGS 32 /* max # of args for esc sequences */ + +/* a large REFRESH_PERIOD causes problems with `cat' */ +#ifndef REFRESH_PERIOD +# define REFRESH_PERIOD 3 +#endif + +#ifndef MULTICLICK_TIME +# define MULTICLICK_TIME 500 +#endif +#ifndef SCROLLBAR_INITIAL_DELAY +# define SCROLLBAR_INITIAL_DELAY 40 +#endif +#ifndef SCROLLBAR_CONTINUOUS_DELAY +# define SCROLLBAR_CONTINUOUS_DELAY 2 +#endif + +/* time factor to slow down a `jumpy' mouse */ +#define MOUSE_THRESHOLD 50 +#define CONSOLE "/dev/console" /* console device */ + +/* key-strings: if only these keys were standardized */ +#ifdef LINUX_KEYS +# define KS_HOME "\033[1~" /* Home == Find */ +# define KS_END "\033[4~" /* End == Select */ +#else +# define KS_HOME "\033[7~" /* Home */ +# define KS_END "\033[8~" /* End */ +#endif +#ifdef NO_DELETE_KEY +# undef KS_DELETE /* use X server definition */ +#else +# ifndef KS_DELETE +# define KS_DELETE "\033[3~" /* Delete = Execute */ +# endif +#endif + +#define VT100_ANS "\033[?1;2c" /* vt100 answerback */ +#ifndef ESCZ_ANSWER +# define ESCZ_ANSWER VT100_ANS /* obsolete ANSI ESC[c */ +#endif + +#if defined(linux) && defined(N_TTY_BUF_SIZE) +# define CMD_BUF_SIZE N_TTY_BUF_SIZE +#else +# ifndef CMD_BUF_SIZE +# define CMD_BUF_SIZE 4096 +# endif +#endif + +#if !defined(EACCESS) && defined(EAGAIN) +# define EACCESS EAGAIN +#endif + +#define PTYCHAR1 "pqrstuvwxyz" +#define PTYCHAR2 "0123456789abcdefghijklmnopqrstuvwxyz" + +#ifdef BACKGROUND_CYCLING_SUPPORT +# if RETSIGTYPE != void +# define CPC_RETURN(x) return ((RETSIGTYPE) x) +# else +# define CPC_RETURN(x) return +# endif +#endif + +#define CHARS_READ() (cmdbuf_ptr < cmdbuf_endp) +#define CHARS_BUFFERED() (count != CMD_BUF_SIZE) +#define RETURN_CHAR() do { refreshed = 0; return (*cmdbuf_ptr++); } while (0) + +#ifdef REFRESH_DELAY +# define REFRESH_DELAY_USEC (1000000/25) +#endif + +#if defined(linux) +# ifdef PTY_BUF_SIZE /* From */ +# define MAX_PTY_WRITE PTY_BUF_SIZE +# endif +#endif + +/* NOTE: _POSIX_MAX_INPUT is defined _through_ at least for + * the following systems: HP-UX 10.20, AIX (no idea about the version), + * OSF1/alpha 4.0, Linux (probably any Linux system). + */ +#ifndef MAX_PTY_WRITE +# ifdef _POSIX_VERSION +# ifdef _POSIX_MAX_INPUT +# define MAX_PTY_WRITE _POSIX_MAX_INPUT +# else +# define MAX_PTY_WRITE 255 /* POSIX minimum MAX_INPUT */ +# endif +# endif +#endif + +#ifndef MAX_PTY_WRITE +# define MAX_PTY_WRITE 128 /* 1/2 POSIX minimum MAX_INPUT */ +#endif + +/************ Structures ************/ +/* Motif window hints */ +typedef struct _mwmhints { + CARD32 flags; + CARD32 functions; + CARD32 decorations; + INT32 input_mode; + CARD32 status; +} MWMHints; +# ifdef HAVE_TERMIOS_H +typedef struct termios ttymode_t; +# else +typedef struct { /* sgtty interface */ + struct sgttyb sg; + struct tchars tc; + struct ltchars lc; + int line; + int local; +} ttymode_t; +# endif + +/************ Variables ************/ +extern int my_ruid, my_rgid, my_euid, my_egid; extern char initial_dir[PATH_MAX+1]; extern unsigned long PrivateModes; +extern Atom wmDeleteWindow; +extern int refresh_count, refresh_limit, refresh_type; +#ifdef USE_POSIX_THREADS +extern static void **retval; +extern static int join_value; +extern static pthread_t main_loop_thr; +extern static pthread_attr_t main_loop_attr; +# ifdef MUTEX_SYNCH +extern pthread_mutex_t mutex; +# endif +#endif +#ifdef USE_XIM +extern XIC Input_Context; /* input context */ +#endif +/************ Function Prototypes ************/ _XFUNCPROTOBEGIN -# ifdef USE_ACTIVE_TAGS -pid_t cmd_pid; -int cmd_fd; -# endif +#ifdef HAVE_U_STACK_TRACE +extern void U_STACK_TRACE(void); +#endif +extern char *ptsname(); +extern void privileges(int); +extern char *sig_to_str(int); +extern const char *event_type_to_name(int); +extern const char *request_code_to_name(int); +extern void dump_stack_trace(void); +extern RETSIGTYPE Child_signal(int); +extern RETSIGTYPE Exit_signal(int); +extern void clean_exit(void); +extern int get_pty(void); +extern int get_tty(void); +extern XFontSet create_fontset(const char *, const char *); +#if defined(USE_XIM) || defined(MULTI_CHARSET) +extern void xim_set_status_position(void); +extern void xim_get_position(XPoint *pos); +extern void xim_set_fontset(void); +extern void init_locale(void); +#else +# define init_locale() ((void)0) +#endif +extern int run_command(char **); extern void init_command(char **); +extern void tt_winsize(int); extern void tt_resize(void); +extern unsigned int cmd_write(const unsigned char *, unsigned int); +#ifdef BACKGROUND_CYCLING_SUPPORT +extern RETSIGTYPE check_pixmap_change(int); +#endif +extern unsigned char cmd_getc(void); extern void tt_write(const unsigned char *, unsigned int); extern void tt_printf(const unsigned char *, ...); -extern unsigned int cmd_write(const unsigned char *, unsigned int); extern void main_loop(void); -extern FILE *popen_printer(void); -extern int pclose_printer(FILE *); -extern void color_aliases (int idx); +extern int v_doPending(void); +extern void v_writeBig(int, char *, int); +#ifdef DISPLAY_IS_IP +extern char *network_display(const char *); +#endif _XFUNCPROTOEND #endif /* _COMMAND_H_ */ -/*----------------------- end-of-file (C header) -----------------------*/ diff --git a/src/debug.h b/src/debug.h index bc576c3..286fc7b 100644 --- a/src/debug.h +++ b/src/debug.h @@ -5,29 +5,43 @@ #ifndef _DEBUG_H # define _DEBUG_H +#include + extern unsigned int debug_level; /* Assert macros stolen from my work on Ebar. If these macros break with your cpp, let me know -- mej@eterm.org */ -# define NOP ((void)0) +# define NOP ((void)0) #if defined(__FILE__) && defined(__LINE__) -# define ASSERT(x) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \ - else {print_warning("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);}}} while (0); -#else -# define ASSERT(x) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed: %s", #x);} \ - else {print_warning("ASSERT failed: %s", #x);}}} while (0); +# ifdef __FUNCTION__ +# define __DEBUG() fprintf(stderr, "[debug] %12s | %4d | %30s: ", __FILE__, __LINE__, __FUNCTION__) +# else +# define __DEBUG() fprintf(stderr, "[debug] %12s | %4d: ", __FILE__, __LINE__) +# endif #endif -#ifdef __FILE__ -#ifdef __LINE__ -#define __DEBUG() fprintf(stderr, "%s, line %d: ", __FILE__, __LINE__); -#endif +#if defined(__FILE__) && defined(__LINE__) +# define ASSERT(x) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \ + else {print_warning("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);}}} while (0) +# define ASSERT_RVAL(x, val) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \ + else {print_warning("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \ + return (val);}} while (0) +# define ABORT() fatal_error("Aborting at %s:%d.", __FILE__, __LINE__) +#else +# define ASSERT(x) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed: %s", #x);} \ + else {print_warning("ASSERT failed: %s", #x);}}} while (0) +# define ASSERT_RVAL(x, val) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed: %s", #x);} \ + else {print_warning("ASSERT failed: %s", #x);} return (val);}} while (0) +# define ABORT() fatal_error("Aborting.") #endif #ifndef __DEBUG -#define __DEBUG() NOP +# define __DEBUG() NOP #endif +#define REQUIRE(x) do {if (!(x)) {if (debug_level>=1) {__DEBUG(); real_dprintf("REQUIRE failed: %s\n", #x);} return;}} while (0) +#define REQUIRE_RVAL(x, v) do {if (!(x)) {if (debug_level>=1) {__DEBUG(); real_dprintf("REQUIRE failed: %s\n", #x);} return (v);}} while (0) + /* Macros for printing debugging messages */ # if DEBUG >= 1 # ifndef DPRINTF @@ -49,6 +63,9 @@ extern unsigned int debug_level; # define DPRINTF5(x) NOP # endif +/* Use this for stuff that you only want turned on in dire situations */ +# define D_NEVER(x) NOP + /* Debugging macros/defines which set the debugging levels for each output type. To change the debugging level at which something appears, change the number in both the DEBUG_ definition and the D_ macro (if there is one). -- mej */ @@ -71,20 +88,20 @@ extern unsigned int debug_level; # define D_PIXMAP(x) DPRINTF1(x) # define DEBUG_EVENTS 1 # define D_EVENTS(x) DPRINTF1(x) -# define DEBUG_STRINGS 1 -# define D_STRINGS(x) DPRINTF1(x) # define DEBUG_X11 2 # define D_X11(x) DPRINTF2(x) +# define DEBUG_ENL 2 +# define D_ENL(x) DPRINTF2(x) # define DEBUG_SCROLLBAR 2 # define D_SCROLLBAR(x) DPRINTF2(x) # define DEBUG_THREADS 2 # define D_THREADS(x) DPRINTF2(x) -# define DEBUG_TAGS 2 -# define D_TAGS(x) DPRINTF2(x) +# define DEBUG_TIMER 2 +# define D_TIMER(x) DPRINTF2(x) # define DEBUG_MENU 3 -# define D_MENUBAR(x) DPRINTF3(x) +# define D_MENU(x) DPRINTF3(x) # define DEBUG_TTYMODE 3 # define D_TTYMODE(x) DPRINTF3(x) # define DEBUG_COLORS 3 @@ -92,14 +109,58 @@ extern unsigned int debug_level; # define DEBUG_MALLOC 4 # define D_MALLOC(x) DPRINTF4(x) -# define DEBUG_MENUARROWS 4 -# define D_MENUARROWS(x) DPRINTF4(x) -# define DEBUG_MENU_LAYOUT 4 -# define D_MENU_LAYOUT(x) DPRINTF4(x) -# define DEBUG_MENUBAR_STACKING 4 -# define D_MENUBAR_STACKING(x) DPRINTF4(x) - +# define DEBUG_ACTIONS 4 +# define D_ACTIONS(x) DPRINTF4(x) + # define DEBUG_X 5 +# define DEBUG_PARSE 9999 +# define D_PARSE(x) D_NEVER(x) +# define DEBUG_STRINGS 9999 +# define D_STRINGS(x) D_NEVER(x) + +#if (SIZEOF_LONG == 8) +# define MEMSET_LONG() l |= l<<32 +#else +# define MEMSET_LONG() ((void)0) +#endif + +#define MEMSET(s, c, count) do { \ + char *end = (char *)(s) + (count); \ + long l; \ + long *l_dest = (long *)(s); \ + char *c_dest; \ + \ + /* areas of less than 4 * sizeof(long) are set in 1-byte chunks. */ \ + if ((count) >= 4 * sizeof(long)) { \ + /* fill l with c. */ \ + l = (c) | (c)<<8; \ + l |= l<<16; \ + MEMSET_LONG(); \ + \ + /* fill in 1-byte chunks until boundary of long is reached. */ \ + if ((unsigned long)l_dest & (unsigned long)(sizeof(long) -1)) { \ + c_dest = (char *)l_dest; \ + while ((unsigned long)c_dest & (unsigned long)(sizeof(long) -1)) { \ + *(c_dest++) = (c); \ + } \ + l_dest = (long *)c_dest; \ + } \ + \ + /* fill in long-size chunks as long as possible. */ \ + while (((unsigned long) (end - (char *)l_dest)) >= sizeof(long)) { \ + *(l_dest++) = l; \ + } \ + } \ + \ + /* fill the tail in 1-byte chunks. */ \ + if ((char *)l_dest < end) { \ + c_dest = (char *)l_dest; \ + *(c_dest++) = (c); \ + while (c_dest < end) { \ + *(c_dest++) = (c); \ + } \ + } \ + } while (0) #endif /* _DEBUG_H */ diff --git a/src/e.c b/src/e.c new file mode 100644 index 0000000..139dbe6 --- /dev/null +++ b/src/e.c @@ -0,0 +1,321 @@ +/* e.c -- Eterm Enlightenment support + + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +static const char cvs_ident[] = "$Id$"; + +#include "config.h" +#include "feature.h" + +#include +#include +#include +#include +#include + +#include "../libmej/debug.h" +#include "../libmej/mem.h" +#include "../libmej/strings.h" +#include "debug.h" +#include "e.h" +#include "command.h" +#include "main.h" +#include "options.h" +#include "pixmap.h" + +Window ipc_win = None; +Atom ipc_atom = None; + +/* Returns true if running under E, false otherwise */ +unsigned char +check_for_enlightenment(void) +{ + static char have_e = -1; + + if (have_e == -1) { + if (XInternAtom(Xdisplay, "ENLIGHTENMENT_COMMS", True) != None) { + D_X11(("Enlightenment detected.\n")); + have_e = 1; + } else { + D_X11(("Enlightenment not detected.\n")); + have_e = 0; + } + } + return (have_e); +} + +Window +enl_ipc_get_win(void) +{ + + unsigned char *str = NULL; + Atom prop, prop2; + unsigned long num, after; + int format; + Window dummy_win; + int dummy_int; + unsigned int dummy_uint; + + prop = XInternAtom(Xdisplay, "ENLIGHTENMENT_COMMS", True); + if (prop == None) { + return None; + } + XGetWindowProperty(Xdisplay, Xroot, prop, 0, 14, False, AnyPropertyType, &prop2, &format, &num, &after, &str); + if (str) { + sscanf((char *) str, "%*s %x", (unsigned int *) &ipc_win); + XFree(str); + } + if (ipc_win != None) { + if (!XGetGeometry(Xdisplay, ipc_win, &dummy_win, &dummy_int, &dummy_int, &dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint)) { + ipc_win = None; + } + str = NULL; + if (ipc_win != None) { + XGetWindowProperty(Xdisplay, ipc_win, prop, 0, 14, False, AnyPropertyType, &prop2, &format, &num, &after, &str); + if (str) { + XFree(str); + } else { + ipc_win = None; + } + } + } + if (ipc_win != None) { + XSelectInput(Xdisplay, ipc_win, StructureNotifyMask | SubstructureNotifyMask); + enl_ipc_send("set clientname " APL_NAME); + enl_ipc_send("set version " VERSION); + enl_ipc_send("set email mej@eterm.org"); + enl_ipc_send("set web http://www.eterm.org/"); + enl_ipc_send("set info Eterm Enlightened Terminal Emulator"); + } + return (ipc_win); +} + +void +enl_ipc_send(char *str) +{ + + char buff[21]; + register unsigned short i; + register unsigned char j; + unsigned short len; + XEvent ev; + + ASSERT(str != NULL); + + if (ipc_win == None) { + if ((ipc_win = enl_ipc_get_win()) == None) { + return; + } + } + len = strlen(str); + ipc_atom = XInternAtom(Xdisplay, "ENL_MSG", True); + if (ipc_atom == None) { + D_ENL(("enl_ipc_send(): IPC error: ENL_MSG atom does not exist.\n")); + return; + } + ev.xclient.type = ClientMessage; + ev.xclient.serial = 0; + ev.xclient.send_event = True; + ev.xclient.window = ipc_win; + ev.xclient.message_type = ipc_atom; + ev.xclient.format = 8; + + for (i = 0; i < len + 1; i += 12) { + sprintf(buff, "%8x", (int) TermWin.parent); + for (j = 0; j < 12; j++) { + buff[8 + j] = str[i + j]; + if (!str[i + j]) { + break; + } + } + buff[20] = 0; + for (j = 0; j < 20; j++) { + ev.xclient.data.b[j] = buff[j]; + } + XSendEvent(Xdisplay, ipc_win, False, 0, (XEvent *) & ev); + } +} + +char * +enl_wait_for_reply(void) +{ + + XEvent ev; + static char msg_buffer[20]; + register unsigned char i; + + for (; !XCheckTypedWindowEvent(Xdisplay, TermWin.parent, ClientMessage, &ev);); + for (i = 0; i < 20; i++) { + msg_buffer[i] = ev.xclient.data.b[i]; + } + return (msg_buffer + 8); +} + +char * +enl_ipc_get(const char *msg_data) +{ + + static char *message = NULL; + static unsigned short len = 0; + char buff[13], *ret_msg = NULL; + register unsigned char i; + unsigned char blen; + + for (i = 0; i < 12; i++) { + buff[i] = msg_data[i]; + } + buff[12] = 0; + blen = strlen(buff); + if (message != NULL) { + len += blen; + message = (char *) REALLOC(message, len + 1); + strcat(message, buff); + } else { + len = blen; + message = (char *) MALLOC(len + 1); + strcpy(message, buff); + } + if (blen < 12) { + ret_msg = message; + message = NULL; + D_ENL(("enl_ipc_get(): Received complete reply: \"%s\"\n", ret_msg)); + } + return (ret_msg); +} + +void +enl_query_for_image(unsigned char type) +{ + + char query[255], *filename; + + snprintf(query, sizeof(query), "insert correct IPC command here"); + enl_ipc_send(""); + for (; !(filename = enl_ipc_get(enl_wait_for_reply()));); + /* Extract filename */ + load_image(filename, type); +} + +void +eterm_ipc_parse(char *str) +{ + + char *params; + + ASSERT(str != NULL); + + params = strchr(str, ':'); + if (params) { + *params++ = 0; /* Nuke the colon */ + } + if (!strcasecmp(str, "echo") || !strcasecmp(str, "tty_write")) { + if (params) { + tt_write(params, strlen(params)); + } else { + print_error("IPC Error: Invalid syntax in command \"%s\"", str); + } + } else if (!strcasecmp(str, "parse")) { + if (params) { + cmd_write(params, strlen(params)); + } else { + print_error("IPC Error: Invalid syntax in command \"%s\"", str); + } + } else if (!strcasecmp(str, "enl_send")) { + if (params) { + enl_ipc_send(params); + } else { + print_error("IPC Error: Invalid syntax in command \"%s\"", str); + } + } else if (!strcasecmp(str, "enl_query")) { + if (params) { + char *reply, header[512]; + + enl_ipc_send(params); + for (; !(reply = enl_ipc_get(enl_wait_for_reply()));); + snprintf(header, sizeof(header), "Enlightenment IPC Reply to \"%s\":\n\n", params); + tt_write(header, strlen(header)); + tt_write(reply, strlen(reply)); + tt_write("\n", 1); + FREE(reply); + } else { + print_error("IPC Error: Invalid syntax in command \"%s\"", str); + } + } else if (!strcasecmp(str, "winop")) { + if (params) { + eterm_handle_winop(params); + } else { + print_error("IPC Error: Invalid syntax in command \"%s\"", str); + } + } else if (!strcasecmp(str, "exit")) { + exit(0); + } else { + print_error("IPC Error: Unrecognized command \"%s\"", str); + } +} + +void +eterm_ipc_send(char *str) +{ + +} + +char * +eterm_ipc_get(void) +{ + + return (NULL); +} + +void +eterm_handle_winop(char *action) +{ + + char *winid; + Window win = 0; + + ASSERT(action != NULL); + + winid = strchr(action, ' '); + if (winid) { + win = (Window) strtoul(winid + 1, (char **) NULL, 0); + } + if (win == 0) { /* If no window ID was given, or if the strtoul() call failed */ + win = TermWin.parent; + } + if (!BEG_STRCASECMP(action, "raise")) { + XRaiseWindow(Xdisplay, win); + } else if (!BEG_STRCASECMP(action, "lower")) { + XLowerWindow(Xdisplay, win); + } else if (!BEG_STRCASECMP(action, "map")) { + XMapWindow(Xdisplay, win); + } else if (!BEG_STRCASECMP(action, "unmap")) { + XUnmapWindow(Xdisplay, win); + } else if (!BEG_STRCASECMP(action, "kill")) { + XKillClient(Xdisplay, win); + } else if (!BEG_STRCASECMP(action, "iconify")) { + XIconifyWindow(Xdisplay, win, Xscreen); + } else { + print_error("IPC Error: Unrecognized window operation \"%s\"", action); + } +} diff --git a/src/e.h b/src/e.h new file mode 100644 index 0000000..019e896 --- /dev/null +++ b/src/e.h @@ -0,0 +1,56 @@ +/* e.h -- Eterm Enlightenment support module header file + * -- 6 June 1999, mej + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _E_H_ +#define _E_H_ +/* includes */ +#include +#include /* Xlib, Xutil, Xresource, Xfuncproto */ +#include "pixmap.h" /* For simage_t */ + +/************ Macros and Definitions ************/ + +/************ Variables ************/ +extern Window ipc_win; +extern Atom ipc_atom; + +/************ Function Prototypes ************/ +_XFUNCPROTOBEGIN + +extern unsigned char check_for_enlightenment(void); +extern Window enl_ipc_get_win(void); +extern void enl_ipc_send(char *); +extern char *enl_wait_for_reply(void); +extern char *enl_ipc_get(const char *); +extern void enl_query_for_image(unsigned char); +extern void eterm_ipc_parse(char *); +extern void eterm_ipc_send(char *); +extern char *eterm_ipc_get(void); +extern void eterm_handle_winop(char *); + +_XFUNCPROTOEND + +#endif /* _E_H_ */ diff --git a/src/eterm_imlib.h b/src/eterm_imlib.h deleted file mode 100644 index 06637e4..0000000 --- a/src/eterm_imlib.h +++ /dev/null @@ -1,26 +0,0 @@ -/* eterm_imlib.h - An include file for porting Eterm to use Imlib 1.0 - * in addition to Imlib 0.x. - * Feb 15 1998, vendu - */ - -#ifndef _ETERM_IMLIB_H -# define _ETERM_IMLIB_H - -# ifdef NEW_IMLIB -# include -# else if defined(OLD_IMLIB) -# include -# endif - -# ifdef NEW_IMLIB -# define ImColor ImlibColor -# define Image ImlibImage -# define ImlibInit(d) Imlib_init(d) -# define ImlibLoadImage(id,f,c) Imlib_load_image(id,f) -# define ImlibFreePixmap(id,p) Imlib_free_pixmap(id,p) -# define ImlibRender(id,i,w,h) Imlib_render(id,i,w,h) -# define ImlibCopyImageToPixmap(id,i) Imlib_copy_image(id,i) -# define ImlibDestroyImage(id,i) Imlib_destroy_image(id,i) -# endif - -#endif /* _ETERM_IMLIB_H */ diff --git a/src/eterm_utmp.h b/src/eterm_utmp.h new file mode 100644 index 0000000..dc0ddc5 --- /dev/null +++ b/src/eterm_utmp.h @@ -0,0 +1,86 @@ +/* eterm_utmp.h -- Eterm utmp module header file + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#if !defined(ETERM_UTMP_H_) && defined(UTMP_SUPPORT) +#define ETERM_UTMP_H_ + +#include +#include /* Xlib, Xutil, Xresource, Xfuncproto */ + +/************ Macros and Definitions ************/ +#ifndef UTMP_FILENAME +# ifdef UTMP_FILE +# define UTMP_FILENAME UTMP_FILE +# elif defined(_PATH_UTMP) +# define UTMP_FILENAME _PATH_UTMP +# else +# define UTMP_FILENAME "/etc/utmp" +# endif +#endif + +#ifndef LASTLOG_FILENAME +# ifdef _PATH_LASTLOG +# define LASTLOG_FILENAME _PATH_LASTLOG +# else +# define LASTLOG_FILENAME "/usr/adm/lastlog" /* only on BSD systems */ +# endif +#endif + +#ifndef WTMP_FILENAME +# ifdef WTMP_FILE +# define WTMP_FILENAME WTMP_FILE +# elif defined(_PATH_WTMP) +# define WTMP_FILENAME _PATH_WTMP +# elif defined(SYSV) +# define WTMP_FILENAME "/etc/wtmp" +# else +# define WTMP_FILENAME "/usr/adm/wtmp" +# endif +#endif + +#ifndef TTYTAB_FILENAME +# ifdef TTYTAB +# define TTYTAB_FILENAME TTYTAB_FILENAME +# else +# define TTYTAB_FILENAME "/etc/ttytab" +# endif +#endif + +#ifndef USER_PROCESS +# define USER_PROCESS 7 +#endif +#ifndef DEAD_PROCESS +# define DEAD_PROCESS 8 +#endif + +/************ Function Prototypes ************/ +_XFUNCPROTOBEGIN + +extern void makeutent(const char *, const char *); +extern void cleanutent(void); + +_XFUNCPROTOEND + +#endif /* ETERM_UTMP_H_ */ diff --git a/src/events.c b/src/events.c new file mode 100644 index 0000000..a62c533 --- /dev/null +++ b/src/events.c @@ -0,0 +1,669 @@ +/* events.c -- Eterm events module + * -- 29 April 1999, mej + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +static const char cvs_ident[] = "$Id$"; + +#include "config.h" +#include "feature.h" + +#include +#include +#include +#include + +#include "../libmej/debug.h" +#include "../libmej/strings.h" +#include "debug.h" +#include "main.h" +#include "mem.h" +#include "strings.h" +#include "actions.h" +#include "command.h" +#include "e.h" +#include "events.h" +#include "graphics.h" +#include "menus.h" +#include "options.h" +#include "pixmap.h" +#include "screen.h" +#include "scrollbar.h" +#include "term.h" +#include "windows.h" + +unsigned char keypress_exit = 0; +event_master_t event_master; +event_dispatcher_data_t primary_data; +mouse_button_state_t button_state = +{0, 0, 0, 0, 0, 0, 0}; + +/********** The Event Handling Subsystem **********/ +void +event_init_subsystem(event_dispatcher_t primary_dispatcher, event_dispatcher_init_t init) +{ + + /* Initialize the subsystem with the main event dispatcher */ + event_master.num_dispatchers = 1; + event_master.dispatchers = (event_dispatcher_t *) MALLOC(sizeof(event_dispatcher_t)); + event_master.dispatchers[0] = (event_dispatcher_t) primary_dispatcher; + (init) (); /* Initialize the dispatcher's data */ +} + +void +event_register_dispatcher(event_dispatcher_t func, event_dispatcher_init_t init) +{ + + /* Add a secondary event dispatcher */ + event_master.num_dispatchers++; + event_master.dispatchers = (event_dispatcher_t *) REALLOC(event_master.dispatchers, sizeof(event_dispatcher_t) * event_master.num_dispatchers); + event_master.dispatchers[event_master.num_dispatchers - 1] = (event_dispatcher_t) func; + (init) (); /* Initialize the dispatcher's data */ +} + +void +event_dispatch(event_t * event) +{ + + register unsigned char i; + register unsigned char handled; + + /* No debugging stuff here. If you need it, take it out when done. This should be ultra-fast. -- mej */ + for (i = 0; i < event_master.num_dispatchers; i++) { + handled = (event_master.dispatchers[i]) (event); + if (handled) { + break; + } + } +} + +void +event_data_add_mywin(event_dispatcher_data_t * data, Window win) +{ + + ASSERT(data != NULL); + + if (data->num_my_windows > 0) { + (data->num_my_windows)++; + data->my_windows = (Window *) REALLOC(data->my_windows, sizeof(Window) * data->num_my_windows); + data->my_windows[data->num_my_windows - 1] = win; + } else { + data->num_my_windows = 1; + data->my_windows = (Window *) MALLOC(sizeof(Window)); + data->my_windows[0] = win; + } +} + +void +event_data_add_parent(event_dispatcher_data_t * data, Window win) +{ + + ASSERT(data != NULL); + + if (data->num_my_parents > 0) { + (data->num_my_parents)++; + data->my_parents = (Window *) REALLOC(data->my_parents, sizeof(Window) * data->num_my_parents); + data->my_parents[data->num_my_parents - 1] = win; + } else { + data->num_my_parents = 1; + data->my_parents = (Window *) MALLOC(sizeof(Window)); + data->my_parents[0] = win; + } +} + +void +event_init_primary_dispatcher(void) +{ + + MEMSET(&primary_data, 0, sizeof(event_dispatcher_data_t)); + + EVENT_DATA_ADD_HANDLER(primary_data, KeyPress, handle_key_press); + EVENT_DATA_ADD_HANDLER(primary_data, PropertyNotify, handle_property_notify); + EVENT_DATA_ADD_HANDLER(primary_data, ClientMessage, handle_client_message); + EVENT_DATA_ADD_HANDLER(primary_data, MappingNotify, handle_mapping_notify); + EVENT_DATA_ADD_HANDLER(primary_data, VisibilityNotify, handle_visibility_notify); + EVENT_DATA_ADD_HANDLER(primary_data, FocusIn, handle_focus_in); + EVENT_DATA_ADD_HANDLER(primary_data, FocusOut, handle_focus_out); + EVENT_DATA_ADD_HANDLER(primary_data, ConfigureNotify, handle_configure_notify); + EVENT_DATA_ADD_HANDLER(primary_data, SelectionClear, handle_selection_clear); + EVENT_DATA_ADD_HANDLER(primary_data, SelectionNotify, handle_selection_notify); + EVENT_DATA_ADD_HANDLER(primary_data, SelectionRequest, handle_selection_request); + EVENT_DATA_ADD_HANDLER(primary_data, GraphicsExpose, handle_expose); + EVENT_DATA_ADD_HANDLER(primary_data, Expose, handle_expose); + EVENT_DATA_ADD_HANDLER(primary_data, ButtonPress, handle_button_press); + EVENT_DATA_ADD_HANDLER(primary_data, ButtonRelease, handle_button_release); + EVENT_DATA_ADD_HANDLER(primary_data, MotionNotify, handle_motion_notify); + + event_data_add_mywin(&primary_data, TermWin.parent); + event_data_add_mywin(&primary_data, TermWin.vt); + event_data_add_mywin(&primary_data, scrollBar.win); + if (scrollbar_is_pixmapped()) { + event_data_add_mywin(&primary_data, scrollBar.up_win); + event_data_add_mywin(&primary_data, scrollBar.dn_win); + event_data_add_mywin(&primary_data, scrollBar.sa_win); + } + if (desktop_window != None) { + event_data_add_parent(&primary_data, desktop_window); + } +} + +unsigned char +event_win_is_mywin(register event_dispatcher_data_t * data, Window win) +{ + + register unsigned short i; + + ASSERT(data != NULL); + + for (i = 0; i < data->num_my_windows; i++) { + if (data->my_windows[i] == win) { + return 1; + } + } + return 0; +} + +unsigned char +event_win_is_parent(register event_dispatcher_data_t * data, Window win) +{ + + register unsigned short i; + + ASSERT(data != NULL); + + for (i = 0; i < data->num_my_parents; i++) { + if (data->my_parents[i] == win) { + return 1; + } + } + return 0; +} + +unsigned char +handle_key_press(event_t * ev) +{ + +#ifdef COUNT_X_EVENTS + static long long keypress_cnt = 0; +#endif +#ifdef PROFILE_X_EVENTS + struct timeval keypress_start, keypress_stop; +#endif + + P_SETTIMEVAL(keypress_start); + D_EVENTS(("handle_key_press(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + COUNT_EVENT(keypress_cnt); + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + lookup_key(ev); + P_SETTIMEVAL(keypress_stop); + P_EVENT_TIME("KeyPress", keypress_start, keypress_stop); + return 1; +} + +unsigned char +handle_property_notify(event_t * ev) +{ + + Atom prop; + + D_EVENTS(("handle_property_notify(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + if (((Options & Opt_pixmapTrans) || (images[image_bg].mode & MODE_TRANS)) && (desktop_window != None)) { + if (ev->xany.window == TermWin.parent) { + prop = XInternAtom(Xdisplay, "_WIN_WORKSPACE", True); + if ((prop == None) || (ev->xproperty.atom != prop)) { + return 0; + } + XSelectInput(Xdisplay, desktop_window, None); + desktop_window = get_desktop_window(); + XSelectInput(Xdisplay, desktop_window, PropertyChangeMask); + if (desktop_pixmap != None) { + free_desktop_pixmap(); + } + render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 1); + scr_expose(0, 0, TermWin_TotalWidth(), TermWin_TotalHeight()); + scrollbar_show(0); + + } else if (ev->xany.window == desktop_window) { + prop = XInternAtom(Xdisplay, "_XROOTPMAP_ID", True); + if ((prop == None) || (ev->xproperty.atom != prop)) { + return 0; + } + if (desktop_pixmap != None) { + free_desktop_pixmap(); + } + render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 1); + scr_expose(0, 0, TermWin_TotalWidth(), TermWin_TotalHeight()); + scrollbar_show(0); + } + } + return 1; +} + +unsigned char +handle_client_message(event_t * ev) +{ + + D_EVENTS(("handle_client_message(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + + if (ev->xclient.format == 32 && ev->xclient.data.l[0] == (signed) wmDeleteWindow) + exit(EXIT_SUCCESS); + if (ev->xclient.format == 8 && ev->xclient.message_type == ipc_atom) { + char buff[13]; + unsigned char i; + + for (i = 0; i < 12; i++) { + buff[i] = ev->xclient.data.b[i + 8]; + } + buff[12] = 0; + D_ENL(("handle_client_message(): Discarding unexpected Enlightenment IPC message: \"%s\"\n", buff)); + return 1; + } +#ifdef OFFIX_DND + /* OffiX Dnd (drag 'n' drop) protocol */ + if (ev->xclient.message_type == DndProtocol && ((ev->xclient.data.l[0] == DndFile) + || (ev->xclient.data.l[0] == DndDir) || (ev->xclient.data.l[0] == DndLink))) { + /* Get DnD data */ + Atom ActualType; + int ActualFormat; + unsigned char *data; + unsigned long Size, RemainingBytes; + + XGetWindowProperty(Xdisplay, Xroot, DndSelection, 0L, 1000000L, False, AnyPropertyType, &ActualType, &ActualFormat, &Size, &RemainingBytes, &data); + XChangeProperty(Xdisplay, Xroot, XA_CUT_BUFFER0, XA_STRING, 8, PropModeReplace, data, strlen(data)); + selection_paste(Xroot, XA_CUT_BUFFER0, True); + XSetInputFocus(Xdisplay, Xroot, RevertToNone, CurrentTime); + return 1; + } +#endif /* OFFIX_DND */ + return 0; +} + +unsigned char +handle_mapping_notify(event_t * ev) +{ + + D_EVENTS(("handle_mapping_notify(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + XRefreshKeyboardMapping(&(ev->xmapping)); + return 1; +} + +unsigned char +handle_visibility_notify(event_t * ev) +{ + + D_EVENTS(("handle_visibility_notify(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + switch (ev->xvisibility.state) { + case VisibilityUnobscured: +#ifdef USE_SMOOTH_REFRESH + refresh_type = SMOOTH_REFRESH; +#else + refresh_type = FAST_REFRESH; +#endif + break; + case VisibilityPartiallyObscured: + refresh_type = SLOW_REFRESH; + break; + default: + refresh_type = NO_REFRESH; + break; + } + return 1; +} + +unsigned char +handle_focus_in(event_t * ev) +{ + + D_EVENTS(("handle_focus_in(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + if (!TermWin.focus) { + TermWin.focus = 1; + if (background_is_pixmap() && (images[image_bg].norm != images[image_bg].selected)) { + images[image_bg].current = images[image_bg].selected; + render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 1); + scr_expose(0, 0, TermWin_TotalWidth(), TermWin_TotalHeight()); + } + if (Options & Opt_scrollbar_popup) { + map_scrollbar(Options & Opt_scrollBar); + } +#ifdef USE_XIM + if (Input_Context != NULL) + XSetICFocus(Input_Context); +#endif + } + return 0; +} + +unsigned char +handle_focus_out(event_t * ev) +{ + + D_EVENTS(("handle_focus_out(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + if (TermWin.focus) { + TermWin.focus = 0; + if (background_is_pixmap() && (images[image_bg].norm != images[image_bg].selected)) { + images[image_bg].current = images[image_bg].norm; + render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 1); + scr_expose(0, 0, TermWin_TotalWidth(), TermWin_TotalHeight()); + } + if (Options & Opt_scrollbar_popup) { + map_scrollbar(0); + } +#ifdef USE_XIM + if (Input_Context != NULL) + XUnsetICFocus(Input_Context); +#endif + } + return 0; +} + +unsigned char +handle_configure_notify(event_t * ev) +{ + XEvent unused_xevent; + + D_EVENTS(("handle_configure_notify(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + + while (XCheckTypedWindowEvent(Xdisplay, ev->xany.window, ConfigureNotify, &unused_xevent)); + resize_window(); +#ifdef USE_XIM + xim_set_status_position(); +#endif + return 1; +} + +unsigned char +handle_selection_clear(event_t * ev) +{ + + D_EVENTS(("handle_selection_clear(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + selection_clear(); + return 1; +} + +unsigned char +handle_selection_notify(event_t * ev) +{ + + D_EVENTS(("handle_selection_notify(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + selection_paste(ev->xselection.requestor, ev->xselection.property, True); + return 1; +} + +unsigned char +handle_selection_request(event_t * ev) +{ + + D_EVENTS(("handle_selection_request(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + selection_send(&(ev->xselectionrequest)); + return 1; +} + +unsigned char +handle_expose(event_t * ev) +{ + +#ifdef COUNT_X_EVENTS + static long long expose_cnt = 0; +#endif +#ifdef PROFILE_X_EVENTS + struct timeval expose_start, expose_stop; +#endif + + P_SETTIMEVAL(expose_start); + D_EVENTS(("handle_expose(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + if (ev->xany.window == TermWin.vt) { + scr_expose(ev->xexpose.x, ev->xexpose.y, ev->xexpose.width, ev->xexpose.height); + } else { + + XEvent unused_xevent; + + while (XCheckTypedWindowEvent(Xdisplay, ev->xany.window, Expose, &unused_xevent)); + while (XCheckTypedWindowEvent(Xdisplay, ev->xany.window, GraphicsExpose, &unused_xevent)); + Gr_expose(ev->xany.window); + } + if (desktop_window != None) { + XSelectInput(Xdisplay, desktop_window, PropertyChangeMask); + } + P_SETTIMEVAL(expose_stop); + P_EVENT_TIME("Expose", expose_start, expose_stop); + return 0; +} + +unsigned char +handle_button_press(event_t * ev) +{ + + D_EVENTS(("handle_button_press(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + if (Options & Opt_borderless) { + XSetInputFocus(Xdisplay, Xroot, RevertToNone, CurrentTime); + } + if (action_dispatch(ev, 0)) { + return 1; + } + + button_state.bypass_keystate = (ev->xbutton.state & (Mod1Mask | ShiftMask)); + button_state.report_mode = (button_state.bypass_keystate ? 0 : ((PrivateModes & PrivMode_mouse_report) ? 1 : 0)); + + if (ev->xany.window == TermWin.vt) { + if (ev->xbutton.subwindow != None) { + Gr_ButtonPress(ev->xbutton.x, ev->xbutton.y); + } else { + if (button_state.report_mode) { + if (PrivateModes & PrivMode_MouseX10) { + /* no state info allowed */ + ev->xbutton.state = 0; + } +#ifdef MOUSE_REPORT_DOUBLECLICK + if (ev->xbutton.button == Button1) { + if (ev->xbutton.time - button_state.button_press < MULTICLICK_TIME) + button_state.clicks++; + else + button_state.clicks = 1; + } +#else + button_state.clicks = 1; +#endif /* MOUSE_REPORT_DOUBLECLICK */ + mouse_report(&(ev->xbutton)); + } else { + switch (ev->xbutton.button) { + case Button1: + if (button_state.last_button_press == 1 + && (ev->xbutton.time - button_state.button_press < MULTICLICK_TIME)) + button_state.clicks++; + else + button_state.clicks = 1; + selection_click(button_state.clicks, ev->xbutton.x, ev->xbutton.y); + button_state.last_button_press = 1; + break; + + case Button3: + if (button_state.last_button_press == 3 + && (ev->xbutton.time - button_state.button_press < MULTICLICK_TIME)) + selection_rotate(ev->xbutton.x, ev->xbutton.y); + else + selection_extend(ev->xbutton.x, ev->xbutton.y, 1); + button_state.last_button_press = 3; + break; + } + } + button_state.button_press = ev->xbutton.time; + return (1); + } + } + return 0; +} + +unsigned char +handle_button_release(event_t * ev) +{ + + D_EVENTS(("handle_button_release(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + button_state.mouse_offset = 0; + button_state.report_mode = (button_state.bypass_keystate ? 0 : ((PrivateModes & PrivMode_mouse_report) ? 1 : 0)); + + if (ev->xany.window == TermWin.vt) { + if (ev->xbutton.subwindow != None) + Gr_ButtonRelease(ev->xbutton.x, ev->xbutton.y); + else { + if (button_state.report_mode) { + switch (PrivateModes & PrivMode_mouse_report) { + case PrivMode_MouseX10: + break; + + case PrivMode_MouseX11: + ev->xbutton.state = button_state.bypass_keystate; + ev->xbutton.button = AnyButton; + mouse_report(&(ev->xbutton)); + break; + } + return (1); + } + /* + * dumb hack to compensate for the failure of click-and-drag + * when overriding mouse reporting + */ + if ((PrivateModes & PrivMode_mouse_report) && (button_state.bypass_keystate) && (ev->xbutton.button == Button1) && (clickOnce())) { + selection_extend(ev->xbutton.x, ev->xbutton.y, 0); + } + switch (ev->xbutton.button) { + case Button1: + case Button3: +#if defined(CTRL_CLICK_RAISE) || defined(CTRL_CLICK_MENU) + if (!(ev->xbutton.state & ControlMask)) +#endif + selection_make(ev->xbutton.time); + break; + + case Button2: +#ifdef CTRL_CLICK_SCROLLBAR + if (!(ev->xbutton.state & ControlMask)) +#endif + selection_request(ev->xbutton.time, ev->xbutton.x, ev->xbutton.y); + break; + case Button4: + scr_page(UP, (ev->xbutton.state & ShiftMask) ? 1 : 5); + break; + case Button5: + scr_page(DN, (ev->xbutton.state & ShiftMask) ? 1 : 5); + break; + } + } + } + return 0; +} + +unsigned char +handle_motion_notify(event_t * ev) +{ + +#ifdef COUNT_X_EVENTS + static long long motion_cnt = 0; +#endif +#ifdef PROFILE_X_EVENTS + struct timeval motion_start, motion_stop; +#endif + + D_EVENTS(("handle_motion_notify(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + COUNT_EVENT(motion_cnt); + P_SETTIMEVAL(motion_start); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); + if ((PrivateModes & PrivMode_mouse_report) && !(button_state.bypass_keystate)) + return 1; + + if (ev->xany.window == TermWin.vt) { + if (ev->xbutton.state & (Button1Mask | Button3Mask)) { + Window unused_root, unused_child; + int unused_root_x, unused_root_y; + unsigned int unused_mask; + + while (XCheckTypedWindowEvent(Xdisplay, TermWin.vt, MotionNotify, ev)); + XQueryPointer(Xdisplay, TermWin.vt, &unused_root, &unused_child, &unused_root_x, &unused_root_y, &(ev->xbutton.x), &(ev->xbutton.y), &unused_mask); +#ifdef MOUSE_THRESHOLD + /* deal with a `jumpy' mouse */ + if ((ev->xmotion.time - button_state.button_press) > MOUSE_THRESHOLD) +#endif + selection_extend((ev->xbutton.x), (ev->xbutton.y), (ev->xbutton.state & Button3Mask)); + } + P_SETTIMEVAL(motion_stop); + P_EVENT_TIME("MotionNotify", motion_start, motion_stop); + return 1; + } + return 0; +} + +unsigned char +process_x_event(event_t * ev) +{ +#ifdef COUNT_X_EVENTS + static long long event_cnt = 0; +#endif + + COUNT_EVENT(event_cnt); + if (primary_data.handlers[ev->type] != NULL) { + return ((primary_data.handlers[ev->type]) (ev)); + } + return (0); +} + +XErrorHandler +xerror_handler(Display * display, XErrorEvent * event) +{ + + char err_string[2048]; + + strcpy(err_string, ""); + XGetErrorText(display, event->error_code, err_string, sizeof(err_string)); + print_error("XError in function %s (request %d.%d): %s (error %d)", request_code_to_name(event->request_code), + event->request_code, event->minor_code, err_string, event->error_code); +#if DEBUG > DEBUG_X11 + if (debug_level >= DEBUG_X11) { + dump_stack_trace(); + } +#endif + print_error("Attempting to continue..."); + return 0; +} diff --git a/src/events.h b/src/events.h new file mode 100644 index 0000000..fab0e9d --- /dev/null +++ b/src/events.h @@ -0,0 +1,123 @@ +/* events.h -- Eterm events module header file + * -- 29 April 1999, mej + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _EVENTS_H_ +#define _EVENTS_H_ + +#include +#include /* Xlib, Xutil, Xresource, Xfuncproto */ + +/************ Macros and Definitions ************/ +#if 0 +# define XEVENT_IS_MYWIN(ev) (((ev)->xany.window == TermWin.parent) \ + || ((ev)->xany.window == TermWin.vt) \ + || ((ev)->xany.window == menuBar.win) \ + || (scrollbar_uparrow_is_pixmapped() && ((ev)->xany.window == scrollBar.up_win)) \ + || (scrollbar_downarrow_is_pixmapped() && ((ev)->xany.window == scrollBar.dn_win)) \ + || (scrollbar_anchor_is_pixmapped() && ((ev)->xany.window == scrollBar.sa_win)) \ + || ((ev)->xany.window == scrollBar.win)) +# define XEVENT_IS_PARENT(ev) (((ev)->xany.window == TermWin.wm_parent) \ + || ((ev)->xany.window == TermWin.wm_grandparent)) +#endif + +#define XEVENT_IS_MYWIN(ev, data) event_win_is_mywin(data, (ev)->xany.window) +#define XEVENT_IS_PARENT(ev, data) event_win_is_parent(data, (ev)->xany.window) + +#define clickOnce() (button_state.clicks <= 1) +#ifdef COUNT_X_EVENTS +# define COUNT_EVENT(x) do {(x)++; D_EVENTS(("%s == %ld\n", #x, x));} while (0) +#else +# define COUNT_EVENT(x) NOP +#endif +#ifdef PROFILE_X_EVENTS +# define P_EVENT_TIME(type, start, stop) real_dprintf(type ": %ld microseconds\n", P_CMPTIMEVALS_USEC((start), (stop))) +#else +# define P_EVENT_TIME(type, start, stop) NOP +# define P_SETTIMEVAL(t) NOP +#endif +#define EVENT_DATA_ADD_HANDLER(data, type, handler) (data).handlers[(type)] = handler + +/************ Structures ************/ +typedef XEvent event_t; +typedef unsigned char (*event_dispatcher_t)(event_t *); +typedef unsigned char (*event_handler_t)(event_t *); +typedef void (*event_dispatcher_init_t)(void); +typedef struct { + event_dispatcher_t *dispatchers; + unsigned char num_dispatchers; +} event_master_t; +typedef struct { + event_handler_t handlers[LASTEvent]; + unsigned char num_my_windows; + Window *my_windows; + unsigned char num_my_parents; + Window *my_parents; +} event_dispatcher_data_t; + +typedef struct { + unsigned short clicks, bypass_keystate, report_mode, mouse_offset; + Time button_press, last_button_press, activate_time; +} mouse_button_state_t; + +/************ Variables ************/ +extern unsigned char keypress_exit; +extern event_master_t event_master; +extern mouse_button_state_t button_state; + +/************ Function Prototypes ************/ +_XFUNCPROTOBEGIN + +extern void event_init_subsystem(event_dispatcher_t, event_dispatcher_init_t); +extern void event_register_dispatcher(event_dispatcher_t, event_dispatcher_init_t); +extern void event_dispatch(event_t *); +extern void event_data_add_mywin(event_dispatcher_data_t *, Window); +extern void event_data_add_parent(event_dispatcher_data_t *, Window); +extern void event_init_primary_dispatcher(void); +extern unsigned char event_win_is_mywin(event_dispatcher_data_t *, Window); +extern unsigned char event_win_is_parent(event_dispatcher_data_t *, Window); +extern unsigned char handle_key_press(event_t *); +extern unsigned char handle_property_notify(event_t *); +extern unsigned char handle_reparent_notify(event_t *); +extern unsigned char handle_client_message(event_t *); +extern unsigned char handle_mapping_notify(event_t *); +extern unsigned char handle_leave_notify(event_t *); +extern unsigned char handle_visibility_notify(event_t *); +extern unsigned char handle_focus_in(event_t *); +extern unsigned char handle_focus_out(event_t *); +extern unsigned char handle_configure_notify(event_t *); +extern unsigned char handle_selection_clear(event_t *); +extern unsigned char handle_selection_notify(event_t *); +extern unsigned char handle_selection_request(event_t *); +extern unsigned char handle_expose(event_t *); +extern unsigned char handle_button_press(event_t *); +extern unsigned char handle_button_release(event_t *); +extern unsigned char handle_motion_notify(event_t *); +extern unsigned char process_x_event(event_t *); +extern XErrorHandler xerror_handler(Display *, XErrorEvent *); + +_XFUNCPROTOEND + +#endif /* _EVENTS_H_ */ diff --git a/src/feature.h.in b/src/feature.h.in deleted file mode 100644 index bfdbb40..0000000 --- a/src/feature.h.in +++ /dev/null @@ -1,527 +0,0 @@ -/* feature.h -- Eterm feature defines header - * -- 10 Sept 1997, mej - * - * This file is original work by Michael Jennings and - * Tuomo Venalainen . This file, and any other file - * bearing this same message or a similar one, is distributed under - * the GNU Public License (GPL) as outlined in the COPYING file. - * - * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * $Id$ - * - */ - -#ifndef _FEATURE_H_ -# define _FEATURE_H_ - -# include -# include - -# include "config.h" -# include "debug.h" - -/********************* Miscellaneous OS fixings *********************/ - -# if defined(hpux) && !defined(_HPUX_SOURCE) -# define _HPUX_SOURCE -# endif - -/* -# if defined(_HPUX_SOURCE) && !defined(SVR4) -# define SVR4 -# endif - */ - -# if defined(SVR4) && !defined(__svr4__) -# define __svr4__ -# endif -# if !defined(SVR4) && defined(__svr4__) -# define SVR4 -# endif - -# if defined(sun) && !defined(__sun__) -# define __sun__ -# endif -# if !defined(sun) && defined(__sun__) -# define sun -# endif - -# if defined (sun) -# undef HAVE_SYS_IOCTL_H -# endif - -# ifdef _SCO_DS /* SCO Osr5 */ -# define ALL_NUMERIC_PTYS /* Scos pty naming is /dev/[pt]typ0 - /dev/[pt]ty256 */ -# endif - -/********************* Debugging stuff *********************/ -/* As Keith Bunge would say, don't crap with the debugging stuff below - * unless you develop this mess. :^) -- mej - */ - -# ifndef DEBUG -# define DEBUG 0 -# endif - -/********************* Random development stuff ***************************/ -/* #define PROFILE */ -#ifdef PROFILE -/* #define PROFILE_SCREEN */ -/* #define PROFILE_X_EVENTS */ -/* #define COUNT_X_EVENTS */ -#endif -/* Active tags are disabled by default until we find a bug that crashes Eterm - * on window resize :( - */ -/* #define USE_ACTIVE_TAGS */ -#define OPTIMIZE_HACKS - -/********************* Color, screen, and image stuff *********************/ - -/* Allow pixmaps in the background of the window */ -# define PIXMAP_SUPPORT - -/* I'm having problems with this... The call to XInitThreads() in main.c seems - * to mess threads up on my system... They run "OK" for a while without that, - * but will make Eterm hang eventually. - */ -/* #define USE_POSIX_THREADS */ -/* Use mutexes for thread synchronization. */ -/* #define MUTEX_SYNCH */ - -/* Support for pseudo-transparency and viewport mode */ -# define PIXMAP_OFFSET - -/* Use Imlib for pseudo-transparency, shading, etc. Still experimental at - this point. -- mej */ -/* # define IMLIB_TRANS */ - -/* Support for background pixmap cycling */ -#define BACKGROUND_CYCLING_SUPPORT - -/* Pixmapped scrollbar. - */ -# define PIXMAP_SCROLLBAR - -/* Pixmapped menubar. - */ -# define PIXMAP_MENUBAR - -/* Enable use of backing store for the terminal window. */ -# define BACKING_STORE - -/* Use Rasterman's Imlib image library for image manipulation - * If you don't use Imlib, you won't be able to have background pixmaps */ -# define USE_IMLIB - -/* Define this to use Eterm with Imlib 0.x. Otherwise, it will use Imlib 1.0's - * API. - */ -/* #define OLD_IMLIB */ - -/* Define this to use Eterm with Imlib 1.x. This certainly is the Imlib you - * want to use. - */ - -# if defined(USE_IMLIB) && !defined(OLD_IMLIB) -# define NEW_IMLIB -# endif - -/* The environment variable in which Eterm looks for a search path for - config files and pixmaps */ -# define PATH_ENV "ETERMPATH" - -/* Enable support for themes. */ -# define USE_THEMES - -/* These are for future use. Defining them won't help anything, and it may - break stuff. */ -#define USE_EFFECTS - -/* Option to watch the desktop pixmap for changes. If the desktop background changes - a pseudo-transparent Eterm will find out about it and update to the new image */ -#define WATCH_DESKTOP_OPTION - -/* Disable support for changing the cursor color (-c and -t options) */ -/* #define NO_CURSORCOLOR */ - -/* Disable use of high-intensity colors 8-15. They will be simulated using - the "bold" font, colorBD, or overstrike */ -/* #define NO_BRIGHTCOLOR */ - -/* Disable separate colors for the bold and underline attributes */ -/* #define NO_BOLDUNDERLINE */ - -/* Disable simulation of bold font using an "overstrike" technique. This technique - has been known to cause pixel droppings, and its use is not advised. See - also FORCE_CLEAR_CHARS. */ -/* #define NO_BOLDOVERSTRIKE */ - -/* Disable the use of a separate "bold" font */ -/* #define NO_BOLDFONT */ - -/* Disable the secondary screen ("\E[?47h" / "\E[?47l") */ -/* #define NO_SECONDARY_SCREEN */ - -/* The number of screenfuls between refreshes. - * If you define this, it will be set to 3. - */ -/*#define REFRESH_PERIOD 3 */ -# define REFRESH_PERIOD 5 - -/* This will force clearing of characters before writing new ones on top of - * them. This is experimental - added in order to try and fix pixel dropping - * problems some people have had. See also NO_BOLDOVERSTRIKE. */ -# define FORCE_CLEAR_CHARS - -/* Rob Nation's graphics escape sequences */ -/* #define RXVT_GRAPHICS */ - -/* The command through which to pipe print-screen requests */ -#define PRINTPIPE "lp" - -/* If the screen can handle 24-bit graphics, force them */ -/* #define PREFER_24BIT */ - -/* Offer some support for the Offix DND (Drag 'n' Drop) protocol (untested) */ -/* #define OFFIX_DND */ - -/* Allows the -w and --border-width options for specifying the width of the - * border (in pixels) between the actual X client window and the program-useable - * terminal window. -- mej - */ -# define BORDER_WIDTH_OPTION - -/********************* Key and key-bindings options *********************/ - -/* Use the X server value for the Delete key, regardless */ -/* #define NO_DELETE_KEY */ - -/* Force the delete key to send ^? instead of ESC [ 3 ~ */ -/* #define KS_DELETE "\177" */ -#ifndef NO_DELETE_KEY -# define KS_DELETE "\177" -#endif - -/* Force the Backspace key to send ^H instead of checking the stty setting */ -#define FORCE_BACKSPACE -/* Force Backspace to send ^? */ -/* #define FORCE_DELETE */ - -/* Pick the hotkey for changing the font size */ -# define HOTKEY_CTRL -/* #define HOTKEY_META */ - -/* Use Home = "\E[1~" and End = "\E[4~" instead of Home = "\E[7~" and End = "\E[8~" */ -/* #define LINUX_KEYS */ -#ifdef linux -# define LINUX_KEYS -#endif - -/* Allow the "keysym" attribute in config files for remapping keysyms */ -#define KEYSYM_ATTRIBUTE - -/* Disable X11R6 support for European languages */ -/* #define NO_XLOCALE */ - -/* Allow unshifted Next and Prior keys to scroll, in addition to their shifted - * counterparts */ -/* #define UNSHIFTED_SCROLLKEYS */ - -/********************* Mouse, scrollbar, and menu bar options *********************/ - -/* Disable sending escape sequences from the scrollbar when mouse reporting - * is enabled */ -/* #define NO_SCROLLBAR_REPORT */ - -/* Set the default number of lines in the scrollback buffer */ -/* #define SAVELINES 256 */ - -/* Set the default separator characters for double-click word selection */ -#define CUTCHARS "\"&'()*,;<=>?@[\\]^`{|}~ \t" - -/* Make it an option */ -#define CUTCHAR_OPTION - -/* To activate double-click reporting for button 1 */ -/* #define MOUSE_REPORT_DOUBLECLICK */ - -/* The delay in milliseconds between multiple clicks */ -/* #define MULTICLICK_TIME 500 */ - -/* Support for the old xterm-style scrollbar */ -#define XTERM_SCROLLBAR - -/* Support for the traditional motif-style scrollbar */ -#define MOTIF_SCROLLBAR - -/* Support for a NeXT-style scrollbar */ -#define NEXT_SCROLLBAR - -/* Default scrollbar type */ -#define SCROLLBAR_DEFAULT_TYPE SCROLLBAR_MOTIF - -/* Scrollbar Colors */ -#define KEEP_SCROLLCOLOR - -/* The default width (in pixels) of the scrollbar. Should be an even number. */ -#define SB_WIDTH 10 - -/* Revert the scrollbar's color to the background color when the window loses focus */ -#define CHANGE_SCROLLCOLOR_ON_FOCUS - -/* Continuous scrolling by pressing the scrollbar arrow buttons */ -#define SCROLLBAR_BUTTON_CONTINUAL_SCROLLING - -/* To allow smooth refresh when the terminal window is fully unobscured. - * Didn't seem to cause a performance hit rolling a big amount of text - * on my Pentium-100 system (Linux) :)... Recommended :) - */ -#define USE_SMOOTH_REFRESH - -/* Delay periods for continuous scrolling */ -/* #define SCROLLBAR_INITIAL_DELAY 40 */ -/* #define SCROLLBAR_CONTINUOUS_DELAY 2 */ - -/* The maximum number of menubars that can be stacked. 1 disabled stacking, 0 - disables menubars altogether */ -#define MENUBAR_MAX 8 - -/* An alternative placement of the menubar shadow */ -/* #define MENUBAR_SHADOW_IN */ - -/* An alternative placement of the menu shadow */ -#define MENU_SHADOW_IN - -/* Allow Ctrl+Button1 in a window to raise and steal focus */ -#define CTRL_CLICK_RAISE - -/* Allow Ctrl+Button2 in a window to toggle the scrollbar */ -#define CTRL_CLICK_SCROLLBAR - -/* Allow Ctrl+Button3 in a window to toggle the menubar */ -#define CTRL_CLICK_MENU - -/********************* Multi-lingual support options *********************/ - -/* Allow option/attribute for Meta to set the 8th bit */ -#define META8_OPTION - -/* To include support for Greek Elot-928 and IBM-437 keyboard modes */ -/* #define GREEK_SUPPORT */ - -/* To compile as a Kanji terminal. Executable should be renamed "Kterm". */ -/* #define KANJI */ - -/********************* Miscellaneous options *********************/ - -/* To have $DISPLAY and the "\E[7n" response be IP addresses rather than FQDN's */ -/* #define DISPLAY_IS_IP */ - -/* To have "\E[7n" reply with the display name. This is a potential security risk, - * so its use is discouraged and unsupported. */ -/* #define ENABLE_DISPLAY_ANSWER */ - -/* To control what the Eterm detection sequence, ESC-Z, replies with */ -/* #define ESCZ_ANSWER "\033[?1;2C" */ - -/* Comment this out to allow printing of the VT100_ANS sequence. See - * command.c. I have no idea what this is supposed to do, but disabling - * it will prevent your terminal from getting garbage when ^E (ctrl-E) - * is printed on it. - */ -#define NO_VT100_ANS - -/* Checks the current value of the window title and icon name before setting them. - Can save unnecessary screen refreshes */ -#define SMART_WINDOW_TITLE - -/* Allow changing of the foreground and background colors with "\E]39;color^G" */ -/* #define XTERM_COLOR_CHANGE */ - -/* Exports TERM=xterm-color instead of just TERM=xterm */ -/* #define DEFINE_XTERM_COLOR */ - -/* Disable automatic de-iconify on bell altogether */ -/* #define NO_MAPALERT */ - -/* Make it an option */ -#define MAPALERT_OPTION - -/* Enable core dumps from Eterm. Not recommended for use by anyone but developers. */ -/* #define ENABLE_CORE_DUMPS */ - -/********************* utmp logging support *********************/ - -/* Enable utmp support. This has been tested and verified to work on Linux, - * FreeBSD, and HP-UX. Other operatings systems should work, but we have - * not been able to verify for sure that they do. Eterm *must* be setuid - * or setgid, usually setuid root, for this to work. Do it at your own risk. - */ -#define UTMP_SUPPORT - -/* Added security for systems with saved uids and gids. If you don't define - * this, and you're not on HP-UX with _HPUX_SOURCE defined, Eterm processes - * may seem to be owned by root. But if you define this and don't have them, - * the utmp and tty stuff could break. Do some testing. DO NOT get this one - * wrong! */ -/* #define HAVE_SAVED_UIDS */ - -/* Use getgrnam() to determine the group id of TTY_GRP_NAME, and chgrp tty - * device files to that group. This should be ok on SVR4 and Linux systems - * with group "tty" and on BSD systems with group "wheel" - */ -#define USE_GETGRNAME -#define TTY_GRP_NAME "tty" - -/********************* Config file parser options *********************/ - -/* Allow evaluation of expressions like `echo hello` in config files. The - * security-paranoid will not want to define this, but I have replaced the - * OS system() call with a secure one that I have tested and verified, so - * child processes run in this way will not run with any privileges, active - * or attainable. - */ -#define ALLOW_BACKQUOTE_EXEC - -/* This is the initial path that Eterm searches for its config file. - * By convention, this should be ".", then "~/.Eterm", then a global - * directory for all users like "/usr/local/lib/Eterm" */ -#define CONFIG_SEARCH_PATH "~/.Eterm/themes:~/.Eterm:@DATADIR@/Eterm/themes:@DATADIR@/Eterm" - -/* The name of the config file. "MAIN" by default. Don't change this - unless you have a darn good reason to. It's never been tested any other way. */ -#define CONFIG_FILE_NAME "MAIN" - -/* This causes Eterm to warn you if a config file it's about to parse was - * designed for an older version of Eterm. */ -/* #define WARN_OLDER */ - -/********************* Anti-cl00bie protection (sigh) *********************/ -/* EDITING THIS FILE BELOW THIS LINE IS UNSUPPORTED! YOU HAVE BEEN WARNED! */ - -#ifdef KANJI -# undef GREEK_SUPPORT -# undef XTERM_FONT_CHANGE -# undef DEFINE_XTERM_COLOR -# define KFONT0 "k14" -# define KFONT1 "jiskan16" -# define KFONT2 "jiskan18" -# define KFONT3 "jiskan24" -# define KFONT4 "jiskan26" -/* sizes matched to kanji fonts */ -# define FONT0 "7x14" -# define FONT1 "8x16" -# define FONT2 "9x18" -# define FONT3 "12x24" -# define FONT4 "13x26" -#else /* KANJI */ -# define FONT0 "7x14" -# define FONT1 "6x10" -# define FONT2 "6x13" -# define FONT3 "8x13" -# define FONT4 "9x15" -#endif /* KANJI */ -#define FONT0_IDX 2 - -#ifndef PIXMAP_SUPPORT -# undef USE_IMLIB -# undef OLD_IMLIB -# undef PIXMAP_SCROLLBAR -# undef PIXMAP_MENUBAR -# undef BACKING_STORE -# undef PIXMAP_OFFSET -# undef IMLIB_TRANS -# undef PIXMAP_BUFFERING -# undef BACKGROUND_CYCLING_SUPPORT -# undef WATCH_PIXMAP_OPTION -#endif - -#ifndef PIXMAP_OFFSET -# undef WATCH_DESKTOP_OPTION -#endif - -#if defined(XTERM_SCROLLBAR) && !defined(NO_MENUBAR) -# define NO_MENUBAR -#endif - -#ifndef TTY_GRP_NAME -# undef USE_GETGRNAME -#endif - -#ifndef HAVE_MEMMOVE -inline void *memmove(void *, const void *, size_t); -#endif - -#define APL_NAME "Eterm" /* The name of our beloved program */ - -/* COLORTERM, TERM environment variables */ -#ifdef KANJI -# define TERMENV "kterm" -# define COLORTERMENV "Kterm" -#else -# define TERMENV "xterm" -# define COLORTERMENV "Eterm" -#endif - -#ifdef NO_MOUSE_REPORT -# ifndef NO_MOUSE_REPORT_SCROLLBAR -# define NO_MOUSE_REPORT_SCROLLBAR -# endif -#endif - -#ifndef DEFAULT_BORDER_WIDTH -# define DEFAULT_BORDER_WIDTH 5 -#endif - -#ifndef SB_WIDTH -# define SB_WIDTH 10 -#endif - -#ifndef KEEP_SCROLLCOLOR -# undef CHANGE_SCROLLCOLOR_ON_FOCUS -#endif - -#ifndef MENUBAR_MAX -# define MENUBAR_MAX 0 -#endif - -#ifndef SAVELINES -# define SAVELINES 256 -#endif - -#ifdef NO_SECONDARY_SCREEN -# define NSCREENS 0 -#else -# define NSCREENS 1 -#endif - -#ifndef CUTCHARS -# define CUTCHARS "\"&'()*,;<=>?@[\\]^`{|}~" -#endif - -#if defined (__sun__) || defined (__svr4__) -# define NO_DELETE_KEY /* These systems seem to be anal this way*/ -#endif - -/* utmp doesn't work on CygWin32 */ -#ifdef __CYGWIN32__ -# undef UTMP_SUPPORT -#endif - -#endif /* _FEATURE_H_ */ diff --git a/src/graphics.c b/src/graphics.c index 916c1c9..113a7bf 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -10,7 +10,8 @@ static const char cvs_ident[] = "$Id$"; -#include "main.h" +#include "config.h" +#include "feature.h" #ifdef HAVE_UNISTD_H # include @@ -20,6 +21,7 @@ static const char cvs_ident[] = "$Id$"; #include "command.h" /* for tt_printf() */ #include "debug.h" #include "graphics.h" +#include "main.h" #include "screen.h" /* commands: @@ -448,11 +450,6 @@ Gr_scroll(int count) for (grwin = gr_root; grwin != NULL; grwin = next) { next = grwin->next; grwin->y -= (count * TermWin.fheight); -# ifdef USE_ACTIVE_TAGS - fprintf(stderr, "FUCK YOU!\n"); - if (grwin == TermWin.vt) - tag_hide(); -# endif if ((grwin->y + grwin->h) < -(TermWin.saveLines * TermWin.fheight)) Gr_DestroyWindow(grwin); else diff --git a/src/grkelot.c b/src/grkelot.c index 7e328eb..98d863b 100644 --- a/src/grkelot.c +++ b/src/grkelot.c @@ -44,8 +44,8 @@ static const char cvs_ident[] = "$Id$"; +#include "config.h" #include "feature.h" -#include "grkelot.h" #ifdef GREEK_SUPPORT # include "grkelot.h" @@ -320,7 +320,6 @@ kstate_cxlat(unsigned int c) return (c); } -# ifdef RXVT void greek_init(void) { @@ -384,6 +383,5 @@ main(void) return 0; } # endif -# endif /* RXVT */ #endif /* GREEK_SUPPORT */ diff --git a/src/main.c b/src/main.c index f2c5d79..500ab90 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,7 @@ /* main.c -- Eterm main() function * -- 22 August 1998, mej * - * This file is original work by Michael Jennings and + * This file is original work by Michael Jennings and * Tuomo Venalainen . This file, and any other file * bearing this same message or a similar one, is distributed under * the GNU Public License (GPL) as outlined in the COPYING file. @@ -26,15 +26,12 @@ static const char cvs_ident[] = "$Id$"; -/* includes */ -#include "main.h" -#ifdef USE_ACTIVE_TAGS -# include "activetags.h" -# include "activeeterm.h" -#endif +#include "config.h" +#include "feature.h" #include #include +#include #ifdef HAVE_UNISTD_H # include #endif @@ -46,30 +43,26 @@ static const char cvs_ident[] = "$Id$"; #include #include -#include "command.h" -#include "feature.h" #include "../libmej/debug.h" /* from libmej */ #include "debug.h" #include "../libmej/mem.h" #include "../libmej/strings.h" -/* For strsep(). -vendu */ -#if defined(linux) -# include -#endif -#include "string.h" +#include "main.h" +#include "actions.h" +#include "command.h" +#include "eterm_utmp.h" +#include "events.h" #include "graphics.h" -#include "scrollbar.h" -#include "menubar.h" -#include "screen.h" #include "options.h" #include "pixmap.h" +#include "screen.h" +#include "scrollbar.h" +#include "term.h" #ifdef USE_POSIX_THREADS # include "threads.h" #endif +#include "windows.h" -/* Global attributes */ -XWindowAttributes attr; -XSetWindowAttributes Attributes; char *orig_argv0; #ifdef PIXMAP_SUPPORT @@ -77,204 +70,32 @@ char *orig_argv0; that doesn't send the right events (*cough* Window Maker *cough*) -- mej */ short bg_needs_update = 1; - #endif - -/* extern functions referenced */ -#ifdef DISPLAY_IS_IP -extern char *network_display(const char *display); - -#endif - -extern void get_initial_options(int, char **); -extern void menubar_read(const char *filename); - #ifdef USE_POSIX_THREADS static void **retval; static int join_value; static pthread_t main_loop_thr; static pthread_attr_t main_loop_attr; - # ifdef MUTEX_SYNCH pthread_mutex_t mutex; - # endif #endif - -#ifdef PIXMAP_SUPPORT -extern void render_pixmap(Window win, imlib_t image, pixmap_t pmap, - int which, renderop_t renderop); - -# ifdef BACKING_STORE -extern const char *rs_saveUnder; - -# endif - -extern char *rs_noCursor; - -# ifdef USE_IMLIB -extern ImlibData *imlib_id; - -# endif -#endif - -/* extern variables referenced */ -extern int my_ruid, my_rgid, my_euid, my_egid; -extern unsigned int rs_shadePct; -extern unsigned long rs_tintMask; - -/* extern variables declared here */ TermWin_t TermWin; Display *Xdisplay; /* display */ - -char *rs_color[NRS_COLORS]; -Pixel PixColors[NRS_COLORS + NSHADOWCOLORS]; - -unsigned long Options = (Opt_scrollBar); +Colormap cmap; unsigned int debug_level = 0; /* Level of debugging information to display */ - const char *display_name = NULL; -char *rs_name = NULL; /* client instance (resource name) */ - -#ifndef NO_BOLDFONT -const char *rs_boldFont = NULL; - -#endif -const char *rs_font[NFONTS]; - -#ifdef KANJI -const char *rs_kfont[NFONTS]; - -#endif - -#ifdef PRINTPIPE -char *rs_print_pipe = NULL; - -#endif - -char *rs_cutchars = NULL; - -/* local variables */ -Cursor TermWin_cursor; /* cursor for vt window */ unsigned int colorfgbg; -menuBar_t menuBar; - -XSizeHints szHint = -{ - PMinSize | PResizeInc | PBaseSize | PWinGravity, - 0, 0, 80, 24, /* x, y, width, height */ - 1, 1, /* Min width, height */ - 0, 0, /* Max width, height - unused */ - 1, 1, /* increments: width, height */ - {1, 1}, /* increments: x, y */ - {0, 0}, /* Aspect ratio - unused */ - 0, 0, /* base size: width, height */ - NorthWestGravity /* gravity */ -}; - -char *def_colorName[] = -{ - "rgb:0/0/0", "rgb:ff/ff/ff", /* fg/bg */ - "rgb:0/0/0", /* 0: black (#000000) */ -#ifndef NO_BRIGHTCOLOR - /* low-intensity colors */ - "rgb:cc/00/00", /* 1: red */ - "rgb:00/cc/00", /* 2: green */ - "rgb:cc/cc/00", /* 3: yellow */ - "rgb:00/00/cc", /* 4: blue */ - "rgb:cc/00/cc", /* 5: magenta */ - "rgb:00/cc/cc", /* 6: cyan */ - "rgb:fa/eb/d7", /* 7: white */ - /* high-intensity colors */ - "rgb:33/33/33", /* 8: bright black */ -#endif /* NO_BRIGHTCOLOR */ - "rgb:ff/00/00", /* 1/9: bright red */ - "rgb:00/ff/00", /* 2/10: bright green */ - "rgb:ff/ff/00", /* 3/11: bright yellow */ - "rgb:00/00/ff", /* 4/12: bright blue */ - "rgb:ff/00/ff", /* 5/13: bright magenta */ - "rgb:00/ff/ff", /* 6/14: bright cyan */ - "rgb:ff/ff/ff", /* 7/15: bright white */ -#ifndef NO_CURSORCOLOR - NULL, NULL, /* cursorColor, cursorColor2 */ -#endif /* NO_CURSORCOLOR */ - NULL, NULL /* pointerColor, borderColor */ -#ifndef NO_BOLDUNDERLINE - ,NULL, NULL /* colorBD, colorUL */ -#endif /* NO_BOLDUNDERLINE */ - ,"rgb:ff/ff/ff" /* menuTextColor */ -#ifdef KEEP_SCROLLCOLOR - ,"rgb:b2/b2/b2" /* scrollColor: match Netscape color */ -# ifdef CHANGE_SCROLLCOLOR_ON_FOCUS - ,NULL /* unfocusedscrollColor: somebody chose black? */ -# endif -#endif -}; - -#ifdef KANJI -/* Kanji font names, roman fonts sized to match */ -const char *def_kfontName[] = -{ - KFONT0, KFONT1, KFONT2, KFONT3, KFONT4 -}; - -#endif /* KANJI */ -const char *def_fontName[] = -{ - FONT0, FONT1, FONT2, FONT3, FONT4 -}; - -/* extern functions referenced */ -#ifdef PIXMAP_SUPPORT -/* the originally loaded pixmap and its scaling */ -extern pixmap_t bgPixmap; -extern void set_bgPixmap(const char * /* file */ ); - -# ifdef USE_IMLIB -extern imlib_t imlib_bg; - -# endif -# ifdef PIXMAP_SCROLLBAR -extern pixmap_t sbPixmap; -extern pixmap_t upPixmap, up_clkPixmap; -extern pixmap_t dnPixmap, dn_clkPixmap; -extern pixmap_t saPixmap, sa_clkPixmap; - -# ifdef USE_IMLIB -extern imlib_t imlib_sb, imlib_sa, imlib_saclk; - -# endif -# endif -# ifdef PIXMAP_MENUBAR -extern pixmap_t mbPixmap, mb_selPixmap; - -# ifdef USE_IMLIB -extern imlib_t imlib_mb, imlib_ms; - -# endif -# endif - -extern int scale_pixmap(const char *geom, pixmap_t * pmap); - -#endif /* PIXMAP_SUPPORT */ - -/* have we changed the font? Needed to avoid race conditions - * while window resizing */ -int font_change_count = 0; - -static void resize(void); - -extern XErrorHandler xerror_handler(Display *, XErrorEvent *); -extern void Create_Windows(int, char **); /* main() */ int main(int argc, char *argv[]) { - int i, count; + int i; char *val; static char windowid_string[20], *display_string, *term_string; /* "WINDOWID=\0" = 10 chars, UINT_MAX = 10 chars */ + ImlibInitParams params; orig_argv0 = argv[0]; @@ -285,13 +106,14 @@ main(int argc, char *argv[]) #endif /* Security enhancements -- mej */ + putenv("IFS= \t"); my_ruid = getuid(); my_euid = geteuid(); my_rgid = getgid(); my_egid = getegid(); privileges(REVERT); + getcwd(initial_dir, PATH_MAX); - TermWin.wm_parent = None; init_defaults(); /* Open display, get options/resources and create the window */ @@ -308,25 +130,7 @@ main(int argc, char *argv[]) } #endif -#ifdef USE_THEMES get_initial_options(argc, argv); -#endif - read_config(); -#ifdef PIXMAP_SUPPORT - if (rs_path) { - rs_path = REALLOC(rs_path, strlen(rs_path) + strlen(initial_dir) + 2); - strcat(rs_path, ":"); - strcat(rs_path, initial_dir); - } -#endif - get_options(argc, argv); -#ifdef USE_ACTIVE_TAGS - tag_init(); -#endif - D_UTMP(("Saved real uid/gid = [ %d, %d ] effective uid/gid = [ %d, %d ]\n", my_ruid, my_rgid, my_euid, my_egid)); - D_UTMP(("Now running with real uid/gid = [ %d, %d ] effective uid/gid = [ %d, %d ]\n", getuid(), getgid(), geteuid(), - getegid())); - #ifdef NEED_LINUX_HACK privileges(INVOKE); /* xdm in new Linux versions requires ruid != root to open the display -- mej */ #endif @@ -334,12 +138,10 @@ main(int argc, char *argv[]) #ifdef NEED_LINUX_HACK privileges(REVERT); #endif - if (!Xdisplay) { print_error("can't open display %s", display_name); exit(EXIT_FAILURE); } - #if DEBUG >= DEBUG_X if (debug_level >= DEBUG_X) { XSetErrorHandler((XErrorHandler) abort); @@ -350,15 +152,68 @@ main(int argc, char *argv[]) XSetErrorHandler((XErrorHandler) xerror_handler); #endif + if (Options & Opt_install) { + cmap = XCreateColormap(Xdisplay, Xroot, Xvisual, AllocNone); + XInstallColormap(Xdisplay, cmap); +#ifdef PIXMAP_SUPPORT + params.cmap = cmap; + params.flags = PARAMS_COLORMAP; +#endif + } else { + cmap = Xcmap; +#ifdef PIXMAP_SUPPORT + params.flags = 0; +#endif + } + /* Since we always use Imlib now, let's initialize it here. */ - imlib_id = Imlib_init(Xdisplay); +#ifdef PIXMAP_SUPPORT + if (params.flags) { + imlib_id = Imlib_init_with_params(Xdisplay, ¶ms); + } else { + imlib_id = Imlib_init(Xdisplay); + } + if (!imlib_id) { + fatal_error("Unable to initialize Imlib. Aborting."); + } +#endif + + read_config(THEME_CFG); + read_config((rs_config_file ? rs_config_file : USER_CFG)); + +#if defined(PIXMAP_SUPPORT) + if (rs_path || theme_dir || user_dir) { + register unsigned long len; + register char *tmp; + + len = strlen(initial_dir); + if (rs_path) { + len += strlen(rs_path) + 1; /* +1 for the colon */ + } + if (theme_dir) { + len += strlen(theme_dir) + 1; + } + if (user_dir) { + len += strlen(user_dir) + 1; + } + tmp = MALLOC(len + 1); /* +1 here for the NUL */ + snprintf(tmp, len + 1, "%s%s%s%s%s%s%s", (rs_path ? rs_path : ""), (rs_path ? ":" : ""), initial_dir, + (theme_dir ? ":" : ""), (theme_dir ? theme_dir : ""), (user_dir ? ":" : ""), (user_dir ? user_dir : "")); + tmp[len] = '\0'; + FREE(rs_path); + rs_path = tmp; + D_OPTIONS(("New rs_path set to \"%s\"\n", rs_path)); + } +#endif + get_options(argc, argv); + D_UTMP(("Saved real uid/gid = [ %d, %d ] effective uid/gid = [ %d, %d ]\n", my_ruid, my_rgid, my_euid, my_egid)); + D_UTMP(("Now running with real uid/gid = [ %d, %d ] effective uid/gid = [ %d, %d ]\n", getuid(), getgid(), geteuid(), + getegid())); post_parse(); #ifdef PREFER_24BIT - Xdepth = DefaultDepth(Xdisplay, Xscreen); - Xcmap = DefaultColormap(Xdisplay, Xscreen); - Xvisual = DefaultVisual(Xdisplay, Xscreen); + cmap = DefaultColormap(Xdisplay, Xscreen); /* * If depth is not 24, look for a 24bit visual. @@ -369,8 +224,8 @@ main(int argc, char *argv[]) if (XMatchVisualInfo(Xdisplay, Xscreen, 24, TrueColor, &vinfo)) { Xdepth = 24; Xvisual = vinfo.visual; - Xcmap = XCreateColormap(Xdisplay, RootWindow(Xdisplay, Xscreen), - Xvisual, AllocNone); + cmap = XCreateColormap(Xdisplay, RootWindow(Xdisplay, Xscreen), + Xvisual, AllocNone); } } #endif @@ -381,13 +236,7 @@ main(int argc, char *argv[]) /* add scrollBar, do it directly to avoid resize() */ scrollbar_mapping(Options & Opt_scrollBar); - /* we can now add menuBar */ - if (delay_menu_drawing) { - delay_menu_drawing = 0; - menubar_mapping(1); - } else if (rs_menubar == *false_vals) { - menubar_mapping(0); - } + #if DEBUG >= DEBUG_X if (debug_level >= DEBUG_X) { XSynchronize(Xdisplay, True); @@ -420,10 +269,10 @@ main(int argc, char *argv[]) sprintf(windowid_string, "WINDOWID=%u", (unsigned int) TermWin.parent); /* add entries to the environment: - * @ DISPLAY: in case we started with -display - * @ WINDOWID: X window id number of the window - * @ COLORTERM: terminal sub-name and also indicates its color - * @ TERM: terminal name + * DISPLAY: in case we started with -display + * WINDOWID: X window id number of the window + * COLORTERM: terminal sub-name and also indicates its color + * TERM: terminal name */ putenv(display_string); putenv(windowid_string); @@ -447,12 +296,9 @@ main(int argc, char *argv[]) putenv("TERM=" TERMENV); #endif } -#ifdef PIXMAP_SUPPORT - putenv("COLORTERM=" COLORTERMENV "-pixmap"); -#else putenv("COLORTERM=" COLORTERMENV); -#endif } + putenv("ETERM_VERSION=" VERSION); D_CMD(("init_command()\n")); init_command(rs_execArgs); diff --git a/src/main.h b/src/main.h index e3b2fed..cb6c581 100644 --- a/src/main.h +++ b/src/main.h @@ -1,90 +1,47 @@ -/*--------------------------------*-C-*---------------------------------* - * File: main.h +/* main.h -- Eterm main program header file + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * */ -/* notes: */ -/*----------------------------------------------------------------------* - * Copyright 1992 John Bovey, University of Kent at Canterbury. - * - * You can do what you like with this source code as long as you don't try - * to make money out of it and you include an unaltered copy of this - * message (including the copyright). - * - * This module has been heavily modified by R. Nation - * - * No additional restrictions are applied - * - * Additional modifications by mj olesen - * No additional restrictions are applied. - * - * As usual, the author accepts no responsibility for anything, nor does - * he guarantee anything whatsoever. - *----------------------------------------------------------------------*/ #ifndef _MAIN_H # define _MAIN_H -# include "config.h" -# include "feature.h" # include -# include +# include /* Xlib, Xutil, Xresource, Xfuncproto */ # include # include - -/* STDC_HEADERS - * don't check for these using configure, since we need them regardless. - * if you don't have them -- figure a workaround. - * - * Sun is often reported as not being STDC_HEADERS, but it's not true - * for our purposes and only generates spurious bug reports. - */ # include # include # include +# include "misc.h" +/************ Macros and Definitions ************/ # ifndef EXIT_SUCCESS /* missing from */ # define EXIT_SUCCESS 0 /* exit function success */ # define EXIT_FAILURE 1 /* exit function failure */ # endif -# include /* Xlib, Xutil, Xresource, Xfuncproto */ -# include "misc.h" - -typedef struct { - int internalBorder; /* Internal border size */ - short width, height; /* window size [pixels] */ - short fwidth, fheight; /* font width and height [pixels] */ - short fprop; /* font is proportional */ - short ncol, nrow; /* window size [characters] */ - short focus; /* window has focus */ - short saveLines; /* number of lines that fit in scrollback */ - short nscrolled; /* number of line actually scrolled */ - short view_start; /* scrollback view starts here */ - Window parent, vt; /* parent (main) and vt100 window */ - Window wm_parent, /* The parent assigned by the WM */ - wm_grandparent; /* The grandparent assigned by the WM */ - GC gc; /* GC for drawing text */ - XFontStruct * font; /* main font structure */ -# ifndef NO_BOLDFONT - XFontStruct * boldFont; /* bold font */ -# endif -# ifdef KANJI - XFontStruct * kanji; /* Kanji font structure */ -# endif -# ifdef PIXMAP_SUPPORT - Pixmap pixmap; -# ifdef PIXMAP_BUFFERING - Pixmap buf_pixmap; -# endif -# endif -} TermWin_t; - -extern TermWin_t TermWin; -extern Window root; -extern Display * Xdisplay; -extern char *def_colorName[]; -extern const char *def_fontName[]; -# ifdef KANJI -extern const char *def_kfontName[]; -# endif +# define THEME_CFG "theme.cfg" +# define USER_CFG "user.cfg" # define MAX_COLS 200 # define MAX_ROWS 128 @@ -99,13 +56,9 @@ extern const char *def_kfontName[]; # ifndef MAX # define MAX(a,b) (((a) > (b)) ? (a) : (b)) # endif - -# define MAX_IT(current, other) if ((other) > (current)) (current) = (other) -# define MIN_IT(current, other) if ((other) < (current)) (current) = (other) -# define SWAP_IT(one, two, tmp) \ -do { \ -(tmp) = (one); (one) = (two); (two) = (tmp); \ -} while (0) +# define MAX_IT(current, other) do {if ((other) > (current)) (current) = (other);} while (0) +# define MIN_IT(current, other) do {if ((other) < (current)) (current) = (other);} while (0) +# define SWAP_IT(one, two, tmp) do {(tmp) = (one); (one) = (two); (two) = (tmp);} while (0) /* width of scrollBar, menuBar shadow ... don't change! */ # define SHADOW 2 @@ -115,7 +68,6 @@ do { \ # define Pixel2Height(y) ((y) / TermWin.fheight) # define Pixel2Col(x) Pixel2Width((x) - TermWin.internalBorder) # define Pixel2Row(y) Pixel2Height((y) - TermWin.internalBorder) - # define Width2Pixel(n) ((n) * TermWin.fwidth) # define Height2Pixel(n) ((n) * TermWin.fheight) # define Col2Pixel(col) (Width2Pixel(col) + TermWin.internalBorder) @@ -128,177 +80,44 @@ do { \ # define Xcmap DefaultColormap(Xdisplay,Xscreen) # define Xdepth DefaultDepth(Xdisplay,Xscreen) # define Xroot DefaultRootWindow(Xdisplay) +# define Xvisual DefaultVisual(Xdisplay, Xscreen) # ifdef DEBUG_DEPTH # undef Xdepth # define Xdepth DEBUG_DEPTH # endif -# define Opt_console (1LU << 0) -# define Opt_loginShell (1LU << 1) -# define Opt_iconic (1LU << 2) -# define Opt_visualBell (1LU << 3) -# define Opt_mapAlert (1LU << 4) -# define Opt_reverseVideo (1LU << 5) -# define Opt_utmpLogging (1LU << 6) -# define Opt_scrollBar (1LU << 7) -# define Opt_meta8 (1LU << 8) -# define Opt_pixmapScale (1LU << 9) -# define Opt_exec (1LU << 10) -# define Opt_homeOnEcho (1LU << 11) -# define Opt_homeOnRefresh (1LU << 12) -# define Opt_scrollBar_floating (1LU << 13) -# define Opt_scrollBar_right (1LU << 14) -# define Opt_borderless (1LU << 15) -# define Opt_pixmapTrans (1LU << 16) -# define Opt_saveUnder (1LU << 17) -# define Opt_noCursor (1LU << 18) -# define Opt_pause (1LU << 19) -# define Opt_watchDesktop (1LU << 20) -# define Opt_homeOnInput (1LU << 21) -# define Opt_menubar_move (1LU << 22) -# define Opt_xterm_select (1LU << 23) -# define Opt_select_whole_line (1LU << 24) -# define Opt_viewport_mode (1LU << 25) -# define Opt_scrollbar_popup (1LU << 26) -# define Opt_select_trailing_spaces (1LU << 24) - -/* place holder used for parsing command-line options */ -# define Opt_Boolean (1LU << 31) -extern unsigned long Options; - -extern const char *display_name; -extern char *rs_name; /* client instance (resource name) */ - -/* - * XTerm escape sequences: ESC ] Ps;Pt BEL - */ -# define XTerm_name 0 -# define XTerm_iconName 1 -# define XTerm_title 2 -# define XTerm_logfile 46 /* not implemented */ -# define XTerm_font 50 - -/* - * rxvt/Eterm extensions of XTerm escape sequences: ESC ] Ps;Pt BEL - */ -# define XTerm_Takeover 5 /* Steal keyboard focus and raise window */ -# define XTerm_EtermSeq 6 /* Eterm proprietary escape sequences */ -# define XTerm_Menu 10 /* set menu item */ -# define XTerm_Pixmap 20 /* new bg pixmap */ -# define XTerm_restoreFG 39 /* change default fg color */ -# define XTerm_restoreBG 49 /* change default bg color */ - -/*----------------------------------------------------------------------*/ - -# define restoreFG 39 /* restore default fg color */ -# define restoreBG 49 /* restore default bg color */ - -enum colour_list { - fgColor, - bgColor, - minColor, /* 2 */ - BlackColor = minColor, - Red3Color, - Green3Color, - Yellow3Color, - Blue3Color, - Magenta3Color, - Cyan3Color, - maxColor, /* minColor + 7 */ -# ifndef NO_BRIGHTCOLOR - AntiqueWhiteColor = maxColor, - minBright, /* maxColor + 1 */ - Grey25Color = minBright, - RedColor, - GreenColor, - YellowColor, - BlueColor, - MagentaColor, - CyanColor, - maxBright, /* minBright + 7 */ - WhiteColor = maxBright, -# else - WhiteColor = maxColor, -# endif -# ifndef NO_CURSORCOLOR - cursorColor, - cursorColor2, -# endif - pointerColor, - borderColor, -# ifndef NO_BOLDUNDERLINE - colorBD, - colorUL, -# endif - menuTextColor, -# if defined(KEEP_SCROLLCOLOR) - scrollColor, -# if defined(CHANGE_SCROLLCOLOR_ON_FOCUS) - unfocusedScrollColor, -# endif -# endif - NRS_COLORS, /* */ -# ifdef KEEP_SCROLLCOLOR - topShadowColor = NRS_COLORS, - bottomShadowColor, -# ifdef CHANGE_SCROLLCOLOR_ON_FOCUS - unfocusedTopShadowColor, - unfocusedBottomShadowColor, -# endif - TOTAL_COLORS /* */ -# else - TOTAL_COLORS = NRS_COLORS /* */ -# endif -}; - -# define NSHADOWCOLORS (TOTAL_COLORS - NRS_COLORS) - -# define DEFAULT_RSTYLE (RS_None | (fgColor<<8) | (bgColor<<16)) - -extern char * rs_color [NRS_COLORS]; -extern Pixel PixColors [NRS_COLORS + NSHADOWCOLORS]; - -# define NFONTS 5 -extern const char * rs_font [NFONTS]; -# ifdef KANJI -extern const char * rs_kfont [NFONTS]; -# endif +/************ Structures ************/ +typedef struct { + int internalBorder; /* Internal border size */ + short width, height; /* window size [pixels] */ + short fwidth, fheight; /* font width and height [pixels] */ + short fprop; /* font is proportional */ + short ncol, nrow; /* window size [characters] */ + short focus; /* window has focus */ + short saveLines; /* number of lines that fit in scrollback */ + short nscrolled; /* number of line actually scrolled */ + short view_start; /* scrollback view starts here */ + Window parent, vt; /* parent (main) and vt100 window */ + GC gc; /* GC for drawing text */ + XFontStruct * font; /* main font structure */ + XFontSet fontset; # ifndef NO_BOLDFONT -extern const char * rs_boldFont; + XFontStruct * boldFont; /* bold font */ # endif - -# ifdef PRINTPIPE -extern char *rs_print_pipe; +# ifdef MULTI_CHARSET + XFontStruct * mfont; /* multibyte font structure */ # endif +} TermWin_t; -# ifdef CUTCHAR_OPTION -extern char * rs_cutchars; -# endif - -/* prototypes */ -_XFUNCPROTOBEGIN - -#ifndef GCC -extern void map_menuBar(int); -extern void map_scrollBar(int); -#else -extern inline void map_menuBar(int); -extern inline void map_scrollBar(int); +/************ Variables ************/ +extern TermWin_t TermWin; +extern Window root; +extern Display *Xdisplay; +extern Colormap cmap; +extern char *orig_argv0; +#ifdef PIXMAP_SUPPORT +extern short bg_needs_update; #endif -extern void xterm_seq(int, const char *); -extern void change_font(int, const char *); -extern void set_width(unsigned short); -extern void resize_window(void); - -/* special (internal) prefix for font commands */ -# define FONT_CMD '#' -# define FONT_DN "#-" -# define FONT_UP "#+" - -# ifdef USE_IMLIB -Pixmap ReadFileToPixmapViaImlib(Display *, char *, int *, int *); -# endif - -_XFUNCPROTOEND +extern const char *display_name; #endif /* whole file */ diff --git a/src/menubar.c b/src/menubar.c deleted file mode 100644 index fef4447..0000000 --- a/src/menubar.c +++ /dev/null @@ -1,2567 +0,0 @@ -/*--------------------------------*-C-*---------------------------------* - * File: menubar.c - * - * Copyright 1996,97 - * mj olesen Queen's Univ at Kingston - * - * You can do what you like with this source code provided you don't make - * money from it and you include an unaltered copy of this message - * (including the copyright). As usual, the author accepts no - * responsibility for anything, nor does he guarantee anything whatsoever. - * - *----------------------------------------------------------------------*/ - -static const char cvs_ident[] = "$Id$"; - -#include "main.h" -#include - -#ifdef HAVE_SYS_SELECT_H -# include -#endif -#ifdef TIME_WITH_SYS_TIME -# include -# include -#else -# ifdef HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -#include "menubar.h" -#include "command.h" -#include "debug.h" -#include "../libmej/debug.h" -#include "mem.h" -#include "misc.h" -#ifdef PIXMAP_MENUBAR -# include "pixmap.h" -# include "options.h" -#endif - -#ifdef KANJI -# ifdef NO_XLOCALE -# include -# else -# include -# endif -static XFontSet fontset = 0; - -#endif - -int delay_menu_drawing; - -extern XSetWindowAttributes Attributes; - -#ifdef PIXMAP_MENUBAR -pixmap_t mbPixmap, mb_selPixmap; - -# ifdef USE_IMLIB -imlib_t imlib_mb, imlib_ms; - -# endif -#endif - -#if (MENUBAR_MAX) -menuitem_t *menuitem_find(menu_t * menu, char *name); -void menuitem_free(menu_t * menu, menuitem_t * item); -int action_type(action_t * action, unsigned char *str); -int action_dispatch(action_t * action); -int menuarrow_find(char name); -void menuarrow_free(char name); -void menuarrow_add(char *string); -menuitem_t *menuitem_add(menu_t * menu, char *name, char *name2, char *action); -char *menu_find_base(menu_t ** menu, char *path); -menu_t *menu_delete(menu_t * menu); -menu_t *menu_add(menu_t * parent, char *path); -void drawbox_menubar(int x, int len, int state); -void drawtriangle(int x, int y, int state); -void drawbox_menuitem(int y, int state); -void print_menu_ancestors(menu_t * menu); -void print_menu_descendants(menu_t * menu); -void menu_show(void); -void menu_display(void (*update) (void)); -void menu_hide_all(void); -void menu_hide(void); -void menu_clear(menu_t * menu); -void menubar_clear(void); -bar_t *menubar_find(const char *name); -int menubar_push(const char *name); -void menubar_remove(const char *name); -void action_decode(FILE * fp, action_t * act); -void menu_dump(FILE * fp, menu_t * menu); -void menubar_dump(FILE * fp); -void menubar_read(const char *filename); -void menubar_dispatch(char *str); -void draw_Arrows(int name, int state); -void menubar_expose(void); -int menubar_mapping(int map); -int menu_select(XButtonEvent * ev); -void menubar_select(XButtonEvent * ev); -void menubar_control(XButtonEvent * ev); - -#define HSPACE 2 -#define MENU_MARGIN 2 -#define menu_height() (TermWin.fheight + 2 * MENU_MARGIN) - -#define MENU_DELAY_USEC 250000 /* 1/4 sec */ - -#define SEPARATOR_HALFHEIGHT (SHADOW + 1) -#define SEPARATOR_HEIGHT (2 * SEPARATOR_HALFHEIGHT) -#define isSeparator(name) ((name)[0] == '\0') - -#define SEPARATOR_NAME "-" -#define MENUITEM_BEG '{' -#define MENUITEM_END '}' -#define COMMENT_CHAR '#' - -#define DOT "." -#define DOTS ".." - -#define Menu_PixelWidth(menu) (2 * SHADOW + Width2Pixel ((menu)->width + 3 * HSPACE)) - -static GC topShadowGC, botShadowGC, neutralGC, menubarGC; - -struct menu_t; - -static int menu_readonly = 1; /* okay to alter menu? */ -static int Arrows_x = 0; - -static const struct { - char name; /* (l)eft, (u)p, (d)own, (r)ight */ - unsigned char *str; /* str[0] = strlen (str+1) */ -} Arrows[NARROWS] = { - - { - 'l', "\003\033[D" - }, - { - 'u', "\003\033[A" - }, - { - 'd', "\003\033[B" - }, - { - 'r', "\003\033[C" - } -}; - -#if (MENUBAR_MAX > 1) -static int Nbars = 0; -static bar_t *CurrentBar = NULL; - -#else /* (MENUBAR_MAX > 1) */ -static bar_t BarList; -static bar_t *CurrentBar = &BarList; - -#endif /* (MENUBAR_MAX > 1) */ - -#ifdef PIXMAP_MENUBAR -menu_t *ActiveMenu = NULL; /* currently active menu */ - -#else -static menu_t *ActiveMenu = NULL; /* currently active menu */ - -#endif - -#ifndef HAVE_MEMMOVE -/* Replacement for memmove() if it's not there -- mej */ -inline void * -memmove(void *s1, const void *s2, size_t size) -{ - - register char *tmp; - register char *dest = (char *) s1; - register const char *source = (const char *) s2; - - if ((tmp = (char *) malloc(size)) == NULL) { - fprintf(stderr, "memmove(): allocation failure for %lu bytes\n", - size); - exit(EXIT_FAILURE); - } - memcpy(tmp, source, size); - memcpy(dest, tmp, size); - free(tmp); - return (dest); -} -#endif /* HAVE_MEMMOVE */ - -/* - * find an item called NAME in MENU - */ -menuitem_t * -menuitem_find(menu_t * menu, char *name) -{ - - menuitem_t *item; - - assert(name != NULL); - assert(menu != NULL); - - D_MENUBAR(("menuitem_find(\"%s\", \"%s\")\n", menu->name, name)); -/* find the last item in the menu, this is good for separators */ - for (item = menu->tail; item != NULL; item = item->prev) { - if (item->entry.type == MenuSubMenu) { - if (!strcmp(name, (item->entry.submenu.menu)->name)) - break; - } else if ((isSeparator(name) && isSeparator(item->name)) || - !strcmp(name, item->name)) - break; - } - return item; -} - -/* - * unlink ITEM from its MENU and free its memory - */ -void -menuitem_free(menu_t * menu, menuitem_t * item) -{ - -/* disconnect */ - menuitem_t *prev, *next; - - assert(menu != NULL); - assert(item != NULL); - - D_MENUBAR(("menuitem_free(\"%s\", \"%s\")\n", menu->name, item->name)); - prev = item->prev; - next = item->next; - if (prev != NULL) - prev->next = next; - if (next != NULL) - next->prev = prev; - -/* new head, tail */ - if (menu->tail == item) - menu->tail = prev; - if (menu->head == item) - menu->head = next; - - switch (item->entry.type) { - case MenuAction: - case MenuTerminalAction: - FREE(item->entry.action.str); - break; - case MenuSubMenu: - menu_delete(item->entry.submenu.menu); - break; - } - if (item->name != NULL) - FREE(item->name); - if (item->name2 != NULL) - FREE(item->name2); - FREE(item); -} - -/* - * sort command vs. terminal actions and - * remove the first character of STR if it's '\0' - */ -int -action_type(action_t * action, unsigned char *str) -{ - - unsigned int len; - - len = parse_escaped_string(str); - D_MENUBAR(("New string is %u bytes\n", len)); - - ASSERT(action != NULL); - - if (!len) - return -1; - -/* sort command vs. terminal actions */ - action->type = MenuAction; - if (str[0] == '\0') { - /* the functional equivalent: memmove (str, str+1, len); */ - unsigned char *dst = (str); - unsigned char *src = (str + 1); - unsigned char *end = (str + len); - - while (src <= end) - *dst++ = *src++; - - len--; /* decrement length */ - if (str[0] != '\0') - action->type = MenuTerminalAction; - } - action->str = str; - action->len = len; - - return 0; -} - -int -action_dispatch(action_t * action) -{ - - assert(action != NULL); - D_MENUBAR(("action_dispatch(\"%s\")\n", action->str)); - - switch (action->type) { - case MenuTerminalAction: - cmd_write(action->str, action->len); - break; - - case MenuAction: - tt_write(action->str, action->len); - break; - - default: - return -1; - break; - } - return 0; -} - -/* return the arrow index corresponding to NAME */ -int -menuarrow_find(char name) -{ - - int i; - - D_MENUARROWS(("menuarrow_find(\'%c\')\n", name)); - - for (i = 0; i < NARROWS; i++) { - if (name == Arrows[i].name) - return (i); - } - return (-1); -} - -/* free the memory associated with arrow NAME of the current menubar */ -void -menuarrow_free(char name) -{ - - int i; - - D_MENUARROWS(("menuarrow_free(\'%c\')\n", name)); - - if (name) { - i = menuarrow_find(name); - if (i >= 0) { - action_t *act = &(CurrentBar->arrows[i]); - - switch (act->type) { - case MenuAction: - case MenuTerminalAction: - FREE(act->str); - act->str = NULL; - act->len = 0; - break; - } - act->type = MenuLabel; - } - } else { - for (i = 0; i < NARROWS; i++) - menuarrow_free(Arrows[i].name); - } -} - -void -menuarrow_add(char *string) -{ - - int i; - unsigned xtra_len; - char *p; - struct { - char *str; - int len; - } beg = { - NULL, 0 - }, end = { - NULL, 0 - }, *cur, parse[NARROWS]; - - D_MENUARROWS(("menuarrow_add(\"%s\")\n", string)); - - memset(parse, 0, sizeof(parse)); - - for (p = string; p != NULL && *p; string = p) { - p = (string + 3); - D_MENUARROWS(("parsing at %s\n", string)); - switch (string[1]) { - case 'b': - cur = &beg; - break; - case 'e': - cur = &end; - break; - default: - i = menuarrow_find(string[1]); - if (i >= 0) - cur = &(parse[i]); - else - continue; /* not found */ - break; - } - - string = p; - cur->str = string; - cur->len = 0; - - if (cur == &end) { - p = strchr(string, '\0'); - } else { - char *next = string; - - while (1) { - p = strchr(next, '<'); - if (p != NULL) { - if (p[1] && p[2] == '>') - break; - /* parsed */ - } else { - if (beg.str == NULL) /* no end needed */ - p = strchr(next, '\0'); - break; - } - next = (p + 1); - } - } - - if (p == NULL) - return; - cur->len = (p - string); - } - -#if DEBUG >= DEBUG_MENUARROWS - if (debug_level >= DEBUG_MENUARROWS) { - cur = &beg; - DPRINTF1(("(len %d) = %.*s\n", cur->len, cur->len, (cur->str ? cur->str : ""))); - for (i = 0; i < NARROWS; i++) { - cur = &(parse[i]); - DPRINTF1(("<%c>(len %d) = %.*s\n", Arrows[i].name, cur->len, cur->len, (cur->str ? cur->str : ""))); - } - cur = &end; - DPRINTF1(("(len %d) = %.*s\n", cur->len, cur->len, (cur->str ? cur->str : ""))); - } -#endif - - xtra_len = (beg.len + end.len); - for (i = 0; i < NARROWS; i++) { - if (xtra_len || parse[i].len) - menuarrow_free(Arrows[i].name); - } - - for (i = 0; i < NARROWS; i++) { - - unsigned char *str; - unsigned int len; - - if (!parse[i].len) - continue; - - str = MALLOC(parse[i].len + xtra_len + 1); - if (str == NULL) - continue; - - len = 0; - if (beg.len) { - strncpy(str + len, beg.str, beg.len); - len += beg.len; - } - strncpy(str + len, parse[i].str, parse[i].len); - len += parse[i].len; - - if (end.len) { - strncpy(str + len, end.str, end.len); - len += end.len; - } - str[len] = '\0'; - - D_MENUARROWS(("<%c>(len %d) = %s\n", Arrows[i].name, len, str)); - if (action_type(&(CurrentBar->arrows[i]), str) < 0) - FREE(str); - } -} - -menuitem_t * -menuitem_add(menu_t * menu, char *name, char *name2, char *action) -{ - - menuitem_t *item = NULL; - unsigned int len; - unsigned char found = 0; - - assert(name != NULL); - assert(action != NULL); - - if (menu == NULL) - return NULL; - - D_MENUBAR(("menuitem_add(\"%s\", \"%s\", \"%s\", \"%s\")\n", menu->name, name, (name2 ? name2 : ""), action)); - - if (isSeparator(name)) { - /* add separator, no action */ - name = ""; - action = ""; - } else { - /* - * add/replace existing menu item - */ - item = menuitem_find(menu, name); - if (item != NULL) { - if (item->name2 != NULL && name2 != NULL) { - FREE(item->name2); - item->len2 = 0; - item->name2 = NULL; - } - switch (item->entry.type) { - case MenuAction: - case MenuTerminalAction: - FREE(item->entry.action.str); - item->entry.action.str = NULL; - break; - } - found = 1; - } - } - - if (!found) { - - /* allocate a new itemect */ - if ((item = (menuitem_t *) MALLOC(sizeof(menuitem_t))) == NULL) - return NULL; - - item->len2 = 0; - item->name2 = NULL; - - len = strlen(name); - item->name = MALLOC(len + 1); - if (item->name != NULL) { - strcpy(item->name, name); - if (name[0] == '.' && name[1] != '.') - len = 0; /* hidden menu name */ - } else { - FREE(item); - return NULL; - } - item->len = len; - - /* add to tail of list */ - item->prev = menu->tail; - item->next = NULL; - - if (menu->tail != NULL) - (menu->tail)->next = item; - menu->tail = item; - /* fix head */ - if (menu->head == NULL) - menu->head = item; - } - /* - * add action - */ - if (name2 != NULL && item->name2 == NULL) { - len = strlen(name2); - if (len == 0 || (item->name2 = MALLOC(len + 1)) == NULL) { - len = 0; - item->name2 = NULL; - } else { - strcpy(item->name2, name2); - } - item->len2 = len; - } - item->entry.type = MenuLabel; - len = strlen(action); - - if (len == 0 && item->name2 != NULL) { - action = item->name2; - len = item->len2; - } - if (len) { - unsigned char *str = MALLOC(len + 1); - - if (str == NULL) { - menuitem_free(menu, item); - return NULL; - } - strcpy(str, action); - - if (action_type(&(item->entry.action), str) < 0) - FREE(str); - } - /* new item and a possible increase in width */ - if (menu->width < (item->len + item->len2)) - menu->width = (item->len + item->len2); - - return item; -} - -/* - * search for the base starting menu for NAME. - * return a pointer to the portion of NAME that remains - */ -char * -menu_find_base(menu_t ** menu, char *path) -{ - - menu_t *m = NULL; - menuitem_t *item; - - assert(menu != NULL); - assert(CurrentBar != NULL); - - D_MENUBAR(("menu_find_base(0x%08x, \"%s\")\n", menu, path)); - - if (path[0] == '\0') - return path; - - if (strchr(path, '/') != NULL) { - register char *p = path; - - while ((p = strchr(p, '/')) != NULL) { - p++; - if (*p == '/') - path = p; - } - if (path[0] == '/') { - path++; - *menu = NULL; - } - while ((p = strchr(path, '/')) != NULL) { - p[0] = '\0'; - if (path[0] == '\0') - return NULL; - if (!strcmp(path, DOT)) { - /* nothing to do */ - } else if (!strcmp(path, DOTS)) { - if (*menu != NULL) - *menu = (*menu)->parent; - } else { - path = menu_find_base(menu, path); - if (path[0] != '\0') { /* not found */ - p[0] = '/'; /* fix-up name again */ - return path; - } - } - - path = (p + 1); - } - } - if (!strcmp(path, DOTS)) { - path += strlen(DOTS); - if (*menu != NULL) - *menu = (*menu)->parent; - return path; - } - /* find this menu */ - if (*menu == NULL) { - for (m = CurrentBar->tail; m != NULL; m = m->prev) { - if (!strcmp(path, m->name)) - break; - } - } else { - /* find this menu */ - for (item = (*menu)->tail; item != NULL; item = item->prev) { - if (item->entry.type == MenuSubMenu && - !strcmp(path, (item->entry.submenu.menu)->name)) { - m = (item->entry.submenu.menu); - break; - } - } - } - if (m != NULL) { - *menu = m; - path += strlen(path); - } - return path; -} - -/* - * delete this entire menu - */ -menu_t * -menu_delete(menu_t * menu) -{ - - menu_t *parent = NULL, *prev, *next; - menuitem_t *item; - - assert(CurrentBar != NULL); - if (menu == NULL) - return NULL; - - D_MENUBAR(("menu_delete(\"%s\")\n", menu->name)); - -/* delete the entire menu */ - parent = menu->parent; - -/* unlink MENU */ - prev = menu->prev; - next = menu->next; - if (prev != NULL) - prev->next = next; - if (next != NULL) - next->prev = prev; - -/* fix the index */ - if (parent == NULL) { - const int len = (menu->len + HSPACE); - - if (CurrentBar->tail == menu) - CurrentBar->tail = prev; - if (CurrentBar->head == menu) - CurrentBar->head = next; - - for (next = menu->next; next != NULL; next = next->next) - next->x -= len; - } else { - for (item = parent->tail; item != NULL; item = item->prev) { - if (item->entry.type == MenuSubMenu && - item->entry.submenu.menu == menu) { - item->entry.submenu.menu = NULL; - menuitem_free(menu->parent, item); - break; - } - } - } - - item = menu->tail; - while (item != NULL) { - menuitem_t *p = item->prev; - - menuitem_free(menu, item); - item = p; - } - - if (menu->name != NULL) - FREE(menu->name); - FREE(menu); - - return parent; -} - -menu_t * -menu_add(menu_t * parent, char *path) -{ - - menu_t *menu; - - assert(CurrentBar != NULL); - - D_MENUBAR(("menu_add(\"%s\", \"%s\")\n", (parent ? parent->name : ""), path)); - - if (strchr(path, '/') != NULL) { - register char *p; - - if (path[0] == '/') { - /* shouldn't happen */ - path++; - parent = NULL; - } - while ((p = strchr(path, '/')) != NULL) { - p[0] = '\0'; - if (path[0] == '\0') - return NULL; - - parent = menu_add(parent, path); - path = (p + 1); - } - } - if (!strcmp(path, DOTS)) - return (parent != NULL ? parent->parent : parent); - - if (!strcmp(path, DOT) || path[0] == '\0') - return parent; - -/* allocate a new menu */ - if ((menu = (menu_t *) MALLOC(sizeof(menu_t))) == NULL) - return parent; - - menu->width = 0; - menu->parent = parent; - menu->len = strlen(path); - menu->name = MALLOC((menu->len + 1)); - if (menu->name == NULL) { - FREE(menu); - return parent; - } - strcpy(menu->name, path); - -/* initialize head/tail */ - menu->head = menu->tail = NULL; - menu->prev = menu->next = NULL; - - menu->win = None; - menu->x = menu->y = menu->w = menu->h = 0; - menu->item = NULL; - -/* add to tail of list */ - if (parent == NULL) { - menu->prev = CurrentBar->tail; - if (CurrentBar->tail != NULL) - CurrentBar->tail->next = menu; - CurrentBar->tail = menu; - if (CurrentBar->head == NULL) - CurrentBar->head = menu; /* fix head */ - if (menu->prev) - menu->x = (menu->prev->x + menu->prev->len + HSPACE); - } else { - menuitem_t *item; - - item = menuitem_add(parent, path, "", ""); - if (item == NULL) { - FREE(menu); - return parent; - } - assert(item->entry.type == MenuLabel); - item->entry.type = MenuSubMenu; - item->entry.submenu.menu = menu; - } - - return menu; -} - -void -drawbox_menubar(int x, int len, int state) -{ - - GC top = None, bot = None; - - x = Width2Pixel(x); - len = Width2Pixel(len + HSPACE); - if (x >= TermWin.width) - return; - else if (x + len >= TermWin.width) - len = (TermWin_TotalWidth() - x); - -#ifdef MENUBAR_SHADOW_IN - state = -state; -#endif - switch (state) { - case +1: - top = topShadowGC; - bot = botShadowGC; - break; /* SHADOW_OUT */ - case -1: - top = botShadowGC; - bot = topShadowGC; - break; /* SHADOW_IN */ - case 0: - top = bot = neutralGC; - break; /* neutral */ - } - - if (!(menubar_is_pixmapped())) - Draw_Shadow(menuBar.win, top, bot, - x, 0, len, menuBar_TotalHeight()); -} - -void -drawtriangle(int x, int y, int state) -{ - - GC top = None, bot = None; - int w; - -#ifdef MENUBAR_SHADOW_IN - state = -state; -#endif - switch (state) { - case +1: - top = topShadowGC; - bot = botShadowGC; - break; /* SHADOW_OUT */ - case -1: - top = botShadowGC; - bot = topShadowGC; - break; /* SHADOW_IN */ - case 0: - top = bot = neutralGC; - break; /* neutral */ - } - - w = menu_height() / 2; - - x -= (SHADOW + MENU_MARGIN) + (3 * w / 2); - y += (SHADOW + MENU_MARGIN) + (w / 2); - - Draw_Triangle(ActiveMenu->win, top, bot, x, y, w, 'r'); -} - -void -drawbox_menuitem(int y, int state) -{ - - GC top = None, bot = None; - -#ifdef MENU_SHADOW_IN - state = -state; -#endif - switch (state) { - case +1: - top = topShadowGC; - bot = botShadowGC; - break; /* SHADOW_OUT */ - case -1: - top = botShadowGC; - bot = topShadowGC; - break; /* SHADOW_IN */ - case 0: - top = bot = neutralGC; - break; /* neutral */ - } - - if (!(menubar_is_pixmapped())) - Draw_Shadow(ActiveMenu->win, top, bot, - SHADOW + 0, - SHADOW + y, - ActiveMenu->w - 2 * (SHADOW), - menu_height() + 2 * MENU_MARGIN); - XFlush(Xdisplay); -} - -#if DEBUG >= DEBUG_MENU_LAYOUT -void -print_menu_ancestors(menu_t * menu) -{ - - if (menu == NULL) { - D_MENU_LAYOUT(("Top Level menu\n")); - return; - } - D_MENU_LAYOUT(("menu %s ", menu->name)); - if (menu->parent != NULL) { - menuitem_t *item; - - for (item = menu->parent->head; item != NULL; item = item->next) { - if (item->entry.type == MenuSubMenu && - item->entry.submenu.menu == menu) { - break; - } - } - if (item == NULL) { - fprintf(stderr, "is an orphan!\n"); - return; - } - } - fprintf(stderr, "\n"); - print_menu_ancestors(menu->parent); -} - -void -print_menu_descendants(menu_t * menu) -{ - - menuitem_t *item; - menu_t *parent; - int i, level = 0; - - parent = menu; - do { - level++; - parent = parent->parent; - } - while (parent != NULL); - - for (i = 0; i < level; i++) - fprintf(stderr, ">"); - fprintf(stderr, "%s\n", menu->name); - - for (item = menu->head; item != NULL; item = item->next) { - if (item->entry.type == MenuSubMenu) { - if (item->entry.submenu.menu == NULL) - fprintf(stderr, "> %s == NULL\n", item->name); - else - print_menu_descendants(item->entry.submenu.menu); - } else { - for (i = 0; i < level; i++) - fprintf(stderr, "+"); - if (item->entry.type == MenuLabel) - fprintf(stderr, "label: "); - fprintf(stderr, "%s\n", item->name); - } - } - - for (i = 0; i < level; i++) - fprintf(stderr, "<"); - fprintf(stderr, "\n"); -} -#endif - -/* pop up/down the current menu and redraw the menuBar button */ -void -menu_show(void) -{ - - int x, y, newx, newy, xright; - menuitem_t *item; - XSetWindowAttributes attr = Attributes; - Window true_parent; - - if (ActiveMenu == NULL) - return; - - attr.override_redirect = TRUE; - x = ActiveMenu->x; - if (ActiveMenu->parent == NULL) { - register int h; - - drawbox_menubar(x, ActiveMenu->len, -1); - x = Width2Pixel(x); - - ActiveMenu->y = 1; - ActiveMenu->w = Menu_PixelWidth(ActiveMenu); - - /* find the height */ - for (h = 0, item = ActiveMenu->head; item != NULL; item = item->next) { - if (isSeparator(item->name)) - h += SEPARATOR_HEIGHT; - else - h += menu_height(); - } - ActiveMenu->h = h + 2 * (SHADOW + MENU_MARGIN); - } - if (ActiveMenu->win == None) { - XTranslateCoordinates(Xdisplay, TermWin.vt, Xroot, 0, 0, &newx, &newy, &true_parent); - if (x < newx) { - x += newx; - } - if (x + ActiveMenu->w >= (ScreenOfDisplay(Xdisplay, Xscreen))->width) { - register int dx = ((ActiveMenu->w + x) - (ScreenOfDisplay(Xdisplay, Xscreen))->width); - - x -= dx; - ActiveMenu->x -= dx; - } - y = ActiveMenu->y + newy; - if (y + ActiveMenu->h >= (ScreenOfDisplay(Xdisplay, Xscreen))->height) { - register int dy = ((ActiveMenu->h + y) - (ScreenOfDisplay(Xdisplay, Xscreen))->height); - - y -= dy; - ActiveMenu->y -= dy; - } - ActiveMenu->win = XCreateWindow(Xdisplay, Xroot, - x, - y, - ActiveMenu->w, - ActiveMenu->h, - 0, - Xdepth, InputOutput, - DefaultVisual(Xdisplay, Xscreen), - CWBackPixel | CWBorderPixel - | CWColormap | CWOverrideRedirect - | CWSaveUnder | CWBackingStore, - &attr - ); - - XMapWindow(Xdisplay, ActiveMenu->win); - } - if (!(menubar_is_pixmapped())) - Draw_Shadow(ActiveMenu->win, - topShadowGC, botShadowGC, - 0, 0, - ActiveMenu->w, ActiveMenu->h); - - /* determine the correct right-alignment */ - for (xright = 0, item = ActiveMenu->head; item != NULL; item = item->next) { - if (item->len2 > xright) { - xright = item->len2; - } - } - D_MENU_LAYOUT(("xright == %d\n", xright)); - - for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next) { - - const int xoff = (SHADOW + Width2Pixel(HSPACE) / 2); - const int yoff = (SHADOW + MENU_MARGIN); - register int h; - GC gc = menubarGC; - - if (isSeparator(item->name)) { - if (!(menubar_is_pixmapped())) - Draw_Shadow(ActiveMenu->win, - topShadowGC, botShadowGC, - xoff, - yoff + y + SEPARATOR_HALFHEIGHT, - ActiveMenu->w - (2 * xoff), - 0); - h = SEPARATOR_HEIGHT; - } else { - char *name = item->name; - int len = item->len; - - if (item->entry.type == MenuLabel) { - gc = botShadowGC; - } else if (item->entry.type == MenuSubMenu) { - register int x1, y1; - menuitem_t *it; - menu_t *menu = item->entry.submenu.menu; - - drawtriangle(ActiveMenu->w, y, +1); - - name = menu->name; - len = menu->len; - - y1 = ActiveMenu->y + y; - - /* place sub-menu at midpoint of parent menu */ - menu->w = Menu_PixelWidth(menu); - x1 = ActiveMenu->w / 2; - - /* right-flush menu if it's too small */ - if (x1 > menu->w) - x1 += (x1 - menu->w); - x1 += x; - - /* find the height of this submenu */ - for (h = 0, it = menu->head; it != NULL; it = it->next) { - if (isSeparator(it->name)) - h += SEPARATOR_HEIGHT; - else - h += menu_height(); - } - menu->h = h + 2 * (SHADOW + MENU_MARGIN); - - menu->x = x1; - menu->y = y1; - } else if (item->name2 && !strcmp(name, item->name2)) - name = NULL; - - if (len && name) { - D_MENU_LAYOUT(("len == %d, name == %s\n", len, name)); -#ifdef KANJI - if (fontset) - XmbDrawString(Xdisplay, - ActiveMenu->win, fontset, gc, - xoff, - yoff + y + menu_height() - (MENU_MARGIN + TermWin.font->descent), - name, len); - else -#endif - XDrawString(Xdisplay, - ActiveMenu->win, gc, - xoff, - yoff + y + menu_height() - (MENU_MARGIN + TermWin.font->descent), - name, len); - } - len = item->len2; - name = item->name2; - if (len && name) { - D_MENU_LAYOUT(("len2 == %d, name2 == %s\n", len, name)); -#ifdef KANJI - if (fontset) - XmbDrawString(Xdisplay, - ActiveMenu->win, fontset, gc, - ActiveMenu->w - (xoff + Width2Pixel(xright)), - yoff + y + menu_height() - (MENU_MARGIN + TermWin.font->descent), - name, len); - else -#endif - XDrawString(Xdisplay, - ActiveMenu->win, gc, - ActiveMenu->w - (xoff + Width2Pixel(xright)), - yoff + y + menu_height() - (MENU_MARGIN + TermWin.font->descent), - name, len); - } - h = menu_height(); - } - y += h; - } -} -void -menu_display(void (*update) (void)) -{ - - D_MENUBAR(("menu_display(0x%08x)\n", update)); - - if (ActiveMenu == NULL) - return; - - if (ActiveMenu->win != None) { - XDestroyWindow(Xdisplay, ActiveMenu->win); - ActiveMenu->win = None; - } - ActiveMenu->item = NULL; - - if (ActiveMenu->parent == NULL) - drawbox_menubar(ActiveMenu->x, ActiveMenu->len, +1); - ActiveMenu = ActiveMenu->parent; - update(); -} - -void -menu_hide_all(void) -{ - - D_MENUBAR(("menu_hide_all()\n")); - menu_display(menu_hide_all); -} void -menu_hide(void) -{ - - D_MENUBAR(("menu_hide()\n")); - menu_display(menu_show); -} void - -menu_clear(menu_t * menu) -{ - - D_MENUBAR(("menu_clear(\"%s\")\n", (menu ? menu->name : ""))); - - if (menu != NULL) { - menuitem_t *item = menu->tail; - - while (item != NULL) { - menuitem_free(menu, item); - /* it didn't get freed ... why? */ - if (item == menu->tail) - return; - item = menu->tail; - } - menu->width = 0; - } -} - -void -menubar_clear(void) -{ - - if (CurrentBar != NULL) { - menu_t *menu = CurrentBar->tail; - - while (menu != NULL) { - menu_t *prev = menu->prev; - - menu_delete(menu); - menu = prev; - } - CurrentBar->head = CurrentBar->tail = ActiveMenu = NULL; - - if (CurrentBar->title) { - FREE(CurrentBar->title); - CurrentBar->title = NULL; - } - menuarrow_free(0); /* remove all arrow functions */ - } - ActiveMenu = NULL; -} - -#if (MENUBAR_MAX > 1) -/* find if menu already exists */ -bar_t * -menubar_find(const char *name) -{ - - bar_t *bar = CurrentBar; - - D_MENUBAR_STACKING(("looking for [menu:%s]...\n", name ? name : "(nil)")); - if (bar == NULL || name == NULL) - return NULL; - - if (strlen(name) && strcmp(name, "*")) { - do { - if (!strcmp(bar->name, name)) { - D_MENUBAR_STACKING(("Found!\n")); - return bar; - } - bar = bar->next; - } - while (bar != CurrentBar); - bar = NULL; - } - D_MENUBAR_STACKING(("%s found!\n", (bar ? "" : " NOT"))); - return bar; -} - -int -menubar_push(const char *name) -{ - - int ret = 1; - bar_t *bar; - - if (CurrentBar == NULL) { - /* allocate first one */ - bar = (bar_t *) MALLOC(sizeof(bar_t)); - - if (bar == NULL) - return 0; - - memset(bar, 0, sizeof(bar_t)); - /* circular linked-list */ - bar->next = bar->prev = bar; - bar->head = bar->tail = NULL; - bar->title = NULL; - CurrentBar = bar; - Nbars++; - - menubar_clear(); - } else { - /* find if menu already exists */ - bar = menubar_find(name); - if (bar != NULL) { - /* found it, use it */ - CurrentBar = bar; - } else { - /* create if needed, or reuse the existing empty menubar */ - if (CurrentBar->head != NULL) { - /* need to malloc another one */ - if (Nbars < MENUBAR_MAX) - bar = (bar_t *) MALLOC(sizeof(bar_t)); - else - bar = NULL; - - /* malloc failed or too many menubars, reuse another */ - if (bar == NULL) { - bar = CurrentBar->next; - ret = -1; - } else { - bar->head = bar->tail = NULL; - bar->title = NULL; - - bar->next = CurrentBar->next; - CurrentBar->next = bar; - bar->prev = CurrentBar; - bar->next->prev = bar; - - Nbars++; - } - CurrentBar = bar; - - } - menubar_clear(); - } - } - -/* give menubar this name */ - strncpy(CurrentBar->name, name, MAXNAME); - CurrentBar->name[MAXNAME - 1] = '\0'; - - return ret; -} - -/* switch to a menu called NAME and remove it */ -void -menubar_remove(const char *name) -{ - - bar_t *bar; - - if ((bar = menubar_find(name)) == NULL) - return; - CurrentBar = bar; - - do { - menubar_clear(); - /* - * pop a menubar, clean it up first - */ - if (CurrentBar != NULL) { - bar_t *prev = CurrentBar->prev; - bar_t *next = CurrentBar->next; - - if (prev == next && prev == CurrentBar) { /* only 1 left */ - prev = NULL; - Nbars = 0; /* safety */ - } else { - next->prev = prev; - prev->next = next; - Nbars--; - } - - FREE(CurrentBar); - CurrentBar = prev; - } - } - while (CurrentBar && !strcmp(name, "*")); -} - -void -action_decode(FILE * fp, action_t * act) -{ - - unsigned char *str; - short len; - - if (act == NULL || (len = act->len) == 0 || (str = act->str) == NULL) - return; - - if (act->type == MenuTerminalAction) { - fprintf(fp, "^@"); - /* can strip trailing ^G from XTerm sequence */ - if (str[0] == 033 && str[1] == ']' && str[len - 1] == 007) - len--; - } else if (str[0] == 033) { - switch (str[1]) { - case '[': - case ']': - break; - - case 'x': - /* can strip trailing '\r' from M-x sequence */ - if (str[len - 1] == '\r') - len--; - /* drop */ - - default: - fprintf(fp, "M-"); /* meta prefix */ - str++; - len--; - break; - } - } -/* - * control character form is preferred, since backslash-escaping - * can be really ugly looking when the backslashes themselves also - * have to be escaped to avoid Shell (or whatever scripting - * language) interpretation - */ - while (len > 0) { - unsigned char ch = *str++; - - switch (ch) { - case 033: - fprintf(fp, "\\e"); - break; /* escape */ - case '\r': - fprintf(fp, "\\r"); - break; /* carriage-return */ - case '\\': - fprintf(fp, "\\\\"); - break; /* backslash */ - case '^': - fprintf(fp, "\\^"); - break; /* caret */ - case 127: - fprintf(fp, "^?"); - default: - if (ch <= 31) - fprintf(fp, "^%c", ('@' + ch)); - else if (ch > 127) - fprintf(fp, "\\%o", ch); - else - fprintf(fp, "%c", ch); - break; - } - len--; - } - fprintf(fp, "\n"); -} - -void -menu_dump(FILE * fp, menu_t * menu) -{ - - menuitem_t *item; - -/* create a new menu and clear it */ - fprintf(fp, (menu->parent ? "./%s/*\n" : "/%s/*\n"), menu->name); - - for (item = menu->head; item != NULL; item = item->next) { - switch (item->entry.type) { - case MenuSubMenu: - if (item->entry.submenu.menu == NULL) - fprintf(fp, "> %s == NULL\n", item->name); - else - menu_dump(fp, item->entry.submenu.menu); - break; - - case MenuLabel: - fprintf(fp, "{%s}\n", - (strlen(item->name) ? item->name : "-")); - break; - - case MenuTerminalAction: - case MenuAction: - fprintf(fp, "{%s}", item->name); - if (item->name2 != NULL && strlen(item->name2)) - fprintf(fp, "{%s}", item->name2); - fprintf(fp, "\t"); - action_decode(fp, &(item->entry.action)); - break; - } - } - fprintf(fp, (menu->parent ? "../\n" : "/\n\n")); -} - -void -menubar_dump(FILE * fp) -{ - - bar_t *bar = CurrentBar; - time_t t; - - if (bar == NULL || fp == NULL) - return; - time(&t); - - fprintf(fp, - "# " APL_NAME " (%s) Pid: %u\n# Date: %s\n\n", - rs_name, (unsigned int) getpid(), ctime(&t)); - -/* dump in reverse order */ - bar = CurrentBar->prev; - do { - menu_t *menu; - int i; - - fprintf(fp, "[menu:%s]\n", bar->name); - - if (bar->title != NULL) - fprintf(fp, "[title:%s]\n", bar->title); - - for (i = 0; i < NARROWS; i++) { - switch (bar->arrows[i].type) { - case MenuTerminalAction: - case MenuAction: - fprintf(fp, "<%c>", Arrows[i].name); - action_decode(fp, &(bar->arrows[i])); - break; - } - } - fprintf(fp, "\n"); - - for (menu = bar->head; menu != NULL; menu = menu->next) - menu_dump(fp, menu); - - fprintf(fp, "\n[done:%s]\n\n", bar->name); - bar = bar->prev; - } - while (bar != CurrentBar->prev); -} -#endif /* (MENUBAR_MAX > 1) */ - -/* - * read in menubar commands from FILENAME - * ignore all input before the tag line [menu] or [menu:???] - * - * Note that since File_find () is used, FILENAME can be semi-colon - * delimited such that the second part can refer to a tag - * so that a large `database' of menus can be collected together - * - * FILENAME = "file" - * FILENAME = "file;" - * read `file' starting with first [menu] or [menu:???] line - * - * FILENAME = "file;tag" - * read `file' starting with [menu:tag] - */ -void -menubar_read(const char *filename) -{ - -/* read in a menu from a file */ - FILE *fp; - char buffer[256]; - char *p, *tag = NULL; - const char *file; - - if (!filename || !strlen(filename)) - return; - - file = find_file(filename, ".menu"); - if (file == NULL || (fp = fopen(file, "rb")) == NULL) { - return; - } -#if (MENUBAR_MAX > 1) - /* semi-colon delimited */ - if ((tag = strchr(filename, ';')) != NULL) { - tag++; - if (*tag == '\0') { - tag = NULL; - } - } -#endif /* (MENUBAR_MAX > 1) */ - - D_MENUBAR(("looking for [menu:%s]\n", tag ? tag : "(nil)")); - - while ((p = fgets(buffer, sizeof(buffer), fp)) != NULL) { - - int n; - - D_MENUBAR(("Got \"%s\"\n", p)); - - if ((n = str_leading_match(p, "[menu")) != 0) { - if (tag) { - /* looking for [menu:tag] */ - if (p[n] == ':' && p[n + 1] != ']') { - n++; - n += str_leading_match(p + n, tag); - if (p[n] == ']') { - D_MENUBAR(("[menu:%s]\n", tag)); - break; - } - } - } else if (p[n] == ':' || p[n] == ']') - break; - } - } - -/* found [menu], [menu:???] tag */ - while (p != NULL) { - - int n; - - D_MENUBAR(("read line = %s\n", p)); - - /* looking for [done:tag] or [done:] */ - if ((n = str_leading_match(p, "[done")) != 0) { - if (p[n] == ']') { - menu_readonly = 1; - break; - } else if (p[n] == ':') { - n++; - if (p[n] == ']') { - menu_readonly = 1; - break; - } else if (tag) { - n += str_leading_match(p + n, tag); - if (p[n] == ']') { - D_MENUBAR(("[done:%s]\n", tag)); - menu_readonly = 1; - break; - } - } else { - /* what? ... skip this line */ - p[0] = COMMENT_CHAR; - } - } - } - /* - * remove leading/trailing space - * and strip-off leading/trailing quotes - * skip blank or comment lines - */ - p = str_trim(p); - if (p != NULL && *p && *p != COMMENT_CHAR) { - menu_readonly = 0; /* if case we read another file */ - menubar_dispatch(p); - } - /* get another line */ - p = fgets(buffer, sizeof(buffer), fp); - } - - fclose(fp); -} - -/* - * user interface for building/deleting and otherwise managing menus - */ -void -menubar_dispatch(char *str) -{ - - static menu_t *BuildMenu = NULL; /* the menu currently being built */ - int n, cmd; - char *path, *name, *name2; - - D_MENUBAR(("menubar_dispatch(%s) called\n", str)); - - if (menubar_visible() && ActiveMenu != NULL) - menubar_expose(); - else - ActiveMenu = NULL; - - cmd = *str; - switch (cmd) { - case '.': - case '/': /* absolute & relative path */ - case MENUITEM_BEG: /* menuitem */ - /* add `+' prefix for these cases */ - cmd = '+'; - break; - - case '+': - case '-': - str++; /* skip cmd character */ - break; - - case '<': -#if (MENUBAR_MAX > 1) - if (CurrentBar == NULL) - break; -#endif /* (MENUBAR_MAX > 1) */ - if (str[1] && str[2] == '>') /* arrow commands */ - menuarrow_add(str); - break; - - case '=': - D_MENUBAR(("Setting title\n")); - str++; - if (CurrentBar != NULL && !menu_readonly) { - if (*str) { - name = REALLOC(CurrentBar->title, strlen(str) + 1); - if (name != NULL) { - strcpy(name, str); - CurrentBar->title = name; - } - menubar_expose(); - } else { - FREE(CurrentBar->title); - CurrentBar->title = NULL; - } - } - break; - - case '[': /* extended command */ - while (str[0] == '[') { - char *next = (++str); /* skip leading '[' */ - - if (str[0] == ':') { /* [:command:] */ - do { - next++; - if ((next = strchr(next, ':')) == NULL) - return; /* parse error */ - } while (next[1] != ']'); - - /* remove and skip ':]' */ - *next = '\0'; - next += 2; - } else { - if ((next = strchr(next, ']')) == NULL) - return; /* parse error */ - /* remove and skip ']' */ - *next = '\0'; - next++; - } - - if (str[0] == ':') { - int saved; - - /* try and dispatch it, regardless of read/write status */ - D_MENUBAR(("Ignoring read-only status to parse command %s\n", str + 1)); - saved = menu_readonly; - menu_readonly = 0; - menubar_dispatch(str + 1); - menu_readonly = saved; - } - /* these ones don't require menu stacking */ - else if (!strcmp(str, "clear")) { - D_MENUBAR(("Extended command \"clear\"\n")); - menubar_clear(); - } else if (!strcmp(str, "done") || str_leading_match(str, "done:")) { - D_MENUBAR(("Extended command \"done\"\n")); - menu_readonly = 1; - } else if (!strcmp(str, "show")) { - D_MENUBAR(("Extended command \"show\"\n")); - map_menuBar(1); - menu_readonly = 1; - } else if (!strcmp(str, "hide")) { - D_MENUBAR(("Extended command \"hide\"\n")); - map_menuBar(0); - menu_readonly = 1; - } else if ((n = str_leading_match(str, "read:")) != 0) { - /* read in a menu from a file */ - D_MENUBAR(("Extended command \"read\"\n")); - str += n; - menubar_read(str); - } else if ((n = str_leading_match(str, "echo:")) != 0) { - D_MENUBAR(("Extended command \"echo\"\n")); - str += n; - tt_write(str, strlen(str)); - tt_write("\r", 1); - } else if ((n = str_leading_match(str, "apptitle:")) != 0) { - D_MENUBAR(("Extended command \"apptitle\"\n")); - str += n; - xterm_seq(XTerm_title, str); - } else if ((n = str_leading_match(str, "title:")) != 0) { - D_MENUBAR(("Extended command \"title\"\n")); - str += n; - if (CurrentBar != NULL && !menu_readonly) { - if (*str) { - name = REALLOC(CurrentBar->title, strlen(str) + 1); - if (name != NULL) { - strcpy(name, str); - CurrentBar->title = name; - } - menubar_expose(); - } else { - FREE(CurrentBar->title); - CurrentBar->title = NULL; - } - } - } else if ((n = str_leading_match(str, "pixmap:")) != 0) { - D_MENUBAR(("Extended command \"pixmap\"\n")); - str += n; - xterm_seq(XTerm_Pixmap, str); - } -#if (MENUBAR_MAX > 1) - else if ((n = str_leading_match(str, "rm")) != 0) { - D_MENUBAR(("Extended command \"rm\"\n")); - str += n; - switch (str[0]) { - case ':': - str++; - menubar_remove(str); - break; - - case '\0': - menubar_remove(str); - break; - - case '*': - menubar_remove(str); - break; - } - menu_readonly = 1; - } else if ((n = str_leading_match(str, "menu")) != 0) { - D_MENUBAR(("Extended command \"menu\"\n")); - str += n; - switch (str[0]) { - case ':': - str++; - /* add/access menuBar */ - if (*str != '\0' && *str != '*') - menubar_push(str); - break; - default: - if (CurrentBar == NULL) { - menubar_push("default"); - } - } - - - if (CurrentBar != NULL) - menu_readonly = 0; /* allow menu build commands */ - } else if (!strcmp(str, "dump")) { - /* dump current menubars to a file */ - FILE *fp; - - /* enough space to hold the results */ - char buffer[32]; - - D_MENUBAR(("Extended command \"dump\"\n")); - sprintf(buffer, "/tmp/" APL_NAME "-%u", - (unsigned int) getpid()); - - if ((fp = fopen(buffer, "wb")) != NULL) { - xterm_seq(XTerm_title, buffer); - menubar_dump(fp); - fclose(fp); - } - } else if (!strcmp(str, "next")) { - if (CurrentBar) { - CurrentBar = CurrentBar->next; - menu_readonly = 1; - } - } else if (!strcmp(str, "prev")) { - if (CurrentBar) { - CurrentBar = CurrentBar->prev; - menu_readonly = 1; - } - } else if (!strcmp(str, "swap")) { - /* swap the top 2 menus */ - if (CurrentBar) { - bar_t *prev = CurrentBar->prev; - bar_t *next = CurrentBar->next; - - prev->next = next; - next->prev = prev; - - CurrentBar->next = prev; - CurrentBar->prev = prev->prev; - - prev->prev->next = CurrentBar; - prev->prev = CurrentBar; - - CurrentBar = prev; - menu_readonly = 1; - } - } -#endif /* (MENUBAR_MAX > 1) */ - str = next; - - BuildMenu = ActiveMenu = NULL; - menubar_expose(); - D_MENUBAR_STACKING(("menus are read%s\n", menu_readonly ? "only" : "/write")); - } - return; - break; - } - -#if (MENUBAR_MAX > 1) - if (CurrentBar == NULL) - return; - if (menu_readonly) { - D_MENUBAR_STACKING(("menus are read%s\n", menu_readonly ? "only" : "/write")); - return; - } -#endif /* (MENUBAR_MAX > 1) */ - - switch (cmd) { - case '+': - case '-': - path = name = str; - - name2 = NULL; - /* parse STR, allow spaces inside (name) */ - if (path[0] != '\0') { - name = strchr(path, MENUITEM_BEG); - str = strchr(path, MENUITEM_END); - if (name != NULL || str != NULL) { - if (name == NULL || str == NULL || str <= (name + 1) - || (name > path && name[-1] != '/')) { - print_error("menu error <%s>\n", path); - break; - } - if (str[1] == MENUITEM_BEG) { - name2 = (str + 2); - str = strchr(name2, MENUITEM_END); - - if (str == NULL) { - print_error("menu error <%s>\n", path); - break; - } - name2[-2] = '\0'; /* remove prev MENUITEM_END */ - } - if (name > path && name[-1] == '/') - name[-1] = '\0'; - - *name++ = '\0'; /* delimit */ - *str++ = '\0'; /* delimit */ - - while (isspace(*str)) - str++; /* skip space */ - } - D_MENUBAR(("`%c' path = <%s>, name = <%s>, name2 = <%s>, action = <%s>\n", cmd, - (path ? path : "(nil)"), (name ? name : "(nil)"), (name2 ? name2 : "(nil)"), - (str ? str : "(nil)"))); - } - /* process the different commands */ - switch (cmd) { - case '+': /* add/replace existing menu or menuitem */ - if (path[0] != '\0') { - int len; - - path = menu_find_base(&BuildMenu, path); - len = strlen(path); - - /* don't allow menus called `*' */ - if (path[0] == '*') { - menu_clear(BuildMenu); - break; - } else if (len >= 2 && !strcmp((path + len - 2), "/*")) { - path[len - 2] = '\0'; - } - if (path[0] != '\0') - BuildMenu = menu_add(BuildMenu, path); - } - if (name != NULL && name[0] != '\0') { - if (!strcmp(name, SEPARATOR_NAME)) - name = ""; - menuitem_add(BuildMenu, name, name2, str); - } - break; - - case '-': /* delete menu entry */ - if (!strcmp(path, "/*") && (name == NULL || name[0] == '\0')) { - menubar_clear(); - BuildMenu = NULL; - menubar_expose(); - break; - } else if (path[0] != '\0') { - int len; - menu_t *menu = BuildMenu; - - path = menu_find_base(&menu, path); - len = strlen(path); - - /* submenu called `*' clears all menu items */ - if (path[0] == '*') { - menu_clear(menu); - break; /* done */ - } else if (len >= 2 && !strcmp(&path[len - 2], "/*")) { - /* done */ - break; - } else if (path[0] != '\0') { - BuildMenu = NULL; - break; - } else { - BuildMenu = menu; - } - } - if (BuildMenu != NULL) { - if (name == NULL || name[0] == '\0') { - BuildMenu = menu_delete(BuildMenu); - } else { - menuitem_t *item; - - if (!strcmp(name, SEPARATOR_NAME)) - name = ""; - item = menuitem_find(BuildMenu, name); - - if (item != NULL && item->entry.type != MenuSubMenu) { - menuitem_free(BuildMenu, item); - - /* fix up the width */ - BuildMenu->width = 0; - for (item = BuildMenu->head; - item != NULL; - item = item->next) { - if (BuildMenu->width < (item->len + item->len2)) - BuildMenu->width = (item->len + item->len2); - } - } - } - menubar_expose(); - } - break; - } - break; - } -} - -void -draw_Arrows(int name, int state) -{ - - GC top = None, bot = None; - - int i; - -#ifdef MENU_SHADOW_IN - state = -state; -#endif - switch (state) { - case +1: - top = topShadowGC; - bot = botShadowGC; - break; /* SHADOW_OUT */ - case -1: - top = botShadowGC; - bot = topShadowGC; - break; /* SHADOW_IN */ - case 0: - top = bot = neutralGC; - break; /* neutral */ - } - if (!Arrows_x) - return; - - for (i = 0; i < NARROWS; i++) { - const int w = Width2Pixel(1); - const int y = (menuBar_TotalHeight() - w) / 2; - int x = Arrows_x + (5 * Width2Pixel(i)) / 4; - - if (!name || name == Arrows[i].name) - Draw_Triangle(menuBar.win, top, bot, x, y, w, - Arrows[i].name); - } - XFlush(Xdisplay); -} - -void -menubar_expose(void) -{ - - menu_t *menu; - int x; - -# ifdef CHANGE_SCROLLCOLOR_ON_FOCUS - static int focus = -1; - -# endif -# ifdef KANJI - static int fsTry = 0; - -# endif - - if (delay_menu_drawing || !menubar_visible()) - return; - -#ifdef KANJI - if (!fontset && !fsTry) { - char *fontname = malloc(strlen(rs_font[0]) + strlen(rs_kfont[0]) + 2); - int i, mc; - char **ml, *ds; - - fsTry = 1; - if (fontname) { - setlocale(LC_ALL, ""); - strcpy(fontname, rs_font[0]); - strcat(fontname, ","); - strcat(fontname, rs_kfont[0]); - fontset = XCreateFontSet(Xdisplay, fontname, &ml, &mc, &ds); - free(fontname); - if (mc) { - XFreeStringList(ml); - fontset = 0; - return; - } - } - } -#endif /* KANJI */ - - if (menubarGC == None) { - /* Create the graphics context */ - XGCValues gcvalue; - - gcvalue.font = TermWin.font->fid; - - gcvalue.foreground = (Xdepth <= 2 ? - PixColors[fgColor] : - PixColors[menuTextColor]); - menubarGC = XCreateGC(Xdisplay, menuBar.win, - GCForeground | GCFont, - &gcvalue); - -#ifdef KEEP_SCROLLCOLOR - gcvalue.foreground = PixColors[scrollColor]; -#endif - neutralGC = XCreateGC(Xdisplay, menuBar.win, - GCForeground, - &gcvalue); - -#ifdef KEEP_SCROLLCOLOR - gcvalue.foreground = PixColors[bottomShadowColor]; -#endif - botShadowGC = XCreateGC(Xdisplay, menuBar.win, - GCForeground | GCFont, - &gcvalue); - -#ifdef KEEP_SCROLLCOLOR - gcvalue.foreground = PixColors[topShadowColor]; -#endif - topShadowGC = XCreateGC(Xdisplay, menuBar.win, - GCForeground, - &gcvalue); - } -# ifdef CHANGE_SCROLLCOLOR_ON_FOCUS - /* Update colors on focus change */ - if (focus != TermWin.focus) { - XGCValues gcvalue; - - focus = TermWin.focus; - - gcvalue.foreground = PixColors[fgColor]; - -# ifdef KEEP_SCROLLCOLOR - if (Xdepth > 2) - gcvalue.foreground = PixColors[focus ? scrollColor : unfocusedScrollColor]; -# endif - - XChangeGC(Xdisplay, neutralGC, GCForeground, - &gcvalue); - - gcvalue.background = gcvalue.foreground; - XChangeGC(Xdisplay, menubarGC, GCBackground, - &gcvalue); - XChangeGC(Xdisplay, neutralGC, GCForeground, - &gcvalue); - - XSetWindowBackground(Xdisplay, menuBar.win, gcvalue.foreground); - - gcvalue.foreground = PixColors[bgColor]; - -# ifdef KEEP_SCROLLCOLOR - gcvalue.foreground = PixColors[focus ? topShadowColor : unfocusedTopShadowColor]; -# endif - XChangeGC(Xdisplay, topShadowGC, - GCForeground, - &gcvalue); - -# ifdef KEEP_SCROLLCOLOR - gcvalue.foreground = PixColors[focus ? bottomShadowColor : unfocusedBottomShadowColor]; -# endif - XChangeGC(Xdisplay, botShadowGC, - GCForeground, - &gcvalue); - - } -#endif - - /* make sure the font is correct */ - XSetFont(Xdisplay, menubarGC, TermWin.font->fid); - XSetFont(Xdisplay, botShadowGC, TermWin.font->fid); - XClearWindow(Xdisplay, menuBar.win); - - menu_hide_all(); - - x = 0; - if (CurrentBar != NULL) { - for (menu = CurrentBar->head; menu != NULL; menu = menu->next) { - int len = menu->len; - - x = (menu->x + menu->len + HSPACE); - -#if DEBUG >= DEBUG_MENU_LAYOUT - if (debug_level >= DEBUG_MENU_LAYOUT) { - print_menu_descendants(menu); - } -#endif - - if (x >= TermWin.ncol) - len = (TermWin.ncol - (menu->x + HSPACE)); - - drawbox_menubar(menu->x, len, +1); - -#ifdef KANJI - if (fontset) - XmbDrawString(Xdisplay, menuBar.win, fontset, menubarGC, (Width2Pixel(menu->x) + Width2Pixel(HSPACE) / 2), - menuBar_height() - (TermWin.font->descent) + 1, menu->name, len); - else -#endif - XDrawString(Xdisplay, menuBar.win, menubarGC, (Width2Pixel(menu->x) + Width2Pixel(HSPACE) / 2), - menuBar_height() - (TermWin.font->descent) + 1, menu->name, len); - if (x >= TermWin.ncol) - break; - } - } - drawbox_menubar(x, TermWin.ncol, 1); - - /* add the menuBar title, if it exists and there's plenty of room */ - Arrows_x = 0; - if (x < TermWin.ncol) { - char *str, title[256]; - int len, ncol = TermWin.ncol; - - if (x < (ncol - (NARROWS + 1))) { - ncol -= (NARROWS + 1); - Arrows_x = menuBar_TotalWidth() - (2 * SHADOW + ((5 * Width2Pixel(1)) / 4 * NARROWS) + HSPACE); - } - draw_Arrows(0, -1); - - str = (CurrentBar && CurrentBar->title ? CurrentBar->title : "%n"); - for (len = 0; str[0] && len < sizeof(title) - 1; str++) { - const char *s = NULL; - - switch (str[0]) { - case '%': - str++; - switch (str[0]) { - case 'n': - s = rs_name; - break; /* resource name */ - case 'v': - s = VERSION; - break; /* version number */ - case '%': - s = "%"; - break; /* literal '%' */ - } - if (s != NULL) - while (*s && len < sizeof(title) - 1) - title[len++] = *s++; - break; - - default: - title[len++] = str[0]; - break; - } - } - title[len] = '\0'; - - ncol = Pixel2Width(Arrows_x - Width2Pixel(x) - Width2Pixel(len) - Width2Pixel(4)); -#ifdef KANJI - if (fontset) { - if (len > 0 && ncol >= 0) - XmbDrawString(Xdisplay, menuBar.win, fontset, menubarGC, - Width2Pixel(x) + ((Arrows_x - Width2Pixel(x)) / 2 - (Width2Pixel(len) / 2)), - menuBar_height() - (TermWin.font->descent) + 1, title, len); - } else -#endif - if (len > 0 && ncol >= 0) - XDrawString(Xdisplay, menuBar.win, menubarGC, - Width2Pixel(x) + ((Arrows_x - Width2Pixel(x + len + 1)) / 2), - menuBar_height() - (TermWin.font->descent) + 1, title, len); - } -} - -int -menubar_mapping(int map) -{ - - int change = 0; - - if (map && !menubar_visible()) { - menuBar.state = 1; - XMapWindow(Xdisplay, menuBar.win); - change = 1; - } else if (!map && menubar_visible()) { - menubar_expose(); - menuBar.state = 0; - XUnmapWindow(Xdisplay, menuBar.win); - change = 1; - } else - menubar_expose(); - - return change; -} - -int -menu_select(XButtonEvent * ev) -{ - - menuitem_t *thisitem, *item = NULL; - int this_y = 0, y = 0; - - Window unused_root, unused_child; - int unused_root_x, unused_root_y; - unsigned int unused_mask; - - if (ActiveMenu == NULL) - return 0; - - D_MENUBAR(("menu_select()\n")); - XQueryPointer(Xdisplay, ActiveMenu->win, - &unused_root, &unused_child, - &unused_root_x, &unused_root_y, - &(ev->x), &(ev->y), - &unused_mask); - - if (ActiveMenu->parent != NULL && (ev->x < 0 || ev->y < 0 || (ev->y > menu_height() && ev->x < 0))) { - menu_hide(); - return 1; - } - - /* determine the menu item corresponding to the Y index */ - if (ev->x >= 0 && ev->x <= (ActiveMenu->w - SHADOW)) { - for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next) { - int h = menu_height(); - - if (isSeparator(item->name)) { - h = SEPARATOR_HEIGHT; - } else if (ev->y >= y && ev->y < (y + h)) { - break; - } - y += h; - } - } - if (item == NULL && ev->type == ButtonRelease) { - menu_hide_all(); - return 0; - } - thisitem = item; - this_y = y; - -/* erase the last item */ - if (ActiveMenu->item != NULL) { - if (ActiveMenu->item != thisitem) { - for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next) { - - int h = menu_height(); - - if (isSeparator(item->name)) { - h = SEPARATOR_HEIGHT; - } else if (item == ActiveMenu->item) { - /* erase old menuitem */ - drawbox_menuitem(y, 0); /* No Shadow */ - if (item->entry.type == MenuSubMenu) - drawtriangle(ActiveMenu->w, y, +1); - break; - } - y += h; - } - } else { - if (ev->type == ButtonRelease) { - switch (item->entry.type) { - case MenuLabel: - case MenuSubMenu: - menu_hide_all(); - break; - - case MenuAction: - case MenuTerminalAction: - drawbox_menuitem(this_y, -1); - -#if MENU_DELAY_USEC > 0 - /* use select for timing */ - { - struct itimerval tv; - - tv.it_value.tv_sec = 0; - tv.it_value.tv_usec = MENU_DELAY_USEC; - - select(0, NULL, NULL, NULL, &tv.it_value); - } -#endif - menu_hide_all(); /* remove menu before sending keys to the application */ - D_MENUBAR(("%s: %s\n", item->name, item->entry.action.str)); - action_dispatch(&(item->entry.action)); - break; - } - return 0; - } else if (item->entry.type != MenuSubMenu) { - return 0; - } - } - } - ActiveMenu->item = thisitem; - y = this_y; - if (thisitem != NULL) { - item = ActiveMenu->item; - if (item->entry.type != MenuLabel) - drawbox_menuitem(y, +1); - if (item->entry.type == MenuSubMenu) { - drawtriangle(ActiveMenu->w, y, -1); - if ((ev->x > ActiveMenu->w / 2) && (ev->y > 0) && (Menu_PixelWidth(item->entry.submenu.menu) + ev->x >= ActiveMenu->w)) { - ActiveMenu = item->entry.submenu.menu; - menu_show(); - return 1; - } - } - } - return 0; -} - -void -menubar_select(XButtonEvent * ev) -{ - - menu_t *menu = NULL; - static int last_mouse_x = 0, last_mouse_y = 0, last_win_x = 0, last_win_y = 0; - int mouse_x, mouse_y, win_x, win_y, dx, dy, unused; - Window unused_window; - -/* determine the pulldown menu corresponding to the X index */ - D_MENUBAR(("menubar_select():\n")); - if (ev->y >= 0 && ev->y <= menuBar_height() && CurrentBar != NULL) { - for (menu = CurrentBar->head; menu != NULL; menu = menu->next) { - int x = Width2Pixel(menu->x); - int w = Width2Pixel(menu->len + HSPACE); - - if ((ev->x >= x && ev->x < x + w)) - break; - } - } - switch (ev->type) { - case ButtonRelease: - D_MENUBAR((" menubar_select(ButtonRelease)\n")); - menu_hide_all(); - break; - - case ButtonPress: - D_MENUBAR((" menubar_select(ButtonPress)\n")); - if (menu == NULL && Arrows_x && ev->x >= Arrows_x) { - int i; - - for (i = 0; i < NARROWS; i++) { - if ((ev->x >= (Arrows_x + (Width2Pixel(4 * i + i)) / 4)) && (ev->x < (Arrows_x + (Width2Pixel(4 * i + i + 4)) / 4))) { - - draw_Arrows(Arrows[i].name, +1); - -#if MENU_DELAY_USEC > 0 - /* - * use select for timing - */ - { - struct itimerval tv; - - tv.it_value.tv_sec = 0; - tv.it_value.tv_usec = MENU_DELAY_USEC; - - select(0, NULL, NULL, NULL, &tv.it_value); - } -#endif - - draw_Arrows(Arrows[i].name, -1); -#if DEBUG >= DEBUG_MENUARROWS - if (debug_level >= DEBUG_MENUARROWS) { - fprintf(stderr, "'%c': ", Arrows[i].name); - - if (CurrentBar == NULL || - (CurrentBar->arrows[i].type != MenuAction && - CurrentBar->arrows[i].type != MenuTerminalAction)) { - if (Arrows[i].str != NULL && Arrows[i].str[0]) - fprintf(stderr, "(default) \\033%s\n", - &(Arrows[i].str[2])); - } else { - fprintf(stderr, "%s\n", CurrentBar->arrows[i].str); - } - } else { -#endif - if (CurrentBar == NULL || - action_dispatch(&(CurrentBar->arrows[i]))) { - if (Arrows[i].str != NULL && - Arrows[i].str[0] != 0) - tt_write((Arrows[i].str + 1), - Arrows[i].str[0]); - } -#if DEBUG >= DEBUG_MENUARROWS - } -#endif /* DEBUG_MENUARROWS */ - return; - } - } - } else if (menu == NULL && ActiveMenu == NULL && Options & Opt_menubar_move) { - XTranslateCoordinates(Xdisplay, TermWin.parent, Xroot, - 0, 0, &last_win_x, &last_win_y, &unused_window); - XQueryPointer(Xdisplay, TermWin.parent, &unused_window, &unused_window, &unused, &unused, - &last_mouse_x, &last_mouse_y, &unused); - D_MENUBAR(("Initial data: last_mouse == %d,%d last_win == %d,%d\n", - last_mouse_x, last_mouse_y, last_win_x, last_win_y)); - break; - } - /*drop */ - case MotionNotify: - if (menu == NULL && ActiveMenu == NULL && Options & Opt_menubar_move) { - XQueryPointer(Xdisplay, TermWin.parent, &unused_window, &unused_window, &unused, &unused, - &mouse_x, &mouse_y, &unused); - if (mouse_x != last_mouse_x || mouse_y != last_mouse_y) { - dx = mouse_x - last_mouse_x; - dy = mouse_y - last_mouse_y; - D_MENUBAR((" -> last_mouse == %d,%d mouse == %d,%d rel == %d,%d move %d,%d to %d,%d\n", - last_mouse_x, last_mouse_y, mouse_x, mouse_y, dx, dy, last_win_x, last_win_y, last_win_x + dx, last_win_y + dy)); - XMoveWindow(Xdisplay, TermWin.parent, last_win_x + dx, last_win_y + dy); - last_win_x += dx; - last_win_y += dy; - } - break; - } - /* drop */ - default: - /* - * press menubar or move to a new entry - */ - D_MENUBAR((" menubar_select(default)\n")); - if (menu != NULL && menu != ActiveMenu) { - menu_hide_all(); /* pop down old menu */ - ActiveMenu = menu; - menu_show(); /* pop up new menu */ - } - break; - } -} - -/* - * general dispatch routine, - * it would be nice to have `sticky' menus - */ -void -menubar_control(XButtonEvent * ev) -{ - - switch (ev->type) { - case ButtonPress: - D_MENUBAR(("menubar_control(ButtonPress)\n")); - if (ev->button == Button1) - menubar_select(ev); - break; - - case ButtonRelease: - D_MENUBAR(("menubar_control(ButtonRelease)\n")); - if (ev->button == Button1) - menu_select(ev); - break; - - case MotionNotify: - D_MENUBAR(("menubar_control(MotionNotify)\n")); - while (XCheckTypedWindowEvent(Xdisplay, TermWin.parent, MotionNotify, (XEvent *) ev)); - - if (ActiveMenu) - while (menu_select(ev)); - else - ev->y = -1; - if (ev->y < 0) { - - Window unused_root, unused_child; - int unused_root_x, unused_root_y; - unsigned int unused_mask; - - XQueryPointer(Xdisplay, menuBar.win, &unused_root, &unused_child, &unused_root_x, &unused_root_y, - &(ev->x), &(ev->y), &unused_mask); - menubar_select(ev); - } - break; - } -} -#endif /* MENUBAR_MAX */ diff --git a/src/menubar.h b/src/menubar.h deleted file mode 100644 index ac19d45..0000000 --- a/src/menubar.h +++ /dev/null @@ -1,126 +0,0 @@ -/*--------------------------------*-C-*---------------------------------* - * File: menubar.h - * - * Copyright 1996,97 - * mj olesen Queen's Univ at Kingston - * - * You can do what you like with this source code provided you don't make - * money from it and you include an unaltered copy of this message - * (including the copyright). As usual, the author accepts no - * responsibility for anything, nor does he guarantee anything whatsoever. - *----------------------------------------------------------------------*/ -#ifndef _MENUBAR_H -# define _MENUBAR_H -# include /* Xlib, Xutil, Xresource, Xfuncproto */ -# include - -typedef struct { - short state; - Window win; -} menuBar_t; - -typedef struct { - short type; /* must not be changed; first element */ - short len; /* strlen (str) */ - unsigned char *str; /* action to take */ -} action_t; - -typedef struct { - short type; /* must not be changed; first element */ - struct menu_t *menu; /* sub-menu */ -} submenu_t; - -typedef struct menuitem_t { - struct menuitem_t *prev; /* prev menu-item */ - struct menuitem_t *next; /* next menu-item */ - char *name; /* character string displayed */ - char *name2; /* character string displayed (right) */ - short len; /* strlen (name) */ - short len2; /* strlen (name) */ - union { - short type; /* must not be changed; first element */ - action_t action; - submenu_t submenu; - } entry; -} menuitem_t; - -enum menuitem_t_action { - MenuLabel, - MenuAction, - MenuTerminalAction, - MenuSubMenu -}; - -typedef struct menu_t { - struct menu_t *parent; /* parent menu */ - struct menu_t *prev; /* prev menu */ - struct menu_t *next; /* next menu */ - menuitem_t *head; /* double-linked list */ - menuitem_t *tail; /* double-linked list */ - menuitem_t *item; /* current item */ - char *name; /* menu name */ - short len; /* strlen (name) */ - short width; /* maximum menu width [chars] */ - Window win; /* window of the menu */ - short x; /* x location [pixels] (chars if parent == NULL) */ - short y; /* y location [pixels] */ - short w, h; /* window width, height [pixels] */ -} menu_t; - -typedef struct bar_t { - menu_t *head, *tail; /* double-linked list of menus */ - char *title; /* title to put in the empty menuBar */ -# if (MENUBAR_MAX > 1) -# define MAXNAME 16 - char name[MAXNAME]; /* name to use to refer to menubar */ - struct bar_t *next, *prev; /* circular linked-list */ -# endif /* (MENUBAR_MAX > 1) */ -# define NARROWS 4 - action_t arrows[NARROWS]; -} bar_t; - -extern menuBar_t menuBar; -extern int delay_menu_drawing; - -# define menuBar_margin 2 /* margin below text */ -# ifdef PIXMAP_MENUBAR -# define menubar_is_pixmapped() (0) -# else -# define menubar_is_pixmapped() (0) -# endif -/* macros */ -#define menubar_visible() (menuBar.state) -#define menuBar_height() (TermWin.fheight + SHADOW) -#define menuBar_TotalHeight() (menuBar_height() + SHADOW + menuBar_margin) -#define menuBar_TotalWidth() (2 * TermWin.internalBorder + TermWin.width) -#define isMenuBarWindow(w) ((w) == menuBar.win) - -_XFUNCPROTOBEGIN - -extern void -menubar_control (XButtonEvent * /* ev */); - -extern void -menubar_dispatch (char * /* str */); - -extern void -menubar_expose (void); - -extern int -menubar_mapping (int /* map */); - -_XFUNCPROTOEND - -#if !(MENUBAR_MAX) -# define menubar_dispatch(str) ((void)0) -# define menubar_expose() ((void)0) -# define menubar_control(ev) ((void)0) -# define menubar_mapping(map) (0) -# undef menubar_visible -# define menubar_visible() (0) -# undef isMenuBarWindow -# define isMenuBarWindow(w) (0) -#endif - -#endif /* _MENUBAR_H */ -/*----------------------- end-of-file (C header) -----------------------*/ diff --git a/src/menus.c b/src/menus.c new file mode 100644 index 0000000..414fbfe --- /dev/null +++ b/src/menus.c @@ -0,0 +1,1029 @@ +/* menus.c -- Eterm popup menu module + + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +static const char cvs_ident[] = "$Id$"; + +#include "config.h" +#include "feature.h" + +#include + +#include "../libmej/debug.h" +#include "../libmej/mem.h" +#include "../libmej/strings.h" +#include "command.h" +#include "events.h" +#include "main.h" +#include "menus.h" +#include "misc.h" +#include "options.h" +#include "pixmap.h" +#include "screen.h" +#include "term.h" +#include "windows.h" + +event_dispatcher_data_t menu_event_data; +menulist_t *menu_list = NULL; +static GC topShadowGC, botShadowGC; +static Time button_press_time; +static menu_t *current_menu; +static menuitem_t *current_item; + +inline void +grab_pointer(Window win) +{ + + int success; + + D_EVENTS(("grab_pointer(): Grabbing control of pointer for window 0x%08x.\n", win)); + success = XGrabPointer(Xdisplay, win, False, + EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask + | Button1MotionMask | Button2MotionMask | Button3MotionMask, + GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + if (success != GrabSuccess) { + switch (success) { + case GrabNotViewable: + D_MENU((" -> Unable to grab pointer -- Grab window is not viewable.\n")); + break; + case AlreadyGrabbed: + D_MENU((" -> Unable to grab pointer -- Pointer is already grabbed by another client.\n")); + break; + case GrabFrozen: + D_MENU((" -> Unable to grab pointer -- Pointer is frozen by another grab.\n")); + break; + case GrabInvalidTime: + D_MENU((" -> Unable to grab pointer -- Invalid grab time.\n")); + break; + default: + break; + } + } +} + +inline void +ungrab_pointer(void) +{ + + D_EVENTS(("ungrab_pointer(): Releasing pointer grab.\n")); + XUngrabPointer(Xdisplay, CurrentTime); +} + +inline void +draw_string(Drawable d, GC gc, int x, int y, char *str, size_t len) +{ + + /*D_MENU(("draw_string(): Writing string \"%s\" (length %lu) onto drawable 0x%08x at %d, %d\n", str, len, d, x, y)); */ + +#ifdef MULTI_CHARSET + if (current_menu && current_menu->fontset) + XmbDrawString(Xdisplay, d, current_menu->fontset, gc, x, y, str, len); + else +#endif + XDrawString(Xdisplay, d, gc, x, y, str, len); +} + +inline unsigned short +center_coords(register unsigned short c1, register unsigned short c2) +{ + + return (((c2 - c1) >> 1) + c1); +} + +void +menu_init(void) +{ + + XGCValues gcvalue; + + if (!menu_list || menu_list->nummenus == 0) { + return; + } + gcvalue.foreground = PixColors[menuTopShadowColor]; + topShadowGC = XCreateGC(Xdisplay, menu_list->menus[0]->win, GCForeground, &gcvalue); + gcvalue.foreground = PixColors[menuBottomShadowColor]; + botShadowGC = XCreateGC(Xdisplay, menu_list->menus[0]->win, GCForeground, &gcvalue); + + event_register_dispatcher(menu_dispatch_event, menu_event_init_dispatcher); +} + +void +menu_event_init_dispatcher(void) +{ + register unsigned char i; + + MEMSET(&menu_event_data, 0, sizeof(event_dispatcher_data_t)); + + EVENT_DATA_ADD_HANDLER(menu_event_data, EnterNotify, menu_handle_enter_notify); + EVENT_DATA_ADD_HANDLER(menu_event_data, LeaveNotify, menu_handle_leave_notify); + EVENT_DATA_ADD_HANDLER(menu_event_data, GraphicsExpose, menu_handle_expose); + EVENT_DATA_ADD_HANDLER(menu_event_data, Expose, menu_handle_expose); + EVENT_DATA_ADD_HANDLER(menu_event_data, ButtonPress, menu_handle_button_press); + EVENT_DATA_ADD_HANDLER(menu_event_data, ButtonRelease, menu_handle_button_release); + EVENT_DATA_ADD_HANDLER(menu_event_data, MotionNotify, menu_handle_motion_notify); + + for (i = 0; i < menu_list->nummenus; i++) { + event_data_add_mywin(&menu_event_data, menu_list->menus[i]->win); + } + + event_data_add_parent(&menu_event_data, TermWin.vt); + event_data_add_parent(&menu_event_data, TermWin.parent); + +} + +unsigned char +menu_handle_enter_notify(event_t * ev) +{ + + register menu_t *menu; + + D_EVENTS(("menu_handle_enter_notify(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &menu_event_data), 0); + + /* Take control of the pointer so we get all events for it, even those outside the menu window */ + menu = find_menu_by_window(menu_list, ev->xany.window); + if (menu && menu != current_menu) { + ungrab_pointer(); + if (menu->state & MENU_STATE_IS_MAPPED) { + grab_pointer(menu->win); + menu->state |= MENU_STATE_IS_FOCUSED; + current_menu = menu; + menu_reset_submenus(menu); + menuitem_change_current(find_item_by_coords(current_menu, ev->xbutton.x, ev->xbutton.y)); + } + } + return 1; +} + +unsigned char +menu_handle_leave_notify(event_t * ev) +{ + + D_EVENTS(("menu_handle_leave_notify(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &menu_event_data), 0); + + if (current_menu) { + current_menu->state &= ~(MENU_STATE_IS_FOCUSED); + } + return 0; +} + +unsigned char +menu_handle_focus_in(event_t * ev) +{ + + D_EVENTS(("menu_handle_focus_in(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &menu_event_data), 0); + + return 0; +} + +unsigned char +menu_handle_focus_out(event_t * ev) +{ + + D_EVENTS(("menu_handle_focus_out(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &menu_event_data), 0); + + return 0; +} + +unsigned char +menu_handle_expose(event_t * ev) +{ + + XEvent unused_xevent; + + D_EVENTS(("menu_handle_expose(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &menu_event_data), 0); + + while (XCheckTypedWindowEvent(Xdisplay, ev->xany.window, Expose, &unused_xevent)); + while (XCheckTypedWindowEvent(Xdisplay, ev->xany.window, GraphicsExpose, &unused_xevent)); + return 0; +} + +unsigned char +menu_handle_button_press(event_t * ev) +{ + + D_EVENTS(("menu_handle_button_press(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &menu_event_data), 0); + + D_EVENTS(("ButtonPress at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); + + button_press_time = ev->xbutton.time; + + return 1; +} + +unsigned char +menu_handle_button_release(event_t * ev) +{ + + D_EVENTS(("menu_handle_button_release(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &menu_event_data), 0); + + D_EVENTS(("ButtonRelease at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); + + if (current_menu && (current_menu->state & MENU_STATE_IS_DRAGGING)) { + + /* Dragging-and-release mode */ + D_MENU(("Drag-and-release mode, detected release.\n")); + ungrab_pointer(); + + if (button_press_time && (ev->xbutton.time - button_press_time > MENU_CLICK_TIME)) { + /* Take action here based on the current menu item */ + if (current_item) { + if (current_item->type == MENUITEM_SUBMENU) { + menu_display_submenu(current_menu, current_item); + current_item = NULL; + } else { + menu_action(current_item); + menuitem_deselect(current_menu, current_item); + } + } + } + /* Reset the state of the menu system. */ + menu_reset_all(menu_list); + current_menu = NULL; + + } else { + + /* Single-click mode */ + D_MENU(("Single click mode, detected click.\n")); + if ((ev->xbutton.x >= 0) && (ev->xbutton.y >= 0) && (ev->xbutton.x < current_menu->w) && (ev->xbutton.y < current_menu->h)) { + /* Click inside the menu window. Activate the current item. */ + if (current_item) { + if (current_item->type == MENUITEM_SUBMENU) { + menu_display_submenu(current_menu, current_item); + current_item = NULL; + } else { + menu_action(current_item); + menuitem_deselect(current_menu, current_item); + menu_reset_all(menu_list); + } + } + } else { + ungrab_pointer(); + /* Reset the state of the menu system. */ + menu_reset_all(menu_list); + current_menu = NULL; + } + } + button_press_time = 0; + + return 1; +} + +unsigned char +menu_handle_motion_notify(event_t * ev) +{ + + register menuitem_t *item = NULL; + + D_EVENTS(("menu_handle_motion_notify(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &menu_event_data), 0); + + while (XCheckTypedWindowEvent(Xdisplay, ev->xany.window, MotionNotify, ev)); + if (!current_menu) { + return 1; + } +#if 0 + if ((current_menu->win != ev->xany.window) + && !(current_item && current_item->type == MENUITEM_SUBMENU + && current_item->action.submenu && current_item->action.submenu->win == ev->xany.window)) { + register menu_t *menu; + + menu = find_menu_by_window(menu_list, ev->xany.window); + if (menu) { + menu_reset_tree(current_menu); + current_menu = menu; + } + } +#endif + + if (button_press_time) { + current_menu->state |= MENU_STATE_IS_DRAGGING; + } + if ((ev->xbutton.x >= 0) && (ev->xbutton.y >= 0) && (ev->xbutton.x < current_menu->w) && (ev->xbutton.y < current_menu->h)) { + /* Motion within the current menu */ + item = find_item_by_coords(current_menu, ev->xbutton.x, ev->xbutton.y); + menuitem_change_current(item); + } else { + /* Motion outside the current menu */ + int dest_x, dest_y; + Window child; + menu_t *menu; + + XTranslateCoordinates(Xdisplay, ev->xany.window, Xroot, ev->xbutton.x, ev->xbutton.y, &dest_x, &dest_y, &child); + menu = find_menu_by_window(menu_list, child); + if (menu) { + D_MENU(("Mouse is actually over window 0x%08x belonging to menu \"%s\"\n", child, menu->title)); + XTranslateCoordinates(Xdisplay, ev->xany.window, child, ev->xbutton.x, ev->xbutton.y, &dest_x, &dest_y, &child); + item = find_item_by_coords(menu, dest_x, dest_y); + if (item && item != current_item) { + ungrab_pointer(); + grab_pointer(menu->win); + current_menu->state &= ~(MENU_STATE_IS_FOCUSED); + menu->state |= MENU_STATE_IS_FOCUSED; + if (!menu_is_child(current_menu, menu)) { + menu_reset_tree(current_menu); + } + current_menu = menu; + menu_reset_submenus(menu); + menuitem_change_current(item); + } + } + } + + return 1; +} + +unsigned char +menu_dispatch_event(event_t * ev) +{ + if (menu_event_data.handlers[ev->type] != NULL) { + return ((menu_event_data.handlers[ev->type]) (ev)); + } + return (0); +} + +menulist_t * +menulist_add_menu(menulist_t * list, menu_t * menu) +{ + + ASSERT_RVAL(menu != NULL, list); + + if (list) { + list->nummenus++; + list->menus = (menu_t **) REALLOC(list->menus, sizeof(menu_t *) * list->nummenus); + } else { + list = (menulist_t *) MALLOC(sizeof(menulist_t)); + list->nummenus = 1; + list->menus = (menu_t **) MALLOC(sizeof(menu_t *)); + } + list->menus[list->nummenus - 1] = menu; + return list; +} + +menu_t * +menu_create(char *title) +{ + + menu_t *menu; + static Cursor cursor; + static long mask; + static XGCValues gcvalue; + static XSetWindowAttributes xattr; + + ASSERT_RVAL(title != NULL, NULL); + + if (!mask) { + xattr.border_pixel = BlackPixel(Xdisplay, Xscreen); + xattr.save_under = TRUE; + xattr.backing_store = WhenMapped; + xattr.override_redirect = TRUE; + xattr.colormap = cmap; + + cursor = XCreateFontCursor(Xdisplay, XC_left_ptr); + mask = EnterNotify | LeaveNotify | PointerMotionMask | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask + | Button1MotionMask | Button2MotionMask | Button3MotionMask; + gcvalue.foreground = PixColors[menuTextColor]; + } + menu = (menu_t *) MALLOC(sizeof(menu_t)); + MEMSET(menu, 0, sizeof(menu_t)); + menu->title = StrDup(title); + + menu->win = XCreateWindow(Xdisplay, Xroot, 0, 0, 1, 1, 0, Xdepth, InputOutput, CopyFromParent, + CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWBorderPixel | CWColormap, &xattr); + XDefineCursor(Xdisplay, menu->win, cursor); + XSelectInput(Xdisplay, menu->win, mask); + XStoreName(Xdisplay, menu->win, menu->title); + + menu->swin = XCreateWindow(Xdisplay, menu->win, 0, 0, 1, 1, 0, Xdepth, InputOutput, CopyFromParent, + CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWBorderPixel | CWColormap, &xattr); + + menu->gc = XCreateGC(Xdisplay, menu->win, GCForeground, &gcvalue); + + return menu; +} + +unsigned char +menu_set_font(menu_t * menu, const char *fontname) +{ + + XFontStruct *font; + XGCValues gcvalue; + + ASSERT_RVAL(menu != NULL, 0); + ASSERT_RVAL(fontname != NULL, 0); + + font = load_font(fontname); +#ifdef MULTI_CHARSET + menu->fontset = create_fontset(fontname, rs_mfont[0]); +#endif + + menu->font = font; + menu->fwidth = font->max_bounds.width; + menu->fheight = font->ascent + font->descent + rs_line_space; + + gcvalue.font = font->fid; + XChangeGC(Xdisplay, menu->gc, GCFont, &gcvalue); + + return 1; +} + +unsigned char +menu_add_item(menu_t * menu, menuitem_t * item) +{ + + ASSERT_RVAL(menu != NULL, 0); + ASSERT_RVAL(item != NULL, 0); + + if (menu->numitems) { + menu->numitems++; + menu->items = (menuitem_t **) REALLOC(menu->items, sizeof(menuitem_t *) * menu->numitems); + } else { + menu->numitems = 1; + menu->items = (menuitem_t **) MALLOC(sizeof(menuitem_t *)); + } + menu->items[menu->numitems - 1] = item; + return 1; + +} + +/* Return 1 if submenu is a child of menu, 0 if not. */ +unsigned char +menu_is_child(menu_t * menu, menu_t * submenu) +{ + + register unsigned char i; + register menuitem_t *item; + + ASSERT_RVAL(menu != NULL, 0); + ASSERT_RVAL(submenu != NULL, 0); + + for (i = 0; i < menu->numitems; i++) { + item = menu->items[i]; + if (item->type == MENUITEM_SUBMENU && item->action.submenu != NULL) { + if (item->action.submenu == submenu) { + return 1; + } else if (menu_is_child(item->action.submenu, submenu)) { + return 1; + } + } + } + return 0; +} + +menu_t * +find_menu_by_title(menulist_t * list, char *title) +{ + + register unsigned char i; + + ASSERT_RVAL(list != NULL, NULL); + + for (i = 0; i < list->nummenus; i++) { + if (!strcasecmp(list->menus[i]->title, title)) { + return (list->menus[i]); + } + } + return NULL; +} + +menu_t * +find_menu_by_window(menulist_t * list, Window win) +{ + + register unsigned char i; + + ASSERT_RVAL(list != NULL, NULL); + + for (i = 0; i < list->nummenus; i++) { + if (list->menus[i]->win == win) { + return (list->menus[i]); + } + } + return NULL; +} + +menuitem_t * +find_item_by_coords(menu_t * menu, int x, int y) +{ + + register unsigned char i; + register menuitem_t *item; + + ASSERT_RVAL(menu != NULL, NULL); + + for (i = 0; i < menu->numitems; i++) { + item = menu->items[i]; + if ((x > item->x) && (y > item->y) && (x < item->x + item->w) && (y < item->y + item->h) && (item->type != MENUITEM_SEP)) { + menu->curitem = i; + return (item); + } + } + return NULL; +} + +unsigned short +find_item_in_menu(menu_t * menu, menuitem_t * item) +{ + + register unsigned char i; + + ASSERT_RVAL(menu != NULL, (unsigned short) -1); + ASSERT_RVAL(item != NULL, (unsigned short) -1); + + for (i = 0; i < menu->numitems; i++) { + if (item == menu->items[i]) { + return (i); + } + } + return ((unsigned short) -1); +} + +void +menuitem_change_current(menuitem_t * item) +{ + + D_MENU(("menuitem_change_current(): Changing current_item from \"%s\" to \"%s\"\n", (current_item ? current_item->text : "(NULL)"), + (item ? item->text : "(NULL)"))); + + if (current_item != item) { + if (current_item) { + /* Reset the current item */ + menuitem_deselect(current_menu, current_item); + /* If we're changing from one submenu to another and neither is a child of the other, or if we're changing from a submenu to + no current item at all, reset the tree for the current submenu */ + if (current_item->type == MENUITEM_SUBMENU && current_item->action.submenu != NULL) { + if ((item && item->type == MENUITEM_SUBMENU && item->action.submenu != NULL + && !menu_is_child(current_item->action.submenu, item->action.submenu) + && !menu_is_child(item->action.submenu, current_item->action.submenu)) + || (!item)) { + menu_reset_tree(current_item->action.submenu); + } + } + } + current_item = item; + if (current_item) { + menuitem_select(current_menu, current_item); + if (current_item->type == MENUITEM_SUBMENU) { + /* Display the submenu */ + menu_display_submenu(current_menu, current_item); + } + } + } +} + +menuitem_t * +menuitem_create(char *text) +{ + + menuitem_t *menuitem; + + menuitem = (menuitem_t *) MALLOC(sizeof(menu_t)); + MEMSET(menuitem, 0, sizeof(menu_t)); + if (text) { + menuitem->text = StrDup(text); + menuitem->len = strlen(text); + } + return menuitem; +} + +unsigned char +menuitem_set_icon(menuitem_t * item, image_t * icon) +{ + + ASSERT_RVAL(item != NULL, 0); + ASSERT_RVAL(icon != NULL, 0); + + item->icon = icon; + return 1; +} + +unsigned char +menuitem_set_action(menuitem_t * item, unsigned char type, char *action) +{ + + ASSERT_RVAL(item != NULL, 0); + + item->type = type; + switch (type) { + case MENUITEM_SUBMENU: + item->action.submenu = find_menu_by_title(menu_list, action); + break; + case MENUITEM_STRING: + case MENUITEM_ECHO: + item->action.string = StrDup(action); + parse_escaped_string(item->action.string); + break; + default: + break; + } + return 1; +} + +unsigned char +menuitem_set_rtext(menuitem_t * item, char *rtext) +{ + + ASSERT_RVAL(item != NULL, 0); + ASSERT_RVAL(rtext != NULL, 0); + + item->rtext = StrDup(rtext); + item->rlen = strlen(rtext); + return 1; +} + +void +menu_reset(menu_t * menu) +{ + + ASSERT(menu != NULL); + + D_MENU(("menu_reset() called for menu \"%s\" (window 0x%08x)\n", menu->title, menu->win)); + menu->state &= ~(MENU_STATE_IS_CURRENT | MENU_STATE_IS_DRAGGING); + XUnmapWindow(Xdisplay, menu->swin); + if (menu->state & MENU_STATE_IS_MAPPED) { + XUnmapWindow(Xdisplay, menu->win); + menu->state &= ~(MENU_STATE_IS_MAPPED); + } +} + +void +menu_reset_all(menulist_t * list) +{ + + register unsigned short i; + register menu_t *menu; + + ASSERT(list != NULL); + + if (list->nummenus == 0) + return; + + D_MENU(("menu_reset_all() called\n")); + if (current_item != NULL) { + menuitem_deselect(current_menu, current_item); + current_item = NULL; + } + for (i = 0; i < list->nummenus; i++) { + menu = list->menus[i]; + menu->state &= ~(MENU_STATE_IS_CURRENT | MENU_STATE_IS_DRAGGING); + XUnmapWindow(Xdisplay, menu->swin); + if (menu->state & MENU_STATE_IS_MAPPED) { + XUnmapWindow(Xdisplay, menu->win); + menu->state &= ~(MENU_STATE_IS_MAPPED); + } + } + current_menu = NULL; +} + +void +menu_reset_tree(menu_t * menu) +{ + + register unsigned short i; + register menuitem_t *item; + + ASSERT(menu != NULL); + + D_MENU(("menu_reset_tree() called for menu \"%s\" (window 0x%08x)\n", menu->title, menu->win)); + for (i = 0; i < menu->numitems; i++) { + item = menu->items[i]; + if (item->type == MENUITEM_SUBMENU && item->action.submenu != NULL) { + menu_reset_tree(item->action.submenu); + } + } + menu->state &= ~(MENU_STATE_IS_CURRENT | MENU_STATE_IS_DRAGGING); + XUnmapWindow(Xdisplay, menu->swin); + if (menu->state & MENU_STATE_IS_MAPPED) { + XUnmapWindow(Xdisplay, menu->win); + menu->state &= ~(MENU_STATE_IS_MAPPED); + } +} + +void +menu_reset_submenus(menu_t * menu) +{ + + register unsigned short i; + register menuitem_t *item; + + ASSERT(menu != NULL); + + D_MENU(("menu_reset_submenus() called for menu \"%s\" (window 0x%08x)\n", menu->title, menu->win)); + for (i = 0; i < menu->numitems; i++) { + item = menu->items[i]; + if (item->type == MENUITEM_SUBMENU && item->action.submenu != NULL) { + menu_reset_tree(item->action.submenu); + } + } +} + +void +menuitem_select(menu_t * menu, menuitem_t * item) +{ + + ASSERT(menu != NULL); + ASSERT(item != NULL); + + D_MENU(("menuitem_select(): Selecting new current item \"%s\" within menu \"%s\" (window 0x%08x, selection window 0x%08x)\n", + item->text, menu->title, menu->win, menu->swin)); + item->state |= MENU_STATE_IS_CURRENT; + XMoveWindow(Xdisplay, menu->swin, item->x, item->y); + XMapWindow(Xdisplay, menu->swin); + if (item->type == MENUITEM_SUBMENU) { + paste_simage(images[image_submenu].selected, menu->swin, 0, 0, item->w - MENU_VGAP, item->h); + } else { + render_simage(images[image_menu].selected, menu->swin, item->w - MENU_VGAP, item->h, image_menu, 0); + } + draw_string(menu->swin, menu->gc, MENU_HGAP, item->h - MENU_VGAP, item->text, item->len); +} + +void +menuitem_deselect(menu_t * menu, menuitem_t * item) +{ + + ASSERT(menu != NULL); + ASSERT(item != NULL); + + D_MENU(("menuitem_deselect(): Deselecting item \"%s\"\n", item->text)); + item->state &= ~(MENU_STATE_IS_CURRENT); + XUnmapWindow(Xdisplay, menu->swin); + if (find_item_in_menu(menu, item) != (unsigned short) -1) { + if (item->type == MENUITEM_SUBMENU) { + paste_simage(images[image_submenu].norm, menu->win, item->x, item->y, item->w - MENU_VGAP, item->h); + } + draw_string(menu->win, menu->gc, 2 * MENU_HGAP, item->y + item->h - MENU_VGAP, item->text, item->len); + } +} + +void +menu_display_submenu(menu_t * menu, menuitem_t * item) +{ + + menu_t *submenu; + + ASSERT(menu != NULL); + ASSERT(item != NULL); + REQUIRE(item->action.submenu != NULL); + + submenu = item->action.submenu; + D_MENU(("menu_display_submenu(): Displaying submenu \"%s\" (window 0x%08x) of menu \"%s\" (window 0x%08x)\n", + submenu->title, submenu->win, menu->title, menu->win)); + menu_invoke(item->x + item->w, item->y, menu->win, submenu, CurrentTime); + + /* Invoking the submenu makes it current. Undo that behavior. */ + ungrab_pointer(); + grab_pointer(menu->win); + current_menu->state &= ~(MENU_STATE_IS_CURRENT); + current_menu = menu; + menu->state |= MENU_STATE_IS_CURRENT; +} + +void +menu_draw(menu_t * menu) +{ + + register unsigned short i, len; + unsigned long width, height; +#if 0 + char *safeaction; +#endif + unsigned short str_x, str_y; + XGCValues gcvalue; + int ascent, descent, direction; + XCharStruct chars; + Screen *scr; + + ASSERT(menu != NULL); + + scr = ScreenOfDisplay(Xdisplay, Xscreen); + if (!menu->font) { + menu_set_font(menu, rs_font[0]); + } + gcvalue.foreground = PixColors[menuTextColor]; + XChangeGC(Xdisplay, menu->gc, GCForeground, &gcvalue); + + if (!menu->w) { + len = strlen(menu->title); + height = menu->fheight + 3 * MENU_VGAP; + for (i = 0; i < menu->numitems; i++) { + unsigned short j = menu->items[i]->len; + menuitem_t *item = menu->items[i]; + + if (item->rtext) { + j += item->rlen + 2; + } + MAX_IT(len, j); + height += ((item->type == MENUITEM_SEP) ? (MENU_VGAP) : (menu->fheight)) + MENU_VGAP; + } + width = len * menu->fwidth + (4 * MENU_HGAP); + if (images[image_submenu].selected->iml->pad) { + width += images[image_submenu].selected->iml->pad->left + images[image_submenu].selected->iml->pad->right; + } + menu->w = width; + menu->h = height; + + /* Size and render menu window */ + D_MENU((" -> width %hu, height %hu\n", menu->w, menu->h)); + XResizeWindow(Xdisplay, menu->win, menu->w, menu->h); + render_simage(images[image_menu].norm, menu->win, menu->w, menu->h, image_menu, 0); + + /* Size and render selected item window */ + XResizeWindow(Xdisplay, menu->swin, menu->w - 2 * MENU_HGAP, menu->fheight + MENU_VGAP); + render_simage(images[image_menu].selected, menu->swin, menu->w - 2 * MENU_HGAP, menu->fheight + MENU_VGAP, image_menu, 0); + } + if (menu->w + menu->x > scr->width) { + menu->x = scr->width - menu->w; + } + if (menu->h + menu->y > scr->height) { + menu->y = scr->height - menu->h; + } + XMoveWindow(Xdisplay, menu->win, menu->x, menu->y); + XRaiseWindow(Xdisplay, menu->win); + + str_x = 2 * MENU_HGAP; + if (images[image_menu].selected->iml->pad) { + str_x += images[image_menu].selected->iml->pad->left; + } + str_y = menu->fheight + MENU_VGAP; + len = strlen(menu->title); + XTextExtents(menu->font, menu->title, len, &direction, &ascent, &descent, &chars); + draw_string(menu->win, menu->gc, center_coords(2 * MENU_HGAP, menu->w - 2 * MENU_HGAP) - (chars.width >> 1), + str_y - chars.descent - MENU_VGAP / 2, menu->title, len); + Draw_Shadow(menu->win, topShadowGC, botShadowGC, str_x, str_y - chars.descent - MENU_VGAP / 2 + 1, menu->w - (4 * MENU_HGAP), MENU_VGAP); + str_y += MENU_VGAP; + + for (i = 0; i < menu->numitems; i++) { + menuitem_t *item = menu->items[i]; + + if (item->type == MENUITEM_SEP) { + + str_y += 2 * MENU_VGAP; + if (!item->x) { + item->x = MENU_HGAP; + item->y = str_y - 2 * MENU_VGAP; + item->w = menu->w - MENU_HGAP; + item->h = 2 * MENU_VGAP; + D_MENU((" -> Hot Area at %hu, %hu to %hu, %hu (width %hu, height %hu)\n", item->x, item->y, item->x + item->w, item->y + item->h, + item->w, item->h)); + } + Draw_Shadow(menu->win, botShadowGC, topShadowGC, str_x, str_y - MENU_VGAP - MENU_VGAP / 2, menu->w - 4 * MENU_HGAP, MENU_VGAP); + + } else { + str_y += menu->fheight + MENU_VGAP; + if (!item->x) { + item->x = MENU_HGAP; + item->y = str_y - menu->fheight - MENU_VGAP / 2; + item->w = menu->w - MENU_HGAP; + item->h = menu->fheight + MENU_VGAP; + D_MENU((" -> Hot Area at %hu, %hu to %hu, %hu (width %hu, height %hu)\n", item->x, item->y, item->x + item->w, item->y + item->h, + item->w, item->h)); + } + switch (item->type) { + case MENUITEM_SUBMENU: + paste_simage(images[image_submenu].norm, menu->win, item->x, item->y, item->w - MENU_VGAP, item->h); + break; + case MENUITEM_STRING: +#if 0 + safeaction = StrDup(item->action.string); + SafeStr(safeaction, strlen(safeaction)); + D_MENU((" Item %hu: %s (string %s)\n", i, item->text, safeaction)); + FREE(safeaction); +#endif + break; + case MENUITEM_ECHO: +#if 0 + safeaction = StrDup(item->action.string); + SafeStr(safeaction, strlen(safeaction)); + D_MENU((" Item %hu: %s (echo %s)\n", i, item->text, safeaction)); + FREE(safeaction); +#endif + break; + default: + fatal_error("Internal Program Error: Unknown menuitem type: %u\n", item->type); + break; + } + draw_string(menu->win, menu->gc, str_x, str_y - MENU_VGAP / 2, item->text, item->len); + } + } +} + +void +menu_display(int x, int y, menu_t * menu) +{ + + ASSERT(menu != NULL); + + menu->state |= (MENU_STATE_IS_CURRENT); + current_menu = menu; + + /* Move, render, and map menu window */ + menu->x = x; + menu->y = y; + D_MENU(("Displaying menu \"%s\" (window 0x%08x) at root coordinates %d, %d\n", menu->title, menu->win, menu->x, menu->y)); + XMoveWindow(Xdisplay, menu->win, menu->x, menu->y); + XUnmapWindow(Xdisplay, menu->swin); + XMapWindow(Xdisplay, menu->win); + menu->state |= (MENU_STATE_IS_MAPPED); + + menu_draw(menu); + + /* Take control of the pointer so we get all events for it, even those outside the menu window */ + grab_pointer(menu->win); +} + +void +menu_action(menuitem_t * item) +{ + + ASSERT(item != NULL); + + D_MENU(("menu_action() called to invoke %s\n", item->text)); + switch (item->type) { + case MENUITEM_SEP: + D_MENU(("Internal Program Error: menu_action() called for a separator.\n")); + break; + case MENUITEM_SUBMENU: + D_MENU(("Internal Program Error: menu_action() called for a submenu.\n")); + break; + case MENUITEM_STRING: + cmd_write(item->action.string, strlen(item->action.string)); + break; + case MENUITEM_ECHO: + tt_write(item->action.string, strlen(item->action.string)); + break; + default: + fatal_error("Internal Program Error: Unknown menuitem type: %u\n", item->type); + break; + } +} + +void +menu_invoke(int x, int y, Window win, menu_t * menu, Time time) +{ + + int root_x, root_y; + Window unused; + + REQUIRE(menu != NULL); + + if (time != CurrentTime) { + button_press_time = time; + } + if (win != Xroot) { + XTranslateCoordinates(Xdisplay, win, Xroot, x, y, &root_x, &root_y, &unused); + } + menu_display(root_x, root_y, menu); + +} + +void +menu_invoke_by_title(int x, int y, Window win, char *title, Time time) +{ + + menu_t *menu; + + REQUIRE(title != NULL); + REQUIRE(menu_list != NULL); + + menu = find_menu_by_title(menu_list, title); + if (!menu) { + D_MENU(("Menu \"%s\" not found!\n", title)); + return; + } + menu_invoke(x, y, win, menu, time); +} diff --git a/src/menus.h b/src/menus.h new file mode 100644 index 0000000..600c6d4 --- /dev/null +++ b/src/menus.h @@ -0,0 +1,134 @@ +/* menus.h -- Eterm popup menu module header file + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ +#ifndef _MENUS_H +# define _MENUS_H + +# include +# include +# include "events.h" +# include "pixmap.h" + +/************ Macros and Definitions ************/ +#define MENUITEM_SEP (1UL << 0) +#define MENUITEM_SUBMENU (1UL << 1) +#define MENUITEM_STRING (1UL << 2) +#define MENUITEM_ECHO (1UL << 3) + +#define MENU_STATE_IS_MAPPED (1UL << 0) +#define MENU_STATE_IS_CURRENT (1UL << 1) +#define MENU_STATE_IS_DRAGGING (1UL << 2) +#define MENU_STATE_IS_SUBMENU (1UL << 3) +#define MENU_STATE_IS_FOCUSED (1UL << 4) + +/* Constants */ +#define MENU_HGAP 4 +#define MENU_VGAP 4 +#define MENU_CLICK_TIME 20 + +#define menu_is_pixmapped() (images[image_menu].current->iml->im) + +/************ Structures ************/ +typedef struct menu_t_struct menu_t; + +typedef struct { + image_t *icon; + unsigned char type, state; + union { + menu_t *submenu; + char *string; + } action; + char *text, *rtext; + unsigned short len, rlen; + unsigned short x, y, w, h; +} menuitem_t; + +struct menu_t_struct { + char *title; + Window win, swin; + unsigned short x, y, w, h; + GC gc; + unsigned char state; + XFontStruct *font; +#ifdef MULTI_CHARSET + XFontSet fontset; +#endif + unsigned short fwidth, fheight; + unsigned short numitems, curitem; + menuitem_t **items; +}; + +typedef struct { + unsigned char nummenus; + menu_t **menus; +} menulist_t; + +/************ Variables ************/ +extern menulist_t *menu_list; + +/************ Function Prototypes ************/ +_XFUNCPROTOBEGIN + +extern void menu_init(void); +extern void menu_event_init_dispatcher(void); +extern unsigned char menu_handle_enter_notify(event_t *); +extern unsigned char menu_handle_leave_notify(event_t *); +extern unsigned char menu_handle_focus_in(event_t *); +extern unsigned char menu_handle_focus_out(event_t *); +extern unsigned char menu_handle_expose(event_t *); +extern unsigned char menu_handle_button_press(event_t *); +extern unsigned char menu_handle_button_release(event_t *); +extern unsigned char menu_handle_motion_notify(event_t *); +extern unsigned char menu_dispatch_event(event_t *); +extern menulist_t *menulist_add_menu(menulist_t *, menu_t *); +extern menu_t *menu_create(char *); +extern unsigned char menu_set_font(menu_t *, const char *); +extern unsigned char menu_add_item(menu_t *, menuitem_t *); +extern unsigned char menu_is_child(menu_t *, menu_t *); +extern menu_t *find_menu_by_title(menulist_t *, char *); +extern menu_t *find_menu_by_window(menulist_t *, Window); +extern menuitem_t *find_item_by_coords(menu_t *, int, int); +extern unsigned short find_item_in_menu(menu_t *, menuitem_t *); +extern void menuitem_change_current(menuitem_t *); +extern menuitem_t *menuitem_create(char *); +extern unsigned char menuitem_set_icon(menuitem_t *, image_t *); +extern unsigned char menuitem_set_action(menuitem_t *, unsigned char, char *); +extern unsigned char menuitem_set_rtext(menuitem_t *, char *); + +extern void menu_reset(menu_t *); +extern void menu_reset_all(menulist_t *); +extern void menu_reset_tree(menu_t *); +extern void menu_reset_submenus(menu_t *); +extern void menuitem_select(menu_t *, menuitem_t *); +extern void menuitem_deselect(menu_t *, menuitem_t *); +extern void menu_display_submenu(menu_t *, menuitem_t *); +extern void menu_draw(menu_t *); +extern void menu_display(int, int, menu_t *); +extern void menu_action(menuitem_t *); +extern void menu_invoke(int, int, Window, menu_t *, Time); +extern void menu_invoke_by_title(int, int, Window, char *, Time); + +_XFUNCPROTOEND + +#endif /* _MENUS_H */ diff --git a/src/misc.c b/src/misc.c index c75a99b..8b24956 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1,35 +1,48 @@ -/*--------------------------------*-C-*---------------------------------* - * File: misc.c +/* misc.c -- Eterm toolkit routines + + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. * - * miscellaneous service routines + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen * - * Copyright 1996,97 - * mj olesen Queen's Univ at Kingston - * - * You can do what you like with this source code provided you don't make - * money from it and you include an unaltered copy of this message - * (including the copyright). As usual, the author accepts no - * responsibility for anything, nor does he guarantee anything whatsoever. - *----------------------------------------------------------------------*/ + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ static const char cvs_ident[] = "$Id$"; +#include "config.h" +#include "feature.h" + #include #include #include #include #include +#include "../libmej/debug.h" +#include "debug.h" +#include "../libmej/mem.h" +#include "../libmej/strings.h" #include "command.h" #include "main.h" #include "misc.h" -#include "debug.h" -#include "../libmej/debug.h" -#include "../libmej/strings.h" -#include "mem.h" #include "options.h" -/*----------------------------------------------------------------------*/ const char * my_basename(const char *str) { @@ -155,8 +168,6 @@ str_trim(char *str) * returns the converted string length */ -#define MAKE_CTRL_CHAR(c) ((c) == '?' ? 127 : ((toupper(c)) - '@')) - int parse_escaped_string(char *str) { @@ -164,20 +175,20 @@ parse_escaped_string(char *str) register char *pold, *pnew; unsigned char i; - D_MENUBAR(("parse_escaped_string(\"%s\")\n", str)); + D_STRINGS(("parse_escaped_string(\"%s\")\n", str)); for (pold = pnew = str; *pold; pold++, pnew++) { - D_MENUBAR(("Looking at \"%s\"\n", pold)); + D_STRINGS(("Looking at \"%s\"\n", pold)); if (!BEG_STRCASECMP(pold, "m-")) { *pold = '\\'; *(pold + 1) = 'e'; } else if (!BEG_STRCASECMP(pold, "c-")) { *(++pold) = '^'; } - D_MENUBAR(("Operating on \'%c\'\n", *pold)); + D_STRINGS(("Operating on \'%c\'\n", *pold)); switch (*pold) { case '\\': - D_MENUBAR(("Backslash + %c\n", *(pold + 1))); + D_STRINGS(("Backslash + %c\n", *(pold + 1))); switch (tolower(*(++pold))) { case '0': case '1': @@ -191,7 +202,7 @@ parse_escaped_string(char *str) i = (i * 8) + (*pold - '0'); } pold--; - D_MENUBAR(("Octal number evaluates to %d\n", i)); + D_STRINGS(("Octal number evaluates to %d\n", i)); *pnew = i; break; case 'n': @@ -228,7 +239,7 @@ parse_escaped_string(char *str) } break; case '^': - D_MENUBAR(("Caret + %c\n", *(pold + 1))); + D_STRINGS(("Caret + %c\n", *(pold + 1))); pold++; *pnew = MAKE_CTRL_CHAR(*pold); break; @@ -238,17 +249,17 @@ parse_escaped_string(char *str) } if (!BEG_STRCASECMP(str, "\033x") && *(pnew - 1) != '\r') { - D_MENUBAR(("Adding carriage return\n")); + D_STRINGS(("Adding carriage return\n")); *(pnew++) = '\r'; - } else if (!BEG_STRCASECMP(str, "\0\e]") && *(pnew - 1) != '\a') { - D_MENUBAR(("Adding bell character\n")); + } else if (!BEG_STRCASECMP(str, "\e]") && *(pnew - 1) != '\a') { + D_STRINGS(("Adding bell character\n")); *(pnew++) = '\a'; } *pnew = 0; -#if DEBUG >= DEBUG_MENU - if (debug_level >= DEBUG_MENU) { - D_MENUBAR(("New value is:\n\n")); +#if DEBUG >= DEBUG_STRINGS + if (debug_level >= DEBUG_STRINGS) { + D_STRINGS(("New value is:\n\n")); HexDump(str, (size_t) (pnew - str)); } #endif @@ -262,16 +273,10 @@ find_file(const char *file, const char *ext) const char *f; -#if defined(PIXMAP_SUPPORT) || (MENUBAR_MAX) +#if defined(PIXMAP_SUPPORT) if ((f = search_path(rs_path, file, ext)) != NULL) { return (f); - } else -# ifdef PATH_ENV - if ((f = search_path(getenv(PATH_ENV), file, ext)) != NULL) { - return (f); - } else -# endif - if ((f = search_path(getenv("PATH"), file, ext)) != NULL) { + } else if ((f = search_path(getenv(PATH_ENV), file, ext)) != NULL) { return (f); } else { return (search_path(initial_dir, file, ext)); @@ -376,4 +381,3 @@ Draw_Triangle(Window win, GC topShadow, GC botShadow, int x, int y, int w, int t #endif } } -/*----------------------- end-of-file (C source) -----------------------*/ diff --git a/src/misc.h b/src/misc.h index fb58a3f..bd4e1c7 100644 --- a/src/misc.h +++ b/src/misc.h @@ -1,37 +1,53 @@ -/*--------------------------------*-C-*---------------------------------* - * File: misc.h +/* misc.h -- Eterm toolkit header file * - * miscellaneous service routines + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. * - * Copyright 1996,97 - * mj olesen Queen's Univ at Kingston + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen * - * You can do what you like with this source code provided you don't make - * money from it and you include an unaltered copy of this message - * (including the copyright). As usual, the author accepts no - * responsibility for anything, nor does he guarantee anything whatsoever. - *----------------------------------------------------------------------*/ + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ #ifndef _MISC_H_ #define _MISC_H_ + +#include /* Xlib, Xutil, Xresource, Xfuncproto */ #include -/* prototypes */ +/************ Macros and Definitions ************/ +#define MAKE_CTRL_CHAR(c) ((c) == '?' ? 127 : ((toupper(c)) - '@')) + +/************ Function Prototypes ************/ _XFUNCPROTOBEGIN -const char *my_basename(const char *str); -void print_error(const char *fmt,...); -void print_warning(const char *fmt,...); -void fatal_error(const char *fmt,...); -unsigned long str_leading_match(register const char *, register const char *); -char *str_trim(char *str); -int parse_escaped_string(char *str); -const char *search_path(const char *pathlist, const char *file, const char *ext); -const char *find_file(const char *file, const char *ext); -void Draw_tl(Window win, GC gc, int x, int y, int w, int h); -void Draw_br(Window win, GC gc, int x, int y, int w, int h); -void Draw_Shadow(Window win, GC topShadow, GC botShadow, int x, int y, int w, int h); -void Draw_Triangle(Window win, GC topShadow, GC botShadow, int x, int y, int w, int type); +extern const char *my_basename(const char *str); +extern void print_error(const char *fmt,...); +extern void print_warning(const char *fmt,...); +extern void fatal_error(const char *fmt,...); +extern unsigned long str_leading_match(register const char *, register const char *); +extern char *str_trim(char *str); +extern int parse_escaped_string(char *str); +extern const char *search_path(const char *pathlist, const char *file, const char *ext); +extern const char *find_file(const char *file, const char *ext); +extern void Draw_tl(Window win, GC gc, int x, int y, int w, int h); +extern void Draw_br(Window win, GC gc, int x, int y, int w, int h); +extern void Draw_Shadow(Window win, GC topShadow, GC botShadow, int x, int y, int w, int h); +extern void Draw_Triangle(Window win, GC topShadow, GC botShadow, int x, int y, int w, int type); _XFUNCPROTOEND diff --git a/src/netdisp.c b/src/netdisp.c index a3a8d18..a3f652c 100644 --- a/src/netdisp.c +++ b/src/netdisp.c @@ -1,7 +1,3 @@ -/*--------------------------------*-C-*---------------------------------* - * File: netdisp.c - */ -/*{{{ notes: */ /*----------------------------------------------------------------------* * support for resolving the actual IP number of the host for remote * DISPLAYs. When the display is local (i.e. :0), we add support for @@ -26,17 +22,7 @@ static const char cvs_ident[] = "$Id$"; #include "config.h" #include "feature.h" -#include "main.h" -/* Put in a dummy routine if this is disabled, inline it if possible */ -#ifndef DISPLAY_IS_IP -inline const char * -network_display(const char *display) -{ - return (display); -} -#else -/*{{{ includes */ #include #include #include @@ -48,19 +34,14 @@ network_display(const char *display) #ifdef HAVE_UNISTD_H # include #endif - -/* On Solaris link with -lsocket and -lnsl */ #include #include - -/* these next two are probably only on Sun (not Solaris) */ #ifdef HAVE_SYS_SOCKIO_H # include #endif #ifdef HAVE_SYS_BYTEORDER_H # include #endif - #ifdef TIME_WITH_SYS_TIME # include # include @@ -71,17 +52,24 @@ network_display(const char *display) # include # endif #endif - #ifdef HAVE_SYS_IOCTL_H # include #endif - #include #include #include #include -/*----------------------------------------------------------------------*/ +#include "main.h" + +/* Put in a dummy routine if this is disabled, inline it if possible */ +#ifndef DISPLAY_IS_IP +inline const char * +network_display(const char *display) +{ + return (display); +} +#else /* return a pointer to a static buffer */ char * network_display(const char *display) diff --git a/src/options.c b/src/options.c index 96cfa2c..99cbdd3 100644 --- a/src/options.c +++ b/src/options.c @@ -1,7 +1,7 @@ /* options.c -- Eterm options module * -- 25 July 1997, mej * - * This file is original work by Michael Jennings and + * This file is original work by Michael Jennings and * Tuomo Venalainen . This file, and any other file * bearing this same message or a similar one, is distributed under * the GNU Public License (GPL) as outlined in the COPYING file. @@ -26,92 +26,38 @@ static const char cvs_ident[] = "$Id$"; -#include "main.h" +#include "config.h" #include "feature.h" +#include #include #include #include #include +#include +#include #include #include +#include #include + #include "../libmej/debug.h" +#include "../libmej/mem.h" #include "../libmej/strings.h" #include "debug.h" -#include "mem.h" -#include "strings.h" +#include "actions.h" #include "command.h" +#include "events.h" #include "grkelot.h" -#include "menubar.h" +#include "main.h" +#include "menus.h" #include "options.h" #include "pixmap.h" #include "scrollbar.h" #include "screen.h" #include "system.h" - -#if PATH_MAX < 1024 -# undef PATH_MAX -# define PATH_MAX 1024 -#endif - -const char *true_vals[] = -{"1", "on", "true", "yes"}; -const char *false_vals[] = -{"0", "off", "false", "no"}; - -char **rs_execArgs = NULL; /* Args to exec (-e or --exec) */ -char *rs_title = NULL; /* Window title */ -char *rs_iconName = NULL; /* Icon name */ -char *rs_geometry = NULL; /* Geometry string */ -int rs_desktop = -1; -char *rs_path = NULL; -int rs_saveLines = SAVELINES; /* Lines in the scrollback buffer */ - -#ifdef KEYSYM_ATTRIBUTE -unsigned char *KeySym_map[256]; /* probably mostly empty */ - -#endif -#if defined (HOTKEY_CTRL) || defined (HOTKEY_META) -/* recognized when combined with HOTKEY */ -KeySym ks_bigfont = XK_greater; -KeySym ks_smallfont = XK_less; - -#endif -#ifdef PIXMAP_SUPPORT -char *rs_pixmapScale = NULL; -const char *rs_saveUnder = NULL; -char *rs_icon = NULL; - -# ifdef BACKGROUND_CYCLING_SUPPORT -char *rs_anim_pixmap_list = NULL; -char **rs_anim_pixmaps = NULL; -time_t rs_anim_delay = 0; - -# endif -# ifdef PIXMAP_OFFSET -char *rs_viewport_mode = NULL; -const char *rs_pixmapTrans = NULL; -unsigned long rs_tintMask = 0xffffff; -unsigned int rs_shadePct = 0; - -# ifdef WATCH_DESKTOP_OPTION -const char *rs_watchDesktop = NULL; - -# endif -# endif -char *rs_pixmaps[11] = -{NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL}; - -#endif -char *rs_noCursor = NULL; - -#ifdef USE_THEMES -char *rs_theme = NULL; -char *rs_config_file = NULL; - -#endif +#include "term.h" +#include "windows.h" /* local functions referenced */ char *chomp(char *); @@ -121,23 +67,152 @@ void parse_attributes(char *); void parse_toggles(char *); void parse_keyboard(char *); void parse_misc(char *); -void parse_pixmaps(char *); -void parse_kanji(char *); +void parse_imageclasses(char *); +void parse_image(char *); +void parse_actions(char *); +void parse_menu(char *); +void parse_menuitem(char *); +void parse_xim(char *); +void parse_multichar(char *); void parse_undef(char *); char *builtin_random(char *); char *builtin_exec(char *); char *builtin_version(char *); char *builtin_appname(char *); -/* local variables */ +const char *true_vals[] = +{"1", "on", "true", "yes"}; +const char *false_vals[] = +{"0", "off", "false", "no"}; +/* This structure defines a context and its attributes */ +struct context_struct { + const unsigned char id; + const char *description; + void (*ctx_handler) (char *); + const unsigned char valid_sub_contexts[CTX_MAX]; +} contexts[] = { + + { + CTX_NULL, "none", NULL, { + CTX_MAIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_MAIN, "main", parse_main, { + CTX_COLOR, CTX_ATTRIBUTES, CTX_TOGGLES, CTX_KEYBOARD, + CTX_MISC, CTX_IMAGECLASSES, CTX_ACTIONS, + CTX_MENU, CTX_XIM, CTX_MULTI_CHARSET, 0, 0, 0 + } + }, + { + CTX_COLOR, "color", parse_color, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_ATTRIBUTES, "attributes", parse_attributes, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_TOGGLES, "toggles", parse_toggles, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_KEYBOARD, "keyboard", parse_keyboard, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_MISC, "misc", parse_misc, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_IMAGECLASSES, "imageclasses", parse_imageclasses, { + CTX_IMAGE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_IMAGE, "image", parse_image, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_ACTIONS, "actions", parse_actions, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_MENU, "menu", parse_menu, { + CTX_MENUITEM, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_MENUITEM, "menuitem", parse_menuitem, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_XIM, "xim", parse_xim, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_MULTI_CHARSET, "multichar", parse_multichar, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + CTX_UNDEF, NULL, parse_undef, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + } + +}; +unsigned char id_stack[MAX_CTX_DEPTH]; +unsigned short cur_ctx = 0; +file_state file_stack[MAX_FILE_DEPTH]; +short cur_file = -1; +eterm_func builtins[] = +{ + {"random", builtin_random, -1}, + {"exec", builtin_exec, -1}, + {"version", builtin_version, 0}, + {"appname", builtin_appname, 0}, + {(char *) NULL, (eterm_function_ptr) NULL, 0} +}; +unsigned long Options = (Opt_scrollBar); +static menu_t *curmenu; +char *theme_dir = NULL, *user_dir = NULL; +char **rs_execArgs = NULL; /* Args to exec (-e or --exec) */ +char *rs_title = NULL; /* Window title */ +char *rs_iconName = NULL; /* Icon name */ +char *rs_geometry = NULL; /* Geometry string */ +int rs_desktop = -1; +char *rs_path = NULL; +int rs_saveLines = SAVELINES; /* Lines in the scrollback buffer */ +#ifdef USE_XIM +char *rs_inputMethod = NULL; +char *rs_preeditType = NULL; +#endif +char *rs_name = NULL; +#ifndef NO_BOLDFONT +const char *rs_boldFont = NULL; +#endif +const char *rs_font[NFONTS]; +#ifdef MULTI_CHARSET +const char *rs_mfont[NFONTS]; +#endif +#ifdef PRINTPIPE +char *rs_print_pipe = NULL; +#endif +char *rs_cutchars = NULL; const char *rs_loginShell = NULL; const char *rs_utmpLogging = NULL; const char *rs_scrollBar = NULL; - -#if (MENUBAR_MAX) -const char *rs_menubar = NULL; - -#endif +const char *rs_install = NULL; const char *rs_app_keypad = NULL; const char *rs_app_cursor = NULL; const char *rs_homeOnEcho = NULL; @@ -151,64 +226,64 @@ const char *rs_pause = NULL; const char *rs_xterm_select = NULL; const char *rs_select_whole_line = NULL; const char *rs_select_trailing_spaces = NULL; +const char *rs_report_as_keysyms = NULL; unsigned short rs_min_anchor_size = 0; - char *rs_scrollbar_type = NULL; unsigned long rs_scrollbar_width = 0; -const char *rs_term_name = NULL; - -#if MENUBAR_MAX -const char *rs_menubar_move = NULL; -const char *rs_menu = NULL; - -#endif - +char *rs_term_name = NULL; #if defined (HOTKEY_CTRL) || defined (HOTKEY_META) static char *rs_bigfont_key = NULL; static char *rs_smallfont_key = NULL; - #endif - #ifndef NO_MAPALERT # ifdef MAPALERT_OPTION static const char *rs_mapAlert = NULL; - # endif #endif static const char *rs_visualBell = NULL; static const char *rs_reverseVideo = NULL; - #ifdef META8_OPTION static const char *rs_meta8 = NULL; - #endif -#ifdef KANJI -static char *rs_kanji_encoding = NULL; - +#ifdef MULTI_CHARSET +static char *rs_multchar_encoding = NULL; #endif #ifdef GREEK_SUPPORT static char *rs_greek_keyboard = NULL; - +#endif +#ifdef PIXMAP_SUPPORT +char *rs_pixmapScale = NULL; +const char *rs_saveUnder = NULL; +char *rs_icon = NULL; +char *rs_cmod_image = NULL; +char *rs_cmod_red = NULL; +char *rs_cmod_green = NULL; +char *rs_cmod_blue = NULL; +# ifdef BACKGROUND_CYCLING_SUPPORT +char *rs_anim_pixmap_list = NULL; +char **rs_anim_pixmaps = NULL; +time_t rs_anim_delay = 0; +# endif +# ifdef PIXMAP_OFFSET +char *rs_viewport_mode = NULL; +const char *rs_pixmapTrans = NULL; +# endif +static char *rs_pixmaps[image_max]; +#endif +char *rs_noCursor = NULL; +char *rs_theme = NULL; +char *rs_config_file = NULL; +unsigned int rs_line_space = 0; +#ifdef KEYSYM_ATTRIBUTE +unsigned char *KeySym_map[256]; /* probably mostly empty */ +#endif +#if defined (HOTKEY_CTRL) || defined (HOTKEY_META) +/* recognized when combined with HOTKEY */ +KeySym ks_bigfont = XK_greater; +KeySym ks_smallfont = XK_less; #endif -extern char initial_dir[PATH_MAX + 1]; - /* Options structure */ - -#define OPT_BOOLEAN 0x0001 -#define OPT_INTEGER 0x0002 -#define OPT_STRING 0x0004 -#define OPT_ARGUMENT 0x0008 - -#define OPT_STR(s, l, d, p) { s, l, "(str) " d, OPT_STRING, (const char **) p, 0, 0 } -#define OPT_INT(s, l, d, p) { s, l, "(int) " d, OPT_INTEGER, (const int *) p, 0, 0 } -#define OPT_BOOL(s, l, d, p, v, m) { s, l, "(bool) " d, OPT_BOOLEAN, (const int *) p, v, m } -#define OPT_LONG(l, d, p) { 0, l, "(str) " d, OPT_STRING, (const char **) p, 0, 0 } -#define OPT_ARGS(s, l, d, p) { s, l, "(str) " d, OPT_ARGUMENT, (const char ***) p, 0, 0 } -#define OPT_BLONG(l, d, p, v, m) { 0, l, "(bool) " d, OPT_BOOLEAN, (const int *) p, v, m } -#define OPT_ILONG(l, d, p) { 0, l, "(int) " d, OPT_INTEGER, (const int *) p, 0, 0 } -#define optList_numoptions() (sizeof(optList)/sizeof(optList[0])) - static const struct { char short_opt; char *long_opt; @@ -219,12 +294,9 @@ static const struct { int mask; } optList[] = { -#ifdef USE_THEMES /* These two MUST be first! */ OPT_STR('t', "theme", "select a theme", &rs_theme), OPT_STR('X', "config-file", "choose an alternate config file", &rs_config_file), -#endif /* USE_THEMES */ - OPT_BOOL('h', "help", "display usage information", NULL, NULL, 0), - OPT_BLONG("version", "display version and configuration information", NULL, NULL, 0), + OPT_STR('d', "display", "X server to connect to", &display_name), #if DEBUG <= 0 OPT_ILONG("debug", "level of debugging information to show (support not compiled in)", &debug_level), #elif DEBUG == 1 @@ -238,6 +310,10 @@ static const struct { #else OPT_ILONG("debug", "level of debugging information to show (0-5)", &debug_level), #endif + OPT_BLONG("install", "install a private colormap", &rs_install, &Options, Opt_install), + + OPT_BOOL('h', "help", "display usage information", NULL, NULL, 0), + OPT_BLONG("version", "display version and configuration information", NULL, NULL, 0), /* =======[ Color options ]======= */ OPT_BOOL('r', "reverse-video", "reverse video", &rs_reverseVideo, &Options, Opt_reverseVideo), @@ -265,13 +341,11 @@ static const struct { OPT_LONG("colorBD", "bold color", &rs_color[colorBD]), OPT_LONG("colorUL", "underline color", &rs_color[colorUL]), #endif /* NO_BOLDUNDERLINE */ + OPT_LONG("menur-color", "menu color", &rs_color[menuColor]), OPT_LONG("menu-text-color", "menu text color", &rs_color[menuTextColor]), -#ifdef KEEP_SCROLLCOLOR OPT_STR('S', "scrollbar-color", "scrollbar color", &rs_color[scrollColor]), -# ifdef CHANGE_SCROLLCOLOR_ON_FOCUS + OPT_LONG("unfocused-menu-color", "unfocused menu color", &rs_color[unfocusedMenuColor]), OPT_LONG("unfocused-scrollbar-color", "unfocused scrollbar color", &rs_color[unfocusedScrollColor]), -# endif -#endif /* KEEP_SCROLLCOLOR */ OPT_LONG("pointer-color", "mouse pointer color", &rs_color[pointerColor]), #ifndef NO_CURSORCOLOR OPT_STR('c', "cursor-color", "cursor color", &rs_color[cursorColor]), @@ -279,7 +353,6 @@ static const struct { #endif /* NO_CURSORCOLOR */ /* =======[ X11 options ]======= */ - OPT_STR('d', "display", "X server to connect to", &display_name), OPT_STR('g', "geometry", "WxH+X+Y = size and position", &rs_geometry), OPT_BOOL('i', "iconic", "start iconified", NULL, &Options, Opt_iconic), OPT_STR('n', "name", "client instance, icon, and title strings", &rs_name), @@ -288,6 +361,7 @@ static const struct { OPT_STR('B', "scrollbar-type", "choose the scrollbar type (motif, next, xterm)", &rs_scrollbar_type), OPT_ILONG("scrollbar-width", "choose the width (in pixels) of the scrollbar", &rs_scrollbar_width), OPT_INT('D', "desktop", "desktop to start on (requires GNOME-compliant window manager)", &rs_desktop), + OPT_ILONG("line-space", "number of extra dots between lines", &rs_line_space), #ifndef NO_BOLDFONT OPT_LONG("bold-font", "bold text font", &rs_boldFont), #endif @@ -299,20 +373,20 @@ static const struct { /* =======[ Pixmap options ]======= */ #ifdef PIXMAP_SUPPORT - OPT_STR('P', "background-pixmap", "background pixmap [scaling optional]", &rs_pixmaps[pixmap_bg]), + OPT_STR('P', "background-pixmap", "background pixmap [scaling optional]", &rs_pixmaps[image_bg]), OPT_STR('I', "icon", "icon pixmap", &rs_icon), - OPT_LONG("up-arrow-pixmap", "up arrow pixmap [scaling optional]", &rs_pixmaps[pixmap_up]), - OPT_LONG("down-arrow-pixmap", "down arrow pixmap [scaling optional]", &rs_pixmaps[pixmap_dn]), - OPT_LONG("trough-pixmap", "scrollbar background (trough) pixmap [scaling optional]", &rs_pixmaps[pixmap_sb]), - OPT_LONG("anchor-pixmap", "scrollbar anchor pixmap [scaling optional]", &rs_pixmaps[pixmap_sa]), + OPT_LONG("up-arrow-pixmap", "up arrow pixmap [scaling optional]", &rs_pixmaps[image_up]), + OPT_LONG("down-arrow-pixmap", "down arrow pixmap [scaling optional]", &rs_pixmaps[image_down]), + OPT_LONG("trough-pixmap", "scrollbar background (trough) pixmap [scaling optional]", &rs_pixmaps[image_sb]), + OPT_LONG("anchor-pixmap", "scrollbar anchor pixmap [scaling optional]", &rs_pixmaps[image_sa]), + OPT_LONG("menu-pixmap", "menu pixmap [scaling optional]", &rs_pixmaps[image_menu]), OPT_BOOL('@', "scale", "scale rather than tile", &rs_pixmapScale, &Options, Opt_pixmapScale), # ifdef PIXMAP_OFFSET -# ifdef WATCH_DESKTOP_OPTION - OPT_BOOL('W', "watch-desktop", "watch the desktop background image for changes", &rs_watchDesktop, &Options, Opt_watchDesktop), -# endif OPT_BOOL('O', "trans", "creates a pseudo-transparent Eterm", &rs_pixmapTrans, &Options, Opt_pixmapTrans), - OPT_ILONG("shade", "percentage to shade the background in a pseudo-transparent Eterm", &rs_shadePct), - OPT_ILONG("tint", "RGB brightness mask for color tinting in a pseudo-transparent Eterm", &rs_tintMask), + OPT_LONG("cmod", "image color modifier (\"brightness contrast gamma\")", &rs_cmod_image), + OPT_LONG("cmod-red", "red-only color modifier (\"brightness contrast gamma\")", &rs_cmod_red), + OPT_LONG("cmod-green", "green-only color modifier (\"brightness contrast gamma\")", &rs_cmod_green), + OPT_LONG("cmod-blue", "blue-only color modifier (\"brightness contrast gamma\")", &rs_cmod_blue), # endif OPT_STR('p', "path", "pixmap file search path", &rs_path), # ifdef BACKGROUND_CYCLING_SUPPORT @@ -321,19 +395,23 @@ static const struct { #endif /* PIXMAP_SUPPORT */ /* =======[ Kanji options ]======= */ -#ifdef KANJI - OPT_STR('K', "kanji-font", "normal text kanji font", &rs_kfont[0]), - OPT_LONG("kanji-font1", "kanji font 1", &rs_kfont[1]), - OPT_LONG("kanji-font2", "kanji font 2", &rs_kfont[2]), - OPT_LONG("kanji-font3", "kanji font 3", &rs_kfont[3]), - OPT_LONG("kanji-font4", "kanji font 4", &rs_kfont[4]), - OPT_LONG("kanji-encoding", "kanji encoding mode (eucj or sjis)", &rs_kanji_encoding), -#endif /* KANJI */ +#ifdef MULTI_CHARSET + OPT_STR('M', "mfont", "normal text multichar font", &rs_mfont[0]), + OPT_LONG("mfont1", "multichar font 1", &rs_mfont[1]), + OPT_LONG("mfont2", "multichar font 2", &rs_mfont[2]), + OPT_LONG("mfont3", "multichar font 3", &rs_mfont[3]), + OPT_LONG("mfont4", "multichar font 4", &rs_mfont[4]), + OPT_LONG("mencoding", "multichar encoding mode (eucj or sjis or euckr)", + &rs_multchar_encoding), +#endif /* MULTI_CHARSET */ +#ifdef USE_XIM + OPT_LONG("input-method", "XIM input method", &rs_inputMethod), + OPT_LONG("preedit-type", "XIM preedit type", &rs_preeditType), +#endif /* =======[ Toggles ]======= */ OPT_BOOL('l', "login-shell", "login shell, prepend - to shell name", &rs_loginShell, &Options, Opt_loginShell), OPT_BOOL('s', "scrollbar", "display scrollbar", &rs_scrollBar, &Options, Opt_scrollBar), - OPT_BLONG("menubar", "display menubar", &rs_menubar, NULL, 0), OPT_BOOL('u', "utmp-logging", "make a utmp entry", &rs_utmpLogging, &Options, Opt_utmpLogging), OPT_BOOL('v', "visual-bell", "visual bell", &rs_visualBell, &Options, Opt_visualBell), OPT_BOOL('H', "home-on-echo", "jump to bottom on output", &rs_homeOnEcho, &Options, Opt_homeOnEcho), @@ -355,13 +433,11 @@ static const struct { OPT_BLONG("save-under", "use backing store", &rs_saveUnder, &Options, Opt_saveUnder), #endif OPT_BLONG("no-cursor", "disable the text cursor", &rs_noCursor, &Options, Opt_noCursor), -#if MENUBAR_MAX - OPT_BOOL('V', "menubar-move", "dragging the menubar will move the window", &rs_menubar_move, &Options, Opt_menubar_move), -#endif OPT_BLONG("pause", "pause for a keypress after the child process exits", &rs_pause, &Options, Opt_pause), OPT_BLONG("xterm-select", "duplicate xterm's broken selection behavior", &rs_xterm_select, &Options, Opt_xterm_select), OPT_BLONG("select-line", "triple-click selects whole line", &rs_select_whole_line, &Options, Opt_select_whole_line), OPT_BLONG("select-trailing-spaces", "do not skip trailing spaces when selecting", &rs_select_trailing_spaces, &Options, Opt_select_trailing_spaces), + OPT_BLONG("report-as-keysyms", "report special keys as keysyms", &rs_report_as_keysyms, &Options, Opt_report_as_keysyms), #ifdef PIXMAP_OFFSET OPT_BLONG("viewport-mode", "use viewport mode for the background image", &rs_viewport_mode, &Options, Opt_viewport_mode), #endif @@ -389,9 +465,6 @@ static const struct { #ifdef CUTCHAR_OPTION OPT_LONG("cut-chars", "seperators for double-click selection", &rs_cutchars), #endif /* CUTCHAR_OPTION */ -#if MENUBAR_MAX - OPT_STR('M', "menu", "Default menubar file", &rs_menu), -#endif OPT_LONG("term-name", "value to use for setting $TERM", &rs_term_name), OPT_BOOL('C', "console", "grab console messages", NULL, &Options, Opt_console), OPT_ARGS('e', "exec", "execute a command rather than a shell", &rs_execArgs) @@ -403,7 +476,7 @@ static void usage(void) { - int i, col; + unsigned short i, col; printf("Eterm Enlightened Terminal Emulator for X Windows\n"); printf("Copyright (c) 1997-1999, Tuomo Venalainen and Michael Jennings\n\n"); @@ -445,8 +518,6 @@ static void version(void) { - int i, col; - printf("Eterm " VERSION "\n"); printf("Copyright (c) 1997-1999, Tuomo Venalainen and Michael Jennings\n\n"); @@ -496,9 +567,6 @@ version(void) #if DEBUG >= DEBUG_THREADS printf(" +DEBUG_THREADS"); #endif -#if DEBUG >= DEBUG_TAGS - printf(" +DEBUG_TAGS"); -#endif #if DEBUG >= DEBUG_MENU printf(" +DEBUG_MENU"); #endif @@ -508,15 +576,6 @@ version(void) #if DEBUG >= DEBUG_COLORS printf(" +DEBUG_COLORS"); #endif -#if DEBUG >= DEBUG_MENUARROWS - printf(" +DEBUG_MENUARROWS"); -#endif -#if DEBUG >= DEBUG_MENU_LAYOUT - printf(" +DEBUG_MENU_LAYOUT"); -#endif -#if DEBUG >= DEBUG_MENUBAR_STACKING - printf(" +DEBUG_MENUBAR_STACKING"); -#endif #if DEBUG >= DEBUG_X printf(" +DEBUG_X"); #endif @@ -543,11 +602,6 @@ version(void) #else printf(" -COUNT_X_EVENTS"); #endif -#ifdef USE_ACTIVE_TAGS - printf(" +USE_ACTIVE_TAGS"); -#else - printf(" -USE_ACTIVE_TAGS"); -#endif #ifdef OPTIMIZE_HACKS printf(" +OPTIMIZE_HACKS"); #else @@ -598,30 +652,11 @@ version(void) #else printf(" -BACKING_STORE"); #endif -#ifdef USE_IMLIB -# ifdef OLD_IMLIB - printf(" +USE_IMLIB (OLD_IMLIB)"); -# elif defined(NEW_IMLIB) - printf(" +USE_IMLIB (NEW_IMLIB)"); -# endif -#else - printf(" -USE_IMLIB"); -#endif -#ifdef USE_THEMES - printf(" +USE_THEMES"); -#else - printf(" -USE_THEMES"); -#endif #ifdef USE_EFFECTS printf(" +USE_EFFECTS"); #else printf(" -USE_EFFECTS"); #endif -#ifdef WATCH_DESKTOP_OPTION - printf(" +WATCH_DESKTOP_OPTION"); -#else - printf(" -WATCH_DESKTOP_OPTION"); -#endif #ifdef NO_CURSORCOLOR printf(" +NO_CURSORCOLOR"); #else @@ -712,10 +747,10 @@ version(void) #else printf(" -KEYSYM_ATTRIBUTE"); #endif -#ifdef NO_XLOCALE - printf(" +NO_XLOCALE"); +#ifdef USE_XIM + printf(" +XIM"); #else - printf(" -NO_XLOCALE"); + printf(" -XIM"); #endif #ifdef UNSHIFTED_SCROLLKEYS printf(" +UNSHIFTED_SCROLLKEYS"); @@ -752,16 +787,6 @@ version(void) #else printf(" -NEXT_SCROLLBAR"); #endif -#ifdef KEEP_SCROLLCOLOR - printf(" +KEEP_SCROLLCOLOR"); -#else - printf(" -KEEP_SCROLLCOLOR"); -#endif -#ifdef CHANGE_SCROLLCOLOR_ON_FOCUS - printf(" +CHANGE_SCROLLCOLOR_ON_FOCUS"); -#else - printf(" -CHANGE_SCROLLCOLOR_ON_FOCUS"); -#endif #ifdef SCROLLBAR_BUTTON_CONTINUAL_SCROLLING printf(" +SCROLLBAR_BUTTON_CONTINUAL_SCROLLING"); #else @@ -772,21 +797,11 @@ version(void) #else printf(" -USE_SMOOTH_REFRESH"); #endif -#ifdef MENUBAR_SHADOW_IN - printf(" +MENUBAR_SHADOW_IN"); -#else - printf(" -MENUBAR_SHADOW_IN"); -#endif #ifdef MENU_SHADOW_IN printf(" +MENU_SHADOW_IN"); #else printf(" -MENU_SHADOW_IN"); #endif -#ifdef MENU_TEXT_FLOATING - printf(" +MENU_TEXT_FLOATING"); -#else - printf(" -MENU_TEXT_FLOATING"); -#endif #ifdef CTRL_CLICK_RAISE printf(" +CTRL_CLICK_RAISE"); #else @@ -802,10 +817,10 @@ version(void) #else printf(" -GREEK_SUPPORT"); #endif -#ifdef KANJI - printf(" +KANJI"); +#ifdef MULTI_CHARSET + printf(" +MULTI_CHARSET"); #else - printf(" -KANJI"); + printf(" -MULTI_CHARSET"); #endif #ifdef DISPLAY_IS_IP printf(" +DISPLAY_IS_IP"); @@ -847,11 +862,6 @@ version(void) #else printf(" -MAPALERT_OPTION"); #endif -#ifdef ENABLE_CORE_DUMPS - printf(" +ENABLE_CORE_DUMPS"); -#else - printf(" -ENABLE_CORE_DUMPS"); -#endif #ifdef UTMP_SUPPORT printf(" +UTMP_SUPPORT"); #else @@ -935,11 +945,6 @@ version(void) #else printf(" -SCROLLBAR_CONTINUOUS_DELAY\n"); #endif -#ifdef MENUBAR_MAX - printf(" MENUBAR_MAX=%d\n", MENUBAR_MAX); -#else - printf(" -MENUBAR_MAX\n"); -#endif #ifdef ESCZ_ANSWER printf(" ESCZ_ANSWER=\"%s\"\n", ESCZ_ANSWER); #else @@ -955,28 +960,21 @@ version(void) #else printf(" -CONFIG_SEARCH_PATH\n"); #endif -#ifdef CONFIG_FILE_NAME - printf(" CONFIG_FILE_NAME=\"%s\"\n", CONFIG_FILE_NAME); +#ifdef THEME_CFG + printf(" THEME_CFG=\"%s\"\n", THEME_CFG); #else - printf(" -CONFIG_FILE_NAME\n"); + printf(" -THEME_CFG\n"); +#endif +#ifdef USER_CFG + printf(" USER_CFG=\"%s\"\n", USER_CFG); +#else + printf(" -USER_CFG\n"); #endif printf("\n"); exit(EXIT_SUCCESS); } -/* This defines how many mistakes to allow before giving up - and printing the usage -- mej */ -#define BAD_THRESHOLD 3 -#define CHECK_BAD() do { \ - if (++bad_opts >= BAD_THRESHOLD) { \ - print_error("error threshold exceeded, giving up"); \ - usage(); \ - } else { \ - print_error("attempting to continue, but performance may be unpredictable"); \ - } \ - } while(0) - void get_options(int argc, char *argv[]) { @@ -984,7 +982,7 @@ get_options(int argc, char *argv[]) register unsigned long i, j, l; unsigned char bad_opts = 0; - for (i = 1; i < argc; i++) { + for (i = 1; i < (unsigned long) argc; i++) { register char *opt = argv[i]; char *val_ptr = NULL; @@ -1053,7 +1051,7 @@ get_options(int argc, char *argv[]) rs_execArgs = (char **) malloc(sizeof(char *) * (argc - i + 1)); for (k = 0; k < len; k++) { - rs_execArgs[k] = strdup(argv[k + i]); + rs_execArgs[k] = StrDup(argv[k + i]); D_OPTIONS(("rs_execArgs[%d] == %s\n", k, rs_execArgs[k])); } rs_execArgs[k] = (char *) NULL; @@ -1115,7 +1113,7 @@ get_options(int argc, char *argv[]) } else { /* String value */ D_OPTIONS(("String option detected\n")); if (val_ptr && optList[j].pval) { - *((const char **) optList[j].pval) = strdup(val_ptr); + *((const char **) optList[j].pval) = StrDup(val_ptr); } } } @@ -1182,15 +1180,15 @@ get_options(int argc, char *argv[]) rs_execArgs = (char **) malloc(sizeof(char *) * len); if (k == i) { - rs_execArgs[0] = strdup((char *) (val_ptr)); + rs_execArgs[0] = StrDup((char *) (val_ptr)); D_OPTIONS(("rs_execArgs[0] == %s\n", rs_execArgs[0])); k++; } else { - rs_execArgs[0] = strdup(argv[k - 1]); + rs_execArgs[0] = StrDup(argv[k - 1]); D_OPTIONS(("rs_execArgs[0] == %s\n", rs_execArgs[0])); } for (; k < argc; k++) { - rs_execArgs[k - i] = strdup(argv[k]); + rs_execArgs[k - i] = StrDup(argv[k]); D_OPTIONS(("rs_execArgs[%d] == %s\n", k - i, rs_execArgs[k - i])); } rs_execArgs[len - 1] = (char *) NULL; @@ -1214,7 +1212,7 @@ get_options(int argc, char *argv[]) } else { /* String value */ D_OPTIONS(("String option detected\n")); if (optList[j].pval) { - *((const char **) optList[j].pval) = strdup(val_ptr); + *((const char **) optList[j].pval) = StrDup(val_ptr); } } /* End if value type */ } /* End if option type */ @@ -1223,14 +1221,13 @@ get_options(int argc, char *argv[]) } /* End main for loop */ } -#ifdef USE_THEMES void get_initial_options(int argc, char *argv[]) { register unsigned long i, j; - for (i = 1; i < argc; i++) { + for (i = 1; i < (unsigned long) argc; i++) { register char *opt = argv[i]; char *val_ptr = NULL; @@ -1251,6 +1248,12 @@ get_initial_options(int argc, char *argv[]) j = 0; } else if (!BEG_STRCASECMP(opt, "config-file")) { j = 1; + } else if (!BEG_STRCASECMP(opt, "display")) { + j = 2; + } else if (!BEG_STRCASECMP(opt, "debug")) { + j = 3; + } else if (!BEG_STRCASECMP(opt, "install")) { + j = 4; } else continue; @@ -1266,13 +1269,46 @@ get_initial_options(int argc, char *argv[]) } } D_OPTIONS(("hasequal == %d val_ptr == %10.8p \"%s\"\n", hasequal, val_ptr, val_ptr)); - if (val_ptr == NULL) { - print_error("long option --%s requires a string value", opt); + if (val_ptr == NULL && j != 4) { + print_error("long option --%s requires a%s value", opt, (j == 3 ? "n integer" : " string")); continue; } - D_OPTIONS(("String option detected\n")); - if (val_ptr && optList[j].pval) { - *((const char **) optList[j].pval) = strdup(val_ptr); + if (j == 3) { + D_OPTIONS(("Integer option detected\n")); + *((int *) optList[j].pval) = strtol(val_ptr, (char **) NULL, 0); + } else if (j == 4) { + if (val_ptr) { + if (BOOL_OPT_ISTRUE(val_ptr)) { + D_OPTIONS(("\"%s\" == TRUE\n", val_ptr)); + if (optList[j].maskvar) { + *(optList[j].maskvar) |= optList[j].mask; + } + if (optList[j].pval) { + *((const char **) optList[j].pval) = *true_vals; + } + } else if (BOOL_OPT_ISFALSE(val_ptr)) { + D_OPTIONS(("\"%s\" == FALSE\n", val_ptr)); + if (optList[j].maskvar) { + *(optList[j].maskvar) &= ~(optList[j].mask); + } + if (optList[j].pval) { + *((const char **) optList[j].pval) = *false_vals; + } + } + } else { /* No value, so force it on */ + D_OPTIONS(("Forcing option --%s to TRUE\n", opt)); + if (optList[j].maskvar) { + *(optList[j].maskvar) |= optList[j].mask; + } + if (optList[j].pval) { + *((const char **) optList[j].pval) = *true_vals; + } + } + } else { + D_OPTIONS(("String option detected\n")); + if (val_ptr && optList[j].pval) { + *((const char **) optList[j].pval) = StrDup(val_ptr); + } } } else { /* It's a POSIX option */ @@ -1284,6 +1320,8 @@ get_initial_options(int argc, char *argv[]) j = 0; } else if (opt[pos] == 'X') { j = 1; + } else if (opt[pos] == 'd') { + j = 2; } else continue; @@ -1303,190 +1341,14 @@ get_initial_options(int argc, char *argv[]) } D_OPTIONS(("String option detected\n")); if (optList[j].pval) { - *((const char **) optList[j].pval) = strdup(val_ptr); + *((const char **) optList[j].pval) = StrDup(val_ptr); } } /* End for loop */ } /* End if (islong) */ } /* End main for loop */ } -#endif - /***** The Config File Section *****/ - -/* Max length of a line in the config file */ -#define CONFIG_BUFF 20480 - -/* The context identifier. This tells us what section of the config file - we're in, for syntax checking purposes and the like. -- mej */ - -#define CTX_NULL 0 -#define CTX_MAIN 1 -#define CTX_COLOR 2 -#define CTX_ATTRIBUTES 3 -#define CTX_TOGGLES 4 -#define CTX_KEYBOARD 5 -#define CTX_MISC 6 -#define CTX_PIXMAPS 7 -#define CTX_KANJI 8 -#define CTX_UNDEF ((unsigned char) -1) -#define CTX_MAX 8 - -/* This structure defines a context and its attributes */ - -struct context_struct { - - const unsigned char id; - const char *description; - void (*ctx_handler) (char *); - const unsigned char valid_sub_contexts[CTX_MAX]; - -} contexts[] = { - - { - CTX_NULL, "none", NULL, { - CTX_MAIN, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_MAIN, "main", parse_main, { - CTX_COLOR, CTX_ATTRIBUTES, CTX_TOGGLES, - CTX_KEYBOARD, CTX_MISC, CTX_PIXMAPS, - CTX_KANJI, 0 - } - }, - { - CTX_COLOR, "color", parse_color, { - 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_ATTRIBUTES, "attributes", parse_attributes, { - 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_TOGGLES, "toggles", parse_toggles, { - 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_KEYBOARD, "keyboard", parse_keyboard, { - 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_MISC, "misc", parse_misc, { - 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_PIXMAPS, "pixmaps", parse_pixmaps, { - 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_KANJI, "kanji", parse_kanji, { - 0, 0, 0, 0, 0, 0, 0, 0 - } - }, - { - CTX_UNDEF, NULL, parse_undef, { - 0, 0, 0, 0, 0, 0, 0, 0 - } - } - -}; - -#define ctx_name_to_id(the_id, n, i) do { \ - for ((i)=0; (i) <= CTX_MAX; (i)++) { \ - if (!strcasecmp((n), contexts[(i)].description)) { \ - (the_id) = contexts[(i)].id; \ - break; \ - } \ - } \ - if ((i) > CTX_MAX) (the_id) = CTX_UNDEF; \ - } while (0) - -#define ctx_id_to_name(id) (contexts[(id)].description) -#define ctx_id_to_func(id) (contexts[(id)].ctx_handler) - -/* The context stack. This keeps track of the current context and each - previous one. You MUST define MAX_CTX_DEPTH to the absolute maximum - number of context levels deep your contexts go, or the results can be - Very Bad. I recommend erring on the side of caution. -- mej */ - -#define MAX_CTX_DEPTH 10 -#define ctx_push(ctx) id_stack[++cur_ctx] = (ctx) -#define ctx_pop() (id_stack[cur_ctx--]) -#define ctx_peek() (id_stack[cur_ctx]) - -unsigned char id_stack[MAX_CTX_DEPTH]; -unsigned short cur_ctx = 0; - -/* The file state stack. This keeps track of the file currently being - parsed. This allows for %include directives. -- mej */ - -typedef struct file_state_struct { - - FILE *fp; - char *path; - unsigned long line; - unsigned char skip_to_end; - -} file_state; - -#define MAX_FILE_DEPTH 10 -#define file_push(fs) do { \ - cur_file++; \ - file_stack[cur_file].fp = (fs).fp; \ - file_stack[cur_file].path = (fs).path; \ - file_stack[cur_file].line = (fs).line; \ - file_stack[cur_file].skip_to_end = (fs).skip_to_end; \ - } while (0) - -#define file_pop() (cur_file--) -#define file_peek(fs) do { \ - (fs).fp = file_stack[cur_file].fp; \ - (fs).path = file_stack[cur_file].path; \ - (fs).line = file_stack[cur_file].line; \ - (fs).skip_to_end = file_stack[cur_file].skip_to_end; \ - } while (0) -#define file_peek_fp() (file_stack[cur_file].fp) -#define file_peek_path() (file_stack[cur_file].path) -#define file_peek_line() (file_stack[cur_file].line) -#define file_peek_skip() (file_stack[cur_file].skip_to_end) - -#define file_poke_fp(f) ((file_stack[cur_file].fp) = (f)) -#define file_poke_path(p) ((file_stack[cur_file].path) = (p)) -#define file_poke_line(l) ((file_stack[cur_file].line) = (l)) -#define file_poke_skip(s) ((file_stack[cur_file].skip_to_end) = (s)) - -#define file_inc_line() (file_stack[cur_file].line++) - -file_state file_stack[MAX_FILE_DEPTH]; -short cur_file = -1; - -/* The function structures */ - -typedef char *(*eterm_function_ptr) (char *); -typedef struct eterm_function_struct { - - char *name; - eterm_function_ptr ptr; - int params; - -} eterm_func; - -eterm_func builtins[] = -{ - {"random", builtin_random, -1}, - {"exec", builtin_exec, -1}, - {"version", builtin_version, 0}, - {"appname", builtin_appname, 0}, - {(char *) NULL, (eterm_function_ptr) NULL, 0} -}; - char * builtin_random(char *param) { @@ -1494,7 +1356,7 @@ builtin_random(char *param) unsigned long n, index; static unsigned int rseed = 0; - D_OPTIONS(("builtin_random(%s) called\n", param)); + D_PARSE(("builtin_random(%s) called\n", param)); if (rseed == 0) { rseed = (unsigned int) (getpid() * time(NULL) % ((unsigned int) -1)); @@ -1502,7 +1364,7 @@ builtin_random(char *param) } n = NumWords(param); index = (int) (n * ((float) rand()) / (RAND_MAX + 1.0)) + 1; - D_OPTIONS(("random index == %lu\n", index)); + D_PARSE(("random index == %lu\n", index)); return (Word(index, param)); } @@ -1511,7 +1373,7 @@ char * builtin_exec(char *param) { - D_OPTIONS(("builtin_exec(%s) called\n", param)); + D_PARSE(("builtin_exec(%s) called\n", param)); return (param); } @@ -1520,7 +1382,7 @@ char * builtin_version(char *param) { - D_OPTIONS(("builtin_version(%s) called\n", param)); + D_PARSE(("builtin_version(%s) called\n", param)); return (Word(1, VERSION)); } @@ -1529,7 +1391,7 @@ char * builtin_appname(char *param) { - D_OPTIONS(("builtin_appname(%s) called\n", param)); + D_PARSE(("builtin_appname(%s) called\n", param)); return (Word(1, APL_NAME "-" VERSION)); } @@ -1565,7 +1427,7 @@ shell_expand(char *s) register char *tmp; register char *new; register char *pbuff = s, *tmp1; - register unsigned long j, k, l; + register unsigned long j, k, l = 0; unsigned char eval_escape = 1, eval_var = 1, eval_exec = 1, eval_func = 1, in_single = 0, in_double = 0; unsigned long fsize; char *Command, *Output, *EnvVar, *OutFile; @@ -1628,7 +1490,7 @@ shell_expand(char *s) case '%': D_OPTIONS(("%% detected.\n")); for (k = 0, pbuff++; builtins[k].name != NULL; k++) { - D_OPTIONS(("Checking for function %%%s, pbuff == \"%s\"\n", builtins[k].name, pbuff)); + D_PARSE(("Checking for function %%%s, pbuff == \"%s\"\n", builtins[k].name, pbuff)); l = strlen(builtins[k].name); if (!strncasecmp(builtins[k].name, pbuff, l) && ((pbuff[l] == '(') || (pbuff[l] == ' ' && pbuff[l + 1] == ')'))) { @@ -1722,7 +1584,7 @@ shell_expand(char *s) strcat(Command, " >"); strcat(Command, OutFile); system(Command); - if ((fp = fopen(OutFile, "rb")) >= 0) { + if ((fp = fopen(OutFile, "rb")) != NULL) { fseek(fp, 0, SEEK_END); fsize = ftell(fp); rewind(fp); @@ -1730,7 +1592,7 @@ shell_expand(char *s) Output = (char *) MALLOC(fsize + 1); fread(Output, fsize, 1, fp); Output[fsize] = 0; - D_OPTIONS(("Command returned \"%s\"\n", Output)); + D_PARSE(("Command returned \"%s\"\n", Output)); fclose(fp); remove(OutFile); Output = CondenseWhitespace(Output); @@ -1817,7 +1679,7 @@ shell_expand(char *s) } new[j] = 0; - D_OPTIONS(("shell_expand(%s) returning \"%s\"\n", s, new)); + D_PARSE(("shell_expand(%s) returning \"%s\"\n", s, new)); strcpy(s, new); FREE(new); @@ -1832,7 +1694,7 @@ parse_main(char *buff) ASSERT(buff != NULL); - print_error("parse error in file %s, line %lu: Attribute " + print_error("Parse error in file %s, line %lu: Attribute " "\"%s\" is not valid within context main\n", file_peek_path(), file_peek_line(), buff); } @@ -1848,51 +1710,35 @@ parse_color(char *buff) } else if (!BEG_STRCASECMP(buff, "background ")) { rs_color[bgColor] = Word(2, buff); - } else if (!BEG_STRCASECMP(buff, "tint ")) { -#ifdef PIXMAP_OFFSET - rs_tintMask = strtoul(buff + 5, (char **) NULL, 0); -#else - print_error("warning: support for the tint attribute was not compiled in, ignoring"); -#endif - - } else if (!BEG_STRCASECMP(buff, "shade ")) { -#ifdef PIXMAP_OFFSET - rs_shadePct = strtoul(buff + 5, (char **) NULL, 0); -#else - print_error("warning: support for the shade attribute was not compiled in, ignoring"); -#endif - } else if (!BEG_STRCASECMP(buff, "cursor ")) { #ifndef NO_CURSORCOLOR rs_color[cursorColor] = Word(2, buff); #else - print_error("warning: support for the cursor attribute was not compiled in, ignoring"); + print_warning("Support for the cursor attribute was not compiled in, ignoring"); #endif } else if (!BEG_STRCASECMP(buff, "cursor_text ")) { #ifndef NO_CURSORCOLOR rs_color[cursorColor2] = Word(2, buff); #else - print_error("warning: support for the cursor_text attribute was not compiled in, ignoring"); + print_warning("Support for the cursor_text attribute was not compiled in, ignoring"); #endif + } else if (!BEG_STRCASECMP(buff, "menu ")) { + rs_color[menuColor] = Word(2, buff); + } else if (!BEG_STRCASECMP(buff, "menu_text ")) { rs_color[menuTextColor] = Word(2, buff); } else if (!BEG_STRCASECMP(buff, "scrollbar ")) { -#if defined(KEEP_SCROLLCOLOR) rs_color[scrollColor] = Word(2, buff); -#else - print_error("warning: support for the scrollbar color attribute was not compiled in, ignoring"); -#endif + + } else if (!BEG_STRCASECMP(buff, "unfocusedmenu ")) { + rs_color[unfocusedMenuColor] = Word(2, buff); } else if (!BEG_STRCASECMP(buff, "unfocusedscrollbar ")) { -#if defined(KEEP_SCROLLCOLOR) && defined(CHANGE_SCROLLCOLOR_ON_FOCUS) rs_color[unfocusedScrollColor] = Word(2, buff); -#else - print_error("warning: support for the unfocusedscrollbar color attribute was not compiled in, ignoring"); -#endif } else if (!BEG_STRCASECMP(buff, "pointer ")) { rs_color[pointerColor] = Word(2, buff); @@ -1905,7 +1751,7 @@ parse_color(char *buff) Options |= Opt_reverseVideo; rs_reverseVideo = *true_vals; } else if (BEG_STRCASECMP(tmp, "normal")) { - print_error("parse error in file %s, line %lu: Invalid value \"%s\" for attribute video", + print_error("Parse error in file %s, line %lu: Invalid value \"%s\" for attribute video", file_peek_path(), file_peek_line(), tmp); } } else if (!BEG_STRCASECMP(buff, "color ")) { @@ -1915,7 +1761,7 @@ parse_color(char *buff) n = NumWords(buff); if (n < 3) { - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for " + print_error("Parse error in file %s, line %lu: Invalid parameter list \"%s\" for " "attribute color", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); return; } @@ -1924,7 +1770,7 @@ parse_color(char *buff) if (!isdigit(*r1)) { if (isdigit(*tmp)) { n = strtoul(tmp, (char **) NULL, 0); - if (n >= 0 && n <= 7) { + if (n <= 7) { index = minColor + n; } else if (n >= 8 && n <= 15) { index = minBright + n - 8; @@ -1936,26 +1782,26 @@ parse_color(char *buff) #ifndef NO_BOLDUNDERLINE rs_color[colorBD] = Word(1, r1); #else - print_error("warning: support for the color bd attribute was not compiled in, ignoring"); + print_warning("Support for the color bd attribute was not compiled in, ignoring"); #endif return; } else if (!BEG_STRCASECMP(tmp, "ul ")) { #ifndef NO_BOLDUNDERLINE rs_color[colorUL] = Word(1, r1); #else - print_error("warning: support for the color ul attribute was not compiled in, ignoring"); + print_warning("Support for the color ul attribute was not compiled in, ignoring"); #endif return; } else { tmp = Word(1, tmp); - print_error("parse error in file %s, line %lu: Invalid color index \"%s\"", + print_error("Parse error in file %s, line %lu: Invalid color index \"%s\"", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - free(tmp); + FREE(tmp); } } } if (n != 5) { - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for " + print_error("Parse error in file %s, line %lu: Invalid parameter list \"%s\" for " "attribute color", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); return; } @@ -1966,7 +1812,7 @@ parse_color(char *buff) r = strtoul(r1, (char **) NULL, 0); g = strtoul(g1, (char **) NULL, 0); b = strtoul(b1, (char **) NULL, 0); - if (n >= 0 && n <= 7) { + if (n <= 7) { index = minColor + n; rs_color[index] = MALLOC(14); sprintf(rs_color[index], "#%02x%02x%02x", r, g, b); @@ -1975,7 +1821,7 @@ parse_color(char *buff) rs_color[index] = MALLOC(14); sprintf(rs_color[index], "#%02x%02x%02x", r, g, b); } else { - print_error("parse error in file %s, line %lu: Invalid color index %lu", + print_error("Parse error in file %s, line %lu: Invalid color index %lu", file_peek_path(), file_peek_line(), n); } @@ -1987,7 +1833,7 @@ parse_color(char *buff) b = strtoul(b1, (char **) NULL, 0); sprintf(rs_color[colorBD], "#%02x%02x%02x", r, g, b); #else - print_error("warning: support for the color bd attribute was not compiled in, ignoring"); + print_warning("Support for the color bd attribute was not compiled in, ignoring"); #endif } else if (!BEG_STRCASECMP(tmp, "ul ")) { @@ -1998,17 +1844,17 @@ parse_color(char *buff) b = strtoul(b1, (char **) NULL, 0); sprintf(rs_color[colorUL], "#%02x%02x%02x", r, g, b); #else - print_error("warning: support for the color ul attribute was not compiled in, ignoring"); + print_warning("Support for the color ul attribute was not compiled in, ignoring"); #endif } else { tmp = Word(1, tmp); - print_error("parse error in file %s, line %lu: Invalid color index \"%s\"", + print_error("Parse error in file %s, line %lu: Invalid color index \"%s\"", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - free(tmp); + FREE(tmp); } } else { - print_error("parse error in file %s, line %lu: Attribute \"%s\" is not valid " + print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " "within context color", file_peek_path(), file_peek_line(), buff); } } @@ -2020,22 +1866,22 @@ parse_attributes(char *buff) ASSERT(buff != NULL); if (!BEG_STRCASECMP(buff, "geometry ")) { - rs_geometry = Word(2, buff); + RESET_AND_ASSIGN(rs_geometry, Word(2, buff)); } else if (!BEG_STRCASECMP(buff, "title ")) { - rs_title = Word(2, buff); + RESET_AND_ASSIGN(rs_title, Word(2, buff)); } else if (!BEG_STRCASECMP(buff, "name ")) { - rs_name = Word(2, buff); + RESET_AND_ASSIGN(rs_name, Word(2, buff)); } else if (!BEG_STRCASECMP(buff, "iconname ")) { - rs_iconName = Word(2, buff); + RESET_AND_ASSIGN(rs_iconName, Word(2, buff)); } else if (!BEG_STRCASECMP(buff, "desktop ")) { rs_desktop = (int) strtol(buff, (char **) NULL, 0); } else if (!BEG_STRCASECMP(buff, "scrollbar_type ")) { - rs_scrollbar_type = Word(2, buff); + RESET_AND_ASSIGN(rs_scrollbar_type, Word(2, buff)); } else if (!BEG_STRCASECMP(buff, "scrollbar_width ")) { rs_scrollbar_width = strtoul(PWord(2, buff), (char **) NULL, 0); @@ -2046,7 +1892,7 @@ parse_attributes(char *buff) unsigned char n; if (NumWords(buff) != 3) { - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for " + print_error("Parse error in file %s, line %lu: Invalid parameter list \"%s\" for " "attribute font", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); return; } @@ -2055,25 +1901,25 @@ parse_attributes(char *buff) if (n <= 4) { rs_font[n] = Word(2, tmp); } else { - print_error("parse error in file %s, line %lu: Invalid font index %d", + print_error("Parse error in file %s, line %lu: Invalid font index %d", file_peek_path(), file_peek_line(), n); } } else if (!BEG_STRCASECMP(tmp, "bold ")) { #ifndef NO_BOLDFONT rs_boldFont = Word(2, tmp); #else - print_error("warning: support for the bold font attribute was not compiled in, ignoring"); + print_warning("Support for the bold font attribute was not compiled in, ignoring"); #endif } else { tmp = Word(1, tmp); - print_error("parse error in file %s, line %lu: Invalid font index \"%s\"", + print_error("Parse error in file %s, line %lu: Invalid font index \"%s\"", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - free(tmp); + FREE(tmp); } } else { - print_error("parse error in file %s, line %lu: Attribute \"%s\" is not valid " + print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " "within context attributes", file_peek_path(), file_peek_line(), (buff ? buff : "")); } } @@ -2088,7 +1934,7 @@ parse_toggles(char *buff) ASSERT(buff != NULL); if (!tmp) { - print_error("parse error in file %s, line %lu: Missing boolean value in context toggles", file_peek_path(), file_peek_line()); + print_error("Parse error in file %s, line %lu: Missing boolean value in context toggles", file_peek_path(), file_peek_line()); return; } if (BOOL_OPT_ISTRUE(tmp)) { @@ -2096,7 +1942,7 @@ parse_toggles(char *buff) } else if (BOOL_OPT_ISFALSE(tmp)) { bool_val = 0; } else { - print_error("parse error in file %s, line %lu: Invalid boolean value \"%s\" in context toggles", + print_error("Parse error in file %s, line %lu: Invalid boolean value \"%s\" in context toggles", file_peek_path(), file_peek_line(), tmp); return; } @@ -2111,7 +1957,7 @@ parse_toggles(char *buff) rs_mapAlert = *false_vals; } #else - print_error("warning: support for the map_alert attribute was not compiled in, ignoring"); + print_warning("Support for the map_alert attribute was not compiled in, ignoring"); #endif } else if (!BEG_STRCASECMP(buff, "visual_bell ")) { @@ -2138,16 +1984,6 @@ parse_toggles(char *buff) Options &= ~(Opt_scrollBar); rs_scrollBar = *false_vals; } - } else if (!BEG_STRCASECMP(buff, "menubar ")) { -#if (MENUBAR_MAX) - if (bool_val) { - rs_menubar = *true_vals; - } else { - rs_menubar = *false_vals; - } -#else - print_error("warning: support for the menubar attribute was not compiled in, ignoring"); -#endif } else if (!BEG_STRCASECMP(buff, "utmp_logging ")) { #ifdef UTMP_SUPPORT @@ -2159,7 +1995,7 @@ parse_toggles(char *buff) rs_utmpLogging = *false_vals; } #else - print_error("warning: support for the utmp_logging attribute was not compiled in, ignoring"); + print_warning("Support for the utmp_logging attribute was not compiled in, ignoring"); #endif } else if (!BEG_STRCASECMP(buff, "meta8 ")) { @@ -2172,7 +2008,7 @@ parse_toggles(char *buff) rs_meta8 = *false_vals; } #else - print_error("warning: support for the meta8 attribute was not compiled in, ignoring"); + print_warning("Support for the meta8 attribute was not compiled in, ignoring"); #endif } else if (!BEG_STRCASECMP(buff, "iconic ")) { @@ -2252,33 +2088,7 @@ parse_toggles(char *buff) rs_saveUnder = *false_vals; } #else - print_error("warning: support for the save_under attribute was not compiled in, ignoring"); -#endif - - } else if (!BEG_STRCASECMP(buff, "trans ")) { -#ifdef PIXMAP_OFFSET - if (bool_val) { - Options |= Opt_pixmapTrans; - rs_pixmapTrans = *true_vals; - } else { - Options &= ~(Opt_pixmapTrans); - rs_pixmapTrans = *false_vals; - } -#else - print_error("warning: support for the trans attribute was not compiled in, ignoring"); -#endif - - } else if (!BEG_STRCASECMP(buff, "watch_desktop ")) { -#ifdef WATCH_DESKTOP_OPTION - if (bool_val) { - Options |= Opt_watchDesktop; - rs_watchDesktop = *true_vals; - } else { - Options &= ~(Opt_watchDesktop); - rs_watchDesktop = *false_vals; - } -#else - print_error("warning: support for the watch_desktop attribute was not compiled in, ignoring"); + print_warning("Support for the save_under attribute was not compiled in, ignoring"); #endif } else if (!BEG_STRCASECMP(buff, "no_cursor ")) { @@ -2290,19 +2100,6 @@ parse_toggles(char *buff) rs_noCursor = (char *) false_vals; } - } else if (!BEG_STRCASECMP(buff, "menubar_move ")) { -#if MENUBAR_MAX - if (bool_val) { - Options |= Opt_menubar_move; - rs_menubar_move = (char *) true_vals; - } else { - Options &= ~(Opt_menubar_move); - rs_menubar_move = (char *) false_vals; - } -#else - print_error("warning: support for the menubar_move attribute was not compiled in, ignoring"); -#endif - } else if (!BEG_STRCASECMP(buff, "pause ")) { if (bool_val) { Options |= Opt_pause; @@ -2339,28 +2136,20 @@ parse_toggles(char *buff) rs_select_trailing_spaces = (char *) false_vals; } - } else if (!BEG_STRCASECMP(buff, "viewport_mode ")) { -#ifdef PIXMAP_OFFSET + } else if (!BEG_STRCASECMP(buff, "report_as_keysyms ")) { if (bool_val) { - Options |= Opt_viewport_mode; - rs_viewport_mode = (char *) true_vals; + Options |= Opt_report_as_keysyms; + rs_report_as_keysyms = (char *) true_vals; } else { - Options &= ~(Opt_viewport_mode); - rs_viewport_mode = (char *) false_vals; + Options &= ~(Opt_report_as_keysyms); + rs_report_as_keysyms = (char *) false_vals; } -#else - print_error("warning: support for the viewport_mode attribute was not compiled in, ignoring"); -#endif } else { - print_error("parse error in file %s, line %lu: Attribute \"%s\" is not valid within context toggles", file_peek_path(), file_peek_line(), buff); + print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid within context toggles", file_peek_path(), file_peek_line(), buff); } } -#define to_keysym(p,s) do { KeySym sym; \ -if (s && ((sym = XStringToKeysym(s)) != 0)) *p = sym; \ - } while (0) - void parse_keyboard(char *buff) { @@ -2369,18 +2158,18 @@ parse_keyboard(char *buff) if (!BEG_STRCASECMP(buff, "smallfont_key ")) { #if defined (HOTKEY_CTRL) || defined (HOTKEY_META) - rs_smallfont_key = Word(2, buff); + RESET_AND_ASSIGN(rs_smallfont_key, Word(2, buff)); to_keysym(&ks_smallfont, rs_smallfont_key); #else - print_error("warning: support for the smallfont_key attribute was not compiled in, ignoring"); + print_warning("Support for the smallfont_key attribute was not compiled in, ignoring"); #endif } else if (!BEG_STRCASECMP(buff, "bigfont_key ")) { #if defined (HOTKEY_CTRL) || defined (HOTKEY_META) - rs_bigfont_key = Word(2, buff); + RESET_AND_ASSIGN(rs_bigfont_key, Word(2, buff)); to_keysym(&ks_bigfont, rs_bigfont_key); #else - print_error("warning: support for the bigfont_key attribute was not compiled in, ignoring"); + print_warning("Support for the bigfont_key attribute was not compiled in, ignoring"); #endif } else if (!BEG_STRCASECMP(buff, "keysym ")) { @@ -2395,7 +2184,7 @@ parse_keyboard(char *buff) if (sym >= 0xff00) sym -= 0xff00; if (sym < 0 || sym > 0xff) { - print_error("parse error in file %s, line %lu: Keysym 0x%x out of range 0xff00-0xffff", + print_error("Parse error in file %s, line %lu: Keysym 0x%x out of range 0xff00-0xffff", file_peek_path(), file_peek_line(), sym + 0xff00); return; } @@ -2414,7 +2203,7 @@ parse_keyboard(char *buff) } } #else - print_error("warning: support for the keysym attributes was not compiled in, ignoring"); + print_warning("Support for the keysym attributes was not compiled in, ignoring"); #endif } else if (!BEG_STRCASECMP(buff, "greek ")) { @@ -2423,29 +2212,29 @@ parse_keyboard(char *buff) char *tmp = PWord(2, buff); if (!tmp) { - print_error("parse error in file %s, line %lu: Missing boolean value for attribute greek", + print_error("Parse error in file %s, line %lu: Missing boolean value for attribute greek", file_peek_path(), file_peek_line()); return; } if (BOOL_OPT_ISTRUE(tmp)) { - rs_greek_keyboard = Word(3, buff); + RESET_AND_ASSIGN(rs_greek_keyboard, Word(3, buff)); if (BEG_STRCASECMP(rs_greek_keyboard, "iso")) { greek_setmode(GREEK_ELOT928); } else if (BEG_STRCASECMP(rs_greek_keyboard, "ibm")) { greek_setmode(GREEK_IBM437); } else { - print_error("parse error in file %s, line %lu: Invalid greek keyboard mode \"%s\"", + print_error("Parse error in file %s, line %lu: Invalid greek keyboard mode \"%s\"", file_peek_path(), file_peek_line(), (rs_greek_keyboard ? rs_greek_keyboard : "")); } } else if (BOOL_OPT_ISFALSE(tmp)) { /* This space intentionally left no longer blank =^) */ } else { - print_error("parse error in file %s, line %lu: Invalid boolean value \"%s\" for attribute %s", + print_error("Parse error in file %s, line %lu: Invalid boolean value \"%s\" for attribute %s", file_peek_path(), file_peek_line(), tmp, buff); return; } #else - print_error("warning: support for the greek attribute was not compiled in, ignoring"); + print_warning("Support for the greek attribute was not compiled in, ignoring"); #endif } else if (!BEG_STRCASECMP(buff, "app_keypad ")) { @@ -2453,7 +2242,7 @@ parse_keyboard(char *buff) char *tmp = PWord(2, buff); if (!tmp) { - print_error("parse error in file %s, line %lu: Missing boolean value for attribute app_keypad", + print_error("Parse error in file %s, line %lu: Missing boolean value for attribute app_keypad", file_peek_path(), file_peek_line()); return; } @@ -2464,7 +2253,7 @@ parse_keyboard(char *buff) PrivateModes &= ~(PrivMode_aplKP); rs_app_keypad = (char *) false_vals; } else { - print_error("parse error in file %s, line %lu: Invalid boolean value \"%s\" for " + print_error("Parse error in file %s, line %lu: Invalid boolean value \"%s\" for " "attribute app_keypad", file_peek_path(), file_peek_line(), tmp); return; } @@ -2474,7 +2263,7 @@ parse_keyboard(char *buff) char *tmp = PWord(2, buff); if (!tmp) { - print_error("parse error in file %s, line %lu: Missing boolean value for attribute app_cursor", + print_error("Parse error in file %s, line %lu: Missing boolean value for attribute app_cursor", file_peek_path(), file_peek_line()); return; } @@ -2485,17 +2274,16 @@ parse_keyboard(char *buff) PrivateModes &= ~(PrivMode_aplCUR); rs_app_cursor = (char *) false_vals; } else { - print_error("parse error in file %s, line %lu: Invalid boolean value \"%s\" for " + print_error("Parse error in file %s, line %lu: Invalid boolean value \"%s\" for " "attribute app_cursor", file_peek_path(), file_peek_line(), tmp); return; } } else { - print_error("parse error in file %s, line %lu: Attribute \"%s\" is not valid " + print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " "within context keyboard", file_peek_path(), file_peek_line(), buff); } } -#undef to_keysym void parse_misc(char *buff) @@ -2505,10 +2293,10 @@ parse_misc(char *buff) if (!BEG_STRCASECMP(buff, "print_pipe ")) { #ifdef PRINTPIPE - rs_print_pipe = strdup(PWord(2, buff)); + RESET_AND_ASSIGN(rs_print_pipe, StrDup(PWord(2, buff))); chomp(rs_print_pipe); #else - print_error("warning: support for the print_pipe attribute was not compiled in, ignoring"); + print_warning("Support for the print_pipe attribute was not compiled in, ignoring"); #endif } else if (!BEG_STRCASECMP(buff, "save_lines ")) { @@ -2521,27 +2309,14 @@ parse_misc(char *buff) #ifdef BORDER_WIDTH_OPTION TermWin.internalBorder = (short) strtol(PWord(2, buff), (char **) NULL, 0); #else - print_error("warning: support for the border_width attribute was not compiled in, ignoring"); + print_warning("Support for the border_width attribute was not compiled in, ignoring"); #endif - } else if (!BEG_STRCASECMP(buff, "menu ")) { -#if MENUBAR_MAX - rs_menu = Word(2, buff); - if (NumWords(buff) > 2) { - char *btmp = Word(3, buff); - - if (BOOL_OPT_ISTRUE(btmp)) { - rs_menubar = *true_vals; - } else if (BOOL_OPT_ISFALSE(btmp)) { - rs_menubar = *false_vals; - } - } -#else - print_error("warning: support for menus was not compiled in, ignoring"); -#endif + } else if (!BEG_STRCASECMP(buff, "line_space ")) { + rs_line_space = strtol(PWord(2, buff), (char **) NULL, 0); } else if (!BEG_STRCASECMP(buff, "term_name ")) { - rs_term_name = Word(2, buff); + RESET_AND_ASSIGN(rs_term_name, Word(2, buff)); } else if (!BEG_STRCASECMP(buff, "debug ")) { debug_level = (unsigned int) strtoul(PWord(2, buff), (char **) NULL, 0); @@ -2552,7 +2327,7 @@ parse_misc(char *buff) Options |= Opt_exec; - rs_execArgs = (char **) malloc(sizeof(char *) * ((n = NumWords(PWord(2, buff))) + 1)); + RESET_AND_ASSIGN(rs_execArgs, (char **) malloc(sizeof(char *) * ((n = NumWords(PWord(2, buff))) + 1))); for (k = 0; k < n; k++) { rs_execArgs[k] = Word(k + 2, buff); @@ -2562,283 +2337,563 @@ parse_misc(char *buff) } else if (!BEG_STRCASECMP(buff, "cut_chars ")) { #ifdef CUTCHAR_OPTION - rs_cutchars = Word(2, buff); + RESET_AND_ASSIGN(rs_cutchars, Word(2, buff)); chomp(rs_cutchars); #else - print_error("warning: support for the cut_chars attribute was not compiled in, ignoring"); + print_warning("Support for the cut_chars attribute was not compiled in, ignoring"); #endif } else { - print_error("parse error in file %s, line %lu: Attribute \"%s\" is not valid " + print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " "within context misc", file_peek_path(), file_peek_line(), buff); } } void -parse_pixmaps(char *buff) +parse_imageclasses(char *buff) { - long w, h; - char *w1, *h1; - unsigned long n; - #ifdef PIXMAP_SUPPORT ASSERT(buff != NULL); - if (!BEG_STRCASECMP(buff, "background ")) { - - if ((n = NumWords(buff) < 4) || (n > 6)) { - char *tmp = PWord(2, buff); - - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for attribute background", - file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - return; - } - w1 = PWord(2, buff); - h1 = PWord(3, buff); - w = strtol(w1, (char **) NULL, 0); - h = strtol(h1, (char **) NULL, 0); - if (w || h) { - rs_pixmapScale = (char *) true_vals; - Options |= Opt_pixmapScale; - rs_pixmaps[pixmap_bg] = Word(4, buff); - rs_pixmaps[pixmap_bg] = (char *) realloc(rs_pixmaps[pixmap_bg], strlen(rs_pixmaps[pixmap_bg]) + 9); - strcat(rs_pixmaps[pixmap_bg], "@100x100"); - } else { - rs_pixmaps[pixmap_bg] = Word(4, buff); - } - - } else if (!BEG_STRCASECMP(buff, "icon ")) { - rs_icon = Word(2, buff); - -# ifdef PIXMAP_SCROLLBAR - } else if (!BEG_STRCASECMP(buff, "scroll_up ")) { - - if ((n = NumWords(buff) < 4) || (n > 6)) { - char *tmp = PWord(2, buff); - - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for attribute " - "scroll_up", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - return; - } - w1 = PWord(2, buff); - h1 = PWord(3, buff); - w = strtol(w1, (char **) NULL, 0); - h = strtol(h1, (char **) NULL, 0); - if (w || h) { - rs_pixmaps[pixmap_up] = Word(4, buff); - rs_pixmaps[pixmap_up] = (char *) realloc(rs_pixmaps[pixmap_up], strlen(rs_pixmaps[pixmap_up]) + 9); - strcat(rs_pixmaps[pixmap_up], "@100x100"); - } else { - rs_pixmaps[pixmap_up] = Word(4, buff); - } - } else if (!BEG_STRCASECMP(buff, "scroll_up_clicked ")) { - - if ((n = NumWords(buff) < 4) || (n > 6)) { - char *tmp = PWord(2, buff); - - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for attribute " - "scroll_up_clicked", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - return; - } - w1 = PWord(2, buff); - h1 = PWord(3, buff); - w = strtol(w1, (char **) NULL, 0); - h = strtol(h1, (char **) NULL, 0); - if (w || h) { - rs_pixmaps[pixmap_upclk] = Word(4, buff); - rs_pixmaps[pixmap_upclk] = (char *) realloc(rs_pixmaps[pixmap_upclk], strlen(rs_pixmaps[pixmap_upclk]) + 9); - strcat(rs_pixmaps[pixmap_upclk], "@100x100"); - } else { - rs_pixmaps[pixmap_upclk] = Word(4, buff); - } - } else if (!BEG_STRCASECMP(buff, "scroll_down ")) { - - if ((n = NumWords(buff) < 4) || (n > 6)) { - char *tmp = PWord(2, buff); - - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for attribute " - "scroll_down", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - return; - } - w1 = PWord(2, buff); - h1 = PWord(3, buff); - w = strtol(w1, (char **) NULL, 0); - h = strtol(h1, (char **) NULL, 0); - if (w || h) { - rs_pixmaps[pixmap_dn] = Word(4, buff); - rs_pixmaps[pixmap_dn] = (char *) realloc(rs_pixmaps[pixmap_dn], strlen(rs_pixmaps[pixmap_dn]) + 9); - strcat(rs_pixmaps[pixmap_dn], "@100x100"); - } else { - rs_pixmaps[pixmap_dn] = Word(4, buff); - } - } else if (!BEG_STRCASECMP(buff, "scroll_down_clicked ")) { - - if ((n = NumWords(buff) < 4) || (n > 6)) { - char *tmp = PWord(2, buff); - - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for attribute " - "scroll_down_clicked", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - return; - } - w1 = PWord(2, buff); - h1 = PWord(3, buff); - w = strtol(w1, (char **) NULL, 0); - h = strtol(h1, (char **) NULL, 0); - if (w || h) { - rs_pixmaps[pixmap_dnclk] = Word(4, buff); - rs_pixmaps[pixmap_dnclk] = (char *) realloc(rs_pixmaps[pixmap_dnclk], strlen(rs_pixmaps[pixmap_dnclk]) + 9); - strcat(rs_pixmaps[pixmap_dnclk], "@100x100"); - } else { - rs_pixmaps[pixmap_dnclk] = Word(4, buff); - } - } else if (!BEG_STRCASECMP(buff, "scroll_background ")) { - - if ((n = NumWords(buff) < 4) || (n > 6)) { - char *tmp = PWord(2, buff); - - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for attribute " - "scroll_background", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - return; - } - w1 = PWord(2, buff); - h1 = PWord(3, buff); - w = strtol(w1, (char **) NULL, 0); - h = strtol(h1, (char **) NULL, 0); - if (w || h) { - rs_pixmaps[pixmap_sb] = Word(4, buff); - rs_pixmaps[pixmap_sb] = (char *) realloc(rs_pixmaps[pixmap_sb], strlen(rs_pixmaps[pixmap_sb]) + 9); - strcat(rs_pixmaps[pixmap_sb], "@100x100"); - } else { - rs_pixmaps[pixmap_sb] = Word(4, buff); - } - } else if (!BEG_STRCASECMP(buff, "scroll_anchor ")) { - - if ((n = NumWords(buff) < 4) || (n > 6)) { - char *tmp = PWord(2, buff); - - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for attribute " - "scroll_anchor", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - return; - } - w1 = PWord(2, buff); - h1 = PWord(3, buff); - w = strtol(w1, (char **) NULL, 0); - h = strtol(h1, (char **) NULL, 0); - if (w || h) { - rs_pixmaps[pixmap_sa] = Word(4, buff); - rs_pixmaps[pixmap_sa] = (char *) realloc(rs_pixmaps[pixmap_sa], strlen(rs_pixmaps[pixmap_sa]) + 9); - strcat(rs_pixmaps[pixmap_sa], "@100x100"); - } else { - rs_pixmaps[pixmap_sa] = Word(4, buff); - } - } else if (!BEG_STRCASECMP(buff, "scroll_anchor_clicked ")) { - - if ((n = NumWords(buff) < 4) || (n > 6)) { - char *tmp = PWord(2, buff); - - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for attribute " - "scroll_anchor_clicked", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - return; - } - w1 = PWord(2, buff); - h1 = PWord(3, buff); - w = strtol(w1, (char **) NULL, 0); - h = strtol(h1, (char **) NULL, 0); - if (w || h) { - rs_pixmaps[pixmap_saclk] = Word(4, buff); - rs_pixmaps[pixmap_saclk] = (char *) realloc(rs_pixmaps[pixmap_saclk], strlen(rs_pixmaps[pixmap_saclk]) + 9); - strcat(rs_pixmaps[pixmap_saclk], "@100x100"); - } else { - rs_pixmaps[pixmap_saclk] = Word(4, buff); - } -# endif /* PIXMAP_SCROLLBAR */ -# ifdef PIXMAP_MENUBAR - } else if (!BEG_STRCASECMP(buff, "menu_background ")) { - - if ((n = NumWords(buff) < 4) || (n > 6)) { - char *tmp = PWord(2, buff); - - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for attribute " - "menu_background", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - return; - } - w1 = PWord(2, buff); - h1 = PWord(3, buff); - w = strtol(w1, (char **) NULL, 0); - h = strtol(h1, (char **) NULL, 0); - if (w || h) { - rs_pixmaps[pixmap_mb] = Word(4, buff); - rs_pixmaps[pixmap_mb] = (char *) realloc(rs_pixmaps[pixmap_mb], strlen(rs_pixmaps[pixmap_mb]) + 9); - strcat(rs_pixmaps[pixmap_mb], "@100x100"); - } else { - rs_pixmaps[pixmap_mb] = Word(4, buff); - } - } else if (!BEG_STRCASECMP(buff, "menu_selected ")) { - - if ((n = NumWords(buff) < 4) || (n > 6)) { - char *tmp = PWord(2, buff); - - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for attribute " - "menu_selected", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - return; - } - w1 = PWord(2, buff); - h1 = PWord(3, buff); - w = strtol(w1, (char **) NULL, 0); - h = strtol(h1, (char **) NULL, 0); - if (w || h) { - rs_pixmaps[pixmap_ms] = Word(4, buff); - rs_pixmaps[pixmap_ms] = (char *) realloc(rs_pixmaps[pixmap_ms], strlen(rs_pixmaps[pixmap_ms]) + 9); - strcat(rs_pixmaps[pixmap_ms], "@100x100"); - } else { - rs_pixmaps[pixmap_ms] = Word(4, buff); - } -# endif /* PIXMAP_MENUBAR */ + if (!BEG_STRCASECMP(buff, "icon ")) { + RESET_AND_ASSIGN(rs_icon, Word(2, buff)); } else if (!BEG_STRCASECMP(buff, "path ")) { - rs_path = Word(2, buff); + RESET_AND_ASSIGN(rs_path, Word(2, buff)); } else if (!BEG_STRCASECMP(buff, "anim ")) { # ifdef BACKGROUND_CYCLING_SUPPORT char *tmp = PWord(2, buff); if (tmp) { - rs_anim_pixmap_list = strdup(tmp); + rs_anim_pixmap_list = StrDup(tmp); } else { - print_error("parse error in file %s, line %lu: Invalid parameter list \"\" for attribute anim", file_peek_path(), file_peek_line()); + print_error("Parse error in file %s, line %lu: Invalid parameter list \"\" for attribute anim", file_peek_path(), file_peek_line()); } # else - print_error("warning: support for the anim attribute was not compiled in, ignoring"); + print_warning("Support for the anim attribute was not compiled in, ignoring"); # endif } else { - print_error("parse error in file %s, line %lu: Attribute \"%s\" is not valid " - "within context pixmaps", file_peek_path(), file_peek_line(), buff); + print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " + "within context imageclasses", file_peek_path(), file_peek_line(), buff); } #else - print_error("warning: pixmap support was not compiled in, ignoring entire context"); + print_warning("Pixmap support was not compiled in, ignoring entire context"); file_poke_skip(1); #endif } void -parse_kanji(char *buff) +parse_image(char *buff) +{ + static short idx = -1; + +#ifdef PIXMAP_SUPPORT + ASSERT(buff != NULL); + + if (!BEG_STRCASECMP(buff, "type ")) { + char *type = PWord(2, buff); + + if (!type) { + print_error("Parse error in file %s, line %lu: Missing image type", file_peek_path(), file_peek_line()); + return; + } + if (!strcasecmp(type, "background")) { + idx = image_bg; + } else if (!strcasecmp(type, "trough")) { + idx = image_sb; + } else if (!strcasecmp(type, "anchor")) { + idx = image_sa; + } else if (!strcasecmp(type, "up_arrow")) { + idx = image_up; + } else if (!strcasecmp(type, "down_arrow")) { + idx = image_down; + } else if (!strcasecmp(type, "left_arrow")) { + idx = image_left; + } else if (!strcasecmp(type, "right_arrow")) { + idx = image_right; + } else if (!strcasecmp(type, "menu")) { + idx = image_menu; + } else if (!strcasecmp(type, "submenu")) { + idx = image_submenu; + } else { + print_error("Parse error in file %s, line %lu: Invalid image type \"%s\"", file_peek_path(), file_peek_line(), type); + return; + } + + } else if (!BEG_STRCASECMP(buff, "state ")) { + char *state = PWord(2, buff), new = 0; + + if (!state) { + print_error("Parse error in file %s, line %lu: Missing state", file_peek_path(), file_peek_line()); + return; + } + if (idx < 0) { + print_error("Parse error in file %s, line %lu: Encountered \"state\" with no image type defined", file_peek_path(), file_peek_line()); + return; + } + if (!strcasecmp(state, "normal")) { + if (images[idx].norm == NULL) { + images[idx].norm = (simage_t *) MALLOC(sizeof(simage_t)); + new = 1; + } + images[idx].current = images[idx].norm; + } else if (!strcasecmp(state, "selected")) { + if (images[idx].selected == NULL) { + images[idx].selected = (simage_t *) MALLOC(sizeof(simage_t)); + new = 1; + } + images[idx].current = images[idx].selected; + } else if (!strcasecmp(state, "clicked")) { + if (images[idx].clicked == NULL) { + images[idx].clicked = (simage_t *) MALLOC(sizeof(simage_t)); + new = 1; + } + images[idx].current = images[idx].clicked; + } else { + print_error("Parse error in file %s, line %lu: Invalid state \"%s\"", file_peek_path(), file_peek_line(), state); + return; + } + if (new) { + images[idx].current->pmap = (pixmap_t *) MALLOC(sizeof(pixmap_t)); + images[idx].current->iml = (imlib_t *) MALLOC(sizeof(imlib_t)); + MEMSET(images[idx].current->pmap, 0, sizeof(pixmap_t)); + MEMSET(images[idx].current->iml, 0, sizeof(imlib_t)); + } + } else if (!BEG_STRCASECMP(buff, "mode ")) { + char *mode = PWord(2, buff); + char *allow_list = PWord(4, buff); + + if (idx < 0) { + print_error("Parse error in file %s, line %lu: Encountered \"mode\" with no image type defined", file_peek_path(), file_peek_line()); + return; + } + if (!mode) { + print_error("Parse error in file %s, line %lu: Missing mode line", file_peek_path(), file_peek_line()); + return; + } + if (!BEG_STRCASECMP(mode, "image ")) { + images[idx].mode = MODE_IMAGE; + } else if (!BEG_STRCASECMP(mode, "trans ")) { + images[idx].mode = MODE_TRANS; + } else if (!BEG_STRCASECMP(mode, "viewport ")) { + images[idx].mode = MODE_VIEWPORT; + } else if (!BEG_STRCASECMP(mode, "auto ")) { + images[idx].mode = MODE_AUTO; + } else { + print_error("Parse error in file %s, line %lu: Invalid mode \"%s\"", file_peek_path(), file_peek_line(), mode); + } + if (allow_list) { + char *allow; + + for (; (allow = strsep(&allow_list, " ")) != NULL;) { + if (!BEG_STRCASECMP("image", allow)) { + images[idx].mode |= ALLOW_IMAGE; + } else if (!BEG_STRCASECMP("transparent", allow)) { + images[idx].mode |= ALLOW_TRANS; + } else if (!BEG_STRCASECMP("viewport", allow)) { + images[idx].mode |= ALLOW_VIEWPORT; + } else if (!BEG_STRCASECMP("auto", allow)) { + images[idx].mode |= ALLOW_AUTO; + } else { + print_error("Parse error in file %s, line %lu: Invalid mode \"%s\"", file_peek_path(), file_peek_line(), allow); + } + } + } + } else if (!BEG_STRCASECMP(buff, "file ")) { + char *filename = PWord(2, buff); + + if (idx < 0) { + print_error("Parse error in file %s, line %lu: Encountered \"file\" with no image type defined", file_peek_path(), file_peek_line()); + return; + } + if (!filename) { + print_error("Parse error in file %s, line %lu: Missing filename", file_peek_path(), file_peek_line()); + return; + } + load_image(filename, idx); + + } else if (!BEG_STRCASECMP(buff, "geom ")) { + char *geom = PWord(2, buff); + + if (idx < 0) { + print_error("Parse error in file %s, line %lu: Encountered \"geom\" with no image type defined", file_peek_path(), file_peek_line()); + return; + } + if (!geom) { + print_error("Parse error in file %s, line %lu: Missing geometry string", file_peek_path(), file_peek_line()); + return; + } + set_pixmap_scale(geom, images[idx].current->pmap); + + } else if (!BEG_STRCASECMP(buff, "cmod ") || !BEG_STRCASECMP(buff, "colormod ")) { + char *color = PWord(2, buff); + char *mods = PWord(3, buff); + unsigned char n; + imlib_t *iml = images[idx].current->iml; + + if (idx < 0) { + print_error("Parse error in file %s, line %lu: Encountered color modifier with no image type defined", file_peek_path(), file_peek_line()); + return; + } + if (!color) { + print_error("Parse error in file %s, line %lu: Missing color name", file_peek_path(), file_peek_line()); + return; + } + if (!mods) { + print_error("Parse error in file %s, line %lu: Missing modifier(s)", file_peek_path(), file_peek_line()); + return; + } + n = NumWords(mods); + + if (!BEG_STRCASECMP(color, "image ")) { + RESET_AND_ASSIGN(iml->mod, (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier))); + iml->mod->contrast = iml->mod->gamma = 0xff; + iml->mod->brightness = (int) strtol(mods, (char **) NULL, 0); + if (n > 1) { + iml->mod->contrast = (int) strtol(PWord(2, mods), (char **) NULL, 0); + } + if (n > 2) { + iml->rmod->gamma = (int) strtol(PWord(3, mods), (char **) NULL, 0); + } + } else if (!BEG_STRCASECMP(color, "red ")) { + RESET_AND_ASSIGN(iml->rmod, (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier))); + iml->rmod->contrast = iml->rmod->gamma = 0xff; + iml->rmod->brightness = (int) strtol(mods, (char **) NULL, 0); + if (n > 1) { + iml->rmod->contrast = (int) strtol(PWord(2, mods), (char **) NULL, 0); + } + if (n > 2) { + iml->rmod->gamma = (int) strtol(PWord(3, mods), (char **) NULL, 0); + } + } else if (!BEG_STRCASECMP(color, "green ")) { + RESET_AND_ASSIGN(iml->gmod, (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier))); + iml->gmod->contrast = iml->gmod->gamma = 0xff; + iml->gmod->brightness = (int) strtol(mods, (char **) NULL, 0); + if (n > 1) { + iml->gmod->contrast = (int) strtol(PWord(2, mods), (char **) NULL, 0); + } + if (n > 2) { + iml->gmod->gamma = (int) strtol(PWord(3, mods), (char **) NULL, 0); + } + } else if (!BEG_STRCASECMP(color, "blue ")) { + RESET_AND_ASSIGN(iml->bmod, (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier))); + iml->bmod->contrast = iml->bmod->gamma = 0xff; + iml->bmod->brightness = (int) strtol(mods, (char **) NULL, 0); + if (n > 1) { + iml->bmod->contrast = (int) strtol(PWord(2, mods), (char **) NULL, 0); + } + if (n > 2) { + iml->bmod->gamma = (int) strtol(PWord(3, mods), (char **) NULL, 0); + } + } else { + print_error("Parse error in file %s, line %lu: Color must be either \"image\", \"red\", \"green\", or \"blue\"", file_peek_path(), file_peek_line()); + return; + } + + } else if (!BEG_STRCASECMP(buff, "border ")) { + if (idx < 0) { + print_error("Parse error in file %s, line %lu: Encountered \"border\" with no image type defined", file_peek_path(), file_peek_line()); + return; + } + if (NumWords(buff + 7) < 4) { + print_error("Parse error in file %s, line %lu: Invalid parameter list for attribute \"border\"", file_peek_path(), file_peek_line()); + return; + } + RESET_AND_ASSIGN(images[idx].current->iml->border, (ImlibBorder *) MALLOC(sizeof(ImlibBorder))); + + images[idx].current->iml->border->left = (unsigned short) strtoul(PWord(2, buff), (char **) NULL, 0); + images[idx].current->iml->border->right = (unsigned short) strtoul(PWord(3, buff), (char **) NULL, 0); + images[idx].current->iml->border->top = (unsigned short) strtoul(PWord(4, buff), (char **) NULL, 0); + images[idx].current->iml->border->bottom = (unsigned short) strtoul(PWord(5, buff), (char **) NULL, 0); + + if ((images[idx].current->iml->border->left == 0) && (images[idx].current->iml->border->right == 0) + && (images[idx].current->iml->border->top == 0) && (images[idx].current->iml->border->bottom == 0)) { + FREE(images[idx].current->iml->border); + images[idx].current->iml->border = (ImlibBorder *) NULL; /* No sense in wasting CPU time and memory if there are no borders */ + } + } else if (!BEG_STRCASECMP(buff, "bevel ")) { + if (idx < 0) { + print_error("Parse error in file %s, line %lu: Encountered \"bevel\" with no image type defined", file_peek_path(), file_peek_line()); + return; + } + if (NumWords(buff + 6) < 5) { + print_error("Parse error in file %s, line %lu: Invalid parameter list for attribute \"bevel\"", file_peek_path(), file_peek_line()); + return; + } + if (images[idx].current->iml->bevel != NULL) { + FREE(images[idx].current->iml->bevel->edges); + FREE(images[idx].current->iml->bevel); + } + images[idx].current->iml->bevel = (bevel_t *) MALLOC(sizeof(bevel_t)); + images[idx].current->iml->bevel->edges = (ImlibBorder *) MALLOC(sizeof(ImlibBorder)); + + if (!BEG_STRCASECMP(PWord(2, buff), "down")) { + images[idx].current->iml->bevel->up = 0; + } else { + images[idx].current->iml->bevel->up = 1; + } + images[idx].current->iml->bevel->edges->left = (unsigned short) strtoul(PWord(3, buff), (char **) NULL, 0); + images[idx].current->iml->bevel->edges->right = (unsigned short) strtoul(PWord(4, buff), (char **) NULL, 0); + images[idx].current->iml->bevel->edges->top = (unsigned short) strtoul(PWord(5, buff), (char **) NULL, 0); + images[idx].current->iml->bevel->edges->bottom = (unsigned short) strtoul(PWord(6, buff), (char **) NULL, 0); + + if ((images[idx].current->iml->bevel->edges->left == 0) && (images[idx].current->iml->bevel->edges->right == 0) + && (images[idx].current->iml->bevel->edges->top == 0) && (images[idx].current->iml->bevel->edges->bottom == 0)) { + FREE(images[idx].current->iml->bevel->edges); + images[idx].current->iml->bevel->edges = (ImlibBorder *) NULL; + FREE(images[idx].current->iml->bevel); + images[idx].current->iml->bevel = (bevel_t *) NULL; + } + } else if (!BEG_STRCASECMP(buff, "padding ")) { + if (idx < 0) { + print_error("Parse error in file %s, line %lu: Encountered \"padding\" with no image type defined", file_peek_path(), file_peek_line()); + return; + } + if (NumWords(buff + 8) < 4) { + print_error("Parse error in file %s, line %lu: Invalid parameter list for attribute \"padding\"", file_peek_path(), file_peek_line()); + return; + } + RESET_AND_ASSIGN(images[idx].current->iml->pad, (ImlibBorder *) MALLOC(sizeof(ImlibBorder))); + + images[idx].current->iml->pad->left = (unsigned short) strtoul(PWord(2, buff), (char **) NULL, 0); + images[idx].current->iml->pad->right = (unsigned short) strtoul(PWord(3, buff), (char **) NULL, 0); + images[idx].current->iml->pad->top = (unsigned short) strtoul(PWord(4, buff), (char **) NULL, 0); + images[idx].current->iml->pad->bottom = (unsigned short) strtoul(PWord(5, buff), (char **) NULL, 0); + + if ((images[idx].current->iml->pad->left == 0) && (images[idx].current->iml->pad->right == 0) + && (images[idx].current->iml->pad->top == 0) && (images[idx].current->iml->pad->bottom == 0)) { + FREE(images[idx].current->iml->pad); + images[idx].current->iml->pad = (ImlibBorder *) NULL; + } + } else { + print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " + "within context image", file_peek_path(), file_peek_line(), buff); + } +#else + print_warning("Pixmap support was not compiled in, ignoring entire context"); + file_poke_skip(1); +#endif +} + +void +parse_actions(char *buff) +{ + unsigned short mod = MOD_NONE; + unsigned char button = BUTTON_NONE; + KeySym keysym = 0; + char *to, *str; + unsigned short i; + + ASSERT(buff != NULL); + + if (!BEG_STRCASECMP(buff, "bind ")) { + for (i = 2; (str = Word(i, buff)) && strcasecmp(str, "to"); i++) { + if (!BEG_STRCASECMP(str, "anymod")) { + mod = MOD_ANY; + } else if (!BEG_STRCASECMP(str, "ctrl")) { + mod |= MOD_CTRL; + } else if (!BEG_STRCASECMP(str, "shift")) { + mod |= MOD_SHIFT; + } else if (!BEG_STRCASECMP(str, "lock")) { + mod |= MOD_LOCK; + } else if (!BEG_STRCASECMP(str, "mod1") || !BEG_STRCASECMP(str, "alt") || !BEG_STRCASECMP(str, "meta")) { + mod |= MOD_MOD1; + } else if (!BEG_STRCASECMP(str, "mod2")) { + mod |= MOD_MOD2; + } else if (!BEG_STRCASECMP(str, "mod3")) { + mod |= MOD_MOD3; + } else if (!BEG_STRCASECMP(str, "mod4")) { + mod |= MOD_MOD4; + } else if (!BEG_STRCASECMP(str, "mod5")) { + mod |= MOD_MOD5; + } else if (!BEG_STRCASECMP(str, "button")) { + switch (*(str+6)) { + case '1': button = Button1; break; + case '2': button = Button2; break; + case '3': button = Button3; break; + case '4': button = Button4; break; + case '5': button = Button5; break; + default: break; + } + } else if (isdigit(*str)) { + keysym = (KeySym) strtoul(str, (char **) NULL, 0); + } else { + keysym = XStringToKeysym(str); + } + FREE(str); + } + if (!str) { + print_error("Parse error in file %s, line %lu: Syntax error (\"to\" not found)", file_peek_path(), file_peek_line()); + FREE(str); + return; + } + FREE(str); + if ((button == BUTTON_NONE) && (keysym == 0)) { + print_error("Parse error in file %s, line %lu: No valid button/keysym found for action", file_peek_path(), file_peek_line()); + return; + } + i++; + str = PWord(i, buff); + if (!BEG_STRCASECMP(str, "string")) { + str = Word(i+1, buff); + action_add(mod, button, keysym, ACTION_STRING, (void *) str); + FREE(str); + } else if (!BEG_STRCASECMP(str, "echo")) { + str = Word(i+1, buff); + action_add(mod, button, keysym, ACTION_ECHO, (void *) str); + FREE(str); + } else if (!BEG_STRCASECMP(str, "menu")) { + menu_t *menu; + + str = Word(i+1, buff); + menu = find_menu_by_title(menu_list, str); + action_add(mod, button, keysym, ACTION_MENU, (void *) menu); + FREE(str); + } else { + print_error("Parse error in file %s, line %lu: Syntax error (\"to\" not found)", file_peek_path(), file_peek_line()); + return; + } + + } else { + print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " + "within context action", file_peek_path(), file_peek_line(), buff); + } +} + +void +parse_menu(char *buff) { -#ifdef KANJI + ASSERT(buff != NULL); + + if (!BEG_STRCASECMP(buff, "title ")) { + char *title = Word(2, buff); + + curmenu = menu_create(title); + menu_list = menulist_add_menu(menu_list, curmenu); + FREE(title); + + } else if (!BEG_STRCASECMP(buff, "font ")) { + char *name = Word(2, buff); + + if (!curmenu) { + print_error("Parse error in file %s, line %lu: You must set the menu title before choosing a font.", file_peek_path(), file_peek_line()); + return; + } + if (!name) { + print_error("Parse error in file %s, line %lu: Missing font name.", file_peek_path(), file_peek_line()); + return; + } + menu_set_font(curmenu, name); + + } else if (!BEG_STRCASECMP(buff, "sep") || !BEG_STRCASECMP(buff, "-")) { + menuitem_t *item; + + item = menuitem_create((char *) NULL); + menu_add_item(curmenu, item); + menuitem_set_action(item, MENUITEM_SEP, (char *) NULL); + + } else { + print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " + "within context menu", file_peek_path(), file_peek_line(), buff); + } +} + +void +parse_menuitem(char *buff) +{ + + static menuitem_t *curitem; + + ASSERT(buff != NULL); + + if (!BEG_STRCASECMP(buff, "text ")) { + char *text = Word(2, buff); + + curitem = menuitem_create(text); + menu_add_item(curmenu, curitem); + FREE(text); + + } else if (!BEG_STRCASECMP(buff, "rtext ")) { + char *rtext = Word(2, buff); + + menuitem_set_rtext(curitem, rtext); + FREE(rtext); + + } else if (!BEG_STRCASECMP(buff, "icon ")) { + + } else if (!BEG_STRCASECMP(buff, "action ")) { + char *type = PWord(2, buff); + char *action = Word(3, buff); + + if (!BEG_STRCASECMP(type, "submenu ")) { + menuitem_set_action(curitem, MENUITEM_SUBMENU, action); + + } else if (!BEG_STRCASECMP(type, "string ")) { + menuitem_set_action(curitem, MENUITEM_STRING, action); + + } else if (!BEG_STRCASECMP(type, "echo ")) { + menuitem_set_action(curitem, MENUITEM_ECHO, action); + + } else if (!BEG_STRCASECMP(type, "separator")) { + menuitem_set_action(curitem, MENUITEM_SEP, action); + + } else { + print_error("Parse error in file %s, line %lu: Invalid menu item action \"%s\"", file_peek_path(), file_peek_line(), type); + } + FREE(action); + + } else { + print_error("Parse error in file %s, line %lu: Attribute \"%s\" is not valid " + "within context menu", file_peek_path(), file_peek_line(), buff); + } +} + +void +parse_xim(char *buff) +{ +#ifdef USE_XIM + ASSERT(buff != NULL); + + if (!BEG_STRCASECMP(buff, "input_method ")) { + rs_inputMethod = Word(2, buff); + } else if (!BEG_STRCASECMP(buff, "preedit_type ")) { + rs_preeditType = Word(2, buff); + } else { + print_error("Parse error in file %s, line %lu:\n" + "Attribute \"%s\" is not valid within context xim", + file_peek_path(), file_peek_line(), buff); + } +#else + print_warning("XIM support was not compiled in, ignoring entire context"); + file_poke_skip(1); +#endif +} + +void +parse_multichar(char *buff) +{ +#ifdef MULTI_CHARSET ASSERT(buff != NULL); if (!BEG_STRCASECMP(buff, "encoding ")) { - if ((rs_kanji_encoding = Word(2, buff)) != NULL) { - if (BEG_STRCASECMP(rs_kanji_encoding, "eucj") && BEG_STRCASECMP(rs_kanji_encoding, "sjis")) { - print_error("parse error in file %s, line %lu: Invalid kanji encoding mode \"%s\"", - file_peek_path(), file_peek_line(), rs_kanji_encoding); + if ((rs_multchar_encoding = Word(2, buff)) != NULL) { + if (BEG_STRCASECMP(rs_multchar_encoding, "eucj") + && BEG_STRCASECMP(rs_multchar_encoding, "sjis") + && BEG_STRCASECMP(rs_multchar_encoding, "euckr")) { + print_error("Parse error in file %s, line %lu:" + " Invalid multichar encoding mode \"%s\"", + file_peek_path(), file_peek_line(), rs_multchar_encoding); return; } - set_kanji_encoding(rs_kanji_encoding); + set_multichar_encoding(rs_multchar_encoding); } else { - print_error("parse error in file %s, line %lu: Invalid parameter list \"\" for attribute encoding", file_peek_path(), file_peek_line()); + print_error("Parse error in file %s, line %lu: " + " Invalid parameter list \"\" for attribute encoding", + file_peek_path(), file_peek_line()); } } else if (!BEG_STRCASECMP(buff, "font ")) { @@ -2846,30 +2901,35 @@ parse_kanji(char *buff) unsigned char n; if (NumWords(buff) != 3) { - print_error("parse error in file %s, line %lu: Invalid parameter list \"%s\" for " - "attribute font", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); + print_error("Parse error in file %s, line %lu:" + " Invalid parameter list \"%s\" for attribute font", + file_peek_path(), file_peek_line(), (tmp ? tmp : "")); return; } if (isdigit(*tmp)) { n = (unsigned char) strtoul(tmp, (char **) NULL, 0); if (n <= 4) { - rs_kfont[n] = Word(2, tmp); + rs_mfont[n] = Word(2, tmp); } else { - print_error("parse error in file %s, line %lu: Invalid font index %d", + print_error("Parse error in file %s, line %lu:" + " Invalid font index %d", file_peek_path(), file_peek_line(), n); } } else { tmp = Word(1, tmp); - print_error("parse error in file %s, line %lu: Invalid font index \"%s\"", + print_error("Parse error in file %s, line %lu:" + " Invalid font index \"%s\"", file_peek_path(), file_peek_line(), (tmp ? tmp : "")); - free(tmp); + FREE(tmp); } } else { - print_error("parse error in file %s, line %lu: Attribute \"%s\" is not valid " - "within context kanji", file_peek_path(), file_peek_line(), buff); + print_error("Parse error in file %s, line %lu:" + " Attribute \"%s\" is not valid within context multichar", + file_peek_path(), file_peek_line(), buff); } #else - print_error("warning: kanji support was not compiled in, ignoring entire context"); + print_warning("Multichar support was not compiled in," + " ignoring entire context"); file_poke_skip(1); #endif } @@ -2880,280 +2940,232 @@ parse_undef(char *buff) ASSERT(buff != NULL); - print_error("parse error in file %s, line %lu: Undefined subcontext \"%s\" within context %s", + print_error("Parse error in file %s, line %lu: Undefined subcontext \"%s\" within context %s", file_peek_path(), file_peek_line(), PWord(2, buff), - ctx_id_to_name(ctx_peek())); + ctx_id_to_name(ctx_peek_last())); file_poke_skip(1); } -/* The config file reader. This loads a file called MAIN, which is - located by searching CONFIG_SEARCH_PATH, PATH_ENV, and $PATH. If - it can't find a config file, it displays a warning but continues. - -- mej */ +/* The config file reader. This looks for the config file by searching CONFIG_SEARCH_PATH and PATH_ENV. + If it can't find a config file, it displays a warning but continues. -- mej */ -#ifdef USE_THEMES -int -find_theme(char *path, char *name) -{ - - register char *search_path = strdup(path); - register char *cur_path, *conf_name; - int ver; - char buff[256]; - char *theme_root, *end_ptr; - char working_dir[PATH_MAX + 1]; - - if (!name) - return (0); - - D_OPTIONS(("Searching for theme %s\n", name)); - - for (cur_path = strtok(search_path, ":"); !file_peek_fp() && cur_path; - cur_path = strtok((char *) NULL, ":")) { - - D_OPTIONS(("cur_path == %s\n", cur_path)); - if (!BEG_STRCASECMP(cur_path, "~/")) { - chdir(getenv("HOME")); - cur_path += 2; - } - if (chdir(cur_path)) { - continue; - } - getcwd(working_dir, PATH_MAX); - D_OPTIONS(("cur_path == %s wd == %s\n", cur_path, working_dir)); - if (chdir(name)) { - continue; - } - if (rs_config_file) { - conf_name = rs_config_file; - } else { - conf_name = CONFIG_FILE_NAME; - } - file_poke_fp(fopen(conf_name, "rt")); - if (file_peek_fp()) { - fgets(buff, 256, file_peek_fp()); - D_OPTIONS(("Magic line \"%s\" [%s] VERSION == \"%s\" size == %lu\n", - buff, buff + 7, VERSION, sizeof(VERSION) - 1)); - if (BEG_STRCASECMP(buff, "')) != NULL) { - *end_ptr = 0; - } - if ((ver = BEG_STRCASECMP(buff + 7, VERSION)) > 0) { - print_error("warning: config file is designed for a newer version of Eterm"); -#ifdef WARN_OLDER - } else if (ver < 0) { - print_error("warning: config file is designed for an older version of Eterm"); -#endif - } - theme_root = (char *) MALLOC(strlen(working_dir) + strlen(cur_path) + strlen(name) + 16 + 1); - sprintf(theme_root, "ETERM_THEME_ROOT=%s/%s", working_dir, name); - putenv(theme_root); - D_OPTIONS(("%s\n", theme_root)); - } - } - } - return ((int) file_peek_fp()); -} - -#endif - -int -find_config_file(char *path, char *name) -{ - - register char *search_path = strdup(path); - register char *cur_path; - int ver; - char buff[256], *end_ptr; - -#if DEBUG >= DEBUG_OPTIONS - char *pwd2; - -#endif - - if (!name) - return (0); - - D_OPTIONS(("Searching for config file %s\n", name)); - - for (cur_path = strtok(search_path, ":"); !file_peek_fp() && cur_path; - cur_path = strtok((char *) NULL, ":")) { - - D_OPTIONS(("cur_path == %s\n", cur_path)); - if (!BEG_STRCASECMP(cur_path, "~/")) { - chdir(getenv("HOME")); - cur_path += 2; - } - chdir(cur_path); -#if DEBUG >= DEBUG_OPTIONS - if (debug_level >= DEBUG_OPTIONS) { - pwd2 = (char *) malloc(2048); - getcwd(pwd2, 2048); - DPRINTF(("cur_path == %s wd == %s\n", cur_path, pwd2)); - free(pwd2); - } -#endif - - file_poke_fp(fopen(name, "rt")); - if (file_peek_fp()) { - fgets(buff, 256, file_peek_fp()); - D_OPTIONS(("Magic line \"%s\" [%s] VERSION == \"%s\" size == %lu\n", - buff, buff + 7, VERSION, sizeof(VERSION) - 1)); - if (BEG_STRCASECMP(buff, "')) != NULL) { - *end_ptr = 0; - } - if ((ver = BEG_STRCASECMP(buff + 7, VERSION)) > 0) { - print_error("warning: config file is designed for a newer version of Eterm"); -#ifdef WARN_OLDER - } else if (ver < 0) { - print_error("warning: config file is designed for an older version of Eterm"); -#endif - } - } - } - } - return ((int) file_peek_fp()); -} - -void -read_config(void) +char * +find_theme(char *path, char *theme_name, char *conf_name) { register char *search_path; - char *env_path, *path_env, *desc; - char buff[CONFIG_BUFF]; - char *conf_name, *end_ptr; - register unsigned long i = 0; - register char *loop_path; /* -nf */ - register char *cur_path; /* -nf */ - int ver; - unsigned char id; - file_state fs = - {NULL, CONFIG_FILE_NAME, 1, 0}; + register char *cur_path; + char working_path[PATH_MAX + 1]; + char *theme_dir = NULL; + struct stat fst; + unsigned long len; - env_path = getenv("PATH"); - if (env_path) - i += strlen(env_path); + ASSERT(path != NULL && conf_name != NULL); + + search_path = StrDup(path); + if (theme_name) { + D_OPTIONS(("Searching for config file %s in theme %s\n", conf_name, theme_name)); + } else { + D_OPTIONS(("Searching for config file %s (no theme)\n", conf_name)); + } + + for (cur_path = strtok(search_path, ":"); cur_path; cur_path = strtok((char *) NULL, ":")) { + + if (!BEG_STRCASECMP(cur_path, "~/")) { + snprintf(working_path, PATH_MAX, "%s/%s/%s%s%s", getenv("HOME"), cur_path + 2, (theme_name ? theme_name : ""), (theme_name ? "/" : ""), conf_name); + } else { + snprintf(working_path, PATH_MAX, "%s/%s%s%s", cur_path, (theme_name ? theme_name : ""), (theme_name ? "/" : ""), conf_name); + } + D_OPTIONS(("Checking for a valid config file at \"%s\"\n", working_path)); + + if (!access(working_path, R_OK)) { + stat(working_path, &fst); + if (!S_ISDIR(fst.st_mode)) { + if (open_config_file(working_path)) { + len = strlen(working_path) - strlen(conf_name); + theme_dir = (char *) MALLOC(len); + snprintf(theme_dir, len, "%s", working_path); + if (theme_name) { + D_OPTIONS(("Found config file %s in theme %s at %s\n", conf_name, theme_name, theme_dir)); + } else { + D_OPTIONS(("Found config file %s at %s\n", conf_name, theme_dir)); + } + break; + } else { + D_OPTIONS((" -> Not a valid config file.\n")); + } + } else { + D_OPTIONS((" -> That is a directory.\n")); + } + } else { + D_OPTIONS((" -> Read access forbidden -- %s\n", strerror(errno))); + } + } + FREE(search_path); + return (theme_dir); +} + +unsigned char +open_config_file(char *name) +{ + + FILE *fp; + int ver; + char buff[256], *end_ptr; + + ASSERT(name != NULL); + + fp = fopen(name, "rt"); + if (fp != NULL) { + fgets(buff, 256, fp); + D_OPTIONS(("Magic line \"%s\" [%s] VERSION == \"%s\" size == %lu\n", buff, buff + 7, VERSION, sizeof(VERSION) - 1)); + if (BEG_STRCASECMP(buff, "')) != NULL) { + *end_ptr = 0; + } + if ((ver = BEG_STRCASECMP(buff + 7, VERSION)) > 0) { + print_warning("Config file is designed for a newer version of Eterm"); +#ifdef WARN_OLDER + } else if (ver < 0) { + print_warning("Config file is designed for an older version of Eterm"); +#endif + } + } + } + file_poke_fp(fp); + return ((unsigned char) (fp == NULL ? 0 : 1)); +} + +void +read_config(char *conf_name) +{ + + register char *search_path; + char *path_env, *desc, *outfile; + char buff[CONFIG_BUFF]; + char *root = NULL; + register unsigned long i = 0; + static char first_time = 1; + unsigned char id = CTX_UNDEF; + file_state fs = + {NULL, NULL, NULL, 1, 0}; + + D_OPTIONS(("read_config(conf_name [%s]) called.\n", conf_name)); path_env = getenv(PATH_ENV); if (path_env) i += strlen(path_env); i += sizeof(CONFIG_SEARCH_PATH) + 3; search_path = (char *) MALLOC(i); - strcpy(search_path, CONFIG_SEARCH_PATH); - if (path_env) { - strcat(search_path, ":"); - strcat(search_path, path_env); - } - if (env_path) { - strcat(search_path, ":"); - strcat(search_path, env_path); - } + snprintf(search_path, i, "%s%s%s", CONFIG_SEARCH_PATH, (path_env ? ":" : ""), (path_env ? path_env : "")); file_push(fs); - getcwd(initial_dir, PATH_MAX); - -#ifdef USE_THEMES - if (rs_config_file) { - conf_name = rs_config_file; - } else { - conf_name = CONFIG_FILE_NAME; + if (rs_theme) { + root = find_theme(search_path, rs_theme, conf_name); } - if (!find_theme(search_path, rs_theme)) { - if (!find_theme(search_path, "Eterm")) { - if (!find_theme(search_path, "DEFAULT")) { - find_config_file(search_path, conf_name); - FREE(rs_theme); - rs_theme = NULL; + if (root == NULL) { + root = find_theme(search_path, "Eterm", conf_name); + if (root == NULL) { + root = find_theme(search_path, "DEFAULT", conf_name); + if (root == NULL) { + root = find_theme(search_path, (char *) NULL, conf_name); + if (rs_theme != NULL) { + FREE(rs_theme); + rs_theme = NULL; + } } } } -#else - conf_name = CONFIG_FILE_NAME; - find_config_file(search_path, conf_name); -#endif - - /* Modifications by NFin8 to print out search path when unable to find the configuration - file. Done 2/17/98 -nf */ - loop_path = strdup(search_path); - if (!file_peek_fp()) { - print_error("unable to find/open config file %s, I looked in:", conf_name); - for (cur_path = strtok(loop_path, ":"); cur_path; cur_path = strtok((char *) NULL, ":")) { - fprintf(stderr, "\t%s\n", cur_path); + FREE(search_path); + if (root == NULL) { + D_OPTIONS((" -> Config file search failed.\n")); + if (first_time) { + print_error("Unable to find/open config file %s. Continuing with defaults.", conf_name); } - print_error("...continuing with defaults"); - FREE(search_path); return; } - FREE(search_path); + D_OPTIONS((" -> Config file search succeeded with root == %s\n", root)); + if (first_time) { + theme_dir = root; + root = (char *) MALLOC(strlen(theme_dir) + 17 + 1); + sprintf(root, "ETERM_THEME_ROOT=%s", theme_dir); + putenv(root); + chdir(theme_dir); + } else { + user_dir = root; + root = (char *) MALLOC(strlen(theme_dir) + 16 + 1); + sprintf(root, "ETERM_USER_ROOT=%s", theme_dir); + putenv(root); + chdir(user_dir); + } + first_time = 0; file_poke_path(conf_name); - ctx_peek() = 0; /* <== This looks weird, but works -- mej */ + ctx_poke(0); for (; cur_file >= 0;) { for (; fgets(buff, CONFIG_BUFF, file_peek_fp());) { file_inc_line(); if (!strchr(buff, '\n')) { - print_error("parse error in file %s, line %lu: line too long", file_peek_path(), file_peek_line()); + print_error("Parse error in file %s, line %lu: line too long", file_peek_path(), file_peek_line()); for (; fgets(buff, CONFIG_BUFF, file_peek_fp()) && !strrchr(buff, '\n');); continue; } + if (!(*buff) || *buff == '\n') { + continue; + } chomp(buff); switch (*buff) { case '#': - case 0: + case '<': break; case '%': + D_OPTIONS(("read_config(): Parsing line #%lu of file %s\n", file_peek_line(), file_peek_path())); if (!BEG_STRCASECMP(PWord(1, buff + 1), "include ")) { shell_expand(buff); fs.path = Word(2, buff + 1); + fs.outfile = (char *) NULL; fs.line = 1; - fs.skip_to_end = 0; - if ((fs.fp = fopen(fs.path, "rt")) == NULL) { - print_error("I/O error in file %s, line %lu: Unable to open %%include file %s " + fs.flags = 0; + file_push(fs); + if (!open_config_file(fs.path)) { + print_error("Error in file %s, line %lu: Unable to locate %%included config file %s " "(%s), continuing", file_peek_path(), file_peek_line(), fs.path, strerror(errno)); - } else { - file_push(fs); - fgets(buff, CONFIG_BUFF, file_peek_fp()); - chomp(buff); - D_OPTIONS(("Magic line \"%s\" [%s] VERSION == \"%s\" " - "size == %lu\n", buff, buff + 7, VERSION, sizeof(VERSION) - 1)); - if ((end_ptr = strchr(buff, '>')) != NULL) { - *end_ptr = 0; - } - if (BEG_STRCASECMP(buff, "')) != NULL) { - *end_ptr = 0; - } - if ((ver = BEG_STRCASECMP(buff + 7, VERSION)) > 0) { - print_error("warning: %%included file %s is designed for a newer version of Eterm", file_peek_path()); -#ifdef WARN_OLDER - } else if (ver < 0) { - print_error("warning: %%included file %s is designed for an older version of Eterm", file_peek_path()); -#endif - } - } + file_pop(); + } + } else if (!BEG_STRCASECMP(PWord(1, buff + 1), "preproc ")) { + char cmd[PATH_MAX]; + FILE *fp; + + if (file_peek_preproc()) { + continue; + } + outfile = tmpnam(NULL); + snprintf(cmd, PATH_MAX, "%s < %s > %s", PWord(2, buff), file_peek_path(), outfile); + system(cmd); + fp = fopen(outfile, "rt"); + if (fp != NULL) { + fclose(file_peek_fp()); + file_poke_fp(fp); + file_poke_preproc(1); + file_poke_outfile(outfile); } } else { - print_error("parse error in file %s, line %lu: Undefined macro \"%s\"", file_peek_path(), file_peek_line(), buff); + print_error("Parse error in file %s, line %lu: Undefined macro \"%s\"", file_peek_path(), file_peek_line(), buff); } break; case 'b': + D_OPTIONS(("read_config(): Parsing line #%lu of file %s\n", file_peek_line(), file_peek_path())); if (file_peek_skip()) continue; if (!BEG_STRCASECMP(buff, "begin ")) { desc = PWord(2, buff); ctx_name_to_id(id, desc, i); if (id == CTX_UNDEF) { + ctx_push(id); parse_undef(buff); } else { if (ctx_peek()) { @@ -3164,14 +3176,14 @@ read_config(void) break; } } else { - print_error("parse error in file %s, line %lu: subcontext %s is not valid " + print_error("Parse error in file %s, line %lu: subcontext %s is not valid " "within context %s", file_peek_path(), file_peek_line(), contexts[id].description, contexts[ctx_peek()].description); break; } } } else if (id != CTX_MAIN) { - print_error("parse error in file %s, line %lu: subcontext %s is not valid " + print_error("Parse error in file %s, line %lu: subcontext %s is not valid " "outside context main", file_peek_path(), file_peek_line(), contexts[id].description); break; @@ -3182,23 +3194,31 @@ read_config(void) break; } case 'e': + D_OPTIONS(("read_config(): Parsing line #%lu of file %s\n", file_peek_line(), file_peek_path())); if (!BEG_STRCASECMP(buff, "end ") || !strcasecmp(buff, "end")) { - ctx_pop(); - file_poke_skip(0); + if (ctx_get_depth()) { + (void) ctx_pop(); + file_poke_skip(0); + } break; } default: + D_OPTIONS(("read_config(): Parsing line #%lu of file %s\n", file_peek_line(), file_peek_path())); if (file_peek_skip()) continue; if ((id = ctx_peek())) { shell_expand(buff); (*ctx_id_to_func(id)) (buff); } else { - print_error("parse error in file %s, line %lu: No established context to parse \"%s\"", + print_error("Parse error in file %s, line %lu: No established context to parse \"%s\"", file_peek_path(), file_peek_line(), buff); } } } + fclose(file_peek_fp()); + if (file_peek_preproc()) { + remove(file_peek_outfile()); + } file_pop(); } } @@ -3208,7 +3228,7 @@ void init_defaults(void) { - rs_name = APL_NAME " " VERSION; + rs_name = StrDup(APL_NAME " " VERSION); #if DEBUG >= DEBUG_MALLOC if (debug_level >= DEBUG_MALLOC) { @@ -3233,9 +3253,6 @@ init_defaults(void) rs_iconName = NULL; /* icon name for window */ rs_geometry = NULL; /* window geometry */ -#if (MENUBAR_MAX) - rs_menu = NULL; -#endif #ifdef PIXMAP_SUPPORT rs_path = NULL; #endif @@ -3244,7 +3261,6 @@ init_defaults(void) #endif TermWin.internalBorder = DEFAULT_BORDER_WIDTH; - } /* Sync up options with our internal data after parsing options and configs */ @@ -3281,9 +3297,9 @@ post_parse(void) scrollBar.width = rs_scrollbar_width; } if (scrollBar.type == SCROLLBAR_XTERM) { - sb_shadow = 0; + scrollbar_set_shadow(0); } else { - sb_shadow = (Options & Opt_scrollBar_floating) ? 0 : SHADOW; + scrollbar_set_shadow((Options & Opt_scrollBar_floating) ? 0 : SHADOW); } /* set any defaults not already set */ @@ -3316,13 +3332,98 @@ post_parse(void) for (i = 0; i < NFONTS; i++) { if (!rs_font[i]) rs_font[i] = def_fontName[i]; -#ifdef KANJI - if (!rs_kfont[i]) { - rs_kfont[i] = def_kfontName[i]; +#ifdef MULTI_CHARSET + if (!rs_mfont[i]) { + rs_mfont[i] = def_kfontName[i]; } #endif } + /* Clean up image stuff */ + for (i = 0; i < image_max; i++) { + if (!(images[i].norm)) { + images[i].norm = (simage_t *) MALLOC(sizeof(simage_t)); + images[i].norm->pmap = (pixmap_t *) MALLOC(sizeof(pixmap_t)); + images[i].norm->iml = (imlib_t *) MALLOC(sizeof(imlib_t)); + MEMSET(images[i].norm->pmap, 0, sizeof(pixmap_t)); + MEMSET(images[i].norm->iml, 0, sizeof(imlib_t)); + images[i].mode = MODE_IMAGE & ALLOW_IMAGE; + } + images[i].current = images[i].norm; + if (rs_pixmaps[i]) { + reset_simage(images[i].norm, RESET_ALL); + load_image(rs_pixmaps[i], i); + FREE(rs_pixmaps[i]); /* These are created by StrDup() */ + } + if (!(images[i].selected)) { + images[i].selected = images[i].norm; + } + if (!(images[i].clicked)) { + images[i].clicked = images[i].selected; + } + } + + if (rs_cmod_image) { + unsigned char n = NumWords(rs_cmod_image); + imlib_t *iml = images[image_bg].norm->iml; + + RESET_AND_ASSIGN(iml->mod, (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier))); + iml->mod->contrast = iml->mod->gamma = 0xff; + iml->mod->brightness = (int) strtol(rs_cmod_image, (char **) NULL, 0); + if (n > 1) { + iml->mod->contrast = (int) strtol(PWord(2, rs_cmod_image), (char **) NULL, 0); + } + if (n > 2) { + iml->mod->gamma = (int) strtol(PWord(3, rs_cmod_image), (char **) NULL, 0); + } + FREE(rs_cmod_image); + } + if (rs_cmod_red) { + unsigned char n = NumWords(rs_cmod_red); + imlib_t *iml = images[image_bg].norm->iml; + + RESET_AND_ASSIGN(iml->rmod, (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier))); + iml->rmod->contrast = iml->rmod->gamma = 0xff; + iml->rmod->brightness = (int) strtol(rs_cmod_red, (char **) NULL, 0); + if (n > 1) { + iml->rmod->contrast = (int) strtol(PWord(2, rs_cmod_red), (char **) NULL, 0); + } + if (n > 2) { + iml->rmod->gamma = (int) strtol(PWord(3, rs_cmod_red), (char **) NULL, 0); + } + FREE(rs_cmod_red); + } + if (rs_cmod_green) { + unsigned char n = NumWords(rs_cmod_green); + imlib_t *iml = images[image_bg].norm->iml; + + RESET_AND_ASSIGN(iml->gmod, (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier))); + iml->gmod->contrast = iml->gmod->gamma = 0xff; + iml->gmod->brightness = (int) strtol(rs_cmod_green, (char **) NULL, 0); + if (n > 1) { + iml->gmod->contrast = (int) strtol(PWord(2, rs_cmod_green), (char **) NULL, 0); + } + if (n > 2) { + iml->gmod->gamma = (int) strtol(PWord(3, rs_cmod_green), (char **) NULL, 0); + } + FREE(rs_cmod_green); + } + if (rs_cmod_blue) { + unsigned char n = NumWords(rs_cmod_blue); + imlib_t *iml = images[image_bg].norm->iml; + + RESET_AND_ASSIGN(iml->bmod, (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier))); + iml->bmod->contrast = iml->bmod->gamma = 0xff; + iml->bmod->brightness = (int) strtol(rs_cmod_blue, (char **) NULL, 0); + if (n > 1) { + iml->bmod->contrast = (int) strtol(PWord(2, rs_cmod_blue), (char **) NULL, 0); + } + if (n > 2) { + iml->bmod->gamma = (int) strtol(PWord(3, rs_cmod_blue), (char **) NULL, 0); + } + FREE(rs_cmod_blue); + } + #ifdef XTERM_REVERSE_VIDEO /* this is how xterm implements reverseVideo */ if (Options & Opt_reverseVideo) { @@ -3338,13 +3439,6 @@ post_parse(void) rs_color[i] = def_colorName[i]; } -#ifdef CHANGE_SCOLLCOLOR_ON_FOCUS - /* If they don't set the unfocused color, use the scrollbar color to "turn the option off" */ - if (!rs_color[unfocusedScrollColor]) { - rs_color[unfocusedScrollColor] = rs_color[scrollColor]; - } -#endif - #ifndef XTERM_REVERSE_VIDEO /* this is how we implement reverseVideo */ if (Options & Opt_reverseVideo) { @@ -3376,28 +3470,12 @@ post_parse(void) color_aliases(pointerColor); color_aliases(borderColor); - /* add startup-menu: */ -#if (MENUBAR_MAX) - /* In a borderless Eterm where the user hasn't said otherwise, make the menubar move the window */ - if (Options & Opt_borderless && rs_menubar_move == NULL) { - Options |= Opt_menubar_move; - } - delay_menu_drawing = 1; - menubar_read(rs_menu); - delay_menu_drawing--; - if (rs_menubar == *false_vals) { - delay_menu_drawing = 0; - } -#else - delay_menu_drawing = 0; -#endif - #ifdef BACKGROUND_CYCLING_SUPPORT if (rs_anim_pixmap_list != NULL) { rs_anim_delay = strtoul(rs_anim_pixmap_list, (char **) NULL, 0); fflush(stdout); if (rs_anim_delay == 0) { - free(rs_anim_pixmap_list); + FREE(rs_anim_pixmap_list); rs_anim_pixmap_list = NULL; } else { char *w1, *h1, *temp; @@ -3422,17 +3500,17 @@ post_parse(void) if (w || h) { rs_anim_pixmaps[i] = Word(3, temp); rs_anim_pixmaps[i] = (char *) realloc(rs_anim_pixmaps[i], strlen(rs_anim_pixmaps[i]) + 9); - strcat(rs_anim_pixmaps[i], ";100x100"); + strcat(rs_anim_pixmaps[i], "@100x100"); } else { rs_anim_pixmaps[i] = Word(3, temp); - rs_anim_pixmaps[i] = (char *) realloc(rs_anim_pixmaps[i], strlen(rs_anim_pixmaps[i]) + 9); - strcat(rs_anim_pixmaps[i], ";0x0"); + rs_anim_pixmaps[i] = (char *) realloc(rs_anim_pixmaps[i], strlen(rs_anim_pixmaps[i]) + 5); + strcat(rs_anim_pixmaps[i], "@0x0"); } FREE(temp); } } rs_anim_pixmaps[count] = NULL; - free(rs_anim_pixmap_list); + FREE(rs_anim_pixmap_list); } } else { rs_anim_delay = 0; @@ -3456,7 +3534,7 @@ save_config(char *path) if (!path) { path = (char *) MALLOC(PATH_MAX + 1); - snprintf(path, PATH_MAX, "%s/MAIN", getenv("ETERM_THEME_ROOT")); + snprintf(path, PATH_MAX, "%s/%s", getenv("ETERM_THEME_ROOT"), (rs_config_file ? rs_config_file : USER_CFG)); path[PATH_MAX] = 0; } if (!lstat(path, &fst)) { @@ -3482,8 +3560,6 @@ save_config(char *path) fprintf(fp, " begin color\n"); fprintf(fp, " foreground %s\n", rs_color[fgColor]); fprintf(fp, " background %s\n", rs_color[bgColor]); - fprintf(fp, " tint 0x%06x\n", rs_tintMask); - fprintf(fp, " shade %lu%%\n", rs_shadePct); fprintf(fp, " cursor %s\n", rs_color[cursorColor]); fprintf(fp, " cursor_text %s\n", rs_color[cursorColor2]); fprintf(fp, " menu_text %s\n", rs_color[menuTextColor]); @@ -3521,37 +3597,18 @@ save_config(char *path) } #ifndef NO_BOLDFONT if (rs_boldFont) { - fprintf(fp, " font bold %s\n", i, rs_boldFont); + fprintf(fp, " font bold %s\n", rs_boldFont); } #endif fprintf(fp, " end attributes\n\n"); - fprintf(fp, " begin pixmaps\n"); - if (rs_pixmaps[pixmap_bg] && *rs_pixmaps[pixmap_bg]) { - fprintf(fp, " background %s %s\n", (Options & Opt_pixmapScale ? "-1 -1" : "0 0"), rs_pixmaps[pixmap_bg]); - } - if (rs_icon) { - fprintf(fp, " icon %s\n", rs_icon); - } - if (rs_path) { - fprintf(fp, " path \"%s\"\n", rs_path); - } - if (rs_anim_delay) { - fprintf(fp, " anim %d ", rs_anim_delay); - for (i = 0; rs_anim_pixmaps[i]; i++) { - fprintf(fp, "\"%s\" ", rs_anim_pixmaps[i]); - } - fprintf(fp, "\n"); - } - fprintf(fp, " end pixmaps\n\n"); - -#ifdef KANJI - fprintf(fp, " begin kanji\n"); - fprintf(fp, " encoding %s\n", rs_kanji_encoding); +#ifdef MULTI_CHARSET + fprintf(fp, " begin multichar\n"); + fprintf(fp, " encoding %s\n", rs_multchar_encoding); for (i = 0; i < 5; i++) { - fprintf(fp, " font %d %s\n", i, rs_kfont[i]); + fprintf(fp, " font %d %s\n", i, rs_mfont[i]); } - fprintf(fp, " end kanji\n\n"); + fprintf(fp, " end multichar\n\n"); #endif fprintf(fp, " begin toggles\n"); @@ -3559,7 +3616,6 @@ save_config(char *path) fprintf(fp, " visual_bell %d\n", (Options & Opt_visualBell ? 1 : 0)); fprintf(fp, " login_shell %d\n", (Options & Opt_loginShell ? 1 : 0)); fprintf(fp, " scrollbar %d\n", (Options & Opt_scrollBar ? 1 : 0)); - fprintf(fp, " menubar %d\n", (menuBar.state ? 1 : 0)); fprintf(fp, " utmp_logging %d\n", (Options & Opt_utmpLogging ? 1 : 0)); fprintf(fp, " meta8 %d\n", (Options & Opt_meta8 ? 1 : 0)); fprintf(fp, " iconic %d\n", (Options & Opt_iconic ? 1 : 0)); @@ -3571,15 +3627,11 @@ save_config(char *path) fprintf(fp, " scrollbar_popup %d\n", (Options & Opt_scrollbar_popup ? 1 : 0)); fprintf(fp, " borderless %d\n", (Options & Opt_borderless ? 1 : 0)); fprintf(fp, " save_under %d\n", (Options & Opt_saveUnder ? 1 : 0)); - fprintf(fp, " trans %d\n", (Options & Opt_pixmapTrans ? 1 : 0)); - fprintf(fp, " watch_desktop %d\n", (Options & Opt_watchDesktop ? 1 : 0)); fprintf(fp, " no_cursor %d\n", (Options & Opt_noCursor ? 1 : 0)); - fprintf(fp, " menubar_move %d\n", (Options & Opt_menubar_move ? 1 : 0)); fprintf(fp, " pause %d\n", (Options & Opt_pause ? 1 : 0)); fprintf(fp, " xterm_select %d\n", (Options & Opt_xterm_select ? 1 : 0)); fprintf(fp, " select_line %d\n", (Options & Opt_select_whole_line ? 1 : 0)); fprintf(fp, " select_trailing_spaces %d\n", (Options & Opt_select_trailing_spaces ? 1 : 0)); - fprintf(fp, " viewport_mode %d\n", (Options & Opt_viewport_mode ? 1 : 0)); fprintf(fp, " end toggles\n\n"); fprintf(fp, " begin keyboard\n"); @@ -3614,7 +3666,6 @@ save_config(char *path) fprintf(fp, " save_lines %d\n", rs_saveLines); fprintf(fp, " min_anchor_size %d\n", rs_min_anchor_size); fprintf(fp, " border_width %d\n", TermWin.internalBorder); - fprintf(fp, " menu %s\n", rs_menu); fprintf(fp, " term_name %s\n", getenv("TERM")); fprintf(fp, " debug %d\n", debug_level); if (Options & Opt_exec && rs_execArgs) { diff --git a/src/options.h b/src/options.h index c5a7895..86a3675 100644 --- a/src/options.h +++ b/src/options.h @@ -1,7 +1,7 @@ /* options.h -- Eterm options module header file * -- 25 July 1997, mej * - * This file is original work by Michael Jennings and + * This file is original work by Michael Jennings and * Tuomo Venalainen . This file, and any other file * bearing this same message or a similar one, is distributed under * the GNU Public License (GPL) as outlined in the COPYING file. @@ -26,15 +26,187 @@ #ifndef _OPTIONS_H_ #define _OPTIONS_H_ -/* includes */ + #include #include /* Xlib, Xutil, Xresource, Xfuncproto */ -#include "feature.h" -/* prototypes */ -unsigned long NumWords(const char *str); +/************ Macros and Definitions ************/ +#define OPT_BOOLEAN 0x0001 +#define OPT_INTEGER 0x0002 +#define OPT_STRING 0x0004 +#define OPT_ARGUMENT 0x0008 -/* extern variables */ +#define OPT_STR(s, l, d, p) { s, l, "(str) " d, OPT_STRING, (const char **) p, 0, 0 } +#define OPT_INT(s, l, d, p) { s, l, "(int) " d, OPT_INTEGER, (const int *) p, 0, 0 } +#define OPT_BOOL(s, l, d, p, v, m) { s, l, "(bool) " d, OPT_BOOLEAN, (const int *) p, v, m } +#define OPT_LONG(l, d, p) { 0, l, "(str) " d, OPT_STRING, (const char **) p, 0, 0 } +#define OPT_ARGS(s, l, d, p) { s, l, "(str) " d, OPT_ARGUMENT, (const char ***) p, 0, 0 } +#define OPT_BLONG(l, d, p, v, m) { 0, l, "(bool) " d, OPT_BOOLEAN, (const int *) p, v, m } +#define OPT_ILONG(l, d, p) { 0, l, "(int) " d, OPT_INTEGER, (const int *) p, 0, 0 } +#define optList_numoptions() (sizeof(optList)/sizeof(optList[0])) + +#if PATH_MAX < 1024 +# undef PATH_MAX +# define PATH_MAX 1024 +#endif + +# define Opt_console (1LU << 0) +# define Opt_loginShell (1LU << 1) +# define Opt_iconic (1LU << 2) +# define Opt_visualBell (1LU << 3) +# define Opt_mapAlert (1LU << 4) +# define Opt_reverseVideo (1LU << 5) +# define Opt_utmpLogging (1LU << 6) +# define Opt_scrollBar (1LU << 7) +# define Opt_meta8 (1LU << 8) +# define Opt_pixmapScale (1LU << 9) +# define Opt_exec (1LU << 10) +# define Opt_homeOnEcho (1LU << 11) +# define Opt_homeOnRefresh (1LU << 12) +# define Opt_scrollBar_floating (1LU << 13) +# define Opt_scrollBar_right (1LU << 14) +# define Opt_borderless (1LU << 15) +# define Opt_pixmapTrans (1LU << 16) +# define Opt_saveUnder (1LU << 17) +# define Opt_noCursor (1LU << 18) +# define Opt_pause (1LU << 19) +# define Opt_homeOnInput (1LU << 20) +# define Opt_report_as_keysyms (1LU << 21) +# define Opt_xterm_select (1LU << 22) +# define Opt_select_whole_line (1LU << 23) +# define Opt_viewport_mode (1LU << 24) +# define Opt_scrollbar_popup (1LU << 25) +# define Opt_select_trailing_spaces (1LU << 26) +# define Opt_install (1LU << 27) + +#define BOOL_OPT_ISTRUE(s) (!strcasecmp((s), true_vals[0]) || !strcasecmp((s), true_vals[1]) \ + || !strcasecmp((s), true_vals[2]) || !strcasecmp((s), true_vals[3])) +#define BOOL_OPT_ISFALSE(s) (!strcasecmp((s), false_vals[0]) || !strcasecmp((s), false_vals[1]) \ + || !strcasecmp((s), false_vals[2]) || !strcasecmp((s), false_vals[3])) + +/* This defines how many mistakes to allow before giving up + and printing the usage -- mej */ +#define BAD_THRESHOLD 3 +#define CHECK_BAD() do { \ + if (++bad_opts >= BAD_THRESHOLD) { \ + print_error("error threshold exceeded, giving up"); \ + usage(); \ + } else { \ + print_error("attempting to continue, but performance may be unpredictable"); \ + } \ + } while(0) + +/* Max length of a line in the config file */ +#define CONFIG_BUFF 20480 + +/* The context identifier. This tells us what section of the config file + we're in, for syntax checking purposes and the like. -- mej */ + +enum { + CTX_NULL, + CTX_MAIN, + CTX_COLOR, + CTX_ATTRIBUTES, + CTX_TOGGLES, + CTX_KEYBOARD, + CTX_MISC, + CTX_IMAGECLASSES, + CTX_IMAGE, + CTX_ACTIONS, + CTX_MENU, + CTX_MENUITEM, + CTX_XIM, + CTX_MULTI_CHARSET, + CTX_MAX = CTX_MULTI_CHARSET, + CTX_UNDEF +}; + +#define ctx_name_to_id(the_id, n, i) do { \ + for ((i)=0; (i) <= CTX_MAX; (i)++) { \ + if (!strcasecmp((n), contexts[(i)].description)) { \ + (the_id) = contexts[(i)].id; \ + break; \ + } \ + } \ + if ((i) > CTX_MAX) (the_id) = CTX_UNDEF; \ + } while (0) + +#define ctx_id_to_name(id) (contexts[(id)].description) +#define ctx_id_to_func(id) (contexts[(id)].ctx_handler) + +/* The context stack. This keeps track of the current context and each + previous one. You MUST define MAX_CTX_DEPTH to the absolute maximum + number of context levels deep your contexts go, or the results can be + Very Bad. I recommend erring on the side of caution. -- mej */ + +#define MAX_CTX_DEPTH 10 +#define ctx_push(ctx) id_stack[++cur_ctx] = (ctx) +#define ctx_pop() (id_stack[cur_ctx--]) +#define ctx_peek() (id_stack[cur_ctx]) +#define ctx_poke(c) (id_stack[cur_ctx] = (c)) +#define ctx_peek_last() (id_stack[(cur_ctx?cur_ctx-1:0)]) +#define ctx_get_depth() (cur_ctx) +#define MAX_FILE_DEPTH 10 +#define FILE_SKIP_TO_END (0x01) +#define FILE_PREPROC (0x02) +#define file_push(fs) do { \ + cur_file++; \ + file_stack[cur_file].fp = (fs).fp; \ + file_stack[cur_file].path = (fs).path; \ + file_stack[cur_file].line = (fs).line; \ + file_stack[cur_file].flags = (fs).flags; \ + } while (0) + +#define file_pop() (cur_file--) +#define file_peek(fs) do { \ + (fs).fp = file_stack[cur_file].fp; \ + (fs).path = file_stack[cur_file].path; \ + (fs).line = file_stack[cur_file].line; \ + (fs).flags = file_stack[cur_file].flags; \ + } while (0) +#define file_peek_fp() (file_stack[cur_file].fp) +#define file_peek_path() (file_stack[cur_file].path) +#define file_peek_outfile() (file_stack[cur_file].outfile) +#define file_peek_line() (file_stack[cur_file].line) +#define file_peek_skip() (file_stack[cur_file].flags & FILE_SKIP_TO_END) +#define file_peek_preproc() (file_stack[cur_file].flags & FILE_PREPROC) + +#define file_poke_fp(f) ((file_stack[cur_file].fp) = (f)) +#define file_poke_path(p) ((file_stack[cur_file].path) = (p)) +#define file_poke_outfile(p) ((file_stack[cur_file].outfile) = (p)) +#define file_poke_line(l) ((file_stack[cur_file].line) = (l)) +#define file_poke_skip(s) do {if (s) {file_stack[cur_file].flags |= FILE_SKIP_TO_END;} else {file_stack[cur_file].flags &= ~(FILE_SKIP_TO_END);} } while (0) +#define file_poke_preproc(s) do {if (s) {file_stack[cur_file].flags |= FILE_PREPROC;} else {file_stack[cur_file].flags &= ~(FILE_PREPROC);} } while (0) + +#define file_inc_line() (file_stack[cur_file].line++) + +#define to_keysym(p,s) do { KeySym sym; \ + if (s && ((sym = XStringToKeysym(s)) != 0)) *p = sym; \ + } while (0) + +#define RESET_AND_ASSIGN(var, val) do {if ((var) != NULL) FREE(var); (var) = (val);} while (0) + +/************ Structures ************/ +/* The file state stack. This keeps track of the file currently being + parsed. This allows for %include directives. -- mej */ +typedef struct file_state_struct { + FILE *fp; + char *path, *outfile; + unsigned long line; + unsigned char flags; +} file_state; +typedef char *(*eterm_function_ptr) (char *); +typedef struct eterm_function_struct { + + char *name; + eterm_function_ptr ptr; + int params; + +} eterm_func; + +/************ Variables ************/ +extern unsigned long Options; +extern char *theme_dir, *user_dir; extern char **rs_execArgs; /* Args to exec (-e or --exec) */ extern char *rs_title; /* Window title */ extern char *rs_iconName; /* Icon name */ @@ -46,7 +218,7 @@ extern const char *rs_scrollBar_right; extern const char *rs_scrollBar_floating; extern const char *rs_scrollbar_popup; extern char *rs_viewport_mode; -extern const char *rs_term_name; +extern char *rs_term_name; extern const char *rs_menubar; extern const char *rs_menu; extern const char *rs_menubar_move; @@ -59,48 +231,50 @@ extern char *rs_anim_pixmap_list; extern char **rs_anim_pixmaps; extern time_t rs_anim_delay; extern char *rs_path; - -extern const char *true_vals[]; -extern const char *false_vals[]; -#define BOOL_OPT_ISTRUE(s) (!strcasecmp((s), true_vals[0]) || !strcasecmp((s), true_vals[1]) \ - || !strcasecmp((s), true_vals[2]) || !strcasecmp((s), true_vals[3])) -#define BOOL_OPT_ISFALSE(s) (!strcasecmp((s), false_vals[0]) || !strcasecmp((s), false_vals[1]) \ - || !strcasecmp((s), false_vals[2]) || !strcasecmp((s), false_vals[3])) - +extern const char *rs_saveUnder; +extern char *rs_noCursor; +#ifdef USE_XIM +extern char *rs_inputMethod; +extern char *rs_preeditType; +#endif +extern char *rs_name; +extern char *rs_pixmapScale; +extern char *rs_config_file; +extern unsigned int rs_line_space; +#ifndef NO_BOLDFONT +extern const char *rs_boldFont; +#endif +#ifdef PRINTPIPE +extern char *rs_print_pipe; +#endif +extern char *rs_cutchars; #ifdef CUTCHAR_OPTION extern char *rs_cutchars; #endif - +extern const char *true_vals[]; +extern const char *false_vals[]; #ifdef KEYSYM_ATTRIBUTE extern unsigned char *KeySym_map[256]; #endif - #if defined (HOTKEY_CTRL) || defined (HOTKEY_META) extern KeySym ks_bigfont; extern KeySym ks_smallfont; #endif -#ifdef PIXMAP_SUPPORT -extern char *rs_pixmaps[]; - -#define pixmap_bg 0 -#define pixmap_sb 1 -#define pixmap_up 2 -#define pixmap_upclk 3 -#define pixmap_dn 4 -#define pixmap_dnclk 5 -#define pixmap_sa 6 -#define pixmap_saclk 7 -#define pixmap_mb 8 -#define pixmap_ms 9 -#endif /* PIXMAP_SUPPORT */ - -/* prototypes */ +/************ Function Prototypes ************/ _XFUNCPROTOBEGIN +unsigned long NumWords(const char *str); +extern void get_initial_options(int, char **); extern void get_options(int, char **); extern char *chomp(char *); -extern void read_config(void); +extern char *shell_expand(char *); +extern char *find_theme(char *, char *, char *); +extern unsigned char open_config_file(char *); +extern void read_config(char *); +extern void init_defaults(void); +extern void post_parse(void); +unsigned char save_config(char *); _XFUNCPROTOEND diff --git a/src/pixmap.c b/src/pixmap.c index 08f465d..96b5f02 100644 --- a/src/pixmap.c +++ b/src/pixmap.c @@ -1,7 +1,6 @@ /* pixmap.c -- Eterm pixmap handling routines - * -- vendu & mej - * - * This file is original work by Michael Jennings and + + * This file is original work by Michael Jennings and * Tuomo Venalainen . This file, and any other file * bearing this same message or a similar one, is distributed under * the GNU Public License (GPL) as outlined in the COPYING file. @@ -26,197 +25,159 @@ static const char cvs_ident[] = "$Id$"; +#include "config.h" +#include "feature.h" + #include #include #include #include #include +#include -#include "main.h" -#include "feature.h" #include "../libmej/debug.h" -#include "mem.h" +#include "../libmej/mem.h" +#include "../libmej/strings.h" +#include "e.h" +#include "main.h" +#include "menus.h" #include "options.h" -#ifdef PIXMAP_SUPPORT -# include "pixmap.h" -# include "screen.h" -# ifdef USE_POSIX_THREADS -# include "threads.h" -# endif -# include "Eterm.xpm" /* Icon pixmap */ -#endif +#include "pixmap.h" +#include "screen.h" #ifdef PIXMAP_SCROLLBAR # include "scrollbar.h" #endif -#ifdef PIXMAP_MENUBAR -# include "menubar.h" -#endif - -#ifdef USE_IMLIB -# include "eterm_imlib.h" +#include "term.h" +#ifdef USE_POSIX_THREADS +# include "threads.h" #endif +#include "Eterm.xpm" /* Icon pixmap */ #ifdef PIXMAP_SUPPORT -/* Specifying a single extension is irrelevant with Imlib. -vendu */ -# ifdef USE_IMLIB -# define PIXMAP_EXT NULL -# endif - -extern XWindowAttributes attr; -extern char *rs_path; -extern char *rs_pixmapScale; - -# ifdef PIXMAP_OFFSET -extern const char *rs_pixmapTrans; -extern unsigned int rs_shadePct; -extern unsigned long rs_tintMask; Pixmap desktop_pixmap = None; Pixmap viewport_pixmap = None; Window desktop_window = None; - -# endif -# ifdef USE_EFFECTS -int fade_in(Pixmap *, ImlibImage *, int); -int fade_out(Pixmap *, ImlibImage *, int); - -# endif - -extern short bg_needs_update; - -void set_bgPixmap(const char * /* file */ ); -void resize_subwindows(int, int); - -# ifdef USE_POSIX_THREADS -extern short bg_set; -extern char *sig_to_str(int sig); -extern pthread_t resize_sub_thr; -extern pthread_attr_t resize_sub_thr_attr; - -# endif - -# ifdef PIXMAP_OFFSET -extern XSizeHints szHint; -Pixmap offset_pixmap(Pixmap, int, int, renderop_t); - -# endif - -pixmap_t bgPixmap = -{0, 0, 50, 50, None}; - -# ifdef PIXMAP_SCROLLBAR -pixmap_t upPixmap = -{0, 0, 50, 50, None}; -pixmap_t dnPixmap = -{0, 0, 50, 50, None}; -pixmap_t sbPixmap = -{0, 0, 50, 50, None}; -pixmap_t saPixmap = -{0, 0, 50, 50, None}; - -# endif - -# ifdef USE_IMLIB +unsigned char desktop_pixmap_is_mine = 0; ImlibData *imlib_id = NULL; -imlib_t imlib_bg = -{NULL, 0, 0}; - -# ifdef PIXMAP_SCROLLBAR -imlib_t imlib_up = -{NULL, 0, 0}; -imlib_t imlib_dn = -{NULL, 0, 0}; -imlib_t imlib_sb = -{NULL, 0, 0}; -imlib_t imlib_sa = -{NULL, 0, 0}; - -# endif - -# ifdef PIXMAP_MENUBAR -extern menu_t *ActiveMenu; -pixmap_t mbPixmap = -{0, 0, 50, 50, None}; -pixmap_t mb_selPixmap = -{0, 0, 50, 50, None}; - -# ifdef USE_IMLIB -imlib_t imlib_mb = -{NULL, 0, 0}; -imlib_t imlib_ms = -{NULL, 0, 0}; - -# endif -# endif - -inline ImlibImage * -ReadImageViaImlib(Display * d, const char *filename) +image_t images[image_max] = { - Image *tmp; + {None, 0, NULL, NULL, NULL, NULL}, + {None, 0, NULL, NULL, NULL, NULL}, + {None, 0, NULL, NULL, NULL, NULL}, + {None, 0, NULL, NULL, NULL, NULL}, + {None, 0, NULL, NULL, NULL, NULL}, +# ifdef PIXMAP_SCROLLBAR + {None, 0, NULL, NULL, NULL, NULL}, + {None, 0, NULL, NULL, NULL, NULL} +# endif +# ifdef PIXMAP_MENUBAR + , + {None, 0, NULL, NULL, NULL, NULL}, + {None, 0, NULL, NULL, NULL, NULL} +# endif +}; - D_IMLIB(("ReadImageViaImlib(%s)\n", filename)); +#endif - tmp = ImlibLoadImage(imlib_id, (char *) filename, NULL); - return tmp; +#ifdef PIXMAP_SUPPORT +inline const char * +get_image_type(unsigned short type) +{ + + switch (type) { + case image_bg: + return "image_bg"; + break; + case image_up: + return "image_up"; + break; + case image_down: + return "image_down"; + break; + case image_left: + return "image_left"; + break; + case image_right: + return "image_right"; + break; +# ifdef PIXMAP_SCROLLBAR + case image_sb: + return "image_sb"; + break; + case image_sa: + return "image_sa"; + break; +# endif +# ifdef PIXMAP_MENUBAR + case image_menu: + return "image_menu"; + break; + case image_submenu: + return "image_submenu"; + break; +# endif + case image_max: + return "image_max"; + break; + default: + return ""; + break; + } + return (""); } -# endif /* USE_IMLIB */ +unsigned short +parse_pixmap_ops(char *str) +{ -/* - * These GEOM strings indicate absolute size/position: - * @ `WxH+X+Y' - * @ `WxH+X' -> Y = X - * @ `WxH' -> Y = X = 50 - * @ `W+X+Y' -> H = W - * @ `W+X' -> H = W, Y = X - * @ `W' -> H = W, X = Y = 50 - * @ `0xH' -> H *= H/100, X = Y = 50 (W unchanged) - * @ `Wx0' -> W *= W/100, X = Y = 50 (H unchanged) - * @ `=+X+Y' -> (H, W unchanged) - * @ `=+X' -> Y = X (H, W unchanged) - * - * These GEOM strings adjust position relative to current position: - * @ `+X+Y' - * @ `+X' -> Y = X - * - * And this GEOM string is for querying current scale/position: - * @ `?' - */ + unsigned short op = OP_NONE; + char *token; + REQUIRE_RVAL(str && *str, OP_NONE); + D_PIXMAP(("parse_pixmap_ops(str [%s]) called.\n", str)); -/* '[', 2*4 + 2*3 digits + 3 delimiters, ']'. -vendu */ -# define GEOM_LEN 19 /* #undef'd immediately after scale_pixmap(). - vendu */ -int -scale_pixmap(const char *geom, pixmap_t * pmap) + for (; (token = strsep(&str, ":"));) { + if (!BEG_STRCASECMP("tiled", token)) { + op |= OP_TILE; + } else if (!BEG_STRCASECMP("hscaled", token)) { + op |= OP_HSCALE; + } else if (!BEG_STRCASECMP("vscaled", token)) { + op |= OP_VSCALE; + } else if (!BEG_STRCASECMP("scaled", token)) { + op |= OP_SCALE; + } else if (!BEG_STRCASECMP("propscaled", token)) { + op |= OP_PROPSCALE; + } + } + return (op); +} + +unsigned short +set_pixmap_scale(const char *geom, pixmap_t *pmap) { static char str[GEOM_LEN + 1] = {'\0'}; int w = 0, h = 0, x = 0, y = 0; + unsigned short op = OP_NONE; int flags; - int changed = 0; - char *p; + unsigned short changed = 0; + char *p, *opstr; int n; - Screen *scr; if (geom == NULL) return 0; - scr = ScreenOfDisplay(Xdisplay, Xscreen); - if (!scr) - return; D_PIXMAP(("scale_pixmap(\"%s\")\n", geom)); if (!strcmp(geom, "?")) { -# if 0 - sprintf(str, /* Nobody in their right mind would want this to happen -- mej */ - "[%dx%d+%d+%d]", - bgPixmap.w, - bgPixmap.h, - bgPixmap.x, - bgPixmap.y); + sprintf(str, "[%dx%d+%d+%d]", pmap->w, pmap->h, pmap->x, pmap->y); xterm_seq(XTerm_title, str); -# endif return 0; } + if ((opstr = strchr(geom, ':')) != NULL) { + *opstr++ = '\0'; + op |= parse_pixmap_ops(opstr); + } if ((p = strchr(geom, ';')) == NULL) p = strchr(geom, '\0'); n = (p - geom); @@ -246,11 +207,20 @@ scale_pixmap(const char *geom, pixmap_t * pmap) w = pmap->w; h = pmap->h * ((float) h / 100); } - /* Can't get any bigger than fullscreen */ - if (w > scr->width) - w = scr->width; - if (h > scr->height) - h = scr->height; + /* If they want scaling, but didn't give a percentage, assume 100% */ + if (op & OP_PROPSCALE) { + if (!w) + w = 100; + if (!h) + h = 100; + } else { + if ((op & OP_HSCALE) && !w) { + w = 100; + } + if ((op & OP_VSCALE) && !h) { + h = 100; + } + } if (pmap->w != w) { pmap->w = w; @@ -286,141 +256,163 @@ scale_pixmap(const char *geom, pixmap_t * pmap) pmap->y = y; changed++; } - D_PIXMAP(("scale_pixmap() exiting with pmap.w == %d, pmap.h == %d, pmap.x == %d, pmap.y == %d\n", pmap->w, pmap->h, pmap->x, pmap->y)); + if (pmap->op != op) { + pmap->op = op; + changed++; + } + D_PIXMAP(("scale_pixmap() returning %hu, *pmap == { op [%hu], w [%hd], h [%hd], x [%hd], y [%hd] }\n", + changed, pmap->op, pmap->w, pmap->h, pmap->x, pmap->y)); return changed; } -# undef GEOM_LEN void -render_pixmap(Window win, imlib_t image, pixmap_t pmap, int which, renderop_t renderop) +reset_simage(simage_t * simg, unsigned long mask) +{ + + ASSERT(simg != NULL); + + if ((mask & RESET_IMLIB_IM) && simg->iml->im) { + Imlib_destroy_image(imlib_id, simg->iml->im); + simg->iml->im = NULL; + } + if ((mask & RESET_PMAP_PIXMAP) && simg->pmap->pixmap != None) { + Imlib_free_pixmap(imlib_id, simg->pmap->pixmap); + simg->pmap->pixmap = None; + } + if ((mask & RESET_PMAP_MASK) && simg->pmap->mask != None) { + Imlib_free_pixmap(imlib_id, simg->pmap->mask); + simg->pmap->mask = None; + } + if ((mask & RESET_IMLIB_BORDER) && simg->iml->border) { + FREE(simg->iml->border); + simg->iml->border = NULL; + } + if ((mask & RESET_IMLIB_MOD) && simg->iml->mod) { + FREE(simg->iml->mod); + simg->iml->mod = NULL; + } + if ((mask & RESET_IMLIB_RMOD) && simg->iml->rmod) { + FREE(simg->iml->rmod); + simg->iml->rmod = NULL; + } + if ((mask & RESET_IMLIB_GMOD) && simg->iml->gmod) { + FREE(simg->iml->gmod); + simg->iml->gmod = NULL; + } + if ((mask & RESET_IMLIB_BMOD) && simg->iml->bmod) { + FREE(simg->iml->bmod); + simg->iml->bmod = NULL; + } + if (mask & RESET_PMAP_GEOM) { + simg->pmap->w = 0; + simg->pmap->h = 0; + simg->pmap->x = 50; + simg->pmap->y = 50; + simg->pmap->op = OP_NONE; + } +} + +void +paste_simage(simage_t * simg, Window win, unsigned short x, unsigned short y, unsigned short w, unsigned short h) +{ + + ASSERT(simg != NULL); + REQUIRE(win != None); + + if (simg->iml->border) { + Imlib_set_image_border(imlib_id, simg->iml->im, simg->iml->border); + } + if (simg->iml->mod) { + Imlib_set_image_modifier(imlib_id, simg->iml->im, simg->iml->mod); + } + if (simg->iml->rmod) { + Imlib_set_image_red_modifier(imlib_id, simg->iml->im, simg->iml->rmod); + } + if (simg->iml->gmod) { + Imlib_set_image_green_modifier(imlib_id, simg->iml->im, simg->iml->gmod); + } + if (simg->iml->bmod) { + Imlib_set_image_blue_modifier(imlib_id, simg->iml->im, simg->iml->bmod); + } + Imlib_paste_image(imlib_id, simg->iml->im, win, x, y, w, h); +} + +void +render_simage(simage_t * simg, Window win, unsigned short width, unsigned short height, int which, renderop_t renderop) { XGCValues gcvalue; GC gc; - unsigned int width = 0; - unsigned int height = 0; - float p, incr; - int xsize, ysize; + short xsize, ysize; + short xpos = 0, ypos = 0; Pixmap pixmap = None; unsigned short rendered = 0; - -# ifdef PIXMAP_OFFSET - static unsigned int last_width = 0, last_height = 0, last_x = 0, last_y = 0; + unsigned short xscaled = 0, yscaled = 0; +# ifdef PIXMAP_OFFSET + static unsigned int last_x = 0, last_y = 0; int x, y; int px, py; unsigned int pw, ph, pb, pd; - Window w; + Window w, dummy; Screen *scr; - -# ifdef PIXMAP_SCROLLBAR - int scr_x, scr_y, scr_w, scr_h; - Window dummy; - -# endif -# endif /* PIXMAP_OFFSET */ +# endif /* PIXMAP_OFFSET */ scr = ScreenOfDisplay(Xdisplay, Xscreen); if (!scr) return; - if (!image.im -# ifdef PIXMAP_OFFSET - && !(Options & Opt_pixmapTrans) -# endif - ) { - D_PIXMAP(("render_pixmap(): no image loaded\n")); + ASSERT(simg != NULL); + ASSERT(simg->iml != NULL); + ASSERT(simg->pmap != NULL); - if (!(background_is_pixmap())) { - XSetWindowBackground(Xdisplay, win, PixColors[bgColor]); - XClearWindow(Xdisplay, win); - } - return; - } - switch (which) { - case pixmap_bg: - D_PIXMAP(("render_pixmap(0x%x): rendering pixmap_bg\n", image.im)); - width = -#ifdef PIXMAP_OFFSET - Options & Opt_viewport_mode ? scr->width : -#endif - TermWin_TotalWidth(); - height = -#ifdef PIXMAP_OFFSET - Options & Opt_viewport_mode ? scr->height : -#endif - TermWin_TotalHeight(); - break; - case pixmap_sb: - if ((scrollbar_is_pixmapped()) - || (!(Options & Opt_pixmapTrans))) { - D_PIXMAP(("render_pixmap(): rendering pixmap_sb\n")); - width = scrollbar_total_width(); - height = TermWin.height; - } - break; - case pixmap_sa: - if (scrollbar_is_pixmapped()) { - D_PIXMAP(("render_pixmap(): rendering pixmap_sa\n")); - width = scrollbar_total_width(); - height = scrollbar_anchor_max_height(); - } - break; - case pixmap_saclk: - if (scrollbar_is_pixmapped()) { - D_PIXMAP(("render_pixmap(): rendering pixmap_saclk\n")); - width = scrollbar_total_width(); - height = scrollbar_anchor_max_height(); - } - break; - case pixmap_up: - if (scrollbar_is_pixmapped()) { - D_PIXMAP(("render_pixmap(): rendering pixmap_up\n")); - width = scrollbar_total_width(); - height = scrollbar_arrow_height(); - } - break; - case pixmap_upclk: - if (scrollbar_is_pixmapped()) { - D_PIXMAP(("render_pixmap(): rendering pixmap_upclk\n")); - width = scrollbar_total_width(); - height = scrollbar_arrow_height(); - } - break; - case pixmap_dn: - if (scrollbar_is_pixmapped()) { - D_PIXMAP(("render_pixmap(): rendering pixmap_dn\n")); - width = scrollbar_total_width(); - height = scrollbar_arrow_height(); - } - break; - case pixmap_dnclk: - if (scrollbar_is_pixmapped()) { - D_PIXMAP(("render_pixmap(): rendering pixmap_dnclk\n")); - width = scrollbar_total_width(); - height = scrollbar_arrow_height(); - } - break; - case pixmap_mb: - if (menubar_is_pixmapped()) { - D_PIXMAP(("render_pixmap(): rendering pixmap_mb\n")); - width = menuBar_TotalHeight(); - height = menuBar_TotalHeight(); - } - break; - default: - D_PIXMAP(("render_pixmap(): nothing to render\n")); - return; - } + D_PIXMAP(("render_simage(): Rendering simg->iml->im 0x%08x (%s) at %hux%hu onto window 0x%08x\n", simg->iml->im, get_image_type(which), + width, height, win)); + if (which == image_bg && (Options & Opt_viewport_mode)) { + width = scr->width; + height = scr->height; + } if (!(width) || !(height)) return; - gcvalue.foreground = PixColors[bgColor]; - gc = XCreateGC(Xdisplay, win, GCForeground, &gcvalue); + gcvalue.foreground = gcvalue.background = PixColors[bgColor]; + gc = XCreateGC(Xdisplay, win, GCForeground | GCBackground, &gcvalue); + pixmap = simg->pmap->pixmap; /* Save this for later */ -# if defined(PIXMAP_OFFSET) - if (Options & Opt_pixmapTrans) { + if ((images[which].mode & MODE_AUTO) && (images[which].mode & ALLOW_AUTO) && (which != image_bg)) { + char buff[255], *iclass = NULL, *state = NULL; + switch (which) { + case image_up: iclass = "BUTTON_ARROW_UP"; break; + case image_down: iclass = "BUTTON_ARROW_DOWN"; break; + case image_left: iclass = "BUTTON_ARROW_LEFT"; break; + case image_right: iclass = "BUTTON_ARROW_RIGHT"; break; +# ifdef PIXMAP_SCROLLBAR + case image_sb: iclass = "BAR_VERTICAL"; state = "clicked"; break; + case image_sa: iclass = "BAR_VERTICAL"; ((images[which].current == images[which].selected) ? (state = "hilited") : (state = "clicked")); break; +# endif + case image_menu: iclass = "BAR_HORIZONTAL"; state = "normal"; break; + case image_submenu: iclass = "DEFAULT_MENU_SUB"; break; + default: break; + } + if (!state) { + if (images[which].current == images[which].selected) { + state = "hilited"; + } else if (images[which].current == images[which].clicked) { + state = "clicked"; + } else { + state = "normal"; + } + } + if (iclass && state) { + snprintf(buff, sizeof(buff), "imageclass %s apply %ld %s", iclass, (long int) win, state); + enl_ipc_send(buff); + return; + } + } + +# ifdef PIXMAP_OFFSET + if (((Options & Opt_pixmapTrans) || (images[which].mode & MODE_TRANS)) && (images[which].mode & ALLOW_TRANS)) { if (desktop_window == None) { get_desktop_window(); } @@ -428,30 +420,18 @@ render_pixmap(Window win, imlib_t image, pixmap_t pmap, int which, renderop_t re print_error("Unable to locate desktop window. If you are running Enlightenment, please\n" "restart. If not, please set your background image with Esetroot, then try again."); Options &= ~(Opt_pixmapTrans); - render_pixmap(win, image, pmap, which, renderop); + images[which].mode |= (MODE_IMAGE | ALLOW_IMAGE); + images[which].mode &= ~(MODE_TRANS | ALLOW_TRANS); + render_simage(simg, win, width, height, which, renderop); return; } if (desktop_pixmap == None) { desktop_pixmap = get_desktop_pixmap(); last_x = last_y = -1; - if (desktop_pixmap != None) { -#ifdef IMLIB_TRANS - if (imlib_bg.im != NULL) { - D_IMLIB(("ImlibDestroyImage()\n")); - Imlib_kill_image(imlib_id, imlib_bg.im); /* No sense in caching transparency stuff */ - imlib_bg.im = NULL; - } - imlib_bg.im = Imlib_create_image_from_drawable(imlib_id, desktop_pixmap, None, 0, 0, scr->width, scr->height); - colormod_trans(imlib_bg, gc, scr->width, scr->height); - D_IMLIB(("ImlibRender(0x%x@%dx%d)\n", imlib_bg.im, scr->width, scr->height)); - ImlibRender(imlib_id, imlib_bg.im, scr->width, scr->height); - desktop_pixmap = Imlib_move_image(imlib_id, imlib_bg.im); - Imlib_kill_image(imlib_id, imlib_bg.im); /* No sense in caching transparency stuff */ - imlib_bg.im = NULL; -#else + if (desktop_pixmap != None && need_colormod()) { pixmap = desktop_pixmap; XGetGeometry(Xdisplay, desktop_pixmap, &w, &px, &py, &pw, &ph, &pb, &pd); - if (pw < scr->width || ph < scr->height) { + if (pw < (unsigned int) scr->width || ph < (unsigned int) scr->height) { desktop_pixmap = XCreatePixmap(Xdisplay, win, pw, ph, Xdepth); XCopyArea(Xdisplay, pixmap, desktop_pixmap, gc, 0, 0, pw, ph, 0, 0); colormod_trans(desktop_pixmap, gc, pw, ph); @@ -460,370 +440,227 @@ render_pixmap(Window win, imlib_t image, pixmap_t pmap, int which, renderop_t re XCopyArea(Xdisplay, pixmap, desktop_pixmap, gc, 0, 0, scr->width, scr->height, 0, 0); colormod_trans(desktop_pixmap, gc, scr->width, scr->height); } -#endif + desktop_pixmap_is_mine = 1; + pixmap = None; + } else { + desktop_pixmap_is_mine = 0; } } if (desktop_pixmap != None) { XTranslateCoordinates(Xdisplay, win, desktop_window, 0, 0, &x, &y, &w); - if (width != last_width || height != last_height || x != last_x || y != last_y) { - if (TermWin.pixmap != None) { - XFreePixmap(Xdisplay, TermWin.pixmap); - } - TermWin.pixmap = XCreatePixmap(Xdisplay, win, width, height, Xdepth); - D_PIXMAP(("desktop_pixmap == %08x, TermWin.pixmap == %08x\n", desktop_pixmap, TermWin.pixmap)); - if (TermWin.pixmap != None) { - XGetGeometry(Xdisplay, desktop_pixmap, &w, &px, &py, &pw, &ph, &pb, &pd); - if (pw < scr->width || ph < scr->height) { - XFreeGC(Xdisplay, gc); - gc = XCreateGC(Xdisplay, desktop_pixmap, 0, &gcvalue); - XSetTile(Xdisplay, gc, desktop_pixmap); - XSetTSOrigin(Xdisplay, gc, pw - (x % pw), ph - (y % ph)); - XSetFillStyle(Xdisplay, gc, FillTiled); - XFillRectangle(Xdisplay, TermWin.pixmap, gc, 0, 0, scr->width, scr->height); - } else { - XCopyArea(Xdisplay, desktop_pixmap, TermWin.pixmap, gc, x, y, width, height, 0, 0); - } - } + if (simg->pmap->pixmap != None) { + XFreePixmap(Xdisplay, simg->pmap->pixmap); } - last_x = x; - last_y = y; - } else { - last_x = last_y = -1; - } - if (TermWin.pixmap != None) { - pmap.pixmap = TermWin.pixmap; - } - last_width = width; - last_height = height; -# ifdef PIXMAP_SCROLLBAR - if (scrollbar_visible() && Options & Opt_scrollBar_floating) { - scr_w = scrollbar_total_width(); - scr_h = height; - if (desktop_pixmap != None) { - sbPixmap.pixmap = XCreatePixmap(Xdisplay, TermWin.parent, scr_w, scr_h, Xdepth); - D_PIXMAP(("0x%x = XCreatePixmap(%d, %d)\n", sbPixmap.pixmap, scr_w, scr_h)); - XTranslateCoordinates(Xdisplay, scrollBar.win, desktop_window, 0, 0, &scr_x, &scr_y, &dummy); - + simg->pmap->pixmap = XCreatePixmap(Xdisplay, win, width, height, Xdepth); + D_PIXMAP(("desktop_pixmap == %08x, simg->pmap->pixmap == %08x\n", desktop_pixmap, simg->pmap->pixmap)); + if (simg->pmap->pixmap != None) { XGetGeometry(Xdisplay, desktop_pixmap, &w, &px, &py, &pw, &ph, &pb, &pd); - XFreeGC(Xdisplay, gc); - gc = XCreateGC(Xdisplay, desktop_pixmap, 0, &gcvalue); - XSetTile(Xdisplay, gc, desktop_pixmap); - XSetTSOrigin(Xdisplay, gc, pw - (scr_x % pw), ph - (scr_y % ph)); - XSetFillStyle(Xdisplay, gc, FillTiled); - XFillRectangle(Xdisplay, sbPixmap.pixmap, gc, 0, 0, scr_w, scr_h); - - D_PIXMAP(("XSetWindowBackgroundPixmap(sbPixmap.pixmap)\n")); + if (pw < (unsigned int) scr->width || ph < (unsigned int) scr->height) { + XFreeGC(Xdisplay, gc); + gc = XCreateGC(Xdisplay, desktop_pixmap, 0, &gcvalue); + XSetTile(Xdisplay, gc, desktop_pixmap); + XSetTSOrigin(Xdisplay, gc, pw - (x % pw), ph - (y % ph)); + XSetFillStyle(Xdisplay, gc, FillTiled); + XFillRectangle(Xdisplay, simg->pmap->pixmap, gc, 0, 0, scr->width, scr->height); + } else { + XCopyArea(Xdisplay, desktop_pixmap, simg->pmap->pixmap, gc, x, y, width, height, 0, 0); + } + XSetWindowBackgroundPixmap(Xdisplay, win, simg->pmap->pixmap); } - XSetWindowBackgroundPixmap(Xdisplay, scrollBar.win, sbPixmap.pixmap); - D_PIXMAP(("XFreePixmap(sbPixmap.pixmap)\n")); - /*XFreePixmap(Xdisplay, sbPixmap.pixmap); */ - XClearWindow(Xdisplay, scrollBar.win); + } else { + XSetWindowBackground(Xdisplay, win, PixColors[bgColor]); } -# endif /* PIXMAP_SCROLLBAR */ + } else if (((Options & Opt_viewport_mode) || (images[which].mode & MODE_VIEWPORT)) && (images[which].mode & ALLOW_VIEWPORT)) { + D_PIXMAP(("Viewport mode enabled. viewport_pixmap == 0x%08x and simg->pmap->pixmap == 0x%08x\n", + viewport_pixmap, simg->pmap->pixmap)); + if (viewport_pixmap == None) { + imlib_t *tmp_iml = images[image_bg].current->iml; + + xsize = tmp_iml->im->rgb_width; + ysize = tmp_iml->im->rgb_height; + if (tmp_iml->border) { + Imlib_set_image_border(imlib_id, tmp_iml->im, tmp_iml->border); + } + if (tmp_iml->mod) { + Imlib_set_image_modifier(imlib_id, tmp_iml->im, tmp_iml->mod); + } + if (tmp_iml->rmod) { + Imlib_set_image_red_modifier(imlib_id, tmp_iml->im, tmp_iml->rmod); + } + if (tmp_iml->gmod) { + Imlib_set_image_green_modifier(imlib_id, tmp_iml->im, tmp_iml->gmod); + } + if (tmp_iml->bmod) { + Imlib_set_image_blue_modifier(imlib_id, tmp_iml->im, tmp_iml->bmod); + } + if ((images[image_bg].current->pmap->w > 0) || (images[image_bg].current->pmap->op & OP_SCALE)) { + D_PIXMAP(("Scaling image to %dx%d\n", scr->width, scr->height)); + Imlib_render(imlib_id, tmp_iml->im, scr->width, scr->height); + } else { + D_PIXMAP(("Tiling image at %dx%d\n", xsize, ysize)); + Imlib_render(imlib_id, tmp_iml->im, xsize, ysize); + } + viewport_pixmap = Imlib_copy_image(imlib_id, tmp_iml->im); + D_PIXMAP(("Created viewport_pixmap == 0x%08x\n", viewport_pixmap)); + } else { + XGetGeometry(Xdisplay, viewport_pixmap, &dummy, &px, &py, &pw, &ph, &pb, &pd); + xsize = (short) pw; + ysize = (short) ph; + } + if (simg->pmap->pixmap != None) { + XGetGeometry(Xdisplay, simg->pmap->pixmap, &dummy, &px, &py, &pw, &ph, &pb, &pd); + if (pw != width || ph != height) { + Imlib_free_pixmap(imlib_id, simg->pmap->pixmap); + simg->pmap->pixmap = None; + } + } + if (simg->pmap->pixmap == None) { + simg->pmap->pixmap = XCreatePixmap(Xdisplay, win, width, height, Xdepth); + D_PIXMAP(("Created simg->pmap->pixmap == 0x%08x\n", simg->pmap->pixmap)); + } + XTranslateCoordinates(Xdisplay, win, Xroot, 0, 0, &x, &y, &dummy); + D_PIXMAP(("Translated coords are %d, %d\n", x, y)); + if ((images[image_bg].current->pmap->w > 0) || (images[image_bg].current->pmap->op & OP_SCALE)) { + XCopyArea(Xdisplay, viewport_pixmap, simg->pmap->pixmap, gc, x, y, width, height, 0, 0); + } else { + XFreeGC(Xdisplay, gc); + gc = XCreateGC(Xdisplay, viewport_pixmap, 0, &gcvalue); + XSetTile(Xdisplay, gc, viewport_pixmap); + XSetTSOrigin(Xdisplay, gc, xsize - (x % xsize), ysize - (y % ysize)); + XSetFillStyle(Xdisplay, gc, FillTiled); + XFillRectangle(Xdisplay, simg->pmap->pixmap, gc, 0, 0, width, height); + } + XSetWindowBackgroundPixmap(Xdisplay, win, simg->pmap->pixmap); } else -# endif +# endif { -# ifdef PIXMAP_OFFSET - last_width = last_height = last_x = last_y = 0; -# endif + if (simg->iml->im) { + int w = simg->pmap->w; + int h = simg->pmap->h; + int x = simg->pmap->x; + int y = simg->pmap->y; - if (image.im) { - int w = pmap.w; - int h = pmap.h; - int x = pmap.x; - int y = pmap.y; + xsize = simg->iml->im->rgb_width; + ysize = simg->iml->im->rgb_height; + D_PIXMAP(("render_simage(): w == %d, h == %d, x == %d, y == %d, xsize == %d, ysize == %d\n", w, h, x, y, xsize, ysize)); - xsize = image.im->rgb_width; - ysize = image.im->rgb_height; + if ((simg->pmap->op & OP_PROPSCALE)) { + double x_ratio, y_ratio; - D_PIXMAP(("render_pixmap(): w == %d, h == %d, x == %d, y == %d\n", w, h, x, y)); - - /* Don't tile too big or scale too small */ - if (w > scr->width || h > scr->height) { - w = 1; /* scale to 100% */ - } else if (width > (10 * xsize) || height > (10 * ysize)) { - w = 0; /* tile */ - } -# ifdef PIXMAP_OFFSET - if (Options & Opt_viewport_mode) { - D_PIXMAP(("Viewport mode enabled. viewport_pixmap == 0x%08x and TermWin.pixmap == 0x%08x\n", - viewport_pixmap, TermWin.pixmap)); - if (viewport_pixmap == None) { - if (w) { - D_PIXMAP(("Scaling image to %dx%d\n", scr->width, scr->height)); - colormod_pixmap(image, gc, scr->width, scr->height); - Imlib_render(imlib_id, image.im, scr->width, scr->height); - } else { - D_PIXMAP(("Tiling image at %dx%d\n", xsize, ysize)); - colormod_pixmap(image, gc, xsize, ysize); - Imlib_render(imlib_id, image.im, xsize, ysize); + x_ratio = ((double) width) / ((double) xsize); + y_ratio = ((double) height) / ((double) ysize); + if (x_ratio > 1) { + /* Window is larger than image. Smaller ratio determines whether which image dimension is closer in value + to the corresponding window dimension, which is the scale factor we want to use */ + if (x_ratio > y_ratio) { + x_ratio = y_ratio; } - viewport_pixmap = Imlib_copy_image(imlib_id, image.im); - } - if (TermWin.pixmap != None) { - XGetGeometry(Xdisplay, TermWin.pixmap, &dummy, &px, &py, &pw, &ph, &pb, &pd); - if (pw != TermWin_TotalWidth() || ph != TermWin_TotalHeight()) { - XFreePixmap(Xdisplay, TermWin.pixmap); - TermWin.pixmap = None; - } - } - if (TermWin.pixmap == None) { - TermWin.pixmap = XCreatePixmap(Xdisplay, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), Xdepth); - D_PIXMAP(("Created pixmap == 0x%08x and TermWin.pixmap == 0x%08x\n", viewport_pixmap, TermWin.pixmap)); - } - XTranslateCoordinates(Xdisplay, win, Xroot, 0, 0, &x, &y, &dummy); - D_PIXMAP(("Translated coords are %d, %d\n", x, y)); - if (w) { - XCopyArea(Xdisplay, viewport_pixmap, TermWin.pixmap, gc, x, y, TermWin_TotalWidth(), TermWin_TotalHeight(), 0, 0); } else { - XFreeGC(Xdisplay, gc); - gc = XCreateGC(Xdisplay, viewport_pixmap, 0, &gcvalue); - XSetTile(Xdisplay, gc, viewport_pixmap); - XSetTSOrigin(Xdisplay, gc, xsize - (x % xsize), ysize - (y % ysize)); - XSetFillStyle(Xdisplay, gc, FillTiled); - XFillRectangle(Xdisplay, TermWin.pixmap, gc, 0, 0, TermWin_TotalWidth(), TermWin_TotalHeight()); - } - pmap.pixmap = TermWin.pixmap; - } else -# endif - - if (w) { - - /* - * horizontal scaling - */ - - D_PIXMAP(("render_pixmap(): horizontal scaling\n")); - - incr = (float) xsize; - - p = 0; - - if (w == 1) { - /* display image directly - no scaling at all */ - incr = width; - - D_PIXMAP(("render_pixmap(): no horizontal scaling\n")); - - if (xsize <= width) { - w = xsize; - x = (width - w) / 2; - w += x; - } else { - x = 0; - w = width; - } - } else if (w < 10) { - incr *= w; /* fit W images across screen */ - x = 0; - w = width; - } else { - incr *= 100.0 / w; - /* contract */ - if (w < 100) { - w = (w * width) / 100; - /* position */ - if (x >= 0) { - float pos; - - pos = (float) x / 100 * width - (w / 2); - - x = (width - w); - if (pos <= 0) - x = 0; - else if (pos < x) - x = pos; - } else { - x = (width - w) / 2; - } - w += x; - } else if (w >= 100) { - /* expand - */ - /* position */ - if (x > 0) { - float pos; - - pos = (float) x / 100 * xsize - (incr / 2); - - p = xsize - (incr); - if (pos <= 0) - p = 0; - else if (pos < p) - p = pos; - } - x = 0; - w = width; + if (x_ratio > y_ratio) { + x_ratio = y_ratio; } } - incr /= width; - - /* - * vertical scaling - */ - - D_PIXMAP(("render_pixmap(): vertical scaling\n")); - - incr = (float) ysize; - p = 0; - - if (h == 1) { - /* display image directly - no scaling at all */ - incr = height; - - D_PIXMAP(("render_pixmap(): no vertical scaling\n")); - - if (ysize <= height) { - h = ysize; - y = (height - h) / 2; - h += y; - } else { - y = 0; - h = height; - } - } else if (h < 10) { - incr *= h; /* fit H images across screen */ - y = 0; - h = height; - } else { - incr *= 100.0 / h; - /* contract */ - if (h < 100) { - h = (h * height) / 100; - /* position */ - if (y >= 0) { - float pos; - - pos = (float) y / 100 * height - (h / 2); - - y = (height - h); - if (pos < 0.0f) - y = 0; - else if (pos < y) - y = pos; - } else { - y = (height - h) / 2; - } - h += y; - } else if (h >= 100) { - /* expand - */ - /* position */ - if (y > 0) { - float pos; - - pos = (float) y / 100 * ysize - (incr / 2); - - p = ysize - (incr); - if (pos < 0) - p = 0; - else if (pos < p) - p = pos; - } - y = 0; - h = height; - } - } - incr /= height; - - image.last_w = w; - image.last_h = h; - - D_IMLIB(("ImlibRender(0x%x@%dx%d)\n", image.im, w, h)); - colormod_pixmap(image, gc, w, h); - ImlibRender(imlib_id, image.im, w, h); - - D_IMLIB(("pmap.pixmap = ImlibCopyImageToPixmap(0x%x)\n", image.im)); - pmap.pixmap = ImlibCopyImageToPixmap(imlib_id, image.im); - + xscaled = (unsigned short) ((xsize * x_ratio) * ((float) w / 100.0)); + yscaled = (unsigned short) ((ysize * x_ratio) * ((float) h / 100.0)); } else { - /* if (w), light years above. -vendu */ - /* tiled */ - - D_PIXMAP(("render_pixmap(): tiling pixmap\n")); - - if (!((Options & Opt_pixmapTrans) && rendered)) { - D_IMLIB(("ImlibRender(0x%x@%dx%d)\n", image.im, xsize, ysize)); - colormod_pixmap(image, gc, xsize, ysize); - ImlibRender(imlib_id, image.im, xsize, ysize); - rendered = 1; + if (w > 0) { + xscaled = width * ((float) w / 100.0); + } else { + xscaled = xsize; } - D_IMLIB(("pixmap = ImlibCopyImageToPixmap()\n")); - pixmap = ImlibCopyImageToPixmap(imlib_id, image.im); - -# ifdef PIXMAP_OFFSET - if (Options & Opt_pixmapTrans) { - D_IMLIB(("ImlibFreePixmap(0x%x)\n", pixmap)); - ImlibFreePixmap(imlib_id, pixmap); - pixmap = None; - } else -# endif - { - D_PIXMAP(("XCreatePixmap(pmap.pixmap(%d,%d))\n", width, height)); - pmap.pixmap = XCreatePixmap(Xdisplay, win, - width, height, Xdepth); - - for (y = 0; y < height; y += ysize) { - unsigned int h = (height - y); - - if (h > ysize) - h = ysize; - - for (x = 0; x < width; x += xsize) { - unsigned int w = (width - x); - - if (w > xsize) - w = xsize; - D_PIXMAP(("XCopyArea(pixmap(%dx%d)->pmap.pixmap)\n", w, h)); - XCopyArea(Xdisplay, pixmap, pmap.pixmap, gc, 0, 0, w, h, x, y); - } - } - - D_IMLIB(("ImlibFreePixmap(0x%x)\n", pixmap)); - ImlibFreePixmap(imlib_id, pixmap); - pixmap = None; + if (h > 0) { + yscaled = height * ((float) h / 100.0); + } else { + yscaled = ysize; } } - } else - XFillRectangle(Xdisplay, pixmap, gc, 0, 0, width, height); - } - if (pmap.pixmap != None) { - D_PIXMAP(("XSetWindowBackgroundPixmap(pmap.pixmap)\n")); - XSetWindowBackgroundPixmap(Xdisplay, win, pmap.pixmap); - if (imlib_id -#ifndef IMLIB_TRANS - && !(Options & Opt_pixmapTrans || Options & Opt_viewport_mode) -#endif - ) { - D_IMLIB(("ImlibFreePixmap(pmap.pixmap)\n")); - ImlibFreePixmap(imlib_id, pmap.pixmap); - pmap.pixmap = None; + + xpos = (short) ((width - xscaled) * ((float) x / 100.0)); + ypos = (short) ((height - yscaled) * ((float) y / 100.0)); + D_PIXMAP(("render_simage(): Calculated scaled size as %hux%hu with origin at (%hd, %hd)\n", xscaled, yscaled, xpos, ypos)); + + if (simg->iml->last_w != xscaled || simg->iml->last_h != yscaled || 1) { + + simg->iml->last_w = xscaled; + simg->iml->last_h = yscaled; + + if (simg->iml->border) { + D_PIXMAP(("render_simage(): Setting image border: { left [%d], right [%d], top [%d], bottom [%d] }\n", + simg->iml->border->left, simg->iml->border->right, simg->iml->border->top, simg->iml->border->bottom)); + Imlib_set_image_border(imlib_id, simg->iml->im, simg->iml->border); + } + if (simg->iml->mod) { + D_PIXMAP(("render_simage(): Setting image modifier: { gamma [0x%08x], brightness [0x%08x], contrast [0x%08x] }\n", + simg->iml->mod->gamma, simg->iml->mod->brightness, simg->iml->mod->contrast)); + Imlib_set_image_modifier(imlib_id, simg->iml->im, simg->iml->mod); + } + if (simg->iml->rmod) { + D_PIXMAP(("render_simage(): Setting image red modifier: { gamma [0x%08x], brightness [0x%08x], contrast [0x%08x] }\n", + simg->iml->rmod->gamma, simg->iml->rmod->brightness, simg->iml->rmod->contrast)); + Imlib_set_image_red_modifier(imlib_id, simg->iml->im, simg->iml->rmod); + } + if (simg->iml->gmod) { + D_PIXMAP(("render_simage(): Setting image green modifier: { gamma [0x%08x], brightness [0x%08x], contrast [0x%08x] }\n", + simg->iml->gmod->gamma, simg->iml->gmod->brightness, simg->iml->gmod->contrast)); + Imlib_set_image_green_modifier(imlib_id, simg->iml->im, simg->iml->gmod); + } + if (simg->iml->bmod) { + D_PIXMAP(("render_simage(): Setting image blue modifier: { gamma [0x%08x], brightness [0x%08x], contrast [0x%08x] }\n", + simg->iml->bmod->gamma, simg->iml->bmod->brightness, simg->iml->bmod->contrast)); + Imlib_set_image_blue_modifier(imlib_id, simg->iml->im, simg->iml->bmod); + } + D_PIXMAP(("render_simage(): Rendering image simg->iml->im [0x%08x] to %hdx%hd pixmap\n", simg->iml->im, xscaled, yscaled)); + Imlib_render(imlib_id, simg->iml->im, xscaled, yscaled); + rendered = 1; + } + simg->pmap->pixmap = Imlib_copy_image(imlib_id, simg->iml->im); + simg->pmap->mask = Imlib_copy_mask(imlib_id, simg->iml->im); + if (simg->pmap->mask != None) { + shaped_window_apply_mask(win, simg->pmap->mask); + } + } else { + XSetWindowBackground(Xdisplay, win, PixColors[bgColor]); + reset_simage(simg, RESET_ALL); + } + if (simg->pmap->pixmap != None) { + if (pixmap != None) { + Imlib_free_pixmap(imlib_id, pixmap); + } + if (xscaled != width || yscaled != height || xpos != 0 || ypos != 0) { + unsigned char single; + + single = ((xscaled < width || yscaled < height) && !(simg->pmap->op & OP_TILE)) ? 1 : 0; + + pixmap = simg->pmap->pixmap; + simg->pmap->pixmap = XCreatePixmap(Xdisplay, win, width, height, Xdepth); + if (single) + XFillRectangle(Xdisplay, simg->pmap->pixmap, gc, 0, 0, width, height); + XSetTile(Xdisplay, gc, pixmap); + XSetTSOrigin(Xdisplay, gc, xpos, ypos); + XSetFillStyle(Xdisplay, gc, FillTiled); + if (single) { + XCopyArea(Xdisplay, pixmap, simg->pmap->pixmap, gc, 0, 0, xscaled, yscaled, xpos, ypos); + } else { + XFillRectangle(Xdisplay, simg->pmap->pixmap, gc, 0, 0, width, height); + } + Imlib_free_pixmap(imlib_id, pixmap); + } + if (simg->iml->bevel != NULL) { + Imlib_bevel_pixmap(imlib_id, simg->pmap->pixmap, width, height, simg->iml->bevel->edges, simg->iml->bevel->up); + } + XSetWindowBackgroundPixmap(Xdisplay, win, simg->pmap->pixmap); } } - XSync(Xdisplay, 0); - XFreeGC(Xdisplay, gc); XClearWindow(Xdisplay, win); - XFlush(Xdisplay); - XSync(Xdisplay, 0); + XFreeGC(Xdisplay, gc); + XSync(Xdisplay, False); } -# else /* PIXMAP_SUPPORT */ -# define scale_pixmap(str,p) ((void)0) -# define render_pixmap() ((void)0) -# endif /* PIXMAP_SUPPORT */ -# if defined(PIXMAP_SUPPORT) || (MENUBAR_MAX) -/* - * search for FILE in the current working directory, and within the - * colon-delimited PATHLIST, adding the file extension EXT if required. - * - * FILE is either @ or zero terminated - */ const char * search_path(const char *pathlist, const char *file, const char *ext) { - /* FIXME: the 256 below should be changed to some #define in */ - static char name[256]; + static char name[PATH_MAX]; char *p; const char *path; int maxpath, len; @@ -835,7 +672,8 @@ search_path(const char *pathlist, const char *file, const char *ext) if (!ext) { ext = ""; } - D_OPTIONS(("search_path(\"%s\", \"%s\", \"%s\") called.\n", pathlist, file, ext)); + getcwd(name, PATH_MAX); + D_OPTIONS(("search_path(\"%s\", \"%s\", \"%s\") called from \"%s\".\n", pathlist, file, ext, name)); D_OPTIONS(("search_path(): Checking for file \"%s\"\n", file)); if (!access(file, R_OK)) { if (stat(file, &fst)) { @@ -846,7 +684,6 @@ search_path(const char *pathlist, const char *file, const char *ext) if (!S_ISDIR(fst.st_mode)) return file; } - /* Changed to use '@' as the delimiter. -vendu */ if ((p = strchr(file, '@')) == NULL) p = strchr(file, '\0'); len = (p - file); @@ -922,318 +759,81 @@ search_path(const char *pathlist, const char *file, const char *ext) } } } - return NULL; -} -# endif /* PIXMAP_SUPPORT || (MENUBAR_MAX) */ - -# ifdef PIXMAP_SUPPORT -/* I think it might be cool to make Eterm load the pixmaps in background. - * You'd be able to start typing commands without waiting for the bg - * pixmap processing to end. Thoughts right now: fork(), pthreads. -vendu - */ - -void -set_bgPixmap(const char *file) -{ - const char *f = NULL; - - ASSERT(file != NULL); - - if (!file) { - return; - } - D_IMLIB(("set_bgPixmap(%s)\n", file)); - - /* Turn on scaling */ - if ((Options & Opt_pixmapScale) || (rs_pixmapScale)) { - bgPixmap.h = 100; - bgPixmap.w = 100; - } - /* XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); */ - - if (*file != '\0') { - /* XGetWindowAttributes(Xdisplay, TermWin.vt, &attr); */ - - /* search environment variables here too */ -# ifdef USE_IMLIB - if ((f = search_path(rs_path, file, PIXMAP_EXT)) == NULL) -# endif -# ifdef PATH_ENV -# ifdef USE_IMLIB - if ((f = search_path(getenv(PATH_ENV), file, PIXMAP_EXT)) == NULL) -# endif -# endif /* PATH_ENV */ -# ifdef USE_IMLIB - f = search_path(getenv("PATH"), file, PIXMAP_EXT); -# endif - -# ifdef USE_IMLIB - if (f != NULL) { - rs_pixmaps[pixmap_bg] = strdup(f); - if (imlib_bg.im != NULL) { - D_IMLIB(("ImlibDestroyImage()\n")); - ImlibDestroyImage(imlib_id, imlib_bg.im); - imlib_bg.im = NULL; - } - D_IMLIB(("ReadImageViaImlib(%s)\n", (char *) f)); - imlib_bg.im = ReadImageViaImlib(Xdisplay, (char *) f); - } - if (imlib_bg.im == NULL) { -# endif - char *p; - - if ((p = strchr(file, ';')) == NULL && (p = strchr(file, '@')) == NULL) - p = strchr(file, '\0'); - print_error("couldn't load image file \"%.*s\"", (p - file), file); - if (!(background_is_pixmap())) { - XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); - } -# ifdef USE_POSIX_THREADS - XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); -# endif - } else { -# ifdef USE_POSIX_THREADS - /* FIXME: the if tests should be removed and done once at the - * else above. - */ - if (bg_needs_update) { - D_THREADS(("pthread_attr_init(resize_sub_thr_attr)\n")); - pthread_attr_init(&resize_sub_thr_attr); -# ifdef MUTEX_SYNCH - if (pthread_mutex_trylock(&mutex) == EBUSY) { - D_THREADS(("set_bgPixmap(): pthread_cancel(resize_sub_thr);\n")); - pthread_cancel(resize_sub_thr); - } else { - D_THREADS(("pthread_mutex_trylock(&mutex): ")); - pthread_mutex_unlock(&mutex); - D_THREADS(("pthread_mutex_unlock(&mutex)\n")); - } -# else - if (bg_set) { - D_THREADS(("Background set, cancelling thread\n")); - pthread_cancel(resize_sub_thr); - } -# endif - - if (!(pthread_create(&resize_sub_thr, &resize_sub_thr_attr, - (void *) &render_bg_thread, NULL))) { - bg_set = 0; -# ifdef MUTEX_SYNCH - /* D_THREADS("pthread_mutex_lock(&mutex);\n"); */ - /* pthread_mutex_lock(&mutex); */ -# endif - D_THREADS(("thread created\n")); - } else { - D_THREADS(("pthread_create() failed!\n")); - } - } -# else - -# ifdef PIXMAP_OFFSET - if (Options & Opt_viewport_mode) { - if (viewport_pixmap != None) { - XFreePixmap(Xdisplay, viewport_pixmap); - viewport_pixmap = None; - bg_needs_update = 1; - } - } -# endif - if (bg_needs_update) { - D_PIXMAP(("set_bgPixmap(): render_pixmap(TermWin.vt), case 2\n")); - render_pixmap(TermWin.vt, imlib_bg, bgPixmap, 0, 1); - scr_touch(); - bg_needs_update = 0; - } -# endif - } - - /* init_imlib = 1; */ - /* pthread_join(resize_sub_thr, NULL); */ - D_PIXMAP(("set_bgPixmap() exitting\n")); - } -# ifdef IMLIB_TRANS - else if (Options & Opt_pixmapTrans) { - render_pixmap(TermWin.vt, imlib_bg, bgPixmap, 0, 1); - scr_touch(); - bg_needs_update = 0; - } -# endif - - if (!f || *f == '\0') { - if (imlib_bg.im != NULL) { - D_IMLIB(("ImlibDestroyImage()\n")); - ImlibDestroyImage(imlib_id, imlib_bg.im); - imlib_bg.im = NULL; - } - XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); - XClearWindow(Xdisplay, TermWin.vt); - scr_touch(); - XFlush(Xdisplay); - } + D_OPTIONS(("search_path(): File \"%s\" not found in path.\n", file)); + return ((const char *) NULL); } -# ifdef PIXMAP_SCROLLBAR -void -set_Pixmap(const char *file, Pixmap dest_pmap, int type) +unsigned short +load_image(const char *file, short type) { const char *f; imlib_t img; + char *geom; - /* FIXME: assert() looks like a bad thing. Calls abort(). IMHO, stupid. */ - assert(file != NULL); + ASSERT_RVAL(file != NULL, 0); + ASSERT_RVAL(type >= 0 && type < image_max, 0); - D_IMLIB(("set_Pixmap(%s)\n", file)); + D_PIXMAP(("load_image(%s, %d)\n", file, type)); if (*file != '\0') { - /* search environment variables here too */ -# ifdef USE_IMLIB - if ((f = search_path(rs_path, file, PIXMAP_EXT)) == NULL) -# endif -# ifdef PATH_ENV -# ifdef USE_IMLIB - if ((f = search_path(getenv(PATH_ENV), file, PIXMAP_EXT)) == NULL) -# endif -# endif /* PATH_ENV */ -# ifdef USE_IMLIB - f = search_path(getenv("PATH"), file, PIXMAP_EXT); -# endif -# ifdef USE_IMLIB + if ((geom = strchr(file, '@')) != NULL) { + *geom++ = 0; + } else if ((geom = strchr(file, ';')) != NULL) { + *geom++ = 0; + } + if (geom != NULL) { + set_pixmap_scale(geom, images[type].current->pmap); + } + if ((f = search_path(rs_path, file, PIXMAP_EXT)) == NULL) { + f = search_path(getenv(PATH_ENV), file, PIXMAP_EXT); + } if (f != NULL) { - D_IMLIB(("ReadImageViaImlib(%s)\n", (char *) f)); - img.im = ReadImageViaImlib(Xdisplay, (char *) f); - } - if (img.im == NULL) { -# endif - char *p; - - if ((p = strchr(file, ';')) == NULL) - p = strchr(file, '\0'); - print_error("couldn't load image file \"%.*s\"", (p - file), file); - } else { - switch (type) { - case pixmap_sb: - render_pixmap(scrollBar.win, img, sbPixmap, pixmap_sb, 0); - break; - case pixmap_sa: - render_pixmap(scrollBar.sa_win, img, saPixmap, pixmap_sa, 0); - break; - case pixmap_saclk: - render_pixmap(scrollBar.sa_win, img, sa_clkPixmap, pixmap_saclk, 0); - break; - case pixmap_up: - render_pixmap(scrollBar.up_win, img, upPixmap, pixmap_up, 0); - break; - case pixmap_upclk: - render_pixmap(scrollBar.up_win, img, up_clkPixmap, pixmap_upclk, 0); - break; - case pixmap_dn: - render_pixmap(scrollBar.dn_win, img, dnPixmap, pixmap_dn, 0); - break; - case pixmap_dnclk: - render_pixmap(scrollBar.dn_win, img, dn_clkPixmap, pixmap_dnclk, 0); - break; - case pixmap_mb: -/* render_pixmap(ActiveMenu->win, img, mbPixmap, pixmap_mb, 0); */ - break; - case pixmap_ms: -/* render_pixmap(ActiveMenu->win, img, mb_selPixmap, pixmap_ms, 0); */ - break; - default: - D_PIXMAP(("WARNING: set_Pixmap() returning\n")); - return; + img.im = Imlib_load_image(imlib_id, (char *) f); + if (img.im == NULL) { + print_error("Unable to load image file \"%s\"", file); + return 0; + } else { + reset_simage(images[type].current, (RESET_IMLIB_IM | RESET_PMAP_PIXMAP | RESET_PMAP_MASK)); + images[type].current->iml->im = img.im; } + D_PIXMAP(("load_image() exiting. images[%s].current->iml->im == 0x%08x\n", get_image_type(type), images[type].current->iml->im)); + return 1; } } - D_PIXMAP(("set_scrPixmap() exitting\n")); + reset_simage(images[type].current, RESET_ALL); + return 0; } -# endif /* PIXMAP_SCROLLBAR */ void -colormod_pixmap(imlib_t image, GC gc, int w, int h) +free_desktop_pixmap(void) { - unsigned int bright; - ImlibColorModifier xform = - {0xff, 0xff, 0xff}, rx = - {0xff, 0xff, 0xff}, gx = - {0xff, 0xff, 0xff}, bx = - {0xff, 0xff, 0xff}; - - if (rs_shadePct == 0 && rs_tintMask == 0xffffff) { - Imlib_set_image_modifier(imlib_id, image.im, &xform); - Imlib_set_image_red_modifier(imlib_id, image.im, &rx); - Imlib_set_image_green_modifier(imlib_id, image.im, &gx); - Imlib_set_image_blue_modifier(imlib_id, image.im, &bx); - return; + if (desktop_pixmap_is_mine) { + XFreePixmap(Xdisplay, desktop_pixmap); + desktop_pixmap_is_mine = 0; } - if (rs_shadePct != 0) { - bright = 0xff - ((rs_shadePct * 0xff) / 100); - xform.brightness = bright; - Imlib_set_image_modifier(imlib_id, image.im, &xform); - } else { - Imlib_set_image_modifier(imlib_id, image.im, &xform); - } - - if (rs_tintMask != 0xffffff) { - rx.brightness = (rs_tintMask & 0xff0000) >> 16; - gx.brightness = (rs_tintMask & 0x00ff00) >> 8; - bx.brightness = rs_tintMask & 0x0000ff; - Imlib_set_image_red_modifier(imlib_id, image.im, &rx); - Imlib_set_image_green_modifier(imlib_id, image.im, &gx); - Imlib_set_image_blue_modifier(imlib_id, image.im, &bx); - } else { - Imlib_set_image_red_modifier(imlib_id, image.im, &rx); - Imlib_set_image_green_modifier(imlib_id, image.im, &gx); - Imlib_set_image_blue_modifier(imlib_id, image.im, &bx); - } - - D_PIXMAP(("Image modifiers: xform == %08x, rx == %08x, gx == %08x, bx == %08x\n", - xform.brightness, rx.brightness, gx.brightness, bx.brightness)); + desktop_pixmap = None; } -# ifdef USE_IMLIB -# undef PIXMAP_EXT -# endif +# ifdef PIXMAP_OFFSET -# ifdef PIXMAP_OFFSET +# define MOD_IS_SET(mod) ((mod) && ((mod)->brightness != 0xff || (mod)->contrast != 0xff || (mod)->gamma != 0xff)) -# ifdef IMLIB_TRANS -void -colormod_trans(imlib_t image, GC gc, int w, int h) +unsigned char +need_colormod(void) { + register imlib_t *iml = images[image_bg].current->iml; - unsigned int bright; - ImlibColorModifier xform = - {0xff, 0xff, 0xff}, rx = - {0xff, 0xff, 0xff}, gx = - {0xff, 0xff, 0xff}, bx = - {0xff, 0xff, 0xff}; - - if (rs_shadePct == 0 && rs_tintMask == 0xffffff) { - return; + if (MOD_IS_SET(iml->mod) || MOD_IS_SET(iml->rmod) || MOD_IS_SET(iml->gmod) || MOD_IS_SET(iml->bmod)) { + return 1; + } else { + return 0; } - if (rs_shadePct != 0) { - bright = 0xff - ((rs_shadePct * 0xff) / 100); - xform.brightness = bright; - Imlib_set_image_modifier(imlib_id, image.im, &xform); - } - if (rs_tintMask != 0xffffff) { - rx.brightness = (rs_tintMask & 0xff0000) >> 16; - gx.brightness = (rs_tintMask & 0x00ff00) >> 8; - bx.brightness = rs_tintMask & 0x0000ff; - Imlib_set_image_red_modifier(imlib_id, image.im, &rx); - Imlib_set_image_green_modifier(imlib_id, image.im, &gx); - Imlib_set_image_blue_modifier(imlib_id, image.im, &bx); - } - D_PIXMAP(("Image modifiers: xform == %08x, rx == %08x, gx == %08x, bx == %08x\n", - xform.brightness, rx.brightness, gx.brightness, bx.brightness)); } -# else /* IMLIB_TRANS */ - void -colormod_trans(Pixmap p, GC gc, int w, int h) +colormod_trans(Pixmap p, GC gc, unsigned short w, unsigned short h) { XImage *ximg; @@ -1245,20 +845,42 @@ colormod_trans(Pixmap p, GC gc, int w, int h) int real_depth = 0; register int br, bg, bb; register unsigned int mr, mg, mb; + imlib_t *iml = images[image_bg].current->iml; - if (rs_shadePct == 0 && rs_tintMask == 0xffffff) { - return; + if (iml->mod) { + shade = (float) (iml->mod->brightness / 255.0); + } else { + shade = 1.0; + } + if (iml->rmod) { + rm = (float) (iml->rmod->brightness) / 255.0 * shade; + } else { + rm = shade; + } + if (iml->gmod) { + gm = (float) (iml->gmod->brightness) / 255.0 * shade; + } else { + gm = shade; + } + if (iml->bmod) { + bm = (float) (iml->bmod->brightness) / 255.0 * shade; + } else { + bm = shade; + } + + if (shade == 1.0 && rm == 1.0 && gm == 1.0 && bm == 1.0) { + return; /* Nothing to do */ } if (Xdepth <= 8) { XColor cols[256]; - for (i = 0; i < (1 << Xdepth); i++) { + for (i = 0; i < (unsigned long) (1 << Xdepth); i++) { cols[i].pixel = i; cols[i].flags = DoRed | DoGreen | DoBlue; } - XQueryColors(Xdisplay, Xcmap, cols, 1 << Xdepth); - for (i = 0; i < (1 << Xdepth); i++) { + XQueryColors(Xdisplay, cmap, cols, 1 << Xdepth); + for (i = 0; i < (unsigned long) (1 << Xdepth); i++) { ctab[i].r = cols[i].red >> 8; ctab[i].g = cols[i].green >> 8; ctab[i].b = cols[i].blue >> 8; @@ -1276,11 +898,6 @@ colormod_trans(Pixmap p, GC gc, int w, int h) if (!real_depth) { real_depth = Xdepth; } - shade = (float) (100 - rs_shadePct) / 100.0; - rm = (float) ((rs_tintMask & 0xff0000) >> 16) / 255.0 * shade; - gm = (float) ((rs_tintMask & 0x00ff00) >> 8) / 255.0 * shade; - bm = (float) (rs_tintMask & 0x0000ff) / 255.0 * shade; - ximg = XGetImage(Xdisplay, p, 0, 0, w, h, -1, ZPixmap); if (ximg == NULL) { print_warning("colormod_trans: XGetImage(Xdisplay, 0x%08x, 0, 0, %d, %d, -1, ZPixmap) returned NULL.", @@ -1340,8 +957,6 @@ colormod_trans(Pixmap p, GC gc, int w, int h) XDestroyImage(ximg); } -# endif /* IMLIB_TRANS */ - Window get_desktop_window(void) { @@ -1352,7 +967,6 @@ get_desktop_window(void) unsigned char *data; unsigned int nchildren; Window w, root, *children, parent; - Window last_desktop_window = desktop_window; if ((prop = XInternAtom(Xdisplay, "_XROOTPMAP_ID", True)) == None) { D_PIXMAP(("No _XROOTPMAP_ID found.\n")); @@ -1363,16 +977,9 @@ get_desktop_window(void) if (prop == None && prop2 == None) { return None; } -#ifdef WATCH_DESKTOP_OPTION - if (Options & Opt_watchDesktop) { - if (TermWin.wm_parent != None) { - XSelectInput(Xdisplay, TermWin.wm_parent, None); - } - if (TermWin.wm_grandparent != None) { - XSelectInput(Xdisplay, TermWin.wm_grandparent, None); - } + if (desktop_window != None) { + XSelectInput(Xdisplay, desktop_window, None); } -#endif for (w = TermWin.parent; w; w = parent) { @@ -1387,17 +994,6 @@ get_desktop_window(void) if (nchildren) { XFree(children); } -#ifdef WATCH_DESKTOP_OPTION - if (Options & Opt_watchDesktop && parent != None) { - if (w == TermWin.parent) { - TermWin.wm_parent = parent; - XSelectInput(Xdisplay, TermWin.wm_parent, StructureNotifyMask); - } else if (w == TermWin.wm_parent) { - TermWin.wm_grandparent = parent; - XSelectInput(Xdisplay, TermWin.wm_grandparent, StructureNotifyMask); - } - } -#endif if (prop != None) { XGetWindowProperty(Xdisplay, w, prop, 0L, 1L, False, AnyPropertyType, @@ -1410,6 +1006,7 @@ get_desktop_window(void) } if (type != None) { D_PIXMAP((" Found desktop as window 0x%08x\n", w)); + XSelectInput(Xdisplay, w, PropertyChangeMask); return (desktop_window = w); } } @@ -1428,8 +1025,6 @@ get_desktop_pixmap(void) int format; unsigned long length, after; unsigned char *data; - register unsigned long i = 0; - time_t blah; if (desktop_window == None) return None; @@ -1441,38 +1036,15 @@ get_desktop_pixmap(void) return None; } if (prop != None) { - XGetWindowProperty(Xdisplay, desktop_window, prop, 0L, 1L, False, AnyPropertyType, - &type, &format, &length, &after, &data); + XGetWindowProperty(Xdisplay, desktop_window, prop, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data); if (type == XA_PIXMAP) { p = *((Pixmap *) data); - /* - blah = time(NULL); - D_PIXMAP(("Time index: %s\n", ctime(&blah))); - for (i=0; i < 4000000000 && !p; i++) { - D_PIXMAP((" Null pixmap returned. i == %lu Trying again in 20 ms.\n", i)); - usleep(2000000); - XGetWindowProperty(Xdisplay, desktop_window, prop, 0L, 1L, False, AnyPropertyType, - &type, &format, &length, &after, &data); - if (type != XA_PIXMAP) { - p = None; - break; - } else { - p = *((Pixmap *)data); - } - } - blah = time(NULL); - D_PIXMAP(("Time index: %s\n", ctime(&blah))); - if (i != 0 && p != 0) { - _exit(0); - } - */ D_PIXMAP((" Found pixmap 0x%08x\n", p)); return p; } } if (prop2 != None) { - XGetWindowProperty(Xdisplay, desktop_window, prop2, 0L, 1L, False, AnyPropertyType, - &type, &format, &length, &after, &data); + XGetWindowProperty(Xdisplay, desktop_window, prop2, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data); if (type == XA_CARDINAL) { D_PIXMAP((" Solid color not yet supported.\n")); return None; @@ -1482,41 +1054,39 @@ get_desktop_pixmap(void) return None; } -# endif /* PIXMAP_OFFSET) */ +# endif /* PIXMAP_OFFSET */ void shaped_window_apply_mask(Window win, Pixmap mask) { static signed char have_shape = -1; - int unused; - D_PIXMAP(("shaped_window_apply_mask(0x%08x, 0x%08x) called.\n", win, mask)); - if (win == None || mask == None) - return; + REQUIRE(win != None && mask != None); + + D_PIXMAP(("shaped_window_apply_mask(win [0x%08x], mask [0x%08x]) called.\n", win, mask)); + +# ifdef HAVE_X_SHAPE_EXT + if (have_shape == -1) { /* Don't know yet. */ + int unused; -#ifdef HAVE_X_SHAPE_EXT - if (1 == have_shape) { - D_PIXMAP(("shaped_window_apply_mask(): Shape extension available, applying mask.\n")); - XShapeCombineMask(Xdisplay, win, ShapeBounding, 0, 0, mask, ShapeSet); - } else if (0 == have_shape) { - D_PIXMAP(("shaped_window_apply_mask(): Shape extension not available.\n")); - return; - } else { /* Don't know yet? */ D_PIXMAP(("shaped_window_apply_mask(): Looking for shape extension.\n")); - if (!XQueryExtension(Xdisplay, "SHAPE", &unused, &unused, &unused)) { - have_shape = 0; - D_PIXMAP(("shaped_window_apply_mask(): Shape extension not found.\n")); - return; - } else { + if (XQueryExtension(Xdisplay, "SHAPE", &unused, &unused, &unused)) { have_shape = 1; - D_PIXMAP(("shaped_window_apply_mask(): Shape extension available, applying mask.\n")); - XShapeCombineMask(Xdisplay, win, ShapeBounding, 0, 0, mask, ShapeSet); + } else { + have_shape = 0; } } -#else + if (have_shape == 1) { + D_PIXMAP(("shaped_window_apply_mask(): Shape extension available, applying mask.\n")); + XShapeCombineMask(Xdisplay, win, ShapeBounding, 0, 0, mask, ShapeSet); + } else if (have_shape == 0) { + D_PIXMAP(("shaped_window_apply_mask(): Shape extension not available.\n")); + return; + } +# else D_PIXMAP(("shaped_window_apply_mask(): Shape support disabled.\n")); -#endif +# endif } void @@ -1535,16 +1105,13 @@ set_icon_pixmap(char *filename, XWMHints * pwm_hints) if (filename && *filename) { if ((icon_path = search_path(rs_path, filename, NULL)) == NULL) -# ifdef PATH_ENV - if ((icon_path = search_path(getenv(PATH_ENV), filename, NULL)) == NULL) -# endif - icon_path = search_path(getenv("PATH"), filename, NULL); + icon_path = search_path(getenv(PATH_ENV), filename, NULL); if (icon_path != NULL) { XIconSize *icon_sizes; int count, i, w = 64, h = 64; - temp_im = ReadImageViaImlib(Xdisplay, icon_path); + temp_im = Imlib_load_image(imlib_id, (char *) icon_path); /* If we're going to render the image anyway, might as well be nice and give it to the WM in a size it likes. */ if (XGetIconSizes(Xdisplay, Xroot, &icon_sizes, &count)) { for (i = 0; i < count; i++) { @@ -1582,9 +1149,9 @@ set_icon_pixmap(char *filename, XWMHints * pwm_hints) } } -# ifdef USE_EFFECTS +# ifdef USE_EFFECTS int -fade_in(Pixmap * pmap, ImlibImage * img, int frames) +fade_in(ImlibImage *img, int frames) { static int i = 0; @@ -1606,6 +1173,6 @@ fade_in(Pixmap * pmap, ImlibImage * img, int frames) /* how many frames to go */ return (f - i); } -# endif /* USE_EFFECTS */ +# endif /* USE_EFFECTS */ #endif /* PIXMAP_SUPPORT */ diff --git a/src/pixmap.h b/src/pixmap.h index d1d9ba3..a403820 100644 --- a/src/pixmap.h +++ b/src/pixmap.h @@ -1,89 +1,172 @@ -/* pixmap.h for Eterm. - * 17 Feb 1998 vendu +/* pixmap.h -- Eterm pixmap module header file + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * */ #ifndef _PIXMAP_H # define _PIXMAP_H #include +#include -# ifdef USE_IMLIB -# include "eterm_imlib.h" -# endif +/************ Macros and Definitions ************/ +#ifdef PIXMAP_SUPPORT +# define background_is_image() (images[image_bg].current && images[image_bg].current->iml && images[image_bg].current->iml->im) +# define background_is_pixmap() (background_is_image() || Options & Opt_pixmapTrans) +# define delete_simage(simg) do { \ + Imlib_free_pixmap(imlib_id, (simg)->pmap->pixmap); \ + Imlib_destroy_image(imlib_id, (simg)->iml->im); \ + (simg)->pmap->pixmap = None; (simg)->iml->im = NULL; \ + } while (0) +# define CONVERT_SHADE(s) (0xff - (((s) * 0xff) / 100)) +# define CONVERT_TINT_RED(t) (((t) & 0xff0000) >> 16) +# define CONVERT_TINT_GREEN(t) (((t) & 0x00ff00) >> 8) +# define CONVERT_TINT_BLUE(t) ((t) & 0x0000ff) +#else +# define background_is_pixmap() ((int)0) +# define background_is_image() ((int)0) +# define delete_simage(simg) ((void)0) +#endif +#define PIXMAP_EXT NULL +/* '[', 2*4 + 2*3 digits + 3 delimiters, ']'. -vendu */ +#define GEOM_LEN 19 +enum { + image_bg, + image_up, + image_down, + image_left, + image_right, +#ifdef PIXMAP_SCROLLBAR + image_sb, + image_sa, +#endif +#ifdef PIXMAP_MENUBAR + image_menu, + image_submenu, +#endif + image_max +}; + +/* Image manipulation operations */ +#define OP_NONE 0x00 +#define OP_TILE 0x01 +#define OP_HSCALE 0x02 +#define OP_VSCALE 0x04 +#define OP_PROPSCALE 0x08 +#define OP_SCALE (OP_HSCALE | OP_VSCALE) + +/* Image modes */ +#define MODE_IMAGE 0x00 +#define MODE_TRANS 0x01 +#define MODE_VIEWPORT 0x02 +#define MODE_AUTO 0x04 +#define MODE_MASK 0x07 +#define ALLOW_IMAGE 0x00 +#define ALLOW_TRANS 0x10 +#define ALLOW_VIEWPORT 0x20 +#define ALLOW_AUTO 0x40 +#define ALLOW_MASK 0x70 + +/* Elements of an simage to be reset */ +#define RESET_NONE (0UL) +#define RESET_IMLIB_MOD (1UL << 0) +#define RESET_IMLIB_RMOD (1UL << 1) +#define RESET_IMLIB_GMOD (1UL << 2) +#define RESET_IMLIB_BMOD (1UL << 3) +#define RESET_ALL_TINT (RESET_IMLIB_RMOD | RESET_IMLIB_GMOD | RESET_IMLIB_BMOD) +#define RESET_ALL_MOD (RESET_IMLIB_MOD | RESET_IMLIB_RMOD | RESET_IMLIB_GMOD | RESET_IMLIB_BMOD) +#define RESET_IMLIB_BORDER (1UL << 4) +#define RESET_IMLIB_IM (1UL << 5) +#define RESET_ALL_IMLIB (RESET_ALL_MOD | RESET_IMLIB_BORDER | RESET_IMLIB_IM) +#define RESET_PMAP_GEOM (1UL << 6) +#define RESET_PMAP_PIXMAP (1UL << 7) +#define RESET_PMAP_MASK (1UL << 8) +#define RESET_ALL_PMAP (RESET_PMAP_GEOM | RESET_PMAP_PIXMAP | RESET_PMAP_MASK) +#define RESET_ALL (RESET_ALL_IMLIB | RESET_ALL_PMAP) + +/************ Structures ************/ typedef struct { - short w, h, x, y; - Pixmap pixmap; + unsigned short op; + short w, h, x, y; + Pixmap pixmap; + Pixmap mask; } pixmap_t; - -# ifdef USE_IMLIB typedef struct { - Image *im; - int last_w,last_h; + ImlibBorder *edges; + unsigned char up; +} bevel_t; +typedef struct { + ImlibImage *im; + ImlibBorder *border, *pad; + bevel_t *bevel; + ImlibColorModifier *mod, *rmod, *gmod, *bmod; + short last_w, last_h; } imlib_t; - -# define background_is_pixmap() ((imlib_id != NULL) || Options & Opt_pixmapTrans) -# define background_is_image() (imlib_bg.im != NULL) - -# else - -# define background_is_pixmap() ((int)0) -# define background_is_image() ((int)0) - -# endif - -# ifdef USE_IMLIB -extern imlib_t imlib_bg; -extern ImlibData *imlib_id; -# ifdef PIXMAP_SCROLLBAR -imlib_t imlib_sb, imlib_sa, imlib_saclk; -# endif -# endif -pixmap_t bgPixmap; -# ifdef PIXMAP_SCROLLBAR -pixmap_t sbPixmap; -pixmap_t upPixmap, up_clkPixmap; -pixmap_t dnPixmap, dn_clkPixmap; -pixmap_t saPixmap, sa_clkPixmap; -# endif - +typedef struct { + pixmap_t *pmap; + imlib_t *iml; +} simage_t; +typedef struct { + Window win; + unsigned char mode; + simage_t *norm, *selected, *clicked, *current; +} image_t; typedef short renderop_t; -# ifdef PIXMAP_OFFSET -enum { FAKE_TRANSPARENCY }; -enum { tint_none, tint_red, tint_green, tint_blue, - tint_cyan, tint_magenta, tint_yellow }; - -# ifdef USE_IMLIB -void render_pixmap(Window win, imlib_t image, pixmap_t pmap, - int which, renderop_t renderop); -# endif -# endif - -# ifdef USE_POSIX_THREADS -void init_bg_pixmap_thread(void *file); -# endif -void set_bgPixmap(const char *file); -void set_Pixmap(const char *file, Pixmap dest_pmap, int type); -int scale_pixmap(const char *geom, pixmap_t *pmap); -# ifdef USE_IMLIB -void colormod_pixmap(imlib_t, GC, int, int); -# endif - -# ifdef PIXMAP_OFFSET -# ifdef IMLIB_TRANS -void colormod_trans(imlib_t, GC, int, int); -# else -void colormod_trans(Pixmap, GC, int, int); -# endif -Window get_desktop_window(void); -Pixmap get_desktop_pixmap(void); +/************ Variables ************/ +extern image_t images[image_max]; +extern ImlibData *imlib_id; +extern Pixmap desktop_pixmap, viewport_pixmap; extern Window desktop_window; -# endif + +/************ Function Prototypes ************/ +_XFUNCPROTOBEGIN + +extern unsigned short parse_pixmap_ops(char *); +extern unsigned short set_pixmap_scale(const char *, pixmap_t *); +extern void reset_simage(simage_t *, unsigned long); +extern void paste_simage(simage_t *, Window, unsigned short, unsigned short, unsigned short, unsigned short); +extern void render_simage(simage_t *, Window, unsigned short, unsigned short, int, renderop_t); +#ifdef USE_POSIX_THREADS +extern void init_bg_pixmap_thread(void *); +#endif +extern const char *search_path(const char *, const char *, const char *); +extern unsigned short load_image(const char *, short); +extern void free_desktop_pixmap(void); +#ifdef PIXMAP_OFFSET +extern unsigned char need_colormod(void); +extern void colormod_trans(Pixmap, GC, unsigned short, unsigned short); +extern Window get_desktop_window(void); +extern Pixmap get_desktop_pixmap(void); +#endif extern void shaped_window_apply_mask(Window, Pixmap); extern void set_icon_pixmap(char *, XWMHints *); -# ifdef USE_IMLIB -extern ImlibImage *ReadImageViaImlib(Display *, const char *); -# endif +#ifdef USE_EFFECTS +extern int fade_in(ImlibImage *, int); +extern int fade_out(ImlibImage *, int); +#endif + +_XFUNCPROTOEND #endif /* _PIXMAP_H */ diff --git a/src/profile.h b/src/profile.h index 816a891..a2519e8 100644 --- a/src/profile.h +++ b/src/profile.h @@ -6,7 +6,6 @@ # define _PROFILE_H /* included for a possible #define PROFILE */ -/* # include "feature.h" */ # include # include # include diff --git a/src/screen.c b/src/screen.c index 0f1b49d..156a36a 100644 --- a/src/screen.c +++ b/src/screen.c @@ -5,20 +5,13 @@ static const char cvs_ident[] = "$Id$"; -/* includes */ -#include "main.h" -#ifdef USE_ACTIVE_TAGS -# include "activetags.h" -# include "activeeterm.h" -#endif -#ifdef USE_POSIX_THREADS -# include "threads.h" -#endif +#include "config.h" +#include "feature.h" +/* includes */ #ifdef HAVE_SYS_TIME_H # include #endif - #include #ifdef HAVE_UNISTD_H # include @@ -29,108 +22,39 @@ static const char cvs_ident[] = "$Id$"; #include #include /* CARD32 */ +#include "../libmej/debug.h" #include "command.h" #include "debug.h" +#include "main.h" #include "mem.h" #include "graphics.h" #include "screen.h" #include "options.h" - -#include -#include /* get the typedef for CARD32 */ - -#if defined(PIXMAP_SUPPORT) && defined(USE_IMLIB) -# include "eterm_imlib.h" -extern ImlibData *imlib_id; - -#endif #ifdef PIXMAP_SUPPORT # include "pixmap.h" #endif #ifdef PROFILE_SCREEN # include "profile.h" #endif - -/* ------------------------------------------------------------------------- */ - -#define WRAP_CHAR (MAX_COLS + 1) -#define PROP_SIZE 4096 -#define TABSIZE 8 /* default tab size */ - -/* ------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------------- * - * GENERAL SCREEN AND SELECTION UPDATE ROUTINES * - * ------------------------------------------------------------------------- */ - -#define ZERO_SCROLLBACK do { \ - D_SCREEN(("ZERO_SCROLLBACK()\n")); \ - if (Options & Opt_homeOnEcho) TermWin.view_start = 0; \ - } while (0) -#define REFRESH_ZERO_SCROLLBACK do { \ - D_SCREEN(("REFRESH_ZERO_SCROLLBACK()\n")); \ - if (Options & Opt_homeOnRefresh) TermWin.view_start = 0; \ - } while (0) -#define CHECK_SELECTION do { \ - if (selection.op) selection_check(); \ - } while (0) - -/* - * CLEAR_ROWS : clear rows starting from row - * CLEAR_CHARS: clear chars starting from pixel position - * ERASE_ROWS : set rows starting from row to the foreground colour - */ -#define drawBuffer (TermWin.vt) -#define CLEAR_ROWS(row, num) do { \ - XClearArea(Xdisplay, drawBuffer, Col2Pixel(0), Row2Pixel(row), \ - TermWin.width, Height2Pixel(num), 0); \ - } while (0) -#define CLEAR_CHARS(x, y, num) do { \ - D_SCREEN(("CLEAR_CHARS(%d, %d, %d)\n", x, y, num)); \ - XClearArea(Xdisplay, drawBuffer, x, y, Width2Pixel(num), Height2Pixel(1), 0); \ - } while (0) -#define FAST_CLEAR_CHARS(x, y, num) do { \ - clear_area(Xdisplay, drawBuffer, x, y, Width2Pixel(num), Height2Pixel(1), 0); \ - } while (0) -#define ERASE_ROWS(row, num) do { \ - XFillRectangle(Xdisplay, drawBuffer, TermWin.gc, Col2Pixel(0), Row2Pixel(row), \ - TermWin.width, Height2Pixel(num)); \ - } while (0) - -/* ------------------------------------------------------------------------- * - * MODULE VARIABLES * - * ------------------------------------------------------------------------- */ +#include "term.h" +#ifdef USE_POSIX_THREADS +# include "threads.h" +#endif /* This tells what's actually on the screen */ -#ifdef USE_ACTIVE_TAGS -text_t **drawn_text = NULL; -rend_t **drawn_rend = NULL; -extern void tag_scroll(int nlines, int row1, int row2); - -#else static text_t **drawn_text = NULL; static rend_t **drawn_rend = NULL; -#endif - static text_t **buf_text = NULL; static rend_t **buf_rend = NULL; static char *tabs = NULL; /* a 1 for a location with a tab-stop */ -#ifdef USE_ACTIVE_TAGS -screen_t screen = -{ - NULL, NULL, 0, 0, 0, 0, 0, Screen_DefaultFlags -}; - -#else static screen_t screen = { NULL, NULL, 0, 0, 0, 0, 0, Screen_DefaultFlags }; -#endif static screen_t swap = { NULL, NULL, 0, 0, 0, 0, 0, Screen_DefaultFlags @@ -159,10 +83,10 @@ static rend_t rstyle = DEFAULT_RSTYLE; static short rvideo = 0; /* reverse video */ int prev_nrow = -1, prev_ncol = -1; /* moved from scr_reset() to squash seg fault in scroll_text() */ -#ifdef KANJI +#ifdef MULTI_CHARSET static short multi_byte = 0; static enum { - EUCJ, SJIS + EUCJ, EUCKR = EUCJ, GB = EUCJ, SJIS, BIG5 } encoding_method = EUCJ; static enum { SBYTE, WBYTE @@ -185,7 +109,7 @@ blank_line(text_t * et, rend_t * er, int width, rend_t efs) register int i = width; rend_t *r = er, fs = efs; - memset(et, ' ', i); + MEMSET(et, ' ', i); for (; i--;) *r++ = fs; } @@ -404,6 +328,9 @@ scr_reset(void) + + + tabs = MALLOC(TermWin.ncol * sizeof(char)); for (i = 0; i < TermWin.ncol; i++) @@ -462,7 +389,7 @@ scr_poweron(void) last_col = TermWin.ncol - 1; - memset(charsets, 'B', sizeof(charsets)); + MEMSET(charsets, 'B', sizeof(charsets)); rvideo = 0; scr_rendition(0, ~RS_None); #if NSCREENS @@ -580,7 +507,7 @@ scr_change_screen(int scrn) /* ------------------------------------------------------------------------- */ /* - * Change the colour for following text + * Change the color for following text */ void scr_color(unsigned int color, unsigned int Intensity) @@ -592,7 +519,7 @@ scr_color(unsigned int color, unsigned int Intensity) else if (color == restoreBG) color = bgColor; else { - if (Xdepth <= 2) { /* Monochrome - ignore colour changes */ + if (Xdepth <= 2) { /* Monochrome - ignore color changes */ switch (Intensity) { case RS_Bold: color = fgColor; @@ -659,7 +586,7 @@ scr_rendition(int set, int style) rstyle &= ~style; switch (style) { - case ~RS_None: /* default fg/bg colours */ + case ~RS_None: /* default fg/bg colors */ rstyle = DEFAULT_RSTYLE; /* FALLTHROUGH */ case RS_RVid: @@ -713,10 +640,6 @@ scroll_text(int row1, int row2, int count, int spec) if (count == 0 || (row1 > row2)) return 0; -#ifdef USE_ACTIVE_TAGS - tag_hide(); -#endif - if (selection.op) { /* move selected region too */ selection.beg.row -= count; selection.end.row -= count; @@ -789,9 +712,6 @@ scroll_text(int row1, int row2, int count, int spec) count = -count; } GR_DISPLAY(Gr_scroll(count)); -#ifdef USE_ACTIVE_TAGS - tag_scroll(count, row1, row2); -#endif #ifdef PROFILE_SCREEN P_SETTIMEVAL(cnt.stop); total_time += P_CMPTIMEVALS_USEC(cnt.start, cnt.stop); @@ -851,14 +771,13 @@ scr_add_lines(const unsigned char *str, int nlines, int len) row = screen.row + TermWin.saveLines; if (screen.text[row] == NULL) { make_screen_mem(screen.text, screen.rend, row); - } /* avoid segfault -- added by Sebastien van K */ - + } /* avoid segfault -- added by Sebastien van K */ beg.row = screen.row; beg.col = screen.col; stp = screen.text[row]; srp = screen.rend[row]; -#ifdef KANJI +#ifdef MULTI_CHARSET if (lost_multi && screen.col > 0 && ((srp[screen.col - 1] & RS_multiMask) == RS_multi1) && *str != '\n' && *str != '\r' && *str != '\t') @@ -867,7 +786,7 @@ scr_add_lines(const unsigned char *str, int nlines, int len) for (i = 0; i < len;) { c = str[i++]; -#ifdef KANJI +#ifdef MULTI_CHARSET if (chstat == WBYTE) { rstyle |= RS_multiMask; /* multibyte 2nd byte */ chstat = SBYTE; @@ -912,7 +831,7 @@ scr_add_lines(const unsigned char *str, int nlines, int len) screen.col = 0; continue; default: -#ifdef KANJI +#ifdef MULTI_CHARSET rstyle &= ~RS_multiMask; #endif break; @@ -1338,7 +1257,7 @@ scr_insdel_chars(int count, int insdel) screen.text[row][TermWin.ncol] = 0; break; } -#ifdef KANJI +#ifdef MULTI_CHARSET if ((screen.rend[row][0] & RS_multiMask) == RS_multi2) { screen.rend[row][0] &= ~RS_multiMask; screen.text[row][0] = ' '; @@ -1443,7 +1362,7 @@ void scr_set_tab(int mode) { if (mode < 0) - memset(tabs, 0, TermWin.ncol * sizeof(char)); + MEMSET(tabs, 0, TermWin.ncol); else if (screen.col < TermWin.ncol) tabs[screen.col] = (mode ? 1 : 0); @@ -1541,7 +1460,7 @@ scr_charset_choose(int set) void scr_charset_set(int set, unsigned int ch) { -#ifdef KANJI +#ifdef MULTI_CHARSET multi_byte = (set < 0); set = abs(set); #endif @@ -1550,29 +1469,28 @@ scr_charset_set(int set, unsigned int ch) } /* ------------------------------------------------------------------------- * - * JAPANESE CHARACTER SET MANIPULATION FUNCTIONS * + * MULTIPLE-CHARACTER SET MANIPULATION FUNCTIONS * * ------------------------------------------------------------------------- */ -#ifdef KANJI -static void (*kanji_decode) (unsigned char *str, int len) = eucj2jis; +#ifdef MULTI_CHARSET -#endif +static void eucj2jis(unsigned char *str, int len); +static void sjis2jis(unsigned char *str, int len); +static void big5dummy(unsigned char *str, int len); -void +static void (*multichar_decode) (unsigned char *str, int len) = eucj2jis; + +static void eucj2jis(unsigned char *str, int len) { -#ifdef KANJI register int i; for (i = 0; i < len; i++) str[i] &= 0x7F; -#endif } -/* ------------------------------------------------------------------------- */ -void +static void sjis2jis(unsigned char *str, int len) { -#ifdef KANJI register int i; unsigned char *high, *low; @@ -1590,28 +1508,39 @@ sjis2jis(unsigned char *str, int len) *low -= 0x1F; } } -#endif } +static void +big5dummy(unsigned char *str, int len) +{ + str = NULL; + len = 0; +} +#endif + /* ------------------------------------------------------------------------- */ void -set_kanji_encoding(const char *str) +set_multichar_encoding(const char *str) { -#ifdef KANJI +#ifdef MULTI_CHARSET if (str && *str) { if (!strcmp(str, "sjis")) { encoding_method = SJIS; - kanji_decode = sjis2jis; - } else if (!strcmp(str, "eucj")) { + multichar_decode = sjis2jis; + } else if (!strcmp(str, "eucj") || !strcmp(str, "euckr") + || !strcmp(str, "gb")) { encoding_method = EUCJ; - kanji_decode = eucj2jis; + multichar_decode = eucj2jis; + } else if (!strcmp(str, "big5")) { + encoding_method = BIG5; + multichar_decode = big5dummy; } } -#endif /* KANJI */ +#endif /* MULTI_CHARSET */ } /* ------------------------------------------------------------------------- * - * GRAPHICS COLOURS * + * GRAPHICS COLORS * * ------------------------------------------------------------------------- */ #ifdef RXVT_GRAPHICS @@ -1686,20 +1615,6 @@ scr_expose(int x, int y, int width, int height) &(drawn_rend[i][full_beg.col]), full_end.col - full_beg.col + 1, DEFAULT_RSTYLE); -/* FIXME: If PIXMAP_BUFFERING will be implemented, I'll have to do something - * here ;) -vendu - */ - -#if defined(PIXMAP_SUPPORT) && defined(PIXMAP_BUFFERING) -/* supposedly we're exposed - so `clear' the fully exposed clear areas */ - x = Col2Pixel(full_beg.col); - y = Row2Pixel(full_beg.row); - width = Width2Pixel(full_end.col - full_beg.col + 1); - height = Height2Pixel(full_end.row - full_beg.row + 1); - XCopyArea(Xdisplay, TermWin.pixmap, drawBuffer, TermWin.gc, - x, y, width, height, x, y); -#endif - /* force an update for partially exposed characters */ if (part_beg.row != full_beg.row) { r = &(drawn_rend[part_beg.row][part_beg.col]); @@ -1723,7 +1638,11 @@ scr_expose(int x, int y, int width, int height) /* * Refresh the entire screen */ +#ifdef __GNUC__ inline void +#else +void +#endif scr_touch(void) { scr_expose(0, 0, TermWin.width, TermWin.height); @@ -1760,17 +1679,8 @@ scr_page(int direction, int nlines) { int start, dirn; -#ifdef USE_ACTIVE_TAGS - int retval; - -#endif - D_SCREEN(("scr_page(%s, %d) view_start:%d\n", ((direction == UP) ? "UP" : "DN"), nlines, TermWin.view_start)); -#ifdef USE_ACTIVE_TAGS - tag_hide(); -#endif - dirn = (direction == UP) ? 1 : -1; start = TermWin.view_start; MAX_IT(nlines, 1); @@ -1780,15 +1690,7 @@ scr_page(int direction, int nlines) MIN_IT(TermWin.view_start, TermWin.nscrolled); GR_DISPLAY(Gr_scroll(0)); -#ifdef USE_ACTIVE_TAGS - tag_scroll((retval = TermWin.view_start - start), - tag_min_row(), tag_max_row()); -#endif -#ifdef USE_ACTIVE_TAGS - return retval; -#else return (TermWin.view_start - start); -#endif } /* ------------------------------------------------------------------------- */ @@ -1815,7 +1717,6 @@ scr_printscreen(int fullhist) #ifdef PRINTPIPE int i, r, nrows, row_offset; text_t *t; - char title[256]; FILE *fd; if ((fd = popen_printer()) == NULL) @@ -1956,12 +1857,13 @@ scr_refresh(int type) col = screen.col; if (screen.flags & Screen_VisibleCursor) { screen.rend[row][col] |= RS_Cursor; -#ifdef KANJI - if ((col < ncols - 1) && ((screen.rend[row][col] & RS_multiMask) == RS_multi1) - && ((screen.rend[row][col + 1] & RS_multiMask) == RS_multi2)) { +#ifdef MULTI_CHARSET + srp = &screen.rend[row][col]; + if ((col < ncols - 1) && ((srp[0] & RS_multiMask) == RS_multi1) + && ((srp[1] & RS_multiMask) == RS_multi2)) { screen.rend[row][col + 1] |= RS_Cursor; - } else if ((col > 0) && ((screen.rend[row][col] & RS_multiMask) == RS_multi2) - && ((screen.rend[row][col - 1] & RS_multiMask) == RS_multi1)) { + } else if ((col > 0) && ((srp[0] & RS_multiMask) == RS_multi2) + && ((srp[-1] & RS_multiMask) == RS_multi1)) { screen.rend[row][col - 1] |= RS_Cursor; } #endif @@ -1969,10 +1871,10 @@ scr_refresh(int type) focus = TermWin.focus; if ((i = screen.row - TermWin.view_start) >= 0) { drawn_rend[i][col] = RS_attrMask; -#ifdef KANJI - if ((col < ncols - 1) && ((screen.rend[row][col + 1] & RS_multiMask) == RS_multi2)) { +#ifdef MULTI_CHARSET + if ((col < ncols - 1) && ((srp[1] & RS_multiMask) == RS_multi2)) { drawn_rend[i][col + 1] = RS_attrMask; - } else if ((col > 0) && ((screen.rend[row][col - 1] & RS_multiMask) == RS_multi1)) { + } else if ((col > 0) && ((srp[-1] & RS_multiMask) == RS_multi1)) { drawn_rend[i][col - 1] = RS_attrMask; } #endif @@ -1995,12 +1897,12 @@ scr_refresh(int type) rt1 = srp[col]; /* screen rendition */ rt2 = drp[col]; /* drawn rendition */ if ((stp[col] == dtp[col]) /* must match characters to skip */ - &&((rt1 == rt2) /* either rendition the same or */ - ||((stp[col] == ' ') /* space w/ no bg change */ - &&(GET_BGATTR(rt1) == GET_BGATTR(rt2)) - && !(rt2 & RS_Dirty)))) -#ifdef KANJI - /* if first byte is Kanji then compare second bytes */ + && ((rt1 == rt2) /* either rendition the same or */ + || ((stp[col] == ' ') /* space w/ no bg change */ + &&(GET_BGATTR(rt1) == GET_BGATTR(rt2)) + && !(rt2 & RS_Dirty)))) { +#ifdef MULTI_CHARSET + /* if first byte is multibyte then compare second bytes */ if ((rt1 & RS_multiMask) != RS_multi1) continue; else if (stp[col + 1] == dtp[col + 1]) { @@ -2011,6 +1913,7 @@ scr_refresh(int type) #else continue; #endif + } lasttext = dtp[col]; lastrend = drp[col]; /* redraw one or more characters */ @@ -2027,16 +1930,16 @@ scr_refresh(int type) * Find out the longest string we can write out at once */ if (fprop == 0) { /* Fixed width font */ -#ifdef KANJI +#ifdef MULTI_CHARSET if (((rend & RS_multiMask) == RS_multi1) && (col < ncols - 1) && ((srp[col + 1]) & RS_multiMask) == RS_multi2) { if (!wbyte) { wbyte = 1; - XSetFont(Xdisplay, TermWin.gc, TermWin.kanji->fid); + XSetFont(Xdisplay, TermWin.gc, TermWin.mfont->fid); draw_string = XDrawString16; draw_image_string = XDrawImageString16; } - /* double stepping - we're in Kanji mode */ + /* double stepping - we're in Multibyte mode */ for (; ++col < ncols;) { /* XXX: could check sanity on 2nd byte */ dtp[col] = stp[col]; @@ -2052,13 +1955,12 @@ scr_refresh(int type) if (len == MAX_COLS) break; dtp[col] = stp[col]; -/* lastchar = drp[col]; */ drp[col] = srp[col]; buffer[len++] = stp[col]; - } /* for (; ++col < TermWin.ncol;) */ + } col--; if (buffer[0] & 0x80) - kanji_decode(buffer, len); + multichar_decode(buffer, len); wlen = len / 2; } else { if ((rend & RS_multiMask) == RS_multi1) { @@ -2092,7 +1994,7 @@ scr_refresh(int type) } /* for (; ++col < TermWin.ncol - 1;) */ col--; wlen = len; -#ifdef KANJI +#ifdef MULTI_CHARSET } #endif } @@ -2249,7 +2151,7 @@ scr_refresh(int type) xpixel, ypixel - TermWin.font->ascent, Width2Pixel(1 + wbyte) - 1, Height2Pixel(1) - 1); } - if (gcmask) { /* restore normal colours */ + if (gcmask) { /* restore normal colors */ gcvalue.foreground = PixColors[fgColor]; gcvalue.background = PixColors[bgColor]; XChangeGC(Xdisplay, TermWin.gc, gcmask, &gcvalue); @@ -2269,7 +2171,7 @@ scr_refresh(int type) col = screen.col; if (screen.flags & Screen_VisibleCursor) { screen.rend[row][col] &= ~RS_Cursor; -#ifdef KANJI +#ifdef MULTI_CHARSET /* very low overhead so don't check properly, just wipe it all out */ if (screen.col < ncols - 1) screen.rend[row][col + 1] &= ~RS_Cursor; @@ -2626,7 +2528,7 @@ selection_make(Time tm) col = 0; if (screen.text[row][TermWin.ncol] != WRAP_CHAR) { if (!(Options & Opt_select_trailing_spaces)) { - for (; isspace(*--str);); + for (str--; *str == ' ' || *str == '\t'; str--); str++; } *str++ = '\n'; @@ -2645,6 +2547,10 @@ selection_make(Time tm) MIN_IT(end_col, TermWin.ncol); for (; col < end_col; col++) *str++ = *t++; + if (!(Options & Opt_select_trailing_spaces)) { + for (str--; *str == ' ' || *str == '\t'; str--); + str++; + } if (i) *str++ = '\n'; *str = '\0'; @@ -2704,7 +2610,7 @@ selection_click(int clicks, int x, int y) #else # define DELIMIT_TEXT(x) (strchr(CUTCHARS, (x)) != NULL) #endif -#ifdef KANJI +#ifdef MULTI_CHARSET #define DELIMIT_REND(x) (((x) & RS_multiMask) ? 1 : 0) #endif @@ -2715,7 +2621,7 @@ selection_delimit_word(int col, int row, row_col_t * beg, row_col_t * end) int row_offset, w1; text_t *stp, *stp1, t; -#ifdef KANJI +#ifdef MULTI_CHARSET int w2; rend_t *srp, r; @@ -2758,7 +2664,7 @@ selection_delimit_word(int col, int row, row_col_t * beg, row_col_t * end) w1 = DELIMIT_TEXT(*stp); if (w1 == 2) w1 = 0; -#ifdef KANJI +#ifdef MULTI_CHARSET srp = &(screen.rend[beg_row + row_offset][beg_col]); w2 = DELIMIT_REND(*srp); #endif @@ -2768,7 +2674,7 @@ selection_delimit_word(int col, int row, row_col_t * beg, row_col_t * end) t = *--stp; if (DELIMIT_TEXT(t) != w1 || (w1 && *stp1 != t && Options & Opt_xterm_select)) break; -#ifdef KANJI +#ifdef MULTI_CHARSET r = *--srp; if (DELIMIT_REND(r) != w2) break; @@ -2778,14 +2684,14 @@ selection_delimit_word(int col, int row, row_col_t * beg, row_col_t * end) if (beg_col == col && beg_col > 0) { if (DELIMIT_TEXT(*stp)) /* space or tab or cutchar */ break; -#ifdef KANJI +#ifdef MULTI_CHARSET srp = &(screen.rend[beg_row + row_offset][beg_col - 1]); #endif for (; --beg_col > 0;) { t = *--stp; if (DELIMIT_TEXT(t)) break; -#ifdef KANJI +#ifdef MULTI_CHARSET r = *--srp; if (DELIMIT_REND(r) != w2) break; @@ -2797,7 +2703,7 @@ selection_delimit_word(int col, int row, row_col_t * beg, row_col_t * end) stp = &(screen.text[beg_row + row_offset - 1][last_col + 1]); if (*stp == WRAP_CHAR) { t = *(stp - 1); -#ifdef KANJI +#ifdef MULTI_CHARSET srp = &(screen.rend[beg_row + row_offset - 1][last_col + 1]); r = *(srp - 1); if (DELIMIT_TEXT(t) == w1 && (!w1 || *stp == t || !(Options & Opt_xterm_select)) && DELIMIT_REND(r) == w2) { @@ -2823,7 +2729,7 @@ selection_delimit_word(int col, int row, row_col_t * beg, row_col_t * end) stp1 = stp = &(screen.text[end_row + row_offset][end_col]); # endif -#ifdef KANJI +#ifdef MULTI_CHARSET srp = &(screen.rend[end_row + row_offset][end_col]); #endif for (;;) { @@ -2831,7 +2737,7 @@ selection_delimit_word(int col, int row, row_col_t * beg, row_col_t * end) t = *++stp; if (DELIMIT_TEXT(t) != w1 || (w1 && *stp1 != t && Options & Opt_xterm_select)) break; -#ifdef KANJI +#ifdef MULTI_CHARSET r = *++srp; if (DELIMIT_REND(r) != w2) break; @@ -2841,14 +2747,14 @@ selection_delimit_word(int col, int row, row_col_t * beg, row_col_t * end) if (end_col == col && end_col < last_col) { if (DELIMIT_TEXT(*stp)) /* space or tab or cutchar */ break; -#ifdef KANJI +#ifdef MULTI_CHARSET srp = &(screen.rend[end_row + row_offset][end_col + 1]); #endif for (; ++end_col < last_col;) { t = *++stp; if (DELIMIT_TEXT(t)) break; -#ifdef KANJI +#ifdef MULTI_CHARSET r = *++srp; if (DELIMIT_REND(r) != w2) break; @@ -2860,7 +2766,7 @@ selection_delimit_word(int col, int row, row_col_t * beg, row_col_t * end) && (end_row < (TermWin.nrow - 1))) { if (*++stp == WRAP_CHAR) { stp = screen.text[end_row + row_offset + 1]; -#ifdef KANJI +#ifdef MULTI_CHARSET srp = screen.rend[end_row + row_offset + 1]; if (DELIMIT_TEXT(*stp) == w1 && (!w1 || *stp1 == *stp || !(Options & Opt_xterm_select)) && DELIMIT_REND(*srp) == w2) { #else @@ -2934,7 +2840,7 @@ selection_extend_colrow(int col, int row, int flag, int cont) LEFT, RIGHT } closeto = RIGHT; -#ifdef KANJI +#ifdef MULTI_CHARSET int r; #endif @@ -3048,7 +2954,7 @@ selection_extend_colrow(int col, int row, int flag, int cont) selection.end.col = TermWin.ncol - 1; } } -#ifdef KANJI +#ifdef MULTI_CHARSET if (selection.beg.col > 0) { r = selection.beg.row + TermWin.saveLines; if (((screen.rend[r][selection.beg.col] & RS_multiMask) == RS_multi2) @@ -3292,3 +3198,12 @@ debug_colors(void) #endif fprintf(stderr, "%s\n", name[color]); } + +#ifdef USE_XIM +void xim_get_position(XPoint *pos) +{ + pos->x = Col2Pixel(screen.col); + pos->y = Height2Pixel(screen.row) + TermWin.font->ascent + + TermWin.internalBorder; +} +#endif diff --git a/src/screen.h b/src/screen.h index d93fe49..bef0128 100644 --- a/src/screen.h +++ b/src/screen.h @@ -12,11 +12,49 @@ *----------------------------------------------------------------------*/ #ifndef _SCREEN_H #define _SCREEN_H -/* includes */ + #include #include "main.h" -/* defines */ +/************ Macros and Definitions ************/ +#define WRAP_CHAR (MAX_COLS + 1) +#define PROP_SIZE 4096 +#define TABSIZE 8 /* default tab size */ + +#define ZERO_SCROLLBACK do { \ + D_SCREEN(("ZERO_SCROLLBACK()\n")); \ + if (Options & Opt_homeOnEcho) TermWin.view_start = 0; \ + } while (0) +#define REFRESH_ZERO_SCROLLBACK do { \ + D_SCREEN(("REFRESH_ZERO_SCROLLBACK()\n")); \ + if (Options & Opt_homeOnRefresh) TermWin.view_start = 0; \ + } while (0) +#define CHECK_SELECTION do { \ + if (selection.op) selection_check(); \ + } while (0) + +/* + * CLEAR_ROWS : clear rows starting from row + * CLEAR_CHARS: clear chars starting from pixel position + * ERASE_ROWS : set rows starting from row to the foreground color + */ +#define drawBuffer (TermWin.vt) +#define CLEAR_ROWS(row, num) do { \ + XClearArea(Xdisplay, drawBuffer, Col2Pixel(0), Row2Pixel(row), \ + TermWin.width, Height2Pixel(num), 0); \ + } while (0) +#define CLEAR_CHARS(x, y, num) do { \ + D_SCREEN(("CLEAR_CHARS(%d, %d, %d)\n", x, y, num)); \ + XClearArea(Xdisplay, drawBuffer, x, y, Width2Pixel(num), Height2Pixel(1), 0); \ + } while (0) +#define FAST_CLEAR_CHARS(x, y, num) do { \ + clear_area(Xdisplay, drawBuffer, x, y, Width2Pixel(num), Height2Pixel(1), 0); \ + } while (0) +#define ERASE_ROWS(row, num) do { \ + XFillRectangle(Xdisplay, drawBuffer, TermWin.gc, Col2Pixel(0), Row2Pixel(row), \ + TermWin.width, Height2Pixel(num)); \ + } while (0) + /* Screen refresh methods */ #define NO_REFRESH 0 /* Window not visible at all! */ #define FAST_REFRESH (1<<1) /* Fully exposed window */ @@ -28,7 +66,6 @@ #define RESTORE 'r' #define REVERT IGNORE #define INVOKE RESTORE -extern void privileges(int); /* flags for scr_gotorc() */ #define C_RELATIVE 1 /* col movement is relative */ @@ -61,7 +98,7 @@ enum { #define RS_acsFont 0x10000000u /* ACS graphics character set */ #define RS_ukFont 0x20000000u /* UK character set */ #define RS_fontMask (RS_acsFont|RS_ukFont) -#ifdef KANJI +#ifdef MULTI_CHARSET #define RS_multi0 0x40000000u /* only multibyte characters */ #define RS_multi1 0x80000000u /* multibyte 1st byte */ #define RS_multi2 (RS_multi0|RS_multi1) /* multibyte 2nd byte */ @@ -75,7 +112,6 @@ enum { #define RS_attrMask (0xFF000000u|RS_Bold|RS_Blink) -/* macros */ /* how to build & extract colors and attributes */ #define GET_FGCOLOR(r) (((r) & RS_fgMask)>>8) #define GET_BGCOLOR(r) (((r) & RS_bgMask)>>16) @@ -87,18 +123,6 @@ enum { #define SET_ATTR(r,a) (((r) & ~RS_attrMask)| (a)) #define DEFAULT_RSTYLE (RS_None | (fgColor<<8) | (bgColor<<16)) -/* extern variables */ -#ifndef NO_BRIGHTCOLOR -extern unsigned int colorfgbg; -#endif - -/* types */ -typedef unsigned char text_t; -typedef unsigned int rend_t; -typedef struct { - int row, col; -} row_col_t; - /* screen_t flags */ #define Screen_Relative (1<<0) /* relative origin mode flag */ #define Screen_VisibleCursor (1<<1) /* cursor visible? */ @@ -107,6 +131,12 @@ typedef struct { #define Screen_WrapNext (1<<4) /* need to wrap for next char? */ #define Screen_DefaultFlags (Screen_VisibleCursor|Screen_Autowrap) +/************ Structures ************/ +typedef unsigned char text_t; +typedef unsigned int rend_t; +typedef struct { + int row, col; +} row_col_t; /* * screen accounting: * screen_t elements @@ -114,7 +144,7 @@ typedef struct { * buffer. Each line is length (TermWin.ncol + 1) * The final character is either the _length_ of the line or * for wrapped lines: (MAX_COLS + 1) - * rend: Contains rendition information: font, bold, colour, etc. + * rend: Contains rendition information: font, bold, color, etc. * * Note: Each line for both text and rend are only allocated on demand, and * text[x] is allocated <=> rend[x] is allocated for all x. * row: Cursor row position : 0 <= row < TermWin.nrow @@ -147,7 +177,6 @@ typedef struct { * Rows [TermWin.saveLines] ... [TermWin.saveLines + TermWin.nrow - 1] * normal `unscrolled' screen region */ - typedef struct { text_t **text; /* _all_ the text */ rend_t **rend; /* rendition, uses RS_ flags */ @@ -158,7 +187,6 @@ typedef struct { short charset; /* character set number [0..3] */ unsigned int flags; } screen_t; - typedef struct { short row, /* cursor row */ col, /* cursor column */ @@ -166,7 +194,6 @@ typedef struct { char charset_char; rend_t rstyle; /* rendition style */ } save_t; - typedef struct { unsigned char *text; /* selected text */ int len; /* length of selected text */ @@ -175,87 +202,86 @@ typedef struct { SELECTION_INIT, /* marked a point */ SELECTION_BEGIN, /* started a selection */ SELECTION_CONT, /* continued selection */ - SELECTION_DONE, /* selection put in CUT_BUFFER0 */ + SELECTION_DONE /* selection put in CUT_BUFFER0 */ } op; /* current operation */ short screen; /* screen being used */ short clicks; /* number of clicks */ row_col_t beg, mark, end; } selection_t; -#ifdef USE_ACTIVE_TAGS -extern screen_t screen; +/************ Variables ************/ +#ifndef NO_BRIGHTCOLOR +extern unsigned int colorfgbg; #endif -/* prototypes: */ +/************ Function Prototypes ************/ _XFUNCPROTOBEGIN -void blank_dline(text_t * et, rend_t * er, int width, rend_t efs); -void blank_sline(text_t * et, rend_t * er, int width); -void make_screen_mem(text_t ** tp, rend_t ** rp, int row); -void scr_reset(void); -void scr_release(void); -void scr_poweron(void); -void scr_cursor(int mode); -int scr_change_screen(int scrn); -void scr_color(unsigned int color, unsigned int Intensity); -void scr_rendition(int set, int style); -int scroll_text(int row1, int row2, int count, int spec); -void scr_add_lines(const unsigned char *str, int nlines, int len); -void scr_backspace(void); -void scr_tab(int count); -void scr_gotorc(int row, int col, int relative); -void scr_index(int direction); -void scr_erase_line(int mode); -void scr_erase_screen(int mode); -void scr_E(void); -void scr_insdel_lines(int count, int insdel); -void scr_insdel_chars(int count, int insdel); -void scr_scroll_region(int top, int bot); -void scr_cursor_visible(int mode); -void scr_autowrap(int mode); -void scr_relative_origin(int mode); -void scr_insert_mode(int mode); -void scr_set_tab(int mode); -void scr_rvideo_mode(int mode); -void scr_report_position(void); -void set_font_style(void); -void scr_charset_choose(int set); -void scr_charset_set(int set, unsigned int ch); -void eucj2jis(unsigned char *str, int len); -void sjis2jis(unsigned char *str, int len); -void set_kanji_encoding(const char *str); -int scr_get_fgcolor(void); -int scr_get_bgcolor(void); -void scr_expose(int x, int y, int width, int height); -void scr_touch(void); -int scr_move_to(int y, int len); -int scr_page(int direction, int nlines); -void scr_bell(void); -void scr_printscreen(int fullhist); -void scr_refresh(int type); -void selection_check(void); -void PasteIt(unsigned char *data, unsigned int nitems); -void selection_paste(Window win, unsigned prop, int Delete); -void selection_request(Time tm, int x, int y); -void selection_reset(void); -void selection_clear(void); -void selection_setclr(int set, int startr, int startc, int endr, int endc); -void selection_start(int x, int y); -void selection_start_colrow(int col, int row); -void selection_make(Time tm); -void selection_click(int clicks, int x, int y); -void selection_delimit_word(int col, int row, row_col_t * beg, row_col_t * end); -void selection_extend(int x, int y, int flag); -void selection_extend_colrow(int col, int row, int flag, int cont); -void selection_rotate(int x, int y); -void selection_send(XSelectionRequestEvent * rq); -void mouse_report(XButtonEvent * ev); -void mouse_tracking(int report, int x, int y, int firstrow, int lastrow); -void debug_PasteIt(unsigned char *data, int nitems); -int debug_selection(void); -void debug_colors(void); +extern void blank_line(text_t *, rend_t *, int, rend_t); +extern void blank_dline(text_t *, rend_t *, int, rend_t); +extern void blank_sline(text_t *, rend_t *, int); +extern void make_screen_mem(text_t **, rend_t **, int); +extern void scr_reset(void); +extern void scr_release(void); +extern void scr_poweron(void); +extern void scr_cursor(int); +extern int scr_change_screen(int); +extern void scr_color(unsigned int, unsigned int); +extern void scr_rendition(int, int); +extern int scroll_text(int, int, int, int); +extern void scr_add_lines(const unsigned char *, int, int); +extern void scr_backspace(void); +extern void scr_tab(int); +extern void scr_gotorc(int, int, int); +extern void scr_index(int); +extern void scr_erase_line(int); +extern void scr_erase_screen(int); +extern void scr_E(void); +extern void scr_insdel_lines(int, int); +extern void scr_insdel_chars(int, int); +extern void scr_scroll_region(int, int); +extern void scr_cursor_visible(int); +extern void scr_autowrap(int); +extern void scr_relative_origin(int); +extern void scr_insert_mode(int); +extern void scr_set_tab(int); +extern void scr_rvideo_mode(int); +extern void scr_report_position(void); +extern void set_font_style(void); +extern void scr_charset_choose(int); +extern void scr_charset_set(int, unsigned int); +extern void set_multichar_encoding(const char *); +extern int scr_get_fgcolor(void); +extern int scr_get_bgcolor(void); +extern void scr_expose(int, int, int, int); +extern void scr_touch(void); +extern int scr_move_to(int, int); +extern int scr_page(int, int); +extern void scr_bell(void); +extern void scr_printscreen(int); +extern void scr_refresh(int); +extern void selection_check(void); +extern void PasteIt(unsigned char *, unsigned int); +extern void selection_paste(Window, unsigned, int); +extern void selection_request(Time, int, int); +extern void selection_reset(void); +extern void selection_clear(void); +extern void selection_setclr(int, int, int, int, int); +extern void selection_start(int, int); +extern void selection_start_colrow(int, int); +extern void selection_make(Time); +extern void selection_click(int, int, int); +extern void selection_delimit_word(int, int, row_col_t *, row_col_t *); +extern void selection_extend(int, int, int); +extern void selection_extend_colrow(int, int, int, int); +extern void selection_rotate(int, int); +extern void selection_send(XSelectionRequestEvent *); +extern void mouse_report(XButtonEvent *); +extern void mouse_tracking(int, int, int, int, int); +extern void debug_PasteIt(unsigned char *, int); +extern int debug_selection(void); +extern void debug_colors(void); _XFUNCPROTOEND -#endif /* whole file */ -/*----------------------- end-of-file (C header) -----------------------*/ +#endif diff --git a/src/scrollbar.c b/src/scrollbar.c index a35cb72..9212750 100644 --- a/src/scrollbar.c +++ b/src/scrollbar.c @@ -1,61 +1,70 @@ -/*--------------------------------*-C-*---------------------------------* - * File: scrollbar.c +/* scrollbar.c -- Eterm scrollbar module + + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. * - * scrollbar routines + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen * - * Copyright 1996,97 - * mj olesen Queen's Univ at Kingston - * - * You can do what you like with this source code provided you don't make - * money from it and you include an unaltered copy of this message - * (including the copyright). As usual, the author accepts no - * responsibility for anything, nor does he guarantee anything whatsoever. - *----------------------------------------------------------------------*/ + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ static const char cvs_ident[] = "$Id$"; +#include "config.h" #include "feature.h" + +#include + +#include "../libmej/debug.h" +#include "command.h" +#include "events.h" #include "main.h" -#include "scrollbar.h" -#include "screen.h" -#include "debug.h" #include "options.h" #ifdef PIXMAP_SCROLLBAR # include "pixmap.h" #endif +#include "screen.h" +#include "scrollbar.h" +#include "term.h" +#include "windows.h" -/* extern functions referenced */ -/* extern variables referenced */ -/* extern variables declared here */ - +event_dispatcher_data_t scrollbar_event_data; #ifdef PIXMAP_SCROLLBAR -scrollBar_t scrollBar = -{0, 0, 0, 0, 0, SCROLLBAR_DEFAULT_TYPE, SB_WIDTH, None, None, None, None}; - -#else -scrollBar_t scrollBar = -{0, 0, 0, 0, 0, SCROLLBAR_DEFAULT_TYPE, SB_WIDTH, None}; - +scrollbar_t scrollBar = +{0, 1, 0, 1, 0, SCROLLBAR_DEFAULT_TYPE, SB_WIDTH, 0, 0, 0, 0, 0, 0, 0, 0, None, None, None, None}; +#else +scrollbar_t scrollBar = +{0, 1, 0, 1, 0, SCROLLBAR_DEFAULT_TYPE, SB_WIDTH, 0, 0, 0, 0, 0, 0, 0, 0, None}; +#endif +#ifdef SCROLLBAR_BUTTON_CONTINUAL_SCROLLING +short scroll_arrow_delay; #endif -int sb_shadow; - -/*----------------------------------------------------------------------* - */ static GC scrollbarGC; static short last_top = 0, last_bot = 0; /* old (drawn) values */ - #ifdef XTERM_SCROLLBAR /* bitmap scrollbar */ static GC shadowGC; static char xterm_sb_bits[] = {0xaa, 0x0a, 0x55, 0x05}; /* 12x2 bitmap */ - #endif - #if defined(MOTIF_SCROLLBAR) || defined(NEXT_SCROLLBAR) static GC topShadowGC, botShadowGC; /* draw triangular up button with a shadow of SHADOW (1 or 2) pixels */ -/* PROTO */ void Draw_up_button(int x, int y, int state) { @@ -64,11 +73,6 @@ Draw_up_button(int x, int y, int state) XPoint pt[3]; GC top = None, bot = None; -# ifdef PIXMAP_SCROLLBAR - Pixmap pixmap = upPixmap.pixmap; - -# endif - D_SCROLLBAR(("Draw_up_button(%d, %d, %d)\n", x, y, state)); switch (state) { @@ -86,60 +90,45 @@ Draw_up_button(int x, int y, int state) break; } -# ifdef PIXMAP_SCROLLBAR - if ((scrollbar_is_pixmapped()) && (pixmap != None)) { - XSetWindowBackgroundPixmap(Xdisplay, scrollBar.up_win, pixmap); - XClearWindow(Xdisplay, scrollBar.up_win); - } else -# endif - { - /* fill triangle */ - pt[0].x = x; - pt[0].y = y + sz - 1; - pt[1].x = x + sz - 1; - pt[1].y = y + sz - 1; - pt[2].x = x + sz2; - pt[2].y = y; - XFillPolygon(Xdisplay, scrollBar.win, scrollbarGC, - pt, 3, Convex, CoordModeOrigin); + /* fill triangle */ + pt[0].x = x; + pt[0].y = y + sz - 1; + pt[1].x = x + sz - 1; + pt[1].y = y + sz - 1; + pt[2].x = x + sz2; + pt[2].y = y; + XFillPolygon(Xdisplay, scrollBar.win, scrollbarGC, pt, 3, Convex, CoordModeOrigin); - /* draw base */ - XDrawLine(Xdisplay, scrollBar.win, bot, - pt[0].x, pt[0].y, pt[1].x, pt[1].y); + /* draw base */ + XDrawLine(Xdisplay, scrollBar.win, bot, pt[0].x, pt[0].y, pt[1].x, pt[1].y); - /* draw shadow */ - pt[1].x = x + sz2 - 1; - pt[1].y = y; - XDrawLine(Xdisplay, scrollBar.win, top, - pt[0].x, pt[0].y, pt[1].x, pt[1].y); + /* draw shadow */ + pt[1].x = x + sz2 - 1; + pt[1].y = y; + XDrawLine(Xdisplay, scrollBar.win, top, pt[0].x, pt[0].y, pt[1].x, pt[1].y); # if (SHADOW > 1) - /* doubled */ - pt[0].x++; - pt[0].y--; - pt[1].y++; - XDrawLine(Xdisplay, scrollBar.win, top, - pt[0].x, pt[0].y, pt[1].x, pt[1].y); + /* doubled */ + pt[0].x++; + pt[0].y--; + pt[1].y++; + XDrawLine(Xdisplay, scrollBar.win, top, pt[0].x, pt[0].y, pt[1].x, pt[1].y); # endif - /* draw shadow */ - pt[0].x = x + sz2; - pt[0].y = y; - pt[1].x = x + sz - 1; - pt[1].y = y + sz - 1; - XDrawLine(Xdisplay, scrollBar.win, bot, - pt[0].x, pt[0].y, pt[1].x, pt[1].y); + /* draw shadow */ + pt[0].x = x + sz2; + pt[0].y = y; + pt[1].x = x + sz - 1; + pt[1].y = y + sz - 1; + XDrawLine(Xdisplay, scrollBar.win, bot, pt[0].x, pt[0].y, pt[1].x, pt[1].y); # if (SHADOW > 1) - /* doubled */ - pt[0].y++; - pt[1].x--; - pt[1].y--; - XDrawLine(Xdisplay, scrollBar.win, bot, - pt[0].x, pt[0].y, pt[1].x, pt[1].y); + /* doubled */ + pt[0].y++; + pt[1].x--; + pt[1].y--; + XDrawLine(Xdisplay, scrollBar.win, bot, pt[0].x, pt[0].y, pt[1].x, pt[1].y); # endif - } } /* draw triangular down button with a shadow of SHADOW (1 or 2) pixels */ -/* PROTO */ void Draw_dn_button(int x, int y, int state) { @@ -148,11 +137,6 @@ Draw_dn_button(int x, int y, int state) XPoint pt[3]; GC top = None, bot = None; -# ifdef PIXMAP_SCROLLBAR - Pixmap pixmap = dnPixmap.pixmap; - -# endif - D_SCROLLBAR(("Draw_dn_button(%d, %d, %d)\n", x, y, state)); switch (state) { @@ -170,85 +154,464 @@ Draw_dn_button(int x, int y, int state) break; } -# ifdef PIXMAP_SCROLLBAR - if ((scrollbar_is_pixmapped()) && (pixmap != None)) { - XSetWindowBackgroundPixmap(Xdisplay, scrollBar.up_win, pixmap); - XClearWindow(Xdisplay, scrollBar.dn_win); - } else -# endif - { - /* fill triangle */ - pt[0].x = x; - pt[0].y = y; - pt[1].x = x + sz - 1; - pt[1].y = y; - pt[2].x = x + sz2; - pt[2].y = y + sz; - XFillPolygon(Xdisplay, scrollBar.win, scrollbarGC, - pt, 3, Convex, CoordModeOrigin); + /* fill triangle */ + pt[0].x = x; + pt[0].y = y; + pt[1].x = x + sz - 1; + pt[1].y = y; + pt[2].x = x + sz2; + pt[2].y = y + sz; + XFillPolygon(Xdisplay, scrollBar.win, scrollbarGC, pt, 3, Convex, CoordModeOrigin); - /* draw base */ - XDrawLine(Xdisplay, scrollBar.win, top, - pt[0].x, pt[0].y, pt[1].x, pt[1].y); + /* draw base */ + XDrawLine(Xdisplay, scrollBar.win, top, pt[0].x, pt[0].y, pt[1].x, pt[1].y); - /* draw shadow */ - pt[1].x = x + sz2 - 1; - pt[1].y = y + sz - 1; - XDrawLine(Xdisplay, scrollBar.win, top, - pt[0].x, pt[0].y, pt[1].x, pt[1].y); + /* draw shadow */ + pt[1].x = x + sz2 - 1; + pt[1].y = y + sz - 1; + XDrawLine(Xdisplay, scrollBar.win, top, pt[0].x, pt[0].y, pt[1].x, pt[1].y); # if (SHADOW > 1) - /* doubled */ - pt[0].x++; - pt[0].y++; - pt[1].y--; - XDrawLine(Xdisplay, scrollBar.win, top, - pt[0].x, pt[0].y, pt[1].x, pt[1].y); + /* doubled */ + pt[0].x++; + pt[0].y++; + pt[1].y--; + XDrawLine(Xdisplay, scrollBar.win, top, pt[0].x, pt[0].y, pt[1].x, pt[1].y); # endif - /* draw shadow */ - pt[0].x = x + sz2; - pt[0].y = y + sz - 1; - pt[1].x = x + sz - 1; - pt[1].y = y; - XDrawLine(Xdisplay, scrollBar.win, bot, - pt[0].x, pt[0].y, pt[1].x, pt[1].y); + /* draw shadow */ + pt[0].x = x + sz2; + pt[0].y = y + sz - 1; + pt[1].x = x + sz - 1; + pt[1].y = y; + XDrawLine(Xdisplay, scrollBar.win, bot, pt[0].x, pt[0].y, pt[1].x, pt[1].y); # if (SHADOW > 1) - /* doubled */ - pt[0].y--; - pt[1].x--; - pt[1].y++; - XDrawLine(Xdisplay, scrollBar.win, bot, - pt[0].x, pt[0].y, pt[1].x, pt[1].y); + /* doubled */ + pt[0].y--; + pt[1].x--; + pt[1].y++; + XDrawLine(Xdisplay, scrollBar.win, bot, pt[0].x, pt[0].y, pt[1].x, pt[1].y); # endif - } } #endif /* MOTIF_SCROLLBAR || NEXT_SCROLLBAR */ -/* PROTO */ -int -scrollbar_mapping(int map) +void +scrollbar_init(void) { - int change = 0; + Cursor cursor; + long mask; - D_SCROLLBAR(("scrollbar_mapping(%d)\n", map)); + Attributes.background_pixel = PixColors[scrollColor]; + Attributes.border_pixel = PixColors[bgColor]; + Attributes.override_redirect = TRUE; + cursor = XCreateFontCursor(Xdisplay, XC_left_ptr); + mask = ExposureMask | EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask + | Button1MotionMask | Button2MotionMask | Button3MotionMask; - if (map && !scrollbar_visible()) { + scrollBar.win = XCreateWindow(Xdisplay, TermWin.parent, 0, 0, 1, 1, 0, Xdepth, InputOutput, CopyFromParent, + CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWBackPixel | CWBorderPixel | CWColormap, &Attributes); + XDefineCursor(Xdisplay, scrollBar.win, cursor); + XSelectInput(Xdisplay, scrollBar.win, mask); + +#ifdef PIXMAP_SCROLLBAR + if (scrollbar_uparrow_is_pixmapped()) { + scrollBar.up_win = XCreateWindow(Xdisplay, scrollBar.win, 0, 0, 1, 1, 0, Xdepth, InputOutput, CopyFromParent, + CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWColormap, &Attributes); + XSelectInput(Xdisplay, scrollBar.up_win, mask); + } + if (scrollbar_downarrow_is_pixmapped()) { + scrollBar.dn_win = XCreateWindow(Xdisplay, scrollBar.win, 0, 0, 1, 1, 0, Xdepth, InputOutput, CopyFromParent, + CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWColormap, &Attributes); + XSelectInput(Xdisplay, scrollBar.dn_win, mask); + } + if (scrollbar_anchor_is_pixmapped()) { + scrollBar.sa_win = XCreateWindow(Xdisplay, scrollBar.win, 0, 0, 1, 1, 0, Xdepth, InputOutput, CopyFromParent, + CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWColormap, &Attributes); + XSelectInput(Xdisplay, scrollBar.sa_win, mask); + } +#endif + + event_register_dispatcher(scrollbar_dispatch_event, scrollbar_event_init_dispatcher); + +} + +void +scrollbar_event_init_dispatcher(void) +{ + + MEMSET(&scrollbar_event_data, 0, sizeof(event_dispatcher_data_t)); + + EVENT_DATA_ADD_HANDLER(scrollbar_event_data, EnterNotify, sb_handle_enter_notify); + EVENT_DATA_ADD_HANDLER(scrollbar_event_data, LeaveNotify, sb_handle_leave_notify); + EVENT_DATA_ADD_HANDLER(scrollbar_event_data, FocusIn, sb_handle_focus_in); + EVENT_DATA_ADD_HANDLER(scrollbar_event_data, FocusOut, sb_handle_focus_out); + EVENT_DATA_ADD_HANDLER(scrollbar_event_data, GraphicsExpose, sb_handle_expose); + EVENT_DATA_ADD_HANDLER(scrollbar_event_data, Expose, sb_handle_expose); + EVENT_DATA_ADD_HANDLER(scrollbar_event_data, ButtonPress, sb_handle_button_press); + EVENT_DATA_ADD_HANDLER(scrollbar_event_data, ButtonRelease, sb_handle_button_release); + EVENT_DATA_ADD_HANDLER(scrollbar_event_data, MotionNotify, sb_handle_motion_notify); + + event_data_add_mywin(&scrollbar_event_data, scrollBar.win); +#ifdef PIXMAP_SCROLLBAR + if (scrollbar_is_pixmapped()) { + event_data_add_mywin(&scrollbar_event_data, scrollBar.up_win); + event_data_add_mywin(&scrollbar_event_data, scrollBar.dn_win); + event_data_add_mywin(&scrollbar_event_data, scrollBar.sa_win); + } +#endif + + event_data_add_parent(&scrollbar_event_data, TermWin.vt); + event_data_add_parent(&scrollbar_event_data, TermWin.parent); + +} + +unsigned char +sb_handle_enter_notify(event_t * ev) +{ + + D_EVENTS(("sb_handle_enter_notify(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &scrollbar_event_data), 0); + + if (scrollbar_uparrow_is_pixmapped() && scrollbar_win_is_uparrow(ev->xany.window)) { + images[image_up].current = images[image_up].selected; + render_simage(images[image_up].current, scrollbar_get_uparrow_win(), scrollbar_arrow_width(), scrollbar_arrow_width(), image_up, 0); + } + if (scrollbar_downarrow_is_pixmapped() && scrollbar_win_is_downarrow(ev->xany.window)) { + images[image_down].current = images[image_down].selected; + render_simage(images[image_down].current, scrollbar_get_downarrow_win(), scrollbar_arrow_width(), scrollbar_arrow_width(), image_down, 0); + } + if (scrollbar_anchor_is_pixmapped() && scrollbar_win_is_anchor(ev->xany.window)) { + images[image_sa].current = images[image_sa].selected; + render_simage(images[image_sa].current, scrollbar_get_anchor_win(), scrollbar_anchor_width(), scrollbar_anchor_height(), image_sa, 0); + } + if (scrollbar_is_pixmapped() && scrollbar_win_is_scrollbar(ev->xany.window)) { + images[image_sb].current = images[image_sb].selected; + render_simage(images[image_sb].current, scrollbar_get_win(), scrollbar_trough_width(), scrollbar_trough_height(), image_sb, 0); + } + return 0; +} + +unsigned char +sb_handle_leave_notify(event_t * ev) +{ + + D_EVENTS(("sb_handle_leave_notify(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &scrollbar_event_data), 0); + + if (scrollbar_uparrow_is_pixmapped() && scrollbar_win_is_uparrow(ev->xany.window)) { + images[image_up].current = images[image_up].norm; + render_simage(images[image_up].current, scrollbar_get_uparrow_win(), scrollbar_arrow_width(), scrollbar_arrow_width(), image_up, 0); + } + if (scrollbar_downarrow_is_pixmapped() && scrollbar_win_is_downarrow(ev->xany.window)) { + images[image_down].current = images[image_down].norm; + render_simage(images[image_down].current, scrollbar_get_downarrow_win(), scrollbar_arrow_width(), scrollbar_arrow_width(), image_down, 0); + } + if (scrollbar_anchor_is_pixmapped() && scrollbar_win_is_anchor(ev->xany.window)) { + images[image_sa].current = images[image_sa].norm; + render_simage(images[image_sa].current, scrollbar_get_anchor_win(), scrollbar_anchor_width(), scrollbar_anchor_height(), image_sa, 0); + } + if (scrollbar_is_pixmapped() && scrollbar_win_is_scrollbar(ev->xany.window)) { + images[image_sb].current = images[image_sb].norm; + render_simage(images[image_sb].current, scrollbar_get_win(), scrollbar_trough_width(), scrollbar_trough_height(), image_sb, 0); + } + return 0; +} + +unsigned char +sb_handle_focus_in(event_t * ev) +{ + + D_EVENTS(("sb_handle_focus_in(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &scrollbar_event_data), 0); + + return 0; +} + +unsigned char +sb_handle_focus_out(event_t * ev) +{ + + D_EVENTS(("sb_handle_focus_out(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &scrollbar_event_data), 0); + + return 0; +} + +unsigned char +sb_handle_expose(event_t * ev) +{ + + XEvent unused_xevent; + + D_EVENTS(("sb_handle_expose(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &scrollbar_event_data), 0); + + while (XCheckTypedWindowEvent(Xdisplay, ev->xany.window, Expose, &unused_xevent)); + while (XCheckTypedWindowEvent(Xdisplay, ev->xany.window, GraphicsExpose, &unused_xevent)); + if (scrollbar_win_is_scrollbar(ev->xany.window)) { + scrollbar_show(0); + } + return 0; +} + +unsigned char +sb_handle_button_press(event_t * ev) +{ + + D_EVENTS(("sb_handle_button_press(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &scrollbar_event_data), 0); + + button_state.bypass_keystate = (ev->xbutton.state & (Mod1Mask | ShiftMask)); + button_state.report_mode = (button_state.bypass_keystate ? 0 : ((PrivateModes & PrivMode_mouse_report) ? 1 : 0)); + + scrollbar_setNone(); +#ifndef NO_SCROLLBAR_REPORT + if (button_state.report_mode) { + /* Mouse report disabled scrollbar. Arrows send cursor key up/down, trough sends pageup/pagedown */ + if (scrollbar_upButton(ev->xany.window, ev->xbutton.y)) + tt_printf("\033[A"); + else if (scrollbar_dnButton(ev->xany.window, ev->xbutton.y)) + tt_printf("\033[B"); + else + switch (ev->xbutton.button) { + case Button2: + tt_printf("\014"); + break; + case Button1: + tt_printf("\033[6~"); + break; + case Button3: + tt_printf("\033[5~"); + break; + } + } else +#endif /* NO_SCROLLBAR_REPORT */ + { + D_EVENTS(("ButtonPress event for window 0x%08x at %d, %d\n", ev->xany.window, ev->xbutton.x, ev->xbutton.y)); + D_EVENTS((" up [0x%08x], down [0x%08x], anchor [0x%08x], trough [0x%08x]\n", scrollBar.up_win, scrollBar.dn_win, scrollBar.sa_win, scrollBar.win)); + + if (scrollbar_upButton(ev->xany.window, ev->xbutton.y)) { + + if (scrollbar_uparrow_is_pixmapped() && images[image_up].current != images[image_up].clicked) { + images[image_up].current = images[image_up].clicked; + render_simage(images[image_up].current, scrollbar_get_uparrow_win(), scrollbar_arrow_width(), scrollbar_arrow_width(), image_up, 0); + } +#ifdef SCROLLBAR_BUTTON_CONTINUAL_SCROLLING + scroll_arrow_delay = SCROLLBAR_INITIAL_DELAY; +#endif + if (scr_page(UP, 1)) { + scrollbar_setUp(); + } + } else if (scrollbar_dnButton(ev->xany.window, ev->xbutton.y)) { + + if (scrollbar_downarrow_is_pixmapped() && images[image_down].current != images[image_down].clicked) { + images[image_down].current = images[image_down].clicked; + render_simage(images[image_down].current, scrollbar_get_downarrow_win(), scrollbar_arrow_width(), scrollbar_arrow_width(), image_down, 0); + } +#ifdef SCROLLBAR_BUTTON_CONTINUAL_SCROLLING + scroll_arrow_delay = SCROLLBAR_INITIAL_DELAY; +#endif + if (scr_page(DN, 1)) { + scrollbar_setDn(); + } + } else { + switch (ev->xbutton.button) { + case Button2: + button_state.mouse_offset = scrollbar_anchor_height() / 2; /* Align to center */ + if (scrollbar_anchor_is_pixmapped() && images[image_sa].current != images[image_sa].clicked) { + images[image_sa].current = images[image_sa].clicked; + render_simage(images[image_sa].current, scrollbar_get_anchor_win(), scrollbar_anchor_width(), scrollbar_anchor_height(), image_sa, 0); + } + if (scrollbar_is_above_anchor(ev->xany.window, ev->xbutton.y) + || scrollbar_is_below_anchor(ev->xany.window, ev->xbutton.y) + || scrollBar.type == SCROLLBAR_XTERM) { + scr_move_to(scrollbar_position(ev->xbutton.y) - button_state.mouse_offset, scrollbar_scrollarea_height()); + } + scrollbar_setMotion(); + break; + + case Button1: + button_state.mouse_offset = ev->xbutton.y - (scrollbar_anchor_is_pixmapped()? 0 : scrollBar.top); + MAX_IT(button_state.mouse_offset, 1); + /* drop */ + case Button3: +#if defined(MOTIF_SCROLLBAR) || defined(NEXT_SCROLLBAR) + if (scrollBar.type == SCROLLBAR_MOTIF || scrollBar.type == SCROLLBAR_NEXT) { + if (scrollbar_is_above_anchor(ev->xany.window, ev->xbutton.y)) { + if (images[image_sb].current != images[image_sb].clicked) { + images[image_sb].current = images[image_sb].clicked; + render_simage(images[image_sb].current, scrollbar_get_win(), scrollbar_trough_width(), scrollbar_trough_height(), image_sb, 0); + } + scr_page(UP, TermWin.nrow - 1); + } else if (scrollbar_is_below_anchor(ev->xany.window, ev->xbutton.y)) { + if (images[image_sb].current != images[image_sb].clicked) { + images[image_sb].current = images[image_sb].clicked; + render_simage(images[image_sb].current, scrollbar_get_win(), scrollbar_trough_width(), scrollbar_trough_height(), image_sb, 0); + } + scr_page(DN, TermWin.nrow - 1); + } else { + if (scrollbar_anchor_is_pixmapped() && images[image_sa].current != images[image_sa].clicked) { + images[image_sa].current = images[image_sa].clicked; + render_simage(images[image_sa].current, scrollbar_get_anchor_win(), scrollbar_anchor_width(), scrollbar_anchor_height(), image_sa, 0); + } + scrollbar_setMotion(); + } + } +#endif /* MOTIF_SCROLLBAR || NEXT_SCROLLBAR */ + +#ifdef XTERM_SCROLLBAR + if (scrollBar.type == SCROLLBAR_XTERM) { + scr_page((ev->xbutton.button == Button1 ? DN : UP), (TermWin.nrow * scrollbar_position(ev->xbutton.y) / scrollbar_scrollarea_height())); + } +#endif /* XTERM_SCROLLBAR */ + break; + } + } + } + + return 1; +} + +unsigned char +sb_handle_button_release(event_t * ev) +{ + + Window root, child; + int root_x, root_y, win_x, win_y, mask; + + D_EVENTS(("sb_handle_button_release(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &scrollbar_event_data), 0); + button_state.mouse_offset = 0; + button_state.report_mode = (button_state.bypass_keystate ? 0 : ((PrivateModes & PrivMode_mouse_report) ? 1 : 0)); + +#ifdef PIXMAP_SCROLLBAR + XQueryPointer(Xdisplay, scrollbar_get_win(), &root, &child, &root_x, &root_y, &win_x, &win_y, &mask); + if (scrollbar_uparrow_is_pixmapped()) { + if (scrollbar_win_is_uparrow(child)) { + images[image_up].current = images[image_up].selected; + render_simage(images[image_up].current, scrollbar_get_uparrow_win(), scrollbar_arrow_width(), scrollbar_arrow_width(), image_up, 0); + } else if (images[image_up].current != images[image_up].norm) { + images[image_up].current = images[image_up].norm; + render_simage(images[image_up].current, scrollbar_get_uparrow_win(), scrollbar_arrow_width(), scrollbar_arrow_width(), image_up, 0); + } + } + if (scrollbar_downarrow_is_pixmapped()) { + if (scrollbar_win_is_downarrow(child)) { + images[image_down].current = images[image_down].selected; + render_simage(images[image_down].current, scrollbar_get_downarrow_win(), scrollbar_arrow_width(), scrollbar_arrow_width(), image_down, 0); + } else if (images[image_down].current != images[image_down].norm) { + images[image_down].current = images[image_down].norm; + render_simage(images[image_down].current, scrollbar_get_downarrow_win(), scrollbar_arrow_width(), scrollbar_arrow_width(), image_down, 0); + } + } + if (scrollbar_anchor_is_pixmapped()) { + if (scrollbar_win_is_anchor(child)) { + images[image_sa].current = images[image_sa].selected; + render_simage(images[image_sa].current, scrollbar_get_anchor_win(), scrollbar_anchor_width(), scrollbar_anchor_height(), image_sa, 0); + } else if (images[image_sa].current != images[image_sa].norm) { + images[image_sa].current = images[image_sa].norm; + render_simage(images[image_sa].current, scrollbar_get_anchor_win(), scrollbar_anchor_width(), scrollbar_anchor_height(), image_sa, 0); + } + } + if (scrollbar_is_pixmapped()) { + if (scrollbar_win_is_scrollbar(child)) { + images[image_sb].current = images[image_sb].selected; + render_simage(images[image_sb].current, scrollbar_get_win(), scrollbar_trough_width(), scrollbar_trough_height(), image_sb, 0); + } else if (images[image_sb].current != images[image_sb].norm) { + images[image_sb].current = images[image_sb].norm; + render_simage(images[image_sb].current, scrollbar_get_win(), scrollbar_trough_width(), scrollbar_trough_height(), image_sb, 0); + } + } +#endif + + if (scrollbar_isUpDn()) { + scrollbar_setNone(); + scrollbar_show(0); + } + return 1; +} + +unsigned char +sb_handle_motion_notify(event_t * ev) +{ + + D_EVENTS(("sb_handle_motion_notify(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window)); + + REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &scrollbar_event_data), 0); + if ((PrivateModes & PrivMode_mouse_report) && !(button_state.bypass_keystate)) + return 1; + + D_EVENTS(("MotionNotify event for window 0x%08x\n", ev->xany.window)); + D_EVENTS((" up [0x%08x], down [0x%08x], anchor [0x%08x], trough [0x%08x]\n", scrollBar.up_win, scrollBar.dn_win, scrollBar.sa_win, scrollBar.win)); + + if ((scrollbar_win_is_scrollbar(ev->xany.window) +#ifdef PIXMAP_SCROLLBAR + || (scrollbar_anchor_is_pixmapped() && scrollbar_win_is_anchor(ev->xany.window)) +#endif + ) && scrollbar_isMotion()) { + + Window unused_root, unused_child; + int unused_root_x, unused_root_y; + unsigned int unused_mask; + + while (XCheckTypedWindowEvent(Xdisplay, scrollBar.win, MotionNotify, ev)); + XQueryPointer(Xdisplay, scrollBar.win, &unused_root, &unused_child, &unused_root_x, &unused_root_y, &(ev->xbutton.x), &(ev->xbutton.y), &unused_mask); + scr_move_to(scrollbar_position(ev->xbutton.y) - button_state.mouse_offset, scrollbar_scrollarea_height()); + refresh_count = refresh_limit = 0; + scr_refresh(refresh_type); + scrollbar_show(button_state.mouse_offset); + } + return 1; +} + +unsigned char +scrollbar_dispatch_event(event_t * ev) +{ + if (scrollbar_event_data.handlers[ev->type] != NULL) { + return ((scrollbar_event_data.handlers[ev->type]) (ev)); + } + return (0); +} + +unsigned char +scrollbar_mapping(unsigned char show) +{ + + unsigned char change = 0; + + D_SCROLLBAR(("scrollbar_mapping(%d)\n", show)); + + if (show && !scrollbar_visible()) { scrollBar.state = 1; XMapWindow(Xdisplay, scrollBar.win); #ifdef PIXMAP_SCROLLBAR - if (scrollbar_is_pixmapped()) { + if (scrollbar_uparrow_is_pixmapped()) { XMapWindow(Xdisplay, scrollBar.up_win); + } + if (scrollbar_downarrow_is_pixmapped()) { XMapWindow(Xdisplay, scrollBar.dn_win); + } + if (scrollbar_anchor_is_pixmapped()) { XMapWindow(Xdisplay, scrollBar.sa_win); } #endif change = 1; - } else if (!map && scrollbar_visible()) { + } else if (!show && scrollbar_visible()) { scrollBar.state = 0; #ifdef PIXMAP_SCROLLBAR - if (scrollbar_is_pixmapped()) { + if (scrollbar_uparrow_is_pixmapped()) { XUnmapWindow(Xdisplay, scrollBar.up_win); + } + if (scrollbar_downarrow_is_pixmapped()) { XUnmapWindow(Xdisplay, scrollBar.dn_win); + } + if (scrollbar_anchor_is_pixmapped()) { XUnmapWindow(Xdisplay, scrollBar.sa_win); } #endif @@ -266,6 +629,7 @@ scrollbar_reset(void) XFreeGC(Xdisplay, scrollbarGC); scrollbarGC = None; } +#if defined(MOTIF_SCROLLBAR) || defined(NEXT_SCROLLBAR) if (topShadowGC != None) { XFreeGC(Xdisplay, topShadowGC); topShadowGC = None; @@ -274,30 +638,28 @@ scrollbar_reset(void) XFreeGC(Xdisplay, botShadowGC); botShadowGC = None; } +#endif +#ifdef XTERM_SCROLLBAR if (shadowGC != None) { XFreeGC(Xdisplay, shadowGC); shadowGC = None; } +#endif last_top = last_bot = 0; if (scrollBar.type == SCROLLBAR_XTERM) { - sb_shadow = 0; + scrollbar_set_shadow(0); } else { - sb_shadow = (Options & Opt_scrollBar_floating) ? 0 : SHADOW; + scrollbar_set_shadow((Options & Opt_scrollBar_floating) ? 0 : SHADOW); } } -int -scrollbar_show(int mouseoffset) +unsigned char +scrollbar_show(short mouseoffset) { - static short sb_width; /* old (drawn) values */ unsigned char xsb = 0, force_update = 0; - -#ifdef CHANGE_SCROLLCOLOR_ON_FOCUS static int focus = -1; -#endif - if (!scrollbar_visible()) return 0; @@ -309,72 +671,49 @@ scrollbar_show(int mouseoffset) #ifdef XTERM_SCROLLBAR if (scrollBar.type == SCROLLBAR_XTERM) { - sb_width = scrollBar.width - 1; - gcvalue.stipple = XCreateBitmapFromData(Xdisplay, scrollBar.win, - xterm_sb_bits, 12, 2); + gcvalue.stipple = XCreateBitmapFromData(Xdisplay, scrollBar.win, xterm_sb_bits, 12, 2); if (!gcvalue.stipple) { - print_error("can't create bitmap"); - exit(EXIT_FAILURE); + print_error("Unable to create xterm scrollbar bitmap. Reverting to default scrollbar."); + scrollBar.type = SCROLLBAR_MOTIF; + } else { + gcvalue.fill_style = FillOpaqueStippled; + gcvalue.foreground = PixColors[fgColor]; + gcvalue.background = PixColors[bgColor]; + scrollbarGC = XCreateGC(Xdisplay, scrollBar.win, GCForeground | GCBackground | GCFillStyle | GCStipple, &gcvalue); + gcvalue.foreground = PixColors[borderColor]; + shadowGC = XCreateGC(Xdisplay, scrollBar.win, GCForeground, &gcvalue); } - gcvalue.fill_style = FillOpaqueStippled; - gcvalue.foreground = PixColors[fgColor]; - gcvalue.background = PixColors[bgColor]; - - scrollbarGC = XCreateGC(Xdisplay, scrollBar.win, - GCForeground | GCBackground | - GCFillStyle | GCStipple, - &gcvalue); - gcvalue.foreground = PixColors[borderColor]; - shadowGC = XCreateGC(Xdisplay, scrollBar.win, GCForeground, &gcvalue); } #endif /* XTERM_SCROLLBAR */ #if defined(MOTIF_SCROLLBAR) || defined(NEXT_SCROLLBAR) if (scrollBar.type == SCROLLBAR_MOTIF || scrollBar.type == SCROLLBAR_NEXT) { - sb_width = scrollBar.width; -# ifdef KEEP_SCROLLCOLOR - gcvalue.foreground = (Xdepth <= 2 ? PixColors[fgColor] - : PixColors[scrollColor]); -# else - gcvalue.foreground = PixColors[fgColor]; -# endif - scrollbarGC = XCreateGC(Xdisplay, scrollBar.win, GCForeground, - &gcvalue); - if ((sb_shadow) && (!(scrollbar_is_pixmapped()))) { - XSetWindowBackground(Xdisplay, scrollBar.win, gcvalue.foreground); - XClearWindow(Xdisplay, scrollBar.win); + gcvalue.foreground = (Xdepth <= 2 ? PixColors[fgColor] : PixColors[scrollColor]); + scrollbarGC = XCreateGC(Xdisplay, scrollBar.win, GCForeground, &gcvalue); + + if (scrollbar_is_pixmapped() || (Options & (Opt_scrollBar_floating | Opt_pixmapTrans))) { + render_simage(images[image_sb].current, scrollBar.win, scrollbar_trough_width(), scrollbar_trough_height(), image_sb, 0); } else if (Options & Opt_scrollBar_floating) { - if (!(Options & Opt_pixmapTrans)) { - if (background_is_pixmap()) { - XSetWindowBackground(Xdisplay, scrollBar.win, PixColors[scrollColor]); - } else { - XSetWindowBackground(Xdisplay, scrollBar.win, PixColors[bgColor]); - } + if (background_is_pixmap()) { + /* FIXME: Extend the bg pixmap into the scrollbar window here? -- mej */ + XSetWindowBackground(Xdisplay, scrollBar.win, gcvalue.foreground); + } else { + XSetWindowBackground(Xdisplay, scrollBar.win, PixColors[bgColor]); } - XClearWindow(Xdisplay, scrollBar.win); + } else { + XSetWindowBackground(Xdisplay, scrollBar.win, gcvalue.foreground); } -# ifdef KEEP_SCROLLCOLOR + XClearWindow(Xdisplay, scrollBar.win); gcvalue.foreground = PixColors[topShadowColor]; -# else /* KEEP_SCROLLCOLOR */ - gcvalue.foreground = PixColors[bgColor]; -# endif /* KEEP_SCROLLCOLOR */ - topShadowGC = XCreateGC(Xdisplay, scrollBar.win, - GCForeground, - &gcvalue); + topShadowGC = XCreateGC(Xdisplay, scrollBar.win, GCForeground, &gcvalue); -# ifdef KEEP_SCROLLCOLOR gcvalue.foreground = PixColors[bottomShadowColor]; -# else /* KEEP_SCROLLCOLOR */ - gcvalue.foreground = PixColors[bgColor]; -# endif /* KEEP_SCROLLCOLOR */ - botShadowGC = XCreateGC(Xdisplay, scrollBar.win, - GCForeground, - &gcvalue); + botShadowGC = XCreateGC(Xdisplay, scrollBar.win, GCForeground, &gcvalue); } #endif /* MOTIF_SCROLLBAR || NEXT_SCROLLBAR */ } -#if defined(CHANGE_SCROLLCOLOR_ON_FOCUS) && (defined(MOTIF_SCROLLBAR) || defined(NEXT_SCROLLBAR)) +#if defined(MOTIF_SCROLLBAR) || defined(NEXT_SCROLLBAR) if (scrollBar.type == SCROLLBAR_MOTIF || scrollBar.type == SCROLLBAR_NEXT) { if (focus != TermWin.focus) { XGCValues gcvalue; @@ -384,37 +723,37 @@ scrollbar_show(int mouseoffset) # ifdef PIXMAP_OFFSET if (!((Options & Opt_pixmapTrans) && (Options & Opt_scrollBar_floating))) { # endif - XSetWindowBackground(Xdisplay, scrollBar.win, gcvalue.foreground); + if (scrollbar_is_pixmapped()) { + XSetWindowBackgroundPixmap(Xdisplay, scrollBar.win, images[image_sb].current->pmap->pixmap); + } else { + XSetWindowBackground(Xdisplay, scrollBar.win, gcvalue.foreground); + } XClearWindow(Xdisplay, scrollBar.win); # ifdef PIXMAP_OFFSET } # endif /* PIXMAP_OFFSET */ - XChangeGC(Xdisplay, scrollbarGC, GCForeground, - &gcvalue); + XChangeGC(Xdisplay, scrollbarGC, GCForeground, &gcvalue); gcvalue.foreground = PixColors[focus ? topShadowColor : unfocusedTopShadowColor]; - XChangeGC(Xdisplay, topShadowGC, - GCForeground, - &gcvalue); + XChangeGC(Xdisplay, topShadowGC, GCForeground, &gcvalue); + gcvalue.foreground = PixColors[focus ? bottomShadowColor : unfocusedBottomShadowColor]; - XChangeGC(Xdisplay, botShadowGC, - GCForeground, - &gcvalue); + XChangeGC(Xdisplay, botShadowGC, GCForeground, &gcvalue); force_update = 1; } } -#endif /* CHANGE_SCROLLCOLOR_ON_FOCUS && (MOTIF_SCROLLBAR || NEXT_SCROLLBAR) */ +#endif /* MOTIF_SCROLLBAR || NEXT_SCROLLBAR */ if (mouseoffset) { int top = (TermWin.nscrolled - TermWin.view_start); int bot = top + (TermWin.nrow - 1); int len = max((TermWin.nscrolled + (TermWin.nrow - 1)), 1); - scrollBar.top = (scrollBar.beg + (top * scrollbar_size()) / len); - scrollBar.bot = (scrollBar.beg + (bot * scrollbar_size()) / len); + scrollBar.top = (scrollBar.beg + (top * scrollbar_scrollarea_height()) / len); + scrollBar.bot = (scrollBar.beg + (bot * scrollbar_scrollarea_height()) / len); if (rs_min_anchor_size && scrollBar.type != SCROLLBAR_XTERM) { - if ((scrollbar_size() > rs_min_anchor_size) && (scrollBar.bot - scrollBar.top < rs_min_anchor_size)) { + if ((scrollbar_scrollarea_height() > rs_min_anchor_size) && (scrollbar_anchor_height() < rs_min_anchor_size)) { int grab_point = scrollBar.top + mouseoffset; @@ -429,8 +768,8 @@ scrollbar_show(int mouseoffset) scrollBar.bot = scrollBar.top + rs_min_anchor_size; } if (scrollBar.bot == scrollBar.end) { - scr_move_to(scrollBar.end, scrollbar_size()); - scr_refresh(SMOOTH_REFRESH); + scr_move_to(scrollBar.end, scrollbar_scrollarea_height()); + scr_refresh(DEFAULT_REFRESH); } } } @@ -442,96 +781,63 @@ scrollbar_show(int mouseoffset) xsb = ((scrollBar.type == SCROLLBAR_XTERM) && (Options & Opt_scrollBar_right)) ? 1 : 0; #endif if (last_top < scrollBar.top) { -#ifdef PIXMAP_SCROLLBAR - if (scrollbar_is_pixmapped()) { - D_SCROLLBAR(("ATTN: XClearArea() #1, going down\n")); - XClearArea(Xdisplay, scrollBar.win, - sb_shadow + xsb, last_top, - sb_width, (scrollBar.top - last_top), - False); - XMoveResizeWindow(Xdisplay, scrollBar.sa_win, - 0, scrollBar.top, - scrollbar_total_width(), - (scrollBar.bot - scrollBar.top)); - } else -#endif - { - D_SCROLLBAR(("ATTN: XClearArea() #2\n")); - XClearArea(Xdisplay, scrollBar.win, - sb_shadow + xsb, last_top, - sb_width, (scrollBar.top - last_top), - False); - } + XClearArea(Xdisplay, scrollBar.win, scrollbar_get_shadow() + xsb, last_top, scrollBar.width, (scrollBar.top - last_top), False); } if (scrollBar.bot < last_bot) { -#ifdef PIXMAP_SCROLLBAR - if (scrollbar_is_pixmapped()) { - D_SCROLLBAR(("ATTN: XClearArea() #3, going up\n")); - XClearArea(Xdisplay, scrollBar.win, - sb_shadow + xsb, scrollBar.bot, - sb_width, (last_bot - scrollBar.bot), - False); - XMoveResizeWindow(Xdisplay, scrollBar.sa_win, - 0, scrollBar.top, - scrollbar_total_width(), - (scrollBar.bot - scrollBar.top)); - } else -#endif - { - D_SCROLLBAR(("ATTN: XClearArea() #4\n")); - XClearArea(Xdisplay, scrollBar.win, - sb_shadow + xsb, scrollBar.bot, - sb_width, (last_bot - scrollBar.bot), - False); - } + XClearArea(Xdisplay, scrollBar.win, scrollbar_get_shadow() + xsb, scrollBar.bot, scrollBar.width, (last_bot - scrollBar.bot), False); } +#ifdef PIXMAP_SCROLLBAR + if (scrollbar_anchor_is_pixmapped()) { + if ((last_top != scrollBar.top) || (scrollBar.bot != last_bot)) { + XMoveResizeWindow(Xdisplay, scrollBar.sa_win, scrollbar_get_shadow(), scrollBar.top, scrollBar.width, scrollbar_anchor_height()); + } + render_simage(images[image_sa].current, scrollBar.sa_win, scrollbar_anchor_width(), scrollbar_anchor_height(), image_sa, 0); + } +#endif last_top = scrollBar.top; last_bot = scrollBar.bot; - /* scrollbar slider */ + /* scrollbar anchor */ #ifdef XTERM_SCROLLBAR if (scrollBar.type == SCROLLBAR_XTERM) { - XFillRectangle(Xdisplay, scrollBar.win, scrollbarGC, - xsb + 1, scrollBar.top, - sb_width - 2, (scrollBar.bot - scrollBar.top)); - XDrawLine(Xdisplay, scrollBar.win, shadowGC, - xsb ? 0 : sb_width, scrollBar.beg, xsb ? 0 : sb_width, scrollBar.end); + XFillRectangle(Xdisplay, scrollBar.win, scrollbarGC, xsb + 1, scrollBar.top, scrollBar.width - 2, scrollbar_anchor_height()); + XDrawLine(Xdisplay, scrollBar.win, shadowGC, xsb ? 0 : scrollBar.width, scrollBar.beg, xsb ? 0 : scrollBar.width, scrollBar.end); } #endif /* XTERM_SCROLLBAR */ #if defined(MOTIF_SCROLLBAR) || defined(NEXT_SCROLLBAR) if (scrollBar.type == SCROLLBAR_MOTIF || scrollBar.type == SCROLLBAR_NEXT) { -# ifdef PIXMAP_SCROLLBAR - if ((scrollbar_is_pixmapped()) && (saPixmap.pixmap != None)) { - D_SCROLLBAR(("ATTN: XCopyArea(%dx%d)", sb_width, (scrollBar.bot - scrollBar.top))); - XCopyArea(Xdisplay, saPixmap.pixmap, scrollBar.sa_win, scrollbarGC, - 0, 0, sb_width, (scrollBar.bot - scrollBar.top), - 0, scrollBar.top); - XClearArea(Xdisplay, scrollBar.sa_win, 0, scrollBar.top, - sb_width, (scrollBar.bot - scrollBar.top), False); - } else -# endif - { - XFillRectangle(Xdisplay, scrollBar.win, scrollbarGC, - sb_shadow, scrollBar.top, - sb_width, (scrollBar.bot - scrollBar.top)); + if (!scrollbar_anchor_is_pixmapped()) { + /* Draw the scrollbar anchor in if it's not pixmapped. */ + if (scrollbar_is_pixmapped()) { + XSetTSOrigin(Xdisplay, scrollbarGC, scrollbar_get_shadow(), scrollBar.top); + XFillRectangle(Xdisplay, scrollBar.win, scrollbarGC, scrollbar_get_shadow(), scrollBar.top, scrollBar.width, scrollbar_anchor_height()); + XSetTSOrigin(Xdisplay, scrollbarGC, 0, 0); + } else { + XFillRectangle(Xdisplay, scrollBar.win, scrollbarGC, scrollbar_get_shadow(), scrollBar.top, scrollBar.width, scrollbar_anchor_height()); + } } - if ((sb_shadow) && (!(scrollbar_is_pixmapped()))) { - /* trough shadow */ - Draw_Shadow(scrollBar.win, botShadowGC, topShadowGC, 0, 0, - (sb_width + 2 * sb_shadow), - scrollBar.end + ((scrollBar.type == SCROLLBAR_NEXT) ? (2 * (sb_width + 1) + sb_shadow) : ((sb_width + 1) + sb_shadow))); + /* Draw trough shadow */ + if (scrollbar_get_shadow() && !scrollbar_is_pixmapped()) { + Draw_Shadow(scrollBar.win, botShadowGC, topShadowGC, 0, 0, scrollbar_trough_width(), scrollbar_trough_height()); } - /* shadow for scrollbar slider */ - if (!(scrollbar_is_pixmapped())) { - Draw_Shadow(scrollBar.win, topShadowGC, botShadowGC, sb_shadow, scrollBar.top, sb_width, - (scrollBar.bot - scrollBar.top)); + /* Draw anchor shadow */ + if (!scrollbar_anchor_is_pixmapped()) { + Draw_Shadow(scrollBar.win, topShadowGC, botShadowGC, scrollbar_get_shadow(), scrollBar.top, scrollBar.width, scrollbar_anchor_height()); + } + /* Draw scrollbar arrows */ + if (scrollbar_uparrow_is_pixmapped()) { + XMoveResizeWindow(Xdisplay, scrollBar.up_win, scrollbar_get_shadow(), scrollbar_up_loc(), scrollbar_arrow_width(), scrollbar_arrow_height()); + render_simage(images[image_up].current, scrollBar.up_win, scrollbar_arrow_width(), scrollbar_arrow_width(), image_up, 0); + } else { + Draw_up_button(scrollbar_get_shadow(), scrollbar_up_loc(), (scrollbar_isUp()? -1 : +1)); + } + if (scrollbar_downarrow_is_pixmapped()) { + XMoveResizeWindow(Xdisplay, scrollBar.dn_win, scrollbar_get_shadow(), scrollbar_dn_loc(), scrollbar_arrow_width(), scrollbar_arrow_height()); + render_simage(images[image_down].current, scrollBar.dn_win, scrollbar_arrow_width(), scrollbar_arrow_width(), image_down, 0); + } else { + Draw_dn_button(scrollbar_get_shadow(), scrollbar_dn_loc(), (scrollbar_isDn()? -1 : +1)); } - /* - * Redraw scrollbar arrows - */ - Draw_up_button(sb_shadow, scrollbar_up_loc(), (scrollbar_isUp()? -1 : +1)); - Draw_dn_button(sb_shadow, scrollbar_dn_loc(), (scrollbar_isDn()? -1 : +1)); } #endif /* MOTIF_SCROLLBAR || NEXT_SCROLLBAR */ diff --git a/src/scrollbar.h b/src/scrollbar.h index cc500bb..8b83ce5 100644 --- a/src/scrollbar.h +++ b/src/scrollbar.h @@ -1,91 +1,160 @@ -/*--------------------------------*-C-*---------------------------------* - * File: scrollbar.h +/* scrollbar.h -- Eterm scrollbar module header file * - * Copyright 1996,97 - * mj olesen Queen's Univ at Kingston + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. * - * You can do what you like with this source code provided you don't make - * money from it and you include an unaltered copy of this message - * (including the copyright). As usual, the author accepts no - * responsibility for anything, nor does he guarantee anything whatsoever. - *----------------------------------------------------------------------*/ + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ #ifndef _SCROLLBAR_H -# define _SCROLLBAR_H +# define _SCROLLBAR_H -# include -# include -# ifdef PIXMAP_SCROLLBAR -# include "eterm_imlib.h" -# endif +# include +# include +# ifdef PIXMAP_SCROLLBAR +# include +# endif +# include "events.h" +/************ Macros and Definitions ************/ /* Scrollbar types we support */ # define SCROLLBAR_MOTIF 1 # define SCROLLBAR_XTERM 2 # define SCROLLBAR_NEXT 3 +/* Scrollbar state macros */ +#define scrollbar_visible() (scrollBar.state) +#define scrollbar_isMotion() (scrollBar.state == 'm') +#define scrollbar_isUp() (scrollBar.state == 'U') +#define scrollbar_isDn() (scrollBar.state == 'D') +#define scrollbar_isUpDn() isupper (scrollBar.state) +#define scrollbar_setNone() do { D_SCROLLBAR(("scrollbar_setNone(): Cancelling motion.\n")); scrollBar.state = 1; } while (0) +#define scrollbar_setMotion() do { D_SCROLLBAR(("scrollbar_setMotion()\n")); scrollBar.state = 'm'; } while (0) +#define scrollbar_setUp() do { D_SCROLLBAR(("scrollbar_setUp()\n")); scrollBar.state = 'U'; } while (0) +#define scrollbar_setDn() do { D_SCROLLBAR(("scrollbar_setNone()\n")); scrollBar.state = 'D'; } while (0) + +/* The various scrollbar elements */ +#ifdef PIXMAP_SCROLLBAR +# define scrollbar_win_is_scrollbar(w) (scrollbar_visible() && (w) == scrollBar.win) +# define scrollbar_win_is_uparrow(w) ((w) == scrollBar.up_win) +# define scrollbar_win_is_downarrow(w) ((w) == scrollBar.dn_win) +# define scrollbar_win_is_anchor(w) ((w) == scrollBar.sa_win) +# define scrollbar_is_pixmapped() (images[image_sb].current->iml->im) +# define scrollbar_uparrow_is_pixmapped() (images[image_up].current->iml->im) +# define scrollbar_downarrow_is_pixmapped() (images[image_down].current->iml->im) +# define scrollbar_anchor_is_pixmapped() (images[image_sa].current->iml->im) +# define scrollbar_upButton(w, y) ( scrollbar_uparrow_is_pixmapped() ? scrollbar_win_is_uparrow(w) \ + : ((scrollBar.type == SCROLLBAR_NEXT && (y) > scrollBar.end && (y) <= scrollbar_dn_loc()) \ + || (scrollBar.type != SCROLLBAR_NEXT && (y) < scrollBar.beg))) +# define scrollbar_dnButton(w, y) ( scrollbar_downarrow_is_pixmapped() ? scrollbar_win_is_downarrow(w) \ + : ((scrollBar.type == SCROLLBAR_NEXT && (y) > scrollbar_dn_loc()) \ + || (scrollBar.type != SCROLLBAR_NEXT && (y) > scrollBar.end))) +#else +# define scrollbar_win_is_scrollbar(w) (scrollbar_visible() && (w) == scrollBar.win) +# define scrollbar_win_is_uparrow(w) (0) +# define scrollbar_win_is_downarrow(w) (0) +# define scrollbar_win_is_anchor(w) (0) +# define scrollbar_is_pixmapped() (0) +# define scrollbar_uparrow_is_pixmapped() (0) +# define scrollbar_downarrow_is_pixmapped() (0) +# define scrollbar_anchor_is_pixmapped() (0) +# define scrollbar_upButton(w, y) ((scrollBar.type == SCROLLBAR_NEXT && (y) > scrollBar.end && (y) <= scrollbar_dn_loc()) \ + || (scrollBar.type != SCROLLBAR_NEXT && (y) < scrollBar.beg)) +# define scrollbar_dnButton(w, y) ((scrollBar.type == SCROLLBAR_NEXT && (y) > scrollbar_dn_loc()) \ + || (scrollBar.type != SCROLLBAR_NEXT && (y) > scrollBar.end)) +#endif + +/* Scrollbar dimensions */ +#define scrollbar_scrollarea_height() (scrollBar.end - scrollBar.beg) +#define scrollbar_anchor_width() (scrollBar.width) +#define scrollbar_anchor_height() (scrollBar.bot - scrollBar.top) +#define scrollbar_trough_width() (scrollBar.width + 2 * scrollBar.shadow) +#define scrollbar_trough_height() (scrollBar.end + ((scrollBar.type == SCROLLBAR_NEXT) ? (2 * (scrollBar.width + 1) + scrollBar.shadow) \ + : ((scrollBar.width + 1) + scrollBar.shadow))) +#define scrollbar_arrow_width() (scrollBar.width) +#define scrollbar_arrow_height() (scrollBar.width) +#define scrollbar_anchor_max_height() ((menubar_visible()) ? (TermWin.height) : (TermWin.height - ((scrollBar.width + 1) + scrollBar.shadow))) + +/* Scrollbar positions */ +#define scrollbar_is_above_anchor(w, y) ((y) < scrollBar.top && !scrollbar_win_is_anchor(w)) +#define scrollbar_is_below_anchor(w, y) ((y) > scrollBar.bot && !scrollbar_win_is_anchor(w)) +#define scrollbar_position(y) ((y) - scrollBar.beg) +#define scrollbar_up_loc() (scrollbar_uparrow_is_pixmapped() ? ((scrollBar.type == SCROLLBAR_NEXT) ? (scrollBar.end + 1) : (scrollBar.shadow)) \ + : ((scrollBar.type == SCROLLBAR_NEXT) ? (scrollBar.end + 1) : (scrollBar.shadow))) +#define scrollbar_dn_loc() (scrollbar_downarrow_is_pixmapped() \ + ? ((scrollBar.type == SCROLLBAR_NEXT) ? (scrollBar.end + scrollBar.width + 2) : (scrollBar.end + 1)) \ + : ((scrollBar.type == SCROLLBAR_NEXT) ? (scrollBar.end + scrollBar.width + 2) : (scrollBar.end + 1))) + +/* Scrollbar operations */ +#define map_scrollbar(show) do {if (scrollbar_mapping(show)) {scr_touch(); resize();} PrivMode(show, PrivMode_scrollBar); } while (0) +#define scrollbar_get_shadow() (scrollBar.shadow) +#define scrollbar_set_shadow(s) do { scrollBar.shadow = (s); } while (0) +#define scrollbar_get_win() (scrollBar.win) +#define scrollbar_get_uparrow_win() (scrollBar.up_win) +#define scrollbar_get_downarrow_win() (scrollBar.dn_win) +#define scrollbar_get_anchor_win() (scrollBar.sa_win) + +/************ Structures ************/ typedef struct { - short beg, end; /* beg/end of slider sub-window */ - short top, bot; /* top/bot of slider */ - short state; /* scrollbar state */ - unsigned char type; /* scrollbar type (see above) */ - short width; /* scrollbar width */ + short beg, end; /* beg/end of slider sub-window */ + short top, bot; /* top/bot of slider */ + unsigned char state; /* scrollbar state */ + unsigned char type; /* scrollbar type (see above) */ + unsigned short width, height; /* scrollbar width and height, without the shadow */ + unsigned short win_width, win_height; /* scrollbar window dimensions */ + short up_arrow_loc, down_arrow_loc; /* y coordinates for arrows */ + unsigned short arrow_width, arrow_height; /* scrollbar arrow dimensions */ + unsigned char shadow; /* shadow width */ Window win; # ifdef PIXMAP_SCROLLBAR Window up_win; Window dn_win; Window sa_win; # endif -} scrollBar_t; -extern scrollBar_t scrollBar; -extern int sb_shadow; +} scrollbar_t; -/* prototypes */ -_XFUNCPROTOBEGIN - -extern int scrollbar_mapping(int); -extern void scrollbar_reset(void); -extern int scrollbar_show(int); -_XFUNCPROTOEND - -/* macros */ -#define scrollbar_visible() (scrollBar.state) -#define scrollbar_isMotion() (scrollBar.state == 'm') -#define scrollbar_isUp() (scrollBar.state == 'U') -#define scrollbar_isDn() (scrollBar.state == 'D') -#define scrollbar_isUpDn() isupper (scrollBar.state) -#define scrollbar_setNone() do { scrollBar.state = 1; } while (0) -#define scrollbar_setMotion() do { scrollBar.state = 'm'; } while (0) -#define scrollbar_setUp() do { scrollBar.state = 'U'; } while (0) -#define scrollbar_setDn() do { scrollBar.state = 'D'; } while (0) - -#define scrollbar_above_slider(y) ((y) < scrollBar.top) -#define scrollbar_below_slider(y) ((y) > scrollBar.bot) -#define scrollbar_position(y) ((y) - scrollBar.beg) -#define scrollbar_size() (scrollBar.end - scrollBar.beg) - -#define scrollbar_total_width() (scrollBar.width + 2 * sb_shadow) -#define scrollbar_arrow_height() ((scrollBar.width + 1) + sb_shadow) -#define scrollbar_anchor_max_height() ((menubar_visible()) ? (TermWin.height) : (TermWin.height - ((scrollBar.width + 1) + sb_shadow))) - -#define scrollbar_up_loc() ((scrollBar.type == SCROLLBAR_NEXT) ? (scrollBar.end + 1) : (sb_shadow)) -#define scrollbar_dn_loc() ((scrollBar.type == SCROLLBAR_NEXT) \ - ? (scrollBar.end + scrollBar.width + 2) \ - : (scrollBar.end + 1)) -#define scrollbar_upButton(y) ((scrollBar.type == SCROLLBAR_NEXT && (y) > scrollBar.end && (y) <= scrollbar_dn_loc()) \ - || (scrollBar.type != SCROLLBAR_NEXT && (y) < scrollBar.beg)) -#define scrollbar_dnButton(y) ((scrollBar.type == SCROLLBAR_NEXT && (y) > scrollbar_dn_loc()) \ - || (scrollBar.type != SCROLLBAR_NEXT && (y) > scrollBar.end)) - -#ifdef PIXMAP_SCROLLBAR -# define isScrollbarWindow(w) ((scrollbar_is_pixmapped() && scrollbar_visible() && (w) == scrollBar.sa_win) \ - || (!scrollbar_is_pixmapped() && scrollbar_visible() && (w) == scrollBar.win)) -# define scrollbar_upButtonWin(w) ((w) == scrollBar.up_win) -# define scrollbar_dnButtonWin(w) ((w) == scrollBar.dn_win) -# define scrollbar_is_pixmapped() (0) -#else -# define isScrollbarWindow(w) (scrollbar_visible() && (w) == scrollBar.win) -# define scrollbar_is_pixmapped() (0) +/************ Variables ************/ +extern scrollbar_t scrollBar; +#ifdef SCROLLBAR_BUTTON_CONTINUAL_SCROLLING +extern short scroll_arrow_delay; #endif +/************ Function Prototypes ************/ +_XFUNCPROTOBEGIN + +extern void Draw_up_button(int, int, int); +extern void Draw_dn_button(int, int, int); +extern void scrollbar_init(void); +extern void scrollbar_event_init_dispatcher(void); +extern unsigned char sb_handle_enter_notify(event_t *); +extern unsigned char sb_handle_leave_notify(event_t *); +extern unsigned char sb_handle_focus_in(event_t *); +extern unsigned char sb_handle_focus_out(event_t *); +extern unsigned char sb_handle_expose(event_t *); +extern unsigned char sb_handle_button_press(event_t *); +extern unsigned char sb_handle_button_release(event_t *); +extern unsigned char sb_handle_motion_notify(event_t *); +extern unsigned char scrollbar_dispatch_event(event_t *); +extern unsigned char scrollbar_mapping(unsigned char); +extern void scrollbar_reset(void); +extern unsigned char scrollbar_show(short); + +_XFUNCPROTOEND + #endif /* _SCROLLBAR_H */ -/*----------------------- end-of-file (C header) -----------------------*/ diff --git a/src/system.c b/src/system.c index e82ade9..1e9825a 100644 --- a/src/system.c +++ b/src/system.c @@ -11,20 +11,17 @@ static const char cvs_ident[] = "$Id$"; #include #include #include +#include #include #ifdef HAVE_SYS_WAIT_H # include #endif -#include "strings.h" -#include "options.h" -#include "screen.h" -#include "system.h" #include "../libmej/debug.h" #include "debug.h" - -int system_wait(char *command); -int system_no_wait(char *command); +#include "command.h" +#include "misc.h" +#include "system.h" int wait_for_chld(int system_pid) @@ -37,8 +34,7 @@ wait_for_chld(int system_pid) while (1) { do { errno = 0; - } while (((pid = waitpid(system_pid, &status, WNOHANG)) == -1) && - (errno == EINTR) || !pid); + } while ((((pid = waitpid(system_pid, &status, WNOHANG)) == -1) && (errno == EINTR)) || !pid); /* If the child that exited is the command we spawned, or if the child exited before fork() returned in the parent, it must be our immediate child that exited. We exit gracefully. */ @@ -50,12 +46,14 @@ wait_for_chld(int system_pid) } else if (WIFSIGNALED(status)) { code = WTERMSIG(status); D_OPTIONS(("wait_for_chld(): Child process was terminated by unhandled signal %lu\n", code)); + } else { + code = 0; } return (code); } errno = save_errno; } - return; + return 0; } /* Replace the system() call with a fork-and-exec that unprivs the child process */ @@ -70,7 +68,7 @@ system_wait(char *command) if (!(pid = fork())) { setreuid(my_ruid, my_ruid); - setreuid(my_rgid, my_rgid); + setregid(my_rgid, my_rgid); execl("/bin/sh", "sh", "-c", command, (char *) NULL); print_error("system_wait(): execl(%s) failed -- %s", command, strerror(errno)); exit(EXIT_FAILURE); @@ -90,7 +88,7 @@ system_no_wait(char *command) if (!(pid = fork())) { setreuid(my_ruid, my_ruid); - setreuid(my_rgid, my_rgid); + setregid(my_rgid, my_rgid); execl("/bin/sh", "sh", "-c", command, (char *) NULL); print_error("system_no_wait(): execl(%s) failed -- %s", command, strerror(errno)); exit(EXIT_FAILURE); diff --git a/src/system.h b/src/system.h index 98f3dbf..48d7746 100644 --- a/src/system.h +++ b/src/system.h @@ -13,9 +13,8 @@ typedef RETSIGTYPE (*sighandler_t)(int); -extern int my_ruid, my_rgid, my_euid, my_egid; - -extern int system_wait(char *command); -extern int system_no_wait(char *command); +extern int wait_for_chld(int); +extern int system_wait(char *); +extern int system_no_wait(char *); #endif /* _SYSTEM_H_ */ diff --git a/src/term.c b/src/term.c new file mode 100644 index 0000000..4928c39 --- /dev/null +++ b/src/term.c @@ -0,0 +1,2023 @@ +/* term.c -- Eterm terminal emulation module + + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +static const char cvs_ident[] = "$Id$"; + +#include "config.h" +#include "feature.h" + +#include +#include +#include +#include + +#include "../libmej/debug.h" +#include "../libmej/mem.h" +#include "../libmej/strings.h" +#include "debug.h" +#include "actions.h" +#include "command.h" +#include "e.h" +#include "events.h" +#include "main.h" +#include "options.h" +#include "pixmap.h" +#include "screen.h" +#include "scrollbar.h" +#include "term.h" +#include "windows.h" + +#ifdef META8_OPTION +unsigned char meta_char = 033; /* Alt-key prefix */ +#endif +unsigned long PrivateModes = PrivMode_Default; +unsigned long SavedModes = PrivMode_Default; +char *def_colorName[] = +{ + "rgb:ff/ff/ff", "rgb:0/0/0", /* fg/bg */ + "rgb:0/0/0", /* 0: black (#000000) */ +#ifndef NO_BRIGHTCOLOR + /* low-intensity colors */ + "rgb:cc/00/00", /* 1: red */ + "rgb:00/cc/00", /* 2: green */ + "rgb:cc/cc/00", /* 3: yellow */ + "rgb:00/00/cc", /* 4: blue */ + "rgb:cc/00/cc", /* 5: magenta */ + "rgb:00/cc/cc", /* 6: cyan */ + "rgb:fa/eb/d7", /* 7: white */ + /* high-intensity colors */ + "rgb:33/33/33", /* 8: bright black */ +#endif /* NO_BRIGHTCOLOR */ + "rgb:ff/00/00", /* 1/9: bright red */ + "rgb:00/ff/00", /* 2/10: bright green */ + "rgb:ff/ff/00", /* 3/11: bright yellow */ + "rgb:00/00/ff", /* 4/12: bright blue */ + "rgb:ff/00/ff", /* 5/13: bright magenta */ + "rgb:00/ff/ff", /* 6/14: bright cyan */ + "rgb:ff/ff/ff", /* 7/15: bright white */ +#ifndef NO_CURSORCOLOR + NULL, NULL, /* cursorColor, cursorColor2 */ +#endif /* NO_CURSORCOLOR */ + NULL, NULL /* pointerColor, borderColor */ +#ifndef NO_BOLDUNDERLINE + ,NULL, NULL /* colorBD, colorUL */ +#endif /* NO_BOLDUNDERLINE */ + ,"rgb:ff/ff/ff" /* menuTextColor */ + ,"rgb:b2/b2/b2" /* scrollColor: match Netscape color */ + ,NULL /* menuColor: match scrollbar color */ + ,NULL /* unfocusedscrollColor: somebody chose black? */ + ,NULL /* unfocusedMenuColor */ +}; +char *rs_color[NRS_COLORS]; +Pixel PixColors[NRS_COLORS + NSHADOWCOLORS]; + +/* Convert the keypress event into a string */ +void +lookup_key(XEvent * ev) +{ + + static int numlock_state = 0; + static unsigned char kbuf[KBUFSZ]; + int ctrl, meta, shft, len; + KeySym keysym; +#ifdef USE_XIM + int valid_keysym; +#endif +#if DEBUG >= DEBUG_CMD + static int debug_key = 1; /* accessible by a debugger only */ +#endif +#ifdef GREEK_SUPPORT + static short greek_mode = 0; +#endif + + /* + * use Num_Lock to toggle Keypad on/off. If Num_Lock is off, allow an + * escape sequence to toggle the Keypad. + * + * Always permit `shift' to override the current setting + */ + shft = (ev->xkey.state & ShiftMask); + ctrl = (ev->xkey.state & ControlMask); + meta = (ev->xkey.state & Mod1Mask); + if (numlock_state || (ev->xkey.state & Mod5Mask)) { + numlock_state = (ev->xkey.state & Mod5Mask); /* numlock toggle */ + PrivMode((!numlock_state), PrivMode_aplKP); + } +#ifdef USE_XIM + if (Input_Context != NULL) { + Status status_return; + + kbuf[0] = '\0'; + len = XmbLookupString(Input_Context, &ev->xkey, kbuf, sizeof(kbuf), + &keysym, &status_return); + valid_keysym = (status_return == XLookupKeySym) || (status_return == XLookupBoth); + } else { + len = XLookupString(&ev->xkey, kbuf, sizeof(kbuf), &keysym, NULL); + } +#else /* USE_XIM */ + len = XLookupString(&ev->xkey, kbuf, sizeof(kbuf), &keysym, NULL); + + /* + * have unmapped Latin[2-4] entries -> Latin1 + * good for installations with correct fonts, but without XLOCALE + */ + if (!len && (keysym >= 0x0100) && (keysym < 0x0400)) { + len = 1; + kbuf[0] = (keysym & 0xff); + } +#endif /* USE_XIM */ + + if (action_dispatch(ev, keysym)) { + return; + } + if (len) { + if (keypress_exit) { + exit(0); + } else if (Options & Opt_homeOnInput) { + TermWin.view_start = 0; + } + } + +#ifdef USE_XIM + if (valid_keysym) { +#endif + + if ((Options & Opt_report_as_keysyms) && (keysym >= 0xff00)) { + len = sprintf(kbuf, "\e[k%X;%X~", (unsigned int) (ev->xkey.state & 0xff), (unsigned int) (keysym & 0xff)); + tt_write(kbuf, len); + return; + } +#ifdef HOTKEY + /* for some backwards compatibility */ + if (HOTKEY) { + if (keysym == ks_bigfont) { + change_font(0, FONT_UP); + return; + } else if (keysym == ks_smallfont) { + change_font(0, FONT_DN); + return; + } + } +#endif + + if (shft) { + /* Shift + F1 - F10 generates F11 - F20 */ + if (keysym >= XK_F1 && keysym <= XK_F10) { + keysym += (XK_F11 - XK_F1); + shft = 0; /* turn off Shift */ + } else if (!ctrl && !meta && (PrivateModes & PrivMode_ShiftKeys)) { + + int lnsppg; /* Lines per page to scroll */ + +#ifdef PAGING_CONTEXT_LINES + lnsppg = TermWin.nrow - PAGING_CONTEXT_LINES; +#else + lnsppg = TermWin.nrow * 4 / 5; +#endif + + switch (keysym) { + /* normal XTerm key bindings */ + case XK_Prior: /* Shift+Prior = scroll back */ + if (TermWin.saveLines) { + scr_page(UP, lnsppg); + return; + } + break; + + case XK_Next: /* Shift+Next = scroll forward */ + if (TermWin.saveLines) { + scr_page(DN, lnsppg); + return; + } + break; + + case XK_Insert: /* Shift+Insert = paste mouse selection */ + selection_request(ev->xkey.time, ev->xkey.x, ev->xkey.y); + return; + break; + + /* Eterm extras */ + case XK_KP_Add: /* Shift+KP_Add = bigger font */ + change_font(0, FONT_UP); + return; + break; + + case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */ + change_font(0, FONT_DN); + return; + break; + } + } + } +#ifdef UNSHIFTED_SCROLLKEYS + else if (!ctrl && !meta) { + switch (keysym) { + case XK_Prior: + if (TermWin.saveLines) { + scr_page(UP, TermWin.nrow * 4 / 5); + return; + } + break; + + case XK_Next: + if (TermWin.saveLines) { + scr_page(DN, TermWin.nrow * 4 / 5); + return; + } + break; + } + } +#endif + + switch (keysym) { + case XK_Print: +#if DEBUG >= DEBUG_SELECTION + if (debug_level >= DEBUG_SELECTION) { + debug_selection(); + } +#endif +#ifdef PRINTPIPE + scr_printscreen(ctrl | shft); + return; +#endif + break; + + case XK_Mode_switch: +#ifdef GREEK_SUPPORT + greek_mode = !greek_mode; + if (greek_mode) { + xterm_seq(XTerm_title, (greek_getmode() == GREEK_ELOT928 ? "[Greek: iso]" : "[Greek: ibm]")); + greek_reset(); + } else + xterm_seq(XTerm_title, APL_NAME "-" VERSION); + return; +#endif + break; + } + + if (keysym >= 0xFF00 && keysym <= 0xFFFF) { +#ifdef KEYSYM_ATTRIBUTE + if (!(shft | ctrl) && KeySym_map[keysym - 0xFF00] != NULL) { + + const unsigned char *kbuf; + unsigned int len; + + kbuf = (KeySym_map[keysym - 0xFF00]); + len = *kbuf++; + + /* escape prefix */ + if (meta +# ifdef META8_OPTION + && (meta_char == 033) +# endif + ) { + const unsigned char ch = '\033'; + + tt_write(&ch, 1); + } + tt_write(kbuf, len); + return; + } else +#endif + switch (keysym) { + case XK_BackSpace: + len = 1; +#ifdef FORCE_BACKSPACE + kbuf[0] = (!(shft | ctrl) ? '\b' : '\177'); +#elif defined(FORCE_DELETE) + kbuf[0] = ((shft | ctrl) ? '\b' : '\177'); +#else + kbuf[0] = (((PrivateModes & PrivMode_BackSpace) ? !(shft | ctrl) : (shft | ctrl)) ? '\b' : '\177'); +#endif + break; + + case XK_Tab: + if (shft) { + len = 3; + strcpy(kbuf, "\033[Z"); + } + break; + +#ifdef XK_KP_Home + case XK_KP_Home: + /* allow shift to override */ + if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { + len = 3; + strcpy(kbuf, "\033Ow"); + break; + } + /* -> else FALL THROUGH */ +#endif + + case XK_Home: + len = strlen(strcpy(kbuf, KS_HOME)); + break; + +#ifdef XK_KP_Left + case XK_KP_Left: /* \033Ot or standard */ + case XK_KP_Up: /* \033Ox or standard */ + case XK_KP_Right: /* \033Ov or standard */ + case XK_KP_Down: /* \033Ow or standard */ + if ((PrivateModes && PrivMode_aplKP) ? !shft : shft) { + len = 3; + strcpy(kbuf, "\033OZ"); + kbuf[2] = ("txvw"[keysym - XK_KP_Left]); + break; + } else { + /* translate to std. cursor key */ + keysym = XK_Left + (keysym - XK_KP_Left); + } + /* FALL THROUGH */ +#endif + case XK_Left: /* "\033[D" */ + case XK_Up: /* "\033[A" */ + case XK_Right: /* "\033[C" */ + case XK_Down: /* "\033[B" */ + len = 3; + strcpy(kbuf, "\033[@"); + kbuf[2] = ("DACB"[keysym - XK_Left]); + if (PrivateModes & PrivMode_aplCUR) { + kbuf[1] = 'O'; + } else if (shft) { /* do Shift first */ + kbuf[2] = ("dacb"[keysym - XK_Left]); + } else if (ctrl) { + kbuf[1] = 'O'; + kbuf[2] = ("dacb"[keysym - XK_Left]); + } + break; +#ifndef UNSHIFTED_SCROLLKEYS +# ifdef XK_KP_Prior + case XK_KP_Prior: + /* allow shift to override */ + if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { + len = 3; + strcpy(kbuf, "\033Oy"); + break; + } + /* -> else FALL THROUGH */ +# endif /* XK_KP_Prior */ + case XK_Prior: + len = 4; + strcpy(kbuf, "\033[5~"); + break; +# ifdef XK_KP_Next + case XK_KP_Next: + /* allow shift to override */ + if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { + len = 3; + strcpy(kbuf, "\033Os"); + break; + } + /* -> else FALL THROUGH */ +# endif /* XK_KP_Next */ + case XK_Next: + len = 4; + strcpy(kbuf, "\033[6~"); + break; +#endif /* UNSHIFTED_SCROLLKEYS */ +#ifdef XK_KP_End + case XK_KP_End: + /* allow shift to override */ + if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { + len = 3; + strcpy(kbuf, "\033Oq"); + break; + } + /* -> else FALL THROUGH */ +#endif /* XK_KP_End */ + case XK_End: + len = strlen(strcpy(kbuf, KS_END)); + break; + + case XK_Select: + len = 4; + strcpy(kbuf, "\033[4~"); + break; + +#ifdef DXK_Remove /* support for DEC remove like key */ + case DXK_Remove: /* drop */ +#endif + case XK_Execute: + len = 4; + strcpy(kbuf, "\033[3~"); + break; + case XK_Insert: + len = 4; + strcpy(kbuf, "\033[2~"); + break; + + case XK_Menu: + len = 5; + strcpy(kbuf, "\033[29~"); + break; + case XK_Find: + len = 4; + strcpy(kbuf, "\033[1~"); + break; + case XK_Help: + len = 5; + strcpy(kbuf, "\033[28~"); + break; + + case XK_KP_Enter: + /* allow shift to override */ + if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { + len = 3; + strcpy(kbuf, "\033OM"); + } else { + len = 1; + kbuf[0] = '\r'; + } + break; + +#ifdef XK_KP_Begin + case XK_KP_Begin: + len = 3; + strcpy(kbuf, "\033Ou"); + break; + + case XK_KP_Insert: + len = 3; + strcpy(kbuf, "\033Op"); + break; + + case XK_KP_Delete: + len = 3; + strcpy(kbuf, "\033On"); + break; +#endif /* XK_KP_Begin */ + + case XK_KP_F1: /* "\033OP" */ + case XK_KP_F2: /* "\033OQ" */ + case XK_KP_F3: /* "\033OR" */ + case XK_KP_F4: /* "\033OS" */ + len = 3; + strcpy(kbuf, "\033OP"); + kbuf[2] += (keysym - XK_KP_F1); + break; + + case XK_KP_Multiply: /* "\033Oj" : "*" */ + case XK_KP_Add: /* "\033Ok" : "+" */ + case XK_KP_Separator: /* "\033Ol" : "," */ + case XK_KP_Subtract: /* "\033Om" : "-" */ + case XK_KP_Decimal: /* "\033On" : "." */ + case XK_KP_Divide: /* "\033Oo" : "/" */ + case XK_KP_0: /* "\033Op" : "0" */ + case XK_KP_1: /* "\033Oq" : "1" */ + case XK_KP_2: /* "\033Or" : "2" */ + case XK_KP_3: /* "\033Os" : "3" */ + case XK_KP_4: /* "\033Ot" : "4" */ + case XK_KP_5: /* "\033Ou" : "5" */ + case XK_KP_6: /* "\033Ov" : "6" */ + case XK_KP_7: /* "\033Ow" : "7" */ + case XK_KP_8: /* "\033Ox" : "8" */ + case XK_KP_9: /* "\033Oy" : "9" */ + /* allow shift to override */ + if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { + len = 3; + strcpy(kbuf, "\033Oj"); + kbuf[2] += (keysym - XK_KP_Multiply); + } else { + len = 1; + kbuf[0] = ('*' + (keysym - XK_KP_Multiply)); + } + break; + +#define FKEY(n,fkey) do { \ +len = 5; \ +sprintf(kbuf,"\033[%02d~", (int)((n) + (keysym - fkey))); \ +} while (0); + + case XK_F1: /* "\033[11~" */ + case XK_F2: /* "\033[12~" */ + case XK_F3: /* "\033[13~" */ + case XK_F4: /* "\033[14~" */ + case XK_F5: /* "\033[15~" */ + FKEY(11, XK_F1); + break; + + case XK_F6: /* "\033[17~" */ + case XK_F7: /* "\033[18~" */ + case XK_F8: /* "\033[19~" */ + case XK_F9: /* "\033[20~" */ + case XK_F10: /* "\033[21~" */ + FKEY(17, XK_F6); + break; + + case XK_F11: /* "\033[23~" */ + case XK_F12: /* "\033[24~" */ + case XK_F13: /* "\033[25~" */ + case XK_F14: /* "\033[26~" */ + FKEY(23, XK_F11); + break; + + case XK_F15: /* "\033[28~" */ + case XK_F16: /* "\033[29~" */ + FKEY(28, XK_F15); + break; + + case XK_F17: /* "\033[31~" */ + case XK_F18: /* "\033[32~" */ + case XK_F19: /* "\033[33~" */ + case XK_F20: /* "\033[34~" */ + case XK_F21: /* "\033[35~" */ + case XK_F22: /* "\033[36~" */ + case XK_F23: /* "\033[37~" */ + case XK_F24: /* "\033[38~" */ + case XK_F25: /* "\033[39~" */ + case XK_F26: /* "\033[40~" */ + case XK_F27: /* "\033[41~" */ + case XK_F28: /* "\033[42~" */ + case XK_F29: /* "\033[43~" */ + case XK_F30: /* "\033[44~" */ + case XK_F31: /* "\033[45~" */ + case XK_F32: /* "\033[46~" */ + case XK_F33: /* "\033[47~" */ + case XK_F34: /* "\033[48~" */ + case XK_F35: /* "\033[49~" */ + FKEY(31, XK_F17); + break; +#undef FKEY +#ifdef KS_DELETE + case XK_Delete: + len = strlen(strcpy(kbuf, KS_DELETE)); + break; +#endif + } + +#ifdef META8_OPTION + if (meta && (meta_char == 0x80) && len > 0) { + kbuf[len - 1] |= 0x80; + } +#endif + } else if (ctrl && keysym == XK_minus) { + len = 1; + kbuf[0] = '\037'; /* Ctrl-Minus generates ^_ (31) */ + } else { +#ifdef META8_OPTION + /* set 8-bit on */ + if (meta && (meta_char == 0x80)) { + + unsigned char *ch; + + for (ch = kbuf; ch < kbuf + len; ch++) + *ch |= 0x80; + meta = 0; + } +#endif +#ifdef GREEK_SUPPORT + if (greek_mode) + len = greek_xlat(kbuf, len); +#endif + } + +#ifdef USE_XIM + } +#endif + + if (len <= 0) + return; /* not mapped */ + + /* + * these modifications only affect the static keybuffer + * pass Shift/Control indicators for function keys ending with `~' + * + * eg, + * Prior = "ESC[5~" + * Shift+Prior = "ESC[5~" + * Ctrl+Prior = "ESC[5^" + * Ctrl+Shift+Prior = "ESC[5@" + */ + if (kbuf[0] == '\033' && kbuf[1] == '[' && kbuf[len - 1] == '~') + kbuf[len - 1] = (shft ? (ctrl ? '@' : '$') : (ctrl ? '^' : '~')); + + /* escape prefix */ + if (meta +#ifdef META8_OPTION + && (meta_char == 033) +#endif + ) { + + const unsigned char ch = '\033'; + + tt_write(&ch, 1); + } +#if DEBUG >= DEBUG_CMD + if (debug_level >= DEBUG_CMD && debug_key) { /* Display keyboard buffer contents */ + + char *p; + int i; + + fprintf(stderr, "key 0x%04X[%d]: `", (unsigned int) keysym, len); + for (i = 0, p = kbuf; i < len; i++, p++) + fprintf(stderr, (*p >= ' ' && *p < '\177' ? "%c" : "\\%03o"), *p); + fprintf(stderr, "'\n"); + } +#endif /* DEBUG_CMD */ + tt_write(kbuf, len); +} + +/* print pipe */ +#ifdef PRINTPIPE +FILE * +popen_printer(void) +{ + FILE *stream = popen(rs_print_pipe, "w"); + + if (stream == NULL) + print_error("can't open printer pipe \"%s\" -- %s", rs_print_pipe, strerror(errno)); + return stream; +} + +int +pclose_printer(FILE * stream) +{ + fflush(stream); + return pclose(stream); +} + +/* simulate attached vt100 printer */ +void +process_print_pipe(void) +{ + const char *const escape_seq = "\033[4i"; + const char *const rev_escape_seq = "i4[\033"; + int index; + FILE *fd; + + if ((fd = popen_printer()) != NULL) { + for (index = 0; index < 4; /* nil */ ) { + unsigned char ch = cmd_getc(); + + if (ch == escape_seq[index]) + index++; + else if (index) + for ( /*nil */ ; index > 0; index--) + fputc(rev_escape_seq[index - 1], fd); + + if (index == 0) + fputc(ch, fd); + } + pclose_printer(fd); + } +} +#endif /* PRINTPIPE */ + +/* process escape sequences */ +void +process_escape_seq(void) +{ + unsigned char ch = cmd_getc(); + + switch (ch) { + /* case 1: do_tek_mode (); break; */ + case '#': + if (cmd_getc() == '8') + scr_E(); + break; + case '(': + scr_charset_set(0, cmd_getc()); + break; + case ')': + scr_charset_set(1, cmd_getc()); + break; + case '*': + scr_charset_set(2, cmd_getc()); + break; + case '+': + scr_charset_set(3, cmd_getc()); + break; +#ifdef MULTI_CHARSET + case '$': + scr_charset_set(-2, cmd_getc()); + break; +#endif + case '7': + scr_cursor(SAVE); + break; + case '8': + scr_cursor(RESTORE); + break; + case '=': + case '>': + PrivMode((ch == '='), PrivMode_aplKP); + break; + case '@': + (void) cmd_getc(); + break; + case 'D': + scr_index(UP); + break; + case 'E': + scr_add_lines("\n\r", 1, 2); + break; + case 'G': + process_graphics(); + break; + case 'H': + scr_set_tab(1); + break; + case 'M': + scr_index(DN); + break; + /*case 'N': scr_single_shift (2); break; */ + /*case 'O': scr_single_shift (3); break; */ + case 'Z': + tt_printf(ESCZ_ANSWER); + break; /* steal obsolete ESC [ c */ + case '[': + process_csi_seq(); + break; + case ']': + process_xterm_seq(); + break; + case 'c': + scr_poweron(); + break; + case 'n': + scr_charset_choose(2); + break; + case 'o': + scr_charset_choose(3); + break; + } +} + +/* process CSI (code sequence introducer) sequences `ESC[' */ +void +process_csi_seq(void) +{ + + unsigned char ch, priv; + unsigned int nargs; + int arg[ESC_ARGS]; + + nargs = 0; + arg[0] = 0; + arg[1] = 0; + + priv = 0; + ch = cmd_getc(); + if (ch >= '<' && ch <= '?') { + priv = ch; + ch = cmd_getc(); + } + /* read any numerical arguments */ + do { + int n; + + for (n = 0; isdigit(ch); ch = cmd_getc()) + n = n * 10 + (ch - '0'); + + if (nargs < ESC_ARGS) + arg[nargs++] = n; + if (ch == '\b') { + scr_backspace(); + } else if (ch == 033) { + process_escape_seq(); + return; + } else if (ch < ' ') { + scr_add_lines(&ch, 0, 1); + return; + } + if (ch < '@') + ch = cmd_getc(); + } + while (ch >= ' ' && ch < '@'); + if (ch == 033) { + process_escape_seq(); + return; + } else if (ch < ' ') + return; + + switch (ch) { +#ifdef PRINTPIPE + case 'i': /* printing */ + switch (arg[0]) { + case 0: + scr_printscreen(0); + break; + case 5: + process_print_pipe(); + break; + } + break; +#endif + case 'A': + case 'e': /* up */ + scr_gotorc((arg[0] ? -arg[0] : -1), 0, RELATIVE); + break; + case 'B': /* down */ + scr_gotorc((arg[0] ? +arg[0] : +1), 0, RELATIVE); + break; + case 'C': + case 'a': /* right */ + scr_gotorc(0, (arg[0] ? +arg[0] : +1), RELATIVE); + break; + case 'D': /* left */ + scr_gotorc(0, (arg[0] ? -arg[0] : -1), RELATIVE); + break; + case 'E': /* down & to first column */ + scr_gotorc((arg[0] ? +arg[0] : +1), 0, R_RELATIVE); + break; + case 'F': /* up & to first column */ + scr_gotorc((arg[0] ? -arg[0] : -1), 0, R_RELATIVE); + break; + case 'G': + case '`': /* move to col */ + scr_gotorc(0, (arg[0] ? arg[0] - 1 : +1), R_RELATIVE); + break; + case 'd': /* move to row */ + scr_gotorc((arg[0] ? arg[0] - 1 : +1), 0, C_RELATIVE); + break; + case 'H': + case 'f': /* position cursor */ + switch (nargs) { + case 0: + scr_gotorc(0, 0, 0); + break; + case 1: + scr_gotorc((arg[0] ? arg[0] - 1 : 0), 0, 0); + break; + default: + scr_gotorc(arg[0] - 1, arg[1] - 1, 0); + break; + } + break; + case 'I': + scr_tab(arg[0] ? +arg[0] : +1); + break; + case 'Z': + scr_tab(arg[0] ? -arg[0] : -1); + break; + case 'J': + scr_erase_screen(arg[0]); + break; + case 'K': + scr_erase_line(arg[0]); + break; + case '@': + scr_insdel_chars((arg[0] ? arg[0] : 1), INSERT); + break; + case 'L': + scr_insdel_lines((arg[0] ? arg[0] : 1), INSERT); + break; + case 'M': + scr_insdel_lines((arg[0] ? arg[0] : 1), DELETE); + break; + case 'X': + scr_insdel_chars((arg[0] ? arg[0] : 1), ERASE); + break; + case 'P': + scr_insdel_chars((arg[0] ? arg[0] : 1), DELETE); + break; + + case 'c': +#ifndef NO_VT100_ANS + tt_printf(VT100_ANS); +#endif + break; + case 'm': + process_sgr_mode(nargs, arg); + break; + case 'n': /* request for information */ + switch (arg[0]) { + case 5: + tt_printf("\033[0n"); + break; /* ready */ + case 6: + scr_report_position(); + break; +#if defined (ENABLE_DISPLAY_ANSWER) + case 7: + tt_printf("%s\n", display_name); + break; +#endif + case 8: + xterm_seq(XTerm_title, APL_NAME "-" VERSION); + break; + case 9: +#ifdef PIXMAP_OFFSET + if (Options & Opt_pixmapTrans) { + char tbuff[70]; + char shading = 0; + unsigned long tint = 0xffffff; + + if (images[image_bg].current->iml->mod) { + shading = images[image_bg].current->iml->mod->brightness / 0xff * 100; + } + if (images[image_bg].current->iml->rmod) { + tint = (tint & 0x00ffff) | ((images[image_bg].current->iml->rmod->brightness & 0xff) << 16); + } + if (images[image_bg].current->iml->gmod) { + tint = (tint & 0xff00ff) | ((images[image_bg].current->iml->gmod->brightness & 0xff) << 8); + } + if (images[image_bg].current->iml->bmod) { + tint = (tint & 0xffff00) | (images[image_bg].current->iml->bmod->brightness & 0xff); + } + snprintf(tbuff, sizeof(tbuff), APL_NAME "-" VERSION ": Transparent - %d%% shading - 0x%06lx tint mask", + shading, tint); + xterm_seq(XTerm_title, tbuff); + } else +#endif +#ifdef PIXMAP_SUPPORT + { + char *tbuff; + unsigned short len; + + if (background_is_pixmap()) { + char *fname = images[image_bg].current->iml->im->filename; + + len = strlen(fname) + sizeof(APL_NAME) + sizeof(VERSION) + 5; + tbuff = MALLOC(len); + snprintf(tbuff, len, APL_NAME "-" VERSION ": %s", fname); + xterm_seq(XTerm_title, tbuff); + FREE(tbuff); + } else { + xterm_seq(XTerm_title, APL_NAME "-" VERSION ": No Pixmap"); + } + } +#endif /* PIXMAP_SUPPORT */ + break; + } + break; + case 'r': /* set top and bottom margins */ + if (priv != '?') { + if (nargs < 2 || arg[0] >= arg[1]) + scr_scroll_region(0, 10000); + else + scr_scroll_region(arg[0] - 1, arg[1] - 1); + break; + } + /* drop */ + case 't': + if (priv != '?') { + process_window_mode(nargs, arg); + break; + } + /* drop */ + case 's': + if (ch == 's' && !nargs) { + scr_cursor(SAVE); + break; + } + /* drop */ + case 'h': + case 'l': + process_terminal_mode(ch, priv, nargs, arg); + break; + case 'u': + if (!nargs) { + scr_cursor(RESTORE); + } + break; + case 'g': + switch (arg[0]) { + case 0: + scr_set_tab(0); + break; /* delete tab */ + case 3: + scr_set_tab(-1); + break; /* clear all tabs */ + } + break; + case 'W': + switch (arg[0]) { + case 0: + scr_set_tab(1); + break; /* = ESC H */ + case 2: + scr_set_tab(0); + break; /* = ESC [ 0 g */ + case 5: + scr_set_tab(-1); + break; /* = ESC [ 3 g */ + } + break; + } +} + +/* process xterm text parameters sequences `ESC ] Ps ; Pt BEL' */ +void +process_xterm_seq(void) +{ + unsigned char ch, string[STRING_MAX]; + int arg; + + ch = cmd_getc(); + if (isdigit(ch)) { + for (arg = 0; isdigit(ch); ch = cmd_getc()) { + arg = arg * 10 + (ch - '0'); + } + } else if (ch == ';') { + arg = 0; + } else { + arg = ch; + ch = cmd_getc(); + } + if (ch == ';') { + unsigned long n = 0; + + while ((ch = cmd_getc()) != 007) { + if (ch) { + if (ch == '\t') + ch = ' '; /* translate '\t' to space */ + else if ((ch < ' ') && !(isspace(ch) && arg == XTerm_EtermIPC)) + return; /* control character - exit */ + + if (n < sizeof(string) - 1) + string[n++] = ch; + } + } + string[n] = '\0'; + xterm_seq(arg, string); + + } else { + unsigned long n = 0; + + for (; ch != '\e'; ch = cmd_getc()) { + if (ch) { + if (ch == '\t') + ch = ' '; /* translate '\t' to space */ + else if (ch < ' ') + return; /* control character - exit */ + + if (n < sizeof(string) - 1) + string[n++] = ch; + } + } + string[n] = '\0'; + + if ((ch = cmd_getc()) != '\\') { + return; + } + switch (arg) { + case 'l': + xterm_seq(XTerm_title, string); + break; + case 'L': + xterm_seq(XTerm_iconName, string); + break; + case 'I': + set_icon_pixmap(string, NULL); + break; + default: + break; + } + } +} + +/* Process window manipulations */ +void +process_window_mode(unsigned int nargs, int args[]) +{ + + register unsigned int i; + unsigned int x, y; + Screen *scr; + Window dummy_child; + char buff[128], *name; + + if (!nargs) + return; + scr = ScreenOfDisplay(Xdisplay, Xscreen); + if (!scr) + return; + + for (i = 0; i < nargs; i++) { + if (args[i] == 14) { + int dummy_x, dummy_y; + unsigned int dummy_border, dummy_depth; + + /* Store current width and height in x and y */ + XGetGeometry(Xdisplay, TermWin.parent, &dummy_child, &dummy_x, &dummy_y, &x, &y, &dummy_border, &dummy_depth); + } + switch (args[i]) { + case 1: + XRaiseWindow(Xdisplay, TermWin.parent); + break; + case 2: + XIconifyWindow(Xdisplay, TermWin.parent, Xscreen); + break; + case 3: + if (i + 2 >= nargs) + return; /* Make sure there are 2 args left */ + x = args[++i]; + y = args[++i]; + if (x > (unsigned long) scr->width || y > (unsigned long) scr->height) + return; /* Don't move off-screen */ + XMoveWindow(Xdisplay, TermWin.parent, x, y); + break; + case 4: + if (i + 2 >= nargs) + return; /* Make sure there are 2 args left */ + y = args[++i]; + x = args[++i]; + XResizeWindow(Xdisplay, TermWin.parent, x, y); +#ifdef USE_XIM + xim_set_status_position(); +#endif + break; + case 5: + XRaiseWindow(Xdisplay, TermWin.parent); + break; + case 6: + XLowerWindow(Xdisplay, TermWin.parent); + break; + case 7: + XClearWindow(Xdisplay, TermWin.vt); + XSync(Xdisplay, False); + scr_touch(); + scr_refresh(SMOOTH_REFRESH); + break; + case 8: + if (i + 2 >= nargs) + return; /* Make sure there are 2 args left */ + y = args[++i]; + x = args[++i]; + XResizeWindow(Xdisplay, TermWin.parent, + Width2Pixel(x) + 2 * TermWin.internalBorder + (scrollbar_visible()? scrollbar_trough_width() : 0), + Height2Pixel(y) + 2 * TermWin.internalBorder); + break; + case 11: + break; + case 13: + XTranslateCoordinates(Xdisplay, TermWin.parent, Xroot, 0, 0, &x, &y, &dummy_child); + snprintf(buff, sizeof(buff), "\e[3;%d;%dt", x, y); + tt_write(buff, strlen(buff)); + break; + case 14: + snprintf(buff, sizeof(buff), "\e[4;%d;%dt", y, x); + tt_write(buff, strlen(buff)); + break; + case 18: + snprintf(buff, sizeof(buff), "\e[8;%d;%dt", TermWin.nrow, TermWin.ncol); + tt_write(buff, strlen(buff)); + break; + case 20: + XGetIconName(Xdisplay, TermWin.parent, &name); + snprintf(buff, sizeof(buff), "\e]L%s\e\\", name); + tt_write(buff, strlen(buff)); + XFree(name); + break; + case 21: + XFetchName(Xdisplay, TermWin.parent, &name); + snprintf(buff, sizeof(buff), "\e]l%s\e\\", name); + tt_write(buff, strlen(buff)); + XFree(name); + break; + default: + break; + } + } +} + +/* process DEC private mode sequences `ESC [ ? Ps mode' */ +/* + * mode can only have the following values: + * 'l' = low + * 'h' = high + * 's' = save + * 'r' = restore + * 't' = toggle + */ +void +process_terminal_mode(int mode, int priv, unsigned int nargs, int arg[]) +{ + unsigned int i; + int state; + + if (nargs == 0) + return; + + /* make lo/hi boolean */ + switch (mode) { + case 'l': + mode = 0; + break; + case 'h': + mode = 1; + break; + } + + switch (priv) { + case 0: + if (mode && mode != 1) + return; /* only do high/low */ + for (i = 0; i < nargs; i++) + switch (arg[i]) { + case 4: + scr_insert_mode(mode); + break; + /* case 38: TEK mode */ + } + break; + + case '?': + for (i = 0; i < nargs; i++) + switch (arg[i]) { + case 1: /* application cursor keys */ + PrivCases(PrivMode_aplCUR); + break; + + /* case 2: - reset charsets to USASCII */ + + case 3: /* 80/132 */ + PrivCases(PrivMode_132); + if (PrivateModes & PrivMode_132OK) + set_width(state ? 132 : 80); + break; + + /* case 4: - smooth scrolling */ + + case 5: /* reverse video */ + PrivCases(PrivMode_rVideo); + scr_rvideo_mode(state); + break; + + case 6: /* relative/absolute origins */ + PrivCases(PrivMode_relOrigin); + scr_relative_origin(state); + break; + + case 7: /* autowrap */ + PrivCases(PrivMode_Autowrap); + scr_autowrap(state); + break; + + /* case 8: - auto repeat, can't do on a per window basis */ + + case 9: /* X10 mouse reporting */ + PrivCases(PrivMode_MouseX10); + /* orthogonal */ + if (PrivateModes & PrivMode_MouseX10) + PrivateModes &= ~(PrivMode_MouseX11); + break; + +#ifdef scrollBar_esc + case scrollBar_esc: + PrivCases(PrivMode_scrollBar); + map_scrollbar(state); + break; +#endif + case 25: /* visible/invisible cursor */ + PrivCases(PrivMode_VisibleCursor); + scr_cursor_visible(state); + break; + + case 35: + PrivCases(PrivMode_ShiftKeys); + break; + + case 40: /* 80 <--> 132 mode */ + PrivCases(PrivMode_132OK); + break; + + case 47: /* secondary screen */ + PrivCases(PrivMode_Screen); + scr_change_screen(state); + break; + + case 66: /* application key pad */ + PrivCases(PrivMode_aplKP); + break; + + case 67: + PrivCases(PrivMode_BackSpace); + break; + + case 1000: /* X11 mouse reporting */ + PrivCases(PrivMode_MouseX11); + /* orthogonal */ + if (PrivateModes & PrivMode_MouseX11) + PrivateModes &= ~(PrivMode_MouseX10); + break; + +#if 0 + case 1001: + break; /* X11 mouse highlighting */ +#endif + case 1010: /* Scroll to bottom on TTY output */ + if (Options & Opt_homeOnEcho) + Options &= ~Opt_homeOnEcho; + else + Options |= Opt_homeOnEcho; + break; + case 1011: /* scroll to bottom on refresh */ + if (Options & Opt_homeOnRefresh) + Options &= ~Opt_homeOnRefresh; + else + Options |= Opt_homeOnRefresh; + break; + case 1012: /* Scroll to bottom on TTY input */ + if (Options & Opt_homeOnInput) + Options &= ~Opt_homeOnInput; + else + Options |= Opt_homeOnInput; + break; + } + break; + } +} + +/* process sgr sequences */ +void +process_sgr_mode(unsigned int nargs, int arg[]) +{ + unsigned int i; + + if (nargs == 0) { + scr_rendition(0, ~RS_None); + return; + } + for (i = 0; i < nargs; i++) + switch (arg[i]) { + case 0: + scr_rendition(0, ~RS_None); + break; + case 1: + scr_rendition(1, RS_Bold); + break; + case 4: + scr_rendition(1, RS_Uline); + break; + case 5: + scr_rendition(1, RS_Blink); + break; + case 7: + scr_rendition(1, RS_RVid); + break; + case 22: + scr_rendition(0, RS_Bold); + break; + case 24: + scr_rendition(0, RS_Uline); + break; + case 25: + scr_rendition(0, RS_Blink); + break; + case 27: + scr_rendition(0, RS_RVid); + break; + + case 30: + case 31: /* set fg color */ + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + scr_color(minColor + (arg[i] - 30), RS_Bold); + break; + case 39: /* default fg */ + scr_color(restoreFG, RS_Bold); + break; + + case 40: + case 41: /* set bg color */ + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + scr_color(minColor + (arg[i] - 40), RS_Blink); + break; + case 49: /* default bg */ + scr_color(restoreBG, RS_Blink); + break; + } +} + +/* process Rob Nation's own graphics mode sequences */ +void +process_graphics(void) +{ + unsigned char ch, cmd = cmd_getc(); + +#ifndef RXVT_GRAPHICS + if (cmd == 'Q') { /* query graphics */ + tt_printf("\033G0\n"); /* no graphics */ + return; + } + /* swallow other graphics sequences until terminating ':' */ + do + ch = cmd_getc(); + while (ch != ':'); +#else + int nargs; + int args[NGRX_PTS]; + unsigned char *text = NULL; + + if (cmd == 'Q') { /* query graphics */ + tt_printf("\033G1\n"); /* yes, graphics (color) */ + return; + } + for (nargs = 0; nargs < (sizeof(args) / sizeof(args[0])) - 1; /*nil */ ) { + int neg; + + ch = cmd_getc(); + neg = (ch == '-'); + if (neg || ch == '+') + ch = cmd_getc(); + + for (args[nargs] = 0; isdigit(ch); ch = cmd_getc()) + args[nargs] = args[nargs] * 10 + (ch - '0'); + if (neg) + args[nargs] = -args[nargs]; + + nargs++; + args[nargs] = 0; + if (ch != ';') + break; + } + + if ((cmd == 'T') && (nargs >= 5)) { + int i, len = args[4]; + + text = MALLOC((len + 1) * sizeof(char)); + + if (text != NULL) { + for (i = 0; i < len; i++) + text[i] = cmd_getc(); + text[len] = '\0'; + } + } + Gr_do_graphics(cmd, nargs, args, text); +#endif +} + +/* color aliases, fg/bg bright-bold */ +void +color_aliases(int idx) +{ + + if (rs_color[idx] && isdigit(*rs_color[idx])) { + + int i = atoi(rs_color[idx]); + + if (i >= 8 && i <= 15) { /* bright colors */ + i -= 8; +#ifndef NO_BRIGHTCOLOR + rs_color[idx] = rs_color[minBright + i]; + return; +#endif + } + if (i >= 0 && i <= 7) /* normal colors */ + rs_color[idx] = rs_color[minColor + i]; + } +} + +/* find if fg/bg matches any of the normal (low-intensity) colors */ +#ifndef NO_BRIGHTCOLOR +void +set_colorfgbg(void) +{ + unsigned int i; + static char *colorfgbg_env = NULL; + char *p; + int fg = -1, bg = -1; + + if (!colorfgbg_env) { + colorfgbg_env = (char *) malloc(30); + strcpy(colorfgbg_env, "COLORFGBG=default;default;bg"); + } + for (i = BlackColor; i <= WhiteColor; i++) { + if (PixColors[fgColor] == PixColors[i]) { + fg = (i - BlackColor); + break; + } + } + for (i = BlackColor; i <= WhiteColor; i++) { + if (PixColors[bgColor] == PixColors[i]) { + bg = (i - BlackColor); + break; + } + } + + p = strchr(colorfgbg_env, '='); + p++; + if (fg >= 0) + sprintf(p, "%d;", fg); + else + strcpy(p, "default;"); + p = strchr(p, '\0'); + if (bg >= 0) + sprintf(p, +# ifdef PIXMAP_SUPPORT + "default;" +# endif + "%d", bg); + else + strcpy(p, "default"); + putenv(colorfgbg_env); + + colorfgbg = DEFAULT_RSTYLE; + for (i = minColor; i <= maxColor; i++) { + if (PixColors[fgColor] == PixColors[i] +# ifndef NO_BOLDUNDERLINE + && PixColors[fgColor] == PixColors[colorBD] +# endif /* NO_BOLDUNDERLINE */ + /* if we wanted boldFont to have precedence */ +# if 0 /* ifndef NO_BOLDFONT */ + && TermWin.boldFont == NULL +# endif /* NO_BOLDFONT */ + ) + colorfgbg = SET_FGCOLOR(colorfgbg, i); + if (PixColors[bgColor] == PixColors[i]) + colorfgbg = SET_BGCOLOR(colorfgbg, i); + } +} +#endif /* NO_BRIGHTCOLOR */ + +/* xterm sequences - title, iconName, color (exptl) */ +#ifdef SMART_WINDOW_TITLE +static void +set_title(const char *str) +{ + + char *name; + + if (XFetchName(Xdisplay, TermWin.parent, &name)) + name = NULL; + if (name == NULL || strcmp(name, str)) + XStoreName(Xdisplay, TermWin.parent, str); + if (name) + XFree(name); +} +#else +# define set_title(str) XStoreName(Xdisplay, TermWin.parent, str) +#endif + +#ifdef SMART_WINDOW_TITLE +static void +set_iconName(const char *str) +{ + + char *name; + + if (XGetIconName(Xdisplay, TermWin.parent, &name)) + name = NULL; + if (name == NULL || strcmp(name, str)) + XSetIconName(Xdisplay, TermWin.parent, str); + if (name) + XFree(name); +} +#else +# define set_iconName(str) XSetIconName(Xdisplay, TermWin.parent, str) +#endif + +/* + * XTerm escape sequences: ESC ] Ps;Pt BEL + * 0 = change iconName/title + * 1 = change iconName + * 2 = change title + * 46 = change logfile (not implemented) + * 50 = change font + * + * rxvt/Eterm extensions: + * 5 = Hostile takeover (grab focus and raise) + * 6 = Transparency mode stuff + * 10 = menu + * 20 = bg pixmap + * 39 = change default fg color + * 49 = change default bg color + */ +void +xterm_seq(int op, const char *str) +{ + + XColor xcol; + char *nstr, *tnstr, *orig_tnstr; + unsigned char eterm_seq_op; +#ifdef PIXMAP_SUPPORT + unsigned char changed = 0, scaled = 0; + char *color, *mod, *valptr; +#endif + + if (!str) + return; + +#ifdef PIXMAP_SUPPORT + orig_tnstr = tnstr = StrDup(str); +#endif + + switch (op) { + case XTerm_title: + set_title(str); + break; + case XTerm_name: + set_title(str); /* drop */ + case XTerm_iconName: + set_iconName(str); + break; + case XTerm_Takeover: + XSetInputFocus(Xdisplay, TermWin.parent, RevertToParent, CurrentTime); + XRaiseWindow(Xdisplay, TermWin.parent); + break; + + case XTerm_EtermSeq: + + /* Eterm proprietary escape sequences + + Syntax: ESC ] 6 ; ; BEL + + where is: 0 Set/toggle transparency + 1 Set color modifiers + 3 Force update of pseudo-transparent background + 10 Set scrollbar type/width + 11 Set/toggle right-side scrollbar + 12 Set/toggle floating scrollbar + 13 Set/toggle popup scrollbar + 20 Set/toggle visual bell + 21 Set/toggle map alert + 22 Set/toggle xterm selection behavior + 23 Set/toggle triple-click line selection + 24 Set/toggle viewport mode + 25 Set/toggle selection of trailing spaces + 30 Do not use + 40 Do not use + 50 Move window to another desktop + 70 Exit Eterm + 71 Save current configuration to a file + and is an optional argument, depending + on the particular sequence being used. It + (along with its preceeding semicolon) may or + may not be needed. + */ + + D_EVENTS(("Got XTerm_EtermSeq sequence\n")); + nstr = strsep(&tnstr, ";"); + eterm_seq_op = (unsigned char) strtol(nstr, (char **) NULL, 10); + D_EVENTS((" XTerm_EtermSeq operation is %d\n", eterm_seq_op)); + /* Yes, there is order to the numbers for this stuff. And here it is: + 0-9 Transparency Configuration + 10-14 Scrollbar Configuration + 15-19 Menu Configuration + 20-29 Miscellaneous Toggles + 30-39 Foreground/Text Color Configuration + 40-49 Background Color Configuration + 50-69 Window/Window Manager Configuration/Interaction + 70-79 Internal Eterm Operations + */ + switch (eterm_seq_op) { +#ifdef PIXMAP_OFFSET + case 0: + nstr = strsep(&tnstr, ";"); + OPT_SET_OR_TOGGLE_NEG(nstr, Options, Opt_pixmapTrans); + if (Options & Opt_pixmapTrans) { + Options &= ~(Opt_pixmapTrans); + } else { + Options |= Opt_pixmapTrans; + if (images[image_bg].current->pmap->pixmap != None) { + Imlib_free_pixmap(imlib_id, images[image_bg].current->pmap->pixmap); + } + images[image_bg].current->pmap->pixmap = None; + } + render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 1); + scr_touch(); + render_simage(images[image_sb].current, scrollBar.win, scrollbar_trough_width(), scrollbar_trough_height(), image_sb, 0); + scrollbar_show(0); + break; + case 1: + color = strsep(&tnstr, ";"); + if (!color) { + break; + } + mod = strsep(&tnstr, ";"); + if (!mod) { + break; + } + valptr = strsep(&tnstr, ";"); + if (!valptr) { + break; + } + D_EVENTS(("Modifying the %s attribute of the %s color modifier to be %s\n", mod, color, valptr)); + if (Options & Opt_pixmapTrans && desktop_pixmap != None) { + free_desktop_pixmap(); + desktop_pixmap = None; /* Force the re-read */ + } + if (Options & Opt_viewport_mode && viewport_pixmap != None) { + XFreePixmap(Xdisplay, viewport_pixmap); + viewport_pixmap = None; /* Force the re-read */ + } + if (!strcasecmp(color, "image")) { + imlib_t *iml = images[image_bg].current->iml; + + if (iml->mod == NULL) { + iml->mod = (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier)); + iml->mod->brightness = iml->mod->contrast = iml->mod->gamma = 0xff; + } + if (!BEG_STRCASECMP("brightness", mod)) { + iml->mod->brightness = (int) strtol(valptr, (char **) NULL, 0); + } else if (!BEG_STRCASECMP("contrast", mod)) { + iml->mod->contrast = (int) strtol(valptr, (char **) NULL, 0); + } else if (!BEG_STRCASECMP("gamma", mod)) { + iml->mod->gamma = (int) strtol(valptr, (char **) NULL, 0); + } + + } else if (!strcasecmp(color, "red")) { + imlib_t *iml = images[image_bg].current->iml; + + if (iml->rmod == NULL) { + iml->rmod = (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier)); + iml->rmod->brightness = iml->rmod->contrast = iml->rmod->gamma = 0xff; + } + if (!BEG_STRCASECMP("brightness", mod)) { + iml->rmod->brightness = (int) strtol(valptr, (char **) NULL, 0); + } else if (!BEG_STRCASECMP("contrast", mod)) { + iml->rmod->contrast = (int) strtol(valptr, (char **) NULL, 0); + } else if (!BEG_STRCASECMP("gamma", mod)) { + iml->rmod->gamma = (int) strtol(valptr, (char **) NULL, 0); + } + + } else if (!strcasecmp(color, "green")) { + imlib_t *iml = images[image_bg].current->iml; + + if (iml->gmod == NULL) { + iml->gmod = (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier)); + iml->gmod->brightness = iml->gmod->contrast = iml->gmod->gamma = 0xff; + } + if (!BEG_STRCASECMP("brightness", mod)) { + iml->gmod->brightness = (int) strtol(valptr, (char **) NULL, 0); + } else if (!BEG_STRCASECMP("contrast", mod)) { + iml->gmod->contrast = (int) strtol(valptr, (char **) NULL, 0); + } else if (!BEG_STRCASECMP("gamma", mod)) { + iml->gmod->gamma = (int) strtol(valptr, (char **) NULL, 0); + } + + } else if (!strcasecmp(color, "blue")) { + imlib_t *iml = images[image_bg].current->iml; + + if (iml->bmod == NULL) { + iml->bmod = (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier)); + iml->bmod->brightness = iml->bmod->contrast = iml->bmod->gamma = 0xff; + } + if (!BEG_STRCASECMP("brightness", mod)) { + iml->bmod->brightness = (int) strtol(valptr, (char **) NULL, 0); + } else if (!BEG_STRCASECMP("contrast", mod)) { + iml->bmod->contrast = (int) strtol(valptr, (char **) NULL, 0); + } else if (!BEG_STRCASECMP("gamma", mod)) { + iml->bmod->gamma = (int) strtol(valptr, (char **) NULL, 0); + } + } + + render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 1); + scr_touch(); + break; + case 3: + if (Options & Opt_pixmapTrans) { + get_desktop_window(); + if (desktop_pixmap != None) { + free_desktop_pixmap(); + } + render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 1); + scr_expose(0, 0, TermWin_TotalWidth(), TermWin_TotalHeight()); + } + break; +#endif + case 10: + nstr = strsep(&tnstr, ";"); + if (nstr && *nstr) { + if (!strcasecmp(nstr, "xterm")) { +#ifdef XTERM_SCROLLBAR + scrollBar.type = SCROLLBAR_XTERM; +#else + print_error("Support for xterm scrollbars was not compiled in. Sorry."); +#endif + } else if (!strcasecmp(nstr, "next")) { +#ifdef NEXT_SCROLLBAR + scrollBar.type = SCROLLBAR_NEXT; +#else + print_error("Support for NeXT scrollbars was not compiled in. Sorry."); +#endif + } else if (!strcasecmp(nstr, "motif")) { +#ifdef MOTIF_SCROLLBAR + scrollBar.type = SCROLLBAR_MOTIF; +#else + print_error("Support for motif scrollbars was not compiled in. Sorry."); +#endif + } else { + print_error("Unrecognized scrollbar type \"%s\".", nstr); + } + scrollbar_reset(); + map_scrollbar(0); + map_scrollbar(1); + scrollbar_show(0); + } + nstr = strsep(&tnstr, ";"); + if (nstr && *nstr) { + scrollBar.width = strtoul(nstr, (char **) NULL, 0); + if (scrollBar.width == 0) { + print_error("Invalid scrollbar length \"%s\".", nstr); + scrollBar.width = SB_WIDTH; + } + scrollbar_reset(); + map_scrollbar(0); + map_scrollbar(1); + scrollbar_show(0); + } + break; + case 11: + nstr = strsep(&tnstr, ";"); + OPT_SET_OR_TOGGLE(nstr, Options, Opt_scrollBar_right); + scrollbar_reset(); + map_scrollbar(0); + map_scrollbar(1); + scrollbar_show(0); + break; + case 12: + nstr = strsep(&tnstr, ";"); + OPT_SET_OR_TOGGLE(nstr, Options, Opt_scrollBar_floating); + scrollbar_reset(); + map_scrollbar(0); + map_scrollbar(1); + scrollbar_show(0); + break; + case 13: + nstr = strsep(&tnstr, ";"); + OPT_SET_OR_TOGGLE(nstr, Options, Opt_scrollbar_popup); + break; + case 20: + nstr = strsep(&tnstr, ";"); + OPT_SET_OR_TOGGLE(nstr, Options, Opt_visualBell); + break; +#ifdef MAPALERT_OPTION + case 21: + nstr = strsep(&tnstr, ";"); + OPT_SET_OR_TOGGLE(nstr, Options, Opt_mapAlert); + break; +#endif + case 22: + nstr = strsep(&tnstr, ";"); + OPT_SET_OR_TOGGLE(nstr, Options, Opt_xterm_select); + break; + case 23: + nstr = strsep(&tnstr, ";"); + OPT_SET_OR_TOGGLE(nstr, Options, Opt_select_whole_line); + break; + case 24: + nstr = strsep(&tnstr, ";"); + OPT_SET_OR_TOGGLE(nstr, Options, Opt_viewport_mode); + render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 1); + scr_touch(); + break; + case 25: + nstr = strsep(&tnstr, ";"); + OPT_SET_OR_TOGGLE(nstr, Options, Opt_select_trailing_spaces); + break; + case 26: + nstr = strsep(&tnstr, ";"); + OPT_SET_OR_TOGGLE(nstr, Options, Opt_report_as_keysyms); + break; + case 30: + nstr = strsep(&tnstr, ";"); + if (nstr) { + if (XParseColor(Xdisplay, cmap, nstr, &xcol) && XAllocColor(Xdisplay, cmap, &xcol)) { + PixColors[fgColor] = xcol.pixel; + scr_refresh(DEFAULT_REFRESH); + } + } + break; + case 40: + nstr = strsep(&tnstr, ";"); + if (nstr) { + if (XParseColor(Xdisplay, cmap, nstr, &xcol) && XAllocColor(Xdisplay, cmap, &xcol)) { + PixColors[bgColor] = xcol.pixel; + scr_refresh(DEFAULT_REFRESH); + } + } + break; + case 50: + /* Change desktops */ + nstr = strsep(&tnstr, ";"); + if (nstr && *nstr) { + XClientMessageEvent xev; + + rs_desktop = (int) strtol(nstr, (char **) NULL, 0); + xev.type = ClientMessage; + xev.window = TermWin.parent; + xev.message_type = XInternAtom(Xdisplay, "_WIN_WORKSPACE", False); + xev.format = 32; + xev.data.l[0] = rs_desktop; + XChangeProperty(Xdisplay, TermWin.parent, xev.message_type, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &rs_desktop, 1); + XSendEvent(Xdisplay, Xroot, False, SubstructureNotifyMask, (XEvent *) & xev); + } + break; + case 70: + /* Exit Eterm */ + exit(0); + break; + case 71: + /* Save current config */ + nstr = strsep(&tnstr, ";"); + if (nstr && *nstr) { + save_config(nstr); + } else { + save_config(NULL); + } + break; + case 80: + /* Set debugging level */ + nstr = strsep(&tnstr, ";"); + if (nstr && *nstr) { + debug_level = (unsigned int) strtoul(nstr, (char **) NULL, 0); + } + break; + + default: + break; + } + break; + + case XTerm_Pixmap: +#ifdef PIXMAP_SUPPORT +# ifdef PIXMAP_OFFSET + if (Options & Opt_pixmapTrans) { + Options &= ~(Opt_pixmapTrans); + } +# endif + if (!strcmp(str, ";")) { + load_image("", image_bg); + bg_needs_update = 1; + } else { + nstr = strsep(&tnstr, ";"); + if (nstr) { + if (*nstr) { + set_pixmap_scale("", images[image_bg].current->pmap); + bg_needs_update = 1; + load_image(nstr, image_bg); + } + while ((nstr = strsep(&tnstr, ";")) && *nstr) { + changed += set_pixmap_scale(nstr, images[image_bg].current->pmap); + scaled = 1; + } + } else { + load_image("", image_bg); + bg_needs_update = 1; + } + } + if ((changed) || (bg_needs_update)) { + render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 1); + scr_touch(); + } +#endif /* PIXMAP_SUPPORT */ + break; + + case XTerm_EtermIPC: + for (; (nstr = strsep(&tnstr, ";"));) { + eterm_ipc_parse(nstr); + } + break; + + case XTerm_restoreFG: +#ifdef XTERM_COLOR_CHANGE + set_window_color(fgColor, str); +#endif + break; + case XTerm_restoreBG: +#ifdef XTERM_COLOR_CHANGE + set_window_color(bgColor, str); +#endif + break; + case XTerm_logfile: + break; + case XTerm_font: + change_font(0, str); + break; +#ifdef ETERM_COMMAND_MODE + case ETerm_command_mode: + fprintf(stderr, "ETerm_command_mode\n"); + break; +#endif + default: + D_CMD(("Unsupported xterm escape sequence operator: 0x%02x\n", op)); + break; + } +#ifdef PIXMAP_SUPPORT + FREE(orig_tnstr); +#endif +} diff --git a/src/term.h b/src/term.h new file mode 100644 index 0000000..21b0ae8 --- /dev/null +++ b/src/term.h @@ -0,0 +1,186 @@ +/* term.h -- Eterm terminal emulation module header file + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _TERM_H_ +#define _TERM_H_ + +#include +#include +#include /* Xlib, Xutil, Xresource, Xfuncproto */ + +/************ Macros and Definitions ************/ +/* Macros to make parsing escape sequences slightly more readable.... */ +#define OPT_SET_OR_TOGGLE(s, mask, bit) do { \ + if (!(s) || !(*(s))) { \ + if ((mask) & (bit)) { \ + (mask) &= ~(bit); \ + } else { \ + (mask) |= (bit); \ + } \ + } else if (BOOL_OPT_ISTRUE(s)) { \ + if ((mask) & (bit)) return; \ + (mask) |= (bit); \ + } else if (BOOL_OPT_ISFALSE(s)) { \ + if (!((mask) & (bit))) return; \ + (mask) &= ~(bit); \ + } \ + } while (0) +/* The macro below forces bit to the opposite state from what we want, so that the + code that follows will set it right. Hackish, but saves space. :) Use this + if you need to do some processing other than just setting the flag right. */ +#define OPT_SET_OR_TOGGLE_NEG(s, mask, bit) do { if (s) { \ + if (BOOL_OPT_ISTRUE(s)) { \ + if ((mask) & (bit)) return; \ + (mask) &= ~(bit); \ + } else if (BOOL_OPT_ISFALSE(s)) { \ + if (!((mask) & (bit))) return; \ + (mask) |= (bit); \ + } \ + } } while (0) + +/* XTerm escape sequences: ESC ] Ps;Pt BEL */ +# define XTerm_name 0 +# define XTerm_iconName 1 +# define XTerm_title 2 +# define XTerm_logfile 46 +# define XTerm_font 50 + +/* rxvt/Eterm extensions of XTerm escape sequences: ESC ] Ps;Pt BEL */ +# define XTerm_Takeover 5 /* Steal keyboard focus and raise window */ +# define XTerm_EtermSeq 6 /* Eterm proprietary escape sequences */ +# define XTerm_EtermIPC 7 /* Eterm escape code/text IPC interface */ +# define XTerm_Pixmap 20 /* new bg pixmap */ +# define XTerm_restoreFG 39 /* change default fg color */ +# define XTerm_restoreBG 49 /* change default bg color */ + +# define restoreFG 39 /* restore default fg color */ +# define restoreBG 49 /* restore default bg color */ + +enum color_list { + fgColor, + bgColor, + minColor, /* 2 */ + BlackColor = minColor, + Red3Color, + Green3Color, + Yellow3Color, + Blue3Color, + Magenta3Color, + Cyan3Color, + maxColor, /* minColor + 7 */ +# ifndef NO_BRIGHTCOLOR + AntiqueWhiteColor = maxColor, + minBright, /* maxColor + 1 */ + Grey25Color = minBright, + RedColor, + GreenColor, + YellowColor, + BlueColor, + MagentaColor, + CyanColor, + maxBright, /* minBright + 7 */ + WhiteColor = maxBright, +# else + WhiteColor = maxColor, +# endif +# ifndef NO_CURSORCOLOR + cursorColor, + cursorColor2, +# endif + pointerColor, + borderColor, +# ifndef NO_BOLDUNDERLINE + colorBD, + colorUL, +# endif + menuTextColor, + scrollColor, + menuColor, + unfocusedScrollColor, + unfocusedMenuColor, + NRS_COLORS, /* */ + topShadowColor = NRS_COLORS, + bottomShadowColor, + unfocusedTopShadowColor, + unfocusedBottomShadowColor, + menuTopShadowColor, + menuBottomShadowColor, + unfocusedMenuTopShadowColor, + unfocusedMenuBottomShadowColor, + TOTAL_COLORS /* */ +}; + +# define NSHADOWCOLORS (TOTAL_COLORS - NRS_COLORS) + +#ifdef HOTKEY_CTRL +# define HOTKEY ctrl +#elif defined(HOTKEY_META) +# define HOTKEY meta +#endif + +#define PrivCases(bit) do {if (mode == 't') state = !(PrivateModes & bit); else state = mode; \ + switch (state) { \ + case 's': SavedModes |= (PrivateModes & bit); continue; break; \ + case 'r': state = (SavedModes & bit) ? 1 : 0; \ + default: PrivMode(state, bit); break; \ + }} while (0) + +/************ Variables ************/ +#ifdef META8_OPTION +extern unsigned char meta_char; /* Alt-key prefix */ +#endif +extern unsigned long PrivateModes; +extern unsigned long SavedModes; +extern char *def_colorName[]; +extern char *rs_color[NRS_COLORS]; +extern Pixel PixColors[NRS_COLORS + NSHADOWCOLORS]; + +/************ Function Prototypes ************/ +_XFUNCPROTOBEGIN + +extern void lookup_key(XEvent *); +#ifdef PRINTPIPE +extern FILE *popen_printer(void); +extern int pclose_printer(FILE *); +extern void process_print_pipe(void); +#endif +extern void process_escape_seq(void); +extern void process_csi_seq(void); +extern void process_xterm_seq(void); +extern void process_window_mode(unsigned int, int []); +extern void process_terminal_mode(int, int, unsigned int, int []); +extern void process_sgr_mode(unsigned int, int []); +extern void process_graphics(void); +extern void color_aliases(int); +#ifndef NO_BRIGHTCOLOR +extern void set_colorfgbg(void); +#else +# define set_colorfgbg() ((void)0) +#endif /* NO_BRIGHTCOLOR */ +extern void xterm_seq(int, const char *); + +_XFUNCPROTOEND + +#endif /* _TERM_H_ */ diff --git a/src/threads.c b/src/threads.c index 7319879..65eacff 100644 --- a/src/threads.c +++ b/src/threads.c @@ -4,9 +4,11 @@ static const char cvs_ident[] = "$Id$"; +#include "config.h" +#include "feature.h" + #include -#include "feature.h" #ifdef USE_POSIX_THREADS # include "main.h" # include "debug.h" diff --git a/src/timer.c b/src/timer.c new file mode 100644 index 0000000..716a7a1 --- /dev/null +++ b/src/timer.c @@ -0,0 +1,132 @@ +/* timer.c -- Eterm timer module + * -- 16 August 1999, mej + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1999-1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +static const char cvs_ident[] = "$Id$"; + +#include "config.h" +#include "feature.h" + +#include +#include +#include +#include + +#include "../libmej/debug.h" +#include "../libmej/strings.h" +#include "debug.h" +#include "main.h" +#include "mem.h" +#include "command.h" +#include "events.h" +#include "options.h" +#include "pixmap.h" +#include "timer.h" + +static timer_t *timers = NULL; + +timerhdl_t +timer_add(unsigned long msec, timer_handler_t handler, void *data) { + + static timer_t *timer; + struct timeval tv; + static struct timezone tz; + + if (!timers) { + timers = (timer_t *) MALLOC(sizeof(timer_t)); + timer = timers; + } else { + timer->next = (timer_t *) MALLOC(sizeof(timer_t)); + timer = timer->next; + } + timer->msec = msec; + gettimeofday(&tv, &tz); + timer->time.tv_sec = (msec / 1000) + tv.tv_sec; + timer->time.tv_usec = ((msec % 1000) * 1000) + tv.tv_usec; + timer->handler = handler; + timer->data = data; + timer->next = NULL; + D_TIMER(("Added timer. Timer set to %lu/%lu with handler 0x%08x and data 0x%08x\n", timer->time.tv_sec, timer->time.tv_usec, timer->handler, timer->data)); + return ((timerhdl_t) timer); +} + +unsigned char +timer_del(timerhdl_t handle) { + + register timer_t *current; + timer_t *temp; + + if (timers == handle) { + timers = handle->next; + FREE(handle); + return 1; + } + for (current = timers; current->next; current = current->next) { + if (current->next == handle) { + break; + } + } + if (!(current->next)) { + return 0; + } + temp = current->next; + current->next = temp->next; + FREE(temp); + return 1; +} + +unsigned char +timer_change_delay(timerhdl_t handle, unsigned long msec) { + + struct timeval tv; + static struct timezone tz; + + handle->msec = msec; + gettimeofday(&tv, &tz); + handle->time.tv_sec = (msec / 1000) + tv.tv_sec; + handle->time.tv_usec = ((msec % 1000) * 1000) + tv.tv_usec; + return 1; +} + +void +timer_check(void) { + + register timer_t *current; + struct timeval tv; + static struct timezone tz; + + if (!timers) return; + + gettimeofday(&tv, &tz); + for (current = timers; current; current = current->next) { + if ((current->time.tv_sec > tv.tv_sec) || ((current->time.tv_sec == tv.tv_sec) && (current->time.tv_usec >= tv.tv_usec))) { + if (!((current->handler)(current->data))) { + timer_del(current); + } else { + timer_change_delay(current, current->msec); + } + } + } +} diff --git a/src/timer.h b/src/timer.h new file mode 100644 index 0000000..a19b4d9 --- /dev/null +++ b/src/timer.h @@ -0,0 +1,64 @@ +/* actions.h -- Eterm action class module header file + * -- 3 August 1999, mej + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1999-1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _TIMER_H_ +#define _TIMER_H_ + +#include +#include +#include +#include /* Xlib, Xutil, Xresource, Xfuncproto */ + +/************ Macros and Definitions ************/ +#define find_timer_by_handle(handle) (handle) +#define timer_change_data(handle, data) ((handle)->data = (data)) +#define timer_change_handler(handle, handler) ((handle)->handler = (handler)) + +/************ Structures ************/ +typedef unsigned char (*timer_handler_t)(void *); +typedef struct timer_struct timer_t; +typedef timer_t *timerhdl_t; /* The timer handles are actually pointers to a timer_t struct, but clients shouldn't use them as such. */ +struct timer_struct { + unsigned long msec; + struct timeval time; + timer_handler_t handler; + void *data; + struct timer_struct *next; +}; + +/************ Variables ************/ + +/************ Function Prototypes ************/ +_XFUNCPROTOBEGIN + +extern timerhdl_t timer_add(unsigned long msec, timer_handler_t handler, void *data); +extern unsigned char timer_del(timerhdl_t handle); +extern unsigned char timer_change_delay(timerhdl_t handle, unsigned long msec); +extern void timer_check(void); + +_XFUNCPROTOEND + +#endif /* _TIMER_H_ */ diff --git a/src/utmp.c b/src/utmp.c index f84b262..2c001de 100644 --- a/src/utmp.c +++ b/src/utmp.c @@ -23,28 +23,21 @@ static const char cvs_ident[] = "$Id$"; -/* includes, defines */ #include "config.h" #include "feature.h" -#include "screen.h" - -int my_ruid, my_euid, my_rgid, my_egid; /* These are needed regardless of utmp support -- mej */ #ifdef UTMP_SUPPORT #include #include - /* For some systems (HP-UX in particular), sys/types.h must be included before utmp*.h -- mej */ #include #include - /* Unsupported/broken utmpx.h on HP-UX, AIX, and glibc 2.1 */ -#if defined(_HPUX_SOURCE) || defined(_AIX) || (defined(__GLIBC__) && __GLIBC__ >= 2) +#if defined(_HPUX_SOURCE) || defined(_AIX) || ((__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)) # undef HAVE_UTMPX_H #endif - #ifdef HAVE_UTMPX_H # include # define USE_SYSV_UTMP @@ -54,7 +47,6 @@ int my_ruid, my_euid, my_rgid, my_egid; /* These are needed regardless of utmp # define USE_SYSV_UTMP # endif #endif - #ifdef TIME_WITH_SYS_TIME # include # include @@ -65,72 +57,37 @@ int my_ruid, my_euid, my_rgid, my_egid; /* These are needed regardless of utmp # include # endif #endif - #ifdef HAVE_UNISTD_H # include #endif -#ifdef HAVE_LASTLOG_H -# include -#endif #include - #include #ifdef HAVE_FCNTL_H # include #endif - -#ifndef UTMP_FILENAME -# ifdef UTMP_FILE -# define UTMP_FILENAME UTMP_FILE -# elif defined(_PATH_UTMP) -# define UTMP_FILENAME _PATH_UTMP -# else -# define UTMP_FILENAME "/etc/utmp" -# endif +#ifdef HAVE_LASTLOG_H +# include +#endif +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__bsdi__) +# include #endif -#ifndef LASTLOG_FILENAME -# ifdef _PATH_LASTLOG -# define LASTLOG_FILENAME _PATH_LASTLOG -# else -# define LASTLOG_FILENAME "/usr/adm/lastlog" /* only on BSD systems */ -# endif -#endif +#include "eterm_utmp.h" +#include "debug.h" +#include "../libmej/debug.h" +#include "command.h" +#include "screen.h" -#ifndef WTMP_FILENAME -# ifdef WTMP_FILE -# define WTMP_FILENAME WTMP_FILE -# elif defined(_PATH_WTMP) -# define WTMP_FILENAME _PATH_WTMP -# elif defined(SYSV) -# define WTMP_FILENAME "/etc/wtmp" -# else -# define WTMP_FILENAME "/usr/adm/wtmp" -# endif -#endif - -#ifndef TTYTAB_FILENAME -# ifdef TTYTAB -# define TTYTAB_FILENAME TTYTAB_FILENAME -# else -# define TTYTAB_FILENAME "/etc/ttytab" -# endif -#endif - -#ifndef USER_PROCESS -# define USER_PROCESS 7 -#endif -#ifndef DEAD_PROCESS -# define DEAD_PROCESS 8 +/* screen.h includes config.h again, so re-fix these. Pointed out by Sung-Hyun Nam */ +#if defined(_HPUX_SOURCE) || defined(_AIX) || ((__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)) +# undef HAVE_UTMPX_H #endif /* don't go off end of ut_id & remember if an entry has been made */ #if defined(USE_SYSV_UTMP) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) static char ut_id[5]; /* remember if entry to utmp made */ - #else static int utmp_pos; /* BSD position of utmp-stamp */ - #endif #ifdef USE_SYSV_UTMP @@ -157,10 +114,6 @@ update_wtmp(char *fname, struct utmp *putmp) lck.l_start = 0; lck.l_type = F_WRLCK; /* we want a write lock */ -# if !defined(EACCESS) && defined(EAGAIN) -# define EACCESS EAGAIN -# endif - /* attempt lock with F_SETLK - F_SETLKW would cause a deadlock! */ while (retry--) { if ((fcntl(fd, F_SETLK, &lck) < 0) && errno != EACCESS) { @@ -187,16 +140,16 @@ update_wtmp(char *fname, struct utmp *putmp) void makeutent(const char *pty, const char *hostname) { - struct passwd *pwent = getpwuid(getuid()); + struct passwd *pwent = getpwuid(my_ruid); #ifdef HAVE_UTMPX_H struct utmpx utmp; struct utmp utmp2; - memset(&utmp, 0, sizeof(struct utmpx)); + MEMSET(&utmp, 0, sizeof(struct utmpx)); #else struct utmp utmp; - memset(&utmp, 0, sizeof(struct utmp)); + MEMSET(&utmp, 0, sizeof(struct utmp)); #endif @@ -255,7 +208,6 @@ makeutent(const char *pty, const char *hostname) pututline(&utmp2); pututxline(&utmp); #else - /* if (!utmpInhibit) */ pututline(&utmp); #endif update_wtmp(WTMP_FILENAME, &utmp); @@ -322,8 +274,6 @@ cleanutent(void) #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__bsdi__) -#include - /* used to hold the line we are using */ static char ut_line[32]; @@ -436,10 +386,10 @@ write_utmp(struct utmp *putmp) void makeutent(const char *pty, const char *hostname) { - struct passwd *pwent = getpwuid(getuid()); + struct passwd *pwent = getpwuid(my_ruid); struct utmp utmp; - memset(&utmp, 0, sizeof(struct utmp)); + MEMSET(&utmp, 0, sizeof(struct utmp)); if (!strncmp(pty, "/dev/", 5)) pty += 5; /* skip /dev/ prefix */ @@ -486,7 +436,7 @@ cleanutent(void) privileges(INVOKE); if (!ut_id[0] && (fd = fopen(UTMP_FILENAME, "r+")) != NULL) { struct utmp utmp; - memset(&utmp, 0, sizeof(struct utmp)); + MEMSET(&utmp, 0, sizeof(struct utmp)); fseek(fd, utmp_pos, 0); fwrite(&utmp, sizeof(struct utmp), 1, fd); diff --git a/src/windows.c b/src/windows.c new file mode 100644 index 0000000..b3c704d --- /dev/null +++ b/src/windows.c @@ -0,0 +1,980 @@ +/* windows.c -- Eterm window handling module + + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +static const char cvs_ident[] = "$Id$"; + +#include "config.h" +#include "feature.h" + +#include +#include +#include +#include +#include + +#include "../libmej/debug.h" +#include "../libmej/mem.h" +#include "../libmej/strings.h" +#include "debug.h" +#include "command.h" +#include "e.h" +#include "events.h" +#include "main.h" +#include "menus.h" +#include "options.h" +#include "pixmap.h" +#include "screen.h" +#include "scrollbar.h" +#include "term.h" +#include "windows.h" + +XWindowAttributes attr; +XSetWindowAttributes Attributes; +XSizeHints szHint = +{ + PMinSize | PResizeInc | PBaseSize | PWinGravity, + 0, 0, 80, 24, /* x, y, width, height */ + 1, 1, /* Min width, height */ + 0, 0, /* Max width, height - unused */ + 1, 1, /* increments: width, height */ + {1, 1}, /* increments: x, y */ + {0, 0}, /* Aspect ratio - unused */ + 0, 0, /* base size: width, height */ + NorthWestGravity /* gravity */ +}; +int font_change_count = 0; +#ifdef MULTI_CHARSET +/* Kanji font names, roman fonts sized to match */ +const char *def_kfontName[] = +{ + KFONT0, KFONT1, KFONT2, KFONT3, KFONT4 +}; +#endif /* MULTI_CHARSET */ +const char *def_fontName[] = +{ + FONT0, FONT1, FONT2, FONT3, FONT4 +}; +Cursor TermWin_cursor; /* cursor for vt window */ + +Pixel +get_bottom_shadow_color(Pixel norm_color, const char *type) +{ + + XColor xcol; + unsigned int r, g, b; + + xcol.pixel = norm_color; + XQueryColor(Xdisplay, cmap, &xcol); + + xcol.red /= 2; + xcol.green /= 2; + xcol.blue /= 2; + r = xcol.red; + g = xcol.green; + b = xcol.blue; + xcol.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); + + if (!XAllocColor(Xdisplay, cmap, &xcol)) { + print_error("Unable to allocate \"%s\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map.", type, xcol.pixel, r, g, b); + xcol.pixel = PixColors[minColor]; + } + return (xcol.pixel); +} + +Pixel +get_top_shadow_color(Pixel norm_color, const char *type) +{ + + XColor xcol, white; + unsigned int r, g, b; + +# ifdef PREFER_24BIT + white.red = white.green = white.blue = r = g = b = ~0; + white.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); + XAllocColor(Xdisplay, cmap, &white); +# else + white.pixel = WhitePixel(Xdisplay, Xscreen); + XQueryColor(Xdisplay, cmap, &white); +# endif + + xcol.pixel = norm_color; + XQueryColor(Xdisplay, cmap, &xcol); + + xcol.red = max((white.red / 5), xcol.red); + xcol.green = max((white.green / 5), xcol.green); + xcol.blue = max((white.blue / 5), xcol.blue); + + xcol.red = min(white.red, (xcol.red * 7) / 5); + xcol.green = min(white.green, (xcol.green * 7) / 5); + xcol.blue = min(white.blue, (xcol.blue * 7) / 5); + r = xcol.red; + g = xcol.green; + b = xcol.blue; + xcol.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); + + if (!XAllocColor(Xdisplay, cmap, &xcol)) { + print_error("Unable to allocate \"%s\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map.", type, xcol.pixel, r, g, b); + xcol.pixel = PixColors[WhiteColor]; + } + return (xcol.pixel); +} + +/* Create_Windows() - Open and map the window */ +void +Create_Windows(int argc, char *argv[]) +{ + + Cursor cursor; + XClassHint classHint; + XWMHints wmHint; + Atom prop = None; + CARD32 val; + int i, x, y, flags; + unsigned int width, height; + unsigned int r, g, b; + MWMHints mwmhints; + + if (Options & Opt_borderless) { + prop = XInternAtom(Xdisplay, "_MOTIF_WM_HINTS", True); + if (prop == None) { + print_warning("Window Manager does not support MWM hints. Bypassing window manager control for borderless window."); + Attributes.override_redirect = TRUE; + mwmhints.flags = 0; + } else { + mwmhints.flags = MWM_HINTS_DECORATIONS; + mwmhints.decorations = 0; + } + } else { + mwmhints.flags = 0; + } + Attributes.save_under = TRUE; + Attributes.backing_store = WhenMapped; + Attributes.colormap = cmap; + + /* + * grab colors before netscape does + */ + for (i = 0; i < (Xdepth <= 2 ? 2 : NRS_COLORS); i++) { + + XColor xcol; + unsigned char found_color = 0; + + if (rs_color[i]) { + if (!XParseColor(Xdisplay, cmap, rs_color[i], &xcol)) { + print_warning("Unable to resolve \"%s\" as a color name. Falling back on \"%s\".", + rs_color[i], def_colorName[i] ? def_colorName[i] : "(nil)"); + rs_color[i] = def_colorName[i]; + if (rs_color[i]) { + if (!XParseColor(Xdisplay, cmap, rs_color[i], &xcol)) { + print_warning("Unable to resolve \"%s\" as a color name. This should never fail. Please repair/restore your RGB database.", rs_color[i]); + found_color = 0; + } else { + found_color = 1; + } + } + } else { + found_color = 1; + } + if (found_color) { + r = xcol.red; + g = xcol.green; + b = xcol.blue; + xcol.pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); + if (!XAllocColor(Xdisplay, cmap, &xcol)) { + print_warning("Unable to allocate \"%s\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map. " + "Falling back on \"%s\".", + rs_color[i], xcol.pixel, r, g, b, def_colorName[i] ? def_colorName[i] : "(nil)"); + rs_color[i] = def_colorName[i]; + if (rs_color[i]) { + if (!XAllocColor(Xdisplay, cmap, &xcol)) { + print_warning("Unable to allocate \"%s\" (0x%08x: 0x%04x, 0x%04x, 0x%04x) in the color map.", + rs_color[i], xcol.pixel, r, g, b); + found_color = 0; + } else { + found_color = 1; + } + } + } else { + found_color = 1; + } + } + } else { + found_color = 0; + } + if (!found_color) { + switch (i) { + case fgColor: + case bgColor: + /* fatal: need bg/fg color */ + fatal_error("Unable to get foreground/background colors!"); + break; +#ifndef NO_CURSORCOLOR + case cursorColor: + xcol.pixel = PixColors[bgColor]; + break; + case cursorColor2: + xcol.pixel = PixColors[fgColor]; + break; +#endif /* NO_CURSORCOLOR */ + case unfocusedMenuColor: + xcol.pixel = PixColors[menuColor]; + break; + case unfocusedScrollColor: + case menuColor: + xcol.pixel = PixColors[scrollColor]; + break; + default: + xcol.pixel = PixColors[bgColor]; /* None */ + break; + } + } + PixColors[i] = xcol.pixel; + } + +#ifndef NO_CURSORCOLOR + if (Xdepth <= 2 || !rs_color[cursorColor]) + PixColors[cursorColor] = PixColors[bgColor]; + if (Xdepth <= 2 || !rs_color[cursorColor2]) + PixColors[cursorColor2] = PixColors[fgColor]; +#endif /* NO_CURSORCOLOR */ + if (Xdepth <= 2 || !rs_color[pointerColor]) + PixColors[pointerColor] = PixColors[fgColor]; + if (Xdepth <= 2 || !rs_color[borderColor]) + PixColors[borderColor] = PixColors[bgColor]; + +#ifndef NO_BOLDUNDERLINE + if (Xdepth <= 2 || !rs_color[colorBD]) + PixColors[colorBD] = PixColors[fgColor]; + if (Xdepth <= 2 || !rs_color[colorUL]) + PixColors[colorUL] = PixColors[fgColor]; +#endif /* NO_BOLDUNDERLINE */ + + /* + * get scrollBar/menu shadow colors + * + * The calculations of topShadow/bottomShadow values are adapted + * from the fvwm window manager. + */ + if (Xdepth <= 2) { /* Monochrome */ + PixColors[scrollColor] = PixColors[bgColor]; + PixColors[topShadowColor] = PixColors[fgColor]; + PixColors[bottomShadowColor] = PixColors[fgColor]; + + PixColors[unfocusedScrollColor] = PixColors[bgColor]; + PixColors[unfocusedTopShadowColor] = PixColors[fgColor]; + PixColors[unfocusedBottomShadowColor] = PixColors[fgColor]; + + PixColors[menuColor] = PixColors[bgColor]; + PixColors[menuTopShadowColor] = PixColors[fgColor]; + PixColors[menuBottomShadowColor] = PixColors[fgColor]; + + PixColors[unfocusedMenuColor] = PixColors[bgColor]; + PixColors[unfocusedMenuTopShadowColor] = PixColors[fgColor]; + PixColors[unfocusedMenuBottomShadowColor] = PixColors[fgColor]; + } else { + PixColors[bottomShadowColor] = get_bottom_shadow_color(PixColors[scrollColor], "bottomShadowColor"); + PixColors[unfocusedBottomShadowColor] = get_bottom_shadow_color(PixColors[unfocusedScrollColor], "unfocusedBottomShadowColor"); + PixColors[topShadowColor] = get_top_shadow_color(PixColors[scrollColor], "topShadowColor"); + PixColors[unfocusedTopShadowColor] = get_top_shadow_color(PixColors[unfocusedScrollColor], "unfocusedTopShadowColor"); + + PixColors[menuBottomShadowColor] = get_bottom_shadow_color(PixColors[menuColor], "menuBottomShadowColor"); + PixColors[unfocusedMenuBottomShadowColor] = get_bottom_shadow_color(PixColors[unfocusedMenuColor], "unfocusedMenuBottomShadowColor"); + PixColors[menuTopShadowColor] = get_top_shadow_color(PixColors[menuColor], "menuTopShadowColor"); + PixColors[unfocusedMenuTopShadowColor] = get_top_shadow_color(PixColors[unfocusedMenuColor], "unfocusedMenuTopShadowColor"); + } + + szHint.base_width = (2 * TermWin.internalBorder + (Options & Opt_scrollBar ? scrollbar_trough_width() : 0)); + szHint.base_height = (2 * TermWin.internalBorder); + + flags = (rs_geometry ? XParseGeometry(rs_geometry, &x, &y, &width, &height) : 0); + D_X11(("XParseGeometry(geom, %d, %d, %d, %d)\n", x, y, width, height)); + + if (flags & WidthValue) { + szHint.width = width; + szHint.flags |= USSize; + } + if (flags & HeightValue) { + szHint.height = height; + szHint.flags |= USSize; + } + TermWin.ncol = szHint.width; + TermWin.nrow = szHint.height; + + change_font(1, NULL); + + if (flags & XValue) { + if (flags & XNegative) { + if (check_for_enlightenment()) { + x += (DisplayWidth(Xdisplay, Xscreen)); + } else { + x += (DisplayWidth(Xdisplay, Xscreen) - (szHint.width + TermWin.internalBorder)); + } + szHint.win_gravity = NorthEastGravity; + } + szHint.x = x; + szHint.flags |= USPosition; + } + if (flags & YValue) { + if (flags & YNegative) { + if (check_for_enlightenment()) { + y += (DisplayHeight(Xdisplay, Xscreen) - (2 * TermWin.internalBorder)); + } else { + y += (DisplayHeight(Xdisplay, Xscreen) - (szHint.height + TermWin.internalBorder)); + } + szHint.win_gravity = (szHint.win_gravity == NorthEastGravity ? + SouthEastGravity : SouthWestGravity); + } + szHint.y = y; + szHint.flags |= USPosition; + } + D_X11(("Geometry values after parsing: %dx%d%+d%+d\n", width, height, x, y)); + + /* parent window - reverse video so we can see placement errors + * sub-window placement & size in resize_subwindows() + */ + + Attributes.background_pixel = PixColors[bgColor]; + Attributes.border_pixel = PixColors[bgColor]; + TermWin.parent = XCreateWindow(Xdisplay, Xroot, szHint.x, szHint.y, szHint.width, szHint.height, 0, Xdepth, InputOutput, +#ifdef PREFER_24BIT + Xvisual, +#else + CopyFromParent, +#endif + CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect, &Attributes); + + xterm_seq(XTerm_title, rs_title); + xterm_seq(XTerm_iconName, rs_iconName); + classHint.res_name = (char *) rs_name; + classHint.res_class = APL_NAME; + wmHint.window_group = TermWin.parent; + wmHint.input = True; + wmHint.initial_state = (Options & Opt_iconic ? IconicState : NormalState); + wmHint.window_group = TermWin.parent; + wmHint.flags = (InputHint | StateHint | WindowGroupHint); +#ifdef PIXMAP_SUPPORT + set_icon_pixmap(rs_icon, &wmHint); +#endif + + XSetWMProperties(Xdisplay, TermWin.parent, NULL, NULL, argv, argc, &szHint, &wmHint, &classHint); + XSelectInput(Xdisplay, TermWin.parent, (KeyPressMask | FocusChangeMask | StructureNotifyMask | VisibilityChangeMask | PropertyChangeMask)); + if (mwmhints.flags) { + XChangeProperty(Xdisplay, TermWin.parent, prop, prop, 32, PropModeReplace, (unsigned char *) &mwmhints, PROP_MWM_HINTS_ELEMENTS); + } + /* vt cursor: Black-on-White is standard, but this is more popular */ + TermWin_cursor = XCreateFontCursor(Xdisplay, XC_xterm); + { + + XColor fg, bg; + + fg.pixel = PixColors[pointerColor]; + XQueryColor(Xdisplay, cmap, &fg); + bg.pixel = PixColors[bgColor]; + XQueryColor(Xdisplay, cmap, &bg); + XRecolorCursor(Xdisplay, TermWin_cursor, &fg, &bg); + } + + /* cursor (menu/scrollbar): Black-on-White */ + cursor = XCreateFontCursor(Xdisplay, XC_left_ptr); + + /* the vt window */ + +#ifdef BACKING_STORE + if ((!(Options & Opt_borderless)) && (Options & Opt_saveUnder)) { + D_X11(("Creating term window with save_under = TRUE\n")); + TermWin.vt = XCreateWindow(Xdisplay, TermWin.parent, 0, 0, szHint.width, szHint.height, 0, Xdepth, InputOutput, CopyFromParent, + CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWColormap, &Attributes); + if (!(background_is_pixmap()) && !(Options & Opt_borderless)) { + XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); + XClearWindow(Xdisplay, TermWin.vt); + } + } else +#endif + { + D_X11(("Creating term window with no backing store\n")); + TermWin.vt = XCreateWindow(Xdisplay, TermWin.parent, 0, 0, szHint.width, szHint.height, 0, Xdepth, InputOutput, CopyFromParent, + CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWColormap, &Attributes); + if (!(background_is_pixmap()) && !(Options & Opt_borderless)) { + XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); + XClearWindow(Xdisplay, TermWin.vt); + } + } + + XDefineCursor(Xdisplay, TermWin.vt, TermWin_cursor); + XSelectInput(Xdisplay, TermWin.vt, (ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask | Button3MotionMask)); + + /* If the user wants a specific desktop, tell the WM that */ + if (rs_desktop != -1) { + prop = XInternAtom(Xdisplay, "_WIN_WORKSPACE", False); + val = rs_desktop; + XChangeProperty(Xdisplay, TermWin.parent, prop, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &val, 1); + } + XMapWindow(Xdisplay, TermWin.vt); + XMapWindow(Xdisplay, TermWin.parent); + + XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); + XClearWindow(Xdisplay, TermWin.vt); + +#ifdef PIXMAP_SUPPORT + if (background_is_image()) { + render_simage(images[image_bg].norm, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 0); + } +#endif /* PIXMAP_SUPPORT */ + + /* graphics context for the vt window */ + { + XGCValues gcvalue; + + gcvalue.font = TermWin.font->fid; + gcvalue.foreground = PixColors[fgColor]; + gcvalue.background = PixColors[bgColor]; + gcvalue.graphics_exposures = 0; + TermWin.gc = XCreateGC(Xdisplay, TermWin.vt, GCForeground | GCBackground | GCFont | GCGraphicsExposures, &gcvalue); + } + + if (Options & Opt_noCursor) + scr_cursor_visible(0); + + /* We're done creating our windows. Now let's initialize the event subsystem to handle them. */ + event_init_subsystem((event_dispatcher_t) process_x_event, (event_dispatcher_init_t) event_init_primary_dispatcher); + + /* Time for the scrollbar to create its windows and add itself to the event subsystem. */ + scrollbar_init(); + + /* Same for the menu subsystem. */ + menu_init(); + +} + +/* window resizing - assuming the parent window is the correct size */ +void +resize_subwindows(int width, int height) +{ + + int x = 0, y = 0; + +#ifdef RXVT_GRAPHICS + int old_width = TermWin.width; + int old_height = TermWin.height; + +#endif + + D_SCREEN(("resize_subwindows(%d, %d)\n", width, height)); + TermWin.width = TermWin.ncol * TermWin.fwidth; + TermWin.height = TermWin.nrow * TermWin.fheight; + + /* size and placement */ + if (scrollbar_visible()) { + scrollBar.beg = 0; + scrollBar.end = height; +#ifdef MOTIF_SCROLLBAR + if (scrollBar.type == SCROLLBAR_MOTIF) { + /* arrows are as high as wide - leave 1 pixel gap */ + scrollBar.beg += scrollbar_arrow_height() + scrollbar_get_shadow() + 1; + scrollBar.end -= scrollbar_arrow_height() + scrollbar_get_shadow() + 1; + } +#endif +#ifdef NEXT_SCROLLBAR + if (scrollBar.type == SCROLLBAR_NEXT) { + scrollBar.beg = scrollbar_get_shadow(); + scrollBar.end -= (scrollBar.width * 2 + (scrollbar_get_shadow()? scrollbar_get_shadow() : 1) + 2); + } +#endif + width -= scrollbar_trough_width(); + XMoveResizeWindow(Xdisplay, scrollBar.win, + ((Options & Opt_scrollBar_right) ? (width) : (x)), + 0, scrollbar_trough_width(), height); + if (scrollbar_is_pixmapped()) { + render_simage(images[image_sb].current, scrollBar.win, scrollbar_trough_width(), scrollbar_trough_height(), image_sb, 0); + } + if (!(Options & Opt_scrollBar_right)) { + x = scrollbar_trough_width(); + } + } + XMoveResizeWindow(Xdisplay, TermWin.vt, x, y, width, height + 1); + +#ifdef RXVT_GRAPHICS + if (old_width) + Gr_Resize(old_width, old_height); +#endif + XClearWindow(Xdisplay, TermWin.vt); + if (!(background_is_pixmap())) + XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); + +#ifdef PIXMAP_SUPPORT +# ifdef USE_POSIX_THREADS + + D_PIXMAP(("resize_subwindows(): start_bg_thread()\n")); + pthread_attr_init(&resize_sub_thr_attr); + +# ifdef MUTEX_SYNCH + if (pthread_mutex_trylock(&mutex) == EBUSY) { + D_THREADS(("resize_subwindows(): mutex locked, bbl\n")); + } else { + D_THREADS(("pthread_mutex_trylock(&mutex): ")); + pthread_mutex_unlock(&mutex); + D_THREADS(("pthread_mutex_unlock(&mutex)\n")); + } +# endif + + if (!(pthread_create(&resize_sub_thr, &resize_sub_thr_attr, + (void *) &render_bg_thread, NULL))) { + /* bg_set = 0; */ + D_THREADS(("thread created\n")); + } else { + D_THREADS(("pthread_create() failed!\n")); + } + +# else + D_PIXMAP(("resize_subwindows(): render_pixmap(TermWin.vt)\n")); + render_simage(images[image_bg].current, TermWin.vt, TermWin_TotalWidth(), TermWin_TotalHeight(), image_bg, 1); + XSync(Xdisplay, 0); +# endif +#endif +} + +void +resize(void) +{ + szHint.base_width = (2 * TermWin.internalBorder); + szHint.base_height = (2 * TermWin.internalBorder); + + szHint.base_width += (scrollbar_visible()? scrollbar_trough_width() : 0); + + szHint.min_width = szHint.base_width + szHint.width_inc; + szHint.min_height = szHint.base_height + szHint.height_inc; + + szHint.width = szHint.base_width + TermWin.width; + szHint.height = szHint.base_height + TermWin.height; + + szHint.flags = PMinSize | PResizeInc | PBaseSize | PWinGravity; + + XSetWMNormalHints(Xdisplay, TermWin.parent, &szHint); + XResizeWindow(Xdisplay, TermWin.parent, szHint.width, szHint.height); + + resize_subwindows(szHint.width, szHint.height); +} + +/* + * Redraw window after exposure or size change + */ +void +resize_window1(unsigned int width, unsigned int height) +{ + static short first_time = 1; + int new_ncol = (width - szHint.base_width) / TermWin.fwidth; + int new_nrow = (height - szHint.base_height) / TermWin.fheight; + + if (first_time || + (new_ncol != TermWin.ncol) || + (new_nrow != TermWin.nrow)) { + int curr_screen = -1; + + /* scr_reset only works on the primary screen */ + if (!first_time) { /* this is not the first time thru */ + selection_clear(); + curr_screen = scr_change_screen(PRIMARY); + } + TermWin.ncol = new_ncol; + TermWin.nrow = new_nrow; + + resize_subwindows(width, height); + scr_reset(); + + if (curr_screen >= 0) /* this is not the first time thru */ + scr_change_screen(curr_screen); + first_time = 0; + } else if (Options & Opt_pixmapTrans || Options & Opt_viewport_mode) { + resize_subwindows(width, height); + scrollbar_show(0); + scr_expose(0, 0, width, height); + } +} + +/* + * good for toggling 80/132 columns + */ +void +set_width(unsigned short width) +{ + unsigned short height = TermWin.nrow; + + if (width != TermWin.ncol) { + width = szHint.base_width + width * TermWin.fwidth; + height = szHint.base_height + height * TermWin.fheight; + + XResizeWindow(Xdisplay, TermWin.parent, width, height); + resize_window1(width, height); + } +} + +/* + * Redraw window after exposure or size change + */ +void +resize_window(void) +{ + Window root; + XEvent dummy; + int x, y; + unsigned int border, depth, width, height; + + while (XCheckTypedWindowEvent(Xdisplay, TermWin.parent, + ConfigureNotify, &dummy)); + + /* do we come from an fontchange? */ + if (font_change_count > 0) { + font_change_count--; + return; + } + XGetGeometry(Xdisplay, TermWin.parent, &root, &x, &y, &width, &height, &border, &depth); + + /* parent already resized */ + + resize_window1(width, height); +} + +#ifdef XTERM_COLOR_CHANGE +void +set_window_color(int idx, const char *color) +{ + + XColor xcol; + int i; + unsigned int pixel, r, g, b; + + if (color == NULL || *color == '\0') + return; + + /* handle color aliases */ + if (isdigit(*color)) { + i = atoi(color); + if (i >= 8 && i <= 15) { /* bright colors */ + i -= 8; +# ifndef NO_BRIGHTCOLOR + PixColors[idx] = PixColors[minBright + i]; + goto Done; +# endif + } + if (i >= 0 && i <= 7) { /* normal colors */ + PixColors[idx] = PixColors[minColor + i]; + goto Done; + } + } + if (XParseColor(Xdisplay, cmap, color, &xcol)) { + r = xcol.red; + g = xcol.green; + b = xcol.blue; + pixel = Imlib_best_color_match(imlib_id, &r, &g, &b); + xcol.pixel = pixel; + if (!XAllocColor(Xdisplay, cmap, &xcol)) { + print_warning("Unable to allocate \"%s\" in the color map.\n", color); + return; + } + } else { + print_warning("Unable to resolve \"%s\" as a color name.\n", color); + return; + } + + /* + * FIXME: should free colors here, but no idea how to do it so instead, + * so just keep gobbling up the colormap + */ +# if 0 + for (i = BlackColor; i <= WhiteColor; i++) + if (PixColors[idx] == PixColors[i]) + break; + if (i > WhiteColor) { + /* fprintf (stderr, "XFreeColors: PixColors[%d] = %lu\n", idx, PixColors[idx]); */ + XFreeColors(Xdisplay, cmap, (PixColors + idx), 1, + DisplayPlanes(Xdisplay, Xscreen)); + } +# endif + + PixColors[idx] = xcol.pixel; + + /* XSetWindowAttributes attr; */ + /* Cursor cursor; */ +Done: + if (idx == bgColor) + XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]); + + /* handle colorBD, scrollbar background, etc. */ + + set_colorfgbg(); + { + + XColor fg, bg; + + fg.pixel = PixColors[fgColor]; + XQueryColor(Xdisplay, cmap, &fg); + bg.pixel = PixColors[bgColor]; + XQueryColor(Xdisplay, cmap, &bg); + + XRecolorCursor(Xdisplay, TermWin_cursor, &fg, &bg); + } + /* the only reasonable way to enforce a clean update */ + scr_poweron(); +} +#else +# define set_window_color(idx,color) ((void)0) +#endif /* XTERM_COLOR_CHANGE */ + +/* load_font(): Load a new font and return a pointer to it. */ +XFontStruct * +load_font(const char *fontname) +{ + + XFontStruct *xfont; + const char *fallback = "fixed"; + + ASSERT_RVAL(fontname != NULL, NULL); + + xfont = XLoadQueryFont(Xdisplay, fontname); + if (!xfont) { + print_error("Unable to load font \"%s\". Falling back on \"%s\"\n", fontname, fallback); + xfont = XLoadQueryFont(Xdisplay, fallback); + if (!xfont) { + fatal_error("Unable to load font \"%s\". Unable to continue.\n", fallback); + } + } + return (xfont); +} + +/* change_font() - Switch to a new font */ +/* + * init = 1 - initialize + * + * fontname == FONT_UP - switch to bigger font + * fontname == FONT_DN - switch to smaller font + */ +void +change_font(int init, const char *fontname) +{ + const char *const msg = "can't load font \"%s\""; + XFontStruct *xfont; + static char *newfont[NFONTS]; +#ifndef NO_BOLDFONT + static XFontStruct *boldFont = NULL; +#endif + static int fnum = FONT0_IDX; /* logical font number */ + int idx = 0; /* index into rs_font[] */ + + if (!init) { + switch (fontname[0]) { + case '\0': + fnum = FONT0_IDX; + fontname = NULL; + break; + + /* special (internal) prefix for font commands */ + case FONT_CMD: + idx = atoi(fontname + 1); + switch (fontname[1]) { + case '+': /* corresponds to FONT_UP */ + fnum += (idx ? idx : 1); + fnum = FNUM_RANGE(fnum); + break; + + case '-': /* corresponds to FONT_DN */ + fnum += (idx ? idx : -1); + fnum = FNUM_RANGE(fnum); + break; + + default: + if (fontname[1] != '\0' && !isdigit(fontname[1])) + return; + if (idx < 0 || idx >= (NFONTS)) + return; + fnum = IDX2FNUM(idx); + break; + } + fontname = NULL; + break; + + default: + if (fontname != NULL) { + /* search for existing fontname */ + for (idx = 0; idx < NFONTS; idx++) { + if (!strcmp(rs_font[idx], fontname)) { + fnum = IDX2FNUM(idx); + fontname = NULL; + break; + } + } + } else + return; + break; + } + /* re-position around the normal font */ + idx = FNUM2IDX(fnum); + + if (fontname != NULL) { + char *name; + + xfont = XLoadQueryFont(Xdisplay, fontname); + if (!xfont) + return; + + name = MALLOC(strlen(fontname + 1) * sizeof(char)); + + if (name == NULL) { + XFreeFont(Xdisplay, xfont); + return; + } + strcpy(name, fontname); + if (newfont[idx] != NULL) + FREE(newfont[idx]); + newfont[idx] = name; + rs_font[idx] = newfont[idx]; + } + } + if (TermWin.font) + XFreeFont(Xdisplay, TermWin.font); + + /* load font or substitute */ + xfont = XLoadQueryFont(Xdisplay, rs_font[idx]); + if (!xfont) { + print_error(msg, rs_font[idx]); + rs_font[idx] = "fixed"; + xfont = XLoadQueryFont(Xdisplay, rs_font[idx]); + if (!xfont) { + print_error(msg, rs_font[idx]); + ABORT(); + } + } + TermWin.font = xfont; + +#ifndef NO_BOLDFONT + /* fail silently */ + if (init && rs_boldFont != NULL) + boldFont = XLoadQueryFont(Xdisplay, rs_boldFont); +#endif + +#ifdef MULTI_CHARSET + if (TermWin.mfont) + XFreeFont(Xdisplay, TermWin.mfont); + + /* load font or substitute */ + xfont = XLoadQueryFont(Xdisplay, rs_mfont[idx]); + if (!xfont) { + print_error(msg, rs_mfont[idx]); + rs_mfont[idx] = "k14"; + xfont = XLoadQueryFont(Xdisplay, rs_mfont[idx]); + if (!xfont) { + print_error(msg, rs_mfont[idx]); + ABORT(); + } + } + TermWin.mfont = xfont; +# ifdef USE_XIM + if (Input_Context) { + if (TermWin.fontset) + XFreeFontSet(Xdisplay, TermWin.fontset); + TermWin.fontset = create_fontset(rs_font[idx], rs_mfont[idx]); + xim_set_fontset(); + } +# endif +#endif /* MULTI_CHARSET */ + + /* alter existing GC */ + if (!init) { + XSetFont(Xdisplay, TermWin.gc, TermWin.font->fid); + } + /* set the sizes */ + { + + int cw, fh, fw = 0; + unsigned long i; + + fw = TermWin.font->min_bounds.width; + fh = TermWin.font->ascent + TermWin.font->descent + rs_line_space; + + D_X11(("Font information: Ascent == %hd, Descent == %hd\n", TermWin.font->ascent, TermWin.font->descent)); + if (TermWin.font->min_bounds.width == TermWin.font->max_bounds.width) + TermWin.fprop = 0; /* Mono-spaced (fixed width) font */ + else + TermWin.fprop = 1; /* Proportional font */ + if (TermWin.fprop == 1) + for (i = TermWin.font->min_char_or_byte2; + i <= TermWin.font->max_char_or_byte2; i++) { + cw = TermWin.font->per_char[i].width; + MAX_IT(fw, cw); + } + /* not the first time thru and sizes haven't changed */ + if (fw == TermWin.fwidth && fh == TermWin.fheight) + return; /* TODO: not return; check MULTI_CHARSET if needed */ + + TermWin.fwidth = fw; + TermWin.fheight = fh; + } + + /* check that size of boldFont is okay */ +#ifndef NO_BOLDFONT + TermWin.boldFont = NULL; + if (boldFont != NULL) { + int i, cw, fh, fw = 0; + + fw = boldFont->min_bounds.width; + fh = boldFont->ascent + boldFont->descent + rs_line_space; + if (TermWin.fprop == 0) { /* bold font must also be monospaced */ + if (fw != boldFont->max_bounds.width) + fw = -1; + } else { + for (i = 0; i < 256; i++) { + if (!isprint(i)) + continue; + cw = boldFont->per_char[i].width; + MAX_IT(fw, cw); + } + } + + if (fw == TermWin.fwidth && fh == TermWin.fheight) + TermWin.boldFont = boldFont; + } +#endif /* NO_BOLDFONT */ + + set_colorfgbg(); + + TermWin.width = TermWin.ncol * TermWin.fwidth; + TermWin.height = TermWin.nrow * TermWin.fheight; + + szHint.width_inc = TermWin.fwidth; + szHint.height_inc = TermWin.fheight; + + szHint.min_width = szHint.base_width + szHint.width_inc; + szHint.min_height = szHint.base_height + szHint.height_inc; + + szHint.width = szHint.base_width + TermWin.width; + szHint.height = szHint.base_height + TermWin.height; + + szHint.flags = PMinSize | PResizeInc | PBaseSize | PWinGravity; + + if (!init) { + font_change_count++; + resize(); + } + return; +} diff --git a/src/windows.h b/src/windows.h new file mode 100644 index 0000000..8b58cf3 --- /dev/null +++ b/src/windows.h @@ -0,0 +1,83 @@ +/* windows.h -- Eterm window handling module header file + * -- 29 April 1999, mej + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . This file, and any other file + * bearing this same message or a similar one, is distributed under + * the GNU Public License (GPL) as outlined in the COPYING file. + * + * Copyright (C) 1997, Michael Jennings and Tuomo Venalainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _WINDOWS_H_ +#define _WINDOWS_H_ +/* includes */ +#include +#include /* Xlib, Xutil, Xresource, Xfuncproto */ + +/************ Macros and Definitions ************/ +# define NFONTS 5 +/* special (internal) prefix for font commands */ +# define FONT_CMD '#' +# define FONT_DN "#-" +# define FONT_UP "#+" +#if (FONT0_IDX == 0) +# define IDX2FNUM(i) (i) +# define FNUM2IDX(f) (f) +#else +# define IDX2FNUM(i) (i == 0? FONT0_IDX : (i <= FONT0_IDX? (i-1) : i)) +# define FNUM2IDX(f) (f == FONT0_IDX ? 0 : (f < FONT0_IDX ? (f+1) : f)) +#endif +#define FNUM_RANGE(i) (i <= 0 ? 0 : (i >= NFONTS ? (NFONTS-1) : i)) + +/************ Variables ************/ +extern char *rs_color[NRS_COLORS]; +extern Pixel PixColors[NRS_COLORS + NSHADOWCOLORS]; +extern XSetWindowAttributes Attributes; +extern XWindowAttributes attr; +extern XSizeHints szHint; +extern int font_change_count; +extern const char *def_fontName[]; +extern const char *rs_font[NFONTS]; +# ifdef MULTI_CHARSET +extern const char *def_kfontName[]; +extern const char *rs_mfont[NFONTS]; +# endif + +/************ Function Prototypes ************/ +_XFUNCPROTOBEGIN + +extern Pixel get_bottom_shadow_color(Pixel, const char *); +extern Pixel get_top_shadow_color(Pixel, const char *); +extern void Create_Windows(int, char * []); +extern void resize_subwindows(int, int); +extern void resize(void); +extern void resize_window1(unsigned int, unsigned int); +extern void set_width(unsigned short); +extern void resize_window(void); +#ifdef XTERM_COLOR_CHANGE +extern void set_window_color(int, const char *); +#else +# define set_window_color(idx,color) ((void)0) +#endif /* XTERM_COLOR_CHANGE */ +extern XFontStruct *load_font(const char *); +extern void change_font(int, const char *); + +_XFUNCPROTOEND + +#endif /* _WINDOWS_H_ */ diff --git a/themes/Eterm/.cvsignore b/themes/Eterm/.cvsignore index e5cdc04..4674fba 100644 --- a/themes/Eterm/.cvsignore +++ b/themes/Eterm/.cvsignore @@ -1 +1 @@ -MAIN +theme.cfg diff --git a/themes/Eterm/Eterm-menu.cfg b/themes/Eterm/Eterm-menu.cfg new file mode 100644 index 0000000..7fec1e1 --- /dev/null +++ b/themes/Eterm/Eterm-menu.cfg @@ -0,0 +1,891 @@ + +begin menu + title Font + font -*-times-bold-r-normal--14-*-*-*-*-*-iso8859-1 + begin menuitem + text "Normal" + action string "\e]50;#" + end + begin menuitem + text "Larger" + action string "\e]50;#+" + end + begin menuitem + text "Smaller" + action string "\e]50;#-" + end + - + begin menuitem + text "Font 1" + action string "\e]50;#1" + end + begin menuitem + text "Font 2" + action string "\e]50;#2" + end + begin menuitem + text "Font 3" + action string "\e]50;#3" + end + begin menuitem + text "Font 4" + action string "\e]50;#4" + end +end +begin menu + title Toggles + font fixed + begin menuitem + text "Cursor Visible" + action string "\e[?25t" + end + begin menuitem + text "Home on Echo" + action string "\e[?1010t" + end + begin menuitem + text "Home on Refresh" + action string "\e[?1011t" + end + begin menuitem + text "Home on Input" + action string "\e[?1012t" + end + begin menuitem + text "Map Alert" + action string "\e]6;21\a" + end + begin menuitem + text "Primary/Secondary Screen" + action string "\e[?47t" + end + begin menuitem + text "Reverse Video" + action string "\e[?5t" + end + begin menuitem + text "Select Trailing Spaces" + action string "\e]6;25\a" + end + begin menuitem + text "Select Whole Line on Triple-click" + action string "\e]6;23\a" + end + begin menuitem + text "Visual Bell" + action string "\e]6;20\a" + end + begin menuitem + text "X11 Mouse Reporting" + action string "\e[?1000t" + end + begin menuitem + text "Xterm Selection Behavior" + action string "\e]6;22\a" + end +end +begin menu + title Keys + font fixed + begin menuitem + text "Application Arrow Keys" + action string "\e[?1t" + end + begin menuitem + text "Application Keypad" + action string "\e[?66t" + end + begin menuitem + text "Backspace/Delete" + action string "\e[?67t" + end + begin menuitem + text "Xterm Shift-Keys" + action string "\e[?35t" + end +end +begin menu + title Scrollbar + font fixed + begin menuitem + text "Toggle Visibility" + rtext "Ctrl-Button2" + action string "\e[?30t" + end + begin menuitem + text "Swap Sides" + action string "\e]6;11\a" + end + begin menuitem + text "Toggle Floating" + action string "\e]6;12\a" + end + begin menuitem + text "Toggle Popup Mode" + action string "\e]6;13\a" + end + - + begin menuitem + text "Motif (Traditional) Style" + action string "\e]6;10;motif;;\a" + end + begin menuitem + text "NeXT Style" + action string "\e]6;10;next;;\a" + end + begin menuitem + text "Xterm Style" + action string "\e]6;10;xterm;;\a" + end +end +begin menu + title Width + font fixed + begin menuitem + text "5" + action string "\e]6;10;;5;\a" + end + begin menuitem + text "6" + action string "\e]6;10;;6;\a" + end + begin menuitem + text "7" + action string "\e]6;10;;7;\a" + end + begin menuitem + text "8" + action string "\e]6;10;;8;\a" + end + begin menuitem + text "9" + action string "\e]6;10;;9;\a" + end + begin menuitem + text "10" + action string "\e]6;10;;10;\a" + end + begin menuitem + text "11" + action string "\e]6;10;;11;\a" + end + begin menuitem + text "12" + action string "\e]6;10;;12;\a" + end + begin menuitem + text "13" + action string "\e]6;10;;13;\a" + end + begin menuitem + text "14" + action string "\e]6;10;;14;\a" + end + begin menuitem + text "15" + action string "\e]6;10;;15;\a" + end + begin menuitem + text "16" + action string "\e]6;10;;16;\a" + end + begin menuitem + text "17" + action string "\e]6;10;;17;\a" + end + begin menuitem + text "18" + action string "\e]6;10;;18;\a" + end + begin menuitem + text "19" + action string "\e]6;10;;19;\a" + end + begin menuitem + text "20" + action string "\e]6;10;;20;\a" + end +end +begin menu + title "Move to Desktop" + font fixed + begin menuitem + text "0" + action string "\e]6;50;0;\a" + end + begin menuitem + text "1" + action string "\e]6;50;1;\a" + end + begin menuitem + text "2" + action string "\e]6;50;2;\a" + end + begin menuitem + text "3" + action string "\e]6;50;3;\a" + end + begin menuitem + text "4" + action string "\e]6;50;4;\a" + end + begin menuitem + text "5" + action string "\e]6;50;5;\a" + end + begin menuitem + text "6" + action string "\e]6;50;6;\a" + end + begin menuitem + text "7" + action string "\e]6;50;7;\a" + end +end +begin menu + title Terminal + font fixed + begin menuitem + text "Toggles" + action submenu "Toggles" + end + begin menuitem + text "Keys" + action submenu "Keys" + end + begin menuitem + text "Scrollbar" + action submenu "Scrollbar" + end + begin menuitem + text "Move to Desktop..." + action submenu "Move to Desktop" + end + - + begin menuitem + text "Steal Focus" + rtext "Ctrl-Button1" + action string "\e]5;\a" + end + begin menuitem + text "Full Reset" + action string "\ec" + end +end + +begin menu + title Transparency + font fixed + begin menuitem + text "Force Update" + action string "\e]6;3\a" + end + begin menuitem + text "Toggle Desktop Watching" + action string "\e]6;4\a" + end + begin menuitem + text "Toggle Transparency" + action string "\e]6;0\a" + end +end +begin menu + title Tiled + font fixed + begin menuitem + text "70's Marble" + action string "\e]20;70s_marble.png;0x0+0+0:tile\a" + end + begin menuitem + text "7m" + action string "\e]20;7m.png;0x0+0+0:tile\a" + end + begin menuitem + text "Alabama Clay" + action string "\e]20;dirt.png;0x0+0+0:tile\a" + end + begin menuitem + text "Anomaly" + action string "\e]20;a8.png;0x0+0+0:tile\a" + end + begin menuitem + text "Black Stone" + action string "\e]20;blackstone.png;0x0+0+0:tile\a" + end + begin menuitem + text "Blue Ether" + action string "\e]20;ether_blue.png;0x0+0+0:tile\a" + end + begin menuitem + text "Blue Marble" + action string "\e]20;blue_marble.png;0x0+0+0:tile\a" + end + begin menuitem + text "Blue Maze" + action string "\e]20;blue_maze.png;0x0+0+0:tile\a" + end + begin menuitem + text "Blue Puzzle" + action string "\e]20;026.png;0x0+0+0:tile\a" + end + begin menuitem + text "Circuit" + action string "\e]20;circuit.png;0x0+0+0:tile\a" + end + begin menuitem + text "Cyber Playground" + action string "\e]20;cyber_bg.png;0x0+0+0:tile\a" + end + begin menuitem + text "Dark Marble" + action string "\e]20;dark_marble.png;0x0+0+0:tile\a" + end + begin menuitem + text "Dimples" + action string "\e]20;014.png;0x0+0+0:tile\a" + end + begin menuitem + text "Ether" + action string "\e]20;ether.png;0x0+0+0:tile\a" + end + begin menuitem + text "Giger 1" + action string "\e]20;giger1.png;0x0+0+0:tile\a" + end + begin menuitem + text "Giger 2" + action string "\e]20;giger2.png;0x0+0+0:tile\a" + end + begin menuitem + text "Gray Matter" + action string "\e]20;22.png;0x0+0+0:tile\a" + end + begin menuitem + text "Gray Waves" + action string "\e]20;gray_waves.png;0x0+0+0:tile\a" + end + begin menuitem + text "Jungle" + action string "\e]20;43.png;0x0+0+0:tile\a" + end + begin menuitem + text "Lava" + action string "\e]20;4.png;0x0+0+0:tile\a" + end + begin menuitem + text "Light B1" + action string "\e]20;lightb1.png;0x0+0+0:tile\a" + end + begin menuitem + text "Maple Leaves" + action string "\e]20;maple1.png;0x0+0+0:tile\a" + end + begin menuitem + text "Marble" + action string "\e]20;marbled.png;0x0+0+0:tile\a" + end + begin menuitem + text "Pebbles" + action string "\e]20;pebble1.png;0x0+0+0:tile\a" + end + begin menuitem + text "Purple Rain" + action string "\e]20;024.png;0x0+0+0:tile\a" + end + begin menuitem + text "Purple Clouds" + action string "\e]20;7.png;0x0+0+0:tile\a" + end + begin menuitem + text "Rainstorm" + action string "\e]20;15.png;0x0+0+0:tile\a" + end + begin menuitem + text "Red Whisper" + action string "\e]20;40.png;0x0+0+0:tile\a" + end + begin menuitem + text "Soft Marble" + action string "\e]20;soft.png;0x0+0+0:tile\a" + end + begin menuitem + text "Space 1" + action string "\e]20;space.png;0x0+0+0:tile\a" + end + begin menuitem + text "Space 2" + action string "\e]20;starry.png;0x0+0+0:tile\a" + end + begin menuitem + text "Whirlpool" + action string "\e]20;015.png;0x0+0+0:tile\a" + end +end +begin menu + title Scaled + font fixed + begin menuitem + text "Alien Spheres" + action string "\e]20;alien_spheres.jpg;100x100+50+50\a" + end + begin menuitem + text "Atlantis" + action string "\e]20;atlantis.jpg;100x100+50+50\a" + end + begin menuitem + text "Before the Storm" + action string "\e]20;before_the_storm.jpg;100x100+50+50\a" + end + begin menuitem + text "Bladerunner" + action string "\e]20;Bladerunner-bg.png;100x100+50+50\a" + end + begin menuitem + text "Canyon" + action string "\e]20;Canyon.jpg;100x100+50+50\a" + end + begin menuitem + text "CaveFire" + action string "\e]20;Cavefire-bg.png;100x100+50+50\a" + end + begin menuitem + text "Crater Lake" + action string "\e]20;crater_lake.jpg;100x100+50+50\a" + end + begin menuitem + text "Daughter" + action string "\e]20;Daughter.jpg;100x100+50+50\a" + end + begin menuitem + text "Dragon" + action string "\e]20;Dragon.jpg;100x100+50+50\a" + end + begin menuitem + text "DVXVB" + action string "\e]20;dvxvb.jpg;100x100+50+50\a" + end + begin menuitem + text "Elysium" + action string "\e]20;elysium.jpg;100x100+50+50\a" + end + begin menuitem + text "Evocation" + action string "\e]20;Evocation.jpg;100x100+50+50\a" + end + begin menuitem + text "Hourglass" + action string "\e]20;hour.jpg;100x100+50+50\a" + end + begin menuitem + text "Ice Moon" + action string "\e]20;icemoon.jpg;100x100+50+50\a" + end + begin menuitem + text "Iron Temple" + action string "\e]20;iron_temple.jpg;100x100+50+50\a" + end + begin menuitem + text "Lake of Fire" + action string "\e]20;lake_of_fire.jpg;100x100+50+50\a" + end + begin menuitem + text "Lighthouse" + action string "\e]20;lighthouse.jpg;100x100+50+50\a" + end + begin menuitem + text "Monolith" + action string "\e]20;monolith.jpg;100x100+50+50\a" + end + begin menuitem + text "Nebula" + action string "\e]20;nebula.jpg;100x100+50+50\a" + end + begin menuitem + text "Neopolis" + action string "\e]20;neopolis.jpg;100x100+50+50\a" + end + begin menuitem + text "Neopolis Horizon" + action string "\e]20;Neopolis-horizon.png;100x100+50+50\a" + end + begin menuitem + text "Planet A" + action string "\e]20;planeta.png;100x100+50+50\a" + end + begin menuitem + text "Pond" + action string "\e]20;pond.png;100x100+50+50\a" + end + begin menuitem + text "Poseidon" + action string "\e]20;poseidon.png;100x100+50+50\a" + end + begin menuitem + text "Return to Giza" + action string "\e]20;return_to_giza.jpg;100x100+50+50\a" + end + begin menuitem + text "Ripple" + action string "\e]20;ripple.png;100x100+50+50\a" + end + begin menuitem + text "River of Lead" + action string "\e]20;river_of_lead.jpg;100x100+50+50\a" + end + begin menuitem + text "Silence" + action string "\e]20;silence.jpg;100x100+50+50\a" + end + begin menuitem + text "Sun" + action string "\e]20;sun.png;100x100+50+50\a" + end + begin menuitem + text "Tunnel" + action string "\e]20;tunnel.jpg;100x100+50+50\a" + end + begin menuitem + text "Wasteland" + action string "\e]20;wasteland.jpg;100x100+50+50\a" + end +end +begin menu + title Attrib + font fixed + begin menuitem + text "Full Size" + action string "\e]20;;100x100" + end + begin menuitem + text "Normal Size" + action string "\e]20;;0x0" + end + - + begin menuitem + text "Tiled" + action string "\e]20;;:tile" + end + begin menuitem + text "Scaled" + action string "\e]20;;:scale" + end + begin menuitem + text "Proportional Scale" + action string "\e]20;;:propscale" + end + - + begin menuitem + text "Center" + action string "\e]20;;=+50+50" + end + begin menuitem + text "Top Left Corner" + action string "\e]20;;=+0+0" + end + begin menuitem + text "Bottom Right Corner" + action string "\e]20;;=+100+100" + end +end +begin menu + title Pixmap + font fixed + begin menuitem + text "None" + action string "\e[m\e]20;;\a" + end + begin menuitem + text "Toggle Viewport Mode" + action string "\e]6;24\a" + end + begin menuitem + text "Tiled" + action submenu "Tiled" + end + begin menuitem + text "Scaled" + action submenu "Scaled" + end + - + begin menuitem + text "Attrib" + action submenu "Attrib" + end +end +begin menu + title Brightness + font fixed + begin menuitem + text "512 (200%)" + action string "\e]6;1;image;brightness;512\a" + end + begin menuitem + text "480 (188%)" + action string "\e]6;1;image;brightness;480\a" + end + begin menuitem + text "448 (175%)" + action string "\e]6;1;image;brightness;448\a" + end + begin menuitem + text "416 (163%)" + action string "\e]6;1;image;brightness;416\a" + end + begin menuitem + text "384 (150%)" + action string "\e]6;1;image;brightness;384\a" + end + begin menuitem + text "352 (138%)" + action string "\e]6;1;image;brightness;352\a" + end + begin menuitem + text "320 (125%)" + action string "\e]6;1;image;brightness;320\a" + end + begin menuitem + text "288 (113%)" + action string "\e]6;1;image;brightness;288\a" + end + begin menuitem + text "256 (100%)" + action string "\e]6;1;image;brightness;256\a" + end + begin menuitem + text "224 (88%)" + action string "\e]6;1;image;brightness;224\a" + end + begin menuitem + text "192 (75%)" + action string "\e]6;1;image;brightness;192\a" + end + begin menuitem + text "160 (63%)" + action string "\e]6;1;image;brightness;160\a" + end + begin menuitem + text "128 (50%)" + action string "\e]6;1;image;brightness;128\a" + end + begin menuitem + text "96 (38%)" + action string "\e]6;1;image;brightness;96\a" + end + begin menuitem + text "64 (25%)" + action string "\e]6;1;image;brightness;64\a" + end + begin menuitem + text "32 (13%)" + action string "\e]6;1;image;brightness;32\a" + end + begin menuitem + text "0 (0%)" + action string "\e]6;1;image;brightness;0\a" + end +end +begin menu + title Contrast + font fixed + begin menuitem + text "512 (200%)" + action string "\e]6;1;image;contrast;512\a" + end + begin menuitem + text "480 (188%)" + action string "\e]6;1;image;contrast;480\a" + end + begin menuitem + text "448 (175%)" + action string "\e]6;1;image;contrast;448\a" + end + begin menuitem + text "416 (163%)" + action string "\e]6;1;image;contrast;416\a" + end + begin menuitem + text "384 (150%)" + action string "\e]6;1;image;contrast;384\a" + end + begin menuitem + text "352 (138%)" + action string "\e]6;1;image;contrast;352\a" + end + begin menuitem + text "320 (125%)" + action string "\e]6;1;image;contrast;320\a" + end + begin menuitem + text "288 (113%)" + action string "\e]6;1;image;contrast;288\a" + end + begin menuitem + text "256 (100%)" + action string "\e]6;1;image;contrast;256\a" + end + begin menuitem + text "224 (88%)" + action string "\e]6;1;image;contrast;224\a" + end + begin menuitem + text "192 (75%)" + action string "\e]6;1;image;contrast;192\a" + end + begin menuitem + text "160 (63%)" + action string "\e]6;1;image;contrast;160\a" + end + begin menuitem + text "128 (50%)" + action string "\e]6;1;image;contrast;128\a" + end + begin menuitem + text "96 (38%)" + action string "\e]6;1;image;contrast;96\a" + end + begin menuitem + text "64 (25%)" + action string "\e]6;1;image;contrast;64\a" + end + begin menuitem + text "32 (13%)" + action string "\e]6;1;image;contrast;32\a" + end + begin menuitem + text "0 (0%)" + action string "\e]6;1;image;contrast;0\a" + end +end +begin menu + title Gamma + font fixed + begin menuitem + text "512 (200%)" + action string "\e]6;1;image;gamma;512\a" + end + begin menuitem + text "480 (188%)" + action string "\e]6;1;image;gamma;480\a" + end + begin menuitem + text "448 (175%)" + action string "\e]6;1;image;gamma;448\a" + end + begin menuitem + text "416 (163%)" + action string "\e]6;1;image;gamma;416\a" + end + begin menuitem + text "384 (150%)" + action string "\e]6;1;image;gamma;384\a" + end + begin menuitem + text "352 (138%)" + action string "\e]6;1;image;gamma;352\a" + end + begin menuitem + text "320 (125%)" + action string "\e]6;1;image;gamma;320\a" + end + begin menuitem + text "288 (113%)" + action string "\e]6;1;image;gamma;288\a" + end + begin menuitem + text "256 (100%)" + action string "\e]6;1;image;gamma;256\a" + end + begin menuitem + text "224 (88%)" + action string "\e]6;1;image;gamma;224\a" + end + begin menuitem + text "192 (75%)" + action string "\e]6;1;image;gamma;192\a" + end + begin menuitem + text "160 (63%)" + action string "\e]6;1;image;gamma;160\a" + end + begin menuitem + text "128 (50%)" + action string "\e]6;1;image;gamma;128\a" + end + begin menuitem + text "96 (38%)" + action string "\e]6;1;image;gamma;96\a" + end + begin menuitem + text "64 (25%)" + action string "\e]6;1;image;gamma;64\a" + end + begin menuitem + text "32 (13%)" + action string "\e]6;1;image;gamma;32\a" + end + begin menuitem + text "0 (0%)" + action string "\e]6;1;image;gamma;0\a" + end +end +begin menu + title Background + font fixed + begin menuitem + text "Transparency" + action submenu "Transparency" + end + begin menuitem + text "Pixmap" + action submenu "Pixmap" + end + begin menuitem + text "Brightness" + action submenu "Brightness" + end + begin menuitem + text "Contrast" + action submenu "Contrast" + end + begin menuitem + text "Gamma" + action submenu "Gamma" + end +end + +# This is the menu that gets called by Ctrl-Button3 +begin menu + title Eterm + font fixed + begin menuitem + text "Font" + action submenu Font + end + begin menuitem + text "Background" + action submenu Background + end + begin menuitem + text "Terminal" + action submenu Terminal + end + - + begin menuitem + text "Version" + action string "\e[8n" + end + begin menuitem + text "Status" + action string "\e[9n" + end + separator + begin menuitem + text "Save Settings..." + action string "\e]6;71\a" + end + begin menuitem + text "Exit" + action string "\e]6;70\a" + end +end + diff --git a/themes/Eterm/Eterm.menu b/themes/Eterm/Eterm.menu deleted file mode 100644 index 79fc94d..0000000 --- a/themes/Eterm/Eterm.menu +++ /dev/null @@ -1,192 +0,0 @@ -# standard settings for an Eterm control menu -[menu:Eterm] - -/Eterm/* - -./Font/* -{Normal} ^@\e]50;# -{Larger} ^@\e]50;#+ -{Smaller} ^@\e]50;#- -{-} -{Font 1} ^@\e]50;#1 -{Font 2} ^@\e]50;#2 -{Font 3} ^@\e]50;#3 -{Font 4} ^@\e]50;#4 - -../Terminal/* -./Toggles/* -{Cursor Visible} ^@\e[?25t -{Home on Echo} ^@\e[?1010t -{Home on Refresh} ^@\e[?1011t -{Home on Input} ^@\e[?1012t -{Map Alert} ^@\e]6;21\a -{Primary/Secondary Screen} ^@\e[?47t -{Reverse Video} ^@\e[?5t -{Select Trailing Spaces} ^@\e]6;25\a -{Select Whole Line on Triple-click} ^@\e]6;23\a -{Visual Bell} ^@\e]6;20\a -{X11 Mouse Reporting} ^@\e[?1000t -{Xterm Selection Behavior} ^@\e]6;22\a -../Keys/* -{Application Arrow Keys} ^@\e[?1t -{Application Keypad} ^@\e[?66t -{Backspace/Delete} ^@\e[?67t -{Xterm Shift-Keys} ^@\e[?35t -../Menubar/* -{Toggle Visibility}{Ctrl-Button3} ^@\e[?10t -{Refresh Menubar} ^@\e[?10h -{Toggle Window Move by Menubar} ^@\e]6;15\a -../Scrollbar/* -{Toggle Visibility}{Ctrl-Button2} ^@\e[?30t -{Swap Sides} ^@\e]6;11\a -{Toggle Floating} ^@\e]6;12\a -{Toggle Popup Mode} ^@\e]6;13\a -{-} -{Motif (Traditional) Style} ^@\e]6;10;motif;;\a -{NeXT Style} ^@\e]6;10;next;;\a -{Xterm Style} ^@\e]6;10;xterm;;\a -./Width/* -{5} ^@\e]6;10;;5;\a -{6} ^@\e]6;10;;6;\a -{7} ^@\e]6;10;;7;\a -{8} ^@\e]6;10;;8;\a -{9} ^@\e]6;10;;9;\a -{10} ^@\e]6;10;;10;\a -{11} ^@\e]6;10;;11;\a -{12} ^@\e]6;10;;12;\a -{13} ^@\e]6;10;;13;\a -{14} ^@\e]6;10;;14;\a -{15} ^@\e]6;10;;15;\a -{16} ^@\e]6;10;;16;\a -{17} ^@\e]6;10;;17;\a -{18} ^@\e]6;10;;18;\a -{19} ^@\e]6;10;;19;\a -{20} ^@\e]6;10;;20;\a -../ -../Move to Desktop/* -{0} ^@\e]6;50;0;\a -{1} ^@\e]6;50;1;\a -{2} ^@\e]6;50;2;\a -{3} ^@\e]6;50;3;\a -{4} ^@\e]6;50;4;\a -{5} ^@\e]6;50;5;\a -{6} ^@\e]6;50;6;\a -{7} ^@\e]6;50;7;\a -../ -{-} -{Steal Focus}{Ctrl-Button1} ^@\e]5;\a -{Full Reset} ^@\ec - -../Background/* -./Transparency/* -{Force Update} ^@\e]6;3\a -{Toggle Desktop Watching} ^@\e]6;4\a -{Toggle Transparency} ^@\e]6;0\a -../Pixmap/* -{None} ^@\e[m\e]20;;\a -{Toggle Viewport Mode} ^@\e]6;24\a -./Tiled/* -{70's Marble} ^@\e]20;70s_marble.png;0x0+50+50\a -{7m} ^@\e]10;[pixmap:7m.png;0x0+50+50] -{Alabama Clay} ^@\e]10;[pixmap:dirt.png;0x0+50+50] -{Anomaly} ^@\e]20;a8.png;0x0+50+50\a -{Black Stone} ^@\e]20;blackstone.png;0x0+50+50\a -{Blue Ether} ^@\e]10;[pixmap:ether_blue.png;0x0+50+50] -{Blue Marble} ^@\e]10;[pixmap:blue_marble.png;0x0+50+50] -{Blue Maze} ^@\e]10;[pixmap:blue_maze.png;0x0+50+50] -{Blue Puzzle} ^@\e]10;[pixmap:026.png;0x0+50+50] -{Circuit} ^@\e]10;[pixmap:circuit.png;0x0+50+50] -{Cyber Playground} ^@\e]10;[pixmap:cyber_bg.png;0x0+50+50] -{Dark Marble} ^@\e]10;[pixmap:dark_marble.png;0x0+50+50] -{Dimples} ^@\e]20;014.png;0x0+50+50\a -{Ether} ^@\e]10;[pixmap:ether.png;0x0+50+50] -{Giger 1} ^@\e]10;[pixmap:giger1.png;0x0+50+50] -{Giger 2} ^@\e]10;[pixmap:giger2.png;0x0+50+50] -{Gray Matter} ^@\e]10;[pixmap:22.png;0x0+50+50] -{Gray Waves} ^@\e]10;[pixmap:gray_waves.png;0x0+50+50] -{Jungle} ^@\e]20;43.png;0x0+50+50\a -{Lava} ^@\e]20;4.png;0x0+50+50\a -{Light B1} ^@\e]10;[pixmap:lightb1.png;0x0+50+50] -{Maple Leaves} ^@\e]10;[pixmap:maple1.png;0x0+50+50] -{Marble} ^@\e]10;[pixmap:marbled.png;0x0+50+50] -{Pebbles} ^@\e]10;[pixmap:pebble1.png;0x0+50+50] -{Purple Rain} ^@\e]20;024.png;0x0+50+50\a -{Purple Clouds} ^@\e]10;[pixmap:7.png;0x0+50+50] -{Rainstorm} ^@\e]20;15.png;0x0+50+50\a -{Red Whisper} ^@\e]10;[pixmap:40.png;0x0+50+50] -{Soft Marble} ^@\e]10;[pixmap:soft.png;0x0+50+50] -{Space 1} ^@\e]10;[pixmap:space.png;0x0+50+50] -{Space 2} ^@\e]10;[pixmap:starry.png;0x0+50+50] -{Whirlpool} ^@\e]20;015.png;0x0+50+50\a - -../Scaled/* -{Alien Spheres} ^@\e]20;alien_spheres.jpg;100x100+50+50\a -{Atlantis} ^@\e]20;atlantis.jpg;100x100+50+50\a -{Before the Storm} ^@\e]20;before_the_storm.jpg;100x100+50+50\a -{Bladerunner} ^@\e]20;Bladerunner-bg.png;100x100+50+50\a -{Canyon} ^@\e]20;Canyon.jpg;100x100+50+50\a -{CaveFire} ^@\e]20;Cavefire-bg.png;100x100+50+50\a -{Crater Lake} ^@\e]20;crater_lake.jpg;100x100+50+50\a -{Daughter} ^@\e]20;Daughter.jpg;100x100+50+50\a -{Dragon} ^@\e]20;Dragon.jpg;100x100+50+50\a -{DVXVB} ^@\e]20;dvxvb.jpg;100x100+50+50\a -{Elysium} ^@\e]20;elysium.jpg;100x100+50+50\a -{Evocation} ^@\e]20;Evocation.jpg;100x100+50+50\a -{Hourglass} ^@\e]20;hour.jpg;100x100+50+50\a -{Ice Moon} ^@\e]20;icemoon.jpg;100x100+50+50\a -{Iron Temple} ^@\e]20;iron_temple.jpg;100x100+50+50\a -{Lake of Fire} ^@\e]20;lake_of_fire.jpg;100x100+50+50\a -{Lighthouse} ^@\e]20;lighthouse.jpg;100x100+50+50\a -{Monolith} ^@\e]20;monolith.jpg;100x100+50+50\a -{Nebula} ^@\e]20;nebula.jpg;100x100+50+50\a -{Neopolis} ^@\e]20;neopolis.jpg;100x100+50+50\a -{Neopolis Horizon} ^@\e]20;Neopolis-horizon.png;100x100+50+50\a -{Planet A} ^@\e]20;planeta.png;100x100+50+50\a -{Pond} ^@\e]20;pond.png;100x100+50+50\a -{Poseidon} ^@\e]20;poseidon.png;100x100+50+50\a -{Return to Giza} ^@\e]20;return_to_giza.jpg;100x100+50+50\a -{Ripple} ^@\e]20;ripple.png;100x100+50+50\a -{River of Lead} ^@\e]20;river_of_lead.jpg;100x100+50+50\a -{Silence} ^@\e]20;silence.jpg;100x100+50+50\a -{Sun} ^@\e]20;sun.png;100x100+50+50\a -{Tunnel} ^@\e]20;tunnel.jpg;100x100+50+50\a -{Wasteland} ^@\e]20;wasteland.jpg;100x100+50+50\a -../ -{-} -./Attrib/* -{Full} ^@\e]20;;100x100+50+50; -{Tiled} ^@\e]20;;0 -{Center} ^@\e]20;;=+50+50; -../ -../Shade/* -{0%} ^@\e]6;1;0%\a -{10%} ^@\e]6;1;10%\a -{20%} ^@\e]6;1;20%\a -{30%} ^@\e]6;1;30%\a -{40%} ^@\e]6;1;40%\a -{50%} ^@\e]6;1;50%\a -{60%} ^@\e]6;1;60%\a -{70%} ^@\e]6;1;70%\a -{80%} ^@\e]6;1;80%\a -{90%} ^@\e]6;1;90%\a -{100%} ^@\e]6;1;100%\a -../Tint/* -{No Tint} ^@\e]6;2;0xffffff\a -{Red Tint} ^@\e]6;2;0xff8080\a -{Green Tint} ^@\e]6;2;0x80ff80\a -{Blue Tint} ^@\e]6;2;0x8080ff\a -{Cyan Tint} ^@\e]6;2;0x80ffff\a -{Magenta Tint} ^@\e]6;2;0xff80ff\a -{Yellow Tint} ^@\e]6;2;0xffff80\a -../ - -../ -{-} -{Version} ^@\e[8n -{Status} ^@\e[9n -{-} -{Save Current Settings} ^@\e]6;71\a -{Exit Eterm} ^@\e]6;70\a -/ -[show] -[done] diff --git a/themes/Eterm/MAIN.in b/themes/Eterm/theme.cfg.in similarity index 56% rename from themes/Eterm/MAIN.in rename to themes/Eterm/theme.cfg.in index 689b811..fafa17b 100644 --- a/themes/Eterm/MAIN.in +++ b/themes/Eterm/theme.cfg.in @@ -24,9 +24,11 @@ begin main background black cursor #ffff00 cursor_text #880000 - menu_text white scrollbar #3f1c00 unfocusedscrollbar #777777 + menu #777777 + unfocusedmenu #777777 + menu_text black pointer white # video attribute can either be "normal" or "reverse" @@ -88,31 +90,161 @@ begin main # font bold 7x14 end attributes -# This section is for pixmap definitions. The only one used currently -# is "background". The supplied numbers work just like they do for -# Enlightenment: first is X (width), second is Y (height). -1 to -# scale 100%, 0 to tile, any other number specifies W/H in pixels - begin pixmaps - background %random(`cat pixmaps.list 2>/dev/null`) - path "./pix/:~/.Eterm/:~/.Eterm/themes/Eterm/pix:~/.Eterm/pix/:@DATADIR@/Eterm/pix/" +# Define the imageclasses. + begin imageclasses -# Support for these is forthcoming -# scroll_up -1 -1 ~/.Eterm/up_arrow.ppm -# scroll_down -1 -1 ~/.Eterm/down_arrow.ppm -# scroll_background 0 0 ~/.Eterm/scroll.ppm -# scroll_anchor -1 -1 ~/.Eterm/anchor.ppm +# You must define this before setting any images that use it. This is the $PATH-style variable +# that determines where Eterm looks for image files. + path "./pix/:~/.Eterm/:~/.Eterm/themes/Eterm/pix:~/.Eterm/pix/:@PKGDATADIR@/pix/" + +# If you want a different icon than the standard Eterm one, set this. +# icon Eterm.xpm + +# This is the background animator. See the man page for the syntax. +# anim 3 foo1 foo2 foo3 + +# Here we define an image. + begin image + +# The first thing you set when defining an image MUST be the type. No type, no dice. The type +# should be one of the following: background, up_arrow, down_arrow, left_arrow, right_arrow, +# trough, anchor, menu, or submenu + type background + +# Next you should set the state. This is either normal, selected, or clicked. + state normal + +# Here you set the file. You can also set the geometry string here if you follow the filename with +# an @ sign. That way, you can include the geometries in your pixmaps.list file. + file %random(`cat pixmaps.list`) + +# The mode line. This defines the startup mode for the image, as well as what modes are allowed. +# Valid modes are "image" (to display the image file), "trans" (to be transparent), or "viewport" +# (for viewport mode). Syntax is "mode allow ". + mode image allow trans viewport + +# Set the image border. This is a portion of the image which will be kept at its actual size when +# scaling. Use this for beveled images (buttons, etc.). + border 0 0 0 0 + +# Th-th-th-th-that's all folks. + end image + +# The rest of the images. + begin image + type trough + mode image allow trans viewport + state normal + file bar_vertical_3.png +# Here is how you specify the geometry string separately. See the man page for its syntax. + geom :scale + border 3 3 2 2 + end image + begin image + type anchor + state normal + file bar_vertical_1.png + geom :scale + border 3 3 2 2 + state selected + file bar_vertical_2.png + geom :scale + border 3 3 2 2 + end image + begin image + type up_arrow + state normal + file button_arrow_up_1.png + geom :scale + border 2 2 2 2 + state selected + file button_arrow_up_2.png + geom :scale + border 2 2 2 2 + state clicked + file button_arrow_up_3.png + geom :scale + border 2 2 2 2 + end image + begin image + type down_arrow + state normal + file button_arrow_down_1.png + geom :scale + border 2 2 2 2 + state selected + file button_arrow_down_2.png + geom :scale + border 2 2 2 2 + state clicked + file button_arrow_down_3.png + geom :scale + border 2 2 2 2 + end image + begin image + type menu + state normal + file bar_horizontal_1.png + geom 100x100+0+0:scale + border 3 3 2 2 + state selected + file bar_horizontal_2.png + geom 100x100+0+0:scale + border 3 3 2 2 + end image + begin image + type submenu + state normal + file menu1.png + geom 100x100+0+0:scale + border 3 15 3 3 + padding 3 15 3 3 + state selected + file menu2.png + geom 100x100+0+0:scale + border 3 15 3 3 + padding 3 15 3 3 + state clicked + file menu3.png + geom 100x100+0+0:scale + border 3 15 3 3 + padding 3 15 3 3 + end image end -# The Kanji support options. Same goes for these fonts as for the normal -# ones. The "encoding" attribute can be either "eucj" or "sjis". -# begin kanji +%include "Eterm-menu.cfg" + +# This section *must* come after the menu definitions if you want +# menu actions to work. C'est la vie. :-) +# +# Syntax: bind [ { | anymod } ] { | |