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 #define strdup Strdup /* avoid conflict with system header files */
73 extern char *strdup(char *);
75 extern void IconUp(), IconDown(), CreateIconWindow();
78 extern void AppletDown();
81 extern void delete_pidfile();
83 /* djhjr - 10/27/02 */
84 extern int MatchName();
86 extern void ResizeTwmWindowContents();
87 extern void SetRaiseWindow();
91 extern int ConstrainedMoveTime;
92 extern TwmWindow *ButtonWindow, *Tmp_win;
93 extern XEvent Event, ButtonEvent;
94 extern char *InitFile;
96 int RootFunction = F_NOFUNCTION;
97 MenuRoot *ActiveMenu = NULL; /* the active menu */
98 MenuItem *ActiveItem = NULL; /* the active menu item */
99 int MoveFunction = F_NOFUNCTION; /* or F_MOVE or F_FORCEMOVE */
100 int WindowMoved = FALSE;
101 int menuFromFrameOrWindowOrTitlebar = FALSE;
102 /* djhjr - 6/22/01 */
103 #ifndef NO_SOUND_SUPPORT
104 int createSoundFromFunction = FALSE;
105 int destroySoundFromFunction = FALSE;
108 void BumpWindowColormap();
110 void HideIconManager();
112 void SendDeleteWindowMessage();
113 void SendSaveYourselfMessage();
116 void WarpScreenToWindow();
117 Cursor NeedToDefer(); /* was an 'int' - Submitted by Michel Eyckmans */
119 int ConstMove = FALSE; /* constrained move variables */
121 /* for comparison against MoveDelta - djhjr - 9/5/98 */
122 static int MenuOrigX, MenuOrigY;
124 /* Globals used to keep track of whether the mouse has moved during
125 a resize function. */
129 extern int origx, origy, origWidth, origHeight;
131 int MenuDepth = 0; /* number of menus up */
135 } MenuOrigins[MAXMENUDEPTH];
136 static Cursor LastCursor;
138 static char *actionHack = ""; /* Submitted by Michel Eyckmans */
141 * context bitmaps for TwmWindows menu, f.showdesktop and f.showiconmgr
144 static int have_twmwindows = -1;
145 static int have_showdesktop = -1;
146 static int have_showlist = -1;
148 void WarpAlongRing();
150 /* djhjr - 4/18/96 */
153 static void Identify();
154 void PaintNormalEntry();
156 /* djhjr - 5/13/98 */
157 static TwmWindow *next_by_class();
158 static int warp_if_warpunmapped();
160 /* djhjr - 7/31/98 */
161 static void setup_restart();
164 /* djhjr - 9/21/99 */
165 int FindMenuOrFuncInBindings();
166 int FindMenuOrFuncInWindows();
167 int FindMenuInMenus();
168 int FindFuncInMenus();
170 /* djhjr - 9/21/99 */
174 /* djhjr - 9/17/02 */
175 static int do_squeezetitle();
180 #define MAX(x,y) ((x)>(y)?(x):(y))
182 #define SHADOWWIDTH 5 /* in pixels */
184 #define EDGE_OFFSET 5 /* DSE */
187 #define PULLDOWNMENU_OFFSET ((Scr->RightHandSidePulldownMenus)?\
188 (ActiveMenu->width - EDGE_OFFSET * 2 - Scr->pullW):\
189 (ActiveMenu->width >> 1)) * DSE *
191 #define PULLDOWNMENU_OFFSET ((Scr->RightHandSidePulldownMenus)?\
192 (JunkWidth - EDGE_OFFSET * 2 - Scr->pullW):\
197 /***********************************************************************
200 * InitMenus - initialize menu roots
202 ***********************************************************************
211 for (i = 0; i < MAX_BUTTONS+1; i++)
212 for (j = 0; j < NUM_CONTEXTS; j++)
213 for (k = 0; k < MOD_SIZE; k++)
215 Scr->Mouse[i][j][k].func = F_NOFUNCTION;
216 Scr->Mouse[i][j][k].item = NULL;
219 Scr->DefaultFunction.func = F_NOFUNCTION;
220 Scr->WindowFunction.func = F_NOFUNCTION;
224 for (key = Scr->FuncKeyRoot.next; key != NULL;)
231 Scr->FuncKeyRoot.next = NULL;
237 /***********************************************************************
240 * AddFuncKey - add a function key to the list
243 * name - the name of the key
244 * cont - the context to look for the key press in
245 * mods - modifier keys that need to be pressed
246 * func - the function to perform
247 * win_name- the window name (if any)
248 * action - the action string associated with the function (if any)
250 ***********************************************************************
253 Bool AddFuncKey (name, cont, mods, func, win_name, action)
255 int cont, mods, func;
264 * Don't let a 0 keycode go through, since that means AnyKey to the
265 * XGrabKey call in GrabKeys().
267 if ((keysym = XStringToKeysym(name)) == NoSymbol ||
268 (keycode = XKeysymToKeycode(dpy, keysym)) == 0)
273 /* see if there already is a key defined for this context */
274 for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next)
276 if (tmp->keysym == keysym &&
284 tmp = (FuncKey *) malloc(sizeof(FuncKey));
285 tmp->next = Scr->FuncKeyRoot.next;
286 Scr->FuncKeyRoot.next = tmp;
290 tmp->keysym = keysym;
291 tmp->keycode = keycode;
295 tmp->win_name = win_name;
296 tmp->action = action;
303 int CreateTitleButton (name, func, action, menuroot, rightside, append)
311 TitleButton *tb = (TitleButton *) malloc (sizeof(TitleButton));
315 "%s: unable to allocate %d bytes for title button\n",
316 ProgramName, sizeof(TitleButton));
321 tb->name = name; /* note that we are not copying */
328 /* tb->bitmap = None;*/ /* WARNING, values not set yet */
329 tb->width = 0; /* see InitTitlebarButtons */
330 tb->height = 0; /* ditto */
333 tb->menuroot = menuroot;
334 tb->rightside = rightside;
336 Scr->TBInfo.nright++;
344 * 1. empty list, prepend left put at head of list
345 * 2. append left, prepend right put in between left and right
346 * 3. append right put at tail of list
348 * Do not refer to widths and heights yet since buttons not created
349 * (since fonts not loaded and heights not known).
351 if ((!Scr->TBInfo.head) || ((!append) && (!rightside))) { /* 1 */
352 tb->next = Scr->TBInfo.head;
353 Scr->TBInfo.head = tb;
354 } else if (append && rightside) { /* 3 */
355 register TitleButton *t;
357 for (t = Scr->TBInfo.head; t->next; t = t->next)
362 register TitleButton *t, *prev = NULL;
364 for (t = Scr->TBInfo.head; t && !t->rightside; t = t->next)
367 tb->next = prev->next;
370 tb->next = Scr->TBInfo.head;
371 Scr->TBInfo.head = tb;
381 * InitTitlebarButtons - Do all the necessary stuff to load in a titlebar
382 * button. If we can't find the button, then put in a question; if we can't
383 * find the question mark, something is wrong and we are probably going to be
384 * in trouble later on.
386 /* was of type 'void', now returns button height - djhjr - 12/10/98 */
387 int InitTitlebarButtons ()
394 * initialize dimensions
396 Scr->TBInfo.width = (Scr->TitleHeight -
397 2 * (Scr->FramePadding + Scr->ButtonIndent));
401 * was 'Scr->use3Dtitles' - djhjr - 8/11/98 *
402 if (Scr->TitleBevelWidth > 0)
403 Scr->TBInfo.pad = ((Scr->TitlePadding > 1)
404 ? ((Scr->TitlePadding + 1) / 2) : 0);
407 Scr->TBInfo.pad = ((Scr->TitlePadding > 1)
408 ? ((Scr->TitlePadding + 1) / 2) : 1);
410 Scr->TBInfo.pad = Scr->TitlePadding;
412 h = Scr->TBInfo.width - 2 * Scr->TBInfo.border;
413 /* djhjr - 10/30/02 */
418 * add in some useful buttons and bindings so that novices can still
419 * use the system. -- modified by DSE
422 if (!Scr->NoDefaultTitleButtons) /* DSE */
424 /* insert extra buttons */
426 /* djhjr - 4/19/96 */
427 /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */
428 if (Scr->TitleBevelWidth > 0) {
429 if (!CreateTitleButton (TBPM_3DDOT, F_ICONIFY, "", (MenuRoot *) NULL,
431 fprintf (stderr, "%s: unable to add iconify button\n", ProgramName);
432 if (!CreateTitleButton (TBPM_3DRESIZE, F_RESIZE, "", (MenuRoot *) NULL,
434 fprintf (stderr, "%s: unable to add resize button\n", ProgramName);
438 if (!CreateTitleButton (TBPM_ICONIFY, F_ICONIFY, "", (MenuRoot *) NULL,
440 fprintf(stderr,"%s: unable to add iconify button\n",ProgramName);
441 if (!CreateTitleButton (TBPM_RESIZE, F_RESIZE, "", (MenuRoot *) NULL,
443 fprintf(stderr,"%s: unable to add resize button\n",ProgramName);
446 if (!Scr->NoDefaultMouseOrKeyboardBindings) /* DSE */
448 AddDefaultBindings ();
451 ComputeCommonTitleOffsets ();
453 /* djhjr - 6/15/98 - moved it back to here... */
454 /* djhjr - 9/14/96 - moved to CreateWindowTitlebarButtons()... */
456 * load in images and do appropriate centering
458 for (tb = Scr->TBInfo.head; tb; tb = tb->next) {
461 tb->bitmap = FindBitmap (tb->name, &tb->width, &tb->height);
463 tb->bitmap = FindBitmap (TBPM_QUESTION, &tb->width, &tb->height);
464 if (!tb->bitmap) { * cannot happen (see util.c) *
466 "%s: unable to add titlebar button \"%s\"\n",
467 ProgramName, tb->name);
472 tb->image = GetImage (tb->name, Scr->TitleC);
474 tb->image = GetImage (TBPM_QUESTION, Scr->TitleC);
475 if (!tb->image) { * cannot happen (see util.c) *
476 fprintf (stderr, "%s: unable to add titlebar button \"%s\"\n",
477 ProgramName, tb->name);
481 /* added width and height - 10/30/02 */
482 image = GetImage (tb->name, h, h, Scr->ButtonBevelWidth * 2,
483 (Scr->ButtonColorIsFrame) ? Scr->BorderColorC : Scr->TitleC);
485 tb->width = image->width;
487 /* added 'height = ' - djhjr - 12/10/98 */
488 height = tb->height = image->height;
490 tb->dstx = (h - tb->width + 1) / 2;
491 if (tb->dstx < 0) { /* clip to minimize copying */
492 tb->srcx = -(tb->dstx);
498 tb->dsty = (h - tb->height + 1) / 2;
500 tb->srcy = -(tb->dsty);
509 /* djhjr - 12/10/98 */
510 return (height > h) ? height : h;
511 /* ...end of moved */
516 /* djhjr - 10/30/02 */
517 void SetMenuIconPixmap(filename)
520 Scr->menuIconName = filename;
523 void PaintEntry(mr, mi, exposure)
528 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
529 if (Scr->MenuBevelWidth > 0)
530 Paint3DEntry (mr, mi, exposure);
532 /* djhjr - 4/22/96 */
535 PaintNormalEntry (mr, mi, exposure);
538 void Paint3DEntry(mr, mi, exposure)
548 y_offset = mi->item_num * Scr->EntryHeight + 2;
551 y_offset = mi->item_num * Scr->EntryHeight + Scr->MenuBevelWidth;
553 y_offset = (mi->item_num - mr->top) * Scr->EntryHeight + Scr->MenuBevelWidth;
556 text_y = y_offset + Scr->MenuFont.y + 2;
558 text_y = y_offset + (((Scr->EntryHeight - Scr->MenuFont.height) / 2) + Scr->MenuFont.y);
560 if (mi->func != F_TITLE)
568 Draw3DBorder (mr->w, 2, y_offset, mr->width - 4, Scr->EntryHeight, 1,
569 mi->highlight, off, True, False);
572 Draw3DBorder (mr->w, 2, y_offset + 1, mr->width - 4, Scr->EntryHeight - 1, 1,
573 mi->highlight, off, True, False);
575 Draw3DBorder (mr->w, Scr->MenuBevelWidth, y_offset + 1, mr->width - 2 * Scr->MenuBevelWidth, Scr->EntryHeight - 1, 1,
576 mi->highlight, off, True, False);
578 /* font was font.font->fid - djhjr - 9/14/03 */
579 FBF(mi->highlight.fore, mi->highlight.back, Scr->MenuFont);
582 XDrawImageString(dpy, mr->w, Scr->NormalGC, mi->x + 2, text_y, mi->item, mi->strlen);
584 /* djhjr - 9/14/03 */
585 #ifndef NO_I18N_SUPPORT
586 MyFont_DrawImageString(dpy, mr->w, &Scr->MenuFont,
588 XDrawImageString(dpy, mr->w,
590 Scr->NormalGC, mi->x + Scr->MenuBevelWidth, text_y, mi->item, mi->strlen);
596 if (mi->user_colors || !exposure)
598 XSetForeground (dpy, Scr->NormalGC, mi->normal.back);
601 XFillRectangle (dpy, mr->w, Scr->NormalGC, 2, y_offset,
602 mr->width - 4, Scr->EntryHeight);
605 XFillRectangle (dpy, mr->w, Scr->NormalGC, 2, y_offset + 1,
606 mr->width - 4, Scr->EntryHeight - 1);
608 XFillRectangle (dpy, mr->w, Scr->NormalGC, Scr->MenuBevelWidth, y_offset + 1,
609 mr->width - 2 * Scr->MenuBevelWidth, Scr->EntryHeight - 1);
611 /* font was font.font->fid - djhjr - 9/14/03 */
612 FBF (mi->normal.fore, mi->normal.back, Scr->MenuFont);
622 XDrawImageString (dpy, mr->w, gc, mi->x + 2, text_y, mi->item, mi->strlen);
624 /* djhjr - 9/14/03 */
625 #ifndef NO_I18N_SUPPORT
626 MyFont_DrawImageString (dpy, mr->w, &Scr->MenuFont,
628 XDrawImageString (dpy, mr->w,
630 gc, mi->x + Scr->MenuBevelWidth, text_y, mi->item, mi->strlen);
634 /* this 'if (...)' - djhjr - 1/19/98 */
635 if (!Scr->BeNiceToColormap)
637 FB (Scr->MenuC.shadd, Scr->MenuC.shadc);
640 XDrawLine (dpy, mr->w, Scr->NormalGC, 1, y_offset + Scr->MenuFont.y + 5,
641 mr->width - 2, y_offset + Scr->MenuFont.y + 5);
644 XDrawLine (dpy, mr->w, Scr->NormalGC, 1, y_offset + Scr->EntryHeight - 1,
645 mr->width - 2, y_offset + Scr->EntryHeight - 1);
647 XDrawLine (dpy, mr->w, Scr->NormalGC, Scr->MenuBevelWidth + 1, y_offset + Scr->EntryHeight - 1,
648 mr->width - Scr->MenuBevelWidth - 3, y_offset + Scr->EntryHeight - 1);
651 FB (Scr->MenuC.shadc, Scr->MenuC.shadd);
654 XDrawLine (dpy, mr->w, Scr->NormalGC, 2, y_offset + Scr->MenuFont.y + 6,
655 mr->width - 3, y_offset + Scr->MenuFont.y + 6);
658 XDrawLine (dpy, mr->w, Scr->NormalGC, 2, y_offset + Scr->EntryHeight,
659 mr->width - 3, y_offset + Scr->EntryHeight);
661 XDrawLine (dpy, mr->w, Scr->NormalGC, Scr->MenuBevelWidth + 2, y_offset + Scr->EntryHeight,
662 mr->width - Scr->MenuBevelWidth - 2, y_offset + Scr->EntryHeight);
666 if (mi->func == F_MENU)
669 * create the pull right pixmap if needed *
670 if (Scr->pullPm == None)
672 Scr->pullPm = Create3DMenuIcon (Scr->MenuFont.height, &Scr->pullW,
673 &Scr->pullH, Scr->MenuC);
678 back = Scr->MenuC.back;
680 Scr->MenuC.back = mi->highlight.back;
682 Scr->MenuC.back = mi->normal.back;
684 Scr->pullW = Scr->pullH = Scr->MenuFont.height;
685 image = GetImage(Scr->menuIconName,
686 Scr->pullW, Scr->pullH,
689 Scr->MenuC.back = back;
695 x = mr->width - Scr->pullW - 5;
697 x = mr->width - Scr->pullW - Scr->MenuBevelWidth - EDGE_OFFSET;
700 y = y_offset + ((Scr->MenuFont.height - Scr->pullH) / 2) + 2;
702 y = y_offset + ((Scr->EntryHeight - Scr->pullH) / 2) + 1;
704 XCopyArea (dpy, image->pixmap, mr->w, gc, 0, 0, Scr->pullW, Scr->pullH, x, y);
711 Draw3DBorder (mr->w, 2, y_offset, mr->width - 4, Scr->EntryHeight, 1,
712 mi->normal, off, True, False);
715 Draw3DBorder (mr->w, 2, y_offset, mr->width - 4, Scr->EntryHeight + 1, 1,
716 mi->normal, off, True, False);
718 Draw3DBorder (mr->w, Scr->MenuBevelWidth, y_offset, mr->width - 2 * Scr->MenuBevelWidth, Scr->EntryHeight + 1, 1,
719 mi->normal, off, True, False);
722 FBF (mi->normal.fore, mi->normal.back, Scr->MenuFont.font->fid);
724 /* font was font.font->fid - djhjr - 9/14/03 */
725 FBF (mi->normal.fore, mi->normal.back, Scr->MenuTitleFont);
728 XDrawImageString (dpy, mr->w, Scr->NormalGC, mi->x + 2, text_y, mi->item, mi->strlen);
730 /* djhjr - 9/14/03 */
731 #ifndef NO_I18N_SUPPORT
732 MyFont_DrawImageString (dpy, mr->w, &Scr->MenuTitleFont,
734 XDrawImageString (dpy, mr->w,
736 Scr->NormalGC, mi->x, text_y, mi->item, mi->strlen);
742 void PaintNormalEntry(mr, mi, exposure)
752 y_offset = mi->item_num * Scr->EntryHeight;
754 y_offset = (mi->item_num - mr->top) * Scr->EntryHeight;
757 text_y = y_offset + Scr->MenuFont.y;
759 text_y = y_offset + (((Scr->EntryHeight - Scr->MenuFont.height) / 2) + Scr->MenuFont.y);
761 if (mi->func != F_TITLE)
767 XSetForeground(dpy, Scr->NormalGC, mi->highlight.back);
769 XFillRectangle(dpy, mr->w, Scr->NormalGC, 0, y_offset,
770 mr->width, Scr->EntryHeight);
772 /* font was font.font->fid - djhjr - 9/14/03 */
773 FBF(mi->highlight.fore, mi->highlight.back, Scr->MenuFont);
775 /* djhjr - 9/14/03 */
776 #ifndef NO_I18N_SUPPORT
777 MyFont_DrawString(dpy, mr->w, &Scr->MenuFont,
779 XDrawString(dpy, mr->w,
781 Scr->NormalGC, mi->x,
782 text_y, mi->item, mi->strlen);
788 if (mi->user_colors || !exposure)
790 XSetForeground(dpy, Scr->NormalGC, mi->normal.back);
792 XFillRectangle(dpy, mr->w, Scr->NormalGC, 0, y_offset,
793 mr->width, Scr->EntryHeight);
795 /* font was font.font->fid - djhjr - 9/14/03 */
796 FBF(mi->normal.fore, mi->normal.back, Scr->MenuFont);
805 /* djhjr - 9/14/03 */
806 #ifndef NO_I18N_SUPPORT
807 MyFont_DrawString(dpy, mr->w, &Scr->MenuFont,
809 XDrawString(dpy, mr->w,
811 gc, mi->x, text_y, mi->item, mi->strlen);
816 XDrawLine (dpy, mr->w, gc, 0, y_offset + Scr->MenuFont.y + 5,
817 mr->width, y_offset + Scr->MenuFont.y + 5);
819 XDrawLine (dpy, mr->w, gc, 0, y_offset + Scr->EntryHeight - 1,
820 mr->width, y_offset + Scr->EntryHeight - 1);
823 if (mi->func == F_MENU)
826 * create the pull right pixmap if needed *
827 if (Scr->pullPm == None)
829 Scr->pullPm = CreateMenuIcon (Scr->MenuFont.height,
830 &Scr->pullW, &Scr->pullH);
835 cp.back = Scr->MenuC.back;
836 if (strncmp(Scr->menuIconName, ":xpm:", 5) != 0)
838 cp.fore = Scr->MenuC.fore;
839 Scr->MenuC.fore = (mi->state) ? mi->highlight.fore : mi->normal.fore;
840 Scr->MenuC.back = (mi->state) ? mi->highlight.back : mi->normal.back;
843 Scr->MenuC.back = (mi->state) ? mi->highlight.back : mi->normal.back;
845 Scr->pullW = Scr->pullH = Scr->MenuFont.height;
846 image = GetImage(Scr->menuIconName,
847 Scr->pullW, Scr->pullH,
850 Scr->MenuC.back = cp.back;
851 if (strncmp(Scr->menuIconName, ":xpm:", 5) != 0)
852 Scr->MenuC.fore = cp.fore;
857 x = mr->width - Scr->pullW - EDGE_OFFSET;
860 y = y_offset + ((Scr->MenuFont.height - Scr->pullH) / 2);
862 y = y_offset + ((Scr->EntryHeight - Scr->pullH) / 2);
865 XCopyPlane(dpy, Scr->pullPm->pixmap, mr->w, gc, 0, 0,
866 Scr->pullW, Scr->pullH, x, y, 1);
868 XCopyArea (dpy, image->pixmap, mr->w, gc, 0, 0,
869 Scr->pullW, Scr->pullH, x, y);
876 XSetForeground(dpy, Scr->NormalGC, mi->normal.back);
878 /* fill the rectangle with the title background color */
879 XFillRectangle(dpy, mr->w, Scr->NormalGC, 0, y_offset,
880 mr->width, Scr->EntryHeight);
882 XSetForeground(dpy, Scr->NormalGC, mi->normal.fore);
884 /* now draw the dividing lines */
886 XDrawLine (dpy, mr->w, Scr->NormalGC, 0, y_offset,
887 mr->width, y_offset);
889 y = ((mi->item_num+1) * Scr->EntryHeight)-1;
890 XDrawLine(dpy, mr->w, Scr->NormalGC, 0, y, mr->width, y);
893 FBF(mi->normal.fore, mi->normal.back, Scr->MenuFont.font->fid);
895 /* font was font.font->fid - djhjr - 9/14/03 */
896 FBF (mi->normal.fore, mi->normal.back, Scr->MenuTitleFont);
898 /* finally render the title */
899 /* djhjr - 9/14/03 */
900 #ifndef NO_I18N_SUPPORT
901 MyFont_DrawString(dpy, mr->w, &Scr->MenuTitleFont,
903 XDrawString(dpy, mr->w,
905 Scr->NormalGC, mi->x, text_y, mi->item, mi->strlen);
909 void PaintMenu(mr, e)
914 /* djhjr - 5/22/00 */
917 /* djhjr - 4/22/96 */
918 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
919 if (Scr->MenuBevelWidth > 0) {
921 Draw3DBorder (mr->w, 0, 0, mr->width, mr->height, 2, Scr->MenuC, off, False, False);
923 Draw3DBorder (mr->w, 0, 0, mr->width, mr->height, Scr->MenuBevelWidth, Scr->MenuC, off, False, False);
926 for (mi = mr->first; mi != NULL; mi = mi->next)
928 /* djhjr - 5/22/00 */
929 if (mi->item_num < mr->top) continue;
932 int y_offset = mi->item_num * Scr->EntryHeight;
934 y_offset = (mi->item_num - mr->top) * Scr->EntryHeight;
936 /* djhjr - 5/22/00 */
937 if (y_offset + Scr->EntryHeight > mr->height) break;
939 /* some servers want the previous entry redrawn - djhjr - 10/24/00 */
940 if (Scr->MenuBevelWidth > 0) y_offset += Scr->EntryHeight;
943 * Be smart about handling the expose, redraw only the entries
946 /* those servers want the next entry redrawn, too - djhjr - 10/24/00 */
947 if (e->xexpose.y < (y_offset + Scr->EntryHeight) &&
948 (e->xexpose.y + e->xexpose.height) > y_offset - ((mr->shadow) ? Scr->EntryHeight : 0))
950 PaintEntry(mr, mi, True);
958 static Bool fromMenu;
960 extern int GlobalFirstTime; /* for StayUpMenus -- PF */
965 int i, x, y, x_root, y_root, entry;
967 MenuItem *badItem = NULL;
968 static int firstTime = True;
973 { /* block until there is an event */
974 #ifdef NEVER /* see the '#else' - Steve Ratcliffe */
976 if (!menuFromFrameOrWindowOrTitlebar && ! Scr->StayUpMenus) {
978 ButtonPressMask | ButtonReleaseMask |
979 EnterWindowMask | ExposureMask |
980 VisibilityChangeMask | LeaveWindowMask |
981 ButtonMotionMask, &Event);
983 if (Event.type == MotionNotify) {
984 /* discard any extra motion events before a release */
985 while(XCheckMaskEvent(dpy,
986 ButtonMotionMask | ButtonReleaseMask, &Event))
987 if (Event.type == ButtonRelease)
991 while (XCheckMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask |
992 EnterWindowMask | ExposureMask, &Event))
993 { /* taken from tvtwm */
996 /* Submitted by Steve Ratcliffe */
997 XNextEvent(dpy, &Event);
1000 if (!DispatchEvent ()) continue;
1002 if (Event.type == ButtonRelease )
1003 { if (Scr->StayUpMenus)
1005 if (firstTime == True)
1006 { /* it was the first release of the button */
1010 { /* thats the second we need to return now */
1012 menuFromFrameOrWindowOrTitlebar = FALSE;
1019 menuFromFrameOrWindowOrTitlebar = FALSE;
1027 #ifdef NEVER /* see the above - Steve Ratcliffe */
1031 /* re-instated - Steve Ratcliffe */
1032 if (Event.type != MotionNotify)
1035 /* if we haven't received the enter notify yet, wait */
1036 if (!ActiveMenu || !ActiveMenu->entered)
1040 XQueryPointer( dpy, ActiveMenu->w, &JunkRoot, &JunkChild,
1041 &x_root, &y_root, &x, &y, &JunkMask);
1043 /* djhjr - 9/5/98 */
1045 if (abs(x_root - MenuOrigX) < Scr->MoveDelta &&
1046 abs(y_root - MenuOrigY) < Scr->MoveDelta)
1050 /* if we haven't recieved the enter notify yet, wait */
1051 if (ActiveMenu && !ActiveMenu->entered)
1055 XFindContext(dpy, ActiveMenu->w, ScreenContext, (caddr_t *)&Scr);
1057 JunkWidth = ActiveMenu->width;
1058 JunkHeight = ActiveMenu->height;
1059 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1060 if (Scr->MenuBevelWidth > 0)
1062 x -= Scr->MenuBevelWidth;
1063 y -= Scr->MenuBevelWidth;
1065 JunkWidth -= 2 * Scr->MenuBevelWidth;
1066 JunkHeight -= Scr->MenuBevelWidth;
1070 if (x < 0 || y < 0 || x >= JunkWidth || y >= JunkHeight)
1072 if ((x < 0 || y < 0 || x >= JunkWidth || y >= JunkHeight) ||
1073 (ActiveMenu->too_tall && (y < Scr->MenuScrollBorderWidth ||
1074 y > JunkHeight - Scr->MenuScrollBorderWidth)))
1076 if (ActiveItem && ActiveItem->func != F_TITLE)
1078 ActiveItem->state = 0;
1079 PaintEntry(ActiveMenu, ActiveItem, False);
1083 /* menu scrolling - djhjr - 5/22/00 */
1084 if (ActiveMenu->too_tall && x >= 0 && x < JunkWidth)
1086 short j = ActiveMenu->top;
1088 if (y < Scr->MenuScrollBorderWidth)
1090 if (ActiveMenu->top - Scr->MenuScrollJump < 0)
1093 j -= Scr->MenuScrollJump;
1095 else if (y > JunkHeight - Scr->MenuScrollBorderWidth)
1097 int k = JunkHeight / Scr->EntryHeight;
1099 if (ActiveMenu->top + k >= ActiveMenu->items)
1102 j += Scr->MenuScrollJump;
1105 if (ActiveMenu->top != j)
1107 ActiveMenu->top = j;
1108 XClearArea(dpy, ActiveMenu->w, 0, 0, 0, 0, True);
1115 /* look for the entry that the mouse is in */
1117 entry = y / Scr->EntryHeight;
1119 entry = (y / Scr->EntryHeight) + ActiveMenu->top;
1120 for (i = 0, mi = ActiveMenu->first; mi != NULL; i++, mi=mi->next)
1126 /* if there is an active item, we might have to turn it off */
1129 /* is the active item the one we are on ? */
1130 if (ActiveItem->item_num == entry && ActiveItem->state)
1133 /* if we weren't on the active entry, let's turn the old
1136 if (!done && ActiveItem->func != F_TITLE)
1138 ActiveItem->state = 0;
1139 PaintEntry(ActiveMenu, ActiveItem, False);
1143 /* djhjr - 5/22/00 */
1144 if (ActiveMenu->too_tall && y + Scr->EntryHeight > JunkHeight)
1147 /* if we weren't on the active item, change the active item and turn
1155 if (ActiveItem->func != F_TITLE && !ActiveItem->state)
1157 if (ActiveItem && ActiveItem->func != F_TITLE && !ActiveItem->state)
1159 ActiveItem->state = 1;
1160 PaintEntry(ActiveMenu, ActiveItem, False);
1162 if (Scr->StayUpOptionalMenus) /* PF */
1163 GlobalFirstTime = firstTime = False; /* PF */
1168 /* now check to see if we were over the arrow of a pull right entry */
1171 if (ActiveItem->func == F_MENU &&
1173 if (ActiveItem && ActiveItem->func == F_MENU &&
1175 /* ((ActiveMenu->width - x) < (ActiveMenu->width >> 1))) */
1176 ( x > PULLDOWNMENU_OFFSET )) /* DSE */
1178 MenuRoot *save = ActiveMenu;
1179 int savex = MenuOrigins[MenuDepth - 1].x;
1180 int savey = MenuOrigins[MenuDepth - 1].y;
1182 if (MenuDepth < MAXMENUDEPTH) {
1183 PopUpMenu (ActiveItem->sub,
1184 (savex + PULLDOWNMENU_OFFSET), /* DSE */
1185 (savey + ActiveItem->item_num * Scr->EntryHeight)
1186 /*(savey + ActiveItem->item_num * Scr->EntryHeight +
1187 (Scr->EntryHeight >> 1))*/, False);
1188 } else if (!badItem) {
1189 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
1190 badItem = ActiveItem;
1193 /* if the menu did get popped up, unhighlight the active item */
1194 if (save != ActiveMenu && ActiveItem->state)
1196 ActiveItem->state = 0;
1197 PaintEntry(save, ActiveItem, False);
1202 if (badItem != ActiveItem) badItem = NULL;
1209 /***********************************************************************
1212 * NewMenuRoot - create a new menu root
1218 * name - the name of the menu root
1220 ***********************************************************************
1229 #define UNUSED_PIXEL ((unsigned long) (~0)) /* more than 24 bits */
1231 tmp = (MenuRoot *) malloc(sizeof(MenuRoot));
1234 tmp->hi_fore = UNUSED_PIXEL;
1235 tmp->hi_back = UNUSED_PIXEL;
1237 tmp->highlight.fore = UNUSED_PIXEL;
1238 tmp->highlight.back = UNUSED_PIXEL;
1246 tmp->mapped = NEVER_MAPPED;
1250 tmp->real_menu = FALSE;
1252 /* djhjr - 5/22/00 */
1256 if (Scr->MenuList == NULL)
1258 Scr->MenuList = tmp;
1259 Scr->MenuList->next = NULL;
1262 if (Scr->LastMenu == NULL)
1264 Scr->LastMenu = tmp;
1265 Scr->LastMenu->next = NULL;
1269 Scr->LastMenu->next = tmp;
1270 Scr->LastMenu = tmp;
1271 Scr->LastMenu->next = NULL;
1275 if (strcmp(name, TWM_WINDOWS) == 0)
1277 if (strcmp(name, TWM_WINDOWS) == 0 || strcmp(name, VTWM_WINDOWS) == 0)
1285 /***********************************************************************
1288 * AddToMenu - add an item to a root menu
1294 * menu - pointer to the root menu to add the item
1295 * item - the text to appear in the menu
1296 * action - the string to possibly execute
1297 * sub - the menu root if it is a pull-right entry
1298 * func - the numeric function
1299 * fore - foreground color string
1300 * back - background color string
1302 ***********************************************************************
1306 AddToMenu(menu, item, action, sub, func, fore, back)
1308 char *item, *action;
1315 MyFont *font; /* DSE */
1318 fprintf(stderr, "adding menu item=\"%s\", action=%s, sub=%d, f=%d\n",
1319 item, action, sub, func);
1322 tmp = (MenuItem *) malloc(sizeof(MenuItem));
1325 if (menu->first == NULL)
1332 menu->last->next = tmp;
1333 tmp->prev = menu->last;
1338 tmp->strlen = strlen(item);
1339 tmp->action = action;
1345 /* djhjr - 4/22/96 */
1348 if ( func == F_TITLE && (Scr->MenuTitleFont.name != NULL) ) /* DSE */
1349 font= &(Scr->MenuTitleFont);
1351 font= &(Scr->MenuFont);
1353 if (!Scr->HaveFonts) CreateFonts();
1354 /* djhjr - 9/14/03 */
1355 #ifndef NO_I18N_SUPPORT
1356 width = MyFont_TextWidth(font,
1358 width = XTextWidth(font->font,
1363 if (width > menu->width)
1364 menu->width = width;
1366 tmp->user_colors = FALSE;
1367 if (Scr->Monochrome == COLOR && fore != NULL)
1371 save = Scr->FirstTime;
1372 Scr->FirstTime = TRUE;
1375 GetColor(COLOR, &tmp->fore, fore);
1376 GetColor(COLOR, &tmp->back, back);
1378 GetColor(COLOR, &tmp->normal.fore, fore);
1379 GetColor(COLOR, &tmp->normal.back, back);
1381 /* djhjr - 4/22/96 */
1382 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1383 /* rem'd 'Scr->MenuBevelWidth' djhjr - 10/30/02 */
1384 if (/*Scr->MenuBevelWidth > 0 && */!Scr->BeNiceToColormap) GetShadeColors (&tmp->normal);
1386 Scr->FirstTime = save;
1387 tmp->user_colors = TRUE;
1394 tmp->item_num = menu->items++;
1405 for (mr = Scr->MenuList; mr != NULL; mr = mr->next)
1407 if (mr->real_menu == FALSE)
1419 MenuItem *start, *end, *cur, *tmp;
1422 XColor save_fore, save_back;
1424 int fred, fgreen, fblue;
1425 int bred, bgreen, bblue;
1428 /* djhjr - 4/22/96 */
1431 unsigned long valuemask;
1432 XSetWindowAttributes attributes;
1433 Colormap cmap = Scr->TwmRoot.cmaps.cwins[0]->colormap->c;
1436 if ( Scr->MenuTitleFont.name != NULL ) /* DSE */
1438 Scr->EntryHeight = MAX(Scr->MenuFont.height,
1439 Scr->MenuTitleFont.height) + 4;
1440 titleFont = &(Scr->MenuTitleFont);
1444 Scr->EntryHeight = Scr->MenuFont.height + 4;
1445 titleFont= &(Scr->MenuFont);
1449 /* lets first size the window accordingly */
1450 if (mr->mapped == NEVER_MAPPED)
1452 if (mr->pull == TRUE)
1454 mr->width += 16 + 2 * EDGE_OFFSET; /* DSE */
1459 if (Scr->use3Dmenus) mr->width += 4;
1461 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1462 if (Scr->MenuBevelWidth > 0) mr->width += 2 * Scr->MenuBevelWidth;
1464 width = mr->width + 2 * EDGE_OFFSET; /* DSE */
1466 for (cur = mr->first; cur != NULL; cur = cur->next)
1468 if (cur->func != F_TITLE)
1469 cur->x = EDGE_OFFSET; /* DSE */
1473 /* djhjr - 9/14/03 */
1474 #ifndef NO_I18N_SUPPORT
1475 MyFont_TextWidth(titleFont,
1477 XTextWidth(titleFont->font,
1479 cur->item, cur->strlen);
1483 mr->height = mr->items * Scr->EntryHeight;
1487 if (Scr->use3Dmenus) mr->height += 4;
1489 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1490 if (Scr->MenuBevelWidth > 0) mr->height += 2 * Scr->MenuBevelWidth;
1492 /* djhjr - 4/22/96 */
1493 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1494 borderwidth = (Scr->MenuBevelWidth > 0) ? 0 : 1;
1496 /* djhjr - 5/22/00 */
1497 if (mr->height > Scr->MyDisplayHeight)
1500 mr->height = Scr->MyDisplayHeight - borderwidth * 2;
1503 /* added this 'if () ... else' - djhjr - 4/29/98 */
1504 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1505 if (Scr->MenuBevelWidth > 0)
1506 mr->width += 2 * Scr->MenuBevelWidth + 6;
1513 * Make sure that you don't draw into the shadow window or else
1514 * the background bits there will get saved
1516 valuemask = (CWBackPixel | CWBorderPixel);
1517 attributes.background_pixel = Scr->MenuShadowColor;
1518 attributes.border_pixel = Scr->MenuShadowColor;
1519 if (Scr->SaveUnder) {
1520 valuemask |= CWSaveUnder;
1521 attributes.save_under = True;
1523 mr->shadow = XCreateWindow (dpy, Scr->Root, 0, 0,
1524 (unsigned int) mr->width,
1525 (unsigned int) mr->height,
1528 (unsigned int) CopyFromParent,
1529 (Visual *) CopyFromParent,
1530 valuemask, &attributes);
1533 valuemask = (CWBackPixel | CWBorderPixel | CWEventMask);
1534 attributes.background_pixel = Scr->MenuC.back;
1535 attributes.border_pixel = Scr->MenuC.fore;
1536 attributes.event_mask = (ExposureMask | EnterWindowMask);
1537 if (Scr->SaveUnder) {
1538 valuemask |= CWSaveUnder;
1539 attributes.save_under = True;
1541 if (Scr->BackingStore) {
1542 valuemask |= CWBackingStore;
1543 attributes.backing_store = Always;
1546 mr->w = XCreateWindow (dpy, Scr->Root, 0, 0, (unsigned int) mr->width,
1549 (unsigned int) mr->height, (unsigned int) 1,
1551 (unsigned int) mr->height, (unsigned int) borderwidth,
1553 CopyFromParent, (unsigned int) CopyFromParent,
1554 (Visual *) CopyFromParent,
1555 valuemask, &attributes);
1558 XSaveContext(dpy, mr->w, MenuContext, (caddr_t)mr);
1559 XSaveContext(dpy, mr->w, ScreenContext, (caddr_t)Scr);
1561 mr->mapped = UNMAPPED;
1564 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1565 if (Scr->MenuBevelWidth > 0 && (Scr->Monochrome == COLOR) && (mr->highlight.back == UNUSED_PIXEL)) {
1570 xcol.pixel = Scr->MenuC.back;
1571 XQueryColor (dpy, cmap, &xcol);
1572 sprintf (colname, "#%04x%04x%04x",
1573 5 * (xcol.red / 6), 5 * (xcol.green / 6), 5 * (xcol.blue / 6));
1574 save = Scr->FirstTime;
1575 Scr->FirstTime = True;
1576 GetColor (Scr->Monochrome, &mr->highlight.back, colname);
1577 Scr->FirstTime = save;
1580 /* djhjr - 4/22/96 */
1581 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1582 if (Scr->MenuBevelWidth > 0 && (Scr->Monochrome == COLOR) && (mr->highlight.fore == UNUSED_PIXEL)) {
1586 xcol.pixel = Scr->MenuC.fore;
1587 XQueryColor (dpy, cmap, &xcol);
1588 sprintf (colname, "#%04x%04x%04x",
1589 5 * (xcol.red / 6), 5 * (xcol.green / 6), 5 * (xcol.blue / 6));
1590 save = Scr->FirstTime;
1591 Scr->FirstTime = True;
1592 GetColor (Scr->Monochrome, &mr->highlight.fore, colname);
1593 Scr->FirstTime = save;
1595 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1596 if (Scr->MenuBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors (&mr->highlight);
1598 /* get the default colors into the menus */
1599 for (tmp = mr->first; tmp != NULL; tmp = tmp->next)
1602 if (!tmp->user_colors) {
1603 if (tmp->func != F_TITLE) {
1604 tmp->fore = Scr->MenuC.fore;
1605 tmp->back = Scr->MenuC.back;
1607 tmp->fore = Scr->MenuTitleC.fore;
1608 tmp->back = Scr->MenuTitleC.back;
1612 if (mr->hi_fore != UNUSED_PIXEL)
1614 tmp->hi_fore = mr->hi_fore;
1615 tmp->hi_back = mr->hi_back;
1619 tmp->hi_fore = tmp->back;
1620 tmp->hi_back = tmp->fore;
1623 if (!tmp->user_colors) {
1624 if (tmp->func != F_TITLE) {
1625 tmp->normal.fore = Scr->MenuC.fore;
1626 tmp->normal.back = Scr->MenuC.back;
1628 tmp->normal.fore = Scr->MenuTitleC.fore;
1629 tmp->normal.back = Scr->MenuTitleC.back;
1633 if (mr->highlight.fore != UNUSED_PIXEL)
1635 tmp->highlight.fore = mr->highlight.fore;
1636 tmp->highlight.back = mr->highlight.back;
1640 tmp->highlight.fore = tmp->normal.back;
1641 tmp->highlight.back = tmp->normal.fore;
1643 /* was 'Scr->use3Dmenus' - djhjr - 8/11/98 */
1644 if (Scr->MenuBevelWidth > 0 && !Scr->BeNiceToColormap) {
1645 if (tmp->func != F_TITLE)
1646 GetShadeColors (&tmp->highlight);
1648 GetShadeColors (&tmp->normal);
1652 } /* end for(...) */
1654 if (Scr->Monochrome == MONOCHROME || !Scr->InterpolateMenuColors)
1660 for (; start != NULL; start = start->next)
1662 if (start->user_colors)
1668 for (end = start->next; end != NULL; end = end->next)
1670 if (end->user_colors)
1676 /* we have a start and end to interpolate between */
1677 num = end->item_num - start->item_num;
1680 f1.pixel = start->fore;
1681 XQueryColor(dpy, cmap, &f1);
1682 f2.pixel = end->fore;
1683 XQueryColor(dpy, cmap, &f2);
1685 b1.pixel = start->back;
1686 XQueryColor(dpy, cmap, &b1);
1687 b2.pixel = end->back;
1688 XQueryColor(dpy, cmap, &b2);
1690 f1.pixel = start->normal.fore;
1691 XQueryColor(dpy, cmap, &f1);
1692 f2.pixel = end->normal.fore;
1693 XQueryColor(dpy, cmap, &f2);
1694 b1.pixel = start->normal.back;
1695 XQueryColor(dpy, cmap, &b1);
1696 b2.pixel = end->normal.back;
1697 XQueryColor(dpy, cmap, &b2);
1699 fred = ((int)f2.red - (int)f1.red) / num;
1700 fgreen = ((int)f2.green - (int)f1.green) / num;
1701 fblue = ((int)f2.blue - (int)f1.blue) / num;
1703 bred = ((int)b2.red - (int)b1.red) / num;
1704 bgreen = ((int)b2.green - (int)b1.green) / num;
1705 bblue = ((int)b2.blue - (int)b1.blue) / num;
1708 f3.flags = DoRed | DoGreen | DoBlue;
1711 b3.flags = DoRed | DoGreen | DoBlue;
1713 /* djhjr - 4/23/96 */
1714 start->highlight.back = start->normal.fore;
1715 start->highlight.fore = start->normal.back;
1718 for (i = 0, cur = start->next; i < num; i++, cur = cur->next)
1730 if (Scr->DontInterpolateTitles && (cur->func == F_TITLE))
1731 continue; /* DSE -- from tvtwm */
1733 XAllocColor(dpy, cmap, &f3);
1734 XAllocColor(dpy, cmap, &b3);
1737 cur->hi_back = cur->fore = f3.pixel;
1738 cur->hi_fore = cur->back = b3.pixel;
1740 cur->highlight.back = cur->normal.fore = f3.pixel;
1741 cur->highlight.fore = cur->normal.back = b3.pixel;
1742 cur->user_colors = True;
1750 start->highlight.back = start->normal.fore;
1751 start->highlight.fore = start->normal.back;
1758 /***********************************************************************
1761 * PopUpMenu - pop up a pull down menu
1764 * menu - the root pointer of the menu to pop up
1765 * x, y - location of upper left of menu
1766 * center - whether or not to center horizontally over position
1768 ***********************************************************************
1771 Bool PopUpMenu (menu, x, y, center)
1776 int WindowNameOffset, WindowNameCount;
1777 TwmWindow **WindowNames;
1778 TwmWindow *tmp_win2,*tmp_win3;
1782 (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1);
1784 /* djhjr - 9/5/98 */
1787 if (!menu) return False;
1789 /* djhjr - 6/22/01 */
1790 #ifndef NO_SOUND_SUPPORT
1791 if (!PlaySound(F_MENU)) PlaySound(S_MMAP);
1794 /* djhjr - 5/22/00 */
1796 if (menu->w) XClearArea(dpy, menu->w, 0, 0, 0, 0, True);
1798 InstallRootColormap();
1800 if (menu == Scr->Windows)
1804 /* this is the twm windows menu, let's go ahead and build it */
1812 menu->mapped = NEVER_MAPPED;
1815 AddToMenu(menu, "TWM Windows", NULLSTR, (MenuRoot *)NULL, F_TITLE,NULLSTR,NULLSTR);
1817 AddToMenu(menu, "VTWM Windows", NULLSTR, (MenuRoot *)NULL, F_TITLE,NULLSTR,NULLSTR);
1819 WindowNameOffset=(char *)Scr->TwmRoot.next->name -
1820 (char *)Scr->TwmRoot.next;
1821 for(tmp_win = Scr->TwmRoot.next , WindowNameCount=0;
1823 tmp_win = tmp_win->next)
1826 if (WindowNameCount != 0) /* Submitted by Jennifer Elaan */
1829 (TwmWindow **)malloc(sizeof(TwmWindow *)*WindowNameCount);
1830 WindowNames[0] = Scr->TwmRoot.next;
1831 for(tmp_win = Scr->TwmRoot.next->next , WindowNameCount=1;
1833 tmp_win = tmp_win->next,WindowNameCount++)
1835 /* Submitted by Erik Agsjo <erik.agsjo@aktiedirekt.com> */
1836 if (LookInList(Scr->DontShowInTWMWindows, tmp_win->full_name, &tmp_win->class))
1843 for (i=0;i<WindowNameCount;i++)
1845 if ((*compar)(tmp_win2->name,WindowNames[i]->name) < 0)
1847 tmp_win3 = tmp_win2;
1848 tmp_win2 = WindowNames[i];
1849 WindowNames[i] = tmp_win3;
1852 WindowNames[WindowNameCount] = tmp_win2;
1854 for (i=0; i<WindowNameCount; i++)
1856 AddToMenu(menu, WindowNames[i]->name, (char *)WindowNames[i],
1857 (MenuRoot *)NULL, F_POPUP,NULLSTR,NULLSTR);
1858 if (!Scr->OldFashionedTwmWindowsMenu
1859 && Scr->Monochrome == COLOR)/*RFBCOLOR*/
1861 menu->last->user_colors = TRUE;/*RFBCOLOR*/
1865 WindowNames[i]->virtual.fore;*RFBCOLOR*
1868 menu->last->normal.fore =
1869 WindowNames[i]->virtual.fore;*RFBCOLOR*
1871 menu->last->normal.fore = Scr->MenuC.fore;
1875 WindowNames[i]->virtual.back;*RFBCOLOR*
1877 menu->last->normal.back =
1878 WindowNames[i]->virtual.back;
1880 /**********************************************************/
1882 /* Okay, okay, it's a bit of a kludge. */
1884 /* On the other hand, it's nice to have the VTWM Windows */
1885 /* menu come up with "the right colors". And the colors */
1886 /* from the panner are not a bad choice... */
1888 /**********************************************************/
1896 if (menu->w == None || menu->items == 0) return False;
1898 /* Prevent recursively bringing up menus. */
1899 if (menu->mapped == MAPPED) return False;
1902 * Dynamically set the parent; this allows pull-ups to also be main
1903 * menus, or to be brought up from more than one place.
1905 menu->prev = ActiveMenu;
1908 * Submitted by Steve Ratcliffe
1910 mask = ButtonPressMask | ButtonReleaseMask |
1911 ButtonMotionMask | PointerMotionHintMask;
1912 if (Scr->StayUpMenus)
1913 mask |= PointerMotionMask;
1915 XGrabPointer(dpy, Scr->Root, True, mask,
1916 GrabModeAsync, GrabModeAsync,
1917 Scr->Root, Scr->MenuCursor, CurrentTime);
1920 menu->mapped = MAPPED;
1921 menu->entered = FALSE;
1924 x -= (menu->width / 2);
1925 y -= (Scr->EntryHeight / 2); /* sticky menus would be nice here */
1931 /* next line and " - i" to "x = " and "y = " - djhjr - 5/22/00 */
1932 i = (Scr->MenuBevelWidth > 0) ? 0 : 2;
1933 if (x + menu->width > Scr->MyDisplayWidth) {
1934 x = Scr->MyDisplayWidth - menu->width - i;
1937 if (y + menu->height > Scr->MyDisplayHeight) {
1938 y = Scr->MyDisplayHeight - menu->height - i;
1942 MenuOrigins[MenuDepth].x = x;
1943 MenuOrigins[MenuDepth].y = y;
1946 XMoveWindow(dpy, menu->w, x, y);
1948 XMoveWindow (dpy, menu->shadow, x + SHADOWWIDTH, y + SHADOWWIDTH);
1951 XRaiseWindow (dpy, menu->shadow);
1953 XMapRaised(dpy, menu->w);
1955 XMapWindow (dpy, menu->shadow);
1959 /* djhjr - 9/5/98 */
1960 XQueryPointer(dpy, menu->w, &JunkRoot, &JunkChild,
1961 &x_root, &y_root, &JunkX, &JunkY, &JunkMask);
1970 /***********************************************************************
1973 * PopDownMenu - unhighlight the current menu selection and
1974 * take down the menus
1976 ***********************************************************************
1983 if (ActiveMenu == NULL)
1986 /* djhjr - 6/22/01 */
1987 #ifndef NO_SOUND_SUPPORT
1988 PlaySound(S_MUNMAP);
1993 ActiveItem->state = 0;
1994 PaintEntry(ActiveMenu, ActiveItem, False);
1997 for (tmp = ActiveMenu; tmp != NULL; tmp = tmp->prev)
2000 XUnmapWindow (dpy, tmp->shadow);
2002 XUnmapWindow(dpy, tmp->w);
2003 tmp->mapped = UNMAPPED;
2004 UninstallRootColormap();
2011 if (Context == C_WINDOW || Context == C_FRAME || Context == C_TITLE)
2012 { menuFromFrameOrWindowOrTitlebar = TRUE;
2018 /***********************************************************************
2021 * FindMenuRoot - look for a menu root
2024 * (MenuRoot *) - a pointer to the menu root structure
2027 * name - the name of the menu root
2029 ***********************************************************************
2038 for (tmp = Scr->MenuList; tmp != NULL; tmp = tmp->next)
2040 if (strcmp(name, tmp->name) == 0)
2048 static Bool belongs_to_twm_window (t, w)
2049 register TwmWindow *t;
2052 if (!t) return False;
2056 if (w == t->frame || w == t->title_w || w == t->hilite_w ||
2057 w == t->icon_w || w == t->icon_bm_w) return True;
2060 if (t && t->titlebuttons) {
2061 register TBWindow *tbw;
2062 register int nb = Scr->TBInfo.nleft + Scr->TBInfo.nright;
2063 for (tbw = t->titlebuttons; nb > 0; tbw++, nb--) {
2064 if (tbw->window == w) return True;
2073 * Hack^H^H^H^HWrapper to moves for non-menu contexts.
2075 * djhjr - 10/11/01 10/4/02
2077 static void moveFromCenterWrapper(tmp_win)
2080 if (!tmp_win->opaque_move) XUngrabServer(dpy);
2082 WarpScreenToWindow(tmp_win);
2084 /* now here's a nice little kludge... */
2086 int hilite = tmp_win->highlight;
2088 tmp_win->highlight = True;
2089 SetBorder(tmp_win, (hilite) ? True : False);
2090 tmp_win->highlight = hilite;
2092 Scr->Focus = tmp_win;
2095 if (!tmp_win->opaque_move) XGrabServer(dpy);
2099 * Jason P. Venner jason@tfs.com
2100 * This function is used by F_WARPTO to match the action name
2101 * against window names.
2102 * Re-written to use list.c:MatchName(), allowing VTWM-style wilcards.
2105 int MatchWinName(action, t)
2110 #ifndef NO_REGEX_SUPPORT
2116 if (MatchName(t->full_name, action, &re, LTYPE_ANY_STRING))
2117 if (MatchName(t->class.res_name, action, &re, LTYPE_ANY_STRING))
2118 if (MatchName(t->class.res_class, action, &re, LTYPE_ANY_STRING))
2126 /***********************************************************************
2129 * ExecuteFunction - execute a twm root function
2132 * func - the function to execute
2133 * action - the menu action to execute
2134 * w - the window to execute this function on
2135 * tmp_win - the twm window structure
2136 * event - the event that caused the function
2137 * context - the context in which the button was pressed
2138 * pulldown- flag indicating execution from pull down menu
2141 * TRUE if should continue with remaining actions else FALSE to abort
2143 ***********************************************************************
2146 extern int MovedFromKeyPress;
2149 ExecuteFunction(func, action, w, tmp_win, eventp, context, pulldown)
2160 char buff[MAX_FILE_SIZE];
2162 int do_next_action = TRUE;
2164 actionHack = action; /* Submitted by Michel Eyckmans */
2165 RootFunction = F_NOFUNCTION;
2167 return TRUE; /* XXX should this be FALSE? */
2173 case F_RIGHTICONMGR:
2183 case F_WARP: /* PF */
2184 case F_WARPCLASSNEXT: /* PF */
2185 case F_WARPCLASSPREV: /* PF */
2186 case F_WARPTOSCREEN:
2189 case F_WARPTOICONMGR:
2192 /* djhjr - 4/30/96 */
2195 /* djhjr - 12/14/98 */
2196 case F_STATICICONPOSITIONS:
2198 /* djhjr - 5/30/00 */
2202 /* djhjr - 6/22/01 */
2203 #ifndef NO_SOUND_SUPPORT
2207 /* djhjr - 10/2/01 */
2208 case F_STRICTICONMGR:
2210 /* djhjr - 9/9/02 */
2213 case F_UNBINDBUTTONS:
2218 XGrabPointer(dpy, Scr->Root, True,
2219 ButtonPressMask | ButtonReleaseMask,
2220 GrabModeAsync, GrabModeAsync,
2221 Scr->Root, Scr->WaitCursor, CurrentTime);
2225 /* djhjr - 6/22/01 */
2226 #ifndef NO_SOUND_SUPPORT
2230 case F_SQUEEZECENTER:
2232 case F_SQUEEZERIGHT:
2234 /* djhjr - 11/4/03 */
2250 case F_WARPCLASSNEXT:
2251 case F_WARPCLASSPREV:
2254 case F_WARPTOICONMGR:
2255 case F_WARPTONEWEST:
2256 case F_WARPTOSCREEN:
2257 /* handle uniquely */
2278 case F_RIGHTICONMGR:
2281 case F_SAVEYOURSELF:
2286 /* djhjr - 9/9/02 */
2289 case F_UNBINDBUTTONS:
2292 /* ignore if from a root menu */
2293 if (Context != C_ROOT && Context != C_NO_CONTEXT)
2310 if (WindowMoved) do_next_action = FALSE;
2315 /* added this 'case' and 'if () ... else ' - djhjr - 7/15/98 */
2317 if (func == F_STARTWM)
2319 /* dynamic allocation of (char **)my_argv - djhjr - 9/26/02 */
2321 char *p, *delims = " \t";
2322 char *new_argv = NULL, **my_argv = NULL;
2325 p = strtok(action, delims);
2331 new_argv = (char *)realloc((char *)my_argv,
2332 i * sizeof(char *));
2333 if (new_argv == NULL)
2336 "%s: unable to allocate %d bytes for execvp()\n",
2337 ProgramName, i * sizeof(char *));
2341 my_argv = (char **)new_argv;
2344 my_argv[j++] = strdup(p);
2345 p = strtok(NULL, delims);
2348 if (new_argv != NULL)
2352 /* djhjr - 7/31/98 */
2353 setup_restart(eventp->xbutton.time);
2355 execvp(*my_argv, my_argv);
2356 fprintf(stderr, "%s: unable to start \"%s\"\n",
2357 ProgramName, *my_argv);
2361 if (new_argv == NULL)
2367 free((char *)my_argv);
2371 /* djhjr - 7/31/98 */
2372 RestartVtwm(eventp->xbutton.time);
2379 case F_RIGHTICONMGR:
2382 MoveIconManager(func);
2387 JumpIconManager(func);
2392 /* added this 'if (...) else ...' - djhjr - 9/21/99 */
2393 if (context == C_ROOT)
2397 ShowIconMgr(&Scr->iconmgr);
2400 * New code in list.c necessitates 'next_entry()' and
2401 * 'contents_of_entry()' - djhjr - 10/20/01
2403 for (list = Scr->IconMgrs; list != NULL; list = next_entry(list))
2404 ShowIconMgr((IconMgr *)contents_of_entry(list));
2410 if ((ip = (IconMgr *)LookInList(Scr->IconMgrs, tmp_win->full_name,
2411 &tmp_win->class)) == NULL)
2417 RaiseStickyAbove(); /* DSE */
2424 if (Scr->NoIconManagers)
2427 /* added argument - djhjr - 9/21/99 */
2428 HideIconManager((context == C_ROOT) ? NULL : tmp_win);
2434 /* djhjr - 6/10/98 */
2435 if (Scr->NoIconManagers || Scr->iconmgr.count == 0)
2438 if (DeferExecution(context, func, Scr->SelectCursor))
2444 save_sort = Scr->SortIconMgr;
2445 Scr->SortIconMgr = TRUE;
2447 if (context == C_ICONMGR)
2448 SortIconManager((IconMgr *) NULL);
2449 else if (tmp_win->iconmgr)
2450 SortIconManager(tmp_win->iconmgrp);
2452 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2454 Scr->SortIconMgr = save_sort;
2459 if (DeferExecution(context, func, Scr->SelectCursor))
2468 Identify ((TwmWindow *) NULL);
2471 case F_ZOOMZOOM: /* RFB silly */
2472 /* added args to iconmgrs - djhjr - 10/11/01 */
2473 Zoom( None, NULL, None, NULL );
2476 case F_AUTOPAN:/*RFB F_AUTOPAN*/
2477 { /* toggle autopan *//*RFB F_AUTOPAN*/
2478 static int saved;/*RFB F_AUTOPAN*/
2480 if ( Scr->AutoPanX )
2481 { saved = Scr->AutoPanX;/*RFB F_AUTOPAN*/
2482 Scr->AutoPanX = 0;/*RFB F_AUTOPAN*/
2483 } else { /*RFB F_AUTOPAN*/
2484 Scr->AutoPanX = saved;/*RFB F_AUTOPAN*/
2485 /* if restart with no autopan, we'll set the
2486 ** variable but we won't pan
2488 RaiseAutoPan(); /* DSE */
2490 break;/*RFB F_AUTOPAN*/
2493 case F_STICKYABOVE: /* DSE */
2494 if (Scr->StickyAbove) {
2495 LowerSticky(); Scr->StickyAbove = FALSE;
2496 /* don't change the order of execution! */
2498 Scr->StickyAbove = TRUE; RaiseStickyAbove(); RaiseAutoPan();
2499 /* don't change the order of execution! */
2502 /* break; *//* NOT REACHABLE */
2505 if (DeferExecution(context, func, Scr->SelectCursor))
2508 tmp_win->auto_raise = !tmp_win->auto_raise;
2509 if (tmp_win->auto_raise) ++(Scr->NumAutoRaises);
2510 else --(Scr->NumAutoRaises);
2515 /* djhjr - 6/22/01 */
2516 #ifndef NO_SOUND_SUPPORT
2517 /* sound has priority over bell */
2518 if (PlaySound(func)) break;
2521 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2525 tmp_win = (TwmWindow *)action;
2526 if (Scr->WindowFunction.func != F_NOFUNCTION)
2528 ExecuteFunction(Scr->WindowFunction.func,
2529 Scr->WindowFunction.item->action,
2530 w, tmp_win, eventp, C_FRAME, FALSE);
2535 XRaiseWindow (dpy, tmp_win->frame);
2536 XRaiseWindow (dpy, tmp_win->VirtualDesktopDisplayWindow);
2545 TwmWindow *focused = NULL; /* djhjr - 5/27/03 */
2546 Bool fromtitlebar = False;
2549 int resizefromcenter = 0; /* djhjr - 10/2/02 */
2550 /* djhjr - 10/6/02 */
2551 #ifndef NO_SOUND_SUPPORT
2552 int did_playsound = FALSE;
2555 if (DeferExecution(context, func, Scr->ResizeCursor))
2561 XWarpPointer(dpy, None, Scr->Root, 0, 0, 0, 0,
2562 eventp->xbutton.x_root,
2563 eventp->xbutton.y_root);
2565 EventHandler[EnterNotify] = HandleUnknown;
2566 EventHandler[LeaveNotify] = HandleUnknown;
2568 /* allow the resizing of doors - djhjr - 2/22/99
2569 if ((w != tmp_win->icon_w) && (context != C_DOOR))
2571 if (context == C_ICON) /* can't resize icons */
2573 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2578 * Resizing from a titlebar menu was handled uniquely long
2579 * before I got here, and I added virtual windows and icon
2580 * managers on 9/15/99 and 10/11/01, leveraging that code.
2581 * It's all been integrated here.
2584 if (Context & (C_FRAME_BIT | C_WINDOW_BIT | C_TITLE_BIT)
2585 && menuFromFrameOrWindowOrTitlebar)
2587 XGetGeometry(dpy, w, &JunkRoot, &origDragX, &origDragY,
2588 (unsigned int *)&DragWidth,
2589 (unsigned int *)&DragHeight,
2590 &JunkBW, &JunkDepth);
2592 resizefromcenter = 2;
2594 else if (Context == C_VIRTUAL_WIN)
2598 if ((XFindContext(dpy, eventp->xbutton.subwindow,
2599 VirtualContext, (caddr_t *) &twin) == XCNOENT))
2601 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2607 resizefromcenter = 1;
2609 else if (Context == C_ICONMGR && tmp_win->list)
2611 /* added the second argument - djhjr - 5/28/00 */
2612 if (!warp_if_warpunmapped(tmp_win, F_NOFUNCTION))
2614 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2618 resizefromcenter = 1;
2621 if (resizefromcenter)
2623 WarpScreenToWindow(tmp_win);
2625 XWarpPointer(dpy, None, Scr->Root, 0, 0, 0, 0,
2626 tmp_win->frame_x + tmp_win->frame_width / 2,
2627 tmp_win->frame_y + tmp_win->frame_height / 2);
2629 /* grr - djhjr - 5/27/03 */
2630 focused = Scr->Focus;
2631 Scr->Focus = tmp_win;
2632 SetBorder(Scr->Focus, True);
2634 /* save positions so we can tell if it was moved or not */
2635 ResizeOrigX = tmp_win->frame_x + tmp_win->frame_width / 2;
2636 ResizeOrigY = tmp_win->frame_y + tmp_win->frame_height / 2;
2640 /* save position so we can tell if it was moved or not */
2641 ResizeOrigX = eventp->xbutton.x_root;
2642 ResizeOrigY = eventp->xbutton.y_root;
2645 /* see if this is being done from the titlebar */
2646 fromtitlebar = belongs_to_twm_window(tmp_win,
2647 eventp->xbutton.window);
2649 if (resizefromcenter == 2)
2651 MenuStartResize(tmp_win, origDragX, origDragY,
2652 DragWidth, DragHeight, Context);
2654 releaseEvent = ButtonPress;
2655 movementMask = PointerMotionMask;
2659 StartResize(eventp, tmp_win, fromtitlebar, context);
2661 fromtitlebar = False;
2662 releaseEvent = ButtonRelease;
2663 movementMask = ButtonMotionMask;
2666 /* substantially re-worked - djhjr - 5/27/03 */
2669 /* added exposure event masks - djhjr - 10/11/01 */
2670 XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask |
2671 EnterWindowMask | LeaveWindowMask |
2672 ExposureMask | VisibilityChangeMask |
2673 movementMask, &Event);
2676 * See down below, after this loop - djhjr - 5/27/03
2679 /* discard crossing events before a release - djhjr - 10/11/01 */
2680 if (Event.xany.type == EnterNotify ||
2681 Event.xany.type == LeaveNotify)
2683 /* this can't be the proper place - djhjr - 10/2/02 */
2684 SetBorder(tmp_win, True);
2691 * Don't discard exposure events before release
2692 * or window borders and/or their titles in the
2693 * virtual desktop won't get redrawn - djhjr
2696 /* discard any extra motion events before a release */
2697 if (Event.type == MotionNotify)
2699 /* was 'ButtonMotionMask' - djhjr - 10/11/01 */
2700 while (XCheckMaskEvent(dpy, releaseEvent | movementMask,
2703 if (Event.type == releaseEvent)
2709 * See above, before this loop - djhjr - 5/27/03
2712 if (fromtitlebar && Event.type == ButtonPress) {
2713 fromtitlebar = False;
2718 if (Event.type == releaseEvent)
2722 if (tmp_win->opaque_resize)
2724 ConstrainSize(tmp_win, &origWidth, &origHeight);
2725 SetupWindow(tmp_win, origx, origy,
2726 origWidth, origHeight, -1);
2727 ResizeTwmWindowContents(tmp_win,
2728 origWidth, origHeight);
2731 MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0);
2733 ResizeWindow = None;
2734 resizing_window = 0;
2735 do_next_action = FALSE;
2739 if (resizefromcenter == 2)
2741 /* added passing of 'Context' - djhjr - 9/30/02 */
2742 MenuEndResize(tmp_win, Context);
2747 /* DispatchEvent2() is depreciated - djhjr - 10/6/02 */
2750 /* djhjr - 5/27/03 11/2/03 */
2751 if (!Scr->NoRaiseResize && !Scr->RaiseOnStart &&
2754 XRaiseWindow(dpy, tmp_win->frame);
2755 SetRaiseWindow(tmp_win);
2762 /* DispatchEvent2() is depreciated - djhjr - 10/6/02 */
2763 if (!DispatchEvent()) continue;
2765 if (Event.type != MotionNotify) continue;
2767 XQueryPointer(dpy, Scr->Root,
2768 &JunkRoot, &JunkChild, &JunkX, &JunkY,
2769 &AddingX, &AddingY, &JunkMask);
2771 if (!resizing_window &&
2772 (abs(AddingX - ResizeOrigX) < Scr->MoveDelta &&
2773 abs(AddingY - ResizeOrigY) < Scr->MoveDelta))
2778 resizing_window = 1;
2781 /* djhjr - 5/27/03 11/3/03 */
2782 if ((!Scr->NoRaiseResize && Scr->RaiseOnStart)
2783 /* trap a Shape extention bug - djhjr - 5/27/03 */
2784 || (tmp_win->opaque_resize &&
2786 (tmp_win->wShaped || tmp_win->squeeze_info)))
2789 XRaiseWindow(dpy, tmp_win->frame);
2790 SetRaiseWindow(tmp_win);
2791 if (Scr->Virtual && tmp_win->VirtualDesktopDisplayWindow)
2792 XRaiseWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
2795 /* djhjr - 6/22/01 */
2796 #ifndef NO_SOUND_SUPPORT
2797 if (did_playsound == FALSE)
2800 did_playsound = TRUE;
2804 /* MenuDoResize() is depreciated - djhjr - 10/6/02 */
2805 DoResize(AddingX, AddingY, tmp_win);
2814 if (!Scr->NoGrabServer) XUngrabServer(dpy);
2816 if (!tmp_win->opaque_resize) XUngrabServer(dpy);
2819 * All this stuff from resize.c:EndResize() - djhjr - 10/6/02
2822 if (!tmp_win->opaque_resize)
2823 UninstallRootColormap();
2825 /* discard queued enter and leave events - djhjr - 5/27/03 */
2826 while (XCheckMaskEvent(dpy, EnterWindowMask | LeaveWindowMask,
2830 if (!Scr->NoRaiseResize)
2832 RaiseStickyAbove (); /* DSE */
2836 /* update virtual coords */
2837 tmp_win->virtual_frame_x = Scr->VirtualDesktopX + tmp_win->frame_x;
2838 tmp_win->virtual_frame_y = Scr->VirtualDesktopY + tmp_win->frame_y;
2840 /* UpdateDesktop(tmp_win); Stig */
2842 MoveResizeDesktop(tmp_win, Scr->NoRaiseResize); * Stig *
2844 MoveResizeDesktop(tmp_win, Cancel | Scr->NoRaiseResize); /* Stig */
2846 /* djhjr - 9/30/02 10/6/02 */
2847 if (Context == C_VIRTUAL_WIN)
2850 * Mask a bug that calls MoveOutline(zeros) after the
2851 * border has been repainted, leaving artifacts. I think
2852 * I know what the bug is, but I can't seem to fix it.
2854 if (Scr->BorderBevelWidth > 0) PaintBorders(tmp_win, False);
2856 JunkX = tmp_win->virtual_frame_x + tmp_win->frame_width / 2;
2857 JunkY = tmp_win->virtual_frame_y + tmp_win->frame_height / 2;
2858 XWarpPointer(dpy, None, Scr->VirtualDesktopDisplayOuter,
2859 0, 0, 0, 0, SCALE_D(JunkX), SCALE_D(JunkY));
2861 /* grr - djhjr - 5/27/03 */
2862 SetBorder(Scr->Focus, False);
2863 Scr->Focus = focused;
2866 /* djhjr - 6/4/98 */
2867 /* don't re-map if the window is the virtual desktop - djhjr - 2/28/99 */
2868 if (Scr->VirtualReceivesMotionEvents &&
2869 /* !tmp_win->opaque_resize && */
2870 tmp_win->w != Scr->VirtualDesktopDisplayOuter)
2872 XUnmapWindow(dpy, Scr->VirtualDesktopDisplay);
2873 XMapWindow(dpy, Scr->VirtualDesktopDisplay);
2886 if (DeferExecution(context, func, Scr->SelectCursor))
2889 /* djhjr - 4/1/00 */
2892 fullzoom(tmp_win, func);
2893 /* UpdateDesktop(tmp_win); Stig */
2894 MoveResizeDesktop(tmp_win, Scr->NoRaiseMove); /* Stig */
2900 static Time last_time = 0;
2902 Bool fromtitlebar = False;
2903 int moving_icon = FALSE;
2904 int constMoveDir, constMoveX, constMoveY;
2905 int constMoveXL, constMoveXR, constMoveYT, constMoveYB;
2910 int movefromcenter = 0; /* djhjr - 10/4/02 */
2911 /* djhjr - 6/22/01 */
2912 #ifndef NO_SOUND_SUPPORT
2913 int did_playsound = FALSE;
2916 if (DeferExecution(context, func, Scr->MoveCursor))
2920 rootw = eventp->xbutton.root;
2923 XWarpPointer(dpy, None, Scr->Root,
2924 0, 0, 0, 0, eventp->xbutton.x_root,
2925 eventp->xbutton.y_root);
2927 EventHandler[EnterNotify] = HandleUnknown;
2928 EventHandler[LeaveNotify] = HandleUnknown;
2931 if (!Scr->NoGrabServer || !Scr->OpaqueMove) XGrabServer(dpy);
2934 if (!Scr->NoGrabServer) XGrabServer(dpy);
2936 if (!tmp_win->opaque_move) XGrabServer(dpy);
2938 /* use initialized size... djhjr - 5/9/96
2940 Scr->SizeStringOffset = SIZE_HINDENT;
2941 XResizeWindow(dpy, Scr->SizeWindow,
2942 Scr->SizeStringWidth + SIZE_HINDENT * 2,
2943 Scr->SizeFont.height + SIZE_VINDENT * 2);
2946 XGrabPointer(dpy, eventp->xbutton.root, True,
2947 ButtonPressMask | ButtonReleaseMask |
2948 ButtonMotionMask | PointerMotionMask,
2949 /* PointerMotionHintMask */
2950 GrabModeAsync, GrabModeAsync,
2951 Scr->Root, Scr->MoveCursor, CurrentTime);
2953 /* added this 'if (...) else' - djhjr - 10/11/01 */
2954 if (context == C_VIRTUAL_WIN)
2958 if ((XFindContext(dpy, eventp->xbutton.subwindow,
2959 VirtualContext, (caddr_t *) &twin) == XCNOENT))
2961 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2966 moveFromCenterWrapper(tmp_win);
2967 /* these two - djhjr - 10/4/02 */
2973 /* added this 'if (...) else' - djhjr - 9/15/99 */
2974 if (context == C_ICONMGR && tmp_win->list)
2976 /* added the second argument - djhjr - 5/28/00 */
2977 if (!warp_if_warpunmapped(tmp_win, F_NOFUNCTION))
2979 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
2983 moveFromCenterWrapper(tmp_win); /* djhjr - 10/11/01 */
2984 /* these two - djhjr - 10/4/02 */
2990 if (context == C_ICON && tmp_win->icon_w)
2992 DragX = eventp->xbutton.x;
2993 DragY = eventp->xbutton.y;
2995 w = tmp_win->icon_w;
2998 else if (w != tmp_win->icon_w)
3000 XTranslateCoordinates(dpy, w, tmp_win->frame,
3003 &DragX, &DragY, &JunkChild);
3008 XMapRaised (dpy, Scr->SizeWindow);
3012 MoveFunction = func; /* set for DispatchEvent() */
3014 XGetGeometry(dpy, w, &JunkRoot, &origDragX, &origDragY,
3015 (unsigned int *)&DragWidth,
3016 (unsigned int *)&DragHeight,
3017 &JunkBW, &JunkDepth);
3019 /* added this 'if (...) else' - djhjr - 10/4/02 */
3020 if (menuFromFrameOrWindowOrTitlebar ||
3021 movefromcenter || (moving_icon && fromMenu))
3023 origX = DragX = origDragX + DragWidth / 2;
3024 origY = DragY = origDragY + DragHeight / 2;
3028 origX = eventp->xbutton.x_root;
3029 origY = eventp->xbutton.y_root;
3032 CurrentDragX = origDragX;
3033 CurrentDragY = origDragY;
3036 * Only do the constrained move if timer is set -
3037 * need to check it in case of stupid or wicked fast servers.
3039 if ( ConstrainedMoveTime &&
3040 eventp->xbutton.time - last_time < ConstrainedMoveTime)
3045 constMoveDir = MOVE_NONE;
3046 constMoveX = eventp->xbutton.x_root - DragX - JunkBW;
3047 constMoveY = eventp->xbutton.y_root - DragY - JunkBW;
3048 width = DragWidth + 2 * JunkBW;
3049 height = DragHeight + 2 * JunkBW;
3050 constMoveXL = constMoveX + width/3;
3051 constMoveXR = constMoveX + 2*(width/3);
3052 constMoveYT = constMoveY + height/3;
3053 constMoveYB = constMoveY + 2*(height/3);
3055 XWarpPointer(dpy, None, w,
3056 0, 0, 0, 0, DragWidth/2, DragHeight/2);
3058 XQueryPointer(dpy, w, &JunkRoot, &JunkChild,
3059 &JunkX, &JunkY, &DragX, &DragY, &JunkMask);
3061 last_time = eventp->xbutton.time;
3064 if (!Scr->OpaqueMove)
3066 if (!tmp_win->opaque_move)
3068 InstallRootColormap();
3069 /*if (!Scr->MoveDelta)*/ /* djhjr - 10/2/02 */
3072 * Draw initial outline. This was previously done the
3073 * first time though the outer loop by dropping out of
3074 * the XCheckMaskEvent inner loop down to one of the
3075 * MoveOutline's below.
3078 origDragX - JunkBW, origDragY - JunkBW,
3079 DragWidth + 2 * JunkBW, DragHeight + 2 * JunkBW,
3082 moving_icon ? 0 : tmp_win->title_height);
3084 moving_icon ? 0 : tmp_win->title_height + tmp_win->frame_bw3D);
3087 * This next line causes HandleButtonRelease to call
3088 * XRaiseWindow(). This is solely to preserve the
3089 * previous behaviour that raises a window being moved
3090 * on button release even if you never actually moved
3091 * any distance (unless you move less than MoveDelta or
3092 * NoRaiseMove is set or OpaqueMove is set).
3094 * It's set way down below; no need to force it here.
3097 * The code referred to above is 'if 0'd out now anyway.
3105 * see if this is being done from the titlebar
3107 fromtitlebar = belongs_to_twm_window(tmp_win,
3108 eventp->xbutton.window);
3110 /* added 'movefromcenter' and 'moving_icon' - djhjr - 10/4/02 */
3111 if ((menuFromFrameOrWindowOrTitlebar && !fromtitlebar) ||
3112 movefromcenter || (moving_icon && fromMenu))
3114 /* warp the pointer to the middle of the window */
3115 XWarpPointer(dpy, None, Scr->Root, 0, 0, 0, 0,
3116 origDragX + DragWidth / 2,
3117 origDragY + DragHeight / 2);
3119 SetBorder(tmp_win, True); /* grr */
3124 /* djhjr - 4/27/96 */
3125 DisplayPosition(CurrentDragX, CurrentDragY);
3127 if (menuFromFrameOrWindowOrTitlebar)
3129 releaseEvent = ButtonPress;
3130 movementMask = PointerMotionMask;
3134 releaseEvent = ButtonRelease;
3135 movementMask = ButtonMotionMask;
3140 /* block until there is an interesting event */
3141 XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask |
3142 EnterWindowMask | LeaveWindowMask |
3143 ExposureMask | VisibilityChangeMask |
3144 movementMask, &Event);
3147 * See down below, after this loop - djhjr - 5/23/03
3150 /* throw away enter and leave events until release */
3151 if (Event.xany.type == EnterNotify ||
3152 Event.xany.type == LeaveNotify)
3159 * Don't discard exposure events before release
3160 * or window borders and/or their titles in the
3161 * virtual desktop won't get redrawn - djhjr
3164 /* discard any extra motion events before a release */
3165 if (Event.type == MotionNotify)
3167 while (XCheckMaskEvent(dpy, movementMask | releaseEvent,
3170 if (Event.type == releaseEvent)
3176 * There used to be a couple of routines that handled the
3177 * cancel functionality here, each doing a portion of the
3178 * job, then returning immediately. They became redundant
3179 * to just letting program execution fall through. So now,
3180 * the 'if (Event.type == releaseEvent) if (Cancel)' below
3181 * does just that, clearing a few flags first.
3185 if (fromtitlebar && Event.type == ButtonPress)
3187 fromtitlebar = False;
3188 CurrentDragX = origX = Event.xbutton.x_root;
3189 CurrentDragY = origY = Event.xbutton.y_root;
3190 XTranslateCoordinates(dpy, rootw, tmp_win->frame,
3192 &DragX, &DragY, &JunkChild);
3197 /* DispatchEvent2() is depreciated - djhjr - 10/6/02 */
3198 if (!DispatchEvent()) continue;
3200 /* re-wrote this stuff - djhjr - 10/4/02 5/24/03 11/2/03 */
3201 if (Event.type == releaseEvent)
3203 MoveOutline(rootw, 0, 0, 0, 0, 0, 0);
3208 ConstMove = WindowMoved = do_next_action = FALSE;
3210 else if (WindowMoved)
3214 tmp_win->icon_moved = TRUE;
3215 XMoveWindow(dpy, tmp_win->icon_w,
3216 CurrentDragX, CurrentDragY);
3218 if (!Scr->NoRaiseMove && !Scr->RaiseOnStart)
3220 XRaiseWindow(dpy, tmp_win->icon_w);
3221 SetRaiseWindow(tmp_win->icon_w);
3228 tmp_win->frame_x = Event.xbutton.x_root -
3230 tmp_win->frame_y = Event.xbutton.y_root -
3235 tmp_win->frame_x = CurrentDragX;
3236 tmp_win->frame_y = CurrentDragY;
3239 XMoveWindow(dpy, tmp_win->frame,
3240 tmp_win->frame_x, tmp_win->frame_y);
3241 SendConfigureNotify(tmp_win, tmp_win->frame_x,
3244 if (!Scr->NoRaiseMove && !Scr->RaiseOnStart)
3246 XRaiseWindow(dpy, tmp_win->frame);
3247 SetRaiseWindow(tmp_win);
3255 /* something left to do only if the pointer moved */
3256 if (Event.type != MotionNotify) continue;
3258 XQueryPointer(dpy, rootw, &(eventp->xmotion.root), &JunkChild,
3259 &(eventp->xmotion.x_root),
3260 &(eventp->xmotion.y_root),
3261 &JunkX, &JunkY, &JunkMask);
3263 if (DragWindow == None &&
3264 abs(eventp->xmotion.x_root - origX) < Scr->MoveDelta &&
3265 abs(eventp->xmotion.y_root - origY) < Scr->MoveDelta)
3274 if (!Scr->NoRaiseMove && Scr->OpaqueMove)
3277 if (!Scr->NoRaiseMove && tmp_win->opaque_move)
3278 XRaiseWindow(dpy, DragWindow);
3280 /* djhjr - 5/24/03 11/3/03 */
3281 if (!Scr->NoRaiseMove && Scr->RaiseOnStart)
3285 XRaiseWindow(dpy, tmp_win->icon_w);
3286 SetRaiseWindow(tmp_win->icon_w);
3290 XRaiseWindow(dpy, tmp_win->frame);
3291 SetRaiseWindow(tmp_win);
3293 tmp_win->VirtualDesktopDisplayWindow)
3295 tmp_win->VirtualDesktopDisplayWindow);
3301 switch (constMoveDir)
3304 if (eventp->xmotion.x_root < constMoveXL ||
3305 eventp->xmotion.x_root > constMoveXR)
3307 constMoveDir = MOVE_HORIZ;
3309 if (eventp->xmotion.y_root < constMoveYT ||
3310 eventp->xmotion.y_root > constMoveYB)
3312 constMoveDir = MOVE_VERT;
3314 XQueryPointer(dpy, DragWindow, &JunkRoot,
3315 &JunkChild, &JunkX, &JunkY,
3316 &DragX, &DragY, &JunkMask);
3319 constMoveY = eventp->xmotion.y_root - DragY -
3323 constMoveX = eventp->xmotion.x_root - DragX -
3331 else if (DragWindow != None)
3333 /* added 'movefromcenter' and 'moving_icon' - djhjr - 10/4/02 */
3334 if (!menuFromFrameOrWindowOrTitlebar &&
3335 !movefromcenter && !(moving_icon && fromMenu))
3337 xl = eventp->xmotion.x_root - DragX - JunkBW;
3338 yt = eventp->xmotion.y_root - DragY - JunkBW;
3342 xl = eventp->xmotion.x_root - (DragWidth / 2);
3343 yt = eventp->xmotion.y_root - (DragHeight / 2);
3347 if ((ConstMove && constMoveDir != MOVE_NONE) ||
3350 int width = DragWidth + 2 * JunkBW;
3351 int height = DragHeight + 2 * JunkBW;
3353 if (Scr->DontMoveOff && MoveFunction != F_FORCEMOVE)
3359 if (xr > Scr->MyDisplayWidth)
3360 xl = Scr->MyDisplayWidth - width;
3363 if (yb > Scr->MyDisplayHeight)
3364 yt = Scr->MyDisplayHeight - height;
3370 /* djhjr - 6/22/01 10/6/02 */
3371 #ifndef NO_SOUND_SUPPORT
3372 if ((!ConstMove || constMoveDir != MOVE_NONE) &&
3373 did_playsound == FALSE)
3376 did_playsound = TRUE;
3381 if (Scr->OpaqueMove)
3383 if (tmp_win->opaque_move)
3384 XMoveWindow(dpy, DragWindow, xl, yt);
3386 MoveOutline(eventp->xmotion.root, xl, yt,
3387 width, height, tmp_win->frame_bw,
3389 moving_icon ? 0 : tmp_win->title_height);
3391 moving_icon ? 0 : tmp_win->title_height + tmp_win->frame_bw3D);
3394 * move the small representation window
3395 * this knows a bit much about the internals i guess
3396 * XMoveWindow(dpy, tmp_win->VirtualDesktopDisplayWindow, SCALE_D(xl), SCALE_D(yt));
3398 if (Scr->VirtualReceivesMotionEvents)
3400 tmp_win->virtual_frame_x = R_TO_V_X(xl);
3401 tmp_win->virtual_frame_y = R_TO_V_Y(yt);
3403 MoveResizeDesktop(tmp_win, Scr->NoRaiseMove);
3405 MoveResizeDesktop(tmp_win, TRUE);
3408 /* djhjr - 4/27/96 */
3409 DisplayPosition (xl, yt);
3415 if (!Scr->NoGrabServer) XUngrabServer(dpy);
3417 if (!tmp_win->opaque_move) XUngrabServer(dpy);
3419 /* djhjr - 4/27/96 */
3420 XUnmapWindow (dpy, Scr->SizeWindow);
3422 MovedFromKeyPress = False;
3424 if (!tmp_win->opaque_move)
3425 UninstallRootColormap();
3427 /* discard queued enter and leave events - djhjr - 5/23/03 */
3428 while (XCheckMaskEvent(dpy, EnterWindowMask | LeaveWindowMask,
3432 /* from events.c:HandleButtonRelease() - djhjr - 10/6/02 */
3433 if (!Scr->NoRaiseMove)
3435 RaiseStickyAbove(); /* DSE */
3439 /* update virtual coords */
3440 tmp_win->virtual_frame_x = Scr->VirtualDesktopX + tmp_win->frame_x;
3441 tmp_win->virtual_frame_y = Scr->VirtualDesktopY + tmp_win->frame_y;
3443 /* UpdateDesktop() hoses the stacking order - djhjr - 10/6/02 */
3445 MoveResizeDesktop(tmp_win, Scr->NoRaiseMove);
3447 MoveResizeDesktop(tmp_win, Cancel | Scr->NoRaiseMove);
3449 /* djhjr - 10/4/02 10/6/02 */
3450 if (Context == C_VIRTUAL_WIN)
3453 * Mask a bug that calls MoveOutline(zeros) after the
3454 * border has been repainted, leaving artifacts. I think
3455 * I know what the bug is, but I can't seem to fix it.
3457 if (Scr->BorderBevelWidth > 0) PaintBorders(tmp_win, False);
3459 JunkX = tmp_win->virtual_frame_x + tmp_win->frame_width / 2;
3460 JunkY = tmp_win->virtual_frame_y + tmp_win->frame_height / 2;
3461 XWarpPointer(dpy, None, Scr->VirtualDesktopDisplayOuter,
3462 0, 0, 0, 0, SCALE_D(JunkX), SCALE_D(JunkY));
3465 /* djhjr - 6/4/98 */
3466 /* don't re-map if the window is the virtual desktop - djhjr - 2/28/99 */
3467 if (Scr->VirtualReceivesMotionEvents &&
3468 /* !tmp_win->opaque_move && */
3469 tmp_win->w != Scr->VirtualDesktopDisplayOuter)
3471 XUnmapWindow(dpy, Scr->VirtualDesktopDisplay);
3472 XMapWindow(dpy, Scr->VirtualDesktopDisplay);
3475 MoveFunction = F_NOFUNCTION; /* clear for DispatchEvent() */
3477 /* sanity check (also in events.c:HandleButtonRelease()) - djhjr - 10/6/02 */
3489 if ((mroot = FindMenuRoot(action)) == NULL)
3491 fprintf (stderr, "%s: couldn't find function \"%s\"\n",
3492 ProgramName, action);
3497 * Changed this 'if ()' for deferred keyboard events (see also events.c)
3498 * Submitted by Michel Eyckmans
3500 if (NeedToDefer(mroot) && DeferExecution(context, func, Scr->SelectCursor))
3502 if ((cursor = NeedToDefer(mroot)) != None && DeferExecution(context, func, cursor))
3506 for (mitem = mroot->first; mitem != NULL; mitem = mitem->next)
3508 if (!ExecuteFunction (mitem->func, mitem->action, w,
3509 tmp_win, eventp, context, pulldown))
3518 if (DeferExecution(context, func, Scr->SelectCursor))
3521 /* added '|| (...)' - djhjr - 6/3/03 */
3522 if (tmp_win->icon ||
3523 (func == F_DEICONIFY && tmp_win == tmp_win->list->twm))
3525 /* djhjr - 6/3/03 */
3526 #ifndef NO_SOUND_SUPPORT
3533 * now HERE's a fine bit of kludge! it's to mask a hole in the
3534 * code I can't find that messes up when trying to warp to the
3535 * de-iconified window not in the real screen when WarpWindows
3536 * isn't used. see also the change in DeIconify().
3539 if (!Scr->WarpWindows && (Scr->WarpCursor ||
3540 LookInList(Scr->WarpCursorL, tmp_win->full_name, &tmp_win->class)))
3542 RaiseStickyAbove(); /* DSE */
3545 WarpToWindow(tmp_win); /* PF */
3548 else if (func == F_ICONIFY)
3550 /* djhjr - 9/10/99 */
3552 TwmWindow *tmgr = NULL, *twin = NULL;
3555 /* sanity check for what's next - djhjr - 9/10/99 */
3556 if (XFindContext(dpy, tmp_win->w, DoorContext,
3557 (caddr_t *)&d) != XCNOENT)
3564 * don't iconify if there's no way to get it back - not fool-proof
3567 if (tmp_win->iconify_by_unmapping)
3569 /* iconified by unmapping */
3571 if (tmp_win->list) tmgr = tmp_win->list->iconmgr->twm_win;
3573 if ((tmgr && !tmgr->mapped && tmgr->iconify_by_unmapping) ||
3574 ((Scr->IconManagerDontShow ||
3575 LookInList(Scr->IconMgrNoShow, tmp_win->full_name, &tmp_win->class)) &&
3576 LookInList(Scr->IconMgrShow, tmp_win->full_name, &tmp_win->class) == (char *)NULL))
3578 /* icon manager not mapped or not shown in one */
3580 if (have_twmwindows == -1)
3582 have_twmwindows = 0;
3584 /* better than two calls to FindMenuRoot() */
3585 for (mr = Scr->MenuList; mr != NULL; mr = mr->next)
3586 if (strcmp(mr->name, TWM_WINDOWS) == 0 ||
3587 strcmp(mr->name, VTWM_WINDOWS) == 0)
3589 /* djhjr - 9/21/99 */
3590 have_twmwindows = FindMenuOrFuncInBindings(C_ALL_BITS, mr, F_NOFUNCTION);
3594 /* djhjr - 9/21/99 */
3595 if (have_showdesktop == -1)
3596 have_showdesktop = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWDESKTOP);
3597 if (have_showlist == -1)
3598 have_showlist = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWLIST);
3600 /* djhjr - 9/21/99 */
3601 if (!FindMenuOrFuncInWindows(tmp_win, have_twmwindows, mr, F_NOFUNCTION) ||
3602 LookInList(Scr->DontShowInTWMWindows, tmp_win->full_name, &tmp_win->class))
3604 /* no TwmWindows menu or not shown in it */
3606 if (tmp_win->w == Scr->VirtualDesktopDisplayOuter &&
3607 FindMenuOrFuncInWindows(tmp_win, have_showdesktop, NULL, F_SHOWDESKTOP))
3609 else if (tmp_win->iconmgr &&
3610 FindMenuOrFuncInWindows(tmp_win, have_showlist, NULL, F_SHOWLIST))
3613 FindMenuOrFuncInWindows(tmgr, have_showlist, NULL, F_SHOWLIST))
3617 /* no f.showdesktop or f.showiconmgr */
3619 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3621 if (twin) tmp_win = twin;
3628 if (twin) tmp_win = twin;
3630 if (tmp_win->list || !Scr->NoIconifyIconManagers) /* PF */
3632 /* djhjr - 6/3/03 */
3633 #ifndef NO_SOUND_SUPPORT
3637 Iconify (tmp_win, eventp->xbutton.x_root - EDGE_OFFSET, /* DSE */
3638 eventp->xbutton.y_root - EDGE_OFFSET); /* DSE */
3644 if (DeferExecution(context, func, Scr->SelectCursor))
3650 xwc.stack_mode = Opposite;
3651 if (w != tmp_win->icon_w)
3653 XConfigureWindow (dpy, w, CWStackMode, &xwc);
3654 XConfigureWindow (dpy, tmp_win->VirtualDesktopDisplayWindow, CWStackMode, &xwc);
3656 XLowerWindow(dpy, Scr->VirtualDesktopDScreen);
3661 if (DeferExecution(context, func, Scr->SelectCursor))
3664 /* check to make sure raise is not from the WindowFunction */
3665 if (w == tmp_win->icon_w && Context != C_ROOT)
3666 XRaiseWindow(dpy, tmp_win->icon_w);
3669 XRaiseWindow(dpy, tmp_win->frame);
3670 XRaiseWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
3673 RaiseStickyAbove(); /* DSE */
3679 if (DeferExecution(context, func, Scr->SelectCursor))
3682 if (!(Scr->StickyAbove && tmp_win->nailed)) { /* DSE */
3683 if (w == tmp_win->icon_w)
3684 XLowerWindow(dpy, tmp_win->icon_w);
3686 { XLowerWindow(dpy, tmp_win->frame);
3687 XLowerWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
3688 XLowerWindow(dpy, Scr->VirtualDesktopDScreen);
3695 if (DeferExecution(context, func, Scr->SelectCursor))
3698 if (tmp_win->icon == FALSE)
3700 if (!Scr->FocusRoot && Scr->Focus == tmp_win)
3706 if (Scr->Focus != NULL) {
3707 SetBorder (Scr->Focus, False);
3710 if (Scr->Focus->hilite_w)
3711 XUnmapWindow (dpy, Scr->Focus->hilite_w);
3713 PaintTitleHighlight(Scr->Focus, off);
3717 InstallWindowColormaps (0, tmp_win);
3720 if (tmp_win->hilite_w) XMapWindow (dpy, tmp_win->hilite_w);
3722 PaintTitleHighlight(tmp_win, on);
3724 SetBorder (tmp_win, True);
3725 SetFocus (tmp_win, eventp->xbutton.time);
3726 Scr->FocusRoot = FALSE;
3727 Scr->Focus = tmp_win;
3733 if (DeferExecution(context, func, Scr->DestroyCursor))
3736 /* djhjr - 6/22/01 */
3737 #ifndef NO_SOUND_SUPPORT
3738 /* flag for the handler */
3739 if (PlaySound(func)) destroySoundFromFunction = TRUE;
3742 /* djhjr - 9/10/96 */
3743 if (tmp_win == Scr->VirtualDesktopDisplayTwin)
3745 /* added this 'if (...) ...' and 'if (...) else' - djhjr - 9/21/99 */
3746 if (have_showdesktop == -1)
3747 have_showdesktop = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWDESKTOP);
3748 if (FindMenuOrFuncInWindows(tmp_win, have_showdesktop, NULL, F_SHOWDESKTOP))
3749 XUnmapWindow(dpy, Scr->VirtualDesktopDisplayTwin->frame);
3752 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3759 if (XFindContext(dpy, tmp_win->w, DoorContext,
3760 (caddr_t *) &d) != XCNOENT)
3765 /* for some reason, we don't get the button up event - djhjr - 9/10/99 */
3767 door_delete(tmp_win->w, d);
3773 if (tmp_win->iconmgr) /* don't send ourself a message */
3775 /* added this 'if (...) ...' and 'if (...) else ...' - djhjr - 9/21/99 */
3776 if (have_showlist == -1)
3777 have_showlist = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWLIST);
3778 if (FindMenuOrFuncInWindows(tmp_win, have_showlist, NULL, F_SHOWLIST))
3780 /* added argument - djhjr - 9/21/99 */
3781 HideIconManager(tmp_win);
3784 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3788 /* djhjr - 4/26/99 */
3789 AppletDown(tmp_win);
3791 XKillClient(dpy, tmp_win->w);
3796 if (DeferExecution(context, func, Scr->DestroyCursor))
3799 /* djhjr - 6/22/01 */
3800 #ifndef NO_SOUND_SUPPORT
3801 /* flag for the handler */
3802 if (PlaySound(func)) destroySoundFromFunction = TRUE;
3805 /* djhjr - 9/21/99 */
3806 if (tmp_win == Scr->VirtualDesktopDisplayTwin)
3808 if (have_showdesktop == -1)
3809 have_showdesktop = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWDESKTOP);
3810 if (FindMenuOrFuncInWindows(tmp_win, have_showdesktop, NULL, F_SHOWDESKTOP))
3811 XUnmapWindow(dpy, Scr->VirtualDesktopDisplayTwin->frame);
3813 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3818 /* djhjr - 9/10/99 */
3822 if (XFindContext(dpy, tmp_win->w, DoorContext,
3823 (caddr_t *) &d) != XCNOENT)
3825 /* for some reason, we don't get the button up event - djhjr - 9/10/99 */
3827 door_delete(tmp_win->w, d);
3833 if (tmp_win->iconmgr) /* don't send ourself a message */
3835 /* added this 'if (...) ...' and 'if (...) else ...' - djhjr - 9/21/99 */
3836 if (have_showlist == -1)
3837 have_showlist = FindMenuOrFuncInBindings(C_ALL_BITS, NULL, F_SHOWLIST);
3838 if (FindMenuOrFuncInWindows(tmp_win, have_showlist, NULL, F_SHOWLIST))
3840 /* added argument - djhjr - 9/21/99 */
3841 HideIconManager(tmp_win);
3844 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3846 else if (tmp_win->protocols & DoesWmDeleteWindow)
3848 /* djhjr - 4/26/99 */
3849 AppletDown(tmp_win);
3851 SendDeleteWindowMessage (tmp_win, LastTimestamp());
3854 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3857 case F_SAVEYOURSELF:
3858 if (DeferExecution (context, func, Scr->SelectCursor))
3861 if (tmp_win->protocols & DoesWmSaveYourself)
3862 SendSaveYourselfMessage (tmp_win, LastTimestamp());
3864 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3868 XCirculateSubwindowsUp(dpy, Scr->Root);
3872 XCirculateSubwindowsDown(dpy, Scr->Root);
3877 if (!Scr->NoGrabServer) {
3878 XUngrabServer (dpy);
3882 /* djhjr - 6/22/01 */
3883 #ifndef NO_SOUND_SUPPORT
3884 /* flag for the handler */
3885 if (PlaySound(func)) createSoundFromFunction = TRUE;
3896 strcpy(tmp, action);
3898 XStoreBytes(dpy, tmp, strlen(tmp));
3902 ptr = XFetchBytes(dpy, &count);
3904 if (sscanf (ptr, "%s", tmp) == 1) {
3906 ptr = ExpandFilename(tmp);
3910 count = read (fd, buff, MAX_FILE_SIZE - 1);
3911 if (count > 0) XStoreBytes (dpy, buff, count);
3915 "%s: unable to open cut file \"%s\"\n",
3918 if (ptr != tmp) free (ptr);
3924 fprintf(stderr, "%s: cut buffer is empty\n", ProgramName);
3928 case F_WARPTOSCREEN:
3930 if (strcmp (action, WARPSCREEN_NEXT) == 0) {
3931 WarpToScreen (Scr->screen + 1, 1);
3932 } else if (strcmp (action, WARPSCREEN_PREV) == 0) {
3933 WarpToScreen (Scr->screen - 1, -1);
3934 } else if (strcmp (action, WARPSCREEN_BACK) == 0) {
3935 WarpToScreen (PreviousScreen, 0);
3937 WarpToScreen (atoi (action), 0);
3944 if (strcmp (action, COLORMAP_NEXT) == 0) {
3945 BumpWindowColormap (tmp_win, 1);
3946 } else if (strcmp (action, COLORMAP_PREV) == 0) {
3947 BumpWindowColormap (tmp_win, -1);
3949 BumpWindowColormap (tmp_win, 0);
3954 case F_WARPCLASSNEXT: /* PF */
3955 case F_WARPCLASSPREV: /* PF */
3956 WarpClass(func == F_WARPCLASSNEXT, tmp_win, action);
3959 case F_WARPTONEWEST: /* PF */
3960 /* added '&& warp_if_warpunmapped()' - djhjr - 5/13/98 */
3961 /* added the second argument - djhjr - 5/28/00 */
3962 if (Scr->Newest && warp_if_warpunmapped(Scr->Newest, F_NOFUNCTION))
3967 /* djhjr - 6/3/03 */
3968 #ifndef NO_SOUND_SUPPORT
3972 WarpToWindow(Scr->Newest);
3975 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
3980 register TwmWindow *t;
3981 /* djhjr - 6/3/03 */
3982 int did_warpto = FALSE;
3984 for (t = Scr->TwmRoot.next; t != NULL; t = t->next)
3987 * This used to fall through into F_WARP, but the
3988 * warp_if_warpunmapped() meant this loop couldn't
3989 * continue to look for a match in the window list.
3994 if (MatchWinName(action, t) == 0 &&
3995 warp_if_warpunmapped(t, func))
3997 tmp_win = t; /* PF */
3998 RaiseStickyAbove(); /* DSE */
4001 /* djhjr - 6/3/03 */
4002 #ifndef NO_SOUND_SUPPORT
4007 WarpToWindow(tmp_win); /* PF */
4012 /* djhjr - 6/3/03 */
4018 case F_WARP: /* PF */
4020 /* added '&& warp_if_warpunmapped()' - djhjr - 5/13/98 */
4021 /* added the second argument - djhjr - 5/28/00 */
4022 if (tmp_win && warp_if_warpunmapped(tmp_win, F_NOFUNCTION)) /* PF */
4024 RaiseStickyAbove(); /* DSE */
4027 /* djhjr - 6/3/03 */
4028 #ifndef NO_SOUND_SUPPORT
4032 WarpToWindow(tmp_win); /* PF */
4034 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4039 case F_WARPTOICONMGR:
4045 Window raisewin = None, iconwin = None;
4048 * raisewin now points to the window's icon manager entry, and
4049 * iconwin now points to raisewin's icon manager - djhjr - 5/30/00
4051 TwmWindow *raisewin = None;
4052 Window iconwin = None;
4054 WList *raisewin = NULL;
4055 TwmWindow *iconwin = None;
4057 len = strlen(action);
4059 if (tmp_win && tmp_win->list) {
4061 raisewin = tmp_win->list->iconmgr->twm_win->frame;
4064 raisewin = tmp_win->list->iconmgr->twm_win;
4065 iconwin = tmp_win->list->icon;
4067 raisewin = tmp_win->list;
4068 } else if (Scr->iconmgr.active) {
4070 raisewin = Scr->iconmgr.twm_win->frame;
4073 raisewin = Scr->iconmgr.twm_win;
4074 iconwin = Scr->iconmgr.active->w;
4076 raisewin = Scr->iconmgr.active;
4079 for (t = Scr->TwmRoot.next; t != NULL; t = t->next) {
4080 if (strncmp (action, t->icon_name, len) == 0) {
4081 if (t->list && t->list->iconmgr->twm_win->mapped) {
4084 raisewin = t->list->iconmgr->twm_win->frame;
4087 raisewin = t->list->iconmgr->twm_win;
4088 iconwin = t->list->icon;
4097 /* djhjr - 6/14/00 */
4100 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4104 /* djhjr - 5/30/00 */
4105 iconwin = raisewin->iconmgr->twm_win;
4107 /* added '&& warp_if_warpunmapped()' - djhjr - 5/13/98 */
4108 /* added the second argument - djhjr - 5/28/00 */
4109 /* was 'raisewin' - djhjr - 5/30/00 */
4110 if (iconwin && warp_if_warpunmapped(iconwin, F_NOFUNCTION)) {
4111 /* djhjr - 6/3/03 */
4112 #ifndef NO_SOUND_SUPPORT
4117 XWarpPointer (dpy, None, iconwin, 0, 0, 0, 0,
4118 EDGE_OFFSET, EDGE_OFFSET); * DSE *
4120 WarpInIconMgr(raisewin, iconwin);
4122 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4127 case F_SQUEEZELEFT:/*RFB*/
4129 static SqueezeInfo left_squeeze = { J_LEFT, 0, 0 };
4131 /* too much dup'd code - djhjr - 9/17/02 */
4132 if (do_squeezetitle(context, func, tmp_win, &left_squeeze))
4133 return TRUE; /* deferred */
4137 case F_SQUEEZERIGHT:/*RFB*/
4139 static SqueezeInfo right_squeeze = { J_RIGHT, 0, 0 };
4141 /* too much dup'd code - djhjr - 9/17/02 */
4142 if (do_squeezetitle(context, func, tmp_win, &right_squeeze))
4143 return TRUE; /* deferred */
4147 case F_SQUEEZECENTER:/*RFB*/
4149 static SqueezeInfo center_squeeze = { J_CENTER, 0, 0 };
4151 /* too much dup'd code - djhjr - 9/17/02 */
4152 if (do_squeezetitle(context, func, tmp_win, ¢er_squeeze))
4153 return TRUE; /* deferred */
4158 if (DeferExecution (context, func, Scr->SelectCursor))
4160 if ( tmp_win->ring.next || tmp_win->ring.prev )
4161 RemoveWindowFromRing(tmp_win);
4163 AddWindowToRing(tmp_win);
4164 #ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */
4165 tmp_win->ring.cursor_valid = False;
4170 switch (action[0]) {
4172 WarpAlongRing (&eventp->xbutton, True);
4175 WarpAlongRing (&eventp->xbutton, False);
4178 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4184 action = ExpandFilename(action);
4185 fd = open(action, 0);
4188 count = read(fd, buff, MAX_FILE_SIZE - 1);
4190 XStoreBytes(dpy, buff, count);
4196 fprintf (stderr, "%s: unable to open file \"%s\"\n",
4197 ProgramName, action);
4203 XSetWindowAttributes attributes;
4204 unsigned long valuemask;
4206 valuemask = (CWBackPixel | CWBackingStore | CWSaveUnder);
4207 attributes.background_pixel = Scr->Black;
4208 attributes.backing_store = NotUseful;
4209 attributes.save_under = False;
4210 w = XCreateWindow (dpy, Scr->Root, 0, 0,
4211 (unsigned int) Scr->MyDisplayWidth,
4212 (unsigned int) Scr->MyDisplayHeight,
4214 CopyFromParent, (unsigned int) CopyFromParent,
4215 (Visual *) CopyFromParent, valuemask,
4217 XMapWindow (dpy, w);
4218 XDestroyWindow (dpy, w);
4224 if (DeferExecution(context, func, Scr->SelectCursor))
4227 if (context == C_ICON && tmp_win->icon_w)
4228 w = XCreateSimpleWindow(dpy, tmp_win->icon_w,
4229 0, 0, 9999, 9999, 0, Scr->Black, Scr->Black);
4231 w = XCreateSimpleWindow(dpy, tmp_win->frame,
4232 0, 0, 9999, 9999, 0, Scr->Black, Scr->Black);
4235 XDestroyWindow(dpy, w);
4240 if (DeferExecution(context, func, Scr->SelectCursor))
4243 tmp_win->nailed = !tmp_win->nailed;
4244 /* update the vd display */
4245 /* UpdateDesktop(tmp_win); Stig */
4246 NailDesktop(tmp_win); /* Stig */
4249 fprintf(stdout, "%s: nail state of %s is now %s\n",
4250 ProgramName, tmp_win->name, (tmp_win->nailed ? "nailed" : "free"));
4253 RaiseStickyAbove(); /* DSE */
4254 RaiseAutoPan(); /* DSE */
4259 * move a percentage in a particular direction
4262 PanRealScreen(0, (atoi(action) * Scr->MyDisplayHeight) / 100
4263 /* DSE */ ,NULL,NULL);
4266 PanRealScreen(-((atoi(action) * Scr->MyDisplayWidth) / 100), 0
4267 /* DSE */ ,NULL,NULL);
4270 PanRealScreen((atoi(action) * Scr->MyDisplayWidth) / 100, 0
4271 /* DSE */ ,NULL,NULL);
4274 PanRealScreen(0, -((atoi(action) * Scr->MyDisplayHeight) / 100)
4275 /* DSE */ ,NULL,NULL);
4278 case F_RESETDESKTOP:
4279 SetRealScreen(0, 0);
4282 /*SNUG*/ /* Robert Forsman added these two functions <thoth@ufl.edu> */
4284 /*SNUG*/ TwmWindow *scan;
4285 /*SNUG*/ int right, left, up, down;
4286 /*SNUG*/ int inited;
4287 /*SNUG*/ case F_SNUGDESKTOP:
4289 /*SNUG*/ inited = 0;
4290 /*SNUG*/ for (scan = Scr->TwmRoot.next; scan!=NULL; scan = scan->next)
4292 /*SNUG*/ if (scan->nailed)
4294 /*SNUG*/ if (scan->frame_x > Scr->MyDisplayWidth ||
4295 /*SNUG*/ scan->frame_y > Scr->MyDisplayHeight)
4297 /*SNUG*/ if (scan->frame_x+scan->frame_width < 0 ||
4298 /*SNUG*/ scan->frame_y+scan->frame_height < 0)
4300 /*SNUG*/ if ( inited==0 || scan->frame_x<right )
4301 /*SNUG*/ right = scan->frame_x;
4302 /*SNUG*/ if ( inited==0 || scan->frame_y<up )
4303 /*SNUG*/ up = scan->frame_y;
4304 /*SNUG*/ if ( inited==0 || scan->frame_x+scan->frame_width>left )
4305 /*SNUG*/ left = scan->frame_x+scan->frame_width;
4306 /*SNUG*/ if ( inited==0 || scan->frame_y+scan->frame_height>down )
4307 /*SNUG*/ down = scan->frame_y+scan->frame_height;
4308 /*SNUG*/ inited = 1;
4310 /*SNUG*/ if (inited)
4313 /*SNUG*/ if (left-right < Scr->MyDisplayWidth && (right<0 || left>Scr->MyDisplayWidth) )
4314 /*SNUG*/ dx = right - ( Scr->MyDisplayWidth - (left-right) ) /2;
4317 /*SNUG*/ if (down-up < Scr->MyDisplayHeight && (up<0 || down>Scr->MyDisplayHeight) )
4318 /*SNUG*/ dy = up - (Scr->MyDisplayHeight - (down-up) ) /2;
4321 /*SNUG*/ if (dx!=0 || dy!=0)
4322 /*SNUG*/ PanRealScreen(dx,dy,NULL,NULL);
4325 /*SNUG*/ DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4328 /*SNUG*/ DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4331 /*SNUG*/ case F_SNUGWINDOW:
4332 /*SNUG*/ if (DeferExecution(context, func, Scr->SelectCursor))
4333 /*SNUG*/ return TRUE;
4335 /*SNUG*/ inited = 0;
4336 /*SNUG*/ right = tmp_win->frame_x;
4337 /*SNUG*/ left = tmp_win->frame_x + tmp_win->frame_width;
4338 /*SNUG*/ up = tmp_win->frame_y;
4339 /*SNUG*/ down = tmp_win->frame_y + tmp_win->frame_height;
4340 /*SNUG*/ inited = 1;
4341 /*SNUG*/ if (inited)
4345 /*SNUG*/ if (left-right < Scr->MyDisplayWidth)
4347 /*SNUG*/ if (right<0)
4348 /*SNUG*/ dx = right;
4349 /*SNUG*/ else if (left>Scr->MyDisplayWidth)
4350 /*SNUG*/ dx = left - Scr->MyDisplayWidth;
4354 /*SNUG*/ if (down-up < Scr->MyDisplayHeight)
4358 /*SNUG*/ else if (down>Scr->MyDisplayHeight)
4359 /*SNUG*/ dy = down - Scr->MyDisplayHeight;
4362 /*SNUG*/ if (dx!=0 || dy!=0)
4363 /*SNUG*/ PanRealScreen(dx,dy,NULL,NULL);
4366 /*SNUG*/ DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4369 /*SNUG*/ DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
4374 /* Next four submitted by Seth Robertson - 9/9/02 */
4379 if (DeferExecution(context, func, Scr->SelectCursor))
4381 for (i = 0; i < MAX_BUTTONS+1; i++)
4382 for (j = 0; j < MOD_SIZE; j++)
4383 if (Scr->Mouse[i][C_WINDOW][j].func != F_NOFUNCTION)
4384 XGrabButton(dpy, i, j, tmp_win->frame,
4385 True, ButtonPressMask | ButtonReleaseMask,
4386 GrabModeAsync, GrabModeAsync, None,
4394 if (DeferExecution(context, func, Scr->SelectCursor))
4396 for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next)
4397 if (tmp->cont == C_WINDOW)
4399 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->w, True,
4400 GrabModeAsync, GrabModeAsync);
4402 GrabModKeys(tmp_win->w, tmp);
4405 case F_UNBINDBUTTONS:
4409 if (DeferExecution(context, func, Scr->SelectCursor))
4411 for (i = 0; i < MAX_BUTTONS+1; i++)
4412 for (j = 0; j < MOD_SIZE; j++)
4413 if (Scr->Mouse[i][C_WINDOW][j].func != F_NOFUNCTION)
4414 XUngrabButton(dpy, i, j, tmp_win->frame);
4421 if (DeferExecution(context, func, Scr->SelectCursor))
4423 for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next)
4424 if (tmp->cont == C_WINDOW)
4426 XUngrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->w);
4428 UngrabModKeys(tmp_win->w, tmp);
4435 * Breaks badly if not called by the default button press.
4439 long releaseEvent = ButtonRelease;
4440 long movementMask = ButtonMotionMask;
4441 #ifndef NO_SOUND_SUPPORT
4442 int did_playsound = FALSE;
4445 StartMoveWindowInDesktop(eventp->xmotion);
4449 /* added exposure event masks - djhjr - 10/11/01 */
4450 XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask |
4451 EnterWindowMask | LeaveWindowMask |
4452 ExposureMask | VisibilityChangeMask |
4453 movementMask, &Event);
4456 * Don't discard exposure events before release
4457 * or window borders and/or their titles in the
4458 * virtual desktop won't get redrawn - djhjr
4461 /* discard any extra motion events before a release */
4462 if (Event.type == MotionNotify)
4464 /* was 'ButtonMotionMask' - djhjr - 10/11/01 */
4465 while (XCheckMaskEvent(dpy, releaseEvent | movementMask,
4468 if (Event.type == releaseEvent)
4473 if (Event.type == releaseEvent)
4475 EndMoveWindowOnDesktop();
4479 if (!DispatchEvent()) continue;
4481 if (Event.type != MotionNotify) continue;
4483 #ifndef NO_SOUND_SUPPORT
4484 if (did_playsound == FALSE)
4487 did_playsound = TRUE;
4491 DoMoveWindowOnDesktop(Event.xmotion.x, Event.xmotion.y);
4494 /* discard queued enter and leave events */
4495 while (XCheckMaskEvent(dpy, EnterWindowMask | LeaveWindowMask,
4499 /* will clear the XGrabPointer() in events.c:HandleButtonPress() */
4507 /* and update the data structures */
4508 SetRealScreen(Scr->VirtualDesktopX, Scr->VirtualDesktopY);
4511 case F_SNAPREALSCREEN:
4512 Scr->snapRealScreen = ! Scr->snapRealScreen;
4515 /* djhjr - 12/14/98 */
4516 case F_STATICICONPOSITIONS:
4517 Scr->StaticIconPositions = ! Scr->StaticIconPositions;
4520 /* djhjr - 12/14/98 */
4521 case F_STRICTICONMGR:
4525 Scr->StrictIconManager = ! Scr->StrictIconManager;
4526 if (Scr->StrictIconManager)
4528 for (t = Scr->TwmRoot.next; t != NULL; t = t->next)
4530 RemoveIconManager(t);
4534 for (t = Scr->TwmRoot.next; t != NULL; t = t->next)
4542 case F_SETREALSCREEN:
4544 int newx = Scr->VirtualDesktopX;
4545 int newy = Scr->VirtualDesktopY;
4547 /* parse the geometry */
4548 JunkMask = XParseGeometry (action, &JunkX, &JunkY, &JunkWidth, &JunkHeight);
4550 if (JunkMask & XValue)
4552 if (JunkMask & YValue)
4556 newx = Scr->VirtualDesktopWidth + newx;
4558 newy = Scr->VirtualDesktopHeight + newy;
4560 SetRealScreen(newx, newy);
4567 XUnmapWindow(dpy, Scr->VirtualDesktopDisplayTwin->frame);
4572 XMapWindow(dpy, Scr->VirtualDesktopDisplayTwin->frame);
4574 /* djhjr - 9/14/96 */
4575 if (Scr->VirtualDesktopDisplayTwin->icon)
4576 DeIconify(Scr->VirtualDesktopDisplayTwin);
4584 if (XFindContext(dpy, tmp_win->w, DoorContext,
4585 (caddr_t *) &d) != XCNOENT)
4586 door_enter(tmp_win->w, d);
4591 { /*marcel@duteca.et.tudelft.nl*/
4594 if (DeferExecution(context, func, Scr->DestroyCursor))
4597 /* djhjr - 6/22/01 */
4598 #ifndef NO_SOUND_SUPPORT
4599 /* flag for the handler */
4600 if (PlaySound(func)) destroySoundFromFunction = TRUE;
4603 if (XFindContext(dpy, tmp_win->w, DoorContext,
4604 (caddr_t *) &d) != XCNOENT)
4606 /* for some reason, we don't get the button up event - djhjr - 5/13/99 */
4609 door_delete(tmp_win->w, d);
4619 /* djhjr - 4/20/98 */
4624 if (XFindContext(dpy, tmp_win->w, DoorContext,
4625 (caddr_t *) &d) != XCNOENT)
4626 door_paste_name(tmp_win->w, d);
4631 /* djhjr - 9/14/96 - it's in Done()...
4635 /* djhjr - 6/22/01 */
4636 #ifndef NO_SOUND_SUPPORT
4637 if (PlaySound(func))
4639 /* allow time to emit */
4640 if (Scr->PauseOnQuit) sleep(Scr->PauseOnQuit);
4649 case F_VIRTUALGEOMETRIES:
4650 Scr->GeometriesAreVirtual = ! Scr->GeometriesAreVirtual;
4653 /* submitted by Ugen Antsilevitch - 5/28/00 */
4655 Scr->WarpVisible = ! Scr->WarpVisible;
4658 /* djhjr - 5/30/00 */
4660 Scr->WarpSnug = ! Scr->WarpSnug;
4663 /* djhjr - 6/22/01 */
4664 #ifndef NO_SOUND_SUPPORT
4669 /* djhjr - 11/15/02 */
4671 PlaySoundAdhoc(action);
4676 if (ButtonPressed == -1) XUngrabPointer(dpy, CurrentTime);
4677 return do_next_action;
4682 /***********************************************************************
4685 * DeferExecution - defer the execution of a function to the
4686 * next button press if the context is C_ROOT
4689 * context - the context in which the mouse button was pressed
4690 * func - the function to defer
4691 * cursor - the cursor to display while waiting
4693 ***********************************************************************
4697 DeferExecution(context, func, cursor)
4701 if (context == C_ROOT)
4703 LastCursor = cursor;
4704 XGrabPointer(dpy, Scr->Root, True,
4705 ButtonPressMask | ButtonReleaseMask,
4706 GrabModeAsync, GrabModeAsync,
4707 Scr->Root, cursor, CurrentTime);
4709 RootFunction = func;
4710 Action = actionHack; /* Submitted by Michel Eyckmans */
4720 /***********************************************************************
4723 * ReGrab - regrab the pointer with the LastCursor;
4725 ***********************************************************************
4730 XGrabPointer(dpy, Scr->Root, True,
4731 ButtonPressMask | ButtonReleaseMask,
4732 GrabModeAsync, GrabModeAsync,
4733 Scr->Root, LastCursor, CurrentTime);
4738 /***********************************************************************
4741 * NeedToDefer - checks each function in the list to see if it
4742 * is one that needs to be defered.
4745 * root - the menu root to check
4747 ***********************************************************************
4750 /* was of type 'int' - Submitted by Michel Eyckmans */
4757 for (mitem = root->first; mitem != NULL; mitem = mitem->next)
4759 switch (mitem->func)
4762 return Scr->ResizeCursor; /* Submitted by Michel Eyckmans */
4765 return Scr->MoveCursor; /* Submitted by Michel Eyckmans */
4766 /* these next four - Submitted by Michel Eyckmans */
4770 return Scr->DestroyCursor;
4771 case F_IDENTIFY: /* was with 'F_RESIZE' - Submitted by Michel Eyckmans */
4789 return Scr->SelectCursor;
4801 static char buf[256];
4802 char *ds = DisplayString (dpy);
4804 char oldDisplay[256];
4808 char *append_this = " &";
4809 char *es = (char *)malloc(strlen(s)+strlen(append_this)+1);
4811 /* a new copy of s, with extra space incase -- DSE */
4813 if (Scr->EnhancedExecResources) /* DSE */
4815 /* chop all space characters from the end of the string */
4816 while ( isspace ( es[strlen(es)-1] ) )
4818 es[strlen(es)-1] = '\0';
4820 switch ( es[strlen(es)-1] ) /* last character */
4823 es[strlen(es)-1] = '\0'; /* remove the semicolon */
4825 case '&': /* already there so do nothing */
4828 strcat(es,append_this); /* don't block the window manager */
4833 oldDisplay[0] = '\0';
4834 doisplay=getenv("DISPLAY");
4836 strcpy (oldDisplay, doisplay);
4839 * Build a display string using the current screen number, so that
4840 * X programs which get fired up from a menu come up on the screen
4841 * that they were invoked from, unless specifically overridden on
4842 * their command line.
4844 colon = rindex (ds, ':');
4845 if (colon) { /* if host[:]:dpy */
4846 strcpy (buf, "DISPLAY=");
4848 colon = buf + 8 + (colon - ds); /* use version in buf */
4849 dot1 = index (colon, '.'); /* first period after colon */
4850 if (!dot1) dot1 = colon + strlen (colon); /* if not there, append */
4851 (void) sprintf (dot1, ".%d", Scr->screen);
4856 (void) system (es); /* DSE */
4857 free (es); /* DSE */
4859 if (restorevar) { /* why bother? */
4860 (void) sprintf (buf, "DISPLAY=%s", oldDisplay);
4867 /***********************************************************************
4870 * FocusOnRoot - put input focus on the root window
4872 ***********************************************************************
4878 SetFocus ((TwmWindow *) NULL, LastTimestamp());
4879 if (Scr->Focus != NULL)
4881 SetBorder (Scr->Focus, False);
4884 if (Scr->Focus->hilite_w) XUnmapWindow (dpy, Scr->Focus->hilite_w);
4886 PaintTitleHighlight(Scr->Focus, off);
4889 InstallWindowColormaps(0, &Scr->TwmRoot);
4891 Scr->FocusRoot = TRUE;
4894 void DeIconify(tmp_win)
4900 * De-iconify the main window first
4903 /* re-vamped the zoom stuff - djhjr - 10/11/01 */
4904 if (Scr->DoZoom && Scr->ZoomCount > 0)
4906 IconMgr *ipf = NULL;
4907 Window wt = None, wf = None;
4911 if (tmp_win->icon_on)
4913 wf = tmp_win->icon_w; wt = tmp_win->frame;
4915 else if (tmp_win->list) /* djhjr - 10/11/01 */
4917 wf = tmp_win->list->w; wt = tmp_win->frame;
4918 ipf = tmp_win->list->iconmgr;
4920 else if (tmp_win->group != None)
4922 for (t = Scr->TwmRoot.next; t != NULL; t = t->next)
4923 if (tmp_win->group == t->w)
4927 else if (t->list) /* djhjr - 10/11/01 */
4930 ipf = t->list->iconmgr;
4933 wt = tmp_win->frame;
4939 /* added Zoom()s args to iconmgrs - djhjr - 10/11/01 */
4940 if (Scr->ZoomZoom || (wf != None && wt != None))
4941 Zoom(wf, ipf, wt, NULL); /* RFBZOOM */
4944 XMapWindow(dpy, tmp_win->w);
4945 tmp_win->mapped = TRUE;
4947 if (Scr->NoRaiseDeicon)
4948 XMapWindow(dpy, tmp_win->frame);
4951 XMapRaised(dpy, tmp_win->frame);
4952 XRaiseWindow(dpy, tmp_win->VirtualDesktopDisplayWindow);
4954 SetMapStateProp(tmp_win, NormalState);
4956 if (tmp_win->icon_w) {
4957 XUnmapWindow(dpy, tmp_win->icon_w);
4961 tmp_win->icon = FALSE;
4962 tmp_win->icon_on = FALSE;
4965 XUnmapWindow(dpy, tmp_win->list->icon);
4968 * RemoveIconManager() done in events.c:HandleMapNotify()
4971 UpdateDesktop(tmp_win);
4974 * Now de-iconify transients
4977 for (t = Scr->TwmRoot.next; t != NULL; t = t->next)
4979 if (t->transient && t->transientfor == tmp_win->w)
4981 /* this 'if (...) else' (see also Iconify()) - djhjr - 6/22/99 */
4982 if (Scr->DontDeiconifyTransients && t->icon_w &&
4983 t->icon == TRUE && t->icon_on == FALSE)
4986 XMapRaised(dpy, t->icon_w);
4991 /* added Zoom()s args to iconmgrs - djhjr - 10/11/01 */
4993 Zoom(t->icon_w, NULL, t->frame, NULL);
4995 Zoom(tmp_win->icon_w, NULL, t->frame, NULL);
4997 XMapWindow(dpy, t->w);
5000 if (Scr->NoRaiseDeicon)
5001 XMapWindow(dpy, t->frame);
5004 XMapRaised(dpy, t->frame);
5005 XRaiseWindow(dpy, t->VirtualDesktopDisplayWindow);
5007 SetMapStateProp(t, NormalState);
5011 XUnmapWindow(dpy, t->icon_w);
5018 if (t->list) XUnmapWindow(dpy, t->list->icon);
5021 * RemoveIconManager() done in events.c:HandleMapNotify()
5029 RaiseStickyAbove(); /* DSE */
5033 * added '&& Scr->WarpWindows'.
5034 * see the kludge in ExecuteFunction(F_ICONIFY, ...).
5037 if (((Scr->WarpCursor ||
5038 LookInList(Scr->WarpCursorL, tmp_win->full_name,
5039 &tmp_win->class)) &&
5040 tmp_win->icon) && Scr->WarpWindows)
5041 WarpToWindow (tmp_win);
5048 void Iconify(tmp_win, def_x, def_y)
5054 XWindowAttributes winattrs;
5055 unsigned long eventMask;
5056 /* djhjr - 6/22/99 */
5059 iconify = ((!tmp_win->iconify_by_unmapping) || tmp_win->transient);
5062 if (tmp_win->icon_w == None)
5063 CreateIconWindow(tmp_win, def_x, def_y);
5067 XMapRaised(dpy, tmp_win->icon_w);
5069 RaiseStickyAbove(); /* DSE */
5073 XGetWindowAttributes(dpy, tmp_win->w, &winattrs);
5074 eventMask = winattrs.your_event_mask;
5077 * Iconify transients first
5080 for (t = Scr->TwmRoot.next; t != NULL; t = t->next)
5082 if (t->transient && t->transientfor == tmp_win->w)
5085 /* RemoveFromDesktop(t); Stig */
5088 * Prevent the receipt of an UnmapNotify, since that would
5089 * cause a transition to the Withdrawn state.
5092 XSelectInput(dpy, t->w, eventMask & ~StructureNotifyMask);
5093 XUnmapWindow(dpy, t->w);
5094 XSelectInput(dpy, t->w, eventMask);
5095 XUnmapWindow(dpy, t->frame);
5097 /* moved to make zooms more aesthetically pleasing -- DSE */
5100 /* added Zoom()s args to iconmgrs - djhjr - 10/11/01 */
5102 Zoom(t->icon_w, NULL, tmp_win->icon_w, NULL);
5104 Zoom(t->frame, NULL, tmp_win->icon_w, NULL);
5108 XUnmapWindow(dpy, t->icon_w);
5109 SetMapStateProp(t, IconicState);
5110 SetBorder (t, False);
5111 if (t == Scr->Focus)
5113 SetFocus ((TwmWindow *) NULL, LastTimestamp());
5115 Scr->FocusRoot = TRUE;
5119 * let current status ride, but "fake out" UpdateDesktop()
5120 * (see also DeIconify()) - djhjr - 6/22/99
5122 fake_icon = t->icon;
5127 /* djhjr - 10/2/01 */
5128 if (Scr->StrictIconManager)
5132 if (t->list) XMapWindow(dpy, t->list->icon);
5136 /* restore icon status - djhjr - 6/22/99 */
5137 t->icon = fake_icon;
5142 * Now iconify the main window
5145 /* if (iconify) RFBZOOM*/
5147 /* RemoveFromDesktop(tmp_win); Stig */
5150 * Prevent the receipt of an UnmapNotify, since that would
5151 * cause a transition to the Withdrawn state.
5153 tmp_win->mapped = FALSE;
5154 XSelectInput(dpy, tmp_win->w, eventMask & ~StructureNotifyMask);
5155 XUnmapWindow(dpy, tmp_win->w);
5156 XSelectInput(dpy, tmp_win->w, eventMask);
5157 XUnmapWindow(dpy, tmp_win->frame);
5159 SetMapStateProp(tmp_win, IconicState);
5161 SetBorder (tmp_win, False);
5162 if (tmp_win == Scr->Focus)
5164 SetFocus ((TwmWindow *) NULL, LastTimestamp());
5166 Scr->FocusRoot = TRUE;
5169 tmp_win->icon = TRUE;
5171 tmp_win->icon_on = TRUE;
5173 tmp_win->icon_on = FALSE;
5175 /* djhjr - 10/2/01 */
5176 if (Scr->StrictIconManager)
5178 AddIconManager(tmp_win);
5180 /* moved to make zooms more aesthetically pleasing -- DSE */
5181 /* moved again to ensure an icon manager entry exists - djhjr - 10/11/01 */
5182 /* added Zoom()s args to iconmgrs - djhjr - 10/11/01 */
5184 Zoom(tmp_win->frame, NULL, tmp_win->icon_w, NULL);
5185 else if (tmp_win->list) /* djhjr - 10/11/01 */
5186 Zoom(tmp_win->frame, NULL, tmp_win->list->w, tmp_win->list->iconmgr);
5189 XMapWindow(dpy, tmp_win->list->icon);
5191 UpdateDesktop(tmp_win);
5197 static void Identify (t)
5200 int i, n, twidth, width, height;
5202 unsigned int wwidth, wheight, bw, depth;
5207 /* djhjr - 6/22/01 */
5208 #ifndef NO_SOUND_SUPPORT
5209 PlaySound(F_IDENTIFY);
5213 (void) sprintf(Info[n++], "%s", Version);
5214 Info[n++][0] = '\0';
5217 XGetGeometry (dpy, t->w, &JunkRoot, &JunkX, &JunkY,
5218 &wwidth, &wheight, &bw, &depth);
5219 (void) XTranslateCoordinates (dpy, t->w, Scr->Root, 0, 0,
5222 /* looks bad with variable fonts... djhjr - 5/10/96
5223 (void) sprintf(Info[n++], "Name = \"%s\"", t->full_name);
5224 (void) sprintf(Info[n++], "Class.res_name = \"%s\"", t->class.res_name);
5225 (void) sprintf(Info[n++], "Class.res_class = \"%s\"", t->class.res_class);
5226 Info[n++][0] = '\0';
5227 (void) sprintf(Info[n++], "Geometry/root = %dx%d+%d+%d", wwidth, wheight, x, y);
5228 (void) sprintf(Info[n++], "Border width = %d", bw);
5229 (void) sprintf(Info[n++], "Depth = %d", depth);
5231 (void) sprintf(Info[n++], "Name: \"%s\"", t->full_name);
5232 (void) sprintf(Info[n++], "Class.res_name: \"%s\"", t->class.res_name);
5233 (void) sprintf(Info[n++], "Class.res_class: \"%s\"", t->class.res_class);
5234 Info[n++][0] = '\0';
5235 (void) sprintf(Info[n++], "Geometry/root: %dx%d+%d+%d", wwidth, wheight, x, y);
5236 (void) sprintf(Info[n++], "Border width: %d", bw);
5237 (void) sprintf(Info[n++], "Depth: %d", depth);
5239 Info[n++][0] = '\0';
5241 /* djhjr - 9/19/96 */
5242 #ifndef NO_BUILD_INFO
5246 char is_rplay; /* djhjr - 6/22/01 */
5247 char is_regex; /* djhjr - 10/20/01 */
5248 char is_i18n; /* djhjr - 10/20/01 */
5250 /* djhjr - 6/22/99 */
5251 #ifdef WE_REALLY_DO_WANT_TO_SEE_THIS
5252 (void) sprintf(Info[n++], "X Server: %s Version %d.%d Release %d",
5253 ServerVendor(dpy), ProtocolVersion(dpy), ProtocolRevision(dpy),
5254 VendorRelease(dpy));
5258 * Was a 'do ... while()' that accessed unallocated memory.
5259 * This and the change to Imakefile submitted by Takeharu Kato
5262 while (lastmake[i][0] != '\0')
5263 (void) sprintf(Info[n++], "%s", lastmake[i++]);
5265 /* djhjr - 1/31/99 */
5266 #ifdef NO_M4_SUPPORT
5271 #ifdef NO_XPM_SUPPORT
5276 /* djhjr - 6/22/01 */
5277 #ifdef NO_SOUND_SUPPORT
5282 /* djhjr - 6/22/01 */
5283 #ifdef NO_REGEX_SUPPORT
5288 /* djhjr - 9/14/03 */
5289 #ifdef NO_I18N_SUPPORT
5294 (void) sprintf(Info[n++],
5295 "Options: %ci18n %cm4 %cregex %crplay %cxpm",
5296 is_i18n, is_m4, is_regex, is_rplay, is_xpm);
5298 Info[n++][0] = '\0';
5302 (void) sprintf(Info[n++], "Click to dismiss...");
5304 /* figure out the width and height of the info window */
5307 height = (n * (Scr->InfoFont.height+2)) + 10; * some padding *
5309 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
5310 i = (Scr->InfoBevelWidth > 0) ? Scr->InfoBevelWidth + 8 : 10;
5311 height = (n * (Scr->InfoFont.height+2)) + i; /* some padding */
5314 for (i = 0; i < n; i++)
5316 /* djhjr - 9/14/03 */
5317 #ifndef NO_I18N_SUPPORT
5318 twidth = MyFont_TextWidth(&Scr->InfoFont,
5320 twidth = XTextWidth(Scr->InfoFont.font,
5322 Info[i], strlen(Info[i]));
5326 if (InfoLines) XUnmapWindow(dpy, Scr->InfoWindow);
5329 width += 20; * some padding *
5331 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
5332 i = (Scr->InfoBevelWidth > 0) ? Scr->InfoBevelWidth + 18 : 20;
5333 width += i; /* some padding */
5335 if (XQueryPointer (dpy, Scr->Root, &JunkRoot, &JunkChild, &px, &py,
5336 &dummy, &dummy, &udummy)) {
5340 /* added this 'if ()' - djhjr - 4/29/98 */
5341 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
5342 if (Scr->InfoBevelWidth > 0)
5344 if (px + width + 2 * Scr->InfoBevelWidth >= Scr->MyDisplayWidth)
5345 px = Scr->MyDisplayWidth - width - 2 * Scr->InfoBevelWidth;
5346 if (py + height + 2 * Scr->InfoBevelWidth >= Scr->MyDisplayHeight)
5347 py = Scr->MyDisplayHeight - height - 2 * Scr->InfoBevelWidth;
5351 if (px + width + BW2 >= Scr->MyDisplayWidth)
5352 px = Scr->MyDisplayWidth - width - BW2;
5353 if (py + height + BW2 >= Scr->MyDisplayHeight)
5354 py = Scr->MyDisplayHeight - height - BW2;
5363 XMoveResizeWindow(dpy, Scr->InfoWindow, px, py, width, height);
5365 /* done in HandleExpose() in events.c - djhjr - 4/30/98 */
5367 /* djhjr - 5/9/96 */
5368 if (Scr->use3Dborders > 0)
5370 XGetGeometry (dpy, Scr->InfoWindow, &JunkRoot, &JunkX, &JunkY,
5371 &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth);
5372 Draw3DBorder(Scr->InfoWindow, 0, 0, JunkWidth, JunkHeight,
5374 BW, Scr->DefaultC, off, False, False);
5376 Scr->InfoBevelWidth, Scr->DefaultC, off, False, False);
5380 XMapRaised(dpy, Scr->InfoWindow);
5386 void SetMapStateProp(tmp_win, state)
5390 unsigned long data[2]; /* "suggested" by ICCCM version 1 */
5392 data[0] = (unsigned long) state;
5393 data[1] = (unsigned long) (tmp_win->iconify_by_unmapping ? None :
5396 XChangeProperty (dpy, tmp_win->w, _XA_WM_STATE, _XA_WM_STATE, 32,
5397 PropModeReplace, (unsigned char *) data, 2);
5402 Bool GetWMState (w, statep, iwp)
5409 unsigned long nitems, bytesafter;
5410 unsigned long *datap = NULL;
5411 Bool retval = False;
5413 /* used to test for '!datap' - djhjr - 1/10/98 */
5414 if (XGetWindowProperty (dpy, w, _XA_WM_STATE, 0L, 2L, False, _XA_WM_STATE,
5415 &actual_type, &actual_format, &nitems, &bytesafter,
5416 (unsigned char **) &datap) != Success ||
5417 actual_type == None)
5420 if (nitems <= 2) { /* "suggested" by ICCCM version 1 */
5421 *statep = (int) datap[0];
5422 *iwp = (Window) datap[1];
5426 XFree ((char *) datap);
5433 * BumpWindowColormap - rotate our internal copy of WM_COLORMAP_WINDOWS
5436 void BumpWindowColormap (tmp, inc)
5440 int i, j, previously_installed;
5441 ColormapWindow **cwins;
5445 if (inc && tmp->cmaps.number_cwins > 0) {
5446 cwins = (ColormapWindow **) malloc(sizeof(ColormapWindow *)*
5447 tmp->cmaps.number_cwins);
5449 if ((previously_installed =
5450 (Scr->cmapInfo.cmaps == &tmp->cmaps) &&
5451 tmp->cmaps.number_cwins)) {
5452 for (i = tmp->cmaps.number_cwins; i-- > 0; )
5453 tmp->cmaps.cwins[i]->colormap->state = 0;
5456 for (i = 0; i < tmp->cmaps.number_cwins; i++) {
5458 if (j >= tmp->cmaps.number_cwins)
5459 j -= tmp->cmaps.number_cwins;
5461 j += tmp->cmaps.number_cwins;
5462 cwins[j] = tmp->cmaps.cwins[i];
5465 free((char *) tmp->cmaps.cwins);
5467 tmp->cmaps.cwins = cwins;
5469 if (tmp->cmaps.number_cwins > 1)
5470 memset( tmp->cmaps.scoreboard, 0,
5471 ColormapsScoreboardLength(&tmp->cmaps));
5473 if (previously_installed)
5474 InstallWindowColormaps(PropertyNotify, (TwmWindow *) NULL);
5477 FetchWmColormapWindows (tmp);
5482 void HideIconManager(tmp_win)
5485 /* added this 'if (...) else ...' - djhjr - 9/21/99 */
5486 if (tmp_win == NULL)
5490 HideIconMgr(&Scr->iconmgr);
5493 * New code in list.c necessitates 'next_entry()' and
5494 * 'contents_of_entry()' - djhjr - 10/20/01
5496 for (list = Scr->IconMgrs; list != NULL; list = next_entry(list))
5497 HideIconMgr((IconMgr *)contents_of_entry(list));
5503 if ((ip = (IconMgr *)LookInList(Scr->IconMgrs, tmp_win->full_name,
5504 &tmp_win->class)) == NULL)
5511 /* djhjr - 9/21/99 */
5512 void HideIconMgr(ip)
5515 /* djhjr - 6/10/98 */
5519 SetMapStateProp (ip->twm_win, WithdrawnState);
5520 XUnmapWindow(dpy, ip->twm_win->frame);
5521 if (ip->twm_win->icon_w)
5522 XUnmapWindow (dpy, ip->twm_win->icon_w);
5523 ip->twm_win->mapped = FALSE;
5524 ip->twm_win->icon = TRUE;
5527 /* djhjr - 9/21/99 */
5528 void ShowIconMgr(ip)
5531 /* added the second condition - djhjr - 6/10/98 */
5532 if (Scr->NoIconManagers || ip->count == 0)
5535 DeIconify(ip->twm_win);
5536 XRaiseWindow(dpy, ip->twm_win->frame);
5537 XRaiseWindow(dpy, ip->twm_win->VirtualDesktopDisplayWindow);
5541 void SetBorder (tmp, onoroff)
5547 /* djhjr - 4/22/96 */
5548 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
5549 if (Scr->BorderBevelWidth > 0)
5550 PaintBorders (tmp, onoroff);
5556 XSetWindowBorder (dpy, tmp->frame, tmp->border);
5559 XSetWindowBorder (dpy, tmp->frame, tmp->border_tile.back);
5561 XSetWindowBorder (dpy, tmp->frame, tmp->border.back);
5565 XSetWindowBorder (dpy, tmp->title_w, tmp->border);
5568 XSetWindowBorder (dpy, tmp->title_w, tmp->border_tile.back);
5570 XSetWindowBorder (dpy, tmp->title_w, tmp->border.back);
5574 XSetWindowBorderPixmap (dpy, tmp->frame, tmp->gray);
5577 XSetWindowBorderPixmap (dpy, tmp->title_w, tmp->gray);
5581 /* djhjr - 11/17/97 */
5582 /* rem'd out test for button color - djhjr - 9/15/99 */
5583 if (/*Scr->ButtonColorIsFrame && */tmp->titlebuttons)
5585 int i, nb = Scr->TBInfo.nleft + Scr->TBInfo.nright;
5588 /* collapsed two functions - djhjr - 8/10/98 */
5589 for (i = 0, tbw = tmp->titlebuttons; i < nb; i++, tbw++)
5590 PaintTitleButton(tmp, tbw, (onoroff) ? 2 : 1);
5597 void DestroyMenu (menu)
5603 XDeleteContext (dpy, menu->w, MenuContext);
5604 XDeleteContext (dpy, menu->w, ScreenContext);
5605 if (Scr->Shadow) XDestroyWindow (dpy, menu->shadow);
5606 XDestroyWindow(dpy, menu->w);
5609 for (item = menu->first; item; ) {
5610 MenuItem *tmp = item;
5612 free ((char *) tmp);
5622 /* for moves and resizes from center - djhjr - 10/4/02 */
5623 void WarpScreenToWindow(t)
5626 int warpwin = Scr->WarpWindows;
5627 int warpsnug = Scr->WarpSnug;
5629 Scr->WarpWindows = Scr->WarpSnug = FALSE;
5631 Scr->WarpWindows = warpwin;
5632 Scr->WarpSnug = warpsnug;
5635 * This is an attempt to have windows redraw themselves, but
5636 * it doesn't always work (non-raising windows in particular).
5641 /* was in-lined in WarpToWindow() - djhjr - 5/30/00 */
5642 void WarpWindowOrScreen(t)
5647 * we are either moving the window onto the screen, or the screen to the
5648 * window, the distances remain the same
5651 if ((t->frame_x < Scr->MyDisplayWidth)
5652 && (t->frame_y < Scr->MyDisplayHeight)
5653 && (t->frame_x + t->frame_width >= 0)
5654 && (t->frame_y + t->frame_height >= 0))
5658 * window is visible; you can simply
5659 * snug it if WarpSnug or WarpWindows is set -- DSE
5662 if (Scr->WarpSnug || Scr->WarpWindows)
5664 int right,left,up,down,dx,dy;
5667 * Adjustment for border widths submitted by Steve Ratcliffe
5668 * Note: Do not include the 3D border width!
5671 left = t->frame_x + t->frame_width + 2 * t->frame_bw;
5673 down = t->frame_y + t->frame_height + 2 * t->frame_bw;
5676 if (left-right < Scr->MyDisplayWidth)
5680 else if (left>Scr->MyDisplayWidth)
5681 dx = left - Scr->MyDisplayWidth;
5685 if (down-up < Scr->MyDisplayHeight)
5689 else if (down>Scr->MyDisplayHeight)
5690 dy = down - Scr->MyDisplayHeight;
5693 if (dx!=0 || dy!=0) {
5694 /* added 'Scr->WarpSnug ||' - djhjr - 5/30/00 */
5695 if (Scr->WarpSnug || Scr->WarpWindows)
5697 /* move the window */
5698 VirtualMoveWindow(t, t->virtual_frame_x - dx,
5699 t->virtual_frame_y - dy);
5703 /* move the screen */
5704 PanRealScreen(dx,dy,NULL,NULL);
5713 * Window is invisible; we need to move it or the screen.
5718 xdiff = ((Scr->MyDisplayWidth - t->frame_width) / 2) - t->frame_x;
5719 ydiff = ((Scr->MyDisplayHeight - t->frame_height) / 2) - t->frame_y;
5721 /* added 'Scr->WarpSnug ||' - djhjr - 5/30/00 */
5722 if (Scr->WarpSnug || Scr->WarpWindows)
5724 /* move the window */
5725 VirtualMoveWindow(t, t->virtual_frame_x + xdiff,
5726 t->virtual_frame_y + ydiff);
5730 /* move the screen */
5731 PanRealScreen(-xdiff, -ydiff,NULL,NULL); /* DSE */
5735 if (t->auto_raise || !Scr->NoRaiseWarp)
5736 AutoRaiseWindow (t);
5739 /* for icon manager management - djhjr - 5/30/00 */
5740 void WarpInIconMgr(w, t)
5744 int x, y, pan_margin = 0;
5745 /* djhjr - 9/9/02 */
5746 int bw = t->frame_bw3D + t->frame_bw;
5751 WarpWindowOrScreen(t);
5753 /* was 'Scr->BorderWidth' - djhjr - 9/9/02 */
5754 x = w->x + bw + EDGE_OFFSET + 5;
5755 x += (Scr->IconMgrBevelWidth > 0) ? Scr->IconMgrBevelWidth : bw;
5756 y = w->y + bw + w->height / 2;
5757 y += (Scr->IconMgrBevelWidth > 0) ? Scr->IconMgrBevelWidth : bw;
5758 y += w->iconmgr->twm_win->title_height;
5761 * adjust the pointer for partially visible windows and the
5762 * AutoPan border width
5765 if (Scr->AutoPanX) pan_margin = Scr->AutoPanBorderWidth;
5767 if (x + t->frame_x >= Scr->MyDisplayWidth - pan_margin)
5768 x = Scr->MyDisplayWidth - t->frame_x - pan_margin - 2;
5769 if (x + t->frame_x <= pan_margin)
5770 x = -t->frame_x + pan_margin + 2;
5771 if (y + t->frame_y >= Scr->MyDisplayHeight - pan_margin)
5772 y = Scr->MyDisplayHeight - t->frame_y - pan_margin - 2;
5773 if (y + t->frame_y <= pan_margin)
5774 y = -t->frame_y + pan_margin + 2;
5776 XWarpPointer(dpy, None, t->frame, 0, 0, 0, 0, x, y); /* DSE */
5780 * substantially re-written and added passing 'next' to next_by_class()
5782 * djhjr - 5/13/98 6/6/98 6/15/98
5784 #ifdef ORIGINAL_WARPCLASS
5785 void WarpClass (next, t, class)
5790 int len = strlen(class);
5792 if (!strncmp(class, t->class.res_class, len))
5793 t = next_by_class(t, class);
5795 t = next_by_class((TwmWindow *)NULL, class);
5797 if (Scr->WarpUnmapped || t->mapped) {
5798 if (!t->mapped) DeIconify (t);
5799 if (!Scr->NoRaiseWarp)
5801 XRaiseWindow (dpy, t->frame);
5803 XRaiseWindow (dpy, t->VirtualDesktopDisplayWindow);
5805 RaiseStickyAbove(); /* DSE */
5812 #else /* ORIGINAL_WARPCLASS */
5813 void WarpClass(next, t, class)
5823 * if an empty class string
5825 * class = the TwmWindow's class
5826 * else if a window with focus
5828 * class = the focused window's class
5831 * if still an empty class string
5837 class = t->class.res_class;
5838 else if (Scr->Focus)
5840 i = XGetClassHint(dpy, Scr->Focus->w, &ch);
5841 if (i && !strncmp(class, ch.res_class, strlen(class)))
5842 class = ch.res_class;
5844 /* djhjr - 6/21/00 */
5847 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
5851 if (!strlen(class) || !strncmp(class, "VTWM", 4))
5855 if (!(tt = next_by_class(next, t, class)))
5859 /* djhjr - 5/28/00 */
5866 if ((tt = next_by_class(next, t, class)))
5868 /* multiple icon managers: gotta test for those without entries */
5869 if (tt->iconmgr && tt->iconmgrp->count == 0)
5881 /* added the second argument - djhjr - 5/28/00 */
5882 if (tt && warp_if_warpunmapped(tt, (next) ? F_WARPCLASSNEXT: F_WARPCLASSPREV))
5884 RaiseStickyAbove(); /* DSE */
5887 /* djhjr - 6/3/03 */
5888 #ifndef NO_SOUND_SUPPORT
5889 PlaySound((next) ? F_WARPCLASSNEXT: F_WARPCLASSPREV);
5894 /* djhjr - 5/28/00 */
5904 #endif /* ORIGINAL_WARPCLASS */
5908 /* moved from add_window.c - djhjr - 10/27/02 */
5909 void AddWindowToRing(tmp_win)
5914 /* link window in after Scr->Ring */
5915 tmp_win->ring.prev = Scr->Ring;
5916 tmp_win->ring.next = Scr->Ring->ring.next;
5918 /* Scr->Ring's next's prev points to this */
5919 /*if (Scr->Ring->ring.next->ring.prev)*/
5920 Scr->Ring->ring.next->ring.prev = tmp_win;
5922 /* Scr->Ring's next points to this */
5923 Scr->Ring->ring.next = tmp_win;
5926 tmp_win->ring.next = tmp_win->ring.prev = Scr->Ring = tmp_win;
5929 /* moved from events.c - djhjr - 10/27/02 */
5930 void RemoveWindowFromRing(tmp_win)
5934 if (tmp_win->ring.prev)
5935 tmp_win->ring.prev->ring.next = tmp_win->ring.next;
5936 if (tmp_win->ring.next)
5937 tmp_win->ring.next->ring.prev = tmp_win->ring.prev;
5939 /* if window was only thing in ring, null out ring */
5940 if (Scr->Ring == tmp_win)
5941 Scr->Ring = (tmp_win->ring.next != tmp_win) ?
5942 tmp_win->ring.next : (TwmWindow *)NULL;
5944 /* if window was ring leader, set to next (or null) */
5945 if (!Scr->Ring || Scr->RingLeader == tmp_win)
5946 Scr->RingLeader = Scr->Ring;
5948 tmp_win->ring.next = tmp_win->ring.prev = NULL;
5951 void WarpAlongRing (ev, forward)
5955 TwmWindow *r, *head;
5958 * Re-vamped much of this to properly handle icon managers, and
5959 * clean up dumb code I added some time back.
5961 * Cleaned it up again. I musta been high. Twice.
5965 if (!(head = (Scr->RingLeader) ? Scr->RingLeader : Scr->Ring))
5972 r = head->ring.next;
5974 r = head->ring.prev;
5976 while (r && r != head)
5978 if (r->mapped || warp_if_warpunmapped(r, F_WARPRING))
5981 r = (forward) ? r->ring.next : r->ring.prev;
5986 #ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */
5987 TwmWindow *p = Scr->RingLeader, *t;
5990 /* done in WarpToWindow - djhjr - 10/27/02
5991 Scr->RingLeader = r;
5997 /* djhjr - 6/3/03 */
5998 #ifndef NO_SOUND_SUPPORT
5999 PlaySound(F_WARPRING);
6004 #ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */
6005 if (p && p->mapped &&
6006 XFindContext (dpy, ev->window, TwmContext, (caddr_t *)&t) == XCSUCCESS &&
6009 p->ring.cursor_valid = True;
6010 p->ring.curs_x = ev->x_root - t->frame_x;
6011 p->ring.curs_y = ev->y_root - t->frame_y;
6012 if (p->ring.curs_x < -p->frame_bw ||
6013 p->ring.curs_x >= p->frame_width + p->frame_bw ||
6014 p->ring.curs_y < -p->frame_bw ||
6015 p->ring.curs_y >= p->frame_height + p->frame_bw)
6017 /* somehow out of window */
6018 p->ring.curs_x = p->frame_width / 2;
6019 p->ring.curs_y = p->frame_height / 2;
6025 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
6030 void WarpToScreen (n, inc)
6035 unsigned int dummask;
6036 ScreenInfo *newscr = NULL;
6042 else if (n >= NumScreens)
6045 newscr = ScreenList[n];
6046 if (!newscr) { /* make sure screen is managed */
6047 if (inc) { /* walk around the list */
6051 fprintf (stderr, "%s: unable to warp to unmanaged screen %d\n",
6053 DoAudible(); /* was 'XBell()' - djhjr - 6/22/01 */
6058 if (Scr->screen == n) return; /* already on that screen */
6060 PreviousScreen = Scr->screen;
6061 XQueryPointer (dpy, Scr->Root, &dumwin, &dumwin, &x, &y,
6062 &dumint, &dumint, &dummask);
6064 /* djhjr - 6/3/03 */
6065 #ifndef NO_SOUND_SUPPORT
6066 PlaySound(F_WARPTOSCREEN);
6069 XWarpPointer (dpy, None, newscr->Root, 0, 0, 0, 0, x, y);
6075 void WarpToWindow (t)
6079 int pan_margin = 0; /* djhjr - 5/28/00 */
6080 int bw = t->frame_bw3D + t->frame_bw; /* djhjr - 9/9/02 */
6081 Window w = t->frame; /* djhjr - 5/30/00 */
6083 WarpWindowOrScreen(t); /* djhjr - 5/30/00 */
6085 #ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */
6086 if (t->ring.cursor_valid) {
6091 x = t->frame_width / 2;
6092 y = t->frame_height / 2;
6095 /* added this 'if (...) else' - djhjr - 6/10/98 */
6099 if (t->iconmgrp->count > 0)
6100 XWarpPointer(dpy, None, t->iconmgrp->first->icon, 0,0,0,0,
6101 EDGE_OFFSET, EDGE_OFFSET);
6105 if (t->iconmgrp->count > 0)
6107 w = t->iconmgrp->twm_win->frame;
6109 /* was 'Scr->BorderWidth' - djhjr - 9/9/02 */
6110 x = t->iconmgrp->x + bw + EDGE_OFFSET + 5;
6111 x += (Scr->IconMgrBevelWidth > 0) ? Scr->IconMgrBevelWidth : bw;
6112 y = t->iconmgrp->y + bw + t->iconmgrp->first->height / 2;
6113 y += (Scr->IconMgrBevelWidth > 0) ? Scr->IconMgrBevelWidth : bw;
6114 y += t->iconmgrp->twm_win->title_height;
6117 else if (!t->title_w)
6119 /* added this 'if (...) else' - djhjr - 10/16/02 */
6120 if (Scr->WarpCentered & WARPC_UNTITLED)
6122 x = t->frame_width / 2;
6123 y = t->frame_height / 2;
6127 x = t->frame_width / 2;
6128 y = (t->wShaped) ? bw : bw / 2; /* djhjr - 9/9/02 */
6133 /* added this 'if (...) else' - djhjr - 10/16/02 */
6134 if (Scr->WarpCentered & WARPC_TITLED)
6136 x = t->frame_width / 2;
6137 y = t->frame_height / 2;
6142 * Added 't->title_x + ' to handle titlebars that
6143 * aren't flush left.
6144 * Submitted by Steve Ratcliffe
6145 * was '(t->frame_bw3D + t->frame_bw)' - djhjr - 9/9/02
6147 x = t->title_x + t->title_width / 2 + bw;
6148 y = t->title_height / 2 + bw;
6152 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
6153 if (!Scr->BorderBevelWidth > 0) y -= t->frame_bw;
6157 * adjust the pointer for partially visible windows and the
6158 * AutoPan border width - djhjr - 5/30/00
6159 * was '(t->frame_bw3D + t->frame_bw)' - djhjr - 9/9/02
6162 if (Scr->AutoPanX) pan_margin = Scr->AutoPanBorderWidth;
6164 if (x + t->frame_x >= Scr->MyDisplayWidth - pan_margin)
6165 x = Scr->MyDisplayWidth - t->frame_x - pan_margin - 2;
6166 if (x + t->frame_x <= pan_margin)
6169 x = t->title_width - (t->frame_x + t->title_width) +
6172 x = -t->frame_x + pan_margin + 2;
6175 /* added test for centered warps - djhjr - 10/16/02 */
6176 if (t->title_w && !(Scr->WarpCentered & WARPC_TITLED) &&
6177 (x < t->title_x || x > t->title_x + t->title_width))
6179 y = t->title_height + bw / 2;
6181 if (y + t->frame_y >= Scr->MyDisplayHeight - pan_margin)
6183 y = Scr->MyDisplayHeight - t->frame_y - pan_margin - 2;
6185 /* move centered warp to titlebar - djhjr - 10/16/02 */
6186 if (y < t->title_y + t->title_height)
6187 x = t->title_x + t->title_width / 2 + bw;
6189 if (y + t->frame_y <= pan_margin)
6190 y = -t->frame_y + pan_margin + 2;
6192 /* was 't->frame' - djhjr - 5/30/00 */
6193 XWarpPointer (dpy, None, w, 0, 0, 0, 0, x, y);
6195 /* djhjr - 10/27/02 */
6196 if (t->ring.next) Scr->RingLeader = t;
6202 * substantially re-written and added receiving and using 'next'
6204 * djhjr - 5/13/98 5/19/98 6/6/98 6/15/98
6206 #ifdef ORIGINAL_WARPCLASS
6208 next_by_class (t, class)
6213 int len = strlen(class);
6216 for (tt = t->next; tt != NULL; tt = tt->next)
6217 if (!strncmp(class, tt->class.res_class, len)) return tt;
6218 for (tt = Scr->TwmRoot.next; tt != NULL; tt = tt->next)
6219 if (!strncmp(class, tt->class.res_class, len)) return tt;
6222 #else /* ORIGINAL_WARPCLASS */
6224 next_by_class (next, t, class)
6229 static TwmWindow *tp = NULL;
6231 int i, len = strlen(class);
6234 #ifdef DEBUG_WARPCLASS
6235 fprintf(stderr, "class=\"%s\", next=%d, %s t, ", class, next, (t) ? "have" : "no");
6238 /* forward or backward from current */
6239 tl = (next) ? ((tp) ? tp->next : Scr->TwmRoot.next) : ((tp) ? tp->prev : Scr->TwmRoot.prev);
6240 for (tt = (next) ? ((t) ? t->next : tl) : ((t) ? t->prev : tl);
6242 tt = (next) ? tt->next : tt->prev)
6243 if (Scr->WarpUnmapped || tt->mapped)
6245 i = XGetClassHint(dpy, tt->w, &ch);
6246 if (i && !strncmp(class, ch.res_class, len))
6248 #ifdef DEBUG_WARPCLASS
6249 fprintf(stderr, "matched \"%s\" \"%s\"\n", tt->class.res_class, tt->class.res_name);
6256 #ifdef DEBUG_WARPCLASS
6257 fprintf(stderr, "(1) skipping \"%s\"\n", (i) ? tt->class.res_class : "NO RES_CLASS!");
6263 /* no match, wrap and retry */
6265 for (tt = Scr->TwmRoot.next; tt != NULL; tt = tt->next)
6266 if (Scr->WarpUnmapped || tt->mapped)
6268 i = XGetClassHint(dpy, tt->w, &ch);
6269 if (i && !strncmp(class, ch.res_class, len))
6273 #ifdef DEBUG_WARPCLASS
6274 fprintf(stderr, "next wrapped to \"%s\ \"%s\"\n", tt->class.res_class, tt->class.res_name);
6282 #ifdef DEBUG_WARPCLASS
6284 fprintf(stderr, "(2) skipping \"%s\"\n", (i) ? tt->class.res_class : "NO RES_CLASS!");
6288 #ifdef DEBUG_WARPCLASS
6289 i = 0; if (tl) i = XGetClassHint(dpy, tl->w, &ch);
6290 fprintf(stderr, "prev wrapped to \"%s\ \"%s\"\n", (i) ? ch.res_class : "NO RES_CLASS!", (i) ? ch.res_name : "NO RES_CLASS!");
6295 #endif /* ORIGINAL_WARPCLASS */
6297 /* this was inlined in many places, and even more now - djhjr - 5/13/98 */
6298 /* added the second argument - djhjr - 5/28/00 */
6299 static int warp_if_warpunmapped(w, func)
6303 /* skip empty icon managers - 10/27/02 */
6304 if (w && (w->iconmgr && w->iconmgrp->count == 0))
6307 if (Scr->WarpUnmapped || w->mapped)
6309 /* submitted by Ugen Antsilevitch - 5/28/00 */
6310 /* if F_NOFUNCTION, override WarpVisible - djhjr - 5/28/00 */
6311 if (func != F_NOFUNCTION && Scr->WarpVisible)
6315 if (Scr->AutoPanX) pan_margin = Scr->AutoPanBorderWidth;
6317 if (w->frame_x >= Scr->MyDisplayWidth - pan_margin ||
6318 w->frame_y >= Scr->MyDisplayHeight - pan_margin ||
6319 w->frame_x + w->frame_width <= pan_margin ||
6320 w->frame_y + w->frame_height <= pan_margin)
6324 if (!w->mapped) DeIconify(w);
6325 if (!Scr->NoRaiseWarp) XRaiseWindow(dpy, w->frame);
6326 XRaiseWindow(dpy, w->VirtualDesktopDisplayWindow);
6334 /* djhjr - 9/17/02 */
6336 do_squeezetitle(context, func, tmp_win, squeeze)
6339 SqueezeInfo *squeeze;
6341 if (DeferExecution (context, func, Scr->SelectCursor))
6344 /* honor "Don't Squeeze" resources - djhjr - 9/17/02 */
6345 if (Scr->SqueezeTitle &&
6346 !LookInList(Scr->DontSqueezeTitleL, tmp_win->full_name, &tmp_win->class))
6348 if ( tmp_win->title_height ) /* Not for untitled windows! */
6350 PopDownMenu(); /* djhjr - 9/17/02 */
6352 #ifndef NO_SOUND_SUPPORT
6356 tmp_win->squeeze_info = squeeze;
6357 SetFrameShape( tmp_win );
6359 /* Can't go in SetFrameShape()... - djhjr - 4/1/00 */
6360 if (Scr->WarpCursor ||
6361 LookInList(Scr->WarpCursorL, tmp_win->full_name, &tmp_win->class))
6362 WarpToWindow(tmp_win);
6372 * Two functions to handle a restart from a SIGUSR1 signal
6373 * (see also twm.c:Done() and twm.c:QueueRestartVtwm())
6375 * adapted from TVTWM-pl11 - djhjr - 7/31/98
6378 static void setup_restart(time)
6381 /* djhjr - 6/22/01 */
6382 #ifndef NO_SOUND_SUPPORT
6391 /* djhjr - 3/13/97 */
6394 /* djhjr - 12/2/01 */
6398 void RestartVtwm(time)
6401 setup_restart(time);
6403 execvp(*Argv, Argv);
6404 fprintf (stderr, "%s: unable to restart \"%s\"\n", ProgramName, *Argv);
6409 * ICCCM Client Messages - Section 4.2.8 of the ICCCM dictates that all
6410 * client messages will have the following form:
6412 * event type ClientMessage
6413 * message type _XA_WM_PROTOCOLS
6416 * data[0] message atom
6417 * data[1] time stamp
6420 static void send_clientmessage (w, a, timestamp)
6425 XClientMessageEvent ev;
6427 ev.type = ClientMessage;
6429 ev.message_type = _XA_WM_PROTOCOLS;
6432 ev.data.l[1] = timestamp;
6433 XSendEvent (dpy, w, False, 0L, (XEvent *) &ev);
6436 void SendDeleteWindowMessage (tmp, timestamp)
6440 send_clientmessage (tmp->w, _XA_WM_DELETE_WINDOW, timestamp);
6443 void SendSaveYourselfMessage (tmp, timestamp)
6447 send_clientmessage (tmp->w, _XA_WM_SAVE_YOURSELF, timestamp);
6450 void SendTakeFocusMessage (tmp, timestamp)
6454 send_clientmessage (tmp->w, _XA_WM_TAKE_FOCUS, timestamp);
6458 /* djhjr - 4/27/96 */
6459 void DisplayPosition (x, y)
6478 i = sprintf (str, " %c%-4d %c%-4d ", signx, x, signy, y);
6481 * Non-SysV systems - specifically, BSD-derived systems - return a
6482 * pointer to the string, not its length. Submitted by Goran Larsson
6483 i = sprintf (str, "%+6d %-+6d", x, y);
6485 sprintf (str, "%+6d %-+6d", x, y);
6488 XRaiseWindow (dpy, Scr->SizeWindow);
6489 /* font was font.font->fid - djhjr - 9/14/03 */
6490 FBF (Scr->DefaultC.fore, Scr->DefaultC.back, Scr->SizeFont);
6491 /* djhjr - 9/14/03 */
6492 #ifndef NO_I18N_SUPPORT
6493 MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont,
6495 XDrawImageString (dpy, Scr->SizeWindow,
6500 Scr->SizeStringOffset,
6502 (Scr->SizeStringWidth -
6503 /* djhjr - 9/14/03 */
6504 #ifndef NO_I18N_SUPPORT
6505 MyFont_TextWidth(&Scr->SizeFont,
6507 XTextWidth(Scr->SizeFont.font,
6512 Scr->SizeFont.font->ascent + SIZE_VINDENT,
6514 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
6516 Scr->SizeFont.font->ascent +
6518 Scr->SizeFont.ascent +
6520 ((Scr->InfoBevelWidth > 0) ? Scr->InfoBevelWidth : 0),
6524 /* I know, I know, but the above code overwrites it... djhjr - 5/9/96 */
6525 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
6526 if (Scr->InfoBevelWidth > 0)
6527 Draw3DBorder(Scr->SizeWindow, 0, 0,
6528 Scr->SizeStringWidth,
6531 (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2),
6532 BW, Scr->DefaultC, off, False, False);
6534 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
6535 (unsigned int) (Scr->SizeFont.height + SIZE_VINDENT*2) +
6536 ((Scr->InfoBevelWidth > 0) ? 2 * Scr->InfoBevelWidth : 0),
6537 Scr->InfoBevelWidth, Scr->DefaultC, off, False, False);
6540 /* djhjr - 9/21/99 */
6541 int FindMenuOrFuncInBindings(contexts, mr, func)
6548 int found = 0; /* context bitmap for menu or function */
6549 int i, j, k, l, fallback = 0;
6553 if (Scr->DefaultFunction.func == F_MENU)
6554 if (FindMenuInMenus(Scr->DefaultFunction.menu, mr))
6559 if (Scr->DefaultFunction.func == func)
6561 else if (Scr->DefaultFunction.func == F_MENU)
6562 if (FindFuncInMenus(Scr->DefaultFunction.menu, func))
6566 for (j = 0; j < NUM_CONTEXTS; j++)
6568 if ((contexts & (1 << j)) == 0) continue;
6576 for (i = 0; i < MAX_BUTTONS + 1; i++)
6580 for (k = 0; k < MOD_SIZE; k++)
6584 if (Scr->Mouse[i][j][k].func == F_MENU)
6585 l = FindMenuInMenus(Scr->Mouse[i][j][k].menu, mr);
6589 if (Scr->Mouse[i][j][k].func == func)
6591 else if (Scr->Mouse[i][j][k].func == F_MENU)
6592 l = FindFuncInMenus(Scr->Mouse[i][j][k].menu, func);
6598 i = MAX_BUTTONS + 1;
6605 for (key = Scr->FuncKeyRoot.next; key != NULL; key = key->next)
6606 if (key->cont & (1 << j))
6610 if (key->func == F_MENU)
6611 for (start = Scr->MenuList; start != NULL; start = start->next)
6612 if (strcmp(start->name, key->action) == 0)
6614 l = FindMenuInMenus(start, mr);
6620 if (key->func == func)
6622 else if (key->func == F_MENU)
6623 for (start = Scr->MenuList; start != NULL; start = start->next)
6624 if (strcmp(start->name, key->action) == 0)
6626 l = FindFuncInMenus(start, func);
6642 /* djhjr - 9/21/99 */
6643 int FindMenuOrFuncInWindows(tmp_win, contexts, mr, func)
6654 if (contexts & C_ROOT_BIT) return 1;
6656 for (twin = Scr->TwmRoot.next; twin != NULL; twin = twin->next)
6657 if (twin != tmp_win)
6660 * if this window is an icon manager,
6661 * skip the windows that aren't in it
6663 if (tmp_win->iconmgr && twin->list &&
6664 tmp_win != twin->list->iconmgr->twm_win)
6669 for (i = 1; i < C_ALL_BITS; i = (1 << i))
6671 if ((contexts & i) == 0) continue;
6679 if (!twin->title_height) continue;
6682 if (twin->w != Scr->VirtualDesktopDisplayOuter)
6686 if (XFindContext(dpy, twin->w, DoorContext,
6687 (caddr_t *)&d) == XCNOENT)
6698 if (twin->titlebuttons)
6700 nb = Scr->TBInfo.nleft + Scr->TBInfo.nright;
6702 for (tbw = twin->titlebuttons; nb > 0; tbw++, nb--)
6705 if (tbw->info->menuroot)
6706 if (FindMenuInMenus(tbw->info->menuroot, mr))
6711 if (tbw->info->func == func)
6713 else if (tbw->info->menuroot)
6714 if (FindFuncInMenus(tbw->info->menuroot, func))
6719 else if (!twin->iconify_by_unmapping)
6721 /* not mapped and shows an icon */
6723 if (contexts & C_ICON_BIT) return 1;
6730 /* djhjr - 9/21/99 */
6731 int FindMenuInMenus(start, sought)
6732 MenuRoot *start, *sought;
6736 if (!start) return 0; /* submitted by Jonathan Paisley - 11/11/02 */
6737 if (start == sought) return 1;
6739 for (mi = start->first; mi != NULL; mi = mi->next)
6741 if (FindMenuInMenus(mi->sub, sought))
6747 /* djhjr - 9/21/99 */
6748 int FindFuncInMenus(mr, func)
6754 for (mi = mr->first; mi != NULL; mi = mi->next)
6755 if (mi->func == func)
6758 if (FindFuncInMenus(mi->sub, func))
6764 /* djhjr - 6/22/01 */
6767 #ifndef NO_SOUND_SUPPORT
6768 if (PlaySound(S_BELL)) return;