commit c79f01a1d99a8e404ef13108822092bf5bfb735c Author: Carsten Haitzler Date: Tue Aug 17 22:56:46 1999 +0000 re-importing E after cvs failure to comply with orders... thus it DIED! SVN revision: 37 diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 00000000..ee5d4972 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,16 @@ +Makefile +Makefile.in +aclocal.m4 +config.status +config.log +config.cache +configure +econfig.h +econfig.h.in +stamp-h +stamp-h.in +confdefs.h +config.sub +ltconfig +ltmain.sh +config.guess diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..ebfd24bb --- /dev/null +++ b/AUTHORS @@ -0,0 +1,68 @@ +The Rasterman: + + + aka. Carsten Haitzler + +Mandrake: + + + aka. Geoff Harrison + +-------------- CONTRIBUTORS: ----------------------------------------------- + +All code contributed by contributors remains copyright to them respectively +if they wish to retain copyright. it is up to the authors of patches and +contributions to clearly mark their contributions with their name, email and +date in comments if they wish to retain copyright, otherwise it is assumed +to be transferred to the main E source body. + +A BIG thanks to all those who have submitted patches: + +Troy Pesola: + + For contributing several patches, both to the current and + previous revisions of E + +Chutt: + aka. Isaac Richards + + Contributed a patch for use with esound that lowered + the RSS by around 200k with the default theme. + +Owen Taylor + + icccm widthdraw WM_STATE patch to fix some java endless loops + +Sung-Hyun Nam + + Fnlib OR X fonts used in text classes. + +Kimball Thurston + + Fixes for cross-platform support on IRIX + +Michael Kellen + + For sound patches..... :) + +Stalyn + For dock support. + +Frederic Devernay + Patch for Session managemend IFDEF. + +Felix Bellaby + LOTs of useful Session Management related code. + +Michael Jennings (KainX) + lots of useful patches :) + +Christian Kreibich + several minor patches some of which were the dox customisable + color patch, shading patch, and some more.. :) + +Peter Kjellerstedt + for finding a bug in theme preparse loaded files. + +And others whose names we probably forgot to add (email us and we'll put you +in here) diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..fe5e1d78 --- /dev/null +++ b/COPYING @@ -0,0 +1,18 @@ +Copyright (C) 1999 Carsten Haitzler and various contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..2967d59c --- /dev/null +++ b/ChangeLog @@ -0,0 +1,1592 @@ +1998-06-02 Raja R Harinath + + * configure.in: Change all [ ... ] to test .... Also `test -e' is + not portable. Use `test -f' instead. + +------------------------------------------------------------------------------- + +Wed May 13 21:03:23 EDT 1998 +(Raster) +Moved everything to autoconf/automake. +Have done piles of the basic work on E 0.14 +Now things get serious with keeping a ChangeLog and stuff. + +------------------------------------------------------------------------------- + +Thu May 14 21:43:41 EDT 1998 +(Raster) +Fixed some raising/lowering bugs for desktops (if 3 desktops were up the top +one would dissapear behind the others when you moved a window that was on +that desktop). +Now E handles multi-depth servers fully - instead of not setting a root pixmap +at all now it inits Imlib especialy for the root visual if the root visual +doesn't match Imlib's chosen visual, and thus can set the bg on the root +window even if it's a different visual to what E normally uses. +Alo created a few more backgrounds for desktops to look cleaner and show off +a bit more. + +------------------------------------------------------------------------------- + +Thu May 14 23:44:31 EDT 1998 +(Raster) +Added STICK action to make windows stick/normal again (toggle it) and made +sticky windows work (ie stick ABOVE every desktop) and not have anything +overlap them.. except other sticky windows. :) Changed internal bindings to +alt-left and alt-right arrow. Added a "slide back in place" action for +sliding the current active desktop back shut - bound this to alt-down arrow. + +------------------------------------------------------------------------------- + +Fri May 15 11:20:47 EDT 1998 +(Raster) +Cleaned up some desktop backgrounds. + +------------------------------------------------------------------------------- + +Sat May 16 12:05:53 EDT 1998 +(Raster) +Added button dragging. Now you can drag buttons around your desktop at will, +with a drage threshold/resistance which E uses to decide if its a drag or a +click. There is a global action for all buttons that defines whihc mosue +butotns/combos are used to init a button drag. This now means a user can +customise his interface "on-the-fly" as needed. I am hoping that on exit E +will be able to save the settings of all buttons to the user config so they +come up in the same spot again on the next login. + +------------------------------------------------------------------------------- + +Sat May 16 23:00:51 EDT 1998 +(Raster) +Okay I've gone stark raving mad. I just added some sound support into E. +Also fixed on mapping/stacking bug too. Changed keybindings for exit to be +alt-End too :) + +------------------------------------------------------------------------------- + +Sun May 17 17:02:41 EDT 1998 +(Raster) +Added #ifdefs for ESD support - if esd isn't installed sound won't be +compiled in at all. +Fixed the ActionExec to check if the progrma can be executed at all first, +(ie the user has exec permission ot the exe and it exists in the explicit +full path or in the users shell path) - if it doesn't tell the user so. + +------------------------------------------------------------------------------- + +Sun May 17 23:46:55 EDT 1998 +(Raster) +Added regex.c for regular expression matching (to be used to match client +names/titlebars using only the "*" wildcard (that is all it supports). I +coudl use full regex - I may do that in future, but for now I have rolled my +own. + +------------------------------------------------------------------------------- + +Mon May 18 23:09:30 EDT 1998 +(Raster) +Added functiosn to create BorderMatch objects in the List and to match +window attributes with a BorderMatch Object and cose a window border style +on this basis. Should *in theory* work - need at least a second border style +to test this out on... +Also added more asnity checks int he configure.in to save idiots form +themselves if they have multiple libraries installed. + +------------------------------------------------------------------------------- + +Wed May 20 19:40:08 EDT 1998 +(Raster) +Added more extended hints for clients to be able to report back to E their +status so E can display icons etc. as will as to if the client is runing, +idle, has an error etc. + +------------------------------------------------------------------------------- + +Fri May 22 14:33:28 EDT 1998 +(Raster) +Screwed aroudn with the extended hints again... moulding them right now... +they need work. Also last night and today completely moved ALL of E's source +to use the interenal debugger system (with debug levels 0-9), that requires +usi macros to start a functiona nd return from it always for internal +accounting. A full release will just define these to be nothing and simple +returns when needed, but for now they will be debugging features for +optimisation purposes and weeding out bugs. + +------------------------------------------------------------------------------- + +Sun May 24 22:58:55 EDT 1998 +(Raster) +fixed some rasing/lowering bewteen client windows bugs after having been +mapped but not moved yet. + +------------------------------------------------------------------------------- + +Sun May 24 23:21:32 EDT 1998 +(Raster) +added timers.c for a timer/interrupt handlign system to be started on. (ie +call a function "In X milliseconds execute this function" and E will safely +exex that function in X milliseconds (or as close to that as it can) - this +needs a global timer queue to be set up, an inserter that will insert a new +timer action into the queue at the right spot modifying the surrounding +members, modifying the current itimer interrupt if needed. Also when an +interrupt happens E should open a second display connection, and then send e +a "fake" event (just a spurious ClientMessage will do or something just to +make E stop sleeping on xNextEvent if it is), so it will go do its events +and after the events are honored will enter the "check timer queu" function +- see if the first member is ready to execute yet, and if it is, remove it +fromt eh head of the queue, execute it, then setup an itimer interrupt for +the next queue member if there is one. That is in a nutshell what I have in +mind that will avoid Xlib sync lost errors (caused by an Xlib call being +interrupted by an itimer fucntion that also calls Xlib calls, confusing the +X server and Xlib itself). This should allow e to set arbitary numbers of +events to happen in X time from now and it should all work. VERY handy for +stuff like acounting (desktop accounting is currently done whenever you +click the mouse - i really should do it every few seconds (lets say 10)), +and autoraise - even animation is possible this way. + +------------------------------------------------------------------------------- + +Tue May 26 10:03:45 EDT 1998 +(Raster) +Finally fixed my stacking problems. I wasn't creating/using/addingto/removing +from the window stack for the desktop properly - makeing the windows go +under the dragbar and buttons with "ontop=-1" (ie onbottom). + +------------------------------------------------------------------------------- + +Tue Jun 2 17:04:57 EDT 1998 +(Raster) +I've been slack keeping up the changelog over Linxu Expo and stuff. Okay. +Just fixed up some wrapper stuff (I didn't have all my memory +allocation/freeing code properly wrapped, now it is and ebgugign is turned +on - it will inform me if i free already freed or non alloced ram, or +similar stuff with realloc). + +------------------------------------------------------------------------------- + +Tue Jun 2 22:22:00 EDT 1998 +(Mandrake) +Okay, damnit. So now we have a finished (I think) config.c. Only things left +before release now are to add the default strings file, add it to the install +routine, convert test.c into main.c, and then write the default theme. Gee, +not asking for much, am I? *grin* Well, time to send this puppy into cvs +before the wrath of god strikes me down. + +------------------------------------------------------------------------------- + +Wed Jun 3 00:03:00 EDT 1998 +(Mandrake) +Ahoy, matey! -Wall -pedantic to the rescue. I've stripped out test.c to turn +into main.c, I'm going to be adding that file with this update, too. config.c +should be pretty much done, but I'm not sure if the +GrabActionKey(ac->list[0]) +in Config_Keybind is going to work or not. raster was a little busy, so maybe +I have to wait until tomorrow morning to find out. Got to remember to add in +the sound action, too. I mangled a bunch of code to cease warnings, should +make things a little happier (fixed a lot of signed / unsigned stuff, too -- +should make life easier when I decide to try to get this thing to compile on +my alpha. This thing had better work. Well, I have GOT to get some sleep. +You know, that work thing. + +------------------------------------------------------------------------------- + +Wed Jun 3 02:04:04 EDT 1998 +(Raster) +Fixed ALL the Warnings (except for the spurious warning from a system header +- bugger if I know why that happens). Added themes and config dirs to cvs - +empty though, and added them to the Makefile.am to start work on them. At +least the directories will be created now. I need to work out how to create +my own cusotm install procedure that wipes $(prefix)/enlightenment if it's +there and also symlinks (ln -sf) $(prefix)/bin/enlightenment to point to +$(prefix)/enlightenment/bin/enlightenment. Sofar the Automake docs don't +help much. + +------------------------------------------------------------------------------- + +Wed Jun 3 10:20:33 EDT 1998 +(Raster) +Added more checks to configure.in to check for an old install of E and +install in the same place if the user didn't select --prefix=something. Also +added symlibk fomr $(prefix)/bin/enlightement to +$(prefix)/enlightenment/bin/enlightenment. + +------------------------------------------------------------------------------- + +Wed Jun 3 12:35:38 EDT 1998 +(Raster) +Did some more configure.in cleanups, moved environment var settign to setup.c +Turned memory debugging off.. this really slows stuff down + +------------------------------------------------------------------------------- + +Wed Jun 3 17:18:36 EDT 1998 +(Mandrake) +*huff huff huff* +Okay. so now I have added the config dir and the initial definitions file. +That file will have to have a bunch more string definitions added to it, as +I run across them in the config.c loading that I'm going to be undergoing +in a little bit. But this should be enough for people to start actually +noticing what is supposed to happen with this. (if only switch was more +mandrake-friendly we wouldn't have this problem...) I may want to go back +and macro out the switch statements with the ReturnStringReference thingie... +That might make it look a little cleaner, at least. Still need to +add EDBUG and ERETURN all throughout the config.c file + +------------------------------------------------------------------------------- + +Thu Jun 4 19:44:06 EDT 1998 +(Raster) +Optimised shape changing to only reset the windows shape mask if the +shape_chnages flag in Border is set (or on resize or client shape changes). +Bundles of joy with more speed. + +------------------------------------------------------------------------------- + +Thu Jun 4 19:55:07 EDT 1998 +(Mandrake) +Okay. Theme loading working its way into the default build. when main.c is +replaced with test.c now it loads the default definitions file from +ENLIGHTENMENT_ROOT/definitions (probably should use the config subdir or +something for that... NOTE TO SELF: should probably change this later) +LoadEConfig now happens off of main.c, as well, passing a configdir string +into it, which is set to 0 now, so it should try loading a MAIN file out +of your .enlightenment directory next. Which is what I am shooting for now. +the next step is going to be an actual compile and runtime debugging of +loading this default theme that I am brewing up as I write this. the +default theme (in theory) should come with my next commit. Scary stuff, +this is. + +------------------------------------------------------------------------------- + +Thu Jun 4 21:10:15 EDT 1998 +(Mandrake) +Hello. it's me again. So I've added the stub of a MAIN file in the +e/src/config directory. I'm also adding liberally to the definitions file. +I'm getting nervous as more of this starts coming together. I'm trying to +put some comments into the MAIN file as appropriate, too. I also realized +that I need to do something about setting up local user configs (something +I keep talking about but never actually put int) as well as local user +definitions files that might need to go with the user configurations. Also +I need to add a CONFIG_LOAD_FILE type to the config loader. I want peopele +to be able to break this into multiple files again. maybe have like their +"control" section and a bunch of LOAD commands in the primary file. So many +things that I'm thinking of at the last minute... +Hey, BTW... is LIST_TYPE_COUNT supposed to be set to the number of LIST_TYPE +thingies there are? I upped the value to 13. (it was 11) + +------------------------------------------------------------------------------- + +Fri Jun 5 00:37:46 EDT 1998 +(Raster) +Added ACTION_PLAYSOUNDCLASS action :) + +------------------------------------------------------------------------------- + +Sat Jun 6 21:14:34 EDT 1998 +(Mandrake) + +ARGH! I can't believe you ran INDENT on my files that I was working on. +no wonder my freakin' macros weren't working right. I didn't even notice +until I had already mangled large portions of code in config.c. +*mandrake beams raster over the head with a large fish* +for future reference, my indent command is +indent -kr -ts4 -l80 -cli4 +Anyways. Added proper mask detection into the sucker. Now the keybinds should +load properly I mapped Mod1Mask to Alt in the defintions file. What do 2-5 +do? + +------------------------------------------------------------------------------- + +Sat Jun 6 21:52:34 EDT 1998 +(Mandrake) + +Okay. fixed some config.c stuff, added more definitions (they just keep GOING +and GOING and GOING) and added a bit more actionclasses to the MAIN file +in configs. I keep running into stuff I forgot to take into account, so I'm +going back and attempting to repair various bits as they strike me. + +------------------------------------------------------------------------------- + +Sat Jun 6 22:44:45 EDT 1998 +(Mandrake) + +Put up the final to do list. (see Things.Left.etc) +fixed up some more minor problems in config.c. Geez, I just keep running +into oversight after oversight. You would think after working at it for +so long it wouldn't have these little bugs in it, eh? More definitions +(I think there are more definitions every time I do a commit now, though) +Added the "next" subset as it will apply to action classes. I can't +believe I didn't realize that the first time I went through. you need +to be able to bind multiple actionlists. *DUH* + +------------------------------------------------------------------------------- + +Sun Jun 7 01:21:07 EDT 1998 +(Mandrake) + +Yet more config.c changes. Now I've got some of the borders loading off +of the default config file, too. All the actionclasses from test.c are +defined properly, too. the first of the imageclasses should be in +the MAIN file, too. Somehow, I also forgot to link in Config_ImageClass from +the default config loader. D'OH! fixed that. much better now. +Also realized that ReadLRTB was not necessary for all imageclasses. +Now it keeps a pointer to the last used and LRTB became a small subshell. +Also, BORDERLESS type is in MAIN, and DEFAULT has been started. (needed +to check something in now that I have this much modified since the last +one) text classes are in the MAIN file now, too. Maybe I'll finish this +some day in the very near future. More definitions for using fnlib, +too. Decided to make MODE_VERBATIM the default mode for fonts, too +(overrideable, of course) + +------------------------------------------------------------------------------- + +Sun Jun 7 02:14:03 EDT 1998 +(Mandrake) + +More MAIN additions. Also, set FLAG_BUTTON as the default borderpart +type. (that's the one I have been typing so damned much...) +Also, I think I am going to make some of this wmin/wmax,hmin/hmax +stuff oneliners so I can do like w 2 2 and define the wmin/max at the +same time. same for the p/a combos like bxp/bxa and byp/bya and txp/tx§, +etc... I think it might make more sense that way. also, ontop defaults to +yes now. I'm tired of typing that, too *grin* Also, wmax is now automatically +set to wmin's value if you don't set it (same with hmin/max). Also had a +typo in config.c (thanks to frb) Anything I'm typing too much in the +MAIN file is suddenly becoming default configuration options for stuff +*grin* Wonder why that is? + +------------------------------------------------------------------------------- + +Sun Jun 7 11:35:06 EDT 1998 +(Mandrake) + +Still working on the default theme. Completed the DEFAULT borderclass. + +------------------------------------------------------------------------------- + +Sun Jun 7 11:51:25 EDT 1998 +(Mandrake) + +Still working on the default theme. Completed the SHAPED borderclass. + +------------------------------------------------------------------------------- + +Sun Jun 7 12:45:16 EDT 1998 +(Mandrake) + +Still working on the default theme. Completed sound initializations. + +------------------------------------------------------------------------------- + +Sun Jun 7 13:06:38 EDT 1998 +(Mandrake) + +Still working on the default theme. Completed desktop initializations +Also, icl defaults for backgrounds now set to 0 for r,g,b (didn't realize +I didn't do that already) Buttons, here i come! + +------------------------------------------------------------------------------- + +Sun Jun 7 13:45:47 EDT 1998 +(Mandrake) + +Damnit I think the default theme is actually finished now. *sigh* +Now it's time to debug the loader fully, eh? I set wmin=1, wmax=99999, +hmin=1,hmax=99999 to buttons by default, too (because that seemed logical) + +------------------------------------------------------------------------------- + +Sun Jun 7 18:38:28 EDT 1998 +(Mandrake) + +Okay. fixed up some warnings in compiling main.c. My local Makefile is +now also modified to link main.o in instead of test.o. Loaded the default +configuration finally, DAMNIT! HAHAHAHAHA it works! Well, kind of. Lots of +bugs to work out, still, but this is a serious improvement. Only a few +hours of hacking to get that to work. + +------------------------------------------------------------------------------- + +Sun Jun 7 21:53:30 EDT 1998 +(Mandrake) + +Okay. Now I'm actually running off this config loading version. Only a couple +of bugs left in the loader (besides the fact that it's still hardcoded to +pull this bastard out of my home directory). Desktop buttons don't work right, +and neither do Desktop settings loading. But for the most part it looks +pretty good. There is prolly an updated definitions and MAIN file with this +patch. + +------------------------------------------------------------------------------- + +Sun Jun 7 23:04:08 EDT 1998 +(Mandrake) + +Damn this button loading piece of crap. This is seriously annoying now. fixed +a few bugs in the loader but it's still giving me grief. lots of debug +textual output in the loader still, but I got rid of most of it. + +------------------------------------------------------------------------------- + +Sun Jun 7 23:15:10 EDT 1998 +(Raster) +At last! I found the "spurious segfault" bug in E... thanks all to a fast +machine and gimp... :) It wasa amatter of windows being destroyed by the +clients before E finished mapping them. I've now apparently fixed that... :) + +------------------------------------------------------------------------------- + +Mon Jun 8 00:49:37 EDT 1998 +(Raster) +Wheee fixed button loaidng bug.. moved LoadEConfig After MapUnmap(0); after +ages of hunting this bastard down - also optimised initial butotn mapping +and button changing (SimpleShowButton added). Also fixed config files... + +------------------------------------------------------------------------------- + +Mon Jun 8 01:11:52 EDT 1998 +(Mandrake) + +Damn it's good to have that bug fixed. now the MAIN file is loaded from the +configs subdir of wherever you are. Much happier. + + +------------------------------------------------------------------------------- + +Mon Jun 8 23:30:06 EDT 1998 +(Mandrake) + +Well, apparently it wasn't a config loading bug. the buttons worked just +fine, I just forgot some stuff in the config file. fixed that. + +------------------------------------------------------------------------------- + +Tue Jun 9 22:27:34 EDT 1998 +(Mandrake) + +Added local user configs, also changed the loader to look in the right +paths... + +------------------------------------------------------------------------------- + +Wed Jun 10 00:32:03 EDT 1998 +(Raster) + +Finally - cleaned up code, fixed stacking problem, made make install work.. +for now, new border theme, it's getting there.... + +------------------------------------------------------------------------------- + +Wed Jun 10 01:33:48 EDT 1998 +(Mandrake) + +Okay... now we have a local.cfg file to copy around. the MAIN file has +had it's pieces hacked out of it into a new file. Now users can happily +hack what various pieces of their configuration do (and add extra stuff) +without affecting the theme that they're using. happy happy. + +------------------------------------------------------------------------------- + +Wed Jun 10 02:12:52 EDT 1998 +(Mandrake) + +fixed a couple of alert box thingies in the config loader which +SOMEONE (who will remain nameless) commented out. that's gone. +NOTE: imlib 1.6 is now required for this snapshot to run properly. +someone make a new font, too, for the titlebar. it's beginning +to hurt my eyes. too clashing. Also updated checklist + +------------------------------------------------------------------------------- + +Wed Jun 10 09:33:44 EDT 1998 +(Raster) +Did a security AUDIT on E.... OOOOOOOOH CONFIG LOADER had mountians of +exploits! (the writer of such code shall remain nameless). #if'd out an +annoying alret box whne there isnt a local.cfg for the user, and only MAIN's +-E should silently continu as this isn't a bad thing. + +Also added extra redundancy for whne Imageclasses defined for buttons cannot +be found - instead an internal fallback (that is now created) is used. +Also added a fallback border incase a DEFUALT border isn't defined. Also +added fallback Imageclass setting for any border. It mightn't look pretty +(okay it's not bad) but at least things work. Cleaned up 2 nasty wrnings in +x.c + +------------------------------------------------------------------------------- + +Wed Jun 10 13:43:46 EDT 1998 +(Mandrake) + +Damnit that alert is useful. I _WANT_ to keep those defs in a seperate file +and force them there. your MAIN file should not contain defs for the +actionclasses, so you can hotswap themes at will, and keep local config options +gotta enforce that one. + +------------------------------------------------------------------------------- + +Fri Jun 12 14:39:37 EDT 1998 +(Mandrake) + +Added some stuff to the imageclass loader so it now does the sticky and +sticky_active portions, also fixed a bug in the sound on/off loader. +Well, I thought I fixed it, anyways. Apparently it doesn't really +affect trying to do sounds. i'm going to try fixing that. + +------------------------------------------------------------------------------- + +Fri Jun 12 18:04:06 EDT 1998 +(Mandrake) + +Got annoyed at not having a simple way to do ACTION_GOTO_DESK so +fixed that. :) also added in bindings into default local.cfg file. + +------------------------------------------------------------------------------- + +Sat Jun 13 12:21:09 EDT 1998 +(Mandrake) + +Apparently raster did some stuff without making notes in the changelog. +have no idea, 'cept that now things are alert'ing again where they +weren't supposed to. Oh well. fixed that. also fixed the alt-f1 -> +alt-f8 stuff to do desktops 0-7 instead of 1-8 (forgot about the +numbering from 0 thing) + +------------------------------------------------------------------------------- + +Sat Jun 13 12:21:09 EDT 1998 +(Raster) + +last night and today... I fixed all the snprintf's to be wrapped by Esnprintf +and we have our own snprintf incase the system doesn't have one. I added +MODe_DESKRAY and deskray stuf to put "tags" where the dragbar of each +desktop is in deskray mode ontop of all desktops to be able to drag a +desktop slid underneath others out when in this mode. -also added images for +this.. it all works perfectly.,. added a ListIdemTypeID to list items by +type ANd id (i now use i'ds to class buttons 0 is nromal "user buttons) 1 is +dragbar, 2 is deskray .. etc..all internal use only). I also added images +for verticla dragbar (looks much nicer now), made button dragging mroe +efficient... fixed mandraked gotodesk action... :) + +------------------------------------------------------------------------------- + +Sat Jun 13 14:04:30 EDT 1998 +(Mandrake) + +added a little bit of a wrapper in ELoadImage() in draw.c to check +a few path locations to find the image that we're going to try to load. +now you shouldn't have to change subdirs for the images. Next to do +the same thing for the sounds. then happy happy that'll be done. + +------------------------------------------------------------------------------- + +Sat Jun 13 14:25:04 EDT 1998 +(Mandrake) + +Excellent. now sound loading has a wrapper around it, too. Things are +looking to be shaping up. Now you don't have to do any special setup +to run the default configuration, it should install nicely and run everything +out of the default theme. next to actually parse the commandline and +get the themepath. :) + +------------------------------------------------------------------------------- + +Sat Jun 13 15:55:47 EDT 1998 +(Raster) +Fixed file.c's pathtoexec and pathtofile fucntiosn to handle absolute paths. + +------------------------------------------------------------------------------- + +Sat Jun 13 16:43:01 EDT 1998 +(Mandrake) + +Made sure that the LoadWav and ELoadImage accept absolute paths (if +they exist) + +------------------------------------------------------------------------------- + +Sat Jun 13 17:02:15 EDT 1998 +(Mandrake) + +Now we take a -theme argument on the commandline to set themepath. + +------------------------------------------------------------------------------- + +Sat Jun 13 17:37:22 EDT 1998 +(Mandrake) + +added some more settings to the control section of the config file. + +------------------------------------------------------------------------------- + +Sat Jun 13 20:37:20 EDT 1998 +(Mandrake) + +Now you can source files using the "file " operative but only +in the primary loader... (there is a reason for this that I would +like to solve so you can source at any point, but for now this will do) +Also, I changed out some of the StringCount stuff that I had done earlier as a +temporary hack that I forgot to remove (1 less global variable that should be +gone anyways after the loader is done with its business...) + +------------------------------------------------------------------------------- + +Sat Jun 13 21:00:37 EDT 1998 +(Mandrake) + +Um... well the global variable hack is back. doesn't work yet without +it. I _DO_ intend to fix that, however. + +------------------------------------------------------------------------------- + +Sat Jun 13 21:12:20 EDT 1998 +(Mandrake) + +Oh yeah... fixed a bug in launching actions, too. I had been meaning to +do that. + +------------------------------------------------------------------------------- + +Sun Jun 14 12:11:43 EDT 1998 +(Mandrake) + +*sigh* finally tracked down a bug in the -theme parameter passing. It +should actually work correctly now. Also removed some of my debugging +comments. + +------------------------------------------------------------------------------- + +Sun Jun 14 13:24:02 EDT 1998 +(Mandrake) + +ARGH! more -theme problems. fixed them. also, Chutt provided me +with a patch that should lower the RSS in the sound.c department. +put that in, too. (the -theme problem REQUIRED you give a -theme +argument. that's taken care of now) + +------------------------------------------------------------------------------- + +Sun Jun 14 13:34:04 EDT 1998 +(Mandrake) + +Also, turned off debug mode. fixed a bug in EDBUG() if DEBUG isn't +defined. debug mode is much slower for certain things. + +------------------------------------------------------------------------------- + +Sun Jun 14 14:28:16 EDT 1998 +(Raster) + +Added new font to theme - added stuff to config.c to add config dir +./enlightenment and the themedir to fnlib'c search path so fonts can be +included in themes (much nicer) - have a new font tin-e it's small as balls +but readable - as long as you're not driving your monitor beyond what it can +do. + +------------------------------------------------------------------------------- + +Sun Jun 14 14:48:10 EDT 1998 +(Mandrake) + +Found and fixed a memory leak on changing drag directions. +Might have noticed another memory leak, still investigating. + +------------------------------------------------------------------------------- + +Sun Jun 14 16:47:05 EDT 1998 +(Raster) + +Added detaild memory debug output to aid in hunting down leaks.. hit left +mouse and E will display (printf) a debug output + +------------------------------------------------------------------------------- + +Sun Jun 14 16:55:54 EDT 1998 +(Mandrake) + +Changed a few things in the local.cfg file. + +------------------------------------------------------------------------------- + +Sun Jun 14 17:24:48 EDT 1998 +(Mandrake) + +-DDBUG_MEM and -DDEBUG should be done at compiletime, not in the source. + +------------------------------------------------------------------------------- + +Sun Jun 14 17:46:56 EDT 1998 +(Mandrake) + +added BorderMatch loader. + +------------------------------------------------------------------------------- + +Sun Jun 14 19:25:15 EDT 1998 +(Raster) + +Finished Colormodifer creation and applying in iclass.c - shoudl work in +theory.. now we need a config loader section for this..... :) then i can try +it out! :) + +------------------------------------------------------------------------------- + +Sun Jun 14 20:39:22 EDT 1998 +(Mandrake) + +*sigh* this ecvs app thing is being a pain in the ass. removed some of it +on my part. Blech. Fixed the BorderMatch loader to do something useful. +(added definitions, changed config.c, conf.h) + +------------------------------------------------------------------------------- + +Sun Jun 14 22:15:02 EDT 1998 +(Mandrake) + +Um, did you even bother attempting to compile cmclass.c? didn't think +so. fixed compilation problems, also added into Makefile.am so +now it should actually compile in (need to run autogen.sh again) +Also fixed a bug in my last commit. I'm getting slow in +my old age. + +------------------------------------------------------------------------------- + +Sun Jun 14 23:51:37 EDT 1998 +(Mandrake) + +Fixed another bug in the damned bordermatch loader. + +------------------------------------------------------------------------------- + +Tue Jun 16 13:16:53 EDT 1998 +(Mandrake) + +SoundInit() was before LoadEConfig. DOH! fixed that. + +------------------------------------------------------------------------------- + +Tue Jun 16 19:18:04 EDT 1998 +(Mandrake) + +themes can now be put in ENLIGHTENMENT_ROOT/theme/ now, as well +(absolute path is still checked first) + +------------------------------------------------------------------------------- + +Tue Jun 16 20:04:51 EDT 1998 +(Mandrake) + +Fleshed out the ColorModifier loader. unfortunately, since I don't know +really what it's supposed to do, that makes testing a wee bit difficult. + +------------------------------------------------------------------------------- + +Fri Jun 19 01:42:02 EDT 1998 +(Mandrake) + +these are some notes from over the past few days... +Been working on ImageClass stuff, realized that I didn't allow users +to load disabled images for imageclasses. fixed that bug. also +worked on class inheritance for the config loader, and allowing +imageclasses to have their own overlays. + +------------------------------------------------------------------------------- + +Sat Jun 20 17:54:10 EDT 1998 +(Raster) + +Fixed ColorModifierClasses to work with bakcgorunds and everything.. they +work.. I just need mandrakes loaidng code to work and we're done there... +changed the tin-e font to be cleanerm neater and easier to read. :) + +------------------------------------------------------------------------------- + +Sun Jun 21 16:07:02 EDT 1998 +(Mandrake) + +Well, the colormodifier loader should work now okay. and yes, this font is +much easier to read. I suppose I'm going to have to write a colormodifier +configuration to read and muck with it now to make sure it works okay. + +------------------------------------------------------------------------------- + +Sun Jun 21 16:20:46 EDT 1998 +(Mandrake) + +Hmm... forgot to let you apply colormodifier's to individual images in +the imageclass. fixed that. now it'll apply to the whole class if you +haven't defined a portion yet. :) + +------------------------------------------------------------------------------- + +Sun Jun 21 19:02:51 EDT 1998 +(Mandrake) + +Now colormodifier curves take x/y coordinate pairs, and they can take +a (theoretically) infinite set per. Much better. +I.E. +red 0,25 1,60 50,100 +I like that lots better than the other way I had. + +------------------------------------------------------------------------------- + +Sun Jun 21 19:32:06 EDT 1998 +(Raster) + +fixed a typo in the actions defines that made it look ugly, fixed up the +soudn class stuff to dynamically on demand load samples, and to fre samples +form ram AND esd when soudn is turned off and reload them when turned on +again on demand, on/off sound works properly now, with an icon/button to +toggle it. Will be working on buttons mroe more stuff in E next... + +------------------------------------------------------------------------------- + +Sun Jun 21 20:53:22 EDT 1998 +(Mandrake) + +Now GetNextLine (text parser) will substitute in environment variables +during config parsing with $VARIABLE substitution. + +------------------------------------------------------------------------------- + +Sun Jun 21 21:34:17 EDT 1998 +(Raster) + +Added several border styles to the list of borders and bordermatches for +them (SHAPED, TRANSIENT and non-resizable (FIXEDSIZE) windows) - and fixed +the shaped window detection routines... + +------------------------------------------------------------------------------- + +Sun Jun 21 22:02:23 EDT 1998 +(Raster) + +made "borderless" windows that are borderless becuase the app requested +being borderless via MWM hints arent slid onto sreen but mapped directly... + +------------------------------------------------------------------------------- + +Sun Jun 21 22:50:16 EDT 1998 +(Raster) + +made the arrangement algorithm avoid buttons when arranign windows on +startup and cleanup... :) + +------------------------------------------------------------------------------- + +Mon Jun 22 11:10:23 EDT 1998 +(Raster) + +Added change focusmode button and images - didcovered now that +click-to-focus over time has become completely fetn and am working on a fix... +I HATE click-to-focus... its always the first thing to break.... DAMN DAMN + +------------------------------------------------------------------------------- + +Mon Jun 22 22:01:08 EDT 1998 +(Raster) + +Finally fixed click to focus.... WHEEEEEEEEEEEEEEEe! oh what funt hat was! + +------------------------------------------------------------------------------- + +Tue Jun 23 00:13:45 EDT 1998 +(Raster) + +fixed missing #ifdef in sound.c - updated things.to.do..... + +------------------------------------------------------------------------------- + +Tue Jun 23 14:53:30 EDT 1998 +(Raster) + +fixed pointer focus and tried a fix for click to focus to stop mandrake form +whining.... + +------------------------------------------------------------------------------- + +Tue Jun 23 15:23:08 EDT 1998 +(Raster) + +added button to change resizemode + +------------------------------------------------------------------------------- + +Wed Jun 24 01:33:15 EDT 1998 +(Raster) + +Added buttons for toggling mapslide and deskslide.... + +------------------------------------------------------------------------------- + +Fri Jun 26 00:30:39 EDT 1998 +(Raster) + +Added buttons for cleanupslide, slidemode, dragdir and dragbarorder and +created buttons for them to config them on the fly, and fixed a minor bug in +the definitons file.. misc typo... + +------------------------------------------------------------------------------- + +Fri Jun 26 10:16:49 EDT 1998 +(Raster) + +Added options to the exit function for restart restart_theme and restart_wm +(to restart another wm). :) also added more env vars set by E. + +------------------------------------------------------------------------------- + +Sat Jun 27 15:20:09 EDT 1998 +(Raster) + +Lots of things: +removed crappy (possibly copyrighted) bgs form the pix dir. Fixed +backgroudns to use one of 3 defined. +fixed desktp bg loader to re-use defined bgs +fixed desktop loader and desktop bg refresher to work 100% properly on multi +depth displays (eg 24+8) - foucn accelX has a bug in 24+8 whereby it "loses" +the framebuffer bits for some windows.. will have to ship this off to xig. +fixed desktop refresher to not accidentally load an extra background when +flipping desktops. +fixed dragbars for bottm and right configs to not accidentaly drag too far +to the bottom and right +fixed resizing of window for sizing to the left or up so it remains +stationary, doesnt jump, and doesnt go sldiin away is i resize too clsoe to +0 in those dirs. +truned of dynamic border chaning caus enetscape does ugly things on tis +transients when they close. not sure exactly why right now, but turning it +off makes things ok again. +added more icons for things like dragbar ordering dragdir chaningng and +others... + +------------------------------------------------------------------------------- + +Sat Jun 27 18:09:32 EDT 1998 +(Raster) + +Added auto-save on exit funtion - changed config fielnames to be more human +redable and make mroe sense +added theme_pre.cfg file to read +added the user_autosave.cfg at the end + +added signal handlers for every signals under the sun. (segfaqult, sigbus, +sigfpe, usr1, usr2, hup etc....) + +------------------------------------------------------------------------------- + +Sun Jun 28 12:50:14 EDT 1998 +(Raster) + +modified button loader to look for previous button defs of that name first +and if they exit the new entry modifies the old one rather than creating a +new one... :) now i can go add button gemoetry saving to the saver too. + +------------------------------------------------------------------------------- + +Sun Jun 28 13:43:50 EDT 1998 +(Raster) + +Wheeeeeeeeee! now E saves the position of all butotn son edit and whne u +restart theyr'e just where oyu left them (and if you change rsolutions ie +use the same configs on yer laptop) it will auto adjust for it :) +neat eh? + +------------------------------------------------------------------------------- + +Sun Jun 28 21:18:40 EDT 1998 +(Raster) + +Okay added lots of icons for programs and button defs for tham. + +------------------------------------------------------------------------------- + +Mon Jun 29 00:28:40 EDT 1998 +(Raster) + +Added autosave toggle butotn - moved defautl butotn locations around, fixed +variable completion bug in config.c + +------------------------------------------------------------------------------- + +Mon Jun 29 12:26:25 EDT 1998 +(Raster) + +fixed box resize and move nto to accidentally leave trails. + +------------------------------------------------------------------------------- + +Mon Jun 29 21:35:36 EDT 1998 +(Raster) + +Changed clock-to-focuse to raise on click too, fixed minor bug when moving +and resizign widnows ANd chanign desktops.... + +------------------------------------------------------------------------------- + +Mon Jun 29 22:56:31 EDT 1998 +(Raster) + +Woho! fixed lots and lots of fd leaks in sound... :) ooops + +------------------------------------------------------------------------------- + +Wed Jul 1 20:18:52 EDT 1998 +(Raster) + +fixed some other minor nigglies in drawing code. + +------------------------------------------------------------------------------- + +Thu Jul 2 20:39:00 EDT 1998 +(Raster) + +Added 2 more buttons for the desktop config and played wiht dox to make it +slicker.. :) + +------------------------------------------------------------------------------- + +Fri Jul 3 03:19:14 EDT 1998 +(Raster) + +Made -theme work properly. +added file seracher function and use that now for loading images and sounds. +added theme finder function +added .tar .tar.gz and dirtecotry theme handlign transparently. +added code to clenaup .tar znd .tar.gz themes hwne done. +made the move on desktops other than root not clicker untilt he window is +dragged out of the bounds of that desktop - still flicker then but it's the +best I can do. + +*** need to reorganise default theme stuff ot be nice and friendly to users +AND theme makers alike. + +------------------------------------------------------------------------------- + +1998-07-05 Yo Ric Dude + + * sound.c (SoundPlay): added necessary changes for esound-0.2.4 api + change. All esd_open_sound() calls now require a string parameter if + a remote esd server is to be used, NULL for defaults. Also adds a + string parameter to the esd_sample_cache call, to identify the sample + by name. All samples currently have the name "E". TODO: make the + name an event type or sound filename. Also included fix to run sample + caching and playing off the same esd socket. A #if 0/1 block switches + between esound-0.2.3 workarounds and the new improved esound-0.2.4 api + +------------------------------------------------------------------------------- + +Mon Jul 6 10:32:26 EDT 1998 +(Mandrake) + +Ric forgot to actually make the stuff for 0.2.3 work with 0.2.3. +fixed that. + +------------------------------------------------------------------------------- + +Wed Jul 8 00:08:21 EDT 1998 +(Raster) + +did lots of minor fixes - fixed theme extraction and file finders, changed +alert messaged to be more helpful, fixed stuff to look smoother when +flipping bakc to desktop 0, and whilst mappign buttons....... + +------------------------------------------------------------------------------- + +1998-07-05 Yo Ric Dude + + * sound.c: corrected parameter to esd_open_sound(). fixed 0.2.4 + compatibility section. cvs versions of each should be in synch. + The calls to esd_open_sound(NULL) may break under esoundd-0.2.3. + +------------------------------------------------------------------------------- + +Wed Jul 8 20:59:29 EDT 1998 +(Mandrake) + +Due to incessant complaints via email, the default esd used in compiles is +0.2.3 once again until 0.2.4 comes out. (change the #if 0/1 place to +flipflop) Also, I think I added multi-key modifiers correctly. not +fully tested, will probably do that a little later. Back to work on +ConfigEdit... + +------------------------------------------------------------------------------- + +Wed Jul 8 22:23:53 EDT 1998 +(Raster) + +Due to lack of incessant complaints via email, the default esd used in +compiles is 0.2.4 once again. (change the #if 0/1 place to +flipflop) I also added hide and showing of buttons with actions (with lots +of options) so u can clean out unused buttons as needed - even using regular +expressions for butotn name matching... also fixed sticky window move bug +and a mem leak int he doCleanup() function. + +------------------------------------------------------------------------------- + +Thu Jul 9 01:28:40 EDT 1998 +(Raster) + +Fixed sticky window drawing bug. +Fixed bug in config loader for ctrl+lat and ctrl+shit+alt etc.. to work. +did a bit of cleaning in the config files and chnaged all the keybindings to +new ones, now things are much mroe sane... + +------------------------------------------------------------------------------- + +Sun Jul 12 13:40:02 EDT 1998 +(Mandrake) + +still updating stuff with configedit. + +------------------------------------------------------------------------------- + +Sun Jul 12 23:23:39 EDT 1998 +(Raster) + +fixed minor rpoblem with initiating other actions whilst another one is in +prograss (ie basically move and resize actions) - excluded these other +actions form being able to happen whilst these "continuing" actions are still +going. + +------------------------------------------------------------------------------- + +Tue Jul 21 22:08:33 EDT 1998 +(Mandrake) + +Added Stalyn's xevent patch in. Hopefully his first of many contributions. +It'll be nice if someone else joins the dev team. Anyways this patch should +theoretically speed up pretty much all of normal operations, since it's the +primary activity in the primary event loop. As soon as stayln gets cvs access +I'll let him ramble about his change. + +------------------------------------------------------------------------------- + +Thu Jul 23 14:25:43 EDT 1998 +(Mandrake) + +Thanks to Ashley Clark for pointing out a fix for the problems that +various people were having with EROOT not being set correctly (has to do +with unexpected behaviours of putenv vs. setenv -- let's hope this one +will work correctly) + +------------------------------------------------------------------------------- + +Tue Jul 28 21:16:26 EDT 1998 +(Mandrake) + +Muahahahaha. StringList compiled into the primary source tree now :) +I'll try to state this whole thing with one commit (I hope this works enough) +A lot of the more fundamental functionality of enl's file system structure +has been moved into StringList (e/eStringList) as well as the StringList +stuff itself, the debugging macros, et cetera. e/src/file.c is no more, +also (fully a part of StringList lib). also, the Alertbox stuff (which +will end up being generically useful for both console and X applications) +was taken and put into StringList. expect a good deal more to go into +the StringList library over the course of the week. + +------------------------------------------------------------------------------- + +Fri Jul 31 23:09:14 EDT 1998 +(Mandrake) + +Changed some stuff in main.c to use the new StringList generic alert box +initialization stuff. Still have a bunch of work to do there, but it's +coming along okay. + +------------------------------------------------------------------------------- + +Sat Aug 1 15:19:17 EDT 1998 +(Mandrake) + +Changed EExit() to return an int and take a (void *) as an argument in order +to comply with the stuff that StringList wants. all files using EExit +were affected. + +------------------------------------------------------------------------------- + +Sat Aug 1 16:19:06 EDT 1998 +(Mandrake) + +Changed the configure.in file to use imlib-config for stuff instead of checking +for various libs (it's a better idea to let users selectively remove support +from imlib if they feel like it, IMNSHO). + +------------------------------------------------------------------------------- + +Sun Aug 2 11:29:07 EDT 1998 +(Mandrake) + +Added a patch from Sung-Hyun Nam to support X fonts in +text classes, as well as Fnlib fonts. Especially important for non-standard +language fonts (like kanji, etc). + +------------------------------------------------------------------------------- + +Wed Aug 5 21:04:36 EDT 1998 +(Mandrake) + +Added in a patch from Kimball Thurston to attempt a little +more cross-platform support. This should help things considerably. +this includes alloca problems, as well as a setenv macro, and a #define for +choosing the shell (IRIX apparently uses restricted mode ksh for its /bin/sh - +evil!) + +------------------------------------------------------------------------------- + +Sat Aug 8 20:07:21 EDT 1998 +(Raster) + +Added minor change to CTF event passing code - added anti-aliased truetype +font support.. :) + +------------------------------------------------------------------------------- + +Sun Aug 9 15:07:34 EDT 1998 +(Mandrake) + +Good lord. Removed ewin->state. Now THAT was a bit tricky. Everything looks +okay. although after mucking with that I think that maybe I should have +gone the other way :) a little of the iconification stuff in this check-in +(lists.c changes specifically not going in due to severe breakage which happens +at that point) + +------------------------------------------------------------------------------- + +Sun Aug 9 22:33:12 EDT 1998 +(Mandrake) + +More General Insanity. Progress on the iconification front. fixed the +stuff I mangled in lists.c (put it back the old way, did a simple thing this +time instead of the copmlicated window listing stuff) ACTION_ICONIFY is +still iffy at best - but it does something now :) + +------------------------------------------------------------------------------- + +Tue Aug 11 12:15:23 EDT 1998 +(Mandrake) + +More Iconification stuff. almost works + +------------------------------------------------------------------------------- + +Wed Aug 12 13:05:48 EDT 1998 +(Mandrake) + +Iconification works. Well, at least kinda. Actionclasses are left over +as a slight memory leak until I fix that. also they all look like the +ACTION_EXIT button. they also all appear in the same location. well, to +be honest there's a lot left to do, but at least this is the model that will +work :) + +------------------------------------------------------------------------------- + +Wed Aug 12 19:38:41 EDT 1998 +(Raster) + +Added program specified position hint support - new default theme. fun. + +------------------------------------------------------------------------------- + +Thu Aug 13 16:29:39 EDT 1998 +(Stalyn) + +Well, i added basic support for dock apps. You can use your old and new +WindowMaker dock apps. There is still lots to be done but this is pretty +usable. You can change your dock icon in theme_pre.cfg, the one i included +is just one i found on my hd. Hopefully raster will make a better looking +one later. + +------------------------------------------------------------------------------- + +Fri Aug 14 13:28:51 EDT 1998 +(Raster) + +Fixed doc support - it actually now works - events are captured on "dock +buttons" so you can drag them around - the events are also passed onto the +dock client window, now random apps aren't docked anymore (fixed ICCCM stuff +for that). Bascially it's working now - maybe not pretty. + +------------------------------------------------------------------------------- + +Fri Aug 14 17:04:27 EDT 1998 +(Raster) + +Added code to do slideouts - missingh config reading code for them though. +need to write this in order to test.... :) + +------------------------------------------------------------------------------- + +Fri Aug 14 19:36:40 EDT 1998 +(Mandrake) + +Created the actual action class destructors. well, you don't really +want to run a destructor of an actionclass from within itself. that was bad. +(we sat staring at gdb for a while on that one *grin*) + +------------------------------------------------------------------------------- + +Sat Aug 15 16:52:27 EDT 1998 +(Mandrake) + +Fixed a leak in dockable apps where a useless actionclass was created on the +button the apps dock themselves in. Should be much cleaner now :) + +------------------------------------------------------------------------------- + +Sat Aug 15 20:04:18 EDT 1998 +(Mandrake) + +Changed things to use DEFAULT_DOCK_BUTTON and DEFAULT_ICON_BUTTON +also adddd the icon button def into theme_pre.cfg + +------------------------------------------------------------------------------- + +Sun Aug 16 01:34:57 EDT 1998 +(Mandrake) + +Added some config code for the slideout menus, but they don't actually +work so don't bother. + +------------------------------------------------------------------------------- + +Sun Aug 16 02:56:26 EDT 1998 +(Raster) + +Slideouts now.. um.. work.. WHEEEEEEEEEEEEEEE What more ned I say.. need to +actually assing sane actions to the slideout and maybe create some new +actions... but it's there and waiting - the onyl thing.. auto reverse +slideout direction if it can't fit on screen. + +------------------------------------------------------------------------------- + +Sun Aug 16 11:48:15 EDT 1998 +(Mandrake) + +pulled windowmatching stuff into it's own .c file + +------------------------------------------------------------------------------- + +Sun Aug 16 12:39:02 EDT 1998 +(Raster) + +Slideouts actually do just that now - slide out. use generic speed adjusting +slide function, You can't drag the buttons out of slidouts now either... + +------------------------------------------------------------------------------- + +Mon Aug 17 00:33:29 EDT 1998 +(Mandrake) + +Changed everything that said BorderMatch to WindowMatch. CreateWindowMatch +will no longer take a Border as a parameter in a moment (you assign that +afterwards, as well as an Icon type, which the WindowMatch struct now also +contains a pointer for) + +------------------------------------------------------------------------------- + +Mon Aug 17 10:37:15 EDT 1998 +(Raster) + +Fixed autosaver to flag buttons as default_show no if they're not visible - +it wont autosave internal buttons now too. the button hider al;so wont go +around hiding buttons in slidouts now. :) + +------------------------------------------------------------------------------- + +Mon Aug 17 22:33:34 EDT 1998 +(Stalyn) + +Alright, i added some code so the docks wont overlap and allows the user +to define a starting dock position and the direction of the docks to be +sorted. Mandrake will have to add config code for this to be usable. + +------------------------------------------------------------------------------- + +Tue Aug 18 00:40:40 EDT 1998 +(Mandrake) + +added configuration for mode.dockdirmode in control segment. also made +up/down stuff accord with the other modes. default direction is +right. you can add a +dockdir right (left/up/down/right) +in the user_main.cfg in the control {} segment + +------------------------------------------------------------------------------- + +Tue Aug 18 13:14:51 EDT 1998 +(Raster) + +Now E passes -pedantic again... :) + +------------------------------------------------------------------------------- + +Fri Aug 21 11:07:57 EDT 1998 +(Mandrake) + +Changed dox's configure.in to check for imlib-config, as well as updated +E's configure.in to say imlib 1.8 + +------------------------------------------------------------------------------- + +Tue Sep 22 11:54:36 CDT 1998 mej + + * dox/Makefile.am, eesh/Makefile.am, src/Makefile.am: Added + -I$(prefix)/include to INCLUDES + * dox/configure.in, eesh/configure.in, src/configure.in: Removed '-g' + from CPPFLAGS. CPPFLAGS should only consist of flags for 'cpp' to + recognize, and '-g' isn't one of those. '-g' belongs in CFLAGS. + +------------------------------------------------------------------------------- + +Wed Sep 23 13:36:21 CDT 1998 mej + + * src/tooltips.c: Fixed E seg faulting if the image classes for the + hard-coded tooltip were not found. (Or as raster would say, + pffffffft!) + +------------------------------------------------------------------------------- + +Mon Sep 28 11:09:43 CDT 1998 mej + + * src/configs/user_main.cfg.in: Fixed typo "tootiptime" + +------------------------------------------------------------------------------- + +Wed Oct 7 19:36:58 PDT 1998 Manish Singh + + * auto* redo: consolidated configure.in's into one, made econfig.h + removed unecessary checks, used imlib and esd config macros, + split the libraries into separate variables, removed cruft + +------------------------------------------------------------------------------- + +Thu Oct 8 10:40:06 EDT 1998 +(Raster) + +Fixed E soe it BUILDS AGAIN - mising stuff like um.. oooh econfig.h.in ? and +also made the header files include "../econfig.h" - also added better gnome +hint support and more.... + +------------------------------------------------------------------------------- + +Mon Oct 12 21:27:09 PDT 1998 Manish Singh + + * configure.in: Be nice to poor, confused people and guess some + LDFLAGS for them. Aren't I a sweetie? Mommy loves you. + +------------------------------------------------------------------------------- + +Tue Oct 13 21:03:59 PDT 1998 Manish Singh + + * fixes for make dist, auto* cleanups, a bit more mothering + +------------------------------------------------------------------------------- + +Thu Oct 22 09:38:18 EDT 1998 +(Mandrake) + +applied a spelling patch from James Fifield + +------------------------------------------------------------------------------- + +Sat Nov 14 23:28:46 EST 1998 +(Raster) + +Recent changes: +added double click event +added virtual desktop support (as in 1 large desktop) - the back end shoudl +all be there... waiting for config changes to go throught to finish it off. + +------------------------------------------------------------------------------- + +Sun Nov 15 11:30:14 EST 1998 +(Raster) + +Please note.. src/ChangeLog actually has all the interesting stuff.... :) That +is generally what gets updated. + +------------------------------------------------------------------------------- + +Tue Nov 24 21:31:56 EST 1998 +(Manish Vachharajani) + +add a #undef HAVE_SM to econfig.h.in + +------------------------------------------------------------------------------- + +Fri Dec 11 15:29:07 CST 1998 +(KainX) + +If FSSTD is enabled, honor configure flags that were getting ignored before, +such as --bindir and --datadir. + +Also, the CPPFLAGS entry for ENLIGHTENMENT_* in epp/Makefile.am was removed +since it is never used. + +------------------------------------------------------------------------------- + +1998-12-14 Herbert Valerio Riedel + + * epp/cppmain.c: added #include + * epp/cpplib.c: added #include + * epp/cppexp.c: always #include + * epp/cppalloc.c: added #include + +------------------------------------------------------------------------------- + +Wed Dec 23 12:29:11 EST 1998 +(Mandrake) + +actually check for esd 0.2.7 if we say that's what we're looking for :) + +------------------------------------------------------------------------------- + +Thu Dec 24 13:02:00 EST 1998 +(Mandrake) + +cleaned up epp a little bit. indent should stop barfing on it, also removed +all instances of alloca. also stopped a few places with potential crashes in +free()'ing memory. + +------------------------------------------------------------------------------- + +Fri Dec 25 17:36:51 EST 1998 +(Mandrake) + +upped imlib requirement to 1.8.2 + +------------------------------------------------------------------------------- + +Mon Dec 28 13:27:18 EST 1998 +(Mandrake) + +added --enable-sound=no option, for those people that want to force E to +compile without sound. + +------------------------------------------------------------------------------- + +Mon Apr 5 19:35:03 PDT 1999 +(Yosh) + +${prefix} and friends aren't expanded in config headers, so put them back +in the Makefile.am. Use DEFS instead of CPPFLAGS, since that solves the +problem better anyway. + +------------------------------------------------------------------------------- + +Fri Jun 4 10:05:32 CDT 1999 +(KainX) + +Don't tell users to proceed with a "make" if the configure step fails. + +------------------------------------------------------------------------------- + +Fri Jun 25 10:22:21 CDT 1999 +(KainX) + +Patch for builddir != srcdir from Colin Gibbs . + +------------------------------------------------------------------------------- + +Thu Jul 1 14:14:06 PDT 1999 +(Mandrake) + +stuff. diff --git a/FAQ b/FAQ new file mode 100644 index 00000000..e69de29b diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..b42a17ac --- /dev/null +++ b/INSTALL @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/IPC.todo b/IPC.todo new file mode 100644 index 00000000..802a939d --- /dev/null +++ b/IPC.todo @@ -0,0 +1,100 @@ +IPC checklist: +( ) - not done +(*) - done + +-------------- + +help: +(*) - basic command list + (this could use some better formatting) +(*) - extended command list +(*) - individual command help +-------------- +(*) version information +-------------- +(*) Copyright information +-------------- +(*) Autosave toggle +-------------- +(*) Default Theme Selector +-------------- +(*) theme lister +-------------- +(*) restart command (also restart_wm, restart_theme) +-------------- +(*) exit command +-------------- +(*) Desktop/area changers +-------------- +(*) Desktop/area number settings +-------------- +(*) icons toggle +-------------- +(*) focus mode selector +-------------- +(*) focus advanced options settings +-------------- +(*) window/client lister +-------------- +(*) move mode selector +-------------- +(*) resize mode selector +-------------- +(*) audio toggle +-------------- +( ) create / delete / modify imageclasses +-------------- +( ) create / delete / modify actionclasses +-------------- +( ) create / delete / modify "keybindings" +-------------- +( ) create / delete / modify "mousebindings" +-------------- +(*) create / delete / modify soundclasses +-------------- +( ) create / delete / modify borderpart +-------------- +( ) create / delete / modify border +-------------- +( ) add / change / delete background +-------------- +(*) toggle/set autoraise timeout +-------------- +(*) toggle/set tooltip timeout +-------------- +(*) toggle/set window placement mode +-------------- +(*) toggle/set dragbar mode +-------------- +(*) toggle/set sliding method / speed +-------------- +(*) toggle/set window shading speed +-------------- +(*) toggle/set edge resistance speed +-------------- +(*) set/retreive focused window +-------------- +(*) toggle menu animation +-------------- +(*) toggle active pager +-------------- +(*) toggle active network +-------------- +window operations: +(*) close +(*) annihilate +(*) iconify +(*) shade +(*) stick +(*) width/height/size toggles +(*) border selector +(*) desk/area selector +(*) raise/lower +(*) move/resize +(*) move/resize relative +(*) focus +-------------- +(*) Pop up a dialog box +-------------- +( ) Pop up a more complicated input box and get results + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..5a639635 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,7 @@ +SUBDIRS = \ + dox \ + eesh \ + epp \ + src + +EXTRA_DIST = e.spec configure configure.in TODO econfig.h.in diff --git a/NEWS b/NEWS new file mode 100644 index 00000000..f8065323 --- /dev/null +++ b/NEWS @@ -0,0 +1,15 @@ +Wed May 13 21:03:23 EDT 1998 + +Moved everything to autoconf/automake + +Sat May 16 12:23:30 EDT 1998 + +Packaged up a snapshot + +Sat May 16 20:42:22 EDT 1998 + +Packaged up a snapshot + +Thu Jul 1 14:20:31 PDT 1999 + +Did stuff diff --git a/README b/README new file mode 100644 index 00000000..d93d5149 --- /dev/null +++ b/README @@ -0,0 +1,16 @@ +------------------------------------------------------------------------------- + E N L I G H T E N M E N T - CVS VERSION IN DEVELOPMENT. +------------------------------------------------------------------------------- + + + +this is a test. +Welcome to Enlightenment 0.16. + +This version is currently only available via CVS, and thus there isn't +any help available. try asking for help online in #E on EFNet (irc) + +the current CVSROOT is +:pserver:anonymous@cvs.on.openprojects.net:/cvs/enlightenment + +the password is blank (just hit return when prompted) diff --git a/TODO b/TODO new file mode 100644 index 00000000..6b36b50e --- /dev/null +++ b/TODO @@ -0,0 +1,51 @@ +---------------- +FEATURES to ADD: +---------------- +(*) extend IPC +(*) focus switching options +(*) icon revisiting +(*) containers +(*) button strips and joints +(*) network file retreival via http and ftp +(*) automatic-upgrade paths +(*) upgrade notification + +(*) snapable and then selectable multiple configs +(*) filemanager in E (Xdnd) +(*) iconbox (also transparent iconbox) +(*) panel - like dock app containers (redo dock apps and an api for them) +(*) widgets (slider, scrollbar, cyclebutton) - fix tables in tables + fix rowspan for table. +(*) optimse menu loading when it has icons. +(*) FX api needs expanding with fx parameer structs and possible gui for them +(*) sound on focus change +(*) add support for icon miniature elements for window borders etc. (need to + munge this out of eirhter the icon pixmap, or the KDE hint if there - also + add hints for apps to be able to set 24bit image data to make it easier + for scaling etc.) +(*) add support for app defined border elements +(*) settigns dialogs need to autoarrange not be centered + +------------ +BUGS to FIX: +------------ + +(*) autoarrange needs to better handle "no space left on display" rather than +just putting window int he middle (and still needs to avoid panel etc.) +(*) dragbar doesn't unpress when you release mouse button 2/3 +(*) focus code cleanup -- context_ewin vs focuswin vs realfocuswin +(*) edge resistance while in click to focus - window from bottom will appear on +the top when flipping. +(*) wow, dox seems to chew up memory for no good reason. + + 7197 mandrake 0 0 15788 8096 496 S 0 0.0 12.8 0:03 dox + 287 mandrake 2 0 1868 1356 768 S 0 0.3 2.1 0:14 enlightenmen + + it starts out at like 2.7 megs and somehow grows to 16. memory leak? naah + :) gains about 300-500k every time I change pages, indefinitely. never + frees the memory, still gains when I visit a page I've already been to. + +------------ +FIXED BUGS: +------------ + diff --git a/acconfig.h b/acconfig.h new file mode 100644 index 00000000..afff7c81 --- /dev/null +++ b/acconfig.h @@ -0,0 +1,18 @@ +#undef ENLIGHTENMENT_VERSION + +#undef HAVE_STDARGS + +#undef HAVE_LIBESD + +#undef HAVE_SM + +#undef ENLIGHTENMENT_MAJOR + +#undef ENLIGHTENMENT_MINOR + +#undef ENLIGHTENMENT_MICRO + +#undef AUTOUPGRADE + +#undef WITH_TARTY_WARP + diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 00000000..39b37898 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,164 @@ +# Configure paths for ESD +# Manish Singh 98-9-30 +# stolen back from Frank Belew +# stolen from Manish Singh +# Shamelessly stolen from Owen Taylor + +dnl AM_PATH_ESD([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for ESD, and define ESD_CFLAGS and ESD_LIBS +dnl +AC_DEFUN(AM_PATH_ESD, +[dnl +dnl Get the cflags and libraries from the esd-config script +dnl +AC_ARG_WITH(esd-prefix,[ --with-esd-prefix=PFX Prefix where ESD is installed (optional)], + esd_prefix="$withval", esd_prefix="") +AC_ARG_WITH(esd-exec-prefix,[ --with-esd-exec-prefix=PFX Exec prefix where ESD is installed (optional)], + esd_exec_prefix="$withval", esd_exec_prefix="") +AC_ARG_ENABLE(esdtest, [ --disable-esdtest Do not try to compile and run a test ESD program], + , enable_esdtest=yes) + + if test x$esd_exec_prefix != x ; then + esd_args="$esd_args --exec-prefix=$esd_exec_prefix" + if test x${ESD_CONFIG+set} != xset ; then + ESD_CONFIG=$esd_exec_prefix/bin/esd-config + fi + fi + if test x$esd_prefix != x ; then + esd_args="$esd_args --prefix=$esd_prefix" + if test x${ESD_CONFIG+set} != xset ; then + ESD_CONFIG=$esd_prefix/bin/esd-config + fi + fi + + AC_PATH_PROG(ESD_CONFIG, esd-config, no) + min_esd_version=ifelse([$1], ,0.2.7,$1) + AC_MSG_CHECKING(for ESD - version >= $min_esd_version) + no_esd="" + if test "$ESD_CONFIG" = "no" ; then + no_esd=yes + else + ESD_CFLAGS=`$ESD_CONFIG $esdconf_args --cflags` + ESD_LIBS=`$ESD_CONFIG $esdconf_args --libs` + + esd_major_version=`$ESD_CONFIG $esd_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + esd_minor_version=`$ESD_CONFIG $esd_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + esd_micro_version=`$ESD_CONFIG $esd_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_esdtest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $ESD_CFLAGS" + LIBS="$LIBS $ESD_LIBS" +dnl +dnl Now check if the installed ESD is sufficiently new. (Also sanity +dnl checks the results of esd-config to some extent +dnl + rm -f conf.esdtest + AC_TRY_RUN([ +#include +#include +#include +#include + +char* +my_strdup (char *str) +{ + char *new_str; + + if (str) + { + new_str = malloc ((strlen (str) + 1) * sizeof(char)); + strcpy (new_str, str); + } + else + new_str = NULL; + + return new_str; +} + +int main () +{ + int major, minor, micro; + char *tmp_version; + + system ("touch conf.esdtest"); + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = my_strdup("$min_esd_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_esd_version"); + exit(1); + } + + if (($esd_major_version > major) || + (($esd_major_version == major) && ($esd_minor_version > minor)) || + (($esd_major_version == major) && ($esd_minor_version == minor) && ($esd_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'esd-config --version' returned %d.%d.%d, but the minimum version\n", $esd_major_version, $esd_minor_version, $esd_micro_version); + printf("*** of ESD required is %d.%d.%d. If esd-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If esd-config was wrong, set the environment variable ESD_CONFIG\n"); + printf("*** to point to the correct copy of esd-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + +],, no_esd=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_esd" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$ESD_CONFIG" = "no" ; then + echo "*** The esd-config script installed by ESD could not be found" + echo "*** If ESD was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the ESD_CONFIG environment variable to the" + echo "*** full path to esd-config." + else + if test -f conf.esdtest ; then + : + else + echo "*** Could not run ESD test program, checking why..." + CFLAGS="$CFLAGS $ESD_CFLAGS" + LIBS="$LIBS $ESD_LIBS" + AC_TRY_LINK([ +#include +#include +], [ return 0; ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding ESD or finding the wrong" + echo "*** version of ESD. If it is not finding ESD, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means ESD was incorrectly installed" + echo "*** or that you have moved ESD since it was installed. In the latter case, you" + echo "*** may want to edit the esd-config script: $ESD_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + ESD_CFLAGS="" + ESD_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(ESD_CFLAGS) + AC_SUBST(ESD_LIBS) + rm -f conf.esdtest +]) diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 00000000..24815895 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,54 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +THEDIR="`pwd`" +cd "$srcdir" +DIE=0 + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have autoconf installed to compile Enlightenment." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +(automake --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have automake installed to compile Enlightenment." + echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +(test -d src && test -d dox) || { + echo "You must run this script in the top-level Enlightenment directory" + exit 1 +} + +if test -z "$*"; then + echo "I am going to run ./configure with no arguments - if you wish " + echo "to pass any to it, please specify them on the $0 command line." +fi + +echo "Generating configuration files for Enlightenment, please wait...." + +echo " aclocal $ACLOCAL_FLAGS" +aclocal $ACLOCAL_FLAGS +echo " autoheader" +autoheader +echo " automake --add-missing" +automake --add-missing +echo " autoconf" +autoconf + +cd "$THEDIR" + +$srcdir/configure "$@" && echo && echo "Now type 'make' to compile Enlightenment." diff --git a/config.h.in b/config.h.in new file mode 100644 index 00000000..eafee5ff --- /dev/null +++ b/config.h.in @@ -0,0 +1,68 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if you need to in order for stat and other things to work. */ +#undef _POSIX_SOURCE + +/* Define as the return type of signal handlers (int or void). */ +#undef RETSIGTYPE + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if your processor stores words with the most significant + byte first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define if the X Window System is missing or not being used. */ +#undef X_DISPLAY_MISSING + +#undef ENLIGHTENMENT_VERSION + +#undef HAVE_STDARGS + +#undef HAVE_LIBESD + +#undef HAVE_SM + +#undef ENLIGHTENMENT_MAJOR + +#undef ENLIGHTENMENT_MINOR + +#undef ENLIGHTENMENT_MICRO + +#undef AUTOUPGRADE + +#undef WITH_TARTY_WARP + +/* Define if you have the blumfrub function. */ +#undef HAVE_BLUMFRUB + +/* Define if you have the buckets_of_erogenous_nym function. */ +#undef HAVE_BUCKETS_OF_EROGENOUS_NYM + +/* Define if you have the buttox function. */ +#undef HAVE_BUTTOX + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD + +/* Define if you have the mkdir function. */ +#undef HAVE_MKDIR + +/* Define if you have the setenv function. */ +#undef HAVE_SETENV + +/* Define if you have the snprintf function. */ +#undef HAVE_SNPRINTF + +/* Define if you have the strcasecmp function. */ +#undef HAVE_STRCASECMP + +/* Define if you have the header file. */ +#undef HAVE_ALLOCA_H + +/* Define if you have the Fridge library (-lFridge). */ +#undef HAVE_LIBFRIDGE + +/* Define if you have the Xtst library (-lXtst). */ +#undef HAVE_LIBXTST diff --git a/configure.in b/configure.in new file mode 100644 index 00000000..80fcb6a7 --- /dev/null +++ b/configure.in @@ -0,0 +1,237 @@ +AC_INIT(e.spec) + +ENLIGHTENMENT_MAJOR=0 +ENLIGHTENMENT_MINOR=16 +ENLIGHTENMENT_MICRO=devel.4 +ENLIGHTENMENT_VERSION=$ENLIGHTENMENT_MAJOR.$ENLIGHTENMENT_MINOR.$ENLIGHTENMENT_MICRO + +VERSION=$ENLIGHTENMENT_VERSION +PACKAGE=enlightenment + +AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define) + +AM_MAINTAINER_MODE + +AM_CONDITIONAL(FSSTD, test x$enable_fsstd = xyes) +AC_SUBST(USE_FSSTD) + +dnl reasonable guesses for where stuff is installed +if test "x$prefix" = "xNONE"; then + prefix="/usr/local" +else + prefix=$prefix +fi + +# +# ok enlightenment d00ds want to ignore civilization and install +# everything in one place. The rest of use prefer sanity. +# +AC_ARG_ENABLE(fsstd, [ --enable-fsstd install files following FSSTD [default=no]], ,enable_fsstd=no) + +if test "x$enable_fsstd" = "xyes"; then + ENLIGHTENMENT_ROOT=${datadir}/enlightenment + ENLIGHTENMENT_BIN=${bindir} + USE_FSSTD=yes +else + ENLIGHTENMENT_ROOT=${prefix}/enlightenment + ENLIGHTENMENT_BIN=${prefix}/enlightenment/bin + USE_FSSTD=no +fi + +AM_CONFIG_HEADER(econfig.h) + +AC_DEFINE_UNQUOTED(ENLIGHTENMENT_VERSION, "$ENLIGHTENMENT_VERSION") +AC_SUBST(ENLIGHTENMENT_VERSION) +AC_DEFINE_UNQUOTED(ENLIGHTENMENT_MAJOR, "$ENLIGHTENMENT_MAJOR") +AC_SUBST(ENLIGHTENMENT_MAJOR) +AC_DEFINE_UNQUOTED(ENLIGHTENMENT_MINOR, "$ENLIGHTENMENT_MINOR") +AC_SUBST(ENLIGHTENMENT_MINOR) +AC_DEFINE_UNQUOTED(ENLIGHTENMENT_MICRO, "$ENLIGHTENMENT_MICRO") +AC_SUBST(ENLIGHTENMENT_MICRO) + +AC_SUBST(ENLIGHTENMENT_ROOT) +AC_SUBST(ENLIGHTENMENT_BIN) + +AC_PROG_CC +AC_PROG_MAKE_SET +AC_ISC_POSIX +AC_PROG_INSTALL +AC_PROG_LN_S + +AC_HEADER_STDC + +AC_PATH_X +AC_PATH_XTRA + +AC_CHECK_HEADER(stdarg.h, AC_DEFINE(HAVE_STDARGS)) +AC_CHECK_HEADER(X11/SM/SMlib.h, AC_DEFINE(HAVE_SM)) +AC_CHECK_HEADERS(alloca.h) + +AC_TYPE_SIGNAL + +AC_C_BIGENDIAN + +AC_CHECK_FUNCS(getcwd) +AC_CHECK_FUNCS(mkdir) +AC_CHECK_FUNCS(snprintf) +AC_CHECK_FUNCS(strcasecmp) +AC_CHECK_FUNCS(setenv) + +AC_CHECK_FUNCS(blumfrub) +AC_CHECK_FUNCS(buckets_of_erogenous_nym) +AC_CHECK_FUNCS(buttox) + +AC_ARG_ENABLE(sound, [ --enable-sound compile with sound support +[default=yes]], ,enable_sound=yes) + +AC_ARG_ENABLE(upgrade, [ --enable-upgrade compile with auto-upgrade support +[default=yes]], ,enable_upgrade=yes) + +if test "x$enable_sound" = "xyes"; then +AM_PATH_ESD(0.2.12,AC_DEFINE(HAVE_LIBESD),[ +echo "WARNING: Enlightenment needs a system with libesd.so (EsounD)" +echo "0.2.12 or higher to use sound support." +echo "Enlightenment can use EsounD (ESD) to be installed to compile." +echo "Sound will be disabled in this binary. If you ever want sound" +echo "You will need to get and install EsounD then recompile Enlightenment" +echo "Please see the EsounD homepage below on how to obtain/install it." +echo "http://pw1.netcom.com/~ericmit/EsounD.html" +echo "You can also obtain it from:" +echo "ftp://ftp.enlightenment.org/pub/enlightenment/" +echo "ftp://www.rasterman.com/pub/enlightenment/" +AC_MSG_WARN([Warning: no EsounD detected.])]) +else +echo "Sound support has been turned off, per the --enable-sound=no" +echo "passed to your configure line." +fi + + +AM_PATH_IMLIB(1.9.5, , [ +echo "ERROR: Enlightenment needs a system with Imlib 1.8.2 or higher" +echo "You can obtain it from:" +echo "ftp://ftp.enlightenment.org/pub/enlightenment/" +echo "ftp://www.rasterman.com/pub/enlightenment/" +echo "ftp://ftp.labs.redhat.com/pub/imlib/" +AC_MSG_ERROR([Fatal Error: no Imlib detected.])]) + +LDFLAGS="$LDFLAGS -L$prefix/lib" +LDFLAGS="$LDFLAGS `echo $IMLIB_LIBS | sed 's/\(.*\)-lImlib.*/\1/'`" +LDFLAGS="$LDFLAGS `echo $IMLIB_LIBS | sed 's/.*-lImlib.*\(-L[[^ ]]*\).*$/\1/'`" +XTST_LIBS="" + +AC_CHECK_LIB(Fnlib, Fnlib_init, FNLIB_LIBS=-lFnlib , [ +echo "ERROR: Enlightenment needs a system with libFnlib.so (Fnlib)" +echo "You can obtain it from:" +echo "ftp://ftp.enlightenment.org/pub/enlightenment/" +echo "ftp://www.rasterman.com/pub/enlightenment/" +echo "ftp://ftp.labs.redhat.com/pub/fnlib/" +AC_MSG_ERROR([Fatal Error: no Fnlib detected.])], $IMLIB_LIBS) +AC_SUBST(FNLIB_LIBS) + +if test "x$enable_upgrade" = "xyes"; then +AC_CHECK_LIB(ghttp, ghttp_uri_validate, [AC_DEFINE(AUTOUPGRADE) +GHTTP_LIBS=-lghttp] , [ +echo "Automatic Upgrades requires libghttp" +AC_MSG_WARN([no libghttp detected.]) +],$IMLIB_LIBS) +else +echo "Automatic Upgrades have been turned off by request at compiletime" +fi +AC_SUBST(GHTTP_LIBS) + +AC_CHECK_LIB(ttf, TT_Init_FreeType, TTF_LIBS=-lttf, [ +echo "ERROR: Enlightenment needs a system with libttf.so (TrueType Font Library)" +echo "You can obtain it from:" +echo "ftp://ftp.enlightenment.org/pub/enlightenment/" +echo "ftp://www.rasterman.com/pub/enlightenment/" +echo "You can also obtain it from:" +echo "http://www.freetype.org/" +echo "You can obtain some truetype fonts from:" +echo "http://voyager.cns.ohiou.edu/~sadkins/web_library/fonts/font_archive/" +AC_MSG_ERROR([Fatal Error: no FreeType detected.])], -lm) +AC_SUBST(TTF_LIBS) + +AC_CHECK_LIB(dl, dlopen, DL_LIBS=-ldl , [ +echo "Warning: Enlightenment requires the dl (dynamic loader) library" +echo "to be supported on your platform for module support. Modules" +echo "have been disabled (this will affect functionality)" +AC_MSG_WARN([Module Support Disabled (no dynamic loader)])], -lm) +AC_SUBST(DL_LIBS) + + + +AC_CHECK_LIB(Xtst, XTestGrabControl, , , $X_LIBS) +AC_CHECK_LIB(Xtst, XTestQueryExtension, XTST_LIBS=-lXtst, , $X_LIBS) +AC_SUBST(XTST_LIBS) +AC_CHECK_LIB(Xext, XkbQueryExtension, AC_DEFINE(WITH_TARTY_WARP), , $X_LIBS) +AC_CHECK_LIB(Xxf86vm, XF86VidModeQueryExtension, AC_DEFINE(WITH_ZOOM), , $X_LIBS) +AC_CHECK_LIB(Xxf86vm, XF86VidModeQueryExtension, XVM_LIBS=-lXxf86vm, , $X_LIBS) +AC_SUBST(XVM_LIBS) +AC_SUBST(XKB) + +#pixdata=`ls -1 $srcdir/src/pix | egrep -v '(Makefile|CVS)'` +#snddata=`ls -1 $srcdir/src/themes/DEFAULT/snd | egrep -v '(Makefile|CVS)'` +#t17data=`ls -1 $srcdir/src/themes/DEFAULT/tin-e/17 | egrep -v '(Makefile|CVS)'` +#ttfdata=`ls -1 $srcdir/src/themes/DEFAULT/ttfonts | egrep -v '(Makefile|CVS)'` + +#pixdata=`echo $pixdata` +#snddata=`echo $snddata` +#t17data=`echo $t17data` +#ttfdata=`echo $ttfdata` + +#AC_SUBST(pixdata) +#AC_SUBST(snddata) +#AC_SUBST(t17data) +#AC_SUBST(ttfdata) + +#CONFIGEDIT= +#AC_PATH_PROG(PERL, perl) +#if test -z "$PERL"; then +# AC_MSG_WARN([perl not found, ConfigEdit will not be installed]) +#else +# CONFIGEDIT=configedit +#fi +#AC_SUBST(CONFIGEDIT) + +AC_CHECK_LIB(Fridge,mass_quantities_of_bass_ale) +AC_CHECK_LIB(Fridge,mass_quantities_of_any_ale, , [ +echo "Warning: No ales were found in your refrigerator." +echo " We highly suggest that you rectify this situation immediately." +]) + +edocdata=`ls -1 $srcdir/dox/E-docs | egrep -v '(Makefile|CVS|^e|^misc|\.sh$)'` +edocexec=`ls -1 $srcdir/dox/E-docs | egrep '\.sh$'` +#e17data=`ls -1 $srcdir/dox/E-docs/e/17 | egrep -v '(Makefile|CVS)'` +#epixdata=`ls -1 $srcdir/dox/E-docs/epix | egrep -v '(Makefile|CVS)'` +#miscdata=`ls -1 $srcdir/dox/E-docs/misc | egrep -v '(Makefile|CVS)'` + +edocdata=`echo $edocdata` +edocexec=`echo $edocexec` +#e17data=`echo $e17data` +#epixdata=`echo $epixdata` +#miscdata=`echo $miscdata` + +AC_SUBST(edocdata) +AC_SUBST(edocexec) +dnl#AC_SUBST(e17data) +dnl#AC_SUBST(epixdata) +dnl#AC_SUBST(miscdata) + + + +#configedit/Makefile +#configedit/configedit.rc +#configedit/ConfigEdit +#src/configs/user_main.cfg +AC_OUTPUT([ +Makefile +src/Makefile +src/themes/Makefile +src/themes/configs/Makefile +src/themes/configs/pix/Makefile +dox/Makefile +dox/E-docs/Makefile +eesh/Makefile +epp/Makefile +]) +#, [chmod +x configedit/ConfigEdit]) diff --git a/debian/README.debian b/debian/README.debian new file mode 100644 index 00000000..d856468e --- /dev/null +++ b/debian/README.debian @@ -0,0 +1,11 @@ +enlightenment for DEBIAN +---------------------- + +The Enlightenment window manager package. +It now complies with the FHS (Thanks DrMike & KainX!). You can +now build your own .debs of CVS if you so choose, since the debian +specific files are going to be commited to the source tree. Just run +'debian/rules binary' and you'll be set. If you have questions, just +email me. + +Brian M. Almeida , Wed, 30 Sep 1998 18:47:42 -0400 diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 00000000..fde866cb --- /dev/null +++ b/debian/changelog @@ -0,0 +1,109 @@ +enlightenment-cvs (0.15-0.11) unstable; urgency=low + + * Package names changed to reflect CVS version + * CVS updates, more auto* fixes + * Removed econfigedit stuff (dead program) + * Made version number two digits again to make it + recognized as a new version + + -- Brian M. Almeida Sat, 19 Dec 1998 10:09:18 -0500 + +enlightenment (0.15-0.1) unstable; urgency=low + + * Happy day! E now supports the FSSTD. + + -- Brian M. Almeida Thu, 10 Dec 1998 17:31:00 -0500 + +enlightenment (0.15-0.08) unstable; urgency=low + + * CVS upstream patches (Snapshot from 19981120) + + -- Brian M. Almeida Fri, 20 Nov 1998 15:46:00 -0500 + +enlightenment (0.15-0.07) unstable; urgency=low + + * CVS upstream patches (Snapshot from 19981115) + * Raster made a commit RIGHT AFTER 0.06 built...grrr... + + -- Brian M. Almeida Sat, 15 Nov 1998 23:21:00 -0500 + +enlightenment (0.15-0.06) unstable; urgency=low + + * CVS upstream patches (Snapshot from 19981115) + * Has a double click event that shades the window, yay! + + -- Brian M. Almeida Sat, 15 Nov 1998 22:30:00 -0400 + +enlightenment (0.15-0.05) unstable; urgency=low + + * CVS upstream patches (Snapshot from 19981110) + + -- Brian M. Almeida Tue, 10 Nov 1998 16:19:00 -0400 + +enlightenment (0.15-0.04) unstable; urgency=low + + * CVS upstream patches (Snapshot from 19981109) + + -- Brian M. Almeida Tue, 10 Nov 1998 10:28:00 -0400 + +enlightenment (0.15-0.03) unstable; urgency=low + + * CVS upstream patches (Snapshot from 19981107) + + -- Brian M. Almeida Sat, 07 Nov 1998 22:24:00 -0400 + +enlightenment (0.15-0.02) unstable; urgency=low + + * CVS upstream patches (Snapshot from 19981104) to satisfy the masses + * Changed econfigedit dependeny to be libgtk-imlib-perl | libgnome-perl + + -- Brian M. Almeida Fri, 06 Nov 1998 12:39:00 -0400 + +enlightenment (0.15-0.01) unstable; urgency=low + + * CVS upstream release (Snapshot from 19981025) to satisfy the masses + + -- Brian M. Almeida Mon, 26 Oct 1998 21:40:00 -0400 + +enlightenment (0.14-5) unstable; urgency=low + + * Added Enlightenment to WindowManagers submenu using update-menus (#27927) + * Changed dependency on libgtk-perl to libgtk-imlib-perl + + -- Brian M. Almeida Wed, 14 Oct 1998 15:15:00 -0400 + +enlightenment (0.14-4) unstable; urgency=low + + * user_main.cfg calls eeyes now, not ee (#27730) + + -- Brian M. Almeida Tue, 13 Oct 1998 20:00:00 -0400 + +enlightenment (0.14-3) unstable; urgency=low + + * New maintainer + + -- Brian M. Almeida Wed, 30 Sep 1998 18:25:18 -0400 + +enlightenment (0.14-2) unstable; urgency=low + + * Fixed writing of dotfiles + + -- Sean E. Perry Tue, 21 Jul 1998 00:03:18 -0400 + +enlightenment (0.14-1) unstable; urgency=low + + * Added the e-docs package + * Official upstream release + + -- Sean E. Perry Sun, 19 Jul 1998 03:38:18 -0400 + +enlightenment (0.14-0) unstable; urgency=low + + * Initial Release. + + -- Sean E. Perry Sun, 5 Jul 1998 20:07:42 -0400 + +Local variables: +mode: debian-changelog +add-log-mailing-address: "bma@debian.org" +End: diff --git a/debian/control b/debian/control new file mode 100644 index 00000000..49dc1966 --- /dev/null +++ b/debian/control @@ -0,0 +1,53 @@ +Source: enlightenment-cvs +Section: x11 +Priority: optional +Maintainer: Brian M. Almeida +Standards-Version: 2.4.0.0 + +Package: enlightenment-cvs-docs +Architecture: all +Recommends: enlightenment-cvs (>= 0.15) +Replaces: enlightenment-docs (<< 0.15-0.11) +Conflicts: enlightenment-docs (<< 0.15-0.11) +Provides: enlightenment-docs +Description: All documentation for Enlightenment and its themes + How to make a theme, how to customize E, FAQ, README, the works + +Package: enlightenment-cvs +Architecture: any +Depends: ${shlibs:Depends}, enlightenment-cvs-docs, enlightenment-cvs-theme +Suggests: dox-cvs, esound-cvs +Replaces: enlightenment (<< 0.15-0.11) +Conflicts: enlightenment (<< 0.15-0.11) +Provides: enlightenment +Description: The Enlightenment Window Manager + The Enlightnment Window Manager, whose motto is "Time to rethink everything". + It allows complete user control of almost every possible setting. This is + accomplished through its use of themes. However at this stage, Enlightenment + is slightly more complex than wmx and many will find it lacking in features. + There is no support for menus or iconization. + +Package: enlightenment-cvs-theme +Architecture: all +Depends: enlightenment-cvs-docs +Recommends: enlightenment-cvs(>= 0.15) +Replaces: enlightenment-theme (<< 0.15-0.11) +Conflicts: enlightenment-theme (<< 0.15-0.11) +Provides: enlightenment-theme +Description: Themes pictures and config files need by the Enlightenment WM + This package contains the graphics, sounds, and font needed for a minimal + install of Enlightenment. The user is allowed and even suggested to make + their own. + +Package: dox-cvs +Architecture: any +Depends: ${shlibs:Depends} +Recommends: enlightenment-cvs +Replaces: dox (<< 0.15-0.11) +Conflicts: dox (<< 0.15-0.11) +Provides: dox +Description: Dox is the Enlightened help program + Dox is Rasterman's little creation for Enlightenment and other Enlightened + apps to use as a mini help viewer. It uses Rasterman's own markup type + language. + diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 00000000..4ca9b5b0 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,8 @@ +This package was debianized by Sean E. Perry shaleh@debian.org on +Sun, 5 Jul 1998 20:07:42 -0400. + +It can be downloaded from www.rasterman.com or www.enlightenment.org + +Copyright: + +Enlightenment and Dox are released under the GPL. diff --git a/debian/dox-cvs.files b/debian/dox-cvs.files new file mode 100644 index 00000000..6bc98161 --- /dev/null +++ b/debian/dox-cvs.files @@ -0,0 +1,3 @@ +usr/X11R6/bin/dox +usr/share/enlightenment/E-docs + diff --git a/debian/enlightenment-cvs-docs.files b/debian/enlightenment-cvs-docs.files new file mode 100644 index 00000000..a4e2d5cf --- /dev/null +++ b/debian/enlightenment-cvs-docs.files @@ -0,0 +1,2 @@ +usr/doc/enlightenment-cvs-docs + diff --git a/debian/enlightenment-cvs-theme.files b/debian/enlightenment-cvs-theme.files new file mode 100644 index 00000000..00067a21 --- /dev/null +++ b/debian/enlightenment-cvs-theme.files @@ -0,0 +1,3 @@ +usr/share/enlightenment/config +usr/share/enlightenment/themes + diff --git a/debian/enlightenment-cvs.files b/debian/enlightenment-cvs.files new file mode 100644 index 00000000..5cb06a82 --- /dev/null +++ b/debian/enlightenment-cvs.files @@ -0,0 +1,3 @@ +usr/X11R6/bin/enlightenment +usr/X11R6/bin/eesh +usr/X11R6/bin/epp diff --git a/debian/enlightenment-cvs.menu b/debian/enlightenment-cvs.menu new file mode 100644 index 00000000..e1cbe50c --- /dev/null +++ b/debian/enlightenment-cvs.menu @@ -0,0 +1,2 @@ +?package(enlightenment):needs="wm" section="WindowManagers"\ + title="Enlightenment" command="/usr/X11R6/bin/enlightenment" diff --git a/debian/enlightenment.substvars b/debian/enlightenment.substvars new file mode 100644 index 00000000..23cd7ed9 --- /dev/null +++ b/debian/enlightenment.substvars @@ -0,0 +1 @@ +shlibs:Depends=freetype2, imlib1, libc6, libesd0, libfnlib0, libjpeg62, libpng2, libtiff3g, libungif3g (>= 3.0-2) | giflib3g (>= 3.0-5.2), xlib6g (>= 3.3-5), zlib1g (>= 1:1.1.3) diff --git a/debian/rules b/debian/rules new file mode 100644 index 00000000..2e518864 --- /dev/null +++ b/debian/rules @@ -0,0 +1,111 @@ +#!/usr/bin/make -f +# Made with the iad of dh_make, by Craig Small + +BUILD_DIR=`pwd`/debian/build +INSTALL_DIR=`pwd`/debian/tmp + +#export DH_VERBOSE=1 + +configure: configure.in + @echo "--- Making configure script and configuring" + ./autogen.sh + +Makefile: configure + @echo "--- Configuring" + ./configure --enable-fsstd=yes --prefix=/usr \ + --bindir=/usr/X11R6/bin + +build: Makefile build-stamp +build-stamp: + @echo "--- Compiling" + dh_testdir + $(MAKE) + touch build-stamp + +clean: + @echo "--- Cleaning" + dh_testdir + dh_testroot + rm -f build-stamp + rm -rf debian/build + rm -rf `find . -name '.deps'` + + -$(MAKE) distclean + dh_clean + +install: build + @echo "--- Installing" + dh_testdir + dh_testroot + $(MAKE) install DESTDIR=${INSTALL_DIR} + mkdir -p ${INSTALL_DIR}/usr/doc/enlightenment-cvs-docs + +binary-indep: build install \ + enlightenment-cvs-docs \ + enlightenment-cvs-theme \ + +binary-arch: build install \ + enlightenment-cvs \ + dox-cvs + +enlightenment-cvs-docs: install + @echo "--- Building: $@" + dh_installdocs -p$@ -P$(BUILD_DIR)/$@ src/README AUTHORS FAQ + dh_installchangelogs -p$@ -P$(BUILD_DIR)/$@ src/ChangeLog + dh_movefiles -p$@ -P$(BUILD_DIR)/$@ + dh_compress -p$@ -P$(BUILD_DIR)/$@ + dh_fixperms -p$@ -P$(BUILD_DIR)/$@ + dh_installdeb -p$@ -P$(BUILD_DIR)/$@ + dh_gencontrol -p$@ -P$(BUILD_DIR)/$@ + dh_md5sums -p$@ -P$(BUILD_DIR)/$@ + dh_builddeb -p$@ -P$(BUILD_DIR)/$@ + +enlightenment-cvs-theme: install + @echo "--- Building: $@" + mkdir -p $(BUILD_DIR)/$@/usr/doc + cd $(BUILD_DIR)/$@/usr/doc; ln -sf enlightenment-cvs-docs $@ + dh_movefiles -p$@ -P$(BUILD_DIR)/$@ + dh_compress -p$@ -P$(BUILD_DIR)/$@ + dh_fixperms -p$@ -P$(BUILD_DIR)/$@ + dh_installdeb -p$@ -P$(BUILD_DIR)/$@ + dh_gencontrol -p$@ -P$(BUILD_DIR)/$@ + dh_md5sums -p$@ -P$(BUILD_DIR)/$@ + dh_builddeb -p$@ -P$(BUILD_DIR)/$@ + +enlightenment-cvs: install + @echo "--- Building: $@" + mkdir -p $(BUILD_DIR)/$@/usr/doc + cd $(BUILD_DIR)/$@/usr/doc; ln -sf enlightenment-cvs-docs $@ + dh_installmenu -p$@ -P$(BUILD_DIR)/$@ + dh_movefiles -p$@ -P$(BUILD_DIR)/$@ + dh_strip -p$@ -P$(BUILD_DIR)/$@ + dh_compress -p$@ -P$(BUILD_DIR)/$@ + dh_fixperms -p$@ -P$(BUILD_DIR)/$@ + dh_installdeb -p$@ -P$(BUILD_DIR)/$@ + dh_undocumented -p$@ -P$(BUILD_DIR)/$@ enlightenment.1x + dh_shlibdeps -p$@ -P$(BUILD_DIR)/$@ + dh_gencontrol -p$@ -P$(BUILD_DIR)/$@ + dh_md5sums -p$@ -P$(BUILD_DIR)/$@ + dh_builddeb -p$@ -P$(BUILD_DIR)/$@ + +dox-cvs: install + @echo "--- Building: $@" + dh_installdocs -p$@ -P$(BUILD_DIR)/$@ dox/README \ + debian/README.debian + dh_installchangelogs -p$@ -P$(BUILD_DIR)/$@ dox/ChangeLog + dh_movefiles -p$@ -P$(BUILD_DIR)/$@ + dh_strip -p$@ -P$(BUILD_DIR)/$@ + dh_compress -p$@ -P$(BUILD_DIR)/$@ + dh_fixperms -p$@ -P$(BUILD_DIR)/$@ + dh_installdeb -p$@ -P$(BUILD_DIR)/$@ + dh_undocumented -p$@ -P$(BUILD_DIR)/$@ dox.1x + dh_shlibdeps -p$@ -P$(BUILD_DIR)/$@ + dh_gencontrol -p$@ -P$(BUILD_DIR)/$@ + dh_md5sums -p$@ -P$(BUILD_DIR)/$@ + dh_builddeb -p$@ -P$(BUILD_DIR)/$@ + +source diff: + @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary diff --git a/dox/.cvsignore b/dox/.cvsignore new file mode 100644 index 00000000..820eca8b --- /dev/null +++ b/dox/.cvsignore @@ -0,0 +1,4 @@ +Makefile +Makefile.in +.deps +dox diff --git a/dox/COPYING b/dox/COPYING new file mode 100644 index 00000000..eeb586b3 --- /dev/null +++ b/dox/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/dox/ChangeLog b/dox/ChangeLog new file mode 100644 index 00000000..dae4779d --- /dev/null +++ b/dox/ChangeLog @@ -0,0 +1,50 @@ + +Thu Jun 25 16:26:27 EDT 1998 +(Raster) + +added dox to cvs - guess what.. it actually works.. :) + +----------------------------------------------------------------- + +Sun Aug 23 22:13:16 EDT 1998 +(Mandrake) + +fixed imlib-config stuff + +----------------------------------------------------------------- + +Sun Sep 6 18:54:17 EDT 1998 +(Mandrake) + +incremented minor rev to 15. + +----------------------------------------------------------------- + +Fri Sep 11 11:29:57 EDT 1998 +(Mandrake) + +added -I$prefix/include to CPPFLAGS in configure.in + +----------------------------------------------------------------- + +Aug 14/1998 (Hilarion, woo hoo!) + +o Added in support for keybindings (PgUp/PgDn/Return/Home/End) +o Can now select buttons with keys +o Previous button/PageUp can now return from a button press + to the original page + +----------------------------------------------------------------- + +Tue Sep 29 18:11:10 PDT 1998 +(Yosh) + +Redid the Makefiles to be less kludgy + +----------------------------------------------------------------- + +Sat Jul 10 16:45:42 PDT 1999 +(Mandrake) + +added patch from Christian Kreibich +to stop the memory leak in dox diff --git a/dox/E-docs/.cvsignore b/dox/E-docs/.cvsignore new file mode 100644 index 00000000..282522db --- /dev/null +++ b/dox/E-docs/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/dox/E-docs/E_app_menu.png b/dox/E-docs/E_app_menu.png new file mode 100644 index 00000000..7569199a Binary files /dev/null and b/dox/E-docs/E_app_menu.png differ diff --git a/dox/E-docs/E_enlightenment_menu.png b/dox/E-docs/E_enlightenment_menu.png new file mode 100644 index 00000000..eac2ab35 Binary files /dev/null and b/dox/E-docs/E_enlightenment_menu.png differ diff --git a/dox/E-docs/E_keyboard.png b/dox/E-docs/E_keyboard.png new file mode 100644 index 00000000..37d2c9d8 Binary files /dev/null and b/dox/E-docs/E_keyboard.png differ diff --git a/dox/E-docs/E_logo.png b/dox/E-docs/E_logo.png new file mode 100644 index 00000000..b49b9250 Binary files /dev/null and b/dox/E-docs/E_logo.png differ diff --git a/dox/E-docs/E_mouse.png b/dox/E-docs/E_mouse.png new file mode 100644 index 00000000..34450fa6 Binary files /dev/null and b/dox/E-docs/E_mouse.png differ diff --git a/dox/E-docs/E_mousewheel.png b/dox/E-docs/E_mousewheel.png new file mode 100644 index 00000000..eb9810d4 Binary files /dev/null and b/dox/E-docs/E_mousewheel.png differ diff --git a/dox/E-docs/E_screen_start.png b/dox/E-docs/E_screen_start.png new file mode 100644 index 00000000..eb77ddb9 Binary files /dev/null and b/dox/E-docs/E_screen_start.png differ diff --git a/dox/E-docs/E_settings_menu.png b/dox/E-docs/E_settings_menu.png new file mode 100644 index 00000000..3cb1b77d Binary files /dev/null and b/dox/E-docs/E_settings_menu.png differ diff --git a/dox/E-docs/E_window.png b/dox/E-docs/E_window.png new file mode 100644 index 00000000..a2245496 Binary files /dev/null and b/dox/E-docs/E_window.png differ diff --git a/dox/E-docs/E_window_diagram.png b/dox/E-docs/E_window_diagram.png new file mode 100644 index 00000000..c8a8daa7 Binary files /dev/null and b/dox/E-docs/E_window_diagram.png differ diff --git a/dox/E-docs/Edoc_bg.png b/dox/E-docs/Edoc_bg.png new file mode 100644 index 00000000..3ca990aa Binary files /dev/null and b/dox/E-docs/Edoc_bg.png differ diff --git a/dox/E-docs/MAIN b/dox/E-docs/MAIN new file mode 100644 index 00000000..26d9d6fc --- /dev/null +++ b/dox/E-docs/MAIN @@ -0,0 +1,530 @@ + + + +

+
+Enlightenment
+0.16 devel snap +
+ +

+Topics:
+
+_About(about)
+_Credits(credits)
+_Website(web)
+_IRC(irc)
+_Email(email)
+
+_Tutorial(tut)
+_Interactive_Hints(INPUT.interactive.sh)
+
+ +Please read the tutorial if you are new to Enlightenment or just upgraded as +there may be new features you may be missing out on. + + + + + + + + + +

+Enlightenment is your Window Manager. The Window Manager controls the +appearance of the borders of your windows, their behavior and +all user interaction with positioning, killing, resizing, moving, iconifying, +shading etc. your windows, virtual desktops, multiple desktops, menus attached +to windows and some root window menus and can also control the background +of your desktop(s). +

+It is a large and complex program and is by no means perfect, but it is being +worked on and is as stable as possible. It has many advanced features as well +as possibly missing some features. This version (0.15.5) is by no means the +end of development and improvements, fixes and new exciting features are +being worked on all the time. Please go and visit the _Web(web) site often, +as new versions, fixes, patches and updates will be released. +

+It is hoped you enjoy using this software and that it is of benefit to you. +It might not be for everyone, but if it has made your day any better than it +was it has done more than enough already. + + + + + + + + + +

+Enlightenment has been written by:
+
+The Rasterman (Carsten Haitzler)
+Mandrake (Geoff Harrison)
+Chutt (Isaac Richards)
+Sung-Hyun Nam
+Kimball Thurston
+Michael Kellen
+Frederic Devernay
+Felix Bellaby
+Michael Jennings (KainX)
+Christian Kreibich
+Peter Kjellerstedt
+Troy Pesola
+Owen Taylor
+
+And many others. +

+A big thanks to several companies that helped support Enlightenment. +

+2rad Networks (www.2rad.net) for providing servers and bandwidth to run the +Enlightenment web site. +

+Red Hat Software (www.redhat.com) for allowing developers resources and time +to work on Enlightenment. +

+VA Linux Systems (www.linux.com) for providing hardware, bandwidth and coke. +

+Xi Graphics (www.xig.com) for providing Xservers. +

+Not only should these people be thanked, but the whole E community - those on +the E mailing list, on #E on IRC on EFnet and all E users who have provided +feedback and debugging information, bug-fixes, patches and support. A big +thanks goes out to all of you who make a project like this possible. +

+In addition people should be aware that E makes use of other projects - such +as XFree86, Imlib, Esound, Freetype and many others, The people working on +projects that provide infrastructure that E can use and build on should not +be forgotten. + + + + + + + + + +
+
+
+
+
+
+

+For updated information on Enlightenment, development, bug-fixes, snapshots of +development versions etc. please visit: +

+ +http://www.enlightenment.org/ + +

+You may want to visit this site often as it changes +regularly with fixes and development releases -- also visiting the +daily-snapshots section +on the FTP site is a good idea (see the snapshots section on the website for +more information). + + + + + + + + + +

+There is an Official Enlightenment IRC channel where you can go and "hang out" +if you want - talk to other E users, developers, get some help, drool +together, or whatever. #E will kill me for this but get onto any EFnet irc +server (irc.efnet.org) then join #E. An example: +

+BitchX your_nick irc.efnet.org
+
+or
+
+irc your_nick irc.efnet.org
+
+or use your favorite graphical IRC client. +

+Please remember that it can get busy with 100's of people talking at once and +not everyone is actually listening all the time or are in the middle of a +conversation - be polite and patient, and have a sense of humor and you'll +have fun. + + + + + + + + + +

+There is a mailing-list for Enlightenment.If you wish to take part in general +and development related discussions concerning Enlightenment you can join +by mailing: +

+e-develop-request@rasterman.com +

+and put only one word in your body of the mail: +

+subscribe +

+This should subscribe you to the mailing list. If you are only interested in +announcements, please mail your subscribe request as above to: +

+e-announce-request@rasterman.com +

+instead. + + + + + + + + + +

+
+
+
+This small tutorial is intended to take you step by step through Enlightenment +and its default setup, how to use it, modify settings, and put it to use for +you. When you have finished reading each page please press the NEXT button on +the top of this window to go to the next page. +

+If you are reading this right now you have managed to get Enlightenment itself +installed correctly and are either running Enlightenment for the first time or +have just upgraded to a new version. Congratulations. Now it's time to take +you on a quick tour of the desktop you will have before you. +

+Please remember that if you use a theme other than the default (Brushed Metal) +that is may look slightly or completely different to the contents of this +tutorial. Some behavior may also vary. + + + + + + + + + + +

+Now that you have started Enlightenment, if you are using it for your desktop +shell, your screen should look something like the image here on the left. +

+Across the whole top of the screen you will see a bar with arrows pointing +up and down on the left and right ends. This is your desktop +_Dragbar(dragbar) . +

+On the bottom-left you'll see 3 boxes. The top box with the scrollbar attached +will be your _Iconbox(iconbox) . +

+The other 2 boxes below are _Pagers(pager) for desktops 0 and 1. Everything +else is your desktop background. + + + + + + + + + + +

+When you click with your left mouse button on the desktop background you will +see an "Applications" menu appear (example displayed on the right here). +Applications you may have installed will appear in this menu. To launch one +of them simply select it from the menu. +

+Note: Menus in Enlightenment work like most menu systems. You can either hold +down the mouse button and navigate with the button down, releasing on the +selection you want, or release elsewhere to not select anything, or you can +quickly click and release then navigate just by moving the mouse, and clicking +again on the item you wish to select, or eslewhere if you do not wish to +select an entry. +

+If you wish to "stick" a menu up and leave it up so you can select items from +it multiple times, clcik and hold down the mouse and release on the title of +the menu (if it has a title) and it will remain up. You can move it and +manipulate it like a normal window. Close the window to unstick the menu. +

+ + + + + + + + + + + +

+You will also find that instead of using the left mouse button, you click the +right mouse button, a menu with the title "Settings" will appear. This is +Enlightenment's settings menu. From it you can select what parts of your +desktop that Enlightenment controls to customise and make more ameniable to +your own needs. +

+When you select one of these _settings(settings) a dialog window will appear +giving you options to configure that part of Enlightenment. +

+Clicking the middle button on the desktop background will display +Enlightenment's main menu. You can access the other menus plus more options +(including those to log out, restart and display Help information) from this +menu. + + + + + + + + + +

+You will also find that holding down the ALT key whilst clicking the middle +mouse button will bring up a menu with the titles of all currently active +application windows. Selecting one of these will take you to that application. +By using the CTRL key instead of ALT you will get a menu displaying all +current desktops as submenus, with applicaitons on each desktop in the +desktop submenu. +

+If your mouse does not have a middle button you should have enabled +"Emulate 3 Buttons" in your X-Server - in which case pressing both left and +right mouse buttons at once will be the equivalent of pressing a middle +mouse button. If this does not work this may not be turned on. Please see +your X Server documentation on how to configure this. +

+This may vary from system to system. OS and XServer may also vary the method +in which you do this, if it is possible. Not having a middle mouse button in +Enlightenment, or for that matter X is not a good thing as it is almost +assumed to be there, and is used by many applications, as well as +Enlightenment. + + + + + + + + + + + +

+If you have a WheelMouse and X is configured to understand this Enlightenment +comes equipped with wheel support out of the box. +

+Rolling your wheel up on the desktop background will take you back a +_desktop(desktops) or by rolling your wheel downward, you will advance +forward a desktop. +

+If this doesn't work, then it may be you haven't configured your XServer to +understand a mouse with a wheel. If you use XFree86 you may need to edit your +XF86Config to have a "Pointer" Section like: + +

+Section "Pointer"
+Protocol "MousemanPlusPS/2"
+Device "/dev/mouse"
+ZAxisMapping 4 5
+Buttons 5
+EndSection + +

+You may need to modify this for your mouse. + + + + + + + + + +

+When you start an application, unless it has special properties, it will come +up on your screen with a border surrounding it that contains a titlebar and +several control buttons. +

+This border is the primary interface to controlling an application window. +The Default setup (shown on the next page) gives adequate control but still +retains simplicity. +

+If you click left mouse button on the titlbar and keep the mouse button down +the window will follow your mouse wherever it moves. Respectively if you click +your left mouse button and drag on any of the resize handles, the window will +be resized in that direction. Clicking right mouse button on the resize +handles will raise thw windows to the top. +

+Clicking right mouse button on the titlebar or any button on the window +operations menu button on the top-left will display a menu that has window +manipulation options in it. +

+Double-Clicking (clicking the mouse twice in sucession really fast) will +make the Window shade or unshade (depending if it was unshaded ro shaded to +start with). + + + + + + + + +

+ + + + + + + + +

+Clicking left mouse button on the iconify button will iconify the window +and send it off to the Iconbox. Hitting the Maximize button will maximize the +size of the application fill your screen. Hitting it again will Unmaximize, +bringing the window back to its normal size. +

+Clicking with the left mouse button on the close button will close the window. +If the application that owns that window does not respond ot a nice request to +exit, then pressing right mouse button on the close button to forcibly +terminate that window. This should not be used unnless the application is +visibly "hung". +

+In addition to these methods of manipulation a window there are additional +ways of performing these. +

+If you hold down the ALT key and hold down left mouse button anywhere in the +window (on the border OR in the application part) whilst dragging, you will +move this window around. Doing the same but with the middle mouse button will +resize the window in that direction. Clicking button 3 anywhere in the window +whilst holding down the ALT key will brung up the window operations menu. + + + + + + + + + + +

+For people who want to use their keyboard to manipulate their personal desktop +there are a number of key combinations bound by default. They are as follows: + +

+CTRL+ALT+Home - Reshuffle windows on screen to be Clean +
+CTRL+ALT+Del - Exit Enlightenment and Log Out +
+CTRL+ALT+Home - Restart Enlightenment +
+CTRL+ALT+Up-Arrow - Raise window to top +
+CTRL+ALT+Down-Arrow - Lower window to the bottom +
+CTRL+ALT+Left-Arrow - Go to the previous desktop +
+CTRL+ALT+Right-Arrow - Go to the next desktop +
+CTRL+ALT+X - Close the currently focused window +
+CTRL+ALT+K - Kill the currently focused window nastily +
+CTRL+ALT+R - Shade/Unshade the currently focused window +
+CTRL+ALT+I - Iconify the currently focused window +
+CTRL+ALT+Tab - Switch focus to the next window +
+CTRL+ALT+R - Shade/Unshade the currently focused window +
+CTRL+ALT+S - Stick/Unstick the currently focused window +
+CTRL+ALT+Enter - Zoom/Unzoom the currently focused window +
+CTRL+ALT+(F1 - F12) - Go directly to desktops 0 - 11 +
+ +(more on next page ...) + + + + + + + +

+SHIFT+ALT+Left-Arrow - Move to the virtual desktop on the left if there is one +
+SHIFT+ALT+Right-Arrow - Move to the virtual desktop on the right if there is +one +
+SHIFT+ALT+Up-Arrow - Move to the virtual desktop above if there is one +
+SHIFT+ALT+Down-Arrow - Move to the virtual desktop below if there is one + +

+Note: Zooming in and out of windows will only work if you have an XFree86 +server or one that impliments the Xf86VidMode extension. You also need +to define lots of screen modes for your display, so ensure your "Display" +subsection of your XF86Config looks like: + +

+SubSection "Display"
+ Depth 16
+ Modes "1600x1200" "1280x1024" "1152x864" "1024x768" "800x600" "640x480" "512x384" "400x300" "320x240"
+EndSubSection + +

+Have a "Display" subsection per depth (this example is for 16 bit) and all +the resolutions defined as above. + + + + + + + + + +

+Multiple & Virtual Desktops + + + + +

+The Dragbar + + + + +

+The Pager + + + + +

+The Iconbox + + + + +

+Settings + + diff --git a/dox/E-docs/Makefile.am b/dox/E-docs/Makefile.am new file mode 100644 index 00000000..2b74850b --- /dev/null +++ b/dox/E-docs/Makefile.am @@ -0,0 +1,10 @@ +if FSSTD +edocdatadir = $(pkgdatadir)/E-docs +else +edocdatadir = $(prefix)/enlightenment/E-docs +endif + +edocdata_DATA = @edocdata@ +edocdata_PROGRAMS = @edocexec@ + +EXTRA_DIST = $(edocdata_DATA) diff --git a/dox/E-docs/aircut3.ttf b/dox/E-docs/aircut3.ttf new file mode 100644 index 00000000..c244ec95 Binary files /dev/null and b/dox/E-docs/aircut3.ttf differ diff --git a/dox/E-docs/benjamingothic.ttf b/dox/E-docs/benjamingothic.ttf new file mode 100644 index 00000000..034de7f4 Binary files /dev/null and b/dox/E-docs/benjamingothic.ttf differ diff --git a/dox/E-docs/interactive.sh b/dox/E-docs/interactive.sh new file mode 100755 index 00000000..61ed4aa1 --- /dev/null +++ b/dox/E-docs/interactive.sh @@ -0,0 +1,66 @@ +#!/bin/sh +cat << __EOF__ + + + +

+Hints and tips +

+ +

+__EOF__ +# checking OS & arch info +UNAME=`uname -a` +OS=`echo "$UNAME" | awk '{print $1;}'` +OSVER=`echo "$UNAME" | awk '{print $3;}'` +ARCH=`echo "$UNAME" | awk '{print $12;}'` + +# checking memory stats +MEM=`free` +TOTAL=`echo "$MEM" | grep Mem: | awk '{print $2;}'` +USED=`echo "$MEM" | grep buffers/cache | awk '{print $3;}'` +SWAPPED=`echo "$MEM" | grep Swap: | awk '{print $3;}'` + +# checking X Server +XDPYINFO=`xdpyinfo` +VENDOR=`echo "$XDPYINFO" | grep "vendor string:" | awk -F: '{print $2;}'` +VERSION=`echo "$XDPYINFO" | grep "vendor release number:" | awk -F: '{print $2;}'` +DEPTH=`echo "$XDPYINFO" | grep "depths (" | awk -F: '{print $2;}' | awk '{print $1;}'` +DEPTHS=`echo "$XDPYINFO" | grep "depths (" | awk "-F(" '{print $2;}' | awk "-F)" '{print $1;}'` + +echo "Your Operating System is:
" +echo "" +echo $OS"
" +echo "" +echo "Your processor type is:
" +echo $ARCH"
" +echo "Your system memory use is:
" +echo $USED" Kb /"$TOTAL" Kb
" +echo $SWAPPED" Kb swapped out to disk
" + +echo "Your X Server is:
" +echo $VENDOR"
" +echo "" +echo "Version:
" +echo $VERSION"
" +echo "" +echo "Running a color depth of:
" +echo $DEPTH" bits per pixel
" +echo "Number of depths:
" +echo $DEPTHS"
" + +cat << __EOF__ +

+Hit Next for more... + + +

+

+__EOF__ +if [ "$DEPTHS" -gt 1 ]; then +echo "It seems you have more than one depth available on your display." +echo "Enlightenment will run but several features may be disabled or not work" +echo "correctly due to this." +echo "

" +echo "Please re-configure your X Server to only have one depth (eg 16, 24, 32)" +fi diff --git a/dox/E-docs/neuropol.ttf b/dox/E-docs/neuropol.ttf new file mode 100644 index 00000000..05b1af20 Binary files /dev/null and b/dox/E-docs/neuropol.ttf differ diff --git a/dox/E-docs/rothwell.ttf b/dox/E-docs/rothwell.ttf new file mode 100644 index 00000000..4d5f4712 Binary files /dev/null and b/dox/E-docs/rothwell.ttf differ diff --git a/dox/E-docs/unionform.ttf b/dox/E-docs/unionform.ttf new file mode 100644 index 00000000..67658864 Binary files /dev/null and b/dox/E-docs/unionform.ttf differ diff --git a/dox/E-docs/window.xcf b/dox/E-docs/window.xcf new file mode 100644 index 00000000..d798fc38 Binary files /dev/null and b/dox/E-docs/window.xcf differ diff --git a/dox/E-docs/x-files.ttf b/dox/E-docs/x-files.ttf new file mode 100644 index 00000000..c034793e Binary files /dev/null and b/dox/E-docs/x-files.ttf differ diff --git a/dox/Makefile.am b/dox/Makefile.am new file mode 100644 index 00000000..1957dc7c --- /dev/null +++ b/dox/Makefile.am @@ -0,0 +1,50 @@ +SUBDIRS=E-docs + +EXTRA_DIST = ChangeLog README + +if FSSTD +bindir = @bindir@ +ENLIGHTENMENT_BIN=$(bindir) +ENLIGHTENMENT_ROOT=$(pkgdatadir) +else +ENLIGHTENMENT_BIN=$(prefix)/enlightenment/bin +ENLIGHTENMENT_ROOT=$(prefix)/enlightenment +bindir=$(ENLIGHTENMENT_BIN) +endif + +bin_PROGRAMS = dox + +dox_SOURCES = \ + format.c \ + file.c \ + ttfont.c \ + text.c \ + dox.c \ + title.xpm \ + prev1.xpm \ + prev2.xpm \ + next1.xpm \ + next2.xpm \ + exit1.xpm \ + exit2.xpm \ + dox.h + +LDADD = $(TTF_LIBS) $(FNLIB_LIBS) $(IMLIB_LIBS) -lm + +INCLUDES=-I$(top_srcdir) $(IMLIB_CFLAGS) -I$(includedir) -I.. + +DEFS=-DENLIGHTENMENT_ROOT=\"@ENLIGHTENMENT_ROOT@\" + +#install-exec-local: +# if [ x@USE_FSSTD@ = "xno" ]; then \ +# ../mkinstalldirs $(exec_prefix)/bin; \ +# for i in $(bin_PROGRAMS); do \ +# rm -f $(exec_prefix)/bin/$$i; \ +# $(LN_S) $(bindir)/$$i $(exec_prefix)/bin/$$i; \ +# done; \ +# fi + +uninstall-local: + for i in $(bin_PROGRAMS); do \ + rm -f $(exec_prefix)/bin/$$i; \ + done diff --git a/dox/README b/dox/README new file mode 100644 index 00000000..f2febd56 --- /dev/null +++ b/dox/README @@ -0,0 +1,4 @@ +This is DOX for Enlightenment - a very very very simple document viewer for +Help docs for Enlightenment. This is part of the Enlightenment distribution. +It is Copyright (C) 1998-1999 by The Rasterman (Carsten Haitzler). It is under +the license described in e/LICENSE diff --git a/dox/dox.c b/dox/dox.c new file mode 100644 index 00000000..2a18b1f4 --- /dev/null +++ b/dox/dox.c @@ -0,0 +1,515 @@ +/* DOX for Enlightenment - by The Rasterman (C) 1998 */ + +#include "econfig.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "econfig.h" + +#include "dox.h" + +#ifdef __alpha__ /* gets rid of some misalignment in GCC */ +#pragma 2 +#endif + +/* Motif window hints */ +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) + +/* bit definitions for MwmHints.functions */ +#define MWM_FUNC_ALL (1L << 0) +#define MWM_FUNC_RESIZE (1L << 1) +#define MWM_FUNC_MOVE (1L << 2) +#define MWM_FUNC_MINIMIZE (1L << 3) +#define MWM_FUNC_MAXIMIZE (1L << 4) +#define MWM_FUNC_CLOSE (1L << 5) + +/* bit definitions for MwmHints.decorations */ +#define MWM_DECOR_ALL (1L << 0) +#define MWM_DECOR_BORDER (1L << 1) +#define MWM_DECOR_RESIZEH (1L << 2) +#define MWM_DECOR_TITLE (1L << 3) +#define MWM_DECOR_MENU (1L << 4) +#define MWM_DECOR_MINIMIZE (1L << 5) +#define MWM_DECOR_MAXIMIZE (1L << 6) + +#define PROP_MWM_HINTS_ELEMENTS 4 + +#define STARTPOS 4 /* to bypass next/prev/exit buttons for key binding positions */ + +typedef struct _mwmhints + { + CARD32 flags; + CARD32 functions; + CARD32 decorations; + INT32 inputMode; + } +MWMHints; + +#include "title.xpm" +#include "prev1.xpm" +#include "prev2.xpm" +#include "next1.xpm" +#include "next2.xpm" +#include "exit1.xpm" +#include "exit2.xpm" + +Display *disp; +ImlibData *id; +FnlibData *fd; +Window win_main, win_title, win_exit, win_next, win_prev, win_text, + win_cover; +int w, h, t; +ImlibImage *im_text; +ImlibImage *im_title; +ImlibImage *im_prev1, *im_prev2; +ImlibImage *im_next1, *im_next2; +ImlibImage *im_exit1, *im_exit2; +char *docdir; + +Window CreateWindow(Window parent, int x, int y, int ww, int hh); +int ReadHeader(FILE * f); +int ReadPages(FILE * f); + +Window +CreateWindow(Window parent, int x, int y, int ww, int hh) +{ + Window win; + XSetWindowAttributes attr; + MWMHints mwm; + +/* Atom a; */ + XSizeHints hnt; + + attr.backing_store = NotUseful; + attr.override_redirect = False; + attr.colormap = Imlib_get_colormap(id); + attr.border_pixel = 0; + attr.background_pixel = 0; + attr.save_under = False; + mwm.flags = MWM_HINTS_DECORATIONS; + mwm.functions = 0; + mwm.decorations = 0; + mwm.inputMode = 0; +/* a = XInternAtom(disp, "_MOTIF_WM_HINTS", False); */ + win = XCreateWindow(disp, parent, x, y, ww, hh, 0, id->x.depth, + InputOutput, Imlib_get_visual(id), + CWOverrideRedirect | CWSaveUnder | CWBackingStore | + CWColormap | CWBackPixel | CWBorderPixel, &attr); + XSetWindowBackground(disp, win, 0); +/* XChangeProperty(disp, win, a, a, 32, PropModeReplace, + * (unsigned char *)&mwm, sizeof(MWMHints) / 4); */ + XStoreName(disp, win, "DOX: Enlightenment Document Viewer"); + hnt.flags = USPosition | USSize | PPosition | PSize | PMinSize | PMaxSize; + hnt.x = x; + hnt.y = y; + hnt.width = ww; + hnt.height = hh; + hnt.min_width = ww; + hnt.max_width = ww; + hnt.min_height = hh; + hnt.max_height = hh; + XSetWMNormalHints(disp, win, &hnt); + return win; +} + +#define FREE_LINKS \ +ll = l; \ +while (ll) \ +{ \ + l = ll; \ + ll = ll->next; \ + free(l->name); \ + free(l); \ +} + +#define UPDATE_NOW \ +{ \ +XSetWindowBackgroundPixmap(disp, win_text, draw); \ +XClearWindow(disp, win_text); \ +} + +#define UPDATE \ +{ \ + int up_i, up_j; \ + int up_lut[16] = { 0, 8, 4, 12, 2, 6, 10, 14, \ + 3, 11, 1, 9, 7, 13, 5, 15}; \ + XSetWindowBackgroundPixmap(disp, win_text, draw); \ + for (up_j = 0; up_j < 16; up_j++) \ + { \ + for (up_i = 0; up_i < h; up_i += 16) \ + { \ + XClearArea(disp, win_text, 0, up_i + up_lut[up_j], w, 1, False); \ + } \ + XSync(disp, False); \ + } \ +} + + +int +main(int argc, char **argv) +{ + int pagenum; + int x, y; + int wx, wy; + FILE *f; + char *s; + Pixmap draw = 0; + Link *l = NULL, *ll = NULL; + ImlibBorder ibd; + ImlibInitParams params; + int *page_hist = NULL; + int page_hist_len = 1; + int page_hist_pos = 0; + + w = 512; + h = 400; + x = 0; + y = 0; + pagenum = 0; + + disp = XOpenDisplay(NULL); + params.flags = PARAMS_IMAGECACHESIZE | PARAMS_PIXMAPCACHESIZE; + params.imagecachesize = (w * h * 3 * 2); + params.pixmapcachesize = (w * h * 3 * 2 * 8); + id = Imlib_init_with_params(disp, ¶ms); + Imlib_set_render_type(id, RT_DITHER_TRUECOL); + fd = Fnlib_init(id); + + im_title = Imlib_create_image_from_xpm_data(id, title_xpm); + ibd.left = 50; + ibd.right = 2; + ibd.top = 2; + ibd.bottom = 2; + Imlib_set_image_border(id, im_title, &ibd); + im_prev1 = Imlib_create_image_from_xpm_data(id, prev1_xpm); + im_prev2 = Imlib_create_image_from_xpm_data(id, prev2_xpm); + im_next1 = Imlib_create_image_from_xpm_data(id, next1_xpm); + im_next2 = Imlib_create_image_from_xpm_data(id, next2_xpm); + im_exit1 = Imlib_create_image_from_xpm_data(id, exit1_xpm); + im_exit2 = Imlib_create_image_from_xpm_data(id, exit2_xpm); + + if (argc < 2) + { + printf("usage:\n%s [-page num] Edoc_dir\n", argv[0]); + exit(1); + } + if (!strcmp(argv[1], "-page")) + { + pagenum = atoi(argv[2]); + docdir = strdup(argv[3]); + } + else + docdir = strdup(argv[1]); + s = malloc(strlen(docdir) + 1 + 5); + strcpy(s, docdir); + strcat(s, "/MAIN"); + f = fopen(s, "r"); + if (!f) + { + printf("Edoc_dir does not contain a MAIN file\n"); + exit(1); + } + t = 16; + GetObjects(f); + fclose(f); + Fnlib_add_dir(fd, docdir); + wx = (DisplayWidth(disp, DefaultScreen(disp)) - w) / 2; + wy = (DisplayHeight(disp, DefaultScreen(disp)) - (h + t)) / 2; + win_main = CreateWindow(id->x.root, wx, wy, w, h + t); + win_title = CreateWindow(win_main, 0, 0, (w - 64 - 64 - t), t); + win_prev = CreateWindow(win_main, (w - 64 - 64 - t), 0, 64, t); + XSelectInput(disp, win_prev, ButtonPressMask | ButtonReleaseMask); + win_next = CreateWindow(win_main, (w - 64 - 64 - t) + 64, 0, 64, t); + XSelectInput(disp, win_next, ButtonPressMask | ButtonReleaseMask); + win_exit = CreateWindow(win_main, (w - 64 - 64 - t) + 64 + 64, 0, t, t); + XSelectInput(disp, win_exit, ButtonPressMask | ButtonReleaseMask); + win_text = CreateWindow(win_main, 0, t, w, h); + XSelectInput(disp, win_text, ButtonPressMask | ButtonReleaseMask | + KeyPressMask | KeyReleaseMask | PointerMotionMask); + draw = XCreatePixmap(disp, win_text, w, h, id->x.depth); + XSetWindowBackgroundPixmap(disp, win_text, draw); + Imlib_apply_image(id, im_title, win_title); + Imlib_apply_image(id, im_exit1, win_exit); + Imlib_apply_image(id, im_next1, win_next); + Imlib_apply_image(id, im_prev1, win_prev); + + l = RenderPage(draw, pagenum, w, h); + + XMapWindow(disp, win_text); + XMapWindow(disp, win_exit); + XMapWindow(disp, win_next); + XMapWindow(disp, win_prev); + XMapWindow(disp, win_title); + XMapWindow(disp, win_main); + XSync(disp, False); + page_hist = malloc(sizeof(int)); + page_hist[0] = 0; + + for (;;) + { + KeySym key; + XEvent ev; + + XNextEvent(disp, &ev); + switch (ev.type) + { + case KeyPress: + key = XLookupKeysym(&ev.xkey, 0); + switch (key) + { + case XK_Escape: + exit(0); + break; + case XK_Down: + case XK_Right: + break; + case XK_Up: + case XK_Left: + break; + case XK_Return: + break; + case XK_Home: + FREE_LINKS; + pagenum = 0; + pagenum = FixPage(pagenum); + l = RenderPage(draw, pagenum, w, h); + UPDATE; + break; + case XK_End: + FREE_LINKS; + pagenum = 99999; + pagenum = FixPage(pagenum); + l = RenderPage(draw, pagenum, w, h); + UPDATE; + break; + case XK_Prior: + FREE_LINKS; + pagenum--; + pagenum = FixPage(pagenum); + l = RenderPage(draw, pagenum, w, h); + UPDATE; + break; + case XK_Next: + FREE_LINKS; + pagenum++; + pagenum = FixPage(pagenum); + l = RenderPage(draw, pagenum, w, h); + UPDATE; + break; + } + break; + case ButtonPress: + if (ev.xbutton.window == win_prev) + Imlib_apply_image(id, im_prev2, win_prev); + else if (ev.xbutton.window == win_next) + Imlib_apply_image(id, im_next2, win_next); + else if (ev.xbutton.window == win_exit) + Imlib_apply_image(id, im_exit2, win_exit); + else + { + int x, y; + + x = ev.xbutton.x; + y = ev.xbutton.y; + ll = l; + while (ll) + { + if ((x >= ll->x) && (y >= ll->y) && + (x < (ll->x + ll->w)) && + (y < (ll->y + ll->h))) + { + int pg; + + if (!strncmp("EXEC.", ll->name, 5)) + { + if (!fork()) + { + char *exe; + + exe = &(ll->name[5]); + execl("/bin/sh", "/bin/sh", "-c", exe, NULL); + exit(0); + } + } + else if (!strncmp("INPUT.", ll->name, 6)) + { + FILE *p; + char *exe, tmp[1024]; + + exe = &(ll->name[6]); + if (exe[0] != '/') + { + sprintf(tmp, "%s/%s", docdir, exe); + exe = tmp; + } + p = popen(exe, "r"); + if (p) + { + int dirlen = 0; + char *sp; + + sp = exe; + while ((*sp) && (*sp != ' ')) + sp++; + while ((*sp != '/') && (sp != exe)) + sp--; + dirlen = sp - exe; + if (dirlen > 1) + { + free(docdir); + docdir = malloc(dirlen + 1); + memcpy(docdir, exe, dirlen); + docdir[dirlen] = 0; + } + GetObjects(p); + pclose(p); + if (page_hist) + free(page_hist); + page_hist = malloc(sizeof(int)); + page_hist[0] = 0; + page_hist_len = 1; + pagenum = 0; + page_hist_pos = 0; + FREE_LINKS; + l = RenderPage(draw, pagenum, w, h); + UPDATE; + } + } + else + { + pg = GetPage(ll->name); + if (pg >= 0) + { + FREE_LINKS; + pagenum = pg; + if (page_hist_pos >= page_hist_len) + { + page_hist_len++; + page_hist = + realloc(page_hist, + sizeof(int) * page_hist_len); + } + page_hist_pos++; + page_hist[page_hist_pos] = pagenum; + l = RenderPage(draw, pagenum, w, h); + UPDATE; + } + } + break; + } + ll = ll->next; + } + } + break; + case ButtonRelease: + if (ev.xbutton.window == win_prev) + { + Imlib_apply_image(id, im_prev1, win_prev); + FREE_LINKS; + page_hist_pos--; + if (page_hist_pos < 0) + page_hist_pos = 0; + pagenum = page_hist[page_hist_pos]; + l = RenderPage(draw, pagenum, w, h); + UPDATE; + } + else if (ev.xbutton.window == win_next) + { + int prev_pagenum; + Imlib_apply_image(id, im_next1, win_next); + FREE_LINKS; + prev_pagenum = pagenum; + pagenum++; + pagenum = FixPage(pagenum); + if (pagenum != prev_pagenum) + { + if (page_hist_pos >= page_hist_len) + { + page_hist_len++; + page_hist = realloc(page_hist, + sizeof(int) * page_hist_len); + page_hist[page_hist_len - 1] = pagenum; + page_hist_pos = page_hist_len - 1; + } + else + page_hist_pos++; + l = RenderPage(draw, pagenum, w, h); + UPDATE; + } + } + else if (ev.xbutton.window == win_exit) + { + Imlib_apply_image(id, im_exit1, win_exit); + exit(0); + } + break; + case EnterNotify: + break; + case LeaveNotify: + break; + case MotionNotify: + while (XCheckTypedEvent(disp, ev.type, &ev)); + { + int x, y; + static Link *pl = NULL; + char found = 0; + + x = ev.xmotion.x; + y = ev.xmotion.y; + ll = l; + while (ll) + { + if ((x >= ll->x) && (y >= ll->y) && + (x < (ll->x + ll->w)) && + (y < (ll->y + ll->h))) + { + GC gc; + XGCValues gcv; + int r, g, b; + + if (pl != ll) + { + if (pl) + { + UPDATE_NOW; + } + GetLinkColors(pagenum, &r, &g, &b); + gc = XCreateGC(disp, win_text, 0, &gcv); + XSetForeground(disp, gc, + Imlib_best_color_match(id, &r, &g, &b)); + XDrawRectangle(disp, win_text, gc, ll->x, ll->y, + ll->w, ll->h); + XFreeGC(disp, gc); + pl = ll; + } + found = 1; + ll = NULL; + } + if (ll) + ll = ll->next; + } + if (!found) + { + UPDATE_NOW; + pl = NULL; + } + } + break; + default: + break; + } + } +} diff --git a/dox/dox.h b/dox/dox.h new file mode 100644 index 00000000..6f0193fd --- /dev/null +++ b/dox/dox.h @@ -0,0 +1,225 @@ +/*****************************************************************************/ +/* Enlightenment - The Window Manager that dares to do what others don't */ +/*****************************************************************************/ +/* Copyright (C) 1997 - 1999 Carsten Haitzler (The Rasterman) */ +/* */ +/* This program and utilites 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 software 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 Library General Public */ +/* License along with this software; if not, write to the */ +/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */ +/* Boston, MA 02111-1307, USA. */ +/*****************************************************************************/ + +#include "econfig.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FILEPATH_LEN_MAX 4096 + +#define DEFAULT_LINKCOLOR_R 30 +#define DEFAULT_LINKCOLOR_G 50 +#define DEFAULT_LINKCOLOR_B 160 + +#define TT_VALID( handle ) ( ( handle ).z != NULL ) +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + +typedef struct _efont + { + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Face_Properties properties; + int num_glyph; + TT_Glyph *glyphs; + TT_Raster_Map **glyphs_cached; + int max_descent; + int max_ascent; + } +Efont; + +typedef struct _textstate + { + char *fontname; + FnlibStyle style; + FnlibFont *font; + ImlibColor fg_col; + ImlibColor bg_col; + int effect; + Efont *efont; + XFontStruct *xfont; + XFontSet xfontset; + int xfontset_ascent; + int height; + } +TextState; + +typedef enum _type + { + IMG, + BR, + FONT, + P, + TEXT, + PAGE + } +Type; + +typedef struct _img + { + char *src; + char *src2; + char *src3; + int x, y; + char *link; + int w, h; + } +Img_; + +typedef struct _font + { + char *face; + int r, g, b; + } +Font_; + +typedef struct _p + { + float align; + } +P_; + +typedef struct _object + { + Type type; + void *object; + } +Object; + +typedef struct _page + { + char *name; + int count; + Object *obj; + int columns; + int padding; + int linkr, linkg, linkb; + char *background; + } +Page; + +typedef struct _link + { + char *name; + int x, y, w, h; + struct _link *next; + } +Link; + +void Efont_extents(Efont * f, char *text, + int *font_ascent_return, + int *font_descent_return, int *width_return, + int *max_ascent_return, + int *max_descent_return, + int *lbearing_return, int *rbearing_return); +Efont *Efont_load(char *file, int size); +void Efont_free(Efont * f); +void EFont_draw_string(Display * disp, Drawable win, GC gc, + int x, int y, char *text, + Efont * font, Visual * vis, Colormap cm); + +char **TextGetLines(char *text, int *count); +void TextStateLoadFont(TextState * ts); +void TextSize(TextState * ts, char *text, + int *width, int *height, int fsize); +void TextDraw(TextState * ts, Window win, char *text, + int x, int y, int w, int h, int fsize, + int justification); + +char *FileExtension(char *file); +void md(char *s); +int exists(char *s); +void mkdirs(char *s); +int isfile(char *s); +int isdir(char *s); +char **ls(char *dir, int *num); +void freestrlist(char **l, int num); +void rm(char *s); +void mv(char *s, char *ss); +void cp(char *s, char *ss); +time_t moddate(char *s); +int filesize(char *s); +int fileinode(char *s); +int filedev(char *s); +void cd(char *s); +char *cwd(void); +int permissions(char *s); +int owner(char *s); +int group(char *s); +char *username(int uid); +char *homedir(int uid); +char *usershell(int uid); +char *atword(char *s, int num); +char *atchar(char *s, char c); +char *getword(char *s, int num); +void word(char *s, int num, char *wd); +int canread(char *s); +int canwrite(char *s); +int canexec(char *s); +char *fileof(char *s); +char *fullfileof(char *s); +char *pathtoexec(char *file); +char *pathtofile(char *file); + +void AddPage(Object * obj); +void AddObject(Object * obj); +void BuildObj(Object * obj, char *var, char *param); +int GetNextTag(Object * obj); +char *GetTextUntilTag(void); +int GetObjects(FILE *f); +int FixPage(int p); +int GetPage(char *name); +void GetLinkColors(int page_num, int *r, int *g, int *b); +Link *RenderPage(Window win, int page_num, int w, int h); + +extern Display *disp; +extern ImlibData *id; +extern FnlibData *fd; +extern char *docdir; diff --git a/dox/exit1.xpm b/dox/exit1.xpm new file mode 100644 index 00000000..ea1bf301 --- /dev/null +++ b/dox/exit1.xpm @@ -0,0 +1,201 @@ +/* XPM */ +static char * exit1_xpm[] = { +"16 16 182 2", +" c None", +". c #CECECD", +"+ c #D7D7D5", +"@ c #CFCFCE", +"# c #D0D0CE", +"$ c #CFCECB", +"% c #DCDAD8", +"& c #EEEDEC", +"* c #FAFAFA", +"= c #FEFEFE", +"- c #CECBC7", +"; c #CFCDC9", +"> c #C4C3C0", +", c #D1D1CE", +"' c #CDCDCB", +") c #C6C4BF", +"! c #E7E5E3", +"~ c #FFFFFF", +"{ c #EEEDEB", +"] c #D7D5D1", +"^ c #C8C6C0", +"/ c #C3C0BA", +"( c #AFADA9", +"_ c #CACAC7", +": c #CACAC9", +"< c #CBCBCA", +"[ c #D6D6D4", +"} c #C4C2BD", +"| c #DDDBD8", +"1 c #ADA8A0", +"2 c #ACA8A0", +"3 c #ACA79F", +"4 c #918C86", +"5 c #969590", +"6 c #CBCBC8", +"7 c #D1D0CE", +"8 c #CCCBC6", +"9 c #D2D0CC", +"0 c #494744", +"a c #C8C5C0", +"b c #B3AFA9", +"c c #726F6B", +"d c #9A9892", +"e c #ADACAA", +"f c #D0CFCD", +"g c #E5E3E1", +"h c #E8E7E5", +"i c #B1ADA6", +"j c #484643", +"k c #B8B6B3", +"l c #474643", +"m c #4D4B48", +"n c #CCC9C5", +"o c #A9A59F", +"p c #868581", +"q c #CECECC", +"r c #C9C7C2", +"s c #F6F6F5", +"t c #C3BFB9", +"u c #A59F96", +"v c #8B867E", +"w c #43403D", +"x c #42403C", +"y c #44413D", +"z c #CECBC6", +"A c #B2ADA5", +"B c #A49E95", +"C c #696764", +"D c #C6C5C2", +"E c #BAB9B5", +"F c #ADA8A1", +"G c #A5A098", +"H c #8A867F", +"I c #43413D", +"J c #454340", +"K c #C4C1BC", +"L c #A49F97", +"M c #9D9991", +"N c #5D5C58", +"O c #BBB9B6", +"P c #C3C2BF", +"Q c #F6F5F5", +"R c #A29D95", +"S c #75716C", +"T c #413F3C", +"U c #C2BFBA", +"V c #A19C94", +"W c #88847E", +"X c #676562", +"Y c #C3C3BF", +"Z c #C1C0BB", +"` c #989389", +" . c #67625B", +".. c #393733", +"+. c #413F3B", +"@. c #BDBAB4", +"#. c #393732", +"$. c #B6B2AB", +"%. c #625E57", +"&. c #75736D", +"*. c #C4C3BE", +"=. c #C4C2BF", +"-. c #C7C6C1", +";. c #B0ACA5", +">. c #726D65", +",. c #373531", +"'. c #3A3834", +"). c #BAB7B1", +"!. c #898378", +"~. c #888277", +"{. c #373530", +"]. c #3C3A35", +"^. c #A29F99", +"/. c #514E4A", +"(. c #95928D", +"_. c #C5C3C0", +":. c #C3C3C0", +"<. c #C0BDB9", +"[. c #787369", +"}. c #9D9992", +"|. c #A9A69F", +"1. c #79746A", +"2. c #777268", +"3. c #8C887F", +"4. c #8B8882", +"5. c #62615D", +"6. c #676560", +"7. c #A9A7A2", +"8. c #C1C1BE", +"9. c #C2C2BF", +"0. c #C1C1BF", +"a. c #B5B4B1", +"b. c #AEABA6", +"c. c #807B71", +"d. c #797368", +"e. c #787368", +"f. c #736E63", +"g. c #656056", +"h. c #534F48", +"i. c #474540", +"j. c #65625C", +"k. c #A09D97", +"l. c #B8B7B3", +"m. c #C3C3C1", +"n. c #D4D4D4", +"o. c #D0D1D0", +"p. c #C9C8C6", +"q. c #B8B6B4", +"r. c #B4B2AE", +"s. c #9E9B94", +"t. c #928E86", +"u. c #4C4A45", +"v. c #514F4A", +"w. c #625F5A", +"x. c #827F79", +"y. c #AAA8A3", +"z. c #C2C1BF", +"A. c #D0D0CF", +"B. c #D2D2D1", +"C. c #E2E3E1", +"D. c #E0E0DE", +"E. c #DEDEDB", +"F. c #DAD9D8", +"G. c #D2D1D0", +"H. c #C8C7C4", +"I. c #BDBBB6", +"J. c #BCBAB5", +"K. c #C6C5C1", +"L. c #D4D4D2", +"M. c #DDDDDB", +"N. c #DFDFDD", +"O. c #DEDEDD", +"P. c #DADADA", +"Q. c #D9D9D9", +"R. c #D7D7D7", +"S. c #D8D8D7", +"T. c #D5D5D4", +"U. c #D4D4D3", +"V. c #D6D6D5", +"W. c #D6D6D6", +"X. c #D5D5D5", +"Y. c #D7D8D7", +". . . . . . . . . . . . + + + + ", +". . @ # $ % & * = - ; > , . + + ", +"' ' ' ) ! ~ { ] ^ / / / ( _ : < ", +"[ [ } | ~ - 1 1 2 3 4 4 3 5 6 @ ", +"7 7 8 ~ 9 0 0 a b c 0 0 - d e f ", +"6 6 g h i j j j k l l m n o p q ", +"r r s t u v w w w x y z A B C D ", +"E E ~ F G G H I I J K L L M N O ", +"P P Q R R S x x x T T U V W X Y ", +"Z Z | ` .....+.@.#.#.#.$.%.&.*.", +"=.=.-.;.>.,.'.).!.~.{.].^./.(._.", +":.:.: <.[.}.|.1.[.2.3.4.5.6.7.8.", +"9.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.", +"n.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.", +"C.C.D.E.F.G.H.I.J.J.J.K.L.M.N.O.", +"P.P.P.Q.Q.R.S.T.U.U.U.V.W.X.Y.U."}; diff --git a/dox/exit2.xpm b/dox/exit2.xpm new file mode 100644 index 00000000..5a9c0fcc --- /dev/null +++ b/dox/exit2.xpm @@ -0,0 +1,203 @@ +/* XPM */ +static char * exit2_xpm[] = { +"16 16 184 2", +" c None", +". c #CECECD", +"+ c #D7D7D5", +"@ c #CFCFCE", +"# c #D0D0CE", +"$ c #CFCECB", +"% c #92908D", +"& c #434241", +"* c #111111", +"= c #010101", +"- c #CFCCC8", +"; c #CFCDC9", +"> c #D2D1CE", +", c #D1D1CE", +"' c #D4D3D2", +") c #CDCDCB", +"! c #C6C4BF", +"~ c #4F4D4B", +"{ c #000000", +"] c #383735", +"^ c #82807C", +"/ c #B1AFA9", +"( c #C4C1BB", +"_ c #CDCBC7", +": c #CACAC7", +"< c #CACAC9", +"[ c #CBCBCA", +"} c #D6D6D4", +"| c #C4C2BD", +"1 c #454340", +"2 c #65625E", +"3 c #ABA69E", +"4 c #ABA79F", +"5 c #ADA8A0", +"6 c #918D86", +"7 c #CAC7C3", +"8 c #CBCBC8", +"9 c #D1D0CE", +"0 c #83807C", +"a c #696763", +"b c #484644", +"c c #C7C4BF", +"d c #B2AEA8", +"e c #73706C", +"f c #494744", +"g c #C3BFBA", +"h c #D0CFCD", +"i c #393836", +"j c #32312F", +"k c #AFABA4", +"l c #474542", +"m c #B7B5B2", +"n c #484643", +"o c #4D4B49", +"p c #CDCAC6", +"q c #B4B0A9", +"r c #D7D6D2", +"s c #CECECC", +"t c #C9C7C2", +"u c #0D0D0C", +"v c #6E6A64", +"w c #A39D94", +"x c #89847C", +"y c #42403C", +"z c #43403D", +"A c #44423E", +"B c #CFCBC7", +"C c #B3AEA6", +"D c #A59F96", +"E c #D7D5D2", +"F c #C6C5C2", +"G c #BAB9B5", +"H c #959089", +"I c #A39E96", +"J c #88847D", +"K c #42403D", +"L c #464440", +"M c #C5C2BD", +"N c #A5A098", +"O c #A8A49C", +"P c #D5D4D0", +"Q c #BBB9B6", +"R c #C3C2BF", +"S c #0D0C0C", +"T c #A09B93", +"U c #74706A", +"V c #413F3B", +"W c #413F3C", +"X c #C3C0BB", +"Y c #A29D95", +"Z c #B0ACA5", +"` c #D5D3D0", +" . c #C3C3BF", +".. c #C1C0BB", +"+. c #312F2C", +"@. c #807B71", +"#. c #656159", +"$. c #393632", +"%. c #403E3A", +"&. c #BDB9B3", +"*. c #393732", +"=. c #B6B2AB", +"-. c #B8B4AD", +";. c #C4C3BE", +">. c #C4C2BF", +",. c #7D7B77", +"'. c #5B5750", +"). c #716C63", +"!. c #373430", +"~. c #3A3733", +"{. c #B9B6B0", +"]. c #888277", +"^. c #898378", +"/. c #373530", +"(. c #3D3A36", +"_. c #C1BEB8", +":. c #B8B5B0", +"<. c #C5C3C0", +"[. c #C3C3C0", +"}. c #53524D", +"|. c #767167", +"1. c #9B9890", +"2. c #A8A49E", +"3. c #777268", +"4. c #787369", +"5. c #8D8880", +"6. c #AFACA6", +"7. c #C8C5C1", +"8. c #AFADA8", +"9. c #A9A7A2", +"0. c #C1C1BE", +"a. c #C2C2BF", +"b. c #C1C1BF", +"c. c #B5B4B1", +"d. c #706D66", +"e. c #7D796F", +"f. c #777166", +"g. c #767166", +"h. c #7C766C", +"i. c #8C877E", +"j. c #A8A59E", +"k. c #C0BDB8", +"l. c #ADAAA4", +"m. c #A09D97", +"n. c #B8B7B3", +"o. c #C3C3C1", +"p. c #D4D4D4", +"q. c #D0D1D0", +"r. c #C9C8C6", +"s. c #B8B6B4", +"t. c #969490", +"u. c #9D9A93", +"v. c #908C84", +"w. c #C3C0BD", +"x. c #BFBCB8", +"y. c #B3B0AA", +"z. c #A5A29C", +"A. c #AAA8A3", +"B. c #C2C1BF", +"C. c #D0D0CF", +"D. c #D2D2D1", +"E. c #E2E3E1", +"F. c #E0E0DE", +"G. c #DEDEDB", +"H. c #DAD9D8", +"I. c #D2D1D0", +"J. c #C8C7C4", +"K. c #BDBBB6", +"L. c #BCBAB5", +"M. c #C6C5C1", +"N. c #D4D4D2", +"O. c #DDDDDB", +"P. c #DFDFDD", +"Q. c #DEDEDD", +"R. c #DADADA", +"S. c #D9D9D9", +"T. c #D7D7D7", +"U. c #D8D8D7", +"V. c #D5D5D4", +"W. c #D4D4D3", +"X. c #D6D6D5", +"Y. c #D6D6D6", +"Z. c #D5D5D5", +"`. c #D7D8D7", +". . . . . . . . . . . . + + + + ", +". . @ # $ % & * = - ; > , ' + + ", +") ) ) ! ~ { ] ^ / ( ( ( _ : < [ ", +"} } | 1 { 2 3 3 4 5 6 6 5 7 8 @ ", +"9 9 0 { a b b c d e f f - g h h ", +"8 8 i j k l l l m n n o p q r s ", +"t t u v w x y y y z A B C D E F ", +"G G { H I I J K K L M N N O P Q ", +"R R S T T U V V W y y X Y Z ` .", +"....+.@.#.$.$.%.&.*.*.*.=.-.! ;.", +">.>.,.'.).!.~.{.].^./.(._.t :.<.", +"[.[.< }.|.1.2.3.3.4.5.6.7.8.9.0.", +"a.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.", +"p.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.", +"E.E.F.G.H.I.J.K.L.L.L.M.N.O.P.Q.", +"R.R.R.S.S.T.U.V.W.W.W.X.Y.Z.`.W."}; diff --git a/dox/file.c b/dox/file.c new file mode 100644 index 00000000..8bee687b --- /dev/null +++ b/dox/file.c @@ -0,0 +1,752 @@ + +#include "dox.h" + +char * +FileExtension(char *file) +{ + char *p; + + p = strrchr(file, '.'); + if (p != NULL) + { + return (p + 1); + } + return (""); +} + +void +md(char *s) +{ + if ((!s) || (!*s)) + return; + mkdir(s, S_IRWXU); + return; +} + +int +exists(char *s) +{ + struct stat st; + + if ((!s) || (!*s)) + return (0); + if (stat(s, &st) < 0) + return (0); + return (1); +} + +void +mkdirs(char *s) +{ + char ss[FILEPATH_LEN_MAX]; + int i, ii; + + i = 0; + ii = 0; + while (s[i]) + { + ss[ii++] = s[i]; + ss[ii] = 0; + if (s[i] == '/') + { + if (!exists(ss)) + md(ss); + else if (!isdir(ss)) + return; + } + i++; + } +} + +int +isfile(char *s) +{ + struct stat st; + + if ((!s) || (!*s)) + return (0); + if (stat(s, &st) < 0) + return (0); + if (S_ISREG(st.st_mode)) + return (1); + return (0); +} + +int +isdir(char *s) +{ + struct stat st; + + if ((!s) || (!*s)) + return (0); + if (stat(s, &st) < 0) + return (0); + if (S_ISDIR(st.st_mode)) + return (1); + return (0); +} + +char ** +ls(char *dir, int *num) +{ + int i, dirlen; + int done = 0; + DIR *dirp; + char **names; + struct dirent *dp; + + if ((!dir) || (!*dir)) + return (0); + dirp = opendir(dir); + if (!dirp) + { + *num = 0; + return (NULL); + } + /* count # of entries in dir (worst case) */ + for (dirlen = 0; (dp = readdir(dirp)) != NULL; dirlen++); + if (!dirlen) + { + closedir(dirp); + *num = dirlen; + return (NULL); + } + names = (char **)malloc(dirlen * sizeof(char *)); + + if (!names) + return (NULL); + + rewinddir(dirp); + for (i = 0; i < dirlen;) + { + dp = readdir(dirp); + if (!dp) + break; + if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, ".."))) + { + names[i] = strdup(dp->d_name); + i++; + } + } + + if (i < dirlen) + dirlen = i; /* dir got shorter... */ + closedir(dirp); + *num = dirlen; + /* do a simple bubble sort here to alphanumberic it */ + while (!done) + { + done = 1; + for (i = 0; i < dirlen - 1; i++) + { + if (strcmp(names[i], names[i + 1]) > 0) + { + char *tmp; + + tmp = names[i]; + names[i] = names[i + 1]; + names[i + 1] = tmp; + done = 0; + } + } + } + return (names); +} + +void +freestrlist(char **l, int num) +{ + if (!l) + return; + while (num--) + if (l[num]) + free(l[num]); + free(l); + return; +} + +void +rm(char *s) +{ + if ((!s) || (!*s)) + return; + unlink(s); + return; +} + +void +mv(char *s, char *ss) +{ + if ((!s) || (!ss) || (!*s) || (!*ss)) + return; + rename(s, ss); + return; +} + +void +cp(char *s, char *ss) +{ + int i; + FILE *f, *ff; + unsigned char buf[1]; + + if ((!s) || (!ss) || (!*s) || (!*ss)) + return; + if (!exists(s)) + return; + i = filesize(s); + f = fopen(s, "r"); + if (!f) + return; + ff = fopen(ss, "w"); + if (!ff) + { + fclose(f); + return; + } + while (fread(buf, 1, 1, f)) + fwrite(buf, 1, 1, ff); + fclose(f); + fclose(ff); + return; +} + +time_t +moddate(char *s) +{ + struct stat st; + + if ((!s) || (!*s)) + return (0); + if (!stat(s, &st) < 0) + return (0); + if (st.st_mtime > st.st_ctime) + { + return (st.st_mtime); + } + else + return (st.st_ctime); + return (0); +} + +int +filesize(char *s) +{ + struct stat st; + + if ((!s) || (!*s)) + return (0); + if (stat(s, &st) < 0) + return (0); + return ((int)st.st_size); +} + +int +fileinode(char *s) +{ + struct stat st; + + if ((!s) || (!*s)) + return (0); + if (stat(s, &st) < 0) + return (0); + return ((int)st.st_ino); +} + +int +filedev(char *s) +{ + struct stat st; + + if ((!s) || (!*s)) + return (0); + if (stat(s, &st) < 0) + return (0); + return ((int)st.st_dev); +} + +void +cd(char *s) +{ + if ((!s) || (!*s)) + return; + chdir(s); + return; +} + +char * +cwd(void) +{ + char *s; + char ss[FILEPATH_LEN_MAX]; + + getcwd(ss, FILEPATH_LEN_MAX); + s = strdup(ss); + return (s); +} + +int +permissions(char *s) +{ + struct stat st; + + if ((!s) || (!*s)) + return (0); + if (!stat(s, &st) < 0) + return (0); + return (st.st_mode); +} + +int +owner(char *s) +{ + struct stat st; + + if ((!s) || (!*s)) + return (0); + if (!stat(s, &st) < 0) + return (0); + return (st.st_uid); +} + +int +group(char *s) +{ + struct stat st; + + if ((!s) || (!*s)) + return (0); + if (!stat(s, &st) < 0) + return (0); + return (st.st_gid); +} + +char * +username(int uid) +{ + static int usr_uid = -1; + static char *usr_s = NULL; + char *s; + struct passwd *pwd; + + if (usr_uid < 0) + usr_uid = getuid(); + if ((uid == usr_uid) && (usr_s)) + return strdup(usr_s); + pwd = getpwuid(uid); + if (pwd) + { + s = strdup(pwd->pw_name); + if (uid == usr_uid) + usr_s = strdup(s); + return (s); + } + return (strdup("unknown")); +} + +char * +homedir(int uid) +{ + static int usr_uid = -1; + static char *usr_s = NULL; + char *s; + struct passwd *pwd; + + if (usr_uid < 0) + usr_uid = getuid(); + if ((uid == usr_uid) && (usr_s)) + return strdup(usr_s); + pwd = getpwuid(uid); + if (pwd) + { + s = strdup(pwd->pw_dir); + if (uid == usr_uid) + usr_s = strdup(s); + return (s); + } + return (strdup("/tmp")); +} + +char * +usershell(int uid) +{ + static int usr_uid = -1; + static char *usr_s = NULL; + char *s; + struct passwd *pwd; + + if (usr_uid < 0) + usr_uid = getuid(); + if ((uid == usr_uid) && (usr_s)) + return strdup(usr_s); + pwd = getpwuid(uid); + if (pwd) + { + s = strdup(pwd->pw_shell); + if (uid == usr_uid) + usr_s = strdup(s); + return (s); + } + return (strdup("/bin/sh")); +} + +char * +atword(char *s, int num) +{ + int cnt, i; + + if (!s) + return (NULL); + cnt = 0; + i = 0; + + while (s[i]) + { + if ((s[i] != ' ') && (s[i] != '\t')) + { + if (i == 0) + cnt++; + else if ((s[i - 1] == ' ') || (s[i - 1] == '\t')) + cnt++; + if (cnt == num) + return (&s[i]); + } + i++; + } + return (NULL); +} + +char * +atchar(char *s, char c) +{ + int i; + + if (!s) + return (NULL); + i = 0; + while (s[i] != 0) + { + if (s[i] == c) + return (&s[i]); + i++; + } + return (NULL); +} + +char * +getword(char *s, int num) +{ + + /* *********FIXME************** + * This function is broken but it isn't in use so I'll fix it later + * (DO NOT USE UNTIL FIXED + */ + int cnt, i; + char *start, *finish, *ss, *w; + char *wd = NULL; + + if (!s) + return (NULL); + if (!wd) + return (NULL); + if (num <= 0) + { + *wd = 0; + return (NULL); + } + cnt = 0; + i = 0; + start = NULL; + finish = NULL; + ss = NULL; + w = wd; + + while (s[i]) + { + if ((cnt == num) && ((s[i] == ' ') || (s[i] == '\t'))) + { + finish = &s[i]; + break; + } + if ((s[i] != ' ') && (s[i] != '\t')) + { + if (i == 0) + { + cnt++; + if (cnt == num) + start = &s[i]; + } + else if ((s[i - 1] == ' ') || (s[i - 1] == '\t')) + { + cnt++; + if (cnt == num) + start = &s[i]; + } + } + i++; + } + if (cnt == num) + { + if ((start) && (finish)) + { + for (ss = start; ss < finish; ss++) + *wd++ = *ss; + } + else if (start) + { + for (ss = start; *ss != 0; ss++) + *wd++ = *ss; + } + *wd = 0; + } + return (wd); +} + +void +word(char *s, int num, char *wd) +{ + int cnt, i; + char *start, *finish, *ss, *w; + + if (!s) + return; + if (!wd) + return; + if (num <= 0) + { + *wd = 0; + return; + } + cnt = 0; + i = 0; + start = NULL; + finish = NULL; + ss = NULL; + w = wd; + + while (s[i]) + { + if ((cnt == num) && ((s[i] == ' ') || (s[i] == '\t'))) + { + finish = &s[i]; + break; + } + if ((s[i] != ' ') && (s[i] != '\t')) + { + if (i == 0) + { + cnt++; + if (cnt == num) + start = &s[i]; + } + else if ((s[i - 1] == ' ') || (s[i - 1] == '\t')) + { + cnt++; + if (cnt == num) + start = &s[i]; + } + } + i++; + } + if (cnt == num) + { + if ((start) && (finish)) + { + for (ss = start; ss < finish; ss++) + *wd++ = *ss; + } + else if (start) + { + for (ss = start; *ss != 0; ss++) + *wd++ = *ss; + } + *wd = 0; + } + return; +} + +int +canread(char *s) +{ + if ((!s) || (!*s)) + return (0); + + if (!(permissions(s) & (S_IRUSR | S_IRGRP | S_IROTH))) + return (0); + + return (1 + access(s, R_OK)); +} + +int +canwrite(char *s) +{ + if ((!s) || (!*s)) + return (0); + + if (!(permissions(s) & (S_IWUSR | S_IWGRP | S_IWOTH))) + return (0); + + return (1 + access(s, W_OK)); +} + +int +canexec(char *s) +{ + if ((!s) || (!*s)) + return (0); + + if (!(permissions(s) & (S_IXUSR | S_IXGRP | S_IXOTH))) + return (0); + + return (1 + access(s, X_OK)); +} + +char * +fileof(char *s) +{ + char ss[1024]; + int i, p1, p2; + + i = 0; + p1 = -1; + p2 = -1; + for (i = strlen(s) - 1; i >= 0; i--) + { + if ((s[i] == '.') && (p2 < 0) && (p1 < 0)) + p2 = i; + if ((s[i] == '/') && (p1 < 0)) + p1 = i; + } + if (p2 < 0) + p2 = strlen(s); + if (p1 < 0) + p1 = 0; + for (i = 0; i < (p2 - p1 - 1); i++) + ss[i] = s[p1 + 1 + i]; + ss[i] = 0; + return (strdup(ss)); +} + +char * +fullfileof(char *s) +{ + char ss[1024]; + int i, p1, p2; + + i = 0; + p1 = -1; + for (i = strlen(s) - 1; i >= 0; i--) + { + if ((s[i] == '/') && (p1 < 0)) + p1 = i; + } + p2 = strlen(s); + for (i = 0; i < (p2 - p1 - 1); i++) + ss[i] = s[p1 + 1 + i]; + ss[i] = 0; + return (strdup(ss)); +} + +char * +pathtoexec(char *file) +{ + char *p, *cp, *ep; + char *s; + int len, exelen; + + if (file[0] == '/') + { + if (canexec(file)) + return (strdup(file)); + } + p = getenv("PATH"); + if (!p) + return (strdup(file)); + if (!file) + return (NULL); + cp = p; + exelen = strlen(file); + while ((ep = strchr(cp, ':'))) + { + len = ep - cp; + s = malloc(len + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = 0; + s = realloc(s, len + 2 + exelen); + strcat(s, "/"); + strcat(s, file); + if (canexec(s)) + return (s); + free(s); + } + cp = ep + 1; + } + len = strlen(cp); + s = malloc(len + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = 0; + s = realloc(s, len + 2 + exelen); + strcat(s, "/"); + strcat(s, file); + if (canexec(s)) + return (s); + free(s); + } + return (NULL); +} + +char * +pathtofile(char *file) +{ + char *p, *cp, *ep; + char *s; + int len, exelen; + + if (file[0] == '/') + { + if (exists(file)) + return (strdup(file)); + } + p = getenv("PATH"); + if (!p) + return (strdup(file)); + if (!file) + return (NULL); + cp = p; + exelen = strlen(file); + while ((ep = strchr(cp, ':'))) + { + len = ep - cp; + s = malloc(len + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = 0; + s = realloc(s, len + 2 + exelen); + strcat(s, "/"); + strcat(s, file); + if (exists(s)) + return (s); + free(s); + } + cp = ep + 1; + } + len = strlen(cp); + s = malloc(len + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = 0; + s = realloc(s, len + 2 + exelen); + strcat(s, "/"); + strcat(s, file); + if (exists(s)) + return (s); + free(s); + } + return (NULL); +} diff --git a/dox/format.c b/dox/format.c new file mode 100644 index 00000000..f91c647d --- /dev/null +++ b/dox/format.c @@ -0,0 +1,896 @@ +#include "dox.h" + +static int num_pages = 0; +static Page *page = NULL; +static char *fdat_ptr = NULL; +static int fdat_size = 0; +static char *fdat = NULL; + +static int fdgetc(void); +static void fdjump(int count); + +static int +fdgetc(void) +{ + int val; + + if (fdat_ptr >= (fdat + fdat_size)) + return EOF; + val = (int)(*fdat_ptr); + fdat_ptr++; + return val; +} + +static void +fdjump(int count) +{ + fdat_ptr += count; + if (fdat_ptr < fdat) + fdat_ptr = fdat; + if (fdat_ptr >= (fdat + fdat_size)) + fdat_ptr = (fdat + fdat_size) - 1; +} + +void +AddPage(Object * obj) +{ + num_pages++; + page = realloc(page, sizeof(Page) * (num_pages)); + page[num_pages - 1].name = NULL; + page[num_pages - 1].count = 0; + page[num_pages - 1].obj = NULL; + page[num_pages - 1].columns = 1; + page[num_pages - 1].background = NULL; + page[num_pages - 1].padding = 2; + page[num_pages - 1].linkr = DEFAULT_LINKCOLOR_R; + page[num_pages - 1].linkg = DEFAULT_LINKCOLOR_G; + page[num_pages - 1].linkb = DEFAULT_LINKCOLOR_B; + + if ((obj) && (obj->type == PAGE)) + { + Page *pg; + + pg = (Page *) (obj->object); + if (pg->name) + page[num_pages - 1].name = pg->name; + page[num_pages - 1].columns = pg->columns; + page[num_pages - 1].padding = pg->padding; + page[num_pages - 1].linkr = pg->linkr; + page[num_pages - 1].linkg = pg->linkg; + page[num_pages - 1].linkb = pg->linkb; + if (pg->background) + page[num_pages - 1].background = pg->background; + } +} + +void +AddObject(Object * obj) +{ + page[num_pages - 1].count++; + page[num_pages - 1].obj = + realloc(page[num_pages - 1].obj, + sizeof(Object) * (page[num_pages - 1].count)); + page[num_pages - 1].obj[page[num_pages - 1].count - 1].type = + obj->type; + page[num_pages - 1].obj[page[num_pages - 1].count - 1].object = + obj->object; +} + +void +BuildObj(Object * obj, char *var, char *param) +{ + static Page *pg = NULL; + static P_ *p = NULL; + static Font_ *fn = NULL; + static Img_ *img = NULL; + + switch (obj->type) + { + case IMG: + if (!obj->object) + { + img = obj->object = malloc(sizeof(Img_)); + img->src = NULL; + img->src2 = NULL; + img->src3 = NULL; + img->x = 0; + img->y = 0; + img->link = NULL; + img->w = 0; + img->h = 0; + } + if (!strcmp(var, "x")) + img->x = atoi(param); + else if (!strcmp(var, "y")) + img->y = atoi(param); + else if (!strcmp(var, "src")) + img->src = strdup(param); + else if (!strcmp(var, "src2")) + img->src2 = strdup(param); + else if (!strcmp(var, "src3")) + img->src3 = strdup(param); + else if (!strcmp(var, "href")) + img->link = strdup(param); + break; + case BR: + break; + case FONT: + if (!obj->object) + { + fn = obj->object = malloc(sizeof(Font_)); + fn->face = NULL; + fn->r = 0; + fn->g = 0; + fn->b = 0; + } + if (!strcmp(var, "face")) + fn->face = strdup(param); + else if (!strcmp(var, "color")) + { + char hex[3] = "00"; + + if (param[0] == '#') + { + hex[0] = param[1]; + hex[1] = param[2]; + sscanf(hex, "%x", &(fn->r)); + hex[0] = param[3]; + hex[1] = param[4]; + sscanf(hex, "%x", &(fn->g)); + hex[0] = param[5]; + hex[1] = param[6]; + sscanf(hex, "%x", &(fn->b)); + } + } + break; + case P: + if (!obj->object) + { + p = obj->object = malloc(sizeof(P_)); + p->align = 0; + } + if (!strcmp(var, "align")) + { + if ((strlen(param) > 0) && (param[strlen(param) - 1] == '%')) + param[strlen(param) - 1] = 0; + p->align = atof(param); + } + break; + case TEXT: + break; + case PAGE: + if (!obj->object) + { + pg = obj->object = malloc(sizeof(Page)); + pg->columns = 1; + pg->padding = 1; + pg->name = NULL; + pg->background = NULL; + pg->linkr = DEFAULT_LINKCOLOR_R; + pg->linkg = DEFAULT_LINKCOLOR_G; + pg->linkb = DEFAULT_LINKCOLOR_B; + } + if (!strcmp(var, "columns")) + pg->columns = atoi(param); + else if (!strcmp(var, "padding")) + pg->padding = atoi(param); + else if (!strcmp(var, "name")) + pg->name = strdup(param); + else if (!strcmp(var, "background")) + pg->background = strdup(param); + else if (!strcmp(var, "linkcolor")) + { + char hex[3] = "00"; + + if (param[0] == '#') + { + hex[0] = param[1]; + hex[1] = param[2]; + sscanf(hex, "%x", &(pg->linkr)); + hex[0] = param[3]; + hex[1] = param[4]; + sscanf(hex, "%x", &(pg->linkg)); + hex[0] = param[5]; + hex[1] = param[6]; + sscanf(hex, "%x", &(pg->linkb)); + } + } + break; + default: + break; + } +} + +int +GetNextTag(Object * obj) +{ + char s[65536]; + int i = 0, wd = 0; + int val; + char intag = 0; + char havobj = 0; + + for (;;) + { + val = fdgetc(); + if (val == EOF) + return 0; + if (intag) + { + if (val == '>') + intag = 0; + s[i++] = (char)val; + if (s[i - 1] == '\n') + s[i - 1] = ' '; + if (s[i - 1] == '>') + s[i - 1] = ' '; + if (s[i - 1] == ' ') + { + if (i == 1) + i = 0; + else + { + s[i - 1] = 0; + if (!havobj) + { + if (wd == 0) + { + if (!strcmp(s, "page")) + obj->type = PAGE; + else if (!strcmp(s, "img")) + obj->type = IMG; + else if (!strcmp(s, "br")) + obj->type = BR; + else if (!strcmp(s, "font")) + obj->type = FONT; + else if (!strcmp(s, "p")) + obj->type = P; + havobj = 1; + } + i = 0; + } + else + { + char w1[1024]; + char w2[1024]; + int j = 0; + + w1[0] = 0; + w2[0] = 0; + while ((s[j]) && (s[j] != '=')) + { + w1[j] = s[j]; + j++; + } + w1[j] = 0; + if (j < (int)strlen(s)) + strcpy(w2, &(s[j + 1])); + BuildObj(obj, w1, w2); + i = 0; + } + wd++; + } + } + if (!intag) + return 1; + } + if (val == '<') + intag = 1; + } + return 1; +} + +char * +GetTextUntilTag(void) +{ + char s[65536]; + int i = 0; + int val; + + for (;;) + { + val = fdgetc(); + if (val == EOF) + { + s[i] = 0; + if (strlen(s) < 1) + return NULL; + return strdup(s); + } + s[i++] = (char)val; + if (s[i - 1] == '\n') + s[i - 1] = ' '; + if ((i == 1) && (s[0] == ' ')) + i--; + else if (s[i - 1] == '<') + { + s[i - 1] = 0; + fdjump(-1); + if (strlen(s) < 1) + return NULL; + return strdup(s); + } + if ((i > 2) && (s[i - 2] == ' ') && (s[i - 1] == ' ')) + i--; + if (i > 65530) + return NULL; + } + return NULL; +} + +int +GetObjects(FILE * f) +{ + static char have_font = 0; + static char in_para = 0; + Object obj; + char *txt; + char buf[4096]; + int count; + + fdat = NULL; + fdat_size = 0; + while ((count = fread(buf, 1, 4096, f)) > 0) + { + if (!fdat) + fdat = malloc(count); + else + fdat = realloc(fdat, (fdat_size + count)); + memcpy(fdat + fdat_size, buf, count); + fdat_size += count; + } + fdat_ptr = fdat; + + if (page) + { + int i; + + for (i = 0; i < num_pages; i++) + { + int j; + + if (page[i].name) + free(page[i].name); + if (page[i].background) + free(page[i].background); + for (j = 0; j < page[i].count; j++) + { + switch (page[i].obj[j].type) + { + case IMG: + if (((Img_ *)page[i].obj[j].object)->src) + free(((Img_ *)page[i].obj[j].object)->src); + if (((Img_ *)page[i].obj[j].object)->src2) + free(((Img_ *)page[i].obj[j].object)->src2); + if (((Img_ *)page[i].obj[j].object)->src3) + free(((Img_ *)page[i].obj[j].object)->src3); + if (((Img_ *)page[i].obj[j].object)->link) + free(((Img_ *)page[i].obj[j].object)->link); + break; + case BR: + break; + case FONT: + if (((Font_ *)page[i].obj[j].object)->face) + free(((Font_ *)page[i].obj[j].object)->face); + break; + case P: + break; + case TEXT: + break; + case PAGE: + break; + } + if (page[i].obj[j].object) + free(page[i].obj[j].object); + } + if (page[i].obj) + free(page[i].obj); + } + free(page); + num_pages = 0; + page = NULL; + have_font = 0; + in_para = 0; + } + + obj.object = NULL; + for (;;) + { + if ((have_font) && (in_para)) + { + txt = GetTextUntilTag(); + if (txt) + { + obj.type = TEXT; + obj.object = (void *)txt; + } + else + { + if (!GetNextTag(&obj)) + { + if (fdat) + free(fdat); + return 0; + } + } + } + else + { + if (!GetNextTag(&obj)) + { + if (fdat) + free(fdat); + return 0; + } + } + if (obj.type == PAGE) + { + in_para = 0; + have_font = 0; + AddPage(&obj); + } + else if (page) + AddObject(&obj); + if (obj.type == IMG) + in_para = 0; + if (obj.type == P) + in_para = 1; + if (obj.type == FONT) + have_font = 1; + obj.object = NULL; + } + free(fdat); +} + +int +FixPage(int p) +{ + if (p < 0) + return 0; + if (p >= num_pages) + return num_pages - 1; + return p; +} + +int +GetPage(char *name) +{ + int i; + + for (i = 0; i < num_pages; i++) + { + if ((page[i].name) && (!strcmp(name, page[i].name))) + return i; + } + return -1; +} + +void +GetLinkColors(int page_num, int *r, int *g, int *b) +{ + if (page_num < 0) + { + *r = DEFAULT_LINKCOLOR_R; + *g = DEFAULT_LINKCOLOR_G; + *b = DEFAULT_LINKCOLOR_B; + } + else + { + *r = page[page_num].linkr; + *g = page[page_num].linkg; + *b = page[page_num].linkb; + } +} + +Link * +RenderPage(Window win, int page_num, int w, int h) +{ + Link *ll = NULL; + Page *pg; + TextState ts; + int i, col_w, col_h; + int x, y; + int justification = 0; + int firstp = 1; + ImlibImage *im; + int wastext = 0; + + ts.fontname = NULL; + ts.style.orientation = FONT_TO_RIGHT; + ts.style.mode = MODE_WRAP_WORD; + ts.style.justification = 0; + ts.style.spacing = 0; + ts.font = NULL; + ts.fg_col.r = 0; + ts.fg_col.g = 0; + ts.fg_col.b = 0; + ts.bg_col.r = 0; + ts.bg_col.g = 0; + ts.bg_col.b = 0; + ts.effect = 0; + ts.efont = NULL; + ts.xfont = NULL; + ts.xfontset = 0; + ts.xfontset_ascent = 0; + ts.height = 0; + pg = &(page[page_num]); + x = pg->padding; + y = pg->padding; + col_w = ((w - (pg->padding * (pg->columns + 1))) / pg->columns); + col_h = h - (pg->padding * 2); + if (pg->background) + { + char tmp[4096]; + + sprintf(tmp, "%s/%s", docdir, pg->background); + im = Imlib_load_image(id, tmp); + if (im) + { + Imlib_paste_image(id, im, win, 0, 0, w, h); + Imlib_destroy_image(id, im); + } + } + for (i = 0; i < pg->count; i++) + { + char s[32768], ss[32768], wd[4096], *txt; + Img_ *img; + Font_ *fn; + P_ *p; + int wc, eol, eot; + int link = -1, lx, lw; + + switch (pg->obj[i].type) + { + case IMG: + img = pg->obj[i].object; + if (img->src) + { + char tmp[4096]; + + sprintf(tmp, "%s/%s", docdir, img->src); + im = Imlib_load_image(id, tmp); + if (im) + { + img->w = im->rgb_width; + img->h = im->rgb_height; + Imlib_paste_image(id, im, win, img->x, img->y, + im->rgb_width, im->rgb_height); + Imlib_destroy_image(id, im); + } + if (img->link) + { + Link *l; + + l = malloc(sizeof(Link)); + l->name = strdup(img->link); + l->x = img->x; + l->y = img->y; + l->w = img->w; + l->h = img->h; + l->next = ll; + ll = l; + } + } + break; + case BR: + if (!wastext) + y += ts.height; + wastext = 0; + break; + case FONT: + fn = pg->obj[i].object; + ts.fontname = NULL; + ts.style.orientation = FONT_TO_RIGHT; + ts.style.mode = MODE_WRAP_WORD; + ts.style.justification = 0; + ts.style.spacing = 0; + if (ts.font) + Fnlib_free_font(fd, ts.font); + ts.font = NULL; + ts.fg_col.r = 0; + ts.fg_col.g = 0; + ts.fg_col.b = 0; + ts.bg_col.r = 0; + ts.bg_col.g = 0; + ts.bg_col.b = 0; + ts.effect = 0; + if (ts.efont) + Efont_free(ts.efont); + ts.efont = NULL; + if (ts.xfont) + XFreeFont(disp, ts.xfont); + ts.xfont = NULL; + if (ts.xfontset) + XFreeFontSet(disp, ts.xfontset); + ts.xfontset = NULL; + ts.xfontset_ascent = 0; + ts.height = 0; + ts.fontname = fn->face; + ts.fg_col.r = fn->r; + ts.fg_col.g = fn->g; + ts.fg_col.b = fn->b; + TextStateLoadFont(&ts); + break; + case P: + p = pg->obj[i].object; + if (p) + justification = (int)((p->align / 100) * 1024); + else + justification = 0; + if (!firstp) + y += ts.height; + else + firstp = 0; + break; + case TEXT: + txt = pg->obj[i].object; + wc = 1; + ss[0] = 0; + s[0] = 0; + eol = 0; + eot = 0; + for (;;) + { + char *txt_disp; + int tw, th, xspace; + int off, j; + int sx, sy, ssx, ssy; + char link_txt[1024]; + char link_link[1024]; + + wd[0] = 0; + word(txt, wc, wd); + if (!wd[0]) + eol = 1; + else + { + if (wd[0] == '_') + { + link = strlen(s); + for (j = 1; wd[j] != '('; j++) + wd[j - 1] = wd[j]; + wd[j - 1] = 0; + j++; + strcpy(link_link, &(wd[j])); + link_link[strlen(link_link) - 1] = 0; + strcpy(link_txt, wd); + TextSize(&ts, link_txt, &lw, &th, 17); + TextSize(&ts, s, &lx, &th, 17); + } + } + wc++; + eot++; + strcpy(ss, s); + strcat(s, wd); + if (!eol) + strcat(s, " "); + xspace = col_w; + off = 0; + sx = x + off; + sy = y; + ssx = sx + col_w - 1; + ssy = sy + ts.height - 1; + for (j = 0; j < pg->count; j++) + { + if (pg->obj[j].type == IMG) + { + img = pg->obj[j].object; + if ((img->w > 0) && (img->h > 0)) + { + int ix, iy, iix, iiy; + + ix = img->x; + iy = img->y; + iix = img->x + img->w - 1; + iiy = img->y + img->h - 1; + + if ((iy <= ssy) && (iiy >= sy)) + { + if ((ix >= sx) && (ix <= ssx)) + { + if ((iix >= sx) && (iix <= ssx)) + { + if (((ix + iix) / 2) > ((sx + ssx) / 2)) + ssx = ix - 1; + else + sx = iix + 1; + } + else + { + ssx = ix - 1; + } + } + else if ((iix >= sx) && (iix <= ssx)) + { + sx = iix + 1; + } + } + } + } + } + off = sx - x; + xspace = (ssx - sx) + 1; + if (xspace < 0) + xspace = 0; + TextSize(&ts, s, &tw, &th, 17); + txt_disp = ss; + if (eot == 1) + txt_disp = s; + if (((tw > xspace) || (eol)) && (strlen(txt_disp) > 0)) + { + txt_disp[strlen(txt_disp) - 1] = 0; + if ((eot == 1) && (tw > xspace)) + { + char p1[4096]; + int point = 0, cnt = 0; + + while (txt_disp[(point + cnt)]) + { + p1[cnt] = txt_disp[point + cnt]; + cnt++; + p1[cnt] = 0; + TextSize(&ts, p1, &tw, &th, 17); + if ((tw > xspace) || (!txt_disp[(point + cnt)])) + { + if (txt_disp[(point + cnt)]) + { + point = point + cnt - 1; + p1[cnt - 1] = 0; + cnt = 0; + } + else + { + point = point + cnt; + p1[cnt] = 0; + cnt = 0; + } + wastext = 1; + TextDraw(&ts, win, p1, x + off, y, + xspace, 99999, 17, justification); + y += ts.height; + if (y >= (h - (pg->padding + ts.height - (ts.height - ts.xfontset_ascent)))) + { + y = pg->padding; + x += col_w + pg->padding; + } + xspace = col_w; + off = 0; + sx = x + off; + sy = y; + ssx = sx + col_w - 1; + ssy = sy + ts.height - 1; + for (j = 0; j < pg->count; j++) + { + if (pg->obj[j].type == IMG) + { + img = pg->obj[j].object; + if ((img->w > 0) && (img->h > 0)) + { + int ix, + iy, + iix, + iiy; + + ix = img->x; + iy = img->y; + iix = img->x + img->w - 1; + iiy = img->y + img->h - 1; + + if ((iy <= ssy) && (iiy >= sy)) + { + if ((ix >= sx) && (ix <= ssx)) + { + if ((iix >= sx) && (iix <= ssx)) + { + if (((ix + iix) / 2) > ((sx + ssx) / 2)) + ssx = ix - 1; + else + sx = iix + 1; + } + else + { + ssx = ix - 1; + } + } + else if ((iix >= sx) && (iix <= ssx)) + { + sx = iix + 1; + } + } + } + } + } + off = sx - x; + xspace = (ssx - sx) + 1; + if (xspace < 0) + xspace = 0; + } + } + } + else + { + if ((tw > xspace) && (eot != 1)) + wc--; + wastext = 1; + TextDraw(&ts, win, txt_disp, x + off, y, + xspace, 99999, 17, justification); + if (link >= 0) + { + int rr, gg, bb; + int r, g, b; + int extra; + GC gc; + XGCValues gcv; + + gc = XCreateGC(disp, win, 0, &gcv); + rr = ts.fg_col.r; + gg = ts.fg_col.g; + bb = ts.fg_col.b; + r = ts.fg_col.r = pg->linkr; + g = ts.fg_col.g = pg->linkg; + b = ts.fg_col.b = pg->linkb; + XSetForeground(disp, gc, + Imlib_best_color_match(id, &r, &g, &b)); + TextSize(&ts, txt_disp, &tw, &th, 17); + extra = ((xspace - tw) * justification) >> 10; + TextDraw(&ts, win, link_txt, x + off + lx + extra, y, + 99999, 99999, 17, 0); + XDrawLine(disp, win, gc, + x + off + lx + extra, + y + ts.xfontset_ascent, + x + off + lx + lw + extra, + y + ts.xfontset_ascent); + ts.fg_col.r = rr; + ts.fg_col.g = gg; + ts.fg_col.b = bb; + link = -1; + XFreeGC(disp, gc); + { + Link *l; + + l = malloc(sizeof(Link)); + l->name = strdup(link_link); + l->x = x + off + lx + extra; + l->y = y; + l->w = lw; + l->h = ts.height; + l->next = ll; + ll = l; + } + } + y += ts.height; + if (y >= (h - (pg->padding + ts.height - (ts.height - ts.xfontset_ascent)))) + { + y = pg->padding; + x += col_w + pg->padding; + } + } + eot = 0; + s[0] = 0; + } + if (eol) + break; + } + + break; + default: + break; + } + if (y >= (h - (pg->padding + ts.height - (ts.height - ts.xfontset_ascent)))) + { + y = pg->padding; + x += col_w + pg->padding; + } + } + + if (ts.font) + Fnlib_free_font(fd, ts.font); + if (ts.efont) + Efont_free(ts.efont); + if (ts.xfont) + XFreeFont(disp, ts.xfont); + if (ts.xfontset) + XFreeFontSet(disp, ts.xfontset); + + return ll; +} diff --git a/dox/next1.xpm b/dox/next1.xpm new file mode 100644 index 00000000..eb85a8b1 --- /dev/null +++ b/dox/next1.xpm @@ -0,0 +1,280 @@ +/* XPM */ +static char * next1_xpm[] = { +"64 16 261 2", +" c None", +". c #FEFEFE", +"+ c #EBEEE5", +"@ c #3B3C3A", +"# c #DADCD3", +"$ c #D1D3CB", +"% c #D3D6CE", +"& c #D0D2CA", +"* c #CED1CA", +"= c #D2D5CD", +"- c #D5D7CF", +"; c #D0D3CB", +"> c #CCCEC7", +", c #D6D8D0", +"' c #D1D4CC", +") c #D5D7D0", +"! c #D3D6D0", +"~ c #D6D9D1", +"{ c #D4D6CE", +"] c #D7DAD2", +"^ c #D8DBD3", +"/ c #DCDFD6", +"( c #DEE0D8", +"_ c #E1E4DB", +": c #E3E4DD", +"< c #E3E5DD", +"[ c #DFE1DB", +"} c #E1E4DC", +"| c #DFE1D9", +"1 c #DEE0D9", +"2 c #E0E3DB", +"3 c #DBDCD6", +"4 c #DDE0D8", +"5 c #E5E8E0", +"6 c #E2E5DE", +"7 c #939590", +"8 c #0F0F0F", +"9 c #E4E6DE", +"0 c #D6D6D3", +"a c #D7D7D4", +"b c #D5D5D3", +"c c #D6D6D4", +"d c #D8D8D6", +"e c #D5D5D2", +"f c #D4D4D2", +"g c #D2D3D0", +"h c #D1D2CF", +"i c #D4D4D1", +"j c #D3D3D1", +"k c #D9D9D7", +"l c #666666", +"m c #CDCCCB", +"n c #9B9C97", +"o c #535450", +"p c #050504", +"q c #CBCEC7", +"r c #C8C9C6", +"s c #C7C7C5", +"t c #000000", +"u c #C7C6C4", +"v c #C9C9C7", +"w c #C6C6C4", +"x c #CACAC8", +"y c #C9CAC7", +"z c #CAC9C8", +"A c #CDCDCB", +"B c #CAC9C7", +"C c #CCCCC9", +"D c #CFCECC", +"E c #D0CFCE", +"F c #D3D2D1", +"G c #D6D5D3", +"H c #D7D7D5", +"I c #D8D7D6", +"J c #D9DAD7", +"K c #D9DAD8", +"L c #D7D6D4", +"M c #D2D2D0", +"N c #D2D1D0", +"O c #CFCFCD", +"P c #D0D0CD", +"Q c #D6D6D5", +"R c #D3D4D1", +"S c #D4D4D3", +"T c #979993", +"U c #484946", +"V c #020202", +"W c #D2D4CC", +"X c #C4C5C3", +"Y c #C7C7C6", +"Z c #C8C9C7", +"` c #CBCBC8", +" . c #CDCECC", +".. c #CECFCD", +"+. c #D0D0CE", +"@. c #D1D1D0", +"#. c #CCCCCA", +"$. c #CDCDCC", +"%. c #CECECC", +"&. c #D1D1CF", +"*. c #D3D4D2", +"=. c #DADAD8", +"-. c #D8D9D7", +";. c #D7D7D6", +">. c #D3D3D2", +",. c #CACBC9", +"'. c #9C9E98", +"). c #474846", +"!. c #E0E3DA", +"~. c #CFCFCE", +"{. c #CECECD", +"]. c #D0D0CF", +"^. c #D2D3D1", +"/. c #D1D1CE", +"(. c #C9CAC8", +"_. c #C8C8C7", +":. c #CACBC8", +"<. c #C5C5C3", +"[. c #9B9D97", +"}. c #474745", +"|. c #030303", +"1. c #DFE0D9", +"2. c #CECFCC", +"3. c #CCCCCB", +"4. c #CBCBCA", +"5. c #CDCECB", +"6. c #D2D2D1", +"7. c #D8D8D7", +"8. c #92948E", +"9. c #434441", +"0. c #EDEFE7", +"a. c #D1D2D0", +"b. c #FFFFFF", +"c. c #444542", +"d. c #E7EAE1", +"e. c #DCDCDC", +"f. c #DDDDDC", +"g. c #DBDBDA", +"h. c #DBDBDB", +"i. c #D8D9D8", +"j. c #D7D8D6", +"k. c #CDCECD", +"l. c #CBCBC9", +"m. c #CBCBCB", +"n. c #CACAC9", +"o. c #CCCCCC", +"p. c #CECFCE", +"q. c #93958F", +"r. c #E1E3DB", +"s. c #DEDEDD", +"t. c #DFDFDD", +"u. c #E0E0DF", +"v. c #DFDFDE", +"w. c #E2E2E0", +"x. c #DCDCDA", +"y. c #DCDCDB", +"z. c #D9D9D8", +"A. c #949691", +"B. c #E5E8E1", +"C. c #DBDBD9", +"D. c #434442", +"E. c #FDFDFD", +"F. c #B5B5B3", +"G. c #B6B6B4", +"H. c #B7B6B4", +"I. c #B8B8B6", +"J. c #B9B9B6", +"K. c #BAB9B7", +"L. c #B8B7B5", +"M. c #B8B8B5", +"N. c #B9B8B7", +"O. c #B9B9B7", +"P. c #B7B8B6", +"Q. c #B7B7B4", +"R. c #B6B7B4", +"S. c #B7B8B5", +"T. c #BBBAB8", +"U. c #BABAB8", +"V. c #BCBCBA", +"W. c #BDBDBB", +"X. c #BEBEBC", +"Y. c #BCBCB9", +"Z. c #BBBBB9", +"`. c #B7B7B5", +" + c #BFBFBE", +".+ c #B1B2AF", +"++ c #4E4F4D", +"@+ c #DBDDDA", +"#+ c #CCCDCA", +"$+ c #CACAC7", +"%+ c #C6C6C3", +"&+ c #C8C7C4", +"*+ c #C8C7C5", +"=+ c #C9C8C6", +"-+ c #C8C8C6", +";+ c #C8C7C6", +">+ c #C7C6C5", +",+ c #CCCBC9", +"'+ c #CBCAC9", +")+ c #CECDCC", +"!+ c #CDCDCA", +"~+ c #CFCECD", +"{+ c #919291", +"]+ c #50504F", +"^+ c #1A1A1A", +"/+ c #C7C9C5", +"(+ c #8C8D89", +"_+ c #8B8C88", +":+ c #898A86", +"<+ c #8A8B87", +"[+ c #888986", +"}+ c #888985", +"|+ c #8A8B88", +"1+ c #898A87", +"2+ c #8A8A88", +"3+ c #898986", +"4+ c #878884", +"5+ c #858683", +"6+ c #858682", +"7+ c #868783", +"8+ c #848481", +"9+ c #81827E", +"0+ c #82837F", +"a+ c #81827F", +"b+ c #80817D", +"c+ c #7F807D", +"d+ c #7F7F7C", +"e+ c #7E7F7C", +"f+ c #7D7E7B", +"g+ c #7E7E7B", +"h+ c #7E7F7B", +"i+ c #7F807E", +"j+ c #80817E", +"k+ c #3F3F3E", +"l+ c #131313", +"m+ c #E0E2DB", +"n+ c #7B7C78", +"o+ c #4B4B49", +"p+ c #484847", +"q+ c #494A48", +"r+ c #4E4E4C", +"s+ c #4D4D4C", +"t+ c #4D4E4C", +"u+ c #4C4D4B", +"v+ c #4C4C4B", +"w+ c #4D4D4B", +"x+ c #4B4C4A", +"y+ c #4C4C4A", +"z+ c #4B4B4A", +"A+ c #4A4A48", +"B+ c #4A4B49", +"C+ c #494A49", +"D+ c #4A4A49", +"E+ c #3A3A38", +"F+ c #414240", +"G+ c #171717", +"H+ c #151515", +"I+ c #363736", +"J+ c #181818", +"K+ c #161616", +"L+ c #141414", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ ", +". . # $ % & & $ & * = = - $ ; ; ; > & $ % , % $ = $ = = ' ) % ) ! ~ { ) ] ] ^ ^ ^ ~ ] / / ( _ : < _ [ } | 1 2 2 ( | 3 4 5 6 7 8 ", +". 9 0 a a b b c a a a d 0 0 0 0 0 b b e f b g h i b a a b f j f j f f f j j j f f f f f b b d c k a a d d b l a f f c c m n o p ", +". q r s t t t u v t t t w t x y t y t t t z A B C C D E F G H I I J I K L 0 f f j M N i f M O P N F F f f f l t Q R G S A T U V ", +". W X Y t Z Z t ` t A ...t +.@.t ..#.t A $.%.&.f f *.*.S S S S j j S *.*.R Q =.=.-.Q c ;.c *.c c S S >.>.S l t t j f f ,.'.).V ", +". !.~...t %.%.t {.t ].>.>.t ^.g t O ~.t %.%./.O ~.{.~.~.&.~.@.O O ~./.%.#.#.(.#.(.(._.C y :.y (.y (.l l l l l t t t <.w j [.}.|.", +". 1...+.t 2.&.t @.t ].].].t 2.3.t 2.#.t 3.` #.#.4.5. . .O ~.~.h j S S ;.H S S S S >.f 6.6.S ;.c 7.7.l t t t t t t t t a &.8.9.|.", +". 0.g ^.t +.+.t +.t $.+.+.t 2. .t 2.&.t @.@.S g g ^.&.g a.&.].].a.a.a.S ^.g a.S ^.g R S S S b S b S l t t t t t t t t t b.8.c.|.", +". d.e.f.t e.g.t e.t t e.f.h.t t h.i.j.t S ^.^.@.@.^.@.@.k.l.3.+. . .m.l.n.n.n.n.l.3.o.$.+.+.+.+.p...l t t t t t t t t t b.q.c.|.", +". r.s.t.t u.v.t u.t v.v.u.t w.u.t u.w.t v.v.t.s.s.x.y.x.x.=.g.K K K J K =.=.k a j.b b b R @.M *.0 R l t t t t t t t t b.z.A.c.V ", +". B.` Z t #.x t 3.t 4. .].t +.P t h 2.t #.` l.:.:.l.l. .P O O P @.@.^.+.^.@.^.^.*.*.R M M *.^.].@.f S b.b.b. .t t t b.].C.7 D.|.", +". E.F.F.t G.H.t H.t I.J.K.t L.M.t M.N.t I.I.M.J.O.N.I.I.O.P.O.M.M.Q.I.R.Q.S.I.O.T.T.U.V.W.X.W.V.Y.T.Z.Z.U.Z.l t t b.G.`. +.+++|.", +". @+l.B t l.#+t x t t t $+t $+$+t %+&+t u *+=+x x x &+&+&+-+=+$+v &+;+>+>+u v ;+y x ,+C '+A )+)+)+D #.#+!+)+l t b.~+~+#.H {+]+^+", +". /+(+_+(+_+:+_+(+<+<+<+[+}+<+|+1+2+1+:+3+4+5+6+5+7+5+8+8+9+0+a+0+9+9+a+a+a+0+0+9+0+b+c+c+d+c+d+e+f+f+e+g+h+c+b.c+d+i+j+9+7+k+l+", +"m+n+o+p+q+p+o+r+r+++r+r+r+r+r+r+r+r+s+s+s+r+t+u+u+v+u+w+v+x+y+o+o+o+o+o+o+x+o+x+x+x+x+x+z+A+q+A+z+o+B+B+C+C+B+D+D+B+B+o+E+F+G+H+", +"I+J+G+G+G+G+K+H+H+H+H+K+K+H+H+H+L+K+G+J+J+G+G+K+K+H+H+H+K+K+K+H+H+H+K+H+L+H+K+K+K+K+G+G+G+H+L+l+L+L+L+L+L+L+l+H+H+l+H+H+V l+l+l+"}; diff --git a/dox/next2.xpm b/dox/next2.xpm new file mode 100644 index 00000000..2d108c81 --- /dev/null +++ b/dox/next2.xpm @@ -0,0 +1,286 @@ +/* XPM */ +static char * next2_xpm[] = { +"64 16 267 2", +" c None", +". c #131313", +"+ c #020202", +"@ c #151515", +"# c #141414", +"$ c #171717", +"% c #161616", +"& c #181818", +"* c #363736", +"= c #414240", +"- c #3A3A38", +"; c #4B4B49", +"> c #4A4B49", +", c #4A4A49", +"' c #494A49", +") c #4B4B4A", +"! c #4A4A48", +"~ c #494A48", +"{ c #4B4C4A", +"] c #4C4C4A", +"^ c #4C4C4B", +"/ c #4D4D4B", +"( c #4C4D4B", +"_ c #4D4E4C", +": c #4E4E4C", +"< c #4D4D4C", +"[ c #4E4F4D", +"} c #484847", +"| c #7B7C78", +"1 c #E0E2DB", +"2 c #3F3F3E", +"3 c #868783", +"4 c #81827E", +"5 c #80817E", +"6 c #7F807E", +"7 c #7F7F7C", +"8 c #7F807D", +"9 c #7E7F7B", +"0 c #7E7E7B", +"a c #7E7F7C", +"b c #7D7E7B", +"c c #80817D", +"d c #82837F", +"e c #81827F", +"f c #848481", +"g c #858683", +"h c #858682", +"i c #878884", +"j c #898986", +"k c #898A86", +"l c #898A87", +"m c #8A8A88", +"n c #8A8B88", +"o c #8A8B87", +"p c #888985", +"q c #888986", +"r c #666666", +"s c #8C8D89", +"t c #8B8C88", +"u c #C7C9C5", +"v c #FEFEFE", +"w c #1A1A1A", +"x c #50504F", +"y c #919291", +"z c #D7D7D5", +"A c #000000", +"B c #CDCDCB", +"C c #CCCDCA", +"D c #CFCECC", +"E c #CECDCC", +"F c #CCCBC9", +"G c #CACAC8", +"H c #C9CAC7", +"I c #C8C7C6", +"J c #C9C9C7", +"K c #C7C6C4", +"L c #C7C6C5", +"M c #C8C7C4", +"N c #CACAC7", +"O c #C9C8C6", +"P c #C8C8C6", +"Q c #C8C7C5", +"R c #C7C7C4", +"S c #C6C6C3", +"T c #CBCAC8", +"U c #CCCBC8", +"V c #CBCBC9", +"W c #CAC9C8", +"X c #CAC9C7", +"Y c #DBDDDA", +"Z c #030303", +"` c #B1B2AF", +" . c #BFBFBE", +".. c #B6B6B4", +"+. c #B9B9B7", +"@. c #BBBBB8", +"#. c #BBBBB9", +"$. c #BABAB8", +"%. c #BBBAB8", +"&. c #BCBCB9", +"*. c #BDBDBB", +"=. c #BEBEBC", +"-. c #BCBCBA", +";. c #B8B8B6", +">. c #B7B8B5", +",. c #B7B7B4", +"'. c #B6B7B4", +"). c #B8B8B5", +"!. c #B7B8B6", +"~. c #B9B8B7", +"{. c #B9B9B6", +"]. c #B6B7B5", +"^. c #B8B7B5", +"/. c #BAB9B7", +"(. c #B7B6B4", +"_. c #B6B5B3", +":. c #B5B5B3", +"<. c #FDFDFD", +"[. c #434442", +"}. c #939590", +"|. c #DBDBD9", +"1. c #CFCFCD", +"2. c #CECFCC", +"3. c #D0D0CD", +"4. c #D1D1D0", +"5. c #D2D3D1", +"6. c #D4D4D2", +"7. c #D3D4D2", +"8. c #D2D2D0", +"9. c #D3D4D1", +"0. c #D0D0CE", +"a. c #CDCECC", +"b. c #CACBC8", +"c. c #CBCBC8", +"d. c #CCCCCA", +"e. c #D1D2CF", +"f. c #D1D1CF", +"g. c #C8C9C7", +"h. c #E5E8E1", +"i. c #444542", +"j. c #949691", +"k. c #D9D9D8", +"l. c #CFCFCE", +"m. c #D3D3D1", +"n. c #D5D5D3", +"o. c #D6D6D3", +"p. c #D7D8D6", +"q. c #D7D7D4", +"r. c #D9D9D7", +"s. c #DADAD8", +"t. c #D9DAD8", +"u. c #D9DAD7", +"v. c #DBDBDA", +"w. c #DCDCDA", +"x. c #DCDCDB", +"y. c #DEDEDD", +"z. c #DFDFDD", +"A. c #DFDFDE", +"B. c #E0E0DE", +"C. c #E2E2E0", +"D. c #E0E0DF", +"E. c #E1E3DB", +"F. c #93958F", +"G. c #CECECD", +"H. c #CCCCCB", +"I. c #CCCCCC", +"J. c #CECFCD", +"K. c #CECFCE", +"L. c #CDCDCC", +"M. c #CACAC9", +"N. c #CBCBCB", +"O. c #CDCECD", +"P. c #D4D4D3", +"Q. c #D8D9D8", +"R. c #DBDBDB", +"S. c #DADADA", +"T. c #FFFFFF", +"U. c #DCDCDC", +"V. c #E7EAE1", +"W. c #92948E", +"X. c #D3D3D2", +"Y. c #D2D3D0", +"Z. c #D1D2D0", +"`. c #D0D0CF", +" + c #EDEFE7", +".+ c #434441", +"++ c #D6D6D4", +"@+ c #D8D8D7", +"#+ c #D7D7D6", +"$+ c #D2D2D1", +"%+ c #CDCECB", +"&+ c #CBCBCA", +"*+ c #DFE0D9", +"=+ c #474745", +"-+ c #9B9D97", +";+ c #C5C5C3", +">+ c #C7C7C5", +",+ c #C9CAC8", +"'+ c #CCCCC9", +")+ c #C8C8C7", +"!+ c #CECECC", +"~+ c #D1D1CE", +"{+ c #CCCDCB", +"]+ c #E0E3DA", +"^+ c #474846", +"/+ c #9C9E98", +"(+ c #CACBC9", +"_+ c #D6D6D5", +":+ c #D8D9D7", +"<+ c #C7C7C6", +"[+ c #C4C5C3", +"}+ c #D2D4CC", +"|+ c #484946", +"1+ c #979993", +"2+ c #D6D5D3", +"3+ c #D3D2D1", +"4+ c #D2D1D0", +"5+ c #D4D4D1", +"6+ c #D7D6D4", +"7+ c #D8D7D6", +"8+ c #D0CFCE", +"9+ c #C9C8C7", +"0+ c #C6C6C4", +"a+ c #C6C5C4", +"b+ c #C8C9C6", +"c+ c #CBCEC7", +"d+ c #050504", +"e+ c #535450", +"f+ c #9B9C97", +"g+ c #CDCCCB", +"h+ c #D8D8D6", +"i+ c #D5D5D2", +"j+ c #E4E6DE", +"k+ c #0F0F0F", +"l+ c #E2E5DE", +"m+ c #E5E8E0", +"n+ c #DDE0D8", +"o+ c #DBDCD6", +"p+ c #DFE1D9", +"q+ c #DEE0D8", +"r+ c #E0E3DB", +"s+ c #DEE0D9", +"t+ c #E1E4DC", +"u+ c #DFE1DB", +"v+ c #E1E4DB", +"w+ c #E3E5DD", +"x+ c #E3E4DD", +"y+ c #DCDFD6", +"z+ c #D7DAD2", +"A+ c #D6D9D1", +"B+ c #D8DBD3", +"C+ c #D5D7D0", +"D+ c #D4D6CE", +"E+ c #D3D6D0", +"F+ c #D3D6CE", +"G+ c #D1D4CC", +"H+ c #D2D5CD", +"I+ c #D1D3CB", +"J+ c #D6D8D0", +"K+ c #D0D2CA", +"L+ c #CCCEC7", +"M+ c #D0D3CB", +"N+ c #D5D7CF", +"O+ c #CED1CA", +"P+ c #DADCD3", +"Q+ c #3B3C3A", +"R+ c #EBEEE5", +". . . + @ @ . @ @ . # # # # # # . # @ $ $ $ % % % % @ # @ % @ @ @ % % % @ @ @ % % $ $ & & $ % # @ @ @ % % @ @ @ @ % $ $ $ $ & * ", +"@ $ = - ; > > , , > ' ' > > ; ) ! ~ ! ) { { { { { ; { ; ; ; ; ; ; ] { ^ / ( ^ ( ( _ : < < < : : : : : : : : [ : : ; } ~ } ; | 1 ", +". 2 3 4 5 6 7 8 8 8 9 0 a b b a 7 8 7 8 8 c d 4 d d e e e 4 4 d e d 4 f f g 3 g h g i j k l m l n o p q o o r s t k t s t s u v ", +"w x y z A A A B B A A A C A D E A E A A A F G H I J K L L I M J N O P M M M G G G O Q K R M S P N N N N T U r A V C V W X V Y v ", +"Z [ ` .A ..+.A @.A #.$.#.A %.&.A *.=.A -.$.%.%.+.;.>.,.'.;.,.).).+.!.+.;.;.~.+.{.).;.;.+.~.).].).^.;./.{.;.r A A (..._.:.:.<.v ", +"Z [.}.|.A 1.1.A 2.A 3.4.5.A 6.4.A 5.7.A 8.9.7.7.5.5.4.5.0.5.4.4.3.1.1.3.a.V V b.b.V c.d.2.2.e.f.3.0.r r r r r A A A d.H g.c.h.v ", +"+ i.j.k.A l.f.A m.A n.6.7.A 9.o.A 8.4.A n.n.n.p.q.r.s.s.t.u.t.t.t.v.s.w.w.x.w.y.y.z.A.A.B.C.D.D.D.C.r A A A A A A A A z.z.y.E.v ", +"Z i.F.G.A H.I.A J.A 0.0.K.A J.K.A 0.0.A L.I.H.V M.M.M.M.V N.a.a.0.H.V O.4.4.5.4.4.5.5.P.n.p.Q.R.S.v.r A A A A A A A A A T.U.V.v ", +"Z i.W.X.A X.P.A f.A A Y.P.Y.A A P.n.P.A P.9.Y.5.P.Z.Y.5.P.Z.Z.Z.`.`.f.Z.Y.f.5.Y.Y.P.4.4.4.f.2.J.a.2.r A A A A A A A A A T.Y. +v ", +"Z .+W.f.A X.n.A p.A z q.++A @+@+A #+P.A $+6.X.P.P.P.P.z #+P.P.m.e.l.l.1.a.a.%+&+d.d.c.H.&+d.2.2.H.2.r A A A A A A A A T.0.J.*+v ", +"Z =+-+m.A ;+;+A >+A c.,+,+A ,+H A H b.A '+)+,+,+d.,+d.d.!+~+l.1.1.4.l.f.l.l.G.l.1.~+!+!+C l.1.l.Y.5.Z.T.T.T.G.A A A T.{+J.l.]+v ", +"+ ^+/+(+A 6.m.A X.A P.X.X.A P.++A 7.++A ++_+:+s.s._+9.7.7.P.m.m.P.P.P.P.7.7.6.6.f.!+L.B L.d.J.J.4.0.0.J.a.B r A A T.g.<+<+[+}+v ", +"+ |+1+B A 2+9.A 2+A A A 6.A 3+4+A 1.8.A 5+4+8.m.6.6.o.6+t.7+u.7+7+z 2+3+8+D '+'+X B W W 9+9+H H H G M 0+0+;+r A T.a+L >+>+b+c+v ", +"d+e+f+g+++++6.6.q.q.n.h+h+q.q.r.++h+n.n.6.6.6.6.6.m.m.m.6.6.6.m.6.m.6.n.q.q.n.5+e.Y.n.6.i+n.n.o.o.o.o.o.h+q.q.T.++n.n.q.q.o.j+v ", +"k+}.l+m+n+o+p+q+r+r+s+p+t+u+v+w+x+v+q+y+y+z+A+B+B+B+z+z+C+D+A+E+C+F+C+G+H+H+I+H+I+F+J+F+I+K+L+M+M+M+I+N+H+H+O+K+I+K+K+F+I+P+v v ", +"Q+R+v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v "}; diff --git a/dox/prev1.xpm b/dox/prev1.xpm new file mode 100644 index 00000000..c6b01996 --- /dev/null +++ b/dox/prev1.xpm @@ -0,0 +1,279 @@ +/* XPM */ +static char * prev1_xpm[] = { +"64 16 260 2", +" c None", +". c #FEFEFE", +"+ c #EBEEE5", +"@ c #3B3C3A", +"# c #DADCD3", +"$ c #D1D3CB", +"% c #D3D6CE", +"& c #D0D2CA", +"* c #CED1CA", +"= c #D2D5CD", +"- c #D5D7CF", +"; c #D0D3CB", +"> c #CCCEC7", +", c #D6D8D0", +"' c #D1D4CC", +") c #D5D7D0", +"! c #D3D6D0", +"~ c #D6D9D1", +"{ c #D4D6CE", +"] c #D7DAD2", +"^ c #D8DBD3", +"/ c #DCDFD6", +"( c #DEE0D8", +"_ c #E1E4DB", +": c #E3E4DD", +"< c #E3E5DD", +"[ c #DFE1DB", +"} c #E1E4DC", +"| c #DFE1D9", +"1 c #DEE0D9", +"2 c #E0E3DB", +"3 c #DBDCD6", +"4 c #DDE0D8", +"5 c #E5E8E0", +"6 c #E2E5DE", +"7 c #939590", +"8 c #0F0F0F", +"9 c #E4E6DE", +"0 c #D6D6D3", +"a c #D7D7D4", +"b c #D5D5D3", +"c c #D6D6D4", +"d c #666666", +"e c #D8D8D6", +"f c #D5D5D2", +"g c #D4D4D2", +"h c #D2D3D0", +"i c #D1D2CF", +"j c #D4D4D1", +"k c #D3D3D1", +"l c #D9D9D7", +"m c #CDCCCB", +"n c #9B9C97", +"o c #535450", +"p c #050504", +"q c #CBCEC7", +"r c #C8C9C6", +"s c #C7C7C5", +"t c #C7C6C5", +"u c #C6C5C4", +"v c #000000", +"w c #FFFFFF", +"x c #C5C5C3", +"y c #C6C6C4", +"z c #C8C7C4", +"A c #CACAC8", +"B c #C9CAC7", +"C c #CAC9C8", +"D c #CCCCC9", +"E c #CFCECC", +"F c #D7D7D5", +"G c #D8D7D6", +"H c #D9DAD7", +"I c #D9DAD8", +"J c #D2D2D0", +"K c #D2D1D0", +"L c #D0D0CD", +"M c #D3D4D1", +"N c #D6D5D3", +"O c #D6D6D5", +"P c #D4D4D3", +"Q c #CDCDCB", +"R c #979993", +"S c #484946", +"T c #020202", +"U c #D2D4CC", +"V c #C4C5C3", +"W c #C7C7C6", +"X c #C8C9C7", +"Y c #CDCECC", +"Z c #CECFCD", +"` c #D0D0CE", +" . c #D1D1D0", +".. c #CCCCCA", +"+. c #CDCDCC", +"@. c #D1D1CF", +"#. c #D3D4D2", +"$. c #DADAD8", +"%. c #D7D7D6", +"&. c #D3D3D2", +"*. c #CACBC9", +"=. c #9C9E98", +"-. c #474846", +";. c #E0E3DA", +">. c #CFCFCE", +",. c #CCCDCB", +"'. c #CECECD", +"). c #D1D2D0", +"!. c #D2D3D1", +"~. c #CCCDCA", +"{. c #CECECC", +"]. c #CFCFCD", +"^. c #C9CAC8", +"/. c #C8C8C7", +"(. c #CACBC8", +"_. c #CBCBC9", +":. c #CBCBC8", +"<. c #9B9D97", +"[. c #474745", +"}. c #030303", +"|. c #DFE0D9", +"1. c #CECFCC", +"2. c #CCCCCB", +"3. c #CBCBCA", +"4. c #D2D2D1", +"5. c #D8D8D7", +"6. c #D7D8D6", +"7. c #92948E", +"8. c #434441", +"9. c #EDEFE7", +"0. c #D0D0CF", +"a. c #444542", +"b. c #E7EAE1", +"c. c #DCDCDC", +"d. c #DDDDDC", +"e. c #DBDBDA", +"f. c #DADADA", +"g. c #DBDBDB", +"h. c #CACAC9", +"i. c #CCCCCC", +"j. c #CECFCE", +"k. c #93958F", +"l. c #E1E3DB", +"m. c #DEDEDD", +"n. c #DFDFDD", +"o. c #E2E2E0", +"p. c #E0E0DF", +"q. c #E0E0DE", +"r. c #DFDFDE", +"s. c #DCDCDA", +"t. c #DCDCDB", +"u. c #D9D9D8", +"v. c #949691", +"w. c #E5E8E1", +"x. c #DBDBD9", +"y. c #434442", +"z. c #FDFDFD", +"A. c #B5B5B3", +"B. c #B6B5B3", +"C. c #B6B6B4", +"D. c #B7B6B4", +"E. c #B8B8B6", +"F. c #B9B9B6", +"G. c #BAB9B7", +"H. c #B8B7B5", +"I. c #B8B8B5", +"J. c #B6B7B5", +"K. c #B9B8B7", +"L. c #B9B9B7", +"M. c #B7B8B6", +"N. c #B7B7B4", +"O. c #B6B7B4", +"P. c #B7B8B5", +"Q. c #BBBAB8", +"R. c #BABAB8", +"S. c #BDBDBB", +"T. c #BEBEBC", +"U. c #BCBCBA", +"V. c #BCBCB9", +"W. c #BBBBB9", +"X. c #BBBBB8", +"Y. c #B7B7B5", +"Z. c #BFBFBE", +"`. c #B1B2AF", +" + c #4E4F4D", +".+ c #DBDDDA", +"++ c #CAC9C7", +"@+ c #CCCBC8", +"#+ c #CBCAC8", +"$+ c #CACAC7", +"%+ c #C8C8C6", +"&+ c #C7C7C4", +"*+ c #C7C6C4", +"=+ c #C8C7C5", +"-+ c #C9C8C6", +";+ c #C9C9C7", +">+ c #C8C7C6", +",+ c #CCCBC9", +"'+ c #CECDCC", +")+ c #CDCDCA", +"!+ c #CFCECD", +"~+ c #919291", +"{+ c #50504F", +"]+ c #1A1A1A", +"^+ c #C7C9C5", +"/+ c #8C8D89", +"(+ c #8B8C88", +"_+ c #898A86", +":+ c #8A8B87", +"<+ c #888986", +"[+ c #888985", +"}+ c #8A8B88", +"|+ c #898A87", +"1+ c #8A8A88", +"2+ c #898986", +"3+ c #878884", +"4+ c #858683", +"5+ c #858682", +"6+ c #868783", +"7+ c #848481", +"8+ c #81827E", +"9+ c #82837F", +"0+ c #81827F", +"a+ c #80817D", +"b+ c #7F807D", +"c+ c #7F7F7C", +"d+ c #7E7F7C", +"e+ c #7D7E7B", +"f+ c #7E7E7B", +"g+ c #7E7F7B", +"h+ c #7F807E", +"i+ c #80817E", +"j+ c #3F3F3E", +"k+ c #131313", +"l+ c #E0E2DB", +"m+ c #7B7C78", +"n+ c #4B4B49", +"o+ c #484847", +"p+ c #494A48", +"q+ c #4E4E4C", +"r+ c #4D4D4C", +"s+ c #4D4E4C", +"t+ c #4C4D4B", +"u+ c #4C4C4B", +"v+ c #4D4D4B", +"w+ c #4B4C4A", +"x+ c #4C4C4A", +"y+ c #4B4B4A", +"z+ c #4A4A48", +"A+ c #4A4B49", +"B+ c #494A49", +"C+ c #4A4A49", +"D+ c #3A3A38", +"E+ c #414240", +"F+ c #171717", +"G+ c #151515", +"H+ c #363736", +"I+ c #181818", +"J+ c #161616", +"K+ c #141414", +". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ ", +". . # $ % & & $ & * = = - $ ; ; ; > & $ % , % $ = $ = = ' ) % ) ! ~ { ) ] ] ^ ^ ^ ~ ] / / ( _ : < _ [ } | 1 2 2 ( | 3 4 5 6 7 8 ", +". 9 0 a a b b c d a a e 0 0 0 0 0 b b f g b h i j b a a b g k g k g g g k k k g g g g g b b e c l a a e e b a a g g c c m n o p ", +". q r s s t u d v w x y y z A B B v v v C C v v v D E v v v F v G H v I v 0 g v v J K v g J v L K v v g g g M N O M N P Q R S T ", +". U V W W X d v v w Q Y Z ` ` .Z v ..+.v +.v @.g v #.v P P P v k k v #.v M v $.$.v O v %.c v c v P P &.&.P &.&.&.k g g *.=.-.T ", +". ;.>.Z ,.d v v v '.d d d ).!.h >.v >.~.v {.v ].>.v >.v @.>. .v ].>.v {.v ..v ..^.v /.v B (.v ^.v ^._.^.^.:.W s y x x y k <.[.}.", +". |.Z ` d v v v v v v v v w 1.2.1.v ..3.v :.v ..3.v Y v ].>.>.v k P v %.v P v P P v g v 4.P v c v 5.%.c a F 6.6.5.b &.a @.7.8.}.", +". 9.h d v v v v v v v v v w 1.Y Z v @. .v .v h h v @.v ).@.0.v ).).v P v h v P !.v M v P P v P b v h P h k ).@.g P &.P &.7.a.}.", +". b.c.d.v v v v v v v v v w e.f.g.v v v P !.v v v !. .v v _.2.` v Y v _.v h.v h._.v i.v ` ` v ` j.Z v j.` ` 0.Z i.i.2.>.'.k.a.}.", +". l.m.n.n.v v v v v v v v w o.p.p.v o.q.r.r.v m.v s.t.v s.$.e.I v I v I v $.v a 6.v b v M .v #.0 M v #.g b P k ).@.>.@.u.v.a.T ", +". w.:.X B ..v v v w w w w w ` L @.v 1.1...:.v (.v _._.v L ].].L v .v ` v .v !.#.v M v J #.v 0. .g v !. .L Y 1.L ].].0.x.7 y.}.", +". z.A.A.B.C.D.v v w E.F.G.E.H.I.J.v K.L.E.E.v F.L.v E.v L.M.L.I.v N.v O.v P.v L.Q.v R.v S.T.v U.V.Q.v W.R.W.R.X.G.L.C.Y.Z.`. +}.", +". .+_.++C _.~._.v w @+#+$+$+$+$+%+v z &+*+=+v A A v z v v v -+$+;+v >+t v *+;+v v A ,+D v v '+'+v v ..~.)+'+!+Q Q !+!+..F ~+{+]+", +". ^+/+(+/+(+_+(+w w :+:+<+[+:+}+|+1+|+_+2+3+4+5+4+6+4+7+7+8+9+0+9+8+8+0+0+0+9+9+8+9+a+b+b+c+b+c+d+e+e+d+f+g+b+b+b+c+h+i+8+6+j+k+", +"l+m+n+o+p+o+n+q+q+ +q+q+q+q+q+q+q+q+r+r+r+q+s+t+t+u+t+v+u+w+x+n+n+n+n+n+n+w+n+w+w+w+w+w+y+z+p+z+y+n+A+A+B+B+A+C+C+A+A+n+D+E+F+G+", +"H+I+F+F+F+F+J+G+G+G+G+J+J+G+G+G+K+J+F+I+I+F+F+J+J+G+G+G+J+J+J+G+G+G+J+G+K+G+J+J+J+J+F+F+F+G+K+k+K+K+K+K+K+K+k+G+G+k+G+G+T k+k+k+"}; diff --git a/dox/prev2.xpm b/dox/prev2.xpm new file mode 100644 index 00000000..67c88a7a --- /dev/null +++ b/dox/prev2.xpm @@ -0,0 +1,283 @@ +/* XPM */ +static char * prev2_xpm[] = { +"64 16 264 2", +" c None", +". c #131313", +"+ c #020202", +"@ c #151515", +"# c #141414", +"$ c #171717", +"% c #161616", +"& c #181818", +"* c #363736", +"= c #414240", +"- c #3A3A38", +"; c #4B4B49", +"> c #4A4B49", +", c #4A4A49", +"' c #494A49", +") c #4B4B4A", +"! c #4A4A48", +"~ c #494A48", +"{ c #4B4C4A", +"] c #4C4C4A", +"^ c #4C4C4B", +"/ c #4D4D4B", +"( c #4C4D4B", +"_ c #4D4E4C", +": c #4E4E4C", +"< c #4D4D4C", +"[ c #4E4F4D", +"} c #484847", +"| c #7B7C78", +"1 c #E0E2DB", +"2 c #3F3F3E", +"3 c #868783", +"4 c #81827E", +"5 c #80817E", +"6 c #7F807E", +"7 c #7F7F7C", +"8 c #7F807D", +"9 c #666666", +"0 c #7E7F7B", +"a c #7E7E7B", +"b c #7E7F7C", +"c c #7D7E7B", +"d c #80817D", +"e c #82837F", +"f c #81827F", +"g c #848481", +"h c #858683", +"i c #858682", +"j c #878884", +"k c #898986", +"l c #898A86", +"m c #898A87", +"n c #8A8A88", +"o c #8A8B88", +"p c #8A8B87", +"q c #888985", +"r c #888986", +"s c #8C8D89", +"t c #8B8C88", +"u c #C7C9C5", +"v c #FEFEFE", +"w c #1A1A1A", +"x c #50504F", +"y c #919291", +"z c #D7D7D5", +"A c #CCCCCA", +"B c #CFCECD", +"C c #000000", +"D c #FFFFFF", +"E c #CECDCC", +"F c #CDCDCA", +"G c #CCCDCA", +"H c #CFCECC", +"I c #CCCCC9", +"J c #CCCBC9", +"K c #C9C9C7", +"L c #C7C6C4", +"M c #C8C7C4", +"N c #CACAC7", +"O c #C9C8C6", +"P c #CACAC8", +"Q c #C8C7C5", +"R c #C7C7C4", +"S c #C8C8C6", +"T c #CBCAC8", +"U c #CCCBC8", +"V c #CBCBC9", +"W c #CAC9C8", +"X c #CAC9C7", +"Y c #DBDDDA", +"Z c #030303", +"` c #B1B2AF", +" . c #BFBFBE", +".. c #B7B7B5", +"+. c #B6B6B4", +"@. c #BBBBB9", +"#. c #BABAB8", +"$. c #BBBAB8", +"%. c #BCBCB9", +"&. c #BCBCBA", +"*. c #BEBEBC", +"=. c #BDBDBB", +"-. c #B9B9B7", +";. c #B7B8B5", +">. c #B6B7B4", +",. c #B8B8B6", +"'. c #B7B7B4", +"). c #B8B8B5", +"!. c #B9B9B6", +"~. c #B9B8B7", +"{. c #B6B7B5", +"]. c #B8B7B5", +"^. c #BAB9B7", +"/. c #B7B6B4", +"(. c #B6B5B4", +"_. c #B6B5B3", +":. c #B5B5B3", +"<. c #FDFDFD", +"[. c #434442", +"}. c #939590", +"|. c #DBDBD9", +"1. c #D0D0CF", +"2. c #CDCECC", +"3. c #D4D4D3", +"4. c #D4D4D2", +"5. c #D1D1D0", +"6. c #D3D4D2", +"7. c #D2D2D0", +"8. c #D3D4D1", +"9. c #D2D3D1", +"0. c #D0D0CE", +"a. c #D0D0CD", +"b. c #CFCFCD", +"c. c #CACBC8", +"d. c #CBCBC8", +"e. c #CECFCC", +"f. c #D1D1CF", +"g. c #CBCBCA", +"h. c #CCCCCB", +"i. c #C9CAC7", +"j. c #C8C9C7", +"k. c #E5E8E1", +"l. c #444542", +"m. c #949691", +"n. c #D9D9D8", +"o. c #D6D6D3", +"p. c #D5D5D3", +"q. c #D7D8D6", +"r. c #D7D7D4", +"s. c #DADAD8", +"t. c #D9DAD8", +"u. c #D9DAD7", +"v. c #DBDBDA", +"w. c #DCDCDA", +"x. c #DCDCDB", +"y. c #DEDEDD", +"z. c #DFDFDE", +"A. c #E0E0DE", +"B. c #E2E2E0", +"C. c #E0E0DF", +"D. c #E1E1DF", +"E. c #DFDFDD", +"F. c #E1E3DB", +"G. c #93958F", +"H. c #CECFCD", +"I. c #CECFCE", +"J. c #CCCCCC", +"K. c #CACAC9", +"L. c #CBCBCB", +"M. c #CDCECD", +"N. c #DBDBDB", +"O. c #DADADA", +"P. c #DDDDDC", +"Q. c #DCDCDC", +"R. c #DDDDDD", +"S. c #E7EAE1", +"T. c #92948E", +"U. c #D3D3D2", +"V. c #D1D2D0", +"W. c #D2D3D0", +"X. c #CDCDCC", +"Y. c #D1D1CE", +"Z. c #EDEFE7", +"`. c #434441", +" + c #D8D8D7", +".+ c #D6D6D4", +"++ c #D2D2D1", +"@+ c #D7D7D6", +"#+ c #D3D3D1", +"$+ c #CFCFCE", +"%+ c #DFE0D9", +"&+ c #474745", +"*+ c #9B9D97", +"=+ c #C6C6C4", +"-+ c #C5C5C3", +";+ c #C9CAC8", +">+ c #C8C8C7", +",+ c #CECECC", +"'+ c #CECECD", +")+ c #CCCDCB", +"!+ c #E0E3DA", +"~+ c #474846", +"{+ c #9C9E98", +"]+ c #CACBC9", +"^+ c #D6D6D5", +"/+ c #CDCDCB", +"(+ c #C7C7C6", +"_+ c #C4C5C3", +":+ c #D2D4CC", +"<+ c #484946", +"[+ c #979993", +"}+ c #D6D5D3", +"|+ c #D3D2D1", +"1+ c #D2D1D0", +"2+ c #D4D4D1", +"3+ c #D8D7D6", +"4+ c #C6C5C4", +"5+ c #C7C6C5", +"6+ c #C7C7C5", +"7+ c #C8C9C6", +"8+ c #CBCEC7", +"9+ c #050504", +"0+ c #535450", +"a+ c #9B9C97", +"b+ c #CDCCCB", +"c+ c #D8D8D6", +"d+ c #D9D9D7", +"e+ c #D1D2CF", +"f+ c #D5D5D2", +"g+ c #E4E6DE", +"h+ c #0F0F0F", +"i+ c #E2E5DE", +"j+ c #E5E8E0", +"k+ c #DDE0D8", +"l+ c #DBDCD6", +"m+ c #DFE1D9", +"n+ c #DEE0D8", +"o+ c #E0E3DB", +"p+ c #DEE0D9", +"q+ c #E1E4DC", +"r+ c #DFE1DB", +"s+ c #E1E4DB", +"t+ c #E3E5DD", +"u+ c #E3E4DD", +"v+ c #DCDFD6", +"w+ c #D7DAD2", +"x+ c #D6D9D1", +"y+ c #D8DBD3", +"z+ c #D5D7D0", +"A+ c #D4D6CE", +"B+ c #D3D6D0", +"C+ c #D3D6CE", +"D+ c #D1D4CC", +"E+ c #D2D5CD", +"F+ c #D1D3CB", +"G+ c #D6D8D0", +"H+ c #D0D2CA", +"I+ c #CCCEC7", +"J+ c #D0D3CB", +"K+ c #D5D7CF", +"L+ c #CED1CA", +"M+ c #DADCD3", +"N+ c #3B3C3A", +"O+ c #EBEEE5", +". . . + @ @ . @ @ . # # # # # # . # @ $ $ $ % % % % @ # @ % @ @ @ % % % @ @ @ % % $ $ & & $ % # @ @ @ % % @ @ @ @ % $ $ $ $ & * ", +"@ $ = - ; > > , , > ' ' > > ; ) ! ~ ! ) { { { { { ; { ; ; ; ; ; ; ] { ^ / ( ^ ( ( _ : < < < : : : : : : : : [ : : ; } ~ } ; | 1 ", +". 2 3 4 5 6 7 8 9 8 0 a b c c b 7 8 7 8 8 d e 4 e e f f f 4 4 e f e 4 g g h 3 h i h j k l m n m o p q r p p p s t l t s t s u v ", +"w x y z A B B 9 C D E F G A H E E C C C I J C C C K L C C C M C N O C M C M P C C O Q C R M C S N C C N T U J P V G V W X V Y v ", +"Z [ ` ...+.9 C C D @.#.@.@.$.%.&.C *.=.C #.C $.-.C ;.C >.,.'.C ).-.C -.C ,.C -.!.C ,.C -.~.C {.C ].,.^.!.,././.(./.+._.:.:.<.v ", +"Z [.}.|.1.9 C C C 2.9 9 9 3.4.5.1.C 6.7.C 8.C 6.9.C 5.C 0.9.5.C a.b.C a.C V C c.c.C d.C e.e.C f.C 0.0.1.2.g.h.h.d.P A i.j.d.k.v ", +"+ l.m.n.9 C C C C C C C C D 8.o.6.C 5.8.C p.C q.r.C s.C t.u.t.C t.v.C w.C x.C y.y.C z.C A.B.C C.C B.D.C.z.z.C.C.A.z.C.E.E.y.F.v ", +"Z l.G.9 C C C C C C C C C D H.I.0.C 0.0.C J.C V K.C K.C V L.2.C 0.h.C M.C 5.C 5.5.C 9.C p.q.C N.O.C N.P.Q.Q.Q.Q.R.v.Q.N.P.Q.S.v ", +"Z l.T.U.C C C C C C C C C D 3.p.3.C C C 3.8.C C C V.W.C C V.V.V.C 1.C V.C f.C W.W.C 5.C 5.f.C H.2.e.C 0.0.X.Y.0.b.0.0.9.9.W.Z.v ", +"Z `.T.f.r.C C C C C C C C D + +.+C 3.++++4.C 3.C 3.3.C @+3.3.#+C $+C b.C 2.C g.A C d.C g.A C e.h.e.C 1.1.1.7.5.5.f.e.b.0.H.%+v ", +"Z &+*+#+=+-+C C C D D D D D ;+i.;+C c.i.I >+C ;+C ;+A C ,+Y.$+b.C 5.C f.C $+C $+b.C ,+C G $+C $+W.9.C U.U.1.'+'+)+,+,+)+H.$+!+v ", +"+ ~+{+]+4.4.#+C C D 3.U.U.3.3..+.+C .+@+.+^+C s.s.C 8.C 6.3.#+#+C 3.C 3.C 6.C 4.f.C X.C X.A C H.5.0.C H.2./+d.d.S j.j.(+(+_+:+v ", +"+ <+[+/+3.}+8.^+C D 4.4.4.|+|+1+a.C 7.4.2+1+C #+4.C o.C C C u.3+3+C }+|+C H I C C /+W W C C i.i.C C M =+=+-+Q K L 4+5+6+6+7+8+v ", +"9+0+a+b+.+.+4.4.D D p.c+c+r.r.d+.+c+p.p.4.4.4.4.4.#+#+#+4.4.4.#+4.#+4.p.r.r.p.2+e+W.p.4.f+p.p.o.o.o.o.o.c+r.r.r..+p.p.r.r.o.g+v ", +"h+}.i+j+k+l+m+n+o+o+p+m+q+r+s+t+u+s+n+v+v+w+x+y+y+y+w+w+z+A+x+B+z+C+z+D+E+E+F+E+F+C+G+C+F+H+I+J+J+J+F+K+E+E+L+H+F+H+H+C+F+M+v v ", +"N+O+v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v "}; diff --git a/dox/text.c b/dox/text.c new file mode 100644 index 00000000..58a4e8db --- /dev/null +++ b/dox/text.c @@ -0,0 +1,420 @@ +#include "dox.h" + +char ** +TextGetLines(char *text, int *count) +{ + int i, j, k; + char **list = NULL; + + *count = 0; + i = 0; + k = 0; + if (!text) + return NULL; + *count = 1; + while (text[i]) + { + j = i; + while ((text[j]) && (text[j] != '\n')) + j++; + k++; + list = realloc(list, sizeof(char *) * k); + list[k - 1] = malloc(sizeof(char) * (j - i + 1)); + + strncpy(list[k - 1], &(text[i]), (j - i)); + list[k - 1][j - i] = 0; + i = j; + if (text[i] == '\n') + i++; + } + *count = k; + return list; +} + +void +TextStateLoadFont(TextState * ts) +{ + if ((ts->font) || (ts->efont) || (ts->xfont) || (ts->xfontset)) + return; + if (!ts->fontname) + return; + if ((!ts->font) && (!ts->efont)) + ts->font = Fnlib_load_font(fd, ts->fontname); + if ((!ts->font) && (!ts->efont)) + { + char s[4096], w[4046], *dup, *ss; + + dup = NULL; + dup = strdup(ts->fontname); + ss = strchr(dup, '/'); + if (ss) + { + *ss = ' '; + word(dup, 1, w); + sprintf(s, "%s/%s.ttf", docdir, w); + word(dup, 2, w); + ts->efont = Efont_load(s, atoi(w)); + if (ts->efont) + { + int as, ds; + + Efont_extents(ts->efont, " ", &as, &ds, NULL, NULL, NULL, NULL, NULL); + ts->xfontset_ascent = as; + ts->height = as + ds; + } + } + if (dup) + free(dup); + } + if ((!ts->font) && (!ts->efont)) + { + if ((!ts->xfont) && (strchr(ts->fontname, ',') == NULL)) + { + ts->xfont = XLoadQueryFont(disp, ts->fontname); + if (ts->xfont) + { + ts->xfontset_ascent = ts->xfont->ascent; + ts->height = ts->xfont->ascent + ts->xfont->descent; + } + } + else if (!ts->xfontset) + { + int i, missing_cnt, font_cnt; + int descent; + char **missing_list, *def_str, **fn; + XFontStruct **fs; + + ts->xfontset = XCreateFontSet(disp, ts->fontname, &missing_list, + &missing_cnt, &def_str); + if (missing_cnt) + { + XFreeStringList(missing_list); + return; + } + if (!ts->xfontset) + return; + font_cnt = XFontsOfFontSet(ts->xfontset, &fs, &fn); + ts->xfontset_ascent = 0; + for (i = 0; i < font_cnt; i++) + ts->xfontset_ascent = MAX(fs[i]->ascent, ts->xfontset_ascent); + descent = 0; + for (i = 0; i < font_cnt; i++) + descent = MAX(fs[i]->descent, descent); + ts->height = ts->xfontset_ascent + descent; + } + } + return; +} + +void +TextSize(TextState * ts, char *text, + int *width, int *height, int fsize) +{ + char **lines; + int i, num_lines; + + *width = 0; + *height = 0; + lines = TextGetLines(text, &num_lines); + if (!lines) + return; + if (!ts) + return; + TextStateLoadFont(ts); + if (ts->font) + { + for (i = 0; i < num_lines; i++) + { + int high, wid, dummy; + + Fnlib_measure(fd, ts->font, 0, 0, 999999, 999999, + 0, 0, fsize, &ts->style, (unsigned char *)lines[i], + 0, 0, &dummy, &dummy, &wid, &high, &dummy, + &dummy, &dummy, &dummy); + *height += high; + if (wid > *width) + *width = wid; + } + } + else if (ts->efont) + { + for (i = 0; i < num_lines; i++) + { + int ascent, descent, wid; + + Efont_extents(ts->efont, lines[i], &ascent, &descent, &wid, + NULL, NULL, NULL, NULL); + *height += ascent + descent; + if (wid > *width) + *width = wid; + } + } + else if (ts->xfontset) + { + for (i = 0; i < num_lines; i++) + { + XRectangle ret1, ret2; + + XmbTextExtents(ts->xfontset, lines[i], strlen(lines[i]), &ret1, &ret2); + *height += ret2.height; + if (ret2.width > *width) + *width = ret2.width; + } + } + else if ((ts->xfont) && (ts->xfont->min_byte1 == 0) && + (ts->xfont->max_byte1 == 0)) + { + for (i = 0; i < num_lines; i++) + { + int wid; + + wid = XTextWidth(ts->xfont, lines[i], strlen(lines[i])); + *height += ts->xfont->ascent + ts->xfont->descent; + if (wid > *width) + *width = wid; + } + } + else if ((ts->xfont)) + { + for (i = 0; i < num_lines; i++) + { + int wid; + + wid = XTextWidth16(ts->xfont, (XChar2b *) lines[i], + strlen(lines[i]) / 2); + *height += ts->xfont->ascent + ts->xfont->descent; + if (wid > *width) + *width = wid; + } + } + freestrlist(lines, num_lines); + return; +} + +void +TextDraw(TextState * ts, Window win, char *text, + int x, int y, int w, int h, int fsize, + int justification) +{ + char **lines; + int i, num_lines; + int xx, yy; + XGCValues gcv; + static GC gc = 0; + int r, g, b; + + lines = TextGetLines(text, &num_lines); + if (!lines) + return; + if (!ts) + return; + TextStateLoadFont(ts); + xx = x; + yy = y; + if (!gc) + gc = XCreateGC(disp, win, 0, &gcv); + if (ts->font) + { + for (i = 0; i < num_lines; i++) + { + int high, wid, dummy; + + Fnlib_measure(fd, ts->font, 0, 0, 999999, 999999, + 0, 0, fsize, &ts->style, (unsigned char *)lines[i], + 0, 0, &dummy, &dummy, &wid, &high, &dummy, + &dummy, &dummy, &dummy); + if ((ts->style.orientation == FONT_TO_UP) || + (ts->style.orientation == FONT_TO_DOWN)) + fsize = w; + xx = x + (((w - wid) * justification) >> 10); + Fnlib_draw(fd, ts->font, win, 0, xx, yy, w, h, + 0, 0, fsize, &ts->style, (unsigned char *)lines[i]); + yy += high; + } + } + else if (ts->efont) + { + for (i = 0; i < num_lines; i++) + { + int ascent, descent, wid; + + Efont_extents(ts->efont, lines[i], &ascent, &descent, &wid, + NULL, NULL, NULL, NULL); + if (i == 0) + yy += ascent; + xx = x + (((w - wid) * justification) >> 10); + if (ts->effect == 1) + { + r = ts->bg_col.r; + g = ts->bg_col.g; + b = ts->bg_col.b; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + EFont_draw_string(disp, win, gc, xx + 1, yy + 1, + lines[i], ts->efont, Imlib_get_visual(id), + Imlib_get_colormap(id)); + } + else if (ts->effect == 2) + { + r = ts->bg_col.r; + g = ts->bg_col.g; + b = ts->bg_col.b; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + EFont_draw_string(disp, win, gc, xx - 1, yy, + lines[i], ts->efont, Imlib_get_visual(id), + Imlib_get_colormap(id)); + EFont_draw_string(disp, win, gc, xx + 1, yy, + lines[i], ts->efont, Imlib_get_visual(id), + Imlib_get_colormap(id)); + EFont_draw_string(disp, win, gc, xx, yy - 1, + lines[i], ts->efont, Imlib_get_visual(id), + Imlib_get_colormap(id)); + EFont_draw_string(disp, win, gc, xx, yy + 1, + lines[i], ts->efont, Imlib_get_visual(id), + Imlib_get_colormap(id)); + } + r = ts->fg_col.r; + g = ts->fg_col.g; + b = ts->fg_col.b; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + EFont_draw_string(disp, win, gc, xx, yy, + lines[i], ts->efont, Imlib_get_visual(id), + Imlib_get_colormap(id)); + yy += ascent + descent; + } + } + else if (ts->xfontset) + { + for (i = 0; i < num_lines; i++) + { + XRectangle ret1, ret2; + + XmbTextExtents(ts->xfontset, lines[i], strlen(lines[i]), &ret1, &ret2); + if (i == 0) + yy += ts->xfontset_ascent; + xx = x + (((w - ret2.width) * justification) >> 10); + if (ts->effect == 1) + { + r = ts->bg_col.r; + g = ts->bg_col.g; + b = ts->bg_col.b; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + XmbDrawString(disp, win, ts->xfontset, gc, xx + 1, yy + 1, + lines[i], strlen(lines[i])); + } + else if (ts->effect == 2) + { + r = ts->bg_col.r; + g = ts->bg_col.g; + b = ts->bg_col.b; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + XmbDrawString(disp, win, ts->xfontset, gc, xx - 1, yy, + lines[i], strlen(lines[i])); + XmbDrawString(disp, win, ts->xfontset, gc, xx + 1, yy, + lines[i], strlen(lines[i])); + XmbDrawString(disp, win, ts->xfontset, gc, xx, yy - 1, + lines[i], strlen(lines[i])); + XmbDrawString(disp, win, ts->xfontset, gc, xx, yy + 1, + lines[i], strlen(lines[i])); + } + r = ts->fg_col.r; + g = ts->fg_col.g; + b = ts->fg_col.b; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + XmbDrawString(disp, win, ts->xfontset, gc, xx, yy, + lines[i], strlen(lines[i])); + yy += ret2.height; + } + } + else if ((ts->xfont) && (ts->xfont->min_byte1 == 0) && + (ts->xfont->max_byte1 == 0)) + { + XSetFont(disp, gc, ts->xfont->fid); + for (i = 0; i < num_lines; i++) + { + int wid; + + wid = XTextWidth(ts->xfont, lines[i], strlen(lines[i])); + if (i == 0) + yy += ts->xfont->ascent; + xx = x + (((w - wid) * justification) >> 10); + if (ts->effect == 1) + { + r = ts->bg_col.r; + g = ts->bg_col.g; + b = ts->bg_col.b; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + XDrawString(disp, win, gc, xx + 1, yy + 1, + lines[i], strlen(lines[i])); + } + else if (ts->effect == 2) + { + r = ts->bg_col.r; + g = ts->bg_col.g; + b = ts->bg_col.b; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + XDrawString(disp, win, gc, xx - 1, yy, + lines[i], strlen(lines[i])); + XDrawString(disp, win, gc, xx + 1, yy, + lines[i], strlen(lines[i])); + XDrawString(disp, win, gc, xx, yy - 1, + lines[i], strlen(lines[i])); + XDrawString(disp, win, gc, xx, yy + 1, + lines[i], strlen(lines[i])); + } + r = ts->fg_col.r; + g = ts->fg_col.g; + b = ts->fg_col.b; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + XDrawString(disp, win, gc, xx, yy, + lines[i], strlen(lines[i])); + yy += ts->xfont->ascent + ts->xfont->descent; + } + } + else if ((ts->xfont)) + { + XSetFont(disp, gc, ts->xfont->fid); + for (i = 0; i < num_lines; i++) + { + int wid; + + wid = XTextWidth16(ts->xfont, (XChar2b *) lines[i], + strlen(lines[i]) / 2); + if (i == 0) + yy += ts->xfont->ascent; + xx = x + (((w - wid) * justification) >> 10); + if (ts->effect == 1) + { + r = ts->bg_col.r; + g = ts->bg_col.g; + b = ts->bg_col.b; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + XDrawString16(disp, win, gc, xx + 1, yy + 1, + (XChar2b *) lines[i], strlen(lines[i]) / 2); + } + else if (ts->effect == 2) + { + r = ts->bg_col.r; + g = ts->bg_col.g; + b = ts->bg_col.b; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + XDrawString16(disp, win, gc, xx - 1, yy, + (XChar2b *) lines[i], strlen(lines[i]) / 2); + XDrawString16(disp, win, gc, xx + 1, yy, + (XChar2b *) lines[i], strlen(lines[i]) / 2); + XDrawString16(disp, win, gc, xx, yy - 1, + (XChar2b *) lines[i], strlen(lines[i]) / 2); + XDrawString16(disp, win, gc, xx, yy + 1, + (XChar2b *) lines[i], strlen(lines[i]) / 2); + } + r = ts->fg_col.r; + g = ts->fg_col.g; + b = ts->fg_col.b; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + XDrawString16(disp, win, gc, xx, yy, + (XChar2b *) lines[i], strlen(lines[i]) / 2); + yy += ts->xfont->ascent + ts->xfont->descent; + } + } + freestrlist(lines, num_lines); + return; +} diff --git a/dox/timestamp.h b/dox/timestamp.h new file mode 100644 index 00000000..e69de29b diff --git a/dox/title.xpm b/dox/title.xpm new file mode 100644 index 00000000..62ea97d2 --- /dev/null +++ b/dox/title.xpm @@ -0,0 +1,259 @@ +/* XPM */ +static char * title_xpm[] = { +"368 16 240 2", +" c None", +". c #D2D2D0", +"+ c #D0D0CE", +"@ c #D1D1CF", +"# c #CFCFCD", +"$ c #CFCFCC", +"% c #CECECC", +"& c #CECECB", +"* c #CDCDCB", +"= c #CCCCCA", +"- c #CBCBC9", +"; c #CBCBC8", +"> c #CCCCC9", +", c #CCCBC9", +"' c #CDCDCA", +") c #CBCBC7", +"! c #C8C8C5", +"~ c #C9C9C6", +"{ c #C9C9C7", +"] c #CECDCA", +"^ c #CDCCC9", +"/ c #D0D0CD", +"( c #D2D2CF", +"_ c #D3D3D0", +": c #D3D3D1", +"< c #D4D4D1", +"[ c #D6D6D3", +"} c #D4D4D2", +"| c #D6D6D4", +"1 c #D7D7D5", +"2 c #D8D8D6", +"3 c #D9D9D7", +"4 c #D6D6D5", +"5 c #DCDCDA", +"6 c #DEDEDC", +"7 c #DDDDDB", +"8 c #DEDDDB", +"9 c #DADAD8", +"0 c #DBDBD9", +"a c #DCDCD9", +"b c #DDDCDA", +"c c #DDDDDA", +"d c #DAD9D7", +"e c #D9D9D6", +"f c #D8D7D5", +"g c #D7D7D4", +"h c #D7D6D4", +"i c #D5D4D2", +"j c #D5D4D1", +"k c #D3D2D0", +"l c #D4D3CF", +"m c #D6D6D2", +"n c #D8D8D5", +"o c #DBDAD8", +"p c #D9D8D6", +"q c #D6D5D3", +"r c #D5D5D2", +"s c #D5D5D3", +"t c #D4D3D1", +"u c #D1D0CE", +"v c #CACAC7", +"w c #CCCCC8", +"x c #D7D6D3", +"y c #DADAD7", +"z c #D6D5D4", +"A c #D5D4D3", +"B c #979795", +"C c #979695", +"D c #959493", +"E c #D2D1CF", +"F c #D3D2D1", +"G c #949492", +"H c #D4D3D2", +"I c #D8D7D6", +"J c #989796", +"K c #D7D6D5", +"L c #999897", +"M c #D9D8D7", +"N c #989896", +"O c #D2D1D0", +"P c #D4D3D0", +"Q c #D1D1CE", +"R c #D2D1CE", +"S c #D1D0CF", +"T c #CFCECD", +"U c #D0CFCD", +"V c #CFCECC", +"W c #D0CFCC", +"X c #D1D0CD", +"Y c #CECDCC", +"Z c #CECDCB", +"` c #CFCECB", +" . c #CDCCCA", +".. c #9C9C99", +"+. c #000000", +"@. c #999997", +"#. c #969693", +"$. c #949491", +"%. c #D7D7D3", +"&. c #DCDCDB", +"*. c #DFDFDD", +"=. c #DEDEDB", +"-. c #DFDFDC", +";. c #E1E1DF", +">. c #E0E0DD", +",. c #E1E1E0", +"'. c #E0E0DE", +"). c #DBDBD8", +"!. c #939290", +"~. c #FFFFFF", +"{. c #949391", +"]. c #C0C0C0", +"^. c #91918F", +"/. c #949392", +"(. c #989795", +"_. c #D7D7D6", +":. c #D0CFCE", +"<. c #CCCBCA", +"[. c #DBDAD7", +"}. c #DCDBD9", +"|. c #DCDBDA", +"1. c #DBDAD9", +"2. c #DAD9D8", +"3. c #9E9E9C", +"4. c #9F9F9D", +"5. c #9D9D9B", +"6. c #9D9D9A", +"7. c #9C9C9A", +"8. c #9B9B99", +"9. c #9E9E9B", +"0. c #DBDBDA", +"a. c #DDDDDC", +"b. c #E0E0DF", +"c. c #939391", +"d. c #939291", +"e. c #969593", +"f. c #9F9E9C", +"g. c #DFDEDD", +"h. c #A1A19F", +"i. c #DEDDDC", +"j. c #9D9C9B", +"k. c #9D9C9A", +"l. c #9A9A98", +"m. c #DDDCDB", +"n. c #D4D4D3", +"o. c #D5D5D4", +"p. c #D3D2CF", +"q. c #CAC9C8", +"r. c #CAC9C7", +"s. c #CDCCCB", +"t. c #CFCFCE", +"u. c #929291", +"v. c #999998", +"w. c #979796", +"x. c #9C9C9B", +"y. c #9D9D9C", +"z. c #A0A09F", +"A. c #9E9E9D", +"B. c #DADAD9", +"C. c #D9D9D8", +"D. c #DFDFDE", +"E. c #E1E1E1", +"F. c #DEDEDD", +"G. c #D3D3D2", +"H. c #D8D8D7", +"I. c #D2D2D1", +"J. c #D1D1D0", +"K. c #E0E0E0", +"L. c #D0D0CF", +"M. c #989897", +"N. c #E0DFDE", +"O. c #9A9A99", +"P. c #DFDFDF", +"Q. c #A2A2A1", +"R. c #A2A2A2", +"S. c #949493", +"T. c #D3D3D3", +"U. c #969694", +"V. c #D7D7D7", +"W. c #D6D6D6", +"X. c #D5D5D5", +"Y. c #DADADA", +"Z. c #D9D9D9", +"`. c #DDDDDD", +" + c #DCDCDC", +".+ c #DEDEDE", +"++ c #DBDBDB", +"@+ c #E2E2E1", +"#+ c #E2E2E2", +"$+ c #E4E4E2", +"%+ c #E3E3E2", +"&+ c #E3E3E1", +"*+ c #E5E5E3", +"=+ c #E5E5E2", +"-+ c #E6E7E5", +";+ c #E2E2E0", +">+ c #E4E4E3", +",+ c #E4E4E1", +"'+ c #E5E5E4", +")+ c #E4E5E3", +"!+ c #CECECD", +"~+ c #CCCCCB", +"{+ c #CDCDCC", +"]+ c #D2D2D2", +"^+ c #D4D4D4", +"/+ c #D6D5D5", +"(+ c #D1D1D1", +"_+ c #D0D0D0", +":+ c #DCDBDB", +"<+ c #E6E6E4", +"[+ c #E7E8E6", +"}+ c #D8D8D8", +"|+ c #CCCDCA", +"1+ c #CACAC8", +"2+ c #CCCBC8", +"3+ c #CBCAC8", +"4+ c #C8C8C6", +"5+ c #C6C6C3", +"6+ c #C8C7C4", +"7+ c #C7C7C4", +"8+ c #C7C6C4", +"9+ c #C8C7C5", +"0+ c #C9C8C6", +"a+ c #C8C7C6", +"b+ c #C7C6C5", +"c+ c #C9CAC7", +"d+ c #CBCAC9", +"e+ c #CDCECB", +"f+ c #D8D9D7", +"g+ c #DDDCDC", +"h+ c #C5C5C2", +"i+ c #C5C6C3", +"j+ c #C4C4C2", +"k+ c #C3C3C1", +"l+ c #C2C1C0", +"m+ c #C4C3C1", +"n+ c #C2C1BF", +"o+ c #C3C2C0", +"p+ c #D2D3D0", +"q+ c #D1D2CF", +". + . . @ # $ # # % % & * = - ; > > = ; ; - - > > , ' > & ' ' ' = > ) ) ! ! ! ! ~ ! ! ! ~ { ) ' ] ^ & / / / $ / ( _ : @ ( . _ _ @ < [ [ [ < } | 1 2 1 3 2 1 | 4 2 2 5 5 6 6 7 8 8 9 3 0 5 0 a 7 b b 6 5 c 0 9 d 3 2 2 e | | f g [ h i f f [ i j k l [ [ [ m n o o o o f [ f n n h h e d p f e g f q i r r i r i s t . u & & $ $ & / & * ' ' % ' ; v ; ; v { v ; ; - ; w ' ' % = & $ / / / # $ + / / + # % % $ + : . i g 1 x 1 1 n n 2 3 3 1 3 9 y y 9 3 3 2 1 g 2 3 2 n 2 9 3 1 1 1 2 e n 2 f 1 r < z [ r < . : . @ @ @ @ @ . : : @ @ : _ < : : : . . + . . @ # $ # # % % & * = - ; > > = ; ; - - > > , ' > & ' ' ' = > ) ) ! ! ! ! ~ ! ! ! ~ { ) ' ] ^ & / / / $ / ( _ : @ ( . _ _ @ < [ [ [ < } | 1 2 1 3 2 1 | 4 2 2 5 5 6 6 7 8 8 9 3 0 5 0 a 7 b b 6 5 c 0 ", +"A B C D ( E k F : G H H i i q I 1 J [ z K L z A : t k t } < A } A h g M 2 2 I 2 M p f g z N K } h p d p p h z z s k O q < P k E Q u R E F z K h M h q f z q i k k k E O _ } } A z | K K | I 1 1 p p 1 3 n h g q K K g q r q | | z } < : < < . i [ [ [ < } | 1 2 1 3 2 1 | 4 2 2 5 0 7 7 5 b 5 3 2 3 9 3 e 3 f p 3 M 9 3 2 p 1 z K i t t H F F @ @ + u R R t t H t t q K I I p h I h q q H } q K s A | | h q s A z q K z 1 2 z I h 2 f | K p p f f K z s O k R u u S S S S t k H t S S T U V U U W % U U X u U U T U ] Y V V U Z ` U U Y .V u O k F A | z H ( E k F : : H H i i q I 1 K [ z K I z A : t k t } < A } A h g M 2 2 I 2 M p f g z 1 K } h p d p p h z z s k O q < P k E Q u R E F z K h M h q f z q i k k k E O _ } } A z | K K | I 1 1 p p 1 3 n h ", +"0 ..+.+.+.3 3 2 2 @.+.| s [ r < r #.+.: } $.+.< < : : @ @ . . : s s } } . s r s s s < s s $.+.[ : . _ } _ _ @ ( @ < : : : s : < : g g g %.r } } } [ s r r | | s : } : Q + / + . . Q Q . . @ < _ _ : _ < r | [ [ g 1 1 q | 1 | i H q } < : k ( E R E F z K h M h q f z q i k k k E k < s s z K 1 I I 2 3 3 3 o 0 0 5 &.7 6 6 7 c 7 5 5 5 a a c a a 5 a 0 0 5 a 5 9 y c a a 7 7 7 5 6 *.*.7 7 7 5 a 6 =.*.*.6 *.-.-.*.;.>.,.;.*.6 *.7 6 6 =.6 7 6 6 *.'.*.*.*.*.6 6 7 c 6 *.7 7 7 6 7 *.7 5 0 0 9 0 9 3 ).).).0 9 9 0 9 3 9 5 7 6 7 5 7 7 7 a a 0 0 5 0 ).).0 e 3 3 2 2 2 e | s [ r < r r [ : } _ < < < : : @ @ . . : s s } } . s r s s s < s s _ : [ : . _ } _ _ @ ( @ < : : : s : < : g g g %.r } } } [ s r r | | s : } : Q + / + . . Q Q . . @ < _ _ : _ < r | ", +": !.+.~.~.~.. F k {.+.].( k @ U u ^.+.~.!./.+.~.E u E . E t F E O S S S F S ( k : s : [ B (.+.~.q | [ | K z A K K H : F H [ K K g 1 M 4 4 1 3 d M e K 1 I p p 2 1 I K 1 f 1 [ h 2 _.I I I z I K K I I d 1 K z | I K 4 [ } r } r } } } | } i : g g g %.r } } } [ s r r | | s : } : ( @ Q @ : : . . : : F < i q | r q A A < t i } A q : O :.:.u Q :.Q / + + u / + U U # Z % * <.- .= ; , <.= = .] Z U W V $ / + u @ : H _ H H H A r 2 z z | 1 x q q z z 1 1 h A H z z q h K 1 f [.o }.|.1.1.o 2.f | | i s q 1 s H k k : t } r q t q i i H H i F k _ : E O : } : . F k k E ( ( k @ U u + :.S E F H } E u E . E t F E O S S S F S ( k : s : [ | h h g q | [ | K z A K K H : F H [ K K g 1 M 4 4 1 3 d M e K 1 I p p 2 1 I K 1 f 1 [ h 2 _.I I I z I K K I I d 1 K ", +"5 3.+.~.5 3.3.7 7 4.+.~.+.5 5.5.5 6.+.~.9 +.+.+.3.7 5 7.8.0 9 7.6.a ..).0 a 5.a 5 6.9.c 6 +.+.+.=.6 6 c 7 7 a a 7 7 5 7 0 6 6 7 6 a 7 5 7 7 0 0 &.7 5 7 5 0 0.0 7 a.a.&.&.0 0.9 3 3 3 3 3 | r | 1 n y n n n f 1 | s | s A K K q s A s g 1 1 g 1 M 4 4 1 3 d M e K 1 I p p 2 1 I K 1 f 1 [ h 1 4 K K K q q s s A s s } . @ @ @ @ @ + / Q + @ _ } : : : _ < : } : } s s r } 1 2 2 9 0 7 7 7 7 5 5 0 5 6 6 7 *.6 *.*.*.'.;.b.'.'.*.'.*.;.6 7 7 6 6 7 7 c 7 7 *.*.6 -.*.c c 6 c c 7 7 5 =.0 a 5 c 5 0 0 3 2 2 2 2 3 3 2 e e 2 3 2 9 9 0 5 5 7 6 6 6 7 7 5 7 7 5 5 7 7 7 7 6 5 5 5 5 5 5 5 a 0 5 9 3 ).5 7 7 5 0 9 0 9 0 a a ).).0 a 5 a 5 a c c 6 =.*.=.=.6 6 c 7 7 a a 7 7 5 7 0 6 6 7 6 a 7 5 7 7 0 0 &.7 5 7 5 0 0.0 7 a.a.&.&.0 0.9 3 3 3 3 3 | r | 1 n y n n n ", +"< c.+.+.S !.+.+.S d.+.].A ].r +.+.D +.+.1 e.+.].~.+.|.f.+.+.g.h.+.+.i.+.5 j.1.+.9 k.+.+.M l.+.~.~.|.|.|.0 m.a.0 m.&.&.i.5 5 7 7 7 m.}.&.|.9 I K K z F F O O F O n.A K F H } n.o.A s 4 I K _.4 z I s H A K 9 d M M p p 3 p p 2.9 9 0 9 7 6 7 6 a 7 5 7 7 0 0 &.7 5 7 5 0 0.0 7 a.a.&.&.0 0.9 9 9 9 2.2.1 [ 1 h 1 2 p I K f 2.9 2 p 9 3 3 1.1.|.1.1.1.2.2.3 1.1.b o |.|.1.3 3 2 M p K q s h z s h z h K 2 1.1.1.2.2.1 K H k k k k p.k E u S k E U :.+ U U U U k O @ u :.+ :.T Y & Z Z Z % V T U u V W V T Z , q.q.r.<.s.Z V s.V V U u u u F t t O } } < . . O S E i k S O O t A } r } H H A A 1 i | | p 2.|.8 6 g.g.'.g.b.i.7 5 |.1.9 9 }.|.0 M 3 o }.}.|.|.|.0 m.a.0 m.&.&.i.5 5 7 7 7 m.}.&.|.9 I K K z F F O O F O n.A K F H } n.o.A s 4 I K _.4 z I s H A K 9 ", +"t.u.+.~.~.u.+.].+.C +.].+.v.+.w.+.].+.].+.v.+.].+.x.+.y.+.].+.8.+.].+.7.+.h.+.z.+.A.+.].+.A.+.~.&.0.0.0.B.0.0.0 5 5 0.C.&.7 D.b.,.E.;.*.F.0 &.&.&.0 9 9 5 5 &.0 &.&.0.0.B.0.5 B.B.0.B.B.B.0.0.&.7 7 5 5 5 0.0.B.1.0 B.2.B.C.1.1.0.m.0 5 7 7 7 m.}.&.|.9 I K K z F F O O F O n.A K F H : G.n.H : n.s n.o.o.} s : F A h 2 _.e 2.H.3 3 H.H.H.2 4 | | _.o.s s s H G.. I.F O . . I.n.} G.n.< F } : _ + / Q O . G.: : : : o.| o.4 1 1 4 o.o.4 1 3 3 3 0.a.a.a.D.F.D.*.*.b.6 6 &.&.0 5 a.7 a.&.&.5 6 7 c B.2 H.2 _.1 _._._._.1 o.o.| 1 n.. : I.I.I.@ @ @ t.t.J.J.. . J.: : s z 4 _._.H.4 4 s o.s o.| H.5 5 0.0.&.&.&.&.9 9 &.B.0.0 a.'.'.D.a.a.F.a.0.a.a.&.&.0.0.0.B.0.0.0 5 5 0.C.&.7 D.b.,.E.;.*.F.0 &.&.&.0 9 9 5 5 &.0 &.&.0.0.B.0.5 B.B.0.B.B.B.0.0.&.7 7 5 5 5 0.", +"_.w.+.~.g w.+.].+.].+.].+.].+.].+.].+.].+.].+.].+.].+.].+.].+.].+.].+.].+.].+.].+.].+.].+.].+.~.n.: I.: @ @ + # # + J.@ I.: n.1 o.n.I.G.I.} } I.I.I.: n.G.n.G.s | | 4 | 4 } : J.G.I.: : G.r | _._.H.0 0 0 0 a 0 B.C.H.3 C.3 B.0 0 C.0.5 F.D.b.K.'.*.F.0 &.&.&.0 9 9 5 5 &.0 &.&.0.0.B.0.5 B.B.B.B.C.B.0.B.0.0 0.0 0.0 0 0 y 4 4 4 | 1 _.| s s n.: . I.G.G.} _ . J.: . t.+ + + J.@ L.@ G.I.. I.I.: I.G.I.: . I.I.I.L.+ J.} } : I.I.I.: G.n.. I.n.: I.I.. : . J.J.I.n.n.s : @ . . L.. : s } s } n.: n.s n.: } . } I.. . I.I.: } n.o.} n.| _.s _.4 1 _._.4 o.| g 4 1 4 H.0.0.B.B.9 _.n _.| g g 3 2 _.1 3 3 C._.C.1 1 _.2 | n.n.: n.I.: I.r : : _ : : : n.: I.: @ @ + # # + J.@ I.: n.1 o.n.I.G.I.} } I.I.I.: n.G.n.G.s | | 4 | 4 } : J.G.I.: : G.r | _._.H.0 0 0 0 ", +"4 M.+.~.2 v.+.].+.].+.].+.].+.].+.].+.].+.].+.].+.+.+.].+.].+.].+.].+.].+.].+.+.+.].+.].+.].+.~.F.a.6 F.D.D.D.7 5 6 a.F.6 a.F.*.*.'.D.6 D.6 7 a.5 5 0.0.2 2 4 4 1 2 2 9 2 9 B.2.3 H.C.0 9 H.3 B.0 0 C.H.C.0 0.9 B.3 H.1 | } : I.G.: G.} o.1 o.o.G.} G.} } I.I.I.: n.G.n.G.s | | 4 | 4 } : I.G.G.t } n.r | _.2 3 9 9 9 2 3 2 C.d B.B.9 1.0 C.3 3 2.C.C.0 a.0.C.0 0 0.&.&.&.&.&.B.0.5 F.6 *.6 D.D.b.D.b.b.;.,.b.6 7 '.N.,.6 7 m.1.0 B.C.B.0 9 C.C.B.B.C.B.5 B.B.B._.4 1 1 _.C.C.H.H.C.2 H.H.C.C.B.3 3 _.| 1 C.H._._._.C.2 3 _.B.9 0 C.9 9 C.9 B.H._.1 4 _.1 | 2 H.H.3 _._._.| | n.| | i n.o.} i i } s o.o.1 _._.3 9 0 0.F.6 &.&.&.&.0.5 B.B.&.F.a.D.D.F.a.6 F.D.D.D.7 5 6 a.F.6 a.F.*.*.'.D.6 D.6 7 a.5 5 0.0.2 2 4 4 1 2 2 9 2 9 B.2.3 H.C.0 9 H.3 B.0 0 C.H.C.0 ", +"3 O.+.~._.w.+.].+.].+.].+.].+.].+.].+.].+.].+.].+.~.~.].+.].+.].+.].+.].+.].+.~.~.].+.].+.].+.~.9 0.9 9 C.H.0 0.B.0.B.0 H.C.9 H.2 _.H.C.C.3 9 B.0 &.0 0 0 B.B.3 0 0 H.2 3 B.B.C.1 4 | } s n.1 o.n.} o._.4 _._._.H.C.B.0 0.0 0 7 &.a.7 a.6 F.*.*.D.6 D.6 7 a.5 5 0.0.2 2 4 4 1 2 2 9 H.0 0.1.9 B.0.5 0 B.9 B.0.5 0 &.&.5 7 B.0.5 5 5 0.0.0 0 5 0 0 ).0 &.&.7 &.5 7 &.0.0.5 0 0 B.B.3 3 3 0.0.&.0.0.&.&.0.B.B.C.C.3 3 C.5 &.0.0.&.a.a.0.0.0.6 &.7 a.&.9 9 9 B.0 &.a.F.a.6 D.7 F.'.'.D.*.*.0.a.F.F.0.&.a.a.F.&.7 '.b.*.7 F.F.&.0.C.&.C.3 2 H.3 3 0 B.B.3 C.C._._.4 _.2 o._._.1 | o.4 | 3 C.9 B.0.9 9 B.y 9 C.2 _._.C.H.H.B.C.3 H.B.C.3 0 0.0.0.5 0.5 0.9 0.9 9 C.H.0 0.B.0.B.0 H.C.9 H.2 _.H.C.C.3 9 B.0 &.0 0 0 B.B.3 0 0 H.2 3 B.B.C.1 4 | } s n.1 o.n.} o._.4 _.", +"P.Q.+.].D.R.+.].+.].+.].+.~.+.].+.].+.].+.].+.~.+.].o.S.+.].+.].+.].+.].+.~.+.].T.U.+.].+.].+.~.V.W._._.V.4 o.o.n.W.4 4 X.H._.C.H.Y.Z.0.0.0.a.&.a.`.0.0.0.0. +F..+D..+D..+`.`.D.`.`.&.&.0.&.0.0.0.0.&.7 6 F.&.0.0 0 0.C.0.5 0.0.0 0 C.C.9 H.2 _.H.C.C.3 9 B.0 &.0 0 0 B.B.3 0 0 H.2 3 B.B.C.1 4 1 o.| 4 2 _._.2 H.C.0.0 &. +a.a.D.D..+D.F..+6 F.a.5 5 Y.0.5 7 5 0.B.9 2 C.B.Y.++++++&. +Y. + + +&.0.0.B.0. +F.F.a.a.&.++5 5 5 ++&.5 7 ++ +&. +F.`.*.D.F.F.F.`.*.F.*.*.*.D.F.6 a.a.`.D.D.D.D.K.E.E.@+@+E.E.E.@+@+@+,.E.E.E.E.@+#+#+$+%+%+#+,.P.P..+P.P.,.P.K.D.E.P.P.K.K.b.P.b..+K.`.&.B.C.3 3 H.2 3 2 2 o.G.n.1 o.s G.: I.I.I.I.I.G.T.s 1 1 _._.W.4 V.W._._.V.4 o.o.n.W.4 4 X.H._.C.H.Y.Z.0.0.0.a.&.a.`.0.0.0.0. +F..+D..+D..+`.`.D.`.`.&.&.0.&.0.0.0.0.&.7 6 F.", +"@+&++.+.+.$++.~.+.~.+.~.+.~.$++.+.~.+.~.+.~.+.~.,.+.+.*.+.~.+.~.+.~.+.~.+.~.a.+.+.o +.~.+.~.+.~.B.B.0 }.0.9 C.H._.H.H.9 H.C.C.9 H.H.0 B.0.7 5 &.a.F.D.D.D.b.,.b.;.b.,.@+@+*+=+=+*+-+-+*+%+*+*+%+%+&+@+&+E.;+@+,.*.a.`.5 1.B.C.Z.3 H.V.C.H.B.C.Y.Z.0.0.0.a.&.a.`.0.0.0.0. +F..+D..+D..+`.`.D.F..+F.F.6 D.*.F.D.'.;.;.;+@+@+;+K.&+$+@+@+@+E.E.E.@+E.@+%+E.E.E.E.E.E.@+,.,.,.,.&+&+%+%+@+@+,.,.,.,.,.b.,.,.E.;.D.,.b.D.D.F.6 6 a.D.D.D.*.D.a.a.&.B.B.0.0.0.B.9 C.H.C.C.3 3 B.C.C.H.3 2 0 0.3 3 C.0.3 5 5 6 F.F.D.,.b.,.@+E.E.,.b.E.E.@+%+@+%+%+%+$+$+&+@+&+%+$+%+$+$+$+%+%+$+$+*+$+$+$+*+$+%+%+&+@+@+;.,.;.;.*.D.F.F.F.6 F.*.*.6 5 a.o 1.o 9 H.3 B.5 9 B.B.0 }.0.9 C.H._.H.H.9 H.C.C.9 H.H.0 B.0.7 5 &.a.F.D.D.D.b.,.b.;.b.,.@+@+*+=+=+*+-+-+*+%+*+*+%+%+&+@+&+E.;+", +": J.: ~.~.~.n.~.G.~._.~._.].@.2 +.~.} ~.G.~.: ~.G.o.~.~.4 ~.H.~.C.~.H.~.H.~.C.C.~.~.2 ~.H.~.2 ~.B.C.H.1 o.| 1 4 | _._.4 4 s | | _.9 3 9 9 9 1 _.4 _.1 | o.| n.1 _.2 2 2 2 2 H.3 4 o.} s G.: : : o.1 4 n.| | o.4 s | | 4 | | o.o.| 1 4 _.H.3 _._.9 B.0.7 5 &.a.F.D.D.D.b.;.b.;.b.,.@+@+>+$+,+$+'+)+%+@+&+@+;.,.D.,.;.,.D.;.;+E.b.,.,.D.*.*.*.6 a.&.0.B.5 B.B.3 2 2 H.1 1 o.} I.J.@ I.I.. } J.t.+ + + t.!+% !+% ~+* ~+~+{+% % % # # # t.+ + % + !+t.t.+ @ J.. . L.J.L.J.. G.I.. @ L.@ + @ : n.s 1 _.H._.1 H._.s 1 4 s G.} . . . . @ . I.} } s } : } : : J.: } . : n.n.G.o._._._.1 2 2 | | } : G.: : G.G.o.1 | 4 1 H.H.C._.H.2 H.H.C.C.3 2 2 C.H.1 2 9 B.C.H.1 o.| 1 4 | _._.4 4 s | | _.9 3 9 9 9 1 _.4 _.1 | o.| n.1 _.2 2 2 2 2 H.3 4 o.} s G.: : : o.1 4 n.| | ", +"++++++Y.C.C.B.B.B.0.0.B.B.C.+.+.1 ~.G.G.G.I.J.J.J.]+G.n.4 4 4 4 4 4 H._._._._.W.4 n.^+n.]+I.n.: G.n.o.G.n.n.n.T.} ^+4 X._.W.H._._.H.4 4 4 /+o.n.T.o.n.n.n.G.(+J.J._+J.t.L.I.I.n.G.I.^+G.G.I.]+(++ S L.@ J.I.I.G.H n.n.o.4 4 1 H.H._._.| 1 1 H.9 3 9 9 9 1 _.4 _.1 | o.| n.1 _.2 2 2 2 2 H.C._.4 s 1 X.4 _._.H.0.&.&. +a.0.a.`.&.F.P.D.P..+b.,.,.E.,.D.P.b.P.P.P.F.F.F.F..+D.a.Y.&.a.a.`.D.,.K.P.b.P.`.`.D..+a.&.C.H.Y.Y.C.B.0.B.Y.B.B.B.C.2.2.C.++Y.C.Y.B.B.&.&.&.&.B.++D.D.F.`.&.0.B.B.C.B.B.0.a.7 &. +`. +`.0.B.B.0.:+5 &.++0.&.&.5 1.B.|.&. +a.a.++++++Y.C.C.B.B.B.0.0.B.B.C.H._.1 z G.G.G.I.J.J.J.]+G.n.4 4 4 4 4 4 H._._._._.W.4 n.^+n.]+I.n.: G.n.o.G.n.n.n.T.} ^+4 X._.W.H._._.H.4 4 4 /+o.n.T.o.n.n.n.G.(+J.J._+J.t.L.I.I.n.G.I.^+G.G.I.]+(++ S L.@ J.I.", +"5 5 5 &.&.F.F.F.b.'.D.'.;.,.@+~.~.E.$+*+<+-+-+<+<+<+-+-+[+-+-+*+=+*+*+*+=+$+&+@+%+%+$+%+%+%+$+@+@+@+,.,.,.'.*.;.,.E.E.b.b.;.b.F.F.D.F.F.F.b.'.6 F.F.a.F.F.b.,.,.b.&.F.&.&.7 0.0.B.0.&.F.F.F.F.F.b.b.a.b.D.F.a.9 B.B.B.C.B.}+2 V.H.H.C.H.C.H.H.H._.4 4 /+o.n.T.o.n.n.n.G.(+I.I.(+I.L.J.n.n.4 o.o._._.V._.}+}+H.C.C.0 0.7 &.a.7 a.*.F.D.6 *.6 a.F.F.D.F.6 6 a.a.F.F.'.6 '.'.F.6 F.D.*.D.F.*.b.b.D.F.*.*.D.D.F.*.*.'.D.,.D.F.a.a.a.7 6 6 a.6 *.6 *.D.b.;.b.b.b.;.b.E.*.*.b.'.b.,.b.*.*.F.6 7 a.5 0 B.3 9 5 5 5 B.0 0 5 7 a.a.a.*.*.*.b.b.b.*.*.F.6 7 &.5 5 5 &.&.F.F.F.b.'.D.'.;.,.@+@+E.E.$+*+<+-+-+<+<+<+-+-+[+-+-+*+=+*+*+*+=+$+&+@+%+%+$+%+%+%+$+@+@+@+,.,.,.'.*.;.,.E.E.b.b.;.b.F.F.D.F.F.F.b.'.6 F.F.a.F.F.b.,.,.b.&.F.&.&.7 0.0.B.0.&.F.F.F.F.F.b.b.a.b.D.F.", +"- r.q.- |+- 1+, 2+3+v v v v 4+5+6+7+8+9+0+1+1+1+6+6+6+4+0+v { 6+a+b+b+8+{ a+c+1+, > d+* Y Y Y V = |+' Y T * * T T = d+d+= |+* Y % % U ~+~+e+S S :.+ * e+% U :.U !+U T T T T |+* # # U U U % U T T u u G.F F t o._.I f+3 3 5 5 +g+a.a.*.F.m.a.F.a.F.F.b.'.6 F.F.a.F.F.b.,.,.b.&.i.&.0.5 B.B.H.C.C.B.C.H.4 1 2 1 } } @ # e+' ] > . .c+{ 8+8+6+4+8+4+7+7+7+a+7+9+6+6+7+h+i+j+k+l+m+k+n+o+k+k+k+m+h+h+6+6+8+7+0+c+v ; * % > % % % U % p+U U / @ u U U U :.@ @ u T * U U U X S @ E q q h K q q q A O / u Y T T q+# * d+> |+, = & T <.T * ' <.<.' d+3+- - r.q.- |+- 1+, 2+3+v v v v 4+5+6+7+8+9+0+1+1+1+6+6+6+4+0+v { 6+a+b+b+8+{ a+c+1+, > d+* Y Y Y V = |+' Y T * * T T = d+d+= |+* Y % % U ~+~+e+S S :.+ * e+% U :.U !+U T T T T |+* # # U U U % U T T u u G.F F "}; diff --git a/dox/ttfont.c b/dox/ttfont.c new file mode 100644 index 00000000..0cc04bc8 --- /dev/null +++ b/dox/ttfont.c @@ -0,0 +1,889 @@ + +#include "dox.h" + +typedef struct _efont_color_tab EfontColorTable; + +struct _efont_color_tab + { + Colormap cmap; + + XColor list[256]; + unsigned char match[8][8][8]; + }; + +/*static EfontColorTable *color_tab = NULL; */ +static unsigned char alpha_lut[5] = +{0, 64, 128, 192, 255}; +static unsigned char bounded_palette[9] = +{0, 1, 2, 3, 4, 4, 4, 4, 4}; + +static TT_Raster_Map * +create_font_raster(int width, int height) +{ + TT_Raster_Map *rmap; + + rmap = malloc(sizeof(TT_Raster_Map)); + rmap->width = (width + 3) & -4; + rmap->rows = height; + rmap->flow = TT_Flow_Down; + rmap->cols = rmap->width; + rmap->size = rmap->rows * rmap->width; + rmap->bitmap = malloc(rmap->size); + memset(rmap->bitmap, 0, rmap->size); + return rmap; +} + +static TT_Raster_Map * +duplicate_raster(TT_Raster_Map * rmap) +{ + TT_Raster_Map *new_rmap; + + new_rmap = malloc(sizeof(TT_Raster_Map)); + *new_rmap = *rmap; + new_rmap->bitmap = malloc(new_rmap->size); + memcpy(new_rmap->bitmap, rmap->bitmap, new_rmap->size); + return new_rmap; +} + +static void +clear_raster(TT_Raster_Map * rmap) +{ + memset(rmap->bitmap, 0, rmap->size); +} + +static void +destroy_font_raster(TT_Raster_Map * rmap) +{ + free(rmap->bitmap); + free(rmap); +} + +static TT_Raster_Map * +calc_size(Efont * f, int *width, int *height, char *text) +{ + int i, upm, ascent, descent, pw, ph; + TT_Instance_Metrics imetrics; + TT_Glyph_Metrics gmetrics; + TT_Raster_Map *rtmp; + + TT_Get_Instance_Metrics(f->instance, &imetrics); + upm = f->properties.header->Units_Per_EM; + ascent = (f->properties.horizontal->Ascender * imetrics.y_ppem) / upm; + descent = (f->properties.horizontal->Descender * imetrics.y_ppem) / upm; + if (descent < 0) + descent = -descent; + pw = 0; + ph = ((f->max_ascent) - f->max_descent) / 64; + + for (i = 0; text[i]; i++) + { + unsigned char j = text[i]; + + if (!TT_VALID(f->glyphs[j])) + continue; + TT_Get_Glyph_Metrics(f->glyphs[j], &gmetrics); + if (i == 0) + { + pw += ((-gmetrics.bearingX) / 64); + } + if (text[i + 1] == 0) + { + pw += (gmetrics.bbox.xMax / 64); + } + else + pw += gmetrics.advance / 64; + } + *width = pw; + *height = ph; + + rtmp = create_font_raster(imetrics.x_ppem + 32, imetrics.y_ppem + 32); + rtmp->flow = TT_Flow_Up; + return rtmp; +} + +static void +render_text(TT_Raster_Map * rmap, TT_Raster_Map * rchr, Efont * f, char *text, + int *xor, int *yor) +{ + TT_Glyph_Metrics metrics; + TT_Instance_Metrics imetrics; + TT_F26Dot6 x, y, xmin, ymin, xmax, ymax; + int i, ioff, iread; + char *off, *read, *_off, *_read; + int x_offset, y_offset; + unsigned char j; + TT_Raster_Map *rtmp; + + TT_Get_Instance_Metrics(f->instance, &imetrics); + + j = text[0]; + TT_Get_Glyph_Metrics(f->glyphs[j], &metrics); + x_offset = (-metrics.bearingX) / 64; + + y_offset = -(f->max_descent / 64); + + *xor = x_offset; + *yor = rmap->rows - y_offset; + + rtmp = NULL; + for (i = 0; text[i]; i++) + { + j = text[i]; + + if (!TT_VALID(f->glyphs[j])) + continue; + + TT_Get_Glyph_Metrics(f->glyphs[j], &metrics); + + xmin = metrics.bbox.xMin & -64; + ymin = metrics.bbox.yMin & -64; + xmax = (metrics.bbox.xMax + 63) & -64; + ymax = (metrics.bbox.yMax + 63) & -64; + + if (f->glyphs_cached[j]) + rtmp = f->glyphs_cached[j]; + else + { + rtmp = rchr; + clear_raster(rtmp); + TT_Get_Glyph_Pixmap(f->glyphs[j], rtmp, -xmin, -ymin); + f->glyphs_cached[j] = duplicate_raster(rtmp); + } + /* Blit-or the resulting small pixmap into the biggest one */ + /* We do that by hand, and provide also clipping. */ + + xmin = (xmin >> 6) + x_offset; + ymin = (ymin >> 6) + y_offset; + xmax = (xmax >> 6) + x_offset; + ymax = (ymax >> 6) + y_offset; + + /* Take care of comparing xmin and ymin with signed values! */ + /* This was the cause of strange misplacements when Bit.rows */ + /* was unsigned. */ + + if (xmin >= (int)rmap->width || + ymin >= (int)rmap->rows || + xmax < 0 || + ymax < 0) + continue; + + /* Note that the clipping check is performed _after_ rendering */ + /* the glyph in the small bitmap to let this function return */ + /* potential error codes for all glyphs, even hidden ones. */ + + /* In exotic glyphs, the bounding box may be larger than the */ + /* size of the small pixmap. Take care of that here. */ + + if (xmax - xmin + 1 > rtmp->width) + xmax = xmin + rtmp->width - 1; + + if (ymax - ymin + 1 > rtmp->rows) + ymax = ymin + rtmp->rows - 1; + + /* set up clipping and cursors */ + + iread = 0; + if (ymin < 0) + { + iread -= ymin * rtmp->cols; + ioff = 0; + ymin = 0; + } + else + ioff = (rmap->rows - ymin - 1) * rmap->cols; + + if (ymax >= rmap->rows) + ymax = rmap->rows - 1; + + if (xmin < 0) + { + iread -= xmin; + xmin = 0; + } + else + ioff += xmin; + + if (xmax >= rmap->width) + xmax = rmap->width - 1; + + _read = (char *)rtmp->bitmap + iread; + _off = (char *)rmap->bitmap + ioff; + + for (y = ymin; y <= ymax; y++) + { + read = _read; + off = _off; + + for (x = xmin; x <= xmax; x++) + { + *off = bounded_palette[*off | *read]; + off++; + read++; + } + _read += rtmp->cols; + _off -= rmap->cols; + } + x_offset += metrics.advance / 64; + } +} + +static void +merge_text_16(XImage * xim, TT_Raster_Map * rmap, int offset_x, int offset_y, + unsigned long col) +{ + int x, y, tmp; + unsigned char *ptr; + unsigned char cr, cg, cb, a, r, g, b, nr, ng, nb; + unsigned long pixel; + + cr = (col >> 8) & 0xf8; + cg = (col >> 3) & 0xfc; + cb = (col << 3) & 0xf8; + for (y = 0; y < xim->height; y++) + { + ptr = (unsigned char *)rmap->bitmap + offset_x + ((y + offset_y) * rmap->cols); + for (x = 0; x < xim->width; x++) + { + if ((a = alpha_lut[*ptr]) > 0) + { + if (a < 255) + { + pixel = XGetPixel(xim, x, y); + r = (pixel >> 8) & 0xf8; + g = (pixel >> 3) & 0xfc; + b = (pixel << 3) & 0xf8; + + tmp = (cr - r) * a; + nr = r + ((tmp + (tmp >> 8) + 0x80) >> 8); + tmp = (cg - g) * a; + ng = g + ((tmp + (tmp >> 8) + 0x80) >> 8); + tmp = (cb - b) * a; + nb = b + ((tmp + (tmp >> 8) + 0x80) >> 8); + pixel = ((nr & 0xf8) << 8) | ((ng & 0xfc) << 3) | ((nb & 0xf8) >> 3); + XPutPixel(xim, x, y, pixel); + } + else + XPutPixel(xim, x, y, col); + } + ptr++; + } + } +} + +static void +merge_text_15(XImage * xim, TT_Raster_Map * rmap, int offset_x, int offset_y, + unsigned long col) +{ + int x, y, tmp; + unsigned char *ptr; + unsigned char cr, cg, cb, a, r, g, b, nr, ng, nb; + unsigned long pixel; + + cr = (col >> 7) & 0xf8; + cg = (col >> 2) & 0xf8; + cb = (col << 3) & 0xf8; + for (y = 0; y < xim->height; y++) + { + ptr = (unsigned char *)rmap->bitmap + offset_x + ((y + offset_y) * rmap->cols); + for (x = 0; x < xim->width; x++) + { + if ((a = alpha_lut[*ptr]) > 0) + { + if (a < 255) + { + pixel = XGetPixel(xim, x, y); + r = (pixel >> 7) & 0xf8; + g = (pixel >> 2) & 0xf8; + b = (pixel << 3) & 0xf8; + + tmp = (cr - r) * a; + nr = r + ((tmp + (tmp >> 8) + 0x80) >> 8); + tmp = (cg - g) * a; + ng = g + ((tmp + (tmp >> 8) + 0x80) >> 8); + tmp = (cb - b) * a; + nb = b + ((tmp + (tmp >> 8) + 0x80) >> 8); + pixel = ((nr & 0xf8) << 7) | ((ng & 0xf8) << 2) | ((nb & 0xf8) >> 3); + XPutPixel(xim, x, y, pixel); + } + else + XPutPixel(xim, x, y, col); + } + ptr++; + } + } +} + +static void +merge_text_24(XImage * xim, TT_Raster_Map * rmap, int offset_x, int offset_y, + unsigned long col) +{ + int x, y, tmp; + unsigned char *ptr; + unsigned char cr, cg, cb, a, r, g, b, nr, ng, nb; + unsigned long pixel; + + cr = (col >> 16) & 0xff; + cg = (col >> 8) & 0xff; + cb = col & 0xff; + for (y = 0; y < xim->height; y++) + { + ptr = (unsigned char *)rmap->bitmap + offset_x + ((y + offset_y) * rmap->cols); + for (x = 0; x < xim->width; x++) + { + if ((a = alpha_lut[*ptr]) > 0) + { + if (a < 255) + { + pixel = XGetPixel(xim, x, y); + r = (pixel >> 16) & 0xff; + g = (pixel >> 8) & 0xff; + b = pixel & 0xff; + + tmp = (cr - r) * a; + nr = r + ((tmp + (tmp >> 8) + 0x80) >> 8); + tmp = (cg - g) * a; + ng = g + ((tmp + (tmp >> 8) + 0x80) >> 8); + tmp = (cb - b) * a; + nb = b + ((tmp + (tmp >> 8) + 0x80) >> 8); + pixel = ((nr << 16) | (ng << 8) | (nb)); + XPutPixel(xim, x, y, pixel); + } + else + XPutPixel(xim, x, y, col); + } + ptr++; + } + } +} + +/* + * static void + * merge_text_8(XImage * xim, TT_Raster_Map * rmap, int offset_x, int offset_y, + * unsigned long col, Colormap cm) + * { + * int x, y, tmp; + * unsigned char *ptr; + * unsigned char a, r, g, b, nr, ng, nb; + * unsigned long pixel; + * + * for (y = 0; y < xim->height; y++) + * { + * ptr = (unsigned char *)rmap->bitmap + offset_x + ((y + offset_y) * rmap->cols); + * for (x = 0; x < xim->width; x++) + * { + * if ((a = alpha_lut[*ptr]) > 0) + * { + * pixel = XGetPixel(xim, x, y); + * r = (pixel >> 8) & 0xf8; + * g = (pixel >> 3) & 0xfc; + * b = (pixel << 3) & 0xf8; + * + * tmp = (255 - r) * a; + * nr = r + ((tmp + (tmp >> 8) + 0x80) >> 8); + * tmp = (255 - g) * a; + * ng = g + ((tmp + (tmp >> 8) + 0x80) >> 8); + * tmp = (255 - b) * a; + * nb = b + ((tmp + (tmp >> 8) + 0x80) >> 8); + * pixel = ((nr & 0xf8) << 8) | ((ng & 0xfc) << 3) | ((nb & 0xf8) >> 3); + * XPutPixel(xim, x, y, pixel); + * } + * ptr++; + * } + * } + * col = 0; + * cm = 0; + * } + */ + +static void +merge_text_1(XImage * xim, TT_Raster_Map * rmap, int offset_x, int offset_y, + unsigned long col) +{ + int x, y; + unsigned char *ptr; + + for (y = 0; y < xim->height; y++) + { + ptr = (unsigned char *)rmap->bitmap + offset_x + ((y + offset_y) * rmap->cols); + for (x = 0; x < xim->width; x++) + { + if (alpha_lut[*ptr] > 2) + XPutPixel(xim, x, y, col); + ptr++; + } + } +} + +static char x_error = 0; + +static void +handle_x_error(Display * d, XErrorEvent * ev) +{ + d = NULL; + ev = NULL; + x_error = 1; +} + +void +EFont_draw_string(Display * disp, Drawable win, GC gc, int x, int y, char *text, + Efont * font, Visual * vis, Colormap cm) +{ + XImage *xim; + XShmSegmentInfo shminfo; + int width, height, w, h, inx, iny, clipx, clipy, rx, ry; + XWindowAttributes xatt, ratt; + TT_Raster_Map *rmap, *rtmp; + unsigned long col; + XGCValues gcv; + static char shm_checked = 0, shm = 1; + XErrorHandler erh = NULL; + Window chld; + char is_pixmap = 0; + + inx = 0; + iny = 0; + rtmp = calc_size(font, &w, &h, text); + rmap = create_font_raster(w, h); + + render_text(rmap, rtmp, font, text, &inx, &iny); + + XGrabServer(disp); + erh = XSetErrorHandler((XErrorHandler) handle_x_error); + x_error = 0; + XGetWindowAttributes(disp, win, &xatt); + XFlush(disp); + if (x_error) + { + x_error = 0; + is_pixmap = 1; + XGetGeometry(disp, win, &chld, &rx, &rx, + (unsigned int *)&xatt.width, (unsigned int *)&xatt.height, + (unsigned int *)&rx, (unsigned int *)&xatt.depth); + XFlush(disp); + if (x_error) + { + destroy_font_raster(rmap); + destroy_font_raster(rtmp); + XUngrabServer(disp); + XFlush(disp); + XSetErrorHandler((XErrorHandler) erh); + return; + } + } + XSetErrorHandler((XErrorHandler) erh); + if (!is_pixmap) + { + XGetWindowAttributes(disp, xatt.root, &ratt); + XTranslateCoordinates(disp, win, xatt.root, 0, 0, &rx, &ry, &chld); + if ((xatt.map_state != IsViewable) && + (xatt.backing_store == NotUseful)) + { + destroy_font_raster(rmap); + destroy_font_raster(rtmp); + XUngrabServer(disp); + XFlush(disp); + return; + } + } + XGetGCValues(disp, gc, GCForeground, &gcv); + col = gcv.foreground; + + clipx = 0; + clipy = 0; + + x = x - inx; + y = y - iny; + + width = xatt.width - x; + height = xatt.height - y; + if (width > w) + width = w; + if (height > h) + height = h; + + if (!is_pixmap) + { + if ((rx + x + width) > ratt.width) + width = ratt.width - (rx + x); + if ((ry + y + height) > ratt.height) + height = ratt.height - (ry + y); + } + if (x < 0) + { + clipx = -x; + width += x; + x = 0; + } + if (y < 0) + { + clipy = -y; + height += y; + y = 0; + } + if (!is_pixmap) + { + if ((rx + x) < 0) + { + clipx -= (rx + x); + width += (rx + x); + x = -rx; + } + if ((ry + y) < 0) + { + clipy -= (ry + y); + height += (ry + y); + y = -ry; + } + } + if ((width <= 0) || (height <= 0)) + { + destroy_font_raster(rmap); + destroy_font_raster(rtmp); + XUngrabServer(disp); + XFlush(disp); + return; + } + if (shm) + { + if (!shm_checked) + { + erh = XSetErrorHandler((XErrorHandler) handle_x_error); + } + xim = XShmCreateImage(disp, vis, xatt.depth, ZPixmap, NULL, + &shminfo, width, height); + if (!shm_checked) + { + XSync(disp, False); + if (x_error) + { + shm = 0; + XDestroyImage(xim); + xim = XGetImage(disp, win, x, y, width, height, 0xffffffff, ZPixmap); + XSetErrorHandler((XErrorHandler) erh); + shm_checked = 1; + } + else + { + shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * + xim->height, IPC_CREAT | 0666); + if (shminfo.shmid < 0) + { + shm = 0; + XDestroyImage(xim); + xim = XGetImage(disp, win, x, y, width, height, 0xffffffff, ZPixmap); + XSetErrorHandler((XErrorHandler) erh); + shm_checked = 1; + } + else + { + shminfo.shmaddr = xim->data = shmat(shminfo.shmid, 0, 0); + shminfo.readOnly = False; + XShmAttach(disp, &shminfo); + } + } + } + else + { + shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * + xim->height, IPC_CREAT | 0666); + if (shminfo.shmid < 0) + { + shm = 0; + XDestroyImage(xim); + xim = XGetImage(disp, win, x, y, width, height, 0xffffffff, ZPixmap); + XSetErrorHandler((XErrorHandler) erh); + shm_checked = 1; + } + else + { + shminfo.shmaddr = xim->data = shmat(shminfo.shmid, 0, 0); + shminfo.readOnly = False; + XShmAttach(disp, &shminfo); + } + } + if (!shm_checked) + { + XSync(disp, False); + if (x_error) + { + shm = 0; + XDestroyImage(xim); + xim = XGetImage(disp, win, x, y, width, height, 0xffffffff, ZPixmap); + shm_checked = 1; + } + XSetErrorHandler((XErrorHandler) erh); + shm_checked = 1; + } + } + else + xim = XGetImage(disp, win, x, y, width, height, 0xffffffff, ZPixmap); + if (shm) + XShmGetImage(disp, win, xim, x, y, 0xffffffff); + XUngrabServer(disp); + XFlush(disp); + + if (xatt.depth == 16) + { + XVisualInfo xvi, *xvir; + int num; + + xvi.visualid = XVisualIDFromVisual(vis);; + xvir = XGetVisualInfo(disp, VisualIDMask, &xvi, &num); + if (xvir) + { + if (xvir->red_mask != 0xf800) + xatt.depth = 15; + XFree(xvir); + } + } + if (xatt.depth == 16) + merge_text_16(xim, rmap, clipx, clipy, col); + else if ((xatt.depth == 24) || (xatt.depth == 32)) + merge_text_24(xim, rmap, clipx, clipy, col); +/* else if (xatt.depth == 8) + * merge_text_8(xim, rmap, clipx, clipy, cm, col); */ + else if (xatt.depth == 15) + merge_text_15(xim, rmap, clipx, clipy, col); + else if (xatt.depth <= 8) + merge_text_1(xim, rmap, clipx, clipy, col); + + if (shm) + XShmPutImage(disp, win, gc, xim, 0, 0, x, y, + width, height, False); + else + XPutImage(disp, win, gc, xim, 0, 0, x, y, width, height); + destroy_font_raster(rmap); + destroy_font_raster(rtmp); + if (shm) + { + XSync(disp, False); + XShmDetach(disp, &shminfo); + shmdt(shminfo.shmaddr); + shmctl(shminfo.shmid, IPC_RMID, 0); + } + XDestroyImage(xim); + cm = 0; +} + +void +Efont_free(Efont * f) +{ + int i; + + if (!f) + return; + TT_Done_Instance(f->instance); + TT_Close_Face(f->face); + for (i = 0; i < 256; i++) + { + if (f->glyphs_cached[i]) + destroy_font_raster(f->glyphs_cached[i]); + if (!TT_VALID(f->glyphs[i])) + TT_Done_Glyph(f->glyphs[i]); + } + free(f->glyphs); + free(f->glyphs_cached); + free(f); +} + +Efont * +Efont_load(char *file, int size) +{ + TT_Error error; + TT_CharMap char_map; + TT_Glyph_Metrics metrics; + static TT_Engine engine; + static char have_engine = 0; + int dpi = 96; + Efont *f; + unsigned short i, n, code, load_flags; + unsigned short num_glyphs = 0, no_cmap = 0; + unsigned short platform, encoding; + + if (!have_engine) + { + error = TT_Init_FreeType(&engine); + if (error) + return NULL; + have_engine = 1; + } + f = malloc(sizeof(Efont)); + f->engine = engine; + error = TT_Open_Face(f->engine, file, &f->face); + if (error) + { + free(f); +/* fprintf(stderr, "Unable to open font\n"); */ + return NULL; + } + error = TT_Get_Face_Properties(f->face, &f->properties); + if (error) + { + TT_Close_Face(f->face); + free(f); +/* fprintf(stderr, "Unable to get face properties\n"); */ + return NULL; + } + error = TT_New_Instance(f->face, &f->instance); + if (error) + { + TT_Close_Face(f->face); + free(f); +/* fprintf(stderr, "Unable to create instance\n"); */ + return NULL; + } + TT_Set_Instance_Resolutions(f->instance, dpi, dpi); + TT_Set_Instance_CharSize(f->instance, size * 64); + + n = f->properties.num_CharMaps; + + for (i = 0; i < n; i++) + { + TT_Get_CharMap_ID(f->face, i, &platform, &encoding); + if ((platform == 3 && encoding == 1) || + (platform == 0 && encoding == 0)) + { + TT_Get_CharMap(f->face, i, &char_map); + break; + } + } + if (i == n) + { + no_cmap = 1; + num_glyphs = f->properties.num_Glyphs; + TT_Done_Instance(f->instance); + TT_Close_Face(f->face); + free(f); +/* fprintf(stderr, "Sorry, but this font doesn't contain any Unicode mapping table\n"); */ + return NULL; + } + f->num_glyph = 256; + f->glyphs = (TT_Glyph *) malloc(256 * sizeof(TT_Glyph)); + memset(f->glyphs, 0, 256 * sizeof(TT_Glyph)); + f->glyphs_cached = (TT_Raster_Map **) malloc(256 * sizeof(TT_Raster_Map *)); + memset(f->glyphs_cached, 0, 256 * sizeof(TT_Raster_Map *)); + + load_flags = TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH; + + f->max_descent = 0; + f->max_ascent = 0; + + for (i = 0; i < 256; ++i) + { + if (TT_VALID(f->glyphs[i])) + continue; + + if (no_cmap) + { + code = (i - ' ' + 1) < 0 ? 0 : (i - ' ' + 1); + if (code >= num_glyphs) + code = 0; + } + else + code = TT_Char_Index(char_map, i); + + TT_New_Glyph(f->face, &f->glyphs[i]); + TT_Load_Glyph(f->instance, f->glyphs[i], code, load_flags); + TT_Get_Glyph_Metrics(f->glyphs[i], &metrics); + + if ((metrics.bbox.yMin & -64) < f->max_descent) + f->max_descent = (metrics.bbox.yMin & -64); + if (((metrics.bbox.yMax + 63) & -64) > f->max_ascent) + f->max_ascent = ((metrics.bbox.yMax + 63) & -64); + } + return f; +} + +void +Efont_extents(Efont * f, char *text, int *font_ascent_return, + int *font_descent_return, int *width_return, + int *max_ascent_return, int *max_descent_return, + int *lbearing_return, int *rbearing_return) +{ + int i, upm, ascent, descent, pw; + TT_Instance_Metrics imetrics; + TT_Glyph_Metrics gmetrics; + + if (!f) + return; + + TT_Get_Instance_Metrics(f->instance, &imetrics); + upm = f->properties.header->Units_Per_EM; + ascent = (f->properties.horizontal->Ascender * imetrics.y_ppem) / upm; + descent = (f->properties.horizontal->Descender * imetrics.y_ppem) / upm; + if (ascent < 0) + ascent = -ascent; + if (descent < 0) + descent = -descent; + pw = 0; + + for (i = 0; text[i]; i++) + { + unsigned char j = text[i]; + + if (!TT_VALID(f->glyphs[j])) + continue; + TT_Get_Glyph_Metrics(f->glyphs[j], &gmetrics); + if (i == 0) + { + if (lbearing_return) + *lbearing_return = ((-gmetrics.bearingX) / 64); + } + if (text[i + 1] == 0) + { + if (rbearing_return) + *rbearing_return = ((gmetrics.bbox.xMax - gmetrics.advance) / 64); + } + pw += gmetrics.advance / 64; + } + if (font_ascent_return) + *font_ascent_return = ascent; + if (font_descent_return) + *font_descent_return = descent; + if (width_return) + *width_return = pw; + if (max_ascent_return) + *max_ascent_return = f->max_ascent; + if (max_descent_return) + *max_descent_return = f->max_descent; +} + +/* + * int + * main( int argc, char **argv) + * { + * Display *disp; + * Efont *f; + * GC gc; + * XGCValues gcv; + * Window win; + * int i; + * + * disp=XOpenDisplay(NULL); + * XSync(disp, False); + * srand(time(NULL)); + * win = XCreateSimpleWindow(disp, DefaultRootWindow(disp), 0, 0, 640, 480, 0, + * 0, 0); + * XMapWindow(disp, win); + * XSync(disp, False); + * + * gcv.subwindow_mode = IncludeInferiors; + * gc = XCreateGC(disp, win, GCSubwindowMode, &gcv); + * for (;;) + * { + * for (i = 3; i < argc; i++) + * { + * XSetForeground(disp, gc, rand()<<16 | rand()); + * f = Efont_load(argv[i], atoi(argv[1])); + * if (f) + * EFont_draw_string(disp, win, gc, 20, (atoi(argv[1])/10) * (i-2), argv[2], + * f, + * DefaultVisual(disp, DefaultScreen(disp)), + * DefaultColormap(disp, DefaultScreen(disp))); + * Efont_free(f); + * f = NULL; + * } + * } + * return 0; + * } + */ diff --git a/e.spec b/e.spec new file mode 100644 index 00000000..e17a90c0 --- /dev/null +++ b/e.spec @@ -0,0 +1,88 @@ +# Note that this is NOT a relocatable package +%define ver 0.16.devel.3 +%define rel 1 +%define prefix /usr + +Summary: The Enlightenment window manager. +Name: enlightenment +Version: %ver +Release: %rel +Copyright: GPL +Group: User Interface/Desktops +Source: ftp://www.rasterman.com/pub/enlightenment/enlightenment-%{ver}.tar.gz +BuildRoot: /tmp/e-%{ver}-root +Packager: The Rasterman +URL: http://www.rasterman.com/ +Requires: imlib >= 1.9 +Requires: fnlib >= 0.4 +Requires: freetype >= 1.1 +Requires: esound >= 0.2.7 + +Docdir: %{prefix}/doc + +%description +Enlightenment is a window manager for the X Window System that +is designed to be powerful, extensible, configurable and +pretty darned good looking! It is one of the more graphically +intense window managers. + +Enlightenment goes beyond managing windows by providing a useful +and appealing graphical shell from which to work. It is open +in design and instead of dictating a policy, allows the user to +define their own policy, down to every last detail. + +This package will install the Enlightenment window manager. + +%changelog + +%prep +%setup + +%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 --enable-fsstd +else + CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix --enable-fsstd +fi +make + +%install +rm -rf $RPM_BUILD_ROOT + +make prefix=$RPM_BUILD_ROOT%{prefix} install + +cd $RPM_BUILD_ROOT%{prefix}/ +chown -R 0.0 * + +%clean +rm -rf $RPM_BUILD_ROOT + +%post + +%postun + +%files +%defattr(-, root, root) + +%{prefix}/share/enlightenment/* +%{prefix}/bin/* + +%doc AUTHORS +%doc COPYING +%doc INSTALL +%doc README +%doc FAQ +%doc TODO diff --git a/eesh/.cvsignore b/eesh/.cvsignore new file mode 100644 index 00000000..c5441a78 --- /dev/null +++ b/eesh/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +eesh +.deps +*.da diff --git a/eesh/E.h b/eesh/E.h new file mode 100644 index 00000000..31d0e9a5 --- /dev/null +++ b/eesh/E.h @@ -0,0 +1,256 @@ +/*****************************************************************************/ +/* Enlightenment - The Window Manager that dares to do what others don't */ +/*****************************************************************************/ +/* Copyright (C) 1997 - 1999 Carsten Haitzler (The Rasterman) */ +/* */ +/* This program and utilites is free software; you can redistribute it */ +/* and/or modify it under the terms of the License shown in COPYING */ +/* */ +/* This software 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. */ +/*****************************************************************************/ + +#include "econfig.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "econfig.h" + +#ifndef ENLIGHTENMENT_ROOT +#define ENLIGHTENMENT_ROOT "/usr/local/enlightenment" +#endif +#define ENLIGHTENMENT_SYSTEM_CONFIG ENLIGHTENMENT_ROOT"/system_config" +#define ENLIGHTENMENT_SYSTEM_THEMES ENLIGHTENMENT_ROOT"/themes" +#define ENLIGHTENMENT_SYSTEM_BGS ENLIGHTENMENT_ROOT"/backgrounds" + +#define LIST_FINDBY_NAME 0 +#define LIST_FINDBY_ID 1 +#define LIST_FINDBY_BOTH 2 +#define LIST_FINDBY_NONE 3 + +#define LIST_TYPE_COUNT 18 +#define LIST_TYPE_ANY 0 +#define LIST_TYPE_CLIENT 1 + +typedef struct _list + { + int type; + char *name; + int id; + void *item; + + struct _list *next; + } +List; + +typedef struct _client + { + char *name; + Window win; + char *msg; + char *clientname; + char *version; + char *author; + char *email; + char *web; + char *address; + char *info; + Pixmap pmap; + } +Client; + +typedef struct _root + { + Window win; + Visual *vis; + int depth; + Colormap cmap; + int scr; + int w, h; + Window focuswin; + } +Root; + +int EExit(void *code); +void *Emalloc(int size); +void *Erealloc(void *ptr, int size); +void Efree(void *ptr); + +void *FindItem(char *name, int id, int find_by, int type); +void AddItem(void *item, char *name, int id, int type); +void *RemoveItem(char *name, int id, int find_by, int type); +void **ListItemType(int *num, int type); +char **ListItems(int *num, int type); +void **ListItemTypeID(int *num, int type, int id); + +void SetupX(void); + +void CommsSetup(void); +void CommsFindCommsWindow(void); +void CommsSend(Client * c, char *s); +char *CommsGet(Client ** c, XEvent * ev); +Client *MakeClient(Window win); +void ListFreeClient(void *ptr); +void DeleteClient(Client * c); +void HandleComms(XEvent * ev); + +#if defined(__FILE__) && defined(__LINE__) +#define Efree(x) \ +{ \ + if (x) \ + __Efree(x); \ + else \ + Alert("%s:%d: Attempt to free a NULL pointer\n", __FILE__, __LINE__); \ +} +#define Emalloc(x) \ +__Emalloc(x) +#define Erealloc(x, y) \ +__Erealloc(x, y) +#else +#define Efree(x) \ +{ \ + if (x) \ + __Efree(x); \ + else \ + Alert("??:??: Attempt to free a NULL pointer\n"); \ +} +#define Emalloc(x) \ +__Emalloc(x) +#define Erealloc(x, y) \ +__Erealloc(x, y) +#endif + +void *__Emalloc(int size); +void *__Erealloc(void *ptr, int size); +void __Efree(void *ptr); +char *duplicate(char *s); + +#define FILEPATH_LEN_MAX 4096 +/* This turns on E's internal stack tracking system for coarse debugging */ +/* and being able to trace E for profiling/optimisation purposes (which */ +/* believe it or not I'm actually doing) */ + +/* #define DEBUG 1 */ + +#ifdef DEBUG +extern int call_level; +extern int debug_level; + +#endif +#ifdef DEBUG +#define EDBUG(l,x) \ +{ \ + int i_call_level; \ + if (lwin; + ev.xclient.message_type = a; + ev.xclient.format = 8; + + for (i = 0; i < len + 1; i += 12) + { + sprintf(ss, "%8x", (int)my_win); + for (j = 0; j < 12; j++) + { + ss[8 + j] = s[i + j]; + if (!s[i + j]) + j = 12; + } + ss[20] = 0; + for (k = 0; k < 20; k++) + ev.xclient.data.b[k] = ss[k]; + XSendEvent(disp, c->win, False, 0, (XEvent *) & ev); + } + EDBUG_RETURN_; +} + +char * +CommsGet(Client ** c, XEvent * ev) +{ + char s[13], s2[9], *msg, st[32]; + int i; + Window win; + Client *cl; + + EDBUG(5, "CommsGet"); + if ((!ev) || (!c)) + EDBUG_RETURN(NULL); + if (ev->type != ClientMessage) + EDBUG_RETURN(NULL); + s[12] = 0; + s2[8] = 0; + msg = NULL; + for (i = 0; i < 8; i++) + s2[i] = ev->xclient.data.b[i]; + for (i = 0; i < 12; i++) + s[i] = ev->xclient.data.b[i + 8]; + sscanf(s2, "%x", (int *)&win); + cl = (Client *) FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_CLIENT); + if (!cl) + { + cl = MakeClient(win); + if (!cl) + EDBUG_RETURN(NULL); + sprintf(st, "%8x", (int)win); + cl->name = duplicate(st); + AddItem((void *)cl, st, cl->win, LIST_TYPE_CLIENT); + XSelectInput(disp, win, StructureNotifyMask | SubstructureNotifyMask); + } + if (cl->msg) + { + /* append text to end of msg */ + cl->msg = Erealloc(cl->msg, strlen(cl->msg) + strlen(s) + 1); + if (!cl->msg) + EDBUG_RETURN(NULL); + strcat(cl->msg, s); + } + else + { + /* new msg */ + cl->msg = Emalloc(strlen(s) + 1); + if (!cl->msg) + EDBUG_RETURN(NULL); + strcpy(cl->msg, s); + } + if (strlen(s) < 12) + { + msg = cl->msg; + cl->msg = NULL; + *c = cl; + } + EDBUG_RETURN(msg); +} + +Client * +MakeClient(Window win) +{ + Client *c; + + EDBUG(6, "MakeClient"); + c = Emalloc(sizeof(Client)); + if (!c) + EDBUG_RETURN(NULL); + c->name = NULL; + c->win = win; + c->msg = NULL; + c->clientname = NULL; + c->version = NULL; + c->author = NULL; + c->email = NULL; + c->web = NULL; + c->address = NULL; + c->info = NULL; + c->pmap = 0; + EDBUG_RETURN(c); +} + +void +ListFreeClient(void *ptr) +{ + Client *c; + + EDBUG(6, "ListFreeClient"); + c = (Client *) ptr; + if (!c) + EDBUG_RETURN_; + if (c->name) + Efree(c->name); + if (c->msg) + Efree(c->msg); + if (c->clientname) + Efree(c->clientname); + if (c->version) + Efree(c->version); + if (c->author) + Efree(c->author); + if (c->email) + Efree(c->email); + if (c->web) + Efree(c->web); + if (c->address) + Efree(c->address); + if (c->info) + Efree(c->info); + Efree(c); + EDBUG_RETURN_; +} + +void +DeleteClient(Client * c) +{ + Client *cc; + + EDBUG(6, "DeleteClient"); + cc = RemoveItem(NULL, c->win, LIST_FINDBY_ID, LIST_TYPE_CLIENT); + ListFreeClient(cc); + EDBUG_RETURN_; +} + +void +HandleComms(XEvent * ev) +{ + Client *c; + char *s; + + EDBUG(4, "HandleComms"); + s = CommsGet(&c, ev); + if (!s) + EDBUG_RETURN_; + printf("%s\n", s); + fflush(stdout); + if (waitonly) + exit(0); + Efree(s); + EDBUG_RETURN_; +} diff --git a/eesh/file.c b/eesh/file.c new file mode 100644 index 00000000..a7649133 --- /dev/null +++ b/eesh/file.c @@ -0,0 +1,642 @@ +#include "E.h" + +void +md(char *s) +{ + EDBUG(9, "md"); + if ((!s) || (!*s)) + EDBUG_RETURN_; + mkdir(s, S_IRWXU); + EDBUG_RETURN_; +} + +int +exists(char *s) +{ + struct stat st; + + EDBUG(9, "exists"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (stat(s, &st) < 0) + EDBUG_RETURN(0); + EDBUG_RETURN(1); +} + +void +mkdirs(char *s) +{ + char ss[FILEPATH_LEN_MAX]; + int i, ii; + + i = 0; + ii = 0; + while (s[i]) + { + ss[ii++] = s[i]; + ss[ii] = 0; + if (s[i] == '/') + { + if (!exists(ss)) + md(ss); + else if (!isdir(ss)) + return; + } + i++; + } +} + +int +isfile(char *s) +{ + struct stat st; + + EDBUG(9, "isfile"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (stat(s, &st) < 0) + EDBUG_RETURN(0); + if (S_ISREG(st.st_mode)) + EDBUG_RETURN(1); + EDBUG_RETURN(0); +} + +int +isdir(char *s) +{ + struct stat st; + + EDBUG(9, "isdir"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (stat(s, &st) < 0) + EDBUG_RETURN(0); + if (S_ISDIR(st.st_mode)) + EDBUG_RETURN(1); + EDBUG_RETURN(0); +} + +char ** +ls(char *dir, int *num) +{ + int i, dirlen; + int done = 0; + DIR *dirp; + char **names; + struct dirent *dp; + + EDBUG(9, "ls"); + if ((!dir) || (!*dir)) + EDBUG_RETURN(0); + dirp = opendir(dir); + if (!dirp) + { + *num = 0; + EDBUG_RETURN(NULL); + } + /* count # of entries in dir (worst case) */ + for (dirlen = 0; (dp = readdir(dirp)) != NULL; dirlen++); + if (!dirlen) + { + closedir(dirp); + *num = dirlen; + EDBUG_RETURN(NULL); + } + /* load up the entries, now that we know how many to make */ + names = (char **)Emalloc(dirlen * sizeof(char *)); + + if (!names) + EDBUG_RETURN(NULL); + + rewinddir(dirp); + for (i = 0; i < dirlen;) + { + dp = readdir(dirp); + if (!dp) + break; + names[i] = (char *)Emalloc(strlen(dp->d_name) + 1); + if (!names) + EDBUG_RETURN(NULL); + strcpy(names[i], dp->d_name); + i++; + } + + if (i < dirlen) + dirlen = i; /* dir got shorter... */ + closedir(dirp); + *num = dirlen; + /* do a simple bubble sort here to alphanumberic it */ + while (!done) + { + done = 1; + for (i = 0; i < dirlen - 2; i++) + { + if (strcmp(names[i], names[i + 1]) < 0) + { + char *temp; + + temp = names[i]; + names[i] = names[i + 1]; + names[i + 1] = temp; + done = 0; + } + } + } + EDBUG_RETURN(names); +} + +void +freestrlist(char **l, int num) +{ + EDBUG(9, "freestrlist"); + if (!l) + EDBUG_RETURN_; + while (num--) + if (l[num]) + Efree(l[num]); + Efree(l); + EDBUG_RETURN_; +} + +void +rm(char *s) +{ + EDBUG(9, "rm"); + if ((!s) || (!*s)) + EDBUG_RETURN_; + unlink(s); + EDBUG_RETURN_; +} + +void +mv(char *s, char *ss) +{ + EDBUG(9, "mv"); + if ((!s) || (!ss) || (!*s) || (!*ss)) + EDBUG_RETURN_; + rename(s, ss); + EDBUG_RETURN_; +} + +void +cp(char *s, char *ss) +{ + int i; + FILE *f, *ff; + unsigned char buf[1]; + + EDBUG(9, "cp"); + if ((!s) || (!ss) || (!*s) || (!*ss)) + EDBUG_RETURN_; + if (!exists(s)) + EDBUG_RETURN_; + i = filesize(s); + f = fopen(s, "r"); + if (!f) + EDBUG_RETURN_; + ff = fopen(ss, "w"); + if (!ff) + { + fclose(f); + EDBUG_RETURN_; + } + while (fread(buf, 1, 1, f)) + fwrite(buf, 1, 1, ff); + fclose(f); + fclose(ff); + EDBUG_RETURN_; +} + +time_t +moddate(char *s) +{ + struct stat st; + + EDBUG(9, "moddate"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (!stat(s, &st) < 0) + EDBUG_RETURN(0); + if (st.st_mtime > st.st_ctime) + { + EDBUG_RETURN(st.st_mtime); + } + else + EDBUG_RETURN(st.st_ctime); + EDBUG_RETURN(0); +} + +int +filesize(char *s) +{ + struct stat st; + + EDBUG(9, "filesize"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (stat(s, &st) < 0) + EDBUG_RETURN(0); + EDBUG_RETURN((int)st.st_size); +} + +void +cd(char *s) +{ + EDBUG(9, "cd"); + if ((!s) || (!*s)) + EDBUG_RETURN_; + chdir(s); + EDBUG_RETURN_; +} + +char * +cwd(void) +{ + char *s; + char ss[FILEPATH_LEN_MAX]; + + EDBUG(9, "cwd"); + getcwd(ss, FILEPATH_LEN_MAX); + s = duplicate(ss); + EDBUG_RETURN(s); +} + +int +permissions(char *s) +{ + struct stat st; + + EDBUG(9, "permissions"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (!stat(s, &st) < 0) + EDBUG_RETURN(0); + EDBUG_RETURN(st.st_mode); +} + +int +owner(char *s) +{ + struct stat st; + + EDBUG(9, "owner"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (!stat(s, &st) < 0) + EDBUG_RETURN(0); + EDBUG_RETURN(st.st_uid); +} + +int +group(char *s) +{ + struct stat st; + + EDBUG(9, "group"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (!stat(s, &st) < 0) + EDBUG_RETURN(0); + EDBUG_RETURN(st.st_gid); +} + +char * +username(int uid) +{ + char *s; + struct passwd *pwd; + + EDBUG(9, "username"); + pwd = getpwuid(uid); + if (pwd) + { + s = duplicate(pwd->pw_name); +/* Efree(pwd); */ + EDBUG_RETURN(s); + } + EDBUG_RETURN(duplicate("unknown")); +} + +char * +homedir(int uid) +{ + char *s; + struct passwd *pwd; + + EDBUG(9, "homedir"); + pwd = getpwuid(uid); + if (pwd) + { + s = duplicate(pwd->pw_dir); +/* Efree(pwd); */ + EDBUG_RETURN(s); + } + EDBUG_RETURN(duplicate("/tmp")); +} + +char * +usershell(int uid) +{ + char *s; + struct passwd *pwd; + + EDBUG(9, "usershell"); + pwd = getpwuid(uid); + if (pwd) + { + s = duplicate(pwd->pw_shell); +/* Efree(pwd); */ + EDBUG_RETURN(s); + } + EDBUG_RETURN(duplicate("/bin/sh")); +} + +char * +atword(char *s, int num) +{ + int cnt, i; + + EDBUG(9, "atword"); + if (!s) + EDBUG_RETURN(NULL); + cnt = 0; + i = 0; + + while (s[i]) + { + if ((s[i] != ' ') && (s[i] != '\t')) + { + if (i == 0) + cnt++; + else if ((s[i - 1] == ' ') || (s[i - 1] == '\t')) + cnt++; + if (cnt == num) + EDBUG_RETURN(&s[i]); + } + i++; + } + EDBUG_RETURN(NULL); +} + +char * +atchar(char *s, char c) +{ + int i; + + EDBUG(9, "atchar"); + if (!s) + EDBUG_RETURN(NULL); + i = 0; + while (s[i] != 0) + { + if (s[i] == c) + EDBUG_RETURN(&s[i]); + i++; + } + EDBUG_RETURN(NULL); +} + +void +word(char *s, int num, char *wd) +{ + int cnt, i; + char *start, *finish, *ss, *w; + + EDBUG(9, "word"); + if (!s) + EDBUG_RETURN_; + if (!wd) + EDBUG_RETURN_; + if (num <= 0) + { + *wd = 0; + EDBUG_RETURN_; + } + cnt = 0; + i = 0; + start = NULL; + finish = NULL; + ss = NULL; + w = wd; + + while (s[i]) + { + if ((cnt == num) && ((s[i] == ' ') || (s[i] == '\t'))) + { + finish = &s[i]; + break; + } + if ((s[i] != ' ') && (s[i] != '\t')) + { + if (i == 0) + { + cnt++; + if (cnt == num) + start = &s[i]; + } + else if ((s[i - 1] == ' ') || (s[i - 1] == '\t')) + { + cnt++; + if (cnt == num) + start = &s[i]; + } + } + i++; + } + if (cnt == num) + { + if ((start) && (finish)) + { + for (ss = start; ss < finish; ss++) + *wd++ = *ss; + } + else if (start) + { + for (ss = start; *ss != 0; ss++) + *wd++ = *ss; + } + *wd = 0; + } + EDBUG_RETURN_; +} + +int +canread(char *s) +{ + EDBUG(9, "canread"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + EDBUG_RETURN(1 + access(s, R_OK)); +} + +int +canwrite(char *s) +{ + EDBUG(9, "canwrite"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + EDBUG_RETURN(1 + access(s, W_OK)); +} + +int +canexec(char *s) +{ + EDBUG(9, "canexec"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + EDBUG_RETURN(1 + access(s, X_OK)); +} + +char * +fileof(char *s) +{ + char ss[1024]; + int i, p1, p2; + + EDBUG(9, "fileof"); + i = 0; + p1 = -1; + p2 = -1; + for (i = strlen(s) - 1; i >= 0; i--) + { + if ((s[i] == '.') && (p2 < 0) && (p1 < 0)) + p2 = i; + if ((s[i] == '/') && (p1 < 0)) + p1 = i; + } + if (p2 < 0) + p2 = strlen(s); + if (p1 < 0) + p1 = 0; + for (i = 0; i < (p2 - p1 - 1); i++) + ss[i] = s[p1 + 1 + i]; + ss[i] = 0; + EDBUG_RETURN(duplicate(ss)); +} + +char * +fullfileof(char *s) +{ + char ss[1024]; + int i, p1, p2; + + EDBUG(9, "fullfileof"); + i = 0; + p1 = -1; + for (i = strlen(s) - 1; i >= 0; i--) + { + if ((s[i] == '/') && (p1 < 0)) + p1 = i; + } + p2 = strlen(s); + for (i = 0; i < (p2 - p1 - 1); i++) + ss[i] = s[p1 + 1 + i]; + ss[i] = 0; + EDBUG_RETURN(duplicate(ss)); +} + +char * +pathtoexec(char *file) +{ + char *p, *cp, *ep; + char *s; + int len, exelen; + + EDBUG(9, "pathtoexec"); + if (file[0] == '/') + { + if (canexec(file)) + EDBUG_RETURN(duplicate(file)); + } + p = getenv("PATH"); + if (!p) + EDBUG_RETURN(duplicate(file)); + if (!file) + EDBUG_RETURN(NULL); + cp = p; + exelen = strlen(file); + while ((ep = strchr(cp, ':'))) + { + len = ep - cp; + s = Emalloc(len + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = 0; + s = Erealloc(s, len + 2 + exelen); + strcat(s, "/"); + strcat(s, file); + if (canexec(s)) + EDBUG_RETURN(s); + Efree(s); + } + cp = ep + 1; + } + len = strlen(cp); + s = Emalloc(len + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = 0; + s = Erealloc(s, len + 2 + exelen); + strcat(s, "/"); + strcat(s, file); + if (canexec(s)) + EDBUG_RETURN(s); + Efree(s); + } + EDBUG_RETURN(NULL); +} + +char * +pathtofile(char *file) +{ + char *p, *cp, *ep; + char *s; + int len, exelen; + + EDBUG(9, "pathtofile"); + if (file[0] == '/') + { + if (exists(file)) + EDBUG_RETURN(duplicate(file)); + } + p = getenv("PATH"); + if (!p) + EDBUG_RETURN(duplicate(file)); + if (!file) + EDBUG_RETURN(NULL); + cp = p; + exelen = strlen(file); + while ((ep = strchr(cp, ':'))) + { + len = ep - cp; + s = Emalloc(len + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = 0; + s = Erealloc(s, len + 2 + exelen); + strcat(s, "/"); + strcat(s, file); + if (exists(s)) + EDBUG_RETURN(s); + Efree(s); + } + cp = ep + 1; + } + len = strlen(cp); + s = Emalloc(len + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = 0; + s = Erealloc(s, len + 2 + exelen); + strcat(s, "/"); + strcat(s, file); + if (exists(s)) + EDBUG_RETURN(s); + Efree(s); + } + EDBUG_RETURN(NULL); +} diff --git a/eesh/globals.c b/eesh/globals.c new file mode 100644 index 00000000..f38e15bd --- /dev/null +++ b/eesh/globals.c @@ -0,0 +1,7 @@ +#include "E.h" + +Display *disp; +List lists; +Window comms_win; +Window my_win; +Root root; diff --git a/eesh/lists.c b/eesh/lists.c new file mode 100644 index 00000000..136569f3 --- /dev/null +++ b/eesh/lists.c @@ -0,0 +1,290 @@ + +#include "E.h" + +void * +FindItem(char *name, int id, int find_by, int type) +{ + List *ptr; + + EDBUG(6, "FindItem"); + ptr = lists.next; + if (find_by == LIST_FINDBY_NAME) + { + while (ptr) + { + if ((ptr->type == type) && (!strcmp(name, ptr->name))) + EDBUG_RETURN(ptr->item); + ptr = ptr->next; + } + } + else if (find_by == LIST_FINDBY_ID) + { + while (ptr) + { + if ((ptr->type == type) && (ptr->id == id)) + EDBUG_RETURN(ptr->item); + ptr = ptr->next; + } + } + else if (find_by == LIST_FINDBY_BOTH) + { + while (ptr) + { + if ((ptr->type == type) && (!strcmp(name, ptr->name)) && (ptr->id == id)) + EDBUG_RETURN(ptr->item); + ptr = ptr->next; + } + } + else if (find_by == LIST_FINDBY_NONE) + { + while (ptr) + { + if ((ptr->type == type)) + EDBUG_RETURN(ptr->item); + ptr = ptr->next; + } + } + EDBUG_RETURN(NULL); +} + +void +AddItem(void *item, char *name, int id, int type) +{ + List *ptr; + + EDBUG(6, "AddItem"); + ptr = Emalloc(sizeof(List)); + if (!ptr) + EDBUG_RETURN_; + ptr->item = item; + ptr->name = duplicate(name); + ptr->id = id; + ptr->type = type; + ptr->next = lists.next; + lists.next = ptr; + EDBUG_RETURN_; +} + +void * +RemoveItem(char *name, int id, int find_by, int type) +{ + List *ptr, *pptr; + void *p; + + EDBUG(6, "RemoveItem"); + pptr = NULL; + ptr = lists.next; + if (find_by == LIST_FINDBY_NAME) + { + while (ptr) + { + if ((ptr->type == type) && (!strcmp(name, ptr->name))) + { + if (pptr) + pptr->next = ptr->next; + else + lists.next = ptr->next; + p = ptr->item; + if (ptr->name) + Efree(ptr->name); + Efree(ptr); + EDBUG_RETURN(p); + } + pptr = ptr; + ptr = ptr->next; + } + } + else if (find_by == LIST_FINDBY_ID) + { + while (ptr) + { + if ((ptr->type == type) && (ptr->id == id)) + { + if (pptr) + pptr->next = ptr->next; + else + lists.next = ptr->next; + p = ptr->item; + if (ptr->name) + Efree(ptr->name); + Efree(ptr); + EDBUG_RETURN(p); + } + pptr = ptr; + ptr = ptr->next; + } + } + else if (find_by == LIST_FINDBY_BOTH) + { + while (ptr) + { + if ((ptr->type == type) && (!strcmp(name, ptr->name)) && (ptr->id == id)) + { + if (pptr) + pptr->next = ptr->next; + else + lists.next = ptr->next; + p = ptr->item; + if (ptr->name) + Efree(ptr->name); + Efree(ptr); + EDBUG_RETURN(p); + } + pptr = ptr; + ptr = ptr->next; + } + } + else if (find_by == LIST_FINDBY_NONE) + { + while (ptr) + { + if ((ptr->type == type)) + { + if (pptr) + pptr->next = ptr->next; + else + lists.next = ptr->next; + p = ptr->item; + if (ptr->name) + Efree(ptr->name); + Efree(ptr); + EDBUG_RETURN(p); + } + pptr = ptr; + ptr = ptr->next; + } + } + EDBUG_RETURN(NULL); +} + +void ** +ListItemType(int *num, int type) +{ + List *ptr; + int i, len; + void **lst; + + EDBUG(6, "ListItemType"); + *num = 0; + len = 0; + if (type == LIST_TYPE_ANY) + EDBUG_RETURN(NULL); + ptr = lists.next; + while (ptr) + { + if (ptr->type == type) + len++; + ptr = ptr->next; + } + if (!len) + EDBUG_RETURN(NULL); + lst = Emalloc(len * sizeof(void *)); + + i = 0; + ptr = lists.next; + while (ptr) + { + if (ptr->type == type) + lst[i++] = ptr->item; + ptr = ptr->next; + } + *num = i; + EDBUG_RETURN(lst); +} + +char ** +ListItems(int *num, int type) +{ + List *ptr; + int i, len; + char **list; + + EDBUG(7, "ListItems"); + i = 0; + len = 0; + list = NULL; + ptr = lists.next; + if (type != LIST_TYPE_ANY) + { + while (ptr) + { + if (ptr->type == type) + len++; + ptr = ptr->next; + } + } + else + { + while (ptr) + { + len++; + ptr = ptr->next; + } + } + list = Emalloc(len * sizeof(char *)); + + if (!list) + { + *num = 0; + EDBUG_RETURN(NULL); + } + ptr = lists.next; + if (type != LIST_TYPE_ANY) + { + while (ptr) + { + if (ptr->type == type) + { + list[i] = duplicate(ptr->name); + i++; + } + ptr = ptr->next; + } + } + else + { + while (ptr) + { + list[i] = duplicate(ptr->name); + i++; + ptr = ptr->next; + } + } + *num = len; + EDBUG_RETURN(list); +} + +void ** +ListItemTypeID(int *num, int type, int id) +{ + List *ptr; + int i, len; + void **lst; + + EDBUG(6, "ListItemType"); + *num = 0; + len = 0; + if (type == LIST_TYPE_ANY) + EDBUG_RETURN(NULL); + ptr = lists.next; + while (ptr) + { + if ((ptr->type == type) && (ptr->id == id)) + len++; + ptr = ptr->next; + } + if (!len) + EDBUG_RETURN(NULL); + lst = Emalloc(len * sizeof(void *)); + + i = 0; + ptr = lists.next; + while (ptr) + { + if ((ptr->type == type) && (ptr->id == id)) + lst[i++] = ptr->item; + ptr = ptr->next; + } + *num = i; + EDBUG_RETURN(lst); +} diff --git a/eesh/main.c b/eesh/main.c new file mode 100644 index 00000000..c0d4d8a2 --- /dev/null +++ b/eesh/main.c @@ -0,0 +1,130 @@ +#include "E.h" +#include +#include +#include + +extern char waitonly; + +int +main(int argc, char **argv) +{ + XEvent ev; + Client *me, *e; + char buf[10240]; + int i, j, k; + fd_set fd; + char ret; + + waitonly = 0; + lists.next = NULL; + SetupX(); + CommsSetup(); + CommsFindCommsWindow(); + XSelectInput(disp, comms_win, StructureNotifyMask); + XSelectInput(disp, root.win, PropertyChangeMask); + e = MakeClient(comms_win); + AddItem(e, "E", e->win, LIST_TYPE_CLIENT); + me = MakeClient(my_win); + AddItem(me, "ME", me->win, LIST_TYPE_CLIENT); + CommsSend(e, "set clientname eesh"); + CommsSend(e, "set version 0.1"); + CommsSend(e, "set author The Rasterman"); + CommsSend(e, "set email raster@rasterman.com"); + CommsSend(e, "set web http://www.enlightenment.org"); +/* CommsSend(e, "set address NONE"); */ + CommsSend(e, "set info Enlightenment IPC Shell - talk to E direct"); +/* CommsSend(e, "set pixmap 0"); */ + + for (i = 0; i < argc; i++) + { + if (!strcmp(argv[i], "-e")) + { + if (i != (argc - 1)) + { + CommsSend(e, argv[++i]); + XSync(disp, False); + exit(0); + } + } + else if (!strcmp(argv[i], "-ewait")) + { + waitonly = 1; + if (i != (argc - 1)) + CommsSend(e, argv[++i]); + } + else if ((!strcmp(argv[i], "-h")) || + (!strcmp(argv[i], "--h")) || + (!strcmp(argv[i], "-help")) || + (!strcmp(argv[i], "--help"))) + { + printf("%s [ -e \"Command to Send to Enlightenment then exit\"]\n" + " [ -ewait \"Command to Send to E then wait for a reply then exit\"]\n", + argv[0]); + printf("Use \"%s\" by itself to enter the \"interactive mode\"\n" + "Ctrl-D will exit interactive mode (EOF)\n" + "use \"help\" from inside interactive mode for further " + "assistance\n", argv[0]); + exit(0); + } + } + + XSync(disp, False); + j = 0; + fcntl(0, F_SETFL, O_NONBLOCK); + for (;;) + { + if (waitonly) + { + XNextEvent(disp, &ev); + if (ev.type == ClientMessage) + HandleComms(&ev); + else if (ev.type == DestroyNotify) + exit(0); + XSync(disp, False); + } + else + { + FD_ZERO(&fd); + FD_SET(0, &fd); + FD_SET(ConnectionNumber(disp), &fd); + if (select(ConnectionNumber(disp) + 1, &fd, NULL, NULL, NULL) < 0) + exit(0); + XSync(disp, False); + + if (FD_ISSET(0, &fd)) + { + k = 0; + while ((ret = read(0, &(buf[j]), 1) > 0)) + { + k = 1; + if (buf[j] == '\n') + { + buf[j] = 0; + if (strlen(buf) > 0) + { + CommsSend(e, buf); + XSync(disp, False); + } + j = -1; + } + j++; + } + if ((ret < 0) || ((k == 0) && (ret == 0))) + exit(0); + } + else if (FD_ISSET(ConnectionNumber(disp), &fd)) + { + while (XPending(disp)) + { + XNextEvent(disp, &ev); + if (ev.type == ClientMessage) + HandleComms(&ev); + else if (ev.type == DestroyNotify) + exit(0); + } + XSync(disp, False); + } + } + } + return 0; +} diff --git a/eesh/memory.c b/eesh/memory.c new file mode 100644 index 00000000..d5c76c73 --- /dev/null +++ b/eesh/memory.c @@ -0,0 +1,145 @@ +#include "E.h" + +/*#define DBUG_MEM 1 */ + +#ifdef DBUG_MEM +#define POINTERS_SIZE 10240 +static unsigned int num_pointers = 0; +static void *pointers_ptr[POINTERS_SIZE]; +static unsigned int pointers_size[POINTERS_SIZE]; + +#endif + +void +EDisplayMemUse() +{ +#ifdef DBUG_MEM + int i, min, max, sum; + + max = 0; + min = 0x7ffffff; + sum = 0; + for (i = 0; i < num_pointers; i++) + { + sum += pointers_size[i]; + if (pointers_size[i] < min) + min = pointers_size[i]; + if (pointers_size[i] > max) + max = pointers_size[i]; + } + if (num_pointers > 0) + { + fprintf(stderr, "Num:%6i Sum:%8i Av:%8i Min:%8i Max%6i\n", + num_pointers, sum, sum / num_pointers, min, max); + } +#endif +} + +void * +__Emalloc(int size) +{ + void *p; + + EDBUG(9, "Emalloc"); + p = malloc(size); + if (!p) + Alert("Warning! malloc for %i bytes failed \n ", size); +#ifdef DBUG_MEM + if (p) + { + num_pointers++; + pointers_ptr[num_pointers - 1] = p; + pointers_size[num_pointers - 1] = size; + } +#endif + EDBUG_RETURN(p); +} + +void * +__Erealloc(void *ptr, int size) +{ + void *p; + +#ifdef DBUG_MEM + char bad = 0; + +#endif + + EDBUG(9, "Erealloc"); + p = realloc(ptr, size); + if (!p) + Alert("Warning! realloc for %i bytes failed\n", size); +#ifdef DBUG_MEM + if (p) + { + int i; + + bad = 1; + for (i = 0; i < num_pointers; i++) + { + if (pointers_ptr[i] == ptr) + { + pointers_size[i] = size; + pointers_ptr[i] = p; + bad = 0; + i = num_pointers; + } + } + } + if (bad) + Alert("WARNING!\n Attempt to free memory that hasn't been allocated.\n"); +#endif + EDBUG_RETURN(p); +} + +void +__Efree(void *ptr) +{ +#ifdef DBUG_MEM + char bad = 0; + +#endif + EDBUG(9, "Efree"); + free(ptr); +#ifdef DBUG_MEM + { + int i, j; + + bad = 1; + for (i = 0; i < num_pointers; i++) + { + if (pointers_ptr[i] == ptr) + { + for (j = i; j < num_pointers - 1; j++) + { + pointers_ptr[j] = pointers_ptr[j + 1]; + } + bad = 0; + i = num_pointers; + num_pointers--; + break; + } + } + } +#endif +#ifdef DBUG_MEM + if (bad) + Alert("WARNING!\n Attempt to free memory that hasn't been allocated.\n"); +#endif + EDBUG_RETURN_; +} + +char * +duplicate(char *s) +{ + char *ss; + int sz; + + EDBUG(9, "duplicate"); + if (!s) + EDBUG_RETURN(NULL); + sz = strlen(s); + ss = Emalloc(sz + 1); + strncpy(ss, s, sz + 1); + EDBUG_RETURN(ss); +} diff --git a/eesh/setup.c b/eesh/setup.c new file mode 100644 index 00000000..b208e2e7 --- /dev/null +++ b/eesh/setup.c @@ -0,0 +1,50 @@ +#include "E.h" + +void +SetupX() +{ + EDBUG(6, "SetupX"); + /* Open a connection to the diplay nominated by the DISPLAY variable */ + disp = XOpenDisplay(NULL); + /* if cannot connect to display */ + if (!disp) + { + Alert("Eesh cannot connect to the display nominated by\n" + "your shell's DISPLAY environment variable. You may set this\n" + "variable to indicate which display name Enlightenment is to\n" + "connect to. It may be that you do not have an Xserver already\n" + "running to serve that Display connection, or that you do not\n" + "have permission to connect to that display. Please make sure\n" + "all is correct before trying again. Run an Xserver by running\n" + "xdm or startx first, or contact your local system\n" + "administrator, or Xserver vendor, or read the X, xdm and\n" + "startx manual pages before proceeding.\n"); + exit(1); + } + + root.win = DefaultRootWindow(disp); + root.scr = DefaultScreen(disp); + root.w = DisplayWidth(disp, root.scr); + root.h = DisplayHeight(disp, root.scr); + + /* warn, if necessary about lack fo multi-head support */ + if (ScreenCount(disp) > 1) + { + Alert("WARNING:\n" + "Your Xserver supports a multi-headed configuration with\n" + "multiple screens attached to the one display. Enlightenment\n" + "does not currently support multi-headed setups, and as a\n" + "result will only manage the first screen (this one).\n"); + } + /* warn, if necessary about X version problems */ + if (ProtocolVersion(disp) != 11) + { + Alert("WARNING:\n" + "This is not an X11 Xserver. It infact talks the X%i protocol.\n" + "This may mean Enlightenment will either not function, or\n" + "function incorrectly. If it is later than X11, then your\n" + "server is one the author(s) of Enlightenment neither have\n" + "access to, nor have heard of.\n", ProtocolVersion(disp)); + } + EDBUG_RETURN_; +} diff --git a/eesh/timestamp.h b/eesh/timestamp.h new file mode 100644 index 00000000..e69de29b diff --git a/epp/.cvsignore b/epp/.cvsignore new file mode 100644 index 00000000..21490c51 --- /dev/null +++ b/epp/.cvsignore @@ -0,0 +1,5 @@ +Makefile.in +Makefile +.deps +epp +*.da diff --git a/epp/ChangeLog b/epp/ChangeLog new file mode 100644 index 00000000..0bbb3c00 --- /dev/null +++ b/epp/ChangeLog @@ -0,0 +1,44 @@ +Sat Jul 10 17:43:10 PDT 1999 +(Mandrake) + +I'm on a warning crushing mission. damn you, llane. Well, I've STARTED to +clean this up. I don't know where all this code came from, but I'll be damned +if I'm going to let this haunt me for the rest of my days because E has some +crappily written code in it. + +------------------------------------------------------------------------------- + +Sat Jul 10 18:49:30 PDT 1999 +(Mandrake) + +down to 155 warnings from like 300-400. Closer, at least. +*sigh* + +------------------------------------------------------------------------------- + +Sat Jul 10 22:07:59 PDT 1999 +(Mandrake) + +Down to 103 warnings to remove. + +------------------------------------------------------------------------------- + +Sun Jul 11 10:08:58 PDT 1999 +(Mandrake) + +Down to ~60 warnings. + +------------------------------------------------------------------------------- + +Sun Jul 11 11:05:39 PDT 1999 +(Mandrake) + +Down to 28 warnings. This is beginning to drive me batty. we'll deal with +this later. + +------------------------------------------------------------------------------- + +Sun Jul 11 11:56:55 PDT 1999 +(Mandrake) + +Forget that last commit message. tagged and bagged all of them. diff --git a/epp/Makefile.am b/epp/Makefile.am new file mode 100644 index 00000000..562f1ea3 --- /dev/null +++ b/epp/Makefile.am @@ -0,0 +1,75 @@ +# Makefile for GNU C compiler. +# Copyright (C) 1987, 88, 90-94, 1995 Free Software Foundation, Inc. + +#This file is part of GNU CC. + +#GNU CC 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, or (at your option) +#any later version. + +#GNU CC 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 GNU CC; see the file COPYING. If not, write to +#the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +if FSSTD +bindir = @bindir@ +else +bindir=$(prefix)/enlightenment/bin +endif + +bin_PROGRAMS = epp + +epp_SOURCES = \ + cpplib.h \ + cpphash.h \ + header.h \ + config.h \ + cppalloc.c \ + cpperror.c \ + cppexp.c \ + cpphash.c \ + cpplib.c \ + cppmain.c + +INCLUDES=-I$(top_srcdir) -I$(top_builddir) -I$(includedir) + +DEFS= \ +-DHAVE_STRERROR \ +-DFATAL_EXIT_CODE=1 \ +-DSUCCESS_EXIT_CODE=1 \ +-DGCC_INCLUDE_DIR=\"/usr/include\" \ +-DGPLUSPLUS_INCLUDE_DIR=\"/usr/include\" \ +-DTOOL_INCLUDE_DIR=\"/usr/bin\" \ +-DHOST_BITS_PER_LONG=32 \ +-DBITS_PER_UNIT=8 \ +-DHOST_BITS_PER_INT=32 \ +-DBITS_PER_WORD=16 \ +-DTARGET_BELL=7 \ +-DTARGET_BS=8 \ +-DTARGET_FF=12 \ +-DTARGET_NEWLINE=10 \ +-DTARGET_CR=13 \ +-DTARGET_TAB=9 \ +-DTARGET_VT=11 + +LIBS = + +#install-exec-local: +# if [ x@USE_FSSTD@ = "xno" ]; then \ +# ../mkinstalldirs $(exec_prefix)/bin; \ +# for i in $(bin_PROGRAMS); do \ +# rm -f $(exec_prefix)/bin/$$i; \ +# $(LN_S) $(bindir)/$$i $(exec_prefix)/bin/$$i; \ +# done; \ +# fi + +uninstall-local: + for i in $(bin_PROGRAMS); do \ + rm -f $(exec_prefix)/bin/$$i; \ + done diff --git a/epp/config.h b/epp/config.h new file mode 100644 index 00000000..e69de29b diff --git a/epp/cppalloc.c b/epp/cppalloc.c new file mode 100644 index 00000000..dfd812d1 --- /dev/null +++ b/epp/cppalloc.c @@ -0,0 +1,69 @@ +/* Part of CPP library. (memory allocation - xmalloc etc) + * Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. + * Written by Per Bothner, 1994. + * Based on CCCP program by by Paul Rubin, June 1986 + * Adapted to ANSI C, Richard Stallman, Jan 1987 + * + * 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! */ + +#include "config.h" +#include +#include "header.h" + +static void +memory_full() +{ + fatal("Memory exhausted."); +} + +void * +xmalloc(size) + unsigned size; +{ + register char *ptr = (char *)malloc(size); + + if (ptr != 0) + return (ptr); + memory_full(); + /*NOTREACHED */ + return 0; +} + +void * +xrealloc(old, size) + void *old; + unsigned size; +{ + register char *ptr = (char *)realloc(old, size); + + if (ptr == 0) + memory_full(); + return ptr; +} + +void * +xcalloc(number, size) + unsigned number, size; +{ + register char *ptr = (char *)calloc(number, size); + + if (ptr == 0) + memory_full(); + return ptr; +} diff --git a/epp/cpperror.c b/epp/cpperror.c new file mode 100644 index 00000000..171f1044 --- /dev/null +++ b/epp/cpperror.c @@ -0,0 +1,129 @@ +/* Default error handlers for CPP Library. + * Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. + * Written by Per Bothner, 1994. + * Based on CCCP program by by Paul Rubin, June 1986 + * Adapted to ANSI C, Richard Stallman, Jan 1987 + * + * 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! */ + +#include +#include "header.h" + +/* Print the file names and line numbers of the #include + * commands which led to the current file. */ + +void fatal(char *str, char *arg); + +void +cpp_print_containing_files(pfile) + cpp_reader *pfile; +{ + cpp_buffer *ip; + int first = 1; + + /* If stack of files hasn't changed since we last printed + * this info, don't repeat it. */ + if (pfile->input_stack_listing_current) + return; + + ip = cpp_file_buffer(pfile); + + /* Give up if we don't find a source file. */ + if (ip == NULL) + return; + + /* Find the other, outer source files. */ + while ((ip = CPP_PREV_BUFFER(ip)), ip != CPP_NULL_BUFFER(pfile)) + { + long line, col; + + cpp_buf_line_and_col(ip, &line, &col); + if (ip->fname != NULL) + { + if (first) + { + first = 0; + fprintf(stderr, "In file included"); + } + else + fprintf(stderr, ",\n "); + } + } + if (!first) + fprintf(stderr, ":\n"); + + /* Record we have printed the status as of this time. */ + pfile->input_stack_listing_current = 1; +} + +void +cpp_file_line_for_message(pfile, filename, line, column) + cpp_reader *pfile; + char *filename; + int line, column; +{ + pfile = NULL; + if (column > 0) + { + fprintf(stderr, "%s:%d:%d: ", filename, line, column); + } + else + { + fprintf(stderr, "%s:%d: ", filename, line); + } +} + +/* IS_ERROR is 1 for error, 0 for warning */ +void +cpp_message(pfile, is_error, msg, arg1, arg2, arg3) + int is_error; + cpp_reader *pfile; + char *msg; + char *arg1, *arg2, *arg3; +{ + if (is_error) + pfile->errors++; + else + fprintf(stderr, "warning: "); + fprintf(stderr, msg, arg1, arg2, arg3); + fprintf(stderr, "\n"); +} + +void +fatal(str, arg) + char *str, *arg; +{ + fprintf(stderr, "%s: ", progname); + fprintf(stderr, str, arg); + fprintf(stderr, "\n"); + exit(FATAL_EXIT_CODE); +} + +void +cpp_pfatal_with_name(pfile, name) + cpp_reader *pfile; + char *name; +{ + cpp_perror_with_name(pfile, name); +#ifdef VMS + exit(vaxc$errno); +#else + exit(FATAL_EXIT_CODE); +#endif +} diff --git a/epp/cppexp.c b/epp/cppexp.c new file mode 100644 index 00000000..e5cb6a8b --- /dev/null +++ b/epp/cppexp.c @@ -0,0 +1,1092 @@ + +/* Parse C expressions for CCCP. + * Copyright (C) 1987, 1992, 1994, 1995 Free Software Foundation. + * + * 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! + * + * Written by Per Bothner 1994. */ + +/* Parse a C expression from text in a string */ + +#include "config.h" +#include "header.h" + +#ifdef MULTIBYTE_CHARS +#include +#endif + +#include +#include +#include + +/* This is used for communicating lists of keywords with cccp.c. */ +struct arglist + { + struct arglist *next; + U_CHAR *name; + int length; + int argno; + }; + +/* Define a generic NULL if one hasn't already been defined. */ + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef GENERIC_PTR +#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) +#define GENERIC_PTR void * +#else +#define GENERIC_PTR char * +#endif +#endif + +#ifndef NULL_PTR +#define NULL_PTR ((GENERIC_PTR)0) +#endif + +#ifndef CHAR_TYPE_SIZE +#define CHAR_TYPE_SIZE BITS_PER_UNIT +#endif + +#ifndef INT_TYPE_SIZE +#define INT_TYPE_SIZE BITS_PER_WORD +#endif + +#ifndef LONG_TYPE_SIZE +#define LONG_TYPE_SIZE BITS_PER_WORD +#endif + +#ifndef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE INT_TYPE_SIZE +#endif + +#ifndef MAX_CHAR_TYPE_SIZE +#define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE +#endif + +#ifndef MAX_INT_TYPE_SIZE +#define MAX_INT_TYPE_SIZE INT_TYPE_SIZE +#endif + +#ifndef MAX_LONG_TYPE_SIZE +#define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE +#endif + +#ifndef MAX_WCHAR_TYPE_SIZE +#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE +#endif + +/* Yield nonzero if adding two numbers with A's and B's signs can yield a + * number with SUM's sign, where A, B, and SUM are all C integers. */ +#define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0) + +static void integer_overflow(); +static long left_shift(); +static long right_shift(); + +#define ERROR 299 +#define OROR 300 +#define ANDAND 301 +#define EQUAL 302 +#define NOTEQUAL 303 +#define LEQ 304 +#define GEQ 305 +#define LSH 306 +#define RSH 307 +#define NAME 308 +#define INT 309 +#define CHAR 310 + +#define LEFT_OPERAND_REQUIRED 1 +#define RIGHT_OPERAND_REQUIRED 2 +#define HAVE_VALUE 4 +/* SKIP_OPERAND is set for '&&' '||' '?' and ':' when the + * following operand should be short-circuited instead of evaluated. */ +#define SKIP_OPERAND 8 +/*#define UNSIGNEDP 16 */ + +struct operation + { + short op; + char rprio; /* Priority of op (relative to it right operand). */ + char flags; + char unsignedp; /* true if value should be treated as unsigned */ + HOST_WIDE_INT value; /* The value logically "right" of op. */ + }; + +/* Take care of parsing a number (anything that starts with a digit). + * LEN is the number of characters in it. */ + +/* maybe needs to actually deal with floating point numbers */ + +struct operation +parse_number(pfile, start, olen) + cpp_reader *pfile; + char *start; + int olen; +{ + struct operation op; + register char *p = start; + register int c; + register unsigned long n = 0, nd, ULONG_MAX_over_base; + register int base = 10; + register int len = olen; + register int overflow = 0; + register int digit, largest_digit = 0; + int spec_long = 0; + + op.unsignedp = 0; + + for (c = 0; c < len; c++) + if (p[c] == '.') + { + /* It's a float since it contains a point. */ + cpp_error(pfile, + "floating point numbers not allowed in #if expressions"); + op.op = ERROR; + return op; + } + if (len >= 3 && (!strncmp(p, "0x", 2) || !strncmp(p, "0X", 2))) + { + p += 2; + base = 16; + len -= 2; + } + else if (*p == '0') + base = 8; + + /* Some buggy compilers (e.g. MPW C) seem to need both casts. */ + ULONG_MAX_over_base = ((unsigned long)-1) / ((unsigned long)base); + + for (; len > 0; len--) + { + c = *p++; + + if (c >= '0' && c <= '9') + digit = c - '0'; + else if (base == 16 && c >= 'a' && c <= 'f') + digit = c - 'a' + 10; + else if (base == 16 && c >= 'A' && c <= 'F') + digit = c - 'A' + 10; + else + { + /* `l' means long, and `u' means unsigned. */ + while (1) + { + if (c == 'l' || c == 'L') + { + if (spec_long) + cpp_error(pfile, "two `l's in integer constant"); + spec_long = 1; + } + else if (c == 'u' || c == 'U') + { + if (op.unsignedp) + cpp_error(pfile, "two `u's in integer constant"); + op.unsignedp = 1; + } + else + break; + + if (--len == 0) + break; + c = *p++; + } + /* Don't look for any more digits after the suffixes. */ + break; + } + if (largest_digit < digit) + largest_digit = digit; + nd = n * base + digit; + overflow |= (ULONG_MAX_over_base < n) | (nd < n); + n = nd; + } + + if (len != 0) + { + cpp_error(pfile, "Invalid number in #if expression"); + op.op = ERROR; + return op; + } + if (base <= largest_digit) + cpp_warning(pfile, "integer constant contains digits beyond the radix"); + + if (overflow) + cpp_warning(pfile, "integer constant out of range"); + + /* If too big to be signed, consider it unsigned. */ + if ((long)n < 0 && !op.unsignedp) + { + if (base == 10) + cpp_warning(pfile, "integer constant is so large that it is unsigned"); + op.unsignedp = 1; + } + op.value = n; + op.op = INT; + return op; +} + +struct token +{ + char *operator; + int token; +}; + +static struct token tokentab2[] = +{ + {"&&", ANDAND}, + {"||", OROR}, + {"<<", LSH}, + {">>", RSH}, + {"==", EQUAL}, + {"!=", NOTEQUAL}, + {"<=", LEQ}, + {">=", GEQ}, + {"++", ERROR}, + {"--", ERROR}, + {NULL, ERROR} +}; + +/* Read one token. */ + +struct operation +cpp_lex(pfile) + cpp_reader *pfile; +{ + register int c; + register struct token *toktab; + enum cpp_token token; + struct operation op; + U_CHAR *tok_start, *tok_end; + int old_written; + + retry: + + old_written = CPP_WRITTEN(pfile); + cpp_skip_hspace(pfile); + c = CPP_BUF_PEEK(CPP_BUFFER(pfile)); + if (c == '#') + return parse_number(pfile, + cpp_read_check_assertion(pfile) ? "1" : "0", 1); + + if (c == '\n') + { + op.op = 0; + return op; + } + token = cpp_get_token(pfile); + tok_start = pfile->token_buffer + old_written; + tok_end = CPP_PWRITTEN(pfile); + pfile->limit = tok_start; + switch (token) + { + case CPP_EOF: /* Should not happen ... */ + op.op = 0; + return op; + case CPP_VSPACE: + case CPP_POP: + if (CPP_BUFFER(pfile)->fname != NULL) + { + op.op = 0; + return op; + } + goto retry; + case CPP_HSPACE: + case CPP_COMMENT: + goto retry; + case CPP_NUMBER: + return parse_number(pfile, tok_start, tok_end - tok_start); + case CPP_STRING: + cpp_error(pfile, "string constants not allowed in #if expressions"); + op.op = ERROR; + return op; + case CPP_CHAR: + /* This code for reading a character constant + * handles multicharacter constants and wide characters. + * It is mostly copied from c-lex.c. */ + { + register int result = 0; + register int num_chars = 0; + unsigned width = MAX_CHAR_TYPE_SIZE; + int wide_flag = 0; + int max_chars; + U_CHAR *ptr = tok_start; + +#ifdef MULTIBYTE_CHARS + char token_buffer[MAX_LONG_TYPE_SIZE / MAX_CHAR_TYPE_SIZE + MB_CUR_MAX]; + +#else + char token_buffer[MAX_LONG_TYPE_SIZE / MAX_CHAR_TYPE_SIZE + 1]; + +#endif + + if (*ptr == 'L') + { + ptr++; + wide_flag = 1; + width = MAX_WCHAR_TYPE_SIZE; +#ifdef MULTIBYTE_CHARS + max_chars = MB_CUR_MAX; +#else + max_chars = 1; +#endif + } + else + max_chars = MAX_LONG_TYPE_SIZE / width; + + while (1) + { + if (ptr >= CPP_PWRITTEN(pfile) || (c = *ptr++) == '\'') + break; + + if (c == '\\') + { + c = cpp_parse_escape(pfile, (char **)&ptr); + if (width < HOST_BITS_PER_INT + && (unsigned)c >= (unsigned)(1 << width)) + cpp_pedwarn(pfile, + "escape sequence out of range for character"); + } + num_chars++; + + /* Merge character into result; ignore excess chars. */ + if (num_chars < max_chars + 1) + { + if (width < HOST_BITS_PER_INT) + result = (result << width) | (c & ((1 << width) - 1)); + else + result = c; + token_buffer[num_chars - 1] = c; + } + } + + token_buffer[num_chars] = 0; + + if (c != '\'') + cpp_error(pfile, "malformatted character constant"); + else if (num_chars == 0) + cpp_error(pfile, "empty character constant"); + else if (num_chars > max_chars) + { + num_chars = max_chars; + cpp_error(pfile, "character constant too long"); + } + else if (num_chars != 1 && !CPP_TRADITIONAL(pfile)) + cpp_warning(pfile, "multi-character character constant"); + + /* If char type is signed, sign-extend the constant. */ + if (!wide_flag) + { + int num_bits = num_chars * width; + + if (cpp_lookup(pfile, "__CHAR_UNSIGNED__", + sizeof("__CHAR_UNSIGNED__") - 1, -1) + || ((result >> (num_bits - 1)) & 1) == 0) + op.value + = result & ((unsigned long)~0 >> (HOST_BITS_PER_LONG - num_bits)); + else + op.value + = result | ~((unsigned long)~0 >> (HOST_BITS_PER_LONG - num_bits)); + } + else + { +#ifdef MULTIBYTE_CHARS + /* Set the initial shift state and convert the next sequence. */ + result = 0; + /* In all locales L'\0' is zero and mbtowc will return zero, + * so don't use it. */ + if (num_chars > 1 + || (num_chars == 1 && token_buffer[0] != '\0')) + { + wchar_t wc; + + (void)mbtowc(NULL_PTR, NULL_PTR, 0); + if (mbtowc(&wc, token_buffer, num_chars) == num_chars) + result = wc; + else + cpp_warning(pfile, "Ignoring invalid multibyte character"); + } +#endif + op.value = result; + } + } + + /* This is always a signed type. */ + op.unsignedp = 0; + op.op = CHAR; + + return op; + + case CPP_NAME: + return parse_number(pfile, "0", 0); + + case CPP_OTHER: + /* See if it is a special token of length 2. */ + if (tok_start + 2 == tok_end) + { + for (toktab = tokentab2; toktab->operator != NULL; toktab++) + if (tok_start[0] == toktab->operator[0] + && tok_start[1] == toktab->operator[1]) + break; + if (toktab->token == ERROR) + { + char *buf = (char *)malloc(40); + + memset(buf, 0, 40); + + sprintf(buf, "`%s' not allowed in operand of `#if'", tok_start); + cpp_error(pfile, buf); + free(buf); + } + op.op = toktab->token; + return op; + } + /* fall through */ + default: + op.op = *tok_start; + return op; + } +} + +/* Parse a C escape sequence. STRING_PTR points to a variable + * containing a pointer to the string to parse. That pointer + * is updated past the characters we use. The value of the + * escape sequence is returned. + * + * A negative value means the sequence \ newline was seen, + * which is supposed to be equivalent to nothing at all. + * + * If \ is followed by a null character, we return a negative + * value and leave the string pointer pointing at the null character. + * + * If \ is followed by 000, we return 0 and leave the string pointer + * after the zeros. A value of 0 does not mean end of string. */ + +int +cpp_parse_escape(pfile, string_ptr) + cpp_reader *pfile; + char **string_ptr; +{ + register int c = *(*string_ptr)++; + + switch (c) + { + case 'a': + return TARGET_BELL; + case 'b': + return TARGET_BS; + case 'e': + case 'E': + if (CPP_PEDANTIC(pfile)) + cpp_pedwarn(pfile, "non-ANSI-standard escape sequence, `\\%c'", c); + return 033; + case 'f': + return TARGET_FF; + case 'n': + return TARGET_NEWLINE; + case 'r': + return TARGET_CR; + case 't': + return TARGET_TAB; + case 'v': + return TARGET_VT; + case '\n': + return -2; + case 0: + (*string_ptr)--; + return 0; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + register int i = c - '0'; + register int count = 0; + + while (++count < 3) + { + c = *(*string_ptr)++; + if (c >= '0' && c <= '7') + i = (i << 3) + c - '0'; + else + { + (*string_ptr)--; + break; + } + } + if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0) + { + i &= (1 << MAX_CHAR_TYPE_SIZE) - 1; + cpp_warning(pfile, + "octal character constant does not fit in a byte"); + } + return i; + } + case 'x': + { + register unsigned i = 0, overflow = 0, digits_found = 0, digit; + + for (;;) + { + c = *(*string_ptr)++; + if (c >= '0' && c <= '9') + digit = c - '0'; + else if (c >= 'a' && c <= 'f') + digit = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + digit = c - 'A' + 10; + else + { + (*string_ptr)--; + break; + } + overflow |= i ^ (i << 4 >> 4); + i = (i << 4) + digit; + digits_found = 1; + } + if (!digits_found) + cpp_error(pfile, "\\x used with no following hex digits"); + if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1))) + { + i &= (1 << BITS_PER_UNIT) - 1; + cpp_warning(pfile, + "hex character constant does not fit in a byte"); + } + return i; + } + default: + return c; + } +} + +static void +integer_overflow(pfile) + cpp_reader *pfile; +{ + if (CPP_PEDANTIC(pfile)) + cpp_pedwarn(pfile, "integer overflow in preprocessor expression"); +} + +static long +left_shift(pfile, a, unsignedp, b) + cpp_reader *pfile; + long a; + int unsignedp; + unsigned long b; +{ + if (b >= HOST_BITS_PER_LONG) + { + if (!unsignedp && a != 0) + integer_overflow(pfile); + return 0; + } + else if (unsignedp) + return (unsigned long)a << b; + else + { + long l = a << b; + + if (l >> b != a) + integer_overflow(pfile); + return l; + } +} + +static long +right_shift(pfile, a, unsignedp, b) + cpp_reader *pfile; + long a; + int unsignedp; + unsigned long b; +{ + pfile = NULL; + if (b >= HOST_BITS_PER_LONG) + { + return unsignedp ? 0 : a >> (HOST_BITS_PER_LONG - 1); + } + else if (unsignedp) + { + return (unsigned long)a >> b; + } + else + { + return a >> b; + } +} + +/* These priorities are all even, so we can handle associatively. */ +#define PAREN_INNER_PRIO 0 +#define COMMA_PRIO 4 +#define COND_PRIO (COMMA_PRIO+2) +#define OROR_PRIO (COND_PRIO+2) +#define ANDAND_PRIO (OROR_PRIO+2) +#define OR_PRIO (ANDAND_PRIO+2) +#define XOR_PRIO (OR_PRIO+2) +#define AND_PRIO (XOR_PRIO+2) +#define EQUAL_PRIO (AND_PRIO+2) +#define LESS_PRIO (EQUAL_PRIO+2) +#define SHIFT_PRIO (LESS_PRIO+2) +#define PLUS_PRIO (SHIFT_PRIO+2) +#define MUL_PRIO (PLUS_PRIO+2) +#define UNARY_PRIO (MUL_PRIO+2) +#define PAREN_OUTER_PRIO (UNARY_PRIO+2) + +#define COMPARE(OP) \ + top->unsignedp = 0;\ + top->value = (unsigned1 || unsigned2) ? (unsigned long) v1 OP (unsigned long) v2 : (v1 OP v2) + +/* Parse and evaluate a C expression, reading from PFILE. + * Returns the value of the expression. */ + +HOST_WIDE_INT +cpp_parse_expr(pfile) + cpp_reader *pfile; +{ + /* The implementation is an operator precedence parser, + * i.e. a bottom-up parser, using a stack for not-yet-reduced tokens. + * + * The stack base is 'stack', and the current stack pointer is 'top'. + * There is a stack element for each operator (only), + * and the most recently pushed operator is 'top->op'. + * An operand (value) is stored in the 'value' field of the stack + * element of the operator that precedes it. + * In that case the 'flags' field has the HAVE_VALUE flag set. */ + +#define INIT_STACK_SIZE 20 + struct operation init_stack[INIT_STACK_SIZE]; + struct operation *stack = init_stack; + struct operation *limit = stack + INIT_STACK_SIZE; + register struct operation *top = stack; + int lprio = 0, rprio = 0; + int skip_evaluation = 0; + + top->rprio = 0; + top->flags = 0; + for (;;) + { + struct operation op; + char flags = 0; + + /* Read a token */ + op = cpp_lex(pfile); + + /* See if the token is an operand, in which case go to set_value. + * If the token is an operator, figure out its left and right + * priorities, and then goto maybe_reduce. */ + + switch (op.op) + { + case NAME: + top->value = 0, top->unsignedp = 0; + goto set_value; + case INT: + case CHAR: + top->value = op.value; + top->unsignedp = op.unsignedp; + goto set_value; + case 0: + lprio = 0; + goto maybe_reduce; + case '+': + case '-': + /* Is this correct if unary ? FIXME */ + flags = RIGHT_OPERAND_REQUIRED; + lprio = PLUS_PRIO; + rprio = lprio + 1; + goto maybe_reduce; + case '!': + case '~': + flags = RIGHT_OPERAND_REQUIRED; + rprio = UNARY_PRIO; + lprio = rprio + 1; + goto maybe_reduce; + case '*': + case '/': + case '%': + lprio = MUL_PRIO; + goto binop; + case '<': + case '>': + case LEQ: + case GEQ: + lprio = LESS_PRIO; + goto binop; + case EQUAL: + case NOTEQUAL: + lprio = EQUAL_PRIO; + goto binop; + case LSH: + case RSH: + lprio = SHIFT_PRIO; + goto binop; + case '&': + lprio = AND_PRIO; + goto binop; + case '^': + lprio = XOR_PRIO; + goto binop; + case '|': + lprio = OR_PRIO; + goto binop; + case ANDAND: + lprio = ANDAND_PRIO; + goto binop; + case OROR: + lprio = OROR_PRIO; + goto binop; + case ',': + lprio = COMMA_PRIO; + goto binop; + case '(': + lprio = PAREN_OUTER_PRIO; + rprio = PAREN_INNER_PRIO; + goto maybe_reduce; + case ')': + lprio = PAREN_INNER_PRIO; + rprio = PAREN_OUTER_PRIO; + goto maybe_reduce; + case ':': + lprio = COND_PRIO; + rprio = COND_PRIO; + goto maybe_reduce; + case '?': + lprio = COND_PRIO + 1; + rprio = COND_PRIO; + goto maybe_reduce; + binop: + flags = LEFT_OPERAND_REQUIRED | RIGHT_OPERAND_REQUIRED; + rprio = lprio + 1; + goto maybe_reduce; + default: + cpp_error(pfile, "invalid character in #if"); + goto syntax_error; + } + + set_value: + /* Push a value onto the stack. */ + if (top->flags & HAVE_VALUE) + { + cpp_error(pfile, "syntax error in #if"); + goto syntax_error; + } + top->flags |= HAVE_VALUE; + continue; + + maybe_reduce: + /* Push an operator, and check if we can reduce now. */ + while (top->rprio > lprio) + { + long v1 = top[-1].value, v2 = top[0].value; + int unsigned1 = top[-1].unsignedp, unsigned2 = top[0].unsignedp; + + top--; + if ((top[1].flags & LEFT_OPERAND_REQUIRED) + && !(top[0].flags & HAVE_VALUE)) + { + cpp_error(pfile, "syntax error - missing left operand"); + goto syntax_error; + } + if ((top[1].flags & RIGHT_OPERAND_REQUIRED) + && !(top[1].flags & HAVE_VALUE)) + { + cpp_error(pfile, "syntax error - missing right operand"); + goto syntax_error; + } + /* top[0].value = (top[1].op)(v1, v2); */ + switch (top[1].op) + { + case '+': + if (!(top->flags & HAVE_VALUE)) + { /* Unary '+' */ + top->value = v2; + top->unsignedp = unsigned2; + top->flags |= HAVE_VALUE; + } + else + { + top->value = v1 + v2; + top->unsignedp = unsigned1 || unsigned2; + if (!top->unsignedp && !skip_evaluation + && !possible_sum_sign(v1, v2, top->value)) + integer_overflow(pfile); + } + break; + case '-': + if (skip_evaluation); /* do nothing */ + else if (!(top->flags & HAVE_VALUE)) + { /* Unary '-' */ + top->value = -v2; + if ((top->value & v2) < 0 && !unsigned2) + integer_overflow(pfile); + top->unsignedp = unsigned2; + top->flags |= HAVE_VALUE; + } + else + { /* Binary '-' */ + top->value = v1 - v2; + top->unsignedp = unsigned1 || unsigned2; + if (!top->unsignedp + && !possible_sum_sign(top->value, v2, v1)) + integer_overflow(pfile); + } + break; + case '*': + top->unsignedp = unsigned1 || unsigned2; + if (top->unsignedp) + top->value = (unsigned long)v1 *v2; + + else if (!skip_evaluation) + { + top->value = v1 * v2; + if (v1 + && (top->value / v1 != v2 + || (top->value & v1 & v2) < 0)) + integer_overflow(pfile); + } + break; + case '/': + if (skip_evaluation) + break; + if (v2 == 0) + { + cpp_error(pfile, "division by zero in #if"); + v2 = 1; + } + top->unsignedp = unsigned1 || unsigned2; + if (top->unsignedp) + top->value = (unsigned long)v1 / v2; + else + { + top->value = v1 / v2; + if ((top->value & v1 & v2) < 0) + integer_overflow(pfile); + } + break; + case '%': + if (skip_evaluation) + break; + if (v2 == 0) + { + cpp_error(pfile, "division by zero in #if"); + v2 = 1; + } + top->unsignedp = unsigned1 || unsigned2; + if (top->unsignedp) + top->value = (unsigned long)v1 % v2; + else + top->value = v1 % v2; + break; + case '!': + if (top->flags & HAVE_VALUE) + { + cpp_error(pfile, "syntax error"); + goto syntax_error; + } + top->value = !v2; + top->unsignedp = 0; + top->flags |= HAVE_VALUE; + break; + case '~': + if (top->flags & HAVE_VALUE) + { + cpp_error(pfile, "syntax error"); + goto syntax_error; + } + top->value = ~v2; + top->unsignedp = unsigned2; + top->flags |= HAVE_VALUE; + break; + case '<': + COMPARE(<); + break; + case '>': + COMPARE(>); + break; + case LEQ: + COMPARE(<=); + break; + case GEQ: + COMPARE(>=); + break; + case EQUAL: + top->value = (v1 == v2); + top->unsignedp = 0; + break; + case NOTEQUAL: + top->value = (v1 != v2); + top->unsignedp = 0; + break; + case LSH: + if (skip_evaluation) + break; + top->unsignedp = unsigned1; + if (v2 < 0 && !unsigned2) + top->value = right_shift(pfile, v1, unsigned1, -v2); + else + top->value = left_shift(pfile, v1, unsigned1, v2); + break; + case RSH: + if (skip_evaluation) + break; + top->unsignedp = unsigned1; + if (v2 < 0 && !unsigned2) + top->value = left_shift(pfile, v1, unsigned1, -v2); + else + top->value = right_shift(pfile, v1, unsigned1, v2); + break; +#define LOGICAL(OP) \ + top->value = v1 OP v2;\ + top->unsignedp = unsigned1 || unsigned2; + case '&': + LOGICAL(&); + break; + case '^': + LOGICAL(^); + break; + case '|': + LOGICAL(|); + break; + case ANDAND: + top->value = v1 && v2; + top->unsignedp = 0; + if (!v1) + skip_evaluation--; + break; + case OROR: + top->value = v1 || v2; + top->unsignedp = 0; + if (v1) + skip_evaluation--; + break; + case ',': + if (CPP_PEDANTIC(pfile)) + cpp_pedwarn(pfile, "comma operator in operand of `#if'"); + top->value = v2; + top->unsignedp = unsigned2; + break; + case '(': + case '?': + cpp_error(pfile, "syntax error in #if"); + goto syntax_error; + case ':': + if (top[0].op != '?') + { + cpp_error(pfile, + "syntax error ':' without preceding '?'"); + goto syntax_error; + } + else if (!(top[1].flags & HAVE_VALUE) + || !(top[-1].flags & HAVE_VALUE) + || !(top[0].flags & HAVE_VALUE)) + { + cpp_error(pfile, "bad syntax for ?: operator"); + goto syntax_error; + } + else + { + top--; + if (top->value) + skip_evaluation--; + top->value = top->value ? v1 : v2; + top->unsignedp = unsigned1 || unsigned2; + } + break; + case ')': + if ((top[1].flags & HAVE_VALUE) + || !(top[0].flags & HAVE_VALUE) + || top[0].op != '(' + || (top[-1].flags & HAVE_VALUE)) + { + cpp_error(pfile, "mismatched parentheses in #if"); + goto syntax_error; + } + else + { + top--; + top->value = v1; + top->unsignedp = unsigned1; + top->flags |= HAVE_VALUE; + } + break; + default: + fprintf(stderr, + top[1].op >= ' ' && top[1].op <= '~' + ? "unimplemented operator '%c'\n" + : "unimplemented operator '\\%03o'\n", + top[1].op); + } + } + if (op.op == 0) + { + if (top != stack) + cpp_error(pfile, "internal error in #if expression"); + if (stack != init_stack) + free(stack); + return top->value; + } + top++; + + /* Check for and handle stack overflow. */ + if (top == limit) + { + struct operation *new_stack; + int old_size = (char *)limit - (char *)stack; + int new_size = 2 * old_size; + + if (stack != init_stack) + new_stack = (struct operation *)xrealloc(stack, new_size); + else + { + new_stack = (struct operation *)xmalloc(new_size); + bcopy((char *)stack, (char *)new_stack, old_size); + } + stack = new_stack; + top = (struct operation *)((char *)new_stack + old_size); + limit = (struct operation *)((char *)new_stack + new_size); + } + top->flags = flags; + top->rprio = rprio; + top->op = op.op; + if ((op.op == OROR && top[-1].value) + || (op.op == ANDAND && !top[-1].value) + || (op.op == '?' && !top[-1].value)) + { + skip_evaluation++; + } + else if (op.op == ':') + { + if (top[-2].value) /* Was condition true? */ + skip_evaluation++; + else + skip_evaluation--; + } + } + syntax_error: + if (stack != init_stack) + free(stack); + skip_rest_of_line(pfile); + return 0; +} diff --git a/epp/cpphash.c b/epp/cpphash.c new file mode 100644 index 00000000..ca1b3101 --- /dev/null +++ b/epp/cpphash.c @@ -0,0 +1,224 @@ +/* Part of CPP library. (Macro hash table support.) + * Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. + * Written by Per Bothner, 1994. + * Based on CCCP program by by Paul Rubin, June 1986 + * Adapted to ANSI C, Richard Stallman, Jan 1987 + * + * 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! */ + +#include "header.h" +#include "cpphash.h" + +static HASHNODE *hashtab[HASHSIZE]; +HASHNODE *cpp_lookup(struct parse_file *pfile, const U_CHAR * name, int len, + int hash); +void delete_macro(HASHNODE * hp); +HASHNODE *install(U_CHAR * name, int len, enum node_type type, int ivalue, + char *value, int hash); + +/* Define a generic NULL if one hasn't already been defined. */ + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef __STDC__ +#define const +#define volatile +#endif + +#include +#include + +/* + * return hash function on name. must be compatible with the one + * computed a step at a time, elsewhere + */ +int +hashf(name, len, hashsize) + register const U_CHAR *name; + register int len; + int hashsize; +{ + register int r = 0; + + while (len--) + r = HASHSTEP(r, *name++); + + return MAKE_POS(r) % hashsize; +} + +/* + * find the most recent hash node for name name (ending with first + * non-identifier char) installed by install + * + * If LEN is >= 0, it is the length of the name. + * Otherwise, compute the length by scanning the entire name. + * + * If HASH is >= 0, it is the precomputed hash code. + * Otherwise, compute the hash code. + */ +HASHNODE * +cpp_lookup(pfile, name, len, hash) + struct parse_file *pfile; + const U_CHAR *name; + int len; + int hash; +{ + register const U_CHAR *bp; + register HASHNODE *bucket; + + pfile = NULL; + if (len < 0) + { + for (bp = name; is_idchar[*bp]; bp++); + len = bp - name; + } + if (hash < 0) + hash = hashf(name, len, HASHSIZE); + + bucket = hashtab[hash]; + while (bucket) + { + if (bucket->length == len && strncmp(bucket->name, name, len) == 0) + return bucket; + bucket = bucket->next; + } + return (HASHNODE *) 0; +} + +/* + * Delete a hash node. Some weirdness to free junk from macros. + * More such weirdness will have to be added if you define more hash + * types that need it. + */ + +/* Note that the DEFINITION of a macro is removed from the hash table + * but its storage is not freed. This would be a storage leak + * except that it is not reasonable to keep undefining and redefining + * large numbers of macros many times. + * In any case, this is necessary, because a macro can be #undef'd + * in the middle of reading the arguments to a call to it. + * If #undef freed the DEFINITION, that would crash. */ + +void +delete_macro(hp) + HASHNODE *hp; +{ + + if (hp->prev != NULL) + hp->prev->next = hp->next; + if (hp->next != NULL) + hp->next->prev = hp->prev; + + /* make sure that the bucket chain header that + * the deleted guy was on points to the right thing afterwards. */ + if (hp == *hp->bucket_hdr) + *hp->bucket_hdr = hp->next; + + if (hp->type == T_MACRO) + { + DEFINITION *d = hp->value.defn; + struct reflist *ap, *nextap; + + for (ap = d->pattern; ap != NULL; ap = nextap) + { + nextap = ap->next; + free(ap); + } + if (d->nargs >= 0) + free(d->args.argnames); + free(d); + } + free(hp); +} +/* + * install a name in the main hash table, even if it is already there. + * name stops with first non alphanumeric, except leading '#'. + * caller must check against redefinition if that is desired. + * delete_macro () removes things installed by install () in fifo order. + * this is important because of the `defined' special symbol used + * in #if, and also if pushdef/popdef directives are ever implemented. + * + * If LEN is >= 0, it is the length of the name. + * Otherwise, compute the length by scanning the entire name. + * + * If HASH is >= 0, it is the precomputed hash code. + * Otherwise, compute the hash code. + */ +HASHNODE * +install(name, len, type, ivalue, value, hash) + U_CHAR *name; + int len; + enum node_type type; + int ivalue; + char *value; + int hash; +{ + register HASHNODE *hp; + register int i, bucket; + register U_CHAR *p, *q; + + if (len < 0) + { + p = name; + while (is_idchar[*p]) + p++; + len = p - name; + } + if (hash < 0) + hash = hashf(name, len, HASHSIZE); + + i = sizeof(HASHNODE) + len + 1; + hp = (HASHNODE *) xmalloc(i); + bucket = hash; + hp->bucket_hdr = &hashtab[bucket]; + hp->next = hashtab[bucket]; + hashtab[bucket] = hp; + hp->prev = NULL; + if (hp->next != NULL) + hp->next->prev = hp; + hp->type = type; + hp->length = len; + if (hp->type == T_CONST) + hp->value.ival = ivalue; + else + hp->value.cpval = value; + hp->name = ((U_CHAR *) hp) + sizeof(HASHNODE); + p = hp->name; + q = name; + for (i = 0; i < len; i++) + *p++ = *q++; + hp->name[len] = 0; + return hp; +} + +void +cpp_hash_cleanup(pfile) + cpp_reader *pfile; +{ + register int i; + + pfile = NULL; + for (i = HASHSIZE; --i >= 0;) + { + while (hashtab[i]) + delete_macro(hashtab[i]); + } +} diff --git a/epp/cpphash.h b/epp/cpphash.h new file mode 100644 index 00000000..35340429 --- /dev/null +++ b/epp/cpphash.h @@ -0,0 +1,36 @@ +enum node_type; + +/* different kinds of things that can appear in the value field + of a hash node. Actually, this may be useless now. */ +union hashval { + int ival; + char *cpval; + DEFINITION *defn; +}; + +struct hashnode { + struct hashnode *next; /* double links for easy deletion */ + struct hashnode *prev; + struct hashnode **bucket_hdr; /* also, a back pointer to this node's hash + chain is kept, in case the node is the head + of the chain and gets deleted. */ + enum node_type type; /* type of special token */ + int length; /* length of token, for quick comparison */ + U_CHAR *name; /* the actual name */ + union hashval value; /* pointer to expansion, or whatever */ +}; + +typedef struct hashnode HASHNODE; + +/* Some definitions for the hash table. The hash function MUST be + computed as shown in hashf () below. That is because the rescan + loop computes the hash value `on the fly' for most tokens, + in order to avoid the overhead of a lot of procedure calls to + the hashf () function. Hashf () only exists for the sake of + politeness, for use when speed isn't so important. */ + +#define HASHSIZE 1403 +#define HASHSTEP(old, c) ((old << 2) + c) +#define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */ + +extern HASHNODE* install PARAMS ((U_CHAR*,int,enum node_type, int,char*,int)); diff --git a/epp/cppmain.c b/epp/cppmain.c new file mode 100644 index 00000000..ce973b35 --- /dev/null +++ b/epp/cppmain.c @@ -0,0 +1,98 @@ +/* CPP main program, using CPP Library. + * Copyright (C) 1995 Free Software Foundation, Inc. + * Written by Per Bothner, 1994-95. + * + * 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * In other words, you are welcome to use, share and improve this program. + * You are forbidden to forbid anyone else to use, share and improve + * what you give them. Help stamp out software-hoarding! */ + +#include "header.h" +#include +#include + +#include "config.h" + +extern char *getenv(); + +cpp_reader parse_in; +cpp_options options; + +/* More 'friendly' abort that prints the line and file. + * config.h can #define abort fancy_abort if you like that sort of thing. */ + +void +fancy_abort() +{ + fatal("Internal gcc abort."); +} + +int +main(argc, argv) + int argc; + char **argv; +{ + char *p; + int i; + int argi = 1; /* Next argument to handle. */ + struct cpp_options *opts = &options; + + p = argv[0] + strlen(argv[0]); + while (p != argv[0] && p[-1] != '/') + --p; + progname = p; + + init_parse_file(&parse_in); + parse_in.data = opts; + + init_parse_options(opts); + + argi += cpp_handle_options(&parse_in, argc - argi, argv + argi); + if (argi < argc) + fatal("Invalid option `%s'", argv[argi]); + parse_in.show_column = 1; + + i = push_parse_file(&parse_in, opts->in_fname); + if (i != SUCCESS_EXIT_CODE) + return i; + + /* Now that we know the input file is valid, open the output. */ + + if (!opts->out_fname || !strcmp(opts->out_fname, "")) + opts->out_fname = "stdout"; + else if (!freopen(opts->out_fname, "w", stdout)) + cpp_pfatal_with_name(&parse_in, opts->out_fname); + + for (;;) + { + enum cpp_token kind; + + if (!opts->no_output) + { + fwrite(parse_in.token_buffer, 1, CPP_WRITTEN(&parse_in), stdout); + } + parse_in.limit = parse_in.token_buffer; + kind = cpp_get_token(&parse_in); + if (kind == CPP_EOF) + break; + } + + cpp_finish(&parse_in); + + if (parse_in.errors) + exit(FATAL_EXIT_CODE); + exit(SUCCESS_EXIT_CODE); +} diff --git a/epp/header.h b/epp/header.h new file mode 100644 index 00000000..b27b7107 --- /dev/null +++ b/epp/header.h @@ -0,0 +1,74 @@ +/* + * declares.h + * This is a file with some declarations in it to get everyone to shut up :) + * --Mandrake + */ + +#include "cpplib.h" + +#ifndef HOST_BITS_PER_WIDE_INT + +#if HOST_BITS_PER_LONG > HOST_BITS_PER_INT +#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG +#define HOST_WIDE_INT long +#else +#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT +#define HOST_WIDE_INT int +#endif + +#endif + +struct directive +{ + int length; + int (*func) (); + char *name; + enum node_type type; + char command_reads_line; + char traditional_comments; + char pass_thru; +}; + +void *xmalloc(unsigned size); +void *xrealloc(void *old, unsigned size); +void *xcalloc(unsigned number, unsigned size); +void cpp_print_containing_files(cpp_reader *pfile); +void cpp_file_line_for_message(cpp_reader *pfile, char *filename, int line, + int column); +void cpp_message(cpp_reader *pfile, int is_error, char *msg, char *arg1, + char *arg2, char *arg3); +void cpp_pfatal_with_name(cpp_reader *pfile, char *name); +struct operation parse_number(cpp_reader *pfile, char *start, int olen); +struct operation cpp_lex(cpp_reader *pfile); +int cpp_parse_escape(cpp_reader *pfile, char **string_ptr); +HOST_WIDE_INT cpp_parse_expr(cpp_reader *pfile); +void cpp_grow_buffer(cpp_reader *pfile, long n); +void cpp_define(cpp_reader *pfile, U_CHAR *str); +void init_parse_options(struct cpp_options *opts); +enum cpp_token null_underflow(cpp_reader *pfile); +int null_cleanup(cpp_buffer *pbuf, cpp_reader *pfile); +int macro_cleanup(cpp_buffer *pbuf, cpp_reader *pfile); +int file_cleanup(cpp_buffer *pbuf, cpp_reader *pfile); +void cpp_skip_hspace(cpp_reader *pfile); +void copy_rest_of_line(cpp_reader *pfile); +void skip_rest_of_line(cpp_reader *pfile); +int handle_directive(cpp_reader *pfile); +cpp_buffer *cpp_push_buffer(cpp_reader *pfile, U_CHAR *buffer, long length); +cpp_buffer *cpp_pop_buffer(cpp_reader *pfile); +void cpp_scan_buffer(cpp_reader *pfile); +void cpp_buf_line_and_col(register cpp_buffer *pbuf, long *linep, long *colp); +int hashf(register const U_CHAR *name,register int len, int hashsize); +void cpp_hash_cleanup(cpp_reader *pfile); +int cpp_read_check(cpp_reader *pfile); +int parse_name(cpp_reader *pfile, int c); +void init_parse_file(cpp_reader *pfile); +void init_parse_options(struct cpp_options *opts); +int push_parse_file(cpp_reader *pfile, char *fname); +void cpp_finish(cpp_reader *pfile); +cpp_buffer *cpp_file_buffer(cpp_reader *pfile); +int cpp_read_check_assertion(cpp_reader *pfile); +void fancy_abort(void); +enum cpp_token cpp_get_token(cpp_reader *pfile); +enum cpp_token cpp_get_non_space_token(cpp_reader *pfile); +int cpp_handle_options(cpp_reader *pfile, int argc, char **argv); +void cpp_print_file_and_line(cpp_reader *pfile); diff --git a/epp/timestamp.h b/epp/timestamp.h new file mode 100644 index 00000000..e69de29b diff --git a/sample-scripts/bouncingball.pl b/sample-scripts/bouncingball.pl new file mode 100644 index 00000000..c13243e3 --- /dev/null +++ b/sample-scripts/bouncingball.pl @@ -0,0 +1,91 @@ +#!/usr/bin/perl + +# This is a little script that will create a window that says +# "Follow the Bouncing Ball" and then drops it to the bottom of the +# screen and slowly bounces it around. +# then when it's done bouncing it gets rid of it. + + +$screen_size = `eesh -ewait \"general_info screen_size\"`; + +chomp($screen_size); + +($crap,$width,$height) = split(/\s+/,$screen_size); + + +# we'll create the ball here and by process of elimination determine what +# the winid is. +@winlist1 = `eesh -ewait window_list`; + +`eesh -e \"dialog_ok Follow the Bouncing Ball\"`; +@winlist2 = `eesh -ewait window_list`; + +# run through the two lists and figure out which one is new. + +foreach $item1 (@winlist2) { + $inside = 0; + foreach $item2 (@winlist1) { + $inside = 1 if($item1 eq $item2); + } + $ballwininfo = $item1 if(!$inside); +} + +# call the ball, ace +# (now we have the windowid of our ball) + +($ball,$message) = split(/ \: /,$ballwininfo); +$ball =~ s/\s+//g; + +$ballloc = `eesh -ewait \"win_op $ball move ?\"`; +$ballsize = `eesh -ewait \"win_op $ball resize ??\"`; + +$ballloc =~ s/^.*\: //g; +$ballloc =~ s/\n//g; +$ballsize =~ s/^.*\: //g; +$ballsize =~ s/\n//g; + +($ballx,$bally) = split(/\s+/,$ballloc); +($ballw,$ballh) = split(/\s+/,$ballsize); + +# now for the fun part. make that baby bounce up and down. +# we're going to open a big pipe for this one and just shove data +# to it. + +open IPCPIPE,"| eesh"; + +@fallspeed = (30,25,20,15,10,5,4,3,2); +$i = 0; +foreach(@fallspeed) { + $originalbally = $bally; + $fallspeed = $fallspeed[i]; + while($bally < ($height - $ballh)) { + if(($bally + $fallspeed + $ballh) < $height) { + $bally += $fallspeed; + } else { + $bally = $height - $ballh; + } + print IPCPIPE "win_op $ball move $ballx $bally\n"; + } + + if($fallspeed[i+1]) { + $fallspeed = $fallspeed[i+1]; + } else { + $fallspeed = 1; + } + + while($bally > ($originalbally + int($originalbally * (1/$#fallspeed)))) { + if(($bally - $fallspeed) > + ($originalbally + int($originalbally * (1/$#fallspeed)))) { + $bally -= $fallspeed; + } else { + $bally = $originalbally + int($originalbally * (1/$#fallspeed)); + } + print IPCPIPE "win_op $ball move $ballx $bally\n"; + } + $i++; +} + +print IPCPIPE "win_op $ball close\n"; +close IPCPIPE; + +# that's all folks. diff --git a/sample-scripts/lcdmover.sh b/sample-scripts/lcdmover.sh new file mode 100755 index 00000000..9bbcfdef --- /dev/null +++ b/sample-scripts/lcdmover.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# Use: none! +# instructions: move the lucy in the sky with diamonds window and see what +# happends to the other window. + +# The very wierd and bad way of getting the windowids of the two message +# windows in bash, there must be a better way! + +a=0 +eesh -e "dialog_ok Lucy in the sky with diamonds" +window=`eesh -ewait window_list|grep Message` +for i in $window;do + a=$(($a + 1)) + if [ $a = 1 ];then + windowid=$i + fi +done +a=0 +eesh -e "dialog_ok Move me with LSD" +window2=`eesh -ewait window_list|grep Message|grep -v $windowid` +for i in $window2;do + a=$(($a + 1)) + if [ $a = 1 ];then + windowid2=$i + fi +done + +# In one endless loop, get window positions and see if the lcd window is moving +# if so we move the other window too +while true;do + lcdpos=`eesh -ewait "win_op $windowid move ? ?"` + a=0 + for i in $lcdpos;do + a=$(($a + 1)) + if [ $a = 3 ];then + lcdxpos=$i + fi + if [ $a = 4 ];then + lcdypos=$i + fi + done + + pupos=`eesh -ewait "win_op $windowid move ? ?"` + a=0 + for i in $pupos;do + a=$(($a + 1)) + if [ $a = 3 ];then + puxpos=$i + fi + if [ $a = 4 ];then + puypos=$i + fi + done + + if [ $puxpos = $(($lcdxpos)) ];then + newxpos=$(($puxpos + 58)) + newypos=$(($puypos + 74)) + eesh -e "win_op $windowid2 move $newxpos $newypos" + fi + + # Is it faster if we give it a little time delay? + # I think it is, atleast we don't stress E too much if we give it a delay + for y in 1 2 3;do + bill=0 + done +done diff --git a/sample-scripts/testroller.pl b/sample-scripts/testroller.pl new file mode 100644 index 00000000..c7897da2 --- /dev/null +++ b/sample-scripts/testroller.pl @@ -0,0 +1,105 @@ +#!/usr/bin/perl + +# This script is still VERY VERY VERY early on in development +# but I wanted to give you folks an idea of why the IPC was being +# set up the way it was. this is just a quick hack. expect better +# samples in the near future. +# This app will take the parameters "on" and "off", and will basically +# shade all the windows on the current desktop and area. (or unshade) +# +# --Mandrake + +@winlist_temp = `eesh -ewait window_list`; +@intlist_temp = `eesh -ewait \"internal_list internal_ewin\"`; + +# here we're going to test to see whether we are shading or unshading +# the window. + +if($ARGV[0] eq "on") { + $shade = 1; +} else { + $shade = 0; +} + + +# make sure that we're not an internal window in our list + +foreach(@winlist_temp) { + chomp; + @stuff = split /\:/; + $insert = 1; + foreach $member (@intlist_temp) { + chomp($member); + $stuff[0] =~ s/\s+//g; + $member =~ s/\s+//g; + if($member eq $stuff[0]) { + $insert = 0; + } + } + if($insert) { + push @winlist,$stuff[0] if($stuff[0]); + } +} + +# here we'll retreive the current desk we're on + +$current_desk = `eesh -ewait \"goto_desktop ?\"`; +@stuff = split(/\:/,$current_desk); +$current_desk = $stuff[1]; +$current_desk =~ s/\n//g; +$current_desk =~ s/^\s+//; + +# here we'll retreive the current area we're on + +$current_area = `eesh -ewait \"goto_area ?\"`; +@stuff = split(/\:/,$current_area); +$current_area = $stuff[1]; +$current_area =~ s/\n//g; +$current_area =~ s/^\s+//; + + +# get the old shadespeed so that we can set it back later +# because we want this to happen fairly quickly, we'll set +# the speed to something really high + +$shadespeed = `eesh -ewait \"fx window_shade_speed ?\"`; +@stuff = split(/\: /,$shadespeed); +$shadespeed = $stuff[1]; +chomp($shadespeed); + +open IPCPIPE,"| eesh"; +print IPCPIPE "fx window_shade_speed 10000000\n"; + +# now we're going to walk through each of these windows and +# shade them + +foreach $window (@winlist) { + $cur_window_desk = `eesh -ewait \"win_op $window desk ?\"`; + @stuff = split(/\:/,$cur_window_desk); + $cur_window_desk = $stuff[1]; + $cur_window_desk =~ s/\n//g; + $cur_window_desk =~ s/^\s+//; + if($cur_window_desk eq $current_desk) { + $cur_window_area = `eesh -ewait \"win_op $window area ?\"`; + @stuff = split(/\:/,$cur_window_area); + $cur_window_area = $stuff[1]; + $cur_window_area =~ s/\n//g; + $cur_window_area =~ s/^\s+//; + if($cur_window_area eq $current_area) { + if($shade) { + print IPCPIPE "win_op $window shade on\n"; + } else { + print IPCPIPE "win_op $window shade off\n"; + } + + } + } +} + +# now we're going to set the shade speed back to what it was originally + +print IPCPIPE "fx window_shade_speed $shadespeed\n"; +close IPCPIPE; + + +# that's it! diff --git a/src/.cvsignore b/src/.cvsignore new file mode 100644 index 00000000..c51bf5df --- /dev/null +++ b/src/.cvsignore @@ -0,0 +1,14 @@ +config.log +confdefs.h +configure +enlightenment +config.cache +Makefile +Makefile.in +.deps +.libs +aclocal.m4 +config.status +*.da +bb.out +gmon.out diff --git a/src/ChangeLog b/src/ChangeLog new file mode 100644 index 00000000..b81625e0 --- /dev/null +++ b/src/ChangeLog @@ -0,0 +1,985 @@ +Sun Mar 14 17:26:01 EST 1999 +(Mandrake) + +Beginning work on 0.16 - new ChangeLog, too. + +------------------------------------------------------------------------------- + +Mon Mar 15 19:16:45 EST 1999 +(Mandrake) + +fixed crashing bug. non-input windows being selected as the selected window no +longer should crash everything + +------------------------------------------------------------------------------- + +Mon Mar 15 20:55:34 EST 1999 +(Mandrake) + +fixing things to say 0.15.3... blah. damned bugs :) + +------------------------------------------------------------------------------- + +Wed Mar 17 02:42:04 EST 1999 +(Mandrake) + +ARGH. bug bug bug. some code got commented out that shouldn't have been +commented out last night in draw.c. uncommented and committing. +(messes up shaped/borderless window resizes) +increased revision number to 0.15.4. hope to release some time tomorrow. +maybe I'll tackle some other bugs before then. + +------------------------------------------------------------------------------- + +Wed Mar 17 14:52:24 EST 1999 +(Mandrake) + +Fixed a bug in translucent move mode in draw.c + +------------------------------------------------------------------------------- + +Thu Mar 18 02:38:18 EST 1999 +(Mandrake) + +Added network.c and update.c - VERY rough skeleton code. user-optional +automatic code updates and update testing + +------------------------------------------------------------------------------- + +Sat Mar 20 13:21:14 EST 1999 +(Mandrake) + +added button_show IPC command + +------------------------------------------------------------------------------- + +Mon Mar 22 02:52:04 EST 1999 +(Mandrake) + +a little bit of work on the auto-update stuff. I still have a long way to go +here, but I thought that I would go ahead and start putting in a little bit of +logic here and there for the upgrade paths. still no actual http support. +debating on whether or not to use ghttp (since it doesn't require any of gnome +I'm thinking about it) + +------------------------------------------------------------------------------- + +Mon Mar 22 03:53:51 EST 1999 +(Mandrake) + +Cleaned up epp a little more. still LOTS of work there. + +------------------------------------------------------------------------------- + +Mon Mar 22 20:46:46 EST 1999 +(Mandrake) + +cleaned up auto-upgrade to where it won't compile if you don't have libghttp. + +------------------------------------------------------------------------------- + +Thu Mar 25 14:36:47 CST 1999 +(KainX) + +Fixed a bug with reverting focus to desktop zero. If you went from desktop 0 +to desktop 2 to desktop 6, then back to desktop 0, a window on desktop 2 would +remain focused. Not any more. =) + +Also added code to revert to the default colormap when leaving a window or a +desktop. Most users won't notice this. But you definitely will see a +difference if you use Netscape with the "-install" option. :-) + +Commented out the debugging output for select() since it was confusing the hell +out of lots of users. + +------------------------------------------------------------------------------- + +Wed Mar 31 09:27:54 EST 1999 +(Raster) + +Well - back from CEBIT... and now to the goodies... + +* added pager that does snapshots - and continuous snapshot updating... works +beautifully with almost no cpu use on a local machine - it'll probably kill +your network if you run it over a network... :( But it does everything +except allowe you to drag and drop windows around (at the moment) - that will +be added. + +* added mode.show_pagers option that is internal for now... + +* added flatfile menu loading - sorry - no examples yet - but it works and +automagically updates the menu if the file changes. It makes constructing menus +childs play - I mean REALLY childs play. + +* fixed countless minor buglets. + +* added area sliding (if desktop sliding is on areas will slide around too) + +* fixed manual placement so the mouse up doesnt get passed onto clients under +the pointer then the window is placed + +* fixed window list off dragbar so things dont die when you try focus an ewin +ID that doesnt exist anymore + +* this brings E's code (not including fnlib, imlib etc.) up to about 60756 +lines of code. + +------------------------------------------------------------------------------- + +Wed Mar 31 10:28:48 CST 1999 +(KainX) + +When we use the pager to make a window sticky, bring that window to the +current desktop as one would expect to happen. + +------------------------------------------------------------------------------- + +Wed Mar 31 17:30:49 EST 1999 +(Raster) + +* fixed numlock / scrollock keybinding / action etc. issues.... + +------------------------------------------------------------------------------- + +Thu Apr 1 14:56:19 EST 1999 +(Mandrake) + +netowrk updates, etc + +------------------------------------------------------------------------------- + +Fri Apr 2 00:56:47 EST 1999 +(Mandrake) + +Lots of stuff. ipc commands. pager command now enables and disables the pager +- made a couple of generic functions EnableAllPagers() and DisableAllPagers() +to do the actual work there. also added skeleton of the fx command. will do +that tonight as I watch a movie. added move_mode and resize_mode commands +(since everyone seems to have wanted that and I don't know how those slipped my +mind) they're not documented well yet, but if you read ipc.c you should be able +to guess how they work (they all work similarly to other ipc commands - I like +the interface I'm brewing up and I'm likely to continue using it) + +------------------------------------------------------------------------------- + +Fri Apr 2 12:04:19 EST 1999 +(Mandrake) + +#if 0'd some stuff out for 0.15.5 release + +------------------------------------------------------------------------------- + +Sun Apr 4 17:10:08 EDT 1999 +(Mandrake) + +lots of IPC work. new fx command. also a big restructuring of the code itself +in the ipc array (much prettier to the eye) +also I commented a few bits of code -- it's now documented somewhat how to add +new IPC commands in there. + +------------------------------------------------------------------------------- + +Sun Apr 4 20:04:20 EDT 1999 +(Mandrake) + +more IPC work. now many win_op commands have status checks +win_op ? +as well as support +win_op + +------------------------------------------------------------------------------- + +Sun Apr 4 21:32:43 EDT 1999 +(Mandrake) + +added more "?" commands to win_op +very useful. + +------------------------------------------------------------------------------- + +Sun Apr 4 23:04:17 EDT 1999 +(Mandrake) + +CPPFLAGS problems people were having should be solved +put the -D stuff from e/src/Makefile.am into econfig.h + +------------------------------------------------------------------------------- + +Mon Apr 5 21:30:50 EDT 1999 +(Mandrake) + +updated some numbers to 0.16.0 -> time to say goodbye to 0.15 + +------------------------------------------------------------------------------- + +Mon Apr 5 22:59:08 EDT 1999 +(Mandrake) + +holy cow, commented some code. Also split out all the initial setup of +fallback classes into SetupFallbackClasses() in init.c -- cleans up main.c +considerably + +------------------------------------------------------------------------------- + +Tue Apr 6 18:54:54 EDT 1999 +(Mandrake) + +minor bugfix care of Daniele Paoni for java applications. +also some more comments. + +------------------------------------------------------------------------------- + +Thu Apr 8 02:33:54 EDT 1999 +(Raster) + +again - minor fixes to manual placement, a few other little things here and +there scattered about.... but one major addition... + +you can drag windows around the pager now... and..... between pagers for +desktops... soi you can move windows form any area to any desktop and around +any desktop now... and it all works nicely... :) + +------------------------------------------------------------------------------- + +Thu Apr 8 11:39:45 EDT 1999 +(Mandrake) + +now we autosave whether or not the pager was on. + +------------------------------------------------------------------------------- + +Thu Apr 8 15:14:19 EDT 1999 +(Mandrake) + +added the very useful internal_list IPC command. +see help for details. + +also added a samplescripts directory with my first sample script, +testroller.pl + +------------------------------------------------------------------------------- + +Thu Apr 8 16:50:22 EDT 1999 +(Mandrake) + +fleshed out the --help / -h cmdline parameter to eesh a little. + +------------------------------------------------------------------------------- + +Thu Apr 8 17:55:20 EDT 1999 +(Mandrake) + +added advanced_focus IPC command. see IPC help for more information + +------------------------------------------------------------------------------- + +Fri Apr 9 00:07:46 EDT 1999 +(Mandrake) + +added set_focus IPC command. +also added "focus" to win_op command +added dialog_ok IPC command. +see ipc help for more details + +------------------------------------------------------------------------------- + +Fri Apr 9 12:36:56 EDT 1999 +(Mandrake) + +added list_class IPC command +see ipc help for more details + +------------------------------------------------------------------------------- + +Fri Apr 9 13:36:12 EDT 1999 +(Mandrake) + +added play_sound IPC command. +started work on soundclass IPC command (not finished) +added -v/--version commandline parameter + +------------------------------------------------------------------------------- + +Fri Apr 9 14:14:54 EDT 1999 +(Mandrake) + +added general_info IPC command. just has screen_size in it now, but I +am sure tehre will be more going in later + +------------------------------------------------------------------------------- + +Fri Apr 9 17:16:27 EDT 1999 +(Mandrake) + +fleshed out soundclass ipc + +------------------------------------------------------------------------------- + +Sat Apr 10 00:26:09 EDT 1999 +(Mandrake) + +GetNetText() actually does something now. also fixed Makefile.am + +------------------------------------------------------------------------------- + +Sat Apr 10 00:44:50 EDT 1999 +(Mandrake) + +mostly-functional GetNetFileDate() now. also cleaned up update.c (doesn't +give warnings anymore) +also the bulk of the work in SaveNetFile() + +------------------------------------------------------------------------------- + +Sat Apr 10 10:53:00 EDT 1999 +(Mandrake) + +Somehow network.c got messed up inbetween compile and commit. + +------------------------------------------------------------------------------- + +Sat Apr 10 11:50:45 EDT 1999 +(Mandrake) + +minor bugfix in ipc.c + +------------------------------------------------------------------------------- + +Sun Apr 11 23:15:27 EDT 1999 +(Mandrake) + +merged pager stuff into uni-pager command. + +------------------------------------------------------------------------------- + +Tue Apr 20 17:48:12 EDT 1999 +(Raster) + +Again - I've been lazy with the changelog... but I have done a buttload... +lets summarise... + +* added slider widget and event handleing +* added drawing area widget and event handleing +* added sliders to all dialog settings boxes that need them +* added start of a background editor dialog +* added multiple desktop editor +* fixed soem menu bugs +* fixed memory leaks +* fixed "app resizes whilst being moved" bug +* fixed tables instie tables so they work +* optimised backgorudns menu a bit better for file searching +* got rid of redundant sound code that esd now does +* fixed minor bug in WAV loading code +* added elements to brushed metal theme to supply data for new widgets & + features +* fixed 1 or 2 little pager bugs +* fixed possible segfault in text shortening code +* fixed internationalisation problem in saving and reading floats +* did lots of other fixes and adds I've forgotten about + +------------------------------------------------------------------------------- + +Fri Apr 23 12:38:30 EDT 1999 +(Raster) + +* added desktop background selector AND editor settings dialog - all gui - all + works. You can't select files to use as backgrounds yet - need file selector + dialog for that (probably next on my list) BUT if you have E generate + background defs from ~/.enlightenmen/backgrounds (which should be a symlink + to wherever you store your images, or just fill that directory with images + and sibdirectories and images - E will auto-index them into the backgrounds + menu). you can edit all of those and their attributes, and clone versions + then edit the clones, modify them, remove the images to use a solid color + instead - etc. all works.. :) + +------------------------------------------------------------------------------- + +Sat May 15 15:04:35 EDT 1999 +(Raster) + +* added pager background caching - now pager backrounds will be cached and + saved to disk for faster "repainting" or initial painting. This should + work now. + +* session saving no longer saves "-theme" optin ofr command line - the + ~/.enlightenment/user_theme.cfg takes pcare of this. + +* "snapshots" now use a snapshot dialog. snapshotting location also snaps + desktop area as well (since a desktop is one virtually large desktop). + It can also snap the "command" and be able to start the apps up again on + startup if you select that option. You can also select if the snapped + attributes are to apply toall windows of that class and not just the first + instance. should be a lot nicer. + +* some minor pager updating bugs fixed - now if you close a window on another + desktop area it updates properly. the pager "hilight" zoom window should + now be pretty hard to make hang around - paranoia added to hide all zoom + window whenever there is a chance we dont want them. + +* minor memory leak fixed. + +* brushed metal theme now has different pager border style - more of a + demonstration now of the power of internal ewins that are beng used for the + pager border and how you can make them vehave like a slideout so you can + shade the pager out of the way when you dont want it. + +* X11R5 apps should be session managed pproperly now if E is X11R6 session + managed - they shoudl normally go back on the same desktop etc. - but its + not guaranteed - still not 100% unambiguous to determine windows of + unique apps. + +* fixed cloning bug where double cloning happens on desktop switch - sticky + windows should not flicker as much now. should be faster / more efficient + +* fixed numerous other little buglets and made numerous other little speedups + and improvements. + +* added new menu scrolling method patch from Christian - very nice - thanks + fixed one minor bug in it. + +* added rotated fonts patch from, Christian - thanks again. + +* fixed app re-focus when we go back to the previous desktop in click-to-focus + +* fixed potential pixmap leak + +* suggest using Imlib from CVS - E triggered a pixmap leak - OOOPS - fixed + +* should have fixed "wierd focus behavior" when flipping desktops - basically + now the code goes throuhg ALL ewins - ALL the border parts and removes motion + enter leave and other miscellaneous events that may trigger E to respond to + these and set the focus to that window - so basically we now get E to not + recieve any such tiggering events whilst flipping desktops. + +* fixed some internal stack tracing problems where we forget to wrap some + returns form some functions. + +* added options for turing pager zoom on and off - loads ans saves it and + has settings check button for it. + +* added window title popup option and code (using tooltip as definition + backend - now have PAGER tooltip type to define this). loads and saves + this option - also has settings check button for it. + +* added PAGER tooltip type (and image & text classes for it) to BrushedMetal + theme. + +------------------------------------------------------------------------------- + +Fri May 14 12:40:27 IST 1999 +(Merlin) + +* Fixed a bug in list.c movetofront that turned lists into loops. + +* Updated keyboard warping to operate more sanely; especially in a cramped + desktop with lots of overlapping windows. At start, it makes a list of + the warpring; then when you release alt (currently hardwired for only + alt) it dumps the warpring. Added configuration option 'raise after warp' + if you use focus with pointer; when you release alt, the chosen window + is raised. Also, displays the title of the windows it is warping to so + you know, even if you can't see them. This is only compiled in if you + define WITH_TARTY_WARP; see E.h; needs XKB X extension. + +* Added action MOVE_CONTRAINED which is a normal window move, but the + window is absolutely constrained to the current view area. + +* Changed menu handling so if you click on a menu item, drag off it and + then release, the menu item is not activated. So you can undo a mistaken + click. + +------------------------------------------------------------------------------- + +Tue May 25 11:43:48 PDT 1999 +(Mandrake) + +modules. that's what I'm going to start working on now. +incidentally, the xkb tests don't seem to work under accelx. + +------------------------------------------------------------------------------- + +Wed May 26 17:13:26 PDT 1999 +(Mandrake) + +More modules work. Now we can load and unload modules. they don't do much +yet, though. + +------------------------------------------------------------------------------- + +Sat May 29 13:14:42 PDT 1999 +(Mandrake) + +more modules work. the unloading should actually work correctly now (wasn't +removing them before). +Also, the ipc "exit" command now runs a logout (pops up a dialog box) unless +you pass a parameter (of any kind) to it. +people should learn to use the IPC help mechanisms. + +------------------------------------------------------------------------------- + +Sat May 29 19:08:59 PDT 1999 +(Mandrake) + +more IPC work. advanced_focus and pager got some stuff added. +check out online help for details. + +------------------------------------------------------------------------------- + +Sun May 30 14:21:39 PDT 1999 +(Mandrake) + +fixed restart_wm in doExit(), which has apparently been broken for ages. +(allows you to start another window manager from inside of E) +this will fix the menus, the ipc, etc... + +------------------------------------------------------------------------------- + +Mon May 31 00:20:06 PDT 1999 +(Mandrake) + +began work on ref_counts in all sorts of things. also added ability to enable +and disable a particular pager at runtime. see pager IPC help for more +details. + +------------------------------------------------------------------------------- + +Mon May 31 15:52:00 PDT 1999 +(Mandrake) + +borderless windows save state between restarts + +------------------------------------------------------------------------------- + +Wed Jun 2 13:33:59 PDT 1999 +(Mandrake) + +fixed pagers on restarts. +sorry about that. use "pager off" "pager on" ipc commands, should reset (after +starting this version) + +------------------------------------------------------------------------------- + +Sun Jun 6 12:59:53 PDT 1999 +(Mandrake) + +some work on reference counting. Things should start picking up now that +at least one class does reference counting properly in one instance. +(this is a very large problem to solve) + +------------------------------------------------------------------------------- + +Wed Jun 9 12:49:52 PDT 1999 +(Mandrake) + +reference counting continues. more of the same. lots of work to do here. + +------------------------------------------------------------------------------- + +Fri Jun 11 14:30:34 PDT 1999 +(Mandrake) + +more work on reference counting. + +------------------------------------------------------------------------------- + +Sat Jun 12 19:20:10 PDT 1999 +(Mandrake) + +reference counting, reference counting, etc. +oh, and some more IPC work in order to test a little more thoroughly. + +------------------------------------------------------------------------------- + +Sat Jun 12 19:46:41 PDT 1999 +(Mandrake) + +flipped around some IPC commands, added a couple of new ones. +still testing. + +------------------------------------------------------------------------------- + +Sun Jun 13 15:54:51 PDT 1999 +(Mandrake) + +more IPC work, more reference count work, as well as some additional +destructors for things like borders. + +------------------------------------------------------------------------------- + +Mon Jun 14 17:39:17 PDT 1999 +(Mandrake) + +more IPC work, skeletoning out some stuff. Also fixed reference counting on +backgrounds. + +------------------------------------------------------------------------------- + +Wed Jun 16 10:39:58 PDT 1999 +(Mandrake) + +just when you thought reference counting madness was over, it wasn't :) +thanks to Christian Kreibich for helping me there :) + +------------------------------------------------------------------------------- + +Fri Jun 18 14:18:58 PDT 1999 +(Mandrake) + +fixed a bug in cached config file loading. thanks to +Peter Kjellerstedt + +------------------------------------------------------------------------------- + +Fri Jun 18 17:51:04 PDT 1999 +(Mandrake) + +fixed the pager bug on restart. also fixed the "88% load bug" + +------------------------------------------------------------------------------- + +Mon Jun 21 15:19:11 PDT 1999 +(Mandrake) + +added "windowlist" and "desktopwindowlist" menu types. -- same code from +dragbar. + +------------------------------------------------------------------------------- + +Tue Jun 22 13:27:57 CDT 1999 +(KainX) + +This should fix the button toggling bug reported by David Joseph Goehrig + + +------------------------------------------------------------------------------- + +Mon Jun 28 01:54:01 PDT 1999 +(Mandrake) + +this should fix some config loading bugs as reported by +Jesse Michael + +------------------------------------------------------------------------------- + +Tue Jun 29 13:13:04 PDT 1999 +(Mandrake) + +Merged in a patch from Christian Kreibich +for Labeled Buttons. Also added dereferening to the destructor for the +additional memory he allocated, as well as removed a couple of lines of +redundant code. Will add to the default themes later. + +------------------------------------------------------------------------------- + +Wed Jun 30 12:22:40 PDT 1999 +(Raster) + +Oooops - overoptimised the event pruner... optimised out some window +map requests - fixed this... just got rid of the map request compressor. +thanks shaleh for bugging us about this + +------------------------------------------------------------------------------- + +Wed Jul 7 13:55:42 PDT 1999 +(Mandrake) + +Fixed labeled buttons definition for Christian. Also added the regex that he +sent in. + +------------------------------------------------------------------------------- + +Sun Jul 11 13:07:07 PDT 1999 +(Mandrake) + +added "dock" IPC command. see +eesh -ewait "help dock" for more information + +------------------------------------------------------------------------------- + +Tue Jul 13 01:07:29 CEST 1999 +(Christian) + +Cleaned up eesh's help output. Also added a generic quicksort algorithm, +see misc.c for details and IPC_Help() for an example. + +------------------------------------------------------------------------------- + +Tue Jul 13 11:12:25 EST 1999 +(Raster) + +Committing work on iconbox - scrollbar, scrollarrows ec. all work - in theory +i can re-arrange the arrows to be either end, on one of the ends or no arrows +and arrange the scrollbar to be on the botton or top.. some code left to do +vertical iconbox - not much though - just scrollbar arrangement code. + +iconify and de-iconfi works all great - only thing to watch.. dont restart +E with iconified windows.. you'll lose their icons right now.. need to fix +that. + +next need to ad non snapshotted icon support (several stages - use E defined +icons only, use E definied icons only if defined, otherwise use snapshotted +icons, use app defined icons only if defined otherwise use snapshots, +use E defined icons if defined, otherwise use app defined icon if defined, +if not defined use snapshot.. not ot mention the introduction of default +E defined icons for all unknown windows - then the actual icon def list itself +and the config system for that etc... then need to support multiple iconboxes +and dnd form pager to iconbox and back... and between iconboxes... then +definable iconification into certain iconboxes - and also need to support +transparent backgrouns for iconbox - thus simulating the old icons floating +about thing... but its all coming... + +------------------------------------------------------------------------------- + +Fri Jul 16 03:31:40 EST 1999 +(Raster) + +Iconbox now handles ghe horizontal, the vertical, all scrollbar optiond - even +has a settings dialog box (right muse on iconbox). it can even be transparent. + +I also optimised property change event handling - e should be much much much +more eficient at it avoiding lots of unecessary X traffic. + +Changed gthe box draw mode to move the inner box 1 pixel in so on borderless +window you can see the border when moving & resizing. + +added icon creation policy code. + +in the middle of ading icon list code /9that determines what icon image is +to be used for what apps and is user definable) + +play with the iconbox - it shouldnt be too bad. :) + +------------------------------------------------------------------------------- + +Fri Jul 16 02:04:42 CEST 1999 +(Christian) + +Replaced about.png so that it matches the look of the website logo. + +------------------------------------------------------------------------------- + +Fri Jul 16 15:54:44 PDT 1999 +(Mandrake) + +KDE hints start. rev 1 didn't actually work, so we started over + +------------------------------------------------------------------------------- + +Mon Jul 19 23:03:11 EST 1999 +(Raster) + +* fixed minor shape propagation bug +* improved dialog code by adding bindable callback keyboard shortcuts +* improved backgroudns dialog... I just got an influx of about 4000 new pix, + and it did get a bit tedious as i have to filter the backgrounds to only + keep the good ones... now the backgrounds dialog can becme almost an image + viewer that lets me filter my background colletcion... not to mention some + keyboard shorts work now (like left/right arrow, d, delete, space and + backspace) +* iconbox now starts up when E starts - still doesnt remember settings but + iconifed windows on start / restart get handled now, and added some + imageclasses for the iconbox widget parts - still need more bits put in + though like a scrollbar knob imageclass and a iconbox frame imageclass + +------------------------------------------------------------------------------- + +Tue Jul 20 02:34:29 EST 1999 +(Raster) + +* added iconbox coverwin support and imageclass - if the iclass is there the +cover win is displayed... also updated brushed metal. again.. to include this +stuff. + +------------------------------------------------------------------------------- + +Fri Jul 23 11:34:11 PDT 1999 +(KainX) + +Added support for HP-UX 10.x modules thanks to a patch from Marty Riedling + + +------------------------------------------------------------------------------- + +Mon Jul 26 14:03:39 PDT 1999 +(Troy R. Pesola) + +Here is a patch file that incorporates the following: + +-fixed actions.c to set the desktop and area when switching to another ewin. + +-added sound "SOUND_FOCUS_SET" to be played when the focus is set. + +-added win_op title to the IPC stuff. + +-changed keybindings to reveal deskmenu and taskmenu. + +-changed menus to remove -geom params on netscape calls (personal pref) + +I will start working on the IPC stuff that has the create/modify/delete +functions. + +------------------------------------------------------------------------------- + +Mon Jul 26 23:31:51 CEST 1999 +(Christian) + +Window Groups :) + +E's windows can new be grouped by opening the winops menu for a +window, and selecting 'Window Group'->'Start Group'. Windows can be added +using 'Window Group'->'Add to group'. There's a control dialog for groups +via 'Window Group'->'Configure group', which defines what actions are +applied to all group members. Moving groups should work in every method +except for translucent, which is turned into opaque. + +The pagers by default are a group. + +The group members can be emphasized using 'Window Group'->'Show/Hide Group', +doing so again returns to the previous borders. Which borders are used for +emphasizing is defined by a tag __BORDER_GROUP_NAME for every +border in the theme. Still needs to be added to BrushedMetal. + +Also corrected a typo. Or two, or three ... ;) + +------------------------------------------------------------------------------- + +Mon Jul 26 16:09:13 PDT 1999 +(Mandrake) + +cleaned up a little bit (especially in actions.c -- there was a spot where i +was being used from a previous context but being reset inside of a closure - I +HAVE to assume that was a mistake). Also took out a couple of warnings. +Expect a new version of kde.c when I get home, also -- time to commit + +------------------------------------------------------------------------------- + +Tue Jul 27 23:38:36 EST 1999 +(Raster) + +guess what... i'm back... and the iconbox is almost 100% done... sorry no +example icondefs.cfg files yt to demo the app window -> micon image matching... +but i'll include that later... just trust me that it all works. + +the icobox now does a hell of a LOT and is very configrable and malleble. set +the right options and it'd look and feel almost exactly like the old +iconification stuff except with enhancements and better behavior. + +at least now you can have multpile iconboxes, create and destroy them at will +and chnage all the options int he iconbox and e will remember and save/load +this info up again. + +quite nice actually... :) try it out - sorry - snapshotted windows only for +those of you not evil enuf to read e's code to figure out thr iconfdefs.cfg +format. :) i''ll let that cat out of the bag soon enuf. + +------------------------------------------------------------------------------- + +Tue Jul 27 22:23:25 CEST 1999 +(Christian) + +Hopefully fixed a segfault in moving windows with transients. + +------------------------------------------------------------------------------- + +Wed Jul 28 08:19:27 EST 1999 +(Raster) + +added in owens withdrawn state patch thst fixes sojme java apps continuously +spinning after withdrawing windows... + +also fixed variable clash.. this could cause segv's - the cvs merge didnt +notice we now had to i variables in different contexts... :) fixed. + +------------------------------------------------------------------------------- + +Thu Jul 29 00:46:24 CEST 1999 +(Christian) + +Added window group shortcuts to titlebar of BrushedMetal. Also dropped +Tigert a mail today and told him that we could use borders for grouped +windows ... I have something here for that purpose but it's Tigert's +theme, right? + +------------------------------------------------------------------------------- + +Wed Jul 28 18:33:09 PDT 1999 +(KainX) + +Added iconbox images to ShinyMetal theme (which I still use...sue me). + +------------------------------------------------------------------------------- + +Thu Jul 29 17:41:14 PDT 1999 +(Knut Neumann) + +this adds create/modify/delete ability to the +background ipc command. Its using the format, Troy suggested on e-develop, +though it might easily be changed to the "old" style system. + +It is using a new value type system as well, which is working the following +way: + + background TEST bg.file /home/test/test.png + +will create a background (resp. modifying it, if it already exists) and set +bg.file property to the specified file. + +This way takes advantage over the way to provide parameters as the set_bg +command from comms.c works as one does not have to hack in every single +parameter. On the other side, it is a real mess, if one wants to set a whole +bunch of options at once. I have no idea how to solve that discrepance at the +moment. Suggestions are welcome. + +------------------------------------------------------------------------------- + +Thu Jul 29 18:33:02 PDT 1999 +(Mandrake) + +shut up compile. still reading kwm.cpp - if we're going to support KDE hints, +we're going to do them right. this _STRING_ stuff is silly. + +------------------------------------------------------------------------------- + +Fri Jul 30 11:10:28 PDT 1999 +(Mandrake) + +applied patch from Valdis Kletnieks to make epp +compile cleanly on AIX. + +------------------------------------------------------------------------------- + +Mon Aug 2 15:06:33 PDT 1999 +(Mandrake) + +KDE Part thirty-seven. should start working soon + +------------------------------------------------------------------------------- + +Mon Aug 2 17:16:55 PDT 1999 +(Mandrake) + +more atom work. + +------------------------------------------------------------------------------- + +Thu Aug 5 00:32:51 CEST 1999 +(Christian) + +The tooltip icons are back. Add tooltip text to the actions in an +action class using __TOOLTIP_ACTION_TEXT "whatever" and you get the mouse +button and key combination visualized for free :) See BrushedMetal's +window titlebar for an example. Theme designers can override the icon +looks by providing imageclasses named: TOOLTIP_MOUSEBUTTON_ANY, +TOOLTIP_MOUSEBUTTON_1, TOOLTIP_MOUSEBUTTON_2, TOOLTIP_MOUSEBUTTON_3, +TOOLTIP_KEY_SHIFT, TOOLTIP_KEY_LOCK, TOOLTIP_KEY_CTRL, TOOLTIP_KEY_MOD1 +TOOLTIP_KEY_MOD2, TOOLTIP_KEY_MOD3, TOOLTIP_KEY_MOD4, TOOLTIP_KEY_MOD5. + +Have fun folks :) + +------------------------------------------------------------------------------- + +Wed Aug 4 23:08:41 PDT 1999 +(KainX) + +The beginnings of the imageclass apply IPC. + +------------------------------------------------------------------------------- diff --git a/src/ChangeLog-pre0.16.gz b/src/ChangeLog-pre0.16.gz new file mode 100644 index 00000000..a451300f Binary files /dev/null and b/src/ChangeLog-pre0.16.gz differ diff --git a/src/E.h b/src/E.h new file mode 100644 index 00000000..99678213 --- /dev/null +++ b/src/E.h @@ -0,0 +1,2776 @@ +/*****************************************************************************/ +/* Enlightenment - The Window Manager that dares to do what others don't */ +/*****************************************************************************/ +/* Copyright (C) 1997 - 1999 Carsten Haitzler (The Rasterman) */ +/* and Geoff Harrison (Mandrake) */ +/* */ +/* This program and utilites is free software; you can redistribute it */ +/* and/or modify it under the terms of the License shown in COPYING */ +/* */ +/* This software 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. */ +/*****************************************************************************/ + +#include "econfig.h" + +#include +#include +#include +#include +#include +#include +/*#include */ +#include +#include +#include +/* sgi's stdio.h has: + * + * #if _SGIAPI && _NO_ANSIMODE + * extern int vsnprintf(char *, ssize_t, const char *, char *); + * #endif + * + * so workaround... + */ +#ifdef __sgi +#ifdef _NO_ANSIMODE +#undef _NO_ANSIMODE +#endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "econfig.h" + +/* workaround for 64bit architectures - xlib expects 32bit CARDINALS to be */ +/* long's on 64bit machines... thus well the CARD32's Im unsing shoudl be.. */ +#define CARD32 long + +#if (WITH_TARTY_WARP == 1) +#define WITH_TARTY_WARP 1 +#else +#undef WITH_TARTY_WARP +#endif /* !WITH_TARTY_WARP */ + +#define RESET_ALERT \ + AssignTitleText("Enlightenment Message Dialog"); \ + AssignIgnoreText("Ignore this message"); \ + AssignRestartText("Restart the Window Manager"); \ + AssignExitText("Quit the Window Manager"); + +#define ASSIGN_ALERT(a, b, c, d) \ + AssignTitleText(a); \ + AssignIgnoreText(b); \ + AssignRestartText(c); \ + AssignExitText(d); + +/************************************************************************/ +/* sound macro convenience funcs */ +/************************************************************************/ + +#define AUDIO_PLAY(sclass) \ +ApplySclass(FindItem((sclass), 0, LIST_FINDBY_NAME, LIST_TYPE_SCLASS)); +/************************************************************************/ +/* dialog macro convenience funcs */ +/************************************************************************/ + +#define DIALOG_OK(title, text) \ +{ \ + Dialog *__d; \ + __d = CreateDialog("DIALOG"); \ + DialogSetTitle(__d, title); \ + DialogSetText(__d, text); \ + DialogAddButton(__d, "OK", NULL, 1); \ + ShowDialog(__d); \ +} + +#define DIALOG_PARAM_OK(title) \ +{ \ + Dialog *__d; \ + __d = CreateDialog("DIALOG"); \ + DialogSetTitle(__d, title); + +#define DIALOG_PARAM \ +DialogSetParamText(__d, + +#define DIALOG_PARAM_END \ + ); \ + DialogAddButton(__d, "OK", NULL, 1); \ + ShowDialog(__d); \ +} + +/************************************************************************/ + +#ifndef HAVE_GETCWD +#error "ERROR: Enlightenment needs a system with getcwd() in it's libs." +#error "You may have to upgrade your Operating system, Distribution, base" +#error "system libraries etc. Please see the the instructions for your" +#error "particular Operating System or Distribution" +#endif +#ifndef HAVE_MKDIR +#error "ERROR: Enlightenment needs a system with mkdir() in it's libs." +#error "You may have to upgrade your Operating system, Distribution, base" +#error "system libraries etc. Please see the the instructions for your" +#error "particular Operating System or Distribution" +#endif + +#ifndef DEFAULT_SH_PATH +#ifdef __sgi +/* + * It appears that SGI (at least IRIX 6.4) uses ksh as their sh, and it + * seems to run in restricted mode, so things like restart fail miserably. + * Let's use csh instead + * -KDT 07/31/98 + */ +#define DEFAULT_SH_PATH "/sbin/csh" +#else +#define DEFAULT_SH_PATH "/bin/sh" +#endif +#endif + +/* shut warnings up + * pid_t wait3(int *status, int options, struct rusage *rusage); + * int setenv(const char *name, const char *value, int overwrite); + */ + +#define FILEPATH_LEN_MAX 4096 +/* This turns on E's internal stack tracking system for coarse debugging */ +/* and being able to trace E for profiling/optimisation purposes (which */ +/* believe it or not I'm actually doing) */ + +/* #define DEBUG 1 */ + +#ifdef DEBUG +extern int call_level; +extern int debug_level; +extern char *call_stack[1024]; + +#endif +#ifdef DEBUG +#define EDBUG(l,x) \ +{ \ + call_stack[call_level] = x; \ + call_level++; \ +} +#else +#define EDBUG(l,x) \ +; +#endif + +#ifdef DEBUG +#define EDBUG_RETURN(x) \ +{ \ + call_level--; \ + return (x); \ +} +#define EDBUG_RETURN_ \ +{ \ + call_level--; \ + return; \ +} +#else +#define EDBUG_RETURN(x) \ +{ \ + return (x); \ +} +#define EDBUG_RETURN_ \ +{ \ + return; \ +} +#endif + +int Evsnprintf(char *str, size_t count, const char *fmt, va_list args); + +#ifdef HAVE_STDARGS +int Esnprintf(char *str, size_t count, const char *fmt,...); + +#else +int Esnprintf(va_alist); + +#endif + +#define Esetenv(var, val, overwrite) \ +{ \ + static char envvar[FILEPATH_LEN_MAX]; \ + Esnprintf(envvar, FILEPATH_LEN_MAX, "%s=%s", var, val);\ + putenv(envvar);\ +} + +#ifdef HAVE_LIBESD +#include +#endif + +#include "arrange.h" + +#define TT_VALID( handle ) ( ( handle ).z != NULL ) +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + +#define IN_RANGE(a, b, range) \ + ((((a) > (b)) && ((a) - (b) <= (range))) || \ + (((a) <= (b)) && ((b) - (a) <= (range)))) + +#define IN_ABOVE(a, b, range) \ + (((a) >= (b)) && ((a) - (b) <= (range))) + +#define IN_BELOW(a, b, range) \ + (((a) <= (b)) && ((b) - (a) <= (range))) + +#define SPANS_COMMON(x1, w1, x2, w2) \ + (!((((x2) + (w2)) <= (x1)) || ((x2) >= ((x1) + (w1))))) + +#define EERR_NONE 0 +#define EERR_OUT_OF_MEMORY 1 +#define EERR_FILE_NOT_EXIST 2 +#define EERR_PERMISSION_DENIED 3 +#define EERR_FILING_SYSTEM_FULL 4 + +#ifndef ENLIGHTENMENT_ROOT +#define ENLIGHTENMENT_ROOT "/usr/local/enlightenment" +#endif +#define ENLIGHTENMENT_SYSTEM_CONFIG ENLIGHTENMENT_ROOT"/system_config" +#define ENLIGHTENMENT_SYSTEM_THEMES ENLIGHTENMENT_ROOT"/themes" +#define ENLIGHTENMENT_SYSTEM_BGS ENLIGHTENMENT_ROOT"/backgrounds" + +#define ENLIGHTENMENT_CONF_NUM_DESKTOPS 32 +/* the cast is so -1 will == UINT_MAX */ +#define DESKTOPS_WRAP_NUM(x) \ + (((unsigned int) (x)) % mode.numdesktops) + +#define LIST_FINDBY_NAME 0 +#define LIST_FINDBY_ID 1 +#define LIST_FINDBY_BOTH 2 +#define LIST_FINDBY_NONE 3 +#define LIST_FINDBY_POINTER 4 + +#define LIST_TYPE_ANY 0 +#define LIST_TYPE_CLIENT 1 +#define LIST_TYPE_EWIN 2 +#define LIST_TYPE_BORDER 3 +#define LIST_TYPE_ICLASS 4 +#define LIST_TYPE_ACLASS 5 +#define LIST_TYPE_AWAIT_ICLASS 6 +#define LIST_TYPE_ACLASS_GLOBAL 7 +#define LIST_TYPE_ACLASS_DESK 8 +#define LIST_TYPE_TCLASS 9 +#define LIST_TYPE_BACKGROUND 10 +#define LIST_TYPE_BUTTON 11 +#define LIST_TYPE_SCLASS 12 +#define LIST_TYPE_WINDOWMATCH 13 +#define LIST_TYPE_COLORMODIFIER 14 +#define LIST_TYPE_ICONIFIEDS 15 +#define LIST_TYPE_SLIDEOUT 16 +#define LIST_TYPE_DRAW 17 +#define LIST_TYPE_TOOLTIP 18 +#define LIST_TYPE_CONTAINER 19 +#define LIST_TYPE_QUEUE_ENTRY 20 +#define LIST_TYPE_MENU 21 +#define LIST_TYPE_MENU_STYLE 22 +#define LIST_TYPE_ECURSOR 23 +#define LIST_TYPE_SNAPSHOT 24 +#define LIST_TYPE_DIALOG 25 +#define LIST_TYPE_CLONE 26 +#define LIST_TYPE_PAGER 27 +#define LIST_TYPE_ICONBOX 28 +#define LIST_TYPE_WARP_RING 29 +#define LIST_TYPE_XID 30 +#define LIST_TYPE_ICONDEF 31 + +#define LIST_TYPE_COUNT 32 + +#define BEVEL_NONE 0 +#define BEVEL_AMIGA 1 +#define BEVEL_MOTIF 2 +#define BEVEL_NEXT 3 +#define BEVEL_DOUBLE 4 +#define BEVEL_WIDEDOUBLE 5 +#define BEVEL_THINPOINT 6 +#define BEVEL_THICKPOINT 7 + +#define EWIN_NORMAL 0 +#define EWIN_ACTIVE 1 +#define EWIN_STICKY 2 +#define EWIN_ICONIFIED 4 + +#define STATE_NORMAL 0 +#define STATE_HILITED 1 +#define STATE_CLICKED 2 +#define STATE_DISABLED 3 + +#define FILL_STRETCH 0 +#define FILL_TILE_H 1 +#define FILL_TILE_V 2 +#define FILL_INT_TILE_H 4 +#define FILL_INT_TILE_V 8 + +#define FLAG_BUTTON 0 +#define FLAG_TITLE 1 +#define FLAG_MINIICON 2 +#define FLAG_FIXED 4 +#define FLAG_FIXED_HORIZ 8 +#define FLAG_FIXED_VERT 16 + +#define FOCUS_POINTER 0 +#define FOCUS_SLOPPY 1 +#define FOCUS_CLICK 2 + +#define DOCK_LEFT 0 +#define DOCK_RIGHT 1 +#define DOCK_UP 2 +#define DOCK_DOWN 3 + +#define ICON_LEFT 0 +#define ICON_RIGHT 1 +#define ICON_UP 2 +#define ICON_DOWN 3 + +#define ACTION_NONE 0 +#define ACTION_EXEC 1 +#define ACTION_ALERT 2 +#define ACTION_MOVE 3 +#define ACTION_RESIZE 4 +#define ACTION_RAISE 5 +#define ACTION_LOWER 6 +#define ACTION_EXIT 7 +#define ACTION_CLEANUP 8 +#define ACTION_SHOW_MENU 9 +#define ACTION_HIDE_MENU 10 +#define ACTION_RESIZE_H 11 +#define ACTION_RESIZE_V 12 +#define ACTION_KILL 13 +#define ACTION_KILL_NASTY 14 +#define ACTION_DESKTOP_NEXT 15 +#define ACTION_DESKTOP_PREV 16 +#define ACTION_DESKTOP_RAISE 17 +#define ACTION_DESKTOP_LOWER 18 +#define ACTION_DESKTOP_DRAG 19 +#define ACTION_STICK 20 +#define ACTION_DESKTOP_INPLACE 21 +#define ACTION_DRAG_BUTTON 22 +#define ACTION_FOCUSMODE_SET 23 +#define ACTION_MOVEMODE_SET 24 +#define ACTION_RESIZEMODE_SET 25 +#define ACTION_SLIDEMODE_SET 26 +#define ACTION_CLEANUPSILDE_SET 27 +#define ACTION_MAPSLIDE_SET 28 +#define ACTION_SOUND_SET 29 +#define ACTION_BUTTONMOVE_RESIST_SET 30 +#define ACTION_DESKTOPBG_TIMEOUT_SET 31 +#define ACTION_MAPSLIDE_SPEED_SET 32 +#define ACTION_CLEANUPSLIDE_SPEED_SET 33 +#define ACTION_DRAGDIR_SET 34 +#define ACTION_DRAGBAR_ORDER_SET 35 +#define ACTION_DRAGBAR_WIDTH_SET 36 +#define ACTION_DRAGBAR_LENGTH_SET 37 +#define ACTION_DESKSLIDE_SET 38 +#define ACTION_DESKSLIDE_SPEED_SET 39 +#define ACTION_HIQUALITYBG_SET 40 +#define ACTION_PLAYSOUNDCLASS 41 +#define ACTION_GOTO_DESK 42 +#define ACTION_DESKRAY 43 +#define ACTION_AUTOSAVE_SET 44 +#define ACTION_HIDESHOW_BUTTON 45 +#define ACTION_ICONIFY 46 +#define ACTION_SLIDEOUT 47 +#define ACTION_SCROLL_WINDOWS 48 +#define ACTION_SHADE 49 +#define ACTION_MAX_HEIGHT 50 +#define ACTION_MAX_WIDTH 51 +#define ACTION_MAX_SIZE 52 +#define ACTION_SEND_TO_NEXT_DESK 53 +#define ACTION_SEND_TO_PREV_DESK 54 +#define ACTION_SNAPSHOT 55 +#define ACTION_SCROLL_CONTAINER 56 +#define ACTION_TOOLTIP_SET 57 +#define ACTION_FOCUS_NEXT 58 +#define ACTION_FOCUS_PREV 59 +#define ACTION_FOCUS_SET 60 +#define ACTION_BACKGROUND_SET 61 +#define ACTION_AREA_SET 62 +#define ACTION_MOVE_BY 63 +#define ACTION_TOGGLE_FIXED 64 +#define ACTION_SET_LAYER 65 +#define ACTION_WARP_POINTER 66 +#define ACTION_MOVE_WINDOW_TO_AREA 67 +#define ACTION_MOVE_WINDOW_BY_AREA 68 +#define ACTION_SET_WINDOW_BORDER 69 +#define ACTION_LINEAR_AREA_SET 70 +#define ACTION_LINEAR_MOVE_BY 71 +#define ACTION_ABOUT 72 +#define ACTION_FX 73 +#define ACTION_MOVE_WINDOW_TO_LINEAR_AREA 74 +#define ACTION_MOVE_WINDOW_BY_LINEAR_AREA 75 +#define ACTION_SET_PAGER_HIQ 76 +#define ACTION_SET_PAGER_SNAP 77 +#define ACTION_CONFIG 78 +#define ACTION_MOVE_CONSTRAINED 79 +#define ACTION_INSERT_KEYS 80 +#define ACTION_START_GROUP 81 +#define ACTION_ADD_TO_GROUP 82 +#define ACTION_REMOVE_FROM_GROUP 83 +#define ACTION_BREAK_GROUP 84 +#define ACTION_SHOW_HIDE_GROUP 85 +#define ACTION_CREATE_ICONBOX 86 +#define ACTION_RAISE_LOWER 87 +#define ACTION_ZOOM 88 +/* false number excluding the above list */ +#define ACTION_NUMBEROF 89 + +#define MODE_NONE 0 +#define MODE_MOVE 1 +#define MODE_RESIZE 2 +#define MODE_RESIZE_H 3 +#define MODE_RESIZE_V 4 +#define MODE_DESKDRAG 5 +#define MODE_BUTTONDRAG 6 +#define MODE_DESKRAY 7 +#define MODE_PAGER_DRAG_PENDING 8 +#define MODE_PAGER_DRAG 9 + +#define EVENT_MOUSE_DOWN 0 +#define EVENT_MOUSE_UP 1 +#define EVENT_MOUSE_ENTER 2 +#define EVENT_MOUSE_LEAVE 3 +#define EVENT_KEY_DOWN 4 +#define EVENT_KEY_UP 5 +#define EVENT_DOUBLE_DOWN 6 + +typedef struct _menu Menu; +typedef struct _dialog Dialog; +typedef struct _pager Pager; +typedef struct _snapshot Snapshot; +typedef struct _iconbox Iconbox; +typedef struct _group Group; + +typedef struct _icondef + { + char *title_match; + char *name_match; + char *class_match; + char *icon_file; + } +Icondef; + +typedef struct _exid + { + Window parent; + Window win; + int x, y, w, h; + char mapped; + int num_rect; + int ord; + XRectangle *rects; + int depth; + Pixmap bgpmap; + int bgcol; + } +EXID; + +typedef struct _actiontype + { + void *params; + struct _actiontype *Next; + int Type; + } +ActionType; + +typedef struct _list + { + char *name; + int id; + void *item; + + struct _list *next; + } +List; + +typedef struct _client + { + char *name; + Window win; + char *msg; + char *clientname; + char *version; + char *author; + char *email; + char *web; + char *address; + char *info; + Pixmap pmap; + } +Client; + +typedef struct _root + { + Window win; + Visual *vis; + int depth; + Colormap cmap; + int scr; + int w, h; + Window focuswin; + } +Root; + +typedef struct _modcurve + { + int num; + unsigned char *px; + unsigned char *py; + unsigned char map[256]; + } +ModCurve; + +typedef struct _colormodifierclass + { + char *name; + ModCurve red, green, blue; + unsigned int ref_count; + } +ColorModifierClass; + +typedef struct _imagestate + { + char *im_file; + char *real_file; + char unloadable; + ImlibImage *im; + ImlibColor *transp; + ImlibBorder *border; + int pixmapfillstyle; + ImlibColor bg, hi, lo, hihi, lolo; + int bevelstyle; + ColorModifierClass *colmod; + } +ImageState; + +typedef struct _ImageStateArray + { + ImageState *normal; + ImageState *hilited; + ImageState *clicked; + ImageState *disabled; + } +ImageStateArray; + +typedef struct _imageclass + { + char *name; + char external; + ImageStateArray norm, active, sticky, sticky_active; + ImlibBorder padding; + ColorModifierClass *colmod; + unsigned int ref_count; + } +ImageClass; + +typedef struct _efont + { + TT_Engine engine; + TT_Face face; + TT_Instance instance; + TT_Face_Properties properties; + int num_glyph; + TT_Glyph *glyphs; + TT_Raster_Map **glyphs_cached; + int max_descent; + int max_ascent; + } +Efont; + +typedef struct _textstate + { + char *fontname; + FnlibStyle style; + FnlibFont *font; + ImlibColor fg_col; + ImlibColor bg_col; + int effect; + Efont *efont; + XFontStruct *xfont; + XFontSet xfontset; + int xfontset_ascent; + } +TextState; + +typedef struct _textclass + { + char *name; + struct + { + TextState *normal; + TextState *hilited; + TextState *clicked; + TextState *disabled; + } + norm , active, sticky, sticky_active; + int justification; + unsigned int ref_count; + } +TextClass; + +typedef struct _action + { + char event; + char anymodifier; + int modifiers; + char anybutton; + int button; + char anykey; + KeyCode key; + char *key_str; + char *tooltipstring; + ActionType *action; + } +Action; + +typedef struct _actionclass + { + char *name; + int num; + Action **list; + char *tooltipstring; + unsigned int ref_count; + } +ActionClass; + +typedef struct _constraints + { + int min, max; + } +Constraints; + +typedef struct _winpoint + { + int originbox; + struct + { + int percent; + int absolute; + } + x , y; + } +WinPoint; + +typedef struct _geometry + { + Constraints width, height; + WinPoint topleft, bottomright; + } +Geometry; + +typedef struct _ecursor + { + char *name; + ImlibColor fg, bg; + char *file; + Cursor cursor; + unsigned int ref_count; + char inroot; + } +ECursor; + +typedef struct _winpart + { + Geometry geom; + ImageClass *iclass; + ActionClass *aclass; + TextClass *tclass; + ECursor *ec; + char ontop; + int flags; + char keep_for_shade; + } +WinPart; + +typedef struct _border + { + char *name; + char *group_border_name; + ImlibBorder border; + int num_winparts; + WinPart *part; + char changes_shape; + char shadedir; + unsigned int ref_count; + } +Border; + +typedef struct _ewinbit + { + Window win; + int x, y, w, h; + int cx, cy, cw, ch; + int state; + char expose; + char no_expose; + char left; + } +EWinBit; + +typedef struct _winclient + { + Window win; + char *title; + int x, y, w, h; + Colormap cmap; + Window icon_win; + Pixmap icon_pmap; + Pixmap icon_mask; + char start_iconified; + Window group; + Window client_leader; + char need_input; + char transient; + Window transient_for; + char *class; + char *name; + char *role; + char *command; + char *machine; + char *icon_name; + char is_group_leader; + char no_resize_h; + char no_resize_v; + char shaped; + Constraints width, height; + int base_w, base_h; + int w_inc, h_inc; + double aspect_min, aspect_max; + char already_placed; + char mwm_decor_border; + char mwm_decor_resizeh; + char mwm_decor_title; + char mwm_decor_menu; + char mwm_decor_minimize; + char mwm_decor_maximize; + char mwm_func_resize; + char mwm_func_move; + char mwm_func_minimize; + char mwm_func_maximize; + char mwm_func_close; + unsigned int app_state; + } +WinClient; + +typedef struct _ewin + { + Window win; + int x, y, w, h, reqx, reqy; + int lx, ly, lw, lh; + char toggle; + Window win_container; + WinClient client; + Border *border; + Border *previous_border; + char border_new; + EWinBit *bits; + int flags; + int desktop; + Group *group; + int docked; + char sticky; + char visible; + char iconified; + char shaded; + char active; + int layer; + char never_use_area; + Window parent; + char floating; + char shapedone; + char fixedpos; + int expanded_x; + int expanded_y; + int expanded_width; + int expanded_height; + char ignorearrange; + char skiptask; + char skipfocus; + char skipwinlist; + char focusclick; + char internal; + Menu *menu; + Window shownmenu; + Dialog *dialog; + Pager *pager; + Iconbox *ibox; + int area_x; + int area_y; + char *session_id; + int has_transients; + int mini_w, mini_h; + Pixmap mini_pmap, mini_mask; + Snapshot *snap; + int icon_pmap_w, icon_pmap_h; + Pixmap icon_pmap, icon_mask; + } +EWin; + +struct _group + { + int index; + int ref_count; + /* these are flags that define what is applied to the whole group */ + char iconify; + char kill; + char move; + char raise; + char set_border; + char stick; + char shade; + }; + +typedef struct _awaiticlass + { + Window client_win; + int ewin_bit; + ImageClass *iclass; + } +AwaitIclass; + +typedef struct _bgeometry + { + Constraints width, height; + int xorigin, yorigin; + int xabs, xrel; + int yabs, yrel; + int xsizerel, xsizeabs; + int ysizerel, ysizeabs; + char size_from_image; + } +BGeometry; + +typedef struct _strip Strip; +typedef struct _stripjoint Stripjoint; + +typedef struct _button + { + char *name; + BGeometry geom; + ImageClass *iclass; + ActionClass *aclass; + TextClass *tclass; + char *label; + char ontop; + int flags; + char sticky; + int desktop; + char visible; + char internal; + char default_show; + char used; + + Window win; + int x, y, w, h; + int cx, cy, cw, ch; + int state; + char expose; + Window inside_win; + Window event_win; + char destroy_inside_win; + char left; + unsigned int ref_count; + } +Button; + +typedef struct _buttoncontainer + { + char *name; + ImageClass *iclass; + + Window win; + int w, h; + int state; + char expose; + char orientation; + Button **ButtonList; + int numofbuttonsinlist; + } +Container; + +struct _strip + { + char *name; + int xabs, yabs; + int xrel, yrel; + char ontop; + char sticky; + int desktop; + char orientation; + char out; + int justification; + int spacing; + + char *anchor_name; + char *bg_name; + Button *anchor; + Button *bg; + + int num_buttons; + Button *button; + + Window win; + int x, y, w, h; + int cx, cy, cw, ch; + }; + +typedef struct _background + { + char *name; + Pixmap pmap; + time_t last_viewed; + struct _bg + { + ImlibColor solid; + char *file; + char *real_file; + ImlibImage *im; + char tile; + char keep_aspect; + int xjust, yjust; + int xperc, yperc; + } + bg; + struct _top + { + char *file; + char *real_file; + ImlibImage *im; + char keep_aspect; + int xjust, yjust; + int xperc, yperc; + } + top; + ColorModifierClass *cmclass; + char keepim; + unsigned int ref_count; + } +Background; + +typedef struct _desk + { + char viewable; + Window win; + int x, y; + Background *bg; + int num; + EWin **list; + Button *tag; + int current_area_x; + int current_area_y; + } +Desk; + +typedef struct _desktops + { + int current; + Desk desk[ENLIGHTENMENT_CONF_NUM_DESKTOPS]; + int dragdir; + int dragbar_width; + int dragbar_ordering; + int dragbar_length; + char slidein; + int slidespeed; + char hiqualitybg; + } +Desktops; + +typedef struct _sample + { + char *file; + int rate; + int format; + int samples; + unsigned char *data; + int id; + } +Sample; + +typedef struct _soundclass + { + char *name; + char *file; + Sample *sample; + unsigned int ref_count; + } +SoundClass; + +typedef struct _windowmatch + { + char *name; + char *win_title; + char *win_name; + char *win_class; + Constraints width; + Constraints height; + signed char transient; + signed char no_resize_h; + signed char no_resize_v; + signed char shaped; + Border *border; + ImageClass *icon; + int desk; + char make_sticky; + } +WindowMatch; + +typedef struct + { + char *name; + char direction; + int num_buttons; + Button **button; + int w, h; + Window win; + Window from_win; + unsigned int ref_count; + } +Slideout; + +typedef struct _emode + { + int mode; + int deskmode; + char place; + char flipp; + char startup; + int next_move_x_plus; + int next_move_y_plus; + EWin *ewin; + Button *button; + int resize_detail; + int win_x, win_y, win_w, win_h; + int start_x, start_y; + char noewin; + char have_place_grab; + int focusmode; + char dockdirmode; + char primaryicondir; + char click_focus_grabbed; + EWin *focuswin; + EWin *realfocuswin; + EWin *mouse_over_win; + EWin *context_ewin; + int px, py, x, y; + char firstlast; + int movemode; + int resizemode; + int slidemode; + char cleanupslide; + char mapslide; + int slidespeedmap; + int slidespeedcleanup; + int shadespeed; + char doingslide; + int server_grabbed; + int desktop_bg_timeout; + int deskdrag; + char sound; + int button_move_resistance; + char button_move_pending; + Colormap current_cmap; + char autosave; + char memory_paranoia; + char destroy; + char adestroy; + Slideout *slideout; + Window context_win; + char tooltips; + double tiptime; + char autoraise; + double autoraisetime; + int dockstartx; + int dockstarty; + char save_under; + char cur_menu_mode; + int cur_menu_depth; + Menu *cur_menu[256]; + char menuslide; + char numdesktops; + char transientsfollowleader; + char switchfortransientmap; + char showicons; + char snap; + int edge_snap_dist; + int screen_snap_dist; + Window menu_cover_win; + char all_new_windows_get_focus; + char new_transients_get_focus; + char new_transients_get_focus_if_group_focused; + char manual_placement; + char raise_on_next_focus; + char raise_after_next_focus; + char display_warp; + char warp_on_next_focus; + char warp_after_next_focus; + int edge_flip_resistance; + EWin *moveresize_pending_ewin; + char borderpartpress; + char windowdestroy; + int context_w; + int context_h; + char autoupgrade; + char activenetwork; + int motddate; + char motd; + char alreadytestingnetwork; + char show_pagers; + Pager *context_pager; + char pager_hiq; + char pager_snap; + char user_bg; + char pager_zoom; + char pager_title; + char constrained; + int pager_scanspeed; + TextClass *icon_textclass; + int icon_mode; + } +EMode; + +typedef struct _handlestruct + { + void (*func) (XEvent * ev); + } +HandleStruct; + +typedef struct _IPCstruct + { + void (*func) (char *params, Client * c); + char *commandname; + char *help_text; + char *extended_help_text; + } +IPCStruct; + +typedef struct _drawqueue + { + Window win; + ImageClass *iclass; + int w, h, active, sticky, state, expose; + TextClass *tclass; + char *text; + char shape_propagate; + Pager *pager; + Pager *redraw_pager; + char newbg; + } +DrawQueue; + +typedef struct _tooltip + { + char *name; + + ImageClass *iclass; + ImageClass *s_iclass[4]; + TextClass *tclass; + int dist; + Window win; + Window iwin; + Window s_win[4]; + char visible; + ImageClass *tooltippic; + unsigned int ref_count; + } +ToolTip; + +typedef struct _qentry + { + char *name; + double in_time; + void (*func) (int val, void *data); + struct _qentry *next; + int runtime_val; + void *runtime_data; + char just_added; + } +Qentry; + +typedef struct _menustyle + { + char *name; + TextClass *tclass; + ImageClass *bg_iclass; + ImageClass *item_iclass; + ImageClass *sub_iclass; + char use_item_bg; + char iconpos; + int maxx; + int maxy; + char *border_name; + unsigned int ref_count; + } +MenuStyle; + +typedef struct _menuitem + { + ImageClass *icon_iclass; + char *text; + short act_id; + void *params; + Menu *child; + char state; + Pixmap pmap[3]; + Pixmap mask[3]; + Window win; + Window icon_win; + short icon_w; + short icon_h; + short text_w; + short text_h; + short text_x; + short text_y; + } +MenuItem; + +struct _menu + { + char *name; + char *title; + MenuStyle *style; + int num; + MenuItem **items; + Window win; + Pixmap pmap; + Pixmap mask; + char stuck; + Menu *parent; + MenuItem *sel_item; + time_t last_change; + void *data; + Menu *ref_menu; + unsigned int ref_count; + }; + +typedef struct _progressbar + { + char *name; + int value; + int x; + int y; + int w; + int h; + Window win; + Window n_win; + Window p_win; + ImageClass *ic, *inc, *ipc; + TextClass *tc, *tnc; + } +Progressbar; + +struct _snapshot + { + char *name; + char *win_title; + char *win_name; + char *win_class; + char *border_name; + char use_desktop; + int desktop; + int area_x, area_y; + char use_wh; + int w, h; + char use_xy; + int x, y; + char use_layer; + int layer; + char use_sticky; + char sticky; + char *iclass_name; + char use_shade; + char shade; + char use_cmd; + char *cmd; + char apply_to_all; + int used; + }; + +typedef struct _ditembutton DItemButton; +typedef struct _ditemcheckbutton DItemCheckButton; +typedef struct _ditemtext DItemText; +typedef struct _ditemimage DItemImage; +typedef struct _ditemseparator DItemSeparator; +typedef struct _ditemtable DItemTable; +typedef struct _ditemradiobutton DItemRadioButton; +typedef struct _ditemslider DItemSlider; +typedef struct _ditemarea DItemArea; +typedef struct _ditem DItem; + +struct _ditemslider + { + char horizontal; + + char numeric; + char numeric_side; + + int upper; + int lower; + int unit; + int jump; + int val; + int *val_ptr; + + int min_length; + + int base_orig_w, base_orig_h; + int knob_orig_w, knob_orig_h; + int border_orig_w, border_orig_h; + + int base_x, base_y, base_w, base_h; + int knob_x, knob_y, knob_w, knob_h; + int border_x, border_y, border_w, border_h; + int numeric_x, numeric_y, numeric_w, numeric_h; + + ImageClass *ic_base; + ImageClass *ic_knob; + ImageClass *ic_border; + + char in_drag; + int wanted_val; + + Window base_win; + Window knob_win; + Window border_win; + }; + +struct _ditemarea + { + Window area_win; + int w, h; + void (*event_func) (int val, void *data); + }; + +struct _ditembutton + { + char *text; + }; + +struct _ditemcheckbutton + { + char *text; + Window check_win; + int check_orig_w, check_orig_h; + char onoff; + char *onoff_ptr; + }; + +struct _ditemtext + { + char *text; + }; + +struct _ditemimage + { + char *image; + }; + +struct _ditemseparator + { + char horizontal; + }; + +struct _ditemtable + { + int num_columns; + char border; + char homogenous_h; + char homogenous_v; + int num_items; + DItem **items; + }; + +struct _ditemradiobutton + { + char *text; + Window radio_win; + int radio_orig_w, radio_orig_h; + char onoff; + int val; + int *val_ptr; + DItem *next; + DItem *first; + }; + +#define DITEM_NONE 0 +#define DITEM_BUTTON 1 +#define DITEM_CHECKBUTTON 2 +#define DITEM_TEXT 3 +#define DITEM_IMAGE 4 +#define DITEM_SEPARATOR 5 +#define DITEM_TABLE 6 +#define DITEM_RADIOBUTTON 7 +#define DITEM_SLIDER 8 +#define DITEM_AREA 9 + +struct _ditem + { + int type; + void (*func) (int val, void *data); + int val; + void *data; + ImageClass *iclass; + TextClass *tclass; + ImlibBorder padding; + char fill_h; + char fill_v; + int align_h; + int align_v; + int row_span; + int col_span; + + int x, y, w, h; + char hilited; + char clicked; + Window win; + union + { + DItemButton button; + DItemCheckButton check_button; + DItemText text; + DItemTable table; + DItemImage image; + DItemSeparator separator; + DItemRadioButton radio_button; + DItemSlider slider; + DItemArea area; + } + item; + }; + +typedef struct _dbutton + { + char *text; + void (*func) (int val, void *data); + Window win; + int x, y, w, h; + char hilited; + char clicked; + char close; + TextClass *tclass; + ImageClass *iclass; + } +DButton; + +typedef struct _Dkeybind + { + KeyCode key; + int val; + void *data; + void (*func) (int val, void *data); + } +DKeyBind; + +struct _dialog + { + char *name; + char *title; + char *text; + int num_buttons; + Window win; + DButton **button; + TextClass *tclass; + ImageClass *iclass; + int w, h; + DItem *item; + void (*exit_func) (int val, void *data); + int exit_val; + void *exit_data; + int num_bindings; + DKeyBind *keybindings; + }; + +typedef struct _PixImg + { + XImage *xim; + XShmSegmentInfo *shminfo; + Pixmap pmap; + GC gc; + } +PixImg; + +typedef struct _Clone + { + char *name; + Window win; + EWin *ewin; + } +Clone; + +struct _iconbox + { + /* user settings */ + char *name; + char orientation; + char scrollbar_side; + char arrow_side; + char shownames; + char nobg; + int iconsize; + int icon_mode; + + char auto_resize; + char draw_icon_base; + char scrollbar_hide; + + /* internally set stuff */ + int w, h; + int pos; + int max; + char arrow1_hilited; + char arrow1_clicked; + char arrow2_hilited; + char arrow2_clicked; + char icon_clicked; + char scrollbar_hilited; + char scrollbar_clicked; + char scrollbox_clicked; + + Pixmap pmap; + + Window win; + Window cover_win; + Window icon_win; + Window scroll_win; + Window arrow1_win; + Window arrow2_win; + Window scrollbar_win; + Window scrollbarknob_win; + EWin *ewin; + + int num_icons; + EWin **icons; + + /* these are theme-settable parameters */ + int scroll_thickness; + int arrow_thickness; + int bar_thickness; + int knob_length; + + }; + +struct _pager + { + char *name; + Window win; + Pixmap pmap; + Pixmap bgpmap; + int desktop; + int w, h; + int dw, dh; + char visible; + int update_phase; + EWin *ewin; + char *border_name; + Window sel_win; + char hi_visible; + Window hi_win; + EWin *hi_ewin; + }; + +void Efont_extents(Efont * f, char *text, + int *font_ascent_return, + int *font_descent_return, int *width_return, + int *max_ascent_return, + int *max_descent_return, + int *lbearing_return, int *rbearing_return); +Efont *Efont_load(char *file, int size); +void Efont_free(Efont * f); +void EFont_draw_string(Display * disp, Drawable win, GC gc, + int x, int y, char *text, + Efont * font, Visual * vis, Colormap cm); + +void ErrAlert(int erno); + +void EDisplayMemUse(void); +int EExit(void *code); +void ShowEdgeWindows(void); +void HideEdgeWindows(void); +int IsEdgeWin(Window win); +void EdgeHandleEnter(XEvent * ev); +void EdgeHandleLeave(XEvent * ev); +void EdgeHandleMotion(XEvent * ev); + +/* lists.c functions */ +void *FindItem(char *name, int id, int find_by, int type); +void AddItem(void *item, char *name, int id, int type); +void AddItemEnd(void *item, char *name, int id, int type); +void *RemoveItem(char *name, int id, int find_by, int type); +void *RemoveItemByPtr(void *ptritem, int type); +void **ListItemType(int *num, int type); +char **ListItems(int *num, int type); +void **ListItemTypeID(int *num, int type, int id); +void **ListItemTypeName(int *num, int type, char *name); +void MoveItemToListTop(void *item, int type); +void ListChangeItemID(int type, void *ptr, int id); +void MoveItemToListBottom(void *item, int type); + +void SetupFallbackClasses(void); +void SetupInit(void); + +void MapUnmap(int start); +void SetupSignals(void); +void SetupX(void); +void SetupDirs(void); +void SetupEnv(void); +Window MakeExtInitWin(void); + +void HandleSigHup(int num); +void HandleSigInt(int num); +void HandleSigQuit(int num); +void HandleSigIll(int num); +void HandleSigAbrt(int num); +void HandleSigFpe(int num); +void HandleSigSegv(int num); +void HandleSigPipe(int num); +void HandleSigAlrm(int num); +void HandleSigTerm(int num); +void HandleSigUsr1(int num); +void HandleSigUsr2(int num); +void HandleSigChild(int num); +void HandleSigTstp(int num); +void HandleSigBus(int num); +void EHandleXError(Display * d, XErrorEvent * ev); +void HandleXIOError(Display * d); + +void CommsSetup(void); +void CommsFindCommsWindow(void); +void CommsSend(Client * c, char *s); +void CommsSendToMasterWM(char *s); +char *CommsGet(Client ** c, XEvent * ev); +void CommsBroadcast(char *s); +void CommsBroadcastToSlaveWMs(char *s); +Client *MakeClient(Window win); +void ListFreeClient(void *ptr); +void DeleteClient(Client * c); +void HandleComms(XEvent * ev); +void DisplayClientInfo(Client * c, int onoff); +void HideClientInfo(void); + +void EMoveWindow(Display * d, Window win, int x, int y); +void EResizeWindow(Display * d, Window win, int w, int h); +void EMoveResizeWindow(Display * d, Window win, int x, int y, + int w, int h); +void EDestroyWindow(Display * d, Window win); +void EMapWindow(Display * d, Window win); +void EUnmapWindow(Display * d, Window win); +void EShapeCombineMask(Display * d, Window win, int dest, + int x, int y, Pixmap pmap, int op); +void EShapeCombineRectangles(Display * d, Window win, int dest, + int x, int y, XRectangle * rect, + int n_rects, int op, int ordering); +void EShapeCombineShape(Display * d, Window win, int dest, + int x, int y, Window src_win, + int src_kind, int op); +XRectangle *EShapeGetRectangles(Display * d, Window win, int dest, + int *rn, int *ord); +void EReparentWindow(Display * d, Window win, Window parent, + int x, int y); +void EMapRaised(Display * d, Window win); +int EGetGeometry(Display * d, Window win, Window * root_return, + int *x, int *y, unsigned int *w, + unsigned int *h, unsigned int *bw, + unsigned int *depth); +void EConfigureWindow(Display * d, Window win, unsigned int mask, + XWindowChanges * wc); +void ESetWindowBackgroundPixmap(Display * d, Window win, + Pixmap pmap); +void ESetWindowBackground(Display * d, Window win, int col); +EXID *NewXID(void); +void AddXID(EXID * xid); +EXID *FindXID(Window win); +void DelXID(Window win); +Pixmap ECreatePixmap(Display * display, Drawable d, + unsigned int width, unsigned int height, + unsigned depth); +void EFreePixmap(Display * display, Pixmap pixmap); +Window ECreateWindow(Window parent, int x, int y, int w, int h, + int saveunder); +Window ECreateEventWindow(Window parent, int x, int y, int w, + int h); +Window ECreateFocusWindow(Window parent, int x, int y, int w, + int h); +void GrabX(void); +void UngrabX(void); +void SetBG(Window win, Pixmap pmap, int color); +void GetWinXY(Window win, int *x, int *y); +void GetWinWH(Window win, unsigned int *w, unsigned int *h); +int GetWinDepth(Window win); +int WinExists(Window win); +Window WindowAtXY_0(Window base, int bx, int by, int x, int y); +Window WindowAtXY(int x, int y); +void PointerAt(int *x, int *y); +void PastePixmap(Display * d, Drawable w, Pixmap p, Mask m, int x, int y); +void PasteMask(Display * d, Drawable w, Pixmap p, int x, int y, int wd, int ht); + +char *NukeBoringevents(XEvent * ev, int num); +void DebugEvent(XEvent * ev); +void HandleEvent(XEvent * ev); +void CheckEvent(void); +void WaitEvent(void); + +void DetermineEwinFloat(EWin * ewin, int dx, int dy); +void SetEInfoOnAll(void); +EWin *GetEwinPointerInClient(void); +EWin *GetEwin(void); +EWin *GetFocusEwin(void); +void SlideEwinTo(EWin * ewin, int fx, int fy, int tx, int ty, + int speed); +void SlideEwinsTo(EWin ** ewin, int *fx, int *fy, int *tx, + int *ty, int num_wins, int speed); +void AddToFamily(Window win); +EWin *AddInternalToFamily(Window win, char noshow, char *bname); +void SetEwinBorder(EWin * ewin); +void SetEwinToBorder(EWin * ewin, Border * b); +void HonorIclass(char *s, int id); +void SyncBorderToEwin(EWin * ewin); +void UpdateBorderInfo(EWin * ewin); +void RealiseEwinWinpart(EWin * ewin, int i); +int DrawEwinWinpart(EWin * ewin, int i); +int ChangeEwinWinpart(EWin * ewin, int i); +void DrawEwin(EWin * ewin); +int ChangeEwinWinpartContents(EWin * ewin, int i); +void CalcEwinWinpart(EWin * ewin, int i); +void CalcEwinSizes(EWin * ewin); +EWin *Adopt(Window win); +EWin *AdoptInternal(Window win, Border * border); +EWin *CreateEwin(void); +void FreeEwin(EWin * ewin); + +/* windowmatch.c functions */ +WindowMatch *CreateWindowMatch(char *name); +char TestWindowMatch(EWin * ewin, WindowMatch * b); +Border *MatchEwinBorder(EWin * ewin, WindowMatch * b); +ImageClass *MatchEwinIcon(EWin * ewin, WindowMatch * b); +int MatchEwinDesktop(EWin * ewin, WindowMatch * b); +void *MatchEwinByFunction(EWin * ewin, + void * (*FunctionToTest) (EWin *, WindowMatch *)); +void RemoveWindowMatch(WindowMatch * wm); + +/* borders.c functions */ +void ResizeEwin(EWin * ewin, int w, int h); +void DetermineEwinArea(EWin * ewin); +void MoveEwin(EWin * ewin, int x, int y); +void MoveResizeEwin(EWin * ewin, int x, int y, int w, int h); +void FloatEwin(EWin * ewin); +void FloatEwinAt(EWin * ewin, int x, int y); +void RestackEwin(EWin * ewin); +void RaiseEwin(EWin * ewin); +void LowerEwin(EWin * ewin); +void ShowEwin(EWin * ewin); +void HideEwin(EWin * ewin); +void FreeBorder(Border * b); +Border *CreateBorder(char *name); +void AddBorderPart(Border * b, ImageClass * iclass, + ActionClass * aclass, TextClass * tclass, + ECursor * ec, + char ontop, int flags, char isregion, + int wmin, int wmax, int hmin, int hmax, + int torigin, int txp, int txa, int typ, + int tya, int borigin, int bxp, int bxa, + int byp, int bya, char keep_for_shade); +void MinShadeSize(EWin * ewin, int *mw, int *mh); +void InstantShadeEwin(EWin * ewin); +void InstantUnShadeEwin(EWin * ewin); +void ShadeEwin(EWin * ewin); +void UnShadeEwin(EWin * ewin); + +/* iclass.c functions */ +ImageClass *CreateIclass(void); +void FreeImageState(ImageState * i); +void FreeImageStateArray(ImageStateArray * isa); +void FreeImageClass(ImageClass * i); +ImageState *CreateImageState(void); +void ImageStatePopulate(ImageState * is); +void ImageStateRealize(ImageState * is); +void IclassPopulate(ImageClass * iclass); +void IclassApply(ImageClass * iclass, Window win, int w, int h, + int active, int sticky, int state, + char expose); +void IclassApplyCopy(ImageClass * iclass, Window win, int w, + int h, int active, int sticky, int state, + Pixmap * pret, Pixmap * mret); + +/* draw.c functions */ +void HandleDrawQueue(void); +char IsPropagateEwinOnQueue(EWin * ewin); +void EFillPixmap(Window win, Pixmap pmap, int x, int y, + int w, int h); +void EPastePixmap(Window win, Pixmap pmap, int x, int y, + int w, int h); +void EBlendRemoveShape(EWin * ewin, Pixmap pmap); +PixImg *ECreatePixImg(Window win, int w, int h); +void EDestroyPixImg(PixImg * pi); +void EBlendPixImg(EWin * ewin, PixImg * s1, PixImg * s2, + PixImg * dst, int x, int y, int w, int h); + +ImlibImage *ELoadImage(char *file); +ImlibImage *ELoadImageImlibData(ImlibData * imd, char *file); +void DrawEwinShape(EWin * ewin, int md, int x, int y, int w, + int h, char firstlast); +void PropagateShapes(Window win); + +void FlipFocusList(void); +void RemoveEwinFromFocusList(EWin * ewin); +void AddEwinToFocusList(EWin * ewin); +void GetNextFocusEwin(void); +void GetPrevFocusEwin(void); +void FixFocus(void); +void FocusToEWin(EWin * ewin); +void FocusToNone(void); +void BeginNewDeskFocus(void); +void NewDeskFocus(void); + +/* icccm.c functions */ +void ICCCM_GetTitle(EWin * ewin, Atom atom_change); +void ICCCM_GetColormap(EWin * ewin); +void ICCCM_Delete(EWin * ewin); +void ICCCM_Save(EWin * ewin); +void ICCCM_Iconify(EWin * ewin); +void ICCCM_DeIconify(EWin * ewin); +void ICCCM_MatchSize(EWin * ewin); +void ICCCM_Configure(EWin * ewin); +void ICCCM_AdoptStart(EWin * ewin, Window win); +void ICCCM_Adopt(EWin * ewin, Window win); +void ICCCM_Withdraw(EWin * ewin); +void ICCCM_Cmap(EWin * ewin); +void ICCCM_Focus(EWin * ewin); +void ICCCM_GetGeoms(EWin * ewin, Atom atom_change); +void ICCCM_GetInfo(EWin * ewin, Atom atom_change); +void ICCCM_GetHints(EWin * ewin, Atom atom_change); +void ICCCM_GetShapeInfo(EWin * ewin); +void ICCCM_SetIconSizes(void); +void ICCCM_SetEInfo(EWin * ewin); +int ICCCM_GetEInfo(EWin * ewin); +void ICCCM_SetMainEInfo(void); +void ICCCM_GetMainEInfo(void); + +/* actions.c functions */ +void GrabButtonGrabs(EWin * ewin); +void UnGrabButtonGrabs(EWin * ewin); +ActionClass *CreateAclass(char *name); +Action *CreateAction(char event, char anymod, int mod, int anybut, + int but, char anykey, char *key, char *tooltipstring); +void RemoveActionType(ActionType * ActionTypeToRemove); +void RemoveAction(Action * ActionToRemove); +void RemoveActionClass(ActionClass * ActionToRemove); +void AddToAction(Action * act, int id, void *params); +void AddAction(ActionClass * a, Action * act); +int EventAclass(XEvent * ev, ActionClass * a); +int handleAction(ActionType * Action); +int spawnMenu(void *params); +int hideMenu(void *params); +int doNothing(void *params); +int execApplication(void *params); +int alert(void *params); +int doExit(void *params); +int doMove(void *params); +int doMoveConstrained(void *params); +int doResize(void *params); +int doResizeH(void *params); +int doResizeV(void *params); +int doResizeEnd(void *params); +int doMoveEnd(void *params); +int doRaise(void *params); +int doLower(void *params); +int doCleanup(void *params); +int doKill(void *params); +int doKillNasty(void *params); +int doNextDesktop(void *params); +int doPrevDesktop(void *params); +int doRaiseDesktop(void *params); +int doLowerDesktop(void *params); +int doDragDesktop(void *params); +int doStick(void *params); +int doInplaceDesktop(void *params); +int doDragButtonStart(void *params); +int doDragButtonEnd(void *params); +int doFocusModeSet(void *params); +int doMoveModeSet(void *params); +int doResizeModeSet(void *params); +int doSlideModeSet(void *params); +int doCleanupSlideSet(void *params); +int doMapSlideSet(void *params); +int doSoundSet(void *params); +int doButtonMoveResistSet(void *params); +int doDesktopBgTimeoutSet(void *params); +int doMapSlideSpeedSet(void *params); +int doCleanupSlideSpeedSet(void *params); +int doDragdirSet(void *params); +int doDragbarOrderSet(void *params); +int doDragbarWidthSet(void *params); +int doDragbarLengthSet(void *params); +int doDeskSlideSet(void *params); +int doDeskSlideSpeedSet(void *params); +int doHiQualityBgSet(void *params); +int doPlaySoundClass(void *params); +int doGotoDesktop(void *params); +int doDeskray(void *params); +int doAutosaveSet(void *params); +int doHideShowButton(void *params); +int doIconifyWindow(void *params); +int doSlideout(void *params); +int doScrollWindows(void *params); +int doShade(void *params); +int doMaxH(void *params); +int doMaxW(void *params); +int doMax(void *params); +int doSendToNextDesk(void *params); +int doSendToPrevDesk(void *params); +int doSnapshot(void *params); +int doScrollContainer(void *params); +int doToolTipSet(void *params); +int doFocusNext(void *params); +int doFocusPrev(void *params); +int doFocusSet(void *params); +int doBackgroundSet(void *params); +int doAreaSet(void *params); +int doAreaMoveBy(void *params); +int doToggleFixedPos(void *params); +int doSetLayer(void *params); +int doWarpPointer(void *params); +int doMoveWinToArea(void *params); +int doMoveWinByArea(void *params); +int doSetWinBorder(void *params); +int doLinearAreaSet(void *params); +int doLinearAreaMoveBy(void *params); +int doAbout(void *params); +int doFX(void *params); +int doMoveWinToLinearArea(void *params); +int doMoveWinByLinearArea(void *params); +int doSetPagerHiq(void *params); +int doSetPagerSnap(void *params); +int doConfigure(void *params); +int doInsertKeys(void *params); +int doCreateIconbox(void *params); +int doRaiseLower(void *params); +int doStartGroup(void *params); +int doAddToGroup(void *params); +int doRemoveFromGroup(void *params); +int doBreakGroup(void *params); +int doShowHideGroup(void *params); +int doZoom(void *params); +int initFunctionArray(void); + +void GrabActionKey(Action * a); +void UnGrabActionKey(Action * a); +void GrabTheButtons(Window win); +int GrabThePointer(Window win); +void UnGrabTheButtons(void); + +char *GetUniqueBGString(Background * bg); +void ChangeNumberOfDesktops(int quantity); +void ShowDesktopControls(void); +void ShowDesktopTabs(void); +void HideDesktopTabs(void); +void MoveToDeskTop(int num); +void MoveToDeskBottom(int num); +void SlideWindowTo(Window win, int fx, int fy, int tx, int ty, + int speed); +void KeepBGimages(Background * bg, char onoff); +void RemoveImagesFromBG(Background * bg); +void FreeDesktopBG(Background * bg); +Background *CreateDesktopBG(char *name, ImlibColor * solid, + char *bg, char tile, char keep_aspect, + int xjust, int yjust, int xperc, int yperc, + char *top, char tkeep_aspect, int txjust, + int tyjust, int txperc, int typerc); +void RefreshCurrentDesktop(void); +void RefreshDesktop(int num); +void SetBackgroundTo(ImlibData * imd, Window win, + Background * dsk, char setbg); +void InitDesktopBgs(void); +void InitDesktopControls(void); +void SetDesktopBg(int desk, Background * bg); +void ConformEwinToDesktop(EWin * ewin); +int DesktopAt(int x, int y); +void MoveStickyWindowsToCurrentDesk(void); +void GotoDesktop(int num); +void MoveDesktop(int num, int x, int y); +void RaiseDesktop(int num); +void LowerDesktop(int num); +void HideDesktop(int num); +void ShowDesktop(int num); +void StackDesktops(void); +void UncoverDesktop(int num); +void MoveEwinToDesktop(EWin * ewin, int num); +void DesktopAddEwinToBottom(EWin * ewin); +void DesktopAddEwinToTop(EWin * ewin); +void DesktopRemoveEwin(EWin * ewin); +void MoveEwinToDesktopAt(EWin * ewin, int num, int x, int y); +void FloatEwinAboveDesktops(EWin * ewin); +void DesktopAccounting(void); + +int AddEToFile(char *file); +int CreateEFile(char *file); +void AddE(void); +void CreateStartupDisplay(char start); + +/* tclass.c */ + +TextClass *CreateTclass(void); +void FreeTextState(TextState * ts); +void DeleteTclass(TextClass * t); +TextState *CreateTextState(void); +void TclassPopulate(TextClass * tclass); +void TclassApply(ImageClass * iclass, Window win, int w, + int h, int active, int sticky, + int state, char expose, + TextClass * tclass, char *text); + +void HandleClientMessage(XEvent * ev); +void HandleFocusWindowIn(Window win); +void HandleFocusWindow(Window win); +void HandleChildShapeChange(XEvent * ev); +void HandleMotion(XEvent * ev); +void HandleDestroy(XEvent * ev); +void HandleProperty(XEvent * ev); +void HandleCirculate(XEvent * ev); +void HandleReparent(XEvent * ev); +void HandleConfigureRequest(XEvent * ev); +void HandleResizeRequest(XEvent * ev); +void HandleUnmap(XEvent * ev); +void HandleMapRequest(XEvent * ev); +void HandleExpose(XEvent * ev); +void HandleMouseDown(XEvent * ev); +void HandleMouseUp(XEvent * ev); +void HandleMouseIn(XEvent * ev); +void HandleMouseOut(XEvent * ev); + +/* dialog.c functions */ +void FocusToEWin(EWin * ewin); +EWin *FindEwinByBase(Window win); +EWin *FindEwinByChildren(Window win); +EWin *FindEwinByDecoration(Window win); +Button *FindButton(Window win); +ActionClass *FindActionClass(Window win); +Menu *FindMenuItem(Window win, MenuItem ** mi); +Menu *FindMenu(Window win); +EWin *FindEwinByMenu(Menu * m); +EWin **ListWinGroupMembers(Group * g, int *num); +EWin **ListWinGroupMembersForEwin(EWin * ewin, int action, int *num); +EWin **ListTransientsFor(Window win, int *num); +EWin **ListGroupMembers(Window win, int *num); +EWin *FindEwinByDialog(Dialog * d); +Dialog *FindDialogButton(Window win, int *bnum); +Dialog *FindDialog(Window win); +EWin *FindEwinSpawningMenu(Menu * m); +Pager *FindPager(Window win); +DItem *FindDialogItem(Window win, Dialog ** dret); + +/* mwm.c functions */ +void MWM_GetHints(EWin * ewin, Atom atom_change); +void MWM_SetInfo(void); + +/* containers.c functions */ +Container *InitializeContainer(char *name, ImageClass * iclass, + int width, int height, char orientation); +void AddButtonToContainer(Container * bc, Button * b); +void RemoveButtonFromContainer(Container * bc, Button * b); +void DestroyContainer(Container * bc); +void RemoveContainer(Container * bc); + +/* buttons.c functions */ +Button *CreateButton(char *name, ImageClass * iclass, + ActionClass * aclass, TextClass * tclass, + char *label, char ontop, int flags, + int minw, int maxw, int minh, int maxh, + int xo, int yo, int xa, int xr, int ya, + int yr, int xsr, int xsa, int ysr, int ysa, + char simg, int desk, char sticky); +void DestroyButton(Button * b); +void CalcButton(Button * b); +void ShowButton(Button * b); +void SimpleShowButton(Button * b); +void MoveButtonToDesktop(Button * b, int num); +void HideButton(Button * b); +void DrawButton(Button * b); +void MovebuttonToCoord(Button * b, int x, int y); +int EmbedWindowIntoButton(Button * ButtonToUse, + Window WindowToEmbed); +void FindEmptySpotForButton(Button * bt, char *listname, + char dirtomove); + +/* atoms.c functions */ +void *AtomGet(Window win, Atom to_get, Atom type, int *size); +void setSimpleHint(Window win, Atom atom, long value); +long *getSimpleHint(Window win, Atom atom); + +/* gnome.c functions */ +void GNOME_GetHintIcons(EWin * ewin, Atom atom_change); +void GNOME_SetCurrentDesk(void); +void GNOME_SetUsedHints(void); +void GNOME_GetExpandedSize(EWin * ewin, Atom atom_change); +void GNOME_GetHintDesktop(EWin * ewin, Atom atom_change); +void GNOME_GetHint(EWin * ewin, Atom atom_change); +void GNOME_GetHintAppState(EWin * ewin, Atom atom_change); +void GNOME_GetHintState(EWin * ewin, Atom atom_change); +void GNOME_GetHintLayer(EWin * ewin, Atom atom_change); +void GNOME_SetEwinArea(EWin * ewin); +void GNOME_SetWMCheck(void); +void GNOME_SetDeskCount(void); +void GNOME_SetDeskNames(void); +void GNOME_SetClientList(void); +void GNOME_GetHints(EWin * ewin, Atom atom_change); +void GNOME_SetHint(EWin * ewin); +void GNOME_SetEwinDesk(EWin * ewin); +void GNOME_SetHints(void); +void GNOME_SetCurrentArea(void); +void GNOME_SetAreaCount(void); +void GNOME_SetWMNameVer(void); +void GNOME_DelHints(EWin * ewin); + +/* kde.c functions */ +void KDE_ClientMessage(EWin * ewin, Atom atom, long data, + Time timestamp); +void KDE_ClientTextMessage(EWin * ewin, Atom atom, char *data); +void KDE_SendMessagesToModules(Atom atom, long data); + +/* sound.c functions */ +Sample *LoadWav(char *file); +void SoundPlay(Sample * s); +void DestroySample(Sample * s); +void DestroySclass(SoundClass * sclass); +SoundClass *CreateSoundClass(char *name, char *file); +void ApplySclass(SoundClass * sclass); +void SoundInit(void); +void SoundExit(void); + +/* regex.c functions */ +int isafter(int p, char *s1, char *s2); +int matchregexp(char *rx, char *s); + +void DoIn(char *name, double in_time, + void (*func) (int val, void *data), + int runtime_val, void *runtime_data); +Qentry *GetHeadTimerQueue(void); +void HandleTimerEvent(void); +void RemoveTimerEvent(char *name); + +/* cmclass.c functions */ +void CreateCurve(ModCurve * c); +void FreeModCurve(ModCurve * c); +void FreeCMClass(ColorModifierClass * cm); +ColorModifierClass *CreateCMClass(char *name, + int rnum, unsigned char *rpx, + unsigned char *rpy, int gnum, + unsigned char *gpx, unsigned char *gpy, + int bnum, unsigned char *bpx, + unsigned char *bpy); +void ModifyCMClass(char *name, + int rnum, unsigned char *rpx, + unsigned char *rpy, int gnum, + unsigned char *gpx, unsigned char *gpy, + int bnum, unsigned char *bpx, + unsigned char *bpy); + +/* config.c functions */ +char *GetLine(char *s, int size, FILE * f); +int testForComment(char *line); +int GetNextLine(char *line, FILE * ConfigFile); +void Config_Text(FILE * ConfigFile); +void Config_Slideout(FILE * ConfigFile); +void Config_Control(FILE * ConfigFile); +void Config_MenuStyle(FILE * ConfigFile); +void Config_Menu(FILE * ConfigFile); +void BorderPartLoad(FILE * ConfigFile, char type, Border * b); +void Config_Border(FILE * ConfigFile); +void Config_Button(FILE * ConfigFile); +void Config_Desktop(FILE * ConfigFile); +void Config_ECursor(FILE * ConfigFile); +void Config_Iconbox(FILE * ConfigFile); +void Config_Sound(FILE * ConfigFile); +void Config_ActionClass(FILE * ConfigFile); +void Config_ImageClass(FILE * ConfigFile); +void Config_ColorModifier(FILE * ConfigFile); +void Config_Extras(FILE * ConfigFile); +void Config_Ibox(FILE * ConfigFile); +void Config_FX(FILE * ConfigFile); +void Config_WindowMatch(FILE * ConfigFile); +int IsWhitespace(const char *s); +FILE *OpenConfigFileForReading(char *path, char preprocess); +void Config_ToolTip(FILE * ConfigFile); +int LoadConfigFile(char *file); +int LoadOpenConfigFile(FILE * ConfigFile); +int LoadStringFiles(void); +char *ExtractTheme(char *theme); +char *FindFile(char *file); +char *FindNoThemeFile(char *file); +char *FindTheme(char *theme); +int LoadEConfig(char *themelocation); +void SaveUserControlConfig(FILE * autosavefile); +void RecoverUserConfig(void); + +void HKeyPress(XEvent * ev); +void HKeyRelease(XEvent * ev); +void HButtonPress(XEvent * ev); +void HButtonRelease(XEvent * ev); +void HMotionNotify(XEvent * ev); +void HEnterNotify(XEvent * ev); +void HLeaveNotify(XEvent * ev); +void HFocusIn(XEvent * ev); +void HFocusOut(XEvent * ev); +void HKeymapNotify(XEvent * ev); +void HExpose(XEvent * ev); +void HGraphicsExpose(XEvent * ev); +void HNoExpose(XEvent * ev); +void HVisibilityNotify(XEvent * ev); +void HCreateNotify(XEvent * ev); +void HDestroyNotify(XEvent * ev); +void HUnmapNotify(XEvent * ev); +void HMapNotify(XEvent * ev); +void HMapRequest(XEvent * ev); +void HReparentNotify(XEvent * ev); +void HConfigureNotify(XEvent * ev); +void HConfigureRequest(XEvent * ev); +void HGravityNotify(XEvent * ev); +void HResizeRequest(XEvent * ev); +void HCirculateNotify(XEvent * ev); +void HCirculateRequest(XEvent * ev); +void HPropertyNotify(XEvent * ev); +void HSelectionClear(XEvent * ev); +void HSelectionRequest(XEvent * ev); +void HSelectionNotify(XEvent * ev); +void HColormapNotify(XEvent * ev); +void HClientMessage(XEvent * ev); +void HMappingNotify(XEvent * ev); +void DefaultFunc(XEvent * ev); + +/* iconify.c functions */ +void IconifyEwin(EWin * ewin); +void DeIconifyEwin(EWin * ewin); +void RemoveMiniIcon(EWin * ewin); +void MakeIcon(EWin * ewin); +void DockIt(EWin * ewin); +void DockDestroy(EWin * ewin); +void HideIcons(void); +void ShowIcons(void); +void HandlePager(void); +Iconbox *CreateIconbox(char *name); +void FreeIconbox(Iconbox * ib); +void ShowIconbox(Iconbox * ib); +void HideIconbox(Iconbox * ib); +void AddEwinToIconbox(Iconbox * ib, EWin * ewin); +void DelEwinFromIconbox(Iconbox * ib, EWin * ewin); +void RedrawIconbox(Iconbox * ib); +void IconboxHandleEvent(XEvent * ev); +void UpdateAppIcon(EWin * ewin, int imode); +void IconboxResize(Iconbox * ib, int w, int h); +void IB_FixPos(Iconbox * ib); +void IB_DrawScroll(Iconbox * ib); +EWin *IB_FindIcon(Iconbox * ib, int px, int py); +void IB_CalcMax(Iconbox * ib); +void IB_Scroll(Iconbox * ib, int dir); +void IB_ShowMenu(Iconbox * ib, int x, int y); +void IB_CompleteRedraw(Iconbox * ib); +void IB_SnapEWin(EWin * ewin); +void IB_GetAppIcon(EWin * ewin); +void IB_PasteDefaultBase(Drawable d, int x, int y, int w, int h); +void IB_PasteDefaultBaseMask(Drawable d, int x, int y, int w, int h); +void IB_GetEIcon(EWin * ewin); +void IB_AddIcondef(char *title, char *name, char *class, char *file); +void IB_RemoveIcondef(Icondef * idef); +Icondef *IB_MatchIcondef(char *title, char *name, char *class); +Icondef **IB_ListIcondef(int *num); +void IB_Setup(void); +void IB_LoadIcodefs(void); +void IB_ReLoadIcodefs(void); +void IB_SaveIcodefs(void); +Iconbox **ListAllIconboxes(int *num); +Iconbox *SelectIconboxForEwin(EWin * ewin); + +/* slideouts.c functions */ +void SlideWindowSizeTo(Window win, int fx, int fy, + int tx, int ty, + int fw, int fh, + int tw, int th, int speed); +Slideout *CreateSlideout(char *name, char dir); +void ShowSlideout(Slideout * s, Window win); +void HideSlideout(Slideout * s, Window w); +void CalcSlideoutSize(Slideout * s); +void AddButtonToSlideout(Slideout * s, Button * b); +void RemoveButtonFromSlideout(Slideout * s, Button * b); + +Strip *CreateStrip(char *name); +void DestroyStrip(Strip * s); +void RotateStripTo(Strip * s, char rot); +void MoveStripTo(Strip * s, int x, int y); +void ShowStrip(Strip * s); +void HideStrip(Strip * s); +void RemoveButtonFromStrip(Strip * s, Button * b); +void AddButtonToStrip(Strip * s, Button * b, int x, int y); +void RepackStrip(Strip * s); +Strip *IsInStrip(int x, int y); + +TextState *TextGetState(TextClass * tclass, int active, int sticky, + int state); +char **TextGetLines(char *text, int *count); +void TextStateLoadFont(TextState * ts); +void TextSize(TextClass * tclass, int active, int sticky, + int state, char *text, int *width, int *height, + int fsize); +void TextDraw(TextClass * tclass, Window win, int active, + int sticky, int state, char *text, int x, int y, + int w, int h, int fsize, int justification); + +void SetupInit(void); + +/* tooltips.c functions */ +ToolTip *CreateToolTip(char *name, + ImageClass * ic0, ImageClass * ic1, + ImageClass * ic2, ImageClass * ic3, + ImageClass * ic4, TextClass * tclass, + int dist, ImageClass * tooltippic); +void ShowToolTip(ToolTip * tt, char *text, ActionClass * ac, + int x, int y); +void HideToolTip(ToolTip * tt); +void FreeToolTip(ToolTip * tt); + +void ShowTaskMenu(void); +void ShowAllTaskMenu(void); +void ShowDeskMenu(void); +Menu *RefreshTaskMenu(int desk); +Menu *RefreshAllTaskMenu(Menu * m); +Menu *RefreshDeskMenu(Menu * m); +void HideMenu(Menu * m); +void ShowMenu(Menu * m, char noshow); +MenuStyle *CreateMenuStyle(void); +MenuItem *CreateMenuItem(char *text, ImageClass * iclass, + int action_id, char *action_params, + Menu * child); +Menu *CreateMenu(void); +void DestroyMenu(Menu * m); +void AddItemToMenu(Menu * menu, MenuItem * item); +void AddTitleToMenu(Menu * menu, char *title); +void RealizeMenu(Menu * m); +void DrawMenuItem(Menu * m, MenuItem * mi, char shape); +Menu *CreateMenuFromDirectory(char *name, MenuStyle * ms, + char *dir); +Menu *CreateMenuFromFlatFile(char *name, MenuStyle * ms, + char *file, Menu * parent); +Menu *CreateMenuFromGnome(char *name, MenuStyle * ms, char *dir); +Menu *CreateMenuFromAllEWins(char *name, MenuStyle * ms); +Menu *CreateMenuFromDesktopEWins(char *name, MenuStyle * ms, int desk); +Menu *CreateMenuFromDesktops(char *name, MenuStyle * ms); +Menu *CreateMenuFromThemes(char *name, MenuStyle * ms); +Menu *CreateMenuFromBorders(char *name, MenuStyle * ms); +void ShowMenuMasker(Menu * m); +void HideMenuMasker(void); +void RepackMenu(Menu * m); +void EmptyMenu(Menu * m); + +void SetNewAreaSize(int ax, int ay); +void GetCurrentArea(int *ax, int *ay); +void SetAreaSize(int aw, int ah); +void GetAreaSize(int *aw, int *ah); +void InitCurrentArea(int ax, int ay); +void SetCurrentArea(int ax, int ay); +void MoveEwinToArea(EWin * ewin, int ax, int ay); +void SetEwinToCurrentArea(EWin * ewin); +void MoveCurrentAreaBy(int ax, int ay); +void SetCurrentLinearArea(int a); +int GetCurrentLinearArea(void); +void MoveCurrentLinearAreaBy(int a); +void SlideWindowsBy(Window * win, int num, int dx, int dy, int speed); +void MoveEwinToLinearArea(EWin * ewin, int a); +void MoveEwinLinearAreaBy(EWin * ewin, int a); + +int Emkstemp(char *template); +void SnapEwin(EWin * ewin, int dx, int dy, int *new_dx, int *new_dy); +void SessionInit(void); +void SessionSave(int shutdown); +void doSMExit(void *params); +void ProcessICEMSGS(void); +int GetSMfd(void); +void SessionGetInfo(EWin * ewin, Atom atom_change); +void SetSMID(char *smid); +void SetSMFile(char *path); +void SetSMUserThemePath(char *path); +char *GetSMFile(void); +char *GetGenericSMFile(void); +void MatchEwinToSM(EWin * ewin); +void SaveSession(int shutdown); +void autosave(void); + +Progressbar *CreateProgressbar(char *name, int width, int height); +void SetProgressbar(Progressbar * p, int progress); +void ShowProgressbar(Progressbar * p); +void HideProgressbar(Progressbar * p); +void FreeProgressbar(Progressbar * p); +Window *ListProgressWindows(int *num); +void RaiseProgressbars(void); + +#if defined(__FILE__) && defined(__LINE__) +#define Efree(x) \ +__Efree(x, __FILE__, __LINE__) +#define Emalloc(x) \ +__Emalloc(x, __FILE__, __LINE__) +#define Erealloc(x, y) \ +__Erealloc(x, y, __FILE__, __LINE__) +void *__Emalloc(int size, const char *file, int line); +void *__Erealloc(void *ptr, int size, const char *file, int line); +void __Efree(void *ptr, const char *file, int line); + +#else +#define Efree(x) \ +free(x); +#define Emalloc(x) \ +malloc(x) +#define Erealloc(x, y) \ +realloc(x, y) +#endif + +char *duplicate(char *s); + +void Alert(char *fmt,...); +void InitStringList(void); +void AssignIgnoreFunction(int (*FunctionToAssign) (void *), void *params); +void AssignRestartFunction(int (*FunctionToAssign) (void *), void *params); +void AssignExitFunction(int (*FunctionToAssign) (void *), void *params); +void AssignTitleText(char *text); +void AssignIgnoreText(char *text); +void AssignRestartText(char *text); +void AssignExitText(char *text); + +void Etmp(char *s); +void md(char *s); +int exists(char *s); +void mkdirs(char *s); +int isfile(char *s); +int isdir(char *s); +char **ls(char *dir, int *num); +void freestrlist(char **l, int num); +void rm(char *s); +void mv(char *s, char *ss); +void cp(char *s, char *ss); +time_t moddate(char *s); +int filesize(char *s); +int fileinode(char *s); +int filedev(char *s); +void cd(char *s); +char *cwd(void); +int permissions(char *s); +int owner(char *s); +int group(char *s); +char *username(int uid); +char *homedir(int uid); +char *usershell(int uid); +char *atword(char *s, int num); +char *atchar(char *s, char c); +char *getword(char *s, int num); +void word(char *s, int num, char *wd); +int canread(char *s); +int canwrite(char *s); +int canexec(char *s); +char *fileof(char *s); +char *fullfileof(char *s); +char *pathtoexec(char *file); +char *pathtofile(char *file); +char *FileExtension(char *file); +char *field(char *s, int field); +int fillfield(char *s, int field, char *buf); +void fword(char *s, int num, char *wd); + +/* cursors.c functions */ +ECursor *CreateECursor(char *name, char *image, ImlibColor * fg, + ImlibColor * bg); +void ApplyECursor(Window win, ECursor * ec); +void FreeECursor(ECursor * ec); + +/* snaps.c functions */ +void SnapshotEwinDialog(EWin * ewin); +Snapshot *FindSnapshot(EWin * ewin); +Snapshot *GetSnapshot(EWin * ewin); +Snapshot *NewSnapshot(char *name); +void SnapshotEwinBorder(EWin * ewin); +void SnapshotEwinDesktop(EWin * ewin); +void SnapshotEwinSize(EWin * ewin); +void SnapshotEwinLocation(EWin * ewin); +void SnapshotEwinLayer(EWin * ewin); +void SnapshotEwinSticky(EWin * ewin); +void SnapshotEwinIcon(EWin * ewin); +void SnapshotEwinShade(EWin * ewin); +void SnapshotEwinCmd(EWin * ewin); +void SnapshotEwinAllInstances(EWin * ewin, char onoff); +void SnapshotEwinAll(EWin * ewin); +void UnsnapshotEwin(EWin * ewin); +void SaveSnapInfo(void); +void SpawnSnappedCmds(void); +void LoadSnapInfo(void); +void MatchEwinToSnapInfo(EWin * ewin); +void MatchEwinToSnapInfoAfter(EWin * ewin); + +void SetCoords(int x, int y, int w, int h); +void HideCoords(void); + +char *append_merge_dir(char *dir, char ***list, int *count); +char **ListThemes(int *number); +char *GetDefaultTheme(void); +void SetDefaultTheme(char *theme); + +char SanitiseThemeDir(char *dir); +void Quicksort(void **a, int l, int r, int (*CompareFunc) (void *d1, void *d2)); + +Dialog *CreateDialog(char *name); +void DialogBindKey(Dialog * d, char *key, + void (*func) (int val, void *data), + int val, void *data); +void FreeDButton(DButton * db); +void FreeDialog(Dialog * d); +void DialogSetText(Dialog * d, char *text); +void DialogSetTitle(Dialog * d, char *title); +void DialogAddButton(Dialog * d, char *text, void (*func) (int val, void *data), char close); +void DialogDrawButton(Dialog * d, int bnum); +void DialogActivateButton(Window win, int inclick); +void DialogDraw(Dialog * d); +void DialogDrawArea(Dialog * d, int x, int y, int w, int h); +void DialogRedraw(Dialog * d); +void ShowDialog(Dialog * d); +void DialogClose(Dialog * d); +void DialogSetParamText(Dialog * d, char *fmt,...); +void DialogAlert(char *fmt,...); +void DialogAlertOK(char *fmt,...); +void DialogRestart(int val, void *data); +void DialogQuit(int val, void *data); +DItem *DialogInitItem(Dialog * d); +DItem *DialogAddItem(DItem * dii, int type); +void DialogItemSetCallback(DItem * di, void (*func) (int val, void *data), int val, char *data); +void DialogItemSetClass(DItem * di, ImageClass * iclass, + TextClass * tclass); +void DialogItemSetPadding(DItem * di, int left, int right, + int top, int bottom); +void DialogItemSetFill(DItem * di, char fill_h, char fill_v); +void DialogItemSetAlign(DItem * di, int align_h, int align_v); +void DialogRealizeItem(Dialog * d, DItem * di); +void DialogDrawItems(Dialog * d, DItem * di, int x, int y, + int w, int h); +void DialogItemsRealize(Dialog * d); +void DialogItemButtonSetText(DItem * di, char *text); +void DialogItemCheckButtonSetText(DItem * di, char *text); +void DialogItemTextSetText(DItem * di, char *text); +void DialogItemCheckButtonSetState(DItem * di, char onoff); +void DialogItemCheckButtonSetPtr(DItem * di, char *onoff_ptr); +void DialogItemTableSetOptions(DItem * di, int num_columns, + char border, char homogenous_h, + char homogenous_v); +void DialogItemSeparatorSetOrientation(DItem * di, + char horizontal); +void DialogItemImageSetFile(DItem * di, char *image); +void DialogFreeItem(DItem * di); +DItem *DialogItemFindWindow(DItem * di, Window win); +void DialogItemSetRowSpan(DItem * di, int row_span); +void DialogItemSetColSpan(DItem * di, int col_span); +void DialogSetExitFunction(Dialog * d, void (*func) (int val, void *data), int val, void *data); +void DialogItemRadioButtonSetText(DItem * di, char *text); +void DialogItemRadioButtonSetFirst(DItem * di, DItem * first); +void DialogItemRadioButtonGroupSetValPtr(DItem * di, int *val_ptr); +void DialogItemRadioButtonGroupSetVal(DItem * di, int val); +void MoveTableBy(Dialog * d, DItem * di, int dx, int dy); +void DialogItemSliderSetVal(DItem * di, int val); +void DialogItemSliderSetBounds(DItem * di, int lower, int upper); +void DialogItemSliderSetUnits(DItem * di, int units); +void DialogItemSliderSetJump(DItem * di, int jump); +void DialogItemSliderSetMinLength(DItem * di, int min); +void DialogItemSliderSetValPtr(DItem * di, int *val_ptr); +void DialogItemSliderSetOrientation(DItem * di, char horizontal); +void DialogItemAreaSetSize(DItem * di, int w, int h); +void DialogItemAreaGetSize(DItem * di, int *w, int *h); +Window DialogItemAreaGetWindow(DItem * di); +void DialogItemAreaSetEventFunc(DItem * di, void (*func) (int val, void *data)); + +Window SC_GetDestWin(void); +void SC_PassEvent(XEvent * ev); +void SC_Main(void); +void SC_Init(void); +void SC_SetWait(void); +void SC_Normal(void); +void SC_SetHotspot(int x, int y); +void SC_SetImage(char *file); +void SC_Kill(void); + +/* fx.c exportable functions */ +void FX_Start(char *name); +void FX_DeskChange(void); +void FX_Pause(void); +char **FX_Active(int *num); +int FX_IsOn(char *effect); +void FX_Deactivate(char *effect); +void FX_Activate(char *effect); + +/* ipc.c functions */ +int HandleIPC(char *params, Client * c); +void ButtonIPC(int val, void *data); + +/* sticky.c functions */ +void MakeWindowSticky(EWin * ewin); +void MakeWindowUnSticky(EWin * ewin); + +/* size.c functions */ +void MaxSize(EWin * ewin, char *resize_type); +void MaxWidth(EWin * ewin, char *resize_type); +void MaxHeight(EWin * ewin, char *resize_type); + +/* modules.c functions */ +int LoadModule(char *module_name); +int UnloadModule(char *module_name); +char *ModuleErrorCodeToString(int error_code); +char *ModuleListAsString(void); +int IsLoadedModule(char *module_name); +char *FindModulePath(char *module_name); + +Clone *CloneEwin(EWin * ewin); +void FreeClone(Clone * c); +void RemoveClones(void); +void CloneDesktop(int d); + +void PagerScaleLine(Pixmap dest, Window src, int dx, int dy, int sw, int pw, int sy, int sh); +void PagerScaleRect(Pixmap dest, Window src, int sx, int sy, int dx, int dy, int sw, int sh, int dw, int dh); +Pager *CreatePager(void); +EWin *EwinInPagerAt(Pager * p, int x, int y); +void PagerResize(Pager * p, int w, int h); +void PagerShow(Pager * p); +void PagerHide(Pager * p); +void PagerTitle(Pager * p, char *title); +void PagerKill(Pager * p); +Pager **PagersForDesktop(int d, int *num); +void RedrawPagersForDesktop(int d, char newbg); +void ForceUpdatePagersForDesktop(int d); +void PagerEwinUpdateMini(Pager * p, EWin * ewin); +void PagerEwinUpdateFromPager(Pager * p, EWin * ewin); +void PagerRedraw(Pager * p, char newbg); +void PagerForceUpdate(Pager * p); +void PagerShowMenu(Pager * p, int x, int y); +void PagerReArea(void); +void PagerEwinOutsideAreaUpdate(EWin * ewin); +void PagerAreaAt(Pager * p, int x, int y, int *ax, int *ay); +void UpdatePagerSel(void); +void PagerHandleMotion(Pager * p, Window win, int x, int y); +void EnableAllPagers(void); +void DisableAllPagers(void); +void PagerHideHi(Pager * p); +void PagerShowHi(Pager * p, EWin * ewin, int x, int y, int w, + int h); +void PagerSetHiQ(char onoff); +void PagerSetSnap(char onoff); +void PagerHideAllHi(void); +void NewPagerForDesktop(int desk); +void EnableSinglePagerForDesktop(int desk); +int PagerForDesktop(int desk); +void DisablePagersForDesktop(int desk); + +int CompareNetVersion(int major, int minor, int patchlevel, + char *date); +int RetrieveUpdate(int major, int minor, int patchlevel, + char *date); +int InstallUpdate(void); +void SpawnNetworkTester(void); +void TestForUpdate(void); +void CheckForNewMOTD(int val, void *data); + +char *GetNetText(char *URL); +time_t GetNetFileDate(char *URL); +int SaveNetFile(char *URL, char *pathtosave); + +void SettingsPager(void); +void SettingsFocus(void); +void SettingsMoveResize(void); +void SettingsDesktops(void); +void SettingsArea(void); +void SettingsPlacement(void); +void SettingsIcons(void); +void SettingsAutoRaise(void); +void SettingsTooltips(void); +void SettingsAudio(void); +void SettingsSpecialFX(void); +void SettingsBackground(Background * bg); +void SettingsIconbox(char *name); +void SettingsGroup(Group * g); + +void BGSettingsGoTo(Background * bg); + +void WarpFocusInitEvents(void); +int WarpFocusHandleEvent(XEvent * event); +void WarpFocus(int delta); + +/* groups.c functions */ +Group *CreateGroup(void); +void BreakWindowGroup(EWin * ewin); +void BuildWindowGroup(EWin ** ewins, int num); +void AddEwinToGroup(EWin * ewin, Group * g); +void RemoveEwinFromGroup(EWin * ewin); + +EWin *GetZoomEWin(void); +void ReZoom(EWin *ewin); +char InZoom(void); +char CanZoom(void); +void ZoomInit(void); +void Zoom(EWin *ewin); + + +extern pid_t master_pid; +extern int master_screen; +extern int display_screens; +extern int single_screen_mode; +extern Display *disp; +extern ImlibData *id; +extern ImlibData *ird; +extern FnlibData *fd; +extern List *lists; +extern int event_base_shape; +extern Window comms_win; +extern Root root; +extern int (*(ActionFunctions[ACTION_NUMBEROF])) (void *); +extern EMode mode; +extern Desktops desks; +extern Window grab_window; +extern Window init_win1; +extern Window init_win2; +extern Window init_win_ext; +extern Window bpress_win; +extern int deskorder[ENLIGHTENMENT_CONF_NUM_DESKTOPS]; +extern int sound_fd; + +#define FILEPATH_LEN_MAX 4096 +extern char themepath[FILEPATH_LEN_MAX]; +extern char themename[FILEPATH_LEN_MAX]; +extern char *command; +extern char mustdel; +extern char queue_up; +extern char just_flipped; +extern Menu *all_task_menu; +extern Menu *task_menu[ENLIGHTENMENT_CONF_NUM_DESKTOPS]; +extern Menu *desk_menu; +extern char no_overwrite; +extern Window external_pager_window; +extern char clickmenu; +extern Window last_bpress; +extern int child_count; +extern pid_t *e_children; +extern int numlock_mask; +extern int scrollock_mask; +extern int mask_mod_combos[8]; +extern Group *current_group; +extern Group *pager_group; + +/* This turns on E's internal stack tracking system for coarse debugging */ +/* and being able to trace E for profiling/optimisation purposes (which */ +/* believe it or not I'm actually doing) */ + +/* #define DEBUG 1 */ diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 00000000..1377a3b8 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,130 @@ +SUBDIRS = themes + +EXTRA_DIST = README ChangeLog + +if FSSTD +bindir=@bindir@ +ENLIGHTENMENT_BIN=@bindir@ +ENLIGHTENMENT_ROOT=$(pkgdatadir) +else +ENLIGHTENMENT_BIN=$(prefix)/enlightenment/bin +ENLIGHTENMENT_ROOT=$(prefix)/enlightenment +bindir=$(ENLIGHTENMENT_BIN) +endif + + +bin_PROGRAMS = enlightenment + +enlightenment_SOURCES = \ + E.h \ + timestamp.h \ + update.h \ + actions.c \ + alert.c \ + areas.c \ + arrange.c \ + arrange.h \ + atoms.c \ + borders.c \ + buttons.c \ + clone.c \ + cmclass.c \ + comms.c \ + conf.h \ + config.c \ + config.h \ + containers.c \ + coords.c \ + cursors.c \ + desktops.c \ + dialog.c \ + dock.c \ + draw.c \ + events.c \ + evhandlers.c \ + file.c \ + finders.c \ + focus.c \ + fx.c \ + globals.c \ + gnome.c \ + grabs.c \ + groups.c \ + handlers.c \ + icccm.c \ + iclass.c \ + iconify.c \ + init.c \ + ipc.c \ + kde.c \ + lists.c \ + main.c \ + memory.c \ + menus.c \ + misc.c \ + modules.c \ + mwm.c \ + network.c \ + pager.c \ + progress.c \ + regex.c \ + scursor.c \ + session.c \ + settings.c \ + setup.c \ + size.c \ + slideout.c \ + snaps.c \ + snprintf.c \ + sound.c \ + startup.c \ + sticky.c \ + stripjoints.c \ + strips.c \ + tclass.c \ + text.c \ + theme.c \ + timers.c \ + tooltips.c \ + ttfont.c \ + update.c \ + warp.c \ + windowmatch.c \ + x.c \ + zoom.c + +LDADD = \ + $(FNLIB_LIBS) \ + $(TTF_LIBS) \ + $(ESD_LIBS) \ + $(IMLIB_LIBS) \ + $(XTST_LIBS) \ + $(XVM_LIBS) \ + $(GHTTP_LIBS) \ + $(DL_LIBS) \ + -lm + +INCLUDES=-I$(top_srcdir) $(ESD_CFLAGS) $(IMLIB_CFLAGS) -I$(includedir) -I.. + +DEFS=-DENLIGHTENMENT_ROOT=\"@ENLIGHTENMENT_ROOT@\" -DENLIGHTENMENT_BIN=\"@ENLIGHTENMENT_BIN@\" + +#install-exec-local: +# if [ x@USE_FSSTD@ = "xno" ]; then \ +# ../mkinstalldirs $(exec_prefix)/bin; \ +# for i in $(bin_PROGRAMS); do \ +# rm -f $(exec_prefix)/bin/$$i; \ +# $(LN_S) $(bindir)/$$i $(exec_prefix)/bin/$$i; \ +# done; \ +# fi + +install-data-local: + $(top_srcdir)/mkinstalldirs $(DESTDIR)$(ENLIGHTENMENT_ROOT)/themes; \ + rm -f $(DESTDIR)$(ENLIGHTENMENT_ROOT)/themes/DEFAULT; \ + $(LN_S) -f \ + BrushedMetal-Tigert \ + $(DESTDIR)$(ENLIGHTENMENT_ROOT)/themes/DEFAULT; + +uninstall-local: + for i in $(bin_PROGRAMS); do \ + rm -f $(exec_prefix)/bin/$$i; \ + done diff --git a/src/README b/src/README new file mode 100644 index 00000000..ace90d15 --- /dev/null +++ b/src/README @@ -0,0 +1,198 @@ ++-----------------------------------------------------------------------------+ +| E N L I G H T E N M E N T | ++-----------------------------------------------------------------------------+ + +Greets go out to: (in alphabetical order particular order) + +Abalynth +Aeonflux +Andrew (the seedy one) +Affa +Allen +Anarchy +Alph +Asc +Aurora +Bigguy +Bwana +Chutt +Colin +C0re +Dan +Donny +Dphase +DrMike +Eidos +Elessar +Eman +Epoch +EricB +Ewen +F-R-E-D +Facility +Finona +Glenn +Gnatti +Gnea +Gus +Haigos +Hans +Hormz +Hilarion +Kane +Kara +Keebler +Jad3d +Jaded +Jason (Fungus) +Jim +Jirah +Johnatan +Kbert +Keys +kjj +Langley +lej +Llane +Marc +Magz +Miguel +Mike +Mistress Kim +Mos +Myth +Nat +Neshy +Nobtel +OctobrX +Ogmo +oznoid +Quartic +RADKade +Ram +Ricdude +Roddez +Punkle +Ryan +SCOboy +Seedy Ben +Shaleh +Sillyhead +SirSpeedy +Slarken +Smelecat +Steve +Stumpy +Tack +Trixxter +Tynian +Vendu +Weird Arms +Waleed +Woody +Wojtek +X5rings + +If you have this you have a SNAPSHOT of Enlightenment Dr 0.15 + +This is a complete rewrite of E. Bascially it is a NEW windowmanager written +from the ground up. + +you NEED: + +libjpeg +libpng +libgif +libtiff +zlib +esound (0.2.4 or higher) +Imlib1.x (1.8 or higher recommended) +Fnlib +Freetype (1.1 or higher) + +Where can u get these? + +---- LIBZ +Please see the PNG homepage for more information: + http://www.cdrom.com/pub/png/ +You can also obtain libz from: + ftp://ftp.enlightenment.org/pub/enlightenment/ + ftp://www.rasterman.com/pub/enlightenment/ + ftp://ftp.labs.redhat.com/pub/imlib/ + +---- LIBTIFF +You can obtain libTIFF from: + ftp://ftp.enlightenment.org/pub/enlightenment/ + ftp://www.rasterman.com/pub/enlightenment/ + ftp://ftp.labs.redhat.com/pub/imlib/ +and + ftp://ftp.sgi.com/graphics/tiff/ + +---- LIBGIF +You can obtain it from: + ftp://ftp.enlightenment.org/pub/enlightenment/ + ftp://www.rasterman.com/pub/enlightenment/ + ftp://ftp.labs.redhat.com/pub/imlib/ + +---- LIBPNG +Please see the PNG homepage for more information: + http://www.cdrom.com/pub/png/ +You can also obtain it from: + ftp://ftp.enlightenment.org/pub/enlightenment/ + ftp://www.rasterman.com/pub/enlightenment/ + ftp://ftp.labs.redhat.com/pub/imlib/ + +---- IMLIB +You can obtain it from: + ftp://ftp.labs.redhat.com/pub/raster/ + ftp://ftp.enlightenment.org/pub/enlightenment/ + ftp://www.rasterman.com/pub/enlightenment/ + ftp://ftp.labs.redhat.com/pub/imlib/ + +---- FNLIB +You can obtain it from: + ftp://ftp.labs.redhat.com/pub/raster/ + ftp://ftp.enlightenment.org/pub/enlightenment/ + ftp://www.rasterman.com/pub/enlightenment/ + ftp://ftp.labs.redhat.com/pub/imlib/ + +---- FREETYPE +You can obtain it from: + http://www.freetype.org/ + +---- ESOUND +Enlightenment requires EsounD (ESD) to be installed to compile. +Please see the EsounD homepage below on how to obtain/install it. + http://pw1.netcom.com/~ericmit/EsounD.html" + +you need all these compiled and installed first - make sure Imlib is compiled +with support for libjpeg libpng libgif and libtiff + +********************* + + +how to compile? + +type: +./configure +make + + +********************* + + +how to install? + +after compiling: +make install + +how to run: + + +********************* + +edit your .xsession or .Xinitrc or .Xclients files to run enlightenment OR +if you're scared to or don't know what I mean then... + +/usr/local/enlightenment/bin/enlightenment + diff --git a/src/TODO b/src/TODO new file mode 100644 index 00000000..e4036716 --- /dev/null +++ b/src/TODO @@ -0,0 +1,44 @@ +user: spacers in menus +user: "default button" indicator for the default "enter" activated button +user: add submenu resistance / timeout for running across to a submenu +user: add "virtual" resistance boxes +user: resistance is still in effect for iconified window +me: window groups... + when adding to a group need group selection dialogbox +me: iconbox name display +me: add dnd to iconbox +me: option to turn off iconbox cover +me: icoify animation suport +me: changing virtual desktop size screws up pager content draws. +me: forbid iconifying of the iconbox +me: forbid shading of any window if its borderless +me: forbid chaning to a borderless window if the window is shaded +me: unshade windows before iconifying then shade again +me: accept right click on scrollbar and cover win for iconbox +kainx: new tooltip stuff doesnt saccoutn for 2x extra in calculating iconbox +kainx: reduce need for tooltip text to have auto gened tooltips work +me: sound.cfg classes to add / support in theme.. +SOUND_MENU_SHOW - whenever a menu is popped up. +SOUND_RESIZE_START - the start of any window resize +SOUND_RESIZE_STOP - the end of any window resize +SOUND_MOVE_START - the start of any window move +SOUND_MOVE_STOP - the end of any window move +SOUND_RAISE - the sound of any window being raised +SOUND_LOWER - the sound of any window being lowered +SOUND_DESKTOP_RAISE - any desktop being raised +SOUND_DESKTOP_LOWER - any desktop being lowered +SOUND_SLIDEOUT_SHOW - when any slideout is shown +SOUND_UNSHADE - when a window is unshaded +SOUND_SHADE - when a window is shaded +SOUND_WINDOW_CHANGE_LAYER_DOWN - when a window changes layers down +SOUND_WINDOW_CHANGE_LAYER_UP - when a window changes layers up +SOUND_WINDOW_BORDER_CHANGE - when a windows border is changed by the user +SOUND_INSERT_KEYS - whenever an insert keys action is called +SOUND_NEW_ICONBOX - when a new iconbox is created +SOUND_MOVE_AREA_LEFT - you move to the area on the left +SOUND_MOVE_AREA_RIGHT - you move to the area on the right +SOUND_MOVE_AREA_UP - you move to the area above +SOUND_MOVE_AREA_DOWN - you move to the area below +SOUND_MOVE_RESIST - sound made whenever a window resists movement + +SOUND_FOCUS_SET - when focus is set to another window... diff --git a/src/actions.c b/src/actions.c new file mode 100644 index 00000000..5c2c97a9 --- /dev/null +++ b/src/actions.c @@ -0,0 +1,3652 @@ +#include "E.h" +#include "timestamp.h" + +ActionClass * +CreateAclass(char *name) +{ + ActionClass *a; + + EDBUG(5, "CreateAclass"); + a = Emalloc(sizeof(ActionClass)); + a->name = duplicate(name); + a->num = 0; + a->list = NULL; + a->tooltipstring = NULL; + a->ref_count = 0; + EDBUG_RETURN(a); +} + +void +GrabButtonGrabs(EWin * ewin) +{ + ActionClass *ac; + int j; + Action *a; + + ac = (ActionClass *) FindItem("BUTTONBINDINGS", 0, + LIST_FINDBY_NAME, + LIST_TYPE_ACLASS); + + if (ac) + { + ac->ref_count++; + for (j = 0; j < ac->num; j++) + { + a = ac->list[j]; + if ((a) && + ((a->event == EVENT_MOUSE_DOWN) || + (a->event == EVENT_MOUSE_UP))) + { + unsigned int mod, button, mask; + int i; + + mod = 0; + button = 0; + if (a->anymodifier) + { + mod = AnyModifier; + } + else + { + mod = a->modifiers; + } + if (a->anybutton) + { + button = AnyButton; + } + else + { + button = a->button; + } + mask = ButtonPressMask | ButtonReleaseMask; + if (mod == AnyModifier) + { + if ((ewin->pager) && (ewin->pager->hi_win)) + XGrabButton(disp, button, mod, ewin->pager->hi_win, + False, mask, GrabModeSync, GrabModeAsync, + None, None); + XGrabButton(disp, button, mod, ewin->win, False, mask, + GrabModeSync, GrabModeAsync, None, None); + } + else + { + for (i = 0; i < 8; i++) + { + if ((ewin->pager) && (ewin->pager->hi_win)) + XGrabButton(disp, button, + mod | mask_mod_combos[i], + ewin->pager->hi_win, False, mask, + GrabModeSync, GrabModeAsync, + None, None); + XGrabButton(disp, button, mod | mask_mod_combos[i], + ewin->win, False, mask, + GrabModeSync, GrabModeAsync, None, None); + } + } + } + } + } +} + +void +UnGrabButtonGrabs(EWin * ewin) +{ + ActionClass *ac; + int j; + Action *a; + + ac = (ActionClass *) FindItem("BUTTONBINDINGS", 0, + LIST_FINDBY_NAME, + LIST_TYPE_ACLASS); + + if (ac) + { + ac->ref_count--; + for (j = 0; j < ac->num; j++) + { + a = ac->list[j]; + if ((a) && + ((a->event == EVENT_MOUSE_DOWN) || + (a->event == EVENT_MOUSE_UP))) + { + unsigned int mod, button; + + mod = 0; + button = 0; + if (a->anymodifier) + { + mod = AnyModifier; + } + else + { + mod = a->modifiers; + } + if (a->anybutton) + { + button = AnyButton; + } + else + { + button = a->button; + } + if (mod == AnyModifier) + { + if ((ewin->pager) && (ewin->pager->hi_win)) + XUngrabButton(disp, button, mod, ewin->pager->hi_win); + XUngrabButton(disp, button, mod, ewin->win); + } + else + { + int i; + + for (i = 0; i < 8; i++) + { + if ((ewin->pager) && (ewin->pager->hi_win)) + XUngrabButton(disp, button, + mod | mask_mod_combos[i], + ewin->pager->hi_win); + XUngrabButton(disp, button, + mod | mask_mod_combos[i], + ewin->win); + } + } + } + } + } +} + +Action * +CreateAction(char event, char anymod, int mod, int anybut, int but, + char anykey, char *key, char *tooltipstring) +{ + Action *act; + + EDBUG(5, "CreateAction"); + + act = Emalloc(sizeof(Action)); + act->action = NULL; + act->event = event; + act->anymodifier = anymod; + act->modifiers = mod; + act->anybutton = anybut; + act->button = but; + act->anykey = anykey; + if (!key) + { + act->key = 0; + } + else + { + act->key = XKeysymToKeycode(disp, XStringToKeysym(key)); + } + act->key_str = duplicate(key); + if (tooltipstring) + { + act->tooltipstring = duplicate(tooltipstring); + } + else + { + act->tooltipstring = NULL; + } + + EDBUG_RETURN(act); +} + +void +RemoveActionType(ActionType * ActionTypeToRemove) +{ + ActionType *ptr, *pp; + + EDBUG(5, "RemoveActionType"); + + ptr = ActionTypeToRemove; + while (ptr) + { + if (ptr->params) + Efree(ptr->params); + pp = ptr; + ptr = ptr->Next; + Efree(pp); + } + + EDBUG_RETURN_; +} + +void +RemoveAction(Action * ActionToRemove) +{ + EDBUG(5, "RemoveAction"); + + if (!ActionToRemove) + EDBUG_RETURN_; + + if ((ActionToRemove->event == EVENT_KEY_DOWN) || + (ActionToRemove->event == EVENT_KEY_UP)) + UnGrabActionKey(ActionToRemove); + if (ActionToRemove->action) + RemoveActionType(ActionToRemove->action); + if (ActionToRemove->tooltipstring) + Efree(ActionToRemove->tooltipstring); + if (ActionToRemove->key_str) + Efree(ActionToRemove->key_str); + Efree(ActionToRemove); + + EDBUG_RETURN_; + +} + +void +RemoveActionClass(ActionClass * ActionClassToRemove) +{ + int i; + + EDBUG(5, "RemoveActionClass"); + + if (!ActionClassToRemove) + EDBUG_RETURN_; + + if (ActionClassToRemove->ref_count > 0) + { + char stuff[255]; + + Esnprintf(stuff, sizeof(stuff), "reference count is still: %u\n", + ActionClassToRemove->ref_count); + DIALOG_OK("ActionClass Error!", stuff); + EDBUG_RETURN_; + } + while (RemoveItemByPtr(ActionClassToRemove, LIST_TYPE_ACLASS)); + + for (i = 0; i < ActionClassToRemove->num; i++) + RemoveAction(ActionClassToRemove->list[i]); + if (ActionClassToRemove->list) + Efree(ActionClassToRemove->list); + if (ActionClassToRemove->name) + Efree(ActionClassToRemove->name); + if (ActionClassToRemove->tooltipstring) + Efree(ActionClassToRemove->tooltipstring); + Efree(ActionClassToRemove); + mode.adestroy = 1; + + EDBUG_RETURN_; +} + +void +AddToAction(Action * act, int id, void *params) +{ + ActionType *pptr, *ptr, *at; + + EDBUG(5, "AddToAction"); + pptr = NULL; + at = Emalloc(sizeof(ActionType)); + at->Next = NULL; + at->Type = id; + at->params = params; + if (!act->action) + { + act->action = at; + } + else + { + ptr = act->action; + while (ptr) + { + pptr = ptr; + ptr = ptr->Next; + } + pptr->Next = at; + } + EDBUG_RETURN_; +} + +void +AddAction(ActionClass * a, Action * act) +{ + EDBUG(5, "AddAction"); + a->num++; + if (!a->list) + a->list = Emalloc(sizeof(Action *)); + else + a->list = Erealloc(a->list, a->num * sizeof(Action *)); + a->list[a->num - 1] = act; + EDBUG_RETURN_; +} + +int +EventAclass(XEvent * ev, ActionClass * a) +{ + KeyCode key; + int i, type, button, modifiers, ok, mouse, mask, val = 0; + Action *act; + char reset_ewin; + + EDBUG(5, "EventAclass"); + reset_ewin = key = type = button = modifiers = mouse = 0; + if (!mode.ewin) + { + mode.ewin = mode.focuswin; + if (!mode.ewin) + mode.ewin = mode.mouse_over_win; + reset_ewin = 1; + } + { + EWin *ewin; + + ewin = GetEwin(); + if ((mode.movemode == 0) && (ewin) && (mode.mode == MODE_MOVE)) + DetermineEwinFloat(ewin, 0, 0); + } + + mask = (ShiftMask | ControlMask | Mod1Mask | Mod2Mask + | Mod3Mask | Mod4Mask | + Mod5Mask) & (~(numlock_mask | scrollock_mask | LockMask)); + + switch (ev->type) + { + case KeyPress: + type = EVENT_KEY_DOWN; + key = ev->xkey.keycode; + modifiers = ev->xbutton.state & mask; + mouse = 0; + break; + case KeyRelease: + type = EVENT_KEY_UP; + key = ev->xkey.keycode; + modifiers = ev->xbutton.state & mask; + mouse = 0; + break; + case ButtonPress: + if (ev->xbutton.time == 0) + type = EVENT_DOUBLE_DOWN; + else + type = EVENT_MOUSE_DOWN; + button = ev->xbutton.button; + modifiers = ev->xbutton.state & mask; + mouse = 1; + break; + case ButtonRelease: + type = EVENT_MOUSE_UP; + button = ev->xbutton.button; + modifiers = ev->xbutton.state & mask; + mouse = 1; + break; + case EnterNotify: + type = EVENT_MOUSE_ENTER; + button = -1; + modifiers = ev->xcrossing.state & mask; + mouse = 1; + break; + case LeaveNotify: + type = EVENT_MOUSE_LEAVE; + button = -1; + modifiers = ev->xcrossing.state & mask; + mouse = 1; + break; + default: + break; + } + + mode.adestroy = 0; + + for (i = 0; i < a->num; i++) + { + if (!mode.adestroy) + { + act = a->list[i]; + ok = 0; + if ((act->event == type) && (act->action)) + { + if (mouse) + { + if (button < 0) + { + if (act->anymodifier) + ok = 1; + else if (act->modifiers == modifiers) + ok = 1; + } + else + { + if (act->anymodifier) + { + if (act->anybutton) + ok = 1; + else if (act->button == button) + ok = 1; + } + else if (act->modifiers == modifiers) + { + if (act->anybutton) + ok = 1; + else if (act->button == button) + ok = 1; + } + } + } + else + { + if (act->anymodifier) + { + if (act->anykey) + ok = 1; + else if (act->key == key) + ok = 1; + } + else if (act->modifiers == modifiers) + { + if (act->anykey) + ok = 1; + else if (act->key == key) + ok = 1; + } + } + if (ok) + { + handleAction(act->action); + val = 1; + } + } + } + if (mode.adestroy) + break; + } + if (reset_ewin) + mode.ewin = NULL; + mode.adestroy = 0; + EDBUG_RETURN(val); +} + +int +handleAction(ActionType * Action) +{ + + /* This function will handle any type of action that is passed into + * it. ALL internal events should be passed through this function. + * No exceptions. --Mandrake (02/26/98) + */ + + int error; + + EDBUG(5, "handleAction"); + error = (*(ActionFunctions[Action->Type])) (Action->params); + + /* Did we just hose ourselves? + * if so, we'd best not stick around here + */ + + if (mode.adestroy) + EDBUG_RETURN(0); + /* If there is another action in this series, (now that + * we're sure we didn't already die) perform it + */ + if (!error) + if (Action->Next) + error = handleAction(Action->Next); + EDBUG_RETURN(error); +} + +int +spawnMenu(void *params) +{ + Menu *m = NULL; + char s[1024]; + char s2[1024]; + int x, y, di; + Window dw; + unsigned int w, h, d; + EWin *ewin; + char desk_click = 0; + int i; + + EDBUG(6, "spawnMenu"); + if (!params) + EDBUG_RETURN(0); + sscanf((char *)params, "%1000s %1000s", s, s2); + ewin = mode.ewin = GetFocusEwin(); + for (i = 0; i < mode.numdesktops; i++) + { + if (mode.context_win == desks.desk[i].win) + { + desk_click = 1; + break; + } + } + if (!desk_click) + { + if ((ewin) && (ewin->win != mode.context_win) && (mode.context_win)) + { + EGetGeometry(disp, mode.context_win, &dw, &di, &di, &w, &h, &d, &d); + XTranslateCoordinates(disp, mode.context_win, root.win, + 0, 0, &x, &y, &dw); + + if (w >= h) + mode.y = -(y + h); + else + mode.x = -(x + w); + mode.context_w = w; + mode.context_h = h; + } + } + if (!strcmp(s, "deskmenu")) + { + AUDIO_PLAY("SOUND_MENU_SHOW"); + ShowDeskMenu(); + } + else if (!strcmp(s, "taskmenu")) + { + AUDIO_PLAY("SOUND_MENU_SHOW"); + ShowAllTaskMenu(); + } + else if (!strcmp(s, "named")) + { + m = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_MENU); + if (m) + { + AUDIO_PLAY("SOUND_MENU_SHOW"); + mode.cur_menu_mode = 1; + XUngrabPointer(disp, CurrentTime); + if (!FindEwinByMenu(m)) + ShowMenu(m, 0); + mode.cur_menu[0] = m; + mode.cur_menu_depth = 1; + ShowMenuMasker(m); + m->ref_count++; + } + else + { + mode.cur_menu[0] = NULL; + mode.cur_menu_depth = 0; + HideMenuMasker(); + } + } + if (((ewin) && (ewin->win == mode.context_win)) || + (ewin = FindEwinByChildren(mode.context_win))) + { + if ((ewin) && (mode.cur_menu_depth > 0) && + (mode.cur_menu[0])) + ewin->shownmenu = mode.cur_menu[0]->win; + } + params = NULL; + if (mode.cur_menu_depth == 0) + EDBUG_RETURN(0); + EDBUG_RETURN(1); +} + +int +hideMenu(void *params) +{ + EDBUG(6, "hideMenu"); + params = NULL; + EDBUG_RETURN(0); +} + +int +doNothing(void *params) +{ + EDBUG(6, "doNothing"); + params = NULL; + EDBUG_RETURN(0); +} + +int +execApplication(void *params) +{ + char *sh; + char *path; + char exe[FILEPATH_LEN_MAX]; + char *real_exec; + + EDBUG(6, "execApplication"); + if (!params) + EDBUG_RETURN(0); + if (fork()) + EDBUG_RETURN(0); + setsid(); + sh = usershell(getuid()); + exe[0] = 0; + sscanf((char *)params, "%4000s", exe); + if (exe[0]) + { + path = pathtoexec(exe); + if (path) + { + Efree(path); + real_exec = (char *)Emalloc(strlen((char *)params) + 6); + sprintf(real_exec, "exec %s", (char *)params); + execl(sh, sh, "-c", (char *)real_exec, NULL); + exit(0); + } + path = pathtofile(exe); + if (!path) + { + /* absolute path */ + if (((char *)exe)[0] == '/') + DialogAlertOK("There was an error running the program:\n" + "%s\n" + "This program could not be executed.\n" + "This is because the file does not exist.\n", + (char *)exe); + /* relative path */ + else + DialogAlertOK("There was an error running the program:\n" + "%s\n" + "This program could not be executed.\n" + "This is most probably because this program " + "is not in the\n" + "path for your shell which is %s. I suggest " + "you read " + "the manual\n" + "page for that shell and read up how to " + "change or add " + "to your\n" + "execution path.\n", + (char *)exe, sh); + } + else + /* it is a node on the filing sys */ + { + /* it's a file */ + if (isfile((char *)path)) + { + /* can execute it */ + if (canexec((char *)path)) + DialogAlertOK("There was an error running the program:\n" + "%s\n" + "This program could not be executed.\n" + "I am unsure as to why you could not " + "do this. " + "The file exists,\n" + "is a file, and you are allowed to " + "execute it. I " + "suggest you look\n" + "into this.\n", + (char *)path); + /* not executable file */ + else + DialogAlertOK("There was an error running the program:\n" + "%s\n" + "This program could not be executed.\n" + "This is because the file exists, is a" + " file, but " + "you are unable\n" + "to execute it because you do not " + "have execute " + "access to this file.\n", + (char *)path); + } + /* it's not a file */ + else + { + /* its a dir */ + if (isdir((char *)path)) + DialogAlertOK("There was an error running the program:\n" + "%s\n" + "This program could not be executed.\n" + "This is because the file is infact " + "a directory.\n", + (char *)path); + /* its not a file or a dir */ + else + DialogAlertOK("There was an error running the program:\n" + "%s\n" + "This program could not be executed.\n" + "This is because the file is not a " + "regular file.\n", + (char *)path); + } + if (path) + Efree(path); + } + exit(100); + } + real_exec = (char *)Emalloc(strlen((char *)params) + 6); + sprintf(real_exec, "exec %s", (char *)params); + execl(sh, sh, "-c", (char *)real_exec, NULL); + exit(0); + EDBUG_RETURN(0); +} + +int +alert(void *params) +{ + char *pp; + int i; + + EDBUG(6, "alert"); + if (InZoom()) + Zoom(NULL); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + pp = duplicate((char *)params); + i = 1; + if (!pp) + EDBUG_RETURN(1); + if (strlen(pp) <= 0) + EDBUG_RETURN(1); + while (pp[i]) + { + if ((pp[i - 1] == '\\') && (((char *)params)[i] == 'n')) + { + pp[i - 1] = ' '; + pp[i] = '\n'; + } + i++; + } + DialogAlertOK(pp); + Efree(pp); + EDBUG_RETURN(0); +} + +int +doExit(void *params) +{ + EDBUG(6, "doExit"); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + /* This function is now handled in session.c */ + if (InZoom()) + Zoom(NULL); + doSMExit(params); + EDBUG_RETURN(0); +} + +int +doResize(void *params) +{ + EWin *ewin; + int x, y, w, h; + + EDBUG(6, "doResize"); + if (InZoom()) + EDBUG_RETURN(0); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + if (mode.slideout) + HideSlideout(mode.slideout, mode.context_win); + ewin = mode.ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + if (ewin->shaded) + EDBUG_RETURN(0); + if (mode.resizemode > 0) + { + FX_Pause(); + GrabX(); + } + queue_up = 0; + AUDIO_PLAY("SOUND_RESIZE_START"); + mode.mode = MODE_RESIZE; + x = mode.x - ewin->x; + y = mode.y - ewin->y; + w = ewin->w >> 1; + h = ewin->h >> 1; + if ((x < w) && (y < h)) + { + mode.resize_detail = 0; + } + if ((x >= w) && (y < h)) + { + mode.resize_detail = 1; + } + if ((x < w) && (y >= h)) + { + mode.resize_detail = 2; + } + if ((x >= w) && (y >= h)) + { + mode.resize_detail = 3; + } + mode.start_x = mode.x; + mode.start_y = mode.y; + mode.win_x = ewin->x; + mode.win_y = ewin->y; + mode.win_w = ewin->client.w; + mode.win_h = ewin->client.h; + mode.firstlast = 0; + DrawEwinShape(ewin, mode.resizemode, ewin->x, ewin->y, ewin->client.w, + ewin->client.h, mode.firstlast); + mode.firstlast = 1; + params = NULL; + EDBUG_RETURN(0); +} + +int +doResizeH(void *params) +{ + EWin *ewin; + int x, w; + + EDBUG(6, "doResizeH"); + if (InZoom()) + EDBUG_RETURN(0); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + if (mode.slideout) + HideSlideout(mode.slideout, mode.context_win); + ewin = mode.ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + if (mode.resizemode > 0) + { + FX_Pause(); + GrabX(); + } + queue_up = 0; + AUDIO_PLAY("SOUND_RESIZE_START"); + mode.mode = MODE_RESIZE_H; + x = mode.x - ewin->x; + w = ewin->w >> 1; + if (x < w) + { + mode.resize_detail = 0; + } + else + { + mode.resize_detail = 1; + } + mode.start_x = mode.x; + mode.start_y = mode.y; + mode.win_x = ewin->x; + mode.win_y = ewin->y; + mode.win_w = ewin->client.w; + mode.win_h = ewin->client.h; + mode.firstlast = 0; + DrawEwinShape(ewin, mode.resizemode, ewin->x, ewin->y, ewin->client.w, + ewin->client.h, mode.firstlast); + mode.firstlast = 1; + params = NULL; + EDBUG_RETURN(0); +} + +int +doResizeV(void *params) +{ + EWin *ewin; + int y, h; + + EDBUG(6, "doResizeV"); + if (InZoom()) + EDBUG_RETURN(0); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + if (mode.slideout) + HideSlideout(mode.slideout, mode.context_win); + ewin = mode.ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + if (mode.resizemode > 0) + { + FX_Pause(); + GrabX(); + } + queue_up = 0; + AUDIO_PLAY("SOUND_RESIZE_START"); + mode.mode = MODE_RESIZE_V; + y = mode.y - ewin->y; + h = ewin->h >> 1; + if (y < h) + { + mode.resize_detail = 0; + } + else + { + mode.resize_detail = 1; + } + mode.start_x = mode.x; + mode.start_y = mode.y; + mode.win_x = ewin->x; + mode.win_y = ewin->y; + mode.win_w = ewin->client.w; + mode.win_h = ewin->client.h; + mode.firstlast = 0; + DrawEwinShape(ewin, mode.resizemode, ewin->x, ewin->y, ewin->client.w, + ewin->client.h, mode.firstlast); + mode.firstlast = 1; + params = NULL; + EDBUG_RETURN(0); +} + +int +doResizeEnd(void *params) +{ + EWin *ewin; + int i; + + EDBUG(0, "doResizeEnd"); + ewin = GetFocusEwin(); + AUDIO_PLAY("SOUND_RESIZE_STOP"); + if (!ewin) + { + if (mode.resizemode > 0) + UngrabX(); + ForceUpdatePagersForDesktop(desks.current); + EDBUG_RETURN(0); + } + queue_up = 1; + mode.mode = MODE_NONE; + if (mode.noewin) + mode.ewin = NULL; + mode.noewin = 0; + mode.firstlast = 2; + DrawEwinShape(ewin, mode.resizemode, ewin->x, ewin->y, ewin->client.w, + ewin->client.h, mode.firstlast); + for (i = 0; i < ewin->border->num_winparts; i++) + ewin->bits[i].no_expose = 1; + ICCCM_Configure(ewin); + HideCoords(); + XSync(disp, False); + if (mode.resizemode > 0) + { + FX_Pause(); + UngrabX(); + } + mode.firstlast = 0; + params = NULL; + ForceUpdatePagersForDesktop(desks.current); + if ((ewin->pager) || (ewin->ibox)) + { + SnapshotEwinBorder(ewin); + SnapshotEwinDesktop(ewin); + SnapshotEwinSize(ewin); + SnapshotEwinLocation(ewin); + SnapshotEwinLayer(ewin); + SnapshotEwinSticky(ewin); + SnapshotEwinShade(ewin); + SaveSnapInfo(); + } + EDBUG_RETURN(0); +} + +static int start_move_desk = 0; +static int start_move_x = 0; +static int start_move_y = 0; + +static int +doMoveImpl(void *params, char constrained) +{ + EWin **gwins; + EWin *ewin; + int xo, yo, i, num; + + EDBUG(6, "doMove"); + if (InZoom()) + EDBUG_RETURN(0); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + if (mode.slideout) + HideSlideout(mode.slideout, mode.context_win); + ewin = mode.ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + mode.moveresize_pending_ewin = ewin; + if (mode.movemode > 0) + { + FX_Pause(); + GrabX(); + } +/* GrabThePointer(root.win); */ + AUDIO_PLAY("SOUND_MOVE_START"); + mode.mode = MODE_MOVE; + mode.constrained = constrained; + mode.start_x = mode.x; + mode.start_y = mode.y; + mode.win_x = ewin->x; + mode.win_y = ewin->y; + mode.win_w = ewin->client.w; + mode.win_h = ewin->client.h; + mode.firstlast = 0; + start_move_desk = ewin->desktop; + xo = desks.desk[ewin->desktop].x; + yo = desks.desk[ewin->desktop].y; + + gwins = ListWinGroupMembersForEwin(ewin, ACTION_MOVE, &num); + for (i = 0; i < num; i++) + { + FloatEwinAt(gwins[i], gwins[i]->x, gwins[i]->y); + if (!mode.moveresize_pending_ewin) + DrawEwinShape(gwins[i], mode.movemode, gwins[i]->x, gwins[i]->y, + gwins[i]->client.w, gwins[i]->client.h, mode.firstlast); + } + Efree(gwins); + mode.firstlast = 1; + params = NULL; + start_move_x = ewin->x; + start_move_y = ewin->y; + EDBUG_RETURN(0); +} + +int +doMove(void *params) +{ + return doMoveImpl(params, 0); +} + +int +doMoveConstrained(void *params) +{ + return doMoveImpl(params, 1); +} + +int +doMoveEnd(void *params) +{ + EWin **gwins; + EWin *ewin; + int d, wasresize = 0, num, i; + + EDBUG(6, "doMoveEnd"); + ewin = GetFocusEwin(); + UnGrabTheButtons(); + AUDIO_PLAY("SOUND_MOVE_STOP"); + if (!ewin) + { + if (mode.movemode > 0) + UngrabX(); + if (!mode.moveresize_pending_ewin) + ForceUpdatePagersForDesktop(desks.current); + EDBUG_RETURN(0); + } + mode.mode = MODE_NONE; + if (mode.noewin) + mode.ewin = NULL; + mode.noewin = 0; + mode.firstlast = 2; + d = DesktopAt(mode.x, mode.y); + gwins = ListWinGroupMembersForEwin(ewin, ACTION_MOVE, &num); + + if (!mode.moveresize_pending_ewin) + { + wasresize = 1; + for (i = 0; i < num; i++) + DrawEwinShape(gwins[i], mode.movemode, gwins[i]->x, gwins[i]->y, gwins[i]->client.w, + gwins[i]->client.h, mode.firstlast); + for (i = 0; i < num; i++) + MoveEwin(gwins[i], gwins[i]->x, gwins[i]->y); + } + mode.moveresize_pending_ewin = NULL; + for (i = 0; i < num; i++) + { + if ((gwins[i]->floating) || (mode.movemode > 0)) + { + if (gwins[i]->floating) + MoveEwinToDesktopAt(gwins[i], d, + gwins[i]->x - (desks.desk[d].x - + desks.desk[gwins[i]->desktop].x), + gwins[i]->y - (desks.desk[d].y - + desks.desk[gwins[i]->desktop].y)); + else + MoveEwinToDesktopAt(gwins[i], d, gwins[i]->x, gwins[i]->y); + gwins[i]->floating = 0; + } + if ((mode.movemode > 0) && (gwins[i]->has_transients)) + { + EWin **lst; + int j, num2; + int dx, dy; + + dx = ewin->x - start_move_x; + dy = ewin->y - start_move_y; + + lst = ListTransientsFor(gwins[i]->client.win, &num2); + if (lst) + { + for (j = 0; j < num2; j++) + MoveEwin(lst[j], lst[j]->x + dx, lst[j]->y + dy); + Efree(lst); + } + } + RaiseEwin(gwins[i]); + ICCCM_Configure(gwins[i]); + } + mode.firstlast = 0; + HideCoords(); + XSync(disp, False); + if (mode.movemode > 0) + { + FX_Pause(); + UngrabX(); + } + for (i = 0; i < num; i++) + { + if ((gwins[i]->pager) || (gwins[i]->ibox)) + { + SnapshotEwinBorder(gwins[i]); + SnapshotEwinDesktop(gwins[i]); + SnapshotEwinSize(gwins[i]); + SnapshotEwinLocation(gwins[i]); + SnapshotEwinLayer(gwins[i]); + SnapshotEwinSticky(gwins[i]); + SnapshotEwinShade(gwins[i]); + SaveSnapInfo(); + } + } + if (wasresize) + ForceUpdatePagersForDesktop(desks.current); + Efree(gwins); + params = NULL; + EDBUG_RETURN(0); +} + +int +doRaise(void *params) +{ + EWin *ewin; + EWin **gwins = NULL; + int i, num; + + EDBUG(6, "doRaise"); + + if (InZoom()) + EDBUG_RETURN(0); + if (params) + ewin = FindItem(NULL, atoi((char *)params), LIST_FINDBY_ID, + LIST_TYPE_EWIN); + else + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + + AUDIO_PLAY("SOUND_RAISE"); + gwins = ListWinGroupMembersForEwin(ewin, ACTION_RAISE, &num); + for (i = 0; i < num; i++) + RaiseEwin(gwins[i]); + Efree(gwins); + EDBUG_RETURN(0); +} + +int +doLower(void *params) +{ + EWin *ewin; + EWin **gwins = NULL; + int i, num; + + EDBUG(6, "doLower"); + + if (InZoom()) + EDBUG_RETURN(0); + if (params) + ewin = FindItem(NULL, atoi((char *)params), LIST_FINDBY_ID, + LIST_TYPE_EWIN); + else + ewin = GetFocusEwin(); + + if (!ewin) + EDBUG_RETURN(0); + + AUDIO_PLAY("SOUND_LOWER"); + gwins = ListWinGroupMembersForEwin(ewin, ACTION_LOWER, &num); + for (i = 0; i < num; i++) + LowerEwin(gwins[i]); + Efree(gwins); + EDBUG_RETURN(0); +} + +int +doCleanup(void *params) +{ + char *type; + int method; + void **lst; + int i, j, k, num, speed; + RectBox *fixed, *ret, *floating; + char doslide; + EWin *ewin; + Button **blst; + + EDBUG(6, "doCleanup"); + + if (InZoom()) + EDBUG_RETURN(0); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + + type = (char *)params; + method = ARRANGE_BY_SIZE; + speed = mode.slidespeedcleanup; + doslide = mode.cleanupslide; + + if (params) + { + if (!strcmp("order", type)) + { + method = ARRANGE_VERBATIM; + } + else if (!strcmp("place", type)) + { + method = ARRANGE_BY_POSITION; + } + } + lst = ListItemType(&num, LIST_TYPE_EWIN); + if (lst) + { + fixed = NULL; + floating = Emalloc(sizeof(RectBox) * num); + ret = Emalloc(sizeof(RectBox) * (num)); + j = 0; + k = 0; + for (i = 0; i < num; i++) + { + if ((((EWin *) lst[i])->desktop == desks.current) && + (!((EWin *) lst[i])->sticky) && (!((EWin *) lst[i])->floating) && + (!((EWin *) lst[i])->iconified) && + (!((EWin *) lst[i])->ignorearrange) && + (((EWin *) lst[i])->area_x == + desks.desk[((EWin *) lst[i])->desktop].current_area_x) && + (((EWin *) lst[i])->area_y == + desks.desk[((EWin *) lst[i])->desktop].current_area_y) + ) + { + floating[j].data = lst[i]; + floating[j].x = ((EWin *) lst[i])->x; + floating[j].y = ((EWin *) lst[i])->y; + floating[j].w = ((EWin *) lst[i])->w; + floating[j].p = ((EWin *) lst[i])->layer; + floating[j++].h = ((EWin *) lst[i])->h; + } + else if ( + ( + (((EWin *) lst[i])->desktop == desks.current) || + (((EWin *) lst[i])->sticky) + ) && + (((EWin *) lst[i])->layer != 4) && + (((EWin *) lst[i])->layer != 0) + ) + { + fixed = Erealloc(fixed, sizeof(RectBox) * (k + 1)); + fixed[k].data = lst[i]; + fixed[k].x = ((EWin *) lst[i])->x; + fixed[k].y = ((EWin *) lst[i])->y; + fixed[k].w = ((EWin *) lst[i])->w; + if (!((EWin *) lst[i])->never_use_area) + { + fixed[k].p = ((EWin *) lst[i])->layer; + } + else + { + fixed[k].p = 99; + } + fixed[k++].h = ((EWin *) lst[i])->h; + } + } + + blst = (Button **) ListItemType(&num, LIST_TYPE_BUTTON); + if (blst) + { + fixed = Erealloc(fixed, sizeof(RectBox) * (num + k)); + ret = Erealloc(ret, sizeof(RectBox) * ((num + j) + 1 + k)); + for (i = 0; i < num; i++) + { + if (((blst[i]->desktop == desks.current) || + ((blst[i]->desktop == 0) && (blst[i]->sticky))) && + (blst[i]->visible)) + { + fixed[k].data = NULL; + fixed[k].x = blst[i]->x; + fixed[k].y = blst[i]->y; + fixed[k].w = blst[i]->w; + if (blst[i]->sticky) + { + fixed[i].p = 50; + } + else + { + fixed[i].p = 0; + } + fixed[k++].h = blst[i]->h; + } + } + Efree(blst); + } + ArrangeRects(fixed, k, floating, j, ret, root.w, root.h, method); + for (i = 0; i < (j + k); i++) + { + if (ret[i].data) + { + if (doslide) + { + ewin = (EWin *) ret[i].data; + if (ewin) + { + if ((ewin->x != ret[i].x) || (ewin->y != ret[i].y)) + { + SlideEwinTo(ewin, ewin->x, ewin->y, + ret[i].x, ret[i].y, speed); + ICCCM_Configure(ewin); + } + } + } + else + { + ewin = (EWin *) ret[i].data; + if (ewin) + { + if ((ewin->x != ret[i].x) || (ewin->y != ret[i].y)) + MoveEwin((EWin *) ret[i].data, ret[i].x, ret[i].y); + } + } + } + } + + if (fixed) + Efree(fixed); + if (ret) + Efree(ret); + if (floating) + Efree(floating); + if (lst) + Efree(lst); + } + SaveSnapInfo(); + EDBUG_RETURN(0); +} + +int +doKill(void *params) +{ + EWin *ewin; + EWin **gwins; + int num, i; + + EDBUG(6, "doKill"); + + if (params) + ewin = FindItem(NULL, atoi((char *)params), LIST_FINDBY_ID, + LIST_TYPE_EWIN); + else + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + + AUDIO_PLAY("SOUND_WINDOW_CLOSE"); + + gwins = ListWinGroupMembersForEwin(ewin, ACTION_KILL, &num); + for (i = 0; i < num; i++) + { + RemoveEwinFromGroup(gwins[i]); + ICCCM_Delete(gwins[i]); + ApplySclass(FindItem("SOUND_WINDOW_CLOSE", 0, + LIST_FINDBY_NAME, LIST_TYPE_SCLASS)); + } + Efree(gwins); + EDBUG_RETURN(0); +} + +int +doKillNasty(void *params) +{ + EWin *ewin; + + EDBUG(6, "doKillNasty"); + + if (params) + ewin = FindItem(NULL, atoi((char *)params), LIST_FINDBY_ID, + LIST_TYPE_EWIN); + else + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + + AUDIO_PLAY("SOUND_WINDOW_CLOSE"); + EDestroyWindow(disp, ewin->client.win); + EDBUG_RETURN(0); +} + +int +doNextDesktop(void *params) +{ + EDBUG(6, "doNextDesktop"); + + if (InZoom()) + EDBUG_RETURN(0); + GotoDesktop(desks.current + 1); + AUDIO_PLAY("SOUND_DESKTOP_SHUT"); + params = NULL; + EDBUG_RETURN(0); +} + +int +doPrevDesktop(void *params) +{ + EDBUG(6, "doPrevDesktop"); + + if (InZoom()) + EDBUG_RETURN(0); + GotoDesktop(desks.current - 1); + AUDIO_PLAY("SOUND_DESKTOP_SHUT"); + params = NULL; + EDBUG_RETURN(0); +} + +int +doRaiseDesktop(void *params) +{ + int d = 0; + + EDBUG(6, "doRaiseDesktop"); + + if (InZoom()) + EDBUG_RETURN(0); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + + if (!params) + d = desks.current; + else + d = atoi((char *)params); + AUDIO_PLAY("SOUND_DESKTOP_RAISE"); + RaiseDesktop(d); + EDBUG_RETURN(0); +} + +int +doLowerDesktop(void *params) +{ + int d = 0; + + EDBUG(6, "doLowerDesktop"); + + if (InZoom()) + EDBUG_RETURN(0); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + + if (!params) + d = desks.current; + else + d = atoi((char *)params); + AUDIO_PLAY("SOUND_DESKTOP_LOWER"); + LowerDesktop(d); + EDBUG_RETURN(0); +} + +int +doDragDesktop(void *params) +{ + int d = 0; + + EDBUG(6, "doDragDesktop"); + + if (InZoom()) + EDBUG_RETURN(0); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + + if (!params) + d = desks.current; + else + d = atoi((char *)params); + mode.deskdrag = d; + mode.mode = MODE_DESKDRAG; + mode.start_x = mode.x; + mode.start_y = mode.y; + mode.win_x = desks.desk[d].x; + mode.win_y = desks.desk[d].y; + EDBUG_RETURN(0); +} + +int +doStick(void *params) +{ + EWin *ewin; + EWin **gwins = NULL; + int i, num; + char sticky; + + EDBUG(6, "doStick"); + + if (InZoom()) + EDBUG_RETURN(0); + if (params) + ewin = FindItem(NULL, atoi((char *)params), LIST_FINDBY_ID, + LIST_TYPE_EWIN); + else + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + gwins = ListWinGroupMembersForEwin(ewin, ACTION_STICK, &num); + sticky = ewin->sticky; + for (i = 0; i < num; i++) + { + if (gwins[i]->sticky && sticky) + { + MakeWindowUnSticky(gwins[i]); + } + else if (!gwins[i]->sticky && !sticky) + { + MakeWindowSticky(gwins[i]); + } + params = NULL; + GNOME_SetHint(gwins[i]); + if ((gwins[i]->pager) || (gwins[i]->ibox)) + { + SnapshotEwinBorder(gwins[i]); + SnapshotEwinDesktop(gwins[i]); + SnapshotEwinSize(gwins[i]); + SnapshotEwinLocation(gwins[i]); + SnapshotEwinLayer(gwins[i]); + SnapshotEwinSticky(gwins[i]); + SnapshotEwinShade(gwins[i]); + SaveSnapInfo(); + } + } + Efree(gwins); + EDBUG_RETURN(0); +} + +int +doInplaceDesktop(void *params) +{ + int d; + + EDBUG(6, "doInplaceDesktop"); + + if (InZoom()) + EDBUG_RETURN(0); + if (!params) + d = desks.current; + else + d = atoi((char *)params); + + GotoDesktop(d); + AUDIO_PLAY("SOUND_DESKTOP_SHUT"); + EDBUG_RETURN(0); +} + +int +doDragButtonStart(void *params) +{ + Button *button; + int xo, yo; + + EDBUG(6, "doDragButtonStart"); + + if (InZoom()) + EDBUG_RETURN(0); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + + button = mode.button; + if (button->flags & FLAG_FIXED) + { + mode.button = NULL; + EDBUG_RETURN(0); + } + if (!button) + EDBUG_RETURN(0); + + GrabThePointer(root.win); + mode.mode = MODE_BUTTONDRAG; + mode.button_move_pending = 1; + mode.start_x = mode.x; + mode.start_y = mode.y; + mode.win_x = button->x; + mode.win_y = button->y; + mode.firstlast = 0; + xo = desks.desk[button->desktop].x; + yo = desks.desk[button->desktop].y; + params = NULL; + + EDBUG_RETURN(0); +} + +int +doDragButtonEnd(void *params) +{ + Button *button; + int d; + + EDBUG(6, "doDragButtonEnd"); + button = mode.button; + if (!button) + EDBUG_RETURN(0); + mode.mode = MODE_NONE; + UnGrabTheButtons(); + if (!mode.button_move_pending) + { + d = DesktopAt(mode.x, mode.y); + MoveButtonToDesktop(button, d); + MovebuttonToCoord(button, button->x - desks.desk[button->desktop].x, + button->y - desks.desk[button->desktop].y); + } + else + mode.button_move_pending = 0; + params = NULL; + autosave(); + + EDBUG_RETURN(0); +} + +int +doFocusModeSet(void *params) +{ + EDBUG(6, "doFocusModeSet"); + if (params) + { + if (!strcmp("pointer", (char *)params)) + mode.focusmode = FOCUS_POINTER; + else if (!strcmp("sloppy", (char *)params)) + mode.focusmode = FOCUS_SLOPPY; + else if (!strcmp("click", (char *)params)) + mode.focusmode = FOCUS_CLICK; + } + else + { + if (mode.focusmode == FOCUS_POINTER) + mode.focusmode = FOCUS_SLOPPY; + else if (mode.focusmode == FOCUS_SLOPPY) + mode.focusmode = FOCUS_CLICK; + else if (mode.focusmode == FOCUS_CLICK) + mode.focusmode = FOCUS_POINTER; + } + FixFocus(); + autosave(); + EDBUG_RETURN(0); +} + +int +doMoveModeSet(void *params) +{ + EDBUG(6, "doMoveModeSet"); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + if (params) + { + mode.movemode = atoi((char *)params); + } + else + { + mode.movemode++; + if (mode.movemode > 5) + mode.movemode = 0; + } + if ((ird) && (mode.movemode == 5)) + mode.movemode = 3; + autosave(); + EDBUG_RETURN(0); +} + +int +doResizeModeSet(void *params) +{ + EDBUG(6, "doResizeModeSet"); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + if (params) + { + mode.resizemode = atoi((char *)params); + } + else + { + mode.resizemode++; + if (mode.resizemode > 4) + mode.resizemode = 0; + } + if (mode.resizemode == 5) + mode.resizemode = 3; + autosave(); + EDBUG_RETURN(0); +} + +int +doSlideModeSet(void *params) +{ + EDBUG(6, "doSlideModeSet"); + if (params) + { + mode.slidemode = atoi((char *)params); + } + else + { + mode.slidemode++; + if (mode.slidemode > 4) + mode.slidemode = 0; + } + autosave(); + EDBUG_RETURN(0); +} + +int +doCleanupSlideSet(void *params) +{ + EDBUG(6, "doCleanupSlideSet"); + if (params) + { + mode.cleanupslide = atoi((char *)params); + } + else + { + if (mode.cleanupslide) + mode.cleanupslide = 0; + else + mode.cleanupslide = 1; + } + autosave(); + EDBUG_RETURN(0); +} + +int +doMapSlideSet(void *params) +{ + EDBUG(6, "doMapSlideSet"); + if (params) + mode.mapslide = atoi((char *)params); + else + { + if (mode.mapslide) + mode.mapslide = 0; + else + mode.mapslide = 1; + } + autosave(); + EDBUG_RETURN(0); +} + +int +doSoundSet(void *params) +{ + SoundClass **lst; + int num, i; + char snd; + + EDBUG(6, "doSoundSet"); + snd = mode.sound; + if (params) + mode.sound = atoi((char *)params); + else + { + if (mode.sound) + mode.sound = 0; + else + mode.sound = 1; + } + if (mode.sound != snd) + { + if (!mode.sound) + { + lst = (SoundClass **) ListItemType(&num, LIST_TYPE_SCLASS); + if (lst) + { + for (i = 0; i < num; i++) + { + if (lst[i]->sample) + DestroySample(lst[i]->sample); + lst[i]->sample = NULL; + } + Efree(lst); + } + close(sound_fd); + sound_fd = -1; + } + else + SoundInit(); + } + autosave(); + EDBUG_RETURN(0); +} + +int +doButtonMoveResistSet(void *params) +{ + EDBUG(6, "doButtonMoveResistSet"); + if (params) + mode.button_move_resistance = atoi((char *)params); + autosave(); + EDBUG_RETURN(0); +} + +int +doDesktopBgTimeoutSet(void *params) +{ + EDBUG(6, "doDesktopBgTimeoutSet"); + if (params) + mode.desktop_bg_timeout = atoi((char *)params); + autosave(); + EDBUG_RETURN(0); +} + +int +doMapSlideSpeedSet(void *params) +{ + EDBUG(6, "doMapSlideSpeedSet"); + if (params) + mode.slidespeedmap = atoi((char *)params); + autosave(); + EDBUG_RETURN(0); +} + +int +doCleanupSlideSpeedSet(void *params) +{ + EDBUG(6, "doCleanupSlideSpeedSet"); + if (params) + mode.slidespeedcleanup = atoi((char *)params); + autosave(); + EDBUG_RETURN(0); +} + +int +doDragdirSet(void *params) +{ + char pd; + Button *b; + int i; + + EDBUG(6, "doDragdirSet"); + pd = desks.dragdir; + if (params) + desks.dragdir = atoi((char *)params); + else + { + desks.dragdir++; + if (desks.dragdir > 3) + desks.dragdir = 0; + } + if (pd != desks.dragdir) + { + GotoDesktop(desks.current); + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + MoveDesktop(i, 0, 0); + while ((b = RemoveItem("_DESKTOP_DRAG_CONTROL", 0, LIST_FINDBY_NAME, + LIST_TYPE_BUTTON))) + DestroyButton(b); + while ((b = RemoveItem("_DESKTOP_DESKRAY_DRAG_CONTROL", + 0, LIST_FINDBY_NAME, LIST_TYPE_BUTTON))) + DestroyButton(b); + InitDesktopControls(); + ShowDesktopControls(); + } + autosave(); + EDBUG_RETURN(0); +} + +int +doDragbarOrderSet(void *params) +{ + char pd; + Button *b; + + EDBUG(6, "doDragbarOrderSet"); + pd = desks.dragbar_ordering; + if (params) + desks.dragbar_ordering = atoi((char *)params); + else + { + desks.dragbar_ordering++; + if (desks.dragbar_ordering > 5) + desks.dragbar_ordering = 0; + } + if (pd != desks.dragbar_ordering) + { + while ((b = RemoveItem("_DESKTOP_DRAG_CONTROL", 0, LIST_FINDBY_NAME, + LIST_TYPE_BUTTON))) + DestroyButton(b); + InitDesktopControls(); + ShowDesktopControls(); + } + autosave(); + EDBUG_RETURN(0); +} + +int +doDragbarWidthSet(void *params) +{ + int pd; + Button *b; + + EDBUG(6, "doDragbarWidthSet"); + pd = desks.dragbar_width; + if (params) + desks.dragbar_width = atoi((char *)params); + if (pd != desks.dragbar_width) + { + while ((b = RemoveItem("_DESKTOP_DRAG_CONTROL", 0, LIST_FINDBY_NAME, + LIST_TYPE_BUTTON))) + DestroyButton(b); + InitDesktopControls(); + ShowDesktopControls(); + } + autosave(); + EDBUG_RETURN(0); +} + +int +doDragbarLengthSet(void *params) +{ + int pd; + Button *b; + + EDBUG(6, "doDragbarLengthSet"); + pd = desks.dragbar_length; + if (params) + desks.dragbar_length = atoi((char *)params); + if (pd != desks.dragbar_length) + { + while ((b = RemoveItem("_DESKTOP_DRAG_CONTROL", 0, LIST_FINDBY_NAME, + LIST_TYPE_BUTTON))) + DestroyButton(b); + InitDesktopControls(); + ShowDesktopControls(); + } + autosave(); + EDBUG_RETURN(0); +} + +int +doDeskSlideSet(void *params) +{ + EDBUG(6, "doDeskSlideSet"); + if (params) + desks.slidein = atoi((char *)params); + else + { + if (desks.slidein) + desks.slidein = 0; + else + desks.slidein = 1; + } + autosave(); + EDBUG_RETURN(0); +} + +int +doDeskSlideSpeedSet(void *params) +{ + EDBUG(6, "doDeskSlideSpeedSet"); + if (params) + desks.slidespeed = atoi((char *)params); + autosave(); + EDBUG_RETURN(0); +} + +int +doHiQualityBgSet(void *params) +{ + EDBUG(6, "doHiQualityBgSet"); + if (params) + desks.hiqualitybg = atoi((char *)params); + else + { + if (desks.hiqualitybg) + desks.hiqualitybg = 0; + else + desks.hiqualitybg = 1; + } + autosave(); + EDBUG_RETURN(0); +} + +int +doPlaySoundClass(void *params) +{ + EDBUG(6, "doPlaySoundClass"); + + if (!params) + EDBUG_RETURN(0); + + ApplySclass(FindItem((char *)params, 0, LIST_FINDBY_NAME, + LIST_TYPE_SCLASS)); + + EDBUG_RETURN(0); +} + +int +doGotoDesktop(void *params) +{ + int d = 0; + + EDBUG(6, "doGotoDesktop"); + + if (InZoom()) + EDBUG_RETURN(0); + if (!params) + EDBUG_RETURN(0); + + sscanf((char *)params, "%i", &d); + GotoDesktop(d); + AUDIO_PLAY("SOUND_DESKTOP_SHUT"); + EDBUG_RETURN(0); +} + +int +doDeskray(void *params) +{ + EDBUG(6, "doDeskray"); + if (InZoom()) + EDBUG_RETURN(0); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + if (params) + { + if (!atoi((char *)params)) + { + HideDesktopTabs(); + mode.deskmode = MODE_NONE; + } + else + { + mode.deskmode = MODE_DESKRAY; + ShowDesktopTabs(); + } + } + else + { + if (mode.deskmode == MODE_DESKRAY) + { + HideDesktopTabs(); + mode.deskmode = MODE_NONE; + } + else + { + mode.deskmode = MODE_DESKRAY; + ShowDesktopTabs(); + } + } + EDBUG_RETURN(0); +} + +int +doAutosaveSet(void *params) +{ + EDBUG(6, "doAutosaveSet"); + if (params) + mode.autosave = atoi((char *)params); + else + { + if (mode.autosave) + mode.autosave = 0; + else + mode.autosave = 1; + } + EDBUG_RETURN(0); +} + +int +doHideShowButton(void *params) +{ + Button **lst, *b; + char s[1024], *ss; + int num, i; + + /* This is unused - where did this come from? -Mandrake */ + /* static char lasthide = 0; */ + + EDBUG(6, "doHideButtons"); + if (InZoom()) + EDBUG_RETURN(0); + if ((mode.mode == MODE_MOVE) || (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || (mode.mode == MODE_RESIZE)) + EDBUG_RETURN(0); + + if (params) + { + sscanf((char *)params, "%1000s", s); + if (!strcmp(s, "button")) + { + sscanf((char *)params, "%*s %1000s", s); + b = (Button *) FindItem(s, 0, LIST_FINDBY_NAME, LIST_TYPE_BUTTON); + if ((b) && (!b->used)) + { + if (b->visible) + { + HideButton(b); + } + else + { + ShowButton(b); + } + } + } + else if (!strcmp(s, "buttons")) + { + ss = atword((char *)params, 2); + if (ss) + { + lst = (Button **) ListItemType(&num, LIST_TYPE_BUTTON); + if (lst) + { + for (i = 0; i < num; i++) + { + if (matchregexp(ss, lst[i]->name)) + { + if ((strcmp(lst[i]->name, + "_DESKTOP_DESKRAY_DRAG_CONTROL") && + (!lst[i]->used))) + { + if (!(lst[i]->visible)) + { + ShowButton(lst[i]); + } + else + { + HideButton(lst[i]); + } + } + } + } + } + } + } + else if (!strcmp(s, "all_buttons_except")) + { + ss = atword((char *)params, 2); + if (ss) + { + lst = (Button **) ListItemTypeID(&num, LIST_TYPE_BUTTON, 0); + if (lst) + { + for (i = 0; i < num; i++) + { + if (!matchregexp(ss, lst[i]->name)) + { + if ((strcmp(lst[i]->name, + "_DESKTOP_DESKRAY_DRAG_CONTROL") && + (!lst[i]->used))) + { + if (!(lst[i]->visible)) + { + ShowButton(lst[i]); + } + else + { + HideButton(lst[i]); + } + } + } + } + } + } + } + else if (!strcmp(s, "all")) + { + lst = (Button **) ListItemType(&num, LIST_TYPE_BUTTON); + if (lst) + { + for (i = 0; i < num; i++) + { + if ((strcmp(lst[i]->name, + "_DESKTOP_DESKRAY_DRAG_CONTROL") && + (!lst[i]->used))) + { + if (!(lst[i]->visible)) + { + ShowButton(lst[i]); + } + else + { + HideButton(lst[i]); + } + } + } + } + } + } + else + { + lst = (Button **) ListItemTypeID(&num, LIST_TYPE_BUTTON, 0); + if (lst) + { + for (i = 0; i < num; i++) + { + if (!lst[i]->used) + { + if (!(lst[i]->visible)) + { + ShowButton(lst[i]); + } + else + { + HideButton(lst[i]); + } + } + } + } + } + autosave(); + + EDBUG_RETURN(0); +} + +int +doIconifyWindow(void *params) +{ + EWin *ewin; + char *windowid = 0; + char iconified; + EWin **gwins = NULL; + int i, num; + + EDBUG(6, "doIconifyWindow"); + + if (params) + { + windowid = (char *)params; + ewin = FindItem("ICON", atoi(windowid), LIST_FINDBY_BOTH, + LIST_TYPE_ICONIFIEDS); + if (!ewin) + ewin = FindItem(NULL, atoi((char *)params), LIST_FINDBY_ID, + LIST_TYPE_EWIN); + } + else + ewin = GetFocusEwin(); + + if (!ewin) + EDBUG_RETURN(1); + + gwins = ListWinGroupMembersForEwin(ewin, ACTION_ICONIFY, &num); + iconified = ewin->iconified; + + for (i = 0; i < num; i++) + { + if (gwins[i]->iconified && iconified) + { + DeIconifyEwin(gwins[i]); + } + else if (!gwins[i]->iconified && !iconified) + { + IconifyEwin(gwins[i]); + } + } + Efree(gwins); + EDBUG_RETURN(0); +} + +int +doSlideout(void *params) +{ + Slideout *s; + + EDBUG(6, "doSlideout"); + if (InZoom()) + EDBUG_RETURN(0); + if (!params) + EDBUG_RETURN(0); + + s = FindItem((char *)params, 0, LIST_FINDBY_NAME, LIST_TYPE_SLIDEOUT); + if (s) + { + AUDIO_PLAY("SOUND_SLIDEOUT_SHOW"); + ShowSlideout(s, mode.context_win); + s->ref_count++; + } + EDBUG_RETURN(0); +} + +int +doScrollWindows(void *params) +{ + + int x, y, num, i; + EWin **lst; + + EDBUG(6, "doScrollWindows"); + if (InZoom()) + EDBUG_RETURN(0); + if (!params) + EDBUG_RETURN(0); + + if (mode.slideout) + HideSlideout(mode.slideout, mode.context_win); + + x = 0; + y = 0; + sscanf((char *)params, "%i %i", &x, &y); + + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + + if ((lst) && (num > 0)) + { + for (i = 0; i < num; i++) + { + if ((lst[i]->desktop == desks.current) && + (!lst[i]->sticky) && (!lst[i]->floating) && + (!lst[i]->fixedpos)) + MoveEwin(lst[i], lst[i]->x + x, lst[i]->y + y); + } + Efree(lst); + } + EDBUG_RETURN(0); +} + +int +doShade(void *params) +{ + EWin *ewin; + EWin **gwins = NULL; + int i, num; + char shaded; + + EDBUG(6, "doShade"); + if (InZoom()) + EDBUG_RETURN(0); + if (params) + ewin = FindItem(NULL, atoi((char *)params), + LIST_FINDBY_ID, LIST_TYPE_EWIN); + else + ewin = GetFocusEwin(); + + if (!ewin) + EDBUG_RETURN(0); + + gwins = ListWinGroupMembersForEwin(ewin, ACTION_SHADE, &num); + shaded = ewin->shaded; + for (i = 0; i < num; i++) + { + if (gwins[i]->shaded && shaded) + { + AUDIO_PLAY("SOUND_UNSHADE"); + UnShadeEwin(gwins[i]); + } + else if (!gwins[i]->shaded && !shaded) + { + AUDIO_PLAY("SOUND_SHADE"); + ShadeEwin(gwins[i]); + } + params = NULL; + if ((gwins[i]->pager) || (gwins[i]->ibox)) + { + SnapshotEwinBorder(gwins[i]); + SnapshotEwinDesktop(gwins[i]); + SnapshotEwinSize(gwins[i]); + SnapshotEwinLocation(gwins[i]); + SnapshotEwinLayer(gwins[i]); + SnapshotEwinSticky(gwins[i]); + SnapshotEwinShade(gwins[i]); + SaveSnapInfo(); + } + } + Efree(gwins); + EDBUG_RETURN(0); +} + +int +doMaxH(void *params) +{ + EWin *ewin; + + EDBUG(6, "doMaxH"); + if (InZoom()) + EDBUG_RETURN(0); + ewin = GetFocusEwin(); + if (ewin) + { + MaxHeight(ewin, (char *)params); + if ((ewin->pager) || (ewin->ibox)) + { + SnapshotEwinBorder(ewin); + SnapshotEwinDesktop(ewin); + SnapshotEwinSize(ewin); + SnapshotEwinLocation(ewin); + SnapshotEwinLayer(ewin); + SnapshotEwinSticky(ewin); + SnapshotEwinShade(ewin); + SaveSnapInfo(); + } + } + EDBUG_RETURN(0); +} + +int +doMaxW(void *params) +{ + EWin *ewin; + + EDBUG(6, "doMaxW"); + if (InZoom()) + EDBUG_RETURN(0); + ewin = GetFocusEwin(); + if (ewin) + { + MaxWidth(ewin, (char *)params); + if ((ewin->pager) || (ewin->ibox)) + { + SnapshotEwinBorder(ewin); + SnapshotEwinDesktop(ewin); + SnapshotEwinSize(ewin); + SnapshotEwinLocation(ewin); + SnapshotEwinLayer(ewin); + SnapshotEwinSticky(ewin); + SnapshotEwinShade(ewin); + SaveSnapInfo(); + } + } + EDBUG_RETURN(0); +} + +int +doMax(void *params) +{ + EWin *ewin; + + EDBUG(6, "doMax"); + if (InZoom()) + EDBUG_RETURN(0); + ewin = GetFocusEwin(); + if (ewin) + { + MaxSize(ewin, (char *)params); + if ((ewin->pager) || (ewin->ibox)) + { + SnapshotEwinBorder(ewin); + SnapshotEwinDesktop(ewin); + SnapshotEwinSize(ewin); + SnapshotEwinLocation(ewin); + SnapshotEwinLayer(ewin); + SnapshotEwinSticky(ewin); + SnapshotEwinShade(ewin); + SaveSnapInfo(); + } + } + EDBUG_RETURN(0); +} + +int +doSendToNextDesk(void *params) +{ + EWin *ewin; + + EDBUG(6, "doSendToNextDesk"); + if (InZoom()) + EDBUG_RETURN(0); + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + + DesktopRemoveEwin(ewin); + MoveEwinToDesktop(ewin, ewin->desktop + 1); + RaiseEwin(ewin); + ICCCM_Configure(ewin); + ewin->sticky = 0; + params = NULL; + + if ((ewin->pager) || (ewin->ibox)) + { + SnapshotEwinBorder(ewin); + SnapshotEwinDesktop(ewin); + SnapshotEwinSize(ewin); + SnapshotEwinLocation(ewin); + SnapshotEwinLayer(ewin); + SnapshotEwinSticky(ewin); + SnapshotEwinShade(ewin); + SaveSnapInfo(); + } + EDBUG_RETURN(0); +} + +int +doSendToPrevDesk(void *params) +{ + EWin *ewin; + + EDBUG(6, "doSendToPrevDesk"); + if (InZoom()) + EDBUG_RETURN(0); + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + + DesktopRemoveEwin(ewin); + MoveEwinToDesktop(ewin, ewin->desktop - 1); + RaiseEwin(ewin); + ICCCM_Configure(ewin); + ewin->sticky = 0; + params = NULL; + + if ((ewin->pager) || (ewin->ibox)) + { + SnapshotEwinBorder(ewin); + SnapshotEwinDesktop(ewin); + SnapshotEwinSize(ewin); + SnapshotEwinLocation(ewin); + SnapshotEwinLayer(ewin); + SnapshotEwinSticky(ewin); + SnapshotEwinShade(ewin); + SaveSnapInfo(); + } + EDBUG_RETURN(0); +} + +int +doSnapshot(void *params) +{ + EWin *ewin; + + EDBUG(6, "doSnapshot"); + + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + + if (!params) + SnapshotEwinAll(ewin); + else if (!strcmp((char *)params, "none")) + UnsnapshotEwin(ewin); + else if (!strcmp((char *)params, "border")) + SnapshotEwinBorder(ewin); + else if (!strcmp((char *)params, "desktop")) + SnapshotEwinDesktop(ewin); + else if (!strcmp((char *)params, "size")) + SnapshotEwinSize(ewin); + else if (!strcmp((char *)params, "location")) + SnapshotEwinLocation(ewin); + else if (!strcmp((char *)params, "layer")) + SnapshotEwinLayer(ewin); + else if (!strcmp((char *)params, "sticky")) + SnapshotEwinSticky(ewin); + else if (!strcmp((char *)params, "icon")) + SnapshotEwinIcon(ewin); + else if (!strcmp((char *)params, "shade")) + SnapshotEwinShade(ewin); + else if (!strcmp((char *)params, "dialog")) + SnapshotEwinDialog(ewin); + EDBUG_RETURN(0); +} + +int +doScrollContainer(void *params) +{ + EDBUG(6, "doScrollContainer"); + + if (!params) + EDBUG_RETURN(0); + if (mode.slideout) + HideSlideout(mode.slideout, mode.context_win); + EDBUG_RETURN(0); + +} + +int +doToolTipSet(void *params) +{ + EDBUG(6, "doToolTipSet"); + + if (params) + mode.tooltips = atoi((char *)params); + else + { + mode.tooltips++; + if (mode.tooltips > 1) + mode.tooltips = 0; + } + autosave(); + EDBUG_RETURN(0); +} + +int +doFocusNext(void *params) +{ + EDBUG(6, "doFocusNext"); + + GetNextFocusEwin(); + params = NULL; + EDBUG_RETURN(0); +} + +int +doFocusPrev(void *params) +{ + EDBUG(6, "doFocusPrev"); + + GetPrevFocusEwin(); + params = NULL; + EDBUG_RETURN(0); +} + +int +doFocusSet(void *params) +{ + Window win; + EWin *ewin; + + EDBUG(6, "doFocusSet"); + + if (!params) + EDBUG_RETURN(0); + sscanf((char *)params, "%i", (int *)&win); + ewin = (EWin *) FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + { + GotoDesktop(ewin->desktop); + SetCurrentArea(ewin->area_x, ewin->area_y); + if (ewin->iconified) + DeIconifyEwin(ewin); + FocusToEWin(ewin); + } + EDBUG_RETURN(0); +} + +int +doBackgroundSet(void *params) +{ + int desk; + Background *bg; + char view, s[1024]; + + EDBUG(6, "doBackgroundSet"); + + if (!params) + EDBUG_RETURN(0); + + desk = desks.current; + if (sscanf((char *)params, "%1000s %i", s, &desk) < 2) + desk = desks.current; + bg = (Background *) FindItem(s, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); + if (!bg) + EDBUG_RETURN(0); + + if (desks.desk[desk].bg != bg) + { + char pq; + + if (desks.desk[desk].bg) + desks.desk[desk].bg->last_viewed = 0; + view = desks.desk[desk].viewable; + desks.desk[desk].viewable = 0; + DesktopAccounting(); + desks.desk[desk].viewable = view; + BGSettingsGoTo(bg); + pq = queue_up; + queue_up = 0; + SetDesktopBg(desk, bg); + RefreshDesktop(desk); + RedrawPagersForDesktop(desk, 2); + ForceUpdatePagersForDesktop(desk); + queue_up = pq; + } + autosave(); + + EDBUG_RETURN(0); +} + +int +doAreaSet(void *params) +{ + int a, b; + + EDBUG(6, "doAreaSet"); + if (InZoom()) + EDBUG_RETURN(0); + if (!params) + EDBUG_RETURN(0); + sscanf((char *)params, "%i %i", &a, &b); + SetCurrentArea(a, b); + + EDBUG_RETURN(0); +} + +int +doAreaMoveBy(void *params) +{ + int a, b; + + EDBUG(6, "doAreaMoveBy"); + if (InZoom()) + EDBUG_RETURN(0); + if (!params) + EDBUG_RETURN(0); + + sscanf((char *)params, "%i %i", &a, &b); + MoveCurrentAreaBy(a, b); + + EDBUG_RETURN(0); +} + +int +doToggleFixedPos(void *params) +{ + EWin *ewin; + + EDBUG(6, "doToggleFixedPos"); + + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + + if (ewin->fixedpos) + ewin->fixedpos = 0; + else + ewin->fixedpos = 1; + + params = NULL; + EDBUG_RETURN(0); +} + +int +doSetLayer(void *params) +{ + EWin *ewin; + int l; + + EDBUG(6, "doSetLayer"); + if (InZoom()) + EDBUG_RETURN(0); + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + if (!params) + EDBUG_RETURN(0); + + l = atoi((char *)params); + if (ewin->layer > l) + { + AUDIO_PLAY("SOUND_WINDOW_CHANGE_LAYER_DOWN"); + } + else if (ewin->layer < l) + { + AUDIO_PLAY("SOUND_WINDOW_CHANGE_LAYER_UP"); + } + ewin->layer = l; + RaiseEwin(ewin); + if ((ewin->pager) || (ewin->ibox)) + { + SnapshotEwinBorder(ewin); + SnapshotEwinDesktop(ewin); + SnapshotEwinSize(ewin); + SnapshotEwinLocation(ewin); + SnapshotEwinLayer(ewin); + SnapshotEwinSticky(ewin); + SnapshotEwinShade(ewin); + SaveSnapInfo(); + } + EDBUG_RETURN(0); +} + +int +doWarpPointer(void *params) +{ + int dx, dy; + + EDBUG(6, "doWarpPointer"); + + if (params) + { + sscanf((char *)params, "%i %i", &dx, &dy); + XWarpPointer(disp, None, None, 0, 0, 0, 0, dx, dy); + } + EDBUG_RETURN(0); +} + +int +doMoveWinToArea(void *params) +{ + EWin *ewin; + int dx, dy; + + EDBUG(6, "doMoveWinToArea"); + if (InZoom()) + EDBUG_RETURN(0); + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + + if (params) + { + sscanf((char *)params, "%i %i", &dx, &dy); + MoveEwinToArea(ewin, dx, dy); + } + if ((ewin->pager) || (ewin->ibox)) + { + SnapshotEwinBorder(ewin); + SnapshotEwinDesktop(ewin); + SnapshotEwinSize(ewin); + SnapshotEwinLocation(ewin); + SnapshotEwinLayer(ewin); + SnapshotEwinSticky(ewin); + SnapshotEwinShade(ewin); + SaveSnapInfo(); + } + EDBUG_RETURN(0); +} + +int +doMoveWinByArea(void *params) +{ + EWin *ewin; + int dx, dy; + + EDBUG(6, "doMoveWinByArea"); + if (InZoom()) + EDBUG_RETURN(0); + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + + if (params) + { + sscanf((char *)params, "%i %i", &dx, &dy); + dx = ewin->area_x + dx; + dy = ewin->area_y + dy; + MoveEwinToArea(ewin, dx, dy); + } + if ((ewin->pager) || (ewin->ibox)) + { + SnapshotEwinBorder(ewin); + SnapshotEwinDesktop(ewin); + SnapshotEwinSize(ewin); + SnapshotEwinLocation(ewin); + SnapshotEwinLayer(ewin); + SnapshotEwinSticky(ewin); + SnapshotEwinShade(ewin); + SaveSnapInfo(); + } + EDBUG_RETURN(0); +} + +int +doSetWinBorder(void *params) +{ + EWin *ewin; + EWin **gwins = NULL; + int i, num; + char buf[1024]; + Border *b; + + EDBUG(6, "doSetWinBorder"); + + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + + if (!params) + EDBUG_RETURN(0); + + gwins = ListWinGroupMembersForEwin(ewin, ACTION_SET_WINDOW_BORDER, &num); + + sscanf((char *)params, "%1000s", buf); + b = (Border *) FindItem(buf, 0, LIST_FINDBY_NAME, LIST_TYPE_BORDER); + if (!b) + EDBUG_RETURN(0); + for (i = 0; i < num; i++) + { + if (b != gwins[i]->border) + { + gwins[i]->border_new = 1; + AUDIO_PLAY("SOUND_WINDOW_BORDER_CHANGE"); + SetEwinToBorder(gwins[i], b); + ICCCM_MatchSize(gwins[i]); + MoveResizeEwin(gwins[i], gwins[i]->x, gwins[i]->y, gwins[i]->client.w, + gwins[i]->client.h); + } + if ((gwins[i]->pager) || (gwins[i]->ibox)) + { + SnapshotEwinBorder(gwins[i]); + SnapshotEwinDesktop(gwins[i]); + SnapshotEwinSize(gwins[i]); + SnapshotEwinLocation(gwins[i]); + SnapshotEwinLayer(gwins[i]); + SnapshotEwinSticky(gwins[i]); + SnapshotEwinShade(gwins[i]); + SaveSnapInfo(); + } + } + Efree(gwins); + EDBUG_RETURN(0); +} + +int +doLinearAreaSet(void *params) +{ + int da; + + EDBUG(6, "doLinearAreaSet"); + if (InZoom()) + EDBUG_RETURN(0); + if (params) + { + sscanf((char *)params, "%i", &da); + SetCurrentLinearArea(da); + } + EDBUG_RETURN(0); +} + +int +doLinearAreaMoveBy(void *params) +{ + int da; + + EDBUG(6, "doLinearAreaMoveBy"); + if (InZoom()) + EDBUG_RETURN(0); + if (params) + { + sscanf((char *)params, "%i", &da); + MoveCurrentLinearAreaBy(da); + } + EDBUG_RETURN(0); +} + +int +doAbout(void *params) +{ + Dialog *d; + DItem *table, *di; + + EDBUG(6, "doAbout"); + if (InZoom()) + EDBUG_RETURN(0); + if ((d = FindItem("ABOUT_ENLIGHTENMENT", 0, + LIST_FINDBY_NAME, LIST_TYPE_DIALOG))) + { + ShowDialog(d); + EDBUG_RETURN(0); + } + d = CreateDialog("ABOUT_ENLIGHTENMENT"); + { + char stuff[255]; + + Esnprintf(stuff, sizeof(stuff), "About Enlightenment %s", + ENLIGHTENMENT_VERSION); + DialogSetTitle(d, stuff); + } + + table = DialogInitItem(d); + DialogItemTableSetOptions(table, 1, 0, 0, 0); + + di = DialogAddItem(table, DITEM_IMAGE); + DialogItemSetPadding(di, 2, 2, 2, 2); + DialogItemImageSetFile(di, "pix/about.png"); + + di = DialogAddItem(table, DITEM_TEXT); + DialogItemSetPadding(di, 2, 2, 2, 2); + DialogItemSetFill(di, 1, 0); + DialogItemTextSetText(di, + "THIS IS NOT A RELEASE VERSION\n" + "You are using this version at your own risk!!\n" + "\n" + "Welcome to the " + ENLIGHTENMENT_VERSION + " development series " + "of the Enlightenment\n" + "window manager. Enlightenment is still under " + "development, but\n" + "we have tried to iron out all the bugs " + "that we can find. If\n" + "you find a bug in the software, please do " + "not hesitate to send\n" + "in a bug report. See \"Help\" for information " + "on joining the\n" + "mailing list.\n" + "\n" + "This code last updated on:\n" + E_CHECKOUT_DATE "\n" + "\n" + "Good luck. I hope you enjoy the software.\n" + "\n" + "The Rasterman - raster@rasterman.com\n" + "Mandrake - mandrake@mandrake.net\n"); + + DialogAddButton(d, "OK", NULL, 1); + ShowDialog(d); + + params = NULL; + EDBUG_RETURN(0); +} + +int +doFX(void *params) +{ + EDBUG(6, "doFX"); + if (InZoom()) + EDBUG_RETURN(0); + if (params) + FX_Start((char *)params); + autosave(); + EDBUG_RETURN(0); +} + +int +doMoveWinToLinearArea(void *params) +{ + EWin *ewin; + int da; + + EDBUG(6, "doMoveWinToLinearArea"); + if (InZoom()) + EDBUG_RETURN(0); + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + if (params) + { + sscanf((char *)params, "%i", &da); + MoveEwinToLinearArea(ewin, da); + } + if ((ewin->pager) || (ewin->ibox)) + { + SnapshotEwinBorder(ewin); + SnapshotEwinDesktop(ewin); + SnapshotEwinSize(ewin); + SnapshotEwinLocation(ewin); + SnapshotEwinLayer(ewin); + SnapshotEwinSticky(ewin); + SnapshotEwinShade(ewin); + SaveSnapInfo(); + } + EDBUG_RETURN(0); +} + +int +doMoveWinByLinearArea(void *params) +{ + EWin *ewin; + int da; + + EDBUG(6, "doMoveWinByLinearArea"); + if (InZoom()) + EDBUG_RETURN(0); + ewin = GetFocusEwin(); + if (!ewin) + EDBUG_RETURN(0); + if (params) + { + sscanf((char *)params, "%i", &da); + MoveEwinLinearAreaBy(ewin, da); + } + if ((ewin->pager) || (ewin->ibox)) + { + SnapshotEwinBorder(ewin); + SnapshotEwinDesktop(ewin); + SnapshotEwinSize(ewin); + SnapshotEwinLocation(ewin); + SnapshotEwinLayer(ewin); + SnapshotEwinSticky(ewin); + SnapshotEwinShade(ewin); + SaveSnapInfo(); + } + EDBUG_RETURN(0); +} + +int +doSetPagerHiq(void *params) +{ + EDBUG(6, "doSetPagerHiq"); + if (params) + { + char num; + + num = atoi(params); + PagerSetHiQ(num); + } + autosave(); + EDBUG_RETURN(0); +} + +int +doSetPagerSnap(void *params) +{ + EDBUG(6, "doSetPagerSnap"); + if (params) + { + char num; + + num = atoi((char *)params); + PagerSetSnap(num); + } + autosave(); + EDBUG_RETURN(0); +} + +int +doConfigure(void *params) +{ + char s[1024]; + + EDBUG(6, "doConfigure"); + if (InZoom()) + EDBUG_RETURN(0); + sscanf((char *)params, "%1000s", s); + if (params) + { + if (!strcmp(s, "pager")) + SettingsPager(); + else if (!strcmp(s, "focus")) + SettingsFocus(); + else if (!strcmp(s, "moveresize")) + SettingsMoveResize(); + else if (!strcmp(s, "desktops")) + SettingsDesktops(); + else if (!strcmp(s, "area")) + SettingsArea(); + else if (!strcmp(s, "placement")) + SettingsPlacement(); + else if (!strcmp(s, "icons")) + SettingsIcons(); + else if (!strcmp(s, "autoraise")) + SettingsAutoRaise(); + else if (!strcmp(s, "tooltips")) + SettingsTooltips(); + else if (!strcmp(s, "audio")) + SettingsAudio(); + else if (!strcmp(s, "fx")) + SettingsSpecialFX(); + else if (!strcmp(s, "bg")) + SettingsBackground(desks.desk[desks.current].bg); + else if (!strcmp(s, "iconbox")) + { + sscanf((char *)params, "%*s %1000s", s); + SettingsIconbox(s); + } + else if (!strcmp(s, "group")) + { + EWin *ewin = GetFocusEwin(); + + if (ewin) + { + if (ewin->group) + SettingsGroup(ewin->group); + else + DIALOG_OK("Window Group Error", "\n This window does not currently \n belong to a group. \n"); + } + } + } + EDBUG_RETURN(0); +} + +struct _keyset +{ + char *sym; + int state; + char *ch; +}; + +int +doInsertKeys(void *params) +{ + const struct _keyset ks[] = + { + {"a", 0, "a"}, + {"b", 0, "b"}, + {"c", 0, "c"}, + {"d", 0, "d"}, + {"e", 0, "e"}, + {"f", 0, "f"}, + {"g", 0, "g"}, + {"h", 0, "h"}, + {"i", 0, "i"}, + {"j", 0, "j"}, + {"k", 0, "k"}, + {"l", 0, "l"}, + {"m", 0, "m"}, + {"n", 0, "n"}, + {"o", 0, "o"}, + {"p", 0, "p"}, + {"q", 0, "q"}, + {"r", 0, "r"}, + {"s", 0, "s"}, + {"t", 0, "t"}, + {"u", 0, "u"}, + {"v", 0, "v"}, + {"w", 0, "w"}, + {"x", 0, "x"}, + {"y", 0, "y"}, + {"z", 0, "z"}, + {"a", ShiftMask, "A"}, + {"b", ShiftMask, "B"}, + {"c", ShiftMask, "C"}, + {"d", ShiftMask, "D"}, + {"e", ShiftMask, "E"}, + {"f", ShiftMask, "F"}, + {"g", ShiftMask, "G"}, + {"h", ShiftMask, "H"}, + {"i", ShiftMask, "I"}, + {"j", ShiftMask, "J"}, + {"k", ShiftMask, "K"}, + {"l", ShiftMask, "L"}, + {"m", ShiftMask, "M"}, + {"n", ShiftMask, "N"}, + {"o", ShiftMask, "O"}, + {"p", ShiftMask, "P"}, + {"q", ShiftMask, "Q"}, + {"r", ShiftMask, "R"}, + {"s", ShiftMask, "S"}, + {"t", ShiftMask, "T"}, + {"u", ShiftMask, "U"}, + {"v", ShiftMask, "V"}, + {"w", ShiftMask, "W"}, + {"x", ShiftMask, "X"}, + {"y", ShiftMask, "Y"}, + {"z", ShiftMask, "Z"}, + {"grave", 0, "`"}, + {"1", 0, "1"}, + {"2", 0, "2"}, + {"3", 0, "3"}, + {"4", 0, "4"}, + {"5", 0, "5"}, + {"6", 0, "6"}, + {"7", 0, "7"}, + {"8", 0, "8"}, + {"9", 0, "9"}, + {"0", 0, "0"}, + {"minus", 0, "-"}, + {"equal", 0, "="}, + {"bracketleft", 0, "["}, + {"bracketright", 0, "]"}, + {"backslash", 0, "\\\\"}, + {"semicolon", 0, "\\s"}, + {"apostrophe", 0, "\\a"}, + {"comma", 0, ","}, + {"period", 0, "."}, + {"slash", 0, "/"}, + {"grave", ShiftMask, "~"}, + {"1", ShiftMask, "!"}, + {"2", ShiftMask, "@"}, + {"3", ShiftMask, "#"}, + {"4", ShiftMask, "$"}, + {"5", ShiftMask, "%"}, + {"6", ShiftMask, "^"}, + {"7", ShiftMask, "&"}, + {"8", ShiftMask, "*"}, + {"9", ShiftMask, "("}, + {"0", ShiftMask, ")"}, + {"minus", ShiftMask, "_"}, + {"equal", ShiftMask, "+"}, + {"bracketleft", ShiftMask, "{"}, + {"bracketright", ShiftMask, "}"}, + {"backslash", ShiftMask, "|"}, + {"semicolon", ShiftMask, ":"}, + {"apostrophe", ShiftMask, "\\q"}, + {"comma", ShiftMask, "<"}, + {"period", ShiftMask, ">"}, + {"slash", ShiftMask, "?"}, + {"space", ShiftMask, " "}, + {"Return", ShiftMask, "\\n"}, + {"Tab", ShiftMask, "\\t"} + }; + + EDBUG(6, "doInsertKeys"); + if (params) + { + Window win = 0; + int i, rev; + char *s; + XKeyEvent ev; + + s = (char *)params; + XGetInputFocus(disp, &win, &rev); + if (win) + { + AUDIO_PLAY("SOUND_INSERT_KEYS"); + ev.window = win; + for (i = 0; i < (int)strlen(s); i++) + { + int j; + + ev.x = mode.x; + ev.y = mode.y; + ev.x_root = mode.x; + ev.y_root = mode.y; + for (j = 0; j < (int)(sizeof(ks) / sizeof(struct _keyset)); j++) + + { + if (!strncmp(ks[j].ch, &(s[i]), strlen(ks[j].ch))) + { + i += (strlen(ks[j].ch) - 1); + ev.keycode = + XKeysymToKeycode(disp, XStringToKeysym(ks[j].sym)); + ev.state = ks[j].state; + ev.type = KeyPress; + XSendEvent(disp, win, False, 0, (XEvent *) & ev); + ev.type = KeyRelease; + XSendEvent(disp, win, False, 0, (XEvent *) & ev); + j = 0x7fffffff; + } + } + } + } + } + EDBUG_RETURN(0); +} + +int +doCreateIconbox(void *params) +{ + EDBUG(6, "doSetPagerSnap"); + if (InZoom()) + EDBUG_RETURN(0); + if (params) + { + Iconbox *ib; + + AUDIO_PLAY("SOUND_NEW_ICONBOX"); + ib = CreateIconbox(params); + ShowIconbox(ib); + } + else + { + Iconbox *ib, **ibl; + int num = 0; + char s[64]; + + ibl = ListAllIconboxes(&num); + if (ibl) + Efree(ibl); + Esnprintf(s, sizeof(s), "_IB_%i", num); + AUDIO_PLAY("SOUND_NEW_ICONBOX"); + ib = CreateIconbox(s); + ShowIconbox(ib); + } + autosave(); + EDBUG_RETURN(0); +} + +int +doRaiseLower(void *params) +{ + EWin *ewin; + + EDBUG(6, "doRaise"); + if (InZoom()) + EDBUG_RETURN(0); + + if (params) + ewin = FindItem(NULL, atoi((char *)params), LIST_FINDBY_ID, + LIST_TYPE_EWIN); + else + ewin = GetFocusEwin(); + + if (!ewin) + EDBUG_RETURN(0); + + if (desks.desk[ewin->desktop].list) + { + if (desks.desk[0].list[0] == ewin) + { + AUDIO_PLAY("SOUND_RAISE"); + RaiseEwin(ewin); + } + else + { + AUDIO_PLAY("SOUND_LOWER"); + LowerEwin(ewin); + } + } + EDBUG_RETURN(0); +} + +int +doShowHideGroup(void *params) +{ + EWin *ewin; + + EWin **gwins; + int i, num; + Border *b = NULL; + + EDBUG(6, "doShowGroup"); + if (InZoom()) + EDBUG_RETURN(0); + if (params) + ewin = FindItem(NULL, atoi((char *)params), LIST_FINDBY_ID, + LIST_TYPE_EWIN); + else + ewin = GetFocusEwin(); + + if (!ewin) + EDBUG_RETURN(0); + + gwins = ListWinGroupMembersForEwin(ewin, ACTION_NONE, &num); + current_group = ewin->group; + + for (i = 0; i < num; i++) + { + if (!gwins[i]->previous_border) + { + if (!gwins[i]->border->group_border_name) + continue; + + b = (Border *) FindItem(gwins[i]->border->group_border_name, 0, LIST_FINDBY_NAME, + LIST_TYPE_BORDER); + if (!b) + b = (Border *) FindItem("__FALLBACK_BORDER", 0, LIST_FINDBY_NAME, + LIST_TYPE_BORDER); + gwins[i]->previous_border = gwins[i]->border; + b->ref_count++; + } + else + { + b = gwins[i]->previous_border; + b->ref_count--; + gwins[i]->previous_border = NULL; + } + + gwins[i]->border_new = 1; + SetEwinToBorder(gwins[i], b); + ICCCM_MatchSize(gwins[i]); + MoveResizeEwin(gwins[i], gwins[i]->x, gwins[i]->y, gwins[i]->client.w, + gwins[i]->client.h); + + if ((gwins[i]->pager) || (gwins[i]->ibox)) + { + SnapshotEwinBorder(gwins[i]); + SnapshotEwinDesktop(gwins[i]); + SnapshotEwinSize(gwins[i]); + SnapshotEwinLocation(gwins[i]); + SnapshotEwinLayer(gwins[i]); + SnapshotEwinSticky(gwins[i]); + SnapshotEwinShade(gwins[i]); + SaveSnapInfo(); + } + } + Efree(gwins); + + EDBUG_RETURN(0); +} + +int +doStartGroup(void *params) +{ + EWin *ewin; + + EDBUG(6, "doStartGroup"); + if (InZoom()) + EDBUG_RETURN(0); + if (params) + ewin = FindItem(NULL, atoi((char *)params), LIST_FINDBY_ID, + LIST_TYPE_EWIN); + else + ewin = GetFocusEwin(); + + if (!ewin) + EDBUG_RETURN(0); + + BuildWindowGroup(&ewin, 1); + + EDBUG_RETURN(0); +} + +int +doAddToGroup(void *params) +{ + EWin *ewin; + + EDBUG(6, "doAddToGroup"); + if (InZoom()) + EDBUG_RETURN(0); + if (params) + ewin = FindItem(NULL, atoi((char *)params), LIST_FINDBY_ID, + LIST_TYPE_EWIN); + else + ewin = GetFocusEwin(); + + if (!ewin) + EDBUG_RETURN(0); + + AddEwinToGroup(ewin, current_group); + + EDBUG_RETURN(0); +} + +int +doRemoveFromGroup(void *params) +{ + EWin *ewin; + + EDBUG(6, "doRemoveFromGroup"); + if (InZoom()) + EDBUG_RETURN(0); + if (params) + ewin = FindItem(NULL, atoi((char *)params), LIST_FINDBY_ID, + LIST_TYPE_EWIN); + else + ewin = GetFocusEwin(); + + if (!ewin) + EDBUG_RETURN(0); + + RemoveEwinFromGroup(ewin); + + EDBUG_RETURN(0); +} + +int +doBreakGroup(void *params) +{ + EWin *ewin; + + EDBUG(6, "doBreakGroup"); + if (InZoom()) + EDBUG_RETURN(0); + if (params) + ewin = FindItem(NULL, atoi((char *)params), LIST_FINDBY_ID, + LIST_TYPE_EWIN); + else + ewin = GetFocusEwin(); + + if (!ewin) + EDBUG_RETURN(0); + + BreakWindowGroup(ewin); + + EDBUG_RETURN(0); +} + +int +doZoom(void *params) +{ + EWin *ewin; + + EDBUG(6, "doZoom"); + + if (!(CanZoom())) + EDBUG_RETURN(0); + + ewin = GetFocusEwin(); + + if (!ewin) + EDBUG_RETURN(0); + if (InZoom()) + Zoom(NULL); + else + Zoom(ewin); + EDBUG_RETURN(0); + params = NULL; +} + +int +initFunctionArray(void) +{ + EDBUG(5, "initFunctionArray"); + ActionFunctions[ACTION_NONE] = (int (*)(void *))(doNothing); + ActionFunctions[ACTION_EXIT] = (int (*)(void *))(doExit); + ActionFunctions[ACTION_EXEC] = (int (*)(void *))(execApplication); + ActionFunctions[ACTION_ALERT] = (int (*)(void *))(alert); + ActionFunctions[ACTION_SHOW_MENU] = (int (*)(void *))(spawnMenu); + ActionFunctions[ACTION_HIDE_MENU] = (int (*)(void *))(hideMenu); + ActionFunctions[ACTION_MOVE] = (int (*)(void *))(doMove); + ActionFunctions[ACTION_RESIZE] = (int (*)(void *))(doResize); + ActionFunctions[ACTION_RAISE] = (int (*)(void *))(doRaise); + ActionFunctions[ACTION_LOWER] = (int (*)(void *))(doLower); + ActionFunctions[ACTION_CLEANUP] = (int (*)(void *))(doCleanup); + ActionFunctions[ACTION_RESIZE_H] = (int (*)(void *))(doResizeH); + ActionFunctions[ACTION_RESIZE_V] = (int (*)(void *))(doResizeV); + ActionFunctions[ACTION_KILL] = (int (*)(void *))(doKill); + ActionFunctions[ACTION_KILL_NASTY] = (int (*)(void *))(doKillNasty); + ActionFunctions[ACTION_DESKTOP_NEXT] = (int (*)(void *))(doNextDesktop); + ActionFunctions[ACTION_DESKTOP_PREV] = (int (*)(void *))(doPrevDesktop); + ActionFunctions[ACTION_DESKTOP_RAISE] = (int (*)(void *))(doRaiseDesktop); + ActionFunctions[ACTION_DESKTOP_LOWER] = (int (*)(void *))(doLowerDesktop); + ActionFunctions[ACTION_DESKTOP_DRAG] = (int (*)(void *))(doDragDesktop); + ActionFunctions[ACTION_STICK] = (int (*)(void *))(doStick); + ActionFunctions[ACTION_DESKTOP_INPLACE] = (int (*)(void *))(doInplaceDesktop); + ActionFunctions[ACTION_DRAG_BUTTON] = (int (*)(void *))(doDragButtonStart); + ActionFunctions[ACTION_FOCUSMODE_SET] = (int (*)(void *))(doFocusModeSet); + ActionFunctions[ACTION_MOVEMODE_SET] = (int (*)(void *))(doMoveModeSet); + ActionFunctions[ACTION_RESIZEMODE_SET] = (int (*)(void *))(doResizeModeSet); + ActionFunctions[ACTION_SLIDEMODE_SET] = (int (*)(void *))(doSlideModeSet); + ActionFunctions[ACTION_CLEANUPSILDE_SET] = (int (*)(void *))(doCleanupSlideSet); + ActionFunctions[ACTION_MAPSLIDE_SET] = (int (*)(void *))(doMapSlideSet); + ActionFunctions[ACTION_SOUND_SET] = (int (*)(void *))(doSoundSet); + ActionFunctions[ACTION_BUTTONMOVE_RESIST_SET] = (int (*)(void *))(doButtonMoveResistSet); + ActionFunctions[ACTION_DESKTOPBG_TIMEOUT_SET] = (int (*)(void *))(doDesktopBgTimeoutSet); + ActionFunctions[ACTION_MAPSLIDE_SPEED_SET] = (int (*)(void *))(doMapSlideSpeedSet); + ActionFunctions[ACTION_CLEANUPSLIDE_SPEED_SET] = (int (*)(void *))(doCleanupSlideSpeedSet); + ActionFunctions[ACTION_DRAGDIR_SET] = (int (*)(void *))(doDragdirSet); + ActionFunctions[ACTION_DRAGBAR_ORDER_SET] = (int (*)(void *))(doDragbarOrderSet); + ActionFunctions[ACTION_DRAGBAR_WIDTH_SET] = (int (*)(void *))(doDragbarWidthSet); + ActionFunctions[ACTION_DRAGBAR_LENGTH_SET] = (int (*)(void *))(doDragbarLengthSet); + ActionFunctions[ACTION_DESKSLIDE_SET] = (int (*)(void *))(doDeskSlideSet); + ActionFunctions[ACTION_DESKSLIDE_SPEED_SET] = (int (*)(void *))(doDeskSlideSpeedSet); + ActionFunctions[ACTION_HIQUALITYBG_SET] = (int (*)(void *))(doHiQualityBgSet); + ActionFunctions[ACTION_PLAYSOUNDCLASS] = (int (*)(void *))(doPlaySoundClass); + ActionFunctions[ACTION_GOTO_DESK] = (int (*)(void *))(doGotoDesktop); + ActionFunctions[ACTION_DESKRAY] = (int (*)(void *))(doDeskray); + ActionFunctions[ACTION_AUTOSAVE_SET] = (int (*)(void *))(doAutosaveSet); + ActionFunctions[ACTION_HIDESHOW_BUTTON] = (int (*)(void *))(doHideShowButton); + ActionFunctions[ACTION_ICONIFY] = (int (*)(void *))(doIconifyWindow); + ActionFunctions[ACTION_SLIDEOUT] = (int (*)(void *))(doSlideout); + ActionFunctions[ACTION_SCROLL_WINDOWS] = (int (*)(void *))(doScrollWindows); + ActionFunctions[ACTION_SHADE] = (int (*)(void *))(doShade); + ActionFunctions[ACTION_MAX_HEIGHT] = (int (*)(void *))(doMaxH); + ActionFunctions[ACTION_MAX_WIDTH] = (int (*)(void *))(doMaxW); + ActionFunctions[ACTION_MAX_SIZE] = (int (*)(void *))(doMax); + ActionFunctions[ACTION_SEND_TO_NEXT_DESK] = (int (*)(void *))(doSendToNextDesk); + ActionFunctions[ACTION_SEND_TO_PREV_DESK] = (int (*)(void *))(doSendToPrevDesk); + ActionFunctions[ACTION_SNAPSHOT] = (int (*)(void *))(doSnapshot); + ActionFunctions[ACTION_SCROLL_CONTAINER] = (int (*)(void *))(doScrollContainer); + ActionFunctions[ACTION_TOOLTIP_SET] = (int (*)(void *))(doToolTipSet); + ActionFunctions[ACTION_FOCUS_NEXT] = (int (*)(void *))(doFocusNext); + ActionFunctions[ACTION_FOCUS_PREV] = (int (*)(void *))(doFocusPrev); + ActionFunctions[ACTION_FOCUS_SET] = (int (*)(void *))(doFocusSet); + ActionFunctions[ACTION_BACKGROUND_SET] = (int (*)(void *))(doBackgroundSet); + ActionFunctions[ACTION_AREA_SET] = (int (*)(void *))(doAreaSet); + ActionFunctions[ACTION_MOVE_BY] = (int (*)(void *))(doAreaMoveBy); + ActionFunctions[ACTION_TOGGLE_FIXED] = (int (*)(void *))(doToggleFixedPos); + ActionFunctions[ACTION_SET_LAYER] = (int (*)(void *))(doSetLayer); + ActionFunctions[ACTION_WARP_POINTER] = (int (*)(void *))(doWarpPointer); + ActionFunctions[ACTION_MOVE_WINDOW_TO_AREA] = (int (*)(void *))(doMoveWinToArea); + ActionFunctions[ACTION_MOVE_WINDOW_BY_AREA] = (int (*)(void *))(doMoveWinByArea); + ActionFunctions[ACTION_SET_WINDOW_BORDER] = (int (*)(void *))(doSetWinBorder); + ActionFunctions[ACTION_LINEAR_AREA_SET] = (int (*)(void *))(doLinearAreaSet); + ActionFunctions[ACTION_LINEAR_MOVE_BY] = (int (*)(void *))(doLinearAreaMoveBy); + ActionFunctions[ACTION_ABOUT] = (int (*)(void *))(doAbout); + ActionFunctions[ACTION_FX] = (int (*)(void *))(doFX); + ActionFunctions[ACTION_MOVE_WINDOW_TO_LINEAR_AREA] = (int (*)(void *))(doMoveWinToLinearArea); + ActionFunctions[ACTION_MOVE_WINDOW_BY_LINEAR_AREA] = (int (*)(void *))(doMoveWinByArea); + ActionFunctions[ACTION_SET_PAGER_HIQ] = (int (*)(void *))(doSetPagerHiq); + ActionFunctions[ACTION_SET_PAGER_SNAP] = (int (*)(void *))(doSetPagerSnap); + ActionFunctions[ACTION_CONFIG] = (int (*)(void *))(doConfigure); + ActionFunctions[ACTION_MOVE_CONSTRAINED] = (int (*)(void *))(doMoveConstrained); + ActionFunctions[ACTION_INSERT_KEYS] = (int (*)(void *))(doInsertKeys); + ActionFunctions[ACTION_START_GROUP] = (int (*)(void *))(doStartGroup); + ActionFunctions[ACTION_ADD_TO_GROUP] = (int (*)(void *))(doAddToGroup); + ActionFunctions[ACTION_REMOVE_FROM_GROUP] = (int (*)(void *))(doRemoveFromGroup); + ActionFunctions[ACTION_BREAK_GROUP] = (int (*)(void *))(doBreakGroup); + ActionFunctions[ACTION_SHOW_HIDE_GROUP] = (int (*)(void *))(doShowHideGroup); + ActionFunctions[ACTION_CREATE_ICONBOX] = (int (*)(void *))(doCreateIconbox); + ActionFunctions[ACTION_RAISE_LOWER] = (int (*)(void *))(doRaiseLower); + ActionFunctions[ACTION_ZOOM] = (int (*)(void *))(doZoom); + EDBUG_RETURN(0); +} diff --git a/src/alert.c b/src/alert.c new file mode 100644 index 00000000..c45553fd --- /dev/null +++ b/src/alert.c @@ -0,0 +1,529 @@ +#include "E.h" + +static void ShowAlert(char *text); +static void AlertHandleClick(int button); + +static int (*IgnoreFunction) (void *) = NULL; +static void *IgnoreParams = NULL; +static char *IgnoreText = NULL; +static int (*RestartFunction) (void *) = NULL; +static void *RestartParams = NULL; +static char *RestartText = NULL; +static int (*ExitFunction) (void *) = NULL; +static void *ExitParams = NULL; +static char *ExitText = NULL; + +static char *TitleText = NULL; + +int call_level; +int debug_level; +char *call_stack[1024]; + +void +Alert(char *fmt,...) +{ + char text[10240]; + va_list ap; + + EDBUG(7, "Alert"); + SC_Kill(); + va_start(ap, fmt); +/* + * #ifdef __USE_GNU + */ + Evsnprintf(text, 10240, fmt, ap); +/* + * #else + * vsprintf(text, fmt, ap); + * #endif + */ + va_end(ap); + AUDIO_PLAY("SOUND_ALERT"); + ShowAlert(text); + EDBUG_RETURN_; +} + +void +AssignTitleText(char *text) +{ + EDBUG(7, "AssignTitleText"); + if (TitleText) + Efree(TitleText); + TitleText = NULL; + TitleText = duplicate(text); + EDBUG_RETURN_; +} + +void +AssignIgnoreText(char *text) +{ + EDBUG(7, "AssignIgnoreText"); + if (IgnoreText) + Efree(IgnoreText); + IgnoreText = NULL; + IgnoreText = duplicate(text); + EDBUG_RETURN_; +} + +void +AssignRestartText(char *text) +{ + EDBUG(7, "AssignRestartText"); + if (RestartText) + Efree(RestartText); + RestartText = NULL; + RestartText = duplicate(text); + EDBUG_RETURN_; +} + +void +AssignExitText(char *text) +{ + EDBUG(7, "AssignExitText"); + if (ExitText) + Efree(ExitText); + ExitText = NULL; + ExitText = duplicate(text); + EDBUG_RETURN_; +} + +void +AssignIgnoreFunction(int (*FunctionToAssign) (void *), void *params) +{ + EDBUG(7, "AssignIgnoreFunction"); + IgnoreFunction = FunctionToAssign; + IgnoreParams = params; + EDBUG_RETURN_; +} + +void +AssignRestartFunction(int (*FunctionToAssign) (void *), void *params) +{ + EDBUG(7, "AssignRestartFunction"); + RestartFunction = FunctionToAssign; + RestartParams = params; + EDBUG_RETURN_; +} + +void +AssignExitFunction(int (*FunctionToAssign) (void *), void *params) +{ + EDBUG(7, "AssignExitFunction"); + ExitFunction = FunctionToAssign; + ExitParams = params; + EDBUG_RETURN_; +} + +static void +ShowAlert(char *text) +{ + Window win = 0, b1 = 0, b2 = 0, b3 = 0; + Display *dd; + int wid, hih, w, h, i, j, k, mask; + XGCValues gcv; + GC gc; + char line[1024]; + XEvent ev; + XFontStruct *xfs; + Font font; + XSetWindowAttributes att; + char colorful; + XColor xcl; + Colormap cmap; + int cols[256]; + int cnum, r, g, b, fh, x, y, ww, hh, mh; + static char *title = NULL, *str1 = NULL, *str2 = NULL, *str3 = NULL; + + EDBUG(8, "ShowAlert"); + if (!text) + EDBUG_RETURN_; + if (disp) + { + XUngrabPointer(disp, CurrentTime); + XUngrabServer(disp); + XSync(disp, False); + } + dd = XOpenDisplay(NULL); + if (!dd) + { + fprintf(stderr, text); + fflush(stderr); + EDBUG_RETURN_; + } + title = TitleText; + str1 = IgnoreText; + str2 = RestartText; + str3 = ExitText; + if (!title) + title = "Enlightenment Error"; + if (!str1) + str1 = "Ignore"; + if (!str2) + str2 = "Restart"; + if (!str3) + str3 = "Exit"; + +#define DRAW_BOX_OUT(mdd, mgc, mwin, mx, my, mw, mh) \ +if (colorful) { \ +XSetForeground(mdd, mgc, cols[3]); \ +XDrawRectangle(mdd, mwin, mgc, mx, my, mw - 1, mh - 1); \ +XSetForeground(mdd, mgc, cols[0]); \ +XDrawLine(mdd, mwin, mgc, mx + 1, my + 1, mx + mw - 3, my + 1); \ +XDrawLine(mdd, mwin, mgc, mx + 1, my + 1, mx + 1, my + mh - 3); \ +XSetForeground(mdd, mgc, cols[2]); \ +XDrawLine(mdd, mwin, mgc, mx + 2, my + mh - 2, mx + mw - 2, my + mh - 2); \ +XDrawLine(mdd, mwin, mgc, mx + mw - 2, my + 2, mx + mw - 2, my + mh - 2); \ +} else { \ +XDrawRectangle(mdd, mwin, mgc, mx, my, mw - 1, mh - 1); \ +} + +#define DRAW_BOX_IN(mdd, mgc, mwin, mx, my, mw, mh) \ +if (colorful) { \ +XSetForeground(mdd, mgc, cols[3]); \ +XDrawRectangle(mdd, mwin, mgc, mx, my, mw - 1, mh - 1); \ +XSetForeground(mdd, mgc, cols[2]); \ +XDrawLine(mdd, mwin, mgc, mx + 1, my + 1, mx + mw - 3, my + 1); \ +XDrawLine(mdd, mwin, mgc, mx + 1, my + 1, mx + 1, my + mh - 3); \ +XSetForeground(mdd, mgc, cols[0]); \ +XDrawLine(mdd, mwin, mgc, mx + 2, my + mh - 2, mx + mw - 2, my + mh - 2); \ +XDrawLine(mdd, mwin, mgc, mx + mw - 2, my + 2, mx + mw - 2, my + mh - 2); \ +} else { \ +XDrawRectangle(mdd, mwin, mgc, mx, my, mw - 1, mh - 1); \ +} + +#define DRAW_THIN_BOX_IN(mdd, mgc, mwin, mx, my, mw, mh) \ +if (colorful) { \ +XSetForeground(mdd, mgc, cols[2]); \ +XDrawLine(mdd, mwin, mgc, mx + 1, my + 1, mx + mw - 3, my + 1); \ +XDrawLine(mdd, mwin, mgc, mx + 1, my + 1, mx + 1, my + mh - 3); \ +XSetForeground(mdd, mgc, cols[0]); \ +XDrawLine(mdd, mwin, mgc, mx + 2, my + mh - 2, mx + mw - 2, my + mh - 2); \ +XDrawLine(mdd, mwin, mgc, mx + mw - 2, my + 2, mx + mw - 2, my + mh - 2); \ +} + +#define DRAW_HEADER(mdd, mgc, mwin, mx, my, mstr) \ +if (colorful) { \ +XSetForeground(mdd, mgc, cols[2]); \ +XDrawString(mdd, mwin, mgc, mx + 1, my + 1, mstr, strlen(mstr)); \ +XDrawString(mdd, mwin, mgc, mx + 2, my + 1, mstr, strlen(mstr)); \ +XDrawString(mdd, mwin, mgc, mx + 2, my + 2, mstr, strlen(mstr)); \ +XDrawString(mdd, mwin, mgc, mx + 1, my + 2, mstr, strlen(mstr)); \ +XSetForeground(mdd, mgc, cols[3]); \ +XDrawString(mdd, mwin, mgc, mx - 1, my, mstr, strlen(mstr)); \ +XDrawString(mdd, mwin, mgc, mx, my - 1, mstr, strlen(mstr)); \ +XDrawString(mdd, mwin, mgc, mx + 1, my, mstr, strlen(mstr)); \ +XDrawString(mdd, mwin, mgc, mx, my + 1, mstr, strlen(mstr)); \ +XSetForeground(mdd, mgc, cols[4]); \ +XDrawString(mdd, mwin, mgc, mx, my, mstr, strlen(mstr)); \ +} else { \ +XDrawString(mdd, mwin, mgc, mx, my, mstr, strlen(mstr)); \ +} + +#define DRAW_STRING(mdd, mgc, mwin, mx, my, mstr) \ +if (colorful) { \ +XSetForeground(mdd, mgc, cols[3]); \ +XDrawString(mdd, mwin, mgc, mx, my, mstr, strlen(mstr)); \ +} else { \ +XDrawString(mdd, mwin, mgc, mx, my, mstr, strlen(mstr)); \ +} + +#define ALLOC_COLOR(d,m,c) \ +if (!XAllocColor(d, m, c)) \ +{ \ +colorful = 0; \ +goto CN; \ +} + + cnum = 0; + cmap = 0; + colorful = 0; + if (DefaultDepth(dd, DefaultScreen(dd)) > 4) + colorful = 1; + if (colorful) + { + cmap = DefaultColormap(dd, DefaultScreen(dd)); + r = 220; + g = 220; + b = 220; + xcl.red = (r << 8) | r; + xcl.green = (g << 8) | g; + xcl.blue = (b << 8) | b; + ALLOC_COLOR(dd, cmap, &xcl); + cols[cnum++] = xcl.pixel; + r = 160; + g = 160; + b = 160; + xcl.red = (r << 8) | r; + xcl.green = (g << 8) | g; + xcl.blue = (b << 8) | b; + ALLOC_COLOR(dd, cmap, &xcl); + cols[cnum++] = xcl.pixel; + r = 100; + g = 100; + b = 100; + xcl.red = (r << 8) | r; + xcl.green = (g << 8) | g; + xcl.blue = (b << 8) | b; + ALLOC_COLOR(dd, cmap, &xcl); + cols[cnum++] = xcl.pixel; + r = 0; + g = 0; + b = 0; + xcl.red = (r << 8) | r; + xcl.green = (g << 8) | g; + xcl.blue = (b << 8) | b; + ALLOC_COLOR(dd, cmap, &xcl); + cols[cnum++] = xcl.pixel; + r = 255; + g = 255; + b = 255; + xcl.red = (r << 8) | r; + xcl.green = (g << 8) | g; + xcl.blue = (b << 8) | b; + ALLOC_COLOR(dd, cmap, &xcl); + cols[cnum++] = xcl.pixel; + } + CN: + wid = DisplayWidth(dd, DefaultScreen(dd)); + hih = DisplayHeight(dd, DefaultScreen(dd)); + w = (wid - 600) / 2; + h = (hih - 440) / 2; + mask = CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWSaveUnder | CWBackingStore; + if (colorful) + att.background_pixel = cols[1]; + else + att.background_pixel = BlackPixel(dd, DefaultScreen(dd)); + if (colorful) + att.border_pixel = cols[3]; + else + att.border_pixel = WhitePixel(dd, DefaultScreen(dd)); + att.backing_store = Always; + att.save_under = True; + att.override_redirect = True; + win = XCreateWindow(dd, DefaultRootWindow(dd), -100, -100, 1, 1, 0, + DefaultDepth(dd, DefaultScreen(dd)), InputOutput, + DefaultVisual(dd, DefaultScreen(dd)), mask, &att); + if (sscanf(str1, "%s", line) > 0) + { + b1 = XCreateWindow(dd, win, -100, -100, 1, 1, 0, + DefaultDepth(dd, DefaultScreen(dd)), InputOutput, + DefaultVisual(dd, DefaultScreen(dd)), mask, &att); + EMapWindow(dd, b1); + } + if (sscanf(str2, "%s", line) > 0) + { + b2 = XCreateWindow(dd, win, -100, -100, 1, 1, 0, + DefaultDepth(dd, DefaultScreen(dd)), InputOutput, + DefaultVisual(dd, DefaultScreen(dd)), mask, &att); + EMapWindow(dd, b2); + } + if (sscanf(str3, "%s", line) > 0) + { + b3 = XCreateWindow(dd, win, -100, -100, 1, 1, 0, + DefaultDepth(dd, DefaultScreen(dd)), InputOutput, + DefaultVisual(dd, DefaultScreen(dd)), mask, &att); + EMapWindow(dd, b3); + } + + gc = XCreateGC(dd, win, 0, &gcv); + if (colorful) + XSetForeground(dd, gc, cols[3]); + else + XSetForeground(dd, gc, att.border_pixel); + fh = 0; + xfs = NULL; + if (!xfs) + { + xfs = XLoadQueryFont(dd, "-*-helvetica-*-r-*-*-12-*-*-*-*-*-*-*"); + } + if (!xfs) + { + xfs = XLoadQueryFont(dd, "fixed"); + } + font = xfs->fid; + fh = xfs->ascent + xfs->descent; + XSetFont(dd, gc, font); + EMapWindow(dd, win); + XGrabServer(dd); + XSync(dd, False); + for (i = 0; i < 600; i += 40) + { + ww = i; + hh = (i * 440) / 600; + x = (wid - ww) >> 1; + y = (hih - hh) >> 1; + EMoveResizeWindow(dd, win, x, y, ww, hh); + DRAW_BOX_OUT(dd, gc, win, 0, 0, ww, hh); + XSync(dd, False); + } + ww = 600; + hh = 440; + x = (wid - 600) >> 1; + y = (hih - 440) >> 1; + EMoveResizeWindow(dd, win, x, y, ww, hh); + XUngrabServer(dd); + XSync(dd, False); + + mh = XTextWidth(xfs, str1, strlen(str1)) + 10; + h = XTextWidth(xfs, str2, strlen(str2)) + 10; + if (h > mh) + mh = h; + h = XTextWidth(xfs, str3, strlen(str3)) + 10; + if (h > mh) + mh = h; + if (sscanf(str1, "%s", line) > 0) + { + h = XTextWidth(xfs, str1, strlen(str1)); + w = 10 + (((580 - mh) * 0) / 4); + EMoveResizeWindow(dd, b1, w - 5, 440 - 15 - fh, mh + 10, fh + 10); + XSelectInput(dd, b1, ButtonPressMask | ButtonReleaseMask | ExposureMask); + } + if (sscanf(str2, "%s", line) > 0) + { + h = XTextWidth(xfs, str2, strlen(str2)); + w = 10 + (((580 - mh) * 1) / 2); + EMoveResizeWindow(dd, b2, w - 5, 440 - 15 - fh, mh + 10, fh + 10); + XSelectInput(dd, b2, ButtonPressMask | ButtonReleaseMask | ExposureMask); + } + if (sscanf(str3, "%s", line) > 0) + { + h = XTextWidth(xfs, str3, strlen(str3)); + w = 10 + (((580 - mh) * 2) / 2); + EMoveResizeWindow(dd, b3, w - 5, 440 - 15 - fh, mh + 10, fh + 10); + XSelectInput(dd, b3, ButtonPressMask | ButtonReleaseMask | ExposureMask); + } + XSync(dd, False); + XSelectInput(dd, win, ExposureMask); + +#define DRAW_ALERT \ +w = XTextWidth(xfs, title, strlen(title)); \ +DRAW_HEADER(dd, gc, win, (600 - w) / 2, 5 + xfs->ascent, title); \ +DRAW_BOX_OUT(dd, gc, win, 0, 0, ww, fh + 10); \ +DRAW_BOX_OUT(dd, gc, win, 0, fh + 10 - 1, ww, hh - fh - fh - 30 + 2); \ +DRAW_BOX_OUT(dd, gc, win, 0, 440 - fh - 20, ww, fh + 20); \ +i = 0; \ +j = 0; \ +k = fh + 10; \ +while (text[i]) { \ +line[j++] = text[i++]; \ +if (line[j - 1] == '\n') { \ +line[j - 1] = 0; \ +j = 0; \ +DRAW_STRING(dd, gc, win, 6, 6 + k + fh, line); \ +k += fh + 2; \ +} \ +} \ +if (sscanf(str1, "%s", line) > 0) \ +{ \ +h = XTextWidth(xfs, str1, strlen(str1)); \ +w = 10 + (((580 - mh) * 0) / 4); \ +DRAW_HEADER(dd, gc, b1, 5 + (mh - h) / 2, fh + 5 - xfs->descent, str1); \ +DRAW_BOX_OUT(dd, gc, b1, 0, 0, mh + 10, fh + 10); \ +DRAW_THIN_BOX_IN(dd, gc, win, w - 7, 440 - 17 - fh, mh + 14, fh + 14); \ +} \ +if (sscanf(str2, "%s", line) > 0) \ +{ \ +h = XTextWidth(xfs, str2, strlen(str2)); \ +w = 10 + (((580 - mh) * 1) / 2); \ +DRAW_HEADER(dd, gc, b2, 5 + (mh - h) / 2, fh + 5 - xfs->descent, str2); \ +DRAW_BOX_OUT(dd, gc, b2, 0, 0, mh + 10, fh + 10); \ +DRAW_THIN_BOX_IN(dd, gc, win, w - 7, 440 - 17 - fh, mh + 14, fh + 14); \ +} \ +if (sscanf(str3, "%s", line) > 0) \ +{ \ +h = XTextWidth(xfs, str3, strlen(str3)); \ +w = 10 + (((580 - mh) * 2) / 2); \ +DRAW_HEADER(dd, gc, b3, 5 + (mh - h) / 2, fh + 5 - xfs->descent, str3); \ +DRAW_BOX_OUT(dd, gc, b3, 0, 0, mh + 10, fh + 10); \ +DRAW_THIN_BOX_IN(dd, gc, win, w - 7, 440 - 17 - fh, mh + 14, fh + 14); \ +XSync(dd, False); \ +} + + DRAW_ALERT; + + w = 1; + while (w == 1) + { + XNextEvent(dd, &ev); + switch (ev.type) + { + case ButtonPress: + if (ev.xbutton.window == b1) + { + DRAW_BOX_IN(dd, gc, b1, 0, 0, mh + 10, fh + 10); + } + else if (ev.xbutton.window == b2) + { + DRAW_BOX_IN(dd, gc, b2, 0, 0, mh + 10, fh + 10); + } + else if (ev.xbutton.window == b3) + { + DRAW_BOX_IN(dd, gc, b3, 0, 0, mh + 10, fh + 10); + } + w = 1; + XSync(dd, False); + break; + case ButtonRelease: + if (ev.xbutton.window == b1) + { + DRAW_BOX_OUT(dd, gc, b1, 0, 0, mh + 10, fh + 10); + XSync(dd, False); + AlertHandleClick(1); + w = 0; + } + else if (ev.xbutton.window == b2) + { + DRAW_BOX_OUT(dd, gc, b2, 0, 0, mh + 10, fh + 10); + XSync(dd, False); + AlertHandleClick(2); + w = 0; + } + else if (ev.xbutton.window == b3) + { + DRAW_BOX_OUT(dd, gc, b3, 0, 0, mh + 10, fh + 10); + XSync(dd, False); + AlertHandleClick(3); + w = 0; + } + break; + case Expose: + DRAW_ALERT; + w = 1; + break; + default: + break; + } + } + EDestroyWindow(dd, win); + XFreeGC(dd, gc); + XFreeFont(dd, xfs); + XUnloadFont(dd, font); + if (cnum > 0) + XFreeColors(dd, cmap, (unsigned long *)cols, cnum, 0); + XCloseDisplay(dd); + EDBUG_RETURN_; +} + +static void +AlertHandleClick(int button) +{ + EDBUG(9, "AlertHandleClick"); + switch (button) + { + case 1: + if (IgnoreFunction) + (*(IgnoreFunction)) (IgnoreParams); + break; + case 2: + if (RestartFunction) + (*(RestartFunction)) (RestartParams); + break; + case 3: + if (ExitFunction) + (*(ExitFunction)) (ExitParams); + break; + default: + break; + } + EDBUG_RETURN_; +} diff --git a/src/areas.c b/src/areas.c new file mode 100644 index 00000000..bc32f41c --- /dev/null +++ b/src/areas.c @@ -0,0 +1,480 @@ +#include "E.h" + +static int area_w = 3; +static int area_h = 3; + +#define AREA_FIX(ax, ay) \ +if (ax < 0) \ +ax = 0; \ +else if (ax >= area_w) \ +ax = area_w - 1; \ +if (ay < 0) \ +ay = 0; \ +else if (ay >= area_h) \ +ay = area_h - 1; + +void +SetNewAreaSize(int ax, int ay) +{ + + int a, b, i, num; + EWin **lst; + + if (ax <= 0) + return; + if (ay <= 0) + return; + + GetAreaSize(&a, &b); + if ((a == ax) && (b == ay)) + return; + SetAreaSize(ax, ay); + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if (lst) + { + for (i = 0; i < num; i++) + { + if (lst[i]->area_x >= ax) + MoveEwinToArea(lst[i], ax - 1, lst[i]->area_x); + if (lst[i]->area_y >= ay) + MoveEwinToArea(lst[i], lst[i]->area_x, ay - 1); + } + Efree(lst); + } + GetCurrentArea(&a, &b); + if (a >= ax) + { + SetCurrentArea(ax - 1, b); + GetCurrentArea(&a, &b); + } + if (b >= ay) + SetCurrentArea(a, ay - 1); +} + +void +GetCurrentArea(int *ax, int *ay) +{ + EDBUG(4, "GetCurrentArea"); + *ax = desks.desk[desks.current].current_area_x; + *ay = desks.desk[desks.current].current_area_y; + EDBUG_RETURN_; +} + +void +SetAreaSize(int aw, int ah) +{ + EDBUG(4, "SetAreaSize"); + if (aw < 1) + aw = 1; + if (ah < 1) + ah = 1; + area_w = aw; + area_h = ah; + GNOME_SetAreaCount(); + PagerReArea(); + EDBUG_RETURN_; +} + +void +GetAreaSize(int *aw, int *ah) +{ + EDBUG(4, "GetAreaSize"); + *aw = area_w; + *ah = area_h; + EDBUG_RETURN_; +} + +void +InitCurrentArea(int ax, int ay) +{ + EDBUG(4, "InitCurrentArea"); + AREA_FIX(ax, ay); + desks.desk[desks.current].current_area_x = ax; + desks.desk[desks.current].current_area_y = ay; + EDBUG_RETURN_; +} + +void +SetCurrentLinearArea(int a) +{ + if (a < 0) + a = 0; + else if (a >= (area_w * area_h)) + a = (area_w * area_h) - 1; + SetCurrentArea(a - ((a / area_w) * area_w), (a / area_w)); +} + +int +GetCurrentLinearArea(void) +{ + return ((desks.desk[desks.current].current_area_y * area_w) + + desks.desk[desks.current].current_area_x); +} + +void +MoveCurrentLinearAreaBy(int a) +{ + SetCurrentLinearArea(GetCurrentLinearArea() + a); +} + +void +MoveEwinToLinearArea(EWin * ewin, int a) +{ + if (a < 0) + a = 0; + else if (a >= (area_w * area_h)) + a = (area_w * area_h) - 1; + MoveEwinToArea(ewin, a - ((a / area_w) * area_w), (a / area_w)); +} + +void +MoveEwinLinearAreaBy(EWin * ewin, int a) +{ + a += (ewin->area_y * area_w) + (ewin->area_x); + if (a < 0) + a = 0; + else if (a >= (area_w * area_h)) + a = (area_w * area_h) - 1; + MoveEwinToArea(ewin, a - ((a / area_w) * area_w), (a / area_w)); +} + +void +SlideWindowsBy(Window * win, int num, int dx, int dy, int speed) +{ + int i, k, spd, x, y, min; + struct timeval timev1, timev2; + int dsec, dusec; + double tm; + struct _xy + { + int x, y; + } + *xy; + + EDBUG(5, "SlideWindowsBy"); + spd = 16; + min = 2; + if (num < 1) + EDBUG_RETURN_; + xy = Emalloc(sizeof(struct _xy) * num); + + for (i = 0; i < num; i++) + GetWinXY(win[i], &(xy[i].x), &(xy[i].y)); + for (k = 0; k <= 1024; k += spd) + { + gettimeofday(&timev1, NULL); + for (i = 0; i < num; i++) + { + x = ((xy[i].x * (1024 - k)) + ((xy[i].x + dx) * k)) >> 10; + y = ((xy[i].y * (1024 - k)) + ((xy[i].y + dy) * k)) >> 10; + EMoveWindow(disp, win[i], x, y); + } + XSync(disp, False); + gettimeofday(&timev2, NULL); + dsec = timev2.tv_sec - timev1.tv_sec; + dusec = timev2.tv_usec - timev1.tv_usec; + if (dusec < 0) + { + dsec--; + dusec += 1000000; + } + tm = (double)dsec + (((double)dusec) / 1000000); + spd = (int)((double)speed * tm); + if (spd < min) + spd = min; + } + for (i = 0; i < num; i++) + EMoveWindow(disp, win[i], xy[i].x + dx, xy[i].y + dy); + if (xy) + Efree(xy); + EDBUG_RETURN_; +} + +void +SetCurrentArea(int ax, int ay) +{ + EWin **lst; + int i, num, a1, a2, x, y, dx, dy; + + EDBUG(4, "SetCurrentArea"); + if ((mode.mode == MODE_RESIZE) || + (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V)) + EDBUG_RETURN_; + + AREA_FIX(ax, ay); + if ((ax == desks.desk[desks.current].current_area_x) && + (ay == desks.desk[desks.current].current_area_y)) + EDBUG_RETURN_; + dx = ax - desks.desk[desks.current].current_area_x; + dy = ay - desks.desk[desks.current].current_area_y; + + /* if we're in move mode.... and its non opaque undraw our boxes */ + if ((mode.mode == MODE_MOVE) && (mode.ewin) && (mode.movemode > 0) && + (!mode.moveresize_pending_ewin)) + { + lst = ListWinGroupMembersForEwin(mode.ewin, ACTION_MOVE, &num); + + for (i = 0; i < num; i++) + { + x = lst[i]->x; + y = lst[i]->y; + DrawEwinShape(lst[i], mode.movemode, + x, y, + lst[i]->client.w, lst[i]->client.h, + 3); + } + Efree(lst); + } + /* remove lots of event masks from windows.. we dont want to bother */ + /* handling events as a result of our playing wiht windows */ + BeginNewDeskFocus(); + /* move all the windows around */ + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if (lst) + { + if (desks.slidein) + { + int wnum = 0; + Window *wl = NULL; + + /* create the list of windwos to move */ + for (i = 0; i < num; i++) + { + if ((lst[i]->desktop == desks.current) && + (!lst[i]->sticky) && (!lst[i]->fixedpos)) + { + if ((lst[i]->floating) && (mode.movemode > 0)) + { + wnum++; + wl = Erealloc(wl, sizeof(Window) * wnum); + wl[wnum - 1] = lst[i]->win; + } + else if (!lst[i]->floating) + { + wnum++; + wl = Erealloc(wl, sizeof(Window) * wnum); + wl[wnum - 1] = lst[i]->win; + } + } + } + /* slide them */ + if (wl) + { + SlideWindowsBy(wl, wnum, + -(root.w * (ax - desks.desk[desks.current].current_area_x)), + -(root.h * (ay - desks.desk[desks.current].current_area_y)), + desks.slidespeed); + Efree(wl); + } + /* move the windows to their final positions */ + for (i = 0; i < num; i++) + { + if ((lst[i]->desktop == desks.current) && + (!lst[i]->sticky) && (!lst[i]->fixedpos)) + { + if (!lst[i]->floating) + { + char setflip = 0; + + a1 = lst[i]->area_x; + a2 = lst[i]->area_y; + if (!mode.flipp) + { + setflip = 1; + mode.flipp = 1; + } + MoveEwin(lst[i], + lst[i]->x - (root.w * (ax - desks.desk[desks.current].current_area_x)), + lst[i]->y - (root.h * (ay - desks.desk[desks.current].current_area_y))); + if (setflip) + mode.flipp = 0; + lst[i]->area_x = a1; + lst[i]->area_y = a2; + GNOME_SetEwinArea(lst[i]); + } + } + } + } + else + { + /* move all widnwos across.... */ + for (i = 0; i < num; i++) + { + if ((lst[i]->desktop == desks.current) && + (!lst[i]->sticky) && (!lst[i]->fixedpos)) + { + /* if we're moving this window and its not opaque move */ + /* warp it across withotu remebering the xy stuff */ + /* well work out the xy stuff later when the move finishes */ + if (lst[i]->floating) + { + if (mode.movemode > 0) + { + GetWinXY(lst[i]->win, &x, &y); + EMoveWindow(disp, lst[i]->win, + x - (root.w * (ax - desks.desk[desks.current].current_area_x)), + y - (root.h * (ay - desks.desk[desks.current].current_area_y))); + } + } + /* if we're not moving it... move it across */ + else + { + char setflip = 0; + + a1 = lst[i]->area_x; + a2 = lst[i]->area_y; + if (!mode.flipp) + { + setflip = 1; + mode.flipp = 1; + } + MoveEwin(lst[i], + lst[i]->x - (root.w * (ax - desks.desk[desks.current].current_area_x)), + lst[i]->y - (root.h * (ay - desks.desk[desks.current].current_area_y))); + if (setflip) + mode.flipp = 0; + lst[i]->area_x = a1; + lst[i]->area_y = a2; + GNOME_SetEwinArea(lst[i]); + } + } + } + } + Efree(lst); + } + /* set the current area up in out data structs */ + desks.desk[desks.current].current_area_x = ax; + desks.desk[desks.current].current_area_y = ay; + /* set gnome hints up for it */ + GNOME_SetCurrentArea(); + XSync(disp, False); + /* redraw any windows that were in "move mode" */ + mode.moveresize_pending_ewin = NULL; + if ((mode.mode == MODE_MOVE) && (mode.ewin)) + { + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if (lst) + { + for (i = 0; i < num; i++) + { + if (lst[i]->floating) + { + if (mode.movemode > 0) + { + if (mode.flipp) + { + x = lst[i]->x - (dx * root.w); + y = lst[i]->y - (dy * root.h); + } + else + { + x = lst[i]->x; + y = lst[i]->y; + } + if (mode.movemode == 5) + DrawEwinShape(lst[i], mode.movemode, + x, y, + lst[i]->client.w, lst[i]->client.h, + 4); + else + DrawEwinShape(lst[i], mode.movemode, + x, y, + lst[i]->client.w, lst[i]->client.h, + 0); + if (mode.flipp) + { + mode.next_move_x_plus = dx * root.w; + mode.next_move_y_plus = dy * root.h; + } + } + else + { + if (mode.flipp) + { + x = lst[i]->x - (dx * root.w); + y = lst[i]->y - (dy * root.h); + } + else + { + x = lst[i]->x; + y = lst[i]->y; + } + DrawEwinShape(lst[i], mode.movemode, + x, y, + lst[i]->client.w, lst[i]->client.h, + 0); + if (mode.flipp) + { + lst[i]->x = x + (dx * root.w); + lst[i]->y = y + (dy * root.h); + lst[i]->reqx = lst[i]->x; + lst[i]->reqy = lst[i]->y; + } + } + } + RedrawPagersForDesktop(lst[i]->desktop, 3); + PagerEwinOutsideAreaUpdate(lst[i]); + } + Efree(lst); + } + } + /* re-focus on a new ewin on that new desktop area */ + NewDeskFocus(); + /* tell the FX api abotu the change */ + FX_DeskChange(); + /* update which "edge flip resistance" detector windows are visible */ + ShowEdgeWindows(); + /* update our pager */ + UpdatePagerSel(); + ForceUpdatePagersForDesktop(desks.current); + EDBUG_RETURN_; +} + +void +MoveEwinToArea(EWin * ewin, int ax, int ay) +{ + EDBUG(4, "MoveEwinToArea"); + AREA_FIX(ax, ay); + MoveEwin(ewin, ewin->x + (root.w * (ax - ewin->area_x)), + ewin->y + (root.h * (ay - ewin->area_y))); + ewin->area_x = ax; + ewin->area_y = ay; + GNOME_SetEwinArea(ewin); + EDBUG_RETURN_; +} + +void +SetEwinToCurrentArea(EWin * ewin) +{ + EDBUG(4, "SetEwinToCurrentArea"); + ewin->area_x = desks.desk[ewin->desktop].current_area_x; + ewin->area_y = desks.desk[ewin->desktop].current_area_y; + GNOME_SetEwinArea(ewin); + EDBUG_RETURN_; +} + +void +MoveCurrentAreaBy(int ax, int ay) +{ + EDBUG(4, "MoveCurrentAreaBy"); + if (ax < 0) + { + AUDIO_PLAY("SOUND_MOVE_AREA_LEFT"); + } + else if (ax > 0) + { + AUDIO_PLAY("SOUND_MOVE_AREA_RIGHT"); + } + else if (ay < 0) + { + AUDIO_PLAY("SOUND_MOVE_AREA_UP"); + } + else if (ay > 0) + { + AUDIO_PLAY("SOUND_MOVE_AREA_DOWN"); + } + SetCurrentArea(desks.desk[desks.current].current_area_x + ax, + desks.desk[desks.current].current_area_y + ay); + EDBUG_RETURN_; +} diff --git a/src/arrange.c b/src/arrange.c new file mode 100644 index 00000000..d3bd1762 --- /dev/null +++ b/src/arrange.c @@ -0,0 +1,716 @@ +#include "E.h" + +int ArrangeAddToList(int **array, int current_size, int value); +void ArrangeSwapList(RectBox * list, int a, int b); + +int +ArrangeAddToList(int **array, int current_size, int value) +{ + int i, j; + + EDBUG(8, "ArrangeAddToList"); + for (i = 0; i < current_size; i++) + { + if (value < (*array)[i]) + { + for (j = current_size; j > i; j--) + (*array)[j] = (*array)[j - 1]; + (*array)[i] = value; + EDBUG_RETURN(current_size + 1); + } + else if (value == (*array)[i]) + EDBUG_RETURN(current_size); + } + (*array)[current_size] = value; + EDBUG_RETURN(current_size + 1); +} + +void +ArrangeSwapList(RectBox * list, int a, int b) +{ + RectBox bb; + + EDBUG(8, "ArrangeSwapList"); + bb.data = list[a].data; + bb.x = list[a].x; + bb.y = list[a].y; + bb.w = list[a].w; + bb.h = list[a].h; + list[a].data = list[b].data; + list[a].x = list[b].x; + list[a].y = list[b].y; + list[a].w = list[b].w; + list[a].h = list[b].h; + list[b].data = bb.data; + list[b].x = bb.x; + list[b].y = bb.y; + list[b].w = bb.w; + list[b].h = bb.h; + EDBUG_RETURN_; +} + +void +ArrangeRects(RectBox * fixed, int fixed_count, RectBox * floating, + int floating_count, RectBox * sorted, int width, int height, + int policy) +{ + int num_sorted = 0; + int xsize = 0, ysize = 0; + int *xarray = NULL, *yarray = NULL; + int *leftover = NULL; + int i, j, k, x, y, x1, x2, y1, y2; + unsigned char *filled = NULL; + RectBox *spaces = NULL; + int num_spaces = 0; + int sort; + int a1, a2; + int num_leftover = 0; + + EDBUG(7, "ArrangeRects"); + switch (policy) + { + case ARRANGE_VERBATIM: + break; + case ARRANGE_BY_SIZE: + sort = 0; + while (!sort) + { + sort = 1; + for (i = 0; i < floating_count - 1; i++) + { + a1 = floating[i].w * floating[i].h; + a2 = floating[i + 1].w * floating[i + 1].h; + if (a2 > a1) + { + sort = 0; + ArrangeSwapList(floating, i, i + 1); + } + } + } + break; + case ARRANGE_BY_POSITION: + sort = 0; + while (!sort) + { + sort = 1; + for (i = 0; i < floating_count - 1; i++) + { + a1 = floating[i].x + floating[i].y; + a2 = (floating[i + 1].x + (floating[i + 1].w >> 1)) + + (floating[i + 1].y + (floating[i + 1].h >> 1)); + if (a2 < a1) + { + sort = 0; + ArrangeSwapList(floating, i, i + 1); + } + } + } + break; + default: + break; + } +/* for every floating rect in order, "fit" it into the sorted list */ + i = ((fixed_count + floating_count) * 2) + 2; + xarray = Emalloc(i * sizeof(int)); + yarray = Emalloc(i * sizeof(int)); + filled = Emalloc(i * i * sizeof(char)); + + spaces = Emalloc(i * i * sizeof(RectBox)); + if (floating_count) + leftover = Emalloc(floating_count * sizeof(int)); + + if (!xarray) + { + if (yarray) + Efree(yarray); + if (filled) + Efree(filled); + if (spaces) + Efree(spaces); + if (leftover) + Efree(leftover); + EDBUG_RETURN_; + } + if (!yarray) + { + Efree(xarray); + if (filled) + Efree(filled); + if (spaces) + Efree(spaces); + if (leftover) + Efree(leftover); + EDBUG_RETURN_; + } + if (!filled) + { + Efree(xarray); + Efree(yarray); + if (spaces) + Efree(spaces); + if (leftover) + Efree(leftover); + EDBUG_RETURN_; + } + if (!spaces) + { + Efree(xarray); + Efree(yarray); + Efree(filled); + if (leftover) + Efree(leftover); + EDBUG_RETURN_; + } +/* copy "fixed" rects into the sorted list */ + for (i = 0; i < fixed_count; i++) + { + sorted[num_sorted].data = fixed[i].data; + sorted[num_sorted].x = fixed[i].x; + sorted[num_sorted].y = fixed[i].y; + sorted[num_sorted].w = fixed[i].w; + sorted[num_sorted].h = fixed[i].h; + sorted[num_sorted].p = fixed[i].p; + num_sorted++; + } +/* go through each floating rect in order and "fit" it in */ + for (i = 0; i < floating_count; i++) + { + xsize = 0; + ysize = 0; +/* put all the sorted rects into the xy arrays */ + xsize = ArrangeAddToList(&xarray, xsize, 0); + xsize = ArrangeAddToList(&xarray, xsize, width); + ysize = ArrangeAddToList(&yarray, ysize, 0); + ysize = ArrangeAddToList(&yarray, ysize, height); + for (j = 0; j < num_sorted; j++) + { + if (sorted[j].x < width) + xsize = ArrangeAddToList(&xarray, xsize, sorted[j].x); + if ((sorted[j].x + sorted[j].w) < width) + xsize = ArrangeAddToList(&xarray, xsize, sorted[j].x + sorted[j].w); + if (sorted[j].y < height) + ysize = ArrangeAddToList(&yarray, ysize, sorted[j].y); + if ((sorted[j].y + sorted[j].h) < height) + ysize = ArrangeAddToList(&yarray, ysize, sorted[j].y + sorted[j].h); + } +/* fill the allocation array */ + for (j = 0; j < (xsize - 1) * (ysize - 1); filled[j++] = 0); + for (j = 0; j < num_sorted; j++) + { + x1 = -1; + x2 = -1; + y1 = -1; + y2 = -1; + for (k = 0; k < xsize - 1; k++) + { + if (sorted[j].x == xarray[k]) + { + x1 = k; + x2 = k; + } + if (sorted[j].x + sorted[j].w == xarray[k + 1]) + x2 = k; + } + for (k = 0; k < ysize - 1; k++) + { + if (sorted[j].y == yarray[k]) + { + y1 = k; + y2 = k; + } + if (sorted[j].y + sorted[j].h == yarray[k + 1]) + y2 = k; + } + if ((x1 >= 0) && (x2 >= 0) && (y1 >= 0) && (y2 >= 0)) + { + for (y = y1; y <= y2; y++) + { + for (x = x1; x <= x2; x++) + { + if (filled[(y * (xsize - 1)) + x] < (sorted[j].p + 1)) + filled[(y * (xsize - 1)) + x] = sorted[j].p + 1; + } + } + } + } + num_spaces = 0; +/* create list of all "spaces" */ + for (y = 0; y < ysize - 1; y++) + { + for (x = 0; x < xsize - 1; x++) + { +/* if the square is empty (lowe prioiryt suares filled) "grow" the space */ + if (filled[(y * (xsize - 1)) + x] < (floating[i].p + 1)) + { + int can_expand_x = 1; + int can_expand_y = 1; + + x1 = x + 1; + y1 = y + 1; + filled[(y * (xsize - 1)) + x] = 100; + if (x >= xsize - 2) + can_expand_x = 0; + if (y >= ysize - 2) + can_expand_y = 0; + while ((can_expand_x) || (can_expand_y)) + { + if (x1 >= xsize - 1) + can_expand_x = 0; + if (y1 >= ysize - 1) + can_expand_y = 0; + if (can_expand_x) + { + for (j = y; j < y1; j++) + { + if (filled[(j * (xsize - 1)) + x1] >= + (floating[i].p + 1)) + can_expand_x = 0; + } + } + if (can_expand_x) + x1++; + if (can_expand_y) + { + for (j = x; j < x1; j++) + { + if (filled[(y1 * (xsize - 1)) + j] >= + (floating[i].p + 1)) + can_expand_y = 0; + } + } + if (can_expand_y) + y1++; + } + spaces[num_spaces].x = xarray[x]; + spaces[num_spaces].y = yarray[y]; + spaces[num_spaces].w = xarray[x1] - xarray[x]; + spaces[num_spaces].h = yarray[y1] - yarray[y]; + spaces[num_spaces].p = 0; + num_spaces++; + } + } + } +/* find the first space that fits */ + k = -1; + sort = 0x7fffffff; + for (j = 0; j < num_spaces; j++) + { + if ((spaces[j].w >= floating[i].w) && + (spaces[j].h >= floating[i].h)) + { + if (policy == ARRANGE_BY_POSITION) + { + a1 = (spaces[j].x + (spaces[j].w >> 1)) - + (floating[i].x + (floating[i].w >> 1)); + a2 = (spaces[j].y + (spaces[j].h >> 1)) - + (floating[i].y + (floating[i].h >> 1)); + if (a1 < 0) + a1 = -a1; + if (a2 < 0) + a2 = -a2; + if ((a1 + a2) < sort) + { + sort = a1 + a2; + k = j; + } + } + else + { + k = j; + j = num_spaces; + } + } + } + if (k >= 0) + { + if (policy == ARRANGE_BY_POSITION) + { + a1 = (spaces[k].x + (spaces[k].w >> 1)) - + (floating[i].x + (floating[i].w >> 1)); + a2 = (spaces[k].y + (spaces[k].h >> 1)) - + (floating[i].y + (floating[i].h >> 1)); + if (a1 >= 0) + sorted[num_sorted].x = spaces[k].x; + else + sorted[num_sorted].x = spaces[k].x + spaces[k].w - floating[i].w; + if (a2 >= 0) + sorted[num_sorted].y = spaces[k].y; + else + sorted[num_sorted].y = spaces[k].y + spaces[k].h - floating[i].h; + } + else + { + sorted[num_sorted].x = spaces[k].x; + sorted[num_sorted].y = spaces[k].y; + } + sorted[num_sorted].data = floating[i].data; + sorted[num_sorted].w = floating[i].w; + sorted[num_sorted].h = floating[i].h; + sorted[num_sorted].p = floating[i].p; + num_sorted++; + } + else + leftover[num_leftover++] = i; + } +/* ok we cant fit everything in this baby.... time fit the leftovers into the */ +/* leftover space */ + for (i = 0; i < num_leftover; i++) + { + xsize = 0; + ysize = 0; +/* put all the sorted rects into the xy arrays */ + xsize = ArrangeAddToList(&xarray, xsize, 0); + xsize = ArrangeAddToList(&xarray, xsize, width); + ysize = ArrangeAddToList(&yarray, ysize, 0); + ysize = ArrangeAddToList(&yarray, ysize, height); + for (j = 0; j < num_sorted; j++) + { + if (sorted[j].x < width) + xsize = ArrangeAddToList(&xarray, xsize, sorted[j].x); + if ((sorted[j].x + sorted[j].w) < width) + xsize = ArrangeAddToList(&xarray, xsize, sorted[j].x + sorted[j].w); + if (sorted[j].y < height) + ysize = ArrangeAddToList(&yarray, ysize, sorted[j].y); + if ((sorted[j].y + sorted[j].h) < height) + ysize = ArrangeAddToList(&yarray, ysize, sorted[j].y + sorted[j].h); + } +/* fill the allocation array */ + for (j = 0; j < (xsize - 1) * (ysize - 1); filled[j++] = 0); + for (j = 0; j < num_sorted; j++) + { + x1 = -1; + x2 = -1; + y1 = -1; + y2 = -1; + for (k = 0; k < xsize - 1; k++) + { + if (sorted[j].x == xarray[k]) + { + x1 = k; + x2 = k; + } + if (sorted[j].x + sorted[j].w == xarray[k + 1]) + x2 = k; + } + for (k = 0; k < ysize - 1; k++) + { + if (sorted[j].y == yarray[k]) + { + y1 = k; + y2 = k; + } + if (sorted[j].y + sorted[j].h == yarray[k + 1]) + y2 = k; + } + if ((x1 >= 0) && (x2 >= 0) && (y1 >= 0) && (y2 >= 0)) + { + for (y = y1; y <= y2; y++) + { + for (x = x1; x <= x2; x++) + { + if (filled[(y * (xsize - 1)) + x] < (sorted[j].p + 1)) + filled[(y * (xsize - 1)) + x] = sorted[j].p + 1; + } + } + } + } + num_spaces = 0; +/* create list of all "spaces" */ + for (y = 0; y < ysize - 1; y++) + { + for (x = 0; x < xsize - 1; x++) + { +/* if the square is empty "grow" the space */ + if (!filled[(y * (xsize - 1)) + x]) + { + int can_expand_x = 1; + int can_expand_y = 1; + char fitswin = 1; + + x1 = x + 1; + y1 = y + 1; + if (x >= xsize - 2) + can_expand_x = 0; + if (y >= ysize - 2) + can_expand_y = 0; + while ((can_expand_x) || (can_expand_y)) + { + if (x1 >= xsize - 1) + can_expand_x = 0; + if (y1 >= ysize - 1) + can_expand_y = 0; + if (can_expand_x) + { + for (j = y; j < y1; j++) + { + if (filled[(j * (xsize - 1)) + x1] >= + (floating[leftover[i]].p + 1)) + { + if (filled[(j * (xsize - 1)) + x1] > + (floating[leftover[i]].p + 1)) + fitswin = 0; + can_expand_x = 0; + } + } + } + if (can_expand_x) + x1++; + if (can_expand_y) + { + for (j = x; j < x1; j++) + { + if (filled[(y1 * (xsize - 1)) + j] >= + (floating[leftover[i]].p + 1)) + { + if (filled[(y1 * (xsize - 1)) + j] > + (floating[leftover[i]].p + 1)) + fitswin = 0; + can_expand_y = 0; + } + } + } + if (can_expand_y) + y1++; + } + spaces[num_spaces].x = xarray[x]; + spaces[num_spaces].y = yarray[y]; + spaces[num_spaces].w = xarray[x1] - xarray[x]; + spaces[num_spaces].h = yarray[y1] - yarray[y]; + spaces[num_spaces].p = fitswin; + num_spaces++; + } + } + } +/* find the first space that fits */ + k = -1; + sort = 0x7fffffff; + a1 = floating[leftover[i]].w * floating[leftover[i]].h; + k = -1; + for (j = 0; j < num_spaces; j++) + { + a2 = spaces[j].w * spaces[j].h; + if ((a2 != 0) && ((a1 - a2) < sort) && (spaces[j].p)) + { + k = j; + sort = a1 - a2; + } + } +/* if there's a small space ... */ + if (k >= 0) + { + sorted[num_sorted].x = spaces[k].x; + sorted[num_sorted].y = spaces[k].y; + sorted[num_sorted].data = floating[leftover[i]].data; + sorted[num_sorted].w = floating[leftover[i]].w; + sorted[num_sorted].h = floating[leftover[i]].h; + if ((sorted[num_sorted].x + sorted[num_sorted].w) > width) + sorted[num_sorted].x = width - sorted[num_sorted].w; + if ((sorted[num_sorted].y + sorted[num_sorted].h) > height) + sorted[num_sorted].y = height - sorted[num_sorted].h; + if (sorted[num_sorted].x < 0) + sorted[num_sorted].x = 0; + if (sorted[num_sorted].y < 0) + sorted[num_sorted].y = 0; + num_sorted++; + } +/* there is no room - put it centered (but dont put top left off screen) */ + else + { + sorted[num_sorted].data = floating[leftover[i]].data; + sorted[num_sorted].x = (width - floating[leftover[i]].w) / 2; + sorted[num_sorted].y = (height - floating[leftover[i]].h) / 2; + sorted[num_sorted].w = floating[leftover[i]].w; + sorted[num_sorted].h = floating[leftover[i]].h; + if (sorted[num_sorted].x < 0) + sorted[num_sorted].x = 0; + if (sorted[num_sorted].y < 0) + sorted[num_sorted].y = 0; + num_sorted++; + } + } +/* free up memory */ + Efree(xarray); + Efree(yarray); + Efree(filled); + Efree(spaces); + if (leftover) + Efree(leftover); + for (i = 0; i < num_sorted; i++) + { + if ((sorted[i].x + sorted[i].w) > root.w) + sorted[i].x = root.w - sorted[i].w; + if ((sorted[i].y + sorted[i].h) > root.h) + sorted[i].y = root.h - sorted[i].h; + if (sorted[i].x < 0) + sorted[i].x = 0; + if (sorted[i].y < 0) + sorted[i].y = 0; + } + EDBUG_RETURN_; +} + +void +SnapEwin(EWin * ewin, int dx, int dy, int *new_dx, int *new_dy) +{ + EWin **lst, **gwins; + int gnum, num, i, j, screen_snap_dist, odx, ody; + + EDBUG(5, "SnapEwin"); + if (!mode.snap) + { + *new_dx = dx; + *new_dy = dy; + EDBUG_RETURN_; + } + screen_snap_dist = mode.constrained ? (root.w + root.h) + : mode.screen_snap_dist; + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + gwins = ListWinGroupMembersForEwin(ewin, ACTION_MOVE, &gnum); + if (gwins) + { + for (i = 0; i < gnum; i++) + { + for (j = 0; j < num; j++) + { + if ((lst[j] == gwins[i]) || (lst[j] == ewin)) + lst[j] = NULL; + } + } + Efree(gwins); + } + odx = dx; + ody = dy; + if (dx < 0) + { + if (IN_BELOW(ewin->x + dx, 0, screen_snap_dist) + && (ewin->x >= 0)) + dx = 0 - ewin->x; + else if (lst) + { + for (i = 0; i < num; i++) + { + if (lst[i]) + { + if (((ewin->desktop == lst[i]->desktop) || + (lst[i]->sticky)) && + (!(lst[i]->floating)) && + (!(lst[i]->ignorearrange))) + { + if (IN_BELOW(ewin->x + dx, lst[i]->x + lst[i]->w - 1, + mode.edge_snap_dist) && + SPANS_COMMON(ewin->y, ewin->h, lst[i]->y, lst[i]->h) + && (ewin->x >= (lst[i]->x + lst[i]->w))) + { + dx = (lst[i]->x + lst[i]->w) - ewin->x; + break; + } + } + } + } + } + if ((ewin->reqx - ewin->x) > 0) + dx = 0; + } + else if (dx > 0) + { + if (IN_ABOVE(ewin->x + ewin->w + dx, root.w, screen_snap_dist) + && ((ewin->x + ewin->w) <= root.w)) + dx = root.w - (ewin->x + ewin->w); + else if (lst) + { + for (i = 0; i < num; i++) + { + if (lst[i]) + { + if (((ewin->desktop == lst[i]->desktop) || + (lst[i]->sticky)) && + (!(lst[i]->floating)) && + (!(lst[i]->ignorearrange))) + { + if (IN_ABOVE(ewin->x + ewin->w + dx - 1, lst[i]->x, + mode.edge_snap_dist) && + SPANS_COMMON(ewin->y, ewin->h, lst[i]->y, lst[i]->h) + && ((ewin->x + ewin->w) <= lst[i]->x)) + { + dx = lst[i]->x - (ewin->x + ewin->w); + break; + } + } + } + } + } + if ((ewin->reqx - ewin->x) < 0) + dx = 0; + } + if (dy < 0) + { + if (IN_BELOW(ewin->y + dy, 0, screen_snap_dist) + && (ewin->y >= 0)) + dy = 0 - ewin->y; + else if (lst) + { + for (i = 0; i < num; i++) + { + if (lst[i]) + { + if (((ewin->desktop == lst[i]->desktop) || + (lst[i]->sticky)) && + (!(lst[i]->floating)) && + (!(lst[i]->ignorearrange))) + { + if (IN_BELOW(ewin->y + dy, lst[i]->y + lst[i]->h - 1, + mode.edge_snap_dist) && + SPANS_COMMON(ewin->x, ewin->w, lst[i]->x, lst[i]->w) + && (ewin->y >= (lst[i]->y + lst[i]->h))) + { + dy = (lst[i]->y + lst[i]->h) - ewin->y; + break; + } + } + } + } + } + if ((ewin->reqy - ewin->y) > 0) + dy = 0; + } + else if (dy > 0) + { + if (IN_ABOVE(ewin->y + ewin->h + dy, root.h, screen_snap_dist) + && ((ewin->y + ewin->h) <= root.h)) + dy = root.h - (ewin->y + ewin->h); + else if (lst) + { + for (i = 0; i < num; i++) + { + if (lst[i]) + { + if (((ewin->desktop == lst[i]->desktop) || + (lst[i]->sticky)) && + (!(lst[i]->floating)) && + (!(lst[i]->ignorearrange))) + { + if (IN_ABOVE(ewin->y + ewin->h + dy - 1, lst[i]->y, + mode.edge_snap_dist) && + SPANS_COMMON(ewin->x, ewin->w, lst[i]->x, lst[i]->w) + && ((ewin->y + ewin->h) <= lst[i]->y)) + { + dy = lst[i]->y - (ewin->y + ewin->h); + break; + } + } + } + } + } + if ((ewin->reqy - ewin->y) < 0) + dy = 0; + } + if (lst) + Efree(lst); + if ((odx != dx) || (ody != dy)) + { + AUDIO_PLAY("SOUND_MOVE_RESIST"); + } + *new_dx = dx; + *new_dy = dy; + EDBUG_RETURN_; +} diff --git a/src/arrange.h b/src/arrange.h new file mode 100644 index 00000000..efccb037 --- /dev/null +++ b/src/arrange.h @@ -0,0 +1,20 @@ + +#include +#include +#include + +#define ARRANGE_VERBATIM 0 +#define ARRANGE_BY_SIZE 1 +#define ARRANGE_BY_POSITION 2 + +typedef struct _rectbox + { + void *data; + int x, y, w, h; + int p; + } +RectBox; + +void ArrangeRects(RectBox * fixed, int fixed_count, RectBox * floating, + int floating_count, RectBox * sorted, int width, int height, + int policy); diff --git a/src/atoms.c b/src/atoms.c new file mode 100644 index 00000000..68228797 --- /dev/null +++ b/src/atoms.c @@ -0,0 +1,104 @@ + +#include "E.h" + +void * +AtomGet(Window win, Atom to_get, Atom type, int *size) +{ + unsigned char *retval; + Atom type_ret; + unsigned long bytes_after, num_ret; + int format_ret; + long length; + void *data; + + EDBUG(5, "AtomGet"); + + retval = NULL; + length = 0x7fffffff; + XGetWindowProperty(disp, win, to_get, 0, + length, + False, type, + &type_ret, + &format_ret, + &num_ret, + &bytes_after, + &retval); + if ((retval) && (num_ret > 0) && (format_ret > 0)) + { + if (format_ret == 32) + { + int i; + + *size = num_ret * sizeof(unsigned long); + + data = Emalloc(*size); + for (i = 0; i < (int)num_ret; i++) + ((unsigned long *)data)[i] = ((unsigned long *)retval)[i]; + } + else if (format_ret == 16) + { + int i; + + *size = num_ret * sizeof(unsigned short); + + data = Emalloc(*size); + for (i = 0; i < (int)num_ret; i++) + ((unsigned short *)data)[i] = ((unsigned short *)retval)[i]; + } + else + { + /* format_ret == 8 */ + *size = num_ret; + data = Emalloc(num_ret); + if (data) + memcpy(data, retval, num_ret); + } + XFree(retval); + EDBUG_RETURN(data); + } + EDBUG_RETURN(NULL); + +} + +void +setSimpleHint(Window win, Atom atom, long value) +{ + + EDBUG(5, "setSimpleHint"); + + XChangeProperty(disp, win, atom, atom, 32, PropModeReplace, + (unsigned char *)&value, 1); + + EDBUG_RETURN_; + +} + +long * +getSimpleHint(Window win, Atom atom) +{ + + long *data = 0; + Atom type_ret; + int fmt_ret; + unsigned long nitems_ret; + unsigned long bytes_after_ret; + + EDBUG(5, "getSimpleHint"); + + if (!atom) + EDBUG_RETURN(NULL); + + if (XGetWindowProperty(disp, win, atom, 0, 1, False, atom, + &type_ret, &fmt_ret, &nitems_ret, &bytes_after_ret, + (unsigned char **)&data) != Success || !data) + { + EDBUG_RETURN(NULL); + } + if (atom != AnyPropertyType && atom != type_ret) + { + XFree(data); + EDBUG_RETURN(NULL); + } + EDBUG_RETURN((long *)data); + +} diff --git a/src/borders.c b/src/borders.c new file mode 100644 index 00000000..efbb1694 --- /dev/null +++ b/src/borders.c @@ -0,0 +1,3045 @@ + +#include "E.h" + +void +DetermineEwinFloat(EWin * ewin, int dx, int dy) +{ + char dofloat = 0; + + EDBUG(5, "DetermineEwinFloat"); + + if ((ewin->desktop != 0) && (ewin->floating < 2) && + ((desks.desk[ewin->desktop].x != 0) + || (desks.desk[ewin->desktop].y != 0) + || (desks.current != ewin->desktop))) + { + if ((desks.dragdir == 0) && + (((ewin->x + dx < 0) || + ((ewin->x + dx + ewin->w <= root.w) && + ((DesktopAt(desks.desk[ewin->desktop].x + ewin->x + dx + + ewin->w - 1, + desks.desk[ewin->desktop].y) + != ewin->desktop)))))) + dofloat = 1; + if ((desks.dragdir == 1) && + (((ewin->x + dx + ewin->w > root.w) || + ((ewin->x + dx >= 0) && + ((DesktopAt(desks.desk[ewin->desktop].x + ewin->x + dx, + desks.desk[ewin->desktop].y) + != ewin->desktop)))))) + dofloat = 1; + if ((desks.dragdir == 2) && + (((ewin->y + dy < 0) || + ((ewin->y + dy + ewin->h <= root.h) && + ((DesktopAt(desks.desk[ewin->desktop].x, + desks.desk[ewin->desktop].y + ewin->y + dy + + ewin->h - 1) + != ewin->desktop)))))) + dofloat = 1; + if ((desks.dragdir == 3) && + (((ewin->y + dy + ewin->h > root.h) || + ((ewin->y + dy >= 0) && + ((DesktopAt(desks.desk[ewin->desktop].x, + desks.desk[ewin->desktop].y + ewin->y + dy) + != ewin->desktop)))))) + dofloat = 1; + if (dofloat) + FloatEwinAt(ewin, ewin->x + desks.desk[ewin->desktop].x, + ewin->y + desks.desk[ewin->desktop].y); + } + EDBUG_RETURN_; +} + +void +SetEInfoOnAll() +{ + int i, num; + EWin **lst; + + EDBUG(5, "SetEInfoOnAll"); + + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if ((lst) && (num > 0)) + { + for (i = 0; i < num; i++) + ICCCM_SetEInfo(lst[i]); + Efree(lst); + } + ICCCM_SetMainEInfo(); + + EDBUG_RETURN_; +} + +EWin * +GetEwinPointerInClient() +{ + Window rt, ch; + int dum, px, py, d, i; + + EDBUG(5, "GetEwinPointerInClient"); + d = DESKTOPS_WRAP_NUM(DesktopAt(mode.x, mode.y)); + XQueryPointer(disp, desks.desk[d].win, &rt, &ch, &(mode.x), &(mode.y), + &dum, &dum, (unsigned int *)&dum); + px = mode.x - desks.desk[d].x; + py = mode.y - desks.desk[d].y; + + for (i = 0; i < desks.desk[d].num; i++) + { + int x, y, w, h; + + x = desks.desk[d].list[i]->x; + y = desks.desk[d].list[i]->y; + w = desks.desk[d].list[i]->w; + h = desks.desk[d].list[i]->h; + if ((px >= x) && (py >= y) && (px < (x + w)) && (py < (y + h)) && + (desks.desk[d].list[i]->visible)) + EDBUG_RETURN(desks.desk[d].list[i]); + } + EDBUG_RETURN(NULL); +} + +EWin * +GetEwin(void) +{ + EDBUG(4, "GetEwin"); + EDBUG_RETURN(mode.ewin); +} + +EWin * +GetFocusEwin(void) +{ + EDBUG(4, "GetFocusEwin"); + + if (mode.cur_menu_mode) + { + if (mode.context_ewin) + { + EDBUG_RETURN(mode.context_ewin); + } + EDBUG_RETURN(mode.realfocuswin); + } + + if (mode.borderpartpress) + { + if (mode.context_ewin) + { + EDBUG_RETURN(mode.context_ewin); + } + else + { + EDBUG_RETURN(mode.realfocuswin); + } + } + + if (mode.mode != MODE_NONE) + EDBUG_RETURN(GetEwin()); + + if (mode.focuswin) + EDBUG_RETURN(mode.focuswin); + + EDBUG_RETURN(mode.ewin); +} + +void +SlideEwinTo(EWin * ewin, int fx, int fy, int tx, int ty, int speed) +{ + int k, spd, x, y, min, tmpx, tmpy, tmpw, tmph; + struct timeval timev1, timev2; + int dsec, dusec; + double tm; + char firstlast; + Window winid; + + EDBUG(3, "SlideEwinTo"); + winid = ewin->client.win; + spd = 16; + min = 2; + firstlast = 0; + mode.doingslide = 1; + ApplySclass(FindItem("SOUND_WINDOW_SLIDE", 0, + LIST_FINDBY_NAME, LIST_TYPE_SCLASS)); + + if (mode.slidemode > 0) + GrabX(); + + for (k = 0; k <= 1024; k += spd) + { + gettimeofday(&timev1, NULL); + x = ((fx * (1024 - k)) + (tx * k)) >> 10; + y = ((fy * (1024 - k)) + (ty * k)) >> 10; + tmpx = x; + tmpy = y; + tmpw = ewin->client.w; + tmph = ewin->client.h; + DrawEwinShape(ewin, mode.slidemode, tmpx, tmpy, tmpw, tmph, firstlast); + if (firstlast == 0) + firstlast = 1; + XSync(disp, False); + gettimeofday(&timev2, NULL); + dsec = timev2.tv_sec - timev1.tv_sec; + dusec = timev2.tv_usec - timev1.tv_usec; + if (dusec < 0) + { + dsec--; + dusec += 1000000; + } + tm = (double)dsec + (((double)dusec) / 1000000); + spd = (int)((double)speed * tm); + if (spd < min) + spd = min; + } + DrawEwinShape(ewin, mode.slidemode, x, y, ewin->client.w, + ewin->client.h, 2); + MoveEwin(ewin, tx, ty); + mode.doingslide = 0; + if (mode.slidemode > 0) + UngrabX(); + ApplySclass(FindItem("SOUND_WINDOW_SLIDE_END", 0, + LIST_FINDBY_NAME, LIST_TYPE_SCLASS)); + EDBUG_RETURN_; +} + +void +SlideEwinsTo(EWin ** ewin, int *fx, int *fy, int *tx, int *ty, + int num_wins, int speed) +{ + int k, spd, *x = NULL, *y = NULL, min, tmpx, tmpy, tmpw, + tmph, i; + struct timeval timev1, timev2; + int dsec, dusec; + double tm; + char firstlast; + + EDBUG(3, "SlideEwinsTo"); + + if (num_wins) + { + x = Emalloc(sizeof(int) * num_wins); + y = Emalloc(sizeof(int) * num_wins); + } + spd = 16; + min = 2; + firstlast = 0; + mode.doingslide = 1; + ApplySclass(FindItem("SOUND_WINDOW_SLIDE", 0, + LIST_FINDBY_NAME, LIST_TYPE_SCLASS)); + if (mode.slidemode > 0) + GrabX(); + for (k = 0; k <= 1024; k += spd) + { + for (i = 0; i < num_wins; i++) + { + if (ewin[i]) + { + gettimeofday(&timev1, NULL); + x[i] = ((fx[i] * (1024 - k)) + (tx[i] * k)) >> 10; + y[i] = ((fy[i] * (1024 - k)) + (ty[i] * k)) >> 10; + tmpx = x[i]; + tmpy = y[i]; + tmpw = ewin[i]->client.w; + tmph = ewin[i]->client.h; + DrawEwinShape(ewin[i], 0, tmpx, tmpy, tmpw, tmph, firstlast); + if (firstlast == 0) + firstlast = 1; + XSync(disp, False); + gettimeofday(&timev2, NULL); + dsec = timev2.tv_sec - timev1.tv_sec; + dusec = timev2.tv_usec - timev1.tv_usec; + if (dusec < 0) + { + dsec--; + dusec += 1000000; + } + tm = (double)dsec + (((double)dusec) / 1000000); + spd = (int)((double)speed * tm); + if (spd < min) + spd = min; + } + } + } + + for (i = 0; i < num_wins; i++) + { + if (ewin[i]) + { + DrawEwinShape(ewin[i], 0, x[i], y[i], ewin[i]->client.w, + ewin[i]->client.h, 2); + MoveEwin(ewin[i], tx[i], ty[i]); + } + } + + mode.doingslide = 0; + if (mode.slidemode > 0) + UngrabX(); + ApplySclass(FindItem("SOUND_WINDOW_SLIDE_END", 0, + LIST_FINDBY_NAME, LIST_TYPE_SCLASS)); + if (x) + Efree(x); + if (y) + Efree(y); + EDBUG_RETURN_; +} + +void +AddToFamily(Window win) +{ + EWin *ewin, *ewin2; + EWin **lst; + Button **blst; + int i, j, k, num, speed, fx, fy, x, y; + char doslide, manplace; + char pq; + RectBox *fixed, *ret, newrect; + Window winid; + char cangrab = 0; + + EDBUG(3, "AddToFamily"); + /* find the client window if it's already managed */ + ewin = FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + /* it's already managed */ + if (ewin) + { + /* if its iconified - de-iconify */ + if (ewin->iconified) + { + RemoveMiniIcon(ewin); + ewin->desktop = desks.current; + MoveEwinToArea(ewin, + desks.desk[desks.current].current_area_x, + desks.desk[desks.current].current_area_y); + RaiseEwin(ewin); + ConformEwinToDesktop(ewin); + ShowEwin(ewin); + ICCCM_DeIconify(ewin); + mode.destroy = 1; + } + EDBUG_RETURN_; + } + /* grab that server */ + GrabX(); + winid = win; + speed = mode.slidespeedmap; + doslide = mode.mapslide; + manplace = 0; + /* adopt the new baby */ + ewin = Adopt(win); + /* if is an afterstep/windowmaker dock app 0- dock it */ + if (ewin->docked) + { + DockIt(ewin); + EDBUG_RETURN_; + } + /* if set for borderless then dont slide it in */ + if ((!ewin->client.mwm_decor_title) && (!ewin->client.mwm_decor_border)) + doslide = 0; + if (!mode.startup) + { + if (ewin->client.start_iconified) + ewin->iconified = 1; + } + x = 0; + y = 0; + DetermineEwinArea(ewin); + ResizeEwin(ewin, ewin->client.w, ewin->client.h); + + /* tag the parent window if this is a transient */ + if (ewin->client.transient) + { + ewin2 = FindItem(NULL, ewin->client.transient_for, LIST_FINDBY_ID, + LIST_TYPE_EWIN); + if (ewin2) + ewin2->has_transients++; + } + if ((mode.transientsfollowleader) && + (ewin->client.transient)) + { + ewin2 = FindItem(NULL, ewin->client.transient_for, LIST_FINDBY_ID, + LIST_TYPE_EWIN); + if (ewin2) + { + ewin->desktop = ewin2->desktop; + if ((mode.switchfortransientmap) && + (ewin->desktop != desks.current) && + (!ewin->iconified)) + { + GotoDesktop(ewin->desktop); + SetCurrentArea(ewin2->area_x, ewin2->area_y); + } + } + else + { + ewin2 = FindItem(NULL, ewin->client.group, LIST_FINDBY_ID, + LIST_TYPE_EWIN); + if (ewin2) + { + ewin->desktop = ewin2->desktop; + if ((mode.switchfortransientmap) && + (ewin->desktop != desks.current) && + (!ewin->iconified)) + { + GotoDesktop(ewin->desktop); + SetCurrentArea(ewin2->area_x, ewin2->area_y); + } + } + else + { + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if ((lst) && (num > 0)) + { + for (i = 0; i < num; i++) + { + if ((!lst[i]->iconified) && + (ewin->client.group == lst[i]->client.group)) + { + ewin->desktop = lst[i]->desktop; + if ((mode.switchfortransientmap) && + (ewin->desktop != desks.current) && + (!ewin->iconified)) + { + GotoDesktop(ewin->desktop); + SetCurrentArea(lst[i]->area_x, lst[i]->area_y); + } + i = num; + } + } + Efree(lst); + } + } + } + } + /* if it hasnt been planed on a desktop - assing it the current desktop */ + if (ewin->desktop < 0) + ewin->desktop = desks.current; + /* assign it the desktop it asked for (modulo the number of desks) */ + else + ewin->desktop = DESKTOPS_WRAP_NUM(ewin->desktop); + + if ((!ewin->client.transient) && (mode.manual_placement) && + (!ewin->client.already_placed) && (!mode.startup) && (!mode.place)) + { + cangrab = GrabThePointer(root.win); + if ((cangrab == GrabNotViewable) || (cangrab == AlreadyGrabbed) || + (cangrab == GrabFrozen)) + { + XUngrabPointer(disp, CurrentTime); + cangrab = 0; + } + else + { + manplace = 1; + cangrab = 1; + } + } + /* if it hasn't been placed yet.... find a spot for it */ + if ((!ewin->client.already_placed) && (!manplace)) + { + ewin->client.already_placed = 1; + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if ((lst) && (num > 0)) + { + fixed = Emalloc(sizeof(RectBox) * num); + ret = Emalloc(sizeof(RectBox) * (num + 1)); + j = 0; + for (i = 0; i < num; i++) + { + if ((lst[i] != ewin) && (!lst[i]->iconified) && + (!lst[i]->ignorearrange) && (lst[i]->layer != 0) && + (((lst[i]->area_x == desks.desk[ewin->desktop].current_area_x) && + (lst[i]->area_y == desks.desk[ewin->desktop].current_area_y) && + (lst[i]->desktop == ewin->desktop)) || + (lst[i]->sticky))) + { + fixed[j].data = lst[i]; + fixed[j].x = (lst[i])->x; + fixed[j].y = (lst[i])->y; + fixed[j].w = (lst[i])->w; + if (!(lst[i])->never_use_area) + fixed[j].p = (lst[i])->layer; + else + fixed[j].p = 50; + fixed[j++].h = (lst[i])->h; + } + } + blst = (Button **) ListItemType(&num, LIST_TYPE_BUTTON); + if (blst) + { + fixed = Erealloc(fixed, sizeof(RectBox) * (num + j)); + ret = Erealloc(ret, sizeof(RectBox) * ((num + j) + 1)); + for (i = 0; i < num; i++) + { + if (((blst[i]->desktop == ewin->desktop) || + ((blst[i]->desktop == 0) && (blst[i]->sticky))) && + (blst[i]->visible)) + { + fixed[j].data = NULL; + fixed[j].x = blst[i]->x; + fixed[j].y = blst[i]->y; + fixed[j].w = blst[i]->w; + if (blst[i]->sticky) + fixed[j].p = 50; + else + fixed[j].p = 0; + fixed[j++].h = blst[i]->h; + } + } + Efree(blst); + } + newrect.data = ewin; + newrect.x = 0; + newrect.y = 0; + newrect.w = ewin->w; + newrect.h = ewin->h; + newrect.p = ewin->layer; + ArrangeRects(fixed, j, &newrect, 1, ret, root.w, root.h, ARRANGE_BY_SIZE); + for (i = 0; i < j + 1; i++) + { + if (ret[i].data == ewin) + { + x = ret[i].x; + y = ret[i].y; + i = j + 1; + } + } + Efree(lst); + if (ret) + Efree(ret); + if (fixed) + Efree(fixed); + } + else + { + x = (root.w - ewin->w) >> 1; + y = (root.h - ewin->h) >> 1; + } + } + else + { + x = ewin->client.x; + y = ewin->client.y; + } + /* add it to our list of managed clients */ + AddItem(ewin, "EWIN", ewin->client.win, LIST_TYPE_EWIN); + DesktopAddEwinToTop(ewin); + /* if the window asked to be iconified at the start */ + if (ewin->iconified) + { + pq = queue_up; + queue_up = 0; + DrawEwin(ewin); + PropagateShapes(ewin->win); + queue_up = pq; + MoveEwinToDesktopAt(ewin, ewin->desktop, x, y); + RaiseEwin(ewin); + if (init_win1) + { + XRaiseWindow(disp, init_win1); + XRaiseWindow(disp, init_win2); + } + if (init_win_ext) + XRaiseWindow(disp, init_win_ext); + ShowEdgeWindows(); + RaiseProgressbars(); + ShowEwin(ewin); + StackDesktops(); + IconifyEwin(ewin); + EDBUG_RETURN_; + } + /* if we should slide it in and are not currently in the middle of a slide */ + if ((manplace) && (!ewin->client.already_placed)) + { + int rx, ry, wx, wy; + unsigned int mask; + Window junk, root_return; + + /* if the loser has manual placement on and the app asks to be on */ + /* a desktop, then send E to that desktop so the user can place */ + /* the window there */ + if (ewin->desktop >= 0) + GotoDesktop(ewin->desktop); + XQueryPointer(disp, root.win, &root_return, &junk, &rx, &ry, + &wx, &wy, &mask); + mode.x = rx; + mode.y = ry; + ewin->client.already_placed = 1; + x = mode.x + 1; + y = mode.y + 1; + pq = queue_up; + queue_up = 0; + DrawEwin(ewin); + ICCCM_Configure(ewin); + PropagateShapes(ewin->win); + queue_up = pq; + MoveEwinToDesktop(ewin, ewin->desktop); + RaiseEwin(ewin); + MoveEwin(ewin, x, y); + RaiseEwin(ewin); + if (init_win1) + { + XRaiseWindow(disp, init_win1); + XRaiseWindow(disp, init_win2); + } + if (init_win_ext) + XRaiseWindow(disp, init_win_ext); + ShowEdgeWindows(); + RaiseProgressbars(); + ShowEwin(ewin); + StackDesktops(); + FocusToEWin(ewin); + mode.ewin = ewin; + GrabThePointer(root.win); + mode.have_place_grab = 1; + mode.place = 1; + ICCCM_Configure(ewin); + UngrabX(); + doMove(NULL); + EDBUG_RETURN_; + } + else if ((doslide) && (!mode.doingslide)) + { + MoveEwin(ewin, root.w, root.h); + k = rand() % 4; + if (k == 0) + { + fx = (rand() % (root.w)) - ewin->w; + fy = -ewin->h; + } + else if (k == 1) + { + fx = (rand() % (root.w)); + fy = root.h; + } + else if (k == 2) + { + fx = -ewin->w; + fy = (rand() % (root.h)); + } + else + { + fx = root.w; + fy = (rand() % (root.h)) - ewin->h; + } + pq = queue_up; + queue_up = 0; + DrawEwin(ewin); + PropagateShapes(ewin->win); + queue_up = pq; + MoveEwinToDesktop(ewin, ewin->desktop); + RaiseEwin(ewin); + MoveEwin(ewin, fx, fy); + if (init_win1) + { + XRaiseWindow(disp, init_win1); + XRaiseWindow(disp, init_win2); + } + if (init_win_ext) + XRaiseWindow(disp, init_win_ext); + ShowEdgeWindows(); + RaiseProgressbars(); + ShowEwin(ewin); + SlideEwinTo(ewin, fx, fy, x, y, speed); + MoveEwinToDesktopAt(ewin, ewin->desktop, x, y); + StackDesktops(); + } + else + { + pq = queue_up; + queue_up = 0; + DrawEwin(ewin); + PropagateShapes(ewin->win); + queue_up = pq; + MoveEwinToDesktopAt(ewin, ewin->desktop, x, y); + RaiseEwin(ewin); + if (init_win1) + { + XRaiseWindow(disp, init_win1); + XRaiseWindow(disp, init_win2); + } + if (init_win_ext) + XRaiseWindow(disp, init_win_ext); + ShowEdgeWindows(); + RaiseProgressbars(); + ShowEwin(ewin); + StackDesktops(); + } + /* send synthetic configure notifies and configure the window */ + ICCCM_Configure(ewin); + + DetermineEwinArea(ewin); + if (mode.all_new_windows_get_focus) + { + FocusToEWin(ewin); + if ((ewin->desktop != desks.current) && + (!ewin->iconified)) + { + GotoDesktop(ewin->desktop); + SetCurrentArea(ewin->area_x, ewin->area_y); + } + } + else if (mode.new_transients_get_focus) + { + if (ewin->client.transient) + { + FocusToEWin(ewin); + if ((ewin->desktop != desks.current) && + (!ewin->iconified)) + { + GotoDesktop(ewin->desktop); + SetCurrentArea(ewin->area_x, ewin->area_y); + } + } + } + else if (mode.new_transients_get_focus_if_group_focused) + { + ewin2 = FindItem(NULL, ewin->client.transient_for, LIST_FINDBY_ID, + LIST_TYPE_EWIN); + if ((ewin2) && (mode.focuswin == ewin2)) + { + FocusToEWin(ewin); + if ((ewin->desktop != desks.current) && + (!ewin->iconified)) + { + GotoDesktop(ewin->desktop); + SetCurrentArea(ewin->area_x, ewin->area_y); + } + } + } + UngrabX(); + EDBUG_RETURN_; +} + +EWin * +AddInternalToFamily(Window win, char noshow, char *bname) +{ + EWin *ewin; + int x, y; + char pq; + Window winid; + Border *b; + + EDBUG(3, "AddInternalToFamily"); + winid = win; + b = NULL; + if (bname) + b = FindItem(bname, 0, LIST_FINDBY_NAME, LIST_TYPE_BORDER); + if (!b) + b = FindItem("DEFAULT", 0, LIST_FINDBY_NAME, LIST_TYPE_BORDER); + ewin = AdoptInternal(win, b); + ResizeEwin(ewin, ewin->client.w, ewin->client.h); + if (ewin->desktop < 0) + { + ewin->desktop = desks.current; + } + else + { + ewin->desktop = DESKTOPS_WRAP_NUM(ewin->desktop); + } + x = ewin->client.x - ewin->border->border.left; + y = ewin->client.y - ewin->border->border.top; + AddItem(ewin, "EWIN", ewin->client.win, LIST_TYPE_EWIN); + pq = queue_up; + queue_up = 0; + DrawEwin(ewin); + PropagateShapes(ewin->win); + queue_up = pq; + MoveEwinToDesktopAt(ewin, ewin->desktop, x, y); + RaiseEwin(ewin); + if (init_win1) + { + XRaiseWindow(disp, init_win1); + XRaiseWindow(disp, init_win2); + } + if (init_win_ext) + XRaiseWindow(disp, init_win_ext); + ShowEdgeWindows(); + RaiseProgressbars(); + if (!noshow) + ShowEwin(ewin); + ICCCM_Configure(ewin); + UngrabX(); + EDBUG_RETURN(ewin); +} + +void +HonorIclass(char *s, int id) +{ + AwaitIclass *a; + EWin *ewin; + + EDBUG(4, "HonorIclass"); + + a = RemoveItem(s, 0, LIST_FINDBY_NAME, LIST_TYPE_AWAIT_ICLASS); + if (!a) + EDBUG_RETURN_; + + ewin = FindItem(NULL, a->client_win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + { + if (a->ewin_bit < ewin->border->num_winparts) + { + if ((ewin->border->part[a->ewin_bit].iclass->external) && + (!ewin->bits[a->ewin_bit].win) && (id)) + { + ewin->bits[a->ewin_bit].win = id; + RealiseEwinWinpart(ewin, a->ewin_bit); + EMapWindow(disp, id); + ewin->shapedone = 0; + if (!ewin->shapedone) + { + PropagateShapes(ewin->win); + } + else + { + if (ewin->border->changes_shape) + PropagateShapes(ewin->win); + } + ewin->shapedone = 1; + } + } + } + if (a->iclass) + a->iclass->ref_count--; + + Efree(a); + + EDBUG_RETURN_; +} + +void +SyncBorderToEwin(EWin * ewin) +{ + Border *b; + + EDBUG(4, "SyncBorderToEwin"); + b = ewin->border; + ICCCM_GetShapeInfo(ewin); + SetEwinBorder(ewin); + if (b != ewin->border) + { + ICCCM_MatchSize(ewin); + MoveResizeEwin(ewin, ewin->client.x, ewin->client.y, ewin->client.w, + ewin->client.h); + } + EDBUG_RETURN_; +} + +void +UpdateBorderInfo(EWin * ewin) +{ + int i; + + for (i = 0; i < ewin->border->num_winparts; i++) + { + if (ewin->border->part[i].flags == FLAG_TITLE) + ChangeEwinWinpartContents(ewin, i); + } +} + +void +RealiseEwinWinpart(EWin * ewin, int i) +{ + EDBUG(4, "RealiseEwinWinpart"); + + if ((ewin->bits[i].cx != ewin->bits[i].x) || + (ewin->bits[i].cy != ewin->bits[i].y) || + (ewin->bits[i].cw != ewin->bits[i].w) || + (ewin->bits[i].ch != ewin->bits[i].h)) + { + if ((ewin->bits[i].w < 0) || (ewin->bits[i].h < 0)) + EUnmapWindow(disp, ewin->bits[i].win); + else + EMapWindow(disp, ewin->bits[i].win); + if ((ewin->bits[i].w > 0) && (ewin->bits[i].h > 0)) + EMoveResizeWindow(disp, ewin->bits[i].win, + ewin->bits[i].x, ewin->bits[i].y, + ewin->bits[i].w, ewin->bits[i].h); + } + EDBUG_RETURN_; +} + +int +DrawEwinWinpart(EWin * ewin, int i) +{ + int move = 0, resize = 0, state = 0, ret = 0; + + EDBUG(4, "DrawEwinWinpart"); + if ((ewin->bits[i].x != ewin->bits[i].cx) || + (ewin->bits[i].y != ewin->bits[i].cy)) + move = 1; + if ((ewin->bits[i].w != ewin->bits[i].cw) || + (ewin->bits[i].h != ewin->bits[i].ch)) + resize = 1; + if ((resize) || (ewin->bits[i].expose)) + { + state = ewin->bits[i].state; + IclassApply(ewin->border->part[i].iclass, ewin->bits[i].win, + ewin->bits[i].w, ewin->bits[i].h, ewin->active, ewin->sticky, state, + ewin->bits[i].expose); + if (ewin->border->part[i].flags == FLAG_TITLE) + TclassApply(ewin->border->part[i].iclass, ewin->bits[i].win, + ewin->bits[i].w, ewin->bits[i].h, ewin->active, ewin->sticky, + state, ewin->bits[i].expose, ewin->border->part[i].tclass, + ewin->client.title); + ret = 1; + } + if ((move) || (resize)) + { + ret = 1; + ewin->bits[i].cx = ewin->bits[i].x; + ewin->bits[i].cy = ewin->bits[i].y; + ewin->bits[i].cw = ewin->bits[i].w; + ewin->bits[i].ch = ewin->bits[i].h; + } + ewin->bits[i].expose = 0; + EDBUG_RETURN(ret); +} + +int +ChangeEwinWinpart(EWin * ewin, int i) +{ + int state = 0, ret = 0; + + EDBUG(3, "ChangeEwinWinpart"); + state = ewin->bits[i].state; + IclassApply(ewin->border->part[i].iclass, ewin->bits[i].win, + ewin->bits[i].w, ewin->bits[i].h, ewin->active, ewin->sticky, state, + ewin->bits[i].expose); + if (ewin->border->part[i].flags == FLAG_TITLE) + TclassApply(ewin->border->part[i].iclass, ewin->bits[i].win, + ewin->bits[i].w, ewin->bits[i].h, ewin->active, ewin->sticky, state, + ewin->bits[i].expose, ewin->border->part[i].tclass, + ewin->client.title); + if (ewin->bits[i].win) + ChangeEwinWinpartContents(ewin, i); + if (!ewin->shapedone) + PropagateShapes(ewin->win); + else + { + if (ewin->border->changes_shape) + PropagateShapes(ewin->win); + } + ewin->shapedone = 1; + ret = 1; + EDBUG_RETURN(ret); +} + +void +DrawEwin(EWin * ewin) +{ + int i, state; + + EDBUG(4, "DrawEwin"); + + if (!ewin) + EDBUG_RETURN_; + for (i = 0; i < ewin->border->num_winparts; i++) + { + state = ewin->bits[i].state; + IclassApply(ewin->border->part[i].iclass, ewin->bits[i].win, + ewin->bits[i].w, ewin->bits[i].h, ewin->active, ewin->sticky, state, + ewin->bits[i].expose); + if (ewin->border->part[i].flags == FLAG_TITLE) + TclassApply(ewin->border->part[i].iclass, ewin->bits[i].win, + ewin->bits[i].w, ewin->bits[i].h, ewin->active, ewin->sticky, state, + ewin->bits[i].expose, ewin->border->part[i].tclass, + ewin->client.title); + } + if (!ewin->shapedone) + PropagateShapes(ewin->win); + else + { + if (ewin->border->changes_shape) + PropagateShapes(ewin->win); + } + ewin->shapedone = 1; + EDBUG_RETURN_; +} + +int +ChangeEwinWinpartContents(EWin * ewin, int i) +{ + int state = 0, ret = 0; + + EDBUG(3, "ChangeEwinWinpartContents"); + ret = 1; + switch (ewin->border->part[i].flags) + { + case FLAG_TITLE: + TclassApply(ewin->border->part[i].iclass, ewin->bits[i].win, + ewin->bits[i].w, ewin->bits[i].h, ewin->active, ewin->sticky, state, + ewin->bits[i].expose, ewin->border->part[i].tclass, + ewin->client.title); + break; + case FLAG_MINIICON: + break; + default: + break; + } + EDBUG_RETURN(ret); +} + +void +CalcEwinWinpart(EWin * ewin, int i) +{ + int x, y, w, h, ox, oy, max, min; + int topleft, bottomright; + + EDBUG(4, "CalcEwinWinpart"); + topleft = ewin->border->part[i].geom.topleft.originbox; + bottomright = ewin->border->part[i].geom.bottomright.originbox; + if (topleft >= 0) + CalcEwinWinpart(ewin, topleft); + if (bottomright >= 0) + CalcEwinWinpart(ewin, bottomright); + x = y = 0; + if (topleft == -1) + { + x = ((ewin->border->part[i].geom.topleft.x.percent * ewin->w) >> 10) + + ewin->border->part[i].geom.topleft.x.absolute; + y = ((ewin->border->part[i].geom.topleft.y.percent * ewin->h) >> 10) + + ewin->border->part[i].geom.topleft.y.absolute; + } + else if (topleft >= 0) + { + x = ((ewin->border->part[i].geom.topleft.x.percent * + ewin->bits[topleft].w) >> 10) + + ewin->border->part[i].geom.topleft.x.absolute + + ewin->bits[topleft].x; + y = ((ewin->border->part[i].geom.topleft.y.percent * + ewin->bits[topleft].h) >> 10) + + ewin->border->part[i].geom.topleft.y.absolute + + ewin->bits[topleft].y; + } + ox = oy = 0; + if (bottomright == -1) + { + ox = ((ewin->border->part[i].geom.bottomright.x.percent * ewin->w) >> 10) + + ewin->border->part[i].geom.bottomright.x.absolute; + oy = ((ewin->border->part[i].geom.bottomright.y.percent * ewin->h) >> 10) + + ewin->border->part[i].geom.bottomright.y.absolute; + } + else if (bottomright >= 0) + { + ox = ((ewin->border->part[i].geom.bottomright.x.percent * + ewin->bits[bottomright].w) >> 10) + + ewin->border->part[i].geom.bottomright.x.absolute + + ewin->bits[bottomright].x; + oy = ((ewin->border->part[i].geom.bottomright.y.percent * + ewin->bits[bottomright].h) >> 10) + + ewin->border->part[i].geom.bottomright.y.absolute + + ewin->bits[bottomright].y; + } + /* + * * calculate height before width, because we may need it in order to + * * determine the font size. + */ + + h = (oy - y) + 1; + max = ewin->border->part[i].geom.height.max; + min = ewin->border->part[i].geom.height.min; + if (h > max) + { + h = max; + y = ((y + oy) - h) >> 1; + } + else if (h < min) + { + h = min; + } + /* + * * and now the width. + */ + + w = (ox - x) + 1; + max = ewin->border->part[i].geom.width.max; + min = ewin->border->part[i].geom.width.min; + + /* + * * If the title bar max size is set to zero, then set the title bar size to + * * just a little bit more than the size of the title text. + */ + + if (max == 0 && ewin->border->part[i].flags == FLAG_TITLE) + { + int dummyheight; + ImageClass *iclass; + TextClass *tclass; + + iclass = ewin->border->part[i].iclass; + tclass = ewin->border->part[i].tclass; + TextSize(tclass, \ + ewin->active, \ + ewin->sticky, \ + ewin->bits[i].state, \ + ewin->client.title, \ + &max, \ + &dummyheight, \ + h - (iclass->padding.top + iclass->padding.bottom) \ + ); + max += iclass->padding.left + iclass->padding.right; + + if (w > max) + { + x = x + (((w - max) * tclass->justification) >> 10); + w = max; + } + } + if (w > max) + { + w = max; + x = ((x + ox) - w) >> 1; + } + else if (w < min) + { + w = min; + } + if ((ewin->shaded) && (!ewin->border->part[i].keep_for_shade)) + { + ewin->bits[i].x = -100; + ewin->bits[i].y = -100; + ewin->bits[i].w = -1; + ewin->bits[i].h = -1; + } + else + { + ewin->bits[i].x = x; + ewin->bits[i].y = y; + ewin->bits[i].w = w; + ewin->bits[i].h = h; + } + EDBUG_RETURN_; +} + +void +CalcEwinSizes(EWin * ewin) +{ + int i; + char reshape; + + EDBUG(4, "CalcEwinSizes"); + if (!ewin) + EDBUG_RETURN_; + for (i = 0; i < ewin->border->num_winparts; i++) + ewin->bits[i].w = -2; + for (i = 0; i < ewin->border->num_winparts; i++) + if (ewin->bits[i].w == -2) + CalcEwinWinpart(ewin, i); + for (i = 0; i < ewin->border->num_winparts; i++) + RealiseEwinWinpart(ewin, i); + reshape = 0; + for (i = 0; i < ewin->border->num_winparts; i++) + { + reshape |= DrawEwinWinpart(ewin, i); + ewin->bits[i].no_expose = 1; + } + if ((reshape) || (mode.have_place_grab)) + { + if (mode.have_place_grab) + { + char pq; + + pq = queue_up; + queue_up = 0; + PropagateShapes(ewin->win); + queue_up = pq; + } + else + PropagateShapes(ewin->win); + ewin->shapedone = 1; + } + EDBUG_RETURN_; +} + +EWin * +Adopt(Window win) +{ + EWin *ewin; + + EDBUG(4, "Adopt"); + GrabX(); + ewin = CreateEwin(); + ewin->client.win = win; + ICCCM_AdoptStart(ewin, win); + ICCCM_GetTitle(ewin, 0); + ICCCM_GetHints(ewin, 0); + ICCCM_GetInfo(ewin, 0); + ICCCM_GetColormap(ewin); + ICCCM_GetShapeInfo(ewin); + GNOME_GetHints(ewin, 0); + ICCCM_GetGeoms(ewin, 0); + SessionGetInfo(ewin, 0); + MatchEwinToSM(ewin); +/* ICCCM_GetEInfo(ewin); */ + MatchEwinToSnapInfo(ewin); + ICCCM_GetEInfo(ewin); + if (!ewin->border) + { + ewin->border_new = 1; + SetEwinBorder(ewin); + } + ICCCM_MatchSize(ewin); + ICCCM_Adopt(ewin, win); + UngrabX(); + if (ewin->shaded) + { + ewin->shaded = 0; + InstantShadeEwin(ewin); + } + EDBUG_RETURN(ewin); +} + +EWin * +AdoptInternal(Window win, Border * border) +{ + EWin *ewin; + + EDBUG(4, "AdoptInternal"); + GrabX(); + ewin = CreateEwin(); + ewin->internal = 1; + ewin->client.win = win; + ICCCM_AdoptStart(ewin, win); + ICCCM_GetTitle(ewin, 0); + ICCCM_GetInfo(ewin, 0); + ICCCM_GetShapeInfo(ewin); + ICCCM_GetGeoms(ewin, 0); + MatchEwinToSnapInfo(ewin); + if (!ewin->border) + { + ewin->border_new = 1; + SetEwinToBorder(ewin, border); + } + ICCCM_MatchSize(ewin); + ICCCM_Adopt(ewin, win); + UngrabX(); + if (ewin->shaded) + { + ewin->shaded = 0; + ShadeEwin(ewin); + } + EDBUG_RETURN(ewin); +} + +EWin * +CreateEwin() +{ + EWin *ewin; + XSetWindowAttributes att; + + EDBUG(5, "CreateEwin"); + ewin = Emalloc(sizeof(EWin)); + ewin->win = 0; + ewin->x = -1; + ewin->y = -1; + ewin->w = -1; + ewin->h = -1; + ewin->reqx = -1; + ewin->reqy = -1; + ewin->lx = -1; + ewin->ly = -1; + ewin->lw = -1; + ewin->lh = -1; + ewin->toggle = 0; + ewin->client.win = 0; + ewin->client.x = -1; + ewin->client.y = -1; + ewin->client.w = -1; + ewin->client.h = -1; + ewin->client.title = NULL; + ewin->client.class = NULL; + ewin->client.name = NULL; + ewin->client.role = NULL; + ewin->client.command = NULL; + ewin->client.machine = NULL; + ewin->client.icon_name = NULL; + ewin->client.is_group_leader = 0; + ewin->client.no_resize_h = 0; + ewin->client.no_resize_v = 0; + ewin->client.shaped = 0; + ewin->client.icon_win = 0; + ewin->client.icon_pmap = 0; + ewin->client.icon_mask = 0; + ewin->client.start_iconified = 0; + ewin->client.group = 0; + ewin->client.need_input = 1; + ewin->client.transient = 0; + ewin->client.client_leader = 0; + ewin->client.transient_for = 0; + ewin->client.already_placed = 0; + ewin->client.aspect_min = 0.0; + ewin->client.aspect_max = 65535.0; + ewin->client.w_inc = 1; + ewin->client.h_inc = 1; + ewin->client.base_w = 0; + ewin->client.base_h = 0; + ewin->client.width.min = 0; + ewin->client.height.min = 0; + ewin->client.width.max = 65535; + ewin->client.height.max = 65535; + ewin->client.mwm_decor_border = 1; + ewin->client.mwm_decor_resizeh = 1; + ewin->client.mwm_decor_title = 1; + ewin->client.mwm_decor_menu = 1; + ewin->client.mwm_decor_minimize = 1; + ewin->client.mwm_decor_maximize = 1; + ewin->client.mwm_func_resize = 1; + ewin->client.mwm_func_move = 1; + ewin->client.mwm_func_minimize = 1; + ewin->client.mwm_func_maximize = 1; + ewin->client.mwm_func_close = 1; + ewin->border = NULL; + ewin->previous_border = NULL; + ewin->border_new = 0; + ewin->bits = NULL; + ewin->sticky = 0; + ewin->desktop = -1; + ewin->group = 0; + ewin->visible = 0; + ewin->active = 0; + ewin->iconified = 0; + ewin->parent = 0; + ewin->layer = 4; + ewin->never_use_area = 0; + ewin->floating = 0; + ewin->win = ECreateWindow(root.win, -10, -10, 1, 1, 1); + ewin->win_container = ECreateWindow(ewin->win, 0, 0, 1, 1, 0); + ewin->shapedone = 0; + ewin->docked = 0; + ewin->shaded = 0; + ewin->fixedpos = 0; + ewin->expanded_x = 0; + ewin->expanded_y = 0; + ewin->expanded_width = -1; + ewin->expanded_height = -1; + ewin->ignorearrange = 0; + ewin->skiptask = 0; + ewin->skipwinlist = 0; + ewin->skipfocus = 0; + ewin->focusclick = 0; + ewin->internal = 0; + ewin->menu = NULL; + ewin->dialog = NULL; + ewin->shownmenu = 0; + ewin->pager = NULL; + ewin->ibox = NULL; + ewin->area_x = -1; + ewin->area_y = -1; + ewin->session_id = NULL; + ewin->has_transients = 0; + ewin->mini_w = 0; + ewin->mini_h = 0; + ewin->mini_pmap = 0; + ewin->mini_mask = 0; + ewin->snap = NULL; + ewin->icon_pmap = 0; + ewin->icon_mask = 0; + + att.event_mask = + StructureNotifyMask | ResizeRedirectMask | + ButtonPressMask | ButtonReleaseMask | + SubstructureNotifyMask | SubstructureRedirectMask; + att.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask; + XChangeWindowAttributes(disp, ewin->win_container, + CWEventMask | CWDontPropagate, &att); + EMapWindow(disp, ewin->win_container); + if (mode.focusmode == FOCUS_CLICK) + XGrabButton(disp, AnyButton, 0, ewin->win_container, False, + ButtonPressMask, + GrabModeSync, GrabModeAsync, None, None); + att.event_mask = + StructureNotifyMask | PointerMotionMask | + ButtonPressMask | ButtonReleaseMask; + att.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask; + XChangeWindowAttributes(disp, ewin->win, + CWEventMask | CWDontPropagate, &att); + GrabButtonGrabs(ewin); + EDBUG_RETURN(ewin); +} + +void +FreeEwin(EWin * ewin) +{ + EWin *ewin2; + + EDBUG(5, "FreeEwin"); + if (!ewin) + EDBUG_RETURN_; + if (GetZoomEWin() == ewin) + Zoom(NULL); + if (ewin->snap) + { + ListChangeItemID(LIST_TYPE_SNAPSHOT, ewin->snap, 0); + ewin->snap->used = 0; + ewin->snap = NULL; + } + DesktopRemoveEwin(ewin); + PagerEwinOutsideAreaUpdate(ewin); + PagerHideAllHi(); + mode.windowdestroy = 1; + /* hide any menus this ewin has brought up if they are still up when we */ + /* destroy this ewin */ + if (ewin->shownmenu) + { + Menu *m; + int i; + int ok = 0; + + m = FindMenu(ewin->shownmenu); + if (m) + { + HideMenu(m); + ok = 0; + for (i = 0; i < mode.cur_menu_depth; i++) + { + if (ok) + HideMenu(mode.cur_menu[i]); + if (mode.cur_menu[i] == m) + ok = 1; + } + HideMenuMasker(); + } + } + if (ewin->pager) + PagerKill(ewin->pager); + if (ewin->ibox) + FreeIconbox(ewin->ibox); + if (mode.context_ewin == ewin) + mode.context_ewin = NULL; + + GNOME_DelHints(ewin); + if (ewin == mode.focuswin) + FocusToEWin(NULL); + if (ewin->client.transient) + { + ewin2 = FindItem(NULL, ewin->client.transient_for, LIST_FINDBY_ID, + LIST_TYPE_EWIN); + if (ewin2) + { + ewin2->has_transients--; + if (ewin2->has_transients < 0) + ewin2->has_transients = 0; + } + } + if (ewin->border) + ewin->border->ref_count--; + if (ewin->client.title) + Efree(ewin->client.title); + if (ewin->client.class) + Efree(ewin->client.class); + if (ewin->client.name) + Efree(ewin->client.name); + if (ewin->client.role) + Efree(ewin->client.role); + if (ewin->client.command) + Efree(ewin->client.command); + if (ewin->client.machine) + Efree(ewin->client.machine); + if (ewin->client.icon_name) + Efree(ewin->client.icon_name); + if (ewin->win) + EDestroyWindow(disp, ewin->win); + if (ewin->bits) + Efree(ewin->bits); + if (ewin->session_id) + Efree(ewin->session_id); + if (ewin->mini_pmap) + EFreePixmap(disp, ewin->mini_pmap); + if (ewin->mini_mask) + EFreePixmap(disp, ewin->mini_mask); + if (ewin->icon_pmap) + Imlib_free_pixmap(id, ewin->icon_pmap); + if (ewin->icon_mask) + Imlib_free_pixmap(id, ewin->icon_mask); + Efree(ewin); + + EDBUG_RETURN_; +} + +void +SetEwinBorder(EWin * ewin) +{ + Border *b; + + EDBUG(4, "SetEwinBorder"); + b = NULL; + ICCCM_GetShapeInfo(ewin); + + if ((!ewin->client.mwm_decor_title) && (!ewin->client.mwm_decor_border)) + { + b = (Border *) FindItem("BORDERLESS", 0, LIST_FINDBY_NAME, + LIST_TYPE_BORDER); + } + else + { + b = MatchEwinByFunction(ewin, (void *(*)(EWin *, WindowMatch *)) + (MatchEwinBorder)); + } + + if (ewin->docked) + b = (Border *) FindItem("BORDERLESS", 0, LIST_FINDBY_NAME, + LIST_TYPE_BORDER); + + if (!b) + b = (Border *) FindItem("DEFAULT", 0, LIST_FINDBY_NAME, + LIST_TYPE_BORDER); + + SetEwinToBorder(ewin, b); + + EDBUG_RETURN_; +} + +void +SetEwinToBorder(EWin * ewin, Border * b) +{ + int i; + int px = -1, py = -1; + char s[1024]; + AwaitIclass *await; + + EDBUG(4, "SetEwinToBorder"); + + if (!b) + b = FindItem("__FALLBACK_BORDER", 0, + LIST_FINDBY_NAME, LIST_TYPE_BORDER); + + if ((!b) || (ewin->border == b) || (!ewin->border_new)) + EDBUG_RETURN_; + + if (ewin->border) + { + px = ewin->border->border.left; + py = ewin->border->border.top; + for (i = 0; i < ewin->border->num_winparts; i++) + { + if (ewin->bits[i].win) + EDestroyWindow(disp, ewin->bits[i].win); + } + if (ewin->bits) + Efree(ewin->bits); + ewin->bits = NULL; + ewin->border->ref_count--; + } + ewin->border_new = 0; + ewin->border = b; + b->ref_count++; + + if (b->num_winparts > 0) + ewin->bits = Emalloc(sizeof(EWinBit) * b->num_winparts); + for (i = 0; i < b->num_winparts; i++) + { + if (b->part[i].iclass->external) + { + ewin->bits[i].win = 0; + Esnprintf(s, sizeof(s), "request imageclass %s", + b->part[i].iclass->name); + CommsBroadcast(s); + await = Emalloc(sizeof(AwaitIclass)); + await->client_win = ewin->client.win; + await->ewin_bit = i; + + await->iclass = b->part[i].iclass; + if (await->iclass) + await->iclass->ref_count++; + + AddItem(await, b->part[i].iclass->name, 0, + LIST_TYPE_AWAIT_ICLASS); + } + else + { + ewin->bits[i].win = ECreateWindow(ewin->win, -10, -10, 1, 1, 0); + ApplyECursor(ewin->bits[i].win, b->part[i].ec); + EMapWindow(disp, ewin->bits[i].win); + /* + * KeyPressMask KeyReleaseMask ButtonPressMask + * ButtonReleaseMask + * EnterWindowMask LeaveWindowMask PointerMotionMask + * PointerMotionHintMask Button1MotionMask + * Button2MotionMask + * Button3MotionMask Button4MotionMask Button5MotionMask + * ButtonMotionMask KeymapStateMask ExposureMask + * VisibilityChangeMask StructureNotifyMask + * ResizeRedirectMask + * SubstructureNotifyMask SubstructureRedirectMask + * FocusChangeMask PropertyChangeMas ColormapChangeMask + * OwnerGrabButtonMask + */ + if (b->part[i].flags & FLAG_TITLE) + { + XSelectInput(disp, ewin->bits[i].win, + ExposureMask | + KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | + LeaveWindowMask | + PointerMotionMask); + } + else + { + XSelectInput(disp, ewin->bits[i].win, + KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | + LeaveWindowMask | + PointerMotionMask); + } + ewin->bits[i].x = -10; + ewin->bits[i].y = -10; + ewin->bits[i].w = -10; + ewin->bits[i].h = -10; + ewin->bits[i].cx = -99; + ewin->bits[i].cy = -99; + ewin->bits[i].cw = -99; + ewin->bits[i].ch = -99; + ewin->bits[i].state = 0; + ewin->bits[i].expose = 0; + ewin->bits[i].no_expose = 0; + ewin->bits[i].left = 0; + } + } + + { + Window *wl; + int j = 0; + + wl = Emalloc((b->num_winparts + 1) * sizeof(Window)); + for (i = b->num_winparts - 1; i >= 0; i--) + { + if (b->part[i].ontop) + wl[j++] = ewin->bits[i].win; + } + wl[j++] = ewin->win_container; + for (i = b->num_winparts - 1; i >= 0; i--) + { + if (!b->part[i].ontop) + wl[j++] = ewin->bits[i].win; + } + XRestackWindows(disp, wl, j); + Efree(wl); + } + + EMoveWindow(disp, ewin->win_container, b->border.left, b->border.top); + if ((px >= 0) && (py >= 0)) + { + MoveEwin(ewin, ewin->x + (px - ewin->border->border.left), + ewin->y + (py - ewin->border->border.top)); + } + ICCCM_Configure(ewin); + CalcEwinSizes(ewin); + PropagateShapes(ewin->win); + + EDBUG_RETURN_; +} + +void +ResizeEwin(EWin * ewin, int w, int h) +{ + char resize = 0; + + EDBUG(3, "ResizeEwin"); + if ((ewin->client.w != w) || (ewin->client.h != h)) + resize = 1; + ewin->client.w = w; + ewin->client.h = h; + ICCCM_MatchSize(ewin); + if (!ewin->shaded) + { + ewin->w = ewin->client.w + ewin->border->border.left + + ewin->border->border.right; + ewin->h = ewin->client.h + ewin->border->border.top + + ewin->border->border.bottom; + } + EResizeWindow(disp, ewin->win, ewin->w, ewin->h); + ICCCM_Configure(ewin); + CalcEwinSizes(ewin); + if ((mode.mode == MODE_NONE) && (resize)) + { + PagerEwinOutsideAreaUpdate(ewin); + ForceUpdatePagersForDesktop(ewin->desktop); + } + if (ewin->pager) + PagerResize(ewin->pager, ewin->client.w, ewin->client.h); + if (ewin->ibox) + IconboxResize(ewin->ibox, ewin->client.w, ewin->client.h); + EDBUG_RETURN_; +} + +void +DetermineEwinArea(EWin * ewin) +{ + int pax, pay; + + EDBUG(4, "DetermineEwinArea"); + + pax = ewin->area_x; + pay = ewin->area_y; + ewin->area_x = (ewin->x + (ewin->w / 2) + + (desks.desk[ewin->desktop].current_area_x * root.w)) / root.w; + ewin->area_y = (ewin->y + (ewin->h / 2) + + (desks.desk[ewin->desktop].current_area_y * root.h)) / root.h; + if ((pax != ewin->area_x) || (pay != ewin->area_y)) + { + GNOME_SetEwinArea(ewin); + } + EDBUG_RETURN_; +} + +void +MoveEwin(EWin * ewin, int x, int y) +{ + int dx, dy; + char move = 0; + static int call_depth = 0; + + EDBUG(3, "MoveEwin"); + call_depth++; + if (call_depth > 256) + { + call_depth--; + EDBUG_RETURN_; + } + dx = x - ewin->x; + dy = y - ewin->y; + if ((dx != 0) || (dy != 0)) + move = 1; + ewin->x = x; + ewin->y = y; + ewin->reqx = x; + ewin->reqy = y; + EMoveWindow(disp, ewin->win, ewin->x, ewin->y); + if (mode.mode != MODE_MOVE) + ICCCM_Configure(ewin); + DetermineEwinArea(ewin); + if (ewin->has_transients) + { + EWin **lst; + int i, num; + + lst = ListTransientsFor(ewin->client.win, &num); + if (lst) + { + for (i = 0; i < num; i++) + { + if (!((mode.flipp) && (lst[i]->floating))) + MoveEwin(lst[i], lst[i]->x + dx, lst[i]->y + dy); + } + Efree(lst); + } + } + if ((mode.mode == MODE_NONE) && (move)) + { + PagerEwinOutsideAreaUpdate(ewin); + ForceUpdatePagersForDesktop(ewin->desktop); + } + call_depth--; + EDBUG_RETURN_; +} + +void +MoveResizeEwin(EWin * ewin, int x, int y, int w, int h) +{ + int dx, dy; + char change = 0; + static int call_depth = 0; + + EDBUG(3, "MoveResizeEwin"); + call_depth++; + if (call_depth > 256) + { + call_depth--; + EDBUG_RETURN_; + } + dx = x - ewin->x; + dy = y - ewin->y; + if ((dx != 0) || (dy != 0) || (w != ewin->w) || (h != ewin->h)) + change = 1; + ewin->x = x; + ewin->y = y; + ewin->reqx = x; + ewin->reqy = y; + ewin->client.w = w; + ewin->client.h = h; + ICCCM_MatchSize(ewin); + if (!ewin->shaded) + { + ewin->w = ewin->client.w + ewin->border->border.left + + ewin->border->border.right; + ewin->h = ewin->client.h + ewin->border->border.top + + ewin->border->border.bottom; + } + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, ewin->w, ewin->h); + DetermineEwinArea(ewin); + if ((mode.mode != MODE_MOVE) || (mode.have_place_grab)) + ICCCM_Configure(ewin); + CalcEwinSizes(ewin); + if (ewin->has_transients) + { + EWin **lst; + int i, num; + + lst = ListTransientsFor(ewin->client.win, &num); + if (lst) + { + for (i = 0; i < num; i++) + { + if (!((mode.flipp) && (lst[i]->floating))) + MoveEwin(lst[i], lst[i]->x + dx, lst[i]->y + dy); + } + Efree(lst); + } + } + if ((mode.mode == MODE_NONE) && (change)) + { + PagerEwinOutsideAreaUpdate(ewin); + ForceUpdatePagersForDesktop(ewin->desktop); + } + if (ewin->pager) + PagerResize(ewin->pager, ewin->client.w, ewin->client.h); + if (ewin->ibox) + IconboxResize(ewin->ibox, ewin->client.w, ewin->client.h); + call_depth--; + EDBUG_RETURN_; +} + +void +FloatEwin(EWin * ewin) +{ + static int call_depth = 0; + + EDBUG(3, "FloatEwin"); + call_depth++; + if (call_depth > 256) + EDBUG_RETURN_; + ewin->floating = 1; + DesktopRemoveEwin(ewin); + ewin->desktop = 0; + ConformEwinToDesktop(ewin); + RaiseEwin(ewin); + if (ewin->has_transients) + { + EWin **lst; + int i, num; + + lst = ListTransientsFor(ewin->client.win, &num); + if (lst) + { + for (i = 0; i < num; i++) + FloatEwin(lst[i]); + Efree(lst); + } + } + call_depth--; + EDBUG_RETURN_; +} + +void +FloatEwinAt(EWin * ewin, int x, int y) +{ + int dx, dy; + static int call_depth = 0; + + EDBUG(3, "FloatEwinAt"); + call_depth++; + if (call_depth > 256) + EDBUG_RETURN_; + if (ewin->floating) + ewin->floating = 2; + else + ewin->floating = 1; + dx = x - ewin->x; + dy = y - ewin->y; + ewin->x = x; + ewin->y = y; + ewin->reqx = x; + ewin->reqy = y; + ConformEwinToDesktop(ewin); + if (ewin->has_transients) + { + EWin **lst; + int i, num; + + lst = ListTransientsFor(ewin->client.win, &num); + if (lst) + { + for (i = 0; i < num; i++) + FloatEwinAt(lst[i], lst[i]->x + dx, lst[i]->y + dy); + Efree(lst); + } + } + call_depth--; + EDBUG_RETURN_; +} + +void +RestackEwin(EWin * ewin) +{ + Window *wl; + EWin **lst; + int num, bnum, wnum; + int i, j, tot; + Button **blst; + EWin *ewin2; + + EDBUG(3, "RestackEwin"); + blst = (Button **) ListItemType(&bnum, LIST_TYPE_BUTTON); + num = desks.desk[ewin->desktop].num; + tot = 0; + wl = NULL; + if (ewin->floating) + { + if (blst) + Efree(blst); + XRaiseWindow(disp, ewin->win); + EDBUG_RETURN_; + } + j = -1; + for (i = ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1; i >= 0; i--) + { + if (deskorder[i] == ewin->desktop) + { + j = i - 1; + i = -1; + } + } + if (ewin->desktop != 0) + j = -1; + if (blst) + { + for (i = 0; i < bnum; i++) + { + if (blst[i]->sticky) + { + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = blst[i]->win; + } + } + } + lst = (EWin **) ListItemType(&wnum, LIST_TYPE_EWIN); + if (lst) + { + for (i = 0; i < wnum; i++) + { + if ( /* ** (lst[i]->sticky) || */ (lst[i]->floating)) + { + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = lst[i]->win; + } + } + Efree(lst); + } + if (j >= 0) + { + for (i = 0; i <= j; i++) + { + if (deskorder[i] == 0) + i = ENLIGHTENMENT_CONF_NUM_DESKTOPS; + else + { + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = desks.desk[deskorder[i]].win; + } + } + } + if (blst) + { + for (i = 0; i < bnum; i++) + { + if ((blst[i]->desktop == ewin->desktop) && + (blst[i]->ontop == 1) && (!blst[i]->sticky)) + { + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = blst[i]->win; + } + } + } + tot += num; + ewin2 = NULL; + if (mode.menu_cover_win) + { + ewin2 = FindEwinByMenu(mode.cur_menu[0]); + if (ewin2) + tot++; + } + wl = Erealloc(wl, tot * sizeof(Window)); + if ((mode.menu_cover_win) && (ewin2)) + { + j = tot - num - 1; + for (i = 0; i < num; i++) + { + wl[j++] = desks.desk[ewin->desktop].list[i]->win; + if (desks.desk[ewin->desktop].list[i]->win == ewin2->win) + wl[j++] = mode.menu_cover_win; + } + } + else + { + for (i = 0; i < num; i++) + { + wl[tot - num + i] = desks.desk[ewin->desktop].list[i]->win; + } + } + if (blst) + { + for (i = 0; i < bnum; i++) + { + if ((blst[i]->desktop == ewin->desktop) && + (blst[i]->ontop == -1) && + (!blst[i]->sticky)) + { + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = blst[i]->win; + } + } + } + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = desks.desk[ewin->desktop].win; + XRestackWindows(disp, wl, tot); + if (wl) + Efree(wl); + if (blst) + Efree(blst); + ShowEdgeWindows(); + if (mode.mode == MODE_NONE) + { + PagerEwinOutsideAreaUpdate(ewin); + ForceUpdatePagersForDesktop(ewin->desktop); + } + EDBUG_RETURN_; +} + +void +RaiseEwin(EWin * ewin) +{ + static int call_depth = 0; + + EDBUG(3, "RaiseEwin"); + call_depth++; + if (call_depth > 256) + EDBUG_RETURN_; + if (ewin->win) + { + if (ewin->floating) + XRaiseWindow(disp, ewin->win); + else + { + DesktopAddEwinToTop(ewin); + if (ewin->has_transients) + { + EWin **lst; + int i, num; + + lst = ListTransientsFor(ewin->client.win, &num); + if (lst) + { + for (i = 0; i < num; i++) + DesktopAddEwinToTop(lst[i]); + Efree(lst); + } + } + RestackEwin(ewin); + } + } + call_depth--; + EDBUG_RETURN_; +} + +void +LowerEwin(EWin * ewin) +{ + static int call_depth = 0; + + EDBUG(3, "LowerEwin"); + call_depth++; + if (call_depth > 256) + EDBUG_RETURN_; + if ((ewin->win) && (!ewin->floating)) + { + if (ewin->has_transients) + { + EWin **lst; + int i, num; + + lst = ListTransientsFor(ewin->client.win, &num); + if (lst) + { + for (i = 0; i < num; i++) + DesktopAddEwinToBottom(lst[i]); + Efree(lst); + } + } + DesktopAddEwinToBottom(ewin); + RestackEwin(ewin); + } + call_depth--; + EDBUG_RETURN_; +} + +void +ShowEwin(EWin * ewin) +{ + EDBUG(3, "ShowEwin"); + if (ewin->visible) + EDBUG_RETURN_; + if (ewin->client.win) + EMapWindow(disp, ewin->client.win); + if (ewin->win) + { + XRaiseWindow(disp, ewin->win); + if (init_win1) + { + XRaiseWindow(disp, init_win1); + XRaiseWindow(disp, init_win2); + } + if (init_win_ext) + XRaiseWindow(disp, init_win_ext); + ShowEdgeWindows(); + RaiseProgressbars(); + EMapWindow(disp, ewin->win); + } + ewin->visible = 1; + SetEwinToCurrentArea(ewin); + if (mode.mode == MODE_NONE) + { + PagerEwinOutsideAreaUpdate(ewin); + ForceUpdatePagersForDesktop(ewin->desktop); + } + EDBUG_RETURN_; +} + +void +HideEwin(EWin * ewin) +{ + EDBUG(3, "HideEwin"); + if (!ewin->visible) + EDBUG_RETURN_; + if (GetZoomEWin() == ewin) + Zoom(NULL); + if (ewin->win) + EUnmapWindow(disp, ewin->win); + ewin->visible = 0; + if (mode.mode == MODE_NONE) + { + PagerEwinOutsideAreaUpdate(ewin); + ForceUpdatePagersForDesktop(ewin->desktop); + } + EDBUG_RETURN_; +} + +void +FreeBorder(Border * b) +{ + int i; + + EDBUG(3, "FreeBorder"); + + if (!b) + EDBUG_RETURN_; + + if (b->ref_count > 0) + { + char stuff[255]; + + Esnprintf(stuff, sizeof(stuff), "%u references remain\n", b->ref_count); + DIALOG_OK("Border Error!", stuff); + EDBUG_RETURN_; + } + while (RemoveItemByPtr(b, LIST_TYPE_BORDER)); + + for (i = 0; i < b->num_winparts; i++) + { + if (b->part[i].iclass) + b->part[i].iclass->ref_count--; + if (b->part[i].tclass) + b->part[i].tclass->ref_count--; + if (b->part[i].aclass) + b->part[i].aclass->ref_count--; + if (b->part[i].ec) + b->part[i].ec->ref_count--; + } + + if (b->num_winparts > 0) + Efree(b->part); + + if (b->name) + Efree(b->name); + if (b->group_border_name) + Efree(b->group_border_name); + + EDBUG_RETURN_; +} + +Border * +CreateBorder(char *name) +{ + Border *b; + + EDBUG(5, "CreateBorder"); + + b = Emalloc(sizeof(Border)); + if (!b) + EDBUG_RETURN(NULL); + + b->name = duplicate(name); + b->group_border_name = NULL; + b->border.left = 0; + b->border.right = 0; + b->border.top = 0; + b->border.bottom = 0; + b->num_winparts = 0; + b->part = NULL; + b->changes_shape = 0; + b->shadedir = 2; + b->ref_count = 0; + + EDBUG_RETURN(b); +} + +void +AddBorderPart(Border * b, ImageClass * iclass, ActionClass * aclass, + TextClass * tclass, ECursor * ec, + char ontop, int flags, char isregion, + int wmin, int wmax, int hmin, int hmax, int torigin, + int txp, int txa, int typ, int tya, int borigin, int bxp, + int bxa, int byp, int bya, char keep_for_shade) +{ + int n; + + EDBUG(6, "AddBorderPart"); + + b->num_winparts++; + n = b->num_winparts; + + if (!b->part) + { + b->part = Emalloc(n * sizeof(WinPart)); + } + else + { + b->part = Erealloc(b->part, n * sizeof(WinPart)); + } + + if (!iclass) + iclass = FindItem("__FALLBACK_ICLASS", 0, LIST_FINDBY_NAME, + LIST_TYPE_ICLASS); + + b->part[n - 1].iclass = iclass; + if (iclass) + iclass->ref_count++; + + b->part[n - 1].aclass = aclass; + if (aclass) + aclass->ref_count++; + + b->part[n - 1].tclass = tclass; + if (tclass) + tclass->ref_count++; + + b->part[n - 1].ec = ec; + if (ec) + ec->ref_count++; + + b->part[n - 1].ontop = ontop; + b->part[n - 1].flags = flags; + b->part[n - 1].keep_for_shade = keep_for_shade; + b->part[n - 1].geom.width.min = wmin; + b->part[n - 1].geom.width.max = wmax; + b->part[n - 1].geom.height.min = hmin; + b->part[n - 1].geom.height.max = hmax; + b->part[n - 1].geom.topleft.originbox = torigin; + b->part[n - 1].geom.topleft.x.percent = txp; + b->part[n - 1].geom.topleft.x.absolute = txa; + b->part[n - 1].geom.topleft.y.percent = typ; + b->part[n - 1].geom.topleft.y.absolute = tya; + b->part[n - 1].geom.bottomright.originbox = borigin; + b->part[n - 1].geom.bottomright.x.percent = bxp; + b->part[n - 1].geom.bottomright.x.absolute = bxa; + b->part[n - 1].geom.bottomright.y.percent = byp; + b->part[n - 1].geom.bottomright.y.absolute = bya; + + EDBUG_RETURN_; +} + +#define DO_CALC \ +for (i = 0; i < ewin->border->num_winparts; i++) \ +ewin->bits[i].w = -2; \ +for (i = 0; i < ewin->border->num_winparts; i++) \ +if (ewin->bits[i].w == -2) \ +CalcEwinWinpart(ewin, i); + +#define FIND_MAX \ +*mw = 0; \ + *mh = 0; \ +for (i = 0; i < ewin->border->num_winparts; i++) \ +{ \ + if (ewin->border->part[i].keep_for_shade) \ + { \ + if (*mw < (ewin->bits[i].w + ewin->bits[i].x)) \ + *mw = ewin->bits[i].w + ewin->bits[i].x; \ + if (*mh < (ewin->bits[i].h + ewin->bits[i].y)) \ + *mh = ewin->bits[i].h + ewin->bits[i].y; \ + } \ +} + +void +MinShadeSize(EWin * ewin, int *mw, int *mh) +{ + int i, p; + + *mw = 32; + *mh = 32; + if (!ewin) + EDBUG_RETURN_; + switch (ewin->border->shadedir) + { + case 0: + case 1: + p = ewin->w; + ewin->w = ewin->border->border.left + + ewin->border->border.right; + DO_CALC; + FIND_MAX; + ewin->w = p; + DO_CALC; + break; + case 2: + case 3: + p = ewin->h; + ewin->h = ewin->border->border.top + + ewin->border->border.bottom; + DO_CALC; + FIND_MAX; + ewin->h = p; + DO_CALC; + break; + default: + break; + } +} + +void +InstantShadeEwin(EWin * ewin) +{ + XSetWindowAttributes att; + int b, d; + char pq; + + EDBUG(4, "InstantShadeEwin"); + + if (GetZoomEWin() == ewin) + EDBUG_RETURN_; + if (ewin->shaded) + EDBUG_RETURN_; + if ((ewin->border) && (!strcmp(ewin->border->name, "BORDERLESS"))) + EDBUG_RETURN_; + pq = queue_up; + queue_up = 0; + switch (ewin->border->shadedir) + { + case 0: + att.win_gravity = EastGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + MinShadeSize(ewin, &b, &d); +/* b = ewin->border->border.left; */ + ewin->shaded = 2; + ewin->w = b; + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + EMoveResizeWindow(disp, ewin->win_container, -30, -30, 1, 1); + CalcEwinSizes(ewin); + XSync(disp, False); + break; + case 1: + att.win_gravity = WestGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + MinShadeSize(ewin, &b, &d); + d = ewin->x + ewin->w - b; +/* b = ewin->border->border.right; + * d = ewin->x + ewin->w - ewin->border->border.right; */ + ewin->shaded = 2; + ewin->w = b; + ewin->x = d; + ewin->reqx = d; + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + EMoveResizeWindow(disp, ewin->win_container, -30, -30, 1, 1); + CalcEwinSizes(ewin); + XSync(disp, False); + break; + case 2: + att.win_gravity = SouthGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + MinShadeSize(ewin, &b, &d); + b = d; +/* b = ewin->border->border.top; */ + ewin->shaded = 2; + ewin->h = b; + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + EMoveResizeWindow(disp, ewin->win_container, -30, -30, 1, 1); + CalcEwinSizes(ewin); + XSync(disp, False); + break; + case 3: + att.win_gravity = SouthGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + MinShadeSize(ewin, &b, &d); + b = d; + d = ewin->y + ewin->h - b; +/* b = ewin->border->border.bottom; + * d = ewin->y + ewin->h - ewin->border->border.bottom; */ + ewin->shaded = 2; + ewin->h = b; + ewin->y = d; + ewin->reqy = d; + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + EMoveResizeWindow(disp, ewin->win_container, -30, -30, 1, 1); + CalcEwinSizes(ewin); + XSync(disp, False); + break; + default: + break; + } + PropagateShapes(ewin->win); + queue_up = pq; + GNOME_SetHint(ewin); + if (mode.mode == MODE_NONE) + { + PagerEwinOutsideAreaUpdate(ewin); + ForceUpdatePagersForDesktop(ewin->desktop); + } + EDBUG_RETURN_; +} + +void +InstantUnShadeEwin(EWin * ewin) +{ + XSetWindowAttributes att; + int b, d; + char pq; + + EDBUG(4, "InstantUnShadeEwin"); + if (GetZoomEWin() == ewin) + EDBUG_RETURN_; + if (!ewin->shaded) + EDBUG_RETURN_; + pq = queue_up; + queue_up = 0; + switch (ewin->border->shadedir) + { + case 0: + att.win_gravity = EastGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + b = ewin->client.w + ewin->border->border.left + + ewin->border->border.right; + ewin->shaded = 0; + ewin->w = b; + MoveResizeEwin(ewin, ewin->x, ewin->y, + ewin->client.w, ewin->client.h); + XSync(disp, False); + break; + case 1: + att.win_gravity = WestGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + b = ewin->client.w + ewin->border->border.left + + ewin->border->border.right; + d = ewin->x + ewin->w - (ewin->border->border.right + + ewin->client.w + + ewin->border->border.left); + ewin->shaded = 0; + ewin->w = b; + ewin->x = d; + ewin->reqx = d; + MoveResizeEwin(ewin, ewin->x, ewin->y, + ewin->client.w, ewin->client.h); + XSync(disp, False); + break; + case 2: + att.win_gravity = SouthGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + b = ewin->client.h + ewin->border->border.top + + ewin->border->border.bottom; + ewin->shaded = 0; + ewin->h = b; + MoveResizeEwin(ewin, ewin->x, ewin->y, + ewin->client.w, ewin->client.h); + XSync(disp, False); + break; + case 3: + att.win_gravity = SouthGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + b = ewin->client.h + ewin->border->border.top + + ewin->border->border.bottom; + d = ewin->y + ewin->h - (ewin->border->border.bottom + + ewin->client.h + + ewin->border->border.top); + ewin->shaded = 0; + ewin->h = b; + ewin->y = d; + ewin->reqy = d; + MoveResizeEwin(ewin, ewin->x, ewin->y, + ewin->client.w, ewin->client.h); + XSync(disp, False); + break; + default: + break; + } + PropagateShapes(ewin->win); + queue_up = pq; + GNOME_SetHint(ewin); + if (mode.mode == MODE_NONE) + { + PagerEwinOutsideAreaUpdate(ewin); + ForceUpdatePagersForDesktop(ewin->desktop); + } + EDBUG_RETURN_; +} + +void +ShadeEwin(EWin * ewin) +{ + XSetWindowAttributes att; + int i, j, speed, a, b, c, d, ww, hh; + int k, spd, min; + struct timeval timev1, timev2; + int dsec, dusec; + double tm; + + EDBUG(4, "ShadeEwin"); + + if (GetZoomEWin() == ewin) + EDBUG_RETURN_; + if (ewin->shaded) + EDBUG_RETURN_; + if ((ewin->border) && (!strcmp(ewin->border->name, "BORDERLESS"))) + EDBUG_RETURN_; + queue_up = 0; + speed = mode.shadespeed; + spd = 32; + min = 2; + GrabX(); + switch (ewin->border->shadedir) + { + case 0: + att.win_gravity = EastGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + MinShadeSize(ewin, &b, &d); +/* b = ewin->border->border.left; */ + a = ewin->w; + for (k = 0; k <= 1024; k += spd) + { + gettimeofday(&timev1, NULL); + i = ((a * (1024 - k)) + (b * k)) >> 10; + ewin->w = i; + if (ewin->w < 1) + ewin->w = 1; + ww = ewin->w - ewin->border->border.left + - ewin->border->border.right; + if (ww < 1) + ww = 1; + hh = ewin->client.h; + EMoveResizeWindow(disp, ewin->win_container, + ewin->border->border.left, ewin->border->border.top, ww, hh); + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + CalcEwinSizes(ewin); + if (ewin->client.shaped) + EShapeCombineShape(disp, ewin->win_container, ShapeBounding, + -(ewin->client.w - ww), 0, + ewin->client.win, ShapeBounding, + ShapeSet); + PropagateShapes(ewin->win); + gettimeofday(&timev2, NULL); + dsec = timev2.tv_sec - timev1.tv_sec; + dusec = timev2.tv_usec - timev1.tv_usec; + if (dusec < 0) + { + dsec--; + dusec += 1000000; + } + tm = (double)dsec + (((double)dusec) / 1000000); + spd = (int)((double)speed * tm); + if (spd < min) + spd = min; + } + ewin->shaded = 2; + ewin->w = b; + EMoveResizeWindow(disp, ewin->win_container, -30, -30, 1, 1); + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + CalcEwinSizes(ewin); + XSync(disp, False); + break; + case 1: + att.win_gravity = WestGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + MinShadeSize(ewin, &b, &d); + a = ewin->w; + c = ewin->x; + d = ewin->x + ewin->w - b; +/* a = ewin->w; + * b = ewin->border->border.right; + * c = ewin->x; + * d = ewin->x + ewin->w - ewin->border->border.right; */ + for (k = 0; k <= 1024; k += spd) + { + gettimeofday(&timev1, NULL); + i = ((a * (1024 - k)) + (b * k)) >> 10; + j = ((c * (1024 - k)) + (d * k)) >> 10; + ewin->w = i; + ewin->x = j; + ewin->reqx = j; + if (ewin->w < 1) + ewin->w = 1; + ww = ewin->w - ewin->border->border.left + - ewin->border->border.right; + if (ww < 1) + ww = 1; + hh = ewin->client.h; + EMoveResizeWindow(disp, ewin->win_container, + ewin->border->border.left, ewin->border->border.top, ww, hh); + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + CalcEwinSizes(ewin); + if (ewin->client.shaped) + EShapeCombineShape(disp, ewin->win_container, ShapeBounding, + 0, 0, + ewin->client.win, ShapeBounding, + ShapeSet); + PropagateShapes(ewin->win); + gettimeofday(&timev2, NULL); + dsec = timev2.tv_sec - timev1.tv_sec; + dusec = timev2.tv_usec - timev1.tv_usec; + if (dusec < 0) + { + dsec--; + dusec += 1000000; + } + tm = (double)dsec + (((double)dusec) / 1000000); + spd = (int)((double)speed * tm); + if (spd < min) + spd = min; + } + ewin->shaded = 2; + ewin->w = b; + ewin->x = d; + ewin->reqx = d; + EMoveResizeWindow(disp, ewin->win_container, -30, -30, 1, 1); + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + CalcEwinSizes(ewin); + XSync(disp, False); + break; + case 2: + att.win_gravity = SouthGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + a = ewin->h; + MinShadeSize(ewin, &b, &d); + b = d; +/* b = ewin->border->border.top; */ + for (k = 0; k <= 1024; k += spd) + { + gettimeofday(&timev1, NULL); + i = ((a * (1024 - k)) + (b * k)) >> 10; + ewin->h = i; + if (ewin->h < 1) + ewin->h = 1; + hh = ewin->h - ewin->border->border.top + - ewin->border->border.bottom; + if (hh < 1) + hh = 1; + ww = ewin->client.w; + EMoveResizeWindow(disp, ewin->win_container, + ewin->border->border.left, ewin->border->border.top, ww, hh); + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + CalcEwinSizes(ewin); + if (ewin->client.shaped) + EShapeCombineShape(disp, ewin->win_container, ShapeBounding, + 0, -(ewin->client.h - hh), + ewin->client.win, ShapeBounding, ShapeSet); + PropagateShapes(ewin->win); + gettimeofday(&timev2, NULL); + dsec = timev2.tv_sec - timev1.tv_sec; + dusec = timev2.tv_usec - timev1.tv_usec; + if (dusec < 0) + { + dsec--; + dusec += 1000000; + } + tm = (double)dsec + (((double)dusec) / 1000000); + spd = (int)((double)speed * tm); + if (spd < min) + spd = min; + } + ewin->shaded = 2; + ewin->h = b; + EMoveResizeWindow(disp, ewin->win_container, -30, -30, 1, 1); + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + CalcEwinSizes(ewin); + XSync(disp, False); + break; + case 3: + att.win_gravity = SouthGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + MinShadeSize(ewin, &b, &d); + a = ewin->h; + b = d; + c = ewin->y; + d = ewin->y + ewin->h - b; +/* a = ewin->h; + * b = ewin->border->border.bottom; + * c = ewin->y; + * d = ewin->y + ewin->h - ewin->border->border.bottom; */ + for (k = 0; k <= 1024; k += spd) + { + gettimeofday(&timev1, NULL); + i = ((a * (1024 - k)) + (b * k)) >> 10; + j = ((c * (1024 - k)) + (d * k)) >> 10; + ewin->h = i; + ewin->y = j; + ewin->reqy = j; + if (ewin->h < 1) + ewin->h = 1; + hh = ewin->h - ewin->border->border.top + - ewin->border->border.bottom; + if (hh < 1) + hh = 1; + ww = ewin->client.w; + EMoveResizeWindow(disp, ewin->win_container, + ewin->border->border.left, ewin->border->border.top, ww, hh); + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + CalcEwinSizes(ewin); + if (ewin->client.shaped) + EShapeCombineShape(disp, ewin->win_container, ShapeBounding, + 0, 0, + ewin->client.win, ShapeBounding, + ShapeSet); + PropagateShapes(ewin->win); + gettimeofday(&timev2, NULL); + dsec = timev2.tv_sec - timev1.tv_sec; + dusec = timev2.tv_usec - timev1.tv_usec; + if (dusec < 0) + { + dsec--; + dusec += 1000000; + } + tm = (double)dsec + (((double)dusec) / 1000000); + spd = (int)((double)speed * tm); + if (spd < min) + spd = min; + } + ewin->shaded = 2; + ewin->h = b; + ewin->y = d; + ewin->reqy = d; + EMoveResizeWindow(disp, ewin->win_container, -30, -30, 1, 1); + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + CalcEwinSizes(ewin); + XSync(disp, False); + break; + default: + break; + } + UngrabX(); + if (ewin->client.shaped) + EShapeCombineShape(disp, ewin->win_container, ShapeBounding, 0, 0, + ewin->client.win, ShapeBounding, ShapeSet); + PropagateShapes(ewin->win); + queue_up = 1; + GNOME_SetHint(ewin); + if (mode.mode == MODE_NONE) + { + PagerEwinOutsideAreaUpdate(ewin); + ForceUpdatePagersForDesktop(ewin->desktop); + } + EDBUG_RETURN_; +} + +void +UnShadeEwin(EWin * ewin) +{ + XSetWindowAttributes att; + int i, j, speed, a, b, c, d; + int k, spd, min; + struct timeval timev1, timev2; + int dsec, dusec; + double tm; + + EDBUG(4, "UnShadeEwin"); + if (GetZoomEWin() == ewin) + EDBUG_RETURN_; + if (!ewin->shaded) + EDBUG_RETURN_; + queue_up = 0; + speed = mode.shadespeed; + spd = 32; + min = 2; + GrabX(); + switch (ewin->border->shadedir) + { + case 0: + att.win_gravity = EastGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + a = ewin->border->border.left; + b = ewin->client.w + ewin->border->border.left + + ewin->border->border.right; + ewin->shaded = 0; + EMoveResizeWindow(disp, ewin->win_container, + ewin->border->border.left, + ewin->border->border.top, + 1, ewin->client.h); + EMoveResizeWindow(disp, ewin->client.win, -ewin->client.w, 0, + ewin->client.w, ewin->client.h); + EMapWindow(disp, ewin->client.win); + EMapWindow(disp, ewin->win_container); + for (k = 0; k <= 1024; k += spd) + { + gettimeofday(&timev1, NULL); + i = ((a * (1024 - k)) + (b * k)) >> 10; + ewin->w = i; + EMoveResizeWindow(disp, ewin->win_container, + ewin->border->border.left, ewin->border->border.top, + ewin->w - ewin->border->border.left - + ewin->border->border.right, + ewin->client.h); + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + CalcEwinSizes(ewin); + if (ewin->client.shaped) + EShapeCombineShape(disp, ewin->win_container, ShapeBounding, + -(ewin->client.w - + (ewin->w - ewin->border->border.left - + ewin->border->border.right)), + 0, + ewin->client.win, ShapeBounding, ShapeSet); + PropagateShapes(ewin->win); + gettimeofday(&timev2, NULL); + dsec = timev2.tv_sec - timev1.tv_sec; + dusec = timev2.tv_usec - timev1.tv_usec; + if (dusec < 0) + { + dsec--; + dusec += 1000000; + } + tm = (double)dsec + (((double)dusec) / 1000000); + spd = (int)((double)speed * tm); + if (spd < min) + spd = min; + } + ewin->w = b; + queue_up = 1; + MoveResizeEwin(ewin, ewin->x, ewin->y, + ewin->client.w, ewin->client.h); + XSync(disp, False); + break; + case 1: + att.win_gravity = WestGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + a = ewin->border->border.right; + b = ewin->client.w + ewin->border->border.left + + ewin->border->border.right; + c = ewin->x; + d = ewin->x + ewin->w - (ewin->border->border.right + + ewin->client.w + + ewin->border->border.left); + ewin->shaded = 0; + EMoveResizeWindow(disp, ewin->win_container, + ewin->border->border.left, + ewin->border->border.top, + 1, ewin->client.h); + EMoveResizeWindow(disp, ewin->client.win, 0, 0, + ewin->client.w, ewin->client.h); + EMapWindow(disp, ewin->client.win); + EMapWindow(disp, ewin->win_container); + for (k = 0; k <= 1024; k += spd) + { + gettimeofday(&timev1, NULL); + i = ((a * (1024 - k)) + (b * k)) >> 10; + j = ((c * (1024 - k)) + (d * k)) >> 10; + ewin->w = i; + ewin->x = j; + ewin->reqx = j; + EMoveResizeWindow(disp, ewin->win_container, + ewin->border->border.left, ewin->border->border.top, + ewin->w - ewin->border->border.left - + ewin->border->border.right, + ewin->client.h); + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + CalcEwinSizes(ewin); + if (ewin->client.shaped) + EShapeCombineShape(disp, ewin->win_container, ShapeBounding, + 0, + 0, + ewin->client.win, ShapeBounding, ShapeSet); + PropagateShapes(ewin->win); + gettimeofday(&timev2, NULL); + dsec = timev2.tv_sec - timev1.tv_sec; + dusec = timev2.tv_usec - timev1.tv_usec; + if (dusec < 0) + { + dsec--; + dusec += 1000000; + } + tm = (double)dsec + (((double)dusec) / 1000000); + spd = (int)((double)speed * tm); + if (spd < min) + spd = min; + } + ewin->w = b; + ewin->x = d; + ewin->reqx = d; + queue_up = 1; + MoveResizeEwin(ewin, ewin->x, ewin->y, + ewin->client.w, ewin->client.h); + XSync(disp, False); + break; + case 2: + att.win_gravity = SouthGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + a = ewin->border->border.top; + b = ewin->client.h + ewin->border->border.top + + ewin->border->border.bottom; + ewin->shaded = 0; + EMoveResizeWindow(disp, ewin->win_container, + ewin->border->border.left, + ewin->border->border.top, + ewin->client.w, 1); + EMoveResizeWindow(disp, ewin->client.win, 0, -ewin->client.h, + ewin->client.w, ewin->client.h); + EMapWindow(disp, ewin->client.win); + EMapWindow(disp, ewin->win_container); + for (k = 0; k <= 1024; k += spd) + { + gettimeofday(&timev1, NULL); + i = ((a * (1024 - k)) + (b * k)) >> 10; + ewin->h = i; + EMoveResizeWindow(disp, ewin->win_container, + ewin->border->border.left, ewin->border->border.top, + ewin->client.w, + ewin->h - ewin->border->border.top - + ewin->border->border.bottom); + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + CalcEwinSizes(ewin); + if (ewin->client.shaped) + EShapeCombineShape(disp, ewin->win_container, ShapeBounding, + 0, + -(ewin->client.h - + (ewin->h - ewin->border->border.top - + ewin->border->border.bottom)), + ewin->client.win, ShapeBounding, ShapeSet); + PropagateShapes(ewin->win); + gettimeofday(&timev2, NULL); + dsec = timev2.tv_sec - timev1.tv_sec; + dusec = timev2.tv_usec - timev1.tv_usec; + if (dusec < 0) + { + dsec--; + dusec += 1000000; + } + tm = (double)dsec + (((double)dusec) / 1000000); + spd = (int)((double)speed * tm); + if (spd < min) + spd = min; + } + ewin->h = b; + queue_up = 1; + MoveResizeEwin(ewin, ewin->x, ewin->y, + ewin->client.w, ewin->client.h); + XSync(disp, False); + break; + case 3: + att.win_gravity = SouthGravity; + XChangeWindowAttributes(disp, ewin->client.win, CWWinGravity, &att); + a = ewin->border->border.bottom; + b = ewin->client.h + ewin->border->border.top + + ewin->border->border.bottom; + c = ewin->y; + d = ewin->y + ewin->h - (ewin->border->border.bottom + + ewin->client.h + + ewin->border->border.top); + ewin->shaded = 0; + EMoveResizeWindow(disp, ewin->win_container, + ewin->border->border.left, + ewin->border->border.top, + ewin->client.w, 1); + EMoveResizeWindow(disp, ewin->client.win, 0, 0, + ewin->client.w, ewin->client.h); + EMapWindow(disp, ewin->client.win); + EMapWindow(disp, ewin->win_container); + for (k = 0; k <= 1024; k += spd) + { + gettimeofday(&timev1, NULL); + i = ((a * (1024 - k)) + (b * k)) >> 10; + j = ((c * (1024 - k)) + (d * k)) >> 10; + ewin->h = i; + ewin->y = j; + ewin->reqy = j; + EMoveResizeWindow(disp, ewin->win_container, + ewin->border->border.left, + ewin->border->border.top, + ewin->client.w, + ewin->h - ewin->border->border.top - + ewin->border->border.bottom); + EMoveResizeWindow(disp, ewin->win, ewin->x, ewin->y, + ewin->w, ewin->h); + CalcEwinSizes(ewin); + if (ewin->client.shaped) + EShapeCombineShape(disp, ewin->win_container, ShapeBounding, + 0, + 0, + ewin->client.win, ShapeBounding, + ShapeSet); + PropagateShapes(ewin->win); + gettimeofday(&timev2, NULL); + dsec = timev2.tv_sec - timev1.tv_sec; + dusec = timev2.tv_usec - timev1.tv_usec; + if (dusec < 0) + { + dsec--; + dusec += 1000000; + } + tm = (double)dsec + (((double)dusec) / 1000000); + spd = (int)((double)speed * tm); + if (spd < min) + spd = min; + } + ewin->h = b; + ewin->y = d; + ewin->reqy = d; + queue_up = 1; + MoveResizeEwin(ewin, ewin->x, ewin->y, + ewin->client.w, ewin->client.h); + XSync(disp, False); + break; + default: + break; + } + UngrabX(); + queue_up = 0; + if (ewin->client.shaped) + EShapeCombineShape(disp, ewin->win_container, ShapeBounding, 0, 0, + ewin->client.win, ShapeBounding, ShapeSet); + PropagateShapes(ewin->win); + queue_up = 1; + GNOME_SetHint(ewin); + if (mode.mode == MODE_NONE) + { + PagerEwinOutsideAreaUpdate(ewin); + ForceUpdatePagersForDesktop(ewin->desktop); + } + EDBUG_RETURN_; +} diff --git a/src/buttons.c b/src/buttons.c new file mode 100644 index 00000000..ec99716f --- /dev/null +++ b/src/buttons.c @@ -0,0 +1,458 @@ + +#include "E.h" + +Button * +CreateButton(char *name, ImageClass * iclass, ActionClass * aclass, + TextClass * tclass, char *label, char ontop, int flags, + int minw, int maxw, int minh, int maxh, int xo, int yo, + int xa, int xr, int ya, int yr, int xsr, int xsa, int ysr, + int ysa, char simg, int desk, char sticky) +{ + Button *b; + + EDBUG(5, "CreateButton"); + + b = Emalloc(sizeof(Button)); + + b->name = duplicate(name); + + b->iclass = iclass; + if (!b->iclass) + b->iclass = FindItem("__FALLBACK_ICLASS", 0, LIST_FINDBY_NAME, + LIST_TYPE_ICLASS); + if (b->iclass) + b->iclass->ref_count++; + + b->aclass = aclass; + if (b->aclass) + b->aclass->ref_count++; + + b->tclass = tclass; + if (b->tclass) + b->tclass->ref_count++; + + if ((!b->tclass) && (b->label)) + { + b->tclass = FindItem("__FALLBACK_TCLASS", 0, LIST_FINDBY_NAME, + LIST_TYPE_TCLASS); + } + + b->label = label; + + b->ontop = ontop; + b->flags = flags; + b->sticky = sticky; + b->desktop = desk; + b->visible = 0; + b->geom.width.min = minw; + b->geom.width.max = maxw; + b->geom.height.min = minh; + b->geom.height.max = maxh; + b->geom.xorigin = xo; + b->geom.yorigin = yo; + b->geom.xabs = xa; + b->geom.xrel = xr; + b->geom.yabs = ya; + b->geom.yrel = yr; + b->geom.xsizeabs = xsa; + b->geom.xsizerel = xsr; + b->geom.ysizeabs = ysa; + b->geom.ysizerel = ysr; + b->geom.size_from_image = simg; + b->inside_win = 0; + b->event_win = 0; + b->destroy_inside_win = 0; + b->internal = 0; + b->default_show = 1; + b->used = 0; + b->left = 0; + b->win = ECreateWindow(desks.desk[desk % ENLIGHTENMENT_CONF_NUM_DESKTOPS].win, + -100, -100, 50, 50, 0); + XSelectInput(disp, b->win, + ExposureMask | KeyPressMask | KeyReleaseMask | + ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask | PointerMotionMask); + b->x = -1; + b->y = -1; + b->w = -1; + b->h = -1; + b->cx = -10; + b->cy = -10; + b->cw = -10; + b->ch = -10; + b->state = 0; + b->expose = 0; + b->ref_count = 0; + + EDBUG_RETURN(b); + +} + +void +DestroyButton(Button * b) +{ + EDBUG(5, "DestroyButton"); + + if (!b) + EDBUG_RETURN_; + + if (b->ref_count > 0) + { + char stuff[255]; + + Esnprintf(stuff, sizeof(stuff), "%u references remain", b->ref_count); + DIALOG_OK("Button Error", stuff); + + EDBUG_RETURN_; + } + + while (RemoveItemByPtr(b, LIST_TYPE_BUTTON)); + + if (b->name) + Efree(b->name); + + if (b->win) + EDestroyWindow(disp, b->win); + + if (b->iclass) + b->iclass->ref_count--; + + if (b->aclass) + b->aclass->ref_count--; + + if (b->tclass) + b->tclass->ref_count--; + + if (b->label) + Efree(b->label); + + Efree(b); + + EDBUG_RETURN_; +} + +void +CalcButton(Button * b) +{ + int w, h, x, y, xo, yo; + ImlibImage *im; + + EDBUG(4, "CalcButton"); + x = 0; + y = 0; + w = 32; + h = 32; + if (b->geom.size_from_image) + { + if ((b->iclass) && (b->iclass->norm.normal->im_file)) + { + im = ELoadImage(b->iclass->norm.normal->im_file); + if (im) + { + w = im->rgb_width; + h = im->rgb_height; + Imlib_destroy_image(id, im); + } + else + { + w = 32; + h = 32; + } + } + else + { + if (!b->iclass) + b->iclass = FindItem("__FALLBACK_ICLASS", 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + w = 32; + h = 32; + } + } + else + { + w = ((b->geom.xsizerel * root.w) >> 10) + b->geom.xsizeabs; + h = ((b->geom.ysizerel * root.h) >> 10) + b->geom.ysizeabs; + } + if (w > b->geom.width.max) + w = b->geom.width.max; + else if (w < b->geom.width.min) + w = b->geom.width.min; + if (h > b->geom.height.max) + h = b->geom.height.max; + else if (h < b->geom.height.min) + h = b->geom.height.min; + xo = (w * b->geom.xorigin) >> 10; + yo = (h * b->geom.yorigin) >> 10; + x = ((b->geom.xrel * root.w) >> 10) + b->geom.xabs - xo; + y = ((b->geom.yrel * root.h) >> 10) + b->geom.yabs - yo; + b->x = x; + b->y = y; + b->w = w; + b->h = h; + EDBUG_RETURN_; +} + +void +SimpleShowButton(Button * b) +{ + char move, resize; + + EDBUG(4, "SimpleShowButton"); + CalcButton(b); + move = 0; + resize = 0; + if ((b->x != b->cx) || (b->y != b->cy)) + move = 1; + if ((b->w != b->cw) || (b->h != b->ch)) + resize = 1; + if ((move) && (resize)) + EMoveResizeWindow(disp, b->win, b->x, b->y, b->w, b->h); + else if (move) + EMoveWindow(disp, b->win, b->x, b->y); + else if (resize) + EResizeWindow(disp, b->win, b->w, b->h); + if (b->sticky) + XRaiseWindow(disp, b->win); + DrawButton(b); + b->visible = 1; + if (init_win1) + { + XRaiseWindow(disp, init_win1); + XRaiseWindow(disp, init_win2); + } + if (init_win_ext) + XRaiseWindow(disp, init_win_ext); + RaiseProgressbars(); + EMapWindow(disp, b->win); + b->cx = b->x; + b->cy = b->y; + b->cw = b->w; + b->ch = b->h; + EDBUG_RETURN_; +} + +void +ShowButton(Button * b) +{ + char move, resize; + + EDBUG(4, "ShowButton"); + + CalcButton(b); + move = 0; + resize = 0; + + if ((b->x != b->cx) || (b->y != b->cy)) + move = 1; + if ((b->w != b->cw) || (b->h != b->ch)) + resize = 1; + + if ((move) && (resize)) + { + EMoveResizeWindow(disp, b->win, b->x, b->y, b->w, b->h); + } + else if (move) + { + EMoveWindow(disp, b->win, b->x, b->y); + } + else if (resize) + { + EResizeWindow(disp, b->win, b->w, b->h); + } + if (b->sticky) + XRaiseWindow(disp, b->win); + + DrawButton(b); + b->visible = 1; + EMapWindow(disp, b->win); + b->cx = b->x; + b->cy = b->y; + b->cw = b->w; + b->ch = b->h; + StackDesktops(); + + EDBUG_RETURN_; +} + +void +MoveButtonToDesktop(Button * b, int num) +{ + EDBUG(3, "MoveButtonToDesktop"); + + if (b->sticky) + { + b->desktop = 0; + EReparentWindow(disp, b->win, desks.desk[0].win, b->x, b->y); + XRaiseWindow(disp, b->win); + } + else + { + b->desktop = num; + EReparentWindow(disp, b->win, desks.desk[DESKTOPS_WRAP_NUM(num)].win, + b->x, b->y); + } + StackDesktops(); + + EDBUG_RETURN_; +} + +void +HideButton(Button * b) +{ + EDBUG(3, "HideButton"); + + EUnmapWindow(disp, b->win); + b->visible = 0; + + EDBUG_RETURN_; +} + +void +DrawButton(Button * b) +{ + + EDBUG(3, "DrawButton"); + + IclassApply(b->iclass, b->win, b->w, b->h, 0, 0, b->state, 0); + + if (b->label) + { + TclassApply(b->iclass, b->win, b->w, b->h, 0, 0, b->state, 0, + b->tclass, b->label); + } + /* there was some other code here that didn't actually do anything useful */ + + EDBUG_RETURN_; +} + +void +MovebuttonToCoord(Button * b, int x, int y) +{ + int rx, ry, relx, rely, absx, absy; + char move, resize; + + EDBUG(3, "MovebuttonToCoord"); + if (b->flags & FLAG_FIXED) + EDBUG_RETURN_; + + if ((x + (b->w >> 1)) < (root.w / 3)) + relx = 0; + else if ((x + (b->w >> 1)) > ((root.w * 2) / 3)) + relx = 1024; + else + relx = 512; + rx = (relx * root.w) >> 10; + absx = x - rx; + if ((y + (b->h >> 1)) < (root.h / 3)) + rely = 0; + else if ((y + (b->h >> 1)) > ((root.h * 2) / 3)) + rely = 1024; + else + rely = 512; + ry = (rely * root.h) >> 10; + absy = y - ry; + if (!(b->flags & FLAG_FIXED_HORIZ)) + { + b->geom.xorigin = 0; + b->geom.xabs = absx; + b->geom.xrel = relx; + } + if (!(b->flags & FLAG_FIXED_VERT)) + { + b->geom.yorigin = 0; + b->geom.yabs = absy; + b->geom.yrel = rely; + } + CalcButton(b); + move = 0; + resize = 0; + if ((b->x != b->cx) || (b->y != b->cy)) + move = 1; + if ((b->w != b->cw) || (b->h != b->ch)) + resize = 1; + if ((move) && (resize)) + EMoveResizeWindow(disp, b->win, b->x, b->y, b->w, b->h); + else if (move) + EMoveWindow(disp, b->win, b->x, b->y); + else if (resize) + EResizeWindow(disp, b->win, b->w, b->h); + if (b->sticky) + XRaiseWindow(disp, b->win); + b->cx = b->x; + b->cy = b->y; + b->cw = b->w; + b->ch = b->h; + StackDesktops(); + EDBUG_RETURN_; +} + +int +EmbedWindowIntoButton(Button * ButtonToUse, Window WindowToEmbed) +{ + + unsigned int w, h; + + EDBUG(4, "EmbedWindowIntoButton"); + EReparentWindow(disp, WindowToEmbed, ButtonToUse->win, 0, 0); + ButtonToUse->inside_win = WindowToEmbed; + GetWinWH(WindowToEmbed, &w, &h); + EMoveWindow(disp, ButtonToUse->inside_win, (ButtonToUse->w - w) >> 1, + (ButtonToUse->h - h) >> 1); + ButtonToUse->event_win = ECreateEventWindow(ButtonToUse->win, 0, 0, w, h); + + XSelectInput(disp, ButtonToUse->event_win, ButtonPressMask | + ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | + ButtonMotionMask); + + EMoveWindow(disp, ButtonToUse->event_win, (ButtonToUse->w - w) >> 1, + (ButtonToUse->h - h) >> 1); + EMapRaised(disp, ButtonToUse->event_win); + + EDBUG_RETURN(0); + +} + +void +FindEmptySpotForButton(Button * bt, char *listname, char dirtomove) +{ + + Button **blst; + int num = 0, i = 0, j = 0, done = 0; + + blst = (Button **) ListItemTypeName(&num, LIST_TYPE_BUTTON, listname); + if (blst) + { + for (i = 0; i < num; i++) + { + for (j = 0; j < num; j++) + { + if ((bt->x + bt->w) <= blst[j]->x || bt->x >= (blst[j]->x + blst[j]->w)) + { + done = 1; + } + else + { + if ((bt->y + bt->h) <= blst[j]->y || bt->y > (blst[j]->y + blst[j]->h)) + done = 1; + else + done = 0; + } + if (!done) + { + if (dirtomove == ICON_RIGHT) + bt->x += bt->w; + else if (dirtomove == ICON_LEFT) + bt->x -= bt->w; + else if (dirtomove == ICON_DOWN) + bt->y += bt->h; + else if (dirtomove == ICON_UP) + bt->y -= bt->h; + } + } + } + Efree(blst); + } + MovebuttonToCoord(bt, bt->x, bt->y); + EDBUG_RETURN_; + +} diff --git a/src/clone.c b/src/clone.c new file mode 100644 index 00000000..9ededff3 --- /dev/null +++ b/src/clone.c @@ -0,0 +1,119 @@ +#include "E.h" + +static int calls = 0; + +Clone * +CloneEwin(EWin * ewin) +{ + Clone *c; + Pixmap pmap; + static GC gc = 0; + XGCValues gcv; + XSetWindowAttributes attr; + + if (!gc) + { + gcv.subwindow_mode = IncludeInferiors; + gc = XCreateGC(disp, root.win, GCSubwindowMode, &gcv); + } + c = Emalloc(sizeof(Clone)); + c->name = NULL; + c->ewin = ewin; + attr.backing_store = NotUseful; + attr.override_redirect = True; + attr.colormap = root.cmap; + attr.border_pixel = 0; + attr.background_pixel = 0; + attr.background_pixmap = None; + attr.save_under = False; + c->win = XCreateWindow(disp, ewin->parent, ewin->x, ewin->y, + ewin->w, ewin->h, 0, root.depth, + InputOutput, root.vis, + CWOverrideRedirect | CWSaveUnder | + CWBackingStore | CWColormap | + CWBackPixmap | CWBackPixel | + CWBorderPixel, + &attr); + pmap = XCreatePixmap(disp, c->win, ewin->w, ewin->h, root.depth); + XSetWindowBackgroundPixmap(disp, c->win, pmap); + XCopyArea(disp, ewin->win, pmap, gc, 0, 0, ewin->w, ewin->h, 0, 0); + XFreePixmap(disp, pmap); + XShapeCombineShape(disp, c->win, ShapeBounding, 0, 0, ewin->win, + ShapeBounding, ShapeSet); + return c; +} + +void +FreeClone(Clone * c) +{ + XDestroyWindow(disp, c->win); + Efree(c); +} + +void +RemoveClones(void) +{ + Clone *c; + + calls--; + if (calls <= 0) + { + while ((c = RemoveItem("CLONE", 0, LIST_FINDBY_NAME, LIST_TYPE_CLONE))) + FreeClone(c); + calls = 0; + } +} + +void +CloneDesktop(int d) +{ + int i, num; + Clone **clist = NULL; + + if (calls > 0) + return; + calls++; + for (i = 0; i < desks.desk[d].num; i++) + { + EWin *ewin; + Clone *c; + + ewin = desks.desk[d].list[i]; + if ((ewin) && (ewin->sticky)) + { + if (!FindItem("CLONE", ewin->client.win, LIST_FINDBY_ID, + LIST_TYPE_CLONE)) + { + c = CloneEwin(ewin); + AddItem(c, "CLONE", ewin->client.win, LIST_TYPE_CLONE); + } + } + } + clist = (Clone **) ListItemType(&num, LIST_TYPE_CLONE); + if (clist) + { + Window *wl; + int k, j = 0; + + wl = Emalloc(sizeof(Window) * (desks.desk[d].num + num)); + if (wl) + { + for (i = 0; i < desks.desk[d].num; i++) + { + for (k = 0; k < num; k++) + { + if (clist[k]->ewin == desks.desk[d].list[i]) + wl[j++] = clist[k]->win; + } + wl[j++] = desks.desk[d].list[i]->win; + } + XRestackWindows(disp, wl, j); + Efree(wl); + } + for (i = 0; i < num; i++) + { + XMapWindow(disp, clist[i]->win); + } + Efree(clist); + } +} diff --git a/src/cmclass.c b/src/cmclass.c new file mode 100644 index 00000000..54eac0b4 --- /dev/null +++ b/src/cmclass.c @@ -0,0 +1,244 @@ + +#include "E.h" + +void +CreateCurve(ModCurve * c) +{ + int i, j, cx, v1, v2, val, dist; + + EDBUG(6, "CreateCurve"); + + if (!c) + EDBUG_RETURN_; + + if (c->num == 0) + { + for (i = 0; i < 256; i++) + c->map[i] = i; + EDBUG_RETURN_; + } + + cx = 0; + c->map[cx++] = c->py[0]; + + for (i = 1; i < c->num; i++) + { + v1 = c->py[i - 1]; + v2 = c->py[i]; + dist = c->px[i] - c->px[i - 1]; + if (dist < 2) + { + c->map[cx++] = v2; + } + else + { + for (j = 0; j < dist; j++) + { + val = ((v2 * j) + (v1 * (dist - j - 1))) / (dist - 1); + c->map[cx++] = (unsigned char)val; + } + } + } + + EDBUG_RETURN_; + +} + +void +FreeModCurve(ModCurve * c) +{ + + EDBUG(6, "FreeModCurve"); + + if (!c) + EDBUG_RETURN_; + + Efree(c->px); + Efree(c->py); + + EDBUG_RETURN_; + +} + +void +FreeCMClass(ColorModifierClass * cm) +{ + + EDBUG(5, "FreeCmClass"); + + if (!cm) + EDBUG_RETURN_; + + if (cm->ref_count > 0) + { + char stuff[255]; + + Esnprintf(stuff, sizeof(stuff), "Error : still have %u references\n", + cm->ref_count); + DIALOG_OK("ColorModClass Error", stuff); + + EDBUG_RETURN_; + + } + + while (RemoveItemByPtr(cm, LIST_TYPE_COLORMODIFIER)); + + Efree(cm->name); + FreeModCurve(&(cm->red)); + FreeModCurve(&(cm->green)); + FreeModCurve(&(cm->blue)); + + EDBUG_RETURN_; + +} + +ColorModifierClass * +CreateCMClass(char *name, + int rnum, unsigned char *rpx, unsigned char *rpy, + int gnum, unsigned char *gpx, unsigned char *gpy, + int bnum, unsigned char *bpx, unsigned char *bpy) +{ + ColorModifierClass *cm; + + EDBUG(5, "CreateCMCLass"); + + cm = Emalloc(sizeof(ColorModifierClass)); + if (!cm) + EDBUG_RETURN(NULL); + + cm->name = duplicate(name); + cm->red.px = NULL; + cm->red.py = NULL; + cm->green.px = NULL; + cm->green.py = NULL; + cm->blue.px = NULL; + cm->blue.py = NULL; + cm->ref_count = 0; + + if (rnum < 2) + { + cm->red.num = 0; + } + else + { + cm->red.num = rnum; + cm->red.px = Emalloc(rnum); + memcpy(cm->red.px, rpx, rnum); + cm->red.py = Emalloc(rnum); + memcpy(cm->red.py, rpy, rnum); + } + + if (gnum < 2) + { + cm->green.num = 0; + } + else + { + cm->green.num = gnum; + cm->green.px = Emalloc(gnum); + memcpy(cm->green.px, gpx, gnum); + cm->green.py = Emalloc(gnum); + memcpy(cm->green.py, gpy, gnum); + } + + if (bnum < 2) + { + cm->blue.num = 0; + } + else + { + cm->blue.num = bnum; + cm->blue.px = Emalloc(bnum); + memcpy(cm->blue.px, bpx, bnum); + cm->blue.py = Emalloc(bnum); + memcpy(cm->blue.py, bpy, bnum); + } + + CreateCurve(&(cm->red)); + CreateCurve(&(cm->green)); + CreateCurve(&(cm->blue)); + + EDBUG_RETURN(cm); + +} + +void +ModifyCMClass(char *name, + int rnum, unsigned char *rpx, unsigned char *rpy, + int gnum, unsigned char *gpx, unsigned char *gpy, + int bnum, unsigned char *bpx, unsigned char *bpy) +{ + ColorModifierClass *cm; + + EDBUG(5, "ModifyCMCLass"); + cm = (ColorModifierClass *) FindItem(name, 0, LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + if (!cm) + EDBUG_RETURN_; + + if (cm->red.px) + Efree(cm->red.px); + if (cm->red.py) + Efree(cm->red.py); + if (cm->green.px) + Efree(cm->green.px); + if (cm->green.py) + Efree(cm->green.py); + if (cm->blue.px) + Efree(cm->blue.px); + if (cm->blue.py) + Efree(cm->blue.py); + + cm->red.px = NULL; + cm->red.py = NULL; + cm->green.px = NULL; + cm->green.py = NULL; + cm->blue.px = NULL; + cm->blue.py = NULL; + + if (rnum < 2) + { + cm->red.num = 0; + } + else + { + cm->red.num = rnum; + cm->red.px = Emalloc(rnum); + memcpy(cm->red.px, rpx, rnum); + cm->red.py = Emalloc(rnum); + memcpy(cm->red.py, rpy, rnum); + } + + if (gnum < 2) + { + cm->green.num = 0; + } + else + { + cm->green.num = gnum; + cm->green.px = Emalloc(gnum); + memcpy(cm->green.px, gpx, gnum); + cm->green.py = Emalloc(gnum); + memcpy(cm->green.py, gpy, gnum); + } + + if (bnum < 2) + { + cm->blue.num = 0; + } + else + { + cm->blue.num = bnum; + cm->blue.px = Emalloc(bnum); + memcpy(cm->blue.px, bpx, bnum); + cm->blue.py = Emalloc(bnum); + memcpy(cm->blue.py, bpy, bnum); + } + + CreateCurve(&(cm->red)); + CreateCurve(&(cm->green)); + CreateCurve(&(cm->blue)); + + EDBUG_RETURN_; + +} diff --git a/src/comms.c b/src/comms.c new file mode 100644 index 00000000..6ad5c98a --- /dev/null +++ b/src/comms.c @@ -0,0 +1,2254 @@ + +#include "E.h" + +void +CommsSetup() +{ + char s[1024]; + static Atom a = 0; + + EDBUG(5, "CommsSetup"); + comms_win = XCreateSimpleWindow(disp, root.win, -100, -100, 5, 5, 0, 0, 0); + Esnprintf(s, sizeof(s), "WINID %8x", (int)comms_win); + a = XInternAtom(disp, "ENLIGHTENMENT_COMMS", False); + XChangeProperty(disp, root.win, a, XA_STRING, 8, PropModeReplace, + (unsigned char *)s, strlen(s)); + XChangeProperty(disp, comms_win, a, XA_STRING, 8, PropModeReplace, + (unsigned char *)s, strlen(s)); + if (!a) + a = XInternAtom(disp, "ENL_MSG", False); + EDBUG_RETURN_; +} + +void +CommsFindCommsWindow() +{ + unsigned char *s; + Atom a, ar; + unsigned long num, after; + int format; + Window rt; + int dint; + unsigned int duint; + + EDBUG(6, "CommsFindCommsWindow"); + a = XInternAtom(disp, "ENLIGHTENMENT_COMMS", True); + if (a != None) + { + s = NULL; + XGetWindowProperty(disp, root.win, a, 0, 14, False, AnyPropertyType, + &ar, &format, &num, &after, &s); + if (s) + { + sscanf((char *)s, "%*s %x", (unsigned int *)&comms_win); + XFree(s); + } + else + { + (comms_win = 0); + } + if (comms_win) + { + if (!EGetGeometry(disp, comms_win, &rt, &dint, &dint, + &duint, &duint, &duint, &duint)) + comms_win = 0; + s = NULL; + if (comms_win) + { + XGetWindowProperty(disp, comms_win, a, 0, 14, False, + AnyPropertyType, &ar, &format, &num, &after, + &s); + if (s) + XFree(s); + else + comms_win = 0; + } + } + } + EDBUG_RETURN_; +} + +void +CommsSend(Client * c, char *s) +{ + char ss[21]; + int i, j, k, len; + XEvent ev; + static Atom a = 0; + + EDBUG(5, "CommsSend"); + if ((!s) || (!c)) + EDBUG_RETURN_; + len = strlen(s); + if (!a) + a = XInternAtom(disp, "ENL_MSG", True); + ev.xclient.type = ClientMessage; + ev.xclient.serial = 0; + ev.xclient.send_event = True; + ev.xclient.window = c->win; + ev.xclient.message_type = a; + ev.xclient.format = 8; + for (i = 0; i < len + 1; i += 12) + { + Esnprintf(ss, sizeof(ss), "%8x", (int)comms_win); + for (j = 0; j < 12; j++) + { + ss[8 + j] = s[i + j]; + if (!s[i + j]) + j = 12; + } + ss[20] = 0; + for (k = 0; k < 20; k++) + ev.xclient.data.b[k] = ss[k]; + XSendEvent(disp, c->win, False, 0, (XEvent *) & ev); + } + EDBUG_RETURN_; +} + +/* + * When we are running in multi-head, connect to the master wm process + * and send the message + */ +void +CommsSendToMasterWM(char *s) +{ + Window otherrootwin; + char ss[21]; + int i, j, k, len; + XEvent ev; + Atom a = 0; + + EDBUG(5, "CommsSendToMasterWM"); + if (root.scr == master_screen || master_pid == getpid()) + EDBUG_RETURN_; + + if (!s) + EDBUG_RETURN_; + + otherrootwin = RootWindow(disp, master_screen); + + len = strlen(s); + if (!a) + a = XInternAtom(disp, "ENL_MSG", True); + ev.xclient.type = ClientMessage; + ev.xclient.serial = 0; + ev.xclient.send_event = True; + ev.xclient.window = otherrootwin; + ev.xclient.message_type = a; + ev.xclient.format = 8; + for (i = 0; i < len + 1; i += 12) + { + Esnprintf(ss, sizeof(ss), "%8x", (int)comms_win); + for (j = 0; j < 12; j++) + { + ss[8 + j] = s[i + j]; + if (!s[i + j]) + j = 12; + } + ss[20] = 0; + for (k = 0; k < 20; k++) + ev.xclient.data.b[k] = ss[k]; + XSendEvent(disp, otherrootwin, False, 0, (XEvent *) & ev); + } + EDBUG_RETURN_; +} + +/* + * When we are running in multi-head, connect to the slave wm processes + * and broadcast the message + */ +void +CommsBroadcastToSlaveWMs(char *s) +{ + Window otherrootwin; + char ss[21]; + int i, j, k, len, screen; + XEvent ev; + Atom a = 0; + + EDBUG(5, "CommsBroadcastToSlaveWMs"); + if (root.scr != master_screen || master_pid != getpid() || + display_screens < 2 || single_screen_mode != 0) + EDBUG_RETURN_; + + if (!s) + EDBUG_RETURN_; + + for (screen = 0; screen < display_screens; screen++) + { + if (screen != master_screen) + { + otherrootwin = RootWindow(disp, screen); + + len = strlen(s); + if (!a) + a = XInternAtom(disp, "ENL_MSG", False); + ev.xclient.type = ClientMessage; + ev.xclient.serial = 0; + ev.xclient.send_event = True; + ev.xclient.window = otherrootwin; + ev.xclient.message_type = a; + ev.xclient.format = 8; + for (i = 0; i < len + 1; i += 12) + { + Esnprintf(ss, sizeof(ss), "%8x", (int)comms_win); + for (j = 0; j < 12; j++) + { + ss[8 + j] = s[i + j]; + if (!s[i + j]) + j = 12; + } + ss[20] = 0; + for (k = 0; k < 20; k++) + ev.xclient.data.b[k] = ss[k]; + XSendEvent(disp, otherrootwin, False, 0, (XEvent *) & ev); + } + } + } + EDBUG_RETURN_; +} + +char * +CommsGet(Client ** c, XEvent * ev) +{ + char s[13], s2[9], *msg, st[32]; + int i; + Window win; + Client *cl; + Atom a = 0; + + EDBUG(5, "CommsGet"); + if (!a) + a = XInternAtom(disp, "ENL_MSG", True); + if ((!ev) || (!c)) + EDBUG_RETURN(NULL); + if (ev->type != ClientMessage) + EDBUG_RETURN(NULL); + if (ev->xclient.message_type != a) + EDBUG_RETURN(NULL); + s[12] = 0; + s2[8] = 0; + msg = NULL; + for (i = 0; i < 8; i++) + s2[i] = ev->xclient.data.b[i]; + for (i = 0; i < 12; i++) + s[i] = ev->xclient.data.b[i + 8]; + sscanf(s2, "%x", (int *)&win); + cl = (Client *) FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_CLIENT); + if (!cl) + { + cl = MakeClient(win); + if (!cl) + EDBUG_RETURN(NULL); + Esnprintf(st, sizeof(st), "%8x", (int)win); + cl->name = duplicate(st); + AddItem((void *)cl, st, cl->win, LIST_TYPE_CLIENT); + XSelectInput(disp, win, StructureNotifyMask | SubstructureNotifyMask); + } + if (cl->msg) + { + /* append text to end of msg */ + cl->msg = Erealloc(cl->msg, strlen(cl->msg) + strlen(s) + 1); + if (!cl->msg) + EDBUG_RETURN(NULL); + strcat(cl->msg, s); + } + else + { + /* new msg */ + cl->msg = Emalloc(strlen(s) + 1); + if (!cl->msg) + EDBUG_RETURN(NULL); + strcpy(cl->msg, s); + } + if (strlen(s) < 12) + { + msg = cl->msg; + cl->msg = NULL; + *c = cl; + } + EDBUG_RETURN(msg); +} + +void +CommsBroadcast(char *s) +{ + char **l; + int num, i; + Client *c; + + EDBUG(5, "CommsBroadcast"); + l = ListItems(&num, LIST_TYPE_CLIENT); + if (!s) + EDBUG_RETURN_; + for (i = 0; i < num; i++) + { + c = (Client *) FindItem(l[i], 0, LIST_FINDBY_NAME, LIST_TYPE_CLIENT); + if (c) + CommsSend(c, s); + } + freestrlist(l, num); + EDBUG_RETURN_; +} + +Client * +MakeClient(Window win) +{ + Client *c; + + EDBUG(6, "MakeClient"); + c = Emalloc(sizeof(Client)); + if (!c) + EDBUG_RETURN(NULL); + c->name = NULL; + c->win = win; + c->msg = NULL; + c->clientname = NULL; + c->version = NULL; + c->author = NULL; + c->email = NULL; + c->web = NULL; + c->address = NULL; + c->info = NULL; + c->pmap = 0; + EDBUG_RETURN(c); +} + +void +ListFreeClient(void *ptr) +{ + Client *c; + + EDBUG(6, "ListFreeClient"); + c = (Client *) ptr; + if (!c) + EDBUG_RETURN_; + if (c->name) + Efree(c->name); + if (c->msg) + Efree(c->msg); + if (c->clientname) + Efree(c->clientname); + if (c->version) + Efree(c->version); + if (c->author) + Efree(c->author); + if (c->email) + Efree(c->email); + if (c->web) + Efree(c->web); + if (c->address) + Efree(c->address); + if (c->info) + Efree(c->info); + Efree(c); + EDBUG_RETURN_; +} + +void +DeleteClient(Client * c) +{ + Client *cc; + + EDBUG(6, "DeleteClient"); + cc = RemoveItem(NULL, c->win, LIST_FINDBY_ID, LIST_TYPE_CLIENT); + ListFreeClient(cc); + EDBUG_RETURN_; +} + +void +HandleComms(XEvent * ev) +{ + Client *c; + char *s, w[FILEPATH_LEN_MAX], w2[FILEPATH_LEN_MAX], *s1, + *s2; + char sunknown[] = "UNKNOWN"; + int unknown; + + EDBUG(4, "HandleComms"); + s = CommsGet(&c, ev); + if (!s) + EDBUG_RETURN_; + if (HandleIPC(s, c)) + EDBUG_RETURN_; + unknown = 0; + s1 = NULL, s2 = NULL; + word(s, 1, w); + if (!strcmp(w, "set")) + { + word(s, 2, w); + if (!strcmp(w, "clientname")) + { + if (c->clientname) + Efree(c->clientname); + c->clientname = duplicate(atword(s, 3)); + } + else if (!strcmp(w, "version")) + { + if (c->version) + Efree(c->version); + c->version = duplicate(atword(s, 3)); + } + else if (!strcmp(w, "author")) + { + if (c->author) + Efree(c->author); + c->author = duplicate(atword(s, 3)); + } + else if (!strcmp(w, "email")) + { + if (c->email) + Efree(c->email); + c->email = duplicate(atword(s, 3)); + } + else if (!strcmp(w, "web")) + { + if (c->web) + Efree(c->web); + c->web = duplicate(atword(s, 3)); + } + else if (!strcmp(w, "address")) + { + if (c->address) + Efree(c->address); + c->address = duplicate(atword(s, 3)); + } + else if (!strcmp(w, "info")) + { + if (c->info) + Efree(c->info); + c->info = duplicate(atword(s, 3)); + } + else if (!strcmp(w, "pixmap")) + { + word(s, 3, w); + sscanf(w, "%x", (int *)&c->pmap); + } + else + unknown = 1; + } + else if (!strcmp(w, "reply")) + { + word(s, 2, w); + if (!strcmp(w, "imageclass")) + { + /* Reply format "reply imageclass NAME 24243" */ + word(s, 3, w); + word(s, 4, w2); + HonorIclass(w, atoi(w2)); + } + else + unknown = 1; + } + else if (!strcmp(w, "get_default_theme")) + { + char *buf; + + buf = GetDefaultTheme(); + if (buf) + { + CommsSend(c, buf); + Efree(buf); + } + else + CommsSend(c, ""); + } + else if (!strcmp(w, "set_default_theme")) + { + char sss[FILEPATH_LEN_MAX], buf[FILEPATH_LEN_MAX]; + + word(s, 2, buf); + if (exists(buf)) + { + SetDefaultTheme(buf); + Esnprintf(sss, sizeof(sss), "restart_theme %s", buf); + doExit(sss); + } + } + else if (!strcmp(w, "list_bg")) + { + Background **bg; + int i, num, len = 0; + char *buf = NULL; + + bg = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); + if (bg) + { + for (i = 0; i < num; i++) + { + len += strlen(bg[i]->name) + 1; + if (buf) + buf = Erealloc(buf, len + 1); + else + { + buf = Erealloc(buf, len + 1); + buf[0] = 0; + } + strcat(buf, bg[i]->name); + strcat(buf, "\n"); + } + Efree(bg); + } + if (buf) + { + CommsSend(c, buf); + Efree(buf); + } + else + CommsSend(c, ""); + } + else if (!strcmp(w, "del_bg")) + { + Background *bg; + int i; + char dodel = 1; + + sscanf(s, "%*s %1000s", w); + bg = (Background *) FindItem(w, 0, LIST_FINDBY_NAME, + LIST_TYPE_BACKGROUND); + if (bg) + { + /* check for desktops referencing this bg - if there are - don't */ + /* delete it */ + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + { + if (desks.desk[i].bg == bg) + dodel = 0; + } + if (dodel) + { + bg = (Background *) RemoveItem(w, 0, LIST_FINDBY_NAME, + LIST_TYPE_BACKGROUND); + if (bg->name) + Efree(bg->name); + if (bg->bg.file) + Efree(bg->bg.file); + if (bg->top.file) + Efree(bg->top.file); + if (bg->pmap) + Imlib_free_pixmap(id, bg->pmap); + Efree(bg); + } + } + } + else if (!strcmp(w, "use_bg")) + { + Background *bg; + int i, wd; + char view; + + sscanf(s, "%*s %1000s", w); + bg = (Background *) FindItem(w, 0, LIST_FINDBY_NAME, + LIST_TYPE_BACKGROUND); + if (bg) + { + wd = 3; + w[0] = ' '; + while (w[0]) + { + w[0] = 0; + word(s, wd++, w); + if (w[0]) + { + i = atoi(w); + if ((i >= 0) && (i < ENLIGHTENMENT_CONF_NUM_DESKTOPS)) + { + if (desks.desk[i].bg) + desks.desk[i].bg->last_viewed = 0; + view = desks.desk[i].viewable; + desks.desk[i].viewable = 0; + DesktopAccounting(); + desks.desk[i].viewable = view; + desks.desk[i].bg = bg; + if (i < mode.numdesktops) + { + if (desks.desk[i].viewable) + RefreshDesktop(i); + if (i == desks.current) + { + RedrawPagersForDesktop(i, 2); + ForceUpdatePagersForDesktop(i); + } + else + RedrawPagersForDesktop(i, 1); + } + } + } + } + } + } + else if (!strcmp(w, "use_no_bg")) + { + int i, wd; + char view; + + wd = 2; + w[0] = ' '; + while (w[0]) + { + w[0] = 0; + word(s, wd++, w); + if (w[0]) + { + i = atoi(w); + if ((i >= 0) && (i < ENLIGHTENMENT_CONF_NUM_DESKTOPS)) + { + if (desks.desk[i].bg) + desks.desk[i].bg->last_viewed = 0; + view = desks.desk[i].viewable; + desks.desk[i].viewable = 0; + DesktopAccounting(); + desks.desk[i].viewable = view; + desks.desk[i].bg = NULL; + if (i < mode.numdesktops) + { + if (desks.desk[i].viewable) + RefreshDesktop(i); + if (i == desks.current) + { + RedrawPagersForDesktop(i, 2); + ForceUpdatePagersForDesktop(i); + } + else + RedrawPagersForDesktop(i, 1); + } + } + } + } + } + else if (!strcmp(w, "uses_bg")) + { + Background *bg; + int i; + char buf[FILEPATH_LEN_MAX], buf2[FILEPATH_LEN_MAX]; + + sscanf(s, "%*s %1000s", w); + bg = (Background *) FindItem(w, 0, LIST_FINDBY_NAME, + LIST_TYPE_BACKGROUND); + buf[0] = 0; + if (bg) + { + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + { + if (desks.desk[i].bg == bg) + { + Esnprintf(buf2, sizeof(buf2), "%i\n", i); + strcat(buf, buf2); + } + } + } + CommsSend(c, buf); + } + else if (!strcmp(w, "get_keybindings")) + { + ActionClass *ac; + Action *a; + int i, mod; + char *buf = NULL, buf2[FILEPATH_LEN_MAX]; + + ac = (ActionClass *) FindItem("KEYBINDINGS", 0, + LIST_FINDBY_NAME, + LIST_TYPE_ACLASS_GLOBAL); + if (ac) + { + for (i = 0; i < ac->num; i++) + { + a = ac->list[i]; + if ((a) && (a->action) && (a->event == EVENT_KEY_DOWN)) + { + char *key; + + key = XKeysymToString(XKeycodeToKeysym(disp, a->key, 0)); + if (key) + { + mod = 0; + if (a->modifiers == (ControlMask)) + mod = 1; + else if (a->modifiers == (Mod1Mask)) + mod = 2; + else if (a->modifiers == (ShiftMask)) + mod = 3; + else if (a->modifiers == (ControlMask | Mod1Mask)) + mod = 4; + else if (a->modifiers == (ShiftMask | ControlMask)) + mod = 5; + else if (a->modifiers == (ShiftMask | Mod1Mask)) + mod = 6; + else if (a->modifiers == (ShiftMask | ControlMask | Mod1Mask)) + mod = 7; + else if (a->modifiers == (Mod2Mask)) + mod = 8; + else if (a->modifiers == (Mod3Mask)) + mod = 9; + else if (a->modifiers == (Mod4Mask)) + mod = 10; + else if (a->modifiers == (Mod5Mask)) + mod = 11; + else if (a->modifiers == (Mod2Mask | ShiftMask)) + mod = 12; + else if (a->modifiers == (Mod2Mask | ControlMask)) + mod = 13; + else if (a->modifiers == (Mod2Mask | Mod1Mask)) + mod = 14; + else if (a->modifiers == (Mod4Mask | ShiftMask)) + mod = 15; + else if (a->modifiers == (Mod4Mask | ControlMask)) + mod = 16; + else if (a->modifiers == (Mod4Mask | ControlMask | ShiftMask)) + mod = 17; + else if (a->modifiers == (Mod5Mask | ShiftMask)) + mod = 18; + else if (a->modifiers == (Mod5Mask | ControlMask)) + mod = 19; + else if (a->modifiers == (Mod5Mask | ControlMask | ShiftMask)) + mod = 20; + if (a->action->params) + Esnprintf(buf2, sizeof(buf2), + "%s %i %i %s\n", key, mod, + a->action->Type, a->action->params); + else + Esnprintf(buf2, sizeof(buf2), + "%s %i %i\n", key, mod, + a->action->Type); + if (buf) + { + buf = Erealloc(buf, strlen(buf) + strlen(buf2) + 1); + strcat(buf, buf2); + } + else + buf = duplicate(buf2); + } + } + } + if (buf) + { + CommsSend(c, buf); + Efree(buf); + } + else + CommsSend(c, "\n"); + } + else + CommsSend(c, "\n"); + } + else if (!strcmp(w, "set_keybindings")) + { + ActionClass *ac; + Action *a; + int i, l; + char buf[FILEPATH_LEN_MAX], *sp, *ss; + + ac = (ActionClass *) RemoveItem("KEYBINDINGS", 0, + LIST_FINDBY_NAME, + LIST_TYPE_ACLASS_GLOBAL); + if (ac) + RemoveActionClass(ac); + ac = CreateAclass("KEYBINDINGS"); + AddItem(ac, ac->name, 0, LIST_TYPE_ACLASS_GLOBAL); + i = 0; + ss = atword(s, 2); + if (ss) + { + l = strlen(ss); + while (i < l) + { + char key[256]; + int mod = 0; + int act_id = 0; + int j = 0; + + /* put line in buf */ + sp = &(ss[i]); + while ((sp[j]) && (sp[j] != '\n')) + { + buf[j] = sp[j]; + j++; + } + buf[j] = 0; + if (sp[j] == '\n') + j++; + i += j; + /* parse the line */ + sscanf(buf, "%250s %i %i", key, &mod, &act_id); + if (mod == 0) + mod = 0; + else if (mod == 1) + mod = ControlMask; + else if (mod == 2) + mod = Mod1Mask; + else if (mod == 3) + mod = ShiftMask; + else if (mod == 4) + mod = ControlMask | Mod1Mask; + else if (mod == 5) + mod = ShiftMask | ControlMask; + else if (mod == 6) + mod = ShiftMask | Mod1Mask; + else if (mod == 7) + mod = ShiftMask | ControlMask | Mod1Mask; + else if (mod == 8) + mod = Mod2Mask; + else if (mod == 9) + mod = Mod3Mask; + else if (mod == 10) + mod = Mod4Mask; + else if (mod == 11) + mod = Mod5Mask; + else if (mod == 12) + mod = Mod2Mask | ShiftMask; + else if (mod == 13) + mod = Mod2Mask | ControlMask; + else if (mod == 14) + mod = Mod2Mask | Mod1Mask; + else if (mod == 15) + mod = Mod4Mask | ShiftMask; + else if (mod == 16) + mod = Mod4Mask | ControlMask; + else if (mod == 17) + mod = Mod4Mask | ControlMask | ShiftMask; + else if (mod == 18) + mod = Mod5Mask | ShiftMask; + else if (mod == 19) + mod = Mod5Mask | ControlMask; + else if (mod == 20) + mod = Mod5Mask | ControlMask | ShiftMask; + a = CreateAction(4, 0, mod, 0, 0, 0, key, NULL); + GrabActionKey(a); + AddAction(ac, a); + if (atword(buf, 4)) + AddToAction(a, act_id, duplicate(atword(buf, 4))); + else + AddToAction(a, act_id, NULL); + } + } + } + else if (!strcmp(w, "set_bg_colmod")) + { + Background *bg; + ColorModifierClass *cm; + int i; + char buf[FILEPATH_LEN_MAX], buf2[FILEPATH_LEN_MAX]; + + sscanf(s, "%*s %1000s %1000s", buf, buf2); + bg = (Background *) FindItem(buf, 0, LIST_FINDBY_NAME, + LIST_TYPE_BACKGROUND); + cm = (ColorModifierClass *) FindItem(buf2, 0, LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + if ((bg) && (bg->cmclass != cm)) + { + if (!strcmp(buf, "(null)")) + { + bg->cmclass->ref_count--; + bg->cmclass = NULL; + } + else if (cm) + { + bg->cmclass->ref_count--; + bg->cmclass = cm; + } + if (bg->pmap) + Imlib_free_pixmap(id, bg->pmap); + bg->pmap = 0; + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + { + if ((desks.desk[i].bg == bg) && + (desks.desk[i].viewable)) + RefreshDesktop(i); + } + } + } + else if (!strcmp(w, "get_bg_colmod")) + { + Background *bg; + char buf[FILEPATH_LEN_MAX]; + + sscanf(s, "%*s %1000s", w); + bg = (Background *) FindItem(w, 0, LIST_FINDBY_NAME, + LIST_TYPE_BACKGROUND); + Esnprintf(buf, sizeof(buf), "(null)"); + if ((bg) && (bg->cmclass)) + Esnprintf(buf, sizeof(buf), "%s", bg->cmclass->name); + CommsSend(c, buf); + } + else if (!strcmp(w, "del_colmod")) + { + ColorModifierClass *cm; + char buf[FILEPATH_LEN_MAX]; + + sscanf(s, "%*s %1000s", w); + cm = (ColorModifierClass *) FindItem(w, 0, LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + Esnprintf(buf, sizeof(buf), "(null)"); + if (cm) + FreeCMClass(cm); + } + else if (!strcmp(w, "get_colmod")) + { + ColorModifierClass *cm; + int i; + char buf[FILEPATH_LEN_MAX], buf2[FILEPATH_LEN_MAX]; + + sscanf(s, "%*s %1000s", w); + cm = (ColorModifierClass *) FindItem(w, 0, LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + Esnprintf(buf, sizeof(buf), "(null)"); + if (cm) + { + Esnprintf(buf, sizeof(buf), "%i", (int)(cm->red.num)); + for (i = 0; i < cm->red.num; i++) + { + Esnprintf(buf2, sizeof(buf2), " %i", (int)(cm->red.px[i])); + strcat(buf, buf2); + Esnprintf(buf2, sizeof(buf2), " %i", (int)(cm->red.py[i])); + strcat(buf, buf2); + } + Esnprintf(buf2, sizeof(buf2), "\n%i", (int)(cm->green.num)); + strcat(buf, buf2); + for (i = 0; i < cm->green.num; i++) + { + Esnprintf(buf2, sizeof(buf2), " %i", (int)(cm->green.px[i])); + strcat(buf, buf2); + Esnprintf(buf2, sizeof(buf2), " %i", (int)(cm->green.py[i])); + strcat(buf, buf2); + } + Esnprintf(buf2, sizeof(buf2), "\n%i", (int)(cm->red.num)); + strcat(buf, buf2); + for (i = 0; i < cm->blue.num; i++) + { + Esnprintf(buf2, sizeof(buf2), " %i", (int)(cm->blue.px[i])); + strcat(buf, buf2); + Esnprintf(buf2, sizeof(buf2), " %i", (int)(cm->blue.py[i])); + strcat(buf, buf2); + } + } + CommsSend(c, buf); + } + else if (!strcmp(w, "set_colmod")) + { + ColorModifierClass *cm; + int i, j, k; + char *name; + int rnum = 0, gnum = 0, bnum = 0; + unsigned char *rpx = NULL, *rpy = NULL; + unsigned char *gpx = NULL, *gpy = NULL; + unsigned char *bpx = NULL, *bpy = NULL; + + sscanf(s, "%*s %1000s", w); + cm = (ColorModifierClass *) FindItem(w, 0, LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + name = duplicate(w); + i = 3; + word(s, i++, w); + rnum = atoi(w); + j = 0; + rpx = Emalloc(rnum); + rpy = Emalloc(rnum); + while (j < rnum) + { + word(s, i++, w); + k = atoi(w); + rpx[j] = k; + word(s, i++, w); + k = atoi(w); + rpy[j++] = k; + } + word(s, i++, w); + gnum = atoi(w); + j = 0; + gpx = Emalloc(gnum); + gpy = Emalloc(gnum); + while (j < gnum) + { + word(s, i++, w); + k = atoi(w); + gpx[j] = k; + word(s, i++, w); + k = atoi(w); + gpy[j++] = k; + } + word(s, i++, w); + bnum = atoi(w); + j = 0; + bpx = Emalloc(bnum); + bpy = Emalloc(bnum); + while (j < bnum) + { + word(s, i++, w); + k = atoi(w); + bpx[j] = k; + word(s, i++, w); + k = atoi(w); + bpy[j++] = k; + } + if (cm) + ModifyCMClass(name, rnum, rpx, rpy, gnum, gpx, gpy, bnum, bpx, bpy); + else + { + cm = CreateCMClass(name, rnum, rpx, rpy, gnum, gpx, gpy, bnum, bpx, bpy); + AddItem(cm, cm->name, 0, LIST_TYPE_COLORMODIFIER); + } + Efree(name); + if (rpx) + Efree(rpx); + if (rpy) + Efree(rpy); + if (gpx) + Efree(gpx); + if (gpy) + Efree(gpy); + if (bpx) + Efree(bpx); + if (bpy) + Efree(bpy); + } + else if (!strcmp(w, "get_bg")) + { + Background *bg; + char buf[FILEPATH_LEN_MAX]; + + sscanf(s, "%*s %1000s", w); + bg = (Background *) FindItem(w, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); + Esnprintf(buf, sizeof(buf), "(null)"); + if (bg) + { + if ((bg->bg.file) && (bg->top.file)) + Esnprintf(buf, sizeof(buf), + "%s %i %i %i %s %i %i %i %i %i %i %s %i %i %i %i %i", + bg->name, + bg->bg.solid.r, bg->bg.solid.g, bg->bg.solid.b, + bg->bg.file, bg->bg.tile, bg->bg.keep_aspect, + bg->bg.xjust, bg->bg.yjust, bg->bg.xperc, bg->bg.yperc, + bg->top.file, bg->top.keep_aspect, bg->top.xjust, + bg->top.yjust, bg->top.xperc, bg->top.yperc); + else if ((!(bg->bg.file)) && (bg->top.file)) + Esnprintf(buf, sizeof(buf), + "%s %i %i %i %s %i %i %i %i %i %i %s %i %i %i %i %i", + bg->name, + bg->bg.solid.r, bg->bg.solid.g, bg->bg.solid.b, + "(null)", bg->bg.tile, bg->bg.keep_aspect, + bg->bg.xjust, bg->bg.yjust, bg->bg.xperc, bg->bg.yperc, + bg->top.file, bg->top.keep_aspect, bg->top.xjust, + bg->top.yjust, bg->top.xperc, bg->top.yperc); + else if ((bg->bg.file) && (!(bg->top.file))) + Esnprintf(buf, sizeof(buf), + "%s %i %i %i %s %i %i %i %i %i %i %s %i %i %i %i %i", + bg->name, + bg->bg.solid.r, bg->bg.solid.g, bg->bg.solid.b, + bg->bg.file, bg->bg.tile, bg->bg.keep_aspect, + bg->bg.xjust, bg->bg.yjust, bg->bg.xperc, bg->bg.yperc, + "(null)", bg->top.keep_aspect, bg->top.xjust, + bg->top.yjust, bg->top.xperc, bg->top.yperc); + else if ((!(bg->bg.file)) && (!(bg->top.file))) + Esnprintf(buf, sizeof(buf), + "%s %i %i %i %s %i %i %i %i %i %i %s %i %i %i %i %i", + bg->name, + bg->bg.solid.r, bg->bg.solid.g, bg->bg.solid.b, + "(null)", bg->bg.tile, bg->bg.keep_aspect, + bg->bg.xjust, bg->bg.yjust, bg->bg.xperc, bg->bg.yperc, + "(null)", bg->top.keep_aspect, bg->top.xjust, + bg->top.yjust, bg->top.xperc, bg->top.yperc); + } + CommsSend(c, buf); + } + else if (!strcmp(w, "set_bg")) + { + Background *bg; + ImlibColor icl; + int i; + char tmp[1024]; + char *name = NULL, *bgf = NULL, *topf = NULL; + int updated = 0, tile, keep_aspect, tkeep_aspect; + int xjust, yjust, xperc, yperc, txjust, tyjust, txperc, + typerc; + + sscanf(s, "%1000s %1000s", tmp, w); + bg = (Background *) FindItem(w, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); + icl.r = 99; + i = sscanf(s, "%1000s %1000s %i %i %i %1000s %i %i %i %i %i %i %1000s %i %i %i %i %i", + tmp, tmp, + &(icl.r), &(icl.g), &(icl.b), tmp, &tile, (int *)&keep_aspect, + &xjust, &yjust, &xperc, &yperc, tmp, &tkeep_aspect, &txjust, + &tyjust, &txperc, &typerc); + if (bg) + { + name = duplicate(w); + word(s, 6, w); + if (strcmp("(null)", w)) + bgf = duplicate(w); + word(s, 13, w); + if (strcmp("(null)", w)) + topf = duplicate(w); + + if (icl.r != bg->bg.solid.r) + updated = 1; + if (icl.g != bg->bg.solid.g) + updated = 1; + if (icl.b != bg->bg.solid.b) + updated = 1; + bg->bg.solid.r = icl.r; + bg->bg.solid.g = icl.g; + bg->bg.solid.b = icl.b; + if ((bg->bg.file) && (bgf)) + { + if (strcmp(bg->bg.file, bgf)) + updated = 1; + } + else + updated = 1; + if (bg->bg.file) + Efree(bg->bg.file); + bg->bg.file = bgf; + if ((int)tile != bg->bg.tile) + updated = 1; + if ((int)keep_aspect != bg->bg.keep_aspect) + updated = 1; + if (xjust != bg->bg.xjust) + updated = 1; + if (yjust != bg->bg.yjust) + updated = 1; + if (xperc != bg->bg.xperc) + updated = 1; + if (yperc != bg->bg.yperc) + updated = 1; + bg->bg.tile = (char)tile; + bg->bg.keep_aspect = (char)keep_aspect; + bg->bg.xjust = xjust; + bg->bg.yjust = yjust; + bg->bg.xperc = xperc; + bg->bg.yperc = yperc; + if ((bg->top.file) && (topf)) + { + if (strcmp(bg->top.file, topf)) + updated = 1; + } + else + updated = 1; + if (bg->top.file) + Efree(bg->top.file); + bg->top.file = topf; + if ((int)tkeep_aspect != bg->top.keep_aspect) + updated = 1; + if (txjust != bg->top.xjust) + updated = 1; + if (tyjust != bg->top.yjust) + updated = 1; + if (txperc != bg->top.xperc) + updated = 1; + if (typerc != bg->top.yperc) + updated = 1; + bg->top.keep_aspect = (char)tkeep_aspect; + bg->top.xjust = txjust; + bg->top.yjust = tyjust; + bg->top.xperc = txperc; + bg->top.yperc = typerc; + if (updated) + { + if (bg->pmap) + Imlib_free_pixmap(id, bg->pmap); + bg->pmap = 0; + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + { + if (desks.desk[i].bg == bg) + { + if (desks.desk[i].viewable) + RefreshDesktop(i); + if (i == desks.current) + { + RedrawPagersForDesktop(i, 2); + ForceUpdatePagersForDesktop(i); + } + else + RedrawPagersForDesktop(i, 1); + } + } + } + } + else + { + name = duplicate(w); + word(s, 6, w); + if (strcmp("(null)", w)) + bgf = duplicate(w); + word(s, 13, w); + if (strcmp("(null)", w)) + topf = duplicate(w); + bg = CreateDesktopBG(name, &icl, bgf, tile, keep_aspect, xjust, + yjust, xperc, yperc, topf, tkeep_aspect, + txjust, tyjust, txperc, typerc); + if (name) + Efree(name); + if (bgf) + Efree(bgf); + if (topf) + Efree(topf); + AddItem(bg, bg->name, 0, LIST_TYPE_BACKGROUND); + } + } + else if (!strcmp(w, "draw_bg_to")) + { + Window win; + Background *bg; + + sscanf(s, "%*s %x %1000s", (unsigned int *)&win, w); + bg = (Background *) FindItem(w, 0, LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND); + if (bg) + SetBackgroundTo(id, win, bg, 0); + CommsSend(c, "done"); + } + else if (!strcmp(w, "set_controls")) + { + int i, num, wd; + Button **blst; + int a, b; + int ax, ay; + char dragbar_change = 0; + + wd = 2; + w[0] = 0; + while (atword(s, wd)) + { + word(s, wd, w); + wd++; + if (!strcmp(w, "FOCUSMODE:")) + { + word(s, wd, w); + mode.focusmode = atoi(w); + } + else if (!strcmp(w, "DOCKDIRMODE:")) + { + word(s, wd, w); + mode.dockdirmode = atoi(w); + } + else if (!strcmp(w, "ICONDIRMODE:")) + { + word(s, wd, w); + mode.primaryicondir = atoi(w); + } + else if (!strcmp(w, "MOVEMODE:")) + { + word(s, wd, w); + mode.movemode = atoi(w); + if ((ird) && (mode.movemode == 5)) + mode.movemode = 3; + } + else if (!strcmp(w, "RESIZEMODE:")) + { + word(s, wd, w); + mode.resizemode = atoi(w); + if (mode.resizemode == 5) + mode.resizemode = 3; + } + else if (!strcmp(w, "SLIDEMODE:")) + { + word(s, wd, w); + mode.slidemode = atoi(w); + } + else if (!strcmp(w, "CLEANUPSLIDE:")) + { + word(s, wd, w); + mode.cleanupslide = atoi(w); + } + else if (!strcmp(w, "MAPSLIDE:")) + { + word(s, wd, w); + mode.mapslide = atoi(w); + } + else if (!strcmp(w, "SLIDESPEEDMAP:")) + { + word(s, wd, w); + mode.slidespeedmap = atoi(w); + } + else if (!strcmp(w, "SLIDESPEEDCLEANUP:")) + { + word(s, wd, w); + mode.slidespeedcleanup = atoi(w); + } + else if (!strcmp(w, "SHADESPEED:")) + { + word(s, wd, w); + mode.shadespeed = atoi(w); + } + else if (!strcmp(w, "DESKTOPBGTIMEOUT:")) + { + word(s, wd, w); + mode.desktop_bg_timeout = atoi(w); + } + else if (!strcmp(w, "SOUND:")) + { + word(s, wd, w); + mode.sound = atoi(w); + if ((mode.sound) && (sound_fd < 0)) + SoundInit(); + } + else if (!strcmp(w, "BUTTONMOVERESISTANCE:")) + { + word(s, wd, w); + mode.button_move_resistance = atoi(w); + } + else if (!strcmp(w, "AUTOSAVE:")) + { + word(s, wd, w); + mode.autosave = atoi(w); + } + else if (!strcmp(w, "MEMORYPARANOIA:")) + { + word(s, wd, w); + mode.memory_paranoia = atoi(w); + } + else if (!strcmp(w, "MENUSLIDE:")) + { + word(s, wd, w); + mode.menuslide = atoi(w); + } + else if (!strcmp(w, "NUMDESKTOPS:")) + { + word(s, wd, w); + ChangeNumberOfDesktops(atoi(w)); + } + else if (!strcmp(w, "TOOLTIPS:")) + { + word(s, wd, w); + mode.tooltips = atoi(w); + } + else if (!strcmp(w, "TIPTIME:")) + { + word(s, wd, w); + mode.tiptime = atof(w); + } + else if (!strcmp(w, "AUTORAISE:")) + { + word(s, wd, w); + mode.autoraise = atoi(w); + } + else if (!strcmp(w, "AUTORAISETIME:")) + { + word(s, wd, w); + mode.autoraisetime = atof(w); + } + else if (!strcmp(w, "DOCKSTARTX:")) + { + word(s, wd, w); + mode.dockstartx = atoi(w); + } + else if (!strcmp(w, "DOCKSTARTY:")) + { + word(s, wd, w); + mode.dockstarty = atoi(w); + } + else if (!strcmp(w, "SAVEUNDER:")) + { + word(s, wd, w); + mode.save_under = atoi(w); + } + else if (!strcmp(w, "DRAGDIR:")) + { + word(s, wd, w); + if (desks.dragdir != atoi(w)) + dragbar_change = 1; + desks.dragdir = atoi(w); + } + else if (!strcmp(w, "DRAGBARWIDTH:")) + { + word(s, wd, w); + if (desks.dragbar_width != atoi(w)) + dragbar_change = 1; + desks.dragbar_width = atoi(w); + } + else if (!strcmp(w, "DRAGBARORDERING:")) + { + word(s, wd, w); + if (desks.dragbar_ordering != atoi(w)) + dragbar_change = 1; + desks.dragbar_ordering = atoi(w); + } + else if (!strcmp(w, "DRAGBARLENGTH:")) + { + word(s, wd, w); + if (desks.dragbar_length != atoi(w)) + dragbar_change = 1; + desks.dragbar_length = atoi(w); + } + else if (!strcmp(w, "DESKSLIDEIN:")) + { + word(s, wd, w); + desks.slidein = atoi(w); + } + else if (!strcmp(w, "DESKSLIDESPEED:")) + { + word(s, wd, w); + desks.slidespeed = atoi(w); + } + else if (!strcmp(w, "HIQUALITYBG:")) + { + word(s, wd, w); + desks.hiqualitybg = atoi(w); + } + else if (!strcmp(w, "TRANSIENTSFOLLOWLEADER:")) + { + word(s, wd, w); + mode.transientsfollowleader = atoi(w); + } + else if (!strcmp(w, "SWITCHFORTRANSIENTMAP:")) + { + word(s, wd, w); + mode.switchfortransientmap = atoi(w); + } + else if (!strcmp(w, "SHOWICONS:")) + { + word(s, wd, w); + mode.showicons = atoi(w); + if (mode.showicons) + ShowIcons(); + else + HideIcons(); + } + else if (!strcmp(w, "ALL_NEW_WINDOWS_GET_FOCUS:")) + { + word(s, wd, w); + mode.all_new_windows_get_focus = atoi(w); + } + else if (!strcmp(w, "NEW_TRANSIENTS_GET_FOCUS:")) + { + word(s, wd, w); + mode.new_transients_get_focus = atoi(w); + } + else if (!strcmp(w, "NEW_TRANSIENTS_GET_FOCUS_IF_GROUP_FOCUSED:")) + { + word(s, wd, w); + mode.new_transients_get_focus_if_group_focused = atoi(w); + } + else if (!strcmp(w, "MANUAL_PLACEMENT:")) + { + word(s, wd, w); + mode.manual_placement = atoi(w); + } + else if (!strcmp(w, "RAISE_ON_NEXT_FOCUS:")) + { + word(s, wd, w); + mode.raise_on_next_focus = atoi(w); + } + else if (!strcmp(w, "RAISE_AFTER_NEXT_FOCUS:")) + { + word(s, wd, w); + mode.raise_after_next_focus = atoi(w); + } + else if (!strcmp(w, "DISPLAY_WARP:")) + { + word(s, wd, w); + mode.display_warp = atoi(w); + } + else if (!strcmp(w, "WARP_ON_NEXT_FOCUS:")) + { + word(s, wd, w); + mode.warp_on_next_focus = atoi(w); + } + else if (!strcmp(w, "WARP_AFTER_NEXT_FOCUS:")) + { + word(s, wd, w); + mode.warp_after_next_focus = atoi(w); + } + else if (!strcmp(w, "EDGE_FLIP_RESISTANCE:")) + { + word(s, wd, w); + mode.edge_flip_resistance = atoi(w); + ShowEdgeWindows(); + } + else if (!strcmp(w, "AREA_SIZE:")) + { + w[0] = 0; + word(s, wd, w); + if (w[0]) + a = atoi(w); + else + a = 0; + wd++; + w[0] = 0; + word(s, wd, w); + if (w[0]) + b = atoi(w); + else + b = 0; + if ((a > 0) && (b > 0)) + SetAreaSize(a, b); + } + wd++; + } + if (dragbar_change) + { + Button *b; + + while ((b = RemoveItem("_DESKTOP_DRAG_CONTROL", 0, LIST_FINDBY_NAME, + LIST_TYPE_BUTTON))) + DestroyButton(b); + InitDesktopControls(); + ShowDesktopControls(); + } + FixFocus(); + GNOME_SetDeskCount(); + GNOME_SetDeskNames(); + GetAreaSize(&ax, &ay); + GetCurrentArea(&a, &b); + if (a >= ax) + { + SetCurrentArea(ax - 1, b); + GetCurrentArea(&a, &b); + } + if (b >= ay) + SetCurrentArea(a, ay - 1); + blst = (Button **) ListItemType(&num, LIST_TYPE_BUTTON); + if (blst) + { + for (i = 0; i < num; i++) + { + if (!strcmp(blst[i]->name, "ICON")) + { + if (mode.showicons) + ShowButton(blst[i]); + else + HideButton(blst[i]); + } + } + Efree(blst); + } + } + else if (!strcmp(w, "get_controls")) + { + char buf[FILEPATH_LEN_MAX]; + int a, b; + + GetAreaSize(&a, &b); + Esnprintf(buf, sizeof(buf), + "FOCUSMODE: %i\n" + "DOCKDIRMODE: %i\n" + "ICONDIRMODE: %i\n" + "MOVEMODE: %i\n" + "RESIZEMODE: %i\n" + "SLIDEMODE: %i\n" + "CLEANUPSLIDE: %i\n" + "MAPSLIDE: %i\n" + "SLIDESPEEDMAP: %i\n" + "SLIDESPEEDCLEANUP: %i\n" + "SHADESPEED: %i\n" + "DESKTOPBGTIMEOUT: %i\n" + "SOUND: %i\n" + "BUTTONMOVERESISTANCE: %i\n" + "AUTOSAVE: %i\n" + "MEMORYPARANOIA: %i\n" + "TOOLTIPS: %i\n" + "TIPTIME: %f\n" + "AUTORAISE: %i\n" + "AUTORAISETIME: %f\n" + "DOCKSTARTX: %i\n" + "DOCKSTARTY: %i\n" + "SAVEUNDER: %i\n" + "MENUSLIDE: %i\n" + "NUMDESKTOPS: %i\n" + + "DRAGDIR: %i\n" + "DRAGBARWIDTH: %i\n" + "DRAGBARORDERING: %i\n" + "DRAGBARLENGTH: %i\n" + "DESKSLIDEIN: %i\n" + "DESKSLIDESPEED: %i\n" + "HIQUALITYBG: %i\n" + + "TRANSIENTSFOLLOWLEADER: %i\n" + "SWITCHFORTRANSIENTMAP: %i\n" + "SHOWICONS: %i\n" + "AREA_SIZE: %i %i\n" + "ALL_NEW_WINDOWS_GET_FOCUS: %i\n" + "NEW_TRANSIENTS_GET_FOCUS: %i\n" + "NEW_TRANSIENTS_GET_FOCUS_IF_GROUP_FOCUSED: %i\n" + "MANUAL_PLACEMENT: %i\n" + "RAISE_ON_NEXT_FOCUS: %i\n" + "RAISE_AFTER_NEXT_FOCUS: %i\n" + "DISPLAY_WARP: %i\n" + "WARP_ON_NEXT_FOCUS: %i\n" + "WARP_AFTER_NEXT_FOCUS: %i\n" + "EDGE_FLIP_RESISTANCE: %i\n" + , + mode.focusmode, mode.dockdirmode, mode.primaryicondir, + mode.movemode, mode.resizemode, mode.slidemode, + mode.cleanupslide, mode.mapslide, mode.slidespeedmap, + mode.slidespeedcleanup, mode.shadespeed, + mode.desktop_bg_timeout, mode.sound, + mode.button_move_resistance, mode.autosave, + mode.memory_paranoia, mode.tooltips, mode.tiptime, + mode.autoraise, mode.autoraisetime, + mode.dockstartx, mode.dockstarty, mode.save_under, + mode.menuslide, mode.numdesktops, + + desks.dragdir, desks.dragbar_width, + desks.dragbar_ordering, desks.dragbar_length, desks.slidein, + desks.slidespeed, desks.hiqualitybg, + + mode.transientsfollowleader, mode.switchfortransientmap, + mode.showicons, a, b, + mode.all_new_windows_get_focus, + mode.new_transients_get_focus, + mode.new_transients_get_focus_if_group_focused, + mode.manual_placement, + mode.raise_on_next_focus, + mode.raise_after_next_focus, + mode.display_warp, + mode.warp_on_next_focus, + mode.warp_after_next_focus, + mode.edge_flip_resistance + ); + CommsSend(c, buf); + } + else if (!strcmp(w, "call_raw")) + { + char *par; + int aid; + + word(s, 2, w); + aid = atoi(w); + par = atword(s, 3); + if ((aid > 0) && (aid < ACTION_NUMBEROF)) + (*(ActionFunctions[aid])) (par); + } + else if (!strcmp(w, "num_desks")) + { + word(s, 2, w); + if (!strcmp(w, "?")) + { + char buf[FILEPATH_LEN_MAX]; + + buf[0] = 0; + Esnprintf(buf, sizeof(buf), "Number of desks is %d\n", + mode.numdesktops); + CommsSend(c, buf); + } + else + { + int i, num; + EWin **lst; + + mode.numdesktops = atoi(w); + if (mode.numdesktops <= 0) + mode.numdesktops = 1; + else if (mode.numdesktops > ENLIGHTENMENT_CONF_NUM_DESKTOPS) + mode.numdesktops = ENLIGHTENMENT_CONF_NUM_DESKTOPS; + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if (lst) + { + for (i = 0; i < num; i++) + { + if (lst[i]->desktop >= mode.numdesktops) + MoveEwinToDesktop(lst[i], mode.numdesktops - 1); + } + Efree(lst); + } + if (desks.current >= mode.numdesktops) + GotoDesktop(mode.numdesktops - 1); + } + } + else if (!strcmp(w, "get_client_info")) + { + char buf[FILEPATH_LEN_MAX], none[] = "-NONE-"; + EWin *ewin; + unsigned int win; + + sscanf(s, "%*s %8x", &win); + ewin = (EWin *) FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + { + if (!ewin->client.title) + ewin->client.title = none; + if (!ewin->client.class) + ewin->client.class = none; + if (!ewin->client.name) + ewin->client.name = none; + if (!ewin->client.command) + ewin->client.command = none; + if (!ewin->client.machine) + ewin->client.machine = none; + if (!ewin->client.icon_name) + ewin->client.icon_name = none; + if (ewin->border) + { + Esnprintf(buf, sizeof(buf), + "***CLIENT***\n" + "CLIENT_WIN_ID: %8x\n" + "FRAME_WIN_ID: %8x\n" + "FRAME_X,Y: %5i , %5i\n" + "FRAME_WIDTH,HEIGHT: %5i , %5i\n" + "BORDER_NAME: %s\n" + "BORDER_BORDER: %5i , %5i , %5i , %5i\n" + "DESKTOP_NUMBER: %5i\n" + "INTERNAL_GROUP_ID: %5i\n" + "DOCKED: %5i\n" + "STICKY: %5i\n" + "VISIBLE: %5i\n" + "ICONIFIED: %5i\n" + "SHADED: %5i\n" + "ACTIVE: %5i\n" + "LAYER: %5i\n" + "NEVER_USE_AREA: %5i\n" + "FLOATING: %5i\n" + "CLIENT_WIDTH,HEIGHT: %5i , %5i\n" + "ICON_WIN_ID: %8x\n" + "ICON_PIXMAP,MASK_ID: %8x , %8x\n" + "CLIENT_GROUP_LEADER_ID: %8x\n" + "CLIENT_NEEDS_INPUT: %5i\n" + "TRANSIENT: %5i\n" + "TITLE: %s\n" + "CLASS: %s\n" + "NAME: %s\n" + "COMMAND: %s\n" + "MACHINE: %s\n" + "ICON_NAME: %s\n" + "IS_GROUP_LEADER: %5i\n" + "NO_RESIZE_HORIZONTAL: %5i\n" + "NO_RESIZE_VERTICAL: %5i\n" + "SHAPED: %5i\n" + "MIN_WIDTH,HEIGHT: %5i , %5i\n" + "MAX_WIDTH,HEIGHT: %5i , %5i\n" + "BASE_WIDTH,HEIGHT: %5i , %5i\n" + "WIDTH,HEIGHT_INC: %5i , %5i\n" + "ASPECT_MIN,MAX: %5.5f , %5.5f\n" + "MWM_BORDER: %5i\n" + "MWM_RESIZEH: %5i\n" + "MWM_TITLE: %5i\n" + "MWM_MENU: %5i\n" + "MWM_MINIMIZE: %5i\n" + "MWM_MAXIMIZE: %5i\n" + "APP_STATE: %5i\n", + ewin->client.win, + ewin->win, + ewin->x, + ewin->y, + ewin->w, + ewin->h, + ewin->border->name, + ewin->border->border.left, + ewin->border->border.right, + ewin->border->border.top, + ewin->border->border.bottom, + ewin->desktop, + ewin->group, + ewin->docked, + ewin->sticky, + ewin->visible, + ewin->iconified, + ewin->shaded, + ewin->active, + ewin->layer, + ewin->never_use_area, + ewin->floating, + ewin->client.w, + ewin->client.h, + ewin->client.icon_win, + ewin->client.icon_pmap, + ewin->client.icon_mask, + ewin->client.group, + ewin->client.need_input, + ewin->client.transient, + ewin->client.title, + ewin->client.class, + ewin->client.name, + ewin->client.command, + ewin->client.machine, + ewin->client.icon_name, + ewin->client.is_group_leader, + ewin->client.no_resize_h, + ewin->client.no_resize_v, + ewin->client.shaped, + ewin->client.width.min, + ewin->client.height.min, + ewin->client.width.max, + ewin->client.height.max, + ewin->client.base_w, + ewin->client.base_h, + ewin->client.w_inc, + ewin->client.h_inc, + ewin->client.aspect_min, + ewin->client.aspect_max, + ewin->client.mwm_decor_border, + ewin->client.mwm_decor_resizeh, + ewin->client.mwm_decor_title, + ewin->client.mwm_decor_menu, + ewin->client.mwm_decor_minimize, + ewin->client.mwm_decor_maximize, + ewin->client.app_state); + } + else + { + Esnprintf(buf, sizeof(buf), + "***CLIENT***\n" + "CLIENT_WIN_ID: %8x\n" + "FRAME_WIN_ID: %8x\n" + "FRAME_X,Y: %5i , %5i\n" + "FRAME_WIDTH,HEIGHT: %5i , %5i\n" + "BORDER_NAME: %s\n" + "BORDER_BORDER: %5i , %5i , %5i , %5i\n" + "DESKTOP_NUMBER: %5i\n" + "INTERNAL_GROUP_ID: %5i\n" + "DOCKED: %5i\n" + "STICKY: %5i\n" + "VISIBLE: %5i\n" + "ICONIFIED: %5i\n" + "SHADED: %5i\n" + "ACTIVE: %5i\n" + "LAYER: %5i\n" + "NEVER_USE_AREA: %5i\n" + "FLOATING: %5i\n" + "CLIENT_WIDTH,HEIGHT: %5i , %5i\n" + "ICON_WIN_ID: %8x\n" + "ICON_PIXMAP,MASK_ID: %8x , %8x\n" + "CLIENT_GROUP_LEADER_ID: %8x\n" + "CLIENT_NEEDS_INPUT: %5i\n" + "TRANSIENT: %5i\n" + "TITLE: %s\n" + "CLASS: %s\n" + "NAME: %s\n" + "COMMAND: %s\n" + "MACHINE: %s\n" + "ICON_NAME: %s\n" + "IS_GROUP_LEADER: %5i\n" + "NO_RESIZE_HORIZONTAL: %5i\n" + "NO_RESIZE_VERTICAL: %5i\n" + "SHAPED: %5i\n" + "MIN_WIDTH,HEIGHT: %5i , %5i\n" + "MAX_WIDTH,HEIGHT: %5i , %5i\n" + "BASE_WIDTH,HEIGHT: %5i , %5i\n" + "WIDTH,HEIGHT_INC: %5i , %5i\n" + "ASPECT_MIN,MAX: %5.5f , %5.5f\n" + "MWM_BORDER: %5i\n" + "MWM_RESIZEH: %5i\n" + "MWM_TITLE: %5i\n" + "MWM_MENU: %5i\n" + "MWM_MINIMIZE: %5i\n" + "MWM_MAXIMIZE: %5i\n" + "APP_STATE: %5i\n", + ewin->client.win, + ewin->win, + ewin->x, + ewin->y, + ewin->w, + ewin->h, + none, + 0, + 0, + 0, + 0, + ewin->desktop, + ewin->group, + ewin->docked, + ewin->sticky, + ewin->visible, + ewin->iconified, + ewin->shaded, + ewin->active, + ewin->layer, + ewin->never_use_area, + ewin->floating, + ewin->client.w, + ewin->client.h, + ewin->client.icon_win, + ewin->client.icon_pmap, + ewin->client.icon_mask, + ewin->client.group, + ewin->client.need_input, + ewin->client.transient, + ewin->client.title, + ewin->client.class, + ewin->client.name, + ewin->client.command, + ewin->client.machine, + ewin->client.icon_name, + ewin->client.is_group_leader, + ewin->client.no_resize_h, + ewin->client.no_resize_v, + ewin->client.shaped, + ewin->client.width.min, + ewin->client.height.min, + ewin->client.width.max, + ewin->client.height.max, + ewin->client.base_w, + ewin->client.base_h, + ewin->client.w_inc, + ewin->client.h_inc, + ewin->client.aspect_min, + ewin->client.aspect_max, + ewin->client.mwm_decor_border, + ewin->client.mwm_decor_resizeh, + ewin->client.mwm_decor_title, + ewin->client.mwm_decor_menu, + ewin->client.mwm_decor_minimize, + ewin->client.mwm_decor_maximize, + ewin->client.app_state); + } + if (ewin->client.title == none) + ewin->client.title = NULL; + if (ewin->client.class == none) + ewin->client.class = NULL; + if (ewin->client.name == none) + ewin->client.name = NULL; + if (ewin->client.command == none) + ewin->client.command = NULL; + if (ewin->client.machine == none) + ewin->client.machine = NULL; + if (ewin->client.icon_name == none) + ewin->client.icon_name = NULL; + } + else + { + Esnprintf(buf, sizeof(buf), "No matching EWin found\n"); + } + if (buf) + { + CommsSend(c, buf); + } + } + else if (!strcmp(w, "dump_info")) + { + + char buf[FILEPATH_LEN_MAX]; + char buf2[FILEPATH_LEN_MAX]; + char buf3[FILEPATH_LEN_MAX]; + char buf4[FILEPATH_LEN_MAX]; + char buf5[FILEPATH_LEN_MAX]; + + Esnprintf(buf, sizeof(buf), "stuff:\n"); + if (mode.ewin) + { + Esnprintf(buf2, sizeof(buf2), "mode.ewin - %8x\n", + mode.ewin->client.win); + strcat(buf, buf2); + } + if (mode.focuswin) + { + Esnprintf(buf3, sizeof(buf3), "mode.focuswin - %8x\n", + mode.focuswin->client.win); + strcat(buf, buf3); + } + if (mode.realfocuswin) + { + Esnprintf(buf4, sizeof(buf4), "mode.realfocuswin - %8x\n", + mode.realfocuswin->client.win); + strcat(buf, buf4); + } + if (mode.cur_menu_mode) + { + strcat(buf, "cur_menu_mode is set\n"); + } + if (mode.context_ewin) + { + Esnprintf(buf5, sizeof(buf5), + "context_ewin - %8x\n", mode.context_ewin->client.win); + strcat(buf, buf5); + } + CommsSend(c, buf); + } + else if (!strcmp(w, "list_clients")) + { + char buf[FILEPATH_LEN_MAX], *ret = NULL, none[] = "-NONE-"; + EWin **lst; + int i, num; + + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + for (i = 0; i < num; i++) + { + if (!lst[i]->client.title) + lst[i]->client.title = none; + if (!lst[i]->client.class) + lst[i]->client.class = none; + if (!lst[i]->client.name) + lst[i]->client.name = none; + if (!lst[i]->client.command) + lst[i]->client.command = none; + if (!lst[i]->client.machine) + lst[i]->client.machine = none; + if (!lst[i]->client.icon_name) + lst[i]->client.icon_name = none; + if (lst[i]->border) + { + Esnprintf(buf, sizeof(buf), + "***CLIENT***\n" + "CLIENT_WIN_ID: %8x\n" + "FRAME_WIN_ID: %8x\n" + "FRAME_X,Y: %5i , %5i\n" + "FRAME_WIDTH,HEIGHT: %5i , %5i\n" + "BORDER_NAME: %s\n" + "BORDER_BORDER: %5i , %5i , %5i , %5i\n" + "DESKTOP_NUMBER: %5i\n" + "INTERNAL_GROUP_ID: %5i\n" + "DOCKED: %5i\n" + "STICKY: %5i\n" + "VISIBLE: %5i\n" + "ICONIFIED: %5i\n" + "SHADED: %5i\n" + "ACTIVE: %5i\n" + "LAYER: %5i\n" + "NEVER_USE_AREA: %5i\n" + "FLOATING: %5i\n" + "CLIENT_WIDTH,HEIGHT: %5i , %5i\n" + "ICON_WIN_ID: %8x\n" + "ICON_PIXMAP,MASK_ID: %8x , %8x\n" + "CLIENT_GROUP_LEADER_ID: %8x\n" + "CLIENT_NEEDS_INPUT: %5i\n" + "TRANSIENT: %5i\n" + "TITLE: %s\n" + "CLASS: %s\n" + "NAME: %s\n" + "COMMAND: %s\n" + "MACHINE: %s\n" + "ICON_NAME: %s\n" + "IS_GROUP_LEADER: %5i\n" + "NO_RESIZE_HORIZONTAL: %5i\n" + "NO_RESIZE_VERTICAL: %5i\n" + "SHAPED: %5i\n" + "MIN_WIDTH,HEIGHT: %5i , %5i\n" + "MAX_WIDTH,HEIGHT: %5i , %5i\n" + "BASE_WIDTH,HEIGHT: %5i , %5i\n" + "WIDTH,HEIGHT_INC: %5i , %5i\n" + "ASPECT_MIN,MAX: %5.5f , %5.5f\n" + "MWM_BORDER: %5i\n" + "MWM_RESIZEH: %5i\n" + "MWM_TITLE: %5i\n" + "MWM_MENU: %5i\n" + "MWM_MINIMIZE: %5i\n" + "MWM_MAXIMIZE: %5i\n" + "APP_STATE: %5i\n", + lst[i]->client.win, + lst[i]->win, + lst[i]->x, + lst[i]->y, + lst[i]->w, + lst[i]->h, + lst[i]->border->name, + lst[i]->border->border.left, + lst[i]->border->border.right, + lst[i]->border->border.top, + lst[i]->border->border.bottom, + lst[i]->desktop, + lst[i]->group, + lst[i]->docked, + lst[i]->sticky, + lst[i]->visible, + lst[i]->iconified, + lst[i]->shaded, + lst[i]->active, + lst[i]->layer, + lst[i]->never_use_area, + lst[i]->floating, + lst[i]->client.w, + lst[i]->client.h, + lst[i]->client.icon_win, + lst[i]->client.icon_pmap, + lst[i]->client.icon_mask, + lst[i]->client.group, + lst[i]->client.need_input, + lst[i]->client.transient, + lst[i]->client.title, + lst[i]->client.class, + lst[i]->client.name, + lst[i]->client.command, + lst[i]->client.machine, + lst[i]->client.icon_name, + lst[i]->client.is_group_leader, + lst[i]->client.no_resize_h, + lst[i]->client.no_resize_v, + lst[i]->client.shaped, + lst[i]->client.width.min, + lst[i]->client.height.min, + lst[i]->client.width.max, + lst[i]->client.height.max, + lst[i]->client.base_w, + lst[i]->client.base_h, + lst[i]->client.w_inc, + lst[i]->client.h_inc, + lst[i]->client.aspect_min, + lst[i]->client.aspect_max, + lst[i]->client.mwm_decor_border, + lst[i]->client.mwm_decor_resizeh, + lst[i]->client.mwm_decor_title, + lst[i]->client.mwm_decor_menu, + lst[i]->client.mwm_decor_minimize, + lst[i]->client.mwm_decor_maximize, + lst[i]->client.app_state); + } + else + { + Esnprintf(buf, sizeof(buf), + "***CLIENT***\n" + "CLIENT_WIN_ID: %8x\n" + "FRAME_WIN_ID: %8x\n" + "FRAME_X,Y: %5i , %5i\n" + "FRAME_WIDTH,HEIGHT: %5i , %5i\n" + "BORDER_NAME: %s\n" + "BORDER_BORDER: %5i , %5i , %5i , %5i\n" + "DESKTOP_NUMBER: %5i\n" + "INTERNAL_GROUP_ID: %5i\n" + "DOCKED: %5i\n" + "STICKY: %5i\n" + "VISIBLE: %5i\n" + "ICONIFIED: %5i\n" + "SHADED: %5i\n" + "ACTIVE: %5i\n" + "LAYER: %5i\n" + "NEVER_USE_AREA: %5i\n" + "FLOATING: %5i\n" + "CLIENT_WIDTH,HEIGHT: %5i , %5i\n" + "ICON_WIN_ID: %8x\n" + "ICON_PIXMAP,MASK_ID: %8x , %8x\n" + "CLIENT_GROUP_LEADER_ID: %8x\n" + "CLIENT_NEEDS_INPUT: %5i\n" + "TRANSIENT: %5i\n" + "TITLE: %s\n" + "CLASS: %s\n" + "NAME: %s\n" + "COMMAND: %s\n" + "MACHINE: %s\n" + "ICON_NAME: %s\n" + "IS_GROUP_LEADER: %5i\n" + "NO_RESIZE_HORIZONTAL: %5i\n" + "NO_RESIZE_VERTICAL: %5i\n" + "SHAPED: %5i\n" + "MIN_WIDTH,HEIGHT: %5i , %5i\n" + "MAX_WIDTH,HEIGHT: %5i , %5i\n" + "BASE_WIDTH,HEIGHT: %5i , %5i\n" + "WIDTH,HEIGHT_INC: %5i , %5i\n" + "ASPECT_MIN,MAX: %5.5f , %5.5f\n" + "MWM_BORDER: %5i\n" + "MWM_RESIZEH: %5i\n" + "MWM_TITLE: %5i\n" + "MWM_MENU: %5i\n" + "MWM_MINIMIZE: %5i\n" + "MWM_MAXIMIZE: %5i\n" + "APP_STATE: %5i\n", + lst[i]->client.win, + lst[i]->win, + lst[i]->x, + lst[i]->y, + lst[i]->w, + lst[i]->h, + none, + 0, + 0, + 0, + 0, + lst[i]->desktop, + lst[i]->group, + lst[i]->docked, + lst[i]->sticky, + lst[i]->visible, + lst[i]->iconified, + lst[i]->shaded, + lst[i]->active, + lst[i]->layer, + lst[i]->never_use_area, + lst[i]->floating, + lst[i]->client.w, + lst[i]->client.h, + lst[i]->client.icon_win, + lst[i]->client.icon_pmap, + lst[i]->client.icon_mask, + lst[i]->client.group, + lst[i]->client.need_input, + lst[i]->client.transient, + lst[i]->client.title, + lst[i]->client.class, + lst[i]->client.name, + lst[i]->client.command, + lst[i]->client.machine, + lst[i]->client.icon_name, + lst[i]->client.is_group_leader, + lst[i]->client.no_resize_h, + lst[i]->client.no_resize_v, + lst[i]->client.shaped, + lst[i]->client.width.min, + lst[i]->client.height.min, + lst[i]->client.width.max, + lst[i]->client.height.max, + lst[i]->client.base_w, + lst[i]->client.base_h, + lst[i]->client.w_inc, + lst[i]->client.h_inc, + lst[i]->client.aspect_min, + lst[i]->client.aspect_max, + lst[i]->client.mwm_decor_border, + lst[i]->client.mwm_decor_resizeh, + lst[i]->client.mwm_decor_title, + lst[i]->client.mwm_decor_menu, + lst[i]->client.mwm_decor_minimize, + lst[i]->client.mwm_decor_maximize, + lst[i]->client.app_state); + } + if (lst[i]->client.title == none) + lst[i]->client.title = NULL; + if (lst[i]->client.class == none) + lst[i]->client.class = NULL; + if (lst[i]->client.name == none) + lst[i]->client.name = NULL; + if (lst[i]->client.command == none) + lst[i]->client.command = NULL; + if (lst[i]->client.machine == none) + lst[i]->client.machine = NULL; + if (lst[i]->client.icon_name == none) + lst[i]->client.icon_name = NULL; + if (!ret) + { + ret = Emalloc(strlen(buf) + 1); + ret[0] = 0; + } + else + { + ret = Erealloc(ret, strlen(ret) + strlen(buf) + 1); + } + strcat(ret, buf); + } + if (ret) + { + CommsSend(c, ret); + Efree(ret); + } + if (lst) + Efree(lst); + } + else + unknown = 1; + + if (unknown) + { + s1 = c->clientname; + s2 = c->version; + if (!s1) + s1 = sunknown; + if (!s2) + s2 = sunknown; + { + char buf[FILEPATH_LEN_MAX]; + + Esnprintf(buf, sizeof(buf), "Received Unknown Client Message.\n" + "Client Name: %s\n" + "Client Version: %s\n" + "Message Contents:\n\n" + "%s\n", s1, s2, s); + DIALOG_OK("E IPC Error", buf); + AUDIO_PLAY("SOUND_ERROR_IPC"); + } + } + Efree(s); + EDBUG_RETURN_; +} + +void +DisplayClientInfo(Client * c, int onoff) +{ + EDBUG(6, "DisplayClientInfo"); + if (!c) + EDBUG_RETURN_; + + onoff = 0; + EDBUG_RETURN_; +} + +void +HideClientInfo() +{ + EDBUG(6, "HideClientInfo"); + EDBUG_RETURN_; +} diff --git a/src/conf.h b/src/conf.h new file mode 100644 index 00000000..ce4f3685 --- /dev/null +++ b/src/conf.h @@ -0,0 +1,286 @@ + +#define CONFIG_CONTROL 0 +#define CONFIG_TEXT 1 +#define CONFIG_MENU 2 +#define CONFIG_BORDER 3 +#define CONFIG_BUTTON 4 +#define CONFIG_DESKTOP 5 +#define CONFIG_ICONBOX 6 +#define CONFIG_EXEC 7 +#define CONFIG_KEYBIND 8 +#define CONFIG_SOUND 9 +#define CONFIG_SLIDERS 10 +#define CONFIG_ACTIONCLASS 11 +#define CONFIG_IMAGECLASS 12 +#define CONFIG_LOADFILE 13 +#define CONFIG_WINDOWMATCH 14 +#define CONFIG_COLORMOD 15 +#define CONFIG_SLIDEOUT 16 +#define CONFIG_TOOLTIP 17 +#define CONFIG_FX 18 +#define CONFIG_IBOX 19 +#define CONFIG_EXTRAS 20 +#define CONFIG_CLASSNAME 100 +#define CONFIG_MODIFIER 101 +#define CONFIG_TYPE 102 +#define CONFIG_ANYMOD 103 +#define CONFIG_ACTION 104 +#define CONFIG_NEXT 105 +#define CONFIG_INHERIT 106 +#define CONFIG_ACTION_TOOLTIP 107 +#define TEXT_ORIENTATION 200 +#define TEXT_JUSTIFICATION 201 +#define TEXT_MODE 202 +#define TEXT_FONTNAME 203 +#define TEXT_EFFECT 204 +#define TEXT_FG_COL 205 +#define TEXT_BG_COL 206 +#define CONTROL_MODE 300 +#define CONTROL_EWIN 301 +#define CONTROL_BUTTON 302 +#define CONTROL_NOEWIN 303 +#define CONTROL_PX 304 +#define CONTROL_PY 305 +#define CONTROL_X 306 +#define CONTROL_FOCUSMODE 307 +#define CONTROL_FOCUSWIN 308 +#define CONTROL_MOUSEOVERWIN 309 +#define CONTROL_CLICKFOCUSGRABBED 310 +#define CONTROL_MOVEMODE 311 +#define CONTROL_RESIZEMODE 312 +#define CONTROL_SLIDEMODE 313 +#define CONTROL_CLEANUPSLIDE 314 +#define CONTROL_MAPSLIDE 315 +#define CONTROL_SLIDESPEEDMAP 316 +#define CONTROL_SLIDESPEEDCLEANUP 317 +#define CONTROL_DOINGSLIDE 318 +#define CONTROL_SERVER_GRABBED 319 +#define CONTROL_DESKTOP_BG_TIMEOUT 320 +#define CONTROL_BUTTON_MOVE_RESISTANCE 321 +#define CONTROL_Y 322 +#define CONTROL_BUTTON_MOVE_PENDING 323 +#define CONTROL_AUTOSAVE 324 +#define CONTROL_DOCKDIRMODE 325 +#define CONTROL_SHADESPEED 326 +#define CONTROL_TOOLTIPS 327 +#define CONTROL_TOOLTIPTIME 328 +#define CONTROL_TOOLTIPTIMEOUT 329 +#define CONTROL_DOCKSTARTPOS 330 +#define CONTROL_SAVE_UNDER 331 +#define CONTROL_MENUSLIDE 332 +#define CONTROL_NUMDESKTOPS 333 +#define CONTROL_MEMORYPARANOIA 334 +#define CONTROL_TRANSIENTS_FOLLOW_LEADER 335 +#define CONTROL_SWITCH_FOR_TRANSIENT_MAP 336 +#define CONTROL_SHOWICONS 337 +#define CONTROL_AUTORAISE 338 +#define CONTROL_AUTORAISETIME 339 +#define CONTROL_ALL_NEW_WINDOWS_GET_FOCUS 340 +#define CONTROL_NEW_TRANSIENTS_GET_FOCUS 341 +#define CONTROL_NEW_TRANSIENTS_GET_FOCUS_IF_GROUP 342 +#define CONTROL_MANUAL_PLACEMENT 343 +#define CONTROL_RAISE_ON_NEXT_FOCUS 344 +#define CONTROL_WARP_ON_NEXT_FOCUS 345 +#define CONTROL_EDGE_FLIP_RESISTANCE 346 +#define CONTROL_SHOW_PAGERS 347 +#define CONTROL_PAGER_HIQ 348 +#define CONTROL_PAGER_SNAP 349 +#define CONTROL_USER_BG 1350 +#define CONTROL_PAGER_ZOOM 1351 +#define CONTROL_PAGER_TITLE 1352 +#define CONTROL_RAISE_AFTER_NEXT_FOCUS 1353 +#define CONTROL_DISPLAY_WARP 1354 +#define CONTROL_WARP_AFTER_NEXT_FOCUS 1355 +#define CONTROL_PAGER_SCANSPEED 1356 +#define CONTROL_ICONTEXT 1357 +#define ICLASS_NAME 350 +#define ICLASS_NORMAL 351 +#define ICLASS_CLICKED 352 +#define ICLASS_HILITED 353 +#define ICLASS_ACTIVE_NORMAL 354 +#define ICLASS_ACTIVE_CLICKED 355 +#define ICLASS_ACTIVE_HILITED 356 +#define ICLASS_LRTB 357 +#define ICLASS_PADDING 358 +#define ICLASS_STICKY_NORMAL 359 +#define ICLASS_STICKY_CLICKED 360 +#define ICLASS_STICKY_HILITED 361 +#define ICLASS_STICKY_ACTIVE_NORMAL 362 +#define ICLASS_STICKY_ACTIVE_CLICKED 363 +#define ICLASS_STICKY_ACTIVE_HILITED 364 +#define ICLASS_SUPERIMPOSE 365 +#define ICLASS_DISABLED 366 +#define ICLASS_ACTIVE_DISABLED 367 +#define ICLASS_STICKY_DISABLED 368 +#define ICLASS_STICKY_ACTIVE_DISABLED 369 +#define ICLASS_COLORMOD 370 +#define ICLASS_FILLRULE 371 +#define DESKTOP_DRAGDIR 400 +#define DESKTOP_DRAGBAR_WIDTH 401 +#define DESKTOP_DRAGBAR_ORDERING 402 +#define DESKTOP_DRAGBAR_LENGTH 403 +#define DESKTOP_SLIDEIN 404 +#define DESKTOP_SLIDESPEED 405 +#define DESKTOP_HIQUALITYBG 406 +#define DESKTOP_AREA_SIZE 407 +#define ACLASS_NAME 420 +#define ACLASS_TYPE 421 +#define ACLASS_MODIFIER 422 +#define ACLASS_ANYMOD 423 +#define ACLASS_ANYBUT 424 +#define ACLASS_BUT 425 +#define ACLASS_ANYKEY 426 +#define ACLASS_KEY 427 +#define ACLASS_EVENT_TRIGGER 428 +#define ACLASS_ACTION 429 +#define BORDERPART_ICLASS 450 +#define BORDERPART_ACLASS 451 +#define BORDERPART_TEXTCLASS 452 +#define BORDERPART_ONTOP 453 +#define BORDERPART_FLAGS 454 +#define BORDERPART_ISREGION 455 +#define BORDERPART_WMIN 456 +#define BORDERPART_WMAX 457 +#define BORDERPART_TXP 458 +#define BORDERPART_TXA 459 +#define BORDERPART_TYP 460 +#define BORDERPART_TYA 461 +#define BORDERPART_BORIGIN 462 +#define BORDERPART_BXP 463 +#define BORDERPART_BXA 464 +#define BORDERPART_BYP 465 +#define BORDERPART_BYA 466 +#define BORDERPART_TORIGIN 467 +#define BORDERPART_HMIN 468 +#define BORDERPART_HMAX 469 +#define BORDERPART_KEEPSHADE 470 +#define WINDOWMATCH_USEBORDER 480 +#define WINDOWMATCH_MATCHNAME 481 +#define WINDOWMATCH_MATCHCLASS 482 +#define WINDOWMATCH_MATCHTITLE 483 +#define WINDOWMATCH_WIDTH 484 +#define WINDOWMATCH_HEIGHT 485 +#define WINDOWMATCH_TRANSIENT 486 +#define WINDOWMATCH_NO_RESIZE_H 487 +#define WINDOWMATCH_NO_RESIZE_V 488 +#define WINDOWMATCH_SHAPED 489 +#define WINDOWMATCH_ICON 490 +#define WINDOWMATCH_DESKTOP 491 +#define WINDOWMATCH_MAKESTICKY 492 +#define BORDER_NAME 500 +#define BORDER_LEFT 501 +#define BORDER_RIGHT 502 +#define BORDER_TOP 503 +#define BORDER_BOTTOM 504 +#define BORDER_INIT 505 +#define SHADEDIR 506 +#define BORDER_CHANGES_SHAPE 507 +#define BORDER_GROUP_NAME 508 +#define BUTTON_NAME 520 +#define BUTTON_ACLASS 521 +#define BUTTON_ICLASS 522 +#define BUTTON_MINW 523 +#define BUTTON_MAXW 524 +#define BUTTON_FLAGS 525 +#define BUTTON_MAXH 526 +#define BUTTON_MINH 527 +#define BUTTON_XO 528 +#define BUTTON_YO 529 +#define BUTTON_XA 530 +#define BUTTON_XR 531 +#define BUTTON_YA 532 +#define BUTTON_YR 533 +#define BUTTON_XSR 534 +#define BUTTON_YSR 535 +#define BUTTON_XSA 536 +#define BUTTON_YSA 537 +#define BUTTON_SIMG 538 +#define BUTTON_DESK 539 +#define BUTTON_STICKY 540 +#define BUTTON_INTERNAL 541 +#define BUTTON_SHOW 542 +#define BUTTON_LABEL 543 +#define BG_RGB 560 +#define BG_BG1 561 +#define BG_BG2 562 +#define BG_NAME 563 +#define BG_DESKNUM 564 +#define KEY_CLASSNAME 580 +#define KEY_MODIFIER 581 +#define KEY_MOD 582 +#define KEY_ANYBUT 583 +#define KEY_BUT 584 +#define KEY_ANYKEY 585 +#define KEY_KEY 586 +#define KEY_BINDACLASS 587 +#define COLORMOD_RED 600 +#define COLORMOD_GREEN 601 +#define COLORMOD_BLUE 602 +#define SLIDEOUT_DIRECTION 620 +#define TOOLTIP_DRAWICLASS 640 +#define TOOLTIP_BUBBLE1 641 +#define TOOLTIP_BUBBLE2 642 +#define TOOLTIP_BUBBLE3 643 +#define TOOLTIP_BUBBLE4 644 +#define TOOLTIP_DISTANCE 645 +#define TOOLTIP_HELP_PIC 646 + +#define MENU_STYLE 699 +#define MENU_BG_ICLASS 700 +#define MENU_ITEM_ICLASS 701 +#define MENU_SUBMENU_ICLASS 702 +#define MENU_USE_ITEM_BACKGROUND 703 +#define MENU_MAX_COLUMNS 704 +#define MENU_MAX_ROWS 705 +#define MENU_USE_STYLE 706 +#define MENU_ITEM 707 +#define MENU_SUBMENU 708 +#define MENU_ACTION 709 +#define MENU_PREBUILT 710 +#define MENU_TITLE 711 + +#define MASK_NONE 0 +#define MASK_SHIFT 900 +#define MASK_LOCK 901 +#define MASK_CTRL 902 +#define MASK_MOD1 903 +#define MASK_MOD2 904 +#define MASK_MOD3 905 +#define MASK_MOD4 906 +#define MASK_MOD5 907 +#define MASK_CTRL_ALT 910 +#define MASK_CTRL_SHIFT 911 +#define MASK_SHIFT_ALT 912 +#define MASK_CTRL_SHIFT_ALT 913 +#define MASK_CTRL_META4 914 +#define MASK_SHIFT_META4 915 +#define MASK_CTRL_META4_SHIFT 916 +#define MASK_CTRL_META5 917 +#define MASK_SHIFT_META5 918 +#define MASK_CTRL_META5_SHIFT 919 +#define MASK_WINDOWS_SHIFT 920 +#define MASK_WINDOWS_CTRL 921 +#define MASK_WINDOWS_ALT 922 +#define CONFIG_ANYBUT 930 +#define CONFIG_ANYKEY 931 +#define CONFIG_OPEN 999 +#define CONFIG_CLOSE 1000 +#define CONFIG_NORMAL 5 + +#define CONFIG_CURSOR 800 +#define CURS_BG_RGB 801 +#define CURS_FG_RGB 802 +#define XBM_FILE 803 + +#define CONFIG_VERSION 1001 +#define CONFIG_INVALID 9999 + +#define CONFIG_TRANSPARENCY 2001 +#define CONFIG_SHOW_NAMES 2002 +#define CONFIG_ICON_SIZE 2003 +#define CONFIG_ICON_MODE 2004 +#define CONFIG_SCROLLBAR_SIDE 2005 +#define CONFIG_SCROLLBAR_ARROWS 2006 +#define CONFIG_AUTOMATIC_RESIZE 2007 +#define CONFIG_SHOW_ICON_BASE 2008 +#define CONFIG_SCROLLBAR_AUTOHIDE 2009 diff --git a/src/config.c b/src/config.c new file mode 100644 index 00000000..7d7834ff --- /dev/null +++ b/src/config.c @@ -0,0 +1,3959 @@ +#include "E.h" +#include "conf.h" + +static char is_autosave = 0; + +char * +GetLine(char *s, int size, FILE * f) +{ + + /* This function will get a single line from the file */ + + char *ret, *ss, inquote; + int i, j, k; + static int line_stack_size = 0; + static char **line_stack = NULL; + + s[0] = 0; + if (line_stack_size > 0) + { + strncpy(s, line_stack[0], size); + Efree(line_stack[0]); + for (i = 0; i < line_stack_size - 1; i++) + line_stack[i] = line_stack[i + 1]; + line_stack_size--; + if (line_stack_size > 0) + { + line_stack = Erealloc(line_stack, line_stack_size * sizeof(char *)); + } + else + { + Efree(line_stack); + line_stack = NULL; + } + return s; + } + + ret = fgets(s, size, f); + + if (strlen(s) > 0) + s[strlen(s) - 1] = 0; + + while (IsWhitespace(s)) + { + s[0] = 0; + ret = fgets(s, size, f); + if (!ret) + return NULL; + if (strlen(s) > 0) + s[strlen(s) - 1] = 0; + } + + i = 0; + inquote = 0; + while (s[i]) + { + if (!inquote) + { + if (s[i] == '"') + { + j = i; + while (s[j]) + { + s[j] = s[j + 1]; + j++; + } + inquote = 1; + i--; + } + } + else + { + if (s[i] == '"') + { + j = i + 1; + while (s[j]) + { + if (s[j] == ';') + break; + if ((s[j] == '"') && (j == (i + 1))) + break; + if (!isspace(s[j])) + { + j--; + break; + } + j++; + } + k = j - i; + j = i; + while (s[j]) + { + s[j] = s[j + k]; + j++; + } + inquote = 0; + i--; + } + } + i++; + } + + j = strlen(s); + if (j > 0) + { + if (strchr(s, ';')) + { + s[j] = ';'; + s[j + 1] = 0; + } + } + + i = 0; + ss = s; + while (s[i]) + { + if (s[i] == ';') + { + j = (&(s[i]) - ss); + if (j > 0) + { + line_stack_size++; + if (!line_stack) + line_stack = Emalloc(line_stack_size * sizeof(char *)); + + else + line_stack = Erealloc(line_stack, + line_stack_size * sizeof(char *)); + + line_stack[line_stack_size - 1] = Emalloc(j + 1); + strncpy(line_stack[line_stack_size - 1], ss, j); + line_stack[line_stack_size - 1][j] = 0; + ss = &(s[i + 1]); + } + } + i++; + } + + if (line_stack_size > 0) + { + strncpy(s, line_stack[0], size); + Efree(line_stack[0]); + for (i = 0; i < line_stack_size - 1; i++) + line_stack[i] = line_stack[i + 1]; + line_stack_size--; + if (line_stack_size > 0) + { + line_stack = Erealloc(line_stack, + line_stack_size * sizeof(char *)); + + } + else + { + Efree(line_stack); + line_stack = NULL; + } + return s; + } + + return ret; +} + +void +Config_Text(FILE * ConfigFile) +{ + + /* This function reads in a TextClass from a configuration file */ + + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + TextClass *tc = NULL; + TextState *ts = NULL; + int fields; + + tc = CreateTclass(); + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000[^=]", &i1, s2); + + if (fields < 1) + { + i1 = CONFIG_INVALID; + } + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + Alert("CONFIG: missing required data in \"%s\"\n", s); + i1 = CONFIG_INVALID; + } + } + switch (i1) + { + case CONFIG_CLOSE: + TclassPopulate(tc); + AddItem(tc, tc->name, 0, LIST_TYPE_TCLASS); + return; + case CONFIG_CLASSNAME: + if (tc->name) + Efree(tc->name); + tc->name = duplicate(s2); + break; + case TEXT_ORIENTATION: + ts->style.orientation = atoi(s2); + break; + case TEXT_JUSTIFICATION: + tc->justification = atoi(s2); + break; + case CONFIG_DESKTOP: + case ICLASS_NORMAL: + tc->norm.normal = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_CLICKED: + tc->norm.clicked = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_HILITED: + tc->norm.hilited = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_DISABLED: + tc->norm.disabled = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_STICKY_NORMAL: + tc->sticky.normal = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_STICKY_CLICKED: + tc->sticky.clicked = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_STICKY_HILITED: + tc->sticky.hilited = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_STICKY_DISABLED: + tc->sticky.disabled = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_ACTIVE_NORMAL: + tc->active.normal = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_ACTIVE_CLICKED: + tc->active.clicked = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_ACTIVE_HILITED: + tc->active.hilited = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_ACTIVE_DISABLED: + tc->active.disabled = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_STICKY_ACTIVE_NORMAL: + tc->sticky_active.normal = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_STICKY_ACTIVE_CLICKED: + tc->sticky_active.clicked = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_STICKY_ACTIVE_HILITED: + tc->sticky_active.hilited = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case ICLASS_STICKY_ACTIVE_DISABLED: + tc->sticky_active.disabled = ts = CreateTextState(); + ts->fontname = duplicate(s2); + ts->style.mode = MODE_VERBATIM; + break; + case TEXT_MODE: + ts->style.mode = atoi(s2); + break; + case TEXT_EFFECT: + ts->effect = atoi(s2); + break; + case TEXT_FG_COL: + sscanf(s, "%*s %i %i %i", + &ts->fg_col.r, + &ts->fg_col.g, + &ts->fg_col.b); + break; + case TEXT_BG_COL: + sscanf(s, "%*s %i %i %i", + &ts->bg_col.r, + &ts->bg_col.g, + &ts->bg_col.b); + break; + default: + Alert("Warning: unable to determine what to do with\n" + "the following text in the middle of current Text" + " definition:\n" + "%s\nWill ignore and continue...\n", s); + } + + } + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading a text block. Outcome is likely not good.\n"); +} + +void +Config_Slideout(FILE * ConfigFile) +{ + + /* This function reads in a slideout from a configuration file */ + + Slideout *slideout = 0; + int i1; + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + char *name = 0; + int fields; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + { + i1 = CONFIG_INVALID; + } + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + Alert("CONFIG: missing required data in \"%s\"\n", s); + i1 = CONFIG_INVALID; + } + } + switch (i1) + { + case CONFIG_CLOSE: + if (slideout) + AddItem(slideout, slideout->name, 0, LIST_TYPE_SLIDEOUT); + return; + case CONFIG_CLASSNAME: + if (name) + Efree(name); + name = duplicate(s2); + break; + case SLIDEOUT_DIRECTION: + slideout = CreateSlideout(name, (char)atoi(s2)); + if (name) + Efree(name); + break; + case CONFIG_BUTTON: + { + Button *b; + + b = (Button *) FindItem(s2, 0, LIST_FINDBY_NAME, + LIST_TYPE_BUTTON); + if (b) + { + AddButtonToSlideout(slideout, b); + b->ref_count++; + } + } + break; + default: + Alert("Warning: unable to determine what to do with\n" + "the following text in the middle of current Text " + "definition:\n" + "%s\nWill ignore and continue...\n", s); + } + + } + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading a Slideout block. Outcome is likely not good.\n"); +} + +void +Config_Control(FILE * ConfigFile) +{ + + /* this function reads in the control segment of the + * configuration file... this contains all the generic mode.blah + * stuff as well as desks.blah + */ + + char s[FILEPATH_LEN_MAX]; + int i1, i2, i3, fields; + float f1; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + i1 = i2 = CONFIG_INVALID; + fields = sscanf(s, "%i %i", &i1, &i2); + + if (fields < 1) + { + i1 = CONFIG_INVALID; + } + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + { + RecoverUserConfig(); + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + RecoverUserConfig(); + Alert("CONFIG: missing required data in \"%s\"\n", s); + i1 = CONFIG_INVALID; + } + } + switch (i1) + { + case CONFIG_CLOSE: + return; + case CONFIG_SOUND: + mode.sound = i2; + break; + case CONTROL_SAVE_UNDER: + mode.save_under = i2; + break; + case CONTROL_FOCUSMODE: + mode.focusmode = i2; + break; + case CONTROL_MOVEMODE: + mode.movemode = i2; + break; + case CONTROL_RESIZEMODE: + mode.resizemode = i2; + break; + case CONTROL_SLIDEMODE: + mode.slidemode = i2; + break; + case CONTROL_CLEANUPSLIDE: + mode.cleanupslide = i2; + break; + case CONTROL_DOCKDIRMODE: + mode.dockdirmode = i2; + break; + case CONTROL_MAPSLIDE: + mode.mapslide = i2; + break; + case CONTROL_TOOLTIPS: + mode.tooltips = i2; + break; + case CONTROL_MENUSLIDE: + mode.menuslide = i2; + break; + case CONTROL_NUMDESKTOPS: + mode.numdesktops = i2; + if (mode.numdesktops <= 0) + { + mode.numdesktops = 1; + } + else if (mode.numdesktops > ENLIGHTENMENT_CONF_NUM_DESKTOPS) + { + mode.numdesktops = ENLIGHTENMENT_CONF_NUM_DESKTOPS; + } + break; + case CONTROL_MEMORYPARANOIA: + mode.memory_paranoia = i2; + break; + case CONTROL_TRANSIENTS_FOLLOW_LEADER: + mode.transientsfollowleader = i2; + break; + case CONTROL_SWITCH_FOR_TRANSIENT_MAP: + mode.switchfortransientmap = i2; + break; + case CONTROL_SHOWICONS: + mode.showicons = i2; + break; + case CONTROL_ALL_NEW_WINDOWS_GET_FOCUS: + mode.all_new_windows_get_focus = i2; + break; + case CONTROL_NEW_TRANSIENTS_GET_FOCUS: + mode.new_transients_get_focus = i2; + break; + case CONTROL_NEW_TRANSIENTS_GET_FOCUS_IF_GROUP: + mode.new_transients_get_focus_if_group_focused = i2; + break; + case CONTROL_MANUAL_PLACEMENT: + mode.manual_placement = i2; + break; + case CONTROL_RAISE_ON_NEXT_FOCUS: + mode.raise_on_next_focus = i2; + break; + case CONTROL_RAISE_AFTER_NEXT_FOCUS: + mode.raise_after_next_focus = i2; + break; + case CONTROL_DISPLAY_WARP: + mode.display_warp = i2; + break; + case CONTROL_WARP_ON_NEXT_FOCUS: + mode.warp_on_next_focus = i2; + break; + case CONTROL_WARP_AFTER_NEXT_FOCUS: + mode.warp_after_next_focus = i2; + break; + case CONTROL_PAGER_SCANSPEED: + mode.pager_scanspeed = i2; + break; + case CONTROL_EDGE_FLIP_RESISTANCE: + mode.edge_flip_resistance = i2; + break; + case CONTROL_TOOLTIPTIME: + sscanf(s, "%*i %f", &f1); + mode.tiptime = f1; + break; + case CONTROL_AUTORAISE: + mode.autoraise = i2; + break; + case CONTROL_AUTORAISETIME: + sscanf(s, "%*i %f", &f1); + mode.autoraisetime = f1; + break; + case DESKTOP_DRAGDIR: + desks.dragdir = i2; + break; + case DESKTOP_DRAGBAR_WIDTH: + desks.dragbar_width = i2; + break; + case DESKTOP_DRAGBAR_ORDERING: + desks.dragbar_ordering = i2; + break; + case DESKTOP_DRAGBAR_LENGTH: + desks.dragbar_length = i2; + break; + case DESKTOP_SLIDEIN: + desks.slidein = i2; + break; + case DESKTOP_SLIDESPEED: + desks.slidespeed = i2; + break; + case CONTROL_SHADESPEED: + mode.shadespeed = i2; + break; + case DESKTOP_HIQUALITYBG: + desks.hiqualitybg = i2; + break; + case DESKTOP_AREA_SIZE: + sscanf(s, "%i %i %i", &i1, &i2, &i3); + SetAreaSize(i2, i3); + break; + case CONTROL_SLIDESPEEDMAP: + mode.slidespeedmap = i2; + break; + case CONTROL_SLIDESPEEDCLEANUP: + mode.slidespeedcleanup = i2; + break; + case CONTROL_DESKTOP_BG_TIMEOUT: + mode.desktop_bg_timeout = i2; + break; + case CONTROL_BUTTON_MOVE_RESISTANCE: + mode.button_move_resistance = i2; + break; + case CONTROL_AUTOSAVE: + mode.autosave = i2; + break; + case CONTROL_SHOW_PAGERS: + mode.show_pagers = i2; + break; + case CONTROL_PAGER_ZOOM: + mode.pager_zoom = i2; + break; + case CONTROL_PAGER_TITLE: + mode.pager_title = i2; + break; + case CONTROL_PAGER_HIQ: + mode.pager_hiq = i2; + break; + case CONTROL_PAGER_SNAP: + mode.pager_snap = i2; + break; + case CONTROL_USER_BG: + mode.user_bg = i2; + break; + case CONTROL_DOCKSTARTPOS: + sscanf(s, "%*s %d %d ", &mode.dockstartx, + &mode.dockstarty); + break; + case CONTROL_ICONTEXT: + { + char s2[FILEPATH_LEN_MAX]; + + s2[0] = 0; + word(s, 2, s2); + mode.icon_textclass = FindItem(s2, 0, LIST_FINDBY_NAME, + LIST_TYPE_TCLASS); + if (mode.icon_textclass) + mode.icon_textclass->ref_count++; + + } + break; + default: + RecoverUserConfig(); + Alert("Warning: unable to determine what to do with\n" + "the following text in the middle of current Control " + "definition:\n" + "%s\nWill ignore and continue...\n", s); + } + } + RecoverUserConfig(); + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading a Control block. Outcome is likely not good.\n"); +} + +void +Config_MenuStyle(FILE * ConfigFile) +{ + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + MenuStyle *ms = NULL; + int fields; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + { + i1 = CONFIG_INVALID; + } + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + Alert("CONFIG: missing required data in \"%s\"\n", s); + } + } + switch (i1) + { + case CONFIG_CLOSE: + AddItem(ms, ms->name, 0, LIST_TYPE_MENU_STYLE); + return; + case CONFIG_CLASSNAME: + ms = CreateMenuStyle(); + if (ms->name) + Efree(ms->name); + ms->name = duplicate(s2); + break; + case CONFIG_TEXT: + ms->tclass = FindItem(s2, 0, + LIST_FINDBY_NAME, LIST_TYPE_TCLASS); + if (ms->tclass) + ms->tclass->ref_count++; + break; + case MENU_BG_ICLASS: + ms->bg_iclass = FindItem(s2, 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ms->bg_iclass) + ms->bg_iclass->ref_count++; + break; + case MENU_ITEM_ICLASS: + ms->item_iclass = FindItem(s2, 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ms->item_iclass) + ms->item_iclass->ref_count++; + + break; + case MENU_SUBMENU_ICLASS: + ms->sub_iclass = FindItem(s2, 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ms->sub_iclass) + ms->sub_iclass->ref_count++; + break; + case MENU_USE_ITEM_BACKGROUND: + ms->use_item_bg = atoi(s2); + if (ms->use_item_bg) + { + if (ms->bg_iclass) + { + ms->bg_iclass->ref_count--; + ms->bg_iclass = NULL; + } + } + break; + case MENU_MAX_COLUMNS: + ms->maxx = atoi(s2); + break; + case MENU_MAX_ROWS: + ms->maxy = atoi(s2); + break; + case CONFIG_BORDER: + { + /* FIXME!!! I don't think this file is loaded in the + * right order! + */ + Border *b; + + if (ms->border_name) + Efree(ms->border_name); + + ms->border_name = duplicate(s2); + + b = (Border *) FindItem(ms->border_name, 0, LIST_FINDBY_NAME, + LIST_TYPE_BORDER); + if (b) + b->ref_count++; + } + break; + default: + break; + } + } + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading a Menu block. Outcome is likely not good.\n"); +} + +void +Config_Menu(FILE * ConfigFile) +{ + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + char s3[FILEPATH_LEN_MAX]; + char s4[FILEPATH_LEN_MAX]; + char s5[FILEPATH_LEN_MAX]; + char *txt = NULL, *params = NULL; + int i1; + Menu *m = NULL, *mm = NULL; + MenuItem *mi = NULL; + ImageClass *ic = NULL; + int fields; + int act = 0; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + { + i1 = CONFIG_INVALID; + } + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + Alert("CONFIG: missing required data in \"%s\"\n", s); + i1 = CONFIG_INVALID; + } + } + switch (i1) + { + case CONFIG_CLOSE: + if (m) + { + RealizeMenu(m); + AddItem(m, m->name, m->win, LIST_TYPE_MENU); + } + return; + case MENU_PREBUILT: + sscanf(s, "%i %4000s %4000s %4000s %4000s", + &i1, s2, s3, s4, s5); + if (!strcmp(s4, "dirscan")) + { + MenuStyle *ms; + + ms = FindItem(s3, 0, + LIST_FINDBY_NAME, LIST_TYPE_MENU_STYLE); + if (ms) + { + AUDIO_PLAY("SOUND_SCANNING"); + m = CreateMenuFromDirectory(s2, ms, s5); + ms->ref_count++; + } + } + else if (!strcmp(s4, "gnome")) + { + MenuStyle *ms; + + ms = FindItem(s3, 0, + LIST_FINDBY_NAME, LIST_TYPE_MENU_STYLE); + if (ms) + { + m = CreateMenuFromGnome(s2, ms, s5); + ms->ref_count++; + } + } + else if (!strcmp(s4, "borders")) + { + MenuStyle *ms; + + ms = FindItem(s3, 0, + LIST_FINDBY_NAME, LIST_TYPE_MENU_STYLE); + if (ms) + { + m = CreateMenuFromBorders(s2, ms); + ms->ref_count++; + } + } + else if (!strcmp(s4, "themes")) + { + MenuStyle *ms; + + ms = FindItem(s3, 0, + LIST_FINDBY_NAME, LIST_TYPE_MENU_STYLE); + if (ms) + { + m = CreateMenuFromThemes(s2, ms); + ms->ref_count++; + } + } + else if (!strcmp(s4, "file")) + { + MenuStyle *ms; + + ms = FindItem(s3, 0, + LIST_FINDBY_NAME, LIST_TYPE_MENU_STYLE); + if (ms) + { + m = CreateMenuFromFlatFile(s2, ms, s5, NULL); + ms->ref_count++; + } + } + else if (!strcmp(s4, "windowlist")) + { + MenuStyle *ms; + + ms = FindItem(s3, 0, + LIST_FINDBY_NAME, LIST_TYPE_MENU_STYLE); + if (ms) + { + m = CreateMenuFromAllEWins(s2, ms); + ms->ref_count++; + } + } + else if (!strcmp(s4, "desktopwindowlist")) + { + MenuStyle *ms; + + ms = FindItem(s3, 0, + LIST_FINDBY_NAME, LIST_TYPE_MENU_STYLE); + if (ms) + { + m = CreateMenuFromDesktops(s2, ms); + ms->ref_count++; + } + } + break; + case CONFIG_CLASSNAME: + if (!m) + m = CreateMenu(); + if (m->name) + Efree(m->name); + m->name = duplicate(s2); + break; + case MENU_USE_STYLE: + { + MenuStyle *ms; + + ms = (MenuStyle *) FindItem(s2, 0, LIST_FINDBY_NAME, + LIST_TYPE_MENU_STYLE); + if (ms) + { + m->style = ms; + ms->ref_count++; + } + } + break; + case MENU_TITLE: + if (m) + AddTitleToMenu(m, atword(s, 2)); + break; + case MENU_ITEM: + if ((txt) || (ic)) + { + mi = CreateMenuItem(txt, ic, act, params, NULL); + AddItemToMenu(m, mi); + } + ic = NULL; + if (txt) + Efree(txt); + txt = NULL; + if (strcmp("NULL", s2)) + ic = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + mi = NULL; + txt = duplicate(atword(s, 3)); + break; + case MENU_ACTION: + if ((txt) || (ic)) + { + char ok = 1; + + /* if its an execute line then check to see if the exec is + * on your system before adding the menu entry */ + act = atoi(s2); + if (act == ACTION_EXEC) + { + char buf[1024]; + char *path; + + sscanf(atword(s, 3), "%1000s", buf); + path = pathtoexec(buf); + if (path) + Efree(path); + else + ok = 0; + } + if (ok) + { + params = atword(s, 3); + mi = CreateMenuItem(txt, ic, act, params, NULL); + AddItemToMenu(m, mi); + } + ic = NULL; + if (txt) + Efree(txt); + txt = NULL; + } + break; + case MENU_SUBMENU: + sscanf(s, "%i %4000s %4000s", &i1, s2, s3); + ic = NULL; + if (strcmp("NULL", s3)) + ic = FindItem(s3, 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + mm = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_MENU); + /* if submenu empty - dont put it in - only if menu found */ + if ((mm) && (mm->num > 0) && (mm->style)) + { + mi = CreateMenuItem(atword(s, 4), ic, 0, NULL, mm); + AddItemToMenu(m, mi); + } + break; + default: + break; + } + } + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading a Menu block. Outcome is likely not good.\n"); +} + +void +BorderPartLoad(FILE * ConfigFile, char type, Border * b) +{ + + /* This function will load a borderpart off the file. + * There are several borderparts in a single border + */ + + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + ImageClass *iclass = 0; + ActionClass *aclass = 0; + TextClass *tclass = 0; + ECursor *ec = NULL; + char ontop = 1; + int flags = FLAG_BUTTON; + char isregion = 0, keepshade = 1; + int wmin = 0, wmax = 0, hmin = 0, hmax = 0, torigin = 0, + txp = 0, txa = 0, typ = 0, tya = 0, borigin = 0; + int bxp = 0, bxa = 0, byp = 0, bya = 0; + int fields; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + { + i1 = CONFIG_INVALID; + } + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + Alert("CONFIG: missing required data in \"%s\"\n", s); + i1 = CONFIG_INVALID; + } + } + switch (i1) + { + case CONFIG_CLOSE: + AddBorderPart(b, iclass, aclass, tclass, + ec, ontop, flags, isregion, + wmin, wmax, hmin, hmax, torigin, txp, txa, typ, + tya, borigin, bxp, bxa, byp, bya, keepshade); + return; + case CONFIG_IMAGECLASS: + case BORDERPART_ICLASS: + iclass = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + break; + case CONFIG_ACTIONCLASS: + case BORDERPART_ACLASS: + aclass = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_ACLASS); + break; + case CONFIG_TEXT: + case BORDERPART_TEXTCLASS: + tclass = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_TCLASS); + break; + case CONFIG_CURSOR: + ec = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_ECURSOR); + break; + case BORDERPART_ONTOP: + ontop = atoi(s2); + break; + case BORDERPART_FLAGS: + flags = atoi(s2); + break; + case BORDERPART_ISREGION: + isregion = atoi(s2); + break; + case BORDERPART_WMIN: + wmin = atoi(s2); + if (!wmax) + wmax = wmin; + break; + case BORDERPART_WMAX: + wmax = atoi(s2); + break; + case BORDERPART_HMIN: + hmin = atoi(s2); + if (!hmax) + hmax = hmin; + break; + case BORDERPART_HMAX: + hmax = atoi(s2); + break; + case BORDERPART_TORIGIN: + torigin = atoi(s2); + break; + case BORDERPART_TXP: + txp = atoi(s2); + break; + case BORDERPART_TXA: + txa = atoi(s2); + break; + case BORDERPART_TYP: + typ = atoi(s2); + break; + case BORDERPART_TYA: + tya = atoi(s2); + break; + case BORDERPART_BORIGIN: + borigin = atoi(s2); + break; + case BORDERPART_BXP: + bxp = atoi(s2); + break; + case BORDERPART_BXA: + bxa = atoi(s2); + break; + case BORDERPART_BYP: + byp = atoi(s2); + break; + case BORDERPART_BYA: + bya = atoi(s2); + break; + case BORDERPART_KEEPSHADE: + keepshade = atoi(s2); + break; + default: + break; + } + } + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading a BorderPart block. Outcome is likely not good.\n"); +} + +void +Config_Border(FILE * ConfigFile) +{ + + /* this function loads a border into memory. each border will + * contain several BorderParts. + */ + + Border *b = 0; + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + char added = 0; + int fields; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + { + i1 = CONFIG_INVALID; + } + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + Alert("CONFIG: missing required data in \"%s\"\n", s); + i1 = CONFIG_INVALID; + } + } + if (atoi(s2) == CONFIG_OPEN) + { + BorderPartLoad(ConfigFile, i1, b); + } + else + { + switch (i1) + { + case CONFIG_CLOSE: + if (!added) + AddItem(b, b->name, 0, LIST_TYPE_BORDER); + return; + case BORDER_INIT: + AddItem(b, b->name, 0, LIST_TYPE_BORDER); + added = 1; + break; + case CONFIG_CLASSNAME: + case BORDER_NAME: + b = CreateBorder(s2); + break; + case BORDER_GROUP_NAME: + b->group_border_name = duplicate(s2); + break; + case BORDER_LEFT: + b->border.left = atoi(s2); + break; + case BORDER_RIGHT: + b->border.right = atoi(s2); + break; + case BORDER_TOP: + b->border.top = atoi(s2); + break; + case BORDER_BOTTOM: + b->border.bottom = atoi(s2); + break; + case SHADEDIR: + b->shadedir = atoi(s2); + break; + case BORDER_CHANGES_SHAPE: + b->changes_shape = atoi(s2); + break; + default: + break; + } + } + } + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading a Main Border block. Outcome is likely not good.\n"); +} + +void +Config_Button(FILE * ConfigFile) +{ + + /* This function will load a Button from the config file */ + + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + char *name = 0; + char *label = 0; + ActionClass *ac = 0; + ImageClass *ic = 0; + TextClass *tc = 0; + Button *bt = 0; + Button *pbt = 0; + char ontop = 0; + int flags = 0, minw = 1, maxw = 99999, minh = 1; + int maxh = 99999, xo = 0, yo = 0, xa = 0; + int xr = 0, ya = 0, yr = 0, xsr = 0, xsa = 0, ysr = 0, + ysa = 0; + char simg = 0; + int desk = 0; + char sticky = 0; + char show = 1; + char internal = 0; + int fields; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + { + i1 = CONFIG_INVALID; + } + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + { + RecoverUserConfig(); + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + RecoverUserConfig(); + Alert("CONFIG: missing required data in \"%s\"\n", s); + i1 = CONFIG_INVALID; + } + } + switch (i1) + { + case CONFIG_CLOSE: + if ((!pbt) && (!is_autosave)) + { + bt = CreateButton(name, ic, ac, tc, label, ontop, flags, + minw, maxw, minh, maxh, xo, yo, xa, xr, ya, + yr, xsr, xsa, ysr, ysa, simg, desk, sticky); + bt->default_show = show; + bt->internal = internal; + AddItem(bt, bt->name, 0, LIST_TYPE_BUTTON); + } + if (name) + Efree(name); + return; + case CONFIG_TEXT: + tc = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_TCLASS); + if (pbt) + pbt->tclass = tc; + break; + case BUTTON_LABEL: + label = duplicate(atword(s, 2)); + if (pbt) + pbt->label = label; + break; + case BORDERPART_ONTOP: + ontop = atoi(s2); + if (pbt) + pbt->ontop = ontop; + break; + case CONFIG_CLASSNAME: + case BUTTON_NAME: + if (name) + Efree(name); + name = duplicate(s2); + pbt = FindItem(name, 0, LIST_FINDBY_NAME, LIST_TYPE_BUTTON); + break; + case CONFIG_ACTIONCLASS: + case BUTTON_ACLASS: + ac = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_ACLASS); + if (pbt) + pbt->aclass = ac; + break; + case CONFIG_IMAGECLASS: + case BUTTON_ICLASS: + ic = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (pbt) + pbt->iclass = ic; + break; + case BORDERPART_WMIN: + minw = atoi(s2); + if (pbt) + pbt->geom.width.min = minw; + break; + case BORDERPART_WMAX: + maxw = atoi(s2); + if (pbt) + pbt->geom.width.max = maxw; + break; + case BORDERPART_HMIN: + minh = atoi(s2); + if (pbt) + pbt->geom.height.min = minh; + break; + case BORDERPART_FLAGS: + flags = atoi(s2); + if (pbt) + pbt->flags = flags; + break; + case BORDERPART_HMAX: + maxh = atoi(s2); + if (pbt) + pbt->geom.height.max = maxh; + break; + case BUTTON_XO: + xo = atoi(s2); + if (pbt) + pbt->geom.xorigin = xo; + break; + case BUTTON_YO: + yo = atoi(s2); + if (pbt) + pbt->geom.yorigin = yo; + break; + case BUTTON_XA: + xa = atoi(s2); + if (pbt) + pbt->geom.xabs = xa; + break; + case BUTTON_XR: + xr = atoi(s2); + if (pbt) + pbt->geom.xrel = xr; + break; + case BUTTON_YA: + ya = atoi(s2); + if (pbt) + pbt->geom.yabs = ya; + break; + case BUTTON_YR: + yr = atoi(s2); + if (pbt) + pbt->geom.yrel = yr; + break; + case BUTTON_XSR: + xsr = atoi(s2); + if (pbt) + pbt->geom.xsizerel = xsr; + break; + case BUTTON_XSA: + xsa = atoi(s2); + if (pbt) + pbt->geom.xsizeabs = xsa; + break; + case BUTTON_YSR: + ysr = atoi(s2); + if (pbt) + pbt->geom.ysizerel = ysr; + break; + case BUTTON_YSA: + ysa = atoi(s2); + if (pbt) + pbt->geom.ysizeabs = ysa; + break; + case BUTTON_SIMG: + simg = atoi(s2); + if (pbt) + pbt->geom.size_from_image = simg; + break; + case BUTTON_DESK: + desk = atoi(s2); + if (pbt) + pbt->desktop = desk; + break; + case BUTTON_STICKY: + sticky = atoi(s2); + if (pbt) + pbt->sticky = sticky; + break; + case BUTTON_INTERNAL: + internal = atoi(s2); + if (pbt) + pbt->internal = internal; + break; + case BUTTON_SHOW: + show = atoi(s2); + if (pbt) + pbt->default_show = show; + break; + default: + break; + } + } + + if (name) + Efree(name); + + RecoverUserConfig(); + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading a Button block. Outcome is likely not good.\n"); + + return; +} + +void +Config_Desktop(FILE * ConfigFile) +{ + /* this sets desktop settings */ + ImlibColor icl; + Background *bg = 0; + char s[FILEPATH_LEN_MAX]; + char s1[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int ii1; + int i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0; + int j1 = 0, j2 = 0, j3 = 0, j4 = 0, j5 = 0; + char *bg1 = 0; + char *bg2 = 0; + char *name = 0; + char ignore = 0; + ColorModifierClass *cm = NULL; + int fields; + + icl.r = 0; + icl.g = 0; + icl.b = 0; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + ii1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &ii1, s2); + + if (fields < 1) + { + ii1 = CONFIG_INVALID; + } + else if (ii1 == CONFIG_CLOSE) + { + if (fields != 1) + { + RecoverUserConfig(); + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + } + else if (ii1 != CONFIG_INVALID) + { + if (fields != 2) + { + RecoverUserConfig(); + Alert("CONFIG: missing required data in \"%s\"\n", s); + ii1 = CONFIG_INVALID; + } + } + switch (ii1) + { + case CONFIG_CLOSE: + if (!ignore) + { + if ((!bg) && (name)) + { + char *tmp; + char ok = 1; + + /* check first if we can actually find the files */ + if (bg1) + { + tmp = FindFile(bg1); + if (!tmp) + { + ok = 0; + } + else + { + Efree(tmp); + } + } + if (bg2) + { + tmp = FindFile(bg2); + if (!tmp) + { + ok = 0; + } + else + { + Efree(tmp); + } + } + if (ok) + { + bg = CreateDesktopBG(name, &icl, bg1, i1, i2, + i3, i4, i5, i6, bg2, j1, j2, j3, j4, j5); + AddItem(bg, bg->name, 0, LIST_TYPE_BACKGROUND); + if (cm) + { + cm->ref_count++; + bg->cmclass = cm; + } + } + } + } + if (name) + Efree(name); + if (bg1) + Efree(bg1); + if (bg2) + Efree(bg2); + + return; + + case CONFIG_COLORMOD: + case ICLASS_COLORMOD: + cm = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_COLORMODIFIER); + break; + case CONFIG_CLASSNAME: + case BG_NAME: + if ((bg = FindItem(s2, 0, + LIST_FINDBY_NAME, LIST_TYPE_BACKGROUND))) + { + ignore = 1; + } + else + { + if (name) + Efree(name); + name = duplicate(s2); + } + break; + case BG_DESKNUM: + if (!ignore) + { + /* if its the root desktop and its another visual ... */ + /* create a desktop def all on its own */ + if ((atoi(s2) < ENLIGHTENMENT_CONF_NUM_DESKTOPS) && + (atoi(s2) >= 0)) + { + if ((desks.desk[atoi(s2)].bg == NULL) || + (mode.user_bg)) + { + if ((ird) && (atoi(s2) == 0)) + bg = NULL; + if (!bg) + { + bg = CreateDesktopBG(name, &icl, bg1, i1, i2, + i3, i4, i5, i6, bg2, j1, j2, j3, j4, j5); + AddItem(bg, bg->name, 0, LIST_TYPE_BACKGROUND); + } + if (!strcmp(bg->name, "NONE")) + { + SetDesktopBg(atoi(s2), NULL); + } + else + { + SetDesktopBg(atoi(s2), bg); + } + if ((ird) && (atoi(s2) == 0)) + bg = NULL; + } + } + } + else + { + if ((atoi(s2) < ENLIGHTENMENT_CONF_NUM_DESKTOPS) && + (atoi(s2) >= 0)) + { + if ((desks.desk[atoi(s2)].bg == NULL) || + (mode.user_bg)) + { + if (bg) + { + if (!strcmp(bg->name, "NONE")) + { + SetDesktopBg(atoi(s2), NULL); + } + else + { + SetDesktopBg(atoi(s2), bg); + } + if ((ird) && (atoi(s2) == 0)) + bg = NULL; + } + } + } + } + break; + case BG_RGB: + sscanf(s, "%4000s %d %d %d", s1, &icl.r, &icl.g, &icl.b); + if (ignore) + { + bg->bg.solid.r = icl.r; + bg->bg.solid.g = icl.g; + bg->bg.solid.b = icl.b; + } + break; + case BG_BG1: + sscanf(s, "%4000s %4000s %d %d %d %d %d %d", s1, + s2, &i1, &i2, &i3, &i4, &i5, &i6); + if (!ignore) + { + if (bg1) + Efree(bg1); + bg1 = duplicate(s2); + } + else + { + if (bg->bg.file) + Efree(bg->bg.file); + if (bg->top.file) + Efree(bg->top.file); + bg->bg.file = duplicate(s2); + bg->bg.tile = i1; + bg->bg.keep_aspect = i2; + bg->bg.xjust = i3; + bg->bg.yjust = i4; + bg->bg.xperc = i5; + bg->bg.yperc = i6; + } + break; + case BG_BG2: + sscanf(s, "%4000s %4000s %d %d %d %d %d", s1, + s2, &j1, &j2, &j3, &j4, &j5); + if (!ignore) + { + if (bg2) + Efree(bg2); + bg2 = duplicate(s2); + } + else + { + bg->top.file = duplicate(s2); + bg->top.keep_aspect = j1; + bg->top.xjust = j2; + bg->top.yjust = j3; + bg->top.xperc = j4; + bg->top.yperc = j5; + } + break; + default: + break; + } + } + + if (name) + Efree(name); + if (bg1) + Efree(bg1); + if (bg2) + Efree(bg2); + + RecoverUserConfig(); + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading a Desktop block. Outcome is likely not good.\n"); + + return; +} + +void +Config_ECursor(FILE * ConfigFile) +{ + ImlibColor icl, icl2; + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int ii1; + char *file = NULL, *name = NULL; + ECursor *ec = NULL; + int fields; + + icl.r = 0; + icl.g = 0; + icl.b = 0; + icl2.r = 255; + icl2.g = 255; + icl2.b = 255; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + ii1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &ii1, s2); + + if (fields < 1) + ii1 = CONFIG_INVALID; + else if (ii1 == CONFIG_CLOSE) + { + if (fields != 1) + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + else if (ii1 != CONFIG_INVALID) + { + if (fields != 2) + { + Alert("CONFIG: missing required data in \"%s\"\n", s); + } + } + switch (ii1) + { + case CONFIG_CLOSE: + ec = CreateECursor(name, file, &icl, &icl2); + if (ec) + AddItem(ec, ec->name, 0, LIST_TYPE_ECURSOR); + if (name) + Efree(name); + if (file) + Efree(file); + return; + case CONFIG_CLASSNAME: + if (name) + Efree(name); + name = duplicate(s2); + break; + case CURS_BG_RGB: + sscanf(s, "%4000s %d %d %d", s2, &icl.r, &icl.g, &icl.b); + break; + case CURS_FG_RGB: + sscanf(s, "%4000s %d %d %d", s2, &icl2.r, &icl2.g, &icl2.b); + break; + case XBM_FILE: + file = duplicate(s2); + break; + default: + break; + } + } + if (name) + Efree(name); + if (file) + Efree(file); + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading a Desktop block. Outcome is likely not good.\n"); +} + +void +Config_Iconbox(FILE * ConfigFile) +{ + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + int fields; + + Alert("Easter Egg! Iconboxes aren't implemented yet.\n"); + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + i1 = CONFIG_INVALID; + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + Alert("CONFIG: missing required data in \"%s\"\n", s); + } + } + switch (i1) + { + case CONFIG_CLOSE: + return; + default: + break; + } + } + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading an Iconbox block. Outcome is likely not good.\n"); +} + +void +Config_Sound(FILE * ConfigFile) +{ + + /* This function loads various soundclasses and sets them to certain + * audio files. + */ + + SoundClass *sc; + char s[FILEPATH_LEN_MAX]; + char s1[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1, ret; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + ret = sscanf(s, "%4000s %4000s", s1, s2); + if (ret == 1) + { + i1 = atoi(s1); + if (i1 == CONFIG_CLOSE) + return; + } + else if (ret == 2) + { + sscanf(s, "%4000s %4000s", s1, s2); + sc = CreateSoundClass(s1, s2); + AddItem(sc, sc->name, 0, LIST_TYPE_SCLASS); + } + } + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading an Sound block. Outcome is likely not good.\n"); +} + +void +Config_ActionClass(FILE * ConfigFile) +{ + + /* This function will load an ActionClass off disk */ + + ActionClass *ac = NULL; + Action *a = NULL; + char s[FILEPATH_LEN_MAX]; + int i1; + char s2[FILEPATH_LEN_MAX]; + char s3[FILEPATH_LEN_MAX]; + char event = 0; + char anymod = 0; + int mod = 0; + int anybut = 0; + int but = 0; + int first = 1; + char anykey = 0; + char *key = NULL; + char *action_tooltipstring = NULL; + char global = 0; + int fields; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + i1 = CONFIG_INVALID; + else if (i1 == CONFIG_CLOSE || i1 == CONFIG_NEXT) + { + if (fields != 1) + { + RecoverUserConfig(); + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + RecoverUserConfig(); + Alert("CONFIG: missing required data in \"%s\"\n", s); + } + } + switch (i1) + { + case CONFIG_CLOSE: + if (key) + Efree(key); + return; + case CONFIG_CLASSNAME: + case ACLASS_NAME: + ac = RemoveItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_ACLASS); + if (!ac) + ac = RemoveItem(s2, 0, + LIST_FINDBY_NAME, LIST_TYPE_ACLASS_GLOBAL); + if (ac) + RemoveActionClass(ac); + ac = CreateAclass(s2); + break; + case CONFIG_TYPE: + case ACLASS_TYPE: + AddItem(ac, ac->name, 0, atoi(s2)); + if (atoi(s2) == LIST_TYPE_ACLASS_GLOBAL) + global = 1; + + break; + case CONFIG_MODIFIER: + case ACLASS_MODIFIER: + /* These are the defines that I have listed... + * These, therefore, are the ones that I am + * going to accept by default. + * REMINDER: add and'ing in future!!!! + * #define ShiftMask (1<<0) + * #define LockMask (1<<1) + * #define ControlMask (1<<2) + * #define Mod1Mask (1<<3) + * #define Mod2Mask (1<<4) + * #define Mod3Mask (1<<5) + * #define Mod4Mask (1<<6) + * #define Mod5Mask (1<<7) + */ + switch (atoi(s2)) + { + case MASK_NONE: + mod = 0; + break; + case MASK_SHIFT: + mod |= ShiftMask; + break; + case MASK_LOCK: + mod |= LockMask; + break; + case MASK_CTRL: + mod |= ControlMask; + break; + case MASK_MOD1: + mod |= Mod1Mask; + break; + case MASK_MOD2: + mod |= Mod2Mask; + break; + case MASK_MOD3: + mod |= Mod3Mask; + break; + case MASK_MOD4: + mod |= Mod4Mask; + break; + case MASK_MOD5: + mod |= Mod5Mask; + break; + case MASK_CTRL_ALT: + mod |= ControlMask | Mod1Mask; + break; + case MASK_SHIFT_ALT: + mod |= ShiftMask | Mod1Mask; + break; + case MASK_CTRL_SHIFT: + mod |= ShiftMask | ControlMask; + break; + case MASK_CTRL_SHIFT_ALT: + mod |= ShiftMask | ControlMask | Mod1Mask; + break; + case MASK_SHIFT_META4: + mod |= Mod4Mask | ShiftMask; + break; + case MASK_CTRL_META4: + mod |= Mod4Mask | ControlMask; + break; + case MASK_CTRL_META4_SHIFT: + mod |= Mod4Mask | ControlMask | ShiftMask; + break; + case MASK_SHIFT_META5: + mod |= Mod5Mask | ShiftMask; + break; + case MASK_CTRL_META5: + mod |= Mod5Mask | ControlMask; + break; + case MASK_CTRL_META5_SHIFT: + mod |= Mod5Mask | ControlMask | ShiftMask; + break; + case MASK_WINDOWS_SHIFT: + mod |= Mod2Mask | ShiftMask; + break; + case MASK_WINDOWS_CTRL: + mod |= Mod2Mask | ControlMask; + break; + case MASK_WINDOWS_ALT: + mod |= Mod2Mask | Mod1Mask; + break; + default: + break; + } + break; + case CONFIG_ANYMOD: + case ACLASS_ANYMOD: + anymod = atoi(s2); + break; + case CONFIG_ANYBUT: + case ACLASS_ANYBUT: + anybut = atoi(s2); + break; + case CONFIG_BUTTON: + case ACLASS_BUT: + but = atoi(s2); + break; + case CONFIG_ANYKEY: + case ACLASS_ANYKEY: + anykey = atoi(s2); + break; + case ACLASS_KEY: + if (key) + Efree(key); + key = duplicate(s2); + break; + case ACLASS_EVENT_TRIGGER: + event = atoi(s2); + break; + case CONFIG_NEXT: + mod = 0; + anymod = 0; + anybut = 0; + first = 1; + break; + case CONFIG_ACTION: + if (first) + { + a = CreateAction(event, anymod, + mod, anybut, but, anykey, key, action_tooltipstring); + /* the correct place to grab an action key */ + if (action_tooltipstring) + { + Efree(action_tooltipstring); + action_tooltipstring = NULL; + } + if (key) + Efree(key); + key = NULL; + if (global) + GrabActionKey(a); + AddAction(ac, a); + first = 0; + } + s3[0] = 0; + sscanf(s, "%*s %4000s %4000s", s2, s3); + if (!s3[0]) + AddToAction(a, atoi(s2), NULL); + else + AddToAction(a, atoi(s2), duplicate(atword(s, 3))); + break; + case CONFIG_ACTION_TOOLTIP: + if (action_tooltipstring) + { + action_tooltipstring = Erealloc(action_tooltipstring, + (strlen(action_tooltipstring) + + strlen(atword(s, 2)) + 2)); + action_tooltipstring = strcat(action_tooltipstring, "\n"); + action_tooltipstring = strcat(action_tooltipstring, atword(s, 2)); + } + else + action_tooltipstring = duplicate(atword(s, 2)); + break; + case CONFIG_TOOLTIP: + if (ac->tooltipstring) + { + ac->tooltipstring = Erealloc(ac->tooltipstring, + (strlen(ac->tooltipstring) + + strlen(atword(s, 2)) + 2)); + ac->tooltipstring = strcat(ac->tooltipstring, "\n"); + ac->tooltipstring = strcat(ac->tooltipstring, atword(s, 2)); + } + else + ac->tooltipstring = duplicate(atword(s, 2)); + break; + default: + RecoverUserConfig(); + Alert("Warning: unable to determine what to do with\n" + "the following text in the middle of current" + " ActionClass definition:\n" + "%s\nWill ignore and continue...\n", s); + break; + } + } + if (key) + Efree(key); + if (ac) + RemoveActionClass(ac); + if (action_tooltipstring) + Efree(action_tooltipstring); + RecoverUserConfig(); + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading an Action Class block. Outcome is likely not good.\n"); +} + +void +Config_ImageClass(FILE * ConfigFile) +{ + + /* This function will load an ImageClass off disk */ + + char s[FILEPATH_LEN_MAX]; + char s1[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + ImageClass *ic = 0; + ImageState *ICToRead = 0; + ColorModifierClass *cm = 0; + int fields;; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + i1 = CONFIG_INVALID; + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + Alert("CONFIG: missing required data in \"%s\"\n", s); + } + } + switch (i1) + { + case CONFIG_CLOSE: + IclassPopulate(ic); + AddItem(ic, ic->name, 0, LIST_TYPE_ICLASS); + return; + case ICLASS_LRTB: + { + char s3[FILEPATH_LEN_MAX]; + char s4[FILEPATH_LEN_MAX]; + char s5[FILEPATH_LEN_MAX]; + + ICToRead->border = Emalloc(sizeof(ImlibBorder)); + + sscanf(s, "%4000s %4000s %4000s %4000s %4000s", + s1, s2, s3, s4, s5); + ICToRead->border->left = atoi(s2); + ICToRead->border->right = atoi(s3); + ICToRead->border->top = atoi(s4); + ICToRead->border->bottom = atoi(s5); + } + break; + case ICLASS_FILLRULE: + ICToRead->pixmapfillstyle = atoi(s2); + break; + case CONFIG_INHERIT: + { + ImageClass *ICToInherit; + + ICToInherit = FindItem(s2, 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + ic->norm = ICToInherit->norm; + ic->active = ICToInherit->active; + ic->sticky = ICToInherit->sticky; + ic->sticky_active = ICToInherit->sticky_active; + ic->padding = ICToInherit->padding; + ic->colmod = ICToInherit->colmod; + ic->external = ICToInherit->external; + } + break; + case CONFIG_COLORMOD: + case ICLASS_COLORMOD: + cm = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_COLORMODIFIER); + if (cm) + { + if (ICToRead) + { + ICToRead->colmod = cm; + } + else + { + ic->colmod = cm; + } + cm->ref_count++; + } + break; + case ICLASS_PADDING: + { + char s3[FILEPATH_LEN_MAX]; + char s4[FILEPATH_LEN_MAX]; + char s5[FILEPATH_LEN_MAX]; + + sscanf(s, "%4000s %4000s %4000s %4000s %4000s", + s1, s2, s3, s4, s5); + ic->padding.left = atoi(s2); + ic->padding.right = atoi(s3); + ic->padding.top = atoi(s4); + ic->padding.bottom = atoi(s5); + } + break; + case CONFIG_CLASSNAME: + case ICLASS_NAME: + ic = CreateIclass(); + ic->name = duplicate(s2); + break; + case CONFIG_DESKTOP: + /* don't ask... --mandrake */ + case ICLASS_NORMAL: + ic->norm.normal = CreateImageState(); + ic->norm.normal->im_file = duplicate(s2); + ICToRead = ic->norm.normal; + break; + case ICLASS_CLICKED: + ic->norm.clicked = CreateImageState(); + ic->norm.clicked->im_file = duplicate(s2); + ICToRead = ic->norm.clicked; + break; + case ICLASS_HILITED: + ic->norm.hilited = CreateImageState(); + ic->norm.hilited->im_file = duplicate(s2); + ICToRead = ic->norm.hilited; + break; + case ICLASS_DISABLED: + ic->norm.disabled = CreateImageState(); + ic->norm.disabled->im_file = duplicate(s2); + ICToRead = ic->norm.disabled; + break; + case ICLASS_STICKY_NORMAL: + ic->sticky.normal = CreateImageState(); + ic->sticky.normal->im_file = duplicate(s2); + ICToRead = ic->sticky.normal; + break; + case ICLASS_STICKY_CLICKED: + ic->sticky.clicked = CreateImageState(); + ic->sticky.clicked->im_file = duplicate(s2); + ICToRead = ic->sticky.clicked; + break; + case ICLASS_STICKY_HILITED: + ic->sticky.hilited = CreateImageState(); + ic->sticky.hilited->im_file = duplicate(s2); + ICToRead = ic->sticky.hilited; + break; + case ICLASS_STICKY_DISABLED: + ic->sticky.disabled = CreateImageState(); + ic->sticky.disabled->im_file = duplicate(s2); + ICToRead = ic->sticky.disabled; + break; + case ICLASS_ACTIVE_NORMAL: + ic->active.normal = CreateImageState(); + ic->active.normal->im_file = duplicate(s2); + ICToRead = ic->active.normal; + break; + case ICLASS_ACTIVE_CLICKED: + ic->active.clicked = CreateImageState(); + ic->active.clicked->im_file = duplicate(s2); + ICToRead = ic->active.clicked; + break; + case ICLASS_ACTIVE_HILITED: + ic->active.hilited = CreateImageState(); + ic->active.hilited->im_file = duplicate(s2); + ICToRead = ic->active.hilited; + break; + case ICLASS_ACTIVE_DISABLED: + ic->active.disabled = CreateImageState(); + ic->active.disabled->im_file = duplicate(s2); + ICToRead = ic->active.disabled; + break; + case ICLASS_STICKY_ACTIVE_NORMAL: + ic->sticky_active.normal = CreateImageState(); + ic->sticky_active.normal->im_file = duplicate(s2); + ICToRead = ic->sticky_active.normal; + break; + case ICLASS_STICKY_ACTIVE_CLICKED: + ic->sticky_active.clicked = CreateImageState(); + ic->sticky_active.clicked->im_file = duplicate(s2); + ICToRead = ic->sticky_active.clicked; + break; + case ICLASS_STICKY_ACTIVE_HILITED: + ic->sticky_active.hilited = CreateImageState(); + ic->sticky_active.hilited->im_file = duplicate(s2); + ICToRead = ic->sticky_active.hilited; + break; + case ICLASS_STICKY_ACTIVE_DISABLED: + ic->sticky_active.disabled = CreateImageState(); + ic->sticky_active.disabled->im_file = duplicate(s2); + ICToRead = ic->sticky_active.disabled; + break; + default: + Alert("Warning: unable to determine what to do with\n" + "the following text in the middle of current " + "ImageClass definition:\n" + "%s\nWill ignore and continue...\n", s); + break; + } + } + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading an ImageClass block. Outcome is likely not good.\n"); +} + +void +Config_ColorModifier(FILE * ConfigFile) +{ + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + char *name = 0; + char *params = 0; + char *current_param = 0; + unsigned char *rx = 0; + unsigned char *ry = 0; + unsigned char *gx = 0; + unsigned char *gy = 0; + unsigned char *bx = 0; + unsigned char *by = 0; + int i = 0, tx, ty; + int rnum = 0, gnum = 0, bnum = 0; + ColorModifierClass *cm; + int fields; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + { + i1 = CONFIG_INVALID; + } + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + { + RecoverUserConfig(); + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + RecoverUserConfig(); + Alert("CONFIG: missing required data in \"%s\"\n", s); + } + } + switch (i1) + { + case CONFIG_CLOSE: + cm = (ColorModifierClass *) FindItem(name, 0, LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + if (cm) + { + ModifyCMClass(name, rnum, rx, ry, gnum, + gx, gy, bnum, bx, by); + } + else + { + cm = CreateCMClass(name, rnum, rx, ry, + gnum, gx, gy, bnum, bx, by); + AddItem(cm, cm->name, 0, LIST_TYPE_COLORMODIFIER); + } + + if (name) + Efree(name); + if (rx) + Efree(rx); + if (ry) + Efree(ry); + if (gx) + Efree(gx); + if (gy) + Efree(gy); + if (bx) + Efree(bx); + if (by) + Efree(by); + + return; + case CONFIG_CLASSNAME: + name = duplicate(s2); + break; + case COLORMOD_RED: + params = atword(s, 2); + current_param = params; + if (!current_param) + { + + if (name) + Efree(name); + if (rx) + Efree(rx); + if (ry) + Efree(ry); + if (gx) + Efree(gx); + if (gy) + Efree(gy); + if (bx) + Efree(bx); + if (by) + Efree(by); + + return; + } + do + { + while (*current_param == ' ') + current_param++; + if (rx) + { + rx = Erealloc(rx, sizeof(unsigned char) * (i + 1)); + ry = Erealloc(ry, sizeof(unsigned char) * (i + 1)); + } + else + { + rx = Emalloc(sizeof(unsigned char)); + ry = Emalloc(sizeof(unsigned char)); + } + if (strstr(current_param, ",")) + *(strstr(current_param, ",")) = ' '; + sscanf(current_param, "%i %i", &tx, &ty); + rx[i] = (unsigned char)tx; + ry[i++] = (unsigned char)ty; + current_param = strstr(current_param, " ") + 1; + current_param = strstr(current_param, " "); + } + while ((current_param) && + (current_param = strstr(current_param, " ")) && + (current_param)); + rnum = i; + break; + case COLORMOD_GREEN: + params = atword(s, 2); + current_param = params; + if (!current_param) + { + + if (name) + Efree(name); + if (rx) + Efree(rx); + if (ry) + Efree(ry); + if (gx) + Efree(gx); + if (gy) + Efree(gy); + if (bx) + Efree(bx); + if (by) + Efree(by); + + return; + } + do + { + while (*current_param == ' ') + current_param++; + if (gx) + { + gx = Erealloc(gx, sizeof(unsigned char) * (i + 1)); + gy = Erealloc(gy, sizeof(unsigned char) * (i + 1)); + } + else + { + gx = Emalloc(sizeof(unsigned char)); + gy = Emalloc(sizeof(unsigned char)); + } + if (strstr(current_param, ",")) + *(strstr(current_param, ",")) = ' '; + sscanf(current_param, "%i %i", &tx, &ty); + gx[i] = (unsigned char)tx; + gy[i++] = (unsigned char)ty; + current_param = strstr(current_param, " ") + 1; + current_param = strstr(current_param, " "); + } + while ((current_param) && + (current_param = strstr(current_param, " ")) && + (current_param)); + gnum = i; + break; + case COLORMOD_BLUE: + params = atword(s, 2); + current_param = params; + if (!current_param) + { + + if (name) + Efree(name); + if (rx) + Efree(rx); + if (ry) + Efree(ry); + if (gx) + Efree(gx); + if (gy) + Efree(gy); + if (bx) + Efree(bx); + if (by) + Efree(by); + + return; + } + do + { + while (*current_param == ' ') + current_param++; + if (bx) + { + bx = Erealloc(bx, sizeof(unsigned char) * (i + 1)); + by = Erealloc(by, sizeof(unsigned char) * (i + 1)); + } + else + { + bx = Emalloc(sizeof(unsigned char)); + by = Emalloc(sizeof(unsigned char)); + } + if (strstr(current_param, ",")) + *(strstr(current_param, ",")) = ' '; + sscanf(current_param, "%i %i", &tx, &ty); + bx[i] = (unsigned char)tx; + by[i++] = (unsigned char)ty; + current_param = strstr(current_param, " ") + 1; + current_param = strstr(current_param, " "); + } + while ((current_param) && + (current_param = strstr(current_param, " ")) && + (current_param)); + bnum = i; + break; + default: + RecoverUserConfig(); + Alert("Warning: unable to determine what to do with\n" + "the following text in the middle of current " + " ColorModifier definition:\n" + "%s\nWill ignore and continue...\n", s); + break; + } + } + + if (name) + Efree(name); + if (rx) + Efree(rx); + if (ry) + Efree(ry); + if (gx) + Efree(gx); + if (gy) + Efree(gy); + if (bx) + Efree(bx); + if (by) + Efree(by); + + RecoverUserConfig(); + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading an ColorModifier block.\n" + "Outcome is likely not good.\n"); + + return; +} + +void +Config_ToolTip(FILE * ConfigFile) +{ + + /* This function will load tooltip arrangement data off of + * the config file + */ + + ToolTip *tt; + char *name = 0; + ImageClass *drawiclass = 0; + ImageClass *bubble1 = 0, *bubble2 = 0, *bubble3 = 0, *bubble4 = 0; + TextClass *tclass = 0; + ImageClass *tooltiphelppic = 0; + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + int distance = 0; + int fields; + + tt = NULL; + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + i1 = CONFIG_INVALID; + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + Alert("CONFIG: missing required data in \"%s\"\n", s); + } + } + switch (i1) + { + case CONFIG_CLOSE: + if ((drawiclass) && (bubble1) && (bubble2) && (bubble3) && + (bubble4) && (tclass) && (name)) + tt = CreateToolTip(name, drawiclass, bubble1, + bubble2, bubble3, + bubble4, tclass, distance, tooltiphelppic); + if (name) + Efree(name); + if (tt) + AddItem(tt, tt->name, 0, LIST_TYPE_TOOLTIP); + return; + case CONFIG_CLASSNAME: + name = duplicate(s2); + break; + case TOOLTIP_DRAWICLASS: + case CONFIG_IMAGECLASS: + drawiclass = FindItem(s2, 0, LIST_FINDBY_NAME, + LIST_TYPE_ICLASS); + break; + case TOOLTIP_BUBBLE1: + bubble1 = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + break; + case TOOLTIP_BUBBLE2: + bubble2 = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + break; + case TOOLTIP_BUBBLE3: + bubble3 = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + break; + case TOOLTIP_BUBBLE4: + bubble4 = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + break; + case CONFIG_TEXT: + tclass = FindItem(s2, 0, LIST_FINDBY_NAME, LIST_TYPE_TCLASS); + break; + case TOOLTIP_DISTANCE: + distance = atoi(s2); + break; + case TOOLTIP_HELP_PIC: + tooltiphelppic = FindItem(s2, 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + break; + default: + Alert("Warning: unable to determine what to do with\n" + "the following text in the middle of current " + "ToolTip definition:\n" + "%s\nWill ignore and continue...\n", s); + break; + } + } + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading an ToolTip block. Outcome is likely not good.\n"); + +} + +void +Config_FX(FILE * ConfigFile) +{ + + /* This function loads various fx out of config file */ + + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + int fields; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i", &i1); + + if (fields < 1) + { + word(s, 1, s2); + FX_Start(s2); + } + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + { + RecoverUserConfig(); + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + return; + } + } + RecoverUserConfig(); + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading an FX block. Outcome is likely not good.\n"); +} + +void +Config_Extras(FILE * ConfigFile) +{ + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + int fields; + Iconbox **ib; + int i, num; + + ib = ListAllIconboxes(&num); + if (ib) + { + for (i = 0; i < num; i++) + FreeIconbox(ib[i]); + Efree(ib); + } + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + + fields = sscanf(s, "%i %4000s", &i1, s2); + switch (i1) + { + case CONFIG_IBOX: + Config_Ibox(ConfigFile); + break; + case CONFIG_CLOSE: + return; + break; + default: + Alert("Warning: unable to determine what to do with\n" + "the following text in the middle of current " + "Extras definition:\n" + "%s\nWill ignore and continue...\n", s); + break; + } + } + RecoverUserConfig(); + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading an Extras block. Outcome is likely not good.\n"); +} + +void +Config_Ibox(FILE * ConfigFile) +{ + + /* This function loads various fx out of config file */ + + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + int fields; + Iconbox *ib = NULL; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + i1 = CONFIG_INVALID; + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + switch (i1) + { + case CONFIG_CLASSNAME: /* __NAME %s */ + ib = CreateIconbox(s2); + break; + case TEXT_ORIENTATION: /* __ORIENTATION [ __HORIZONTAL | __VERTICAL ] */ + if (ib) + ib->orientation = (char)atoi(s2); + break; + case CONFIG_TRANSPARENCY: /* __TRANSPARENCY [ __ON | __OFF ] */ + if (ib) + ib->nobg = (char)atoi(s2); + break; + case CONFIG_SHOW_NAMES: /* __SHOW_NAMES [ __ON | __OFF ] */ + if (ib) + ib->shownames = (char)atoi(s2); + break; + case CONFIG_ICON_SIZE: /* __ICON_SIZE %i */ + if (ib) + ib->iconsize = (int)atoi(s2); + break; + case CONFIG_ICON_MODE: /* __ICON_MODE [ 0 | 1 | 2 | 3 | 4 ] */ + if (ib) + ib->icon_mode = (int)atoi(s2); + break; + case CONFIG_SCROLLBAR_SIDE: /* __SCROLLBAR_SIDE [ __BAR_LEFT/__BAR_TOP | __BAR_RIGHT/__BAR_BOTTOM ] */ + if (ib) + ib->scrollbar_side = (char)atoi(s2); + break; + case CONFIG_SCROLLBAR_ARROWS: /* __SCROLLBAR_ARROWS [ __START | __BOTH | __FINISH | __NEITHER ] */ + if (ib) + ib->arrow_side = (char)atoi(s2); + break; + case CONFIG_AUTOMATIC_RESIZE: /* __AUTOMATIC_RESIZE [ __ON | __OFF ] */ + if (ib) + ib->auto_resize = (char)atoi(s2); + break; + case CONFIG_SHOW_ICON_BASE: /* __SHOW_ICON_BASE [ __ON | __OFF ] */ + if (ib) + ib->draw_icon_base = (char)atoi(s2); + break; + case CONFIG_SCROLLBAR_AUTOHIDE: /* __SCROLLBAR_AUTOHIDE [ __ON | __OFF ] */ + if (ib) + ib->scrollbar_hide = (char)atoi(s2); + break; + case CONFIG_CLOSE: + return; + break; + default: + Alert("Warning: unable to determine what to do with\n" + "the following text in the middle of current " + "Iconbox definition:\n" + "%s\nWill ignore and continue...\n", s); + break; + } + } + RecoverUserConfig(); + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading an Iconbox block. Outcome is likely not good.\n"); +} + +void +Config_WindowMatch(FILE * ConfigFile) +{ + + /* This function will load a windowmatch out of configuration. + * windowmatches can be used to generically perform various actions + * upon a window on startup. + */ + + WindowMatch *bm = 0; + char s[FILEPATH_LEN_MAX]; + char s2[FILEPATH_LEN_MAX]; + int i1; + int fields; + + while (GetLine(s, sizeof(s), ConfigFile)) + { + s2[0] = 0; + i1 = CONFIG_INVALID; + fields = sscanf(s, "%i %4000s", &i1, s2); + + if (fields < 1) + i1 = CONFIG_INVALID; + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + Alert("CONFIG: missing required data in \"%s\"\n", s); + } + } + switch (i1) + { + case CONFIG_CLOSE: + AddItem(bm, bm->name, 0, LIST_TYPE_WINDOWMATCH); + return; + case CONFIG_CLASSNAME: + bm = CreateWindowMatch(s2); + break; + case CONFIG_BORDER: + case WINDOWMATCH_USEBORDER: + bm->border = FindItem(s2, 0, + LIST_FINDBY_NAME, LIST_TYPE_BORDER); + if (bm->border) + bm->border->ref_count++; + break; + case WINDOWMATCH_MATCHNAME: + bm->win_name = duplicate(atword(s, 2)); + break; + case WINDOWMATCH_MATCHCLASS: + bm->win_class = duplicate(atword(s, 2)); + break; + case WINDOWMATCH_MATCHTITLE: + bm->win_title = duplicate(atword(s, 2)); + break; + case WINDOWMATCH_DESKTOP: + case CONFIG_DESKTOP: + bm->desk = atoi(s2); + break; + case WINDOWMATCH_ICON: + case CONFIG_ICONBOX: + bm->icon = FindItem(s2, 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (bm->icon) + bm->icon->ref_count++; + break; + case WINDOWMATCH_WIDTH: + { + char s3[FILEPATH_LEN_MAX]; + + sscanf(s, "%*s %4000s %4000s", s2, s3); + bm->width.min = atoi(s2); + bm->width.max = atoi(s3); + } + break; + case WINDOWMATCH_HEIGHT: + { + char s3[FILEPATH_LEN_MAX]; + + sscanf(s, "%*s %4000s %4000s", s2, s3); + bm->height.min = atoi(s2); + bm->height.max = atoi(s3); + } + break; + case WINDOWMATCH_TRANSIENT: + bm->transient = atoi(s2); + break; + case WINDOWMATCH_NO_RESIZE_H: + bm->no_resize_h = atoi(s2); + break; + case WINDOWMATCH_NO_RESIZE_V: + bm->no_resize_v = atoi(s2); + break; + case WINDOWMATCH_SHAPED: + bm->shaped = atoi(s2); + break; + case WINDOWMATCH_MAKESTICKY: + bm->make_sticky = atoi(s2); + break; + default: + Alert("Warning: unable to determine what to do with\n" + "the following text in the middle of current " + "WindowMatch definition:\n" + "%s\nWill ignore and continue...\n", s); + break; + } + } + Alert("Warning: Configuration appears to have ended before we were\n" + "Done loading an WindowMatch block. Outcome is likely not good.\n"); +} + +int +IsWhitespace(const char *s) +{ + int i = 0; + + while (s[i]) + { + if ((s[i] != ' ') && (s[i] != '\n') && (s[i] != '\t')) + return 0; + i++; + } + return 1; +} + +static char *cfg_tmpfile = NULL; + +FILE * +OpenConfigFileForReading(char *path, char preprocess) +{ + /* This function will open a file at location path for */ + /* reading. If the file is executable it will execute the file */ + /* All output is passed through epp for preprocessing however. */ + FILE *fpin /*, *fpout */ ; + char execline[FILEPATH_LEN_MAX]; + char *epp_path = ENLIGHTENMENT_BIN "/epp"; + + EDBUG(5, "OpenConfigFileForReading"); + if (!path) + EDBUG_RETURN(0); +/* FIXME: DISABLED - seems to be giving lots of people problems + * if ((canexec(path)) && + * ((owner(path) == (int)getuid()) || (owner(path) == owner(command)) || + * (owner(path) == 0))) + * { + * { + * if ((fpin = popen(path, "r")) == NULL) + * Alert("The config file:\n" + * "%s\n" + * "Is executable but an error occurred whilst attempting\n" + * "to execute it and read its output.\n" + * "Enlightenment will skip reading this file.\n", path); + * else + * { + * Esnprintf(newfile, sizeof(newfile), + * "/tmp/e_temp_theme_%i-%i-%i-%i-%i", + * rand(), time(NULL), getpid(), getppid()); + * if ((fpout = fopen(newfile, "w")) == NULL) + * Alert("Enlightenment is attempting to write to a temporary file:\n" + * "%s\n" + * "There was an error trying to write to it.\n" + * "Enlightenment will not read this file now.\n", newfile); + * else + * { + * while (GetLine(line, FILEPATH_LEN_MAX, fpin) != NULL) + * { + * if (fputs(line, fpout) == EOF) + * Alert("Enlightenment is attempting to write to a temporary file:\n" + * "%s\n" + * "There was an error trying to write to it.\n" + * "Enlightenment will not read this file now.\n", newfile); + * } + * } + * cfg_tmpfile = duplicate(newfile); + * pclose(fpin); + * fclose(fpout); + * path = newfile; + * } + * } + * } + */ + if (preprocess) + { + char *def_home, *def_user, *def_shell, *s; + int i = 0; + static char have_epp = 0; + + if ((!have_epp) && (!(isfile(epp_path)) && (canexec(epp_path)))) + { + Alert("Help! Cannot find epp!\n" + "Enlightenment is looking for epp here:\n" + "%s\n" + "This is a FATAL ERROR.\n" + "This is probaly due to either the program not existing or\n" + "it not being able to be executed by you.\n", + epp_path); + doExit("error"); + } + else + have_epp = 1; + + def_home = homedir(getuid()); + def_user = username(getuid()); + def_shell = usershell(getuid()); + + s = duplicate(path); + while (s[i]) + { + if (s[i] == '/') + s[i] = '.'; + i++; + } + Esnprintf(execline, sizeof(execline), + "%s " + "-P " + "-nostdinc " + "-undef " + "-include %s/config/definitions " + "-I%s/config " + "-D ENLIGHTENMENT_VERSION=%s " + "-D ENLIGHTENMENT_ROOT=%s " + "-D ENLIGHTENMENT_BIN=%s " + "-D ENLIGHTENMENT_THEME=%s " + "-D SCREEN_RESOLUTION_%ix%i=1 " + "-D SCREEN_WIDTH_%i=1 " + "-D SCREEN_HEIGHT_%i=1 " + "-D SCREEN_DEPTH_%i=1 " + "-D USER_NAME=%s " + "-D HOME_DIR=%s " + "-D USER_SHELL=%s " + "-D ENLIGHTENMENT_VERSION_015=1 " + "%s %s/.enlightenment/cached/cfg/%s.preparsed", + epp_path, ENLIGHTENMENT_ROOT, ENLIGHTENMENT_ROOT, + ENLIGHTENMENT_VERSION, ENLIGHTENMENT_ROOT, ENLIGHTENMENT_BIN, + themepath, + root.w, root.h, root.w, root.h, root.depth, + def_user, def_home, def_shell, + path, def_home, s); + system(execline); + Esnprintf(execline, sizeof(execline), + "%s/.enlightenment/cached/cfg/%s.preparsed", + def_home, s); + fpin = fopen(execline, "r"); + if (s) + Efree(s); + if (def_user) + Efree(def_user); + if (def_home) + Efree(def_home); + if (def_shell) + Efree(def_shell); + EDBUG_RETURN(fpin); + } + else + { + fpin = fopen(path, "r"); + EDBUG_RETURN(fpin); + } + EDBUG_RETURN(0); +} + +int +LoadConfigFile(char *f) +{ + FILE *ConfigFile; + char s[FILEPATH_LEN_MAX], s2[FILEPATH_LEN_MAX], *file, + *ppfile; + int i; + char notheme = 0; + + EDBUG(5, "LoadConfigFile"); + + Esnprintf(s, sizeof(s), "%s", f); + file = FindFile(s); + if (!file) + EDBUG_RETURN(0); + + strcpy(s2, file); + i = 0; + + while (s2[i]) + { + if (s2[i] == '/') + s2[i] = '.'; + i++; + } + + Esnprintf(s, sizeof(s), "cached/cfg/%s.preparsed", s2); + + if (strstr(f, "control.cfg")) + { + notheme = 1; + } + else if (strstr(f, "menus.cfg")) + { + notheme = 1; + } + else if (strstr(f, "keybindings.cfg")) + { + notheme = 1; + } + if (notheme) + { + ppfile = FindNoThemeFile(s); + } + else + { + ppfile = FindFile(s); + } + + if (!ppfile) + { + if (notheme) + file = FindNoThemeFile(f); + else + file = FindFile(f); + } + if ((ppfile) && (exists(ppfile)) && (moddate(file) < moddate(ppfile))) + { + ConfigFile = OpenConfigFileForReading(ppfile, 0); + } + else + ConfigFile = OpenConfigFileForReading(file, 1); + if (ppfile) + Efree(ppfile); + if (file) + Efree(file); + return LoadOpenConfigFile(ConfigFile); +} + +/* Split the process of finding the file from the process of loading it */ +int +LoadOpenConfigFile(FILE * ConfigFile) +{ + int i1, i2, fields; + char s[FILEPATH_LEN_MAX]; + int e_cfg_ver = 0; + int min_e_cfg_ver = 0; + + if (!ConfigFile) + { + EDBUG_RETURN(0); + } + while (GetLine(s, sizeof(s), ConfigFile)) + { + if (IsWhitespace(s)) + continue; + i1 = i2 = CONFIG_INVALID; + fields = sscanf(s, "%i %i", &i1, &i2); + + if (fields < 1) + i1 = CONFIG_INVALID; + else if (i1 == CONFIG_VERSION) + { + if (fields == 2) + e_cfg_ver = i2; + } + else if (i1 == CONFIG_CLOSE) + { + if (fields != 1) + { + RecoverUserConfig(); + Alert("CONFIG: ignoring extra data in \"%s\"\n", s); + } + } + else if (i1 != CONFIG_INVALID) + { + if (fields != 2) + { + RecoverUserConfig(); + Alert("CONFIG: missing required data in \"%s\"\n", s); + } + } + if (i2 == CONFIG_OPEN) + { + if (e_cfg_ver != min_e_cfg_ver) + { + if (!is_autosave) + { + ASSIGN_ALERT("Theme versioning ERROR", + "Restart with Defaults", + " ", + "Abort and Exit"); + Alert("ERROR:\n" + "\n" + "The configuration for the theme you are " + "running is\n" + "incompatible. It's config revision is %i. " + "It needs to\n" + "be marked as being revision %i\n" + "\n" + "Please contact the theme author or " + "maintainer and\n" + "inform them that in order for their theme " + "to function\n" + "with this version of Enlightenment, they " + "have to\n" + "update it to the current settings, and " + "then match\n" + "the revision number.\n" + "\n" + "If the theme revision is higher than " + "Enlightenment's\n" + "it may be that you haven't upgraded " + "Enlightenment for\n" + "a while and this theme takes advantages of new\n" + "features in Enlightenment in new versions.\n", + e_cfg_ver, min_e_cfg_ver); + RESET_ALERT; + doExit("restart_theme DEFAULT"); + } + else + { + mode.autosave = 0; + ASSIGN_ALERT("User Config Version ERROR", + "Restart with Defaults", + " ", + "Abort and Exit"); + Alert("ERROR:\n" + "\n" + "The settings you are using are " + "incompatible with\n" + "this version of Enlightenment.\n" + "It's revision is %i It needs to be revision " + "%i to\n" + "be compatible.\n" + "\n" + "If you just upgraded to a new version of E\n" + "Restarting with Defaults will remove your current\n" + "user preferences and start cleanly with system\n" + "defaults. You can then modify your " + "configuration to\n" + "your liking again safely.\n", + e_cfg_ver, min_e_cfg_ver); + RESET_ALERT; + doExit("restart"); + } + } + else + { + switch (i1) + { + case CONFIG_CLOSE: + if (pclose(ConfigFile) == -1) + fclose(ConfigFile); + EDBUG_RETURN(1); + case CONFIG_IMAGECLASS: + Config_ImageClass(ConfigFile); + break; + case CONFIG_FX: + Config_FX(ConfigFile); + break; + case CONFIG_EXTRAS: + Config_Extras(ConfigFile); + break; + case CONFIG_TOOLTIP: + Config_ToolTip(ConfigFile); + break; + case CONFIG_TEXT: + Config_Text(ConfigFile); + break; + case CONFIG_MENU: + Config_Menu(ConfigFile); + break; + case MENU_STYLE: + Config_MenuStyle(ConfigFile); + break; + case CONFIG_BORDER: + Config_Border(ConfigFile); + break; + case CONFIG_BUTTON: + Config_Button(ConfigFile); + break; + case CONFIG_DESKTOP: + Config_Desktop(ConfigFile); + break; + case CONFIG_ICONBOX: + Config_Iconbox(ConfigFile); + break; + case CONFIG_CONTROL: + Config_Control(ConfigFile); + break; + case CONFIG_WINDOWMATCH: + Config_WindowMatch(ConfigFile); + break; + case CONFIG_COLORMOD: + Config_ColorModifier(ConfigFile); + break; + case CONFIG_SOUND: + Config_Sound(ConfigFile); + break; + case CONFIG_ACTIONCLASS: + Config_ActionClass(ConfigFile); + break; + case CONFIG_SLIDEOUT: + Config_Slideout(ConfigFile); + break; + case CONFIG_CURSOR: + Config_ECursor(ConfigFile); + break; + default: + break; + } + } + } + } + fclose(ConfigFile); + if (cfg_tmpfile) + { + rm(cfg_tmpfile); + Efree(cfg_tmpfile); + cfg_tmpfile = NULL; + } + EDBUG_RETURN(1); +} + +char * +FindFile(char *file) +{ + char s[FILEPATH_LEN_MAX]; + char *home; + + EDBUG(6, "FindFile"); + /* if absolute path - and file exists - return it */ + if (file[0] == '/') + { + if (isfile(file)) + EDBUG_RETURN(duplicate(file)); + } + /* look in ~/.enlightenment first */ + home = homedir(getuid()); + Esnprintf(s, sizeof(s), "%s/.enlightenment/%s", home, file); + Efree(home); + if (isfile(s)) + EDBUG_RETURN(duplicate(s)); + /* look in theme dir */ + Esnprintf(s, sizeof(s), "%s/%s", themepath, file); + if (isfile(s)) + EDBUG_RETURN(duplicate(s)); + /* look in system config dir */ + Esnprintf(s, sizeof(s), "%s/config/%s", ENLIGHTENMENT_ROOT, file); + if (isfile(s)) + EDBUG_RETURN(duplicate(s)); + /* not found.... NULL */ + EDBUG_RETURN(NULL); +} + +char * +FindNoThemeFile(char *file) +{ + char s[FILEPATH_LEN_MAX]; + char *home; + + EDBUG(6, "FindFile"); + /* if absolute path - and file exists - return it */ + if (file[0] == '/') + { + if (isfile(file)) + EDBUG_RETURN(duplicate(file)); + } + /* look in ~/.enlightenment first */ + home = homedir(getuid()); + Esnprintf(s, sizeof(s), "%s/.enlightenment/%s", home, file); + Efree(home); + if (isfile(s)) + EDBUG_RETURN(duplicate(s)); + /* look in system config dir */ + Esnprintf(s, sizeof(s), "%s/config/%s", ENLIGHTENMENT_ROOT, file); + if (isfile(s)) + EDBUG_RETURN(duplicate(s)); + /* not found.... NULL */ + EDBUG_RETURN(NULL); +} + +int +LoadEConfig(char *themelocation) +{ + char s[FILEPATH_LEN_MAX], ss[FILEPATH_LEN_MAX]; + char *theme, *home; + FILE *f; + + EDBUG(5, "LoadEConfig"); + home = NULL; + mustdel = 0; + + home = homedir(getuid()); + Esnprintf(s, sizeof(s), "%s/.enlightenment/", home); + Fnlib_add_dir(fd, s); + Esnprintf(s, sizeof(s), "%s/config/", ENLIGHTENMENT_ROOT); + Fnlib_add_dir(fd, s); + /* save the current theme */ + if ((themelocation) && (themelocation[0] != 0)) + { + Etmp(s); + f = fopen(s, "w"); + if (f) + { + fprintf(f, "%s\n", themelocation); + fclose(f); + } + Esnprintf(ss, sizeof(ss), "%s/.enlightenment/user_theme.cfg", home); + rm(ss); + mv(s, ss); + if (!isfile(ss)) + Alert("WARNING!\n" + "There was an error writing the file:\n" + "%s\n" + "This may be due to lack of disk space, quota or\n" + "filesystem permissions.\n", + ss + ); + } + strcpy(themename, themelocation); + theme = FindTheme(themelocation); + if (!theme) + { + Alert("Enlightenment has just experienced some major problems in\n" + "attempting to load the theme you specified or the default\n" + "configuration directory:\n" + "%s/config/\n" + "This will prevent Enlightenment from loading any " + "configuration\n" + "files at all.\n" + "Since this couldn't be found Enlightenment is probably not\n" + "going to find any configuration files anywhere on your\n" + "system, and so it will have almost no configuration loaded\n" + "when it starts up. This is most likely the sign of a bad\n" + "installation of Enlightenment if this directory is missing.\n" + "The likely causes are that the package was improperly built,\n" + "if a binary package, or 'make install' hasn't been typed\n" + "or during the installation the directory above was not\n" + "able to be copied over for installation perhaps due to\n" + "permissions or lack of disk space. It also could be that the\n" + "config directory has been inadvertently deleted since\n" + "installation.\n" + "This is a serious problem and should be rectified immediately\n" + "Please contact your system administrator or package " + "maintainer.\n" + "If you are the administrator of your own system please\n" + "consult the documentation that came with Enlightenment for\n" + "addional information.\n", ENLIGHTENMENT_ROOT); + if (home) + Efree(home); + EDBUG_RETURN(0); + } + strcpy(themepath, theme); + Esnprintf(s, sizeof(s), "%s/", theme); + Fnlib_add_dir(fd, s); + { + Progressbar *p = NULL; + int i; + char *config_files[] = + { + "init.cfg", + "control.cfg", + "textclasses.cfg", + "colormodifiers.cfg", + "imageclasses.cfg", + "sound.cfg", + "desktops.cfg", + "actionclasses.cfg", + "cursors.cfg", + "buttons.cfg", + "slideouts.cfg", + "borders.cfg", + "windowmatches.cfg", + "tooltips.cfg", + "menustyles.cfg", + "keybindings.cfg", + "...e_autosave.cfg", + "menus.cfg" + }; + + for (i = 0; i < (int)(sizeof(config_files) / sizeof(char *)); i++) + + { + if (i == 1) + CreateStartupDisplay(1); + if ((i > 0) && (!p) && (!init_win_ext)) + { + p = CreateProgressbar("Enlightenment Starting...", 400, 16); + if (p) + ShowProgressbar(p); + } + if (!strcmp(config_files[i], "...e_autosave.cfg")) + { + is_autosave = 1; + /* This file is always preprocessed at a known location: */ +/* + * if (exists(GetSMFile())) + * LoadOpenConfigFile(OpenConfigFileForReading(GetSMFile(), 0)); + * else */ + EDBUG(5, "Dummy-LoadOpenConfigFile"); + LoadOpenConfigFile(OpenConfigFileForReading(GetGenericSMFile(), + 0)); + SoundInit(); + is_autosave = 0; + } + else + LoadConfigFile(config_files[i]); + if (p) + SetProgressbar(p, (i * 100) / 17); + } + + if (p) + FreeProgressbar(p); + } + if (theme) + Efree(theme); + if (home) + Efree(home); + themelocation = NULL; + EDBUG_RETURN(0); +} + +/**************************************************************************/ + +/* This is only called by the master_pid process (see session.c) */ +void +SaveUserControlConfig(FILE * autosavefile) +{ + Button **blst; + Background **bglist; + ColorModifierClass **cmlist; + Iconbox **iblist; + ActionClass *ac; + Action *aa; + int i, num, flags, j; + int a, b; + + EDBUG(5, "SaveUserControlConfig"); + if (autosavefile) + { + fprintf(autosavefile, "0 999\n"); + fprintf(autosavefile, "307 %i\n", (int)mode.focusmode); + fprintf(autosavefile, "311 %i\n", (int)mode.movemode); + fprintf(autosavefile, "312 %i\n", (int)mode.resizemode); + fprintf(autosavefile, "9 %i\n", (int)mode.sound); + fprintf(autosavefile, "313 %i\n", (int)mode.slidemode); + fprintf(autosavefile, "314 %i\n", (int)mode.cleanupslide); + fprintf(autosavefile, "315 %i\n", (int)mode.mapslide); + fprintf(autosavefile, "316 %i\n", (int)mode.slidespeedmap); + fprintf(autosavefile, "317 %i\n", (int)mode.slidespeedcleanup); + fprintf(autosavefile, "320 %i\n", (int)mode.desktop_bg_timeout); + fprintf(autosavefile, "321 %i\n", (int)mode.button_move_resistance); + fprintf(autosavefile, "400 %i\n", (int)desks.dragdir); + fprintf(autosavefile, "401 %i\n", (int)desks.dragbar_width); + fprintf(autosavefile, "402 %i\n", (int)desks.dragbar_ordering); + fprintf(autosavefile, "403 %i\n", (int)desks.dragbar_length); + fprintf(autosavefile, "404 %i\n", (int)desks.slidein); + fprintf(autosavefile, "405 %i\n", (int)desks.slidespeed); + fprintf(autosavefile, "406 %i\n", (int)desks.hiqualitybg); + fprintf(autosavefile, "325 %i\n", (int)mode.dockdirmode); + fprintf(autosavefile, "326 %i\n", (int)mode.shadespeed); + fprintf(autosavefile, "327 %i\n", (int)mode.tooltips); + fprintf(autosavefile, "328 %f\n", (float)mode.tiptime); + fprintf(autosavefile, "338 %i\n", (int)mode.autoraise); + fprintf(autosavefile, "339 %f\n", (float)mode.autoraisetime); + fprintf(autosavefile, "331 %i\n", (int)mode.save_under); + fprintf(autosavefile, "330 %i %i\n", (int)mode.dockstartx, + (int)mode.dockstarty); + fprintf(autosavefile, "334 %i\n", (int)mode.memory_paranoia); + fprintf(autosavefile, "332 %i\n", (int)mode.menuslide); + fprintf(autosavefile, "333 %i\n", (int)mode.numdesktops); + fprintf(autosavefile, "335 %i\n", (int)mode.transientsfollowleader); + fprintf(autosavefile, "336 %i\n", (int)mode.switchfortransientmap); + fprintf(autosavefile, "337 %i\n", (int)mode.showicons); + GetAreaSize(&a, &b); + fprintf(autosavefile, "407 %i %i\n", a, b); + fprintf(autosavefile, "340 %i\n", (int)mode.all_new_windows_get_focus); + fprintf(autosavefile, "341 %i\n", (int)mode.new_transients_get_focus); + fprintf(autosavefile, "342 %i\n", + (int)mode.new_transients_get_focus_if_group_focused); + fprintf(autosavefile, "343 %i\n", (int)mode.manual_placement); + fprintf(autosavefile, "344 %i\n", (int)mode.raise_on_next_focus); + fprintf(autosavefile, "345 %i\n", (int)mode.warp_on_next_focus); + fprintf(autosavefile, "346 %i\n", (int)mode.edge_flip_resistance); + fprintf(autosavefile, "347 %i\n", (int)mode.show_pagers); + fprintf(autosavefile, "348 %i\n", (int)mode.pager_hiq); + fprintf(autosavefile, "349 %i\n", (int)mode.pager_snap); + fprintf(autosavefile, "1350 %i\n", (int)mode.user_bg); + fprintf(autosavefile, "1351 %i\n", (int)mode.pager_zoom); + fprintf(autosavefile, "1352 %i\n", (int)mode.pager_title); + fprintf(autosavefile, "1353 %i\n", (int)mode.raise_after_next_focus); + fprintf(autosavefile, "1354 %i\n", (int)mode.display_warp); + fprintf(autosavefile, "1355 %i\n", (int)mode.warp_after_next_focus); + fprintf(autosavefile, "1356 %i\n", (int)mode.pager_scanspeed); + fprintf(autosavefile, "1000\n"); + fprintf(autosavefile, "1001 0\n"); + ac = (ActionClass *) FindItem("KEYBINDINGS", 0, + LIST_FINDBY_NAME, + LIST_TYPE_ACLASS_GLOBAL); + if ((ac) && (ac->num > 0)) + { + fprintf(autosavefile, "11 999\n"); + fprintf(autosavefile, "100 %s\n", ac->name); + fprintf(autosavefile, "102 7\n"); + for (i = 0; i < ac->num; i++) + { + aa = ac->list[i]; + if ((aa) && (aa->action) && (aa->event == EVENT_KEY_DOWN) && + (aa->key_str)) + { + int mod; + + /* next action */ + if (i > 0) + fprintf(autosavefile, "105\n"); + /* key */ + fprintf(autosavefile, "427 %s\n", aa->key_str); + /* event */ + fprintf(autosavefile, "428 4\n"); + /* modifier */ + mod = 0; + if (aa->modifiers == (ControlMask)) + { + mod = 902; + } + else if (aa->modifiers == (Mod1Mask)) + { + mod = 903; + } + else if (aa->modifiers == (Mod2Mask)) + { + mod = 904; + } + else if (aa->modifiers == (Mod3Mask)) + { + mod = 905; + } + else if (aa->modifiers == (Mod4Mask)) + { + mod = 906; + } + else if (aa->modifiers == (Mod5Mask)) + { + mod = 907; + } + else if (aa->modifiers == (ShiftMask)) + { + mod = 900; + } + else if (aa->modifiers == (ControlMask | Mod1Mask)) + { + mod = 910; + } + else if (aa->modifiers == (ShiftMask | ControlMask)) + { + mod = 911; + } + else if (aa->modifiers == (ShiftMask | Mod1Mask)) + { + mod = 912; + } + else if (aa->modifiers == (ShiftMask | ControlMask + | Mod1Mask)) + { + mod = 913; + } + else if (aa->modifiers == (ControlMask | Mod4Mask)) + { + mod = 914; + } + else if (aa->modifiers == (ShiftMask | Mod4Mask)) + { + mod = 915; + } + else if (aa->modifiers == (ControlMask | ShiftMask + | Mod4Mask)) + { + mod = 916; + } + else if (aa->modifiers == (ControlMask | Mod5Mask)) + { + mod = 917; + } + else if (aa->modifiers == (ShiftMask | Mod5Mask)) + { + mod = 918; + } + else if (aa->modifiers == (ControlMask | ShiftMask + | Mod5Mask)) + { + mod = 919; + } + else if (aa->modifiers == (Mod2Mask | ShiftMask)) + { + mod = 920; + } + else if (aa->modifiers == (Mod2Mask | ControlMask)) + { + mod = 921; + } + else if (aa->modifiers == (Mod2Mask | Mod1Mask)) + { + mod = 922; + } + fprintf(autosavefile, "101 %i\n", mod); + /* action */ + if (aa->action->params) + { + fprintf(autosavefile, "104 %i %s\n", aa->action->Type, + (char *)aa->action->params); + } + else + { + fprintf(autosavefile, "104 %i\n", aa->action->Type); + } + } + } + fprintf(autosavefile, "1000\n"); + } + { + char **slist; + + slist = FX_Active(&num); + if (slist) + { + fprintf(autosavefile, "18 999\n"); + for (i = 0; i < num; i++) + fprintf(autosavefile, "%s\n", slist[i]); + freestrlist(slist, num); + fprintf(autosavefile, "1000\n"); + } + } + blst = (Button **) ListItemTypeID(&num, LIST_TYPE_BUTTON, 0); + if ((blst) && (num > 0)) + { + for (i = 0; i < num; i++) + { + if (!blst[i]->internal) + { + fprintf(autosavefile, "4 999\n"); + fprintf(autosavefile, "100 %s\n", blst[i]->name); + if (blst[i]->iclass) + fprintf(autosavefile, "12 %s\n", + blst[i]->iclass->name); + if (blst[i]->aclass) + fprintf(autosavefile, "11 %s\n", + blst[i]->aclass->name); + if (blst[i]->ontop >= 0) + fprintf(autosavefile, "453 %i\n", + (int)blst[i]->ontop); + fprintf(autosavefile, "456 %i\n", + blst[i]->geom.width.min); + fprintf(autosavefile, "457 %i\n", + blst[i]->geom.width.max); + fprintf(autosavefile, "468 %i\n", + blst[i]->geom.height.min); + fprintf(autosavefile, "469 %i\n", + blst[i]->geom.height.max); + fprintf(autosavefile, "528 %i\n", blst[i]->geom.xorigin); + fprintf(autosavefile, "529 %i\n", blst[i]->geom.yorigin); + fprintf(autosavefile, "530 %i\n", blst[i]->geom.xabs); + fprintf(autosavefile, "531 %i\n", blst[i]->geom.xrel); + fprintf(autosavefile, "532 %i\n", blst[i]->geom.yabs); + fprintf(autosavefile, "533 %i\n", blst[i]->geom.yrel); + fprintf(autosavefile, "534 %i\n", + blst[i]->geom.xsizerel); + fprintf(autosavefile, "535 %i\n", + blst[i]->geom.xsizeabs); + fprintf(autosavefile, "536 %i\n", + blst[i]->geom.ysizerel); + fprintf(autosavefile, "537 %i\n", + blst[i]->geom.ysizeabs); + fprintf(autosavefile, "538 %i\n", + blst[i]->geom.size_from_image); + fprintf(autosavefile, "539 %i\n", blst[i]->desktop); + fprintf(autosavefile, "540 %i\n", (int)blst[i]->sticky); + fprintf(autosavefile, "542 %i\n", (int)blst[i]->visible); + + if (blst[i]->flags) + { + flags = 0; + if (((blst[i]->flags & FLAG_FIXED_HORIZ) && + (blst[i]->flags & FLAG_FIXED_VERT)) || + (blst[i]->flags & FLAG_FIXED)) + flags = 2; + else if (blst[i]->flags & FLAG_FIXED_HORIZ) + flags = 3; + else if (blst[i]->flags & FLAG_FIXED_VERT) + flags = 4; + else if (blst[i]->flags & FLAG_TITLE) + flags = 0; + else if (blst[i]->flags & FLAG_MINIICON) + flags = 1; + fprintf(autosavefile, "454 %i\n", flags); + } + fprintf(autosavefile, "1000\n"); + } + } + Efree(blst); + } + /* extras section - for object that can be created or destroyed */ + /* by users */ + fprintf(autosavefile, "20 999\n"); + num = 0; + iblist = ListAllIconboxes(&num); + if (iblist) + { + for (i = num - 1; i >= 0; i--) + { + fprintf(autosavefile, "19 999\n"); + fprintf(autosavefile, "100 %s\n", iblist[i]->name); + fprintf(autosavefile, "200 %i\n", (int)iblist[i]->orientation); + fprintf(autosavefile, "2001 %i\n", (int)iblist[i]->nobg); + fprintf(autosavefile, "2002 %i\n", (int)iblist[i]->shownames); + fprintf(autosavefile, "2003 %i\n", iblist[i]->iconsize); + fprintf(autosavefile, "2004 %i\n", (int)iblist[i]->icon_mode); + fprintf(autosavefile, "2005 %i\n", (int)iblist[i]->scrollbar_side); + fprintf(autosavefile, "2006 %i\n", (int)iblist[i]->arrow_side); + fprintf(autosavefile, "2007 %i\n", (int)iblist[i]->auto_resize); + fprintf(autosavefile, "2008 %i\n", (int)iblist[i]->draw_icon_base); + fprintf(autosavefile, "2009 %i\n", (int)iblist[i]->scrollbar_hide); + fprintf(autosavefile, "1000\n"); + } + Efree(iblist); + } + fprintf(autosavefile, "1000\n"); + cmlist = (ColorModifierClass **) ListItemType(&num, + LIST_TYPE_COLORMODIFIER); + if ((cmlist) && (num > 0)) + { + for (i = num - 1; i >= 0; i--) + { + fprintf(autosavefile, "15 999\n"); + fprintf(autosavefile, "100 %s\n", cmlist[i]->name); + fprintf(autosavefile, "600"); + for (j = 0; j < cmlist[i]->red.num; j++) + fprintf(autosavefile, " %i,%i", cmlist[i]->red.px[j], + cmlist[i]->red.py[j]); + fprintf(autosavefile, "\n601"); + for (j = 0; j < cmlist[i]->green.num; j++) + fprintf(autosavefile, " %i,%i", cmlist[i]->green.px[j], + cmlist[i]->green.py[j]); + fprintf(autosavefile, "\n602"); + for (j = 0; j < cmlist[i]->blue.num; j++) + fprintf(autosavefile, " %i,%i", cmlist[i]->blue.px[j], + cmlist[i]->blue.py[j]); + fprintf(autosavefile, "\n1000\n"); + } + Efree(cmlist); + } + bglist = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); + if ((bglist) && (num > 0)) + { + for (i = num - 1; i >= 0; i--) + { + fprintf(autosavefile, "5 999\n"); + fprintf(autosavefile, "100 %s\n", bglist[i]->name); + fprintf(autosavefile, "560 %d %d %d\n", + bglist[i]->bg.solid.r, bglist[i]->bg.solid.g, + bglist[i]->bg.solid.b); + if ((bglist[i]->bg.file) && (!bglist[i]->bg.real_file)) + bglist[i]->bg.real_file = FindFile(bglist[i]->bg.file); + if ((bglist[i]->top.file) && (!bglist[i]->top.real_file)) + bglist[i]->top.real_file = FindFile(bglist[i]->top.file); + if ((bglist[i]->bg.file) && (bglist[i]->bg.real_file)) + { + fprintf(autosavefile, "561 %s %d %d %d %d %d %d\n", + bglist[i]->bg.real_file, + bglist[i]->bg.tile, bglist[i]->bg.keep_aspect, + bglist[i]->bg.xjust, bglist[i]->bg.yjust, + bglist[i]->bg.xperc, bglist[i]->bg.yperc); + } + else if (bglist[i]->bg.file) + { + fprintf(autosavefile, "561 %s %d %d %d %d %d %d\n", + bglist[i]->bg.file, + bglist[i]->bg.tile, bglist[i]->bg.keep_aspect, + bglist[i]->bg.xjust, bglist[i]->bg.yjust, + bglist[i]->bg.xperc, bglist[i]->bg.yperc); + } + if ((bglist[i]->top.file) && (bglist[i]->top.real_file)) + { + fprintf(autosavefile, "562 %s %d %d %d %d %d\n", + bglist[i]->top.real_file, + bglist[i]->top.keep_aspect, + bglist[i]->top.xjust, bglist[i]->top.yjust, + bglist[i]->top.xperc, bglist[i]->top.yperc); + } + else if (bglist[i]->top.file) + { + fprintf(autosavefile, "562 %s %d %d %d %d %d\n", + bglist[i]->top.file, + bglist[i]->top.keep_aspect, + bglist[i]->top.xjust, bglist[i]->top.yjust, + bglist[i]->top.xperc, bglist[i]->top.yperc); + } + if (bglist[i]->cmclass) + { + fprintf(autosavefile, "370 %s\n", + bglist[i]->cmclass->name); + } + for (j = 0; j < (ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1); j++) + { + if ((!strcmp(bglist[i]->name, "NONE")) && + (!desks.desk[j].bg)) + fprintf(autosavefile, "564 %d\n", j); + if (desks.desk[j].bg == bglist[i]) + fprintf(autosavefile, "564 %d\n", j); + } + fprintf(autosavefile, "1000\n"); + } + Efree(bglist); + } + fclose(autosavefile); + } + EDBUG_RETURN_; +} + +void +RecoverUserConfig(void) +{ + if (is_autosave) + { + ASSIGN_ALERT("Recover system config?", + "Yes, Attempt recovery", + "Restart and try again", + "Quit and give up"); + Alert("Enlightenment has encountered parsing errors in your autosaved\n" + "configuration.\n" + "\n" + "This may be due to filing system errors, Minor bugs or" + " unforseen\n" + "system shutdowns.\n" + "\n" + "Do you wish Enlightenment to recover its original system\n" + "configuration and try again?\n"); + RESET_ALERT; + mode.autosave = 0; + MapUnmap(1); + if (getpid() == master_pid && init_win_ext) + { + XKillClient(disp, init_win_ext); + init_win_ext = 0; + } + doExit("restart"); + } +} diff --git a/src/config.h b/src/config.h new file mode 100644 index 00000000..e69de29b diff --git a/src/containers.c b/src/containers.c new file mode 100644 index 00000000..eeb3ae6b --- /dev/null +++ b/src/containers.c @@ -0,0 +1,114 @@ +#include "E.h" + +/* + * void + * EmbedContainerInEwin(Container * MyContainer) + * { + * + * } + */ + +Container * +InitializeContainer(char *name, ImageClass * iclass, int width, + int height, char orientation) +{ + Container *bc; + + EDBUG(5, "InitializeContainer"); + bc = Emalloc(sizeof(Container)); + + bc->name = duplicate(name); + bc->iclass = iclass; + if (bc->iclass) + bc->iclass->ref_count++; + bc->state = 0; + bc->expose = 0; + bc->w = width; + bc->h = height; + bc->orientation = orientation; + bc->ButtonList = NULL; + bc->numofbuttonsinlist = 0; + + bc->win = ECreateWindow(root.win, -100, -100, width, height, 0); + + EDBUG_RETURN(bc); + +} + +void +AddButtonToContainer(Container * bc, Button * b) +{ + EDBUG(5, "AddButtonToContainer"); + + if (!bc->ButtonList) + { + bc->ButtonList = Emalloc(sizeof(Container *)); + } + else + { + bc->ButtonList = Erealloc(bc->ButtonList, + (bc->numofbuttonsinlist + 1) * sizeof(Container *)); + } + bc->ButtonList[bc->numofbuttonsinlist++] = b; + b->ref_count++; + + EDBUG_RETURN_; +} + +void +RemoveButtonFromContainer(Container * bc, Button * b) +{ + + int i, j, found; + Button **MyButtonList; + + EDBUG(5, "RemoveButtonFromContainer"); + + MyButtonList = Emalloc(bc->numofbuttonsinlist * sizeof(Container *)); + j = 0; + found = 0; + for (i = 0; i < bc->numofbuttonsinlist; i++) + MyButtonList[i] = bc->ButtonList[i]; + + for (i = 0; i < bc->numofbuttonsinlist; i++) + { + if (bc->ButtonList[i] == b) + { + j = i; + found = 1; + } + } + if (found && ((bc->numofbuttonsinlist - 1) > 0)) + { + bc->ButtonList = Erealloc(bc->ButtonList, + (bc->numofbuttonsinlist * sizeof(Container *))); + for (i = 0; i <= bc->numofbuttonsinlist; i++) + { + if (i != j) + bc->ButtonList[j++] = MyButtonList[i]; + } + bc->numofbuttonsinlist--; + } + else if (found && (bc->numofbuttonsinlist - 1) == 0) + { + Efree(bc->ButtonList); + bc->ButtonList = NULL; + bc->numofbuttonsinlist = 0; + } + Efree(MyButtonList); + b->ref_count--; + EDBUG_RETURN_; +} + +void +RemoveContainer(Container * bc) +{ + EDBUG(5, "RemoveContainer"); + if (bc) + { + if (bc->name) + Efree(bc->name); + Efree(bc); + } + EDBUG_RETURN_; +} diff --git a/src/coords.c b/src/coords.c new file mode 100644 index 00000000..00fc373e --- /dev/null +++ b/src/coords.c @@ -0,0 +1,95 @@ +#include "E.h" + +static char coords_visible = 0; +static Window c_win = 0; +static int cx = 0, cy = 0, cw = 0, ch = 0; + +void +SetCoords(int x, int y, int w, int h) +{ + TextClass *tc = NULL; + ImageClass *ic = NULL; + char s[256], pq; + EWin *ewin; + int md; + + if (!tc) + tc = FindItem("COORDS", 0, LIST_FINDBY_NAME, LIST_TYPE_TCLASS); + if (!ic) + ic = FindItem("COORDS", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (!c_win) + c_win = ECreateWindow(root.win, 0, 0, 1, 1, 2); + if ((!ic) || (!tc)) + return; + + Esnprintf(s, sizeof(s), "%i x %i (%i, %i)", w, h, x, y); + TextSize(tc, 0, 0, 0, s, &cw, &ch, 17); + ewin = mode.ewin; + cw += (ic->padding.left + ic->padding.right); + ch += (ic->padding.top + ic->padding.bottom); + if (ewin) + { + md = 0; + if (mode.mode == MODE_MOVE) + md = mode.movemode; + else + md = mode.resizemode; + if ((md > 0) && ((cw >= (ewin->w)) || (ch >= (ewin->h)))) + { + cx = 0; + cy = 0; + } + else + { + switch (md) + { + case 0: + case 1: + case 2: + cx = ewin->x + ((ewin->w - cw) / 2) - desks.desk[ewin->desktop].x; + cy = ewin->y + ((ewin->h - ch) / 2) - desks.desk[ewin->desktop].y; + break; + case 3: + cx = 0; + cy = 0; + break; + case 4: + cx = 0; + cy = 0; + break; + case 5: + cx = 0; + cy = 0; + break; + default: + cx = 0; + cy = 0; + break; + } + } + } + else + { + cx = 0; + cy = 0; + } + if (!coords_visible) + EMapWindow(disp, c_win); + XRaiseWindow(disp, c_win); + EMoveResizeWindow(disp, c_win, cx, cy, cw, ch); + pq = queue_up; + queue_up = 0; + IclassApply(ic, c_win, cw, ch, 1, 0, STATE_NORMAL, 0); + TclassApply(ic, c_win, cw, ch, 0, 0, STATE_NORMAL, 0, tc, s); + queue_up = pq; + XFlush(disp); + coords_visible = 1; +} + +void +HideCoords(void) +{ + if (c_win) + EUnmapWindow(disp, c_win); + coords_visible = 0; +} diff --git a/src/cursors.c b/src/cursors.c new file mode 100644 index 00000000..fab41298 --- /dev/null +++ b/src/cursors.c @@ -0,0 +1,104 @@ +#include "E.h" + +ECursor * +CreateECursor(char *name, char *image, ImlibColor * fg, ImlibColor * bg) +{ + Cursor curs; + XColor xfg, xbg; + Pixmap pmap, mask; + int xh, yh; + unsigned int w, h, ww, hh; + char *img, msk[FILEPATH_LEN_MAX]; + ECursor *ec; + int r, g, b; + + if ((!name) || (!image)) + return NULL; + img = FindFile(image); + if (!img) + return NULL; + + Esnprintf(msk, sizeof(msk), "%s.mask", img); + pmap = 0; + mask = 0; + xh = 0; + yh = 0; + XReadBitmapFile(disp, root.win, msk, &w, &h, &mask, &xh, &yh); + XReadBitmapFile(disp, root.win, img, &w, &h, &pmap, &xh, &yh); + XQueryBestCursor(disp, root.win, w, h, &ww, &hh); + if ((w > ww) || (h > hh)) + { + EFreePixmap(disp, pmap); + EFreePixmap(disp, mask); + Efree(img); + return NULL; + } + r = fg->r; + g = fg->g; + b = fg->b; + xfg.red = (fg->r << 8) | (fg->r); + xfg.green = (fg->g << 8) | (fg->g); + xfg.blue = (fg->b << 8) | (fg->b); + xfg.pixel = Imlib_best_color_match(id, &r, &g, &b); + r = bg->r; + g = bg->g; + b = bg->b; + xbg.red = (bg->r << 8) | (bg->r); + xbg.green = (bg->g << 8) | (bg->g); + xbg.blue = (bg->b << 8) | (bg->b); + xbg.pixel = Imlib_best_color_match(id, &r, &g, &b); + curs = 0; + curs = XCreatePixmapCursor(disp, pmap, mask, &xfg, &xbg, xh, yh); + EFreePixmap(disp, pmap); + EFreePixmap(disp, mask); + Efree(img); + ec = Emalloc(sizeof(ECursor)); + ec->name = duplicate(name); + ec->file = duplicate(image); + ec->fg = *fg; + ec->bg = *bg; + ec->cursor = curs; + ec->ref_count = 0; + ec->inroot = 0; + + return ec; +} + +void +ApplyECursor(Window win, ECursor * ec) +{ + if (!ec) + return; + XDefineCursor(disp, win, ec->cursor); + + return; +} + +void +FreeECursor(ECursor * ec) +{ + + if (!ec) + return; + + if (ec->ref_count > 0) + { + char stuff[255]; + + Esnprintf(stuff, sizeof(stuff), "Error: %u references remain\n", + ec->ref_count); + DIALOG_OK("ECursor Error", stuff); + + return; + } + + while (RemoveItemByPtr(ec, LIST_TYPE_ECURSOR)); + + if (ec->name) + Efree(ec->name); + if (ec->file) + Efree(ec->file); + Efree(ec); + + return; +} diff --git a/src/desktops.c b/src/desktops.c new file mode 100644 index 00000000..f46b3004 --- /dev/null +++ b/src/desktops.c @@ -0,0 +1,2215 @@ +#include "E.h" + +char * +GetUniqueBGString(Background * bg) +{ + char s[256]; + const char *chmap = + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"; + int n1, n2, n3, n4, n5, f1, f2, f3, f4, f5, f6; + + n1 = (bg->bg.solid.r << 24) | (bg->bg.solid.g << 16) | + (bg->bg.solid.b << 8) | (bg->bg.tile << 7) | (bg->bg.keep_aspect << 6) | + (bg->top.keep_aspect << 5); + n2 = (bg->bg.xjust << 16) | (bg->bg.yjust); + n3 = (bg->bg.xperc << 16) | (bg->bg.yperc); + n4 = (bg->top.xjust << 16) | (bg->top.yjust); + n5 = (bg->top.xperc << 16) | (bg->top.yperc); + f1 = 0; + f2 = 0; + f3 = 0; + f4 = 0; + f5 = 0; + f6 = 0; + if (bg->bg.file) + { + char *f; + + f = FindFile(bg->bg.file); + if (f) + { + f1 = fileinode(f); + f2 = filedev(f); + f3 = (int)moddate(f); + Efree(f); + } + } + if (bg->top.file) + { + char *f; + + f = FindFile(bg->top.file); + if (f) + { + f4 = fileinode(f); + f5 = filedev(f); + f6 = (int)moddate(f); + Efree(f); + } + } + Esnprintf(s, sizeof(s), + "%c%c%c%c%c%c" + "%c%c%c%c%c%c" + "%c%c%c%c%c%c" + "%c%c%c%c%c%c" + "%c%c%c%c%c%c" + "%c%c%c%c%c%c" + "%c%c%c%c%c%c" + "%c%c%c%c%c%c" + "%c%c%c%c%c%c" + "%c%c%c%c%c%c" + "%c%c%c%c%c%c" + , + chmap[(n1 >> 0) & 0x3f], + chmap[(n1 >> 6) & 0x3f], + chmap[(n1 >> 12) & 0x3f], + chmap[(n1 >> 18) & 0x3f], + chmap[(n1 >> 24) & 0x3f], + chmap[(n1 >> 28) & 0x3f], + chmap[(n2 >> 0) & 0x3f], + chmap[(n2 >> 6) & 0x3f], + chmap[(n2 >> 12) & 0x3f], + chmap[(n2 >> 18) & 0x3f], + chmap[(n2 >> 24) & 0x3f], + chmap[(n2 >> 28) & 0x3f], + chmap[(n3 >> 0) & 0x3f], + chmap[(n3 >> 6) & 0x3f], + chmap[(n3 >> 12) & 0x3f], + chmap[(n3 >> 18) & 0x3f], + chmap[(n3 >> 24) & 0x3f], + chmap[(n3 >> 28) & 0x3f], + chmap[(n4 >> 0) & 0x3f], + chmap[(n4 >> 6) & 0x3f], + chmap[(n4 >> 12) & 0x3f], + chmap[(n4 >> 18) & 0x3f], + chmap[(n4 >> 24) & 0x3f], + chmap[(n4 >> 28) & 0x3f], + chmap[(n5 >> 0) & 0x3f], + chmap[(n5 >> 6) & 0x3f], + chmap[(n5 >> 12) & 0x3f], + chmap[(n5 >> 18) & 0x3f], + chmap[(n5 >> 24) & 0x3f], + chmap[(n5 >> 28) & 0x3f], + chmap[(f1 >> 0) & 0x3f], + chmap[(f1 >> 6) & 0x3f], + chmap[(f1 >> 12) & 0x3f], + chmap[(f1 >> 18) & 0x3f], + chmap[(f1 >> 24) & 0x3f], + chmap[(f1 >> 28) & 0x3f], + chmap[(f2 >> 0) & 0x3f], + chmap[(f2 >> 6) & 0x3f], + chmap[(f2 >> 12) & 0x3f], + chmap[(f2 >> 18) & 0x3f], + chmap[(f2 >> 24) & 0x3f], + chmap[(f2 >> 28) & 0x3f], + chmap[(f3 >> 0) & 0x3f], + chmap[(f3 >> 6) & 0x3f], + chmap[(f3 >> 12) & 0x3f], + chmap[(f3 >> 18) & 0x3f], + chmap[(f3 >> 24) & 0x3f], + chmap[(f3 >> 28) & 0x3f], + chmap[(f4 >> 0) & 0x3f], + chmap[(f4 >> 6) & 0x3f], + chmap[(f4 >> 12) & 0x3f], + chmap[(f4 >> 18) & 0x3f], + chmap[(f4 >> 24) & 0x3f], + chmap[(f4 >> 28) & 0x3f], + chmap[(f5 >> 0) & 0x3f], + chmap[(f5 >> 6) & 0x3f], + chmap[(f5 >> 12) & 0x3f], + chmap[(f5 >> 18) & 0x3f], + chmap[(f5 >> 24) & 0x3f], + chmap[(f5 >> 28) & 0x3f], + chmap[(f6 >> 0) & 0x3f], + chmap[(f6 >> 6) & 0x3f], + chmap[(f6 >> 12) & 0x3f], + chmap[(f6 >> 18) & 0x3f], + chmap[(f6 >> 24) & 0x3f], + chmap[(f6 >> 28) & 0x3f] + ); + return duplicate(s); +} + +void +ChangeNumberOfDesktops(int quantity) +{ + int pnum, i, num; + EWin **lst; + + pnum = mode.numdesktops; + mode.numdesktops = quantity; + if (mode.numdesktops <= 0) + mode.numdesktops = 1; + else if (mode.numdesktops > ENLIGHTENMENT_CONF_NUM_DESKTOPS) + mode.numdesktops = ENLIGHTENMENT_CONF_NUM_DESKTOPS; + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if (lst) + { + for (i = 0; i < num; i++) + { + if (lst[i]->desktop >= mode.numdesktops) + MoveEwinToDesktop(lst[i], mode.numdesktops - 1); + } + Efree(lst); + } + if (mode.numdesktops > pnum) + { + Pager *p; + char s[1024]; + + for (i = pnum; i < mode.numdesktops; i++) + { + p = CreatePager(); + if (p) + { + p->desktop = i; + Esnprintf(s, sizeof(s), "%i", i); + PagerTitle(p, s); + PagerShow(p); + } + } + } + else if (mode.numdesktops < pnum) + { + Pager **pl; + int j, num; + + for (j = mode.numdesktops; j < pnum; j++) + { + pl = PagersForDesktop(j, &num); + if (pl) + { + for (i = 0; i < num; i++) + { + if (pl[i]->ewin) + ICCCM_Delete(pl[i]->ewin); + } + Efree(pl); + } + } + } + if (desks.current >= mode.numdesktops) + GotoDesktop(mode.numdesktops - 1); + GNOME_SetDeskCount(); + GNOME_SetDeskNames(); + for (i = mode.numdesktops; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + LowerDesktop(i); +} + +void +ShowDesktopControls() +{ + Button **lst; + int num, i; + + lst = (Button **) ListItemTypeID(&num, LIST_TYPE_BUTTON, 1); + if ((lst) && (num > 0)) + { + for (i = 0; i < num; i++) + SimpleShowButton(lst[i]); + Efree(lst); + StackDesktops(); + } +} + +void +ShowDesktopTabs() +{ + Button **lst; + int num, i; + + lst = (Button **) ListItemTypeID(&num, LIST_TYPE_BUTTON, 2); + if ((lst) && (num > 0)) + { + for (i = 0; i < num; i++) + SimpleShowButton(lst[i]); + Efree(lst); + StackDesktops(); + } +} + +void +HideDesktopTabs() +{ + Button **lst; + int num, i; + + lst = (Button **) ListItemTypeID(&num, LIST_TYPE_BUTTON, 2); + if ((lst) && (num > 0)) + { + for (i = 0; i < num; i++) + HideButton(lst[i]); + Efree(lst); + StackDesktops(); + } +} + +void +MoveToDeskTop(int num) +{ + int i, j; + + EDBUG(6, "MoveToDeskTop"); + j = -1; + i = 0; + while ((j < 0) && (i < ENLIGHTENMENT_CONF_NUM_DESKTOPS)) + { + if (deskorder[i] == num) + j = i; + i++; + } + if (j < 0) + EDBUG_RETURN_; + if (j > 0) + { + for (i = j - 1; i >= 0; i--) + deskorder[i + 1] = deskorder[i]; + deskorder[0] = num; + } + EDBUG_RETURN_; +} + +void +MoveToDeskBottom(int num) +{ + int i, j; + + EDBUG(6, "MoveToDeskBottom"); + j = -1; + i = 0; + while ((j < 0) && (i < ENLIGHTENMENT_CONF_NUM_DESKTOPS)) + { + if (deskorder[i] == num) + j = i; + i++; + } + if (j < 0) + EDBUG_RETURN_; + if (j < ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1) + { + for (i = j; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1; i++) + deskorder[i] = deskorder[i + 1]; + deskorder[ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1] = num; + } + EDBUG_RETURN_; +} + +void +SlideWindowTo(Window win, int fx, int fy, int tx, int ty, int speed) +{ + int k, spd, x, y, min; + struct timeval timev1, timev2; + int dsec, dusec; + double tm; + + EDBUG(5, "SlideWindowTo"); + spd = 16; + min = 2; + GrabX(); + for (k = 0; k <= 1024; k += spd) + { + gettimeofday(&timev1, NULL); + x = ((fx * (1024 - k)) + (tx * k)) >> 10; + y = ((fy * (1024 - k)) + (ty * k)) >> 10; + EMoveWindow(disp, win, x, y); + XSync(disp, False); + gettimeofday(&timev2, NULL); + dsec = timev2.tv_sec - timev1.tv_sec; + dusec = timev2.tv_usec - timev1.tv_usec; + if (dusec < 0) + { + dsec--; + dusec += 1000000; + } + tm = (double)dsec + (((double)dusec) / 1000000); + spd = (int)((double)speed * tm); + if (spd < min) + spd = min; + } + EMoveWindow(disp, win, tx, ty); + UngrabX(); + EDBUG_RETURN_; +} + +void +KeepBGimages(Background * bg, char onoff) +{ + if (onoff) + { + bg->keepim = 1; + } + else + { + bg->keepim = 0; + if (bg->bg.im) + Imlib_destroy_image(id, bg->bg.im); + bg->bg.im = NULL; + if (bg->top.im) + Imlib_destroy_image(id, bg->top.im); + bg->top.im = NULL; + if (bg->pmap) + Imlib_free_pixmap(id, bg->pmap); + bg->pmap = 0; + } +} + +void +RemoveImagesFromBG(Background * bg) +{ + if (bg->bg.file) + Efree(bg->bg.file); + if (bg->bg.real_file) + Efree(bg->bg.real_file); + bg->bg.file = NULL; + bg->bg.real_file = NULL; + if (bg->bg.im) + Imlib_destroy_image(id, bg->bg.im); + bg->bg.im = NULL; + if (bg->top.im) + Imlib_destroy_image(id, bg->top.im); + bg->top.im = NULL; + bg->keepim = 0; + if (bg->pmap) + Imlib_free_pixmap(id, bg->pmap); + bg->pmap = 0; +} + +void +FreeDesktopBG(Background * bg) +{ + + EDBUG(6, "FreeDesktopBG"); + + if (!bg) + EDBUG_RETURN_; + + if (bg->ref_count > 0) + { + char stuff[255]; + + Esnprintf(stuff, sizeof(stuff), "%u references remain", bg->ref_count); + DIALOG_OK("Background Error!", stuff); + + EDBUG_RETURN_; + } + + if (bg->bg.file) + Efree(bg->bg.file); + if (bg->bg.real_file) + Efree(bg->bg.real_file); + if (bg->bg.im) + Imlib_destroy_image(id, bg->bg.im); + if (bg->top.file) + Efree(bg->top.file); + if (bg->top.real_file) + Efree(bg->top.real_file); + if (bg->top.im) + Imlib_destroy_image(id, bg->top.im); + if (bg->pmap) + Imlib_free_pixmap(id, bg->pmap); + if (bg->name) + Efree(bg->name); + Efree(bg); + + EDBUG_RETURN_; +} + +Background * +CreateDesktopBG(char *name, ImlibColor * solid, + char *bg, char tile, char keep_aspect, + int xjust, int yjust, int xperc, int yperc, + char *top, char tkeep_aspect, + int txjust, int tyjust, int txperc, int typerc) +{ + ImlibData *imd; + Background *d; + + EDBUG(6, "CreateDesktopBG"); + + if (ird) + { + imd = ird; + } + else + { + imd = id; + } + + d = Emalloc(sizeof(Background)); + if (!d) + EDBUG_RETURN(NULL); + d->name = duplicate(name); + d->pmap = 0; + d->last_viewed = 0; + d->bg.solid.r = 160; + d->bg.solid.g = 160; + d->bg.solid.b = 160; + d->bg.file = NULL; + d->bg.real_file = NULL; + d->bg.im = NULL; + d->bg.tile = 1; + d->bg.keep_aspect = 1; + d->bg.xjust = 512; + d->bg.yjust = 512; + d->bg.xperc = 1024; + d->bg.yperc = 1024; + d->top.file = NULL; + d->top.real_file = NULL; + d->top.im = NULL; + d->top.keep_aspect = 1; + d->top.xjust = 512; + d->top.yjust = 512; + d->top.xperc = 0; + d->top.yperc = 0; + if (solid) + { + d->bg.solid.r = solid->r; + d->bg.solid.g = solid->g; + d->bg.solid.b = solid->b; + } + d->bg.file = NULL; + if (bg) + d->bg.file = duplicate(bg); + d->bg.tile = tile; + d->bg.keep_aspect = keep_aspect; + d->bg.xjust = xjust; + d->bg.yjust = yjust; + d->bg.xperc = xperc; + d->bg.yperc = yperc; + if (top) + d->top.file = duplicate(top); + d->top.keep_aspect = tkeep_aspect; + d->top.xjust = txjust; + d->top.yjust = tyjust; + d->top.xperc = txperc; + d->top.yperc = typerc; + d->cmclass = NULL; + d->keepim = 0; + d->ref_count = 0; + + EDBUG_RETURN(d); +} + +void +RefreshCurrentDesktop() +{ + EDBUG(5, "RefreshCurrentDesktop"); + RefreshDesktop(desks.current); + EDBUG_RETURN_; +} + +void +RefreshDesktop(int num) +{ + Background *dsk; + ImlibData *imd; + + EDBUG(4, "RefreshDesktop"); + + num = num % ENLIGHTENMENT_CONF_NUM_DESKTOPS; + if (!desks.desk[num].viewable) + EDBUG_RETURN_; + dsk = desks.desk[num].bg; + if (!dsk) + EDBUG_RETURN_; + if ((ird) && (num == 0)) + imd = ird; + else + imd = id; + + SetBackgroundTo(imd, desks.desk[num].win, dsk, 1); + EDBUG_RETURN_; +} + +void +SetBackgroundTo(ImlibData * imd, Window win, Background * dsk, char setbg) +{ + int r, g, b, w, h, x, y, ww, hh; + unsigned int rw, rh; + Pixmap pmap, mask, dpmap; + GC gc; + XGCValues gcv; + char hasbg, hasfg; + int rt, depth; + ColorModifierClass *cm; + + EDBUG(4, "SetBackgroundTo"); + + if (!WinExists(win)) + EDBUG_RETURN_; + GetWinWH(win, &rw, &rh); + depth = GetWinDepth(win); + if ((depth != imd->x.depth) && (ird) && (depth == ird->x.depth)) + imd = ird; + r = dsk->bg.solid.r; + g = dsk->bg.solid.g; + b = dsk->bg.solid.b; + dsk->bg.solid.pixel = Imlib_best_color_match(imd, &r, &g, &b); + pmap = 0; + gc = 0; + w = 0; + h = 0; + hasbg = 0; + hasfg = 0; + rt = Imlib_get_render_type(id); + + if (desks.hiqualitybg) + Imlib_set_render_type(imd, RT_DITHER_TRUECOL); + + dpmap = dsk->pmap; + if (!setbg) + dpmap = 0; + if (!dpmap) + { + cm = dsk->cmclass; + if (cm) + { + cm->ref_count--; + } + else + { + cm = (ColorModifierClass *) FindItem("BACKGROUND", 0, + LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + } + + if (dsk->bg.file) + { + if (!dsk->bg.im) + { + if (!dsk->bg.real_file) + dsk->bg.real_file = FindFile(dsk->bg.file); + dsk->bg.im = ELoadImageImlibData(imd, dsk->bg.real_file); + } + } + if (dsk->top.file) + { + if (!dsk->top.im) + { + if (!dsk->top.real_file) + dsk->top.real_file = FindFile(dsk->top.file); + dsk->top.im = ELoadImageImlibData(imd, dsk->top.real_file); + } + } + if (cm) + { + cm->ref_count++; + if (dsk->top.im) + { + Imlib_set_image_red_curve(id, dsk->top.im, + cm->red.map); + Imlib_set_image_green_curve(id, dsk->top.im, + cm->green.map); + Imlib_set_image_blue_curve(id, dsk->top.im, + cm->blue.map); + } + if (dsk->bg.im) + { + Imlib_set_image_red_curve(id, dsk->bg.im, + cm->red.map); + Imlib_set_image_green_curve(id, dsk->bg.im, + cm->green.map); + Imlib_set_image_blue_curve(id, dsk->bg.im, + cm->blue.map); + } + } + } + if (dsk->top.im) + hasfg = 1; + if (dsk->bg.im) + hasbg = 1; + if ((hasfg) && (hasbg)) + { + if (dsk->bg.xperc > 0) + { + w = (rw * dsk->bg.xperc) >> 10; + } + else + { + if (!setbg) + w = (dsk->bg.im->rgb_width * rw) / root.w; + else + w = dsk->bg.im->rgb_width; + } + if (dsk->bg.yperc > 0) + { + h = (rh * dsk->bg.yperc) >> 10; + } + else + { + if (!setbg) + { + h = (dsk->bg.im->rgb_height * rh) / root.h; + } + else + { + h = dsk->bg.im->rgb_height; + } + } + if (w <= 0) + w = 1; + if (h <= 0) + h = 1; + if (dsk->bg.keep_aspect) + { + if (dsk->bg.yperc <= 0) + { + if (((w << 10) / h) != + ((dsk->bg.im->rgb_width << 10) / dsk->bg.im->rgb_height)) + h = ((w * dsk->bg.im->rgb_height) / dsk->bg.im->rgb_width); + } + else + { + if (((h << 10) / w) != + ((dsk->bg.im->rgb_height << 10) / dsk->bg.im->rgb_width)) + w = ((h * dsk->bg.im->rgb_width) / dsk->bg.im->rgb_height); + } + } + dpmap = ECreatePixmap(disp, win, rw, rh, imd->x.depth); + gc = XCreateGC(disp, dpmap, 0, &gcv); + if (!dsk->bg.tile) + { + XSetForeground(disp, gc, dsk->bg.solid.pixel); + XFillRectangle(disp, dpmap, gc, 0, 0, rw, rh); + } + x = ((rw - w) * dsk->bg.xjust) >> 10; + y = ((rh - h) * dsk->bg.yjust) >> 10; + Imlib_render(imd, dsk->bg.im, w, h); + pmap = Imlib_move_image(imd, dsk->bg.im); + XSetTile(disp, gc, pmap); + XSetTSOrigin(disp, gc, x, y); + XSetFillStyle(disp, gc, FillTiled); + if (!dsk->bg.tile) + { + XFillRectangle(disp, dpmap, gc, x, y, w, h); + } + else + { + XFillRectangle(disp, dpmap, gc, 0, 0, rw, rh); + } + Imlib_free_pixmap(imd, pmap); + + if (dsk->top.xperc > 0) + { + ww = (rw * dsk->top.xperc) >> 10; + } + else + { + if (!setbg) + { + ww = (dsk->top.im->rgb_width * rw) / root.w; + } + else + { + ww = dsk->top.im->rgb_width; + } + } + if (dsk->top.yperc > 0) + { + hh = (rh * dsk->top.yperc) >> 10; + } + else + { + if (!setbg) + { + hh = (dsk->top.im->rgb_height * rh) / root.h; + } + else + { + hh = dsk->top.im->rgb_height; + } + } + if (ww <= 0) + ww = 1; + if (hh <= 0) + hh = 1; + if (dsk->top.keep_aspect) + { + if (dsk->top.yperc <= 0) + { + if (((ww << 10) / hh) != + ((dsk->top.im->rgb_width << 10) / dsk->top.im->rgb_height)) + hh = ((ww * dsk->top.im->rgb_height) + / dsk->top.im->rgb_width); + } + else + { + if (((hh << 10) / ww) != + ((dsk->top.im->rgb_height << 10) / dsk->top.im->rgb_width)) + ww = ((hh * dsk->top.im->rgb_width) + / dsk->top.im->rgb_height); + } + } + Imlib_render(imd, dsk->top.im, ww, hh); + pmap = Imlib_move_image(imd, dsk->top.im); + mask = Imlib_move_mask(imd, dsk->top.im); + x = ((rw - ww) * dsk->top.xjust) >> 10; + y = ((rh - hh) * dsk->top.yjust) >> 10; + XSetTile(disp, gc, pmap); + XSetTSOrigin(disp, gc, x, y); + XSetFillStyle(disp, gc, FillTiled); + if (mask) + { + XSetClipMask(disp, gc, mask); + XSetClipOrigin(disp, gc, x, y); + } + XFillRectangle(disp, dpmap, gc, x, y, ww, hh); + Imlib_free_pixmap(imd, pmap); + } + else if (hasbg) + { + if (dsk->bg.xperc > 0) + w = (rw * dsk->bg.xperc) >> 10; + else + { + if (!setbg) + w = (dsk->bg.im->rgb_width * rw) / root.w; + else + w = dsk->bg.im->rgb_width; + } + if (dsk->bg.yperc > 0) + h = (rh * dsk->bg.yperc) >> 10; + else + { + if (!setbg) + h = (dsk->bg.im->rgb_height * rh) / root.h; + else + h = dsk->bg.im->rgb_height; + } + if (w <= 0) + w = 1; + if (h <= 0) + h = 1; + if (dsk->bg.keep_aspect) + { + if (dsk->bg.yperc <= 0) + { + if (((w << 10) / h) != + ((dsk->bg.im->rgb_width << 10) / dsk->bg.im->rgb_height)) + h = ((w * dsk->bg.im->rgb_height) / dsk->bg.im->rgb_width); + } + else + { + if (((h << 10) / w) != + ((dsk->bg.im->rgb_height << 10) / dsk->bg.im->rgb_width)) + w = ((h * dsk->bg.im->rgb_width) / dsk->bg.im->rgb_height); + } + } + dpmap = 0; + x = ((rw - w) * dsk->bg.xjust) >> 10; + y = ((rh - h) * dsk->bg.yjust) >> 10; + if (setbg) + { + if (dsk->bg.tile) + { + if ((x != 0) || (y != 0)) + { + dpmap = ECreatePixmap(disp, win, w, h, imd->x.depth); + gc = XCreateGC(disp, dpmap, 0, &gcv); + } + } + else if ((x != 0) || (y != 0) || ((int)rw != (int)w) + || ((int)rh != (int)h)) + { + dpmap = ECreatePixmap(disp, win, rw, rh, imd->x.depth); + gc = XCreateGC(disp, dpmap, 0, &gcv); + XSetForeground(disp, gc, dsk->bg.solid.pixel); + XFillRectangle(disp, dpmap, gc, 0, 0, rw, rh); + } + } + else + { + if (dsk->bg.tile) + { + dpmap = ECreatePixmap(disp, win, w, h, imd->x.depth); + gc = XCreateGC(disp, dpmap, 0, &gcv); + } + else + { + dpmap = ECreatePixmap(disp, win, rw, rh, imd->x.depth); + gc = XCreateGC(disp, dpmap, 0, &gcv); + XSetForeground(disp, gc, dsk->bg.solid.pixel); + XFillRectangle(disp, dpmap, gc, 0, 0, rw, rh); + } + } + Imlib_render(imd, dsk->bg.im, w, h); + pmap = Imlib_move_image(imd, dsk->bg.im); + if (dpmap) + { + XSetTile(disp, gc, pmap); + XSetTSOrigin(disp, gc, x, y); + XSetFillStyle(disp, gc, FillTiled); + if (dsk->bg.tile) + { + XFillRectangle(disp, dpmap, gc, 0, 0, w, h); + } + else + { + XFillRectangle(disp, dpmap, gc, x, y, w, h); + } + Imlib_free_pixmap(imd, pmap); + } + else + dpmap = pmap; + } + else if (hasfg) + { + dpmap = ECreatePixmap(disp, win, rw, rh, imd->x.depth); + gc = XCreateGC(disp, dpmap, 0, &gcv); + XSetForeground(disp, gc, dsk->bg.solid.pixel); + XFillRectangle(disp, dpmap, gc, 0, 0, rw, rh); + + if (dsk->top.xperc > 0) + { + ww = (rw * dsk->top.xperc) >> 10; + } + else + { + if (!setbg) + { + ww = (dsk->top.im->rgb_width * rw) / root.w; + } + else + { + ww = dsk->top.im->rgb_width; + } + } + + if (dsk->top.yperc > 0) + { + hh = (rh * dsk->top.yperc) >> 10; + } + else + { + if (!setbg) + { + hh = (dsk->top.im->rgb_height * rh) / root.h; + } + else + { + hh = dsk->top.im->rgb_height; + } + } + if (ww <= 0) + ww = 1; + if (hh <= 0) + hh = 1; + if (dsk->top.keep_aspect) + { + if (dsk->top.yperc <= 0) + { + if (((ww << 10) / hh) != + ((dsk->top.im->rgb_width << 10) / dsk->top.im->rgb_height)) + hh = ((ww * dsk->top.im->rgb_height) + / dsk->top.im->rgb_width); + } + else + { + if (((hh << 10) / ww) != + ((dsk->top.im->rgb_height << 10) / dsk->top.im->rgb_width)) + ww = ((hh * dsk->top.im->rgb_width) + / dsk->top.im->rgb_height); + } + } + Imlib_render(imd, dsk->top.im, ww, hh); + pmap = Imlib_move_image(imd, dsk->top.im); + mask = Imlib_move_mask(imd, dsk->top.im); + x = ((rw - ww) * dsk->top.xjust) >> 10; + y = ((rh - hh) * dsk->top.yjust) >> 10; + XSetTile(disp, gc, pmap); + XSetTSOrigin(disp, gc, x, y); + XSetFillStyle(disp, gc, FillTiled); + if (mask) + { + XSetClipMask(disp, gc, mask); + XSetClipOrigin(disp, gc, x, y); + } + XFillRectangle(disp, dpmap, gc, x, y, ww, hh); + Imlib_free_pixmap(imd, pmap); + } + if (!dsk->keepim) + { + if (dsk->top.im) + Imlib_destroy_image(imd, dsk->top.im); + if (dsk->bg.im) + Imlib_destroy_image(imd, dsk->bg.im); + dsk->top.im = NULL; + dsk->bg.im = NULL; + } + if (setbg) + { + if (dpmap) + { + SetBG(win, dpmap, 0); + } + else + { + SetBG(win, 0, dsk->bg.solid.pixel); + } + dsk->pmap = dpmap; + } + else + { + if (dpmap) + { + if (!gc) + gc = XCreateGC(disp, dpmap, 0, &gcv); + XSetClipMask(disp, gc, 0); + XSetTile(disp, gc, dpmap); + XSetTSOrigin(disp, gc, 0, 0); + XSetFillStyle(disp, gc, FillTiled); + XFillRectangle(disp, win, gc, 0, 0, rw, rh); + Imlib_free_pixmap(imd, dpmap); + } + else + { + if (!gc) + gc = XCreateGC(disp, win, 0, &gcv); + XSetClipMask(disp, gc, 0); + XSetFillStyle(disp, gc, FillSolid); + XSetForeground(disp, gc, dsk->bg.solid.pixel); + XFillRectangle(disp, win, gc, 0, 0, rw, rh); + } + XSync(disp, False); + } + if (gc) + XFreeGC(disp, gc); + Imlib_set_render_type(imd, rt); + + EDBUG_RETURN_; + +} + +void +InitDesktopBgs() +{ + int i; + Desk *d; + Atom at; + + EDBUG(6, "InitDesktopBgs"); + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + { + d = &desks.desk[i]; + d->bg = NULL; + deskorder[i] = i; + d->num = 0; + d->list = NULL; + d->tag = NULL; + d->x = 0; + d->y = 0; + d->current_area_x = 0; + d->current_area_y = 0; + if (i == 0) + { + d->win = root.win; + d->viewable = 0; + } + else + { + d->win = ECreateWindow(root.win, 0, 0, root.w, root.h, 0); + XSelectInput(disp, d->win, + SubstructureNotifyMask | ButtonPressMask | + ButtonReleaseMask | EnterWindowMask | + LeaveWindowMask | ButtonMotionMask | + PropertyChangeMask | SubstructureRedirectMask | + KeyPressMask | KeyReleaseMask | PointerMotionMask); + d->viewable = 0; + } + at = XInternAtom(disp, "ENLIGHTENMENT_DESKTOP", False); + XChangeProperty(disp, d->win, at, XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)&i, 1); +/* I don't believe it.. this property causes xv and Xscreensaver to barf + * stupid bloody clients - I cant' believe peope write such shitty code + */ +/* + * at = XInternAtom(disp, "__SWM_VROOT", False); + * XChangeProperty(disp, d->win, at, XA_CARDINAL, 32, PropModeReplace, + * (unsigned char *)&i, 1); + */ + } + + EDBUG_RETURN_; + +} + +void +InitDesktopControls() +{ + int i; + ActionClass *ac, *ac2, *ac3; + ImageClass *ic, *ic2, *ic3, *ic4; + Button *b; + Action *a; + int x[3], y[3], w[3], h[3], m, n, o; + char s[512], *param; + + EDBUG(6, "InitDesktopControls"); + + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + { + Esnprintf(s, sizeof(s), "DRAGBAR_DESKTOP_%i", i); + ac = FindItem(s, 0, LIST_FINDBY_NAME, LIST_TYPE_ACLASS); + if (!ac) + { + ac = CreateAclass(s); + AddItem(ac, ac->name, 0, LIST_TYPE_ACLASS); + a = CreateAction(EVENT_MOUSE_DOWN, 0, 0, 0, 1, 0, NULL, NULL); + AddAction(ac, a); + param = Emalloc(3); + Esnprintf(param, 3, "%i", i); + AddToAction(a, ACTION_DESKTOP_DRAG, param); + a = CreateAction(EVENT_MOUSE_DOWN, 0, 0, 0, 3, 0, NULL, NULL); + AddAction(ac, a); + Esnprintf(s, sizeof(s), "deskmenu"); + AddToAction(a, ACTION_SHOW_MENU, duplicate(s)); + a = CreateAction(EVENT_MOUSE_DOWN, 0, 0, 0, 2, 0, NULL, NULL); + AddAction(ac, a); + Esnprintf(s, sizeof(s), "taskmenu"); + AddToAction(a, ACTION_SHOW_MENU, duplicate(s)); + if (i > 0) + { + ac->tooltipstring = duplicate("Hold down the mouse button " + "and drag\n" + "the mouse to be able to " + "drag the desktop\n" + "back and forth.\n" + "Click right mouse button " + "for a list of all\n" + "Desktops and their " + "applications.\n" + "Click middle mouse button " + "for a list of all\n" + "applications currently" + " running.\n"); + } + else + { + ac->tooltipstring = duplicate("This is the Root desktop.\n" + "You cannot drag the " + "root desktop around.\n" + "Click right mouse button " + "for a list of all\n" + "Desktops and their " + "applications.\n" + "Click middle mouse button " + "for a list of all\n" + "applications currently " + "running.\n"); + } + } + Esnprintf(s, sizeof(s), "RAISEBUTTON_DESKTOP_%i", i); + ac2 = FindItem(s, 0, LIST_FINDBY_NAME, LIST_TYPE_ACLASS); + if (!ac2) + { + ac2 = CreateAclass(s); + AddItem(ac2, ac2->name, 0, LIST_TYPE_ACLASS); + a = CreateAction(EVENT_MOUSE_UP, 1, 0, 1, 0, 0, NULL, NULL); + AddAction(ac2, a); + param = Emalloc(3); + Esnprintf(param, 3, "%i", i); + AddToAction(a, ACTION_DESKTOP_RAISE, param); + ac2->tooltipstring = duplicate("Click here to raise this desktop\n" + "to the top.\n"); + } + Esnprintf(s, sizeof(s), "LOWERBUTTON_DESKTOP_%i", i); + ac3 = FindItem(s, 0, LIST_FINDBY_NAME, LIST_TYPE_ACLASS); + if (!ac3) + { + ac3 = CreateAclass(s); + AddItem(ac3, ac3->name, 0, LIST_TYPE_ACLASS); + a = CreateAction(EVENT_MOUSE_UP, 1, 0, 1, 0, 0, NULL, NULL); + AddAction(ac3, a); + param = Emalloc(3); + Esnprintf(param, 3, "%i", i); + AddToAction(a, ACTION_DESKTOP_LOWER, param); + ac3->tooltipstring = duplicate("Click here to lower this desktop\n" + "to the bottom.\n"); + } + b = NULL; + + if (desks.dragdir < 2) + { + ic = FindItem("DESKTOP_DRAGBUTTON_VERT", 0, LIST_FINDBY_NAME, + LIST_TYPE_ICLASS); + ic2 = FindItem("DESKTOP_RAISEBUTTON_VERT", 0, LIST_FINDBY_NAME, + LIST_TYPE_ICLASS); + ic3 = FindItem("DESKTOP_LOWERBUTTON_VERT", 0, LIST_FINDBY_NAME, + LIST_TYPE_ICLASS); + ic4 = FindItem("DESKTOP_DESKRAY_VERT", 0, LIST_FINDBY_NAME, + LIST_TYPE_ICLASS); + } + else + { + ic = FindItem("DESKTOP_DRAGBUTTON_HORIZ", 0, LIST_FINDBY_NAME, + LIST_TYPE_ICLASS); + ic2 = FindItem("DESKTOP_RAISEBUTTON_HORIZ", 0, LIST_FINDBY_NAME, + LIST_TYPE_ICLASS); + ic3 = FindItem("DESKTOP_LOWERBUTTON_HORIZ", 0, LIST_FINDBY_NAME, + LIST_TYPE_ICLASS); + ic4 = FindItem("DESKTOP_DESKRAY_HORIZ", 0, LIST_FINDBY_NAME, + LIST_TYPE_ICLASS); + } + + switch (desks.dragbar_ordering) + { + case 0: + m = 0; + n = 1; + o = 2; + break; + case 1: + m = 0; + n = 2; + o = 1; + break; + case 2: + m = 2; + n = 0; + o = 1; + break; + case 3: + m = 1; + n = 0; + o = 2; + break; + case 4: + m = 1; + n = 2; + o = 0; + break; + case 5: + m = 2; + n = 1; + o = 0; + break; + default: + m = 0; + n = 1; + o = 2; + break; + } + + switch (desks.dragdir) + { + case 0: + w[0] = w[1] = w[2] = h[0] = h[1] = desks.dragbar_width; + if (desks.dragbar_length == 0) + h[2] = root.h - (desks.dragbar_width * 2); + else + h[2] = desks.dragbar_length; + x[0] = x[1] = x[2] = 0; + y[m] = 0; + y[n] = y[m] + h[m]; + y[o] = y[n] + h[n]; + break; + case 1: + w[0] = w[1] = w[2] = h[0] = h[1] = desks.dragbar_width; + if (desks.dragbar_length == 0) + h[2] = root.h - (desks.dragbar_width * 2); + else + h[2] = desks.dragbar_length; + x[0] = x[1] = x[2] = root.w - desks.dragbar_width; + y[m] = 0; + y[n] = y[m] + h[m]; + y[o] = y[n] + h[n]; + break; + case 2: + h[0] = h[1] = h[2] = w[0] = w[1] = desks.dragbar_width; + if (desks.dragbar_length == 0) + w[2] = root.w - (desks.dragbar_width * 2); + else + w[2] = desks.dragbar_length; + y[0] = y[1] = y[2] = 0; + x[m] = 0; + x[n] = x[m] + w[m]; + x[o] = x[n] + w[n]; + break; + case 3: + h[0] = h[1] = h[2] = w[0] = w[1] = desks.dragbar_width; + if (desks.dragbar_length == 0) + w[2] = root.w - (desks.dragbar_width * 2); + else + w[2] = desks.dragbar_length; + y[0] = y[1] = y[2] = root.h - desks.dragbar_width; + x[m] = 0; + x[n] = x[m] + w[m]; + x[o] = x[n] + w[n]; + break; + default: + break; + } + + if (desks.dragbar_width > 0) + { + b = CreateButton("_DESKTOP_DRAG_CONTROL", ic2, ac2, NULL, NULL, -1, + FLAG_FIXED, 1, 99999, 1, 99999, 0, 0, x[0], 0, + y[0], 0, 0, w[0], 0, h[0], 0, i, 0); + AddItem(b, b->name, 1, LIST_TYPE_BUTTON); + b = CreateButton("_DESKTOP_DRAG_CONTROL", ic3, ac3, NULL, NULL, -1, + FLAG_FIXED, 1, 99999, 1, 99999, 0, 0, x[1], 0, + y[1], 0, 0, w[1], 0, h[1], 0, i, 0); + AddItem(b, b->name, 1, LIST_TYPE_BUTTON); + b = CreateButton("_DESKTOP_DRAG_CONTROL", ic, ac, NULL, NULL, -1, + FLAG_FIXED, 1, 99999, 1, 99999, 0, 0, x[2], + 0, y[2], 0, 0, w[2], 0, h[2], 0, i, 0); + AddItem(b, b->name, 1, LIST_TYPE_BUTTON); + } + if (i > 0) + { + if (desks.dragdir == 0) + { + b = CreateButton("_DESKTOP_DESKRAY_DRAG_CONTROL", ic4, ac, + NULL, NULL, 1, FLAG_FIXED_VERT, 1, 99999, 1, + 99999, 0, 0, desks.desk[i].x, 0, + desks.desk[i].y, 0, 0, 0, 0, 0, 1, 0, 1); + } + else if (desks.dragdir == 1) + { + b = CreateButton("_DESKTOP_DESKRAY_DRAG_CONTROL", ic4, ac, + NULL, NULL, 1, FLAG_FIXED_VERT, 1, + 99999, 1, 99999, 0, 0, + desks.desk[i].x + root.w + - desks.dragbar_width, + 0, desks.desk[i].y, 0, 0, 0, 0, 0, 1, 0, 1); + } + else if (desks.dragdir == 2) + { + b = CreateButton("_DESKTOP_DESKRAY_DRAG_CONTROL", ic4, ac, + NULL, NULL, 1, FLAG_FIXED_HORIZ, 1, 99999, 1, + 99999, 0, 0, desks.desk[i].x, 0, + desks.desk[i].y, 0, 0, 0, 0, 0, 1, 0, 1); + } + else + { + b = CreateButton("_DESKTOP_DESKRAY_DRAG_CONTROL", ic4, ac, + NULL, NULL, 1, FLAG_FIXED_HORIZ, 1, 99999, 1, + 99999, 0, 0, desks.desk[i].x, 0, + desks.desk[i].y + root.h - desks.dragbar_width, + 0, 0, 0, 0, 0, 1, 0, 1); + } + AddItem(b, b->name, 2, LIST_TYPE_BUTTON); + desks.desk[i].tag = b; + } + else + desks.desk[i].tag = NULL; + } + EDBUG_RETURN_; +} + +void +SetDesktopBg(int desk, Background * bg) +{ + EDBUG(5, "SetDesktopBg"); + + if (desk < 0) + EDBUG_RETURN_; + if (desk >= ENLIGHTENMENT_CONF_NUM_DESKTOPS) + EDBUG_RETURN_; + + if (desks.desk[desk].bg) + { + if (desks.desk[desk].bg != bg) + { + desks.desk[desk].bg->ref_count--; + if (bg) + bg->ref_count++; + } + } + desks.desk[desk].bg = bg; + if (desks.desk[desk].viewable) + RefreshDesktop(desk); + if (desk == desks.current) + { + RedrawPagersForDesktop(desk, 2); + ForceUpdatePagersForDesktop(desk); + } + else + RedrawPagersForDesktop(desk, 1); + EDBUG_RETURN_; +} + +void +ConformEwinToDesktop(EWin * ewin) +{ + int xo, yo; + + EDBUG(3, "ConformEwinToDesktop"); + + if ((ewin->iconified) && + (ewin->parent != desks.desk[ewin->desktop].win)) + { + ewin->parent = desks.desk[ewin->desktop].win; + DesktopAddEwinToTop(ewin); + EReparentWindow(disp, ewin->win, desks.desk[ewin->desktop].win, + ewin->x, ewin->y); + ICCCM_Configure(ewin); + StackDesktops(); + GNOME_SetEwinDesk(ewin); + EDBUG_RETURN_; + } + if (ewin->floating) + { + DesktopRemoveEwin(ewin); + xo = desks.desk[ewin->desktop].x; + yo = desks.desk[ewin->desktop].y; + if ((ewin->parent != root.win) && (ewin->floating == 2)) + { + ewin->parent = root.win; + EReparentWindow(disp, ewin->win, root.win, ewin->x, ewin->y); + ewin->desktop = 0; + } + XRaiseWindow(disp, ewin->win); + ShowEdgeWindows(); + ICCCM_Configure(ewin); + GNOME_SetEwinDesk(ewin); + EDBUG_RETURN_; + } + if (ewin->parent != desks.desk[ewin->desktop].win) + { + ewin->parent = desks.desk[ewin->desktop].win; + DesktopAddEwinToTop(ewin); + EReparentWindow(disp, ewin->win, desks.desk[ewin->desktop].win, + ewin->x, ewin->y); + RaiseEwin(ewin); +/* ShowEwin(ewin); */ + ICCCM_Configure(ewin); + GNOME_SetEwinDesk(ewin); + StackDesktops(); + SetEwinToCurrentArea(ewin); + } + EDBUG_RETURN_; + +} + +int +DesktopAt(int x, int y) +{ + int i; + + EDBUG(3, "DesktopAt"); + + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + { + if ((x >= desks.desk[deskorder[i]].x) && + (x < (desks.desk[deskorder[i]].x + root.w)) && + (y >= desks.desk[deskorder[i]].y) && + (y < (desks.desk[deskorder[i]].y + root.h))) + EDBUG_RETURN(deskorder[i]); + } + + EDBUG_RETURN(0); +} + +void +MoveStickyWindowsToCurrentDesk(void) +{ + EWin **lst, *ewin, *last_ewin; + int i, num; + + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if ((lst) && (num > 0)) + { + last_ewin = NULL; + for (i = 0; i < num; i++) + { + ewin = (EWin *) lst[i]; + if (ewin->sticky) + { + DesktopRemoveEwin(ewin); + ewin->desktop = DESKTOPS_WRAP_NUM(desks.current); + ewin->parent = desks.desk[ewin->desktop].win; + EReparentWindow(disp, ewin->win, desks.desk[ewin->desktop].win, + root.w, root.h); + XLowerWindow(disp, ewin->win); + EMoveWindow(disp, ewin->win, ewin->x, ewin->y); + DesktopAddEwinToTop(ewin); + last_ewin = ewin; + } + } + if (last_ewin) + RestackEwin(last_ewin); + Efree(lst); + } +} + +void +GotoDesktop(int num) +{ + int x, y, pdesk; + + EDBUG(2, "GotoDesktop"); + + if (num < 0) + EDBUG_RETURN_; + if (num >= mode.numdesktops) + EDBUG_RETURN_; + if (num == desks.current) + EDBUG_RETURN_; + pdesk = desks.current; + + if (mode.slideout) + HideSlideout(mode.slideout, mode.context_win); + + if ((mode.mode == MODE_RESIZE) || + (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V)) + { + doResizeEnd(NULL); + } + else if ((mode.mode == MODE_MOVE) && (mode.ewin)) + { + if ((mode.movemode > 0) && (!mode.moveresize_pending_ewin)) + { + if (mode.ewin) + { + x = mode.ewin->x; + y = mode.ewin->y; + mode.ewin->x = -99999; + mode.ewin->y = -99999; + mode.ewin->reqx = -99999; + mode.ewin->reqy = -99999; + DrawEwinShape(mode.ewin, mode.movemode, + x, y, + mode.ewin->client.w, mode.ewin->client.h, + 3); + } + } + else + { + FloatEwinAt(mode.ewin, mode.ewin->x + + desks.desk[mode.ewin->desktop].x, + mode.ewin->y + desks.desk[mode.ewin->desktop].y); + } + } + BeginNewDeskFocus(); + CloneDesktop(desks.current); + ICCCM_Cmap(NULL); + desks.current = num; + MoveStickyWindowsToCurrentDesk(); + GNOME_SetCurrentDesk(); + + if (num > 0) + { + if (desks.slidein) + { + if (!desks.desk[num].viewable) + { + switch (desks.dragdir) + { + case 0: + MoveDesktop(num, root.w, 0); + RaiseDesktop(num); + SlideWindowTo(desks.desk[num].win, root.w, + 0, 0, 0, desks.slidespeed); + break; + case 1: + MoveDesktop(num, -root.w, 0); + RaiseDesktop(num); + SlideWindowTo(desks.desk[num].win, -root.w, + 0, 0, 0, desks.slidespeed); + break; + case 2: + MoveDesktop(num, 0, root.h); + RaiseDesktop(num); + SlideWindowTo(desks.desk[num].win, 0, + root.h, 0, 0, desks.slidespeed); + break; + case 3: + MoveDesktop(num, 0, -root.h); + RaiseDesktop(num); + SlideWindowTo(desks.desk[num].win, 0, + -root.h, 0, 0, desks.slidespeed); + break; + default: + break; + } + } + else + { + GetWinXY(desks.desk[num].win, &x, &y); + SlideWindowTo(desks.desk[num].win, desks.desk[num].x, + desks.desk[num].y, 0, 0, desks.slidespeed); + RaiseDesktop(num); + } + StackDesktops(); + } + else + { + RaiseDesktop(num); + StackDesktops(); + } + MoveDesktop(num, 0, 0); + } + else + { + RaiseDesktop(num); + } + + mode.moveresize_pending_ewin = NULL; + + if ((mode.mode == MODE_MOVE) && (mode.movemode > 0) && (mode.ewin)) + { + if (mode.ewin) + { + XLowerWindow(disp, mode.ewin->win); + x = mode.ewin->x; + y = mode.ewin->y; + mode.ewin->x = -99999; + mode.ewin->y = -99999; + mode.ewin->reqx = -99999; + mode.ewin->reqy = -99999; + if (mode.movemode == 5) + { + DrawEwinShape(mode.ewin, mode.movemode, x, y, + mode.ewin->client.w, mode.ewin->client.h, + 4); + } + else + { + DrawEwinShape(mode.ewin, mode.movemode, x, y, + mode.ewin->client.w, mode.ewin->client.h, + 0); + } + } + } + NewDeskFocus(); + FX_DeskChange(); + RemoveClones(); + RedrawPagersForDesktop(num, 3); + ForceUpdatePagersForDesktop(num); + UpdatePagerSel(); + HandleDrawQueue(); + EDBUG_RETURN_; +} + +void +MoveDesktop(int num, int x, int y) +{ + int i; + EWin **lst; + int n, v, dx, dy; + + EDBUG(3, "MoveDesktop"); + if (num < 0) + EDBUG_RETURN_; + if (num >= mode.numdesktops) + EDBUG_RETURN_; + if (num == 0) + EDBUG_RETURN_; + dx = x - desks.desk[num].x; + dy = y - desks.desk[num].y; + if ((x == 0) && (y == 0)) + { + n = -1; + i = 0; + while ((n < 0) && (i < ENLIGHTENMENT_CONF_NUM_DESKTOPS)) + { + if (deskorder[i] == num) + n = i; + i++; + } + if (n >= 0) + { + for (i = n + 1; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + { + if ((desks.desk[deskorder[i]].viewable) + && (desks.desk[deskorder[i]].bg)) + desks.desk[deskorder[i]].bg->last_viewed = time(NULL); + desks.desk[deskorder[i]].viewable = 0; + } + } + } + else + { + n = -1; + i = 0; + + while ((n < 0) && (i < ENLIGHTENMENT_CONF_NUM_DESKTOPS)) + { + if (deskorder[i] == num) + n = i; + i++; + } + + if (n >= 0) + { + if (desks.desk[deskorder[n]].viewable) + { + v = 1; + } + else + { + v = 0; + } + + for (i = n + 1; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + { + + if ((!desks.desk[deskorder[i]].viewable) && (v)) + { + desks.desk[deskorder[i]].viewable = v; + RefreshDesktop(deskorder[i]); + } + else + { + if ((!v) && (desks.desk[deskorder[i]].viewable) + && (desks.desk[deskorder[i]].bg)) + { + desks.desk[deskorder[i]].bg->last_viewed = time(NULL); + } + desks.desk[deskorder[i]].viewable = v; + } + + if ((desks.desk[deskorder[i]].x == 0) && + (desks.desk[deskorder[i]].y == 0)) + { + v = 0; + } + } + } + } + + EMoveWindow(disp, desks.desk[num].win, x, y); + + if (desks.desk[num].tag) + { + MovebuttonToCoord(desks.desk[num].tag, + desks.desk[num].tag->x + dx, + desks.desk[num].tag->y + dy); + } + desks.desk[num].x = x; + desks.desk[num].y = y; + + lst = (EWin **) ListItemType(&n, LIST_TYPE_EWIN); + if (lst) + { + for (i = 0; i < n; i++) + if (lst[i]->desktop == num) + ICCCM_Configure(lst[i]); + Efree(lst); + } + EDBUG_RETURN_; + +} + +void +RaiseDesktop(int num) +{ + int i; + + EDBUG(3, "RaiseDesktop"); + + if ((num < 0) || (num >= mode.numdesktops)) + EDBUG_RETURN_; + + BeginNewDeskFocus(); + CloneDesktop(deskorder[0]); + desks.desk[num].viewable = 1; + RefreshDesktop(num); + MoveToDeskTop(num); + + if (num == 0) + { + for (i = ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1; i > 0; i--) + { + HideDesktop(deskorder[i]); + } + } + StackDesktops(); + desks.current = num; + MoveStickyWindowsToCurrentDesk(); + NewDeskFocus(); + FX_DeskChange(); + RemoveClones(); + RedrawPagersForDesktop(num, 3); + ForceUpdatePagersForDesktop(num); + UpdatePagerSel(); + HandleDrawQueue(); + GNOME_SetCurrentDesk(); + EMapWindow(disp, desks.desk[num].win); + XSync(disp, False); + + EDBUG_RETURN_; + +} + +void +LowerDesktop(int num) +{ + EDBUG(3, "LowerDesktop"); + + if ((num < 0) || (num >= mode.numdesktops)) + EDBUG_RETURN_; + + BeginNewDeskFocus(); + CloneDesktop(num); + MoveToDeskBottom(num); + UncoverDesktop(deskorder[0]); + HideDesktop(num); + StackDesktops(); + desks.current = deskorder[0]; + MoveStickyWindowsToCurrentDesk(); + NewDeskFocus(); + FX_DeskChange(); + RemoveClones(); + RedrawPagersForDesktop(deskorder[0], 3); + ForceUpdatePagersForDesktop(deskorder[0]); + UpdatePagerSel(); + HandleDrawQueue(); + GNOME_SetCurrentDesk(); + XSync(disp, False); + + EDBUG_RETURN_; + +} + +void +HideDesktop(int num) +{ + EDBUG(3, "HideDesktop"); + + if ((num < 0) || (num >= mode.numdesktops)) + EDBUG_RETURN_; + if (num == 0) + EDBUG_RETURN_; + + if ((desks.desk[num].viewable) && (desks.desk[num].bg)) + desks.desk[num].bg->last_viewed = time(NULL); + desks.desk[num].viewable = 0; + EMoveWindow(disp, desks.desk[num].win, root.w, 0); + + EDBUG_RETURN_; + +} + +void +ShowDesktop(int num) +{ + int i; + + EDBUG(3, "ShowDesktop"); + + if (num < 0) + EDBUG_RETURN_; + if (num >= mode.numdesktops) + EDBUG_RETURN_; + + desks.desk[num].viewable = 1; + RefreshDesktop(num); + MoveToDeskTop(num); + + if (num == 0) + { + for (i = ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1; i > 0; i--) + HideDesktop(deskorder[i]); + } + else + { + StackDesktops(); + EMapWindow(disp, desks.desk[num].win); + } + + EDBUG_RETURN_; +} + +void +StackDesktops() +{ + Window *wl, *wl2; + int i, num, tot, bnum, n; + EWin **lst; + Button **blst; + + EDBUG(2, "StackDesktops"); + tot = 0; + wl = NULL; + + wl2 = ListProgressWindows(&n); + if (wl2) + { + tot += n; + wl = Erealloc(wl, tot * sizeof(Window)); + for (i = 0; i < n; i++) + wl[tot - n + i] = wl2[i]; + Efree(wl2); + } + if (init_win_ext) + { + tot += 1; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = init_win_ext; + } + if (init_win1) + { + tot += 2; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 2] = init_win1; + wl[tot - 1] = init_win2; + } + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + blst = (Button **) ListItemType(&bnum, LIST_TYPE_BUTTON); + + if (blst) + { + for (i = 0; i < bnum; i++) + { + if (blst[i]->sticky) + { + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = blst[i]->win; + } + } + } + if (lst) + { + for (i = 0; i < num; i++) + { + if ( /* ** (lst[i]->sticky) || */ (lst[i]->floating)) + { + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = lst[i]->win; + } + } + } + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + { + if (deskorder[i] == 0) + i = ENLIGHTENMENT_CONF_NUM_DESKTOPS; + else + { + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = desks.desk[deskorder[i]].win; + } + } + if (blst) + { + for (i = 0; i < bnum; i++) + { + if ((blst[i]->desktop == 0) && (blst[i]->ontop == 1) && + (!blst[i]->sticky)) + { + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = blst[i]->win; + } + } + } + for (i = 0; i < desks.desk[0].num; i++) + { + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = desks.desk[0].list[i]->win; + } + if (blst) + { + for (i = 0; i < bnum; i++) + { + if ((blst[i]->desktop == 0) && (blst[i]->ontop == -1) && + (!blst[i]->sticky)) + { + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = blst[i]->win; + } + } + } + tot++; + wl = Erealloc(wl, tot * sizeof(Window)); + wl[tot - 1] = desks.desk[0].win; + if (wl) + { + XRestackWindows(disp, wl, tot); + Efree(wl); + } + if (lst) + Efree(lst); + if (blst) + Efree(blst); + ShowEdgeWindows(); + EDBUG_RETURN_; +} + +void +UncoverDesktop(int num) +{ + EDBUG(3, "UncoverDesktop"); + if (num < 0) + EDBUG_RETURN_; + if (num >= mode.numdesktops) + EDBUG_RETURN_; + desks.desk[num].viewable = 1; + RefreshDesktop(num); + if (num != 0) + EMapWindow(disp, desks.desk[num].win); + EDBUG_RETURN_; +} + +void +MoveEwinToDesktop(EWin * ewin, int num) +{ + int pdesk; + + EDBUG(3, "MoveEwinToDesktop"); +/* ** ewin->sticky = 0; */ + ewin->floating = 0; + DesktopRemoveEwin(ewin); + pdesk = ewin->desktop; + ewin->desktop = DESKTOPS_WRAP_NUM(num); + DesktopAddEwinToTop(ewin); + ConformEwinToDesktop(ewin); + if (ewin->has_transients) + { + EWin **lst; + int i, nn; + + lst = ListTransientsFor(ewin->client.win, &nn); + if (lst) + { + for (i = 0; i < nn; i++) + { + MoveEwinToDesktop(lst[i], num); + } + Efree(lst); + } + } + ForceUpdatePagersForDesktop(pdesk); + ForceUpdatePagersForDesktop(ewin->desktop); + EDBUG_RETURN_; +} + +void +DesktopRemoveEwin(EWin * ewin) +{ + int i, j; + + EDBUG(5, "DesktopRemoveEwin"); + if ((ewin->desktop < 0) || (ewin->desktop > ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1)) + EDBUG_RETURN_; + for (i = 0; i < desks.desk[ewin->desktop].num; i++) + { + if (desks.desk[ewin->desktop].list[i] == ewin) + { + for (j = i; j < desks.desk[ewin->desktop].num - 1; j++) + desks.desk[ewin->desktop].list[j] = + desks.desk[ewin->desktop].list[j + 1]; + desks.desk[ewin->desktop].num--; + if (desks.desk[ewin->desktop].num <= 0) + { + desks.desk[ewin->desktop].num = 0; + if (desks.desk[ewin->desktop].list) + Efree(desks.desk[ewin->desktop].list); + desks.desk[ewin->desktop].list = NULL; + } + else + { + desks.desk[ewin->desktop].list = + Erealloc(desks.desk[ewin->desktop].list, + desks.desk[ewin->desktop].num * sizeof(EWin *)); + } + EDBUG_RETURN_; + } + } + EDBUG_RETURN_; +} + +void +DesktopAddEwinToTop(EWin * ewin) +{ + int i, j; + + EDBUG(5, "DesktopAddEwinToTop"); + if ((ewin->desktop < 0) || + (ewin->desktop > ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1)) + EDBUG_RETURN_; + + DesktopRemoveEwin(ewin); + desks.desk[ewin->desktop].num++; + if (desks.desk[ewin->desktop].list) + desks.desk[ewin->desktop].list = + Erealloc(desks.desk[ewin->desktop].list, + desks.desk[ewin->desktop].num * sizeof(EWin *)); + else + desks.desk[ewin->desktop].list = Emalloc(sizeof(EWin *)); + if (desks.desk[ewin->desktop].num == 1) + { + desks.desk[ewin->desktop].list[0] = ewin; + ForceUpdatePagersForDesktop(ewin->desktop); + EDBUG_RETURN_; + } + for (i = 0; i < desks.desk[ewin->desktop].num - 1; i++) + { + if (desks.desk[ewin->desktop].list[i]->layer <= ewin->layer) + { + for (j = desks.desk[ewin->desktop].num - 1; j > i; j--) + desks.desk[ewin->desktop].list[j] = + desks.desk[ewin->desktop].list[j - 1]; + desks.desk[ewin->desktop].list[i] = ewin; + ForceUpdatePagersForDesktop(ewin->desktop); + EDBUG_RETURN_; + } + } + desks.desk[ewin->desktop].list[desks.desk[ewin->desktop].num - 1] = ewin; + ForceUpdatePagersForDesktop(ewin->desktop); + EDBUG_RETURN_; +} + +void +DesktopAddEwinToBottom(EWin * ewin) +{ + int i, j; + + EDBUG(5, "DesktopAddEwinToBottom"); + if ((ewin->desktop < 0) || + (ewin->desktop > ENLIGHTENMENT_CONF_NUM_DESKTOPS - 1)) + EDBUG_RETURN_; + + DesktopRemoveEwin(ewin); + desks.desk[ewin->desktop].num++; + if (desks.desk[ewin->desktop].list) + desks.desk[ewin->desktop].list = + Erealloc(desks.desk[ewin->desktop].list, + desks.desk[ewin->desktop].num * sizeof(EWin *)); + else + desks.desk[ewin->desktop].list = Emalloc(sizeof(EWin *)); + if (desks.desk[ewin->desktop].num == 1) + { + desks.desk[ewin->desktop].list[0] = ewin; + ForceUpdatePagersForDesktop(ewin->desktop); + EDBUG_RETURN_; + } + for (i = 0; i < desks.desk[ewin->desktop].num - 1; i++) + { + if (desks.desk[ewin->desktop].list[i]->layer < ewin->layer) + { + for (j = desks.desk[ewin->desktop].num - 1; j > i; j--) + desks.desk[ewin->desktop].list[j] = + desks.desk[ewin->desktop].list[j - 1]; + desks.desk[ewin->desktop].list[i] = ewin; + ForceUpdatePagersForDesktop(ewin->desktop); + EDBUG_RETURN_; + } + } + desks.desk[ewin->desktop].list[desks.desk[ewin->desktop].num - 1] = ewin; + ForceUpdatePagersForDesktop(ewin->desktop); + EDBUG_RETURN_; +} + +void +MoveEwinToDesktopAt(EWin * ewin, int num, int x, int y) +{ + int dx, dy, pdesk; + + EDBUG(3, "MoveEwinToDesktopAt"); +/* ** ewin->sticky = 0; */ + pdesk = ewin->desktop; + ewin->floating = 0; + DesktopRemoveEwin(ewin); + ewin->desktop = DESKTOPS_WRAP_NUM(num); + DesktopAddEwinToTop(ewin); + dx = x - ewin->x; + dy = y - ewin->y; + ewin->x = x; + ewin->y = y; + ConformEwinToDesktop(ewin); + if (ewin->has_transients) + { + EWin **lst; + int i, nn; + + lst = ListTransientsFor(ewin->client.win, &nn); + if (lst) + { + for (i = 0; i < nn; i++) + { + MoveEwinToDesktopAt(lst[i], num, lst[i]->x + dx, lst[i]->y + dy); + } + Efree(lst); + } + } + ForceUpdatePagersForDesktop(pdesk); + ForceUpdatePagersForDesktop(ewin->desktop); + EDBUG_RETURN_; +} + +void +FloatEwinAboveDesktops(EWin * ewin) +{ + int xo, yo; + + EDBUG(2, "FloatEwinAboveDesktops"); + xo = desks.desk[ewin->desktop].x; + yo = desks.desk[ewin->desktop].y; + ewin->desktop = 0; + ewin->floating = 1; + ConformEwinToDesktop(ewin); + if (ewin->has_transients) + { + EWin **lst; + int i, num; + + lst = ListTransientsFor(ewin->client.win, &num); + if (lst) + { + for (i = 0; i < num; i++) + FloatEwinAboveDesktops(lst[i]); + Efree(lst); + } + } + EDBUG_RETURN_; +} + +void +DesktopAccounting() +{ + time_t now; + int i, j, num; + Background **lst; + ImlibData *imd = 0; + + EDBUG(3, "DesktopAccounting"); + now = time(NULL); + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + { + if ((desks.desk[i].bg) && (desks.desk[i].viewable)) + desks.desk[i].bg->last_viewed = now; + } + lst = (Background **) ListItemType(&num, LIST_TYPE_BACKGROUND); + if (lst) + { + for (i = 0; i < num; i++) + { + if (lst[i]->pmap) + { + if ((now - lst[i]->last_viewed) > mode.desktop_bg_timeout) + { + imd = id; + for (j = 0; j < ENLIGHTENMENT_CONF_NUM_DESKTOPS; j++) + { + if (desks.desk[j].bg == lst[i]) + { + if ((ird) && (j == 0)) + imd = ird; + else + imd = id; + j = ENLIGHTENMENT_CONF_NUM_DESKTOPS; + } + } + Imlib_free_pixmap(imd, lst[i]->pmap); + lst[i]->pmap = 0; + for (j = 0; j < ENLIGHTENMENT_CONF_NUM_DESKTOPS; j++) + { + if ((desks.desk[j].bg == lst[i]) + && (!desks.desk[j].viewable)) + SetBG(desks.desk[j].win, 0, 0); + } + } + } + } + Efree(lst); + } + EDBUG_RETURN_; +} diff --git a/src/dialog.c b/src/dialog.c new file mode 100644 index 00000000..3d03c968 --- /dev/null +++ b/src/dialog.c @@ -0,0 +1,1897 @@ +#include "E.h" +static ImageClass *d_ic_default = NULL; +static TextClass *d_tc_default = NULL; + +static void DialogRealizeTClassDefault(void); +static void DialogRealizeIClassDefault(void); + +static void +DialogRealizeTClassDefault(void) +{ + if (!d_tc_default) + { + d_tc_default = CreateTclass(); + d_tc_default->norm.normal = CreateTextState(); + d_tc_default->norm.normal->fontname = + duplicate("-*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*"); + d_tc_default->norm.normal->fg_col.r = 0; + d_tc_default->norm.normal->fg_col.g = 0; + d_tc_default->norm.normal->fg_col.b = 0; + } +} + +static void +DialogRealizeIClassDefault(void) +{ + if (!d_ic_default) + { + d_ic_default = CreateIclass(); + d_ic_default->name = NULL; + + d_ic_default->norm.normal = CreateImageState(); + d_ic_default->norm.normal->hihi.r = 255; + d_ic_default->norm.normal->hihi.g = 255; + d_ic_default->norm.normal->hihi.b = 255; + d_ic_default->norm.normal->hi.r = 220; + d_ic_default->norm.normal->hi.g = 220; + d_ic_default->norm.normal->hi.b = 220; + d_ic_default->norm.normal->bg.r = 160; + d_ic_default->norm.normal->bg.g = 160; + d_ic_default->norm.normal->bg.b = 160; + d_ic_default->norm.normal->lo.r = 100; + d_ic_default->norm.normal->lo.g = 100; + d_ic_default->norm.normal->lo.b = 100; + d_ic_default->norm.normal->lolo.r = 0; + d_ic_default->norm.normal->lolo.g = 0; + d_ic_default->norm.normal->lolo.b = 0; + d_ic_default->norm.normal->bevelstyle = BEVEL_NEXT; + + d_ic_default->norm.hilited = CreateImageState(); + d_ic_default->norm.hilited->hihi.r = 255; + d_ic_default->norm.hilited->hihi.g = 255; + d_ic_default->norm.hilited->hihi.b = 255; + d_ic_default->norm.hilited->hi.r = 240; + d_ic_default->norm.hilited->hi.g = 240; + d_ic_default->norm.hilited->hi.b = 240; + d_ic_default->norm.hilited->bg.r = 200; + d_ic_default->norm.hilited->bg.g = 200; + d_ic_default->norm.hilited->bg.b = 200; + d_ic_default->norm.hilited->lo.r = 160; + d_ic_default->norm.hilited->lo.g = 160; + d_ic_default->norm.hilited->lo.b = 160; + d_ic_default->norm.hilited->lolo.r = 0; + d_ic_default->norm.hilited->lolo.g = 0; + d_ic_default->norm.hilited->lolo.b = 0; + d_ic_default->norm.hilited->bevelstyle = BEVEL_NEXT; + + d_ic_default->norm.clicked = CreateImageState(); + d_ic_default->norm.clicked->hihi.r = 0; + d_ic_default->norm.clicked->hihi.g = 0; + d_ic_default->norm.clicked->hihi.b = 0; + d_ic_default->norm.clicked->hi.r = 100; + d_ic_default->norm.clicked->hi.g = 100; + d_ic_default->norm.clicked->hi.b = 100; + d_ic_default->norm.clicked->bg.r = 160; + d_ic_default->norm.clicked->bg.g = 160; + d_ic_default->norm.clicked->bg.b = 160; + d_ic_default->norm.clicked->lo.r = 220; + d_ic_default->norm.clicked->lo.g = 220; + d_ic_default->norm.clicked->lo.b = 220; + d_ic_default->norm.clicked->lolo.r = 255; + d_ic_default->norm.clicked->lolo.g = 255; + d_ic_default->norm.clicked->lolo.b = 255; + d_ic_default->norm.clicked->bevelstyle = BEVEL_NEXT; + + d_ic_default->active.normal = CreateImageState(); + d_ic_default->active.normal->hihi.r = 0; + d_ic_default->active.normal->hihi.g = 0; + d_ic_default->active.normal->hihi.b = 0; + d_ic_default->active.normal->hi.r = 100; + d_ic_default->active.normal->hi.g = 100; + d_ic_default->active.normal->hi.b = 100; + d_ic_default->active.normal->bg.r = 160; + d_ic_default->active.normal->bg.g = 160; + d_ic_default->active.normal->bg.b = 160; + d_ic_default->active.normal->lo.r = 220; + d_ic_default->active.normal->lo.g = 220; + d_ic_default->active.normal->lo.b = 220; + d_ic_default->active.normal->lolo.r = 255; + d_ic_default->active.normal->lolo.g = 255; + d_ic_default->active.normal->lolo.b = 255; + d_ic_default->active.normal->bevelstyle = BEVEL_NEXT; + + d_ic_default->active.hilited = CreateImageState(); + d_ic_default->active.hilited->hihi.r = 0; + d_ic_default->active.hilited->hihi.g = 0; + d_ic_default->active.hilited->hihi.b = 0; + d_ic_default->active.hilited->hi.r = 100; + d_ic_default->active.hilited->hi.g = 100; + d_ic_default->active.hilited->hi.b = 100; + d_ic_default->active.hilited->bg.r = 160; + d_ic_default->active.hilited->bg.g = 160; + d_ic_default->active.hilited->bg.b = 160; + d_ic_default->active.hilited->lo.r = 220; + d_ic_default->active.hilited->lo.g = 220; + d_ic_default->active.hilited->lo.b = 220; + d_ic_default->active.hilited->lolo.r = 255; + d_ic_default->active.hilited->lolo.g = 255; + d_ic_default->active.hilited->lolo.b = 255; + d_ic_default->active.hilited->bevelstyle = BEVEL_NEXT; + + d_ic_default->active.clicked = CreateImageState(); + d_ic_default->active.clicked->hihi.r = 0; + d_ic_default->active.clicked->hihi.g = 0; + d_ic_default->active.clicked->hihi.b = 0; + d_ic_default->active.clicked->hi.r = 100; + d_ic_default->active.clicked->hi.g = 100; + d_ic_default->active.clicked->hi.b = 100; + d_ic_default->active.clicked->bg.r = 160; + d_ic_default->active.clicked->bg.g = 160; + d_ic_default->active.clicked->bg.b = 160; + d_ic_default->active.clicked->lo.r = 220; + d_ic_default->active.clicked->lo.g = 220; + d_ic_default->active.clicked->lo.b = 220; + d_ic_default->active.clicked->lolo.r = 255; + d_ic_default->active.clicked->lolo.g = 255; + d_ic_default->active.clicked->lolo.b = 255; + d_ic_default->active.clicked->bevelstyle = BEVEL_NEXT; + + d_ic_default->padding.left = 8; + d_ic_default->padding.right = 8; + d_ic_default->padding.top = 8; + d_ic_default->padding.bottom = 8; + } + IclassPopulate(d_ic_default); +} + +void +DialogBindKey(Dialog * d, char *key, void (*func) (int val, void *data), + int val, void *data) +{ + d->num_bindings++; + if (!d->keybindings) + d->keybindings = Emalloc(sizeof(DKeyBind) * d->num_bindings); + else + d->keybindings = Erealloc(d->keybindings, sizeof(DKeyBind) * d->num_bindings); + d->keybindings[d->num_bindings - 1].val = val; + d->keybindings[d->num_bindings - 1].data = data; + d->keybindings[d->num_bindings - 1].func = func; + d->keybindings[d->num_bindings - 1].key = + XKeysymToKeycode(disp, XStringToKeysym(key));; +} + +Dialog * +CreateDialog(char *name) +{ + Dialog *d; + + d = Emalloc(sizeof(Dialog)); + d->name = duplicate(name); + d->title = NULL; + d->text = NULL; + d->num_buttons = 0; + d->win = 0; + d->button = NULL; + d->win = ECreateWindow(root.win, -20, -20, 2, 2, 0); + + d->item = NULL; + d->exit_func = NULL; + d->exit_val = 0; + d->exit_data = NULL; + + d->tclass = FindItem("DIALOG", 0, LIST_FINDBY_NAME, LIST_TYPE_TCLASS); + if (!d->tclass) + { + DialogRealizeTClassDefault(); + d->tclass = d_tc_default; + } + if (d->tclass) + d->tclass->ref_count++; + + d->iclass = FindItem("DIALOG", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (!d->iclass) + { + DialogRealizeIClassDefault(); + d->iclass = d_ic_default; + } + if (d->iclass) + d->iclass->ref_count++; + d->num_bindings = 0; + d->keybindings = NULL; + + return d; +} + +void +FreeDButton(DButton * db) +{ + if (db->text) + Efree(db->text); + if (db->iclass) + db->iclass->ref_count--; + if (db->tclass) + db->tclass->ref_count--; + Efree(db); +} + +void +FreeDialog(Dialog * d) +{ + int i; + + if (d->name) + Efree(d->name); + if (d->title) + Efree(d->title); + if (d->text) + Efree(d->text); + for (i = 0; i < d->num_buttons; i++) + FreeDButton(d->button[i]); + if (d->button) + Efree(d->button); + if (d->item) + DialogFreeItem(d->item); + if (d->iclass) + d->iclass->ref_count--; + if (d->tclass) + d->tclass->ref_count--; + if (d->keybindings) + Efree(d->keybindings); + Efree(d); +} + +void +DialogRestart(int val, void *data) +{ + doExit("restart"); + val = 0; + data = NULL; +} + +void +DialogQuit(int val, void *data) +{ + doExit("error"); + val = 0; + data = NULL; +} + +void +DialogAlert(char *fmt,...) +{ + char text[10240]; + va_list ap; + + SC_Kill(); + va_start(ap, fmt); + Evsnprintf(text, 10240, fmt, ap); + va_end(ap); + Alert(text); +} + +void +DialogAlertOK(char *fmt,...) +{ + char text[10240]; + va_list ap; + + va_start(ap, fmt); + Evsnprintf(text, 10240, fmt, ap); + va_end(ap); + ASSIGN_ALERT("Attention !!!", "OK", " ", " "); + Alert(text); + RESET_ALERT; +} + +void +DialogSetParamText(Dialog * d, char *fmt,...) +{ + char text[10240]; + va_list ap; + + va_start(ap, fmt); + Evsnprintf(text, 10240, fmt, ap); + va_end(ap); + DialogSetText(d, text); +} + +void +DialogSetText(Dialog * d, char *text) +{ + int w, h; + + if (d->text) + Efree(d->text); + + d->text = duplicate(text); + if ((!d->tclass) || (!d->iclass)) + return; + TextSize(d->tclass, 0, 0, STATE_NORMAL, text, &w, &h, 17); + d->w = w + d->iclass->padding.left + d->iclass->padding.right; + d->h = h + d->iclass->padding.top + d->iclass->padding.bottom; +} + +void +DialogSetTitle(Dialog * d, char *title) +{ + if (d->title) + Efree(d->title); + d->title = duplicate(title); +} + +void +DialogSetExitFunction(Dialog * d, void (*func) (int val, void *data), + int val, void *data) +{ + d->exit_func = func; + d->exit_val = val; + d->exit_data = data; +} + +void +DialogAddButton(Dialog * d, char *text, void (*func) (int val, void *data), + char close) +{ + DButton *db; + int w, h; + + db = Emalloc(sizeof(DButton)); + d->num_buttons++; + d->button = Erealloc(d->button, d->num_buttons * (sizeof(DButton *))); + d->button[d->num_buttons - 1] = db; + db->text = duplicate(text); + db->func = func; + db->win = ECreateWindow(d->win, -20, -20, 2, 2, 0); + EMapWindow(disp, db->win); + db->x = -1; + db->y = -1; + db->w = -1; + db->h = -1; + db->hilited = 0; + db->clicked = 0; + db->close = close; + + db->tclass = FindItem("DIALOG_BUTTON", 0, + LIST_FINDBY_NAME, LIST_TYPE_TCLASS); + if (!db->tclass) + { + DialogRealizeTClassDefault(); + db->tclass = d_tc_default; + } + if (db->tclass) + db->tclass->ref_count++; + + db->iclass = FindItem("DIALOG_BUTTON", 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (!db->iclass) + { + DialogRealizeTClassDefault(); + db->iclass = d_ic_default; + } + if (db->iclass) + db->iclass->ref_count++; + + TextSize(db->tclass, 0, 0, STATE_NORMAL, text, &w, &h, 17); + db->w = w + db->iclass->padding.left + db->iclass->padding.right; + db->h = h + db->iclass->padding.top + db->iclass->padding.bottom; + XSelectInput(disp, db->win, EnterWindowMask | LeaveWindowMask | + ButtonPressMask | ButtonReleaseMask | ExposureMask); +} + +void +DialogDrawButton(Dialog * d, int bnum) +{ + int state; + + state = STATE_NORMAL; + if ((d->button[bnum]->hilited) && (d->button[bnum]->clicked)) + { + state = STATE_CLICKED; + } + else if ((d->button[bnum]->hilited) && (!d->button[bnum]->clicked)) + { + state = STATE_HILITED; + } + else if (!(d->button[bnum]->hilited) && (d->button[bnum]->clicked)) + { + state = STATE_CLICKED; + } + IclassApply(d->button[bnum]->iclass, d->button[bnum]->win, + d->button[bnum]->w, d->button[bnum]->h, 0, 0, + state, 0); + TclassApply(d->button[bnum]->iclass, d->button[bnum]->win, + d->button[bnum]->w, d->button[bnum]->h, + 0, 0, state, 1, d->button[bnum]->tclass, + d->button[bnum]->text); +} + +void +DialogActivateButton(Window win, int inclick) +{ + Dialog *d; + int bnum; + char doact = 0; + + d = FindDialogButton(win, &bnum); + if (!d) + return; + if ((d->button[bnum]->hilited) && (d->button[bnum]->clicked) && + (inclick == 3)) + doact = 1; + if (inclick == 0) + d->button[bnum]->hilited = 1; + if (inclick == 1) + d->button[bnum]->hilited = 0; + if (inclick == 2) + d->button[bnum]->clicked = 1; + if (inclick == 3) + d->button[bnum]->clicked = 0; + DialogDrawButton(d, bnum); + if ((doact) && (d->button[bnum]->func)) + (d->button[bnum]->func) (bnum, d); + if ((doact) && (d->button[bnum]->close)) + DialogClose(d); +} + +void +DialogDraw(Dialog * d) +{ + if ((!d->tclass) || (!d->iclass)) + return; + + if (d->text) + { + TclassApply(d->iclass, d->win, d->w, d->h, + 0, 0, STATE_NORMAL, 1, d->tclass, + d->text); + } + else if (d->item) + { + DialogDrawItems(d, d->item, 0, 0, 99999, 99999); + } +} + +void +DialogDrawArea(Dialog * d, int x, int y, int w, int h) +{ + if ((!d->tclass) || (!d->iclass)) + return; + + if (d->text) + { + TclassApply(d->iclass, d->win, d->w, d->h, + 0, 0, STATE_NORMAL, 1, d->tclass, + d->text); + } + else if (d->item) + { + DialogDrawItems(d, d->item, x, y, w, h); + } +} + +void +DialogRedraw(Dialog * d) +{ + int i; + + if ((!d->tclass) || (!d->iclass)) + return; + for (i = 0; i < d->num_buttons; i++) + DialogDrawButton(d, i); + DialogDraw(d); +} + +void +ShowDialog(Dialog * d) +{ + char pq; + int i, w, h, mw, mh; + EWin *ewin; + XTextProperty xtp; + + SC_Kill(); + if (d->title) + { + xtp.encoding = XA_STRING; + xtp.format = 8; + xtp.value = (unsigned char *)(d->title); + xtp.nitems = strlen((char *)(xtp.value)); + XSetWMName(disp, d->win, &xtp); + } + + ewin = FindEwinByDialog(d); + if (ewin) + { + RaiseEwin(ewin); + ShowEwin(ewin); + return; + } + + if (d->item) + DialogItemsRealize(d); + + w = d->w; + h = d->h; + mw = 0; + mh = 0; + for (i = 0; i < d->num_buttons; i++) + { + if (d->button[i]->w > mw) + mw = d->button[i]->w; + if (d->button[i]->h > mh) + mh = d->button[i]->h; + } + h += d->iclass->padding.top + d->iclass->padding.bottom + mh; + + if ((d->iclass->padding.left + d->iclass->padding.right + + (d->num_buttons * (mw + d->iclass->padding.left + + d->iclass->padding.right))) + > w) + w = d->iclass->padding.left + d->iclass->padding.right + + (d->num_buttons * (mw + d->iclass->padding.left + + d->iclass->padding.right)); + + for (i = 0; i < d->num_buttons; i++) + { + d->button[i]->x = + (((w - (d->iclass->padding.left + d->iclass->padding.right)) - + (d->num_buttons * (mw + d->iclass->padding.left + + d->iclass->padding.right))) / 2) + + d->iclass->padding.left + + (i * (mw + d->iclass->padding.left + d->iclass->padding.right)) + + d->iclass->padding.left; + d->button[i]->y = d->h - d->iclass->padding.bottom + + d->iclass->padding.top; + + d->button[i]->w = mw; + d->button[i]->h = mh; + EMoveResizeWindow(disp, d->button[i]->win, + d->button[i]->x, d->button[i]->y, + d->button[i]->w, d->button[i]->h); + } + d->w = w; + d->h = d->h - d->iclass->padding.bottom; + EResizeWindow(disp, d->win, w, h); + pq = queue_up; + queue_up = 0; + IclassApply(d->iclass, d->win, w, h, 0, 0, STATE_NORMAL, 0); + + for (i = 0; i < d->num_buttons; i++) + IclassApply(d->button[i]->iclass, d->button[i]->win, + d->button[i]->w, d->button[i]->h, 0, 0, + STATE_NORMAL, 0); + queue_up = pq; + + ewin = AddInternalToFamily(d->win, 1, "DEFAULT"); + XSelectInput(disp, d->win, ExposureMask | PointerMotionMask | + EnterWindowMask | LeaveWindowMask | + FocusChangeMask | KeyPressMask); + if (ewin) + { + DesktopRemoveEwin(ewin); + ewin->layer = 4; + DesktopAddEwinToTop(ewin); + MoveEwin(ewin, (root.w - ewin->w) / 2, (root.h - ewin->h) / 2); + RestackEwin(ewin); + ShowEwin(ewin); + ewin->dialog = d; + } + + if (!FindDialog(d->win)) + AddItem(d, d->name, d->win, LIST_TYPE_DIALOG); + XSync(disp, False); + DialogRedraw(d); +} + +void +DialogClose(Dialog * d) +{ + EWin *ewin; + XEvent ev; + + if (!d) + return; + ewin = FindEwinByDialog(d); + EDestroyWindow(disp, d->win); + if (ewin) + { + HideEwin(ewin); + ev.xunmap.window = d->win; + HandleUnmap(&ev); + } + if (d->exit_func) + (d->exit_func) (d->exit_val, d->exit_data); + RemoveItem(NULL, d->win, LIST_FINDBY_ID, LIST_TYPE_DIALOG); + FreeDialog(d); +} + +DItem * +DialogInitItem(Dialog * d) +{ + if (!d->item) + { + DItem *di; + + di = Emalloc(sizeof(DItem)); + d->item = di; + di->type = DITEM_TABLE; + di->func = NULL; + di->val = 0; + di->data = NULL; + di->iclass = NULL; + di->tclass = NULL; + di->padding.left = 0; + di->padding.right = 0; + di->padding.top = 0; + di->padding.bottom = 0; + di->fill_h = 0; + di->fill_v = 0; + di->align_h = 512; + di->align_v = 512; + di->row_span = 1; + di->col_span = 1; + di->x = 0; + di->y = 0; + di->w = 0; + di->h = 0; + di->hilited = 0; + di->clicked = 0; + di->win = 0; + di->item.table.num_columns = 1; + di->item.table.border = 0; + di->item.table.homogenous_h = 0; + di->item.table.homogenous_v = 0; + di->item.table.num_items = 0; + di->item.table.items = NULL; + return di; + } + return NULL; +} + +DItem * +DialogAddItem(DItem * dii, int type) +{ + DItem *di; + + di = Emalloc(sizeof(DItem)); + di->type = type; + di->func = NULL; + di->val = 0; + di->data = NULL; + di->iclass = NULL; + di->tclass = NULL; + di->padding.left = 0; + di->padding.right = 0; + di->padding.top = 0; + di->padding.bottom = 0; + di->fill_h = 1; + di->fill_v = 1; + di->align_h = 512; + di->align_v = 512; + di->row_span = 1; + di->col_span = 1; + + di->x = 0; + di->y = 0; + di->w = 0; + di->h = 0; + di->hilited = 0; + di->clicked = 0; + di->win = 0; + switch (di->type) + { + case DITEM_NONE: + break; + case DITEM_AREA: + di->item.area.area_win = 0; + di->item.area.w = 32; + di->item.area.h = 32; + di->item.area.event_func = NULL; + break; + case DITEM_BUTTON: + di->item.button.text = NULL; + break; + case DITEM_CHECKBUTTON: + di->item.check_button.text = NULL; + di->item.check_button.check_win = 0; + di->item.check_button.onoff = 0; + di->item.check_button.onoff_ptr = NULL; + di->item.check_button.check_orig_w = 10; + di->item.check_button.check_orig_h = 10; + break; + case DITEM_TEXT: + di->item.text.text = NULL; + break; + case DITEM_TABLE: + di->item.table.num_columns = 1; + di->item.table.border = 0; + di->item.table.homogenous_h = 0; + di->item.table.homogenous_v = 0; + di->item.table.num_items = 0; + di->item.table.items = NULL; + break; + case DITEM_IMAGE: + di->item.image.image = NULL; + break; + case DITEM_SEPARATOR: + di->item.separator.horizontal = 0; + break; + case DITEM_RADIOBUTTON: + di->item.radio_button.text = NULL; + di->item.radio_button.radio_win = 0; + di->item.radio_button.onoff = 0; + di->item.radio_button.val = 0; + di->item.radio_button.val_ptr = 0; + di->item.radio_button.next = NULL; + di->item.radio_button.first = NULL; + di->item.radio_button.radio_orig_w = 10; + di->item.radio_button.radio_orig_h = 10; + break; + case DITEM_SLIDER: + di->item.slider.horizontal = 1; + di->item.slider.numeric = 0; + di->item.slider.numeric_side = 0; + di->item.slider.upper = 100; + di->item.slider.lower = 0; + di->item.slider.unit = 10; + di->item.slider.jump = 20; + di->item.slider.val = 0; + di->item.slider.val_ptr = NULL; + di->item.slider.min_length = 64; + di->item.slider.ic_base = NULL; + di->item.slider.ic_knob = NULL; + di->item.slider.ic_border = NULL; + di->item.slider.base_win = 0; + di->item.slider.knob_win = 0; + di->item.slider.border_win = 0; + di->item.slider.base_orig_w = 10; + di->item.slider.base_orig_h = 10; + di->item.slider.knob_orig_w = 6; + di->item.slider.knob_orig_h = 6; + di->item.slider.border_orig_w = 14; + di->item.slider.border_orig_h = 14; + di->item.slider.base_x = 0; + di->item.slider.base_y = 0; + di->item.slider.base_w = 0; + di->item.slider.base_h = 0; + di->item.slider.knob_x = 0; + di->item.slider.knob_y = 0; + di->item.slider.knob_w = 0; + di->item.slider.knob_h = 0; + di->item.slider.border_x = 0; + di->item.slider.border_y = 0; + di->item.slider.border_w = 0; + di->item.slider.border_h = 0; + di->item.slider.numeric_x = 0; + di->item.slider.numeric_y = 0; + di->item.slider.numeric_w = 0; + di->item.slider.numeric_h = 0; + di->item.slider.in_drag = 0; + di->item.slider.wanted_val = 0; + break; + default: + break; + } + + if (dii) + { + dii->item.table.num_items++; + dii->item.table.items = Erealloc(dii->item.table.items, + sizeof(DItem *) * + dii->item.table.num_items); + dii->item.table.items[dii->item.table.num_items - 1] = di; + } + + return di; +} + +void +DialogItemSetCallback(DItem * di, void (*func) (int val, void *data), + int val, char *data) +{ + di->func = func; + di->val = val; + di->data = data; +} + +void +DialogItemSetClass(DItem * di, ImageClass * iclass, TextClass * tclass) +{ + if (di->iclass) + di->iclass->ref_count--; + di->iclass = iclass; + if (di->iclass) + di->iclass->ref_count++; + + if (di->tclass) + di->tclass->ref_count--; + di->tclass = tclass; + if (di->tclass) + di->tclass->ref_count++; +} + +void +DialogItemSetPadding(DItem * di, int left, int right, int top, int bottom) +{ + di->padding.left = left; + di->padding.right = right; + di->padding.top = top; + di->padding.bottom = bottom; +} + +void +DialogItemSetFill(DItem * di, char fill_h, char fill_v) +{ + di->fill_h = fill_h; + di->fill_v = fill_v; +} + +void +DialogItemSetAlign(DItem * di, int align_h, int align_v) +{ + di->align_h = align_h; + di->align_v = align_v; +} + +void +DialogItemSetRowSpan(DItem * di, int row_span) +{ + di->row_span = row_span; +} + +void +DialogItemSetColSpan(DItem * di, int col_span) +{ + di->col_span = col_span; +} + +void +DialogRealizeItem(Dialog * d, DItem * di) +{ + char *def = NULL; + int iw = 0, ih = 0; + + if (di->type == DITEM_BUTTON) + { + def = "DIALOG_WIDGET_BUTTON"; + } + else if (di->type == DITEM_CHECKBUTTON) + { + def = "DIALOG_WIDGET_CHECK_BUTTON"; + } + else if (di->type == DITEM_TEXT) + { + def = "DIALOG_WIDGET_TEXT"; + } + else if (di->type == DITEM_SEPARATOR) + { + def = "DIALOG_WIDGET_SEPARATOR"; + } + else if (di->type == DITEM_TABLE) + { + def = "DIALOG_WIDGET_TABLE"; + } + else if (di->type == DITEM_RADIOBUTTON) + { + def = "DIALOG_WIDGET_RADIO_BUTTON"; + } + else if (di->type == DITEM_AREA) + { + def = "DIALOG_WIDGET_AREA"; + } + else + { + def = "DIALOG_WIDGET_BUTTON"; + } + + if (def) + { + if (!di->tclass) + di->tclass = FindItem(def, 0, LIST_FINDBY_NAME, LIST_TYPE_TCLASS); + if (!di->iclass) + di->iclass = FindItem(def, 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + } + if (!di->tclass) + { + DialogRealizeTClassDefault(); + di->tclass = d_tc_default; + } + if (di->tclass) + di->tclass->ref_count++; + + if (!di->iclass) + { + DialogRealizeIClassDefault(); + di->iclass = d_ic_default; + } + if (di->iclass) + di->iclass->ref_count++; + + if (di->type == DITEM_TABLE) + { + int i; + + for (i = 0; i < di->item.table.num_items; i++) + DialogRealizeItem(d, di->item.table.items[i]); + } + switch (di->type) + { + case DITEM_SLIDER: + if (di->item.slider.numeric) + { + di->win = ECreateWindow(d->win, -20, -20, 2, 2, 0); + EMapWindow(disp, di->win); + XSelectInput(disp, di->win, EnterWindowMask | LeaveWindowMask | + ButtonPressMask | ButtonReleaseMask); + } + di->item.slider.base_win = ECreateWindow(d->win, -20, -20, 2, 2, 0); + EMapWindow(disp, di->item.slider.base_win); + di->item.slider.knob_win = ECreateWindow(d->win, -20, -20, 2, 2, 0); + EMapWindow(disp, di->item.slider.knob_win); + XSelectInput(disp, di->item.slider.base_win, + EnterWindowMask | LeaveWindowMask | ButtonPressMask | + ButtonReleaseMask); + XSelectInput(disp, di->item.slider.knob_win, + ButtonPressMask | + ButtonReleaseMask | PointerMotionMask); + if (!di->item.slider.ic_base) + { + if (di->item.slider.horizontal) + { + di->item.slider.ic_base = + FindItem("DIALOG_WIDGET_SLIDER_BASE_HORIZONTAL", 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + } + else + { + di->item.slider.ic_base = + FindItem("DIALOG_WIDGET_SLIDER_BASE_VERTICAL", 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + } + } + if (!di->item.slider.ic_base) + { + DialogRealizeIClassDefault(); + di->item.slider.ic_base = d_ic_default; + } + if (di->item.slider.ic_base->norm.normal->im_file) + { + ImlibImage *im; + + im = ELoadImage(di->item.slider.ic_base->norm.normal->im_file); + if (im) + { + di->item.slider.base_orig_w = im->rgb_width; + di->item.slider.base_orig_h = im->rgb_height; + Imlib_destroy_image(id, im); + } + } + if (di->item.slider.ic_base) + di->item.slider.ic_base->ref_count++; + + if (!di->item.slider.ic_knob) + { + if (di->item.slider.horizontal) + { + di->item.slider.ic_knob = + FindItem("DIALOG_WIDGET_SLIDER_KNOB_HORIZONTAL", 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + } + else + { + di->item.slider.ic_knob = + FindItem("DIALOG_WIDGET_SLIDER_KNOB_VERTICAL", 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + } + } + if (!di->item.slider.ic_knob) + { + DialogRealizeIClassDefault(); + di->item.slider.ic_knob = d_ic_default; + } + if (di->item.slider.ic_knob) + di->item.slider.ic_knob->ref_count++; + + if (di->item.slider.ic_knob->norm.normal->im_file) + { + ImlibImage *im; + + im = ELoadImage(di->item.slider.ic_knob->norm.normal->im_file); + if (im) + { + di->item.slider.knob_orig_w = im->rgb_width; + di->item.slider.knob_orig_h = im->rgb_height; + Imlib_destroy_image(id, im); + } + } + if (!di->item.slider.ic_border) + { + if (di->item.slider.horizontal) + { + di->item.slider.ic_border = + FindItem("DIALOG_WIDGET_SLIDER_BORDER_HORIZONTAL", 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + } + else + { + di->item.slider.ic_border = + FindItem("DIALOG_WIDGET_SLIDER_BORDER_VERTICAL", 0, + LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + } + } + if (di->item.slider.ic_border) + { + if (di->item.slider.ic_border->norm.normal->im_file) + { + ImlibImage *im; + + im = ELoadImage(di->item.slider.ic_border->norm.normal->im_file); + if (im) + { + di->item.slider.border_orig_w = im->rgb_width; + di->item.slider.border_orig_h = im->rgb_height; + Imlib_destroy_image(id, im); + di->item.slider.border_win = ECreateWindow(d->win, -20, + -20, 2, 2, 0); + EMapWindow(disp, di->item.slider.border_win); + } + } + di->item.slider.ic_border->ref_count++; + } + if (di->item.slider.horizontal) + { + iw = di->item.slider.min_length + + di->item.slider.ic_base->padding.left + + di->item.slider.ic_base->padding.right; + ih = di->item.slider.base_orig_h; + } + else + { + iw = di->item.slider.base_orig_w; + ih = di->item.slider.min_length + + di->item.slider.ic_base->padding.top + + di->item.slider.ic_base->padding.bottom; + } + di->w = iw; + di->h = ih; + break; + case DITEM_BUTTON: + TextSize(di->tclass, 0, 0, STATE_NORMAL, di->item.button.text, + &iw, &ih, 17); + iw += di->iclass->padding.left + di->iclass->padding.right; + ih += di->iclass->padding.top + di->iclass->padding.bottom; + di->win = ECreateWindow(d->win, -20, -20, 2, 2, 0); + EMapWindow(disp, di->win); + XSelectInput(disp, di->win, EnterWindowMask | LeaveWindowMask | + ButtonPressMask | ButtonReleaseMask | ExposureMask); + di->w = iw; + di->h = ih; + break; + case DITEM_AREA: + iw = di->item.area.w; + ih = di->item.area.h; + iw += di->iclass->padding.left + di->iclass->padding.right; + ih += di->iclass->padding.top + di->iclass->padding.bottom; + di->win = ECreateWindow(d->win, -20, -20, 2, 2, 0); + EMapWindow(disp, di->win); + XSelectInput(disp, di->win, ExposureMask); + di->item.area.area_win = ECreateWindow(di->win, -20, -20, 2, 2, 0); + EMapWindow(disp, di->item.area.area_win); + XSelectInput(disp, di->item.area.area_win, EnterWindowMask | + LeaveWindowMask | ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask); + di->w = iw; + di->h = ih; + break; + case DITEM_CHECKBUTTON: + if (di->iclass->norm.normal->im_file) + { + ImlibImage *im; + + im = ELoadImage(di->iclass->norm.normal->im_file); + if (im) + { + di->item.check_button.check_orig_w = im->rgb_width; + di->item.check_button.check_orig_h = im->rgb_height; + Imlib_destroy_image(id, im); + } + } + TextSize(di->tclass, 0, 0, STATE_NORMAL, di->item.check_button.text, + &iw, &ih, 17); + if (ih < di->item.check_button.check_orig_h) + ih = di->item.check_button.check_orig_h; + iw += di->item.check_button.check_orig_w + di->iclass->padding.left; + di->item.check_button.check_win = ECreateWindow(d->win, -20, -20, + 2, 2, 0); + di->win = ECreateEventWindow(d->win, -20, -20, 2, 2); + EMapWindow(disp, di->item.check_button.check_win); + EMapWindow(disp, di->win); + XSelectInput(disp, di->win, EnterWindowMask | LeaveWindowMask | + ButtonPressMask | ButtonReleaseMask | ExposureMask); + di->w = iw; + di->h = ih; + break; + case DITEM_TEXT: + TextSize(di->tclass, 0, 0, STATE_NORMAL, di->item.text.text, + &iw, &ih, 17); + di->w = iw; + di->h = ih; + break; + case DITEM_IMAGE: + { + ImlibImage *im; + + im = ELoadImage(di->item.image.image); + if (im) + { + iw = im->rgb_width; + ih = im->rgb_height; + di->win = ECreateWindow(d->win, 0, 0, iw, ih, 0); + EMapWindow(disp, di->win); + Imlib_apply_image(id, im, di->win); + Imlib_destroy_image(id, im); + } + } + di->w = iw; + di->h = ih; + break; + case DITEM_SEPARATOR: + iw = di->iclass->padding.left + di->iclass->padding.right; + ih = di->iclass->padding.top + di->iclass->padding.bottom; + di->win = ECreateWindow(d->win, -20, -20, 2, 2, 0); + EMapWindow(disp, di->win); + di->w = iw; + di->h = ih; + break; + case DITEM_RADIOBUTTON: + if (di->iclass->norm.normal->im_file) + { + ImlibImage *im; + + im = ELoadImage(di->iclass->norm.normal->im_file); + if (im) + { + di->item.radio_button.radio_orig_w = im->rgb_width; + di->item.radio_button.radio_orig_h = im->rgb_height; + Imlib_destroy_image(id, im); + } + } + TextSize(di->tclass, 0, 0, STATE_NORMAL, di->item.radio_button.text, + &iw, &ih, 17); + if (ih < di->item.radio_button.radio_orig_h) + ih = di->item.radio_button.radio_orig_h; + iw += di->item.radio_button.radio_orig_w + di->iclass->padding.left; + di->item.radio_button.radio_win = ECreateWindow(d->win, -20, -20, + 2, 2, 0); + di->win = ECreateEventWindow(d->win, -20, -20, 2, 2); + EMapWindow(disp, di->item.radio_button.radio_win); + EMapWindow(disp, di->win); + XSelectInput(disp, di->win, EnterWindowMask | LeaveWindowMask | + ButtonPressMask | ButtonReleaseMask | ExposureMask); + di->w = iw; + di->h = ih; + break; + case DITEM_TABLE: + { + int cols, rows; + + cols = di->item.table.num_columns; + rows = 1; + if ((cols > 0) && (rows > 0)) + { + int i, *col_size, *row_size = NULL, r = 0, + c = 0, x = 0, y = 0; + + col_size = Emalloc(sizeof(int) * cols); + row_size = Erealloc(row_size, sizeof(int)); + + row_size[0] = 0; + for (i = 0; i < cols; i++) + col_size[i] = 0; + for (i = 0; i < di->item.table.num_items; i++) + { + DItem *dii; + int w, h, j, csum = 0; + + dii = di->item.table.items[i]; + w = dii->w + (dii->padding.left + dii->padding.right); + h = dii->h + (dii->padding.top + dii->padding.bottom); + for (j = 0; j < dii->col_span; j++) + csum += col_size[c + j]; + if (w > csum) + col_size[c + di->col_span - 1] += (w - csum); + if (h > row_size[r]) + row_size[r] = h; + c += dii->col_span; + if (c >= cols) + { + c = 0; + r++; + rows++; + row_size = Erealloc(row_size, sizeof(int) * rows); + + row_size[rows - 1] = 0; + } + } + if (di->item.table.homogenous_h) + { + int max = 0; + + for (i = 0; i < cols; i++) + { + if (col_size[i] > max) + max = col_size[i]; + } + for (i = 0; i < cols; i++) + col_size[i] = max; + } + if (di->item.table.homogenous_v) + { + int max = 0; + + for (i = 0; i < rows; i++) + { + if (row_size[i] > max) + max = row_size[i]; + } + for (i = 0; i < rows; i++) + row_size[i] = max; + } + iw = 0; + ih = 0; + for (i = 0; i < cols; i++) + iw += col_size[i]; + for (i = 0; i < rows; i++) + ih += row_size[i]; + di->w = iw; + di->h = ih; + r = 0; + c = 0; + for (i = 0; i < di->item.table.num_items; i++) + { + DItem *dii; + int j, sw = 0, sh = 0; + + dii = di->item.table.items[i]; + + for (j = 0; j < dii->col_span; j++) + sw += col_size[c + j]; + for (j = 0; j < dii->row_span; j++) + sh += row_size[r + j]; + if (dii->fill_h) + dii->w = sw - (dii->padding.left + + dii->padding.right); + if (dii->fill_v) + dii->h = sh - (dii->padding.top + + dii->padding.bottom); + if (dii->type == DITEM_TABLE) + { + int dx, dy, newx, newy; + + newx = di->x + x + d->iclass->padding.left + + dii->padding.left + + (((sw - (dii->padding.left + + dii->padding.right) - + dii->w) * dii->align_h) >> 10); + newy = di->y + y + d->iclass->padding.top + + dii->padding.top + + (((sh - (dii->padding.top + + dii->padding.bottom) - + dii->h) * dii->align_v) >> 10); + dx = newx - dii->x - d->iclass->padding.left; + dy = newy - dii->y - d->iclass->padding.top; + MoveTableBy(d, dii, dx, dy); + } + else + { + dii->x = di->x + x + d->iclass->padding.left + + dii->padding.left + + (((sw - (dii->padding.left + + dii->padding.right) - + dii->w) * dii->align_h) >> 10); + dii->y = di->y + y + d->iclass->padding.top + + dii->padding.top + + (((sh - (dii->padding.top + dii->padding.bottom) + - dii->h) * dii->align_v) >> 10); + if (dii->win) + EMoveResizeWindow(disp, dii->win, dii->x, dii->y, + dii->w, dii->h); + if (dii->type == DITEM_CHECKBUTTON) + EMoveResizeWindow(disp, + dii->item.check_button.check_win, + dii->x, dii->y + + ((dii->h - + dii->item.check_button.check_orig_h) / 2), + dii->item.check_button.check_orig_w, + dii->item.check_button.check_orig_h); + if (dii->type == DITEM_RADIOBUTTON) + EMoveResizeWindow(disp, + dii->item.radio_button.radio_win, + dii->x, dii->y + + ((dii->h - + dii->item.radio_button.radio_orig_h) / 2), + dii->item.radio_button.radio_orig_w, + dii->item.radio_button.radio_orig_h); + if (dii->type == DITEM_AREA) + { + dii->item.area.w = dii->w - + (dii->iclass->padding.left + + dii->iclass->padding.right); + dii->item.area.h = dii->h - + (dii->iclass->padding.top + + dii->iclass->padding.bottom); + EMoveResizeWindow(disp, dii->item.area.area_win, + dii->iclass->padding.left, + dii->iclass->padding.top, + dii->item.area.w, + dii->item.area.h); + } + if (dii->type == DITEM_SLIDER) + { + dii->item.slider.base_x = 0; + dii->item.slider.base_y = 0; + dii->item.slider.base_w = dii->w; + dii->item.slider.base_h = dii->h; + dii->item.slider.border_x = 0; + dii->item.slider.border_y = 0; + dii->item.slider.border_w = dii->w; + dii->item.slider.border_h = dii->h; + dii->item.slider.knob_w = + dii->item.slider.knob_orig_w; + dii->item.slider.knob_h = + dii->item.slider.knob_orig_h; + if (dii->item.slider.base_win) + EMoveResizeWindow(disp, + dii->item.slider.base_win, + dii->x + dii->item.slider.base_x, + dii->y + dii->item.slider.base_y, + dii->item.slider.base_w, + dii->item.slider.base_h); + if (dii->item.slider.border_win) + EMoveResizeWindow(disp, + dii->item.slider.border_win, + dii->x + dii->item.slider.border_x, + dii->y + dii->item.slider.border_y, + dii->item.slider.border_w, + dii->item.slider.border_h); + if (dii->win) + EMoveResizeWindow(disp, dii->win, + dii->x + dii->item.slider.numeric_x, + dii->y + dii->item.slider.numeric_y, + dii->item.slider.numeric_w, + dii->item.slider.numeric_h); + } + } + x += sw; + c += dii->col_span; + if (c >= cols) + { + x = 0; + y += row_size[r]; + c = 0; + r++; + } + } + if (col_size) + Efree(col_size); + if (row_size) + Efree(row_size); + } + } + break; + case DITEM_NONE: + default: + di->w = 0; + di->h = 0; + break; + } +} + +void +MoveTableBy(Dialog * d, DItem * di, int dx, int dy) +{ + int i; + + di->x += dx; + di->y += dy; + for (i = 0; i < di->item.table.num_items; i++) + { + DItem *dii; + + dii = di->item.table.items[i]; + dii->x += dx; + dii->y += dy; + if (dii->type == DITEM_TABLE) + MoveTableBy(d, dii, dx, dy); + if (dii->win) + EMoveWindow(disp, dii->win, dii->x, dii->y); + if (dii->type == DITEM_CHECKBUTTON) + EMoveWindow(disp, dii->item.check_button.check_win, + dii->x, dii->y + + ((dii->h - dii->item.check_button.check_orig_h) / 2)); + if (dii->type == DITEM_RADIOBUTTON) + EMoveWindow(disp, dii->item.radio_button.radio_win, + dii->x, dii->y + + ((dii->h - dii->item.radio_button.radio_orig_h) / 2)); + if (dii->type == DITEM_SLIDER) + { + if (dii->item.slider.base_win) + EMoveResizeWindow(disp, dii->item.slider.base_win, + dii->x + dii->item.slider.base_x, + dii->y + dii->item.slider.base_y, + dii->item.slider.base_w, + dii->item.slider.base_h); + if (dii->item.slider.knob_win) + EMoveResizeWindow(disp, dii->item.slider.knob_win, + dii->x + dii->item.slider.knob_x, + dii->y + dii->item.slider.knob_y, + dii->item.slider.knob_w, + dii->item.slider.knob_h); + if (dii->item.slider.border_win) + EMoveResizeWindow(disp, dii->item.slider.border_win, + dii->x + dii->item.slider.border_x, + dii->y + dii->item.slider.border_y, + dii->item.slider.border_w, + dii->item.slider.border_h); + if (dii->win) + EMoveResizeWindow(disp, dii->win, + dii->x + dii->item.slider.numeric_x, + dii->y + dii->item.slider.numeric_y, + dii->item.slider.numeric_w, + dii->item.slider.numeric_h); + } + } +} + +#define INTERSECTS(x, y, w, h, xx, yy, ww, hh) \ +((x < (xx + ww)) && \ + (y < (yy + hh)) && \ + ((x + w) > xx) && \ + ((y + h) > yy)) + +void +DialogDrawItems(Dialog * d, DItem * di, int x, int y, int w, int h) +{ + int state; + + if (di->type == DITEM_TABLE) + { + int i; + + if (INTERSECTS(x, y, w, h, + di->x, di->y, di->w, di->h)) + { + for (i = 0; i < di->item.table.num_items; i++) + DialogDrawItems(d, di->item.table.items[i], x, y, w, h); + } + return; + } + if (INTERSECTS(x, y, w, h, + di->x, di->y, di->w, di->h)) + { + switch (di->type) + { + case DITEM_SLIDER: + if (di->item.slider.horizontal) + { + di->item.slider.knob_x = di->item.slider.base_x + + (((di->item.slider.base_w - di->item.slider.knob_w) * + (di->item.slider.val - di->item.slider.lower)) / + (di->item.slider.upper - di->item.slider.lower)); + di->item.slider.knob_y = di->item.slider.base_y + + ((di->item.slider.base_h - di->item.slider.knob_h) / 2); + } + else + { + di->item.slider.knob_y = (di->item.slider.base_y + + di->item.slider.base_h - + di->item.slider.knob_h) - + (((di->item.slider.base_h - di->item.slider.knob_h) * + (di->item.slider.val - di->item.slider.lower)) / + (di->item.slider.upper - di->item.slider.lower)); + di->item.slider.knob_x = di->item.slider.base_x + + ((di->item.slider.base_w - di->item.slider.knob_w) / 2); + } + if (di->item.slider.knob_win) + EMoveResizeWindow(disp, di->item.slider.knob_win, + di->x + di->item.slider.knob_x, + di->y + di->item.slider.knob_y, + di->item.slider.knob_w, + di->item.slider.knob_h); + if (di->item.slider.base_win) + IclassApply(di->item.slider.ic_base, + di->item.slider.base_win, + di->item.slider.base_w, di->item.slider.base_h, + 0, 0, STATE_NORMAL, 0); + if (di->item.slider.border_win) + IclassApply(di->item.slider.ic_border, + di->item.slider.border_win, + di->item.slider.border_w, di->item.slider.border_h, + 0, 0, STATE_NORMAL, 0); + state = STATE_NORMAL; + if ((di->hilited) && (di->clicked)) + state = STATE_CLICKED; + else if ((di->hilited) && (!di->clicked)) + state = STATE_HILITED; + else if (!(di->hilited) && (di->clicked)) + state = STATE_CLICKED; + if (di->item.slider.knob_win) + IclassApply(di->item.slider.ic_knob, + di->item.slider.knob_win, + di->item.slider.knob_w, di->item.slider.knob_h, + 0, 0, state, 0); + break; + case DITEM_BUTTON: + state = STATE_NORMAL; + if ((di->hilited) && (di->clicked)) + state = STATE_CLICKED; + else if ((di->hilited) && (!di->clicked)) + state = STATE_HILITED; + else if (!(di->hilited) && (di->clicked)) + state = STATE_CLICKED; + IclassApply(di->iclass, di->win, di->w, di->h, 0, 0, state, 0); + TclassApply(di->iclass, di->win, di->w, di->h, 0, 0, state, 1, + di->tclass, di->item.button.text); + break; + case DITEM_AREA: + IclassApply(di->iclass, di->win, di->w, di->h, + 0, 0, STATE_NORMAL, 0); + break; + case DITEM_CHECKBUTTON: + state = STATE_NORMAL; + if ((di->hilited) && (di->clicked)) + state = STATE_CLICKED; + else if ((di->hilited) && (!di->clicked)) + state = STATE_HILITED; + else if (!(di->hilited) && (di->clicked)) + state = STATE_CLICKED; + if (di->item.check_button.onoff) + IclassApply(di->iclass, di->item.check_button.check_win, + di->item.check_button.check_orig_w, + di->item.check_button.check_orig_h, 1, 0, + state, 0); + else + IclassApply(di->iclass, di->item.check_button.check_win, + di->item.check_button.check_orig_w, + di->item.check_button.check_orig_h, 0, 0, + state, 0); + XClearArea(disp, d->win, di->x, di->y, di->w, di->h, False); + TextDraw(di->tclass, d->win, 0, 0, STATE_NORMAL, + di->item.check_button.text, + di->x + di->item.check_button.check_orig_w + + di->iclass->padding.left, di->y, + di->w - di->item.check_button.check_orig_w - + di->iclass->padding.left, 99999, + 17, di->tclass->justification); + break; + case DITEM_TEXT: + XClearArea(disp, d->win, di->x, di->y, di->w, di->h, False); + TextDraw(di->tclass, d->win, 0, 0, STATE_NORMAL, + di->item.text.text, di->x, di->y, di->w, + 99999, 17, di->tclass->justification); + break; + case DITEM_IMAGE: + break; + case DITEM_SEPARATOR: + if (di->item.separator.horizontal) + IclassApply(di->iclass, di->win, di->w, + di->h, 0, 0, STATE_NORMAL, 0); + else + IclassApply(di->iclass, di->win, di->w, + di->h, 0, 0, STATE_CLICKED, 0); + break; + case DITEM_RADIOBUTTON: + state = STATE_NORMAL; + if ((di->hilited) && (di->clicked)) + state = STATE_CLICKED; + else if ((di->hilited) && (!di->clicked)) + state = STATE_HILITED; + else if (!(di->hilited) && (di->clicked)) + state = STATE_CLICKED; + if (di->item.radio_button.onoff) + IclassApply(di->iclass, di->item.radio_button.radio_win, + di->item.radio_button.radio_orig_w, + di->item.radio_button.radio_orig_h, 1, 0, + state, 0); + else + IclassApply(di->iclass, di->item.radio_button.radio_win, + di->item.radio_button.radio_orig_w, + di->item.radio_button.radio_orig_w, 0, 0, + state, 0); + XClearArea(disp, d->win, di->x, di->y, di->w, di->h, False); + TextDraw(di->tclass, d->win, 0, 0, STATE_NORMAL, + di->item.radio_button.text, + di->x + di->item.radio_button.radio_orig_w + + di->iclass->padding.left, di->y, + di->w - di->item.radio_button.radio_orig_w - + di->iclass->padding.left, 99999, + 17, di->tclass->justification); + break; + default: + break; + } + } +} + +void +DialogItemsRealize(Dialog * d) +{ + char pq; + + if (!d->item) + return; + DialogRealizeItem(d, d->item); + pq = queue_up; + queue_up = 0; + DialogDrawItems(d, d->item, 0, 0, 99999, 99999); + queue_up = pq; + d->w = d->item->w + d->iclass->padding.left + d->iclass->padding.right; + d->h = d->item->h + d->iclass->padding.top + d->iclass->padding.bottom; +} + +void +DialogItemButtonSetText(DItem * di, char *text) +{ + if (di->item.button.text) + Efree(di->item.button.text); + di->item.button.text = duplicate(text); +} + +void +DialogItemCheckButtonSetText(DItem * di, char *text) +{ + if (di->item.check_button.text) + Efree(di->item.check_button.text); + di->item.check_button.text = duplicate(text); +} + +void +DialogItemTextSetText(DItem * di, char *text) +{ + if (di->item.text.text) + Efree(di->item.text.text); + di->item.text.text = duplicate(text); +} + +void +DialogItemRadioButtonSetText(DItem * di, char *text) +{ + if (di->item.check_button.text) + Efree(di->item.check_button.text); + di->item.check_button.text = duplicate(text); +} + +void +DialogItemRadioButtonSetFirst(DItem * di, DItem * first) +{ + di->item.radio_button.first = first; + if (di == first) + return; + while (first->item.radio_button.next) + first = first->item.radio_button.next; + first->item.radio_button.next = di; +} + +void +DialogItemRadioButtonGroupSetValPtr(DItem * di, int *val_ptr) +{ + while (di) + { + di->item.radio_button.val_ptr = val_ptr; + if (*val_ptr == di->item.radio_button.val) + di->item.check_button.onoff = 1; + di = di->item.radio_button.next; + } +} + +void +DialogItemRadioButtonGroupSetVal(DItem * di, int val) +{ + di->item.radio_button.val = val; +} + +void +DialogItemCheckButtonSetState(DItem * di, char onoff) +{ + di->item.check_button.onoff = onoff; +} + +void +DialogItemCheckButtonSetPtr(DItem * di, char *onoff_ptr) +{ + di->item.check_button.onoff_ptr = onoff_ptr; +} + +void +DialogItemTableSetOptions(DItem * di, int num_columns, char border, + char homogenous_h, char homogenous_v) +{ + di->item.table.num_columns = num_columns; + di->item.table.border = border; + di->item.table.homogenous_h = homogenous_h; + di->item.table.homogenous_v = homogenous_v; +} + +void +DialogItemSeparatorSetOrientation(DItem * di, char horizontal) +{ + di->item.separator.horizontal = horizontal; +} + +void +DialogItemImageSetFile(DItem * di, char *image) +{ + if (di->item.image.image) + Efree(di->item.image.image); + di->item.image.image = duplicate(image); + di->fill_h = 0; + di->fill_v = 0; +} + +void +DialogItemSliderSetVal(DItem * di, int val) +{ + di->item.slider.val = val; + if (val < di->item.slider.lower) + { + di->item.slider.val = di->item.slider.lower; + } + else if (val > di->item.slider.upper) + { + di->item.slider.val = di->item.slider.upper; + } +} + +void +DialogItemSliderSetBounds(DItem * di, int lower, int upper) +{ + if (lower < upper) + { + di->item.slider.lower = lower; + di->item.slider.upper = upper; + } + else + { + di->item.slider.lower = upper; + di->item.slider.upper = lower; + } + if (di->item.slider.upper <= di->item.slider.lower) + di->item.slider.upper = di->item.slider.lower + 1; +} + +void +DialogItemSliderSetUnits(DItem * di, int units) +{ + di->item.slider.unit = units; +} + +void +DialogItemSliderSetJump(DItem * di, int jump) +{ + di->item.slider.jump = jump; +} + +void +DialogItemSliderSetMinLength(DItem * di, int min) +{ + di->item.slider.min_length = min; +} + +void +DialogItemSliderSetValPtr(DItem * di, int *val_ptr) +{ + di->item.slider.val_ptr = val_ptr; +} + +void +DialogItemSliderSetOrientation(DItem * di, char horizontal) +{ + di->item.slider.horizontal = horizontal; +} + +void +DialogItemAreaSetSize(DItem * di, int w, int h) +{ + di->item.area.w = w; + di->item.area.h = h; +} + +Window +DialogItemAreaGetWindow(DItem * di) +{ + return di->item.area.area_win; +} + +void +DialogItemAreaGetSize(DItem * di, int *w, int *h) +{ + *w = di->item.area.w; + *h = di->item.area.h; +} + +void +DialogItemAreaSetEventFunc(DItem * di, void (*func) (int val, void *data)) +{ + di->item.area.event_func = func; +} + +void +DialogFreeItem(DItem * di) +{ + if (di->type == DITEM_TABLE) + { + int i; + + for (i = 0; i < di->item.table.num_items; i++) + DialogFreeItem(di->item.table.items[i]); + } + switch (di->type) + { + case DITEM_BUTTON: + if (di->item.text.text) + Efree(di->item.text.text); + break; + case DITEM_CHECKBUTTON: + if (di->item.text.text) + Efree(di->item.text.text); + break; + case DITEM_TEXT: + if (di->item.text.text) + Efree(di->item.text.text); + break; + case DITEM_IMAGE: + if (di->item.image.image) + Efree(di->item.image.image); + break; + case DITEM_SLIDER: + if (di->item.slider.ic_base) + di->item.slider.ic_base->ref_count--; + if (di->item.slider.ic_knob) + di->item.slider.ic_knob->ref_count--; + if (di->item.slider.ic_border) + di->item.slider.ic_border->ref_count--; + break; + case DITEM_SEPARATOR: + break; + case DITEM_TABLE: + if (di->item.table.items) + Efree(di->item.table.items); + break; + default: + break; + } + + if (di->iclass) + di->iclass->ref_count--; + if (di->tclass) + di->tclass->ref_count--; + + Efree(di); +} + +DItem * +DialogItemFindWindow(DItem * di, Window win) +{ + DItem *dii = NULL; + + if (di->type == DITEM_TABLE) + { + int i; + + for (i = 0; i < di->item.table.num_items; i++) + { + if ((dii = DialogItemFindWindow(di->item.table.items[i], win))) + return dii; + } + } + else if ((di->win == win) || ((di->type == DITEM_SLIDER) && + ((di->item.slider.base_win == win) || + (di->item.slider.knob_win == win))) || + ((di->type == DITEM_AREA) && + (di->item.area.area_win == win))) + { + return di; + } + + return NULL; +} diff --git a/src/dock.c b/src/dock.c new file mode 100644 index 00000000..0c1e6186 --- /dev/null +++ b/src/dock.c @@ -0,0 +1,55 @@ +#include "E.h" + +void +DockIt(EWin * ewin) +{ + ActionClass *ac; + ImageClass *ic; + Button *bt; + char id[32]; + + EDBUG(3, "DockIt"); + Esnprintf(id, sizeof(id), "%i", ewin->client.win); + ac = 0; + ic = FindItem("DEFAULT_DOCK_BUTTON", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (mode.dockstartx > 0) + { + bt = CreateButton(id, ic, ac, NULL, NULL, 1, 0, 64, 64, 64, 64, 0, 0, + mode.dockstartx, 0, mode.dockstarty, 0, 0, 0, 0, 0, + 1, 0, 1); + } + else + { + bt = CreateButton(id, ic, ac, NULL, NULL, 1, 0, 64, 64, 64, 64, 0, + 2046, 0, 0, 0, 1023, 0, 0, 0, 0, 1, 0, 1); + } + UngrabX(); + + if (!bt) + EDBUG_RETURN_; + + ShowButton(bt); + FindEmptySpotForButton(bt, "DOCK_APP_BUTTON", mode.dockdirmode); + + AddItem(ewin, "EWIN", ewin->client.win, LIST_TYPE_EWIN); + AddItem(bt, "DOCK_APP_BUTTON", ewin->client.win, LIST_TYPE_BUTTON); + + EmbedWindowIntoButton(bt, ewin->client.win); + ShowEwin(ewin); + + EDBUG_RETURN_; +} + +void +DockDestroy(EWin * ewin) +{ + + Button *bt; + + EDBUG(3, "DockDestroy"); + bt = FindItem(NULL, ewin->client.win, LIST_FINDBY_ID, LIST_TYPE_BUTTON); + if (bt) + DestroyButton(RemoveItem(NULL, ewin->client.win, + LIST_FINDBY_ID, LIST_TYPE_BUTTON)); + EDBUG_RETURN_; +} diff --git a/src/draw.c b/src/draw.c new file mode 100644 index 00000000..07b6e22c --- /dev/null +++ b/src/draw.c @@ -0,0 +1,1255 @@ +#include "E.h" + +void +HandleDrawQueue() +{ + DrawQueue **lst = NULL, *dq; + int i, num; + char already, p_queue; + + EDBUG(4, "HandleDrawQueue"); + if ((mode.mode == MODE_MOVE) && (mode.movemode > 0)) + EDBUG_RETURN_; + if ((mode.mode == MODE_RESIZE) && (mode.resizemode > 0)) + EDBUG_RETURN_; + if ((mode.mode == MODE_RESIZE_H) && (mode.resizemode > 0)) + EDBUG_RETURN_; + if ((mode.mode == MODE_RESIZE_V) && (mode.resizemode > 0)) + EDBUG_RETURN_; + p_queue = queue_up; + queue_up = 0; + num = 0; + /* find all DRAW queue entries most recent first and add them to the */ + /* end of the draw list array if there are no previous entries for that */ + /* draw type and that window in the array */ + while ((dq = (DrawQueue *) RemoveItem(NULL, 0, LIST_FINDBY_NONE, + LIST_TYPE_DRAW))) + { + already = 0; + if (dq->shape_propagate) + { + for (i = 0; i < num; i++) + { + if ((lst[i]->win == dq->win) && (lst[i]->shape_propagate)) + { + already = 1; + i = num; + } + } + } + else if (dq->text) + { + for (i = 0; i < num; i++) + { + if ((lst[i]->win == dq->win) && (lst[i]->text)) + { + Efree(dq->text); + already = 1; + i = num; + } + } + } + else if (dq->iclass) + { + for (i = 0; i < num; i++) + { + if ((lst[i]->win == dq->win) && (!lst[i]->shape_propagate) + && (!lst[i]->text)) + { + already = 1; + i = num; + } + } + } + else if (dq->pager) + { + for (i = 0; i < num; i++) + { + if ((lst[i]->win == dq->win) && (lst[i]->pager)) + { + already = 1; + i = num; + } + } + } + else if (dq->redraw_pager) + { + for (i = 0; i < num; i++) + { + if ((lst[i]->win == dq->win) && (lst[i]->redraw_pager)) + { + switch (dq->newbg) + { + case 0: + if (lst[i]->newbg == 1) + dq->newbg = 1; + if (lst[i]->newbg == 2) + dq->newbg = 1; + break; + case 1: + break; + case 2: + if (lst[i]->newbg == 1) + dq->newbg = 1; + else if (lst[i]->newbg == 0) + dq->newbg = 1; + break; + case 3: + if (lst[i]->newbg == 0) + dq->newbg = 0; + else if (lst[i]->newbg == 1) + dq->newbg = 1; + else if (lst[i]->newbg == 2) + dq->newbg = 2; + break; + default: + break; + } + already = 1; + i = num; + } + } + } + if (already) + { + if (dq) + { + if (dq->iclass) + dq->iclass->ref_count--; + if (dq->tclass) + dq->tclass->ref_count--; + Efree(dq); + } + } + else + { + num++; + lst = Erealloc(lst, num * sizeof(DrawQueue *)); + lst[num - 1] = dq; + } + } + /* go thru the list in chronological order (ie reverse) and do the draws */ + if (lst) + { + for (i = num - 1; i >= 0; i--) + { + if (lst[i]->shape_propagate) + { + PropagateShapes(lst[i]->win); +/* printf("S %x\n", lst[i]->win); */ + } + else if (lst[i]->text) + { + TclassApply(lst[i]->iclass, lst[i]->win, lst[i]->w, lst[i]->h, + lst[i]->active, lst[i]->sticky, lst[i]->state, + lst[i]->expose, lst[i]->tclass, lst[i]->text); + Efree(lst[i]->text); +/* printf("T %x\n", lst[i]->win); */ + } + else if (lst[i]->iclass) + { + IclassApply(lst[i]->iclass, lst[i]->win, lst[i]->w, lst[i]->h, + lst[i]->active, lst[i]->sticky, lst[i]->state, + 0); +/* printf("I %x\n", lst[i]->win); */ + } + else if (lst[i]->pager) + { + if (FindItem((char *)(lst[i]->pager), 0, + LIST_FINDBY_POINTER, LIST_TYPE_PAGER)) + PagerForceUpdate(lst[i]->pager); +/* printf("P %x\n", lst[i]->win); */ + } + else if (lst[i]->redraw_pager) + { + if (FindItem((char *)(lst[i]->redraw_pager), 0, + LIST_FINDBY_POINTER, LIST_TYPE_PAGER)) + PagerRedraw(lst[i]->redraw_pager, lst[i]->newbg); +/* printf("p %x\n", lst[i]->win); */ + } + Efree(lst[i]); + } + Efree(lst); + } + queue_up = p_queue; + EDBUG_RETURN_; +} + +char +IsPropagateEwinOnQueue(EWin * ewin) +{ + EDBUG(6, "IsPropagateOnQueue"); + + if (FindItem(NULL, ewin->win, LIST_FINDBY_ID, LIST_TYPE_DRAW)) + EDBUG_RETURN(1); + EDBUG_RETURN(0); +} + +void +EFillPixmap(Window win, Pixmap pmap, int x, int y, int w, int h) +{ + XGCValues gcv; + GC gc; + + gcv.subwindow_mode = IncludeInferiors; + gc = XCreateGC(disp, win, GCSubwindowMode, &gcv); + XCopyArea(disp, win, pmap, gc, x, y, w, h, x, y); + XFreeGC(disp, gc); +} + +void +EPastePixmap(Window win, Pixmap pmap, int x, int y, int w, int h) +{ + XGCValues gcv; + GC gc; + + gcv.subwindow_mode = IncludeInferiors; + gc = XCreateGC(disp, win, GCSubwindowMode, &gcv); + XCopyArea(disp, pmap, win, gc, x, y, w, h, x, y); + XFreeGC(disp, gc); +} + +PixImg * +ECreatePixImg(Window win, int w, int h) +{ + XGCValues gcv; + int bpp; + PixImg *pi; + + if (id->x.depth <= 8) + bpp = 1; + else if (id->x.depth <= 16) + bpp = 2; + else if (id->x.depth <= 24) + bpp = 3; + else + bpp = 4; + if ((id->max_shm) && ((bpp * w * h) > id->max_shm)) + return NULL; + if ((!id->x.shm) || (!id->x.shmp)) + return NULL; + + pi = Emalloc(sizeof(PixImg)); + pi->shminfo = Emalloc(sizeof(XShmSegmentInfo)); + pi->xim = XShmCreateImage(disp, root.vis, root.depth, ZPixmap, NULL, + pi->shminfo, w, h); + pi->shminfo->shmid = shmget(IPC_PRIVATE, pi->xim->bytes_per_line * + pi->xim->height, IPC_CREAT | 0666); + pi->shminfo->shmaddr = pi->xim->data = shmat(pi->shminfo->shmid, 0, 0); + pi->shminfo->readOnly = False; + XShmAttach(disp, pi->shminfo); + pi->pmap = XShmCreatePixmap(disp, win, pi->shminfo->shmaddr, pi->shminfo, + w, h, root.depth); + gcv.subwindow_mode = IncludeInferiors; + pi->gc = XCreateGC(disp, win, GCSubwindowMode, &gcv); + return pi; +} + +void +EDestroyPixImg(PixImg * pi) +{ + XSync(disp, False); + XShmDetach(disp, pi->shminfo); + shmdt(pi->shminfo->shmaddr); + shmctl(pi->shminfo->shmid, IPC_RMID, 0); + XDestroyImage(pi->xim); + Efree(pi->shminfo); + XFreePixmap(disp, pi->pmap); + XFreeGC(disp, pi->gc); + Efree(pi); +} + +void +EBlendRemoveShape(EWin * ewin, Pixmap pmap) +{ + XGCValues gcv; + int i, x, y, w, h; + static GC gc = 0, gcm = 0; + static int rn, ord; + static XRectangle *rl = NULL; + static Pixmap mask = 0; + + if (!ewin) + { + if (rl) + XFree(rl); + if (gc) + XFreeGC(disp, gc); + if (gcm) + XFreeGC(disp, gcm); + if (mask) + EFreePixmap(disp, mask); + mask = 0; + gc = 0; + gcm = 0; + rl = NULL; + return; + } + if ((ewin->sticky) || (ewin->floating)) + { + x = ewin->x; + y = ewin->y; + } + else + { + x = ewin->x + desks.desk[ewin->desktop].x; + y = ewin->y + desks.desk[ewin->desktop].y; + } + w = ewin->w; + h = ewin->h; + + if (x < 0) + { + w += x; + x = 0; + } + if ((x + w) > root.w) + w -= (x + w) - root.w; + if (w < 0) + w = 0; + if (y < 0) + { + h += y; + y = 0; + } + if ((y + h) > root.h) + h -= (y + h) - root.h; + if (h < 0) + h = 0; + if ((w <= 0) || (h <= 0)) + return; + if (!rl) + { + rl = EShapeGetRectangles(disp, ewin->win, ShapeBounding, &rn, &ord); + if (rn < 1) + return; + else if (rn == 1) + { + if ((rl[0].x == 0) && (rl[0].y == 0) && + (rl[0].width == ewin->w) && (rl[0].height == ewin->h)) + { + if (rl) + XFree(rl); + rl = NULL; + return; + } + } + } + if (!mask) + mask = ECreatePixmap(disp, root.win, w, h, 1); + if (!gcm) + gcm = XCreateGC(disp, mask, 0, &gcv); + if (!gc) + { + gcv.subwindow_mode = IncludeInferiors; + gc = XCreateGC(disp, root.win, GCSubwindowMode, &gcv); + XSetForeground(disp, gcm, 1); + XFillRectangle(disp, mask, gcm, 0, 0, w, h); + XSetForeground(disp, gcm, 0); + for (i = 0; i < rn; i++) + XFillRectangle(disp, mask, gcm, rl[i].x, rl[i].y, rl[i].width, rl[i].height); + XSetClipMask(disp, gc, mask); + } + XSetClipOrigin(disp, gc, x, y); + XCopyArea(disp, pmap, root.win, gc, x, y, w, h, x, y); +} + +void +EBlendPixImg(EWin * ewin, PixImg * s1, PixImg * s2, PixImg * dst, int x, int y, int w, int h) +{ + int ox, oy; + int i, j; + XGCValues gcv; + static int rn, ord; + static XRectangle *rl = NULL; + static GC gc = 0; + + if (!s1) + { + if (gc) + XFreeGC(disp, gc); + if (rl > (XRectangle *) 1) + XFree(rl); + gc = 0; + rl = NULL; + return; + } + if (!gc) + { + gcv.subwindow_mode = IncludeInferiors; + gc = XCreateGC(disp, root.win, GCSubwindowMode, &gcv); + } + if (!rl) + { + rl = EShapeGetRectangles(disp, ewin->win, ShapeBounding, &rn, &ord); + if (rl) + XSetClipRectangles(disp, gc, x, y, rl, rn, ord); + if (!rl) + rl = (XRectangle *) 1; + } + else + XSetClipOrigin(disp, gc, x, y); + ox = 0; + oy = 0; + if ((x >= root.w) || (y >= root.h)) + return; + if (x + w > root.w) + w -= ((x + w) - root.w); + if (x < 0) + { + ox = -x; + w -= ox; + x = 0; + } + if (y + h > root.h) + h -= ((y + h) - root.h); + if (y < 0) + { + oy = -y; + h -= oy; + y = 0; + } + if ((w <= 0) || (h <= 0)) + return; + XSync(disp, False); + if (dst) + { + switch (dst->xim->bits_per_pixel) + { + case 32: + for (j = 0; j < h; j++) + { + unsigned int *ptr1, *ptr2, *ptr3; + + ptr1 = (unsigned int *) + (s1->xim->data + + ((x) * ((s1->xim->bits_per_pixel) >> 3)) + + ((j + y) * s1->xim->bytes_per_line)); + ptr2 = (unsigned int *) + (s2->xim->data + + ((ox) * ((s2->xim->bits_per_pixel) >> 3)) + + ((j + oy) * s2->xim->bytes_per_line)); + ptr3 = (unsigned int *) + (dst->xim->data + + ((ox) * ((dst->xim->bits_per_pixel) >> 3)) + + ((j + oy) * dst->xim->bytes_per_line)); + for (i = 0; i < w; i++) + { + unsigned int p1, p2; + + p1 = *ptr1++; + p2 = *ptr2++; + *ptr3++ = ((p1 >> 1) & 0x7f7f7f7f) + ((p2 >> 1) & 0x7f7f7f7f) + + (p1 & p2 & 0x01010101); + } + } + break; + case 16: + if (id->x.render_depth != 15) + { + for (j = 0; j < h; j++) + { + unsigned int *ptr1, *ptr2, *ptr3; + + ptr1 = (unsigned int *) + (s1->xim->data + + ((x) * ((s1->xim->bits_per_pixel) >> 3)) + + ((j + y) * s1->xim->bytes_per_line)); + ptr2 = (unsigned int *) + (s2->xim->data + + ((ox) * ((s2->xim->bits_per_pixel) >> 3)) + + ((j + oy) * s2->xim->bytes_per_line)); + ptr3 = (unsigned int *) + (dst->xim->data + + ((ox) * ((dst->xim->bits_per_pixel) >> 3)) + + ((j + oy) * dst->xim->bytes_per_line)); + if (!(w & 0x1)) + { + for (i = 0; i < w; i += 2) + { + unsigned int p1, p2; + + p1 = *ptr1++; + p2 = *ptr2++; + *ptr3++ = + ((p1 >> 1) & ((0x78 << 8) | (0x7c << 3) | (0x78 >> 3) | + (0x78 << 24) | (0x7c << 19) | (0x78 << 13))) + + ((p2 >> 1) & ((0x78 << 8) | (0x7c << 3) | (0x78 >> 3) | + (0x78 << 24) | (0x7c << 19) | (0x78 << 13))) + + (p1 & p2 & ((0x1 << 11) | (0x1 << 5) | (0x1) | + (0x1 << 27) | (0x1 << 21) | (0x1 << 16))); + } + } + else + { + for (i = 0; i < (w - 1); i += 2) + { + unsigned int p1, p2; + + p1 = *ptr1++; + p2 = *ptr2++; + *ptr3++ = + ((p1 >> 1) & ((0x78 << 8) | (0x7c << 3) | (0x78 >> 3) | + (0x78 << 24) | (0x7c << 19) | (0x78 << 13))) + + ((p2 >> 1) & ((0x78 << 8) | (0x7c << 3) | (0x78 >> 3) | + (0x78 << 24) | (0x7c << 19) | (0x78 << 13))) + + (p1 & p2 & ((0x1 << 11) | (0x1 << 5) | (0x1) | + (0x1 << 27) | (0x1 << 21) | (0x1 << 16))); + } + { + unsigned short *pptr1, *pptr2, *pptr3; + unsigned short pp1, pp2; + + pptr1 = (unsigned short *)ptr1; + pptr2 = (unsigned short *)ptr2; + pptr3 = (unsigned short *)ptr3; + pp1 = *pptr1; + pp2 = *pptr2; + *pptr3 = ((pp1 >> 1) & ((0x78 << 8) | (0x7c << 3) | (0x78 >> 3))) + + ((pp2 >> 1) & ((0x78 << 8) | (0x7c << 3) | (0x78 >> 3))) + + (pp1 & pp2 & ((0x1 << 11) | (0x1 << 5) | (0x1))); + } + } + } + } + else + { + for (j = 0; j < h; j++) + { + unsigned int *ptr1, *ptr2, *ptr3; + + ptr1 = (unsigned int *) + (s1->xim->data + + ((x) * ((s1->xim->bits_per_pixel) >> 3)) + + ((j + y) * s1->xim->bytes_per_line)); + ptr2 = (unsigned int *) + (s2->xim->data + + ((ox) * ((s2->xim->bits_per_pixel) >> 3)) + + ((j + oy) * s2->xim->bytes_per_line)); + ptr3 = (unsigned int *) + (dst->xim->data + + ((ox) * ((dst->xim->bits_per_pixel) >> 3)) + + ((j + oy) * dst->xim->bytes_per_line)); + if (!(w & 0x1)) + { + for (i = 0; i < w; i += 2) + { + unsigned int p1, p2; + + p1 = *ptr1++; + p2 = *ptr2++; + *ptr3++ = + ((p1 >> 1) & ((0x78 << 7) | (0x78 << 2) | (0x78 >> 3) | + (0x78 << 23) | (0x78 << 18) | (0x78 << 13))) + + ((p2 >> 1) & ((0x78 << 7) | (0x78 << 2) | (0x78 >> 3) | + (0x78 << 23) | (0x78 << 18) | (0x78 << 13))) + + (p1 & p2 & ((0x1 << 10) | (0x1 << 5) | (0x1) | + (0x1 << 26) | (0x1 << 20) | (0x1 << 16))); + } + } + else + { + for (i = 0; i < (w - 1); i += 2) + { + unsigned int p1, p2; + + p1 = *ptr1++; + p2 = *ptr2++; + *ptr3++ = + ((p1 >> 1) & ((0x78 << 7) | (0x78 << 2) | (0x78 >> 3) | + (0x78 << 23) | (0x78 << 18) | (0x78 << 13))) + + ((p2 >> 1) & ((0x78 << 7) | (0x78 << 2) | (0x78 >> 3) | + (0x78 << 23) | (0x78 << 18) | (0x78 << 13))) + + (p1 & p2 & ((0x1 << 10) | (0x1 << 5) | (0x1) | + (0x1 << 26) | (0x1 << 20) | (0x1 << 16))); + } + { + unsigned short *pptr1, *pptr2, *pptr3; + unsigned short pp1, pp2; + + pptr1 = (unsigned short *)ptr1; + pptr2 = (unsigned short *)ptr2; + pptr3 = (unsigned short *)ptr3; + pp1 = *pptr1; + pp2 = *pptr2; + *pptr3++ = ((pp1 >> 1) & ((0x78 << 7) | (0x78 << 2) | (0x78 >> 3))) + + ((pp2 >> 1) & ((0x78 << 7) | (0x78 << 2) | (0x78 >> 3))) + + (pp1 & pp2 & ((0x1 << 10) | (0x1 << 5) | (0x1))); + } + } + } + } + break; + default: + for (j = 0; j < h; j++) + { + unsigned char *ptr1, *ptr2, *ptr3; + + ptr1 = (unsigned char *) + (s1->xim->data + + ((x) * ((s1->xim->bits_per_pixel) >> 3)) + + ((j + y) * s1->xim->bytes_per_line)); + ptr2 = (unsigned char *) + (s2->xim->data + + ((ox) * ((s2->xim->bits_per_pixel) >> 3)) + + ((j + oy) * s2->xim->bytes_per_line)); + ptr3 = (unsigned char *) + (dst->xim->data + + ((ox) * ((dst->xim->bits_per_pixel) >> 3)) + + ((j + oy) * dst->xim->bytes_per_line)); + if (!(w & 0x1)) + { + if (j & 0x1) + { + ptr2++; + for (i = 0; i < w; i += 2) + { + unsigned char p1; + + p1 = *ptr1; + ptr1 += 2; + *ptr3++ = p1; + p1 = *ptr2; + ptr2 += 2; + *ptr3++ = p1; + } + } + else + { + ptr1++; + for (i = 0; i < w; i += 2) + { + unsigned char p1; + + p1 = *ptr2; + ptr2 += 2; + *ptr3++ = p1; + p1 = *ptr1; + ptr1 += 2; + *ptr3++ = p1; + } + } + } + else + { + if (j & 0x1) + { + ptr2++; + for (i = 0; i < (w - 1); i += 2) + { + unsigned char p1; + + p1 = *ptr1; + ptr1 += 2; + *ptr3++ = p1; + p1 = *ptr2; + ptr2 += 2; + *ptr3++ = p1; + } + *ptr3 = *ptr1; + } + else + { + ptr1++; + for (i = 0; i < (w - 1); i += 2) + { + unsigned char p1; + + p1 = *ptr2; + ptr2 += 2; + *ptr3++ = p1; + p1 = *ptr1; + ptr1 += 2; + *ptr3++ = p1; + } + *ptr3 = *ptr2; + } + } + } + break; + } +/* workaround since XCopyArea doesnt always work with shared pixmaps */ + XShmPutImage(disp, root.win, gc, dst->xim, ox, oy, x, y, w, h, False); + } +/* I dont believe it - you cannot do this to a shared pixmaps to the screen */ +/* XCopyArea(disp, dst->pmap, root.win, dst->gc, x, y, w, h, x, y); */ +} + +#include +#include +#include + +void +DrawEwinShape(EWin * ewin, int md, int x, int y, int w, int h, char firstlast) +{ + static GC gc = 0; + XGCValues gcv; + int x1, y1, w1, h1, i, j, pw, ph; + static Pixmap b1 = 0, b2 = 0, b3 = 0; + static Font font = 0; + int bpp; + char str[32]; + + EDBUG(4, "DrawEwinShape"); + if ((mode.mode == MODE_RESIZE) || + (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V)) + { + w1 = ewin->client.w; + h1 = ewin->client.h; + ewin->client.w = w; + ewin->client.h = h; + ICCCM_MatchSize(ewin); + i = (x - ewin->x) / ewin->client.w_inc; + j = (y - ewin->y) / ewin->client.h_inc; + x = ewin->x + (i * ewin->client.w_inc); + y = ewin->y + (j * ewin->client.h_inc); + ewin->client.w = w1; + ewin->client.h = h1; + } + if ((md == 5) + && ((mode.mode == MODE_RESIZE) || + (mode.mode == MODE_RESIZE_H) || + (mode.mode == MODE_RESIZE_V) || + (ewin->group && ewin->group->move))) + md = 0; + if (md == 5) + { + if (id->x.depth <= 8) + bpp = 1; + else if (id->x.depth <= 16) + bpp = 2; + else if (id->x.depth <= 24) + bpp = 3; + else + bpp = 4; + if ((ird) || + ((id->max_shm) && ((bpp * w * h) > id->max_shm)) || + ((!id->x.shm) || (!id->x.shmp))) + md = 0; + } + pw = w; + ph = h; + switch (md) + { + case 0: + MoveResizeEwin(ewin, x, y, w, h); + if (mode.mode != MODE_NONE) + SetCoords(ewin->x, ewin->y, + (ewin->client.w - ewin->client.base_w) / ewin->client.w_inc, + (ewin->client.h - ewin->client.base_h) / ewin->client.h_inc); + break; + case 1: + case 2: + case 3: + case 4: + case 5: + if (!b1) + b1 = XCreateBitmapFromData(disp, root.win, flipped_gray_bits, + flipped_gray_width, + flipped_gray_height); + if (!b2) + b2 = XCreateBitmapFromData(disp, root.win, gray_bits, + gray_width, + gray_height); + if (!b3) + b3 = XCreateBitmapFromData(disp, root.win, gray3_bits, + gray3_width, + gray3_height); + x1 = ewin->x + desks.desk[ewin->desktop].x; + y1 = ewin->y + desks.desk[ewin->desktop].y; + w1 = ewin->w - (ewin->border->border.left + ewin->border->border.right); + h1 = ewin->h - (ewin->border->border.top + ewin->border->border.bottom); + ewin->x = x; + ewin->y = y; + ewin->reqx = x; + ewin->reqy = y; + x = ewin->x + desks.desk[ewin->desktop].x; + y = ewin->y + desks.desk[ewin->desktop].y; + if ((w != ewin->client.w) || (h != ewin->client.h)) + { + ewin->client.w = w; + ewin->client.h = h; + ICCCM_MatchSize(ewin); + ewin->w = ewin->client.w + ewin->border->border.left + ewin->border->border.right; + ewin->h = ewin->client.h + ewin->border->border.top + ewin->border->border.bottom; + } + w = ewin->w - (ewin->border->border.left + ewin->border->border.right); + h = ewin->h - (ewin->border->border.top + ewin->border->border.bottom); + if (!gc) + { + gcv.function = GXxor; + gcv.foreground = WhitePixel(disp, root.scr); + if (gcv.foreground == 0) + gcv.foreground = BlackPixel(disp, root.scr); + gcv.subwindow_mode = IncludeInferiors; + gc = XCreateGC(disp, root.win, GCFunction | GCForeground | GCSubwindowMode, &gcv); + } +#define DRAW_H_ARROW(x1, x2, y1) \ + if (((x2) - (x1)) >= 12) \ + { \ + XDrawLine(disp, root.win, gc, x1, y1, (x1) + 6, (y1) - 3); \ + XDrawLine(disp, root.win, gc, x1, y1, (x1) + 6, (y1) + 3); \ + XDrawLine(disp, root.win, gc, x2, y1, (x2) - 6, (y1) - 3); \ + XDrawLine(disp, root.win, gc, x2, y1, (x2) - 6, (y1) + 3); \ + } \ + if ((x2) >= (x1)) \ + { \ + XDrawLine(disp, root.win, gc, x1, y1, x2, y1); \ + Esnprintf(str, sizeof(str), "%i", (x2) - (x1) + 1); \ + XDrawString(disp, root.win, gc, ((x1) + (x2)) / 2, (y1) - 10, str, strlen(str)); \ + } +#define DRAW_V_ARROW(y1, y2, x1) \ + if (((y2) - (y1)) >= 12) \ + { \ + XDrawLine(disp, root.win, gc, x1, y1, (x1) + 3, (y1) + 6); \ + XDrawLine(disp, root.win, gc, x1, y1, (x1) - 3, (y1) + 6); \ + XDrawLine(disp, root.win, gc, x1, y2, (x1) + 3, (y2) - 6); \ + XDrawLine(disp, root.win, gc, x1, y2, (x1) - 3, (y2) - 6); \ + } \ + if ((y2) >= (y1)) \ + { \ + XDrawLine(disp, root.win, gc, x1, y1, x1, y2); \ + Esnprintf(str, sizeof(str), "%i", (y2) - (y1) + 1); \ + XDrawString(disp, root.win, gc, x1 + 10, ((y1) + (y2)) / 2, str, strlen(str)); \ + } +#define DO_DRAW_MODE_1(aa, bb, cc, dd) \ + if (!font) \ + font = XLoadFont(disp, "-*-helvetica-medium-r-*-*-10-*-*-*-*-*-*-*"); \ + XSetFont(disp, gc, font); \ + if (cc < 3) cc = 3; \ + if (dd < 3) dd = 3; \ + DRAW_H_ARROW(aa + ewin->border->border.left, \ + aa + ewin->border->border.left + cc - 1, \ + bb + ewin->border->border.top + dd - 16); \ + DRAW_H_ARROW(0, \ + aa - 1, \ + bb + ewin->border->border.top + (dd / 2)); \ + DRAW_H_ARROW(aa + cc + ewin->border->border.left + ewin->border->border.right, \ + root.w - 1, \ + bb + ewin->border->border.top + (dd / 2)); \ + DRAW_V_ARROW(bb + ewin->border->border.top, \ + bb + ewin->border->border.top + dd - 1, \ + aa + ewin->border->border.left + 16); \ + DRAW_V_ARROW(0, \ + bb - 1, \ + aa + ewin->border->border.left + (cc / 2)); \ + DRAW_V_ARROW(bb + dd + ewin->border->border.top + ewin->border->border.bottom, \ + root.h - 1, \ + aa + ewin->border->border.left + (cc / 2)); \ + XDrawLine(disp, root.win, gc, aa, 0, aa, root.h); \ + XDrawLine(disp, root.win, gc, \ + aa + cc + ewin->border->border.left + \ + ewin->border->border.right - 1, 0, \ + aa + cc + ewin->border->border.left + \ + ewin->border->border.right - 1, root.h); \ + XDrawLine(disp, root.win, gc, 0, bb, root.w, bb); \ + XDrawLine(disp, root.win, gc, 0, \ + bb + dd + ewin->border->border.top + \ + ewin->border->border.bottom - 1, root.w, \ + bb + dd + ewin->border->border.top + \ + ewin->border->border.bottom - 1); \ + XDrawRectangle(disp, root.win, gc, aa + ewin->border->border.left + 1, \ + bb + ewin->border->border.top + 1, cc - 3, dd - 3); + +#define DO_DRAW_MODE_2(aa, bb, cc, dd) \ + if (cc < 3) cc = 3; \ + if (dd < 3) dd = 3; \ + XDrawRectangle(disp, root.win, gc, aa, bb, \ + cc + ewin->border->border.left + \ + ewin->border->border.right - 1, \ + dd + ewin->border->border.top + \ + ewin->border->border.bottom - 1); \ + XDrawRectangle(disp, root.win, gc, aa + ewin->border->border.left + 1, \ + bb + ewin->border->border.top + 1, cc - 3, dd - 3); + +#define DO_DRAW_MODE_3(aa, bb, cc, dd) \ + XSetFillStyle(disp, gc, FillStippled); \ + XSetStipple(disp, gc, b2); \ + if ((cc + ewin->border->border.left + ewin->border->border.right > 0) && \ + (ewin->border->border.top > 0)) \ + XFillRectangle(disp, root.win, gc, aa, bb, \ + cc + ewin->border->border.left + \ + ewin->border->border.right, \ + ewin->border->border.top); \ + if ((cc + ewin->border->border.left + ewin->border->border.right > 0) && \ + (ewin->border->border.bottom > 0)) \ + XFillRectangle(disp, root.win, gc, aa, bb + dd + \ + ewin->border->border.top, \ + cc + ewin->border->border.left + \ + ewin->border->border.right, \ + ewin->border->border.bottom); \ + if ((dd > 0) && (ewin->border->border.left > 0)) \ + XFillRectangle(disp, root.win, gc, aa, bb + ewin->border->border.top, \ + ewin->border->border.left, \ + dd); \ + if ((dd > 0) && (ewin->border->border.right > 0)) \ + XFillRectangle(disp, root.win, gc, aa + cc + ewin->border->border.left, \ + bb + ewin->border->border.top, \ + ewin->border->border.right, \ + dd); \ + XSetStipple(disp, gc, b3); \ + if ((cc > 0) && (dd > 0)) \ + XFillRectangle(disp, root.win, gc, aa + ewin->border->border.left + 1, \ + bb + ewin->border->border.top + 1, cc - 3, dd - 3); + +#define DO_DRAW_MODE_4(aa, bb, cc, dd) \ + XSetFillStyle(disp, gc, FillStippled); \ + XSetStipple(disp, gc, b2); \ + XFillRectangle(disp, root.win, gc, aa, bb, \ + cc + ewin->border->border.left + \ + ewin->border->border.right, \ + dd + ewin->border->border.top + \ + ewin->border->border.bottom); + if (md == 1) + { + if (firstlast > 0) + { + DO_DRAW_MODE_1(x1, y1, w1, h1); + } + if ((mode.mode != MODE_NONE) && + (!ewin->group || (ewin->group && !ewin->group->move))) + SetCoords(ewin->x, ewin->y, + (ewin->client.w - ewin->client.base_w) / ewin->client.w_inc, + (ewin->client.h - ewin->client.base_h) / ewin->client.h_inc); + if (firstlast < 2) + { + DO_DRAW_MODE_1(x, y, w, h); + } + } + else if (md == 2) + { + if (firstlast > 0) + { + DO_DRAW_MODE_2(x1, y1, w1, h1); + } + if ((mode.mode != MODE_NONE) && + (!ewin->group || (ewin->group && !ewin->group->move))) + SetCoords(ewin->x, ewin->y, + (ewin->client.w - ewin->client.base_w) / ewin->client.w_inc, + (ewin->client.h - ewin->client.base_h) / ewin->client.h_inc); + if (firstlast < 2) + { + DO_DRAW_MODE_2(x, y, w, h); + } + } + else if (md == 3) + { + if (firstlast > 0) + { + DO_DRAW_MODE_3(x1, y1, w1, h1); + } + if ((mode.mode != MODE_NONE) && + (!ewin->group || (ewin->group && !ewin->group->move))) + SetCoords(ewin->x, ewin->y, + (ewin->client.w - ewin->client.base_w) / ewin->client.w_inc, + (ewin->client.h - ewin->client.base_h) / ewin->client.h_inc); + if (firstlast < 2) + { + DO_DRAW_MODE_3(x, y, w, h); + } + } + else if (md == 4) + { + if (firstlast > 0) + { + DO_DRAW_MODE_4(x1, y1, w1, h1); + } + if (firstlast < 2) + if ((mode.mode != MODE_NONE) && + (!ewin->group || (ewin->group && !ewin->group->move))) + SetCoords(ewin->x, ewin->y, + (ewin->client.w - ewin->client.base_w) / ewin->client.w_inc, + (ewin->client.h - ewin->client.base_h) / ewin->client.h_inc); + if (firstlast < 2) + { + DO_DRAW_MODE_4(x, y, w, h); + } + } + else if (md == 5) + { + static PixImg *ewin_pi = NULL; + static PixImg *root_pi = NULL; + static PixImg *draw_pi = NULL; + + if (mode.mode != MODE_NONE) + SetCoords(ewin->x, ewin->y, + (ewin->client.w - ewin->client.base_w) / ewin->client.w_inc, + (ewin->client.h - ewin->client.base_h) / ewin->client.h_inc); + if (firstlast == 0) + { + if (ewin_pi) + EDestroyPixImg(ewin_pi); + if (root_pi) + EDestroyPixImg(root_pi); + if (draw_pi) + EDestroyPixImg(draw_pi); + EBlendRemoveShape(NULL, 0); + EBlendPixImg(NULL, NULL, NULL, NULL, 0, 0, 0, 0); + ewin_pi = NULL; + root_pi = NULL; + draw_pi = NULL; + root_pi = ECreatePixImg(root.win, root.w, root.h); + ewin_pi = ECreatePixImg(root.win, ewin->w, ewin->h); + draw_pi = ECreatePixImg(root.win, ewin->w, ewin->h); + EFillPixmap(root.win, root_pi->pmap, x1, y1, ewin->w, ewin->h); + EFillPixmap(ewin->win, ewin_pi->pmap, 0, 0, ewin->w, ewin->h); + EBlendPixImg(ewin, root_pi, ewin_pi, draw_pi, x, y, + ewin->w, ewin->h); + } + else if (firstlast == 1) + { + int dx, dy, wt, ht; + int adx, ady; + + dx = x - x1; + dy = y - y1; + if (dx < 0) + adx = -dx; + else + adx = dx; + if (dy < 0) + ady = -dy; + else + ady = dy; + wt = ewin->w; + ht = ewin->h; + if ((adx <= wt) && (ady <= ht)) + { + if (dx < 0) + EFillPixmap(root.win, root_pi->pmap, x, y, -dx, ht); + else if (dx > 0) + EFillPixmap(root.win, root_pi->pmap, x + wt - dx, y, dx, ht); + if (dy < 0) + EFillPixmap(root.win, root_pi->pmap, x, y, wt, -dy); + else if (dy > 0) + EFillPixmap(root.win, root_pi->pmap, x, y + ht - dy, wt, dy); + } + else + EFillPixmap(root.win, root_pi->pmap, x, y, wt, ht); + if ((adx <= wt) && (ady <= ht)) + { + EBlendPixImg(ewin, root_pi, ewin_pi, draw_pi, x, y, + ewin->w, ewin->h); + if (dx > 0) + EPastePixmap(root.win, root_pi->pmap, x1, y1, dx, ht); + else if (dx < 0) + EPastePixmap(root.win, root_pi->pmap, x1 + wt + dx, y1, -dx, ht); + if (dy > 0) + EPastePixmap(root.win, root_pi->pmap, x1, y1, wt, dy); + else if (dy < 0) + EPastePixmap(root.win, root_pi->pmap, x1, y1 + ht + dy, wt, -dy); + } + else + { + EPastePixmap(root.win, root_pi->pmap, x1, y1, wt, ht); + EBlendPixImg(ewin, root_pi, ewin_pi, draw_pi, x, y, + ewin->w, ewin->h); + } + EBlendRemoveShape(ewin, root_pi->pmap); + } + else if (firstlast == 2) + { + EPastePixmap(root.win, root_pi->pmap, x1, y1, ewin->w, ewin->h); + if (ewin_pi) + EDestroyPixImg(ewin_pi); + if (root_pi) + EDestroyPixImg(root_pi); + if (draw_pi) + EDestroyPixImg(draw_pi); + EBlendRemoveShape(NULL, 0); + EBlendPixImg(NULL, NULL, NULL, NULL, 0, 0, 0, 0); + ewin_pi = NULL; + root_pi = NULL; + draw_pi = NULL; + } + else if (firstlast == 3) + { + EPastePixmap(root.win, root_pi->pmap, x, y, ewin->w, ewin->h); + if (root_pi) + EDestroyPixImg(root_pi); + root_pi->pmap = 0; + } + else if (firstlast == 4) + { + int wt, ht; + + wt = ewin->w; + ht = ewin->h; + root_pi = ECreatePixImg(root.win, root.w, root.h); + EFillPixmap(root.win, root_pi->pmap, x, y, wt, ht); + EBlendPixImg(ewin, root_pi, ewin_pi, draw_pi, x, y, + ewin->w, ewin->h); + } + else if (firstlast == 5) + { + if (root_pi) + EDestroyPixImg(root_pi); + root_pi->pmap = 0; + } + } + if (firstlast == 2) + { + /* If we're moving a group, don't do this, + * otherwise we have a lot of garbage onscreen */ + if (!ewin->floating || !ewin->group || (ewin->group && !ewin->group->move)) + { + if (ewin->shaded) + MoveEwin(ewin, ewin->x, ewin->y); + else + MoveResizeEwin(ewin, ewin->x, ewin->y, pw, ph); + } + XFreeGC(disp, gc); + gc = 0; + } + break; + default: + break; + } + EDBUG_RETURN_; +} + +ImlibImage * +ELoadImage(char *file) +{ + EDBUG(5, "ELoadImage"); + EDBUG_RETURN(ELoadImageImlibData(id, file)); +} + +ImlibImage * +ELoadImageImlibData(ImlibData * imd, char *file) +{ + ImlibImage *im; + char *f = NULL; + + EDBUG(5, "ELoadImageImlibData"); + if (!file) + EDBUG_RETURN(NULL); + if (file[0] == '/') + { + EDBUG_RETURN(Imlib_load_image(imd, file)); + } + else + f = FindFile(file); + if (f) + { + im = Imlib_load_image(imd, f); + Efree(f); + EDBUG_RETURN(im); + } + EDBUG_RETURN(NULL); +} + +void +PropagateShapes(Window win) +{ + Window rt, par, *list = NULL; + int k, i, num = 0, num_rects = 0, rn = 0, ord; + int x, y; + unsigned int ww, hh, w, h, d; + XRectangle *rects = NULL, *rl = NULL; + XWindowAttributes att; + + EDBUG(6, "PropagateShapes"); + if (queue_up) + { + DrawQueue *dq; + + dq = Emalloc(sizeof(DrawQueue)); + dq->win = win; + dq->iclass = NULL; + dq->w = 0; + dq->h = 0; + dq->active = 0; + dq->sticky = 0; + dq->state = 0; + dq->expose = 0; + dq->tclass = NULL; + dq->text = NULL; + dq->shape_propagate = 1; + dq->pager = NULL; + dq->redraw_pager = NULL; + AddItem(dq, "DRAW", dq->win, LIST_TYPE_DRAW); + EDBUG_RETURN_; + } + EGetGeometry(disp, win, &rt, &x, &y, &w, &h, &d, &d); + if ((w <= 0) || (h <= 0)) + EDBUG_RETURN_; + + ww = w; + hh = h; + + XQueryTree(disp, win, &rt, &par, &list, (unsigned int *)&num); + if (list) + { + /* go through all child windows and create/inset spans */ + for (i = 0; i < num; i++) + { + XGetWindowAttributes(disp, list[i], &att); + x = att.x; + y = att.y; + w = att.width; + h = att.height; + if ((att.class == InputOutput) && (att.map_state != IsUnmapped)) + { + rl = NULL; + rl = EShapeGetRectangles(disp, list[i], ShapeBounding, &rn, &ord); + if (rl) + { + num_rects += rn; + if (rn > 0) + { + rects = Erealloc(rects, num_rects * sizeof(XRectangle)); + /* go through all clip rects in thsi window's shape */ + for (k = 0; k < rn; k++) + { + /* for each clip rect, add it to the rect list */ + rects[num_rects - rn + k].x = x + rl[k].x; + rects[num_rects - rn + k].y = y + rl[k].y; + rects[num_rects - rn + k].width = rl[k].width; + rects[num_rects - rn + k].height = rl[k].height; + } + } + XFree(rl); + } + else + { + num_rects++; + rects = Erealloc(rects, num_rects * sizeof(XRectangle)); + + rects[num_rects - 1].x = x; + rects[num_rects - 1].y = y; + rects[num_rects - 1].width = w; + rects[num_rects - 1].height = h; + } + } + } + /* set the rects as the shape mask */ + if (rects) + { + EShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rects, num_rects, + ShapeSet, Unsorted); + Efree(rects); + rl = NULL; + rl = EShapeGetRectangles(disp, win, ShapeBounding, &rn, &ord); + if (rl) + { + if (rn < 1) + EShapeCombineMask(disp, win, ShapeBounding, 0, 0, None, + ShapeSet); + else if (rn == 1) + { + if ((rl[0].x == 0) && (rl[0].y == 0) && + (rl[0].width == ww) && (rl[0].height == hh)) + EShapeCombineMask(disp, win, ShapeBounding, 0, 0, + None, ShapeSet); + } + XFree(rl); + } + else + EShapeCombineMask(disp, win, ShapeBounding, 0, 0, None, ShapeSet); + } + XFree(list); + } + EDBUG_RETURN_; +} diff --git a/src/ecvs b/src/ecvs new file mode 100644 index 00000000..1888cc4b --- /dev/null +++ b/src/ecvs @@ -0,0 +1,24 @@ +#!/bin/bash + +indent -i3 -bl -bad -nbap -sob -ncdb -di20 -nbc -lp -nce -npcs -sc -ncs -l80 \ +*.c *.h >& /dev/null + +if [ "$1" = "commit" -o "$1" = "ci" -o "$1" = "com" ]; then + echo "#define E_CHECKOUT_DATE \"\$Date\$\"" > timestamp.h +fi +cvs -z3 $@ + +if [ $USER = raster ]; then + indent -i3 -bl -bad -nbap -sob -ncdb -di20 -nbc -lp -nce -npcs -sc -ncs -l80 \ + *.c *.h >& /dev/null +elif [ $USER = kimball ]; then + indent -bad -bap -bli0 -cli0 -ss -di20 -nbc -lp -i4 -ts4 -ncs -nce -npcs \ + -sc -ncdb *.c *.h 1>/dev/null 2>&1 +elif [ $USER = mike ]; then + indent -i2 -bl -bad -nbap -sob -ncdb -di20 -nbc -lp -nce -npcs -sc -ncs -l80 \ + *.c *.h >& /dev/null +fi + + +rm *~ +touch timestamp.h diff --git a/src/events.c b/src/events.c new file mode 100644 index 00000000..2d039582 --- /dev/null +++ b/src/events.c @@ -0,0 +1,848 @@ +#include "E.h" +#include + +void DeskAccountTimeout(int val, void *data); + +HandleStruct HArray[] = +{ + {DefaultFunc}, + {DefaultFunc}, + {HKeyPress}, + {HKeyRelease}, + {HButtonPress}, + {HButtonRelease}, + {HMotionNotify}, + {HEnterNotify}, + {HLeaveNotify}, + {HFocusIn}, + {HFocusOut}, + {HKeymapNotify}, + {HExpose}, + {HGraphicsExpose}, + {HNoExpose}, + {HVisibilityNotify}, + {HCreateNotify}, + {HDestroyNotify}, + {HUnmapNotify}, + {HMapNotify}, + {HMapRequest}, + {HReparentNotify}, + {HConfigureNotify}, + {HConfigureRequest}, + {HGravityNotify}, + {HResizeRequest}, + {HCirculateNotify}, + {HCirculateRequest}, + {HPropertyNotify}, + {HSelectionClear}, + {HSelectionRequest}, + {HSelectionNotify}, + {HColormapNotify}, + {HClientMessage}, + {HMappingNotify}, + {DefaultFunc} +}; + +static char diddeskaccount = 1; + +void +DeskAccountTimeout(int val, void *data) +{ + EDBUG(5, "DeskAccountTimeout"); + + DesktopAccounting(); + diddeskaccount = 1; + EDBUG_RETURN_; + data = NULL; + val = 0; + + EDBUG_RETURN_; +} + +char * +NukeBoringevents(XEvent * ev, int num) +{ + char *ok; + int i, j; + int first, last; + + if (!num) + return NULL; + + ok = Emalloc(num * sizeof(char)); + + for (i = 0; i < num; i++) + { +/* DebugEvent(&(ev[i])); */ + ok[i] = 1; + } + /* get rid of all but the last motion event */ + last = -1; + for (i = 0; i < num; i++) + { + if (ev[i].type == MotionNotify) + { + ok[i] = 0; + last = i; + } + } + if (last >= 0) + ok[last] = 1; + /* look for paired enter / leave events for windows that contain no click */ + /* events for those windows whilst mouse is in them */ + for (i = 0; i < num; i++) + { + if (ev[i].type == EnterNotify) + { + Window win; + char is_ok; + + first = -1; + last = -1; + win = ev[i].xany.window; + /* if its a normal window we created - not an event window */ + if (FindXID(win)) + { + first = i; + for (j = i + 1; j < num; j++) + { + if ((ev[j].xany.window == win) && + ((ev[j].type == LeaveNotify) || + (ev[j].type == UnmapNotify) || + (ev[j].type == DestroyNotify))) + { + last = j; + break; + } + } + if ((first >= 0) && (last > first)) + { + is_ok = 0; + for (j = first + 1; j <= last; j++) + { + if (ev[j].xany.window == win) + { + if ((ev[j].type == ButtonPress) || + (ev[j].type == ButtonRelease)) + { + is_ok = 1; + break; + } + } + } + if (!is_ok) + { + for (j = first; j <= last; j++) + { + if (ev[j].xany.window == win) + { + if ((ev[j].type == EnterNotify) || + (ev[j].type == LeaveNotify) || + (ev[j].type == MotionNotify)) + ok[j] = 0; + } + } + } + } + } + } + } + /* compress all shapenotify events for a window and onyl take the last one */ + /* as beign valid */ + for (i = 0; i < num; i++) + { + if (ev[i].type == event_base_shape + ShapeNotify) + { + Window win; + + last = i; + win = ev[i].xany.window; + for (j = i; j < num; j++) + { + if ((ev[j].type == event_base_shape + ShapeNotify) && + (ev[j].xany.window == win)) + { + ok[j] = 0; + last = j; + } + } + ok[last] = 1; + } + } + /* FIXME: add maprequest compression */ + /* FIXME: add configurerequest compression */ + /* FIXME: add resizerequest compression */ + return ok; +} + +void +DebugEvent(XEvent * ev) +{ + EDBUG(8, "DebugEvent"); + if (ev->type == event_base_shape + ShapeNotify) + fprintf(stderr, "EV: ShapeNotify:\n"); + else + { + switch (ev->type) + { + case KeyPress: + fprintf(stderr, "EV: KeyPress:\n"); + break; + case KeyRelease: + fprintf(stderr, "EV: KeyRelease:\n"); + break; + case ButtonPress: + fprintf(stderr, "EV: ButtonPress:\n"); + break; + case ButtonRelease: + fprintf(stderr, "EV: ButtonRelease:\n"); + break; + case MotionNotify: + fprintf(stderr, "EV: MotionNotify:\n"); + break; + case EnterNotify: + fprintf(stderr, "EV: EnterNotify:\n"); + break; + case LeaveNotify: + fprintf(stderr, "EV: LeaveNotify:\n"); + break; + case FocusIn: + fprintf(stderr, "EV: FocusIn:\n"); + break; + case FocusOut: + fprintf(stderr, "EV: FocusOut:\n"); + break; + case KeymapNotify: + fprintf(stderr, "EV: KeymapNotify:\n"); + break; + case Expose: + fprintf(stderr, "EV: Expose:\n"); + break; + case GraphicsExpose: + fprintf(stderr, "EV: GraphicsExpose:\n"); + break; + case NoExpose: + fprintf(stderr, "EV: NoExpose:\n"); + break; + case VisibilityNotify: + fprintf(stderr, "EV: VisibilityNotify:\n"); + break; + case CreateNotify: + fprintf(stderr, "EV: CreateNotify:\n"); + break; + case DestroyNotify: + fprintf(stderr, "EV: DestroyNotify:\n"); + break; + case UnmapNotify: + fprintf(stderr, "EV: UnmapNotify:\n"); + break; + case MapNotify: + fprintf(stderr, "EV: MapNotify:\n"); + break; + case MapRequest: + fprintf(stderr, "EV: MapRequest:\n"); + break; + case ReparentNotify: + fprintf(stderr, "EV: ReparentNotify:\n"); + break; + case ConfigureNotify: + fprintf(stderr, "EV: ConfigureNotify:\n"); + break; + case ConfigureRequest: + fprintf(stderr, "EV: ConfigureRequest:\n"); + break; + case GravityNotify: + fprintf(stderr, "EV: GravityNotify:\n"); + break; + case ResizeRequest: + fprintf(stderr, "EV: ResizeRequest:\n"); + break; + case CirculateNotify: + fprintf(stderr, "EV: CirculateNotify:\n"); + break; + case CirculateRequest: + fprintf(stderr, "EV: CirculateRequest:\n"); + break; + case PropertyNotify: + fprintf(stderr, "EV: PropertyNotify:\n"); + break; + case SelectionClear: + fprintf(stderr, "EV: SelectionClear:\n"); + break; + case SelectionRequest: + fprintf(stderr, "EV: SelectionRequest:\n"); + break; + case SelectionNotify: + fprintf(stderr, "EV: SelectionNotify:\n"); + break; + case ColormapNotify: + fprintf(stderr, "EV: ColormapNotify:\n"); + break; + case ClientMessage: + fprintf(stderr, "EV: ClientMessage:\n"); + break; + case MappingNotify: + fprintf(stderr, "EV: MappingNotify:\n"); + break; + default: + fprintf(stderr, "EV: ???\n"); + break; + } + } + EDBUG_RETURN_; +} + +void +HandleEvent(XEvent * ev) +{ + void **lst; + int i, num; + + EDBUG(7, "HandleEvent"); + WarpFocusHandleEvent(ev); + if (ev->type == event_base_shape + ShapeNotify) + HandleChildShapeChange(ev); + if ((ev->type == KeyPress) || (ev->type == KeyRelease) || + (ev->type == ButtonPress) || (ev->type == ButtonRelease) || + (ev->type == EnterNotify) || (ev->type == LeaveNotify)) + { + lst = ListItemType(&num, LIST_TYPE_ACLASS_GLOBAL); + if (lst) + { + for (i = 0; i < num; i++) + EventAclass(ev, (ActionClass *) lst[i]); + Efree(lst); + } + } + if (ev->type <= 35) + HArray[ev->type].func(ev); + IconboxHandleEvent(ev); + + if (diddeskaccount) + { + DoIn("DESKTOP_ACCOUNTING_TIMEOUT", 30.0, DeskAccountTimeout, 0, NULL); + diddeskaccount = 0; + } + EDBUG_RETURN_; +} + +void +CheckEvent() +{ + XEvent ev; + + EDBUG(7, "CheckEvent"); + while (XPending(disp)) + { + XNextEvent(disp, &ev); + HandleEvent(&ev); + } + EDBUG_RETURN_; +} + +#ifdef DEBUG +#define DBUG_STACKSTART \ + int save = call_level + 1; +#define DBUG_STACKCHECK \ + if (save != call_level) { \ + fprintf (stderr, "Unstack error: ["); \ + for (save = 0; save < 4; ++ save) \ + fprintf (stderr, "%s%s", save ? ", " : "", call_stack[save]); \ + fprintf (stderr, "]\n"); \ + save = call_level; \ + } +#else +#define DBUG_STACKSTART +#define DBUG_STACKCHECK +#endif + + /* This is the primary event loop. Everything that is going to happen in the + * window manager has to start here at some point. This is where all the + * events from the X server are interpreted, timer events are inserted, etc + */ + +void +WaitEvent() +{ +/* XEvent ev; */ + fd_set fdset; + struct timeval tval; + static struct timeval tval_last = + {0, 0}; + double time1, time2; + Qentry *qe; + int count, pcount; + int fdsize; + int xfd, smfd; + int i; + static int evq_num = 0; + static XEvent *evq = NULL; + char *ok; + + DBUG_STACKSTART; + + EDBUG(7, "WaitEvent"); + smfd = GetSMfd(); + xfd = ConnectionNumber(disp); + fdsize = MAX(xfd, smfd) + 1; + + /* if we've never set the time we were last here before */ + if ((tval_last.tv_sec == 0) && (tval_last.tv_usec == 0)) + gettimeofday(&tval_last, NULL); + /* time1 = time we last entered this routine */ + time1 = ((double)tval_last.tv_sec) + (((double)tval_last.tv_usec) / 1000000); + gettimeofday(&tval, NULL); + tval_last.tv_sec = tval.tv_sec; + tval_last.tv_usec = tval.tv_usec; + /* time2 = current time */ + time2 = ((double)tval.tv_sec) + (((double)tval.tv_usec) / 1000000); + time2 -= time1; + if (time2 < 0.0) + time2 = 0.0; + /* time2 = time spent since we last were here */ + + count = 0; + while (XPending(disp)) + { + count++; + if (count > evq_num) + { + evq_num += 16; + if (!evq) + evq = Emalloc(sizeof(XEvent) * evq_num); + else + evq = Erealloc(evq, sizeof(XEvent) * evq_num); + } + XNextEvent(disp, &(evq[count - 1])); + } + /* remove multiple extraneous events here */ + ok = NukeBoringevents(evq, count); + if (ok) + { + for (i = 0; i < count; i++) + { + if (ok[i]) + HandleEvent(&(evq[i])); + } + Efree(ok); + } + + DBUG_STACKCHECK; + + HandleDrawQueue(); + XFlush(disp); + pcount = count; + + DBUG_STACKCHECK; + + count = 0; + while (XPending(disp)) + { + count++; + if (count > evq_num) + { + evq_num += 16; + if (!evq) + evq = Emalloc(sizeof(XEvent) * evq_num); + else + evq = Erealloc(evq, sizeof(XEvent) * evq_num); + } + XNextEvent(disp, &(evq[count - 1])); + } + /* remove multiple extraneous events here */ + ok = NukeBoringevents(evq, count); + if (ok) + { + for (i = 0; i < count; i++) + { + if (ok[i]) + HandleEvent(&(evq[i])); + } + Efree(ok); + } + if (count > 0) + XFlush(disp); + + if (pcount > count) + count = pcount; + if ((evq) && ((evq_num - count) > 64)) + { + evq_num = 0; + Efree(evq); + evq = NULL; + } + + DBUG_STACKCHECK; + + FD_ZERO(&fdset); + FD_SET(xfd, &fdset); + if (smfd >= 0) + FD_SET(smfd, &fdset); + + qe = GetHeadTimerQueue(); + if (qe) + { + if (qe->just_added) + { + qe->just_added = 0; + time1 = qe->in_time; + } + else + { + time1 = qe->in_time - time2; + if (time1 < 0.0) + time1 = 0.0; + qe->in_time = time1; + } + tval.tv_sec = (long)time1; + tval.tv_usec = (long)((time1 - ((double)tval.tv_sec)) * 1000000); + count = select(fdsize, &fdset, NULL, NULL, &tval); + } + else + count = select(fdsize, &fdset, NULL, NULL, NULL); + if (count < 0) + { + EDBUG_RETURN_; + } + if ((smfd >= 0) && (count > 0) && (FD_ISSET(smfd, &fdset))) + ProcessICEMSGS(); + + DBUG_STACKCHECK; + + if ((!(FD_ISSET(xfd, &fdset))) && (qe) && (count == 0) && + (((smfd >= 0) && (!(FD_ISSET(smfd, &fdset)))) || (smfd < 0))) + HandleTimerEvent(); + + DBUG_STACKCHECK; + + EDBUG_RETURN_; +} + +void +HKeyPress(XEvent * ev) +{ + Dialog *d; + + EDBUG(7, "HKeyPress"); + d = FindDialog(ev->xkey.window); + if (d) + { + int i; + + for (i = 0; i < d->num_bindings; i++) + { + if (ev->xkey.keycode == d->keybindings[i].key) + (d->keybindings[i].func) (d->keybindings[i].val, + d->keybindings[i].data); + } + } + EDBUG_RETURN_; +} + +void +HKeyRelease(XEvent * ev) +{ + EDBUG(7, "HKeyRelease"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HButtonPress(XEvent * ev) +{ + EDBUG(7, "HButtonPress"); + ApplySclass(FindItem("SOUND_BUTTON_CLICK", 0, + LIST_FINDBY_NAME, LIST_TYPE_SCLASS)); + HandleMouseDown(ev); + EDisplayMemUse(); + EDBUG_RETURN_; +} + +void +HButtonRelease(XEvent * ev) +{ + EDBUG(7, "HButtonRelease"); + ApplySclass(FindItem("SOUND_BUTTON_RAISE", 0, + LIST_FINDBY_NAME, LIST_TYPE_SCLASS)); + HandleMouseUp(ev); + EDBUG_RETURN_; +} + +void +HMotionNotify(XEvent * ev) +{ + EDBUG(7, "HMotionNotify"); + HandleMotion(ev); + EDBUG_RETURN_; +} + +void +HEnterNotify(XEvent * ev) +{ + EDBUG(7, "HEnterNotify"); + if (mode.mode == MODE_NONE) + { + /* + * multi screen handling -- root windows receive + * enter / leave notify + */ + if (ev->xany.window == root.win) + { + PagerHideAllHi(); + if (!mode.focuswin || FOCUS_POINTER == mode.focusmode) + HandleFocusWindow(root.focuswin); + } + else + { + HandleMouseIn(ev); + HandleFocusWindow(ev->xcrossing.window); + } + } + EDBUG_RETURN_; +} + +void +HLeaveNotify(XEvent * ev) +{ + EDBUG(7, "HLeaveNotify"); + if (mode.mode == MODE_NONE) + { + HandleMouseOut(ev); + + /* + * If we are leaving the root window, we are switching + * screens on a multi screen system - need to unfocus + * to allow other desk to grab focus... + */ + if (ev->xcrossing.window == root.win) + { + if (ev->xcrossing.mode == NotifyNormal && + ev->xcrossing.detail != NotifyInferior && + mode.focuswin) + HandleFocusWindow(root.focuswin); + else + HandleFocusWindow(ev->xcrossing.window); + } +/* THIS caused the "emacs focus bug" ? */ +/* else */ +/* HandleFocusWindow(ev->xcrossing.window); */ + } + EDBUG_RETURN_; +} + +void +HFocusIn(XEvent * ev) +{ + EDBUG(7, "HFocusIn"); + if (ev->xfocus.detail != NotifyPointer) + HandleFocusWindowIn(ev->xfocus.window); + EDBUG_RETURN_; +} + +void +HFocusOut(XEvent * ev) +{ + EDBUG(7, "HFocusOut"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HKeymapNotify(XEvent * ev) +{ + EDBUG(7, "HKeymapNotify"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HExpose(XEvent * ev) +{ + EDBUG(7, "HExpose"); + HandleExpose(ev); + EDBUG_RETURN_; +} + +void +HGraphicsExpose(XEvent * ev) +{ + EDBUG(7, "HGraphicsExpose"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HNoExpose(XEvent * ev) +{ + EDBUG(7, "HNoExpose"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HVisibilityNotify(XEvent * ev) +{ + EDBUG(7, "HVisibilityNotify"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HCreateNotify(XEvent * ev) +{ + EDBUG(7, "HCreateNotify"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HDestroyNotify(XEvent * ev) +{ + EDBUG(7, "HDestroyNotify"); + HandleDestroy(ev); + EDBUG_RETURN_; +} + +void +HUnmapNotify(XEvent * ev) +{ + EDBUG(7, "HUnmapNotify"); + HandleUnmap(ev); + EDBUG_RETURN_; +} + +void +HMapNotify(XEvent * ev) +{ + EDBUG(7, "HMapNotify"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HMapRequest(XEvent * ev) +{ + EDBUG(7, "HMapRequest"); + HandleMapRequest(ev); + EDBUG_RETURN_; +} + +void +HReparentNotify(XEvent * ev) +{ + EDBUG(7, "HReparentNotify"); + HandleReparent(ev); + EDBUG_RETURN_; +} + +void +HConfigureNotify(XEvent * ev) +{ + EDBUG(7, "HConfigureNotify"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HConfigureRequest(XEvent * ev) +{ + EDBUG(7, "HConfigureRequest"); + HandleConfigureRequest(ev); + EDBUG_RETURN_; +} + +void +HGravityNotify(XEvent * ev) +{ + EDBUG(7, "HGravityNotify"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HResizeRequest(XEvent * ev) +{ + EDBUG(7, "HResizeRequest"); + HandleResizeRequest(ev); + EDBUG_RETURN_; +} + +void +HCirculateNotify(XEvent * ev) +{ + EDBUG(7, "HCirculateNotify"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HCirculateRequest(XEvent * ev) +{ + EDBUG(7, "HCirculateRequest"); + HandleCirculate(ev); + EDBUG_RETURN_; +} + +void +HPropertyNotify(XEvent * ev) +{ + EDBUG(7, "HPropertyNotify"); + HandleProperty(ev); + EDBUG_RETURN_; +} + +void +HSelectionClear(XEvent * ev) +{ + EDBUG(7, "HSelectionClear"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HSelectionRequest(XEvent * ev) +{ + EDBUG(7, "HSelectionRequest"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HSelectionNotify(XEvent * ev) +{ + EDBUG(7, "HSelectionNotify"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HColormapNotify(XEvent * ev) +{ + EDBUG(7, "HColormapNotify"); + ev = NULL; + EDBUG_RETURN_; +} + +void +HClientMessage(XEvent * ev) +{ + EDBUG(7, "HClientMessage"); + HandleClientMessage(ev); + EDBUG_RETURN_; +} + +void +HMappingNotify(XEvent * ev) +{ + EDBUG(7, "HMappingNotify"); + ev = NULL; + EDBUG_RETURN_; +} + +void +DefaultFunc(XEvent * ev) +{ + EDBUG(7, "DefaultFunc"); + ev = NULL; + EDBUG_RETURN_; +} diff --git a/src/evhandlers.c b/src/evhandlers.c new file mode 100644 index 00000000..a572b56e --- /dev/null +++ b/src/evhandlers.c @@ -0,0 +1,2572 @@ +#include "E.h" + +#define WIN_LAYER_DESKTOP 0 +#define WIN_LAYER_BELOW 2 +#define WIN_LAYER_NORMAL 4 +#define WIN_LAYER_ONTOP 6 +#define WIN_LAYER_DOCK 8 +#define WIN_LAYER_ABOVE_DOCK 10 +#define WIN_LAYER_MENU 12 + +#define WIN_STATE_STICKY (1<<0) /* everyone knows sticky */ +#define WIN_STATE_RESERVED_BIT1 (1<<1) /* removed minimize here */ +#define WIN_STATE_MAXIMIZED_VERT (1<<2) /* window in maximized V state */ +#define WIN_STATE_MAXIMIZED_HORIZ (1<<3) /* window in maximized H state */ +#define WIN_STATE_HIDDEN (1<<4) /* not on taskbar but window visible */ +#define WIN_STATE_SHADED (1<<5) /* shaded (NeXT style) */ +#define WIN_STATE_HID_WORKSPACE (1<<6) /* not on current desktop */ +#define WIN_STATE_HID_TRANSIENT (1<<7) /* owner of transient is hidden */ +#define WIN_STATE_FIXED_POSITION (1<<8) /* window is fixed in position even */ +#define WIN_STATE_ARRANGE_IGNORE (1<<9) /* ignore for auto arranging */ + +/* this is temporary */ +static ToolTip *ttip = NULL; +struct _mdata + { + Menu *m; + MenuItem *mi; + EWin *ewin; + }; + +void ToolTipTimeout(int val, void *data); +void SubmenuShowTimeout(int val, void *dat); + +static char sentpress = 0; +static Window click_was_in = 0; +static Time last_time = 0; +static int last_button = 0; +static int pgd_x = 0, pgd_y = 0; + +void +ToolTipTimeout(int val, void *data) +{ + int x, y, dum; + unsigned int mask; + Window win, rt, ch; + ActionClass *ac; + + EDBUG(5, "ToolTipTimeout"); + + /* In the case of multiple screens, check to make sure + * the root window is still where the mouse is... */ + if (False == XQueryPointer(disp, root.win, &rt, &ch, &x, &y, &dum, + &dum, &mask)) + EDBUG_RETURN_; + /* dont pop up tooltip is mouse button down */ + if (mask & (Button1Mask | Button2Mask | Button3Mask | + Button4Mask | Button5Mask)) + EDBUG_RETURN_; + win = WindowAtXY(x, y); + ac = FindActionClass(win); + if (!ac) + EDBUG_RETURN_; + + if (!ttip) + ttip = FindItem("DEFAULT", 0, LIST_FINDBY_NAME, + LIST_TYPE_TOOLTIP); + + if (ac->tooltipstring) + ShowToolTip(ttip, ac->tooltipstring, ac, x, y); + + data = NULL; + val = 0; + + EDBUG_RETURN_; +} + +/* end temporary stuff */ + +void +HandleClientMessage(XEvent * ev) +{ + EWin *ewin; + +/* ** int d, xo, yo; */ + static Atom a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0, a6 = 0; + + EDBUG(5, "HandleClientMessage"); + if (!a1) + a1 = XInternAtom(disp, "ENL_MSG", False); + if (!a2) + a2 = XInternAtom(disp, "_WIN_AREA", False); + if (!a3) + a3 = XInternAtom(disp, "_WIN_WORKSPACE", False); + if (!a4) + a4 = XInternAtom(disp, "_WIN_LAYER", False); + if (!a5) + a5 = XInternAtom(disp, "_WIN_STATE", False); + if (!a6) + a6 = XInternAtom(disp, "WM_CHANGE_STATE", False); + if (ev->xclient.message_type == a1) + { + HandleComms(ev); + EDBUG_RETURN_; + } + if (ev->xclient.message_type == a2) + { + SetCurrentArea(ev->xclient.data.l[0], ev->xclient.data.l[1]); + EDBUG_RETURN_; + } + if (ev->xclient.message_type == a3) + { + GotoDesktop(ev->xclient.data.l[0]); + EDBUG_RETURN_; + } + if (ev->xclient.message_type == a4) + { + ewin = FindItem(NULL, ev->xclient.window, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + { + ewin->layer = ev->xclient.data.l[0]; + XChangeProperty(disp, ewin->win, a4, XA_CARDINAL, 32, + PropModeReplace, + (unsigned char *)(&(ev->xclient.data.l[0])), 1); + RaiseEwin(ewin); + } + EDBUG_RETURN_; + } + if (ev->xclient.message_type == a5) + { + ewin = FindItem(NULL, ev->xclient.window, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (!ewin) + EDBUG_RETURN_; + if (ev->xclient.data.l[0] & WIN_STATE_FIXED_POSITION) + { + if (ev->xclient.data.l[1] & WIN_STATE_FIXED_POSITION) + ewin->fixedpos = 1; + else + ewin->fixedpos = 0; + } + if (ev->xclient.data.l[0] & WIN_STATE_ARRANGE_IGNORE) + { + if (ev->xclient.data.l[1] & WIN_STATE_ARRANGE_IGNORE) + ewin->ignorearrange = 1; + else + ewin->ignorearrange = 0; + } + if ((ev->xclient.data.l[0] & WIN_STATE_STICKY) && (!ewin->ignorearrange)) + { + if (ev->xclient.data.l[1] & WIN_STATE_STICKY) + { + if (!(ewin->sticky)) + { + ewin->sticky = 1; + RaiseEwin(ewin); + DrawEwin(ewin); + ApplySclass(FindItem("SOUND_WINDOW_STICK", 0, + LIST_FINDBY_NAME, LIST_TYPE_SCLASS)); + } + } + else + { + if (ewin->sticky) + { + ewin->sticky = 0; + RaiseEwin(ewin); + DrawEwin(ewin); + ApplySclass(FindItem("SOUND_WINDOW_UNSTICK", 0, + LIST_FINDBY_NAME, LIST_TYPE_SCLASS)); + } + } + } + if (ev->xclient.data.l[0] & WIN_STATE_SHADED) + { + if (ev->xclient.data.l[1] & WIN_STATE_SHADED) + ShadeEwin(ewin); + else + UnShadeEwin(ewin); + } + GNOME_SetHint(ewin); + EDBUG_RETURN_; + } + if (ev->xclient.message_type == a6) + { + ewin = FindItem(NULL, ev->xclient.window, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if ((ewin) && (ev->xclient.data.l[0] == IconicState) && + (!(ewin->iconified))) + { + IconifyEwin(ewin); + } + } + EDBUG_RETURN_; +} + +void +HandleFocusWindowIn(Window win) +{ + EWin *ewin; + + EDBUG(5, "HandleFocusWindowIn"); + ewin = FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin != mode.focuswin) + { + if (mode.focuswin) + { + mode.focuswin->active = 0; + DrawEwin(mode.focuswin); + if (mode.focusmode == FOCUS_CLICK) + XGrabButton(disp, AnyButton, AnyModifier, + mode.focuswin->win_container, False, + ButtonPressMask, + GrabModeSync, GrabModeAsync, None, None); + } + mode.focuswin = ewin; + if ((ewin) && (!ewin->menu)) + { + mode.realfocuswin = ewin; + if (!mode.cur_menu_mode) + mode.context_ewin = ewin; + } + if (mode.focuswin) + { + mode.focuswin->active = 1; + DrawEwin(mode.focuswin); + if (mode.focusmode == FOCUS_CLICK) + { + XUngrabButton(disp, AnyButton, AnyModifier, mode.focuswin->win_container); + GrabButtonGrabs(mode.focuswin); + } + } + } + EDBUG_RETURN_; +} + +void +HandleFocusWindow(Window win) +{ + EWin *found_ewin; + + EDBUG(5, "HandleFocusWindow"); + if (root.focuswin == win) + FocusToEWin(NULL); + else + { + found_ewin = FindEwinByChildren(win); + if (!found_ewin) + found_ewin = FindEwinByBase(win); + if (mode.focusmode == FOCUS_CLICK) + mode.mouse_over_win = found_ewin; + else if (mode.focusmode == FOCUS_SLOPPY) + { + if (!found_ewin) + ICCCM_Cmap(NULL); + if (found_ewin) + FocusToEWin(found_ewin); + mode.mouse_over_win = found_ewin; + } + else if (mode.focusmode == FOCUS_POINTER) + { + if (!found_ewin) + found_ewin = GetEwinPointerInClient(); + FocusToEWin(found_ewin); + mode.mouse_over_win = found_ewin; + } + } + EDBUG_RETURN_; +} + +void +HandleChildShapeChange(XEvent * ev) +{ + Window win; + EWin *ewin; + Border *b; + + EDBUG(5, "HandleChildShapeChange"); + win = ((XShapeEvent *) ev)->window; + ewin = FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + { + b = ewin->border; + SyncBorderToEwin(ewin); + if (ewin->border == b) + PropagateShapes(ewin->win); + } + EDBUG_RETURN_; +} + +void +HandleMotion(XEvent * ev) +{ + int dx, dy; + int pw, ph; + int x, y, w, h; + EWin *ewin; + + EDBUG(5, "HandleMotion"); + + if (ttip) + HideToolTip(ttip); + RemoveTimerEvent("TOOLTIP_TIMEOUT"); + if (mode.tooltips) + DoIn("TOOLTIP_TIMEOUT", mode.tiptime, ToolTipTimeout, 0, NULL); + + EdgeHandleMotion(ev); + mode.px = mode.x; + mode.py = mode.y; + mode.x = ev->xmotion.x_root; + mode.y = ev->xmotion.y_root; + ewin = NULL; + desks.current = DesktopAt(mode.x, mode.y); + + if ((!(ev->xmotion.state & (Button1Mask | Button2Mask | + Button3Mask | Button4Mask | + Button5Mask)) && + (!mode.place))) + { + switch (mode.mode) + { + case MODE_RESIZE: + case MODE_RESIZE_H: + case MODE_RESIZE_V: + doResizeEnd(NULL); + EDBUG_RETURN_; + break; + case MODE_MOVE: + doMoveEnd(NULL); + EDBUG_RETURN_; + break; + case MODE_BUTTONDRAG: + doDragButtonEnd(NULL); + EDBUG_RETURN_; + break; + default: + break; + } + } + switch (mode.mode) + { + case MODE_MOVE: + if (mode.ewin) + { + EWin **gwins; + int i, num; + int ndx, ndy; + int prx, pry; + int screen_snap_dist; + + ewin = mode.ewin; + gwins = ListWinGroupMembersForEwin(ewin, ACTION_MOVE, &num); + + if ((mode.moveresize_pending_ewin) && + (mode.ewin == mode.moveresize_pending_ewin)) + { + for (i = 0; i < num; i++) + DrawEwinShape(gwins[i], mode.movemode, gwins[i]->x, gwins[i]->y, + gwins[i]->client.w, gwins[i]->client.h, 0); + mode.moveresize_pending_ewin = NULL; + } + dx = mode.x - mode.px; + dy = mode.y - mode.py; + if (mode.next_move_x_plus != 0) + { + dx += mode.next_move_x_plus; + mode.next_move_x_plus = 0; + } + if (mode.next_move_y_plus != 0) + { + dy += mode.next_move_y_plus; + mode.next_move_y_plus = 0; + } + { + char jumpx, jumpy; + int min_dx, max_dx, min_dy, max_dy; + + jumpx = 0; + jumpy = 0; + min_dx = dx; + min_dy = dy; + max_dx = dx; + max_dy = dy; + for (i = 0; i < num; i++) + { + ndx = dx; + ndy = dy; + /* make our ewin resist other ewins around the place */ + SnapEwin(gwins[i], dx, dy, &ndx, &ndy); + if ((dx < 0) && (ndx <= 0)) + { + if (ndx > min_dx) + min_dx = ndx; + if (ndx < max_dx) + max_dx = ndx; + } + else if (ndx >= 0) + { + if (ndx < min_dx) + min_dx = ndx; + if (ndx > max_dx) + max_dx = ndx; + } + if ((dy < 0) && (ndy <= 0)) + { + if (ndy > min_dy) + min_dy = ndy; + if (ndy < max_dy) + max_dy = ndy; + } + else if (ndy >= 0) + { + if (ndy < min_dy) + min_dy = ndy; + if (ndy > max_dy) + max_dy = ndy; + } + } + if (min_dx == dx) + ndx = max_dx; + else + ndx = min_dx; + if (min_dy == dy) + ndy = max_dy; + else + ndy = min_dy; + screen_snap_dist = mode.constrained ? (root.w + root.h) + : mode.screen_snap_dist; + for (i = 0; i < num; i++) + { + /* jump out of snap horizontally */ + if ((ndx != dx) && + (((gwins[i]->x == 0) && + (!(IN_RANGE(gwins[i]->reqx, gwins[i]->x, screen_snap_dist)))) || + ((gwins[i]->x == (root.w - gwins[i]->w)) && + (!(IN_RANGE(gwins[i]->reqx, gwins[i]->x, screen_snap_dist)))) || + ((gwins[i]->x != 0) && + (gwins[i]->x != (root.w - gwins[i]->w) && + (!(IN_RANGE(gwins[i]->reqx, gwins[i]->x, mode.edge_snap_dist))))))) + { + jumpx = 1; + ndx = gwins[i]->reqx - gwins[i]->x + dx; + } + /* jump out of snap vertically */ + if ((ndy != dy) && + (((gwins[i]->y == 0) && + (!(IN_RANGE(gwins[i]->reqy, gwins[i]->y, screen_snap_dist)))) || + ((gwins[i]->y == (root.h - gwins[i]->h)) && + (!(IN_RANGE(gwins[i]->reqy, gwins[i]->y, screen_snap_dist)))) || + ((gwins[i]->y != 0) && + (gwins[i]->y != (root.h - gwins[i]->h) && + (!(IN_RANGE(gwins[i]->reqy, gwins[i]->y, mode.edge_snap_dist))))))) + { + jumpy = 1; + ndy = gwins[i]->reqy - gwins[i]->y + dy; + } + } + for (i = 0; i < num; i++) + { + /* if its opaque move mode check to see if we have to float */ + /* the window aboe all desktops (reparent to root) */ + if (mode.movemode == 0) + DetermineEwinFloat(gwins[i], ndx, ndy); + /* draw the new position of the window */ + prx = gwins[i]->reqx; + pry = gwins[i]->reqy; + DrawEwinShape(gwins[i], mode.movemode, + gwins[i]->x + ndx, gwins[i]->y + ndy, + gwins[i]->client.w, gwins[i]->client.h, + mode.firstlast); + /* if we didnt jump the winow after a reist at the edge */ + /* reset the requested x to be the prev requested + delta */ + if (!(jumpx)) + gwins[i]->reqx = prx + dx; + if (!(jumpy)) + gwins[i]->reqy = pry + dy; + } + } +#if 0 + for (i = 0; i < num; i++) + { + /* make our ewin resist other ewins around the place */ + SnapEwin(gwins[i], dx, dy, &ndx, &ndy); + /* if in constrained mode set the screen edge resist */ + /* to something huge so it doesnt have any effect */ + screen_snap_dist = mode.constrained ? (root.w + root.h) + : mode.screen_snap_dist; + prx = gwins[i]->reqx; + pry = gwins[i]->reqy; + /* snap the window to the screen edges horizontally */ + if ((ndx != dx) && + (((gwins[i]->x == 0) && + (!(IN_RANGE(gwins[i]->reqx, gwins[i]->x, screen_snap_dist)))) || + ((gwins[i]->x == (root.w - gwins[i]->w)) && + (!(IN_RANGE(gwins[i]->reqx, gwins[i]->x, screen_snap_dist)))) || + ((gwins[i]->x != 0) && (gwins[i]->x != (root.w - gwins[i]->w) && + (!(IN_RANGE(gwins[i]->reqx, gwins[i]->x, mode.edge_snap_dist))))))) + { + ndx = gwins[i]->reqx - gwins[i]->x + dx; + prx = gwins[i]->x; + dx = 0; + dox = 1; + } + /* snap the window to the screen edges vertically */ + if ((ndy != dy) && + (((gwins[i]->y == 0) && + (!(IN_RANGE(gwins[i]->reqy, gwins[i]->y, screen_snap_dist)))) || + ((gwins[i]->y == (root.h - gwins[i]->h)) && + (!(IN_RANGE(gwins[i]->reqy, gwins[i]->y, screen_snap_dist)))) || + ((gwins[i]->y != 0) && (gwins[i]->y != (root.h - gwins[i]->h) && + (!(IN_RANGE(gwins[i]->reqy, gwins[i]->y, mode.edge_snap_dist))))))) + { + ndy = gwins[i]->reqy - gwins[i]->y + dy; + pry = gwins[i]->y; + dy = 0; + doy = 1; + } + /* if its opaque move mode check to see if we have to float */ + /* the window aboe all desktops (reparent to root) */ + if (mode.movemode == 0) + DetermineEwinFloat(gwins[i], ndx, ndy); + /* draw the new position of the window */ + DrawEwinShape(gwins[i], mode.movemode, gwins[i]->x + ndx, gwins[i]->y + ndy, + gwins[i]->client.w, gwins[i]->client.h, mode.firstlast); + /* if we didnt jump the winow after a reist at the edge */ + /* reset the requested x to be the prev requested + delta */ + if (!(dox)) + gwins[i]->reqx = prx + dx; + if (!(doy)) + gwins[i]->reqy = pry + dy; + } +#endif + Efree(gwins); + } + break; + case MODE_RESIZE: + if (mode.ewin) + { + ewin = mode.ewin; + switch (mode.resize_detail) + { + case 0: + pw = ewin->client.w; + ph = ewin->client.h; + w = mode.win_w - (mode.x - mode.start_x); + h = mode.win_h - (mode.y - mode.start_y); + x = mode.win_x + (mode.x - mode.start_x); + y = mode.win_y + (mode.y - mode.start_y); + ewin->client.w = w; + ewin->client.h = h; + ICCCM_MatchSize(ewin); + w = ewin->client.w; + h = ewin->client.h; + if (pw == ewin->client.w) + x = ewin->x; + else + x = mode.win_x + mode.win_w - w; + if (ph == ewin->client.h) + y = ewin->y; + else + y = mode.win_y + mode.win_h - h; + ewin->client.w = pw; + ewin->client.h = ph; + DrawEwinShape(ewin, mode.resizemode, x, y, w, h, mode.firstlast); + break; + case 1: + ph = ewin->client.h; + w = mode.win_w + (mode.x - mode.start_x); + h = mode.win_h - (mode.y - mode.start_y); + x = ewin->x; + y = mode.win_y + (mode.y - mode.start_y); + ewin->client.h = h; + ICCCM_MatchSize(ewin); + h = ewin->client.h; + if (ph == ewin->client.h) + y = ewin->y; + else + y = mode.win_y + mode.win_h - h; + ewin->client.h = ph; + DrawEwinShape(ewin, mode.resizemode, x, y, w, h, mode.firstlast); + break; + case 2: + pw = ewin->client.w; + w = mode.win_w - (mode.x - mode.start_x); + h = mode.win_h + (mode.y - mode.start_y); + x = mode.win_x + (mode.x - mode.start_x); + y = ewin->y; + ewin->client.w = w; + ICCCM_MatchSize(ewin); + w = ewin->client.w; + if (pw == ewin->client.w) + x = ewin->x; + else + x = mode.win_x + mode.win_w - w; + ewin->client.w = pw; + DrawEwinShape(ewin, mode.resizemode, x, y, w, h, mode.firstlast); + break; + case 3: + w = mode.win_w + (mode.x - mode.start_x); + h = mode.win_h + (mode.y - mode.start_y); + x = ewin->x; + y = ewin->y; + DrawEwinShape(ewin, mode.resizemode, x, y, w, h, mode.firstlast); + break; + default: + break; + } + } + break; + case MODE_RESIZE_H: + if (mode.ewin) + { + ewin = mode.ewin; + switch (mode.resize_detail) + { + case 0: + pw = ewin->client.w; + w = mode.win_w - (mode.x - mode.start_x); + h = ewin->client.h; + x = mode.win_x + (mode.x - mode.start_x); + y = ewin->y; + ewin->client.w = w; + ICCCM_MatchSize(ewin); + w = ewin->client.w; + if (pw == ewin->client.w) + x = ewin->x; + else + x = mode.win_x + mode.win_w - w; + ewin->client.w = pw; + DrawEwinShape(ewin, mode.resizemode, x, y, w, h, mode.firstlast); + break; + case 1: + w = mode.win_w + (mode.x - mode.start_x); + h = ewin->client.h; + x = ewin->x; + y = ewin->y; + DrawEwinShape(ewin, mode.resizemode, x, y, w, h, mode.firstlast); + break; + default: + break; + } + } + break; + case MODE_RESIZE_V: + if (mode.ewin) + { + ewin = mode.ewin; + switch (mode.resize_detail) + { + case 0: + ph = ewin->client.h; + w = ewin->client.w; + h = mode.win_h - (mode.y - mode.start_y); + x = ewin->x; + y = mode.win_y + (mode.y - mode.start_y); + ewin->client.h = h; + ICCCM_MatchSize(ewin); + h = ewin->client.h; + if (ph == ewin->client.h) + y = ewin->y; + else + y = mode.win_y + mode.win_h - h; + ewin->client.h = ph; + DrawEwinShape(ewin, mode.resizemode, x, y, w, h, mode.firstlast); + break; + case 1: + w = ewin->client.w; + h = mode.win_h + (mode.y - mode.start_y); + x = ewin->x; + y = ewin->y; + DrawEwinShape(ewin, mode.resizemode, x, y, w, h, mode.firstlast); + break; + default: + break; + } + } + break; + case MODE_DESKDRAG: + dx = mode.x - mode.px; + dy = mode.y - mode.py; + switch (desks.dragdir) + { + case 0: + if ((desks.desk[mode.deskdrag].x + dx) < 0) + dx = -desks.desk[mode.deskdrag].x; + MoveDesktop(mode.deskdrag, desks.desk[mode.deskdrag].x + dx, + desks.desk[mode.deskdrag].y); + break; + case 1: + if ((desks.desk[mode.deskdrag].x + dx) > 0) + MoveDesktop(mode.deskdrag, 0, desks.desk[mode.deskdrag].y); + else + MoveDesktop(mode.deskdrag, desks.desk[mode.deskdrag].x + dx, + desks.desk[mode.deskdrag].y); + break; + case 2: + if ((desks.desk[mode.deskdrag].y + dy) < 0) + dy = -desks.desk[mode.deskdrag].y; + MoveDesktop(mode.deskdrag, desks.desk[mode.deskdrag].x, + desks.desk[mode.deskdrag].y + dy); + break; + case 3: + if ((desks.desk[mode.deskdrag].y + dy) > 0) + MoveDesktop(mode.deskdrag, desks.desk[mode.deskdrag].x, 0); + else + MoveDesktop(mode.deskdrag, desks.desk[mode.deskdrag].x, + desks.desk[mode.deskdrag].y + dy); + break; + default: + break; + } + break; + case MODE_BUTTONDRAG: + dx = mode.x - mode.px; + dy = mode.y - mode.py; + if (mode.button_move_pending) + { + x = mode.x - mode.start_x; + y = mode.y - mode.start_y; + if (x < 0) + x = -x; + if (y < 0) + y = -y; + if ((x > mode.button_move_resistance) || + (y > mode.button_move_resistance)) + mode.button_move_pending = 0; + } + if (!mode.button_move_pending) + { + if (mode.button) + { + MovebuttonToCoord(mode.button, + mode.button->x + dx, + mode.button->y + dy); + if (mode.deskmode == MODE_DESKRAY) + { + MoveDesktop(mode.deskdrag, desks.desk[mode.deskdrag].x, + desks.desk[mode.deskdrag].y + dy); + } + } + } + break; + default: + break; + } +#define SCROLL_RATIO 2/3 + if (((mode.cur_menu_mode) || (clickmenu)) && (mode.cur_menu_depth > 0)) + { + int i, offx = 0, offy = 0, xdist = 0, ydist = 0; + EWin *ewin; + + EWin *menus[256]; + int fx[256]; + int fy[256]; + int tx[256]; + int ty[256]; + static int menu_scroll_dist = 13; + + if (mode.x > (root.w - (menu_scroll_dist + 1))) + xdist = -(menu_scroll_dist + (mode.x - root.w)); + else if (mode.x < menu_scroll_dist) + xdist = menu_scroll_dist - (mode.x); + + if (mode.y > (root.h - (menu_scroll_dist + 1))) + ydist = -(menu_scroll_dist + (mode.y - root.h)); + else if (mode.y < menu_scroll_dist) + ydist = menu_scroll_dist - (mode.y); + + /* That's a hack to avoid unwanted events: + * If the user entered the border area, he has to + * leave it first, before he can scroll menus again ... + */ + if ((xdist != 0) || (ydist != 0) || mode.doingslide) + menu_scroll_dist = -10; /* -10 has no meaning, only makes sure that the if's */ + else /* above can't be fulfilled ... */ + menu_scroll_dist = 13; + + if (mode.cur_menu_depth > 0) + { + int x1, y1, x2, y2; + + x1 = root.w; + x2 = -1; + y1 = root.h; + y2 = -1; + /* work out the minimum and maximum extents of our */ + /* currently active menus */ + for (i = 0; i < mode.cur_menu_depth; i++) + { + if (mode.cur_menu[i]) + { + ewin = FindEwinByMenu(mode.cur_menu[i]); + if (ewin) + { + if (ewin->x < x1) + x1 = ewin->x; + if (ewin->y < y1) + y1 = ewin->y; + if ((ewin->x + ewin->w - 1) > x2) + x2 = ewin->x + ewin->w - 1; + if ((ewin->y + ewin->h - 1) > y2) + y2 = ewin->y + ewin->h - 1; + } + } + } + + if (xdist < 0) + offx = root.w - x2; + else if (xdist > 0) + offx = -x1; + if (ydist < 0) + offy = root.h - y2; + else if (ydist > 0) + offy = -y1; + + if ((xdist < 0) && (offx <= 0)) + xdist = offx; + if ((xdist > 0) && (offx >= 0)) + xdist = offx; + if ((ydist < 0) && (offy <= 0)) + ydist = offy; + if ((ydist > 0) && (offy >= 0)) + ydist = offy; + + /* only if any active menus are partially off screen then scroll */ + if ((((xdist > 0) && (x1 < 0)) || ((xdist < 0) && (x2 >= root.w))) || + (((ydist > 0) && (y1 < 0)) || ((ydist < 0) && (y2 >= root.h)))) + { + /* If we would scroll too far, limit scrolling to 2/3s of screen */ + if (ydist < -root.h) + ydist = -root.h * SCROLL_RATIO; + if (ydist > root.h) + ydist = root.h * SCROLL_RATIO; + + if (xdist < -root.w) + xdist = -root.w * SCROLL_RATIO; + if (xdist > root.w) + xdist = root.w * SCROLL_RATIO; + + for (i = 0; i < mode.cur_menu_depth; i++) + { + menus[i] = NULL; + if (mode.cur_menu[i]) + { + ewin = FindEwinByMenu(mode.cur_menu[i]); + if (ewin) + { + menus[i] = ewin; + fx[i] = ewin->x; + fy[i] = ewin->y; + tx[i] = ewin->x + xdist; + ty[i] = ewin->y + ydist; + } + } + } + SlideEwinsTo(menus, fx, fy, tx, ty, mode.cur_menu_depth, mode.shadespeed); + } + } + if ((xdist != 0) || (ydist != 0)) + XWarpPointer(disp, None, None, 0, 0, 0, 0, xdist, ydist); + } + if (mode.mode == MODE_NONE) + { + Pager *p; + + p = FindPager(ev->xmotion.window); + if (p) + PagerHandleMotion(p, ev->xmotion.window, ev->xmotion.x, ev->xmotion.y); + else + PagerHandleMotion(NULL, ev->xmotion.window, -99, -99); + } + if ((mode.mode == MODE_PAGER_DRAG_PENDING) || (mode.mode == MODE_PAGER_DRAG)) + { + Pager *p; + + mode.mode = MODE_PAGER_DRAG; + p = mode.context_pager; + if (p) + { + int ax, ay, cx, cy; + + cx = desks.desk[p->desktop].current_area_x; + cy = desks.desk[p->desktop].current_area_y; + GetAreaSize(&ax, &ay); + dx = mode.x - mode.px; + dy = mode.y - mode.py; + GetWinXY(p->hi_win, &x, &y); + XRaiseWindow(disp, p->hi_win); + EMoveWindow(disp, p->hi_win, x + dx, y + dy); + if ((p->hi_ewin) && (!p->hi_ewin->pager)) + { + Window dw; + int px, py; + + XTranslateCoordinates(disp, p->win, root.win, 0, 0, &px, &py, &dw); + MoveEwin(p->hi_ewin, + ((x + dx - px) - (cx * (p->w / ax))) * + (root.w / (p->w / ax)), + ((y + dy - py) - (cy * (p->h / ay))) * + (root.h / (p->h / ay))); + } + } + } + { + Dialog *d; + DItem *di; + int dx, dy; + + di = FindDialogItem(ev->xmotion.window, &d); + if (di) + { + if (di->type == DITEM_AREA) + { + if (di->item.area.event_func) + (di->item.area.event_func) (0, ev); + } + else if ((di->type == DITEM_SLIDER) && (di->item.slider.in_drag)) + { + if (ev->xmotion.window == di->item.slider.knob_win) + { + dx = mode.x - mode.px; + dy = mode.y - mode.py; + if (di->item.slider.horizontal) + { + di->item.slider.wanted_val += dx; + di->item.slider.val = di->item.slider.lower + + (((di->item.slider.wanted_val * + (di->item.slider.upper - di->item.slider.lower)) / + (di->item.slider.base_w - di->item.slider.knob_w)) / + di->item.slider.unit) * di->item.slider.unit; + } + else + { + di->item.slider.wanted_val += dy; + di->item.slider.val = di->item.slider.lower + + ((((di->item.slider.base_h - di->item.slider.knob_h - + di->item.slider.wanted_val) * + (di->item.slider.upper - di->item.slider.lower)) / + (di->item.slider.base_h - di->item.slider.knob_h)) / + di->item.slider.unit) * di->item.slider.unit; + } + if (di->item.slider.val < di->item.slider.lower) + di->item.slider.val = di->item.slider.lower; + if (di->item.slider.val > di->item.slider.upper) + di->item.slider.val = di->item.slider.upper; + if (di->item.slider.val_ptr) + *di->item.slider.val_ptr = di->item.slider.val; + if (di->func) + (di->func) (di->val, di->data); + } + DialogDrawItems(d, di, 0, 0, 99999, 99999); + } + } + } + EDBUG_RETURN_; +} + +void +HandleDestroy(XEvent * ev) +{ + Window win; + EWin *ewin; + Client *c; + + EDBUG(5, "HandleDestroy"); + win = ev->xdestroywindow.window; + DelXID(win); + ewin = RemoveItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + if (ewin->iconified > 0) + RemoveMiniIcon(ewin); + + mode.context_win = win; + + if (ewin) + { + Pager *p; + + p = FindPager(ev->xdestroywindow.window); + if (p) + { + if ((mode.mode == MODE_PAGER_DRAG) && (p->hi_ewin)) + { + PagerHideHi(p); + } + mode.mode = MODE_NONE; + mode.context_pager = NULL; + } + if (ewin == mode.ewin) + { + if (mode.slideout) + HideSlideout(mode.slideout, mode.context_win); + switch (mode.mode) + { + case MODE_RESIZE: + case MODE_RESIZE_H: + case MODE_RESIZE_V: + doResizeEnd(NULL); + break; + case MODE_MOVE: + doMoveEnd(NULL); + break; + default: + break; + } + } + if (mode.doingslide) + { + DrawEwinShape(ewin, mode.slidemode, ewin->x, ewin->y, ewin->client.w, ewin->client.h, 2); + mode.doingslide = 0; + } + if (ewin == mode.focuswin) + FocusToEWin(NULL); + if (ewin == mode.mouse_over_win) + mode.mouse_over_win = NULL; + if (ewin == mode.ewin) + mode.ewin = NULL; + if (ewin->docked) + DockDestroy(ewin); + DesktopRemoveEwin(ewin); + FreeEwin(ewin); + GNOME_SetClientList(); + EDBUG_RETURN_; + } + c = FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_CLIENT); + if (c) + DeleteClient(c); + if (win == external_pager_window) + { + ShowIcons(); + } + EDBUG_RETURN_; +} + +void +HandleProperty(XEvent * ev) +{ + Window win; + EWin *ewin; + char title[10240]; + int desktop; + static Atom pga = 0; + + EDBUG(5, "HandleProperty"); + win = ev->xproperty.window; + ewin = FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + { + GrabX(); + if (ewin->client.title) + strncpy(title, ewin->client.title, 10240); + desktop = ewin->desktop; + GNOME_GetHintDesktop(ewin, ev->xproperty.atom); + if ((desktop != ewin->desktop) && (!ewin->sticky)) + MoveEwinToDesktop(ewin, ewin->desktop); + GNOME_GetHintIcons(ewin, ev->xproperty.atom); + GNOME_GetHintAppState(ewin, ev->xproperty.atom); + GNOME_GetExpandedSize(ewin, ev->xproperty.atom); + GNOME_GetHint(ewin, ev->xproperty.atom); + ICCCM_GetTitle(ewin, ev->xproperty.atom); + ICCCM_GetHints(ewin, ev->xproperty.atom); + ICCCM_GetInfo(ewin, ev->xproperty.atom); + ICCCM_GetColormap(ewin); + ICCCM_GetGeoms(ewin, ev->xproperty.atom); + SessionGetInfo(ewin, ev->xproperty.atom); + SyncBorderToEwin(ewin); + if (ewin->client.title) + if (strncmp(title, ewin->client.title, 10240)) + { + UpdateBorderInfo(ewin); + CalcEwinSizes(ewin); + } + UngrabX(); + } + else if (win == root.win) + { + if (!pga) + pga = XInternAtom(disp, "_GNOME_PAGER_ACTIVE", False); + if (ev->xproperty.atom == pga) + HandlePager(); + } + EDBUG_RETURN_; +} + +void +HandleCirculate(XEvent * ev) +{ + Window win; + EWin *ewin; + + EDBUG(5, "HandleCirculate"); + win = ev->xcirculaterequest.window; + ewin = FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + { + if (ev->xcirculaterequest.place == PlaceOnTop) + RaiseEwin(ewin); + else + LowerEwin(ewin); + } + else + { + if (ev->xcirculaterequest.place == PlaceOnTop) + XRaiseWindow(disp, win); + else + XLowerWindow(disp, win); + } + EDBUG_RETURN_; +} + +void +HandleReparent(XEvent * ev) +{ + Window par; + EWin *ewin, *ewin2; + void **lst; + int i, num, found = 0; + + EDBUG(5, "HandleReparent"); + par = ev->xreparent.window; + EDBUG_RETURN_; + ewin = FindItem(NULL, ev->xreparent.window, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (!ewin) + EDBUG_RETURN_; + lst = ListItemType(&num, LIST_TYPE_EWIN); + if ((lst) && (num > 0)) + { + for (i = 0; i < num; i++) + { + ewin2 = (EWin *) lst[i]; + if (ewin2->win == ev->xreparent.parent) + found = 1; + } + } + if (lst) + Efree(lst); + if (!found) + { + ewin = RemoveItem(NULL, ev->xreparent.window, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + { + if (ewin == mode.ewin) + { + switch (mode.mode) + { + case MODE_RESIZE: + case MODE_RESIZE_H: + case MODE_RESIZE_V: + doResizeEnd(NULL); + break; + case MODE_MOVE: + doMoveEnd(NULL); + break; + default: + break; + } + } + ewin->client.win = 0; + if ((mode.slideout) && (ewin == mode.ewin)) + HideSlideout(mode.slideout, mode.context_win); + FreeEwin(ewin); + GNOME_SetClientList(); + } + } + EDBUG_RETURN_; +} + +void +HandleConfigureRequest(XEvent * ev) +{ + Window win, winrel; + EWin *ewin, *ewin2; + int x = 0, y = 0, w = 0, h = 0; + XWindowChanges xwc; + + EDBUG(5, "HandleConfigureRequest"); + win = ev->xconfigurerequest.window; + ewin = FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + { + x = ewin->x + ewin->border->border.left; + y = ewin->y + ewin->border->border.top; + w = ewin->client.w; + h = ewin->client.h; + winrel = 0; + if (ev->xconfigurerequest.value_mask & CWX) + x = ev->xconfigurerequest.x; + if (ev->xconfigurerequest.value_mask & CWY) + y = ev->xconfigurerequest.y; + if (ev->xconfigurerequest.value_mask & CWWidth) + w = ev->xconfigurerequest.width; + if (ev->xconfigurerequest.value_mask & CWHeight) + h = ev->xconfigurerequest.height; + if (ev->xconfigurerequest.value_mask & CWSibling) + winrel = ev->xconfigurerequest.above; + if (ev->xconfigurerequest.value_mask & CWStackMode) + { + ewin2 = FindItem(NULL, winrel, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin2) + winrel = ewin2->win; + xwc.sibling = winrel; + xwc.stack_mode = ev->xconfigurerequest.detail; + if (mode.mode == MODE_NONE) + { + if (xwc.stack_mode == Above) + RaiseEwin(ewin); + else if (xwc.stack_mode == Below) + LowerEwin(ewin); + } +/* else + * XConfigureWindow(disp, ewin->win, + * ev->xconfigurerequest.value_mask & + * (CWSibling | CWStackMode), &xwc); */ + } + /* this ugly workaround here is because x11amp is very brain-dead */ + /* and sets its minunum and maximm sizes the same - fair enough */ + /* to ensure it doesnt get resized - BUT hwne it shades itself */ + /* it resizes down to a smaller size - of course keeping the */ + /* minimum and maximim size same - E unconditionally disallows any */ + /* client window to be resized outside of its constraints */ + /* (any client could do this resize - not just x11amp thus E is */ + /* imposing the hints x11amp set up - this works around by */ + /* modifying the constraints to fit what the app requested */ + if (w < ewin->client.width.min) + ewin->client.width.min = w; + if (w > ewin->client.width.max) + ewin->client.width.max = w; + if (h < ewin->client.height.min) + ewin->client.height.min = h; + if (h > ewin->client.height.max) + ewin->client.height.max = h; + MoveResizeEwin(ewin, + x - ewin->border->border.left, + y - ewin->border->border.top, + w, h); + if (mode.mode == MODE_MOVE) + ICCCM_Configure(ewin); + ReZoom(ewin); + } + else + { + xwc.x = ev->xconfigurerequest.x; + xwc.y = ev->xconfigurerequest.y; + xwc.width = ev->xconfigurerequest.width; + xwc.height = ev->xconfigurerequest.height; + xwc.border_width = ev->xconfigurerequest.border_width; + xwc.sibling = ev->xconfigurerequest.above; + xwc.stack_mode = ev->xconfigurerequest.detail; + XConfigureWindow(disp, win, ev->xconfigurerequest.value_mask, &xwc); + } + EDBUG_RETURN_; +} + +void +HandleResizeRequest(XEvent * ev) +{ + Window win; + EWin *ewin; + int w, h; + + EDBUG(5, "HandleResizeRequest"); + win = ev->xresizerequest.window; + ewin = FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + { + w = ev->xresizerequest.width; + h = ev->xresizerequest.height; + ResizeEwin(ewin, w, h); + ReZoom(ewin); + } + else + EResizeWindow(disp, win, ev->xresizerequest.width, ev->xresizerequest.height); + EDBUG_RETURN_; +} + +void +HandleUnmap(XEvent * ev) +{ + Window win; + EWin *ewin; + + EDBUG(5, "HandleUnmap"); + win = ev->xunmap.window; + ewin = FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + { + if (ewin->iconified > 1) + { + ewin->iconified = ewin->iconified - 1; + EDBUG_RETURN_; + } + } + if (ewin) + { + Pager *p; + + p = FindPager(ev->xdestroywindow.window); + if (p) + { + if ((mode.mode == MODE_PAGER_DRAG) && (p->hi_ewin)) + { + PagerHideHi(p); + } + mode.mode = MODE_NONE; + mode.context_pager = NULL; + } + if (ewin->pager) + PagerHideHi(ewin->pager); + if (ewin->docked) + DockDestroy(ewin); + if (ewin == mode.ewin) + { + switch (mode.mode) + { + case MODE_RESIZE: + case MODE_RESIZE_H: + case MODE_RESIZE_V: + doResizeEnd(NULL); + break; + case MODE_MOVE: + doMoveEnd(NULL); + break; + default: + break; + } + } + if (!ewin->iconified) + { + if ((mode.slideout) && (ewin == mode.ewin)) + HideSlideout(mode.slideout, mode.context_win); + } + if (ewin == mode.focuswin) + FocusToEWin(NULL); + if (ewin == mode.mouse_over_win) + mode.mouse_over_win = NULL; + if (ewin == mode.ewin) + mode.ewin = NULL; + if (!ewin->iconified) + { + XTranslateCoordinates(disp, ewin->client.win, root.win, + -ewin->border->border.left, + -ewin->border->border.top, + &ewin->client.x, &ewin->client.y, &win); + EReparentWindow(disp, ewin->client.win, root.win, + ewin->client.x, ewin->client.y); + XRemoveFromSaveSet(disp, ewin->client.win); + ICCCM_Withdraw(ewin); + RemoveItem(NULL, ewin->client.win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + DesktopRemoveEwin(ewin); + FreeEwin(ewin); + GNOME_SetClientList(); + } + else + HideEwin(ewin); + } + EDBUG_RETURN_; +} + +void +HandleMapRequest(XEvent * ev) +{ + EDBUG(5, "HandleMapRequest"); + AddToFamily(ev->xmap.window); + GNOME_SetClientList(); + EDBUG_RETURN_; +} + +void +HandleExpose(XEvent * ev) +{ + Window win; + EWin **ewin; + int i, j, num; + + EDBUG(5, "HandleExpose"); + + win = ev->xexpose.window; + + ewin = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + for (i = 0; i < num; i++) + { + for (j = 0; j < ewin[i]->border->num_winparts; j++) + { + if (win == ewin[i]->bits[j].win) + { + ewin[i]->bits[j].no_expose = 0; + ewin[i]->bits[j].expose = 1; + if ((DrawEwinWinpart(ewin[i], j)) && + (IsPropagateEwinOnQueue(ewin[i]))) + PropagateShapes(ewin[i]->win); + Efree(ewin); + EDBUG_RETURN_; + } + } + } + + if (ewin) + Efree(ewin); + + { + Button **button; + + button = (Button **) ListItemType(&num, LIST_TYPE_BUTTON); + for (i = 0; i < num; i++) + { + if (win == button[i]->win) + { + DrawButton(button[i]); + Efree(button); + EDBUG_RETURN_; + } + } + if (button) + Efree(button); + } + + { + Dialog *d; + int bnum; + + d = FindDialogButton(win, &bnum); + if (d) + DialogDrawButton(d, bnum); + else + { + d = FindDialog(win); + if (d) + { + DialogDrawArea(d, ev->xexpose.x, ev->xexpose.y, + ev->xexpose.width, ev->xexpose.height); + } + else + { + DItem *di; + int x, y, w, h; + + di = FindDialogItem(win, &d); + GetWinXY(win, &x, &y); + GetWinWH(win, (unsigned int *)&w, (unsigned int *)&h); + if (d) + DialogDrawArea(d, x, y, w, h); + if (di) + { + if (di->type == DITEM_AREA) + { + if (di->func) + (di->func) (di->val, di->data); + } + } + } + } + } + + EDBUG_RETURN_; +} + +void +HandleMouseDown(XEvent * ev) +{ + Window win; + EWin *ewin; + EWin **ewins; + int i, j, num; + Button **buttons; + ActionClass *ac; + Menu *m; + MenuItem *mi; + int desk_click = -1; + char double_click = 0; + float mode_double_click_time = 0.25; + + EDBUG(5, "HandleMouseDown"); + + /* DON'T handle clicks whilst moving/resizing things unless doing manual placement */ + if (mode.mode != MODE_NONE) + EDBUG_RETURN_; + if ((mode.cur_menu_mode) && (!clickmenu)) + EDBUG_RETURN_; + if (ttip) + HideToolTip(ttip); + RemoveTimerEvent("TOOLTIP_TIMEOUT"); + if (mode.tooltips) + DoIn("TOOLTIP_TIMEOUT", mode.tiptime, ToolTipTimeout, 0, NULL); + + if ((((float)(ev->xbutton.time - last_time) / 1000) < mode_double_click_time) && + ((int)(ev->xbutton.button) == (int)(last_button))) + double_click = 1; + last_time = ev->xbutton.time; + last_button = ev->xbutton.button; + + last_bpress = click_was_in = win = ev->xbutton.window; + + mode.x = ev->xbutton.x_root; + mode.y = ev->xbutton.y_root; + +/* + * if (sentpress) + * { + * win = WindowAtXY(ev->xbutton.x_root, ev->xbutton.y_root); + * sentpress = 0; + * } + */ + mode.context_win = win; + for (i = 0; i < mode.numdesktops; i++) + { + if (win == desks.desk[i].win) + { + desk_click = i; + break; + } + } + if (desk_click >= 0) + { + ActionClass *ac; + + XUngrabPointer(disp, CurrentTime); + + ac = FindItem("DESKBINDINGS", 0, LIST_FINDBY_NAME, + LIST_TYPE_ACLASS); + if (ac) + { + if (!EventAclass(ev, ac)) + XSendEvent(disp, bpress_win, False, SubstructureNotifyMask, ev); + } + EDBUG_RETURN_; + } + m = FindMenuItem(click_was_in, &mi); + if ((!m) && (mode.focusmode == FOCUS_CLICK)) + { + ewin = FindEwinByChildren(win); + if (!ewin) + ewin = FindEwinByBase(win); + if (ewin) + FocusToEWin(ewin); + if (ewin) + RaiseEwin(ewin); +/* allow click to pass thorugh */ + if ((ewin) && (ewin->win_container == win)) + { + XSync(disp, False); + XAllowEvents(disp, ReplayPointer, CurrentTime); + XSync(disp, False); + } +/* done */ + } + if (m) + { + mode.cur_menu_mode = 1; + mi->state = STATE_CLICKED; + DrawMenuItem(m, mi, 1); + if (mi->child) + { + int mx, my; + unsigned int mw, mh; + EWin *ewin2; + + mode.cur_menu[0] = m; + mode.cur_menu_depth = 1; + ShowMenuMasker(m); + XUngrabPointer(disp, CurrentTime); + ewin = FindEwinByMenu(m); + if (ewin) + { + GetWinXY(mi->win, &mx, &my); + GetWinWH(mi->win, &mw, &mh); + ShowMenu(mi->child, 1); + ewin2 = FindEwinByMenu(mi->child); + if (ewin2) + { + MoveEwin(ewin2, ewin->x + ewin->border->border.left + mx + mw, + ewin->y + ewin->border->border.top + my - + ewin2->border->border.top); + RaiseEwin(ewin2); + ShowEwin(ewin2); + if (mode.menuslide) + UnShadeEwin(ewin2); + mode.cur_menu[mode.cur_menu_depth++] = mi->child; + } + } + } + EDBUG_RETURN_; + } + if (double_click) + ev->xbutton.time = 0; + + ewins = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if (ewins) + { + for (i = 0; i < num; i++) + { + for (j = 0; j < ewins[i]->border->num_winparts; j++) + { + if (win == ewins[i]->bits[j].win) + { + if (!clickmenu) + { + GrabThePointer(win); + mode.ewin = ewins[i]; + ewins[i]->bits[j].state = STATE_CLICKED; + ChangeEwinWinpart(ewins[i], j); + if ((!ewins[i]->menu) && (!mode.cur_menu_mode)) + mode.context_ewin = ewins[i]; + mode.borderpartpress = 1; + if (ewins[i]->border->part[j].aclass) + EventAclass(ev, ewins[i]->border->part[j].aclass); + mode.borderpartpress = 0; + } + Efree(ewins); + EDBUG_RETURN_; + } + } + } + Efree(ewins); + } + if (win) + { + buttons = (Button **) ListItemType(&num, LIST_TYPE_BUTTON); + for (i = 0; i < num; i++) + { + if ((win == buttons[i]->win) || (win == buttons[i]->event_win)) + { + GrabThePointer(win); + if (buttons[i]->inside_win) + XSendEvent(disp, buttons[i]->inside_win, False, ButtonPressMask, ev); + mode.button = buttons[i]; + buttons[i]->state = STATE_CLICKED; + DrawButton(buttons[i]); + ac = FindItem("ACTION_BUTTON_DRAG", 0, LIST_FINDBY_NAME, + LIST_TYPE_ACLASS); + if (ac) + EventAclass(ev, ac); + if (buttons[i]->aclass) + EventAclass(ev, buttons[i]->aclass); + Efree(buttons); + EDBUG_RETURN_; + } + } + if (buttons) + Efree(buttons); + } + { + Dialog *d; + int bnum; + + d = FindDialogButton(win, &bnum); + if (d) + DialogActivateButton(win, 2); + else + { + DItem *di; + + di = FindDialogItem(win, &d); + if (di) + { + if (di->type == DITEM_AREA) + { + if (di->item.area.event_func) + (di->item.area.event_func) (0, ev); + } + else if (di->type == DITEM_SLIDER) + { + if (win == di->item.slider.base_win) + { + if (di->item.slider.horizontal) + { + if (ev->xbutton.x > + (di->item.slider.knob_x + + (di->item.slider.knob_w / 2))) + di->item.slider.val += di->item.slider.jump; + else + di->item.slider.val -= di->item.slider.jump; + } + else + { + if (ev->xbutton.y > + (di->item.slider.knob_y + + (di->item.slider.knob_h / 2))) + di->item.slider.val -= di->item.slider.jump; + else + di->item.slider.val += di->item.slider.jump; + } + if (di->item.slider.val < di->item.slider.lower) + di->item.slider.val = di->item.slider.lower; + if (di->item.slider.val > di->item.slider.upper) + di->item.slider.val = di->item.slider.upper; + if (di->item.slider.val_ptr) + *di->item.slider.val_ptr = di->item.slider.val; + if (di->func) + (di->func) (di->val, di->data); + } + else if (win == di->item.slider.knob_win) + { + di->item.slider.in_drag = 1; + if (di->item.slider.horizontal) + di->item.slider.wanted_val = di->item.slider.knob_x; + else + di->item.slider.wanted_val = di->item.slider.knob_y; + } + } + di->clicked = 1; + DialogDrawItems(d, di, 0, 0, 99999, 99999); + } + } + } + ewin = FindEwinByBase(ev->xbutton.window); + if (ewin) + { + ActionClass *ac; + + ac = (ActionClass *) FindItem("BUTTONBINDINGS", 0, + LIST_FINDBY_NAME, + LIST_TYPE_ACLASS); + if (ac) + { + mode.ewin = ewin; + GrabThePointer(ewin->win); + mode.borderpartpress = 1; + if (EventAclass(ev, ac)) + { + mode.borderpartpress = 0; + EDBUG_RETURN_; + } + mode.borderpartpress = 0; + } + } + { + Pager *p; + + p = FindPager(ev->xbutton.window); + if (p) + { + if (ev->xbutton.window == p->hi_win) + { + int hx, hy; + Window dw; + + XTranslateCoordinates(disp, p->hi_win, p->win, 0, 0, &hx, &hy, &dw); + ev->xbutton.x += hx; + ev->xbutton.y += hy; + } + if (ev->xbutton.button == 3) + { + if ((ev->xbutton.x >= 0) && (ev->xbutton.y >= 0) && + (ev->xbutton.x < p->w) && (ev->xbutton.y < p->h)) + PagerShowMenu(p, ev->xbutton.x, ev->xbutton.y); + } + else if (ev->xbutton.button == 1) + { + ewin = EwinInPagerAt(p, ev->xbutton.x, ev->xbutton.y); + if ((ewin) && (!ewin->pager)) + { + Window dw; + int wx, wy, ww, wh, ax, ay, cx, cy, + px, py; + + PagerHideHi(p); + GetAreaSize(&ax, &ay); + cx = desks.desk[p->desktop].current_area_x; + cy = desks.desk[p->desktop].current_area_y; + wx = ((ewin->x + (cx * root.w)) * (p->w / ax)) / root.w; + wy = ((ewin->y + (cy * root.h)) * (p->h / ay)) / root.h; + ww = ((ewin->w) * (p->w / ax)) / root.w; + wh = ((ewin->h) * (p->h / ay)) / root.h; + XTranslateCoordinates(disp, p->win, root.win, 0, 0, &px, &py, &dw); + EMoveResizeWindow(disp, p->hi_win, px + wx, py + wy, ww, wh); + ESetWindowBackgroundPixmap(disp, p->hi_win, ewin->mini_pmap); + EMapRaised(disp, p->hi_win); + GrabThePointer(p->hi_win); + p->hi_visible = 1; + mode.mode = MODE_PAGER_DRAG_PENDING; + mode.context_pager = p; + pgd_x = ewin->x; + pgd_y = ewin->y; + } + } + } + } + EDBUG_RETURN_; +} + +void +HandleMouseUp(XEvent * ev) +{ + Window win, win2; + EWin *ewin; + EWin **ewins; + int i, j, num; + Button **buttons; + char wasdrag; + char wasmovres; + char justclicked = 0; + Slideout *pslideout; + Menu *m; + MenuItem *mi; + EWin **gwins; + + EDBUG(5, "HandleMouseUp"); + + /* DON'T handle clicks whilst moving/resizing things */ + if ((mode.mode != MODE_NONE) && + (!((mode.place) && (mode.mode == MODE_MOVE)))) + { + if ((int)last_button != (int)ev->xbutton.button) + EDBUG_RETURN_; + } + if (ttip) + HideToolTip(ttip); + RemoveTimerEvent("TOOLTIP_TIMEOUT"); + if (mode.tooltips) + DoIn("TOOLTIP_TIMEOUT", mode.tiptime, ToolTipTimeout, 0, NULL); + + UnGrabTheButtons(); + win2 = WindowAtXY(ev->xbutton.x_root, ev->xbutton.y_root); + win = ev->xbutton.window; + + mode.x = ev->xbutton.x_root; + mode.y = ev->xbutton.y_root; + + if ((mode.place) && (mode.mode == MODE_MOVE)) + { + ewin = GetEwin(); + if (ewin) + { + gwins = ListWinGroupMembersForEwin(ewin, ACTION_MOVE, &num); + if ((mode.movemode == 0) && (mode.mode == MODE_MOVE)) + for (i = 0; i < num; i++) + DetermineEwinFloat(gwins[i], 0, 0); + Efree(gwins); + } + doMoveEnd(NULL); + if (mode.have_place_grab) + { + mode.have_place_grab = 0; + XUngrabPointer(disp, CurrentTime); + } + mode.place = 0; + EDBUG_RETURN_; + } + wasdrag = 0; + wasmovres = 0; + pslideout = mode.slideout; + + if ((last_bpress) && (last_bpress != win)) + { + ewin = FindEwinByChildren(last_bpress); + if (ewin) + { + for (j = 0; j < ewin->border->num_winparts; j++) + { + if (last_bpress == ewin->bits[j].win) + { + if ((ewin->bits[j].state == STATE_CLICKED) && + (!ewin->bits[j].left)) + ewin->bits[j].state = STATE_HILITED; + else + ewin->bits[j].state = STATE_NORMAL; + ewin->bits[j].left = 0; + ChangeEwinWinpart(ewin, j); + break; + } + } + } + last_bpress = 0; + } + wasdrag = 0; + wasmovres = 0; + switch (mode.mode) + { + case MODE_RESIZE: + case MODE_RESIZE_H: + case MODE_RESIZE_V: + doResizeEnd(NULL); + wasmovres = 1; + break; + case MODE_MOVE: + ewin = GetEwin(); + if (ewin) + { + gwins = ListWinGroupMembersForEwin(ewin, ACTION_MOVE, &num); + if ((mode.movemode == 0) && (mode.mode == MODE_MOVE)) + for (i = 0; i < num; i++) + DetermineEwinFloat(gwins[i], 0, 0); + Efree(gwins); + } + doMoveEnd(NULL); + if (mode.have_place_grab) + { + mode.have_place_grab = 0; + XUngrabPointer(disp, CurrentTime); + } + mode.place = 0; + wasmovres = 1; + mode.ewin = NULL; + break; + default: + break; + } + + if (sentpress) + { + sentpress = 0; + XSendEvent(disp, bpress_win, False, SubstructureNotifyMask, ev); + } + mode.context_win = click_was_in; + mode.destroy = 0; + pslideout = mode.slideout; + if (mode.slideout) + { + ewin = FindEwinByChildren(mode.slideout->from_win); + if (ewin) + mode.ewin = ewin; + } + if (mode.mode == MODE_DESKDRAG) + mode.mode = MODE_NONE; + if (mode.mode == MODE_BUTTONDRAG) + { + if (!mode.button_move_pending) + wasdrag = 1; + doDragButtonEnd(NULL); + } + m = FindMenuItem(win, &mi); +/* if ((m) || (win2 == mode.context_win)) */ + if ((((float)(ev->xbutton.time - last_time) / 1000) < 0.5) && + (mode.cur_menu_depth > 0) && (!clickmenu)) + { + clickmenu = 1; + justclicked = 1; + } + if ((m) && (mi->state)) + { + mi->state = STATE_HILITED; + DrawMenuItem(m, mi, 1); + if ((mi->act_id) && (!justclicked)) + { + (*(ActionFunctions[mi->act_id])) (mi->params); + if (clickmenu) + { + for (i = 0; i < mode.cur_menu_depth; i++) + { + if (!mode.cur_menu[i]->stuck) + HideMenu(mode.cur_menu[i]); + } + HideMenuMasker(); + mode.cur_menu_depth = 0; + mode.cur_menu_mode = 0; + mode.context_ewin = NULL; + last_bpress = 0; + clickmenu = 0; + EDBUG_RETURN_; + } + } + } + if ((mode.cur_menu_mode) && (!clickmenu)) + { + if (!m) + { + Window ww; + + ww = WindowAtXY(mode.x, mode.y); + if ((ewin = FindEwinByChildren(ww))) + { + if ((ewin->menu) && (ww != ewin->menu->win)) + { + ewin->menu->stuck = 1; + mode.context_ewin = ewin; + } + } + } + for (i = 0; i < mode.cur_menu_depth; i++) + { + if (!mode.cur_menu[i]->stuck) + HideMenu(mode.cur_menu[i]); + } + HideMenuMasker(); + mode.cur_menu_depth = 0; + mode.cur_menu_mode = 0; + last_bpress = 0; + clickmenu = 0; + EDBUG_RETURN_; + } + if ((mode.cur_menu_mode) && (!justclicked)) + { + for (i = 0; i < mode.cur_menu_depth; i++) + { + if (!mode.cur_menu[i]->stuck) + HideMenu(mode.cur_menu[i]); + } + HideMenuMasker(); + mode.cur_menu_depth = 0; + mode.cur_menu_mode = 0; + last_bpress = 0; + clickmenu = 0; + EDBUG_RETURN_; + } + ewins = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + for (i = 0; i < num; i++) + { + for (j = 0; j < ewins[i]->border->num_winparts; j++) + { + if (click_was_in == ewins[i]->bits[j].win) + { + if (!clickmenu) + { + if (ewins[i] == mode.ewin) + { + switch (mode.mode) + { + case MODE_RESIZE: + case MODE_RESIZE_H: + case MODE_RESIZE_V: + doResizeEnd(NULL); + break; + case MODE_MOVE: + doMoveEnd(NULL); + break; + default: + break; + } + } + if ((ewins[i]->bits[j].state == STATE_CLICKED) && + (!ewins[i]->bits[j].left)) + ewins[i]->bits[j].state = STATE_HILITED; + else + ewins[i]->bits[j].state = STATE_NORMAL; + ewins[i]->bits[j].left = 0; + ChangeEwinWinpart(ewins[i], j); + if ((!ewins[i]->menu) && (!mode.cur_menu_mode)) + mode.context_ewin = ewins[i]; + mode.borderpartpress = 1; + if ((click_was_in == win2) && (ewins[i]->border->part[j].aclass) && + (!wasmovres)) + EventAclass(ev, ewins[i]->border->part[j].aclass); + mode.borderpartpress = 0; + if ((mode.slideout) && (pslideout)) + HideSlideout(mode.slideout, mode.context_win); + } + Efree(ewins); + click_was_in = 0; + last_bpress = 0; + EDBUG_RETURN_; + } + } + } + if (ewins) + Efree(ewins); + if (click_was_in) + { + buttons = (Button **) ListItemType(&num, LIST_TYPE_BUTTON); + for (i = 0; i < num; i++) + { + if ((click_was_in == buttons[i]->win) || (click_was_in == buttons[i]->event_win)) + { + if ((buttons[i]->inside_win) && (!wasmovres)) + XSendEvent(disp, buttons[i]->inside_win, False, + ButtonReleaseMask, ev); + mode.button = buttons[i]; + if ((buttons[i]->state == STATE_CLICKED) && + (!buttons[i]->left)) + buttons[i]->state = STATE_HILITED; + else + buttons[i]->state = STATE_NORMAL; + buttons[i]->left = 0; + DrawButton(buttons[i]); + if ((buttons[i]->aclass) && (!wasdrag) && (!wasmovres)) + EventAclass(ev, buttons[i]->aclass); + mode.destroy = 0; + if ((mode.slideout) && (pslideout)) + HideSlideout(mode.slideout, mode.context_win); + Efree(buttons); + click_was_in = 0; + last_bpress = 0; + EDBUG_RETURN_; + } + } + if (buttons) + Efree(buttons); + } + { + Dialog *d; + int bnum; + + d = FindDialogButton(click_was_in, &bnum); + if (d) + DialogActivateButton(click_was_in, 3); + else + { + DItem *di; + + di = FindDialogItem(click_was_in, &d); + if (di) + { + di->clicked = 0; + if (click_was_in) + { + if (di->type == DITEM_AREA) + { + if (di->item.area.event_func) + (di->item.area.event_func) (0, ev); + } + else if (di->type == DITEM_CHECKBUTTON) + { + if (di->item.check_button.onoff) + di->item.check_button.onoff = 0; + else + di->item.check_button.onoff = 1; + if (di->item.check_button.onoff_ptr) + *di->item.check_button.onoff_ptr = + di->item.check_button.onoff; + } + else if (di->type == DITEM_RADIOBUTTON) + { + DItem *dii; + + dii = di->item.radio_button.first; + while (dii) + { + if (dii->item.radio_button.onoff) + { + dii->item.radio_button.onoff = 0; + DialogDrawItems(d, dii, 0, 0, 99999, 99999); + } + dii = dii->item.radio_button.next; + } + di->item.radio_button.onoff = 1; + if (di->item.radio_button.val_ptr) + *di->item.radio_button.val_ptr = + di->item.radio_button.val; + } + else if (di->type == DITEM_SLIDER) + { + if (win == di->item.slider.knob_win) + di->item.slider.in_drag = 0; + } + } + DialogDrawItems(d, di, 0, 0, 99999, 99999); + if (click_was_in) + { + if (di->func) + (di->func) (di->val, di->data); + } + } + } + } + ewin = FindEwinByBase(ev->xbutton.window); + if (ewin) + { + ActionClass *ac; + + ac = (ActionClass *) FindItem("BUTTONBINDINGS", 0, + LIST_FINDBY_NAME, + LIST_TYPE_ACLASS); + if (ac) + { + mode.borderpartpress = 1; + if (EventAclass(ev, ac)) + { + mode.borderpartpress = 0; + mode.destroy = 0; + if ((mode.slideout) && (pslideout)) + HideSlideout(mode.slideout, mode.context_win); + click_was_in = 0; + EDBUG_RETURN_; + } + mode.borderpartpress = 0; + } + } + if (!wasmovres) + { + Pager *p; + int pax, pay; + + p = FindPager(ev->xbutton.window); + if (p) + { + if (ev->xbutton.window == p->hi_win) + { + int hx, hy; + Window dw; + + XTranslateCoordinates(disp, p->hi_win, p->win, 0, 0, &hx, &hy, &dw); + ev->xbutton.x += hx; + ev->xbutton.y += hy; + } + if ((mode.mode == MODE_PAGER_DRAG) && (p->hi_ewin)) + { + ewin = GetEwinPointerInClient(); + if ((ewin) && (ewin->pager)) + { + Pager *pp; + int x, y, ax, ay, cx, cy, px, py; + Window dw; + + pp = ewin->pager; + cx = desks.desk[pp->desktop].current_area_x; + cy = desks.desk[pp->desktop].current_area_y; + GetAreaSize(&ax, &ay); + GetWinXY(p->hi_win, &x, &y); + XTranslateCoordinates(disp, pp->win, root.win, 0, 0, &px, &py, &dw); + MoveEwinToDesktopAt(p->hi_ewin, pp->desktop, + ((x - px) - (cx * (pp->w / ax))) * + (root.w / (pp->w / ax)), + ((y - py) - (cy * (pp->h / ay))) * + (root.h / (pp->h / ay))); + } + else + { + int ndesk, nx, ny; + + ndesk = desks.current; + nx = (int)ev->xbutton.x_root - desks.desk[desks.current].x - + ((int)p->hi_ewin->w / 2); + ny = (int)ev->xbutton.y_root - desks.desk[desks.current].y - + ((int)p->hi_ewin->h / 2); + MoveEwin(p->hi_ewin, nx, ny); + MoveEwinToDesktop(p->hi_ewin, ndesk); + } + RedrawPagersForDesktop(p->hi_ewin->desktop, 3); + ForceUpdatePagersForDesktop(p->hi_ewin->desktop); + p->hi_visible = 1; + PagerHideHi(p); + } + else if ((ev->xbutton.x >= 0) && (ev->xbutton.y >= 0) && + (ev->xbutton.x < p->w) && (ev->xbutton.y < p->h)) + { + PagerAreaAt(p, ev->xbutton.x, ev->xbutton.y, &pax, &pay); + GotoDesktop(p->desktop); + SetCurrentArea(pax, pay); + ewin = EwinInPagerAt(p, ev->xbutton.x, ev->xbutton.y); + if (ewin) + { + RaiseEwin(ewin); + FocusToEWin(ewin); + } + } + mode.mode = MODE_NONE; + mode.context_pager = NULL; + } + } + mode.destroy = 0; + if ((mode.slideout) && (pslideout)) + HideSlideout(mode.slideout, mode.context_win); + click_was_in = 0; + EDBUG_RETURN_; +} + +void +SubmenuShowTimeout(int val, void *dat) +{ + int mx, my; + unsigned int mw, mh; + EWin *ewin2; + struct _mdata *data; + + data = (struct _mdata *)dat; + if (!data) + return; + if (!data->m) + return; + if (!FindEwinByMenu(data->m)) + return; + GetWinXY(data->mi->win, &mx, &my); + GetWinWH(data->mi->win, &mw, &mh); + ShowMenu(data->mi->child, 1); + ewin2 = FindEwinByMenu(data->mi->child); + if (ewin2) + { + MoveEwin(ewin2, data->ewin->x + data->ewin->border->border.left + mx + mw, + data->ewin->y + data->ewin->border->border.top + my - + ewin2->border->border.top); + RaiseEwin(ewin2); + ShowEwin(ewin2); + if (mode.menuslide) + UnShadeEwin(ewin2); + if (mode.cur_menu[mode.cur_menu_depth - 1] != data->mi->child) + mode.cur_menu[mode.cur_menu_depth++] = data->mi->child; + } + val = 0; +} + +void +HandleMouseIn(XEvent * ev) +{ + Window win; + EWin *ewin; + EWin **ewins; + int i, j, num; + Button **buttons; + Menu *m; + MenuItem *mi; + static struct _mdata mdata; + + EDBUG(5, "HandleMouseIn"); + + if (ttip) + HideToolTip(ttip); + RemoveTimerEvent("TOOLTIP_TIMEOUT"); + if (mode.tooltips) + DoIn("TOOLTIP_TIMEOUT", mode.tiptime, ToolTipTimeout, 0, NULL); + + EdgeHandleEnter(ev); + win = ev->xcrossing.window; + + mode.context_win = win; + + m = FindMenuItem(win, &mi); + if (m) + { + int j; + + PagerHideAllHi(); + if ((win == mi->icon_win) && (ev->xcrossing.detail == NotifyAncestor)) + EDBUG_RETURN_; + if ((win == mi->win) && (ev->xcrossing.detail == NotifyInferior)) + EDBUG_RETURN_; + mi->state = STATE_HILITED; + DrawMenuItem(m, mi, 1); + + RemoveTimerEvent("SUBMENU_SHOW"); + for (i = 0; i < mode.cur_menu_depth; i++) + { + if (mode.cur_menu[i] == m) + { + if ((!mi->child) || + ((mi->child) && (mode.cur_menu[i + 1] != mi->child))) + { + for (j = i + 1; j < mode.cur_menu_depth; j++) + HideMenu(mode.cur_menu[j]); + mode.cur_menu_depth = i + 1; + i = mode.cur_menu_depth; + break; + } + } + } + if ((mi->child) && (mode.cur_menu_mode)) + { + ewin = FindEwinByMenu(m); + if (ewin) + { + mdata.m = m; + mdata.mi = mi; + mdata.ewin = ewin; + DoIn("SUBMENU_SHOW", 0.2, SubmenuShowTimeout, + 0, &mdata); +/* + * GetWinXY(mi->win, &mx, &my); + * GetWinWH(mi->win, &mw, &mh); + * ShowMenu(mi->child, 1); + * ewin2 = FindEwinByMenu(mi->child); + * if (ewin2) + * { + * MoveEwin(ewin2, ewin->x + ewin->border->border.left + mx + mw, + * ewin->y + ewin->border->border.top + my - + * ewin2->border->border.top); + * RaiseEwin(ewin2); + * ShowEwin(ewin2); + * if (mode.menuslide) + * UnShadeEwin(ewin2); + * if (mode.cur_menu[mode.cur_menu_depth - 1] != mi->child) + * mode.cur_menu[mode.cur_menu_depth++] = mi->child; + * } + */ + } + } + EDBUG_RETURN_; + } + ewins = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + for (i = 0; i < num; i++) + { + for (j = 0; j < ewins[i]->border->num_winparts; j++) + { + if (win == ewins[i]->bits[j].win) + { + PagerHideAllHi(); + if (!clickmenu) + { + mode.noewin = 0; + mode.ewin = ewins[i]; + if (ewins[i]->bits[j].state == STATE_CLICKED) + ewins[i]->bits[j].left = 0; + else + { + ewins[i]->bits[j].state = STATE_HILITED; + ChangeEwinWinpart(ewins[i], j); + if ((!ewins[i]->menu) && (!mode.cur_menu_mode)) + mode.context_ewin = ewins[i]; + if (ewins[i]->border->part[j].aclass) + EventAclass(ev, ewins[i]->border->part[j].aclass); + } + } + Efree(ewins); + EDBUG_RETURN_; + } + } + } + if (ewins) + Efree(ewins); + if (win) + { + buttons = (Button **) ListItemType(&num, LIST_TYPE_BUTTON); + for (i = 0; i < num; i++) + { + if ((win == buttons[i]->win) || (win == buttons[i]->event_win)) + { + PagerHideAllHi(); +/* if (b->inside_win) + * XSendEvent(disp, b->inside_win, False, EnterWindowMask, ev); */ + mode.button = buttons[i]; + if (buttons[i]->state == STATE_CLICKED) + buttons[i]->left = 0; + else + { + buttons[i]->state = STATE_HILITED; + DrawButton(buttons[i]); + if (buttons[i]->aclass) + EventAclass(ev, buttons[i]->aclass); + } + Efree(buttons); + EDBUG_RETURN_; + } + } + if (buttons) + Efree(buttons); + } + { + Dialog *d; + int bnum; + + d = FindDialogButton(win, &bnum); + + if (d) + { + PagerHideAllHi(); + DialogActivateButton(win, 0); + } + else + { + DItem *di; + + di = FindDialogItem(win, &d); + if (di) + { + PagerHideAllHi(); + if (di->type == DITEM_AREA) + { + if (di->item.area.event_func) + (di->item.area.event_func) (0, ev); + } + di->hilited = 1; + DialogDrawItems(d, di, 0, 0, 99999, 99999); + } + } + } + EDBUG_RETURN_; +} + +void +HandleMouseOut(XEvent * ev) +{ + Window win; + EWin **ewins; + int i, j, num; + Button **buttons; + Menu *m; + MenuItem *mi; + + EDBUG(5, "HandleMouseOut"); + + if (ttip) + HideToolTip(ttip); + RemoveTimerEvent("TOOLTIP_TIMEOUT"); + if (mode.tooltips) + DoIn("TOOLTIP_TIMEOUT", mode.tiptime, ToolTipTimeout, 0, NULL); + + EdgeHandleLeave(ev); + + win = ev->xcrossing.window; + + mode.context_win = win; + + m = FindMenuItem(win, &mi); + if (m) + { + if ((win == mi->icon_win) && (ev->xcrossing.detail == NotifyAncestor)) + EDBUG_RETURN_; + if ((win == mi->win) && (ev->xcrossing.detail == NotifyInferior)) + EDBUG_RETURN_; + mi->state = STATE_NORMAL; + DrawMenuItem(m, mi, 1); + EDBUG_RETURN_; + } + ewins = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + ICCCM_Cmap(NULL); + for (i = 0; i < num; i++) + { + for (j = 0; j < ewins[i]->border->num_winparts; j++) + { + if (win == ewins[i]->bits[j].win) + { + if (!clickmenu) + { + if (mode.mode == MODE_NONE) + mode.ewin = NULL; + else + mode.noewin = 1; + if (ewins[i]->bits[j].state == STATE_CLICKED) + ewins[i]->bits[j].left = 1; + else + { + ewins[i]->bits[j].state = STATE_NORMAL; + ChangeEwinWinpart(ewins[i], j); + if ((!ewins[i]->menu) && (!mode.cur_menu_mode)) + mode.context_ewin = ewins[i]; + if (ewins[i]->border->part[j].aclass) + EventAclass(ev, ewins[i]->border->part[j].aclass); + } + } + Efree(ewins); + EDBUG_RETURN_; + } + } + } + if (ewins) + Efree(ewins); + if (win) + { + buttons = (Button **) ListItemType(&num, LIST_TYPE_BUTTON); + for (i = 0; i < num; i++) + { + if ((win == buttons[i]->win) || (win == buttons[i]->event_win)) + { +/* if (b->inside_win) + * XSendEvent(disp, b->inside_win, False, LeaveWindowMask, ev); */ + mode.button = NULL; + if (buttons[i]->state == STATE_CLICKED) + buttons[i]->left = 1; + else + { + buttons[i]->state = STATE_NORMAL; + DrawButton(buttons[i]); + if (buttons[i]->aclass) + EventAclass(ev, buttons[i]->aclass); + } + Efree(buttons); + EDBUG_RETURN_; + } + } + if (buttons) + Efree(buttons); + } + { + Dialog *d; + int bnum; + + d = FindDialogButton(win, &bnum); + if (d) + DialogActivateButton(win, 1); + else + { + DItem *di; + + di = FindDialogItem(win, &d); + if (di) + { + if (di->type == DITEM_AREA) + { + if (di->item.area.event_func) + (di->item.area.event_func) (0, ev); + } + di->hilited = 0; + DialogDrawItems(d, di, 0, 0, 99999, 99999); + } + } + } + EDBUG_RETURN_; +} diff --git a/src/file.c b/src/file.c new file mode 100644 index 00000000..604f5025 --- /dev/null +++ b/src/file.c @@ -0,0 +1,941 @@ +#include "E.h" + +char * +FileExtension(char *file) +{ + char *p; + + EDBUG(5, "FileExtension"); + + p = strrchr(file, '.'); + if (p != NULL) + { + EDBUG_RETURN(p + 1); + } + EDBUG_RETURN(""); +} + +void +Etmp(char *s) +{ + static char *home = NULL; + static unsigned long n_calls = 0; + + EDBUG(9, "Etmp"); + if (!n_calls) + n_calls = (unsigned long)time(NULL) + (unsigned long)getpid(); + if (!home) + home = homedir(getuid()); + Esnprintf(s, 1024, "%s/.enlightenment/TMP_%Xl", home, n_calls); + n_calls++; + EDBUG_RETURN_ +} + +void +md(char *s) +{ + EDBUG(9, "md"); + if ((!s) || (!*s)) + EDBUG_RETURN_; + mkdir(s, S_IRWXU); + EDBUG_RETURN_; +} + +int +exists(char *s) +{ + struct stat st; + + EDBUG(9, "exists"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (stat(s, &st) < 0) + EDBUG_RETURN(0); + EDBUG_RETURN(1); +} + +void +mkdirs(char *s) +{ + char ss[FILEPATH_LEN_MAX]; + int i, ii; + + i = 0; + ii = 0; + while (s[i]) + { + ss[ii++] = s[i]; + ss[ii] = 0; + if (s[i] == '/') + { + if (!exists(ss)) + md(ss); + else if (!isdir(ss)) + return; + } + i++; + } +} + +int +isfile(char *s) +{ + struct stat st; + + EDBUG(9, "isfile"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (stat(s, &st) < 0) + EDBUG_RETURN(0); + if (S_ISREG(st.st_mode)) + EDBUG_RETURN(1); + EDBUG_RETURN(0); +} + +int +isdir(char *s) +{ + struct stat st; + + EDBUG(9, "isdir"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (stat(s, &st) < 0) + EDBUG_RETURN(0); + if (S_ISDIR(st.st_mode)) + EDBUG_RETURN(1); + EDBUG_RETURN(0); +} + +char ** +ls(char *dir, int *num) +{ + int i, dirlen; + int done = 0; + DIR *dirp; + char **names; + struct dirent *dp; + + EDBUG(9, "ls"); + if ((!dir) || (!*dir)) + EDBUG_RETURN(0); + dirp = opendir(dir); + if (!dirp) + { + *num = 0; + EDBUG_RETURN(NULL); + } + /* count # of entries in dir (worst case) */ + for (dirlen = 0; (dp = readdir(dirp)) != NULL; dirlen++); + if (!dirlen) + { + closedir(dirp); + *num = dirlen; + EDBUG_RETURN(NULL); + } + names = (char **)Emalloc(dirlen * sizeof(char *)); + + if (!names) + EDBUG_RETURN(NULL); + + rewinddir(dirp); + for (i = 0; i < dirlen;) + { + dp = readdir(dirp); + if (!dp) + break; + if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, ".."))) + { + names[i] = duplicate(dp->d_name); + i++; + } + } + + if (i < dirlen) + dirlen = i; /* dir got shorter... */ + closedir(dirp); + *num = dirlen; + /* do a simple bubble sort here to alphanumberic it */ + while (!done) + { + done = 1; + for (i = 0; i < dirlen - 1; i++) + { + if (strcmp(names[i], names[i + 1]) > 0) + { + char *tmp; + + tmp = names[i]; + names[i] = names[i + 1]; + names[i + 1] = tmp; + done = 0; + } + } + } + EDBUG_RETURN(names); +} + +void +freestrlist(char **l, int num) +{ + EDBUG(9, "freestrlist"); + if (!l) + EDBUG_RETURN_; + while (num--) + if (l[num]) + Efree(l[num]); + Efree(l); + EDBUG_RETURN_; +} + +void +rm(char *s) +{ + EDBUG(9, "rm"); + if ((!s) || (!*s)) + EDBUG_RETURN_; + unlink(s); + EDBUG_RETURN_; +} + +void +mv(char *s, char *ss) +{ + EDBUG(9, "mv"); + if ((!s) || (!ss) || (!*s) || (!*ss)) + EDBUG_RETURN_; + rename(s, ss); + EDBUG_RETURN_; +} + +void +cp(char *s, char *ss) +{ + int i; + FILE *f, *ff; + unsigned char buf[1]; + + EDBUG(9, "cp"); + if ((!s) || (!ss) || (!*s) || (!*ss)) + EDBUG_RETURN_; + if (!exists(s)) + EDBUG_RETURN_; + i = filesize(s); + f = fopen(s, "r"); + if (!f) + EDBUG_RETURN_; + ff = fopen(ss, "w"); + if (!ff) + { + fclose(f); + EDBUG_RETURN_; + } + while (fread(buf, 1, 1, f)) + fwrite(buf, 1, 1, ff); + fclose(f); + fclose(ff); + EDBUG_RETURN_; +} + +time_t +moddate(char *s) +{ + struct stat st; + + EDBUG(9, "moddate"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (!stat(s, &st) < 0) + EDBUG_RETURN(0); + if (st.st_mtime > st.st_ctime) + { + EDBUG_RETURN(st.st_mtime); + } + else + EDBUG_RETURN(st.st_ctime); + EDBUG_RETURN(0); +} + +int +filesize(char *s) +{ + struct stat st; + + EDBUG(9, "filesize"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (stat(s, &st) < 0) + EDBUG_RETURN(0); + EDBUG_RETURN((int)st.st_size); +} + +int +fileinode(char *s) +{ + struct stat st; + + EDBUG(9, "filesize"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (stat(s, &st) < 0) + EDBUG_RETURN(0); + EDBUG_RETURN((int)st.st_ino); +} + +int +filedev(char *s) +{ + struct stat st; + + EDBUG(9, "filesize"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (stat(s, &st) < 0) + EDBUG_RETURN(0); + EDBUG_RETURN((int)st.st_dev); +} + +void +cd(char *s) +{ + EDBUG(9, "cd"); + if ((!s) || (!*s)) + EDBUG_RETURN_; + chdir(s); + EDBUG_RETURN_; +} + +char * +cwd(void) +{ + char *s; + char ss[FILEPATH_LEN_MAX]; + + EDBUG(9, "cwd"); + getcwd(ss, FILEPATH_LEN_MAX); + s = duplicate(ss); + EDBUG_RETURN(s); +} + +int +permissions(char *s) +{ + struct stat st; + + EDBUG(9, "permissions"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (!stat(s, &st) < 0) + EDBUG_RETURN(0); + EDBUG_RETURN(st.st_mode); +} + +int +owner(char *s) +{ + struct stat st; + + EDBUG(9, "owner"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (!stat(s, &st) < 0) + EDBUG_RETURN(0); + EDBUG_RETURN(st.st_uid); +} + +int +group(char *s) +{ + struct stat st; + + EDBUG(9, "group"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + if (!stat(s, &st) < 0) + EDBUG_RETURN(0); + EDBUG_RETURN(st.st_gid); +} + +char * +username(int uid) +{ + static int usr_uid = -1; + static char *usr_s = NULL; + char *s; + struct passwd *pwd; + + EDBUG(9, "username"); + if (usr_uid < 0) + usr_uid = getuid(); + if ((uid == usr_uid) && (usr_s)) + EDBUG_RETURN(duplicate(usr_s)); + pwd = getpwuid(uid); + if (pwd) + { + s = duplicate(pwd->pw_name); + if (uid == usr_uid) + usr_s = duplicate(s); + EDBUG_RETURN(s); + } + EDBUG_RETURN(duplicate("unknown")); +} + +char * +homedir(int uid) +{ + static int usr_uid = -1; + static char *usr_s = NULL; + char *s; + struct passwd *pwd; + + EDBUG(9, "homedir"); + if (usr_uid < 0) + usr_uid = getuid(); + if ((uid == usr_uid) && (usr_s)) + { + EDBUG_RETURN(duplicate(usr_s)); + } + pwd = getpwuid(uid); + if (pwd) + { + s = duplicate(pwd->pw_dir); + if (uid == usr_uid) + usr_s = duplicate(s); + EDBUG_RETURN(s); + } + EDBUG_RETURN(duplicate((getenv("TMPDIR") == NULL) ? "/tmp" + : getenv("TMPDIR"))); +} + +char * +usershell(int uid) +{ + static int usr_uid = -1; + static char *usr_s = NULL; + char *s; + struct passwd *pwd; + + EDBUG(9, "usershell"); + if (usr_uid < 0) + usr_uid = getuid(); + if ((uid == usr_uid) && (usr_s)) + return duplicate(usr_s); + pwd = getpwuid(uid); + if (pwd) + { + if (!pwd->pw_shell) + EDBUG_RETURN(duplicate("/bin/sh")); + if (strlen(pwd->pw_shell) < 1) + EDBUG_RETURN(duplicate("/bin/sh")); + if (!(canexec(pwd->pw_shell))) + EDBUG_RETURN(duplicate("/bin/sh")); + s = duplicate(pwd->pw_shell); + if (uid == usr_uid) + usr_s = duplicate(s); + EDBUG_RETURN(s); + } + EDBUG_RETURN(duplicate("/bin/sh")); +} + +char * +atword(char *s, int num) +{ + int cnt, i; + + EDBUG(9, "atword"); + if (!s) + EDBUG_RETURN(NULL); + cnt = 0; + i = 0; + + while (s[i]) + { + if ((s[i] != ' ') && (s[i] != '\t')) + { + if (i == 0) + cnt++; + else if ((s[i - 1] == ' ') || (s[i - 1] == '\t')) + cnt++; + if (cnt == num) + EDBUG_RETURN(&s[i]); + } + i++; + } + EDBUG_RETURN(NULL); +} + +char * +atchar(char *s, char c) +{ + int i; + + EDBUG(9, "atchar"); + if (!s) + EDBUG_RETURN(NULL); + i = 0; + while (s[i] != 0) + { + if (s[i] == c) + EDBUG_RETURN(&s[i]); + i++; + } + EDBUG_RETURN(NULL); +} + +char * +getword(char *s, int num) +{ + + /* *********FIXME************** + * This function is broken but it isn't in use so I'll fix it later + * (DO NOT USE UNTIL FIXED + */ + int cnt, i; + char *start, *finish, *ss, *w; + char *wd = NULL; + + EDBUG(9, "getword"); + if (!s) + EDBUG_RETURN(NULL); + if (!wd) + EDBUG_RETURN(NULL); + if (num <= 0) + { + *wd = 0; + EDBUG_RETURN(NULL); + } + cnt = 0; + i = 0; + start = NULL; + finish = NULL; + ss = NULL; + w = wd; + + while (s[i]) + { + if ((cnt == num) && ((s[i] == ' ') || (s[i] == '\t'))) + { + finish = &s[i]; + break; + } + if ((s[i] != ' ') && (s[i] != '\t')) + { + if (i == 0) + { + cnt++; + if (cnt == num) + start = &s[i]; + } + else if ((s[i - 1] == ' ') || (s[i - 1] == '\t')) + { + cnt++; + if (cnt == num) + start = &s[i]; + } + } + i++; + } + if (cnt == num) + { + if ((start) && (finish)) + { + for (ss = start; ss < finish; ss++) + *wd++ = *ss; + } + else if (start) + { + for (ss = start; *ss != 0; ss++) + *wd++ = *ss; + } + *wd = 0; + } + EDBUG_RETURN(wd); +} + +void +word(char *s, int num, char *wd) +{ + int cnt, i; + char *start, *finish, *ss, *w; + + EDBUG(9, "word"); + if (!s) + EDBUG_RETURN_; + if (!wd) + EDBUG_RETURN_; + if (num <= 0) + { + *wd = 0; + EDBUG_RETURN_; + } + cnt = 0; + i = 0; + start = NULL; + finish = NULL; + ss = NULL; + w = wd; + + while (s[i]) + { + if ((cnt == num) && ((s[i] == ' ') || (s[i] == '\t'))) + { + finish = &s[i]; + break; + } + if ((s[i] != ' ') && (s[i] != '\t')) + { + if (i == 0) + { + cnt++; + if (cnt == num) + start = &s[i]; + } + else if ((s[i - 1] == ' ') || (s[i - 1] == '\t')) + { + cnt++; + if (cnt == num) + start = &s[i]; + } + } + i++; + } + if (cnt == num) + { + if ((start) && (finish)) + { + for (ss = start; ss < finish; ss++) + *wd++ = *ss; + } + else if (start) + { + for (ss = start; *ss != 0; ss++) + *wd++ = *ss; + } + *wd = 0; + } + EDBUG_RETURN_; +} + +/* gets word number [num] in the string [s] and copies it into [wd] */ +/* wd is NULL terminated. If word [num] does not exist wd = "" */ +/* NB: this function now handles quotes so for a line: */ +/* Hello to "Welcome sir - may I Help" Shub Foo */ +/* Word 1 = Hello */ +/* Word 2 = to */ +/* Word 3 = Welcome sir - may I Help */ +/* Word 4 = Shub */ +/* word 5 = Foo */ +void +fword(char *s, int num, char *wd) +{ + char *cur, *start, *end; + int count, inword, inquote, len; + + EDBUG(9, "word"); + if (!s) + EDBUG_RETURN_; + if (!wd) + EDBUG_RETURN_; + *wd = 0; + if (num <= 0) + EDBUG_RETURN_; + cur = s; + count = 0; + inword = 0; + inquote = 0; + start = NULL; + end = NULL; + while ((*cur) && (count < num)) + { + if (inword) + { + if (inquote) + { + if (*cur == '"') + { + inquote = 0; + inword = 0; + end = cur; + count++; + } + } + else + { + if (isspace(*cur)) + { + end = cur; + inword = 0; + count++; + } + } + } + else + { + if (!isspace(*cur)) + { + if (*cur == '"') + { + inquote = 1; + start = cur + 1; + } + else + start = cur; + inword = 1; + } + } + if (count == num) + break; + cur++; + } + if (!start) + EDBUG_RETURN_; + if (!end) + end = cur; + if (end <= start) + EDBUG_RETURN_; + len = (int)(end - start); + if (len > 4000) + len = 4000; + if (len > 0) + { + strncpy(wd, start, len); + wd[len] = 0; + } + EDBUG_RETURN_; +} + +char * +field(char *s, int field) +{ + char buf[4096]; + + EDBUG(9, "field"); + buf[0] = 0; + fword(s, field + 1, buf); + if (buf[0]) + { + if ((!strcmp(buf, "NULL")) || + (!strcmp(buf, "(null)"))) + EDBUG_RETURN(NULL); + EDBUG_RETURN(duplicate(buf)); + } + EDBUG_RETURN(NULL); +} + +int +fillfield(char *s, int field, char *buf) +{ + EDBUG(9, "fillfield"); + if (!buf) + EDBUG_RETURN(0); + buf[0] = 0; + fword(s, field + 1, buf); + if (buf[0]) + { + if ((!strcmp(buf, "NULL")) || + (!strcmp(buf, "(null)"))) + { + buf[0] = 0; + EDBUG_RETURN(0); + } + EDBUG_RETURN(1); + } + EDBUG_RETURN(0); +} + +int +canread(char *s) +{ + EDBUG(9, "canread"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + + if (!(permissions(s) & (S_IRUSR | S_IRGRP | S_IROTH))) + EDBUG_RETURN(0); + + EDBUG_RETURN(1 + access(s, R_OK)); +} + +int +canwrite(char *s) +{ + EDBUG(9, "canwrite"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + + if (!(permissions(s) & (S_IWUSR | S_IWGRP | S_IWOTH))) + EDBUG_RETURN(0); + + EDBUG_RETURN(1 + access(s, W_OK)); +} + +int +canexec(char *s) +{ + EDBUG(9, "canexec"); + if ((!s) || (!*s)) + EDBUG_RETURN(0); + + if (!(permissions(s) & (S_IXUSR | S_IXGRP | S_IXOTH))) + EDBUG_RETURN(0); + + EDBUG_RETURN(1 + access(s, X_OK)); +} + +char * +fileof(char *s) +{ + char ss[1024]; + int i, p1, p2; + + EDBUG(9, "fileof"); + i = 0; + p1 = -1; + p2 = -1; + for (i = strlen(s) - 1; i >= 0; i--) + { + if ((s[i] == '.') && (p2 < 0) && (p1 < 0)) + p2 = i - 1; + if ((s[i] == '/') && (p1 < 0)) + p1 = i + 1; + } + if (p2 < 0) + p2 = strlen(s) - 1; + if (p1 < 0) + p1 = 0; + if (p2 <= 0) + EDBUG_RETURN(duplicate("")); + for (i = 0; i <= (p2 - p1); i++) + ss[i] = s[p1 + i]; + ss[i] = 0; + EDBUG_RETURN(duplicate(ss)); +} + +char * +fullfileof(char *s) +{ + char ss[1024]; + int i, p1, p2; + + EDBUG(9, "fullfileof"); + i = 0; + p1 = -1; + for (i = strlen(s) - 1; i >= 0; i--) + { + if ((s[i] == '/') && (p1 < 0)) + p1 = i + 1; + } + if (p1 < 0) + p1 = 0; + p2 = strlen(s); + for (i = 0; i < (p2 - p1); i++) + ss[i] = s[p1 + i]; + ss[i] = 0; + EDBUG_RETURN(duplicate(ss)); +} + +char * +pathtoexec(char *file) +{ + char *p, *cp, *ep; + char *s; + int len, exelen; + + EDBUG(9, "pathtoexec"); + if (file[0] == '/') + { + if (canexec(file)) + EDBUG_RETURN(duplicate(file)); + } + p = getenv("PATH"); + if (!p) + EDBUG_RETURN(duplicate(file)); + if (!file) + EDBUG_RETURN(NULL); + cp = p; + exelen = strlen(file); + while ((ep = strchr(cp, ':'))) + { + len = ep - cp; + s = Emalloc(len + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = 0; + s = Erealloc(s, len + 2 + exelen); + strcat(s, "/"); + strcat(s, file); + if (canexec(s)) + EDBUG_RETURN(s); + Efree(s); + } + cp = ep + 1; + } + len = strlen(cp); + s = Emalloc(len + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = 0; + s = Erealloc(s, len + 2 + exelen); + strcat(s, "/"); + strcat(s, file); + if (canexec(s)) + EDBUG_RETURN(s); + Efree(s); + } + EDBUG_RETURN(NULL); +} + +char * +pathtofile(char *file) +{ + char *p, *cp, *ep; + char *s; + int len, exelen; + + EDBUG(9, "pathtofile"); + if (file[0] == '/') + { + if (exists(file)) + EDBUG_RETURN(duplicate(file)); + } + p = getenv("PATH"); + if (!p) + EDBUG_RETURN(duplicate(file)); + if (!file) + EDBUG_RETURN(NULL); + cp = p; + exelen = strlen(file); + while ((ep = strchr(cp, ':'))) + { + len = ep - cp; + s = Emalloc(len + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = 0; + s = Erealloc(s, len + 2 + exelen); + strcat(s, "/"); + strcat(s, file); + if (exists(s)) + EDBUG_RETURN(s); + Efree(s); + } + cp = ep + 1; + } + len = strlen(cp); + s = Emalloc(len + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = 0; + s = Erealloc(s, len + 2 + exelen); + strcat(s, "/"); + strcat(s, file); + if (exists(s)) + EDBUG_RETURN(s); + Efree(s); + } + EDBUG_RETURN(NULL); +} diff --git a/src/finders.c b/src/finders.c new file mode 100644 index 00000000..66b06b7e --- /dev/null +++ b/src/finders.c @@ -0,0 +1,504 @@ +#include "E.h" + +EWin * +FindEwinByBase(Window win) +{ + EWin **ewins; + EWin *ewin; + int i, num; + + EDBUG(6, "FindEwinByBase"); + ewins = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + for (i = 0; i < num; i++) + { + if (win == ewins[i]->win) + { + ewin = ewins[i]; + Efree(ewins); + EDBUG_RETURN(ewin); + } + } + if (ewins) + Efree(ewins); + EDBUG_RETURN(NULL); +} + +EWin * +FindEwinByChildren(Window win) +{ + EWin *ewin; + EWin **ewins; + int i, j, num; + + EDBUG(6, "FindEwinByChildren"); + + ewins = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + for (i = 0; i < num; i++) + { + if ((win == ewins[i]->client.win) || (win == ewins[i]->win_container)) + { + ewin = ewins[i]; + Efree(ewins); + EDBUG_RETURN(ewin); + } + else + { + for (j = 0; j < ewins[i]->border->num_winparts; j++) + if (win == ewins[i]->bits[j].win) + { + ewin = ewins[i]; + Efree(ewins); + EDBUG_RETURN(ewin); + } + } + } + if (ewins) + Efree(ewins); + EDBUG_RETURN(NULL); +} + +EWin * +FindEwinByDecoration(Window win) +{ + EWin *ewin; + EWin **ewins; + int i, j, num; + + EDBUG(6, "FindEwinByDecoration"); + + ewins = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + for (i = 0; i < num; i++) + { + for (j = 0; j < ewins[i]->border->num_winparts; j++) + { + if (win == ewins[i]->bits[j].win) + { + ewin = ewins[i]; + Efree(ewins); + EDBUG_RETURN(ewin); + } + } + } + if (ewins) + Efree(ewins); + EDBUG_RETURN(NULL); +} + +Button * +FindButton(Window win) +{ + Button *b; + Button **buttons; + int i, num; + + EDBUG(6, "FindButton"); + + buttons = (Button **) ListItemType(&num, LIST_TYPE_BUTTON); + for (i = 0; i < num; i++) + { + if ((win == buttons[i]->win) || (win == buttons[i]->inside_win) || + (win == buttons[i]->event_win)) + { + b = buttons[i]; + Efree(buttons); + EDBUG_RETURN(b); + } + } + if (buttons) + Efree(buttons); + EDBUG_RETURN(NULL); +} + +ActionClass * +FindActionClass(Window win) +{ + Button *b; + EWin *ewin; + int i; + + EDBUG(6, "FindActionClass"); + b = FindButton(win); + if (b) + EDBUG_RETURN(b->aclass); + ewin = FindEwinByDecoration(win); + if (ewin) + { + for (i = 0; i < ewin->border->num_winparts; i++) + if (win == ewin->bits[i].win) + EDBUG_RETURN(ewin->border->part[i].aclass); + } + EDBUG_RETURN(NULL); +} + +Menu * +FindMenuItem(Window win, MenuItem ** mi) +{ + Menu *menu; + Menu **menus; + int i, j, num; + + EDBUG(6, "FindMenuItem"); + + menus = (Menu **) ListItemType(&num, LIST_TYPE_MENU); + for (i = 0; i < num; i++) + { + for (j = 0; j < menus[i]->num; j++) + { + if ((win == menus[i]->items[j]->win) || + (win == menus[i]->items[j]->icon_win)) + { + *mi = menus[i]->items[j]; + menu = menus[i]; + Efree(menus); + EDBUG_RETURN(menu); + } + } + } + if (menus) + Efree(menus); + EDBUG_RETURN(NULL); +} + +Menu * +FindMenu(Window win) +{ + Menu *menu; + Menu **menus; + int i, num; + + EDBUG(6, "FindMenu"); + menus = (Menu **) ListItemType(&num, LIST_TYPE_MENU); + for (i = 0; i < num; i++) + { + if (menus[i]->win == win) + { + menu = menus[i]; + Efree(menus); + EDBUG_RETURN(menu); + } + } + if (menus) + Efree(menus); + EDBUG_RETURN(NULL); +} + +EWin * +FindEwinByMenu(Menu * m) +{ + EWin *ewin; + EWin **ewins; + int i, num; + + EDBUG(6, "FindEwinByMenu"); + ewins = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + for (i = 0; i < num; i++) + { + if (ewins[i]->menu == m) + { + ewin = ewins[i]; + Efree(ewins); + EDBUG_RETURN(ewin); + } + } + if (ewins) + Efree(ewins); + EDBUG_RETURN(NULL); +} + +EWin ** +ListWinGroupMembers(Group * g, int *num) +{ + EWin **ewins, **lst = NULL; + int i, j, n; + + if (!g) + { + *num = 0; + EDBUG_RETURN(NULL); + } + + ewins = (EWin **) ListItemType(&n, LIST_TYPE_EWIN); + j = 0; + for (i = 0; i < n; i++) + { + if (ewins[i]->group) + { + if (g->index == ewins[i]->group->index) + { + j++; + lst = Erealloc(lst, sizeof(EWin *) * j); + lst[j - 1] = ewins[i]; + } + } + } + if (ewins) + Efree(ewins); + *num = j; + EDBUG_RETURN(lst); +} + +EWin ** +ListWinGroupMembersForEwin(EWin * ewin, int action, int *num) +{ + + EWin **gwins = NULL; + int daddy_says_no_no = 0; + + if (ewin) + { + if (ewin->group) + { + switch (action) + { + case ACTION_SET_WINDOW_BORDER: + if (!ewin->group->set_border) + daddy_says_no_no = 1; + break; + case ACTION_ICONIFY: + if (!ewin->group->iconify) + daddy_says_no_no = 1; + break; + case ACTION_MOVE: + if (!ewin->group->move) + daddy_says_no_no = 1; + break; + case ACTION_RAISE: + case ACTION_LOWER: + if (!ewin->group->raise) + daddy_says_no_no = 1; + break; + case ACTION_STICK: + if (!ewin->group->stick) + daddy_says_no_no = 1; + break; + case ACTION_SHADE: + if (!ewin->group->shade) + daddy_says_no_no = 1; + break; + case ACTION_KILL: + if (!ewin->group->kill) + daddy_says_no_no = 1; + break; + default: + break; + } + } + else + { + daddy_says_no_no = 1; + } + + if (daddy_says_no_no) + { + gwins = Emalloc(sizeof(EWin *)); + gwins[0] = ewin; + *num = 1; + EDBUG_RETURN(gwins); + } + else + { + EDBUG_RETURN(ListWinGroupMembers(ewin->group, num)); + } + } + else + EDBUG_RETURN(NULL); +} + +EWin ** +ListTransientsFor(Window win, int *num) +{ + EWin **ewins, **lst = NULL; + int i, j, n; + + EDBUG(6, "ListTransientsFor"); + + ewins = (EWin **) ListItemType(&n, LIST_TYPE_EWIN); + j = 0; + for (i = 0; i < n; i++) + { + if (win == ewins[i]->client.transient_for) + { + j++; + lst = Erealloc(lst, sizeof(EWin *) * j); + lst[j - 1] = ewins[i]; + } + } + if (ewins) + Efree(ewins); + *num = j; + EDBUG_RETURN(lst); +} + +EWin ** +ListGroupMembers(Window win, int *num) +{ + EWin **ewins, **lst = NULL; + int i, j, n; + + EDBUG(6, "ListGroupMembers"); + + ewins = (EWin **) ListItemType(&n, LIST_TYPE_EWIN); + j = 0; + for (i = 0; i < n; i++) + { + if (win == ewins[i]->client.group) + { + j++; + lst = Erealloc(lst, sizeof(EWin *) * j); + lst[j - 1] = ewins[i]; + } + } + if (ewins) + Efree(ewins); + *num = j; + EDBUG_RETURN(lst); +} + +EWin * +FindEwinByDialog(Dialog * d) +{ + EWin *ewin; + EWin **ewins; + int i, num; + + EDBUG(6, "FindEwinByMenu"); + ewins = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + for (i = 0; i < num; i++) + { + if (ewins[i]->dialog == d) + { + ewin = ewins[i]; + Efree(ewins); + EDBUG_RETURN(ewin); + } + } + if (ewins) + Efree(ewins); + EDBUG_RETURN(NULL); +} + +Dialog * +FindDialogButton(Window win, int *bnum) +{ + Dialog *d; + Dialog **ds; + int i, j, num; + + EDBUG(6, "FindDialogButton"); + + ds = (Dialog **) ListItemType(&num, LIST_TYPE_DIALOG); + for (i = 0; i < num; i++) + { + for (j = 0; j < ds[i]->num_buttons; j++) + { + if (win == ds[i]->button[j]->win) + { + *bnum = j; + d = ds[i]; + Efree(ds); + EDBUG_RETURN(d); + } + } + } + if (ds) + Efree(ds); + *bnum = 0; + EDBUG_RETURN(NULL); +} + +DItem * +FindDialogItem(Window win, Dialog ** dret) +{ + DItem *di; + Dialog **ds; + int i, num; + + EDBUG(6, "FindDialogButton"); + + ds = (Dialog **) ListItemType(&num, LIST_TYPE_DIALOG); + for (i = 0; i < num; i++) + { + if (ds[i]->item) + { + if ((di = DialogItemFindWindow(ds[i]->item, win))) + { + *dret = ds[i]; + Efree(ds); + EDBUG_RETURN(di); + } + } + } + *dret = NULL; + if (ds) + Efree(ds); + EDBUG_RETURN(NULL); +} + +Dialog * +FindDialog(Window win) +{ + Dialog *d; + Dialog **ds; + int i, num; + + EDBUG(6, "FindDialog"); + ds = (Dialog **) ListItemType(&num, LIST_TYPE_DIALOG); + for (i = 0; i < num; i++) + { + if (ds[i]->win == win) + { + d = ds[i]; + Efree(ds); + EDBUG_RETURN(d); + } + } + if (ds) + Efree(ds); + EDBUG_RETURN(NULL); +} + +EWin * +FindEwinSpawningMenu(Menu * m) +{ + EWin *ewin; + EWin **ewins; + int i, num; + + EDBUG(6, "FindEwinSpawningMenu"); + ewins = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + for (i = 0; i < num; i++) + { + if (ewins[i]->shownmenu == m->win) + { + ewin = ewins[i]; + Efree(ewins); + EDBUG_RETURN(ewin); + } + } + if (ewins) + Efree(ewins); + EDBUG_RETURN(NULL); +} + +Pager * +FindPager(Window win) +{ + Pager *p; + Pager **ps; + int i, num; + + EDBUG(6, "FindDialog"); + ps = (Pager **) ListItemType(&num, LIST_TYPE_PAGER); + for (i = 0; i < num; i++) + { + if ((ps[i]->win == win) || (ps[i]->hi_win == win)) + { + p = ps[i]; + Efree(ps); + EDBUG_RETURN(p); + } + } + if (ps) + Efree(ps); + EDBUG_RETURN(NULL); +} diff --git a/src/focus.c b/src/focus.c new file mode 100644 index 00000000..ad4e1a00 --- /dev/null +++ b/src/focus.c @@ -0,0 +1,558 @@ + +#include "E.h" + +void ReverseTimeout(int val, void *data); +void AutoraiseTimeout(int val, void *data); + +/* Mostly stolen from the temporary 'ToolTipTimeout' */ +void +AutoraiseTimeout(int val, void *data) +{ + EWin *found_ewin; + + if (mode.focusmode == FOCUS_CLICK) + return; + found_ewin = FindItem("", val, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (found_ewin) + RaiseEwin(found_ewin); + data = NULL; +} + +void +ReverseTimeout(int val, void *data) +{ + EWin *ewin; + + ewin = RemoveItem("EWIN", val, LIST_FINDBY_ID, LIST_TYPE_EWIN); + if (ewin) + AddItem(ewin, "EWIN", ewin->client.win, LIST_TYPE_EWIN); + val = 0; + data = NULL; +} + +void +GetNextFocusEwin(void) +{ + EWin **lst0, **lst, *ewin; + int i, num0, num, ax, ay; + + EDBUG(5, "GetNextFocusEwin"); + if (mode.display_warp) + { + WarpFocus(1); + EDBUG_RETURN_; + } + lst0 = (EWin **) ListItemType(&num0, LIST_TYPE_EWIN); + num = 0; + lst = NULL; + GetCurrentArea(&ax, &ay); + if (lst0) + { + for (i = 0; i < num0; i++) + { + ewin = lst0[i]; + if (((ewin->sticky) || (ewin->desktop == desks.current)) && + ((ewin->area_x == ax) && (ewin->area_y == ay)) && + (!ewin->skipfocus) && (!ewin->internal) && (!ewin->shaded) && + (!ewin->iconified) && (ewin->client.mwm_decor_title) && + (ewin->client.mwm_decor_border)) + { + num++; + lst = Erealloc(lst, sizeof(EWin *) * num); + lst[num - 1] = lst0[i]; + } + } + Efree(lst0); + } + ewin = NULL; + if (lst) + { + for (i = 0; i < num; i++) + { + if (mode.focuswin == lst[i]) + { + if (i < num - 1) + ewin = lst[i + 1]; + else + ewin = lst[0]; + Efree(lst); + if (mode.raise_on_next_focus) + RaiseEwin(ewin); + if (mode.warp_on_next_focus) + XWarpPointer(disp, None, ewin->win, 0, 0, 0, 0, + ewin->w / 2, ewin->h / 2); + FocusToEWin(ewin); + EDBUG_RETURN_; + } + } + ewin = lst[0]; + Efree(lst); + if (mode.raise_on_next_focus) + RaiseEwin(ewin); + if (mode.warp_on_next_focus) + XWarpPointer(disp, None, ewin->win, 0, 0, 0, 0, + ewin->w / 2, ewin->h / 2); + FocusToEWin(ewin); + } + EDBUG_RETURN_; +} + +void +GetPrevFocusEwin(void) +{ + EWin **lst0, **lst, *ewin; + int i, num0, num, ax, ay; + + EDBUG(5, "GetPrevFocusEwin"); + if (mode.display_warp) + { + WarpFocus(-1); + EDBUG_RETURN_; + } + RemoveTimerEvent("REVERSE_FOCUS_TIMEOUT"); + DoIn("REVERSE_FOCUS_TIMEOUT", 1.0, ReverseTimeout, 0, NULL); + lst0 = (EWin **) ListItemType(&num0, LIST_TYPE_EWIN); + num = 0; + lst = NULL; + GetCurrentArea(&ax, &ay); + if (lst0) + { + for (i = 0; i < num0; i++) + { + ewin = lst0[i]; + DetermineEwinArea(ewin); + if (((ewin->sticky) || (ewin->desktop == desks.current)) && + ((ewin->area_x == ax) && (ewin->area_y == ay)) && + (!ewin->skipfocus) && (!ewin->internal) && (!ewin->shaded) && + (!ewin->iconified) && (ewin->client.mwm_decor_title) && + (ewin->client.mwm_decor_border)) + { + num++; + lst = Erealloc(lst, sizeof(EWin *) * num); + lst[num - 1] = lst0[i]; + } + } + Efree(lst0); + } + ewin = NULL; + if (lst) + { + for (i = 0; i < num; i++) + { + if (mode.focuswin == lst[i]) + { + if (i == 0) + ewin = lst[num - 1]; + else + ewin = lst[i - 1]; + Efree(lst); + if (mode.raise_on_next_focus) + RaiseEwin(ewin); + if (mode.warp_on_next_focus) + XWarpPointer(disp, None, ewin->win, 0, 0, 0, 0, + ewin->w / 2, ewin->h / 2); + FocusToEWin(ewin); + EDBUG_RETURN_; + } + } + ewin = lst[0]; + Efree(lst); + if (mode.raise_on_next_focus) + RaiseEwin(ewin); + if (mode.warp_on_next_focus) + XWarpPointer(disp, None, ewin->win, 0, 0, 0, 0, + ewin->w / 2, ewin->h / 2); + FocusToEWin(ewin); + } + EDBUG_RETURN_; +} + +void +FixFocus(void) +{ + EWin **lst, *ewin; + int i, num; + + EDBUG(5, "FixFocus"); + num = 0; + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if (lst) + { + for (i = 0; i < num; i++) + { + ewin = lst[i]; + if (mode.focusmode == FOCUS_CLICK) + { + if (!(ewin->active)) + XGrabButton(disp, AnyButton, AnyModifier, ewin->win_container, + False, ButtonPressMask, + GrabModeSync, GrabModeAsync, None, None); + } + else + { + XUngrabButton(disp, AnyButton, AnyModifier, ewin->win_container); + GrabButtonGrabs(ewin); + } + } + Efree(lst); + } +} + +void +FocusToEWin(EWin * ewin) +{ + int ax, ay; + EWin *ewin2 = NULL; + + EDBUG(4, "FocusToEWin"); + + if (mode.slideout) + EDBUG_RETURN_; + ICCCM_Cmap(ewin); + if ((!ewin) && (mode.focusmode != FOCUS_POINTER)) + { + ewin = FindItem("", 0, LIST_FINDBY_NONE, LIST_TYPE_EWIN); + if (mode.focusmode == FOCUS_CLICK) + { + if ((mode.focuswin) && (ewin)) + { + if (!(((ewin->desktop == mode.focuswin->desktop) || + (ewin->sticky)) && + (ewin->area_x == mode.focuswin->area_x) && + (ewin->area_y == mode.focuswin->area_y))) + ewin = NULL; + } + else if (!mode.focuswin) + ewin = NULL; + } + } + if (ewin == mode.focuswin) + { + if (!mode.cur_menu_mode) + mode.context_ewin = ewin; + EDBUG_RETURN_; + } + /* Never focus a window that's not on the current desktop. That's just dumb. -- mej */ + if ((ewin) && (ewin->desktop != desks.current && !(ewin->sticky))) + ewin = NULL; + if ((ewin) && (!ewin->client.need_input)) + { + if (mode.windowdestroy == 1) + { + mode.focuswin = NULL; + mode.realfocuswin = NULL; + mode.windowdestroy = 0; + } + if (!mode.cur_menu_mode) + mode.context_ewin = ewin; + EDBUG_RETURN_; + } + mode.windowdestroy = 0; + if (mode.focuswin) + { + ewin2 = mode.focuswin; + if (mode.autoraise) + RemoveTimerEvent("AUTORAISE_TIMEOUT"); + mode.focuswin->active = 0; + /* losing the focus may cause the titlebar to be resized */ + CalcEwinSizes(mode.focuswin); + DrawEwin(mode.focuswin); + if (mode.focusmode == FOCUS_CLICK) + XGrabButton(disp, AnyButton, AnyModifier, + mode.focuswin->win_container, False, + ButtonPressMask, + GrabModeSync, GrabModeAsync, None, None); + } + if (!ewin) + { + XSetInputFocus(disp, root.win, RevertToPointerRoot, CurrentTime); + mode.focuswin = NULL; + mode.realfocuswin = NULL; + mode.context_ewin = NULL; + EDBUG_RETURN_; + } + else if (!ewin->menu) + mode.realfocuswin = ewin; + if (ewin) + { + if (!mode.cur_menu_mode) + mode.context_ewin = ewin; + mode.focuswin = ewin; + mode.focuswin->active = 1; + } + /* gaining the focus may cause the titlebar to be resized */ + if ((mode.focusmode == FOCUS_CLICK) && (mode.focuswin)) + { + XUngrabButton(disp, AnyButton, AnyModifier, + mode.focuswin->win_container); + GrabButtonGrabs(mode.focuswin); + } + if (mode.focuswin) + { + CalcEwinSizes(mode.focuswin); + DrawEwin(mode.focuswin); + AUDIO_PLAY("SOUND_FOCUS_SET"); + ICCCM_Focus(mode.focuswin); + } + ReZoom(mode.focuswin); + if ((mode.autoraise) && (mode.focuswin) && (!mode.focuswin->menu) && + (mode.focusmode != FOCUS_CLICK)) + DoIn("AUTORAISE_TIMEOUT", mode.autoraisetime, AutoraiseTimeout, + mode.focuswin->client.win, NULL); + if (mode.focusmode == FOCUS_CLICK) + { + if (ewin) + { + if (!ewin->sticky) + { + if ((ewin->desktop != desks.current) && (!ewin->iconified)) + GotoDesktop(ewin->desktop); + } + if ((!ewin->fixedpos) && (!ewin->sticky)) + { + GetCurrentArea(&ax, &ay); + if ((ax != ewin->area_x) || (ay != ewin->area_y)) + { + if ((ewin->x >= root.w) || (ewin->y >= root.h) || + ((ewin->x + ewin->w) < 0) || ((ewin->y + ewin->h) < 0)) + SetCurrentArea(ewin->area_x, ewin->area_y); + } + } + } + } + RemoveTimerEvent("REVERSE_FOCUS_TIMEOUT"); + if (mode.focuswin) + DoIn("REVERSE_FOCUS_TIMEOUT", 0.5, ReverseTimeout, + mode.focuswin->client.win, NULL); + EDBUG_RETURN_; +} + +void +BeginNewDeskFocus(void) +{ + EWin *ewin, **lst; + int i, j, num; + + /* we are about to flip desktops or areas - disable enter and leave events + * temproarily */ + + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if (lst) + { + for (i = 0; i < num; i++) + { + ewin = lst[i]; + XSelectInput(disp, ewin->win, + FocusChangeMask | + SubstructureNotifyMask | + SubstructureRedirectMask | + PropertyChangeMask | + ResizeRedirectMask); + if (ewin->pager) + XSelectInput(disp, ewin->client.win, + PropertyChangeMask | + FocusChangeMask | + ResizeRedirectMask | + StructureNotifyMask | + ColormapChangeMask | + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask); + else if (ewin->dialog) + XSelectInput(disp, ewin->client.win, + PropertyChangeMask | + FocusChangeMask | + ResizeRedirectMask | + StructureNotifyMask | + ColormapChangeMask | + ExposureMask | + KeyPressMask); + else + XSelectInput(disp, ewin->client.win, + PropertyChangeMask | + FocusChangeMask | + ResizeRedirectMask | + StructureNotifyMask | + ColormapChangeMask); + for (j = 0; j < ewin->border->num_winparts; j++) + { + if (ewin->border->part[j].flags & FLAG_TITLE) + XSelectInput(disp, ewin->bits[j].win, + ExposureMask | + ButtonPressMask | + ButtonReleaseMask); + else + XSelectInput(disp, ewin->bits[j].win, + ButtonPressMask | + ButtonReleaseMask); + } + } + Efree(lst); + } + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + XSelectInput(disp, desks.desk[i].win, + PropertyChangeMask | + SubstructureRedirectMask | + ButtonPressMask | + ButtonReleaseMask); +} + +void +NewDeskFocus(void) +{ + EWin *ewin, **lst; + int i, j, num; + + EDBUG(4, "NewDeskFocus"); + + /* we flipped - re-enable ener and leave events */ + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if (lst) + { + for (i = 0; i < num; i++) + { + ewin = lst[i]; + XSelectInput(disp, ewin->win, + FocusChangeMask | + SubstructureNotifyMask | + SubstructureRedirectMask | + EnterWindowMask | + LeaveWindowMask | + PointerMotionMask | + PropertyChangeMask | + ResizeRedirectMask | + ButtonPressMask | + ButtonReleaseMask); + if (ewin->pager) + XSelectInput(disp, ewin->client.win, + PropertyChangeMask | + EnterWindowMask | + LeaveWindowMask | + FocusChangeMask | + ResizeRedirectMask | + StructureNotifyMask | + ColormapChangeMask | + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask); + else if (ewin->dialog) + XSelectInput(disp, ewin->client.win, + PropertyChangeMask | + EnterWindowMask | + LeaveWindowMask | + FocusChangeMask | + ResizeRedirectMask | + StructureNotifyMask | + ColormapChangeMask | + ExposureMask | + KeyPressMask); + else + XSelectInput(disp, ewin->client.win, + PropertyChangeMask | + EnterWindowMask | + LeaveWindowMask | + FocusChangeMask | + ResizeRedirectMask | + StructureNotifyMask | + ColormapChangeMask); + for (j = 0; j < ewin->border->num_winparts; j++) + { + if (ewin->border->part[j].flags & FLAG_TITLE) + XSelectInput(disp, ewin->bits[j].win, + ExposureMask | + KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | + LeaveWindowMask | + PointerMotionMask); + else + XSelectInput(disp, ewin->bits[j].win, + KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | + LeaveWindowMask | + PointerMotionMask); + } + } + Efree(lst); + } + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + XSelectInput(disp, desks.desk[i].win, + SubstructureNotifyMask | + ButtonPressMask | + ButtonReleaseMask | + EnterWindowMask | + LeaveWindowMask | + ButtonMotionMask | + PropertyChangeMask | + SubstructureRedirectMask | + KeyPressMask | + KeyReleaseMask | + PointerMotionMask); + if ((mode.focusmode == FOCUS_POINTER) || + (mode.focusmode == FOCUS_SLOPPY)) + { + ewin = GetEwinPointerInClient(); + if (ewin) + ICCCM_Focus(ewin); + else + ICCCM_Focus(NULL); + } + else + { + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if (lst) + { + int ax, ay; + + GetCurrentArea(&ax, &ay); + for (i = 0; i < num; i++) + { + ewin = lst[i]; + if ((ewin->sticky) || + ((((ewin->area_x == ax) && (ewin->area_y == ay)) || + (ewin->fixedpos)) && (ewin->desktop == desks.current))) + { + ICCCM_Focus(ewin); + Efree(lst); + EDBUG_RETURN_; + } + } + Efree(lst); + } + } + EDBUG_RETURN_; +} + +void +FocusToNone(void) +{ + + EDBUG(4, "FocusToNone"); + + if ((mode.focuswin) && (mode.focuswin->floating)) + EDBUG_RETURN_; + ICCCM_Cmap(NULL); + if (mode.focuswin) + { + if (mode.autoraise) + RemoveTimerEvent("AUTORAISE_TIMEOUT"); + mode.focuswin->active = 0; + /* losing the focus may cause the titlebar to be resized */ + CalcEwinSizes(mode.focuswin); + DrawEwin(mode.focuswin); + if (mode.focusmode == FOCUS_CLICK) + XGrabButton(disp, AnyButton, AnyModifier, + mode.focuswin->win_container, False, + ButtonPressMask, + GrabModeSync, GrabModeAsync, None, None); + } + XSetInputFocus(disp, root.win, RevertToPointerRoot, CurrentTime); + mode.focuswin = NULL; + mode.realfocuswin = NULL; + EDBUG_RETURN_; +} diff --git a/src/fx.c b/src/fx.c new file mode 100644 index 00000000..d7dec2a7 --- /dev/null +++ b/src/fx.c @@ -0,0 +1,940 @@ +#include "E.h" + +#ifndef M_PI_2 +#define M_PI_2 (3.141592654 / 2) +#endif + +typedef struct _fxhandler + { + char *name; + void (*init_func) (char *name); + void (*desk_func) (void); + void (*quit_func) (void); + void (*pause_func) (void); + char in_use; + char paused; + } +FXHandler; + +void FX_Ripple_Init(char *name); +void FX_Ripple_Desk(void); +void FX_Ripple_Quit(void); +void FX_Ripple_Pause(void); +void FX_Raindrops_Init(char *name); +void FX_Raindrops_Desk(void); +void FX_Raindrops_Quit(void); +void FX_Raindrops_Pause(void); +void FX_Waves_Init(char *name); +void FX_Waves_Desk(void); +void FX_Waves_Quit(void); +void FX_Waves_Pause(void); +void FX_ImageSpinner_Init(char *name); +void FX_ImageSpinner_Desk(void); +void FX_ImageSpinner_Quit(void); +void FX_ImageSpinner_Pause(void); + +static int num_fx_handlers = 4; +static FXHandler fx_handlers[] = +{ + {"ripples", + FX_Ripple_Init, FX_Ripple_Desk, FX_Ripple_Quit, FX_Ripple_Pause, + 0, 0}, + {"raindrops", + FX_Raindrops_Init, FX_Raindrops_Desk, FX_Raindrops_Quit, FX_Raindrops_Pause, + 0, 0}, + {"waves", + FX_Waves_Init, FX_Waves_Desk, FX_Waves_Quit, FX_Waves_Pause, + 0, 0}, + {"imagespinner", + FX_ImageSpinner_Init, FX_ImageSpinner_Desk, FX_ImageSpinner_Quit, FX_ImageSpinner_Pause, + 0, 0} +}; + +/****************************** Effect handlers *****************************/ + +void +FX_Start(char *name) +{ + int i; + + for (i = 0; i < num_fx_handlers; i++) + { + if (!strcmp(fx_handlers[i].name, name)) + { + if ((fx_handlers[i].in_use) && (fx_handlers[i].quit_func)) + { + (*(fx_handlers[i].quit_func)) (); + fx_handlers[i].in_use = 0; + } + else + { + if (fx_handlers[i].init_func) + (*(fx_handlers[i].init_func)) (name); + fx_handlers[i].in_use = 1; + } + } + } +} + +void +FX_DeskChange(void) +{ + int i; + + for (i = 0; i < num_fx_handlers; i++) + { + if (fx_handlers[i].in_use) + { + if (fx_handlers[i].desk_func) + (*(fx_handlers[i].desk_func)) (); + } + } +} + +void +FX_Pause(void) +{ + int i; + + for (i = 0; i < num_fx_handlers; i++) + { + if (fx_handlers[i].in_use) + { + if (fx_handlers[i].paused) + { + if (fx_handlers[i].pause_func) + (*(fx_handlers[i].pause_func)) (); + fx_handlers[i].paused = 1; + } + else + { + if (fx_handlers[i].pause_func) + (*(fx_handlers[i].pause_func)) (); + fx_handlers[i].paused = 0; + } + } + } +} + +char ** +FX_Active(int *num) +{ + int i; + char **list = NULL; + + *num = 0; + for (i = 0; i < num_fx_handlers; i++) + { + if (fx_handlers[i].in_use) + { + (*num)++; + list = Erealloc(list, sizeof(char *) * (*num)); + + list[(*num) - 1] = duplicate(fx_handlers[i].name); + } + } + return list; +} + +int +FX_IsOn(char *effect) +{ + int i; + + for (i = 0; i < num_fx_handlers; i++) + { + if (!strcmp(fx_handlers[i].name, effect)) + { + if (fx_handlers[i].in_use) + return 1; + return 0; + } + } + return 0; + +} + +void +FX_Deactivate(char *effect) +{ + int i; + + for (i = 0; i < num_fx_handlers; i++) + { + if (!strcmp(fx_handlers[i].name, effect)) + { + if (fx_handlers[i].in_use) + { + fx_handlers[i].in_use = 0; + (*(fx_handlers[i].quit_func)) (); + } + } + } + return; +} + +void +FX_Activate(char *effect) +{ + int i; + + for (i = 0; i < num_fx_handlers; i++) + { + if (!strcmp(fx_handlers[i].name, effect)) + { + if (!fx_handlers[i].in_use) + { + fx_handlers[i].in_use = 1; + (*(fx_handlers[i].init_func)) (effect); + } + } + } + return; +} + +/****************************** RIPPLES *************************************/ + +#define fx_ripple_waterh 64 +static Pixmap fx_ripple_above = 0; +static Window fx_ripple_win = 0; +static int fx_ripple_count = 0; + +void FX_ripple_timeout(int val, void *data); + +void +FX_ripple_timeout(int val, void *data) +{ + static char before = 0; + static double incv = 0, inch = 0; + static GC gc1 = 0, gc = 0; + int y; + + if (!fx_ripple_above) + { + XGCValues gcv; + + fx_ripple_win = desks.desk[desks.current].win; + if ((desks.current == 0) && (ird)) + fx_ripple_above = ECreatePixmap(disp, fx_ripple_win, root.w, + fx_ripple_waterh * 2, ird->x.depth); + else + fx_ripple_above = ECreatePixmap(disp, fx_ripple_win, root.w, + fx_ripple_waterh * 2, id->x.depth); + if (gc) + XFreeGC(disp, gc); + if (gc1) + XFreeGC(disp, gc1); + gcv.subwindow_mode = IncludeInferiors; + gc = XCreateGC(disp, fx_ripple_win, GCSubwindowMode, &gcv); + gc1 = XCreateGC(disp, fx_ripple_win, 0L, &gcv); + if (!before) + DIALOG_OK("Starting up Ripples FX...", + "\n" + "You have just started the Ripples Effect.\n" + "\n" + "If you look closely on your desktop background, and if it\n" + "doesn't have a solid colour (ie has a background texture or\n" + "image), you will see a pool of water at the bottom of your\n" + "screen that reflects everythig above it and \"ripples\".\n" + "\n" + "To disable this effect just select this option again to toggle\n" + "it off.\n"); + before = 1; + } + if (fx_ripple_count == 0) + XCopyArea(disp, fx_ripple_win, fx_ripple_above, gc, + 0, root.h - (fx_ripple_waterh * 3), + root.w, fx_ripple_waterh * 2, + 0, 0); + fx_ripple_count++; + if (fx_ripple_count > 32) + fx_ripple_count = 0; + incv += 0.40; + if (incv > (M_PI_2 * 4)) + { + incv = 0; + } + inch += 0.32; + if (inch > (M_PI_2 * 4)) + { + inch = 0; + } + for (y = 0; y < fx_ripple_waterh; y++) + { + double aa, a, p; + int yoff, off, yy; + + p = (((double)(fx_ripple_waterh - y)) / ((double)fx_ripple_waterh)); + a = p * p * 48 + incv; + yoff = y + (int)(sin(a) * 7) + 1; + yy = (fx_ripple_waterh * 2) - yoff; + aa = p * p * 64 + inch; + off = (int)(sin(aa) * 10 * (1 - p)); + XCopyArea(disp, fx_ripple_above, fx_ripple_win, gc1, + 0, yy, root.w, 1, off, root.h - fx_ripple_waterh + y); + } + DoIn("FX_RIPPLE_TIMEOUT", 0.066, FX_ripple_timeout, 0, NULL); + return; + val = 0; + data = NULL; +} + +void +FX_Ripple_Init(char *name) +{ + fx_ripple_count = 0; + DoIn("FX_RIPPLE_TIMEOUT", 0.066, FX_ripple_timeout, 0, NULL); + name = NULL; +} + +void +FX_Ripple_Desk(void) +{ + EFreePixmap(disp, fx_ripple_above); + fx_ripple_count = 0; + fx_ripple_above = 0; +} + +void +FX_Ripple_Quit(void) +{ + RemoveTimerEvent("FX_RIPPLE_TIMEOUT"); + XClearArea(disp, fx_ripple_win, + 0, root.h - fx_ripple_waterh, + root.w, fx_ripple_waterh, False); +} + +void +FX_Ripple_Pause(void) +{ + static char paused = 0; + + if (!paused) + { + FX_Ripple_Quit(); + paused = 1; + } + else + { + FX_Ripple_Init(NULL); + paused = 0; + } +} + +/****************************************************************************/ + +/****************************** RAIN DROPS **********************************/ + +#define fx_raindrop_size 96 +#define fx_raindrop_size2 (fx_raindrop_size / 2) +#define fx_raindrop_duration 32 +#define fx_frequency 4 +#define fx_amplitude 48 +static Window fx_raindrops_win = 0; +static int fx_raindrops_number = 4; +static PixImg *fx_raindrops_draw = NULL; + +void FX_raindrops_timeout(int val, void *data); + +typedef struct _drop_context + { + int x, y; + int count; + PixImg *buf; + } +DropContext; + +static DropContext fx_raindrops[4]; + +void +FX_raindrops_timeout(int val, void *data) +{ + static char before = 0; + static GC gc1 = 0, gc = 0; + int i, x, y, xx, yy; + int percent_done; + static char first = 1; + static char sintab[256]; + static unsigned char disttab[fx_raindrop_size][fx_raindrop_size]; + + if (!fx_raindrops_win) + { + XGCValues gcv; + + if (!id->x.shm) + { + DIALOG_OK("Unable to display raindrops", + "\n" + "Enlightenment is unable to display raindrops on this\n" + "display because Shared memory is not available on this\n" + "X-Server.\n" + "\n" + "This may be due to Enlightenment being a remote client\n" + "running over the network, a MIT-SHM incapable X-server,\n" + "having run out of SHM ID's on the system or Shared\n" + "Memory support being turned off in Imlib\n" + "\n" + "You may correct this by either running `imlib_config'\n" + "or copying the system imrc (/usr/etc/imrc) to ~/.imrc\n" + "and editing it, enabling shared memory.\n" + "\n"); + return; + } + if (!id->x.shmp) + { + DIALOG_OK("Unable to display raindrops", + "\n" + "Enlightenment is unable to display raindrops on this\n" + "display because shared pixmaps are not available on this\n" + "X-Server.\n" + "\n" + "This may be due to either the X-Server not implimenting\n" + "shared pixmaps, or shared pixmaps being disabled in\n" + "Imlib's configuration.\n" + "\n" + "You may correct this by either running `imlib_config'\n" + "or copying the system imrc (/usr/etc/imrc) to ~/.imrc\n" + "and editing it, enabling shared pixmaps.\n" + "\n"); + return; + } + if (!before) + DIALOG_OK("Starting up Raindrops FX...", + "\n" + "You have just started the Raindrops Effect.\n" + "\n" + "If you look closely on your desktop background, and if it\n" + "doesn't have a solid colour (ie has a background texture or\n" + "image), you will see \"raindrops\" hit the background and\n" + "make little splashes. This Effect can be VERY CPU intensive.\n" + "\n" + "To disable this effect just select this option again to toggle\n" + "it off.\n"); + before = 1; + if (first) + { + int j; + + first = 0; + for (i = 0; i < 256; i++) + sintab[i] = (char)(sin(((double)i) * M_PI_2 * 4 / 256) * fx_amplitude); + for (j = 0; j < fx_raindrop_size; j++) + { + for (i = 0; i < fx_raindrop_size; i++) + { + xx = i - fx_raindrop_size2; + yy = j - fx_raindrop_size2; + disttab[i][j] = (unsigned char)sqrt((double)((xx * xx) + (yy * yy))); + } + } + } + fx_raindrops_win = desks.desk[desks.current].win; + if (gc) + XFreeGC(disp, gc); + if (gc1) + XFreeGC(disp, gc1); + gcv.subwindow_mode = IncludeInferiors; + gc = XCreateGC(disp, fx_raindrops_win, GCSubwindowMode, &gcv); + gc1 = XCreateGC(disp, fx_raindrops_win, 0L, &gcv); + fx_raindrops_draw = ECreatePixImg(fx_raindrops_win, + fx_raindrop_size, + fx_raindrop_size); + if (!fx_raindrops_draw) + return; + for (i = 0; i < fx_raindrops_number; i++) + { + fx_raindrops[i].buf = ECreatePixImg(fx_raindrops_win, + fx_raindrop_size, + fx_raindrop_size); + if (fx_raindrops[i].buf) + XShmGetImage(disp, fx_raindrops_win, fx_raindrops[i].buf->xim, + fx_raindrops[i].x, fx_raindrops[i].y, 0xffffffff); + if (!fx_raindrops[i].buf) + return; + } + } + for (i = 0; i < fx_raindrops_number; i++) + { + fx_raindrops[i].count++; + if (fx_raindrops[i].count == fx_raindrop_duration) + { + int j, count = 0; + char intersect = 1; + + XClearArea(disp, fx_raindrops_win, + fx_raindrops[i].x, fx_raindrops[i].y, + fx_raindrop_size, fx_raindrop_size, False); + fx_raindrops[i].count = 0; + while (intersect) + { + count++; + if (count > 10240) + break; + intersect = 0; + for (j = 0; j < fx_raindrops_number; j++) + { + fx_raindrops[i].x = rand() % (root.w - fx_raindrop_size); + fx_raindrops[i].y = rand() % (root.h - fx_raindrop_size); + if (fx_raindrops[i].x < 0) + fx_raindrops[i].x = 0; + else if (fx_raindrops[i].x > (root.w - fx_raindrop_size)) + fx_raindrops[i].x = root.w - fx_raindrop_size; + if (fx_raindrops[i].y < 0) + fx_raindrops[i].y = 0; + else if (fx_raindrops[i].y > (root.h - fx_raindrop_size)) + fx_raindrops[i].y = root.h - fx_raindrop_size; + if (i != j) + { + if (((fx_raindrops[i].x >= fx_raindrops[j].x) && + (fx_raindrops[i].x < fx_raindrops[j].x + fx_raindrop_size) && + (fx_raindrops[i].y >= fx_raindrops[j].y) && + (fx_raindrops[i].y < fx_raindrops[j].y + fx_raindrop_size)) || + ((fx_raindrops[i].x + fx_raindrop_size >= fx_raindrops[j].x) && + (fx_raindrops[i].x + fx_raindrop_size < fx_raindrops[j].x + fx_raindrop_size) && + (fx_raindrops[i].y >= fx_raindrops[j].y) && + (fx_raindrops[i].y < fx_raindrops[j].y + fx_raindrop_size)) || + ((fx_raindrops[i].x >= fx_raindrops[j].x) && + (fx_raindrops[i].x < fx_raindrops[j].x + fx_raindrop_size) && + (fx_raindrops[i].y + fx_raindrop_size >= fx_raindrops[j].y) && + (fx_raindrops[i].y + fx_raindrop_size < fx_raindrops[j].y + fx_raindrop_size)) || + ((fx_raindrops[i].x + fx_raindrop_size >= fx_raindrops[j].x) && + (fx_raindrops[i].x + fx_raindrop_size < fx_raindrops[j].x + fx_raindrop_size) && + (fx_raindrops[i].y + fx_raindrop_size >= fx_raindrops[j].y) && + (fx_raindrops[i].y + fx_raindrop_size < fx_raindrops[j].y + fx_raindrop_size))) + intersect = 1; + } + } + } + XShmGetImage(disp, fx_raindrops_win, fx_raindrops[i].buf->xim, + fx_raindrops[i].x, fx_raindrops[i].y, 0xffffffff); + } + percent_done = 1 + ((fx_raindrops[i].count << 8) / fx_raindrop_duration); + for (y = 0; y < fx_raindrop_size; y++) + { + for (x = 0; x < fx_raindrop_size; x++) + { + int dist; + + dist = disttab[x][y]; + if (dist > fx_raindrop_size2) + XPutPixel(fx_raindrops_draw->xim, x, y, + XGetPixel(fx_raindrops[i].buf->xim, x, y)); + else + { + int percent; + + percent = 1 + ((dist << 8) / fx_raindrop_size2); + if (percent > percent_done) + XPutPixel(fx_raindrops_draw->xim, x, y, + XGetPixel(fx_raindrops[i].buf->xim, x, y)); + else + { + int varx, vary; + int phase, divisor, multiplier; + + phase = ((percent - percent_done) * fx_frequency) & 0xff; + xx = x - fx_raindrop_size2; + yy = y - fx_raindrop_size2; + divisor = 1 + (dist << 8); + multiplier = (int)sintab[phase] * (256 - percent_done); + varx = ((-xx) * multiplier) / divisor; + vary = ((-yy) * multiplier) / divisor; + xx = x + varx; + yy = y + vary; + if (xx < 0) + xx = 0; + else if (xx >= fx_raindrop_size) + xx = fx_raindrop_size - 1; + if (yy < 0) + yy = 0; + else if (yy >= fx_raindrop_size) + yy = fx_raindrop_size - 1; + XPutPixel(fx_raindrops_draw->xim, x, y, + XGetPixel(fx_raindrops[i].buf->xim, xx, yy)); + } + } + } + } + XShmPutImage(disp, fx_raindrops_win, gc1, fx_raindrops_draw->xim, + 0, 0, fx_raindrops[i].x, fx_raindrops[i].y, + fx_raindrop_size, fx_raindrop_size, False); + XSync(disp, False); + } + DoIn("FX_RAINDROPS_TIMEOUT", (0.066 /*/ (float)fx_raindrops_number */ ), FX_raindrops_timeout, 0, NULL); + return; + val = 0; + data = NULL; +} + +void +FX_Raindrops_Init(char *name) +{ + int i; + + fx_raindrops_win = 0; + for (i = 0; i < fx_raindrops_number; i++) + { + fx_raindrops[i].count = rand() % fx_raindrop_duration; + fx_raindrops[i].x = rand() % (root.w - fx_raindrop_size); + fx_raindrops[i].y = rand() % (root.h - fx_raindrop_size); + } + DoIn("FX_RAINDROPS_TIMEOUT", 0.066, FX_raindrops_timeout, 0, NULL); + name = NULL; +} + +void +FX_Raindrops_Desk(void) +{ + fx_raindrops_win = 0; +} + +void +FX_Raindrops_Quit(void) +{ + int i; + + RemoveTimerEvent("FX_RAINDROPS_TIMEOUT"); + for (i = 0; i < fx_raindrops_number; i++) + { + XClearArea(disp, fx_raindrops_win, + fx_raindrops[i].x, fx_raindrops[i].y, + fx_raindrop_size, fx_raindrop_size, False); + if (fx_raindrops[i].buf) + EDestroyPixImg(fx_raindrops[i].buf); + fx_raindrops[i].buf = NULL; + } + if (fx_raindrops_draw) + EDestroyPixImg(fx_raindrops_draw); + fx_raindrops_draw = NULL; + fx_raindrops_win = 0; +} + +void +FX_Raindrops_Pause(void) +{ + static char paused = 0; + + if (!paused) + { + FX_Raindrops_Quit(); + paused = 1; + } + else + { + FX_Raindrops_Init(NULL); + paused = 0; + } +} + +/****************************************************************************/ + +/****************************** WAVES ***************************************/ +/* by tsade :) */ +/****************************************************************************/ + +#define FX_WAVE_WATERH 64 +#define FX_WAVE_WATERW 64 +#define FX_WAVE_DEPTH 10 +#define FX_WAVE_GRABH (FX_WAVE_WATERH + FX_WAVE_DEPTH) +#define FX_WAVE_CROSSPERIOD 0.42 +static Pixmap fx_wave_above = 0; +static Window fx_wave_win = 0; +static int fx_wave_count = 0; + +void FX_Wave_timeout(int val, void *data); + +void +FX_Wave_timeout(int val, void *data) +{ + /* Variables */ + static char before = 0; + static double incv = 0, inch = 0; + static double incx = 0; + double incx2; + static GC gc1 = 0, gc = 0; + int y; + + /* Check to see if we need to create stuff */ + if (!fx_wave_above) + { + XGCValues gcv; + + fx_wave_win = desks.desk[desks.current].win; + if ((desks.current == 0) && (ird)) + fx_wave_above = XCreatePixmap(disp, fx_wave_win, root.w, + FX_WAVE_WATERH * 2, ird->x.depth); + else + fx_wave_above = XCreatePixmap(disp, fx_wave_win, root.w, + FX_WAVE_WATERH * 2, id->x.depth); + if (gc) + XFreeGC(disp, gc); + if (gc1) + XFreeGC(disp, gc1); + gcv.subwindow_mode = IncludeInferiors; + gc = XCreateGC(disp, fx_wave_win, GCSubwindowMode, &gcv); + gc1 = XCreateGC(disp, fx_wave_win, 0L, &gcv); + if (!before) + DIALOG_OK("Starting up Waves FX...", + "\n" + "You have just started the Waves Effect.\n" + "\n" + "If you look closely on your desktop background, and if it\n" + "doesn't have a solid colour (ie has a background texture or\n" + "image), you will see a pool of water at the bottom of your\n" + "screen that reflects everythig above it and \"waves\".\n" + "\n" + "To disable this effect just select this option again to toggle\n" + "it off.\n"); + before = 1; + } + + /* On the zero, grab the desktop again. */ + if (fx_wave_count == 0) + { + XCopyArea(disp, fx_wave_win, fx_wave_above, gc, + 0, root.h - (FX_WAVE_WATERH * 3), + root.w, FX_WAVE_WATERH * 2, + 0, 0); + } + + /* Increment and roll the counter */ + fx_wave_count++; + if (fx_wave_count > 32) + fx_wave_count = 0; + + /* Increment and roll some other variables */ + incv += 0.40; + if (incv > (M_PI_2 * 4)) + incv = 0; + + inch += 0.32; + if (inch > (M_PI_2 * 4)) + inch = 0; + + incx += 0.32; + if (incx > (M_PI_2 * 4)) + incx = 0; + + /* Copy the area to correct bugs */ + if (fx_wave_count == 0) + { + XCopyArea(disp, fx_wave_above, fx_wave_win, gc1, + 0, root.h - FX_WAVE_GRABH, + root.w, FX_WAVE_DEPTH * 2, + 0, root.h - FX_WAVE_GRABH); + } + + /* Go through the bottom couple (FX_WAVE_WATERH) lines of the window */ + for (y = 0; y < FX_WAVE_WATERH; y++) + { + /* Variables */ + double aa, a, p; + int yoff, off, yy; + int x; + + /* Figure out the side-to-side movement */ + p = (((double)(FX_WAVE_WATERH - y)) / ((double)FX_WAVE_WATERH)); + a = p * p * 48 + incv; + yoff = y + (int)(sin(a) * 7) + 1; + yy = (FX_WAVE_WATERH * 2) - yoff; + aa = p * p * FX_WAVE_WATERH + inch; + off = (int)(sin(aa) * 10 * (1 - p)); + + /* Set up the next part */ + incx2 = incx; + + /* Go through the width of the screen, in block sizes */ + for (x = 0; x < root.w; x += FX_WAVE_WATERW) + { + /* Variables */ + int sx; + + /* Add something to incx2 and roll it */ + incx2 += FX_WAVE_CROSSPERIOD; + + if (incx2 > (M_PI_2 * 4)) + incx2 = 0; + + /* Figure it out */ + sx = (int)(sin(incx2) * FX_WAVE_DEPTH); + + /* Display this block */ + XCopyArea(disp, fx_wave_above, fx_wave_win, gc1, + x, yy, /* x, y */ + FX_WAVE_WATERW, 1, /* w, h */ + off + x, root.h - FX_WAVE_WATERH + y + sx /* dx, dy */ + ); + } + } + + /* Make noise */ + DoIn("FX_WAVE_TIMEOUT", 0.066, FX_Wave_timeout, 0, NULL); + + /* Return */ + return; + + /* Never gets here */ + val = 0; + data = NULL; +} + +void +FX_Waves_Init(char *name) +{ + fx_wave_count = 0; + DoIn("FX_WAVE_TIMEOUT", 0.066, FX_Wave_timeout, 0, NULL); + name = NULL; +} + +void +FX_Waves_Desk(void) +{ + XFreePixmap(disp, fx_wave_above); + fx_wave_count = 0; + fx_wave_above = 0; +} + +void +FX_Waves_Quit(void) +{ + RemoveTimerEvent("FX_WAVE_TIMEOUT"); + XClearArea(disp, fx_wave_win, + 0, root.h - FX_WAVE_WATERH, + root.w, FX_WAVE_WATERH, False); +} + +void +FX_Waves_Pause(void) +{ + static char paused = 0; + + if (!paused) + { + FX_Waves_Quit(); + paused = 1; + } + else + { + FX_Waves_Init(NULL); + paused = 0; + } +} + +/****************************************************************************/ + +/****************************** IMAGESPINNER ********************************/ + +static Window fx_imagespinner_win = 0; +static int fx_imagespinner_count = 3; +static ImlibData *fx_imagespinner_imd = NULL; +static char *fx_imagespinner_params = NULL; +static +void FX_imagespinner_timeout(int val, void *data); + +void +FX_imagespinner_timeout(int val, void *data) +{ + static char before = 0; + char *string = NULL; + + if (!fx_imagespinner_win) + { + fx_imagespinner_win = desks.desk[desks.current].win; + if ((desks.current == 0) && (ird)) + fx_imagespinner_imd = ird; + else + fx_imagespinner_imd = id; + if (!before) + DIALOG_OK("Starting up imagespinners FX...", + "\n" + "You have just started the imagespinners Effect.\n" + "\n" + "To disable this effect just select this option again to toggle\n" + "it off.\n"); + before = 1; + } +/* do stuff here */ + string = getword(fx_imagespinner_params, fx_imagespinner_count); + if (!string) + { + fx_imagespinner_count = 3; + string = getword(fx_imagespinner_params, fx_imagespinner_count); + } + fx_imagespinner_count++; + if (string) + { + ImlibImage *im; + + im = ELoadImageImlibData(fx_imagespinner_imd, string); + if (im) + { + int x, y, w, h; + + w = im->rgb_width; + h = im->rgb_height; + sscanf(fx_imagespinner_params, "%*s %i %i ", &x, &y); + x = ((root.w * x) >> 10) - ((w * x) >> 10); + y = ((root.h * y) >> 10) - ((h * y) >> 10); + Imlib_paste_image(fx_imagespinner_imd, im, + fx_imagespinner_win, + x, y, w, h); + Imlib_destroy_image(fx_imagespinner_imd, im); + } + Efree(string); + } + + DoIn("FX_IMAGESPINNER_TIMEOUT", 0.066, FX_imagespinner_timeout, 0, NULL); + return; + val = 0; + data = NULL; +} + +void +FX_ImageSpinner_Init(char *name) +{ + fx_imagespinner_count = 3; + DoIn("FX_IMAGESPINNER_TIMEOUT", 0.066, FX_imagespinner_timeout, 0, NULL); + fx_imagespinner_params = duplicate(name); +} + +void +FX_ImageSpinner_Desk(void) +{ + fx_imagespinner_win = desks.desk[desks.current].win; + if ((desks.current == 0) && (ird)) + fx_imagespinner_imd = ird; + else + fx_imagespinner_imd = id; +} + +void +FX_ImageSpinner_Quit(void) +{ + RemoveTimerEvent("FX_IMAGESPINNER_TIMEOUT"); + XClearArea(disp, fx_imagespinner_win, + 0, 0, + root.w, root.h, + False); + if (fx_imagespinner_params) + Efree(fx_imagespinner_params); + fx_imagespinner_params = NULL; + fx_imagespinner_win = 0; +} + +void +FX_ImageSpinner_Pause(void) +{ + static char paused = 0; + + if (!paused) + { + FX_ImageSpinner_Quit(); + paused = 1; + } + else + { + FX_ImageSpinner_Init(NULL); + paused = 0; + } +} +/****************************************************************************/ diff --git a/src/globals.c b/src/globals.c new file mode 100644 index 00000000..e046e782 --- /dev/null +++ b/src/globals.c @@ -0,0 +1,45 @@ + +#include "E.h" + +pid_t master_pid; +int master_screen; +int display_screens; +int single_screen_mode; +Display *disp; +ImlibData *id; +ImlibData *ird; +FnlibData *fd; +List *lists; +int event_base_shape; +Window comms_win; +Root root; +int (*(ActionFunctions[ACTION_NUMBEROF])) (void *); +EMode mode; +Desktops desks; +Window grab_window; +Window init_win1 = 0; +Window init_win2 = 0; +Window init_win_ext = 0; +Window bpress_win = 0; +int deskorder[ENLIGHTENMENT_CONF_NUM_DESKTOPS]; +int sound_fd = -1; +char themepath[FILEPATH_LEN_MAX]; +char themename[FILEPATH_LEN_MAX]; +char *command; +char mustdel; +char queue_up; +char just_flipped = 0; +Menu *all_task_menu = NULL; +Menu *task_menu[ENLIGHTENMENT_CONF_NUM_DESKTOPS]; +Menu *desk_menu = NULL; +char no_overwrite = 0; +Window external_pager_window = 0; +char clickmenu = 0; +Window last_bpress = 0; +int child_count = 0; +pid_t *e_children = NULL; +int numlock_mask = 0; +int scrollock_mask = 0; +int mask_mod_combos[8]; +Group *current_group; +Group *pager_group = NULL; diff --git a/src/gnome.c b/src/gnome.c new file mode 100644 index 00000000..0d61eb7e --- /dev/null +++ b/src/gnome.c @@ -0,0 +1,758 @@ + +#include "E.h" + +/*********************************************************/ +/* Properties set on the root window (or desktop window) */ +/* */ +/* Even though the rest of E is GPL consider this file */ +/* Public Domain - use it howvere you see fit to make */ +/* your WM GNOME compiant */ +/*********************************************************/ + +/* WIN_WM_NAME STRING - contains a string identifier for the WM's name */ +#define XA_WIN_WM_NAME "_WIN_WM_NAME" + +/* WIN_WM_NAME VERSION - contains a string identifier for the WM's version */ +#define XA_WIN_WM_VERSION "_WIN_WM_VERSION" + +/* WIN_AREA CARD32[2] contains the current desktop area X,Y */ +#define XA_WIN_AREA "_WIN_AREA" + +/* WIN_AREA CARD32[2] contains the current desktop area size WxH */ +#define XA_WIN_AREA_COUNT "_WIN_AREA_COUNT" + +/* array of atoms - atom being one of the following atoms */ +#define XA_WIN_PROTOCOLS "_WIN_PROTOCOLS" + +/* array of iocn in various sizes */ +/* Type: array of CARD32 */ +/* first item is icon count (n) */ +/* second item is icon record length (in CARD32s) */ +/* this is followed by (n) icon records as follows */ +/* pixmap (XID) */ +/* mask (XID) */ +/* width (CARD32) */ +/* height (CARD32) */ +/* depth (of pixmap, mask is assumed to be of depth 1) (CARD32) */ +/* drawable (screen root drawable of pixmap) (XID) */ +/* ... additional fields can be added at the end of this list */ +#define XA_WIN_ICONS "_WIN_ICONS" + +/* WIN_WORKSPACE CARD32 contains the current desktop number */ +#define XA_WIN_WORKSPACE "_WIN_WORKSPACE" +/* WIN_WORKSPACE_COUNT CARD32 contains the number of desktops */ +#define XA_WIN_WORKSPACE_COUNT "_WIN_WORKSPACE_COUNT" + +/* WIN_WORKSPACE_NAMES StringList (Text Property) of workspace names */ +/* unused by enlightenment */ +#define XA_WIN_WORKSPACE_NAMES "_WIN_WORKSPACE_NAMES" + +/* ********** Don't use this.. iffy at best. *********** */ +/* The available work area for client windows. The WM can set this and the WM */ +/* and/or clients may change it at any time. If it is changed the WM and/or */ +/* clients should honor the changes. If this property does not exist a client */ +/* or WM can create it. */ +/* + * CARD32 min_x; + * CARD32 min_y; + * CARD32 max_x; + * CARD32 max_y; + */ +#define XA_WIN_WORKAREA "_WIN_WORKAREA" +/* array of 4 CARD32's */ + +/* This is a list of window id's the WM is currently managing - primarily */ +/* for being able to have external "tasklist" apps */ +#define XA_WIN_CLIENT_LIST "_WIN_CLIENT_LIST" +/* array of N XID's */ + +/*********************************************************/ +/* Properties on client windows */ +/*********************************************************/ + +/* The layer the window exists in */ +/* 0 = Desktop */ +/* 1 = Below */ +/* 2 = Normal (default app layer) */ +/* 4 = OnTop */ +/* 6 = Dock (always on top - for panel) */ +/* The app sets this alone, not the WM. If this property changes the WM */ +/* should comply and change the appearance/behavior of the Client window */ +/* if this hint does nto exist the WM Will create it ont he Client window */ +#define WIN_LAYER_DESKTOP 0 +#define WIN_LAYER_BELOW 2 +#define WIN_LAYER_NORMAL 4 +#define WIN_LAYER_ONTOP 6 +#define WIN_LAYER_DOCK 8 +#define WIN_LAYER_ABOVE_DOCK 10 +#define WIN_LAYER_MENU 12 +#define XA_WIN_LAYER "_WIN_LAYER" +/* WIN_LAYER = CARD32 */ + +/* flags for the window's state. The WM will change these as needed when */ +/* state changes. If the property contains info on client map, E will modify */ +/* the windows state accordingly. if the Hint does not exist the WM will */ +/* create it on the client window. 0 for the bit means off, 1 means on. */ +/* unused (default) values are 0 */ + +/* removed Minimized - no explanation of what it really means - ambiguity */ +/* should not be here if not clear */ +#define WIN_STATE_STICKY (1<<0) /* everyone knows sticky */ +#define WIN_STATE_RESERVED_BIT1 (1<<1) /* removed minimize here */ +#define WIN_STATE_MAXIMIZED_VERT (1<<2) /* window in maximized V state */ +#define WIN_STATE_MAXIMIZED_HORIZ (1<<3) /* window in maximized H state */ +#define WIN_STATE_HIDDEN (1<<4) /* not on taskbar but window visible */ +#define WIN_STATE_SHADED (1<<5) /* shaded (NeXT style) */ +#define WIN_STATE_HID_WORKSPACE (1<<6) /* not on current desktop */ +#define WIN_STATE_HID_TRANSIENT (1<<7) /* owner of transient is hidden */ +#define WIN_STATE_FIXED_POSITION (1<<8) /* window is fixed in position even */ +#define WIN_STATE_ARRANGE_IGNORE (1<<9) /* ignore for auto arranging */ + /* when scrolling about large */ + /* virtual desktops ala fvwm */ +#define XA_WIN_STATE "_WIN_STATE" +/* WIN_STATE = CARD32 */ + +/* Preferences for behavior for app */ +/* ONLY the client sets this */ +#define WIN_HINTS_SKIP_FOCUS (1<<0) /* "alt-tab" skips this win */ +#define WIN_HINTS_SKIP_WINLIST (1<<1) /* not in win list */ +#define WIN_HINTS_SKIP_TASKBAR (1<<2) /* not on taskbar */ +#define WIN_HINTS_GROUP_TRANSIENT (1<<3) /* ??????? */ +#define WIN_HINTS_FOCUS_ON_CLICK (1<<4) /* app only accepts focus when clicked */ +#define WIN_HINTS_DO_NOT_COVER (1<<5) /* attempt to not cover this window */ +#define XA_WIN_HINTS "_WIN_HINTS" +/* WIN_HINTS = CARD32 */ + +/* Application state - also "color reactiveness" - the app can keep changing */ +/* this property when it changes its state and the WM or monitoring program */ +/* will pick this up and display somehting accordingly. ONLY the client sets */ +/* this. */ +#define WIN_APP_STATE_NONE 0 +#define WIN_APP_STATE_ACTIVE1 1 +#define WIN_APP_STATE_ACTIVE2 2 +#define WIN_APP_STATE_ERROR1 3 +#define WIN_APP_STATE_ERROR2 4 +#define WIN_APP_STATE_FATAL_ERROR1 5 +#define WIN_APP_STATE_FATAL_ERROR2 6 +#define WIN_APP_STATE_IDLE1 7 +#define WIN_APP_STATE_IDLE2 8 +#define WIN_APP_STATE_WAITING1 9 +#define WIN_APP_STATE_WAITING2 10 +#define WIN_APP_STATE_WORKING1 11 +#define WIN_APP_STATE_WORKING2 12 +#define WIN_APP_STATE_NEED_USER_INPUT1 13 +#define WIN_APP_STATE_NEED_USER_INPUT2 14 +#define WIN_APP_STATE_STRUGGLING1 15 +#define WIN_APP_STATE_STRUGGLING2 16 +#define WIN_APP_STATE_DISK_TRAFFIC1 17 +#define WIN_APP_STATE_DISK_TRAFFIC2 18 +#define WIN_APP_STATE_NETWORK_TRAFFIC1 19 +#define WIN_APP_STATE_NETWORK_TRAFFIC2 20 +#define WIN_APP_STATE_OVERLOADED1 21 +#define WIN_APP_STATE_OVERLOADED2 22 +#define WIN_APP_STATE_PERCENT000_1 23 +#define WIN_APP_STATE_PERCENT000_2 24 +#define WIN_APP_STATE_PERCENT010_1 25 +#define WIN_APP_STATE_PERCENT010_2 26 +#define WIN_APP_STATE_PERCENT020_1 27 +#define WIN_APP_STATE_PERCENT020_2 28 +#define WIN_APP_STATE_PERCENT030_1 29 +#define WIN_APP_STATE_PERCENT030_2 30 +#define WIN_APP_STATE_PERCENT040_1 31 +#define WIN_APP_STATE_PERCENT040_2 32 +#define WIN_APP_STATE_PERCENT050_1 33 +#define WIN_APP_STATE_PERCENT050_2 34 +#define WIN_APP_STATE_PERCENT060_1 35 +#define WIN_APP_STATE_PERCENT060_2 36 +#define WIN_APP_STATE_PERCENT070_1 37 +#define WIN_APP_STATE_PERCENT070_2 38 +#define WIN_APP_STATE_PERCENT080_1 39 +#define WIN_APP_STATE_PERCENT080_2 40 +#define WIN_APP_STATE_PERCENT090_1 41 +#define WIN_APP_STATE_PERCENT090_2 42 +#define WIN_APP_STATE_PERCENT100_1 43 +#define WIN_APP_STATE_PERCENT100_2 44 +#define XA_WIN_APP_STATE "_WIN_APP_STATE" +/* WIN_APP_STATE = CARD32 */ + +/* Expanded space occupied - this is the area on screen the app's window */ +/* will occupy when "expanded" - ie if you have a button on an app that */ +/* "hides" it by reducing its size, this is the geometry of the expanded */ +/* window - so the window manager can allow for this when doign auto */ +/* positioing of client windows assuming the app can at any point use this */ +/* this area and thus try and keep it clear. ONLY the client sets this */ +/* + * CARD32 x; + * CARD32 y; + * CARD32 width; + * CARD32 height; + */ +#define XA_WIN_EXPANDED_SIZE "_WIN_EXPANDED_SIZE" +/* array of 4 CARD32's */ + +/* CARD32 that contians the desktop number the application is on If the */ +/* application's state is "sticky" it is irrelevant. Only the WM should */ +/* change this. */ +#define XA_WIN_WORKSPACE "_WIN_WORKSPACE" + +/* This atom is a 32-bit integer that is either 0 or 1 (currently). */ +/* 0 denotes everything is as per usual but 1 denotes that ALL configure */ +/* requests by the client on the client window with this property are */ +/* not just a simple "moving" of the window, but the result of a user */ +/* moving the window BUT the client handling that interaction by moving */ +/* its own window. The window manager should respond accordingly by assuming */ +/* any configure requests for this window whilst this atom is "active" in */ +/* the "1" state are a client move and should handle flipping desktops if */ +/* the window is being dragged "off screem" or across desktop boundaries */ +/* etc. This atom is ONLY ever set by the client */ +#define XA_WIN_CLIENT_MOVING "_WIN_CLIENT_MOVING" +/* WIN_CLIENT_MOVING = CARD32 */ + +/* Designed for checking if the WIN_ supporting WM is still there */ +/* and kicking about - basically check this property - check the window */ +/* ID it points to - then check that window Id has this property too */ +/* if that is the case the WIN_ supporting WM is there and alive and the */ +/* list of WIN_PROTOCOLS is valid */ +#define XA_WIN_SUPPORTING_WM_CHECK "_WIN_SUPPORTING_WM_CHECK" +/* CARD32 */ + +/*********************************************************/ +/* How an app can modify things after mapping */ +/*********************************************************/ + +/* For a client to change layer or state it should send a client message */ +/* to the root window as follows: */ +/* + * Display *disp; + * Window root, client_window; + * XClientMessageEvent xev; + * CARD32 new_layer; + * + * xev.type = ClientMessage; + * xev.window = client_window; + * xev.message_type = XInternAtom(disp, XA_WIN_LAYER, False); + * xev.format = 32; + * xev.data.l[0] = new_layer; + * xev.data.l[1] = CurrentTime; + * XSendEvent(disp, root, False, SubstructureNotifyMask, (XEvent *) &xev); + */ +/* + * Display *disp; + * Window root, client_window; + * XClientMessageEvent xev; + * CARD32 mask_of_members_to_change, new_members; + * + * xev.type = ClientMessage; + * xev.window = client_window; + * xev.message_type = XInternAtom(disp, XA_WIN_STATE, False); + * xev.format = 32; + * xev.data.l[0] = mask_of_members_to_change; + * xev.data.l[1] = new_members; + * xev.data.l[2] = CurrentTimep; + * XSendEvent(disp, root, False, SubstructureNotifyMask, (XEvent *) &xev); + */ +/* + * Display *disp; + * Window root, client_window; + * XClientMessageEvent xev; + * CARD32 new_desktop_number; + * + * xev.type = ClientMessage; + * xev.window = client_window; + * xev.message_type = XInternAtom(disp, XA_WIN_WORKSPACE, False); + * xev.format = 32; + * xev.data.l[0] = new_desktop_number; + * xev.data.l[2] = CurrentTimep; + * XSendEvent(disp, root, False, SubstructureNotifyMask, (XEvent *) &xev); + */ + +void +GNOME_GetHintIcons(EWin * ewin, Atom atom_change) +{ + static Atom atom_get = 0; + CARD32 *retval; + int size; + unsigned int i; + Pixmap pmap; + Pixmap mask; + + EDBUG(6, "GNOME_GetHintIcons"); + if (ewin->internal) + EDBUG_RETURN_; + if (!atom_get) + atom_get = XInternAtom(disp, XA_WIN_ICONS, False); + if ((atom_change) && (atom_change != atom_get)) + EDBUG_RETURN_; + retval = AtomGet(ewin->client.win, atom_get, XA_PIXMAP, &size); + if (retval) + { + for (i = 0; i < (size / (sizeof(CARD32))); i += 2) + { + pmap = retval[i]; + mask = retval[i + 1]; + } + Efree(retval); + } + EDBUG_RETURN_; +} + +void +GNOME_GetHintLayer(EWin * ewin, Atom atom_change) +{ + static Atom atom_get = 0; + CARD32 *retval; + int size; + + EDBUG(6, "GNOME_GetHintLayer"); + if (ewin->internal) + EDBUG_RETURN_; + if (!atom_get) + atom_get = XInternAtom(disp, XA_WIN_LAYER, False); + if ((atom_change) && (atom_change != atom_get)) + EDBUG_RETURN_; + retval = AtomGet(ewin->client.win, atom_get, XA_CARDINAL, &size); + if (retval) + { + ewin->layer = *retval; + Efree(retval); + } + EDBUG_RETURN_; +} + +void +GNOME_GetHintState(EWin * ewin, Atom atom_change) +{ + static Atom atom_get = 0; + CARD32 *retval; + int size; + + EDBUG(6, "GNOME_GetHintState"); + if (ewin->internal) + EDBUG_RETURN_; + if (!atom_get) + atom_get = XInternAtom(disp, XA_WIN_STATE, False); + if ((atom_change) && (atom_change != atom_get)) + EDBUG_RETURN_; + retval = AtomGet(ewin->client.win, atom_get, XA_CARDINAL, &size); + if (retval) + { + if (*retval & WIN_STATE_SHADED) + ewin->shaded = 1; + if (*retval & WIN_STATE_STICKY) + ewin->sticky = 1; + if (*retval & WIN_STATE_FIXED_POSITION) + ewin->fixedpos = 1; + if (*retval & WIN_STATE_ARRANGE_IGNORE) + ewin->ignorearrange = 1; + Efree(retval); + } + EDBUG_RETURN_; +} + +void +GNOME_GetHintAppState(EWin * ewin, Atom atom_change) +{ + static Atom atom_get = 0; + unsigned char *retval; + int size; + + /* have nothing interesting to do with an app state (lamp) right now */ + EDBUG(6, "GNOME_GetHintAppState"); + if (ewin->internal) + EDBUG_RETURN_; + if (!atom_get) + atom_get = XInternAtom(disp, XA_WIN_APP_STATE, False); + if ((atom_change) && (atom_change != atom_get)) + EDBUG_RETURN_; + retval = AtomGet(ewin->client.win, atom_get, XA_CARDINAL, &size); + if (retval) + { + Efree(retval); + } + EDBUG_RETURN_; +} + +void +GNOME_GetHintDesktop(EWin * ewin, Atom atom_change) +{ + static Atom atom_get = 0; + unsigned char *retval; + int size; + int *desk; + + EDBUG(6, "GNOME_GetHintDesktop"); + if (ewin->internal) + EDBUG_RETURN_; + if (!atom_get) + atom_get = XInternAtom(disp, XA_WIN_WORKSPACE, False); + if ((atom_change) && (atom_change != atom_get)) + EDBUG_RETURN_; + retval = AtomGet(ewin->client.win, atom_get, XA_CARDINAL, &size); + if (retval) + { + desk = (int *)retval; + ewin->desktop = *desk; + Efree(retval); + } + EDBUG_RETURN_; +} + +void +GNOME_GetHint(EWin * ewin, Atom atom_change) +{ + static Atom atom_get = 0; + int *retval; + int size; + + /* E doesn't really care about these hints right now */ + EDBUG(6, "GNOME_GetHint"); + if (ewin->internal) + EDBUG_RETURN_; + if (!atom_get) + atom_get = XInternAtom(disp, XA_WIN_HINTS, False); + if ((atom_change) && (atom_change != atom_get)) + EDBUG_RETURN_; + retval = AtomGet(ewin->client.win, atom_get, XA_CARDINAL, &size); + if (retval) + { + if (*retval & WIN_HINTS_SKIP_TASKBAR) + ewin->skiptask = 1; + if (*retval & WIN_HINTS_SKIP_FOCUS) + ewin->skipfocus = 1; + if (*retval & WIN_HINTS_SKIP_WINLIST) + ewin->skipwinlist = 1; + if (*retval & WIN_HINTS_FOCUS_ON_CLICK) + ewin->focusclick = 1; + if (*retval & WIN_HINTS_DO_NOT_COVER) + ewin->never_use_area = 1; + Efree(retval); + } + EDBUG_RETURN_; +} + +void +GNOME_SetHint(EWin * ewin) +{ + static Atom atom_set = 0; + int val; + + EDBUG(6, "GNOME_SetHint"); + if ((ewin->menu) || (ewin->pager)) + EDBUG_RETURN_; + if (!atom_set) + atom_set = XInternAtom(disp, XA_WIN_STATE, False); + val = 0; + if (ewin->sticky) + val |= WIN_STATE_STICKY; + if (ewin->shaded) + val |= WIN_STATE_SHADED; + if (ewin->fixedpos) + val |= WIN_STATE_FIXED_POSITION; + XChangeProperty(disp, ewin->client.win, atom_set, XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)&val, 1); + EDBUG_RETURN_; +} + +void +GNOME_SetEwinArea(EWin * ewin) +{ + static Atom atom_set = 0; + CARD32 val[2]; + + EDBUG(6, "GNOME_SetEwinArea"); + if ((ewin->menu) || (ewin->pager)) + EDBUG_RETURN_; + if (!atom_set) + atom_set = XInternAtom(disp, XA_WIN_AREA, False); + val[0] = (CARD32) ewin->area_x; + val[1] = (CARD32) ewin->area_y; + XChangeProperty(disp, ewin->client.win, atom_set, XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)val, 2); + EDBUG_RETURN_; +} + +void +GNOME_SetEwinDesk(EWin * ewin) +{ + static Atom atom_set = 0; + int val; + + EDBUG(6, "GNOME_SetEwinDesk"); + if ((ewin->menu) || (ewin->pager)) + EDBUG_RETURN_; + if (!atom_set) + atom_set = XInternAtom(disp, XA_WIN_WORKSPACE, False); + val = ewin->desktop; + XChangeProperty(disp, ewin->client.win, atom_set, XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)&val, 1); + EDBUG_RETURN_; +} + +void +GNOME_GetExpandedSize(EWin * ewin, Atom atom_change) +{ + static Atom atom_get = 0; + CARD32 *retval; + int size; + + EDBUG(6, "GNOME_GetExpandedSize"); + if (ewin->internal) + EDBUG_RETURN_; + if (!atom_get) + atom_get = XInternAtom(disp, XA_WIN_EXPANDED_SIZE, False); + if ((atom_change) && (atom_change != atom_get)) + EDBUG_RETURN_; + retval = AtomGet(ewin->client.win, atom_get, XA_CARDINAL, &size); + if (retval) + { + ewin->expanded_x = retval[0]; + ewin->expanded_y = retval[1]; + ewin->expanded_width = retval[2]; + ewin->expanded_height = retval[3]; + Efree(retval); + } + EDBUG_RETURN_; +} + +void +GNOME_SetUsedHints(void) +{ + static Atom atom_set = 0; + Atom list[10]; + + EDBUG(6, "GNOME_SetUsedHints"); + if (!atom_set) + atom_set = XInternAtom(disp, XA_WIN_PROTOCOLS, False); + list[0] = XInternAtom(disp, XA_WIN_LAYER, False); + list[1] = XInternAtom(disp, XA_WIN_STATE, False); + list[2] = XInternAtom(disp, XA_WIN_HINTS, False); + list[3] = XInternAtom(disp, XA_WIN_APP_STATE, False); + list[4] = XInternAtom(disp, XA_WIN_EXPANDED_SIZE, False); + list[5] = XInternAtom(disp, XA_WIN_ICONS, False); + list[6] = XInternAtom(disp, XA_WIN_WORKSPACE, False); + list[7] = XInternAtom(disp, XA_WIN_WORKSPACE_COUNT, False); + list[8] = XInternAtom(disp, XA_WIN_WORKSPACE_NAMES, False); + list[9] = XInternAtom(disp, XA_WIN_CLIENT_LIST, False); + XChangeProperty(disp, root.win, atom_set, XA_ATOM, 32, PropModeReplace, + (unsigned char *)list, 10); + EDBUG_RETURN_; +} + +void +GNOME_SetCurrentArea(void) +{ + static Atom atom_set = 0; + CARD32 val[2]; + int ax, ay; + + EDBUG(6, "GNOME_SetCurrentArea"); + if (!atom_set) + atom_set = XInternAtom(disp, XA_WIN_AREA, False); + GetCurrentArea(&ax, &ay); + val[0] = ax; + val[1] = ay; + XChangeProperty(disp, root.win, atom_set, XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)val, 2); + EDBUG_RETURN_; +} + +void +GNOME_SetCurrentDesk(void) +{ + static Atom atom_set = 0; + CARD32 val; + + EDBUG(6, "GNOME_SetCurrentDesk"); + if (!atom_set) + atom_set = XInternAtom(disp, XA_WIN_WORKSPACE, False); + val = (CARD32) desks.current; + XChangeProperty(disp, root.win, atom_set, XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)&val, 1); + GNOME_SetCurrentArea(); + EDBUG_RETURN_; +} + +void +GNOME_SetWMCheck(void) +{ + static Atom atom_set = 0; + CARD32 val; + Window win; + + EDBUG(6, "GNOME_SetWMCheck"); + + if (!atom_set) + atom_set = XInternAtom(disp, XA_WIN_SUPPORTING_WM_CHECK, False); + win = ECreateWindow(root.win, -200, -200, 5, 5, 0); + val = win; + XChangeProperty(disp, root.win, atom_set, XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)&val, 1); + XChangeProperty(disp, win, atom_set, XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)&val, 1); + EDBUG_RETURN_; +} + +void +GNOME_SetDeskCount(void) +{ + static Atom atom_set = 0; + CARD32 val; + + EDBUG(6, "GNOME_SetDeskCount"); + if (!atom_set) + atom_set = XInternAtom(disp, XA_WIN_WORKSPACE_COUNT, False); + val = mode.numdesktops; + XChangeProperty(disp, root.win, atom_set, XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)&val, 1); + EDBUG_RETURN_; +} + +void +GNOME_SetAreaCount(void) +{ + static Atom atom_set = 0; + int ax, ay; + CARD32 val[2]; + + EDBUG(6, "GNOME_SetAreaCount"); + if (!atom_set) + atom_set = XInternAtom(disp, XA_WIN_AREA_COUNT, False); + GetAreaSize(&ax, &ay); + val[0] = ax; + val[1] = ay; + XChangeProperty(disp, root.win, atom_set, XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)val, 2); + EDBUG_RETURN_; +} + +void +GNOME_SetDeskNames(void) +{ + static Atom atom_set = 0; + XTextProperty text; + char s[1024], *names[ENLIGHTENMENT_CONF_NUM_DESKTOPS]; + int i; + + EDBUG(6, "GNOME_SetDeskNames"); + if (!atom_set) + atom_set = XInternAtom(disp, XA_WIN_WORKSPACE_NAMES, False); + for (i = 0; i < mode.numdesktops; i++) + { + Esnprintf(s, sizeof(s), "%i", i); + names[i] = duplicate(s); + } + if (XStringListToTextProperty(names, mode.numdesktops, &text)) + { + XSetTextProperty(disp, root.win, &text, atom_set); + XFree(text.value); + } + for (i = 0; i < mode.numdesktops; i++) + if (names[i]) + Efree(names[i]); + EDBUG_RETURN_; +} + +void +GNOME_SetClientList(void) +{ + static Atom atom_set = 0; + Window *wl; + int j, i, num; + EWin **lst; + + EDBUG(6, "GNOME_SetClientList"); + if (!atom_set) + atom_set = XInternAtom(disp, XA_WIN_CLIENT_LIST, False); + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + wl = NULL; + j = 0; + if (lst) + { + wl = Emalloc(sizeof(Window) * num); + for (i = 0; i < num; i++) + { + if ((!lst[i]->menu) && (!lst[i]->pager)) + wl[j++] = lst[i]->client.win; + } + } + XChangeProperty(disp, root.win, atom_set, XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)wl, j); + if (wl) + Efree(wl); + if (lst) + Efree(lst); + EDBUG_RETURN_; +} + +void +GNOME_SetWMNameVer(void) +{ + static Atom atom_set = 0, atom_set2 = 0; + const char *wm_name = "Enlightenment"; + const char *wm_version = "0.16.0"; + + EDBUG(6, "GNOME_SetWMNameVer"); + if (!atom_set) + atom_set = XInternAtom(disp, XA_WIN_WM_NAME, False); + XChangeProperty(disp, root.win, atom_set, XA_STRING, 8, PropModeReplace, + (unsigned char *)wm_name, strlen(wm_name)); + if (!atom_set2) + atom_set2 = XInternAtom(disp, XA_WIN_WM_VERSION, False); + XChangeProperty(disp, root.win, atom_set2, XA_STRING, 8, PropModeReplace, + (unsigned char *)wm_version, strlen(wm_version)); + EDBUG_RETURN_; +} + +void +GNOME_DelHints(EWin * ewin) +{ + static Atom atom_get[7] = + {0, 0, 0, 0, 0, 0, 0}; + + EDBUG(6, "GNOME_DelHints"); + if (!atom_get[0]) + { + atom_get[0] = XInternAtom(disp, XA_WIN_WORKSPACE, False); + atom_get[1] = XInternAtom(disp, XA_WIN_LAYER, False); + atom_get[2] = XInternAtom(disp, XA_WIN_STATE, False); + atom_get[3] = XInternAtom(disp, XA_WIN_HINTS, False); + atom_get[4] = XInternAtom(disp, XA_WIN_APP_STATE, False); + atom_get[5] = XInternAtom(disp, XA_WIN_WORKSPACE, False); + atom_get[6] = XInternAtom(disp, XA_WIN_AREA, False); + } + XDeleteProperty(disp, ewin->client.win, atom_get[0]); + XDeleteProperty(disp, ewin->client.win, atom_get[1]); + XDeleteProperty(disp, ewin->client.win, atom_get[2]); + XDeleteProperty(disp, ewin->client.win, atom_get[3]); + XDeleteProperty(disp, ewin->client.win, atom_get[4]); + XDeleteProperty(disp, ewin->client.win, atom_get[5]); + XDeleteProperty(disp, ewin->client.win, atom_get[6]); + EDBUG_RETURN_; +} + +void +GNOME_GetHints(EWin * ewin, Atom atom_change) +{ + EDBUG(6, "GNOME_GetHints"); + GNOME_GetHintDesktop(ewin, atom_change); + GNOME_GetHintIcons(ewin, atom_change); + GNOME_GetHintLayer(ewin, atom_change); + GNOME_GetHintState(ewin, atom_change); + GNOME_GetHintAppState(ewin, atom_change); + GNOME_GetHint(ewin, atom_change); + GNOME_GetExpandedSize(ewin, atom_change); + EDBUG_RETURN_; +} + +void +GNOME_SetHints(void) +{ + EDBUG(6, "GNOME_SetHints"); + GNOME_SetWMNameVer(); + GNOME_SetUsedHints(); + GNOME_SetDeskCount(); + GNOME_SetDeskNames(); + GNOME_SetAreaCount(); + GNOME_SetWMCheck(); + EDBUG_RETURN_; +} diff --git a/src/grabs.c b/src/grabs.c new file mode 100644 index 00000000..d5ec66d9 --- /dev/null +++ b/src/grabs.c @@ -0,0 +1,94 @@ + +#include "E.h" + +void +GrabActionKey(Action * a) +{ + int mod; + + EDBUG(4, "GrabActionKey"); + if (!a->key) + EDBUG_RETURN_; + mod = a->modifiers; + if (a->anymodifier) + { + mod = AnyModifier; + XGrabKey(disp, a->key, mod, root.win, False, GrabModeAsync, GrabModeAsync); + } + else + { + int i; + + /* grab the key even if locks are on or not */ + for (i = 0; i < 8; i++) + XGrabKey(disp, a->key, mod | mask_mod_combos[i], root.win, False, GrabModeAsync, GrabModeAsync); + } + EDBUG_RETURN_; +} + +void +UnGrabActionKey(Action * a) +{ + int mod; + + EDBUG(4, "UnGrabActionKey"); + if (!a->key) + EDBUG_RETURN_; + mod = a->modifiers; + if (a->anymodifier) + { + mod = AnyModifier; + XUngrabKey(disp, a->key, mod, root.win); + } + else + { + int i; + + /* ungrab the key even if locks are on or not */ + for (i = 0; i < 8; i++) + XUngrabKey(disp, a->key, mod | mask_mod_combos[i], root.win); + } + EDBUG_RETURN_; +} + +void +GrabTheButtons(Window win) +{ + EDBUG(4, "GrabTheButtons"); + if (mode.click_focus_grabbed) + EDBUG_RETURN_; + XGrabPointer(disp, win, True, ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + grab_window = win; + mode.click_focus_grabbed = 1; + EDBUG_RETURN_; +} + +int +GrabThePointer(Window win) +{ + int ret; + + EDBUG(4, "GrabThePointer"); + if (mode.click_focus_grabbed) + EDBUG_RETURN(1); + ret = XGrabPointer(disp, win, True, ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | ButtonMotionMask | + EnterWindowMask | LeaveWindowMask, GrabModeAsync, + GrabModeAsync, None, None, CurrentTime); + grab_window = win; + mode.click_focus_grabbed = 1; + EDBUG_RETURN(ret); +} + +void +UnGrabTheButtons() +{ + EDBUG(4, "UnGrabTheButtons"); + if (!mode.click_focus_grabbed) + EDBUG_RETURN_; + XUngrabPointer(disp, CurrentTime); + mode.click_focus_grabbed = 0; + grab_window = 0; + EDBUG_RETURN_; +} diff --git a/src/groups.c b/src/groups.c new file mode 100644 index 00000000..c29e72ef --- /dev/null +++ b/src/groups.c @@ -0,0 +1,88 @@ +#include "E.h" + +Group * +CreateGroup() +{ + static int index = 0; + Group *g; + + g = Emalloc(sizeof(Group)); + if (!g) + EDBUG_RETURN(NULL); + + g->index = index++; + g->iconify = 1; + g->kill = 0; + g->move = 1; + g->raise = 0; + g->set_border = 1; + g->stick = 1; + g->shade = 1; + g->ref_count = 0; + + EDBUG_RETURN(g); +} + +void +BreakWindowGroup(EWin * ewin) +{ + + int i, num; + EWin **gwins; + + if (ewin) + { + gwins = ListWinGroupMembers(ewin->group, &num); + + if (gwins) + { + for (i = 0; i < num; i++) + RemoveEwinFromGroup(gwins[i]); + + Efree(gwins); + } + } +} + +void +BuildWindowGroup(EWin ** ewins, int num) +{ + + int i; + Group *g; + + g = CreateGroup(); + current_group = g; + + for (i = 0; i < num; i++) + { + RemoveEwinFromGroup(ewins[i]); + g->ref_count++; + ewins[i]->group = g; + } +} + +void +AddEwinToGroup(EWin * ewin, Group * g) +{ + if (ewin && g) + { + RemoveEwinFromGroup(ewin); + ewin->group = g; + ewin->group->ref_count++; + } +} + +void +RemoveEwinFromGroup(EWin * ewin) +{ + if (ewin) + { + if (ewin->group) + { + if (--(ewin->group->ref_count) <= 0) + Efree(ewin->group); + } + ewin->group = NULL; + } +} diff --git a/src/handlers.c b/src/handlers.c new file mode 100644 index 00000000..796c0ef1 --- /dev/null +++ b/src/handlers.c @@ -0,0 +1,241 @@ +#include "E.h" + +void +HandleSigHup(int num) +{ + EDBUG(7, "HandleSigHup"); + num = 0; + doExit("restart"); + EDBUG_RETURN_; +} + +void +HandleSigInt(int num) +{ + EDBUG(7, "HandleSigQuit"); + num = 0; + doExit("error"); + EDBUG_RETURN_; +} + +void +HandleSigQuit(int num) +{ + EDBUG(7, "HandleSigQuit"); + num = 0; + doExit("error"); + EDBUG_RETURN_; +} + +void +HandleSigIll(int num) +{ + EDBUG(7, "HandleSigIll"); + num = 0; + if (disp) + UngrabX(); + DialogAlert("Enlightenment performed an Illegal Instruction.\n" + "\n" + "This most likely is due to you having installed an run a\n" + "binary of Enlightenment that was compiled for a make or model\n" + "of CPU not 100% identical or compatible with yours. Please\n" + "either obtain the correct package for your system, or\n" + "re-compile enlightenment and possibly any support libraries\n" + "that you got in binary format to run Enlightenment.\n"); + doExit("error"); + EDBUG_RETURN_; +} + +void +HandleSigAbrt(int num) +{ + EDBUG(7, "HandleSigAbrt"); + num = 0; + doExit("error"); + EDBUG_RETURN_; +} + +void +HandleSigFpe(int num) +{ + EDBUG(7, "HandleSigFpe"); + num = 0; + if (disp) + UngrabX(); + DialogAlert("Enlightenment caused a Floating Point Exception.\n" + "\n" + "This means that Enlightenment or support library routines it calls\n" + "have performed an illegal mathematical operation (most likely\n" + "dividing a number by zero). This is most likely a bug. It is\n" + "recommended to restart now. If you wish to help fix this please\n" + "compile Enlightenment with debugging symbols in and run\n" + "Enlightenment under gdb so you can backtrace for where it died and\n" + "send in a useful bug report with backtrace information and variable\n" + "dumps etc.\n"); + doExit("error"); + EDBUG_RETURN_; +} + +void +HandleSigSegv(int num) +{ + static int loop_count = 0; + + EDBUG(7, "HandleSigSegv"); + if (loop_count > 0) + abort(); + loop_count++; + if (disp) + UngrabX(); + DialogAlert("Enlightenment caused Segment Violation (Segfault)\n" + "\n" + "This means that Enlightenment or support library routines it calls\n" + "have accessed areas of your system's memory that they are not\n" + "allowed access to. This is most likely a bug. It is recommended to\n" + "restart now. If you wish to help fix this please compile\n" + "Enlightenment with debugging symbols in and run Enlightenment\n" + "under gdb so you can backtrace for where it died and send in a\n" + "useful bug report with backtrace information and variable\n" + "dumps etc.\n"); + abort(); + num = 0; + EDBUG_RETURN_; +} + +void +HandleSigPipe(int num) +{ + EDBUG(7, "HandleSigPipe"); + num = 0; + EDBUG_RETURN_; +} + +void +HandleSigAlrm(int num) +{ + EDBUG(7, "HandleSigAlrm"); + num = 0; + EDBUG_RETURN_; +} +void +HandleSigTerm(int num) +{ + EDBUG(7, "HandleSigTerm"); + num = 0; + doExit("error"); + EDBUG_RETURN_; +} +void +HandleSigUsr1(int num) +{ + EDBUG(7, "HandleSigUsr1"); + num = 0; + EDBUG_RETURN_; +} + +void +HandleSigUsr2(int num) +{ + EDBUG(7, "HandleSigUsr2"); + num = 0; + EDBUG_RETURN_; +} + +void +HandleSigChild(int num) +{ + int status; + + EDBUG(7, "HandleSigChild"); + num = 0; + while (waitpid(-1, &status, WNOHANG) > 0); + EDBUG_RETURN_; +} + +void +HandleSigTstp(int num) +{ + EDBUG(7, "HandleSigTstp"); + num = 0; + EDBUG_RETURN_; +} + +void +HandleSigBus(int num) +{ + EDBUG(7, "HandleSigBus"); + num = 0; + if (disp) + UngrabX(); + DialogAlert("Enlightenment cause Bus Error.\n" + "\n" + "It is suggested you check your hardware and OS installation.\n" + "It is highly unusual to cause Bus Errors on operational\n" + "hardware.\n"); + EDBUG_RETURN_; +} + +void +EHandleXError(Display * d, XErrorEvent * ev) +{ +/* char buf[64]; */ + + EDBUG(7, "EHandleXError"); + if ((ev->request_code == X_ChangeWindowAttributes) && + (ev->error_code == BadAccess)) + { + if (!no_overwrite) + { + ASSIGN_ALERT("Another Window Manager is already running", + "OK (edit file)", + "", + "Cancel (do NOT edit)"); + Alert("Another Window Manager is already running.\n" + "\n" + "You will have to quit your current Window Manager first before\n" + "you can successfully run Enlightenment.\n" + "\n" + "If you haven't edited your user startup files, Enlightenment\n" + "can do that now for you, so when you log in again after\n" + "quitting your current window manager, you will have\n" + "Enlightenment running.\n" + "\n" + "If you want to do this, click OK, otherwise hit cancel\n" + "to abort this operation and edit the files by hand.\n" + "\n" + "WARNING WARNING WARNING WARNING!\n" + "\n" + "It is possible that this MAY not properly edit your files.\n" + ); + ASSIGN_ALERT("Are you sure?", + "YES (edit file)", + "", + "NO (do not edit)"); + Alert("Are you absolutely sure you want to have Enlightenment\n" + "edit your startup files for you?\n" + "\n" + "If your startup files are highly customised this may not\n" + "work.\n" + "\n" + "Are you ABSOLUTELY sure?\n" + ); + RESET_ALERT; + AddE(); + EExit((void *)1); + } + } +/* XGetErrorText (disp, ev->error_code, buf, 63); + * fprintf(stderr, "Whee %i: %s : %i\n", time(NULL), buf, ev->request_code); */ + d = NULL; + EDBUG_RETURN_; +} + +void +HandleXIOError(Display * d) +{ + EDBUG(7, "HandleXIOError"); + disp = NULL; + doExit("error"); + EDBUG_RETURN_; + d = NULL; +} diff --git a/src/icccm.c b/src/icccm.c new file mode 100644 index 00000000..98d37a35 --- /dev/null +++ b/src/icccm.c @@ -0,0 +1,1256 @@ +#include "E.h" + +void +ICCCM_GetTitle(EWin * ewin, Atom atom_change) +{ + XTextProperty xtp; + + EDBUG(6, "ICCCM_GetTitle"); + if (atom_change) + { + static Atom atom = 0; + + if (!atom) + atom = XInternAtom(disp, "WM_NAME", False); + if (atom_change != atom) + EDBUG_RETURN_; + } + if (ewin->client.title) + Efree(ewin->client.title); + if (XGetWMName(disp, ewin->client.win, &xtp)) + { + int items; + char **list; + Status s; + + if (xtp.format == 8) + { + s = XmbTextPropertyToTextList(disp, &xtp, &list, &items); + if ((s == Success) && (items > 0)) + { + ewin->client.title = duplicate(*list); + XFreeStringList(list); + } + else + ewin->client.title = duplicate((char *)xtp.value); + } + else + ewin->client.title = duplicate((char *)xtp.value); + XFree(xtp.value); + } + else if (!ewin->internal) + ewin->client.title = duplicate("No Title"); + EDBUG_RETURN_; +} + +void +ICCCM_GetColormap(EWin * ewin) +{ + static Atom atom = 0; + XWindowAttributes xwa; + Window win, *wlist; + int num; + + EDBUG(6, "ICCCM_GetColormap"); + if (ewin->internal) + EDBUG_RETURN_; + if (!atom) + atom = XInternAtom(disp, "WM_COLORMAP_WINDOWS", False); + win = ewin->client.win; + wlist = AtomGet(win, atom, XA_WINDOW, &num); + if (wlist) + { + win = wlist[0]; + Efree(wlist); + } + if (XGetWindowAttributes(disp, ewin->client.win, &xwa)) + { + if (xwa.colormap) + ewin->client.cmap = xwa.colormap; + else + ewin->client.cmap = 0; + } + else + ewin->client.cmap = 0; + EDBUG_RETURN_; +} + +void +ICCCM_Delete(EWin * ewin) +{ + XClientMessageEvent ev; + static Atom a1 = 0, a2 = 0; + Atom a3, *prop; + unsigned long lnum, ldummy; + int num, i, del, dummy; + + EDBUG(6, "ICCCM_Delete"); + if (ewin->internal) + { + XEvent ev; + + if (ewin->menu) + HideMenu(ewin->menu); + if (ewin->pager) + { + HideEwin(ewin); + ev.xunmap.window = ewin->pager->win; + HandleUnmap(&ev); + } + if (ewin->ibox) + { + HideEwin(ewin); + ev.xunmap.window = ewin->ibox->win; + HandleUnmap(&ev); + } + if (ewin->dialog) + DialogClose(ewin->dialog); + EDBUG_RETURN_; + } + if (!a1) + { + a1 = XInternAtom(disp, "WM_DELETE_WINDOW", False); + a2 = XInternAtom(disp, "WM_PROTOCOLS", False); + } + num = 0; + prop = NULL; + del = 0; + if (!XGetWMProtocols(disp, ewin->client.win, &prop, &num)) + { + XGetWindowProperty(disp, ewin->client.win, a2, 0, 10, False, a2, &a3, &dummy, + &lnum, &ldummy, (unsigned char **)&prop); + num = (int)lnum; + } + if (prop) + { + for (i = 0; i < num; i++) + if (prop[i] == a1) + del = 1; + XFree(prop); + } + if (del) + { + ev.type = ClientMessage; + ev.window = ewin->client.win; + ev.message_type = a2; + ev.format = 32; + ev.data.l[0] = a1; + ev.data.l[1] = CurrentTime; + XSendEvent(disp, ewin->client.win, False, 0, (XEvent *) & ev); + } + else + XKillClient(disp, (XID) ewin->client.win); + EDBUG_RETURN_; +} + +void +ICCCM_Save(EWin * ewin) +{ + XClientMessageEvent ev; + static Atom a1 = 0, a2 = 0; + + EDBUG(6, "ICCCM_Save"); + if (ewin->internal) + EDBUG_RETURN_; + if (!a1) + { + a1 = XInternAtom(disp, "WM_SAVE_YOURSELF", False); + a2 = XInternAtom(disp, "WM_PROTOCOLS", False); + } + ev.type = ClientMessage; + ev.window = ewin->client.win; + ev.message_type = a2; + ev.format = 32; + ev.data.l[0] = a1; + ev.data.l[1] = CurrentTime; + XSendEvent(disp, ewin->client.win, False, 0, (XEvent *) & ev); + EDBUG_RETURN_; +} + +void +ICCCM_Iconify(EWin * ewin) +{ + static Atom a = 0; + unsigned long c[2]; + + EDBUG(6, "ICCCM_Iconify"); + if (!ewin) + EDBUG_RETURN_; + if (!a) + a = XInternAtom(disp, "WM_STATE", False); + c[0] = IconicState; + c[1] = 0; + XChangeProperty(disp, ewin->client.win, a, a, 32, PropModeReplace, + (unsigned char *)c, 2); + ewin->iconified = 3; + AddItem(ewin, "ICON", ewin->client.win, LIST_TYPE_ICONIFIEDS); + EUnmapWindow(disp, ewin->client.win); + EDBUG_RETURN_; +} + +void +ICCCM_DeIconify(EWin * ewin) +{ + static Atom a; + unsigned long c[2]; + + EDBUG(6, "ICCCM_DeIconify"); + if (!ewin) + EDBUG_RETURN_; + if (!a) + a = XInternAtom(disp, "WM_STATE", False); + c[0] = NormalState; + c[1] = 0; + ewin->iconified = 0; + XChangeProperty(disp, ewin->client.win, a, a, 32, PropModeReplace, + (unsigned char *)c, 2); + RemoveItem("ICON", ewin->client.win, LIST_FINDBY_BOTH, + LIST_TYPE_ICONIFIEDS); + EMapWindow(disp, ewin->client.win); + EDBUG_RETURN_; +} + +void +ICCCM_MatchSize(EWin * ewin) +{ + int w, h; + int i, j; + double aspect; + + EDBUG(6, "ICCCM_MatchSize"); + w = ewin->client.w; + h = ewin->client.h; + + if (w < ewin->client.width.min) + w = ewin->client.width.min; + if (w > ewin->client.width.max) + w = ewin->client.width.max; + if (h < ewin->client.height.min) + h = ewin->client.height.min; + if (h > ewin->client.height.max) + h = ewin->client.height.max; + if ((w > 0) && (h > 0)) + { + w -= ewin->client.base_w; + h -= ewin->client.base_h; + if ((w > 0) && (h > 0)) + { + aspect = ((double)w) / ((double)h); + if (mode.mode == MODE_RESIZE_H) + { + if (aspect < ewin->client.aspect_min) + h = (int)((double)w / ewin->client.aspect_min); + if (aspect > ewin->client.aspect_max) + h = (int)((double)w / ewin->client.aspect_max); + } + else if (mode.mode == MODE_RESIZE_V) + { + if (aspect < ewin->client.aspect_min) + w = (int)((double)h * ewin->client.aspect_min); + if (aspect > ewin->client.aspect_max) + w = (int)((double)h * ewin->client.aspect_max); + } + else + { + if (aspect < ewin->client.aspect_min) + w = (int)((double)h * ewin->client.aspect_min); + if (aspect > ewin->client.aspect_max) + h = (int)((double)w / ewin->client.aspect_max); + } + i = w / ewin->client.w_inc; + j = h / ewin->client.h_inc; + w = i * ewin->client.w_inc; + h = j * ewin->client.h_inc; + } + w += ewin->client.base_w; + h += ewin->client.base_h; + } + ewin->client.w = w; + ewin->client.h = h; + EDBUG_RETURN_; +} + +void +ICCCM_Configure(EWin * ewin) +{ + XEvent ev; + XWindowChanges xwc; + + EDBUG(6, "ICCCM_Configure"); + xwc.x = ewin->border->border.left; + xwc.y = ewin->border->border.top; + xwc.width = ewin->client.w; + xwc.height = ewin->client.h; + if (ewin->shaded != 2) + XConfigureWindow(disp, ewin->win_container, CWX | CWY | CWWidth | CWHeight, &xwc); + xwc.x = 0; + xwc.y = 0; + XConfigureWindow(disp, ewin->client.win, CWX | CWY | CWWidth | CWHeight, &xwc); + if ((ewin->menu) || (ewin->dialog)) + EDBUG_RETURN_; + ev.type = ConfigureNotify; + ev.xconfigure.display = disp; + ev.xconfigure.event = ewin->client.win; + ev.xconfigure.window = ewin->client.win; + ev.xconfigure.x = desks.desk[ewin->desktop].x + ewin->x + + ewin->border->border.left; + ev.xconfigure.y = desks.desk[ewin->desktop].y + ewin->y + + ewin->border->border.top; + ev.xconfigure.width = ewin->client.w; + ev.xconfigure.height = ewin->client.h; + ev.xconfigure.border_width = 0; + ev.xconfigure.above = ewin->win; + ev.xconfigure.override_redirect = False; + XSendEvent(disp, ewin->client.win, False, StructureNotifyMask, &ev); + EDBUG_RETURN_; +} + +void +ICCCM_AdoptStart(EWin * ewin, Window win) +{ + EDBUG(6, "ICCCM_AdoptStart"); + if (!ewin->internal) + { + XAddToSaveSet(disp, win); + } + EDBUG_RETURN_; +} + +void +ICCCM_Adopt(EWin * ewin, Window win) +{ + static Atom a = 0; + unsigned long c[2]; + XWindowAttributes att; + + EDBUG(6, "ICCCM_Adopt"); + if (!ewin->internal) + { + XSetWindowBorderWidth(disp, win, 0); + } + EReparentWindow(disp, win, ewin->win_container, 0, 0); + XGetWindowAttributes(disp, win, &att); + XSelectInput(disp, win, att.your_event_mask | PropertyChangeMask | + EnterWindowMask | LeaveWindowMask | FocusChangeMask | + ResizeRedirectMask | StructureNotifyMask | ColormapChangeMask); + XShapeSelectInput(disp, win, ShapeNotifyMask); + if (!a) + a = XInternAtom(disp, "WM_STATE", False); + if (ewin->client.start_iconified) + c[0] = IconicState; + else + c[0] = NormalState; + c[1] = 0; + XChangeProperty(disp, win, a, a, 32, PropModeReplace, (unsigned char *)c, 2); + ewin->x = ewin->client.x; + ewin->y = ewin->client.y; + ewin->reqx = ewin->client.x; + ewin->reqy = ewin->client.y; + ewin->w = ewin->client.w + ewin->border->border.left + ewin->border->border.right; + ewin->h = ewin->client.h + ewin->border->border.top + ewin->border->border.bottom; + EDBUG_RETURN_; +} + +void +ICCCM_Withdraw(EWin * ewin) +{ + static Atom a = 0; + unsigned long c[2]; + + EDBUG(6, "ICCCM_Withdraw"); + if (!ewin) + EDBUG_RETURN_; + if (!a) + a = XInternAtom(disp, "WM_STATE", False); + + /* We have a choice of deleting the WM_STATE property + * or changing the value to Withdrawn. Since twm/fvwm does + * it that way, we change it to Withdrawn. + */ + c[0] = WithdrawnState; + c[1] = 0; + XChangeProperty(disp, ewin->client.win, a, a, 32, PropModeReplace, (unsigned char *)c, 2); + EDBUG_RETURN_; +} + +void +ICCCM_Cmap(EWin * ewin) +{ + EDBUG(6, "ICCCM_Cmap"); + + if (!ewin) + { + if (mode.current_cmap) + { + XUninstallColormap(disp, mode.current_cmap); + mode.current_cmap = 0; + } + EDBUG_RETURN_; + } + if ((ewin->client.cmap) && (mode.current_cmap != ewin->client.cmap)) + { + XInstallColormap(disp, ewin->client.cmap); + mode.current_cmap = ewin->client.cmap; + } + EDBUG_RETURN_; +} + +void +ICCCM_Focus(EWin * ewin) +{ + XClientMessageEvent ev; + static Atom a1 = 0, a2 = 0; + Atom a3, *prop; + unsigned long lnum, ldummy; + int num, i, foc, dummy; + + EDBUG(6, "ICCCM_Focus"); + if (!a1) + { + a1 = XInternAtom(disp, "WM_TAKE_FOCUS", False); + a2 = XInternAtom(disp, "WM_PROTOCOLS", False); + } + num = 0; + prop = NULL; + foc = 0; + if (!ewin) + { + XSetInputFocus(disp, root.win, RevertToPointerRoot, CurrentTime); + EDBUG_RETURN_; + } + if (ewin->menu) + EDBUG_RETURN_; + if (!ewin->client.need_input) + { + if (!mode.cur_menu_mode) + mode.context_ewin = ewin; + EDBUG_RETURN_; + } + if (!XGetWMProtocols(disp, ewin->client.win, &prop, &num)) + { + XGetWindowProperty(disp, ewin->client.win, a2, 0, 10, False, a2, &a3, &dummy, + &lnum, &ldummy, (unsigned char **)&prop); + num = (int)lnum; + } + if (prop) + { + for (i = 0; i < num; i++) + if (prop[i] == a1) + foc = 1; + XFree(prop); + } + if (foc) + { + ev.type = ClientMessage; + ev.window = ewin->client.win; + ev.message_type = a2; + ev.format = 32; + ev.data.l[0] = a1; + ev.data.l[1] = CurrentTime; + XSendEvent(disp, ewin->client.win, False, 0, (XEvent *) & ev); + } +/* else */ + XSetInputFocus(disp, ewin->client.win, RevertToPointerRoot, CurrentTime); + EDBUG_RETURN_; +} + +void +ICCCM_GetGeoms(EWin * ewin, Atom atom_change) +{ + XSizeHints hint; + Window ww; + long mask; + unsigned int dummy, w, h; + int x, y; + + EDBUG(6, "ICCCM_GetGeoms"); + if (atom_change) + { + static Atom atom = 0; + + if (!atom) + atom = XInternAtom(disp, "WM_NORMAL_HINTS", False); + if (atom_change != atom) + EDBUG_RETURN_; + } + EGetGeometry(disp, ewin->client.win, &ww, &x, &y, &w, &h, &dummy, &dummy); + ewin->client.x = x; + ewin->client.y = y; + ewin->client.w = w; + ewin->client.h = h; + if (XGetWMNormalHints(disp, ewin->client.win, &hint, &mask)) + { + if (!(ewin->client.already_placed)) + { + if ((hint.flags & USPosition) || + ((hint.flags & PPosition))) + { +/* OK I tried to be ICCCM compliant but it seems apps arent. + * if (hint.flags & PWinGravity) + * { + * switch (hint.win_gravity) + * { + * case NorthWestGravity: + * ewin->client.x = x; + * ewin->client.y = y; + * break; + * case NorthGravity: + * ewin->client.x = x - (w >> 1); + * ewin->client.y = y; + * break; + * case NorthEastGravity: + * ewin->client.x = x - w; + * ewin->client.y = y; + * break; + * case EastGravity: + * ewin->client.x = x - w; + * ewin->client.y = y - (h >> 1); + * break; + * case SouthEastGravity: + * ewin->client.x = x - w; + * ewin->client.y = y - h; + * break; + * case SouthGravity: + * ewin->client.x = x - (w >> 1); + * ewin->client.y = y - h; + * break; + * case SouthWestGravity: + * ewin->client.x = x; + * ewin->client.y = y - h; + * break; + * case WestGravity: + * ewin->client.x = x; + * ewin->client.y = y - (h >> 1); + * break; + * case CenterGravity: + * ewin->client.x = x - (w >> 1); + * ewin->client.y = y - (h >> 1); + * break; + * default: + * break; + * } + * } + * else */ + { + ewin->client.x = x; + ewin->client.y = y; + } + if ((hint.flags & PPosition) && (!ewin->sticky)) + { + int dsk; + + dsk = ewin->desktop; + if ((dsk < 0) || (dsk >= mode.numdesktops)) + dsk = desks.current; + ewin->client.x -= desks.desk[dsk].x; + ewin->client.y -= desks.desk[dsk].y; + if (ewin->client.x + ewin->client.w >= root.w) + ewin->client.x += desks.desk[dsk].x; + else if (ewin->client.x < 0) + ewin->client.x += desks.desk[dsk].x; + if (ewin->client.y + ewin->client.h >= root.h) + ewin->client.y += desks.desk[dsk].y; + else if (ewin->client.y < 0) + ewin->client.y += desks.desk[dsk].y; + } + ewin->client.already_placed = 1; + } + } + else + { + ewin->client.x = 0; + ewin->client.y = 0; + ewin->client.already_placed = 0; + } + if (hint.flags & PMinSize) + { + ewin->client.width.min = hint.min_width; + ewin->client.height.min = hint.min_height; + } + else + { + ewin->client.width.min = 0; + ewin->client.height.min = 0; + } + if (hint.flags & PMaxSize) + { + ewin->client.width.max = hint.max_width; + ewin->client.height.max = hint.max_height; + if (hint.max_width < ewin->client.w) + ewin->client.width.max = ewin->client.w; + if (hint.max_height < ewin->client.h) + ewin->client.height.max = ewin->client.h; + } + else + { + ewin->client.width.max = 65535; + ewin->client.height.max = 65535; + } + if (hint.flags & PResizeInc) + { + ewin->client.w_inc = hint.width_inc; + ewin->client.h_inc = hint.height_inc; + if (ewin->client.w_inc < 1) + ewin->client.w_inc = 1; + if (ewin->client.h_inc < 1) + ewin->client.h_inc = 1; + } + else + { + ewin->client.w_inc = 1; + ewin->client.h_inc = 1; + } + if (hint.flags & PAspect) + { + if ((hint.min_aspect.y > 0.0) && (hint.min_aspect.x > 0.0)) + { + ewin->client.aspect_min = ((double)hint.min_aspect.x) / + ((double)hint.min_aspect.y); + } + else + ewin->client.aspect_min = 0.0; + if ((hint.max_aspect.y > 0.0) && (hint.max_aspect.x > 0.0)) + { + ewin->client.aspect_max = ((double)hint.max_aspect.x) / + ((double)hint.max_aspect.y); + } + else + ewin->client.aspect_max = 65535.0; + } + else + { + ewin->client.aspect_min = 0.0; + ewin->client.aspect_max = 65535.0; + } + if (hint.flags & PBaseSize) + { + if (!(hint.flags & PMaxSize)) + { + ewin->client.width.min = hint.base_width; + ewin->client.height.min = hint.base_height; + } + ewin->client.base_w = hint.base_width; + ewin->client.base_h = hint.base_height; + } + else + { + ewin->client.base_w = ewin->client.width.min; + ewin->client.base_h = ewin->client.height.min; + } + if (ewin->client.width.min < 1) + ewin->client.width.min = 1; + if (ewin->client.height.min < 1) + ewin->client.height.min = 1; + } + if (ewin->client.width.min == 0) + { + if (ewin->internal) + { + ewin->client.width.min = w; + ewin->client.height.min = h; + ewin->client.width.max = w; + ewin->client.height.max = h; + } + } + ewin->client.no_resize_h = 0; + ewin->client.no_resize_v = 0; + if (ewin->client.width.min == ewin->client.width.max) + ewin->client.no_resize_h = 1; + if (ewin->client.height.min == ewin->client.height.max) + ewin->client.no_resize_v = 1; + EDBUG_RETURN_; +} + +void +ICCCM_GetInfo(EWin * ewin, Atom atom_change) +{ + XClassHint hint; + XTextProperty xtp; + int cargc, i, size; + char **cargv, *s; + Atom a3; + static Atom a2 = 0; + unsigned long lnum, ldummy; + int num, dummy; + char ok = 1; + + EDBUG(6, "ICCCM_GetInfo"); + if (atom_change) + { + static Atom atom = 0; + + if (!atom) + atom = XInternAtom(disp, "WM_CLASS", False); + if (atom_change != atom) + ok = 0; + } + if (ok) + { + if (XGetClassHint(disp, ewin->client.win, &hint)) + { + if (ewin->client.name) + Efree(ewin->client.name); + if (ewin->client.class) + Efree(ewin->client.class); + ewin->client.name = duplicate(hint.res_name); + ewin->client.class = duplicate(hint.res_class); + XFree(hint.res_name); + XFree(hint.res_class); + } + else if (XGetClassHint(disp, ewin->client.group, &hint)) + { + if (ewin->client.name) + Efree(ewin->client.name); + if (ewin->client.class) + Efree(ewin->client.class); + ewin->client.name = duplicate(hint.res_name); + ewin->client.class = duplicate(hint.res_class); + XFree(hint.res_name); + XFree(hint.res_class); + } + else + { + ewin->client.name = NULL; + ewin->client.class = NULL; + } + } + ok = 1; + if (atom_change) + { + static Atom atom = 0; + + if (!atom) + atom = XInternAtom(disp, "WM_COMMAND", False); + if (atom_change != atom) + ok = 0; + } + if (ok) + { + if (XGetCommand(disp, ewin->client.win, &cargv, &cargc)) + { + if (cargc > 0) + { + size = strlen(cargv[0]) + 1; + s = Emalloc(size); + strcpy(s, cargv[0]); + for (i = 1; i < cargc; i++) + { + size += strlen(cargv[i]) + 1; + s = Erealloc(s, size); + strcat(s, " "); + strcat(s, cargv[i]); + } + XFreeStringList(cargv); + if (ewin->client.command) + Efree(ewin->client.command); + ewin->client.command = s; + } + else + { + ewin->client.command = NULL; + } + } + else if (XGetCommand(disp, ewin->client.group, &cargv, &cargc)) + { + if (cargc > 0) + { + size = strlen(cargv[0]) + 1; + s = Emalloc(size); + strcpy(s, cargv[0]); + for (i = 1; i < cargc; i++) + { + size += strlen(cargv[i]) + 1; + s = Erealloc(s, size); + strcat(s, " "); + strcat(s, cargv[i]); + } + XFreeStringList(cargv); + if (ewin->client.command) + Efree(ewin->client.command); + ewin->client.command = s; + } + else + { + ewin->client.command = NULL; + } + } + else + ewin->client.command = NULL; + } + ok = 1; + if (atom_change) + { + static Atom atom = 0; + + if (!atom) + atom = XInternAtom(disp, "WM_CLIENT_MACHINE", False); + if (atom_change != atom) + ok = 0; + } + if (ok) + { + if (XGetWMClientMachine(disp, ewin->client.win, &xtp)) + { + if (ewin->client.machine) + Efree(ewin->client.machine); + ewin->client.machine = duplicate((char *)xtp.value); + XFree(xtp.value); + } + else if (XGetWMClientMachine(disp, ewin->client.group, &xtp)) + { + if (ewin->client.machine) + Efree(ewin->client.machine); + ewin->client.machine = duplicate((char *)xtp.value); + XFree(xtp.value); + } + else + ewin->client.machine = NULL; + } + ok = 1; + if (atom_change) + { + static Atom atom = 0; + + if (!atom) + atom = XInternAtom(disp, "WM_ICON_NAME", False); + if (atom_change != atom) + ok = 0; + } + if (ok) + { + if (XGetWMIconName(disp, ewin->client.win, &xtp)) + { + if (ewin->client.icon_name) + Efree(ewin->client.icon_name); + if (xtp.encoding == XA_STRING) + ewin->client.icon_name = duplicate((char *)xtp.value); + else + { + char **cl; + Status status; + int n; + + status = XmbTextPropertyToTextList(disp, &xtp, &cl, &n); + if (status >= Success && n > 0 && cl[0]) + { + ewin->client.icon_name = duplicate(cl[0]); + XFreeStringList(cl); + } + else + ewin->client.icon_name = duplicate((char *)xtp.value); + } + XFree(xtp.value); + } + else if (XGetWMIconName(disp, ewin->client.group, &xtp)) + { + if (ewin->client.icon_name) + Efree(ewin->client.icon_name); + if (xtp.encoding == XA_STRING) + ewin->client.icon_name = duplicate((char *)xtp.value); + else + { + char **cl; + Status status; + int n; + + status = XmbTextPropertyToTextList(disp, &xtp, &cl, &n); + if (status >= Success && n > 0 && cl[0]) + { + ewin->client.icon_name = duplicate(cl[0]); + XFreeStringList(cl); + } + else + ewin->client.icon_name = duplicate((char *)xtp.value); + } + XFree(xtp.value); + } + else + ewin->client.icon_name = NULL; + } + + ok = 1; + if (atom_change) + { + static Atom atom = 0; + + if (!atom) + atom = XInternAtom(disp, "WM_WINDOW_ROLE", False); + if (atom_change != atom) + ok = 0; + } + if (ok) + { + num = 0; + s = NULL; + if (!a2) + a2 = XInternAtom(disp, "WM_WINDOW_ROLE", False); + XGetWindowProperty(disp, ewin->client.win, a2, 0, 10, False, + XA_STRING, &a3, &dummy, &lnum, &ldummy, + (unsigned char **)&s); + num = (int)lnum; + if (s) + { + if (ewin->client.role) + Efree(ewin->client.role); + ewin->client.role = Emalloc(num + 1); + memcpy(ewin->client.role, s, num); + ewin->client.role[num] = 0; + XFree(s); + } + } + EDBUG_RETURN_; +} +void +ICCCM_GetHints(EWin * ewin, Atom atom_change) +{ + XWMHints *hint = NULL; + Window w; + static Atom a = 0; + Atom a2, *prop; + Window *cleader = NULL; + unsigned long lnum, ldummy; + int i, num, dummy; + static Atom a3 = 0; + char ok = 1; + + EDBUG(6, "ICCCM_GetHints"); + if (ewin->internal) + EDBUG_RETURN_; + MWM_GetHints(ewin, atom_change); + if (atom_change) + { + static Atom atom = 0; + + if (!atom) + atom = XInternAtom(disp, "WM_HINTS", False); + if (atom_change != atom) + ok = 0; + } + if (ok) + hint = XGetWMHints(disp, ewin->client.win); + if (hint) + { + /* I have to make sure the thing i'm docking is a dock app */ + if ((hint->flags & StateHint) && (hint->initial_state == WithdrawnState)) + { + if (hint->flags & (StateHint | IconWindowHint | + IconPositionHint | WindowGroupHint)) + { + if ((hint->icon_x == 0) && (hint->icon_y == 0) && + hint->window_group == ewin->client.win) + ewin->docked = 1; + } + } + if (hint->flags & InputHint) + { + if (hint->input) + ewin->client.need_input = 1; + else + ewin->client.need_input = 0; + } + else + ewin->client.need_input = 1; + if (hint->flags & StateHint) + { + if (hint->initial_state == IconicState) + ewin->client.start_iconified = 1; + else + ewin->client.start_iconified = 0; + } + else + ewin->client.start_iconified = 0; + if (hint->flags & IconPixmapHint) + ewin->client.icon_pmap = hint->icon_pixmap; + else + ewin->client.icon_pmap = 0; + if (hint->flags & IconMaskHint) + ewin->client.icon_mask = hint->icon_mask; + else + ewin->client.icon_mask = 0; + if (hint->flags & IconWindowHint) + ewin->client.icon_win = hint->icon_window; + else + ewin->client.icon_win = 0; + if (hint->flags & WindowGroupHint) + ewin->client.group = hint->window_group; + else + ewin->client.group = 0; + XFree(hint); + } + ok = 1; + if (atom_change) + { + static Atom atom = 0; + + if (!atom) + atom = XInternAtom(disp, "WM_PROTOCOLS", False); + if (atom_change != atom) + ok = 0; + } + if (ok) + { + if (XGetWMProtocols(disp, ewin->client.win, &prop, &num)) + { + if (!a3) + a3 = XInternAtom(disp, "WM_TAKE_FOCUS", False); + if (prop) + { + for (i = 0; i < num; i++) + if (prop[i] == a3) + ewin->client.need_input = 1; + XFree(prop); + } + } + } + if (!ewin->client.need_input) + { + ewin->skipfocus = 1; + } + if (XGetTransientForHint(disp, ewin->client.win, &w)) + { + ewin->client.transient = 1; + ewin->client.transient_for = w; + } + else + ewin->client.transient = 0; + if (ewin->client.group == ewin->client.win) + ewin->client.is_group_leader = 1; + else + ewin->client.is_group_leader = 0; + ok = 1; + if (atom_change) + { + static Atom atom = 0; + + if (!atom) + atom = XInternAtom(disp, "WM_CLIENT_LEADER", False); + if (atom_change != atom) + ok = 0; + } + if (ok) + { + if (!a) + a = XInternAtom(disp, "WM_CLIENT_LEADER", False); + XGetWindowProperty(disp, ewin->client.win, a, 0, 0x7fffffff, False, + XA_WINDOW, &a2, &dummy, &lnum, &ldummy, + (unsigned char **)&cleader); + if (cleader) + { + ewin->client.client_leader = *cleader; + if (!ewin->client.group) + ewin->client.group = *cleader; + XFree(cleader); + } + } + EDBUG_RETURN_; +} + +void +ICCCM_GetShapeInfo(EWin * ewin) +{ + XRectangle *rl = NULL; + int rn = 0, ord; + int x, y; + unsigned int w, h, d; + Window rt; + + EDBUG(6, "ICCCM_GetShapeInfo"); + GrabX(); + EGetGeometry(disp, ewin->client.win, &rt, &x, &y, &w, &h, &d, &d); + rl = EShapeGetRectangles(disp, ewin->client.win, ShapeBounding, &rn, &ord); + UngrabX(); + if (rn < 1) + { + ewin->client.shaped = 0; + EShapeCombineMask(disp, ewin->win_container, ShapeBounding, 0, 0, + None, ShapeSet); + } + else if (rn == 1) + { + if ((rl[0].x == 0) && (rl[0].y == 0) && + (rl[0].width == w) && (rl[0].height == h)) + { + ewin->client.shaped = 0; + EShapeCombineMask(disp, ewin->win_container, ShapeBounding, 0, 0, + None, ShapeSet); + } + } + else + { + ewin->client.shaped = 1; + EShapeCombineShape(disp, ewin->win_container, ShapeBounding, 0, 0, + ewin->client.win, ShapeBounding, ShapeSet); + } + if ((rl) && (rn > 0)) + XFree(rl); + EDBUG_RETURN_; +} + +void +ICCCM_SetIconSizes() +{ + XIconSize *is; + + EDBUG(6, "ICCCM_SetIconSizes"); + is = XAllocIconSize(); + is->min_width = 8; + is->min_height = 8; + is->max_width = 48; + is->max_height = 48; + is->width_inc = 1; + is->height_inc = 1; + XSetIconSizes(disp, root.win, is, 1); + XFree(is); + EDBUG_RETURN_; +} + +void +ICCCM_SetEInfo(EWin * ewin) +{ + static Atom a = 0; + CARD32 c[9]; + + EDBUG(6, "ICCCM_SetEInfo"); + if (ewin->internal) + EDBUG_RETURN_; + if (!a) + a = XInternAtom(disp, "ENL_INTERNAL_DATA", False); + c[0] = ewin->desktop; + c[1] = ewin->sticky; + c[2] = ewin->x; + c[3] = ewin->y; + c[4] = ewin->iconified; + if (ewin->iconified) + ICCCM_DeIconify(ewin); + c[5] = ewin->shaded; + if (!strcmp(ewin->border->name, "BORDERLESS")) + { + c[8] = 1; + } + else + { + c[8] = 0; + } + c[6] = ewin->client.w; + c[7] = ewin->client.h; + XChangeProperty(disp, ewin->client.win, a, XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)c, 9); + EDBUG_RETURN_; +} + +void +ICCCM_SetMainEInfo(void) +{ + Atom a; + int i; + CARD32 cc[ENLIGHTENMENT_CONF_NUM_DESKTOPS * 2]; + + for (i = 0; i < ENLIGHTENMENT_CONF_NUM_DESKTOPS; i++) + { + cc[(i * 2)] = desks.desk[i].current_area_x; + cc[(i * 2) + 1] = desks.desk[i].current_area_y; + } + a = XInternAtom(disp, "ENL_INTERNAL_AREA_DATA", False); + XChangeProperty(disp, root.win, a, XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)cc, ENLIGHTENMENT_CONF_NUM_DESKTOPS * 2); + a = XInternAtom(disp, "ENL_INTERNAL_DESK_DATA", False); + XChangeProperty(disp, root.win, a, XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)(&desks.current), 1); +} + +void +ICCCM_GetMainEInfo(void) +{ + Atom a, a2; + CARD32 *c = NULL; + unsigned long lnum, ldummy; + int num, dummy, i; + + a = XInternAtom(disp, "ENL_INTERNAL_AREA_DATA", False); + XGetWindowProperty(disp, root.win, a, 0, 10, False, XA_CARDINAL, + &a2, &dummy, &lnum, &ldummy, (unsigned char **)&c); + num = (int)lnum; + if ((num > 0) && (c)) + { + for (i = 0; i < (num / 2); i++) + { + if (i < ENLIGHTENMENT_CONF_NUM_DESKTOPS) + { + desks.desk[i].current_area_x = c[(i * 2)]; + desks.desk[i].current_area_y = c[(i * 2) + 1]; + } + } + XFree(c); + } + num = 0; + c = NULL; + + a = XInternAtom(disp, "ENL_INTERNAL_DESK_DATA", False); + XGetWindowProperty(disp, root.win, a, 0, 10, False, XA_CARDINAL, + &a2, &dummy, &lnum, &ldummy, (unsigned char **)&c); + num = (int)lnum; + if ((num > 0) && (c)) + { + GotoDesktop(*c); + XFree(c); + } +} + +int +ICCCM_GetEInfo(EWin * ewin) +{ + static Atom a = 0; + Atom a2; + CARD32 *c = NULL; + unsigned long lnum, ldummy; + int num, dummy; + + EDBUG(6, "ICCCM_GetEInfo"); + if (ewin->internal) + EDBUG_RETURN(0); + if (!a) + a = XInternAtom(disp, "ENL_INTERNAL_DATA", False); + XGetWindowProperty(disp, ewin->client.win, a, 0, 10, True, XA_CARDINAL, + &a2, &dummy, &lnum, &ldummy, (unsigned char **)&c); + num = (int)lnum; + if ((num > 0) && (c)) + { + if (mode.startup) + { + ewin->desktop = c[0]; + ewin->sticky = c[1]; + ewin->client.x = c[2]; + ewin->client.y = c[3]; + ewin->iconified = c[4]; + ewin->shaded = c[5]; + if (ewin->sticky) + ewin->desktop = -1; + if (ewin->iconified) + { + ewin->client.start_iconified = 1; + ewin->iconified = 0; + } + ewin->client.already_placed = 1; + if (num >= 9) + { + ewin->client.w = c[6]; + ewin->client.h = c[7]; + if (c[8]) + { + Border *b; + + b = (Border *) FindItem("BORDERLESS", 0, LIST_FINDBY_NAME, LIST_TYPE_BORDER); + ewin->border_new = 1; + SetEwinToBorder(ewin, b); + ICCCM_MatchSize(ewin); + MoveResizeEwin(ewin, ewin->x, ewin->y, ewin->client.w, + ewin->client.h); + + } + } + } + XFree(c); + EDBUG_RETURN(1); + } + EDBUG_RETURN(0); +} diff --git a/src/iclass.c b/src/iclass.c new file mode 100644 index 00000000..855a98da --- /dev/null +++ b/src/iclass.c @@ -0,0 +1,1169 @@ + +#include "E.h" + +ImageClass * +CreateIclass() +{ + ImageClass *i; + + EDBUG(5, "CreateIclass"); + + i = Emalloc(sizeof(ImageClass)); + if (!i) + EDBUG_RETURN(NULL); + + i->name = NULL; + i->external = 0; + i->norm.normal = i->norm.hilited = i->norm.clicked + = i->norm.disabled = NULL; + i->active.normal = i->active.hilited = i->active.clicked + = i->active.disabled = NULL; + i->sticky.normal = i->sticky.hilited = i->sticky.clicked + = i->sticky.disabled = NULL; + i->sticky_active.normal = i->sticky_active.hilited + = i->sticky_active.clicked = i->sticky_active.disabled = NULL; + i->padding.left = 0; + i->padding.right = 0; + i->padding.top = 0; + i->padding.bottom = 0; + i->colmod = NULL; + i->ref_count = 0; + + EDBUG_RETURN(i); + +} + +void +FreeImageState(ImageState * i) +{ + + EDBUG(7, "FreeImageState"); + + Efree(i->im_file); + Efree(i->real_file); + + if (i->im) + Imlib_destroy_image(id, i->im); + if (i->transp) + Efree(i->transp); + if (i->border) + Efree(i->border); + + if (i->colmod) + i->colmod->ref_count--; + + EDBUG_RETURN_; + +} + +void +FreeImageStateArray(ImageStateArray * isa) +{ + + EDBUG(6, "FreeImageStateArray"); + + FreeImageState(isa->normal); + Efree(isa->normal); + FreeImageState(isa->hilited); + Efree(isa->hilited); + FreeImageState(isa->clicked); + Efree(isa->clicked); + FreeImageState(isa->disabled); + Efree(isa->disabled); + + EDBUG_RETURN_; + +} + +void +FreeImageClass(ImageClass * i) +{ + + EDBUG(5, "FreeImageClass"); + + if (!i) + EDBUG_RETURN_; + + if (i->ref_count > 0) + { + char stuff[255]; + + Esnprintf(stuff, sizeof(stuff), "Error: %u references remain\n", + i->ref_count); + DIALOG_OK("ImageClass Error", stuff); + EDBUG_RETURN_; + } + while (RemoveItemByPtr(i, LIST_TYPE_ICLASS)); + + if (i->name) + Efree(i->name); + + FreeImageStateArray(&(i->norm)); + FreeImageStateArray(&(i->active)); + FreeImageStateArray(&(i->sticky)); + FreeImageStateArray(&(i->sticky_active)); + + if (i->colmod) + i->colmod->ref_count--; + + EDBUG_RETURN_; + +} + +ImageState * +CreateImageState() +{ + ImageState *is; + + EDBUG(6, "CreateImageState"); + + is = Emalloc(sizeof(ImageState)); + if (!is) + EDBUG_RETURN(NULL); + + is->im_file = NULL; + is->real_file = NULL; + is->unloadable = 0; + is->im = NULL; + is->transp = NULL; + is->border = NULL; + is->pixmapfillstyle = FILL_STRETCH; + is->bg.r = 160; + is->bg.g = 160; + is->bg.b = 160; + is->hi.r = 200; + is->hi.g = 200; + is->hi.b = 200; + is->lo.r = 120; + is->lo.g = 120; + is->lo.b = 120; + is->hihi.r = 255; + is->hihi.g = 255; + is->hihi.b = 255; + is->lolo.r = 64; + is->lolo.g = 64; + is->lolo.b = 64; + is->bevelstyle = BEVEL_NONE; + is->colmod = NULL; + + EDBUG_RETURN(is); + +} + +void +ImageStatePopulate(ImageState * is) +{ + int r, g, b; + + EDBUG(6, "ImageStatePopulate"); + + if (!is) + EDBUG_RETURN_; + + r = is->bg.r; + g = is->bg.g; + b = is->bg.b; + is->bg.pixel = Imlib_best_color_match(id, &r, &g, &b); + + r = is->hi.r; + g = is->hi.g; + b = is->hi.b; + is->hi.pixel = Imlib_best_color_match(id, &r, &g, &b); + + r = is->lo.r; + g = is->lo.g; + b = is->lo.b; + is->lo.pixel = Imlib_best_color_match(id, &r, &g, &b); + + r = is->hihi.r; + g = is->hihi.g; + b = is->hihi.b; + is->hihi.pixel = Imlib_best_color_match(id, &r, &g, &b); + + r = is->lolo.r; + g = is->lolo.g; + b = is->lolo.b; + is->lolo.pixel = Imlib_best_color_match(id, &r, &g, &b); + + EDBUG_RETURN_; + +} + +void +IclassPopulate(ImageClass * iclass) +{ + ColorModifierClass *cm; + + EDBUG(6, "IclassPopulate"); + if ((!iclass) || (iclass->external)) + EDBUG_RETURN_; + + if (!iclass->norm.normal) + EDBUG_RETURN_; + + ImageStatePopulate(iclass->norm.normal); + if (!iclass->norm.hilited) + { + iclass->norm.hilited = iclass->norm.normal; + } + else + { + ImageStatePopulate(iclass->norm.hilited); + } + if (!iclass->norm.clicked) + { + iclass->norm.clicked = iclass->norm.normal; + } + else + { + ImageStatePopulate(iclass->norm.clicked); + } + if (!iclass->norm.disabled) + { + iclass->norm.disabled = iclass->norm.normal; + } + else + { + ImageStatePopulate(iclass->norm.disabled); + } + + if (!iclass->active.normal) + { + iclass->active.normal = iclass->norm.normal; + } + else + { + ImageStatePopulate(iclass->active.normal); + } + if (!iclass->active.hilited) + { + iclass->active.hilited = iclass->active.normal; + } + else + { + ImageStatePopulate(iclass->active.hilited); + } + if (!iclass->active.clicked) + { + iclass->active.clicked = iclass->active.normal; + } + else + { + ImageStatePopulate(iclass->active.clicked); + } + if (!iclass->active.disabled) + { + iclass->active.disabled = iclass->active.normal; + } + else + { + ImageStatePopulate(iclass->active.disabled); + } + + if (!iclass->sticky.normal) + { + iclass->sticky.normal = iclass->norm.normal; + } + else + { + ImageStatePopulate(iclass->sticky.normal); + } + if (!iclass->sticky.hilited) + { + iclass->sticky.hilited = iclass->sticky.normal; + } + else + { + ImageStatePopulate(iclass->sticky.hilited); + } + if (!iclass->sticky.clicked) + { + iclass->sticky.clicked = iclass->sticky.normal; + } + else + { + ImageStatePopulate(iclass->sticky.clicked); + } + if (!iclass->sticky.disabled) + { + iclass->sticky.disabled = iclass->sticky.normal; + } + else + { + ImageStatePopulate(iclass->sticky.disabled); + } + + if (!iclass->sticky_active.normal) + { + iclass->sticky_active.normal = iclass->norm.normal; + } + else + { + ImageStatePopulate(iclass->sticky_active.normal); + } + if (!iclass->sticky_active.hilited) + { + iclass->sticky_active.hilited = iclass->sticky_active.normal; + } + else + { + ImageStatePopulate(iclass->sticky_active.hilited); + } + if (!iclass->sticky_active.clicked) + { + iclass->sticky_active.clicked = iclass->sticky_active.normal; + } + else + { + ImageStatePopulate(iclass->sticky_active.clicked); + } + if (!iclass->sticky_active.disabled) + { + iclass->sticky_active.disabled = iclass->sticky_active.normal; + } + else + { + ImageStatePopulate(iclass->sticky_active.disabled); + } + + if (!iclass->colmod) + { + cm = (ColorModifierClass *) FindItem("ICLASS", 0, LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + if (!cm) + cm = (ColorModifierClass *) FindItem("DEFAULT", 0, LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + iclass->colmod = cm; + } + cm = (ColorModifierClass *) FindItem("NORMAL", 0, LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + if (!cm) + cm = iclass->colmod; + if (!iclass->norm.normal->colmod) + { + iclass->norm.normal->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + if (!iclass->norm.hilited->colmod) + { + iclass->norm.hilited->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + if (!iclass->norm.clicked->colmod) + { + iclass->norm.clicked->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + if (!iclass->norm.disabled->colmod) + { + iclass->norm.disabled->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + cm = (ColorModifierClass *) FindItem("ACTIVE", 0, LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + if (!cm) + cm = iclass->colmod; + if (!iclass->active.normal->colmod) + { + iclass->active.normal->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + if (!iclass->active.hilited->colmod) + { + iclass->active.hilited->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + if (!iclass->active.clicked->colmod) + { + iclass->active.clicked->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + if (!iclass->active.disabled->colmod) + { + iclass->active.disabled->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + cm = (ColorModifierClass *) FindItem("STICKY", 0, LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + if (!cm) + cm = iclass->colmod; + if (!iclass->sticky.normal->colmod) + { + iclass->sticky.normal->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + if (!iclass->sticky.hilited->colmod) + { + iclass->sticky.hilited->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + if (!iclass->sticky.clicked->colmod) + { + iclass->sticky.clicked->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + if (!iclass->sticky.disabled->colmod) + { + iclass->sticky.disabled->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + cm = (ColorModifierClass *) FindItem("STICKY_ACTIVE", 0, LIST_FINDBY_NAME, + LIST_TYPE_COLORMODIFIER); + if (!cm) + cm = iclass->colmod; + if (!iclass->sticky_active.normal->colmod) + { + iclass->sticky_active.normal->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + if (!iclass->sticky_active.hilited->colmod) + { + iclass->sticky_active.hilited->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + if (!iclass->sticky_active.clicked->colmod) + { + iclass->sticky_active.clicked->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + if (!iclass->sticky_active.disabled->colmod) + { + iclass->sticky_active.disabled->colmod = cm; + if (cm) + { + cm->ref_count++; + } + } + EDBUG_RETURN_; + +} + +void +IclassApply(ImageClass * iclass, Window win, int w, int h, + int active, int sticky, int state, char expose) +{ + ImageState *is; + + EDBUG(4, "IclassApply"); + + if ((!iclass) || (!win)) + EDBUG_RETURN_; + if (w < 0) + GetWinWH(win, &w, &h); + if ((w < 0) || (h < 0)) + EDBUG_RETURN_; + + if (queue_up) + { + DrawQueue *dq; + + dq = Emalloc(sizeof(DrawQueue)); + dq->win = win; + dq->iclass = iclass; + if (dq->iclass) + dq->iclass->ref_count++; + dq->w = w; + dq->h = h; + dq->active = active; + dq->sticky = sticky; + dq->state = state; + dq->expose = expose; + dq->tclass = NULL; + dq->text = NULL; + dq->shape_propagate = 0; + dq->pager = NULL; + dq->redraw_pager = NULL; + AddItem(dq, "DRAW", dq->win, LIST_TYPE_DRAW); + EDBUG_RETURN_; + } + if (iclass->external) + EDBUG_RETURN_; + + is = NULL; + + if (active) + { + if (!sticky) + { + switch (state) + { + case STATE_NORMAL: + is = iclass->active.normal; + break; + case STATE_HILITED: + is = iclass->active.hilited; + break; + case STATE_CLICKED: + is = iclass->active.clicked; + break; + case STATE_DISABLED: + is = iclass->active.disabled; + break; + default: + break; + } + } + else + { + switch (state) + { + case STATE_NORMAL: + is = iclass->sticky_active.normal; + break; + case STATE_HILITED: + is = iclass->sticky_active.hilited; + break; + case STATE_CLICKED: + is = iclass->sticky_active.clicked; + break; + case STATE_DISABLED: + is = iclass->sticky_active.disabled; + break; + default: + break; + } + } + } + else if (sticky) + { + switch (state) + { + case STATE_NORMAL: + is = iclass->sticky.normal; + break; + case STATE_HILITED: + is = iclass->sticky.hilited; + break; + case STATE_CLICKED: + is = iclass->sticky.clicked; + break; + case STATE_DISABLED: + is = iclass->sticky.disabled; + break; + default: + break; + } + } + else + { + switch (state) + { + case STATE_NORMAL: + is = iclass->norm.normal; + break; + case STATE_HILITED: + is = iclass->norm.hilited; + break; + case STATE_CLICKED: + is = iclass->norm.clicked; + break; + case STATE_DISABLED: + is = iclass->norm.disabled; + break; + default: + break; + } + } + + if (is) + { + XGCValues gcv; + GC gc; + Pixmap pmap, mask; + + if (!expose) + { + if (is->im_file) + { + /* has bg pixmap */ + if (!is->im) + { + /* not loaded, load and setup */ + if (!is->real_file) + is->real_file = FindFile(is->im_file); + is->im = ELoadImage(is->real_file); + if (is->border) + Imlib_set_image_border(id, is->im, is->border); + if (is->transp) + Imlib_set_image_shape(id, is->im, is->transp); + if (is->colmod) + { + Imlib_set_image_red_curve(id, is->im, + is->colmod->red.map); + Imlib_set_image_green_curve(id, is->im, + is->colmod->green.map); + Imlib_set_image_blue_curve(id, is->im, + is->colmod->blue.map); + } + } + if (is->im) + { + /* if image, render */ + if (is->pixmapfillstyle == FILL_STRETCH) + { + Imlib_render(id, is->im, w, h); + pmap = Imlib_move_image(id, is->im); + mask = Imlib_move_mask(id, is->im); + if (pmap) + { + ESetWindowBackgroundPixmap(disp, win, pmap); + EShapeCombineMask(disp, win, ShapeBounding, + 0, 0, mask, ShapeSet); + } + Imlib_free_pixmap(id, pmap); + } + else + { + int cw, ch, pw, ph; + Pixmap tm = 0; + GC gc; + XGCValues gcv; + + pw = w; + ph = h; + if (is->pixmapfillstyle & FILL_TILE_H) + pw = is->im->rgb_width; + if (is->pixmapfillstyle & FILL_TILE_V) + ph = is->im->rgb_height; + if (is->pixmapfillstyle & FILL_INT_TILE_H) + { + cw = w / is->im->rgb_width; + if (cw * is->im->rgb_width < w) + cw++; + if (cw < 1) + cw = 1; + pw = w / cw; + } + if (is->pixmapfillstyle & FILL_INT_TILE_V) + { + ch = h / is->im->rgb_height; + if (ch * is->im->rgb_height < h) + ch++; + if (ch < 1) + ch = 1; + ph = h / ch; + } + Imlib_render(id, is->im, pw, ph); + pmap = Imlib_move_image(id, is->im); + mask = Imlib_move_mask(id, is->im); + if (mask) + { + gcv.fill_style = FillTiled; + gcv.tile = mask; + gcv.ts_x_origin = 0; + gcv.ts_y_origin = 0; + tm = ECreatePixmap(disp, win, w, h, 1); + gc = XCreateGC(disp, tm, GCFillStyle | GCTile | + GCTileStipXOrigin | GCTileStipYOrigin, + &gcv); + XFillRectangle(disp, tm, gc, 0, 0, w, h); + XFreeGC(disp, gc); + EShapeCombineMask(disp, win, ShapeBounding, + 0, 0, tm, ShapeSet); + EFreePixmap(disp, tm); + } + Imlib_free_pixmap(id, pmap); + ESetWindowBackgroundPixmap(disp, win, pmap); + } + } + } + if (!is->im) + { + /* bg color */ + ESetWindowBackground(disp, win, is->bg.pixel); + } + else if (is->im_file) + { + /* if unloadable - then unload */ + if ((is->unloadable) || (mode.memory_paranoia)) + { + Imlib_destroy_image(id, is->im); + is->im = NULL; + } + } + } + XClearWindow(disp, win); + /* if there is a bevel to draw, draw it */ + if (is->bevelstyle != BEVEL_NONE) + { + gc = XCreateGC(disp, win, 0, &gcv); + switch (is->bevelstyle) + { + case BEVEL_AMIGA: + XSetForeground(disp, gc, is->hihi.pixel); + XDrawLine(disp, win, gc, 0, 0, w - 2, 0); + XDrawLine(disp, win, gc, 0, 0, 0, h - 2); + XSetForeground(disp, gc, is->lolo.pixel); + XDrawLine(disp, win, gc, 1, h - 1, w - 1, h - 1); + XDrawLine(disp, win, gc, w - 1, 1, w - 1, h - 1); + break; + case BEVEL_MOTIF: + XSetForeground(disp, gc, is->hi.pixel); + XDrawLine(disp, win, gc, 0, 0, w - 1, 0); + XDrawLine(disp, win, gc, 0, 0, 0, h - 1); + XDrawLine(disp, win, gc, 1, 1, w - 2, 1); + XDrawLine(disp, win, gc, 1, 1, 1, h - 2); + XSetForeground(disp, gc, is->lo.pixel); + XDrawLine(disp, win, gc, 0, h - 1, w - 1, h - 1); + XDrawLine(disp, win, gc, w - 1, 1, w - 1, h - 1); + XDrawLine(disp, win, gc, 1, h - 2, w - 2, h - 2); + XDrawLine(disp, win, gc, w - 2, 2, w - 2, h - 2); + break; + case BEVEL_NEXT: + XSetForeground(disp, gc, is->hihi.pixel); + XDrawLine(disp, win, gc, 0, 0, w - 1, 0); + XDrawLine(disp, win, gc, 0, 0, 0, h - 1); + XSetForeground(disp, gc, is->hi.pixel); + XDrawLine(disp, win, gc, 1, 1, w - 2, 1); + XDrawLine(disp, win, gc, 1, 1, 1, h - 2); + XSetForeground(disp, gc, is->lolo.pixel); + XDrawLine(disp, win, gc, 1, h - 1, w - 1, h - 1); + XDrawLine(disp, win, gc, w - 1, 1, w - 1, h - 1); + XSetForeground(disp, gc, is->lo.pixel); + XDrawLine(disp, win, gc, 2, h - 2, w - 2, h - 2); + XDrawLine(disp, win, gc, w - 2, 2, w - 2, h - 2); + break; + case BEVEL_DOUBLE: + XSetForeground(disp, gc, is->hi.pixel); + XDrawLine(disp, win, gc, 0, 0, w - 2, 0); + XDrawLine(disp, win, gc, 0, 0, 0, h - 2); + XSetForeground(disp, gc, is->lo.pixel); + XDrawLine(disp, win, gc, 1, 1, w - 3, 1); + XDrawLine(disp, win, gc, 1, 1, 1, h - 3); + XSetForeground(disp, gc, is->lo.pixel); + XDrawLine(disp, win, gc, 1, h - 1, w - 1, h - 1); + XDrawLine(disp, win, gc, w - 1, 1, w - 1, h - 1); + XSetForeground(disp, gc, is->hi.pixel); + XDrawLine(disp, win, gc, 2, h - 2, w - 2, h - 2); + XDrawLine(disp, win, gc, w - 2, 2, w - 2, h - 2); + break; + case BEVEL_WIDEDOUBLE: + XSetForeground(disp, gc, is->hihi.pixel); + XDrawLine(disp, win, gc, 0, 0, w - 1, 0); + XDrawLine(disp, win, gc, 0, 0, 0, h - 1); + XSetForeground(disp, gc, is->hi.pixel); + XDrawLine(disp, win, gc, 1, 1, w - 2, 1); + XDrawLine(disp, win, gc, 1, 1, 1, h - 2); + XDrawLine(disp, win, gc, 3, h - 4, w - 4, h - 4); + XDrawLine(disp, win, gc, w - 4, 3, w - 4, h - 4); + XSetForeground(disp, gc, is->lolo.pixel); + XDrawLine(disp, win, gc, 1, h - 1, w - 1, h - 1); + XDrawLine(disp, win, gc, w - 1, 1, w - 1, h - 1); + XSetForeground(disp, gc, is->lo.pixel); + XDrawLine(disp, win, gc, 2, h - 2, w - 2, h - 2); + XDrawLine(disp, win, gc, w - 2, 2, w - 2, h - 2); + XDrawLine(disp, win, gc, 3, 3, w - 4, 3); + XDrawLine(disp, win, gc, 3, 3, 3, h - 4); + break; + case BEVEL_THINPOINT: + XSetForeground(disp, gc, is->hi.pixel); + XDrawLine(disp, win, gc, 0, 0, w - 2, 0); + XDrawLine(disp, win, gc, 0, 0, 0, h - 2); + XSetForeground(disp, gc, is->lo.pixel); + XDrawLine(disp, win, gc, 1, h - 1, w - 1, h - 1); + XDrawLine(disp, win, gc, w - 1, 1, w - 1, h - 1); + XSetForeground(disp, gc, is->hihi.pixel); + XDrawLine(disp, win, gc, 0, 0, 1, 0); + XDrawLine(disp, win, gc, 0, 0, 0, 1); + XSetForeground(disp, gc, is->lolo.pixel); + XDrawLine(disp, win, gc, w - 2, h - 1, w - 1, h - 1); + XDrawLine(disp, win, gc, w - 1, h - 2, w - 1, h - 1); + XSync(disp, False); + break; + case BEVEL_THICKPOINT: + XSetForeground(disp, gc, is->hi.pixel); + XDrawRectangle(disp, win, gc, 0, 0, w - 1, h - 1); + break; + default: + break; + } + XFreeGC(disp, gc); + } + } + EDBUG_RETURN_; +} + +void +IclassApplyCopy(ImageClass * iclass, Window win, int w, int h, int active, + int sticky, int state, Pixmap * pret, Pixmap * mret) +{ + ImageState *is; + + EDBUG(4, "IclassApply"); + if ((!iclass) || (!win) || (w < 1) || (h < 1) || (!pret)) + EDBUG_RETURN_; + + *pret = 0; + if (mret) + *mret = 0; + + if (iclass->external) + EDBUG_RETURN_; + is = NULL; + + if (active) + { + if (!sticky) + { + switch (state) + { + case STATE_NORMAL: + is = iclass->active.normal; + break; + case STATE_HILITED: + is = iclass->active.hilited; + break; + case STATE_CLICKED: + is = iclass->active.clicked; + break; + case STATE_DISABLED: + is = iclass->active.disabled; + break; + default: + break; + } + } + else + { + switch (state) + { + case STATE_NORMAL: + is = iclass->sticky_active.normal; + break; + case STATE_HILITED: + is = iclass->sticky_active.hilited; + break; + case STATE_CLICKED: + is = iclass->sticky_active.clicked; + break; + case STATE_DISABLED: + is = iclass->sticky_active.disabled; + break; + default: + break; + } + } + } + else if (sticky) + { + switch (state) + { + case STATE_NORMAL: + is = iclass->sticky.normal; + break; + case STATE_HILITED: + is = iclass->sticky.hilited; + break; + case STATE_CLICKED: + is = iclass->sticky.clicked; + break; + case STATE_DISABLED: + is = iclass->sticky.disabled; + break; + default: + break; + } + } + else + { + switch (state) + { + case STATE_NORMAL: + is = iclass->norm.normal; + break; + case STATE_HILITED: + is = iclass->norm.hilited; + break; + case STATE_CLICKED: + is = iclass->norm.clicked; + break; + case STATE_DISABLED: + is = iclass->norm.disabled; + break; + default: + break; + } + } + + if (is) + { + XGCValues gcv; + GC gc; + + if (is->im_file) + { + /* has bg pixmap */ + if (!is->im) + { + ImageStateRealize(is); + } + if (is->im) + { + /* if image, render */ + if (is->pixmapfillstyle == FILL_STRETCH) + { + Imlib_render(id, is->im, w, h); + *pret = Imlib_copy_image(id, is->im); + if (mret) + *mret = Imlib_copy_mask(id, is->im); + /* if unloadable - then unload */ + if ((is->unloadable) || (mode.memory_paranoia)) + { + Imlib_destroy_image(id, is->im); + is->im = NULL; + } + EDBUG_RETURN_; + } + else + { + int cw, ch, pw, ph; + Pixmap pmap, mask, tp = 0, tm = 0; + GC gc; + XGCValues gcv; + + pw = w; + ph = h; + if (is->pixmapfillstyle & FILL_TILE_H) + pw = is->im->rgb_width; + if (is->pixmapfillstyle & FILL_TILE_V) + ph = is->im->rgb_height; + if (is->pixmapfillstyle & FILL_INT_TILE_H) + { + cw = w / is->im->rgb_width; + if (cw * is->im->rgb_width < w) + cw++; + if (cw < 1) + cw = 1; + pw = w / cw; + } + if (is->pixmapfillstyle & FILL_INT_TILE_V) + { + ch = h / is->im->rgb_height; + if (ch * is->im->rgb_height < h) + ch++; + if (ch < 1) + ch = 1; + ph = h / ch; + } + Imlib_render(id, is->im, pw, ph); + pmap = Imlib_move_image(id, is->im); + mask = Imlib_move_mask(id, is->im); + tp = ECreatePixmap(disp, win, w, h, id->x.depth); + if ((mret) && (mask)) + tm = ECreatePixmap(disp, win, w, h, 1); + gcv.fill_style = FillTiled; + gcv.tile = pmap; + gcv.ts_x_origin = 0; + gcv.ts_y_origin = 0; + gc = XCreateGC(disp, tp, GCFillStyle | GCTile | + GCTileStipXOrigin | GCTileStipYOrigin, + &gcv); + XFillRectangle(disp, tp, gc, 0, 0, w, h); + XFreeGC(disp, gc); + if ((mret) && (mask)) + { + gcv.fill_style = FillTiled; + gcv.tile = mask; + gcv.ts_x_origin = 0; + gcv.ts_y_origin = 0; + gc = XCreateGC(disp, tm, GCFillStyle | GCTile | + GCTileStipXOrigin | GCTileStipYOrigin, + &gcv); + XFillRectangle(disp, tm, gc, 0, 0, w, h); + XFreeGC(disp, gc); + } + *pret = tp; + if (mret) + *mret = tm; + Imlib_free_pixmap(id, pmap); + /* if unloadable - then unload */ + if ((is->unloadable) || (mode.memory_paranoia)) + { + Imlib_destroy_image(id, is->im); + is->im = NULL; + } + EDBUG_RETURN_; + } + } + } + /* if there is a bevel to draw, draw it */ + if (is->bevelstyle != BEVEL_NONE) + { + *pret = ECreatePixmap(disp, win, w, h, id->x.depth); + gc = XCreateGC(disp, *pret, 0, &gcv); + /* bg color */ + XSetForeground(disp, gc, is->bg.pixel); + XFillRectangle(disp, *pret, gc, 0, 0, w, h); + switch (is->bevelstyle) + { + case BEVEL_AMIGA: + XSetForeground(disp, gc, is->hihi.pixel); + XDrawLine(disp, *pret, gc, 0, 0, w - 2, 0); + XDrawLine(disp, *pret, gc, 0, 0, 0, h - 2); + XSetForeground(disp, gc, is->lolo.pixel); + XDrawLine(disp, *pret, gc, 1, h - 1, w - 1, h - 1); + XDrawLine(disp, *pret, gc, w - 1, 1, w - 1, h - 1); + break; + case BEVEL_MOTIF: + XSetForeground(disp, gc, is->hi.pixel); + XDrawLine(disp, *pret, gc, 0, 0, w - 1, 0); + XDrawLine(disp, *pret, gc, 0, 0, 0, h - 1); + XDrawLine(disp, *pret, gc, 1, 1, w - 2, 1); + XDrawLine(disp, *pret, gc, 1, 1, 1, h - 2); + XSetForeground(disp, gc, is->lo.pixel); + XDrawLine(disp, *pret, gc, 0, h - 1, w - 1, h - 1); + XDrawLine(disp, *pret, gc, w - 1, 1, w - 1, h - 1); + XDrawLine(disp, *pret, gc, 1, h - 2, w - 2, h - 2); + XDrawLine(disp, *pret, gc, w - 2, 2, w - 2, h - 2); + break; + case BEVEL_NEXT: + XSetForeground(disp, gc, is->hihi.pixel); + XDrawLine(disp, *pret, gc, 0, 0, w - 1, 0); + XDrawLine(disp, *pret, gc, 0, 0, 0, h - 1); + XSetForeground(disp, gc, is->hi.pixel); + XDrawLine(disp, *pret, gc, 1, 1, w - 2, 1); + XDrawLine(disp, *pret, gc, 1, 1, 1, h - 2); + XSetForeground(disp, gc, is->lolo.pixel); + XDrawLine(disp, *pret, gc, 1, h - 1, w - 1, h - 1); + XDrawLine(disp, *pret, gc, w - 1, 1, w - 1, h - 1); + XSetForeground(disp, gc, is->lo.pixel); + XDrawLine(disp, *pret, gc, 2, h - 2, w - 2, h - 2); + XDrawLine(disp, *pret, gc, w - 2, 2, w - 2, h - 2); + break; + case BEVEL_DOUBLE: + XSetForeground(disp, gc, is->hi.pixel); + XDrawLine(disp, *pret, gc, 0, 0, w - 2, 0); + XDrawLine(disp, *pret, gc, 0, 0, 0, h - 2); + XSetForeground(disp, gc, is->lo.pixel); + XDrawLine(disp, *pret, gc, 1, 1, w - 3, 1); + XDrawLine(disp, *pret, gc, 1, 1, 1, h - 3); + XSetForeground(disp, gc, is->lo.pixel); + XDrawLine(disp, *pret, gc, 1, h - 1, w - 1, h - 1); + XDrawLine(disp, *pret, gc, w - 1, 1, w - 1, h - 1); + XSetForeground(disp, gc, is->hi.pixel); + XDrawLine(disp, *pret, gc, 2, h - 2, w - 2, h - 2); + XDrawLine(disp, *pret, gc, w - 2, 2, w - 2, h - 2); + break; + case BEVEL_WIDEDOUBLE: + XSetForeground(disp, gc, is->hihi.pixel); + XDrawLine(disp, *pret, gc, 0, 0, w - 1, 0); + XDrawLine(disp, *pret, gc, 0, 0, 0, h - 1); + XSetForeground(disp, gc, is->hi.pixel); + XDrawLine(disp, *pret, gc, 1, 1, w - 2, 1); + XDrawLine(disp, *pret, gc, 1, 1, 1, h - 2); + XDrawLine(disp, *pret, gc, 3, h - 4, w - 4, h - 4); + XDrawLine(disp, *pret, gc, w - 4, 3, w - 4, h - 4); + XSetForeground(disp, gc, is->lolo.pixel); + XDrawLine(disp, *pret, gc, 1, h - 1, w - 1, h - 1); + XDrawLine(disp, *pret, gc, w - 1, 1, w - 1, h - 1); + XSetForeground(disp, gc, is->lo.pixel); + XDrawLine(disp, *pret, gc, 2, h - 2, w - 2, h - 2); + XDrawLine(disp, *pret, gc, w - 2, 2, w - 2, h - 2); + XDrawLine(disp, *pret, gc, 3, 3, w - 4, 3); + XDrawLine(disp, *pret, gc, 3, 3, 3, h - 4); + break; + case BEVEL_THINPOINT: + XSetForeground(disp, gc, is->hi.pixel); + XDrawLine(disp, *pret, gc, 0, 0, w - 2, 0); + XDrawLine(disp, *pret, gc, 0, 0, 0, h - 2); + XSetForeground(disp, gc, is->lo.pixel); + XDrawLine(disp, *pret, gc, 1, h - 1, w - 1, h - 1); + XDrawLine(disp, *pret, gc, w - 1, 1, w - 1, h - 1); + XSetForeground(disp, gc, is->hihi.pixel); + XDrawLine(disp, *pret, gc, 0, 0, 1, 0); + XDrawLine(disp, *pret, gc, 0, 0, 0, 1); + XSetForeground(disp, gc, is->lolo.pixel); + XDrawLine(disp, *pret, gc, w - 2, h - 1, w - 1, h - 1); + XDrawLine(disp, *pret, gc, w - 1, h - 2, w - 1, h - 1); + XSync(disp, False); + break; + case BEVEL_THICKPOINT: + XSetForeground(disp, gc, is->hi.pixel); + XDrawRectangle(disp, *pret, gc, 0, 0, w - 1, h - 1); + break; + default: + break; + } + XFreeGC(disp, gc); + } + } + EDBUG_RETURN_; + +} + +void +ImageStateRealize(ImageState * is) +{ + if (is) + { + if (is->im_file) + { + /* has bg pixmap */ + if (!is->im) + { + /* not loaded, load and setup */ + if (!is->real_file) + is->real_file = FindFile(is->im_file); + is->im = ELoadImage(is->real_file); + if (is->border) + Imlib_set_image_border(id, is->im, is->border); + if (is->transp) + Imlib_set_image_shape(id, is->im, is->transp); + if (is->colmod) + { + Imlib_set_image_red_curve(id, is->im, + is->colmod->red.map); + Imlib_set_image_green_curve(id, is->im, + is->colmod->green.map); + Imlib_set_image_blue_curve(id, is->im, + is->colmod->blue.map); + } + } + } + } +} diff --git a/src/iconify.c b/src/iconify.c new file mode 100644 index 00000000..f9338538 --- /dev/null +++ b/src/iconify.c @@ -0,0 +1,2149 @@ +#include "E.h" + +static void IcondefChecker(int val, void *data); + +void +IconifyEwin(EWin * ewin) +{ + static int call_depth = 0; + + if (!ewin) + EDBUG_RETURN_; + if (GetZoomEWin() == ewin) + Zoom(NULL); + if (ewin->ibox) + EDBUG_RETURN_; + if (ewin->client.need_input) + { + if ((ewin->skiptask) || (ewin->skipwinlist)) + EDBUG_RETURN_; + } + call_depth++; + if (call_depth > 256) + { + call_depth--; + return; + } + if (!ewin->iconified) + { + Iconbox *ib; + + ib = SelectIconboxForEwin(ewin); + if (ib) + UpdateAppIcon(ewin, ib->icon_mode); + HideEwin(ewin); + MakeIcon(ewin); + ICCCM_Iconify(ewin); + if (ewin == mode.focuswin) + FocusToEWin(NULL); + } + if (ewin->has_transients) + { + EWin **lst; + int i, num; + + lst = ListTransientsFor(ewin->client.win, &num); + if (lst) + { + for (i = 0; i < num; i++) + { + IconifyEwin(lst[i]); + if (lst[i] == mode.focuswin) + FocusToEWin(NULL); + } + Efree(lst); + } + } + call_depth--; +} + +void +DeIconifyEwin(EWin * ewin) +{ + static int call_depth = 0; + + call_depth++; + if (call_depth > 256) + { + call_depth--; + return; + } + if (ewin->iconified) + { + RemoveMiniIcon(ewin); + if (!ewin->sticky) + { + MoveEwinToDesktopAt(ewin, desks.current, ewin->x, ewin->y); + MoveEwinToArea(ewin, + desks.desk[desks.current].current_area_x, + desks.desk[desks.current].current_area_y); + } + else + ConformEwinToDesktop(ewin); + RaiseEwin(ewin); + ShowEwin(ewin); + ICCCM_DeIconify(ewin); + FocusToEWin(ewin); + mode.destroy = 1; + } + if (ewin->has_transients) + { + EWin **lst; + int i, num; + + lst = ListTransientsFor(ewin->client.win, &num); + if (lst) + { + for (i = 0; i < num; i++) + DeIconifyEwin(lst[i]); + Efree(lst); + } + } + call_depth--; +} + +void +MakeIcon(EWin * ewin) +{ + Iconbox *ib; + + ib = SelectIconboxForEwin(ewin); + if (ib) + AddEwinToIconbox(ib, ewin); +} + +void +RemoveMiniIcon(EWin * ewin) +{ + Iconbox *ib; + + ib = SelectIconboxForEwin(ewin); + if (ib) + DelEwinFromIconbox(ib, ewin); +} + +void +HideIcons(void) +{ + /* ummmmmmmmmm don't need this anymore - but it used to hide the icons */ + /* when a the gnome pager came up */ +} + +void +ShowIcons(void) +{ + /* ummmmmmmmmm don't need this anymore - but it used to show the icons */ + /* when a the gnome pager came up */ +} + +void +HandlePager(void) +{ + Window *w1, *w2; + int size; + static Atom pga = 0; + + if (!pga) + pga = XInternAtom(disp, "_GNOME_PAGER_ACTIVE", False); + external_pager_window = 0; + w1 = (Window *) AtomGet(root.win, pga, XA_WINDOW, &size); + if (w1) + { + if (WinExists(*w1)) + { + w2 = (Window *) AtomGet(*w1, pga, XA_WINDOW, &size); + if (w2) + { + XSelectInput(disp, *w2, StructureNotifyMask | + SubstructureNotifyMask); + external_pager_window = *w2; + HideIcons(); + Efree(w2); + } + } + Efree(w1); + } +} + +Iconbox * +CreateIconbox(char *name) +{ + Iconbox *ib; + + ib = Emalloc(sizeof(Iconbox)); + ib->name = duplicate(name); + ib->orientation = 0; + ib->scrollbar_side = 1; + ib->arrow_side = 1; + ib->nobg = 0; + ib->shownames = 1; + ib->iconsize = 48; + ib->icon_mode = 2; + ib->auto_resize = 0; + ib->draw_icon_base = 0; + ib->scrollbar_hide = 0; + /* FIXME: need to have theme settable params for this and get them */ + ib->scroll_thickness = 12; + ib->arrow_thickness = 12; + ib->bar_thickness = 8; + ib->knob_length = 8; + + ib->w = 0; + ib->h = 0; + ib->pos = 0; + ib->max = 1; + ib->arrow1_hilited = 0; + ib->arrow1_clicked = 0; + ib->arrow2_hilited = 0; + ib->arrow2_clicked = 0; + ib->icon_clicked = 0; + ib->scrollbar_hilited = 0; + ib->scrollbar_clicked = 0; + ib->scrollbox_clicked = 0; + ib->win = ECreateWindow(root.win, 0, 0, 128, 32, 0); + ib->icon_win = ECreateWindow(ib->win, 0, 0, 128, 26, 0); + ib->cover_win = ECreateWindow(ib->win, 0, 0, 128, 26, 0); + ib->scroll_win = ECreateWindow(ib->win, 6, 26, 116, 6, 0); + ib->arrow1_win = ECreateWindow(ib->win, 0, 26, 6, 6, 0); + ib->arrow2_win = ECreateWindow(ib->win, 122, 26, 6, 6, 0); + ib->scrollbar_win = ECreateWindow(ib->scroll_win, 122, 26, 6, 6, 0); + ib->scrollbarknob_win = ECreateWindow(ib->scrollbar_win, -20, -20, 4, 4, 0); + ib->pmap = ECreatePixmap(disp, ib->icon_win, 128, 32, id->x.depth); + XSelectInput(disp, ib->icon_win, EnterWindowMask | LeaveWindowMask | + ButtonPressMask | ButtonReleaseMask); + XSelectInput(disp, ib->scroll_win, EnterWindowMask | LeaveWindowMask | + ButtonPressMask | ButtonReleaseMask); + XSelectInput(disp, ib->arrow1_win, EnterWindowMask | LeaveWindowMask | + ButtonPressMask | ButtonReleaseMask); + XSelectInput(disp, ib->arrow2_win, EnterWindowMask | LeaveWindowMask | + ButtonPressMask | ButtonReleaseMask); + XSelectInput(disp, ib->scrollbar_win, EnterWindowMask | LeaveWindowMask | + ButtonPressMask | ButtonReleaseMask | PointerMotionMask); + EMapWindow(disp, ib->icon_win); + EMapWindow(disp, ib->scroll_win); + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMapWindow(disp, ib->scrollbar_win); + EMapWindow(disp, ib->scrollbarknob_win); + ib->ewin = NULL; + ib->num_icons = 0; + ib->icons = NULL; + AddItem(ib, ib->name, 0, LIST_TYPE_ICONBOX); + return ib; +} + +void +FreeIconbox(Iconbox * ib) +{ + int i; + + RemoveItem((char *)ib, 0, LIST_FINDBY_POINTER, LIST_TYPE_ICONBOX); + if (ib->name) + Efree(ib->name); + for (i = 0; i < ib->num_icons; i++) + DeIconifyEwin(ib->icons[i]); + if (ib->icons) + Efree(ib->icons); + if (ib->pmap) + EFreePixmap(disp, ib->pmap); + EDestroyWindow(disp, ib->win); + Efree(ib); + autosave(); +} + +void +ShowIconbox(Iconbox * ib) +{ + EWin *ewin = NULL; + XClassHint *xch; + + xch = XAllocClassHint(); + xch->res_name = ib->name; + xch->res_class = "Enlightenment_IconBox"; + XSetClassHint(disp, ib->win, xch); + XFree(xch); + ewin = AddInternalToFamily(ib->win, 1, "ICONBOX"); + if (ewin) + { + Snapshot *sn; + + ib->ewin = ewin; + ewin->client.width.min = 8; + ewin->client.height.min = 8; + ewin->client.width.max = 16384; + ewin->client.height.max = 16384; + ewin->client.no_resize_h = 0; + ewin->client.no_resize_v = 0; + if (ib->orientation) + { + ImageClass *ic; + int extra = 0; + + ic = FindItem("ICONBOX_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + extra = ic->padding.left + ic->padding.right; + ib->ewin->client.width.max = + ib->ewin->client.width.min = + ib->iconsize + ib->scroll_thickness + extra; + ewin->client.no_resize_h = 1; + } + else + { + ImageClass *ic; + int extra = 0; + + ic = FindItem("ICONBOX_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + extra = ic->padding.left + ic->padding.right; + ib->ewin->client.height.max = + ib->ewin->client.height.min = + ib->iconsize + ib->scroll_thickness + extra; + ewin->client.no_resize_v = 1; + } + ewin->desktop = desks.current; + ewin->ibox = ib; + DesktopRemoveEwin(ewin); + ewin->sticky = 1; + ResizeEwin(ewin, 160, 160); + sn = FindSnapshot(ewin); + /* get the size right damnit! */ + if (sn) + { + if (sn->use_wh) + ResizeEwin(ewin, sn->w, sn->h); + if (sn->use_xy) + MoveEwin(ewin, sn->x, sn->y); + } + else + MoveEwin(ewin, 0, 0); + DesktopAddEwinToTop(ewin); + RestackEwin(ewin); + ShowEwin(ewin); + SnapshotEwinBorder(ewin); + SnapshotEwinDesktop(ewin); + SnapshotEwinSize(ewin); + SnapshotEwinLocation(ewin); + SnapshotEwinLayer(ewin); + SnapshotEwinSticky(ewin); + SnapshotEwinShade(ewin); + } + IconboxResize(ib, ib->ewin->client.w, ib->ewin->client.h); +} + +void +HideIconbox(Iconbox * ib) +{ + if (ib->ewin) + HideEwin(ib->ewin); +} + +void +AddEwinToIconbox(Iconbox * ib, EWin * ewin) +{ + int i; + + /* check if its already there - then dont add */ + for (i = 0; i < ib->num_icons; i++) + { + if (ib->icons[i] == ewin) + return; + } + ib->num_icons++; + ib->icons = Erealloc(ib->icons, sizeof(EWin *) * ib->num_icons); + ib->icons[ib->num_icons - 1] = ewin; + RedrawIconbox(ib); +} + +void +DelEwinFromIconbox(Iconbox * ib, EWin * ewin) +{ + int i, j; + + for (i = 0; i < ib->num_icons; i++) + { + if (ib->icons[i] == ewin) + { + for (j = i; j < ib->num_icons - 1; j++) + ib->icons[j] = ib->icons[j + 1]; + ib->num_icons--; + if (ib->num_icons > 0) + ib->icons = Erealloc(ib->icons, sizeof(EWin *) * ib->num_icons); + else + { + Efree(ib->icons); + ib->icons = NULL; + } + RedrawIconbox(ib); + return; + } + } +} + +void +IB_SnapEWin(EWin * ewin) +{ + int w, h, ord, rn, i; + GC gc; + XGCValues gcv; + XRectangle *r = NULL; + Iconbox *ib; + + if (!ewin->visible) + return; + w = 40; + h = 40; + ib = SelectIconboxForEwin(ewin); + if (ib) + { + w = ib->iconsize; + h = ib->iconsize; + } + if (ewin->w > ewin->h) + h = (w * ewin->h) / ewin->w; + else + w = (h * ewin->w) / ewin->h; + ewin->icon_pmap_w = w; + ewin->icon_pmap_h = h; + ewin->icon_pmap = ECreatePixmap(disp, ewin->win, w, h, id->x.depth); + PagerScaleRect(ewin->icon_pmap, ewin->win, + 0, 0, 0, 0, + ewin->w, ewin->h, w, h); + r = EShapeGetRectangles(disp, ewin->win, ShapeBounding, &rn, &ord); + ewin->icon_mask = ECreatePixmap(disp, ewin->win, w, h, 1); + gc = XCreateGC(disp, ewin->icon_mask, 0, &gcv); + if (r) + { + XSetForeground(disp, gc, 0); + XFillRectangle(disp, ewin->icon_mask, gc, 0, 0, w, h); + XSetForeground(disp, gc, 1); + for (i = 0; i < rn; i++) + { + int x, y, ww, hh; + + x = (r[i].x * w) / ewin->w; + y = (r[i].y * h) / ewin->h; + ww = (r[i].width * w) / ewin->w; + hh = (r[i].height * h) / ewin->h; + if (ww < 1) + ww = 1; + if (hh < 1) + hh = 1; + XFillRectangle(disp, ewin->icon_mask, gc, x, y, ww, hh); + } + XFree(r); + } + else + { + XSetForeground(disp, gc, 1); + XFillRectangle(disp, ewin->icon_mask, gc, 0, 0, w, h); + } + XFreeGC(disp, gc); + if ((ewin->icon_pmap_w < 1) || (ewin->icon_pmap_h < 1)) + { + if (ewin->icon_pmap) + Imlib_free_pixmap(id, ewin->icon_pmap); + if (ewin->icon_mask) + Imlib_free_pixmap(id, ewin->icon_mask); + ewin->icon_pmap = 0; + ewin->icon_mask = 0; + } +} + +void +IB_GetAppIcon(EWin * ewin) +{ + /* get the applications icon pixmap and make a copy... */ + int x, y; + unsigned int w, h, depth, bw; + Window rt; + + if (!ewin->client.icon_pmap) + return; + w = 0; + h = 0; + EGetGeometry(disp, ewin->client.icon_pmap, &rt, &x, &y, &w, &h, &bw, &depth); + ewin->icon_pmap_w = (int)w; + ewin->icon_pmap_h = (int)h; + ewin->icon_pmap = ECreatePixmap(disp, root.win, w, h, root.depth); + if (ewin->client.icon_mask) + ewin->icon_mask = ECreatePixmap(disp, root.win, w, h, 1); + if (depth == 1) + { + GC gc; + XGCValues gcv; + int r, g, b; + + gc = XCreateGC(disp, ewin->icon_pmap, 0, &gcv); + r = 255; + g = 255; + b = 255; + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + XFillRectangle(disp, ewin->icon_pmap, gc, 0, 0, w, h); + r = 0; + g = 0; + b = 0; + XSetClipOrigin(disp, gc, 0, 0); + XSetClipMask(disp, gc, ewin->client.icon_pmap); + XSetForeground(disp, gc, Imlib_best_color_match(id, &r, &g, &b)); + XFillRectangle(disp, ewin->icon_pmap, gc, 0, 0, w, h); + XFreeGC(disp, gc); + } + else + EPastePixmap(ewin->icon_pmap, ewin->client.icon_pmap, 0, 0, w, h); + if (ewin->client.icon_mask) + EPastePixmap(ewin->icon_mask, ewin->client.icon_mask, 0, 0, w, h); + if ((ewin->icon_pmap_w < 1) || (ewin->icon_pmap_h < 1)) + { + if (ewin->icon_pmap) + Imlib_free_pixmap(id, ewin->icon_pmap); + if (ewin->icon_mask) + Imlib_free_pixmap(id, ewin->icon_mask); + ewin->icon_pmap = 0; + ewin->icon_mask = 0; + } +} + +void +IB_PasteDefaultBase(Drawable d, int x, int y, int w, int h) +{ + ImageClass *ic; + Pixmap p, m; + + /* get the base pixmap */ + ic = FindItem("DEFAULT_ICON_BUTTON", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (!ic) + return; + IclassApplyCopy(ic, d, w, h, 0, 0, STATE_NORMAL, &p, &m); + PastePixmap(disp, d, p, m, x, y); + Imlib_free_pixmap(id, p); + Imlib_free_pixmap(id, m); +} + +void +IB_PasteDefaultBaseMask(Drawable d, int x, int y, int w, int h) +{ + ImageClass *ic; + Pixmap p, m; + GC gc; + XGCValues gcv; + + /* get the base pixmap */ + ic = FindItem("DEFAULT_ICON_BUTTON", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (!ic) + return; + IclassApplyCopy(ic, d, w, h, 0, 0, STATE_NORMAL, &p, &m); + if (m) + { + PasteMask(disp, d, m, x, y, w, h); + Imlib_free_pixmap(id, m); + } + else + { + gc = XCreateGC(disp, d, 0, &gcv); + XSetForeground(disp, gc, 1); + XFillRectangle(disp, d, gc, x, y, w, h); + XFreeGC(disp, gc); + } + Imlib_free_pixmap(id, p); +} + +void +IB_GetEIcon(EWin * ewin) +{ + /* get the icon defined for this window in E's iconf match file */ + Icondef *idef; + + idef = IB_MatchIcondef(ewin->client.title, ewin->client.name, ewin->client.class); + + if (!idef) + return; + { + ImlibImage *im; + + im = ELoadImage(idef->icon_file); + if (im) + { + Imlib_render(id, im, im->rgb_width, im->rgb_height); + ewin->icon_pmap = Imlib_move_image(id, im); + ewin->icon_mask = Imlib_move_mask(id, im); + ewin->icon_pmap_w = im->rgb_width; + ewin->icon_pmap_h = im->rgb_height; + Imlib_destroy_image(id, im); + } + } +} + +void +IB_AddIcondef(char *title, char *name, char *class, char *file) +{ + /* add match for a window pointing to an iconfile */ + /* form: "*term*" "name*" "*class" "path/to_image.png" */ + Icondef *idef; + + idef = Emalloc(sizeof(Icondef)); + if (!idef) + return; + idef->title_match = duplicate(title); + idef->name_match = duplicate(name); + idef->class_match = duplicate(class); + idef->icon_file = duplicate(file); + AddItem(idef, "", 0, LIST_TYPE_ICONDEF); +} + +void +IB_RemoveIcondef(Icondef * idef) +{ + /* remove the pointed to icondef from our database */ + Icondef *idef2; + + idef2 = RemoveItem((char *)idef, 0, LIST_FINDBY_POINTER, LIST_TYPE_ICONDEF); + if (!idef2) + return; + if (idef->title_match) + Efree(idef->title_match); + if (idef->name_match) + Efree(idef->name_match); + if (idef->class_match) + Efree(idef->class_match); + if (idef->icon_file) + Efree(idef->icon_file); + Efree(idef); +} + +Icondef * +IB_MatchIcondef(char *title, char *name, char *class) +{ + /* return an icondef that matches the data given */ + Icondef **il, *idef; + int i, num; + + il = IB_ListIcondef(&num); + if (il) + { + for (i = 0; i < num; i++) + { + char match = 1; + + if ((il[i]->title_match) && (!title)) + match = 0; + if ((il[i]->name_match) && (!name)) + match = 0; + if ((il[i]->class_match) && (!class)) + match = 0; + if ((il[i]->title_match) && (title)) + { + if (!matchregexp(il[i]->title_match, title)) + match = 0; + } + if ((il[i]->name_match) && (name)) + { + if (!matchregexp(il[i]->name_match, name)) + match = 0; + } + if ((il[i]->class_match) && (class)) + { + if (!matchregexp(il[i]->class_match, class)) + match = 0; + } + if (match) + { + idef = il[i]; + Efree(il); + return idef; + } + } + Efree(il); + } + return NULL; +} + +Icondef ** +IB_ListIcondef(int *num) +{ + return (Icondef **) ListItemType(num, LIST_TYPE_ICONDEF); +} + +static time_t last_icondefs_time = 0; + +void +IB_LoadIcodefs(void) +{ + /* load the icon defs */ + char *ff = NULL, s[1024], *s1, *s2, *s3, *s4; + FILE *f; + + ff = FindFile("icondefs.cfg"); + if (!ff) + return; + f = fopen(ff, "r"); + while (fgets(s, 1024, f)) + { + s[strlen(s) - 1] = 0; + /* file format : */ + /* "icon/image.png" "*title*" "*name*" "*class*" */ + /* any field except field 1 can be NULL if you dont care */ + /* the default match is: */ + /* "icon/defailt_image.png" NULL NULL NULL */ + /* and must be first in the file */ + s1 = field(s, 0); + s2 = field(s, 1); + s3 = field(s, 2); + s4 = field(s, 3); + if (s1) + IB_AddIcondef(s2, s3, s4, s1); + if (s1) + Efree(s1); + if (s2) + Efree(s2); + if (s3) + Efree(s3); + if (s4) + Efree(s4); + } + fclose(f); + last_icondefs_time = moddate(ff); + Efree(ff); +} + +void +IB_ReLoadIcodefs(void) +{ + /* stat the icondefs and compare mod date to last known mod date - if */ + /* modified, delete all icondefs and load again */ + char *ff = NULL; + Icondef **idef; + int i, num; + + ff = FindFile("icondefs.cfg"); + if (!ff) + { + idef = IB_ListIcondef(&num); + if (idef) + { + for (i = 0; i < num; i++) + IB_RemoveIcondef(idef[i]); + Efree(idef); + } + return; + } + if (moddate(ff) > last_icondefs_time) + { + idef = IB_ListIcondef(&num); + if (idef) + { + for (i = 0; i < num; i++) + IB_RemoveIcondef(idef[i]); + Efree(idef); + } + IB_LoadIcodefs(); + } + Efree(ff); +} + +static void +IcondefChecker(int val, void *data) +{ + IB_ReLoadIcodefs(); + DoIn("ICONDEF_CHECK", 2.0, IcondefChecker, 0, NULL); + val = 0; + data = NULL; +} + +void +IB_SaveIcodefs(void) +{ + /* save the icondefs */ + char s[1024], *home; + FILE *f; + + home = homedir(getuid()); + Esnprintf(s, sizeof(s), "%s/.enlightenment/icondefs.cfg", home); + Efree(home); + f = fopen(s, "w"); + if (f) + { + Icondef **idef; + int i, num; + + idef = IB_ListIcondef(&num); + for (i = num - 1; i >= 0; i--) + { + char *f1, *f2, *f3, *f4; + + f1 = idef[i]->icon_file; + f2 = idef[i]->title_match; + f3 = idef[i]->name_match; + f4 = idef[i]->class_match; + + if (f1) + { + fprintf(f, "\"%s\" ", f1); + if (f2) + fprintf(f, "\"%s\" ", f2); + else + fprintf(f, "NULL "); + if (f3) + fprintf(f, "\"%s\" ", f3); + else + fprintf(f, "NULL "); + if (f4) + fprintf(f, "\"%s\"\n", f4); + else + fprintf(f, "NULL\n"); + } + } + fclose(f); + last_icondefs_time = moddate(s); + } +} + +Iconbox ** +ListAllIconboxes(int *num) +{ + /* list all currently available Iconboxes */ + return (Iconbox **) ListItemType(num, LIST_TYPE_ICONBOX); +} + +Iconbox * +SelectIconboxForEwin(EWin * ewin) +{ + /* find the appropriate iconbox from all available ones for this app */ + /* if it is to be iconified, or if it is alreayd return which iconbox */ + /* it's in */ + Iconbox **ib, *ib_sel = NULL; + int i, j, num = 0; + + if (!ewin) + return NULL; + ib = ListAllIconboxes(&num); + if (ib) + { + if (ewin->iconified) + { + /* find the iconbox this window got iconifed into */ + for (i = 0; i < num; i++) + { + for (j = 0; j < ib[i]->num_icons; j++) + { + if (ib[i]->icons[j] == ewin) + { + Iconbox *ibr; + + ibr = ib[i]; + Efree(ib); + return ibr; + } + } + } + } + else + { + /* pick the closest iconbox physically on screen to put it in */ + int min_dist; + + ib_sel = ib[0]; + min_dist = 0x7fffffff; + for (i = 0; i < num; i++) + { + int dx, dy, dist; + + dx = (ib[i]->ewin->x + (ib[i]->ewin->w / 2)) - + (ewin->x + (ewin->w / 2)); + dy = (ib[i]->ewin->y + (ib[i]->ewin->h / 2)) - + (ewin->y + (ewin->h / 2)); + dist = (dx * dx) + (dy * dy); + if ((!ib[i]->ewin->sticky) && + (ib[i]->ewin->desktop != ewin->desktop)) + dist += (root.w * root.w) + (root.h * root.h); + if (dist < min_dist) + { + min_dist = dist; + ib_sel = ib[i]; + } + } + } + Efree(ib); + } + return ib_sel; +} + +void +UpdateAppIcon(EWin * ewin, int imode) +{ + /* free whatever we had before */ + Iconbox *ib; + + if (ewin->icon_pmap) + Imlib_free_pixmap(id, ewin->icon_pmap); + if (ewin->icon_mask) + Imlib_free_pixmap(id, ewin->icon_mask); + ewin->icon_pmap = 0; + ewin->icon_mask = 0; + + switch (imode) + { + case 0: + /* snap first - if fails try app, then e */ + if (!ewin->icon_pmap) + { + RaiseEwin(ewin); + IB_SnapEWin(ewin); + } + if (!ewin->icon_pmap) + IB_GetAppIcon(ewin); + if (!ewin->icon_pmap) + IB_GetEIcon(ewin); + break; + case 1: + /* try app first, then e, then snap */ + if (!ewin->icon_pmap) + IB_GetAppIcon(ewin); + if (!ewin->icon_pmap) + IB_GetEIcon(ewin); + if (!ewin->icon_pmap) + { + RaiseEwin(ewin); + IB_SnapEWin(ewin); + } + break; + case 2: + /* try E first, then snap */ + if (!ewin->icon_pmap) + IB_GetEIcon(ewin); + if (!ewin->icon_pmap) + { + RaiseEwin(ewin); + IB_SnapEWin(ewin); + } + break; + default: + break; + } + ib = SelectIconboxForEwin(ewin); + if ((ewin->iconified) && (ib)) + RedrawIconbox(ib); +} + +void +IB_CalcMax(Iconbox * ib) +{ + int i, x, y; + + x = 0; + y = 0; + for (i = 0; i < ib->num_icons; i++) + { + int w, h; + EWin *ewin; + + w = 8; + h = 8; + ewin = ib->icons[i]; + if (!ewin->icon_pmap) + UpdateAppIcon(ewin, mode.icon_mode); + if (ewin->icon_pmap) + { + w = ewin->icon_pmap_w; + h = ewin->icon_pmap_h; + } + if (ib->draw_icon_base) + { + x += ib->iconsize; + y += ib->iconsize; + } + else + { + x += w + 2; + y += h + 2; + } + } + if (ib->orientation) + ib->max = y - 2; + else + ib->max = x - 2; + if (ib->max < 1) + ib->max = 1; +} + +EWin * +IB_FindIcon(Iconbox * ib, int px, int py) +{ + int i, x = 0, y = 0; + ImageClass *ic = NULL; + + if (ib->orientation) + { + ic = FindItem("ICONBOX_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + y = -ib->pos; + x = 0; + if (ic) + { + x += ic->padding.left; + y += ic->padding.top; + } + } + else + { + ic = FindItem("ICONBOX_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + x = -ib->pos; + y = 0; + if (ic) + { + x += ic->padding.left; + y += ic->padding.top; + } + } + for (i = 0; i < ib->num_icons; i++) + { + int w, h; + EWin *ewin; + + w = 8; + h = 8; + ewin = ib->icons[i]; + if (!ewin->icon_pmap) + UpdateAppIcon(ewin, mode.icon_mode); + if (ewin->icon_pmap) + { + w = ewin->icon_pmap_w; + h = ewin->icon_pmap_h; + if ((px >= (x - 1)) && (py >= (y - 1)) && + (px < (x + w + 1)) && + (py < (y + h + 1))) + return ewin; + } + if (ib->orientation) + { + if (ib->draw_icon_base) + y += ib->iconsize; + else + y += h + 2; + } + else + { + if (ib->draw_icon_base) + x += ib->iconsize; + else + x += w + 2; + } + } + return NULL; +} + +void +IB_DrawScroll(Iconbox * ib) +{ + ImageClass *ic; + char show_sb = 1; + + if (ib->orientation) + { + int bs, bw, bx; + + ic = FindItem("ICONBOX_SCROLLBAR_BASE_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ib->arrow_side < 3) + bs = ib->h - (ib->arrow_thickness * 2); + else + bs = ib->h; + bw = (ib->h * bs) / ib->max; + if (ic) + { + bs -= (ic->padding.top + ic->padding.bottom); + bw = ((ib->h - (ic->padding.top + ic->padding.bottom)) * + bs) / ib->max; + } + if (bs < 1) + bs = 1; + if (bw > bs) + bw = bs; + if (bw < 1) + bw = 1; + bx = ((ib->pos * bs) / ib->max); + if (ic) + bx += ic->padding.top; + if ((ib->scrollbar_hide) && (bw == bs)) + show_sb = 0; + ic = FindItem("ICONBOX_SCROLLKNOB_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if ((ic) && (bw > ib->knob_length)) + EMoveResizeWindow(disp, ib->scrollbarknob_win, + 0, (bw - ib->knob_length) / 2, + ib->bar_thickness, ib->knob_length); + else + EMoveResizeWindow(disp, ib->scrollbarknob_win, + -9999, -9999, + ib->bar_thickness, ib->knob_length); + if (show_sb) + { + /* fix this area */ + if (ib->scrollbar_side == 1) + /* right */ + { + /* start */ + if (ib->arrow_side == 0) + { + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->arrow1_win, + ib->w - ib->scroll_thickness, 0, + ib->scroll_thickness, ib->arrow_thickness); + EMoveResizeWindow(disp, ib->arrow2_win, + ib->w - ib->scroll_thickness, ib->arrow_thickness, + ib->scroll_thickness, ib->arrow_thickness); + EMoveResizeWindow(disp, ib->scroll_win, + ib->w - ib->scroll_thickness, ib->arrow_thickness * 2, + ib->scroll_thickness, ib->h - (ib->arrow_thickness * 2)); + } + /* both ends */ + else if (ib->arrow_side == 1) + { + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->arrow1_win, + ib->w - ib->scroll_thickness, 0, + ib->scroll_thickness, ib->arrow_thickness); + EMoveResizeWindow(disp, ib->arrow2_win, + ib->w - ib->scroll_thickness, ib->h - ib->arrow_thickness, + ib->scroll_thickness, ib->arrow_thickness); + EMoveResizeWindow(disp, ib->scroll_win, + ib->w - ib->scroll_thickness, ib->arrow_thickness, + ib->scroll_thickness, ib->h - (ib->arrow_thickness * 2)); + } + /* end */ + else if (ib->arrow_side == 2) + { + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->arrow1_win, + ib->w - ib->scroll_thickness, ib->h - (ib->arrow_thickness * 2), + ib->scroll_thickness, ib->arrow_thickness); + EMoveResizeWindow(disp, ib->arrow2_win, + ib->w - ib->scroll_thickness, ib->h - ib->arrow_thickness, + ib->scroll_thickness, ib->arrow_thickness); + EMoveResizeWindow(disp, ib->scroll_win, + ib->w - ib->scroll_thickness, 0, + ib->scroll_thickness, ib->h - (ib->arrow_thickness * 2)); + } + /* no arrows */ + else + { + EUnmapWindow(disp, ib->arrow1_win); + EUnmapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->scroll_win, + ib->w - ib->scroll_thickness, 0, + ib->scroll_thickness, ib->h); + } + } + else + /* left */ + { + /* start */ + if (ib->arrow_side == 0) + { + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->arrow1_win, + 0, 0, + ib->scroll_thickness, ib->arrow_thickness); + EMoveResizeWindow(disp, ib->arrow2_win, + 0, ib->arrow_thickness, + ib->scroll_thickness, ib->arrow_thickness); + EMoveResizeWindow(disp, ib->scroll_win, + 0, ib->arrow_thickness * 2, + ib->scroll_thickness, ib->h - (ib->arrow_thickness * 2)); + } + /* both ends */ + else if (ib->arrow_side == 1) + { + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->arrow1_win, + 0, 0, + ib->scroll_thickness, ib->arrow_thickness); + EMoveResizeWindow(disp, ib->arrow2_win, + 0, ib->h - ib->arrow_thickness, + ib->scroll_thickness, ib->arrow_thickness); + EMoveResizeWindow(disp, ib->scroll_win, + 0, ib->arrow_thickness, + ib->scroll_thickness, ib->h - (ib->arrow_thickness * 2)); + } + /* end */ + else if (ib->arrow_side == 2) + { + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->arrow1_win, + 0, ib->h - (ib->arrow_thickness * 2), + ib->scroll_thickness, ib->arrow_thickness); + EMoveResizeWindow(disp, ib->arrow2_win, + 0, ib->h - ib->arrow_thickness, + ib->scroll_thickness, ib->arrow_thickness); + EMoveResizeWindow(disp, ib->scroll_win, + 0, 0, + ib->scroll_thickness, ib->h - (ib->arrow_thickness * 2)); + } + /* no arrows */ + else + { + EUnmapWindow(disp, ib->arrow1_win); + EUnmapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->scroll_win, + 0, 0, + ib->scroll_thickness, ib->h); + } + } + } + else + { + EMoveResizeWindow(disp, ib->scroll_win, -9999, -9999, 2, 2); + EMoveResizeWindow(disp, ib->arrow1_win, -9999, -9999, 2, 2); + EMoveResizeWindow(disp, ib->arrow2_win, -9999, -9999, 2, 2); + } + EMoveResizeWindow(disp, ib->scrollbar_win, + (ib->scroll_thickness - ib->bar_thickness) / 2, bx, + ib->bar_thickness, bw); + + ic = FindItem("ICONBOX_SCROLLBAR_BASE_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + IclassApply(ic, ib->scroll_win, -1, -1, 0, 0, STATE_NORMAL, 0); + ic = FindItem("ICONBOX_SCROLLBAR_KNOB_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + { + int state = STATE_NORMAL; + + if (ib->scrollbar_hilited) + state = STATE_HILITED; + if (ib->scrollbar_clicked) + state = STATE_CLICKED; + IclassApply(ic, ib->scrollbar_win, -1, -1, 0, 0, state, 0); + } + ic = FindItem("ICONBOX_SCROLLKNOB_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + { + int state = STATE_NORMAL; + + if (ib->scrollbar_hilited) + state = STATE_HILITED; + if (ib->scrollbar_clicked) + state = STATE_CLICKED; + IclassApply(ic, ib->scrollbarknob_win, -1, -1, 0, 0, state, 0); + } + ic = FindItem("ICONBOX_ARROW_UP", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + { + int state = STATE_NORMAL; + + if (ib->arrow1_hilited) + state = STATE_HILITED; + if (ib->arrow1_clicked) + state = STATE_CLICKED; + IclassApply(ic, ib->arrow1_win, -1, -1, 0, 0, state, 0); + } + ic = FindItem("ICONBOX_ARROW_DOWN", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + { + int state = STATE_NORMAL; + + if (ib->arrow2_hilited) + state = STATE_HILITED; + if (ib->arrow2_clicked) + state = STATE_CLICKED; + IclassApply(ic, ib->arrow2_win, -1, -1, 0, 0, state, 0); + } + /* remove this coment when fixed */ + } + else + { + int bs, bw, bx; + + ic = FindItem("ICONBOX_SCROLLBAR_BASE_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ib->arrow_side < 3) + bs = ib->w - (ib->arrow_thickness * 2); + else + bs = ib->w; + bw = (ib->w * bs) / ib->max; + if (ic) + { + bs -= (ic->padding.left + ic->padding.right); + bw = ((ib->w - (ic->padding.left + ic->padding.right)) * + bs) / ib->max; + } + if (bs < 1) + bs = 1; + if (bw > bs) + bw = bs; + if (bw < 1) + bw = 1; + bx = ((ib->pos * bs) / ib->max); + if (ic) + bx += ic->padding.left; + if ((ib->scrollbar_hide) && (bw == bs)) + show_sb = 0; + ic = FindItem("ICONBOX_SCROLLKNOB_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if ((ic) && (bw > ib->knob_length)) + EMoveResizeWindow(disp, ib->scrollbarknob_win, + (bw - ib->knob_length) / 2, 0, + ib->knob_length, ib->bar_thickness); + else + EMoveResizeWindow(disp, ib->scrollbarknob_win, + -9999, -9999, + ib->knob_length, ib->bar_thickness); + + if (show_sb) + { + if (ib->scrollbar_side == 1) + /* bottom */ + { + /* start */ + if (ib->arrow_side == 0) + { + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->arrow1_win, + 0, ib->h - ib->scroll_thickness, + ib->arrow_thickness, ib->scroll_thickness); + EMoveResizeWindow(disp, ib->arrow2_win, + ib->arrow_thickness, ib->h - ib->scroll_thickness, + ib->arrow_thickness, ib->scroll_thickness); + EMoveResizeWindow(disp, ib->scroll_win, + ib->arrow_thickness * 2, ib->h - ib->scroll_thickness, + ib->w - (ib->arrow_thickness * 2), ib->scroll_thickness); + } + /* both ends */ + else if (ib->arrow_side == 1) + { + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->arrow1_win, + 0, ib->h - ib->scroll_thickness, + ib->arrow_thickness, ib->scroll_thickness); + EMoveResizeWindow(disp, ib->arrow2_win, + ib->w - ib->arrow_thickness, ib->h - ib->scroll_thickness, + ib->arrow_thickness, ib->scroll_thickness); + EMoveResizeWindow(disp, ib->scroll_win, + ib->arrow_thickness, ib->h - ib->scroll_thickness, + ib->w - (ib->arrow_thickness * 2), ib->scroll_thickness); + } + /* end */ + else if (ib->arrow_side == 2) + { + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->arrow1_win, + ib->w - (ib->arrow_thickness * 2), ib->h - ib->scroll_thickness, + ib->arrow_thickness, ib->scroll_thickness); + EMoveResizeWindow(disp, ib->arrow2_win, + ib->w - ib->arrow_thickness, ib->h - ib->scroll_thickness, + ib->arrow_thickness, ib->scroll_thickness); + EMoveResizeWindow(disp, ib->scroll_win, + 0, ib->h - ib->scroll_thickness, + ib->w - (ib->arrow_thickness * 2), ib->scroll_thickness); + } + /* no arrows */ + else + { + EUnmapWindow(disp, ib->arrow1_win); + EUnmapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->scroll_win, + 0, ib->h - ib->scroll_thickness, + ib->w, ib->scroll_thickness); + } + } + else + /* top */ + { + /* start */ + if (ib->arrow_side == 0) + { + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->arrow1_win, + 0, 0, + ib->arrow_thickness, ib->scroll_thickness); + EMoveResizeWindow(disp, ib->arrow2_win, + ib->arrow_thickness, 0, + ib->arrow_thickness, ib->scroll_thickness); + EMoveResizeWindow(disp, ib->scroll_win, + ib->arrow_thickness * 2, 0, + ib->w - (ib->arrow_thickness * 2), ib->scroll_thickness); + } + /* both ends */ + else if (ib->arrow_side == 1) + { + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->arrow1_win, + 0, 0, + ib->arrow_thickness, ib->scroll_thickness); + EMoveResizeWindow(disp, ib->arrow2_win, + ib->w - ib->arrow_thickness, 0, + ib->arrow_thickness, ib->scroll_thickness); + EMoveResizeWindow(disp, ib->scroll_win, + ib->arrow_thickness, 0, + ib->w - (ib->arrow_thickness * 2), ib->scroll_thickness); + } + /* end */ + else if (ib->arrow_side == 2) + { + EMapWindow(disp, ib->arrow1_win); + EMapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->arrow1_win, + ib->w - (ib->arrow_thickness * 2), 0, + ib->arrow_thickness, ib->scroll_thickness); + EMoveResizeWindow(disp, ib->arrow2_win, + ib->w - ib->arrow_thickness, 0, + ib->arrow_thickness, ib->scroll_thickness); + EMoveResizeWindow(disp, ib->scroll_win, + 0, 0, + ib->w - (ib->arrow_thickness * 2), ib->scroll_thickness); + } + /* no arrows */ + else + { + EUnmapWindow(disp, ib->arrow1_win); + EUnmapWindow(disp, ib->arrow2_win); + EMoveResizeWindow(disp, ib->scroll_win, + 0, 0, + ib->w, ib->scroll_thickness); + } + } + } + else + { + EMoveResizeWindow(disp, ib->scroll_win, -9999, -9999, 2, 2); + EMoveResizeWindow(disp, ib->arrow1_win, -9999, -9999, 2, 2); + EMoveResizeWindow(disp, ib->arrow2_win, -9999, -9999, 2, 2); + } + + EMoveResizeWindow(disp, ib->scrollbar_win, + bx, (ib->scroll_thickness - ib->bar_thickness) / 2, + bw, ib->bar_thickness); + + ic = FindItem("ICONBOX_SCROLLBAR_BASE_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + IclassApply(ic, ib->scroll_win, -1, -1, 0, 0, STATE_NORMAL, 0); + ic = FindItem("ICONBOX_SCROLLBAR_KNOB_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + { + int state = STATE_NORMAL; + + if (ib->scrollbar_hilited) + state = STATE_HILITED; + if (ib->scrollbar_clicked) + state = STATE_CLICKED; + IclassApply(ic, ib->scrollbar_win, -1, -1, 0, 0, state, 0); + } + ic = FindItem("ICONBOX_SCROLLKNOB_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + { + int state = STATE_NORMAL; + + if (ib->scrollbar_hilited) + state = STATE_HILITED; + if (ib->scrollbar_clicked) + state = STATE_CLICKED; + IclassApply(ic, ib->scrollbarknob_win, -1, -1, 0, 0, state, 0); + } + ic = FindItem("ICONBOX_ARROW_LEFT", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + { + int state = STATE_NORMAL; + + if (ib->arrow1_hilited) + state = STATE_HILITED; + if (ib->arrow1_clicked) + state = STATE_CLICKED; + IclassApply(ic, ib->arrow1_win, -1, -1, 0, 0, state, 0); + } + ic = FindItem("ICONBOX_ARROW_RIGHT", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + { + int state = STATE_NORMAL; + + if (ib->arrow2_hilited) + state = STATE_HILITED; + if (ib->arrow2_clicked) + state = STATE_CLICKED; + IclassApply(ic, ib->arrow2_win, -1, -1, 0, 0, state, 0); + } + } + PropagateShapes(ib->win); + { + Border *b; + + b = ib->ewin->border; + SyncBorderToEwin(ib->ewin); + if (ib->ewin->border == b) + PropagateShapes(ib->ewin->win); + } +} + +void +IB_FixPos(Iconbox * ib) +{ + if (ib->orientation) + { + ImageClass *ic; + int v = 0; + + ic = FindItem("ICONBOX_SCROLLBAR_BASE_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + v = ib->max - ib->h; + if (ic) + v += ic->padding.top + ic->padding.bottom; + if (ib->pos > v) + ib->pos = v; + } + else + { + ImageClass *ic; + int v = 0; + + ic = FindItem("ICONBOX_SCROLLBAR_BASE_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + v = ib->max - ib->w; + if (ic) + v += ic->padding.left + ic->padding.right; + if (ib->pos > v) + ib->pos = v; + } + if (ib->pos < 0) + ib->pos = 0; + +} + +void +RedrawIconbox(Iconbox * ib) +{ + ImageClass *ic; + Pixmap m = 0; + char pq; + + if (!ib) + return; + + if (ib->auto_resize) + { + int add = 0; + int x, y, w, h; + + x = ib->ewin->x; + y = ib->ewin->y; + w = ib->ewin->client.w; + h = ib->ewin->client.h; + IB_CalcMax(ib); + if (ib->orientation) + { + ic = FindItem("ICONBOX_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + add = ic->padding.top + ic->padding.bottom; + add += ib->max; + if ((ib->ewin->border->border.top + + ib->ewin->border->border.bottom + add) > + root.h) + add = root.h - (ib->ewin->border->border.top + + ib->ewin->border->border.bottom); + x = ib->ewin->x; + y = ib->ewin->y; + w = ib->ewin->client.w; + h = add; + if ((ib->ewin->y + ib->ewin->border->border.top + + ib->ewin->border->border.bottom + add) > + root.h) + { + x = ib->ewin->x; + y = root.h - (ib->ewin->border->border.top + + ib->ewin->border->border.bottom + add); + w = ib->ewin->client.w; + h = add; + } + } + else + { + ic = FindItem("ICONBOX_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + add = ic->padding.left + ic->padding.right; + add += ib->max; + if ((ib->ewin->border->border.left + + ib->ewin->border->border.right + add) > + root.w) + add = root.w - (ib->ewin->border->border.left + + ib->ewin->border->border.right); + x = ib->ewin->x; + y = ib->ewin->y; + w = add; + h = ib->ewin->client.h; + if ((ib->ewin->x + ib->ewin->border->border.left + + ib->ewin->border->border.right + add) > + root.w) + { + x = root.w - (ib->ewin->border->border.left + + ib->ewin->border->border.right + add); + y = ib->ewin->y; + w = add; + h = ib->ewin->client.h; + } + } + if ((x != ib->ewin->x) || (y != ib->ewin->y) || + (w != ib->ewin->client.w) || (h != ib->ewin->client.h)) + MoveResizeEwin(ib->ewin, x, y, w, h); + EResizeWindow(disp, ib->win, w, h); + EFreePixmap(disp, ib->pmap); + ib->pmap = ECreatePixmap(disp, ib->icon_win, w, h, id->x.depth); + ib->w = w; + ib->h = h; + } + + pq = queue_up; + queue_up = 0; + + IB_CalcMax(ib); + IB_FixPos(ib); + IB_DrawScroll(ib); + + if (ib->orientation) + { + int i; + int x, y; + + if (ib->scrollbar_side == 1) + { + /* right */ + EMoveResizeWindow(disp, ib->icon_win, + 0, 0, + ib->w - ib->scroll_thickness, ib->h); + if ((ic = FindItem("ICONBOX_COVER_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS))) + { + EMoveResizeWindow(disp, ib->cover_win, + 0, 0, + ib->w - ib->scroll_thickness, ib->h); + EMapWindow(disp, ib->cover_win); + IclassApply(ic, ib->cover_win, -1, -1, 0, 0, STATE_NORMAL, 0); + } + else + { + EMoveResizeWindow(disp, ib->cover_win, + -30000, -30000, + 2, 2); + EUnmapWindow(disp, ib->cover_win); + } + } + else + { + /* left */ + EMoveResizeWindow(disp, ib->icon_win, + ib->scroll_thickness, 0, + ib->w - ib->scroll_thickness, ib->h); + if ((ic = FindItem("ICONBOX_COVER_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS))) + { + EMoveResizeWindow(disp, ib->cover_win, + ib->scroll_thickness, 0, + ib->w - ib->scroll_thickness, ib->h); + EMapWindow(disp, ib->cover_win); + IclassApply(ic, ib->cover_win, -1, -1, 0, 0, STATE_NORMAL, 0); + } + else + { + EMoveResizeWindow(disp, ib->cover_win, + -30000, -30000, + 2, 2); + EUnmapWindow(disp, ib->cover_win); + } + } + + ic = FindItem("ICONBOX_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (!ib->nobg) + { + if (ic) + { + Pixmap pmap = 0, mask = 0; + int iw, ih; + + GetWinWH(ib->icon_win, &iw, &ih); + IclassApplyCopy(ic, ib->icon_win, iw, ih, 0, 0, STATE_NORMAL, + &pmap, &mask); + EShapeCombineMask(disp, ib->icon_win, ShapeBounding, 0, 0, mask, ShapeSet); + PastePixmap(disp, ib->pmap, pmap, mask, 0, 0); + Imlib_free_pixmap(id, pmap); + Imlib_free_pixmap(id, mask); + } + } + else + { + int iw, ih; + GC gc; + XGCValues gcv; + + GetWinWH(ib->icon_win, &iw, &ih); + m = ECreatePixmap(disp, ib->icon_win, iw, ih, 1); + gc = XCreateGC(disp, m, 0, &gcv); + XSetForeground(disp, gc, 0); + XFillRectangle(disp, m, gc, 0, 0, iw, ih); + XFreeGC(disp, gc); + } + + y = -ib->pos; + x = 0; + if (ic) + { + x += ic->padding.left; + y += ic->padding.top; + } + for (i = 0; i < ib->num_icons; i++) + { + int w, h; + EWin *ewin; + + w = 8; + h = 8; + ewin = ib->icons[i]; + if (!ewin->icon_pmap) + UpdateAppIcon(ewin, mode.icon_mode); + if (ewin->icon_pmap) + { + w = ewin->icon_pmap_w; + h = ewin->icon_pmap_h; + if (ib->draw_icon_base) + { + IB_PasteDefaultBase(ib->pmap, x, y, ib->iconsize, ib->iconsize); + if (ib->nobg) + IB_PasteDefaultBaseMask(m, x, y, ib->iconsize, ib->iconsize); + } + if (ib->draw_icon_base) + PastePixmap(disp, ib->pmap, + ewin->icon_pmap, + ewin->icon_mask, x + ((ib->iconsize - w) / 2), y + ((ib->iconsize - h) / 2)); + else + PastePixmap(disp, ib->pmap, + ewin->icon_pmap, + ewin->icon_mask, x + ((ib->iconsize - w) / 2), y); + if (ib->nobg) + PasteMask(disp, m, ewin->icon_mask, x, y, w, h); + } + if (ib->draw_icon_base) + y += ib->iconsize; + else + y += h + 2; + } + } + else + { + int i; + int x, y; + + if (ib->scrollbar_side == 1) + { + /* bottom */ + EMoveResizeWindow(disp, ib->icon_win, + 0, 0, + ib->w, ib->h - ib->scroll_thickness); + if ((ic = FindItem("ICONBOX_COVER_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS))) + { + EMoveResizeWindow(disp, ib->cover_win, + 0, 0, + ib->w, ib->h - ib->scroll_thickness); + EMapWindow(disp, ib->cover_win); + IclassApply(ic, ib->cover_win, -1, -1, 0, 0, STATE_NORMAL, 0); + } + else + { + EMoveResizeWindow(disp, ib->cover_win, + -30000, -30000, + 2, 2); + EUnmapWindow(disp, ib->cover_win); + } + } + else + { + /* top */ + EMoveResizeWindow(disp, ib->icon_win, + 0, ib->scroll_thickness, + ib->w, ib->h - ib->scroll_thickness); + if ((ic = FindItem("ICONBOX_COVER_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS))) + { + EMoveResizeWindow(disp, ib->cover_win, + 0, ib->scroll_thickness, + ib->w, ib->h - ib->scroll_thickness); + EMapWindow(disp, ib->cover_win); + IclassApply(ic, ib->cover_win, -1, -1, 0, 0, STATE_NORMAL, 0); + } + else + { + EMoveResizeWindow(disp, ib->cover_win, + -30000, -30000, + 2, 2); + EUnmapWindow(disp, ib->cover_win); + } + } + + ic = FindItem("ICONBOX_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (!ib->nobg) + { + if (ic) + { + Pixmap pmap = 0, mask = 0; + int iw, ih; + + GetWinWH(ib->icon_win, &iw, &ih); + IclassApplyCopy(ic, ib->icon_win, iw, ih, 0, 0, STATE_NORMAL, + &pmap, &mask); + EShapeCombineMask(disp, ib->icon_win, ShapeBounding, 0, 0, mask, ShapeSet); + PastePixmap(disp, ib->pmap, pmap, mask, 0, 0); + Imlib_free_pixmap(id, pmap); + Imlib_free_pixmap(id, mask); + } + } + else + { + int iw, ih; + GC gc; + XGCValues gcv; + + GetWinWH(ib->icon_win, &iw, &ih); + m = ECreatePixmap(disp, ib->icon_win, iw, ih, 1); + gc = XCreateGC(disp, m, 0, &gcv); + XSetForeground(disp, gc, 0); + XFillRectangle(disp, m, gc, 0, 0, iw, ih); + XFreeGC(disp, gc); + } + + x = -ib->pos; + y = 0; + if (ic) + { + x += ic->padding.left; + y += ic->padding.top; + } + for (i = 0; i < ib->num_icons; i++) + { + int w, h; + EWin *ewin; + + w = 8; + h = 8; + ewin = ib->icons[i]; + if (!ewin->icon_pmap) + UpdateAppIcon(ewin, mode.icon_mode); + if (ewin->icon_pmap) + { + w = ewin->icon_pmap_w; + h = ewin->icon_pmap_h; + if (ib->draw_icon_base) + { + IB_PasteDefaultBase(ib->pmap, x, y, ib->iconsize, ib->iconsize); + if (ib->nobg) + IB_PasteDefaultBaseMask(m, x, y, ib->iconsize, ib->iconsize); + } + if (ib->draw_icon_base) + PastePixmap(disp, ib->pmap, + ewin->icon_pmap, + ewin->icon_mask, x + ((ib->iconsize - w) / 2), y + ((ib->iconsize - h) / 2)); + else + PastePixmap(disp, ib->pmap, + ewin->icon_pmap, + ewin->icon_mask, x, y + ((ib->iconsize - h) / 2)); + if (ib->nobg) + PasteMask(disp, m, ewin->icon_mask, x, y, w, h); + } + if (ib->draw_icon_base) + x += ib->iconsize; + else + x += w + 2; + } + } + if (ib->nobg) + { + EShapeCombineMask(disp, ib->icon_win, ShapeBounding, 0, 0, m, ShapeSet); + EFreePixmap(disp, m); + if (ib->num_icons == 0) + EMoveWindow(disp, ib->icon_win, + -ib->w, -ib->h); + } + ESetWindowBackgroundPixmap(disp, ib->icon_win, ib->pmap); + XClearWindow(disp, ib->icon_win); + PropagateShapes(ib->win); + ICCCM_GetShapeInfo(ib->ewin); + PropagateShapes(ib->ewin->win); + queue_up = pq; +} + +void +IconboxResize(Iconbox * ib, int w, int h) +{ + if ((ib->w == w) && (ib->h == h)) + return; + EResizeWindow(disp, ib->win, w, h); + EFreePixmap(disp, ib->pmap); + ib->pmap = ECreatePixmap(disp, ib->icon_win, w, h, id->x.depth); + ib->w = w; + ib->h = h; + RedrawIconbox(ib); +} + +void +IB_Scroll(Iconbox * ib, int dir) +{ + ib->pos += dir; + IB_FixPos(ib); + RedrawIconbox(ib); +} + +void +IB_ShowMenu(Iconbox * ib, int x, int y) +{ + static Menu *p_menu = NULL; + MenuItem *mi; + char s[1024]; + + if (p_menu) + DestroyMenu(p_menu); + p_menu = CreateMenu(); + + AddTitleToMenu(p_menu, "Iconbox Options"); + p_menu->name = duplicate("__IBOX_MENU"); + p_menu->style = FindItem("DEFAULT", 0, LIST_FINDBY_NAME, LIST_TYPE_MENU_STYLE); + Esnprintf(s, sizeof(s), "iconbox %s", ib->name); + mi = CreateMenuItem("This Iconbox Settings...", NULL, ACTION_CONFIG, s, NULL); + AddItemToMenu(p_menu, mi); + mi = CreateMenuItem("Close Iconbox", NULL, ACTION_KILL, NULL, NULL); + AddItemToMenu(p_menu, mi); + mi = CreateMenuItem("Create New Iconbox", NULL, ACTION_CREATE_ICONBOX, NULL, NULL); + AddItemToMenu(p_menu, mi); + AddItem(p_menu, p_menu->name, 0, LIST_TYPE_MENU); + Esnprintf(s, sizeof(s), "named %s", p_menu->name); + spawnMenu(s); + x = 0; + y = 0; +} + +void +IB_CompleteRedraw(Iconbox * ib) +{ + ib->ewin->client.width.min = 8; + ib->ewin->client.height.min = 8; + ib->ewin->client.width.max = 16384; + ib->ewin->client.height.max = 16384; + ib->ewin->client.no_resize_h = 0; + ib->ewin->client.no_resize_v = 0; + if (ib->orientation) + { + ImageClass *ic; + int extra = 0; + + ic = FindItem("ICONBOX_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + extra = ic->padding.left + ic->padding.right; + ib->ewin->client.width.max = + ib->ewin->client.width.min = + ib->iconsize + ib->scroll_thickness + extra; + ib->ewin->client.no_resize_h = 1; + } + else + { + ImageClass *ic; + int extra = 0; + + ic = FindItem("ICONBOX_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + if (ic) + extra = ic->padding.left + ic->padding.right; + ib->ewin->client.height.max = + ib->ewin->client.height.min = + ib->iconsize + ib->scroll_thickness + extra; + ib->ewin->client.no_resize_v = 1; + } + RedrawIconbox(ib); + ResizeEwin(ib->ewin, ib->ewin->client.w, ib->ewin->client.h); + + SnapshotEwinBorder(ib->ewin); + SnapshotEwinDesktop(ib->ewin); + SnapshotEwinSize(ib->ewin); + SnapshotEwinLocation(ib->ewin); + SnapshotEwinLayer(ib->ewin); + SnapshotEwinSticky(ib->ewin); + SnapshotEwinShade(ib->ewin); +} + +void +IB_Setup(void) +{ + EWin **lst; + int i, num; + Iconbox **ibl; + + IcondefChecker(0, NULL); + ibl = ListAllIconboxes(&num); + if (ibl) + { + for (i = 0; i < num; i++) + ShowIconbox(ibl[i]); + Efree(ibl); + } + lst = (EWin **) ListItemType(&num, LIST_TYPE_EWIN); + if (lst) + { + for (i = 0; i < num; i++) + { + if (lst[i]->client.start_iconified) + IconifyEwin(lst[i]); + } + Efree(lst); + } +} + +void +IconboxHandleEvent(XEvent * ev) +{ + Iconbox **ib; + int i, num; + + if (mode.mode != MODE_NONE) + return; + ib = ListAllIconboxes(&num); + if (!ib) + return; + for (i = 0; i < num; i++) + { + if (ev->xany.window == ib[i]->scroll_win) + { + if (ev->type == ButtonPress) + ib[i]->scrollbox_clicked = 1; + else if ((ev->type == ButtonRelease) && (ib[i]->scrollbox_clicked)) + { + int x, y, w, h; + + ib[i]->scrollbox_clicked = 0; + GetWinXY(ib[i]->scrollbar_win, &x, &y); + GetWinWH(ib[i]->scrollbar_win, &w, &h); + if (ev->xbutton.x < x) + IB_Scroll(ib[i], -8); + if (ev->xbutton.x > (x + w)) + IB_Scroll(ib[i], 8); + } + } + if (ev->xany.window == ib[i]->scrollbar_win) + { + static int px, py; + + if (ev->type == ButtonPress) + { + px = ev->xbutton.x_root; + py = ev->xbutton.y_root; + ib[i]->scrollbar_clicked = 1; + } + else if ((ev->type == ButtonRelease) && (ib[i]->scrollbar_clicked)) + ib[i]->scrollbar_clicked = 0; + else if (ev->type == EnterNotify) + ib[i]->scrollbar_hilited = 1; + else if (ev->type == LeaveNotify) + ib[i]->scrollbar_hilited = 0; + else if ((ev->type == MotionNotify) && (ib[i]->scrollbar_clicked)) + { + int dx, dy, bs, x, y; + ImageClass *ic; + + dx = ev->xmotion.x_root - px; + dy = ev->xmotion.y_root - py; + px = ev->xmotion.x_root; + py = ev->xmotion.y_root; + + if (ib[i]->orientation) + { + ic = FindItem("ICONBOX_SCROLLBAR_BASE_VERTICAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + GetWinXY(ib[i]->scrollbar_win, &x, &y); + bs = ib[i]->h - (ib[i]->arrow_thickness * 2); + if (ic) + { + bs -= (ic->padding.top + ic->padding.bottom); + y -= ic->padding.top; + } + if (bs < 1) + bs = 1; + ib[i]->pos = ((y + dy + 1) * ib[i]->max) / bs; + IB_FixPos(ib[i]); + RedrawIconbox(ib[i]); + } + else + { + ic = FindItem("ICONBOX_SCROLLBAR_BASE_HORIZONTAL", 0, LIST_FINDBY_NAME, LIST_TYPE_ICLASS); + GetWinXY(ib[i]->scrollbar_win, &x, &y); + bs = ib[i]->w - (ib[i]->arrow_thickness * 2); + if (ic) + { + bs -= (ic->padding.left + ic->padding.right); + x -= ic->padding.left; + } + if (bs < 1) + bs = 1; + ib[i]->pos = ((x + dx + 1) * ib[i]->max) / bs; + IB_FixPos(ib[i]); + RedrawIconbox(ib[i]); + } + } + IB_DrawScroll(ib[i]); + } + else if (ev->xany.window == ib[i]->arrow1_win) + { + if (ev->type == ButtonPress) + ib[i]->arrow1_clicked = 1; + else if ((ev->type == ButtonRelease) && (ib[i]->arrow1_clicked)) + { + ib[i]->arrow1_clicked = 0; + IB_Scroll(ib[i], -8); + } + else if (ev->type == EnterNotify) + ib[i]->arrow1_hilited = 1; + else if (ev->type == LeaveNotify) + ib[i]->arrow1_hilited = 0; + IB_DrawScroll(ib[i]); + } + else if (ev->xany.window == ib[i]->arrow2_win) + { + if (ev->type == ButtonPress) + ib[i]->arrow2_clicked = 1; + else if ((ev->type == ButtonRelease) && (ib[i]->arrow2_clicked)) + { + ib[i]->arrow2_clicked = 0; + IB_Scroll(ib[i], 8); + } + else if (ev->type == EnterNotify) + ib[i]->arrow2_hilited = 1; + else if (ev->type == LeaveNotify) + ib[i]->arrow2_hilited = 0; + IB_DrawScroll(ib[i]); + } + else if (ev->xany.window == ib[i]->icon_win) + { + if (ev->type == ButtonPress) + { + if (ev->xbutton.button == 1) + ib[i]->icon_clicked = 1; + else + IB_ShowMenu(ib[i], ev->xbutton.x, ev->xbutton.y); + } + else if ((ev->type == ButtonRelease) && (ib[i]->icon_clicked)) + { + EWin *ewin; + EWin **gwins; + int j, num; + char iconified; + + ib[i]->icon_clicked = 0; + ewin = IB_FindIcon(ib[i], ev->xbutton.x, ev->xbutton.y); + + if (ewin) + { + gwins = ListWinGroupMembersForEwin(ewin, ACTION_ICONIFY, &num); + iconified = ewin->iconified; + + if (gwins) + { + for (j = 0; j < num; j++) + { + if ((gwins[j]->iconified) && (iconified)) + DeIconifyEwin(gwins[j]); + } + Efree(gwins); + } + } + } + } + } + Efree(ib); +} diff --git a/src/init.c b/src/init.c new file mode 100644 index 00000000..9434863e --- /dev/null +++ b/src/init.c @@ -0,0 +1,196 @@ +#include "E.h" + +void +SetupFallbackClasses(void) +{ + + /* + * This function creates simple internal data members to be used in + * emergencies - ie when all else fails - ie a button is told to use an + * imageclass that doesn't exist, or no DEFAULT border is defined... at + * least E won't barf on us then. + */ + + Border *b; + ImageClass *ic; + ActionClass *ac; + Action *a; + Background *bg; + ImlibColor icl; + TextClass *tc; + + EDBUG(5, "SetupFallbackClasses"); + + /* create a default fallback actionclass for the fallback border */ + ac = CreateAclass("__FALLBACK_ACTION"); + AddItem(ac, ac->name, 0, LIST_TYPE_ACLASS); + a = CreateAction(EVENT_MOUSE_DOWN, 1, 0, 0, 1, 0, NULL, NULL); + AddAction(ac, a); + AddToAction(a, ACTION_MOVE, NULL); + a = CreateAction(EVENT_MOUSE_DOWN, 1, 0, 0, 2, 0, NULL, NULL); + AddAction(ac, a); + AddToAction(a, ACTION_KILL, NULL); + a = CreateAction(EVENT_MOUSE_DOWN, 1, 0, 0, 3, 0, NULL, NULL); + AddAction(ac, a); + AddToAction(a, ACTION_RESIZE, NULL); + + /* create a fallback imageclass in case no imageclass can be found */ + ic = CreateIclass(); + ic->name = duplicate("__FALLBACK_ICLASS"); + ic->norm.normal = CreateImageState(); + ic->norm.normal->hihi.r = 255; + ic->norm.normal->hihi.g = 255; + ic->norm.normal->hihi.b = 255; + ic->norm.normal->hi.r = 255; + ic->norm.normal->hi.g = 255; + ic->norm.normal->hi.b = 255; + ic->norm.normal->bg.r = 160; + ic->norm.normal->bg.g = 160; + ic->norm.normal->bg.b = 160; + ic->norm.normal->lo.r = 0; + ic->norm.normal->lo.g = 0; + ic->norm.normal->lo.b = 0; + ic->norm.normal->lolo.r = 0; + ic->norm.normal->lolo.g = 0; + ic->norm.normal->lolo.b = 0; + ic->norm.normal->bevelstyle = BEVEL_AMIGA; + + ic->norm.hilited = CreateImageState(); + ic->norm.hilited->hihi.r = 255; + ic->norm.hilited->hihi.g = 255; + ic->norm.hilited->hihi.b = 255; + ic->norm.hilited->hi.r = 255; + ic->norm.hilited->hi.g = 255; + ic->norm.hilited->hi.b = 255; + ic->norm.hilited->bg.r = 192; + ic->norm.hilited->bg.g = 192; + ic->norm.hilited->bg.b = 192; + ic->norm.hilited->lo.r = 0; + ic->norm.hilited->lo.g = 0; + ic->norm.hilited->lo.b = 0; + ic->norm.hilited->lolo.r = 0; + ic->norm.hilited->lolo.g = 0; + ic->norm.hilited->lolo.b = 0; + ic->norm.hilited->bevelstyle = BEVEL_AMIGA; + + ic->norm.clicked = CreateImageState(); + ic->norm.clicked->hihi.r = 0; + ic->norm.clicked->hihi.g = 0; + ic->norm.clicked->hihi.b = 0; + ic->norm.clicked->hi.r = 0; + ic->norm.clicked->hi.g = 0; + ic->norm.clicked->hi.b = 0; + ic->norm.clicked->bg.r = 192; + ic->norm.clicked->bg.g = 192; + ic->norm.clicked->bg.b = 192; + ic->norm.clicked->lo.r = 255; + ic->norm.clicked->lo.g = 255; + ic->norm.clicked->lo.b = 255; + ic->norm.clicked->lolo.r = 255; + ic->norm.clicked->lolo.g = 255; + ic->norm.clicked->lolo.b = 255; + ic->norm.clicked->bevelstyle = BEVEL_AMIGA; + + ic->active.normal = CreateImageState(); + ic->active.normal->hihi.r = 255; + ic->active.normal->hihi.g = 255; + ic->active.normal->hihi.b = 255; + ic->active.normal->hi.r = 255; + ic->active.normal->hi.g = 255; + ic->active.normal->hi.b = 255; + ic->active.normal->bg.r = 180; + ic->active.normal->bg.g = 140; + ic->active.normal->bg.b = 160; + ic->active.normal->lo.r = 0; + ic->active.normal->lo.g = 0; + ic->active.normal->lo.b = 0; + ic->active.normal->lolo.r = 0; + ic->active.normal->lolo.g = 0; + ic->active.normal->lolo.b = 0; + ic->active.normal->bevelstyle = BEVEL_AMIGA; + + ic->active.hilited = CreateImageState(); + ic->active.hilited->hihi.r = 255; + ic->active.hilited->hihi.g = 255; + ic->active.hilited->hihi.b = 255; + ic->active.hilited->hi.r = 255; + ic->active.hilited->hi.g = 255; + ic->active.hilited->hi.b = 255; + ic->active.hilited->bg.r = 230; + ic->active.hilited->bg.g = 190; + ic->active.hilited->bg.b = 210; + ic->active.hilited->lo.r = 0; + ic->active.hilited->lo.g = 0; + ic->active.hilited->lo.b = 0; + ic->active.hilited->lolo.r = 0; + ic->active.hilited->lolo.g = 0; + ic->active.hilited->lolo.b = 0; + ic->active.hilited->bevelstyle = BEVEL_AMIGA; + + ic->active.clicked = CreateImageState(); + ic->active.clicked->hihi.r = 0; + ic->active.clicked->hihi.g = 0; + ic->active.clicked->hihi.b = 0; + ic->active.clicked->hi.r = 0; + ic->active.clicked->hi.g = 0; + ic->active.clicked->hi.b = 0; + ic->active.clicked->bg.r = 230; + ic->active.clicked->bg.g = 190; + ic->active.clicked->bg.b = 210; + ic->active.clicked->lo.r = 255; + ic->active.clicked->lo.g = 255; + ic->active.clicked->lo.b = 255; + ic->active.clicked->lolo.r = 255; + ic->active.clicked->lolo.g = 255; + ic->active.clicked->lolo.b = 255; + ic->active.clicked->bevelstyle = BEVEL_AMIGA; + + IclassPopulate(ic); + AddItem(ic, ic->name, 0, LIST_TYPE_ICLASS); + + /* create a fallback border in case no border is found */ + b = CreateBorder("__FALLBACK_BORDER"); + b->border.left = 8; + b->border.right = 8; + b->border.top = 8; + b->border.bottom = 8; + AddBorderPart(b, ic, ac, NULL, NULL, 1, FLAG_BUTTON, 0, 8, 99999, 8, 99999, + -1, 0, 0, 0, 0, + -1, 1024, -1, 0, 7, 1); + AddBorderPart(b, ic, ac, NULL, NULL, 1, FLAG_BUTTON, 0, 8, 99999, 8, 99999, + -1, 0, 0, 1024, -8, + -1, 1024, -1, 1024, -1, 1); + AddBorderPart(b, ic, ac, NULL, NULL, 1, FLAG_BUTTON, 0, 8, 99999, 8, 99999, + -1, 0, 0, 0, 8, + -1, 0, 7, 1024, -9, 1); + + AddBorderPart(b, ic, ac, NULL, NULL, 1, FLAG_BUTTON, 0, 8, 99999, 8, 99999, + -1, 1024, -8, 0, 8, + -1, 1024, -1, 1024, -9, 1); + AddItem(b, b->name, 0, LIST_TYPE_BORDER); + + /* create a fallback background in case no background is found */ + bg = CreateDesktopBG("NONE", &icl, NULL, 0, 0, 0, 0, 0, 0, NULL, + 0, 0, 0, 0, 0); + AddItem(bg, bg->name, 0, LIST_TYPE_BACKGROUND); + + /* create a fallback textclass in case no textclass is found */ + tc = CreateTclass(); + tc->name = "__FALLBACK_TCLASS"; + tc->norm.normal = CreateTextState(); + tc->norm.normal->fontname = duplicate("-*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*"); + tc->norm.normal->fg_col.r = 0; + tc->norm.normal->fg_col.g = 0; + tc->norm.normal->fg_col.b = 0; + AddItem(tc, tc->name, 0, LIST_TYPE_TCLASS); + + EDBUG_RETURN_; +} + +void +SetupInit(void) +{ + EDBUG(5, "SetupInit"); + + EDBUG_RETURN_; +} diff --git a/src/ipc.c b/src/ipc.c new file mode 100644 index 00000000..5a10bcbb --- /dev/null +++ b/src/ipc.c @@ -0,0 +1,4318 @@ +#include "E.h" +#include "timestamp.h" + +/* IPC array member function declarations */ + +/* this is needed for the IPC array below to not give us any warnings + * during compiletime. Since we don't use these anywhere else and I + * don't expect us to ever, we're not going to bother putting them in + * E.h + * --Mandrake + */ + +void IPC_Help(char *params, Client * c); +void IPC_Version(char *params, Client * c); +void IPC_Copyright(char *params, Client * c); +void IPC_AutoSave(char *params, Client * c); +void IPC_DefaultTheme(char *params, Client * c); +void IPC_Restart(char *params, Client * c); +void IPC_RestartWM(char *params, Client * c); +void IPC_RestartTheme(char *params, Client * c); +void IPC_Exit(char *params, Client * c); +void IPC_ForceSave(char *params, Client * c); +void IPC_SMFile(char *params, Client * c); +void IPC_ListThemes(char *params, Client * c); +void IPC_GotoDesktop(char *params, Client * c); +void IPC_ShowIcons(char *params, Client * c); +void IPC_FocusMode(char *params, Client * c); +void IPC_AdvancedFocus(char *params, Client * c); +void IPC_NumDesks(char *params, Client * c); +void IPC_NumAreas(char *params, Client * c); +void IPC_WinOps(char *params, Client * c); +void IPC_WinList(char *params, Client * c); +void IPC_GotoArea(char *params, Client * c); +void IPC_ButtonShow(char *params, Client * c); +void IPC_ActiveNetwork(char *params, Client * c); +void IPC_FX(char *params, Client * c); +void IPC_MoveMode(char *params, Client * c); +void IPC_ResizeMode(char *params, Client * c); +void IPC_Pager(char *params, Client * c); +void IPC_InternalList(char *params, Client * c); +void IPC_SetFocus(char *params, Client * c); +void IPC_DialogOK(char *params, Client * c); +void IPC_SoundClass(char *params, Client * c); +void IPC_ImageClass(char *params, Client * c); +void IPC_ActionClass(char *params, Client * c); +void IPC_ColorModifierClass(char *params, Client * c); +void IPC_TextClass(char *params, Client * c); +void IPC_Border(char *params, Client * c); +void IPC_Button(char *params, Client * c); +void IPC_Background(char *params, Client * c); +void IPC_Cursor(char *params, Client * c); +void IPC_PlaySoundClass(char *params, Client * c); +void IPC_ListClassMembers(char *params, Client * c); +void IPC_GeneralInfo(char *params, Client * c); +void IPC_Modules(char *params, Client * c); +void IPC_DockPosition(char *params, Client * c); + +/* the IPC Array */ + +/* the format of an IPC member of the IPC array is as follows: + * { + * NameOfMyFunction, + * "command_name", + * "quick-help explanation", + * "extended help data" + * "may go on for several lines, be sure\n" + * "to add line feeds when you need them and to \"quote\"\n" + * "properly" + * } + * + * when you add a function into this array, make sure you also add it into + * the declarations above and also put the function in this file. PLEASE + * if you add a new function in, add help to it also. since my end goal + * is going to be to have this whole IPC usable by an end-user or to your + * scripter, it should be easy to learn to use without having to crack + * open the source code. + * --Mandrake + */ + +IPCStruct IPCArray[] = +{ + { + IPC_Help, + "help", + "gives you this help screen", + "Additional parameters will retreive help on many topics - " + "\"help \".\nuse \"help all\" for a list of commands." + }, + { + IPC_Version, + "version", + "displays the current version of Enlightenment running", + NULL + }, + { + IPC_Copyright, + "copyright", + "displays copyright information for Enlightenment", + NULL + }, + { + IPC_AutoSave, + "autosave", + "toggle the Automatic Saving Feature", + "Use \"autosave ?\" to list the current status\n" + "use \"autosave on\" or \"autosave off\" to toggle the status" + }, + { + IPC_DefaultTheme, + "default_theme", + "toggle the default theme", + "Use \"default_theme ?\" to get the current default theme\n" + "use \"default_theme /path/to/theme\"\n" + "you can retrieve a list of available themes from the " + "\"list_themes\" command" + }, + { + IPC_Restart, + "restart", + "Restart Enlightenment", + NULL + }, + { + IPC_RestartWM, + "restart_wm", + "Restart another window manager", + "Use \"restart_wm \" to start another window manager.\n" + "Example: \"restart_wm fvwm\"" + }, + { + IPC_RestartTheme, + "restart_theme", + "Restart with another theme", + "Use \"restart_theme \" to restart enlightenment " + "with another theme\nExample: \"restart_theme icE\"" + }, + { + IPC_Exit, + "exit", + "Exit Enlightenment", + NULL + }, + { + IPC_ForceSave, + "save_config", + "Force Enlightenment to save settings now", + NULL + }, + { + IPC_SMFile, + "sm_file", + "Change the default prefix used for session saves", + "Average users are encouraged not to touch this setting.\n" + "Use \"sm_file ?\" to retreive the current session management " + "file prefix\nUse \"sm_file /path/to/prefix/filenameprefix\" " + "to change." + }, + { + IPC_ListThemes, + "list_themes", + "List currently available themes", + NULL + }, + { + IPC_GotoDesktop, + "goto_desktop", + "Change currently active destkop", + "Use \"goto_desktop num\" to go to a specific desktop.\n" + "Use \"goto_desktop next\" and \"goto_desktop prev\" to go to " + "the next and\n previous desktop\n" + "Use \"goto_desktop ?\" to find out what desktop you are " + "currently on" + }, + { + IPC_GotoArea, + "goto_area", + "Change currently active area", + "Use \"goto_area \" to go to a specific desktop.\n" + "Use \"goto_desktop next \" and \"goto_desktop " + "prev \" to go to the next and\n " + "previous areas\nUse \"goto_area ?\" to find out what area " + "you are currently on" + }, + { + IPC_ShowIcons, + "show_icons", + "Toggle the display of icons on the desktop", + "Use \"show_icons on\" and \"show_icons off\" to change this setting\n" + "Use \"show_icons ?\" to retrieve the current setting" + }, + { + IPC_FocusMode, + "focus_mode", + "Change the current focus mode setting", + "Use \"focus_mode \" to change the focus mode.\n" + "Use \"focus_mode ?\" to retrieve the current setting\n" + "Focus Types:\n" + "click: This is the traditional click-to-focus mode.\n" + "clicknograb: This is a similar focus mode, but without the " + "grabbing of the click\n " + "(you cannot click anywhere in a window to focus it)\n" + "pointer: The focus will follow the mouse pointer\n" + "sloppy: in sloppy-focus, the focus follows the mouse, " + "but when over\n " + "the desktop background the last window does not lose the focus" + }, + { + IPC_AdvancedFocus, + "advanced_focus", + "Toggle Advanced Focus Settings", + "use \"advanced_focus