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 libraries 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 = 0, yAdj = 0;
570 unsigned int width, height;
571 RList *prlTop = NULL, *prlBot = NULL;
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);
754 if((pcd->dtwmBehaviors & DtWM_BEHAVIOR_PANEL) &&
755 (pcd->clientDecoration == WM_DECOR_BORDER))
759 BevelRectangle (pcd->pclientBottomShadows, /* inside */
760 pcd->pclientTopShadows,
761 (int)(pcd->frameInfo.lowerBorderWidth-insideBevel),
762 (int)(pcd->frameInfo.lowerBorderWidth-insideBevel),
763 pcd->frameInfo.width -
764 2*pcd->frameInfo.lowerBorderWidth +
766 pcd->frameInfo.height -
767 2*pcd->frameInfo.lowerBorderWidth +
769 (unsigned int)insideBevel,
770 (unsigned int)insideBevel,
771 (unsigned int)insideBevel,
772 (unsigned int)insideBevel);
780 * set bevels for title bar and parts
782 if (decoration & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
784 nTitleBevel = JOIN_BEVEL(pcd); /* north side of title */
785 if (wmGD.frameStyle == WmSLAB)
787 sTitleBevel = JOIN_BEVEL(pcd); /* south side of title */
791 sTitleBevel = insideBevel; /* south side of title */
793 eTitleBevel = JOIN_BEVEL(pcd); /* east side of title */
794 wTitleBevel = JOIN_BEVEL(pcd); /* west side of title */
795 meTitleBevel = JOIN_BEVEL(pcd); /* btw Minimize, Maximize */
799 /* borderless window */
801 nTitleBevel = EXTERNAL_BEVEL(pcd);
802 if (wmGD.frameStyle == WmSLAB)
804 sTitleBevel = (matte_width > 0) ? JOIN_BEVEL(pcd) :
809 sTitleBevel = (matte_width > 0) ? insideBevel : EXTERNAL_BEVEL(pcd);
811 eTitleBevel = (decoration & (MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE))?
812 JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
813 wTitleBevel = (decoration & MWM_DECOR_MENU) ?
814 JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
816 /* beveling east of minimize */
817 meTitleBevel = (decoration & (MWM_DECOR_MAXIMIZE)) ?
818 JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
822 if (decoration & MWM_DECOR_TITLE)
825 * Use a different set of rectangles if title appearance
826 * is different from the rest of the frame.
828 if (DECOUPLE_TITLE_APPEARANCE(pcd))
830 prlTop = pcd->pclientTitleTopShadows;
831 prlBot = pcd->pclientTitleBottomShadows;
832 xAdj = yAdj = pcd->frameInfo.upperBorderWidth;
836 prlTop = pcd->pclientTopShadows;
837 prlBot = pcd->pclientBottomShadows;
842 GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height);
843 if (pcd->decorFlags & TITLE_DEPRESSED) {
844 /* show depressed title gadget */
845 GetDepressInfo (pcd, FRAME_TITLE, &jX, &jY, &jW, &jH,
847 BevelDepressedRectangle (prlTop, prlBot,
848 x-xAdj, y-yAdj, width, height,
849 nTitleBevel, eTitleBevel,
850 sTitleBevel, wTitleBevel, inWidth);
853 /* show normal title gadget */
854 BevelRectangle (prlTop, prlBot,
855 x-xAdj, y-yAdj, width, height,
856 nTitleBevel, eTitleBevel,
857 sTitleBevel, wTitleBevel);
861 if (decoration & MWM_DECOR_MENU) {
863 GetFramePartInfo (pcd, FRAME_SYSTEM, &x, &y, &width, &height);
864 if (pcd->decorFlags & SYSTEM_DEPRESSED) {
865 /* show depressed system gadget */
866 GetDepressInfo (pcd, FRAME_SYSTEM, &jX, &jY, &jW, &jH,
868 BevelDepressedRectangle (prlTop, prlBot,
869 x-xAdj, y-yAdj, width, height,
870 nTitleBevel, wTitleBevel,
871 sTitleBevel, nTitleBevel, inWidth);
875 /* show normal system gadget */
876 BevelRectangle (prlTop, prlBot,
877 x-xAdj, y-yAdj, width, height,
878 nTitleBevel, wTitleBevel,
879 sTitleBevel, nTitleBevel);
884 BevelSystemButton (prlTop, prlBot,
885 x-xAdj, y-yAdj, width, height);
888 if (decoration & MWM_DECOR_MINIMIZE) {
889 GetFramePartInfo (pcd, FRAME_MINIMIZE, &x, &y, &width, &height);
891 if (pcd->decorFlags & MINIMIZE_DEPRESSED) {
892 /* show depressed minimize gadget */
893 GetDepressInfo (pcd, FRAME_MINIMIZE, &jX, &jY, &jW, &jH,
895 BevelDepressedRectangle (prlTop, prlBot,
896 x-xAdj, y-yAdj, width, height,
897 nTitleBevel, meTitleBevel,
898 sTitleBevel, eTitleBevel, inWidth);
901 /* show normal minimize gadget */
902 BevelRectangle (prlTop, prlBot,
903 x-xAdj, y-yAdj, width, height,
904 nTitleBevel, meTitleBevel,
905 sTitleBevel, eTitleBevel);
909 BevelMinimizeButton(prlTop, /* minimize icon */
911 x-xAdj, y-yAdj, height);
914 if (decoration & MWM_DECOR_MAXIMIZE) {
915 GetFramePartInfo (pcd, FRAME_MAXIMIZE, &x, &y, &width, &height);
918 if (pcd->decorFlags & MAXIMIZE_DEPRESSED) {
919 /* show depressed maximize gadget */
920 GetDepressInfo (pcd, FRAME_MAXIMIZE, &jX, &jY, &jW, &jH,
922 BevelDepressedRectangle (prlTop, prlBot,
923 x-xAdj, y-yAdj, width, height,
924 nTitleBevel, nTitleBevel,
925 sTitleBevel, eTitleBevel, inWidth);
928 /* show normal maximize gadget */
929 BevelRectangle (prlTop, prlBot,
930 x-xAdj, y-yAdj, width, height,
931 nTitleBevel, nTitleBevel,
932 sTitleBevel, eTitleBevel);
935 /* maximize icon - in or out depending on client state */
936 if (pcd->maxConfig) {
937 BevelMaximizeButton(prlBot,
939 x-xAdj, y-yAdj, height);
942 BevelMaximizeButton(prlTop,
944 x-xAdj, y-yAdj, height);
949 /* draw the client matte (this is in the base window!!!) */
951 if (matte_width > 0) {
952 unsigned int mWidth, mHeight, exMatteBevel, tMatteBevel;
954 mWidth = BaseWindowWidth (pcd);
955 mHeight = BaseWindowHeight (pcd);
957 if (decoration & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
959 exMatteBevel = JOIN_BEVEL(pcd);
960 tMatteBevel = JOIN_BEVEL(pcd);
964 exMatteBevel = EXTERNAL_BEVEL(pcd);
965 tMatteBevel = (decoration & MWM_DECOR_TITLE) ?
966 JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
969 /* set up beveling around the edges */
971 BevelRectangle (pcd->pclientMatteTopShadows,
972 pcd->pclientMatteBottomShadows,
977 tMatteBevel, exMatteBevel,
978 exMatteBevel, exMatteBevel);
980 /* reversed beveling on inside rectange ! */
982 BevelRectangle ( pcd->pclientMatteBottomShadows,
983 pcd->pclientMatteTopShadows,
984 matte_width - pcd->internalBevel,
985 matte_width - pcd->internalBevel,
986 mWidth - 2*matte_width + 2*pcd->internalBevel,
987 mHeight - 2*matte_width + 2*pcd->internalBevel,
988 (unsigned int) pcd->internalBevel,
989 (unsigned int) pcd->internalBevel,
990 (unsigned int) pcd->internalBevel,
991 (unsigned int) pcd->internalBevel);
996 /*************************************<->*************************************
1003 * Reparent the client window to the window frame
1008 * pcd - pointer to client data record
1019 *************************************<->***********************************/
1021 void AdoptClient (ClientData *pcd)
1023 XWindowChanges windowChanges;
1026 /* Put the window in the window manager's save set */
1028 if (!(pcd->clientFlags & CLIENT_WM_CLIENTS))
1030 XChangeSaveSet (DISPLAY, pcd->client, SetModeInsert);
1031 pcd->clientFlags |= CLIENT_IN_SAVE_SET;
1035 * set window geometry to be consistent with what we believe
1037 mask = CWWidth | CWHeight;
1038 windowChanges.width = pcd->clientWidth;
1039 windowChanges.height = pcd->clientHeight;
1042 * strip off previous window border if we're adding our own border
1045 if ( (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)) ||
1046 (pcd->matteWidth > 0) )
1048 mask |= CWBorderWidth;
1049 windowChanges.border_width = 0;
1052 XConfigureWindow (DISPLAY, pcd->client, mask, &windowChanges);
1055 /* shape our frame to match that of the client's window */
1058 int xws, yws, xbs, ybs;
1059 unsigned wws, hws, wbs, hbs;
1060 int boundingShaped, clipShaped;
1062 XShapeSelectInput (DISPLAY, pcd->client, ShapeNotifyMask);
1063 XShapeQueryExtents (DISPLAY, pcd->client,
1064 &boundingShaped, &xws, &yws, &wws, &hws,
1065 &clipShaped, &xbs, &ybs, &wbs, &hbs);
1066 pcd->wShaped = boundingShaped;
1068 #endif /* NO_SHAPE */
1069 /* reparent the window to the base window */
1071 XReparentWindow (DISPLAY, pcd->client, pcd->clientBaseWin,
1074 pcd->clientFlags |= CLIENT_REPARENTED;
1076 } /* END OF FUNCTION AdoptClient */
1080 /*************************************<->*************************************
1082 * GetTextBox (pcd, pBox)
1087 * Gets the rectangle that the text should fit into in the title bar
1092 * pcd - pointer to client data
1093 * pBox - pointer to an XRectangle structure that gets return data
1097 * pBox - data is returned here
1102 *************************************<->***********************************/
1104 void GetTextBox (ClientData *pcd, XRectangle *pBox)
1107 unsigned int width,height;
1108 #if defined(WSM) && defined(DT_LEFT_JUSTIFIED_TITLE)
1109 Dimension textWidth;
1111 XmFontList fontList;
1114 /* get size of title area */
1116 if (!GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height))
1118 /* no title area !!! */
1126 /* adjust for shadowing and allow for some padding around the edges */
1127 x += WM_TOP_TITLE_SHADOW + WM_TOP_TITLE_PADDING;
1128 y += WM_TOP_TITLE_SHADOW + WM_TOP_TITLE_PADDING;
1130 width -= WM_TOP_TITLE_SHADOW + WM_BOTTOM_TITLE_SHADOW +
1131 WM_TOP_TITLE_PADDING + WM_BOTTOM_TITLE_PADDING;
1132 height -= WM_TOP_TITLE_SHADOW + WM_BOTTOM_TITLE_SHADOW +
1133 WM_TOP_TITLE_PADDING + WM_BOTTOM_TITLE_PADDING;
1135 #ifdef DT_LEFT_JUSTIFIED_TITLE
1136 if (wmGD.frameStyle == WmSLAB)
1139 * We left justify the title in this style.
1140 * To keep it a little neat, we offset the title from
1141 * the left edge just a little (half the title height).
1142 * See if we have room to do this.
1144 if (DECOUPLE_TITLE_APPEARANCE(pcd))
1145 fontList = CLIENT_TITLE_APPEARANCE(pcd).fontList;
1147 fontList = CLIENT_APPEARANCE(pcd).fontList;
1148 textWidth = XmStringWidth(fontList, pcd->clientTitle);
1150 offset = TitleBarHeight(pcd)/2;
1152 if ((textWidth + offset) <= width)
1154 /* We have plenty of room, do the offset */
1158 else if ((short) (width - textWidth) > 0)
1160 /* We don't have enough room to do our usual offset,
1161 * but if we reduce the offset, the text won't get
1164 offset = (width - textWidth) / 2;
1170 #endif /* DT_LEFT_JUSTIFIED_TITLE */
1171 /* return position and size */
1174 pBox->width = width;
1175 pBox->height = height;
1182 /*************************************<->*************************************
1184 * DrawWindowTitle (pcd, eraseFirst)
1189 * Overwrites or replaces the client's title text in the
1190 * title bar of the frame.
1195 * pcd - pointer to client data
1196 * eraseFirst - if true, then the old title is erased first
1204 * o Assumes 8-bit text for now.
1207 *************************************<->***********************************/
1209 void DrawWindowTitle (ClientData *pcd, Boolean eraseFirst)
1212 unsigned long decoration = pcd->decor;
1215 XmFontList fontList;
1217 /* make sure there is a title bar first */
1218 if (!(decoration & MWM_DECOR_TITLE))
1221 if (DECOUPLE_TITLE_APPEARANCE(pcd))
1223 /* use "active" GC if we have keyboard focus */
1224 if (pcd == wmGD.keyboardFocus) {
1225 clientGC = CLIENT_TITLE_APPEARANCE(pcd).activeGC;
1228 clientGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveGC;
1231 /* get the area that the text must fit in */
1232 GetTextBox (pcd, &textBox);
1234 /* adjust position to be relative to titlebar window, not frame */
1235 textBox.x -= (short) pcd->frameInfo.upperBorderWidth;
1236 textBox.y -= (short) pcd->frameInfo.upperBorderWidth;
1238 win = pcd->clientTitleWin;
1239 fontList = CLIENT_TITLE_APPEARANCE(pcd).fontList;
1243 /* use "active" GC if we have keyboard focus */
1244 if (pcd == wmGD.keyboardFocus) {
1245 clientGC = CLIENT_APPEARANCE(pcd).activeGC;
1248 clientGC = CLIENT_APPEARANCE(pcd).inactiveGC;
1251 /* get the area that the text must fit in */
1252 GetTextBox (pcd, &textBox);
1253 win = pcd->clientFrameWin;
1254 fontList = CLIENT_APPEARANCE(pcd).fontList;
1259 XClearArea (DISPLAY, win, textBox.x, textBox.y,
1260 (unsigned int) textBox.width, (unsigned int) textBox.height,
1264 #ifdef DT_LEFT_JUSTIFIED_TITLE
1265 WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1266 textBox.x, textBox.y, textBox.width, &textBox,
1267 ((wmGD.frameStyle == WmSLAB) ? False : True));
1268 #else /* DT_LEFT_JUSTIFIED_TITLE */
1270 WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1271 textBox.x, textBox.y, textBox.width, &textBox,
1274 WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1275 textBox.x, textBox.y, textBox.width, &textBox);
1277 #endif /* DT_LEFT_JUSTIFIED_TITLE */
1281 } /* END OF FUNCTION DrawWindowTitle */
1285 /*************************************<->*************************************
1287 * CreateStretcherWindows (pcd)
1292 * Create the input-only windows that overlay the resize gadgets.
1297 * pcd - pointer to client data.
1309 * o The windows are sized based upon resizeBorderWidth
1310 * o This should be called before creating the title bar,
1311 * and reparenting window. Later windows should obscure parts of the
1313 * o The stretchers are given special cursors.
1315 *************************************<->***********************************/
1317 void CreateStretcherWindows (ClientData *pcd)
1321 unsigned int width, height;
1322 XSetWindowAttributes win_attribs;
1323 unsigned long attr_mask;
1325 for (iWin = 0; iWin < STRETCH_COUNT; iWin++) {
1327 case STRETCH_NORTH_WEST:
1328 GetFramePartInfo (pcd, FRAME_RESIZE_NW,
1329 &x, &y, &width, &height);
1333 GetFramePartInfo (pcd, FRAME_RESIZE_N,
1334 &x, &y, &width, &height);
1337 case STRETCH_NORTH_EAST:
1338 GetFramePartInfo (pcd, FRAME_RESIZE_NE,
1339 &x, &y, &width, &height);
1343 GetFramePartInfo (pcd, FRAME_RESIZE_E,
1344 &x, &y, &width, &height);
1347 case STRETCH_SOUTH_EAST:
1348 GetFramePartInfo (pcd, FRAME_RESIZE_SE,
1349 &x, &y, &width, &height);
1353 GetFramePartInfo (pcd, FRAME_RESIZE_S,
1354 &x, &y, &width, &height);
1357 case STRETCH_SOUTH_WEST:
1358 GetFramePartInfo (pcd, FRAME_RESIZE_SW,
1359 &x, &y, &width, &height);
1363 GetFramePartInfo (pcd, FRAME_RESIZE_W,
1364 &x, &y, &width, &height);
1368 attr_mask = CWCursor;
1369 win_attribs.cursor = wmGD.stretchCursors[iWin];
1371 pcd->clientStretchWin[iWin] =
1372 XCreateWindow(DISPLAY, pcd->clientFrameWin,
1373 x, y, width, height, 0, CopyFromParent,
1374 InputOnly, CopyFromParent, attr_mask, &win_attribs);
1376 } /* END OF FUNCTION CreateStretcherWindows */
1380 /*************************************<->*************************************
1382 * CountFrameRectangles (pSD)
1387 * Computes the number of top and bottom shadow rectangles to allocate
1392 * pWS - pointer to workspace data
1401 *************************************<->***********************************/
1403 void CountFrameRectangles (WmScreenData *pSD)
1407 pSD->Num_Title_Ts_Elements = pSD->Num_Title_Bs_Elements = 0;
1409 /* count up rectangles for title bar */
1410 for (i = FRAME_SYSTEM; i <= FRAME_MAXIMIZE; i++)
1412 pSD->Num_Title_Ts_Elements += ((Bevels[i].top.external *
1413 pSD->externalBevel) +
1414 (Bevels[i].top.internal * MAX_INTERNAL_BEVEL) +
1415 (Bevels[i].top.join * pSD->joinBevel));
1417 pSD->Num_Title_Bs_Elements += ((Bevels[i].bottom.external*
1418 pSD->externalBevel)+
1419 (Bevels[i].bottom.internal * MAX_INTERNAL_BEVEL) +
1420 (Bevels[i].bottom.join * pSD->joinBevel));
1423 pSD->Num_Resize_Ts_Elements = pSD->Num_Resize_Bs_Elements = 0;
1425 /* count up rectangles for resize handles*/
1426 for (i = FRAME_RESIZE_NW; i <= FRAME_RESIZE_W; i++)
1428 pSD->Num_Resize_Ts_Elements += ((Bevels[i].top.external *
1429 pSD->externalBevel) +
1430 (Bevels[i].top.internal * MAX_INTERNAL_BEVEL) +
1431 (Bevels[i].top.join * pSD->joinBevel));
1433 pSD->Num_Resize_Bs_Elements += ((Bevels[i].bottom.external*
1434 pSD->externalBevel)+
1435 (Bevels[i].bottom.internal * MAX_INTERNAL_BEVEL) +
1436 (Bevels[i].bottom.join * pSD->joinBevel));
1438 } /* END OF FUNCTION CountFrameRectangles */
1442 /*************************************<->*************************************
1444 * AllocateFrameDisplayLists (pcd)
1449 * Allocates memory for the graphic display lists for the frame.
1454 * pcd - pointer to the client data
1459 * pcd - fields modified
1461 * Return - TRUE if successful, FALSE otherwise.
1468 *************************************<->***********************************/
1470 Boolean AllocateFrameDisplayLists (ClientData *pcd)
1472 int frame_top_count, frame_bottom_count;
1475 * If the title bar has it's own appearance, then allocate
1476 * separate display lists for it.
1478 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
1479 (pcd->decor & MWM_DECOR_TITLE))
1481 if (((pcd->pclientTitleTopShadows =
1482 AllocateRList ((unsigned)NUM_TITLE_TS_ELEMENTS(pcd))) == NULL) ||
1483 ((pcd->pclientTitleBottomShadows =
1484 AllocateRList ((unsigned)NUM_TITLE_BS_ELEMENTS(pcd))) == NULL))
1486 /* out of memory! */
1487 Warning (((char *)GETMESSAGE(8, 1, "Insufficient memory for client window framing")));
1491 frame_top_count = NUM_RESIZE_TS_ELEMENTS(pcd);
1492 frame_bottom_count = NUM_RESIZE_BS_ELEMENTS(pcd);
1496 frame_top_count = NUM_RESIZE_TS_ELEMENTS(pcd) +
1497 NUM_TITLE_TS_ELEMENTS(pcd);
1498 frame_bottom_count = NUM_RESIZE_BS_ELEMENTS(pcd) +
1499 NUM_RESIZE_BS_ELEMENTS(pcd);
1503 * Allocate the primary lists for the frame
1505 if ( (pcd->pclientTopShadows == NULL) &&
1506 ((pcd->pclientTopShadows =
1507 AllocateRList ((unsigned)frame_top_count)) == NULL) )
1509 /* out of memory! */
1510 Warning (((char *)GETMESSAGE(8, 2, "Insufficient memory for client window framing")));
1514 if ( (pcd->pclientBottomShadows == NULL) &&
1515 ((pcd->pclientBottomShadows =
1516 AllocateRList ((unsigned)frame_bottom_count)) == NULL) )
1518 /* out of memory! */
1519 Warning (((char *)GETMESSAGE(8, 3, "Insufficient memory for client window framing")));
1524 * Only allocate matte lists if there is a matte.
1526 if ( (pcd->matteWidth) &&
1527 (pcd->pclientMatteTopShadows == NULL) &&
1528 ((pcd->pclientMatteTopShadows =
1529 AllocateRList ((unsigned)NUM_MATTE_TS_RECTS)) == NULL))
1531 /* out of memory! */
1532 Warning (((char *)GETMESSAGE(8, 4, "Insufficient memory for client window framing")));
1536 if ( (pcd->matteWidth) &&
1537 (pcd->pclientMatteBottomShadows == NULL) &&
1538 ((pcd->pclientMatteBottomShadows =
1539 AllocateRList ((unsigned)NUM_MATTE_BS_RECTS)) == NULL))
1541 /* out of memory! */
1542 Warning (((char *)GETMESSAGE(8, 5, "Insufficient memory for client window framing")));
1547 } /* END OF FUNCTION AllocateFrameDisplayLists */
1550 /*************************************<->*************************************
1552 * InitClientDecoration (pSD)
1557 * Initializes client decoration routines
1562 * pSD - pointer to screen data
1570 * This must be called once before decorating any client frames.
1571 *************************************<->***********************************/
1573 void InitClientDecoration (WmScreenData *pSD)
1575 CountFrameRectangles(pSD);
1576 } /* END OF FUNCTION InitClientDecoration */
1580 /*************************************<->*************************************
1582 * AllocateGadgetRectangles (pcd)
1587 * Allocate the memory for event rectangles structures.
1592 * pcd - pointer to client data structure
1602 *************************************<->***********************************/
1604 Boolean AllocateGadgetRectangles (ClientData *pcd)
1607 unsigned long decor = pcd->decor;
1608 GadgetRectangle *pgr;
1610 if (decor & MWM_DECOR_TITLE) {
1612 /* count how many rectangles to allocate for titlebar */
1614 if (decor & MWM_DECOR_MENU) num_rects += 1;
1615 if (decor & MWM_DECOR_MINIMIZE) num_rects += 1;
1616 if (decor & MWM_DECOR_MAXIMIZE) num_rects += 1;
1618 /* allocate memory if no memory is allocated */
1619 if ( pcd->pTitleGadgets == NULL) {
1620 /* allocate memory for these guys */
1621 pgr = (GadgetRectangle *)
1622 XtMalloc (num_rects * sizeof(GadgetRectangle));
1625 /* out of memory! */
1626 Warning (((char *)GETMESSAGE(8, 6, "Insufficient memory for client window framing")));
1630 /* update client data */
1631 pcd->pTitleGadgets = pgr;
1632 pcd->cTitleGadgets = 0;
1636 if (decor & MWM_DECOR_RESIZEH) {
1638 /* allocate memory if no memory is allocated */
1639 if ( pcd->pResizeGadgets == NULL) {
1640 /* allocate memory for these guys */
1641 pgr = (GadgetRectangle *)
1642 XtMalloc (STRETCH_COUNT * sizeof(GadgetRectangle));
1645 /* out of memory! */
1646 Warning (((char *)GETMESSAGE(8, 7, "Insufficient memory for client window framing")));
1650 /* update client data */
1651 pcd->pResizeGadgets = pgr;
1655 } /* END OF FUNCTION AllocateGadgetRectangles */
1658 /*************************************<->*************************************
1660 * ComputeGadgetRectangles (pcd)
1665 * Creates the event rectangles structures to aid in identifying
1666 * frame parts when events come in
1671 * pcd - pointer to client data structure
1680 * o assumes gadget rectangles are already allocated.
1682 *************************************<->***********************************/
1684 void ComputeGadgetRectangles (ClientData *pcd)
1686 unsigned long decor = pcd->decor;
1687 GadgetRectangle *pgr;
1689 unsigned int fpWidth, fpHeight;
1691 int clientWidth = (pcd->maxConfig) ? pcd->maxWidth : pcd->clientWidth;
1696 if (decor & MWM_DECOR_TITLE) {
1698 if ( (pgr = pcd->pTitleGadgets) == NULL) {
1699 return; /* nothing there !!! */
1702 /* do title rectangle */
1703 pcd->titleRectangle.x = pcd->frameInfo.upperBorderWidth;
1704 pcd->titleRectangle.y = pcd->frameInfo.upperBorderWidth;
1707 * Fixed bug where last button in title bar did not activate when
1708 * the client's X border was showing.
1710 pcd->titleRectangle.width = clientWidth +
1711 (XBorderIsShowing(pcd) ? 2*pcd->xBorderWidth : 2*pcd->matteWidth);
1712 pcd->titleRectangle.height = pcd->frameInfo.titleBarHeight;
1714 /* fill in title bar rectangles */
1717 pgr[igr].id = FRAME_TITLE;
1718 GetFramePartInfo (pcd, FRAME_TITLE, &fpX, &fpY, &fpWidth, &fpHeight);
1720 /* copy in and convert to shorts */
1721 pgr[igr].rect.x = fpX;
1722 pgr[igr].rect.y = fpY;
1723 pgr[igr].rect.width = fpWidth;
1724 pgr[igr].rect.height = fpHeight;
1727 if (decor & MWM_DECOR_MENU) {
1728 pgr[igr].id = FRAME_SYSTEM;
1729 GetFramePartInfo (pcd, FRAME_SYSTEM, &fpX, &fpY, &fpWidth,
1732 /* copy in and convert to shorts */
1733 pgr[igr].rect.x = fpX;
1734 pgr[igr].rect.y = fpY;
1735 pgr[igr].rect.width = fpWidth;
1736 pgr[igr].rect.height = fpHeight;
1740 if (decor & MWM_DECOR_MINIMIZE) {
1741 pgr[igr].id = FRAME_MINIMIZE;
1742 GetFramePartInfo (pcd, FRAME_MINIMIZE,
1743 &fpX, &fpY, &fpWidth, &fpHeight);
1744 /* copy in and convert to shorts */
1745 pgr[igr].rect.x = fpX;
1746 pgr[igr].rect.y = fpY;
1747 pgr[igr].rect.width = fpWidth;
1748 pgr[igr].rect.height = fpHeight;
1752 if (decor & MWM_DECOR_MAXIMIZE) {
1753 pgr[igr].id = FRAME_MAXIMIZE;
1754 GetFramePartInfo (pcd, FRAME_MAXIMIZE,
1755 &fpX, &fpY, &fpWidth, &fpHeight);
1756 /* copy in and convert to shorts */
1757 pgr[igr].rect.x = fpX;
1758 pgr[igr].rect.y = fpY;
1759 pgr[igr].rect.width = fpWidth;
1760 pgr[igr].rect.height = fpHeight;
1764 /* update client data */
1765 pcd->pTitleGadgets = pgr;
1766 pcd->cTitleGadgets = igr;
1769 /* client matte area (actually base window area) */
1771 if (decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
1773 pcd->matteRectangle.x = pcd->frameInfo.lowerBorderWidth;
1774 pcd->matteRectangle.y = pcd->frameInfo.upperBorderWidth +
1775 pcd->frameInfo.titleBarHeight;
1776 pcd->matteRectangle.width = pcd->frameInfo.width -
1777 (2 * pcd->frameInfo.lowerBorderWidth);
1778 pcd->matteRectangle.height = pcd->frameInfo.height -
1779 pcd->frameInfo.upperBorderWidth -
1780 pcd->frameInfo.lowerBorderWidth -
1781 pcd->frameInfo.titleBarHeight;
1785 pcd->matteRectangle.x = 0;
1786 pcd->matteRectangle.y = pcd->frameInfo.titleBarHeight;
1787 pcd->matteRectangle.width = pcd->frameInfo.width;
1788 pcd->matteRectangle.height = pcd->frameInfo.height -
1789 pcd->frameInfo.titleBarHeight;
1792 if (decor & MWM_DECOR_RESIZEH) {
1794 if ( (pgr = pcd->pResizeGadgets) == NULL) {
1795 return; /* nothing there !!! */
1798 /* fill in resize rectangles */
1800 if (decor & MWM_DECOR_RESIZEH) {
1802 pgr[igr].id = FRAME_RESIZE_NW;
1803 GetFramePartInfo (pcd, FRAME_RESIZE_NW,
1804 &fpX, &fpY, &fpWidth, &fpHeight);
1805 /* copy in and convert to shorts */
1806 pgr[igr].rect.x = fpX;
1807 pgr[igr].rect.y = fpY;
1808 pgr[igr].rect.width = fpWidth;
1809 pgr[igr].rect.height = fpHeight;
1812 pgr[igr].id = FRAME_RESIZE_N;
1813 GetFramePartInfo (pcd, FRAME_RESIZE_N,
1814 &fpX, &fpY, &fpWidth, &fpHeight);
1815 if ((int) fpWidth > 0) {
1816 /* copy in and convert to shorts */
1817 pgr[igr].rect.x = fpX;
1818 pgr[igr].rect.y = fpY;
1819 pgr[igr].rect.width = fpWidth;
1820 pgr[igr].rect.height = fpHeight;
1824 pgr[igr].id = FRAME_RESIZE_NE;
1825 GetFramePartInfo (pcd, FRAME_RESIZE_NE,
1826 &fpX, &fpY, &fpWidth, &fpHeight);
1827 /* copy in and convert to shorts */
1828 pgr[igr].rect.x = fpX;
1829 pgr[igr].rect.y = fpY;
1830 pgr[igr].rect.width = fpWidth;
1831 pgr[igr].rect.height = fpHeight;
1834 pgr[igr].id = FRAME_RESIZE_W;
1835 GetFramePartInfo (pcd, FRAME_RESIZE_W,
1836 &fpX, &fpY, &fpWidth, &fpHeight);
1837 if ((int)fpHeight > 0) {
1838 /* copy in and convert to shorts */
1839 pgr[igr].rect.x = fpX;
1840 pgr[igr].rect.y = fpY;
1841 pgr[igr].rect.width = fpWidth;
1842 pgr[igr].rect.height = fpHeight;
1846 pgr[igr].id = FRAME_RESIZE_E;
1847 GetFramePartInfo (pcd, FRAME_RESIZE_E,
1848 &fpX, &fpY, &fpWidth, &fpHeight);
1849 if ((int) fpHeight > 0) {
1850 /* copy in and convert to shorts */
1851 pgr[igr].rect.x = fpX;
1852 pgr[igr].rect.y = fpY;
1853 pgr[igr].rect.width = fpWidth;
1854 pgr[igr].rect.height = fpHeight;
1858 pgr[igr].id = FRAME_RESIZE_SW;
1859 GetFramePartInfo (pcd, FRAME_RESIZE_SW,
1860 &fpX, &fpY, &fpWidth, &fpHeight);
1861 /* copy in and convert to shorts */
1862 pgr[igr].rect.x = fpX;
1863 pgr[igr].rect.y = fpY;
1864 pgr[igr].rect.width = fpWidth;
1865 pgr[igr].rect.height = fpHeight;
1868 pgr[igr].id = FRAME_RESIZE_S;
1869 GetFramePartInfo (pcd, FRAME_RESIZE_S,
1870 &fpX, &fpY, &fpWidth, &fpHeight);
1871 if ((int) fpWidth > 0) {
1872 /* copy in and convert to shorts */
1873 pgr[igr].rect.x = fpX;
1874 pgr[igr].rect.y = fpY;
1875 pgr[igr].rect.width = fpWidth;
1876 pgr[igr].rect.height = fpHeight;
1880 pgr[igr].id = FRAME_RESIZE_SE;
1881 GetFramePartInfo (pcd, FRAME_RESIZE_SE,
1882 &fpX, &fpY, &fpWidth, &fpHeight);
1883 /* copy in and convert to shorts */
1884 pgr[igr].rect.x = fpX;
1885 pgr[igr].rect.y = fpY;
1886 pgr[igr].rect.width = fpWidth;
1887 pgr[igr].rect.height = fpHeight;
1890 /* update client data */
1891 pcd->pResizeGadgets = pgr;
1894 } /* END OF FUNCTION ComputeGadgetRectangles */
1898 /*************************************<->*************************************
1900 * GetSystemMenuPosition (pcd, px, py, height, context)
1905 * Returns the position of where the system menu should be popped up.
1906 * The hotspotRectangle in global is also set up to match the icon or
1907 * system menu button area.
1912 * pcd = pointer to client data
1914 * px = pointer to x location
1916 * py = pointer to y location
1918 * height = height of the system menu
1920 * context = context that the menu is to be posted under.
1929 * wmGD.hotspotRectangle = system menu button or icon area (root relative)
1931 *************************************<->***********************************/
1933 void GetSystemMenuPosition (ClientData *pcd, int *px, int *py,
1934 unsigned int height, Context context)
1937 if ((pcd->clientState == MINIMIZED_STATE) ||
1938 ((pcd->clientState != MINIMIZED_STATE) &&
1939 (context == F_SUBCONTEXT_IB_WICON)))
1942 * Try to put the menu directly above the icon.
1943 * If it would hit the top of the screen then try to put it below
1944 * the icon and label.
1945 * If it would then hit the bottom of the screen turn of the hotspot
1950 if (pcd->pSD->useIconBox && P_ICON_BOX(pcd))
1952 GetIconBoxIconRootXY (pcd, px, py);
1954 wmGD.hotspotRectangle.x = *px;
1955 wmGD.hotspotRectangle.y = *py;
1961 *py += height + ICON_HEIGHT(pcd);
1962 if (*py + height >= DisplayHeight (DISPLAY,
1963 SCREEN_FOR_CLIENT(pcd)))
1965 wmGD.checkHotspot = FALSE;
1972 *py = ICON_Y(pcd) - height;
1976 *py = ICON_Y(pcd) + ICON_HEIGHT(pcd);
1977 if (*py + height >= DisplayHeight (DISPLAY,
1978 SCREEN_FOR_CLIENT(pcd)))
1980 wmGD.checkHotspot = FALSE;
1984 wmGD.hotspotRectangle.x = ICON_X(pcd);
1985 wmGD.hotspotRectangle.y = ICON_Y(pcd);
1988 /* setup the hotspot rectangle data */
1990 wmGD.hotspotRectangle.width = ICON_WIDTH(pcd);
1991 wmGD.hotspotRectangle.height = ICON_HEIGHT(pcd);
1996 * Try to put the menu directly below the SW corner of the
1998 * If it would hit the bottom of the screen then try to put it directly
1999 * above the NW corner of the titlebar/border.
2000 * If it would then hit the top of the screen turn of the hotspot
2004 if ((pcd->decor & MWM_DECOR_TITLE) &&
2005 !(pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)))
2007 *px = pcd->frameInfo.x;
2008 *py = pcd->frameInfo.y + pcd->frameInfo.titleBarHeight;
2012 *px = pcd->frameInfo.x + pcd->frameInfo.lowerBorderWidth;
2013 *py = pcd->frameInfo.y + pcd->frameInfo.upperBorderWidth +
2014 pcd->frameInfo.titleBarHeight;
2016 if (*py + height >= DisplayHeight (DISPLAY,
2017 SCREEN_FOR_CLIENT(pcd)))
2019 if ((pcd->decor & MWM_DECOR_TITLE) &&
2020 !(pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)))
2022 *py = pcd->frameInfo.y - height;
2026 *py = pcd->frameInfo.y + pcd->frameInfo.upperBorderWidth -
2031 wmGD.checkHotspot = FALSE;
2035 /* setup the hotspot rectangle data */
2037 wmGD.hotspotRectangle.x = pcd->frameInfo.x +
2038 pcd->frameInfo.lowerBorderWidth;
2039 wmGD.hotspotRectangle.y = pcd->frameInfo.y +
2040 pcd->frameInfo.upperBorderWidth;
2042 /* assume square button */
2043 wmGD.hotspotRectangle.width = pcd->frameInfo.titleBarHeight;
2044 wmGD.hotspotRectangle.height = pcd->frameInfo.titleBarHeight;
2047 } /* END OF FUNCTION GetSystemMenuPosition */
2051 /*************************************<->*************************************
2053 * ShowActiveClientFrame (pcd)
2058 * Paint the frame to indicate an "active" window
2063 * pcd - pointer to client data
2072 * o This calls the frame exposure procedure, which gets some GCs based
2073 * on the current keyboard focus. Thus, wmGD.keyboardFocus == pcd
2074 * must be TRUE when this is called for the correct highlighting to
2077 *************************************<->***********************************/
2080 ShowActiveClientFrame (ClientData *pcd)
2082 unsigned long attr_mask = 0;
2083 XSetWindowAttributes window_attribs;
2085 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
2086 (pcd->decor & MWM_DECOR_TITLE))
2089 * Use background pixmap if one is specified, otherwise set the
2090 * appropriate background color.
2093 if (CLIENT_TITLE_APPEARANCE(pcd).activeBackgroundPixmap)
2095 attr_mask |= CWBackPixmap;
2096 window_attribs.background_pixmap =
2097 CLIENT_TITLE_APPEARANCE(pcd).activeBackgroundPixmap;
2101 attr_mask |= CWBackPixel;
2102 window_attribs.background_pixel =
2103 CLIENT_TITLE_APPEARANCE(pcd).activeBackground;
2107 XChangeWindowAttributes (DISPLAY, pcd->clientTitleWin, attr_mask,
2110 /* clear the frame to the right background */
2111 XClearWindow (DISPLAY, pcd->clientTitleWin);
2115 * Use background pixmap if one is specified, otherwise set the
2116 * appropriate background color.
2119 if (CLIENT_APPEARANCE(pcd).activeBackgroundPixmap)
2121 attr_mask |= CWBackPixmap;
2122 window_attribs.background_pixmap =
2123 CLIENT_APPEARANCE(pcd).activeBackgroundPixmap;
2127 attr_mask |= CWBackPixel;
2128 window_attribs.background_pixel =
2129 CLIENT_APPEARANCE(pcd).activeBackground;
2133 XChangeWindowAttributes (DISPLAY, pcd->clientFrameWin, attr_mask,
2136 /* clear the frame to the right background */
2137 XClearWindow (DISPLAY, pcd->clientFrameWin);
2139 /* simulate exposure of window */
2140 FrameExposureProc (pcd);
2143 } /* END OF FUNCTION ShowActiveClient */
2147 /*************************************<->*************************************
2149 * ShowInactiveClientFrame (pcd)
2154 * Paint the frame to indicate an "inactive" window
2159 * pcd - pointer to client data
2168 * o This calls the frame exposure procedure, which gets some GCs based
2169 * on the current keyboard focus. Thus, wmGD.keyboardFocus == pcd
2170 * must be FALSE when this is called for the correct highlighting to
2174 ******************************<->***********************************/
2177 ShowInactiveClientFrame (ClientData *pcd)
2179 unsigned long attr_mask = 0;
2180 XSetWindowAttributes window_attribs;
2182 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
2183 (pcd->decor & MWM_DECOR_TITLE))
2186 * Use background pixmap if one is specified, otherwise set the
2187 * appropriate background color.
2190 if (CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap)
2192 attr_mask |= CWBackPixmap;
2193 window_attribs.background_pixmap =
2194 CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap;
2198 attr_mask |= CWBackPixel;
2199 window_attribs.background_pixel =
2200 CLIENT_TITLE_APPEARANCE(pcd).background;
2204 XChangeWindowAttributes (DISPLAY, pcd->clientTitleWin, attr_mask,
2207 /* clear the frame to the right background */
2208 XClearWindow (DISPLAY, pcd->clientTitleWin);
2211 * attr_mask must be cleared because it is set if
2212 * DECOUPLE_TITLE_APPEARANCE(pcd) is true.
2218 * Use background pixmap if one is specified, otherwise set the
2219 * appropriate background color.
2222 if (CLIENT_APPEARANCE(pcd).backgroundPixmap)
2224 attr_mask |= CWBackPixmap;
2225 window_attribs.background_pixmap =
2226 CLIENT_APPEARANCE(pcd).backgroundPixmap;
2230 attr_mask |= CWBackPixel;
2231 window_attribs.background_pixel =
2232 CLIENT_APPEARANCE(pcd).background;
2236 /* change window attribs so clear does the right thing */
2237 XChangeWindowAttributes (DISPLAY, pcd->clientFrameWin, attr_mask,
2240 /* clear the frame to the right background */
2241 XClearWindow (DISPLAY, pcd->clientFrameWin);
2243 /* simulate exposure of window */
2244 FrameExposureProc (pcd);
2246 } /* END OF FUNCTION ShowInactiveClientFrame */
2250 /*************************************<->*************************************
2252 * RegenerateClientFrame (pcd)
2257 * Reconfigure the sizes of all the components of the client frame
2262 * pcd - pointer to client data
2272 *************************************<->***********************************/
2274 void RegenerateClientFrame (ClientData *pcd)
2276 unsigned long decor = pcd->decor;
2278 * If an embedded client, there is no frame.
2282 if (!pcd->clientFrameWin)
2288 /* recompute frame information */
2291 /* move & resize frame window */
2292 XMoveResizeWindow (DISPLAY, pcd->clientFrameWin, pcd->frameInfo.x,
2293 pcd->frameInfo.y, pcd->frameInfo.width, pcd->frameInfo.height);
2296 /* resize title bar window */
2297 if (decor & MWM_DECOR_TITLE)
2299 XResizeWindow (DISPLAY, pcd->clientTitleWin,
2300 pcd->frameInfo.width - 2*pcd->frameInfo.upperBorderWidth,
2301 pcd->frameInfo.titleBarHeight);
2304 /* resize base window */
2305 XResizeWindow (DISPLAY, pcd->clientBaseWin, BaseWindowWidth (pcd),
2306 BaseWindowHeight (pcd));
2308 /* resize the stretcher windows */
2309 if (SHOW_RESIZE_CURSORS(pcd) && (decor & MWM_DECOR_RESIZEH)) {
2310 XMoveResizeWindow (DISPLAY,
2311 pcd->clientStretchWin[STRETCH_NORTH_WEST],
2312 0, 0, pcd->frameInfo.cornerWidth,
2313 pcd->frameInfo.cornerHeight);
2315 XMoveResizeWindow (DISPLAY,
2316 pcd->clientStretchWin[STRETCH_NORTH],
2317 (int) pcd->frameInfo.cornerWidth, 0,
2318 pcd->frameInfo.width - 2*pcd->frameInfo.cornerWidth,
2319 pcd->frameInfo.upperBorderWidth);
2321 XMoveResizeWindow (DISPLAY,
2322 pcd->clientStretchWin[STRETCH_NORTH_EAST],
2323 (int) (pcd->frameInfo.width - pcd->frameInfo.cornerWidth), 0,
2324 pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2326 XMoveResizeWindow (DISPLAY,
2327 pcd->clientStretchWin[STRETCH_EAST],
2328 (int) (pcd->frameInfo.width - pcd->frameInfo.lowerBorderWidth),
2329 (int) (pcd->frameInfo.cornerHeight),
2330 pcd->frameInfo.lowerBorderWidth,
2331 pcd->frameInfo.height - 2*pcd->frameInfo.cornerHeight);
2333 XMoveResizeWindow (DISPLAY,
2334 pcd->clientStretchWin[STRETCH_SOUTH_EAST],
2335 (int) (pcd->frameInfo.width - pcd->frameInfo.cornerWidth),
2336 (int) (pcd->frameInfo.height - pcd->frameInfo.cornerHeight),
2337 pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2339 XMoveResizeWindow (DISPLAY,
2340 pcd->clientStretchWin[STRETCH_SOUTH],
2341 (int) pcd->frameInfo.cornerWidth,
2342 (int) (pcd->frameInfo.height - pcd->frameInfo.lowerBorderWidth),
2343 pcd->frameInfo.width - 2*pcd->frameInfo.cornerWidth,
2344 pcd->frameInfo.lowerBorderWidth);
2346 XMoveResizeWindow (DISPLAY,
2347 pcd->clientStretchWin[STRETCH_SOUTH_WEST],
2348 0, (int) (pcd->frameInfo.height - pcd->frameInfo.cornerHeight),
2349 pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2351 XMoveResizeWindow (DISPLAY,
2352 pcd->clientStretchWin[STRETCH_WEST],
2353 0, (int) pcd->frameInfo.cornerHeight,
2354 pcd->frameInfo.lowerBorderWidth,
2355 pcd->frameInfo.height - 2*pcd->frameInfo.cornerHeight);
2358 /* recreate gadget rectangles */
2359 ComputeGadgetRectangles (pcd);
2361 /* regenerate the graphics */
2362 GenerateFrameDisplayLists (pcd);
2365 if (wmGD.hasShape && pcd->wShaped)
2367 SetFrameShape (pcd);
2369 #endif /* NO_SHAPE */
2371 } /* END OF FUNCTION RegenerateClientFrame */
2376 /*************************************<->*************************************
2378 * BevelSystemButton (prTop, prBot, x, y, width, height)
2383 * Bevels a rectangle for the system button (drawer handle?)
2388 * prTop - ptr to top shadow rectangles
2389 * prBot - ptr to bottom shadow rectangles
2390 * x - x coord of maximize gadget
2391 * y - y coord of maximize gadget
2392 * width - width of maximize gadget
2393 * height - height of maximize gadget
2402 * o This draws a horizontal "drawer handle" for the system gadget.
2403 * Assumptions: the enclosing box is square (width == height)
2404 *************************************<->***********************************/
2406 void BevelSystemButton (RList *prTop, RList *prBot, int x, int y,
2407 unsigned int width, unsigned int height)
2409 int offset1, offset2;
2410 unsigned int dim1, dim2;
2415 offset1 = offset2 = 2;
2416 dim1 = dim2 = height-4;
2420 offset1 = offset2 = 2;
2444 offset2 = (height-3)/2;
2451 offset2 = (height - 4)/2;
2460 BevelRectangle (prTop, prBot, /* system icon */
2461 (x+offset1), (y+offset2),
2465 } /* END OF FUNCTION BevelSystemButton */
2469 /*************************************<->*************************************
2471 * BevelMinimizeButton (prTop, prBot, x, y, height)
2476 * Bevels a rectangle for the minimize button
2481 * prTop - ptr to top shadow rectangles
2482 * prBot - ptr to bottom shadow rectangles
2483 * x - x coord of maximize gadget
2484 * y - y coord of maximize gadget
2485 * height - height of maximize gadget
2495 *************************************<->***********************************/
2497 void BevelMinimizeButton (RList *prTop, RList *prBot, int x, int y,
2498 unsigned int height)
2500 int offset1, offset2;
2501 unsigned int dim1, dim2;
2507 offset1 = offset2 = 3;
2508 dim1 = dim2 = height-6;
2514 offset1 = offset2 = (height-3)/2;
2519 offset1 = offset2 = (height-4)/2;
2526 BevelRectangle (prTop, prBot,
2527 (x+offset1), (y+offset2),
2531 } /* END OF FUNCTION BevelMinimizeButton */
2535 /*************************************<->*************************************
2537 * BevelMaximizeButton (prTop, prBot, x, y, height)
2542 * Bevels a rectangle for the maximize button
2547 * prTop - ptr to top shadow rectangles
2548 * prBot - ptr to bottom shadow rectangles
2549 * x - x coord of maximize gadget
2550 * y - y coord of maximize gadget
2551 * height - height of maximize gadget
2561 *************************************<->***********************************/
2563 void BevelMaximizeButton (RList *prTop, RList *prBot, int x, int y,
2564 unsigned int height)
2566 int offset1, offset2;
2567 unsigned int dim1, dim2;
2577 offset1 = offset2 = 2;
2578 dim1 = dim2 = height-4;
2585 offset1 = offset2 = 3;
2586 dim1 = dim2 = height-6;
2590 offset1 = offset2 = 4;
2591 dim1 = dim2 = height-8;
2596 BevelRectangle (prTop, prBot,
2597 (x+offset1), (y+offset2),
2600 } /* END OF FUNCTION BevelMaximizeButton */
2603 /*************************************<->*************************************
2605 * DepressGadget (pcd, gadget, depressed)
2610 * Show the gadget in a "depressed" state
2615 * pcd - pointer to client data
2616 * gadget - gadget id
2617 * depressed - if True, then gadget is shown depressed, if False it is
2618 * shown not depressed
2623 * return - true if sucessful
2628 * o This assumes there is a one-pixel bevel around the gadget.
2629 * o This only works on title bar gadgets.
2631 *************************************<->***********************************/
2633 Boolean DepressGadget (ClientData *pcd, int gadget, Boolean depressed)
2636 unsigned int width, height, invertWidth;
2637 static RList *pTopRect = NULL;
2638 static RList *pBotRect = NULL;
2642 /* get outside dimensions of box we want */
2647 case FRAME_MINIMIZE:
2648 case FRAME_MAXIMIZE:
2649 if (!GetDepressInfo (pcd, gadget, &x, &y, &width,
2650 &height, &invertWidth))
2656 return(FALSE); /* do nothing on non-title bar gagdets */
2659 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
2660 (pcd->decor & MWM_DECOR_TITLE))
2662 /* adjust position to be relative to titlebar window, not frame */
2663 x -= (short) pcd->frameInfo.upperBorderWidth;
2664 y -= (short) pcd->frameInfo.upperBorderWidth;
2666 /* use "active" GCs if we have keyboard focus */
2667 if (pcd == wmGD.keyboardFocus) {
2668 topGC = CLIENT_TITLE_APPEARANCE(pcd).activeTopShadowGC;
2669 botGC = CLIENT_TITLE_APPEARANCE(pcd).activeBottomShadowGC;
2672 topGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveTopShadowGC;
2674 CLIENT_TITLE_APPEARANCE(pcd).inactiveBottomShadowGC;
2677 /* draw into title bar window */
2678 win = pcd->clientTitleWin;
2682 /* use "active" GCs if we have keyboard focus */
2683 if (pcd == wmGD.keyboardFocus) {
2684 topGC = CLIENT_APPEARANCE(pcd).activeTopShadowGC;
2685 botGC = CLIENT_APPEARANCE(pcd).activeBottomShadowGC;
2688 topGC = CLIENT_APPEARANCE(pcd).inactiveTopShadowGC;
2689 botGC = CLIENT_APPEARANCE(pcd).inactiveBottomShadowGC;
2692 /* draw into client frame window */
2693 win = pcd->clientFrameWin;
2697 * Bevel a rectangle for the desired button effect
2698 * Allocate the rectangles if necessary.
2700 if ( (pTopRect && pBotRect) ||
2701 ((pTopRect = AllocateRList(2)) &&
2702 (pBotRect = AllocateRList(2))))
2706 BevelRectangle (pTopRect, pBotRect,
2707 x, y, width, height,
2708 invertWidth, invertWidth,
2709 invertWidth, invertWidth);
2712 /* draw the gadget border to make it look depressed or normal */
2715 XFillRectangles (DISPLAY, win, botGC, pTopRect->prect, pTopRect->used);
2716 XFillRectangles (DISPLAY, win, topGC, pBotRect->prect, pBotRect->used);
2719 XFillRectangles (DISPLAY, win, topGC, pTopRect->prect, pTopRect->used);
2720 XFillRectangles (DISPLAY, win, botGC, pBotRect->prect, pBotRect->used);
2723 } /* END OF FUNCTION DepressGadget */
2726 /*************************************<->*************************************
2728 * PushGadgetIn (pcd, gadget)
2733 * Shows a title bar gadget in a depressed state
2738 * pcd - pointer to client data
2739 * gadget - gadget id
2747 *************************************<->***********************************/
2749 void PushGadgetIn (ClientData *pcd, int gadget)
2753 pcd->decorFlags |= SYSTEM_DEPRESSED;
2757 pcd->decorFlags |= TITLE_DEPRESSED;
2760 case FRAME_MINIMIZE:
2761 pcd->decorFlags |= MINIMIZE_DEPRESSED;
2764 case FRAME_MAXIMIZE:
2765 pcd->decorFlags |= MAXIMIZE_DEPRESSED;
2771 GenerateFrameDisplayLists(pcd);
2772 (void) DepressGadget (pcd, gadget, TRUE);
2773 wmGD.gadgetClient = pcd;
2774 wmGD.gadgetDepressed = gadget;
2775 } /* END OF FUNCTION PushGadgetIn */
2778 /*************************************<->*************************************
2780 * PopGadgetOut (pcd, gadget)
2785 * Shows a title bar gadget in a depressed state
2790 * pcd - pointer to client data
2791 * gadget - gadget id
2799 *************************************<->***********************************/
2801 void PopGadgetOut (ClientData *pcd, int gadget)
2805 pcd->decorFlags &= ~SYSTEM_DEPRESSED;
2809 pcd->decorFlags &= ~TITLE_DEPRESSED;
2812 case FRAME_MINIMIZE:
2813 pcd->decorFlags &= ~MINIMIZE_DEPRESSED;
2816 case FRAME_MAXIMIZE:
2817 pcd->decorFlags &= ~MAXIMIZE_DEPRESSED;
2823 GenerateFrameDisplayLists(pcd);
2824 (void) DepressGadget (pcd, gadget, FALSE);
2825 wmGD.gadgetClient = NULL;
2826 wmGD.gadgetDepressed = 0;
2827 } /* END OF FUNCTION PopGadgetOut */
2831 /*************************************<->*************************************
2833 * SetFrameShape (pcd)
2838 * Shapes the frame and base window to the shape of the client
2839 * window. Also ors the title window into the shaped frame
2840 * window if present.
2844 * pcd - pointer to client data
2851 * o currently punt on resize handle around the frame.
2853 *************************************<->***********************************/
2854 void SetFrameShape (ClientData *pcd)
2857 * The frame consists of the shape of the contents window offset by
2858 * title_height or'ed with the shape of title window (which is always
2864 if (XBorderIsShowing(pcd))
2866 xOffset = pcd->xBorderWidth;
2867 yOffset = pcd->xBorderWidth;
2869 else if(pcd->matteWidth > 0)
2871 xOffset = pcd->matteWidth;
2872 yOffset = pcd->matteWidth;
2878 * need to do general case
2880 XShapeCombineShape (DISPLAY, pcd->clientBaseWin, ShapeBounding,
2883 pcd->client, ShapeBounding,
2886 XShapeCombineShape (DISPLAY, pcd->clientFrameWin, ShapeBounding,
2889 pcd->clientBaseWin, ShapeBounding,
2892 if (pcd->decor & MWM_DECOR_TITLE)
2894 XShapeCombineShape (DISPLAY, pcd->clientFrameWin, ShapeBounding,
2895 pcd->frameInfo.upperBorderWidth,
2896 pcd->frameInfo.upperBorderWidth,
2897 pcd->clientTitleWin, ShapeBounding,
2903 (void) XShapeCombineMask (DISPLAY, pcd->clientFrameWin,
2904 ShapeBounding, 0, 0,
2906 (void) XShapeCombineMask (DISPLAY, pcd->clientFrameWin,
2909 (void) XShapeCombineMask (DISPLAY, pcd->clientBaseWin,
2910 ShapeBounding, 0, 0,
2912 (void) XShapeCombineMask (DISPLAY, pcd->clientBaseWin,
2916 } /* END OF FUNCTION SetFrameShape */
2917 #endif /* NO_SHAPE */