|
|
1.1 ! root 1: #ifndef lint ! 2: static char rcsid[] = "$Header: Label.c,v 1.25 87/09/13 22:09:43 newman Exp $"; ! 3: #endif lint ! 4: ! 5: /* ! 6: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. ! 7: * ! 8: * All Rights Reserved ! 9: * ! 10: * Permission to use, copy, modify, and distribute this software and its ! 11: * documentation for any purpose and without fee is hereby granted, ! 12: * provided that the above copyright notice appear in all copies and that ! 13: * both that copyright notice and this permission notice appear in ! 14: * supporting documentation, and that the name of Digital Equipment ! 15: * Corporation not be used in advertising or publicity pertaining to ! 16: * distribution of the software without specific, written prior permission. ! 17: * ! 18: * ! 19: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 20: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 21: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 22: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 23: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 24: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 25: * SOFTWARE. ! 26: */ ! 27: /* ! 28: * Label.c - Label widget ! 29: * ! 30: * Author: Charles Haynes ! 31: * Digital Equipment Corporation ! 32: * Western Research Laboratory ! 33: * Date: Sat Jan 24 1987 ! 34: * ! 35: * Converted to classing toolkit on Wed Aug 26 by Charles Haynes ! 36: */ ! 37: ! 38: #define XtStrlen(s) ((s) ? strlen(s) : 0) ! 39: ! 40: #include <stdio.h> ! 41: #include <string.h> ! 42: #include <ctype.h> ! 43: #include "Intrinsic.h" ! 44: #include "Label.h" ! 45: #include "LabelP.h" ! 46: #include "Atoms.h" ! 47: ! 48: /**************************************************************** ! 49: * ! 50: * Full class record constant ! 51: * ! 52: ****************************************************************/ ! 53: ! 54: /* Private Data */ ! 55: ! 56: #define XtRjustify "Justify" ! 57: ! 58: static XtResource resources[] = { ! 59: {XtNforeground, XtCForeground, XrmRPixel, sizeof(Pixel), ! 60: XtOffset(LabelWidget, label.foreground), XrmRString, "Black"}, ! 61: {XtNfont, XtCFont, XrmRFontStruct, sizeof(XFontStruct *), ! 62: XtOffset(LabelWidget, label.font),XrmRString, "Fixed"}, ! 63: {XtNlabel, XtCLabel, XrmRString, sizeof(String), ! 64: XtOffset(LabelWidget, label.label), XrmRString, NULL}, ! 65: {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify), ! 66: XtOffset(LabelWidget, label.justify), XrmRString, "Center"}, ! 67: {XtNinternalWidth, XtCWidth, XrmRInt, sizeof(Dimension), ! 68: XtOffset(LabelWidget, label.internal_width),XrmRString, "4"}, ! 69: {XtNinternalHeight, XtCHeight, XrmRInt, sizeof(Dimension), ! 70: XtOffset(LabelWidget, label.internal_height),XrmRString, "2"}, ! 71: }; ! 72: ! 73: static void Initialize(); ! 74: static void Realize(); ! 75: static void Resize(); ! 76: static void Redisplay(); ! 77: static Boolean SetValues(); ! 78: static void ClassInitialize(); ! 79: ! 80: LabelClassRec labelClassRec = { ! 81: { ! 82: /* core_class fields */ ! 83: /* superclass */ (WidgetClass) &widgetClassRec, ! 84: /* class_name */ "Label", ! 85: /* widget_size */ sizeof(LabelRec), ! 86: /* class_initialize */ ClassInitialize, ! 87: /* class_inited */ FALSE, ! 88: /* initialize */ Initialize, ! 89: /* realize */ Realize, ! 90: /* actions */ NULL, ! 91: /* num_actions */ 0, ! 92: /* resources */ resources, ! 93: /* num_resources */ XtNumber(resources), ! 94: /* xrm_class */ NULLQUARK, ! 95: /* compress_motion */ TRUE, ! 96: /* compress_exposure */ TRUE, ! 97: /* visible_interest */ FALSE, ! 98: /* destroy */ NULL, ! 99: /* resize */ Resize, ! 100: /* expose */ Redisplay, ! 101: /* set_values */ SetValues, ! 102: /* accept_focus */ NULL, ! 103: } ! 104: }; ! 105: WidgetClass labelWidgetClass = (WidgetClass)&labelClassRec; ! 106: /**************************************************************** ! 107: * ! 108: * Private Procedures ! 109: * ! 110: ****************************************************************/ ! 111: ! 112: static void CvtStringToJustify(); ! 113: ! 114: static XrmQuark XrmQEleft; ! 115: static XrmQuark XrmQEcenter; ! 116: static XrmQuark XrmQEright; ! 117: ! 118: static void ClassInitialize() ! 119: { ! 120: ! 121: XrmQEleft = XrmAtomToQuark("left"); ! 122: XrmQEcenter = XrmAtomToQuark("center"); ! 123: XrmQEright = XrmAtomToQuark("right"); ! 124: ! 125: XrmRegisterTypeConverter(XrmRString, XtRJustify, CvtStringToJustify); ! 126: } /* ClassInitialize */ ! 127: ! 128: /* ARGSUSED */ ! 129: static void CvtStringToJustify(display, fromVal, toVal) ! 130: Display *display; ! 131: XrmValue fromVal; ! 132: XrmValue *toVal; ! 133: { ! 134: static XtJustify e; ! 135: XrmQuark q; ! 136: char *s = (char *) fromVal.addr; ! 137: char lowerName[1000]; ! 138: int i; ! 139: ! 140: if (s == NULL) return; ! 141: ! 142: for (i=0; i<=strlen(s); i++) { ! 143: char c = s[i]; ! 144: lowerName[i] = isupper(c) ? (char) tolower(c) : c; ! 145: } ! 146: ! 147: q = XrmAtomToQuark(lowerName); ! 148: ! 149: (*toVal).size = sizeof(XtJustify); ! 150: (*toVal).addr = (caddr_t) &e; ! 151: ! 152: if (q == XrmQEleft) { e = XtJustifyLeft; return; } ! 153: if (q == XrmQEcenter) { e = XtJustifyCenter; return; } ! 154: if (q == XrmQEright) { e = XtJustifyRight; return; } ! 155: ! 156: (*toVal).size = 0; ! 157: (*toVal).addr = NULL; ! 158: }; ! 159: ! 160: /* ! 161: * Calculate width and height of displayed text in pixels ! 162: */ ! 163: ! 164: static void SetTextWidthAndHeight(lw) ! 165: LabelWidget lw; ! 166: { ! 167: register XFontStruct *fs = lw->label.font; ! 168: ! 169: lw->label.label_len = XtStrlen(lw->label.label); ! 170: lw->label.label_height = fs->max_bounds.ascent + fs->max_bounds.descent; ! 171: lw->label.label_width = XTextWidth( ! 172: fs, lw->label.label, (int) lw->label.label_len); ! 173: } ! 174: ! 175: static void GetnormalGC(lw) ! 176: LabelWidget lw; ! 177: { ! 178: XGCValues values; ! 179: ! 180: values.foreground = lw->label.foreground; ! 181: values.font = lw->label.font->fid; ! 182: ! 183: lw->label.normal_GC = XtGetGC( ! 184: (Widget)lw, ! 185: (unsigned) GCForeground | GCFont, ! 186: &values); ! 187: } ! 188: ! 189: static void GetgrayGC(lw) ! 190: LabelWidget lw; ! 191: { ! 192: XGCValues values; ! 193: ! 194: lw->label.gray_pixmap = XtGrayPixmap(XtScreen((Widget)lw)); ! 195: ! 196: values.foreground = lw->label.foreground; ! 197: values.font = lw->label.font->fid; ! 198: values.tile = lw->label.gray_pixmap; ! 199: values.fill_style = FillTiled; ! 200: ! 201: lw->label.gray_GC = XtGetGC( ! 202: (Widget)lw, ! 203: (unsigned) GCForeground | GCFont | GCTile | GCFillStyle, ! 204: &values); ! 205: } ! 206: ! 207: static void Initialize(request, new, args, num_args) ! 208: Widget request, new; ! 209: ArgList args; ! 210: Cardinal num_args; ! 211: { ! 212: LabelWidget lw = (LabelWidget) new; ! 213: ! 214: if (lw->label.label == NULL) { ! 215: unsigned int len = strlen(lw->core.name); ! 216: lw->label.label = XtMalloc(len+1); ! 217: (void) strcpy(lw->label.label, lw->core.name); ! 218: } ! 219: ! 220: GetnormalGC(lw); ! 221: GetgrayGC(lw); ! 222: ! 223: SetTextWidthAndHeight(lw); ! 224: ! 225: if (lw->core.width == 0) ! 226: lw->core.width = lw->label.label_width + 2 * lw->label.internal_width; ! 227: if (lw->core.height == 0) ! 228: lw->core.height = lw->label.label_height + 2*lw->label.internal_height; ! 229: ! 230: Resize((Widget)lw); ! 231: ! 232: lw->label.display_sensitive = FALSE; ! 233: ! 234: } /* Initialize */ ! 235: ! 236: ! 237: static void Realize(w, valueMask, attributes) ! 238: register Widget w; ! 239: Mask valueMask; ! 240: XSetWindowAttributes *attributes; ! 241: { ! 242: LabelWidget lw = (LabelWidget)w; ! 243: ! 244: valueMask |= CWBitGravity; ! 245: switch (((LabelWidget)w)->label.justify) { ! 246: case XtJustifyLeft: attributes->bit_gravity = WestGravity; break; ! 247: case XtJustifyCenter: attributes->bit_gravity = CenterGravity; break; ! 248: case XtJustifyRight: attributes->bit_gravity = EastGravity; break; ! 249: } ! 250: ! 251: if (!(w->core.sensitive)) ! 252: { ! 253: /* change border to gray */ ! 254: lw->core.border_pixmap = lw->label.gray_pixmap; ! 255: attributes->border_pixmap = lw->label.gray_pixmap; ! 256: valueMask |= CWBorderPixmap; ! 257: lw->label.display_sensitive = TRUE; ! 258: } ! 259: ! 260: ! 261: w->core.window = ! 262: XCreateWindow( ! 263: XtDisplay(w), w->core.parent->core.window, ! 264: w->core.x, w->core.y, ! 265: w->core.width, w->core.height, w->core.border_width, ! 266: (int) w->core.depth, ! 267: InputOutput, (Visual *)CopyFromParent, ! 268: valueMask, attributes); ! 269: } /* Realize */ ! 270: ! 271: ! 272: ! 273: /* ! 274: * Repaint the widget window ! 275: */ ! 276: ! 277: /* ARGSUSED */ ! 278: static void Redisplay(w, event) ! 279: Widget w; ! 280: XEvent *event; ! 281: { ! 282: LabelWidget lw = (LabelWidget) w; ! 283: ! 284: XDrawString( ! 285: XtDisplay(w), XtWindow(w), lw->label.normal_GC, ! 286: lw->label.label_x, lw->label.label_y, ! 287: lw->label.label, (int) lw->label.label_len); ! 288: } ! 289: ! 290: ! 291: static void Resize(w) ! 292: Widget w; ! 293: { ! 294: LabelWidget lw = (LabelWidget) w; ! 295: ! 296: switch (lw->label.justify) { ! 297: ! 298: case XtJustifyLeft : ! 299: lw->label.label_x = lw->label.internal_width; ! 300: break; ! 301: ! 302: case XtJustifyRight : ! 303: lw->label.label_x = lw->core.width - ! 304: (lw->label.label_width + lw->label.internal_width); ! 305: break; ! 306: ! 307: case XtJustifyCenter : ! 308: lw->label.label_x = (lw->core.width - lw->label.label_width) / 2; ! 309: break; ! 310: } ! 311: if (lw->label.label_x < 0) lw->label.label_x = 0; ! 312: lw->label.label_y = (lw->core.height - lw->label.label_height) / 2 ! 313: + lw->label.font->max_bounds.ascent; ! 314: } ! 315: ! 316: /* ! 317: * Set specified arguments into widget ! 318: */ ! 319: ! 320: static Boolean SetValues(current, request, new, last) ! 321: Widget current, request, new; ! 322: Boolean last; ! 323: { ! 324: LabelWidget curlw = (LabelWidget) current; ! 325: LabelWidget reqlw = (LabelWidget) request; ! 326: LabelWidget newlw = (LabelWidget) new; ! 327: XtWidgetGeometry reqGeo; ! 328: ! 329: if (newlw->label.label == NULL) { ! 330: /* the string will be copied below... */ ! 331: newlw->label.label = newlw->core.name; ! 332: } ! 333: ! 334: if ((curlw->label.label != newlw->label.label) ! 335: || (curlw->label.font != newlw->label.font) ! 336: || (curlw->label.justify != newlw->label.justify)) { ! 337: ! 338: SetTextWidthAndHeight(newlw); ! 339: ! 340: } ! 341: ! 342: /* note that there is no way to change the label and force the window */ ! 343: /* to keep it's current size (and possibly clip the text) perhaps we */ ! 344: /* should make the user set width and height to 0 when they set the */ ! 345: /* label if they want the label to recompute size based on the new */ ! 346: /* label? */ ! 347: if (curlw->label.label != newlw->label.label) { ! 348: if (newlw->label.label != NULL) { ! 349: newlw->label.label = strcpy( ! 350: XtMalloc((unsigned) newlw->label.label_len + 1), ! 351: newlw->label.label); ! 352: } ! 353: XtFree ((char *) curlw->label.label); ! 354: } ! 355: ! 356: /* calculate the window size */ ! 357: if (curlw->core.width == newlw->core.width) ! 358: newlw->core.width = ! 359: newlw->label.label_width +2*newlw->label.internal_width; ! 360: ! 361: if (curlw->core.height == newlw->core.height) ! 362: newlw->core.height = ! 363: newlw->label.label_height + 2*newlw->label.internal_height; ! 364: ! 365: reqGeo.request_mode = NULL; ! 366: ! 367: if (curlw->core.x != newlw->core.x) { ! 368: reqGeo.request_mode |= CWX; ! 369: reqGeo.x = newlw->core.x; ! 370: } ! 371: if (curlw->core.y != newlw->core.y) { ! 372: reqGeo.request_mode |= CWY; ! 373: reqGeo.y = newlw->core.y; ! 374: } ! 375: if (curlw->core.width != newlw->core.width) { ! 376: reqGeo.request_mode |= CWWidth; ! 377: reqGeo.width = newlw->core.width; ! 378: } ! 379: if (curlw->core.height != newlw->core.height) { ! 380: reqGeo.request_mode |= CWHeight; ! 381: reqGeo.height = newlw->core.height; ! 382: } ! 383: if (curlw->core.border_width != newlw->core.border_width) { ! 384: reqGeo.request_mode |= CWBorderWidth; ! 385: reqGeo.border_width = newlw->core.border_width; ! 386: } ! 387: ! 388: if (reqGeo.request_mode != NULL) { ! 389: if (XtMakeGeometryRequest( ! 390: (Widget)curlw, ! 391: &reqGeo, ! 392: (XtWidgetGeometry *)NULL) != XtGeometryYes) { ! 393: /* punt, undo requested change */ ! 394: newlw->core.x = curlw->core.x; ! 395: newlw->core.y = curlw->core.y; ! 396: newlw->core.width = curlw->core.width; ! 397: newlw->core.height = curlw->core.height; ! 398: newlw->core.border_width = curlw->core.border_width; ! 399: } ! 400: } ! 401: ! 402: if (newlw->core.depth != curlw->core.depth) { ! 403: XtWarning("SetValues: Attempt to change existing widget depth."); ! 404: newlw->core.depth = curlw->core.depth; ! 405: } ! 406: ! 407: if ((curlw->core.background_pixel != newlw->core.background_pixel) ! 408: || (curlw->core.border_pixel != newlw->core.border_pixel)) { ! 409: ! 410: Mask valueMask = 0; ! 411: XSetWindowAttributes attributes; ! 412: ! 413: if (curlw->core.background_pixel != newlw->core.background_pixel) { ! 414: valueMask |= CWBackPixel; ! 415: attributes.background_pixel = newlw->core.background_pixel; ! 416: } ! 417: if (curlw->core.border_pixel != newlw->core.border_pixel) { ! 418: valueMask |= CWBorderPixel; ! 419: attributes.border_pixel = newlw->core.border_pixel; ! 420: } ! 421: XChangeWindowAttributes( ! 422: XtDisplay(newlw), newlw->core.window, valueMask, &attributes); ! 423: } ! 424: ! 425: if (curlw->core.sensitive != newlw->core.sensitive) { ! 426: XtWarning("Setting Label sensitivity not implemented."); ! 427: } ! 428: ! 429: if (curlw->label.foreground != newlw->label.foreground ! 430: || curlw->label.font->fid != newlw->label.font->fid) { ! 431: ! 432: XtDestroyGC(curlw->label.normal_GC); ! 433: GetnormalGC(newlw); ! 434: GetgrayGC(newlw); ! 435: } ! 436: ! 437: if ((curlw->label.internal_width != newlw->label.internal_width) ! 438: || (curlw->label.internal_height != newlw->label.internal_height)) { ! 439: Resize((Widget)newlw); ! 440: } ! 441: ! 442: return( True ); /* want Redisplay */ ! 443: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.