13e747e6dSmrg/* 2ffd25bcaSmrg * 33e747e6dSmrgCopyright 1989, 1998 The Open Group 43e747e6dSmrg 53e747e6dSmrgPermission to use, copy, modify, distribute, and sell this software and its 63e747e6dSmrgdocumentation for any purpose is hereby granted without fee, provided that 73e747e6dSmrgthe above copyright notice appear in all copies and that both that 83e747e6dSmrgcopyright notice and this permission notice appear in supporting 93e747e6dSmrgdocumentation. 103e747e6dSmrg 113e747e6dSmrgThe above copyright notice and this permission notice shall be included in 123e747e6dSmrgall copies or substantial portions of the Software. 133e747e6dSmrg 143e747e6dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 153e747e6dSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 163e747e6dSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 173e747e6dSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 183e747e6dSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 193e747e6dSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 203e747e6dSmrg 213e747e6dSmrgExcept as contained in this notice, the name of The Open Group shall not be 223e747e6dSmrgused in advertising or otherwise to promote the sale, use or other dealings 233e747e6dSmrgin this Software without prior written authorization from The Open Group. 243e747e6dSmrg * */ 253e747e6dSmrg 263e747e6dSmrg/********************************************************************** 273e747e6dSmrg * 28f66df612Smrg * Icon related routines 293e747e6dSmrg * 303e747e6dSmrg * 10-Apr-89 Tom LaStrange Initial Version. 313e747e6dSmrg * 323e747e6dSmrg **********************************************************************/ 333e747e6dSmrg 343e747e6dSmrg#include <stdio.h> 353e747e6dSmrg#include "twm.h" 363e747e6dSmrg#include "screen.h" 373e747e6dSmrg#include "icons.h" 383e747e6dSmrg#include "parse.h" 393e747e6dSmrg#include "util.h" 403e747e6dSmrg 41f66df612Smrg#define iconWidth(w) (Scr->IconBorderWidth * 2 + w->icon_w_width) 42f66df612Smrg#define iconHeight(w) (Scr->IconBorderWidth * 2 + w->icon_w_height) 433e747e6dSmrg 44f66df612Smrgstatic void splitEntry(IconEntry *ie, int grav1, int grav2, int w, int h); 45f66df612Smrgstatic IconEntry *FindIconEntry(TwmWindow *tmp_win, IconRegion **irp); 46f66df612Smrgstatic IconEntry *prevIconEntry(IconEntry *ie, IconRegion *ir); 47f66df612Smrgstatic void mergeEntries(IconEntry *old, IconEntry *ie); 483e747e6dSmrg 493e747e6dSmrgstatic void 50f66df612SmrgsplitEntry(IconEntry *ie, int grav1, int grav2, int w, int h) 513e747e6dSmrg{ 526d8e82c3Smrg IconEntry *entry; 533e747e6dSmrg 543e747e6dSmrg switch (grav1) { 553e747e6dSmrg case D_NORTH: 563e747e6dSmrg case D_SOUTH: 57f66df612Smrg if (w != ie->w) 58f66df612Smrg splitEntry(ie, grav2, grav1, w, ie->h); 59f66df612Smrg if (h != ie->h) { 606d8e82c3Smrg entry = (IconEntry *) malloc(sizeof(IconEntry)); 616d8e82c3Smrg entry->twm_win = NULL; 626d8e82c3Smrg entry->used = 0; 636d8e82c3Smrg entry->next = ie->next; 646d8e82c3Smrg ie->next = entry; 656d8e82c3Smrg entry->x = ie->x; 666d8e82c3Smrg entry->h = (ie->h - h); 676d8e82c3Smrg entry->w = ie->w; 68f66df612Smrg ie->h = h; 69f66df612Smrg if (grav1 == D_SOUTH) { 706d8e82c3Smrg entry->y = ie->y; 716d8e82c3Smrg ie->y = entry->y + entry->h; 72f66df612Smrg } 73f66df612Smrg else 746d8e82c3Smrg entry->y = ie->y + ie->h; 75f66df612Smrg } 76f66df612Smrg break; 773e747e6dSmrg case D_EAST: 783e747e6dSmrg case D_WEST: 79f66df612Smrg if (h != ie->h) 80f66df612Smrg splitEntry(ie, grav2, grav1, ie->w, h); 81f66df612Smrg if (w != ie->w) { 826d8e82c3Smrg entry = (IconEntry *) malloc(sizeof(IconEntry)); 836d8e82c3Smrg entry->twm_win = NULL; 846d8e82c3Smrg entry->used = 0; 856d8e82c3Smrg entry->next = ie->next; 866d8e82c3Smrg ie->next = entry; 876d8e82c3Smrg entry->y = ie->y; 886d8e82c3Smrg entry->w = (ie->w - w); 896d8e82c3Smrg entry->h = ie->h; 90f66df612Smrg ie->w = w; 91f66df612Smrg if (grav1 == D_EAST) { 926d8e82c3Smrg entry->x = ie->x; 936d8e82c3Smrg ie->x = entry->x + entry->w; 94f66df612Smrg } 95f66df612Smrg else 966d8e82c3Smrg entry->x = ie->x + ie->w; 97f66df612Smrg } 98f66df612Smrg break; 993e747e6dSmrg } 1003e747e6dSmrg} 1013e747e6dSmrg 102c2535118Smrgstatic inline int 103f66df612SmrgroundUp(int v, int multiple) 1043e747e6dSmrg{ 1053e747e6dSmrg return ((v + multiple - 1) / multiple) * multiple; 1063e747e6dSmrg} 1073e747e6dSmrg 108c2535118Smrgstatic void 1093e747e6dSmrgPlaceIcon(TwmWindow *tmp_win, int def_x, int def_y, int *final_x, int *final_y) 1103e747e6dSmrg{ 111f66df612Smrg IconRegion *ir; 112f66df612Smrg IconEntry *ie; 113f66df612Smrg int w = 0, h = 0; 1143e747e6dSmrg 1156d8e82c3Smrg ie = NULL; 1163e747e6dSmrg for (ir = Scr->FirstRegion; ir; ir = ir->next) { 117f66df612Smrg w = roundUp(iconWidth(tmp_win), ir->stepx); 118f66df612Smrg h = roundUp(iconHeight(tmp_win), ir->stepy); 119f66df612Smrg for (ie = ir->entries; ie; ie = ie->next) { 120f66df612Smrg if (ie->used) 121f66df612Smrg continue; 122f66df612Smrg if (ie->w >= w && ie->h >= h) 123f66df612Smrg break; 124f66df612Smrg } 125f66df612Smrg if (ie) 126f66df612Smrg break; 1273e747e6dSmrg } 1283e747e6dSmrg if (ie) { 129f66df612Smrg splitEntry(ie, ir->grav1, ir->grav2, w, h); 130f66df612Smrg ie->used = 1; 131f66df612Smrg ie->twm_win = tmp_win; 132f66df612Smrg *final_x = ie->x + (ie->w - iconWidth(tmp_win)) / 2; 133f66df612Smrg *final_y = ie->y + (ie->h - iconHeight(tmp_win)) / 2; 134f66df612Smrg } 135f66df612Smrg else { 136f66df612Smrg *final_x = def_x; 137f66df612Smrg *final_y = def_y; 1383e747e6dSmrg } 1393e747e6dSmrg return; 1403e747e6dSmrg} 1413e747e6dSmrg 1423e747e6dSmrgstatic IconEntry * 143f66df612SmrgFindIconEntry(TwmWindow *tmp_win, IconRegion **irp) 1443e747e6dSmrg{ 145f66df612Smrg IconRegion *ir; 146f66df612Smrg IconEntry *ie; 1473e747e6dSmrg 1483e747e6dSmrg for (ir = Scr->FirstRegion; ir; ir = ir->next) { 149f66df612Smrg for (ie = ir->entries; ie; ie = ie->next) 150f66df612Smrg if (ie->twm_win == tmp_win) { 151f66df612Smrg if (irp) 152f66df612Smrg *irp = ir; 153f66df612Smrg return ie; 154f66df612Smrg } 1553e747e6dSmrg } 1566d8e82c3Smrg return NULL; 1573e747e6dSmrg} 1583e747e6dSmrg 1593e747e6dSmrgvoid 160f66df612SmrgIconUp(TwmWindow *tmp_win) 1613e747e6dSmrg{ 162f66df612Smrg int x, y; 163f66df612Smrg int defx, defy; 1643e747e6dSmrg struct IconRegion *ir; 1656d8e82c3Smrg unsigned udummy = 0; 1666d8e82c3Smrg Window wdummy = None; 1673e747e6dSmrg 1683e747e6dSmrg /* 1693e747e6dSmrg * If the client specified a particular location, let's use it (this might 1703e747e6dSmrg * want to be an option at some point). Otherwise, try to fit within the 1713e747e6dSmrg * icon region. 1723e747e6dSmrg */ 1733e747e6dSmrg if (tmp_win->wmhints && (tmp_win->wmhints->flags & IconPositionHint)) 174f66df612Smrg return; 1753e747e6dSmrg 1763e747e6dSmrg if (tmp_win->icon_moved) { 1776d8e82c3Smrg unsigned width = 0; 1786d8e82c3Smrg unsigned height = 0; 1796d8e82c3Smrg 1806d8e82c3Smrg if (!XGetGeometry(dpy, tmp_win->icon_w, &wdummy, &defx, &defy, 1816d8e82c3Smrg &width, &height, &udummy, &udummy)) 182f66df612Smrg return; 183f66df612Smrg 1846d8e82c3Smrg x = defx + ((int) width) / 2; 1856d8e82c3Smrg y = defy + ((int) height) / 2; 186f66df612Smrg 187f66df612Smrg for (ir = Scr->FirstRegion; ir; ir = ir->next) { 188f66df612Smrg if (x >= ir->x && x < (ir->x + ir->w) && 189f66df612Smrg y >= ir->y && y < (ir->y + ir->h)) 190f66df612Smrg break; 191f66df612Smrg } 192f66df612Smrg if (!ir) 193f66df612Smrg return; /* outside icon regions, leave alone */ 1943e747e6dSmrg } 1953e747e6dSmrg 1963e747e6dSmrg defx = -100; 1973e747e6dSmrg defy = -100; 1983e747e6dSmrg PlaceIcon(tmp_win, defx, defy, &x, &y); 1993e747e6dSmrg if (x != defx || y != defy) { 200f66df612Smrg XMoveWindow(dpy, tmp_win->icon_w, x, y); 201f66df612Smrg tmp_win->icon_moved = FALSE; /* since we've restored it */ 2023e747e6dSmrg } 2033e747e6dSmrg} 2043e747e6dSmrg 2053e747e6dSmrgstatic IconEntry * 206f66df612SmrgprevIconEntry(IconEntry *ie, IconRegion *ir) 2073e747e6dSmrg{ 208f66df612Smrg IconEntry *ip; 2093e747e6dSmrg 2103e747e6dSmrg if (ie == ir->entries) 2116d8e82c3Smrg return NULL; 212f66df612Smrg for (ip = ir->entries; ip->next != ie; ip = ip->next); 2133e747e6dSmrg return ip; 2143e747e6dSmrg} 2153e747e6dSmrg 2163e747e6dSmrg/** 2173e747e6dSmrg * old is being freed; and is adjacent to ie. Merge 2183e747e6dSmrg * regions together 2193e747e6dSmrg */ 2203e747e6dSmrgstatic void 221f66df612SmrgmergeEntries(IconEntry *old, IconEntry *ie) 2223e747e6dSmrg{ 2233e747e6dSmrg if (old->y == ie->y) { 224f66df612Smrg ie->w = old->w + ie->w; 225f66df612Smrg if (old->x < ie->x) 226f66df612Smrg ie->x = old->x; 227f66df612Smrg } 228f66df612Smrg else { 229f66df612Smrg ie->h = old->h + ie->h; 230f66df612Smrg if (old->y < ie->y) 231f66df612Smrg ie->y = old->y; 2323e747e6dSmrg } 2333e747e6dSmrg} 2343e747e6dSmrg 2353e747e6dSmrgvoid 236f66df612SmrgIconDown(TwmWindow *tmp_win) 2373e747e6dSmrg{ 238f66df612Smrg IconEntry *ie, *ip, *in; 239f66df612Smrg IconRegion *ir; 2403e747e6dSmrg 241f66df612Smrg ie = FindIconEntry(tmp_win, &ir); 2423e747e6dSmrg if (ie) { 2436d8e82c3Smrg ie->twm_win = NULL; 244f66df612Smrg ie->used = 0; 245f66df612Smrg ip = prevIconEntry(ie, ir); 246f66df612Smrg in = ie->next; 247f66df612Smrg for (;;) { 248f66df612Smrg if (ip && ip->used == 0 && 249f66df612Smrg ((ip->x == ie->x && ip->w == ie->w) || 250f66df612Smrg (ip->y == ie->y && ip->h == ie->h))) { 251f66df612Smrg ip->next = ie->next; 252f66df612Smrg mergeEntries(ie, ip); 253f66df612Smrg free(ie); 254f66df612Smrg ie = ip; 255f66df612Smrg ip = prevIconEntry(ip, ir); 256f66df612Smrg } 257f66df612Smrg else if (in && in->used == 0 && 258f66df612Smrg ((in->x == ie->x && in->w == ie->w) || 259f66df612Smrg (in->y == ie->y && in->h == ie->h))) { 260f66df612Smrg ie->next = in->next; 261f66df612Smrg mergeEntries(in, ie); 262f66df612Smrg free(in); 263f66df612Smrg in = ie->next; 264f66df612Smrg } 265f66df612Smrg else 266f66df612Smrg break; 267f66df612Smrg } 2683e747e6dSmrg } 2693e747e6dSmrg} 2703e747e6dSmrg 2713e747e6dSmrgvoid 2723e747e6dSmrgAddIconRegion(char *geom, int grav1, int grav2, int stepx, int stepy) 2733e747e6dSmrg{ 2743e747e6dSmrg IconRegion *ir; 2753e747e6dSmrg int mask; 2763e747e6dSmrg 2776d8e82c3Smrg ir = (IconRegion *) malloc(sizeof(IconRegion)); 2783e747e6dSmrg ir->next = NULL; 2793e747e6dSmrg if (Scr->LastRegion) 280f66df612Smrg Scr->LastRegion->next = ir; 2813e747e6dSmrg Scr->LastRegion = ir; 2823e747e6dSmrg if (!Scr->FirstRegion) 283f66df612Smrg Scr->FirstRegion = ir; 2843e747e6dSmrg 2853e747e6dSmrg ir->entries = NULL; 2863e747e6dSmrg ir->grav1 = grav1; 2873e747e6dSmrg ir->grav2 = grav2; 2883e747e6dSmrg if (stepx <= 0) 289f66df612Smrg stepx = 1; 2903e747e6dSmrg if (stepy <= 0) 291f66df612Smrg stepy = 1; 2923e747e6dSmrg ir->stepx = stepx; 2933e747e6dSmrg ir->stepy = stepy; 2943e747e6dSmrg ir->x = ir->y = ir->w = ir->h = 0; 2953e747e6dSmrg 296f66df612Smrg mask = 297f66df612Smrg XParseGeometry(geom, &ir->x, &ir->y, (unsigned int *) &ir->w, 298f66df612Smrg (unsigned int *) &ir->h); 2993e747e6dSmrg 3003e747e6dSmrg if (mask & XNegative) 301f66df612Smrg ir->x += Scr->MyDisplayWidth - ir->w; 3023e747e6dSmrg 3033e747e6dSmrg if (mask & YNegative) 304f66df612Smrg ir->y += Scr->MyDisplayHeight - ir->h; 3056d8e82c3Smrg ir->entries = (IconEntry *) malloc(sizeof(IconEntry)); 3066d8e82c3Smrg ir->entries->next = NULL; 3073e747e6dSmrg ir->entries->x = ir->x; 3083e747e6dSmrg ir->entries->y = ir->y; 3093e747e6dSmrg ir->entries->w = ir->w; 3103e747e6dSmrg ir->entries->h = ir->h; 3116d8e82c3Smrg ir->entries->twm_win = NULL; 3123e747e6dSmrg ir->entries->used = 0; 3133e747e6dSmrg} 3143e747e6dSmrg 3153e747e6dSmrgvoid 3163e747e6dSmrgCreateIconWindow(TwmWindow *tmp_win, int def_x, int def_y) 3173e747e6dSmrg{ 3183e747e6dSmrg unsigned long event_mask; 319f66df612Smrg unsigned long valuemask; /* mask for create windows */ 320f66df612Smrg XSetWindowAttributes attributes; /* attributes for create windows */ 321f66df612Smrg Pixmap pm = None; /* tmp pixmap variable */ 3223e747e6dSmrg int final_x, final_y; 3236d8e82c3Smrg int dummy = 0; 3246d8e82c3Smrg unsigned udummy = 0; 3256d8e82c3Smrg Window wdummy = None; 3263e747e6dSmrg 3273e747e6dSmrg FB(tmp_win->iconc.fore, tmp_win->iconc.back); 3283e747e6dSmrg 3293e747e6dSmrg tmp_win->forced = FALSE; 3303e747e6dSmrg tmp_win->icon_not_ours = FALSE; 3313e747e6dSmrg 332ffd25bcaSmrg /* now go through the steps to get an icon window, if ForceIcon is 3333e747e6dSmrg * set, then no matter what else is defined, the bitmap from the 3343e747e6dSmrg * .twmrc file is used 3353e747e6dSmrg */ 336f66df612Smrg if (Scr->ForceIcon) { 337f66df612Smrg char *icon_name; 338f66df612Smrg Pixmap bm; 3393e747e6dSmrg 340f66df612Smrg icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name); 3413e747e6dSmrg if (icon_name == NULL) 342f66df612Smrg icon_name = LookInList(Scr->IconNames, tmp_win->full_name, 3436d8e82c3Smrg &tmp_win->xclass); 344f66df612Smrg 345f66df612Smrg bm = None; 346f66df612Smrg if (icon_name != NULL) { 347f66df612Smrg if ((bm = 348f66df612Smrg (Pixmap) (void *) LookInNameList(Scr->Icons, 349f66df612Smrg icon_name)) == None) { 350f66df612Smrg if ((bm = GetBitmap(icon_name)) != None) 351f66df612Smrg AddToList(&Scr->Icons, icon_name, (char *) bm); 352f66df612Smrg } 353f66df612Smrg } 354f66df612Smrg 355f66df612Smrg if (bm != None) { 3566d8e82c3Smrg XGetGeometry(dpy, bm, &wdummy, &dummy, &dummy, 357f66df612Smrg (unsigned int *) &tmp_win->icon_width, 3586d8e82c3Smrg (unsigned int *) &tmp_win->icon_height, &udummy, 3596d8e82c3Smrg &udummy); 360f66df612Smrg 361f66df612Smrg pm = XCreatePixmap(dpy, Scr->Root, (unsigned) tmp_win->icon_width, 362f66df612Smrg (unsigned) tmp_win->icon_height, 363f66df612Smrg (unsigned) Scr->d_depth); 364f66df612Smrg 365f66df612Smrg /* the copy plane works on color ! */ 366f66df612Smrg XCopyPlane(dpy, bm, pm, Scr->NormalGC, 367f66df612Smrg 0, 0, (unsigned) tmp_win->icon_width, 368f66df612Smrg (unsigned) tmp_win->icon_height, 0, 0, 1); 369f66df612Smrg 370f66df612Smrg tmp_win->forced = TRUE; 371f66df612Smrg } 3723e747e6dSmrg } 3733e747e6dSmrg 3743e747e6dSmrg /* if the pixmap is still NULL, we didn't get one from the above code, 3753e747e6dSmrg * that could mean that ForceIcon was not set, or that the window 3763e747e6dSmrg * was not in the Icons list, now check the WM hints for an icon 3773e747e6dSmrg */ 3783e747e6dSmrg if (pm == None && tmp_win->wmhints && 379f66df612Smrg tmp_win->wmhints->flags & IconPixmapHint) { 380f66df612Smrg 381f66df612Smrg XGetGeometry(dpy, tmp_win->wmhints->icon_pixmap, 3826d8e82c3Smrg &wdummy, &dummy, &dummy, 383f66df612Smrg (unsigned int *) &tmp_win->icon_width, 3846d8e82c3Smrg (unsigned int *) &tmp_win->icon_height, &udummy, 3856d8e82c3Smrg &udummy); 386f66df612Smrg 387f66df612Smrg pm = XCreatePixmap(dpy, Scr->Root, 388f66df612Smrg (unsigned) tmp_win->icon_width, 389f66df612Smrg (unsigned) tmp_win->icon_height, 390f66df612Smrg (unsigned) Scr->d_depth); 391f66df612Smrg 392f66df612Smrg XCopyPlane(dpy, tmp_win->wmhints->icon_pixmap, pm, Scr->NormalGC, 393f66df612Smrg 0, 0, (unsigned) tmp_win->icon_width, 394f66df612Smrg (unsigned) tmp_win->icon_height, 0, 0, 1); 3953e747e6dSmrg } 3963e747e6dSmrg 397ffd25bcaSmrg /* if we still haven't got an icon, let's look in the Icon list 3983e747e6dSmrg * if ForceIcon is not set 3993e747e6dSmrg */ 400f66df612Smrg if (pm == None && !Scr->ForceIcon) { 401f66df612Smrg char *icon_name; 402f66df612Smrg Pixmap bm; 4033e747e6dSmrg 404f66df612Smrg icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name); 4053e747e6dSmrg if (icon_name == NULL) 406f66df612Smrg icon_name = LookInList(Scr->IconNames, tmp_win->full_name, 4076d8e82c3Smrg &tmp_win->xclass); 408f66df612Smrg 409f66df612Smrg bm = None; 410f66df612Smrg if (icon_name != NULL) { 411f66df612Smrg if ((bm = 412f66df612Smrg (Pixmap) (void *) LookInNameList(Scr->Icons, 413f66df612Smrg icon_name)) == None) { 414f66df612Smrg if ((bm = GetBitmap(icon_name)) != None) 415f66df612Smrg AddToList(&Scr->Icons, icon_name, (char *) bm); 416f66df612Smrg } 417f66df612Smrg } 418f66df612Smrg 419f66df612Smrg if (bm != None) { 4206d8e82c3Smrg XGetGeometry(dpy, bm, &wdummy, &dummy, &dummy, 421f66df612Smrg (unsigned int *) &tmp_win->icon_width, 4226d8e82c3Smrg (unsigned int *) &tmp_win->icon_height, &udummy, 4236d8e82c3Smrg &udummy); 424f66df612Smrg 425f66df612Smrg pm = XCreatePixmap(dpy, Scr->Root, (unsigned) tmp_win->icon_width, 426f66df612Smrg (unsigned) tmp_win->icon_height, 427f66df612Smrg (unsigned) Scr->d_depth); 428f66df612Smrg 429f66df612Smrg /* the copy plane works on color ! */ 430f66df612Smrg XCopyPlane(dpy, bm, pm, Scr->NormalGC, 431f66df612Smrg 0, 0, (unsigned) tmp_win->icon_width, 432f66df612Smrg (unsigned) tmp_win->icon_height, 0, 0, 1); 433f66df612Smrg } 4343e747e6dSmrg } 4353e747e6dSmrg 4363e747e6dSmrg /* if we still don't have an icon, assign the UnknownIcon */ 4373e747e6dSmrg 438f66df612Smrg if (pm == None && Scr->UnknownPm != None) { 439f66df612Smrg tmp_win->icon_width = Scr->UnknownWidth; 440f66df612Smrg tmp_win->icon_height = Scr->UnknownHeight; 4413e747e6dSmrg 442f66df612Smrg pm = XCreatePixmap(dpy, Scr->Root, (unsigned) tmp_win->icon_width, 443f66df612Smrg (unsigned) tmp_win->icon_height, 444f66df612Smrg (unsigned) Scr->d_depth); 4453e747e6dSmrg 446f66df612Smrg /* the copy plane works on color ! */ 447f66df612Smrg XCopyPlane(dpy, Scr->UnknownPm, pm, Scr->NormalGC, 448f66df612Smrg 0, 0, (unsigned) tmp_win->icon_width, 449f66df612Smrg (unsigned) tmp_win->icon_height, 0, 0, 1); 4503e747e6dSmrg } 4513e747e6dSmrg 452f66df612Smrg if (pm == None) { 453f66df612Smrg tmp_win->icon_height = 0; 454f66df612Smrg tmp_win->icon_width = 0; 455f66df612Smrg valuemask = 0; 4563e747e6dSmrg } 457f66df612Smrg else { 458f66df612Smrg valuemask = CWBackPixmap; 459f66df612Smrg attributes.background_pixmap = pm; 4603e747e6dSmrg } 4613e747e6dSmrg 4623e747e6dSmrg tmp_win->icon_w_width = MyFont_TextWidth(&Scr->IconFont, 463f66df612Smrg tmp_win->icon_name, 464f66df612Smrg (int) strlen(tmp_win->icon_name)); 4653e747e6dSmrg 4663e747e6dSmrg tmp_win->icon_w_width += 6; 467f66df612Smrg if (tmp_win->icon_w_width < tmp_win->icon_width) { 468f66df612Smrg tmp_win->icon_x = (tmp_win->icon_width - tmp_win->icon_w_width) / 2; 469f66df612Smrg tmp_win->icon_x += 3; 470f66df612Smrg tmp_win->icon_w_width = tmp_win->icon_width; 4713e747e6dSmrg } 472f66df612Smrg else { 473f66df612Smrg tmp_win->icon_x = 3; 4743e747e6dSmrg } 4753e747e6dSmrg tmp_win->icon_y = tmp_win->icon_height + Scr->IconFont.height; 4763e747e6dSmrg tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 4; 4773e747e6dSmrg 4783e747e6dSmrg event_mask = 0; 479f66df612Smrg if (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint) { 480f66df612Smrg tmp_win->icon_w = tmp_win->wmhints->icon_window; 481f66df612Smrg if (tmp_win->forced || 4826d8e82c3Smrg XGetGeometry(dpy, tmp_win->icon_w, &wdummy, &dummy, &dummy, 483f66df612Smrg (unsigned int *) &tmp_win->icon_w_width, 4846d8e82c3Smrg (unsigned int *) &tmp_win->icon_w_height, &udummy, 4856d8e82c3Smrg &udummy) == 0) { 486f66df612Smrg tmp_win->icon_w = None; 487f66df612Smrg tmp_win->wmhints->flags &= ~IconWindowHint; 488f66df612Smrg } 489f66df612Smrg else { 490f66df612Smrg tmp_win->icon_not_ours = TRUE; 491f66df612Smrg event_mask = EnterWindowMask | LeaveWindowMask; 492f66df612Smrg } 4933e747e6dSmrg } 494f66df612Smrg else { 495f66df612Smrg tmp_win->icon_w = None; 4963e747e6dSmrg } 4973e747e6dSmrg 498f66df612Smrg if (tmp_win->icon_w == None) { 499f66df612Smrg tmp_win->icon_w = XCreateSimpleWindow(dpy, Scr->Root, 500f66df612Smrg 0, 0, 501f66df612Smrg (unsigned) tmp_win->icon_w_width, 502f66df612Smrg (unsigned) tmp_win->icon_w_height, 503f66df612Smrg (unsigned) Scr->IconBorderWidth, 504f66df612Smrg tmp_win->icon_border, 505f66df612Smrg tmp_win->iconc.back); 506f66df612Smrg event_mask = ExposureMask; 5073e747e6dSmrg } 5083e747e6dSmrg 509f66df612Smrg XSelectInput(dpy, tmp_win->icon_w, 510f66df612Smrg (long) (KeyPressMask | ButtonPressMask | ButtonReleaseMask | 511f66df612Smrg event_mask)); 5123e747e6dSmrg 5133e747e6dSmrg tmp_win->icon_bm_w = None; 5143e747e6dSmrg if (pm != None && 515f66df612Smrg (!(tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint))) { 516f66df612Smrg int y; 517f66df612Smrg int x; 518f66df612Smrg 519f66df612Smrg y = 0; 520f66df612Smrg if (tmp_win->icon_w_width == tmp_win->icon_width) 521f66df612Smrg x = 0; 522f66df612Smrg else 523f66df612Smrg x = (tmp_win->icon_w_width - tmp_win->icon_width) / 2; 524f66df612Smrg 525f66df612Smrg tmp_win->icon_bm_w = XCreateWindow(dpy, tmp_win->icon_w, x, y, 526f66df612Smrg (unsigned int) tmp_win->icon_width, 527f66df612Smrg (unsigned int) tmp_win->icon_height, 528f66df612Smrg (unsigned int) 0, Scr->d_depth, 529f66df612Smrg (unsigned int) CopyFromParent, 530f66df612Smrg Scr->d_visual, valuemask, 531f66df612Smrg &attributes); 5323e747e6dSmrg } 5333e747e6dSmrg 534ffd25bcaSmrg /* I need to figure out where to put the icon window now, because 5353e747e6dSmrg * getting here means that I am going to make the icon visible 5363e747e6dSmrg */ 537f66df612Smrg if (tmp_win->wmhints && tmp_win->wmhints->flags & IconPositionHint) { 538f66df612Smrg final_x = tmp_win->wmhints->icon_x; 539f66df612Smrg final_y = tmp_win->wmhints->icon_y; 5403e747e6dSmrg } 541f66df612Smrg else { 542f66df612Smrg PlaceIcon(tmp_win, def_x, def_y, &final_x, &final_y); 5433e747e6dSmrg } 5443e747e6dSmrg 5453e747e6dSmrg if (final_x > Scr->MyDisplayWidth) 546f66df612Smrg final_x = Scr->MyDisplayWidth - tmp_win->icon_w_width - 547f66df612Smrg (2 * Scr->IconBorderWidth); 5483e747e6dSmrg 5493e747e6dSmrg if (final_y > Scr->MyDisplayHeight) 550f66df612Smrg final_y = Scr->MyDisplayHeight - tmp_win->icon_height - 551f66df612Smrg Scr->IconFont.height - 4 - (2 * Scr->IconBorderWidth); 5523e747e6dSmrg 5533e747e6dSmrg XMoveWindow(dpy, tmp_win->icon_w, final_x, final_y); 5543e747e6dSmrg tmp_win->iconified = TRUE; 5553e747e6dSmrg 5563e747e6dSmrg XMapSubwindows(dpy, tmp_win->icon_w); 557f66df612Smrg XSaveContext(dpy, tmp_win->icon_w, TwmContext, (XPointer) tmp_win); 558f66df612Smrg XSaveContext(dpy, tmp_win->icon_w, ScreenContext, (XPointer) Scr); 5593e747e6dSmrg XDefineCursor(dpy, tmp_win->icon_w, Scr->IconCursor); 560f66df612Smrg if (pm) 561f66df612Smrg XFreePixmap(dpy, pm); 5623e747e6dSmrg return; 5633e747e6dSmrg} 564