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.
31 * (c) Copyright 1987,1988,1989,1990,1991,1993 HEWLETT-PACKARD COMPANY */
41 #include <X11/cursorfont.h>
51 * include extern functions
56 #include "WmGraphics.h"
57 #include "WmIconBox.h"
59 #include "WmWinInfo.h"
66 int external; /* bevel from frame to root */
67 int join; /* bevel between frame components */
68 int internal; /* bevel from frame to client */
72 Single_Bevel_Count top;
73 Single_Bevel_Count bottom;
77 * "Worst case" bevel counts for frame pieces: this structure is
78 * indexed by definitions in WmGlobal.h. Edit if they change!
80 * These counts are multiplied by the internal, external,
81 * and join bevel resources to determine the sizes of dynamic
82 * data structures to allocate.
85 static Bevel_Count Bevels[] =
87 { {0, 0, 0}, {0, 0, 0} }, /* FRAME_NONE */
88 { {0, 0, 0}, {0, 0, 0} }, /* FRAME_CLIENT */
89 { {0, 4, 0}, {0, 3, 1} }, /* FRAME_SYSTEM */
90 { {0, 2, 0}, {0, 1, 1} }, /* FRAME_TITLE */
91 { {0, 4, 0}, {0, 3, 1} }, /* FRAME_MINIMIZE */
92 { {0, 4, 0}, {0, 3, 1} }, /* FRAME_MAXIMIZE */
93 { {2, 0, 0}, {0, 2, 2} }, /* FRAME_RESIZE_NW */
94 { {1, 1, 0}, {0, 1, 1} }, /* FRAME_RESIZE_N */
95 { {1, 1, 1}, {1, 1, 1} }, /* FRAME_RESIZE_NE */
96 { {0, 1, 1}, {1, 1, 0} }, /* FRAME_RESIZE_E */
97 { {0, 2, 2}, {2, 0, 0} }, /* FRAME_RESIZE_SE */
98 { {0, 1, 1}, {1, 1, 0} }, /* FRAME_RESIZE_S */
99 { {1, 1, 1}, {1, 1, 1} }, /* FRAME_RESIZE_SW */
100 { {1, 1, 0}, {0, 1, 1} } /* FRAME_RESIZE_W */
108 /*************************************<->*************************************
115 * Build a decorated frame for a client window and reparent the client
116 * window to the frame.
121 * pcd - pointer to client data structure for window
123 * << Need the following member data >>
126 * fields from WM_HINTS property
127 * fields from WM_CLASS property
128 * fields from WM_NORMAL_HINTS property
133 * fields from WM_NAME property
142 * This will create a top level shell (frame), fill in the appropriate
143 * decoration, and reparent the window (in *pcd) to the frame.
145 *************************************<->***********************************/
147 Boolean FrameWindow (ClientData *pcd)
149 if (!ConstructFrame (pcd)) /* window hierarchy for frame */
154 GenerateFrameDisplayLists (pcd); /* graphics for frame decoration */
156 AdoptClient(pcd); /* reparent the window */
159 /* shape the frame */
160 if (wmGD.hasShape && pcd->wShaped)
164 #endif /* NO_SHAPE */
168 } /* END OF FUNCTION FrameWindow */
172 /*************************************<->*************************************
174 * FrameExposureProc (pcd)
179 * Repaint the frame graphics
184 * pcd - pointer to client data
193 * Assumes that the display lists for the frame graphics are already
196 *************************************<->***********************************/
198 void FrameExposureProc (ClientData *pcd)
201 Window win = pcd->clientFrameWin;
203 /* use "active" GCs if we have keyboard focus */
205 if (pcd == wmGD.keyboardFocus) {
206 topGC = CLIENT_APPEARANCE(pcd).activeTopShadowGC;
207 botGC = CLIENT_APPEARANCE(pcd).activeBottomShadowGC;
210 topGC = CLIENT_APPEARANCE(pcd).inactiveTopShadowGC;
211 botGC = CLIENT_APPEARANCE(pcd).inactiveBottomShadowGC;
214 /* draw the frame decoration */
216 if (pcd->pclientTopShadows) {
217 XFillRectangles (DISPLAY,
220 pcd->pclientTopShadows->prect,
221 pcd->pclientTopShadows->used);
224 if (pcd->pclientBottomShadows) {
225 XFillRectangles (DISPLAY,
228 pcd->pclientBottomShadows->prect,
229 pcd->pclientBottomShadows->used);
232 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
233 (pcd->decor & MWM_DECOR_TITLE))
235 if (pcd == wmGD.keyboardFocus) {
236 topGC = CLIENT_TITLE_APPEARANCE(pcd).activeTopShadowGC;
237 botGC = CLIENT_TITLE_APPEARANCE(pcd).activeBottomShadowGC;
240 topGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveTopShadowGC;
241 botGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveBottomShadowGC;
244 if (pcd->pclientTitleTopShadows) {
245 XFillRectangles (DISPLAY,
248 pcd->pclientTitleTopShadows->prect,
249 pcd->pclientTitleTopShadows->used);
252 if (pcd->pclientTitleBottomShadows) {
253 XFillRectangles (DISPLAY,
256 pcd->pclientTitleBottomShadows->prect,
257 pcd->pclientTitleBottomShadows->used);
261 /* draw the title bar text */
262 DrawWindowTitle(pcd, False);
267 /*************************************<->*************************************
269 * BaseWinExposureProc (pcd)
274 * Repaint the beveled matte graphics if any.
279 * pcd - pointer to client data
288 * Assumes that the display lists for the matte graphics are already
291 *************************************<->***********************************/
293 void BaseWinExposureProc (ClientData *pcd)
295 /* bevel the matte (if there is one) */
297 if (pcd->matteWidth > 0) {
299 if (pcd->pclientMatteTopShadows) {
300 XFillRectangles (DISPLAY,
302 pcd->clientMatteTopShadowGC,
303 pcd->pclientMatteTopShadows->prect,
304 pcd->pclientMatteTopShadows->used);
307 if (pcd->pclientMatteBottomShadows) {
308 XFillRectangles (DISPLAY,
310 pcd->clientMatteBottomShadowGC,
311 pcd->pclientMatteBottomShadows->prect,
312 pcd->pclientMatteBottomShadows->used);
319 /*************************************<->*************************************
321 * ConstructFrame (pcd)
326 * Construct the window hierarchy for the frame
331 * pcd - pointer to client data record
341 *************************************<->***********************************/
343 Boolean ConstructFrame (ClientData *pcd)
345 unsigned long decoration = pcd->decor;
346 unsigned int wclass; /* window class */
347 unsigned long attr_mask;
348 XSetWindowAttributes window_attribs;
351 /* set frame information */
355 if (!AllocateFrameDisplayLists(pcd)) {
359 /* create frame window */
361 attr_mask = CWEventMask;
362 window_attribs.event_mask = (ButtonPressMask | ButtonReleaseMask |
363 SELECT_BUTTON_MOTION_MASK |
364 DMANIP_BUTTON_MOTION_MASK |
367 if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER) ||
368 (wmGD.colormapFocusPolicy == CMAP_FOCUS_POINTER))
370 window_attribs.event_mask |= EnterWindowMask | LeaveWindowMask;
374 * Use background pixmap if one is specified, otherwise set the
375 * appropriate background color.
378 if (CLIENT_APPEARANCE(pcd).backgroundPixmap)
380 attr_mask |= CWBackPixmap;
381 window_attribs.background_pixmap =
382 CLIENT_APPEARANCE(pcd).backgroundPixmap;
386 attr_mask |= CWBackPixel;
387 window_attribs.background_pixel = CLIENT_APPEARANCE(pcd).background;
390 attr_mask |= CWCursor;
391 window_attribs.cursor = wmGD.workspaceCursor;
393 frmY = pcd->frameInfo.y;
394 frmX = pcd->frameInfo.x;
396 if (CLIENT_APPEARANCE(pcd).saveUnder &&
397 WmGetWindowAttributes (pcd->client) &&
398 wmGD.windowAttributes.save_under)
400 attr_mask |= CWSaveUnder;
401 window_attribs.save_under = True;
404 pcd->clientFrameWin = XCreateWindow(DISPLAY,
406 SCREEN_FOR_CLIENT(pcd)),
409 pcd->frameInfo.width,
410 pcd->frameInfo.height, 0,
411 CopyFromParent,InputOutput,CopyFromParent,
412 attr_mask, &window_attribs);
414 /* create resizing windows with cursors*/
415 if (SHOW_RESIZE_CURSORS(pcd) && (decoration & MWM_DECOR_RESIZEH)) {
416 CreateStretcherWindows (pcd);
420 * Create title bar window. If the title bar has its own appearance,
421 * or if there is no border around the client area,
422 * then we need to create an input/output window to draw in. Otherwise
423 * we can use an input-only window (to clip the corner resize windows).
425 if (decoration & MWM_DECOR_TITLE) {
427 attr_mask = CWCursor;
428 window_attribs.cursor = wmGD.workspaceCursor;
430 if (DECOUPLE_TITLE_APPEARANCE(pcd))
432 /* title bar has a different appearance than rest of frame */
433 wclass = InputOutput;
435 /* need to handle exposure events */
436 attr_mask |= CWEventMask;
437 window_attribs.event_mask = ExposureMask;
440 * Use background pixmap if one is specified, otherwise set the
441 * appropriate background color.
444 if (CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap)
446 attr_mask |= CWBackPixmap;
447 window_attribs.background_pixmap =
448 CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap;
452 attr_mask |= CWBackPixel;
453 window_attribs.background_pixel =
454 CLIENT_TITLE_APPEARANCE(pcd).background;
459 /* title bar has same appearance as rest of frame */
463 pcd->clientTitleWin = XCreateWindow(DISPLAY, pcd->clientFrameWin,
464 (int) pcd->frameInfo.upperBorderWidth,
465 (int) pcd->frameInfo.upperBorderWidth,
466 pcd->frameInfo.width -
467 2*pcd->frameInfo.upperBorderWidth,
468 pcd->frameInfo.titleBarHeight,
470 CopyFromParent,wclass,CopyFromParent,
471 attr_mask, &window_attribs);
474 /* generate gadget position search structure */
475 if (!AllocateGadgetRectangles (pcd))
477 ComputeGadgetRectangles (pcd);
481 * Create base window for reparenting. Save rectangle data for use
482 * in event dispatching.
485 window_attribs.event_mask = (SubstructureRedirectMask |
486 SubstructureNotifyMask |
488 if (pcd->matteWidth > 0)
490 window_attribs.event_mask |= ExposureMask;
491 window_attribs.background_pixel = pcd->matteBackground;
495 window_attribs.background_pixel =
496 CLIENT_TITLE_APPEARANCE(pcd).background;
499 attr_mask = CWBackPixel | CWEventMask;
501 pcd->clientBaseWin = XCreateWindow(DISPLAY, pcd->clientFrameWin,
504 BaseWindowWidth (pcd),
505 BaseWindowHeight (pcd),
507 CopyFromParent,InputOutput,CopyFromParent,
508 attr_mask, &window_attribs);
510 /* map all subwindows of client frame */
512 XMapSubwindows(DISPLAY, pcd->clientFrameWin);
519 /*************************************<->*************************************
521 * GenerateFrameDisplayLists (pcd)
526 * Set up the graphic decorations for the frame
531 * pcd - pointer to client data record
541 * o This must be called after ConstructFrame to insure that the memory
542 * for the rectangles has been allocated.
543 * o If cnum values for StretcherCorner change, also change
544 * StretcherCorner() in WmGraphics.c
545 * o The variable internalBevel sets the depth of shadowing from the
546 * frame to the client area.
547 * o The variable insideBevel is used to decide how deep the bevel is
548 * immediately inside the frame. This may not be internalBevel if
549 * there's a matte, for example.
550 * o The variable diffBevel stores the difference between insideBevel
551 * and what's needed so the bottom of the title bar is correctly
552 * beveled down to the client.
554 *************************************<->***********************************/
556 void GenerateFrameDisplayLists (ClientData *pcd)
558 unsigned long decoration = pcd->decor;
559 int matte_width = pcd->matteWidth;
561 int insideBevel, inset, diffBevel;
562 unsigned int nTitleBevel, sTitleBevel, eTitleBevel, wTitleBevel;
563 unsigned int meTitleBevel, inWidth;
564 int x, y, xAdj = 0, yAdj = 0;
565 unsigned int width, height;
566 RList *prlTop = NULL, *prlBot = NULL;
571 /* zero out part counts */
573 if (pcd->pclientTopShadows)
574 pcd->pclientTopShadows->used = 0;
575 if (pcd->pclientBottomShadows)
576 pcd->pclientBottomShadows->used = 0;
578 if (pcd->pclientTitleTopShadows)
579 pcd->pclientTitleTopShadows->used = 0;
580 if (pcd->pclientTitleBottomShadows)
581 pcd->pclientTitleBottomShadows->used = 0;
583 if (pcd->pclientMatteTopShadows)
584 pcd->pclientMatteTopShadows->used = 0;
585 if (pcd->pclientMatteBottomShadows)
586 pcd->pclientMatteBottomShadows->used = 0;
588 /* adjust inside bevel of gadgetry if there's a matte */
589 if ((wmGD.frameStyle == WmRECESSED) && (matte_width > 0))
590 insideBevel = JOIN_BEVEL(pcd);
592 insideBevel = pcd->internalBevel;
594 diffBevel = insideBevel - 1;
596 if (decoration & MWM_DECOR_RESIZEH)
598 /* adjust part width/heights if no title bar */
599 if ((pcd->internalBevel > 1) && !(decoration & MWM_DECOR_TITLE))
609 * Draw the stretchers. If the horizontal or vertical pieces
610 * get "too small", then don't draw them at all.
612 GetFramePartInfo (pcd, FRAME_RESIZE_NW, &x, &y, &width, &height);
613 StretcherCorner (pcd->pclientTopShadows, /* NW */
614 pcd->pclientBottomShadows,
617 pcd->frameInfo.upperBorderWidth - inset,
620 GetFramePartInfo (pcd, FRAME_RESIZE_N, &x, &y, &width, &height);
622 BevelRectangle (pcd->pclientTopShadows, /* N */
623 pcd->pclientBottomShadows,
625 width, height - inset,
626 2, 1, ((wmGD.frameStyle == WmSLAB) ? 0 : 1), 1);
628 GetFramePartInfo (pcd, FRAME_RESIZE_NE, &x, &y, &width, &height);
629 StretcherCorner (pcd->pclientTopShadows,
630 pcd->pclientBottomShadows,
633 pcd->frameInfo.upperBorderWidth - inset, width, height);
635 GetFramePartInfo (pcd, FRAME_RESIZE_E, &x, &y, &width, &height);
637 BevelRectangle (pcd->pclientTopShadows, /* E */
638 pcd->pclientBottomShadows,
640 width-diffBevel, height,
641 1, 2, 1, ((wmGD.frameStyle == WmSLAB) ? 0 : 1));
643 GetFramePartInfo (pcd, FRAME_RESIZE_SE, &x, &y, &width, &height);
644 StretcherCorner (pcd->pclientTopShadows, /* SE */
645 pcd->pclientBottomShadows,
648 pcd->frameInfo.upperBorderWidth-inset, width, height);
650 GetFramePartInfo (pcd, FRAME_RESIZE_S, &x, &y, &width, &height);
652 BevelRectangle (pcd->pclientTopShadows, /* S */
653 pcd->pclientBottomShadows,
655 width, height-diffBevel,
656 ((wmGD.frameStyle == WmSLAB) ? 0 : 1), 1, 2, 1);
658 GetFramePartInfo (pcd, FRAME_RESIZE_SW, &x, &y, &width, &height);
659 StretcherCorner (pcd->pclientTopShadows, /* SW */
660 pcd->pclientBottomShadows,
663 pcd->frameInfo.upperBorderWidth-inset, width, height);
665 GetFramePartInfo (pcd, FRAME_RESIZE_W, &x, &y, &width, &height);
666 if ((int) height > 0)
667 BevelRectangle (pcd->pclientTopShadows, /* W */
668 pcd->pclientBottomShadows,
670 width-diffBevel, height,
671 1, ((wmGD.frameStyle == WmSLAB) ? 0 : 1), 1, 2);
676 * Draw second inside bevel level. This goes just around the
677 * client area under the title bar.
679 BevelRectangle (pcd->pclientBottomShadows, /* inside */
680 pcd->pclientTopShadows,
681 (int) (pcd->frameInfo.lowerBorderWidth-diffBevel),
682 (int) (pcd->clientOffset.y - diffBevel),
683 pcd->frameInfo.width -
684 2*pcd->frameInfo.lowerBorderWidth +
686 pcd->frameInfo.height - pcd->clientOffset.y -
687 pcd->frameInfo.lowerBorderWidth +
689 (unsigned int) diffBevel, (unsigned int) diffBevel,
690 (unsigned int) diffBevel, (unsigned int) diffBevel);
693 else if (decoration & MWM_DECOR_BORDER)
696 /* produce default border with no resizing functions */
699 BevelRectangle (pcd->pclientTopShadows, /* outside */
700 pcd->pclientBottomShadows,
702 pcd->frameInfo.width, pcd->frameInfo.height,
703 FRAME_EXTERNAL_SHADOW_WIDTH,
704 FRAME_EXTERNAL_SHADOW_WIDTH,
705 FRAME_EXTERNAL_SHADOW_WIDTH,
706 FRAME_EXTERNAL_SHADOW_WIDTH);
708 BevelRectangle (pcd->pclientTopShadows, /* outside */
709 pcd->pclientBottomShadows,
711 pcd->frameInfo.width, pcd->frameInfo.height,
715 if ((pcd->internalBevel > 1) &&
717 (decoration & MWM_DECOR_TITLE)) {
719 * Need to do special beveling around the inside of the
720 * client area separately from around title area.
722 GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height);
723 inset = 1 + (pcd->frameInfo.lowerBorderWidth -
724 pcd->frameInfo.upperBorderWidth);
725 BevelRectangle (pcd->pclientBottomShadows,
726 pcd->pclientTopShadows,
727 (int) (pcd->frameInfo.lowerBorderWidth-inset),
728 (int) (pcd->frameInfo.lowerBorderWidth-inset),
729 pcd->frameInfo.width -
730 2*pcd->frameInfo.lowerBorderWidth + 2*inset,
731 pcd->frameInfo.height -
732 2*pcd->frameInfo.lowerBorderWidth + 2*inset,
735 BevelRectangle (pcd->pclientBottomShadows, /* inside */
736 pcd->pclientTopShadows,
737 (int) (pcd->frameInfo.lowerBorderWidth-diffBevel),
738 pcd->clientOffset.y - diffBevel,
739 pcd->frameInfo.width -
740 2*pcd->frameInfo.lowerBorderWidth +
742 pcd->frameInfo.height - pcd->clientOffset.y -
743 pcd->frameInfo.lowerBorderWidth + 2*diffBevel,
744 (unsigned int)diffBevel, (unsigned int)diffBevel,
745 (unsigned int)diffBevel, (unsigned int)diffBevel);
749 if((pcd->dtwmBehaviors & DtWM_BEHAVIOR_PANEL) &&
750 (pcd->clientDecoration == WM_DECOR_BORDER))
754 BevelRectangle (pcd->pclientBottomShadows, /* inside */
755 pcd->pclientTopShadows,
756 (int)(pcd->frameInfo.lowerBorderWidth-insideBevel),
757 (int)(pcd->frameInfo.lowerBorderWidth-insideBevel),
758 pcd->frameInfo.width -
759 2*pcd->frameInfo.lowerBorderWidth +
761 pcd->frameInfo.height -
762 2*pcd->frameInfo.lowerBorderWidth +
764 (unsigned int)insideBevel,
765 (unsigned int)insideBevel,
766 (unsigned int)insideBevel,
767 (unsigned int)insideBevel);
775 * set bevels for title bar and parts
777 if (decoration & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
779 nTitleBevel = JOIN_BEVEL(pcd); /* north side of title */
780 if (wmGD.frameStyle == WmSLAB)
782 sTitleBevel = JOIN_BEVEL(pcd); /* south side of title */
786 sTitleBevel = insideBevel; /* south side of title */
788 eTitleBevel = JOIN_BEVEL(pcd); /* east side of title */
789 wTitleBevel = JOIN_BEVEL(pcd); /* west side of title */
790 meTitleBevel = JOIN_BEVEL(pcd); /* btw Minimize, Maximize */
794 /* borderless window */
796 nTitleBevel = EXTERNAL_BEVEL(pcd);
797 if (wmGD.frameStyle == WmSLAB)
799 sTitleBevel = (matte_width > 0) ? JOIN_BEVEL(pcd) :
804 sTitleBevel = (matte_width > 0) ? insideBevel : EXTERNAL_BEVEL(pcd);
806 eTitleBevel = (decoration & (MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE))?
807 JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
808 wTitleBevel = (decoration & MWM_DECOR_MENU) ?
809 JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
811 /* beveling east of minimize */
812 meTitleBevel = (decoration & (MWM_DECOR_MAXIMIZE)) ?
813 JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
817 if (decoration & MWM_DECOR_TITLE)
820 * Use a different set of rectangles if title appearance
821 * is different from the rest of the frame.
823 if (DECOUPLE_TITLE_APPEARANCE(pcd))
825 prlTop = pcd->pclientTitleTopShadows;
826 prlBot = pcd->pclientTitleBottomShadows;
827 xAdj = yAdj = pcd->frameInfo.upperBorderWidth;
831 prlTop = pcd->pclientTopShadows;
832 prlBot = pcd->pclientBottomShadows;
837 GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height);
838 if (pcd->decorFlags & TITLE_DEPRESSED) {
839 /* show depressed title gadget */
840 GetDepressInfo (pcd, FRAME_TITLE, &jX, &jY, &jW, &jH,
842 BevelDepressedRectangle (prlTop, prlBot,
843 x-xAdj, y-yAdj, width, height,
844 nTitleBevel, eTitleBevel,
845 sTitleBevel, wTitleBevel, inWidth);
848 /* show normal title gadget */
849 BevelRectangle (prlTop, prlBot,
850 x-xAdj, y-yAdj, width, height,
851 nTitleBevel, eTitleBevel,
852 sTitleBevel, wTitleBevel);
856 if (decoration & MWM_DECOR_MENU) {
858 GetFramePartInfo (pcd, FRAME_SYSTEM, &x, &y, &width, &height);
859 if (pcd->decorFlags & SYSTEM_DEPRESSED) {
860 /* show depressed system gadget */
861 GetDepressInfo (pcd, FRAME_SYSTEM, &jX, &jY, &jW, &jH,
863 BevelDepressedRectangle (prlTop, prlBot,
864 x-xAdj, y-yAdj, width, height,
865 nTitleBevel, wTitleBevel,
866 sTitleBevel, nTitleBevel, inWidth);
870 /* show normal system gadget */
871 BevelRectangle (prlTop, prlBot,
872 x-xAdj, y-yAdj, width, height,
873 nTitleBevel, wTitleBevel,
874 sTitleBevel, nTitleBevel);
879 BevelSystemButton (prlTop, prlBot,
880 x-xAdj, y-yAdj, width, height);
883 if (decoration & MWM_DECOR_MINIMIZE) {
884 GetFramePartInfo (pcd, FRAME_MINIMIZE, &x, &y, &width, &height);
886 if (pcd->decorFlags & MINIMIZE_DEPRESSED) {
887 /* show depressed minimize gadget */
888 GetDepressInfo (pcd, FRAME_MINIMIZE, &jX, &jY, &jW, &jH,
890 BevelDepressedRectangle (prlTop, prlBot,
891 x-xAdj, y-yAdj, width, height,
892 nTitleBevel, meTitleBevel,
893 sTitleBevel, eTitleBevel, inWidth);
896 /* show normal minimize gadget */
897 BevelRectangle (prlTop, prlBot,
898 x-xAdj, y-yAdj, width, height,
899 nTitleBevel, meTitleBevel,
900 sTitleBevel, eTitleBevel);
904 BevelMinimizeButton(prlTop, /* minimize icon */
906 x-xAdj, y-yAdj, height);
909 if (decoration & MWM_DECOR_MAXIMIZE) {
910 GetFramePartInfo (pcd, FRAME_MAXIMIZE, &x, &y, &width, &height);
913 if (pcd->decorFlags & MAXIMIZE_DEPRESSED) {
914 /* show depressed maximize gadget */
915 GetDepressInfo (pcd, FRAME_MAXIMIZE, &jX, &jY, &jW, &jH,
917 BevelDepressedRectangle (prlTop, prlBot,
918 x-xAdj, y-yAdj, width, height,
919 nTitleBevel, nTitleBevel,
920 sTitleBevel, eTitleBevel, inWidth);
923 /* show normal maximize gadget */
924 BevelRectangle (prlTop, prlBot,
925 x-xAdj, y-yAdj, width, height,
926 nTitleBevel, nTitleBevel,
927 sTitleBevel, eTitleBevel);
930 /* maximize icon - in or out depending on client state */
931 if (pcd->maxConfig) {
932 BevelMaximizeButton(prlBot,
934 x-xAdj, y-yAdj, height);
937 BevelMaximizeButton(prlTop,
939 x-xAdj, y-yAdj, height);
944 /* draw the client matte (this is in the base window!!!) */
946 if (matte_width > 0) {
947 unsigned int mWidth, mHeight, exMatteBevel, tMatteBevel;
949 mWidth = BaseWindowWidth (pcd);
950 mHeight = BaseWindowHeight (pcd);
952 if (decoration & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
954 exMatteBevel = JOIN_BEVEL(pcd);
955 tMatteBevel = JOIN_BEVEL(pcd);
959 exMatteBevel = EXTERNAL_BEVEL(pcd);
960 tMatteBevel = (decoration & MWM_DECOR_TITLE) ?
961 JOIN_BEVEL(pcd) : EXTERNAL_BEVEL(pcd);
964 /* set up beveling around the edges */
966 BevelRectangle (pcd->pclientMatteTopShadows,
967 pcd->pclientMatteBottomShadows,
972 tMatteBevel, exMatteBevel,
973 exMatteBevel, exMatteBevel);
975 /* reversed beveling on inside rectange ! */
977 BevelRectangle ( pcd->pclientMatteBottomShadows,
978 pcd->pclientMatteTopShadows,
979 matte_width - pcd->internalBevel,
980 matte_width - pcd->internalBevel,
981 mWidth - 2*matte_width + 2*pcd->internalBevel,
982 mHeight - 2*matte_width + 2*pcd->internalBevel,
983 (unsigned int) pcd->internalBevel,
984 (unsigned int) pcd->internalBevel,
985 (unsigned int) pcd->internalBevel,
986 (unsigned int) pcd->internalBevel);
991 /*************************************<->*************************************
998 * Reparent the client window to the window frame
1003 * pcd - pointer to client data record
1014 *************************************<->***********************************/
1016 void AdoptClient (ClientData *pcd)
1018 XWindowChanges windowChanges;
1021 /* Put the window in the window manager's save set */
1023 if (!(pcd->clientFlags & CLIENT_WM_CLIENTS))
1025 XChangeSaveSet (DISPLAY, pcd->client, SetModeInsert);
1026 pcd->clientFlags |= CLIENT_IN_SAVE_SET;
1030 * set window geometry to be consistent with what we believe
1032 mask = CWWidth | CWHeight;
1033 windowChanges.width = pcd->clientWidth;
1034 windowChanges.height = pcd->clientHeight;
1037 * strip off previous window border if we're adding our own border
1040 if ( (pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)) ||
1041 (pcd->matteWidth > 0) )
1043 mask |= CWBorderWidth;
1044 windowChanges.border_width = 0;
1047 XConfigureWindow (DISPLAY, pcd->client, mask, &windowChanges);
1050 /* shape our frame to match that of the client's window */
1053 int xws, yws, xbs, ybs;
1054 unsigned wws, hws, wbs, hbs;
1055 int boundingShaped, clipShaped;
1057 XShapeSelectInput (DISPLAY, pcd->client, ShapeNotifyMask);
1058 XShapeQueryExtents (DISPLAY, pcd->client,
1059 &boundingShaped, &xws, &yws, &wws, &hws,
1060 &clipShaped, &xbs, &ybs, &wbs, &hbs);
1061 pcd->wShaped = boundingShaped;
1063 #endif /* NO_SHAPE */
1064 /* reparent the window to the base window */
1066 XReparentWindow (DISPLAY, pcd->client, pcd->clientBaseWin,
1069 pcd->clientFlags |= CLIENT_REPARENTED;
1071 } /* END OF FUNCTION AdoptClient */
1075 /*************************************<->*************************************
1077 * GetTextBox (pcd, pBox)
1082 * Gets the rectangle that the text should fit into in the title bar
1087 * pcd - pointer to client data
1088 * pBox - pointer to an XRectangle structure that gets return data
1092 * pBox - data is returned here
1097 *************************************<->***********************************/
1099 void GetTextBox (ClientData *pcd, XRectangle *pBox)
1102 unsigned int width,height;
1103 #if defined(WSM) && defined(DT_LEFT_JUSTIFIED_TITLE)
1104 Dimension textWidth;
1106 XmFontList fontList;
1109 /* get size of title area */
1111 if (!GetFramePartInfo (pcd, FRAME_TITLE, &x, &y, &width, &height))
1113 /* no title area !!! */
1121 /* adjust for shadowing and allow for some padding around the edges */
1122 x += WM_TOP_TITLE_SHADOW + WM_TOP_TITLE_PADDING;
1123 y += WM_TOP_TITLE_SHADOW + WM_TOP_TITLE_PADDING;
1125 width -= WM_TOP_TITLE_SHADOW + WM_BOTTOM_TITLE_SHADOW +
1126 WM_TOP_TITLE_PADDING + WM_BOTTOM_TITLE_PADDING;
1127 height -= WM_TOP_TITLE_SHADOW + WM_BOTTOM_TITLE_SHADOW +
1128 WM_TOP_TITLE_PADDING + WM_BOTTOM_TITLE_PADDING;
1130 #ifdef DT_LEFT_JUSTIFIED_TITLE
1131 if (wmGD.frameStyle == WmSLAB)
1134 * We left justify the title in this style.
1135 * To keep it a little neat, we offset the title from
1136 * the left edge just a little (half the title height).
1137 * See if we have room to do this.
1139 if (DECOUPLE_TITLE_APPEARANCE(pcd))
1140 fontList = CLIENT_TITLE_APPEARANCE(pcd).fontList;
1142 fontList = CLIENT_APPEARANCE(pcd).fontList;
1143 textWidth = XmStringWidth(fontList, pcd->clientTitle);
1145 offset = TitleBarHeight(pcd)/2;
1147 if ((textWidth + offset) <= width)
1149 /* We have plenty of room, do the offset */
1153 else if ((short) (width - textWidth) > 0)
1155 /* We don't have enough room to do our usual offset,
1156 * but if we reduce the offset, the text won't get
1159 offset = (width - textWidth) / 2;
1165 #endif /* DT_LEFT_JUSTIFIED_TITLE */
1166 /* return position and size */
1169 pBox->width = width;
1170 pBox->height = height;
1177 /*************************************<->*************************************
1179 * DrawWindowTitle (pcd, eraseFirst)
1184 * Overwrites or replaces the client's title text in the
1185 * title bar of the frame.
1190 * pcd - pointer to client data
1191 * eraseFirst - if true, then the old title is erased first
1199 * o Assumes 8-bit text for now.
1202 *************************************<->***********************************/
1204 void DrawWindowTitle (ClientData *pcd, Boolean eraseFirst)
1207 unsigned long decoration = pcd->decor;
1210 XmFontList fontList;
1212 /* make sure there is a title bar first */
1213 if (!(decoration & MWM_DECOR_TITLE))
1216 if (DECOUPLE_TITLE_APPEARANCE(pcd))
1218 /* use "active" GC if we have keyboard focus */
1219 if (pcd == wmGD.keyboardFocus) {
1220 clientGC = CLIENT_TITLE_APPEARANCE(pcd).activeGC;
1223 clientGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveGC;
1226 /* get the area that the text must fit in */
1227 GetTextBox (pcd, &textBox);
1229 /* adjust position to be relative to titlebar window, not frame */
1230 textBox.x -= (short) pcd->frameInfo.upperBorderWidth;
1231 textBox.y -= (short) pcd->frameInfo.upperBorderWidth;
1233 win = pcd->clientTitleWin;
1234 fontList = CLIENT_TITLE_APPEARANCE(pcd).fontList;
1238 /* use "active" GC if we have keyboard focus */
1239 if (pcd == wmGD.keyboardFocus) {
1240 clientGC = CLIENT_APPEARANCE(pcd).activeGC;
1243 clientGC = CLIENT_APPEARANCE(pcd).inactiveGC;
1246 /* get the area that the text must fit in */
1247 GetTextBox (pcd, &textBox);
1248 win = pcd->clientFrameWin;
1249 fontList = CLIENT_APPEARANCE(pcd).fontList;
1254 XClearArea (DISPLAY, win, textBox.x, textBox.y,
1255 (unsigned int) textBox.width, (unsigned int) textBox.height,
1259 #ifdef DT_LEFT_JUSTIFIED_TITLE
1260 WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1261 textBox.x, textBox.y, textBox.width, &textBox,
1262 ((wmGD.frameStyle == WmSLAB) ? False : True));
1263 #else /* DT_LEFT_JUSTIFIED_TITLE */
1265 WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1266 textBox.x, textBox.y, textBox.width, &textBox,
1269 WmDrawXmString(DISPLAY, win, fontList, pcd->clientTitle, clientGC,
1270 textBox.x, textBox.y, textBox.width, &textBox);
1272 #endif /* DT_LEFT_JUSTIFIED_TITLE */
1276 } /* END OF FUNCTION DrawWindowTitle */
1280 /*************************************<->*************************************
1282 * CreateStretcherWindows (pcd)
1287 * Create the input-only windows that overlay the resize gadgets.
1292 * pcd - pointer to client data.
1304 * o The windows are sized based upon resizeBorderWidth
1305 * o This should be called before creating the title bar,
1306 * and reparenting window. Later windows should obscure parts of the
1308 * o The stretchers are given special cursors.
1310 *************************************<->***********************************/
1312 void CreateStretcherWindows (ClientData *pcd)
1316 unsigned int width, height;
1317 XSetWindowAttributes win_attribs;
1318 unsigned long attr_mask;
1320 for (iWin = 0; iWin < STRETCH_COUNT; iWin++) {
1322 case STRETCH_NORTH_WEST:
1323 GetFramePartInfo (pcd, FRAME_RESIZE_NW,
1324 &x, &y, &width, &height);
1328 GetFramePartInfo (pcd, FRAME_RESIZE_N,
1329 &x, &y, &width, &height);
1332 case STRETCH_NORTH_EAST:
1333 GetFramePartInfo (pcd, FRAME_RESIZE_NE,
1334 &x, &y, &width, &height);
1338 GetFramePartInfo (pcd, FRAME_RESIZE_E,
1339 &x, &y, &width, &height);
1342 case STRETCH_SOUTH_EAST:
1343 GetFramePartInfo (pcd, FRAME_RESIZE_SE,
1344 &x, &y, &width, &height);
1348 GetFramePartInfo (pcd, FRAME_RESIZE_S,
1349 &x, &y, &width, &height);
1352 case STRETCH_SOUTH_WEST:
1353 GetFramePartInfo (pcd, FRAME_RESIZE_SW,
1354 &x, &y, &width, &height);
1358 GetFramePartInfo (pcd, FRAME_RESIZE_W,
1359 &x, &y, &width, &height);
1363 attr_mask = CWCursor;
1364 win_attribs.cursor = wmGD.stretchCursors[iWin];
1366 pcd->clientStretchWin[iWin] =
1367 XCreateWindow(DISPLAY, pcd->clientFrameWin,
1368 x, y, width, height, 0, CopyFromParent,
1369 InputOnly, CopyFromParent, attr_mask, &win_attribs);
1371 } /* END OF FUNCTION CreateStretcherWindows */
1375 /*************************************<->*************************************
1377 * CountFrameRectangles (pSD)
1382 * Computes the number of top and bottom shadow rectangles to allocate
1387 * pWS - pointer to workspace data
1396 *************************************<->***********************************/
1398 void CountFrameRectangles (WmScreenData *pSD)
1402 pSD->Num_Title_Ts_Elements = pSD->Num_Title_Bs_Elements = 0;
1404 /* count up rectangles for title bar */
1405 for (i = FRAME_SYSTEM; i <= FRAME_MAXIMIZE; i++)
1407 pSD->Num_Title_Ts_Elements += ((Bevels[i].top.external *
1408 pSD->externalBevel) +
1409 (Bevels[i].top.internal * MAX_INTERNAL_BEVEL) +
1410 (Bevels[i].top.join * pSD->joinBevel));
1412 pSD->Num_Title_Bs_Elements += ((Bevels[i].bottom.external*
1413 pSD->externalBevel)+
1414 (Bevels[i].bottom.internal * MAX_INTERNAL_BEVEL) +
1415 (Bevels[i].bottom.join * pSD->joinBevel));
1418 pSD->Num_Resize_Ts_Elements = pSD->Num_Resize_Bs_Elements = 0;
1420 /* count up rectangles for resize handles*/
1421 for (i = FRAME_RESIZE_NW; i <= FRAME_RESIZE_W; i++)
1423 pSD->Num_Resize_Ts_Elements += ((Bevels[i].top.external *
1424 pSD->externalBevel) +
1425 (Bevels[i].top.internal * MAX_INTERNAL_BEVEL) +
1426 (Bevels[i].top.join * pSD->joinBevel));
1428 pSD->Num_Resize_Bs_Elements += ((Bevels[i].bottom.external*
1429 pSD->externalBevel)+
1430 (Bevels[i].bottom.internal * MAX_INTERNAL_BEVEL) +
1431 (Bevels[i].bottom.join * pSD->joinBevel));
1433 } /* END OF FUNCTION CountFrameRectangles */
1437 /*************************************<->*************************************
1439 * AllocateFrameDisplayLists (pcd)
1444 * Allocates memory for the graphic display lists for the frame.
1449 * pcd - pointer to the client data
1454 * pcd - fields modified
1456 * Return - TRUE if successful, FALSE otherwise.
1463 *************************************<->***********************************/
1465 Boolean AllocateFrameDisplayLists (ClientData *pcd)
1467 int frame_top_count, frame_bottom_count;
1470 * If the title bar has it's own appearance, then allocate
1471 * separate display lists for it.
1473 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
1474 (pcd->decor & MWM_DECOR_TITLE))
1476 if (((pcd->pclientTitleTopShadows =
1477 AllocateRList ((unsigned)NUM_TITLE_TS_ELEMENTS(pcd))) == NULL) ||
1478 ((pcd->pclientTitleBottomShadows =
1479 AllocateRList ((unsigned)NUM_TITLE_BS_ELEMENTS(pcd))) == NULL))
1481 /* out of memory! */
1482 Warning (((char *)GETMESSAGE(8, 1, "Insufficient memory for client window framing")));
1486 frame_top_count = NUM_RESIZE_TS_ELEMENTS(pcd);
1487 frame_bottom_count = NUM_RESIZE_BS_ELEMENTS(pcd);
1491 frame_top_count = NUM_RESIZE_TS_ELEMENTS(pcd) +
1492 NUM_TITLE_TS_ELEMENTS(pcd);
1493 frame_bottom_count = NUM_RESIZE_BS_ELEMENTS(pcd) +
1494 NUM_RESIZE_BS_ELEMENTS(pcd);
1498 * Allocate the primary lists for the frame
1500 if ( (pcd->pclientTopShadows == NULL) &&
1501 ((pcd->pclientTopShadows =
1502 AllocateRList ((unsigned)frame_top_count)) == NULL) )
1504 /* out of memory! */
1505 Warning (((char *)GETMESSAGE(8, 2, "Insufficient memory for client window framing")));
1509 if ( (pcd->pclientBottomShadows == NULL) &&
1510 ((pcd->pclientBottomShadows =
1511 AllocateRList ((unsigned)frame_bottom_count)) == NULL) )
1513 /* out of memory! */
1514 Warning (((char *)GETMESSAGE(8, 3, "Insufficient memory for client window framing")));
1519 * Only allocate matte lists if there is a matte.
1521 if ( (pcd->matteWidth) &&
1522 (pcd->pclientMatteTopShadows == NULL) &&
1523 ((pcd->pclientMatteTopShadows =
1524 AllocateRList ((unsigned)NUM_MATTE_TS_RECTS)) == NULL))
1526 /* out of memory! */
1527 Warning (((char *)GETMESSAGE(8, 4, "Insufficient memory for client window framing")));
1531 if ( (pcd->matteWidth) &&
1532 (pcd->pclientMatteBottomShadows == NULL) &&
1533 ((pcd->pclientMatteBottomShadows =
1534 AllocateRList ((unsigned)NUM_MATTE_BS_RECTS)) == NULL))
1536 /* out of memory! */
1537 Warning (((char *)GETMESSAGE(8, 5, "Insufficient memory for client window framing")));
1542 } /* END OF FUNCTION AllocateFrameDisplayLists */
1545 /*************************************<->*************************************
1547 * InitClientDecoration (pSD)
1552 * Initializes client decoration routines
1557 * pSD - pointer to screen data
1565 * This must be called once before decorating any client frames.
1566 *************************************<->***********************************/
1568 void InitClientDecoration (WmScreenData *pSD)
1570 CountFrameRectangles(pSD);
1571 } /* END OF FUNCTION InitClientDecoration */
1575 /*************************************<->*************************************
1577 * AllocateGadgetRectangles (pcd)
1582 * Allocate the memory for event rectangles structures.
1587 * pcd - pointer to client data structure
1597 *************************************<->***********************************/
1599 Boolean AllocateGadgetRectangles (ClientData *pcd)
1602 unsigned long decor = pcd->decor;
1603 GadgetRectangle *pgr;
1605 if (decor & MWM_DECOR_TITLE) {
1607 /* count how many rectangles to allocate for titlebar */
1609 if (decor & MWM_DECOR_MENU) num_rects += 1;
1610 if (decor & MWM_DECOR_MINIMIZE) num_rects += 1;
1611 if (decor & MWM_DECOR_MAXIMIZE) num_rects += 1;
1613 /* allocate memory if no memory is allocated */
1614 if ( pcd->pTitleGadgets == NULL) {
1615 /* allocate memory for these guys */
1616 pgr = (GadgetRectangle *)
1617 XtMalloc (num_rects * sizeof(GadgetRectangle));
1620 /* out of memory! */
1621 Warning (((char *)GETMESSAGE(8, 6, "Insufficient memory for client window framing")));
1625 /* update client data */
1626 pcd->pTitleGadgets = pgr;
1627 pcd->cTitleGadgets = 0;
1631 if (decor & MWM_DECOR_RESIZEH) {
1633 /* allocate memory if no memory is allocated */
1634 if ( pcd->pResizeGadgets == NULL) {
1635 /* allocate memory for these guys */
1636 pgr = (GadgetRectangle *)
1637 XtMalloc (STRETCH_COUNT * sizeof(GadgetRectangle));
1640 /* out of memory! */
1641 Warning (((char *)GETMESSAGE(8, 7, "Insufficient memory for client window framing")));
1645 /* update client data */
1646 pcd->pResizeGadgets = pgr;
1650 } /* END OF FUNCTION AllocateGadgetRectangles */
1653 /*************************************<->*************************************
1655 * ComputeGadgetRectangles (pcd)
1660 * Creates the event rectangles structures to aid in identifying
1661 * frame parts when events come in
1666 * pcd - pointer to client data structure
1675 * o assumes gadget rectangles are already allocated.
1677 *************************************<->***********************************/
1679 void ComputeGadgetRectangles (ClientData *pcd)
1681 unsigned long decor = pcd->decor;
1682 GadgetRectangle *pgr;
1684 unsigned int fpWidth, fpHeight;
1686 int clientWidth = (pcd->maxConfig) ? pcd->maxWidth : pcd->clientWidth;
1691 if (decor & MWM_DECOR_TITLE) {
1693 if ( (pgr = pcd->pTitleGadgets) == NULL) {
1694 return; /* nothing there !!! */
1697 /* do title rectangle */
1698 pcd->titleRectangle.x = pcd->frameInfo.upperBorderWidth;
1699 pcd->titleRectangle.y = pcd->frameInfo.upperBorderWidth;
1702 * Fixed bug where last button in title bar did not activate when
1703 * the client's X border was showing.
1705 pcd->titleRectangle.width = clientWidth +
1706 (XBorderIsShowing(pcd) ? 2*pcd->xBorderWidth : 2*pcd->matteWidth);
1707 pcd->titleRectangle.height = pcd->frameInfo.titleBarHeight;
1709 /* fill in title bar rectangles */
1712 pgr[igr].id = FRAME_TITLE;
1713 GetFramePartInfo (pcd, FRAME_TITLE, &fpX, &fpY, &fpWidth, &fpHeight);
1715 /* copy in and convert to shorts */
1716 pgr[igr].rect.x = fpX;
1717 pgr[igr].rect.y = fpY;
1718 pgr[igr].rect.width = fpWidth;
1719 pgr[igr].rect.height = fpHeight;
1722 if (decor & MWM_DECOR_MENU) {
1723 pgr[igr].id = FRAME_SYSTEM;
1724 GetFramePartInfo (pcd, FRAME_SYSTEM, &fpX, &fpY, &fpWidth,
1727 /* copy in and convert to shorts */
1728 pgr[igr].rect.x = fpX;
1729 pgr[igr].rect.y = fpY;
1730 pgr[igr].rect.width = fpWidth;
1731 pgr[igr].rect.height = fpHeight;
1735 if (decor & MWM_DECOR_MINIMIZE) {
1736 pgr[igr].id = FRAME_MINIMIZE;
1737 GetFramePartInfo (pcd, FRAME_MINIMIZE,
1738 &fpX, &fpY, &fpWidth, &fpHeight);
1739 /* copy in and convert to shorts */
1740 pgr[igr].rect.x = fpX;
1741 pgr[igr].rect.y = fpY;
1742 pgr[igr].rect.width = fpWidth;
1743 pgr[igr].rect.height = fpHeight;
1747 if (decor & MWM_DECOR_MAXIMIZE) {
1748 pgr[igr].id = FRAME_MAXIMIZE;
1749 GetFramePartInfo (pcd, FRAME_MAXIMIZE,
1750 &fpX, &fpY, &fpWidth, &fpHeight);
1751 /* copy in and convert to shorts */
1752 pgr[igr].rect.x = fpX;
1753 pgr[igr].rect.y = fpY;
1754 pgr[igr].rect.width = fpWidth;
1755 pgr[igr].rect.height = fpHeight;
1759 /* update client data */
1760 pcd->pTitleGadgets = pgr;
1761 pcd->cTitleGadgets = igr;
1764 /* client matte area (actually base window area) */
1766 if (decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER))
1768 pcd->matteRectangle.x = pcd->frameInfo.lowerBorderWidth;
1769 pcd->matteRectangle.y = pcd->frameInfo.upperBorderWidth +
1770 pcd->frameInfo.titleBarHeight;
1771 pcd->matteRectangle.width = pcd->frameInfo.width -
1772 (2 * pcd->frameInfo.lowerBorderWidth);
1773 pcd->matteRectangle.height = pcd->frameInfo.height -
1774 pcd->frameInfo.upperBorderWidth -
1775 pcd->frameInfo.lowerBorderWidth -
1776 pcd->frameInfo.titleBarHeight;
1780 pcd->matteRectangle.x = 0;
1781 pcd->matteRectangle.y = pcd->frameInfo.titleBarHeight;
1782 pcd->matteRectangle.width = pcd->frameInfo.width;
1783 pcd->matteRectangle.height = pcd->frameInfo.height -
1784 pcd->frameInfo.titleBarHeight;
1787 if (decor & MWM_DECOR_RESIZEH) {
1789 if ( (pgr = pcd->pResizeGadgets) == NULL) {
1790 return; /* nothing there !!! */
1793 /* fill in resize rectangles */
1795 if (decor & MWM_DECOR_RESIZEH) {
1797 pgr[igr].id = FRAME_RESIZE_NW;
1798 GetFramePartInfo (pcd, FRAME_RESIZE_NW,
1799 &fpX, &fpY, &fpWidth, &fpHeight);
1800 /* copy in and convert to shorts */
1801 pgr[igr].rect.x = fpX;
1802 pgr[igr].rect.y = fpY;
1803 pgr[igr].rect.width = fpWidth;
1804 pgr[igr].rect.height = fpHeight;
1807 pgr[igr].id = FRAME_RESIZE_N;
1808 GetFramePartInfo (pcd, FRAME_RESIZE_N,
1809 &fpX, &fpY, &fpWidth, &fpHeight);
1810 if ((int) fpWidth > 0) {
1811 /* copy in and convert to shorts */
1812 pgr[igr].rect.x = fpX;
1813 pgr[igr].rect.y = fpY;
1814 pgr[igr].rect.width = fpWidth;
1815 pgr[igr].rect.height = fpHeight;
1819 pgr[igr].id = FRAME_RESIZE_NE;
1820 GetFramePartInfo (pcd, FRAME_RESIZE_NE,
1821 &fpX, &fpY, &fpWidth, &fpHeight);
1822 /* copy in and convert to shorts */
1823 pgr[igr].rect.x = fpX;
1824 pgr[igr].rect.y = fpY;
1825 pgr[igr].rect.width = fpWidth;
1826 pgr[igr].rect.height = fpHeight;
1829 pgr[igr].id = FRAME_RESIZE_W;
1830 GetFramePartInfo (pcd, FRAME_RESIZE_W,
1831 &fpX, &fpY, &fpWidth, &fpHeight);
1832 if ((int)fpHeight > 0) {
1833 /* copy in and convert to shorts */
1834 pgr[igr].rect.x = fpX;
1835 pgr[igr].rect.y = fpY;
1836 pgr[igr].rect.width = fpWidth;
1837 pgr[igr].rect.height = fpHeight;
1841 pgr[igr].id = FRAME_RESIZE_E;
1842 GetFramePartInfo (pcd, FRAME_RESIZE_E,
1843 &fpX, &fpY, &fpWidth, &fpHeight);
1844 if ((int) fpHeight > 0) {
1845 /* copy in and convert to shorts */
1846 pgr[igr].rect.x = fpX;
1847 pgr[igr].rect.y = fpY;
1848 pgr[igr].rect.width = fpWidth;
1849 pgr[igr].rect.height = fpHeight;
1853 pgr[igr].id = FRAME_RESIZE_SW;
1854 GetFramePartInfo (pcd, FRAME_RESIZE_SW,
1855 &fpX, &fpY, &fpWidth, &fpHeight);
1856 /* copy in and convert to shorts */
1857 pgr[igr].rect.x = fpX;
1858 pgr[igr].rect.y = fpY;
1859 pgr[igr].rect.width = fpWidth;
1860 pgr[igr].rect.height = fpHeight;
1863 pgr[igr].id = FRAME_RESIZE_S;
1864 GetFramePartInfo (pcd, FRAME_RESIZE_S,
1865 &fpX, &fpY, &fpWidth, &fpHeight);
1866 if ((int) fpWidth > 0) {
1867 /* copy in and convert to shorts */
1868 pgr[igr].rect.x = fpX;
1869 pgr[igr].rect.y = fpY;
1870 pgr[igr].rect.width = fpWidth;
1871 pgr[igr].rect.height = fpHeight;
1875 pgr[igr].id = FRAME_RESIZE_SE;
1876 GetFramePartInfo (pcd, FRAME_RESIZE_SE,
1877 &fpX, &fpY, &fpWidth, &fpHeight);
1878 /* copy in and convert to shorts */
1879 pgr[igr].rect.x = fpX;
1880 pgr[igr].rect.y = fpY;
1881 pgr[igr].rect.width = fpWidth;
1882 pgr[igr].rect.height = fpHeight;
1885 /* update client data */
1886 pcd->pResizeGadgets = pgr;
1889 } /* END OF FUNCTION ComputeGadgetRectangles */
1893 /*************************************<->*************************************
1895 * GetSystemMenuPosition (pcd, px, py, height, context)
1900 * Returns the position of where the system menu should be popped up.
1901 * The hotspotRectangle in global is also set up to match the icon or
1902 * system menu button area.
1907 * pcd = pointer to client data
1909 * px = pointer to x location
1911 * py = pointer to y location
1913 * height = height of the system menu
1915 * context = context that the menu is to be posted under.
1924 * wmGD.hotspotRectangle = system menu button or icon area (root relative)
1926 *************************************<->***********************************/
1928 void GetSystemMenuPosition (ClientData *pcd, int *px, int *py,
1929 unsigned int height, Context context)
1932 if ((pcd->clientState == MINIMIZED_STATE) ||
1933 ((pcd->clientState != MINIMIZED_STATE) &&
1934 (context == F_SUBCONTEXT_IB_WICON)))
1937 * Try to put the menu directly above the icon.
1938 * If it would hit the top of the screen then try to put it below
1939 * the icon and label.
1940 * If it would then hit the bottom of the screen turn of the hotspot
1945 if (pcd->pSD->useIconBox && P_ICON_BOX(pcd))
1947 GetIconBoxIconRootXY (pcd, px, py);
1949 wmGD.hotspotRectangle.x = *px;
1950 wmGD.hotspotRectangle.y = *py;
1956 *py += height + ICON_HEIGHT(pcd);
1957 if (*py + height >= DisplayHeight (DISPLAY,
1958 SCREEN_FOR_CLIENT(pcd)))
1960 wmGD.checkHotspot = FALSE;
1967 *py = ICON_Y(pcd) - height;
1971 *py = ICON_Y(pcd) + ICON_HEIGHT(pcd);
1972 if (*py + height >= DisplayHeight (DISPLAY,
1973 SCREEN_FOR_CLIENT(pcd)))
1975 wmGD.checkHotspot = FALSE;
1979 wmGD.hotspotRectangle.x = ICON_X(pcd);
1980 wmGD.hotspotRectangle.y = ICON_Y(pcd);
1983 /* setup the hotspot rectangle data */
1985 wmGD.hotspotRectangle.width = ICON_WIDTH(pcd);
1986 wmGD.hotspotRectangle.height = ICON_HEIGHT(pcd);
1991 * Try to put the menu directly below the SW corner of the
1993 * If it would hit the bottom of the screen then try to put it directly
1994 * above the NW corner of the titlebar/border.
1995 * If it would then hit the top of the screen turn of the hotspot
1999 if ((pcd->decor & MWM_DECOR_TITLE) &&
2000 !(pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)))
2002 *px = pcd->frameInfo.x;
2003 *py = pcd->frameInfo.y + pcd->frameInfo.titleBarHeight;
2007 *px = pcd->frameInfo.x + pcd->frameInfo.lowerBorderWidth;
2008 *py = pcd->frameInfo.y + pcd->frameInfo.upperBorderWidth +
2009 pcd->frameInfo.titleBarHeight;
2011 if (*py + height >= DisplayHeight (DISPLAY,
2012 SCREEN_FOR_CLIENT(pcd)))
2014 if ((pcd->decor & MWM_DECOR_TITLE) &&
2015 !(pcd->decor & (MWM_DECOR_RESIZEH | MWM_DECOR_BORDER)))
2017 *py = pcd->frameInfo.y - height;
2021 *py = pcd->frameInfo.y + pcd->frameInfo.upperBorderWidth -
2026 wmGD.checkHotspot = FALSE;
2030 /* setup the hotspot rectangle data */
2032 wmGD.hotspotRectangle.x = pcd->frameInfo.x +
2033 pcd->frameInfo.lowerBorderWidth;
2034 wmGD.hotspotRectangle.y = pcd->frameInfo.y +
2035 pcd->frameInfo.upperBorderWidth;
2037 /* assume square button */
2038 wmGD.hotspotRectangle.width = pcd->frameInfo.titleBarHeight;
2039 wmGD.hotspotRectangle.height = pcd->frameInfo.titleBarHeight;
2042 } /* END OF FUNCTION GetSystemMenuPosition */
2046 /*************************************<->*************************************
2048 * ShowActiveClientFrame (pcd)
2053 * Paint the frame to indicate an "active" window
2058 * pcd - pointer to client data
2067 * o This calls the frame exposure procedure, which gets some GCs based
2068 * on the current keyboard focus. Thus, wmGD.keyboardFocus == pcd
2069 * must be TRUE when this is called for the correct highlighting to
2072 *************************************<->***********************************/
2075 ShowActiveClientFrame (ClientData *pcd)
2077 unsigned long attr_mask = 0;
2078 XSetWindowAttributes window_attribs;
2080 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
2081 (pcd->decor & MWM_DECOR_TITLE))
2084 * Use background pixmap if one is specified, otherwise set the
2085 * appropriate background color.
2088 if (CLIENT_TITLE_APPEARANCE(pcd).activeBackgroundPixmap)
2090 attr_mask |= CWBackPixmap;
2091 window_attribs.background_pixmap =
2092 CLIENT_TITLE_APPEARANCE(pcd).activeBackgroundPixmap;
2096 attr_mask |= CWBackPixel;
2097 window_attribs.background_pixel =
2098 CLIENT_TITLE_APPEARANCE(pcd).activeBackground;
2102 XChangeWindowAttributes (DISPLAY, pcd->clientTitleWin, attr_mask,
2105 /* clear the frame to the right background */
2106 XClearWindow (DISPLAY, pcd->clientTitleWin);
2110 * Use background pixmap if one is specified, otherwise set the
2111 * appropriate background color.
2114 if (CLIENT_APPEARANCE(pcd).activeBackgroundPixmap)
2116 attr_mask |= CWBackPixmap;
2117 window_attribs.background_pixmap =
2118 CLIENT_APPEARANCE(pcd).activeBackgroundPixmap;
2122 attr_mask |= CWBackPixel;
2123 window_attribs.background_pixel =
2124 CLIENT_APPEARANCE(pcd).activeBackground;
2128 XChangeWindowAttributes (DISPLAY, pcd->clientFrameWin, attr_mask,
2131 /* clear the frame to the right background */
2132 XClearWindow (DISPLAY, pcd->clientFrameWin);
2134 /* simulate exposure of window */
2135 FrameExposureProc (pcd);
2138 } /* END OF FUNCTION ShowActiveClient */
2142 /*************************************<->*************************************
2144 * ShowInactiveClientFrame (pcd)
2149 * Paint the frame to indicate an "inactive" window
2154 * pcd - pointer to client data
2163 * o This calls the frame exposure procedure, which gets some GCs based
2164 * on the current keyboard focus. Thus, wmGD.keyboardFocus == pcd
2165 * must be FALSE when this is called for the correct highlighting to
2169 ******************************<->***********************************/
2172 ShowInactiveClientFrame (ClientData *pcd)
2174 unsigned long attr_mask = 0;
2175 XSetWindowAttributes window_attribs;
2177 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
2178 (pcd->decor & MWM_DECOR_TITLE))
2181 * Use background pixmap if one is specified, otherwise set the
2182 * appropriate background color.
2185 if (CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap)
2187 attr_mask |= CWBackPixmap;
2188 window_attribs.background_pixmap =
2189 CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap;
2193 attr_mask |= CWBackPixel;
2194 window_attribs.background_pixel =
2195 CLIENT_TITLE_APPEARANCE(pcd).background;
2199 XChangeWindowAttributes (DISPLAY, pcd->clientTitleWin, attr_mask,
2202 /* clear the frame to the right background */
2203 XClearWindow (DISPLAY, pcd->clientTitleWin);
2206 * attr_mask must be cleared because it is set if
2207 * DECOUPLE_TITLE_APPEARANCE(pcd) is true.
2213 * Use background pixmap if one is specified, otherwise set the
2214 * appropriate background color.
2217 if (CLIENT_APPEARANCE(pcd).backgroundPixmap)
2219 attr_mask |= CWBackPixmap;
2220 window_attribs.background_pixmap =
2221 CLIENT_APPEARANCE(pcd).backgroundPixmap;
2225 attr_mask |= CWBackPixel;
2226 window_attribs.background_pixel =
2227 CLIENT_APPEARANCE(pcd).background;
2231 /* change window attribs so clear does the right thing */
2232 XChangeWindowAttributes (DISPLAY, pcd->clientFrameWin, attr_mask,
2235 /* clear the frame to the right background */
2236 XClearWindow (DISPLAY, pcd->clientFrameWin);
2238 /* simulate exposure of window */
2239 FrameExposureProc (pcd);
2241 } /* END OF FUNCTION ShowInactiveClientFrame */
2245 /*************************************<->*************************************
2247 * RegenerateClientFrame (pcd)
2252 * Reconfigure the sizes of all the components of the client frame
2257 * pcd - pointer to client data
2267 *************************************<->***********************************/
2269 void RegenerateClientFrame (ClientData *pcd)
2271 unsigned long decor = pcd->decor;
2273 * If an embedded client, there is no frame.
2277 if (!pcd->clientFrameWin)
2283 /* recompute frame information */
2286 /* move & resize frame window */
2287 XMoveResizeWindow (DISPLAY, pcd->clientFrameWin, pcd->frameInfo.x,
2288 pcd->frameInfo.y, pcd->frameInfo.width, pcd->frameInfo.height);
2291 /* resize title bar window */
2292 if (decor & MWM_DECOR_TITLE)
2294 XResizeWindow (DISPLAY, pcd->clientTitleWin,
2295 pcd->frameInfo.width - 2*pcd->frameInfo.upperBorderWidth,
2296 pcd->frameInfo.titleBarHeight);
2299 /* resize base window */
2300 XResizeWindow (DISPLAY, pcd->clientBaseWin, BaseWindowWidth (pcd),
2301 BaseWindowHeight (pcd));
2303 /* resize the stretcher windows */
2304 if (SHOW_RESIZE_CURSORS(pcd) && (decor & MWM_DECOR_RESIZEH)) {
2305 XMoveResizeWindow (DISPLAY,
2306 pcd->clientStretchWin[STRETCH_NORTH_WEST],
2307 0, 0, pcd->frameInfo.cornerWidth,
2308 pcd->frameInfo.cornerHeight);
2310 XMoveResizeWindow (DISPLAY,
2311 pcd->clientStretchWin[STRETCH_NORTH],
2312 (int) pcd->frameInfo.cornerWidth, 0,
2313 pcd->frameInfo.width - 2*pcd->frameInfo.cornerWidth,
2314 pcd->frameInfo.upperBorderWidth);
2316 XMoveResizeWindow (DISPLAY,
2317 pcd->clientStretchWin[STRETCH_NORTH_EAST],
2318 (int) (pcd->frameInfo.width - pcd->frameInfo.cornerWidth), 0,
2319 pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2321 XMoveResizeWindow (DISPLAY,
2322 pcd->clientStretchWin[STRETCH_EAST],
2323 (int) (pcd->frameInfo.width - pcd->frameInfo.lowerBorderWidth),
2324 (int) (pcd->frameInfo.cornerHeight),
2325 pcd->frameInfo.lowerBorderWidth,
2326 pcd->frameInfo.height - 2*pcd->frameInfo.cornerHeight);
2328 XMoveResizeWindow (DISPLAY,
2329 pcd->clientStretchWin[STRETCH_SOUTH_EAST],
2330 (int) (pcd->frameInfo.width - pcd->frameInfo.cornerWidth),
2331 (int) (pcd->frameInfo.height - pcd->frameInfo.cornerHeight),
2332 pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2334 XMoveResizeWindow (DISPLAY,
2335 pcd->clientStretchWin[STRETCH_SOUTH],
2336 (int) pcd->frameInfo.cornerWidth,
2337 (int) (pcd->frameInfo.height - pcd->frameInfo.lowerBorderWidth),
2338 pcd->frameInfo.width - 2*pcd->frameInfo.cornerWidth,
2339 pcd->frameInfo.lowerBorderWidth);
2341 XMoveResizeWindow (DISPLAY,
2342 pcd->clientStretchWin[STRETCH_SOUTH_WEST],
2343 0, (int) (pcd->frameInfo.height - pcd->frameInfo.cornerHeight),
2344 pcd->frameInfo.cornerWidth, pcd->frameInfo.cornerHeight);
2346 XMoveResizeWindow (DISPLAY,
2347 pcd->clientStretchWin[STRETCH_WEST],
2348 0, (int) pcd->frameInfo.cornerHeight,
2349 pcd->frameInfo.lowerBorderWidth,
2350 pcd->frameInfo.height - 2*pcd->frameInfo.cornerHeight);
2353 /* recreate gadget rectangles */
2354 ComputeGadgetRectangles (pcd);
2356 /* regenerate the graphics */
2357 GenerateFrameDisplayLists (pcd);
2360 if (wmGD.hasShape && pcd->wShaped)
2362 SetFrameShape (pcd);
2364 #endif /* NO_SHAPE */
2366 } /* END OF FUNCTION RegenerateClientFrame */
2371 /*************************************<->*************************************
2373 * BevelSystemButton (prTop, prBot, x, y, width, height)
2378 * Bevels a rectangle for the system button (drawer handle?)
2383 * prTop - ptr to top shadow rectangles
2384 * prBot - ptr to bottom shadow rectangles
2385 * x - x coord of maximize gadget
2386 * y - y coord of maximize gadget
2387 * width - width of maximize gadget
2388 * height - height of maximize gadget
2397 * o This draws a horizontal "drawer handle" for the system gadget.
2398 * Assumptions: the enclosing box is square (width == height)
2399 *************************************<->***********************************/
2401 void BevelSystemButton (RList *prTop, RList *prBot, int x, int y,
2402 unsigned int width, unsigned int height)
2404 int offset1, offset2;
2405 unsigned int dim1, dim2;
2410 offset1 = offset2 = 2;
2411 dim1 = dim2 = height-4;
2415 offset1 = offset2 = 2;
2439 offset2 = (height-3)/2;
2446 offset2 = (height - 4)/2;
2455 BevelRectangle (prTop, prBot, /* system icon */
2456 (x+offset1), (y+offset2),
2460 } /* END OF FUNCTION BevelSystemButton */
2464 /*************************************<->*************************************
2466 * BevelMinimizeButton (prTop, prBot, x, y, height)
2471 * Bevels a rectangle for the minimize button
2476 * prTop - ptr to top shadow rectangles
2477 * prBot - ptr to bottom shadow rectangles
2478 * x - x coord of maximize gadget
2479 * y - y coord of maximize gadget
2480 * height - height of maximize gadget
2490 *************************************<->***********************************/
2492 void BevelMinimizeButton (RList *prTop, RList *prBot, int x, int y,
2493 unsigned int height)
2495 int offset1, offset2;
2496 unsigned int dim1, dim2;
2502 offset1 = offset2 = 3;
2503 dim1 = dim2 = height-6;
2509 offset1 = offset2 = (height-3)/2;
2514 offset1 = offset2 = (height-4)/2;
2521 BevelRectangle (prTop, prBot,
2522 (x+offset1), (y+offset2),
2526 } /* END OF FUNCTION BevelMinimizeButton */
2530 /*************************************<->*************************************
2532 * BevelMaximizeButton (prTop, prBot, x, y, height)
2537 * Bevels a rectangle for the maximize button
2542 * prTop - ptr to top shadow rectangles
2543 * prBot - ptr to bottom shadow rectangles
2544 * x - x coord of maximize gadget
2545 * y - y coord of maximize gadget
2546 * height - height of maximize gadget
2556 *************************************<->***********************************/
2558 void BevelMaximizeButton (RList *prTop, RList *prBot, int x, int y,
2559 unsigned int height)
2561 int offset1, offset2;
2562 unsigned int dim1, dim2;
2572 offset1 = offset2 = 2;
2573 dim1 = dim2 = height-4;
2580 offset1 = offset2 = 3;
2581 dim1 = dim2 = height-6;
2585 offset1 = offset2 = 4;
2586 dim1 = dim2 = height-8;
2591 BevelRectangle (prTop, prBot,
2592 (x+offset1), (y+offset2),
2595 } /* END OF FUNCTION BevelMaximizeButton */
2598 /*************************************<->*************************************
2600 * DepressGadget (pcd, gadget, depressed)
2605 * Show the gadget in a "depressed" state
2610 * pcd - pointer to client data
2611 * gadget - gadget id
2612 * depressed - if True, then gadget is shown depressed, if False it is
2613 * shown not depressed
2618 * return - true if sucessful
2623 * o This assumes there is a one-pixel bevel around the gadget.
2624 * o This only works on title bar gadgets.
2626 *************************************<->***********************************/
2628 Boolean DepressGadget (ClientData *pcd, int gadget, Boolean depressed)
2631 unsigned int width, height, invertWidth;
2632 static RList *pTopRect = NULL;
2633 static RList *pBotRect = NULL;
2637 /* get outside dimensions of box we want */
2642 case FRAME_MINIMIZE:
2643 case FRAME_MAXIMIZE:
2644 if (!GetDepressInfo (pcd, gadget, &x, &y, &width,
2645 &height, &invertWidth))
2651 return(FALSE); /* do nothing on non-title bar gagdets */
2654 if (DECOUPLE_TITLE_APPEARANCE(pcd) &&
2655 (pcd->decor & MWM_DECOR_TITLE))
2657 /* adjust position to be relative to titlebar window, not frame */
2658 x -= (short) pcd->frameInfo.upperBorderWidth;
2659 y -= (short) pcd->frameInfo.upperBorderWidth;
2661 /* use "active" GCs if we have keyboard focus */
2662 if (pcd == wmGD.keyboardFocus) {
2663 topGC = CLIENT_TITLE_APPEARANCE(pcd).activeTopShadowGC;
2664 botGC = CLIENT_TITLE_APPEARANCE(pcd).activeBottomShadowGC;
2667 topGC = CLIENT_TITLE_APPEARANCE(pcd).inactiveTopShadowGC;
2669 CLIENT_TITLE_APPEARANCE(pcd).inactiveBottomShadowGC;
2672 /* draw into title bar window */
2673 win = pcd->clientTitleWin;
2677 /* use "active" GCs if we have keyboard focus */
2678 if (pcd == wmGD.keyboardFocus) {
2679 topGC = CLIENT_APPEARANCE(pcd).activeTopShadowGC;
2680 botGC = CLIENT_APPEARANCE(pcd).activeBottomShadowGC;
2683 topGC = CLIENT_APPEARANCE(pcd).inactiveTopShadowGC;
2684 botGC = CLIENT_APPEARANCE(pcd).inactiveBottomShadowGC;
2687 /* draw into client frame window */
2688 win = pcd->clientFrameWin;
2692 * Bevel a rectangle for the desired button effect
2693 * Allocate the rectangles if necessary.
2695 if ( (pTopRect && pBotRect) ||
2696 ((pTopRect = AllocateRList(2)) &&
2697 (pBotRect = AllocateRList(2))))
2701 BevelRectangle (pTopRect, pBotRect,
2702 x, y, width, height,
2703 invertWidth, invertWidth,
2704 invertWidth, invertWidth);
2707 /* draw the gadget border to make it look depressed or normal */
2710 XFillRectangles (DISPLAY, win, botGC, pTopRect->prect, pTopRect->used);
2711 XFillRectangles (DISPLAY, win, topGC, pBotRect->prect, pBotRect->used);
2714 XFillRectangles (DISPLAY, win, topGC, pTopRect->prect, pTopRect->used);
2715 XFillRectangles (DISPLAY, win, botGC, pBotRect->prect, pBotRect->used);
2718 } /* END OF FUNCTION DepressGadget */
2721 /*************************************<->*************************************
2723 * PushGadgetIn (pcd, gadget)
2728 * Shows a title bar gadget in a depressed state
2733 * pcd - pointer to client data
2734 * gadget - gadget id
2742 *************************************<->***********************************/
2744 void PushGadgetIn (ClientData *pcd, int gadget)
2748 pcd->decorFlags |= SYSTEM_DEPRESSED;
2752 pcd->decorFlags |= TITLE_DEPRESSED;
2755 case FRAME_MINIMIZE:
2756 pcd->decorFlags |= MINIMIZE_DEPRESSED;
2759 case FRAME_MAXIMIZE:
2760 pcd->decorFlags |= MAXIMIZE_DEPRESSED;
2766 GenerateFrameDisplayLists(pcd);
2767 (void) DepressGadget (pcd, gadget, TRUE);
2768 wmGD.gadgetClient = pcd;
2769 wmGD.gadgetDepressed = gadget;
2770 } /* END OF FUNCTION PushGadgetIn */
2773 /*************************************<->*************************************
2775 * PopGadgetOut (pcd, gadget)
2780 * Shows a title bar gadget in a depressed state
2785 * pcd - pointer to client data
2786 * gadget - gadget id
2794 *************************************<->***********************************/
2796 void PopGadgetOut (ClientData *pcd, int gadget)
2800 pcd->decorFlags &= ~SYSTEM_DEPRESSED;
2804 pcd->decorFlags &= ~TITLE_DEPRESSED;
2807 case FRAME_MINIMIZE:
2808 pcd->decorFlags &= ~MINIMIZE_DEPRESSED;
2811 case FRAME_MAXIMIZE:
2812 pcd->decorFlags &= ~MAXIMIZE_DEPRESSED;
2818 GenerateFrameDisplayLists(pcd);
2819 (void) DepressGadget (pcd, gadget, FALSE);
2820 wmGD.gadgetClient = NULL;
2821 wmGD.gadgetDepressed = 0;
2822 } /* END OF FUNCTION PopGadgetOut */
2826 /*************************************<->*************************************
2828 * SetFrameShape (pcd)
2833 * Shapes the frame and base window to the shape of the client
2834 * window. Also ors the title window into the shaped frame
2835 * window if present.
2839 * pcd - pointer to client data
2846 * o currently punt on resize handle around the frame.
2848 *************************************<->***********************************/
2849 void SetFrameShape (ClientData *pcd)
2852 * The frame consists of the shape of the contents window offset by
2853 * title_height or'ed with the shape of title window (which is always
2859 if (XBorderIsShowing(pcd))
2861 xOffset = pcd->xBorderWidth;
2862 yOffset = pcd->xBorderWidth;
2864 else if(pcd->matteWidth > 0)
2866 xOffset = pcd->matteWidth;
2867 yOffset = pcd->matteWidth;
2873 * need to do general case
2875 XShapeCombineShape (DISPLAY, pcd->clientBaseWin, ShapeBounding,
2878 pcd->client, ShapeBounding,
2881 XShapeCombineShape (DISPLAY, pcd->clientFrameWin, ShapeBounding,
2884 pcd->clientBaseWin, ShapeBounding,
2887 if (pcd->decor & MWM_DECOR_TITLE)
2889 XShapeCombineShape (DISPLAY, pcd->clientFrameWin, ShapeBounding,
2890 pcd->frameInfo.upperBorderWidth,
2891 pcd->frameInfo.upperBorderWidth,
2892 pcd->clientTitleWin, ShapeBounding,
2898 (void) XShapeCombineMask (DISPLAY, pcd->clientFrameWin,
2899 ShapeBounding, 0, 0,
2901 (void) XShapeCombineMask (DISPLAY, pcd->clientFrameWin,
2904 (void) XShapeCombineMask (DISPLAY, pcd->clientBaseWin,
2905 ShapeBounding, 0, 0,
2907 (void) XShapeCombineMask (DISPLAY, pcd->clientBaseWin,
2911 } /* END OF FUNCTION SetFrameShape */
2912 #endif /* NO_SHAPE */