|
|
1.1 ! root 1: /* $Header: Label.c,v 1.2 87/09/12 12:43:01 swick Exp $ */ ! 2: #ifndef lint ! 3: static char *sccsid = "@(#)Label.c 1.15 2/25/87"; ! 4: #endif lint ! 5: ! 6: /* ! 7: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. ! 8: * ! 9: * All Rights Reserved ! 10: * ! 11: * Permission to use, copy, modify, and distribute this software and its ! 12: * documentation for any purpose and without fee is hereby granted, ! 13: * provided that the above copyright notice appear in all copies and that ! 14: * both that copyright notice and this permission notice appear in ! 15: * supporting documentation, and that the name of Digital Equipment ! 16: * Corporation not be used in advertising or publicity pertaining to ! 17: * distribution of the software without specific, written prior permission. ! 18: * ! 19: * ! 20: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 21: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 22: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 23: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 24: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 25: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 26: * SOFTWARE. ! 27: */ ! 28: ! 29: ! 30: #include <stdio.h> ! 31: #include <strings.h> ! 32: #include "Xlib.h" ! 33: #include "Intrinsic.h" ! 34: #include "Label.h" ! 35: #include "Atoms.h" ! 36: ! 37: /* Private Definitions */ ! 38: ! 39: ! 40: typedef struct { ! 41: Display *dpy; /* widget display connection */ ! 42: Window window; /* widget window */ ! 43: Dimension borderWidth; /* border width in pixels */ ! 44: Dimension width; /* window width in pixels */ ! 45: Dimension height; /* window height in pixels */ ! 46: Dimension internalWidth; /* internal border width in pixels */ ! 47: Dimension internalHeight; /* internal border height in pixels */ ! 48: String label; /* button text to display */ ! 49: int labelLength; /* number of non-NULL chars in label */ ! 50: Pixel foreground; ! 51: Pixel background; ! 52: Pixel border; ! 53: XFontStruct *fontStruct; /* label font */ ! 54: Dimension labelWidth; /* label width in pixels */ ! 55: Dimension labelHeight; /* label height in pixels */ ! 56: XtJustify justify; /* left, right, or center */ ! 57: GC gc; /* pointer to GraphicsContext */ ! 58: } WidgetDataRec, *WidgetData; ! 59: ! 60: static WidgetDataRec globaldata; ! 61: ! 62: ! 63: /* Private Data */ ! 64: ! 65: static caddr_t defNULL = (caddr_t) NULL; ! 66: static Dimension defBorderWidth = 1; ! 67: static Dimension defInternalWidth = 4; ! 68: static Dimension defInternalHeight = 2; ! 69: static XFontStruct *defFontStruct; ! 70: static XtJustify defJustify = XtjustifyCenter; ! 71: ! 72: static Resource resources[] = { ! 73: {XtNwindow, XtCWindow, XrmRWindow, sizeof(Window), ! 74: (caddr_t) &globaldata.window, (caddr_t) &defNULL}, ! 75: {XtNborderWidth, XtCBorderWidth, XrmRInt, sizeof(Dimension), ! 76: (caddr_t) &globaldata.borderWidth, (caddr_t) &defBorderWidth}, ! 77: {XtNwidth, XtCWidth, XrmRInt, sizeof(Dimension), ! 78: (caddr_t) &globaldata.width, (caddr_t) &defNULL}, ! 79: {XtNheight, XtCHeight, XrmRInt, sizeof(Dimension), ! 80: (caddr_t) &globaldata.height, (caddr_t) &defNULL}, ! 81: {XtNinternalWidth, XtCWidth, XrmRInt, sizeof(Dimension), ! 82: (caddr_t) &globaldata.internalWidth, (caddr_t) &defInternalWidth}, ! 83: {XtNinternalHeight, XtCHeight, XrmRInt, sizeof(Dimension), ! 84: (caddr_t) &globaldata.internalHeight, (caddr_t) &defInternalHeight}, ! 85: {XtNlabel, XtCLabel, XrmRString, sizeof(String), ! 86: (caddr_t) &globaldata.label, (caddr_t) &defNULL}, ! 87: {XtNforeground, XtCColor, XrmRPixel, sizeof(Pixel), ! 88: (caddr_t) &globaldata.foreground, (caddr_t) &XtDefaultFGPixel}, ! 89: {XtNbackground, XtCColor, XrmRPixel, sizeof(Pixel), ! 90: (caddr_t) &globaldata.background, (caddr_t) &XtDefaultBGPixel}, ! 91: {XtNborder, XtCColor, XrmRPixel, sizeof(Pixel), ! 92: (caddr_t) &globaldata.border, (caddr_t) &XtDefaultFGPixel}, ! 93: {XtNfont, XtCFont, XrmRFontStruct, sizeof(XFontStruct *), ! 94: (caddr_t) &globaldata.fontStruct, (caddr_t) &defFontStruct}, ! 95: {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify), ! 96: (caddr_t) &globaldata.justify, (caddr_t) &defJustify}, ! 97: }; ! 98: ! 99: ! 100: /**************************************************************** ! 101: * ! 102: * Private Procedures ! 103: * ! 104: ****************************************************************/ ! 105: ! 106: static Boolean initialized = FALSE; ! 107: ! 108: static XContext widgetContext; ! 109: ! 110: static void LabelInitialize(dpy) ! 111: Display *dpy; ! 112: { ! 113: if (initialized) ! 114: return; ! 115: initialized = TRUE; ! 116: ! 117: widgetContext = XUniqueContext(); ! 118: defFontStruct = XLoadQueryFont(dpy,"fixed"); ! 119: } ! 120: ! 121: /* ! 122: * Given a display and window, get the widget data. ! 123: */ ! 124: ! 125: static WidgetData DataFromWindow(dpy, window) ! 126: Display *dpy; ! 127: Window window; ! 128: { ! 129: WidgetData result; ! 130: if (XFindContext(dpy, window, widgetContext, (caddr_t *)&result)) ! 131: return NULL; ! 132: return result; ! 133: } ! 134: ! 135: /* ! 136: * Calculate width and height of displayed text in pixels ! 137: */ ! 138: ! 139: static void SetTextWidthAndHeight(data) ! 140: WidgetData data; ! 141: { ! 142: register XFontStruct *fs = data->fontStruct; ! 143: ! 144: data->labelHeight = fs->max_bounds.ascent + fs->max_bounds.descent; ! 145: data->labelWidth = XTextWidth(fs, data->label, data->labelLength); ! 146: } ! 147: ! 148: ! 149: /* ! 150: * Repaint the widget window ! 151: */ ! 152: ! 153: static void Redisplay(data) ! 154: WidgetData data; ! 155: { ! 156: Position x, y; ! 157: ! 158: /* Calculate text position within window given window width and height */ ! 159: switch (data->justify) { ! 160: case XtjustifyLeft : ! 161: x = data->internalWidth; ! 162: break; ! 163: case XtjustifyRight : ! 164: x = data->width - data->labelWidth - data->internalWidth; ! 165: break; ! 166: case XtjustifyCenter : ! 167: x = (data->width - data->labelWidth) / 2; ! 168: break; ! 169: } ! 170: if (x < 0) x = 0; ! 171: y = (data->height - data->labelHeight) / 2 ! 172: + data->fontStruct->max_bounds.ascent; ! 173: ! 174: XDrawString(data->dpy, data->window, data->gc, x, y, ! 175: data->label, data->labelLength); ! 176: } ! 177: ! 178: ! 179: /* ! 180: * Fill in the gc field ! 181: */ ! 182: ! 183: static void GetGC(data) ! 184: WidgetData data; ! 185: { ! 186: XGCValues values; ! 187: ! 188: values.foreground = data->foreground; ! 189: values.font = data->fontStruct->fid; ! 190: values.background = data->background; ! 191: data->gc = XtGetGC(data->dpy, (XContext) widgetContext, data->window, ! 192: GCForeground | GCFont | GCBackground, &values); ! 193: } ! 194: ! 195: ! 196: /* ! 197: * Widget event handlers ! 198: */ ! 199: ! 200: static XtEventReturnCode HandleExpose(event, eventdata) ! 201: XEvent *event; ! 202: caddr_t eventdata; ! 203: { ! 204: if (event->xexpose.count == 0) ! 205: Redisplay((WidgetData) eventdata); ! 206: return XteventHandled; ! 207: } ! 208: ! 209: ! 210: /* ! 211: * ||| Kludge as long as X events are clumped together ! 212: */ ! 213: ! 214: static XtEventReturnCode HandleStructureNotify(event, eventdata) ! 215: XEvent *event; ! 216: caddr_t eventdata; ! 217: { ! 218: register WidgetData data = (WidgetData) eventdata; ! 219: ! 220: switch (event->type) { ! 221: case ConfigureNotify : ! 222: data->height = event->xconfigure.height; ! 223: data->width = event->xconfigure.width; ! 224: return XteventHandled; ! 225: ! 226: case DestroyNotify : ! 227: (void) XDeleteContext(data->dpy, data->window, widgetContext); ! 228: XtClearEventHandlers(data->dpy, data->window); ! 229: /* ||| XtFreeGC(data->gc); */ ! 230: XtFree(data->label); ! 231: XtFree ((char *) data); ! 232: return XteventHandled; ! 233: } ! 234: return XteventNotHandled; ! 235: } ! 236: ! 237: ! 238: /**************************************************************** ! 239: * ! 240: * Public Procedures ! 241: * ! 242: ****************************************************************/ ! 243: ! 244: Window XtLabelCreate(dpy, parent, args, argCount) ! 245: Display *dpy; ! 246: Window parent; ! 247: ArgList args; ! 248: int argCount; ! 249: { ! 250: register WidgetData data; ! 251: XrmNameList names; ! 252: XrmClassList classes; ! 253: ! 254: if (!initialized) ! 255: LabelInitialize (dpy); ! 256: ! 257: data = (WidgetData ) XtMalloc (sizeof (WidgetDataRec)); ! 258: ! 259: /* Set resource values */ ! 260: globaldata.dpy = dpy; ! 261: XtGetResources(dpy, resources, XtNumber(resources), args, argCount, parent, ! 262: "label", "Label", &names, &classes); ! 263: *data = globaldata; ! 264: ! 265: ! 266: /* Set text label to widget name if needed */ ! 267: if (data->label == NULL) ! 268: data->label = XrmNameToAtom(names[XrmNameListLength(names) - 1]); ! 269: data->labelLength = strlen(data->label); ! 270: data->label = strcpy( XtMalloc ((unsigned) data->labelLength + 1), ! 271: data->label); ! 272: ! 273: /* obtain text dimensions and calculate the window size */ ! 274: SetTextWidthAndHeight(data); ! 275: if (data->width == 0) ! 276: data->width = data->labelWidth + 2 * data->internalWidth; ! 277: if (data->height == 0) ! 278: data->height = data->labelHeight + 2 * data->internalHeight; ! 279: ! 280: if (data->window != NULL) { ! 281: XWindowAttributes wi; ! 282: /* set global data from window parameters */ ! 283: if (! XGetWindowAttributes(data->dpy, data->window, &wi)) { ! 284: data->window = NULL; ! 285: } else { ! 286: data->borderWidth = wi.border_width; ! 287: data->width = wi.width; ! 288: data->height = wi.height; ! 289: } ! 290: } ! 291: if (data->window == NULL) { ! 292: #ifdef notdef ! 293: int gravity; ! 294: switch(data->justify) { ! 295: case XtjustifyLeft : gravity = WestGravity; break; ! 296: case XtjustifyRight : gravity = EastGravity; break; ! 297: case XtjustifyCenter : gravity = CenterGravity; break; ! 298: } ! 299: #endif ! 300: /* !!! put window gravity into window !!! */ ! 301: /* create the Label button window */ ! 302: data->window = XCreateSimpleWindow(data->dpy,parent, 0, 0, ! 303: data->width, data->height, ! 304: data->borderWidth, data->border, data->background); ! 305: } ! 306: ! 307: XtSetNameAndClass(data->dpy, data->window, names, classes); ! 308: XrmFreeNameList(names); ! 309: XrmFreeClassList(classes); ! 310: ! 311: /* Create a graphics context */ ! 312: GetGC(data); ! 313: ! 314: (void)XSaveContext(data->dpy, data->window, widgetContext, (caddr_t)data); ! 315: ! 316: /* Set handlers for expose, resize, destroy, and message events */ ! 317: XtSetEventHandler (data->dpy, data->window, (XtEventHandler)HandleStructureNotify, ! 318: StructureNotifyMask, (caddr_t)data); ! 319: XtSetEventHandler (data->dpy, data->window, (XtEventHandler)HandleExpose, ! 320: ExposureMask, (caddr_t)data); ! 321: ! 322: return (data->window); ! 323: } ! 324: ! 325: ! 326: /* ! 327: * Get specified arguments from widget ! 328: */ ! 329: ! 330: void XtLabelGetValues(dpy, window, args, argCount) ! 331: Display *dpy; ! 332: Window window; ! 333: ArgList args; ! 334: int argCount; ! 335: { ! 336: WidgetData data; ! 337: data = DataFromWindow(dpy, window); ! 338: if (data == NULL) return; ! 339: globaldata = *data; ! 340: XtGetValues(resources, XtNumber(resources), args, argCount); ! 341: } ! 342: ! 343: ! 344: /* ! 345: * Set specified arguments into widget ! 346: */ ! 347: ! 348: void XtLabelSetValues(dpy, window, args, argCount) ! 349: Display *dpy; ! 350: Window window; ! 351: ArgList args; ! 352: int argCount; ! 353: { ! 354: WidgetData data; ! 355: data = DataFromWindow(dpy, window); ! 356: if (data == NULL) return; ! 357: globaldata = *data; ! 358: XtSetValues(resources, XtNumber(resources), args, argCount); ! 359: ! 360: if (strcmp(data->label, globaldata.label) != 0 ! 361: || data->fontStruct != globaldata.fontStruct) { ! 362: XtGeometryReturnCode reply; ! 363: WindowBox reqbox, replybox; ! 364: ! 365: globaldata.labelLength = strlen(globaldata.label); ! 366: globaldata.label = strcpy( ! 367: XtMalloc ((unsigned) globaldata.labelLength + 1), ! 368: globaldata.label); ! 369: XtFree ((char *) data->label); ! 370: ! 371: /* obtain text dimensions and calculate the window size */ ! 372: SetTextWidthAndHeight(&globaldata); ! 373: reqbox.width = globaldata.labelWidth + 2*globaldata.internalWidth; ! 374: reqbox.height = globaldata.labelHeight + 2*globaldata.internalHeight; ! 375: reply = XtMakeGeometryRequest(globaldata.dpy, globaldata.window, XtgeometryResize, ! 376: &reqbox, &replybox); ! 377: if (reply == XtgeometryAlmost) { ! 378: reqbox = replybox; ! 379: reply = XtMakeGeometryRequest(globaldata.dpy, globaldata.window, XtgeometryResize, ! 380: &reqbox, &replybox); ! 381: } ! 382: if (reply == XtgeometryYes) { ! 383: globaldata.width = reqbox.width; ! 384: globaldata.height = reqbox.height; ! 385: } ! 386: } ! 387: ! 388: if (data->foreground != globaldata.foreground ! 389: || data->background != globaldata.background ! 390: || data->fontStruct->fid != globaldata.fontStruct->fid) { ! 391: /* Need new graphics context */ ! 392: /* ||| XtFreeGC(data->gc) */ ! 393: GetGC(&globaldata); ! 394: } ! 395: XClearWindow(data->dpy, data->window); ! 396: *data = globaldata; ! 397: Redisplay (data); ! 398: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.