/*****************************************************************************/
/** 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 <stdio.h>
#include <string.h>
#include "twm.h"
#include <X11/Xatom.h>
#ifndef NO_XPM_SUPPORT
#include <X11/xpm.h>
#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 <seth@baka.org> - 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 <seth@baka.org> - 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;
}
}
syntax highlighted by Code2HTML, v. 0.9.1