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 /*****************************************************************************/
29 /**********************************************************************
31 * $XConsortium: add_window.c,v 1.153 91/07/10 13:17:26 dave Exp $
33 * Add a new window, put the titlbar and other stuff around
36 * 31-Mar-88 Tom LaStrange Initial Version.
38 **********************************************************************/
43 #include <X11/Xatom.h>
44 #ifndef NO_XPM_SUPPORT
48 #include "add_window.h"
63 /* random placement coordinates */
64 #define PLACEMENT_START 50
65 #define PLACEMENT_INCR 30
68 extern int PlaceApplet();
72 static char gray_bits[] = {
76 static unsigned char black_bits[] = {
84 static void CreateWindowTitlebarButtons();
85 void SetHighlightPixmap();
88 static void AddMoveAndResize();
90 char NoName[] = "Untitled"; /* name if no name is specified */
93 /************************************************************************
96 * GetGravityOffsets - map gravity to (x,y) offset signs for adding
97 * to x and y when window is mapped to get proper placement.
99 ************************************************************************
102 void GetGravityOffsets (tmp, xp, yp)
103 TwmWindow *tmp; /* window from which to get gravity */
104 int *xp, *yp; /* return values */
106 static struct _gravity_offset {
108 } gravity_offsets[11] = {
109 { 0, 0 }, /* ForgetGravity */
110 { -1, -1 }, /* NorthWestGravity */
111 { 0, -1 }, /* NorthGravity */
112 { 1, -1 }, /* NorthEastGravity */
113 { -1, 0 }, /* WestGravity */
114 { 0, 0 }, /* CenterGravity */
115 { 1, 0 }, /* EastGravity */
116 { -1, 1 }, /* SouthWestGravity */
117 { 0, 1 }, /* SouthGravity */
118 { 1, 1 }, /* SouthEastGravity */
119 { 0, 0 }, /* StaticGravity */
121 register int g = ((tmp->hints.flags & PWinGravity)
122 ? tmp->hints.win_gravity : NorthWestGravity);
124 if (g < ForgetGravity || g > StaticGravity) {
127 *xp = gravity_offsets[g].x;
128 *yp = gravity_offsets[g].y;
133 /***********************************************************************
136 * AddWindow - add a new window to the twm list
139 * (TwmWindow *) - pointer to the TwmWindow structure
142 * w - the window id of the window to add
143 * iconm - flag to tell if this is an icon manager window
144 * iconp - pointer to icon manager struct
146 ***********************************************************************
150 AddWindow(w, iconm, iconp)
155 TwmWindow *tmp_win; /* new twm window structure */
156 unsigned long valuemask; /* mask for create windows */
157 XSetWindowAttributes attributes; /* attributes for create windows */
158 #ifdef NO_I18N_SUPPORT
159 XTextProperty text_property;
163 unsigned long nitems, bytesafter;
164 int ask_user; /* don't know where to put the window */
165 int *ppos_ptr, ppos_on; /* djhjr - 9/24/02 */
166 int gravx, gravy; /* gravity signs for positioning */
169 char *icon_name; /* djhjr - 2/20/99 */
170 #ifndef NO_I18N_SUPPORT
173 /* next two submitted by Jonathan Paisley - 11/8/02 */
174 Atom motifhints = XInternAtom( dpy, "_MOTIF_WM_HINTS", 0);
175 MotifWmHints *mwmhints;
178 fprintf(stderr, "AddWindow: w = 0x%x\n", w);
181 /* allocate space for the twm window */
182 tmp_win = (TwmWindow *)calloc(1, sizeof(TwmWindow));
185 fprintf (stderr, "%s: Unable to allocate memory to manage window ID %lx.\n",
190 tmp_win->zoomed = ZOOM_NONE;
191 tmp_win->iconmgr = iconm;
192 tmp_win->iconmgrp = iconp;
193 tmp_win->cmaps.number_cwins = 0;
195 XSelectInput(dpy, tmp_win->w, PropertyChangeMask);
196 XGetWindowAttributes(dpy, tmp_win->w, &tmp_win->attr);
198 /* djhjr - 9/14/03 */
199 #ifndef NO_I18N_SUPPORT
200 if (I18N_FetchName(dpy, tmp_win->w, &name))
202 tmp_win->name = strdup(name);
207 * Ask the window manager for a name with "newer" R4 function -
208 * it was 'XFetchName()', which apparently failed more often.
209 * Submitted by Nicholas Jacobs
211 if (XGetWMName(dpy, tmp_win->w, &text_property) != 0)
213 tmp_win->name = (char *)strdup(text_property.value);
214 XFree(text_property.value);
218 tmp_win->name = NoName;
220 tmp_win->class = NoClass;
221 XGetClassHint(dpy, tmp_win->w, &tmp_win->class);
222 FetchWmProtocols (tmp_win);
223 FetchWmColormapWindows (tmp_win);
226 * do initial clip; should look at window gravity
228 if (tmp_win->attr.width > Scr->MaxWindowWidth)
229 tmp_win->attr.width = Scr->MaxWindowWidth;
230 if (tmp_win->attr.height > Scr->MaxWindowHeight)
231 tmp_win->attr.height = Scr->MaxWindowHeight;
233 tmp_win->wmhints = XGetWMHints(dpy, tmp_win->w);
234 if (tmp_win->wmhints && (tmp_win->wmhints->flags & WindowGroupHint))
235 tmp_win->group = tmp_win->wmhints->window_group;
237 tmp_win->group = tmp_win->w/* NULL */;
239 /* submitted by Jonathan Paisley - 11/8/02 */
240 tmp_win->mwmhints.flags = 0;
241 if (motifhints != None)
243 if (XGetWindowProperty(dpy, tmp_win->w, motifhints,
244 0L, sizeof(MotifWmHints), False,
245 motifhints, &actual_type, &actual_format,
246 &nitems, &bytesafter,
247 (unsigned char**)&mwmhints) == Success && actual_type != None)
251 tmp_win->mwmhints = *mwmhints;
258 * The July 27, 1988 draft of the ICCCM ignores the size and position
259 * fields in the WM_NORMAL_HINTS property.
262 tmp_win->transient = Transient(tmp_win->w, &tmp_win->transientfor);
264 if (tmp_win->class.res_name == NULL)
265 tmp_win->class.res_name = NoName;
266 if (tmp_win->class.res_class == NULL)
267 tmp_win->class.res_class = NoName;
269 tmp_win->full_name = tmp_win->name;
270 namelen = strlen (tmp_win->name);
272 tmp_win->highlight = Scr->Highlight &&
274 (!(short)(int) LookInList(Scr->NoHighlight, tmp_win->full_name,
277 (LookInList(Scr->NoHighlight, tmp_win->full_name,
278 &tmp_win->class) == (char *)NULL);
280 tmp_win->stackmode = Scr->StackMode &&
282 (!(short)(int) LookInList(Scr->NoStackModeL, tmp_win->full_name,
285 (LookInList(Scr->NoStackModeL, tmp_win->full_name,
286 &tmp_win->class) == (char *)NULL);
288 tmp_win->titlehighlight = Scr->TitleHighlight &&
290 (!(short)(int) LookInList(Scr->NoTitleHighlight, tmp_win->full_name,
293 (LookInList(Scr->NoTitleHighlight, tmp_win->full_name,
294 &tmp_win->class) == (char *)NULL);
296 tmp_win->auto_raise = Scr->AutoRaiseDefault || /* RAISEDELAY */
298 (short)(int) LookInList(Scr->AutoRaise, tmp_win->full_name,
301 (LookInList(Scr->AutoRaise, tmp_win->full_name,
302 &tmp_win->class) != (char *)NULL);
303 if (tmp_win->auto_raise) Scr->NumAutoRaises++;
305 tmp_win->iconify_by_unmapping = Scr->IconifyByUnmapping;
306 if (Scr->IconifyByUnmapping)
309 tmp_win->iconify_by_unmapping = iconm ? FALSE :
311 tmp_win->iconify_by_unmapping =
313 !(short)(int) LookInList(Scr->DontIconify, tmp_win->full_name,
316 (LookInList(Scr->DontIconify, tmp_win->full_name,
317 &tmp_win->class) == (char *)NULL);
319 tmp_win->iconify_by_unmapping |=
321 (short)(int) LookInList(Scr->IconifyByUn, tmp_win->full_name,
324 (LookInList(Scr->IconifyByUn, tmp_win->full_name,
325 &tmp_win->class) != (char *)NULL);
327 /* Scr->NoWindowRingL submitted by Jonathan Paisley - 10/27/02 */
328 if ((Scr->UseWindowRing ||
329 LookInList(Scr->WindowRingL, tmp_win->full_name,
331 LookInList(Scr->NoWindowRingL, tmp_win->full_name,
332 &tmp_win->class) == (char *)NULL)
334 /* in menus.c now - djhjr - 10/27/02 */
335 AddWindowToRing(tmp_win);
338 tmp_win->ring.next = tmp_win->ring.prev = NULL;
339 #ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */
340 tmp_win->ring.cursor_valid = False;
343 if (LookInList(Scr->NailedDown, tmp_win->full_name, &tmp_win->class))
344 tmp_win->nailed = TRUE;
346 tmp_win->nailed = FALSE;
348 if (LookInList(Scr->DontShowInDisplay, tmp_win->full_name, &tmp_win->class))
349 tmp_win->showindesktopdisplay = FALSE;
351 tmp_win->showindesktopdisplay = TRUE;
353 tmp_win->squeeze_info = NULL;
355 * get the squeeze information; note that this does not have to be freed
356 * since it is coming from the screen list
359 if (!LookInList (Scr->DontSqueezeTitleL, tmp_win->full_name,
361 tmp_win->squeeze_info = (SqueezeInfo *)
362 LookInList (Scr->SqueezeTitleL, tmp_win->full_name,
364 if (!tmp_win->squeeze_info) {
365 static SqueezeInfo default_squeeze = { J_LEFT, 0, 0 };
366 if (Scr->SqueezeTitle)
367 tmp_win->squeeze_info = &default_squeeze;
372 tmp_win->old_bw = tmp_win->attr.border_width;
374 #ifdef NEVER /* see the next '#ifdef NEVER's '#else' - C. F. Jalali */
375 /* djhjr - 4/19/96 */
376 /* was 'Scr->ThreeDBorderWidth' - djhjr - 8/11/98 */
377 tmp_win->frame_bw3D = Scr->BorderWidth;
379 /* added 'Scr->NoBorders' test - djhjr - 8/23/02 */
380 if (Scr->NoBorders || LookInList(Scr->NoBorder, tmp_win->full_name, &tmp_win->class))
382 tmp_win->frame_bw = 0;
383 tmp_win->frame_bw3D = 0;
387 if (tmp_win->frame_bw3D != 0)
389 tmp_win->frame_bw = 0;
390 Scr->ClientBorderWidth = FALSE;
393 if (Scr->ClientBorderWidth)
394 tmp_win->frame_bw = tmp_win->old_bw;
396 tmp_win->frame_bw = Scr->BorderWidth;
399 * Submitted by Caveh Frank Jalali - 8/25/98
402 if (Scr->BorderBevelWidth > 0)
404 tmp_win->frame_bw3D = Scr->BorderWidth;
405 tmp_win->frame_bw = 0;
406 Scr->ClientBorderWidth = FALSE;
410 tmp_win->frame_bw3D = 0;
411 if (Scr->ClientBorderWidth)
412 tmp_win->frame_bw = tmp_win->old_bw;
414 tmp_win->frame_bw = Scr->BorderWidth;
419 /* submitted by Jonathan Paisley - 11/8/02 */
420 if (tmp_win->mwmhints.flags & MWM_HINTS_DECORATIONS)
422 if (tmp_win->mwmhints.decorations & MWM_DECOR_ALL)
423 tmp_win->mwmhints.decorations |= (MWM_DECOR_BORDER |
424 MWM_DECOR_RESIZEH | MWM_DECOR_TITLE |
425 MWM_DECOR_MENU | MWM_DECOR_MINIMIZE |
428 if (!(tmp_win->mwmhints.decorations & MWM_DECOR_BORDER))
429 tmp_win->frame_bw = tmp_win->frame_bw3D = 0;
431 if (tmp_win->mwmhints.flags & MWM_HINTS_FUNCTIONS)
432 if (tmp_win->mwmhints.functions & MWM_FUNC_ALL)
433 tmp_win->mwmhints.functions |= (MWM_FUNC_RESIZE |
434 MWM_FUNC_MOVE | MWM_FUNC_MINIMIZE |
435 MWM_FUNC_MAXIMIZE | MWM_FUNC_CLOSE);
437 bw2 = tmp_win->frame_bw * 2;
439 /* moved MakeTitle under NoTitle - djhjr - 10/20/01 */
440 tmp_win->title_height = Scr->TitleHeight + tmp_win->frame_bw;
442 /* submitted by Jonathan Paisley 11/8/02 */
443 if (tmp_win->mwmhints.flags & MWM_HINTS_DECORATIONS &&
444 !(tmp_win->mwmhints.decorations & MWM_DECOR_TITLE))
445 tmp_win->title_height = 0;
448 tmp_win->title_height = 0;
449 if (LookInList(Scr->NoTitle, tmp_win->full_name, &tmp_win->class))
450 tmp_win->title_height = 0;
451 if (LookInList(Scr->MakeTitle, tmp_win->full_name, &tmp_win->class))
452 tmp_win->title_height = Scr->TitleHeight + tmp_win->frame_bw;
455 if (LookInList(Scr->OpaqueMoveL, tmp_win->full_name, &tmp_win->class))
456 tmp_win->opaque_move = TRUE;
458 tmp_win->opaque_move = Scr->OpaqueMove &&
460 !(short)(int)LookInList(Scr->NoOpaqueMoveL, tmp_win->full_name, &tmp_win->class);
462 (LookInList(Scr->NoOpaqueMoveL, tmp_win->full_name,
463 &tmp_win->class) == (char *)NULL);
465 /* djhjr - 9/21/99 */
466 if (tmp_win->opaque_move) tmp_win->attr.save_under = True;
469 if (LookInList(Scr->OpaqueResizeL, tmp_win->full_name, &tmp_win->class))
470 tmp_win->opaque_resize = TRUE;
472 tmp_win->opaque_resize = Scr->OpaqueResize &&
474 !(short)(int)LookInList(Scr->NoOpaqueResizeL, tmp_win->full_name, &tmp_win->class);
476 (LookInList(Scr->NoOpaqueResizeL, tmp_win->full_name,
477 &tmp_win->class) == (char *)NULL);
479 /* djhjr - 9/21/99 */
480 if (tmp_win->opaque_resize) tmp_win->attr.save_under = True;
482 /* if it is a transient window, don't put a title on it */
483 if (tmp_win->transient && !Scr->DecorateTransients)
484 tmp_win->title_height = 0;
486 if (LookInList(Scr->StartIconified, tmp_win->full_name, &tmp_win->class))
488 if (!tmp_win->wmhints)
490 tmp_win->wmhints = (XWMHints *)malloc(sizeof(XWMHints));
491 tmp_win->wmhints->flags = 0;
493 tmp_win->wmhints->initial_state = IconicState;
494 tmp_win->wmhints->flags |= StateHint;
497 GetWindowSizeHints (tmp_win);
498 GetGravityOffsets (tmp_win, &gravx, &gravy);
501 * Don't bother user if:
503 * o the window is a transient, or
505 * o a USPosition was requested, or
507 * o a PPosition was requested and UsePPosition is ON or
508 * NON_ZERO if the window is at other than (0,0)
511 /* djhjr - 9/24/02 */
512 if ((ppos_ptr = (int *)LookInList(Scr->UsePPositionL,
513 tmp_win->full_name, &tmp_win->class)))
516 ppos_on = Scr->UsePPosition;
517 if (ppos_on == PPOS_NON_ZERO &&
518 (tmp_win->attr.x != 0 || tmp_win->attr.y != 0))
522 if (tmp_win->transient ||
523 (tmp_win->hints.flags & USPosition) ||
524 ((tmp_win->hints.flags & PPosition) && ppos_on == PPOS_ON))
527 /* check for applet regions - djhjr - 4/26/99 */
528 if (PlaceApplet(tmp_win, tmp_win->attr.x, tmp_win->attr.y,
529 &tmp_win->attr.x, &tmp_win->attr.y))
532 if (LookInList(Scr->NailedDown, tmp_win->full_name, &tmp_win->class))
533 tmp_win->nailed = TRUE;
535 tmp_win->nailed = FALSE;
538 * 25/09/90 - Nailed windows should always be on the real screen,
539 * regardless of PPosition or UPosition. If we are dealing with
540 * PPosition, then offset by the current real screen offset on the vd.
542 if (tmp_win->nailed ||
543 ((tmp_win->hints.flags & PPosition) && (ask_user == FALSE))) {
544 tmp_win->attr.x = R_TO_V_X(tmp_win->attr.x);
545 tmp_win->attr.y = R_TO_V_Y(tmp_win->attr.y);
548 /* moved to after window prep and creation - djhjr - 4/14/98
549 AddMoveAndResize(tmp_win, ask_user);
552 if (!Scr->ClientBorderWidth) { /* need to adjust for twm borders */
555 int delta = tmp_win->attr.border_width - tmp_win->frame_bw;
557 /* submitted by Jonathan Paisley - 11/8/02
558 int delta = tmp_win->attr.border_width - tmp_win->frame_bw - tmp_win->frame_bw3D;
560 int delta = -(tmp_win->frame_bw + tmp_win->frame_bw3D);
562 tmp_win->attr.x += gravx * delta;
563 tmp_win->attr.y += gravy * delta;
567 * For windows with specified non-northwest gravities.
568 * Submitted by Jonathan Paisley - 11/8/02
570 if (tmp_win->old_bw) {
571 if (!Scr->ClientBorderWidth) {
577 tmp_win->attr.x += JunkX * tmp_win->old_bw;
578 tmp_win->attr.y += JunkY * tmp_win->old_bw;
581 tmp_win->title_width = tmp_win->attr.width;
583 if (tmp_win->old_bw) XSetWindowBorderWidth (dpy, tmp_win->w, 0);
585 /* djhjr - 9/14/03 */
586 #ifndef NO_I18N_SUPPORT
587 tmp_win->name_width = MyFont_TextWidth(&Scr->TitleBarFont,
589 tmp_win->name_width = XTextWidth(Scr->TitleBarFont.font,
591 tmp_win->name, namelen);
593 /* djhjr - 9/14/03 */
594 #ifndef NO_I18N_SUPPORT
595 if (!I18N_GetIconName(dpy, tmp_win->w, &icon_name))
597 /* used to be a simple boolean test for success - djhjr - 1/10/98 */
598 if (XGetWindowProperty (dpy, tmp_win->w, XA_WM_ICON_NAME, 0L, 200L, False,
599 XA_STRING, &actual_type, &actual_format, &nitems, &bytesafter,
601 /* see that the icon name is it's own memory - djhjr - 2/20/99
602 (unsigned char **)&tmp_win->icon_name) != Success || actual_type == None)
603 tmp_win->icon_name = tmp_win->name;
605 (unsigned char **)&icon_name) != Success || actual_type == None)
607 tmp_win->icon_name = strdup(tmp_win->name);
610 tmp_win->icon_name = strdup(icon_name);
611 /* djhjr - 9/14/03 */
612 #ifndef NO_I18N_SUPPORT
619 /* redundant? - djhjr - 1/10/98
620 if (tmp_win->icon_name == NULL)
621 tmp_win->icon_name = tmp_win->name;
624 tmp_win->iconified = FALSE;
625 tmp_win->icon = FALSE;
626 tmp_win->icon_on = FALSE;
631 * Make sure the client window still exists. We don't want to leave an
632 * orphan frame window if it doesn't. Since we now have the server
633 * grabbed, the window can't disappear later without having been
634 * reparented, so we'll get a DestroyNotify for it. We won't have
635 * gotten one for anything up to here, however.
637 if (XGetGeometry(dpy, tmp_win->w, &JunkRoot, &JunkX, &JunkY,
638 &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0)
640 free((char *)tmp_win);
645 /* add the window into the twm list */
646 tmp_win->next = Scr->TwmRoot.next;
647 if (Scr->TwmRoot.next != NULL)
648 Scr->TwmRoot.next->prev = tmp_win;
649 tmp_win->prev = &Scr->TwmRoot;
650 Scr->TwmRoot.next = tmp_win;
652 /* get all the colors for the window */
655 tmp_win->border = Scr->BorderColor;
657 tmp_win->border.back = Scr->BorderColor;
659 tmp_win->icon_border = Scr->IconBorderColor;
660 tmp_win->border_tile.fore = Scr->BorderTileC.fore;
661 tmp_win->border_tile.back = Scr->BorderTileC.back;
662 tmp_win->title.fore = Scr->TitleC.fore;
663 tmp_win->title.back = Scr->TitleC.back;
664 tmp_win->iconc.fore = Scr->IconC.fore;
665 tmp_win->iconc.back = Scr->IconC.back;
666 tmp_win->virtual.fore = Scr->VirtualDesktopDisplayC.fore;
667 tmp_win->virtual.back = Scr->VirtualDesktopDisplayC.back;
670 GetColorFromList(Scr->BorderColorL, tmp_win->full_name, &tmp_win->class,
673 GetColorFromList(Scr->BorderColorL, tmp_win->full_name, &tmp_win->class,
674 &tmp_win->border.back);
676 GetColorFromList(Scr->IconBorderColorL, tmp_win->full_name, &tmp_win->class,
677 &tmp_win->icon_border);
678 GetColorFromList(Scr->BorderTileForegroundL, tmp_win->full_name,
679 &tmp_win->class, &tmp_win->border_tile.fore);
680 GetColorFromList(Scr->BorderTileBackgroundL, tmp_win->full_name,
681 &tmp_win->class, &tmp_win->border_tile.back);
682 GetColorFromList(Scr->TitleForegroundL, tmp_win->full_name, &tmp_win->class,
683 &tmp_win->title.fore);
684 GetColorFromList(Scr->TitleBackgroundL, tmp_win->full_name, &tmp_win->class,
685 &tmp_win->title.back);
686 GetColorFromList(Scr->IconForegroundL, tmp_win->full_name, &tmp_win->class,
687 &tmp_win->iconc.fore);
688 GetColorFromList(Scr->IconBackgroundL, tmp_win->full_name, &tmp_win->class,
689 &tmp_win->iconc.back);
691 /* fixed transposed fallback fore and back color lists - djhjr - 9/25/01 */
692 if (!GetColorFromList(Scr->VirtualDesktopColorFL, tmp_win->full_name,
693 &tmp_win->class, &tmp_win->virtual.fore))
694 GetColorFromList(Scr->TitleForegroundL, tmp_win->full_name,
695 &tmp_win->class, &tmp_win->virtual.fore);
696 if (!GetColorFromList(Scr->VirtualDesktopColorBL, tmp_win->full_name,
697 &tmp_win->class, &tmp_win->virtual.back))
698 GetColorFromList(Scr->TitleBackgroundL, tmp_win->full_name,
699 &tmp_win->class, &tmp_win->virtual.back);
701 /* djhjr - 4/19/96 */
702 /* loosened up for titlebar-colored 3D buttons - djhjr - 4/1/98
703 if (Scr->use3Dtitles && !Scr->BeNiceToColormap)
705 if (!Scr->BeNiceToColormap)
706 GetShadeColors (&tmp_win->title);
707 /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */
708 /* rearranged the parenthesis - djhjr - 10/30/02 */
709 if ((Scr->ButtonColorIsFrame || Scr->BorderBevelWidth > 0) && !Scr->BeNiceToColormap)
711 GetShadeColors (&tmp_win->border);
712 GetShadeColors (&tmp_win->border_tile);
718 tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->frame_bw;
719 tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height +
720 tmp_win->old_bw - tmp_win->frame_bw;
721 tmp_win->frame_width = tmp_win->attr.width;
722 tmp_win->frame_height = tmp_win->attr.height + tmp_win->title_height;
724 /* done in AddMoveAndResize() - djhjr - 4/14/98
725 tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->frame_bw
726 - tmp_win->frame_bw3D;
727 tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height +
728 tmp_win->old_bw - tmp_win->frame_bw - tmp_win->frame_bw3D;
730 tmp_win->frame_width = tmp_win->attr.width + 2 * tmp_win->frame_bw3D;
731 tmp_win->frame_height = tmp_win->attr.height + tmp_win->title_height +
732 2 * tmp_win->frame_bw3D;
733 /* done in AddMoveAndResize() - djhjr - 4/14/98
734 ConstrainSize (tmp_win, &tmp_win->frame_width, &tmp_win->frame_height);
736 tmp_win->virtual_frame_x = R_TO_V_X(tmp_win->frame_x);
737 tmp_win->virtual_frame_y = R_TO_V_Y(tmp_win->frame_y);
741 valuemask = CWBackPixmap | CWBorderPixel | CWCursor | CWEventMask;
742 attributes.background_pixmap = None;
743 attributes.border_pixel = tmp_win->border;
744 attributes.cursor = Scr->FrameCursor;
745 attributes.event_mask = (SubstructureRedirectMask |
746 ButtonPressMask | ButtonReleaseMask |
747 EnterWindowMask | LeaveWindowMask);
748 if (tmp_win->attr.save_under) {
749 attributes.save_under = True;
750 valuemask |= CWSaveUnder;
754 valuemask = CWBackPixmap | CWBorderPixel | CWCursor | CWEventMask | CWBackPixel;
755 attributes.background_pixmap = None;
757 valuemask = CWBorderPixel | CWCursor | CWEventMask | CWBackPixel;
759 attributes.background_pixel = tmp_win->border.back;
760 attributes.border_pixel = tmp_win->border.back;
761 attributes.cursor = Scr->FrameCursor;
762 attributes.event_mask = (SubstructureRedirectMask |
763 ButtonPressMask | ButtonReleaseMask |
764 EnterWindowMask | LeaveWindowMask | ExposureMask);
765 if (tmp_win->attr.save_under) {
766 attributes.save_under = True;
767 valuemask |= CWSaveUnder;
770 /* djhjr - 9/17/96 - slows down iconify/delete/destroy too much...
771 if (Scr->BackingStore)
773 attributes.backing_store = WhenMapped;
774 valuemask |= CWBackingStore;
778 if (tmp_win->hints.flags & PWinGravity) {
779 attributes.win_gravity = tmp_win->hints.win_gravity;
780 valuemask |= CWWinGravity;
783 tmp_win->frame = XCreateWindow (dpy, Scr->Root, tmp_win->frame_x,
785 (unsigned int) tmp_win->frame_width,
786 (unsigned int) tmp_win->frame_height,
787 (unsigned int) tmp_win->frame_bw,
789 (unsigned int) CopyFromParent,
790 Scr->d_visual, valuemask, &attributes);
792 if (tmp_win->title_height)
794 valuemask = (CWEventMask | CWBorderPixel | CWBackPixel);
795 attributes.event_mask = (KeyPressMask | ButtonPressMask |
796 ButtonReleaseMask | ExposureMask);
798 attributes.border_pixel = tmp_win->border;
800 attributes.border_pixel = tmp_win->title.back;
801 attributes.background_pixel = tmp_win->title.back;
803 /* djhjr - 9/17/96 */
804 if (Scr->BackingStore)
806 attributes.backing_store = WhenMapped;
807 valuemask |= CWBackingStore;
810 tmp_win->title_w = XCreateWindow (dpy, tmp_win->frame,
815 tmp_win->frame_bw3D - tmp_win->frame_bw,
816 tmp_win->frame_bw3D - tmp_win->frame_bw,
818 (unsigned int) tmp_win->attr.width,
819 (unsigned int) Scr->TitleHeight,
820 (unsigned int) tmp_win->frame_bw,
822 (unsigned int) CopyFromParent,
823 Scr->d_visual, valuemask,
827 tmp_win->title_w = 0;
828 tmp_win->squeeze_info = NULL;
831 if (tmp_win->highlight)
834 /* djhjr - 4/19/96 */
835 /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */
836 if (Scr->TitleBevelWidth > 0 && (Scr->Monochrome != COLOR))
837 tmp_win->gray = XCreatePixmapFromBitmapData(dpy, Scr->Root,
838 (char *)black_bits, gray_width, gray_height,
839 tmp_win->border_tile.fore, tmp_win->border_tile.back,
843 tmp_win->gray = XCreatePixmapFromBitmapData(dpy, Scr->Root,
844 gray_bits, gray_width, gray_height,
845 tmp_win->border_tile.fore, tmp_win->border_tile.back,
848 SetBorder (tmp_win, False);
851 tmp_win->gray = None;
853 if (tmp_win->title_w) {
854 CreateWindowTitlebarButtons (tmp_win);
855 ComputeTitleLocation (tmp_win);
856 XMoveWindow (dpy, tmp_win->title_w,
857 tmp_win->title_x, tmp_win->title_y);
858 XDefineCursor(dpy, tmp_win->title_w, Scr->TitleCursor);
861 /* djhjr - 4/19/96 */
863 tmp_win->title_x = tmp_win->frame_bw3D - tmp_win->frame_bw;
864 tmp_win->title_y = tmp_win->frame_bw3D - tmp_win->frame_bw;
867 valuemask = (CWEventMask | CWDontPropagate);
868 attributes.event_mask = (StructureNotifyMask | PropertyChangeMask |
869 ColormapChangeMask | VisibilityChangeMask |
870 EnterWindowMask | LeaveWindowMask);
871 attributes.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask;
872 XChangeWindowAttributes (dpy, tmp_win->w, valuemask, &attributes);
875 XShapeSelectInput (dpy, tmp_win->w, ShapeNotifyMask);
877 if (tmp_win->title_w) {
878 XMapWindow (dpy, tmp_win->title_w);
882 int xws, yws, xbs, ybs;
883 unsigned wws, hws, wbs, hbs;
884 int boundingShaped, clipShaped;
886 XShapeSelectInput (dpy, tmp_win->w, ShapeNotifyMask);
887 XShapeQueryExtents (dpy, tmp_win->w,
888 &boundingShaped, &xws, &yws, &wws, &hws,
889 &clipShaped, &xbs, &ybs, &wbs, &hbs);
890 tmp_win->wShaped = boundingShaped;
893 if (!tmp_win->iconmgr)
894 XAddToSaveSet(dpy, tmp_win->w);
897 XReparentWindow(dpy, tmp_win->w, tmp_win->frame, 0, tmp_win->title_height);
899 XReparentWindow(dpy, tmp_win->w, tmp_win->frame, tmp_win->frame_bw3D,
900 tmp_win->title_height + tmp_win->frame_bw3D);
903 * Reparenting generates an UnmapNotify event, followed by a MapNotify.
904 * Set the map state to FALSE to prevent a transition back to
905 * WithdrawnState in HandleUnmapNotify. Map state gets set correctly
906 * again in HandleMapNotify.
908 tmp_win->mapped = FALSE;
911 * NOW do the move and resize - windows needed to be created
912 * first to accomodate the opaque resources - djhjr - 4/14/98
914 AddMoveAndResize(tmp_win, ask_user);
916 SetupFrame (tmp_win, tmp_win->frame_x, tmp_win->frame_y,
917 tmp_win->frame_width, tmp_win->frame_height, -1, True);
919 /* wait until the window is iconified and the icon window is mapped
920 * before creating the icon window
922 tmp_win->icon_w = None;
924 if (!tmp_win->iconmgr)
926 GrabButtons(tmp_win);
930 (void) AddIconManager(tmp_win);
931 UpdateDesktop(tmp_win);
933 XSaveContext(dpy, tmp_win->w, TwmContext, (caddr_t) tmp_win);
934 XSaveContext(dpy, tmp_win->w, ScreenContext, (caddr_t) Scr);
935 XSaveContext(dpy, tmp_win->frame, TwmContext, (caddr_t) tmp_win);
936 XSaveContext(dpy, tmp_win->frame, ScreenContext, (caddr_t) Scr);
937 if (tmp_win->title_height)
940 int nb = Scr->TBInfo.nleft + Scr->TBInfo.nright;
942 XSaveContext(dpy, tmp_win->title_w, TwmContext, (caddr_t) tmp_win);
943 XSaveContext(dpy, tmp_win->title_w, ScreenContext, (caddr_t) Scr);
944 for (i = 0; i < nb; i++) {
945 XSaveContext(dpy, tmp_win->titlebuttons[i].window, TwmContext,
947 XSaveContext(dpy, tmp_win->titlebuttons[i].window, ScreenContext,
950 if (tmp_win->hilite_w)
952 XSaveContext(dpy, tmp_win->hilite_w, TwmContext, (caddr_t)tmp_win);
953 XSaveContext(dpy, tmp_win->hilite_w, ScreenContext, (caddr_t)Scr);
959 /* if we were in the middle of a menu activated function, regrab
962 if (RootFunction != F_NOFUNCTION)
965 Scr->Newest = tmp_win; /* PF */
966 if (tmp_win->transient && Scr->WarpToTransients) /* PF */
967 WarpToWindow(tmp_win); /* PF,DSE */
974 * AddPaintRealWindows()
976 * a little helper for AddMoveAndResize() - djhjr - 4/15/98
979 AddPaintRealWindows(tmp_win, x, y)
983 /* handled in add_window() now - djhjr - 9/21/99
984 XSetWindowAttributes attr;
986 attr.save_under = True;
987 XChangeWindowAttributes(dpy, tmp_win->frame, CWSaveUnder, &attr);
990 /* don't need to send a configure notify event */
991 SetupWindow(tmp_win, tmp_win->frame_x, tmp_win->frame_y,
992 tmp_win->frame_width, tmp_win->frame_height, -1);
994 XMoveWindow(dpy, tmp_win->frame, x, y);
996 XMapWindow(dpy, tmp_win->frame);
997 XMapSubwindows(dpy, tmp_win->frame);
998 XMapSubwindows(dpy, tmp_win->title_w);
1000 PaintBorderAndTitlebar(tmp_win);
1002 /* djhjr - 4/15/98 */
1003 if (!Scr->NoGrabServer)
1005 /* these allow the application window to be drawn */
1006 XUngrabServer(dpy); XSync(dpy, 0); XGrabServer(dpy);
1012 * AddMoveAndResize()
1014 * was inline in AddWindow() at first call to this function,
1015 * now handles the opaque move and resize resources - djhjr - 4/14/98
1018 AddMoveAndResize(tmp_win, ask_user)
1022 static int PlaceX = PLACEMENT_START;
1023 static int PlaceY = PLACEMENT_START;
1025 int stat, gravx, gravy;
1026 int bw2 = tmp_win->frame_bw * 2;
1027 int wd = tmp_win->attr.width + bw2;
1028 int ht = tmp_win->attr.height + tmp_win->title_height + bw2;
1031 * do any prompting for position
1033 if (HandlingEvents && ask_user) {
1034 if (Scr->RandomPlacement) { /* just stick it somewhere */
1035 if (PlaceX + wd > Scr->MyDisplayWidth) {
1036 /* submitted by Seth Robertson <seth@baka.org> - 8/25/02 */
1037 if (PLACEMENT_START + wd < Scr->MyDisplayWidth)
1038 PlaceX = PLACEMENT_START;
1040 PlaceX = tmp_win->frame_bw;
1041 if (wd < Scr->MyDisplayWidth)
1042 PlaceX += (Scr->MyDisplayWidth - wd) / 2;
1045 if (PlaceY + ht > Scr->MyDisplayHeight) {
1046 /* submitted by Seth Robertson <seth@baka.org> - 8/25/02 */
1047 if (PLACEMENT_START + ht < Scr->MyDisplayHeight)
1048 PlaceY = PLACEMENT_START;
1050 PlaceY = tmp_win->title_height + tmp_win->frame_bw;
1051 if (ht < Scr->MyDisplayHeight)
1052 PlaceY += (Scr->MyDisplayHeight - ht) / 2;
1056 tmp_win->attr.x = PlaceX;
1057 tmp_win->attr.y = PlaceY;
1058 PlaceX += PLACEMENT_INCR;
1059 PlaceY += PLACEMENT_INCR;
1060 } else if (Scr->PointerPlacement) {
1062 if (!XQueryPointer (dpy, Scr->Root, &JunkRoot,
1063 &JunkChild, &JunkX, &JunkY,
1064 &AddingX, &AddingY, &JunkMask))
1066 /* fit window onto screen */
1067 if (Scr->WarpSnug) {
1068 if (JunkX + wd > Scr->MyDisplayWidth)
1069 JunkX -= (JunkX + wd - Scr->MyDisplayWidth);
1070 if (JunkY + tmp_win->attr.height > Scr->MyDisplayHeight)
1071 JunkY -= (JunkY + tmp_win->attr.height - Scr->MyDisplayHeight);
1073 tmp_win->attr.x = JunkX;
1074 tmp_win->attr.y = JunkY;
1075 } else { /* else prompt */
1076 if (!(tmp_win->wmhints && tmp_win->wmhints->flags & StateHint &&
1077 tmp_win->wmhints->initial_state == IconicState))
1079 Bool firsttime = True;
1081 /* djhjr - 11/15/01 */
1082 Bool doorismapped = False;
1083 TwmDoor *door = NULL;
1084 XFindContext(dpy, tmp_win->w, DoorContext, (caddr_t *)&door);
1086 /* better wait until all the mouse buttons have been
1096 if (!XQueryPointer (dpy, Scr->Root, &JunkRoot,
1097 &JunkChild, &JunkX, &JunkY,
1098 &AddingX, &AddingY, &JunkMask))
1101 JunkMask &= (Button1Mask | Button2Mask | Button3Mask |
1102 Button4Mask | Button5Mask);
1105 * watch out for changing screens
1108 if (JunkRoot != Scr->Root) {
1109 register int scrnum;
1111 for (scrnum = 0; scrnum < NumScreens; scrnum++) {
1112 if (JunkRoot == RootWindow (dpy, scrnum)) break;
1115 if (scrnum != NumScreens) PreviousScreen = scrnum;
1121 * wait for buttons to come up; yuck
1123 if (JunkMask != 0) continue;
1126 * this will cause a warp to the indicated root
1128 stat = XGrabPointer(dpy, Scr->Root, False,
1129 ButtonPressMask | ButtonReleaseMask |
1130 PointerMotionMask | PointerMotionHintMask,
1131 GrabModeAsync, GrabModeAsync,
1132 Scr->Root, UpperLeftCursor, CurrentTime);
1134 if (stat == GrabSuccess)
1138 /* djhjr - 4/15/98 */
1139 if (Scr->NoGrabServer) XUngrabServer(dpy);
1141 /* use initialized size... djhjr - 5/9/96
1143 #ifndef NO_I18N_SUPPORT
1144 width = (SIZE_HINDENT + MyFont_TextWidth (&Scr->SizeFont,
1146 width = (SIZE_HINDENT + XTextWidth (Scr->SizeFont.font,
1148 tmp_win->name, namelen));
1149 height = Scr->SizeFont.height + SIZE_VINDENT * 2;
1152 XResizeWindow (dpy, Scr->SizeWindow, width + SIZE_HINDENT, height);
1154 XResizeWindow (dpy, Scr->SizeWindow, Scr->SizeStringOffset +
1155 Scr->SizeStringWidth, height);
1158 XMapRaised(dpy, Scr->SizeWindow);
1159 InstallRootColormap();
1161 /* DisplayPosition overwrites it anyway... djhjr - 5/9/96
1162 * font was font.font->fid - djhjr - 9/14/03 *
1163 FBF(Scr->DefaultC.fore, Scr->DefaultC.back, Scr->SizeFont);
1165 #ifndef NO_I18N_SUPPORT
1166 MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont,
1168 XDrawImageString (dpy, Scr->SizeWindow,
1170 Scr->NormalGC, SIZE_HINDENT,
1172 SIZE_VINDENT + Scr->SizeFont.font->ascent,
1174 SIZE_VINDENT + Scr->SizeFont.ascent,
1175 tmp_win->name, namelen);
1179 AddingW = tmp_win->attr.width + bw2;
1180 AddingH = tmp_win->attr.height + tmp_win->title_height + bw2;
1182 MoveOutline(Scr->Root, AddingX, AddingY, AddingW, AddingH,
1183 tmp_win->frame_bw, tmp_win->title_height);
1185 AddingW = tmp_win->attr.width + bw2 + 2 * tmp_win->frame_bw3D;
1186 AddingH = tmp_win->attr.height + tmp_win->title_height +
1187 bw2 + 2 * tmp_win->frame_bw3D;
1189 /* added this 'if ... else' - djhjr - 4/14/98 */
1190 if (tmp_win->opaque_move)
1192 AddPaintRealWindows(tmp_win, AddingX, AddingY);
1194 /* djhjr - 11/15/01 */
1195 if (door && !doorismapped)
1197 XMapWindow(dpy, door->w);
1198 RedoDoorName(tmp_win, door);
1199 doorismapped = True;
1203 MoveOutline(Scr->Root, AddingX, AddingY, AddingW, AddingH,
1204 tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D);
1206 /* djhjr - 4/17/98 */
1207 if (Scr->VirtualReceivesMotionEvents)
1209 tmp_win->virtual_frame_x = R_TO_V_X(AddingX);
1210 tmp_win->virtual_frame_y = R_TO_V_Y(AddingY);
1211 UpdateDesktop(tmp_win);
1214 /* DisplayPosition() overwrites it anyway... djhjr - 5/9/96
1216 #ifndef NO_I18N_SUPPORT
1217 MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont,
1220 XDrawImageString (dpy, Scr->SizeWindow,
1222 Scr->NormalGC, width,
1224 SIZE_VINDENT + Scr->SizeFont.font->ascent, ": ", 2);
1226 SIZE_VINDENT + Scr->SizeFont.ascent, ": ", 2);
1229 /* djhjr - 4/27/96 */
1230 DisplayPosition (AddingX, AddingY);
1234 XMaskEvent(dpy, ButtonPressMask | PointerMotionMask, &event);
1236 if (Event.type == MotionNotify) {
1237 /* discard any extra motion events before a release */
1238 while(XCheckMaskEvent(dpy,
1239 ButtonMotionMask | ButtonPressMask, &Event))
1240 if (Event.type == ButtonPress)
1244 if (event.type == ButtonPress) {
1245 AddingX = event.xbutton.x_root;
1246 AddingY = event.xbutton.y_root;
1248 /* DontMoveOff prohibits user form off-screen placement */
1249 if (Scr->DontMoveOff)
1251 int AddingR, AddingB;
1253 AddingR = AddingX + AddingW;
1254 AddingB = AddingY + AddingH;
1258 if (AddingR > Scr->MyDisplayWidth)
1259 AddingX = Scr->MyDisplayWidth - AddingW;
1263 if (AddingB > Scr->MyDisplayHeight)
1264 AddingY = Scr->MyDisplayHeight - AddingH;
1270 if (event.type != MotionNotify) {
1274 XQueryPointer(dpy, Scr->Root, &JunkRoot, &JunkChild,
1275 &JunkX, &JunkY, &AddingX, &AddingY, &JunkMask);
1277 if (Scr->DontMoveOff)
1279 int AddingR, AddingB;
1281 AddingR = AddingX + AddingW;
1282 AddingB = AddingY + AddingH;
1286 if (AddingR > Scr->MyDisplayWidth)
1287 AddingX = Scr->MyDisplayWidth - AddingW;
1291 if (AddingB > Scr->MyDisplayHeight)
1292 AddingY = Scr->MyDisplayHeight - AddingH;
1296 MoveOutline(Scr->Root, AddingX, AddingY, AddingW, AddingH,
1297 tmp_win->frame_bw, tmp_win->title_height);
1299 /* added this 'if ... else' - djhjr - 4/14/98 */
1300 if (tmp_win->opaque_move)
1302 XMoveWindow(dpy, tmp_win->frame, AddingX, AddingY);
1303 PaintBorderAndTitlebar(tmp_win);
1305 /* djhjr - 4/15/98 */
1306 if (!Scr->NoGrabServer)
1308 /* these allow the application window to be drawn */
1309 XUngrabServer(dpy); XSync(dpy, 0); XGrabServer(dpy);
1313 MoveOutline(Scr->Root, AddingX, AddingY, AddingW, AddingH,
1314 tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D);
1316 /* djhjr - 4/17/98 */
1317 if (Scr->VirtualReceivesMotionEvents)
1319 tmp_win->virtual_frame_x = R_TO_V_X(AddingX);
1320 tmp_win->virtual_frame_y = R_TO_V_Y(AddingY);
1321 MoveResizeDesktop(tmp_win, Scr->NoRaiseResize);
1324 /* djhjr - 4/27/96 */
1325 DisplayPosition (AddingX, AddingY);
1329 if (event.xbutton.button == Button2) {
1332 /* AddStartResize() overwrites it anyway... djhjr - 5/9/96
1333 Scr->SizeStringOffset = width +
1335 #ifndef NO_I18N_SUPPORT
1336 MyFont_TextWidth(&Scr->SizeFont, ": ", 2);
1338 XTextWidth(Scr->SizeFont.font, ": ", 2);
1340 XResizeWindow (dpy, Scr->SizeWindow, Scr->SizeStringOffset +
1341 Scr->SizeStringWidth, height);
1343 #ifndef NO_I18N_SUPPORT
1344 MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont,
1346 XDrawImageString (dpy, Scr->SizeWindow,
1348 Scr->NormalGC, width,
1350 SIZE_VINDENT + Scr->SizeFont.font->ascent,
1352 SIZE_VINDENT + Scr->SizeFont.ascent,
1356 /* djhjr - 4/15/98 */
1357 if (!tmp_win->opaque_move && tmp_win->opaque_resize)
1359 /* erase the move outline */
1360 MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0);
1362 AddPaintRealWindows(tmp_win, AddingX, AddingY);
1364 /* djhjr - 11/15/01 */
1365 if (door && !doorismapped)
1367 XMapWindow(dpy, door->w);
1368 RedoDoorName(tmp_win, door);
1369 doorismapped = True;
1374 if (0/*Scr->AutoRelativeResize*/)
1375 My R5 vtvwm came with this commented out, always 0.
1378 if (Scr->AutoRelativeResize)
1380 int dx = (tmp_win->attr.width / 4);
1381 int dy = (tmp_win->attr.height / 4);
1383 #define HALF_AVE_CURSOR_SIZE 8 /* so that it is visible */
1384 if (dx < HALF_AVE_CURSOR_SIZE) dx = HALF_AVE_CURSOR_SIZE;
1385 if (dy < HALF_AVE_CURSOR_SIZE) dy = HALF_AVE_CURSOR_SIZE;
1386 #undef HALF_AVE_CURSOR_SIZE
1387 dx += (tmp_win->frame_bw + 1);
1388 dy += (bw2 + tmp_win->title_height + 1);
1389 if (AddingX + dx >= Scr->MyDisplayWidth)
1390 dx = Scr->MyDisplayWidth - AddingX - 1;
1391 if (AddingY + dy >= Scr->MyDisplayHeight)
1392 dy = Scr->MyDisplayHeight - AddingY - 1;
1393 if (dx > 0 && dy > 0)
1394 XWarpPointer (dpy, None, None, 0, 0, 0, 0, dx, dy);
1396 XWarpPointer (dpy, None, Scr->Root, 0, 0, 0, 0,
1397 AddingX + AddingW/2, AddingY + AddingH/2);
1399 AddStartResize(tmp_win, AddingX, AddingY, AddingW, AddingH);
1406 ButtonReleaseMask | ButtonMotionMask, &event);
1408 if (Event.type == MotionNotify) {
1409 /* discard any extra motion events before a release */
1410 while(XCheckMaskEvent(dpy,
1411 ButtonMotionMask | ButtonReleaseMask, &Event))
1412 if (Event.type == ButtonRelease)
1416 if (event.type == ButtonRelease)
1418 AddEndResize(tmp_win);
1420 /* don't need to send a configure notify event - djhjr - 4/15/98 */
1421 if (tmp_win->opaque_move && !tmp_win->opaque_resize)
1422 SetupWindow(tmp_win, AddingX, AddingY, AddingW, AddingH, -1);
1424 /* djhjr - 11/15/01 */
1425 if (!tmp_win->opaque_resize && door && doorismapped)
1426 RedoDoorName(tmp_win, door);
1431 if (event.type != MotionNotify) {
1436 * XXX - if we are going to do a loop, we ought to consider
1437 * using multiple GXxor lines so that we don't need to
1440 XQueryPointer(dpy, Scr->Root, &JunkRoot, &JunkChild,
1441 &JunkX, &JunkY, &AddingX, &AddingY, &JunkMask);
1443 if (lastx != AddingX || lasty != AddingY)
1445 DoResize(AddingX, AddingY, tmp_win);
1452 } /* if (event.xbutton.button == Button2) */
1453 else if (event.xbutton.button == Button3)
1455 int maxw = Scr->MyDisplayWidth - AddingX - bw2;
1456 int maxh = Scr->MyDisplayHeight - AddingY - bw2;
1459 * Make window go to bottom of screen, and clip to right edge.
1460 * This is useful when popping up large windows and fixed
1461 * column text windows.
1463 if (AddingW > maxw) AddingW = maxw;
1466 ConstrainSize (tmp_win, &AddingW, &AddingH); /* w/o borders */
1470 /* don't need to send a configure notify event - djhjr - 4/15/98 */
1471 SetupWindow(tmp_win, AddingX, AddingY, AddingW, AddingH, -1);
1473 /* djhjr - 11/15/01 */
1474 if (!tmp_win->opaque_resize && door && doorismapped)
1475 RedoDoorName(tmp_win, door);
1480 XMaskEvent(dpy, ButtonReleaseMask, &event);
1483 /* erase the move outline */
1484 MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0);
1486 XUnmapWindow(dpy, Scr->SizeWindow);
1487 UninstallRootColormap();
1488 XUngrabPointer(dpy, CurrentTime);
1491 tmp_win->attr.x = AddingX;
1492 tmp_win->attr.y = AddingY + tmp_win->title_height;
1494 tmp_win->attr.x = AddingX + tmp_win->frame_bw + tmp_win->frame_bw3D;
1495 tmp_win->attr.y = AddingY + tmp_win->title_height +
1496 tmp_win->frame_bw + tmp_win->frame_bw3D;
1499 tmp_win->attr.width = AddingW - bw2;
1500 tmp_win->attr.height = AddingH - tmp_win->title_height - bw2;
1502 tmp_win->attr.width = AddingW - bw2 - 2 * tmp_win->frame_bw3D;
1503 tmp_win->attr.height = AddingH - tmp_win->title_height -
1504 bw2 - 2 * tmp_win->frame_bw3D;
1506 /* un-grabbed in the caller AddWindow() on return - djhjr - 4/15/98
1512 /* djhjr - 6/4/98 */
1513 if (Scr->VirtualReceivesMotionEvents && !tmp_win->opaque_move)
1515 XUnmapWindow(dpy, Scr->VirtualDesktopDisplay);
1516 XMapWindow(dpy, Scr->VirtualDesktopDisplay);
1518 } else { /* put it where asked, mod title bar */
1519 /* interpret the position specified as a virtual one if asked */
1521 /* added 'FixManagedVirtualGeometries' - djhjr - 1/6/98 */
1522 /* added test for 'PPosition' - submitted by Michael Dales */
1523 if (Scr->GeometriesAreVirtual ||
1524 (!Scr->GeometriesAreVirtual &&
1526 ( ( (Scr->FixManagedVirtualGeometries &&
1527 !tmp_win->transient) ||
1528 (Scr->FixTransientVirtualGeometries &&
1530 ) && (tmp_win->hints.flags & PPosition)
1536 * If virtual geometries is set, or virtual geometries
1537 * isn't set and (nailed or (fix virtual geometries and
1538 * preferred position)). This is a bug workaround -- DSE
1541 tmp_win->attr.x = V_TO_R_X(tmp_win->attr.x);
1542 tmp_win->attr.y = V_TO_R_Y(tmp_win->attr.y);
1545 GetGravityOffsets (tmp_win, &gravx, &gravy);
1547 /* if the gravity is towards the top, move it by the title height */
1548 if (gravy < 0) tmp_win->attr.y -= gravy * tmp_win->title_height;
1551 /* should never have been - djhjr - 9/21/99
1552 if (tmp_win->opaque_move)
1554 XSetWindowAttributes attr;
1556 attr.save_under = False;
1557 XChangeWindowAttributes(dpy, tmp_win->frame, CWSaveUnder, &attr);
1562 * consider client borderwidths based on the ClientBorderWidth and
1563 * RandomPlacement resources, PPosition with the UsePPosition resource,
1564 * and the USPosition spec - djhjr - 6/3/98
1566 tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->frame_bw
1567 - tmp_win->frame_bw3D;
1568 tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height +
1569 tmp_win->old_bw - tmp_win->frame_bw - tmp_win->frame_bw3D;
1571 tmp_win->frame_x = tmp_win->attr.x -
1572 tmp_win->frame_bw - tmp_win->frame_bw3D;
1573 tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height -
1574 tmp_win->frame_bw - tmp_win->frame_bw3D;
1575 /* Not needed? - submitted by Jonathan Paisley - 11/8/02
1576 if (Scr->ClientBorderWidth || !ask_user)
1578 tmp_win->frame_x += tmp_win->old_bw;
1579 tmp_win->frame_y += tmp_win->old_bw;
1583 tmp_win->frame_width = tmp_win->attr.width + 2 * tmp_win->frame_bw3D;
1584 tmp_win->frame_height = tmp_win->attr.height + tmp_win->title_height +
1585 2 * tmp_win->frame_bw3D;
1586 ConstrainSize (tmp_win, &tmp_win->frame_width, &tmp_win->frame_height);
1588 tmp_win->virtual_frame_x = R_TO_V_X(tmp_win->frame_x);
1589 tmp_win->virtual_frame_y = R_TO_V_Y(tmp_win->frame_y);
1592 fprintf(stderr, " position window %d, %d %dx%d\n",
1595 tmp_win->attr.width,
1596 tmp_win->attr.height);
1601 /***********************************************************************
1604 * MappedNotOverride - checks to see if we should really
1605 * put a twm frame on the window
1608 * TRUE - go ahead and frame the window
1609 * FALSE - don't frame the window
1612 * w - the window to check
1614 ***********************************************************************
1618 MappedNotOverride(w)
1621 XWindowAttributes wa;
1623 XGetWindowAttributes(dpy, w, &wa);
1624 return ((wa.map_state != IsUnmapped) && (wa.override_redirect != True));
1628 /***********************************************************************
1631 * AddDefaultBindings - attach default bindings so that naive users
1632 * don't get messed up if they provide a minimal twmrc.
1634 static void do_add_binding (button, context, modifier, func)
1635 int button, context, modifier;
1638 MouseButton *mb = &Scr->Mouse[button][context][modifier];
1640 if (mb->func) return; /* already defined */
1646 void AddDefaultBindings ()
1649 * The bindings are stored in Scr->Mouse, indexed by
1650 * Mouse[button_number][C_context][modifier].
1653 #define NoModifierMask 0
1655 do_add_binding (Button1, C_TITLE, NoModifierMask, F_MOVE);
1656 do_add_binding (Button1, C_ICON, NoModifierMask, F_ICONIFY);
1657 do_add_binding (Button1, C_ICONMGR, NoModifierMask, F_ICONIFY);
1658 do_add_binding (Button1, C_VIRTUAL, NoModifierMask, F_MOVESCREEN);
1659 do_add_binding (Button1, C_VIRTUAL_WIN, NoModifierMask, F_MOVESCREEN);
1661 do_add_binding (Button2, C_TITLE, NoModifierMask, F_RAISELOWER);
1662 do_add_binding (Button2, C_ICON, NoModifierMask, F_ICONIFY);
1663 do_add_binding (Button2, C_ICONMGR, NoModifierMask, F_ICONIFY);
1664 do_add_binding (Button2, C_VIRTUAL, NoModifierMask, F_MOVESCREEN);
1665 do_add_binding (Button2, C_VIRTUAL_WIN, NoModifierMask, F_MOVESCREEN);
1667 #undef NoModifierMask
1673 /***********************************************************************
1676 * GrabButtons - grab needed buttons for the window
1679 * tmp_win - the twm window structure to use
1681 ***********************************************************************
1685 GrabButtons(tmp_win)
1690 for (i = 0; i < MAX_BUTTONS+1; i++)
1692 for (j = 0; j < MOD_SIZE; j++)
1694 if (Scr->Mouse[i][C_WINDOW][j].func != F_NOFUNCTION)
1696 /* twm used to do this grab on the application main window,
1697 * tmp_win->w . This was not ICCCM complient and was changed.
1699 XGrabButton(dpy, i, j, tmp_win->frame,
1700 True, ButtonPressMask | ButtonReleaseMask,
1701 GrabModeAsync, GrabModeAsync, None,
1708 /***********************************************************************
1711 * GrabKeys - grab needed keys for the window
1714 * tmp_win - the twm window structure to use
1716 ***********************************************************************
1719 /* djhjr - 9/10/03 */
1727 XGrabKey(dpy, k->keycode, k->mods, w, True, GrabModeAsync, GrabModeAsync);
1729 for (i = 1; i <= Scr->IgnoreModifiers; i++)
1730 if ((Scr->IgnoreModifiers & i) == i)
1731 XGrabKey(dpy, k->keycode, k->mods | i, w, True,
1732 GrabModeAsync, GrabModeAsync);
1735 /* djhjr - 9/10/03 */
1743 XUngrabKey(dpy, k->keycode, k->mods, w);
1745 for (i = 1; i <= Scr->IgnoreModifiers; i++)
1746 if ((Scr->IgnoreModifiers & i) == i)
1747 XUngrabKey(dpy, k->keycode, k->mods | i, w);
1757 for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next)
1763 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->w, True,
1764 GrabModeAsync, GrabModeAsync);
1766 GrabModKeys(tmp_win->w, tmp);
1770 if (tmp_win->icon_w)
1772 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->icon_w, True,
1773 GrabModeAsync, GrabModeAsync);
1775 GrabModKeys(tmp_win->icon_w, tmp);
1778 if (tmp_win->title_w)
1780 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->title_w, True,
1781 GrabModeAsync, GrabModeAsync);
1783 GrabModKeys(tmp_win->title_w, tmp);
1788 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->w, True,
1789 GrabModeAsync, GrabModeAsync);
1791 GrabModKeys(tmp_win->w, tmp);
1792 if (tmp_win->icon_w)
1794 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->icon_w, True,
1795 GrabModeAsync, GrabModeAsync);
1797 GrabModKeys(tmp_win->icon_w, tmp);
1798 if (tmp_win->title_w)
1800 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->title_w, True,
1801 GrabModeAsync, GrabModeAsync);
1803 GrabModKeys(tmp_win->title_w, tmp);
1809 XGrabKey(dpy, tmp->keycode, tmp->mods, Scr->Root, True,
1810 GrabModeAsync, GrabModeAsync);
1812 GrabModKeys(Scr->Root, tmp);
1817 for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next)
1819 if (tmp->cont == C_ICONMGR && !Scr->NoIconManagers)
1821 for (p = &Scr->iconmgr; p != NULL; p = p->next)
1824 XUngrabKey(dpy, tmp->keycode, tmp->mods, p->twm_win->w);
1826 UngrabModKeys(p->twm_win->w, tmp);
1832 static Window CreateHighlightWindow (tmp_win)
1835 XSetWindowAttributes attributes; /* attributes for create windows */
1839 unsigned long valuemask;
1840 unsigned int pm_numcolors;
1841 /* added '- 2' - djhjr - 10/18/02 */
1842 int h = (Scr->TitleHeight - 2 * Scr->FramePadding) - 2;
1846 #ifndef NO_I18N_SUPPORT
1847 int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1);
1850 int en = XTextWidth(Scr->TitleBarFont.font, "n", 1);
1854 int width = Scr->TBInfo.titlex + tmp_win->name_width + 2 * en;
1858 * If a special highlight pixmap was given, use that. Otherwise,
1859 * use a nice, even gray pattern. The old horizontal lines look really
1860 * awful on interlaced monitors (as well as resembling other looks a
1861 * little bit too closely), but can be used by putting
1863 * Pixmaps { TitleHighlight "hline2" }
1865 * (or whatever the horizontal line bitmap is named) in the startup
1866 * file. If all else fails, use the foreground color to look like a
1871 * re-written to use an Image structure for XPM support
1875 #ifdef ORIGINAL_PIXMAPS
1876 if (!Scr->hilitePm) {
1878 /* djhjr - 4/20/96 */
1879 /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */
1880 if (Scr->TitleBevelWidth > 0 && (Scr->Monochrome != COLOR))
1881 Scr->hilitePm = XCreateBitmapFromData (dpy, tmp_win->title_w,
1882 (char *)black_bits, gray_width, gray_height);
1884 Scr->hilitePm = XCreateBitmapFromData (dpy, tmp_win->title_w,
1885 gray_bits, gray_width, gray_height);
1887 Scr->hilite_pm_width = gray_width;
1888 Scr->hilite_pm_height = gray_height;
1890 if (Scr->hilitePm) {
1891 pm = XCreatePixmap (dpy, tmp_win->title_w,
1892 Scr->hilite_pm_width, Scr->hilite_pm_height,
1894 gcv.foreground = tmp_win->title.fore;
1895 gcv.background = tmp_win->title.back;
1896 gcv.graphics_exposures = False;
1897 gc = XCreateGC (dpy, pm,
1898 (GCForeground|GCBackground|GCGraphicsExposures),
1901 XCopyPlane (dpy, Scr->hilitePm, pm, gc, 0, 0,
1902 Scr->hilite_pm_width, Scr->hilite_pm_height,
1906 XFreePixmap (dpy, pm);
1911 valuemask = CWBackPixmap;
1912 attributes.background_pixmap = pm;
1914 valuemask = CWBackPixel;
1915 attributes.background_pixel = tmp_win->title.fore;
1917 #else /* ORIGINAL_PIXMAPS */
1920 Scr->hilitePm = (Image *)malloc(sizeof(Image));
1923 Scr->hilitePm->width = gray_width;
1924 Scr->hilitePm->height = gray_height;
1925 Scr->hilitePm->mask = None;
1927 /* djhjr - 4/20/96 */
1928 /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */
1929 if (Scr->TitleBevelWidth > 0 && (Scr->Monochrome != COLOR))
1930 Scr->hilitePm->pixmap = XCreateBitmapFromData (dpy,
1931 tmp_win->title_w, (char *)black_bits,
1932 Scr->hilitePm->width, Scr->hilitePm->height);
1934 Scr->hilitePm->pixmap = XCreateBitmapFromData (dpy,
1935 tmp_win->title_w, gray_bits,
1936 Scr->hilitePm->width, Scr->hilitePm->height);
1942 /* djhjr - 5/23/98 9/2/98 */
1943 #ifndef NO_XPM_SUPPORT
1944 /* removed this for non-transparent pixmaps - djhjr - 5/26/98
1945 if (Scr->hilitePm->mask != None)
1947 pm_numcolors = SetPixmapsBackground(Scr->hilitePm, Scr->Root,
1948 tmp_win->title.back);
1952 * Modified to handle non-transparent pixmaps - Jason Gloudon
1954 if (Scr->hilitePm->pixmap)
1956 if (pm_numcolors > 2) /* not a bitmap */
1958 valuemask = CWBackPixmap;
1959 attributes.background_pixmap = Scr->hilitePm->pixmap;
1963 pm = XCreatePixmap (dpy, tmp_win->title_w,
1964 Scr->hilitePm->width, Scr->hilitePm->height,
1967 gcv.foreground = tmp_win->title.fore;
1968 gcv.background = tmp_win->title.back;
1969 gcv.graphics_exposures = False;
1971 gc = XCreateGC (dpy, pm,
1972 (GCForeground | GCBackground | GCGraphicsExposures),
1977 /* the copy plane works on color ! */
1978 XCopyPlane (dpy, Scr->hilitePm->pixmap, pm, gc, 0, 0,
1979 Scr->hilitePm->width, Scr->hilitePm->height,
1984 valuemask = CWBackPixmap;
1985 attributes.background_pixmap = pm;
1989 valuemask = CWBackPixel;
1990 attributes.background_pixel = tmp_win->title.fore;
1996 valuemask = CWBackPixel;
1997 attributes.background_pixel = tmp_win->title.fore;
1999 #endif /* ORIGINAL_PIXMAPS */
2001 /* djhjr - 10/18/02 */
2003 /* djhjr - 4/19/96 */
2004 /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */
2005 if (Scr->TitleBevelWidth > 0)
2007 w = XCreateWindow (dpy, tmp_win->title_w, 0, Scr->FramePadding + 2,
2008 (unsigned int) Scr->TBInfo.width, (unsigned int) (h - 4),
2011 w = XCreateWindow (dpy, tmp_win->title_w, 0, Scr->FramePadding + 3,
2012 (unsigned int) Scr->TBInfo.width, (unsigned int) (h - 6),
2014 w = XCreateWindow (dpy, tmp_win->title_w, width, Scr->FramePadding + 4,
2015 ComputeHighlightWindowWidth(tmp_win), (unsigned int) (h - 8),
2018 Scr->d_depth, (unsigned int) CopyFromParent,
2019 Scr->d_visual, valuemask, &attributes);
2023 w = XCreateWindow (dpy, tmp_win->title_w, 0, Scr->FramePadding,
2024 (unsigned int) Scr->TBInfo.width, (unsigned int) h,
2026 w = XCreateWindow (dpy, tmp_win->title_w, width, Scr->FramePadding + 2,
2027 ComputeHighlightWindowWidth(tmp_win), (unsigned int) (h - 4),
2029 Scr->d_depth, (unsigned int) CopyFromParent,
2030 Scr->d_visual, valuemask, &attributes);
2032 w = XCreateWindow (dpy, tmp_win->title_w,
2033 tmp_win->highlightx, Scr->FramePadding + 1,
2034 ComputeHighlightWindowWidth(tmp_win), (unsigned int) h,
2036 Scr->d_depth, (unsigned int) CopyFromParent,
2037 Scr->d_visual, valuemask, &attributes);
2040 if (pm) XFreePixmap (dpy, pm);
2046 void ComputeCommonTitleOffsets ()
2048 /* djhjr - 9/14/03 */
2049 #ifndef NO_I18N_SUPPORT
2050 int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1);
2052 /* djhjr - 10/18/02 */
2053 int en = XTextWidth(Scr->TitleBarFont.font, "n", 1);
2056 int buttonwidth = (Scr->TBInfo.width + Scr->TBInfo.pad);
2058 Scr->TBInfo.leftx = Scr->TBInfo.rightoff = Scr->FramePadding;
2060 if (Scr->TBInfo.nleft > 0)
2061 Scr->TBInfo.leftx += Scr->ButtonIndent;
2063 /* 'en' was 'Scr->TitlePadding' - djhjr - 10/18/02 */
2064 Scr->TBInfo.titlex = (Scr->TBInfo.leftx +
2065 (Scr->TBInfo.nleft * buttonwidth) - Scr->TBInfo.pad +
2068 if (Scr->TBInfo.nright > 0)
2069 Scr->TBInfo.rightoff += (Scr->ButtonIndent +
2070 ((Scr->TBInfo.nright * buttonwidth) -
2075 void ComputeWindowTitleOffsets (tmp_win, width, squeeze)
2080 /* djhjr - 9/14/03 */
2081 #ifndef NO_I18N_SUPPORT
2082 int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1);
2084 /* djhjr - 10/18/02 */
2085 int en = XTextWidth(Scr->TitleBarFont.font, "n", 1);
2088 /* added 'en' - djhjr - 10/18/02 */
2089 tmp_win->highlightx = Scr->TBInfo.titlex + tmp_win->name_width + en;
2093 * was 'Scr->use3Dtitles' - djhjr - 8/11/98 *
2094 if (Scr->TitleBevelWidth > 0)
2097 #ifndef NO_I18N_SUPPORT
2098 int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1);
2100 int en = XTextWidth(Scr->TitleBarFont.font, "n", 1);
2102 tmp_win->highlightx += en;
2104 * rem'd out - djhjr - 4/19/96 *
2105 * reinstated - djhjr - 4/1/98 *
2106 tmp_win->highlightx += 6;
2109 if (tmp_win->hilite_w || Scr->TBInfo.nright > 0)
2110 tmp_win->highlightx += Scr->TitlePadding;
2113 tmp_win->rightx = width - Scr->TBInfo.rightoff;
2115 if (squeeze && tmp_win->squeeze_info)
2117 /* djhjr - 3/13/97 8/11/98 */
2118 /* this used to care about title bevels - djhjr - 10/18/02 */
2119 int rx = tmp_win->highlightx +
2120 ((tmp_win->titlehighlight) ? Scr->TitleHeight * 2 : 0);
2122 if (rx < tmp_win->rightx) tmp_win->rightx = rx;
2130 * ComputeTitleLocation - calculate the position of the title window.
2132 * substantially re-written - djhjr - 1/8/98
2134 void ComputeTitleLocation (tmp)
2137 tmp->title_x = tmp->frame_bw3D - tmp->frame_bw;
2138 tmp->title_y = tmp->frame_bw3D - tmp->frame_bw;
2140 if (tmp->squeeze_info)
2142 SqueezeInfo *si = tmp->squeeze_info;
2144 int fw = tmp->frame_bw + tmp->frame_bw3D;
2146 if (si->denom != 0 && si->num != 0)
2147 basex = ((tmp->frame_width - tmp->title_width) / si->denom) * si->num + fw;
2149 if (si->denom == 0 && si->num != 0)
2150 basex = si->num + fw;
2152 switch (si->justify)
2155 basex = tmp->title_x + fw;
2158 basex = tmp->frame_width / 2 - (tmp->title_width / 2 - fw);
2161 basex = tmp->frame_width - tmp->title_width;
2165 if (basex > tmp->frame_width - tmp->title_width)
2166 basex = tmp->frame_width - tmp->title_width;
2168 basex = tmp->title_x + fw;
2170 tmp->title_x = basex - fw;
2175 static void CreateWindowTitlebarButtons (tmp_win)
2178 unsigned long valuemask; /* mask for create windows */
2179 XSetWindowAttributes attributes; /* attributes for create windows */
2182 int boxwidth = Scr->TBInfo.width + Scr->TBInfo.pad;
2183 unsigned int h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
2184 int x, y = Scr->FramePadding + Scr->ButtonIndent; /* init - djhjr - 10/18/02 */
2185 int nb, leftx, rightx;
2187 if (tmp_win->title_height == 0)
2189 tmp_win->hilite_w = 0;
2194 * create the title bar windows; let the event handler deal with painting
2195 * so that we don't have to spend two pixmaps (or deal with hashing)
2197 ComputeWindowTitleOffsets (tmp_win, tmp_win->attr.width, False);
2200 leftx = y = Scr->TBInfo.leftx;
2202 leftx = Scr->TBInfo.leftx;
2203 rightx = tmp_win->rightx;
2205 attributes.background_pixel = tmp_win->title.back;
2206 attributes.border_pixel = tmp_win->title.fore;
2207 attributes.event_mask = (ButtonPressMask | ButtonReleaseMask | ExposureMask);
2208 attributes.cursor = Scr->ButtonCursor;
2210 valuemask = (CWWinGravity | CWBackPixel | CWBorderPixel | CWEventMask | CWCursor);
2212 tmp_win->titlebuttons = NULL;
2213 nb = Scr->TBInfo.nleft + Scr->TBInfo.nright;
2215 tmp_win->titlebuttons = (TBWindow *) malloc (nb * sizeof(TBWindow));
2216 if (!tmp_win->titlebuttons) {
2217 fprintf (stderr, "%s: unable to allocate %d titlebuttons\n",
2220 for (tb = Scr->TBInfo.head, tbw = tmp_win->titlebuttons; tb;
2221 tb = tb->next, tbw++) {
2222 if (tb->rightside) {
2225 attributes.win_gravity = NorthEastGravity;
2229 attributes.win_gravity = NorthWestGravity;
2232 tbw->window = XCreateWindow (dpy, tmp_win->title_w, x, y, h, h,
2233 (unsigned int) Scr->TBInfo.border,
2234 0, (unsigned int) CopyFromParent,
2235 (Visual *) CopyFromParent,
2236 valuemask, &attributes);
2239 } /* end for(...) */
2244 tmp_win->hilite_w = (tmp_win->titlehighlight
2245 ? CreateHighlightWindow (tmp_win) : None);
2247 XMapSubwindows(dpy, tmp_win->title_w);
2250 if (tmp_win->hilite_w)
2251 XUnmapWindow(dpy, tmp_win->hilite_w);
2253 PaintTitleHighlight(tmp_win, off);
2255 /* was '!Scr->SunkFocusWindowTitle' - djhjr - 10/25/02 */
2257 (tmp_win->titlehighlight && !Scr->hiliteName) ?
2258 CreateHighlightWindow(tmp_win) : None;
2265 * re-written to use an Image structure for XPM support
2269 #ifdef ORIGINAL_PIXMAPS
2270 void SetHighlightPixmap (filename)
2273 Pixmap pm = GetBitmap (filename);
2276 if (Scr->hilitePm) {
2277 XFreePixmap (dpy, Scr->hilitePm);
2280 Scr->hilite_pm_width = JunkWidth;
2281 Scr->hilite_pm_height = JunkHeight;
2284 #else /* ORIGINAL_PIXMAPS */
2285 void SetHighlightPixmap (filename)
2288 /* added this 'if (...) else' - djhjr - 10/25/02 */
2289 if (filename[0] == ':')
2290 Scr->hiliteName = filename;
2293 if (!Scr->hilitePm) Scr->hilitePm = SetPixmapsPixmap(filename);
2295 #endif /* ORIGINAL_PIXMAPS */
2298 void FetchWmProtocols (tmp)
2301 unsigned long flags = 0L;
2302 Atom *protocols = NULL;
2305 if (XGetWMProtocols (dpy, tmp->w, &protocols, &n)) {
2309 for (i = 0, ap = protocols; i < n; i++, ap++) {
2310 if (*ap == _XA_WM_TAKE_FOCUS) flags |= DoesWmTakeFocus;
2311 if (*ap == _XA_WM_SAVE_YOURSELF) flags |= DoesWmSaveYourself;
2312 if (*ap == _XA_WM_DELETE_WINDOW) flags |= DoesWmDeleteWindow;
2314 if (protocols) XFree ((char *) protocols);
2316 tmp->protocols = flags;
2320 CreateTwmColormap(c)
2324 cmap = (TwmColormap *) malloc(sizeof(TwmColormap));
2326 XSaveContext(dpy, c, ColormapContext, (caddr_t) cmap)) {
2327 if (cmap) free((char *) cmap);
2332 cmap->install_req = 0;
2339 CreateColormapWindow(w, creating_parent, property_window)
2341 Bool creating_parent;
2342 Bool property_window;
2344 ColormapWindow *cwin;
2346 XWindowAttributes attributes;
2348 cwin = (ColormapWindow *) malloc(sizeof(ColormapWindow));
2350 if (!XGetWindowAttributes(dpy, w, &attributes) ||
2351 XSaveContext(dpy, w, ColormapContext, (caddr_t) cwin)) {
2352 free((char *) cwin);
2356 if (XFindContext(dpy, attributes.colormap, ColormapContext,
2357 (caddr_t *)&cwin->colormap) == XCNOENT) {
2358 cwin->colormap = cmap = CreateTwmColormap(attributes.colormap);
2360 XDeleteContext(dpy, w, ColormapContext);
2361 free((char *) cwin);
2365 cwin->colormap->refcnt++;
2370 * Assume that windows in colormap list are
2371 * obscured if we are creating the parent window.
2372 * Otherwise, we assume they are unobscured.
2374 cwin->visibility = creating_parent ?
2375 VisibilityPartiallyObscured : VisibilityUnobscured;
2379 * If this is a ColormapWindow property window and we
2380 * are not monitoring ColormapNotify or VisibilityNotify
2381 * events, we need to.
2383 if (property_window &&
2384 (attributes.your_event_mask &
2385 (ColormapChangeMask|VisibilityChangeMask)) !=
2386 (ColormapChangeMask|VisibilityChangeMask)) {
2387 XSelectInput(dpy, w, attributes.your_event_mask |
2388 (ColormapChangeMask|VisibilityChangeMask));
2395 void FetchWmColormapWindows (tmp)
2399 Window *cmap_windows = NULL;
2400 Bool can_free_cmap_windows = False;
2401 int number_cmap_windows = 0;
2402 ColormapWindow **cwins = NULL;
2403 int previously_installed;
2404 extern void free_cwins();
2406 number_cmap_windows = 0;
2408 if ((previously_installed =
2409 (Scr->cmapInfo.cmaps == &tmp->cmaps) && tmp->cmaps.number_cwins)) {
2410 cwins = tmp->cmaps.cwins;
2411 for (i = 0; i < tmp->cmaps.number_cwins; i++)
2412 cwins[i]->colormap->state = 0;
2415 if (XGetWMColormapWindows (dpy, tmp->w, &cmap_windows,
2416 &number_cmap_windows) &&
2417 number_cmap_windows > 0) {
2419 can_free_cmap_windows = False;
2421 * check if the top level is in the list, add to front if not
2423 for (i = 0; i < number_cmap_windows; i++) {
2424 if (cmap_windows[i] == tmp->w) break;
2426 if (i == number_cmap_windows) { /* not in list */
2427 Window *new_cmap_windows =
2428 (Window *) malloc (sizeof(Window) * (number_cmap_windows + 1));
2430 if (!new_cmap_windows) {
2432 "%s: unable to allocate %d element colormap window array\n",
2433 ProgramName, number_cmap_windows+1);
2436 new_cmap_windows[0] = tmp->w; /* add to front */
2437 for (i = 0; i < number_cmap_windows; i++) { /* append rest */
2438 new_cmap_windows[i+1] = cmap_windows[i];
2440 XFree ((char *) cmap_windows);
2441 can_free_cmap_windows = True; /* do not use XFree any more */
2442 cmap_windows = new_cmap_windows;
2443 number_cmap_windows++;
2446 cwins = (ColormapWindow **) malloc(sizeof(ColormapWindow *) *
2447 number_cmap_windows);
2449 for (i = 0; i < number_cmap_windows; i++) {
2452 * Copy any existing entries into new list.
2454 for (j = 0; j < tmp->cmaps.number_cwins; j++) {
2455 if (tmp->cmaps.cwins[j]->w == cmap_windows[i]) {
2456 cwins[i] = tmp->cmaps.cwins[j];
2463 * If the colormap window is not being pointed by
2464 * some other applications colormap window list,
2465 * create a new entry.
2467 if (j == tmp->cmaps.number_cwins) {
2468 if (XFindContext(dpy, cmap_windows[i], ColormapContext,
2469 (caddr_t *)&cwins[i]) == XCNOENT) {
2470 if ((cwins[i] = CreateColormapWindow(cmap_windows[i],
2471 (Bool) tmp->cmaps.number_cwins == 0,
2474 for (k = i + 1; k < number_cmap_windows; k++)
2475 cmap_windows[k-1] = cmap_windows[k];
2477 number_cmap_windows--;
2486 /* No else here, in case we bailed out of clause above.
2488 if (number_cmap_windows == 0) {
2490 number_cmap_windows = 1;
2492 cwins = (ColormapWindow **) malloc(sizeof(ColormapWindow *));
2493 if (XFindContext(dpy, tmp->w, ColormapContext, (caddr_t *)&cwins[0]) ==
2495 cwins[0] = CreateColormapWindow(tmp->w,
2496 (Bool) tmp->cmaps.number_cwins == 0, False);
2501 if (tmp->cmaps.number_cwins)
2504 tmp->cmaps.cwins = cwins;
2505 tmp->cmaps.number_cwins = number_cmap_windows;
2506 if (number_cmap_windows > 1)
2507 tmp->cmaps.scoreboard =
2508 (char *) calloc(1, ColormapsScoreboardLength(&tmp->cmaps));
2510 if (previously_installed)
2511 InstallWindowColormaps(PropertyNotify, (TwmWindow *) NULL);
2515 if (can_free_cmap_windows)
2516 free ((char *) cmap_windows);
2518 XFree ((char *) cmap_windows);
2525 void GetWindowSizeHints (tmp)
2530 if (!XGetWMNormalHints (dpy, tmp->w, &tmp->hints, &supplied))
2531 tmp->hints.flags = 0;
2533 if (tmp->hints.flags & PResizeInc) {
2534 if (tmp->hints.width_inc == 0) tmp->hints.width_inc = 1;
2535 if (tmp->hints.height_inc == 0) tmp->hints.height_inc = 1;
2538 if (!(supplied & PWinGravity) && (tmp->hints.flags & USPosition)) {
2539 static int gravs[] = { SouthEastGravity, SouthWestGravity,
2540 NorthEastGravity, NorthWestGravity };
2541 int right = tmp->attr.x + tmp->attr.width + 2 * tmp->old_bw;
2542 int bottom = tmp->attr.y + tmp->attr.height + 2 * tmp->old_bw;
2545 tmp->hints.win_gravity =
2546 gravs[((Scr->MyDisplayHeight - bottom < tmp->title_height) ? 0 : 2) |
2547 ((Scr->MyDisplayWidth - right < tmp->title_height) ? 0 : 1)];
2549 tmp->hints.win_gravity =
2550 gravs[((Scr->MyDisplayHeight - bottom <
2551 tmp->title_height + 2 * tmp->frame_bw3D) ? 0 : 2) |
2552 ((Scr->MyDisplayWidth - right <
2553 tmp->title_height + 2 * tmp->frame_bw3D) ? 0 : 1)];
2555 tmp->hints.flags |= PWinGravity;