dtwm: Remove the define PANELIST, it is always on for dtwm
[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 libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* 
24  * (c) Copyright 1989, 1990, 1991, 1992 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 = 0, yAdj = 0;
570     unsigned int width, height;
571     RList *prlTop = NULL, *prlBot = NULL;
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             if((pcd->dtwmBehaviors & DtWM_BEHAVIOR_PANEL) &&
755                (pcd->clientDecoration == WM_DECOR_BORDER))
756             {
757                 insideBevel = 0;
758             }
759             BevelRectangle (pcd->pclientBottomShadows,  /* inside */
760                             pcd->pclientTopShadows, 
761                             (int)(pcd->frameInfo.lowerBorderWidth-insideBevel), 
762                             (int)(pcd->frameInfo.lowerBorderWidth-insideBevel), 
763                             pcd->frameInfo.width - 
764                                 2*pcd->frameInfo.lowerBorderWidth + 
765                                 2*insideBevel, 
766                             pcd->frameInfo.height - 
767                                 2*pcd->frameInfo.lowerBorderWidth + 
768                                 2*insideBevel,
769                             (unsigned int)insideBevel, 
770                             (unsigned int)insideBevel,
771                             (unsigned int)insideBevel, 
772                             (unsigned int)insideBevel);
773         }
774     }
775
776
777     /* draw title bar */
778
779     /* 
780      * set bevels for title bar and parts 
781      */
782     if (decoration & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
783     {
784         nTitleBevel = JOIN_BEVEL(pcd);  /* north side of title */
785         if (wmGD.frameStyle == WmSLAB)
786         {
787             sTitleBevel = JOIN_BEVEL(pcd);      /* south side of title */
788         }
789         else
790         {
791             sTitleBevel = insideBevel;  /* south side of title */
792         }
793         eTitleBevel = JOIN_BEVEL(pcd);  /* east side of title */
794         wTitleBevel = JOIN_BEVEL(pcd);  /* west side of title */
795         meTitleBevel = JOIN_BEVEL(pcd); /* btw Minimize, Maximize */
796     }
797     else 
798     {
799         /* borderless window */
800
801         nTitleBevel = EXTERNAL_BEVEL(pcd);
802         if (wmGD.frameStyle == WmSLAB)
803         {
804             sTitleBevel = (matte_width > 0) ? JOIN_BEVEL(pcd) : 
805                                                 EXTERNAL_BEVEL(pcd);
806         }
807         else
808         {
809             sTitleBevel = (matte_width > 0) ? insideBevel : EXTERNAL_BEVEL(pcd);
810         }
811         eTitleBevel = (decoration & (MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE))?
812                           JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
813         wTitleBevel = (decoration & MWM_DECOR_MENU) ?
814                           JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
815
816         /* beveling east of minimize */
817         meTitleBevel = (decoration & (MWM_DECOR_MAXIMIZE)) ?
818                           JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
819     }
820
821
822     if (decoration & MWM_DECOR_TITLE) 
823     {
824         /*
825          * Use a different set of rectangles if title appearance
826          * is different from the rest of the frame.
827          */
828         if (DECOUPLE_TITLE_APPEARANCE(pcd)) 
829         {
830             prlTop = pcd->pclientTitleTopShadows;
831             prlBot = pcd->pclientTitleBottomShadows;
832             xAdj = yAdj = pcd->frameInfo.upperBorderWidth;
833         }
834         else
835         {
836             prlTop = pcd->pclientTopShadows;
837             prlBot = pcd->pclientBottomShadows;
838             xAdj = yAdj = 0;
839         }
840
841
842         GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height);
843         if (pcd->decorFlags & TITLE_DEPRESSED) {
844             /* show depressed title gadget */
845             GetDepressInfo (pcd, FRAME_TITLE, &jX, &jY, &jW, &jH, 
846                             &inWidth);
847             BevelDepressedRectangle (prlTop, prlBot, 
848                         x-xAdj, y-yAdj, width, height,
849                         nTitleBevel, eTitleBevel, 
850                         sTitleBevel, wTitleBevel, inWidth);
851         }
852         else {
853             /* show normal title gadget */
854             BevelRectangle (prlTop, prlBot, 
855                         x-xAdj, y-yAdj, width, height,
856                         nTitleBevel, eTitleBevel, 
857                         sTitleBevel, wTitleBevel);
858         }
859     }
860
861     if (decoration & MWM_DECOR_MENU) {
862
863         GetFramePartInfo (pcd, FRAME_SYSTEM, &x, &y, &width, &height);
864         if (pcd->decorFlags & SYSTEM_DEPRESSED) {
865             /* show depressed system gadget */
866             GetDepressInfo (pcd, FRAME_SYSTEM, &jX, &jY, &jW, &jH, 
867                             &inWidth);
868             BevelDepressedRectangle (prlTop, prlBot, 
869                             x-xAdj, y-yAdj, width, height,
870                             nTitleBevel, wTitleBevel, 
871                             sTitleBevel, nTitleBevel, inWidth);
872         }
873         else
874         {
875             /* show normal system gadget */
876             BevelRectangle (prlTop, prlBot, 
877                             x-xAdj, y-yAdj, width, height,
878                             nTitleBevel, wTitleBevel, 
879                             sTitleBevel, nTitleBevel);
880         }
881
882
883         /* system icon */
884         BevelSystemButton (prlTop, prlBot, 
885                            x-xAdj, y-yAdj, width, height);
886     }
887                     
888     if (decoration & MWM_DECOR_MINIMIZE) { 
889         GetFramePartInfo (pcd, FRAME_MINIMIZE, &x, &y, &width, &height);
890
891         if (pcd->decorFlags & MINIMIZE_DEPRESSED) {
892             /* show depressed minimize gadget */
893             GetDepressInfo (pcd, FRAME_MINIMIZE, &jX, &jY, &jW, &jH, 
894                             &inWidth);
895             BevelDepressedRectangle (prlTop, prlBot, 
896                             x-xAdj, y-yAdj, width, height,
897                             nTitleBevel, meTitleBevel, 
898                             sTitleBevel, eTitleBevel, inWidth);
899         }
900         else {
901             /* show normal minimize gadget */
902             BevelRectangle (prlTop, prlBot, 
903                             x-xAdj, y-yAdj, width, height,
904                             nTitleBevel, meTitleBevel, 
905                             sTitleBevel, eTitleBevel);
906         }
907
908
909         BevelMinimizeButton(prlTop,     /* minimize icon */
910                             prlBot, 
911                             x-xAdj, y-yAdj, height);
912     }
913
914     if (decoration & MWM_DECOR_MAXIMIZE) {
915         GetFramePartInfo (pcd, FRAME_MAXIMIZE, &x, &y, &width, &height);
916
917
918         if (pcd->decorFlags & MAXIMIZE_DEPRESSED) {
919             /* show depressed maximize gadget */
920             GetDepressInfo (pcd, FRAME_MAXIMIZE, &jX, &jY, &jW, &jH, 
921                             &inWidth);
922             BevelDepressedRectangle (prlTop, prlBot, 
923                             x-xAdj, y-yAdj, width, height,
924                             nTitleBevel, nTitleBevel, 
925                             sTitleBevel, eTitleBevel, inWidth);
926         }
927         else {
928             /* show normal maximize gadget */
929             BevelRectangle (prlTop, prlBot, 
930                             x-xAdj, y-yAdj, width, height,
931                             nTitleBevel, nTitleBevel, 
932                             sTitleBevel, eTitleBevel);
933         }
934
935         /* maximize icon - in or out depending on client state */
936         if (pcd->maxConfig) {
937             BevelMaximizeButton(prlBot, 
938                                 prlTop,
939                                 x-xAdj, y-yAdj, height);
940         }
941         else {
942             BevelMaximizeButton(prlTop,
943                                 prlBot, 
944                                 x-xAdj, y-yAdj, height);
945         }
946         
947     }
948
949     /* draw the client matte (this is in the base window!!!) */
950
951     if (matte_width > 0) {
952         unsigned int mWidth, mHeight, exMatteBevel, tMatteBevel;
953
954         mWidth = BaseWindowWidth (pcd);
955         mHeight = BaseWindowHeight (pcd);
956
957         if (decoration & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
958         {
959             exMatteBevel = JOIN_BEVEL(pcd);
960             tMatteBevel = JOIN_BEVEL(pcd);
961         }
962         else 
963         {
964             exMatteBevel = EXTERNAL_BEVEL(pcd);
965             tMatteBevel = (decoration & MWM_DECOR_TITLE) ?
966                            JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
967         }
968
969         /* set up beveling around the edges */
970
971         BevelRectangle (pcd->pclientMatteTopShadows,
972                     pcd->pclientMatteBottomShadows,
973                     0, 
974                     0,
975                     mWidth,
976                     mHeight,
977                     tMatteBevel, exMatteBevel, 
978                     exMatteBevel, exMatteBevel);
979
980         /* reversed beveling on inside rectange ! */
981
982         BevelRectangle ( pcd->pclientMatteBottomShadows,
983                     pcd->pclientMatteTopShadows,
984                     matte_width - pcd->internalBevel, 
985                     matte_width - pcd->internalBevel,
986                     mWidth - 2*matte_width + 2*pcd->internalBevel, 
987                     mHeight - 2*matte_width + 2*pcd->internalBevel,
988                     (unsigned int) pcd->internalBevel, 
989                     (unsigned int) pcd->internalBevel, 
990                     (unsigned int) pcd->internalBevel, 
991                     (unsigned int) pcd->internalBevel);
992     }
993 }
994
995 \f
996 /*************************************<->*************************************
997  *
998  *  AdoptClient (pcd)
999  *
1000  *
1001  *  Description:
1002  *  -----------
1003  *  Reparent the client window to the window frame
1004  *
1005  *
1006  *  Inputs:
1007  *  ------
1008  *  pcd         - pointer to client data record
1009  *
1010  * 
1011  *  Outputs:
1012  *  -------
1013  *  None
1014  *
1015  *
1016  *  Comments:
1017  *  --------
1018  * 
1019  *************************************<->***********************************/
1020
1021 void AdoptClient (ClientData *pcd)
1022 {
1023     XWindowChanges windowChanges;
1024     unsigned int mask;
1025
1026     /* Put the window in the window manager's save set */
1027
1028     if (!(pcd->clientFlags & CLIENT_WM_CLIENTS))
1029     {
1030         XChangeSaveSet (DISPLAY, pcd->client, SetModeInsert);
1031         pcd->clientFlags |= CLIENT_IN_SAVE_SET;
1032     }
1033
1034     /*
1035      * set window geometry to be consistent with what we believe 
1036      */
1037     mask = CWWidth | CWHeight;
1038     windowChanges.width = pcd->clientWidth;
1039     windowChanges.height = pcd->clientHeight;
1040
1041     /*
1042      * strip off previous window border if we're adding our own border
1043      * or matte
1044      */
1045     if ( (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)) ||
1046          (pcd->matteWidth > 0) )
1047     {
1048         mask |= CWBorderWidth;
1049         windowChanges.border_width = 0;
1050     }
1051
1052     XConfigureWindow (DISPLAY, pcd->client, mask, &windowChanges);
1053
1054 #ifndef NO_SHAPE
1055     /* shape our frame to match that of the client's window */
1056     if (wmGD.hasShape)
1057     {
1058         int xws, yws, xbs, ybs;
1059         unsigned wws, hws, wbs, hbs;
1060         int boundingShaped, clipShaped;
1061         
1062         XShapeSelectInput (DISPLAY, pcd->client, ShapeNotifyMask);
1063         XShapeQueryExtents (DISPLAY, pcd->client,
1064                             &boundingShaped, &xws, &yws, &wws, &hws,
1065                             &clipShaped, &xbs, &ybs, &wbs, &hbs);
1066         pcd->wShaped = boundingShaped;
1067     }
1068 #endif /* NO_SHAPE  */
1069     /* reparent the window to the base window */
1070
1071     XReparentWindow (DISPLAY, pcd->client, pcd->clientBaseWin, 
1072                         pcd->matteWidth, 
1073                         pcd->matteWidth);
1074     pcd->clientFlags |= CLIENT_REPARENTED;
1075
1076 } /* END OF FUNCTION AdoptClient */
1077
1078
1079 \f
1080 /*************************************<->*************************************
1081  *
1082  *  GetTextBox (pcd, pBox)
1083  *
1084  *
1085  *  Description:
1086  *  -----------
1087  *  Gets the rectangle that the text should fit into in the title bar
1088  *
1089  *
1090  *  Inputs:
1091  *  ------
1092  *  pcd         - pointer to client data
1093  *  pBox        - pointer to an XRectangle structure that gets return data
1094  * 
1095  *  Outputs:
1096  *  -------
1097  *  pBox        - data is returned here
1098  *
1099  *  Comments:
1100  *  --------
1101  * 
1102  *************************************<->***********************************/
1103
1104 void GetTextBox (ClientData *pcd, XRectangle *pBox)
1105 {
1106     int x,y;
1107     unsigned int width,height;
1108 #if defined(WSM) && defined(DT_LEFT_JUSTIFIED_TITLE)
1109     Dimension textWidth;
1110     Dimension offset;
1111     XmFontList  fontList;
1112 #endif /* WSM */
1113
1114     /* get size of title area */
1115
1116     if (!GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height))
1117     {
1118         /* no title area !!! */
1119         pBox->x = 0;
1120         pBox->y = 0;
1121         pBox->width = 0;
1122         pBox->height = 0;
1123         return;
1124     }
1125
1126     /* adjust for shadowing and allow for some padding around the edges */
1127     x += WM_TOP_TITLE_SHADOW + WM_TOP_TITLE_PADDING;
1128     y += WM_TOP_TITLE_SHADOW + WM_TOP_TITLE_PADDING;
1129
1130     width -= WM_TOP_TITLE_SHADOW + WM_BOTTOM_TITLE_SHADOW +
1131              WM_TOP_TITLE_PADDING + WM_BOTTOM_TITLE_PADDING;
1132     height -= WM_TOP_TITLE_SHADOW + WM_BOTTOM_TITLE_SHADOW +
1133               WM_TOP_TITLE_PADDING + WM_BOTTOM_TITLE_PADDING;
1134
1135 #ifdef DT_LEFT_JUSTIFIED_TITLE
1136     if (wmGD.frameStyle == WmSLAB)
1137     {
1138         /*
1139          * We left justify the title in this style.
1140          * To keep it a little neat, we offset the title from 
1141          * the left edge just a little (half the title height).
1142          * See if we have room to do this.
1143          */
1144         if (DECOUPLE_TITLE_APPEARANCE(pcd))
1145             fontList = CLIENT_TITLE_APPEARANCE(pcd).fontList;
1146         else
1147             fontList = CLIENT_APPEARANCE(pcd).fontList;
1148         textWidth = XmStringWidth(fontList, pcd->clientTitle);
1149
1150         offset = TitleBarHeight(pcd)/2;
1151
1152         if ((textWidth + offset) <= width)
1153         {
1154             /* We have plenty of room, do the offset */
1155             x += offset;
1156             width -= offset;
1157         }
1158         else if ((short) (width - textWidth) > 0)
1159         {
1160             /* We don't have enough room to do our usual offset,
1161              * but if we reduce the offset, the text won't get
1162              * clipped.
1163              */
1164             offset = (width - textWidth) / 2;
1165             x += offset;
1166             width -= offset;
1167         }
1168     }
1169
1170 #endif /* DT_LEFT_JUSTIFIED_TITLE */
1171     /* return position and size */
1172     pBox->x = x;
1173     pBox->y = y;
1174     pBox->width = width;
1175     pBox->height = height;
1176
1177 }
1178
1179
1180
1181 \f
1182 /*************************************<->*************************************
1183  *
1184  *  DrawWindowTitle (pcd, eraseFirst)
1185  *
1186  *
1187  *  Description:
1188  *  -----------
1189  *  Overwrites or replaces the client's title text in the 
1190  *  title bar of the frame.
1191  *
1192  *
1193  *  Inputs:
1194  *  ------
1195  *  pcd         - pointer to client data
1196  *  eraseFirst  - if true, then the old title is erased first
1197  * 
1198  *  Outputs:
1199  *  -------
1200  *  none
1201  *
1202  *  Comments:
1203  *  --------
1204  *  o Assumes 8-bit text for now.
1205  *  
1206  * 
1207  *************************************<->***********************************/
1208
1209 void DrawWindowTitle (ClientData *pcd, Boolean eraseFirst)
1210 {
1211     GC clientGC;
1212     unsigned long decoration = pcd->decor;
1213     XRectangle textBox;
1214     Window win;
1215     XmFontList  fontList;
1216
1217     /* make sure there is a title bar first */
1218     if (!(decoration & MWM_DECOR_TITLE))
1219         return;
1220
1221     if (DECOUPLE_TITLE_APPEARANCE(pcd))
1222     {
1223         /* use "active" GC if we have keyboard focus */
1224         if (pcd == wmGD.keyboardFocus) {
1225             clientGC = CLIENT_TITLE_APPEARANCE(pcd).activeGC;
1226         }
1227         else {
1228             clientGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveGC;
1229         }
1230
1231         /* get the area that the text must fit in */
1232         GetTextBox (pcd, &textBox);
1233
1234         /* adjust position to be relative to titlebar window, not frame */
1235         textBox.x -= (short) pcd->frameInfo.upperBorderWidth;
1236         textBox.y -= (short) pcd->frameInfo.upperBorderWidth;
1237
1238         win = pcd->clientTitleWin;
1239         fontList = CLIENT_TITLE_APPEARANCE(pcd).fontList;
1240     }
1241     else 
1242     {
1243         /* use "active" GC if we have keyboard focus */
1244         if (pcd == wmGD.keyboardFocus) {
1245             clientGC = CLIENT_APPEARANCE(pcd).activeGC;
1246         }
1247         else {
1248             clientGC = CLIENT_APPEARANCE(pcd).inactiveGC;
1249         }
1250
1251         /* get the area that the text must fit in */
1252         GetTextBox (pcd, &textBox);
1253         win = pcd->clientFrameWin;
1254         fontList = CLIENT_APPEARANCE(pcd).fontList;
1255     }
1256
1257     if (eraseFirst)
1258     {
1259         XClearArea (DISPLAY, win, textBox.x, textBox.y, 
1260                 (unsigned int) textBox.width, (unsigned int) textBox.height, 
1261                 FALSE);
1262     }
1263
1264 #ifdef  DT_LEFT_JUSTIFIED_TITLE
1265     WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1266                    textBox.x, textBox.y, textBox.width, &textBox,
1267                    ((wmGD.frameStyle == WmSLAB) ? False : True));
1268 #else /* DT_LEFT_JUSTIFIED_TITLE */
1269 #ifdef WSM
1270     WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1271                    textBox.x, textBox.y, textBox.width, &textBox,
1272                    True);
1273 #else
1274     WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1275                    textBox.x, textBox.y, textBox.width, &textBox);
1276 #endif
1277 #endif /* DT_LEFT_JUSTIFIED_TITLE */
1278                      
1279
1280
1281 } /* END OF FUNCTION DrawWindowTitle */
1282
1283
1284 \f
1285 /*************************************<->*************************************
1286  *
1287  *  CreateStretcherWindows (pcd)
1288  *
1289  *
1290  *  Description:
1291  *  -----------
1292  *  Create the input-only windows that overlay the resize gadgets.
1293  *
1294  *
1295  *  Inputs:
1296  *  ------
1297  *  pcd         - pointer to client data.
1298  *
1299  * 
1300  *  Outputs:
1301  *  -------
1302  *  pcd         - modified
1303  *
1304  *  Return      - none
1305  *
1306  *
1307  *  Comments:
1308  *  --------
1309  *  o The windows are sized based upon resizeBorderWidth
1310  *  o This should be called before creating the title bar, 
1311  *    and reparenting window. Later windows should obscure parts of the 
1312  *    stretchers.
1313  *  o The stretchers are given special cursors.
1314  * 
1315  *************************************<->***********************************/
1316
1317 void CreateStretcherWindows (ClientData *pcd)
1318 {
1319     int iWin;
1320     int x, y;
1321     unsigned int width, height;
1322     XSetWindowAttributes win_attribs;
1323     unsigned long attr_mask;
1324
1325     for (iWin = 0; iWin < STRETCH_COUNT; iWin++) {
1326         switch (iWin) {
1327             case STRETCH_NORTH_WEST:
1328                     GetFramePartInfo (pcd, FRAME_RESIZE_NW, 
1329                                       &x, &y, &width, &height);
1330                     break;
1331
1332             case STRETCH_NORTH:
1333                     GetFramePartInfo (pcd, FRAME_RESIZE_N, 
1334                                       &x, &y, &width, &height);
1335                     break;
1336
1337             case STRETCH_NORTH_EAST:
1338                     GetFramePartInfo (pcd, FRAME_RESIZE_NE, 
1339                                       &x, &y, &width, &height);
1340                     break;
1341
1342             case STRETCH_EAST:
1343                     GetFramePartInfo (pcd, FRAME_RESIZE_E, 
1344                                       &x, &y, &width, &height);
1345                     break;
1346
1347             case STRETCH_SOUTH_EAST:
1348                     GetFramePartInfo (pcd, FRAME_RESIZE_SE, 
1349                                       &x, &y, &width, &height);
1350                     break;
1351
1352             case STRETCH_SOUTH:
1353                     GetFramePartInfo (pcd, FRAME_RESIZE_S, 
1354                                       &x, &y, &width, &height);
1355                     break;
1356
1357             case STRETCH_SOUTH_WEST:
1358                     GetFramePartInfo (pcd, FRAME_RESIZE_SW, 
1359                                       &x, &y, &width, &height);
1360                     break;
1361
1362             case STRETCH_WEST:
1363                     GetFramePartInfo (pcd, FRAME_RESIZE_W, 
1364                                       &x, &y, &width, &height);
1365                     break;
1366         }
1367
1368         attr_mask = CWCursor;
1369         win_attribs.cursor = wmGD.stretchCursors[iWin];
1370
1371         pcd->clientStretchWin[iWin] = 
1372                     XCreateWindow(DISPLAY, pcd->clientFrameWin,
1373                     x, y, width, height, 0, CopyFromParent,
1374                     InputOnly, CopyFromParent, attr_mask, &win_attribs);
1375     }
1376 } /* END OF FUNCTION  CreateStretcherWindows  */
1377
1378
1379 \f
1380 /*************************************<->*************************************
1381  *
1382  *  CountFrameRectangles (pSD)
1383  *
1384  *
1385  *  Description:
1386  *  -----------
1387  *  Computes the number of top and bottom shadow rectangles to allocate
1388  *  per frame.
1389  *
1390  *  Inputs:
1391  *  ------
1392  *  pWS         - pointer to workspace data
1393  * 
1394  *  Outputs:
1395  *  -------
1396  *
1397  *  Comments:
1398  *  --------
1399  *  
1400  * 
1401  *************************************<->***********************************/
1402
1403 void CountFrameRectangles (WmScreenData *pSD)
1404 {
1405     int i;
1406
1407     pSD->Num_Title_Ts_Elements = pSD->Num_Title_Bs_Elements = 0;
1408
1409     /* count up rectangles for title bar */
1410     for (i = FRAME_SYSTEM; i <= FRAME_MAXIMIZE; i++)
1411     {
1412         pSD->Num_Title_Ts_Elements += ((Bevels[i].top.external * 
1413                                  pSD->externalBevel) +
1414                           (Bevels[i].top.internal * MAX_INTERNAL_BEVEL) +
1415                           (Bevels[i].top.join * pSD->joinBevel));
1416
1417         pSD->Num_Title_Bs_Elements += ((Bevels[i].bottom.external*
1418                                  pSD->externalBevel)+
1419                           (Bevels[i].bottom.internal * MAX_INTERNAL_BEVEL) +
1420                           (Bevels[i].bottom.join * pSD->joinBevel));
1421     }
1422
1423     pSD->Num_Resize_Ts_Elements = pSD->Num_Resize_Bs_Elements = 0;
1424
1425     /* count up rectangles for resize handles*/
1426     for (i = FRAME_RESIZE_NW; i <= FRAME_RESIZE_W; i++)
1427     {
1428         pSD->Num_Resize_Ts_Elements += ((Bevels[i].top.external * 
1429                                    pSD->externalBevel) +
1430                           (Bevels[i].top.internal * MAX_INTERNAL_BEVEL) +
1431                           (Bevels[i].top.join * pSD->joinBevel));
1432
1433         pSD->Num_Resize_Bs_Elements += ((Bevels[i].bottom.external*
1434                                    pSD->externalBevel)+
1435                           (Bevels[i].bottom.internal * MAX_INTERNAL_BEVEL) +
1436                           (Bevels[i].bottom.join * pSD->joinBevel));
1437     }
1438 } /* END OF FUNCTION  CountFrameRectangles  */
1439
1440
1441 \f
1442 /*************************************<->*************************************
1443  *
1444  *  AllocateFrameDisplayLists (pcd)
1445  *
1446  *
1447  *  Description:
1448  *  -----------
1449  *  Allocates memory for the graphic display lists for the frame.
1450  *
1451  *
1452  *  Inputs:
1453  *  ------
1454  *  pcd         - pointer to the client data
1455  *
1456  * 
1457  *  Outputs:
1458  *  -------
1459  *  pcd         - fields modified
1460  *
1461  *  Return      - TRUE if successful, FALSE otherwise.
1462  *
1463  *
1464  *  Comments:
1465  *  --------
1466  *  
1467  * 
1468  *************************************<->***********************************/
1469
1470 Boolean AllocateFrameDisplayLists (ClientData *pcd)
1471 {
1472     int frame_top_count, frame_bottom_count;
1473
1474     /*
1475      *  If the title bar has it's own appearance, then allocate
1476      *  separate display lists for it. 
1477      */
1478     if (DECOUPLE_TITLE_APPEARANCE(pcd) && 
1479         (pcd->decor & MWM_DECOR_TITLE))
1480     {
1481         if (((pcd->pclientTitleTopShadows = 
1482               AllocateRList ((unsigned)NUM_TITLE_TS_ELEMENTS(pcd))) == NULL) ||
1483             ((pcd->pclientTitleBottomShadows = 
1484               AllocateRList ((unsigned)NUM_TITLE_BS_ELEMENTS(pcd))) == NULL))
1485         {
1486             /* out of memory! */
1487             Warning (((char *)GETMESSAGE(8, 1, "Insufficient memory for client window framing")));
1488             return(FALSE);
1489         }
1490
1491         frame_top_count = NUM_RESIZE_TS_ELEMENTS(pcd);
1492         frame_bottom_count = NUM_RESIZE_BS_ELEMENTS(pcd);
1493     }
1494     else
1495     {
1496         frame_top_count = NUM_RESIZE_TS_ELEMENTS(pcd) + 
1497                           NUM_TITLE_TS_ELEMENTS(pcd);
1498         frame_bottom_count = NUM_RESIZE_BS_ELEMENTS(pcd) + 
1499                              NUM_RESIZE_BS_ELEMENTS(pcd);
1500     }
1501
1502     /* 
1503      * Allocate the primary lists for the frame
1504      */
1505     if ( (pcd->pclientTopShadows == NULL) &&
1506          ((pcd->pclientTopShadows = 
1507                  AllocateRList ((unsigned)frame_top_count)) == NULL) )
1508     {
1509         /* out of memory! */
1510         Warning (((char *)GETMESSAGE(8, 2, "Insufficient memory for client window framing")));
1511         return(FALSE);
1512     }
1513
1514     if ( (pcd->pclientBottomShadows == NULL) &&
1515          ((pcd->pclientBottomShadows = 
1516                  AllocateRList ((unsigned)frame_bottom_count)) == NULL) )
1517     {
1518         /* out of memory! */
1519         Warning (((char *)GETMESSAGE(8, 3, "Insufficient memory for client window framing")));
1520         return(FALSE);
1521     }
1522
1523     /*
1524      * Only allocate matte lists if there is a matte.
1525      */
1526     if ( (pcd->matteWidth) &&
1527          (pcd->pclientMatteTopShadows == NULL) &&
1528          ((pcd->pclientMatteTopShadows = 
1529              AllocateRList ((unsigned)NUM_MATTE_TS_RECTS)) == NULL))
1530     {
1531         /* out of memory! */
1532         Warning (((char *)GETMESSAGE(8, 4, "Insufficient memory for client window framing")));
1533         return(FALSE);
1534     }
1535
1536     if ( (pcd->matteWidth) &&
1537          (pcd->pclientMatteBottomShadows == NULL) &&
1538          ((pcd->pclientMatteBottomShadows = 
1539                  AllocateRList ((unsigned)NUM_MATTE_BS_RECTS)) == NULL)) 
1540     {
1541         /* out of memory! */
1542         Warning (((char *)GETMESSAGE(8, 5, "Insufficient memory for client window framing")));
1543         return(FALSE);
1544     }
1545
1546     return(TRUE);
1547 } /* END OF FUNCTION  AllocateFrameDisplayLists  */
1548
1549 \f
1550 /*************************************<->*************************************
1551  *
1552  *  InitClientDecoration (pSD)
1553  *
1554  *
1555  *  Description:
1556  *  -----------
1557  *  Initializes client decoration routines
1558  *
1559  *
1560  *  Inputs:
1561  *  ------
1562  *  pSD         - pointer to screen data
1563  * 
1564  *  Outputs:
1565  *  -------
1566  *
1567  *
1568  *  Comments:
1569  *  --------
1570  *  This must be called once before decorating any client frames.
1571  *************************************<->***********************************/
1572
1573 void InitClientDecoration (WmScreenData *pSD)
1574 {
1575     CountFrameRectangles(pSD);
1576 } /* END OF FUNCTION   InitClientDecoration */
1577
1578
1579 \f
1580 /*************************************<->*************************************
1581  *
1582  *  AllocateGadgetRectangles (pcd)
1583  *
1584  *
1585  *  Description:
1586  *  -----------
1587  *  Allocate the memory for event rectangles structures.
1588  *
1589  *
1590  *  Inputs:
1591  *  ------
1592  *  pcd         - pointer to client data structure
1593  * 
1594  *  Outputs:
1595  *  -------
1596  *  pcd         - modified
1597  *
1598  *
1599  *  Comments:
1600  *  --------
1601  * 
1602  *************************************<->***********************************/
1603
1604 Boolean AllocateGadgetRectangles (ClientData *pcd)
1605 {
1606     int num_rects;
1607     unsigned long decor = pcd->decor;
1608     GadgetRectangle *pgr;
1609     
1610     if (decor & MWM_DECOR_TITLE) {
1611
1612         /* count how many rectangles to allocate for titlebar */
1613         num_rects = 1;          
1614         if (decor & MWM_DECOR_MENU)     num_rects += 1;
1615         if (decor & MWM_DECOR_MINIMIZE) num_rects += 1;
1616         if (decor & MWM_DECOR_MAXIMIZE) num_rects += 1;
1617     
1618         /* allocate memory if no memory is allocated */
1619         if ( pcd->pTitleGadgets == NULL) {
1620             /* allocate memory for these guys */
1621             pgr = (GadgetRectangle *) 
1622                    XtMalloc (num_rects * sizeof(GadgetRectangle));
1623             if (pgr == NULL)
1624             {
1625                 /* out of memory! */
1626                 Warning (((char *)GETMESSAGE(8, 6, "Insufficient memory for client window framing")));
1627                 return (FALSE);
1628             }
1629
1630             /* update client data */
1631             pcd->pTitleGadgets = pgr;
1632             pcd->cTitleGadgets = 0;
1633         }
1634     }
1635
1636     if (decor & MWM_DECOR_RESIZEH) {
1637
1638         /* allocate memory if no memory is allocated */
1639         if ( pcd->pResizeGadgets == NULL) {
1640             /* allocate memory for these guys */
1641             pgr = (GadgetRectangle *) 
1642                   XtMalloc (STRETCH_COUNT * sizeof(GadgetRectangle));
1643             if (pgr == NULL) 
1644             {
1645                 /* out of memory! */
1646                 Warning (((char *)GETMESSAGE(8, 7, "Insufficient memory for client window framing")));
1647                 return (FALSE);
1648             }
1649
1650             /* update client data */
1651             pcd->pResizeGadgets = pgr;
1652         }
1653     }
1654     return(TRUE);
1655 } /* END OF FUNCTION  AllocateGadgetRectangles  */
1656
1657 \f
1658 /*************************************<->*************************************
1659  *
1660  *  ComputeGadgetRectangles (pcd)
1661  *
1662  *
1663  *  Description:
1664  *  -----------
1665  *  Creates the event rectangles structures to aid in identifying
1666  *  frame parts when events come in
1667  *
1668  *
1669  *  Inputs:
1670  *  ------
1671  *  pcd         - pointer to client data structure
1672  * 
1673  *  Outputs:
1674  *  -------
1675  *  pcd         - modified
1676  *
1677  *
1678  *  Comments:
1679  *  --------
1680  *  o assumes gadget rectangles are already allocated.
1681  * 
1682  *************************************<->***********************************/
1683
1684 void ComputeGadgetRectangles (ClientData *pcd)
1685 {
1686     unsigned long decor = pcd->decor;
1687     GadgetRectangle *pgr;
1688     int fpX, fpY;
1689     unsigned int fpWidth, fpHeight;
1690     int igr;
1691     int clientWidth = (pcd->maxConfig) ? pcd->maxWidth : pcd->clientWidth;
1692     
1693
1694     /* title bar */
1695
1696     if (decor & MWM_DECOR_TITLE) {
1697
1698         if ( (pgr = pcd->pTitleGadgets) == NULL) {
1699             return;             /* nothing there !!! */
1700         }
1701
1702         /* do title rectangle */
1703         pcd->titleRectangle.x = pcd->frameInfo.upperBorderWidth;
1704         pcd->titleRectangle.y = pcd->frameInfo.upperBorderWidth;
1705
1706         /*
1707          * Fixed bug where last button in title bar did not activate when
1708          * the client's X border was showing.
1709          */
1710         pcd->titleRectangle.width = clientWidth +
1711           (XBorderIsShowing(pcd) ? 2*pcd->xBorderWidth : 2*pcd->matteWidth);
1712         pcd->titleRectangle.height = pcd->frameInfo.titleBarHeight;
1713
1714         /* fill in title bar rectangles */
1715         igr = 0;
1716
1717         pgr[igr].id = FRAME_TITLE;
1718         GetFramePartInfo (pcd, FRAME_TITLE, &fpX, &fpY, &fpWidth, &fpHeight);
1719
1720         /* copy in and convert to shorts */
1721         pgr[igr].rect.x = fpX;
1722         pgr[igr].rect.y = fpY;
1723         pgr[igr].rect.width = fpWidth;
1724         pgr[igr].rect.height = fpHeight;
1725         igr += 1;
1726
1727         if (decor & MWM_DECOR_MENU) {
1728             pgr[igr].id = FRAME_SYSTEM;
1729             GetFramePartInfo (pcd, FRAME_SYSTEM, &fpX, &fpY, &fpWidth, 
1730                               &fpHeight);
1731
1732             /* copy in and convert to shorts */
1733             pgr[igr].rect.x = fpX;
1734             pgr[igr].rect.y = fpY;
1735             pgr[igr].rect.width = fpWidth;
1736             pgr[igr].rect.height = fpHeight;
1737             igr += 1;
1738         }
1739
1740         if (decor & MWM_DECOR_MINIMIZE) {
1741             pgr[igr].id = FRAME_MINIMIZE;
1742             GetFramePartInfo (pcd, FRAME_MINIMIZE, 
1743                               &fpX, &fpY, &fpWidth, &fpHeight);
1744             /* copy in and convert to shorts */
1745             pgr[igr].rect.x = fpX;
1746             pgr[igr].rect.y = fpY;
1747             pgr[igr].rect.width = fpWidth;
1748             pgr[igr].rect.height = fpHeight;
1749             igr += 1;
1750         }
1751
1752         if (decor & MWM_DECOR_MAXIMIZE) {
1753             pgr[igr].id = FRAME_MAXIMIZE;
1754             GetFramePartInfo (pcd, FRAME_MAXIMIZE, 
1755                               &fpX, &fpY, &fpWidth, &fpHeight);
1756             /* copy in and convert to shorts */
1757             pgr[igr].rect.x = fpX;
1758             pgr[igr].rect.y = fpY;
1759             pgr[igr].rect.width = fpWidth;
1760             pgr[igr].rect.height = fpHeight;
1761             igr += 1;
1762         }
1763
1764         /* update client data */
1765         pcd->pTitleGadgets = pgr;
1766         pcd->cTitleGadgets = igr;
1767     }
1768
1769     /* client matte area (actually base window area) */
1770
1771     if (decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
1772     {
1773         pcd->matteRectangle.x = pcd->frameInfo.lowerBorderWidth;
1774         pcd->matteRectangle.y = pcd->frameInfo.upperBorderWidth + 
1775                                     pcd->frameInfo.titleBarHeight;
1776         pcd->matteRectangle.width = pcd->frameInfo.width - 
1777                                         (2 * pcd->frameInfo.lowerBorderWidth);
1778         pcd->matteRectangle.height = pcd->frameInfo.height - 
1779                                          pcd->frameInfo.upperBorderWidth - 
1780                                          pcd->frameInfo.lowerBorderWidth - 
1781                                          pcd->frameInfo.titleBarHeight;
1782     }
1783     else 
1784     {
1785         pcd->matteRectangle.x = 0;
1786         pcd->matteRectangle.y = pcd->frameInfo.titleBarHeight;
1787         pcd->matteRectangle.width = pcd->frameInfo.width;
1788         pcd->matteRectangle.height = pcd->frameInfo.height - 
1789                                          pcd->frameInfo.titleBarHeight;
1790     }
1791
1792     if (decor & MWM_DECOR_RESIZEH) {
1793
1794         if ( (pgr = pcd->pResizeGadgets) == NULL) {
1795             return;             /* nothing there !!! */
1796         }
1797
1798         /* fill in resize rectangles */
1799         igr = 0;
1800         if (decor & MWM_DECOR_RESIZEH) { 
1801
1802             pgr[igr].id = FRAME_RESIZE_NW;
1803             GetFramePartInfo (pcd, FRAME_RESIZE_NW, 
1804                               &fpX, &fpY, &fpWidth, &fpHeight);
1805             /* copy in and convert to shorts */
1806             pgr[igr].rect.x = fpX;
1807             pgr[igr].rect.y = fpY;
1808             pgr[igr].rect.width = fpWidth;
1809             pgr[igr].rect.height = fpHeight;
1810             igr += 1;
1811
1812             pgr[igr].id = FRAME_RESIZE_N;
1813             GetFramePartInfo (pcd, FRAME_RESIZE_N, 
1814                               &fpX, &fpY, &fpWidth, &fpHeight);
1815             if ((int) fpWidth > 0)  {
1816                 /* copy in and convert to shorts */
1817                 pgr[igr].rect.x = fpX;
1818                 pgr[igr].rect.y = fpY;
1819                 pgr[igr].rect.width = fpWidth;
1820                 pgr[igr].rect.height = fpHeight;
1821                 igr += 1;
1822             }
1823
1824             pgr[igr].id = FRAME_RESIZE_NE;
1825             GetFramePartInfo (pcd, FRAME_RESIZE_NE, 
1826                               &fpX, &fpY, &fpWidth, &fpHeight);
1827             /* copy in and convert to shorts */
1828             pgr[igr].rect.x = fpX;
1829             pgr[igr].rect.y = fpY;
1830             pgr[igr].rect.width = fpWidth;
1831             pgr[igr].rect.height = fpHeight;
1832             igr += 1;
1833
1834             pgr[igr].id = FRAME_RESIZE_W;
1835             GetFramePartInfo (pcd, FRAME_RESIZE_W, 
1836                               &fpX, &fpY, &fpWidth, &fpHeight);
1837             if ((int)fpHeight > 0) {
1838                 /* copy in and convert to shorts */
1839                 pgr[igr].rect.x = fpX;
1840                 pgr[igr].rect.y = fpY;
1841                 pgr[igr].rect.width = fpWidth;
1842                 pgr[igr].rect.height = fpHeight;
1843                 igr += 1;
1844             }
1845
1846             pgr[igr].id = FRAME_RESIZE_E;
1847             GetFramePartInfo (pcd, FRAME_RESIZE_E, 
1848                               &fpX, &fpY, &fpWidth, &fpHeight);
1849             if ((int) fpHeight > 0) {
1850                 /* copy in and convert to shorts */
1851                 pgr[igr].rect.x = fpX;
1852                 pgr[igr].rect.y = fpY;
1853                 pgr[igr].rect.width = fpWidth;
1854                 pgr[igr].rect.height = fpHeight;
1855                 igr += 1;
1856             }
1857
1858             pgr[igr].id = FRAME_RESIZE_SW;
1859             GetFramePartInfo (pcd, FRAME_RESIZE_SW, 
1860                               &fpX, &fpY, &fpWidth, &fpHeight);
1861             /* copy in and convert to shorts */
1862             pgr[igr].rect.x = fpX;
1863             pgr[igr].rect.y = fpY;
1864             pgr[igr].rect.width = fpWidth;
1865             pgr[igr].rect.height = fpHeight;
1866             igr += 1;
1867
1868             pgr[igr].id = FRAME_RESIZE_S;
1869             GetFramePartInfo (pcd, FRAME_RESIZE_S, 
1870                               &fpX, &fpY, &fpWidth, &fpHeight);
1871             if ((int) fpWidth > 0) {
1872                 /* copy in and convert to shorts */
1873                 pgr[igr].rect.x = fpX;
1874                 pgr[igr].rect.y = fpY;
1875                 pgr[igr].rect.width = fpWidth;
1876                 pgr[igr].rect.height = fpHeight;
1877                 igr += 1;
1878             }
1879
1880             pgr[igr].id = FRAME_RESIZE_SE;
1881             GetFramePartInfo (pcd, FRAME_RESIZE_SE, 
1882                               &fpX, &fpY, &fpWidth, &fpHeight);
1883             /* copy in and convert to shorts */
1884             pgr[igr].rect.x = fpX;
1885             pgr[igr].rect.y = fpY;
1886             pgr[igr].rect.width = fpWidth;
1887             pgr[igr].rect.height = fpHeight;
1888         }
1889
1890         /* update client data */
1891         pcd->pResizeGadgets = pgr;
1892     }
1893
1894 } /* END OF FUNCTION  ComputeGadgetRectangles   */
1895
1896
1897 \f
1898 /*************************************<->*************************************
1899  *
1900  *  GetSystemMenuPosition (pcd, px, py, height, context)
1901  *
1902  *
1903  *  Description:
1904  *  -----------
1905  *  Returns the position of where the system menu should be popped up.
1906  *  The hotspotRectangle in global is also set up to match the icon or
1907  *  system menu button area.
1908  *
1909  *
1910  *  Inputs:
1911  *  ------
1912  *  pcd = pointer to client data
1913  *
1914  *  px = pointer to x location
1915  *
1916  *  py = pointer to y location
1917  *
1918  *  height = height of the system menu
1919  *
1920  *  context =  context that the menu is to be posted under.
1921  *
1922  *
1923  *  Outputs:
1924  *  -------
1925  *  *px = x location
1926  *
1927  *  *py = y location
1928  *
1929  *  wmGD.hotspotRectangle = system menu button or icon area (root relative)
1930  *
1931  *************************************<->***********************************/
1932
1933 void GetSystemMenuPosition (ClientData *pcd, int *px, int *py, 
1934                             unsigned int height, Context context)
1935 {
1936
1937     if ((pcd->clientState == MINIMIZED_STATE) ||
1938         ((pcd->clientState != MINIMIZED_STATE) &&
1939          (context == F_SUBCONTEXT_IB_WICON)))
1940     {
1941         /* 
1942          * Try to put the menu directly above the icon.
1943          * If it would hit the top of the screen then try to put it below
1944          *   the icon and label.
1945          * If it would then hit the bottom of the screen turn of the hotspot
1946          *   processing.
1947          */
1948
1949
1950         if (pcd->pSD->useIconBox && P_ICON_BOX(pcd))
1951         {
1952             GetIconBoxIconRootXY (pcd, px, py);
1953
1954             wmGD.hotspotRectangle.x = *px;
1955             wmGD.hotspotRectangle.y = *py;
1956
1957             *py -= height;
1958
1959             if (*py < 0)
1960             {
1961                 *py += height + ICON_HEIGHT(pcd);
1962                 if (*py + height >= DisplayHeight (DISPLAY, 
1963                                                    SCREEN_FOR_CLIENT(pcd)))
1964                 {
1965                     wmGD.checkHotspot = FALSE;
1966                 }
1967             }
1968         }
1969         else
1970         {
1971             *px = ICON_X(pcd);
1972             *py = ICON_Y(pcd) - height;
1973             
1974             if (*py < 0)
1975             {
1976                 *py = ICON_Y(pcd) + ICON_HEIGHT(pcd);
1977                 if (*py + height >= DisplayHeight (DISPLAY, 
1978                                                    SCREEN_FOR_CLIENT(pcd)))
1979                 {
1980                     wmGD.checkHotspot = FALSE;
1981                 }
1982             }
1983             
1984             wmGD.hotspotRectangle.x = ICON_X(pcd);
1985             wmGD.hotspotRectangle.y = ICON_Y(pcd);
1986         }
1987
1988         /* setup the hotspot rectangle data */
1989
1990         wmGD.hotspotRectangle.width = ICON_WIDTH(pcd);
1991         wmGD.hotspotRectangle.height = ICON_HEIGHT(pcd);
1992     }
1993     else
1994     {
1995         /* 
1996          * Try to put the menu directly below the SW corner of the 
1997          *   titlebar/border.
1998          * If it would hit the bottom of the screen then try to put it directly
1999          *   above the NW corner of the titlebar/border.
2000          * If it would then hit the top of the screen turn of the hotspot
2001          *   processing.
2002          */
2003
2004         if ((pcd->decor & MWM_DECOR_TITLE) &&
2005             !(pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)))
2006         {
2007             *px = pcd->frameInfo.x;
2008             *py = pcd->frameInfo.y + pcd->frameInfo.titleBarHeight;
2009         }
2010         else 
2011         {
2012             *px = pcd->frameInfo.x + pcd->frameInfo.lowerBorderWidth;
2013             *py = pcd->frameInfo.y + pcd->frameInfo.upperBorderWidth + 
2014                   pcd->frameInfo.titleBarHeight;
2015         }
2016         if (*py + height >= DisplayHeight (DISPLAY, 
2017                   SCREEN_FOR_CLIENT(pcd)))
2018         {
2019             if ((pcd->decor & MWM_DECOR_TITLE) &&
2020                 !(pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)))
2021             {
2022                 *py = pcd->frameInfo.y - height;
2023             }
2024             else
2025             {
2026                 *py = pcd->frameInfo.y + pcd->frameInfo.upperBorderWidth - 
2027                     height;
2028             }
2029             if (*py < 0)
2030             {
2031                 wmGD.checkHotspot = FALSE;
2032             }
2033         }
2034
2035         /* setup the hotspot rectangle data */
2036
2037         wmGD.hotspotRectangle.x = pcd->frameInfo.x + 
2038                                   pcd->frameInfo.lowerBorderWidth;
2039         wmGD.hotspotRectangle.y = pcd->frameInfo.y + 
2040                                   pcd->frameInfo.upperBorderWidth;
2041
2042             /* assume square button */
2043         wmGD.hotspotRectangle.width = pcd->frameInfo.titleBarHeight;
2044         wmGD.hotspotRectangle.height = pcd->frameInfo.titleBarHeight;
2045     }
2046
2047 } /* END OF FUNCTION GetSystemMenuPosition */
2048
2049
2050 \f
2051 /*************************************<->*************************************
2052  *
2053  *  ShowActiveClientFrame (pcd)
2054  *
2055  *
2056  *  Description:
2057  *  -----------
2058  *  Paint the frame to indicate an "active" window
2059  *
2060  *
2061  *  Inputs:
2062  *  ------
2063  *  pcd         - pointer to client data
2064  *
2065  * 
2066  *  Outputs:
2067  *  -------
2068  *
2069  *
2070  *  Comments:
2071  *  --------
2072  *  o This calls the frame exposure procedure, which gets some GCs based
2073  *    on the current keyboard focus. Thus, wmGD.keyboardFocus == pcd
2074  *    must be TRUE when this is called for the correct highlighting to 
2075  *    occur.
2076  * 
2077  *************************************<->***********************************/
2078
2079 void 
2080 ShowActiveClientFrame (ClientData *pcd)
2081 {
2082     unsigned long attr_mask = 0;
2083     XSetWindowAttributes window_attribs;
2084
2085     if (DECOUPLE_TITLE_APPEARANCE(pcd) && 
2086          (pcd->decor & MWM_DECOR_TITLE))
2087     {
2088         /* 
2089          * Use background pixmap if one is specified, otherwise set the
2090          * appropriate background color. 
2091          */
2092
2093         if (CLIENT_TITLE_APPEARANCE(pcd).activeBackgroundPixmap)
2094             {
2095             attr_mask |= CWBackPixmap;
2096             window_attribs.background_pixmap =
2097                 CLIENT_TITLE_APPEARANCE(pcd).activeBackgroundPixmap;
2098         }
2099         else
2100         {
2101             attr_mask |= CWBackPixel;
2102             window_attribs.background_pixel = 
2103                 CLIENT_TITLE_APPEARANCE(pcd).activeBackground;
2104         }
2105
2106
2107         XChangeWindowAttributes (DISPLAY, pcd->clientTitleWin, attr_mask, 
2108                                  &window_attribs);
2109
2110         /* clear the frame to the right background */
2111         XClearWindow (DISPLAY, pcd->clientTitleWin);
2112     }
2113
2114     /* 
2115      * Use background pixmap if one is specified, otherwise set the
2116      * appropriate background color. 
2117      */
2118
2119     if (CLIENT_APPEARANCE(pcd).activeBackgroundPixmap)
2120     {
2121         attr_mask |= CWBackPixmap;
2122         window_attribs.background_pixmap =
2123                 CLIENT_APPEARANCE(pcd).activeBackgroundPixmap;
2124     }
2125     else
2126     {
2127         attr_mask |= CWBackPixel;
2128         window_attribs.background_pixel = 
2129                 CLIENT_APPEARANCE(pcd).activeBackground;
2130     }
2131
2132
2133     XChangeWindowAttributes (DISPLAY, pcd->clientFrameWin, attr_mask, 
2134                              &window_attribs);
2135
2136     /* clear the frame to the right background */
2137     XClearWindow (DISPLAY, pcd->clientFrameWin);
2138
2139     /* simulate exposure of window */
2140     FrameExposureProc (pcd);
2141
2142
2143 } /* END OF FUNCTION ShowActiveClient */
2144
2145
2146 \f
2147 /*************************************<->*************************************
2148  *
2149  *  ShowInactiveClientFrame (pcd)
2150  *
2151  *
2152  *  Description:
2153  *  -----------
2154  *  Paint the frame to indicate an "inactive" window
2155  *
2156  *
2157  *  Inputs:
2158  *  ------
2159  *  pcd         - pointer to client data
2160  *
2161  * 
2162  *  Outputs:
2163  *  -------
2164  *
2165  *
2166  *  Comments:
2167  *  --------
2168  *  o This calls the frame exposure procedure, which gets some GCs based
2169  *    on the current keyboard focus. Thus, wmGD.keyboardFocus == pcd
2170  *    must be FALSE when this is called for the correct highlighting to 
2171  *    occur.
2172  *  
2173  * 
2174  ******************************<->***********************************/
2175
2176 void 
2177 ShowInactiveClientFrame (ClientData *pcd)
2178 {
2179     unsigned long attr_mask = 0;
2180     XSetWindowAttributes window_attribs;
2181
2182     if (DECOUPLE_TITLE_APPEARANCE(pcd) && 
2183         (pcd->decor & MWM_DECOR_TITLE))
2184     {
2185         /* 
2186          * Use background pixmap if one is specified, otherwise set the
2187          * appropriate background color. 
2188          */
2189
2190         if (CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap)
2191         {
2192             attr_mask |= CWBackPixmap;
2193             window_attribs.background_pixmap =
2194                 CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap;
2195         }
2196         else
2197         {
2198             attr_mask |= CWBackPixel;
2199             window_attribs.background_pixel = 
2200                     CLIENT_TITLE_APPEARANCE(pcd).background;
2201         }
2202
2203
2204         XChangeWindowAttributes (DISPLAY, pcd->clientTitleWin, attr_mask, 
2205                                  &window_attribs);
2206
2207         /* clear the frame to the right background */
2208         XClearWindow (DISPLAY, pcd->clientTitleWin);
2209   
2210         /*
2211          * attr_mask must be cleared because it is set if
2212          * DECOUPLE_TITLE_APPEARANCE(pcd) is true.
2213          */
2214         attr_mask = 0;
2215   
2216     }
2217     /* 
2218      * Use background pixmap if one is specified, otherwise set the
2219      * appropriate background color. 
2220      */
2221
2222     if (CLIENT_APPEARANCE(pcd).backgroundPixmap)
2223     {
2224         attr_mask |= CWBackPixmap;
2225         window_attribs.background_pixmap =
2226             CLIENT_APPEARANCE(pcd).backgroundPixmap;
2227     }
2228     else
2229     {
2230         attr_mask |= CWBackPixel;
2231         window_attribs.background_pixel = 
2232                     CLIENT_APPEARANCE(pcd).background;
2233     }
2234
2235
2236     /* change window attribs so clear does the right thing */
2237     XChangeWindowAttributes (DISPLAY, pcd->clientFrameWin, attr_mask, 
2238                              &window_attribs);
2239
2240     /* clear the frame to the right background */
2241     XClearWindow (DISPLAY, pcd->clientFrameWin);
2242
2243     /* simulate exposure of window */
2244     FrameExposureProc (pcd);
2245
2246 } /* END OF FUNCTION ShowInactiveClientFrame */
2247
2248
2249 \f
2250 /*************************************<->*************************************
2251  *
2252  *  RegenerateClientFrame (pcd)
2253  *
2254  *
2255  *  Description:
2256  *  -----------
2257  *  Reconfigure the sizes of all the components of the client frame
2258  *
2259  *
2260  *  Inputs:
2261  *  ------
2262  *  pcd         - pointer to client data
2263  *
2264  * 
2265  *  Outputs:
2266  *  -------
2267  *
2268  *  Comments:
2269  *  --------
2270  *  
2271  * 
2272  *************************************<->***********************************/
2273
2274 void RegenerateClientFrame (ClientData *pcd)
2275 {
2276     unsigned long decor = pcd->decor;
2277     /* 
2278      * If an embedded client, there is no frame.
2279      */
2280     if (pcd->pECD)
2281     {
2282         if (!pcd->clientFrameWin)
2283         {
2284             return;
2285         }
2286     }
2287
2288     /* recompute frame information */
2289     SetFrameInfo (pcd);
2290
2291     /* move & resize frame window */
2292     XMoveResizeWindow (DISPLAY, pcd->clientFrameWin, pcd->frameInfo.x, 
2293            pcd->frameInfo.y, pcd->frameInfo.width, pcd->frameInfo.height);
2294
2295
2296     /* resize title bar window */
2297     if (decor & MWM_DECOR_TITLE)
2298     {
2299         XResizeWindow (DISPLAY, pcd->clientTitleWin, 
2300            pcd->frameInfo.width - 2*pcd->frameInfo.upperBorderWidth, 
2301            pcd->frameInfo.titleBarHeight);
2302     }
2303
2304     /* resize base window */
2305     XResizeWindow (DISPLAY, pcd->clientBaseWin, BaseWindowWidth (pcd),
2306            BaseWindowHeight (pcd));
2307     
2308     /* resize the stretcher windows */
2309     if (SHOW_RESIZE_CURSORS(pcd) && (decor & MWM_DECOR_RESIZEH)) {
2310         XMoveResizeWindow (DISPLAY, 
2311             pcd->clientStretchWin[STRETCH_NORTH_WEST], 
2312             0, 0, pcd->frameInfo.cornerWidth, 
2313             pcd->frameInfo.cornerHeight);
2314
2315         XMoveResizeWindow (DISPLAY, 
2316             pcd->clientStretchWin[STRETCH_NORTH], 
2317             (int) pcd->frameInfo.cornerWidth, 0, 
2318             pcd->frameInfo.width - 2*pcd->frameInfo.cornerWidth, 
2319             pcd->frameInfo.upperBorderWidth);
2320
2321         XMoveResizeWindow (DISPLAY, 
2322             pcd->clientStretchWin[STRETCH_NORTH_EAST], 
2323             (int) (pcd->frameInfo.width - pcd->frameInfo.cornerWidth), 0, 
2324             pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2325
2326         XMoveResizeWindow (DISPLAY, 
2327             pcd->clientStretchWin[STRETCH_EAST], 
2328             (int) (pcd->frameInfo.width - pcd->frameInfo.lowerBorderWidth),
2329             (int) (pcd->frameInfo.cornerHeight), 
2330             pcd->frameInfo.lowerBorderWidth, 
2331             pcd->frameInfo.height - 2*pcd->frameInfo.cornerHeight);
2332
2333         XMoveResizeWindow (DISPLAY, 
2334             pcd->clientStretchWin[STRETCH_SOUTH_EAST], 
2335             (int) (pcd->frameInfo.width - pcd->frameInfo.cornerWidth),
2336             (int) (pcd->frameInfo.height - pcd->frameInfo.cornerHeight), 
2337             pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2338         
2339         XMoveResizeWindow (DISPLAY, 
2340             pcd->clientStretchWin[STRETCH_SOUTH], 
2341             (int) pcd->frameInfo.cornerWidth,
2342             (int) (pcd->frameInfo.height - pcd->frameInfo.lowerBorderWidth), 
2343             pcd->frameInfo.width - 2*pcd->frameInfo.cornerWidth,
2344             pcd->frameInfo.lowerBorderWidth);
2345
2346         XMoveResizeWindow (DISPLAY, 
2347             pcd->clientStretchWin[STRETCH_SOUTH_WEST], 
2348             0, (int) (pcd->frameInfo.height - pcd->frameInfo.cornerHeight), 
2349             pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2350
2351         XMoveResizeWindow (DISPLAY, 
2352             pcd->clientStretchWin[STRETCH_WEST], 
2353             0, (int) pcd->frameInfo.cornerHeight, 
2354             pcd->frameInfo.lowerBorderWidth,
2355             pcd->frameInfo.height - 2*pcd->frameInfo.cornerHeight);
2356     }
2357
2358     /* recreate gadget rectangles */
2359     ComputeGadgetRectangles (pcd);
2360
2361     /* regenerate the graphics */
2362     GenerateFrameDisplayLists (pcd);
2363
2364 #ifndef NO_SHAPE
2365     if (wmGD.hasShape && pcd->wShaped)
2366     {
2367         SetFrameShape (pcd);
2368     }
2369 #endif /*  NO_SHAPE  */
2370
2371 } /* END OF FUNCTION  RegenerateClientFrame  */
2372
2373
2374
2375 \f
2376 /*************************************<->*************************************
2377  *
2378  *  BevelSystemButton (prTop, prBot, x, y, width, height)
2379  *
2380  *
2381  *  Description:
2382  *  -----------
2383  *  Bevels a rectangle for the system button (drawer handle?)
2384  *
2385  *
2386  *  Inputs:
2387  *  ------
2388  *  prTop       - ptr to top shadow rectangles
2389  *  prBot       - ptr to bottom shadow rectangles
2390  *  x           - x coord of maximize gadget
2391  *  y           - y coord of maximize gadget
2392  *  width       - width of maximize gadget
2393  *  height      - height of maximize gadget
2394  *
2395  * 
2396  *  Outputs:
2397  *  -------
2398  *
2399  *
2400  *  Comments:
2401  *  --------
2402  *  o This draws a horizontal "drawer handle" for the system gadget.
2403  *    Assumptions: the enclosing box is square (width == height)
2404  *************************************<->***********************************/
2405
2406 void BevelSystemButton (RList *prTop, RList *prBot, int x, int y, 
2407                         unsigned int width, unsigned int height)
2408 {
2409     int offset1, offset2;
2410     unsigned int dim1, dim2;
2411
2412     switch (height) {
2413         case 5:
2414         case 6:
2415             offset1 = offset2 = 2;
2416             dim1 = dim2 = height-4;
2417             break;
2418
2419         case 7:
2420             offset1 = offset2 = 2;
2421             dim1 = 3;
2422             dim2 = 2;
2423             break;
2424         
2425         case 8:
2426         case 9:
2427             offset1 = 2;
2428             offset2 = 3;
2429             dim1 = width - 4;
2430             dim2 = height - 6;
2431             break;
2432
2433         case 10:
2434         case 11:
2435             offset1 = 3;
2436             offset2 = 4;
2437             dim1 = width - 6;
2438             dim2 = height - 8;
2439             break;
2440
2441         case 12:
2442         case 13:
2443             offset1 = 3;
2444             offset2 = (height-3)/2;
2445             dim1 = width - 6;
2446             dim2 = 3;
2447             break;
2448
2449         default:
2450             offset1 = 4;
2451             offset2 = (height - 4)/2;
2452             dim1 = width - 8;
2453             dim2 = 4;
2454             break;
2455
2456     }
2457
2458     if (height >= 5) {
2459         /* system icon */
2460         BevelRectangle (prTop, prBot,           /* system icon */
2461                     (x+offset1), (y+offset2),
2462                     dim1, dim2,
2463                     1, 1, 1, 1);
2464         }
2465 } /* END OF FUNCTION  BevelSystemButton   */
2466
2467
2468 \f
2469 /*************************************<->*************************************
2470  *
2471  *  BevelMinimizeButton (prTop, prBot, x, y, height)
2472  *
2473  *
2474  *  Description:
2475  *  -----------
2476  *  Bevels a rectangle for the minimize button
2477  *
2478  *
2479  *  Inputs:
2480  *  ------
2481  *  prTop       - ptr to top shadow rectangles
2482  *  prBot       - ptr to bottom shadow rectangles
2483  *  x           - x coord of maximize gadget
2484  *  y           - y coord of maximize gadget
2485  *  height      - height of maximize gadget
2486  *
2487  * 
2488  *  Outputs:
2489  *  -------
2490  *
2491  *
2492  *  Comments:
2493  *  --------
2494  * 
2495  *************************************<->***********************************/
2496
2497 void BevelMinimizeButton (RList *prTop, RList *prBot, int x, int y, 
2498                           unsigned int height)
2499 {
2500     int offset1, offset2;
2501     unsigned int dim1, dim2;
2502
2503     switch (height) {
2504         case 7:
2505         case 8:
2506         case 9:
2507             offset1 = offset2 = 3;
2508             dim1 = dim2 = height-6;
2509             break;
2510
2511         case 10:
2512         case 11:
2513         case 12:
2514             offset1 = offset2 = (height-3)/2;
2515             dim1 = dim2 = 3;
2516             break;
2517
2518         default:
2519             offset1 = offset2 = (height-4)/2;
2520             dim1 = dim2 = 4;
2521             break;
2522     }
2523
2524     if (height >= 7) {
2525         /* minimize icon */
2526         BevelRectangle (prTop, prBot,
2527                     (x+offset1), (y+offset2),
2528                     dim1, dim2,
2529                     1, 1, 1, 1);
2530     }
2531 } /* END OF FUNCTION  BevelMinimizeButton   */
2532
2533
2534 \f
2535 /*************************************<->*************************************
2536  *
2537  *  BevelMaximizeButton (prTop, prBot, x, y, height)
2538  *
2539  *
2540  *  Description:
2541  *  -----------
2542  *  Bevels a rectangle for the maximize button
2543  *
2544  *
2545  *  Inputs:
2546  *  ------
2547  *  prTop       - ptr to top shadow rectangles
2548  *  prBot       - ptr to bottom shadow rectangles
2549  *  x           - x coord of maximize gadget
2550  *  y           - y coord of maximize gadget
2551  *  height      - height of maximize gadget
2552  *
2553  * 
2554  *  Outputs:
2555  *  -------
2556  *
2557  *
2558  *  Comments:
2559  *  --------
2560  * 
2561  *************************************<->***********************************/
2562
2563 void BevelMaximizeButton (RList *prTop, RList *prBot, int x, int y, 
2564                           unsigned int height)
2565 {
2566     int offset1, offset2;
2567     unsigned int dim1, dim2;
2568
2569     switch (height) {
2570         case 5:
2571         case 6:
2572         case 7:
2573         case 8:
2574         case 9:
2575         case 10:
2576         case 11:
2577             offset1 = offset2 = 2;
2578             dim1 = dim2 = height-4;
2579             break;
2580
2581         case 12:
2582         case 13:
2583         case 14:
2584         case 15:
2585             offset1 = offset2 = 3;
2586             dim1 = dim2 = height-6;
2587             break;
2588
2589         default:
2590             offset1 = offset2 = 4;
2591             dim1 = dim2 = height-8;
2592             break;
2593     }
2594
2595     /* maximize icon */
2596     BevelRectangle (prTop, prBot,
2597                     (x+offset1), (y+offset2),
2598                     dim1, dim2,
2599                     1, 1, 1, 1);
2600 } /* END OF FUNCTION  BevelMaximizeButton   */
2601
2602 \f
2603 /*************************************<->*************************************
2604  *
2605  *  DepressGadget (pcd, gadget, depressed)
2606  *
2607  *
2608  *  Description:
2609  *  -----------
2610  *  Show the gadget in a "depressed" state
2611  *
2612  *
2613  *  Inputs:
2614  *  ------
2615  *  pcd         - pointer to client data
2616  *  gadget      - gadget id
2617  *  depressed   - if True, then gadget is shown depressed, if False it is
2618  *                shown not depressed
2619  *
2620  * 
2621  *  Outputs:
2622  *  -------
2623  *  return      - true if sucessful
2624  *
2625  *
2626  *  Comments:
2627  *  --------
2628  *  o This assumes there is a one-pixel bevel around the gadget.
2629  *  o This only works on title bar gadgets.
2630  * 
2631  *************************************<->***********************************/
2632
2633 Boolean DepressGadget (ClientData *pcd, int gadget, Boolean depressed)
2634 {
2635     int x, y; 
2636     unsigned int width, height, invertWidth;
2637     static RList *pTopRect = NULL; 
2638     static RList *pBotRect = NULL; 
2639     GC topGC, botGC;
2640     Window win;
2641
2642     /* get outside dimensions of box we want */
2643
2644     switch (gadget) {
2645         case FRAME_TITLE:
2646         case FRAME_SYSTEM:
2647         case FRAME_MINIMIZE:
2648         case FRAME_MAXIMIZE:
2649             if (!GetDepressInfo (pcd, gadget, &x, &y, &width, 
2650                                  &height, &invertWidth))
2651                 return(FALSE);
2652             
2653             break;
2654
2655         default:
2656             return(FALSE);      /* do nothing on non-title bar gagdets */
2657     }
2658
2659     if (DECOUPLE_TITLE_APPEARANCE(pcd) && 
2660          (pcd->decor & MWM_DECOR_TITLE))
2661     {
2662         /* adjust position to be relative to titlebar window, not frame */
2663         x -= (short) pcd->frameInfo.upperBorderWidth;
2664         y -= (short) pcd->frameInfo.upperBorderWidth;
2665
2666         /* use "active" GCs if we have keyboard focus */
2667         if (pcd == wmGD.keyboardFocus) {
2668             topGC = CLIENT_TITLE_APPEARANCE(pcd).activeTopShadowGC;
2669             botGC = CLIENT_TITLE_APPEARANCE(pcd).activeBottomShadowGC;
2670         }
2671         else {
2672             topGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveTopShadowGC;
2673             botGC = 
2674                 CLIENT_TITLE_APPEARANCE(pcd).inactiveBottomShadowGC;
2675         }
2676
2677         /* draw into title bar window */
2678         win = pcd->clientTitleWin;
2679     }
2680     else 
2681     {
2682         /* use "active" GCs if we have keyboard focus */
2683         if (pcd == wmGD.keyboardFocus) {
2684             topGC = CLIENT_APPEARANCE(pcd).activeTopShadowGC;
2685             botGC = CLIENT_APPEARANCE(pcd).activeBottomShadowGC;
2686         }
2687         else {
2688             topGC = CLIENT_APPEARANCE(pcd).inactiveTopShadowGC;
2689             botGC = CLIENT_APPEARANCE(pcd).inactiveBottomShadowGC;
2690         }
2691
2692         /* draw into client frame window */
2693         win = pcd->clientFrameWin;
2694     }
2695
2696     /* 
2697      * Bevel a rectangle for the desired button effect 
2698      * Allocate the rectangles if necessary.
2699      */
2700     if ( (pTopRect && pBotRect) ||
2701          ((pTopRect = AllocateRList(2)) &&
2702           (pBotRect = AllocateRList(2))))
2703     {
2704         pTopRect->used = 0;
2705         pBotRect->used = 0;
2706         BevelRectangle (pTopRect, pBotRect, 
2707                     x, y, width, height, 
2708                     invertWidth, invertWidth, 
2709                     invertWidth, invertWidth);
2710     }
2711
2712     /* draw the gadget border to make it look depressed or normal */
2713
2714     if (depressed) {
2715         XFillRectangles (DISPLAY, win, botGC, pTopRect->prect, pTopRect->used);
2716         XFillRectangles (DISPLAY, win, topGC, pBotRect->prect, pBotRect->used);
2717     }
2718     else {
2719         XFillRectangles (DISPLAY, win, topGC, pTopRect->prect, pTopRect->used);
2720         XFillRectangles (DISPLAY, win, botGC, pBotRect->prect, pBotRect->used);
2721     }
2722     return(TRUE);
2723 } /* END OF FUNCTION  DepressGadget   */
2724
2725 \f
2726 /*************************************<->*************************************
2727  *
2728  *  PushGadgetIn (pcd, gadget)
2729  *
2730  *
2731  *  Description:
2732  *  -----------
2733  *  Shows a title bar gadget in a depressed state
2734  *
2735  *
2736  *  Inputs:
2737  *  ------
2738  *  pcd         - pointer to client data
2739  *  gadget      - gadget id
2740  * 
2741  *  Outputs:
2742  *  -------
2743  *
2744  *  Comments:
2745  *  --------
2746  * 
2747  *************************************<->***********************************/
2748
2749 void PushGadgetIn (ClientData *pcd, int gadget)
2750 {
2751     switch (gadget) {
2752         case FRAME_SYSTEM:
2753             pcd->decorFlags |= SYSTEM_DEPRESSED;
2754             break;
2755
2756         case FRAME_TITLE:
2757             pcd->decorFlags |= TITLE_DEPRESSED;
2758             break;
2759
2760         case FRAME_MINIMIZE:
2761             pcd->decorFlags |= MINIMIZE_DEPRESSED;
2762             break;
2763
2764         case FRAME_MAXIMIZE:
2765             pcd->decorFlags |= MAXIMIZE_DEPRESSED;
2766             break;
2767
2768         default:
2769             return;
2770     }
2771     GenerateFrameDisplayLists(pcd);
2772     (void) DepressGadget (pcd, gadget, TRUE);
2773     wmGD.gadgetClient = pcd;
2774     wmGD.gadgetDepressed =  gadget;
2775 } /* END OF FUNCTION  PushGadgetIn   */
2776
2777 \f
2778 /*************************************<->*************************************
2779  *
2780  *  PopGadgetOut (pcd, gadget)
2781  *
2782  *
2783  *  Description:
2784  *  -----------
2785  *  Shows a title bar gadget in a depressed state
2786  *
2787  *
2788  *  Inputs:
2789  *  ------
2790  *  pcd         - pointer to client data
2791  *  gadget      - gadget id
2792  * 
2793  *  Outputs:
2794  *  -------
2795  *
2796  *  Comments:
2797  *  --------
2798  * 
2799  *************************************<->***********************************/
2800
2801 void PopGadgetOut (ClientData *pcd, int gadget)
2802 {
2803     switch (gadget) {
2804         case FRAME_SYSTEM:
2805             pcd->decorFlags &= ~SYSTEM_DEPRESSED;
2806             break;
2807
2808         case FRAME_TITLE:
2809             pcd->decorFlags &= ~TITLE_DEPRESSED;
2810             break;
2811
2812         case FRAME_MINIMIZE:
2813             pcd->decorFlags &= ~MINIMIZE_DEPRESSED;
2814             break;
2815
2816         case FRAME_MAXIMIZE:
2817             pcd->decorFlags &= ~MAXIMIZE_DEPRESSED;
2818             break;
2819
2820         default:
2821             return;
2822     }
2823     GenerateFrameDisplayLists(pcd);
2824     (void) DepressGadget (pcd, gadget, FALSE);
2825     wmGD.gadgetClient    = NULL;
2826     wmGD.gadgetDepressed = 0;
2827 } /* END OF FUNCTION  PopGadgetOut   */
2828
2829 #ifndef NO_SHAPE
2830 \f
2831 /*************************************<->*************************************
2832  *
2833  *  SetFrameShape (pcd)
2834  *
2835  *
2836  *  Description:
2837  *  -----------
2838  *  Shapes the frame and base window to the shape of the client
2839  *  window. Also ors the title window into the shaped frame
2840  *  window if present.
2841  *
2842  *  Inputs:
2843  *  ------
2844  *  pcd         - pointer to client data
2845  * 
2846  *  Outputs:
2847  *  -------
2848  *
2849  *  Comments:
2850  *  --------
2851  *  o currently punt on resize handle around the frame.
2852  *  
2853  *************************************<->***********************************/
2854 void SetFrameShape (ClientData *pcd)
2855 {
2856     /*
2857      * The frame consists of the shape of the contents window offset by
2858      * title_height or'ed with the shape of title window (which is always
2859      * rectangular).
2860      */
2861     int xOffset = 0;
2862     int yOffset = 0;
2863
2864     if (XBorderIsShowing(pcd))
2865     {
2866         xOffset = pcd->xBorderWidth;
2867         yOffset = pcd->xBorderWidth;
2868     }
2869     else if(pcd->matteWidth > 0)
2870     {
2871         xOffset = pcd->matteWidth;
2872         yOffset = pcd->matteWidth;
2873     }
2874
2875     if (pcd->wShaped)
2876     {
2877         /*
2878          * need to do general case
2879          */
2880         XShapeCombineShape (DISPLAY, pcd->clientBaseWin, ShapeBounding,
2881                             xOffset,
2882                             yOffset,
2883                             pcd->client, ShapeBounding,
2884                             ShapeSet);
2885
2886         XShapeCombineShape (DISPLAY, pcd->clientFrameWin, ShapeBounding,
2887                             BaseWindowX (pcd),
2888                             BaseWindowY (pcd),
2889                             pcd->clientBaseWin, ShapeBounding,
2890                             ShapeSet);
2891
2892         if (pcd->decor & MWM_DECOR_TITLE)
2893         {
2894             XShapeCombineShape (DISPLAY, pcd->clientFrameWin, ShapeBounding,
2895                                 pcd->frameInfo.upperBorderWidth,
2896                                 pcd->frameInfo.upperBorderWidth,
2897                                 pcd->clientTitleWin, ShapeBounding,
2898                                 ShapeUnion);
2899         }
2900     }
2901     else
2902     {
2903          (void) XShapeCombineMask (DISPLAY, pcd->clientFrameWin, 
2904                                    ShapeBounding, 0, 0,
2905                                    None, ShapeSet);
2906          (void) XShapeCombineMask (DISPLAY, pcd->clientFrameWin, 
2907                                    ShapeClip, 0, 0,
2908                                    None, ShapeSet);
2909          (void) XShapeCombineMask (DISPLAY, pcd->clientBaseWin, 
2910                                    ShapeBounding, 0, 0,
2911                                    None, ShapeSet);
2912          (void) XShapeCombineMask (DISPLAY, pcd->clientBaseWin, 
2913                                    ShapeClip, 0, 0,
2914                                    None, ShapeSet);
2915     }
2916 } /* END OF FUNCTION  SetFrameShape  */
2917 #endif /* NO_SHAPE */
2918
2919
2920 \f