icons.c revision 645f5050
1645f5050Syouri/* 2645f5050Syouri * Copyright 1989 Massachusetts Institute of Technology 3645f5050Syouri * 4645f5050Syouri * Permission to use, copy, modify, and distribute this software and its 5645f5050Syouri * documentation for any purpose and without fee is hereby granted, provided 6645f5050Syouri * that the above copyright notice appear in all copies and that both that 7645f5050Syouri * copyright notice and this permission notice appear in supporting 8645f5050Syouri * documentation, and that the name of M.I.T. not be used in advertising 9645f5050Syouri * or publicity pertaining to distribution of the software without specific, 10645f5050Syouri * written prior permission. M.I.T. makes no representations about the 11645f5050Syouri * suitability of this software for any purpose. It is provided "as is" 12645f5050Syouri * without express or implied warranty. 13645f5050Syouri * 14645f5050Syouri * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 15645f5050Syouri * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. 16645f5050Syouri * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17645f5050Syouri * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 18645f5050Syouri * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 19645f5050Syouri * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20645f5050Syouri */ 21645f5050Syouri/* 22645f5050Syouri * [ ctwm ] 23645f5050Syouri * 24645f5050Syouri * Copyright 1992 Claude Lecommandeur. 25645f5050Syouri * 26645f5050Syouri * Permission to use, copy, modify and distribute this software [ctwm] and 27645f5050Syouri * its documentation for any purpose is hereby granted without fee, provided 28645f5050Syouri * that the above copyright notice appear in all copies and that both that 29645f5050Syouri * copyright notice and this permission notice appear in supporting documen- 30645f5050Syouri * tation, and that the name of Claude Lecommandeur not be used in adverti- 31645f5050Syouri * sing or publicity pertaining to distribution of the software without 32645f5050Syouri * specific, written prior permission. Claude Lecommandeur make no represen- 33645f5050Syouri * tations about the suitability of this software for any purpose. It is 34645f5050Syouri * provided "as is" without express or implied warranty. 35645f5050Syouri * 36645f5050Syouri * Claude Lecommandeur DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 37645f5050Syouri * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 38645f5050Syouri * EVENT SHALL Claude Lecommandeur BE LIABLE FOR ANY SPECIAL, INDIRECT OR 39645f5050Syouri * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 40645f5050Syouri * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 41645f5050Syouri * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 42645f5050Syouri * PERFORMANCE OF THIS SOFTWARE. 43645f5050Syouri * 44645f5050Syouri * Author: Claude Lecommandeur [ lecom@sic.epfl.ch ][ April 1992 ] 45645f5050Syouri */ 46645f5050Syouri 47645f5050Syouri/********************************************************************** 48645f5050Syouri * 49645f5050Syouri * $XConsortium: icons.c,v 1.22 91/07/12 09:58:38 dave Exp $ 50645f5050Syouri * 51645f5050Syouri * Icon releated routines 52645f5050Syouri * 53645f5050Syouri * 10-Apr-89 Tom LaStrange Initial Version. 54645f5050Syouri * 55645f5050Syouri * Do the necessary modification to be integrated in ctwm. 56645f5050Syouri * Can no longer be used for the standard twm. 57645f5050Syouri * 58645f5050Syouri * 22-April-92 Claude Lecommandeur. 59645f5050Syouri * 60645f5050Syouri * 61645f5050Syouri **********************************************************************/ 62645f5050Syouri 63645f5050Syouri#include <stdio.h> 64645f5050Syouri#include "twm.h" 65645f5050Syouri#include "screen.h" 66645f5050Syouri#include "icons.h" 67645f5050Syouri#include "list.h" 68645f5050Syouri#include "parse.h" 69645f5050Syouri#include "util.h" 70645f5050Syouri 71645f5050Syouriextern void twmrc_error_prefix(void); 72645f5050Syouriextern Bool AnimationPending; 73645f5050Syouriextern Bool AnimationActive; 74645f5050Syouriextern Bool MaybeAnimate; 75645f5050Syouri 76645f5050Syouri#define iconWidth(w) (w->icon->border_width * 2 + \ 77645f5050Syouri Scr->ShrinkIconTitles ? w->icon->width : w->icon->w_width) 78645f5050Syouri#define iconHeight(w) (w->icon->border_width * 2 + w->icon->w_height) 79645f5050Syouri 80645f5050Syouristatic void splitEntry (IconEntry *ie, int grav1, int grav2, int w, int h) 81645f5050Syouri{ 82645f5050Syouri IconEntry *new; 83645f5050Syouri 84645f5050Syouri switch (grav1) { 85645f5050Syouri case D_NORTH: 86645f5050Syouri case D_SOUTH: 87645f5050Syouri if (w != ie->w) 88645f5050Syouri splitEntry (ie, grav2, grav1, w, ie->h); 89645f5050Syouri if (h != ie->h) { 90645f5050Syouri new = (IconEntry *)malloc (sizeof (IconEntry)); 91645f5050Syouri new->twm_win = 0; 92645f5050Syouri new->used = 0; 93645f5050Syouri new->next = ie->next; 94645f5050Syouri ie->next = new; 95645f5050Syouri new->x = ie->x; 96645f5050Syouri new->h = (ie->h - h); 97645f5050Syouri new->w = ie->w; 98645f5050Syouri ie->h = h; 99645f5050Syouri if (grav1 == D_SOUTH) { 100645f5050Syouri new->y = ie->y; 101645f5050Syouri ie->y = new->y + new->h; 102645f5050Syouri } else 103645f5050Syouri new->y = ie->y + ie->h; 104645f5050Syouri } 105645f5050Syouri break; 106645f5050Syouri case D_EAST: 107645f5050Syouri case D_WEST: 108645f5050Syouri if (h != ie->h) 109645f5050Syouri splitEntry (ie, grav2, grav1, ie->w, h); 110645f5050Syouri if (w != ie->w) { 111645f5050Syouri new = (IconEntry *)malloc (sizeof (IconEntry)); 112645f5050Syouri new->twm_win = 0; 113645f5050Syouri new->used = 0; 114645f5050Syouri new->next = ie->next; 115645f5050Syouri ie->next = new; 116645f5050Syouri new->y = ie->y; 117645f5050Syouri new->w = (ie->w - w); 118645f5050Syouri new->h = ie->h; 119645f5050Syouri ie->w = w; 120645f5050Syouri if (grav1 == D_EAST) { 121645f5050Syouri new->x = ie->x; 122645f5050Syouri ie->x = new->x + new->w; 123645f5050Syouri } else 124645f5050Syouri new->x = ie->x + ie->w; 125645f5050Syouri } 126645f5050Syouri break; 127645f5050Syouri } 128645f5050Syouri} 129645f5050Syouri 130645f5050Syouristatic int roundUp (int v, int multiple) 131645f5050Syouri{ 132645f5050Syouri return ((v + multiple - 1) / multiple) * multiple; 133645f5050Syouri} 134645f5050Syouri 135645f5050Syouristatic void PlaceIcon(TwmWindow *tmp_win, int def_x, int def_y, 136645f5050Syouri int *final_x, int *final_y) 137645f5050Syouri{ 138645f5050Syouri IconRegion *ir, *oldir; 139645f5050Syouri IconEntry *ie; 140645f5050Syouri int w = 0, h = 0; 141645f5050Syouri 142645f5050Syouri /* 143645f5050Syouri * First, check to see if the window is in a region's client list 144645f5050Syouri */ 145645f5050Syouri ie = 0; 146645f5050Syouri for (ir = Scr->FirstRegion; ir; ir = ir->next) { 147645f5050Syouri if (LookInList(ir->clientlist, tmp_win->full_name, &tmp_win->class)) 148645f5050Syouri { 149645f5050Syouri w = roundUp (iconWidth (tmp_win), ir->stepx); 150645f5050Syouri h = roundUp (iconHeight (tmp_win), ir->stepy); 151645f5050Syouri for (ie = ir->entries; ie; ie=ie->next) { 152645f5050Syouri if (ie->used) 153645f5050Syouri continue; 154645f5050Syouri if (ie->w >= w && ie->h >= h) 155645f5050Syouri break; 156645f5050Syouri } 157645f5050Syouri if (ie) 158645f5050Syouri break; 159645f5050Syouri } 160645f5050Syouri } 161645f5050Syouri 162645f5050Syouri /* 163645f5050Syouri * If not found in any region's client list, place anywhere 164645f5050Syouri */ 165645f5050Syouri if (!ie) 166645f5050Syouri { 167645f5050Syouri for (ir = Scr->FirstRegion; ir; ir = ir->next) { 168645f5050Syouri w = roundUp (iconWidth (tmp_win), ir->stepx); 169645f5050Syouri h = roundUp (iconHeight (tmp_win), ir->stepy); 170645f5050Syouri for (ie = ir->entries; ie; ie=ie->next) { 171645f5050Syouri if (ie->used) 172645f5050Syouri continue; 173645f5050Syouri if (ie->w >= w && ie->h >= h) 174645f5050Syouri break; 175645f5050Syouri } 176645f5050Syouri if (ie) 177645f5050Syouri break; 178645f5050Syouri } 179645f5050Syouri } 180645f5050Syouri oldir = tmp_win->icon->ir; 181645f5050Syouri if (ie) { 182645f5050Syouri splitEntry (ie, ir->grav1, ir->grav2, w, h); 183645f5050Syouri ie->used = 1; 184645f5050Syouri ie->twm_win = tmp_win; 185645f5050Syouri switch (ir->Justification) { 186645f5050Syouri case J_LEFT : 187645f5050Syouri *final_x = ie->x; 188645f5050Syouri break; 189645f5050Syouri case J_UNDEF : 190645f5050Syouri case J_CENTER : 191645f5050Syouri *final_x = ie->x + (ie->w - iconWidth (tmp_win)) / 2; 192645f5050Syouri break; 193645f5050Syouri case J_RIGHT : 194645f5050Syouri *final_x = ie->x + ie->w - iconWidth (tmp_win); 195645f5050Syouri break; 196645f5050Syouri case J_BORDER : 197645f5050Syouri if (ir->grav2 == D_EAST) 198645f5050Syouri *final_x = ie->x + ie->w - iconWidth (tmp_win); 199645f5050Syouri else 200645f5050Syouri *final_x = ie->x; 201645f5050Syouri break; 202645f5050Syouri } 203645f5050Syouri switch (ir->Alignement) { 204645f5050Syouri case J_TOP : 205645f5050Syouri *final_y = ie->y; 206645f5050Syouri break; 207645f5050Syouri case J_UNDEF : 208645f5050Syouri case J_CENTER : 209645f5050Syouri *final_y = ie->y + (ie->h - iconHeight (tmp_win)) / 2; 210645f5050Syouri break; 211645f5050Syouri case J_BOTTOM : 212645f5050Syouri *final_y = ie->y + ie->h - iconHeight (tmp_win); 213645f5050Syouri break; 214645f5050Syouri case J_BORDER : 215645f5050Syouri if (ir->grav1 == D_SOUTH) 216645f5050Syouri *final_y = ie->y + ie->h - iconHeight (tmp_win); 217645f5050Syouri else 218645f5050Syouri *final_y = ie->y; 219645f5050Syouri break; 220645f5050Syouri } 221645f5050Syouri tmp_win->icon->ir = ir; 222645f5050Syouri } else { 223645f5050Syouri *final_x = def_x; 224645f5050Syouri *final_y = def_y; 225645f5050Syouri tmp_win->icon->ir = (IconRegion*)0; 226645f5050Syouri return; 227645f5050Syouri } 228645f5050Syouri if (Scr->ShrinkIconTitles && tmp_win->icon->has_title) { 229645f5050Syouri *final_x -= GetIconOffset (tmp_win->icon); 230645f5050Syouri if (tmp_win->icon->ir != oldir) ReshapeIcon (tmp_win->icon); 231645f5050Syouri } 232645f5050Syouri return; 233645f5050Syouri} 234645f5050Syouri 235645f5050Syouristatic IconEntry *FindIconEntry (TwmWindow *tmp_win, IconRegion **irp) 236645f5050Syouri{ 237645f5050Syouri IconRegion *ir; 238645f5050Syouri IconEntry *ie; 239645f5050Syouri 240645f5050Syouri for (ir = Scr->FirstRegion; ir; ir = ir->next) { 241645f5050Syouri for (ie = ir->entries; ie; ie=ie->next) 242645f5050Syouri if (ie->twm_win == tmp_win) { 243645f5050Syouri if (irp) 244645f5050Syouri *irp = ir; 245645f5050Syouri return ie; 246645f5050Syouri } 247645f5050Syouri } 248645f5050Syouri return 0; 249645f5050Syouri} 250645f5050Syouri 251645f5050Syouriint IconUp (TwmWindow *tmp_win) 252645f5050Syouri{ 253645f5050Syouri int x, y; 254645f5050Syouri int defx, defy; 255645f5050Syouri struct IconRegion *ir; 256645f5050Syouri 257645f5050Syouri /* 258645f5050Syouri * If the client specified a particular location, let's use it (this might 259645f5050Syouri * want to be an option at some point). Otherwise, try to fit within the 260645f5050Syouri * icon region. 261645f5050Syouri */ 262645f5050Syouri if (tmp_win->wmhints && (tmp_win->wmhints->flags & IconPositionHint)) 263645f5050Syouri return (0); 264645f5050Syouri 265645f5050Syouri if (tmp_win->icon_moved) { 266645f5050Syouri if (!XGetGeometry (dpy, tmp_win->icon->w, &JunkRoot, &defx, &defy, 267645f5050Syouri &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth)) 268645f5050Syouri return (1); 269645f5050Syouri 270645f5050Syouri x = defx + ((int) JunkWidth) / 2; 271645f5050Syouri y = defy + ((int) JunkHeight) / 2; 272645f5050Syouri 273645f5050Syouri for (ir = Scr->FirstRegion; ir; ir = ir->next) { 274645f5050Syouri if (x >= ir->x && x < (ir->x + ir->w) && 275645f5050Syouri y >= ir->y && y < (ir->y + ir->h)) 276645f5050Syouri break; 277645f5050Syouri } 278645f5050Syouri if (!ir) return (0); /* outside icon regions, leave alone */ 279645f5050Syouri } 280645f5050Syouri 281645f5050Syouri defx = -100; 282645f5050Syouri defy = -100; 283645f5050Syouri PlaceIcon(tmp_win, defx, defy, &x, &y); 284645f5050Syouri if (x != defx || y != defy) { 285645f5050Syouri XMoveWindow (dpy, tmp_win->icon->w, x, y); 286645f5050Syouri tmp_win->icon_moved = FALSE; /* since we've restored it */ 287645f5050Syouri } 288645f5050Syouri MaybeAnimate = True; 289645f5050Syouri return (0); 290645f5050Syouri} 291645f5050Syouri 292645f5050Syouristatic IconEntry *prevIconEntry (IconEntry *ie, IconRegion *ir) 293645f5050Syouri{ 294645f5050Syouri IconEntry *ip; 295645f5050Syouri 296645f5050Syouri if (ie == ir->entries) 297645f5050Syouri return 0; 298645f5050Syouri for (ip = ir->entries; ip->next != ie; ip=ip->next) 299645f5050Syouri ; 300645f5050Syouri return ip; 301645f5050Syouri} 302645f5050Syouri 303645f5050Syouri/* old is being freed; and is adjacent to ie. Merge 304645f5050Syouri * regions together 305645f5050Syouri */ 306645f5050Syouri 307645f5050Syouristatic void mergeEntries (IconEntry *old, IconEntry *ie) 308645f5050Syouri{ 309645f5050Syouri if (old->y == ie->y) { 310645f5050Syouri ie->w = old->w + ie->w; 311645f5050Syouri if (old->x < ie->x) 312645f5050Syouri ie->x = old->x; 313645f5050Syouri } else { 314645f5050Syouri ie->h = old->h + ie->h; 315645f5050Syouri if (old->y < ie->y) 316645f5050Syouri ie->y = old->y; 317645f5050Syouri } 318645f5050Syouri} 319645f5050Syouri 320645f5050Syourivoid IconDown (TwmWindow *tmp_win) 321645f5050Syouri{ 322645f5050Syouri IconEntry *ie, *ip, *in; 323645f5050Syouri IconRegion *ir; 324645f5050Syouri 325645f5050Syouri ie = FindIconEntry (tmp_win, &ir); 326645f5050Syouri if (ie) { 327645f5050Syouri ie->twm_win = 0; 328645f5050Syouri ie->used = 0; 329645f5050Syouri ip = prevIconEntry (ie, ir); 330645f5050Syouri in = ie->next; 331645f5050Syouri for (;;) { 332645f5050Syouri if (ip && ip->used == 0 && 333645f5050Syouri ((ip->x == ie->x && ip->w == ie->w) || 334645f5050Syouri (ip->y == ie->y && ip->h == ie->h))) 335645f5050Syouri { 336645f5050Syouri ip->next = ie->next; 337645f5050Syouri mergeEntries (ie, ip); 338645f5050Syouri free ((char *) ie); 339645f5050Syouri ie = ip; 340645f5050Syouri ip = prevIconEntry (ip, ir); 341645f5050Syouri } else if (in && in->used == 0 && 342645f5050Syouri ((in->x == ie->x && in->w == ie->w) || 343645f5050Syouri (in->y == ie->y && in->h == ie->h))) 344645f5050Syouri { 345645f5050Syouri ie->next = in->next; 346645f5050Syouri mergeEntries (in, ie); 347645f5050Syouri free ((char *) in); 348645f5050Syouri in = ie->next; 349645f5050Syouri } else 350645f5050Syouri break; 351645f5050Syouri } 352645f5050Syouri } 353645f5050Syouri} 354645f5050Syouri 355645f5050Syouriname_list **AddIconRegion(char *geom, 356645f5050Syouri int grav1, int grav2, 357645f5050Syouri int stepx, int stepy, 358645f5050Syouri char *ijust, char *just, char *align) 359645f5050Syouri{ 360645f5050Syouri IconRegion *ir; 361645f5050Syouri int mask, tmp; 362645f5050Syouri 363645f5050Syouri ir = (IconRegion *)malloc(sizeof(IconRegion)); 364645f5050Syouri ir->next = NULL; 365645f5050Syouri 366645f5050Syouri if (Scr->LastRegion) Scr->LastRegion->next = ir; 367645f5050Syouri Scr->LastRegion = ir; 368645f5050Syouri if (!Scr->FirstRegion) Scr->FirstRegion = ir; 369645f5050Syouri 370645f5050Syouri ir->entries = NULL; 371645f5050Syouri ir->clientlist = NULL; 372645f5050Syouri ir->grav1 = grav1; 373645f5050Syouri ir->grav2 = grav2; 374645f5050Syouri if (stepx <= 0) 375645f5050Syouri stepx = 1; 376645f5050Syouri if (stepy <= 0) 377645f5050Syouri stepy = 1; 378645f5050Syouri ir->stepx = stepx; 379645f5050Syouri ir->stepy = stepy; 380645f5050Syouri ir->x = ir->y = ir->w = ir->h = 0; 381645f5050Syouri 382645f5050Syouri mask = XParseGeometry(geom, &ir->x, &ir->y, (unsigned int *)&ir->w, (unsigned int *)&ir->h); 383645f5050Syouri 384645f5050Syouri if (mask & XNegative) ir->x += Scr->rootw - ir->w; 385645f5050Syouri if (mask & YNegative) ir->y += Scr->rooth - ir->h; 386645f5050Syouri 387645f5050Syouri ir->entries = (IconEntry *)malloc(sizeof(IconEntry)); 388645f5050Syouri ir->entries->next = 0; 389645f5050Syouri ir->entries->x = ir->x; 390645f5050Syouri ir->entries->y = ir->y; 391645f5050Syouri ir->entries->w = ir->w; 392645f5050Syouri ir->entries->h = ir->h; 393645f5050Syouri ir->entries->twm_win = 0; 394645f5050Syouri ir->entries->used = 0; 395645f5050Syouri 396645f5050Syouri tmp = ParseJustification (ijust); 397645f5050Syouri if ((tmp < 0) || (tmp == J_BORDER)) { 398645f5050Syouri twmrc_error_prefix(); 399645f5050Syouri fprintf (stderr, "ignoring invalid IconRegion argument \"%s\"\n", ijust); 400645f5050Syouri tmp = J_UNDEF; 401645f5050Syouri } 402645f5050Syouri ir->TitleJustification = tmp; 403645f5050Syouri 404645f5050Syouri tmp = ParseJustification (just); 405645f5050Syouri if ((tmp = ParseJustification (just)) < 0) { 406645f5050Syouri twmrc_error_prefix(); 407645f5050Syouri fprintf (stderr, "ignoring invalid IconRegion argument \"%s\"\n", just); 408645f5050Syouri tmp = J_UNDEF; 409645f5050Syouri } 410645f5050Syouri ir->Justification = tmp; 411645f5050Syouri 412645f5050Syouri if ((tmp = ParseAlignement (align)) < 0) { 413645f5050Syouri twmrc_error_prefix(); 414645f5050Syouri fprintf (stderr, "ignoring invalid IconRegion argument \"%s\"\n", align); 415645f5050Syouri tmp = J_UNDEF; 416645f5050Syouri } 417645f5050Syouri ir->Alignement = tmp; 418645f5050Syouri 419645f5050Syouri return(&(ir->clientlist)); 420645f5050Syouri} 421645f5050Syouri 422645f5050Syouri#ifdef comment 423645f5050SyouriFreeIconEntries (ir) 424645f5050Syouri IconRegion *ir; 425645f5050Syouri{ 426645f5050Syouri IconEntry *ie, *tmp; 427645f5050Syouri 428645f5050Syouri for (ie = ir->entries; ie; ie=tmp) 429645f5050Syouri { 430645f5050Syouri tmp = ie->next; 431645f5050Syouri free ((char *) ie); 432645f5050Syouri } 433645f5050Syouri} 434645f5050SyouriFreeIconRegions() 435645f5050Syouri{ 436645f5050Syouri IconRegion *ir, *tmp; 437645f5050Syouri 438645f5050Syouri for (ir = Scr->FirstRegion; ir != NULL;) 439645f5050Syouri { 440645f5050Syouri tmp = ir; 441645f5050Syouri FreeIconEntries (ir); 442645f5050Syouri ir = ir->next; 443645f5050Syouri free((char *) tmp); 444645f5050Syouri } 445645f5050Syouri Scr->FirstRegion = NULL; 446645f5050Syouri Scr->LastRegion = NULL; 447645f5050Syouri} 448645f5050Syouri#endif 449645f5050Syouri 450645f5050Syouriint CreateIconWindow(TwmWindow *tmp_win, int def_x, int def_y) 451645f5050Syouri{ 452645f5050Syouri unsigned long event_mask; 453645f5050Syouri unsigned long valuemask; /* mask for create windows */ 454645f5050Syouri XSetWindowAttributes attributes; /* attributes for create windows */ 455645f5050Syouri int final_x, final_y; 456645f5050Syouri int x; 457645f5050Syouri Icon *icon; 458645f5050Syouri Image *image = None; 459645f5050Syouri 460645f5050Syouri icon = (Icon*) malloc (sizeof (struct Icon)); 461645f5050Syouri 462645f5050Syouri icon->border = Scr->IconBorderColor; 463645f5050Syouri icon->iconc.fore = Scr->IconC.fore; 464645f5050Syouri icon->iconc.back = Scr->IconC.back; 465645f5050Syouri 466645f5050Syouri GetColorFromList(Scr->IconBorderColorL, tmp_win->full_name, &tmp_win->class, 467645f5050Syouri &icon->border); 468645f5050Syouri GetColorFromList(Scr->IconForegroundL, tmp_win->full_name, &tmp_win->class, 469645f5050Syouri &icon->iconc.fore); 470645f5050Syouri GetColorFromList(Scr->IconBackgroundL, tmp_win->full_name, &tmp_win->class, 471645f5050Syouri &icon->iconc.back); 472645f5050Syouri if (Scr->use3Diconmanagers && !Scr->BeNiceToColormap) GetShadeColors (&icon->iconc); 473645f5050Syouri 474645f5050Syouri FB(icon->iconc.fore, icon->iconc.back); 475645f5050Syouri 476645f5050Syouri icon->match = match_none; 477645f5050Syouri icon->pattern = NULL; 478645f5050Syouri icon->image = None; 479645f5050Syouri icon->ir = (IconRegion*) 0; 480645f5050Syouri 481645f5050Syouri tmp_win->forced = FALSE; 482645f5050Syouri tmp_win->icon_not_ours = FALSE; 483645f5050Syouri 484645f5050Syouri /* now go through the steps to get an icon window, if ForceIcon is 485645f5050Syouri * set, then no matter what else is defined, the bitmap from the 486645f5050Syouri * .twmrc file is used 487645f5050Syouri */ 488645f5050Syouri if (Scr->ForceIcon) { 489645f5050Syouri char *icon_name; 490645f5050Syouri 491645f5050Syouri icon_name = LookInNameList (Scr->IconNames, tmp_win->icon_name); 492645f5050Syouri if (icon_name != NULL) { 493645f5050Syouri icon->pattern = LookPatternInNameList (Scr->IconNames, tmp_win->icon_name); 494645f5050Syouri icon->match = match_icon; 495645f5050Syouri } 496645f5050Syouri if (icon->match == match_none) 497645f5050Syouri icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name); 498645f5050Syouri if ((icon->match == match_none) && (icon_name != NULL)) { 499645f5050Syouri icon->pattern = LookPatternInNameList (Scr->IconNames, tmp_win->full_name); 500645f5050Syouri icon->match = match_name; 501645f5050Syouri } 502645f5050Syouri if (icon->match == match_none) 503645f5050Syouri icon_name = LookInList(Scr->IconNames, tmp_win->full_name, &tmp_win->class); 504645f5050Syouri if ((icon->match == match_none) && (icon_name != NULL)) { 505645f5050Syouri icon->pattern = LookPatternInList (Scr->IconNames, tmp_win->full_name, &tmp_win->class); 506645f5050Syouri icon->match = match_class; 507645f5050Syouri } 508645f5050Syouri if ((image = GetImage (icon_name, icon->iconc)) != None) { 509645f5050Syouri icon->image = image; 510645f5050Syouri icon->width = image->width; 511645f5050Syouri icon->height = image->height; 512645f5050Syouri tmp_win->forced = TRUE; 513645f5050Syouri } 514645f5050Syouri } 515645f5050Syouri 516645f5050Syouri /* if the pixmap is still NULL, we didn't get one from the above code, 517645f5050Syouri * that could mean that ForceIcon was not set, or that the window 518645f5050Syouri * was not in the Icons list, now check the WM hints for an icon 519645f5050Syouri */ 520645f5050Syouri if (image == None && tmp_win->wmhints && 521645f5050Syouri tmp_win->wmhints->flags & IconPixmapHint) { 522645f5050Syouri if (XGetGeometry(dpy, tmp_win->wmhints->icon_pixmap, 523645f5050Syouri &JunkRoot, &JunkX, &JunkY, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth)) { 524645f5050Syouri image = (Image*) malloc (sizeof (struct _Image)); 525645f5050Syouri image->width = JunkWidth; 526645f5050Syouri image->height = JunkHeight; 527645f5050Syouri image->pixmap = XCreatePixmap (dpy, Scr->Root, image->width, 528645f5050Syouri image->height, Scr->d_depth); 529645f5050Syouri image->mask = None; 530645f5050Syouri image->next = None; 531645f5050Syouri if (JunkDepth == Scr->d_depth) 532645f5050Syouri XCopyArea (dpy, tmp_win->wmhints->icon_pixmap, image->pixmap, Scr->NormalGC, 533645f5050Syouri 0, 0, image->width, image->height, 0, 0); 534645f5050Syouri else 535645f5050Syouri XCopyPlane (dpy, tmp_win->wmhints->icon_pixmap, image->pixmap, Scr->NormalGC, 536645f5050Syouri 0, 0, image->width, image->height, 0, 0, 1 ); 537645f5050Syouri 538645f5050Syouri icon->width = image->width; 539645f5050Syouri icon->height = image->height; 540645f5050Syouri 541645f5050Syouri if ((tmp_win->wmhints->flags & IconMaskHint) && 542645f5050Syouri XGetGeometry(dpy, tmp_win->wmhints->icon_mask, 543645f5050Syouri &JunkRoot, &JunkX, &JunkY, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) && 544645f5050Syouri (JunkDepth == 1)) { 545645f5050Syouri GC gc; 546645f5050Syouri 547645f5050Syouri image->mask = XCreatePixmap (dpy, Scr->Root, JunkWidth, JunkHeight, 1); 548645f5050Syouri if (image->mask) { 549645f5050Syouri gc = XCreateGC (dpy, image->mask, 0, NULL); 550645f5050Syouri if (gc) { 551645f5050Syouri XCopyArea (dpy, tmp_win->wmhints->icon_mask, image->mask, gc, 552645f5050Syouri 0, 0, JunkWidth, JunkHeight, 0, 0); 553645f5050Syouri XFreeGC (dpy, gc); 554645f5050Syouri } 555645f5050Syouri } 556645f5050Syouri } 557645f5050Syouri icon->image = image; 558645f5050Syouri } 559645f5050Syouri } 560645f5050Syouri 561645f5050Syouri /* if we still haven't got an icon, let's look in the Icon list 562645f5050Syouri * if ForceIcon is not set 563645f5050Syouri */ 564645f5050Syouri if (image == None && !Scr->ForceIcon) { 565645f5050Syouri char *icon_name; 566645f5050Syouri 567645f5050Syouri icon->match = match_none; 568645f5050Syouri icon->pattern = NULL; 569645f5050Syouri icon_name = LookInNameList(Scr->IconNames, tmp_win->icon_name); 570645f5050Syouri if (icon_name != NULL) { 571645f5050Syouri icon->pattern = LookPatternInNameList (Scr->IconNames, tmp_win->icon_name); 572645f5050Syouri icon->match = match_icon; 573645f5050Syouri } 574645f5050Syouri if (icon->match == match_none) 575645f5050Syouri icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name); 576645f5050Syouri if ((icon->match == match_none) && (icon_name != NULL)) { 577645f5050Syouri icon->pattern = LookPatternInNameList (Scr->IconNames, tmp_win->full_name); 578645f5050Syouri icon->match = match_name; 579645f5050Syouri } 580645f5050Syouri if (icon->match == match_none) 581645f5050Syouri icon_name = LookInList(Scr->IconNames, tmp_win->full_name, &tmp_win->class); 582645f5050Syouri if ((icon->match == match_none) && (icon_name != NULL)) { 583645f5050Syouri icon->pattern = LookPatternInList (Scr->IconNames, 584645f5050Syouri tmp_win->full_name, &tmp_win->class); 585645f5050Syouri icon->match = match_class; 586645f5050Syouri } 587645f5050Syouri if ((image = GetImage (icon_name, icon->iconc)) != None) { 588645f5050Syouri icon->image = image; 589645f5050Syouri icon->width = image->width; 590645f5050Syouri icon->height = image->height; 591645f5050Syouri tmp_win->forced = TRUE; 592645f5050Syouri } 593645f5050Syouri } 594645f5050Syouri 595645f5050Syouri /* if we still don't have an icon, assign the UnknownIcon */ 596645f5050Syouri if (image == None && Scr->UnknownImage != None) 597645f5050Syouri { 598645f5050Syouri image = Scr->UnknownImage; 599645f5050Syouri icon->width = image->width; 600645f5050Syouri icon->height = image->height; 601645f5050Syouri icon->image = image; 602645f5050Syouri } 603645f5050Syouri 604645f5050Syouri if (image == None) 605645f5050Syouri { 606645f5050Syouri icon->height = 0; 607645f5050Syouri icon->width = 0; 608645f5050Syouri valuemask = 0; 609645f5050Syouri } 610645f5050Syouri else 611645f5050Syouri { 612645f5050Syouri valuemask = CWBackPixmap; 613645f5050Syouri attributes.background_pixmap = image->pixmap; 614645f5050Syouri } 615645f5050Syouri 616645f5050Syouri icon->border_width = Scr->IconBorderWidth; 617645f5050Syouri if (Scr->NoIconTitlebar || 618645f5050Syouri LookInNameList (Scr->NoIconTitle, tmp_win->icon_name) || 619645f5050Syouri LookInList (Scr->NoIconTitle, tmp_win->full_name, &tmp_win->class)) 620645f5050Syouri { 621645f5050Syouri icon->w_width = icon->width; 622645f5050Syouri icon->w_height = icon->height; 623645f5050Syouri icon->x = 0; 624645f5050Syouri icon->y = 0; 625645f5050Syouri icon->has_title = False; 626645f5050Syouri } 627645f5050Syouri else { 628645f5050Syouri XRectangle inc_rect; 629645f5050Syouri XRectangle logical_rect; 630645f5050Syouri 631645f5050Syouri XmbTextExtents(Scr->IconFont.font_set, 632645f5050Syouri tmp_win->icon_name, strlen (tmp_win->icon_name), 633645f5050Syouri &inc_rect, &logical_rect); 634645f5050Syouri icon->w_width = logical_rect.width; 635645f5050Syouri 636645f5050Syouri icon->w_width += 2 * Scr->IconManagerShadowDepth + 6; 637645f5050Syouri if (icon->w_width > Scr->MaxIconTitleWidth) icon->w_width = Scr->MaxIconTitleWidth; 638645f5050Syouri if (icon->w_width < icon->width) 639645f5050Syouri { 640645f5050Syouri icon->x = (icon->width - icon->w_width) / 2; 641645f5050Syouri icon->x += Scr->IconManagerShadowDepth + 3; 642645f5050Syouri icon->w_width = icon->width; 643645f5050Syouri } 644645f5050Syouri else 645645f5050Syouri { 646645f5050Syouri icon->x = Scr->IconManagerShadowDepth + 3; 647645f5050Syouri } 648645f5050Syouri icon->y = icon->height + Scr->IconFont.height + Scr->IconManagerShadowDepth; 649645f5050Syouri icon->w_height = icon->height + Scr->IconFont.height + 650645f5050Syouri 2 * Scr->IconManagerShadowDepth + 6; 651645f5050Syouri icon->has_title = True; 652645f5050Syouri if (icon->height) icon->border_width = 0; 653645f5050Syouri } 654645f5050Syouri 655645f5050Syouri event_mask = 0; 656645f5050Syouri if (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint) 657645f5050Syouri { 658645f5050Syouri icon->w = tmp_win->wmhints->icon_window; 659645f5050Syouri if (tmp_win->forced || 660645f5050Syouri XGetGeometry(dpy, icon->w, &JunkRoot, &JunkX, &JunkY, 661645f5050Syouri (unsigned int *)&icon->w_width, (unsigned int *)&icon->w_height, 662645f5050Syouri &JunkBW, &JunkDepth) == 0) 663645f5050Syouri { 664645f5050Syouri icon->w = None; 665645f5050Syouri tmp_win->wmhints->flags &= ~IconWindowHint; 666645f5050Syouri } 667645f5050Syouri else 668645f5050Syouri { 669645f5050Syouri tmp_win->icon_not_ours = TRUE; 670645f5050Syouri image = None; 671645f5050Syouri icon->width = icon->w_width; 672645f5050Syouri icon->height = icon->w_height; 673645f5050Syouri icon->image = image; 674645f5050Syouri icon->has_title = False; 675645f5050Syouri event_mask = 0; 676645f5050Syouri } 677645f5050Syouri } 678645f5050Syouri else 679645f5050Syouri { 680645f5050Syouri icon->w = None; 681645f5050Syouri } 682645f5050Syouri 683645f5050Syouri if ((image != None) && 684645f5050Syouri image->mask != None && 685645f5050Syouri (! (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint))) { 686645f5050Syouri icon->border_width = 0; 687645f5050Syouri } 688645f5050Syouri if (icon->w == None) 689645f5050Syouri { 690645f5050Syouri icon->w = XCreateSimpleWindow(dpy, Scr->Root, 691645f5050Syouri 0,0, 692645f5050Syouri icon->w_width, icon->w_height, 693645f5050Syouri icon->border_width, icon->border, icon->iconc.back); 694645f5050Syouri event_mask = ExposureMask; 695645f5050Syouri } 696645f5050Syouri 697645f5050Syouri if (Scr->AutoRaiseIcons || Scr->ShrinkIconTitles) 698645f5050Syouri event_mask |= EnterWindowMask | LeaveWindowMask; 699645f5050Syouri event_mask |= KeyPressMask | ButtonPressMask | ButtonReleaseMask; 700645f5050Syouri 701645f5050Syouri if (tmp_win->icon_not_ours) { 702645f5050Syouri XWindowAttributes wattr; 703645f5050Syouri 704645f5050Syouri XGetWindowAttributes(dpy, icon->w, &wattr); 705645f5050Syouri if (wattr.all_event_masks & ButtonPressMask) { 706645f5050Syouri event_mask &= ~ButtonPressMask; 707645f5050Syouri } 708645f5050Syouri } 709645f5050Syouri XSelectInput (dpy, icon->w, event_mask); 710645f5050Syouri 711645f5050Syouri if (icon->width == 0) icon->width = icon->w_width; 712645f5050Syouri icon->bm_w = None; 713645f5050Syouri if (image && (! (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint))) { 714645f5050Syouri XRectangle rect; 715645f5050Syouri 716645f5050Syouri x = GetIconOffset (icon); 717645f5050Syouri icon->bm_w = XCreateWindow (dpy, icon->w, x, 0, 718645f5050Syouri (unsigned int)icon->width, 719645f5050Syouri (unsigned int)icon->height, 720645f5050Syouri (unsigned int) 0, Scr->d_depth, 721645f5050Syouri (unsigned int) CopyFromParent, 722645f5050Syouri Scr->d_visual, valuemask, 723645f5050Syouri &attributes); 724645f5050Syouri if (image->mask) { 725645f5050Syouri XShapeCombineMask (dpy, icon->bm_w, ShapeBounding, 0, 0, image->mask, ShapeSet); 726645f5050Syouri XShapeCombineMask (dpy, icon->w, ShapeBounding, x, 0, image->mask, ShapeSet); 727645f5050Syouri } else if (icon->has_title) { 728645f5050Syouri rect.x = x; 729645f5050Syouri rect.y = 0; 730645f5050Syouri rect.width = icon->width; 731645f5050Syouri rect.height = icon->height; 732645f5050Syouri XShapeCombineRectangles (dpy, icon->w, ShapeBounding, 733645f5050Syouri 0, 0, &rect, 1, ShapeSet, 0); 734645f5050Syouri } 735645f5050Syouri if (icon->has_title) { 736645f5050Syouri if (Scr->ShrinkIconTitles) { 737645f5050Syouri rect.x = x; 738645f5050Syouri rect.y = icon->height; 739645f5050Syouri rect.width = icon->width; 740645f5050Syouri rect.height = icon->w_height - icon->height; 741645f5050Syouri icon->title_shrunk = True; 742645f5050Syouri } else { 743645f5050Syouri rect.x = 0; 744645f5050Syouri rect.y = icon->height; 745645f5050Syouri rect.width = icon->w_width; 746645f5050Syouri rect.height = icon->w_height - icon->height; 747645f5050Syouri icon->title_shrunk = False; 748645f5050Syouri } 749645f5050Syouri XShapeCombineRectangles (dpy, icon->w, ShapeBounding, 750645f5050Syouri 0, 0, &rect, 1, ShapeUnion, 0); 751645f5050Syouri } 752645f5050Syouri } 753645f5050Syouri 754645f5050Syouri if (icon->match != match_none) 755645f5050Syouri AddToList (&tmp_win->iconslist, icon->pattern, (char*) icon); 756645f5050Syouri 757645f5050Syouri tmp_win->icon = icon; 758645f5050Syouri /* I need to figure out where to put the icon window now, because 759645f5050Syouri * getting here means that I am going to make the icon visible 760645f5050Syouri */ 761645f5050Syouri if (tmp_win->wmhints && 762645f5050Syouri tmp_win->wmhints->flags & IconPositionHint) 763645f5050Syouri { 764645f5050Syouri final_x = tmp_win->wmhints->icon_x; 765645f5050Syouri final_y = tmp_win->wmhints->icon_y; 766645f5050Syouri } 767645f5050Syouri else 768645f5050Syouri { 769645f5050Syouri if (visible (tmp_win)) 770645f5050Syouri PlaceIcon(tmp_win, def_x, def_y, &final_x, &final_y); 771645f5050Syouri } 772645f5050Syouri 773645f5050Syouri if (visible (tmp_win) || 774645f5050Syouri (tmp_win->wmhints && tmp_win->wmhints->flags & IconPositionHint)) { 775645f5050Syouri if (final_x > Scr->rootw) 776645f5050Syouri final_x = Scr->rootw - icon->w_width - (2 * Scr->IconBorderWidth); 777645f5050Syouri if (Scr->ShrinkIconTitles && icon->bm_w) { 778645f5050Syouri if (final_x + (icon->w_width - icon->width) < 0) final_x = 0; 779645f5050Syouri } else { 780645f5050Syouri if (final_x < 0) final_x = 0; 781645f5050Syouri } 782645f5050Syouri if (final_y > Scr->rooth) 783645f5050Syouri final_y = Scr->rooth - icon->height - 784645f5050Syouri Scr->IconFont.height - 6 - (2 * Scr->IconBorderWidth); 785645f5050Syouri if (final_y < 0) final_y = 0; 786645f5050Syouri 787645f5050Syouri XMoveWindow(dpy, icon->w, final_x, final_y); 788645f5050Syouri } 789645f5050Syouri tmp_win->iconified = TRUE; 790645f5050Syouri 791645f5050Syouri XMapSubwindows(dpy, icon->w); 792645f5050Syouri XSaveContext(dpy, icon->w, TwmContext, (XPointer)tmp_win); 793645f5050Syouri XSaveContext(dpy, icon->w, ScreenContext, (XPointer)Scr); 794645f5050Syouri XDefineCursor(dpy, icon->w, Scr->IconCursor); 795645f5050Syouri MaybeAnimate = True; 796645f5050Syouri return (0); 797645f5050Syouri} 798645f5050Syouri 799645f5050Syourivoid DeleteIconsList(TwmWindow *tmp_win) 800645f5050Syouri{ 801645f5050Syouri /* 802645f5050Syouri * Only the list itself needs to be freed, since the pointers it 803645f5050Syouri * contains point into various lists that belong to Scr. 804645f5050Syouri */ 805645f5050Syouri FreeList(&tmp_win->iconslist); 806645f5050Syouri} 807645f5050Syouri 808645f5050Syourivoid ShrinkIconTitle (TwmWindow *tmp_win) 809645f5050Syouri{ 810645f5050Syouri Icon *icon; 811645f5050Syouri XRectangle rect; 812645f5050Syouri 813645f5050Syouri if (!tmp_win || !tmp_win->icon) return; 814645f5050Syouri icon = tmp_win->icon; 815645f5050Syouri if (!icon->has_title) return; 816645f5050Syouri if (icon->w_width == icon->width) return; 817645f5050Syouri if (icon->height == 0) return; 818645f5050Syouri 819645f5050Syouri rect.x = GetIconOffset (icon); 820645f5050Syouri rect.y = 0; 821645f5050Syouri rect.width = icon->width; 822645f5050Syouri rect.height = icon->w_height; 823645f5050Syouri XShapeCombineRectangles (dpy, icon->w, ShapeBounding, 0, 0, &rect, 1, ShapeIntersect, 0); 824645f5050Syouri icon->title_shrunk = True; 825645f5050Syouri XClearArea (dpy, icon->w, 0, icon->height, icon->w_width, 826645f5050Syouri icon->w_height - icon->height, True); 827645f5050Syouri} 828645f5050Syouri 829645f5050Syourivoid ExpandIconTitle (TwmWindow *tmp_win) 830645f5050Syouri{ 831645f5050Syouri Icon *icon; 832645f5050Syouri XRectangle rect; 833645f5050Syouri 834645f5050Syouri if (!tmp_win || !tmp_win->icon) return; 835645f5050Syouri icon = tmp_win->icon; 836645f5050Syouri if (!icon->has_title) return; 837645f5050Syouri if (icon->w_width == icon->width) return; 838645f5050Syouri if (icon->height == 0) return; 839645f5050Syouri 840645f5050Syouri rect.x = 0; 841645f5050Syouri rect.y = icon->height; 842645f5050Syouri rect.width = icon->w_width; 843645f5050Syouri rect.height = icon->w_height - icon->height; 844645f5050Syouri XShapeCombineRectangles (dpy, icon->w, ShapeBounding, 0, 0, &rect, 1, ShapeUnion, 0); 845645f5050Syouri icon->title_shrunk = False; 846645f5050Syouri XClearArea (dpy, icon->w, 0, icon->height, icon->w_width, 847645f5050Syouri icon->w_height - icon->height, True); 848645f5050Syouri} 849645f5050Syouri 850645f5050Syourivoid ReshapeIcon (Icon *icon) 851645f5050Syouri{ 852645f5050Syouri int x; 853645f5050Syouri XRectangle rect; 854645f5050Syouri 855645f5050Syouri if (!icon) return; 856645f5050Syouri x = GetIconOffset (icon); 857645f5050Syouri XMoveWindow (dpy, icon->bm_w, x, 0); 858645f5050Syouri 859645f5050Syouri if (icon->image && icon->image->mask) { 860645f5050Syouri XShapeCombineMask (dpy, icon->w, ShapeBounding, x, 0, icon->image->mask, ShapeSet); 861645f5050Syouri } else { 862645f5050Syouri rect.x = x; 863645f5050Syouri rect.y = 0; 864645f5050Syouri rect.width = icon->width; 865645f5050Syouri rect.height = icon->height; 866645f5050Syouri XShapeCombineRectangles (dpy, icon->w, ShapeBounding, 0, 0, &rect, 1, ShapeSet, 0); 867645f5050Syouri } 868645f5050Syouri rect.x = x; 869645f5050Syouri rect.y = icon->height; 870645f5050Syouri rect.width = icon->width; 871645f5050Syouri rect.height = icon->w_height - icon->height; 872645f5050Syouri XShapeCombineRectangles (dpy, icon->w, ShapeBounding, 0, 0, &rect, 1, ShapeUnion, 0); 873645f5050Syouri} 874645f5050Syouri 875645f5050Syouriint GetIconOffset (Icon *icon) 876645f5050Syouri{ 877645f5050Syouri short justif; 878645f5050Syouri 879645f5050Syouri if (!icon) return (0); 880645f5050Syouri 881645f5050Syouri justif = icon->ir ? icon->ir->TitleJustification : Scr->IconJustification; 882645f5050Syouri switch (justif) { 883645f5050Syouri case J_LEFT : 884645f5050Syouri return (0); 885645f5050Syouri 886645f5050Syouri case J_CENTER : 887645f5050Syouri return ((icon->w_width - icon->width) / 2); 888645f5050Syouri 889645f5050Syouri case J_RIGHT : 890645f5050Syouri return (icon->w_width - icon->width); 891645f5050Syouri 892645f5050Syouri default : 893645f5050Syouri return (0); 894645f5050Syouri } 895645f5050Syouri} 896645f5050Syouri 897645f5050SyouriBool AnimateIcons (ScreenInfo *scr, Icon *icon) 898645f5050Syouri{ 899645f5050Syouri Image *image; 900645f5050Syouri XRectangle rect; 901645f5050Syouri XSetWindowAttributes attr; 902645f5050Syouri int x; 903645f5050Syouri 904645f5050Syouri image = icon->image; 905645f5050Syouri attr.background_pixmap = image->pixmap; 906645f5050Syouri XChangeWindowAttributes (dpy, icon->bm_w, CWBackPixmap, &attr); 907645f5050Syouri 908645f5050Syouri if (image->mask != None) { 909645f5050Syouri x = GetIconOffset (icon); 910645f5050Syouri XShapeCombineMask (dpy, icon->bm_w, ShapeBounding, 0, 0, image->mask, ShapeSet); 911645f5050Syouri if (icon->has_title) { 912645f5050Syouri rect.x = 0; 913645f5050Syouri rect.y = icon->height; 914645f5050Syouri rect.width = icon->w_width; 915645f5050Syouri rect.height = scr->IconFont.height + 6; 916645f5050Syouri 917645f5050Syouri XShapeCombineShape (dpy, scr->ShapeWindow, ShapeBounding, x, 0, icon->bm_w, 918645f5050Syouri ShapeBounding, ShapeSet); 919645f5050Syouri XShapeCombineRectangles (dpy, scr->ShapeWindow, ShapeBounding, 0, 0, &rect, 1, 920645f5050Syouri ShapeUnion, 0); 921645f5050Syouri XShapeCombineShape (dpy, icon->w, ShapeBounding, 0, 0, scr->ShapeWindow, 922645f5050Syouri ShapeBounding, ShapeSet); 923645f5050Syouri } 924645f5050Syouri else 925645f5050Syouri XShapeCombineShape (dpy, icon->w, ShapeBounding, x, 0, icon->bm_w, 926645f5050Syouri ShapeBounding, ShapeSet); 927645f5050Syouri } 928645f5050Syouri XClearWindow (dpy, icon->bm_w); 929645f5050Syouri icon->image = image->next; 930645f5050Syouri return (True); 931645f5050Syouri} 932645f5050Syouri 933