icons.c revision 3e747e6d
13e747e6dSmrg/* 23e747e6dSmrg * 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/* $XFree86: xc/programs/twm/icons.c,v 1.6 2001/12/14 20:01:08 dawes Exp $ */ 263e747e6dSmrg 273e747e6dSmrg/********************************************************************** 283e747e6dSmrg * 293e747e6dSmrg * $Xorg: icons.c,v 1.4 2001/02/09 02:05:36 xorgcvs Exp $ 303e747e6dSmrg * 313e747e6dSmrg * Icon releated routines 323e747e6dSmrg * 333e747e6dSmrg * 10-Apr-89 Tom LaStrange Initial Version. 343e747e6dSmrg * 353e747e6dSmrg **********************************************************************/ 363e747e6dSmrg 373e747e6dSmrg#include <stdio.h> 383e747e6dSmrg#include "twm.h" 393e747e6dSmrg#include "screen.h" 403e747e6dSmrg#include "icons.h" 413e747e6dSmrg#include "gram.h" 423e747e6dSmrg#include "parse.h" 433e747e6dSmrg#include "util.h" 443e747e6dSmrg 453e747e6dSmrg#define iconWidth(w) (Scr->IconBorderWidth * 2 + w->icon_w_width) 463e747e6dSmrg#define iconHeight(w) (Scr->IconBorderWidth * 2 + w->icon_w_height) 473e747e6dSmrg 483e747e6dSmrgstatic void splitEntry ( IconEntry *ie, int grav1, int grav2, int w, int h ); 493e747e6dSmrgstatic IconEntry * FindIconEntry ( TwmWindow *tmp_win, IconRegion **irp ); 503e747e6dSmrgstatic IconEntry * prevIconEntry ( IconEntry *ie, IconRegion *ir ); 513e747e6dSmrgstatic void mergeEntries ( IconEntry *old, IconEntry *ie ); 523e747e6dSmrg 533e747e6dSmrgstatic void 543e747e6dSmrgsplitEntry (IconEntry *ie, int grav1, int grav2, int w, int h) 553e747e6dSmrg{ 563e747e6dSmrg IconEntry *new; 573e747e6dSmrg 583e747e6dSmrg switch (grav1) { 593e747e6dSmrg case D_NORTH: 603e747e6dSmrg case D_SOUTH: 613e747e6dSmrg if (w != ie->w) 623e747e6dSmrg splitEntry (ie, grav2, grav1, w, ie->h); 633e747e6dSmrg if (h != ie->h) { 643e747e6dSmrg new = (IconEntry *)malloc (sizeof (IconEntry)); 653e747e6dSmrg new->twm_win = 0; 663e747e6dSmrg new->used = 0; 673e747e6dSmrg new->next = ie->next; 683e747e6dSmrg ie->next = new; 693e747e6dSmrg new->x = ie->x; 703e747e6dSmrg new->h = (ie->h - h); 713e747e6dSmrg new->w = ie->w; 723e747e6dSmrg ie->h = h; 733e747e6dSmrg if (grav1 == D_SOUTH) { 743e747e6dSmrg new->y = ie->y; 753e747e6dSmrg ie->y = new->y + new->h; 763e747e6dSmrg } else 773e747e6dSmrg new->y = ie->y + ie->h; 783e747e6dSmrg } 793e747e6dSmrg break; 803e747e6dSmrg case D_EAST: 813e747e6dSmrg case D_WEST: 823e747e6dSmrg if (h != ie->h) 833e747e6dSmrg splitEntry (ie, grav2, grav1, ie->w, h); 843e747e6dSmrg if (w != ie->w) { 853e747e6dSmrg new = (IconEntry *)malloc (sizeof (IconEntry)); 863e747e6dSmrg new->twm_win = 0; 873e747e6dSmrg new->used = 0; 883e747e6dSmrg new->next = ie->next; 893e747e6dSmrg ie->next = new; 903e747e6dSmrg new->y = ie->y; 913e747e6dSmrg new->w = (ie->w - w); 923e747e6dSmrg new->h = ie->h; 933e747e6dSmrg ie->w = w; 943e747e6dSmrg if (grav1 == D_EAST) { 953e747e6dSmrg new->x = ie->x; 963e747e6dSmrg ie->x = new->x + new->w; 973e747e6dSmrg } else 983e747e6dSmrg new->x = ie->x + ie->w; 993e747e6dSmrg } 1003e747e6dSmrg break; 1013e747e6dSmrg } 1023e747e6dSmrg} 1033e747e6dSmrg 1043e747e6dSmrgint 1053e747e6dSmrgroundUp (int v, int multiple) 1063e747e6dSmrg{ 1073e747e6dSmrg return ((v + multiple - 1) / multiple) * multiple; 1083e747e6dSmrg} 1093e747e6dSmrg 1103e747e6dSmrgvoid 1113e747e6dSmrgPlaceIcon(TwmWindow *tmp_win, int def_x, int def_y, int *final_x, int *final_y) 1123e747e6dSmrg{ 1133e747e6dSmrg IconRegion *ir; 1143e747e6dSmrg IconEntry *ie; 1153e747e6dSmrg int w = 0, h = 0; 1163e747e6dSmrg 1173e747e6dSmrg ie = 0; 1183e747e6dSmrg for (ir = Scr->FirstRegion; ir; ir = ir->next) { 1193e747e6dSmrg w = roundUp (iconWidth (tmp_win), ir->stepx); 1203e747e6dSmrg h = roundUp (iconHeight (tmp_win), ir->stepy); 1213e747e6dSmrg for (ie = ir->entries; ie; ie=ie->next) { 1223e747e6dSmrg if (ie->used) 1233e747e6dSmrg continue; 1243e747e6dSmrg if (ie->w >= w && ie->h >= h) 1253e747e6dSmrg break; 1263e747e6dSmrg } 1273e747e6dSmrg if (ie) 1283e747e6dSmrg break; 1293e747e6dSmrg } 1303e747e6dSmrg if (ie) { 1313e747e6dSmrg splitEntry (ie, ir->grav1, ir->grav2, w, h); 1323e747e6dSmrg ie->used = 1; 1333e747e6dSmrg ie->twm_win = tmp_win; 1343e747e6dSmrg *final_x = ie->x + (ie->w - iconWidth (tmp_win)) / 2; 1353e747e6dSmrg *final_y = ie->y + (ie->h - iconHeight (tmp_win)) / 2; 1363e747e6dSmrg } else { 1373e747e6dSmrg *final_x = def_x; 1383e747e6dSmrg *final_y = def_y; 1393e747e6dSmrg } 1403e747e6dSmrg return; 1413e747e6dSmrg} 1423e747e6dSmrg 1433e747e6dSmrgstatic IconEntry * 1443e747e6dSmrgFindIconEntry (TwmWindow *tmp_win, IconRegion **irp) 1453e747e6dSmrg{ 1463e747e6dSmrg IconRegion *ir; 1473e747e6dSmrg IconEntry *ie; 1483e747e6dSmrg 1493e747e6dSmrg for (ir = Scr->FirstRegion; ir; ir = ir->next) { 1503e747e6dSmrg for (ie = ir->entries; ie; ie=ie->next) 1513e747e6dSmrg if (ie->twm_win == tmp_win) { 1523e747e6dSmrg if (irp) 1533e747e6dSmrg *irp = ir; 1543e747e6dSmrg return ie; 1553e747e6dSmrg } 1563e747e6dSmrg } 1573e747e6dSmrg return 0; 1583e747e6dSmrg} 1593e747e6dSmrg 1603e747e6dSmrgvoid 1613e747e6dSmrgIconUp (TwmWindow *tmp_win) 1623e747e6dSmrg{ 1633e747e6dSmrg int x, y; 1643e747e6dSmrg int defx, defy; 1653e747e6dSmrg struct IconRegion *ir; 1663e747e6dSmrg 1673e747e6dSmrg /* 1683e747e6dSmrg * If the client specified a particular location, let's use it (this might 1693e747e6dSmrg * want to be an option at some point). Otherwise, try to fit within the 1703e747e6dSmrg * icon region. 1713e747e6dSmrg */ 1723e747e6dSmrg if (tmp_win->wmhints && (tmp_win->wmhints->flags & IconPositionHint)) 1733e747e6dSmrg return; 1743e747e6dSmrg 1753e747e6dSmrg if (tmp_win->icon_moved) { 1763e747e6dSmrg if (!XGetGeometry (dpy, tmp_win->icon_w, &JunkRoot, &defx, &defy, 1773e747e6dSmrg &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth)) 1783e747e6dSmrg return; 1793e747e6dSmrg 1803e747e6dSmrg x = defx + ((int) JunkWidth) / 2; 1813e747e6dSmrg y = defy + ((int) JunkHeight) / 2; 1823e747e6dSmrg 1833e747e6dSmrg for (ir = Scr->FirstRegion; ir; ir = ir->next) { 1843e747e6dSmrg if (x >= ir->x && x < (ir->x + ir->w) && 1853e747e6dSmrg y >= ir->y && y < (ir->y + ir->h)) 1863e747e6dSmrg break; 1873e747e6dSmrg } 1883e747e6dSmrg if (!ir) return; /* outside icon regions, leave alone */ 1893e747e6dSmrg } 1903e747e6dSmrg 1913e747e6dSmrg defx = -100; 1923e747e6dSmrg defy = -100; 1933e747e6dSmrg PlaceIcon(tmp_win, defx, defy, &x, &y); 1943e747e6dSmrg if (x != defx || y != defy) { 1953e747e6dSmrg XMoveWindow (dpy, tmp_win->icon_w, x, y); 1963e747e6dSmrg tmp_win->icon_moved = FALSE; /* since we've restored it */ 1973e747e6dSmrg } 1983e747e6dSmrg} 1993e747e6dSmrg 2003e747e6dSmrgstatic IconEntry * 2013e747e6dSmrgprevIconEntry (IconEntry *ie, IconRegion *ir) 2023e747e6dSmrg{ 2033e747e6dSmrg IconEntry *ip; 2043e747e6dSmrg 2053e747e6dSmrg if (ie == ir->entries) 2063e747e6dSmrg return 0; 2073e747e6dSmrg for (ip = ir->entries; ip->next != ie; ip=ip->next) 2083e747e6dSmrg ; 2093e747e6dSmrg return ip; 2103e747e6dSmrg} 2113e747e6dSmrg 2123e747e6dSmrg/** 2133e747e6dSmrg * old is being freed; and is adjacent to ie. Merge 2143e747e6dSmrg * regions together 2153e747e6dSmrg */ 2163e747e6dSmrgstatic void 2173e747e6dSmrgmergeEntries (IconEntry *old, IconEntry *ie) 2183e747e6dSmrg{ 2193e747e6dSmrg if (old->y == ie->y) { 2203e747e6dSmrg ie->w = old->w + ie->w; 2213e747e6dSmrg if (old->x < ie->x) 2223e747e6dSmrg ie->x = old->x; 2233e747e6dSmrg } else { 2243e747e6dSmrg ie->h = old->h + ie->h; 2253e747e6dSmrg if (old->y < ie->y) 2263e747e6dSmrg ie->y = old->y; 2273e747e6dSmrg } 2283e747e6dSmrg} 2293e747e6dSmrg 2303e747e6dSmrgvoid 2313e747e6dSmrgIconDown (TwmWindow *tmp_win) 2323e747e6dSmrg{ 2333e747e6dSmrg IconEntry *ie, *ip, *in; 2343e747e6dSmrg IconRegion *ir; 2353e747e6dSmrg 2363e747e6dSmrg ie = FindIconEntry (tmp_win, &ir); 2373e747e6dSmrg if (ie) { 2383e747e6dSmrg ie->twm_win = 0; 2393e747e6dSmrg ie->used = 0; 2403e747e6dSmrg ip = prevIconEntry (ie, ir); 2413e747e6dSmrg in = ie->next; 2423e747e6dSmrg for (;;) { 2433e747e6dSmrg if (ip && ip->used == 0 && 2443e747e6dSmrg ((ip->x == ie->x && ip->w == ie->w) || 2453e747e6dSmrg (ip->y == ie->y && ip->h == ie->h))) 2463e747e6dSmrg { 2473e747e6dSmrg ip->next = ie->next; 2483e747e6dSmrg mergeEntries (ie, ip); 2493e747e6dSmrg free ((char *) ie); 2503e747e6dSmrg ie = ip; 2513e747e6dSmrg ip = prevIconEntry (ip, ir); 2523e747e6dSmrg } else if (in && in->used == 0 && 2533e747e6dSmrg ((in->x == ie->x && in->w == ie->w) || 2543e747e6dSmrg (in->y == ie->y && in->h == ie->h))) 2553e747e6dSmrg { 2563e747e6dSmrg ie->next = in->next; 2573e747e6dSmrg mergeEntries (in, ie); 2583e747e6dSmrg free ((char *) in); 2593e747e6dSmrg in = ie->next; 2603e747e6dSmrg } else 2613e747e6dSmrg break; 2623e747e6dSmrg } 2633e747e6dSmrg } 2643e747e6dSmrg} 2653e747e6dSmrg 2663e747e6dSmrgvoid 2673e747e6dSmrgAddIconRegion(char *geom, int grav1, int grav2, int stepx, int stepy) 2683e747e6dSmrg{ 2693e747e6dSmrg IconRegion *ir; 2703e747e6dSmrg int mask; 2713e747e6dSmrg 2723e747e6dSmrg ir = (IconRegion *)malloc(sizeof(IconRegion)); 2733e747e6dSmrg ir->next = NULL; 2743e747e6dSmrg if (Scr->LastRegion) 2753e747e6dSmrg Scr->LastRegion->next = ir; 2763e747e6dSmrg Scr->LastRegion = ir; 2773e747e6dSmrg if (!Scr->FirstRegion) 2783e747e6dSmrg Scr->FirstRegion = ir; 2793e747e6dSmrg 2803e747e6dSmrg ir->entries = NULL; 2813e747e6dSmrg ir->grav1 = grav1; 2823e747e6dSmrg ir->grav2 = grav2; 2833e747e6dSmrg if (stepx <= 0) 2843e747e6dSmrg stepx = 1; 2853e747e6dSmrg if (stepy <= 0) 2863e747e6dSmrg stepy = 1; 2873e747e6dSmrg ir->stepx = stepx; 2883e747e6dSmrg ir->stepy = stepy; 2893e747e6dSmrg ir->x = ir->y = ir->w = ir->h = 0; 2903e747e6dSmrg 2913e747e6dSmrg mask = XParseGeometry(geom, &ir->x, &ir->y, (unsigned int *)&ir->w, (unsigned int *)&ir->h); 2923e747e6dSmrg 2933e747e6dSmrg if (mask & XNegative) 2943e747e6dSmrg ir->x += Scr->MyDisplayWidth - ir->w; 2953e747e6dSmrg 2963e747e6dSmrg if (mask & YNegative) 2973e747e6dSmrg ir->y += Scr->MyDisplayHeight - ir->h; 2983e747e6dSmrg ir->entries = (IconEntry *)malloc(sizeof(IconEntry)); 2993e747e6dSmrg ir->entries->next = 0; 3003e747e6dSmrg ir->entries->x = ir->x; 3013e747e6dSmrg ir->entries->y = ir->y; 3023e747e6dSmrg ir->entries->w = ir->w; 3033e747e6dSmrg ir->entries->h = ir->h; 3043e747e6dSmrg ir->entries->twm_win = 0; 3053e747e6dSmrg ir->entries->used = 0; 3063e747e6dSmrg} 3073e747e6dSmrg 3083e747e6dSmrg#ifdef comment 3093e747e6dSmrgvoid 3103e747e6dSmrgFreeIconEntries (IconRegion *ir) 3113e747e6dSmrg{ 3123e747e6dSmrg IconEntry *ie, *tmp; 3133e747e6dSmrg 3143e747e6dSmrg for (ie = ir->entries; ie; ie=tmp) 3153e747e6dSmrg { 3163e747e6dSmrg tmp = ie->next; 3173e747e6dSmrg free ((char *) ie); 3183e747e6dSmrg } 3193e747e6dSmrg} 3203e747e6dSmrg 3213e747e6dSmrgvoid 3223e747e6dSmrgFreeIconRegions() 3233e747e6dSmrg{ 3243e747e6dSmrg IconRegion *ir, *tmp; 3253e747e6dSmrg 3263e747e6dSmrg for (ir = Scr->FirstRegion; ir != NULL;) 3273e747e6dSmrg { 3283e747e6dSmrg tmp = ir; 3293e747e6dSmrg FreeIconEntries (ir); 3303e747e6dSmrg ir = ir->next; 3313e747e6dSmrg free((char *) tmp); 3323e747e6dSmrg } 3333e747e6dSmrg Scr->FirstRegion = NULL; 3343e747e6dSmrg Scr->LastRegion = NULL; 3353e747e6dSmrg} 3363e747e6dSmrg#endif 3373e747e6dSmrg 3383e747e6dSmrgvoid 3393e747e6dSmrgCreateIconWindow(TwmWindow *tmp_win, int def_x, int def_y) 3403e747e6dSmrg{ 3413e747e6dSmrg unsigned long event_mask; 3423e747e6dSmrg unsigned long valuemask; /* mask for create windows */ 3433e747e6dSmrg XSetWindowAttributes attributes; /* attributes for create windows */ 3443e747e6dSmrg Pixmap pm = None; /* tmp pixmap variable */ 3453e747e6dSmrg int final_x, final_y; 3463e747e6dSmrg int x; 3473e747e6dSmrg 3483e747e6dSmrg 3493e747e6dSmrg FB(tmp_win->iconc.fore, tmp_win->iconc.back); 3503e747e6dSmrg 3513e747e6dSmrg tmp_win->forced = FALSE; 3523e747e6dSmrg tmp_win->icon_not_ours = FALSE; 3533e747e6dSmrg 3543e747e6dSmrg /* now go through the steps to get an icon window, if ForceIcon is 3553e747e6dSmrg * set, then no matter what else is defined, the bitmap from the 3563e747e6dSmrg * .twmrc file is used 3573e747e6dSmrg */ 3583e747e6dSmrg if (Scr->ForceIcon) 3593e747e6dSmrg { 3603e747e6dSmrg char *icon_name; 3613e747e6dSmrg Pixmap bm; 3623e747e6dSmrg 3633e747e6dSmrg icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name); 3643e747e6dSmrg if (icon_name == NULL) 3653e747e6dSmrg icon_name = LookInList(Scr->IconNames, tmp_win->full_name, 3663e747e6dSmrg &tmp_win->class); 3673e747e6dSmrg 3683e747e6dSmrg bm = None; 3693e747e6dSmrg if (icon_name != NULL) 3703e747e6dSmrg { 3713e747e6dSmrg if ((bm = (Pixmap)LookInNameList(Scr->Icons, icon_name)) == None) 3723e747e6dSmrg { 3733e747e6dSmrg if ((bm = GetBitmap (icon_name)) != None) 3743e747e6dSmrg AddToList(&Scr->Icons, icon_name, (char *)bm); 3753e747e6dSmrg } 3763e747e6dSmrg } 3773e747e6dSmrg 3783e747e6dSmrg if (bm != None) 3793e747e6dSmrg { 3803e747e6dSmrg XGetGeometry(dpy, bm, &JunkRoot, &JunkX, &JunkY, 3813e747e6dSmrg (unsigned int *) &tmp_win->icon_width, (unsigned int *)&tmp_win->icon_height, 3823e747e6dSmrg &JunkBW, &JunkDepth); 3833e747e6dSmrg 3843e747e6dSmrg pm = XCreatePixmap(dpy, Scr->Root, tmp_win->icon_width, 3853e747e6dSmrg tmp_win->icon_height, Scr->d_depth); 3863e747e6dSmrg 3873e747e6dSmrg /* the copy plane works on color ! */ 3883e747e6dSmrg XCopyPlane(dpy, bm, pm, Scr->NormalGC, 3893e747e6dSmrg 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 ); 3903e747e6dSmrg 3913e747e6dSmrg tmp_win->forced = TRUE; 3923e747e6dSmrg } 3933e747e6dSmrg } 3943e747e6dSmrg 3953e747e6dSmrg /* if the pixmap is still NULL, we didn't get one from the above code, 3963e747e6dSmrg * that could mean that ForceIcon was not set, or that the window 3973e747e6dSmrg * was not in the Icons list, now check the WM hints for an icon 3983e747e6dSmrg */ 3993e747e6dSmrg if (pm == None && tmp_win->wmhints && 4003e747e6dSmrg tmp_win->wmhints->flags & IconPixmapHint) 4013e747e6dSmrg { 4023e747e6dSmrg 4033e747e6dSmrg XGetGeometry(dpy, tmp_win->wmhints->icon_pixmap, 4043e747e6dSmrg &JunkRoot, &JunkX, &JunkY, 4053e747e6dSmrg (unsigned int *)&tmp_win->icon_width, (unsigned int *)&tmp_win->icon_height, &JunkBW, &JunkDepth); 4063e747e6dSmrg 4073e747e6dSmrg pm = XCreatePixmap(dpy, Scr->Root, 4083e747e6dSmrg tmp_win->icon_width, tmp_win->icon_height, 4093e747e6dSmrg Scr->d_depth); 4103e747e6dSmrg 4113e747e6dSmrg XCopyPlane(dpy, tmp_win->wmhints->icon_pixmap, pm, Scr->NormalGC, 4123e747e6dSmrg 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 ); 4133e747e6dSmrg } 4143e747e6dSmrg 4153e747e6dSmrg /* if we still haven't got an icon, let's look in the Icon list 4163e747e6dSmrg * if ForceIcon is not set 4173e747e6dSmrg */ 4183e747e6dSmrg if (pm == None && !Scr->ForceIcon) 4193e747e6dSmrg { 4203e747e6dSmrg char *icon_name; 4213e747e6dSmrg Pixmap bm; 4223e747e6dSmrg 4233e747e6dSmrg icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name); 4243e747e6dSmrg if (icon_name == NULL) 4253e747e6dSmrg icon_name = LookInList(Scr->IconNames, tmp_win->full_name, 4263e747e6dSmrg &tmp_win->class); 4273e747e6dSmrg 4283e747e6dSmrg bm = None; 4293e747e6dSmrg if (icon_name != NULL) 4303e747e6dSmrg { 4313e747e6dSmrg if ((bm = (Pixmap)LookInNameList(Scr->Icons, icon_name)) == None) 4323e747e6dSmrg { 4333e747e6dSmrg if ((bm = GetBitmap (icon_name)) != None) 4343e747e6dSmrg AddToList(&Scr->Icons, icon_name, (char *)bm); 4353e747e6dSmrg } 4363e747e6dSmrg } 4373e747e6dSmrg 4383e747e6dSmrg if (bm != None) 4393e747e6dSmrg { 4403e747e6dSmrg XGetGeometry(dpy, bm, &JunkRoot, &JunkX, &JunkY, 4413e747e6dSmrg (unsigned int *)&tmp_win->icon_width, (unsigned int *)&tmp_win->icon_height, 4423e747e6dSmrg &JunkBW, &JunkDepth); 4433e747e6dSmrg 4443e747e6dSmrg pm = XCreatePixmap(dpy, Scr->Root, tmp_win->icon_width, 4453e747e6dSmrg tmp_win->icon_height, Scr->d_depth); 4463e747e6dSmrg 4473e747e6dSmrg /* the copy plane works on color ! */ 4483e747e6dSmrg XCopyPlane(dpy, bm, pm, Scr->NormalGC, 4493e747e6dSmrg 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 ); 4503e747e6dSmrg } 4513e747e6dSmrg } 4523e747e6dSmrg 4533e747e6dSmrg /* if we still don't have an icon, assign the UnknownIcon */ 4543e747e6dSmrg 4553e747e6dSmrg if (pm == None && Scr->UnknownPm != None) 4563e747e6dSmrg { 4573e747e6dSmrg tmp_win->icon_width = Scr->UnknownWidth; 4583e747e6dSmrg tmp_win->icon_height = Scr->UnknownHeight; 4593e747e6dSmrg 4603e747e6dSmrg pm = XCreatePixmap(dpy, Scr->Root, tmp_win->icon_width, 4613e747e6dSmrg tmp_win->icon_height, Scr->d_depth); 4623e747e6dSmrg 4633e747e6dSmrg /* the copy plane works on color ! */ 4643e747e6dSmrg XCopyPlane(dpy, Scr->UnknownPm, pm, Scr->NormalGC, 4653e747e6dSmrg 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 ); 4663e747e6dSmrg } 4673e747e6dSmrg 4683e747e6dSmrg if (pm == None) 4693e747e6dSmrg { 4703e747e6dSmrg tmp_win->icon_height = 0; 4713e747e6dSmrg tmp_win->icon_width = 0; 4723e747e6dSmrg valuemask = 0; 4733e747e6dSmrg } 4743e747e6dSmrg else 4753e747e6dSmrg { 4763e747e6dSmrg valuemask = CWBackPixmap; 4773e747e6dSmrg attributes.background_pixmap = pm; 4783e747e6dSmrg } 4793e747e6dSmrg 4803e747e6dSmrg tmp_win->icon_w_width = MyFont_TextWidth(&Scr->IconFont, 4813e747e6dSmrg tmp_win->icon_name, strlen(tmp_win->icon_name)); 4823e747e6dSmrg 4833e747e6dSmrg tmp_win->icon_w_width += 6; 4843e747e6dSmrg if (tmp_win->icon_w_width < tmp_win->icon_width) 4853e747e6dSmrg { 4863e747e6dSmrg tmp_win->icon_x = (tmp_win->icon_width - tmp_win->icon_w_width)/2; 4873e747e6dSmrg tmp_win->icon_x += 3; 4883e747e6dSmrg tmp_win->icon_w_width = tmp_win->icon_width; 4893e747e6dSmrg } 4903e747e6dSmrg else 4913e747e6dSmrg { 4923e747e6dSmrg tmp_win->icon_x = 3; 4933e747e6dSmrg } 4943e747e6dSmrg tmp_win->icon_y = tmp_win->icon_height + Scr->IconFont.height; 4953e747e6dSmrg tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 4; 4963e747e6dSmrg 4973e747e6dSmrg event_mask = 0; 4983e747e6dSmrg if (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint) 4993e747e6dSmrg { 5003e747e6dSmrg tmp_win->icon_w = tmp_win->wmhints->icon_window; 5013e747e6dSmrg if (tmp_win->forced || 5023e747e6dSmrg XGetGeometry(dpy, tmp_win->icon_w, &JunkRoot, &JunkX, &JunkY, 5033e747e6dSmrg (unsigned int *)&tmp_win->icon_w_width, (unsigned int *)&tmp_win->icon_w_height, 5043e747e6dSmrg &JunkBW, &JunkDepth) == 0) 5053e747e6dSmrg { 5063e747e6dSmrg tmp_win->icon_w = None; 5073e747e6dSmrg tmp_win->wmhints->flags &= ~IconWindowHint; 5083e747e6dSmrg } 5093e747e6dSmrg else 5103e747e6dSmrg { 5113e747e6dSmrg tmp_win->icon_not_ours = TRUE; 5123e747e6dSmrg event_mask = EnterWindowMask | LeaveWindowMask; 5133e747e6dSmrg } 5143e747e6dSmrg } 5153e747e6dSmrg else 5163e747e6dSmrg { 5173e747e6dSmrg tmp_win->icon_w = None; 5183e747e6dSmrg } 5193e747e6dSmrg 5203e747e6dSmrg if (tmp_win->icon_w == None) 5213e747e6dSmrg { 5223e747e6dSmrg tmp_win->icon_w = XCreateSimpleWindow(dpy, Scr->Root, 5233e747e6dSmrg 0,0, 5243e747e6dSmrg tmp_win->icon_w_width, tmp_win->icon_w_height, 5253e747e6dSmrg Scr->IconBorderWidth, tmp_win->icon_border, tmp_win->iconc.back); 5263e747e6dSmrg event_mask = ExposureMask; 5273e747e6dSmrg } 5283e747e6dSmrg 5293e747e6dSmrg XSelectInput (dpy, tmp_win->icon_w, 5303e747e6dSmrg KeyPressMask | ButtonPressMask | ButtonReleaseMask | 5313e747e6dSmrg event_mask); 5323e747e6dSmrg 5333e747e6dSmrg tmp_win->icon_bm_w = None; 5343e747e6dSmrg if (pm != None && 5353e747e6dSmrg (! (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint))) 5363e747e6dSmrg { 5373e747e6dSmrg int y; 5383e747e6dSmrg 5393e747e6dSmrg y = 0; 5403e747e6dSmrg if (tmp_win->icon_w_width == tmp_win->icon_width) 5413e747e6dSmrg x = 0; 5423e747e6dSmrg else 5433e747e6dSmrg x = (tmp_win->icon_w_width - tmp_win->icon_width)/2; 5443e747e6dSmrg 5453e747e6dSmrg tmp_win->icon_bm_w = XCreateWindow (dpy, tmp_win->icon_w, x, y, 5463e747e6dSmrg (unsigned int)tmp_win->icon_width, 5473e747e6dSmrg (unsigned int)tmp_win->icon_height, 5483e747e6dSmrg (unsigned int) 0, Scr->d_depth, 5493e747e6dSmrg (unsigned int) CopyFromParent, 5503e747e6dSmrg Scr->d_visual, valuemask, 5513e747e6dSmrg &attributes); 5523e747e6dSmrg } 5533e747e6dSmrg 5543e747e6dSmrg /* I need to figure out where to put the icon window now, because 5553e747e6dSmrg * getting here means that I am going to make the icon visible 5563e747e6dSmrg */ 5573e747e6dSmrg if (tmp_win->wmhints && 5583e747e6dSmrg tmp_win->wmhints->flags & IconPositionHint) 5593e747e6dSmrg { 5603e747e6dSmrg final_x = tmp_win->wmhints->icon_x; 5613e747e6dSmrg final_y = tmp_win->wmhints->icon_y; 5623e747e6dSmrg } 5633e747e6dSmrg else 5643e747e6dSmrg { 5653e747e6dSmrg PlaceIcon(tmp_win, def_x, def_y, &final_x, &final_y); 5663e747e6dSmrg } 5673e747e6dSmrg 5683e747e6dSmrg if (final_x > Scr->MyDisplayWidth) 5693e747e6dSmrg final_x = Scr->MyDisplayWidth - tmp_win->icon_w_width - 5703e747e6dSmrg (2 * Scr->IconBorderWidth); 5713e747e6dSmrg 5723e747e6dSmrg if (final_y > Scr->MyDisplayHeight) 5733e747e6dSmrg final_y = Scr->MyDisplayHeight - tmp_win->icon_height - 5743e747e6dSmrg Scr->IconFont.height - 4 - (2 * Scr->IconBorderWidth); 5753e747e6dSmrg 5763e747e6dSmrg XMoveWindow(dpy, tmp_win->icon_w, final_x, final_y); 5773e747e6dSmrg tmp_win->iconified = TRUE; 5783e747e6dSmrg 5793e747e6dSmrg XMapSubwindows(dpy, tmp_win->icon_w); 5803e747e6dSmrg XSaveContext(dpy, tmp_win->icon_w, TwmContext, (caddr_t)tmp_win); 5813e747e6dSmrg XSaveContext(dpy, tmp_win->icon_w, ScreenContext, (caddr_t)Scr); 5823e747e6dSmrg XDefineCursor(dpy, tmp_win->icon_w, Scr->IconCursor); 5833e747e6dSmrg if (pm) XFreePixmap (dpy, pm); 5843e747e6dSmrg return; 5853e747e6dSmrg} 586