00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <X11/Xlib.h>
00031 #include <X11/StringDefs.h>
00032 #include <X11/IntrinsicP.h>
00033 #include <X11/Xaw3d/XawInit.h>
00034 #include <X11/Xaw3d/SmeThreeDP.h>
00035 #include <X11/Xosdefs.h>
00036
00037
00038
00039 #define XtNtopShadowPixmap "topShadowPixmap"
00040 #define XtCTopShadowPixmap "TopShadowPixmap"
00041 #define XtNbottomShadowPixmap "bottomShadowPixmap"
00042 #define XtCBottomShadowPixmap "BottomShadowPixmap"
00043 #define XtNshadowed "shadowed"
00044 #define XtCShadowed "Shadowed"
00045
00046 #define offset(field) XtOffsetOf(SmeThreeDRec, field)
00047
00048 static XtResource resources[] = {
00049 {XtNshadowWidth, XtCShadowWidth, XtRDimension, sizeof(Dimension),
00050 offset(sme_threeD.shadow_width), XtRImmediate, (XtPointer) 2},
00051 {XtNtopShadowPixel, XtCTopShadowPixel, XtRPixel, sizeof(Pixel),
00052 offset(sme_threeD.top_shadow_pixel), XtRString, XtDefaultForeground},
00053 {XtNbottomShadowPixel, XtCBottomShadowPixel, XtRPixel, sizeof(Pixel),
00054 offset(sme_threeD.bot_shadow_pixel), XtRString, XtDefaultForeground},
00055 {XtNtopShadowPixmap, XtCTopShadowPixmap, XtRPixmap, sizeof(Pixmap),
00056 offset(sme_threeD.top_shadow_pxmap), XtRImmediate, (XtPointer) NULL},
00057 {XtNbottomShadowPixmap, XtCBottomShadowPixmap, XtRPixmap, sizeof(Pixmap),
00058 offset(sme_threeD.bot_shadow_pxmap), XtRImmediate, (XtPointer) NULL},
00059 {XtNtopShadowContrast, XtCTopShadowContrast, XtRInt, sizeof(int),
00060 offset(sme_threeD.top_shadow_contrast), XtRImmediate, (XtPointer) 20},
00061 {XtNbottomShadowContrast, XtCBottomShadowContrast, XtRInt, sizeof(int),
00062 offset(sme_threeD.bot_shadow_contrast), XtRImmediate, (XtPointer) 40},
00063 {XtNuserData, XtCUserData, XtRPointer, sizeof(XtPointer),
00064 offset(sme_threeD.user_data), XtRPointer, (XtPointer) NULL},
00065 {XtNbeNiceToColormap, XtCBeNiceToColormap, XtRBoolean, sizeof(Boolean),
00066 offset(sme_threeD.be_nice_to_cmap), XtRImmediate, (XtPointer) True},
00067 {XtNshadowed, XtCShadowed, XtRBoolean, sizeof(Boolean),
00068 offset(sme_threeD.shadowed), XtRImmediate, (XtPointer) False},
00069 {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
00070 XtOffsetOf(RectObjRec,rectangle.border_width), XtRImmediate,
00071 (XtPointer)0}
00072 };
00073
00074 #undef offset
00075
00076 static void Initialize(), Destroy();
00077 static void ClassPartInitialize(), _XawSme3dDrawShadows();
00078 static Boolean SetValues();
00079
00080 SmeThreeDClassRec smeThreeDClassRec = {
00081 {
00082 (WidgetClass) &smeClassRec,
00083 "SmeThreeD",
00084 sizeof(SmeThreeDRec),
00085 NULL,
00086 ClassPartInitialize,
00087 FALSE,
00088 Initialize,
00089 NULL,
00090 NULL,
00091 NULL,
00092 0,
00093 resources,
00094 XtNumber(resources),
00095 NULLQUARK,
00096 TRUE,
00097 TRUE,
00098 TRUE,
00099 FALSE,
00100 Destroy,
00101 XtInheritResize,
00102 NULL,
00103 SetValues,
00104 NULL,
00105 XtInheritSetValuesAlmost,
00106 NULL,
00107 NULL,
00108 XtVersion,
00109 NULL,
00110 NULL,
00111 XtInheritQueryGeometry,
00112 NULL,
00113 NULL
00114 },
00115 {
00116 XtInheritHighlight,
00117 XtInheritUnhighlight,
00118 XtInheritNotify,
00119 NULL
00120 },
00121 {
00122 _XawSme3dDrawShadows
00123 }
00124 };
00125
00126 WidgetClass smeThreeDObjectClass = (WidgetClass) &smeThreeDClassRec;
00127
00128
00129
00130
00131
00132
00133
00134
00135 #define shadowpm_width 8
00136 #define shadowpm_height 8
00137 static char shadowpm_bits[] = {
00138 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
00139
00140 static char mtshadowpm_bits[] = {
00141 0x92, 0x24, 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
00142
00143 static char mbshadowpm_bits[] = {
00144 0x6d, 0xdb, 0xb6, 0x6d, 0xdb, 0xb6, 0x6d, 0xdb};
00145
00146
00147 static void AllocTopShadowGC (w)
00148 Widget w;
00149 {
00150 SmeThreeDObject tdo = (SmeThreeDObject) w;
00151 Screen *scn = XtScreenOfObject (w);
00152 XtGCMask valuemask;
00153 XGCValues myXGCV;
00154
00155 if (tdo->sme_threeD.be_nice_to_cmap || DefaultDepthOfScreen (scn) == 1) {
00156 valuemask = GCTile | GCFillStyle;
00157 myXGCV.tile = tdo->sme_threeD.top_shadow_pxmap;
00158 myXGCV.fill_style = FillTiled;
00159 } else {
00160 valuemask = GCForeground;
00161 myXGCV.foreground = tdo->sme_threeD.top_shadow_pixel;
00162 }
00163 tdo->sme_threeD.top_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
00164 }
00165
00166
00167 static void AllocBotShadowGC (w)
00168 Widget w;
00169 {
00170 SmeThreeDObject tdo = (SmeThreeDObject) w;
00171 Screen *scn = XtScreenOfObject (w);
00172 XtGCMask valuemask;
00173 XGCValues myXGCV;
00174
00175 if (tdo->sme_threeD.be_nice_to_cmap || DefaultDepthOfScreen (scn) == 1) {
00176 valuemask = GCTile | GCFillStyle;
00177 myXGCV.tile = tdo->sme_threeD.bot_shadow_pxmap;
00178 myXGCV.fill_style = FillTiled;
00179 } else {
00180 valuemask = GCForeground;
00181 myXGCV.foreground = tdo->sme_threeD.bot_shadow_pixel;
00182 }
00183 tdo->sme_threeD.bot_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
00184 }
00185
00186
00187 static void AllocEraseGC (w)
00188 Widget w;
00189 {
00190 Widget parent = XtParent (w);
00191 SmeThreeDObject tdo = (SmeThreeDObject) w;
00192 XtGCMask valuemask;
00193 XGCValues myXGCV;
00194
00195 valuemask = GCForeground;
00196 myXGCV.foreground = parent->core.background_pixel;
00197 tdo->sme_threeD.erase_GC = XtGetGC(w, valuemask, &myXGCV);
00198 }
00199
00200
00201 static void AllocTopShadowPixmap (new)
00202 Widget new;
00203 {
00204 SmeThreeDObject tdo = (SmeThreeDObject) new;
00205 Widget parent = XtParent (new);
00206 Display *dpy = XtDisplayOfObject (new);
00207 Screen *scn = XtScreenOfObject (new);
00208 unsigned long top_fg_pixel = 0, top_bg_pixel = 0;
00209 char *pm_data;
00210 Boolean create_pixmap = FALSE;
00211
00212
00213
00214
00215
00216
00217
00218 if (DefaultDepthOfScreen (scn) == 1) {
00219 top_fg_pixel = BlackPixelOfScreen (scn);
00220 top_bg_pixel = WhitePixelOfScreen (scn);
00221 pm_data = mtshadowpm_bits;
00222 create_pixmap = TRUE;
00223 } else if (tdo->sme_threeD.be_nice_to_cmap) {
00224 if (parent->core.background_pixel == WhitePixelOfScreen (scn)) {
00225 top_fg_pixel = WhitePixelOfScreen (scn);
00226 top_bg_pixel = BlackPixelOfScreen (scn);
00227 } else if (parent->core.background_pixel == BlackPixelOfScreen (scn)) {
00228 top_fg_pixel = BlackPixelOfScreen (scn);
00229 top_bg_pixel = WhitePixelOfScreen (scn);
00230 } else {
00231 top_fg_pixel = parent->core.background_pixel;
00232 top_bg_pixel = WhitePixelOfScreen (scn);
00233 }
00234 if (parent->core.background_pixel == WhitePixelOfScreen (scn) ||
00235 parent->core.background_pixel == BlackPixelOfScreen (scn))
00236 pm_data = mtshadowpm_bits;
00237 else
00238 pm_data = shadowpm_bits;
00239 create_pixmap = TRUE;
00240 }
00241 if (create_pixmap)
00242 tdo->sme_threeD.top_shadow_pxmap = XCreatePixmapFromBitmapData (dpy,
00243 RootWindowOfScreen (scn),
00244 pm_data,
00245 shadowpm_width,
00246 shadowpm_height,
00247 top_fg_pixel,
00248 top_bg_pixel,
00249 DefaultDepthOfScreen (scn));
00250 }
00251
00252
00253 static void AllocBotShadowPixmap (new)
00254 Widget new;
00255 {
00256 SmeThreeDObject tdo = (SmeThreeDObject) new;
00257 Widget parent = XtParent (new);
00258 Display *dpy = XtDisplayOfObject (new);
00259 Screen *scn = XtScreenOfObject (new);
00260 unsigned long bot_fg_pixel = 0, bot_bg_pixel = 0;
00261 char *pm_data;
00262 Boolean create_pixmap = FALSE;
00263
00264 if (DefaultDepthOfScreen (scn) == 1) {
00265 bot_fg_pixel = BlackPixelOfScreen (scn);
00266 bot_bg_pixel = WhitePixelOfScreen (scn);
00267 pm_data = mbshadowpm_bits;
00268 create_pixmap = TRUE;
00269 } else if (tdo->sme_threeD.be_nice_to_cmap) {
00270 if (parent->core.background_pixel == WhitePixelOfScreen (scn)) {
00271 bot_fg_pixel = WhitePixelOfScreen (scn);
00272 bot_bg_pixel = BlackPixelOfScreen (scn);
00273 } else if (parent->core.background_pixel == BlackPixelOfScreen (scn)) {
00274 bot_fg_pixel = BlackPixelOfScreen (scn);
00275 bot_bg_pixel = WhitePixelOfScreen (scn);
00276 } else {
00277 bot_fg_pixel = parent->core.background_pixel;
00278 bot_bg_pixel = BlackPixelOfScreen (scn);
00279 }
00280 if (parent->core.background_pixel == WhitePixelOfScreen (scn) ||
00281 parent->core.background_pixel == BlackPixelOfScreen (scn))
00282 pm_data = mbshadowpm_bits;
00283 else
00284 pm_data = shadowpm_bits;
00285 create_pixmap = TRUE;
00286 }
00287 if (create_pixmap)
00288 tdo->sme_threeD.bot_shadow_pxmap = XCreatePixmapFromBitmapData (dpy,
00289 RootWindowOfScreen (scn),
00290 pm_data,
00291 shadowpm_width,
00292 shadowpm_height,
00293 bot_fg_pixel,
00294 bot_bg_pixel,
00295 DefaultDepthOfScreen (scn));
00296 }
00297
00298
00299 void XawSme3dComputeTopShadowRGB (new, xcol_out)
00300 Widget new;
00301 XColor *xcol_out;
00302 {
00303 if (XtIsSubclass (new, smeThreeDObjectClass)) {
00304 SmeThreeDObject tdo = (SmeThreeDObject) new;
00305 Widget w = XtParent (new);
00306 XColor get_c;
00307 double contrast;
00308 Display *dpy = XtDisplayOfObject (new);
00309 Screen *scn = XtScreenOfObject (new);
00310 Colormap cmap = DefaultColormapOfScreen (scn);
00311
00312 get_c.pixel = w->core.background_pixel;
00313 if (get_c.pixel == WhitePixelOfScreen (scn) ||
00314 get_c.pixel == BlackPixelOfScreen (scn)) {
00315 contrast = (100 - tdo->sme_threeD.top_shadow_contrast) / 100.0;
00316 xcol_out->red = contrast * 65535.0;
00317 xcol_out->green = contrast * 65535.0;
00318 xcol_out->blue = contrast * 65535.0;
00319 } else {
00320 contrast = 1.0 + tdo->sme_threeD.top_shadow_contrast / 100.0;
00321 XQueryColor (dpy, cmap, &get_c);
00322 #define MIN(x,y) (unsigned short) (x < y) ? x : y
00323 xcol_out->red = MIN (65535, (int) (contrast * (double) get_c.red));
00324 xcol_out->green = MIN (65535, (int) (contrast * (double) get_c.green));
00325 xcol_out->blue = MIN (65535, (int) (contrast * (double) get_c.blue));
00326 #undef MIN
00327 }
00328 } else
00329 xcol_out->red = xcol_out->green = xcol_out->blue = 0;
00330 }
00331
00332
00333 static void AllocTopShadowPixel (new)
00334 Widget new;
00335 {
00336 XColor set_c;
00337 SmeThreeDObject tdo = (SmeThreeDObject) new;
00338 Display *dpy = XtDisplayOfObject (new);
00339 Screen *scn = XtScreenOfObject (new);
00340 Colormap cmap = DefaultColormapOfScreen (scn);
00341
00342 XawSme3dComputeTopShadowRGB (new, &set_c);
00343 (void) XAllocColor (dpy, cmap, &set_c);
00344 tdo->sme_threeD.top_shadow_pixel = set_c.pixel;
00345 }
00346
00347
00348
00349 void XawSme3dComputeBottomShadowRGB (new, xcol_out)
00350 Widget new;
00351 XColor *xcol_out;
00352 {
00353 if (XtIsSubclass (new, smeThreeDObjectClass)) {
00354 SmeThreeDObject tdo = (SmeThreeDObject) new;
00355 Widget w = XtParent (new);
00356 XColor get_c;
00357 double contrast;
00358 Display *dpy = XtDisplayOfObject (new);
00359 Screen *scn = XtScreenOfObject (new);
00360 Colormap cmap = DefaultColormapOfScreen (scn);
00361
00362 get_c.pixel = w->core.background_pixel;
00363 if (get_c.pixel == WhitePixelOfScreen (scn) ||
00364 get_c.pixel == BlackPixelOfScreen (scn)) {
00365 contrast = tdo->sme_threeD.bot_shadow_contrast / 100.0;
00366 xcol_out->red = contrast * 65535.0;
00367 xcol_out->green = contrast * 65535.0;
00368 xcol_out->blue = contrast * 65535.0;
00369 } else {
00370 XQueryColor (dpy, cmap, &get_c);
00371 contrast = (100 - tdo->sme_threeD.bot_shadow_contrast) / 100.0;
00372 xcol_out->red = contrast * get_c.red;
00373 xcol_out->green = contrast * get_c.green;
00374 xcol_out->blue = contrast * get_c.blue;
00375 }
00376 } else
00377 xcol_out->red = xcol_out->green = xcol_out->blue = 0;
00378 }
00379
00380
00381 static void AllocBotShadowPixel (new)
00382 Widget new;
00383 {
00384 XColor set_c;
00385 SmeThreeDObject tdo = (SmeThreeDObject) new;
00386 Display *dpy = XtDisplayOfObject (new);
00387 Screen *scn = XtScreenOfObject (new);
00388 Colormap cmap = DefaultColormapOfScreen (scn);
00389
00390 XawSme3dComputeBottomShadowRGB (new, &set_c);
00391 (void) XAllocColor (dpy, cmap, &set_c);
00392 tdo->sme_threeD.bot_shadow_pixel = set_c.pixel;
00393 }
00394
00395
00396
00397 static void ClassPartInitialize (wc)
00398 WidgetClass wc;
00399 {
00400 SmeThreeDClassRec *tdwc = (SmeThreeDClassRec *) wc;
00401 SmeThreeDClassRec *super =
00402 (SmeThreeDClassRec *) tdwc->rect_class.superclass;
00403
00404 if (tdwc->sme_threeD_class.shadowdraw == XtInheritXawSme3dShadowDraw)
00405 tdwc->sme_threeD_class.shadowdraw = super->sme_threeD_class.shadowdraw;
00406 }
00407
00408
00409 static void Initialize (request, new, args, num_args)
00410 Widget request, new;
00411 ArgList args;
00412 Cardinal *num_args;
00413 {
00414 SmeThreeDObject w = (SmeThreeDObject) new;
00415 Screen *scr = XtScreenOfObject (new);
00416
00417 if (w->sme_threeD.be_nice_to_cmap || DefaultDepthOfScreen (scr) == 1) {
00418 AllocTopShadowPixmap (new);
00419 AllocBotShadowPixmap (new);
00420 } else {
00421 if (w->sme_threeD.top_shadow_pixel == w->sme_threeD.bot_shadow_pixel) {
00422 AllocTopShadowPixel (new);
00423 AllocBotShadowPixel (new);
00424 }
00425 w->sme_threeD.top_shadow_pxmap = w->sme_threeD.bot_shadow_pxmap = 0;
00426 }
00427 AllocTopShadowGC (new);
00428 AllocBotShadowGC (new);
00429 AllocEraseGC (new);
00430 }
00431
00432 static void Destroy (gw)
00433 Widget gw;
00434 {
00435 SmeThreeDObject w = (SmeThreeDObject) gw;
00436 XtReleaseGC (gw, w->sme_threeD.top_shadow_GC);
00437 XtReleaseGC (gw, w->sme_threeD.bot_shadow_GC);
00438 XtReleaseGC (gw, w->sme_threeD.erase_GC);
00439 if (w->sme_threeD.top_shadow_pxmap)
00440 XFreePixmap (XtDisplayOfObject (gw), w->sme_threeD.top_shadow_pxmap);
00441 if (w->sme_threeD.bot_shadow_pxmap)
00442 XFreePixmap (XtDisplayOfObject (gw), w->sme_threeD.bot_shadow_pxmap);
00443 }
00444
00445
00446 static Boolean SetValues (gcurrent, grequest, gnew, args, num_args)
00447 Widget gcurrent, grequest, gnew;
00448 ArgList args;
00449 Cardinal *num_args;
00450 {
00451 SmeThreeDObject current = (SmeThreeDObject) gcurrent;
00452 SmeThreeDObject new = (SmeThreeDObject) gnew;
00453 Boolean redisplay = FALSE;
00454 Boolean alloc_top_pixel = FALSE;
00455 Boolean alloc_bot_pixel = FALSE;
00456 Boolean alloc_top_pixmap = FALSE;
00457 Boolean alloc_bot_pixmap = FALSE;
00458
00459 #if 0
00460 (*threeDWidgetClass->core_class.superclass->core_class.set_values)
00461 (gcurrent, grequest, gnew, NULL, 0);
00462 #endif
00463 if (new->sme_threeD.shadow_width != current->sme_threeD.shadow_width)
00464 redisplay = TRUE;
00465 if (new->sme_threeD.be_nice_to_cmap != current->sme_threeD.be_nice_to_cmap) {
00466 if (new->sme_threeD.be_nice_to_cmap) {
00467 alloc_top_pixmap = TRUE;
00468 alloc_bot_pixmap = TRUE;
00469 } else {
00470 alloc_top_pixel = TRUE;
00471 alloc_bot_pixel = TRUE;
00472 }
00473 redisplay = TRUE;
00474 }
00475 if (!new->sme_threeD.be_nice_to_cmap &&
00476 new->sme_threeD.top_shadow_contrast != current->sme_threeD.top_shadow_contrast)
00477 alloc_top_pixel = TRUE;
00478 if (!new->sme_threeD.be_nice_to_cmap &&
00479 new->sme_threeD.bot_shadow_contrast != current->sme_threeD.bot_shadow_contrast)
00480 alloc_bot_pixel = TRUE;
00481 if (alloc_top_pixel)
00482 AllocTopShadowPixel (gnew);
00483 if (alloc_bot_pixel)
00484 AllocBotShadowPixel (gnew);
00485 if (alloc_top_pixmap)
00486 AllocTopShadowPixmap (gnew);
00487 if (alloc_bot_pixmap)
00488 AllocBotShadowPixmap (gnew);
00489 if (!new->sme_threeD.be_nice_to_cmap &&
00490 new->sme_threeD.top_shadow_pixel != current->sme_threeD.top_shadow_pixel)
00491 alloc_top_pixel = TRUE;
00492 if (!new->sme_threeD.be_nice_to_cmap &&
00493 new->sme_threeD.bot_shadow_pixel != current->sme_threeD.bot_shadow_pixel)
00494 alloc_bot_pixel = TRUE;
00495 if (new->sme_threeD.be_nice_to_cmap) {
00496 if (alloc_top_pixmap) {
00497 XtReleaseGC (gcurrent, current->sme_threeD.top_shadow_GC);
00498 AllocTopShadowGC (gnew);
00499 redisplay = True;
00500 }
00501 if (alloc_bot_pixmap) {
00502 XtReleaseGC (gcurrent, current->sme_threeD.bot_shadow_GC);
00503 AllocBotShadowGC (gnew);
00504 redisplay = True;
00505 }
00506 } else {
00507 if (alloc_top_pixel) {
00508 if (new->sme_threeD.top_shadow_pxmap) {
00509 XFreePixmap (XtDisplayOfObject (gnew), new->sme_threeD.top_shadow_pxmap);
00510 new->sme_threeD.top_shadow_pxmap = (Pixmap) NULL;
00511 }
00512 XtReleaseGC (gcurrent, current->sme_threeD.top_shadow_GC);
00513 AllocTopShadowGC (gnew);
00514 redisplay = True;
00515 }
00516 if (alloc_bot_pixel) {
00517 if (new->sme_threeD.bot_shadow_pxmap) {
00518 XFreePixmap (XtDisplayOfObject (gnew), new->sme_threeD.bot_shadow_pxmap);
00519 new->sme_threeD.bot_shadow_pxmap = (Pixmap) NULL;
00520 }
00521 XtReleaseGC (gcurrent, current->sme_threeD.bot_shadow_GC);
00522 AllocBotShadowGC (gnew);
00523 redisplay = True;
00524 }
00525 }
00526 return (redisplay);
00527 }
00528
00529
00530 static void
00531 _XawSme3dDrawShadows (gw)
00532 Widget gw;
00533 {
00534 XPoint pt[6];
00535 SmeThreeDObject tdo = (SmeThreeDObject) gw;
00536 Dimension s = tdo->sme_threeD.shadow_width;
00537
00538
00539
00540
00541
00542
00543
00544 if((s > 0) && XtIsRealized (gw)){
00545
00546 Dimension h = tdo->rectangle.height;
00547 Dimension w = tdo->rectangle.width;
00548 Dimension x = tdo->rectangle.x;
00549 Dimension y = tdo->rectangle.y;
00550 Display *dpy = XtDisplayOfObject (gw);
00551 Window win = XtWindowOfObject (gw);
00552 GC top, bot;
00553
00554 if (tdo->sme_threeD.shadowed) {
00555 top = tdo->sme_threeD.top_shadow_GC;
00556 bot = tdo->sme_threeD.bot_shadow_GC;
00557 } else
00558 top = bot = tdo->sme_threeD.erase_GC;
00559
00560
00561 pt[0].x = x; pt[0].y = y + h;
00562 pt[1].x = x; pt[1].y = y;
00563 pt[2].x = w; pt[2].y = y;
00564 pt[3].x = w - s; pt[3].y = y + s;
00565 pt[4].x = s; pt[4].y = y + s;
00566 pt[5].x = s; pt[5].y = y + h - s;
00567 XFillPolygon (dpy, win, top, pt, 6,Complex,CoordModeOrigin);
00568
00569
00570
00571 pt[1].x = w; pt[1].y = y + h;
00572
00573
00574 pt[4].x = w - s; pt[4].y = y + h - s;
00575
00576 XFillPolygon (dpy, win, bot, pt,6, Complex,CoordModeOrigin);
00577 }
00578 }
00579