1 /*****************************************************************************/
2 /**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
3 /**                          Salt Lake City, Utah                           **/
4 /**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
5 /**                        Cambridge, Massachusetts                         **/
6 /**                                                                         **/
7 /**                           All Rights Reserved                           **/
8 /**                                                                         **/
9 /**    Permission to use, copy, modify, and distribute this software and    **/
10 /**    its documentation  for  any  purpose  and  without  fee is hereby    **/
11 /**    granted, provided that the above copyright notice appear  in  all    **/
12 /**    copies and that both  that  copyright  notice  and  this  permis-    **/
13 /**    sion  notice appear in supporting  documentation,  and  that  the    **/
14 /**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
15 /**    in publicity pertaining to distribution of the  software  without    **/
16 /**    specific, written prior permission.                                  **/
17 /**                                                                         **/
18 /**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
19 /**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
20 /**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
21 /**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
22 /**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
23 /**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
24 /**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
25 /**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
26 /*****************************************************************************/
27 /****************************************************************************
28  * This module is based on Twm, but has been siginificantly modified
29  * by Rob Nation
30  ****************************************************************************/
31 /***********************************************************************
32  * The rest of it is all my fault -- MLM
33  * mwm - "LessTif Window Manager"
34  ***********************************************************************/
35 
36 #include <LTconfig.h>
37 
38 #include <string.h>
39 
40 #include <Xm/Xm.h>
41 #include <Xm/MwmUtil.h>
42 #include "mwm.h"
43 
44 #include <X11/extensions/shape.h>
45 
46 /*
47  * button dimensions
48  */
49 static int lbut_styles[2] =
50 {
51     22,
52     55
53 };
54 static int rbut_style_min[2] =
55 {
56     22,
57     22
58 };
59 static int rbut_style_max[2] =
60 {
61     55,
62     55
63 };
64 
65 
66 /*
67  * change some window attributes
68  */
69 static void
set_value_attributes(ScreenInfo * scr,MwmWindow * t,unsigned long * valuemask,XSetWindowAttributes * attributes,ComponentInfo * comp)70 set_value_attributes(ScreenInfo *scr, MwmWindow *t, unsigned long *valuemask,
71 		     XSetWindowAttributes *attributes, ComponentInfo *comp)
72 {
73 
74     *valuemask = CWBorderPixel;
75     if (scr->mwm_highlight == t)
76     {
77 	attributes->border_pixel = comp->active_background;
78 	if (comp->active_background_pixmap != XmUNSPECIFIED_PIXMAP)
79 	{
80 	    attributes->background_pixmap = comp->active_background_pixmap;
81 	    *valuemask |= CWBackPixmap;
82 	}
83 	else
84 	{
85 	    attributes->background_pixel = comp->active_background;
86 	    *valuemask |= CWBackPixel;
87 	}
88     }
89     else
90     {
91 	attributes->border_pixel = comp->background;
92 	if (comp->background_pixmap != XmUNSPECIFIED_PIXMAP)
93 	{
94 	    attributes->background_pixmap = comp->background_pixmap;
95 	    *valuemask |= CWBackPixmap;
96 	}
97 	else
98 	{
99 	    attributes->background_pixel = comp->background;
100 	    *valuemask |= CWBackPixel;
101 	}
102     }
103 }
104 
105 static void
draw_corners(MwmWindow * t,int i,GC hor,GC vert)106 draw_corners(MwmWindow *t, int i, GC hor, GC vert)
107 {
108     XSegment seg[2];
109     int n = 0;
110 
111     switch (i)
112     {
113     case 0:
114 	seg[0].x1 = t->boundary_width - 1;
115 	seg[0].x2 = t->corner_width;
116 	seg[0].y1 = t->boundary_width - 1;
117 	seg[0].y2 = t->boundary_width - 1;
118 	n = 1;
119 	break;
120     case 1:
121 	seg[0].x1 = 0;
122 	seg[0].x2 = t->corner_width - t->boundary_width;
123 	seg[0].y1 = t->boundary_width - 1;
124 	seg[0].y2 = t->boundary_width - 1;
125 	n = 1;
126 	break;
127     case 2:
128 	seg[0].x1 = t->boundary_width - 1;
129 	seg[0].x2 = t->corner_width - 2;
130 	seg[0].y1 = t->corner_width - t->boundary_width + t->bw;
131 	seg[0].y2 = t->corner_width - t->boundary_width + t->bw;
132 	n = 1;
133 	break;
134     case 3:
135 	seg[0].x1 = 0;
136 	seg[0].x2 = t->corner_width - t->boundary_width;
137 	seg[0].y1 = t->corner_width - t->boundary_width + t->bw;
138 	seg[0].y2 = t->corner_width - t->boundary_width + t->bw;
139 	n = 1;
140 	break;
141     }
142     XDrawSegments(dpy, t->corners[i], hor, seg, n);
143     switch (i)
144     {
145     case 0:
146 	seg[0].y1 = t->boundary_width - 1;
147 	seg[0].y2 = t->corner_width;
148 	seg[0].x1 = t->boundary_width - 1;
149 	seg[0].x2 = t->boundary_width - 1;
150 	n = 1;
151 	break;
152     case 1:
153 	seg[0].y1 = t->boundary_width - 1;
154 	seg[0].y2 = t->corner_width - 2;
155 	seg[0].x1 = t->corner_width - t->boundary_width;
156 	seg[0].x2 = t->corner_width - t->boundary_width;
157 	n = 1;
158 	break;
159     case 2:
160 	seg[0].y1 = 0;
161 	seg[0].y2 = t->corner_width - t->boundary_width;
162 	seg[0].x1 = t->boundary_width - 1;
163 	seg[0].x2 = t->boundary_width - 1;
164 	n = 1;
165 	break;
166     case 3:
167 	seg[0].y1 = 0;
168 	seg[0].y2 = t->corner_width - t->boundary_width + t->bw;
169 	seg[0].x1 = t->corner_width - t->boundary_width;
170 	seg[0].x2 = t->corner_width - t->boundary_width;
171 	n = 1;
172 	break;
173     }
174     XDrawSegments(dpy, t->corners[i], vert, seg, 1);
175 }
176 
177 /*
178  * draws a pattern within a window
179  */
180 static void
draw_pattern(Window win,GC ShadowGC,GC ReliefGC,int h1,int w1,int t1)181 draw_pattern(Window win, GC ShadowGC, GC ReliefGC, int h1, int w1, int t1)
182 {
183     XSegment seg[2];
184     int i, h, b, u, w, r, l;
185 
186     h = t1 * h1 / 200;
187     b = (t1 >> 1) + h;
188     u = t1 - b - 1;
189     w = t1 * w1 / 200;
190     r = (t1 >> 1) + w;
191     l = t1 - r - 1;
192 
193     i = 0;
194     seg[i].x1 = l;
195     seg[i].y1 = u;
196     seg[i].x2 = r;
197     seg[i++].y2 = u;
198 
199     seg[i].x1 = l;
200     seg[i].y1 = u;
201     seg[i].x2 = l;
202     seg[i++].y2 = b;
203     XDrawSegments(dpy, win, ShadowGC, seg, i);
204 
205     i = 0;
206     seg[i].x1 = l;
207     seg[i].y1 = b;
208     seg[i].x2 = r;
209     seg[i++].y2 = b;
210 
211     seg[i].x1 = r;
212     seg[i].y1 = u;
213     seg[i].x2 = r;
214     seg[i++].y2 = b;
215     XDrawSegments(dpy, win, ReliefGC, seg, i);
216 }
217 
218 /*
219  * relieve a rectangle
220  */
221 static void
relieve_rectangle(Window win,int x,int y,int w,int h,GC Hilite,GC Shadow)222 relieve_rectangle(Window win, int x, int y, int w, int h, GC Hilite, GC Shadow)
223 {
224     XDrawLine(dpy, win, Hilite, x, y, w + x - 1, y);
225     XDrawLine(dpy, win, Hilite, x, y, x, h + y - 1);
226     XDrawLine(dpy, win, Hilite, x, y + 1, w + x - 2, y + 1);
227     XDrawLine(dpy, win, Hilite, x + 1, y + 1, x + 1, h + y - 2);
228 
229     XDrawLine(dpy, win, Shadow, x, h + y - 1, w + x - 1, h + y - 1);
230     XDrawLine(dpy, win, Shadow, w + x - 1, y, w + x - 1, h + y - 1);
231     XDrawLine(dpy, win, Shadow, x + 1, h + y - 2, w + x - 2, h + y - 2);
232     XDrawLine(dpy, win, Shadow, w + x - 2, y + 1, w + x - 2, h + y - 2);
233 }
234 
235 /*
236  * draw border windows
237  */
238 void
DEC_DrawBorder(MwmWindow * t,Window win,int x,int y,int w,int h,GC ReliefGC,GC ShadowGC)239 DEC_DrawBorder(MwmWindow *t, Window win, int x, int y, int w, int h,
240 	       GC ReliefGC, GC ShadowGC)
241 {
242     XSegment seg[4];
243     int i;
244 
245     /* top */
246     if (win == t->sides[0])
247     {
248 	i = 0;
249 	seg[i].x1 = x;
250 	seg[i].y1 = y;
251 	seg[i].x2 = w + x - 1;
252 	seg[i++].y2 = y;
253 
254 	seg[i].x1 = x;
255 	seg[i].y1 = y;
256 	seg[i].x2 = x;
257 	seg[i++].y2 = h + y - 1;
258 
259 	XDrawSegments(dpy, win, ReliefGC, seg, i);
260 
261 	i = 0;
262 	seg[i].x1 = x + t->boundary_width;
263 	seg[i].y1 = y + h - 1;
264 	seg[i].x2 = w + x - 1 - t->boundary_width;
265 	seg[i++].y2 = y + h - 1;
266 
267 	seg[i].x1 = x + w - 1;
268 	seg[i].y1 = y;
269 	seg[i].x2 = x + w - 1;
270 	seg[i++].y2 = y + h - 1;
271 
272 	XDrawSegments(dpy, win, ShadowGC, seg, i);
273     }
274     /* right */
275     else if (win == t->sides[1])
276     {
277 	i = 0;
278 	seg[i].x1 = x;
279 	seg[i].y1 = y;
280 	seg[i].x2 = w + x - 1;
281 	seg[i++].y2 = y;
282 
283 	seg[i].x1 = x;
284 	seg[i].y1 = y + t->boundary_width - 1;
285 	seg[i].x2 = x;
286 	seg[i++].y2 = h + y - 1 - t->boundary_width;
287 
288 	XDrawSegments(dpy, win, ReliefGC, seg, i);
289 
290 	i = 0;
291 	seg[i].x1 = x;
292 	seg[i].y1 = y + h - 1;
293 	seg[i].x2 = w + x - 1;
294 	seg[i++].y2 = y + h - 1;
295 
296 	seg[i].x1 = x + w - 1;
297 	seg[i].y1 = y;
298 	seg[i].x2 = x + w - 1;
299 	seg[i++].y2 = y + h - 1;
300 
301 	XDrawSegments(dpy, win, ShadowGC, seg, i);
302     }
303     /* bottom */
304     else if (win == t->sides[2])
305     {
306 	i = 0;
307 	seg[i].x1 = x + t->boundary_width;
308 	seg[i].y1 = y;
309 	seg[i].x2 = w + x - t->boundary_width;
310 	seg[i++].y2 = y;
311 
312 	seg[i].x1 = x;
313 	seg[i].y1 = y;
314 	seg[i].x2 = x;
315 	seg[i++].y2 = h + y - 1;
316 
317 	XDrawSegments(dpy, win, ReliefGC, seg, i);
318 
319 	i = 0;
320 	seg[i].x1 = x;
321 	seg[i].y1 = y + h - 1;
322 	seg[i].x2 = w + x - 1;
323 	seg[i++].y2 = y + h - 1;
324 
325 	seg[i].x1 = x + w - 1;
326 	seg[i].y1 = y;
327 	seg[i].x2 = x + w - 1;
328 	seg[i++].y2 = y + h - 1;
329 
330 	XDrawSegments(dpy, win, ShadowGC, seg, i);
331     }
332     /* left */
333     else
334     {
335 	i = 0;
336 	seg[i].x1 = x;
337 	seg[i].y1 = y;
338 	seg[i].x2 = w + x - 1;
339 	seg[i++].y2 = y;
340 
341 	seg[i].x1 = x;
342 	seg[i].y1 = y;
343 	seg[i].x2 = x;
344 	seg[i++].y2 = h + y - 1;
345 
346 	XDrawSegments(dpy, win, ReliefGC, seg, i);
347 
348 	i = 0;
349 	seg[i].x1 = x;
350 	seg[i].y1 = y + h - 1;
351 	seg[i].x2 = w + x - 1;
352 	seg[i++].y2 = y + h - 1;
353 
354 	seg[i].x1 = x + w - 1;
355 	seg[i].y1 = y + t->boundary_width - 1;
356 	seg[i].x2 = x + w - 1;
357 	seg[i++].y2 = y + h - t->boundary_width;
358 
359 	XDrawSegments(dpy, win, ShadowGC, seg, i);
360     }
361 }
362 
363 /*
364  * draws the relief pattern around a window
365  */
366 void
DEC_DrawShadows(MwmWindow * t,Window win,int x,int y,int w,int h,GC ReliefGC,GC ShadowGC)367 DEC_DrawShadows(MwmWindow *t, Window win, int x, int y, int w, int h,
368 		GC ReliefGC, GC ShadowGC)
369 {
370     XSegment seg[4];
371     int i;
372 
373     i = 0;
374     seg[i].x1 = x;
375     seg[i].y1 = y;
376     seg[i].x2 = w + x - 1;
377     seg[i++].y2 = y;
378 
379     seg[i].x1 = x;
380     seg[i].y1 = y;
381     seg[i].x2 = x;
382     seg[i++].y2 = h + y - 1;
383 
384     XDrawSegments(dpy, win, ReliefGC, seg, i);
385 
386     i = 0;
387     seg[i].x1 = x;
388     seg[i].y1 = y + h - 1;
389     seg[i].x2 = w + x - 1;
390     seg[i++].y2 = y + h - 1;
391 
392     seg[i].x1 = x + w - 1;
393     seg[i].y1 = y;
394     seg[i].x2 = x + w - 1;
395     seg[i++].y2 = y + h - 1;
396 
397     XDrawSegments(dpy, win, ShadowGC, seg, i);
398 }
399 
400 /*
401  * Interprets the property MOTIF_WM_HINTS, sets decoration and functions
402  * accordingly
403  */
404 void
DEC_SelectDecorations(ScreenInfo * scr,MwmWindow * t)405 DEC_SelectDecorations(ScreenInfo *scr, MwmWindow *t)
406 {
407     int border_width, resize_width;
408 
409     border_width = scr->frame_border_width;
410     resize_width = scr->resize_border_width;
411 
412     if (t->mwm_hints && (t->mwm_hints->flags & MWM_HINTS_FUNCTIONS))
413     {
414 	t->functions = t->mwm_hints->functions;
415 
416 	/*
417 	 * functions affect the decorations! if the user says no iconify
418 	 * function, then the iconify button doesn't show up.  So do functions
419 	 * first.
420 	 */
421 	if (t->functions & MWM_FUNC_ALL)
422 	{
423 	    /* If we get ALL + some other things, that means to use ALL except
424 	     * the other things... */
425 	    t->functions &= ~MWM_FUNC_ALL;
426 	    t->functions = (MWM_FUNC_RESIZE | MWM_FUNC_MOVE | MWM_FUNC_MINIMIZE |
427 			    MWM_FUNC_MAXIMIZE | MWM_FUNC_CLOSE)
428 		& (~(t->functions));
429 	}
430 
431 	if (t->flags & TRANSIENT)
432 	    t->functions &= scr->transient_functions;
433 	else
434 	    t->functions &= t->client_functions;
435 
436     }
437     else if (t->flags & TRANSIENT)
438 	t->functions = scr->transient_functions;
439     else
440 	t->functions = t->client_functions;
441 
442 
443     if (t->mwm_hints && (t->mwm_hints->flags & MWM_HINTS_DECORATIONS))
444     {
445 	t->decorations = t->mwm_hints->decorations;
446 
447 	/*
448 	 * next, figure out the decorations
449 	 */
450 	if (t->decorations & MWM_DECOR_ALL)
451 	{
452 	    /* If we get ALL + some other things, that means to use ALL except
453 	     * the other things... */
454 	    t->decorations &= ~MWM_DECOR_ALL;
455 	    t->decorations = (MWM_DECOR_BORDER | MWM_DECOR_RESIZEH |
456 			      MWM_DECOR_TITLE | MWM_DECOR_MENU |
457 			      MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE)
458 		& (~t->decorations);
459 	}
460 
461 	if (t->flags & TRANSIENT)
462 	    t->decorations &= scr->transient_decoration;
463 	else
464 	    t->decorations &= t->client_decoration;
465 
466     }
467     else if (t->flags & TRANSIENT)
468 	t->decorations = scr->transient_decoration;
469     else
470 	t->decorations = t->client_decoration;
471 
472     /*
473      * Now I have the un-altered decor and functions, but with the ALL
474      * attribute cleared and interpreted. I need to modify the decorations
475      * that are affected by the functions
476      */
477     if (!(t->functions & MWM_FUNC_RESIZE))
478 	t->decorations &= ~MWM_DECOR_RESIZEH;
479     /* MWM_FUNC_MOVE has no impact on decorations. */
480     if (!(t->functions & MWM_FUNC_MINIMIZE))
481 	t->decorations &= ~MWM_DECOR_MINIMIZE;
482     if (!(t->functions & MWM_FUNC_MAXIMIZE))
483 	t->decorations &= ~MWM_DECOR_MAXIMIZE;
484     /* MWM_FUNC_CLOSE has no impact on decorations. */
485 
486     /*
487      * This rule is implicit, but its easier to deal with if I take care of
488      * it now
489      */
490     if (t->decorations & (MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE))
491 	t->decorations |= MWM_DECOR_TITLE;
492 
493     if (t->decorations & (MWM_DECOR_TITLE | MWM_DECOR_RESIZEH))
494 	t->decorations |= MWM_DECOR_BORDER;
495 
496     if (t->wShaped)
497 	t->decorations &= ~(MWM_DECOR_BORDER | MWM_DECOR_RESIZEH);
498 
499     /*
500      * Assume no decorations, and build up
501      */
502     t->boundary_width = 0;
503     t->corner_width = 0;
504     t->title_height = 0;
505 
506     if (t->decorations & MWM_DECOR_BORDER)
507     {
508 	/* A narrow border is displayed (5 pixels - 2 relief, 1 top, 2
509 	 * shadow) */
510 	t->boundary_width = border_width;
511     }
512 
513     if (t->decorations & MWM_DECOR_TITLE)
514     {
515 	/* A title barm with no buttons in it - window gets a 1 pixel wide
516 	 * black border. */
517 	t->title_height = scr->components[MWM_TITLE_A].f_height + 3;
518     }
519 
520     if (t->decorations & MWM_DECOR_RESIZEH)
521     {
522 	/* A wide border, with corner tiles is desplayed (10 pixels - 2
523 	 * relief, 2 shadow) */
524 	t->boundary_width = resize_width;
525 	t->corner_width = scr->components[MWM_TITLE_A].f_height + 3 +
526 	    t->boundary_width;
527     }
528 
529     t->bw = 0;
530     if (t->title_height > 0)
531 	t->title_height += t->bw;
532 }
533 
534 /*
535  * Interprets the property MOTIF_WM_HINTS, sets decoration and functions
536  * accordingly
537  */
538 void
DEC_ReselectDecorations(ScreenInfo * scr,MwmWindow * t)539 DEC_ReselectDecorations(ScreenInfo *scr, MwmWindow *t)
540 {
541     int border_width, resize_width, i;
542     unsigned long valuemask;	/* mask for create windows */
543     XSetWindowAttributes attributes;	/* attributes for create windows */
544 
545     border_width = scr->frame_border_width;
546     resize_width = scr->resize_border_width;
547 
548     if (t->mwm_hints && (t->mwm_hints->flags & MWM_HINTS_FUNCTIONS))
549     {
550 	t->functions = t->mwm_hints->functions;
551 
552 	/*
553 	 * functions affect the decorations! if the user says no iconify
554 	 * function, then the iconify button doesn't show up.  So do functions
555 	 * first.
556 	 */
557 	if (t->functions & MWM_FUNC_ALL)
558 	{
559 	    /* If we get ALL + some other things, that means to use ALL except
560 	     * the other things... */
561 	    t->functions &= ~MWM_FUNC_ALL;
562 	    t->functions = (MWM_FUNC_RESIZE | MWM_FUNC_MOVE | MWM_FUNC_MINIMIZE |
563 			    MWM_FUNC_MAXIMIZE | MWM_FUNC_CLOSE)
564 		& (~(t->functions));
565 	}
566 
567 	if (t->flags & TRANSIENT)
568 	    t->functions &= scr->transient_functions;
569 	else
570 	    t->functions &= t->client_functions;
571 
572     }
573     else if (t->flags & TRANSIENT)
574 	t->functions = scr->transient_functions;
575     else
576 	t->functions = t->client_functions;
577 
578 
579     if (t->mwm_hints && (t->mwm_hints->flags & MWM_HINTS_DECORATIONS))
580     {
581 	t->decorations = t->mwm_hints->decorations;
582 
583 	/*
584 	 * next, figure out the decorations
585 	 */
586 	if (t->decorations & MWM_DECOR_ALL)
587 	{
588 	    /* If we get ALL + some other things, that means to use ALL except
589 	     * the other things... */
590 	    t->decorations &= ~MWM_DECOR_ALL;
591 	    t->decorations = (MWM_DECOR_BORDER | MWM_DECOR_RESIZEH |
592 			      MWM_DECOR_TITLE | MWM_DECOR_MENU |
593 			      MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE)
594 		& (~t->decorations);
595 	}
596 
597 	if (t->flags & TRANSIENT)
598 	    t->decorations &= scr->transient_decoration;
599 	else
600 	    t->decorations &= t->client_decoration;
601 
602     }
603     else if (t->flags & TRANSIENT)
604 	t->decorations = scr->transient_decoration;
605     else
606 	t->decorations = t->client_decoration;
607 
608     /*
609      * Now I have the un-altered decor and functions, but with the ALL
610      * attribute cleared and interpreted. I need to modify the decorations
611      * that are affected by the functions
612      */
613     if (!(t->functions & MWM_FUNC_RESIZE))
614 	t->decorations &= ~MWM_DECOR_RESIZEH;
615     /* MWM_FUNC_MOVE has no impact on decorations. */
616     if (!(t->functions & MWM_FUNC_MINIMIZE))
617 	t->decorations &= ~MWM_DECOR_MINIMIZE;
618     if (!(t->functions & MWM_FUNC_MAXIMIZE))
619 	t->decorations &= ~MWM_DECOR_MAXIMIZE;
620     /* MWM_FUNC_CLOSE has no impact on decorations. */
621 
622     /*
623      * This rule is implicit, but its easier to deal with if I take care of
624      * it now
625      */
626     if (t->decorations & (MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE))
627 	t->decorations |= MWM_DECOR_TITLE;
628 
629     if (t->decorations & (MWM_DECOR_TITLE | MWM_DECOR_RESIZEH))
630 	t->decorations |= MWM_DECOR_BORDER;
631 
632     if (t->wShaped)
633 	t->decorations &= ~(MWM_DECOR_BORDER | MWM_DECOR_RESIZEH);
634 
635     /*
636      * Assume no decorations, and build up
637      */
638     t->boundary_width = 0;
639     t->corner_width = 0;
640     t->title_height = 0;
641 
642     valuemask = CWBorderPixel | CWCursor | CWEventMask |
643 	CWSaveUnder | CWBackingStore;
644     attributes.backing_store = WhenMapped;
645     if (scr->components[MWM_BORDER].background_pixmap
646 	!= XmUNSPECIFIED_PIXMAP)
647     {
648 	attributes.background_pixmap =
649 	    scr->components[MWM_BORDER].background_pixmap;
650 	valuemask &= ~CWBackPixel;
651 	valuemask |= CWBackPixmap;
652     }
653     else
654     {
655 	attributes.background_pixel = scr->components[MWM_BORDER].background;
656 	valuemask &= ~CWBackPixmap;
657 	valuemask |= CWBackPixel;
658     }
659     attributes.event_mask = (ButtonPressMask | ButtonReleaseMask |
660 			     ExposureMask | EnterWindowMask | LeaveWindowMask);
661 
662 
663     if (t->decorations & MWM_DECOR_BORDER)
664     {
665 	/* A narrow border is displayed (5 pixels - 2 relief, 1 top, 2
666 	 * shadow) */
667 	t->boundary_width = border_width;
668 
669 	if (t->sides[0] == None)
670 	{
671 
672 	    for (i = 0; i < 4; i++)
673 	    {
674 		if (scr->resize_cursors)
675 		    attributes.cursor = scr->cursors[TOP_CURS + i];
676 		else
677 		    attributes.cursor = scr->cursors[DEFAULT_CURS];
678 		attributes.save_under =
679 		    scr->components[MWM_BORDER].save_under;
680 		t->sides[i] = XCreateWindow(dpy, t->frame, 0, 0,
681 					    t->boundary_width,
682 					    t->boundary_width,
683 					    0,
684 					    CopyFromParent, InputOutput,
685 					    CopyFromParent,
686 					    valuemask, &attributes);
687 
688 		XSaveContext(dpy, t->sides[i], MwmContext, (XPointer)t);
689 	    }
690 	}
691 	for (i = 0; i < 4; i++)
692 	    XRaiseWindow(dpy, t->sides[i]);
693     }
694     else if (t->sides[0] != None)
695     {
696 	for (i = 0; i < 4; i++)
697 	{
698 	    XDeleteContext(dpy, t->sides[i], MwmContext);
699 	    XDestroyWindow(dpy, t->sides[i]);
700 	    t->sides[i] = None;
701 	}
702     }
703 
704     if (scr->components[MWM_RESIZE_H].background_pixmap
705 	!= XmUNSPECIFIED_PIXMAP)
706     {
707 	attributes.background_pixmap =
708 	    scr->components[MWM_RESIZE_H].background_pixmap;
709 	valuemask &= ~CWBackPixel;
710 	valuemask |= CWBackPixmap;
711     }
712     else
713     {
714 	attributes.background_pixel =
715 	    scr->components[MWM_RESIZE_H].background;
716 	valuemask &= ~CWBackPixmap;
717 	valuemask |= CWBackPixel;
718     }
719     if (t->decorations & MWM_DECOR_RESIZEH)
720     {
721 	/* A wide border, with corner tiles is desplayed (10 pixels - 2
722 	 * relief, 2 shadow) */
723 	t->boundary_width = resize_width;
724 	t->corner_width = scr->components[MWM_TITLE_A].f_height + 3 +
725 	    t->boundary_width;
726 
727 	if (t->corners[0] == None)
728 	{
729 
730 	    attributes.event_mask = (ButtonPressMask | ButtonReleaseMask |
731 			     ExposureMask | EnterWindowMask | LeaveWindowMask);
732 
733 	    /*
734 	     * Just dump the windows any old place and let
735 	     * DEC_ConfigureDecorations take care of the mess
736 	     */
737 	    for (i = 0; i < 4; i++)
738 	    {
739 		if (scr->resize_cursors)
740 		    attributes.cursor = scr->cursors[TOP_LEFT_CURS + i];
741 		else
742 		    attributes.cursor = scr->cursors[DEFAULT_CURS];
743 		attributes.save_under =
744 		    scr->components[MWM_RESIZE_H].save_under;
745 		t->corners[i] = XCreateWindow(dpy, t->frame, 0, 0,
746 					      t->corner_width,
747 					      t->corner_width,
748 					      0, CopyFromParent,
749 					      InputOutput, CopyFromParent,
750 					      valuemask, &attributes);
751 
752 		XSaveContext(dpy, t->corners[i], MwmContext, (XPointer)t);
753 	    }
754 	}
755 	for (i = 0; i < 4; i++)
756 	    XRaiseWindow(dpy, t->corners[i]);
757     }
758     else if (t->corners[0] != None)
759     {
760 	for (i = 0; i < 4; i++)
761 	{
762 	    XDestroyWindow(dpy, t->corners[i]);
763 	    XDeleteContext(dpy, t->corners[i], MwmContext);
764 	    t->corners[i] = None;
765 	}
766     }
767 
768     if (scr->components[MWM_TITLE_A].background_pixmap
769 	!= XmUNSPECIFIED_PIXMAP)
770     {
771 	attributes.background_pixmap =
772 	    scr->components[MWM_TITLE_A].background_pixmap;
773 	valuemask &= ~CWBackPixel;
774 	valuemask |= CWBackPixmap;
775     }
776     else
777     {
778 	attributes.background_pixel =
779 	    scr->components[MWM_TITLE_A].background;
780 	valuemask &= ~CWBackPixmap;
781 	valuemask |= CWBackPixel;
782     }
783     if (t->decorations & MWM_DECOR_TITLE)
784     {
785 	/* A title barm with no buttons in it - window gets a 1 pixel wide
786 	 * black border. */
787 	t->title_height = scr->components[MWM_TITLE_A].f_height + 3;
788 	if (t->title_height > 0)
789 	    t->title_height += t->bw;
790 
791 	t->title_x = t->title_y = 0;
792 	t->title_width = t->frame_width - 2 * t->corner_width - 3 + t->bw;
793 	if (t->title_width < 1)
794 	    t->title_width = 1;
795 
796 	if (t->title == None)
797 	{
798 
799 	    attributes.cursor = scr->cursors[TITLE_CURS];
800 	    attributes.save_under = scr->components[MWM_TITLE_A].save_under;
801 	    t->title = XCreateWindow(dpy, t->frame,
802 				     t->title_x, t->title_y,
803 				     t->title_width, t->title_height,
804 				     0,
805 				     CopyFromParent, InputOutput,
806 				     CopyFromParent,
807 				     valuemask, &attributes);
808 
809 	    XSaveContext(dpy, t->title, MwmContext, (XPointer)t);
810 	}
811 	XRaiseWindow(dpy, t->title);
812     }
813     else if (t->title != None)
814     {
815 	XDeleteContext(dpy, t->title, MwmContext);
816 	XDestroyWindow(dpy, t->title);
817 	t->title = None;
818     }
819 
820     if (scr->components[MWM_MENU_B].background_pixmap
821 	!= XmUNSPECIFIED_PIXMAP)
822     {
823 	attributes.background_pixmap =
824 	    scr->components[MWM_MENU_B].background_pixmap;
825 	valuemask &= ~CWBackPixel;
826 	valuemask |= CWBackPixmap;
827     }
828     else
829     {
830 	attributes.background_pixel =
831 	    scr->components[MWM_MENU_B].background;
832 	valuemask &= ~CWBackPixmap;
833 	valuemask |= CWBackPixel;
834     }
835     if (t->decorations & MWM_DECOR_MENU)
836     {
837 	/* title-bar menu button window gets 1 pixel wide black border */
838 	if (t->menub == None)
839 	{
840 	    attributes.save_under = scr->components[MWM_MENU_B].save_under;
841 	    t->menub = XCreateWindow(dpy, t->frame,
842 				     t->title_height, 0,
843 				     t->title_height, t->title_height,
844 				     0,
845 				     CopyFromParent, InputOutput,
846 				     CopyFromParent,
847 				     valuemask, &attributes);
848 
849 	    XSaveContext(dpy, t->menub, MwmContext, (XPointer)t);
850 	}
851 	XRaiseWindow(dpy, t->menub);
852     }
853     else if (t->menub != None)
854     {
855 	XDeleteContext(dpy, t->menub, MwmContext);
856 	XDestroyWindow(dpy, t->menub);
857 	t->menub = None;
858     }
859 
860     if (scr->components[MWM_MINIMIZE_B].background_pixmap
861 	!= XmUNSPECIFIED_PIXMAP)
862     {
863 	attributes.background_pixmap =
864 	    scr->components[MWM_MINIMIZE_B].background_pixmap;
865 	valuemask &= ~CWBackPixel;
866 	valuemask |= CWBackPixmap;
867     }
868     else
869     {
870 	attributes.background_pixel =
871 	    scr->components[MWM_MINIMIZE_B].background;
872 	valuemask &= ~CWBackPixmap;
873 	valuemask |= CWBackPixel;
874     }
875     if (t->decorations & MWM_DECOR_MINIMIZE)
876     {
877 	/* title-bar + iconify button, no menu button. window gets 1 pixel
878 	 * wide black border */
879 	if (t->minimizeb == None)
880 	{
881 	    attributes.save_under = scr->components[MWM_MINIMIZE_B].save_under;
882 	    t->minimizeb = XCreateWindow(dpy, t->frame,
883 					 t->title_width - t->title_height * 2,
884 					 0,
885 					 t->title_height, t->title_height,
886 					 0,
887 					 CopyFromParent, InputOutput,
888 					 CopyFromParent,
889 					 valuemask, &attributes);
890 
891 	    XSaveContext(dpy, t->minimizeb, MwmContext, (XPointer)t);
892 	}
893 	XRaiseWindow(dpy, t->minimizeb);
894     }
895     else if (t->minimizeb != None)
896     {
897 	XDeleteContext(dpy, t->minimizeb, MwmContext);
898 	XDestroyWindow(dpy, t->minimizeb);
899 	t->minimizeb = None;
900     }
901 
902     if (scr->components[MWM_MAXIMIZE_B].background_pixmap
903 	!= XmUNSPECIFIED_PIXMAP)
904     {
905 	attributes.background_pixmap =
906 	    scr->components[MWM_MAXIMIZE_B].background_pixmap;
907 	valuemask &= ~CWBackPixel;
908 	valuemask |= CWBackPixmap;
909     }
910     else
911     {
912 	attributes.background_pixel =
913 	    scr->components[MWM_MAXIMIZE_B].background;
914 	valuemask &= ~CWBackPixmap;
915 	valuemask |= CWBackPixel;
916     }
917     if (t->decorations & MWM_DECOR_MAXIMIZE)
918     {
919 	/* title-bar + maximize button, no menu button, no iconify. * window
920 	 * has 1 pixel wide black border */
921 	if (t->maximizeb == None)
922 	{
923 	    attributes.save_under = scr->components[MWM_MINIMIZE_B].save_under;
924 	    t->maximizeb = XCreateWindow(dpy, t->frame,
925 					 t->title_width - t->title_height * 1,
926 					 0,
927 					 t->title_height, t->title_height,
928 					 0,
929 					 CopyFromParent, InputOutput,
930 					 CopyFromParent,
931 					 valuemask, &attributes);
932 
933 	    XSaveContext(dpy, t->maximizeb, MwmContext, (XPointer)t);
934 	}
935 	XRaiseWindow(dpy, t->maximizeb);
936     }
937     else if (t->maximizeb != None)
938     {
939 	XDeleteContext(dpy, t->maximizeb, MwmContext);
940 	XDestroyWindow(dpy, t->maximizeb);
941 	t->maximizeb = None;
942     }
943 
944     XMapSubwindows(dpy, t->frame);
945     XLowerWindow(dpy, t->shield);
946     XRaiseWindow(dpy, t->parent);
947 
948     t->bw = 0;
949 }
950 
951 /*
952  * create the decoration windows
953  */
954 void
DEC_CreateDecorations(ScreenInfo * scr,MwmWindow * tmp_win)955 DEC_CreateDecorations(ScreenInfo *scr, MwmWindow *tmp_win)
956 {
957     unsigned long valuemask;	/* mask for create windows */
958     XSetWindowAttributes attributes;	/* attributes for create windows */
959     int i;
960 
961     /*
962      * create windows
963      */
964     tmp_win->frame_x = tmp_win->attr.x + tmp_win->old_bw - tmp_win->bw;
965     tmp_win->frame_y = tmp_win->attr.y + tmp_win->old_bw - tmp_win->bw;
966 
967     tmp_win->frame_width = tmp_win->attr.width +
968 	2 * tmp_win->boundary_width +
969 	2 * tmp_win->matte_width;
970     tmp_win->frame_height = tmp_win->attr.height + tmp_win->title_height +
971 	2 * tmp_win->matte_width +
972 	2 * tmp_win->boundary_width;
973 
974     valuemask = CWBorderPixel | CWCursor | CWEventMask;
975     if (scr->components[MWM_BORDER].background_pixmap
976 	!= XmUNSPECIFIED_PIXMAP)
977     {
978 	attributes.background_pixmap =
979 	    scr->components[MWM_BORDER].background_pixmap;
980 	valuemask &= ~CWBackPixel;
981 	valuemask |= CWBackPixmap;
982     }
983     else
984     {
985 	attributes.background_pixel =
986 	    scr->components[MWM_BORDER].background;
987 	valuemask &= ~CWBackPixmap;
988 	valuemask |= CWBackPixel;
989     }
990 
991     attributes.border_pixel = scr->components[MWM_BORDER].bottom_shadow_color;
992 
993     attributes.cursor = scr->cursors[DEFAULT_CURS];
994     attributes.event_mask = (SubstructureRedirectMask | ButtonPressMask |
995 			     ButtonReleaseMask | EnterWindowMask |
996 			     LeaveWindowMask | ExposureMask);
997     valuemask |= CWSaveUnder;
998     attributes.save_under = True;
999 
1000     /* What the heck, we'll always reparent everything from now on! */
1001     tmp_win->frame =
1002 	XCreateWindow(dpy, scr->root_win, tmp_win->frame_x, tmp_win->frame_y,
1003 		      tmp_win->frame_width, tmp_win->frame_height,
1004 		      tmp_win->bw, CopyFromParent, InputOutput,
1005 		      CopyFromParent, valuemask, &attributes);
1006 
1007     attributes.save_under = False;
1008 
1009     /* Thats not all, we'll double-reparent the window ! */
1010     attributes.cursor = scr->cursors[DEFAULT_CURS];
1011     attributes.background_pixel = tmp_win->matte_background;
1012     valuemask &= ~CWBackPixmap;
1013     valuemask |= CWBackPixel;
1014     tmp_win->parent =
1015 	XCreateWindow(dpy, tmp_win->frame,
1016 		      tmp_win->boundary_width,
1017 		      tmp_win->boundary_width + tmp_win->title_height,
1018 		      (tmp_win->frame_width - 2 * tmp_win->boundary_width),
1019 		      (tmp_win->frame_height - 2 * tmp_win->boundary_width -
1020 		       tmp_win->title_height), tmp_win->bw, CopyFromParent,
1021 		      InputOutput, CopyFromParent, valuemask, &attributes);
1022 
1023     attributes.cursor = scr->cursors[SYS_MODAL_CURS];
1024     attributes.override_redirect = True;
1025     attributes.event_mask = ButtonPressMask | ButtonPressMask;
1026 
1027     tmp_win->shield =
1028 	XCreateWindow(dpy, tmp_win->frame,
1029 		      tmp_win->boundary_width,
1030 		      tmp_win->boundary_width + tmp_win->title_height,
1031 		      (tmp_win->frame_width - 2 * tmp_win->boundary_width),
1032 		      (tmp_win->frame_height - 2 * tmp_win->boundary_width -
1033 		       tmp_win->title_height),
1034 		      tmp_win->bw,
1035 		      0, InputOnly, CopyFromParent,
1036 		      CWEventMask | CWCursor | CWOverrideRedirect, &attributes);
1037 
1038     valuemask |= CWBackingStore;
1039     attributes.backing_store = WhenMapped;
1040     attributes.event_mask = (SubstructureRedirectMask | ButtonPressMask |
1041 			     ButtonReleaseMask | EnterWindowMask |
1042 			     LeaveWindowMask | ExposureMask);
1043 
1044     attributes.cursor = scr->cursors[DEFAULT_CURS];
1045     if (scr->pager_win)
1046     {
1047 	if (scr->components[MWM_PAGER].background_pixmap
1048 	    != XmUNSPECIFIED_PIXMAP)
1049 	{
1050 	    attributes.background_pixmap =
1051 		scr->components[MWM_PAGER].background_pixmap;
1052 	    valuemask |= CWBackPixmap;
1053 	}
1054 	else
1055 	{
1056 	    attributes.background_pixel = scr->components[MWM_PAGER].background;
1057 	    valuemask |= CWBackPixel;
1058 	}
1059 
1060 	/* Create the pager_view window even if we're sticky, in case the
1061 	 * user unsticks the window */
1062 	attributes.event_mask = ExposureMask;
1063 	tmp_win->pager_view = XCreateWindow(dpy, scr->pager_win,
1064 					    -10, -10,
1065 					    2, 2,
1066 					    1,
1067 					    CopyFromParent, InputOutput,
1068 					    CopyFromParent, valuemask,
1069 					    &attributes);
1070 	XMapRaised(dpy, tmp_win->pager_view);
1071     }
1072 
1073     attributes.event_mask = (ButtonPressMask | ButtonReleaseMask |
1074 			     ExposureMask | EnterWindowMask | LeaveWindowMask);
1075     tmp_win->title_x = tmp_win->title_y = 0;
1076     tmp_win->title_width = tmp_win->frame_width - 2 * tmp_win->corner_width
1077 	- 3 + tmp_win->bw;
1078     if (tmp_win->title_width < 1)
1079 	tmp_win->title_width = 1;
1080 
1081     if (scr->components[MWM_RESIZE_H].background_pixmap
1082 	!= XmUNSPECIFIED_PIXMAP)
1083     {
1084 	attributes.background_pixmap =
1085 	    scr->components[MWM_RESIZE_H].background_pixmap;
1086 	valuemask &= ~CWBackPixel;
1087 	valuemask |= CWBackPixmap;
1088     }
1089     else
1090     {
1091 	attributes.background_pixel =
1092 	    scr->components[MWM_RESIZE_H].background;
1093 	valuemask &= ~CWBackPixmap;
1094 	valuemask |= CWBackPixel;
1095     }
1096     if (tmp_win->decorations & MWM_DECOR_RESIZEH)
1097     {
1098 	/* Just dump the windows any old place and let
1099 	 * DEC_ConfigureDecorations take care of the mess */
1100 	attributes.save_under = scr->components[MWM_RESIZE_H].save_under;
1101 	for (i = 0; i < 4; i++)
1102 	{
1103 	    attributes.cursor = scr->cursors[TOP_LEFT_CURS + i];
1104 	    tmp_win->corners[i] =
1105 		XCreateWindow(dpy, tmp_win->frame, 0, 0,
1106 			      tmp_win->corner_width, tmp_win->corner_width,
1107 			      0, CopyFromParent, InputOutput,
1108 			      CopyFromParent, valuemask, &attributes);
1109 	}
1110     }
1111     else
1112     {
1113 	for (i = 0; i < 4; i++)
1114 	    tmp_win->corners[i] = None;
1115     }
1116 
1117     if (scr->components[MWM_TITLE_A].background_pixmap
1118 	!= XmUNSPECIFIED_PIXMAP)
1119     {
1120 	attributes.background_pixmap =
1121 	    scr->components[MWM_TITLE_A].background_pixmap;
1122 	valuemask &= ~CWBackPixel;
1123 	valuemask |= CWBackPixmap;
1124     }
1125     else
1126     {
1127 	attributes.background_pixel =
1128 	    scr->components[MWM_TITLE_A].background;
1129 	valuemask &= ~CWBackPixmap;
1130 	valuemask |= CWBackPixel;
1131     }
1132     if (tmp_win->decorations & MWM_DECOR_TITLE)
1133     {
1134 	tmp_win->title_x = tmp_win->boundary_width + tmp_win->title_height + 1;
1135 	tmp_win->title_y = tmp_win->boundary_width;
1136 	attributes.cursor = scr->cursors[TITLE_CURS];
1137 	attributes.save_under = scr->components[MWM_TITLE_A].save_under;
1138 	tmp_win->title =
1139 	    XCreateWindow(dpy, tmp_win->frame,
1140 			  tmp_win->title_x, tmp_win->title_y,
1141 			  tmp_win->title_width, tmp_win->title_height,
1142 			  0,
1143 			  CopyFromParent, InputOutput, CopyFromParent,
1144 			  valuemask, &attributes);
1145     }
1146     else
1147 	tmp_win->title = None;
1148 
1149     if (scr->components[MWM_MENU_B].background_pixmap
1150 	!= XmUNSPECIFIED_PIXMAP)
1151     {
1152 	attributes.background_pixmap =
1153 	    scr->components[MWM_MENU_B].background_pixmap;
1154 	valuemask &= ~CWBackPixel;
1155 	valuemask |= CWBackPixmap;
1156     }
1157     else
1158     {
1159 	attributes.background_pixel =
1160 	    scr->components[MWM_MENU_B].background;
1161 	valuemask &= ~CWBackPixmap;
1162 	valuemask |= CWBackPixel;
1163     }
1164     if (tmp_win->decorations & MWM_DECOR_MENU)
1165     {
1166 	attributes.cursor = scr->cursors[SYS_CURS];
1167 	attributes.save_under = scr->components[MWM_MENU_B].save_under;
1168 	tmp_win->menub =
1169 	    XCreateWindow(dpy, tmp_win->frame,
1170 			  tmp_win->title_height, 0,
1171 			  tmp_win->title_height, tmp_win->title_height,
1172 			  0,
1173 			  CopyFromParent, InputOutput, CopyFromParent,
1174 			  valuemask, &attributes);
1175     }
1176     else
1177 	tmp_win->menub = None;
1178 
1179     if (scr->components[MWM_MINIMIZE_B].background_pixmap
1180 	!= XmUNSPECIFIED_PIXMAP)
1181     {
1182 	attributes.background_pixmap =
1183 	    scr->components[MWM_MINIMIZE_B].background_pixmap;
1184 	valuemask &= ~CWBackPixel;
1185 	valuemask |= CWBackPixmap;
1186     }
1187     else
1188     {
1189 	attributes.background_pixel =
1190 	    scr->components[MWM_MINIMIZE_B].background;
1191 	valuemask &= ~CWBackPixmap;
1192 	valuemask |= CWBackPixel;
1193     }
1194     if (tmp_win->decorations & MWM_DECOR_MINIMIZE)
1195     {
1196 	attributes.save_under = scr->components[MWM_MINIMIZE_B].save_under;
1197 	tmp_win->minimizeb =
1198 	    XCreateWindow(dpy, tmp_win->frame,
1199 			  tmp_win->title_width -
1200 			  tmp_win->title_height * 2, 0,
1201 			  tmp_win->title_height, tmp_win->title_height,
1202 			  0,
1203 			  CopyFromParent, InputOutput, CopyFromParent,
1204 			  valuemask, &attributes);
1205     }
1206     else
1207 	tmp_win->minimizeb = None;
1208 
1209     if (scr->components[MWM_MAXIMIZE_B].background_pixmap
1210 	!= XmUNSPECIFIED_PIXMAP)
1211     {
1212 	attributes.background_pixmap =
1213 	    scr->components[MWM_MAXIMIZE_B].background_pixmap;
1214 	valuemask &= ~CWBackPixel;
1215 	valuemask |= CWBackPixmap;
1216     }
1217     else
1218     {
1219 	attributes.background_pixel =
1220 	    scr->components[MWM_MAXIMIZE_B].background;
1221 	valuemask &= ~CWBackPixmap;
1222 	valuemask |= CWBackPixel;
1223     }
1224     if (tmp_win->decorations & MWM_DECOR_MAXIMIZE)
1225     {
1226 	attributes.save_under = scr->components[MWM_MAXIMIZE_B].save_under;
1227 	tmp_win->maximizeb =
1228 	    XCreateWindow(dpy, tmp_win->frame,
1229 			  tmp_win->title_width -
1230 			  tmp_win->title_height * 1, 0,
1231 			  tmp_win->title_height, tmp_win->title_height,
1232 			  0,
1233 			  CopyFromParent, InputOutput, CopyFromParent,
1234 			  valuemask, &attributes);
1235     }
1236     else
1237 	tmp_win->maximizeb = None;
1238 
1239     if (scr->components[MWM_BORDER].background_pixmap
1240 	!= XmUNSPECIFIED_PIXMAP)
1241     {
1242 	attributes.background_pixmap =
1243 	    scr->components[MWM_BORDER].background_pixmap;
1244 	valuemask &= ~CWBackPixel;
1245 	valuemask |= CWBackPixmap;
1246     }
1247     else
1248     {
1249 	attributes.background_pixel =
1250 	    scr->components[MWM_BORDER].background;
1251 	valuemask &= ~CWBackPixmap;
1252 	valuemask |= CWBackPixel;
1253     }
1254     if (tmp_win->decorations & MWM_DECOR_BORDER)
1255     {
1256 	attributes.save_under = scr->components[MWM_BORDER].save_under;
1257 	for (i = 0; i < 4; i++)
1258 	{
1259 	    attributes.cursor = scr->cursors[TOP_CURS + i];
1260 	    tmp_win->sides[i] =
1261 		XCreateWindow(dpy, tmp_win->frame,
1262 			      0, 0,
1263 			      tmp_win->boundary_width, tmp_win->boundary_width,
1264 			      0,
1265 			      CopyFromParent, InputOutput, CopyFromParent,
1266 			      valuemask, &attributes);
1267 	}
1268     }
1269     else
1270     {
1271 	for (i = 0; i < 4; i++)
1272 	    tmp_win->sides[i] = None;
1273     }
1274 
1275     XMapSubwindows(dpy, tmp_win->frame);
1276     XLowerWindow(dpy, tmp_win->shield);
1277     XRaiseWindow(dpy, tmp_win->parent);
1278     XReparentWindow(dpy, tmp_win->w, tmp_win->parent,
1279 		    tmp_win->matte_width, tmp_win->matte_width);
1280 
1281     valuemask = (CWEventMask | CWDontPropagate);
1282     attributes.event_mask = (StructureNotifyMask | PropertyChangeMask |
1283 			     VisibilityChangeMask | EnterWindowMask |
1284 			     LeaveWindowMask | ColormapChangeMask |
1285 			     FocusChangeMask);
1286 
1287     if (tmp_win->w == scr->pager_win)
1288     {
1289 	scr->mwm_pager = tmp_win;
1290 	tmp_win->flags |= STICKY;
1291 	attributes.event_mask |= ButtonPressMask | ButtonReleaseMask |
1292 	    ExposureMask | ButtonMotionMask;
1293 	attributes.do_not_propagate_mask = ButtonPressMask;
1294     }
1295     else
1296 	attributes.do_not_propagate_mask = ButtonPressMask | ButtonReleaseMask;
1297 
1298     valuemask |= CWBackingStore;
1299     attributes.backing_store = WhenMapped;
1300 
1301     XChangeWindowAttributes(dpy, tmp_win->w, valuemask, &attributes);
1302 }
1303 
1304 /*
1305  *  Inputs:
1306  *      tmp_win - the MwmWindow pointer
1307  *      x       - the x coordinate of the upper-left outer corner of the frame
1308  *      y       - the y coordinate of the upper-left outer corner of the frame
1309  *      w       - the width of the frame window w/o border
1310  *      h       - the height of the frame window w/o border
1311  *
1312  *  Special Considerations:
1313  *      This routine will check to make sure the window is not completely
1314  *      off the display, if it is, it'll bring some of it back on.
1315  *
1316  *      The tmp_win->frame_XXX variables should NOT be updated with the
1317  *      values of x,y,w,h prior to calling this routine, since the new
1318  *      values are compared against the old to see whether a synthetic
1319  *      ConfigureNotify event should be sent.  (It should be sent if the
1320  *      window was moved but not resized.)
1321  *
1322  */
1323 void
DEC_ConfigureDecorations(ScreenInfo * scr,MwmWindow * tmp_win,int x,int y,int w,int h,Boolean sendEvent)1324 DEC_ConfigureDecorations(ScreenInfo *scr, MwmWindow *tmp_win,
1325 			 int x, int y, int w, int h, Boolean sendEvent)
1326 {
1327     XEvent client_event;
1328     XWindowChanges frame_wc, xwc;
1329     unsigned long frame_mask, xwcm;
1330     int cx, cy, i;
1331     Bool Resized = False;
1332     MwmWindow *t;
1333     int xwidth, ywidth;
1334 
1335     /* if windows is not being maximized, save size in case of maximization */
1336     if (!(tmp_win->flags & MAXIMIZED))
1337     {
1338 	tmp_win->orig_x = x;
1339 	tmp_win->orig_y = y;
1340 	tmp_win->orig_wd = w;
1341 	tmp_win->orig_ht = h;
1342     }
1343 
1344     /* make sure we stay on the screen -- used to be DontMoveOff */
1345     if (x + scr->virt_x + w < 16)
1346 	x = 16 - scr->virt_x - w;
1347     if (y + scr->virt_y + h < 16)
1348 	y = 16 - scr->virt_y - h;
1349 
1350     if (x >= scr->d_width + scr->virt_x_max - scr->virt_x - 16)
1351 	x = scr->d_width + scr->virt_x_max - scr->virt_x - 16;
1352     if (y >= scr->d_height + scr->virt_y_max - scr->virt_y - 16)
1353 	y = scr->d_height + scr->virt_y_max - scr->virt_y - 16;
1354 
1355     /*
1356      * According to the July 27, 1988 ICCCM draft, we should send a
1357      * "synthetic" ConfigureNotify event to the client if the window
1358      * was moved but not resized.
1359      */
1360     if ((x != tmp_win->frame_x || y != tmp_win->frame_y) &&
1361 	(w == tmp_win->frame_width && h == tmp_win->frame_height))
1362 	sendEvent = True;
1363 
1364     if ((w != tmp_win->frame_width) || (h != tmp_win->frame_height))
1365 	Resized = True;
1366 
1367     if (Resized)
1368     {
1369 	if (tmp_win->menub != None && tmp_win->minimizeb != None &&
1370 	    tmp_win->maximizeb != None)
1371 	{
1372 	    tmp_win->title_width = w - 3 * tmp_win->title_height -
1373 		2 * tmp_win->boundary_width + tmp_win->bw;
1374 	}
1375 	else if ((tmp_win->menub != None && tmp_win->minimizeb != None) ||
1376 		 (tmp_win->menub != None && tmp_win->maximizeb != None) ||
1377 		 (tmp_win->menub != None && tmp_win->minimizeb != None))
1378 	{
1379 	    tmp_win->title_width = w - 2 * tmp_win->title_height -
1380 		2 * tmp_win->boundary_width + tmp_win->bw;
1381 	}
1382 	else if ((tmp_win->menub != None) || (tmp_win->minimizeb != None) ||
1383 		 (tmp_win->maximizeb != None))
1384 	{
1385 	    tmp_win->title_width = w - 1 * tmp_win->title_height -
1386 		2 * tmp_win->boundary_width + tmp_win->bw;
1387 	}
1388 	else
1389 	{
1390 	    tmp_win->title_width = w - 2 * tmp_win->boundary_width +
1391 		tmp_win->bw;
1392 	}
1393 
1394 
1395 	if (tmp_win->title_width < 1)
1396 	    tmp_win->title_width = 1;
1397 
1398 	if (tmp_win->decorations & MWM_DECOR_TITLE)
1399 	{
1400 	    xwcm = CWWidth | CWX | CWY;
1401 
1402 	    if (tmp_win->menub != None)
1403 		tmp_win->title_x = tmp_win->boundary_width +
1404 		    (1) * tmp_win->title_height;
1405 	    else
1406 		tmp_win->title_x = tmp_win->boundary_width;
1407 
1408 	    if (tmp_win->title_x >= w - tmp_win->boundary_width)
1409 		tmp_win->title_x = -10;
1410 	    tmp_win->title_y = tmp_win->boundary_width;
1411 
1412 	    xwc.width = tmp_win->title_width;
1413 	    xwc.x = tmp_win->title_x;
1414 	    xwc.y = tmp_win->title_y;
1415 	    XConfigureWindow(dpy, tmp_win->title, xwcm, &xwc);
1416 	}
1417 
1418 	if (tmp_win->decorations & MWM_DECOR_MENU)
1419 	{
1420 	    xwcm = CWX | CWY;
1421 	    xwc.x = tmp_win->boundary_width;
1422 	    xwc.y = tmp_win->boundary_width;
1423 
1424 	    if (tmp_win->menub != None)
1425 	    {
1426 		if (xwc.x + tmp_win->title_height < w - tmp_win->boundary_width)
1427 		    XConfigureWindow(dpy, tmp_win->menub, xwcm, &xwc);
1428 		else
1429 		{
1430 		    xwc.x = -tmp_win->title_height;
1431 		    XConfigureWindow(dpy, tmp_win->menub, xwcm, &xwc);
1432 		}
1433 		xwc.x += tmp_win->title_height;
1434 	    }
1435 	}
1436 
1437 	/* Note that we set X here.  That's because MINIMIZE will use what's
1438 	 * computed by maximize (if it's around) to adjust it's right margin */
1439 	xwc.x = w - tmp_win->boundary_width + tmp_win->bw;
1440 	if (tmp_win->decorations & MWM_DECOR_MAXIMIZE)
1441 	{
1442 	    xwcm = CWX | CWY;
1443 	    xwc.y = tmp_win->boundary_width;
1444 
1445 	    if (tmp_win->maximizeb != None)
1446 	    {
1447 		xwc.x -= tmp_win->title_height;
1448 		if (xwc.x > tmp_win->boundary_width)
1449 		    XConfigureWindow(dpy, tmp_win->maximizeb, xwcm, &xwc);
1450 		else
1451 		{
1452 		    xwc.x = -tmp_win->title_height;
1453 		    XConfigureWindow(dpy, tmp_win->maximizeb, xwcm, &xwc);
1454 		}
1455 	    }
1456 	}
1457 
1458 	if (tmp_win->decorations & MWM_DECOR_MINIMIZE)
1459 	{
1460 	    xwcm = CWX | CWY;
1461 	    /* note that X doesn't appear here.  See comment in paragraph
1462 	     * above */
1463 	    xwc.y = tmp_win->boundary_width;
1464 
1465 	    if (tmp_win->minimizeb != None)
1466 	    {
1467 		xwc.x -= tmp_win->title_height;
1468 		if (xwc.x > tmp_win->boundary_width)
1469 		    XConfigureWindow(dpy, tmp_win->minimizeb, xwcm, &xwc);
1470 		else
1471 		{
1472 		    xwc.x = -tmp_win->title_height;
1473 		    XConfigureWindow(dpy, tmp_win->minimizeb, xwcm, &xwc);
1474 		}
1475 	    }
1476 	}
1477 
1478 	if (tmp_win->decorations & MWM_DECOR_BORDER)
1479 	{
1480 	    xwcm = CWWidth | CWHeight | CWX | CWY;
1481 	    xwidth = w - 2 * tmp_win->corner_width + tmp_win->bw;
1482 	    ywidth = h - 2 * tmp_win->corner_width;
1483 
1484 	    if (xwidth < 2)
1485 		xwidth = 2;
1486 	    if (ywidth < 2)
1487 		ywidth = 2;
1488 
1489 	    for (i = 0; i < 4; i++)
1490 	    {
1491 		if (i == 0)
1492 		{
1493 		    xwc.x = tmp_win->corner_width;
1494 		    xwc.y = 0;
1495 		    xwc.height = tmp_win->boundary_width;
1496 		    xwc.width = xwidth;
1497 		}
1498 		else if (i == 1)
1499 		{
1500 		    xwc.x = w - tmp_win->boundary_width + tmp_win->bw;
1501 		    xwc.y = tmp_win->corner_width;
1502 		    xwc.width = tmp_win->boundary_width;
1503 		    xwc.height = ywidth;
1504 
1505 		}
1506 		else if (i == 2)
1507 		{
1508 		    xwc.x = tmp_win->corner_width;
1509 		    xwc.y = h - tmp_win->boundary_width + tmp_win->bw;
1510 		    xwc.height = tmp_win->boundary_width + tmp_win->bw;
1511 		    xwc.width = xwidth;
1512 		}
1513 		else
1514 		{
1515 		    xwc.x = 0;
1516 		    xwc.y = tmp_win->corner_width;
1517 		    xwc.width = tmp_win->boundary_width;
1518 		    xwc.height = ywidth;
1519 		}
1520 		XConfigureWindow(dpy, tmp_win->sides[i], xwcm, &xwc);
1521 	    }
1522 	}
1523 
1524 	if (tmp_win->decorations & MWM_DECOR_RESIZEH)
1525 	{
1526 	    xwcm = CWX | CWY;
1527 
1528 	    for (i = 0; i < 4; i++)
1529 	    {
1530 		if (i % 2)
1531 		    xwc.x = w - tmp_win->corner_width + tmp_win->bw;
1532 		else
1533 		    xwc.x = 0;
1534 
1535 		if (i / 2)
1536 		    xwc.y = h - tmp_win->corner_width;
1537 		else
1538 		    xwc.y = 0;
1539 
1540 		XConfigureWindow(dpy, tmp_win->corners[i], xwcm, &xwc);
1541 	    }
1542 	}
1543     }
1544 
1545     tmp_win->attr.width = w - 2 * tmp_win->boundary_width -
1546 	2 * tmp_win->matte_width;
1547     tmp_win->attr.height = h - tmp_win->title_height -
1548 	2 * tmp_win->boundary_width -
1549 	2 * tmp_win->matte_width;
1550     /* may need to omit the -1 for shaped windows, next two lines */
1551     cx = tmp_win->boundary_width - tmp_win->bw;
1552     cy = tmp_win->title_height + tmp_win->boundary_width - tmp_win->bw;
1553 
1554     XMoveResizeWindow(dpy, tmp_win->w,
1555 		      tmp_win->matte_width, tmp_win->matte_width,
1556 		      tmp_win->attr.width, tmp_win->attr.height);
1557     XMoveResizeWindow(dpy, tmp_win->parent, cx, cy,
1558 		      tmp_win->attr.width + 2 * tmp_win->matte_width,
1559 		      tmp_win->attr.height + 2 * tmp_win->matte_width);
1560     XMoveResizeWindow(dpy, tmp_win->shield, cx, cy,
1561 		      tmp_win->attr.width + 2 * tmp_win->matte_width,
1562 		      tmp_win->attr.height + 2 * tmp_win->matte_width);
1563 
1564     /*
1565      * fix up frame and assign size/location values in tmp_win
1566      */
1567     frame_wc.x = tmp_win->frame_x = x;
1568     frame_wc.y = tmp_win->frame_y = y;
1569     frame_wc.width = tmp_win->frame_width = w;
1570     frame_wc.height = tmp_win->frame_height = h;
1571     frame_mask = (CWX | CWY | CWWidth | CWHeight);
1572     XConfigureWindow(dpy, tmp_win->frame, frame_mask, &frame_wc);
1573 
1574 
1575     if ((Resized) && (tmp_win->wShaped))
1576     {
1577 	DEC_SetShape(tmp_win, w);
1578     }
1579     XSync(dpy, 0);
1580     if (sendEvent)
1581     {
1582 	client_event.type = ConfigureNotify;
1583 	client_event.xconfigure.display = dpy;
1584 	client_event.xconfigure.event = tmp_win->w;
1585 	client_event.xconfigure.window = tmp_win->w;
1586 
1587 	client_event.xconfigure.x = x + tmp_win->boundary_width +
1588 	    tmp_win->matte_width;
1589 	client_event.xconfigure.y = y + tmp_win->title_height +
1590 	    tmp_win->boundary_width +
1591 	    tmp_win->matte_width;
1592 	client_event.xconfigure.width = w - 2 * tmp_win->boundary_width -
1593 	    2 * tmp_win->matte_width;
1594 	client_event.xconfigure.height = h - tmp_win->title_height -
1595 	    2 * tmp_win->boundary_width -
1596 	    2 * tmp_win->matte_width;
1597 
1598 	client_event.xconfigure.border_width = tmp_win->bw;
1599 	/* Real ConfigureNotify events say we're above title window, so ... */
1600 	/* what if we don't have a title ????? */
1601 	client_event.xconfigure.above = tmp_win->frame;
1602 	client_event.xconfigure.override_redirect = False;
1603 	XSendEvent(dpy, tmp_win->w, False, StructureNotifyMask, &client_event);
1604     }
1605     if (tmp_win == scr->mwm_pager)
1606     {
1607 	PAGER_UpdateViewPort(scr);
1608 	for (t = scr->mwm_root.next; t != NULL; t = t->next)
1609 	{
1610 	    PAGER_UpdateView(scr, t);
1611 	}
1612     }
1613     else
1614 	PAGER_UpdateView(scr, tmp_win);
1615 }
1616 
1617 
1618 
1619 /*
1620  *  draws the title bar
1621  */
1622 void
DEC_DrawTitleBar(ScreenInfo * scr,MwmWindow * t,Bool onoroff,Bool NewTitle)1623 DEC_DrawTitleBar(ScreenInfo *scr, MwmWindow *t, Bool onoroff, Bool NewTitle)
1624 {
1625     int hor_off, w;
1626     GC ReliefGC, ShadowGC;
1627     Pixel Forecolor, BackColor;
1628 
1629     if (!t)
1630 	return;
1631     if (!(t->decorations & MWM_DECOR_TITLE))
1632 	return;
1633 
1634     if (onoroff)
1635     {
1636 	Forecolor = scr->components[MWM_TITLE_A].active_foreground;
1637 	BackColor = scr->components[MWM_TITLE_A].active_background;
1638 	ReliefGC = scr->pressed_win == t->title
1639 	    ? scr->components[MWM_TITLE_A].active_bot_GC
1640 	    : scr->components[MWM_TITLE_A].active_top_GC;
1641 	ShadowGC = scr->pressed_win == t->title
1642 	    ? scr->components[MWM_TITLE_A].active_top_GC
1643 	    : scr->components[MWM_TITLE_A].active_bot_GC;
1644     }
1645     else
1646     {
1647 	Forecolor = scr->components[MWM_TITLE_A].foreground;
1648 	BackColor = scr->components[MWM_TITLE_A].background;
1649 	ReliefGC = scr->pressed_win == t->title
1650 	    ? scr->components[MWM_TITLE_A].bot_GC
1651 	    : scr->components[MWM_TITLE_A].top_GC;
1652 	ShadowGC = scr->pressed_win == t->title
1653 	    ? scr->components[MWM_TITLE_A].top_GC
1654 	    : scr->components[MWM_TITLE_A].bot_GC;
1655     }
1656     MISC_FlushExpose(t->title);
1657 
1658     if (t->name != (char *)NULL)
1659     {
1660 	w = XTextWidth(scr->components[MWM_TITLE_A].font,
1661 		       t->name, strlen(t->name));
1662 	if (w > t->title_width - 12)
1663 	    w = t->title_width - 4;
1664 	if (w < 0)
1665 	    w = 0;
1666     }
1667     else
1668 	w = 0;
1669 
1670 
1671     hor_off = (t->title_width - w) / 2;
1672 
1673     if (NewTitle)
1674 	XClearWindow(dpy, t->title);
1675 
1676     if (t->name != (char *)NULL)
1677     {
1678 	if (scr->clean_text)
1679 	{
1680 	    XClearArea(dpy, t->title,
1681 		       hor_off - 2, 0, w + 4, t->title_height, False);
1682 	}
1683 
1684 	XDrawImageString(dpy, t->title,
1685 			 onoroff
1686 			 ? scr->components[MWM_TITLE_A].active_GC
1687 			 : scr->components[MWM_TITLE_A].normal_GC,
1688 			 hor_off,
1689 			 scr->components[MWM_TITLE_A].f_y + 2,
1690 			 t->name, strlen(t->name));
1691 
1692 	DEC_DrawShadows(t, t->title, 0, 0, t->title_width, t->title_height,
1693 			ReliefGC, ShadowGC);
1694     }
1695 
1696     XFlush(dpy);
1697 }
1698 
1699 /*
1700  * draws the windows decorations
1701  */
1702 void
DEC_DrawDecorations(ScreenInfo * scr,MwmWindow * t,Bool onoroff,Bool force,Bool Mapped,Window expose_win)1703 DEC_DrawDecorations(ScreenInfo *scr, MwmWindow *t,
1704 		    Bool onoroff, Bool force, Bool Mapped, Window expose_win)
1705 {
1706     Window w = None;
1707     int y, x;
1708     Bool NewColor = False;
1709     XSetWindowAttributes attributes;
1710     unsigned long valuemask;
1711     GC top_GC, bot_GC;
1712 
1713     if (!t)
1714 	return;
1715 
1716     if (onoroff)
1717     {
1718 	/* don't re-draw just for kicks */
1719 	if ((!force) && (scr->mwm_highlight == t))
1720 	    return;
1721 
1722 	if (scr->mwm_highlight != t)
1723 	    NewColor = True;
1724 
1725 	/* make sure that the previously highlighted window got unhighlighted */
1726 	if ((scr->mwm_highlight != t) && (scr->mwm_highlight != NULL))
1727 	    DEC_DrawDecorations(scr, scr->mwm_highlight, False, False, True, None);
1728 
1729 	/* set the keyboard focus */
1730 	if ((Mapped) && (t->flags & MAPPED) && (scr->mwm_highlight != t))
1731 	    w = t->w;
1732 	else if ((t->flags & ICONIFIED) && scr->mwm_highlight != t)
1733 	    w = t->icon_w;
1734 	scr->mwm_highlight = t;
1735     }
1736     else
1737     {
1738 	/* don't re-draw just for kicks */
1739 	if ((!force) && (scr->mwm_highlight != t))
1740 	    return;
1741 
1742 	if (scr->mwm_highlight == t)
1743 	{
1744 	    scr->mwm_highlight = NULL;
1745 	    NewColor = True;
1746 	}
1747     }
1748 
1749     if ((scr->pager_win) && !(t->flags & STICKY))
1750     {
1751 	if (NewColor)
1752 	{
1753 	    if (scr->components[MWM_PAGER].background_pixmap
1754 		!= XmUNSPECIFIED_PIXMAP)
1755 		XSetWindowBackgroundPixmap(dpy,
1756 					   t->pager_view,
1757 				 scr->components[MWM_PAGER].background_pixmap);
1758 	    else
1759 		XSetWindowBackground(dpy, t->pager_view,
1760 				     scr->components[MWM_PAGER].background);
1761 	    XClearWindow(dpy, t->pager_view);
1762 	}
1763 
1764 	if ((t->icon_image != NULL) &&
1765 	    (scr->components[MWM_PAGER].f_height > 0))
1766 	{
1767 	    XDrawImageString(dpy, t->pager_view,
1768 			     scr->components[MWM_PAGER].normal_GC,
1769 			     2, scr->components[MWM_PAGER].f_y + 2,
1770 			     t->icon_image, strlen(t->icon_image));
1771 	}
1772     }
1773 
1774     if (t->flags & ICONIFIED)
1775     {
1776 	ICON_DrawWindow(scr, t);
1777 	return;
1778     }
1779 
1780     set_value_attributes(scr, t, &valuemask, &attributes, &scr->components[MWM_BORDER]);
1781 
1782     if (t->decorations & (MWM_DECOR_TITLE | MWM_DECOR_BORDER))
1783     {
1784 	XSetWindowBorder(dpy, t->parent, attributes.background_pixel);
1785 	XSetWindowBorder(dpy, t->frame, attributes.background_pixel);
1786     }
1787 
1788 
1789     if (t->decorations & MWM_DECOR_TITLE)
1790     {
1791 	set_value_attributes(scr, t, &valuemask, &attributes, &scr->components[MWM_TITLE_A]);
1792 	if (NewColor)
1793 	{
1794 	    XChangeWindowAttributes(dpy, t->title, valuemask, &attributes);
1795 	    XClearWindow(dpy, t->title);
1796 	}
1797     }
1798     if (t->decorations & MWM_DECOR_MENU)
1799     {
1800 	if (t->menub != None)
1801 	{
1802 	    set_value_attributes(scr, t, &valuemask, &attributes, &scr->components[MWM_MENU_B]);
1803 	    if (scr->mwm_highlight == t)
1804 	    {
1805 		top_GC = scr->components[MWM_MENU_B].active_top_GC;
1806 		bot_GC = scr->components[MWM_MENU_B].active_bot_GC;
1807 	    }
1808 	    else
1809 	    {
1810 		top_GC = scr->components[MWM_MENU_B].top_GC;
1811 		bot_GC = scr->components[MWM_MENU_B].bot_GC;
1812 	    }
1813 	    if (NewColor)
1814 	    {
1815 		XChangeWindowAttributes(dpy, t->menub, valuemask, &attributes);
1816 		XClearWindow(dpy, t->menub);
1817 	    }
1818 	    if (MISC_FlushExpose(t->menub) || (expose_win == t->menub) ||
1819 		(expose_win == None))
1820 	    {
1821 		DEC_DrawShadows(t, t->menub, 0, 0, t->title_height,
1822 				t->title_height,
1823 				(scr->pressed_win == t->menub
1824 				 ? bot_GC
1825 				 : top_GC),
1826 				(scr->pressed_win == t->menub
1827 				 ? top_GC
1828 				 : bot_GC));
1829 		draw_pattern(t->menub, top_GC, bot_GC,
1830 			     lbut_styles[0],
1831 			     lbut_styles[1],
1832 			     t->title_height);
1833 	    }
1834 	}
1835     }
1836 
1837     if (t->decorations & MWM_DECOR_MAXIMIZE)
1838     {
1839 	if (t->maximizeb != None)
1840 	{
1841 	    set_value_attributes(scr, t, &valuemask, &attributes,
1842 				 &scr->components[MWM_MAXIMIZE_B]);
1843 	    if (NewColor)
1844 	    {
1845 		XChangeWindowAttributes(dpy, t->maximizeb, valuemask, &attributes);
1846 		XClearWindow(dpy, t->maximizeb);
1847 	    }
1848 	    if (scr->mwm_highlight == t)
1849 	    {
1850 		top_GC = scr->components[MWM_MAXIMIZE_B].active_top_GC;
1851 		bot_GC = scr->components[MWM_MAXIMIZE_B].active_bot_GC;
1852 	    }
1853 	    else
1854 	    {
1855 		top_GC = scr->components[MWM_MAXIMIZE_B].top_GC;
1856 		bot_GC = scr->components[MWM_MAXIMIZE_B].bot_GC;
1857 	    }
1858 	    if (MISC_FlushExpose(t->maximizeb) || (expose_win == t->maximizeb) ||
1859 		(expose_win == None))
1860 	    {
1861 		DEC_DrawShadows(t, t->maximizeb, 0, 0, t->title_height,
1862 				t->title_height,
1863 				(scr->pressed_win == t->maximizeb
1864 				 ? bot_GC
1865 				 : top_GC),
1866 				(scr->pressed_win == t->maximizeb
1867 				 ? top_GC
1868 				 : bot_GC));
1869 		draw_pattern(t->maximizeb, top_GC, bot_GC,
1870 			     rbut_style_max[0],
1871 			     rbut_style_max[1],
1872 			     t->title_height);
1873 	    }
1874 	}
1875     }
1876 
1877     if (t->decorations & MWM_DECOR_MINIMIZE)
1878     {
1879 	if (t->minimizeb != None)
1880 	{
1881 	    set_value_attributes(scr, t, &valuemask, &attributes, &scr->components[MWM_MINIMIZE_B]);
1882 	    if (NewColor)
1883 	    {
1884 		XChangeWindowAttributes(dpy, t->minimizeb, valuemask, &attributes);
1885 		XClearWindow(dpy, t->minimizeb);
1886 	    }
1887 	    if (scr->mwm_highlight == t)
1888 	    {
1889 		top_GC = scr->components[MWM_MINIMIZE_B].active_top_GC;
1890 		bot_GC = scr->components[MWM_MINIMIZE_B].active_bot_GC;
1891 	    }
1892 	    else
1893 	    {
1894 		top_GC = scr->components[MWM_MINIMIZE_B].top_GC;
1895 		bot_GC = scr->components[MWM_MINIMIZE_B].bot_GC;
1896 	    }
1897 	    if (MISC_FlushExpose(t->minimizeb) || (expose_win == t->minimizeb) ||
1898 		(expose_win == None))
1899 	    {
1900 		DEC_DrawShadows(t, t->minimizeb, 0, 0, t->title_height,
1901 				t->title_height,
1902 				(scr->pressed_win == t->minimizeb
1903 				 ? bot_GC
1904 				 : top_GC),
1905 				(scr->pressed_win == t->minimizeb
1906 				 ? top_GC
1907 				 : bot_GC));
1908 		draw_pattern(t->minimizeb, top_GC, bot_GC,
1909 			     rbut_style_min[0],
1910 			     rbut_style_min[1],
1911 			     t->title_height);
1912 	    }
1913 	}
1914     }
1915 
1916     if (t->decorations & MWM_DECOR_TITLE)
1917 	DEC_DrawTitleBar(scr, t, onoroff, False);
1918 
1919     if (t->decorations & MWM_DECOR_BORDER)
1920     {
1921 	int i;
1922 
1923 	/* draw relief lines */
1924 	y = t->frame_height - 2 * t->corner_width;
1925 	x = t->frame_width - 2 * t->corner_width + t->bw;
1926 
1927 	for (i = 0; i < 4; i++)
1928 	{
1929 	    set_value_attributes(scr, t, &valuemask, &attributes, &scr->components[MWM_BORDER]);
1930 	    if (NewColor)
1931 	    {
1932 		XChangeWindowAttributes(dpy, t->sides[i], valuemask, &attributes);
1933 		XClearWindow(dpy, t->sides[i]);
1934 	    }
1935 	    if (scr->mwm_highlight == t)
1936 	    {
1937 		top_GC = scr->components[MWM_BORDER].active_top_GC;
1938 		bot_GC = scr->components[MWM_BORDER].active_bot_GC;
1939 	    }
1940 	    else
1941 	    {
1942 		top_GC = scr->components[MWM_BORDER].top_GC;
1943 		bot_GC = scr->components[MWM_BORDER].bot_GC;
1944 	    }
1945 
1946 	    if ((MISC_FlushExpose(t->sides[i])) || (expose_win == t->sides[i]) ||
1947 		(expose_win == None))
1948 	    {
1949 		GC sgc, rgc;
1950 
1951 		sgc = bot_GC;
1952 		rgc = top_GC;
1953 		/* index    side
1954 		 * 0        TOP
1955 		 * 1        RIGHT
1956 		 * 2        BOTTOM
1957 		 * 3        LEFT
1958 		 */
1959 
1960 		if (t->decorations & MWM_DECOR_RESIZEH)
1961 		    DEC_DrawShadows(t, t->sides[i], 0, 0,
1962 				    ((i % 2) ? t->boundary_width : x),
1963 				    ((i % 2) ? y : t->boundary_width),
1964 				    rgc, sgc);
1965 		else
1966 		    DEC_DrawBorder(t, t->sides[i], 0, 0,
1967 				   ((i % 2) ? t->boundary_width : x),
1968 				   ((i % 2) ? y : t->boundary_width),
1969 				   rgc, sgc);
1970 	    }
1971 	}
1972     }
1973 
1974 
1975     if (t->decorations & MWM_DECOR_RESIZEH)
1976     {
1977 	int i;
1978 
1979 	/* draw relief lines */
1980 	y = t->frame_height - 2 * t->corner_width;
1981 	x = t->frame_width - 2 * t->corner_width + t->bw;
1982 
1983 	for (i = 0; i < 4; i++)
1984 	{
1985 	    set_value_attributes(scr, t, &valuemask, &attributes, &scr->components[MWM_RESIZE_H]);
1986 	    if (NewColor)
1987 	    {
1988 		XChangeWindowAttributes(dpy, t->corners[i], valuemask, &attributes);
1989 		XClearWindow(dpy, t->corners[i]);
1990 	    }
1991 	    if (scr->mwm_highlight == t)
1992 	    {
1993 		top_GC = scr->components[MWM_RESIZE_H].active_top_GC;
1994 		bot_GC = scr->components[MWM_RESIZE_H].active_bot_GC;
1995 	    }
1996 	    else
1997 	    {
1998 		top_GC = scr->components[MWM_RESIZE_H].top_GC;
1999 		bot_GC = scr->components[MWM_RESIZE_H].bot_GC;
2000 	    }
2001 	    if ((MISC_FlushExpose(t->corners[i])) ||
2002 		(expose_win == t->corners[i]) || (expose_win == None))
2003 	    {
2004 		GC rgc, sgc;
2005 
2006 		rgc = top_GC;
2007 		sgc = bot_GC;
2008 		DEC_DrawShadows(t, t->corners[i], 0, 0, t->corner_width,
2009 				(i / 2)
2010 				? t->corner_width + t->bw
2011 				: t->corner_width,
2012 				rgc, sgc);
2013 		if (t->boundary_width > 1)
2014 		    draw_corners(t, i, ((i / 2) ? rgc : sgc), ((i % 2) ? rgc : sgc));
2015 		else
2016 		    draw_corners(t, i, ((i / 2) ? sgc : sgc), ((i % 2) ? sgc : sgc));
2017 	    }
2018 	}
2019     }
2020 
2021     if (t->matte_width > 1)
2022     {
2023 	if (MISC_FlushExpose(t->parent) || expose_win == t->parent ||
2024 	    expose_win == None)
2025 	{
2026 	    XGCValues gcv;
2027 	    unsigned long gcm;
2028 
2029 	    if (t->matte_bottom_shadow_pixmap != None &&
2030 		t->matte_bottom_shadow_pixmap != XmUNSPECIFIED_PIXMAP)
2031 	    {
2032 		gcm = GCTile | GCFillStyle;
2033 
2034 		gcv.tile = t->matte_bottom_shadow_pixmap;
2035 		gcv.fill_style = FillTiled;
2036 	    }
2037 	    else
2038 	    {
2039 		gcm = GCForeground | GCBackground;
2040 
2041 		gcv.foreground = t->matte_bottom_shadow_color;
2042 		gcv.background = t->matte_background;
2043 	    }
2044 	    gcm |= GCLineWidth | GCLineStyle | GCCapStyle | GCGraphicsExposures;
2045 	    gcv.line_width = 0;
2046 	    gcv.line_style = LineSolid;
2047 	    gcv.cap_style = CapButt;
2048 	    gcv.graphics_exposures = False;
2049 	    XChangeGC(dpy, scr->matte_bs_GC, gcm, &gcv);
2050 
2051 	    if (t->matte_top_shadow_pixmap != None &&
2052 		t->matte_top_shadow_pixmap != XmUNSPECIFIED_PIXMAP)
2053 	    {
2054 		gcm = GCTile | GCFillStyle;
2055 
2056 		gcv.tile = t->matte_top_shadow_pixmap;
2057 		gcv.fill_style = FillTiled;
2058 	    }
2059 	    else
2060 	    {
2061 		gcm = GCForeground | GCBackground;
2062 
2063 		gcv.foreground = t->matte_top_shadow_color;
2064 		gcv.background = t->matte_background;
2065 	    }
2066 	    gcm |= GCLineWidth | GCLineStyle | GCCapStyle | GCGraphicsExposures;
2067 	    gcv.line_width = 0;
2068 	    gcv.line_style = LineSolid;
2069 	    gcv.cap_style = CapButt;
2070 	    gcv.graphics_exposures = False;
2071 	    XChangeGC(dpy, scr->matte_ts_GC, gcm, &gcv);
2072 
2073 	    if (t->matte_width > 3)
2074 	    {
2075 		DEC_DrawShadows(t, t->parent, 0, 0,
2076 				t->attr.width + 2 * t->matte_width,
2077 				t->attr.height + 2 * t->matte_width,
2078 				scr->matte_ts_GC, scr->matte_bs_GC);
2079 		relieve_rectangle(t->parent,
2080 				  t->matte_width - 2, t->matte_width - 2,
2081 				  t->attr.width + 4, t->attr.height + 4,
2082 				  scr->matte_bs_GC, scr->matte_ts_GC);
2083 	    }
2084 	    else
2085 	    {
2086 		DEC_DrawShadows(t, t->parent,
2087 				t->matte_width - 2, t->matte_width - 2,
2088 				t->attr.width + 3, t->attr.height + 3,
2089 				scr->matte_bs_GC, scr->matte_ts_GC);
2090 	    }
2091 	}
2092     }
2093 
2094     if (!(t->decorations & MWM_DECOR_BORDER))
2095     {				/* no decorative border */
2096 	/* for mono - put a black border on
2097 	 * for color, make it the color of the decoration background */
2098 	if (t->boundary_width < 2)
2099 	{
2100 	    MISC_FlushExpose(t->frame);
2101 	    XSetWindowBorder(dpy, t->frame, scr->components[MWM_BORDER].background);
2102 	    XSetWindowBorder(dpy, t->parent, scr->components[MWM_BORDER].background);
2103 	    if (scr->components[MWM_BORDER].background_pixmap)
2104 		XSetWindowBackgroundPixmap(dpy, t->frame, scr->components[MWM_BORDER].background_pixmap);
2105 	    XClearWindow(dpy, t->frame);
2106 	    if (scr->components[MWM_BORDER].background_pixmap)
2107 		XSetWindowBackgroundPixmap(dpy, t->parent, scr->components[MWM_BORDER].background_pixmap);
2108 	    XClearWindow(dpy, t->parent);
2109 	}
2110 	else
2111 	{
2112 	    GC rgc, sgc;
2113 
2114 	    if (scr->mwm_highlight == t)
2115 	    {
2116 		top_GC = scr->components[MWM_BORDER].active_top_GC;
2117 		bot_GC = scr->components[MWM_BORDER].active_bot_GC;
2118 	    }
2119 	    else
2120 	    {
2121 		top_GC = scr->components[MWM_BORDER].top_GC;
2122 		bot_GC = scr->components[MWM_BORDER].bot_GC;
2123 	    }
2124 	    XSetWindowBorder(dpy, t->parent, scr->components[MWM_BORDER].background);
2125 	    XSetWindowBorder(dpy, t->frame, scr->components[MWM_BORDER].background);
2126 
2127 	    rgc = top_GC;
2128 	    sgc = bot_GC;
2129 	    if (NewColor)
2130 	    {
2131 		XChangeWindowAttributes(dpy, t->frame, valuemask, &attributes);
2132 		XClearWindow(dpy, t->frame);
2133 	    }
2134 	    if ((MISC_FlushExpose(t->frame)) || (expose_win == t->frame) ||
2135 		(expose_win == None))
2136 	    {
2137 		if (t->boundary_width > 2)
2138 		{
2139 		    DEC_DrawShadows(t, t->frame, t->boundary_width - 1 - t->bw,
2140 				    t->boundary_width - 1 - t->bw,
2141 				    t->frame_width -
2142 				    (t->boundary_width << 1) + 2 + 3 * t->bw,
2143 				    t->frame_height -
2144 				    (t->boundary_width << 1) + 2 + 3 * t->bw,
2145 				    sgc, rgc);
2146 		    DEC_DrawShadows(t, t->frame, 0, 0, t->frame_width + t->bw,
2147 				    t->frame_height + t->bw, rgc, sgc);
2148 		}
2149 		else
2150 		{
2151 		    DEC_DrawShadows(t, t->frame, 0, 0, t->frame_width + t->bw,
2152 				    t->frame_height + t->bw, rgc, rgc);
2153 		}
2154 	    }
2155 	    else
2156 	    {
2157 		XSetWindowBackground(dpy, t->parent, scr->components[MWM_BORDER].background);
2158 	    }
2159 	}
2160     }
2161 }
2162 
2163 /*
2164  * set up the shaped window borders
2165  */
2166 void
DEC_SetShape(MwmWindow * tmp_win,int w)2167 DEC_SetShape(MwmWindow *tmp_win, int w)
2168 {
2169     XRectangle rect;
2170 
2171     XShapeCombineShape(dpy, tmp_win->frame, ShapeBounding,
2172 		       tmp_win->boundary_width,
2173 		       tmp_win->title_height + tmp_win->boundary_width,
2174 		       tmp_win->w,
2175 		       ShapeBounding, ShapeSet);
2176     if (tmp_win->title)
2177     {
2178 	/* windows w/ titles */
2179 	rect.x = tmp_win->boundary_width;
2180 	rect.y = tmp_win->title_y;
2181 	rect.width = w - 2 * tmp_win->boundary_width + tmp_win->bw;
2182 	rect.height = tmp_win->title_height;
2183 
2184 
2185 	XShapeCombineRectangles(dpy, tmp_win->frame, ShapeBounding,
2186 				0, 0, &rect, 1, ShapeUnion, Unsorted);
2187     }
2188 }
2189