source: trunk/third/mwm/WmCDecor.c @ 9757

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