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