2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * (c) Copyright 1989, 1990, 1991, 1992 OPEN SOFTWARE FOUNDATION, INC.
32 static char rcsid[] = "$XConsortium: WmCDecor.c /main/7 1996/06/20 09:38:16 rswiston $"
36 * (c) Copyright 1987,1988,1989,1990,1991,1993 HEWLETT-PACKARD COMPANY */
46 #include <X11/cursorfont.h>
56 * include extern functions
61 #include "WmGraphics.h"
62 #include "WmIconBox.h"
64 #include "WmWinInfo.h"
71 int external; /* bevel from frame to root */
72 int join; /* bevel between frame components */
73 int internal; /* bevel from frame to client */
77 Single_Bevel_Count top;
78 Single_Bevel_Count bottom;
82 * "Worst case" bevel counts for frame pieces: this structure is
83 * indexed by definitions in WmGlobal.h. Edit if they change!
85 * These counts are multiplied by the internal, external,
86 * and join bevel resources to determine the sizes of dynamic
87 * data structures to allocate.
90 static Bevel_Count Bevels[] =
92 { {0, 0, 0}, {0, 0, 0} }, /* FRAME_NONE */
93 { {0, 0, 0}, {0, 0, 0} }, /* FRAME_CLIENT */
94 { {0, 4, 0}, {0, 3, 1} }, /* FRAME_SYSTEM */
95 { {0, 2, 0}, {0, 1, 1} }, /* FRAME_TITLE */
96 { {0, 4, 0}, {0, 3, 1} }, /* FRAME_MINIMIZE */
97 { {0, 4, 0}, {0, 3, 1} }, /* FRAME_MAXIMIZE */
98 { {2, 0, 0}, {0, 2, 2} }, /* FRAME_RESIZE_NW */
99 { {1, 1, 0}, {0, 1, 1} }, /* FRAME_RESIZE_N */
100 { {1, 1, 1}, {1, 1, 1} }, /* FRAME_RESIZE_NE */
101 { {0, 1, 1}, {1, 1, 0} }, /* FRAME_RESIZE_E */
102 { {0, 2, 2}, {2, 0, 0} }, /* FRAME_RESIZE_SE */
103 { {0, 1, 1}, {1, 1, 0} }, /* FRAME_RESIZE_S */
104 { {1, 1, 1}, {1, 1, 1} }, /* FRAME_RESIZE_SW */
105 { {1, 1, 0}, {0, 1, 1} } /* FRAME_RESIZE_W */
113 /*************************************<->*************************************
120 * Build a decorated frame for a client window and reparent the client
121 * window to the frame.
126 * pcd - pointer to client data structure for window
128 * << Need the following member data >>
131 * fields from WM_HINTS property
132 * fields from WM_CLASS property
133 * fields from WM_NORMAL_HINTS property
138 * fields from WM_NAME property
147 * This will create a top level shell (frame), fill in the appropriate
148 * decoration, and reparent the window (in *pcd) to the frame.
150 *************************************<->***********************************/
152 Boolean FrameWindow (ClientData *pcd)
154 if (!ConstructFrame (pcd)) /* window hierarchy for frame */
159 GenerateFrameDisplayLists (pcd); /* graphics for frame decoration */
161 AdoptClient(pcd); /* reparent the window */
164 /* shape the frame */
165 if (wmGD.hasShape && pcd->wShaped)
169 #endif /* NO_SHAPE */
173 } /* END OF FUNCTION FrameWindow */
177 /*************************************<->*************************************
179 * FrameExposureProc (pcd)
184 * Repaint the frame graphics
189 * pcd - pointer to client data
198 * Assumes that the display lists for the frame graphics are already
201 *************************************<->***********************************/
203 void FrameExposureProc (ClientData *pcd)
206 Window win = pcd->clientFrameWin;
208 /* use "active" GCs if we have keyboard focus */
210 if (pcd == wmGD.keyboardFocus) {
211 topGC = CLIENT_APPEARANCE(pcd).activeTopShadowGC;
212 botGC = CLIENT_APPEARANCE(pcd).activeBottomShadowGC;
215 topGC = CLIENT_APPEARANCE(pcd).inactiveTopShadowGC;
216 botGC = CLIENT_APPEARANCE(pcd).inactiveBottomShadowGC;
219 /* draw the frame decoration */
221 if (pcd->pclientTopShadows) {
222 XFillRectangles (DISPLAY,
225 pcd->pclientTopShadows->prect,
226 pcd->pclientTopShadows->used);
229 if (pcd->pclientBottomShadows) {
230 XFillRectangles (DISPLAY,
233 pcd->pclientBottomShadows->prect,
234 pcd->pclientBottomShadows->used);
237 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
238 (pcd->decor & MWM_DECOR_TITLE))
240 if (pcd == wmGD.keyboardFocus) {
241 topGC = CLIENT_TITLE_APPEARANCE(pcd).activeTopShadowGC;
242 botGC = CLIENT_TITLE_APPEARANCE(pcd).activeBottomShadowGC;
245 topGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveTopShadowGC;
246 botGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveBottomShadowGC;
249 if (pcd->pclientTitleTopShadows) {
250 XFillRectangles (DISPLAY,
253 pcd->pclientTitleTopShadows->prect,
254 pcd->pclientTitleTopShadows->used);
257 if (pcd->pclientTitleBottomShadows) {
258 XFillRectangles (DISPLAY,
261 pcd->pclientTitleBottomShadows->prect,
262 pcd->pclientTitleBottomShadows->used);
266 /* draw the title bar text */
267 DrawWindowTitle(pcd, False);
272 /*************************************<->*************************************
274 * BaseWinExposureProc (pcd)
279 * Repaint the beveled matte graphics if any.
284 * pcd - pointer to client data
293 * Assumes that the display lists for the matte graphics are already
296 *************************************<->***********************************/
298 void BaseWinExposureProc (ClientData *pcd)
300 /* bevel the matte (if there is one) */
302 if (pcd->matteWidth > 0) {
304 if (pcd->pclientMatteTopShadows) {
305 XFillRectangles (DISPLAY,
307 pcd->clientMatteTopShadowGC,
308 pcd->pclientMatteTopShadows->prect,
309 pcd->pclientMatteTopShadows->used);
312 if (pcd->pclientMatteBottomShadows) {
313 XFillRectangles (DISPLAY,
315 pcd->clientMatteBottomShadowGC,
316 pcd->pclientMatteBottomShadows->prect,
317 pcd->pclientMatteBottomShadows->used);
324 /*************************************<->*************************************
326 * ConstructFrame (pcd)
331 * Construct the window hierarchy for the frame
336 * pcd - pointer to client data record
346 *************************************<->***********************************/
348 Boolean ConstructFrame (ClientData *pcd)
350 unsigned long decoration = pcd->decor;
351 unsigned int wclass; /* window class */
352 unsigned long attr_mask;
353 XSetWindowAttributes window_attribs;
356 /* set frame information */
360 if (!AllocateFrameDisplayLists(pcd)) {
364 /* create frame window */
366 attr_mask = CWEventMask;
367 window_attribs.event_mask = (ButtonPressMask | ButtonReleaseMask |
368 SELECT_BUTTON_MOTION_MASK |
369 DMANIP_BUTTON_MOTION_MASK |
372 if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER) ||
373 (wmGD.colormapFocusPolicy == CMAP_FOCUS_POINTER))
375 window_attribs.event_mask |= EnterWindowMask | LeaveWindowMask;
379 * Use background pixmap if one is specified, otherwise set the
380 * appropriate background color.
383 if (CLIENT_APPEARANCE(pcd).backgroundPixmap)
385 attr_mask |= CWBackPixmap;
386 window_attribs.background_pixmap =
387 CLIENT_APPEARANCE(pcd).backgroundPixmap;
391 attr_mask |= CWBackPixel;
392 window_attribs.background_pixel = CLIENT_APPEARANCE(pcd).background;
395 attr_mask |= CWCursor;
396 window_attribs.cursor = wmGD.workspaceCursor;
398 frmY = pcd->frameInfo.y;
399 frmX = pcd->frameInfo.x;
401 if (CLIENT_APPEARANCE(pcd).saveUnder &&
402 WmGetWindowAttributes (pcd->client) &&
403 wmGD.windowAttributes.save_under)
405 attr_mask |= CWSaveUnder;
406 window_attribs.save_under = True;
409 pcd->clientFrameWin = XCreateWindow(DISPLAY,
411 SCREEN_FOR_CLIENT(pcd)),
414 pcd->frameInfo.width,
415 pcd->frameInfo.height, 0,
416 CopyFromParent,InputOutput,CopyFromParent,
417 attr_mask, &window_attribs);
419 /* create resizing windows with cursors*/
420 if (SHOW_RESIZE_CURSORS(pcd) && (decoration & MWM_DECOR_RESIZEH)) {
421 CreateStretcherWindows (pcd);
425 * Create title bar window. If the title bar has its own appearance,
426 * or if there is no border around the client area,
427 * then we need to create an input/output window to draw in. Otherwise
428 * we can use an input-only window (to clip the corner resize windows).
430 if (decoration & MWM_DECOR_TITLE) {
432 attr_mask = CWCursor;
433 window_attribs.cursor = wmGD.workspaceCursor;
435 if (DECOUPLE_TITLE_APPEARANCE(pcd))
437 /* title bar has a different appearance than rest of frame */
438 wclass = InputOutput;
440 /* need to handle exposure events */
441 attr_mask |= CWEventMask;
442 window_attribs.event_mask = ExposureMask;
445 * Use background pixmap if one is specified, otherwise set the
446 * appropriate background color.
449 if (CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap)
451 attr_mask |= CWBackPixmap;
452 window_attribs.background_pixmap =
453 CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap;
457 attr_mask |= CWBackPixel;
458 window_attribs.background_pixel =
459 CLIENT_TITLE_APPEARANCE(pcd).background;
464 /* title bar has same appearance as rest of frame */
468 pcd->clientTitleWin = XCreateWindow(DISPLAY, pcd->clientFrameWin,
469 (int) pcd->frameInfo.upperBorderWidth,
470 (int) pcd->frameInfo.upperBorderWidth,
471 pcd->frameInfo.width -
472 2*pcd->frameInfo.upperBorderWidth,
473 pcd->frameInfo.titleBarHeight,
475 CopyFromParent,wclass,CopyFromParent,
476 attr_mask, &window_attribs);
479 /* generate gadget position search structure */
480 if (!AllocateGadgetRectangles (pcd))
482 ComputeGadgetRectangles (pcd);
486 * Create base window for reparenting. Save rectangle data for use
487 * in event dispatching.
490 window_attribs.event_mask = (SubstructureRedirectMask |
491 SubstructureNotifyMask |
493 if (pcd->matteWidth > 0)
495 window_attribs.event_mask |= ExposureMask;
496 window_attribs.background_pixel = pcd->matteBackground;
500 window_attribs.background_pixel =
501 CLIENT_TITLE_APPEARANCE(pcd).background;
504 attr_mask = CWBackPixel | CWEventMask;
506 pcd->clientBaseWin = XCreateWindow(DISPLAY, pcd->clientFrameWin,
509 BaseWindowWidth (pcd),
510 BaseWindowHeight (pcd),
512 CopyFromParent,InputOutput,CopyFromParent,
513 attr_mask, &window_attribs);
515 /* map all subwindows of client frame */
517 XMapSubwindows(DISPLAY, pcd->clientFrameWin);
524 /*************************************<->*************************************
526 * GenerateFrameDisplayLists (pcd)
531 * Set up the graphic decorations for the frame
536 * pcd - pointer to client data record
546 * o This must be called after ConstructFrame to insure that the memory
547 * for the rectangles has been allocated.
548 * o If cnum values for StretcherCorner change, also change
549 * StretcherCorner() in WmGraphics.c
550 * o The variable internalBevel sets the depth of shadowing from the
551 * frame to the client area.
552 * o The variable insideBevel is used to decide how deep the bevel is
553 * immediately inside the frame. This may not be internalBevel if
554 * there's a matte, for example.
555 * o The variable diffBevel stores the difference between insideBevel
556 * and what's needed so the bottom of the title bar is correctly
557 * beveled down to the client.
559 *************************************<->***********************************/
561 void GenerateFrameDisplayLists (ClientData *pcd)
563 unsigned long decoration = pcd->decor;
564 int matte_width = pcd->matteWidth;
566 int insideBevel, inset, diffBevel;
567 unsigned int nTitleBevel, sTitleBevel, eTitleBevel, wTitleBevel;
568 unsigned int meTitleBevel, inWidth;
569 int x, y, xAdj, yAdj;
570 unsigned int width, height;
571 RList *prlTop, *prlBot;
576 /* zero out part counts */
578 if (pcd->pclientTopShadows)
579 pcd->pclientTopShadows->used = 0;
580 if (pcd->pclientBottomShadows)
581 pcd->pclientBottomShadows->used = 0;
583 if (pcd->pclientTitleTopShadows)
584 pcd->pclientTitleTopShadows->used = 0;
585 if (pcd->pclientTitleBottomShadows)
586 pcd->pclientTitleBottomShadows->used = 0;
588 if (pcd->pclientMatteTopShadows)
589 pcd->pclientMatteTopShadows->used = 0;
590 if (pcd->pclientMatteBottomShadows)
591 pcd->pclientMatteBottomShadows->used = 0;
593 /* adjust inside bevel of gadgetry if there's a matte */
594 if ((wmGD.frameStyle == WmRECESSED) && (matte_width > 0))
595 insideBevel = JOIN_BEVEL(pcd);
597 insideBevel = pcd->internalBevel;
599 diffBevel = insideBevel - 1;
601 if (decoration & MWM_DECOR_RESIZEH)
603 /* adjust part width/heights if no title bar */
604 if ((pcd->internalBevel > 1) && !(decoration & MWM_DECOR_TITLE))
614 * Draw the stretchers. If the horizontal or vertical pieces
615 * get "too small", then don't draw them at all.
617 GetFramePartInfo (pcd, FRAME_RESIZE_NW, &x, &y, &width, &height);
618 StretcherCorner (pcd->pclientTopShadows, /* NW */
619 pcd->pclientBottomShadows,
622 pcd->frameInfo.upperBorderWidth - inset,
625 GetFramePartInfo (pcd, FRAME_RESIZE_N, &x, &y, &width, &height);
627 BevelRectangle (pcd->pclientTopShadows, /* N */
628 pcd->pclientBottomShadows,
630 width, height - inset,
631 2, 1, ((wmGD.frameStyle == WmSLAB) ? 0 : 1), 1);
633 GetFramePartInfo (pcd, FRAME_RESIZE_NE, &x, &y, &width, &height);
634 StretcherCorner (pcd->pclientTopShadows,
635 pcd->pclientBottomShadows,
638 pcd->frameInfo.upperBorderWidth - inset, width, height);
640 GetFramePartInfo (pcd, FRAME_RESIZE_E, &x, &y, &width, &height);
642 BevelRectangle (pcd->pclientTopShadows, /* E */
643 pcd->pclientBottomShadows,
645 width-diffBevel, height,
646 1, 2, 1, ((wmGD.frameStyle == WmSLAB) ? 0 : 1));
648 GetFramePartInfo (pcd, FRAME_RESIZE_SE, &x, &y, &width, &height);
649 StretcherCorner (pcd->pclientTopShadows, /* SE */
650 pcd->pclientBottomShadows,
653 pcd->frameInfo.upperBorderWidth-inset, width, height);
655 GetFramePartInfo (pcd, FRAME_RESIZE_S, &x, &y, &width, &height);
657 BevelRectangle (pcd->pclientTopShadows, /* S */
658 pcd->pclientBottomShadows,
660 width, height-diffBevel,
661 ((wmGD.frameStyle == WmSLAB) ? 0 : 1), 1, 2, 1);
663 GetFramePartInfo (pcd, FRAME_RESIZE_SW, &x, &y, &width, &height);
664 StretcherCorner (pcd->pclientTopShadows, /* SW */
665 pcd->pclientBottomShadows,
668 pcd->frameInfo.upperBorderWidth-inset, width, height);
670 GetFramePartInfo (pcd, FRAME_RESIZE_W, &x, &y, &width, &height);
671 if ((int) height > 0)
672 BevelRectangle (pcd->pclientTopShadows, /* W */
673 pcd->pclientBottomShadows,
675 width-diffBevel, height,
676 1, ((wmGD.frameStyle == WmSLAB) ? 0 : 1), 1, 2);
681 * Draw second inside bevel level. This goes just around the
682 * client area under the title bar.
684 BevelRectangle (pcd->pclientBottomShadows, /* inside */
685 pcd->pclientTopShadows,
686 (int) (pcd->frameInfo.lowerBorderWidth-diffBevel),
687 (int) (pcd->clientOffset.y - diffBevel),
688 pcd->frameInfo.width -
689 2*pcd->frameInfo.lowerBorderWidth +
691 pcd->frameInfo.height - pcd->clientOffset.y -
692 pcd->frameInfo.lowerBorderWidth +
694 (unsigned int) diffBevel, (unsigned int) diffBevel,
695 (unsigned int) diffBevel, (unsigned int) diffBevel);
698 else if (decoration & MWM_DECOR_BORDER)
701 /* produce default border with no resizing functions */
704 BevelRectangle (pcd->pclientTopShadows, /* outside */
705 pcd->pclientBottomShadows,
707 pcd->frameInfo.width, pcd->frameInfo.height,
708 FRAME_EXTERNAL_SHADOW_WIDTH,
709 FRAME_EXTERNAL_SHADOW_WIDTH,
710 FRAME_EXTERNAL_SHADOW_WIDTH,
711 FRAME_EXTERNAL_SHADOW_WIDTH);
713 BevelRectangle (pcd->pclientTopShadows, /* outside */
714 pcd->pclientBottomShadows,
716 pcd->frameInfo.width, pcd->frameInfo.height,
720 if ((pcd->internalBevel > 1) &&
722 (decoration & MWM_DECOR_TITLE)) {
724 * Need to do special beveling around the inside of the
725 * client area separately from around title area.
727 GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height);
728 inset = 1 + (pcd->frameInfo.lowerBorderWidth -
729 pcd->frameInfo.upperBorderWidth);
730 BevelRectangle (pcd->pclientBottomShadows,
731 pcd->pclientTopShadows,
732 (int) (pcd->frameInfo.lowerBorderWidth-inset),
733 (int) (pcd->frameInfo.lowerBorderWidth-inset),
734 pcd->frameInfo.width -
735 2*pcd->frameInfo.lowerBorderWidth + 2*inset,
736 pcd->frameInfo.height -
737 2*pcd->frameInfo.lowerBorderWidth + 2*inset,
740 BevelRectangle (pcd->pclientBottomShadows, /* inside */
741 pcd->pclientTopShadows,
742 (int) (pcd->frameInfo.lowerBorderWidth-diffBevel),
743 pcd->clientOffset.y - diffBevel,
744 pcd->frameInfo.width -
745 2*pcd->frameInfo.lowerBorderWidth +
747 pcd->frameInfo.height - pcd->clientOffset.y -
748 pcd->frameInfo.lowerBorderWidth + 2*diffBevel,
749 (unsigned int)diffBevel, (unsigned int)diffBevel,
750 (unsigned int)diffBevel, (unsigned int)diffBevel);
755 if((pcd->dtwmBehaviors & DtWM_BEHAVIOR_PANEL) &&
756 (pcd->clientDecoration == WM_DECOR_BORDER))
760 #endif /* PANELIST */
761 BevelRectangle (pcd->pclientBottomShadows, /* inside */
762 pcd->pclientTopShadows,
763 (int)(pcd->frameInfo.lowerBorderWidth-insideBevel),
764 (int)(pcd->frameInfo.lowerBorderWidth-insideBevel),
765 pcd->frameInfo.width -
766 2*pcd->frameInfo.lowerBorderWidth +
768 pcd->frameInfo.height -
769 2*pcd->frameInfo.lowerBorderWidth +
771 (unsigned int)insideBevel,
772 (unsigned int)insideBevel,
773 (unsigned int)insideBevel,
774 (unsigned int)insideBevel);
782 * set bevels for title bar and parts
784 if (decoration & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
786 nTitleBevel = JOIN_BEVEL(pcd); /* north side of title */
787 if (wmGD.frameStyle == WmSLAB)
789 sTitleBevel = JOIN_BEVEL(pcd); /* south side of title */
793 sTitleBevel = insideBevel; /* south side of title */
795 eTitleBevel = JOIN_BEVEL(pcd); /* east side of title */
796 wTitleBevel = JOIN_BEVEL(pcd); /* west side of title */
797 meTitleBevel = JOIN_BEVEL(pcd); /* btw Minimize, Maximize */
801 /* borderless window */
803 nTitleBevel = EXTERNAL_BEVEL(pcd);
804 if (wmGD.frameStyle == WmSLAB)
806 sTitleBevel = (matte_width > 0) ? JOIN_BEVEL(pcd) :
811 sTitleBevel = (matte_width > 0) ? insideBevel : EXTERNAL_BEVEL(pcd);
813 eTitleBevel = (decoration & (MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE))?
814 JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
815 wTitleBevel = (decoration & MWM_DECOR_MENU) ?
816 JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
818 /* beveling east of minimize */
819 meTitleBevel = (decoration & (MWM_DECOR_MAXIMIZE)) ?
820 JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
824 if (decoration & MWM_DECOR_TITLE)
827 * Use a different set of rectangles if title appearance
828 * is different from the rest of the frame.
830 if (DECOUPLE_TITLE_APPEARANCE(pcd))
832 prlTop = pcd->pclientTitleTopShadows;
833 prlBot = pcd->pclientTitleBottomShadows;
834 xAdj = yAdj = pcd->frameInfo.upperBorderWidth;
838 prlTop = pcd->pclientTopShadows;
839 prlBot = pcd->pclientBottomShadows;
844 GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height);
845 if (pcd->decorFlags & TITLE_DEPRESSED) {
846 /* show depressed title gadget */
847 GetDepressInfo (pcd, FRAME_TITLE, &jX, &jY, &jW, &jH,
849 BevelDepressedRectangle (prlTop, prlBot,
850 x-xAdj, y-yAdj, width, height,
851 nTitleBevel, eTitleBevel,
852 sTitleBevel, wTitleBevel, inWidth);
855 /* show normal title gadget */
856 BevelRectangle (prlTop, prlBot,
857 x-xAdj, y-yAdj, width, height,
858 nTitleBevel, eTitleBevel,
859 sTitleBevel, wTitleBevel);
863 if (decoration & MWM_DECOR_MENU) {
865 GetFramePartInfo (pcd, FRAME_SYSTEM, &x, &y, &width, &height);
866 if (pcd->decorFlags & SYSTEM_DEPRESSED) {
867 /* show depressed system gadget */
868 GetDepressInfo (pcd, FRAME_SYSTEM, &jX, &jY, &jW, &jH,
870 BevelDepressedRectangle (prlTop, prlBot,
871 x-xAdj, y-yAdj, width, height,
872 nTitleBevel, wTitleBevel,
873 sTitleBevel, nTitleBevel, inWidth);
877 /* show normal system gadget */
878 BevelRectangle (prlTop, prlBot,
879 x-xAdj, y-yAdj, width, height,
880 nTitleBevel, wTitleBevel,
881 sTitleBevel, nTitleBevel);
886 BevelSystemButton (prlTop, prlBot,
887 x-xAdj, y-yAdj, width, height);
890 if (decoration & MWM_DECOR_MINIMIZE) {
891 GetFramePartInfo (pcd, FRAME_MINIMIZE, &x, &y, &width, &height);
893 if (pcd->decorFlags & MINIMIZE_DEPRESSED) {
894 /* show depressed minimize gadget */
895 GetDepressInfo (pcd, FRAME_MINIMIZE, &jX, &jY, &jW, &jH,
897 BevelDepressedRectangle (prlTop, prlBot,
898 x-xAdj, y-yAdj, width, height,
899 nTitleBevel, meTitleBevel,
900 sTitleBevel, eTitleBevel, inWidth);
903 /* show normal minimize gadget */
904 BevelRectangle (prlTop, prlBot,
905 x-xAdj, y-yAdj, width, height,
906 nTitleBevel, meTitleBevel,
907 sTitleBevel, eTitleBevel);
911 BevelMinimizeButton(prlTop, /* minimize icon */
913 x-xAdj, y-yAdj, height);
916 if (decoration & MWM_DECOR_MAXIMIZE) {
917 GetFramePartInfo (pcd, FRAME_MAXIMIZE, &x, &y, &width, &height);
920 if (pcd->decorFlags & MAXIMIZE_DEPRESSED) {
921 /* show depressed maximize gadget */
922 GetDepressInfo (pcd, FRAME_MAXIMIZE, &jX, &jY, &jW, &jH,
924 BevelDepressedRectangle (prlTop, prlBot,
925 x-xAdj, y-yAdj, width, height,
926 nTitleBevel, nTitleBevel,
927 sTitleBevel, eTitleBevel, inWidth);
930 /* show normal maximize gadget */
931 BevelRectangle (prlTop, prlBot,
932 x-xAdj, y-yAdj, width, height,
933 nTitleBevel, nTitleBevel,
934 sTitleBevel, eTitleBevel);
937 /* maximize icon - in or out depending on client state */
938 if (pcd->maxConfig) {
939 BevelMaximizeButton(prlBot,
941 x-xAdj, y-yAdj, height);
944 BevelMaximizeButton(prlTop,
946 x-xAdj, y-yAdj, height);
951 /* draw the client matte (this is in the base window!!!) */
953 if (matte_width > 0) {
954 unsigned int mWidth, mHeight, exMatteBevel, tMatteBevel;
956 mWidth = BaseWindowWidth (pcd);
957 mHeight = BaseWindowHeight (pcd);
959 if (decoration & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
961 exMatteBevel = JOIN_BEVEL(pcd);
962 tMatteBevel = JOIN_BEVEL(pcd);
966 exMatteBevel = EXTERNAL_BEVEL(pcd);
967 tMatteBevel = (decoration & MWM_DECOR_TITLE) ?
968 JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
971 /* set up beveling around the edges */
973 BevelRectangle (pcd->pclientMatteTopShadows,
974 pcd->pclientMatteBottomShadows,
979 tMatteBevel, exMatteBevel,
980 exMatteBevel, exMatteBevel);
982 /* reversed beveling on inside rectange ! */
984 BevelRectangle ( pcd->pclientMatteBottomShadows,
985 pcd->pclientMatteTopShadows,
986 matte_width - pcd->internalBevel,
987 matte_width - pcd->internalBevel,
988 mWidth - 2*matte_width + 2*pcd->internalBevel,
989 mHeight - 2*matte_width + 2*pcd->internalBevel,
990 (unsigned int) pcd->internalBevel,
991 (unsigned int) pcd->internalBevel,
992 (unsigned int) pcd->internalBevel,
993 (unsigned int) pcd->internalBevel);
998 /*************************************<->*************************************
1005 * Reparent the client window to the window frame
1010 * pcd - pointer to client data record
1021 *************************************<->***********************************/
1023 void AdoptClient (ClientData *pcd)
1025 XWindowChanges windowChanges;
1028 /* Put the window in the window manager's save set */
1030 if (!(pcd->clientFlags & CLIENT_WM_CLIENTS))
1032 XChangeSaveSet (DISPLAY, pcd->client, SetModeInsert);
1033 pcd->clientFlags |= CLIENT_IN_SAVE_SET;
1037 * set window geometry to be consistent with what we believe
1039 mask = CWWidth | CWHeight;
1040 windowChanges.width = pcd->clientWidth;
1041 windowChanges.height = pcd->clientHeight;
1044 * strip off previous window border if we're adding our own border
1047 if ( (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)) ||
1048 (pcd->matteWidth > 0) )
1050 mask |= CWBorderWidth;
1051 windowChanges.border_width = 0;
1054 XConfigureWindow (DISPLAY, pcd->client, mask, &windowChanges);
1057 /* shape our frame to match that of the client's window */
1060 int xws, yws, xbs, ybs;
1061 unsigned wws, hws, wbs, hbs;
1062 int boundingShaped, clipShaped;
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;
1070 #endif /* NO_SHAPE */
1071 /* reparent the window to the base window */
1073 XReparentWindow (DISPLAY, pcd->client, pcd->clientBaseWin,
1076 pcd->clientFlags |= CLIENT_REPARENTED;
1078 } /* END OF FUNCTION AdoptClient */
1082 /*************************************<->*************************************
1084 * GetTextBox (pcd, pBox)
1089 * Gets the rectangle that the text should fit into in the title bar
1094 * pcd - pointer to client data
1095 * pBox - pointer to an XRectangle structure that gets return data
1099 * pBox - data is returned here
1104 *************************************<->***********************************/
1106 void GetTextBox (ClientData *pcd, XRectangle *pBox)
1109 unsigned int width,height;
1111 Dimension textWidth;
1113 XmFontList fontList;
1116 /* get size of title area */
1118 if (!GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height))
1120 /* no title area !!! */
1128 /* adjust for shadowing and allow for some padding around the edges */
1129 x += WM_TOP_TITLE_SHADOW + WM_TOP_TITLE_PADDING;
1130 y += WM_TOP_TITLE_SHADOW + WM_TOP_TITLE_PADDING;
1132 width -= WM_TOP_TITLE_SHADOW + WM_BOTTOM_TITLE_SHADOW +
1133 WM_TOP_TITLE_PADDING + WM_BOTTOM_TITLE_PADDING;
1134 height -= WM_TOP_TITLE_SHADOW + WM_BOTTOM_TITLE_SHADOW +
1135 WM_TOP_TITLE_PADDING + WM_BOTTOM_TITLE_PADDING;
1137 #ifdef DT_LEFT_JUSTIFIED_TITLE
1138 if (wmGD.frameStyle == WmSLAB)
1141 * We left justify the title in this style.
1142 * To keep it a little neat, we offset the title from
1143 * the left edge just a little (half the title height).
1144 * See if we have room to do this.
1146 if (DECOUPLE_TITLE_APPEARANCE(pcd))
1147 fontList = CLIENT_TITLE_APPEARANCE(pcd).fontList;
1149 fontList = CLIENT_APPEARANCE(pcd).fontList;
1150 textWidth = XmStringWidth(fontList, pcd->clientTitle);
1152 offset = TitleBarHeight(pcd)/2;
1154 if ((textWidth + offset) <= width)
1156 /* We have plenty of room, do the offset */
1160 else if ((short) (width - textWidth) > 0)
1162 /* We don't have enough room to do our usual offset,
1163 * but if we reduce the offset, the text won't get
1166 offset = (width - textWidth) / 2;
1172 #endif /* DT_LEFT_JUSTIFIED_TITLE */
1173 /* return position and size */
1176 pBox->width = width;
1177 pBox->height = height;
1184 /*************************************<->*************************************
1186 * DrawWindowTitle (pcd, eraseFirst)
1191 * Overwrites or replaces the client's title text in the
1192 * title bar of the frame.
1197 * pcd - pointer to client data
1198 * eraseFirst - if true, then the old title is erased first
1206 * o Assumes 8-bit text for now.
1209 *************************************<->***********************************/
1211 void DrawWindowTitle (ClientData *pcd, Boolean eraseFirst)
1214 unsigned long decoration = pcd->decor;
1217 XmFontList fontList;
1219 /* make sure there is a title bar first */
1220 if (!(decoration & MWM_DECOR_TITLE))
1223 if (DECOUPLE_TITLE_APPEARANCE(pcd))
1225 /* use "active" GC if we have keyboard focus */
1226 if (pcd == wmGD.keyboardFocus) {
1227 clientGC = CLIENT_TITLE_APPEARANCE(pcd).activeGC;
1230 clientGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveGC;
1233 /* get the area that the text must fit in */
1234 GetTextBox (pcd, &textBox);
1236 /* adjust position to be relative to titlebar window, not frame */
1237 textBox.x -= (short) pcd->frameInfo.upperBorderWidth;
1238 textBox.y -= (short) pcd->frameInfo.upperBorderWidth;
1240 win = pcd->clientTitleWin;
1241 fontList = CLIENT_TITLE_APPEARANCE(pcd).fontList;
1245 /* use "active" GC if we have keyboard focus */
1246 if (pcd == wmGD.keyboardFocus) {
1247 clientGC = CLIENT_APPEARANCE(pcd).activeGC;
1250 clientGC = CLIENT_APPEARANCE(pcd).inactiveGC;
1253 /* get the area that the text must fit in */
1254 GetTextBox (pcd, &textBox);
1255 win = pcd->clientFrameWin;
1256 fontList = CLIENT_APPEARANCE(pcd).fontList;
1261 XClearArea (DISPLAY, win, textBox.x, textBox.y,
1262 (unsigned int) textBox.width, (unsigned int) textBox.height,
1266 #ifdef DT_LEFT_JUSTIFIED_TITLE
1267 WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1268 textBox.x, textBox.y, textBox.width, &textBox,
1269 ((wmGD.frameStyle == WmSLAB) ? False : True));
1270 #else /* DT_LEFT_JUSTIFIED_TITLE */
1272 WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1273 textBox.x, textBox.y, textBox.width, &textBox,
1276 WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1277 textBox.x, textBox.y, textBox.width, &textBox);
1279 #endif /* DT_LEFT_JUSTIFIED_TITLE */
1283 } /* END OF FUNCTION DrawWindowTitle */
1287 /*************************************<->*************************************
1289 * CreateStretcherWindows (pcd)
1294 * Create the input-only windows that overlay the resize gadgets.
1299 * pcd - pointer to client data.
1311 * o The windows are sized based upon resizeBorderWidth
1312 * o This should be called before creating the title bar,
1313 * and reparenting window. Later windows should obscure parts of the
1315 * o The stretchers are given special cursors.
1317 *************************************<->***********************************/
1319 void CreateStretcherWindows (ClientData *pcd)
1323 unsigned int width, height;
1324 XSetWindowAttributes win_attribs;
1325 unsigned long attr_mask;
1327 for (iWin = 0; iWin < STRETCH_COUNT; iWin++) {
1329 case STRETCH_NORTH_WEST:
1330 GetFramePartInfo (pcd, FRAME_RESIZE_NW,
1331 &x, &y, &width, &height);
1335 GetFramePartInfo (pcd, FRAME_RESIZE_N,
1336 &x, &y, &width, &height);
1339 case STRETCH_NORTH_EAST:
1340 GetFramePartInfo (pcd, FRAME_RESIZE_NE,
1341 &x, &y, &width, &height);
1345 GetFramePartInfo (pcd, FRAME_RESIZE_E,
1346 &x, &y, &width, &height);
1349 case STRETCH_SOUTH_EAST:
1350 GetFramePartInfo (pcd, FRAME_RESIZE_SE,
1351 &x, &y, &width, &height);
1355 GetFramePartInfo (pcd, FRAME_RESIZE_S,
1356 &x, &y, &width, &height);
1359 case STRETCH_SOUTH_WEST:
1360 GetFramePartInfo (pcd, FRAME_RESIZE_SW,
1361 &x, &y, &width, &height);
1365 GetFramePartInfo (pcd, FRAME_RESIZE_W,
1366 &x, &y, &width, &height);
1370 attr_mask = CWCursor;
1371 win_attribs.cursor = wmGD.stretchCursors[iWin];
1373 pcd->clientStretchWin[iWin] =
1374 XCreateWindow(DISPLAY, pcd->clientFrameWin,
1375 x, y, width, height, 0, CopyFromParent,
1376 InputOnly, CopyFromParent, attr_mask, &win_attribs);
1378 } /* END OF FUNCTION CreateStretcherWindows */
1382 /*************************************<->*************************************
1384 * CountFrameRectangles (pSD)
1389 * Computes the number of top and bottom shadow rectangles to allocate
1394 * pWS - pointer to workspace data
1403 *************************************<->***********************************/
1405 void CountFrameRectangles (WmScreenData *pSD)
1409 pSD->Num_Title_Ts_Elements = pSD->Num_Title_Bs_Elements = 0;
1411 /* count up rectangles for title bar */
1412 for (i = FRAME_SYSTEM; i <= FRAME_MAXIMIZE; i++)
1414 pSD->Num_Title_Ts_Elements += ((Bevels[i].top.external *
1415 pSD->externalBevel) +
1416 (Bevels[i].top.internal * MAX_INTERNAL_BEVEL) +
1417 (Bevels[i].top.join * pSD->joinBevel));
1419 pSD->Num_Title_Bs_Elements += ((Bevels[i].bottom.external*
1420 pSD->externalBevel)+
1421 (Bevels[i].bottom.internal * MAX_INTERNAL_BEVEL) +
1422 (Bevels[i].bottom.join * pSD->joinBevel));
1425 pSD->Num_Resize_Ts_Elements = pSD->Num_Resize_Bs_Elements = 0;
1427 /* count up rectangles for resize handles*/
1428 for (i = FRAME_RESIZE_NW; i <= FRAME_RESIZE_W; i++)
1430 pSD->Num_Resize_Ts_Elements += ((Bevels[i].top.external *
1431 pSD->externalBevel) +
1432 (Bevels[i].top.internal * MAX_INTERNAL_BEVEL) +
1433 (Bevels[i].top.join * pSD->joinBevel));
1435 pSD->Num_Resize_Bs_Elements += ((Bevels[i].bottom.external*
1436 pSD->externalBevel)+
1437 (Bevels[i].bottom.internal * MAX_INTERNAL_BEVEL) +
1438 (Bevels[i].bottom.join * pSD->joinBevel));
1440 } /* END OF FUNCTION CountFrameRectangles */
1444 /*************************************<->*************************************
1446 * AllocateFrameDisplayLists (pcd)
1451 * Allocates memory for the graphic display lists for the frame.
1456 * pcd - pointer to the client data
1461 * pcd - fields modified
1463 * Return - TRUE if successful, FALSE otherwise.
1470 *************************************<->***********************************/
1472 Boolean AllocateFrameDisplayLists (ClientData *pcd)
1474 int frame_top_count, frame_bottom_count;
1477 * If the title bar has it's own appearance, then allocate
1478 * separate display lists for it.
1480 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
1481 (pcd->decor & MWM_DECOR_TITLE))
1483 if (((pcd->pclientTitleTopShadows =
1484 AllocateRList ((unsigned)NUM_TITLE_TS_ELEMENTS(pcd))) == NULL) ||
1485 ((pcd->pclientTitleBottomShadows =
1486 AllocateRList ((unsigned)NUM_TITLE_BS_ELEMENTS(pcd))) == NULL))
1488 /* out of memory! */
1489 Warning (((char *)GETMESSAGE(8, 1, "Insufficient memory for client window framing")));
1493 frame_top_count = NUM_RESIZE_TS_ELEMENTS(pcd);
1494 frame_bottom_count = NUM_RESIZE_BS_ELEMENTS(pcd);
1498 frame_top_count = NUM_RESIZE_TS_ELEMENTS(pcd) +
1499 NUM_TITLE_TS_ELEMENTS(pcd);
1500 frame_bottom_count = NUM_RESIZE_BS_ELEMENTS(pcd) +
1501 NUM_RESIZE_BS_ELEMENTS(pcd);
1505 * Allocate the primary lists for the frame
1507 if ( (pcd->pclientTopShadows == NULL) &&
1508 ((pcd->pclientTopShadows =
1509 AllocateRList ((unsigned)frame_top_count)) == NULL) )
1511 /* out of memory! */
1512 Warning (((char *)GETMESSAGE(8, 2, "Insufficient memory for client window framing")));
1516 if ( (pcd->pclientBottomShadows == NULL) &&
1517 ((pcd->pclientBottomShadows =
1518 AllocateRList ((unsigned)frame_bottom_count)) == NULL) )
1520 /* out of memory! */
1521 Warning (((char *)GETMESSAGE(8, 3, "Insufficient memory for client window framing")));
1526 * Only allocate matte lists if there is a matte.
1528 if ( (pcd->matteWidth) &&
1529 (pcd->pclientMatteTopShadows == NULL) &&
1530 ((pcd->pclientMatteTopShadows =
1531 AllocateRList ((unsigned)NUM_MATTE_TS_RECTS)) == NULL))
1533 /* out of memory! */
1534 Warning (((char *)GETMESSAGE(8, 4, "Insufficient memory for client window framing")));
1538 if ( (pcd->matteWidth) &&
1539 (pcd->pclientMatteBottomShadows == NULL) &&
1540 ((pcd->pclientMatteBottomShadows =
1541 AllocateRList ((unsigned)NUM_MATTE_BS_RECTS)) == NULL))
1543 /* out of memory! */
1544 Warning (((char *)GETMESSAGE(8, 5, "Insufficient memory for client window framing")));
1549 } /* END OF FUNCTION AllocateFrameDisplayLists */
1552 /*************************************<->*************************************
1554 * InitClientDecoration (pSD)
1559 * Initializes client decoration routines
1564 * pSD - pointer to screen data
1572 * This must be called once before decorating any client frames.
1573 *************************************<->***********************************/
1575 void InitClientDecoration (WmScreenData *pSD)
1577 CountFrameRectangles(pSD);
1578 } /* END OF FUNCTION InitClientDecoration */
1582 /*************************************<->*************************************
1584 * AllocateGadgetRectangles (pcd)
1589 * Allocate the memory for event rectangles structures.
1594 * pcd - pointer to client data structure
1604 *************************************<->***********************************/
1606 Boolean AllocateGadgetRectangles (ClientData *pcd)
1609 unsigned long decor = pcd->decor;
1610 GadgetRectangle *pgr;
1612 if (decor & MWM_DECOR_TITLE) {
1614 /* count how many rectangles to allocate for titlebar */
1616 if (decor & MWM_DECOR_MENU) num_rects += 1;
1617 if (decor & MWM_DECOR_MINIMIZE) num_rects += 1;
1618 if (decor & MWM_DECOR_MAXIMIZE) num_rects += 1;
1620 /* allocate memory if no memory is allocated */
1621 if ( pcd->pTitleGadgets == NULL) {
1622 /* allocate memory for these guys */
1623 pgr = (GadgetRectangle *)
1624 XtMalloc (num_rects * sizeof(GadgetRectangle));
1627 /* out of memory! */
1628 Warning (((char *)GETMESSAGE(8, 6, "Insufficient memory for client window framing")));
1632 /* update client data */
1633 pcd->pTitleGadgets = pgr;
1634 pcd->cTitleGadgets = 0;
1638 if (decor & MWM_DECOR_RESIZEH) {
1640 /* allocate memory if no memory is allocated */
1641 if ( pcd->pResizeGadgets == NULL) {
1642 /* allocate memory for these guys */
1643 pgr = (GadgetRectangle *)
1644 XtMalloc (STRETCH_COUNT * sizeof(GadgetRectangle));
1647 /* out of memory! */
1648 Warning (((char *)GETMESSAGE(8, 7, "Insufficient memory for client window framing")));
1652 /* update client data */
1653 pcd->pResizeGadgets = pgr;
1657 } /* END OF FUNCTION AllocateGadgetRectangles */
1660 /*************************************<->*************************************
1662 * ComputeGadgetRectangles (pcd)
1667 * Creates the event rectangles structures to aid in identifying
1668 * frame parts when events come in
1673 * pcd - pointer to client data structure
1682 * o assumes gadget rectangles are already allocated.
1684 *************************************<->***********************************/
1686 void ComputeGadgetRectangles (ClientData *pcd)
1688 unsigned long decor = pcd->decor;
1689 GadgetRectangle *pgr;
1691 unsigned int fpWidth, fpHeight;
1693 int clientWidth = (pcd->maxConfig) ? pcd->maxWidth : pcd->clientWidth;
1698 if (decor & MWM_DECOR_TITLE) {
1700 if ( (pgr = pcd->pTitleGadgets) == NULL) {
1701 return; /* nothing there !!! */
1704 /* do title rectangle */
1705 pcd->titleRectangle.x = pcd->frameInfo.upperBorderWidth;
1706 pcd->titleRectangle.y = pcd->frameInfo.upperBorderWidth;
1709 * Fixed bug where last button in title bar did not activate when
1710 * the client's X border was showing.
1712 pcd->titleRectangle.width = clientWidth +
1713 (XBorderIsShowing(pcd) ? 2*pcd->xBorderWidth : 2*pcd->matteWidth);
1714 pcd->titleRectangle.height = pcd->frameInfo.titleBarHeight;
1716 /* fill in title bar rectangles */
1719 pgr[igr].id = FRAME_TITLE;
1720 GetFramePartInfo (pcd, FRAME_TITLE, &fpX, &fpY, &fpWidth, &fpHeight);
1722 /* copy in and convert to shorts */
1723 pgr[igr].rect.x = fpX;
1724 pgr[igr].rect.y = fpY;
1725 pgr[igr].rect.width = fpWidth;
1726 pgr[igr].rect.height = fpHeight;
1729 if (decor & MWM_DECOR_MENU) {
1730 pgr[igr].id = FRAME_SYSTEM;
1731 GetFramePartInfo (pcd, FRAME_SYSTEM, &fpX, &fpY, &fpWidth,
1734 /* copy in and convert to shorts */
1735 pgr[igr].rect.x = fpX;
1736 pgr[igr].rect.y = fpY;
1737 pgr[igr].rect.width = fpWidth;
1738 pgr[igr].rect.height = fpHeight;
1742 if (decor & MWM_DECOR_MINIMIZE) {
1743 pgr[igr].id = FRAME_MINIMIZE;
1744 GetFramePartInfo (pcd, FRAME_MINIMIZE,
1745 &fpX, &fpY, &fpWidth, &fpHeight);
1746 /* copy in and convert to shorts */
1747 pgr[igr].rect.x = fpX;
1748 pgr[igr].rect.y = fpY;
1749 pgr[igr].rect.width = fpWidth;
1750 pgr[igr].rect.height = fpHeight;
1754 if (decor & MWM_DECOR_MAXIMIZE) {
1755 pgr[igr].id = FRAME_MAXIMIZE;
1756 GetFramePartInfo (pcd, FRAME_MAXIMIZE,
1757 &fpX, &fpY, &fpWidth, &fpHeight);
1758 /* copy in and convert to shorts */
1759 pgr[igr].rect.x = fpX;
1760 pgr[igr].rect.y = fpY;
1761 pgr[igr].rect.width = fpWidth;
1762 pgr[igr].rect.height = fpHeight;
1766 /* update client data */
1767 pcd->pTitleGadgets = pgr;
1768 pcd->cTitleGadgets = igr;
1771 /* client matte area (actually base window area) */
1773 if (decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
1775 pcd->matteRectangle.x = pcd->frameInfo.lowerBorderWidth;
1776 pcd->matteRectangle.y = pcd->frameInfo.upperBorderWidth +
1777 pcd->frameInfo.titleBarHeight;
1778 pcd->matteRectangle.width = pcd->frameInfo.width -
1779 (2 * pcd->frameInfo.lowerBorderWidth);
1780 pcd->matteRectangle.height = pcd->frameInfo.height -
1781 pcd->frameInfo.upperBorderWidth -
1782 pcd->frameInfo.lowerBorderWidth -
1783 pcd->frameInfo.titleBarHeight;
1787 pcd->matteRectangle.x = 0;
1788 pcd->matteRectangle.y = pcd->frameInfo.titleBarHeight;
1789 pcd->matteRectangle.width = pcd->frameInfo.width;
1790 pcd->matteRectangle.height = pcd->frameInfo.height -
1791 pcd->frameInfo.titleBarHeight;
1794 if (decor & MWM_DECOR_RESIZEH) {
1796 if ( (pgr = pcd->pResizeGadgets) == NULL) {
1797 return; /* nothing there !!! */
1800 /* fill in resize rectangles */
1802 if (decor & MWM_DECOR_RESIZEH) {
1804 pgr[igr].id = FRAME_RESIZE_NW;
1805 GetFramePartInfo (pcd, FRAME_RESIZE_NW,
1806 &fpX, &fpY, &fpWidth, &fpHeight);
1807 /* copy in and convert to shorts */
1808 pgr[igr].rect.x = fpX;
1809 pgr[igr].rect.y = fpY;
1810 pgr[igr].rect.width = fpWidth;
1811 pgr[igr].rect.height = fpHeight;
1814 pgr[igr].id = FRAME_RESIZE_N;
1815 GetFramePartInfo (pcd, FRAME_RESIZE_N,
1816 &fpX, &fpY, &fpWidth, &fpHeight);
1817 if ((int) fpWidth > 0) {
1818 /* copy in and convert to shorts */
1819 pgr[igr].rect.x = fpX;
1820 pgr[igr].rect.y = fpY;
1821 pgr[igr].rect.width = fpWidth;
1822 pgr[igr].rect.height = fpHeight;
1826 pgr[igr].id = FRAME_RESIZE_NE;
1827 GetFramePartInfo (pcd, FRAME_RESIZE_NE,
1828 &fpX, &fpY, &fpWidth, &fpHeight);
1829 /* copy in and convert to shorts */
1830 pgr[igr].rect.x = fpX;
1831 pgr[igr].rect.y = fpY;
1832 pgr[igr].rect.width = fpWidth;
1833 pgr[igr].rect.height = fpHeight;
1836 pgr[igr].id = FRAME_RESIZE_W;
1837 GetFramePartInfo (pcd, FRAME_RESIZE_W,
1838 &fpX, &fpY, &fpWidth, &fpHeight);
1839 if ((int)fpHeight > 0) {
1840 /* copy in and convert to shorts */
1841 pgr[igr].rect.x = fpX;
1842 pgr[igr].rect.y = fpY;
1843 pgr[igr].rect.width = fpWidth;
1844 pgr[igr].rect.height = fpHeight;
1848 pgr[igr].id = FRAME_RESIZE_E;
1849 GetFramePartInfo (pcd, FRAME_RESIZE_E,
1850 &fpX, &fpY, &fpWidth, &fpHeight);
1851 if ((int) fpHeight > 0) {
1852 /* copy in and convert to shorts */
1853 pgr[igr].rect.x = fpX;
1854 pgr[igr].rect.y = fpY;
1855 pgr[igr].rect.width = fpWidth;
1856 pgr[igr].rect.height = fpHeight;
1860 pgr[igr].id = FRAME_RESIZE_SW;
1861 GetFramePartInfo (pcd, FRAME_RESIZE_SW,
1862 &fpX, &fpY, &fpWidth, &fpHeight);
1863 /* copy in and convert to shorts */
1864 pgr[igr].rect.x = fpX;
1865 pgr[igr].rect.y = fpY;
1866 pgr[igr].rect.width = fpWidth;
1867 pgr[igr].rect.height = fpHeight;
1870 pgr[igr].id = FRAME_RESIZE_S;
1871 GetFramePartInfo (pcd, FRAME_RESIZE_S,
1872 &fpX, &fpY, &fpWidth, &fpHeight);
1873 if ((int) fpWidth > 0) {
1874 /* copy in and convert to shorts */
1875 pgr[igr].rect.x = fpX;
1876 pgr[igr].rect.y = fpY;
1877 pgr[igr].rect.width = fpWidth;
1878 pgr[igr].rect.height = fpHeight;
1882 pgr[igr].id = FRAME_RESIZE_SE;
1883 GetFramePartInfo (pcd, FRAME_RESIZE_SE,
1884 &fpX, &fpY, &fpWidth, &fpHeight);
1885 /* copy in and convert to shorts */
1886 pgr[igr].rect.x = fpX;
1887 pgr[igr].rect.y = fpY;
1888 pgr[igr].rect.width = fpWidth;
1889 pgr[igr].rect.height = fpHeight;
1892 /* update client data */
1893 pcd->pResizeGadgets = pgr;
1896 } /* END OF FUNCTION ComputeGadgetRectangles */
1900 /*************************************<->*************************************
1902 * GetSystemMenuPosition (pcd, px, py, height, context)
1907 * Returns the position of where the system menu should be popped up.
1908 * The hotspotRectangle in global is also set up to match the icon or
1909 * system menu button area.
1914 * pcd = pointer to client data
1916 * px = pointer to x location
1918 * py = pointer to y location
1920 * height = height of the system menu
1922 * context = context that the menu is to be posted under.
1931 * wmGD.hotspotRectangle = system menu button or icon area (root relative)
1933 *************************************<->***********************************/
1935 void GetSystemMenuPosition (ClientData *pcd, int *px, int *py,
1936 unsigned int height, Context context)
1939 if ((pcd->clientState == MINIMIZED_STATE) ||
1940 ((pcd->clientState != MINIMIZED_STATE) &&
1941 (context == F_SUBCONTEXT_IB_WICON)))
1944 * Try to put the menu directly above the icon.
1945 * If it would hit the top of the screen then try to put it below
1946 * the icon and label.
1947 * If it would then hit the bottom of the screen turn of the hotspot
1952 if (pcd->pSD->useIconBox && P_ICON_BOX(pcd))
1954 GetIconBoxIconRootXY (pcd, px, py);
1956 wmGD.hotspotRectangle.x = *px;
1957 wmGD.hotspotRectangle.y = *py;
1963 *py += height + ICON_HEIGHT(pcd);
1964 if (*py + height >= DisplayHeight (DISPLAY,
1965 SCREEN_FOR_CLIENT(pcd)))
1967 wmGD.checkHotspot = FALSE;
1974 *py = ICON_Y(pcd) - height;
1978 *py = ICON_Y(pcd) + ICON_HEIGHT(pcd);
1979 if (*py + height >= DisplayHeight (DISPLAY,
1980 SCREEN_FOR_CLIENT(pcd)))
1982 wmGD.checkHotspot = FALSE;
1986 wmGD.hotspotRectangle.x = ICON_X(pcd);
1987 wmGD.hotspotRectangle.y = ICON_Y(pcd);
1990 /* setup the hotspot rectangle data */
1992 wmGD.hotspotRectangle.width = ICON_WIDTH(pcd);
1993 wmGD.hotspotRectangle.height = ICON_HEIGHT(pcd);
1998 * Try to put the menu directly below the SW corner of the
2000 * If it would hit the bottom of the screen then try to put it directly
2001 * above the NW corner of the titlebar/border.
2002 * If it would then hit the top of the screen turn of the hotspot
2006 if ((pcd->decor & MWM_DECOR_TITLE) &&
2007 !(pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)))
2009 *px = pcd->frameInfo.x;
2010 *py = pcd->frameInfo.y + pcd->frameInfo.titleBarHeight;
2014 *px = pcd->frameInfo.x + pcd->frameInfo.lowerBorderWidth;
2015 *py = pcd->frameInfo.y + pcd->frameInfo.upperBorderWidth +
2016 pcd->frameInfo.titleBarHeight;
2018 if (*py + height >= DisplayHeight (DISPLAY,
2019 SCREEN_FOR_CLIENT(pcd)))
2021 if ((pcd->decor & MWM_DECOR_TITLE) &&
2022 !(pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)))
2024 *py = pcd->frameInfo.y - height;
2028 *py = pcd->frameInfo.y + pcd->frameInfo.upperBorderWidth -
2033 wmGD.checkHotspot = FALSE;
2037 /* setup the hotspot rectangle data */
2039 wmGD.hotspotRectangle.x = pcd->frameInfo.x +
2040 pcd->frameInfo.lowerBorderWidth;
2041 wmGD.hotspotRectangle.y = pcd->frameInfo.y +
2042 pcd->frameInfo.upperBorderWidth;
2044 /* assume square button */
2045 wmGD.hotspotRectangle.width = pcd->frameInfo.titleBarHeight;
2046 wmGD.hotspotRectangle.height = pcd->frameInfo.titleBarHeight;
2049 } /* END OF FUNCTION GetSystemMenuPosition */
2053 /*************************************<->*************************************
2055 * ShowActiveClientFrame (pcd)
2060 * Paint the frame to indicate an "active" window
2065 * pcd - pointer to client data
2074 * o This calls the frame exposure procedure, which gets some GCs based
2075 * on the current keyboard focus. Thus, wmGD.keyboardFocus == pcd
2076 * must be TRUE when this is called for the correct highlighting to
2079 *************************************<->***********************************/
2082 ShowActiveClientFrame (ClientData *pcd)
2084 unsigned long attr_mask = 0;
2085 XSetWindowAttributes window_attribs;
2087 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
2088 (pcd->decor & MWM_DECOR_TITLE))
2091 * Use background pixmap if one is specified, otherwise set the
2092 * appropriate background color.
2095 if (CLIENT_TITLE_APPEARANCE(pcd).activeBackgroundPixmap)
2097 attr_mask |= CWBackPixmap;
2098 window_attribs.background_pixmap =
2099 CLIENT_TITLE_APPEARANCE(pcd).activeBackgroundPixmap;
2103 attr_mask |= CWBackPixel;
2104 window_attribs.background_pixel =
2105 CLIENT_TITLE_APPEARANCE(pcd).activeBackground;
2109 XChangeWindowAttributes (DISPLAY, pcd->clientTitleWin, attr_mask,
2112 /* clear the frame to the right background */
2113 XClearWindow (DISPLAY, pcd->clientTitleWin);
2117 * Use background pixmap if one is specified, otherwise set the
2118 * appropriate background color.
2121 if (CLIENT_APPEARANCE(pcd).activeBackgroundPixmap)
2123 attr_mask |= CWBackPixmap;
2124 window_attribs.background_pixmap =
2125 CLIENT_APPEARANCE(pcd).activeBackgroundPixmap;
2129 attr_mask |= CWBackPixel;
2130 window_attribs.background_pixel =
2131 CLIENT_APPEARANCE(pcd).activeBackground;
2135 XChangeWindowAttributes (DISPLAY, pcd->clientFrameWin, attr_mask,
2138 /* clear the frame to the right background */
2139 XClearWindow (DISPLAY, pcd->clientFrameWin);
2141 /* simulate exposure of window */
2142 FrameExposureProc (pcd);
2145 } /* END OF FUNCTION ShowActiveClient */
2149 /*************************************<->*************************************
2151 * ShowInactiveClientFrame (pcd)
2156 * Paint the frame to indicate an "inactive" window
2161 * pcd - pointer to client data
2170 * o This calls the frame exposure procedure, which gets some GCs based
2171 * on the current keyboard focus. Thus, wmGD.keyboardFocus == pcd
2172 * must be FALSE when this is called for the correct highlighting to
2176 ******************************<->***********************************/
2179 ShowInactiveClientFrame (ClientData *pcd)
2181 unsigned long attr_mask = 0;
2182 XSetWindowAttributes window_attribs;
2184 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
2185 (pcd->decor & MWM_DECOR_TITLE))
2188 * Use background pixmap if one is specified, otherwise set the
2189 * appropriate background color.
2192 if (CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap)
2194 attr_mask |= CWBackPixmap;
2195 window_attribs.background_pixmap =
2196 CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap;
2200 attr_mask |= CWBackPixel;
2201 window_attribs.background_pixel =
2202 CLIENT_TITLE_APPEARANCE(pcd).background;
2206 XChangeWindowAttributes (DISPLAY, pcd->clientTitleWin, attr_mask,
2209 /* clear the frame to the right background */
2210 XClearWindow (DISPLAY, pcd->clientTitleWin);
2213 * attr_mask must be cleared because it is set if
2214 * DECOUPLE_TITLE_APPEARANCE(pcd) is true.
2220 * Use background pixmap if one is specified, otherwise set the
2221 * appropriate background color.
2224 if (CLIENT_APPEARANCE(pcd).backgroundPixmap)
2226 attr_mask |= CWBackPixmap;
2227 window_attribs.background_pixmap =
2228 CLIENT_APPEARANCE(pcd).backgroundPixmap;
2232 attr_mask |= CWBackPixel;
2233 window_attribs.background_pixel =
2234 CLIENT_APPEARANCE(pcd).background;
2238 /* change window attribs so clear does the right thing */
2239 XChangeWindowAttributes (DISPLAY, pcd->clientFrameWin, attr_mask,
2242 /* clear the frame to the right background */
2243 XClearWindow (DISPLAY, pcd->clientFrameWin);
2245 /* simulate exposure of window */
2246 FrameExposureProc (pcd);
2248 } /* END OF FUNCTION ShowInactiveClientFrame */
2252 /*************************************<->*************************************
2254 * RegenerateClientFrame (pcd)
2259 * Reconfigure the sizes of all the components of the client frame
2264 * pcd - pointer to client data
2274 *************************************<->***********************************/
2276 void RegenerateClientFrame (ClientData *pcd)
2278 unsigned long decor = pcd->decor;
2281 * If an embedded client, there is no frame.
2285 if (!pcd->clientFrameWin)
2290 #endif /* PANELIST */
2292 /* recompute frame information */
2295 /* move & resize frame window */
2296 XMoveResizeWindow (DISPLAY, pcd->clientFrameWin, pcd->frameInfo.x,
2297 pcd->frameInfo.y, pcd->frameInfo.width, pcd->frameInfo.height);
2300 /* resize title bar window */
2301 if (decor & MWM_DECOR_TITLE)
2303 XResizeWindow (DISPLAY, pcd->clientTitleWin,
2304 pcd->frameInfo.width - 2*pcd->frameInfo.upperBorderWidth,
2305 pcd->frameInfo.titleBarHeight);
2308 /* resize base window */
2309 XResizeWindow (DISPLAY, pcd->clientBaseWin, BaseWindowWidth (pcd),
2310 BaseWindowHeight (pcd));
2312 /* resize the stretcher windows */
2313 if (SHOW_RESIZE_CURSORS(pcd) && (decor & MWM_DECOR_RESIZEH)) {
2314 XMoveResizeWindow (DISPLAY,
2315 pcd->clientStretchWin[STRETCH_NORTH_WEST],
2316 0, 0, pcd->frameInfo.cornerWidth,
2317 pcd->frameInfo.cornerHeight);
2319 XMoveResizeWindow (DISPLAY,
2320 pcd->clientStretchWin[STRETCH_NORTH],
2321 (int) pcd->frameInfo.cornerWidth, 0,
2322 pcd->frameInfo.width - 2*pcd->frameInfo.cornerWidth,
2323 pcd->frameInfo.upperBorderWidth);
2325 XMoveResizeWindow (DISPLAY,
2326 pcd->clientStretchWin[STRETCH_NORTH_EAST],
2327 (int) (pcd->frameInfo.width - pcd->frameInfo.cornerWidth), 0,
2328 pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2330 XMoveResizeWindow (DISPLAY,
2331 pcd->clientStretchWin[STRETCH_EAST],
2332 (int) (pcd->frameInfo.width - pcd->frameInfo.lowerBorderWidth),
2333 (int) (pcd->frameInfo.cornerHeight),
2334 pcd->frameInfo.lowerBorderWidth,
2335 pcd->frameInfo.height - 2*pcd->frameInfo.cornerHeight);
2337 XMoveResizeWindow (DISPLAY,
2338 pcd->clientStretchWin[STRETCH_SOUTH_EAST],
2339 (int) (pcd->frameInfo.width - pcd->frameInfo.cornerWidth),
2340 (int) (pcd->frameInfo.height - pcd->frameInfo.cornerHeight),
2341 pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2343 XMoveResizeWindow (DISPLAY,
2344 pcd->clientStretchWin[STRETCH_SOUTH],
2345 (int) pcd->frameInfo.cornerWidth,
2346 (int) (pcd->frameInfo.height - pcd->frameInfo.lowerBorderWidth),
2347 pcd->frameInfo.width - 2*pcd->frameInfo.cornerWidth,
2348 pcd->frameInfo.lowerBorderWidth);
2350 XMoveResizeWindow (DISPLAY,
2351 pcd->clientStretchWin[STRETCH_SOUTH_WEST],
2352 0, (int) (pcd->frameInfo.height - pcd->frameInfo.cornerHeight),
2353 pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2355 XMoveResizeWindow (DISPLAY,
2356 pcd->clientStretchWin[STRETCH_WEST],
2357 0, (int) pcd->frameInfo.cornerHeight,
2358 pcd->frameInfo.lowerBorderWidth,
2359 pcd->frameInfo.height - 2*pcd->frameInfo.cornerHeight);
2362 /* recreate gadget rectangles */
2363 ComputeGadgetRectangles (pcd);
2365 /* regenerate the graphics */
2366 GenerateFrameDisplayLists (pcd);
2369 if (wmGD.hasShape && pcd->wShaped)
2371 SetFrameShape (pcd);
2373 #endif /* NO_SHAPE */
2375 } /* END OF FUNCTION RegenerateClientFrame */
2380 /*************************************<->*************************************
2382 * BevelSystemButton (prTop, prBot, x, y, width, height)
2387 * Bevels a rectangle for the system button (drawer handle?)
2392 * prTop - ptr to top shadow rectangles
2393 * prBot - ptr to bottom shadow rectangles
2394 * x - x coord of maximize gadget
2395 * y - y coord of maximize gadget
2396 * width - width of maximize gadget
2397 * height - height of maximize gadget
2406 * o This draws a horizontal "drawer handle" for the system gadget.
2407 * Assumptions: the enclosing box is square (width == height)
2408 *************************************<->***********************************/
2410 void BevelSystemButton (RList *prTop, RList *prBot, int x, int y,
2411 unsigned int width, unsigned int height)
2413 int offset1, offset2;
2414 unsigned int dim1, dim2;
2419 offset1 = offset2 = 2;
2420 dim1 = dim2 = height-4;
2424 offset1 = offset2 = 2;
2448 offset2 = (height-3)/2;
2455 offset2 = (height - 4)/2;
2464 BevelRectangle (prTop, prBot, /* system icon */
2465 (x+offset1), (y+offset2),
2469 } /* END OF FUNCTION BevelSystemButton */
2473 /*************************************<->*************************************
2475 * BevelMinimizeButton (prTop, prBot, x, y, height)
2480 * Bevels a rectangle for the minimize button
2485 * prTop - ptr to top shadow rectangles
2486 * prBot - ptr to bottom shadow rectangles
2487 * x - x coord of maximize gadget
2488 * y - y coord of maximize gadget
2489 * height - height of maximize gadget
2499 *************************************<->***********************************/
2501 void BevelMinimizeButton (RList *prTop, RList *prBot, int x, int y,
2502 unsigned int height)
2504 int offset1, offset2;
2505 unsigned int dim1, dim2;
2511 offset1 = offset2 = 3;
2512 dim1 = dim2 = height-6;
2518 offset1 = offset2 = (height-3)/2;
2523 offset1 = offset2 = (height-4)/2;
2530 BevelRectangle (prTop, prBot,
2531 (x+offset1), (y+offset2),
2535 } /* END OF FUNCTION BevelMinimizeButton */
2539 /*************************************<->*************************************
2541 * BevelMaximizeButton (prTop, prBot, x, y, height)
2546 * Bevels a rectangle for the maximize button
2551 * prTop - ptr to top shadow rectangles
2552 * prBot - ptr to bottom shadow rectangles
2553 * x - x coord of maximize gadget
2554 * y - y coord of maximize gadget
2555 * height - height of maximize gadget
2565 *************************************<->***********************************/
2567 void BevelMaximizeButton (RList *prTop, RList *prBot, int x, int y,
2568 unsigned int height)
2570 int offset1, offset2;
2571 unsigned int dim1, dim2;
2581 offset1 = offset2 = 2;
2582 dim1 = dim2 = height-4;
2589 offset1 = offset2 = 3;
2590 dim1 = dim2 = height-6;
2594 offset1 = offset2 = 4;
2595 dim1 = dim2 = height-8;
2600 BevelRectangle (prTop, prBot,
2601 (x+offset1), (y+offset2),
2604 } /* END OF FUNCTION BevelMaximizeButton */
2607 /*************************************<->*************************************
2609 * DepressGadget (pcd, gadget, depressed)
2614 * Show the gadget in a "depressed" state
2619 * pcd - pointer to client data
2620 * gadget - gadget id
2621 * depressed - if True, then gadget is shown depressed, if False it is
2622 * shown not depressed
2627 * return - true if sucessful
2632 * o This assumes there is a one-pixel bevel around the gadget.
2633 * o This only works on title bar gadgets.
2635 *************************************<->***********************************/
2637 Boolean DepressGadget (ClientData *pcd, int gadget, Boolean depressed)
2640 unsigned int width, height, invertWidth;
2641 static RList *pTopRect = NULL;
2642 static RList *pBotRect = NULL;
2646 /* get outside dimensions of box we want */
2651 case FRAME_MINIMIZE:
2652 case FRAME_MAXIMIZE:
2653 if (!GetDepressInfo (pcd, gadget, &x, &y, &width,
2654 &height, &invertWidth))
2660 return(FALSE); /* do nothing on non-title bar gagdets */
2663 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
2664 (pcd->decor & MWM_DECOR_TITLE))
2666 /* adjust position to be relative to titlebar window, not frame */
2667 x -= (short) pcd->frameInfo.upperBorderWidth;
2668 y -= (short) pcd->frameInfo.upperBorderWidth;
2670 /* use "active" GCs if we have keyboard focus */
2671 if (pcd == wmGD.keyboardFocus) {
2672 topGC = CLIENT_TITLE_APPEARANCE(pcd).activeTopShadowGC;
2673 botGC = CLIENT_TITLE_APPEARANCE(pcd).activeBottomShadowGC;
2676 topGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveTopShadowGC;
2678 CLIENT_TITLE_APPEARANCE(pcd).inactiveBottomShadowGC;
2681 /* draw into title bar window */
2682 win = pcd->clientTitleWin;
2686 /* use "active" GCs if we have keyboard focus */
2687 if (pcd == wmGD.keyboardFocus) {
2688 topGC = CLIENT_APPEARANCE(pcd).activeTopShadowGC;
2689 botGC = CLIENT_APPEARANCE(pcd).activeBottomShadowGC;
2692 topGC = CLIENT_APPEARANCE(pcd).inactiveTopShadowGC;
2693 botGC = CLIENT_APPEARANCE(pcd).inactiveBottomShadowGC;
2696 /* draw into client frame window */
2697 win = pcd->clientFrameWin;
2701 * Bevel a rectangle for the desired button effect
2702 * Allocate the rectangles if necessary.
2704 if ( (pTopRect && pBotRect) ||
2705 ((pTopRect = AllocateRList(2)) &&
2706 (pBotRect = AllocateRList(2))))
2710 BevelRectangle (pTopRect, pBotRect,
2711 x, y, width, height,
2712 invertWidth, invertWidth,
2713 invertWidth, invertWidth);
2716 /* draw the gadget border to make it look depressed or normal */
2719 XFillRectangles (DISPLAY, win, botGC, pTopRect->prect, pTopRect->used);
2720 XFillRectangles (DISPLAY, win, topGC, pBotRect->prect, pBotRect->used);
2723 XFillRectangles (DISPLAY, win, topGC, pTopRect->prect, pTopRect->used);
2724 XFillRectangles (DISPLAY, win, botGC, pBotRect->prect, pBotRect->used);
2727 } /* END OF FUNCTION DepressGadget */
2730 /*************************************<->*************************************
2732 * PushGadgetIn (pcd, gadget)
2737 * Shows a title bar gadget in a depressed state
2742 * pcd - pointer to client data
2743 * gadget - gadget id
2751 *************************************<->***********************************/
2753 void PushGadgetIn (ClientData *pcd, int gadget)
2757 pcd->decorFlags |= SYSTEM_DEPRESSED;
2761 pcd->decorFlags |= TITLE_DEPRESSED;
2764 case FRAME_MINIMIZE:
2765 pcd->decorFlags |= MINIMIZE_DEPRESSED;
2768 case FRAME_MAXIMIZE:
2769 pcd->decorFlags |= MAXIMIZE_DEPRESSED;
2775 GenerateFrameDisplayLists(pcd);
2776 (void) DepressGadget (pcd, gadget, TRUE);
2777 wmGD.gadgetClient = pcd;
2778 wmGD.gadgetDepressed = gadget;
2779 } /* END OF FUNCTION PushGadgetIn */
2782 /*************************************<->*************************************
2784 * PopGadgetOut (pcd, gadget)
2789 * Shows a title bar gadget in a depressed state
2794 * pcd - pointer to client data
2795 * gadget - gadget id
2803 *************************************<->***********************************/
2805 void PopGadgetOut (ClientData *pcd, int gadget)
2809 pcd->decorFlags &= ~SYSTEM_DEPRESSED;
2813 pcd->decorFlags &= ~TITLE_DEPRESSED;
2816 case FRAME_MINIMIZE:
2817 pcd->decorFlags &= ~MINIMIZE_DEPRESSED;
2820 case FRAME_MAXIMIZE:
2821 pcd->decorFlags &= ~MAXIMIZE_DEPRESSED;
2827 GenerateFrameDisplayLists(pcd);
2828 (void) DepressGadget (pcd, gadget, FALSE);
2829 wmGD.gadgetClient = NULL;
2830 wmGD.gadgetDepressed = 0;
2831 } /* END OF FUNCTION PopGadgetOut */
2835 /*************************************<->*************************************
2837 * SetFrameShape (pcd)
2842 * Shapes the frame and base window to the shape of the client
2843 * window. Also ors the title window into the shaped frame
2844 * window if present.
2848 * pcd - pointer to client data
2855 * o currently punt on resize handle around the frame.
2857 *************************************<->***********************************/
2858 void SetFrameShape (ClientData *pcd)
2861 * The frame consists of the shape of the contents window offset by
2862 * title_height or'ed with the shape of title window (which is always
2868 if (XBorderIsShowing(pcd))
2870 xOffset = pcd->xBorderWidth;
2871 yOffset = pcd->xBorderWidth;
2873 else if(pcd->matteWidth > 0)
2875 xOffset = pcd->matteWidth;
2876 yOffset = pcd->matteWidth;
2882 * need to do general case
2884 XShapeCombineShape (DISPLAY, pcd->clientBaseWin, ShapeBounding,
2887 pcd->client, ShapeBounding,
2890 XShapeCombineShape (DISPLAY, pcd->clientFrameWin, ShapeBounding,
2893 pcd->clientBaseWin, ShapeBounding,
2896 if (pcd->decor & MWM_DECOR_TITLE)
2898 XShapeCombineShape (DISPLAY, pcd->clientFrameWin, ShapeBounding,
2899 pcd->frameInfo.upperBorderWidth,
2900 pcd->frameInfo.upperBorderWidth,
2901 pcd->clientTitleWin, ShapeBounding,
2907 (void) XShapeCombineMask (DISPLAY, pcd->clientFrameWin,
2908 ShapeBounding, 0, 0,
2910 (void) XShapeCombineMask (DISPLAY, pcd->clientFrameWin,
2913 (void) XShapeCombineMask (DISPLAY, pcd->clientBaseWin,
2914 ShapeBounding, 0, 0,
2916 (void) XShapeCombineMask (DISPLAY, pcd->clientBaseWin,
2920 } /* END OF FUNCTION SetFrameShape */
2921 #endif /* NO_SHAPE */