chiark / gitweb /
debian/changelog: start -4~
[vtwm.git] / icons.c
1 /*
2  * Copyright 1989 Massachusetts Institute of Technology
3  *
4  * Permission to use, copy, modify, and distribute this software and its
5  * documentation for any purpose and without fee is hereby granted, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of M.I.T. not be used in advertising
9  * or publicity pertaining to distribution of the software without specific,
10  * written prior permission.  M.I.T. makes no representations about the
11  * suitability of this software for any purpose.  It is provided "as is"
12  * without express or implied warranty.
13  *
14  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
16  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
18  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
19  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21
22 /**********************************************************************
23  *
24  * $XConsortium: icons.c,v 1.22 91/07/12 09:58:38 dave Exp $
25  *
26  * Icon releated routines
27  *
28  * 10-Apr-89 Tom LaStrange        Initial Version.
29  *
30  **********************************************************************/
31
32 #include <stdio.h>
33 #include <string.h>
34 #include "twm.h"
35 #include "screen.h"
36 #include "regions.h"
37 #include "list.h"
38 #include "gram.h"
39 #include "parse.h"
40 #include "util.h"
41
42 extern void splitRegionEntry();
43 extern int roundEntryUp();
44 extern RegionEntry *prevRegionEntry();
45 extern void mergeRegionEntries();
46 extern void downRegionEntry();
47 extern RootRegion *AddRegion();
48
49 #define iconWidth(w)    (Scr->IconBorderWidth * 2 + w->icon_w_width)
50 #define iconHeight(w)   (Scr->IconBorderWidth * 2 + w->icon_w_height)
51
52 void PlaceIcon(tmp_win, def_x, def_y, final_x, final_y)
53 TwmWindow *tmp_win;
54 int def_x, def_y;
55 int *final_x, *final_y;
56 {
57     RootRegion  *rr;
58     RegionEntry *re;
59     int         w, h;
60
61     re = 0;
62     for (rr = Scr->FirstIconRegion; rr; rr = rr->next) {
63         w = roundEntryUp (iconWidth (tmp_win), rr->stepx);
64         h = roundEntryUp (iconHeight (tmp_win), rr->stepy);
65         for (re = rr->entries; re; re=re->next) {
66             if (re->usedby)
67                 continue;
68 /* don't include grid spacing - djhjr - 5/22/99
69             if (re->w >= w && re->h >= h)
70 */
71             if (re->w >= iconWidth(tmp_win) && re->h >= iconHeight(tmp_win))
72                 break;
73         }
74         if (re)
75             break;
76     }
77     if (re) {
78         splitRegionEntry (re, rr->grav1, rr->grav2, w, h);
79         re->usedby = USEDBY_TWIN;
80         re->u.twm_win = tmp_win;
81
82 /* evenly spaced icon placement - djhjr - 4/24/99
83         *final_x = re->x + (re->w - iconWidth (tmp_win)) / 2;
84         *final_y = re->y + (re->h - iconHeight (tmp_win)) / 2;
85 */
86         *final_x = re->x;
87         *final_y = re->y;
88
89         /* adjust for region gravity - djhjr 4/26/99 */
90         if (rr->grav2 == D_EAST)
91                 *final_x += re->w - iconWidth(tmp_win);
92         if (rr->grav1 == D_SOUTH)
93                 *final_y += re->h - iconHeight(tmp_win);
94
95     } else {
96         *final_x = def_x;
97         *final_y = def_y;
98     }
99     return;
100 }
101
102 static RegionEntry *
103 FindIconEntry (tmp_win, rrp)
104     TwmWindow   *tmp_win;
105     RootRegion  **rrp;
106 {
107     RootRegion  *rr;
108     RegionEntry *re;
109
110     for (rr = Scr->FirstIconRegion; rr; rr = rr->next) {
111         for (re = rr->entries; re; re=re->next)
112             if (re->u.twm_win == tmp_win) {
113                 if (rrp)
114                     *rrp = rr;
115                 return re;
116             }
117     }
118     return 0;
119 }
120
121 void IconUp (tmp_win)
122     TwmWindow   *tmp_win;
123 {
124     int         x, y;
125     int         defx, defy;
126     struct RootRegion *rr;
127
128     /*
129      * If the client specified a particular location, let's use it (this might
130      * want to be an option at some point).  Otherwise, try to fit within the
131      * icon region.
132      */
133     if (tmp_win->wmhints && (tmp_win->wmhints->flags & IconPositionHint))
134       return;
135
136     if (tmp_win->icon_moved) {
137         if (!XGetGeometry (dpy, tmp_win->icon_w, &JunkRoot, &defx, &defy,
138                            &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth))
139           return;
140
141 /* evenly spaced icon placement - djhjr - 4/24/99
142         x = defx + ((int) JunkWidth) / 2;
143         y = defy + ((int) JunkHeight) / 2;
144 */
145         x = defx;
146         y = defy;
147
148         for (rr = Scr->FirstIconRegion; rr; rr = rr->next) {
149             if (x >= rr->x && x < (rr->x + rr->w) &&
150                 y >= rr->y && y < (rr->y + rr->h))
151               break;
152         }
153         if (!rr) return;                /* outside icon regions, leave alone */
154     }
155
156     defx = -100;
157     defy = -100;
158     PlaceIcon(tmp_win, defx, defy, &x, &y);
159     if (x != defx || y != defy) {
160         XMoveWindow (dpy, tmp_win->icon_w, x, y);
161         tmp_win->icon_moved = FALSE;    /* since we've restored it */
162     }
163 }
164
165 void
166 IconDown (tmp_win)
167     TwmWindow   *tmp_win;
168 {
169     RegionEntry *re;
170     RootRegion  *rr;
171
172     re = FindIconEntry (tmp_win, &rr);
173     if (re)
174         downRegionEntry(rr, re);
175 }
176
177 void
178 AddIconRegion(geom, grav1, grav2, stepx, stepy)
179 char *geom;
180 int grav1, grav2, stepx, stepy;
181 {
182     RootRegion *rr;
183
184     rr = AddRegion(geom, grav1, grav2, stepx, stepy);
185
186     if (Scr->LastIconRegion)
187         Scr->LastIconRegion->next = rr;
188     Scr->LastIconRegion = rr;
189     if (!Scr->FirstIconRegion)
190         Scr->FirstIconRegion = rr;
191 }
192
193 #ifdef ORIGINAL_PIXMAPS
194 void CreateIconWindow(tmp_win, def_x, def_y)
195 TwmWindow *tmp_win;
196 int def_x, def_y;
197 {
198     unsigned long event_mask;
199     unsigned long valuemask;            /* mask for create windows */
200     XSetWindowAttributes attributes;    /* attributes for create windows */
201     Pixmap pm = None;                   /* tmp pixmap variable */
202     int final_x, final_y;
203     int x;
204
205         /* djhjr - 4/27/96 */
206     GetColorFromList(Scr->IconBorderColorL, tmp_win->full_name, &tmp_win->class,
207         &tmp_win->icon_border);
208     GetColorFromList(Scr->IconForegroundL, tmp_win->full_name, &tmp_win->class,
209         &tmp_win->iconc.fore);
210     GetColorFromList(Scr->IconBackgroundL, tmp_win->full_name, &tmp_win->class,
211         &tmp_win->iconc.back);
212
213 /* djhjr - 5/5/98
214     if (Scr->use3Diconmanagers && !Scr->BeNiceToColormap) GetShadeColors(&tmp_win->iconc);
215 */
216         /* was 'Scr->use3Dicons' - djhjr - 8/11/98 */
217         if (Scr->IconBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors(&tmp_win->iconc);
218
219     FB(tmp_win->iconc.fore, tmp_win->iconc.back);
220
221     tmp_win->forced = FALSE;
222     tmp_win->icon_not_ours = FALSE;
223
224     /* now go through the steps to get an icon window,  if ForceIcon is 
225      * set, then no matter what else is defined, the bitmap from the
226      * .twmrc file is used
227      */
228     if (Scr->ForceIcon)
229     {
230         char *icon_name;
231         Pixmap bm;
232
233         icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name);
234         if (icon_name == NULL)
235             icon_name = LookInList(Scr->IconNames, tmp_win->full_name,
236                                    &tmp_win->class);
237
238         bm = None;
239         if (icon_name != NULL)
240         {
241             if ((bm = (Pixmap)LookInNameList(Scr->Icons, icon_name)) == None)
242             {
243                 if ((bm = GetBitmap (icon_name)) != None)
244                     /* added 'type' argument - djhjr - 10/20/01 */
245                     AddToList(&Scr->Icons, icon_name, LTYPE_EXACT_NAME,
246                                 (char *)bm);
247             }
248         }
249
250         if (bm != None)
251         {
252             XGetGeometry(dpy, bm, &JunkRoot, &JunkX, &JunkY,
253                 (unsigned int *) &tmp_win->icon_width, (unsigned int *)&tmp_win->icon_height,
254                 &JunkBW, &JunkDepth);
255
256             pm = XCreatePixmap(dpy, Scr->Root, tmp_win->icon_width,
257                 tmp_win->icon_height, Scr->d_depth);
258
259             /* the copy plane works on color ! */
260             XCopyPlane(dpy, bm, pm, Scr->NormalGC,
261                 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 );
262
263             tmp_win->forced = TRUE;
264         }
265     }
266
267     /* if the pixmap is still NULL, we didn't get one from the above code,
268      * that could mean that ForceIcon was not set, or that the window
269      * was not in the Icons list, now check the WM hints for an icon
270      */
271     if (pm == None && tmp_win->wmhints &&
272         tmp_win->wmhints->flags & IconPixmapHint)
273     {
274     
275         XGetGeometry(dpy,   tmp_win->wmhints->icon_pixmap,
276              &JunkRoot, &JunkX, &JunkY,
277              (unsigned int *)&tmp_win->icon_width, (unsigned int *)&tmp_win->icon_height, &JunkBW, &JunkDepth);
278
279         pm = XCreatePixmap(dpy, Scr->Root,
280                            tmp_win->icon_width, tmp_win->icon_height,
281                            Scr->d_depth);
282
283         XCopyPlane(dpy, tmp_win->wmhints->icon_pixmap, pm, Scr->NormalGC,
284             0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 );
285     }
286
287     /* if we still haven't got an icon, let's look in the Icon list 
288      * if ForceIcon is not set
289      */
290     if (pm == None && !Scr->ForceIcon)
291     {
292         char *icon_name;
293         Pixmap bm;
294
295         icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name);
296         if (icon_name == NULL)
297             icon_name = LookInList(Scr->IconNames, tmp_win->full_name,
298                                    &tmp_win->class);
299
300         bm = None;
301         if (icon_name != NULL)
302         {
303             if ((bm = (Pixmap)LookInNameList(Scr->Icons, icon_name)) == None)
304             {
305                 if ((bm = GetBitmap (icon_name)) != None)
306                     /* added 'type' argument - djhjr - 10/20/01 */
307                     AddToList(&Scr->Icons, icon_name, LTYPE_EXACT_NAME,
308                                 (char *)bm);
309             }
310         }
311
312         if (bm != None)
313         {
314             XGetGeometry(dpy, bm, &JunkRoot, &JunkX, &JunkY,
315                 (unsigned int *)&tmp_win->icon_width, (unsigned int *)&tmp_win->icon_height,
316                 &JunkBW, &JunkDepth);
317
318             pm = XCreatePixmap(dpy, Scr->Root, tmp_win->icon_width,
319                 tmp_win->icon_height, Scr->d_depth);
320
321             /* the copy plane works on color ! */
322             XCopyPlane(dpy, bm, pm, Scr->NormalGC,
323                 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 );
324         }
325     }
326
327     /* if we still don't have an icon, assign the UnknownIcon */
328
329     if (pm == None && Scr->UnknownPm != None)
330     {
331         tmp_win->icon_width = Scr->UnknownWidth;
332         tmp_win->icon_height = Scr->UnknownHeight;
333
334         pm = XCreatePixmap(dpy, Scr->Root, tmp_win->icon_width,
335             tmp_win->icon_height, Scr->d_depth);
336
337         /* the copy plane works on color ! */
338         XCopyPlane(dpy, Scr->UnknownPm, pm, Scr->NormalGC,
339             0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 );
340     }
341
342     if (pm == None)
343     {
344         tmp_win->icon_height = 0;
345         tmp_win->icon_width = 0;
346         valuemask = 0;
347     }
348     else
349     {
350         /* added pixel specs - djhjr - 12/28/98 */
351         valuemask = CWBackPixmap | CWBackPixel;
352         attributes.background_pixmap = pm;
353         attributes.background_pixel = tmp_win->iconc.fore;
354     }
355
356 /* djhjr - 9/14/03 */
357 #ifndef NO_I18N_SUPPORT
358     tmp_win->icon_w_width = MyFont_TextWidth(&Scr->IconFont,
359 #else
360     tmp_win->icon_w_width = XTextWidth(Scr->IconFont.font,
361 #endif
362         tmp_win->icon_name, strlen(tmp_win->icon_name));
363
364 /* djhjr - 6/11/96
365     tmp_win->icon_w_width += 6;
366     if (tmp_win->icon_w_width < tmp_win->icon_width)
367     {
368                 tmp_win->icon_x = (tmp_win->icon_width - tmp_win->icon_w_width)/2;
369                 tmp_win->icon_x += 3;
370                 tmp_win->icon_w_width = tmp_win->icon_width;
371     }
372     else
373         {
374                 tmp_win->icon_x = 3;
375         }
376 */
377     tmp_win->icon_w_width += 8;
378     if (tmp_win->icon_w_width < tmp_win->icon_width + 8)
379     {
380                 tmp_win->icon_x = (((tmp_win->icon_width + 8) - tmp_win->icon_w_width)/2) + 4;
381                 tmp_win->icon_w_width = tmp_win->icon_width + 8;
382     }
383     else
384                 tmp_win->icon_x = 4;
385
386 /* djhjr - 6/11/96
387     tmp_win->icon_y = tmp_win->icon_height + Scr->IconFont.height;
388 */
389     tmp_win->icon_y = tmp_win->icon_height + Scr->IconFont.height + 2;
390
391 /* djhjr - 4/27/96
392     tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 4;
393 */
394 /* djhjr - 6/11/96
395     tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 6;
396 */
397     tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 8;
398
399     event_mask = 0;
400     if (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint)
401     {
402         tmp_win->icon_w = tmp_win->wmhints->icon_window;
403         if (tmp_win->forced ||
404             XGetGeometry(dpy, tmp_win->icon_w, &JunkRoot, &JunkX, &JunkY,
405                      (unsigned int *)&tmp_win->icon_w_width, (unsigned int *)&tmp_win->icon_w_height,
406                      &JunkBW, &JunkDepth) == 0)
407         {
408             tmp_win->icon_w = None;
409             tmp_win->wmhints->flags &= ~IconWindowHint;
410         }
411         else
412         {
413             tmp_win->icon_not_ours = TRUE;
414             event_mask = EnterWindowMask | LeaveWindowMask;
415         }
416     }
417     else
418     {
419         tmp_win->icon_w = None;
420     }
421
422         /* djhjr - 5/5/98 */
423         /* was 'Scr->use3Dicons' and 'Scr->BorderBevelWidth' - djhjr - 8/11/98 */
424         if (Scr->IconBevelWidth > 0)
425         {
426                 tmp_win->icon_w_width += 2 * Scr->IconBevelWidth;
427                 tmp_win->icon_w_height += 2 * Scr->IconBevelWidth;
428
429                 tmp_win->icon_x += Scr->IconBevelWidth;
430                 tmp_win->icon_y += Scr->IconBevelWidth;
431         }
432
433     if (tmp_win->icon_w == None)
434     {
435         tmp_win->icon_w = XCreateSimpleWindow(dpy, Scr->Root,
436             0,0,
437             tmp_win->icon_w_width, tmp_win->icon_w_height,
438             Scr->IconBorderWidth, tmp_win->icon_border, tmp_win->iconc.back);
439         event_mask = ExposureMask;
440     }
441
442     XSelectInput (dpy, tmp_win->icon_w,
443                   KeyPressMask | ButtonPressMask | ButtonReleaseMask |
444                   event_mask);
445
446     tmp_win->icon_bm_w = None;
447     if (pm != None &&
448         (! (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint)))
449     {
450         int y;
451
452 /* djhjr - 6/11/96
453         y = 0;
454 */
455         y = 4;
456
457         if (tmp_win->icon_w_width == tmp_win->icon_width)
458             x = 0;
459         else
460             x = (tmp_win->icon_w_width - tmp_win->icon_width)/2;
461
462         /* djhjr - 5/5/98 */
463         /* was 'Scr->use3Dicons' and 'Scr->BorderBevelWidth' - djhjr - 8/11/98 */
464         if (Scr->IconBevelWidth > 0)
465                 y += Scr->IconBevelWidth;
466
467         tmp_win->icon_bm_w = XCreateWindow (dpy, tmp_win->icon_w, x, y,
468                                             (unsigned int)tmp_win->icon_width,
469                                             (unsigned int)tmp_win->icon_height,
470                                             (unsigned int) 0, Scr->d_depth,
471                                             (unsigned int) CopyFromParent,
472                                             Scr->d_visual, valuemask,
473                                             &attributes);
474     }
475
476     /* I need to figure out where to put the icon window now, because 
477      * getting here means that I am going to make the icon visible
478      */
479     if (tmp_win->wmhints &&
480         tmp_win->wmhints->flags & IconPositionHint)
481     {
482         final_x = tmp_win->wmhints->icon_x;
483         final_y = tmp_win->wmhints->icon_y;
484     }
485     else
486     {
487         PlaceIcon(tmp_win, def_x, def_y, &final_x, &final_y);
488     }
489
490     if (final_x > Scr->MyDisplayWidth)
491         final_x = Scr->MyDisplayWidth - tmp_win->icon_w_width -
492             (2 * Scr->IconBorderWidth);
493
494     if (final_y > Scr->MyDisplayHeight)
495         final_y = Scr->MyDisplayHeight - tmp_win->icon_height -
496             Scr->IconFont.height - 4 - (2 * Scr->IconBorderWidth);
497
498     XMoveWindow(dpy, tmp_win->icon_w, final_x, final_y);
499     tmp_win->iconified = TRUE;
500
501     XMapSubwindows(dpy, tmp_win->icon_w);
502     XSaveContext(dpy, tmp_win->icon_w, TwmContext, (caddr_t)tmp_win);
503     XSaveContext(dpy, tmp_win->icon_w, ScreenContext, (caddr_t)Scr);
504     XDefineCursor(dpy, tmp_win->icon_w, Scr->IconCursor);
505     if (pm) XFreePixmap (dpy, pm);
506     return;
507 }
508 #else /* ORIGINAL_PIXMAPS */
509 /*
510  * to help clean up CreateIconWindow() below - djhjr - 8/13/98
511  * added background color and XPM indicator - djhjr - 12/28/98
512  */
513 Image *
514 GetIconImage(name, background, numcolors)
515 char *name;
516 Pixel background;
517 unsigned int *numcolors;
518 {
519     Image *iconimage;
520         GC gc;
521     Pixmap bm;
522     int bitmap_height, bitmap_width;
523
524         iconimage = (Image *)LookInNameList(Scr->Icons, name);
525         if (iconimage == NULL)
526         {
527                 bm = FindBitmap(name, &bitmap_width, &bitmap_height);
528                 if (bm != None)
529                 {
530                         iconimage = (Image *)malloc(sizeof(Image));
531                         iconimage->mask = None;
532                         iconimage->height = bitmap_height;
533                         iconimage->width = bitmap_width;
534                         iconimage->pixmap = XCreatePixmap(dpy, Scr->Root, bitmap_width,
535                                         bitmap_height, Scr->d_depth);
536             
537                         XGetGeometry(dpy, bm,
538                                         &JunkRoot, &JunkX, &JunkY,
539                                         &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth);
540
541                         /*
542                          * XCopyArea() seems to be necessary for some apps that change
543                          * their icons - djhjr - rem'd 8/23/98, re-instated 11/15/98
544                          */
545                         if (JunkDepth == Scr->d_depth) 
546                                 XCopyArea(dpy, bm, iconimage->pixmap,
547                                                 Scr->NormalGC, 0, 0, iconimage->width, iconimage->height,
548                                                 0, 0);
549                         else
550                                 XCopyPlane(dpy, bm, iconimage->pixmap,
551                                                 Scr->NormalGC, 0, 0, iconimage->width, iconimage->height,
552                                                 0, 0, 1);
553
554                         iconimage->mask = XCreatePixmap(dpy, Scr->Root,
555                                         iconimage->width, iconimage->height, 1);
556                         if (iconimage->mask)
557                         {
558                                 gc = XCreateGC(dpy, iconimage->mask, 0, NULL);
559                                 if (gc)
560                                 {
561                                         XCopyArea(dpy, bm, iconimage->mask,
562                                                         gc, 0, 0, iconimage->width, iconimage->height, 0, 0);
563                                         XFreeGC (dpy, gc);
564                                 }
565                         }
566
567                         XFreePixmap(dpy, bm);
568                 }
569 #ifndef NO_XPM_SUPPORT
570                 else
571                 {
572                         /* added color argument - djhjr - 9/28/99 */
573                         iconimage = FindImage(name, background);
574                 }
575 #endif
576
577                 if (iconimage != NULL)
578                         /* added 'type' argument - djhjr - 10/20/01 */
579                         AddToList(&Scr->Icons, name, LTYPE_EXACT_NAME,
580                                         (char *)iconimage);
581         }
582
583         /* djhjr - 12/28/98 */
584         *numcolors = 0;
585 #ifndef NO_XPM_SUPPORT
586         if (iconimage != NULL)
587                 *numcolors = SetPixmapsBackground(iconimage, Scr->Root, background);
588 #endif
589
590         return (iconimage);
591 }
592
593 /*
594  * Submitted by Jason Gloudon
595  */
596 void
597 CreateIconWindow(tmp_win, def_x, def_y)
598 TwmWindow *tmp_win;
599 int def_x, def_y;
600 {
601     unsigned long event_mask;
602     unsigned long valuemask;            /* mask for create windows */
603     XSetWindowAttributes attributes;    /* attributes for create windows */
604     Pixmap pm;                          /* tmp pixmap variable */
605     Image *iconimage;
606     char *icon_name;
607     int x, final_x, final_y;
608         unsigned int pm_numcolors = 0; /* djhjr - 12/28/98 */
609
610         /* djhjr - 4/27/96 */
611     GetColorFromList(Scr->IconBorderColorL, tmp_win->full_name, &tmp_win->class,
612         &tmp_win->icon_border);
613     GetColorFromList(Scr->IconForegroundL, tmp_win->full_name, &tmp_win->class,
614         &tmp_win->iconc.fore);
615     GetColorFromList(Scr->IconBackgroundL, tmp_win->full_name, &tmp_win->class,
616         &tmp_win->iconc.back);
617
618 /* djhjr - 5/5/98
619     if (Scr->use3Diconmanagers && !Scr->BeNiceToColormap) GetShadeColors(&tmp_win->iconc);
620 */
621         /* was 'Scr->use3Dicons' - djhjr - 8/11/98 */
622         if (Scr->IconBevelWidth > 0 && !Scr->BeNiceToColormap) GetShadeColors(&tmp_win->iconc);
623
624     FB(tmp_win->iconc.fore, tmp_win->iconc.back);
625
626     tmp_win->forced = FALSE;
627     tmp_win->icon_not_ours = FALSE;
628     iconimage = NULL;
629     pm = None;
630
631     /*
632      * now go through the steps to get an icon window,  if ForceIcon is 
633      * set, then no matter what else is defined, the bitmap from the
634      * .vtwmrc file is used
635      */
636         if (Scr->ForceIcon)
637         {
638                 icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name);
639                 if (icon_name == NULL)
640                         icon_name = LookInList(Scr->IconNames, tmp_win->full_name,
641                                         &tmp_win->class);
642
643                 if (icon_name != NULL)
644                         /* added background and XPM indicator - djhjr - 12/28/98 */
645                         iconimage = GetIconImage(icon_name, tmp_win->iconc.back,
646                                         &pm_numcolors);
647       
648                 if (iconimage != NULL)
649                 {
650                         tmp_win->icon_width = iconimage->width;
651                         tmp_win->icon_height = iconimage->height;
652
653                         pm = iconimage->pixmap;
654                         tmp_win->forced = TRUE;
655                 }
656         }
657
658         /*
659          * if the pixmap is still NULL, we didn't get one from the above code,
660          * that could mean that ForceIcon was not set, or that the window
661          * was not in the Icons list, now check the WM hints for an icon
662          */
663         if (pm == None && tmp_win->wmhints &&
664                         tmp_win->wmhints->flags & IconPixmapHint)
665         {
666 /* djhjr - 8/14/98
667                 XGetGeometry(dpy, tmp_win->wmhints->icon_pixmap,
668                                 &JunkRoot, &JunkX, &JunkY,
669                                 (unsigned int *)&tmp_win->icon_width,
670                                 (unsigned int *)&tmp_win->icon_height, &JunkBW, &JunkDepth);
671       
672                 pm = XCreatePixmap(dpy, Scr->Root,
673                                 tmp_win->icon_width, tmp_win->icon_height,
674                                 Scr->d_depth);
675       
676                 XCopyPlane(dpy, tmp_win->wmhints->icon_pixmap, pm, Scr->NormalGC,
677                                 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 );
678
679                 XFreePixmap(dpy, pm);
680 */
681                 XGetGeometry(dpy, tmp_win->wmhints->icon_pixmap,
682                                 &JunkRoot, &JunkX, &JunkY,
683                                 &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth);
684
685                 pm_numcolors = 3; /* Submitted by Caveh Frank Jalali */
686
687                 iconimage = (Image*)malloc(sizeof(Image));
688                 iconimage->mask = None;
689                 iconimage->width = JunkWidth;
690                 iconimage->height = JunkHeight;
691                 iconimage->pixmap = XCreatePixmap(dpy, Scr->Root, iconimage->width,
692                                 iconimage->height, Scr->d_depth);
693
694                 if (JunkDepth == Scr->d_depth) 
695                         XCopyArea(dpy, tmp_win->wmhints->icon_pixmap, iconimage->pixmap,
696                                         Scr->NormalGC, 0, 0, iconimage->width, iconimage->height,
697                                         0, 0);
698                 else
699                         XCopyPlane(dpy, tmp_win->wmhints->icon_pixmap, iconimage->pixmap,
700                                         Scr->NormalGC, 0, 0, iconimage->width, iconimage->height,
701                                         0, 0, 1);
702
703                 if ((tmp_win->wmhints->flags & IconMaskHint) &&
704                                 XGetGeometry(dpy, tmp_win->wmhints->icon_mask,
705                                                 &JunkRoot, &JunkX, &JunkY, &JunkWidth, &JunkHeight,
706                                                 &JunkBW, &JunkDepth) &&
707                                 JunkDepth == 1)
708                 {
709                         GC gc;
710
711                         iconimage->mask = XCreatePixmap(dpy, Scr->Root,
712                                         JunkWidth, JunkHeight, 1);
713                         if (iconimage->mask)
714                         {
715                                 gc = XCreateGC(dpy, iconimage->mask, 0, NULL);
716                                 if (gc)
717                                 {
718                                         XCopyArea(dpy, tmp_win->wmhints->icon_mask, iconimage->mask,
719                                                         gc, 0, 0, JunkWidth, JunkHeight, 0, 0);
720                                         XFreeGC (dpy, gc);
721                                 }
722                         }
723                 }
724
725                 if (iconimage != NULL)
726                 {
727                         tmp_win->icon_width = iconimage->width;
728                         tmp_win->icon_height = iconimage->height;
729
730                         pm = iconimage->pixmap;
731                 }
732         }
733         
734         /*
735          * if we still haven't got an icon, let's look in the Icon list 
736          * if ForceIcon is not set
737          */
738         if (pm == None && !Scr->ForceIcon)
739         {
740                 icon_name = LookInNameList(Scr->IconNames, tmp_win->full_name);
741                 if (icon_name == NULL)
742                         icon_name = LookInList(Scr->IconNames, tmp_win->full_name,
743                                         &tmp_win->class);
744
745                 if (icon_name != NULL)
746                         /* added background and XPM indicator - djhjr - 12/28/98 */
747                         iconimage = GetIconImage(icon_name, tmp_win->iconc.back,
748                                         &pm_numcolors);
749
750                 if (iconimage != NULL)
751                 {
752                         tmp_win->icon_width = iconimage->width;
753                         tmp_win->icon_height = iconimage->height;
754
755                         pm = iconimage->pixmap;
756                 }
757         }
758     
759         /*
760          * if we still don't have an icon, assign the UnknownIcon
761          */
762 /* djhjr - 8/13/98
763         if (pm == None && Scr->UnknownPm != None)
764         {
765                 tmp_win->icon_width = Scr->UnknownWidth;
766                 tmp_win->icon_height = Scr->UnknownHeight;
767
768                 pm = XCreatePixmap(dpy, Scr->Root, tmp_win->icon_width,
769                                 tmp_win->icon_height, Scr->d_depth);
770
771                 * the copy plane works on color ! *
772                 XCopyPlane(dpy, Scr->UnknownPm, pm, Scr->NormalGC,
773                                 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 );
774
775                 XFreePixmap(dpy, pm);
776         }
777 */
778         if (pm == None && Scr->unknownName != NULL)
779         {
780                 /* added background and XPM indicator - djhjr - 12/28/98 */
781                 iconimage = GetIconImage(Scr->unknownName, tmp_win->iconc.back,
782                                 &pm_numcolors);
783
784                 if (iconimage != NULL)
785                 {
786                         tmp_win->icon_width = iconimage->width;
787                         tmp_win->icon_height = iconimage->height;
788         
789                         pm = iconimage->pixmap;
790                 }
791         }
792
793     if (pm == None)
794     {
795         tmp_win->icon_height = 0;
796         tmp_win->icon_width = 0;
797         valuemask = 0;
798     }
799     else
800     {
801         valuemask = CWBackPixmap;
802         attributes.background_pixmap = pm;
803
804                 /* djhjr - 12/28/98 */
805                 if (pm_numcolors <= 2) /* not a pixmap */
806                 {
807                         valuemask |= CWBackPixel;
808                         attributes.background_pixel = tmp_win->iconc.fore;
809                 }
810     }
811
812 /* djhjr - 9/14/03 */
813 #ifndef NO_I18N_SUPPORT
814     tmp_win->icon_w_width = MyFont_TextWidth(&Scr->IconFont,
815 #else
816     tmp_win->icon_w_width = XTextWidth(Scr->IconFont.font,
817 #endif
818                                        tmp_win->icon_name, strlen(tmp_win->icon_name));
819
820 /* djhjr - 6/11/96
821     tmp_win->icon_w_width += 6;
822     if (tmp_win->icon_w_width < tmp_win->icon_width)
823     {
824                 tmp_win->icon_x = (tmp_win->icon_width - tmp_win->icon_w_width)/2;
825                 tmp_win->icon_x += 3;
826                 tmp_win->icon_w_width = tmp_win->icon_width;
827     }
828     else
829     {
830     tmp_win->icon_x = 3;
831     }
832 */
833     tmp_win->icon_w_width += 8;
834     if (tmp_win->icon_w_width < tmp_win->icon_width + 8)
835     {
836                 tmp_win->icon_x = (((tmp_win->icon_width + 8) - tmp_win->icon_w_width)/2) + 4;
837                 tmp_win->icon_w_width = tmp_win->icon_width + 8;
838     }
839     else
840                 tmp_win->icon_x = 4;
841
842 /* djhjr - 6/11/96
843     tmp_win->icon_y = tmp_win->icon_height + Scr->IconFont.height;
844 */
845     tmp_win->icon_y = tmp_win->icon_height + Scr->IconFont.height + 2;
846
847 /* djhjr - 4/27/96
848     tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 4;
849 */
850 /* djhjr - 6/11/96
851     tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 6;
852 */
853     tmp_win->icon_w_height = tmp_win->icon_height + Scr->IconFont.height + 8;
854
855     event_mask = 0;
856     if (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint)
857     {
858         tmp_win->icon_w = tmp_win->wmhints->icon_window;
859         if (tmp_win->forced ||
860             XGetGeometry(dpy, tmp_win->icon_w, &JunkRoot, &JunkX, &JunkY,
861                      (unsigned int *)&tmp_win->icon_w_width, (unsigned int *)&tmp_win->icon_w_height,
862                      &JunkBW, &JunkDepth) == 0)
863         {
864             tmp_win->icon_w = None;
865             tmp_win->wmhints->flags &= ~IconWindowHint;
866         }
867         else
868         {
869             tmp_win->icon_not_ours = TRUE;
870             event_mask = EnterWindowMask | LeaveWindowMask;
871         }
872     }
873     else
874     {
875         tmp_win->icon_w = None;
876     }
877
878         /* djhjr - 5/5/98 */
879         /* was 'Scr->use3Dicons' and 'Scr->BorderBevelWidth' - djhjr - 8/11/98 */
880         if (Scr->IconBevelWidth > 0)
881         {
882                 tmp_win->icon_w_width += 2 * Scr->IconBevelWidth;
883                 tmp_win->icon_w_height += 2 * Scr->IconBevelWidth;
884
885                 tmp_win->icon_x += Scr->IconBevelWidth;
886                 tmp_win->icon_y += Scr->IconBevelWidth;
887         }
888
889     if (tmp_win->icon_w == None)
890     {
891         tmp_win->icon_w = XCreateSimpleWindow(dpy, Scr->Root,
892             0,0,
893             tmp_win->icon_w_width, tmp_win->icon_w_height,
894             Scr->IconBorderWidth, tmp_win->icon_border, tmp_win->iconc.back);
895         event_mask = ExposureMask;
896     }
897
898     XSelectInput (dpy, tmp_win->icon_w,
899                   KeyPressMask | ButtonPressMask | ButtonReleaseMask |
900                   event_mask);
901
902     tmp_win->icon_bm_w = None;
903     if (pm != None &&
904         (! (tmp_win->wmhints && tmp_win->wmhints->flags & IconWindowHint)))
905     {
906         int y;
907
908 /* djhjr - 6/11/96
909         y = 0;
910 */
911         y = 4;
912
913         if (tmp_win->icon_w_width == tmp_win->icon_width)
914             x = 0;
915         else
916             x = (tmp_win->icon_w_width - tmp_win->icon_width)/2;
917
918         /* djhjr - 5/5/98 */
919         /* was 'Scr->use3Dicons' and 'Scr->BorderBevelWidth' - djhjr - 8/11/98 */
920         if (Scr->IconBevelWidth > 0)
921                 y += Scr->IconBevelWidth;
922
923         tmp_win->icon_bm_w = XCreateWindow (dpy, tmp_win->icon_w, x, y,
924                                             (unsigned int)tmp_win->icon_width,
925                                             (unsigned int)tmp_win->icon_height,
926                                             (unsigned int) 0, Scr->d_depth,
927                                             (unsigned int) CopyFromParent,
928                                             Scr->d_visual, valuemask,
929                                             &attributes);
930
931     if (HasShape)
932                 if (iconimage != NULL && iconimage->mask != None)
933                         XShapeCombineMask(dpy,tmp_win->icon_bm_w , ShapeBounding, 0, 0,
934                                         iconimage->mask, ShapeSet);
935     }
936
937     /* I need to figure out where to put the icon window now, because 
938      * getting here means that I am going to make the icon visible
939      */
940     if (tmp_win->wmhints &&
941         tmp_win->wmhints->flags & IconPositionHint)
942     {
943         final_x = tmp_win->wmhints->icon_x;
944         final_y = tmp_win->wmhints->icon_y;
945     }
946     else
947     {
948         PlaceIcon(tmp_win, def_x, def_y, &final_x, &final_y);
949     }
950
951     if (final_x > Scr->MyDisplayWidth)
952         final_x = Scr->MyDisplayWidth - tmp_win->icon_w_width -
953             (2 * Scr->IconBorderWidth);
954
955     if (final_y > Scr->MyDisplayHeight)
956         final_y = Scr->MyDisplayHeight - tmp_win->icon_height -
957             Scr->IconFont.height - 4 - (2 * Scr->IconBorderWidth);
958
959     XMoveWindow(dpy, tmp_win->icon_w, final_x, final_y);
960     tmp_win->iconified = TRUE;
961
962     XMapSubwindows(dpy, tmp_win->icon_w);
963     XSaveContext(dpy, tmp_win->icon_w, TwmContext, (caddr_t)tmp_win);
964     XSaveContext(dpy, tmp_win->icon_w, ScreenContext, (caddr_t)Scr);
965     XDefineCursor(dpy, tmp_win->icon_w, Scr->IconCursor);
966
967     return;
968 }
969 #endif /* ORIGINAL_PIXMAPS */
970