1 #if ( !defined(lint) && !defined(SABER) )
2 static char Xrcsid
[] = "$XConsortium: SmeBSB.c,v 1.12 90/02/15 13:57:53 kit Exp $";
6 * Copyright 1989 Massachusetts Institute of Technology
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of M.I.T. not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission. M.I.T. makes no representations about the
15 * suitability of this software for any purpose. It is provided "as is"
16 * without express or implied warranty.
18 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
20 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
22 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 * SmeBSB.c - Source code file for BSB Menu Entry object.
29 * Date: September 26, 1989
31 * By: Chris D. Peterson
33 * kit@expo.lcs.mit.edu
37 #include <X11/IntrinsicP.h>
38 #include <X11/StringDefs.h>
40 #include <X11/Xmu/Drawing.h>
42 #include <./Xaw3_1XawInit.h>
43 #include <./Xaw3_1SimpleMenu.h>
44 #include <./Xaw3_1SmeBSBP.h>
45 #include <./Xaw3_1Cardinals.h>
47 #define ONE_HUNDRED 100
49 #define offset(field) XtOffset(SmeBSBObject, sme_bsb.field)
51 static XtResource resources
[] = {
52 {XtNlabel
, XtCLabel
, XtRString
, sizeof(String
),
53 offset(label
), XtRString
, NULL
},
54 {XtNvertSpace
, XtCVertSpace
, XtRInt
, sizeof(int),
55 offset(vert_space
), XtRImmediate
, (caddr_t
) 25},
56 {XtNleftBitmap
, XtCLeftBitmap
, XtRBitmap
, sizeof(Pixmap
),
57 offset(left_bitmap
), XtRImmediate
, (caddr_t
)None
},
58 {XtNjustify
, XtCJustify
, XtRJustify
, sizeof(XtJustify
),
59 offset(justify
), XtRImmediate
, (caddr_t
) XtJustifyLeft
},
60 {XtNrightBitmap
, XtCRightBitmap
, XtRBitmap
, sizeof(Pixmap
),
61 offset(right_bitmap
), XtRImmediate
, (caddr_t
)None
},
62 {XtNleftMargin
, XtCHorizontalMargins
, XtRDimension
, sizeof(Dimension
),
63 offset(left_margin
), XtRImmediate
, (caddr_t
) 4},
64 {XtNrightMargin
, XtCHorizontalMargins
, XtRDimension
, sizeof(Dimension
),
65 offset(right_margin
), XtRImmediate
, (caddr_t
) 4},
66 {XtNforeground
, XtCForeground
, XtRPixel
, sizeof(Pixel
),
67 offset(foreground
), XtRString
, "XtDefaultForeground"},
68 {XtNfont
, XtCFont
, XtRFontStruct
, sizeof(XFontStruct
*),
69 offset(font
), XtRString
, "XtDefaultFont"},
74 * Semi Public function definitions.
77 static void Redisplay(), Destroy(), Initialize(), FlipColors();
78 static void ClassInitialize();
79 static Boolean
SetValues();
80 static XtGeometryResult
QueryGeometry();
83 * Private Function Definitions.
86 static void GetDefaultSize(), DrawBitmaps(), GetBitmapInfo();
87 static void CreateGCs(), DestroyGCs();
89 #define superclass (&smeClassRec)
90 SmeBSBClassRec smeBSBClassRec
= {
92 /* superclass */ (WidgetClass
) superclass
,
93 /* class_name */ "SmeBSB",
94 /* size */ sizeof(SmeBSBRec
),
95 /* class_initializer */ ClassInitialize
,
96 /* class_part_initialize*/ NULL
,
97 /* Class init'ed */ FALSE
,
98 /* initialize */ Initialize
,
99 /* initialize_hook */ NULL
,
102 /* num_actions */ ZERO
,
103 /* resources */ resources
,
104 /* resource_count */ XtNumber(resources
),
105 /* xrm_class */ NULLQUARK
,
106 /* compress_motion */ FALSE
,
107 /* compress_exposure */ FALSE
,
108 /* compress_enterleave*/ FALSE
,
109 /* visible_interest */ FALSE
,
110 /* destroy */ Destroy
,
112 /* expose */ Redisplay
,
113 /* set_values */ SetValues
,
114 /* set_values_hook */ NULL
,
115 /* set_values_almost */ XtInheritSetValuesAlmost
,
116 /* get_values_hook */ NULL
,
117 /* accept_focus */ NULL
,
118 /* intrinsics version */ XtVersion
,
119 /* callback offsets */ NULL
,
121 /* query_geometry */ QueryGeometry
,
122 /* display_accelerator*/ NULL
,
125 /* Menu Entry Fields */
127 /* highlight */ FlipColors
,
128 /* unhighlight */ FlipColors
,
129 /* notify */ XtInheritNotify
,
132 /* BSB Menu entry Fields */
138 WidgetClass smeBSBObjectClass
= (WidgetClass
) &smeBSBClassRec
;
140 /************************************************************
142 * Semi-Public Functions.
144 ************************************************************/
146 /* Function Name: ClassInitialize
147 * Description: Initializes the SmeBSBObject.
155 XawInitializeWidgetSet();
156 XtAddConverter( XtRString
, XtRJustify
, XmuCvtStringToJustify
, NULL
, 0 );
159 /* Function Name: Initialize
160 * Description: Initializes the simple menu widget
161 * Arguments: request - the widget requested by the argument list.
162 * new - the new widget with both resource and non
169 Initialize(request
, new)
172 SmeBSBObject entry
= (SmeBSBObject
) new;
174 if (entry
->sme_bsb
.label
== NULL
)
175 entry
->sme_bsb
.label
= XtName(new);
177 entry
->sme_bsb
.label
= XtNewString( entry
->sme_bsb
.label
);
179 GetDefaultSize(new, &(entry
->rectangle
.width
), &(entry
->rectangle
.height
));
182 entry
->sme_bsb
.left_bitmap_width
= entry
->sme_bsb
.left_bitmap_height
= 0;
183 entry
->sme_bsb
.right_bitmap_width
= entry
->sme_bsb
.right_bitmap_height
= 0;
185 GetBitmapInfo(new, TRUE
); /* Left Bitmap Info */
186 GetBitmapInfo(new, FALSE
); /* Right Bitmap Info */
189 /* Function Name: Destroy
190 * Description: Called at destroy time, cleans up.
191 * Arguments: w - the simple menu widget.
199 SmeBSBObject entry
= (SmeBSBObject
) w
;
202 if (entry
->sme_bsb
.label
!= XtName(w
))
203 XtFree(entry
->sme_bsb
.label
);
206 /* Function Name: Redisplay
207 * Description: Redisplays the contents of the widget.
208 * Arguments: w - the simple menu widget.
209 * event - the X event that caused this redisplay.
210 * region - the region the needs to be repainted.
216 Redisplay(w
, event
, region
)
222 SmeBSBObject entry
= (SmeBSBObject
) w
;
223 int font_ascent
, font_descent
, y_loc
;
225 entry
->sme_bsb
.set_values_area_cleared
= FALSE
;
226 font_ascent
= entry
->sme_bsb
.font
->max_bounds
.ascent
;
227 font_descent
= entry
->sme_bsb
.font
->max_bounds
.descent
;
229 y_loc
= entry
->rectangle
.y
;
231 if (XtIsSensitive(w
) && XtIsSensitive( XtParent(w
) ) ) {
232 if ( w
== XawSimpleMenuGetActiveEntry(XtParent(w
)) ) {
233 XFillRectangle(XtDisplayOfObject(w
), XtWindowOfObject(w
),
234 entry
->sme_bsb
.norm_gc
, 0, y_loc
,
235 (unsigned int) entry
->rectangle
.width
,
236 (unsigned int) entry
->rectangle
.height
);
237 gc
= entry
->sme_bsb
.rev_gc
;
240 gc
= entry
->sme_bsb
.norm_gc
;
243 gc
= entry
->sme_bsb
.norm_gray_gc
;
245 if (entry
->sme_bsb
.label
!= NULL
) {
246 int x_loc
= entry
->sme_bsb
.left_margin
;
247 int len
= strlen(entry
->sme_bsb
.label
);
248 char * label
= entry
->sme_bsb
.label
;
250 switch(entry
->sme_bsb
.justify
) {
253 case XtJustifyCenter
:
254 t_width
= XTextWidth(entry
->sme_bsb
.font
, label
, len
);
255 width
= entry
->rectangle
.width
- (entry
->sme_bsb
.left_margin
+
256 entry
->sme_bsb
.right_margin
);
257 x_loc
+= (width
- t_width
)/2;
260 t_width
= XTextWidth(entry
->sme_bsb
.font
, label
, len
);
261 x_loc
= entry
->rectangle
.width
- (entry
->sme_bsb
.right_margin
+
269 y_loc
+= (entry
->rectangle
.height
-
270 (font_ascent
+ font_descent
)) / 2 + font_ascent
;
272 XDrawString(XtDisplayOfObject(w
), XtWindowOfObject(w
), gc
,
273 x_loc
, y_loc
, label
, len
);
280 /* Function Name: SetValues
281 * Description: Relayout the menu when one of the resources is changed.
282 * Arguments: current - current state of the widget.
283 * request - what was requested.
284 * new - what the widget will become.
290 SetValues(current
, request
, new)
291 Widget current
, request
, new;
293 SmeBSBObject entry
= (SmeBSBObject
) new;
294 SmeBSBObject old_entry
= (SmeBSBObject
) current
;
295 Boolean ret_val
= FALSE
;
297 if (old_entry
->sme_bsb
.label
!= entry
->sme_bsb
.label
) {
298 if (old_entry
->sme_bsb
.label
!= XtName( new ) )
299 XtFree( (char *) old_entry
->sme_bsb
.label
);
301 if (entry
->sme_bsb
.label
!= XtName(new) )
302 entry
->sme_bsb
.label
= XtNewString( entry
->sme_bsb
.label
);
307 if (entry
->rectangle
.sensitive
!= old_entry
->rectangle
.sensitive
)
310 if (entry
->sme_bsb
.left_bitmap
!= old_entry
->sme_bsb
.left_bitmap
) {
311 GetBitmapInfo(new, TRUE
);
315 if (entry
->sme_bsb
.right_bitmap
!= old_entry
->sme_bsb
.right_bitmap
) {
316 GetBitmapInfo(new, FALSE
);
320 if ( (old_entry
->sme_bsb
.font
!= entry
->sme_bsb
.font
) ||
321 (old_entry
->sme_bsb
.foreground
!= entry
->sme_bsb
.foreground
) ) {
329 &(entry
->rectangle
.width
), &(entry
->rectangle
.height
));
330 entry
->sme_bsb
.set_values_area_cleared
= TRUE
;
335 /* Function Name: QueryGeometry.
336 * Description: Returns the preferred geometry for this widget.
337 * Arguments: w - the menu entry object.
338 * itended, return_val - the intended and return geometry info.
339 * Returns: A Geometry Result.
341 * See the Intrinsics manual for details on what this function is for.
343 * I just return the height and width of the label plus the margins.
346 static XtGeometryResult
347 QueryGeometry(w
, intended
, return_val
)
349 XtWidgetGeometry
*intended
, *return_val
;
351 SmeBSBObject entry
= (SmeBSBObject
) w
;
352 Dimension width
, height
;
353 XtGeometryResult ret_val
= XtGeometryYes
;
354 XtGeometryMask mode
= intended
->request_mode
;
356 GetDefaultSize(w
, &width
, &height
);
358 if ( ((mode
& CWWidth
) && (intended
->width
!= width
)) ||
359 !(mode
& CWWidth
) ) {
360 return_val
->request_mode
|= CWWidth
;
361 return_val
->width
= width
;
362 ret_val
= XtGeometryAlmost
;
365 if ( ((mode
& CWHeight
) && (intended
->height
!= height
)) ||
366 !(mode
& CWHeight
) ) {
367 return_val
->request_mode
|= CWHeight
;
368 return_val
->height
= height
;
369 ret_val
= XtGeometryAlmost
;
372 if (ret_val
== XtGeometryAlmost
) {
373 mode
= return_val
->request_mode
;
375 if ( ((mode
& CWWidth
) && (width
== entry
->rectangle
.width
)) &&
376 ((mode
& CWHeight
) && (height
== entry
->rectangle
.height
)) )
377 return(XtGeometryNo
);
383 /* Function Name: FlipColors
384 * Description: Invert the colors of the current entry.
385 * Arguments: w - the bsb menu entry widget.
393 SmeBSBObject entry
= (SmeBSBObject
) w
;
395 if (entry
->sme_bsb
.set_values_area_cleared
) return;
397 XFillRectangle(XtDisplayOfObject(w
), XtWindowOfObject(w
),
398 entry
->sme_bsb
.invert_gc
, 0, (int) entry
->rectangle
.y
,
399 (unsigned int) entry
->rectangle
.width
,
400 (unsigned int) entry
->rectangle
.height
);
403 /************************************************************
407 ************************************************************/
409 /* Function Name: GetDefaultSize
410 * Description: Calculates the Default (preferred) size of
412 * Arguments: w - the menu entry widget.
413 * width, height - default sizes (RETURNED).
418 GetDefaultSize(w
, width
, height
)
420 Dimension
* width
, * height
;
422 SmeBSBObject entry
= (SmeBSBObject
) w
;
424 if (entry
->sme_bsb
.label
== NULL
)
427 *width
= XTextWidth(entry
->sme_bsb
.font
, entry
->sme_bsb
.label
,
428 strlen(entry
->sme_bsb
.label
));
430 *width
+= entry
->sme_bsb
.left_margin
+ entry
->sme_bsb
.right_margin
;
432 *height
= (entry
->sme_bsb
.font
->max_bounds
.ascent
+
433 entry
->sme_bsb
.font
->max_bounds
.descent
);
435 *height
= (*height
* ( ONE_HUNDRED
+
436 entry
->sme_bsb
.vert_space
)) / ONE_HUNDRED
;
439 /* Function Name: DrawBitmaps
440 * Description: Draws left and right bitmaps.
441 * Arguments: w - the simple menu widget.
442 * gc - graphics context to use for drawing.
452 SmeBSBObject entry
= (SmeBSBObject
) w
;
454 if ( (entry
->sme_bsb
.left_bitmap
== None
) &&
455 (entry
->sme_bsb
.right_bitmap
== None
) ) return;
461 if (entry
->sme_bsb
.left_bitmap
!= None
) {
462 x_loc
= (entry
->sme_bsb
.left_margin
-
463 entry
->sme_bsb
.left_bitmap_width
) / 2;
465 y_loc
= entry
->rectangle
.y
+ (entry
->rectangle
.height
-
466 entry
->sme_bsb
.left_bitmap_height
) / 2;
468 XCopyPlane(XtDisplayOfObject(w
), entry
->sme_bsb
.left_bitmap
,
469 XtWindowOfObject(w
), gc
, 0, 0,
470 entry
->sme_bsb
.left_bitmap_width
,
471 entry
->sme_bsb
.left_bitmap_height
, x_loc
, y_loc
, 1);
479 if (entry
->sme_bsb
.right_bitmap
!= None
) {
480 x_loc
= entry
->rectangle
.width
- (entry
->sme_bsb
.right_margin
+
481 entry
->sme_bsb
.right_bitmap_width
) / 2;
483 y_loc
= entry
->rectangle
.y
+ (entry
->rectangle
.height
-
484 entry
->sme_bsb
.right_bitmap_height
) / 2;
486 XCopyPlane(XtDisplayOfObject(w
), entry
->sme_bsb
.right_bitmap
,
487 XtWindowOfObject(w
), gc
, 0, 0,
488 entry
->sme_bsb
.right_bitmap_width
,
489 entry
->sme_bsb
.right_bitmap_height
, x_loc
, y_loc
, 1);
493 /* Function Name: GetBitmapInfo
494 * Description: Gets the bitmap information from either of the bitmaps.
495 * Arguments: w - the bsb menu entry widget.
496 * is_left - TRUE if we are testing left bitmap,
497 * FALSE if we are testing the right bitmap.
502 GetBitmapInfo(w
, is_left
)
506 SmeBSBObject entry
= (SmeBSBObject
) w
;
507 unsigned int depth
, bw
;
510 unsigned int width
, height
;
514 if (entry
->sme_bsb
.left_bitmap
!= None
) {
515 if (!XGetGeometry(XtDisplayOfObject(w
),
516 entry
->sme_bsb
.left_bitmap
, &root
,
517 &x
, &y
, &width
, &height
, &bw
, &depth
)) {
518 sprintf(buf
, "SmeBSB Object: %s %s \"%s\".", "Could not",
519 "get Left Bitmap geometry information for menu entry ",
521 XtAppError(XtWidgetToApplicationContext(w
), buf
);
524 sprintf(buf
, "SmeBSB Object: %s \"%s\"%s.",
525 "Left Bitmap of entry ",
526 XtName(w
), " is not one bit deep.");
527 XtAppError(XtWidgetToApplicationContext(w
), buf
);
529 entry
->sme_bsb
.left_bitmap_width
= (Dimension
) width
;
530 entry
->sme_bsb
.left_bitmap_height
= (Dimension
) height
;
533 else if (entry
->sme_bsb
.right_bitmap
!= None
) {
534 if (!XGetGeometry(XtDisplayOfObject(w
),
535 entry
->sme_bsb
.right_bitmap
, &root
,
536 &x
, &y
, &width
, &height
, &bw
, &depth
)) {
537 sprintf(buf
, "SmeBSB Object: %s %s \"%s\".", "Could not",
538 "get Right Bitmap geometry information for menu entry ",
540 XtAppError(XtWidgetToApplicationContext(w
), buf
);
543 sprintf(buf
, "SmeBSB Object: %s \"%s\"%s.",
544 "Right Bitmap of entry ", XtName(w
),
545 " is not one bit deep.");
546 XtAppError(XtWidgetToApplicationContext(w
), buf
);
548 entry
->sme_bsb
.right_bitmap_width
= (Dimension
) width
;
549 entry
->sme_bsb
.right_bitmap_height
= (Dimension
) height
;
553 /* Function Name: CreateGCs
554 * Description: Creates all gc's for the simple menu widget.
555 * Arguments: w - the simple menu widget.
563 SmeBSBObject entry
= (SmeBSBObject
) w
;
567 values
.foreground
= XtParent(w
)->core
.background_pixel
;
568 values
.background
= entry
->sme_bsb
.foreground
;
569 values
.font
= entry
->sme_bsb
.font
->fid
;
570 values
.graphics_exposures
= FALSE
;
571 mask
= GCForeground
| GCBackground
| GCFont
| GCGraphicsExposures
;
572 entry
->sme_bsb
.rev_gc
= XtGetGC(w
, mask
, &values
);
574 values
.foreground
= entry
->sme_bsb
.foreground
;
575 values
.background
= XtParent(w
)->core
.background_pixel
;
576 entry
->sme_bsb
.norm_gc
= XtGetGC(w
, mask
, &values
);
578 values
.fill_style
= FillTiled
;
579 values
.tile
= XmuCreateStippledPixmap(XtScreenOfObject(w
),
580 entry
->sme_bsb
.foreground
,
581 XtParent(w
)->core
.background_pixel
,
582 XtParent(w
)->core
.depth
);
583 values
.graphics_exposures
= FALSE
;
584 mask
|= GCTile
| GCFillStyle
;
585 entry
->sme_bsb
.norm_gray_gc
= XtGetGC(w
, mask
, &values
);
587 values
.foreground
^= values
.background
;
588 values
.background
= 0;
589 values
.function
= GXxor
;
590 mask
= GCForeground
| GCBackground
| GCGraphicsExposures
| GCFunction
;
591 entry
->sme_bsb
.invert_gc
= XtGetGC(w
, mask
, &values
);
594 /* Function Name: DestroyGCs
595 * Description: Removes all gc's for the simple menu widget.
596 * Arguments: w - the simple menu widget.
604 SmeBSBObject entry
= (SmeBSBObject
) w
;
606 XtReleaseGC(w
, entry
->sme_bsb
.norm_gc
);
607 XtReleaseGC(w
, entry
->sme_bsb
.norm_gray_gc
);
608 XtReleaseGC(w
, entry
->sme_bsb
.rev_gc
);
609 XtReleaseGC(w
, entry
->sme_bsb
.invert_gc
);
615 * The apollo compiler that we have optomizes out my code for
616 * FlipColors() since it is static. and no one executes it in this
617 * file. I am setting the function pointer into the class structure so
618 * that it can be called by my parent who will tell me to when to
619 * highlight and unhighlight.
622 void _XawSmeBSBApolloHack ()