1 /*
2 * Copyright (C) 1995, 1996 Karl-Johan Johnsson.
3 */
4
5 #include <X11/IntrinsicP.h>
6 #include <X11/StringDefs.h>
7
8 #include "Compat.h"
9 #include "ShadowP.h"
10 #include "Util.h"
11
12 static XtResource resources[] = {
13 {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
14 XtOffsetOf(ShadowRec, core.border_width), XtRImmediate, (XtPointer)0},
15 #define offset(field) XtOffsetOf(ShadowRec, shadow.field)
16 {XtNshadowWidth, XtCShadowWidth, XtRDimension, sizeof(Dimension),
17 offset(shadow_width), XtRImmediate, (XtPointer)2},
18 {XtNallocArmColor, XtCAllocArmColor, XtRBoolean, sizeof(Boolean),
19 offset(alloc_arm_color), XtRImmediate, (XtPointer)True},
20 {XtNallocArmPixmap, XtCAllocArmPixmap, XtRBoolean, sizeof(Boolean),
21 offset(alloc_arm_pixmap), XtRImmediate, (XtPointer)True},
22 {XtNallocShadowColors, XtCAllocShadowColors, XtRBoolean, sizeof(Boolean),
23 offset(alloc_shadow_colors), XtRImmediate, (XtPointer)True},
24 {XtNuseLineShadows, XtCUseLineShadows, XtRBoolean, sizeof(Boolean),
25 offset(use_lines), XtRImmediate, (XtPointer)False},
26 #undef offset
27 };
28
29 static void ClassPartInitialize(WidgetClass);
30 static void Initialize(Widget, Widget, ArgList, Cardinal*);
31 static void Destroy(Widget);
32 static void Realize(Widget, XtValueMask*, XSetWindowAttributes*);
33 static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal*);
34 static Boolean AllocShadowColors(ShadowWidget, XColor*);
35 static void AllocShadowPixmaps(ShadowWidget, Pixel);
36 static Boolean AllocArmColor(ShadowWidget, XColor*);
37 static void AllocArmPixmap(ShadowWidget, Pixel);
38 static void AllocGCs(ShadowWidget);
39
40 ShadowClassRec shadowClassRec = {
41 { /* core fields */
42 (WidgetClass) &widgetClassRec, /* superclass */
43 "Shadow", /* class_name */
44 sizeof(ShadowRec), /* widget_size */
45 NULL, /* class_initialize */
46 ClassPartInitialize, /* class_part_initialize */
47 FALSE, /* class_inited */
48 Initialize, /* initialize */
49 NULL, /* initialize_hook */
50 Realize, /* realize */
51 NULL, /* actions */
52 0, /* num_actions */
53 resources, /* resources */
54 XtNumber(resources), /* num_resources */
55 NULLQUARK, /* xrm_class */
56 TRUE, /* compress_motion */
57 TRUE, /* compress_exposure */
58 TRUE, /* compress_enterleave */
59 FALSE, /* visible_interest */
60 Destroy, /* destroy */
61 NULL, /* resize */
62 NULL, /* expose */
63 SetValues, /* set_values */
64 NULL, /* set_values_hook */
65 XtInheritSetValuesAlmost, /* set_values_almost */
66 NULL, /* get_values_hook */
67 NULL, /* accept_focus */
68 XtVersion, /* version */
69 NULL, /* callback_private */
70 NULL, /* tm_table */
71 NULL, /* query_geometry */
72 XtInheritDisplayAccelerator, /* display_accelerator */
73 NULL /* extension */
74 },
75 { /* shadow fields */
76 XtOffsetOf(CoreRec, core.background_pixel), /* pixel_offset */
77 False, /* use_arm_for_background */
78 AllocShadowColors, /* alloc_shadow_colors */
79 AllocShadowPixmaps, /* alloc_shadow_pixmaps */
80 AllocArmColor, /* alloc_arm_color */
81 AllocArmPixmap, /* alloc_arm_pixmap */
82 AllocGCs, /* alloc_gcs */
83 NULL, /* extension */
84 }
85 };
86
87 WidgetClass shadowWidgetClass = (WidgetClass)&shadowClassRec;
88
89 /*************************************************************************/
90
get_pixel(ShadowWidget w)91 static Pixel get_pixel(ShadowWidget w)
92 {
93 ShadowWidgetClass class = (ShadowWidgetClass)XtClass(w);
94 Cardinal offset = class->shadow_class.pixel_offset;
95
96 return *(Pixel *)((char *)w + offset);
97 }
98
99 typedef struct pixmap_cache_ref {
100 struct pixmap_cache_ref *next;
101 struct pixmap_cache_ref *prev;
102 Screen *screen;
103 Pixmap pixmap;
104 Pixel fg;
105 Pixel bg;
106 int depth;
107 int size;
108 int ref_count;
109 } PixmapCacheRef;
110
111 static PixmapCacheRef *pixmap_cache;
112
CacheCreatePixmap(ShadowWidget w,int size,Pixel fg,Pixel bg)113 static Pixmap CacheCreatePixmap(ShadowWidget w, int size, Pixel fg, Pixel bg)
114 {
115 static char bitmap2by2_data[] = {0x01, 0x02};
116 static char bitmap4by4_data[] = {0x08, 0x02, 0x04, 0x01};
117 Display *disp = XtDisplay(w);
118 Screen *screen = XtScreen(w);
119 PixmapCacheRef *loop;
120 char *bitmap_data;
121
122 for (loop = pixmap_cache ; loop ; loop = loop->next)
123 if (loop->screen == screen && loop->fg == fg && loop->bg == bg &&
124 loop->depth == w->core.depth && loop->size == size) {
125 loop->ref_count++;
126 return loop->pixmap;
127 }
128
129 switch (size) {
130 case 2:
131 bitmap_data = bitmap2by2_data;
132 break;
133 case 4:
134 bitmap_data = bitmap4by4_data;
135 break;
136 default:
137 return None;
138 }
139
140 loop = (PixmapCacheRef *)XtMalloc(sizeof(PixmapCacheRef));
141 loop->next = pixmap_cache;
142 loop->prev = NULL;
143 loop->screen = screen;
144 loop->depth = w->core.depth;
145 loop->size = size;
146 loop->fg = fg;
147 loop->bg = bg;
148 loop->ref_count = 1;
149
150 loop->pixmap =
151 XCreatePixmapFromBitmapData(disp, RootWindowOfScreen(screen),
152 bitmap_data, size, size, fg, bg,
153 w->core.depth);
154 if (pixmap_cache)
155 pixmap_cache->prev = loop;
156 pixmap_cache = loop;
157
158 return loop->pixmap;
159 }
160
CacheFreePixmap(ShadowWidget w,Pixmap pixmap)161 static void CacheFreePixmap(ShadowWidget w, Pixmap pixmap)
162 {
163 Display *disp = XtDisplay(w);
164 Screen *screen = XtScreen(w);
165 PixmapCacheRef *loop;
166
167 for (loop = pixmap_cache ; loop ; loop = loop->next)
168 if (loop->screen == screen && loop->pixmap == pixmap) {
169 PixmapCacheRef *prev = loop->prev;
170
171 loop->ref_count--;
172 if (loop->ref_count != 0)
173 break;
174
175 XFreePixmap(disp, loop->pixmap);
176
177 if (prev) {
178 prev->next = loop->next;
179 if (loop->next)
180 loop->next->prev = prev;
181 } else {
182 pixmap_cache = loop->next;
183 if (pixmap_cache)
184 pixmap_cache->prev = NULL;
185 }
186 XtFree((char *)loop);
187 break;
188 }
189 }
190
191 /*************************************************************************/
192
193 #define MIN(a, b) ((a) < (b) ? (a) : (b))
AllocShadowColors(ShadowWidget w,XColor * col)194 static Boolean AllocShadowColors(ShadowWidget w, XColor *col)
195 {
196 Display *disp = XtDisplay(w);
197 Colormap cmap = w->core.colormap;
198 XColor sh_col;
199
200 if ((col->red > 0xefff && col->green > 0xefff && col->blue > 0xefff) ||
201 (col->red < 0x1000 && col->green < 0x1000 && col->blue < 0x1000)) {
202 sh_col.red = 65535L * 4 / 5;
203 sh_col.green = 65535L * 4 / 5;
204 sh_col.blue = 65535L * 4 / 5;
205 if (!XAllocColor(disp, cmap, &sh_col))
206 return False;
207 w->shadow.light_pixel = sh_col.pixel;
208
209 sh_col.red = 65535L * 3 /5;
210 sh_col.green = 65535L * 3 /5;
211 sh_col.blue = 65535L * 3 /5;
212 if (!XAllocColor(disp, cmap, &sh_col)) {
213 unsigned long tmp = w->shadow.light_pixel;
214
215 XFreeColors(disp, cmap, &tmp, 1, 0);
216 return False;
217 }
218 w->shadow.dark_pixel = sh_col.pixel;
219 } else {
220 sh_col.red = MIN (65535, 6 * (long)col->red / 5);
221 sh_col.green = MIN (65535, 6 * (long)col->green / 5);
222 sh_col.blue = MIN (65535, 6 * (long)col->blue / 5);
223 if (!XAllocColor(disp, cmap, &sh_col))
224 return False;
225 w->shadow.light_pixel = sh_col.pixel;
226
227 sh_col.red = MIN (65535, 3 * (long)col->red / 5);
228 sh_col.green = MIN (65535, 3 * (long)col->green / 5);
229 sh_col.blue = MIN (65535, 3 * (long)col->blue / 5);
230 if (!XAllocColor(disp, cmap, &sh_col)) {
231 unsigned long tmp = w->shadow.light_pixel;
232
233 XFreeColors(disp, cmap, &tmp, 1, 0);
234 return False;
235 }
236 w->shadow.dark_pixel = sh_col.pixel;
237 }
238
239 return True;
240 }
241 #undef MIN
242
AllocShadowPixmaps(ShadowWidget w,Pixel pix)243 static void AllocShadowPixmaps(ShadowWidget w, Pixel pix)
244 {
245 if (w->core.depth == 1)
246 w->shadow.light_pixmap = CacheCreatePixmap(w, 2, 0, 1);
247 else {
248 Screen *screen = XtScreen(w);
249 Visual *visual = get_visual((Widget)w);
250 Pixel black, white;
251
252 black_and_white(screen, visual, &black, &white);
253 w->shadow.light_pixmap = CacheCreatePixmap(w, 2, pix, white);
254 w->shadow.dark_pixmap = CacheCreatePixmap(w, 2, pix, black);
255 }
256 }
257
AllocArmColor(ShadowWidget w,XColor * col)258 static Boolean AllocArmColor(ShadowWidget w, XColor *col)
259 {
260 Display *disp = XtDisplay(w);
261 Colormap cmap = w->core.colormap;
262 XColor arm_col;
263 long t, r, g, b;
264
265 t = col->red + col->green + col->blue;
266 t /= 3;
267 r = 3 * t / 4 + 3 * ((long)col->red - t) / 2;
268 g = 3 * t / 4 + 3 * ((long)col->green - t) / 2;
269 b = 3 * t / 4 + 3 * ((long)col->blue - t) / 2;
270 if (r < 0)
271 r = 0;
272 else if (r > 65535)
273 r = 65535;
274 if (g < 0)
275 g = 0;
276 else if (g > 65535)
277 g = 65535;
278 if (b < 0)
279 b = 0;
280 else if (b > 65535)
281 b = 65535;
282
283 arm_col.red = r;
284 arm_col.green = g;
285 arm_col.blue = b;
286 if (!XAllocColor(disp, cmap, &arm_col))
287 return False;
288 w->shadow.arm_pixel = arm_col.pixel;
289
290 return True;
291 }
292
AllocArmPixmap(ShadowWidget w,Pixel pix)293 static void AllocArmPixmap(ShadowWidget w, Pixel pix)
294 {
295 if (w->core.depth == 1)
296 w->shadow.arm_pixmap = CacheCreatePixmap(w, 4, 0, 1);
297 else
298 w->shadow.arm_pixmap =
299 CacheCreatePixmap(w, 4, get_black((Widget)w), pix);
300 }
301
AllocGCs(ShadowWidget w)302 static void AllocGCs(ShadowWidget w)
303 {
304 ShadowWidgetClass class = (ShadowWidgetClass)XtClass(w);
305 XGCValues values;
306
307 if (w->shadow.alloced_shadow_pixels) {
308 values.line_width = 1;
309 values.foreground = w->shadow.light_pixel;
310 w->shadow.light_gc =
311 XtGetGC((Widget)w, GCForeground | GCLineWidth, &values);
312 values.foreground = w->shadow.dark_pixel;
313 w->shadow.dark_gc =
314 XtGetGC((Widget)w, GCForeground | GCLineWidth, &values);
315 } else if (w->shadow.line_mode) {
316 Pixel pix = get_pixel(w);
317
318 /* depth == 1... */
319 values.foreground = (pix == 1) ? 0 : 1;
320 values.line_width = 1;
321 w->shadow.light_gc =
322 XtGetGC((Widget)w, GCForeground | GCLineWidth, &values);
323 values.line_width = w->shadow.shadow_width;
324 w->shadow.dark_gc =
325 XtGetGC((Widget)w, GCForeground | GCLineWidth, &values);
326 } else {
327 Screen *scr = XtScreen(w);
328 Visual *vis = get_visual((Widget)w);
329 Pixel black, white;
330
331 black_and_white(scr, vis, &black, &white);
332 values.line_width = 1;
333 if (w->shadow.light_pixmap == None) {
334 values.foreground =
335 (w->core.background_pixel == black) ? white : black;
336 w->shadow.light_gc =
337 XtGetGC((Widget)w, GCLineWidth | GCForeground, &values);
338 } else {
339 values.fill_style = FillTiled;
340 values.tile = w->shadow.light_pixmap;
341 w->shadow.light_gc =
342 XtGetGC((Widget)w,
343 GCLineWidth | GCFillStyle | GCTile,
344 &values);
345 }
346
347 if (w->shadow.dark_pixmap == None) {
348 values.foreground =
349 (w->core.background_pixel == black) ? white : black;
350 w->shadow.dark_gc =
351 XtGetGC((Widget)w, GCLineWidth | GCForeground, &values);
352 } else {
353 values.fill_style = FillTiled;
354 values.tile = w->shadow.dark_pixmap;
355 w->shadow.dark_gc =
356 XtGetGC((Widget)w,
357 GCLineWidth | GCFillStyle | GCTile,
358 &values);
359 }
360 }
361
362 if (class->shadow_class.use_arm_for_background)
363 return;
364
365 if (w->shadow.alloced_arm_pixel) {
366 values.line_width = 1;
367 values.foreground = w->shadow.arm_pixel;
368 w->shadow.arm_gc =
369 XtGetGC((Widget)w, GCForeground | GCLineWidth, &values);
370 } else if (w->shadow.arm_pixmap != None) {
371 values.line_width = 1;
372 values.tile = w->shadow.arm_pixmap;
373 values.fill_style = FillTiled;
374 w->shadow.arm_gc =
375 XtGetGC((Widget)w, GCFillStyle | GCTile| GCLineWidth, &values);
376 }
377 }
378
379 /*************************************************************************/
380
ClassPartInitialize(WidgetClass gclass)381 static void ClassPartInitialize(WidgetClass gclass)
382 {
383 ShadowClassRec *class, *super;
384
385 class = (ShadowClassRec *)gclass;
386 super = (ShadowClassRec *)class->core_class.superclass;
387
388 if (class->shadow_class.pixel_offset == XtInheritPixelOffset)
389 class->shadow_class.pixel_offset = super->shadow_class.pixel_offset;
390 if (class->shadow_class.alloc_shadow_colors == XtInheritAllocShadowColors)
391 class->shadow_class.alloc_shadow_colors =
392 super->shadow_class.alloc_shadow_colors;
393 if (class->shadow_class.alloc_shadow_pixmaps ==
394 XtInheritAllocShadowPixmaps)
395 class->shadow_class.alloc_shadow_pixmaps =
396 super->shadow_class.alloc_shadow_pixmaps;
397 if (class->shadow_class.alloc_arm_color == XtInheritAllocArmColor)
398 class->shadow_class.alloc_arm_color =
399 super->shadow_class.alloc_arm_color;
400 if (class->shadow_class.alloc_arm_pixmap == XtInheritAllocArmPixmap)
401 class->shadow_class.alloc_arm_pixmap =
402 super->shadow_class.alloc_arm_pixmap;
403 if (class->shadow_class.alloc_gcs == XtInheritAllocGCs)
404 class->shadow_class.alloc_gcs = super->shadow_class.alloc_gcs;
405 }
406
Initialize(Widget grequest,Widget gnew,ArgList args,Cardinal * no_args)407 static void Initialize(Widget grequest, Widget gnew,
408 ArgList args, Cardinal *no_args)
409 {
410 ShadowWidget new = (ShadowWidget)gnew;
411 ShadowWidgetClass class = (ShadowWidgetClass)XtClass(new);
412 Display *disp = XtDisplay(new);
413 Colormap cmap = new->core.colormap;
414 XColor col;
415 Boolean query_done = False;
416
417 new->shadow.light_pixmap = None;
418 new->shadow.dark_pixmap = None;
419 new->shadow.arm_pixmap = None;
420 new->shadow.light_gc = (GC)0;
421 new->shadow.dark_gc = (GC)0;
422 new->shadow.arm_gc = (GC)0;
423 new->shadow.line_mode = False;
424 new->shadow.alloced_shadow_pixels = False;
425 new->shadow.alloced_arm_pixel = False;
426 col.pixel = get_pixel(new);
427
428 if (new->shadow.alloc_shadow_colors && new->core.depth != 1 &&
429 class->shadow_class.alloc_shadow_colors) {
430 XQueryColor(disp, cmap, &col);
431 query_done = True;
432 if (class->shadow_class.alloc_shadow_colors(new, &col))
433 new->shadow.alloced_shadow_pixels = True;
434 }
435
436 if (!new->shadow.alloced_shadow_pixels)
437 if (new->shadow.use_lines && new->core.depth == 1)
438 new->shadow.line_mode = True;
439 else if (class->shadow_class.alloc_shadow_pixmaps)
440 class->shadow_class.alloc_shadow_pixmaps(new, col.pixel);
441
442 if (new->shadow.alloc_arm_color && class->shadow_class.alloc_arm_color &&
443 new->core.depth != 1) {
444 if (!query_done)
445 XQueryColor(disp, cmap, &col);
446 if (class->shadow_class.alloc_arm_color(new, &col))
447 new->shadow.alloced_arm_pixel = True;
448 }
449
450 if (!new->shadow.alloced_arm_pixel && new->shadow.alloc_arm_pixmap &&
451 class->shadow_class.alloc_arm_pixmap)
452 class->shadow_class.alloc_arm_pixmap(new, col.pixel);
453
454 if (class->shadow_class.alloc_gcs)
455 class->shadow_class.alloc_gcs(new);
456 }
457
Realize(Widget gw,XtValueMask * mask,XSetWindowAttributes * attributes)458 static void Realize(Widget gw, XtValueMask *mask,
459 XSetWindowAttributes *attributes)
460 {
461 ShadowWidget w = (ShadowWidget)gw;
462 ShadowWidgetClass class = (ShadowWidgetClass)XtClass(w);
463
464 if (class->shadow_class.use_arm_for_background)
465 if (w->shadow.arm_pixmap != None) {
466 *mask |= CWBackPixmap;
467 *mask &= ~CWBackPixel;
468 attributes->background_pixmap = w->shadow.arm_pixmap;
469 } else if (w->shadow.alloced_arm_pixel) {
470 *mask |= CWBackPixel;
471 attributes->background_pixel = w->shadow.arm_pixel;
472 }
473
474 coreWidgetClass->core_class.realize((Widget)w, mask, attributes);
475 }
476
Destroy(Widget gw)477 static void Destroy(Widget gw)
478 {
479 ShadowWidget w = (ShadowWidget)gw;
480 Display *disp = XtDisplay(w);
481 unsigned long pixels[3];
482 int n = 0;
483
484 if (w->shadow.light_gc != 0)
485 XtReleaseGC((Widget)w, w->shadow.light_gc);
486 if (w->shadow.dark_gc != 0)
487 XtReleaseGC((Widget)w, w->shadow.dark_gc);
488 if (w->shadow.arm_gc != 0)
489 XtReleaseGC((Widget)w, w->shadow.arm_gc);
490 if (w->shadow.light_pixmap != None)
491 CacheFreePixmap(w, w->shadow.light_pixmap);
492 if (w->shadow.dark_pixmap != None)
493 CacheFreePixmap(w, w->shadow.dark_pixmap);
494 if (w->shadow.arm_pixmap != None)
495 CacheFreePixmap(w, w->shadow.arm_pixmap);
496 if (w->shadow.alloced_shadow_pixels) {
497 pixels[n] = w->shadow.light_pixel;
498 n++;
499 pixels[n] = w->shadow.dark_pixel;
500 n++;
501 }
502 if (w->shadow.alloced_arm_pixel) {
503 pixels[n] = w->shadow.arm_pixel;
504 n++;
505 }
506 if (n != 0) {
507 Colormap cmap = w->core.colormap;
508
509 XFreeColors(disp, cmap, pixels, n, 0);
510 }
511 }
512
SetValues(Widget gcurrent,Widget grequest,Widget gnew,ArgList args,Cardinal * num_args)513 static Boolean SetValues(Widget gcurrent,
514 Widget grequest,
515 Widget gnew,
516 ArgList args,
517 Cardinal *num_args)
518 {
519 Boolean redisplay = False;
520 ShadowWidget new = (ShadowWidget)gnew;
521 ShadowWidget current = (ShadowWidget)gcurrent;
522 ShadowWidgetClass class = (ShadowWidgetClass)XtClass(new);
523 Pixel new_pix = get_pixel(new);
524 Pixel current_pix = get_pixel(current);
525
526 if (new_pix != current_pix ||
527 (new->shadow.line_mode &&
528 new->shadow.shadow_width != current->shadow.shadow_width) ||
529 new->shadow.alloc_shadow_colors !=
530 current->shadow.alloc_shadow_colors ||
531 new->shadow.alloc_arm_color != current->shadow.alloc_arm_color ||
532 new->shadow.use_lines != current->shadow.use_lines ||
533 new->shadow.alloc_arm_pixmap != current->shadow.alloc_arm_pixmap) {
534 Pixel pixels[3];
535 int n = 0;
536
537 /* initialize first, then free, except for pixels... */
538 if (current->shadow.alloced_shadow_pixels) {
539 pixels[n++] = current->shadow.light_pixel;
540 pixels[n++] = current->shadow.dark_pixel;
541 }
542 if (current->shadow.alloced_arm_pixel)
543 pixels[n++] = current->shadow.arm_pixel;
544
545 if (n > 0)
546 XFreeColors(XtDisplay(current),
547 current->core.colormap, pixels, n, 0);
548
549 Initialize(NULL, (Widget)new, NULL, NULL);
550
551 if (current->shadow.light_gc != 0)
552 XtReleaseGC((Widget)new, current->shadow.light_gc);
553 if (current->shadow.dark_gc != 0)
554 XtReleaseGC((Widget)new, current->shadow.dark_gc);
555 if (current->shadow.arm_gc != 0)
556 XtReleaseGC((Widget)new, current->shadow.arm_gc);
557 if (current->shadow.light_pixmap != None)
558 CacheFreePixmap(new, current->shadow.light_pixmap);
559 if (current->shadow.dark_pixmap != None)
560 CacheFreePixmap(new, current->shadow.dark_pixmap);
561 if (current->shadow.arm_pixmap != None)
562 CacheFreePixmap(new, current->shadow.arm_pixmap);
563
564 redisplay = True;
565 }
566
567 if (class->shadow_class.use_arm_for_background &&
568 (redisplay ||
569 new->core.background_pixel != current->core.background_pixel)) {
570 Display *disp = XtDisplay(new);
571 Window win = XtWindow(new);
572
573 if (new->shadow.alloced_arm_pixel)
574 XSetWindowBackground(disp, win, new->shadow.arm_pixel);
575 else if (new->shadow.arm_pixmap != None)
576 XSetWindowBackgroundPixmap(disp, win, new->shadow.arm_pixmap);
577 else
578 XSetWindowBackground(disp, win, new->core.background_pixel);
579 }
580
581 return redisplay;
582 }
583
584 /*************************************************************************/
585
ShadowDrawShadows(ShadowWidget w,Position x,Position y,Dimension width,Dimension height,Boolean swap)586 void ShadowDrawShadows(ShadowWidget w, Position x, Position y,
587 Dimension width, Dimension height, Boolean swap)
588 {
589 Display *disp = XtDisplay(w);
590 Window win = XtWindow(w);
591 short sw = w->shadow.shadow_width;
592
593 if (sw == 0 || !XtIsRealized((Widget)w)) return;
594
595 if (w->shadow.line_mode) {
596 if (swap)
597 XDrawRectangle(disp, win, w->shadow.dark_gc, x + sw/2, y + sw/2,
598 width - sw, height - sw);
599 else
600 XDrawRectangle(disp, win, w->shadow.light_gc, x, y,
601 width - 1, height - 1);
602 } else {
603 GC light_gc, dark_gc;
604 XPoint points[6];
605
606 if (swap) {
607 light_gc = w->shadow.dark_gc;
608 dark_gc = w->shadow.light_gc;
609 } else {
610 light_gc = w->shadow.light_gc;
611 dark_gc = w->shadow.dark_gc;
612 }
613
614 points[0].x = x;
615 points[0].y = y;
616 points[1].x = x + width;
617 points[1].y = y;
618 points[2].x = x + width - sw;
619 points[2].y = y + sw;
620 points[3].x = x + sw;
621 points[3].y = y + sw;
622 points[4].x = x + sw;
623 points[4].y = y + height - sw;
624 points[5].x = x;
625 points[5].y = y + height;
626 XFillPolygon(disp, win, light_gc, points, 6,
627 (sw > 1) ? Nonconvex : Complex, CoordModeOrigin);
628
629 points[0].x = x + width;
630 points[0].y = y + height;
631 points[3].x = x + width - sw;
632 points[3].y = y + height - sw;
633 XFillPolygon(disp, win, dark_gc, points, 6,
634 (sw > 1) ? Nonconvex : Complex, CoordModeOrigin);
635 }
636 }
637
638 /* the widget must be able to handle NULL events and regions */
639
ShadowRedrawWidget(Widget w)640 void ShadowRedrawWidget(Widget w)
641 {
642 if (XtIsRealized(w)) {
643 XtExposeProc expose_proc = XtClass(w)->core_class.expose;
644
645 if (expose_proc)
646 expose_proc(w, NULL, NULL);
647 }
648 }
649