1 /*****************************************************************************/
2 /** Copyright 1988 by Evans & Sutherland Computer Corporation, **/
3 /** Salt Lake City, Utah **/
4 /** Portions Copyright 1989 by the Massachusetts Institute of Technology **/
5 /** Cambridge, Massachusetts **/
7 /** All Rights Reserved **/
9 /** Permission to use, copy, modify, and distribute this software and **/
10 /** its documentation for any purpose and without fee is hereby **/
11 /** granted, provided that the above copyright notice appear in all **/
12 /** copies and that both that copyright notice and this permis- **/
13 /** sion notice appear in supporting documentation, and that the **/
14 /** names of Evans & Sutherland and M.I.T. not be used in advertising **/
15 /** in publicity pertaining to distribution of the software without **/
16 /** specific, written prior permission. **/
18 /** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/
19 /** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/
20 /** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/
21 /** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/
22 /** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/
23 /** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/
24 /** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/
25 /** OR PERFORMANCE OF THIS SOFTWARE. **/
26 /*****************************************************************************/
28 /***********************************************************************
30 * $XConsortium: menus.c,v 1.186 91/07/17 13:58:00 dave Exp $
34 * 17-Nov-87 Thomas E. LaStrange File created
36 ***********************************************************************/
38 #include <X11/Xmu/CharSet.h>
40 /* djhjr - 10/27/02 */
41 #ifndef NO_REGEX_SUPPORT
42 #include <sys/types.h>
53 #include <ctype.h> /* DSE */
65 #include "add_window.h"
67 #ifndef NO_SOUND_SUPPORT
72 extern void IconUp(), IconDown(), CreateIconWindow();
75 extern void AppletDown();
78 extern void delete_pidfile();
80 /* djhjr - 10/27/02 */
81 extern int MatchName();
83 extern void ResizeTwmWindowContents();
84 extern void SetRaiseWindow();
88 extern int ConstrainedMoveTime;
89 extern TwmWindow *ButtonWindow, *Tmp_win;
90 extern XEvent Event, ButtonEvent;
91 extern char *InitFile;
93 int RootFunction = F_NOFUNCTION;
94 MenuRoot *ActiveMenu = NULL; /* the active menu */
95 MenuItem *ActiveItem = NULL; /* the active menu item */
96 int MoveFunction = F_NOFUNCTION; /* or F_MOVE or F_FORCEMOVE */
97 int WindowMoved = FALSE;
98 int menuFromFrameOrWindowOrTitlebar = FALSE;
100 #ifndef NO_SOUND_SUPPORT
101 int createSoundFromFunction = FALSE;
102 int destroySoundFromFunction = FALSE;
105 void BumpWindowColormap();
107 void HideIconManager();
109 void SendDeleteWindowMessage();
110 void SendSaveYourselfMessage();
113 void WarpScreenToWindow();
114 Cursor NeedToDefer(); /* was an 'int' - Submitted by Michel Eyckmans */
116 int ConstMove = FALSE; /* constrained move variables */
118 /* for comparison against MoveDelta - djhjr - 9/5/98 */
119 static int MenuOrigX, MenuOrigY;
121 /* Globals used to keep track of whether the mouse has moved during
122 a resize function. */
126 extern int origx, origy, origWidth, origHeight;
128 int MenuDepth = 0; /* number of menus up */
132 } MenuOrigins[MAXMENUDEPTH];
133 static Cursor LastCursor;
135 static char *actionHack = ""; /* Submitted by Michel Eyckmans */
138 * context bitmaps for TwmWindows menu, f.showdesktop and f.showiconmgr
141 static int have_twmwindows = -1;
142 static int have_showdesktop = -1;
143 static int have_showlist = -1;
145 void WarpAlongRing();
147 /* djhjr - 4/18/96 */
150 static void Identify();
151 void PaintNormalEntry();
153 /* djhjr - 5/13/98 */
154 static TwmWindow *next_by_class();
155 static int warp_if_warpunmapped();
157 /* djhjr - 7/31/98 */
158 static void setup_restart();
161 /* djhjr - 9/21/99 */
162 int FindMenuOrFuncInBindings();
163 int FindMenuOrFuncInWindows();
164 int FindMenuInMenus();
165 int FindFuncInMenus();
167 /* djhjr - 9/21/99 */
171 /* djhjr - 9/17/02 */
172 static int do_squeezetitle();
177 #define MAX(x,y) ((x)>(y)?(x):(y))
179 #define SHADOWWIDTH 5 /* in pixels */
181 #define EDGE_OFFSET 5 /* DSE */
184 #define PULLDOWNMENU_OFFSET ((Scr->RightHandSidePulldownMenus)?\
185 (ActiveMenu->width - EDGE_OFFSET * 2 - Scr->pullW):\
186 (ActiveMenu->width >> 1)) * DSE *
188 #define PULLDOWNMENU_OFFSET ((Scr->RightHandSidePulldownMenus)?\
189 (JunkWidth - EDGE_OFFSET * 2 - Scr->pullW):\
194 /***********************************************************************
197 * InitMenus - initialize menu roots
199 ***********************************************************************
208 for (i = 0; i < MAX_BUTTONS+1; i++)
209 for (j = 0; j < NUM_CONTEXTS; j++)
210 for (k = 0; k < MOD_SIZE; k++)
212 Scr->Mouse[i][j][k].func = F_NOFUNCTION;
213 Scr->Mouse[i][j][k].item = NULL;
216 Scr->DefaultFunction.func = F_NOFUNCTION;
217 Scr->WindowFunction.func = F_NOFUNCTION;
221 for (key = Scr->FuncKeyRoot.next; key != NULL;)
228 Scr->FuncKeyRoot.next = NULL;
234 /***********************************************************************
237 * AddFuncKey - add a function key to the list
240 * name - the name of the key
241 * cont - the context to look for the key press in
242 * mods - modifier keys that need to be pressed
243 * func - the function to perform
244 * win_name- the window name (if any)
245 * action - the action string associated with the function (if any)
247 ***********************************************************************
250 Bool AddFuncKey (name, cont, mods, func, win_name, action)
252 int cont, mods, func;
261 * Don't let a 0 keycode go through, since that means AnyKey to the
262 * XGrabKey call in GrabKeys().
264 if ((keysym = XStringToKeysym(name)) == NoSymbol ||
265 (keycode = XKeysymToKeycode(dpy, keysym)) == 0)
270 /* see if there already is a key defined for this context */
271 for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next)
273 if (tmp->keysym == keysym &&
281 tmp = (FuncKey *) malloc(sizeof(FuncKey));
282 tmp->next = Scr->FuncKeyRoot.next;
283 Scr->FuncKeyRoot.next = tmp;
287 tmp->keysym = keysym;
288 tmp->keycode = keycode;
292 tmp->win_name = win_name;
293 tmp->action = action;
300 int CreateTitleButton (name, func, action, menuroot, rightside, append)
308 TitleButton *tb = (TitleButton *) malloc (sizeof(TitleButton));
312 "%s: unable to allocate %d bytes for title button\n",
313 ProgramName, sizeof(TitleButton));
318 tb->name = name; /* note that we are not copying */
325 /* tb->bitmap = None;*/ /* WARNING, values not set yet */
326 tb->width = 0; /* see InitTitlebarButtons */
327 tb->height = 0; /* ditto */
330 tb->menuroot = menuroot;
331 tb->rightside = rightside;
333 Scr->TBInfo.nright++;
341 * 1. empty list, prepend left put at head of list
342 * 2. append left, prepend right put in between left and right
343 * 3. append right put at tail of list
345 * Do not refer to widths and heights yet since buttons not created
346 * (since fonts not loaded and heights not known).
348 if ((!Scr->TBInfo.head) || ((!append) && (!rightside))) { /* 1 */
349 tb->next = Scr->TBInfo.head;
350 Scr->TBInfo.head = tb;
351 } else if (append && rightside) { /* 3 */
352 register TitleButton *t;
354 for (t = Scr->TBInfo.head; t->next; t = t->next)
359 register TitleButton *t, *prev = NULL;
361 for (t = Scr->TBInfo.head; t && !t->rightside; t = t->next)
364 tb->next = prev->next;
367 tb->next = Scr->TBInfo.head;
368 Scr->TBInfo.head = tb;
378 * InitTitlebarButtons - Do all the necessary stuff to load in a titlebar
379 * button. If we can't find the button, then put in a question; if we can't
380 * find the question mark, something is wrong and we are probably going to be
381 * in trouble later on.
383 /* was of type 'void', now returns button height - djhjr - 12/10/98 */
384 int InitTitlebarButtons ()
391 * initialize dimensions
393 Scr->TBInfo.width = (Scr->TitleHeight -
394 2 * (Scr->FramePadding + Scr->ButtonIndent));
398 * was 'Scr->use3Dtitles' - djhjr - 8/11/98 *
399 if (Scr->TitleBevelWidth > 0)
400 Scr->TBInfo.pad = ((Scr->TitlePadding > 1)
401 ? ((Scr->TitlePadding + 1) / 2) : 0);
404 Scr->TBInfo.pad = ((Scr->TitlePadding > 1)
405 ? ((Scr->TitlePadding + 1) / 2) : 1);
407 Scr->TBInfo.pad = Scr->TitlePadding;
409 h = Scr->TBInfo.width - 2 * Scr->TBInfo.border;
410 /* djhjr - 10/30/02 */
415 * add in some useful buttons and bindings so that novices can still
416 * use the system. -- modified by DSE
419 if (!Scr->NoDefaultTitleButtons) /* DSE */
421 /* insert extra buttons */
423 /* djhjr - 4/19/96 */
424 /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */
425 if (Scr->TitleBevelWidth > 0) {
426 if (!CreateTitleButton (TBPM_3DDOT, F_ICONIFY, "", (MenuRoot *) NULL,
428 fprintf (stderr, "%s: unable to add iconify button\n", ProgramName);
429 if (!CreateTitleButton (TBPM_3DRESIZE, F_RESIZE, "", (MenuRoot *) NULL,
431 fprintf (stderr, "%s: unable to add resize button\n", ProgramName);
435 if (!CreateTitleButton (TBPM_ICONIFY, F_ICONIFY, "", (MenuRoot *) NULL,
437 fprintf(stderr,"%s: unable to add iconify button\n",ProgramName);
438 if (!CreateTitleButton (TBPM_RESIZE, F_RESIZE, "", (MenuRoot *) NULL,
440 fprintf(stderr,"%s: unable to add resize button\n",ProgramName);
443 if (!Scr->NoDefaultMouseOrKeyboardBindings) /* DSE */
445 AddDefaultBindings ();
448 ComputeCommonTitleOffsets ();
450 /* djhjr - 6/15/98 - moved it back to here... */
451 /* djhjr - 9/14/96 - moved to CreateWindowTitlebarButtons()... */
453 * load in images and do appropriate centering
455 for (tb = Scr->TBInfo.head; tb; tb = tb->next) {
458 tb->bitmap = FindBitmap (tb->name, &tb->width, &tb->height);
460 tb->bitmap = FindBitmap (TBPM_QUESTION, &tb->width, &tb->height);
461 if (!tb->bitmap) { * cannot happen (see util.c) *
463 "%s: unable to add titlebar button \"%s\"\n",
464 ProgramName, tb->name);
469 tb->image = GetImage (tb->name, Scr->TitleC);
471 tb->image = GetImage (TBPM_QUESTION, Scr->TitleC);
472 if (!tb->image) { * cannot happen (see util.c) *
473 fprintf (stderr, "%s: unable to add titlebar button \"%s\"\n",
474 ProgramName, tb->name);
478 /* added width and height - 10/30/02 */
479 image = GetImage (tb->name, h, h, Scr->ButtonBevelWidth * 2,
480 (Scr->ButtonColorIsFrame) ? Scr->BorderColorC : Scr->TitleC);
482 tb->width = image->width;
484 /* added 'height = ' - djhjr - 12/10/98 */
485 height = tb->height = image->height;
487 tb->dstx = (h - tb->width + 1) / 2;
488 if (tb->dstx < 0) { /* clip to minimize copying */
489 tb->srcx = -(tb->dstx);
495 tb->dsty = (h - tb->height + 1) / 2;
497 tb->srcy = -(tb->dsty);
506 /* djhjr - 12/10/98 */
507 return (height > h) ? height : h;
508 /* ...end of moved */
513 /* djhjr - 10/30/02 */
514 void SetMenuIconPixmap(filename)
517 Scr->menuIconName = filename;
520 void PaintEntry(mr, mi, exposure)
525 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
526 if (Scr->MenuBevelWidth > 0)
527 Paint3DEntry (mr, mi, exposure);
529 /* djhjr - 4/22/96 */
532 PaintNormalEntry (mr, mi, exposure);
535 void Paint3DEntry(mr, mi, exposure)
545 y_offset = mi->item_num * Scr->EntryHeight + 2;
548 y_offset = mi->item_num * Scr->EntryHeight + Scr->MenuBevelWidth;
550 y_offset = (mi->item_num - mr->top) * Scr->EntryHeight + Scr->MenuBevelWidth;
553 text_y = y_offset + Scr->MenuFont.y + 2;
555 text_y = y_offset + (((Scr->EntryHeight - Scr->MenuFont.height) / 2) + Scr->MenuFont.y);
557 if (mi->func != F_TITLE)
565 Draw3DBorder (mr->w, 2, y_offset, mr->width - 4, Scr->EntryHeight, 1,
566 mi->highlight, off, True, False);
569 Draw3DBorder (mr->w, 2, y_offset + 1, mr->width - 4, Scr->EntryHeight - 1, 1,
570 mi->highlight, off, True, False);
572 Draw3DBorder (mr->w, Scr->MenuBevelWidth, y_offset + 1, mr->width - 2 * Scr->MenuBevelWidth, Scr->EntryHeight - 1, 1,
573 mi->highlight, off, True, False);
575 /* font was font.font->fid - djhjr - 9/14/03 */
576 FBF(mi->highlight.fore, mi->highlight.back, Scr->MenuFont);
579 XDrawImageString(dpy, mr->w, Scr->NormalGC, mi->x + 2, text_y, mi->item, mi->strlen);
581 /* djhjr - 9/14/03 */
582 #ifndef NO_I18N_SUPPORT
583 MyFont_DrawImageString(dpy, mr->w, &Scr->MenuFont,
585 XDrawImageString(dpy, mr->w,
587 Scr->NormalGC, mi->x + Scr->MenuBevelWidth, text_y, mi->item, mi->strlen);
593 if (mi->user_colors || !exposure)
595 XSetForeground (dpy, Scr->NormalGC, mi->normal.back);
598 XFillRectangle (dpy, mr->w, Scr->NormalGC, 2, y_offset,
599 mr->width - 4, Scr->EntryHeight);
602 XFillRectangle (dpy, mr->w, Scr->NormalGC, 2, y_offset + 1,
603 mr->width - 4, Scr->EntryHeight - 1);
605 XFillRectangle (dpy, mr->w, Scr->NormalGC, Scr->MenuBevelWidth, y_offset + 1,
606 mr->width - 2 * Scr->MenuBevelWidth, Scr->EntryHeight - 1);
608 /* font was font.font->fid - djhjr - 9/14/03 */
609 FBF (mi->normal.fore, mi->normal.back, Scr->MenuFont);
619 XDrawImageString (dpy, mr->w, gc, mi->x + 2, text_y, mi->item, mi->strlen);
621 /* djhjr - 9/14/03 */
622 #ifndef NO_I18N_SUPPORT
623 MyFont_DrawImageString (dpy, mr->w, &Scr->MenuFont,
625 XDrawImageString (dpy, mr->w,
627 gc, mi->x + Scr->MenuBevelWidth, text_y, mi->item, mi->strlen);
631 /* this 'if (...)' - djhjr - 1/19/98 */
632 if (!Scr->BeNiceToColormap)
634 FB (Scr->MenuC.shadd, Scr->MenuC.shadc);
637 XDrawLine (dpy, mr->w, Scr->NormalGC, 1, y_offset + Scr->MenuFont.y + 5,
638 mr->width - 2, y_offset + Scr->MenuFont.y + 5);
641 XDrawLine (dpy, mr->w, Scr->NormalGC, 1, y_offset + Scr->EntryHeight - 1,
642 mr->width - 2, y_offset + Scr->EntryHeight - 1);
644 XDrawLine (dpy, mr->w, Scr->NormalGC, Scr->MenuBevelWidth + 1, y_offset + Scr->EntryHeight - 1,
645 mr->width - Scr->MenuBevelWidth - 3, y_offset + Scr->EntryHeight - 1);
648 FB (Scr->MenuC.shadc, Scr->MenuC.shadd);
651 XDrawLine (dpy, mr->w, Scr->NormalGC, 2, y_offset + Scr->MenuFont.y + 6,
652 mr->width - 3, y_offset + Scr->MenuFont.y + 6);
655 XDrawLine (dpy, mr->w, Scr->NormalGC, 2, y_offset + Scr->EntryHeight,
656 mr->width - 3, y_offset + Scr->EntryHeight);
658 XDrawLine (dpy, mr->w, Scr->NormalGC, Scr->MenuBevelWidth + 2, y_offset + Scr->EntryHeight,
659 mr->width - Scr->MenuBevelWidth - 2, y_offset + Scr->EntryHeight);
663 if (mi->func == F_MENU)
666 * create the pull right pixmap if needed *
667 if (Scr->pullPm == None)
669 Scr->pullPm = Create3DMenuIcon (Scr->MenuFont.height, &Scr->pullW,
670 &Scr->pullH, Scr->MenuC);
675 back = Scr->MenuC.back;
677 Scr->MenuC.back = mi->highlight.back;
679 Scr->MenuC.back = mi->normal.back;
681 Scr->pullW = Scr->pullH = Scr->MenuFont.height;
682 image = GetImage(Scr->menuIconName,
683 Scr->pullW, Scr->pullH,
686 Scr->MenuC.back = back;
692 x = mr->width - Scr->pullW - 5;
694 x = mr->width - Scr->pullW - Scr->MenuBevelWidth - EDGE_OFFSET;
697 y = y_offset + ((Scr->MenuFont.height - Scr->pullH) / 2) + 2;
699 y = y_offset + ((Scr->EntryHeight - Scr->pullH) / 2) + 1;
701 XCopyArea (dpy, image->pixmap, mr->w, gc, 0, 0, Scr->pullW, Scr->pullH, x, y);
708 Draw3DBorder (mr->w, 2, y_offset, mr->width - 4, Scr->EntryHeight, 1,
709 mi->normal, off, True, False);
712 Draw3DBorder (mr->w, 2, y_offset, mr->width - 4, Scr->EntryHeight + 1, 1,
713 mi->normal, off, True, False);
715 Draw3DBorder (mr->w, Scr->MenuBevelWidth, y_offset, mr->width - 2 * Scr->MenuBevelWidth, Scr->EntryHeight + 1, 1,
716 mi->normal, off, True, False);
719 FBF (mi->normal.fore, mi->normal.back, Scr->MenuFont.font->fid);
721 /* font was font.font->fid - djhjr - 9/14/03 */
722 FBF (mi->normal.fore, mi->normal.back, Scr->MenuTitleFont);
725 XDrawImageString (dpy, mr->w, Scr->NormalGC, mi->x + 2, text_y, mi->item, mi->strlen);
727 /* djhjr - 9/14/03 */
728 #ifndef NO_I18N_SUPPORT
729 MyFont_DrawImageString (dpy, mr->w, &Scr->MenuTitleFont,
731 XDrawImageString (dpy, mr->w,
733 Scr->NormalGC, mi->x, text_y, mi->item, mi->strlen);
739 void PaintNormalEntry(mr, mi, exposure)
749 y_offset = mi->item_num * Scr->EntryHeight;
751 y_offset = (mi->item_num - mr->top) * Scr->EntryHeight;
754 text_y = y_offset + Scr->MenuFont.y;
756 text_y = y_offset + (((Scr->EntryHeight - Scr->MenuFont.height) / 2) + Scr->MenuFont.y);
758 if (mi->func != F_TITLE)
764 XSetForeground(dpy, Scr->NormalGC, mi->highlight.back);
766 XFillRectangle(dpy, mr->w, Scr->NormalGC, 0, y_offset,
767 mr->width, Scr->EntryHeight);
769 /* font was font.font->fid - djhjr - 9/14/03 */
770 FBF(mi->highlight.fore, mi->highlight.back, Scr->MenuFont);
772 /* djhjr - 9/14/03 */
773 #ifndef NO_I18N_SUPPORT
774 MyFont_DrawString(dpy, mr->w, &Scr->MenuFont,
776 XDrawString(dpy, mr->w,
778 Scr->NormalGC, mi->x,
779 text_y, mi->item, mi->strlen);
785 if (mi->user_colors || !exposure)
787 XSetForeground(dpy, Scr->NormalGC, mi->normal.back);
789 XFillRectangle(dpy, mr->w, Scr->NormalGC, 0, y_offset,
790 mr->width, Scr->EntryHeight);
792 /* font was font.font->fid - djhjr - 9/14/03 */
793 FBF(mi->normal.fore, mi->normal.back, Scr->MenuFont);
802 /* djhjr - 9/14/03 */
803 #ifndef NO_I18N_SUPPORT
804 MyFont_DrawString(dpy, mr->w, &Scr->MenuFont,
806 XDrawString(dpy, mr->w,
808 gc, mi->x, text_y, mi->item, mi->strlen);
813 XDrawLine (dpy, mr->w, gc, 0, y_offset + Scr->MenuFont.y + 5,
814 mr->width, y_offset + Scr->MenuFont.y + 5);
816 XDrawLine (dpy, mr->w, gc, 0, y_offset + Scr->EntryHeight - 1,
817 mr->width, y_offset + Scr->EntryHeight - 1);
820 if (mi->func == F_MENU)
823 * create the pull right pixmap if needed *
824 if (Scr->pullPm == None)
826 Scr->pullPm = CreateMenuIcon (Scr->MenuFont.height,
827 &Scr->pullW, &Scr->pullH);
832 cp.back = Scr->MenuC.back;
833 if (strncmp(Scr->menuIconName, ":xpm:", 5) != 0)
835 cp.fore = Scr->MenuC.fore;
836 Scr->MenuC.fore = (mi->state) ? mi->highlight.fore : mi->normal.fore;
837 Scr->MenuC.back = (mi->state) ? mi->highlight.back : mi->normal.back;
840 Scr->MenuC.back = (mi->state) ? mi->highlight.back : mi->normal.back;
842 Scr->pullW = Scr->pullH = Scr->MenuFont.height;
843 image = GetImage(Scr->menuIconName,
844 Scr->pullW, Scr->pullH,
847 Scr->MenuC.back = cp.back;
848 if (strncmp(Scr->menuIconName, ":xpm:", 5) != 0)
849 Scr->MenuC.fore = cp.fore;
854 x = mr->width - Scr->pullW - EDGE_OFFSET;
857 y = y_offset + ((Scr->MenuFont.height - Scr->pullH) / 2);
859 y = y_offset + ((Scr->EntryHeight - Scr->pullH) / 2);
862 XCopyPlane(dpy, Scr->pullPm->pixmap, mr->w, gc, 0, 0,
863 Scr->pullW, Scr->pullH, x, y, 1);
865 XCopyArea (dpy, image->pixmap, mr->w, gc, 0, 0,
866 Scr->pullW, Scr->pullH, x, y);
873 XSetForeground(dpy, Scr->NormalGC, mi->normal.back);
875 /* fill the rectangle with the title background color */
876 XFillRectangle(dpy, mr->w, Scr->NormalGC, 0, y_offset,
877 mr->width, Scr->EntryHeight);
879 XSetForeground(dpy, Scr->NormalGC, mi->normal.fore);
881 /* now draw the dividing lines */
883 XDrawLine (dpy, mr->w, Scr->NormalGC, 0, y_offset,
884 mr->width, y_offset);
886 y = ((mi->item_num+1) * Scr->EntryHeight)-1;
887 XDrawLine(dpy, mr->w, Scr->NormalGC, 0, y, mr->width, y);
890 FBF(mi->normal.fore, mi->normal.back, Scr->MenuFont.font->fid);
892 /* font was font.font->fid - djhjr - 9/14/03 */
893 FBF (mi->normal.fore, mi->normal.back, Scr->MenuTitleFont);
895 /* finally render the title */
896 /* djhjr - 9/14/03 */
897 #ifndef NO_I18N_SUPPORT
898 MyFont_DrawString(dpy, mr->w, &Scr->MenuTitleFont,
900 XDrawString(dpy, mr->w,
902 Scr->NormalGC, mi->x, text_y, mi->item, mi->strlen);
906 void PaintMenu(mr, e)
911 /* djhjr - 5/22/00 */
914 /* djhjr - 4/22/96 */
915 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
916 if (Scr->MenuBevelWidth > 0) {
918 Draw3DBorder (mr->w, 0, 0, mr->width, mr->height, 2, Scr->MenuC, off, False, False);
920 Draw3DBorder (mr->w, 0, 0, mr->width, mr->height, Scr->MenuBevelWidth, Scr->MenuC, off, False, False);
923 for (mi = mr->first; mi != NULL; mi = mi->next)
925 /* djhjr - 5/22/00 */
926 if (mi->item_num < mr->top) continue;
929 int y_offset = mi->item_num * Scr->EntryHeight;
931 y_offset = (mi->item_num - mr->top) * Scr->EntryHeight;
933 /* djhjr - 5/22/00 */
934 if (y_offset + Scr->EntryHeight > mr->height) break;
936 /* some servers want the previous entry redrawn - djhjr - 10/24/00 */
937 if (Scr->MenuBevelWidth > 0) y_offset += Scr->EntryHeight;
940 * Be smart about handling the expose, redraw only the entries
943 /* those servers want the next entry redrawn, too - djhjr - 10/24/00 */
944 if (e->xexpose.y < (y_offset + Scr->EntryHeight) &&
945 (e->xexpose.y + e->xexpose.height) > y_offset - ((mr->shadow) ? Scr->EntryHeight : 0))
947 PaintEntry(mr, mi, True);
955 static Bool fromMenu;
957 extern int GlobalFirstTime; /* for StayUpMenus -- PF */
962 int i, x, y, x_root, y_root, entry;
964 MenuItem *badItem = NULL;
965 static int firstTime = True;
970 { /* block until there is an event */
971 #ifdef NEVER /* see the '#else' - Steve Ratcliffe */
973 if (!menuFromFrameOrWindowOrTitlebar && ! Scr->StayUpMenus) {
975 ButtonPressMask | ButtonReleaseMask |
976 EnterWindowMask | ExposureMask |
977 VisibilityChangeMask | LeaveWindowMask |
978 ButtonMotionMask, &Event);
980 if (Event.type == MotionNotify) {
981 /* discard any extra motion events before a release */
982 while(XCheckMaskEvent(dpy,
983 ButtonMotionMask | ButtonReleaseMask, &Event))
984 if (Event.type == ButtonRelease)
988 while (XCheckMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask |
989 EnterWindowMask | ExposureMask, &Event))
990 { /* taken from tvtwm */
993 /* Submitted by Steve Ratcliffe */
994 XNextEvent(dpy, &Event);
997 if (!DispatchEvent ()) continue;
999 if (Event.type == ButtonRelease )
1000 { if (Scr->StayUpMenus)
1002 if (firstTime == True)
1003 { /* it was the first release of the button */
1007 { /* thats the second we need to return now */
1009 menuFromFrameOrWindowOrTitlebar = FALSE;
1016 menuFromFrameOrWindowOrTitlebar = FALSE;
1024 #ifdef NEVER /* see the above - Steve Ratcliffe */
1028 /* re-instated - Steve Ratcliffe */
1029 if (Event.type != MotionNotify)
1032 /* if we haven't received the enter notify yet, wait */
1033 if (!ActiveMenu || !ActiveMenu->entered)
1037 XQueryPointer( dpy, ActiveMenu->w, &JunkRoot, &JunkChild,
1038 &x_root, &y_root, &x, &y, &JunkMask);
1040 /* djhjr - 9/5/98 */
1042 if (abs(x_root - MenuOrigX) < Scr->MoveDelta &&
1043 abs(y_root - MenuOrigY) < Scr->MoveDelta)
1047 /* if we haven't recieved the enter notify yet, wait */
1048 if (ActiveMenu && !ActiveMenu->entered)
1052 XFindContext(dpy, ActiveMenu->w, ScreenContext, (caddr_t *)&Scr);
1054 JunkWidth = ActiveMenu->width;
1055 JunkHeight = ActiveMenu->height;
1056 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1057 if (Scr->MenuBevelWidth > 0)
1059 x -= Scr->MenuBevelWidth;
1060 y -= Scr->MenuBevelWidth;
1062 JunkWidth -= 2 * Scr->MenuBevelWidth;
1063 JunkHeight -= Scr->MenuBevelWidth;
1067 if (x < 0 || y < 0 || x >= JunkWidth || y >= JunkHeight)
1069 if ((x < 0 || y < 0 || x >= JunkWidth || y >= JunkHeight) ||
1070 (ActiveMenu->too_tall && (y < Scr->MenuScrollBorderWidth ||
1071 y > JunkHeight - Scr->MenuScrollBorderWidth)))
1073 if (ActiveItem && ActiveItem->func != F_TITLE)
1075 ActiveItem->state = 0;
1076 PaintEntry(ActiveMenu, ActiveItem, False);
1080 /* menu scrolling - djhjr - 5/22/00 */
1081 if (ActiveMenu->too_tall && x >= 0 && x < JunkWidth)
1083 short j = ActiveMenu->top;
1085 if (y < Scr->MenuScrollBorderWidth)
1087 if (ActiveMenu->top - Scr->MenuScrollJump < 0)
1090 j -= Scr->MenuScrollJump;
1092 else if (y > JunkHeight - Scr->MenuScrollBorderWidth)
1094 int k = JunkHeight / Scr->EntryHeight;
1096 if (ActiveMenu->top + k >= ActiveMenu->items)
1099 j += Scr->MenuScrollJump;
1102 if (ActiveMenu->top != j)
1104 ActiveMenu->top = j;
1105 XClearArea(dpy, ActiveMenu->w, 0, 0, 0, 0, True);
1112 /* look for the entry that the mouse is in */
1114 entry = y / Scr->EntryHeight;
1116 entry = (y / Scr->EntryHeight) + ActiveMenu->top;
1117 for (i = 0, mi = ActiveMenu->first; mi != NULL; i++, mi=mi->next)
1123 /* if there is an active item, we might have to turn it off */
1126 /* is the active item the one we are on ? */
1127 if (ActiveItem->item_num == entry && ActiveItem->state)
1130 /* if we weren't on the active entry, let's turn the old
1133 if (!done && ActiveItem->func != F_TITLE)
1135 ActiveItem->state = 0;
1136 PaintEntry(ActiveMenu, ActiveItem, False);
1140 /* djhjr - 5/22/00 */
1141 if (ActiveMenu->too_tall && y + Scr->EntryHeight > JunkHeight)
1144 /* if we weren't on the active item, change the active item and turn
1152 if (ActiveItem->func != F_TITLE && !ActiveItem->state)
1154 if (ActiveItem && ActiveItem->func != F_TITLE && !ActiveItem->state)
1156 ActiveItem->state = 1;
1157 PaintEntry(ActiveMenu, ActiveItem, False);
1159 if (Scr->StayUpOptionalMenus) /* PF */
1160 GlobalFirstTime = firstTime = False; /* PF */
1165 /* now check to see if we were over the arrow of a pull right entry */
1168 if (ActiveItem->func == F_MENU &&
1170 if (ActiveItem && ActiveItem->func == F_MENU &&
1172 /* ((ActiveMenu->width - x) < (ActiveMenu->width >> 1))) */
1173 ( x > PULLDOWNMENU_OFFSET )) /* DSE */
1175 MenuRoot *save = ActiveMenu;
1176 int savex = MenuOrigins[MenuDepth - 1].x;
1177 int savey = MenuOrigins[MenuDepth - 1].y;
1179 if (MenuDepth < MAXMENUDEPTH) {
1180 PopUpMenu (ActiveItem->sub,
1181 (savex + PULLDOWNMENU_OFFSET), /* DSE */
1182 (savey + ActiveItem->item_num * Scr->EntryHeight)
1183 /*(savey + ActiveItem->item_num * Scr->EntryHeight +
1184 (Scr->EntryHeight >> 1))*/, False);
1185 } else if (!badItem) {
1186 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
1187 badItem = ActiveItem;
1190 /* if the menu did get popped up, unhighlight the active item */
1191 if (save != ActiveMenu && ActiveItem->state)
1193 ActiveItem->state = 0;
1194 PaintEntry(save, ActiveItem, False);
1199 if (badItem != ActiveItem) badItem = NULL;
1206 /***********************************************************************
1209 * NewMenuRoot - create a new menu root
1215 * name - the name of the menu root
1217 ***********************************************************************
1226 #define UNUSED_PIXEL ((unsigned long) (~0)) /* more than 24 bits */
1228 tmp = (MenuRoot *) malloc(sizeof(MenuRoot));
1231 tmp->hi_fore = UNUSED_PIXEL;
1232 tmp->hi_back = UNUSED_PIXEL;
1234 tmp->highlight.fore = UNUSED_PIXEL;
1235 tmp->highlight.back = UNUSED_PIXEL;
1243 tmp->mapped = NEVER_MAPPED;
1247 tmp->real_menu = FALSE;
1249 /* djhjr - 5/22/00 */
1253 if (Scr->MenuList == NULL)
1255 Scr->MenuList = tmp;
1256 Scr->MenuList->next = NULL;
1259 if (Scr->LastMenu == NULL)
1261 Scr->LastMenu = tmp;
1262 Scr->LastMenu->next = NULL;
1266 Scr->LastMenu->next = tmp;
1267 Scr->LastMenu = tmp;
1268 Scr->LastMenu->next = NULL;
1272 if (strcmp(name, TWM_WINDOWS) == 0)
1274 if (strcmp(name, TWM_WINDOWS) == 0 || strcmp(name, VTWM_WINDOWS) == 0)
1282 /***********************************************************************
1285 * AddToMenu - add an item to a root menu
1291 * menu - pointer to the root menu to add the item
1292 * item - the text to appear in the menu
1293 * action - the string to possibly execute
1294 * sub - the menu root if it is a pull-right entry
1295 * func - the numeric function
1296 * fore - foreground color string
1297 * back - background color string
1299 ***********************************************************************
1303 AddToMenu(menu, item, action, sub, func, fore, back)
1305 char *item, *action;
1312 MyFont *font; /* DSE */
1315 fprintf(stderr, "adding menu item=\"%s\", action=%s, sub=%d, f=%d\n",
1316 item, action, sub, func);
1319 tmp = (MenuItem *) malloc(sizeof(MenuItem));
1322 if (menu->first == NULL)
1329 menu->last->next = tmp;
1330 tmp->prev = menu->last;
1335 tmp->strlen = strlen(item);
1336 tmp->action = action;
1342 /* djhjr - 4/22/96 */
1345 if ( func == F_TITLE && (Scr->MenuTitleFont.name != NULL) ) /* DSE */
1346 font= &(Scr->MenuTitleFont);
1348 font= &(Scr->MenuFont);
1350 if (!Scr->HaveFonts) CreateFonts();
1351 /* djhjr - 9/14/03 */
1352 #ifndef NO_I18N_SUPPORT
1353 width = MyFont_TextWidth(font,
1355 width = XTextWidth(font->font,
1360 if (width > menu->width)
1361 menu->width = width;
1363 tmp->user_colors = FALSE;
1364 if (Scr->Monochrome == COLOR && fore != NULL)
1368 save = Scr->FirstTime;
1369 Scr->FirstTime = TRUE;
1372 GetColor(COLOR, &tmp->fore, fore);
1373 GetColor(COLOR, &tmp->back, back);
1375 GetColor(COLOR, &tmp->normal.fore, fore);
1376 GetColor(COLOR, &tmp->normal.back, back);
1378 /* djhjr - 4/22/96 */
1379 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1380 /* rem'd 'Scr->MenuBevelWidth' djhjr - 10/30/02 */
1381 if (/*Scr->MenuBevelWidth > 0 && */!Scr->BeNiceToColormap) GetShadeColors (&tmp->normal);
1383 Scr->FirstTime = save;
1384 tmp->user_colors = TRUE;
1391 tmp->item_num = menu->items++;
1402 for (mr = Scr->MenuList; mr != NULL; mr = mr->next)
1404 if (mr->real_menu == FALSE)
1416 MenuItem *start, *end, *cur, *tmp;
1419 XColor save_fore, save_back;
1421 int fred, fgreen, fblue;
1422 int bred, bgreen, bblue;
1425 /* djhjr - 4/22/96 */
1428 unsigned long valuemask;
1429 XSetWindowAttributes attributes;
1430 Colormap cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c;
1433 if ( Scr->MenuTitleFont.name != NULL ) /* DSE */
1435 Scr->EntryHeight = MAX(Scr->MenuFont.height,
1436 Scr->MenuTitleFont.height) + 4;
1437 titleFont = &(Scr->MenuTitleFont);
1441 Scr->EntryHeight = Scr->MenuFont.height + 4;
1442 titleFont= &(Scr->MenuFont);
1446 /* lets first size the window accordingly */
1447 if (mr->mapped == NEVER_MAPPED)
1449 if (mr->pull == TRUE)
1451 mr->width += 16 + 2 * EDGE_OFFSET; /* DSE */
1456 if (Scr->use3Dmenus) mr->width += 4;
1458 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1459 if (Scr->MenuBevelWidth > 0) mr->width += 2 * Scr->MenuBevelWidth;
1461 width = mr->width + 2 * EDGE_OFFSET; /* DSE */
1463 for (cur = mr->first; cur != NULL; cur = cur->next)
1465 if (cur->func != F_TITLE)
1466 cur->x = EDGE_OFFSET; /* DSE */
1470 /* djhjr - 9/14/03 */
1471 #ifndef NO_I18N_SUPPORT
1472 MyFont_TextWidth(titleFont,
1474 XTextWidth(titleFont->font,
1476 cur->item, cur->strlen);
1480 mr->height = mr->items * Scr->EntryHeight;
1484 if (Scr->use3Dmenus) mr->height += 4;
1486 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1487 if (Scr->MenuBevelWidth > 0) mr->height += 2 * Scr->MenuBevelWidth;
1489 /* djhjr - 4/22/96 */
1490 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1491 borderwidth = (Scr->MenuBevelWidth > 0) ? 0 : 1;
1493 /* djhjr - 5/22/00 */
1494 if (mr->height > Scr->MyDisplayHeight)
1497 mr->height = Scr->MyDisplayHeight - borderwidth * 2;
1500 /* added this 'if () ... else' - djhjr - 4/29/98 */
1501 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1502 if (Scr->MenuBevelWidth > 0)
1503 mr->width += 2 * Scr->MenuBevelWidth + 6;
1510 * Make sure that you don't draw into the shadow window or else
1511 * the background bits there will get saved
1513 valuemask = (CWBackPixel | CWBorderPixel);
1514 attributes.background_pixel = Scr->MenuShadowColor;
1515 attributes.border_pixel = Scr->MenuShadowColor;
1516 if (Scr->SaveUnder) {
1517 valuemask |= CWSaveUnder;
1518 attributes.save_under = True;
1520 mr->shadow = XCreateWindow (dpy, Scr->Root, 0, 0,
1521 (unsigned int) mr->width,
1522 (unsigned int) mr->height,
1525 (unsigned int) CopyFromParent,
1526 (Visual *) CopyFromParent,
1527 valuemask, &attributes);
1530 valuemask = (CWBackPixel | CWBorderPixel | CWEventMask);
1531 attributes.background_pixel = Scr->MenuC.back;
1532 attributes.border_pixel = Scr->MenuC.fore;
1533 attributes.event_mask = (ExposureMask | EnterWindowMask);
1534 if (Scr->SaveUnder) {
1535 valuemask |= CWSaveUnder;
1536 attributes.save_under = True;
1538 if (Scr->BackingStore) {
1539 valuemask |= CWBackingStore;
1540 attributes.backing_store = Always;
1543 mr->w = XCreateWindow (dpy, Scr->Root, 0, 0, (unsigned int) mr->width,
1546 (unsigned int) mr->height, (unsigned int) 1,
1548 (unsigned int) mr->height, (unsigned int) borderwidth,
1550 CopyFromParent, (unsigned int) CopyFromParent,
1551 (Visual *) CopyFromParent,
1552 valuemask, &attributes);
1555 XSaveContext(dpy, mr->w, MenuContext, (caddr_t)mr);
1556 XSaveContext(dpy, mr->w, ScreenContext, (caddr_t)Scr);
1558 mr->mapped = UNMAPPED;
1561 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1562 if (Scr->MenuBevelWidth > 0 && (Scr->Monochrome == COLOR) && (mr->highlight.back == UNUSED_PIXEL)) {
1567 xcol.pixel = Scr->MenuC.back;
1568 XQueryColor (dpy, cmap, &xcol);
1569 sprintf (colname, "#%04x%04x%04x",
1570 5 * (xcol.red / 6), 5 * (xcol.green / 6), 5 * (xcol.blue / 6));
1571 save = Scr->FirstTime;
1572 Scr->FirstTime = True;
1573 GetColor (Scr->Monochrome, &mr->highlight.back, colname);
1574 Scr->FirstTime = save;
1577 /* djhjr - 4/22/96 */
1578 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1579 if (Scr->MenuBevelWidth > 0 && (Scr->Monochrome == COLOR) && (mr->highlight.fore == UNUSED_PIXEL)) {
1583 xcol.pixel = Scr->MenuC.fore;
1584 XQueryColor (dpy, cmap, &xcol);
1585 sprintf (colname, "#%04x%04x%04x",
1586 5 * (xcol.red / 6), 5 * (xcol.green / 6), 5 * (xcol.blue / 6));
1587 save = Scr->FirstTime;
1588 Scr->FirstTime = True;
1589 GetColor (Scr->Monochrome, &mr->highlight.fore, colname);
1590 Scr->FirstTime = save;
1592 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1593 if (Scr->MenuBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&mr->highlight);
1595 /* get the default colors into the menus */
1596 for (tmp = mr->first; tmp != NULL; tmp = tmp->next)
1599 if (!tmp->user_colors) {
1600 if (tmp->func != F_TITLE) {
1601 tmp->fore = Scr->MenuC.fore;
1602 tmp->back = Scr->MenuC.back;
1604 tmp->fore = Scr->MenuTitleC.fore;
1605 tmp->back = Scr->MenuTitleC.back;
1609 if (mr->hi_fore != UNUSED_PIXEL)
1611 tmp->hi_fore = mr->hi_fore;
1612 tmp->hi_back = mr->hi_back;
1616 tmp->hi_fore = tmp->back;
1617 tmp->hi_back = tmp->fore;
1620 if (!tmp->user_colors) {
1621 if (tmp->func != F_TITLE) {
1622 tmp->normal.fore = Scr->MenuC.fore;
1623 tmp->normal.back = Scr->MenuC.back;
1625 tmp->normal.fore = Scr->MenuTitleC.fore;
1626 tmp->normal.back = Scr->MenuTitleC.back;
1630 if (mr->highlight.fore != UNUSED_PIXEL)
1632 tmp->highlight.fore = mr->highlight.fore;
1633 tmp->highlight.back = mr->highlight.back;
1637 tmp->highlight.fore = tmp->normal.back;
1638 tmp->highlight.back = tmp->normal.fore;
1640 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1641 if (Scr->MenuBevelWidth > 0 && !Scr->BeNiceToColormap) {
1642 if (tmp->func != F_TITLE)
1643 GetShadeColors (&tmp->highlight);
1645 GetShadeColors (&tmp->normal);
1649 } /* end for(...) */
1651 if (Scr->Monochrome == MONOCHROME || !Scr->InterpolateMenuColors)
1657 for (; start != NULL; start = start->next)
1659 if (start->user_colors)
1665 for (end = start->next; end != NULL; end = end->next)
1667 if (end->user_colors)
1673 /* we have a start and end to interpolate between */
1674 num = end->item_num - start->item_num;
1677 f1.pixel = start->fore;
1678 XQueryColor(dpy, cmap, &f1);
1679 f2.pixel = end->fore;
1680 XQueryColor(dpy, cmap, &f2);
1682 b1.pixel = start->back;
1683 XQueryColor(dpy, cmap, &b1);
1684 b2.pixel = end->back;
1685 XQueryColor(dpy, cmap, &b2);
1687 f1.pixel = start->normal.fore;
1688 XQueryColor(dpy, cmap, &f1);
1689 f2.pixel = end->normal.fore;
1690 XQueryColor(dpy, cmap, &f2);
1691 b1.pixel = start->normal.back;
1692 XQueryColor(dpy, cmap, &b1);
1693 b2.pixel = end->normal.back;
1694 XQueryColor(dpy, cmap, &b2);
1696 fred = ((int)f2.red - (int)f1.red) / num;
1697 fgreen = ((int)f2.green - (int)f1.green) / num;
1698 fblue = ((int)f2.blue - (int)f1.blue) / num;
1700 bred = ((int)b2.red - (int)b1.red) / num;
1701 bgreen = ((int)b2.green - (int)b1.green) / num;
1702 bblue = ((int)b2.blue - (int)b1.blue) / num;
1705 f3.flags = DoRed | DoGreen | DoBlue;
1708 b3.flags = DoRed | DoGreen | DoBlue;
1710 /* djhjr - 4/23/96 */
1711 start->highlight.back = start->normal.fore;
1712 start->highlight.fore = start->normal.back;
1715 for (i = 0, cur = start->next; i < num; i++, cur = cur->next)
1727 if (Scr->DontInterpolateTitles && (cur->func == F_TITLE))
1728 continue; /* DSE -- from tvtwm */
1730 XAllocColor(dpy, cmap, &f3);
1731 XAllocColor(dpy, cmap, &b3);
1734 cur->hi_back = cur->fore = f3.pixel;
1735 cur->hi_fore = cur->back = b3.pixel;
1737 cur->highlight.back = cur->normal.fore = f3.pixel;
1738 cur->highlight.fore = cur->normal.back = b3.pixel;
1739 cur->user_colors = True;
1747 start->highlight.back = start->normal.fore;
1748 start->highlight.fore = start->normal.back;
1755 /***********************************************************************
1758 * PopUpMenu - pop up a pull down menu
1761 * menu - the root pointer of the menu to pop up
1762 * x, y - location of upper left of menu
1763 * center - whether or not to center horizontally over position
1765 ***********************************************************************
1768 Bool PopUpMenu (menu, x, y, center)
1773 int WindowNameOffset, WindowNameCount;
1774 TwmWindow **WindowNames;
1775 TwmWindow *tmp_win2,*tmp_win3;
1779 (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1);
1781 /* djhjr - 9/5/98 */
1784 if (!menu) return False;
1786 /* djhjr - 6/22/01 */
1787 #ifndef NO_SOUND_SUPPORT
1788 if (!PlaySound(F_MENU)) PlaySound(S_MMAP);
1791 /* djhjr - 5/22/00 */
1793 if (menu->w) XClearArea(dpy, menu->w, 0, 0, 0, 0, True);
1795 InstallRootColormap();
1797 if (menu == Scr->Windows)
1801 /* this is the twm windows menu, let's go ahead and build it */
1809 menu->mapped = NEVER_MAPPED;
1812 AddToMenu(menu, "TWM Windows", NULLSTR, (MenuRoot *)NULL, F_TITLE,NULLSTR,NULLSTR);
1814 AddToMenu(menu, "VTWM Windows", NULLSTR, (MenuRoot *)NULL, F_TITLE,NULLSTR,NULLSTR);
1816 WindowNameOffset=(char *)Scr->TwmRoot.next->name -
1817 (char *)Scr->TwmRoot.next;
1818 for(tmp_win = Scr->TwmRoot.next , WindowNameCount=0;
1820 tmp_win = tmp_win->next)
1823 if (WindowNameCount != 0) /* Submitted by Jennifer Elaan */
1826 (TwmWindow **)malloc(sizeof(TwmWindow *)*WindowNameCount);
1827 WindowNames[0] = Scr->TwmRoot.next;
1828 for(tmp_win = Scr->TwmRoot.next->next , WindowNameCount=1;
1830 tmp_win = tmp_win->next,WindowNameCount++)
1832 /* Submitted by Erik Agsjo <erik.agsjo@aktiedirekt.com> */
1833 if (LookInList(Scr->DontShowInTWMWindows, tmp_win->full_name, &tmp_win->class))
1840 for (i=0;i<WindowNameCount;i++)
1842 if ((*compar)(tmp_win2->name,WindowNames[i]->name) < 0)
1844 tmp_win3 = tmp_win2;
1845 tmp_win2 = WindowNames[i];
1846 WindowNames[i] = tmp_win3;
1849 WindowNames[WindowNameCount] = tmp_win2;
1851 for (i=0; i<WindowNameCount; i++)
1853 AddToMenu(menu, WindowNames[i]->name, (char *)WindowNames[i],
1854 (MenuRoot *)NULL, F_POPUP,NULLSTR,NULLSTR);
1855 if (!Scr->OldFashionedTwmWindowsMenu
1856 && Scr->Monochrome == COLOR)/*RFBCOLOR*/
1858 menu->last->user_colors = TRUE;/*RFBCOLOR*/
1862 WindowNames[i]->virtual.fore;*RFBCOLOR*
1865 menu->last->normal.fore =
1866 WindowNames[i]->virtual.fore;*RFBCOLOR*
1868 menu->last->normal.fore = Scr->MenuC.fore;
1872 WindowNames[i]->virtual.back;*RFBCOLOR*
1874 menu->last->normal.back =
1875 WindowNames[i]->virtual.back;
1877 /**********************************************************/
1879 /* Okay, okay, it's a bit of a kludge. */
1881 /* On the other hand, it's nice to have the VTWM Windows */
1882 /* menu come up with "the right colors". And the colors */
1883 /* from the panner are not a bad choice... */
1885 /**********************************************************/
1893 if (menu->w == None || menu->items == 0) return False;
1895 /* Prevent recursively bringing up menus. */
1896 if (menu->mapped == MAPPED) return False;
1899 * Dynamically set the parent; this allows pull-ups to also be main
1900 * menus, or to be brought up from more than one place.
1902 menu->prev = ActiveMenu;
1905 * Submitted by Steve Ratcliffe
1907 mask = ButtonPressMask | ButtonReleaseMask |
1908 ButtonMotionMask | PointerMotionHintMask;
1909 if (Scr->StayUpMenus)
1910 mask |= PointerMotionMask;
1912 XGrabPointer(dpy, Scr->Root, True, mask,
1913 GrabModeAsync, GrabModeAsync,
1914 Scr->Root, Scr->MenuCursor, CurrentTime);
1917 menu->mapped = MAPPED;
1918 menu->entered = FALSE;
1921 x -= (menu->width / 2);
1922 y -= (Scr->EntryHeight / 2); /* sticky menus would be nice here */
1928 /* next line and " - i" to "x = " and "y = " - djhjr - 5/22/00 */
1929 i = (Scr->MenuBevelWidth > 0) ? 0 : 2;
1930 if (x + menu->width > Scr->MyDisplayWidth) {
1931 x = Scr->MyDisplayWidth - menu->width - i;
1934 if (y + menu->height > Scr->MyDisplayHeight) {
1935 y = Scr->MyDisplayHeight - menu->height - i;
1939 MenuOrigins[MenuDepth].x = x;
1940 MenuOrigins[MenuDepth].y = y;
1943 XMoveWindow(dpy, menu->w, x, y);
1945 XMoveWindow (dpy, menu->shadow, x + SHADOWWIDTH, y + SHADOWWIDTH);
1948 XRaiseWindow (dpy, menu->shadow);
1950 XMapRaised(dpy, menu->w);
1952 XMapWindow (dpy, menu->shadow);
1956 /* djhjr - 9/5/98 */
1957 XQueryPointer(dpy, menu->w, &JunkRoot, &JunkChild,
1958 &x_root, &y_root, &JunkX, &JunkY, &JunkMask);
1967 /***********************************************************************
1970 * PopDownMenu - unhighlight the current menu selection and
1971 * take down the menus
1973 ***********************************************************************
1980 if (ActiveMenu == NULL)
1983 /* djhjr - 6/22/01 */
1984 #ifndef NO_SOUND_SUPPORT
1985 PlaySound(S_MUNMAP);
1990 ActiveItem->state = 0;
1991 PaintEntry(ActiveMenu, ActiveItem, False);
1994 for (tmp = ActiveMenu; tmp != NULL; tmp = tmp->prev)
1997 XUnmapWindow (dpy, tmp->shadow);
1999 XUnmapWindow(dpy, tmp->w);
2000 tmp->mapped = UNMAPPED;
2001 UninstallRootColormap();
2008 if (Context == C_WINDOW || Context == C_FRAME || Context == C_TITLE)
2009 { menuFromFrameOrWindowOrTitlebar = TRUE;
2015 /***********************************************************************
2018 * FindMenuRoot - look for a menu root
2021 * (MenuRoot *) - a pointer to the menu root structure
2024 * name - the name of the menu root
2026 ***********************************************************************
2035 for (tmp = Scr->MenuList; tmp != NULL; tmp = tmp->next)
2037 if (strcmp(name, tmp->name) == 0)
2045 static Bool belongs_to_twm_window (t, w)
2046 register TwmWindow *t;
2049 if (!t) return False;
2053 if (w == t->frame || w == t->title_w || w == t->hilite_w ||
2054 w == t->icon_w || w == t->icon_bm_w) return True;
2057 if (t && t->titlebuttons) {
2058 register TBWindow *tbw;
2059 register int nb = Scr->TBInfo.nleft + Scr->TBInfo.nright;
2060 for (tbw = t->titlebuttons; nb > 0; tbw++, nb--) {
2061 if (tbw->window == w) return True;
2070 * Hack^H^H^H^HWrapper to moves for non-menu contexts.
2072 * djhjr - 10/11/01 10/4/02
2074 static void moveFromCenterWrapper(tmp_win)
2077 if (!tmp_win->opaque_move) XUngrabServer(dpy);
2079 WarpScreenToWindow(tmp_win);
2081 /* now here's a nice little kludge... */
2083 int hilite = tmp_win->highlight;
2085 tmp_win->highlight = True;
2086 SetBorder(tmp_win, (hilite) ? True : False);
2087 tmp_win->highlight = hilite;
2089 Scr->Focus = tmp_win;
2092 if (!tmp_win->opaque_move) XGrabServer(dpy);
2096 * Jason P. Venner jason@tfs.com
2097 * This function is used by F_WARPTO to match the action name
2098 * against window names.
2099 * Re-written to use list.c:MatchName(), allowing VTWM-style wilcards.
2102 int MatchWinName(action, t)
2107 #ifndef NO_REGEX_SUPPORT
2113 if (MatchName(t->full_name, action, &re, LTYPE_ANY_STRING))
2114 if (MatchName(t->class.res_name, action, &re, LTYPE_ANY_STRING))
2115 if (MatchName(t->class.res_class, action, &re, LTYPE_ANY_STRING))
2123 /***********************************************************************
2126 * ExecuteFunction - execute a twm root function
2129 * func - the function to execute
2130 * action - the menu action to execute
2131 * w - the window to execute this function on
2132 * tmp_win - the twm window structure
2133 * event - the event that caused the function
2134 * context - the context in which the button was pressed
2135 * pulldown- flag indicating execution from pull down menu
2138 * TRUE if should continue with remaining actions else FALSE to abort
2140 ***********************************************************************
2143 extern int MovedFromKeyPress;
2146 ExecuteFunction(func, action, w, tmp_win, eventp, context, pulldown)
2157 char buff[MAX_FILE_SIZE];
2159 int do_next_action = TRUE;
2161 actionHack = action; /* Submitted by Michel Eyckmans */
2162 RootFunction = F_NOFUNCTION;
2164 return TRUE; /* XXX should this be FALSE? */
2170 case F_RIGHTICONMGR:
2180 case F_WARP: /* PF */
2181 case F_WARPCLASSNEXT: /* PF */
2182 case F_WARPCLASSPREV: /* PF */
2183 case F_WARPTOSCREEN:
2186 case F_WARPTOICONMGR:
2189 /* djhjr - 4/30/96 */
2192 /* djhjr - 12/14/98 */
2193 case F_STATICICONPOSITIONS:
2195 /* djhjr - 5/30/00 */
2199 /* djhjr - 6/22/01 */
2200 #ifndef NO_SOUND_SUPPORT
2204 /* djhjr - 10/2/01 */
2205 case F_STRICTICONMGR:
2207 /* djhjr - 9/9/02 */
2210 case F_UNBINDBUTTONS:
2215 XGrabPointer(dpy, Scr->Root, True,
2216 ButtonPressMask | ButtonReleaseMask,
2217 GrabModeAsync, GrabModeAsync,
2218 Scr->Root, Scr->WaitCursor, CurrentTime);
2222 /* djhjr - 6/22/01 */
2223 #ifndef NO_SOUND_SUPPORT
2227 case F_SQUEEZECENTER:
2229 case F_SQUEEZERIGHT:
2231 /* djhjr - 11/4/03 */
2247 case F_WARPCLASSNEXT:
2248 case F_WARPCLASSPREV:
2251 case F_WARPTOICONMGR:
2252 case F_WARPTONEWEST:
2253 case F_WARPTOSCREEN:
2254 /* handle uniquely */
2275 case F_RIGHTICONMGR:
2278 case F_SAVEYOURSELF:
2283 /* djhjr - 9/9/02 */
2286 case F_UNBINDBUTTONS:
2289 /* ignore if from a root menu */
2290 if (Context != C_ROOT && Context != C_NO_CONTEXT)
2307 if (WindowMoved) do_next_action = FALSE;
2312 /* added this 'case' and 'if () ... else ' - djhjr - 7/15/98 */
2314 if (func == F_STARTWM)
2316 /* dynamic allocation of (char **)my_argv - djhjr - 9/26/02 */
2318 char *p, *delims = " \t";
2319 char *new_argv = NULL, **my_argv = NULL;
2322 p = strtok(action, delims);
2328 new_argv = (char *)realloc((char *)my_argv,
2329 i * sizeof(char *));
2330 if (new_argv == NULL)
2333 "%s: unable to allocate %d bytes for execvp()\n",
2334 ProgramName, i * sizeof(char *));
2338 my_argv = (char **)new_argv;
2341 my_argv[j++] = strdup(p);
2342 p = strtok(NULL, delims);
2345 if (new_argv != NULL)
2349 /* djhjr - 7/31/98 */
2350 setup_restart(eventp->xbutton.time);
2352 execvp(*my_argv, my_argv);
2353 fprintf(stderr, "%s: unable to start \"%s\"\n",
2354 ProgramName, *my_argv);
2358 if (new_argv == NULL)
2364 free((char *)my_argv);
2368 /* djhjr - 7/31/98 */
2369 RestartVtwm(eventp->xbutton.time);
2376 case F_RIGHTICONMGR:
2379 MoveIconManager(func);
2384 JumpIconManager(func);
2389 /* added this 'if (...) else ...' - djhjr - 9/21/99 */
2390 if (context == C_ROOT)
2394 ShowIconMgr(&Scr->iconmgr);
2397 * New code in list.c necessitates 'next_entry()' and
2398 * 'contents_of_entry()' - djhjr - 10/20/01
2400 for (list = Scr->IconMgrs; list != NULL; list = next_entry(list))
2401 ShowIconMgr((IconMgr *)contents_of_entry(list));
2407 if ((ip = (IconMgr *)LookInList(Scr->IconMgrs, tmp_win->full_name,
2408 &tmp_win->class)) == NULL)
2414 RaiseStickyAbove(); /* DSE */
2421 if (Scr->NoIconManagers)
2424 /* added argument - djhjr - 9/21/99 */
2425 HideIconManager((context == C_ROOT) ? NULL : tmp_win);
2431 /* djhjr - 6/10/98 */
2432 if (Scr->NoIconManagers || Scr->iconmgr.count == 0)
2435 if (DeferExecution(context, func, Scr->SelectCursor))
2441 save_sort = Scr->SortIconMgr;
2442 Scr->SortIconMgr = TRUE;
2444 if (context == C_ICONMGR)
2445 SortIconManager((IconMgr *) NULL);
2446 else if (tmp_win->iconmgr)
2447 SortIconManager(tmp_win->iconmgrp);
2449 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2451 Scr->SortIconMgr = save_sort;
2456 if (DeferExecution(context, func, Scr->SelectCursor))
2465 Identify ((TwmWindow *) NULL);
2468 case F_ZOOMZOOM: /* RFB silly */
2469 /* added args to iconmgrs - djhjr - 10/11/01 */
2470 Zoom( None, NULL, None, NULL );
2473 case F_AUTOPAN:/*RFB F_AUTOPAN*/
2474 { /* toggle autopan *//*RFB F_AUTOPAN*/
2475 static int saved;/*RFB F_AUTOPAN*/
2477 if ( Scr->AutoPanX )
2478 { saved = Scr->AutoPanX;/*RFB F_AUTOPAN*/
2479 Scr->AutoPanX = 0;/*RFB F_AUTOPAN*/
2480 } else { /*RFB F_AUTOPAN*/
2481 Scr->AutoPanX = saved;/*RFB F_AUTOPAN*/
2482 /* if restart with no autopan, we'll set the
2483 ** variable but we won't pan
2485 RaiseAutoPan(); /* DSE */
2487 break;/*RFB F_AUTOPAN*/
2490 case F_STICKYABOVE: /* DSE */
2491 if (Scr->StickyAbove) {
2492 LowerSticky(); Scr->StickyAbove = FALSE;
2493 /* don't change the order of execution! */
2495 Scr->StickyAbove = TRUE; RaiseStickyAbove(); RaiseAutoPan();
2496 /* don't change the order of execution! */
2499 /* break; *//* NOT REACHABLE */
2502 if (DeferExecution(context, func, Scr->SelectCursor))
2505 tmp_win->auto_raise = !tmp_win->auto_raise;
2506 if (tmp_win->auto_raise) ++(Scr->NumAutoRaises);
2507 else --(Scr->NumAutoRaises);
2512 /* djhjr - 6/22/01 */
2513 #ifndef NO_SOUND_SUPPORT
2514 /* sound has priority over bell */
2515 if (PlaySound(func)) break;
2518 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2522 tmp_win = (TwmWindow *)action;
2523 if (Scr->WindowFunction.func != F_NOFUNCTION)
2525 ExecuteFunction(Scr->WindowFunction.func,
2526 Scr->WindowFunction.item->action,
2527 w, tmp_win, eventp, C_FRAME, FALSE);
2532 XRaiseWindow (dpy, tmp_win->frame);
2533 XRaiseWindow (dpy, tmp_win->VirtualDesktopDisplayWindow);
2542 TwmWindow *focused = NULL; /* djhjr - 5/27/03 */
2543 Bool fromtitlebar = False;
2546 int resizefromcenter = 0; /* djhjr - 10/2/02 */
2547 /* djhjr - 10/6/02 */
2548 #ifndef NO_SOUND_SUPPORT
2549 int did_playsound = FALSE;
2552 if (DeferExecution(context, func, Scr->ResizeCursor))
2558 XWarpPointer(dpy, None, Scr->Root, 0, 0, 0, 0,
2559 eventp->xbutton.x_root,
2560 eventp->xbutton.y_root);
2562 EventHandler[EnterNotify] = HandleUnknown;
2563 EventHandler[LeaveNotify] = HandleUnknown;
2565 /* allow the resizing of doors - djhjr - 2/22/99
2566 if ((w != tmp_win->icon_w) && (context != C_DOOR))
2568 if (context == C_ICON) /* can't resize icons */
2570 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2575 * Resizing from a titlebar menu was handled uniquely long
2576 * before I got here, and I added virtual windows and icon
2577 * managers on 9/15/99 and 10/11/01, leveraging that code.
2578 * It's all been integrated here.
2581 if (Context & (C_FRAME_BIT | C_WINDOW_BIT | C_TITLE_BIT)
2582 && menuFromFrameOrWindowOrTitlebar)
2584 XGetGeometry(dpy, w, &JunkRoot, &origDragX, &origDragY,
2585 (unsigned int *)&DragWidth,
2586 (unsigned int *)&DragHeight,
2587 &JunkBW, &JunkDepth);
2589 resizefromcenter = 2;
2591 else if (Context == C_VIRTUAL_WIN)
2595 if ((XFindContext(dpy, eventp->xbutton.subwindow,
2596 VirtualContext, (caddr_t *) &twin) == XCNOENT))
2598 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2604 resizefromcenter = 1;
2606 else if (Context == C_ICONMGR && tmp_win->list)
2608 /* added the second argument - djhjr - 5/28/00 */
2609 if (!warp_if_warpunmapped(tmp_win, F_NOFUNCTION))
2611 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2615 resizefromcenter = 1;
2618 if (resizefromcenter)
2620 WarpScreenToWindow(tmp_win);
2622 XWarpPointer(dpy, None, Scr->Root, 0, 0, 0, 0,
2623 tmp_win->frame_x + tmp_win->frame_width / 2,
2624 tmp_win->frame_y + tmp_win->frame_height / 2);
2626 /* grr - djhjr - 5/27/03 */
2627 focused = Scr->Focus;
2628 Scr->Focus = tmp_win;
2629 SetBorder(Scr->Focus, True);
2631 /* save positions so we can tell if it was moved or not */
2632 ResizeOrigX = tmp_win->frame_x + tmp_win->frame_width / 2;
2633 ResizeOrigY = tmp_win->frame_y + tmp_win->frame_height / 2;
2637 /* save position so we can tell if it was moved or not */
2638 ResizeOrigX = eventp->xbutton.x_root;
2639 ResizeOrigY = eventp->xbutton.y_root;
2642 /* see if this is being done from the titlebar */
2643 fromtitlebar = belongs_to_twm_window(tmp_win,
2644 eventp->xbutton.window);
2646 if (resizefromcenter == 2)
2648 MenuStartResize(tmp_win, origDragX, origDragY,
2649 DragWidth, DragHeight, Context);
2651 releaseEvent = ButtonPress;
2652 movementMask = PointerMotionMask;
2656 StartResize(eventp, tmp_win, fromtitlebar, context);
2658 fromtitlebar = False;
2659 releaseEvent = ButtonRelease;
2660 movementMask = ButtonMotionMask;
2663 /* substantially re-worked - djhjr - 5/27/03 */
2666 /* added exposure event masks - djhjr - 10/11/01 */
2667 XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask |
2668 EnterWindowMask | LeaveWindowMask |
2669 ExposureMask | VisibilityChangeMask |
2670 movementMask, &Event);
2673 * See down below, after this loop - djhjr - 5/27/03
2676 /* discard crossing events before a release - djhjr - 10/11/01 */
2677 if (Event.xany.type == EnterNotify ||
2678 Event.xany.type == LeaveNotify)
2680 /* this can't be the proper place - djhjr - 10/2/02 */
2681 SetBorder(tmp_win, True);
2688 * Don't discard exposure events before release
2689 * or window borders and/or their titles in the
2690 * virtual desktop won't get redrawn - djhjr
2693 /* discard any extra motion events before a release */
2694 if (Event.type == MotionNotify)
2696 /* was 'ButtonMotionMask' - djhjr - 10/11/01 */
2697 while (XCheckMaskEvent(dpy, releaseEvent | movementMask,
2700 if (Event.type == releaseEvent)
2706 * See above, before this loop - djhjr - 5/27/03
2709 if (fromtitlebar && Event.type == ButtonPress) {
2710 fromtitlebar = False;
2715 if (Event.type == releaseEvent)
2719 if (tmp_win->opaque_resize)
2721 ConstrainSize(tmp_win, &origWidth, &origHeight);
2722 SetupWindow(tmp_win, origx, origy,
2723 origWidth, origHeight, -1);
2724 ResizeTwmWindowContents(tmp_win,
2725 origWidth, origHeight);
2728 MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0);
2730 ResizeWindow = None;
2731 resizing_window = 0;
2732 do_next_action = FALSE;
2736 if (resizefromcenter == 2)
2738 /* added passing of 'Context' - djhjr - 9/30/02 */
2739 MenuEndResize(tmp_win, Context);
2744 /* DispatchEvent2() is depreciated - djhjr - 10/6/02 */
2747 /* djhjr - 5/27/03 11/2/03 */
2748 if (!Scr->NoRaiseResize && !Scr->RaiseOnStart &&
2751 XRaiseWindow(dpy, tmp_win->frame);
2752 SetRaiseWindow(tmp_win);
2759 /* DispatchEvent2() is depreciated - djhjr - 10/6/02 */
2760 if (!DispatchEvent()) continue;
2762 if (Event.type != MotionNotify) continue;
2764 XQueryPointer(dpy, Scr->Root,
2765 &JunkRoot, &JunkChild, &JunkX, &JunkY,
2766 &AddingX, &AddingY, &JunkMask);
2768 if (!resizing_window &&
2769 (abs(AddingX - ResizeOrigX) < Scr->MoveDelta &&
2770 abs(AddingY - ResizeOrigY) < Scr->MoveDelta))
2775 resizing_window = 1;
2778 /* djhjr - 5/27/03 11/3/03 */
2779 if ((!Scr->NoRaiseResize && Scr->RaiseOnStart)
2780 /* trap a Shape extention bug - djhjr - 5/27/03 */
2781 || (tmp_win->opaque_resize &&
2783 (tmp_win->wShaped || tmp_win->squeeze_info)))
2786 XRaiseWindow(dpy, tmp_win->frame);
2787 SetRaiseWindow(tmp_win);
2788 if (Scr->Virtual && tmp_win->VirtualDesktopDisplayWindow)
2789 XRaiseWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
2792 /* djhjr - 6/22/01 */
2793 #ifndef NO_SOUND_SUPPORT
2794 if (did_playsound == FALSE)
2797 did_playsound = TRUE;
2801 /* MenuDoResize() is depreciated - djhjr - 10/6/02 */
2802 DoResize(AddingX, AddingY, tmp_win);
2811 if (!Scr->NoGrabServer) XUngrabServer(dpy);
2813 if (!tmp_win->opaque_resize) XUngrabServer(dpy);
2816 * All this stuff from resize.c:EndResize() - djhjr - 10/6/02
2819 if (!tmp_win->opaque_resize)
2820 UninstallRootColormap();
2822 /* discard queued enter and leave events - djhjr - 5/27/03 */
2823 while (XCheckMaskEvent(dpy, EnterWindowMask | LeaveWindowMask,
2827 if (!Scr->NoRaiseResize)
2829 RaiseStickyAbove (); /* DSE */
2833 /* update virtual coords */
2834 tmp_win->virtual_frame_x = Scr->VirtualDesktopX + tmp_win->frame_x;
2835 tmp_win->virtual_frame_y = Scr->VirtualDesktopY + tmp_win->frame_y;
2837 /* UpdateDesktop(tmp_win); Stig */
2839 MoveResizeDesktop(tmp_win, Scr->NoRaiseResize); * Stig *
2841 MoveResizeDesktop(tmp_win, Cancel | Scr->NoRaiseResize); /* Stig */
2843 /* djhjr - 9/30/02 10/6/02 */
2844 if (Context == C_VIRTUAL_WIN)
2847 * Mask a bug that calls MoveOutline(zeros) after the
2848 * border has been repainted, leaving artifacts. I think
2849 * I know what the bug is, but I can't seem to fix it.
2851 if (Scr->BorderBevelWidth > 0) PaintBorders(tmp_win, False);
2853 JunkX = tmp_win->virtual_frame_x + tmp_win->frame_width / 2;
2854 JunkY = tmp_win->virtual_frame_y + tmp_win->frame_height / 2;
2855 XWarpPointer(dpy, None, Scr->VirtualDesktopDisplayOuter,
2856 0, 0, 0, 0, SCALE_D(JunkX), SCALE_D(JunkY));
2858 /* grr - djhjr - 5/27/03 */
2859 SetBorder(Scr->Focus, False);
2860 Scr->Focus = focused;
2863 /* djhjr - 6/4/98 */
2864 /* don't re-map if the window is the virtual desktop - djhjr - 2/28/99 */
2865 if (Scr->VirtualReceivesMotionEvents &&
2866 /* !tmp_win->opaque_resize && */
2867 tmp_win->w != Scr->VirtualDesktopDisplayOuter)
2869 XUnmapWindow(dpy, Scr->VirtualDesktopDisplay);
2870 XMapWindow(dpy, Scr->VirtualDesktopDisplay);
2883 if (DeferExecution(context, func, Scr->SelectCursor))
2886 /* djhjr - 4/1/00 */
2889 fullzoom(tmp_win, func);
2890 /* UpdateDesktop(tmp_win); Stig */
2891 MoveResizeDesktop(tmp_win, Scr->NoRaiseMove); /* Stig */
2897 static Time last_time = 0;
2899 Bool fromtitlebar = False;
2900 int moving_icon = FALSE;
2901 int constMoveDir, constMoveX, constMoveY;
2902 int constMoveXL, constMoveXR, constMoveYT, constMoveYB;
2907 int movefromcenter = 0; /* djhjr - 10/4/02 */
2908 /* djhjr - 6/22/01 */
2909 #ifndef NO_SOUND_SUPPORT
2910 int did_playsound = FALSE;
2913 if (DeferExecution(context, func, Scr->MoveCursor))
2917 rootw = eventp->xbutton.root;
2920 XWarpPointer(dpy, None, Scr->Root,
2921 0, 0, 0, 0, eventp->xbutton.x_root,
2922 eventp->xbutton.y_root);
2924 EventHandler[EnterNotify] = HandleUnknown;
2925 EventHandler[LeaveNotify] = HandleUnknown;
2928 if (!Scr->NoGrabServer || !Scr->OpaqueMove) XGrabServer(dpy);
2931 if (!Scr->NoGrabServer) XGrabServer(dpy);
2933 if (!tmp_win->opaque_move) XGrabServer(dpy);
2935 /* use initialized size... djhjr - 5/9/96
2937 Scr->SizeStringOffset = SIZE_HINDENT;
2938 XResizeWindow(dpy, Scr->SizeWindow,
2939 Scr->SizeStringWidth + SIZE_HINDENT * 2,
2940 Scr->SizeFont.height + SIZE_VINDENT * 2);
2943 XGrabPointer(dpy, eventp->xbutton.root, True,
2944 ButtonPressMask | ButtonReleaseMask |
2945 ButtonMotionMask | PointerMotionMask,
2946 /* PointerMotionHintMask */
2947 GrabModeAsync, GrabModeAsync,
2948 Scr->Root, Scr->MoveCursor, CurrentTime);
2950 /* added this 'if (...) else' - djhjr - 10/11/01 */
2951 if (context == C_VIRTUAL_WIN)
2955 if ((XFindContext(dpy, eventp->xbutton.subwindow,
2956 VirtualContext, (caddr_t *) &twin) == XCNOENT))
2958 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2963 moveFromCenterWrapper(tmp_win);
2964 /* these two - djhjr - 10/4/02 */
2970 /* added this 'if (...) else' - djhjr - 9/15/99 */
2971 if (context == C_ICONMGR && tmp_win->list)
2973 /* added the second argument - djhjr - 5/28/00 */
2974 if (!warp_if_warpunmapped(tmp_win, F_NOFUNCTION))
2976 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2980 moveFromCenterWrapper(tmp_win); /* djhjr - 10/11/01 */
2981 /* these two - djhjr - 10/4/02 */
2987 if (context == C_ICON && tmp_win->icon_w)
2989 DragX = eventp->xbutton.x;
2990 DragY = eventp->xbutton.y;
2992 w = tmp_win->icon_w;
2995 else if (w != tmp_win->icon_w)
2997 XTranslateCoordinates(dpy, w, tmp_win->frame,
3000 &DragX, &DragY, &JunkChild);
3005 XMapRaised (dpy, Scr->SizeWindow);
3009 MoveFunction = func; /* set for DispatchEvent() */
3011 XGetGeometry(dpy, w, &JunkRoot, &origDragX, &origDragY,
3012 (unsigned int *)&DragWidth,
3013 (unsigned int *)&DragHeight,
3014 &JunkBW, &JunkDepth);
3016 /* added this 'if (...) else' - djhjr - 10/4/02 */
3017 if (menuFromFrameOrWindowOrTitlebar ||
3018 movefromcenter || (moving_icon && fromMenu))
3020 origX = DragX = origDragX + DragWidth / 2;
3021 origY = DragY = origDragY + DragHeight / 2;
3025 origX = eventp->xbutton.x_root;
3026 origY = eventp->xbutton.y_root;
3029 CurrentDragX = origDragX;
3030 CurrentDragY = origDragY;
3033 * Only do the constrained move if timer is set -
3034 * need to check it in case of stupid or wicked fast servers.
3036 if ( ConstrainedMoveTime &&
3037 eventp->xbutton.time - last_time < ConstrainedMoveTime)
3042 constMoveDir = MOVE_NONE;
3043 constMoveX = eventp->xbutton.x_root - DragX - JunkBW;
3044 constMoveY = eventp->xbutton.y_root - DragY - JunkBW;
3045 width = DragWidth + 2 * JunkBW;
3046 height = DragHeight + 2 * JunkBW;
3047 constMoveXL = constMoveX + width/3;
3048 constMoveXR = constMoveX + 2*(width/3);
3049 constMoveYT = constMoveY + height/3;
3050 constMoveYB = constMoveY + 2*(height/3);
3052 XWarpPointer(dpy, None, w,
3053 0, 0, 0, 0, DragWidth/2, DragHeight/2);
3055 XQueryPointer(dpy, w, &JunkRoot, &JunkChild,
3056 &JunkX, &JunkY, &DragX, &DragY, &JunkMask);
3058 last_time = eventp->xbutton.time;
3061 if (!Scr->OpaqueMove)
3063 if (!tmp_win->opaque_move)
3065 InstallRootColormap();
3066 /*if (!Scr->MoveDelta)*/ /* djhjr - 10/2/02 */
3069 * Draw initial outline. This was previously done the
3070 * first time though the outer loop by dropping out of
3071 * the XCheckMaskEvent inner loop down to one of the
3072 * MoveOutline's below.
3075 origDragX - JunkBW, origDragY - JunkBW,
3076 DragWidth + 2 * JunkBW, DragHeight + 2 * JunkBW,
3079 moving_icon ? 0 : tmp_win->title_height);
3081 moving_icon ? 0 : tmp_win->title_height + tmp_win->frame_bw3D);
3084 * This next line causes HandleButtonRelease to call
3085 * XRaiseWindow(). This is solely to preserve the
3086 * previous behaviour that raises a window being moved
3087 * on button release even if you never actually moved
3088 * any distance (unless you move less than MoveDelta or
3089 * NoRaiseMove is set or OpaqueMove is set).
3091 * It's set way down below; no need to force it here.
3094 * The code referred to above is 'if 0'd out now anyway.
3102 * see if this is being done from the titlebar
3104 fromtitlebar = belongs_to_twm_window(tmp_win,
3105 eventp->xbutton.window);
3107 /* added 'movefromcenter' and 'moving_icon' - djhjr - 10/4/02 */
3108 if ((menuFromFrameOrWindowOrTitlebar && !fromtitlebar) ||
3109 movefromcenter || (moving_icon && fromMenu))
3111 /* warp the pointer to the middle of the window */
3112 XWarpPointer(dpy, None, Scr->Root, 0, 0, 0, 0,
3113 origDragX + DragWidth / 2,
3114 origDragY + DragHeight / 2);
3116 SetBorder(tmp_win, True); /* grr */
3121 /* djhjr - 4/27/96 */
3122 DisplayPosition(CurrentDragX, CurrentDragY);
3124 if (menuFromFrameOrWindowOrTitlebar)
3126 releaseEvent = ButtonPress;
3127 movementMask = PointerMotionMask;
3131 releaseEvent = ButtonRelease;
3132 movementMask = ButtonMotionMask;
3137 /* block until there is an interesting event */
3138 XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask |
3139 EnterWindowMask | LeaveWindowMask |
3140 ExposureMask | VisibilityChangeMask |
3141 movementMask, &Event);
3144 * See down below, after this loop - djhjr - 5/23/03
3147 /* throw away enter and leave events until release */
3148 if (Event.xany.type == EnterNotify ||
3149 Event.xany.type == LeaveNotify)
3156 * Don't discard exposure events before release
3157 * or window borders and/or their titles in the
3158 * virtual desktop won't get redrawn - djhjr
3161 /* discard any extra motion events before a release */
3162 if (Event.type == MotionNotify)
3164 while (XCheckMaskEvent(dpy, movementMask | releaseEvent,
3167 if (Event.type == releaseEvent)
3173 * There used to be a couple of routines that handled the
3174 * cancel functionality here, each doing a portion of the
3175 * job, then returning immediately. They became redundant
3176 * to just letting program execution fall through. So now,
3177 * the 'if (Event.type == releaseEvent) if (Cancel)' below
3178 * does just that, clearing a few flags first.
3182 if (fromtitlebar && Event.type == ButtonPress)
3184 fromtitlebar = False;
3185 CurrentDragX = origX = Event.xbutton.x_root;
3186 CurrentDragY = origY = Event.xbutton.y_root;
3187 XTranslateCoordinates(dpy, rootw, tmp_win->frame,
3189 &DragX, &DragY, &JunkChild);
3194 /* DispatchEvent2() is depreciated - djhjr - 10/6/02 */
3195 if (!DispatchEvent()) continue;
3197 /* re-wrote this stuff - djhjr - 10/4/02 5/24/03 11/2/03 */
3198 if (Event.type == releaseEvent)
3200 MoveOutline(rootw, 0, 0, 0, 0, 0, 0);
3205 ConstMove = WindowMoved = do_next_action = FALSE;
3207 else if (WindowMoved)
3211 tmp_win->icon_moved = TRUE;
3212 XMoveWindow(dpy, tmp_win->icon_w,
3213 CurrentDragX, CurrentDragY);
3215 if (!Scr->NoRaiseMove && !Scr->RaiseOnStart)
3217 XRaiseWindow(dpy, tmp_win->icon_w);
3218 SetRaiseWindow(tmp_win->icon_w);
3225 tmp_win->frame_x = Event.xbutton.x_root -
3227 tmp_win->frame_y = Event.xbutton.y_root -
3232 tmp_win->frame_x = CurrentDragX;
3233 tmp_win->frame_y = CurrentDragY;
3236 XMoveWindow(dpy, tmp_win->frame,
3237 tmp_win->frame_x, tmp_win->frame_y);
3238 SendConfigureNotify(tmp_win, tmp_win->frame_x,
3241 if (!Scr->NoRaiseMove && !Scr->RaiseOnStart)
3243 XRaiseWindow(dpy, tmp_win->frame);
3244 SetRaiseWindow(tmp_win);
3252 /* something left to do only if the pointer moved */
3253 if (Event.type != MotionNotify) continue;
3255 XQueryPointer(dpy, rootw, &(eventp->xmotion.root), &JunkChild,
3256 &(eventp->xmotion.x_root),
3257 &(eventp->xmotion.y_root),
3258 &JunkX, &JunkY, &JunkMask);
3260 if (DragWindow == None &&
3261 abs(eventp->xmotion.x_root - origX) < Scr->MoveDelta &&
3262 abs(eventp->xmotion.y_root - origY) < Scr->MoveDelta)
3271 if (!Scr->NoRaiseMove && Scr->OpaqueMove)
3274 if (!Scr->NoRaiseMove && tmp_win->opaque_move)
3275 XRaiseWindow(dpy, DragWindow);
3277 /* djhjr - 5/24/03 11/3/03 */
3278 if (!Scr->NoRaiseMove && Scr->RaiseOnStart)
3282 XRaiseWindow(dpy, tmp_win->icon_w);
3283 SetRaiseWindow(tmp_win->icon_w);
3287 XRaiseWindow(dpy, tmp_win->frame);
3288 SetRaiseWindow(tmp_win);
3290 tmp_win->VirtualDesktopDisplayWindow)
3292 tmp_win->VirtualDesktopDisplayWindow);
3298 switch (constMoveDir)
3301 if (eventp->xmotion.x_root < constMoveXL ||
3302 eventp->xmotion.x_root > constMoveXR)
3304 constMoveDir = MOVE_HORIZ;
3306 if (eventp->xmotion.y_root < constMoveYT ||
3307 eventp->xmotion.y_root > constMoveYB)
3309 constMoveDir = MOVE_VERT;
3311 XQueryPointer(dpy, DragWindow, &JunkRoot,
3312 &JunkChild, &JunkX, &JunkY,
3313 &DragX, &DragY, &JunkMask);
3316 constMoveY = eventp->xmotion.y_root - DragY -
3320 constMoveX = eventp->xmotion.x_root - DragX -
3328 else if (DragWindow != None)
3330 /* added 'movefromcenter' and 'moving_icon' - djhjr - 10/4/02 */
3331 if (!menuFromFrameOrWindowOrTitlebar &&
3332 !movefromcenter && !(moving_icon && fromMenu))
3334 xl = eventp->xmotion.x_root - DragX - JunkBW;
3335 yt = eventp->xmotion.y_root - DragY - JunkBW;
3339 xl = eventp->xmotion.x_root - (DragWidth / 2);
3340 yt = eventp->xmotion.y_root - (DragHeight / 2);
3344 if ((ConstMove && constMoveDir != MOVE_NONE) ||
3347 int width = DragWidth + 2 * JunkBW;
3348 int height = DragHeight + 2 * JunkBW;
3350 if (Scr->DontMoveOff && MoveFunction != F_FORCEMOVE)
3356 if (xr > Scr->MyDisplayWidth)
3357 xl = Scr->MyDisplayWidth - width;
3360 if (yb > Scr->MyDisplayHeight)
3361 yt = Scr->MyDisplayHeight - height;
3367 /* djhjr - 6/22/01 10/6/02 */
3368 #ifndef NO_SOUND_SUPPORT
3369 if ((!ConstMove || constMoveDir != MOVE_NONE) &&
3370 did_playsound == FALSE)
3373 did_playsound = TRUE;
3378 if (Scr->OpaqueMove)
3380 if (tmp_win->opaque_move)
3381 XMoveWindow(dpy, DragWindow, xl, yt);
3383 MoveOutline(eventp->xmotion.root, xl, yt,
3384 width, height, tmp_win->frame_bw,
3386 moving_icon ? 0 : tmp_win->title_height);
3388 moving_icon ? 0 : tmp_win->title_height + tmp_win->frame_bw3D);
3391 * move the small representation window
3392 * this knows a bit much about the internals i guess
3393 * XMoveWindow(dpy, tmp_win->VirtualDesktopDisplayWindow, SCALE_D(xl), SCALE_D(yt));
3395 if (Scr->VirtualReceivesMotionEvents)
3397 tmp_win->virtual_frame_x = R_TO_V_X(xl);
3398 tmp_win->virtual_frame_y = R_TO_V_Y(yt);
3400 MoveResizeDesktop(tmp_win, Scr->NoRaiseMove);
3402 MoveResizeDesktop(tmp_win, TRUE);
3405 /* djhjr - 4/27/96 */
3406 DisplayPosition (xl, yt);
3412 if (!Scr->NoGrabServer) XUngrabServer(dpy);
3414 if (!tmp_win->opaque_move) XUngrabServer(dpy);
3416 /* djhjr - 4/27/96 */
3417 XUnmapWindow (dpy, Scr->SizeWindow);
3419 MovedFromKeyPress = False;
3421 if (!tmp_win->opaque_move)
3422 UninstallRootColormap();
3424 /* discard queued enter and leave events - djhjr - 5/23/03 */
3425 while (XCheckMaskEvent(dpy, EnterWindowMask | LeaveWindowMask,
3429 /* from events.c:HandleButtonRelease() - djhjr - 10/6/02 */
3430 if (!Scr->NoRaiseMove)
3432 RaiseStickyAbove(); /* DSE */
3436 /* update virtual coords */
3437 tmp_win->virtual_frame_x = Scr->VirtualDesktopX + tmp_win->frame_x;
3438 tmp_win->virtual_frame_y = Scr->VirtualDesktopY + tmp_win->frame_y;
3440 /* UpdateDesktop() hoses the stacking order - djhjr - 10/6/02 */
3442 MoveResizeDesktop(tmp_win, Scr->NoRaiseMove);
3444 MoveResizeDesktop(tmp_win, Cancel | Scr->NoRaiseMove);
3446 /* djhjr - 10/4/02 10/6/02 */
3447 if (Context == C_VIRTUAL_WIN)
3450 * Mask a bug that calls MoveOutline(zeros) after the
3451 * border has been repainted, leaving artifacts. I think
3452 * I know what the bug is, but I can't seem to fix it.
3454 if (Scr->BorderBevelWidth > 0) PaintBorders(tmp_win, False);
3456 JunkX = tmp_win->virtual_frame_x + tmp_win->frame_width / 2;
3457 JunkY = tmp_win->virtual_frame_y + tmp_win->frame_height / 2;
3458 XWarpPointer(dpy, None, Scr->VirtualDesktopDisplayOuter,
3459 0, 0, 0, 0, SCALE_D(JunkX), SCALE_D(JunkY));
3462 /* djhjr - 6/4/98 */
3463 /* don't re-map if the window is the virtual desktop - djhjr - 2/28/99 */
3464 if (Scr->VirtualReceivesMotionEvents &&
3465 /* !tmp_win->opaque_move && */
3466 tmp_win->w != Scr->VirtualDesktopDisplayOuter)
3468 XUnmapWindow(dpy, Scr->VirtualDesktopDisplay);
3469 XMapWindow(dpy, Scr->VirtualDesktopDisplay);
3472 MoveFunction = F_NOFUNCTION; /* clear for DispatchEvent() */
3474 /* sanity check (also in events.c:HandleButtonRelease()) - djhjr - 10/6/02 */
3486 if ((mroot = FindMenuRoot(action)) == NULL)
3488 fprintf (stderr, "%s: couldn't find function \"%s\"\n",
3489 ProgramName, action);
3494 * Changed this 'if ()' for deferred keyboard events (see also events.c)
3495 * Submitted by Michel Eyckmans
3497 if (NeedToDefer(mroot) && DeferExecution(context, func, Scr->SelectCursor))
3499 if ((cursor = NeedToDefer(mroot)) != None && DeferExecution(context, func, cursor))
3503 for (mitem = mroot->first; mitem != NULL; mitem = mitem->next)
3505 if (!ExecuteFunction (mitem->func, mitem->action, w,
3506 tmp_win, eventp, context, pulldown))
3515 if (DeferExecution(context, func, Scr->SelectCursor))
3518 /* added '|| (...)' - djhjr - 6/3/03 */
3519 if (tmp_win->icon ||
3520 (func == F_DEICONIFY && tmp_win == tmp_win->list->twm))
3522 /* djhjr - 6/3/03 */
3523 #ifndef NO_SOUND_SUPPORT
3530 * now HERE's a fine bit of kludge! it's to mask a hole in the
3531 * code I can't find that messes up when trying to warp to the
3532 * de-iconified window not in the real screen when WarpWindows
3533 * isn't used. see also the change in DeIconify().
3536 if (!Scr->WarpWindows && (Scr->WarpCursor ||
3537 LookInList(Scr->WarpCursorL, tmp_win->full_name, &tmp_win->class)))
3539 RaiseStickyAbove(); /* DSE */
3542 WarpToWindow(tmp_win); /* PF */
3545 else if (func == F_ICONIFY)
3547 /* djhjr - 9/10/99 */
3549 TwmWindow *tmgr = NULL, *twin = NULL;
3552 /* sanity check for what's next - djhjr - 9/10/99 */
3553 if (XFindContext(dpy, tmp_win->w, DoorContext,
3554 (caddr_t *)&d) != XCNOENT)
3561 * don't iconify if there's no way to get it back - not fool-proof
3564 if (tmp_win->iconify_by_unmapping)
3566 /* iconified by unmapping */
3568 if (tmp_win->list) tmgr = tmp_win->list->iconmgr->twm_win;
3570 if ((tmgr && !tmgr->mapped && tmgr->iconify_by_unmapping) ||
3571 ((Scr->IconManagerDontShow ||
3572 LookInList(Scr->IconMgrNoShow, tmp_win->full_name, &tmp_win->class)) &&
3573 LookInList(Scr->IconMgrShow, tmp_win->full_name, &tmp_win->class) == (char *)NULL))
3575 /* icon manager not mapped or not shown in one */
3577 if (have_twmwindows == -1)
3579 have_twmwindows = 0;
3581 /* better than two calls to FindMenuRoot() */
3582 for (mr = Scr->MenuList; mr != NULL; mr = mr->next)
3583 if (strcmp(mr->name, TWM_WINDOWS) == 0 ||
3584 strcmp(mr->name, VTWM_WINDOWS) == 0)
3586 /* djhjr - 9/21/99 */
3587 have_twmwindows = FindMenuOrFuncInBindings(C_ALL_BITS, mr, F_NOFUNCTION);
3591 /* djhjr - 9/21/99 */
3592 if (have_showdesktop == -1)
3593 have_showdesktop = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWDESKTOP);
3594 if (have_showlist == -1)
3595 have_showlist = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWLIST);
3597 /* djhjr - 9/21/99 */
3598 if (!FindMenuOrFuncInWindows(tmp_win, have_twmwindows, mr, F_NOFUNCTION) ||
3599 LookInList(Scr->DontShowInTWMWindows, tmp_win->full_name, &tmp_win->class))
3601 /* no TwmWindows menu or not shown in it */
3603 if (tmp_win->w == Scr->VirtualDesktopDisplayOuter &&
3604 FindMenuOrFuncInWindows(tmp_win, have_showdesktop, NULL, F_SHOWDESKTOP))
3606 else if (tmp_win->iconmgr &&
3607 FindMenuOrFuncInWindows(tmp_win, have_showlist, NULL, F_SHOWLIST))
3610 FindMenuOrFuncInWindows(tmgr, have_showlist, NULL, F_SHOWLIST))
3614 /* no f.showdesktop or f.showiconmgr */
3616 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3618 if (twin) tmp_win = twin;
3625 if (twin) tmp_win = twin;
3627 if (tmp_win->list || !Scr->NoIconifyIconManagers) /* PF */
3629 /* djhjr - 6/3/03 */
3630 #ifndef NO_SOUND_SUPPORT
3634 Iconify (tmp_win, eventp->xbutton.x_root - EDGE_OFFSET, /* DSE */
3635 eventp->xbutton.y_root - EDGE_OFFSET); /* DSE */
3641 if (DeferExecution(context, func, Scr->SelectCursor))
3647 xwc.stack_mode = Opposite;
3648 if (w != tmp_win->icon_w)
3650 XConfigureWindow (dpy, w, CWStackMode, &xwc);
3651 XConfigureWindow (dpy, tmp_win->VirtualDesktopDisplayWindow, CWStackMode, &xwc);
3653 XLowerWindow(dpy, Scr->VirtualDesktopDScreen);
3658 if (DeferExecution(context, func, Scr->SelectCursor))
3661 /* check to make sure raise is not from the WindowFunction */
3662 if (w == tmp_win->icon_w && Context != C_ROOT)
3663 XRaiseWindow(dpy, tmp_win->icon_w);
3666 XRaiseWindow(dpy, tmp_win->frame);
3667 XRaiseWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
3670 RaiseStickyAbove(); /* DSE */
3676 if (DeferExecution(context, func, Scr->SelectCursor))
3679 if (!(Scr->StickyAbove && tmp_win->nailed)) { /* DSE */
3680 if (w == tmp_win->icon_w)
3681 XLowerWindow(dpy, tmp_win->icon_w);
3683 { XLowerWindow(dpy, tmp_win->frame);
3684 XLowerWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
3685 XLowerWindow(dpy, Scr->VirtualDesktopDScreen);
3692 if (DeferExecution(context, func, Scr->SelectCursor))
3695 if (tmp_win->icon == FALSE)
3697 if (!Scr->FocusRoot && Scr->Focus == tmp_win)
3703 if (Scr->Focus != NULL) {
3704 SetBorder (Scr->Focus, False);
3707 if (Scr->Focus->hilite_w)
3708 XUnmapWindow (dpy, Scr->Focus->hilite_w);
3710 PaintTitleHighlight(Scr->Focus, off);
3714 InstallWindowColormaps (0, tmp_win);
3717 if (tmp_win->hilite_w) XMapWindow (dpy, tmp_win->hilite_w);
3719 PaintTitleHighlight(tmp_win, on);
3721 SetBorder (tmp_win, True);
3722 SetFocus (tmp_win, eventp->xbutton.time);
3723 Scr->FocusRoot = FALSE;
3724 Scr->Focus = tmp_win;
3730 if (DeferExecution(context, func, Scr->DestroyCursor))
3733 /* djhjr - 6/22/01 */
3734 #ifndef NO_SOUND_SUPPORT
3735 /* flag for the handler */
3736 if (PlaySound(func)) destroySoundFromFunction = TRUE;
3739 /* djhjr - 9/10/96 */
3740 if (tmp_win == Scr->VirtualDesktopDisplayTwin)
3742 /* added this 'if (...) ...' and 'if (...) else' - djhjr - 9/21/99 */
3743 if (have_showdesktop == -1)
3744 have_showdesktop = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWDESKTOP);
3745 if (FindMenuOrFuncInWindows(tmp_win, have_showdesktop, NULL, F_SHOWDESKTOP))
3746 XUnmapWindow(dpy, Scr->VirtualDesktopDisplayTwin->frame);
3749 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3756 if (XFindContext(dpy, tmp_win->w, DoorContext,
3757 (caddr_t *) &d) != XCNOENT)
3762 /* for some reason, we don't get the button up event - djhjr - 9/10/99 */
3764 door_delete(tmp_win->w, d);
3770 if (tmp_win->iconmgr) /* don't send ourself a message */
3772 /* added this 'if (...) ...' and 'if (...) else ...' - djhjr - 9/21/99 */
3773 if (have_showlist == -1)
3774 have_showlist = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWLIST);
3775 if (FindMenuOrFuncInWindows(tmp_win, have_showlist, NULL, F_SHOWLIST))
3777 /* added argument - djhjr - 9/21/99 */
3778 HideIconManager(tmp_win);
3781 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3785 /* djhjr - 4/26/99 */
3786 AppletDown(tmp_win);
3788 XKillClient(dpy, tmp_win->w);
3793 if (DeferExecution(context, func, Scr->DestroyCursor))
3796 /* djhjr - 6/22/01 */
3797 #ifndef NO_SOUND_SUPPORT
3798 /* flag for the handler */
3799 if (PlaySound(func)) destroySoundFromFunction = TRUE;
3802 /* djhjr - 9/21/99 */
3803 if (tmp_win == Scr->VirtualDesktopDisplayTwin)
3805 if (have_showdesktop == -1)
3806 have_showdesktop = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWDESKTOP);
3807 if (FindMenuOrFuncInWindows(tmp_win, have_showdesktop, NULL, F_SHOWDESKTOP))
3808 XUnmapWindow(dpy, Scr->VirtualDesktopDisplayTwin->frame);
3810 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3815 /* djhjr - 9/10/99 */
3819 if (XFindContext(dpy, tmp_win->w, DoorContext,
3820 (caddr_t *) &d) != XCNOENT)
3822 /* for some reason, we don't get the button up event - djhjr - 9/10/99 */
3824 door_delete(tmp_win->w, d);
3830 if (tmp_win->iconmgr) /* don't send ourself a message */
3832 /* added this 'if (...) ...' and 'if (...) else ...' - djhjr - 9/21/99 */
3833 if (have_showlist == -1)
3834 have_showlist = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWLIST);
3835 if (FindMenuOrFuncInWindows(tmp_win, have_showlist, NULL, F_SHOWLIST))
3837 /* added argument - djhjr - 9/21/99 */
3838 HideIconManager(tmp_win);
3841 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3843 else if (tmp_win->protocols & DoesWmDeleteWindow)
3845 /* djhjr - 4/26/99 */
3846 AppletDown(tmp_win);
3848 SendDeleteWindowMessage (tmp_win, LastTimestamp());
3851 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3854 case F_SAVEYOURSELF:
3855 if (DeferExecution (context, func, Scr->SelectCursor))
3858 if (tmp_win->protocols & DoesWmSaveYourself)
3859 SendSaveYourselfMessage (tmp_win, LastTimestamp());
3861 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3865 XCirculateSubwindowsUp(dpy, Scr->Root);
3869 XCirculateSubwindowsDown(dpy, Scr->Root);
3874 if (!Scr->NoGrabServer) {
3875 XUngrabServer (dpy);
3879 /* djhjr - 6/22/01 */
3880 #ifndef NO_SOUND_SUPPORT
3881 /* flag for the handler */
3882 if (PlaySound(func)) createSoundFromFunction = TRUE;
3893 strcpy(tmp, action);
3895 XStoreBytes(dpy, tmp, strlen(tmp));
3899 ptr = XFetchBytes(dpy, &count);
3901 if (sscanf (ptr, "%s", tmp) == 1) {
3903 ptr = ExpandFilename(tmp);
3907 count = read (fd, buff, MAX_FILE_SIZE - 1);
3908 if (count > 0) XStoreBytes (dpy, buff, count);
3912 "%s: unable to open cut file \"%s\"\n",
3915 if (ptr != tmp) free (ptr);
3921 fprintf(stderr, "%s: cut buffer is empty\n", ProgramName);
3925 case F_WARPTOSCREEN:
3927 if (strcmp (action, WARPSCREEN_NEXT) == 0) {
3928 WarpToScreen (Scr->screen + 1, 1);
3929 } else if (strcmp (action, WARPSCREEN_PREV) == 0) {
3930 WarpToScreen (Scr->screen - 1, -1);
3931 } else if (strcmp (action, WARPSCREEN_BACK) == 0) {
3932 WarpToScreen (PreviousScreen, 0);
3934 WarpToScreen (atoi (action), 0);
3941 if (strcmp (action, COLORMAP_NEXT) == 0) {
3942 BumpWindowColormap (tmp_win, 1);
3943 } else if (strcmp (action, COLORMAP_PREV) == 0) {
3944 BumpWindowColormap (tmp_win, -1);
3946 BumpWindowColormap (tmp_win, 0);
3951 case F_WARPCLASSNEXT: /* PF */
3952 case F_WARPCLASSPREV: /* PF */
3953 WarpClass(func == F_WARPCLASSNEXT, tmp_win, action);
3956 case F_WARPTONEWEST: /* PF */
3957 /* added '&& warp_if_warpunmapped()' - djhjr - 5/13/98 */
3958 /* added the second argument - djhjr - 5/28/00 */
3959 if (Scr->Newest && warp_if_warpunmapped(Scr->Newest, F_NOFUNCTION))
3964 /* djhjr - 6/3/03 */
3965 #ifndef NO_SOUND_SUPPORT
3969 WarpToWindow(Scr->Newest);
3972 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3977 register TwmWindow *t;
3978 /* djhjr - 6/3/03 */
3979 int did_warpto = FALSE;
3981 for (t = Scr->TwmRoot.next; t != NULL; t = t->next)
3984 * This used to fall through into F_WARP, but the
3985 * warp_if_warpunmapped() meant this loop couldn't
3986 * continue to look for a match in the window list.
3991 if (MatchWinName(action, t) == 0 &&
3992 warp_if_warpunmapped(t, func))
3994 tmp_win = t; /* PF */
3995 RaiseStickyAbove(); /* DSE */
3998 /* djhjr - 6/3/03 */
3999 #ifndef NO_SOUND_SUPPORT
4004 WarpToWindow(tmp_win); /* PF */
4009 /* djhjr - 6/3/03 */
4015 case F_WARP: /* PF */
4017 /* added '&& warp_if_warpunmapped()' - djhjr - 5/13/98 */
4018 /* added the second argument - djhjr - 5/28/00 */
4019 if (tmp_win && warp_if_warpunmapped(tmp_win, F_NOFUNCTION)) /* PF */
4021 RaiseStickyAbove(); /* DSE */
4024 /* djhjr - 6/3/03 */
4025 #ifndef NO_SOUND_SUPPORT
4029 WarpToWindow(tmp_win); /* PF */
4031 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4036 case F_WARPTOICONMGR:
4042 Window raisewin = None, iconwin = None;
4045 * raisewin now points to the window's icon manager entry, and
4046 * iconwin now points to raisewin's icon manager - djhjr - 5/30/00
4048 TwmWindow *raisewin = None;
4049 Window iconwin = None;
4051 WList *raisewin = NULL;
4052 TwmWindow *iconwin = None;
4054 len = strlen(action);
4056 if (tmp_win && tmp_win->list) {
4058 raisewin = tmp_win->list->iconmgr->twm_win->frame;
4061 raisewin = tmp_win->list->iconmgr->twm_win;
4062 iconwin = tmp_win->list->icon;
4064 raisewin = tmp_win->list;
4065 } else if (Scr->iconmgr.active) {
4067 raisewin = Scr->iconmgr.twm_win->frame;
4070 raisewin = Scr->iconmgr.twm_win;
4071 iconwin = Scr->iconmgr.active->w;
4073 raisewin = Scr->iconmgr.active;
4076 for (t = Scr->TwmRoot.next; t != NULL; t = t->next) {
4077 if (strncmp (action, t->icon_name, len) == 0) {
4078 if (t->list && t->list->iconmgr->twm_win->mapped) {
4081 raisewin = t->list->iconmgr->twm_win->frame;
4084 raisewin = t->list->iconmgr->twm_win;
4085 iconwin = t->list->icon;
4094 /* djhjr - 6/14/00 */
4097 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4101 /* djhjr - 5/30/00 */
4102 iconwin = raisewin->iconmgr->twm_win;
4104 /* added '&& warp_if_warpunmapped()' - djhjr - 5/13/98 */
4105 /* added the second argument - djhjr - 5/28/00 */
4106 /* was 'raisewin' - djhjr - 5/30/00 */
4107 if (iconwin && warp_if_warpunmapped(iconwin, F_NOFUNCTION)) {
4108 /* djhjr - 6/3/03 */
4109 #ifndef NO_SOUND_SUPPORT
4114 XWarpPointer (dpy, None, iconwin, 0, 0, 0, 0,
4115 EDGE_OFFSET, EDGE_OFFSET); * DSE *
4117 WarpInIconMgr(raisewin, iconwin);
4119 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4124 case F_SQUEEZELEFT:/*RFB*/
4126 static SqueezeInfo left_squeeze = { J_LEFT, 0, 0 };
4128 /* too much dup'd code - djhjr - 9/17/02 */
4129 if (do_squeezetitle(context, func, tmp_win, &left_squeeze))
4130 return TRUE; /* deferred */
4134 case F_SQUEEZERIGHT:/*RFB*/
4136 static SqueezeInfo right_squeeze = { J_RIGHT, 0, 0 };
4138 /* too much dup'd code - djhjr - 9/17/02 */
4139 if (do_squeezetitle(context, func, tmp_win, &right_squeeze))
4140 return TRUE; /* deferred */
4144 case F_SQUEEZECENTER:/*RFB*/
4146 static SqueezeInfo center_squeeze = { J_CENTER, 0, 0 };
4148 /* too much dup'd code - djhjr - 9/17/02 */
4149 if (do_squeezetitle(context, func, tmp_win, ¢er_squeeze))
4150 return TRUE; /* deferred */
4155 if (DeferExecution (context, func, Scr->SelectCursor))
4157 if ( tmp_win->ring.next || tmp_win->ring.prev )
4158 RemoveWindowFromRing(tmp_win);
4160 AddWindowToRing(tmp_win);
4161 #ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */
4162 tmp_win->ring.cursor_valid = False;
4167 switch (action[0]) {
4169 WarpAlongRing (&eventp->xbutton, True);
4172 WarpAlongRing (&eventp->xbutton, False);
4175 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4181 action = ExpandFilename(action);
4182 fd = open(action, 0);
4185 count = read(fd, buff, MAX_FILE_SIZE - 1);
4187 XStoreBytes(dpy, buff, count);
4193 fprintf (stderr, "%s: unable to open file \"%s\"\n",
4194 ProgramName, action);
4200 XSetWindowAttributes attributes;
4201 unsigned long valuemask;
4203 valuemask = (CWBackPixel | CWBackingStore | CWSaveUnder);
4204 attributes.background_pixel = Scr->Black;
4205 attributes.backing_store = NotUseful;
4206 attributes.save_under = False;
4207 w = XCreateWindow (dpy, Scr->Root, 0, 0,
4208 (unsigned int) Scr->MyDisplayWidth,
4209 (unsigned int) Scr->MyDisplayHeight,
4211 CopyFromParent, (unsigned int) CopyFromParent,
4212 (Visual *) CopyFromParent, valuemask,
4214 XMapWindow (dpy, w);
4215 XDestroyWindow (dpy, w);
4221 if (DeferExecution(context, func, Scr->SelectCursor))
4224 if (context == C_ICON && tmp_win->icon_w)
4225 w = XCreateSimpleWindow(dpy, tmp_win->icon_w,
4226 0, 0, 9999, 9999, 0, Scr->Black, Scr->Black);
4228 w = XCreateSimpleWindow(dpy, tmp_win->frame,
4229 0, 0, 9999, 9999, 0, Scr->Black, Scr->Black);
4232 XDestroyWindow(dpy, w);
4237 if (DeferExecution(context, func, Scr->SelectCursor))
4240 tmp_win->nailed = !tmp_win->nailed;
4241 /* update the vd display */
4242 /* UpdateDesktop(tmp_win); Stig */
4243 NailDesktop(tmp_win); /* Stig */
4246 fprintf(stdout, "%s: nail state of %s is now %s\n",
4247 ProgramName, tmp_win->name, (tmp_win->nailed ? "nailed" : "free"));
4250 RaiseStickyAbove(); /* DSE */
4251 RaiseAutoPan(); /* DSE */
4256 * move a percentage in a particular direction
4259 PanRealScreen(0, (atoi(action) * Scr->MyDisplayHeight) / 100
4260 /* DSE */ ,NULL,NULL);
4263 PanRealScreen(-((atoi(action) * Scr->MyDisplayWidth) / 100), 0
4264 /* DSE */ ,NULL,NULL);
4267 PanRealScreen((atoi(action) * Scr->MyDisplayWidth) / 100, 0
4268 /* DSE */ ,NULL,NULL);
4271 PanRealScreen(0, -((atoi(action) * Scr->MyDisplayHeight) / 100)
4272 /* DSE */ ,NULL,NULL);
4275 case F_RESETDESKTOP:
4276 SetRealScreen(0, 0);
4279 /*SNUG*/ /* Robert Forsman added these two functions <thoth@ufl.edu> */
4281 /*SNUG*/ TwmWindow *scan;
4282 /*SNUG*/ int right, left, up, down;
4283 /*SNUG*/ int inited;
4284 /*SNUG*/ case F_SNUGDESKTOP:
4286 /*SNUG*/ inited = 0;
4287 /*SNUG*/ for (scan = Scr->TwmRoot.next; scan!=NULL; scan = scan->next)
4289 /*SNUG*/ if (scan->nailed)
4291 /*SNUG*/ if (scan->frame_x > Scr->MyDisplayWidth ||
4292 /*SNUG*/ scan->frame_y > Scr->MyDisplayHeight)
4294 /*SNUG*/ if (scan->frame_x+scan->frame_width < 0 ||
4295 /*SNUG*/ scan->frame_y+scan->frame_height < 0)
4297 /*SNUG*/ if ( inited==0 || scan->frame_x<right )
4298 /*SNUG*/ right = scan->frame_x;
4299 /*SNUG*/ if ( inited==0 || scan->frame_y<up )
4300 /*SNUG*/ up = scan->frame_y;
4301 /*SNUG*/ if ( inited==0 || scan->frame_x+scan->frame_width>left )
4302 /*SNUG*/ left = scan->frame_x+scan->frame_width;
4303 /*SNUG*/ if ( inited==0 || scan->frame_y+scan->frame_height>down )
4304 /*SNUG*/ down = scan->frame_y+scan->frame_height;
4305 /*SNUG*/ inited = 1;
4307 /*SNUG*/ if (inited)
4310 /*SNUG*/ if (left-right < Scr->MyDisplayWidth && (right<0 || left>Scr->MyDisplayWidth) )
4311 /*SNUG*/ dx = right - ( Scr->MyDisplayWidth - (left-right) ) /2;
4314 /*SNUG*/ if (down-up < Scr->MyDisplayHeight && (up<0 || down>Scr->MyDisplayHeight) )
4315 /*SNUG*/ dy = up - (Scr->MyDisplayHeight - (down-up) ) /2;
4318 /*SNUG*/ if (dx!=0 || dy!=0)
4319 /*SNUG*/ PanRealScreen(dx,dy,NULL,NULL);
4322 /*SNUG*/ DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4325 /*SNUG*/ DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4328 /*SNUG*/ case F_SNUGWINDOW:
4329 /*SNUG*/ if (DeferExecution(context, func, Scr->SelectCursor))
4330 /*SNUG*/ return TRUE;
4332 /*SNUG*/ inited = 0;
4333 /*SNUG*/ right = tmp_win->frame_x;
4334 /*SNUG*/ left = tmp_win->frame_x + tmp_win->frame_width;
4335 /*SNUG*/ up = tmp_win->frame_y;
4336 /*SNUG*/ down = tmp_win->frame_y + tmp_win->frame_height;
4337 /*SNUG*/ inited = 1;
4338 /*SNUG*/ if (inited)
4342 /*SNUG*/ if (left-right < Scr->MyDisplayWidth)
4344 /*SNUG*/ if (right<0)
4345 /*SNUG*/ dx = right;
4346 /*SNUG*/ else if (left>Scr->MyDisplayWidth)
4347 /*SNUG*/ dx = left - Scr->MyDisplayWidth;
4351 /*SNUG*/ if (down-up < Scr->MyDisplayHeight)
4355 /*SNUG*/ else if (down>Scr->MyDisplayHeight)
4356 /*SNUG*/ dy = down - Scr->MyDisplayHeight;
4359 /*SNUG*/ if (dx!=0 || dy!=0)
4360 /*SNUG*/ PanRealScreen(dx,dy,NULL,NULL);
4363 /*SNUG*/ DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4366 /*SNUG*/ DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4371 /* Next four submitted by Seth Robertson - 9/9/02 */
4376 if (DeferExecution(context, func, Scr->SelectCursor))
4378 for (i = 0; i < MAX_BUTTONS+1; i++)
4379 for (j = 0; j < MOD_SIZE; j++)
4380 if (Scr->Mouse[i][C_WINDOW][j].func != F_NOFUNCTION)
4381 XGrabButton(dpy, i, j, tmp_win->frame,
4382 True, ButtonPressMask | ButtonReleaseMask,
4383 GrabModeAsync, GrabModeAsync, None,
4391 if (DeferExecution(context, func, Scr->SelectCursor))
4393 for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next)
4394 if (tmp->cont == C_WINDOW)
4396 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->w, True,
4397 GrabModeAsync, GrabModeAsync);
4399 GrabModKeys(tmp_win->w, tmp);
4402 case F_UNBINDBUTTONS:
4406 if (DeferExecution(context, func, Scr->SelectCursor))
4408 for (i = 0; i < MAX_BUTTONS+1; i++)
4409 for (j = 0; j < MOD_SIZE; j++)
4410 if (Scr->Mouse[i][C_WINDOW][j].func != F_NOFUNCTION)
4411 XUngrabButton(dpy, i, j, tmp_win->frame);
4418 if (DeferExecution(context, func, Scr->SelectCursor))
4420 for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next)
4421 if (tmp->cont == C_WINDOW)
4423 XUngrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->w);
4425 UngrabModKeys(tmp_win->w, tmp);
4432 * Breaks badly if not called by the default button press.
4436 long releaseEvent = ButtonRelease;
4437 long movementMask = ButtonMotionMask;
4438 #ifndef NO_SOUND_SUPPORT
4439 int did_playsound = FALSE;
4442 StartMoveWindowInDesktop(eventp->xmotion);
4446 /* added exposure event masks - djhjr - 10/11/01 */
4447 XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask |
4448 EnterWindowMask | LeaveWindowMask |
4449 ExposureMask | VisibilityChangeMask |
4450 movementMask, &Event);
4453 * Don't discard exposure events before release
4454 * or window borders and/or their titles in the
4455 * virtual desktop won't get redrawn - djhjr
4458 /* discard any extra motion events before a release */
4459 if (Event.type == MotionNotify)
4461 /* was 'ButtonMotionMask' - djhjr - 10/11/01 */
4462 while (XCheckMaskEvent(dpy, releaseEvent | movementMask,
4465 if (Event.type == releaseEvent)
4470 if (Event.type == releaseEvent)
4472 EndMoveWindowOnDesktop();
4476 if (!DispatchEvent()) continue;
4478 if (Event.type != MotionNotify) continue;
4480 #ifndef NO_SOUND_SUPPORT
4481 if (did_playsound == FALSE)
4484 did_playsound = TRUE;
4488 DoMoveWindowOnDesktop(Event.xmotion.x, Event.xmotion.y);
4491 /* discard queued enter and leave events */
4492 while (XCheckMaskEvent(dpy, EnterWindowMask | LeaveWindowMask,
4496 /* will clear the XGrabPointer() in events.c:HandleButtonPress() */
4504 /* and update the data structures */
4505 SetRealScreen(Scr->VirtualDesktopX, Scr->VirtualDesktopY);
4508 case F_SNAPREALSCREEN:
4509 Scr->snapRealScreen = ! Scr->snapRealScreen;
4512 /* djhjr - 12/14/98 */
4513 case F_STATICICONPOSITIONS:
4514 Scr->StaticIconPositions = ! Scr->StaticIconPositions;
4517 /* djhjr - 12/14/98 */
4518 case F_STRICTICONMGR:
4522 Scr->StrictIconManager = ! Scr->StrictIconManager;
4523 if (Scr->StrictIconManager)
4525 for (t = Scr->TwmRoot.next; t != NULL; t = t->next)
4527 RemoveIconManager(t);
4531 for (t = Scr->TwmRoot.next; t != NULL; t = t->next)
4539 case F_SETREALSCREEN:
4541 int newx = Scr->VirtualDesktopX;
4542 int newy = Scr->VirtualDesktopY;
4544 /* parse the geometry */
4545 JunkMask = XParseGeometry (action, &JunkX, &JunkY, &JunkWidth, &JunkHeight);
4547 if (JunkMask & XValue)
4549 if (JunkMask & YValue)
4553 newx = Scr->VirtualDesktopWidth + newx;
4555 newy = Scr->VirtualDesktopHeight + newy;
4557 SetRealScreen(newx, newy);
4564 XUnmapWindow(dpy, Scr->VirtualDesktopDisplayTwin->frame);
4569 XMapWindow(dpy, Scr->VirtualDesktopDisplayTwin->frame);
4571 /* djhjr - 9/14/96 */
4572 if (Scr->VirtualDesktopDisplayTwin->icon)
4573 DeIconify(Scr->VirtualDesktopDisplayTwin);
4581 if (XFindContext(dpy, tmp_win->w, DoorContext,
4582 (caddr_t *) &d) != XCNOENT)
4583 door_enter(tmp_win->w, d);
4588 { /*marcel@duteca.et.tudelft.nl*/
4591 if (DeferExecution(context, func, Scr->DestroyCursor))
4594 /* djhjr - 6/22/01 */
4595 #ifndef NO_SOUND_SUPPORT
4596 /* flag for the handler */
4597 if (PlaySound(func)) destroySoundFromFunction = TRUE;
4600 if (XFindContext(dpy, tmp_win->w, DoorContext,
4601 (caddr_t *) &d) != XCNOENT)
4603 /* for some reason, we don't get the button up event - djhjr - 5/13/99 */
4606 door_delete(tmp_win->w, d);
4616 /* djhjr - 4/20/98 */
4621 if (XFindContext(dpy, tmp_win->w, DoorContext,
4622 (caddr_t *) &d) != XCNOENT)
4623 door_paste_name(tmp_win->w, d);
4628 /* djhjr - 9/14/96 - it's in Done()...
4632 /* djhjr - 6/22/01 */
4633 #ifndef NO_SOUND_SUPPORT
4634 if (PlaySound(func))
4636 /* allow time to emit */
4637 if (Scr->PauseOnQuit) sleep(Scr->PauseOnQuit);
4646 case F_VIRTUALGEOMETRIES:
4647 Scr->GeometriesAreVirtual = ! Scr->GeometriesAreVirtual;
4650 /* submitted by Ugen Antsilevitch - 5/28/00 */
4652 Scr->WarpVisible = ! Scr->WarpVisible;
4655 /* djhjr - 5/30/00 */
4657 Scr->WarpSnug = ! Scr->WarpSnug;
4660 /* djhjr - 6/22/01 */
4661 #ifndef NO_SOUND_SUPPORT
4666 /* djhjr - 11/15/02 */
4668 PlaySoundAdhoc(action);
4673 if (ButtonPressed == -1) XUngrabPointer(dpy, CurrentTime);
4674 return do_next_action;
4679 /***********************************************************************
4682 * DeferExecution - defer the execution of a function to the
4683 * next button press if the context is C_ROOT
4686 * context - the context in which the mouse button was pressed
4687 * func - the function to defer
4688 * cursor - the cursor to display while waiting
4690 ***********************************************************************
4694 DeferExecution(context, func, cursor)
4698 if (context == C_ROOT)
4700 LastCursor = cursor;
4701 XGrabPointer(dpy, Scr->Root, True,
4702 ButtonPressMask | ButtonReleaseMask,
4703 GrabModeAsync, GrabModeAsync,
4704 Scr->Root, cursor, CurrentTime);
4706 RootFunction = func;
4707 Action = actionHack; /* Submitted by Michel Eyckmans */
4717 /***********************************************************************
4720 * ReGrab - regrab the pointer with the LastCursor;
4722 ***********************************************************************
4727 XGrabPointer(dpy, Scr->Root, True,
4728 ButtonPressMask | ButtonReleaseMask,
4729 GrabModeAsync, GrabModeAsync,
4730 Scr->Root, LastCursor, CurrentTime);
4735 /***********************************************************************
4738 * NeedToDefer - checks each function in the list to see if it
4739 * is one that needs to be defered.
4742 * root - the menu root to check
4744 ***********************************************************************
4747 /* was of type 'int' - Submitted by Michel Eyckmans */
4754 for (mitem = root->first; mitem != NULL; mitem = mitem->next)
4756 switch (mitem->func)
4759 return Scr->ResizeCursor; /* Submitted by Michel Eyckmans */
4762 return Scr->MoveCursor; /* Submitted by Michel Eyckmans */
4763 /* these next four - Submitted by Michel Eyckmans */
4767 return Scr->DestroyCursor;
4768 case F_IDENTIFY: /* was with 'F_RESIZE' - Submitted by Michel Eyckmans */
4786 return Scr->SelectCursor;
4798 static char buf[256];
4799 char *ds = DisplayString (dpy);
4801 char oldDisplay[256];
4805 char *append_this = " &";
4806 char *es = (char *)malloc(strlen(s)+strlen(append_this)+1);
4808 /* a new copy of s, with extra space incase -- DSE */
4810 if (Scr->EnhancedExecResources) /* DSE */
4812 /* chop all space characters from the end of the string */
4813 while ( isspace ( es[strlen(es)-1] ) )
4815 es[strlen(es)-1] = '\0';
4817 switch ( es[strlen(es)-1] ) /* last character */
4820 es[strlen(es)-1] = '\0'; /* remove the semicolon */
4822 case '&': /* already there so do nothing */
4825 strcat(es,append_this); /* don't block the window manager */
4830 oldDisplay[0] = '\0';
4831 doisplay=getenv("DISPLAY");
4833 strcpy (oldDisplay, doisplay);
4836 * Build a display string using the current screen number, so that
4837 * X programs which get fired up from a menu come up on the screen
4838 * that they were invoked from, unless specifically overridden on
4839 * their command line.
4841 colon = rindex (ds, ':');
4842 if (colon) { /* if host[:]:dpy */
4843 strcpy (buf, "DISPLAY=");
4845 colon = buf + 8 + (colon - ds); /* use version in buf */
4846 dot1 = index (colon, '.'); /* first period after colon */
4847 if (!dot1) dot1 = colon + strlen (colon); /* if not there, append */
4848 (void) sprintf (dot1, ".%d", Scr->screen);
4853 (void) system (es); /* DSE */
4854 free (es); /* DSE */
4856 if (restorevar) { /* why bother? */
4857 (void) sprintf (buf, "DISPLAY=%s", oldDisplay);
4864 /***********************************************************************
4867 * FocusOnRoot - put input focus on the root window
4869 ***********************************************************************
4875 SetFocus ((TwmWindow *) NULL, LastTimestamp());
4876 if (Scr->Focus != NULL)
4878 SetBorder (Scr->Focus, False);
4881 if (Scr->Focus->hilite_w) XUnmapWindow (dpy, Scr->Focus->hilite_w);
4883 PaintTitleHighlight(Scr->Focus, off);
4886 InstallWindowColormaps(0, &Scr->TwmRoot);
4888 Scr->FocusRoot = TRUE;
4891 void DeIconify(tmp_win)
4897 * De-iconify the main window first
4900 /* re-vamped the zoom stuff - djhjr - 10/11/01 */
4901 if (Scr->DoZoom && Scr->ZoomCount > 0)
4903 IconMgr *ipf = NULL;
4904 Window wt = None, wf = None;
4908 if (tmp_win->icon_on)
4910 wf = tmp_win->icon_w; wt = tmp_win->frame;
4912 else if (tmp_win->list) /* djhjr - 10/11/01 */
4914 wf = tmp_win->list->w; wt = tmp_win->frame;
4915 ipf = tmp_win->list->iconmgr;
4917 else if (tmp_win->group != None)
4919 for (t = Scr->TwmRoot.next; t != NULL; t = t->next)
4920 if (tmp_win->group == t->w)
4924 else if (t->list) /* djhjr - 10/11/01 */
4927 ipf = t->list->iconmgr;
4930 wt = tmp_win->frame;
4936 /* added Zoom()s args to iconmgrs - djhjr - 10/11/01 */
4937 if (Scr->ZoomZoom || (wf != None && wt != None))
4938 Zoom(wf, ipf, wt, NULL); /* RFBZOOM */
4941 XMapWindow(dpy, tmp_win->w);
4942 tmp_win->mapped = TRUE;
4944 if (Scr->NoRaiseDeicon)
4945 XMapWindow(dpy, tmp_win->frame);
4948 XMapRaised(dpy, tmp_win->frame);
4949 XRaiseWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
4951 SetMapStateProp(tmp_win, NormalState);
4953 if (tmp_win->icon_w) {
4954 XUnmapWindow(dpy, tmp_win->icon_w);
4958 tmp_win->icon = FALSE;
4959 tmp_win->icon_on = FALSE;
4962 XUnmapWindow(dpy, tmp_win->list->icon);
4965 * RemoveIconManager() done in events.c:HandleMapNotify()
4968 UpdateDesktop(tmp_win);
4971 * Now de-iconify transients
4974 for (t = Scr->TwmRoot.next; t != NULL; t = t->next)
4976 if (t->transient && t->transientfor == tmp_win->w)
4978 /* this 'if (...) else' (see also Iconify()) - djhjr - 6/22/99 */
4979 if (Scr->DontDeiconifyTransients && t->icon_w &&
4980 t->icon == TRUE && t->icon_on == FALSE)
4983 XMapRaised(dpy, t->icon_w);
4988 /* added Zoom()s args to iconmgrs - djhjr - 10/11/01 */
4990 Zoom(t->icon_w, NULL, t->frame, NULL);
4992 Zoom(tmp_win->icon_w, NULL, t->frame, NULL);
4994 XMapWindow(dpy, t->w);
4997 if (Scr->NoRaiseDeicon)
4998 XMapWindow(dpy, t->frame);
5001 XMapRaised(dpy, t->frame);
5002 XRaiseWindow(dpy, t->VirtualDesktopDisplayWindow);
5004 SetMapStateProp(t, NormalState);
5008 XUnmapWindow(dpy, t->icon_w);
5015 if (t->list) XUnmapWindow(dpy, t->list->icon);
5018 * RemoveIconManager() done in events.c:HandleMapNotify()
5026 RaiseStickyAbove(); /* DSE */
5030 * added '&& Scr->WarpWindows'.
5031 * see the kludge in ExecuteFunction(F_ICONIFY, ...).
5034 if (((Scr->WarpCursor ||
5035 LookInList(Scr->WarpCursorL, tmp_win->full_name,
5036 &tmp_win->class)) &&
5037 tmp_win->icon) && Scr->WarpWindows)
5038 WarpToWindow (tmp_win);
5045 void Iconify(tmp_win, def_x, def_y)
5051 XWindowAttributes winattrs;
5052 unsigned long eventMask;
5053 /* djhjr - 6/22/99 */
5056 iconify = ((!tmp_win->iconify_by_unmapping) || tmp_win->transient);
5059 if (tmp_win->icon_w == None)
5060 CreateIconWindow(tmp_win, def_x, def_y);
5064 XMapRaised(dpy, tmp_win->icon_w);
5066 RaiseStickyAbove(); /* DSE */
5070 XGetWindowAttributes(dpy, tmp_win->w, &winattrs);
5071 eventMask = winattrs.your_event_mask;
5074 * Iconify transients first
5077 for (t = Scr->TwmRoot.next; t != NULL; t = t->next)
5079 if (t->transient && t->transientfor == tmp_win->w)
5082 /* RemoveFromDesktop(t); Stig */
5085 * Prevent the receipt of an UnmapNotify, since that would
5086 * cause a transition to the Withdrawn state.
5089 XSelectInput(dpy, t->w, eventMask & ~StructureNotifyMask);
5090 XUnmapWindow(dpy, t->w);
5091 XSelectInput(dpy, t->w, eventMask);
5092 XUnmapWindow(dpy, t->frame);
5094 /* moved to make zooms more aesthetically pleasing -- DSE */
5097 /* added Zoom()s args to iconmgrs - djhjr - 10/11/01 */
5099 Zoom(t->icon_w, NULL, tmp_win->icon_w, NULL);
5101 Zoom(t->frame, NULL, tmp_win->icon_w, NULL);
5105 XUnmapWindow(dpy, t->icon_w);
5106 SetMapStateProp(t, IconicState);
5107 SetBorder (t, False);
5108 if (t == Scr->Focus)
5110 SetFocus ((TwmWindow *) NULL, LastTimestamp());
5112 Scr->FocusRoot = TRUE;
5116 * let current status ride, but "fake out" UpdateDesktop()
5117 * (see also DeIconify()) - djhjr - 6/22/99
5119 fake_icon = t->icon;
5124 /* djhjr - 10/2/01 */
5125 if (Scr->StrictIconManager)
5129 if (t->list) XMapWindow(dpy, t->list->icon);
5133 /* restore icon status - djhjr - 6/22/99 */
5134 t->icon = fake_icon;
5139 * Now iconify the main window
5142 /* if (iconify) RFBZOOM*/
5144 /* RemoveFromDesktop(tmp_win); Stig */
5147 * Prevent the receipt of an UnmapNotify, since that would
5148 * cause a transition to the Withdrawn state.
5150 tmp_win->mapped = FALSE;
5151 XSelectInput(dpy, tmp_win->w, eventMask & ~StructureNotifyMask);
5152 XUnmapWindow(dpy, tmp_win->w);
5153 XSelectInput(dpy, tmp_win->w, eventMask);
5154 XUnmapWindow(dpy, tmp_win->frame);
5156 SetMapStateProp(tmp_win, IconicState);
5158 SetBorder (tmp_win, False);
5159 if (tmp_win == Scr->Focus)
5161 SetFocus ((TwmWindow *) NULL, LastTimestamp());
5163 Scr->FocusRoot = TRUE;
5166 tmp_win->icon = TRUE;
5168 tmp_win->icon_on = TRUE;
5170 tmp_win->icon_on = FALSE;
5172 /* djhjr - 10/2/01 */
5173 if (Scr->StrictIconManager)
5175 AddIconManager(tmp_win);
5177 /* moved to make zooms more aesthetically pleasing -- DSE */
5178 /* moved again to ensure an icon manager entry exists - djhjr - 10/11/01 */
5179 /* added Zoom()s args to iconmgrs - djhjr - 10/11/01 */
5181 Zoom(tmp_win->frame, NULL, tmp_win->icon_w, NULL);
5182 else if (tmp_win->list) /* djhjr - 10/11/01 */
5183 Zoom(tmp_win->frame, NULL, tmp_win->list->w, tmp_win->list->iconmgr);
5186 XMapWindow(dpy, tmp_win->list->icon);
5188 UpdateDesktop(tmp_win);
5194 static void Identify (t)
5197 int i, n, twidth, width, height;
5199 unsigned int wwidth, wheight, bw, depth;
5204 /* djhjr - 6/22/01 */
5205 #ifndef NO_SOUND_SUPPORT
5206 PlaySound(F_IDENTIFY);
5210 (void) sprintf(Info[n++], "%s", Version);
5211 Info[n++][0] = '\0';
5214 XGetGeometry (dpy, t->w, &JunkRoot, &JunkX, &JunkY,
5215 &wwidth, &wheight, &bw, &depth);
5216 (void) XTranslateCoordinates (dpy, t->w, Scr->Root, 0, 0,
5219 /* looks bad with variable fonts... djhjr - 5/10/96
5220 (void) sprintf(Info[n++], "Name = \"%s\"", t->full_name);
5221 (void) sprintf(Info[n++], "Class.res_name = \"%s\"", t->class.res_name);
5222 (void) sprintf(Info[n++], "Class.res_class = \"%s\"", t->class.res_class);
5223 Info[n++][0] = '\0';
5224 (void) sprintf(Info[n++], "Geometry/root = %dx%d+%d+%d", wwidth, wheight, x, y);
5225 (void) sprintf(Info[n++], "Border width = %d", bw);
5226 (void) sprintf(Info[n++], "Depth = %d", depth);
5228 (void) sprintf(Info[n++], "Name: \"%s\"", t->full_name);
5229 (void) sprintf(Info[n++], "Class.res_name: \"%s\"", t->class.res_name);
5230 (void) sprintf(Info[n++], "Class.res_class: \"%s\"", t->class.res_class);
5231 Info[n++][0] = '\0';
5232 (void) sprintf(Info[n++], "Geometry/root: %dx%d+%d+%d", wwidth, wheight, x, y);
5233 (void) sprintf(Info[n++], "Border width: %d", bw);
5234 (void) sprintf(Info[n++], "Depth: %d", depth);
5236 Info[n++][0] = '\0';
5238 /* djhjr - 9/19/96 */
5239 #ifndef NO_BUILD_INFO
5243 char is_rplay; /* djhjr - 6/22/01 */
5244 char is_regex; /* djhjr - 10/20/01 */
5245 char is_i18n; /* djhjr - 10/20/01 */
5247 /* djhjr - 6/22/99 */
5248 #ifdef WE_REALLY_DO_WANT_TO_SEE_THIS
5249 (void) sprintf(Info[n++], "X Server: %s Version %d.%d Release %d",
5250 ServerVendor(dpy), ProtocolVersion(dpy), ProtocolRevision(dpy),
5251 VendorRelease(dpy));
5255 * Was a 'do ... while()' that accessed unallocated memory.
5256 * This and the change to Imakefile submitted by Takeharu Kato
5259 while (lastmake[i][0] != '\0')
5260 (void) sprintf(Info[n++], "%s", lastmake[i++]);
5262 /* djhjr - 1/31/99 */
5263 #ifdef NO_M4_SUPPORT
5268 #ifdef NO_XPM_SUPPORT
5273 /* djhjr - 6/22/01 */
5274 #ifdef NO_SOUND_SUPPORT
5279 /* djhjr - 6/22/01 */
5280 #ifdef NO_REGEX_SUPPORT
5285 /* djhjr - 9/14/03 */
5286 #ifdef NO_I18N_SUPPORT
5291 (void) sprintf(Info[n++],
5292 "Options: %ci18n %cm4 %cregex %crplay %cxpm",
5293 is_i18n, is_m4, is_regex, is_rplay, is_xpm);
5295 Info[n++][0] = '\0';
5299 (void) sprintf(Info[n++], "Click to dismiss...");
5301 /* figure out the width and height of the info window */
5304 height = (n * (Scr->InfoFont.height+2)) + 10; * some padding *
5306 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
5307 i = (Scr->InfoBevelWidth > 0) ? Scr->InfoBevelWidth + 8 : 10;
5308 height = (n * (Scr->InfoFont.height+2)) + i; /* some padding */
5311 for (i = 0; i < n; i++)
5313 /* djhjr - 9/14/03 */
5314 #ifndef NO_I18N_SUPPORT
5315 twidth = MyFont_TextWidth(&Scr->InfoFont,
5317 twidth = XTextWidth(Scr->InfoFont.font,
5319 Info[i], strlen(Info[i]));
5323 if (InfoLines) XUnmapWindow(dpy, Scr->InfoWindow);
5326 width += 20; * some padding *
5328 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
5329 i = (Scr->InfoBevelWidth > 0) ? Scr->InfoBevelWidth + 18 : 20;
5330 width += i; /* some padding */
5332 if (XQueryPointer (dpy, Scr->Root, &JunkRoot, &JunkChild, &px, &py,
5333 &dummy, &dummy, &udummy)) {
5337 /* added this 'if ()' - djhjr - 4/29/98 */
5338 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
5339 if (Scr->InfoBevelWidth > 0)
5341 if (px + width + 2 * Scr->InfoBevelWidth >= Scr->MyDisplayWidth)
5342 px = Scr->MyDisplayWidth - width - 2 * Scr->InfoBevelWidth;
5343 if (py + height + 2 * Scr->InfoBevelWidth >= Scr->MyDisplayHeight)
5344 py = Scr->MyDisplayHeight - height - 2 * Scr->InfoBevelWidth;
5348 if (px + width + BW2 >= Scr->MyDisplayWidth)
5349 px = Scr->MyDisplayWidth - width - BW2;
5350 if (py + height + BW2 >= Scr->MyDisplayHeight)
5351 py = Scr->MyDisplayHeight - height - BW2;
5360 XMoveResizeWindow(dpy, Scr->InfoWindow, px, py, width, height);
5362 /* done in HandleExpose() in events.c - djhjr - 4/30/98 */
5364 /* djhjr - 5/9/96 */
5365 if (Scr->use3Dborders > 0)
5367 XGetGeometry (dpy, Scr->InfoWindow, &JunkRoot, &JunkX, &JunkY,
5368 &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth);
5369 Draw3DBorder(Scr->InfoWindow, 0, 0, JunkWidth, JunkHeight,
5371 BW, Scr->DefaultC, off, False, False);
5373 Scr->InfoBevelWidth, Scr->DefaultC, off, False, False);
5377 XMapRaised(dpy, Scr->InfoWindow);
5383 void SetMapStateProp(tmp_win, state)
5387 unsigned long data[2]; /* "suggested" by ICCCM version 1 */
5389 data[0] = (unsigned long) state;
5390 data[1] = (unsigned long) (tmp_win->iconify_by_unmapping ? None :
5393 XChangeProperty (dpy, tmp_win->w, _XA_WM_STATE, _XA_WM_STATE, 32,
5394 PropModeReplace, (unsigned char *) data, 2);
5399 Bool GetWMState (w, statep, iwp)
5406 unsigned long nitems, bytesafter;
5407 unsigned long *datap = NULL;
5408 Bool retval = False;
5410 /* used to test for '!datap' - djhjr - 1/10/98 */
5411 if (XGetWindowProperty (dpy, w, _XA_WM_STATE, 0L, 2L, False, _XA_WM_STATE,
5412 &actual_type, &actual_format, &nitems, &bytesafter,
5413 (unsigned char **) &datap) != Success ||
5414 actual_type == None)
5417 if (nitems <= 2) { /* "suggested" by ICCCM version 1 */
5418 *statep = (int) datap[0];
5419 *iwp = (Window) datap[1];
5423 XFree ((char *) datap);
5430 * BumpWindowColormap - rotate our internal copy of WM_COLORMAP_WINDOWS
5433 void BumpWindowColormap (tmp, inc)
5437 int i, j, previously_installed;
5438 ColormapWindow **cwins;
5442 if (inc && tmp->cmaps.number_cwins > 0) {
5443 cwins = (ColormapWindow **) malloc(sizeof(ColormapWindow *)*
5444 tmp->cmaps.number_cwins);
5446 if ((previously_installed =
5447 (Scr->cmapInfo.cmaps == &tmp->cmaps) &&
5448 tmp->cmaps.number_cwins)) {
5449 for (i = tmp->cmaps.number_cwins; i-- > 0; )
5450 tmp->cmaps.cwins[i]->colormap->state = 0;
5453 for (i = 0; i < tmp->cmaps.number_cwins; i++) {
5455 if (j >= tmp->cmaps.number_cwins)
5456 j -= tmp->cmaps.number_cwins;
5458 j += tmp->cmaps.number_cwins;
5459 cwins[j] = tmp->cmaps.cwins[i];
5462 free((char *) tmp->cmaps.cwins);
5464 tmp->cmaps.cwins = cwins;
5466 if (tmp->cmaps.number_cwins > 1)
5467 memset( tmp->cmaps.scoreboard, 0,
5468 ColormapsScoreboardLength(&tmp->cmaps));
5470 if (previously_installed)
5471 InstallWindowColormaps(PropertyNotify, (TwmWindow *) NULL);
5474 FetchWmColormapWindows (tmp);
5479 void HideIconManager(tmp_win)
5482 /* added this 'if (...) else ...' - djhjr - 9/21/99 */
5483 if (tmp_win == NULL)
5487 HideIconMgr(&Scr->iconmgr);
5490 * New code in list.c necessitates 'next_entry()' and
5491 * 'contents_of_entry()' - djhjr - 10/20/01
5493 for (list = Scr->IconMgrs; list != NULL; list = next_entry(list))
5494 HideIconMgr((IconMgr *)contents_of_entry(list));
5500 if ((ip = (IconMgr *)LookInList(Scr->IconMgrs, tmp_win->full_name,
5501 &tmp_win->class)) == NULL)
5508 /* djhjr - 9/21/99 */
5509 void HideIconMgr(ip)
5512 /* djhjr - 6/10/98 */
5516 SetMapStateProp (ip->twm_win, WithdrawnState);
5517 XUnmapWindow(dpy, ip->twm_win->frame);
5518 if (ip->twm_win->icon_w)
5519 XUnmapWindow (dpy, ip->twm_win->icon_w);
5520 ip->twm_win->mapped = FALSE;
5521 ip->twm_win->icon = TRUE;
5524 /* djhjr - 9/21/99 */
5525 void ShowIconMgr(ip)
5528 /* added the second condition - djhjr - 6/10/98 */
5529 if (Scr->NoIconManagers || ip->count == 0)
5532 DeIconify(ip->twm_win);
5533 XRaiseWindow(dpy, ip->twm_win->frame);
5534 XRaiseWindow(dpy, ip->twm_win->VirtualDesktopDisplayWindow);
5538 void SetBorder (tmp, onoroff)
5544 /* djhjr - 4/22/96 */
5545 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
5546 if (Scr->BorderBevelWidth > 0)
5547 PaintBorders (tmp, onoroff);
5553 XSetWindowBorder (dpy, tmp->frame, tmp->border);
5556 XSetWindowBorder (dpy, tmp->frame, tmp->border_tile.back);
5558 XSetWindowBorder (dpy, tmp->frame, tmp->border.back);
5562 XSetWindowBorder (dpy, tmp->title_w, tmp->border);
5565 XSetWindowBorder (dpy, tmp->title_w, tmp->border_tile.back);
5567 XSetWindowBorder (dpy, tmp->title_w, tmp->border.back);
5571 XSetWindowBorderPixmap (dpy, tmp->frame, tmp->gray);
5574 XSetWindowBorderPixmap (dpy, tmp->title_w, tmp->gray);
5578 /* djhjr - 11/17/97 */
5579 /* rem'd out test for button color - djhjr - 9/15/99 */
5580 if (/*Scr->ButtonColorIsFrame && */tmp->titlebuttons)
5582 int i, nb = Scr->TBInfo.nleft + Scr->TBInfo.nright;
5585 /* collapsed two functions - djhjr - 8/10/98 */
5586 for (i = 0, tbw = tmp->titlebuttons; i < nb; i++, tbw++)
5587 PaintTitleButton(tmp, tbw, (onoroff) ? 2 : 1);
5594 void DestroyMenu (menu)
5600 XDeleteContext (dpy, menu->w, MenuContext);
5601 XDeleteContext (dpy, menu->w, ScreenContext);
5602 if (Scr->Shadow) XDestroyWindow (dpy, menu->shadow);
5603 XDestroyWindow(dpy, menu->w);
5606 for (item = menu->first; item; ) {
5607 MenuItem *tmp = item;
5609 free ((char *) tmp);
5619 /* for moves and resizes from center - djhjr - 10/4/02 */
5620 void WarpScreenToWindow(t)
5623 int warpwin = Scr->WarpWindows;
5624 int warpsnug = Scr->WarpSnug;
5626 Scr->WarpWindows = Scr->WarpSnug = FALSE;
5628 Scr->WarpWindows = warpwin;
5629 Scr->WarpSnug = warpsnug;
5632 * This is an attempt to have windows redraw themselves, but
5633 * it doesn't always work (non-raising windows in particular).
5638 /* was in-lined in WarpToWindow() - djhjr - 5/30/00 */
5639 void WarpWindowOrScreen(t)
5644 * we are either moving the window onto the screen, or the screen to the
5645 * window, the distances remain the same
5648 if ((t->frame_x < Scr->MyDisplayWidth)
5649 && (t->frame_y < Scr->MyDisplayHeight)
5650 && (t->frame_x + t->frame_width >= 0)
5651 && (t->frame_y + t->frame_height >= 0))
5655 * window is visible; you can simply
5656 * snug it if WarpSnug or WarpWindows is set -- DSE
5659 if (Scr->WarpSnug || Scr->WarpWindows)
5661 int right,left,up,down,dx,dy;
5664 * Adjustment for border widths submitted by Steve Ratcliffe
5665 * Note: Do not include the 3D border width!
5668 left = t->frame_x + t->frame_width + 2 * t->frame_bw;
5670 down = t->frame_y + t->frame_height + 2 * t->frame_bw;
5673 if (left-right < Scr->MyDisplayWidth)
5677 else if (left>Scr->MyDisplayWidth)
5678 dx = left - Scr->MyDisplayWidth;
5682 if (down-up < Scr->MyDisplayHeight)
5686 else if (down>Scr->MyDisplayHeight)
5687 dy = down - Scr->MyDisplayHeight;
5690 if (dx!=0 || dy!=0) {
5691 /* added 'Scr->WarpSnug ||' - djhjr - 5/30/00 */
5692 if (Scr->WarpSnug || Scr->WarpWindows)
5694 /* move the window */
5695 VirtualMoveWindow(t, t->virtual_frame_x - dx,
5696 t->virtual_frame_y - dy);
5700 /* move the screen */
5701 PanRealScreen(dx,dy,NULL,NULL);
5710 * Window is invisible; we need to move it or the screen.
5715 xdiff = ((Scr->MyDisplayWidth - t->frame_width) / 2) - t->frame_x;
5716 ydiff = ((Scr->MyDisplayHeight - t->frame_height) / 2) - t->frame_y;
5718 /* added 'Scr->WarpSnug ||' - djhjr - 5/30/00 */
5719 if (Scr->WarpSnug || Scr->WarpWindows)
5721 /* move the window */
5722 VirtualMoveWindow(t, t->virtual_frame_x + xdiff,
5723 t->virtual_frame_y + ydiff);
5727 /* move the screen */
5728 PanRealScreen(-xdiff, -ydiff,NULL,NULL); /* DSE */
5732 if (t->auto_raise || !Scr->NoRaiseWarp)
5733 AutoRaiseWindow (t);
5736 /* for icon manager management - djhjr - 5/30/00 */
5737 void WarpInIconMgr(w, t)
5741 int x, y, pan_margin = 0;
5742 /* djhjr - 9/9/02 */
5743 int bw = t->frame_bw3D + t->frame_bw;
5748 WarpWindowOrScreen(t);
5750 /* was 'Scr->BorderWidth' - djhjr - 9/9/02 */
5751 x = w->x + bw + EDGE_OFFSET + 5;
5752 x += (Scr->IconMgrBevelWidth > 0) ? Scr->IconMgrBevelWidth : bw;
5753 y = w->y + bw + w->height / 2;
5754 y += (Scr->IconMgrBevelWidth > 0) ? Scr->IconMgrBevelWidth : bw;
5755 y += w->iconmgr->twm_win->title_height;
5758 * adjust the pointer for partially visible windows and the
5759 * AutoPan border width
5762 if (Scr->AutoPanX) pan_margin = Scr->AutoPanBorderWidth;
5764 if (x + t->frame_x >= Scr->MyDisplayWidth - pan_margin)
5765 x = Scr->MyDisplayWidth - t->frame_x - pan_margin - 2;
5766 if (x + t->frame_x <= pan_margin)
5767 x = -t->frame_x + pan_margin + 2;
5768 if (y + t->frame_y >= Scr->MyDisplayHeight - pan_margin)
5769 y = Scr->MyDisplayHeight - t->frame_y - pan_margin - 2;
5770 if (y + t->frame_y <= pan_margin)
5771 y = -t->frame_y + pan_margin + 2;
5773 XWarpPointer(dpy, None, t->frame, 0, 0, 0, 0, x, y); /* DSE */
5777 * substantially re-written and added passing 'next' to next_by_class()
5779 * djhjr - 5/13/98 6/6/98 6/15/98
5781 #ifdef ORIGINAL_WARPCLASS
5782 void WarpClass (next, t, class)
5787 int len = strlen(class);
5789 if (!strncmp(class, t->class.res_class, len))
5790 t = next_by_class(t, class);
5792 t = next_by_class((TwmWindow *)NULL, class);
5794 if (Scr->WarpUnmapped || t->mapped) {
5795 if (!t->mapped) DeIconify (t);
5796 if (!Scr->NoRaiseWarp)
5798 XRaiseWindow (dpy, t->frame);
5800 XRaiseWindow (dpy, t->VirtualDesktopDisplayWindow);
5802 RaiseStickyAbove(); /* DSE */
5809 #else /* ORIGINAL_WARPCLASS */
5810 void WarpClass(next, t, class)
5820 * if an empty class string
5822 * class = the TwmWindow's class
5823 * else if a window with focus
5825 * class = the focused window's class
5828 * if still an empty class string
5834 class = t->class.res_class;
5835 else if (Scr->Focus)
5837 i = XGetClassHint(dpy, Scr->Focus->w, &ch);
5838 if (i && !strncmp(class, ch.res_class, strlen(class)))
5839 class = ch.res_class;
5841 /* djhjr - 6/21/00 */
5844 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
5848 if (!strlen(class) || !strncmp(class, "VTWM", 4))
5852 if (!(tt = next_by_class(next, t, class)))
5856 /* djhjr - 5/28/00 */
5863 if ((tt = next_by_class(next, t, class)))
5865 /* multiple icon managers: gotta test for those without entries */
5866 if (tt->iconmgr && tt->iconmgrp->count == 0)
5878 /* added the second argument - djhjr - 5/28/00 */
5879 if (tt && warp_if_warpunmapped(tt, (next) ? F_WARPCLASSNEXT: F_WARPCLASSPREV))
5881 RaiseStickyAbove(); /* DSE */
5884 /* djhjr - 6/3/03 */
5885 #ifndef NO_SOUND_SUPPORT
5886 PlaySound((next) ? F_WARPCLASSNEXT: F_WARPCLASSPREV);
5891 /* djhjr - 5/28/00 */
5901 #endif /* ORIGINAL_WARPCLASS */
5905 /* moved from add_window.c - djhjr - 10/27/02 */
5906 void AddWindowToRing(tmp_win)
5911 /* link window in after Scr->Ring */
5912 tmp_win->ring.prev = Scr->Ring;
5913 tmp_win->ring.next = Scr->Ring->ring.next;
5915 /* Scr->Ring's next's prev points to this */
5916 /*if (Scr->Ring->ring.next->ring.prev)*/
5917 Scr->Ring->ring.next->ring.prev = tmp_win;
5919 /* Scr->Ring's next points to this */
5920 Scr->Ring->ring.next = tmp_win;
5923 tmp_win->ring.next = tmp_win->ring.prev = Scr->Ring = tmp_win;
5926 /* moved from events.c - djhjr - 10/27/02 */
5927 void RemoveWindowFromRing(tmp_win)
5931 if (tmp_win->ring.prev)
5932 tmp_win->ring.prev->ring.next = tmp_win->ring.next;
5933 if (tmp_win->ring.next)
5934 tmp_win->ring.next->ring.prev = tmp_win->ring.prev;
5936 /* if window was only thing in ring, null out ring */
5937 if (Scr->Ring == tmp_win)
5938 Scr->Ring = (tmp_win->ring.next != tmp_win) ?
5939 tmp_win->ring.next : (TwmWindow *)NULL;
5941 /* if window was ring leader, set to next (or null) */
5942 if (!Scr->Ring || Scr->RingLeader == tmp_win)
5943 Scr->RingLeader = Scr->Ring;
5945 tmp_win->ring.next = tmp_win->ring.prev = NULL;
5948 void WarpAlongRing (ev, forward)
5952 TwmWindow *r, *head;
5955 * Re-vamped much of this to properly handle icon managers, and
5956 * clean up dumb code I added some time back.
5958 * Cleaned it up again. I musta been high. Twice.
5962 if (!(head = (Scr->RingLeader) ? Scr->RingLeader : Scr->Ring))
5969 r = head->ring.next;
5971 r = head->ring.prev;
5973 while (r && r != head)
5975 if (r->mapped || warp_if_warpunmapped(r, F_WARPRING))
5978 r = (forward) ? r->ring.next : r->ring.prev;
5983 #ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */
5984 TwmWindow *p = Scr->RingLeader, *t;
5987 /* done in WarpToWindow - djhjr - 10/27/02
5988 Scr->RingLeader = r;
5994 /* djhjr - 6/3/03 */
5995 #ifndef NO_SOUND_SUPPORT
5996 PlaySound(F_WARPRING);
6001 #ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */
6002 if (p && p->mapped &&
6003 XFindContext (dpy, ev->window, TwmContext, (caddr_t *)&t) == XCSUCCESS &&
6006 p->ring.cursor_valid = True;
6007 p->ring.curs_x = ev->x_root - t->frame_x;
6008 p->ring.curs_y = ev->y_root - t->frame_y;
6009 if (p->ring.curs_x < -p->frame_bw ||
6010 p->ring.curs_x >= p->frame_width + p->frame_bw ||
6011 p->ring.curs_y < -p->frame_bw ||
6012 p->ring.curs_y >= p->frame_height + p->frame_bw)
6014 /* somehow out of window */
6015 p->ring.curs_x = p->frame_width / 2;
6016 p->ring.curs_y = p->frame_height / 2;
6022 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
6027 void WarpToScreen (n, inc)
6032 unsigned int dummask;
6033 ScreenInfo *newscr = NULL;
6039 else if (n >= NumScreens)
6042 newscr = ScreenList[n];
6043 if (!newscr) { /* make sure screen is managed */
6044 if (inc) { /* walk around the list */
6048 fprintf (stderr, "%s: unable to warp to unmanaged screen %d\n",
6050 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
6055 if (Scr->screen == n) return; /* already on that screen */
6057 PreviousScreen = Scr->screen;
6058 XQueryPointer (dpy, Scr->Root, &dumwin, &dumwin, &x, &y,
6059 &dumint, &dumint, &dummask);
6061 /* djhjr - 6/3/03 */
6062 #ifndef NO_SOUND_SUPPORT
6063 PlaySound(F_WARPTOSCREEN);
6066 XWarpPointer (dpy, None, newscr->Root, 0, 0, 0, 0, x, y);
6072 void WarpToWindow (t)
6076 int pan_margin = 0; /* djhjr - 5/28/00 */
6077 int bw = t->frame_bw3D + t->frame_bw; /* djhjr - 9/9/02 */
6078 Window w = t->frame; /* djhjr - 5/30/00 */
6080 WarpWindowOrScreen(t); /* djhjr - 5/30/00 */
6082 #ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */
6083 if (t->ring.cursor_valid) {
6088 x = t->frame_width / 2;
6089 y = t->frame_height / 2;
6092 /* added this 'if (...) else' - djhjr - 6/10/98 */
6096 if (t->iconmgrp->count > 0)
6097 XWarpPointer(dpy, None, t->iconmgrp->first->icon, 0,0,0,0,
6098 EDGE_OFFSET, EDGE_OFFSET);
6102 if (t->iconmgrp->count > 0)
6104 w = t->iconmgrp->twm_win->frame;
6106 /* was 'Scr->BorderWidth' - djhjr - 9/9/02 */
6107 x = t->iconmgrp->x + bw + EDGE_OFFSET + 5;
6108 x += (Scr->IconMgrBevelWidth > 0) ? Scr->IconMgrBevelWidth : bw;
6109 y = t->iconmgrp->y + bw + t->iconmgrp->first->height / 2;
6110 y += (Scr->IconMgrBevelWidth > 0) ? Scr->IconMgrBevelWidth : bw;
6111 y += t->iconmgrp->twm_win->title_height;
6114 else if (!t->title_w)
6116 /* added this 'if (...) else' - djhjr - 10/16/02 */
6117 if (Scr->WarpCentered & WARPC_UNTITLED)
6119 x = t->frame_width / 2;
6120 y = t->frame_height / 2;
6124 x = t->frame_width / 2;
6125 y = (t->wShaped) ? bw : bw / 2; /* djhjr - 9/9/02 */
6130 /* added this 'if (...) else' - djhjr - 10/16/02 */
6131 if (Scr->WarpCentered & WARPC_TITLED)
6133 x = t->frame_width / 2;
6134 y = t->frame_height / 2;
6139 * Added 't->title_x + ' to handle titlebars that
6140 * aren't flush left.
6141 * Submitted by Steve Ratcliffe
6142 * was '(t->frame_bw3D + t->frame_bw)' - djhjr - 9/9/02
6144 x = t->title_x + t->title_width / 2 + bw;
6145 y = t->title_height / 2 + bw;
6149 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
6150 if (!Scr->BorderBevelWidth > 0) y -= t->frame_bw;
6154 * adjust the pointer for partially visible windows and the
6155 * AutoPan border width - djhjr - 5/30/00
6156 * was '(t->frame_bw3D + t->frame_bw)' - djhjr - 9/9/02
6159 if (Scr->AutoPanX) pan_margin = Scr->AutoPanBorderWidth;
6161 if (x + t->frame_x >= Scr->MyDisplayWidth - pan_margin)
6162 x = Scr->MyDisplayWidth - t->frame_x - pan_margin - 2;
6163 if (x + t->frame_x <= pan_margin)
6166 x = t->title_width - (t->frame_x + t->title_width) +
6169 x = -t->frame_x + pan_margin + 2;
6172 /* added test for centered warps - djhjr - 10/16/02 */
6173 if (t->title_w && !(Scr->WarpCentered & WARPC_TITLED) &&
6174 (x < t->title_x || x > t->title_x + t->title_width))
6176 y = t->title_height + bw / 2;
6178 if (y + t->frame_y >= Scr->MyDisplayHeight - pan_margin)
6180 y = Scr->MyDisplayHeight - t->frame_y - pan_margin - 2;
6182 /* move centered warp to titlebar - djhjr - 10/16/02 */
6183 if (y < t->title_y + t->title_height)
6184 x = t->title_x + t->title_width / 2 + bw;
6186 if (y + t->frame_y <= pan_margin)
6187 y = -t->frame_y + pan_margin + 2;
6189 /* was 't->frame' - djhjr - 5/30/00 */
6190 XWarpPointer (dpy, None, w, 0, 0, 0, 0, x, y);
6192 /* djhjr - 10/27/02 */
6193 if (t->ring.next) Scr->RingLeader = t;
6199 * substantially re-written and added receiving and using 'next'
6201 * djhjr - 5/13/98 5/19/98 6/6/98 6/15/98
6203 #ifdef ORIGINAL_WARPCLASS
6205 next_by_class (t, class)
6210 int len = strlen(class);
6213 for (tt = t->next; tt != NULL; tt = tt->next)
6214 if (!strncmp(class, tt->class.res_class, len)) return tt;
6215 for (tt = Scr->TwmRoot.next; tt != NULL; tt = tt->next)
6216 if (!strncmp(class, tt->class.res_class, len)) return tt;
6219 #else /* ORIGINAL_WARPCLASS */
6221 next_by_class (next, t, class)
6226 static TwmWindow *tp = NULL;
6228 int i, len = strlen(class);
6231 #ifdef DEBUG_WARPCLASS
6232 fprintf(stderr, "class=\"%s\", next=%d, %s t, ", class, next, (t) ? "have" : "no");
6235 /* forward or backward from current */
6236 tl = (next) ? ((tp) ? tp->next : Scr->TwmRoot.next) : ((tp) ? tp->prev : Scr->TwmRoot.prev);
6237 for (tt = (next) ? ((t) ? t->next : tl) : ((t) ? t->prev : tl);
6239 tt = (next) ? tt->next : tt->prev)
6240 if (Scr->WarpUnmapped || tt->mapped)
6242 i = XGetClassHint(dpy, tt->w, &ch);
6243 if (i && !strncmp(class, ch.res_class, len))
6245 #ifdef DEBUG_WARPCLASS
6246 fprintf(stderr, "matched \"%s\" \"%s\"\n", tt->class.res_class, tt->class.res_name);
6253 #ifdef DEBUG_WARPCLASS
6254 fprintf(stderr, "(1) skipping \"%s\"\n", (i) ? tt->class.res_class : "NO RES_CLASS!");
6260 /* no match, wrap and retry */
6262 for (tt = Scr->TwmRoot.next; tt != NULL; tt = tt->next)
6263 if (Scr->WarpUnmapped || tt->mapped)
6265 i = XGetClassHint(dpy, tt->w, &ch);
6266 if (i && !strncmp(class, ch.res_class, len))
6270 #ifdef DEBUG_WARPCLASS
6271 fprintf(stderr, "next wrapped to \"%s\ \"%s\"\n", tt->class.res_class, tt->class.res_name);
6279 #ifdef DEBUG_WARPCLASS
6281 fprintf(stderr, "(2) skipping \"%s\"\n", (i) ? tt->class.res_class : "NO RES_CLASS!");
6285 #ifdef DEBUG_WARPCLASS
6286 i = 0; if (tl) i = XGetClassHint(dpy, tl->w, &ch);
6287 fprintf(stderr, "prev wrapped to \"%s\ \"%s\"\n", (i) ? ch.res_class : "NO RES_CLASS!", (i) ? ch.res_name : "NO RES_CLASS!");
6292 #endif /* ORIGINAL_WARPCLASS */
6294 /* this was inlined in many places, and even more now - djhjr - 5/13/98 */
6295 /* added the second argument - djhjr - 5/28/00 */
6296 static int warp_if_warpunmapped(w, func)
6300 /* skip empty icon managers - 10/27/02 */
6301 if (w && (w->iconmgr && w->iconmgrp->count == 0))
6304 if (Scr->WarpUnmapped || w->mapped)
6306 /* submitted by Ugen Antsilevitch - 5/28/00 */
6307 /* if F_NOFUNCTION, override WarpVisible - djhjr - 5/28/00 */
6308 if (func != F_NOFUNCTION && Scr->WarpVisible)
6312 if (Scr->AutoPanX) pan_margin = Scr->AutoPanBorderWidth;
6314 if (w->frame_x >= Scr->MyDisplayWidth - pan_margin ||
6315 w->frame_y >= Scr->MyDisplayHeight - pan_margin ||
6316 w->frame_x + w->frame_width <= pan_margin ||
6317 w->frame_y + w->frame_height <= pan_margin)
6321 if (!w->mapped) DeIconify(w);
6322 if (!Scr->NoRaiseWarp) XRaiseWindow(dpy, w->frame);
6323 XRaiseWindow(dpy, w->VirtualDesktopDisplayWindow);
6331 /* djhjr - 9/17/02 */
6333 do_squeezetitle(context, func, tmp_win, squeeze)
6336 SqueezeInfo *squeeze;
6338 if (DeferExecution (context, func, Scr->SelectCursor))
6341 /* honor "Don't Squeeze" resources - djhjr - 9/17/02 */
6342 if (Scr->SqueezeTitle &&
6343 !LookInList(Scr->DontSqueezeTitleL, tmp_win->full_name, &tmp_win->class))
6345 if ( tmp_win->title_height ) /* Not for untitled windows! */
6347 PopDownMenu(); /* djhjr - 9/17/02 */
6349 #ifndef NO_SOUND_SUPPORT
6353 tmp_win->squeeze_info = squeeze;
6354 SetFrameShape( tmp_win );
6356 /* Can't go in SetFrameShape()... - djhjr - 4/1/00 */
6357 if (Scr->WarpCursor ||
6358 LookInList(Scr->WarpCursorL, tmp_win->full_name, &tmp_win->class))
6359 WarpToWindow(tmp_win);
6369 * Two functions to handle a restart from a SIGUSR1 signal
6370 * (see also twm.c:Done() and twm.c:QueueRestartVtwm())
6372 * adapted from TVTWM-pl11 - djhjr - 7/31/98
6375 static void setup_restart(time)
6378 /* djhjr - 6/22/01 */
6379 #ifndef NO_SOUND_SUPPORT
6388 /* djhjr - 3/13/97 */
6391 /* djhjr - 12/2/01 */
6395 void RestartVtwm(time)
6398 setup_restart(time);
6400 execvp(*Argv, Argv);
6401 fprintf (stderr, "%s: unable to restart \"%s\"\n", ProgramName, *Argv);
6406 * ICCCM Client Messages - Section 4.2.8 of the ICCCM dictates that all
6407 * client messages will have the following form:
6409 * event type ClientMessage
6410 * message type _XA_WM_PROTOCOLS
6413 * data[0] message atom
6414 * data[1] time stamp
6417 static void send_clientmessage (w, a, timestamp)
6422 XClientMessageEvent ev;
6424 ev.type = ClientMessage;
6426 ev.message_type = _XA_WM_PROTOCOLS;
6429 ev.data.l[1] = timestamp;
6430 XSendEvent (dpy, w, False, 0L, (XEvent *) &ev);
6433 void SendDeleteWindowMessage (tmp, timestamp)
6437 send_clientmessage (tmp->w, _XA_WM_DELETE_WINDOW, timestamp);
6440 void SendSaveYourselfMessage (tmp, timestamp)
6444 send_clientmessage (tmp->w, _XA_WM_SAVE_YOURSELF, timestamp);
6447 void SendTakeFocusMessage (tmp, timestamp)
6451 send_clientmessage (tmp->w, _XA_WM_TAKE_FOCUS, timestamp);
6455 /* djhjr - 4/27/96 */
6456 void DisplayPosition (x, y)
6475 i = sprintf (str, " %c%-4d %c%-4d ", signx, x, signy, y);
6478 * Non-SysV systems - specifically, BSD-derived systems - return a
6479 * pointer to the string, not its length. Submitted by Goran Larsson
6480 i = sprintf (str, "%+6d %-+6d", x, y);
6482 sprintf (str, "%+6d %-+6d", x, y);
6485 XRaiseWindow (dpy, Scr->SizeWindow);
6486 /* font was font.font->fid - djhjr - 9/14/03 */
6487 FBF (Scr->DefaultC.fore, Scr->DefaultC.back, Scr->SizeFont);
6488 /* djhjr - 9/14/03 */
6489 #ifndef NO_I18N_SUPPORT
6490 MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont,
6492 XDrawImageString (dpy, Scr->SizeWindow,
6497 Scr->SizeStringOffset,
6499 (Scr->SizeStringWidth -
6500 /* djhjr - 9/14/03 */
6501 #ifndef NO_I18N_SUPPORT
6502 MyFont_TextWidth(&Scr->SizeFont,
6504 XTextWidth(Scr->SizeFont.font,
6509 Scr->SizeFont.font->ascent + SIZE_VINDENT,
6511 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
6513 Scr->SizeFont.font->ascent +
6515 Scr->SizeFont.ascent +
6517 ((Scr->InfoBevelWidth > 0) ? Scr->InfoBevelWidth : 0),
6521 /* I know, I know, but the above code overwrites it... djhjr - 5/9/96 */
6522 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
6523 if (Scr->InfoBevelWidth > 0)
6524 Draw3DBorder(Scr->SizeWindow, 0, 0,
6525 Scr->SizeStringWidth,
6528 (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2),
6529 BW, Scr->DefaultC, off, False, False);
6531 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
6532 (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2) +
6533 ((Scr->InfoBevelWidth > 0) ? 2 * Scr->InfoBevelWidth : 0),
6534 Scr->InfoBevelWidth, Scr->DefaultC, off, False, False);
6537 /* djhjr - 9/21/99 */
6538 int FindMenuOrFuncInBindings(contexts, mr, func)
6545 int found = 0; /* context bitmap for menu or function */
6546 int i, j, k, l, fallback = 0;
6550 if (Scr->DefaultFunction.func == F_MENU)
6551 if (FindMenuInMenus(Scr->DefaultFunction.menu, mr))
6556 if (Scr->DefaultFunction.func == func)
6558 else if (Scr->DefaultFunction.func == F_MENU)
6559 if (FindFuncInMenus(Scr->DefaultFunction.menu, func))
6563 for (j = 0; j < NUM_CONTEXTS; j++)
6565 if ((contexts & (1 << j)) == 0) continue;
6573 for (i = 0; i < MAX_BUTTONS + 1; i++)
6577 for (k = 0; k < MOD_SIZE; k++)
6581 if (Scr->Mouse[i][j][k].func == F_MENU)
6582 l = FindMenuInMenus(Scr->Mouse[i][j][k].menu, mr);
6586 if (Scr->Mouse[i][j][k].func == func)
6588 else if (Scr->Mouse[i][j][k].func == F_MENU)
6589 l = FindFuncInMenus(Scr->Mouse[i][j][k].menu, func);
6595 i = MAX_BUTTONS + 1;
6602 for (key = Scr->FuncKeyRoot.next; key != NULL; key = key->next)
6603 if (key->cont & (1 << j))
6607 if (key->func == F_MENU)
6608 for (start = Scr->MenuList; start != NULL; start = start->next)
6609 if (strcmp(start->name, key->action) == 0)
6611 l = FindMenuInMenus(start, mr);
6617 if (key->func == func)
6619 else if (key->func == F_MENU)
6620 for (start = Scr->MenuList; start != NULL; start = start->next)
6621 if (strcmp(start->name, key->action) == 0)
6623 l = FindFuncInMenus(start, func);
6639 /* djhjr - 9/21/99 */
6640 int FindMenuOrFuncInWindows(tmp_win, contexts, mr, func)
6651 if (contexts & C_ROOT_BIT) return 1;
6653 for (twin = Scr->TwmRoot.next; twin != NULL; twin = twin->next)
6654 if (twin != tmp_win)
6657 * if this window is an icon manager,
6658 * skip the windows that aren't in it
6660 if (tmp_win->iconmgr && twin->list &&
6661 tmp_win != twin->list->iconmgr->twm_win)
6666 for (i = 1; i < C_ALL_BITS; i = (1 << i))
6668 if ((contexts & i) == 0) continue;
6676 if (!twin->title_height) continue;
6679 if (twin->w != Scr->VirtualDesktopDisplayOuter)
6683 if (XFindContext(dpy, twin->w, DoorContext,
6684 (caddr_t *)&d) == XCNOENT)
6695 if (twin->titlebuttons)
6697 nb = Scr->TBInfo.nleft + Scr->TBInfo.nright;
6699 for (tbw = twin->titlebuttons; nb > 0; tbw++, nb--)
6702 if (tbw->info->menuroot)
6703 if (FindMenuInMenus(tbw->info->menuroot, mr))
6708 if (tbw->info->func == func)
6710 else if (tbw->info->menuroot)
6711 if (FindFuncInMenus(tbw->info->menuroot, func))
6716 else if (!twin->iconify_by_unmapping)
6718 /* not mapped and shows an icon */
6720 if (contexts & C_ICON_BIT) return 1;
6727 /* djhjr - 9/21/99 */
6728 int FindMenuInMenus(start, sought)
6729 MenuRoot *start, *sought;
6733 if (!start) return 0; /* submitted by Jonathan Paisley - 11/11/02 */
6734 if (start == sought) return 1;
6736 for (mi = start->first; mi != NULL; mi = mi->next)
6738 if (FindMenuInMenus(mi->sub, sought))
6744 /* djhjr - 9/21/99 */
6745 int FindFuncInMenus(mr, func)
6751 for (mi = mr->first; mi != NULL; mi = mi->next)
6752 if (mi->func == func)
6755 if (FindFuncInMenus(mi->sub, func))
6761 /* djhjr - 6/22/01 */
6764 #ifndef NO_SOUND_SUPPORT
6765 if (PlaySound(S_BELL)) return;