dtcm: Coverity 89287
[oweals/cde.git] / cde / programs / dtwm / WmIDecor.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* 
24  * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC. 
25  * ALL RIGHTS RESERVED 
26 */ 
27 /* 
28  * Motif Release 1.2.3
29 */
30 /*
31  * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
32
33 /*
34  * Included Files:
35  */
36
37
38 #include "WmGlobal.h"
39 #include <Xm/Xm.h>
40 #include <Xm/DrawP.h>           /* for XmeClearBorder */
41 /*
42  * include extern functions
43  */
44 #include "WmIDecor.h"
45 #include "WmError.h"
46 #include "WmGraphics.h"
47 #include "WmIconBox.h"
48 #include "WmMenu.h"
49 #include "WmWinInfo.h"
50 #include "WmWrkspace.h"
51
52
53
54 /*
55  * Global Variables:
56  */
57 static unsigned int activeIconTextWidth = 1;
58 static unsigned int activeIconTextHeight = 1;
59 static RList *pActiveIconTopRects = NULL;
60 static RList *pActiveIconBotRects = NULL;
61
62 static int  iconShrinkX; 
63 static int  iconShrinkY;
64 static unsigned int iconShrinkWidth;
65 static unsigned int iconShrinkHeight;
66
67 \f
68 /*************************************<->*************************************
69  *
70  *  MakeIcon (pWS, pcd)
71  *
72  *
73  *  Description:
74  *  -----------
75  *  Create an icon frame and fill it in as appropriate for the client.
76  *
77  *
78  *  Inputs:
79  *  ------
80  *  pWS         - pointer to workspace data
81  *  pcd         - pointer to client data
82  *
83  * 
84  *  Outputs:
85  *  -------
86  *  Return      - TRUE if success, FALSE if failure.
87  *
88  *
89  *  Comments:
90  *  --------
91  *  
92  * 
93  *************************************<->***********************************/
94
95 Boolean MakeIcon (WmWorkspaceData *pWS, ClientData *pcd)
96 {
97     XSetWindowAttributes window_attribs;
98     unsigned long attr_mask;
99     int xOffset;
100     int yOffset;
101     WsClientData *pWsc = GetWsClientData (pWS, pcd);
102
103
104     /*
105      * Common to all icons
106      */
107
108     /* compute dimensions of outer icon frame */
109     /* create icon frame window */
110
111     attr_mask = CWEventMask | CWCursor;
112     window_attribs.event_mask = (ButtonPressMask | ButtonReleaseMask |
113                                  SELECT_BUTTON_MOTION_MASK |
114                                  DMANIP_BUTTON_MOTION_MASK |
115                                  ExposureMask |
116                                  SubstructureRedirectMask |
117                                  FocusChangeMask);
118     window_attribs.cursor = wmGD.workspaceCursor;
119
120     if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER) ||
121         (wmGD.colormapFocusPolicy == CMAP_FOCUS_POINTER))
122     {
123         window_attribs.event_mask |= EnterWindowMask | LeaveWindowMask;
124     }
125
126     /* 
127      * Use background pixmap if one is specified, otherwise set the
128      * appropriate background color. 
129      */
130
131     if (ICON_APPEARANCE(pcd).backgroundPixmap)
132     {
133         attr_mask |= CWBackPixmap;
134         window_attribs.background_pixmap = 
135                             ICON_APPEARANCE(pcd).backgroundPixmap;
136     }
137     else
138     {
139         attr_mask |= CWBackPixel;
140         window_attribs.background_pixel = 
141                                 ICON_APPEARANCE(pcd).background;
142     }
143    
144     if ((!pcd->pSD->useIconBox) || 
145         (pcd->clientFlags & (CLIENT_WM_CLIENTS | FRONT_PANEL_BOX)))
146     {
147         pWsc->iconFrameWin = XCreateWindow (DISPLAY,
148                                ROOT_FOR_CLIENT(pcd),    /* parent */
149                                pWsc->iconX,
150                                pWsc->iconY,
151                                (unsigned int) ICON_WIDTH(pcd),
152                                (unsigned int) ICON_HEIGHT(pcd),
153                                0,               /* border width */
154                                CopyFromParent,  /* depth */
155                                InputOutput,     /* class */
156                                CopyFromParent,  /* visual */
157                                attr_mask,
158                                &window_attribs);
159
160     }
161     else
162     {
163         /*
164          * Insert the icon into the icon box.
165          * Don't make icon in the box for any icon box (or any WM window)
166          * OR any client that doesn't have the MWM_FUNC_MINIMIZE bit set
167          * in pcd->clientFunctions
168          */
169
170         if ((pcd->pSD->useIconBox) && 
171             (!(pcd->clientFlags & CLIENT_WM_CLIENTS)) &&
172             (pcd->clientFunctions & MWM_FUNC_MINIMIZE) )
173         {
174             if (!InsertIconIntoBox(pWS->pIconBox, pcd))
175                 Warning(((char *)GETMESSAGE(30, 1, "Could not make icon to go in icon box")));
176
177         }
178
179     }
180
181
182     /* make space for the top/bottom changing shadow rectangles */
183
184     if ((pcd->piconTopShadows = 
185             AllocateRList ((unsigned)NUM_BOTH_TOP_RECTS)) == NULL)
186     {
187         /* Out of memory! */
188         Warning (((char *)GETMESSAGE(30, 2, "Insufficient memory for icon creation")));
189         return(FALSE);
190     }
191     
192     if ((pcd->piconBottomShadows = 
193          AllocateRList ((unsigned)NUM_BOTH_BOTTOM_RECTS)) == NULL)
194     {
195         /* Out of memory! */
196         Warning (((char *)GETMESSAGE(30, 3, "Insufficient memory for icon creation")));
197         return(FALSE);
198     }
199
200
201     /*
202      * Adjust for icons in the box 
203      * Don't adjust the icon for the icon box itself
204      */
205
206     if (pWS->pIconBox && (pWS->pIconBox->pCD_iconBox != pcd) &&
207         !(pcd->clientFlags & FRONT_PANEL_BOX))
208     {
209         xOffset = IB_MARGIN_WIDTH;
210         yOffset = IB_MARGIN_HEIGHT;
211     }
212     else
213     {
214         xOffset = 0;
215         yOffset = 0;
216     }
217
218
219     /*
220      * Reparent the icon window if there is one
221      */
222     if ((ICON_DECORATION(pcd) & ICON_IMAGE_PART) && 
223         (pcd->iconWindow))
224     {
225         ReparentIconWindow (pcd, xOffset, yOffset);
226     }
227
228     if (pcd->piconTopShadows->used == 0)
229     MakeIconShadows (pcd, xOffset, yOffset);
230
231     return(TRUE);
232
233 } /* END OF FUNCTION MakeIcon */
234
235
236 \f
237 /*************************************<->*************************************
238  *
239  *  MakeIconShadows (pcd, xOffset, yOffset)
240  *
241  *  Comments:
242  *  --------
243  * 
244  *************************************<->***********************************/
245
246 void MakeIconShadows (ClientData *pcd, int xOffset, int yOffset)
247 {        
248
249     /*
250      * Handle different icon styles
251      */
252     
253     switch (ICON_DECORATION(pcd) & (ICON_LABEL_PART | ICON_IMAGE_PART)) 
254     {
255         case ICON_LABEL_PART:
256             BevelRectangle (pcd->piconTopShadows,       /* label */
257                             pcd->piconBottomShadows, 
258                             0 + xOffset, (int)ICON_IMAGE_HEIGHT(pcd) + yOffset,
259                             (unsigned int) ICON_WIDTH(pcd), 
260                             (unsigned int) ICON_LABEL_HEIGHT(pcd),
261                             ICON_EXTERNAL_SHADOW_WIDTH,
262                             ICON_EXTERNAL_SHADOW_WIDTH,
263                             ICON_EXTERNAL_SHADOW_WIDTH,
264                             ICON_EXTERNAL_SHADOW_WIDTH);
265             break;
266
267         case ICON_IMAGE_PART:
268             BevelRectangle (pcd->piconTopShadows,       /* image outside */
269                             pcd->piconBottomShadows, 
270                             0 + xOffset, 0 + yOffset,
271                             (unsigned int) ICON_WIDTH(pcd), 
272                             (unsigned int) ICON_IMAGE_HEIGHT(pcd),
273                             ICON_EXTERNAL_SHADOW_WIDTH,
274                             ICON_EXTERNAL_SHADOW_WIDTH,
275                             ICON_EXTERNAL_SHADOW_WIDTH,
276                             ICON_EXTERNAL_SHADOW_WIDTH);
277
278             if (wmGD.frameStyle == WmRECESSED)
279                 BevelRectangle (pcd->piconBottomShadows, /* image inside */
280                             pcd->piconTopShadows, 
281                             ICON_INNER_X_OFFSET + xOffset,
282                             ICON_INNER_Y_OFFSET + yOffset,
283                             (unsigned int) (ICON_IMAGE_MAXIMUM(pcd).width + 
284                                 4*ICON_INTERNAL_SHADOW_WIDTH),
285                             (unsigned int) (ICON_IMAGE_MAXIMUM(pcd).height + 
286                                 4*ICON_INTERNAL_SHADOW_WIDTH),
287                             ICON_INTERNAL_SHADOW_WIDTH,
288                             ICON_INTERNAL_SHADOW_WIDTH,
289                             ICON_INTERNAL_SHADOW_WIDTH,
290                             ICON_INTERNAL_SHADOW_WIDTH);
291
292             break;
293
294         case (ICON_IMAGE_PART | ICON_LABEL_PART):
295             if (wmGD.frameStyle == WmSLAB)
296             {
297                 BevelRectangle (pcd->piconTopShadows,   /* image outside */
298                             pcd->piconBottomShadows, 
299                             0 + xOffset, 0 + yOffset,
300                             (unsigned int) ICON_WIDTH(pcd), 
301                             (unsigned int) (ICON_IMAGE_HEIGHT(pcd) +
302                                             ICON_LABEL_HEIGHT(pcd)),
303                             ICON_EXTERNAL_SHADOW_WIDTH,
304                             ICON_EXTERNAL_SHADOW_WIDTH,
305                             ICON_EXTERNAL_SHADOW_WIDTH,
306                             ICON_EXTERNAL_SHADOW_WIDTH);
307             }
308             else
309             {
310                 BevelRectangle (pcd->piconTopShadows,   /* image outside */
311                             pcd->piconBottomShadows, 
312                             0 + xOffset, 0 + yOffset, 
313                             (unsigned int) ICON_WIDTH(pcd), 
314                             (unsigned int) ICON_IMAGE_HEIGHT(pcd),
315                             ICON_EXTERNAL_SHADOW_WIDTH,
316                             ICON_EXTERNAL_SHADOW_WIDTH,
317                             ICON_INTERNAL_SHADOW_WIDTH,
318                             ICON_EXTERNAL_SHADOW_WIDTH);
319             }
320
321             if (wmGD.frameStyle == WmRECESSED)
322                 BevelRectangle (pcd->piconBottomShadows, /* image inside */
323                             pcd->piconTopShadows, 
324                             ICON_INNER_X_OFFSET + xOffset,
325                             ICON_INNER_Y_OFFSET + yOffset,
326                             (unsigned int) (ICON_IMAGE_MAXIMUM(pcd).width + 
327                                 4*ICON_INTERNAL_SHADOW_WIDTH),
328                             (unsigned int) (ICON_IMAGE_MAXIMUM(pcd).height + 
329                                 4*ICON_INTERNAL_SHADOW_WIDTH),
330                             ICON_INTERNAL_SHADOW_WIDTH,
331                             ICON_INTERNAL_SHADOW_WIDTH,
332                             ICON_INTERNAL_SHADOW_WIDTH,
333                             ICON_INTERNAL_SHADOW_WIDTH);
334
335             if (wmGD.frameStyle == WmRECESSED)
336                 BevelRectangle (pcd->piconTopShadows,   /* label */
337                             pcd->piconBottomShadows, 
338                             0 + xOffset, (int)ICON_IMAGE_HEIGHT(pcd) + yOffset,
339                             (unsigned int) ICON_WIDTH(pcd), 
340                             (unsigned int) ICON_LABEL_HEIGHT(pcd),
341                             ICON_INTERNAL_SHADOW_WIDTH,
342                             ICON_EXTERNAL_SHADOW_WIDTH,
343                             ICON_EXTERNAL_SHADOW_WIDTH,
344                             ICON_EXTERNAL_SHADOW_WIDTH);
345
346             break;
347     }
348
349 } /* END OF FUNCTION MakeIconShadows */
350
351
352
353
354
355 \f
356 /*************************************<->*************************************
357  *
358  *  IconExposureProc (pcd, expose)
359  *
360  *
361  *  Description:
362  *  -----------
363  *  Repaint the icon.
364  *
365  *
366  *  Inputs:
367  *  ------
368  *  pcd         - pointer to client data
369  *
370  * 
371  *  Outputs:
372  *  -------
373  *
374  *  Comments:
375  *  --------
376  * 
377  *************************************<->***********************************/
378
379 void IconExposureProc (ClientData *pcd, Boolean expose)
380 {
381
382     Pixmap image;
383     int dest_x, dest_y;
384     int xOffset;
385     int yOffset;
386     unsigned int width, height;
387     GC iconGC, topGC, botGC;
388     static XRectangle   shrinkRects[4];
389
390
391
392     /*
393      * Adjust for icons in the iconBox
394      */
395
396     if (P_ICON_BOX(pcd))
397     {
398         xOffset = IB_MARGIN_WIDTH;
399         yOffset = IB_MARGIN_HEIGHT;
400     }
401     else
402     {
403         xOffset = 0;
404         yOffset = 0;
405     }
406     
407     /* get appropriate GCs */
408
409     if ((wmGD.keyboardFocus == pcd) && (pcd->clientState == MINIMIZED_STATE))
410     {
411         iconGC = ICON_APPEARANCE(pcd).activeGC;
412         topGC = ICON_APPEARANCE(pcd).activeTopShadowGC;
413         botGC = ICON_APPEARANCE(pcd).activeBottomShadowGC;
414     }
415     else
416     {
417         iconGC = ICON_APPEARANCE(pcd).inactiveGC;
418         topGC = ICON_APPEARANCE(pcd).inactiveTopShadowGC;
419         botGC = ICON_APPEARANCE(pcd).inactiveBottomShadowGC;
420     }
421
422     if (ACTIVE_PSD->useIconBox && P_ICON_BOX(pcd))
423     {
424         /* draw shadowing */
425
426         if (expose)
427         {
428             XClearArea (DISPLAY, 
429                             ICON_FRAME_WIN(pcd), 
430                             IB_MARGIN_WIDTH, 
431                             IB_MARGIN_HEIGHT, 
432                             (unsigned int) ICON_WIDTH(pcd), 
433                             (unsigned int) ICON_HEIGHT(pcd), False);
434         }
435
436         if (pcd->clientState == MINIMIZED_STATE)
437         {
438             /*
439              * This is the "raised" icon appearance
440              */
441
442             if (pcd->piconTopShadows)
443             {
444
445                 XFillRectangles (DISPLAY, 
446                                     ICON_FRAME_WIN(pcd), 
447                                     topGC,
448                                     pcd->piconTopShadows->prect,
449                                     pcd->piconTopShadows->used);
450             }
451
452             if (pcd->piconBottomShadows)
453             { 
454                 XFillRectangles (DISPLAY,
455                                     ICON_FRAME_WIN(pcd), 
456                                     botGC,
457                                     pcd->piconBottomShadows->prect,
458                                     pcd->piconBottomShadows->used);
459             }
460         }
461         else 
462         {
463             shrinkRects[0].x = IB_MARGIN_WIDTH;
464             shrinkRects[0].y = IB_MARGIN_HEIGHT;
465             shrinkRects[0].width = (unsigned int) ICON_WIDTH(pcd);
466             shrinkRects[0].height = iconShrinkY - IB_MARGIN_HEIGHT;
467
468             shrinkRects[1].x = IB_MARGIN_WIDTH;
469             shrinkRects[1].y = iconShrinkY;
470             shrinkRects[1].width = iconShrinkX - IB_MARGIN_WIDTH;
471             shrinkRects[1].height = iconShrinkHeight;
472
473             shrinkRects[2].x = iconShrinkX + iconShrinkWidth;
474             shrinkRects[2].y = iconShrinkY;
475             shrinkRects[2].width = iconShrinkX - IB_MARGIN_WIDTH;
476             shrinkRects[2].height = iconShrinkHeight;
477
478             shrinkRects[3].x = IB_MARGIN_WIDTH;
479             shrinkRects[3].y = iconShrinkY + iconShrinkHeight;
480             shrinkRects[3].width = (unsigned int) ICON_WIDTH(pcd);
481             shrinkRects[3].height = iconShrinkY - IB_MARGIN_HEIGHT;
482
483             XFillRectangles (DISPLAY, 
484                             ICON_FRAME_WIN(pcd), 
485                             SHRINK_WRAP_GC(pcd),
486                             &shrinkRects[0], 4);
487                             
488         }
489
490     }
491     else 
492     {
493         /* draw shadowing */
494
495         if (pcd->clientState == MINIMIZED_STATE)
496         {
497             /*
498              * This is the "raised" icon appearance
499              */
500
501             if (pcd->piconTopShadows->prect)
502             {
503
504                 XFillRectangles (DISPLAY, 
505                                 ICON_FRAME_WIN(pcd), 
506                                 topGC,
507                                 pcd->piconTopShadows->prect,
508                                 pcd->piconTopShadows->used);
509             }
510
511             if (pcd->piconBottomShadows->prect)
512             { 
513                 XFillRectangles (DISPLAY,
514                                 ICON_FRAME_WIN(pcd), 
515                                 botGC,
516                                 pcd->piconBottomShadows->prect,
517                                 pcd->piconBottomShadows->used);
518             }
519
520         }
521     }
522
523
524     /* draw icon text */
525 /*
526     if ((ICON_DECORATION(pcd) & ICON_LABEL_PART) &&
527         (expose || !(ICON_DECORATION(pcd) & ICON_ACTIVE_LABEL_PART)))
528 */
529     if (ICON_DECORATION(pcd) & ICON_LABEL_PART)
530     {
531         DrawIconTitle (pcd);
532     }
533
534     /* 
535      * Draw image if no icon window (client has to redraw that!) 
536      *  OR if using the iconbox, draw the default image where
537      *  the icon window was.
538      */
539
540     if (expose &&
541         ((!pcd->iconWindow && (ICON_DECORATION(pcd) & ICON_IMAGE_PART)) ||
542          (ACTIVE_PSD->useIconBox && P_ICON_BOX(pcd) &&
543                 pcd->iconWindow && 
544                 pcd->clientState != MINIMIZED_STATE &&
545                 (ICON_DECORATION(pcd) & ICON_IMAGE_PART))))
546     {
547         if (pcd->iconWindow)
548         {
549             image = DEFAULT_PIXMAP(pcd);
550         }
551         else
552         {
553             image = pcd->iconPixmap;
554         }
555
556         if (image)
557         {
558
559             if ((ACTIVE_PSD->useIconBox) && (P_ICON_BOX(pcd)))
560             {
561
562                 if (pcd->clientState != MINIMIZED_STATE)
563                 {
564                     dest_x = ICON_IMAGE_X_OFFSET 
565                             + ICON_INTERNAL_SHADOW_WIDTH
566                             + xOffset;
567
568                     dest_y = ICON_IMAGE_Y_OFFSET 
569                             + ICON_INTERNAL_SHADOW_WIDTH
570                             + yOffset;
571                     if (wmGD.frameStyle == WmSLAB)
572                     {
573                         /* less beveling in this style */
574                         dest_x -= ICON_INTERNAL_SHADOW_WIDTH;
575                         dest_y -= ICON_INTERNAL_SHADOW_WIDTH;
576                     } 
577
578                     width = ICON_IMAGE_MAXIMUM(pcd).width;
579                     height= ICON_IMAGE_MAXIMUM(pcd).height;
580                     if (wmGD.frameStyle == WmSLAB)
581                     {
582                         width += 2;
583                         height += 2;
584                     } 
585                     XCopyArea (DISPLAY, image, 
586                                 ICON_FRAME_WIN(pcd), 
587                                 iconGC,
588                                 ICON_INTERNAL_SHADOW_WIDTH, 
589                                 ICON_INTERNAL_SHADOW_WIDTH, 
590                                 width, height, dest_x, dest_y);
591
592                     if (FADE_NORMAL_ICON(pcd))
593                     {
594                         iconGC = FADE_ICON_GC(pcd);
595                         XFillRectangle (DISPLAY, 
596                                     ICON_FRAME_WIN(pcd), 
597                                     iconGC,
598                                     dest_x, dest_y,
599                                     width, height);
600                     }
601
602                 }
603                 else
604                 {
605                     dest_x = ICON_IMAGE_X_OFFSET 
606                             + xOffset;
607
608                     dest_y = ICON_IMAGE_Y_OFFSET 
609                             + yOffset;
610                     if (wmGD.frameStyle == WmSLAB)
611                     {
612                         /* less beveling in this style */
613                         dest_x -= ICON_INTERNAL_SHADOW_WIDTH;
614                         dest_y -= ICON_INTERNAL_SHADOW_WIDTH;
615                     } 
616
617                     width = ICON_IMAGE_MAXIMUM(pcd).width
618                             + (2 * ICON_INTERNAL_SHADOW_WIDTH);
619                     height= ICON_IMAGE_MAXIMUM(pcd).height
620                             + (2 * ICON_INTERNAL_SHADOW_WIDTH);
621
622                     if (wmGD.frameStyle == WmSLAB)
623                     {
624                         width += 2;
625                         height += 2;
626                     } 
627                     XCopyArea (DISPLAY, image, 
628                                 ICON_FRAME_WIN(pcd), 
629                                 iconGC, 0, 0, width, height, 
630                                 dest_x, dest_y);
631
632                 }
633             }
634             else
635
636             {
637                 width = ICON_IMAGE_MAXIMUM(pcd).width +
638                         2 * ICON_INTERNAL_SHADOW_WIDTH;
639
640                 height= ICON_IMAGE_MAXIMUM(pcd).height +
641                         2 * ICON_INTERNAL_SHADOW_WIDTH;
642
643                 if (wmGD.frameStyle == WmSLAB)
644                 {
645                     dest_x = ICON_INNER_X_OFFSET;
646                     dest_y = ICON_INNER_Y_OFFSET;
647                     width += 2;
648                     height += 2;
649                 } 
650                 else 
651                 {
652                     dest_x = ICON_INNER_X_OFFSET + ICON_INTERNAL_SHADOW_WIDTH;
653                     dest_y = ICON_INNER_Y_OFFSET + ICON_INTERNAL_SHADOW_WIDTH;
654                 }
655                 XCopyArea (DISPLAY, image, 
656                             ICON_FRAME_WIN(pcd), 
657                             iconGC, 0, 0, width, height, 
658                             dest_x, dest_y);
659
660
661             }
662
663         }
664     }
665
666
667 } /* END OF FUNCTION IconExposureProc */
668
669
670
671 \f
672 /*************************************<->*************************************
673  *
674  *  GetIconTitleBox (pcd, pBox)
675  *
676  *
677  *  Description:
678  *  -----------
679  *  Returns a rectangle containing the icon text box
680  *
681  *
682  *  Inputs:
683  *  ------
684  *  pcd - pointer to client data
685  *  pBox - pointer to an XRectangle structure that gets returned data
686  *
687  *  Outputs:
688  *  -------
689  *  pBox - returned data
690  *
691  *  Comments:
692  *  --------
693  * 
694  *************************************<->***********************************/
695
696 void GetIconTitleBox (ClientData *pcd, XRectangle *pBox)
697 {
698     int xOffset;
699     int yOffset;
700
701
702     /*
703      * Adjust for icons in the iconBox
704      */
705
706     if (P_ICON_BOX(pcd))
707     {
708         xOffset = IB_MARGIN_WIDTH;
709         yOffset = IB_MARGIN_HEIGHT;
710     }
711     else
712     {
713         xOffset = 0;
714         yOffset = 0;
715     }
716
717     if ((P_ICON_BOX(pcd)) && (pcd->clientState != MINIMIZED_STATE))
718     {
719         /* move label up to enhance shrink wrap effect */
720         pBox->x = ICON_EXTERNAL_SHADOW_WIDTH 
721                 + ICON_IMAGE_LEFT_PAD
722                 + (2 * ICON_INTERNAL_SHADOW_WIDTH)
723                 + ICON_IMAGE_LEFT_PAD
724                 + xOffset;
725
726         pBox->y = ICON_IMAGE_HEIGHT(pcd) 
727                 +  yOffset
728                 + ((ICON_IMAGE_HEIGHT(pcd) > 0) 
729                         ? - ICON_IMAGE_BOTTOM_PAD
730                         : ICON_EXTERNAL_SHADOW_WIDTH)
731                 +  ((ICON_IMAGE_HEIGHT(pcd) >0)
732                         ? 0
733                         : WM_TOP_TITLE_PADDING );
734
735         if (wmGD.frameStyle == WmSLAB)
736         {
737             /* account for less beveling in this style */
738             pBox->x -= ICON_INTERNAL_SHADOW_WIDTH;
739             pBox->y -= ICON_INTERNAL_SHADOW_WIDTH;
740         }
741
742
743
744         pBox->width = ICON_IMAGE_MAXIMUM(pcd).width 
745                         + ((wmGD.frameStyle == WmSLAB) ? 2 : 0) 
746                         - ICON_IMAGE_LEFT_PAD
747                         - ICON_EXTERNAL_SHADOW_WIDTH;
748
749         pBox->height = TEXT_HEIGHT(ICON_APPEARANCE(pcd).font);
750
751     }
752     else if ((P_ICON_BOX(pcd)) && (pcd->clientState == MINIMIZED_STATE))
753     {
754         pBox->x = ICON_EXTERNAL_SHADOW_WIDTH 
755                 + ICON_IMAGE_LEFT_PAD
756                 + (2 * ICON_INTERNAL_SHADOW_WIDTH)
757                 + ICON_IMAGE_LEFT_PAD
758                 + xOffset;
759
760         pBox->y = ICON_IMAGE_HEIGHT(pcd) 
761                 +  yOffset
762                 + ((ICON_IMAGE_HEIGHT(pcd) > 0) 
763                         ? ICON_INTERNAL_SHADOW_WIDTH 
764                         : ICON_EXTERNAL_SHADOW_WIDTH)
765                 +  WM_TOP_TITLE_PADDING ;
766
767         pBox->width = ICON_IMAGE_MAXIMUM(pcd).width 
768                         + ((wmGD.frameStyle == WmSLAB) ? 2 : 0) 
769                         - ICON_IMAGE_LEFT_PAD;
770
771         pBox->height = TEXT_HEIGHT(ICON_APPEARANCE(pcd).font);
772
773         if (wmGD.frameStyle == WmSLAB)
774         {
775             /* account for less beveling in this style */
776             pBox->x -= ICON_INTERNAL_SHADOW_WIDTH + 2*ICON_IMAGE_LEFT_PAD;
777             pBox->y -= 3 * ICON_INTERNAL_SHADOW_WIDTH;
778             pBox->width += ICON_IMAGE_LEFT_PAD + 2;
779         }
780
781     }
782     else
783     {
784         pBox->x = ICON_EXTERNAL_SHADOW_WIDTH 
785                 + WM_TOP_TITLE_PADDING
786                 + xOffset;
787
788         if (wmGD.frameStyle == WmSLAB)
789         {
790             /* account for less beveling in this style */
791             yOffset -= ICON_INTERNAL_SHADOW_WIDTH;
792         }
793         pBox->y = ICON_IMAGE_HEIGHT(pcd) 
794                 +  WM_TOP_TITLE_PADDING 
795                 +  yOffset
796                 + ((ICON_IMAGE_HEIGHT(pcd) > 0) 
797                         ? ICON_INTERNAL_SHADOW_WIDTH 
798                         : ICON_EXTERNAL_SHADOW_WIDTH);
799
800         pBox->width = ICON_WIDTH(pcd) - 2 * ICON_EXTERNAL_SHADOW_WIDTH - 
801                   WM_TOP_TITLE_PADDING - WM_BOTTOM_TITLE_PADDING;
802         pBox->height = TEXT_HEIGHT(ICON_APPEARANCE(pcd).font);
803
804     }
805
806
807 } /* END OF FUNCTION GetIconTitleBox */
808
809
810 \f
811 /*************************************<->*************************************
812  *
813  *  DrawIconTitle (pcd)
814  *
815  *
816  *  Description:
817  *  -----------
818  *  Draws the title in the Icon title area
819  *
820  *
821  *  Inputs:
822  *  ------
823  *  pcd - pointer to client data
824  *
825  *  Outputs:
826  *  -------
827  *
828  *  Comments:
829  *  --------
830  * 
831  *************************************<->***********************************/
832
833 void DrawIconTitle (ClientData *pcd)
834 {
835     XRectangle textBox;
836     GC iconGC;
837     
838     
839     GetIconTitleBox (pcd, &textBox);
840
841     /* get appropriate GCs */
842     if ((ACTIVE_PSD->useIconBox && 
843         !((pcd->dtwmBehaviors & (DtWM_BEHAVIOR_PANEL)) ||
844           (pcd->clientFlags & CLIENT_WM_CLIENTS))) ||
845         !(wmGD.keyboardFocus == pcd)) 
846     {
847         iconGC = ICON_APPEARANCE(pcd).inactiveGC;
848     }
849     else 
850     {
851         iconGC = ICON_APPEARANCE(pcd).activeGC;
852     }
853
854     /* 
855      * Dim text if this is in the icon box and the client is mapped 
856      */
857
858     if ((ACTIVE_PSD->useIconBox) && 
859         (P_ICON_BOX(pcd)) &&
860         (FADE_NORMAL_ICON(pcd)) && 
861         (!(pcd->clientState == MINIMIZED_STATE)))
862     {
863             iconGC = FADE_ICON_TEXT_GC(pcd);
864     }
865
866
867
868
869     /* paint the text */
870     WmDrawXmString(DISPLAY, ICON_FRAME_WIN(pcd), ICON_APPEARANCE(pcd).fontList,
871                    pcd->iconTitle, iconGC, 
872                    textBox.x, textBox.y, textBox.width, &textBox, True);
873
874 } /* END OF FUNCTION DrawIconTitle */
875
876
877
878 \f
879 /*************************************<->*************************************
880  *
881  *  RedisplayIconTitle (pcd)
882  *
883  *
884  *  Description:
885  *  -----------
886  *  Draws the title in the Icon title area
887  *
888  *
889  *  Inputs:
890  *  ------
891  *  pcd - pointer to client data
892  *
893  *  Outputs:
894  *  -------
895  *
896  *  Comments:
897  *  --------
898  * 
899  *************************************<->***********************************/
900
901 void RedisplayIconTitle (ClientData *pcd)
902 {
903     XRectangle textBox;
904     GC iconGC;
905
906     /*
907      * only proceed if we've got the right icon parts to work on
908      */
909
910     if (ICON_DECORATION(pcd) & ICON_LABEL_PART && ICON_FRAME_WIN(pcd))
911     {
912
913         /* nothing to do if no labels */
914         if (!(ICON_DECORATION(pcd) & ICON_LABEL_PART))
915             return;
916
917         /* get the box that the text sits in */
918         GetIconTitleBox (pcd, &textBox);
919
920         /* 
921          * Get appropriate GCs 
922          * Dim text if this is in the icon box and the client is mapped 
923          */
924         if ((ACTIVE_PSD->useIconBox && (P_ICON_BOX(pcd)) &&
925             !(pcd->clientFlags & CLIENT_WM_CLIENTS)) || 
926             !(wmGD.keyboardFocus == pcd)) 
927         {
928             iconGC = ICON_APPEARANCE(pcd).inactiveGC;
929         }
930         else 
931         {
932             iconGC = ICON_APPEARANCE(pcd).activeGC;
933         }
934
935         if ((ACTIVE_PSD->useIconBox) && 
936             (P_ICON_BOX(pcd)) &&
937             (FADE_NORMAL_ICON(pcd)) && 
938             (!(pcd->clientState == MINIMIZED_STATE)))
939         {
940             iconGC = FADE_ICON_TEXT_GC(pcd);
941         }
942
943         /* out with the old */
944         XClearArea (DISPLAY, 
945             ICON_FRAME_WIN(pcd), 
946             textBox.x, textBox.y,
947             (unsigned int) textBox.width, (unsigned int) textBox.height, 
948             FALSE);
949
950         /* in with the new */
951         WmDrawXmString(DISPLAY, ICON_FRAME_WIN(pcd), 
952                        ICON_APPEARANCE(pcd).fontList,
953                        pcd->iconTitle, iconGC, 
954                        textBox.x, textBox.y, textBox.width, &textBox,
955                        True);
956
957         /* 
958          * Erase & paint text in the active icon text window
959          */
960         if ((wmGD.keyboardFocus == pcd) && 
961             (ICON_DECORATION(pcd) & ICON_ACTIVE_LABEL_PART))
962         {
963             PaintActiveIconText (pcd, True);
964         }
965     }
966 } /* END OF FUNCTION  RedisplayIconTitle */
967
968
969 \f
970 /*************************************<->*************************************
971  *
972  *  GetIconDimensions (pSD, &pWidth, &pLabelHeight, &pImageHeight)
973  *
974  *
975  *  Description:
976  *  -----------
977  *  returns dimensions of icon frame parts
978  *
979  *
980  *  Inputs:
981  *  ------
982  *  pSD           - pointer to screen data
983  *  pWidth        - pointer to width of frame
984  *  pLabelHeight  - pointer to height of label part of icon
985  *  pImageHeight  - pointer to height of image part of icon 
986  *
987  * 
988  *  Outputs:
989  *  -------
990  *  *pWidth       - width of frame
991  *  *pLabelHeight - height of label part of icon
992  *  *pImageHeight - height of image part of icon 
993  *
994  *
995  *  Comments:
996  *  --------
997  * 
998  *************************************<->***********************************/
999 void GetIconDimensions (WmScreenData *pSD, unsigned int *pWidth, unsigned int *pLabelHeight, unsigned int *pImageHeight)
1000 {
1001     /*
1002      * The icon width is always keyed to the icon image maximum regardless
1003      * of whether an icon image part appears or not.
1004      */
1005     *pWidth = pSD->iconImageMaximum.width + 
1006                 ((wmGD.frameStyle == WmSLAB) ? 2 : 0) +
1007                 ICON_IMAGE_LEFT_PAD +
1008                 ICON_IMAGE_RIGHT_PAD +
1009                 2 * ICON_EXTERNAL_SHADOW_WIDTH +
1010                 4 * ICON_INTERNAL_SHADOW_WIDTH;
1011     if (wmGD.frameStyle == WmSLAB)
1012     {
1013         /* less beveling in this style */
1014         *pWidth -= 2 * ICON_INTERNAL_SHADOW_WIDTH;
1015     }
1016
1017     switch (pSD->iconDecoration & (ICON_IMAGE_PART | ICON_LABEL_PART)) 
1018     {
1019         case ICON_LABEL_PART:
1020             *pImageHeight = 0;
1021
1022             *pLabelHeight = ICON_EXTERNAL_SHADOW_WIDTH            +
1023                             WM_TOP_TITLE_PADDING                  +
1024                             TEXT_HEIGHT(pSD->iconAppearance.font) +
1025                             WM_BOTTOM_TITLE_PADDING               +
1026                             ICON_EXTERNAL_SHADOW_WIDTH;
1027             break;
1028
1029         case ICON_IMAGE_PART:
1030             *pImageHeight = ICON_EXTERNAL_SHADOW_WIDTH   +
1031                             ICON_IMAGE_TOP_PAD           +
1032                             ICON_INTERNAL_SHADOW_WIDTH   +
1033                             ICON_INTERNAL_SHADOW_WIDTH   +
1034                             pSD->iconImageMaximum.height + 
1035                             ((wmGD.frameStyle == WmSLAB) ? 2 : 0) +
1036                             ICON_INTERNAL_SHADOW_WIDTH   +
1037                             ICON_INTERNAL_SHADOW_WIDTH   +
1038                             ICON_IMAGE_BOTTOM_PAD        +
1039                             ICON_EXTERNAL_SHADOW_WIDTH;
1040             if (wmGD.frameStyle == WmSLAB)
1041             {
1042                 /* less beveling in this style */
1043                 *pImageHeight -= 2 * ICON_INTERNAL_SHADOW_WIDTH;
1044             }
1045
1046
1047             *pLabelHeight = 0;
1048
1049             break;
1050
1051         case (ICON_IMAGE_PART | ICON_LABEL_PART):
1052             *pImageHeight = ICON_EXTERNAL_SHADOW_WIDTH   +
1053                             ICON_IMAGE_TOP_PAD           +
1054                             ICON_INTERNAL_SHADOW_WIDTH   +
1055                             ICON_INTERNAL_SHADOW_WIDTH   +
1056                             pSD->iconImageMaximum.height + 
1057                             ((wmGD.frameStyle == WmSLAB) ? 2 : 0) +
1058                             ICON_INTERNAL_SHADOW_WIDTH   +
1059                             ICON_INTERNAL_SHADOW_WIDTH   +
1060                             ICON_IMAGE_BOTTOM_PAD        +
1061                             ICON_INTERNAL_SHADOW_WIDTH;
1062
1063             *pLabelHeight = ICON_INTERNAL_SHADOW_WIDTH            +
1064                             WM_TOP_TITLE_PADDING                  +
1065                             TEXT_HEIGHT(pSD->iconAppearance.font) +
1066                             WM_BOTTOM_TITLE_PADDING               +
1067                             ICON_EXTERNAL_SHADOW_WIDTH;
1068             if (wmGD.frameStyle == WmSLAB)
1069             {
1070                 /*
1071                  * In this style there is less beveling and no 
1072                  * etching between the icon image and label.
1073                  */
1074                 *pImageHeight -= 3 * ICON_INTERNAL_SHADOW_WIDTH;
1075                 *pLabelHeight -= ICON_INTERNAL_SHADOW_WIDTH;
1076             }
1077
1078             break;
1079
1080         default:
1081             *pLabelHeight = *pImageHeight = 0;
1082             break;
1083             
1084     }
1085 }
1086
1087 \f
1088 /*************************************<->*************************************
1089  *
1090  *  InitIconSize (pSD)
1091  *
1092  *
1093  *  Description:
1094  *  -----------
1095  *  set global icon size variables
1096  *
1097  *
1098  *  Inputs:
1099  *  ------
1100  *
1101  * 
1102  *  Outputs:
1103  *  -------
1104  *
1105  *
1106  *  Comments:
1107  *  --------
1108  * 
1109  *************************************<->***********************************/
1110 void InitIconSize (WmScreenData *pSD)
1111 {
1112     Cardinal label, image;
1113
1114     GetIconDimensions (pSD, (unsigned int *)&(pSD->iconWidth), 
1115         &label, &image);
1116     
1117     pSD->iconHeight = label+image;
1118
1119     pSD->iconImageHeight = image;
1120     pSD->iconLabelHeight = label;
1121
1122
1123     iconShrinkX =   IB_MARGIN_WIDTH 
1124                   + ICON_EXTERNAL_SHADOW_WIDTH
1125                   + ICON_IMAGE_LEFT_PAD
1126                   + 2 * ICON_INTERNAL_SHADOW_WIDTH;
1127
1128                 
1129     iconShrinkY =   IB_MARGIN_HEIGHT
1130                   + ICON_EXTERNAL_SHADOW_WIDTH 
1131                   + ((pSD->iconDecoration & ICON_IMAGE_PART)
1132                         ? (ICON_IMAGE_TOP_PAD + 
1133                             (2 * ICON_INTERNAL_SHADOW_WIDTH))
1134                         : (WM_TOP_TITLE_PADDING));
1135     if (wmGD.frameStyle == WmSLAB)
1136     {
1137         /* less beveling in this style */
1138         iconShrinkX -= ICON_INTERNAL_SHADOW_WIDTH;
1139         iconShrinkY -= ICON_INTERNAL_SHADOW_WIDTH;
1140     }
1141
1142
1143     iconShrinkWidth  =  pSD->iconImageMaximum.width ;
1144     if (wmGD.frameStyle == WmSLAB)
1145     {
1146         iconShrinkWidth  += 2;
1147     }
1148
1149
1150
1151
1152     switch (pSD->iconDecoration & (ICON_IMAGE_PART | ICON_LABEL_PART)) 
1153     {
1154         case ICON_LABEL_PART:
1155             iconShrinkHeight = TEXT_HEIGHT(pSD->iconAppearance.font);
1156             break;
1157
1158         case ICON_IMAGE_PART:
1159             iconShrinkHeight = pSD->iconImageMaximum.height;
1160
1161             break;
1162
1163         case (ICON_IMAGE_PART | ICON_LABEL_PART):
1164             iconShrinkHeight =  pSD->iconHeight
1165                     - ICON_EXTERNAL_SHADOW_WIDTH
1166                     - ICON_IMAGE_TOP_PAD
1167                     - ICON_INTERNAL_SHADOW_WIDTH
1168                     - ICON_INTERNAL_SHADOW_WIDTH
1169                     - ICON_IMAGE_BOTTOM_PAD
1170                     - WM_BOTTOM_TITLE_PADDING
1171                     - ICON_EXTERNAL_SHADOW_WIDTH;
1172             if (wmGD.frameStyle == WmSLAB)
1173             {
1174                 /* adjust for less beveling in this style */
1175                 iconShrinkHeight += ICON_INTERNAL_SHADOW_WIDTH;
1176             }
1177             break;
1178
1179     }
1180
1181     
1182 } /* END OF FUNCTION InitIconSize */
1183
1184 \f
1185 /*************************************<->*************************************
1186  *
1187  *  ShowActiveIcon (pcd)
1188  *
1189  *
1190  *  Description:
1191  *  -----------
1192  *  Paint the icon to indicate an "active" state
1193  *
1194  *
1195  *  Inputs:
1196  *  ------
1197  *  pcd         - pointer to client data
1198  *
1199  * 
1200  *  Outputs:
1201  *  -------
1202  *
1203  *
1204  *  Comments:
1205  *  --------
1206  *  
1207  * 
1208  *************************************<->***********************************/
1209
1210 void ShowActiveIcon (ClientData *pcd)
1211 {
1212     unsigned long attr_mask;
1213     XSetWindowAttributes window_attribs;
1214
1215     if (ICON_FRAME_WIN(pcd))
1216     {
1217         /* 
1218          * Use background pixmap if one is specified, otherwise set the
1219          * appropriate background color. 
1220          */
1221
1222         if (ICON_APPEARANCE(pcd).activeBackgroundPixmap)
1223         {
1224             attr_mask = CWBackPixmap;
1225             window_attribs.background_pixmap = 
1226                                 ICON_APPEARANCE(pcd).activeBackgroundPixmap;
1227         }
1228         else
1229         {
1230             attr_mask = CWBackPixel;
1231             window_attribs.background_pixel = 
1232                                 ICON_APPEARANCE(pcd).activeBackground;
1233         }
1234         
1235
1236         /* set active window attributes */
1237         XChangeWindowAttributes (DISPLAY, 
1238                                 ICON_FRAME_WIN(pcd), 
1239                                 attr_mask, &window_attribs);
1240
1241         /* clear the frame to the right background */
1242         if ((!ACTIVE_PSD->useIconBox) || 
1243             (P_ICON_BOX(pcd) == NULL))
1244         {
1245             if (ICON_DECORATION(pcd) & ICON_IMAGE_PART)
1246             {
1247                 Dimension dheight, dwidth;
1248
1249                 dwidth = ICON_WIDTH(pcd) -
1250                         2*ICON_EXTERNAL_SHADOW_WIDTH;
1251                 if (ICON_DECORATION(pcd) & ICON_LABEL_PART)
1252                 {
1253                     dheight =   ICON_IMAGE_HEIGHT(pcd) -
1254                                 ICON_EXTERNAL_SHADOW_WIDTH;
1255                 }
1256                 else
1257                 {
1258                     dheight =   ICON_IMAGE_HEIGHT(pcd) -
1259                                 2*ICON_EXTERNAL_SHADOW_WIDTH;
1260                 }
1261                 if (wmGD.frameStyle == WmRECESSED)
1262                 {
1263                     dheight -=  ICON_INTERNAL_SHADOW_WIDTH;
1264                 }
1265
1266                 XmeClearBorder (DISPLAY, ICON_FRAME_WIN(pcd),
1267                                 ICON_EXTERNAL_SHADOW_WIDTH, 
1268                                 ICON_EXTERNAL_SHADOW_WIDTH,
1269                                 dwidth,
1270                                 dheight,
1271                                 ICON_IMAGE_TOP_PAD);
1272             }
1273
1274             if (ICON_DECORATION(pcd) & ICON_LABEL_PART)
1275             {
1276                 XClearArea (DISPLAY, 
1277                             ICON_FRAME_WIN(pcd), 
1278                             0, 
1279                             ICON_IMAGE_HEIGHT(pcd),
1280                             (unsigned int) ICON_WIDTH(pcd), 
1281                             (unsigned int) ICON_HEIGHT(pcd), False);
1282             }
1283         }
1284         else
1285         {
1286             /*
1287              * clear only area of real frame, not highlight area
1288              */
1289
1290             XClearArea (DISPLAY, 
1291                             ICON_FRAME_WIN(pcd), 
1292                             IB_MARGIN_WIDTH,
1293                             IB_MARGIN_HEIGHT,
1294                             (unsigned int) ICON_WIDTH(pcd), 
1295                             (unsigned int) ICON_HEIGHT(pcd), False);
1296         }
1297
1298
1299         /* 
1300          * Put up a big icon text label.
1301          */
1302
1303         if (ICON_DECORATION(pcd) & ICON_ACTIVE_LABEL_PART)
1304             
1305         {
1306             if (wmGD.activeIconTextDisplayed)
1307                 PaintActiveIconText(pcd, True);
1308             else
1309                 ShowActiveIconText(pcd);
1310         }
1311
1312         /* simulate exposure of window */
1313         IconExposureProc(pcd, False);
1314
1315     }
1316
1317 } /* END OF FUNCTION ShowActiveIcon */
1318
1319
1320 \f
1321 /*************************************<->*************************************
1322  *
1323  *  ShowInactiveIcon (pcd, refresh)
1324  *
1325  *
1326  *  Description:
1327  *  -----------
1328  *  Make the icon appear "inactive"
1329  *
1330  *
1331  *  Inputs:
1332  *  ------
1333  *  pcd         - pointer to client data
1334  *
1335  *  refresh     - if True redraw the icon
1336  *
1337  *************************************<->***********************************/
1338 void ShowInactiveIcon (ClientData *pcd, Boolean refresh)
1339 {
1340     unsigned long attr_mask = 0;
1341     XSetWindowAttributes window_attribs;
1342
1343     /* turn off the active icon text */
1344     if (ICON_DECORATION(pcd) & ICON_ACTIVE_LABEL_PART)
1345     {
1346         /* pass in screen to fix multiscreen bug [P3385] */
1347         HideActiveIconText(pcd->pSD);
1348     }
1349    
1350     if (ICON_FRAME_WIN(pcd))
1351     {
1352         /* 
1353          * Use background pixmap if one is specified, otherwise set the
1354          * appropriate background color. 
1355          */
1356
1357         if (ICON_APPEARANCE(pcd).backgroundPixmap)
1358         {
1359             attr_mask |= CWBackPixmap;
1360             window_attribs.background_pixmap = 
1361                                 ICON_APPEARANCE(pcd).backgroundPixmap;
1362         }
1363         else
1364         {
1365             attr_mask |= CWBackPixel;
1366             window_attribs.background_pixel = 
1367                                 ICON_APPEARANCE(pcd).background;
1368         }
1369         
1370
1371         /* set active window attributes */
1372         XChangeWindowAttributes (DISPLAY, ICON_FRAME_WIN(pcd), attr_mask, 
1373                                  &window_attribs);
1374
1375
1376         if (refresh)
1377         {
1378             /* clear the frame to the right background */
1379             if ((!ACTIVE_PSD->useIconBox) || 
1380                 (P_ICON_BOX(pcd) == NULL))
1381             {
1382                 XmeClearBorder (DISPLAY, ICON_FRAME_WIN(pcd),
1383                                 0, 0,
1384                                 ICON_WIDTH(pcd), ICON_IMAGE_HEIGHT(pcd), 4);
1385
1386                 XClearArea (DISPLAY, 
1387                             ICON_FRAME_WIN(pcd), 
1388                             0, ICON_IMAGE_HEIGHT(pcd),
1389                             (unsigned int) ICON_WIDTH(pcd), 
1390                             (unsigned int) ICON_HEIGHT(pcd), False);
1391             }
1392             else
1393             {
1394                 /*
1395                  * clear only area of real frame, not highlight area
1396                  */
1397
1398                 XClearArea (DISPLAY, 
1399                             ICON_FRAME_WIN(pcd), 
1400                             IB_MARGIN_WIDTH,
1401                             IB_MARGIN_HEIGHT,
1402                             (unsigned int) ICON_WIDTH(pcd), 
1403                             (unsigned int) ICON_HEIGHT(pcd), False);
1404             }
1405         
1406
1407         /* simulate exposure of window */
1408             IconExposureProc(pcd, False);
1409         }
1410
1411     }
1412
1413 } /* END OF FUNTION ShowInactiveIcon  */
1414
1415
1416 \f
1417 /*************************************<->*************************************
1418  *
1419  *  ReparentIconWindow (pcd, xOffset, yOffset)
1420  *
1421  *
1422  *  Description:
1423  *  -----------
1424  *  Reparent the icon window in the center of the image area
1425  *
1426  *
1427  *  Inputs:
1428  *  ------
1429  *  pcd         - pointer to client data
1430  *  xOffset     - adjusts for icons in the iconBox
1431  *  yOffset     - adjusts for icons in the iconBox
1432  *
1433  * 
1434  *  Outputs:
1435  *  -------
1436  *
1437  *
1438  *  Comments:
1439  *  --------
1440  * 
1441  *************************************<->***********************************/
1442 void ReparentIconWindow (ClientData *pcd, int xOffset, int yOffset)
1443 {
1444     int x, y, rpX, rpY;
1445     unsigned int width, height, bw, depth;
1446     Window root;
1447     XWindowChanges windowChanges;
1448     unsigned int mask;
1449
1450     if (!pcd->pECD)
1451     {
1452     /*
1453      * Check if window size is too big
1454      */
1455     XGetGeometry (DISPLAY, pcd->iconWindow, &root, &x, &y, &width, &height, 
1456                   &bw, &depth);
1457
1458     /*
1459      * strip off previous window border and set window geometry to 
1460      * fit inside icon frame
1461      */
1462     if (width != 0) {
1463         mask = CWBorderWidth;
1464         windowChanges.border_width = 0;
1465     }
1466     else
1467     {
1468         mask = 0;
1469     }
1470
1471     if (width > ((ICON_IMAGE_MAXIMUM(pcd).width) +
1472                  ((wmGD.frameStyle == WmSLAB) ? 2 : 0)))
1473     {
1474         width = windowChanges.width = ICON_IMAGE_MAXIMUM(pcd).width +
1475                                      ((wmGD.frameStyle == WmSLAB) ? 2 : 0);
1476         mask |= CWWidth;
1477     }
1478     else if (width < ICON_IMAGE_MINIMUM(pcd).width) {
1479         width = windowChanges.width = ICON_IMAGE_MINIMUM(pcd).width;
1480         mask |= CWWidth;
1481     }
1482
1483     if (height > ((ICON_IMAGE_MAXIMUM(pcd).height) +
1484                  ((wmGD.frameStyle == WmSLAB) ? 2 : 0)))
1485     {
1486         height = windowChanges.height = ICON_IMAGE_MAXIMUM(pcd).height +
1487                                      ((wmGD.frameStyle == WmSLAB) ? 2 : 0);
1488         mask |= CWHeight;
1489     }
1490     else if (height < ICON_IMAGE_MINIMUM(pcd).height) {
1491         height = windowChanges.height = ICON_IMAGE_MINIMUM(pcd).height;
1492         mask |= CWHeight;
1493     }
1494
1495     if (mask)
1496         XConfigureWindow (DISPLAY, pcd->iconWindow, mask, &windowChanges);
1497
1498     /*
1499      * Reparent the icon window to the center of the icon image frame
1500      */
1501
1502     if (ICON_DECORATION(pcd) & ICON_LABEL_PART)
1503     {
1504         yOffset += ICON_INTERNAL_SHADOW_WIDTH;
1505     }
1506
1507     rpX = ((ICON_WIDTH(pcd) - width)/2)    + xOffset;
1508     rpY = ((ICON_IMAGE_HEIGHT(pcd) - height)/2) + yOffset;
1509
1510
1511
1512
1513     XReparentWindow (DISPLAY, pcd->iconWindow, ICON_FRAME_WIN(pcd), rpX, rpY);
1514     pcd->clientFlags  |= ICON_REPARENTED;
1515
1516     /*
1517      * Map the icon window when the icon frame is mapped.
1518      */
1519     } /* END if (!pcd->pECD) */
1520 } /* END OF FUNCTION ReparentIconWindow */
1521
1522 \f
1523 /*************************************<->*************************************
1524  *
1525  *  PutBoxOnScreen (screen, px, py, width, height)
1526  *
1527  *
1528  *  Description:
1529  *  -----------
1530  *  Changes the position of the passed box so that it is all on screen
1531  *
1532  *
1533  *  Inputs:
1534  *  ------
1535  *  screen      - screen we're talking about
1536  *  px          - pointer to x-coord
1537  *  py          - pointer to y-coord
1538  *  width       - width of box
1539  *  height      - height of box
1540  * 
1541  *  Outputs:
1542  *  -------
1543  *  *px         - new x-coord
1544  *  *py         - new y-coord
1545  *
1546  *
1547  *  Comments:
1548  *  --------
1549  * 
1550  *************************************<->***********************************/
1551 void PutBoxOnScreen (int screen, int *px, int *py, unsigned int width, unsigned int height)
1552 {
1553     /*
1554      * Place active label text nicely on screen
1555      */
1556
1557     if (*px+width+1 > DisplayWidth (DISPLAY, screen))
1558         *px -= (*px+width+1) - DisplayWidth (DISPLAY, screen);
1559
1560     if (*py+height+1 > DisplayHeight (DISPLAY, screen))
1561         *py -= (*py+height+1) - DisplayHeight (DISPLAY, screen);
1562
1563     if (*px < 1) *px = 1;
1564
1565     if (*py < 1) *py = 1;
1566
1567 } /* END OF FUNCTION PutBoxOnScreen */
1568
1569 \f
1570 /*************************************<->*************************************
1571  *
1572  *  PutBoxInIconBox (pCD, px, py, width, height)
1573  *
1574  *
1575  *  Description:
1576  *  -----------
1577  *  Changes the position of the passed box so that it is not
1578  *  clipped by the bulletin board
1579  *  
1580  *
1581  *
1582  *  Inputs:
1583  *  ------
1584  *  pCD         - pointer to client data
1585  *  px          - pointer to x-coord
1586  *  py          - pointer to y-coord
1587  *  width       - width of box
1588  *  height      - height of box
1589  * 
1590  *  Outputs:
1591  *  -------
1592  *  *px         - new x-coord
1593  *  *py         - new y-coord
1594  *
1595  *
1596  *  Comments:
1597  *  --------
1598  * 
1599  *************************************<->***********************************/
1600 void PutBoxInIconBox (ClientData *pCD, int *px, int *py, unsigned int *width, unsigned int *height)
1601 {
1602
1603     int i;
1604     Arg getArgs[3];
1605     Dimension bBoardWidth;
1606     Dimension bBoardHeight;
1607
1608     int clipWidth;
1609     int clipHeight;
1610
1611
1612     i=0;
1613     XtSetArg (getArgs[i], XmNwidth, (XtArgVal) &bBoardWidth ); i++;
1614     XtSetArg (getArgs[i], XmNheight, (XtArgVal) &bBoardHeight ); i++;
1615     XtGetValues (P_ICON_BOX(pCD)->bBoardWidget, getArgs, i);
1616
1617     clipWidth = (int) bBoardWidth;
1618     clipHeight = (int) bBoardHeight;
1619
1620     if (*px + *width-1 > clipWidth)
1621         *px -= (*px + *width-1) - clipWidth;
1622
1623     if (*py + *height-1 > clipHeight)
1624         *py -= (*py + *height-1) - clipHeight;
1625
1626     if (*px < 0) *px = 0;
1627
1628     if (*py < 0) *py = 0;
1629
1630
1631 } /* END OF FUNCTION PutBoxInIconBox */
1632
1633 \f
1634 /*************************************<->*************************************
1635  *
1636  *  CreateActiveIconTextWindow (pSD)
1637  *
1638  *
1639  *  Description:
1640  *  -----------
1641  *  creates the window that's popped up when an icon is activated
1642  *
1643  *  Inputs:
1644  *  ------
1645  *  pSD         - pointer to screen data
1646  * 
1647  *  Outputs:
1648  *  -------
1649  *
1650  *  Comments:
1651  *  --------
1652  * 
1653  *************************************<->***********************************/
1654
1655 void CreateActiveIconTextWindow (WmScreenData *pSD)
1656 {
1657     XSetWindowAttributes window_attribs;
1658     unsigned long attr_mask;
1659
1660     /* create active icon text window */
1661     attr_mask = CWEventMask| CWCursor;
1662     window_attribs.event_mask =  ExposureMask;
1663     window_attribs.cursor = wmGD.workspaceCursor;
1664
1665     /* 
1666      * Use background pixmap if one is specified, otherwise set the
1667      * appropriate background color. 
1668      */
1669
1670     if (pSD->iconAppearance.activeBackgroundPixmap)
1671     {
1672         attr_mask |= CWBackPixmap;
1673         window_attribs.background_pixmap = 
1674                                 pSD->iconAppearance.activeBackgroundPixmap;
1675     }
1676     else
1677     {
1678         attr_mask |= CWBackPixel;
1679         window_attribs.background_pixel = 
1680                                 pSD->iconAppearance.activeBackground;
1681     }
1682         
1683
1684     pSD->activeIconTextWin = XCreateWindow (DISPLAY,
1685                                        pSD->rootWindow, /* parent */
1686                                        0, 0,            /* x, y */
1687                                        1, 1,            /* width, height */
1688                                        0,               /* border width */
1689                                        CopyFromParent,  /* depth */
1690                                        InputOutput,     /* class */
1691                                        CopyFromParent,  /* visual */
1692                                        attr_mask,
1693                                        &window_attribs);
1694
1695     
1696     pSD->activeLabelParent = pSD->rootWindow;
1697
1698 } /* END OF FUNCTION CreateActiveIconTextWindow */
1699
1700
1701 \f
1702 /*************************************<->*************************************
1703  *
1704  *  PaintActiveIconText (pcd, erase)
1705  *
1706  *
1707  *  Description:
1708  *  -----------
1709  *
1710  *
1711  *  Inputs:
1712  *  ------
1713  *  pcd         - pointer to client data
1714  *  erase       - if true, then erase the area before repainting
1715  * 
1716  *  Outputs:
1717  *  -------
1718  *
1719  *
1720  *  Comments:
1721  *  --------
1722  * 
1723  *************************************<->***********************************/
1724 void PaintActiveIconText (ClientData *pcd, Boolean erase)
1725 {
1726     XRectangle textBox;
1727     GC iconGC, topGC, botGC;
1728
1729     if (!(ICON_DECORATION(pcd) & ICON_ACTIVE_LABEL_PART))
1730         return;
1731
1732     /* get appropriate GCs */
1733     iconGC = ICON_APPEARANCE(pcd).activeGC;
1734     topGC = ICON_APPEARANCE(pcd).activeTopShadowGC;
1735     botGC = ICON_APPEARANCE(pcd).activeBottomShadowGC;
1736
1737     /* draw shadowing */
1738
1739     if (pActiveIconTopRects) {
1740         XFillRectangles (DISPLAY, 
1741                          pcd->pSD->activeIconTextWin,
1742                          topGC,
1743                          pActiveIconTopRects->prect,
1744                          pActiveIconTopRects->used);
1745     }
1746
1747     if (pActiveIconBotRects) {
1748         XFillRectangles (DISPLAY,
1749                          pcd->pSD->activeIconTextWin,
1750                          botGC,
1751                          pActiveIconBotRects->prect,
1752                          pActiveIconBotRects->used);
1753     }
1754
1755     /* paint the text */
1756     textBox.x = ICON_EXTERNAL_SHADOW_WIDTH;
1757     textBox.y = ICON_EXTERNAL_SHADOW_WIDTH;
1758     textBox.width = activeIconTextWidth - 2*ICON_EXTERNAL_SHADOW_WIDTH;
1759     textBox.height = activeIconTextHeight - 2*ICON_EXTERNAL_SHADOW_WIDTH;
1760
1761     if (erase)
1762     {
1763         XClearArea (DISPLAY, pcd->pSD->activeIconTextWin, textBox.x, textBox.y,
1764                     (unsigned int) textBox.width, 
1765                     (unsigned int) textBox.height, 
1766                     FALSE);
1767     }
1768
1769     WmDrawXmString(DISPLAY, pcd->pSD->activeIconTextWin, 
1770                    ICON_APPEARANCE(pcd).fontList,
1771                    pcd->iconTitle, iconGC, 
1772                    textBox.x, textBox.y, textBox.width, &textBox, True);
1773
1774
1775 } /* END OF FUNCTION PaintActiveIconText */
1776
1777 \f
1778 /*************************************<->*************************************
1779  *
1780  *  ShowActiveIconText (pcd)
1781  *
1782  *
1783  *  Description:
1784  *  -----------
1785  *
1786  *
1787  *  Inputs:
1788  *  ------
1789  * 
1790  *  Outputs:
1791  *  -------
1792  *
1793  *
1794  *  Comments:
1795  *  --------
1796  * 
1797  *************************************<->***********************************/
1798 void ShowActiveIconText (ClientData *pcd)
1799 {
1800     XWindowAttributes iconFrameAttribs;
1801     XSetWindowAttributes window_attribs;
1802     XWindowChanges windowChanges;
1803     unsigned int mask;
1804     int x, y; 
1805     unsigned int junk;
1806     Window root;
1807     Dimension dWidth, dHeight;
1808
1809
1810     /* 
1811      * put up a big icon text label
1812      */
1813     if (pcd->pSD->activeIconTextWin) {
1814         /* copy event mask from icon frame window */
1815         XGetWindowAttributes (DISPLAY, ICON_FRAME_WIN(pcd), &iconFrameAttribs);
1816
1817         /* set attributes of window */
1818         window_attribs.event_mask =  iconFrameAttribs.your_event_mask;
1819         XChangeWindowAttributes (DISPLAY, pcd->pSD->activeIconTextWin,
1820                                  CWEventMask, &window_attribs);
1821
1822         /* set up geometry for the window */
1823
1824         XmStringExtent (ICON_APPEARANCE(pcd).fontList, pcd->iconTitle,
1825                         &dWidth, &dHeight);
1826
1827         activeIconTextHeight =  (unsigned int) dHeight + 
1828                   WM_BOTTOM_TITLE_PADDING +
1829                   2*ICON_EXTERNAL_SHADOW_WIDTH;
1830
1831         activeIconTextWidth = (unsigned int) dWidth;
1832
1833         if (activeIconTextWidth < (1.2 * ICON_WIDTH(pcd))) 
1834         {
1835             activeIconTextWidth = 1.2 * ICON_WIDTH(pcd);
1836         }
1837
1838         activeIconTextWidth += 2*ICON_EXTERNAL_SHADOW_WIDTH;
1839
1840         XGetGeometry (DISPLAY, 
1841                         (Drawable) ICON_FRAME_WIN(pcd), 
1842                         &root, &x, &y, 
1843                         &junk, &junk, &junk, &junk);
1844
1845
1846         y += ICON_IMAGE_HEIGHT(pcd);
1847         x -= (activeIconTextWidth - ICON_WIDTH(pcd))/2;
1848
1849
1850
1851         if (!(P_ICON_BOX(pcd)))
1852         {
1853             /* 
1854              * This is a normal icon
1855              */
1856             PutBoxOnScreen (SCREEN_FOR_CLIENT(pcd), &x, &y, 
1857                     activeIconTextWidth, activeIconTextHeight);
1858             if (ACTIVE_LABEL_PARENT(pcd) != root)
1859             {
1860                 XReparentWindow(DISPLAY, pcd->pSD->activeIconTextWin , 
1861                                 root, x, y );
1862                 ACTIVE_LABEL_PARENT(pcd) = root;
1863             }
1864             
1865         }
1866         else
1867         {
1868             /* 
1869              * This is an icon in an icon box
1870              */
1871             x = x + IB_MARGIN_WIDTH;
1872             y = y + IB_MARGIN_HEIGHT;
1873
1874             if(!(pcd->pSD->iconDecoration & ( ICON_LABEL_PART)))
1875             {
1876                 y -= activeIconTextHeight;
1877             }
1878
1879             PutBoxInIconBox (pcd, &x, &y, 
1880                                 &activeIconTextWidth, &activeIconTextHeight);
1881             if (ACTIVE_LABEL_PARENT(pcd) != pcd->client)
1882             {
1883                 XReparentWindow(DISPLAY, pcd->pSD->activeIconTextWin , 
1884                     XtWindow(P_ICON_BOX(pcd)->bBoardWidget),
1885                     x, y );
1886                 ACTIVE_LABEL_PARENT(pcd) = pcd->client;
1887             }
1888         }
1889
1890
1891         mask = CWX | CWY | CWWidth | CWHeight; 
1892         windowChanges.x = x;
1893         windowChanges.y = y;
1894         windowChanges.width = activeIconTextWidth;
1895         windowChanges.height = activeIconTextHeight;
1896         XConfigureWindow (DISPLAY, pcd->pSD->activeIconTextWin, mask, 
1897                           &windowChanges);
1898
1899         /* bevel the rectangle around the edges */
1900         if ((pActiveIconTopRects && pActiveIconBotRects) || 
1901             ((pActiveIconTopRects = 
1902                  AllocateRList((unsigned)4*ICON_EXTERNAL_SHADOW_WIDTH)) &&
1903              (pActiveIconBotRects = 
1904                  AllocateRList((unsigned)4*ICON_EXTERNAL_SHADOW_WIDTH))))
1905         {
1906             pActiveIconTopRects->used = 0;
1907             pActiveIconBotRects->used = 0;
1908             BevelRectangle (pActiveIconTopRects,        
1909                             pActiveIconBotRects, 
1910                             0, 0, 
1911                             activeIconTextWidth, 
1912                             activeIconTextHeight,
1913                             ICON_EXTERNAL_SHADOW_WIDTH,
1914                             ICON_EXTERNAL_SHADOW_WIDTH,
1915                             ICON_EXTERNAL_SHADOW_WIDTH,
1916                             ICON_EXTERNAL_SHADOW_WIDTH);
1917         }
1918
1919         XMapRaised (DISPLAY, pcd->pSD->activeIconTextWin);
1920         wmGD.activeIconTextDisplayed = True;
1921
1922         /* save context for this window */
1923         XSaveContext (DISPLAY, pcd->pSD->activeIconTextWin, 
1924             wmGD.windowContextType, (caddr_t) pcd);
1925     }
1926 } /* END OF FUNCTION ShowActiveIconText */
1927
1928 \f
1929 /*************************************<->*************************************
1930  *
1931  *  HideActiveIconText ()
1932  *
1933  *
1934  *  Description:
1935  *  -----------
1936  *  Hides the big label shown over the active icon.
1937  *
1938  *
1939  *  Inputs:
1940  *  ------
1941  * 
1942  *  Outputs:
1943  *  -------
1944  *
1945  *
1946  *  Comments:
1947  *  --------
1948  * 
1949  *************************************<->***********************************/
1950 void HideActiveIconText (WmScreenData *pSD)
1951 {
1952
1953
1954     if ((pSD && pSD->activeIconTextWin) || ACTIVE_ICON_TEXT_WIN)
1955     {
1956         /* disassociate the big label window with this client */
1957         XDeleteContext (DISPLAY, 
1958                         pSD 
1959                          ? pSD->activeIconTextWin
1960                          : ACTIVE_PSD->activeIconTextWin, 
1961                         wmGD.windowContextType);
1962
1963         /* hide the big label */
1964         XUnmapWindow (DISPLAY,
1965                       pSD 
1966                        ? pSD->activeIconTextWin
1967                        : ACTIVE_PSD->activeIconTextWin);
1968         wmGD.activeIconTextDisplayed = False;
1969     }
1970 }
1971
1972 \f
1973 /*************************************<->*************************************
1974  *
1975  *  MoveActiveIconText (pcd)
1976  *
1977  *
1978  *  Description:
1979  *  -----------
1980  *
1981  *
1982  *  Inputs:
1983  *  ------
1984  * 
1985  *  Outputs:
1986  *  -------
1987  *
1988  *
1989  *  Comments:
1990  *  --------
1991  * 
1992  *************************************<->***********************************/
1993 void MoveActiveIconText (ClientData *pcd)
1994 {
1995     int x, y; 
1996     unsigned int junk;
1997     Window root;
1998     Dimension dWidth, dHeight;
1999     
2000     
2001     /* 
2002      * put up a big icon text label
2003      */
2004     if (pcd->pSD->activeIconTextWin && wmGD.activeIconTextDisplayed) {
2005         /* set up geometry for the window */
2006
2007         XmStringExtent (ICON_APPEARANCE(pcd).fontList, pcd->iconTitle,
2008                         &dWidth, &dHeight);
2009
2010         activeIconTextHeight =  (unsigned int) dHeight +
2011                   WM_BOTTOM_TITLE_PADDING +
2012                   2 * ICON_EXTERNAL_SHADOW_WIDTH;
2013         
2014         activeIconTextWidth = (unsigned int) dWidth;
2015
2016         if (activeIconTextWidth < (1.2 * ICON_WIDTH(pcd))) 
2017         {
2018             activeIconTextWidth = 1.2 * ICON_WIDTH(pcd);
2019         }
2020         
2021         activeIconTextWidth += 2 * ICON_EXTERNAL_SHADOW_WIDTH;
2022
2023         XGetGeometry (DISPLAY, 
2024                         (Drawable) ICON_FRAME_WIN(pcd), 
2025                         &root, &x, &y, 
2026                         &junk, &junk, &junk, &junk);
2027
2028         
2029         y += ICON_IMAGE_HEIGHT(pcd);
2030         x -= (activeIconTextWidth - ICON_WIDTH(pcd))/2;
2031
2032         if (!(P_ICON_BOX(pcd)))
2033         {
2034             /* This is a normal icon */
2035             PutBoxOnScreen (SCREEN_FOR_CLIENT(pcd), &x, &y, 
2036                 activeIconTextWidth, activeIconTextHeight);
2037         }
2038         else 
2039         {
2040             /* icon box */
2041             x = x + IB_MARGIN_WIDTH;
2042             y = y + IB_MARGIN_HEIGHT;
2043
2044             if(!(pcd->pSD->iconDecoration & ( ICON_LABEL_PART)))
2045             {
2046                 y -= activeIconTextHeight;
2047             }
2048
2049             PutBoxInIconBox (pcd, &x, &y, 
2050                              &activeIconTextWidth, &activeIconTextHeight);
2051         }
2052         
2053         XMoveWindow(DISPLAY, pcd->pSD->activeIconTextWin, x, y );
2054
2055     }
2056 }  /* END OF FUNCTION  MoveActiveIconText */
2057
2058