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 <X11/Xos.h> /* Needed for string manipulation */
- #include <X11/IntrinsicP.h> /* Intrinsics header file */
- #include <X11/StringDefs.h> /* Resource string definitions */
- #include <X11/Xatom.h> /* For selection atoms */
- #include "LabelP.h" /* Label private header file */
-
- #define Offset(field) XtOffsetOf(LabelRec, 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},
- {XtNloseSelection, XtCLoseSelection, XtRCallback,
- sizeof(XtCallbackList), Offset(lose_selection),
- XtRCallback, (XtPointer) NULL},
- {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
- XtOffsetOf(LabelRec, core.border_width),
- XtRImmediate, (XtPointer) 0},
- };
- #undef Offset
-
- /* Forward declarations */
-
- static void ClassInitialize(), ClassPartInitialize(), Initialize(),
- Redisplay(), Destroy(), Resize(), LoseSelection();
- static Boolean SetValues(), SelectText();
- static XtGeometryResult QueryGeometry();
-
- /* Class record declaration */
-
- LabelClassRec labelClassRec = {
- /* Core class part */
- {
- /* superclass */ (WidgetClass) &widgetClassRec,
- /* class_name */ "Label",
- /* widget_size */ sizeof(LabelRec),
- /* class_initialize */ ClassInitialize,
- /* class_part_initialize */ ClassPartInitialize,
- /* class_inited */ FALSE,
- /* initialize */ Initialize,
- /* initialize_hook */ NULL,
- /* realize */ XtInheritRealize,
- /* actions */ NULL,
- /* num_actions */ 0,
- /* resources */ resources,
- /* num_resources */ XtNumber(resources),
- /* xrm_class */ NULLQUARK,
- /* compress_motion */ TRUE,
- /* compress_exposure */ XtExposeCompressMultiple,
- /* compress_enterleave */ TRUE,
- /* visible_interest */ FALSE,
- /* destroy */ Destroy,
- /* resize */ Resize,
- /* expose */ Redisplay,
- /* set_values */ SetValues,
- /* set_values_hook */ NULL,
- /* set_values_almost */ XtInheritSetValuesAlmost,
- /* get_values_hook */ NULL,
- /* accept_focus */ NULL,
- /* version */ XtVersion,
- /* callback offsets */ NULL,
- /* tm_table */ NULL,
- /* query_geometry */ QueryGeometry,
- /* display_accelerator */ NULL,
- /* extension */ NULL
- },
- /* Label class part */
- {
- /* select */ SelectText,
- /* extension */ NULL
- }
- };
-
- /* Class record pointer */
-
- WidgetClass labelWidgetClass = (WidgetClass) &labelClassRec;
-
- static Boolean LowerCase(from, to, size)
- register String from, to;
- int size;
- {
- register char ch;
- register int i;
-
- for (i = 0; i < size; i++) {
- ch = from[i];
- if (ch >= 'A' && ch <= 'Z') to[i] = ch - 'A' + 'a';
- else to[i] = ch;
- if (ch == '\0') return FALSE;
- }
- return TRUE;
- }
-
- Boolean CvtStringToJustify(dpy, args, num_args, from, to, data)
- Display *dpy;
- XrmValuePtr args;
- Cardinal *num_args;
- XrmValuePtr from, to;
- XtPointer *data;
- {
- #define LOWER_SIZE 10
- char lower[LOWER_SIZE]; /* Lower cased string value */
- register int i;
- Boolean badConvert;
- static Justify j;
-
- if (*num_args != 0) { /* Check for correct number */
- XtAppErrorMsg(XtDisplayToApplicationContext(dpy),
- "cvtStringToJustify", "wrongParameters",
- "XtToolkitError",
- "String to justify conversion needs no extra arguments",
- (String *) NULL, (Cardinal *) NULL);
- }
-
- /* Lower case the value */
- badConvert = LowerCase(from->addr, lower, LOWER_SIZE);
-
- /* Try to convert if a short enough string specified */
- if (!badConvert) {
- if (strcmp(lower, "left") == 0) j = Left;
- else if (strcmp(lower, "center") == 0) j = Center;
- else if (strcmp(lower, "right") == 0) j = Right;
- else badConvert = TRUE;
- }
-
- /* String too long or unknown value -- issue warning */
- if (badConvert) {
- XtDisplayStringConversionWarning(dpy, from->addr, "Justify");
- } else {
- if (to->addr == NULL) to->addr = (caddr_t) &j;
- else if (to->size < sizeof(Justify)) badConvert = TRUE;
- else *(Justify *) to->addr = j;
-
- to->size = sizeof(Justify);
- }
- return !badConvert;
- #undef LOWER_SIZE
- }
-
- #if 0
- Boolean CvtStringToJustify(dpy, args, num_args, from, to, data)
- Display *dpy;
- XrmValuePtr args;
- Cardinal *num_args;
- XrmValuePtr from, to;
- XtPointer *data;
- {
- #define LOWER_SIZE 10
- char lower[LOWER_SIZE]; /* Lower cased string value */
- register int i;
- Boolean badConvert;
- XrmQuark q;
- static Justify j;
- static XrmQuark Qleft, Qcenter, Qright;
- static Boolean haveQuarks = FALSE;
-
- if (*num_args != 0) { /* Check for correct number */
- XtAppErrorMsg(XtDisplayToApplicationContext(dpy),
- "cvtStringToJustify", "wrongParameters",
- "XtToolkitError",
- "String to justify conversion needs no extra arguments",
- (String *) NULL, (Cardinal *) NULL);
- }
-
- if (!haveQuarks) {
- Qleft = XrmStringToQuark("left");
- Qcenter = XrmStringToQuark("center");
- Qright = XrmStringToQuark("right");
- haveQuarks = TRUE;
- }
-
- badConvert = LowerCase(from->addr, lower, LOWER_SIZE);
-
- /* Try to convert if a short enough string specified */
-
- if (!badConvert) {
- q = XrmStringToQuark(lower);
- if (q == Qleft) j = Left;
- else if (q == Qcenter) j = Center;
- else if (q == Qright) j = Right;
- else badConvert = TRUE;
- }
-
- /* String too long or unknown value -- issue warning */
-
- if (badConvert) {
- XtDisplayStringConversionWarning(dpy, from->addr, "Justify");
- } else {
- if (to->addr == NULL) to->addr = (caddr_t) &j;
- else if (to->size < sizeof(Justify)) badConvert = TRUE;
- else *(Justify *) to->addr = j;
-
- to->size = sizeof(Justify);
- }
- return !badConvert;
- #undef LOWER_SIZE
- }
- #endif
-
- static Atom FetchAtom(w, name)
- Widget w;
- String name;
- {
- Atom a;
- XrmValue source, dest;
-
- source.size = strlen(name)+1;
- source.addr = name;
- dest.size = sizeof(Atom);
- dest.addr = (caddr_t) &a;
-
- (void) XtConvertAndStore(w, XtRString, &source, XtRAtom, &dest);
- return a;
- }
-
- static Boolean DeliverSelection(w, selection, target,
- type, value, length, format)
- Widget w;
- Atom *selection, *target, *type;
- XtPointer *value;
- unsigned long *length;
- int *format;
- {
- LabelWidget lw = (LabelWidget) w;
- static Atom targets = 0;
-
- if (targets == 0) {
- targets = FetchAtom(w, "TARGETS");
- }
-
- if (*target == targets) {
- *type = XA_ATOM;
- *value = (XtPointer) XtNew(Atom);
- *(Atom *) *value = XA_STRING;
- *length = 1;
- *format = 32;
- return TRUE;
- }
-
- if (*target == XA_STRING) {
- *type = XA_STRING;
- *value = (XtPointer) XtNewString(lw->label.label);
- *length = lw->label.label_len;
- *format = 8;
- return TRUE;
- }
-
- return FALSE;
- }
-
- static void LoseSelection(w, selection)
- Widget w;
- Atom *selection;
- {
- LabelWidget lw = (LabelWidget) w;
-
- XtCallCallbackList(lw, lw->label.lose_selection,
- (XtPointer) selection);
- }
-
- /* Label's select implementation */
-
- static Boolean SelectText(w, selection, own)
- Widget w;
- Atom selection;
- Boolean own;
- {
- LabelWidget lw = (LabelWidget) w;
-
- if (own) {
- return XtOwnSelection(w, selection,
- XtLastTimestampProcessed(XtDisplay(w)),
- DeliverSelection, LoseSelection,
- (XtSelectionDoneProc) NULL);
- } else {
- XtDisownSelection(w, selection,
- XtLastTimestampProcessed(XtDisplay(w)));
- return TRUE;
- }
- }
-
- Boolean LabelSelectText(w, selection, own)
- Widget w;
- Atom selection;
- Boolean own;
- {
- /* Check that we're in Label or a subclass */
-
- XtCheckSubclass(w, labelWidgetClass, NULL);
-
- /* Call the class method */
-
- return (*((LabelWidgetClass) XtClass(w))->label_class.select)
- (w, selection, own);
- }
-
- static void ClassInitialize()
- {
- /* Register a converter for string to justification */
-
- XtSetTypeConverter(XtRString, XtRJustify, CvtStringToJustify,
- (XtConvertArgList) NULL, 0,
- XtCacheAll, (XtDestructor) NULL);
- }
-
- static void ClassPartInitialize(widget_class)
- WidgetClass widget_class;
- {
- register LabelWidgetClass wc = (LabelWidgetClass) widget_class;
- LabelWidgetClass super =
- (LabelWidgetClass) wc->core_class.superclass;
-
- if (wc->label_class.select == InheritSelectText) {
- wc->label_class.select = super->label_class.select;
- }
- }
-
- static void SetTextWidthAndHeight(lw)
- register LabelWidget lw;
- {
- register XFontStruct *fs = lw->label.font;
- int accel_len;
-
- 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;
-
- if (lw->label.accel_string != NULL) {
- accel_len = strlen(lw->label.accel_string);
- lw->label.label_len += accel_len;
- lw->label.label_width +=
- XTextWidth(fs, lw->label.accel_string, accel_len);
- }
- }
-
- static GC GetNormalGC(lw)
- LabelWidget 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 void Initialize(request, new, args, num_args)
- Widget request, new;
- ArgList args;
- Cardinal *num_args;
- {
- LabelWidget lw = (LabelWidget) new;
-
- /* If no label is specified, use the name */
- if (lw->label.label == NULL) lw->label.label = lw->core.name;
-
- /* Copy the label */
- lw->label.label = XtNewString(lw->label.label);
-
- /* Clear accelerator string */
- lw->label.accel_string = NULL;
-
- /* Compute the text dimensions and get a graphics context. */
- SetTextWidthAndHeight(lw);
- lw->label.gc = lw->label.current_gc = GetNormalGC(lw);
-
- /* If no size specified, compute one */
- lw->label.size_computed =
- (lw->core.width == 0) && (lw->core.height == 0);
-
- if (lw->core.width == 0) {
- lw->core.width = lw->label.label_width + 2 * lw->label.space;
- }
- if (lw->core.height == 0) {
- lw->core.height = lw->label.label_height + 2 * lw->label.space;
- }
-
- lw->label.desired_width = lw->core.width;
- lw->label.desired_height = lw->core.height;
- }
-
- static Boolean SetValues(old, request, new, args, num_args)
- Widget old, request, new;
- ArgList args;
- Cardinal *num_args;
- {
- LabelWidget oldlw = (LabelWidget) old;
- LabelWidget newlw = (LabelWidget) 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 = newlw->core.name;
- }
-
- /* Decide whether to compute the size */
-
- if (newlw->core.width == 0 && newlw->core.height == 0) {
- newlw->label.size_computed = TRUE;
- } else if (NE(core.width) || NE(core.height)) {
- newlw->label.size_computed = FALSE;
- if (NE(core.width)) {
- newlw->label.desired_width = newlw->core.width;
- }
- if (NE(core.height)) {
- newlw->label.desired_height = newlw->core.height;
- }
- } /* else leave the same */
-
- /* If label, font, or accelerator string has changed,
- compute size and recopy */
-
- if (NE(label.label) || NE(label.font) || NE(label.accel_string)) {
- SetTextWidthAndHeight(newlw);
- redisplay = TRUE;
-
- if (NE(label.label)) {
- XtFree((char *) oldlw->label.label);
- newlw->label.label = XtNewString(newlw->label.label);
- }
-
- if (NE(label.accel_string)) {
- XtFree((char *) oldlw->label.accel_string);
- newlw->label.accel_string =
- XtNewString(newlw->label.accel_string);
- }
- }
-
- /* Compute the size if necessary */
-
- if ((newlw->label.size_computed && redisplay) ||
- newlw->core.width == 0) {
- newlw->label.desired_width = newlw->core.width =
- newlw->label.label_width + 2 * newlw->label.space;
- }
- if ((newlw->label.size_computed && redisplay) ||
- newlw->core.height == 0) {
- newlw->label.desired_height = newlw->core.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;
- }
- }
-
- return redisplay || NE(label.space) || NE(label.justify);
- #undef NE
- }
-
- static void Destroy(w)
- Widget w;
- {
- LabelWidget lw = (LabelWidget) w;
-
- XtFree((char *) lw->label.label);
- XtReleaseGC(w, lw->label.gc);
- }
-
- static void Redisplay(w, event, region)
- Widget w;
- XEvent *event;
- Region region;
- {
- LabelWidget lw = (LabelWidget) w;
- char *string;
- Boolean allocated = FALSE;
- int x;
-
- if (lw->label.accel_string == NULL) {
- string = lw->label.label;
- } else {
- string = XtMalloc(lw->label.label_len + 1);
- (void) strcpy(string, lw->label.label);
- (void) strcat(string, lw->label.accel_string);
- allocated = TRUE;
- }
-
- switch (lw->label.justify) {
- case Left:
- x = lw->label.space;
- break;
- case Right:
- x = (int) lw->core.width - (int) lw->label.space -
- (int) lw->label.label_width;
- break;
- case Center:
- x = ((int) lw->core.width -
- (int) lw->label.label_width) / 2;
- break;
- }
-
- XDrawString(XtDisplay(w), XtWindow(w), lw->label.current_gc,
- x, lw->label.space + lw->label.font->max_bounds.ascent,
- string, lw->label.label_len);
-
- if (allocated) XtFree(string);
- }
-
- static void Resize(w)
- Widget w;
- {
- /* If widget is realized, clear and redisplay */
-
- if (XtIsRealized(w)) {
- XClearWindow(XtDisplay(w), XtWindow(w));
- (*(XtClass(w)->core_class.expose))(w,
- (XEvent *) NULL, (Region) NULL);
- }
- }
-
- static XtGeometryResult QueryGeometry(w, proposed, desired)
- Widget w;
- XtWidgetGeometry *proposed, *desired;
- {
- LabelWidget lw = (LabelWidget) 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->core.width &&
- desired->height == lw->core.height) {
- return XtGeometryNo;
- }
- return XtGeometryAlmost;
- #undef Set
- }
-