add_window.c revision 645f5050
1645f5050Syouri/*****************************************************************************/ 2645f5050Syouri/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/ 3645f5050Syouri/** Salt Lake City, Utah **/ 4645f5050Syouri/** Portions Copyright 1989 by the Massachusetts Institute of Technology **/ 5645f5050Syouri/** Cambridge, Massachusetts **/ 6645f5050Syouri/** **/ 7645f5050Syouri/** All Rights Reserved **/ 8645f5050Syouri/** **/ 9645f5050Syouri/** Permission to use, copy, modify, and distribute this software and **/ 10645f5050Syouri/** its documentation for any purpose and without fee is hereby **/ 11645f5050Syouri/** granted, provided that the above copyright notice appear in all **/ 12645f5050Syouri/** copies and that both that copyright notice and this permis- **/ 13645f5050Syouri/** sion notice appear in supporting documentation, and that the **/ 14645f5050Syouri/** names of Evans & Sutherland and M.I.T. not be used in advertising **/ 15645f5050Syouri/** in publicity pertaining to distribution of the software without **/ 16645f5050Syouri/** specific, written prior permission. **/ 17645f5050Syouri/** **/ 18645f5050Syouri/** EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD **/ 19645f5050Syouri/** TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- **/ 20645f5050Syouri/** ABILITY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND OR **/ 21645f5050Syouri/** M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAM- **/ 22645f5050Syouri/** AGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ 23645f5050Syouri/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ 24645f5050Syouri/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ 25645f5050Syouri/** OR PERFORMANCE OF THIS SOFTWARE. **/ 26645f5050Syouri/*****************************************************************************/ 27645f5050Syouri 28645f5050Syouri/* 29645f5050Syouri * [ ctwm ] 30645f5050Syouri * 31645f5050Syouri * Copyright 1992 Claude Lecommandeur. 32645f5050Syouri * 33645f5050Syouri * Permission to use, copy, modify and distribute this software [ctwm] and 34645f5050Syouri * its documentation for any purpose is hereby granted without fee, provided 35645f5050Syouri * that the above copyright notice appear in all copies and that both that 36645f5050Syouri * copyright notice and this permission notice appear in supporting documen- 37645f5050Syouri * tation, and that the name of Claude Lecommandeur not be used in adverti- 38645f5050Syouri * sing or publicity pertaining to distribution of the software without 39645f5050Syouri * specific, written prior permission. Claude Lecommandeur make no represen- 40645f5050Syouri * tations about the suitability of this software for any purpose. It is 41645f5050Syouri * provided "as is" without express or implied warranty. 42645f5050Syouri * 43645f5050Syouri * Claude Lecommandeur DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 44645f5050Syouri * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 45645f5050Syouri * EVENT SHALL Claude Lecommandeur BE LIABLE FOR ANY SPECIAL, INDIRECT OR 46645f5050Syouri * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 47645f5050Syouri * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 48645f5050Syouri * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 49645f5050Syouri * PERFORMANCE OF THIS SOFTWARE. 50645f5050Syouri * 51645f5050Syouri * Author: Claude Lecommandeur [ lecom@sic.epfl.ch ][ April 1992 ] 52645f5050Syouri */ 53645f5050Syouri 54645f5050Syouri/********************************************************************** 55645f5050Syouri * 56645f5050Syouri * $XConsortium: add_window.c,v 1.153 91/07/10 13:17:26 dave Exp $ 57645f5050Syouri * 58645f5050Syouri * Add a new window, put the titlbar and other stuff around 59645f5050Syouri * the window 60645f5050Syouri * 61645f5050Syouri * 31-Mar-88 Tom LaStrange Initial Version. 62645f5050Syouri * 63645f5050Syouri * Do the necessary modification to be integrated in ctwm. 64645f5050Syouri * Can no longer be used for the standard twm. 65645f5050Syouri * 66645f5050Syouri * 22-April-92 Claude Lecommandeur. 67645f5050Syouri * 68645f5050Syouri **********************************************************************/ 69645f5050Syouri 70645f5050Syouri#include <stdio.h> 71645f5050Syouri#include <string.h> 72645f5050Syouri#ifndef VMS 73645f5050Syouri#include <sys/time.h> 74645f5050Syouri#else 75645f5050Syouri#include <time.h> 76645f5050Syouri#endif 77645f5050Syouri#if defined(AIXV3) || defined(_SYSTYPE_SVR4) || defined(ibm) || defined __QNX__ 78645f5050Syouri#include <sys/select.h> 79645f5050Syouri#endif 80645f5050Syouri#include "twm.h" 81645f5050Syouri#ifdef VMS 82645f5050Syouri#include <decw$include/Xatom.h> 83645f5050Syouri#else 84645f5050Syouri#include <X11/Xatom.h> 85645f5050Syouri#endif 86645f5050Syouri#include "add_window.h" 87645f5050Syouri#include "windowbox.h" 88645f5050Syouri#include "util.h" 89645f5050Syouri#include "resize.h" 90645f5050Syouri#include "parse.h" 91645f5050Syouri#include "list.h" 92645f5050Syouri#include "events.h" 93645f5050Syouri#include "menus.h" 94645f5050Syouri#include "screen.h" 95645f5050Syouri#include "icons.h" 96645f5050Syouri#include "iconmgr.h" 97645f5050Syouri#include "session.h" 98645f5050Syouri#include "mwmhints.h" 99645f5050Syouri 100645f5050Syouri#define gray_width 2 101645f5050Syouri#define gray_height 2 102645f5050Syouristatic unsigned char gray_bits[] = { 103645f5050Syouri 0x02, 0x01}; 104645f5050Syouristatic unsigned char black_bits[] = { 105645f5050Syouri 0xFF, 0xFF}; 106645f5050Syouri 107645f5050Syouriint AddingX; 108645f5050Syouriint AddingY; 109645f5050Syouriunsigned int AddingW; 110645f5050Syouriunsigned int AddingH; 111645f5050Syouri 112645f5050Syouristatic int PlaceX = -1; 113645f5050Syouristatic int PlaceY = -1; 114645f5050Syouristatic void CreateWindowTitlebarButtons(TwmWindow *tmp_win); 115645f5050Syourivoid DealWithNonSensicalGeometries(Display *dpy, Window vroot, TwmWindow *tmp_win); 116645f5050Syouri 117645f5050Syouristatic void splitWindowRegionEntry (WindowEntry *we, 118645f5050Syouri int grav1, int grav2, 119645f5050Syouri int w, int h); 120645f5050Syouristatic WindowEntry *findWindowEntry (WorkSpace *wl, 121645f5050Syouri TwmWindow *tmp_win, 122645f5050Syouri WindowRegion **wrp); 123645f5050Syouristatic WindowEntry *prevWindowEntry (WindowEntry *we, 124645f5050Syouri WindowRegion *wr); 125645f5050Syouristatic void mergeWindowEntries (WindowEntry *old, WindowEntry *we); 126645f5050Syouri 127645f5050Syourichar NoName[] = "Untitled"; /* name if no name is specified */ 128645f5050Syouriint resizeWhenAdd; 129645f5050Syouri 130645f5050Syouriextern Atom _OL_WIN_ATTR; 131645f5050Syouri 132645f5050Syouri#if defined(__hpux) && !defined(_XPG4_EXTENDED) 133645f5050Syouri# define FDSET int* 134645f5050Syouri#else 135645f5050Syouri# define FDSET fd_set* 136645f5050Syouri#endif 137645f5050Syouri/************************************************************************ 138645f5050Syouri * 139645f5050Syouri * Procedure: 140645f5050Syouri * GetGravityOffsets - map gravity to (x,y) offset signs for adding 141645f5050Syouri * to x and y when window is mapped to get proper placement. 142645f5050Syouri * 143645f5050Syouri ************************************************************************ 144645f5050Syouri */ 145645f5050Syouri 146645f5050Syourivoid GetGravityOffsets (TwmWindow *tmp, /* window from which to get gravity */ 147645f5050Syouri int *xp, int *yp) /* return values */ 148645f5050Syouri{ 149645f5050Syouri static struct _gravity_offset { 150645f5050Syouri int x, y; 151645f5050Syouri } gravity_offsets[11] = { 152645f5050Syouri { 0, 0 }, /* ForgetGravity */ 153645f5050Syouri { -1, -1 }, /* NorthWestGravity */ 154645f5050Syouri { 0, -1 }, /* NorthGravity */ 155645f5050Syouri { 1, -1 }, /* NorthEastGravity */ 156645f5050Syouri { -1, 0 }, /* WestGravity */ 157645f5050Syouri { 0, 0 }, /* CenterGravity */ 158645f5050Syouri { 1, 0 }, /* EastGravity */ 159645f5050Syouri { -1, 1 }, /* SouthWestGravity */ 160645f5050Syouri { 0, 1 }, /* SouthGravity */ 161645f5050Syouri { 1, 1 }, /* SouthEastGravity */ 162645f5050Syouri { 0, 0 }, /* StaticGravity */ 163645f5050Syouri }; 164645f5050Syouri register int g = ((tmp->hints.flags & PWinGravity) 165645f5050Syouri ? tmp->hints.win_gravity : NorthWestGravity); 166645f5050Syouri 167645f5050Syouri if (g < ForgetGravity || g > StaticGravity) { 168645f5050Syouri *xp = *yp = 0; 169645f5050Syouri } else { 170645f5050Syouri *xp = gravity_offsets[g].x; 171645f5050Syouri *yp = gravity_offsets[g].y; 172645f5050Syouri } 173645f5050Syouri} 174645f5050Syouri 175645f5050Syouri 176645f5050Syouri 177645f5050Syouri 178645f5050Syouri/*********************************************************************** 179645f5050Syouri * 180645f5050Syouri * Procedure: 181645f5050Syouri * AddWindow - add a new window to the twm list 182645f5050Syouri * 183645f5050Syouri * Returned Value: 184645f5050Syouri * (TwmWindow *) - pointer to the TwmWindow structure 185645f5050Syouri * 186645f5050Syouri * Inputs: 187645f5050Syouri * w - the window id of the window to add 188645f5050Syouri * iconm - flag to tell if this is an icon manager window 189645f5050Syouri * 0 --> normal window. 190645f5050Syouri * 1 --> icon manager. 191645f5050Syouri * 2 --> window box; 192645f5050Syouri * else --> iconmgr; 193645f5050Syouri * 194645f5050Syouri * iconp - pointer to icon manager struct 195645f5050Syouri * 196645f5050Syouri *********************************************************************** 197645f5050Syouri */ 198645f5050Syouri 199645f5050SyouriTwmWindow *AddWindow(Window w, int iconm, IconMgr *iconp) 200645f5050Syouri{ 201645f5050Syouri virtualScreen *vs; 202645f5050Syouri TwmWindow *tmp_win; /* new twm window structure */ 203645f5050Syouri int stat; 204645f5050Syouri XEvent event; 205645f5050Syouri unsigned long valuemask; /* mask for create windows */ 206645f5050Syouri XSetWindowAttributes attributes; /* attributes for create windows */ 207645f5050Syouri int width, height; /* tmp variable */ 208645f5050Syouri int ask_user; /* don't know where to put the window */ 209645f5050Syouri int gravx, gravy; /* gravity signs for positioning */ 210645f5050Syouri int namelen; 211645f5050Syouri int bw2; 212645f5050Syouri short saved_x, saved_y, restore_icon_x, restore_icon_y; 213645f5050Syouri unsigned short saved_width, saved_height; 214645f5050Syouri Bool restore_iconified = 0; 215645f5050Syouri Bool restore_icon_info_present = 0; 216645f5050Syouri int restoredFromPrevSession; 217645f5050Syouri Bool width_ever_changed_by_user; 218645f5050Syouri Bool height_ever_changed_by_user; 219645f5050Syouri int saved_occupation; /* <== [ Matthew McNeill Feb 1997 ] == */ 220645f5050Syouri Bool random_placed = False; 221645f5050Syouri int found = 0; 222645f5050Syouri#ifndef VMS 223645f5050Syouri fd_set mask; 224645f5050Syouri int fd; 225645f5050Syouri struct timeval timeout; 226645f5050Syouri#endif 227645f5050Syouri XRectangle ink_rect; 228645f5050Syouri XRectangle logical_rect; 229645f5050Syouri WindowBox *winbox; 230645f5050Syouri int iswinbox = 0; 231645f5050Syouri int iswman = 0; 232645f5050Syouri Window vroot; 233645f5050Syouri 234645f5050Syouri#ifdef DEBUG 235645f5050Syouri fprintf(stderr, "AddWindow: w = 0x%x\n", w); 236645f5050Syouri#endif 237645f5050Syouri 238645f5050Syouri if (!captive && RedirectToCaptive (w)) return (NULL); 239645f5050Syouri 240645f5050Syouri /* allocate space for the twm window */ 241645f5050Syouri tmp_win = (TwmWindow *)calloc(1, sizeof(TwmWindow)); 242645f5050Syouri if (tmp_win == 0) 243645f5050Syouri { 244645f5050Syouri fprintf (stderr, "%s: Unable to allocate memory to manage window ID %lx.\n", 245645f5050Syouri ProgramName, w); 246645f5050Syouri return NULL; 247645f5050Syouri } 248645f5050Syouri switch (iconm) { 249645f5050Syouri case 0 : iswinbox = 0; break; 250645f5050Syouri case 1 : iswinbox = 0; break; 251645f5050Syouri case 2 : iswinbox = 1; iconm = 0; break; 252645f5050Syouri case 3 : iswman = 1; iconm = 0; break; 253645f5050Syouri default : iswinbox = 0; iswman = 0; iconm = 1; break; 254645f5050Syouri } 255645f5050Syouri tmp_win->w = w; 256645f5050Syouri tmp_win->zoomed = ZOOM_NONE; 257645f5050Syouri tmp_win->iconmgr = iconm; 258645f5050Syouri tmp_win->iconmgrp = iconp; 259645f5050Syouri tmp_win->wspmgr = iswman; 260645f5050Syouri tmp_win->iswinbox = iswinbox; 261645f5050Syouri tmp_win->vs = NULL; 262645f5050Syouri tmp_win->old_parent_vs = NULL; 263645f5050Syouri tmp_win->savevs = NULL; 264645f5050Syouri tmp_win->cmaps.number_cwins = 0; 265645f5050Syouri tmp_win->savegeometry.width = -1; 266645f5050Syouri 267645f5050Syouri XSelectInput(dpy, tmp_win->w, PropertyChangeMask); 268645f5050Syouri XGetWindowAttributes(dpy, tmp_win->w, &tmp_win->attr); 269645f5050Syouri tmp_win->name = (char*) GetWMPropertyString(tmp_win->w, XA_WM_NAME); 270645f5050Syouri tmp_win->class = NoClass; 271645f5050Syouri XGetClassHint(dpy, tmp_win->w, &tmp_win->class); 272645f5050Syouri FetchWmProtocols (tmp_win); 273645f5050Syouri FetchWmColormapWindows (tmp_win); 274645f5050Syouri 275645f5050Syouri if (GetWindowConfig (tmp_win, 276645f5050Syouri &saved_x, &saved_y, &saved_width, &saved_height, 277645f5050Syouri &restore_iconified, &restore_icon_info_present, 278645f5050Syouri &restore_icon_x, &restore_icon_y, 279645f5050Syouri &width_ever_changed_by_user, &height_ever_changed_by_user, 280645f5050Syouri &saved_occupation)) /* <== [ Matthew McNeill Feb 1997 ] == */ 281645f5050Syouri { 282645f5050Syouri tmp_win->attr.x = saved_x; 283645f5050Syouri tmp_win->attr.y = saved_y; 284645f5050Syouri 285645f5050Syouri tmp_win->widthEverChangedByUser = width_ever_changed_by_user; 286645f5050Syouri tmp_win->heightEverChangedByUser = height_ever_changed_by_user; 287645f5050Syouri 288645f5050Syouri if (width_ever_changed_by_user) 289645f5050Syouri tmp_win->attr.width = saved_width; 290645f5050Syouri 291645f5050Syouri if (height_ever_changed_by_user) 292645f5050Syouri tmp_win->attr.height = saved_height; 293645f5050Syouri 294645f5050Syouri restoredFromPrevSession = 1; 295645f5050Syouri } 296645f5050Syouri else 297645f5050Syouri { 298645f5050Syouri tmp_win->widthEverChangedByUser = False; 299645f5050Syouri tmp_win->heightEverChangedByUser = False; 300645f5050Syouri 301645f5050Syouri restoredFromPrevSession = 0; 302645f5050Syouri } 303645f5050Syouri 304645f5050Syouri /* 305645f5050Syouri * do initial clip; should look at window gravity 306645f5050Syouri */ 307645f5050Syouri if (tmp_win->attr.width > Scr->MaxWindowWidth) 308645f5050Syouri tmp_win->attr.width = Scr->MaxWindowWidth; 309645f5050Syouri if (tmp_win->attr.height > Scr->MaxWindowHeight) 310645f5050Syouri tmp_win->attr.height = Scr->MaxWindowHeight; 311645f5050Syouri 312645f5050Syouri tmp_win->wmhints = XGetWMHints(dpy, tmp_win->w); 313645f5050Syouri 314645f5050Syouri if (tmp_win->wmhints) 315645f5050Syouri { 316645f5050Syouri if (restore_iconified) 317645f5050Syouri { 318645f5050Syouri tmp_win->wmhints->initial_state = IconicState; 319645f5050Syouri tmp_win->wmhints->flags |= StateHint; 320645f5050Syouri } 321645f5050Syouri 322645f5050Syouri if (restore_icon_info_present) 323645f5050Syouri { 324645f5050Syouri tmp_win->wmhints->icon_x = restore_icon_x; 325645f5050Syouri tmp_win->wmhints->icon_y = restore_icon_y; 326645f5050Syouri tmp_win->wmhints->flags |= IconPositionHint; 327645f5050Syouri } 328645f5050Syouri } 329645f5050Syouri 330645f5050Syouri if (tmp_win->wmhints) tmp_win->wmhints->input = True; 331645f5050Syouri /* CL: Having with not willing focus 332645f5050Syouri cause problems with AutoSqueeze and a few others 333645f5050Syouri things. So I suppress it. And the whole focus thing 334645f5050Syouri is buggy anyway */ 335645f5050Syouri if (tmp_win->wmhints && !(tmp_win->wmhints->flags & InputHint)) 336645f5050Syouri tmp_win->wmhints->input = True; 337645f5050Syouri if (tmp_win->wmhints && (tmp_win->wmhints->flags & WindowGroupHint)) { 338645f5050Syouri tmp_win->group = tmp_win->wmhints->window_group; 339645f5050Syouri if (tmp_win->group) { 340645f5050Syouri /* 341645f5050Syouri * GTK windows often have a spurious "group leader" window which is 342645f5050Syouri * never reported to us and therefore does not really exist. This 343645f5050Syouri * is annoying because we treat group members a lot like transient 344645f5050Syouri * windows. Look for that here. It is in fact a duplicate of the 345645f5050Syouri * WM_CLIENT_LEADER property. 346645f5050Syouri */ 347645f5050Syouri if (tmp_win->group != w && !GetTwmWindow(tmp_win->group)) { 348645f5050Syouri tmp_win->group = 0; 349645f5050Syouri } 350645f5050Syouri } 351645f5050Syouri } else 352645f5050Syouri tmp_win->group = 0; 353645f5050Syouri 354645f5050Syouri /* 355645f5050Syouri * The July 27, 1988 draft of the ICCCM ignores the size and position 356645f5050Syouri * fields in the WM_NORMAL_HINTS property. 357645f5050Syouri */ 358645f5050Syouri 359645f5050Syouri tmp_win->transient = Transient(tmp_win->w, &tmp_win->transientfor); 360645f5050Syouri 361645f5050Syouri tmp_win->nameChanged = 0; 362645f5050Syouri if (tmp_win->name == NULL) 363645f5050Syouri tmp_win->name = NoName; 364645f5050Syouri if (tmp_win->class.res_name == NULL) 365645f5050Syouri tmp_win->class.res_name = NoName; 366645f5050Syouri if (tmp_win->class.res_class == NULL) 367645f5050Syouri tmp_win->class.res_class = NoName; 368645f5050Syouri 369645f5050Syouri /* 370645f5050Syouri * full_name seems to exist only because in the conditional code below, 371645f5050Syouri * name is sometimes changed. In all other cases, name and full_name 372645f5050Syouri * seem to be identical. Is that worth it? 373645f5050Syouri */ 374645f5050Syouri tmp_win->full_name = tmp_win->name; 375645f5050Syouri#ifdef CLAUDE 376645f5050Syouri if (strstr (tmp_win->name, " - Mozilla")) { 377645f5050Syouri char *moz = strstr (tmp_win->name, " - Mozilla"); 378645f5050Syouri *moz = '\0'; 379645f5050Syouri } 380645f5050Syouri#endif 381645f5050Syouri namelen = strlen (tmp_win->name); 382645f5050Syouri 383645f5050Syouri if (LookInList(Scr->IgnoreTransientL, tmp_win->full_name, &tmp_win->class)) 384645f5050Syouri tmp_win->transient = 0; 385645f5050Syouri 386645f5050Syouri tmp_win->highlight = Scr->Highlight && 387645f5050Syouri (!LookInList(Scr->NoHighlight, tmp_win->full_name, 388645f5050Syouri &tmp_win->class)); 389645f5050Syouri 390645f5050Syouri tmp_win->stackmode = Scr->StackMode && 391645f5050Syouri (!LookInList(Scr->NoStackModeL, tmp_win->full_name, 392645f5050Syouri &tmp_win->class)); 393645f5050Syouri 394645f5050Syouri tmp_win->ontoppriority = (LookInList(Scr->AlwaysOnTopL, 395645f5050Syouri tmp_win->full_name, &tmp_win->class)) ? ONTOP_MAX : ONTOP_DEFAULT; 396645f5050Syouri 397645f5050Syouri tmp_win->titlehighlight = Scr->TitleHighlight && 398645f5050Syouri (!LookInList(Scr->NoTitleHighlight, tmp_win->full_name, 399645f5050Syouri &tmp_win->class)); 400645f5050Syouri 401645f5050Syouri tmp_win->auto_raise = Scr->AutoRaiseDefault || 402645f5050Syouri LookInList(Scr->AutoRaise, tmp_win->full_name, 403645f5050Syouri &tmp_win->class); 404645f5050Syouri if (tmp_win->auto_raise) Scr->NumAutoRaises++; 405645f5050Syouri 406645f5050Syouri tmp_win->auto_lower = Scr->AutoLowerDefault || 407645f5050Syouri LookInList(Scr->AutoLower, tmp_win->full_name, 408645f5050Syouri &tmp_win->class); 409645f5050Syouri if (tmp_win->auto_lower) Scr->NumAutoLowers++; 410645f5050Syouri 411645f5050Syouri tmp_win->iconify_by_unmapping = Scr->IconifyByUnmapping; 412645f5050Syouri if (Scr->IconifyByUnmapping) 413645f5050Syouri { 414645f5050Syouri tmp_win->iconify_by_unmapping = iconm ? FALSE : 415645f5050Syouri !LookInList(Scr->DontIconify, tmp_win->full_name, 416645f5050Syouri &tmp_win->class); 417645f5050Syouri } 418645f5050Syouri tmp_win->iconify_by_unmapping = tmp_win->iconify_by_unmapping || 419645f5050Syouri LookInList(Scr->IconifyByUn, tmp_win->full_name, &tmp_win->class); 420645f5050Syouri 421645f5050Syouri if (LookInList (Scr->UnmapByMovingFarAway, tmp_win->full_name, &tmp_win->class)) 422645f5050Syouri tmp_win->UnmapByMovingFarAway = True; 423645f5050Syouri else 424645f5050Syouri tmp_win->UnmapByMovingFarAway = False; 425645f5050Syouri 426645f5050Syouri if (LookInList (Scr->DontSetInactive, tmp_win->full_name, &tmp_win->class)) 427645f5050Syouri tmp_win->DontSetInactive = True; 428645f5050Syouri else 429645f5050Syouri tmp_win->DontSetInactive = False; 430645f5050Syouri 431645f5050Syouri if (LookInList (Scr->AutoSqueeze, tmp_win->full_name, &tmp_win->class)) 432645f5050Syouri tmp_win->AutoSqueeze = True; 433645f5050Syouri else 434645f5050Syouri tmp_win->AutoSqueeze = False; 435645f5050Syouri 436645f5050Syouri if (LookInList (Scr->StartSqueezed, tmp_win->full_name, &tmp_win->class)) 437645f5050Syouri tmp_win->StartSqueezed = True; 438645f5050Syouri else 439645f5050Syouri tmp_win->StartSqueezed = False; 440645f5050Syouri 441645f5050Syouri if (Scr->AlwaysSqueezeToGravity 442645f5050Syouri || LookInList (Scr->AlwaysSqueezeToGravityL, tmp_win->full_name, &tmp_win->class)) 443645f5050Syouri tmp_win->AlwaysSqueezeToGravity = True; 444645f5050Syouri else 445645f5050Syouri tmp_win->AlwaysSqueezeToGravity = False; 446645f5050Syouri 447645f5050Syouri if (tmp_win->transient || tmp_win->group) { 448645f5050Syouri TwmWindow *t = NULL; 449645f5050Syouri if (tmp_win->transient) t = GetTwmWindow(tmp_win->transientfor); 450645f5050Syouri if (!t && tmp_win->group) t = GetTwmWindow(tmp_win->group); 451645f5050Syouri if (t) tmp_win->UnmapByMovingFarAway = t->UnmapByMovingFarAway; 452645f5050Syouri } 453645f5050Syouri if ((Scr->WindowRingAll && !iswman && 454645f5050Syouri !LookInList(Scr->WindowRingExcludeL, tmp_win->full_name, &tmp_win->class)) || 455645f5050Syouri LookInList(Scr->WindowRingL, tmp_win->full_name, &tmp_win->class)) { 456645f5050Syouri if (Scr->Ring) { 457645f5050Syouri tmp_win->ring.next = Scr->Ring->ring.next; 458645f5050Syouri if (Scr->Ring->ring.next->ring.prev) 459645f5050Syouri Scr->Ring->ring.next->ring.prev = tmp_win; 460645f5050Syouri Scr->Ring->ring.next = tmp_win; 461645f5050Syouri tmp_win->ring.prev = Scr->Ring; 462645f5050Syouri } else { 463645f5050Syouri tmp_win->ring.next = tmp_win->ring.prev = Scr->Ring = tmp_win; 464645f5050Syouri } 465645f5050Syouri } else 466645f5050Syouri tmp_win->ring.next = tmp_win->ring.prev = NULL; 467645f5050Syouri tmp_win->ring.cursor_valid = False; 468645f5050Syouri 469645f5050Syouri tmp_win->squeeze_info = NULL; 470645f5050Syouri tmp_win->squeeze_info_copied = 0; 471645f5050Syouri /* 472645f5050Syouri * get the squeeze information; note that this does not have to be freed 473645f5050Syouri * since it is coming from the screen list 474645f5050Syouri */ 475645f5050Syouri if (HasShape) { 476645f5050Syouri if (!LookInList (Scr->DontSqueezeTitleL, tmp_win->full_name, 477645f5050Syouri &tmp_win->class)) { 478645f5050Syouri tmp_win->squeeze_info = (SqueezeInfo *) 479645f5050Syouri LookInList (Scr->SqueezeTitleL, tmp_win->full_name, 480645f5050Syouri &tmp_win->class); 481645f5050Syouri if (!tmp_win->squeeze_info) { 482645f5050Syouri static SqueezeInfo default_squeeze = { J_LEFT, 0, 0 }; 483645f5050Syouri if (Scr->SqueezeTitle) 484645f5050Syouri tmp_win->squeeze_info = &default_squeeze; 485645f5050Syouri } 486645f5050Syouri } 487645f5050Syouri } 488645f5050Syouri 489645f5050Syouri tmp_win->old_bw = tmp_win->attr.border_width; 490645f5050Syouri 491645f5050Syouri { 492645f5050Syouri MotifWmHints mwmHints; 493645f5050Syouri Boolean have_title; 494645f5050Syouri 495645f5050Syouri GetMWMHints(tmp_win->w, &mwmHints); 496645f5050Syouri 497645f5050Syouri tmp_win->frame_bw3D = Scr->ThreeDBorderWidth; 498645f5050Syouri if (((mwmHints.flags & MWM_HINTS_DECORATIONS) && 499645f5050Syouri (mwmHints.decorations & MWM_DECOR_BORDER) == 0) 500645f5050Syouri || LookInList(Scr->NoBorder, tmp_win->full_name, &tmp_win->class)) { 501645f5050Syouri tmp_win->frame_bw = 0; 502645f5050Syouri tmp_win->frame_bw3D = 0; 503645f5050Syouri } else if (tmp_win->frame_bw3D != 0) { 504645f5050Syouri tmp_win->frame_bw = 0; 505645f5050Syouri Scr->ClientBorderWidth = FALSE; 506645f5050Syouri } else if (Scr->ClientBorderWidth) { 507645f5050Syouri tmp_win->frame_bw = tmp_win->old_bw; 508645f5050Syouri } else { 509645f5050Syouri tmp_win->frame_bw = Scr->BorderWidth; 510645f5050Syouri } 511645f5050Syouri bw2 = tmp_win->frame_bw * 2; 512645f5050Syouri 513645f5050Syouri 514645f5050Syouri have_title = True; 515645f5050Syouri if (mwmHints.flags & MWM_HINTS_DECORATIONS) 516645f5050Syouri have_title = (mwmHints.decorations & MWM_DECOR_TITLE) != 0; 517645f5050Syouri if (Scr->NoTitlebar) 518645f5050Syouri have_title = False; 519645f5050Syouri if (LookInList(Scr->MakeTitle, tmp_win->full_name, &tmp_win->class)) 520645f5050Syouri have_title = True; 521645f5050Syouri if (LookInList(Scr->NoTitle, tmp_win->full_name, &tmp_win->class)) 522645f5050Syouri have_title = False; 523645f5050Syouri 524645f5050Syouri if (have_title) { 525645f5050Syouri tmp_win->title_height = Scr->TitleHeight + tmp_win->frame_bw; 526645f5050Syouri } else { 527645f5050Syouri tmp_win->title_height = 0; 528645f5050Syouri } 529645f5050Syouri } 530645f5050Syouri 531645f5050Syouri tmp_win->OpaqueMove = Scr->DoOpaqueMove; 532645f5050Syouri if (LookInList(Scr->OpaqueMoveList, tmp_win->full_name, &tmp_win->class)) 533645f5050Syouri tmp_win->OpaqueMove = TRUE; 534645f5050Syouri else 535645f5050Syouri if (LookInList(Scr->NoOpaqueMoveList, tmp_win->full_name, &tmp_win->class)) 536645f5050Syouri tmp_win->OpaqueMove = FALSE; 537645f5050Syouri 538645f5050Syouri tmp_win->OpaqueResize = Scr->DoOpaqueResize; 539645f5050Syouri if (LookInList(Scr->OpaqueResizeList, tmp_win->full_name, &tmp_win->class)) 540645f5050Syouri tmp_win->OpaqueResize = TRUE; 541645f5050Syouri else 542645f5050Syouri if (LookInList(Scr->NoOpaqueResizeList, tmp_win->full_name, &tmp_win->class)) 543645f5050Syouri tmp_win->OpaqueResize = FALSE; 544645f5050Syouri 545645f5050Syouri /* if it is a transient window, don't put a title on it */ 546645f5050Syouri if (tmp_win->transient && !Scr->DecorateTransients) 547645f5050Syouri tmp_win->title_height = 0; 548645f5050Syouri 549645f5050Syouri if (LookInList(Scr->StartIconified, tmp_win->full_name, &tmp_win->class)) 550645f5050Syouri { 551645f5050Syouri if (!tmp_win->wmhints) 552645f5050Syouri { 553645f5050Syouri tmp_win->wmhints = (XWMHints *)malloc(sizeof(XWMHints)); 554645f5050Syouri tmp_win->wmhints->flags = 0; 555645f5050Syouri } 556645f5050Syouri tmp_win->wmhints->initial_state = IconicState; 557645f5050Syouri tmp_win->wmhints->flags |= StateHint; 558645f5050Syouri } 559645f5050Syouri 560645f5050Syouri GetWindowSizeHints (tmp_win); 561645f5050Syouri 562645f5050Syouri if (restoredFromPrevSession) 563645f5050Syouri { 564645f5050Syouri /* 565645f5050Syouri * When restoring window positions from the previous session, 566645f5050Syouri * we always use NorthWest gravity. 567645f5050Syouri */ 568645f5050Syouri 569645f5050Syouri gravx = gravy = -1; 570645f5050Syouri } 571645f5050Syouri else 572645f5050Syouri { 573645f5050Syouri GetGravityOffsets (tmp_win, &gravx, &gravy); 574645f5050Syouri } 575645f5050Syouri 576645f5050Syouri /* 577645f5050Syouri * Don't bother user if: 578645f5050Syouri * 579645f5050Syouri * o the window is a transient, or 580645f5050Syouri * 581645f5050Syouri * o a USPosition was requested, or 582645f5050Syouri * 583645f5050Syouri * o a PPosition was requested and UsePPosition is ON or 584645f5050Syouri * NON_ZERO if the window is at other than (0,0) 585645f5050Syouri */ 586645f5050Syouri ask_user = TRUE; 587645f5050Syouri if (tmp_win->transient || 588645f5050Syouri (tmp_win->hints.flags & USPosition) || 589645f5050Syouri ((tmp_win->hints.flags & PPosition) && Scr->UsePPosition && 590645f5050Syouri (Scr->UsePPosition == PPOS_ON || 591645f5050Syouri tmp_win->attr.x != 0 || tmp_win->attr.y != 0))) 592645f5050Syouri ask_user = FALSE; 593645f5050Syouri 594645f5050Syouri /*===============[ Matthew McNeill 1997 ]==========================* 595645f5050Syouri * added the occupation parameter to this function call so that the 596645f5050Syouri * occupation can be set up in a specific state if desired 597645f5050Syouri * (restore session for example) 598645f5050Syouri */ 599645f5050Syouri 600645f5050Syouri /* note, this is where tmp_win->vs get setup, among other things */ 601645f5050Syouri 602645f5050Syouri if (restoredFromPrevSession) { 603645f5050Syouri SetupOccupation (tmp_win, saved_occupation); 604645f5050Syouri } else 605645f5050Syouri SetupOccupation (tmp_win, 0); 606645f5050Syouri /*=================================================================*/ 607645f5050Syouri 608645f5050Syouri tmp_win->frame_width = tmp_win->attr.width + 2 * tmp_win->frame_bw3D; 609645f5050Syouri tmp_win->frame_height = tmp_win->attr.height + 2 * tmp_win->frame_bw3D + 610645f5050Syouri tmp_win->title_height; 611645f5050Syouri ConstrainSize (tmp_win, &tmp_win->frame_width, &tmp_win->frame_height); 612645f5050Syouri winbox = findWindowBox (tmp_win); 613645f5050Syouri if (PlaceWindowInRegion (tmp_win, &(tmp_win->attr.x), &(tmp_win->attr.y))) { 614645f5050Syouri ask_user = False; 615645f5050Syouri } 616645f5050Syouri if (LookInList (Scr->WindowGeometries, tmp_win->full_name, &tmp_win->class)) { 617645f5050Syouri char *geom; 618645f5050Syouri int mask_; 619645f5050Syouri geom = LookInList (Scr->WindowGeometries, tmp_win->full_name, &tmp_win->class); 620645f5050Syouri mask_ = XParseGeometry (geom, &tmp_win->attr.x, &tmp_win->attr.y, 621645f5050Syouri (unsigned int*) &tmp_win->attr.width, 622645f5050Syouri (unsigned int*) &tmp_win->attr.height); 623645f5050Syouri 624645f5050Syouri if (mask_ & XNegative) tmp_win->attr.x += Scr->rootw - tmp_win->attr.width; 625645f5050Syouri if (mask_ & YNegative) tmp_win->attr.y += Scr->rooth - tmp_win->attr.height; 626645f5050Syouri ask_user = False; 627645f5050Syouri } 628645f5050Syouri 629645f5050Syouri if (XFindContext (dpy, w, VirtScreenContext, (XPointer *)&vs) == XCSUCCESS) 630645f5050Syouri vroot = vs->window; 631645f5050Syouri else 632645f5050Syouri if (tmp_win->vs) 633645f5050Syouri vroot = tmp_win->vs->window; 634645f5050Syouri else 635645f5050Syouri vroot = Scr->Root; 636645f5050Syouri if (winbox) vroot = winbox->window; 637645f5050Syouri 638645f5050Syouri /* 639645f5050Syouri * do any prompting for position 640645f5050Syouri */ 641645f5050Syouri 642645f5050Syouri if (HandlingEvents && ask_user && !restoredFromPrevSession) { 643645f5050Syouri if ((Scr->RandomPlacement == RP_ALL) || 644645f5050Syouri ((Scr->RandomPlacement == RP_UNMAPPED) && 645645f5050Syouri ((tmp_win->wmhints && (tmp_win->wmhints->initial_state == IconicState)) || 646645f5050Syouri (! visible (tmp_win))))) { /* just stick it somewhere */ 647645f5050Syouri 648645f5050Syouri#ifdef DEBUG 649645f5050Syouri fprintf(stderr, 650645f5050Syouri "DEBUG[RandomPlacement]: win: %dx%d+%d+%d, screen: %dx%d, title height: %d, random: +%d+%d\n", 651645f5050Syouri tmp_win->attr.width, tmp_win->attr.height, 652645f5050Syouri tmp_win->attr.x, tmp_win->attr.y, 653645f5050Syouri Scr->rootw, Scr->rooth, 654645f5050Syouri tmp_win->title_height, 655645f5050Syouri PlaceX, PlaceY); 656645f5050Syouri#endif 657645f5050Syouri 658645f5050Syouri /* Initiallise PlaceX and PlaceY */ 659645f5050Syouri if (PlaceX < 0 && PlaceY < 0) { 660645f5050Syouri if (Scr->RandomDisplacementX >= 0) 661645f5050Syouri PlaceX = Scr->BorderLeft + 5; 662645f5050Syouri else 663645f5050Syouri PlaceX = Scr->rootw - tmp_win->attr.width - Scr->BorderRight - 5; 664645f5050Syouri if (Scr->RandomDisplacementY >= 0) 665645f5050Syouri PlaceY = Scr->BorderTop + 5; 666645f5050Syouri else 667645f5050Syouri PlaceY = Scr->rooth - tmp_win->attr.height - tmp_win->title_height 668645f5050Syouri - Scr->BorderBottom - 5; 669645f5050Syouri } 670645f5050Syouri 671645f5050Syouri /* For a positive horizontal displacement, if the right edge 672645f5050Syouri of the window would fall outside of the screen, start over 673645f5050Syouri by placing the left edge of the window 5 pixels inside 674645f5050Syouri the left edge of the screen.*/ 675645f5050Syouri if (Scr->RandomDisplacementX >= 0 676645f5050Syouri && (PlaceX + tmp_win->attr.width 677645f5050Syouri > Scr->rootw - Scr->BorderRight - 5)) 678645f5050Syouri PlaceX = Scr->BorderLeft + 5; 679645f5050Syouri 680645f5050Syouri /* For a negative horizontal displacement, if the left edge 681645f5050Syouri of the window would fall outside of the screen, start over 682645f5050Syouri by placing the right edge of the window 5 pixels inside 683645f5050Syouri the right edge of the screen.*/ 684645f5050Syouri if (Scr->RandomDisplacementX < 0 && PlaceX < Scr->BorderLeft + 5) 685645f5050Syouri PlaceX = Scr->rootw - tmp_win->attr.width - Scr->BorderRight - 5; 686645f5050Syouri 687645f5050Syouri /* For a positive vertical displacement, if the bottom edge 688645f5050Syouri of the window would fall outside of the screen, start over 689645f5050Syouri by placing the top edge of the window 5 pixels inside the 690645f5050Syouri top edge of the screen. Because we add the title height 691645f5050Syouri further down, we need to count with it here as well. */ 692645f5050Syouri if (Scr->RandomDisplacementY >= 0 693645f5050Syouri && (PlaceY + tmp_win->attr.height + tmp_win->title_height 694645f5050Syouri > Scr->rooth - Scr->BorderBottom - 5)) 695645f5050Syouri PlaceY = Scr->BorderTop + 5; 696645f5050Syouri 697645f5050Syouri /* For a negative vertical displacement, if the top edge of 698645f5050Syouri the window would fall outside of the screen, start over by 699645f5050Syouri placing the bottom edge of the window 5 pixels inside the 700645f5050Syouri bottom edge of the screen. Because we add the title height 701645f5050Syouri further down, we need to count with it here as well. */ 702645f5050Syouri if (Scr->RandomDisplacementY < 0 && PlaceY < Scr->BorderTop + 5) 703645f5050Syouri PlaceY = Scr->rooth - tmp_win->attr.height - tmp_win->title_height 704645f5050Syouri - Scr->BorderBottom - 5; 705645f5050Syouri 706645f5050Syouri /* Assign the current random placement to the new window, as 707645f5050Syouri a preliminary measure. Add the title height so things will 708645f5050Syouri look right. */ 709645f5050Syouri tmp_win->attr.x = PlaceX; 710645f5050Syouri tmp_win->attr.y = PlaceY + tmp_win->title_height; 711645f5050Syouri 712645f5050Syouri /* If the window is not supposed to move off the screen, check 713645f5050Syouri that it's still within the screen, and if not, attempt to 714645f5050Syouri correct the situation. */ 715645f5050Syouri if (Scr->DontMoveOff) { 716645f5050Syouri int available; 717645f5050Syouri 718645f5050Syouri#ifdef DEBUG 719645f5050Syouri fprintf(stderr, 720645f5050Syouri "DEBUG[DontMoveOff]: win: %dx%d+%d+%d, screen: %dx%d, bw2: %d, bw3D: %d\n", 721645f5050Syouri tmp_win->attr.width, tmp_win->attr.height, 722645f5050Syouri tmp_win->attr.x, tmp_win->attr.y, 723645f5050Syouri Scr->rootw, Scr->rooth, 724645f5050Syouri bw2, tmp_win->frame_bw3D); 725645f5050Syouri#endif 726645f5050Syouri 727645f5050Syouri /* If the right edge of the window is outside the right edge 728645f5050Syouri of the screen, we need to move the window left. Note that 729645f5050Syouri this can only happen with windows that are less than 50 730645f5050Syouri pixels less wide than the screen. */ 731645f5050Syouri if ((tmp_win->attr.x + tmp_win->attr.width) > Scr->rootw) { 732645f5050Syouri available = Scr->rootw - tmp_win->attr.width 733645f5050Syouri - 2 * (bw2 + tmp_win->frame_bw3D); 734645f5050Syouri 735645f5050Syouri#ifdef DEBUG 736645f5050Syouri fprintf(stderr, "DEBUG[DontMoveOff]: availableX: %d\n", 737645f5050Syouri available); 738645f5050Syouri#endif 739645f5050Syouri 740645f5050Syouri /* If the window is wider than the screen or exactly the width 741645f5050Syouri of the screen, the availability is exactly 0. The result 742645f5050Syouri will be to have the window placed as much to the left as 743645f5050Syouri possible. */ 744645f5050Syouri if (available <= 0) available = 0; 745645f5050Syouri 746645f5050Syouri /* Place the window exactly between the left and right edge of 747645f5050Syouri the screen when possible. If available was originally less 748645f5050Syouri than zero, it means the window's left edge will be against 749645f5050Syouri the screen's left edge, and the window's right edge will be 750645f5050Syouri outside the screen. */ 751645f5050Syouri tmp_win->attr.x = available / 2; 752645f5050Syouri } 753645f5050Syouri 754645f5050Syouri /* If the bottom edge of the window is outside the bottom edge 755645f5050Syouri of the screen, we need to move the window up. Note that 756645f5050Syouri this can only happen with windows that are less than 50 757645f5050Syouri pixels less tall than the screen. Don't forget to count 758645f5050Syouri with the title height and the frame widths. */ 759645f5050Syouri if ((tmp_win->attr.y + tmp_win->attr.height) > Scr->rooth) { 760645f5050Syouri available = Scr->rooth - tmp_win->attr.height 761645f5050Syouri - tmp_win->title_height - 2 * (bw2 + tmp_win->frame_bw3D); 762645f5050Syouri 763645f5050Syouri#ifdef DEBUG 764645f5050Syouri fprintf(stderr, "DEBUG[DontMoveOff]: availableY: %d\n", 765645f5050Syouri available); 766645f5050Syouri#endif 767645f5050Syouri 768645f5050Syouri /* If the window is taller than the screen or exactly the 769645f5050Syouri height of the screen, the availability is exactly 0. 770645f5050Syouri The result will be to have the window placed as much to 771645f5050Syouri the top as possible. */ 772645f5050Syouri if (available <= 0) available = 0; 773645f5050Syouri 774645f5050Syouri /* Place the window exactly between the top and bottom edge of 775645f5050Syouri the screen when possible. If available was originally less 776645f5050Syouri than zero, it means the window's top edge will be against 777645f5050Syouri the screen's top edge, and the window's bottom edge will be 778645f5050Syouri outside the screen. Again, don't forget to add the title 779645f5050Syouri height. */ 780645f5050Syouri tmp_win->attr.y = available / 2 + tmp_win->title_height; 781645f5050Syouri } 782645f5050Syouri 783645f5050Syouri#ifdef DEBUG 784645f5050Syouri fprintf(stderr, 785645f5050Syouri "DEBUG[DontMoveOff]: win: %dx%d+%d+%d, screen: %dx%d\n", 786645f5050Syouri tmp_win->attr.width, tmp_win->attr.height, 787645f5050Syouri tmp_win->attr.x, tmp_win->attr.y, 788645f5050Syouri Scr->rootw, Scr->rooth); 789645f5050Syouri#endif 790645f5050Syouri } 791645f5050Syouri 792645f5050Syouri /* We know that if the window's left edge has moved compared to 793645f5050Syouri PlaceX, it will have moved to the left. If it was moved less 794645f5050Syouri than 15 pixel either way, change the next "random position" 795645f5050Syouri 30 pixels down and right. */ 796645f5050Syouri if (PlaceX - tmp_win->attr.x < 15 797645f5050Syouri || PlaceY - (tmp_win->attr.y - tmp_win->title_height) < 15) { 798645f5050Syouri PlaceX += Scr->RandomDisplacementX; 799645f5050Syouri PlaceY += Scr->RandomDisplacementY; 800645f5050Syouri } 801645f5050Syouri 802645f5050Syouri random_placed = True; 803645f5050Syouri } else { /* else prompt */ 804645f5050Syouri if (!(tmp_win->wmhints && tmp_win->wmhints->flags & StateHint && 805645f5050Syouri tmp_win->wmhints->initial_state == IconicState)) 806645f5050Syouri { 807645f5050Syouri Bool firsttime = True; 808645f5050Syouri 809645f5050Syouri /* better wait until all the mouse buttons have been 810645f5050Syouri * released. 811645f5050Syouri */ 812645f5050Syouri while (TRUE) 813645f5050Syouri { 814645f5050Syouri XUngrabServer(dpy); 815645f5050Syouri XSync(dpy, 0); 816645f5050Syouri XGrabServer(dpy); 817645f5050Syouri 818645f5050Syouri JunkMask = 0; 819645f5050Syouri if (!XQueryPointer (dpy, Scr->Root, &JunkRoot, 820645f5050Syouri &JunkChild, &JunkX, &JunkY, 821645f5050Syouri &AddingX, &AddingY, &JunkMask)) 822645f5050Syouri JunkMask = 0; 823645f5050Syouri 824645f5050Syouri JunkMask &= (Button1Mask | Button2Mask | Button3Mask | 825645f5050Syouri Button4Mask | Button5Mask); 826645f5050Syouri 827645f5050Syouri /* 828645f5050Syouri * watch out for changing screens 829645f5050Syouri */ 830645f5050Syouri if (firsttime) { 831645f5050Syouri if (JunkRoot != Scr->Root) { 832645f5050Syouri register int scrnum; 833645f5050Syouri for (scrnum = 0; scrnum < NumScreens; scrnum++) { 834645f5050Syouri if (JunkRoot == RootWindow (dpy, scrnum)) break; 835645f5050Syouri } 836645f5050Syouri if (scrnum != NumScreens) PreviousScreen = scrnum; 837645f5050Syouri } 838645f5050Syouri if (Scr->currentvs) { 839645f5050Syouri vroot = Scr->currentvs->window; 840645f5050Syouri } 841645f5050Syouri firsttime = False; 842645f5050Syouri } 843645f5050Syouri if (winbox) vroot = winbox->window; 844645f5050Syouri 845645f5050Syouri /* 846645f5050Syouri * wait for buttons to come up; yuck 847645f5050Syouri */ 848645f5050Syouri if (JunkMask != 0) continue; 849645f5050Syouri 850645f5050Syouri /* 851645f5050Syouri * this will cause a warp to the indicated root 852645f5050Syouri */ 853645f5050Syouri stat = XGrabPointer(dpy, vroot, False, 854645f5050Syouri ButtonPressMask | ButtonReleaseMask | 855645f5050Syouri PointerMotionMask | PointerMotionHintMask, 856645f5050Syouri GrabModeAsync, GrabModeAsync, 857645f5050Syouri vroot, UpperLeftCursor, CurrentTime); 858645f5050Syouri if (stat == GrabSuccess) break; 859645f5050Syouri } 860645f5050Syouri 861645f5050Syouri XmbTextExtents(Scr->SizeFont.font_set, 862645f5050Syouri tmp_win->name, namelen, 863645f5050Syouri &ink_rect, &logical_rect); 864645f5050Syouri width = SIZE_HINDENT + ink_rect.width; 865645f5050Syouri height = logical_rect.height + SIZE_VINDENT * 2; 866645f5050Syouri XmbTextExtents(Scr->SizeFont.font_set, 867645f5050Syouri ": ", 2, &logical_rect, &logical_rect); 868645f5050Syouri Scr->SizeStringOffset = width + logical_rect.width; 869645f5050Syouri 870645f5050Syouri XResizeWindow (dpy, Scr->SizeWindow, Scr->SizeStringOffset + 871645f5050Syouri Scr->SizeStringWidth + SIZE_HINDENT, height); 872645f5050Syouri XMapRaised(dpy, Scr->SizeWindow); 873645f5050Syouri InstallRootColormap(); 874645f5050Syouri FB(Scr->DefaultC.fore, Scr->DefaultC.back); 875645f5050Syouri XmbDrawImageString (dpy, Scr->SizeWindow, Scr->SizeFont.font_set, 876645f5050Syouri Scr->NormalGC, SIZE_HINDENT, 877645f5050Syouri SIZE_VINDENT + Scr->SizeFont.ascent, 878645f5050Syouri tmp_win->name, namelen); 879645f5050Syouri 880645f5050Syouri if (winbox) ConstrainedToWinBox (tmp_win, AddingX, AddingY, &AddingX, &AddingY); 881645f5050Syouri 882645f5050Syouri AddingW = tmp_win->attr.width + bw2 + 2 * tmp_win->frame_bw3D; 883645f5050Syouri AddingH = tmp_win->attr.height + tmp_win->title_height + 884645f5050Syouri bw2 + 2 * tmp_win->frame_bw3D; 885645f5050Syouri MoveOutline(vroot,AddingX, AddingY, AddingW, AddingH, 886645f5050Syouri tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); 887645f5050Syouri 888645f5050Syouri XmbDrawImageString (dpy, Scr->SizeWindow, Scr->SizeFont.font_set, 889645f5050Syouri Scr->NormalGC, width, 890645f5050Syouri SIZE_VINDENT + Scr->SizeFont.ascent, ": ", 2); 891645f5050Syouri DisplayPosition (tmp_win, AddingX, AddingY); 892645f5050Syouri 893645f5050Syouri tmp_win->frame_width = AddingW; 894645f5050Syouri tmp_win->frame_height = AddingH; 895645f5050Syouri /*SetFocus ((TwmWindow *) NULL, CurrentTime);*/ 896645f5050Syouri while (TRUE) 897645f5050Syouri { 898645f5050Syouri#ifndef VMS /* I'll try to implement this later. RL */ 899645f5050Syouri if (Scr->OpenWindowTimeout) { 900645f5050Syouri fd = ConnectionNumber (dpy); 901645f5050Syouri while (!XCheckMaskEvent (dpy, ButtonMotionMask | ButtonPressMask, &event)) { 902645f5050Syouri FD_ZERO (&mask); 903645f5050Syouri FD_SET (fd, &mask); 904645f5050Syouri timeout.tv_sec = Scr->OpenWindowTimeout; 905645f5050Syouri timeout.tv_usec = 0; 906645f5050Syouri found = select (fd + 1, (FDSET)&mask, (FDSET)0, (FDSET)0, &timeout); 907645f5050Syouri if (found == 0) break; 908645f5050Syouri } 909645f5050Syouri if (found == 0) break; 910645f5050Syouri } else { 911645f5050Syouri#else 912645f5050Syouri { 913645f5050Syouri#endif 914645f5050Syouri found = 1; 915645f5050Syouri XMaskEvent(dpy, ButtonPressMask | PointerMotionMask, &event); 916645f5050Syouri } 917645f5050Syouri if (event.type == MotionNotify) { 918645f5050Syouri /* discard any extra motion events before a release */ 919645f5050Syouri while(XCheckMaskEvent(dpy, 920645f5050Syouri ButtonMotionMask | ButtonPressMask, &event)) 921645f5050Syouri if (event.type == ButtonPress) 922645f5050Syouri break; 923645f5050Syouri } 924645f5050Syouri FixRootEvent (&event); 925645f5050Syouri if (event.type == ButtonPress) { 926645f5050Syouri AddingX = event.xbutton.x_root; 927645f5050Syouri AddingY = event.xbutton.y_root; 928645f5050Syouri 929645f5050Syouri TryToGrid (tmp_win, &AddingX, &AddingY); 930645f5050Syouri if (Scr->PackNewWindows) TryToPack (tmp_win, &AddingX, &AddingY); 931645f5050Syouri 932645f5050Syouri /* DontMoveOff prohibits user form off-screen placement */ 933645f5050Syouri if (Scr->DontMoveOff) 934645f5050Syouri { 935645f5050Syouri ConstrainByBorders (tmp_win, &AddingX, AddingW, &AddingY, AddingH); 936645f5050Syouri } 937645f5050Syouri break; 938645f5050Syouri } 939645f5050Syouri 940645f5050Syouri if (event.type != MotionNotify) { 941645f5050Syouri continue; 942645f5050Syouri } 943645f5050Syouri 944645f5050Syouri XQueryPointer(dpy, vroot, &JunkRoot, &JunkChild, 945645f5050Syouri &JunkX, &JunkY, &AddingX, &AddingY, &JunkMask); 946645f5050Syouri 947645f5050Syouri TryToGrid (tmp_win, &AddingX, &AddingY); 948645f5050Syouri if (Scr->PackNewWindows) TryToPack (tmp_win, &AddingX, &AddingY); 949645f5050Syouri if (Scr->DontMoveOff) 950645f5050Syouri { 951645f5050Syouri ConstrainByBorders (tmp_win, &AddingX, AddingW, &AddingY, AddingH); 952645f5050Syouri } 953645f5050Syouri MoveOutline(vroot, AddingX, AddingY, AddingW, AddingH, 954645f5050Syouri tmp_win->frame_bw, tmp_win->title_height + tmp_win->frame_bw3D); 955645f5050Syouri 956645f5050Syouri DisplayPosition (tmp_win, AddingX, AddingY); 957645f5050Syouri } 958645f5050Syouri 959645f5050Syouri if (found) { 960645f5050Syouri if (event.xbutton.button == Button2) { 961645f5050Syouri int lastx, lasty; 962645f5050Syouri 963645f5050Syouri XmbTextExtents(Scr->SizeFont.font_set, 964645f5050Syouri ": ", 2, &logical_rect, &logical_rect); 965645f5050Syouri Scr->SizeStringOffset = width + logical_rect.width; 966645f5050Syouri 967645f5050Syouri XResizeWindow (dpy, Scr->SizeWindow, Scr->SizeStringOffset + 968645f5050Syouri Scr->SizeStringWidth + SIZE_HINDENT, height); 969645f5050Syouri 970645f5050Syouri XmbDrawImageString(dpy, Scr->SizeWindow, Scr->SizeFont.font_set, 971645f5050Syouri Scr->NormalGC, width, 972645f5050Syouri SIZE_VINDENT + Scr->SizeFont.ascent, ": ", 2); 973645f5050Syouri 974645f5050Syouri if (0/*Scr->AutoRelativeResize*/) { 975645f5050Syouri int dx = (tmp_win->attr.width / 4); 976645f5050Syouri int dy = (tmp_win->attr.height / 4); 977645f5050Syouri 978645f5050Syouri#define HALF_AVE_CURSOR_SIZE 8 /* so that it is visible */ 979645f5050Syouri if (dx < HALF_AVE_CURSOR_SIZE + Scr->BorderLeft) 980645f5050Syouri dx = HALF_AVE_CURSOR_SIZE + Scr->BorderLeft; 981645f5050Syouri if (dy < HALF_AVE_CURSOR_SIZE + Scr->BorderTop) 982645f5050Syouri dy = HALF_AVE_CURSOR_SIZE + Scr->BorderTop; 983645f5050Syouri#undef HALF_AVE_CURSOR_SIZE 984645f5050Syouri dx += (tmp_win->frame_bw + 1); 985645f5050Syouri dy += (bw2 + tmp_win->title_height + 1); 986645f5050Syouri if (AddingX + dx >= Scr->rootw - Scr->BorderRight) 987645f5050Syouri dx = Scr->rootw - Scr->BorderRight - AddingX - 1; 988645f5050Syouri if (AddingY + dy >= Scr->rooth - Scr->BorderBottom) 989645f5050Syouri dy = Scr->rooth - Scr->BorderBottom - AddingY - 1; 990645f5050Syouri if (dx > 0 && dy > 0) 991645f5050Syouri XWarpPointer (dpy, None, None, 0, 0, 0, 0, dx, dy); 992645f5050Syouri } else { 993645f5050Syouri XWarpPointer (dpy, None, vroot, 0, 0, 0, 0, 994645f5050Syouri AddingX + AddingW/2, AddingY + AddingH/2); 995645f5050Syouri } 996645f5050Syouri AddStartResize(tmp_win, AddingX, AddingY, AddingW, AddingH); 997645f5050Syouri 998645f5050Syouri lastx = -10000; 999645f5050Syouri lasty = -10000; 1000645f5050Syouri while (TRUE) 1001645f5050Syouri { 1002645f5050Syouri XMaskEvent(dpy, 1003645f5050Syouri ButtonReleaseMask | ButtonMotionMask, &event); 1004645f5050Syouri 1005645f5050Syouri if (event.type == MotionNotify) { 1006645f5050Syouri /* discard any extra motion events before a release */ 1007645f5050Syouri while(XCheckMaskEvent(dpy, 1008645f5050Syouri ButtonMotionMask | ButtonReleaseMask, &event)) 1009645f5050Syouri if (event.type == ButtonRelease) 1010645f5050Syouri break; 1011645f5050Syouri } 1012645f5050Syouri FixRootEvent (&event); 1013645f5050Syouri 1014645f5050Syouri if (event.type == ButtonRelease) 1015645f5050Syouri { 1016645f5050Syouri AddEndResize(tmp_win); 1017645f5050Syouri break; 1018645f5050Syouri } 1019645f5050Syouri 1020645f5050Syouri if (event.type != MotionNotify) { 1021645f5050Syouri continue; 1022645f5050Syouri } 1023645f5050Syouri 1024645f5050Syouri /* 1025645f5050Syouri * XXX - if we are going to do a loop, we ought to consider 1026645f5050Syouri * using multiple GXxor lines so that we don't need to 1027645f5050Syouri * grab the server. 1028645f5050Syouri */ 1029645f5050Syouri XQueryPointer(dpy, vroot, &JunkRoot, &JunkChild, 1030645f5050Syouri &JunkX, &JunkY, &AddingX, &AddingY, &JunkMask); 1031645f5050Syouri 1032645f5050Syouri if (lastx != AddingX || lasty != AddingY) 1033645f5050Syouri { 1034645f5050Syouri resizeWhenAdd = TRUE; 1035645f5050Syouri DoResize(AddingX, AddingY, tmp_win); 1036645f5050Syouri resizeWhenAdd = FALSE; 1037645f5050Syouri 1038645f5050Syouri lastx = AddingX; 1039645f5050Syouri lasty = AddingY; 1040645f5050Syouri } 1041645f5050Syouri 1042645f5050Syouri } 1043645f5050Syouri } 1044645f5050Syouri else if (event.xbutton.button == Button3) 1045645f5050Syouri { 1046645f5050Syouri int maxw = Scr->rootw - Scr->BorderRight - AddingX - bw2; 1047645f5050Syouri int maxh = Scr->rooth - Scr->BorderBottom - AddingY - bw2; 1048645f5050Syouri 1049645f5050Syouri /* 1050645f5050Syouri * Make window go to bottom of screen, and clip to right edge. 1051645f5050Syouri * This is useful when popping up large windows and fixed 1052645f5050Syouri * column text windows. 1053645f5050Syouri */ 1054645f5050Syouri if (AddingW > maxw) AddingW = maxw; 1055645f5050Syouri AddingH = maxh; 1056645f5050Syouri 1057645f5050Syouri ConstrainSize (tmp_win, &AddingW, &AddingH); /* w/o borders */ 1058645f5050Syouri AddingW += bw2; 1059645f5050Syouri AddingH += bw2; 1060645f5050Syouri XMaskEvent(dpy, ButtonReleaseMask, &event); 1061645f5050Syouri } 1062645f5050Syouri else 1063645f5050Syouri { 1064645f5050Syouri XMaskEvent(dpy, ButtonReleaseMask, &event); 1065645f5050Syouri } 1066645f5050Syouri } 1067645f5050Syouri MoveOutline(vroot, 0, 0, 0, 0, 0, 0); 1068645f5050Syouri XUnmapWindow(dpy, Scr->SizeWindow); 1069645f5050Syouri UninstallRootColormap(); 1070645f5050Syouri XUngrabPointer(dpy, CurrentTime); 1071645f5050Syouri 1072645f5050Syouri tmp_win->attr.x = AddingX; 1073645f5050Syouri tmp_win->attr.y = AddingY + tmp_win->title_height; 1074645f5050Syouri tmp_win->attr.width = AddingW - bw2 - 2 * tmp_win->frame_bw3D; 1075645f5050Syouri tmp_win->attr.height = AddingH - tmp_win->title_height - 1076645f5050Syouri bw2 - 2 * tmp_win->frame_bw3D; 1077645f5050Syouri 1078645f5050Syouri XUngrabServer(dpy); 1079645f5050Syouri } 1080645f5050Syouri } 1081645f5050Syouri } else { /* put it where asked, mod title bar */ 1082645f5050Syouri /* if the gravity is towards the top, move it by the title height */ 1083645f5050Syouri if (gravy < 0) tmp_win->attr.y -= gravy * tmp_win->title_height; 1084645f5050Syouri } 1085645f5050Syouri 1086645f5050Syouri#ifdef DEBUG 1087645f5050Syouri fprintf(stderr, " position window %d, %d %dx%d\n", 1088645f5050Syouri tmp_win->attr.x, 1089645f5050Syouri tmp_win->attr.y, 1090645f5050Syouri tmp_win->attr.width, 1091645f5050Syouri tmp_win->attr.height); 1092645f5050Syouri#endif 1093645f5050Syouri 1094645f5050Syouri if (!Scr->ClientBorderWidth) { /* need to adjust for twm borders */ 1095645f5050Syouri int delta = tmp_win->attr.border_width - tmp_win->frame_bw - tmp_win->frame_bw3D; 1096645f5050Syouri tmp_win->attr.x += gravx * delta; 1097645f5050Syouri tmp_win->attr.y += gravy * delta; 1098645f5050Syouri } 1099645f5050Syouri 1100645f5050Syouri tmp_win->title_width = tmp_win->attr.width; 1101645f5050Syouri 1102645f5050Syouri tmp_win->icon_name = (char*) GetWMPropertyString(tmp_win->w, XA_WM_ICON_NAME); 1103645f5050Syouri if (!tmp_win->icon_name) 1104645f5050Syouri tmp_win->icon_name = tmp_win->name; 1105645f5050Syouri 1106645f5050Syouri#ifdef CLAUDE 1107645f5050Syouri if (strstr (tmp_win->icon_name, " - Mozilla")) { 1108645f5050Syouri char *moz = strstr (tmp_win->icon_name, " - Mozilla"); 1109645f5050Syouri *moz = '\0'; 1110645f5050Syouri } 1111645f5050Syouri#endif 1112645f5050Syouri 1113645f5050Syouri XmbTextExtents (Scr->TitleBarFont.font_set, tmp_win->name, namelen, &ink_rect, &logical_rect); 1114645f5050Syouri tmp_win->name_width = logical_rect.width; 1115645f5050Syouri 1116645f5050Syouri if (tmp_win->old_bw) XSetWindowBorderWidth (dpy, tmp_win->w, 0); 1117645f5050Syouri 1118645f5050Syouri tmp_win->squeezed = FALSE; 1119645f5050Syouri tmp_win->iconified = FALSE; 1120645f5050Syouri tmp_win->isicon = FALSE; 1121645f5050Syouri tmp_win->icon_on = FALSE; 1122645f5050Syouri 1123645f5050Syouri XGrabServer(dpy); 1124645f5050Syouri 1125645f5050Syouri /* 1126645f5050Syouri * Make sure the client window still exists. We don't want to leave an 1127645f5050Syouri * orphan frame window if it doesn't. Since we now have the server 1128645f5050Syouri * grabbed, the window can't disappear later without having been 1129645f5050Syouri * reparented, so we'll get a DestroyNotify for it. We won't have 1130645f5050Syouri * gotten one for anything up to here, however. 1131645f5050Syouri */ 1132645f5050Syouri if (XGetGeometry(dpy, tmp_win->w, &JunkRoot, &JunkX, &JunkY, 1133645f5050Syouri &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0) 1134645f5050Syouri { 1135645f5050Syouri TwmWindow *prev = tmp_win->ring.prev, *next = tmp_win->ring.next; 1136645f5050Syouri 1137645f5050Syouri if (prev) prev->ring.next = next; 1138645f5050Syouri if (next) next->ring.prev = prev; 1139645f5050Syouri if (Scr->Ring == tmp_win) Scr->Ring = (next != tmp_win ? next : (TwmWindow *) NULL); 1140645f5050Syouri if (!Scr->Ring || Scr->RingLeader == tmp_win) Scr->RingLeader = Scr->Ring; 1141645f5050Syouri 1142645f5050Syouri free((char *)tmp_win); 1143645f5050Syouri XUngrabServer(dpy); 1144645f5050Syouri return(NULL); 1145645f5050Syouri } 1146645f5050Syouri 1147645f5050Syouri /* add the window into the twm list */ 1148645f5050Syouri tmp_win->next = Scr->FirstWindow; 1149645f5050Syouri if (Scr->FirstWindow != NULL) 1150645f5050Syouri Scr->FirstWindow->prev = tmp_win; 1151645f5050Syouri tmp_win->prev = NULL; 1152645f5050Syouri Scr->FirstWindow = tmp_win; 1153645f5050Syouri 1154645f5050Syouri /* get all the colors for the window */ 1155645f5050Syouri 1156645f5050Syouri tmp_win->borderC.fore = Scr->BorderColorC.fore; 1157645f5050Syouri tmp_win->borderC.back = Scr->BorderColorC.back; 1158645f5050Syouri tmp_win->border_tile.fore = Scr->BorderTileC.fore; 1159645f5050Syouri tmp_win->border_tile.back = Scr->BorderTileC.back; 1160645f5050Syouri tmp_win->title.fore = Scr->TitleC.fore; 1161645f5050Syouri tmp_win->title.back = Scr->TitleC.back; 1162645f5050Syouri 1163645f5050Syouri GetColorFromList(Scr->BorderColorL, tmp_win->full_name, &tmp_win->class, 1164645f5050Syouri &tmp_win->borderC.fore); 1165645f5050Syouri GetColorFromList(Scr->BorderColorL, tmp_win->full_name, &tmp_win->class, 1166645f5050Syouri &tmp_win->borderC.back); 1167645f5050Syouri GetColorFromList(Scr->BorderTileForegroundL, tmp_win->full_name, 1168645f5050Syouri &tmp_win->class, &tmp_win->border_tile.fore); 1169645f5050Syouri GetColorFromList(Scr->BorderTileBackgroundL, tmp_win->full_name, 1170645f5050Syouri &tmp_win->class, &tmp_win->border_tile.back); 1171645f5050Syouri GetColorFromList(Scr->TitleForegroundL, tmp_win->full_name, &tmp_win->class, 1172645f5050Syouri &tmp_win->title.fore); 1173645f5050Syouri GetColorFromList(Scr->TitleBackgroundL, tmp_win->full_name, &tmp_win->class, 1174645f5050Syouri &tmp_win->title.back); 1175645f5050Syouri 1176645f5050Syouri if (Scr->use3Dtitles && !Scr->BeNiceToColormap) GetShadeColors (&tmp_win->title); 1177645f5050Syouri if (Scr->use3Dborders && !Scr->BeNiceToColormap) { 1178645f5050Syouri GetShadeColors (&tmp_win->borderC); 1179645f5050Syouri GetShadeColors (&tmp_win->border_tile); 1180645f5050Syouri } 1181645f5050Syouri /* create windows */ 1182645f5050Syouri 1183645f5050Syouri tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->frame_bw 1184645f5050Syouri - tmp_win->frame_bw3D; 1185645f5050Syouri tmp_win->frame_y = tmp_win->attr.y - tmp_win->title_height + 1186645f5050Syouri tmp_win->old_bw - tmp_win->frame_bw - tmp_win->frame_bw3D; 1187645f5050Syouri tmp_win->frame_width = tmp_win->attr.width + 2 * tmp_win->frame_bw3D; 1188645f5050Syouri tmp_win->frame_height = tmp_win->attr.height + tmp_win->title_height + 1189645f5050Syouri 2 * tmp_win->frame_bw3D; 1190645f5050Syouri 1191645f5050Syouri ConstrainSize (tmp_win, &tmp_win->frame_width, &tmp_win->frame_height); 1192645f5050Syouri if (random_placed) 1193645f5050Syouri ConstrainByBorders (tmp_win, &tmp_win->frame_x, tmp_win->frame_width, 1194645f5050Syouri &tmp_win->frame_y, tmp_win->frame_height); 1195645f5050Syouri 1196645f5050Syouri valuemask = CWBackPixmap | CWBorderPixel | CWCursor | CWEventMask | CWBackPixel; 1197645f5050Syouri attributes.background_pixmap = None; 1198645f5050Syouri attributes.border_pixel = tmp_win->border_tile.back; 1199645f5050Syouri attributes.background_pixel = tmp_win->border_tile.back; 1200645f5050Syouri attributes.cursor = Scr->FrameCursor; 1201645f5050Syouri attributes.event_mask = (SubstructureRedirectMask | 1202645f5050Syouri ButtonPressMask | ButtonReleaseMask | 1203645f5050Syouri EnterWindowMask | LeaveWindowMask | ExposureMask); 1204645f5050Syouri if (Scr->BorderCursors) attributes.event_mask |= PointerMotionMask; 1205645f5050Syouri if (tmp_win->attr.save_under) { 1206645f5050Syouri attributes.save_under = True; 1207645f5050Syouri valuemask |= CWSaveUnder; 1208645f5050Syouri } 1209645f5050Syouri if (tmp_win->hints.flags & PWinGravity) { 1210645f5050Syouri attributes.win_gravity = tmp_win->hints.win_gravity; 1211645f5050Syouri valuemask |= CWWinGravity; 1212645f5050Syouri } 1213645f5050Syouri 1214645f5050Syouri if ((tmp_win->frame_x > Scr->rootw) || 1215645f5050Syouri (tmp_win->frame_y > Scr->rooth) || 1216645f5050Syouri ((int)(tmp_win->frame_x + tmp_win->frame_width) < 0) || 1217645f5050Syouri ((int)(tmp_win->frame_y + tmp_win->frame_height) < 0)) { 1218645f5050Syouri tmp_win->frame_x = 0; 1219645f5050Syouri tmp_win->frame_y = 0; 1220645f5050Syouri } 1221645f5050Syouri 1222645f5050Syouri DealWithNonSensicalGeometries(dpy, vroot, tmp_win); 1223645f5050Syouri 1224645f5050Syouri tmp_win->frame = XCreateWindow (dpy, vroot, tmp_win->frame_x, tmp_win->frame_y, 1225645f5050Syouri (unsigned int) tmp_win->frame_width, 1226645f5050Syouri (unsigned int) tmp_win->frame_height, 1227645f5050Syouri (unsigned int) tmp_win->frame_bw, 1228645f5050Syouri Scr->d_depth, 1229645f5050Syouri (unsigned int) CopyFromParent, 1230645f5050Syouri Scr->d_visual, valuemask, &attributes); 1231645f5050Syouri 1232645f5050Syouri if (tmp_win->title_height) 1233645f5050Syouri { 1234645f5050Syouri valuemask = (CWEventMask | CWDontPropagate | CWBorderPixel | CWBackPixel); 1235645f5050Syouri attributes.event_mask = (KeyPressMask | ButtonPressMask | 1236645f5050Syouri ButtonReleaseMask | ExposureMask); 1237645f5050Syouri attributes.do_not_propagate_mask = PointerMotionMask; 1238645f5050Syouri attributes.border_pixel = tmp_win->borderC.back; 1239645f5050Syouri attributes.background_pixel = tmp_win->title.back; 1240645f5050Syouri tmp_win->title_w = XCreateWindow (dpy, tmp_win->frame, 1241645f5050Syouri tmp_win->frame_bw3D - tmp_win->frame_bw, 1242645f5050Syouri tmp_win->frame_bw3D - tmp_win->frame_bw, 1243645f5050Syouri (unsigned int) tmp_win->attr.width, 1244645f5050Syouri (unsigned int) Scr->TitleHeight, 1245645f5050Syouri (unsigned int) tmp_win->frame_bw, 1246645f5050Syouri Scr->d_depth, 1247645f5050Syouri (unsigned int) CopyFromParent, 1248645f5050Syouri Scr->d_visual, valuemask, 1249645f5050Syouri &attributes); 1250645f5050Syouri } 1251645f5050Syouri else { 1252645f5050Syouri tmp_win->title_w = 0; 1253645f5050Syouri tmp_win->squeeze_info = NULL; 1254645f5050Syouri } 1255645f5050Syouri 1256645f5050Syouri if (tmp_win->highlight) 1257645f5050Syouri { 1258645f5050Syouri if (Scr->use3Dtitles && (Scr->Monochrome != COLOR)) 1259645f5050Syouri tmp_win->gray = XCreatePixmapFromBitmapData(dpy, vroot, 1260645f5050Syouri (char*)black_bits, gray_width, gray_height, 1261645f5050Syouri tmp_win->border_tile.fore, tmp_win->border_tile.back, 1262645f5050Syouri Scr->d_depth); 1263645f5050Syouri else 1264645f5050Syouri tmp_win->gray = XCreatePixmapFromBitmapData(dpy, vroot, 1265645f5050Syouri (char*)gray_bits, gray_width, gray_height, 1266645f5050Syouri tmp_win->border_tile.fore, tmp_win->border_tile.back, 1267645f5050Syouri Scr->d_depth); 1268645f5050Syouri 1269645f5050Syouri tmp_win->hasfocusvisible = True; 1270645f5050Syouri SetFocusVisualAttributes (tmp_win, False); 1271645f5050Syouri } 1272645f5050Syouri else 1273645f5050Syouri tmp_win->gray = None; 1274645f5050Syouri 1275645f5050Syouri RaiseWindow(tmp_win); 1276645f5050Syouri 1277645f5050Syouri if (tmp_win->title_w) { 1278645f5050Syouri ComputeTitleLocation (tmp_win); 1279645f5050Syouri CreateWindowTitlebarButtons (tmp_win); 1280645f5050Syouri XMoveWindow (dpy, tmp_win->title_w, 1281645f5050Syouri tmp_win->title_x, tmp_win->title_y); 1282645f5050Syouri XDefineCursor(dpy, tmp_win->title_w, Scr->TitleCursor); 1283645f5050Syouri } 1284645f5050Syouri else { 1285645f5050Syouri tmp_win->title_x = tmp_win->frame_bw3D - tmp_win->frame_bw; 1286645f5050Syouri tmp_win->title_y = tmp_win->frame_bw3D - tmp_win->frame_bw; 1287645f5050Syouri } 1288645f5050Syouri 1289645f5050Syouri valuemask = (CWEventMask | CWDontPropagate); 1290645f5050Syouri attributes.event_mask = (StructureNotifyMask | PropertyChangeMask | 1291645f5050Syouri ColormapChangeMask | VisibilityChangeMask | 1292645f5050Syouri FocusChangeMask | 1293645f5050Syouri EnterWindowMask | LeaveWindowMask); 1294645f5050Syouri attributes.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask; 1295645f5050Syouri XChangeWindowAttributes (dpy, tmp_win->w, valuemask, &attributes); 1296645f5050Syouri 1297645f5050Syouri if (HasShape) 1298645f5050Syouri XShapeSelectInput (dpy, tmp_win->w, ShapeNotifyMask); 1299645f5050Syouri 1300645f5050Syouri if (tmp_win->title_w) { 1301645f5050Syouri XMapWindow (dpy, tmp_win->title_w); 1302645f5050Syouri } 1303645f5050Syouri 1304645f5050Syouri if (HasShape) { 1305645f5050Syouri int xws, yws, xbs, ybs; 1306645f5050Syouri unsigned wws, hws, wbs, hbs; 1307645f5050Syouri int boundingShaped, clipShaped; 1308645f5050Syouri 1309645f5050Syouri XShapeSelectInput (dpy, tmp_win->w, ShapeNotifyMask); 1310645f5050Syouri XShapeQueryExtents (dpy, tmp_win->w, 1311645f5050Syouri &boundingShaped, &xws, &yws, &wws, &hws, 1312645f5050Syouri &clipShaped, &xbs, &ybs, &wbs, &hbs); 1313645f5050Syouri tmp_win->wShaped = boundingShaped; 1314645f5050Syouri } 1315645f5050Syouri 1316645f5050Syouri if (!tmp_win->iconmgr &&! iswman && 1317645f5050Syouri (tmp_win->w != Scr->workSpaceMgr.occupyWindow->w)) 1318645f5050Syouri XAddToSaveSet(dpy, tmp_win->w); 1319645f5050Syouri 1320645f5050Syouri XReparentWindow(dpy, tmp_win->w, tmp_win->frame, tmp_win->frame_bw3D, 1321645f5050Syouri tmp_win->title_height + tmp_win->frame_bw3D); 1322645f5050Syouri /* 1323645f5050Syouri * Reparenting generates an UnmapNotify event, followed by a MapNotify. 1324645f5050Syouri * Set the map state to FALSE to prevent a transition back to 1325645f5050Syouri * WithdrawnState in HandleUnmapNotify. Map state gets set correctly 1326645f5050Syouri * again in HandleMapNotify. 1327645f5050Syouri */ 1328645f5050Syouri tmp_win->mapped = FALSE; 1329645f5050Syouri 1330645f5050Syouri SetupFrame (tmp_win, tmp_win->frame_x, tmp_win->frame_y, 1331645f5050Syouri tmp_win->frame_width, tmp_win->frame_height, -1, True); 1332645f5050Syouri 1333645f5050Syouri /* wait until the window is iconified and the icon window is mapped 1334645f5050Syouri * before creating the icon window 1335645f5050Syouri */ 1336645f5050Syouri tmp_win->icon = (Icon*) 0; 1337645f5050Syouri tmp_win->iconslist = (name_list*) 0; 1338645f5050Syouri 1339645f5050Syouri if (!tmp_win->iconmgr) 1340645f5050Syouri { 1341645f5050Syouri GrabButtons(tmp_win); 1342645f5050Syouri GrabKeys(tmp_win); 1343645f5050Syouri } 1344645f5050Syouri 1345645f5050Syouri (void) AddIconManager(tmp_win); 1346645f5050Syouri 1347645f5050Syouri XSaveContext(dpy, tmp_win->w, TwmContext, (XPointer) tmp_win); 1348645f5050Syouri XSaveContext(dpy, tmp_win->w, ScreenContext, (XPointer) Scr); 1349645f5050Syouri XSaveContext(dpy, tmp_win->frame, TwmContext, (XPointer) tmp_win); 1350645f5050Syouri XSaveContext(dpy, tmp_win->frame, ScreenContext, (XPointer) Scr); 1351645f5050Syouri 1352645f5050Syouri if (tmp_win->title_height) 1353645f5050Syouri { 1354645f5050Syouri int i; 1355645f5050Syouri int nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; 1356645f5050Syouri 1357645f5050Syouri XSaveContext(dpy, tmp_win->title_w, TwmContext, (XPointer) tmp_win); 1358645f5050Syouri XSaveContext(dpy, tmp_win->title_w, ScreenContext, (XPointer) Scr); 1359645f5050Syouri for (i = 0; i < nb; i++) { 1360645f5050Syouri XSaveContext(dpy, tmp_win->titlebuttons[i].window, TwmContext, 1361645f5050Syouri (XPointer) tmp_win); 1362645f5050Syouri XSaveContext(dpy, tmp_win->titlebuttons[i].window, ScreenContext, 1363645f5050Syouri (XPointer) Scr); 1364645f5050Syouri } 1365645f5050Syouri if (tmp_win->hilite_wl) 1366645f5050Syouri { 1367645f5050Syouri XSaveContext(dpy, tmp_win->hilite_wl, TwmContext, (XPointer)tmp_win); 1368645f5050Syouri XSaveContext(dpy, tmp_win->hilite_wl, ScreenContext, (XPointer)Scr); 1369645f5050Syouri } 1370645f5050Syouri if (tmp_win->hilite_wr) 1371645f5050Syouri { 1372645f5050Syouri XSaveContext(dpy, tmp_win->hilite_wr, TwmContext, (XPointer)tmp_win); 1373645f5050Syouri XSaveContext(dpy, tmp_win->hilite_wr, ScreenContext, (XPointer)Scr); 1374645f5050Syouri } 1375645f5050Syouri if (tmp_win->lolite_wl) 1376645f5050Syouri { 1377645f5050Syouri XSaveContext(dpy, tmp_win->lolite_wl, TwmContext, (XPointer)tmp_win); 1378645f5050Syouri XSaveContext(dpy, tmp_win->lolite_wl, ScreenContext, (XPointer)Scr); 1379645f5050Syouri } 1380645f5050Syouri if (tmp_win->lolite_wr) 1381645f5050Syouri { 1382645f5050Syouri XSaveContext(dpy, tmp_win->lolite_wr, TwmContext, (XPointer)tmp_win); 1383645f5050Syouri XSaveContext(dpy, tmp_win->lolite_wr, ScreenContext, (XPointer)Scr); 1384645f5050Syouri } 1385645f5050Syouri } 1386645f5050Syouri 1387645f5050Syouri XUngrabServer(dpy); 1388645f5050Syouri 1389645f5050Syouri /* if we were in the middle of a menu activated function, regrab 1390645f5050Syouri * the pointer 1391645f5050Syouri */ 1392645f5050Syouri if (RootFunction) ReGrab(); 1393645f5050Syouri if (!iswman) WMapAddWindow (tmp_win); 1394645f5050Syouri SetPropsIfCaptiveCtwm (tmp_win); 1395645f5050Syouri savegeometry (tmp_win); 1396645f5050Syouri return (tmp_win); 1397645f5050Syouri} 1398645f5050Syouri 1399645f5050Syouri/*********************************************************************** 1400645f5050Syouri * 1401645f5050Syouri * Procedure: 1402645f5050Syouri * GetTwmWindow - finds the TwmWindow structure associated with 1403645f5050Syouri * a Window (if any), or NULL. 1404645f5050Syouri * 1405645f5050Syouri * Returned Value: 1406645f5050Syouri * NULL - it is not a Window we know about 1407645f5050Syouri * otherwise- the TwmWindow * 1408645f5050Syouri * 1409645f5050Syouri * Inputs: 1410645f5050Syouri * w - the window to check 1411645f5050Syouri * 1412645f5050Syouri * Note: 1413645f5050Syouri * This is a relatively cheap function since it does not involve 1414645f5050Syouri * communication with the server. Probably faster than walking 1415645f5050Syouri * the list of TwmWindows, since the lookup is by a hash table. 1416645f5050Syouri * 1417645f5050Syouri *********************************************************************** 1418645f5050Syouri */ 1419645f5050SyouriTwmWindow *GetTwmWindow(Window w) 1420645f5050Syouri{ 1421645f5050Syouri TwmWindow *twmwin; 1422645f5050Syouri int stat; 1423645f5050Syouri 1424645f5050Syouri stat = XFindContext(dpy, w, TwmContext, (XPointer *)&twmwin); 1425645f5050Syouri if (stat == XCNOENT) 1426645f5050Syouri twmwin = NULL; 1427645f5050Syouri 1428645f5050Syouri return twmwin; 1429645f5050Syouri} 1430645f5050Syouri 1431645f5050Syouri/*********************************************************************** 1432645f5050Syouri * 1433645f5050Syouri * Procedure: 1434645f5050Syouri * MappedNotOverride - checks to see if we should really 1435645f5050Syouri * put a twm frame on the window 1436645f5050Syouri * 1437645f5050Syouri * Returned Value: 1438645f5050Syouri * TRUE - go ahead and frame the window 1439645f5050Syouri * FALSE - don't frame the window 1440645f5050Syouri * 1441645f5050Syouri * Inputs: 1442645f5050Syouri * w - the window to check 1443645f5050Syouri * 1444645f5050Syouri *********************************************************************** 1445645f5050Syouri */ 1446645f5050Syouri 1447645f5050Syouriint MappedNotOverride(Window w) 1448645f5050Syouri{ 1449645f5050Syouri XWindowAttributes wa; 1450645f5050Syouri 1451645f5050Syouri XGetWindowAttributes(dpy, w, &wa); 1452645f5050Syouri return ((wa.map_state != IsUnmapped) && (wa.override_redirect != True)); 1453645f5050Syouri} 1454645f5050Syouri 1455645f5050Syouri 1456645f5050Syouri/*********************************************************************** 1457645f5050Syouri * 1458645f5050Syouri * Procedure: 1459645f5050Syouri * AddDefaultBindings - attach default bindings so that naive users 1460645f5050Syouri * don't get messed up if they provide a minimal twmrc. 1461645f5050Syouri */ 1462645f5050Syouristatic void do_add_binding (int button, int context, int modifier, int func) 1463645f5050Syouri{ 1464645f5050Syouri AddFuncButton (button, context, modifier, func, NULL, NULL); 1465645f5050Syouri} 1466645f5050Syouri 1467645f5050Syourivoid AddDefaultBindings (void) 1468645f5050Syouri{ 1469645f5050Syouri#define NoModifierMask 0 1470645f5050Syouri 1471645f5050Syouri do_add_binding (Button1, C_TITLE, NoModifierMask, F_MOVE); 1472645f5050Syouri do_add_binding (Button1, C_ICON, NoModifierMask, F_ICONIFY); 1473645f5050Syouri do_add_binding (Button1, C_ICONMGR, NoModifierMask, F_ICONIFY); 1474645f5050Syouri 1475645f5050Syouri do_add_binding (Button2, C_TITLE, NoModifierMask, F_RAISELOWER); 1476645f5050Syouri do_add_binding (Button2, C_ICON, NoModifierMask, F_ICONIFY); 1477645f5050Syouri do_add_binding (Button2, C_ICONMGR, NoModifierMask, F_ICONIFY); 1478645f5050Syouri 1479645f5050Syouri#undef NoModifierMask 1480645f5050Syouri} 1481645f5050Syouri 1482645f5050Syouri 1483645f5050Syouri 1484645f5050Syouri 1485645f5050Syouri/*********************************************************************** 1486645f5050Syouri * 1487645f5050Syouri * Procedure: 1488645f5050Syouri * GrabButtons - grab needed buttons for the window 1489645f5050Syouri * 1490645f5050Syouri * Inputs: 1491645f5050Syouri * tmp_win - the twm window structure to use 1492645f5050Syouri * 1493645f5050Syouri *********************************************************************** 1494645f5050Syouri */ 1495645f5050Syouri 1496645f5050Syouri#define AltMask (Alt1Mask | Alt2Mask | Alt3Mask | Alt4Mask | Alt5Mask) 1497645f5050Syouri#define grabbutton(button, modifier, window, pointer_mode) \ 1498645f5050Syouri XGrabButton (dpy, button, modifier, window, \ 1499645f5050Syouri True, ButtonPressMask | ButtonReleaseMask, \ 1500645f5050Syouri pointer_mode, GrabModeAsync, None, \ 1501645f5050Syouri Scr->FrameCursor); 1502645f5050Syouri 1503645f5050Syourivoid GrabButtons(TwmWindow *tmp_win) 1504645f5050Syouri{ 1505645f5050Syouri FuncButton *tmp; 1506645f5050Syouri int i; 1507645f5050Syouri unsigned int ModifierMask[8] = { ShiftMask, ControlMask, LockMask, 1508645f5050Syouri Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, 1509645f5050Syouri Mod5Mask }; 1510645f5050Syouri 1511645f5050Syouri for (tmp = Scr->FuncButtonRoot.next; tmp != NULL; tmp = tmp->next) { 1512645f5050Syouri if ((tmp->cont != C_WINDOW) || (tmp->func == 0)) continue; 1513645f5050Syouri grabbutton (tmp->num, tmp->mods, tmp_win->frame, GrabModeAsync); 1514645f5050Syouri 1515645f5050Syouri if (Scr->IgnoreLockModifier && !(tmp->mods & LockMask)) { 1516645f5050Syouri grabbutton (tmp->num, tmp->mods | LockMask, tmp_win->frame, GrabModeAsync); 1517645f5050Syouri } 1518645f5050Syouri for (i = 0 ; i < 8 ; i++) { 1519645f5050Syouri if ((Scr->IgnoreModifier & ModifierMask [i]) && !(tmp->mods & ModifierMask [i])) 1520645f5050Syouri grabbutton (tmp->num, tmp->mods | ModifierMask [i], 1521645f5050Syouri tmp_win->frame, GrabModeAsync); 1522645f5050Syouri } 1523645f5050Syouri } 1524645f5050Syouri if (Scr->ClickToFocus) { 1525645f5050Syouri grabbutton (AnyButton, None, tmp_win->w, GrabModeSync); 1526645f5050Syouri for (i = 0 ; i < 8 ; i++) { 1527645f5050Syouri grabbutton (AnyButton, ModifierMask [i], tmp_win->w, GrabModeSync); 1528645f5050Syouri } 1529645f5050Syouri } else 1530645f5050Syouri if (Scr->RaiseOnClick) { 1531645f5050Syouri grabbutton (Scr->RaiseOnClickButton, None, tmp_win->w, GrabModeSync); 1532645f5050Syouri for (i = 0 ; i < 8 ; i++) { 1533645f5050Syouri grabbutton (Scr->RaiseOnClickButton, 1534645f5050Syouri ModifierMask [i], tmp_win->w, GrabModeSync); 1535645f5050Syouri } 1536645f5050Syouri } 1537645f5050Syouri} 1538645f5050Syouri 1539645f5050Syouri/*********************************************************************** 1540645f5050Syouri * 1541645f5050Syouri * Procedure: 1542645f5050Syouri * GrabKeys - grab needed keys for the window 1543645f5050Syouri * 1544645f5050Syouri * Inputs: 1545645f5050Syouri * tmp_win - the twm window structure to use 1546645f5050Syouri * 1547645f5050Syouri *********************************************************************** 1548645f5050Syouri */ 1549645f5050Syouri 1550645f5050Syouri#define MAX_KEYCODE 256 1551645f5050Syouri#define grabkey(funckey, modifier, window) \ 1552645f5050Syouri XGrabKey(dpy, funckey->keycode, funckey->mods | modifier, window, True, \ 1553645f5050Syouri GrabModeAsync, GrabModeAsync); 1554645f5050Syouri#define ungrabkey(funckey, modifier, window) \ 1555645f5050Syouri XUngrabKey (dpy, funckey->keycode, funckey->mods | modifier, window); 1556645f5050Syouri 1557645f5050Syourivoid GrabKeys(TwmWindow *tmp_win) 1558645f5050Syouri{ 1559645f5050Syouri FuncKey *tmp; 1560645f5050Syouri IconMgr *p; 1561645f5050Syouri int i; 1562645f5050Syouri unsigned int ModifierMask[8] = { ShiftMask, ControlMask, LockMask, 1563645f5050Syouri Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, 1564645f5050Syouri Mod5Mask }; 1565645f5050Syouri 1566645f5050Syouri for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next) 1567645f5050Syouri { 1568645f5050Syouri switch (tmp->cont) 1569645f5050Syouri { 1570645f5050Syouri case C_WINDOW: 1571645f5050Syouri /* case C_WORKSPACE: */ 1572645f5050Syouri if (tmp->mods & AltMask) break; 1573645f5050Syouri grabkey (tmp, 0, tmp_win->w); 1574645f5050Syouri if (Scr->IgnoreLockModifier && !(tmp->mods & LockMask)) 1575645f5050Syouri grabkey (tmp, LockMask, tmp_win->w); 1576645f5050Syouri for (i = 0 ; i < 8 ; i++) { 1577645f5050Syouri if ((Scr->IgnoreModifier & ModifierMask [i]) && 1578645f5050Syouri !(tmp->mods & ModifierMask [i])) 1579645f5050Syouri grabkey (tmp, ModifierMask [i], tmp_win->w); 1580645f5050Syouri } 1581645f5050Syouri break; 1582645f5050Syouri 1583645f5050Syouri case C_ICON: 1584645f5050Syouri if (!tmp_win->icon || tmp_win->icon->w) break; 1585645f5050Syouri grabkey (tmp, 0, tmp_win->icon->w); 1586645f5050Syouri if (Scr->IgnoreLockModifier && !(tmp->mods & LockMask)) 1587645f5050Syouri grabkey (tmp, LockMask, tmp_win->icon->w); 1588645f5050Syouri for (i = 0 ; i < 8 ; i++) { 1589645f5050Syouri if ((Scr->IgnoreModifier & ModifierMask [i]) && 1590645f5050Syouri !(tmp->mods & ModifierMask [i])) 1591645f5050Syouri grabkey (tmp, ModifierMask [i], tmp_win->icon->w); 1592645f5050Syouri } 1593645f5050Syouri break; 1594645f5050Syouri 1595645f5050Syouri case C_TITLE: 1596645f5050Syouri if (!tmp_win->title_w) break; 1597645f5050Syouri grabkey (tmp, 0, tmp_win->title_w); 1598645f5050Syouri if (Scr->IgnoreLockModifier && !(tmp->mods & LockMask)) 1599645f5050Syouri grabkey (tmp, LockMask, tmp_win->title_w); 1600645f5050Syouri for (i = 0 ; i < 8 ; i++) { 1601645f5050Syouri if ((Scr->IgnoreModifier & ModifierMask [i]) && 1602645f5050Syouri !(tmp->mods & ModifierMask [i])) 1603645f5050Syouri grabkey (tmp, ModifierMask [i], tmp_win->title_w); 1604645f5050Syouri } 1605645f5050Syouri break; 1606645f5050Syouri 1607645f5050Syouri case C_NAME: 1608645f5050Syouri grabkey (tmp, 0, tmp_win->w); 1609645f5050Syouri if (Scr->IgnoreLockModifier && !(tmp->mods & LockMask)) { 1610645f5050Syouri grabkey (tmp, LockMask, tmp_win->w); 1611645f5050Syouri } 1612645f5050Syouri for (i = 0 ; i < 8 ; i++) { 1613645f5050Syouri if ((Scr->IgnoreModifier & ModifierMask [i]) && 1614645f5050Syouri !(tmp->mods & ModifierMask [i])) 1615645f5050Syouri grabkey (tmp, ModifierMask [i], tmp_win->w); 1616645f5050Syouri } 1617645f5050Syouri if (tmp_win->icon && tmp_win->icon->w) { 1618645f5050Syouri grabkey (tmp, 0, tmp_win->icon->w); 1619645f5050Syouri if (Scr->IgnoreLockModifier && !(tmp->mods & LockMask)) 1620645f5050Syouri grabkey (tmp, LockMask, tmp_win->icon->w); 1621645f5050Syouri for (i = 0 ; i < 8 ; i++) { 1622645f5050Syouri if ((Scr->IgnoreModifier & ModifierMask [i]) && 1623645f5050Syouri !(tmp->mods & ModifierMask [i])) 1624645f5050Syouri grabkey (tmp, ModifierMask [i], tmp_win->icon->w); 1625645f5050Syouri } 1626645f5050Syouri } 1627645f5050Syouri if (tmp_win->title_w) { 1628645f5050Syouri grabkey (tmp, 0, tmp_win->title_w); 1629645f5050Syouri if (Scr->IgnoreLockModifier && !(tmp->mods & LockMask)) 1630645f5050Syouri grabkey (tmp, LockMask, tmp_win->title_w); 1631645f5050Syouri for (i = 0 ; i < 8 ; i++) { 1632645f5050Syouri if ((Scr->IgnoreModifier & ModifierMask [i]) && 1633645f5050Syouri !(tmp->mods & ModifierMask [i])) 1634645f5050Syouri grabkey (tmp, ModifierMask [i], tmp_win->title_w); 1635645f5050Syouri } 1636645f5050Syouri } 1637645f5050Syouri break; 1638645f5050Syouri /* 1639645f5050Syouri case C_ROOT: 1640645f5050Syouri XGrabKey(dpy, tmp->keycode, tmp->mods, Scr->Root, True, 1641645f5050Syouri GrabModeAsync, GrabModeAsync); 1642645f5050Syouri break; 1643645f5050Syouri */ 1644645f5050Syouri } 1645645f5050Syouri } 1646645f5050Syouri for (tmp = Scr->FuncKeyRoot.next; tmp != NULL; tmp = tmp->next) 1647645f5050Syouri { 1648645f5050Syouri if (tmp->cont == C_ICONMGR && !Scr->NoIconManagers) 1649645f5050Syouri { 1650645f5050Syouri for (p = Scr->iconmgr; p != NULL; p = p->next) { 1651645f5050Syouri ungrabkey (tmp, 0, p->twm_win->w); 1652645f5050Syouri if (Scr->IgnoreLockModifier && !(tmp->mods & LockMask)) 1653645f5050Syouri ungrabkey (tmp, LockMask, p->twm_win->w); 1654645f5050Syouri for (i = 0 ; i < 8 ; i++) { 1655645f5050Syouri if ((Scr->IgnoreModifier & ModifierMask [i]) && 1656645f5050Syouri !(tmp->mods & ModifierMask [i])) 1657645f5050Syouri ungrabkey (tmp, ModifierMask [i], p->twm_win->w); 1658645f5050Syouri } 1659645f5050Syouri } 1660645f5050Syouri } 1661645f5050Syouri } 1662645f5050Syouri} 1663645f5050Syouri 1664645f5050Syourivoid ComputeCommonTitleOffsets (void) 1665645f5050Syouri{ 1666645f5050Syouri int buttonwidth = (Scr->TBInfo.width + Scr->TBInfo.pad); 1667645f5050Syouri 1668645f5050Syouri Scr->TBInfo.leftx = Scr->TBInfo.rightoff = Scr->FramePadding; 1669645f5050Syouri if (Scr->TBInfo.nleft > 0) Scr->TBInfo.leftx += Scr->ButtonIndent; 1670645f5050Syouri if (Scr->TBInfo.nright > 0) Scr->TBInfo.rightoff += (Scr->ButtonIndent + 1671645f5050Syouri (Scr->TBInfo.nright * buttonwidth) - 1672645f5050Syouri Scr->TBInfo.pad); 1673645f5050Syouri 1674645f5050Syouri Scr->TBInfo.titlex = (Scr->TBInfo.leftx + 1675645f5050Syouri (Scr->TBInfo.nleft * buttonwidth) - 1676645f5050Syouri Scr->TBInfo.pad + 1677645f5050Syouri Scr->TitlePadding); 1678645f5050Syouri} 1679645f5050Syouri 1680645f5050Syouristatic void CreateHighlightWindows (TwmWindow *tmp_win) 1681645f5050Syouri{ 1682645f5050Syouri XSetWindowAttributes attributes; /* attributes for create windows */ 1683645f5050Syouri GC gc; 1684645f5050Syouri XGCValues gcv; 1685645f5050Syouri unsigned long valuemask; 1686645f5050Syouri int h = (Scr->TitleHeight - 2 * Scr->FramePadding); 1687645f5050Syouri int y = Scr->FramePadding; 1688645f5050Syouri 1689645f5050Syouri if (! tmp_win->titlehighlight) { 1690645f5050Syouri tmp_win->hilite_wl = (Window) 0; 1691645f5050Syouri tmp_win->hilite_wr = (Window) 0; 1692645f5050Syouri return; 1693645f5050Syouri } 1694645f5050Syouri /* 1695645f5050Syouri * If a special highlight pixmap was given, use that. Otherwise, 1696645f5050Syouri * use a nice, even gray pattern. The old horizontal lines look really 1697645f5050Syouri * awful on interlaced monitors (as well as resembling other looks a 1698645f5050Syouri * little bit too closely), but can be used by putting 1699645f5050Syouri * 1700645f5050Syouri * Pixmaps { TitleHighlight "hline2" } 1701645f5050Syouri * 1702645f5050Syouri * (or whatever the horizontal line bitmap is named) in the startup 1703645f5050Syouri * file. If all else fails, use the foreground color to look like a 1704645f5050Syouri * solid line. 1705645f5050Syouri */ 1706645f5050Syouri 1707645f5050Syouri if (! tmp_win->HiliteImage) { 1708645f5050Syouri if (Scr->HighlightPixmapName) { 1709645f5050Syouri tmp_win->HiliteImage = GetImage (Scr->HighlightPixmapName, tmp_win->title); 1710645f5050Syouri } 1711645f5050Syouri } 1712645f5050Syouri if (! tmp_win->HiliteImage) { 1713645f5050Syouri Pixmap pm = None; 1714645f5050Syouri Pixmap bm = None; 1715645f5050Syouri 1716645f5050Syouri if (Scr->use3Dtitles && (Scr->Monochrome != COLOR)) 1717645f5050Syouri bm = XCreateBitmapFromData (dpy, tmp_win->title_w, 1718645f5050Syouri (char*)black_bits, gray_width, gray_height); 1719645f5050Syouri else 1720645f5050Syouri bm = XCreateBitmapFromData (dpy, tmp_win->title_w, 1721645f5050Syouri (char*)gray_bits, gray_width, gray_height); 1722645f5050Syouri 1723645f5050Syouri pm = XCreatePixmap (dpy, tmp_win->title_w, gray_width, gray_height, Scr->d_depth); 1724645f5050Syouri gcv.foreground = tmp_win->title.fore; 1725645f5050Syouri gcv.background = tmp_win->title.back; 1726645f5050Syouri gcv.graphics_exposures = False; 1727645f5050Syouri gc = XCreateGC (dpy, pm, (GCForeground|GCBackground|GCGraphicsExposures), &gcv); 1728645f5050Syouri if (gc) { 1729645f5050Syouri XCopyPlane (dpy, bm, pm, gc, 0, 0, gray_width, gray_height, 0, 0, 1); 1730645f5050Syouri tmp_win->HiliteImage = (Image*) malloc (sizeof (struct _Image)); 1731645f5050Syouri tmp_win->HiliteImage->pixmap = pm; 1732645f5050Syouri tmp_win->HiliteImage->width = gray_width; 1733645f5050Syouri tmp_win->HiliteImage->height = gray_height; 1734645f5050Syouri tmp_win->HiliteImage->mask = None; 1735645f5050Syouri tmp_win->HiliteImage->next = None; 1736645f5050Syouri XFreeGC (dpy, gc); 1737645f5050Syouri } else { 1738645f5050Syouri XFreePixmap (dpy, pm); 1739645f5050Syouri pm = None; 1740645f5050Syouri } 1741645f5050Syouri XFreePixmap (dpy, bm); 1742645f5050Syouri } 1743645f5050Syouri if (tmp_win->HiliteImage) { 1744645f5050Syouri valuemask = CWBackPixmap; 1745645f5050Syouri attributes.background_pixmap = tmp_win->HiliteImage->pixmap; 1746645f5050Syouri } else { 1747645f5050Syouri valuemask = CWBackPixel; 1748645f5050Syouri attributes.background_pixel = tmp_win->title.fore; 1749645f5050Syouri } 1750645f5050Syouri 1751645f5050Syouri if (Scr->use3Dtitles) { 1752645f5050Syouri y += Scr->TitleShadowDepth; 1753645f5050Syouri h -= 2 * Scr->TitleShadowDepth; 1754645f5050Syouri } 1755645f5050Syouri if (Scr->TitleJustification == J_LEFT) 1756645f5050Syouri tmp_win->hilite_wl = (Window) 0; 1757645f5050Syouri else 1758645f5050Syouri tmp_win->hilite_wl = XCreateWindow (dpy, tmp_win->title_w, 0, y, 1759645f5050Syouri (unsigned int) Scr->TBInfo.width, (unsigned int) h, 1760645f5050Syouri (unsigned int) 0, Scr->d_depth, (unsigned int) CopyFromParent, 1761645f5050Syouri Scr->d_visual, valuemask, &attributes); 1762645f5050Syouri 1763645f5050Syouri if (Scr->TitleJustification == J_RIGHT) 1764645f5050Syouri tmp_win->hilite_wr = (Window) 0; 1765645f5050Syouri else 1766645f5050Syouri tmp_win->hilite_wr = XCreateWindow (dpy, tmp_win->title_w, 0, y, 1767645f5050Syouri (unsigned int) Scr->TBInfo.width, (unsigned int) h, 1768645f5050Syouri (unsigned int) 0, Scr->d_depth, (unsigned int) CopyFromParent, 1769645f5050Syouri Scr->d_visual, valuemask, &attributes); 1770645f5050Syouri} 1771645f5050Syouri 1772645f5050Syourivoid DeleteHighlightWindows(TwmWindow *tmp_win) 1773645f5050Syouri{ 1774645f5050Syouri if (tmp_win->HiliteImage) { 1775645f5050Syouri if (Scr->HighlightPixmapName) { 1776645f5050Syouri /* 1777645f5050Syouri * Image obtained from GetImage(): it is in a cache 1778645f5050Syouri * so we don't need to free it. There will not be multiple 1779645f5050Syouri * copies if the same xpm:foo image is requested again. 1780645f5050Syouri */ 1781645f5050Syouri } else { 1782645f5050Syouri XFreePixmap (dpy, tmp_win->HiliteImage->pixmap); 1783645f5050Syouri free(tmp_win->HiliteImage); 1784645f5050Syouri } 1785645f5050Syouri tmp_win->HiliteImage = NULL; 1786645f5050Syouri } 1787645f5050Syouri} 1788645f5050Syouri 1789645f5050Syouristatic void CreateLowlightWindows (TwmWindow *tmp_win) 1790645f5050Syouri{ 1791645f5050Syouri XSetWindowAttributes attributes; /* attributes for create windows */ 1792645f5050Syouri unsigned long valuemask; 1793645f5050Syouri int h = (Scr->TitleHeight - 2 * Scr->FramePadding); 1794645f5050Syouri int y = Scr->FramePadding; 1795645f5050Syouri ColorPair cp; 1796645f5050Syouri 1797645f5050Syouri if (!Scr->UseSunkTitlePixmap || ! tmp_win->titlehighlight) { 1798645f5050Syouri tmp_win->lolite_wl = (Window) 0; 1799645f5050Syouri tmp_win->lolite_wr = (Window) 0; 1800645f5050Syouri return; 1801645f5050Syouri } 1802645f5050Syouri /* 1803645f5050Syouri * If a special highlight pixmap was given, use that. Otherwise, 1804645f5050Syouri * use a nice, even gray pattern. The old horizontal lines look really 1805645f5050Syouri * awful on interlaced monitors (as well as resembling other looks a 1806645f5050Syouri * little bit too closely), but can be used by putting 1807645f5050Syouri * 1808645f5050Syouri * Pixmaps { TitleHighlight "hline2" } 1809645f5050Syouri * 1810645f5050Syouri * (or whatever the horizontal line bitmap is named) in the startup 1811645f5050Syouri * file. If all else fails, use the foreground color to look like a 1812645f5050Syouri * solid line. 1813645f5050Syouri */ 1814645f5050Syouri 1815645f5050Syouri if (! tmp_win->LoliteImage) { 1816645f5050Syouri if (Scr->HighlightPixmapName) { 1817645f5050Syouri cp = tmp_win->title; 1818645f5050Syouri cp.shadc = tmp_win->title.shadd; 1819645f5050Syouri cp.shadd = tmp_win->title.shadc; 1820645f5050Syouri tmp_win->LoliteImage = GetImage (Scr->HighlightPixmapName, cp); 1821645f5050Syouri } 1822645f5050Syouri } 1823645f5050Syouri if (tmp_win->LoliteImage) { 1824645f5050Syouri valuemask = CWBackPixmap; 1825645f5050Syouri attributes.background_pixmap = tmp_win->LoliteImage->pixmap; 1826645f5050Syouri } else { 1827645f5050Syouri valuemask = CWBackPixel; 1828645f5050Syouri attributes.background_pixel = tmp_win->title.fore; 1829645f5050Syouri } 1830645f5050Syouri 1831645f5050Syouri if (Scr->use3Dtitles) { 1832645f5050Syouri y += 2; 1833645f5050Syouri h -= 4; 1834645f5050Syouri } 1835645f5050Syouri if (Scr->TitleJustification == J_LEFT) 1836645f5050Syouri tmp_win->lolite_wl = (Window) 0; 1837645f5050Syouri else 1838645f5050Syouri tmp_win->lolite_wl = XCreateWindow (dpy, tmp_win->title_w, 0, y, 1839645f5050Syouri (unsigned int) Scr->TBInfo.width, (unsigned int) h, 1840645f5050Syouri (unsigned int) 0, Scr->d_depth, (unsigned int) CopyFromParent, 1841645f5050Syouri Scr->d_visual, valuemask, &attributes); 1842645f5050Syouri 1843645f5050Syouri if (Scr->TitleJustification == J_RIGHT) 1844645f5050Syouri tmp_win->lolite_wr = (Window) 0; 1845645f5050Syouri else 1846645f5050Syouri tmp_win->lolite_wr = XCreateWindow (dpy, tmp_win->title_w, 0, y, 1847645f5050Syouri (unsigned int) Scr->TBInfo.width, (unsigned int) h, 1848645f5050Syouri (unsigned int) 0, Scr->d_depth, (unsigned int) CopyFromParent, 1849645f5050Syouri Scr->d_visual, valuemask, &attributes); 1850645f5050Syouri} 1851645f5050Syouri 1852645f5050Syouri 1853645f5050Syourivoid ComputeWindowTitleOffsets (TwmWindow *tmp_win, unsigned int width, 1854645f5050Syouri Bool squeeze) 1855645f5050Syouri{ 1856645f5050Syouri int titlew = width - Scr->TBInfo.titlex - Scr->TBInfo.rightoff; 1857645f5050Syouri 1858645f5050Syouri switch (Scr->TitleJustification) { 1859645f5050Syouri case J_LEFT : 1860645f5050Syouri tmp_win->name_x = Scr->TBInfo.titlex; 1861645f5050Syouri if (Scr->use3Dtitles) tmp_win->name_x += Scr->TitleShadowDepth + 2; 1862645f5050Syouri break; 1863645f5050Syouri case J_CENTER : 1864645f5050Syouri tmp_win->name_x = Scr->TBInfo.titlex + (titlew - tmp_win->name_width) / 2; 1865645f5050Syouri break; 1866645f5050Syouri case J_RIGHT : 1867645f5050Syouri tmp_win->name_x = Scr->TBInfo.titlex + titlew - tmp_win->name_width; 1868645f5050Syouri if (Scr->use3Dtitles) tmp_win->name_x -= Scr->TitleShadowDepth - 2; 1869645f5050Syouri break; 1870645f5050Syouri } 1871645f5050Syouri if (Scr->use3Dtitles) { 1872645f5050Syouri if (tmp_win->name_x < (Scr->TBInfo.titlex + 2 * Scr->TitleShadowDepth)) 1873645f5050Syouri tmp_win->name_x = Scr->TBInfo.titlex + 2 * Scr->TitleShadowDepth; 1874645f5050Syouri } 1875645f5050Syouri else 1876645f5050Syouri if (tmp_win->name_x < Scr->TBInfo.titlex) { 1877645f5050Syouri tmp_win->name_x = Scr->TBInfo.titlex; 1878645f5050Syouri } 1879645f5050Syouri tmp_win->highlightxl = Scr->TBInfo.titlex; 1880645f5050Syouri tmp_win->highlightxr = tmp_win->name_x + tmp_win->name_width + 2; 1881645f5050Syouri 1882645f5050Syouri if (Scr->use3Dtitles) { 1883645f5050Syouri tmp_win->highlightxl += Scr->TitleShadowDepth; 1884645f5050Syouri } 1885645f5050Syouri if (tmp_win->hilite_wr || Scr->TBInfo.nright > 0) 1886645f5050Syouri tmp_win->highlightxr += Scr->TitlePadding; 1887645f5050Syouri tmp_win->rightx = width - Scr->TBInfo.rightoff; 1888645f5050Syouri if (squeeze && tmp_win->squeeze_info && !tmp_win->squeezed) { 1889645f5050Syouri int rx = (tmp_win->highlightxr + 1890645f5050Syouri (tmp_win->hilite_wr 1891645f5050Syouri ? Scr->TBInfo.width * 2 : 0) + 1892645f5050Syouri (Scr->TBInfo.nright > 0 ? Scr->TitlePadding : 0) + 1893645f5050Syouri Scr->FramePadding); 1894645f5050Syouri if (rx < tmp_win->rightx) tmp_win->rightx = rx; 1895645f5050Syouri } 1896645f5050Syouri return; 1897645f5050Syouri} 1898645f5050Syouri 1899645f5050Syouri 1900645f5050Syouri/* 1901645f5050Syouri * ComputeTitleLocation - calculate the position of the title window; we need 1902645f5050Syouri * to take the frame_bw into account since we want (0,0) of the title window 1903645f5050Syouri * to line up with (0,0) of the frame window. 1904645f5050Syouri */ 1905645f5050Syourivoid ComputeTitleLocation (register TwmWindow *tmp) 1906645f5050Syouri{ 1907645f5050Syouri tmp->title_x = tmp->frame_bw3D - tmp->frame_bw; 1908645f5050Syouri tmp->title_y = tmp->frame_bw3D - tmp->frame_bw; 1909645f5050Syouri 1910645f5050Syouri if (tmp->squeeze_info && !tmp->squeezed) { 1911645f5050Syouri register SqueezeInfo *si = tmp->squeeze_info; 1912645f5050Syouri int basex; 1913645f5050Syouri int maxwidth = tmp->frame_width; 1914645f5050Syouri int tw = tmp->title_width + 2 * tmp->frame_bw3D; 1915645f5050Syouri 1916645f5050Syouri /* 1917645f5050Syouri * figure label base from squeeze info (justification fraction) 1918645f5050Syouri */ 1919645f5050Syouri if (si->denom == 0) { /* num is pixel based */ 1920645f5050Syouri basex = si->num; 1921645f5050Syouri } else { /* num/denom is fraction */ 1922645f5050Syouri basex = ((si->num * maxwidth) / si->denom); 1923645f5050Syouri } 1924645f5050Syouri if (si->num < 0) 1925645f5050Syouri basex += maxwidth; 1926645f5050Syouri 1927645f5050Syouri /* 1928645f5050Syouri * adjust for left (nop), center, right justify and clip 1929645f5050Syouri */ 1930645f5050Syouri switch (si->justify) { 1931645f5050Syouri case J_CENTER: 1932645f5050Syouri basex -= tw / 2; 1933645f5050Syouri break; 1934645f5050Syouri case J_RIGHT: 1935645f5050Syouri basex -= tw - 1; 1936645f5050Syouri break; 1937645f5050Syouri } 1938645f5050Syouri if (basex > maxwidth - tw) 1939645f5050Syouri basex = maxwidth - tw; 1940645f5050Syouri if (basex < 0) basex = 0; 1941645f5050Syouri 1942645f5050Syouri tmp->title_x = basex - tmp->frame_bw + tmp->frame_bw3D; 1943645f5050Syouri } 1944645f5050Syouri} 1945645f5050Syouri 1946645f5050Syouri 1947645f5050Syouristatic void CreateWindowTitlebarButtons (TwmWindow *tmp_win) 1948645f5050Syouri{ 1949645f5050Syouri unsigned long valuemask; /* mask for create windows */ 1950645f5050Syouri XSetWindowAttributes attributes; /* attributes for create windows */ 1951645f5050Syouri int leftx, rightx, y; 1952645f5050Syouri TitleButton *tb; 1953645f5050Syouri int nb; 1954645f5050Syouri 1955645f5050Syouri if (tmp_win->title_height == 0) 1956645f5050Syouri { 1957645f5050Syouri tmp_win->hilite_wl = (Window) 0; 1958645f5050Syouri tmp_win->hilite_wr = (Window) 0; 1959645f5050Syouri tmp_win->lolite_wl = (Window) 0; 1960645f5050Syouri tmp_win->lolite_wr = (Window) 0; 1961645f5050Syouri return; 1962645f5050Syouri } 1963645f5050Syouri 1964645f5050Syouri 1965645f5050Syouri /* 1966645f5050Syouri * create the title bar windows; let the event handler deal with painting 1967645f5050Syouri * so that we don't have to spend two pixmaps (or deal with hashing) 1968645f5050Syouri */ 1969645f5050Syouri ComputeWindowTitleOffsets (tmp_win, tmp_win->attr.width, False); 1970645f5050Syouri 1971645f5050Syouri leftx = y = Scr->TBInfo.leftx; 1972645f5050Syouri rightx = tmp_win->rightx; 1973645f5050Syouri 1974645f5050Syouri attributes.win_gravity = NorthWestGravity; 1975645f5050Syouri attributes.background_pixel = tmp_win->title.back; 1976645f5050Syouri attributes.border_pixel = tmp_win->title.fore; 1977645f5050Syouri attributes.event_mask = (ButtonPressMask | ButtonReleaseMask | 1978645f5050Syouri ExposureMask); 1979645f5050Syouri attributes.cursor = Scr->ButtonCursor; 1980645f5050Syouri valuemask = (CWWinGravity | CWBackPixel | CWBorderPixel | CWEventMask | 1981645f5050Syouri CWCursor); 1982645f5050Syouri 1983645f5050Syouri tmp_win->titlebuttons = NULL; 1984645f5050Syouri nb = Scr->TBInfo.nleft + Scr->TBInfo.nright; 1985645f5050Syouri if (nb > 0) { 1986645f5050Syouri tmp_win->titlebuttons = (TBWindow *) malloc (nb * sizeof(TBWindow)); 1987645f5050Syouri if (!tmp_win->titlebuttons) { 1988645f5050Syouri fprintf (stderr, "%s: unable to allocate %d titlebuttons\n", 1989645f5050Syouri ProgramName, nb); 1990645f5050Syouri } else { 1991645f5050Syouri TBWindow *tbw; 1992645f5050Syouri int boxwidth = (Scr->TBInfo.width + Scr->TBInfo.pad); 1993645f5050Syouri unsigned int h = (Scr->TBInfo.width - Scr->TBInfo.border * 2); 1994645f5050Syouri 1995645f5050Syouri for (tb = Scr->TBInfo.head, tbw = tmp_win->titlebuttons; tb; 1996645f5050Syouri tb = tb->next, tbw++) { 1997645f5050Syouri int x; 1998645f5050Syouri if (tb->rightside) { 1999645f5050Syouri x = rightx; 2000645f5050Syouri rightx += boxwidth; 2001645f5050Syouri attributes.win_gravity = NorthEastGravity; 2002645f5050Syouri } else { 2003645f5050Syouri x = leftx; 2004645f5050Syouri leftx += boxwidth; 2005645f5050Syouri attributes.win_gravity = NorthWestGravity; 2006645f5050Syouri } 2007645f5050Syouri tbw->window = XCreateWindow (dpy, tmp_win->title_w, x, y, h, h, 2008645f5050Syouri (unsigned int) Scr->TBInfo.border, 2009645f5050Syouri 0, (unsigned int) CopyFromParent, 2010645f5050Syouri (Visual *) CopyFromParent, 2011645f5050Syouri valuemask, &attributes); 2012645f5050Syouri tbw->image = GetImage (tb->name, tmp_win->title); 2013645f5050Syouri if (! tbw->image) { 2014645f5050Syouri tbw->image = GetImage (TBPM_QUESTION, tmp_win->title); 2015645f5050Syouri if (! tbw->image) { /* cannot happen (see util.c) */ 2016645f5050Syouri fprintf (stderr, "%s: unable to add titlebar button \"%s\"\n", 2017645f5050Syouri ProgramName, tb->name); 2018645f5050Syouri } 2019645f5050Syouri } 2020645f5050Syouri tbw->info = tb; 2021645f5050Syouri } 2022645f5050Syouri } 2023645f5050Syouri } 2024645f5050Syouri 2025645f5050Syouri CreateHighlightWindows (tmp_win); 2026645f5050Syouri CreateLowlightWindows (tmp_win); 2027645f5050Syouri XMapSubwindows(dpy, tmp_win->title_w); 2028645f5050Syouri if (tmp_win->hilite_wl) XUnmapWindow(dpy, tmp_win->hilite_wl); 2029645f5050Syouri if (tmp_win->hilite_wr) XUnmapWindow(dpy, tmp_win->hilite_wr); 2030645f5050Syouri if (tmp_win->lolite_wl) XMapWindow(dpy, tmp_win->lolite_wl); 2031645f5050Syouri if (tmp_win->lolite_wr) XMapWindow(dpy, tmp_win->lolite_wr); 2032645f5050Syouri return; 2033645f5050Syouri} 2034645f5050Syouri 2035645f5050Syourivoid SetHighlightPixmap (char *filename) 2036645f5050Syouri{ 2037645f5050Syouri#ifdef VMS 2038645f5050Syouri char *ftemp; 2039645f5050Syouri ftemp = (char *) malloc((strlen(filename)+1)*sizeof(char)); 2040645f5050Syouri Scr->HighlightPixmapName = strcpy (ftemp,filename); 2041645f5050Syouri#else 2042645f5050Syouri Scr->HighlightPixmapName = (char*) strdup (filename); 2043645f5050Syouri#endif 2044645f5050Syouri} 2045645f5050Syouri 2046645f5050Syouri 2047645f5050Syourivoid FetchWmProtocols (TwmWindow *tmp) 2048645f5050Syouri{ 2049645f5050Syouri unsigned long flags = 0L; 2050645f5050Syouri Atom *protocols = NULL; 2051645f5050Syouri int n; 2052645f5050Syouri 2053645f5050Syouri if (XGetWMProtocols (dpy, tmp->w, &protocols, &n)) { 2054645f5050Syouri register int i; 2055645f5050Syouri register Atom *ap; 2056645f5050Syouri 2057645f5050Syouri for (i = 0, ap = protocols; i < n; i++, ap++) { 2058645f5050Syouri if (*ap == _XA_WM_TAKE_FOCUS) flags |= DoesWmTakeFocus; 2059645f5050Syouri if (*ap == _XA_WM_SAVE_YOURSELF) flags |= DoesWmSaveYourself; 2060645f5050Syouri if (*ap == _XA_WM_DELETE_WINDOW) flags |= DoesWmDeleteWindow; 2061645f5050Syouri } 2062645f5050Syouri if (protocols) XFree ((char *) protocols); 2063645f5050Syouri } 2064645f5050Syouri tmp->protocols = flags; 2065645f5050Syouri} 2066645f5050Syouri 2067645f5050SyouriTwmColormap *CreateTwmColormap(Colormap c) 2068645f5050Syouri{ 2069645f5050Syouri TwmColormap *cmap; 2070645f5050Syouri cmap = (TwmColormap *) malloc(sizeof(TwmColormap)); 2071645f5050Syouri if (!cmap || 2072645f5050Syouri XSaveContext(dpy, c, ColormapContext, (XPointer) cmap)) { 2073645f5050Syouri if (cmap) free((char *) cmap); 2074645f5050Syouri return (NULL); 2075645f5050Syouri } 2076645f5050Syouri cmap->c = c; 2077645f5050Syouri cmap->state = 0; 2078645f5050Syouri cmap->install_req = 0; 2079645f5050Syouri cmap->w = None; 2080645f5050Syouri cmap->refcnt = 1; 2081645f5050Syouri return (cmap); 2082645f5050Syouri} 2083645f5050Syouri 2084645f5050SyouriColormapWindow *CreateColormapWindow(Window w, 2085645f5050Syouri Bool creating_parent, 2086645f5050Syouri Bool property_window) 2087645f5050Syouri{ 2088645f5050Syouri ColormapWindow *cwin; 2089645f5050Syouri TwmColormap *cmap; 2090645f5050Syouri XWindowAttributes attributes; 2091645f5050Syouri 2092645f5050Syouri cwin = (ColormapWindow *) malloc(sizeof(ColormapWindow)); 2093645f5050Syouri if (cwin) { 2094645f5050Syouri if (!XGetWindowAttributes(dpy, w, &attributes) || 2095645f5050Syouri XSaveContext(dpy, w, ColormapContext, (XPointer) cwin)) { 2096645f5050Syouri free((char *) cwin); 2097645f5050Syouri return (NULL); 2098645f5050Syouri } 2099645f5050Syouri 2100645f5050Syouri if (XFindContext(dpy, attributes.colormap, ColormapContext, 2101645f5050Syouri (XPointer *)&cwin->colormap) == XCNOENT) { 2102645f5050Syouri cwin->colormap = cmap = CreateTwmColormap(attributes.colormap); 2103645f5050Syouri if (!cmap) { 2104645f5050Syouri XDeleteContext(dpy, w, ColormapContext); 2105645f5050Syouri free((char *) cwin); 2106645f5050Syouri return (NULL); 2107645f5050Syouri } 2108645f5050Syouri } else { 2109645f5050Syouri cwin->colormap->refcnt++; 2110645f5050Syouri } 2111645f5050Syouri 2112645f5050Syouri cwin->w = w; 2113645f5050Syouri /* 2114645f5050Syouri * Assume that windows in colormap list are 2115645f5050Syouri * obscured if we are creating the parent window. 2116645f5050Syouri * Otherwise, we assume they are unobscured. 2117645f5050Syouri */ 2118645f5050Syouri cwin->visibility = creating_parent ? 2119645f5050Syouri VisibilityPartiallyObscured : VisibilityUnobscured; 2120645f5050Syouri cwin->refcnt = 1; 2121645f5050Syouri 2122645f5050Syouri /* 2123645f5050Syouri * If this is a ColormapWindow property window and we 2124645f5050Syouri * are not monitoring ColormapNotify or VisibilityNotify 2125645f5050Syouri * events, we need to. 2126645f5050Syouri */ 2127645f5050Syouri if (property_window && 2128645f5050Syouri (attributes.your_event_mask & 2129645f5050Syouri (ColormapChangeMask|VisibilityChangeMask)) != 2130645f5050Syouri (ColormapChangeMask|VisibilityChangeMask)) { 2131645f5050Syouri XSelectInput(dpy, w, attributes.your_event_mask | 2132645f5050Syouri (ColormapChangeMask|VisibilityChangeMask)); 2133645f5050Syouri } 2134645f5050Syouri } 2135645f5050Syouri 2136645f5050Syouri return (cwin); 2137645f5050Syouri} 2138645f5050Syouri 2139645f5050Syouriint FetchWmColormapWindows (TwmWindow *tmp) 2140645f5050Syouri{ 2141645f5050Syouri register int i, j; 2142645f5050Syouri Window *cmap_windows = NULL; 2143645f5050Syouri Bool can_free_cmap_windows = False; 2144645f5050Syouri int number_cmap_windows = 0; 2145645f5050Syouri ColormapWindow **cwins = NULL; 2146645f5050Syouri int previously_installed; 2147645f5050Syouri 2148645f5050Syouri number_cmap_windows = 0; 2149645f5050Syouri 2150645f5050Syouri if (/* SUPPRESS 560 */ 2151645f5050Syouri (previously_installed = 2152645f5050Syouri (Scr->cmapInfo.cmaps == &tmp->cmaps && tmp->cmaps.number_cwins))) { 2153645f5050Syouri cwins = tmp->cmaps.cwins; 2154645f5050Syouri for (i = 0; i < tmp->cmaps.number_cwins; i++) 2155645f5050Syouri cwins[i]->colormap->state = 0; 2156645f5050Syouri } 2157645f5050Syouri 2158645f5050Syouri if (XGetWMColormapWindows (dpy, tmp->w, &cmap_windows, 2159645f5050Syouri &number_cmap_windows) && 2160645f5050Syouri number_cmap_windows > 0) { 2161645f5050Syouri 2162645f5050Syouri can_free_cmap_windows = False; 2163645f5050Syouri /* 2164645f5050Syouri * check if the top level is in the list, add to front if not 2165645f5050Syouri */ 2166645f5050Syouri for (i = 0; i < number_cmap_windows; i++) { 2167645f5050Syouri if (cmap_windows[i] == tmp->w) break; 2168645f5050Syouri } 2169645f5050Syouri if (i == number_cmap_windows) { /* not in list */ 2170645f5050Syouri Window *new_cmap_windows = 2171645f5050Syouri (Window *) malloc (sizeof(Window) * (number_cmap_windows + 1)); 2172645f5050Syouri 2173645f5050Syouri if (!new_cmap_windows) { 2174645f5050Syouri fprintf (stderr, 2175645f5050Syouri "%s: unable to allocate %d element colormap window array\n", 2176645f5050Syouri ProgramName, number_cmap_windows+1); 2177645f5050Syouri goto done; 2178645f5050Syouri } 2179645f5050Syouri new_cmap_windows[0] = tmp->w; /* add to front */ 2180645f5050Syouri for (i = 0; i < number_cmap_windows; i++) { /* append rest */ 2181645f5050Syouri new_cmap_windows[i+1] = cmap_windows[i]; 2182645f5050Syouri } 2183645f5050Syouri XFree ((char *) cmap_windows); 2184645f5050Syouri can_free_cmap_windows = True; /* do not use XFree any more */ 2185645f5050Syouri cmap_windows = new_cmap_windows; 2186645f5050Syouri number_cmap_windows++; 2187645f5050Syouri } 2188645f5050Syouri 2189645f5050Syouri cwins = (ColormapWindow **) malloc(sizeof(ColormapWindow *) * 2190645f5050Syouri number_cmap_windows); 2191645f5050Syouri if (cwins) { 2192645f5050Syouri for (i = 0; i < number_cmap_windows; i++) { 2193645f5050Syouri 2194645f5050Syouri /* 2195645f5050Syouri * Copy any existing entries into new list. 2196645f5050Syouri */ 2197645f5050Syouri for (j = 0; j < tmp->cmaps.number_cwins; j++) { 2198645f5050Syouri if (tmp->cmaps.cwins[j]->w == cmap_windows[i]) { 2199645f5050Syouri cwins[i] = tmp->cmaps.cwins[j]; 2200645f5050Syouri cwins[i]->refcnt++; 2201645f5050Syouri break; 2202645f5050Syouri } 2203645f5050Syouri } 2204645f5050Syouri 2205645f5050Syouri /* 2206645f5050Syouri * If the colormap window is not being pointed by 2207645f5050Syouri * some other applications colormap window list, 2208645f5050Syouri * create a new entry. 2209645f5050Syouri */ 2210645f5050Syouri if (j == tmp->cmaps.number_cwins) { 2211645f5050Syouri if (XFindContext(dpy, cmap_windows[i], ColormapContext, 2212645f5050Syouri (XPointer *)&cwins[i]) == XCNOENT) { 2213645f5050Syouri if ((cwins[i] = CreateColormapWindow(cmap_windows[i], 2214645f5050Syouri (Bool) tmp->cmaps.number_cwins == 0, 2215645f5050Syouri True)) == NULL) { 2216645f5050Syouri int k; 2217645f5050Syouri for (k = i + 1; k < number_cmap_windows; k++) 2218645f5050Syouri cmap_windows[k-1] = cmap_windows[k]; 2219645f5050Syouri i--; 2220645f5050Syouri number_cmap_windows--; 2221645f5050Syouri } 2222645f5050Syouri } else 2223645f5050Syouri cwins[i]->refcnt++; 2224645f5050Syouri } 2225645f5050Syouri } 2226645f5050Syouri } 2227645f5050Syouri } 2228645f5050Syouri 2229645f5050Syouri /* No else here, in case we bailed out of clause above. 2230645f5050Syouri */ 2231645f5050Syouri if (number_cmap_windows == 0) { 2232645f5050Syouri 2233645f5050Syouri number_cmap_windows = 1; 2234645f5050Syouri 2235645f5050Syouri cwins = (ColormapWindow **) malloc(sizeof(ColormapWindow *)); 2236645f5050Syouri if (XFindContext(dpy, tmp->w, ColormapContext, (XPointer *)&cwins[0]) == 2237645f5050Syouri XCNOENT) 2238645f5050Syouri cwins[0] = CreateColormapWindow(tmp->w, 2239645f5050Syouri (Bool) tmp->cmaps.number_cwins == 0, False); 2240645f5050Syouri else 2241645f5050Syouri cwins[0]->refcnt++; 2242645f5050Syouri } 2243645f5050Syouri 2244645f5050Syouri if (tmp->cmaps.number_cwins) 2245645f5050Syouri free_cwins(tmp); 2246645f5050Syouri 2247645f5050Syouri tmp->cmaps.cwins = cwins; 2248645f5050Syouri tmp->cmaps.number_cwins = number_cmap_windows; 2249645f5050Syouri if (number_cmap_windows > 1) 2250645f5050Syouri tmp->cmaps.scoreboard = 2251645f5050Syouri (char *) calloc(1, ColormapsScoreboardLength(&tmp->cmaps)); 2252645f5050Syouri 2253645f5050Syouri if (previously_installed) { 2254645f5050Syouri InstallColormaps(PropertyNotify, NULL); 2255645f5050Syouri } 2256645f5050Syouri 2257645f5050Syouri done: 2258645f5050Syouri if (cmap_windows) { 2259645f5050Syouri if (can_free_cmap_windows) 2260645f5050Syouri free ((char *) cmap_windows); 2261645f5050Syouri else 2262645f5050Syouri XFree ((char *) cmap_windows); 2263645f5050Syouri } 2264645f5050Syouri 2265645f5050Syouri return (0); 2266645f5050Syouri} 2267645f5050Syouri 2268645f5050Syouri 2269645f5050Syourivoid GetWindowSizeHints (TwmWindow *tmp) 2270645f5050Syouri{ 2271645f5050Syouri long supplied = 0; 2272645f5050Syouri XSizeHints *hints = &tmp->hints; 2273645f5050Syouri 2274645f5050Syouri if (!XGetWMNormalHints (dpy, tmp->w, hints, &supplied)) 2275645f5050Syouri hints->flags = 0; 2276645f5050Syouri 2277645f5050Syouri if (hints->flags & PResizeInc) { 2278645f5050Syouri if (hints->width_inc == 0) hints->width_inc = 1; 2279645f5050Syouri if (hints->height_inc == 0) hints->height_inc = 1; 2280645f5050Syouri } 2281645f5050Syouri 2282645f5050Syouri if (!(supplied & PWinGravity) && (hints->flags & USPosition)) { 2283645f5050Syouri static int gravs[] = { SouthEastGravity, SouthWestGravity, 2284645f5050Syouri NorthEastGravity, NorthWestGravity }; 2285645f5050Syouri int right = tmp->attr.x + tmp->attr.width + 2 * tmp->old_bw; 2286645f5050Syouri int bottom = tmp->attr.y + tmp->attr.height + 2 * tmp->old_bw; 2287645f5050Syouri hints->win_gravity = 2288645f5050Syouri gravs[((Scr->rooth - bottom < 2289645f5050Syouri tmp->title_height + 2 * tmp->frame_bw3D) ? 0 : 2) | 2290645f5050Syouri ((Scr->rootw - right < 2291645f5050Syouri tmp->title_height + 2 * tmp->frame_bw3D) ? 0 : 1)]; 2292645f5050Syouri hints->flags |= PWinGravity; 2293645f5050Syouri } 2294645f5050Syouri 2295645f5050Syouri /* Check for min size < max size */ 2296645f5050Syouri if ((hints->flags & (PMinSize|PMaxSize)) == (PMinSize|PMaxSize)) { 2297645f5050Syouri if (hints->max_width < hints->min_width) { 2298645f5050Syouri if (hints->max_width > 0) { 2299645f5050Syouri hints->min_width = hints->max_width; 2300645f5050Syouri } else if (hints->min_width > 0) { 2301645f5050Syouri hints->max_width = hints->min_width; 2302645f5050Syouri } else { 2303645f5050Syouri hints->max_width = hints->min_width = 1; 2304645f5050Syouri } 2305645f5050Syouri } 2306645f5050Syouri 2307645f5050Syouri if (hints->max_height < hints->min_height) { 2308645f5050Syouri if (hints->max_height > 0) { 2309645f5050Syouri hints->min_height = hints->max_height; 2310645f5050Syouri } else if (hints->min_height > 0) { 2311645f5050Syouri hints->max_height = hints->min_height; 2312645f5050Syouri } else { 2313645f5050Syouri hints->max_height = hints->min_height = 1; 2314645f5050Syouri } 2315645f5050Syouri } 2316645f5050Syouri } 2317645f5050Syouri} 2318645f5050Syouri 2319645f5050Syourivoid AnimateButton (TBWindow *tbw) 2320645f5050Syouri{ 2321645f5050Syouri Image *image; 2322645f5050Syouri XSetWindowAttributes attr; 2323645f5050Syouri 2324645f5050Syouri image = tbw->image; 2325645f5050Syouri attr.background_pixmap = image->pixmap; 2326645f5050Syouri XChangeWindowAttributes (dpy, tbw->window, CWBackPixmap, &attr); 2327645f5050Syouri XClearWindow (dpy, tbw->window); 2328645f5050Syouri tbw->image = image->next; 2329645f5050Syouri} 2330645f5050Syouri 2331645f5050Syourivoid AnimateHighlight (TwmWindow *t) 2332645f5050Syouri{ 2333645f5050Syouri Image *image; 2334645f5050Syouri XSetWindowAttributes attr; 2335645f5050Syouri 2336645f5050Syouri image = t->HiliteImage; 2337645f5050Syouri attr.background_pixmap = image->pixmap; 2338645f5050Syouri if (t->hilite_wl) { 2339645f5050Syouri XChangeWindowAttributes (dpy, t->hilite_wl, CWBackPixmap, &attr); 2340645f5050Syouri XClearWindow (dpy, t->hilite_wl); 2341645f5050Syouri } 2342645f5050Syouri if (t->hilite_wr) { 2343645f5050Syouri XChangeWindowAttributes (dpy, t->hilite_wr, CWBackPixmap, &attr); 2344645f5050Syouri XClearWindow (dpy, t->hilite_wr); 2345645f5050Syouri } 2346645f5050Syouri t->HiliteImage = image->next; 2347645f5050Syouri} 2348645f5050Syouri 2349645f5050Syouriname_list **AddWindowRegion (char *geom, int grav1, int grav2) 2350645f5050Syouri{ 2351645f5050Syouri WindowRegion *wr; 2352645f5050Syouri int mask; 2353645f5050Syouri 2354645f5050Syouri wr = (WindowRegion*) malloc (sizeof (WindowRegion)); 2355645f5050Syouri wr->next = NULL; 2356645f5050Syouri 2357645f5050Syouri if (!Scr->FirstWindowRegion) Scr->FirstWindowRegion = wr; 2358645f5050Syouri 2359645f5050Syouri wr->entries = NULL; 2360645f5050Syouri wr->clientlist = NULL; 2361645f5050Syouri wr->grav1 = grav1; 2362645f5050Syouri wr->grav2 = grav2; 2363645f5050Syouri wr->x = wr->y = wr->w = wr->h = 0; 2364645f5050Syouri 2365645f5050Syouri mask = XParseGeometry (geom, &wr->x, &wr->y, (unsigned int*) &wr->w, 2366645f5050Syouri (unsigned int*) &wr->h); 2367645f5050Syouri 2368645f5050Syouri if (mask & XNegative) wr->x += Scr->rootw - wr->w; 2369645f5050Syouri if (mask & YNegative) wr->y += Scr->rooth - wr->h; 2370645f5050Syouri 2371645f5050Syouri return (&(wr->clientlist)); 2372645f5050Syouri} 2373645f5050Syouri 2374645f5050Syourivoid CreateWindowRegions (void) { 2375645f5050Syouri WindowRegion *wr, *wr1 = NULL, *wr2 = NULL; 2376645f5050Syouri WorkSpace *wl; 2377645f5050Syouri 2378645f5050Syouri for (wl = Scr->workSpaceMgr.workSpaceList; wl != NULL; wl = wl->next) { 2379645f5050Syouri wl->FirstWindowRegion = NULL; 2380645f5050Syouri wr2 = NULL; 2381645f5050Syouri for (wr = Scr->FirstWindowRegion; wr != NULL; wr = wr->next) { 2382645f5050Syouri wr1 = (WindowRegion*) malloc (sizeof (WindowRegion)); 2383645f5050Syouri *wr1 = *wr; 2384645f5050Syouri wr1->entries = (WindowEntry*) malloc (sizeof (WindowEntry)); 2385645f5050Syouri wr1->entries->next = 0; 2386645f5050Syouri wr1->entries->x = wr1->x; 2387645f5050Syouri wr1->entries->y = wr1->y; 2388645f5050Syouri wr1->entries->w = wr1->w; 2389645f5050Syouri wr1->entries->h = wr1->h; 2390645f5050Syouri wr1->entries->twm_win = (TwmWindow*) 0; 2391645f5050Syouri wr1->entries->used = 0; 2392645f5050Syouri if (wr2) wr2->next = wr1; else wl->FirstWindowRegion = wr1; 2393645f5050Syouri wr2 = wr1; 2394645f5050Syouri } 2395645f5050Syouri if (wr1) wr1->next = NULL; 2396645f5050Syouri } 2397645f5050Syouri} 2398645f5050Syouri 2399645f5050Syouri 2400645f5050SyouriBool PlaceWindowInRegion (TwmWindow *tmp_win, int *final_x, int *final_y) 2401645f5050Syouri{ 2402645f5050Syouri WindowRegion *wr; 2403645f5050Syouri WindowEntry *we; 2404645f5050Syouri int w, h; 2405645f5050Syouri WorkSpace *wl; 2406645f5050Syouri 2407645f5050Syouri if (!Scr->FirstWindowRegion) return (False); 2408645f5050Syouri for (wl = Scr->workSpaceMgr.workSpaceList; wl != NULL; wl = wl->next) { 2409645f5050Syouri if (OCCUPY (tmp_win, wl)) break; 2410645f5050Syouri } 2411645f5050Syouri if (!wl) return (False); 2412645f5050Syouri w = tmp_win->frame_width; 2413645f5050Syouri h = tmp_win->frame_height; 2414645f5050Syouri we = (WindowEntry*) 0; 2415645f5050Syouri for (wr = wl->FirstWindowRegion; wr; wr = wr->next) { 2416645f5050Syouri if (LookInList (wr->clientlist, tmp_win->full_name, &tmp_win->class)) { 2417645f5050Syouri for (we = wr->entries; we; we=we->next) { 2418645f5050Syouri if (we->used) continue; 2419645f5050Syouri if (we->w >= w && we->h >= h) break; 2420645f5050Syouri } 2421645f5050Syouri if (we) break; 2422645f5050Syouri } 2423645f5050Syouri } 2424645f5050Syouri tmp_win->wr = (WindowRegion*) 0; 2425645f5050Syouri if (!we) return (False); 2426645f5050Syouri 2427645f5050Syouri splitWindowRegionEntry (we, wr->grav1, wr->grav2, w, h); 2428645f5050Syouri we->used = 1; 2429645f5050Syouri we->twm_win = tmp_win; 2430645f5050Syouri *final_x = we->x; 2431645f5050Syouri *final_y = we->y; 2432645f5050Syouri tmp_win->wr = wr; 2433645f5050Syouri return (True); 2434645f5050Syouri} 2435645f5050Syouri 2436645f5050Syouristatic void splitWindowRegionEntry (WindowEntry *we, int grav1, int grav2, 2437645f5050Syouri int w, int h) 2438645f5050Syouri{ 2439645f5050Syouri WindowEntry *new; 2440645f5050Syouri 2441645f5050Syouri switch (grav1) { 2442645f5050Syouri case D_NORTH: 2443645f5050Syouri case D_SOUTH: 2444645f5050Syouri if (w != we->w) splitWindowRegionEntry (we, grav2, grav1, w, we->h); 2445645f5050Syouri if (h != we->h) { 2446645f5050Syouri new = (WindowEntry *) malloc (sizeof (WindowEntry)); 2447645f5050Syouri new->twm_win = 0; 2448645f5050Syouri new->used = 0; 2449645f5050Syouri new->next = we->next; 2450645f5050Syouri we->next = new; 2451645f5050Syouri new->x = we->x; 2452645f5050Syouri new->h = (we->h - h); 2453645f5050Syouri new->w = we->w; 2454645f5050Syouri we->h = h; 2455645f5050Syouri if (grav1 == D_SOUTH) { 2456645f5050Syouri new->y = we->y; 2457645f5050Syouri we->y = new->y + new->h; 2458645f5050Syouri } else 2459645f5050Syouri new->y = we->y + we->h; 2460645f5050Syouri } 2461645f5050Syouri break; 2462645f5050Syouri case D_EAST: 2463645f5050Syouri case D_WEST: 2464645f5050Syouri if (h != we->h) splitWindowRegionEntry (we, grav2, grav1, we->w, h); 2465645f5050Syouri if (w != we->w) { 2466645f5050Syouri new = (WindowEntry *) malloc (sizeof (WindowEntry)); 2467645f5050Syouri new->twm_win = 0; 2468645f5050Syouri new->used = 0; 2469645f5050Syouri new->next = we->next; 2470645f5050Syouri we->next = new; 2471645f5050Syouri new->y = we->y; 2472645f5050Syouri new->w = (we->w - w); 2473645f5050Syouri new->h = we->h; 2474645f5050Syouri we->w = w; 2475645f5050Syouri if (grav1 == D_EAST) { 2476645f5050Syouri new->x = we->x; 2477645f5050Syouri we->x = new->x + new->w; 2478645f5050Syouri } else 2479645f5050Syouri new->x = we->x + we->w; 2480645f5050Syouri } 2481645f5050Syouri break; 2482645f5050Syouri } 2483645f5050Syouri} 2484645f5050Syouri 2485645f5050Syouristatic WindowEntry *findWindowEntry (WorkSpace *wl, TwmWindow *tmp_win, 2486645f5050Syouri WindowRegion **wrp) 2487645f5050Syouri{ 2488645f5050Syouri WindowRegion *wr; 2489645f5050Syouri WindowEntry *we; 2490645f5050Syouri 2491645f5050Syouri for (wr = wl->FirstWindowRegion; wr; wr = wr->next) { 2492645f5050Syouri for (we = wr->entries; we; we=we->next) { 2493645f5050Syouri if (we->twm_win == tmp_win) { 2494645f5050Syouri if (wrp) *wrp = wr; 2495645f5050Syouri return we; 2496645f5050Syouri } 2497645f5050Syouri } 2498645f5050Syouri } 2499645f5050Syouri return (WindowEntry*) 0; 2500645f5050Syouri} 2501645f5050Syouri 2502645f5050Syouristatic WindowEntry *prevWindowEntry (WindowEntry *we, WindowRegion *wr) 2503645f5050Syouri{ 2504645f5050Syouri WindowEntry *wp; 2505645f5050Syouri 2506645f5050Syouri if (we == wr->entries) return 0; 2507645f5050Syouri for (wp = wr->entries; wp->next != we; wp=wp->next); 2508645f5050Syouri return wp; 2509645f5050Syouri} 2510645f5050Syouri 2511645f5050Syouristatic void mergeWindowEntries (WindowEntry *old, WindowEntry *we) 2512645f5050Syouri{ 2513645f5050Syouri if (old->y == we->y) { 2514645f5050Syouri we->w = old->w + we->w; 2515645f5050Syouri if (old->x < we->x) we->x = old->x; 2516645f5050Syouri } else { 2517645f5050Syouri we->h = old->h + we->h; 2518645f5050Syouri if (old->y < we->y) we->y = old->y; 2519645f5050Syouri } 2520645f5050Syouri} 2521645f5050Syouri 2522645f5050Syourivoid RemoveWindowFromRegion (TwmWindow *tmp_win) 2523645f5050Syouri{ 2524645f5050Syouri WindowEntry *we, *wp, *wn; 2525645f5050Syouri WindowRegion *wr; 2526645f5050Syouri WorkSpace *wl; 2527645f5050Syouri 2528645f5050Syouri if (!Scr->FirstWindowRegion) return; 2529645f5050Syouri we = (WindowEntry*) 0; 2530645f5050Syouri for (wl = Scr->workSpaceMgr.workSpaceList; wl != NULL; wl = wl->next) { 2531645f5050Syouri we = findWindowEntry (wl, tmp_win, &wr); 2532645f5050Syouri if (we) break; 2533645f5050Syouri } 2534645f5050Syouri if (!we) return; 2535645f5050Syouri 2536645f5050Syouri we->twm_win = 0; 2537645f5050Syouri we->used = 0; 2538645f5050Syouri wp = prevWindowEntry (we, wr); 2539645f5050Syouri wn = we->next; 2540645f5050Syouri for (;;) { 2541645f5050Syouri if (wp && wp->used == 0 && 2542645f5050Syouri ((wp->x == we->x && wp->w == we->w) || 2543645f5050Syouri (wp->y == we->y && wp->h == we->h))) { 2544645f5050Syouri wp->next = we->next; 2545645f5050Syouri mergeWindowEntries (we, wp); 2546645f5050Syouri free ((char *) we); 2547645f5050Syouri we = wp; 2548645f5050Syouri wp = prevWindowEntry (wp, wr); 2549645f5050Syouri } else 2550645f5050Syouri if (wn && wn->used == 0 && 2551645f5050Syouri ((wn->x == we->x && wn->w == we->w) || 2552645f5050Syouri (wn->y == we->y && wn->h == we->h))) { 2553645f5050Syouri we->next = wn->next; 2554645f5050Syouri mergeWindowEntries (wn, we); 2555645f5050Syouri free ((char *) wn); 2556645f5050Syouri wn = we->next; 2557645f5050Syouri } else break; 2558645f5050Syouri } 2559645f5050Syouri} 2560645f5050Syouri 2561645f5050Syouri/* 2562645f5050Syouri * This is largely for Xinerama support with VirtualScreens. 2563645f5050Syouri * In this case, windows may be on something other then the main screen 2564645f5050Syouri * on startup, or the mapping may be relative to the right side of the 2565645f5050Syouri * screen, which is on a different monitor, which will cause issues with 2566645f5050Syouri * the virtual screens. 2567645f5050Syouri * 2568645f5050Syouri * It probably needs to be congnizant of windows that are actually owned by 2569645f5050Syouri * other workspaces, and ignore them (this needs to be revisited), or perhaps 2570645f5050Syouri * that functionality is appropriate in AddWindow(). This needs to be dug into 2571645f5050Syouri * more deply. 2572645f5050Syouri * 2573645f5050Syouri * this approach assumes screens that are next to each other horizontally, 2574645f5050Syouri * Other possibilities need to be investigated and accounted for. 2575645f5050Syouri */ 2576645f5050Syourivoid DealWithNonSensicalGeometries(Display *mydpy, Window vroot, TwmWindow *tmp_win) 2577645f5050Syouri{ 2578645f5050Syouri Window vvroot; 2579645f5050Syouri int x,y; 2580645f5050Syouri unsigned int w,h; 2581645f5050Syouri unsigned int j; 2582645f5050Syouri virtualScreen *myvs, *vs; 2583645f5050Syouri int dropx = 0; 2584645f5050Syouri 2585645f5050Syouri if(! vroot) 2586645f5050Syouri return; 2587645f5050Syouri 2588645f5050Syouri if(!(XGetGeometry(mydpy, vroot, &vvroot, &x, &y, &w, &h, &j, &j))) 2589645f5050Syouri return; 2590645f5050Syouri 2591645f5050Syouri myvs = findIfVScreenOf(x, y); 2592645f5050Syouri 2593645f5050Syouri /* 2594645f5050Syouri * probably need to rethink this for unmapped vs's. ugh. 2595645f5050Syouri */ 2596645f5050Syouri if(!myvs) 2597645f5050Syouri return; 2598645f5050Syouri 2599645f5050Syouri for(vs = myvs->next; vs; vs = vs->next) { 2600645f5050Syouri dropx += vs->w; 2601645f5050Syouri } 2602645f5050Syouri 2603645f5050Syouri for(vs = Scr->vScreenList; vs && vs != myvs; vs = vs->next) { 2604645f5050Syouri dropx -= vs->w; 2605645f5050Syouri } 2606645f5050Syouri 2607645f5050Syouri if(tmp_win->frame_x > 0 && tmp_win->frame_x >= w) { 2608645f5050Syouri tmp_win->frame_x -= abs(dropx); 2609645f5050Syouri } else { 2610645f5050Syouri} 2611645f5050Syouri 2612645f5050Syouri} 2613