Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtwm / WmCDecor.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 librararies 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 OPEN SOFTWARE FOUNDATION, INC. 
25  * ALL RIGHTS RESERVED 
26 */ 
27 /* 
28  * Motif Release 1.2.1
29 */ 
30 #ifdef REV_INFO
31 #ifndef lint
32 static char rcsid[] = "$XConsortium: WmCDecor.c /main/7 1996/06/20 09:38:16 rswiston $"
33 #endif
34 #endif
35 /*
36  * (c) Copyright 1987,1988,1989,1990,1991,1993 HEWLETT-PACKARD COMPANY */
37
38 /*
39  * Included Files:
40  */
41
42 #include "WmGlobal.h"
43 #include "WmXSMP.h"
44
45
46 #include <X11/cursorfont.h>
47 #include <Xm/Xm.h>
48
49
50
51 /* 
52  * Definitions
53  */
54
55 /*
56  * include extern functions
57  */
58 #include "WmCDecor.h"
59 #include "WmCDInfo.h"
60 #include "WmError.h"
61 #include "WmGraphics.h"
62 #include "WmIconBox.h"
63 #include "WmMenu.h"
64 #include "WmWinInfo.h"
65
66
67 /*
68  * Global Variables:
69  */
70 typedef struct {
71     int external;               /* bevel from frame to root */
72     int join;                   /* bevel between frame components */
73     int internal;               /* bevel from frame to client */
74 } Single_Bevel_Count;
75
76 typedef struct {
77     Single_Bevel_Count top;
78     Single_Bevel_Count bottom;
79 } Bevel_Count;
80
81 /* 
82  * "Worst case" bevel counts for frame pieces: this structure is 
83  * indexed by definitions in WmGlobal.h. Edit if they change!
84  *
85  * These counts are multiplied by the internal, external,
86  * and join bevel resources to determine the sizes of dynamic
87  * data structures to allocate. 
88  *
89  */
90 static Bevel_Count Bevels[] =
91 {
92     { {0, 0, 0}, {0, 0, 0} },           /* FRAME_NONE */
93     { {0, 0, 0}, {0, 0, 0} },           /* FRAME_CLIENT */
94     { {0, 4, 0}, {0, 3, 1} },           /* FRAME_SYSTEM */
95     { {0, 2, 0}, {0, 1, 1} },           /* FRAME_TITLE */
96     { {0, 4, 0}, {0, 3, 1} },           /* FRAME_MINIMIZE */
97     { {0, 4, 0}, {0, 3, 1} },           /* FRAME_MAXIMIZE */
98     { {2, 0, 0}, {0, 2, 2} },           /* FRAME_RESIZE_NW */
99     { {1, 1, 0}, {0, 1, 1} },           /* FRAME_RESIZE_N */
100     { {1, 1, 1}, {1, 1, 1} },           /* FRAME_RESIZE_NE */
101     { {0, 1, 1}, {1, 1, 0} },           /* FRAME_RESIZE_E */
102     { {0, 2, 2}, {2, 0, 0} },           /* FRAME_RESIZE_SE */
103     { {0, 1, 1}, {1, 1, 0} },           /* FRAME_RESIZE_S */
104     { {1, 1, 1}, {1, 1, 1} },           /* FRAME_RESIZE_SW */
105     { {1, 1, 0}, {0, 1, 1} }            /* FRAME_RESIZE_W */
106 };
107
108
109
110
111
112 \f
113 /*************************************<->*************************************
114  *
115  *  FrameWindow (pcd)
116  *
117  *
118  *  Description:
119  *  -----------
120  *  Build a decorated frame for a client window and reparent the client 
121  *  window to the frame.
122  *
123  *
124  *  Inputs:
125  *  ------
126  *  pcd         - pointer to client data structure for window
127  *
128  *                << Need the following member data >>
129  *
130  *                client
131  *                fields from WM_HINTS property
132  *                fields from WM_CLASS property
133  *                fields from WM_NORMAL_HINTS property
134  *                clientX
135  *                clientY
136  *                clientWidth
137  *                clientHeight
138  *                fields from WM_NAME property
139  * 
140  * 
141  *  Outputs:
142  *  -------
143  *
144  * 
145  *  Comments:
146  *  --------
147  *  This will create a top level shell (frame), fill in the appropriate 
148  *  decoration, and reparent the window (in *pcd) to the frame.
149  * 
150  *************************************<->***********************************/
151
152 Boolean FrameWindow (ClientData *pcd)
153 {
154     if (!ConstructFrame (pcd))          /* window hierarchy for frame */
155     {
156         return(FALSE);
157     }
158
159     GenerateFrameDisplayLists (pcd);    /* graphics for frame decoration */
160
161     AdoptClient(pcd);                   /* reparent the window */
162
163 #ifndef NO_SHAPE
164     /* shape the frame */
165     if (wmGD.hasShape && pcd->wShaped)
166     {
167         SetFrameShape (pcd);
168     }
169 #endif /* NO_SHAPE */
170
171     return(TRUE);
172
173 } /* END OF FUNCTION FrameWindow */
174
175
176 \f
177 /*************************************<->*************************************
178  *
179  *  FrameExposureProc (pcd)
180  *
181  *
182  *  Description:
183  *  -----------
184  *  Repaint the frame graphics
185  *
186  *
187  *  Inputs:
188  *  ------
189  *  pcd         - pointer to client data
190  *
191  * 
192  *  Outputs:
193  *  -------
194  *  none
195  *
196  *  Comments:
197  *  --------
198  *  Assumes that the display lists for the frame graphics are already
199  *  set up.
200  * 
201  *************************************<->***********************************/
202
203 void FrameExposureProc (ClientData *pcd)
204 {
205     GC topGC, botGC;
206     Window win = pcd->clientFrameWin;
207
208     /* use "active" GCs if we have keyboard focus */
209
210     if (pcd == wmGD.keyboardFocus) {
211         topGC = CLIENT_APPEARANCE(pcd).activeTopShadowGC;
212         botGC = CLIENT_APPEARANCE(pcd).activeBottomShadowGC;
213     }
214     else {
215         topGC = CLIENT_APPEARANCE(pcd).inactiveTopShadowGC;
216         botGC = CLIENT_APPEARANCE(pcd).inactiveBottomShadowGC;
217     }
218
219     /* draw the frame decoration */
220
221     if (pcd->pclientTopShadows)  {
222         XFillRectangles (DISPLAY, 
223                          win, 
224                          topGC,
225                          pcd->pclientTopShadows->prect,
226                          pcd->pclientTopShadows->used);
227     }
228
229     if (pcd->pclientBottomShadows) { 
230         XFillRectangles (DISPLAY,
231                          win,
232                          botGC,
233                          pcd->pclientBottomShadows->prect,
234                          pcd->pclientBottomShadows->used);
235     }
236
237     if (DECOUPLE_TITLE_APPEARANCE(pcd) && 
238         (pcd->decor & MWM_DECOR_TITLE))
239     {
240         if (pcd == wmGD.keyboardFocus) {
241             topGC = CLIENT_TITLE_APPEARANCE(pcd).activeTopShadowGC;
242             botGC = CLIENT_TITLE_APPEARANCE(pcd).activeBottomShadowGC;
243         }
244         else {
245             topGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveTopShadowGC;
246             botGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveBottomShadowGC;
247         }
248
249         if (pcd->pclientTitleTopShadows)  {
250                 XFillRectangles (DISPLAY, 
251                              pcd->clientTitleWin, 
252                              topGC,
253                              pcd->pclientTitleTopShadows->prect,
254                              pcd->pclientTitleTopShadows->used);
255         }
256
257         if (pcd->pclientTitleBottomShadows) { 
258             XFillRectangles (DISPLAY,
259                              pcd->clientTitleWin,
260                              botGC,
261                              pcd->pclientTitleBottomShadows->prect,
262                              pcd->pclientTitleBottomShadows->used);
263         }
264     }
265
266     /* draw the title bar text */
267     DrawWindowTitle(pcd, False);
268 }
269
270
271 \f
272 /*************************************<->*************************************
273  *
274  *  BaseWinExposureProc (pcd)
275  *
276  *
277  *  Description:
278  *  -----------
279  *  Repaint the beveled matte graphics if any.
280  *
281  *
282  *  Inputs:
283  *  ------
284  *  pcd         - pointer to client data
285  *
286  * 
287  *  Outputs:
288  *  -------
289  *  none
290  *
291  *  Comments:
292  *  --------
293  *  Assumes that the display lists for the matte graphics are already
294  *  set up.
295  * 
296  *************************************<->***********************************/
297
298 void BaseWinExposureProc (ClientData *pcd)
299 {
300     /* bevel the matte (if there is one) */
301
302     if (pcd->matteWidth > 0) {
303
304         if (pcd->pclientMatteTopShadows) {
305             XFillRectangles (DISPLAY,
306                              pcd->clientBaseWin,
307                              pcd->clientMatteTopShadowGC,
308                              pcd->pclientMatteTopShadows->prect,
309                              pcd->pclientMatteTopShadows->used);
310         }
311
312         if (pcd->pclientMatteBottomShadows) {
313             XFillRectangles (DISPLAY,
314                              pcd->clientBaseWin,
315                              pcd->clientMatteBottomShadowGC,
316                              pcd->pclientMatteBottomShadows->prect,
317                              pcd->pclientMatteBottomShadows->used);
318         }
319     }
320 }
321
322
323 \f
324 /*************************************<->*************************************
325  *
326  *  ConstructFrame (pcd)
327  *
328  *
329  *  Description:
330  *  -----------
331  *  Construct the window hierarchy for the frame
332  *
333  *
334  *  Inputs:
335  *  ------
336  *  pcd         - pointer to client data record
337  * 
338  *  Outputs:
339  *  -------
340  *  pcd         - modified
341  *
342  *
343  *  Comments:
344  *  --------
345  * 
346  *************************************<->***********************************/
347
348 Boolean ConstructFrame (ClientData *pcd)
349 {
350     unsigned long        decoration = pcd->decor;
351     unsigned int         wclass;                /* window class */
352     unsigned long        attr_mask;
353     XSetWindowAttributes window_attribs;
354     int                  frmX, frmY;
355
356     /* set frame information */
357     SetFrameInfo (pcd);
358
359     /* allocate space */
360     if (!AllocateFrameDisplayLists(pcd)) {
361         return(FALSE);
362     }
363
364     /* create frame window  */
365
366     attr_mask =  CWEventMask;
367     window_attribs.event_mask = (ButtonPressMask | ButtonReleaseMask |
368                                  SELECT_BUTTON_MOTION_MASK | 
369                                  DMANIP_BUTTON_MOTION_MASK |
370                                  ExposureMask);
371
372     if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER) ||
373         (wmGD.colormapFocusPolicy == CMAP_FOCUS_POINTER))
374     {
375         window_attribs.event_mask |= EnterWindowMask | LeaveWindowMask;
376     }
377
378     /* 
379      * Use background pixmap if one is specified, otherwise set the
380      * appropriate background color. 
381      */
382
383     if (CLIENT_APPEARANCE(pcd).backgroundPixmap)
384     {
385         attr_mask |= CWBackPixmap;
386         window_attribs.background_pixmap =
387                 CLIENT_APPEARANCE(pcd).backgroundPixmap;
388     }
389     else
390     {
391         attr_mask |= CWBackPixel;
392         window_attribs.background_pixel = CLIENT_APPEARANCE(pcd).background;
393     }
394
395     attr_mask |= CWCursor;
396     window_attribs.cursor = wmGD.workspaceCursor;
397
398     frmY = pcd->frameInfo.y;
399     frmX = pcd->frameInfo.x;
400
401     if (CLIENT_APPEARANCE(pcd).saveUnder &&
402         WmGetWindowAttributes (pcd->client) &&
403         wmGD.windowAttributes.save_under)
404     {
405         attr_mask |= CWSaveUnder;
406         window_attribs.save_under = True;
407     }
408
409             pcd->clientFrameWin = XCreateWindow(DISPLAY, 
410                                 RootWindow (DISPLAY,
411                                     SCREEN_FOR_CLIENT(pcd)),
412                                 frmX, 
413                                 frmY, 
414                                 pcd->frameInfo.width, 
415                         pcd->frameInfo.height, 0, 
416                         CopyFromParent,InputOutput,CopyFromParent,
417                         attr_mask, &window_attribs);
418
419     /* create resizing windows with cursors*/
420     if (SHOW_RESIZE_CURSORS(pcd) && (decoration & MWM_DECOR_RESIZEH)) {
421         CreateStretcherWindows (pcd);
422     }
423
424     /* 
425      * Create title bar window. If the title bar has its own appearance,
426      * or if there is no border around the client area,
427      * then we need to create an input/output window to draw in. Otherwise
428      * we can use an input-only window (to clip the corner resize windows).
429      */
430     if (decoration & MWM_DECOR_TITLE) {
431
432         attr_mask = CWCursor;
433         window_attribs.cursor = wmGD.workspaceCursor;
434
435         if (DECOUPLE_TITLE_APPEARANCE(pcd)) 
436         {
437             /* title bar has a different appearance than rest of frame */
438             wclass = InputOutput;
439
440             /* need to handle exposure events */
441             attr_mask |= CWEventMask;
442             window_attribs.event_mask = ExposureMask;
443
444             /* 
445              * Use background pixmap if one is specified, otherwise set the
446              * appropriate background color. 
447              */
448
449             if (CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap)
450             {
451                 attr_mask |= CWBackPixmap;
452                 window_attribs.background_pixmap =
453                             CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap;
454             }
455             else
456             {
457                 attr_mask |= CWBackPixel;
458                 window_attribs.background_pixel = 
459                             CLIENT_TITLE_APPEARANCE(pcd).background;
460             }
461         }
462         else 
463         {
464             /* title bar has same appearance as rest of frame */
465             wclass = InputOnly;
466         }
467
468         pcd->clientTitleWin = XCreateWindow(DISPLAY, pcd->clientFrameWin,
469                                 (int) pcd->frameInfo.upperBorderWidth, 
470                                 (int) pcd->frameInfo.upperBorderWidth, 
471                                 pcd->frameInfo.width - 
472                                     2*pcd->frameInfo.upperBorderWidth, 
473                                 pcd->frameInfo.titleBarHeight, 
474                                 0, 
475                                 CopyFromParent,wclass,CopyFromParent,
476                                 attr_mask, &window_attribs);
477     }
478
479     /* generate gadget position search structure */
480     if (!AllocateGadgetRectangles (pcd))
481         return(FALSE);
482     ComputeGadgetRectangles (pcd);
483
484
485     /*
486      * Create base window for reparenting. Save rectangle data for use
487      * in event dispatching.
488      */
489
490     window_attribs.event_mask = (SubstructureRedirectMask |
491                                  SubstructureNotifyMask |
492                                  FocusChangeMask);
493     if (pcd->matteWidth > 0)
494     {
495         window_attribs.event_mask |= ExposureMask;
496         window_attribs.background_pixel = pcd->matteBackground;
497     }
498     else
499     {
500         window_attribs.background_pixel = 
501             CLIENT_TITLE_APPEARANCE(pcd).background;
502     }
503
504     attr_mask = CWBackPixel | CWEventMask;
505
506         pcd->clientBaseWin = XCreateWindow(DISPLAY, pcd->clientFrameWin,
507                                 BaseWindowX (pcd),
508                                 BaseWindowY (pcd),
509                                 BaseWindowWidth (pcd),
510                                 BaseWindowHeight (pcd),
511                                 0, 
512                                 CopyFromParent,InputOutput,CopyFromParent,
513                                 attr_mask, &window_attribs);
514
515     /* map all subwindows of client frame */
516
517     XMapSubwindows(DISPLAY, pcd->clientFrameWin);
518     return(TRUE);
519 }
520
521
522
523 \f
524 /*************************************<->*************************************
525  *
526  *  GenerateFrameDisplayLists (pcd)
527  *
528  *
529  *  Description:
530  *  -----------
531  *  Set up the graphic decorations for the frame
532  *
533  *
534  *  Inputs:
535  *  ------
536  *  pcd         - pointer to client data record
537  *
538  * 
539  *  Outputs:
540  *  -------
541  *  pcd         - modified
542  *
543  *
544  *  Comments:
545  *  --------
546  *  o This must be called after ConstructFrame to insure that the memory
547  *    for the rectangles has been allocated.
548  *  o If cnum values for StretcherCorner change, also change
549  *    StretcherCorner() in WmGraphics.c
550  *  o The variable internalBevel sets the depth of shadowing from the 
551  *    frame to the client area.
552  *  o The variable insideBevel is used to decide how deep the bevel is
553  *    immediately inside the frame. This may not be internalBevel if
554  *    there's a matte, for example.
555  *  o The variable diffBevel stores the difference between insideBevel
556  *    and what's needed so the bottom of the title bar is correctly 
557  *    beveled down to the client.
558  * 
559  *************************************<->***********************************/
560
561 void GenerateFrameDisplayLists (ClientData *pcd)
562 {
563     unsigned long decoration   = pcd->decor;
564     int           matte_width  = pcd->matteWidth;
565
566     int insideBevel, inset, diffBevel;
567     unsigned int nTitleBevel, sTitleBevel, eTitleBevel, wTitleBevel;
568     unsigned int meTitleBevel, inWidth;
569     int x, y, xAdj, yAdj;
570     unsigned int width, height;
571     RList *prlTop, *prlBot;
572
573     int jX, jY;
574     unsigned int jW, jH;
575  
576     /* zero out part counts */
577
578     if (pcd->pclientTopShadows)
579         pcd->pclientTopShadows->used = 0;
580     if (pcd->pclientBottomShadows)
581         pcd->pclientBottomShadows->used = 0;
582
583     if (pcd->pclientTitleTopShadows)
584         pcd->pclientTitleTopShadows->used = 0;
585     if (pcd->pclientTitleBottomShadows)
586         pcd->pclientTitleBottomShadows->used = 0;
587
588     if (pcd->pclientMatteTopShadows)
589         pcd->pclientMatteTopShadows->used = 0;
590     if (pcd->pclientMatteBottomShadows)
591         pcd->pclientMatteBottomShadows->used = 0;
592
593     /* adjust inside bevel of gadgetry if there's a matte */
594     if ((wmGD.frameStyle == WmRECESSED) && (matte_width > 0))
595         insideBevel = JOIN_BEVEL(pcd);
596     else
597         insideBevel = pcd->internalBevel;
598
599     diffBevel = insideBevel - 1;
600
601     if (decoration & MWM_DECOR_RESIZEH) 
602     {
603         /* adjust part width/heights if no title bar */
604         if ((pcd->internalBevel > 1) && !(decoration & MWM_DECOR_TITLE))
605         {
606             inset = 1;
607         }
608         else
609         {
610             inset = 0;
611         }
612
613         /*
614          * Draw the stretchers. If the horizontal or vertical pieces
615          * get "too small", then don't draw them at all.
616          */
617         GetFramePartInfo (pcd, FRAME_RESIZE_NW, &x, &y, &width, &height);
618         StretcherCorner (pcd->pclientTopShadows,        /* NW */
619                     pcd->pclientBottomShadows, 
620                     x, y, 
621                     STRETCH_NORTH_WEST, 
622                     pcd->frameInfo.upperBorderWidth - inset, 
623                     width, height);
624
625         GetFramePartInfo (pcd, FRAME_RESIZE_N, &x, &y, &width, &height);
626         if ((int)width > 0)
627             BevelRectangle (pcd->pclientTopShadows,     /* N */
628                     pcd->pclientBottomShadows, 
629                     x, y, 
630                     width, height - inset,
631                     2, 1, ((wmGD.frameStyle == WmSLAB) ? 0 : 1), 1);
632
633         GetFramePartInfo (pcd, FRAME_RESIZE_NE, &x, &y, &width, &height);
634         StretcherCorner (pcd->pclientTopShadows, 
635                     pcd->pclientBottomShadows, 
636                     x, y,
637                     STRETCH_NORTH_EAST, 
638                     pcd->frameInfo.upperBorderWidth - inset, width, height);
639   
640         GetFramePartInfo (pcd, FRAME_RESIZE_E, &x, &y, &width, &height);
641         if ((int)height > 0) 
642             BevelRectangle (pcd->pclientTopShadows,     /* E */
643                     pcd->pclientBottomShadows, 
644                     x+diffBevel, y, 
645                     width-diffBevel, height,
646                     1, 2, 1, ((wmGD.frameStyle == WmSLAB) ? 0 : 1));
647
648         GetFramePartInfo (pcd, FRAME_RESIZE_SE, &x, &y, &width, &height);
649         StretcherCorner (pcd->pclientTopShadows,        /* SE */
650                     pcd->pclientBottomShadows, 
651                     x, y, 
652                     STRETCH_SOUTH_EAST, 
653                     pcd->frameInfo.upperBorderWidth-inset, width, height);
654
655         GetFramePartInfo (pcd, FRAME_RESIZE_S, &x, &y, &width, &height);
656         if ((int) width > 0)
657             BevelRectangle (pcd->pclientTopShadows,     /* S */
658                     pcd->pclientBottomShadows, 
659                     x, y+diffBevel, 
660                     width, height-diffBevel,
661                     ((wmGD.frameStyle == WmSLAB) ? 0 : 1), 1, 2, 1);
662
663         GetFramePartInfo (pcd, FRAME_RESIZE_SW, &x, &y, &width, &height);
664         StretcherCorner (pcd->pclientTopShadows,        /* SW */
665                     pcd->pclientBottomShadows, 
666                     x, y, 
667                     STRETCH_SOUTH_WEST, 
668                     pcd->frameInfo.upperBorderWidth-inset, width, height);
669   
670         GetFramePartInfo (pcd, FRAME_RESIZE_W, &x, &y, &width, &height);
671         if ((int) height > 0)
672             BevelRectangle (pcd->pclientTopShadows,     /* W */
673                     pcd->pclientBottomShadows, 
674                     x, y, 
675                     width-diffBevel, height,
676                     1, ((wmGD.frameStyle == WmSLAB) ? 0 : 1), 1, 2);
677
678         if (diffBevel)
679         {
680             /*
681              * Draw second inside bevel level. This goes just around the 
682              * client area under the title bar.
683              */
684             BevelRectangle (pcd->pclientBottomShadows,  /* inside */
685                             pcd->pclientTopShadows, 
686                             (int) (pcd->frameInfo.lowerBorderWidth-diffBevel), 
687                             (int) (pcd->clientOffset.y - diffBevel),
688                             pcd->frameInfo.width - 
689                                 2*pcd->frameInfo.lowerBorderWidth + 
690                                 2*diffBevel, 
691                             pcd->frameInfo.height - pcd->clientOffset.y - 
692                                 pcd->frameInfo.lowerBorderWidth + 
693                                 2*diffBevel,
694                             (unsigned int) diffBevel, (unsigned int) diffBevel,
695                             (unsigned int) diffBevel, (unsigned int) diffBevel);
696         }
697     }
698     else if (decoration & MWM_DECOR_BORDER)
699     {
700
701     /* produce default border with no resizing functions */
702
703 #ifdef WSM
704         BevelRectangle (pcd->pclientTopShadows,         /* outside */
705                     pcd->pclientBottomShadows, 
706                     0, 0, 
707                     pcd->frameInfo.width, pcd->frameInfo.height,
708                     FRAME_EXTERNAL_SHADOW_WIDTH,
709                     FRAME_EXTERNAL_SHADOW_WIDTH,
710                     FRAME_EXTERNAL_SHADOW_WIDTH,
711                     FRAME_EXTERNAL_SHADOW_WIDTH);
712 #else /* WSM */
713         BevelRectangle (pcd->pclientTopShadows,         /* outside */
714                     pcd->pclientBottomShadows, 
715                     0, 0, 
716                     pcd->frameInfo.width, pcd->frameInfo.height,
717                     2, 2, 2, 2);
718 #endif /* WSM */
719
720         if ((pcd->internalBevel > 1) &&
721             !matte_width && 
722             (decoration & MWM_DECOR_TITLE)) {
723             /*
724              * Need to do special beveling around the inside of the 
725              * client area separately from around title area.
726              */
727             GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height);
728             inset = 1 + (pcd->frameInfo.lowerBorderWidth - 
729                          pcd->frameInfo.upperBorderWidth);
730             BevelRectangle (pcd->pclientBottomShadows,
731                             pcd->pclientTopShadows, 
732                             (int) (pcd->frameInfo.lowerBorderWidth-inset), 
733                             (int) (pcd->frameInfo.lowerBorderWidth-inset), 
734                             pcd->frameInfo.width - 
735                                 2*pcd->frameInfo.lowerBorderWidth + 2*inset, 
736                             pcd->frameInfo.height - 
737                                 2*pcd->frameInfo.lowerBorderWidth + 2*inset,
738                             1, 1, 1, 1);
739
740             BevelRectangle (pcd->pclientBottomShadows,  /* inside */
741                             pcd->pclientTopShadows, 
742                             (int) (pcd->frameInfo.lowerBorderWidth-diffBevel), 
743                             pcd->clientOffset.y - diffBevel,
744                             pcd->frameInfo.width - 
745                                 2*pcd->frameInfo.lowerBorderWidth + 
746                                 2*diffBevel, 
747                             pcd->frameInfo.height - pcd->clientOffset.y - 
748                                 pcd->frameInfo.lowerBorderWidth + 2*diffBevel,
749                             (unsigned int)diffBevel, (unsigned int)diffBevel,
750                             (unsigned int)diffBevel, (unsigned int)diffBevel);
751         }
752         else 
753         {
754 #ifdef PANELIST
755             if((pcd->dtwmBehaviors & DtWM_BEHAVIOR_PANEL) &&
756                (pcd->clientDecoration == WM_DECOR_BORDER))
757             {
758                 insideBevel = 0;
759             }
760 #endif /* PANELIST */
761             BevelRectangle (pcd->pclientBottomShadows,  /* inside */
762                             pcd->pclientTopShadows, 
763                             (int)(pcd->frameInfo.lowerBorderWidth-insideBevel), 
764                             (int)(pcd->frameInfo.lowerBorderWidth-insideBevel), 
765                             pcd->frameInfo.width - 
766                                 2*pcd->frameInfo.lowerBorderWidth + 
767                                 2*insideBevel, 
768                             pcd->frameInfo.height - 
769                                 2*pcd->frameInfo.lowerBorderWidth + 
770                                 2*insideBevel,
771                             (unsigned int)insideBevel, 
772                             (unsigned int)insideBevel,
773                             (unsigned int)insideBevel, 
774                             (unsigned int)insideBevel);
775         }
776     }
777
778
779     /* draw title bar */
780
781     /* 
782      * set bevels for title bar and parts 
783      */
784     if (decoration & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
785     {
786         nTitleBevel = JOIN_BEVEL(pcd);  /* north side of title */
787         if (wmGD.frameStyle == WmSLAB)
788         {
789             sTitleBevel = JOIN_BEVEL(pcd);      /* south side of title */
790         }
791         else
792         {
793             sTitleBevel = insideBevel;  /* south side of title */
794         }
795         eTitleBevel = JOIN_BEVEL(pcd);  /* east side of title */
796         wTitleBevel = JOIN_BEVEL(pcd);  /* west side of title */
797         meTitleBevel = JOIN_BEVEL(pcd); /* btw Minimize, Maximize */
798     }
799     else 
800     {
801         /* borderless window */
802
803         nTitleBevel = EXTERNAL_BEVEL(pcd);
804         if (wmGD.frameStyle == WmSLAB)
805         {
806             sTitleBevel = (matte_width > 0) ? JOIN_BEVEL(pcd) : 
807                                                 EXTERNAL_BEVEL(pcd);
808         }
809         else
810         {
811             sTitleBevel = (matte_width > 0) ? insideBevel : EXTERNAL_BEVEL(pcd);
812         }
813         eTitleBevel = (decoration & (MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE))?
814                           JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
815         wTitleBevel = (decoration & MWM_DECOR_MENU) ?
816                           JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
817
818         /* beveling east of minimize */
819         meTitleBevel = (decoration & (MWM_DECOR_MAXIMIZE)) ?
820                           JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
821     }
822
823
824     if (decoration & MWM_DECOR_TITLE) 
825     {
826         /*
827          * Use a different set of rectangles if title appearance
828          * is different from the rest of the frame.
829          */
830         if (DECOUPLE_TITLE_APPEARANCE(pcd)) 
831         {
832             prlTop = pcd->pclientTitleTopShadows;
833             prlBot = pcd->pclientTitleBottomShadows;
834             xAdj = yAdj = pcd->frameInfo.upperBorderWidth;
835         }
836         else
837         {
838             prlTop = pcd->pclientTopShadows;
839             prlBot = pcd->pclientBottomShadows;
840             xAdj = yAdj = 0;
841         }
842
843
844         GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height);
845         if (pcd->decorFlags & TITLE_DEPRESSED) {
846             /* show depressed title gadget */
847             GetDepressInfo (pcd, FRAME_TITLE, &jX, &jY, &jW, &jH, 
848                             &inWidth);
849             BevelDepressedRectangle (prlTop, prlBot, 
850                         x-xAdj, y-yAdj, width, height,
851                         nTitleBevel, eTitleBevel, 
852                         sTitleBevel, wTitleBevel, inWidth);
853         }
854         else {
855             /* show normal title gadget */
856             BevelRectangle (prlTop, prlBot, 
857                         x-xAdj, y-yAdj, width, height,
858                         nTitleBevel, eTitleBevel, 
859                         sTitleBevel, wTitleBevel);
860         }
861     }
862
863     if (decoration & MWM_DECOR_MENU) {
864
865         GetFramePartInfo (pcd, FRAME_SYSTEM, &x, &y, &width, &height);
866         if (pcd->decorFlags & SYSTEM_DEPRESSED) {
867             /* show depressed system gadget */
868             GetDepressInfo (pcd, FRAME_SYSTEM, &jX, &jY, &jW, &jH, 
869                             &inWidth);
870             BevelDepressedRectangle (prlTop, prlBot, 
871                             x-xAdj, y-yAdj, width, height,
872                             nTitleBevel, wTitleBevel, 
873                             sTitleBevel, nTitleBevel, inWidth);
874         }
875         else
876         {
877             /* show normal system gadget */
878             BevelRectangle (prlTop, prlBot, 
879                             x-xAdj, y-yAdj, width, height,
880                             nTitleBevel, wTitleBevel, 
881                             sTitleBevel, nTitleBevel);
882         }
883
884
885         /* system icon */
886         BevelSystemButton (prlTop, prlBot, 
887                            x-xAdj, y-yAdj, width, height);
888     }
889                     
890     if (decoration & MWM_DECOR_MINIMIZE) { 
891         GetFramePartInfo (pcd, FRAME_MINIMIZE, &x, &y, &width, &height);
892
893         if (pcd->decorFlags & MINIMIZE_DEPRESSED) {
894             /* show depressed minimize gadget */
895             GetDepressInfo (pcd, FRAME_MINIMIZE, &jX, &jY, &jW, &jH, 
896                             &inWidth);
897             BevelDepressedRectangle (prlTop, prlBot, 
898                             x-xAdj, y-yAdj, width, height,
899                             nTitleBevel, meTitleBevel, 
900                             sTitleBevel, eTitleBevel, inWidth);
901         }
902         else {
903             /* show normal minimize gadget */
904             BevelRectangle (prlTop, prlBot, 
905                             x-xAdj, y-yAdj, width, height,
906                             nTitleBevel, meTitleBevel, 
907                             sTitleBevel, eTitleBevel);
908         }
909
910
911         BevelMinimizeButton(prlTop,     /* minimize icon */
912                             prlBot, 
913                             x-xAdj, y-yAdj, height);
914     }
915
916     if (decoration & MWM_DECOR_MAXIMIZE) {
917         GetFramePartInfo (pcd, FRAME_MAXIMIZE, &x, &y, &width, &height);
918
919
920         if (pcd->decorFlags & MAXIMIZE_DEPRESSED) {
921             /* show depressed maximize gadget */
922             GetDepressInfo (pcd, FRAME_MAXIMIZE, &jX, &jY, &jW, &jH, 
923                             &inWidth);
924             BevelDepressedRectangle (prlTop, prlBot, 
925                             x-xAdj, y-yAdj, width, height,
926                             nTitleBevel, nTitleBevel, 
927                             sTitleBevel, eTitleBevel, inWidth);
928         }
929         else {
930             /* show normal maximize gadget */
931             BevelRectangle (prlTop, prlBot, 
932                             x-xAdj, y-yAdj, width, height,
933                             nTitleBevel, nTitleBevel, 
934                             sTitleBevel, eTitleBevel);
935         }
936
937         /* maximize icon - in or out depending on client state */
938         if (pcd->maxConfig) {
939             BevelMaximizeButton(prlBot, 
940                                 prlTop,
941                                 x-xAdj, y-yAdj, height);
942         }
943         else {
944             BevelMaximizeButton(prlTop,
945                                 prlBot, 
946                                 x-xAdj, y-yAdj, height);
947         }
948         
949     }
950
951     /* draw the client matte (this is in the base window!!!) */
952
953     if (matte_width > 0) {
954         unsigned int mWidth, mHeight, exMatteBevel, tMatteBevel;
955
956         mWidth = BaseWindowWidth (pcd);
957         mHeight = BaseWindowHeight (pcd);
958
959         if (decoration & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
960         {
961             exMatteBevel = JOIN_BEVEL(pcd);
962             tMatteBevel = JOIN_BEVEL(pcd);
963         }
964         else 
965         {
966             exMatteBevel = EXTERNAL_BEVEL(pcd);
967             tMatteBevel = (decoration & MWM_DECOR_TITLE) ?
968                            JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
969         }
970
971         /* set up beveling around the edges */
972
973         BevelRectangle (pcd->pclientMatteTopShadows,
974                     pcd->pclientMatteBottomShadows,
975                     0, 
976                     0,
977                     mWidth,
978                     mHeight,
979                     tMatteBevel, exMatteBevel, 
980                     exMatteBevel, exMatteBevel);
981
982         /* reversed beveling on inside rectange ! */
983
984         BevelRectangle ( pcd->pclientMatteBottomShadows,
985                     pcd->pclientMatteTopShadows,
986                     matte_width - pcd->internalBevel, 
987                     matte_width - pcd->internalBevel,
988                     mWidth - 2*matte_width + 2*pcd->internalBevel, 
989                     mHeight - 2*matte_width + 2*pcd->internalBevel,
990                     (unsigned int) pcd->internalBevel, 
991                     (unsigned int) pcd->internalBevel, 
992                     (unsigned int) pcd->internalBevel, 
993                     (unsigned int) pcd->internalBevel);
994     }
995 }
996
997 \f
998 /*************************************<->*************************************
999  *
1000  *  AdoptClient (pcd)
1001  *
1002  *
1003  *  Description:
1004  *  -----------
1005  *  Reparent the client window to the window frame
1006  *
1007  *
1008  *  Inputs:
1009  *  ------
1010  *  pcd         - pointer to client data record
1011  *
1012  * 
1013  *  Outputs:
1014  *  -------
1015  *  None
1016  *
1017  *
1018  *  Comments:
1019  *  --------
1020  * 
1021  *************************************<->***********************************/
1022
1023 void AdoptClient (ClientData *pcd)
1024 {
1025     XWindowChanges windowChanges;
1026     unsigned int mask;
1027
1028     /* Put the window in the window manager's save set */
1029
1030     if (!(pcd->clientFlags & CLIENT_WM_CLIENTS))
1031     {
1032         XChangeSaveSet (DISPLAY, pcd->client, SetModeInsert);
1033         pcd->clientFlags |= CLIENT_IN_SAVE_SET;
1034     }
1035
1036     /*
1037      * set window geometry to be consistent with what we believe 
1038      */
1039     mask = CWWidth | CWHeight;
1040     windowChanges.width = pcd->clientWidth;
1041     windowChanges.height = pcd->clientHeight;
1042
1043     /*
1044      * strip off previous window border if we're adding our own border
1045      * or matte
1046      */
1047     if ( (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)) ||
1048          (pcd->matteWidth > 0) )
1049     {
1050         mask |= CWBorderWidth;
1051         windowChanges.border_width = 0;
1052     }
1053
1054     XConfigureWindow (DISPLAY, pcd->client, mask, &windowChanges);
1055
1056 #ifndef NO_SHAPE
1057     /* shape our frame to match that of the client's window */
1058     if (wmGD.hasShape)
1059     {
1060         int xws, yws, xbs, ybs;
1061         unsigned wws, hws, wbs, hbs;
1062         int boundingShaped, clipShaped;
1063         
1064         XShapeSelectInput (DISPLAY, pcd->client, ShapeNotifyMask);
1065         XShapeQueryExtents (DISPLAY, pcd->client,
1066                             &boundingShaped, &xws, &yws, &wws, &hws,
1067                             &clipShaped, &xbs, &ybs, &wbs, &hbs);
1068         pcd->wShaped = boundingShaped;
1069     }
1070 #endif /* NO_SHAPE  */
1071     /* reparent the window to the base window */
1072
1073     XReparentWindow (DISPLAY, pcd->client, pcd->clientBaseWin, 
1074                         pcd->matteWidth, 
1075                         pcd->matteWidth);
1076     pcd->clientFlags |= CLIENT_REPARENTED;
1077
1078 } /* END OF FUNCTION AdoptClient */
1079
1080
1081 \f
1082 /*************************************<->*************************************
1083  *
1084  *  GetTextBox (pcd, pBox)
1085  *
1086  *
1087  *  Description:
1088  *  -----------
1089  *  Gets the rectangle that the text should fit into in the title bar
1090  *
1091  *
1092  *  Inputs:
1093  *  ------
1094  *  pcd         - pointer to client data
1095  *  pBox        - pointer to an XRectangle structure that gets return data
1096  * 
1097  *  Outputs:
1098  *  -------
1099  *  pBox        - data is returned here
1100  *
1101  *  Comments:
1102  *  --------
1103  * 
1104  *************************************<->***********************************/
1105
1106 void GetTextBox (ClientData *pcd, XRectangle *pBox)
1107 {
1108     int x,y;
1109     unsigned int width,height;
1110 #ifdef WSM
1111     Dimension textWidth;
1112     Dimension offset;
1113     XmFontList  fontList;
1114 #endif /* WSM */
1115
1116     /* get size of title area */
1117
1118     if (!GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height))
1119     {
1120         /* no title area !!! */
1121         pBox->x = 0;
1122         pBox->y = 0;
1123         pBox->width = 0;
1124         pBox->height = 0;
1125         return;
1126     }
1127
1128     /* adjust for shadowing and allow for some padding around the edges */
1129     x += WM_TOP_TITLE_SHADOW + WM_TOP_TITLE_PADDING;
1130     y += WM_TOP_TITLE_SHADOW + WM_TOP_TITLE_PADDING;
1131
1132     width -= WM_TOP_TITLE_SHADOW + WM_BOTTOM_TITLE_SHADOW +
1133              WM_TOP_TITLE_PADDING + WM_BOTTOM_TITLE_PADDING;
1134     height -= WM_TOP_TITLE_SHADOW + WM_BOTTOM_TITLE_SHADOW +
1135               WM_TOP_TITLE_PADDING + WM_BOTTOM_TITLE_PADDING;
1136
1137 #ifdef DT_LEFT_JUSTIFIED_TITLE
1138     if (wmGD.frameStyle == WmSLAB)
1139     {
1140         /*
1141          * We left justify the title in this style.
1142          * To keep it a little neat, we offset the title from 
1143          * the left edge just a little (half the title height).
1144          * See if we have room to do this.
1145          */
1146         if (DECOUPLE_TITLE_APPEARANCE(pcd))
1147             fontList = CLIENT_TITLE_APPEARANCE(pcd).fontList;
1148         else
1149             fontList = CLIENT_APPEARANCE(pcd).fontList;
1150         textWidth = XmStringWidth(fontList, pcd->clientTitle);
1151
1152         offset = TitleBarHeight(pcd)/2;
1153
1154         if ((textWidth + offset) <= width)
1155         {
1156             /* We have plenty of room, do the offset */
1157             x += offset;
1158             width -= offset;
1159         }
1160         else if ((short) (width - textWidth) > 0)
1161         {
1162             /* We don't have enough room to do our usual offset,
1163              * but if we reduce the offset, the text won't get
1164              * clipped.
1165              */
1166             offset = (width - textWidth) / 2;
1167             x += offset;
1168             width -= offset;
1169         }
1170     }
1171
1172 #endif /* DT_LEFT_JUSTIFIED_TITLE */
1173     /* return position and size */
1174     pBox->x = x;
1175     pBox->y = y;
1176     pBox->width = width;
1177     pBox->height = height;
1178
1179 }
1180
1181
1182
1183 \f
1184 /*************************************<->*************************************
1185  *
1186  *  DrawWindowTitle (pcd, eraseFirst)
1187  *
1188  *
1189  *  Description:
1190  *  -----------
1191  *  Overwrites or replaces the client's title text in the 
1192  *  title bar of the frame.
1193  *
1194  *
1195  *  Inputs:
1196  *  ------
1197  *  pcd         - pointer to client data
1198  *  eraseFirst  - if true, then the old title is erased first
1199  * 
1200  *  Outputs:
1201  *  -------
1202  *  none
1203  *
1204  *  Comments:
1205  *  --------
1206  *  o Assumes 8-bit text for now.
1207  *  
1208  * 
1209  *************************************<->***********************************/
1210
1211 void DrawWindowTitle (ClientData *pcd, Boolean eraseFirst)
1212 {
1213     GC clientGC;
1214     unsigned long decoration = pcd->decor;
1215     XRectangle textBox;
1216     Window win;
1217     XmFontList  fontList;
1218
1219     /* make sure there is a title bar first */
1220     if (!(decoration & MWM_DECOR_TITLE))
1221         return;
1222
1223     if (DECOUPLE_TITLE_APPEARANCE(pcd))
1224     {
1225         /* use "active" GC if we have keyboard focus */
1226         if (pcd == wmGD.keyboardFocus) {
1227             clientGC = CLIENT_TITLE_APPEARANCE(pcd).activeGC;
1228         }
1229         else {
1230             clientGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveGC;
1231         }
1232
1233         /* get the area that the text must fit in */
1234         GetTextBox (pcd, &textBox);
1235
1236         /* adjust position to be relative to titlebar window, not frame */
1237         textBox.x -= (short) pcd->frameInfo.upperBorderWidth;
1238         textBox.y -= (short) pcd->frameInfo.upperBorderWidth;
1239
1240         win = pcd->clientTitleWin;
1241         fontList = CLIENT_TITLE_APPEARANCE(pcd).fontList;
1242     }
1243     else 
1244     {
1245         /* use "active" GC if we have keyboard focus */
1246         if (pcd == wmGD.keyboardFocus) {
1247             clientGC = CLIENT_APPEARANCE(pcd).activeGC;
1248         }
1249         else {
1250             clientGC = CLIENT_APPEARANCE(pcd).inactiveGC;
1251         }
1252
1253         /* get the area that the text must fit in */
1254         GetTextBox (pcd, &textBox);
1255         win = pcd->clientFrameWin;
1256         fontList = CLIENT_APPEARANCE(pcd).fontList;
1257     }
1258
1259     if (eraseFirst)
1260     {
1261         XClearArea (DISPLAY, win, textBox.x, textBox.y, 
1262                 (unsigned int) textBox.width, (unsigned int) textBox.height, 
1263                 FALSE);
1264     }
1265
1266 #ifdef  DT_LEFT_JUSTIFIED_TITLE
1267     WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1268                    textBox.x, textBox.y, textBox.width, &textBox,
1269                    ((wmGD.frameStyle == WmSLAB) ? False : True));
1270 #else /* DT_LEFT_JUSTIFIED_TITLE */
1271 #ifdef WSM
1272     WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1273                    textBox.x, textBox.y, textBox.width, &textBox,
1274                    True);
1275 #else
1276     WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1277                    textBox.x, textBox.y, textBox.width, &textBox);
1278 #endif
1279 #endif /* DT_LEFT_JUSTIFIED_TITLE */
1280                      
1281
1282
1283 } /* END OF FUNCTION DrawWindowTitle */
1284
1285
1286 \f
1287 /*************************************<->*************************************
1288  *
1289  *  CreateStretcherWindows (pcd)
1290  *
1291  *
1292  *  Description:
1293  *  -----------
1294  *  Create the input-only windows that overlay the resize gadgets.
1295  *
1296  *
1297  *  Inputs:
1298  *  ------
1299  *  pcd         - pointer to client data.
1300  *
1301  * 
1302  *  Outputs:
1303  *  -------
1304  *  pcd         - modified
1305  *
1306  *  Return      - none
1307  *
1308  *
1309  *  Comments:
1310  *  --------
1311  *  o The windows are sized based upon resizeBorderWidth
1312  *  o This should be called before creating the title bar, 
1313  *    and reparenting window. Later windows should obscure parts of the 
1314  *    stretchers.
1315  *  o The stretchers are given special cursors.
1316  * 
1317  *************************************<->***********************************/
1318
1319 void CreateStretcherWindows (ClientData *pcd)
1320 {
1321     int iWin;
1322     int x, y;
1323     unsigned int width, height;
1324     XSetWindowAttributes win_attribs;
1325     unsigned long attr_mask;
1326
1327     for (iWin = 0; iWin < STRETCH_COUNT; iWin++) {
1328         switch (iWin) {
1329             case STRETCH_NORTH_WEST:
1330                     GetFramePartInfo (pcd, FRAME_RESIZE_NW, 
1331                                       &x, &y, &width, &height);
1332                     break;
1333
1334             case STRETCH_NORTH:
1335                     GetFramePartInfo (pcd, FRAME_RESIZE_N, 
1336                                       &x, &y, &width, &height);
1337                     break;
1338
1339             case STRETCH_NORTH_EAST:
1340                     GetFramePartInfo (pcd, FRAME_RESIZE_NE, 
1341                                       &x, &y, &width, &height);
1342                     break;
1343
1344             case STRETCH_EAST:
1345                     GetFramePartInfo (pcd, FRAME_RESIZE_E, 
1346                                       &x, &y, &width, &height);
1347                     break;
1348
1349             case STRETCH_SOUTH_EAST:
1350                     GetFramePartInfo (pcd, FRAME_RESIZE_SE, 
1351                                       &x, &y, &width, &height);
1352                     break;
1353
1354             case STRETCH_SOUTH:
1355                     GetFramePartInfo (pcd, FRAME_RESIZE_S, 
1356                                       &x, &y, &width, &height);
1357                     break;
1358
1359             case STRETCH_SOUTH_WEST:
1360                     GetFramePartInfo (pcd, FRAME_RESIZE_SW, 
1361                                       &x, &y, &width, &height);
1362                     break;
1363
1364             case STRETCH_WEST:
1365                     GetFramePartInfo (pcd, FRAME_RESIZE_W, 
1366                                       &x, &y, &width, &height);
1367                     break;
1368         }
1369
1370         attr_mask = CWCursor;
1371         win_attribs.cursor = wmGD.stretchCursors[iWin];
1372
1373         pcd->clientStretchWin[iWin] = 
1374                     XCreateWindow(DISPLAY, pcd->clientFrameWin,
1375                     x, y, width, height, 0, CopyFromParent,
1376                     InputOnly, CopyFromParent, attr_mask, &win_attribs);
1377     }
1378 } /* END OF FUNCTION  CreateStretcherWindows  */
1379
1380
1381 \f
1382 /*************************************<->*************************************
1383  *
1384  *  CountFrameRectangles (pSD)
1385  *
1386  *
1387  *  Description:
1388  *  -----------
1389  *  Computes the number of top and bottom shadow rectangles to allocate
1390  *  per frame.
1391  *
1392  *  Inputs:
1393  *  ------
1394  *  pWS         - pointer to workspace data
1395  * 
1396  *  Outputs:
1397  *  -------
1398  *
1399  *  Comments:
1400  *  --------
1401  *  
1402  * 
1403  *************************************<->***********************************/
1404
1405 void CountFrameRectangles (WmScreenData *pSD)
1406 {
1407     int i;
1408
1409     pSD->Num_Title_Ts_Elements = pSD->Num_Title_Bs_Elements = 0;
1410
1411     /* count up rectangles for title bar */
1412     for (i = FRAME_SYSTEM; i <= FRAME_MAXIMIZE; i++)
1413     {
1414         pSD->Num_Title_Ts_Elements += ((Bevels[i].top.external * 
1415                                  pSD->externalBevel) +
1416                           (Bevels[i].top.internal * MAX_INTERNAL_BEVEL) +
1417                           (Bevels[i].top.join * pSD->joinBevel));
1418
1419         pSD->Num_Title_Bs_Elements += ((Bevels[i].bottom.external*
1420                                  pSD->externalBevel)+
1421                           (Bevels[i].bottom.internal * MAX_INTERNAL_BEVEL) +
1422                           (Bevels[i].bottom.join * pSD->joinBevel));
1423     }
1424
1425     pSD->Num_Resize_Ts_Elements = pSD->Num_Resize_Bs_Elements = 0;
1426
1427     /* count up rectangles for resize handles*/
1428     for (i = FRAME_RESIZE_NW; i <= FRAME_RESIZE_W; i++)
1429     {
1430         pSD->Num_Resize_Ts_Elements += ((Bevels[i].top.external * 
1431                                    pSD->externalBevel) +
1432                           (Bevels[i].top.internal * MAX_INTERNAL_BEVEL) +
1433                           (Bevels[i].top.join * pSD->joinBevel));
1434
1435         pSD->Num_Resize_Bs_Elements += ((Bevels[i].bottom.external*
1436                                    pSD->externalBevel)+
1437                           (Bevels[i].bottom.internal * MAX_INTERNAL_BEVEL) +
1438                           (Bevels[i].bottom.join * pSD->joinBevel));
1439     }
1440 } /* END OF FUNCTION  CountFrameRectangles  */
1441
1442
1443 \f
1444 /*************************************<->*************************************
1445  *
1446  *  AllocateFrameDisplayLists (pcd)
1447  *
1448  *
1449  *  Description:
1450  *  -----------
1451  *  Allocates memory for the graphic display lists for the frame.
1452  *
1453  *
1454  *  Inputs:
1455  *  ------
1456  *  pcd         - pointer to the client data
1457  *
1458  * 
1459  *  Outputs:
1460  *  -------
1461  *  pcd         - fields modified
1462  *
1463  *  Return      - TRUE if successful, FALSE otherwise.
1464  *
1465  *
1466  *  Comments:
1467  *  --------
1468  *  
1469  * 
1470  *************************************<->***********************************/
1471
1472 Boolean AllocateFrameDisplayLists (ClientData *pcd)
1473 {
1474     int frame_top_count, frame_bottom_count;
1475
1476     /*
1477      *  If the title bar has it's own appearance, then allocate
1478      *  separate display lists for it. 
1479      */
1480     if (DECOUPLE_TITLE_APPEARANCE(pcd) && 
1481         (pcd->decor & MWM_DECOR_TITLE))
1482     {
1483         if (((pcd->pclientTitleTopShadows = 
1484               AllocateRList ((unsigned)NUM_TITLE_TS_ELEMENTS(pcd))) == NULL) ||
1485             ((pcd->pclientTitleBottomShadows = 
1486               AllocateRList ((unsigned)NUM_TITLE_BS_ELEMENTS(pcd))) == NULL))
1487         {
1488             /* out of memory! */
1489             Warning (((char *)GETMESSAGE(8, 1, "Insufficient memory for client window framing")));
1490             return(FALSE);
1491         }
1492
1493         frame_top_count = NUM_RESIZE_TS_ELEMENTS(pcd);
1494         frame_bottom_count = NUM_RESIZE_BS_ELEMENTS(pcd);
1495     }
1496     else
1497     {
1498         frame_top_count = NUM_RESIZE_TS_ELEMENTS(pcd) + 
1499                           NUM_TITLE_TS_ELEMENTS(pcd);
1500         frame_bottom_count = NUM_RESIZE_BS_ELEMENTS(pcd) + 
1501                              NUM_RESIZE_BS_ELEMENTS(pcd);
1502     }
1503
1504     /* 
1505      * Allocate the primary lists for the frame
1506      */
1507     if ( (pcd->pclientTopShadows == NULL) &&
1508          ((pcd->pclientTopShadows = 
1509                  AllocateRList ((unsigned)frame_top_count)) == NULL) )
1510     {
1511         /* out of memory! */
1512         Warning (((char *)GETMESSAGE(8, 2, "Insufficient memory for client window framing")));
1513         return(FALSE);
1514     }
1515
1516     if ( (pcd->pclientBottomShadows == NULL) &&
1517          ((pcd->pclientBottomShadows = 
1518                  AllocateRList ((unsigned)frame_bottom_count)) == NULL) )
1519     {
1520         /* out of memory! */
1521         Warning (((char *)GETMESSAGE(8, 3, "Insufficient memory for client window framing")));
1522         return(FALSE);
1523     }
1524
1525     /*
1526      * Only allocate matte lists if there is a matte.
1527      */
1528     if ( (pcd->matteWidth) &&
1529          (pcd->pclientMatteTopShadows == NULL) &&
1530          ((pcd->pclientMatteTopShadows = 
1531              AllocateRList ((unsigned)NUM_MATTE_TS_RECTS)) == NULL))
1532     {
1533         /* out of memory! */
1534         Warning (((char *)GETMESSAGE(8, 4, "Insufficient memory for client window framing")));
1535         return(FALSE);
1536     }
1537
1538     if ( (pcd->matteWidth) &&
1539          (pcd->pclientMatteBottomShadows == NULL) &&
1540          ((pcd->pclientMatteBottomShadows = 
1541                  AllocateRList ((unsigned)NUM_MATTE_BS_RECTS)) == NULL)) 
1542     {
1543         /* out of memory! */
1544         Warning (((char *)GETMESSAGE(8, 5, "Insufficient memory for client window framing")));
1545         return(FALSE);
1546     }
1547
1548     return(TRUE);
1549 } /* END OF FUNCTION  AllocateFrameDisplayLists  */
1550
1551 \f
1552 /*************************************<->*************************************
1553  *
1554  *  InitClientDecoration (pSD)
1555  *
1556  *
1557  *  Description:
1558  *  -----------
1559  *  Initializes client decoration routines
1560  *
1561  *
1562  *  Inputs:
1563  *  ------
1564  *  pSD         - pointer to screen data
1565  * 
1566  *  Outputs:
1567  *  -------
1568  *
1569  *
1570  *  Comments:
1571  *  --------
1572  *  This must be called once before decorating any client frames.
1573  *************************************<->***********************************/
1574
1575 void InitClientDecoration (WmScreenData *pSD)
1576 {
1577     CountFrameRectangles(pSD);
1578 } /* END OF FUNCTION   InitClientDecoration */
1579
1580
1581 \f
1582 /*************************************<->*************************************
1583  *
1584  *  AllocateGadgetRectangles (pcd)
1585  *
1586  *
1587  *  Description:
1588  *  -----------
1589  *  Allocate the memory for event rectangles structures.
1590  *
1591  *
1592  *  Inputs:
1593  *  ------
1594  *  pcd         - pointer to client data structure
1595  * 
1596  *  Outputs:
1597  *  -------
1598  *  pcd         - modified
1599  *
1600  *
1601  *  Comments:
1602  *  --------
1603  * 
1604  *************************************<->***********************************/
1605
1606 Boolean AllocateGadgetRectangles (ClientData *pcd)
1607 {
1608     int num_rects;
1609     unsigned long decor = pcd->decor;
1610     GadgetRectangle *pgr;
1611     
1612     if (decor & MWM_DECOR_TITLE) {
1613
1614         /* count how many rectangles to allocate for titlebar */
1615         num_rects = 1;          
1616         if (decor & MWM_DECOR_MENU)     num_rects += 1;
1617         if (decor & MWM_DECOR_MINIMIZE) num_rects += 1;
1618         if (decor & MWM_DECOR_MAXIMIZE) num_rects += 1;
1619     
1620         /* allocate memory if no memory is allocated */
1621         if ( pcd->pTitleGadgets == NULL) {
1622             /* allocate memory for these guys */
1623             pgr = (GadgetRectangle *) 
1624                    XtMalloc (num_rects * sizeof(GadgetRectangle));
1625             if (pgr == NULL)
1626             {
1627                 /* out of memory! */
1628                 Warning (((char *)GETMESSAGE(8, 6, "Insufficient memory for client window framing")));
1629                 return (FALSE);
1630             }
1631
1632             /* update client data */
1633             pcd->pTitleGadgets = pgr;
1634             pcd->cTitleGadgets = 0;
1635         }
1636     }
1637
1638     if (decor & MWM_DECOR_RESIZEH) {
1639
1640         /* allocate memory if no memory is allocated */
1641         if ( pcd->pResizeGadgets == NULL) {
1642             /* allocate memory for these guys */
1643             pgr = (GadgetRectangle *) 
1644                   XtMalloc (STRETCH_COUNT * sizeof(GadgetRectangle));
1645             if (pgr == NULL) 
1646             {
1647                 /* out of memory! */
1648                 Warning (((char *)GETMESSAGE(8, 7, "Insufficient memory for client window framing")));
1649                 return (FALSE);
1650             }
1651
1652             /* update client data */
1653             pcd->pResizeGadgets = pgr;
1654         }
1655     }
1656     return(TRUE);
1657 } /* END OF FUNCTION  AllocateGadgetRectangles  */
1658
1659 \f
1660 /*************************************<->*************************************
1661  *
1662  *  ComputeGadgetRectangles (pcd)
1663  *
1664  *
1665  *  Description:
1666  *  -----------
1667  *  Creates the event rectangles structures to aid in identifying
1668  *  frame parts when events come in
1669  *
1670  *
1671  *  Inputs:
1672  *  ------
1673  *  pcd         - pointer to client data structure
1674  * 
1675  *  Outputs:
1676  *  -------
1677  *  pcd         - modified
1678  *
1679  *
1680  *  Comments:
1681  *  --------
1682  *  o assumes gadget rectangles are already allocated.
1683  * 
1684  *************************************<->***********************************/
1685
1686 void ComputeGadgetRectangles (ClientData *pcd)
1687 {
1688     unsigned long decor = pcd->decor;
1689     GadgetRectangle *pgr;
1690     int fpX, fpY;
1691     unsigned int fpWidth, fpHeight;
1692     int igr;
1693     int clientWidth = (pcd->maxConfig) ? pcd->maxWidth : pcd->clientWidth;
1694     
1695
1696     /* title bar */
1697
1698     if (decor & MWM_DECOR_TITLE) {
1699
1700         if ( (pgr = pcd->pTitleGadgets) == NULL) {
1701             return;             /* nothing there !!! */
1702         }
1703
1704         /* do title rectangle */
1705         pcd->titleRectangle.x = pcd->frameInfo.upperBorderWidth;
1706         pcd->titleRectangle.y = pcd->frameInfo.upperBorderWidth;
1707
1708         /*
1709          * Fixed bug where last button in title bar did not activate when
1710          * the client's X border was showing.
1711          */
1712         pcd->titleRectangle.width = clientWidth +
1713           (XBorderIsShowing(pcd) ? 2*pcd->xBorderWidth : 2*pcd->matteWidth);
1714         pcd->titleRectangle.height = pcd->frameInfo.titleBarHeight;
1715
1716         /* fill in title bar rectangles */
1717         igr = 0;
1718
1719         pgr[igr].id = FRAME_TITLE;
1720         GetFramePartInfo (pcd, FRAME_TITLE, &fpX, &fpY, &fpWidth, &fpHeight);
1721
1722         /* copy in and convert to shorts */
1723         pgr[igr].rect.x = fpX;
1724         pgr[igr].rect.y = fpY;
1725         pgr[igr].rect.width = fpWidth;
1726         pgr[igr].rect.height = fpHeight;
1727         igr += 1;
1728
1729         if (decor & MWM_DECOR_MENU) {
1730             pgr[igr].id = FRAME_SYSTEM;
1731             GetFramePartInfo (pcd, FRAME_SYSTEM, &fpX, &fpY, &fpWidth, 
1732                               &fpHeight);
1733
1734             /* copy in and convert to shorts */
1735             pgr[igr].rect.x = fpX;
1736             pgr[igr].rect.y = fpY;
1737             pgr[igr].rect.width = fpWidth;
1738             pgr[igr].rect.height = fpHeight;
1739             igr += 1;
1740         }
1741
1742         if (decor & MWM_DECOR_MINIMIZE) {
1743             pgr[igr].id = FRAME_MINIMIZE;
1744             GetFramePartInfo (pcd, FRAME_MINIMIZE, 
1745                               &fpX, &fpY, &fpWidth, &fpHeight);
1746             /* copy in and convert to shorts */
1747             pgr[igr].rect.x = fpX;
1748             pgr[igr].rect.y = fpY;
1749             pgr[igr].rect.width = fpWidth;
1750             pgr[igr].rect.height = fpHeight;
1751             igr += 1;
1752         }
1753
1754         if (decor & MWM_DECOR_MAXIMIZE) {
1755             pgr[igr].id = FRAME_MAXIMIZE;
1756             GetFramePartInfo (pcd, FRAME_MAXIMIZE, 
1757                               &fpX, &fpY, &fpWidth, &fpHeight);
1758             /* copy in and convert to shorts */
1759             pgr[igr].rect.x = fpX;
1760             pgr[igr].rect.y = fpY;
1761             pgr[igr].rect.width = fpWidth;
1762             pgr[igr].rect.height = fpHeight;
1763             igr += 1;
1764         }
1765
1766         /* update client data */
1767         pcd->pTitleGadgets = pgr;
1768         pcd->cTitleGadgets = igr;
1769     }
1770
1771     /* client matte area (actually base window area) */
1772
1773     if (decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
1774     {
1775         pcd->matteRectangle.x = pcd->frameInfo.lowerBorderWidth;
1776         pcd->matteRectangle.y = pcd->frameInfo.upperBorderWidth + 
1777                                     pcd->frameInfo.titleBarHeight;
1778         pcd->matteRectangle.width = pcd->frameInfo.width - 
1779                                         (2 * pcd->frameInfo.lowerBorderWidth);
1780         pcd->matteRectangle.height = pcd->frameInfo.height - 
1781                                          pcd->frameInfo.upperBorderWidth - 
1782                                          pcd->frameInfo.lowerBorderWidth - 
1783                                          pcd->frameInfo.titleBarHeight;
1784     }
1785     else 
1786     {
1787         pcd->matteRectangle.x = 0;
1788         pcd->matteRectangle.y = pcd->frameInfo.titleBarHeight;
1789         pcd->matteRectangle.width = pcd->frameInfo.width;
1790         pcd->matteRectangle.height = pcd->frameInfo.height - 
1791                                          pcd->frameInfo.titleBarHeight;
1792     }
1793
1794     if (decor & MWM_DECOR_RESIZEH) {
1795
1796         if ( (pgr = pcd->pResizeGadgets) == NULL) {
1797             return;             /* nothing there !!! */
1798         }
1799
1800         /* fill in resize rectangles */
1801         igr = 0;
1802         if (decor & MWM_DECOR_RESIZEH) { 
1803
1804             pgr[igr].id = FRAME_RESIZE_NW;
1805             GetFramePartInfo (pcd, FRAME_RESIZE_NW, 
1806                               &fpX, &fpY, &fpWidth, &fpHeight);
1807             /* copy in and convert to shorts */
1808             pgr[igr].rect.x = fpX;
1809             pgr[igr].rect.y = fpY;
1810             pgr[igr].rect.width = fpWidth;
1811             pgr[igr].rect.height = fpHeight;
1812             igr += 1;
1813
1814             pgr[igr].id = FRAME_RESIZE_N;
1815             GetFramePartInfo (pcd, FRAME_RESIZE_N, 
1816                               &fpX, &fpY, &fpWidth, &fpHeight);
1817             if ((int) fpWidth > 0)  {
1818                 /* copy in and convert to shorts */
1819                 pgr[igr].rect.x = fpX;
1820                 pgr[igr].rect.y = fpY;
1821                 pgr[igr].rect.width = fpWidth;
1822                 pgr[igr].rect.height = fpHeight;
1823                 igr += 1;
1824             }
1825
1826             pgr[igr].id = FRAME_RESIZE_NE;
1827             GetFramePartInfo (pcd, FRAME_RESIZE_NE, 
1828                               &fpX, &fpY, &fpWidth, &fpHeight);
1829             /* copy in and convert to shorts */
1830             pgr[igr].rect.x = fpX;
1831             pgr[igr].rect.y = fpY;
1832             pgr[igr].rect.width = fpWidth;
1833             pgr[igr].rect.height = fpHeight;
1834             igr += 1;
1835
1836             pgr[igr].id = FRAME_RESIZE_W;
1837             GetFramePartInfo (pcd, FRAME_RESIZE_W, 
1838                               &fpX, &fpY, &fpWidth, &fpHeight);
1839             if ((int)fpHeight > 0) {
1840                 /* copy in and convert to shorts */
1841                 pgr[igr].rect.x = fpX;
1842                 pgr[igr].rect.y = fpY;
1843                 pgr[igr].rect.width = fpWidth;
1844                 pgr[igr].rect.height = fpHeight;
1845                 igr += 1;
1846             }
1847
1848             pgr[igr].id = FRAME_RESIZE_E;
1849             GetFramePartInfo (pcd, FRAME_RESIZE_E, 
1850                               &fpX, &fpY, &fpWidth, &fpHeight);
1851             if ((int) fpHeight > 0) {
1852                 /* copy in and convert to shorts */
1853                 pgr[igr].rect.x = fpX;
1854                 pgr[igr].rect.y = fpY;
1855                 pgr[igr].rect.width = fpWidth;
1856                 pgr[igr].rect.height = fpHeight;
1857                 igr += 1;
1858             }
1859
1860             pgr[igr].id = FRAME_RESIZE_SW;
1861             GetFramePartInfo (pcd, FRAME_RESIZE_SW, 
1862                               &fpX, &fpY, &fpWidth, &fpHeight);
1863             /* copy in and convert to shorts */
1864             pgr[igr].rect.x = fpX;
1865             pgr[igr].rect.y = fpY;
1866             pgr[igr].rect.width = fpWidth;
1867             pgr[igr].rect.height = fpHeight;
1868             igr += 1;
1869
1870             pgr[igr].id = FRAME_RESIZE_S;
1871             GetFramePartInfo (pcd, FRAME_RESIZE_S, 
1872                               &fpX, &fpY, &fpWidth, &fpHeight);
1873             if ((int) fpWidth > 0) {
1874                 /* copy in and convert to shorts */
1875                 pgr[igr].rect.x = fpX;
1876                 pgr[igr].rect.y = fpY;
1877                 pgr[igr].rect.width = fpWidth;
1878                 pgr[igr].rect.height = fpHeight;
1879                 igr += 1;
1880             }
1881
1882             pgr[igr].id = FRAME_RESIZE_SE;
1883             GetFramePartInfo (pcd, FRAME_RESIZE_SE, 
1884                               &fpX, &fpY, &fpWidth, &fpHeight);
1885             /* copy in and convert to shorts */
1886             pgr[igr].rect.x = fpX;
1887             pgr[igr].rect.y = fpY;
1888             pgr[igr].rect.width = fpWidth;
1889             pgr[igr].rect.height = fpHeight;
1890         }
1891
1892         /* update client data */
1893         pcd->pResizeGadgets = pgr;
1894     }
1895
1896 } /* END OF FUNCTION  ComputeGadgetRectangles   */
1897
1898
1899 \f
1900 /*************************************<->*************************************
1901  *
1902  *  GetSystemMenuPosition (pcd, px, py, height, context)
1903  *
1904  *
1905  *  Description:
1906  *  -----------
1907  *  Returns the position of where the system menu should be popped up.
1908  *  The hotspotRectangle in global is also set up to match the icon or
1909  *  system menu button area.
1910  *
1911  *
1912  *  Inputs:
1913  *  ------
1914  *  pcd = pointer to client data
1915  *
1916  *  px = pointer to x location
1917  *
1918  *  py = pointer to y location
1919  *
1920  *  height = height of the system menu
1921  *
1922  *  context =  context that the menu is to be posted under.
1923  *
1924  *
1925  *  Outputs:
1926  *  -------
1927  *  *px = x location
1928  *
1929  *  *py = y location
1930  *
1931  *  wmGD.hotspotRectangle = system menu button or icon area (root relative)
1932  *
1933  *************************************<->***********************************/
1934
1935 void GetSystemMenuPosition (ClientData *pcd, int *px, int *py, 
1936                             unsigned int height, Context context)
1937 {
1938
1939     if ((pcd->clientState == MINIMIZED_STATE) ||
1940         ((pcd->clientState != MINIMIZED_STATE) &&
1941          (context == F_SUBCONTEXT_IB_WICON)))
1942     {
1943         /* 
1944          * Try to put the menu directly above the icon.
1945          * If it would hit the top of the screen then try to put it below
1946          *   the icon and label.
1947          * If it would then hit the bottom of the screen turn of the hotspot
1948          *   processing.
1949          */
1950
1951
1952         if (pcd->pSD->useIconBox && P_ICON_BOX(pcd))
1953         {
1954             GetIconBoxIconRootXY (pcd, px, py);
1955
1956             wmGD.hotspotRectangle.x = *px;
1957             wmGD.hotspotRectangle.y = *py;
1958
1959             *py -= height;
1960
1961             if (*py < 0)
1962             {
1963                 *py += height + ICON_HEIGHT(pcd);
1964                 if (*py + height >= DisplayHeight (DISPLAY, 
1965                                                    SCREEN_FOR_CLIENT(pcd)))
1966                 {
1967                     wmGD.checkHotspot = FALSE;
1968                 }
1969             }
1970         }
1971         else
1972         {
1973             *px = ICON_X(pcd);
1974             *py = ICON_Y(pcd) - height;
1975             
1976             if (*py < 0)
1977             {
1978                 *py = ICON_Y(pcd) + ICON_HEIGHT(pcd);
1979                 if (*py + height >= DisplayHeight (DISPLAY, 
1980                                                    SCREEN_FOR_CLIENT(pcd)))
1981                 {
1982                     wmGD.checkHotspot = FALSE;
1983                 }
1984             }
1985             
1986             wmGD.hotspotRectangle.x = ICON_X(pcd);
1987             wmGD.hotspotRectangle.y = ICON_Y(pcd);
1988         }
1989
1990         /* setup the hotspot rectangle data */
1991
1992         wmGD.hotspotRectangle.width = ICON_WIDTH(pcd);
1993         wmGD.hotspotRectangle.height = ICON_HEIGHT(pcd);
1994     }
1995     else
1996     {
1997         /* 
1998          * Try to put the menu directly below the SW corner of the 
1999          *   titlebar/border.
2000          * If it would hit the bottom of the screen then try to put it directly
2001          *   above the NW corner of the titlebar/border.
2002          * If it would then hit the top of the screen turn of the hotspot
2003          *   processing.
2004          */
2005
2006         if ((pcd->decor & MWM_DECOR_TITLE) &&
2007             !(pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)))
2008         {
2009             *px = pcd->frameInfo.x;
2010             *py = pcd->frameInfo.y + pcd->frameInfo.titleBarHeight;
2011         }
2012         else 
2013         {
2014             *px = pcd->frameInfo.x + pcd->frameInfo.lowerBorderWidth;
2015             *py = pcd->frameInfo.y + pcd->frameInfo.upperBorderWidth + 
2016                   pcd->frameInfo.titleBarHeight;
2017         }
2018         if (*py + height >= DisplayHeight (DISPLAY, 
2019                   SCREEN_FOR_CLIENT(pcd)))
2020         {
2021             if ((pcd->decor & MWM_DECOR_TITLE) &&
2022                 !(pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)))
2023             {
2024                 *py = pcd->frameInfo.y - height;
2025             }
2026             else
2027             {
2028                 *py = pcd->frameInfo.y + pcd->frameInfo.upperBorderWidth - 
2029                     height;
2030             }
2031             if (*py < 0)
2032             {
2033                 wmGD.checkHotspot = FALSE;
2034             }
2035         }
2036
2037         /* setup the hotspot rectangle data */
2038
2039         wmGD.hotspotRectangle.x = pcd->frameInfo.x + 
2040                                   pcd->frameInfo.lowerBorderWidth;
2041         wmGD.hotspotRectangle.y = pcd->frameInfo.y + 
2042                                   pcd->frameInfo.upperBorderWidth;
2043
2044             /* assume square button */
2045         wmGD.hotspotRectangle.width = pcd->frameInfo.titleBarHeight;
2046         wmGD.hotspotRectangle.height = pcd->frameInfo.titleBarHeight;
2047     }
2048
2049 } /* END OF FUNCTION GetSystemMenuPosition */
2050
2051
2052 \f
2053 /*************************************<->*************************************
2054  *
2055  *  ShowActiveClientFrame (pcd)
2056  *
2057  *
2058  *  Description:
2059  *  -----------
2060  *  Paint the frame to indicate an "active" window
2061  *
2062  *
2063  *  Inputs:
2064  *  ------
2065  *  pcd         - pointer to client data
2066  *
2067  * 
2068  *  Outputs:
2069  *  -------
2070  *
2071  *
2072  *  Comments:
2073  *  --------
2074  *  o This calls the frame exposure procedure, which gets some GCs based
2075  *    on the current keyboard focus. Thus, wmGD.keyboardFocus == pcd
2076  *    must be TRUE when this is called for the correct highlighting to 
2077  *    occur.
2078  * 
2079  *************************************<->***********************************/
2080
2081 void 
2082 ShowActiveClientFrame (ClientData *pcd)
2083 {
2084     unsigned long attr_mask = 0;
2085     XSetWindowAttributes window_attribs;
2086
2087     if (DECOUPLE_TITLE_APPEARANCE(pcd) && 
2088          (pcd->decor & MWM_DECOR_TITLE))
2089     {
2090         /* 
2091          * Use background pixmap if one is specified, otherwise set the
2092          * appropriate background color. 
2093          */
2094
2095         if (CLIENT_TITLE_APPEARANCE(pcd).activeBackgroundPixmap)
2096             {
2097             attr_mask |= CWBackPixmap;
2098             window_attribs.background_pixmap =
2099                 CLIENT_TITLE_APPEARANCE(pcd).activeBackgroundPixmap;
2100         }
2101         else
2102         {
2103             attr_mask |= CWBackPixel;
2104             window_attribs.background_pixel = 
2105                 CLIENT_TITLE_APPEARANCE(pcd).activeBackground;
2106         }
2107
2108
2109         XChangeWindowAttributes (DISPLAY, pcd->clientTitleWin, attr_mask, 
2110                                  &window_attribs);
2111
2112         /* clear the frame to the right background */
2113         XClearWindow (DISPLAY, pcd->clientTitleWin);
2114     }
2115
2116     /* 
2117      * Use background pixmap if one is specified, otherwise set the
2118      * appropriate background color. 
2119      */
2120
2121     if (CLIENT_APPEARANCE(pcd).activeBackgroundPixmap)
2122     {
2123         attr_mask |= CWBackPixmap;
2124         window_attribs.background_pixmap =
2125                 CLIENT_APPEARANCE(pcd).activeBackgroundPixmap;
2126     }
2127     else
2128     {
2129         attr_mask |= CWBackPixel;
2130         window_attribs.background_pixel = 
2131                 CLIENT_APPEARANCE(pcd).activeBackground;
2132     }
2133
2134
2135     XChangeWindowAttributes (DISPLAY, pcd->clientFrameWin, attr_mask, 
2136                              &window_attribs);
2137
2138     /* clear the frame to the right background */
2139     XClearWindow (DISPLAY, pcd->clientFrameWin);
2140
2141     /* simulate exposure of window */
2142     FrameExposureProc (pcd);
2143
2144
2145 } /* END OF FUNCTION ShowActiveClient */
2146
2147
2148 \f
2149 /*************************************<->*************************************
2150  *
2151  *  ShowInactiveClientFrame (pcd)
2152  *
2153  *
2154  *  Description:
2155  *  -----------
2156  *  Paint the frame to indicate an "inactive" window
2157  *
2158  *
2159  *  Inputs:
2160  *  ------
2161  *  pcd         - pointer to client data
2162  *
2163  * 
2164  *  Outputs:
2165  *  -------
2166  *
2167  *
2168  *  Comments:
2169  *  --------
2170  *  o This calls the frame exposure procedure, which gets some GCs based
2171  *    on the current keyboard focus. Thus, wmGD.keyboardFocus == pcd
2172  *    must be FALSE when this is called for the correct highlighting to 
2173  *    occur.
2174  *  
2175  * 
2176  ******************************<->***********************************/
2177
2178 void 
2179 ShowInactiveClientFrame (ClientData *pcd)
2180 {
2181     unsigned long attr_mask = 0;
2182     XSetWindowAttributes window_attribs;
2183
2184     if (DECOUPLE_TITLE_APPEARANCE(pcd) && 
2185         (pcd->decor & MWM_DECOR_TITLE))
2186     {
2187         /* 
2188          * Use background pixmap if one is specified, otherwise set the
2189          * appropriate background color. 
2190          */
2191
2192         if (CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap)
2193         {
2194             attr_mask |= CWBackPixmap;
2195             window_attribs.background_pixmap =
2196                 CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap;
2197         }
2198         else
2199         {
2200             attr_mask |= CWBackPixel;
2201             window_attribs.background_pixel = 
2202                     CLIENT_TITLE_APPEARANCE(pcd).background;
2203         }
2204
2205
2206         XChangeWindowAttributes (DISPLAY, pcd->clientTitleWin, attr_mask, 
2207                                  &window_attribs);
2208
2209         /* clear the frame to the right background */
2210         XClearWindow (DISPLAY, pcd->clientTitleWin);
2211   
2212         /*
2213          * attr_mask must be cleared because it is set if
2214          * DECOUPLE_TITLE_APPEARANCE(pcd) is true.
2215          */
2216         attr_mask = 0;
2217   
2218     }
2219     /* 
2220      * Use background pixmap if one is specified, otherwise set the
2221      * appropriate background color. 
2222      */
2223
2224     if (CLIENT_APPEARANCE(pcd).backgroundPixmap)
2225     {
2226         attr_mask |= CWBackPixmap;
2227         window_attribs.background_pixmap =
2228             CLIENT_APPEARANCE(pcd).backgroundPixmap;
2229     }
2230     else
2231     {
2232         attr_mask |= CWBackPixel;
2233         window_attribs.background_pixel = 
2234                     CLIENT_APPEARANCE(pcd).background;
2235     }
2236
2237
2238     /* change window attribs so clear does the right thing */
2239     XChangeWindowAttributes (DISPLAY, pcd->clientFrameWin, attr_mask, 
2240                              &window_attribs);
2241
2242     /* clear the frame to the right background */
2243     XClearWindow (DISPLAY, pcd->clientFrameWin);
2244
2245     /* simulate exposure of window */
2246     FrameExposureProc (pcd);
2247
2248 } /* END OF FUNCTION ShowInactiveClientFrame */
2249
2250
2251 \f
2252 /*************************************<->*************************************
2253  *
2254  *  RegenerateClientFrame (pcd)
2255  *
2256  *
2257  *  Description:
2258  *  -----------
2259  *  Reconfigure the sizes of all the components of the client frame
2260  *
2261  *
2262  *  Inputs:
2263  *  ------
2264  *  pcd         - pointer to client data
2265  *
2266  * 
2267  *  Outputs:
2268  *  -------
2269  *
2270  *  Comments:
2271  *  --------
2272  *  
2273  * 
2274  *************************************<->***********************************/
2275
2276 void RegenerateClientFrame (ClientData *pcd)
2277 {
2278     unsigned long decor = pcd->decor;
2279 #ifdef PANELIST
2280     /* 
2281      * If an embedded client, there is no frame.
2282      */
2283     if (pcd->pECD)
2284     {
2285         if (!pcd->clientFrameWin)
2286         {
2287             return;
2288         }
2289     }
2290 #endif /* PANELIST */
2291
2292     /* recompute frame information */
2293     SetFrameInfo (pcd);
2294
2295     /* move & resize frame window */
2296     XMoveResizeWindow (DISPLAY, pcd->clientFrameWin, pcd->frameInfo.x, 
2297            pcd->frameInfo.y, pcd->frameInfo.width, pcd->frameInfo.height);
2298
2299
2300     /* resize title bar window */
2301     if (decor & MWM_DECOR_TITLE)
2302     {
2303         XResizeWindow (DISPLAY, pcd->clientTitleWin, 
2304            pcd->frameInfo.width - 2*pcd->frameInfo.upperBorderWidth, 
2305            pcd->frameInfo.titleBarHeight);
2306     }
2307
2308     /* resize base window */
2309     XResizeWindow (DISPLAY, pcd->clientBaseWin, BaseWindowWidth (pcd),
2310            BaseWindowHeight (pcd));
2311     
2312     /* resize the stretcher windows */
2313     if (SHOW_RESIZE_CURSORS(pcd) && (decor & MWM_DECOR_RESIZEH)) {
2314         XMoveResizeWindow (DISPLAY, 
2315             pcd->clientStretchWin[STRETCH_NORTH_WEST], 
2316             0, 0, pcd->frameInfo.cornerWidth, 
2317             pcd->frameInfo.cornerHeight);
2318
2319         XMoveResizeWindow (DISPLAY, 
2320             pcd->clientStretchWin[STRETCH_NORTH], 
2321             (int) pcd->frameInfo.cornerWidth, 0, 
2322             pcd->frameInfo.width - 2*pcd->frameInfo.cornerWidth, 
2323             pcd->frameInfo.upperBorderWidth);
2324
2325         XMoveResizeWindow (DISPLAY, 
2326             pcd->clientStretchWin[STRETCH_NORTH_EAST], 
2327             (int) (pcd->frameInfo.width - pcd->frameInfo.cornerWidth), 0, 
2328             pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2329
2330         XMoveResizeWindow (DISPLAY, 
2331             pcd->clientStretchWin[STRETCH_EAST], 
2332             (int) (pcd->frameInfo.width - pcd->frameInfo.lowerBorderWidth),
2333             (int) (pcd->frameInfo.cornerHeight), 
2334             pcd->frameInfo.lowerBorderWidth, 
2335             pcd->frameInfo.height - 2*pcd->frameInfo.cornerHeight);
2336
2337         XMoveResizeWindow (DISPLAY, 
2338             pcd->clientStretchWin[STRETCH_SOUTH_EAST], 
2339             (int) (pcd->frameInfo.width - pcd->frameInfo.cornerWidth),
2340             (int) (pcd->frameInfo.height - pcd->frameInfo.cornerHeight), 
2341             pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2342         
2343         XMoveResizeWindow (DISPLAY, 
2344             pcd->clientStretchWin[STRETCH_SOUTH], 
2345             (int) pcd->frameInfo.cornerWidth,
2346             (int) (pcd->frameInfo.height - pcd->frameInfo.lowerBorderWidth), 
2347             pcd->frameInfo.width - 2*pcd->frameInfo.cornerWidth,
2348             pcd->frameInfo.lowerBorderWidth);
2349
2350         XMoveResizeWindow (DISPLAY, 
2351             pcd->clientStretchWin[STRETCH_SOUTH_WEST], 
2352             0, (int) (pcd->frameInfo.height - pcd->frameInfo.cornerHeight), 
2353             pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2354
2355         XMoveResizeWindow (DISPLAY, 
2356             pcd->clientStretchWin[STRETCH_WEST], 
2357             0, (int) pcd->frameInfo.cornerHeight, 
2358             pcd->frameInfo.lowerBorderWidth,
2359             pcd->frameInfo.height - 2*pcd->frameInfo.cornerHeight);
2360     }
2361
2362     /* recreate gadget rectangles */
2363     ComputeGadgetRectangles (pcd);
2364
2365     /* regenerate the graphics */
2366     GenerateFrameDisplayLists (pcd);
2367
2368 #ifndef NO_SHAPE
2369     if (wmGD.hasShape && pcd->wShaped)
2370     {
2371         SetFrameShape (pcd);
2372     }
2373 #endif /*  NO_SHAPE  */
2374
2375 } /* END OF FUNCTION  RegenerateClientFrame  */
2376
2377
2378
2379 \f
2380 /*************************************<->*************************************
2381  *
2382  *  BevelSystemButton (prTop, prBot, x, y, width, height)
2383  *
2384  *
2385  *  Description:
2386  *  -----------
2387  *  Bevels a rectangle for the system button (drawer handle?)
2388  *
2389  *
2390  *  Inputs:
2391  *  ------
2392  *  prTop       - ptr to top shadow rectangles
2393  *  prBot       - ptr to bottom shadow rectangles
2394  *  x           - x coord of maximize gadget
2395  *  y           - y coord of maximize gadget
2396  *  width       - width of maximize gadget
2397  *  height      - height of maximize gadget
2398  *
2399  * 
2400  *  Outputs:
2401  *  -------
2402  *
2403  *
2404  *  Comments:
2405  *  --------
2406  *  o This draws a horizontal "drawer handle" for the system gadget.
2407  *    Assumptions: the enclosing box is square (width == height)
2408  *************************************<->***********************************/
2409
2410 void BevelSystemButton (RList *prTop, RList *prBot, int x, int y, 
2411                         unsigned int width, unsigned int height)
2412 {
2413     int offset1, offset2;
2414     unsigned int dim1, dim2;
2415
2416     switch (height) {
2417         case 5:
2418         case 6:
2419             offset1 = offset2 = 2;
2420             dim1 = dim2 = height-4;
2421             break;
2422
2423         case 7:
2424             offset1 = offset2 = 2;
2425             dim1 = 3;
2426             dim2 = 2;
2427             break;
2428         
2429         case 8:
2430         case 9:
2431             offset1 = 2;
2432             offset2 = 3;
2433             dim1 = width - 4;
2434             dim2 = height - 6;
2435             break;
2436
2437         case 10:
2438         case 11:
2439             offset1 = 3;
2440             offset2 = 4;
2441             dim1 = width - 6;
2442             dim2 = height - 8;
2443             break;
2444
2445         case 12:
2446         case 13:
2447             offset1 = 3;
2448             offset2 = (height-3)/2;
2449             dim1 = width - 6;
2450             dim2 = 3;
2451             break;
2452
2453         default:
2454             offset1 = 4;
2455             offset2 = (height - 4)/2;
2456             dim1 = width - 8;
2457             dim2 = 4;
2458             break;
2459
2460     }
2461
2462     if (height >= 5) {
2463         /* system icon */
2464         BevelRectangle (prTop, prBot,           /* system icon */
2465                     (x+offset1), (y+offset2),
2466                     dim1, dim2,
2467                     1, 1, 1, 1);
2468         }
2469 } /* END OF FUNCTION  BevelSystemButton   */
2470
2471
2472 \f
2473 /*************************************<->*************************************
2474  *
2475  *  BevelMinimizeButton (prTop, prBot, x, y, height)
2476  *
2477  *
2478  *  Description:
2479  *  -----------
2480  *  Bevels a rectangle for the minimize button
2481  *
2482  *
2483  *  Inputs:
2484  *  ------
2485  *  prTop       - ptr to top shadow rectangles
2486  *  prBot       - ptr to bottom shadow rectangles
2487  *  x           - x coord of maximize gadget
2488  *  y           - y coord of maximize gadget
2489  *  height      - height of maximize gadget
2490  *
2491  * 
2492  *  Outputs:
2493  *  -------
2494  *
2495  *
2496  *  Comments:
2497  *  --------
2498  * 
2499  *************************************<->***********************************/
2500
2501 void BevelMinimizeButton (RList *prTop, RList *prBot, int x, int y, 
2502                           unsigned int height)
2503 {
2504     int offset1, offset2;
2505     unsigned int dim1, dim2;
2506
2507     switch (height) {
2508         case 7:
2509         case 8:
2510         case 9:
2511             offset1 = offset2 = 3;
2512             dim1 = dim2 = height-6;
2513             break;
2514
2515         case 10:
2516         case 11:
2517         case 12:
2518             offset1 = offset2 = (height-3)/2;
2519             dim1 = dim2 = 3;
2520             break;
2521
2522         default:
2523             offset1 = offset2 = (height-4)/2;
2524             dim1 = dim2 = 4;
2525             break;
2526     }
2527
2528     if (height >= 7) {
2529         /* minimize icon */
2530         BevelRectangle (prTop, prBot,
2531                     (x+offset1), (y+offset2),
2532                     dim1, dim2,
2533                     1, 1, 1, 1);
2534     }
2535 } /* END OF FUNCTION  BevelMinimizeButton   */
2536
2537
2538 \f
2539 /*************************************<->*************************************
2540  *
2541  *  BevelMaximizeButton (prTop, prBot, x, y, height)
2542  *
2543  *
2544  *  Description:
2545  *  -----------
2546  *  Bevels a rectangle for the maximize button
2547  *
2548  *
2549  *  Inputs:
2550  *  ------
2551  *  prTop       - ptr to top shadow rectangles
2552  *  prBot       - ptr to bottom shadow rectangles
2553  *  x           - x coord of maximize gadget
2554  *  y           - y coord of maximize gadget
2555  *  height      - height of maximize gadget
2556  *
2557  * 
2558  *  Outputs:
2559  *  -------
2560  *
2561  *
2562  *  Comments:
2563  *  --------
2564  * 
2565  *************************************<->***********************************/
2566
2567 void BevelMaximizeButton (RList *prTop, RList *prBot, int x, int y, 
2568                           unsigned int height)
2569 {
2570     int offset1, offset2;
2571     unsigned int dim1, dim2;
2572
2573     switch (height) {
2574         case 5:
2575         case 6:
2576         case 7:
2577         case 8:
2578         case 9:
2579         case 10:
2580         case 11:
2581             offset1 = offset2 = 2;
2582             dim1 = dim2 = height-4;
2583             break;
2584
2585         case 12:
2586         case 13:
2587         case 14:
2588         case 15:
2589             offset1 = offset2 = 3;
2590             dim1 = dim2 = height-6;
2591             break;
2592
2593         default:
2594             offset1 = offset2 = 4;
2595             dim1 = dim2 = height-8;
2596             break;
2597     }
2598
2599     /* maximize icon */
2600     BevelRectangle (prTop, prBot,
2601                     (x+offset1), (y+offset2),
2602                     dim1, dim2,
2603                     1, 1, 1, 1);
2604 } /* END OF FUNCTION  BevelMaximizeButton   */
2605
2606 \f
2607 /*************************************<->*************************************
2608  *
2609  *  DepressGadget (pcd, gadget, depressed)
2610  *
2611  *
2612  *  Description:
2613  *  -----------
2614  *  Show the gadget in a "depressed" state
2615  *
2616  *
2617  *  Inputs:
2618  *  ------
2619  *  pcd         - pointer to client data
2620  *  gadget      - gadget id
2621  *  depressed   - if True, then gadget is shown depressed, if False it is
2622  *                shown not depressed
2623  *
2624  * 
2625  *  Outputs:
2626  *  -------
2627  *  return      - true if sucessful
2628  *
2629  *
2630  *  Comments:
2631  *  --------
2632  *  o This assumes there is a one-pixel bevel around the gadget.
2633  *  o This only works on title bar gadgets.
2634  * 
2635  *************************************<->***********************************/
2636
2637 Boolean DepressGadget (ClientData *pcd, int gadget, Boolean depressed)
2638 {
2639     int x, y; 
2640     unsigned int width, height, invertWidth;
2641     static RList *pTopRect = NULL; 
2642     static RList *pBotRect = NULL; 
2643     GC topGC, botGC;
2644     Window win;
2645
2646     /* get outside dimensions of box we want */
2647
2648     switch (gadget) {
2649         case FRAME_TITLE:
2650         case FRAME_SYSTEM:
2651         case FRAME_MINIMIZE:
2652         case FRAME_MAXIMIZE:
2653             if (!GetDepressInfo (pcd, gadget, &x, &y, &width, 
2654                                  &height, &invertWidth))
2655                 return(FALSE);
2656             
2657             break;
2658
2659         default:
2660             return(FALSE);      /* do nothing on non-title bar gagdets */
2661     }
2662
2663     if (DECOUPLE_TITLE_APPEARANCE(pcd) && 
2664          (pcd->decor & MWM_DECOR_TITLE))
2665     {
2666         /* adjust position to be relative to titlebar window, not frame */
2667         x -= (short) pcd->frameInfo.upperBorderWidth;
2668         y -= (short) pcd->frameInfo.upperBorderWidth;
2669
2670         /* use "active" GCs if we have keyboard focus */
2671         if (pcd == wmGD.keyboardFocus) {
2672             topGC = CLIENT_TITLE_APPEARANCE(pcd).activeTopShadowGC;
2673             botGC = CLIENT_TITLE_APPEARANCE(pcd).activeBottomShadowGC;
2674         }
2675         else {
2676             topGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveTopShadowGC;
2677             botGC = 
2678                 CLIENT_TITLE_APPEARANCE(pcd).inactiveBottomShadowGC;
2679         }
2680
2681         /* draw into title bar window */
2682         win = pcd->clientTitleWin;
2683     }
2684     else 
2685     {
2686         /* use "active" GCs if we have keyboard focus */
2687         if (pcd == wmGD.keyboardFocus) {
2688             topGC = CLIENT_APPEARANCE(pcd).activeTopShadowGC;
2689             botGC = CLIENT_APPEARANCE(pcd).activeBottomShadowGC;
2690         }
2691         else {
2692             topGC = CLIENT_APPEARANCE(pcd).inactiveTopShadowGC;
2693             botGC = CLIENT_APPEARANCE(pcd).inactiveBottomShadowGC;
2694         }
2695
2696         /* draw into client frame window */
2697         win = pcd->clientFrameWin;
2698     }
2699
2700     /* 
2701      * Bevel a rectangle for the desired button effect 
2702      * Allocate the rectangles if necessary.
2703      */
2704     if ( (pTopRect && pBotRect) ||
2705          ((pTopRect = AllocateRList(2)) &&
2706           (pBotRect = AllocateRList(2))))
2707     {
2708         pTopRect->used = 0;
2709         pBotRect->used = 0;
2710         BevelRectangle (pTopRect, pBotRect, 
2711                     x, y, width, height, 
2712                     invertWidth, invertWidth, 
2713                     invertWidth, invertWidth);
2714     }
2715
2716     /* draw the gadget border to make it look depressed or normal */
2717
2718     if (depressed) {
2719         XFillRectangles (DISPLAY, win, botGC, pTopRect->prect, pTopRect->used);
2720         XFillRectangles (DISPLAY, win, topGC, pBotRect->prect, pBotRect->used);
2721     }
2722     else {
2723         XFillRectangles (DISPLAY, win, topGC, pTopRect->prect, pTopRect->used);
2724         XFillRectangles (DISPLAY, win, botGC, pBotRect->prect, pBotRect->used);
2725     }
2726     return(TRUE);
2727 } /* END OF FUNCTION  DepressGadget   */
2728
2729 \f
2730 /*************************************<->*************************************
2731  *
2732  *  PushGadgetIn (pcd, gadget)
2733  *
2734  *
2735  *  Description:
2736  *  -----------
2737  *  Shows a title bar gadget in a depressed state
2738  *
2739  *
2740  *  Inputs:
2741  *  ------
2742  *  pcd         - pointer to client data
2743  *  gadget      - gadget id
2744  * 
2745  *  Outputs:
2746  *  -------
2747  *
2748  *  Comments:
2749  *  --------
2750  * 
2751  *************************************<->***********************************/
2752
2753 void PushGadgetIn (ClientData *pcd, int gadget)
2754 {
2755     switch (gadget) {
2756         case FRAME_SYSTEM:
2757             pcd->decorFlags |= SYSTEM_DEPRESSED;
2758             break;
2759
2760         case FRAME_TITLE:
2761             pcd->decorFlags |= TITLE_DEPRESSED;
2762             break;
2763
2764         case FRAME_MINIMIZE:
2765             pcd->decorFlags |= MINIMIZE_DEPRESSED;
2766             break;
2767
2768         case FRAME_MAXIMIZE:
2769             pcd->decorFlags |= MAXIMIZE_DEPRESSED;
2770             break;
2771
2772         default:
2773             return;
2774     }
2775     GenerateFrameDisplayLists(pcd);
2776     (void) DepressGadget (pcd, gadget, TRUE);
2777     wmGD.gadgetClient = pcd;
2778     wmGD.gadgetDepressed =  gadget;
2779 } /* END OF FUNCTION  PushGadgetIn   */
2780
2781 \f
2782 /*************************************<->*************************************
2783  *
2784  *  PopGadgetOut (pcd, gadget)
2785  *
2786  *
2787  *  Description:
2788  *  -----------
2789  *  Shows a title bar gadget in a depressed state
2790  *
2791  *
2792  *  Inputs:
2793  *  ------
2794  *  pcd         - pointer to client data
2795  *  gadget      - gadget id
2796  * 
2797  *  Outputs:
2798  *  -------
2799  *
2800  *  Comments:
2801  *  --------
2802  * 
2803  *************************************<->***********************************/
2804
2805 void PopGadgetOut (ClientData *pcd, int gadget)
2806 {
2807     switch (gadget) {
2808         case FRAME_SYSTEM:
2809             pcd->decorFlags &= ~SYSTEM_DEPRESSED;
2810             break;
2811
2812         case FRAME_TITLE:
2813             pcd->decorFlags &= ~TITLE_DEPRESSED;
2814             break;
2815
2816         case FRAME_MINIMIZE:
2817             pcd->decorFlags &= ~MINIMIZE_DEPRESSED;
2818             break;
2819
2820         case FRAME_MAXIMIZE:
2821             pcd->decorFlags &= ~MAXIMIZE_DEPRESSED;
2822             break;
2823
2824         default:
2825             return;
2826     }
2827     GenerateFrameDisplayLists(pcd);
2828     (void) DepressGadget (pcd, gadget, FALSE);
2829     wmGD.gadgetClient    = NULL;
2830     wmGD.gadgetDepressed = 0;
2831 } /* END OF FUNCTION  PopGadgetOut   */
2832
2833 #ifndef NO_SHAPE
2834 \f
2835 /*************************************<->*************************************
2836  *
2837  *  SetFrameShape (pcd)
2838  *
2839  *
2840  *  Description:
2841  *  -----------
2842  *  Shapes the frame and base window to the shape of the client
2843  *  window. Also ors the title window into the shaped frame
2844  *  window if present.
2845  *
2846  *  Inputs:
2847  *  ------
2848  *  pcd         - pointer to client data
2849  * 
2850  *  Outputs:
2851  *  -------
2852  *
2853  *  Comments:
2854  *  --------
2855  *  o currently punt on resize handle around the frame.
2856  *  
2857  *************************************<->***********************************/
2858 void SetFrameShape (ClientData *pcd)
2859 {
2860     /*
2861      * The frame consists of the shape of the contents window offset by
2862      * title_height or'ed with the shape of title window (which is always
2863      * rectangular).
2864      */
2865     int xOffset = 0;
2866     int yOffset = 0;
2867
2868     if (XBorderIsShowing(pcd))
2869     {
2870         xOffset = pcd->xBorderWidth;
2871         yOffset = pcd->xBorderWidth;
2872     }
2873     else if(pcd->matteWidth > 0)
2874     {
2875         xOffset = pcd->matteWidth;
2876         yOffset = pcd->matteWidth;
2877     }
2878
2879     if (pcd->wShaped)
2880     {
2881         /*
2882          * need to do general case
2883          */
2884         XShapeCombineShape (DISPLAY, pcd->clientBaseWin, ShapeBounding,
2885                             xOffset,
2886                             yOffset,
2887                             pcd->client, ShapeBounding,
2888                             ShapeSet);
2889
2890         XShapeCombineShape (DISPLAY, pcd->clientFrameWin, ShapeBounding,
2891                             BaseWindowX (pcd),
2892                             BaseWindowY (pcd),
2893                             pcd->clientBaseWin, ShapeBounding,
2894                             ShapeSet);
2895
2896         if (pcd->decor & MWM_DECOR_TITLE)
2897         {
2898             XShapeCombineShape (DISPLAY, pcd->clientFrameWin, ShapeBounding,
2899                                 pcd->frameInfo.upperBorderWidth,
2900                                 pcd->frameInfo.upperBorderWidth,
2901                                 pcd->clientTitleWin, ShapeBounding,
2902                                 ShapeUnion);
2903         }
2904     }
2905     else
2906     {
2907          (void) XShapeCombineMask (DISPLAY, pcd->clientFrameWin, 
2908                                    ShapeBounding, 0, 0,
2909                                    None, ShapeSet);
2910          (void) XShapeCombineMask (DISPLAY, pcd->clientFrameWin, 
2911                                    ShapeClip, 0, 0,
2912                                    None, ShapeSet);
2913          (void) XShapeCombineMask (DISPLAY, pcd->clientBaseWin, 
2914                                    ShapeBounding, 0, 0,
2915                                    None, ShapeSet);
2916          (void) XShapeCombineMask (DISPLAY, pcd->clientBaseWin, 
2917                                    ShapeClip, 0, 0,
2918                                    None, ShapeSet);
2919     }
2920 } /* END OF FUNCTION  SetFrameShape  */
2921 #endif /* NO_SHAPE */
2922
2923
2924 \f