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
00031
00032
00033
00034
00035
00036
00037
00038 #include <X11/IntrinsicP.h>
00039 #include <X11/StringDefs.h>
00040 #include <X11/Xos.h>
00041
00042
00043 #ifdef X_NOT_STDC_ENV
00044 extern int abs();
00045 #else
00046 #include <stdlib.h>
00047 #endif
00048
00049 #include <X11/Xmu/Drawing.h>
00050
00051 #include <X11/Xaw3d/XawInit.h>
00052 #include <X11/Xaw3d/SimpleMenu.h>
00053 #include <X11/Xaw3d/SmeBSBP.h>
00054 #include <X11/Xaw3d/Cardinals.h>
00055
00056 #include <stdio.h>
00057
00058 #define ONE_HUNDRED 100
00059
00060 #define offset(field) XtOffsetOf(SmeBSBRec, sme_bsb.field)
00061
00062 static XtResource resources[] = {
00063 {XtNlabel, XtCLabel, XtRString, sizeof(String),
00064 offset(label), XtRString, NULL},
00065 {XtNvertSpace, XtCVertSpace, XtRInt, sizeof(int),
00066 offset(vert_space), XtRImmediate, (XtPointer) 25},
00067 {XtNleftBitmap, XtCLeftBitmap, XtRBitmap, sizeof(Pixmap),
00068 offset(left_bitmap), XtRImmediate, (XtPointer)None},
00069 {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify),
00070 offset(justify), XtRImmediate, (XtPointer) XtJustifyLeft},
00071 {XtNrightBitmap, XtCRightBitmap, XtRBitmap, sizeof(Pixmap),
00072 offset(right_bitmap), XtRImmediate, (XtPointer)None},
00073 {XtNleftMargin, XtCHorizontalMargins, XtRDimension, sizeof(Dimension),
00074 offset(left_margin), XtRImmediate, (XtPointer) 4},
00075 {XtNrightMargin, XtCHorizontalMargins, XtRDimension, sizeof(Dimension),
00076 offset(right_margin), XtRImmediate, (XtPointer) 4},
00077 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
00078 offset(foreground), XtRString, XtDefaultForeground},
00079 {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
00080 offset(font), XtRString, XtDefaultFont},
00081 {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet ),
00082 offset(fontset),XtRString, XtDefaultFontSet},
00083 };
00084 #undef offset
00085
00086
00087
00088
00089
00090 static void Redisplay(), Destroy(), Initialize(), FlipColors();
00091 static void ClassInitialize();
00092 static Boolean SetValues();
00093 static XtGeometryResult QueryGeometry();
00094
00095
00096
00097
00098
00099 static void GetDefaultSize(), DrawBitmaps(), GetBitmapInfo();
00100 static void CreateGCs(), DestroyGCs();
00101
00102 #define superclass (&smeThreeDClassRec)
00103 SmeBSBClassRec smeBSBClassRec = {
00104 {
00105 (WidgetClass) superclass,
00106 "SmeBSB",
00107 sizeof(SmeBSBRec),
00108 ClassInitialize,
00109 NULL,
00110 FALSE,
00111 Initialize,
00112 NULL,
00113 NULL,
00114 NULL,
00115 ZERO,
00116 resources,
00117 XtNumber(resources),
00118 NULLQUARK,
00119 FALSE,
00120 FALSE,
00121 FALSE,
00122 FALSE,
00123 Destroy,
00124 NULL,
00125 Redisplay,
00126 SetValues,
00127 NULL,
00128 XtInheritSetValuesAlmost,
00129 NULL,
00130 NULL,
00131 XtVersion,
00132 NULL,
00133 NULL,
00134 QueryGeometry,
00135 NULL,
00136 NULL
00137 },{
00138
00139 FlipColors,
00140 FlipColors,
00141 XtInheritNotify,
00142 NULL
00143 }, {
00144
00145 XtInheritXawSme3dShadowDraw
00146 }, {
00147
00148 NULL
00149 }
00150 };
00151
00152 WidgetClass smeBSBObjectClass = (WidgetClass) &smeBSBClassRec;
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 static void
00167 ClassInitialize()
00168 {
00169 XawInitializeWidgetSet();
00170 XtAddConverter( XtRString, XtRJustify, XmuCvtStringToJustify,
00171 (XtConvertArgList)NULL, (Cardinal)0 );
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 static void
00184 Initialize(request, new, args, num_args)
00185 Widget request, new;
00186 ArgList args;
00187 Cardinal *num_args;
00188 {
00189 SmeBSBObject entry = (SmeBSBObject) new;
00190
00191 if (entry->sme_bsb.label == NULL)
00192 entry->sme_bsb.label = XtName(new);
00193 else
00194 entry->sme_bsb.label = XtNewString( entry->sme_bsb.label );
00195
00196 GetDefaultSize(new, &(entry->rectangle.width), &(entry->rectangle.height));
00197 CreateGCs(new);
00198
00199 entry->sme_bsb.left_bitmap_width = entry->sme_bsb.left_bitmap_height = 0;
00200 entry->sme_bsb.right_bitmap_width = entry->sme_bsb.right_bitmap_height = 0;
00201
00202 GetBitmapInfo(new, TRUE);
00203 GetBitmapInfo(new, FALSE);
00204 }
00205
00206
00207
00208
00209
00210
00211
00212 static void
00213 Destroy(w)
00214 Widget w;
00215 {
00216 SmeBSBObject entry = (SmeBSBObject) w;
00217
00218 DestroyGCs(w);
00219 if (entry->sme_bsb.label != XtName(w))
00220 XtFree(entry->sme_bsb.label);
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 static void
00233 Redisplay(w, event, region)
00234 Widget w;
00235 XEvent * event;
00236 Region region;
00237 {
00238 GC gc;
00239 SmeBSBObject entry = (SmeBSBObject) w;
00240 Dimension s = entry->sme_threeD.shadow_width;
00241 int font_ascent = 0, font_descent = 0, y_loc;
00242
00243 int fontset_ascent = 0, fontset_descent = 0;
00244 XFontSetExtents *ext = XExtentsOfFontSet(entry->sme_bsb.fontset);
00245
00246 entry->sme_bsb.set_values_area_cleared = FALSE;
00247 if ( entry->sme.international == True ) {
00248 fontset_ascent = abs(ext->max_ink_extent.y);
00249 fontset_descent = ext->max_ink_extent.height - fontset_ascent;
00250 }
00251 else {
00252 font_ascent = entry->sme_bsb.font->max_bounds.ascent;
00253 font_descent = entry->sme_bsb.font->max_bounds.descent;
00254 }
00255 y_loc = entry->rectangle.y;
00256
00257
00258 if (XtIsSensitive(w) && XtIsSensitive( XtParent(w) ) ) {
00259 if ( w == XawSimpleMenuGetActiveEntry(XtParent(w)) ) {
00260 XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
00261 entry->sme_bsb.norm_gc, s, y_loc + s,
00262 (unsigned int) entry->rectangle.width - 2 * s,
00263 (unsigned int) entry->rectangle.height - 2 * s);
00264 gc = entry->sme_bsb.rev_gc;
00265 }
00266 else
00267 gc = entry->sme_bsb.norm_gc;
00268 }
00269 else
00270 gc = entry->sme_bsb.norm_gray_gc;
00271
00272 if (entry->sme_bsb.label != NULL) {
00273 int x_loc = entry->sme_bsb.left_margin;
00274 int len = strlen(entry->sme_bsb.label);
00275 char * label = entry->sme_bsb.label;
00276
00277 switch(entry->sme_bsb.justify) {
00278 int width, t_width;
00279
00280 case XtJustifyCenter:
00281 if ( entry->sme.international == True ) {
00282 t_width = XmbTextEscapement(entry->sme_bsb.fontset,label,len);
00283 width = entry->rectangle.width - (entry->sme_bsb.left_margin +
00284 entry->sme_bsb.right_margin);
00285 }
00286 else {
00287 t_width = XTextWidth(entry->sme_bsb.font, label, len);
00288 width = entry->rectangle.width - (entry->sme_bsb.left_margin +
00289 entry->sme_bsb.right_margin);
00290 }
00291 x_loc += (width - t_width)/2;
00292 break;
00293 case XtJustifyRight:
00294 if ( entry->sme.international == True ) {
00295 t_width = XmbTextEscapement(entry->sme_bsb.fontset,label,len);
00296 x_loc = entry->rectangle.width - ( entry->sme_bsb.right_margin
00297 + t_width );
00298 }
00299 else {
00300 t_width = XTextWidth(entry->sme_bsb.font, label, len);
00301 x_loc = entry->rectangle.width - ( entry->sme_bsb.right_margin
00302 + t_width );
00303 }
00304 break;
00305 case XtJustifyLeft:
00306 default:
00307 break;
00308 }
00309
00310
00311
00312
00313 if ( entry->sme.international==True ) {
00314 y_loc += ((int)entry->rectangle.height -
00315 (fontset_ascent + fontset_descent)) / 2 + fontset_ascent;
00316
00317 XmbDrawString(XtDisplayOfObject(w), XtWindowOfObject(w),
00318 entry->sme_bsb.fontset, gc, x_loc + s, y_loc, label, len);
00319 }
00320 else {
00321 y_loc += ((int)entry->rectangle.height -
00322 (font_ascent + font_descent)) / 2 + font_ascent;
00323
00324 XDrawString(XtDisplayOfObject(w), XtWindowOfObject(w), gc,
00325 x_loc + s, y_loc, label, len);
00326 }
00327 }
00328
00329 DrawBitmaps(w, gc);
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 static Boolean
00343 SetValues(current, request, new, args, num_args)
00344 Widget current, request, new;
00345 ArgList args;
00346 Cardinal *num_args;
00347 {
00348 SmeBSBObject entry = (SmeBSBObject) new;
00349 SmeBSBObject old_entry = (SmeBSBObject) current;
00350 Boolean ret_val = FALSE;
00351
00352 if (old_entry->sme_bsb.label != entry->sme_bsb.label) {
00353 if (old_entry->sme_bsb.label != XtName( new ) )
00354 XtFree( (char *) old_entry->sme_bsb.label );
00355
00356 if (entry->sme_bsb.label != XtName(new) )
00357 entry->sme_bsb.label = XtNewString( entry->sme_bsb.label );
00358
00359 ret_val = True;
00360 }
00361
00362 if (entry->rectangle.sensitive != old_entry->rectangle.sensitive )
00363 ret_val = TRUE;
00364
00365 if (entry->sme_bsb.left_bitmap != old_entry->sme_bsb.left_bitmap) {
00366 GetBitmapInfo(new, TRUE);
00367 ret_val = TRUE;
00368 }
00369
00370 if (entry->sme_bsb.right_bitmap != old_entry->sme_bsb.right_bitmap) {
00371 GetBitmapInfo(new, FALSE);
00372 ret_val = TRUE;
00373 }
00374
00375 if ( ( (old_entry->sme_bsb.font != entry->sme_bsb.font) &&
00376 (old_entry->sme.international == False ) ) ||
00377 (old_entry->sme_bsb.foreground != entry->sme_bsb.foreground) ) {
00378 DestroyGCs(current);
00379 CreateGCs(new);
00380 ret_val = TRUE;
00381 }
00382
00383 if ( ( old_entry->sme_bsb.fontset != entry->sme_bsb.fontset) &&
00384 (old_entry->sme.international == True ) )
00385
00386 ret_val = TRUE;
00387
00388 if (ret_val) {
00389 GetDefaultSize(new,
00390 &(entry->rectangle.width), &(entry->rectangle.height));
00391 entry->sme_bsb.set_values_area_cleared = TRUE;
00392 }
00393 return(ret_val);
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 static XtGeometryResult
00408 QueryGeometry(w, intended, return_val)
00409 Widget w;
00410 XtWidgetGeometry *intended, *return_val;
00411 {
00412 SmeBSBObject entry = (SmeBSBObject) w;
00413 Dimension width, height;
00414 XtGeometryResult ret_val = XtGeometryYes;
00415 XtGeometryMask mode = intended->request_mode;
00416
00417 GetDefaultSize(w, &width, &height );
00418
00419 if ( ((mode & CWWidth) && (intended->width != width)) ||
00420 !(mode & CWWidth) ) {
00421 return_val->request_mode |= CWWidth;
00422 return_val->width = width;
00423 ret_val = XtGeometryAlmost;
00424 }
00425
00426 if ( ((mode & CWHeight) && (intended->height != height)) ||
00427 !(mode & CWHeight) ) {
00428 return_val->request_mode |= CWHeight;
00429 return_val->height = height;
00430 ret_val = XtGeometryAlmost;
00431 }
00432
00433 if (ret_val == XtGeometryAlmost) {
00434 mode = return_val->request_mode;
00435
00436 if ( ((mode & CWWidth) && (width == entry->rectangle.width)) &&
00437 ((mode & CWHeight) && (height == entry->rectangle.height)) )
00438 return(XtGeometryNo);
00439 }
00440
00441 return(ret_val);
00442 }
00443
00444
00445
00446
00447
00448
00449
00450 static void
00451 FlipColors(w)
00452 Widget w;
00453 {
00454 SmeBSBObject entry = (SmeBSBObject) w;
00455 SmeBSBObjectClass oclass = (SmeBSBObjectClass) XtClass (w);
00456
00457 if (entry->sme_bsb.set_values_area_cleared) {
00458 entry->sme_threeD.shadowed = False;
00459 return;
00460 }
00461
00462 if (entry->sme_threeD.shadow_width > 0) {
00463 entry->sme_threeD.shadowed ^= True;
00464 (*oclass->sme_threeD_class.shadowdraw) (w);
00465 } else
00466 XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
00467 entry->sme_bsb.invert_gc,
00468 0, (int) entry->rectangle.y,
00469 (unsigned int) entry->rectangle.width,
00470 (unsigned int) entry->rectangle.height);
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 static void
00488 GetDefaultSize(w, width, height)
00489 Widget w;
00490 Dimension * width, * height;
00491 {
00492 SmeBSBObject entry = (SmeBSBObject) w;
00493
00494 if ( entry->sme.international == True ) {
00495 XFontSetExtents *ext = XExtentsOfFontSet(entry->sme_bsb.fontset);
00496 if (entry->sme_bsb.label == NULL)
00497 *width = 0;
00498 else
00499 *width = XmbTextEscapement(entry->sme_bsb.fontset, entry->sme_bsb.label,
00500 strlen(entry->sme_bsb.label));
00501 *width += entry->sme_bsb.left_margin + entry->sme_bsb.right_margin;
00502 *width += (2 * entry->sme_threeD.shadow_width);
00503 *height = ext->max_ink_extent.height;
00504 *height = ((int)*height * ( ONE_HUNDRED +
00505 entry->sme_bsb.vert_space )) / ONE_HUNDRED;
00506 *height += (2 * entry->sme_threeD.shadow_width);
00507 }
00508 else {
00509 if (entry->sme_bsb.label == NULL)
00510 *width = 0;
00511 else
00512 *width = XTextWidth(entry->sme_bsb.font, entry->sme_bsb.label,
00513 strlen(entry->sme_bsb.label));
00514
00515 *width += entry->sme_bsb.left_margin + entry->sme_bsb.right_margin;
00516 *width += (2 * entry->sme_threeD.shadow_width);
00517
00518 *height = (entry->sme_bsb.font->max_bounds.ascent +
00519 entry->sme_bsb.font->max_bounds.descent);
00520
00521 *height = ((int)*height * ( ONE_HUNDRED +
00522 entry->sme_bsb.vert_space )) / ONE_HUNDRED;
00523 *height += (2 * entry->sme_threeD.shadow_width);
00524 }
00525 }
00526
00527
00528
00529
00530
00531
00532
00533
00534 static void
00535 DrawBitmaps(w, gc)
00536 Widget w;
00537 GC gc;
00538 {
00539 int x_loc, y_loc;
00540 SmeBSBObject entry = (SmeBSBObject) w;
00541
00542 if ( (entry->sme_bsb.left_bitmap == None) &&
00543 (entry->sme_bsb.right_bitmap == None) ) return;
00544
00545
00546
00547
00548
00549 if (entry->sme_bsb.left_bitmap != None) {
00550 x_loc = entry->sme_threeD.shadow_width +
00551 (int)(entry->sme_bsb.left_margin -
00552 entry->sme_bsb.left_bitmap_width) / 2;
00553
00554 y_loc = entry->rectangle.y +
00555 (int)(entry->rectangle.height -
00556 entry->sme_bsb.left_bitmap_height) / 2;
00557
00558 XCopyPlane(XtDisplayOfObject(w), entry->sme_bsb.left_bitmap,
00559 XtWindowOfObject(w), gc, 0, 0,
00560 entry->sme_bsb.left_bitmap_width,
00561 entry->sme_bsb.left_bitmap_height, x_loc, y_loc, 1);
00562 }
00563
00564
00565
00566
00567
00568
00569 if (entry->sme_bsb.right_bitmap != None) {
00570 x_loc = entry->rectangle.width - entry->sme_threeD.shadow_width -
00571 (int)(entry->sme_bsb.right_margin +
00572 entry->sme_bsb.right_bitmap_width) / 2;
00573
00574 y_loc = entry->rectangle.y +
00575 (int)(entry->rectangle.height -
00576 entry->sme_bsb.right_bitmap_height) / 2;
00577
00578 XCopyPlane(XtDisplayOfObject(w), entry->sme_bsb.right_bitmap,
00579 XtWindowOfObject(w), gc, 0, 0,
00580 entry->sme_bsb.right_bitmap_width,
00581 entry->sme_bsb.right_bitmap_height, x_loc, y_loc, 1);
00582 }
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 static void
00594 GetBitmapInfo(w, is_left)
00595 Widget w;
00596 Boolean is_left;
00597 {
00598 SmeBSBObject entry = (SmeBSBObject) w;
00599 unsigned int depth, bw;
00600 Window root;
00601 int x, y;
00602 unsigned int width, height;
00603 char buf[BUFSIZ];
00604
00605 if (is_left) {
00606 if (entry->sme_bsb.left_bitmap != None) {
00607 if (!XGetGeometry(XtDisplayOfObject(w),
00608 entry->sme_bsb.left_bitmap, &root,
00609 &x, &y, &width, &height, &bw, &depth)) {
00610 (void) sprintf(buf, "Xaw SmeBSB Object: %s %s \"%s\".", "Could not",
00611 "get Left Bitmap geometry information for menu entry ",
00612 XtName(w));
00613 XtAppError(XtWidgetToApplicationContext(w), buf);
00614 }
00615 if (depth != 1) {
00616 (void) sprintf(buf, "Xaw SmeBSB Object: %s \"%s\"%s.",
00617 "Left Bitmap of entry ",
00618 XtName(w), " is not one bit deep.");
00619 XtAppError(XtWidgetToApplicationContext(w), buf);
00620 }
00621 entry->sme_bsb.left_bitmap_width = (Dimension) width;
00622 entry->sme_bsb.left_bitmap_height = (Dimension) height;
00623 }
00624 }
00625 else if (entry->sme_bsb.right_bitmap != None) {
00626 if (!XGetGeometry(XtDisplayOfObject(w),
00627 entry->sme_bsb.right_bitmap, &root,
00628 &x, &y, &width, &height, &bw, &depth)) {
00629 (void) sprintf(buf, "Xaw SmeBSB Object: %s %s \"%s\".", "Could not",
00630 "get Right Bitmap geometry information for menu entry ",
00631 XtName(w));
00632 XtAppError(XtWidgetToApplicationContext(w), buf);
00633 }
00634 if (depth != 1) {
00635 (void) sprintf(buf, "Xaw SmeBSB Object: %s \"%s\"%s.",
00636 "Right Bitmap of entry ", XtName(w),
00637 " is not one bit deep.");
00638 XtAppError(XtWidgetToApplicationContext(w), buf);
00639 }
00640 entry->sme_bsb.right_bitmap_width = (Dimension) width;
00641 entry->sme_bsb.right_bitmap_height = (Dimension) height;
00642 }
00643 }
00644
00645
00646
00647
00648
00649
00650
00651 static void
00652 CreateGCs(w)
00653 Widget w;
00654 {
00655 SmeBSBObject entry = (SmeBSBObject) w;
00656 XGCValues values;
00657 XtGCMask mask, mask_i18n;
00658
00659 values.foreground = XtParent(w)->core.background_pixel;
00660 values.background = entry->sme_bsb.foreground;
00661 values.font = entry->sme_bsb.font->fid;
00662 values.graphics_exposures = FALSE;
00663 mask = GCForeground | GCBackground | GCGraphicsExposures | GCFont;
00664 mask_i18n = GCForeground | GCBackground | GCGraphicsExposures;
00665 if ( entry->sme.international == True )
00666 entry->sme_bsb.rev_gc = XtAllocateGC(w, 0, mask_i18n, &values, GCFont, 0 );
00667 else
00668 entry->sme_bsb.rev_gc = XtGetGC(w, mask, &values);
00669
00670 values.foreground = entry->sme_bsb.foreground;
00671 values.background = XtParent(w)->core.background_pixel;
00672 if ( entry->sme.international == True )
00673 entry->sme_bsb.norm_gc = XtAllocateGC(w, 0, mask_i18n, &values, GCFont, 0 );
00674 else
00675 entry->sme_bsb.norm_gc = XtGetGC(w, mask, &values);
00676
00677 values.fill_style = FillTiled;
00678 values.tile = XmuCreateStippledPixmap(XtScreenOfObject(w),
00679 entry->sme_bsb.foreground,
00680 XtParent(w)->core.background_pixel,
00681 XtParent(w)->core.depth);
00682 values.graphics_exposures = FALSE;
00683 mask |= GCTile | GCFillStyle;
00684 if ( entry->sme.international == True )
00685 entry->sme_bsb.norm_gray_gc = XtAllocateGC(w, 0, mask_i18n, &values, GCFont, 0 );
00686 else
00687 entry->sme_bsb.norm_gray_gc = XtGetGC(w, mask, &values);
00688
00689 values.foreground ^= values.background;
00690 values.background = 0;
00691 values.function = GXxor;
00692 mask = GCForeground | GCBackground | GCGraphicsExposures | GCFunction;
00693 entry->sme_bsb.invert_gc = XtGetGC(w, mask, &values);
00694 }
00695
00696
00697
00698
00699
00700
00701
00702 static void
00703 DestroyGCs(w)
00704 Widget w;
00705 {
00706 SmeBSBObject entry = (SmeBSBObject) w;
00707
00708 XtReleaseGC(w, entry->sme_bsb.norm_gc);
00709 XtReleaseGC(w, entry->sme_bsb.norm_gray_gc);
00710 XtReleaseGC(w, entry->sme_bsb.rev_gc);
00711 XtReleaseGC(w, entry->sme_bsb.invert_gc);
00712 }
00713
00714 #ifdef apollo
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 void _XawSmeBSBApolloHack ()
00725 {
00726 FlipColors();
00727 }
00728 #endif