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