/*****************************************************************************/ /** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ /** Salt Lake City, Utah **/ /** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ /** Cambridge, Massachusetts **/ /** **/ /** All Rights Reserved **/ /** **/ /** Permission to use, copy, modify, and distribute this software and **/ /** its documentation for any purpose and without fee is hereby **/ /** granted, provided that the above copyright notice appear in all **/ /** copies and that both that copyright notice and this permis- **/ /** sion notice appear in supporting documentation, and that the **/ /** names of Evans & Sutherland and M.I.T. not be used in advertising **/ /** in publicity pertaining to distribution of the software without **/ /** specific, written prior permission. **/ /** **/ /** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ /** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ /** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ /** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ /** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ /** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ /** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ /** OR PERFORMANCE OF THIS SOFTWARE. **/ /*****************************************************************************/ /********************************************************************** * * $XConsortium: add_window.c,v 1.153 91/07/10 13:17:26 dave Exp $ * * Add a new window, put the titlbar and other stuff around * the window * * 31-Mar-88 Tom LaStrange Initial Version. * **********************************************************************/ #include #include #include "twm.h" #include #ifndef NO_XPM_SUPPORT #include #endif #include "add_window.h" #include "util.h" #include "resize.h" #include "parse.h" /* djhjr - 4/19/96 */ #include "gram.h" #include "list.h" #include "events.h" #include "menus.h" #include "screen.h" #include "iconmgr.h" #include "desktop.h" /* random placement coordinates */ #define PLACEMENT_START 50 #define PLACEMENT_INCR 30 /* 4/26/99 - djhjr */ extern int PlaceApplet(); #define gray_width 2 #define gray_height 2 static char gray_bits[] = { 0x02, 0x01}; /* djhjr - 4/19/96 */ static unsigned char black_bits[] = { 0xFF, 0xFF}; int AddingX; int AddingY; int AddingW; int AddingH; static void CreateWindowTitlebarButtons(); void SetHighlightPixmap(); /* djhjr - 4/14/98 */ static void AddMoveAndResize(); char NoName[] = "Untitled"; /* name if no name is specified */ /************************************************************************ * * Procedure: * GetGravityOffsets - map gravity to (x,y) offset signs for adding * to x and y when window is mapped to get proper placement. * ************************************************************************ */ void GetGravityOffsets (tmp, xp, yp) TwmWindow *tmp; /* window from which to get gravity */ int *xp, *yp; /* return values */ { static struct _gravity_offset { int x, y; } gravity_offsets[11] = { { 0, 0 }, /* ForgetGravity */ { -1, -1 }, /* NorthWestGravity */ { 0, -1 }, /* NorthGravity */ { 1, -1 }, /* NorthEastGravity */ { -1, 0 }, /* WestGravity */ { 0, 0 }, /* CenterGravity */ { 1, 0 }, /* EastGravity */ { -1, 1 }, /* SouthWestGravity */ { 0, 1 }, /* SouthGravity */ { 1, 1 }, /* SouthEastGravity */ { 0, 0 }, /* StaticGravity */ }; register int g = ((tmp->hints.flags & PWinGravity) ? tmp->hints.win_gravity : NorthWestGravity); if (g < ForgetGravity || g > StaticGravity) { *xp = *yp = 0; } else { *xp = gravity_offsets[g].x; *yp = gravity_offsets[g].y; } } /*********************************************************************** * * Procedure: * AddWindow - add a new window to the twm list * * Returned Value: * (TwmWindow *) - pointer to the TwmWindow structure * * Inputs: * w - the window id of the window to add * iconm - flag to tell if this is an icon manager window * iconp - pointer to icon manager struct * *********************************************************************** */ TwmWindow * AddWindow(w, iconm, iconp) Window w; int iconm; IconMgr *iconp; { TwmWindow *tmp_win; /* new twm window structure */ unsigned long valuemask; /* mask for create windows */ XSetWindowAttributes attributes; /* attributes for create windows */ #ifdef NO_I18N_SUPPORT XTextProperty text_property; #endif Atom actual_type; int actual_format; unsigned long nitems, bytesafter; int ask_user; /* don't know where to put the window */ int *ppos_ptr, ppos_on; /* djhjr - 9/24/02 */ int gravx, gravy; /* gravity signs for positioning */ int namelen; int bw2; char *icon_name; /* djhjr - 2/20/99 */ #ifndef NO_I18N_SUPPORT char *name; #endif /* next two submitted by Jonathan Paisley - 11/8/02 */ Atom motifhints = XInternAtom( dpy, "_MOTIF_WM_HINTS", 0); MotifWmHints *mwmhints; #ifdef DEBUG fprintf(stderr, "AddWindow: w = 0x%x\n", w); #endif /* allocate space for the twm window */ tmp_win = (TwmWindow *)calloc(1, sizeof(TwmWindow)); if (tmp_win == 0) { fprintf (stderr, "%s: Unable to allocate memory to manage window ID %lx.\n", ProgramName, w); return NULL; } tmp_win->w = w; tmp_win->zoomed = ZOOM_NONE; tmp_win->iconmgr = iconm; tmp_win->iconmgrp = iconp; tmp_win->cmaps.number_cwins = 0; XSelectInput(dpy, tmp_win->w, PropertyChangeMask); XGetWindowAttributes(dpy, tmp_win->w, &tmp_win->attr); /* djhjr - 9/14/03 */ #ifndef NO_I18N_SUPPORT if (I18N_FetchName(dpy, tmp_win->w, &name)) { tmp_win->name = strdup(name); free(name); } #else /* * Ask the window manager for a name with "newer" R4 function - * it was 'XFetchName()', which apparently failed more often. * Submitted by Nicholas Jacobs */ if (XGetWMName(dpy, tmp_win->w, &text_property) != 0) { tmp_win->name = (char *)strdup(text_property.value); XFree(text_property.value); } #endif else tmp_win->name = NoName; tmp_win->class = NoClass; XGetClassHint(dpy, tmp_win->w, &tmp_win->class); FetchWmProtocols (tmp_win); FetchWmColormapWindows (tmp_win); /* * do initial clip; should look at window gravity */ if (tmp_win->attr.width > Scr->MaxWindowWidth) tmp_win->attr.width = Scr->MaxWindowWidth; if (tmp_win->attr.height > Scr->MaxWindowHeight) tmp_win->attr.height = Scr->MaxWindowHeight; tmp_win->wmhints = XGetWMHints(dpy, tmp_win->w); if (tmp_win->wmhints && (tmp_win->wmhints->flags & WindowGroupHint)) tmp_win->group = tmp_win->wmhints->window_group; else tmp_win->group = tmp_win->w/* NULL */; /* submitted by Jonathan Paisley - 11/8/02 */ tmp_win->mwmhints.flags = 0; if (motifhints != None) { if (XGetWindowProperty(dpy, tmp_win->w, motifhints, 0L, sizeof(MotifWmHints), False, motifhints, &actual_type, &actual_format, &nitems, &bytesafter, (unsigned char**)&mwmhints) == Success && actual_type != None) { if (mwmhints) { tmp_win->mwmhints = *mwmhints; XFree(mwmhints); } } } /* * The July 27, 1988 draft of the ICCCM ignores the size and position * fields in the WM_NORMAL_HINTS property. */ tmp_win->transient = Transient(tmp_win->w, &tmp_win->transientfor); if (tmp_win->class.res_name == NULL) tmp_win->class.res_name = NoName; if (tmp_win->class.res_class == NULL) tmp_win->class.res_class = NoName; tmp_win->full_name = tmp_win->name; namelen = strlen (tmp_win->name); tmp_win->highlight = Scr->Highlight && /* djhjr - 4/22/98 (!(short)(int) LookInList(Scr->NoHighlight, tmp_win->full_name, &tmp_win->class)); */ (LookInList(Scr->NoHighlight, tmp_win->full_name, &tmp_win->class) == (char *)NULL); tmp_win->stackmode = Scr->StackMode && /* djhjr - 4/22/98 (!(short)(int) LookInList(Scr->NoStackModeL, tmp_win->full_name, &tmp_win->class)); */ (LookInList(Scr->NoStackModeL, tmp_win->full_name, &tmp_win->class) == (char *)NULL); tmp_win->titlehighlight = Scr->TitleHighlight && /* djhjr - 4/22/98 (!(short)(int) LookInList(Scr->NoTitleHighlight, tmp_win->full_name, &tmp_win->class)); */ (LookInList(Scr->NoTitleHighlight, tmp_win->full_name, &tmp_win->class) == (char *)NULL); tmp_win->auto_raise = Scr->AutoRaiseDefault || /* RAISEDELAY */ /* djhjr - 4/22/98 (short)(int) LookInList(Scr->AutoRaise, tmp_win->full_name, &tmp_win->class); */ (LookInList(Scr->AutoRaise, tmp_win->full_name, &tmp_win->class) != (char *)NULL); if (tmp_win->auto_raise) Scr->NumAutoRaises++; tmp_win->iconify_by_unmapping = Scr->IconifyByUnmapping; if (Scr->IconifyByUnmapping) { /* djhjr - 9/21/99 tmp_win->iconify_by_unmapping = iconm ? FALSE : */ tmp_win->iconify_by_unmapping = /* djhjr - 4/22/98 !(short)(int) LookInList(Scr->DontIconify, tmp_win->full_name, &tmp_win->class); */ (LookInList(Scr->DontIconify, tmp_win->full_name, &tmp_win->class) == (char *)NULL); } tmp_win->iconify_by_unmapping |= /* djhjr - 4/22/98 (short)(int) LookInList(Scr->IconifyByUn, tmp_win->full_name, &tmp_win->class); */ (LookInList(Scr->IconifyByUn, tmp_win->full_name, &tmp_win->class) != (char *)NULL); /* Scr->NoWindowRingL submitted by Jonathan Paisley - 10/27/02 */ if ((Scr->UseWindowRing || LookInList(Scr->WindowRingL, tmp_win->full_name, &tmp_win->class)) && LookInList(Scr->NoWindowRingL, tmp_win->full_name, &tmp_win->class) == (char *)NULL) { /* in menus.c now - djhjr - 10/27/02 */ AddWindowToRing(tmp_win); } else tmp_win->ring.next = tmp_win->ring.prev = NULL; #ifdef ORIGINAL_WARPRINGCOORDINATES /* djhjr - 5/11/98 */ tmp_win->ring.cursor_valid = False; #endif if (LookInList(Scr->NailedDown, tmp_win->full_name, &tmp_win->class)) tmp_win->nailed = TRUE; else tmp_win->nailed = FALSE; if (LookInList(Scr->DontShowInDisplay, tmp_win->full_name, &tmp_win->class)) tmp_win->showindesktopdisplay = FALSE; else tmp_win->showindesktopdisplay = TRUE; tmp_win->squeeze_info = NULL; /* * get the squeeze information; note that this does not have to be freed * since it is coming from the screen list */ if (HasShape) { if (!LookInList (Scr->DontSqueezeTitleL, tmp_win->full_name, &tmp_win->class)) { tmp_win->squeeze_info = (SqueezeInfo *) LookInList (Scr->SqueezeTitleL, tmp_win->full_name, &tmp_win->class); if (!tmp_win->squeeze_info) { static SqueezeInfo default_squeeze = { J_LEFT, 0, 0 }; if (Scr->SqueezeTitle) tmp_win->squeeze_info = &default_squeeze; } } } tmp_win->old_bw = tmp_win->attr.border_width; #ifdef NEVER /* see the next '#ifdef NEVER's '#else' - C. F. Jalali */ /* djhjr - 4/19/96 */ /* was 'Scr->ThreeDBorderWidth' - djhjr - 8/11/98 */ tmp_win->frame_bw3D = Scr->BorderWidth; #endif /* added 'Scr->NoBorders' test - djhjr - 8/23/02 */ if (Scr->NoBorders || LookInList(Scr->NoBorder, tmp_win->full_name, &tmp_win->class)) { tmp_win->frame_bw = 0; tmp_win->frame_bw3D = 0; } else #ifdef NEVER if (tmp_win->frame_bw3D != 0) { tmp_win->frame_bw = 0; Scr->ClientBorderWidth = FALSE; } else if (Scr->ClientBorderWidth) tmp_win->frame_bw = tmp_win->old_bw; else tmp_win->frame_bw = Scr->BorderWidth; #else /* * Submitted by Caveh Frank Jalali - 8/25/98 */ { if (Scr->BorderBevelWidth > 0) { tmp_win->frame_bw3D = Scr->BorderWidth; tmp_win->frame_bw = 0; Scr->ClientBorderWidth = FALSE; } else { tmp_win->frame_bw3D = 0; if (Scr->ClientBorderWidth) tmp_win->frame_bw = tmp_win->old_bw; else tmp_win->frame_bw = Scr->BorderWidth; } } #endif /* submitted by Jonathan Paisley - 11/8/02 */ if (tmp_win->mwmhints.flags & MWM_HINTS_DECORATIONS) { if (tmp_win->mwmhints.decorations & MWM_DECOR_ALL) tmp_win->mwmhints.decorations |= (MWM_DECOR_BORDER | MWM_DECOR_RESIZEH | MWM_DECOR_TITLE | MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE); if (!(tmp_win->mwmhints.decorations & MWM_DECOR_BORDER)) tmp_win->frame_bw = tmp_win->frame_bw3D = 0; } if (tmp_win->mwmhints.flags & MWM_HINTS_FUNCTIONS) if (tmp_win->mwmhints.functions & MWM_FUNC_ALL) tmp_win->mwmhints.functions |= (MWM_FUNC_RESIZE | MWM_FUNC_MOVE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_CLOSE); bw2 = tmp_win->frame_bw * 2; /* moved MakeTitle under NoTitle - djhjr - 10/20/01 */ tmp_win->title_height = Scr->TitleHeight + tmp_win->frame_bw; /* submitted by Jonathan Paisley 11/8/02 */ if (tmp_win->mwmhints.flags & MWM_HINTS_DECORATIONS && !(tmp_win->mwmhints.decorations & MWM_DECOR_TITLE)) tmp_win->title_height = 0; if (Scr->NoTitlebar) tmp_win->title_height = 0; if (LookInList(Scr->NoTitle, tmp_win->full_name, &tmp_win->class)) tmp_win->title_height = 0; if (LookInList(Scr->MakeTitle, tmp_win->full_name, &tmp_win->class)) tmp_win->title_height = Scr->TitleHeight + tmp_win->frame_bw; /* djhjr - 4/7/98 */ if (LookInList(Scr->OpaqueMoveL, tmp_win->full_name, &tmp_win->class)) tmp_win->opaque_move = TRUE; else tmp_win->opaque_move = Scr->OpaqueMove && /* djhjr - 4/22/98 !(short)(int)LookInList(Scr->NoOpaqueMoveL, tmp_win->full_name, &tmp_win->class); */ (LookInList(Scr->NoOpaqueMoveL, tmp_win->full_name, &tmp_win->class) == (char *)NULL); /* djhjr - 9/21/99 */ if (tmp_win->opaque_move) tmp_win->attr.save_under = True; /* djhjr - 4/7/98 */ if (LookInList(Scr->OpaqueResizeL, tmp_win->full_name, &tmp_win->class)) tmp_win->opaque_resize = TRUE; else tmp_win->opaque_resize = Scr->OpaqueResize && /* djhjr - 4/22/98 !(short)(int)LookInList(Scr->NoOpaqueResizeL, tmp_win->full_name, &tmp_win->class); */ (LookInList(Scr->NoOpaqueResizeL, tmp_win->full_name, &tmp_win->class) == (char *)NULL); /* djhjr - 9/21/99 */ if (tmp_win->opaque_resize) tmp_win->attr.save_under = True; /* if it is a transient window, don't put a title on it */ if (tmp_win->transient && !Scr->DecorateTransients) tmp_win->title_height = 0; if (LookInList(Scr->StartIconified, tmp_win->full_name, &tmp_win->class)) { if (!tmp_win->wmhints) { tmp_win->wmhints = (XWMHints *)malloc(sizeof(XWMHints)); tmp_win->wmhints->flags = 0; } tmp_win->wmhints->initial_state = IconicState; tmp_win->wmhints->flags |= StateHint; } GetWindowSizeHints (tmp_win); GetGravityOffsets (tmp_win, &gravx, &gravy); /* * Don't bother user if: * * o the window is a transient, or * * o a USPosition was requested, or * * o a PPosition was requested and UsePPosition is ON or * NON_ZERO if the window is at other than (0,0) */ /* djhjr - 9/24/02 */ if ((ppos_ptr = (int *)LookInList(Scr->UsePPositionL, tmp_win->full_name, &tmp_win->class))) ppos_on = *ppos_ptr; else ppos_on = Scr->UsePPosition; if (ppos_on == PPOS_NON_ZERO && (tmp_win->attr.x != 0 || tmp_win->attr.y != 0)) ppos_on = PPOS_ON; ask_user = TRUE; if (tmp_win->transient || (tmp_win->hints.flags & USPosition) || ((tmp_win->hints.flags & PPosition) && ppos_on == PPOS_ON)) ask_user = FALSE; /* check for applet regions - djhjr - 4/26/99 */ if (PlaceApplet(tmp_win, tmp_win->attr.x, tmp_win->attr.y, &tmp_win->attr.x, &tmp_win->attr.y)) ask_user = FALSE; if (LookInList(Scr->NailedDown, tmp_win->full_name, &tmp_win->class)) tmp_win->nailed = TRUE; else tmp_win->nailed = FALSE; /* * 25/09/90 - Nailed windows should always be on the real screen, * regardless of PPosition or UPosition. If we are dealing with * PPosition, then offset by the current real screen offset on the vd. */ if (tmp_win->nailed || ((tmp_win->hints.flags & PPosition) && (ask_user == FALSE))) { tmp_win->attr.x = R_TO_V_X(tmp_win->attr.x); tmp_win->attr.y = R_TO_V_Y(tmp_win->attr.y); } /* moved to after window prep and creation - djhjr - 4/14/98 AddMoveAndResize(tmp_win, ask_user); */ if (!Scr->ClientBorderWidth) { /* need to adjust for twm borders */ /* djhjr - 4/19/96 int delta = tmp_win->attr.border_width - tmp_win->frame_bw; */ /* submitted by Jonathan Paisley - 11/8/02 int delta = tmp_win->attr.border_width - tmp_win->frame_bw - tmp_win->frame_bw3D; */ int delta = -(tmp_win->frame_bw + tmp_win->frame_bw3D); tmp_win->attr.x += gravx * delta; tmp_win->attr.y += gravy * delta; } /* * For windows with specified non-northwest gravities. * Submitted by Jonathan Paisley - 11/8/02 */ if (tmp_win->old_bw) { if (!Scr->ClientBorderWidth) { JunkX = gravx + 1; JunkY = gravy + 1; } else JunkX = JunkY = 1; tmp_win->attr.x += JunkX * tmp_win->old_bw; tmp_win->attr.y += JunkY * tmp_win->old_bw; } tmp_win->title_width = tmp_win->attr.width; if (tmp_win->old_bw) XSetWindowBorderWidth (dpy, tmp_win->w, 0); /* djhjr - 9/14/03 */ #ifndef NO_I18N_SUPPORT tmp_win->name_width = MyFont_TextWidth(&Scr->TitleBarFont, #else tmp_win->name_width = XTextWidth(Scr->TitleBarFont.font, #endif tmp_win->name, namelen); /* djhjr - 9/14/03 */ #ifndef NO_I18N_SUPPORT if (!I18N_GetIconName(dpy, tmp_win->w, &icon_name)) #else /* used to be a simple boolean test for success - djhjr - 1/10/98 */ if (XGetWindowProperty (dpy, tmp_win->w, XA_WM_ICON_NAME, 0L, 200L, False, XA_STRING, &actual_type, &actual_format, &nitems, &bytesafter, /* see that the icon name is it's own memory - djhjr - 2/20/99 (unsigned char **)&tmp_win->icon_name) != Success || actual_type == None) tmp_win->icon_name = tmp_win->name; */ (unsigned char **)&icon_name) != Success || actual_type == None) #endif tmp_win->icon_name = strdup(tmp_win->name); else { tmp_win->icon_name = strdup(icon_name); /* djhjr - 9/14/03 */ #ifndef NO_I18N_SUPPORT free(icon_name); #else XFree(icon_name); #endif } /* redundant? - djhjr - 1/10/98 if (tmp_win->icon_name == NULL) tmp_win->icon_name = tmp_win->name; */ tmp_win->iconified = FALSE; tmp_win->icon = FALSE; tmp_win->icon_on = FALSE; XGrabServer(dpy); /* * Make sure the client window still exists. We don't want to leave an * orphan frame window if it doesn't. Since we now have the server * grabbed, the window can't disappear later without having been * reparented, so we'll get a DestroyNotify for it. We won't have * gotten one for anything up to here, however. */ if (XGetGeometry(dpy, tmp_win->w, &JunkRoot, &JunkX, &JunkY, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0) { free((char *)tmp_win); XUngrabServer(dpy); return(NULL); } /* add the window into the twm list */ tmp_win->next = Scr->TwmRoot.next; if (Scr->TwmRoot.next != NULL) Scr->TwmRoot.next->prev = tmp_win; tmp_win->prev = &Scr->TwmRoot; Scr->TwmRoot.next = tmp_win; /* get all the colors for the window */ /* djhjr - 4/25/96 tmp_win->border = Scr->BorderColor; */ tmp_win->border.back = Scr->BorderColor; tmp_win->icon_border = Scr->IconBorderColor; tmp_win->border_tile.fore = Scr->BorderTileC.fore; tmp_win->border_tile.back = Scr->BorderTileC.back; tmp_win->title.fore = Scr->TitleC.fore; tmp_win->title.back = Scr->TitleC.back; tmp_win->iconc.fore = Scr->IconC.fore; tmp_win->iconc.back = Scr->IconC.back; tmp_win->virtual.fore = Scr->VirtualDesktopDisplayC.fore; tmp_win->virtual.back = Scr->VirtualDesktopDisplayC.back; /* djhjr - 4/25/96 GetColorFromList(Scr->BorderColorL, tmp_win->full_name, &tmp_win->class, &tmp_win->border); */ GetColorFromList(Scr->BorderColorL, tmp_win->full_name, &tmp_win->class, &tmp_win->border.back); GetColorFromList(Scr->IconBorderColorL, tmp_win->full_name, &tmp_win->class, &tmp_win->icon_border); GetColorFromList(Scr->BorderTileForegroundL, tmp_win->full_name, &tmp_win->class, &tmp_win->border_tile.fore); GetColorFromList(Scr->BorderTileBackgroundL, tmp_win->full_name, &tmp_win->class, &tmp_win->border_tile.back); GetColorFromList(Scr->TitleForegroundL, tmp_win->full_name, &tmp_win->class, &tmp_win->title.fore); GetColorFromList(Scr->TitleBackgroundL, tmp_win->full_name, &tmp_win->class, &tmp_win->title.back); GetColorFromList(Scr->IconForegroundL, tmp_win->full_name, &tmp_win->class, &tmp_win->iconc.fore); GetColorFromList(Scr->IconBackgroundL, tmp_win->full_name, &tmp_win->class, &tmp_win->iconc.back); /* fixed transposed fallback fore and back color lists - djhjr - 9/25/01 */ if (!GetColorFromList(Scr->VirtualDesktopColorFL, tmp_win->full_name, &tmp_win->class, &tmp_win->virtual.fore)) GetColorFromList(Scr->TitleForegroundL, tmp_win->full_name, &tmp_win->class, &tmp_win->virtual.fore); if (!GetColorFromList(Scr->VirtualDesktopColorBL, tmp_win->full_name, &tmp_win->class, &tmp_win->virtual.back)) GetColorFromList(Scr->TitleBackgroundL, tmp_win->full_name, &tmp_win->class, &tmp_win->virtual.back); /* djhjr - 4/19/96 */ /* loosened up for titlebar-colored 3D buttons - djhjr - 4/1/98 if (Scr->use3Dtitles && !Scr->BeNiceToColormap) */ if (!Scr->BeNiceToColormap) GetShadeColors (&tmp_win->title); /* was 'Scr->use3Dborders' - djhjr - 8/11/98 */ /* rearranged the parenthesis - djhjr - 10/30/02 */ if ((Scr->ButtonColorIsFrame || Scr->BorderBevelWidth > 0) && !Scr->BeNiceToColormap) { GetShadeColors (&tmp_win->border); GetShadeColors (&tmp_win->border_tile); } /* create windows */ /* djhjr - 4/19/96 tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->frame_bw; tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height + tmp_win->old_bw - tmp_win->frame_bw; tmp_win->frame_width = tmp_win->attr.width; tmp_win->frame_height = tmp_win->attr.height + tmp_win->title_height; */ /* done in AddMoveAndResize() - djhjr - 4/14/98 tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->frame_bw - tmp_win->frame_bw3D; tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height + tmp_win->old_bw - tmp_win->frame_bw - tmp_win->frame_bw3D; */ tmp_win->frame_width = tmp_win->attr.width + 2 * tmp_win->frame_bw3D; tmp_win->frame_height = tmp_win->attr.height + tmp_win->title_height + 2 * tmp_win->frame_bw3D; /* done in AddMoveAndResize() - djhjr - 4/14/98 ConstrainSize (tmp_win, &tmp_win->frame_width, &tmp_win->frame_height); tmp_win->virtual_frame_x = R_TO_V_X(tmp_win->frame_x); tmp_win->virtual_frame_y = R_TO_V_Y(tmp_win->frame_y); */ /* djhjr - 4/19/96 valuemask = CWBackPixmap | CWBorderPixel | CWCursor | CWEventMask; attributes.background_pixmap = None; attributes.border_pixel = tmp_win->border; attributes.cursor = Scr->FrameCursor; attributes.event_mask = (SubstructureRedirectMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask); if (tmp_win->attr.save_under) { attributes.save_under = True; valuemask |= CWSaveUnder; } */ /* djhjr - 9/14/96 valuemask = CWBackPixmap | CWBorderPixel | CWCursor | CWEventMask | CWBackPixel; attributes.background_pixmap = None; */ valuemask = CWBorderPixel | CWCursor | CWEventMask | CWBackPixel; attributes.background_pixel = tmp_win->border.back; attributes.border_pixel = tmp_win->border.back; attributes.cursor = Scr->FrameCursor; attributes.event_mask = (SubstructureRedirectMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | ExposureMask); if (tmp_win->attr.save_under) { attributes.save_under = True; valuemask |= CWSaveUnder; } /* djhjr - 9/17/96 - slows down iconify/delete/destroy too much... if (Scr->BackingStore) { attributes.backing_store = WhenMapped; valuemask |= CWBackingStore; } */ if (tmp_win->hints.flags & PWinGravity) { attributes.win_gravity = tmp_win->hints.win_gravity; valuemask |= CWWinGravity; } tmp_win->frame = XCreateWindow (dpy, Scr->Root, tmp_win->frame_x, tmp_win->frame_y, (unsigned int) tmp_win->frame_width, (unsigned int) tmp_win->frame_height, (unsigned int) tmp_win->frame_bw, Scr->d_depth, (unsigned int) CopyFromParent, Scr->d_visual, valuemask, &attributes); if (tmp_win->title_height) { valuemask = (CWEventMask | CWBorderPixel | CWBackPixel); attributes.event_mask = (KeyPressMask | ButtonPressMask | ButtonReleaseMask | ExposureMask); /* djhjr - 4/19/96 attributes.border_pixel = tmp_win->border; */ attributes.border_pixel = tmp_win->title.back; attributes.background_pixel = tmp_win->title.back; /* djhjr - 9/17/96 */ if (Scr->BackingStore) { attributes.backing_store = WhenMapped; valuemask |= CWBackingStore; } tmp_win->title_w = XCreateWindow (dpy, tmp_win->frame, /* djhjr - 4/19/96 -tmp_win->frame_bw, -tmp_win->frame_bw, */ tmp_win->frame_bw3D - tmp_win->frame_bw, tmp_win->frame_bw3D - tmp_win->frame_bw, (unsigned int) tmp_win->attr.width, (unsigned int) Scr->TitleHeight, (unsigned int) tmp_win->frame_bw, Scr->d_depth, (unsigned int) CopyFromParent, Scr->d_visual, valuemask, &attributes); } else { tmp_win->title_w = 0; tmp_win->squeeze_info = NULL; } if (tmp_win->highlight) { /* djhjr - 4/19/96 */ /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */ if (Scr->TitleBevelWidth > 0 && (Scr->Monochrome != COLOR)) tmp_win->gray = XCreatePixmapFromBitmapData(dpy, Scr->Root, (char *)black_bits, gray_width, gray_height, tmp_win->border_tile.fore, tmp_win->border_tile.back, Scr->d_depth); else tmp_win->gray = XCreatePixmapFromBitmapData(dpy, Scr->Root, gray_bits, gray_width, gray_height, tmp_win->border_tile.fore, tmp_win->border_tile.back, Scr->d_depth); SetBorder (tmp_win, False); } else tmp_win->gray = None; if (tmp_win->title_w) { CreateWindowTitlebarButtons (tmp_win); ComputeTitleLocation (tmp_win); XMoveWindow (dpy, tmp_win->title_w, tmp_win->title_x, tmp_win->title_y); XDefineCursor(dpy, tmp_win->title_w, Scr->TitleCursor); } /* djhjr - 4/19/96 */ else { tmp_win->title_x = tmp_win->frame_bw3D - tmp_win->frame_bw; tmp_win->title_y = tmp_win->frame_bw3D - tmp_win->frame_bw; } valuemask = (CWEventMask | CWDontPropagate); attributes.event_mask = (StructureNotifyMask | PropertyChangeMask | ColormapChangeMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask); attributes.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask; XChangeWindowAttributes (dpy, tmp_win->w, valuemask, &attributes); if (HasShape) XShapeSelectInput (dpy, tmp_win->w, ShapeNotifyMask); if (tmp_win->title_w) { XMapWindow (dpy, tmp_win->title_w); } if (HasShape) { int xws, yws, xbs, ybs; unsigned wws, hws, wbs, hbs; int boundingShaped, clipShaped; XShapeSelectInput (dpy, tmp_win->w, ShapeNotifyMask); XShapeQueryExtents (dpy, tmp_win->w, &boundingShaped, &xws, &yws, &wws, &hws, &clipShaped, &xbs, &ybs, &wbs, &hbs); tmp_win->wShaped = boundingShaped; } if (!tmp_win->iconmgr) XAddToSaveSet(dpy, tmp_win->w); /* djhjr - 4/19/96 XReparentWindow(dpy, tmp_win->w, tmp_win->frame, 0, tmp_win->title_height); */ XReparentWindow(dpy, tmp_win->w, tmp_win->frame, tmp_win->frame_bw3D, tmp_win->title_height + tmp_win->frame_bw3D); /* * Reparenting generates an UnmapNotify event, followed by a MapNotify. * Set the map state to FALSE to prevent a transition back to * WithdrawnState in HandleUnmapNotify. Map state gets set correctly * again in HandleMapNotify. */ tmp_win->mapped = FALSE; /* * NOW do the move and resize - windows needed to be created * first to accomodate the opaque resources - djhjr - 4/14/98 */ AddMoveAndResize(tmp_win, ask_user); SetupFrame (tmp_win, tmp_win->frame_x, tmp_win->frame_y, tmp_win->frame_width, tmp_win->frame_height, -1, True); /* wait until the window is iconified and the icon window is mapped * before creating the icon window */ tmp_win->icon_w = None; if (!tmp_win->iconmgr) { GrabButtons(tmp_win); GrabKeys(tmp_win); } (void) AddIconManager(tmp_win); UpdateDesktop(tmp_win); XSaveContext(dpy, tmp_win->w, TwmContext, (caddr_t) tmp_win); XSaveContext(dpy, tmp_win->w, ScreenContext, (caddr_t) Scr); XSaveContext(dpy, tmp_win->frame, TwmContext, (caddr_t) tmp_win); XSaveContext(dpy, tmp_win->frame, ScreenContext, (caddr_t) Scr); if (tmp_win->title_height) { int i; int nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; XSaveContext(dpy, tmp_win->title_w, TwmContext, (caddr_t) tmp_win); XSaveContext(dpy, tmp_win->title_w, ScreenContext, (caddr_t) Scr); for (i = 0; i < nb; i++) { XSaveContext(dpy, tmp_win->titlebuttons[i].window, TwmContext, (caddr_t) tmp_win); XSaveContext(dpy, tmp_win->titlebuttons[i].window, ScreenContext, (caddr_t) Scr); } if (tmp_win->hilite_w) { XSaveContext(dpy, tmp_win->hilite_w, TwmContext, (caddr_t)tmp_win); XSaveContext(dpy, tmp_win->hilite_w, ScreenContext, (caddr_t)Scr); } } XUngrabServer(dpy); /* if we were in the middle of a menu activated function, regrab * the pointer */ if (RootFunction != F_NOFUNCTION) ReGrab(); Scr->Newest = tmp_win; /* PF */ if (tmp_win->transient && Scr->WarpToTransients) /* PF */ WarpToWindow(tmp_win); /* PF,DSE */ return (tmp_win); } /* * AddPaintRealWindows() * * a little helper for AddMoveAndResize() - djhjr - 4/15/98 */ static void AddPaintRealWindows(tmp_win, x, y) TwmWindow *tmp_win; int x, y; { /* handled in add_window() now - djhjr - 9/21/99 XSetWindowAttributes attr; attr.save_under = True; XChangeWindowAttributes(dpy, tmp_win->frame, CWSaveUnder, &attr); */ /* don't need to send a configure notify event */ SetupWindow(tmp_win, tmp_win->frame_x, tmp_win->frame_y, tmp_win->frame_width, tmp_win->frame_height, -1); XMoveWindow(dpy, tmp_win->frame, x, y); XMapWindow(dpy, tmp_win->frame); XMapSubwindows(dpy, tmp_win->frame); XMapSubwindows(dpy, tmp_win->title_w); PaintBorderAndTitlebar(tmp_win); /* djhjr - 4/15/98 */ if (!Scr->NoGrabServer) { /* these allow the application window to be drawn */ XUngrabServer(dpy); XSync(dpy, 0); XGrabServer(dpy); } } /* * AddMoveAndResize() * * was inline in AddWindow() at first call to this function, * now handles the opaque move and resize resources - djhjr - 4/14/98 */ static void AddMoveAndResize(tmp_win, ask_user) TwmWindow *tmp_win; int ask_user; { static int PlaceX = PLACEMENT_START; static int PlaceY = PLACEMENT_START; XEvent event; int stat, gravx, gravy; int bw2 = tmp_win->frame_bw * 2; int wd = tmp_win->attr.width + bw2; int ht = tmp_win->attr.height + tmp_win->title_height + bw2; /* * do any prompting for position */ if (HandlingEvents && ask_user) { if (Scr->RandomPlacement) { /* just stick it somewhere */ if (PlaceX + wd > Scr->MyDisplayWidth) { /* submitted by Seth Robertson - 8/25/02 */ if (PLACEMENT_START + wd < Scr->MyDisplayWidth) PlaceX = PLACEMENT_START; else { PlaceX = tmp_win->frame_bw; if (wd < Scr->MyDisplayWidth) PlaceX += (Scr->MyDisplayWidth - wd) / 2; } } if (PlaceY + ht > Scr->MyDisplayHeight) { /* submitted by Seth Robertson - 8/25/02 */ if (PLACEMENT_START + ht < Scr->MyDisplayHeight) PlaceY = PLACEMENT_START; else { PlaceY = tmp_win->title_height + tmp_win->frame_bw; if (ht < Scr->MyDisplayHeight) PlaceY += (Scr->MyDisplayHeight - ht) / 2; } } tmp_win->attr.x = PlaceX; tmp_win->attr.y = PlaceY; PlaceX += PLACEMENT_INCR; PlaceY += PLACEMENT_INCR; } else if (Scr->PointerPlacement) { /* find pointer */ if (!XQueryPointer (dpy, Scr->Root, &JunkRoot, &JunkChild, &JunkX, &JunkY, &AddingX, &AddingY, &JunkMask)) JunkMask = 0; /* fit window onto screen */ if (Scr->WarpSnug) { if (JunkX + wd > Scr->MyDisplayWidth) JunkX -= (JunkX + wd - Scr->MyDisplayWidth); if (JunkY + tmp_win->attr.height > Scr->MyDisplayHeight) JunkY -= (JunkY + tmp_win->attr.height - Scr->MyDisplayHeight); } tmp_win->attr.x = JunkX; tmp_win->attr.y = JunkY; } else { /* else prompt */ if (!(tmp_win->wmhints && tmp_win->wmhints->flags & StateHint && tmp_win->wmhints->initial_state == IconicState)) { Bool firsttime = True; /* djhjr - 11/15/01 */ Bool doorismapped = False; TwmDoor *door = NULL; XFindContext(dpy, tmp_win->w, DoorContext, (caddr_t *)&door); /* better wait until all the mouse buttons have been * released. */ while (TRUE) { XUngrabServer(dpy); XSync(dpy, 0); XGrabServer(dpy); JunkMask = 0; if (!XQueryPointer (dpy, Scr->Root, &JunkRoot, &JunkChild, &JunkX, &JunkY, &AddingX, &AddingY, &JunkMask)) JunkMask = 0; JunkMask &= (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask); /* * watch out for changing screens */ if (firsttime) { if (JunkRoot != Scr->Root) { register int scrnum; for (scrnum = 0; scrnum < NumScreens; scrnum++) { if (JunkRoot == RootWindow (dpy, scrnum)) break; } if (scrnum != NumScreens) PreviousScreen = scrnum; } firsttime = False; } /* * wait for buttons to come up; yuck */ if (JunkMask != 0) continue; /* * this will cause a warp to the indicated root */ stat = XGrabPointer(dpy, Scr->Root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | PointerMotionHintMask, GrabModeAsync, GrabModeAsync, Scr->Root, UpperLeftCursor, CurrentTime); if (stat == GrabSuccess) break; } /* djhjr - 4/15/98 */ if (Scr->NoGrabServer) XUngrabServer(dpy); /* use initialized size... djhjr - 5/9/96 * djhjr - 9/14/03 * #ifndef NO_I18N_SUPPORT width = (SIZE_HINDENT + MyFont_TextWidth (&Scr->SizeFont, #else width = (SIZE_HINDENT + XTextWidth (Scr->SizeFont.font, #endif tmp_win->name, namelen)); height = Scr->SizeFont.height + SIZE_VINDENT * 2; * djhjr - 4/27/96 XResizeWindow (dpy, Scr->SizeWindow, width + SIZE_HINDENT, height); * XResizeWindow (dpy, Scr->SizeWindow, Scr->SizeStringOffset + Scr->SizeStringWidth, height); */ XMapRaised(dpy, Scr->SizeWindow); InstallRootColormap(); /* DisplayPosition overwrites it anyway... djhjr - 5/9/96 * font was font.font->fid - djhjr - 9/14/03 * FBF(Scr->DefaultC.fore, Scr->DefaultC.back, Scr->SizeFont); * djhjr - 9/14/03 * #ifndef NO_I18N_SUPPORT MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont, #else XDrawImageString (dpy, Scr->SizeWindow, #endif Scr->NormalGC, SIZE_HINDENT, * djhjr - 9/14/03 SIZE_VINDENT + Scr->SizeFont.font->ascent, * SIZE_VINDENT + Scr->SizeFont.ascent, tmp_win->name, namelen); */ /* djhjr - 4/19/96 AddingW = tmp_win->attr.width + bw2; AddingH = tmp_win->attr.height + tmp_win->title_height + bw2; MoveOutline(Scr->Root, AddingX, AddingY, AddingW, AddingH, tmp_win->frame_bw, tmp_win->title_height); */ AddingW = tmp_win->attr.width + bw2 + 2 * tmp_win->frame_bw3D; AddingH = tmp_win->attr.height + tmp_win->title_height + bw2 + 2 * tmp_win->frame_bw3D; /* added this 'if ... else' - djhjr - 4/14/98 */ if (tmp_win->opaque_move) { AddPaintRealWindows(tmp_win, AddingX, AddingY); /* djhjr - 11/15/01 */ if (door && !doorismapped) { XMapWindow(dpy, door->w); RedoDoorName(tmp_win, door); doorismapped = True; } } else MoveOutline(Scr->Root, AddingX, AddingY, AddingW, AddingH, tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); /* djhjr - 4/17/98 */ if (Scr->VirtualReceivesMotionEvents) { tmp_win->virtual_frame_x = R_TO_V_X(AddingX); tmp_win->virtual_frame_y = R_TO_V_Y(AddingY); UpdateDesktop(tmp_win); } /* DisplayPosition() overwrites it anyway... djhjr - 5/9/96 * djhjr - 9/14/03 * #ifndef NO_I18N_SUPPORT MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont, #else * djhjr - 4/27/96 * XDrawImageString (dpy, Scr->SizeWindow, #endif Scr->NormalGC, width, * djhjr - 9/14/03 SIZE_VINDENT + Scr->SizeFont.font->ascent, ": ", 2); * SIZE_VINDENT + Scr->SizeFont.ascent, ": ", 2); */ /* djhjr - 4/27/96 */ DisplayPosition (AddingX, AddingY); while (TRUE) { XMaskEvent(dpy, ButtonPressMask | PointerMotionMask, &event); if (Event.type == MotionNotify) { /* discard any extra motion events before a release */ while(XCheckMaskEvent(dpy, ButtonMotionMask | ButtonPressMask, &Event)) if (Event.type == ButtonPress) break; } if (event.type == ButtonPress) { AddingX = event.xbutton.x_root; AddingY = event.xbutton.y_root; /* DontMoveOff prohibits user form off-screen placement */ if (Scr->DontMoveOff) { int AddingR, AddingB; AddingR = AddingX + AddingW; AddingB = AddingY + AddingH; if (AddingX < 0) AddingX = 0; if (AddingR > Scr->MyDisplayWidth) AddingX = Scr->MyDisplayWidth - AddingW; if (AddingY < 0) AddingY = 0; if (AddingB > Scr->MyDisplayHeight) AddingY = Scr->MyDisplayHeight - AddingH; } break; } if (event.type != MotionNotify) { continue; } XQueryPointer(dpy, Scr->Root, &JunkRoot, &JunkChild, &JunkX, &JunkY, &AddingX, &AddingY, &JunkMask); if (Scr->DontMoveOff) { int AddingR, AddingB; AddingR = AddingX + AddingW; AddingB = AddingY + AddingH; if (AddingX < 0) AddingX = 0; if (AddingR > Scr->MyDisplayWidth) AddingX = Scr->MyDisplayWidth - AddingW; if (AddingY < 0) AddingY = 0; if (AddingB > Scr->MyDisplayHeight) AddingY = Scr->MyDisplayHeight - AddingH; } /* djhjr - 4/19/96 MoveOutline(Scr->Root, AddingX, AddingY, AddingW, AddingH, tmp_win->frame_bw, tmp_win->title_height); */ /* added this 'if ... else' - djhjr - 4/14/98 */ if (tmp_win->opaque_move) { XMoveWindow(dpy, tmp_win->frame, AddingX, AddingY); PaintBorderAndTitlebar(tmp_win); /* djhjr - 4/15/98 */ if (!Scr->NoGrabServer) { /* these allow the application window to be drawn */ XUngrabServer(dpy); XSync(dpy, 0); XGrabServer(dpy); } } else MoveOutline(Scr->Root, AddingX, AddingY, AddingW, AddingH, tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); /* djhjr - 4/17/98 */ if (Scr->VirtualReceivesMotionEvents) { tmp_win->virtual_frame_x = R_TO_V_X(AddingX); tmp_win->virtual_frame_y = R_TO_V_Y(AddingY); MoveResizeDesktop(tmp_win, Scr->NoRaiseResize); } /* djhjr - 4/27/96 */ DisplayPosition (AddingX, AddingY); } if (event.xbutton.button == Button2) { int lastx, lasty; /* AddStartResize() overwrites it anyway... djhjr - 5/9/96 Scr->SizeStringOffset = width + * djhjr - 9/14/03 * #ifndef NO_I18N_SUPPORT MyFont_TextWidth(&Scr->SizeFont, ": ", 2); #else XTextWidth(Scr->SizeFont.font, ": ", 2); #endif XResizeWindow (dpy, Scr->SizeWindow, Scr->SizeStringOffset + Scr->SizeStringWidth, height); * djhjr - 9/14/03 * #ifndef NO_I18N_SUPPORT MyFont_DrawImageString (dpy, Scr->SizeWindow, &Scr->SizeFont, #else XDrawImageString (dpy, Scr->SizeWindow, #endif Scr->NormalGC, width, * djhjr - 9/14/03 SIZE_VINDENT + Scr->SizeFont.font->ascent, * SIZE_VINDENT + Scr->SizeFont.ascent, ": ", 2); */ /* djhjr - 4/15/98 */ if (!tmp_win->opaque_move && tmp_win->opaque_resize) { /* erase the move outline */ MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); AddPaintRealWindows(tmp_win, AddingX, AddingY); /* djhjr - 11/15/01 */ if (door && !doorismapped) { XMapWindow(dpy, door->w); RedoDoorName(tmp_win, door); doorismapped = True; } } #if 0 if (0/*Scr->AutoRelativeResize*/) My R5 vtvwm came with this commented out, always 0. Why? #endif if (Scr->AutoRelativeResize) { int dx = (tmp_win->attr.width / 4); int dy = (tmp_win->attr.height / 4); #define HALF_AVE_CURSOR_SIZE 8 /* so that it is visible */ if (dx < HALF_AVE_CURSOR_SIZE) dx = HALF_AVE_CURSOR_SIZE; if (dy < HALF_AVE_CURSOR_SIZE) dy = HALF_AVE_CURSOR_SIZE; #undef HALF_AVE_CURSOR_SIZE dx += (tmp_win->frame_bw + 1); dy += (bw2 + tmp_win->title_height + 1); if (AddingX + dx >= Scr->MyDisplayWidth) dx = Scr->MyDisplayWidth - AddingX - 1; if (AddingY + dy >= Scr->MyDisplayHeight) dy = Scr->MyDisplayHeight - AddingY - 1; if (dx > 0 && dy > 0) XWarpPointer (dpy, None, None, 0, 0, 0, 0, dx, dy); } else { XWarpPointer (dpy, None, Scr->Root, 0, 0, 0, 0, AddingX + AddingW/2, AddingY + AddingH/2); } AddStartResize(tmp_win, AddingX, AddingY, AddingW, AddingH); lastx = -10000; lasty = -10000; while (TRUE) { XMaskEvent(dpy, ButtonReleaseMask | ButtonMotionMask, &event); if (Event.type == MotionNotify) { /* discard any extra motion events before a release */ while(XCheckMaskEvent(dpy, ButtonMotionMask | ButtonReleaseMask, &Event)) if (Event.type == ButtonRelease) break; } if (event.type == ButtonRelease) { AddEndResize(tmp_win); /* don't need to send a configure notify event - djhjr - 4/15/98 */ if (tmp_win->opaque_move && !tmp_win->opaque_resize) SetupWindow(tmp_win, AddingX, AddingY, AddingW, AddingH, -1); /* djhjr - 11/15/01 */ if (!tmp_win->opaque_resize && door && doorismapped) RedoDoorName(tmp_win, door); break; } if (event.type != MotionNotify) { continue; } /* * XXX - if we are going to do a loop, we ought to consider * using multiple GXxor lines so that we don't need to * grab the server. */ XQueryPointer(dpy, Scr->Root, &JunkRoot, &JunkChild, &JunkX, &JunkY, &AddingX, &AddingY, &JunkMask); if (lastx != AddingX || lasty != AddingY) { DoResize(AddingX, AddingY, tmp_win); lastx = AddingX; lasty = AddingY; } } } /* if (event.xbutton.button == Button2) */ else if (event.xbutton.button == Button3) { int maxw = Scr->MyDisplayWidth - AddingX - bw2; int maxh = Scr->MyDisplayHeight - AddingY - bw2; /* * Make window go to bottom of screen, and clip to right edge. * This is useful when popping up large windows and fixed * column text windows. */ if (AddingW > maxw) AddingW = maxw; AddingH = maxh; ConstrainSize (tmp_win, &AddingW, &AddingH); /* w/o borders */ AddingW += bw2; AddingH += bw2; /* don't need to send a configure notify event - djhjr - 4/15/98 */ SetupWindow(tmp_win, AddingX, AddingY, AddingW, AddingH, -1); /* djhjr - 11/15/01 */ if (!tmp_win->opaque_resize && door && doorismapped) RedoDoorName(tmp_win, door); } else { XMaskEvent(dpy, ButtonReleaseMask, &event); } /* erase the move outline */ MoveOutline(Scr->Root, 0, 0, 0, 0, 0, 0); XUnmapWindow(dpy, Scr->SizeWindow); UninstallRootColormap(); XUngrabPointer(dpy, CurrentTime); /* djhjr - 4/15/98 tmp_win->attr.x = AddingX; tmp_win->attr.y = AddingY + tmp_win->title_height; */ tmp_win->attr.x = AddingX + tmp_win->frame_bw + tmp_win->frame_bw3D; tmp_win->attr.y = AddingY + tmp_win->title_height + tmp_win->frame_bw + tmp_win->frame_bw3D; /* djhjr - 4/19/96 tmp_win->attr.width = AddingW - bw2; tmp_win->attr.height = AddingH - tmp_win->title_height - bw2; */ tmp_win->attr.width = AddingW - bw2 - 2 * tmp_win->frame_bw3D; tmp_win->attr.height = AddingH - tmp_win->title_height - bw2 - 2 * tmp_win->frame_bw3D; /* un-grabbed in the caller AddWindow() on return - djhjr - 4/15/98 XUngrabServer(dpy); */ } } /* djhjr - 6/4/98 */ if (Scr->VirtualReceivesMotionEvents && !tmp_win->opaque_move) { XUnmapWindow(dpy, Scr->VirtualDesktopDisplay); XMapWindow(dpy, Scr->VirtualDesktopDisplay); } } else { /* put it where asked, mod title bar */ /* interpret the position specified as a virtual one if asked */ /* added 'FixManagedVirtualGeometries' - djhjr - 1/6/98 */ /* added test for 'PPosition' - submitted by Michael Dales */ if (Scr->GeometriesAreVirtual || (!Scr->GeometriesAreVirtual && (tmp_win->nailed || ( ( (Scr->FixManagedVirtualGeometries && !tmp_win->transient) || (Scr->FixTransientVirtualGeometries && tmp_win->transient) ) && (tmp_win->hints.flags & PPosition) ) ) ) ) /* * If virtual geometries is set, or virtual geometries * isn't set and (nailed or (fix virtual geometries and * preferred position)). This is a bug workaround -- DSE */ { tmp_win->attr.x = V_TO_R_X(tmp_win->attr.x); tmp_win->attr.y = V_TO_R_Y(tmp_win->attr.y); } GetGravityOffsets (tmp_win, &gravx, &gravy); /* if the gravity is towards the top, move it by the title height */ if (gravy < 0) tmp_win->attr.y -= gravy * tmp_win->title_height; } /* should never have been - djhjr - 9/21/99 if (tmp_win->opaque_move) { XSetWindowAttributes attr; attr.save_under = False; XChangeWindowAttributes(dpy, tmp_win->frame, CWSaveUnder, &attr); } */ /* * consider client borderwidths based on the ClientBorderWidth and * RandomPlacement resources, PPosition with the UsePPosition resource, * and the USPosition spec - djhjr - 6/3/98 * tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->frame_bw - tmp_win->frame_bw3D; tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height + tmp_win->old_bw - tmp_win->frame_bw - tmp_win->frame_bw3D; */ tmp_win->frame_x = tmp_win->attr.x - tmp_win->frame_bw - tmp_win->frame_bw3D; tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height - tmp_win->frame_bw - tmp_win->frame_bw3D; /* Not needed? - submitted by Jonathan Paisley - 11/8/02 if (Scr->ClientBorderWidth || !ask_user) { tmp_win->frame_x += tmp_win->old_bw; tmp_win->frame_y += tmp_win->old_bw; } */ tmp_win->frame_width = tmp_win->attr.width + 2 * tmp_win->frame_bw3D; tmp_win->frame_height = tmp_win->attr.height + tmp_win->title_height + 2 * tmp_win->frame_bw3D; ConstrainSize (tmp_win, &tmp_win->frame_width, &tmp_win->frame_height); tmp_win->virtual_frame_x = R_TO_V_X(tmp_win->frame_x); tmp_win->virtual_frame_y = R_TO_V_Y(tmp_win->frame_y); #ifdef DEBUG fprintf(stderr, " position window %d, %d %dx%d\n", tmp_win->attr.x, tmp_win->attr.y, tmp_win->attr.width, tmp_win->attr.height); #endif } /*********************************************************************** * * Procedure: * MappedNotOverride - checks to see if we should really * put a twm frame on the window * * Returned Value: * TRUE - go ahead and frame the window * FALSE - don't frame the window * * Inputs: * w - the window to check * *********************************************************************** */ int MappedNotOverride(w) Window w; { XWindowAttributes wa; XGetWindowAttributes(dpy, w, &wa); return ((wa.map_state != IsUnmapped) && (wa.override_redirect != True)); } /*********************************************************************** * * Procedure: * AddDefaultBindings - attach default bindings so that naive users * don't get messed up if they provide a minimal twmrc. */ static void do_add_binding (button, context, modifier, func) int button, context, modifier; int func; { MouseButton *mb = &Scr->Mouse[button][context][modifier]; if (mb->func) return; /* already defined */ mb->func = func; mb->item = NULL; } void AddDefaultBindings () { /* * The bindings are stored in Scr->Mouse, indexed by * Mouse[button_number][C_context][modifier]. */ #define NoModifierMask 0 do_add_binding (Button1, C_TITLE, NoModifierMask, F_MOVE); do_add_binding (Button1, C_ICON, NoModifierMask, F_ICONIFY); do_add_binding (Button1, C_ICONMGR, NoModifierMask, F_ICONIFY); do_add_binding (Button1, C_VIRTUAL, NoModifierMask, F_MOVESCREEN); do_add_binding (Button1, C_VIRTUAL_WIN, NoModifierMask, F_MOVESCREEN); do_add_binding (Button2, C_TITLE, NoModifierMask, F_RAISELOWER); do_add_binding (Button2, C_ICON, NoModifierMask, F_ICONIFY); do_add_binding (Button2, C_ICONMGR, NoModifierMask, F_ICONIFY); do_add_binding (Button2, C_VIRTUAL, NoModifierMask, F_MOVESCREEN); do_add_binding (Button2, C_VIRTUAL_WIN, NoModifierMask, F_MOVESCREEN); #undef NoModifierMask } /*********************************************************************** * * Procedure: * GrabButtons - grab needed buttons for the window * * Inputs: * tmp_win - the twm window structure to use * *********************************************************************** */ void GrabButtons(tmp_win) TwmWindow *tmp_win; { int i, j; for (i = 0; i < MAX_BUTTONS+1; i++) { for (j = 0; j < MOD_SIZE; j++) { if (Scr->Mouse[i][C_WINDOW][j].func != F_NOFUNCTION) { /* twm used to do this grab on the application main window, * tmp_win->w . This was not ICCCM complient and was changed. */ XGrabButton(dpy, i, j, tmp_win->frame, True, ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, Scr->FrameCursor); } } } } /*********************************************************************** * * Procedure: * GrabKeys - grab needed keys for the window * * Inputs: * tmp_win - the twm window structure to use * *********************************************************************** */ /* djhjr - 9/10/03 */ void GrabModKeys(w, k) Window w; FuncKey *k; { int i; XGrabKey(dpy, k->keycode, k->mods, w, True, GrabModeAsync, GrabModeAsync); for (i = 1; i <= Scr->IgnoreModifiers; i++) if ((Scr->IgnoreModifiers & i) == i) XGrabKey(dpy, k->keycode, k->mods | i, w, True, GrabModeAsync, GrabModeAsync); } /* djhjr - 9/10/03 */ void UngrabModKeys(w, k) Window w; FuncKey *k; { int i; XUngrabKey(dpy, k->keycode, k->mods, w); for (i = 1; i <= Scr->IgnoreModifiers; i++) if ((Scr->IgnoreModifiers & i) == i) XUngrabKey(dpy, k->keycode, k->mods | i, w); } void GrabKeys(tmp_win) TwmWindow *tmp_win; { FuncKey *tmp; IconMgr *p; for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next) { switch (tmp->cont) { case C_WINDOW: /* djhjr - 9/10/03 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->w, True, GrabModeAsync, GrabModeAsync); */ GrabModKeys(tmp_win->w, tmp); break; case C_ICON: if (tmp_win->icon_w) /* djhjr - 9/10/03 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->icon_w, True, GrabModeAsync, GrabModeAsync); */ GrabModKeys(tmp_win->icon_w, tmp); case C_TITLE: if (tmp_win->title_w) /* djhjr - 9/10/03 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->title_w, True, GrabModeAsync, GrabModeAsync); */ GrabModKeys(tmp_win->title_w, tmp); break; case C_NAME: /* djhjr - 9/10/03 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->w, True, GrabModeAsync, GrabModeAsync); */ GrabModKeys(tmp_win->w, tmp); if (tmp_win->icon_w) /* djhjr - 9/10/03 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->icon_w, True, GrabModeAsync, GrabModeAsync); */ GrabModKeys(tmp_win->icon_w, tmp); if (tmp_win->title_w) /* djhjr - 9/10/03 XGrabKey(dpy, tmp->keycode, tmp->mods, tmp_win->title_w, True, GrabModeAsync, GrabModeAsync); */ GrabModKeys(tmp_win->title_w, tmp); break; /* case C_ROOT: * djhjr - 9/10/03 XGrabKey(dpy, tmp->keycode, tmp->mods, Scr->Root, True, GrabModeAsync, GrabModeAsync); * GrabModKeys(Scr->Root, tmp); break; */ } } for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next) { if (tmp->cont == C_ICONMGR && !Scr->NoIconManagers) { for (p = &Scr->iconmgr; p != NULL; p = p->next) { /* djhjr - 9/10/03 XUngrabKey(dpy, tmp->keycode, tmp->mods, p->twm_win->w); */ UngrabModKeys(p->twm_win->w, tmp); } } } } static Window CreateHighlightWindow (tmp_win) TwmWindow *tmp_win; { XSetWindowAttributes attributes; /* attributes for create windows */ Pixmap pm = None; GC gc; XGCValues gcv; unsigned long valuemask; unsigned int pm_numcolors; /* added '- 2' - djhjr - 10/18/02 */ int h = (Scr->TitleHeight - 2 * Scr->FramePadding) - 2; Window w; /* djhjr - 9/14/03 #ifndef NO_I18N_SUPPORT int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1); #else * djhjr - 4/1/98 * int en = XTextWidth(Scr->TitleBarFont.font, "n", 1); #endif */ /* djhjr - 10/18/02 int width = Scr->TBInfo.titlex + tmp_win->name_width + 2 * en; */ /* * If a special highlight pixmap was given, use that. Otherwise, * use a nice, even gray pattern. The old horizontal lines look really * awful on interlaced monitors (as well as resembling other looks a * little bit too closely), but can be used by putting * * Pixmaps { TitleHighlight "hline2" } * * (or whatever the horizontal line bitmap is named) in the startup * file. If all else fails, use the foreground color to look like a * solid line. */ /* * re-written to use an Image structure for XPM support * * djhjr - 5/17/98 */ #ifdef ORIGINAL_PIXMAPS if (!Scr->hilitePm) { /* djhjr - 4/20/96 */ /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */ if (Scr->TitleBevelWidth > 0 && (Scr->Monochrome != COLOR)) Scr->hilitePm = XCreateBitmapFromData (dpy, tmp_win->title_w, (char *)black_bits, gray_width, gray_height); else Scr->hilitePm = XCreateBitmapFromData (dpy, tmp_win->title_w, gray_bits, gray_width, gray_height); Scr->hilite_pm_width = gray_width; Scr->hilite_pm_height = gray_height; } if (Scr->hilitePm) { pm = XCreatePixmap (dpy, tmp_win->title_w, Scr->hilite_pm_width, Scr->hilite_pm_height, Scr->d_depth); gcv.foreground = tmp_win->title.fore; gcv.background = tmp_win->title.back; gcv.graphics_exposures = False; gc = XCreateGC (dpy, pm, (GCForeground|GCBackground|GCGraphicsExposures), &gcv); if (gc) { XCopyPlane (dpy, Scr->hilitePm, pm, gc, 0, 0, Scr->hilite_pm_width, Scr->hilite_pm_height, 0, 0, 1); XFreeGC (dpy, gc); } else { XFreePixmap (dpy, pm); pm = None; } } if (pm) { valuemask = CWBackPixmap; attributes.background_pixmap = pm; } else { valuemask = CWBackPixel; attributes.background_pixel = tmp_win->title.fore; } #else /* ORIGINAL_PIXMAPS */ if (!Scr->hilitePm) { Scr->hilitePm = (Image *)malloc(sizeof(Image)); if (Scr->hilitePm) { Scr->hilitePm->width = gray_width; Scr->hilitePm->height = gray_height; Scr->hilitePm->mask = None; /* djhjr - 4/20/96 */ /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */ if (Scr->TitleBevelWidth > 0 && (Scr->Monochrome != COLOR)) Scr->hilitePm->pixmap = XCreateBitmapFromData (dpy, tmp_win->title_w, (char *)black_bits, Scr->hilitePm->width, Scr->hilitePm->height); else Scr->hilitePm->pixmap = XCreateBitmapFromData (dpy, tmp_win->title_w, gray_bits, Scr->hilitePm->width, Scr->hilitePm->height); } } pm_numcolors = 0; /* djhjr - 5/23/98 9/2/98 */ #ifndef NO_XPM_SUPPORT /* removed this for non-transparent pixmaps - djhjr - 5/26/98 if (Scr->hilitePm->mask != None) */ pm_numcolors = SetPixmapsBackground(Scr->hilitePm, Scr->Root, tmp_win->title.back); #endif /* * Modified to handle non-transparent pixmaps - Jason Gloudon */ if (Scr->hilitePm->pixmap) { if (pm_numcolors > 2) /* not a bitmap */ { valuemask = CWBackPixmap; attributes.background_pixmap = Scr->hilitePm->pixmap; } else { pm = XCreatePixmap (dpy, tmp_win->title_w, Scr->hilitePm->width, Scr->hilitePm->height, Scr->d_depth); gcv.foreground = tmp_win->title.fore; gcv.background = tmp_win->title.back; gcv.graphics_exposures = False; gc = XCreateGC (dpy, pm, (GCForeground | GCBackground | GCGraphicsExposures), &gcv); if (gc) { /* the copy plane works on color ! */ XCopyPlane (dpy, Scr->hilitePm->pixmap, pm, gc, 0, 0, Scr->hilitePm->width, Scr->hilitePm->height, 0, 0, 1); XFreeGC(dpy, gc); valuemask = CWBackPixmap; attributes.background_pixmap = pm; } else { valuemask = CWBackPixel; attributes.background_pixel = tmp_win->title.fore; } } } else { valuemask = CWBackPixel; attributes.background_pixel = tmp_win->title.fore; } #endif /* ORIGINAL_PIXMAPS */ /* djhjr - 10/18/02 */ #if 0 /* djhjr - 4/19/96 */ /* was 'Scr->use3Dtitles' - djhjr - 8/11/98 */ if (Scr->TitleBevelWidth > 0) /* djhjr - 4/25/96 w = XCreateWindow (dpy, tmp_win->title_w, 0, Scr->FramePadding + 2, (unsigned int) Scr->TBInfo.width, (unsigned int) (h - 4), */ /* djhjr - 4/1/98 w = XCreateWindow (dpy, tmp_win->title_w, 0, Scr->FramePadding + 3, (unsigned int) Scr->TBInfo.width, (unsigned int) (h - 6), */ w = XCreateWindow (dpy, tmp_win->title_w, width, Scr->FramePadding + 4, ComputeHighlightWindowWidth(tmp_win), (unsigned int) (h - 8), (unsigned int) 0, Scr->d_depth, (unsigned int) CopyFromParent, Scr->d_visual, valuemask, &attributes); else /* djhjr - 4/1/98 w = XCreateWindow (dpy, tmp_win->title_w, 0, Scr->FramePadding, (unsigned int) Scr->TBInfo.width, (unsigned int) h, */ w = XCreateWindow (dpy, tmp_win->title_w, width, Scr->FramePadding + 2, ComputeHighlightWindowWidth(tmp_win), (unsigned int) (h - 4), (unsigned int) 0, Scr->d_depth, (unsigned int) CopyFromParent, Scr->d_visual, valuemask, &attributes); #else w = XCreateWindow (dpy, tmp_win->title_w, tmp_win->highlightx, Scr->FramePadding + 1, ComputeHighlightWindowWidth(tmp_win), (unsigned int) h, (unsigned int) 0, Scr->d_depth, (unsigned int) CopyFromParent, Scr->d_visual, valuemask, &attributes); #endif if (pm) XFreePixmap (dpy, pm); return w; } void ComputeCommonTitleOffsets () { /* djhjr - 9/14/03 */ #ifndef NO_I18N_SUPPORT int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1); #else /* djhjr - 10/18/02 */ int en = XTextWidth(Scr->TitleBarFont.font, "n", 1); #endif int buttonwidth = (Scr->TBInfo.width + Scr->TBInfo.pad); Scr->TBInfo.leftx = Scr->TBInfo.rightoff = Scr->FramePadding; if (Scr->TBInfo.nleft > 0) Scr->TBInfo.leftx += Scr->ButtonIndent; /* 'en' was 'Scr->TitlePadding' - djhjr - 10/18/02 */ Scr->TBInfo.titlex = (Scr->TBInfo.leftx + (Scr->TBInfo.nleft * buttonwidth) - Scr->TBInfo.pad + en); if (Scr->TBInfo.nright > 0) Scr->TBInfo.rightoff += (Scr->ButtonIndent + ((Scr->TBInfo.nright * buttonwidth) - Scr->TBInfo.pad)); return; } void ComputeWindowTitleOffsets (tmp_win, width, squeeze) TwmWindow *tmp_win; int width; Bool squeeze; { /* djhjr - 9/14/03 */ #ifndef NO_I18N_SUPPORT int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1); #else /* djhjr - 10/18/02 */ int en = XTextWidth(Scr->TitleBarFont.font, "n", 1); #endif /* added 'en' - djhjr - 10/18/02 */ tmp_win->highlightx = Scr->TBInfo.titlex + tmp_win->name_width + en; /* djhjr - 10/18/02 * djhjr - 4/1/98 * * was 'Scr->use3Dtitles' - djhjr - 8/11/98 * if (Scr->TitleBevelWidth > 0) { * djhjr - 9/14/03 * #ifndef NO_I18N_SUPPORT int en = MyFont_TextWidth(&Scr->TitleBarFont, "n", 1); #else int en = XTextWidth(Scr->TitleBarFont.font, "n", 1); #endif tmp_win->highlightx += en; * rem'd out - djhjr - 4/19/96 * * reinstated - djhjr - 4/1/98 * tmp_win->highlightx += 6; } if (tmp_win->hilite_w || Scr->TBInfo.nright > 0) tmp_win->highlightx += Scr->TitlePadding; */ tmp_win->rightx = width - Scr->TBInfo.rightoff; if (squeeze && tmp_win->squeeze_info) { /* djhjr - 3/13/97 8/11/98 */ /* this used to care about title bevels - djhjr - 10/18/02 */ int rx = tmp_win->highlightx + ((tmp_win->titlehighlight) ? Scr->TitleHeight * 2 : 0); if (rx < tmp_win->rightx) tmp_win->rightx = rx; } return; } /* * ComputeTitleLocation - calculate the position of the title window. * * substantially re-written - djhjr - 1/8/98 */ void ComputeTitleLocation (tmp) TwmWindow *tmp; { tmp->title_x = tmp->frame_bw3D - tmp->frame_bw; tmp->title_y = tmp->frame_bw3D - tmp->frame_bw; if (tmp->squeeze_info) { SqueezeInfo *si = tmp->squeeze_info; int basex; int fw = tmp->frame_bw + tmp->frame_bw3D; if (si->denom != 0 && si->num != 0) basex = ((tmp->frame_width - tmp->title_width) / si->denom) * si->num + fw; else if (si->denom == 0 && si->num != 0) basex = si->num + fw; else switch (si->justify) { case J_LEFT: basex = tmp->title_x + fw; break; case J_CENTER: basex = tmp->frame_width / 2 - (tmp->title_width / 2 - fw); break; case J_RIGHT: basex = tmp->frame_width - tmp->title_width; break; } if (basex > tmp->frame_width - tmp->title_width) basex = tmp->frame_width - tmp->title_width; if (basex < 0) basex = tmp->title_x + fw; tmp->title_x = basex - fw; } } static void CreateWindowTitlebarButtons (tmp_win) TwmWindow *tmp_win; { unsigned long valuemask; /* mask for create windows */ XSetWindowAttributes attributes; /* attributes for create windows */ TitleButton *tb; TBWindow *tbw; int boxwidth = Scr->TBInfo.width + Scr->TBInfo.pad; unsigned int h = Scr->TBInfo.width - Scr->TBInfo.border * 2; int x, y = Scr->FramePadding + Scr->ButtonIndent; /* init - djhjr - 10/18/02 */ int nb, leftx, rightx; if (tmp_win->title_height == 0) { tmp_win->hilite_w = 0; return; } /* * create the title bar windows; let the event handler deal with painting * so that we don't have to spend two pixmaps (or deal with hashing) */ ComputeWindowTitleOffsets (tmp_win, tmp_win->attr.width, False); /* djhjr - 10/18/02 leftx = y = Scr->TBInfo.leftx; */ leftx = Scr->TBInfo.leftx; rightx = tmp_win->rightx; attributes.background_pixel = tmp_win->title.back; attributes.border_pixel = tmp_win->title.fore; attributes.event_mask = (ButtonPressMask | ButtonReleaseMask | ExposureMask); attributes.cursor = Scr->ButtonCursor; valuemask = (CWWinGravity | CWBackPixel | CWBorderPixel | CWEventMask | CWCursor); tmp_win->titlebuttons = NULL; nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; if (nb > 0) { tmp_win->titlebuttons = (TBWindow *) malloc (nb * sizeof(TBWindow)); if (!tmp_win->titlebuttons) { fprintf (stderr, "%s: unable to allocate %d titlebuttons\n", ProgramName, nb); } else { for (tb = Scr->TBInfo.head, tbw = tmp_win->titlebuttons; tb; tb = tb->next, tbw++) { if (tb->rightside) { x = rightx; rightx += boxwidth; attributes.win_gravity = NorthEastGravity; } else { x = leftx; leftx += boxwidth; attributes.win_gravity = NorthWestGravity; } tbw->window = XCreateWindow (dpy, tmp_win->title_w, x, y, h, h, (unsigned int) Scr->TBInfo.border, 0, (unsigned int) CopyFromParent, (Visual *) CopyFromParent, valuemask, &attributes); tbw->info = tb; } /* end for(...) */ } } /* djhjr - 4/5/98 tmp_win->hilite_w = (tmp_win->titlehighlight ? CreateHighlightWindow (tmp_win) : None); XMapSubwindows(dpy, tmp_win->title_w); * djhjr - 4/25/96 if (tmp_win->hilite_w) XUnmapWindow(dpy, tmp_win->hilite_w); * PaintTitleHighlight(tmp_win, off); */ /* was '!Scr->SunkFocusWindowTitle' - djhjr - 10/25/02 */ tmp_win->hilite_w = (tmp_win->titlehighlight && !Scr->hiliteName) ? CreateHighlightWindow(tmp_win) : None; return; } /* * re-written to use an Image structure for XPM support * * djhjr - 5/17/98 */ #ifdef ORIGINAL_PIXMAPS void SetHighlightPixmap (filename) char *filename; { Pixmap pm = GetBitmap (filename); if (pm) { if (Scr->hilitePm) { XFreePixmap (dpy, Scr->hilitePm); } Scr->hilitePm = pm; Scr->hilite_pm_width = JunkWidth; Scr->hilite_pm_height = JunkHeight; } } #else /* ORIGINAL_PIXMAPS */ void SetHighlightPixmap (filename) char *filename; { /* added this 'if (...) else' - djhjr - 10/25/02 */ if (filename[0] == ':') Scr->hiliteName = filename; else if (!Scr->hilitePm) Scr->hilitePm = SetPixmapsPixmap(filename); } #endif /* ORIGINAL_PIXMAPS */ void FetchWmProtocols (tmp) TwmWindow *tmp; { unsigned long flags = 0L; Atom *protocols = NULL; int n; if (XGetWMProtocols (dpy, tmp->w, &protocols, &n)) { register int i; register Atom *ap; for (i = 0, ap = protocols; i < n; i++, ap++) { if (*ap == _XA_WM_TAKE_FOCUS) flags |= DoesWmTakeFocus; if (*ap == _XA_WM_SAVE_YOURSELF) flags |= DoesWmSaveYourself; if (*ap == _XA_WM_DELETE_WINDOW) flags |= DoesWmDeleteWindow; } if (protocols) XFree ((char *) protocols); } tmp->protocols = flags; } TwmColormap * CreateTwmColormap(c) Colormap c; { TwmColormap *cmap; cmap = (TwmColormap *) malloc(sizeof(TwmColormap)); if (!cmap || XSaveContext(dpy, c, ColormapContext, (caddr_t) cmap)) { if (cmap) free((char *) cmap); return (NULL); } cmap->c = c; cmap->state = 0; cmap->install_req = 0; cmap->w = None; cmap->refcnt = 1; return (cmap); } ColormapWindow * CreateColormapWindow(w, creating_parent, property_window) Window w; Bool creating_parent; Bool property_window; { ColormapWindow *cwin; TwmColormap *cmap; XWindowAttributes attributes; cwin = (ColormapWindow *) malloc(sizeof(ColormapWindow)); if (cwin) { if (!XGetWindowAttributes(dpy, w, &attributes) || XSaveContext(dpy, w, ColormapContext, (caddr_t) cwin)) { free((char *) cwin); return (NULL); } if (XFindContext(dpy, attributes.colormap, ColormapContext, (caddr_t *)&cwin->colormap) == XCNOENT) { cwin->colormap = cmap = CreateTwmColormap(attributes.colormap); if (!cmap) { XDeleteContext(dpy, w, ColormapContext); free((char *) cwin); return (NULL); } } else { cwin->colormap->refcnt++; } cwin->w = w; /* * Assume that windows in colormap list are * obscured if we are creating the parent window. * Otherwise, we assume they are unobscured. */ cwin->visibility = creating_parent ? VisibilityPartiallyObscured : VisibilityUnobscured; cwin->refcnt = 1; /* * If this is a ColormapWindow property window and we * are not monitoring ColormapNotify or VisibilityNotify * events, we need to. */ if (property_window && (attributes.your_event_mask & (ColormapChangeMask|VisibilityChangeMask)) != (ColormapChangeMask|VisibilityChangeMask)) { XSelectInput(dpy, w, attributes.your_event_mask | (ColormapChangeMask|VisibilityChangeMask)); } } return (cwin); } void FetchWmColormapWindows (tmp) TwmWindow *tmp; { register int i, j; Window *cmap_windows = NULL; Bool can_free_cmap_windows = False; int number_cmap_windows = 0; ColormapWindow **cwins = NULL; int previously_installed; extern void free_cwins(); number_cmap_windows = 0; if ((previously_installed = (Scr->cmapInfo.cmaps == &tmp->cmaps) && tmp->cmaps.number_cwins)) { cwins = tmp->cmaps.cwins; for (i = 0; i < tmp->cmaps.number_cwins; i++) cwins[i]->colormap->state = 0; } if (XGetWMColormapWindows (dpy, tmp->w, &cmap_windows, &number_cmap_windows) && number_cmap_windows > 0) { can_free_cmap_windows = False; /* * check if the top level is in the list, add to front if not */ for (i = 0; i < number_cmap_windows; i++) { if (cmap_windows[i] == tmp->w) break; } if (i == number_cmap_windows) { /* not in list */ Window *new_cmap_windows = (Window *) malloc (sizeof(Window) * (number_cmap_windows + 1)); if (!new_cmap_windows) { fprintf (stderr, "%s: unable to allocate %d element colormap window array\n", ProgramName, number_cmap_windows+1); goto done; } new_cmap_windows[0] = tmp->w; /* add to front */ for (i = 0; i < number_cmap_windows; i++) { /* append rest */ new_cmap_windows[i+1] = cmap_windows[i]; } XFree ((char *) cmap_windows); can_free_cmap_windows = True; /* do not use XFree any more */ cmap_windows = new_cmap_windows; number_cmap_windows++; } cwins = (ColormapWindow **) malloc(sizeof(ColormapWindow *) * number_cmap_windows); if (cwins) { for (i = 0; i < number_cmap_windows; i++) { /* * Copy any existing entries into new list. */ for (j = 0; j < tmp->cmaps.number_cwins; j++) { if (tmp->cmaps.cwins[j]->w == cmap_windows[i]) { cwins[i] = tmp->cmaps.cwins[j]; cwins[i]->refcnt++; break; } } /* * If the colormap window is not being pointed by * some other applications colormap window list, * create a new entry. */ if (j == tmp->cmaps.number_cwins) { if (XFindContext(dpy, cmap_windows[i], ColormapContext, (caddr_t *)&cwins[i]) == XCNOENT) { if ((cwins[i] = CreateColormapWindow(cmap_windows[i], (Bool) tmp->cmaps.number_cwins == 0, True)) == NULL) { int k; for (k = i + 1; k < number_cmap_windows; k++) cmap_windows[k-1] = cmap_windows[k]; i--; number_cmap_windows--; } } else cwins[i]->refcnt++; } } } } /* No else here, in case we bailed out of clause above. */ if (number_cmap_windows == 0) { number_cmap_windows = 1; cwins = (ColormapWindow **) malloc(sizeof(ColormapWindow *)); if (XFindContext(dpy, tmp->w, ColormapContext, (caddr_t *)&cwins[0]) == XCNOENT) cwins[0] = CreateColormapWindow(tmp->w, (Bool) tmp->cmaps.number_cwins == 0, False); else cwins[0]->refcnt++; } if (tmp->cmaps.number_cwins) free_cwins(tmp); tmp->cmaps.cwins = cwins; tmp->cmaps.number_cwins = number_cmap_windows; if (number_cmap_windows > 1) tmp->cmaps.scoreboard = (char *) calloc(1, ColormapsScoreboardLength(&tmp->cmaps)); if (previously_installed) InstallWindowColormaps(PropertyNotify, (TwmWindow *) NULL); done: if (cmap_windows) { if (can_free_cmap_windows) free ((char *) cmap_windows); else XFree ((char *) cmap_windows); } return; } void GetWindowSizeHints (tmp) TwmWindow *tmp; { long supplied = 0; if (!XGetWMNormalHints (dpy, tmp->w, &tmp->hints, &supplied)) tmp->hints.flags = 0; if (tmp->hints.flags & PResizeInc) { if (tmp->hints.width_inc == 0) tmp->hints.width_inc = 1; if (tmp->hints.height_inc == 0) tmp->hints.height_inc = 1; } if (!(supplied & PWinGravity) && (tmp->hints.flags & USPosition)) { static int gravs[] = { SouthEastGravity, SouthWestGravity, NorthEastGravity, NorthWestGravity }; int right = tmp->attr.x + tmp->attr.width + 2 * tmp->old_bw; int bottom = tmp->attr.y + tmp->attr.height + 2 * tmp->old_bw; /* djhjr - 4/19/96 tmp->hints.win_gravity = gravs[((Scr->MyDisplayHeight - bottom < tmp->title_height) ? 0 : 2) | ((Scr->MyDisplayWidth - right < tmp->title_height) ? 0 : 1)]; */ tmp->hints.win_gravity = gravs[((Scr->MyDisplayHeight - bottom < tmp->title_height + 2 * tmp->frame_bw3D) ? 0 : 2) | ((Scr->MyDisplayWidth - right < tmp->title_height + 2 * tmp->frame_bw3D) ? 0 : 1)]; tmp->hints.flags |= PWinGravity; } }