1 /***********************************************************
2 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
3 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
4 Copyright 1992, 1993 by Kaleb Keithley
5
6 All Rights Reserved
7
8 Permission to use, copy, modify, and distribute this software and its
9 documentation for any purpose and without fee is hereby granted,
10 provided that the above copyright notice appear in all copies and that
11 both that copyright notice and this permission notice appear in
12 supporting documentation, and that the names of Digital, MIT, or Kaleb
13 Keithley not be used in advertising or publicity pertaining to distribution
14 of the software without specific, written prior permission.
15
16 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
17 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
18 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
19 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
22 SOFTWARE.
23
24 ******************************************************************/
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 #include <X11/Xaw3dxft/Xaw3dP.h>
30 #include <X11/Xlib.h>
31 #include <X11/StringDefs.h>
32 #include <X11/IntrinsicP.h>
33 #include <X11/Xaw3dxft/XawInit.h>
34 #include <X11/Xaw3dxft/ThreeDP.h>
35 #include <X11/Xaw3dxft/SimpleMenP.h>
36 #include <X11/Xaw3dxft/SmeThreeDP.h>
37 #include <X11/Xosdefs.h>
38
39 /* Initialization of defaults */
40
41 #define XtNtopShadowPixmap "topShadowPixmap"
42 #define XtCTopShadowPixmap "TopShadowPixmap"
43 #define XtNbottomShadowPixmap "bottomShadowPixmap"
44 #define XtCBottomShadowPixmap "BottomShadowPixmap"
45 #define XtNshadowed "shadowed"
46 #define XtCShadowed "Shadowed"
47
48 #define offset(field) XtOffsetOf(SmeThreeDRec, field)
49
50 static XtResource resources[] = {
51 {XtNshadowWidth, XtCShadowWidth, XtRDimension, sizeof(Dimension),
52 offset(sme_threeD.shadow_width), XtRImmediate, (XtPointer) 2},
53 {XtNtopShadowPixel, XtCTopShadowPixel, XtRPixel, sizeof(Pixel),
54 offset(sme_threeD.top_shadow_pixel), XtRString, XtDefaultForeground},
55 {XtNbottomShadowPixel, XtCBottomShadowPixel, XtRPixel, sizeof(Pixel),
56 offset(sme_threeD.bot_shadow_pixel), XtRString, XtDefaultForeground},
57 {XtNtopShadowPixmap, XtCTopShadowPixmap, XtRPixmap, sizeof(Pixmap),
58 offset(sme_threeD.top_shadow_pxmap), XtRImmediate, (XtPointer) NULL},
59 {XtNbottomShadowPixmap, XtCBottomShadowPixmap, XtRPixmap, sizeof(Pixmap),
60 offset(sme_threeD.bot_shadow_pxmap), XtRImmediate, (XtPointer) NULL},
61 {XtNtopShadowContrast, XtCTopShadowContrast, XtRInt, sizeof(int),
62 offset(sme_threeD.top_shadow_contrast), XtRImmediate, (XtPointer) 20},
63 {XtNbottomShadowContrast, XtCBottomShadowContrast, XtRInt, sizeof(int),
64 offset(sme_threeD.bot_shadow_contrast), XtRImmediate, (XtPointer) 40},
65 {XtNuserData, XtCUserData, XtRPointer, sizeof(XtPointer),
66 offset(sme_threeD.user_data), XtRPointer, (XtPointer) NULL},
67 {XtNbeNiceToColormap, XtCBeNiceToColormap, XtRBoolean, sizeof(Boolean),
68 offset(sme_threeD.be_nice_to_cmap), XtRImmediate, (XtPointer) True},
69 {XtNshadowed, XtCShadowed, XtRBoolean, sizeof(Boolean),
70 offset(sme_threeD.shadowed), XtRImmediate, (XtPointer) False},
71 {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
72 XtOffsetOf(RectObjRec,rectangle.border_width), XtRImmediate,
73 (XtPointer)0}
74 };
75
76 #undef offset
77
78 static void Initialize(Widget, Widget, ArgList, Cardinal *);
79 static void Destroy(Widget);
80 static void ClassPartInitialize(WidgetClass);
81 static void _XawSme3dDrawShadows(Widget);
82 static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
83
84 SmeThreeDClassRec smeThreeDClassRec = {
85 { /* core fields */
86 /* superclass */ (WidgetClass) &smeClassRec,
87 /* class_name */ "SmeThreeD",
88 /* widget_size */ sizeof(SmeThreeDRec),
89 /* class_initialize */ NULL,
90 /* class_part_initialize */ ClassPartInitialize,
91 /* class_inited */ FALSE,
92 /* initialize */ Initialize,
93 /* initialize_hook */ NULL,
94 /* realize */ NULL,
95 /* actions */ NULL,
96 /* num_actions */ 0,
97 /* resources */ resources,
98 /* resource_count */ XtNumber(resources),
99 /* xrm_class */ NULLQUARK,
100 /* compress_motion */ TRUE,
101 /* compress_exposure */ TRUE,
102 /* compress_enterleave */ TRUE,
103 /* visible_interest */ FALSE,
104 /* destroy */ Destroy,
105 /* resize */ XtInheritResize,
106 /* expose */ NULL,
107 /* set_values */ SetValues,
108 /* set_values_hook */ NULL,
109 /* set_values_almost */ XtInheritSetValuesAlmost,
110 /* get_values_hook */ NULL,
111 /* accept_focus */ NULL,
112 /* version */ XtVersion,
113 /* callback_private */ NULL,
114 /* tm_table */ NULL,
115 /* query_geometry */ XtInheritQueryGeometry,
116 /* display_accelerator */ NULL,
117 /* extension */ NULL
118 },
119 { /* Menu Entry fields */
120 /* highlight */ XtInheritHighlight,
121 /* unhighlight */ XtInheritUnhighlight,
122 /* notify */ XtInheritNotify,
123 /* extension */ NULL
124 },
125 { /* threeD fields */
126 /* shadow draw */ _XawSme3dDrawShadows
127 }
128 };
129
130 WidgetClass smeThreeDObjectClass = (WidgetClass) &smeThreeDClassRec;
131
132 /****************************************************************
133 *
134 * Private Procedures
135 *
136 ****************************************************************/
137
138
139 #define shadowpm_width 8
140 #define shadowpm_height 8
141 static char shadowpm_bits[] = {
142 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
143
144 static char mtshadowpm_bits[] = {
145 0x92, 0x24, 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
146
147 static char mbshadowpm_bits[] = {
148 0x6d, 0xdb, 0xb6, 0x6d, 0xdb, 0xb6, 0x6d, 0xdb};
149
150 /* ARGSUSED */
151 static void
AllocTopShadowGC(Widget w)152 AllocTopShadowGC (Widget w)
153 {
154 SmeThreeDObject tdo = (SmeThreeDObject) w;
155 Screen *scn = XtScreenOfObject (w);
156 XtGCMask valuemask;
157 XGCValues myXGCV;
158
159 if (tdo->sme_threeD.be_nice_to_cmap || DefaultDepthOfScreen (scn) == 1) {
160 valuemask = GCTile | GCFillStyle;
161 myXGCV.tile = tdo->sme_threeD.top_shadow_pxmap;
162 myXGCV.fill_style = FillTiled;
163 } else {
164 valuemask = GCForeground;
165 myXGCV.foreground = tdo->sme_threeD.top_shadow_pixel;
166 }
167 tdo->sme_threeD.top_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
168 }
169
170 /* ARGSUSED */
171 static void
AllocBotShadowGC(Widget w)172 AllocBotShadowGC (Widget w)
173 {
174 SmeThreeDObject tdo = (SmeThreeDObject) w;
175 Screen *scn = XtScreenOfObject (w);
176 XtGCMask valuemask;
177 XGCValues myXGCV;
178
179 if (tdo->sme_threeD.be_nice_to_cmap || DefaultDepthOfScreen (scn) == 1) {
180 valuemask = GCTile | GCFillStyle;
181 myXGCV.tile = tdo->sme_threeD.bot_shadow_pxmap;
182 myXGCV.fill_style = FillTiled;
183 } else {
184 valuemask = GCForeground;
185 myXGCV.foreground = tdo->sme_threeD.bot_shadow_pixel;
186 }
187 tdo->sme_threeD.bot_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
188 }
189
190 /* ARGSUSED */
191 static void
AllocEraseGC(Widget w)192 AllocEraseGC (Widget w)
193 {
194 Widget parent = XtParent (w);
195 SmeThreeDObject tdo = (SmeThreeDObject) w;
196 XtGCMask valuemask;
197 XGCValues myXGCV;
198
199 valuemask = GCForeground;
200 myXGCV.foreground = parent->core.background_pixel;
201 tdo->sme_threeD.erase_GC = XtGetGC(w, valuemask, &myXGCV);
202 }
203
204 /* ARGSUSED */
205 static void
AllocTopShadowPixmap(Widget new)206 AllocTopShadowPixmap (Widget new)
207 {
208 SmeThreeDObject tdo = (SmeThreeDObject) new;
209 Widget parent = XtParent (new);
210 Display *dpy = XtDisplayOfObject (new);
211 Screen *scn = XtScreenOfObject (new);
212 unsigned long top_fg_pixel = 0, top_bg_pixel = 0;
213 char *pm_data;
214 Boolean create_pixmap = FALSE;
215
216 /*
217 * I know, we're going to create two pixmaps for each and every
218 * shadow'd widget. Yeuck. I'm semi-relying on server side
219 * pixmap cacheing.
220 */
221
222 if (DefaultDepthOfScreen (scn) == 1) {
223 top_fg_pixel = BlackPixelOfScreen (scn);
224 top_bg_pixel = WhitePixelOfScreen (scn);
225 pm_data = mtshadowpm_bits;
226 create_pixmap = TRUE;
227 } else if (tdo->sme_threeD.be_nice_to_cmap) {
228 if (parent->core.background_pixel == WhitePixelOfScreen (scn)) {
229 top_fg_pixel = WhitePixelOfScreen (scn);
230 top_bg_pixel = grayPixel( BlackPixelOfScreen (scn), dpy, scn);
231 } else if (parent->core.background_pixel == BlackPixelOfScreen (scn)) {
232 top_fg_pixel = grayPixel( BlackPixelOfScreen (scn), dpy, scn);
233 top_bg_pixel = WhitePixelOfScreen (scn);
234 } else {
235 top_fg_pixel = parent->core.background_pixel;
236 top_bg_pixel = WhitePixelOfScreen (scn);
237 }
238 #ifndef XAW_GRAY_BLKWHT_STIPPLES
239 if (parent->core.background_pixel == WhitePixelOfScreen (scn) ||
240 parent->core.background_pixel == BlackPixelOfScreen (scn)) {
241 pm_data = mtshadowpm_bits;
242 } else
243 #endif
244 pm_data = shadowpm_bits;
245
246 create_pixmap = TRUE;
247 }
248
249 if (create_pixmap)
250 tdo->sme_threeD.top_shadow_pxmap = XCreatePixmapFromBitmapData (dpy,
251 RootWindowOfScreen (scn),
252 pm_data,
253 shadowpm_width,
254 shadowpm_height,
255 top_fg_pixel,
256 top_bg_pixel,
257 DefaultDepthOfScreen (scn));
258 }
259
260 /* ARGSUSED */
261 static void
AllocBotShadowPixmap(Widget new)262 AllocBotShadowPixmap (Widget new)
263 {
264 SmeThreeDObject tdo = (SmeThreeDObject) new;
265 Widget parent = XtParent (new);
266 Display *dpy = XtDisplayOfObject (new);
267 Screen *scn = XtScreenOfObject (new);
268 unsigned long bot_fg_pixel = 0, bot_bg_pixel = 0;
269 char *pm_data;
270 Boolean create_pixmap = FALSE;
271
272 if (DefaultDepthOfScreen (scn) == 1) {
273 bot_fg_pixel = BlackPixelOfScreen (scn);
274 bot_bg_pixel = WhitePixelOfScreen (scn);
275 pm_data = mbshadowpm_bits;
276 create_pixmap = TRUE;
277 } else if (tdo->sme_threeD.be_nice_to_cmap) {
278 if (parent->core.background_pixel == WhitePixelOfScreen (scn)) {
279 bot_fg_pixel = grayPixel( WhitePixelOfScreen (scn), dpy, scn);
280 bot_bg_pixel = BlackPixelOfScreen (scn);
281 } else if (parent->core.background_pixel == BlackPixelOfScreen (scn)) {
282 bot_fg_pixel = BlackPixelOfScreen (scn);
283 bot_bg_pixel = grayPixel( BlackPixelOfScreen (scn), dpy, scn);
284 } else {
285 bot_fg_pixel = parent->core.background_pixel;
286 bot_bg_pixel = BlackPixelOfScreen (scn);
287 }
288 #ifndef XAW_GRAY_BLKWHT_STIPPLES
289 if (parent->core.background_pixel == WhitePixelOfScreen (scn) ||
290 parent->core.background_pixel == BlackPixelOfScreen (scn)) {
291 pm_data = mbshadowpm_bits;
292 } else
293 #endif
294 pm_data = shadowpm_bits;
295
296 create_pixmap = TRUE;
297 }
298
299 if (create_pixmap)
300 tdo->sme_threeD.bot_shadow_pxmap = XCreatePixmapFromBitmapData (dpy,
301 RootWindowOfScreen (scn),
302 pm_data,
303 shadowpm_width,
304 shadowpm_height,
305 bot_fg_pixel,
306 bot_bg_pixel,
307 DefaultDepthOfScreen (scn));
308 }
309
310 /* ARGSUSED */
311 void
XawSme3dComputeTopShadowRGB(Widget new,XColor * xcol_out)312 XawSme3dComputeTopShadowRGB (Widget new, XColor *xcol_out)
313 {
314 if (XtIsSubclass (new, smeThreeDObjectClass)) {
315 SmeThreeDObject tdo = (SmeThreeDObject) new;
316 Widget w = XtParent (new);
317 XColor get_c;
318 double contrast;
319 Display *dpy = XtDisplayOfObject (new);
320 Screen *scn = XtScreenOfObject (new);
321 Colormap cmap = w->core.colormap;
322
323 get_c.pixel = w->core.background_pixel;
324 if (get_c.pixel == WhitePixelOfScreen (scn) ||
325 get_c.pixel == BlackPixelOfScreen (scn)) {
326 contrast = (100 - tdo->sme_threeD.top_shadow_contrast) / 100.0;
327 xcol_out->red = contrast * 65535.0;
328 xcol_out->green = contrast * 65535.0;
329 xcol_out->blue = contrast * 65535.0;
330 } else {
331 contrast = 1.0 + tdo->sme_threeD.top_shadow_contrast / 100.0;
332 XQueryColor (dpy, cmap, &get_c);
333 #define MIN(x,y) (unsigned short) (x < y) ? x : y
334 xcol_out->red = MIN (65535, (int) (contrast * (double) get_c.red));
335 xcol_out->green = MIN (65535, (int) (contrast * (double) get_c.green));
336 xcol_out->blue = MIN (65535, (int) (contrast * (double) get_c.blue));
337 #undef MIN
338 }
339 } else
340 xcol_out->red = xcol_out->green = xcol_out->blue = 0;
341 }
342
343 /* ARGSUSED */
344 static void
AllocTopShadowPixel(Widget new)345 AllocTopShadowPixel (Widget new)
346 {
347 XColor set_c;
348 SmeThreeDObject tdo = (SmeThreeDObject) new;
349 Widget w = XtParent (new);
350 Display *dpy = XtDisplayOfObject (new);
351 Colormap cmap = w->core.colormap;
352
353 XawSme3dComputeTopShadowRGB (new, &set_c);
354 (void) XAllocColor (dpy, cmap, &set_c);
355 tdo->sme_threeD.top_shadow_pixel = set_c.pixel;
356 }
357
358
359 /* ARGSUSED */
360 void
XawSme3dComputeBottomShadowRGB(Widget new,XColor * xcol_out)361 XawSme3dComputeBottomShadowRGB (Widget new, XColor *xcol_out)
362 {
363 if (XtIsSubclass (new, smeThreeDObjectClass)) {
364 SmeThreeDObject tdo = (SmeThreeDObject) new;
365 Widget w = XtParent (new);
366 XColor get_c;
367 double contrast;
368 Display *dpy = XtDisplayOfObject (new);
369 Screen *scn = XtScreenOfObject (new);
370 Colormap cmap = w->core.colormap;
371
372 get_c.pixel = w->core.background_pixel;
373 if (get_c.pixel == WhitePixelOfScreen (scn) ||
374 get_c.pixel == BlackPixelOfScreen (scn)) {
375 contrast = tdo->sme_threeD.bot_shadow_contrast / 100.0;
376 xcol_out->red = contrast * 65535.0;
377 xcol_out->green = contrast * 65535.0;
378 xcol_out->blue = contrast * 65535.0;
379 } else {
380 XQueryColor (dpy, cmap, &get_c);
381 contrast = (100 - tdo->sme_threeD.bot_shadow_contrast) / 100.0;
382 xcol_out->red = contrast * get_c.red;
383 xcol_out->green = contrast * get_c.green;
384 xcol_out->blue = contrast * get_c.blue;
385 }
386 } else
387 xcol_out->red = xcol_out->green = xcol_out->blue = 0;
388 }
389
390 /* ARGSUSED */
391 static void
AllocBotShadowPixel(Widget new)392 AllocBotShadowPixel (Widget new)
393 {
394 XColor set_c;
395 SmeThreeDObject tdo = (SmeThreeDObject) new;
396 Widget w = XtParent (new);
397 Display *dpy = XtDisplayOfObject (new);
398 Colormap cmap = w->core.colormap;
399
400 XawSme3dComputeBottomShadowRGB (new, &set_c);
401 (void) XAllocColor (dpy, cmap, &set_c);
402 tdo->sme_threeD.bot_shadow_pixel = set_c.pixel;
403 }
404
405
406 /* ARGSUSED */
407 static void
ClassPartInitialize(WidgetClass wc)408 ClassPartInitialize (WidgetClass wc)
409 {
410 SmeThreeDClassRec *tdwc = (SmeThreeDClassRec *) wc;
411 SmeThreeDClassRec *super =
412 (SmeThreeDClassRec *) tdwc->rect_class.superclass;
413
414 if (tdwc->sme_threeD_class.shadowdraw == XtInheritXawSme3dShadowDraw)
415 tdwc->sme_threeD_class.shadowdraw = super->sme_threeD_class.shadowdraw;
416 }
417
418 /* ARGSUSED */
419 static void
Initialize(Widget request,Widget new,ArgList args,Cardinal * num_args)420 Initialize (Widget request, Widget new, ArgList args, Cardinal *num_args)
421 {
422 SmeThreeDObject w = (SmeThreeDObject) new;
423 Screen *scr = XtScreenOfObject (new);
424
425 if (w->sme_threeD.be_nice_to_cmap || DefaultDepthOfScreen (scr) == 1) {
426 AllocTopShadowPixmap (new);
427 AllocBotShadowPixmap (new);
428 } else {
429 if (w->sme_threeD.top_shadow_pixel == w->sme_threeD.bot_shadow_pixel) {
430 AllocTopShadowPixel (new);
431 AllocBotShadowPixel (new);
432 }
433 w->sme_threeD.top_shadow_pxmap = w->sme_threeD.bot_shadow_pxmap = 0;
434 }
435 AllocTopShadowGC (new);
436 AllocBotShadowGC (new);
437 AllocEraseGC (new);
438 }
439
440 static void
Destroy(Widget gw)441 Destroy (Widget gw)
442 {
443 SmeThreeDObject w = (SmeThreeDObject) gw;
444 XtReleaseGC (gw, w->sme_threeD.top_shadow_GC);
445 XtReleaseGC (gw, w->sme_threeD.bot_shadow_GC);
446 XtReleaseGC (gw, w->sme_threeD.erase_GC);
447 if (w->sme_threeD.top_shadow_pxmap)
448 XFreePixmap (XtDisplayOfObject (gw), w->sme_threeD.top_shadow_pxmap);
449 if (w->sme_threeD.bot_shadow_pxmap)
450 XFreePixmap (XtDisplayOfObject (gw), w->sme_threeD.bot_shadow_pxmap);
451 }
452
453 /* ARGSUSED */
454 static Boolean
SetValues(Widget gcurrent,Widget grequest,Widget gnew,ArgList args,Cardinal * num_args)455 SetValues (Widget gcurrent, Widget grequest, Widget gnew, ArgList args, Cardinal *num_args)
456 {
457 SmeThreeDObject current = (SmeThreeDObject) gcurrent;
458 SmeThreeDObject new = (SmeThreeDObject) gnew;
459 Boolean redisplay = FALSE;
460 Boolean alloc_top_pixel = FALSE;
461 Boolean alloc_bot_pixel = FALSE;
462 Boolean alloc_top_pixmap = FALSE;
463 Boolean alloc_bot_pixmap = FALSE;
464
465 #if 0
466 (*threeDWidgetClass->core_class.superclass->core_class.set_values)
467 (gcurrent, grequest, gnew, NULL, 0);
468 #endif
469 if (new->sme_threeD.shadow_width != current->sme_threeD.shadow_width)
470 redisplay = TRUE;
471 if (new->sme_threeD.be_nice_to_cmap != current->sme_threeD.be_nice_to_cmap) {
472 if (new->sme_threeD.be_nice_to_cmap) {
473 alloc_top_pixmap = TRUE;
474 alloc_bot_pixmap = TRUE;
475 } else {
476 alloc_top_pixel = TRUE;
477 alloc_bot_pixel = TRUE;
478 }
479 redisplay = TRUE;
480 }
481 if (!new->sme_threeD.be_nice_to_cmap &&
482 new->sme_threeD.top_shadow_contrast != current->sme_threeD.top_shadow_contrast)
483 alloc_top_pixel = TRUE;
484 if (!new->sme_threeD.be_nice_to_cmap &&
485 new->sme_threeD.bot_shadow_contrast != current->sme_threeD.bot_shadow_contrast)
486 alloc_bot_pixel = TRUE;
487 if (alloc_top_pixel)
488 AllocTopShadowPixel (gnew);
489 if (alloc_bot_pixel)
490 AllocBotShadowPixel (gnew);
491 if (alloc_top_pixmap)
492 AllocTopShadowPixmap (gnew);
493 if (alloc_bot_pixmap)
494 AllocBotShadowPixmap (gnew);
495 if (!new->sme_threeD.be_nice_to_cmap &&
496 new->sme_threeD.top_shadow_pixel != current->sme_threeD.top_shadow_pixel)
497 alloc_top_pixel = TRUE;
498 if (!new->sme_threeD.be_nice_to_cmap &&
499 new->sme_threeD.bot_shadow_pixel != current->sme_threeD.bot_shadow_pixel)
500 alloc_bot_pixel = TRUE;
501 if (new->sme_threeD.be_nice_to_cmap) {
502 if (alloc_top_pixmap) {
503 XtReleaseGC (gcurrent, current->sme_threeD.top_shadow_GC);
504 AllocTopShadowGC (gnew);
505 redisplay = True;
506 }
507 if (alloc_bot_pixmap) {
508 XtReleaseGC (gcurrent, current->sme_threeD.bot_shadow_GC);
509 AllocBotShadowGC (gnew);
510 redisplay = True;
511 }
512 } else {
513 if (alloc_top_pixel) {
514 if (new->sme_threeD.top_shadow_pxmap) {
515 XFreePixmap (XtDisplayOfObject (gnew), new->sme_threeD.top_shadow_pxmap);
516 new->sme_threeD.top_shadow_pxmap = (Pixmap) NULL;
517 }
518 XtReleaseGC (gcurrent, current->sme_threeD.top_shadow_GC);
519 AllocTopShadowGC (gnew);
520 redisplay = True;
521 }
522 if (alloc_bot_pixel) {
523 if (new->sme_threeD.bot_shadow_pxmap) {
524 XFreePixmap (XtDisplayOfObject (gnew), new->sme_threeD.bot_shadow_pxmap);
525 new->sme_threeD.bot_shadow_pxmap = (Pixmap) NULL;
526 }
527 XtReleaseGC (gcurrent, current->sme_threeD.bot_shadow_GC);
528 AllocBotShadowGC (gnew);
529 redisplay = True;
530 }
531 }
532 return (redisplay);
533 }
534
535 /* ARGSUSED */
536 static void
_XawSme3dDrawShadows(Widget gw)537 _XawSme3dDrawShadows(Widget gw)
538 {
539 SmeThreeDObject tdo = (SmeThreeDObject) gw;
540 SimpleMenuWidget smw = (SimpleMenuWidget) XtParent(gw);
541 ThreeDWidget tdw = (ThreeDWidget) smw->simple_menu.threeD;
542 Dimension s = tdo->sme_threeD.shadow_width;
543 Dimension ps = tdw->threeD.shadow_width;
544 XPoint pt[6];
545
546 /*
547 * draw the shadows using the core part width and height,
548 * and the threeD part shadow_width.
549 *
550 * no point to do anything if the shadow_width is 0 or the
551 * widget has not been realized.
552 */
553 if (s > 0 && XtIsRealized(gw))
554 {
555 Dimension h = tdo->rectangle.height;
556 Dimension w = tdo->rectangle.width - ps;
557 Dimension x = tdo->rectangle.x + ps;
558 Dimension y = tdo->rectangle.y;
559 Display *dpy = XtDisplayOfObject(gw);
560 Window win = XtWindowOfObject(gw);
561 GC top, bot;
562
563 if (tdo->sme_threeD.shadowed)
564 {
565 top = tdo->sme_threeD.top_shadow_GC;
566 bot = tdo->sme_threeD.bot_shadow_GC;
567 }
568 else
569 top = bot = tdo->sme_threeD.erase_GC;
570
571 /* top-left shadow */
572 pt[0].x = x; pt[0].y = y + h;
573 pt[1].x = x; pt[1].y = y;
574 pt[2].x = w; pt[2].y = y;
575 pt[3].x = w - s; pt[3].y = y + s;
576 pt[4].x = ps + s; pt[4].y = y + s;
577 pt[5].x = ps + s; pt[5].y = y + h - s;
578 XFillPolygon(dpy, win, top, pt, 6, Complex, CoordModeOrigin);
579
580 /* bottom-right shadow */
581 /* pt[0].x = x; pt[0].y = y + h; */
582 pt[1].x = w; pt[1].y = y + h;
583 /* pt[2].x = w; pt[2].y = y; */
584 /* pt[3].x = w - s; pt[3].y = y + s; */
585 pt[4].x = w - s; pt[4].y = y + h - s;
586 /* pt[5].x = ps + s; pt[5].y = y + h - s; */
587 XFillPolygon(dpy, win, bot, pt, 6, Complex, CoordModeOrigin);
588 }
589 }
590
591