home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- Copyright 1990 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute these examples for any
- purpose and without fee is hereby granted, provided that the above
- copyright notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting documentation,
- and that the name of Digital not be used in advertising or publicity
- pertaining to distribution of the software without specific, written
- prior permission.
-
- DIGITAL AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT
- OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
- OR PERFORMANCE OF THIS SOFTWARE.
-
- ******************************************************************/
-
- #include <string.h> /* Needed for string manipulation */
- #include <X11/IntrinsicP.h> /* Intrinsics header file */
- #include <X11/StringDefs.h> /* Resource string definitions */
- #include "LabelGadgP.h" /* LabelGadget private header file */
-
- #define Offset(field) XtOffsetOf(LabelGadgetRec, label.field)
-
- static XtResource resources[] = {
- {XtNlabel, XtCLabel, XtRString, sizeof(String),
- Offset(label), XtRString, (XtPointer) NULL},
- {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
- Offset(font), XtRString, (XtPointer) XtDefaultFont},
- {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
- Offset(foreground), XtRString,
- (XtPointer) XtDefaultForeground},
- {XtNjustify, XtCJustify, XtRJustify, sizeof(Justify),
- Offset(justify), XtRImmediate, (XtPointer) Left},
- {XtNspace, XtCSpace, XtRDimension, sizeof(Dimension),
- Offset(space), XtRImmediate, (XtPointer) 2},
- {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
- XtOffsetOf(LabelGadgetRec, rectObj.border_width),
- XtRImmediate, (XtPointer) 0},
- {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
- Offset(background), XtRString,
- (XtPointer) XtDefaultBackground},
- {XtNborderColor, XtCBorderColor, XtRPixel, sizeof(Pixel),
- Offset(border), XtRString, (XtPointer) XtDefaultForeground},
- };
- #undef Offset
-
- /* Forward declarations */
-
- static void ClassInitialize(), Initialize(),
- Redisplay(), Destroy(), Resize();
- static Boolean SetValues();
- static XtGeometryResult QueryGeometry();
-
- /* Class record declaration */
-
- LabelGadgetClassRec labelGadgetClassRec = {
- /* RectObj class part */
- {
- /* superclass */ (WidgetClass) &rectObjClassRec,
- /* class_name */ "LabelGadget",
- /* widget_size */ sizeof(LabelGadgetRec),
- /* class_initialize */ ClassInitialize,
- /* class_part_initialize */ NULL,
- /* class_inited */ FALSE,
- /* initialize */ Initialize,
- /* initialize_hook */ NULL,
- /* rect1 */ NULL,
- /* rect2 */ NULL,
- /* rect3 */ 0,
- /* resources */ resources,
- /* num_resources */ XtNumber(resources),
- /* xrm_class */ NULLQUARK,
- /* rect4 */ 0,
- /* rect5 */ 0,
- /* rect6 */ 0,
- /* rect7 */ 0,
- /* destroy */ Destroy,
- /* resize */ Resize,
- /* expose */ Redisplay,
- /* set_values */ SetValues,
- /* set_values_hook */ NULL,
- /* set_values_almost */ XtInheritSetValuesAlmost,
- /* get_values_hook */ NULL,
- /* rect9 */ NULL,
- /* version */ XtVersion,
- /* callback offsets */ NULL,
- /* rect10 */ NULL,
- /* query_geometry */ QueryGeometry,
- /* rect11 */ NULL,
- /* extension */ NULL
- },
- /* LabelGadget class part */
- {
- /* extension */ NULL
- }
- };
-
- /* Class record pointer */
-
- WidgetClass labelGadgetClass = (WidgetClass) &labelGadgetClassRec;
-
- static void ClassInitialize()
- {
- extern void CvtStringToJustify(); /* Defined in Label.c */
-
- /* Register a converter for string to justification */
-
- XtSetTypeConverter(XtRString, XtRJustify, CvtStringToJustify,
- (XtConvertArgList) NULL, 0,
- XtCacheAll, (XtDestructor) NULL);
- }
-
- static void SetTextWidthAndHeight(lw)
- LabelGadget lw;
- {
- register XFontStruct *fs = lw->label.font;
-
- /* Compute the text dimensions based on the string and the font */
-
- lw->label.label_len = strlen(lw->label.label);
- lw->label.label_width =
- XTextWidth(fs, lw->label.label, lw->label.label_len);
- lw->label.label_height =
- fs->max_bounds.ascent + fs->max_bounds.descent;
- }
-
- static GC GetNormalGC(lw)
- LabelGadget lw;
- {
- XGCValues values;
-
- /* Allocate a graphics context with the foreground and font */
-
- values.foreground = lw->label.foreground;
- values.font = lw->label.font->fid;
- return XtGetGC((Widget) lw, GCForeground | GCFont, &values);
- }
-
- static GC GetBackgroundGC(lw)
- LabelGadget lw;
- {
- XGCValues values;
-
- /* Allocate a graphics context with the background */
-
- values.foreground = lw->label.background;
- return XtGetGC((Widget) lw, GCForeground, &values);
- }
-
- static GC GetBorderGC(lw)
- LabelGadget lw;
- {
- XGCValues values;
-
- if (lw->rectObj.border_width == 0) return NULL;
-
- /* Allocate a graphics context with the border values */
-
- values.foreground = lw->label.border;
- values.line_width = lw->rectObj.border_width;
- return XtGetGC((Widget) lw, GCForeground | GCLineWidth, &values);
- }
-
- static void Initialize(request, new, args, num_args)
- Widget request, new;
- ArgList args;
- Cardinal *num_args;
- {
- LabelGadget lw = (LabelGadget) new;
-
- /* If no label is specified, use the name */
- if (lw->label.label == NULL) lw->label.label = XtName(lw);
-
- /* Copy the label */
- lw->label.label = XtNewString(lw->label.label);
-
- /* Compute the text dimensions and get graphics contexts. */
- SetTextWidthAndHeight(lw);
- lw->label.gc = lw->label.current_gc = GetNormalGC(lw);
- lw->label.background_gc =
- lw->label.current_bg_gc = GetBackgroundGC(lw);
- lw->label.border_gc = GetBorderGC(lw);
-
- /* If no size specified, compute one */
- lw->label.size_computed =
- (lw->rectObj.width == 0) && (lw->rectObj.height == 0);
-
- if (lw->rectObj.width == 0) {
- lw->rectObj.width = lw->label.label_width +
- 2 * lw->label.space;
- }
- if (lw->rectObj.height == 0) {
- lw->rectObj.height = lw->label.label_height +
- 2 * lw->label.space;
- }
-
- lw->label.old_border = lw->rectObj.border_width;
-
- lw->label.desired_width = lw->rectObj.width;
- lw->label.desired_height = lw->rectObj.height;
- }
-
- static Boolean SetValues(old, request, new, args, num_args)
- Widget old, request, new;
- ArgList args;
- Cardinal *num_args;
- {
- LabelGadget oldlw = (LabelGadget) old;
- LabelGadget newlw = (LabelGadget) new;
- Boolean redisplay = FALSE;
-
- #define NE(field) (oldlw->field != newlw->field)
-
- /* If the label has been reset to NULL, change to the name */
-
- if (newlw->label.label == NULL) {
- newlw->label.label = XtName(newlw);
- }
-
- /* Decide whether to compute the size */
-
- if (newlw->rectObj.width == 0 && newlw->rectObj.height == 0) {
- newlw->label.size_computed = TRUE;
- } else if (NE(rectObj.width) || NE(rectObj.height)) {
- newlw->label.size_computed = FALSE;
- if (NE(rectObj.width)) {
- newlw->label.desired_width = newlw->rectObj.width;
- }
- if (NE(rectObj.height)) {
- newlw->label.desired_height = newlw->rectObj.height;
- }
- } /* else leave the same */
-
- /* If label, or font has changed, recopy and compute size */
-
- if (NE(label.label) || NE(label.font)) {
- if (NE(label.label)) {
- XtFree((char *) oldlw->label.label);
- newlw->label.label = XtNewString(newlw->label.label);
- }
- SetTextWidthAndHeight(newlw);
- redisplay = TRUE;
- }
-
- /* Compute the size if necessary */
-
- if (newlw->label.size_computed || newlw->rectObj.width == 0) {
- newlw->label.desired_width = newlw->rectObj.width =
- newlw->label.label_width + 2 * newlw->label.space;
- }
- if (newlw->label.size_computed || newlw->rectObj.height == 0) {
- newlw->label.desired_height = newlw->rectObj.height =
- newlw->label.label_height + 2 * newlw->label.space;
- }
-
- /* If foreground or font has changed, update GC */
-
- if (NE(label.foreground) || NE(label.font->fid)) {
- XtReleaseGC(newlw, oldlw->label.gc);
- newlw->label.gc = GetNormalGC(newlw);
-
- if (newlw->label.current_gc == oldlw->label.gc) {
- newlw->label.current_gc = newlw->label.gc;
- redisplay = TRUE;
- }
- }
-
- /* If background has changed, update background GC */
-
- if (NE(label.background)) {
- XtReleaseGC(newlw, oldlw->label.background_gc);
- newlw->label.background_gc = GetBackgroundGC(newlw);
-
- if (newlw->label.current_bg_gc == oldlw->label.background_gc) {
- newlw->label.current_bg_gc = newlw->label.background_gc;
- redisplay = TRUE;
- }
- }
-
- /* If border has changed, update border GC */
-
- if (NE(label.border) || NE(rectObj.border_width)) {
- if (oldlw->label.border_gc != NULL) {
- XtReleaseGC(newlw, oldlw->label.border_gc);
- }
- newlw->label.border_gc = GetBorderGC(newlw);
- redisplay = TRUE;
- }
-
- return redisplay || NE(label.space) || NE(label.justify);
- #undef NE
- }
-
- static void Destroy(w)
- Widget w;
- {
- LabelGadget lw = (LabelGadget) w;
-
- XtFree((char *) lw->label.label);
-
- XtReleaseGC(w, lw->label.gc);
- XtReleaseGC(w, lw->label.background_gc);
- if (lw->label.border_gc != NULL) {
- XtReleaseGC(w, lw->label.border_gc);
- }
- }
-
- static void Redisplay(w, event, region)
- Widget w;
- XEvent *event;
- Region region;
- {
- LabelGadget lw = (LabelGadget) w;
- int offset, x;
- XRectangle rect;
- Region r1, r2;
-
- /* Draw the background */
- XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
- lw->label.current_bg_gc,
- lw->rectObj.x + lw->rectObj.border_width,
- lw->rectObj.y + lw->rectObj.border_width,
- lw->rectObj.width, lw->rectObj.height);
-
- /* Draw the border */
- if (lw->rectObj.border_width != 0) {
- offset = lw->rectObj.border_width / 2;
- XDrawRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
- lw->label.border_gc,
- lw->rectObj.x + offset, lw->rectObj.y + offset,
- lw->rectObj.width + lw->rectObj.border_width,
- lw->rectObj.height + lw->rectObj.border_width);
- }
-
- switch (lw->label.justify) {
- case Left:
- x = lw->label.space;
- break;
- case Right:
- x = (int) lw->rectObj.width - (int) lw->label.space -
- (int) lw->label.label_width;
- break;
- case Center:
- x = ((int) lw->rectObj.width -
- (int) lw->label.label_width) / 2;
- break;
- }
-
- /* Temporarily change the clip mask in the gc */
- rect.x = lw->rectObj.x + lw->rectObj.border_width;
- rect.y = lw->rectObj.y + lw->rectObj.border_width;
- rect.width = lw->rectObj.width;
- rect.height = lw->rectObj.height;
-
- r1 = XCreateRegion();
- r2 = XCreateRegion();
- if (region != NULL) {
- XUnionRectWithRegion(&rect, r1, r2); /* r2 = rectangle */
- XIntersectRegion(region, r2, r1); /* r1 = intersection */
- } else XUnionRectWithRegion(&rect, r2, r1); /* r1 = rectangle */
-
- XSetRegion(XtDisplayOfObject(w), lw->label.current_gc, r1);
- XDestroyRegion(r1);
- XDestroyRegion(r2);
-
- XDrawString(XtDisplayOfObject(w), XtWindowOfObject(w),
- lw->label.current_gc,
- lw->rectObj.x + lw->rectObj.border_width + x,
- lw->rectObj.y + lw->rectObj.border_width +
- lw->label.space + lw->label.font->max_bounds.ascent,
- lw->label.label, lw->label.label_len);
-
- /* Restore the GC */
- XSetClipMask(XtDisplayOfObject(w), lw->label.current_gc, None);
- }
-
- static void Resize(w)
- Widget w;
- {
- LabelGadget lw = (LabelGadget) w;
-
- /* If border width changed, update border GC */
-
- if (lw->label.old_border != lw->rectObj.border_width) {
- if (lw->label.border_gc != NULL) {
- XtReleaseGC(w, lw->label.border_gc);
- }
- lw->label.border_gc = GetBorderGC(lw);
- lw->label.old_border = lw->rectObj.border_width;
- }
- }
-
- static XtGeometryResult QueryGeometry(w, proposed, desired)
- Widget w;
- XtWidgetGeometry *proposed, *desired;
- {
- LabelGadget lw = (LabelGadget) w;
- #define Set(bit) (proposed->request_mode & bit)
-
- desired->width = lw->label.desired_width;
- desired->height = lw->label.desired_height;
- desired->request_mode = CWWidth | CWHeight;
-
- if (Set(CWWidth) && proposed->width == desired->width &&
- Set(CWHeight) && proposed->height == desired->height) {
- return XtGeometryYes;
- }
-
- if (desired->width == lw->rectObj.width &&
- desired->height == lw->rectObj.height) {
- return XtGeometryNo;
- }
- return XtGeometryAlmost;
- #undef Set
- }
-