|
|
1.1 ! root 1: /* $Header: Boolean.c,v 1.2 87/09/12 12:41:35 swick Exp $ */ ! 2: #ifndef lint ! 3: static char *sccsid = "@(#)Boolean.c 1.8 2/24/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 "Boolean.h" ! 35: #include "Atoms.h" ! 36: ! 37: /* Private Definitions */ ! 38: ! 39: typedef void (*NotifyProc)(); ! 40: ! 41: typedef struct _WidgetDataRec { ! 42: Display *dpy; /* widget display connection */ ! 43: Window window; /* widget window */ ! 44: Position x, y; /* location of widget */ ! 45: Dimension borderWidth; /* border width in pixels */ ! 46: Dimension width, height; /* width/height in pixels */ ! 47: int ibw, ibh; /* internal border width/height in pixels */ ! 48: char *text; /* button text */ ! 49: int fgpixel; /* color index for text */ ! 50: int bgpixel; /* color index for background */ ! 51: int brpixel; /* color for border */ ! 52: Boolean highlighted; /* are we highlighted? */ ! 53: Boolean value; /* pointer to value */ ! 54: XFontStruct *fontstruct; /* font for text */ ! 55: Dimension twidth, theight;/* text width/height */ ! 56: XtJustify justify; /* text justification */ ! 57: NotifyProc proc; /* procedure to invoke on value change */ ! 58: caddr_t tag; /* widget client data */ ! 59: XtEventsPtr eventTable; /* Table for Translation Manager */ ! 60: caddr_t state; /* state for Translation Manager */ ! 61: int eventlevels; /* recursion levels of event handling */ ! 62: GC gc; /* current gc */ ! 63: GC onGC; /* GC to use when on */ ! 64: GC offGC; /* GC to use when off */ ! 65: } WidgetDataRec, *WidgetData; ! 66: ! 67: extern void Dummy(); ! 68: static WidgetDataRec globaldata; ! 69: static WidgetDataRec globalinit = { ! 70: ! 71: NULL, /* Display dpy; */ ! 72: NULL, /* Window window; */ ! 73: 0,0, /* x,y */ ! 74: 1, /* int borderWidth; */ ! 75: 0, 0, /* int width, height; */ ! 76: 4, 2, /* int ibw, ibh; */ ! 77: NULL, /* char *text; */ ! 78: NULL, /* int fgpixel; */ /* init proc */ ! 79: NULL, /* int bgpixel; */ /* init proc */ ! 80: NULL, /* Pixmap brpixmap; */ /* init proc */ ! 81: FALSE, /* Boolean highlighted; */ ! 82: FALSE, /* Boolean value; */ ! 83: NULL, /* XFontStruct *fontstruct; */ /* init proc */ ! 84: 0, 0, /* int twidth, theight; */ ! 85: XtjustifyCenter, /* justify */ ! 86: Dummy, /* void (*proc) (); */ ! 87: NULL, /* caddr_t tag; */ ! 88: NULL, /* event table pointer */ ! 89: NULL, /* state for Translation Manager */ ! 90: NULL, /* event levels */ ! 91: NULL, /* gc */ ! 92: NULL, /* onGC */ ! 93: NULL, /* offGC */ ! 94: }; ! 95: ! 96: /* Private Data */ ! 97: ! 98: static int defaultBorderWidth = 1; ! 99: static int defaultInternalBorderWidth = 4; ! 100: static int defaultInternalBorderHeight = 2; ! 101: static XtJustify defaultJustify = XtjustifyCenter; ! 102: static NotifyProc defaultFunction = Dummy; ! 103: ! 104: static Resource resources[] = { ! 105: {XtNvalue, XtCValue, XrmRBoolean, sizeof(Boolean), ! 106: (caddr_t)&globaldata.value, (caddr_t)NULL}, ! 107: {XtNwindow, XtCWindow, XrmRWindow, sizeof(Window), ! 108: (caddr_t)&globaldata.window, (caddr_t)NULL}, ! 109: {XtNborderWidth, XtCBorderWidth, XrmRInt, sizeof(int), ! 110: (caddr_t)&globaldata.borderWidth, (caddr_t)&defaultBorderWidth}, ! 111: {XtNwidth, XtCWidth, XrmRInt, sizeof(int), ! 112: (caddr_t)&globaldata.width, (caddr_t)NULL}, ! 113: {XtNheight, XtCHeight, XrmRInt, sizeof(int), ! 114: (caddr_t)&globaldata.height, (caddr_t)NULL}, ! 115: {XtNinternalWidth, XtCWidth, XrmRInt, sizeof(int), ! 116: (caddr_t)&globaldata.ibw, (caddr_t)&defaultInternalBorderWidth}, ! 117: {XtNinternalHeight, XtCHeight, XrmRInt, sizeof(int), ! 118: (caddr_t)&globaldata.ibh, (caddr_t)&defaultInternalBorderHeight}, ! 119: {XtNlabel, XtCLabel, XrmRString, sizeof(char *), ! 120: (caddr_t)&globaldata.text, (caddr_t)NULL}, ! 121: {XtNforeground, XtCColor, XrmRPixel, sizeof(int), ! 122: (caddr_t)&globaldata.fgpixel, (caddr_t)&XtDefaultFGPixel}, ! 123: {XtNbackground, XtCColor, XrmRPixel, sizeof(int), ! 124: (caddr_t)&globaldata.bgpixel, (caddr_t)&XtDefaultBGPixel}, ! 125: {XtNborder, XtCColor, XrmRPixel, sizeof(int), ! 126: (caddr_t)&globaldata.brpixel, (caddr_t)&XtDefaultFGPixel}, ! 127: {XtNfont, XtCFont, XrmRFontStruct, sizeof(XFontStruct *), ! 128: (caddr_t)&globaldata.fontstruct,(caddr_t)NULL}, ! 129: {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify), ! 130: (caddr_t)&globaldata.justify, (caddr_t)&defaultJustify}, ! 131: {XtNfunction, XtCFunction, XtRFunction, sizeof(NotifyProc), ! 132: (caddr_t)&globaldata.proc, (caddr_t)&defaultFunction}, ! 133: {XtNparameter, XtCParameter, XrmRPointer, sizeof(caddr_t), ! 134: (caddr_t)&globaldata.tag, (caddr_t)NULL}, ! 135: {XtNeventBindings, XtCEventBindings,XtREventBindings, sizeof(caddr_t), ! 136: (caddr_t)&globaldata.eventTable,NULL }, ! 137: }; ! 138: ! 139: static char *defaultEventBindings[] = { ! 140: "<EnterWindow>: highlight\n", ! 141: "<LeaveWindow>: unhighlight\n", ! 142: "<ButtonPress>left: toggle\n", ! 143: "<ButtonRelease>left: notify\n", ! 144: NULL ! 145: }; ! 146: ! 147: /**************************************************************** ! 148: * ! 149: * Private Procedures ! 150: * ! 151: ****************************************************************/ ! 152: ! 153: static Boolean initialized = FALSE; /* !!! STATIC !!! */ ! 154: ! 155: static XContext widgetContext; ! 156: ! 157: static void BooleanInitialize (dpy) ! 158: Display *dpy; ! 159: { ! 160: if (initialized) ! 161: return; ! 162: initialized = TRUE; ! 163: ! 164: widgetContext = XUniqueContext(); ! 165: ! 166: globalinit.fontstruct = XLoadQueryFont(dpy,"fixed"); ! 167: globalinit.justify = XtjustifyCenter; ! 168: globalinit.eventTable = XtParseEventBindings(defaultEventBindings); ! 169: } ! 170: ! 171: static void SetTextWidthAndHeight(data) ! 172: WidgetData data; ! 173: { ! 174: data->theight = data->fontstruct->max_bounds.ascent + ! 175: data->fontstruct->max_bounds.descent; ! 176: data->twidth = XTextWidth(data->fontstruct, data->text, ! 177: strlen(data->text)); ! 178: } ! 179: ! 180: /*ARGSUSED*/ ! 181: static void Dummy(p) ! 182: caddr_t p; ! 183: { ! 184: (void) printf("dummy notify for Boolean\n"); ! 185: } ! 186: ! 187: static void Ignore () ! 188: { ! 189: (void) printf("you are being ignored\n"); ! 190: } ! 191: ! 192: /* ! 193: * Given a display and window, get the widget data. ! 194: */ ! 195: ! 196: static WidgetData DataFromWindow(dpy, window) ! 197: Display *dpy; ! 198: Window window; ! 199: { ! 200: WidgetData result; ! 201: if (XFindContext(dpy, window, widgetContext, (caddr_t *)&result)) ! 202: return NULL; ! 203: return result; ! 204: } ! 205: ! 206: /* ! 207: * ! 208: * Repaint the widget window ! 209: * ! 210: */ ! 211: ! 212: static void Redisplay (data) ! 213: WidgetData data; ! 214: { ! 215: int textx, texty; ! 216: Window w = data->window; ! 217: ! 218: ! 219: /* ! 220: * Calculate Text x,y given window width and text width ! 221: * to the specified justification ! 222: */ ! 223: ! 224: if (data->justify == XtjustifyLeft) ! 225: textx = 2; ! 226: else if (data->justify == XtjustifyRight) ! 227: textx = data->width - data->twidth; ! 228: else ! 229: textx = ((data->width - data->twidth) / 2); ! 230: if (textx < 0) textx = 0; ! 231: texty = (data->height - data->theight) / 2 + ! 232: data->fontstruct->max_bounds.ascent; ! 233: ! 234: XFillRectangle(data->dpy, w, ! 235: (data->highlighted ? data->onGC : data->offGC), ! 236: 0, 0, data->width, data->height); ! 237: ! 238: XDrawImageString( ! 239: data->dpy, w, (((data->value)) ? data->offGC : data->onGC), ! 240: textx, texty, data->text, strlen(data->text)); ! 241: ! 242: } ! 243: ! 244: extern void Destroy(); ! 245: ! 246: /* ! 247: * ! 248: * Generic widget event handler ! 249: * ! 250: */ ! 251: ! 252: static XtEventReturnCode EventHandler(event, eventdata) ! 253: XEvent *event; ! 254: caddr_t eventdata; ! 255: { ! 256: WidgetData data = (WidgetData) eventdata; ! 257: XtActionTokenPtr actionList; ! 258: NotifyProc proc; ! 259: ! 260: data->eventlevels++; ! 261: ! 262: switch (event->type) { ! 263: case ConfigureNotify: ! 264: data->width = event->xconfigure.width; ! 265: data->height = event->xconfigure.height; ! 266: data->borderWidth = event->xconfigure.border_width; ! 267: break; ! 268: ! 269: case DestroyNotify: Destroy(data); break; ! 270: ! 271: case Expose: ! 272: if (event->xexpose.count == 0) ! 273: Redisplay(data); ! 274: break; ! 275: ! 276: default: ! 277: actionList = (XtActionTokenPtr)XtTranslateEvent( ! 278: event, (TranslationPtr) data->state); ! 279: for (; actionList != NULL; actionList = actionList->next) { ! 280: if (actionList->type == XttokenAction) { ! 281: proc = (NotifyProc)XtInterpretAction( ! 282: data->dpy, ! 283: (TranslationPtr) data->state, ! 284: actionList->value.action); ! 285: (*proc) (data); ! 286: } ! 287: } ! 288: break; ! 289: } ! 290: ! 291: data->eventlevels--; ! 292: return (XteventHandled); ! 293: } ! 294: ! 295: /* ! 296: * ! 297: * Widget hilight event handler ! 298: * ! 299: */ ! 300: ! 301: /*ARGSUSED*/ ! 302: static XtEventReturnCode Highlight(data) ! 303: WidgetData data; ! 304: { ! 305: data->highlighted = TRUE; ! 306: Redisplay(data); ! 307: return (XteventHandled); ! 308: } ! 309: ! 310: /* ! 311: * ! 312: * Widget un-hilight event handler ! 313: * ! 314: */ ! 315: ! 316: /*ARGSUSED*/ ! 317: static XtEventReturnCode Unhighlight(data) ! 318: WidgetData data; ! 319: { ! 320: data->highlighted = FALSE; ! 321: Redisplay(data); ! 322: return (XteventHandled); ! 323: } ! 324: ! 325: static void SetValue(data, newval) ! 326: WidgetData data; ! 327: Boolean newval; ! 328: { ! 329: if ((data->value) == newval) return; ! 330: ! 331: (data->value) = newval; ! 332: data->gc = (newval ? data->onGC : data->offGC); ! 333: /* ! 334: XSetWindowBackground(data->dpy, data->window, data->gc->value.background); ! 335: */ ! 336: Redisplay(data); ! 337: } ! 338: ! 339: /* ! 340: * ! 341: * Widget set value event handler ! 342: * ! 343: */ ! 344: ! 345: /*ARGSUSED*/ ! 346: static XtEventReturnCode On(event, eventdata) ! 347: XEvent *event; ! 348: caddr_t eventdata; ! 349: { ! 350: WidgetData data = (WidgetData) eventdata; ! 351: ! 352: SetValue(data, TRUE); ! 353: return (XteventHandled); ! 354: } ! 355: ! 356: /* ! 357: * ! 358: * Widget un-set value event handler ! 359: * ! 360: */ ! 361: ! 362: /*ARGSUSED*/ ! 363: static XtEventReturnCode Off(event, eventdata) ! 364: XEvent *event; ! 365: caddr_t eventdata; ! 366: { ! 367: WidgetData data = (WidgetData) eventdata; ! 368: ! 369: SetValue(data, FALSE); ! 370: return (XteventHandled); ! 371: } ! 372: ! 373: /* ! 374: * ! 375: * Widget toggle value event handler ! 376: * ! 377: */ ! 378: ! 379: /*ARGSUSED*/ ! 380: static XtEventReturnCode Toggle(data) ! 381: WidgetData data; ! 382: { ! 383: SetValue(data, ! (data->value)); ! 384: return (XteventHandled); ! 385: } ! 386: ! 387: /* ! 388: * Widget handler to invoke application routine */ ! 389: ! 390: /*ARGSUSED*/ ! 391: static XtEventReturnCode Notify(data) ! 392: WidgetData data; ! 393: { ! 394: Redisplay(data); ! 395: XFlush(data->dpy); ! 396: data->proc(data->tag); /* invoke application proc */ ! 397: ! 398: return(XteventHandled); ! 399: } ! 400: ! 401: ! 402: /* ! 403: * ! 404: * Destroy the widget ! 405: * ! 406: */ ! 407: ! 408: static void Destroy(data) ! 409: WidgetData data; ! 410: { ! 411: (void) XDeleteContext(data->dpy, data->window, widgetContext); ! 412: XtClearEventHandlers(data->dpy, data->window); ! 413: XtFree ((char*)data->text); ! 414: XtFree ((char *) data); ! 415: } ! 416: ! 417: /**************************************************************** ! 418: * ! 419: * Public Procedures ! 420: * ! 421: ****************************************************************/ ! 422: ! 423: Window XtBooleanCreate(dpy, parent, args, argCount) ! 424: Display *dpy; ! 425: Window parent; ! 426: ArgList args; ! 427: int argCount; ! 428: { ! 429: WidgetData data; ! 430: XrmNameList names; ! 431: XrmClassList classes; ! 432: Position x, y; ! 433: unsigned int depth; ! 434: Drawable root; ! 435: unsigned long valuemask; ! 436: XSetWindowAttributes wvals; ! 437: XGCValues values; ! 438: ! 439: static XtActionsRec actionsTable[] = { ! 440: {"toggle", (caddr_t)Toggle}, ! 441: {"highlight", (caddr_t)Highlight}, ! 442: {"unhighlight", (caddr_t)Unhighlight}, ! 443: {"notify", (caddr_t)Notify}, ! 444: {"on", (caddr_t)On}, ! 445: {"off", (caddr_t)Off}, ! 446: {NULL, NULL} ! 447: }; ! 448: ! 449: ! 450: if (!initialized) ! 451: BooleanInitialize(dpy); ! 452: ! 453: data = (WidgetData) XtMalloc (sizeof(WidgetDataRec)); ! 454: ! 455: /* Set Default Values */ ! 456: globaldata = globalinit; ! 457: globaldata.dpy = dpy; ! 458: XtGetResources(dpy, resources, XtNumber(resources), args, argCount, parent, ! 459: "boolean", "Boolean", &names, &classes); ! 460: *data = globaldata; ! 461: ! 462: data->state = XtSetActionBindings( ! 463: data->dpy, ! 464: data->eventTable, actionsTable, (caddr_t)Ignore); ! 465: ! 466: if (data->text == NULL) ! 467: data->text = XrmNameToAtom(names[XrmNameListLength(names) - 1]); ! 468: data->text = strcpy( XtMalloc ((unsigned) strlen(data->text) + 1), ! 469: data->text); ! 470: ! 471: /* obtain text dimensions and calculate the window size */ ! 472: SetTextWidthAndHeight(data); ! 473: if (data->width == 0) data->width = data->twidth + 2*data->ibw; ! 474: if (data->height == 0) data->height = data->theight + 2*data->ibh; ! 475: ! 476: wvals.background_pixel = data->bgpixel; ! 477: wvals.border_pixel = data->brpixel; ! 478: wvals.bit_gravity = CenterGravity; ! 479: ! 480: valuemask = CWBackPixel | CWBorderPixel | CWBitGravity; ! 481: ! 482: if (data->window != NULL) { ! 483: /* set global data from window parameters */ ! 484: if ( ! 485: XGetGeometry( ! 486: data->dpy, data->window, &root, ! 487: &x, &y, &(data->width), &(data->height), ! 488: &(data->borderWidth), &depth) ! 489: ) { ! 490: XReparentWindow(data->dpy, data->window, parent, data->x,data->y); ! 491: XChangeWindowAttributes(data->dpy, data->window, valuemask, &wvals); ! 492: } else ! 493: data->window = NULL; ! 494: } ! 495: if (data->window == NULL) ! 496: data->window = XCreateWindow(data->dpy, parent, data->x, data->y, ! 497: data->width, data->height, data->borderWidth, ! 498: 0, (unsigned) InputOutput, (Visual *) CopyFromParent, ! 499: valuemask, &wvals); ! 500: ! 501: values.foreground = data->fgpixel; ! 502: values.background = data->bgpixel; ! 503: values.font = data->fontstruct->fid; ! 504: valuemask = GCForeground | GCBackground | GCFont; ! 505: data->onGC = XtGetGC(data->dpy, widgetContext, data->window, ! 506: valuemask, &values); ! 507: values.foreground = data->bgpixel; ! 508: values.background = data->fgpixel; ! 509: data->offGC = XtGetGC(data->dpy, widgetContext, data->window, ! 510: valuemask, &values); ! 511: ! 512: XtSetNameAndClass(data->dpy, data->window, names, classes); ! 513: XrmFreeNameList(names); ! 514: XrmFreeClassList(classes); ! 515: ! 516: (void)XSaveContext(data->dpy, data->window, widgetContext, (caddr_t)data); ! 517: ! 518: /* set handler for expose, resize, and message events */ ! 519: XtSetEventHandler (data->dpy, data->window, (XtEventHandler) EventHandler, ! 520: StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask ! 521: | EnterWindowMask | LeaveWindowMask, (caddr_t)data); ! 522: ! 523: return (data->window); ! 524: } ! 525: ! 526: /* ! 527: * Set specified arguments in widget ! 528: */ ! 529: ! 530: void XtBooleanSetValues (dpy, window, args, argCount) ! 531: Display *dpy; ! 532: Window window; ! 533: ArgList args; ! 534: int argCount; ! 535: { ! 536: WidgetData data; ! 537: data = DataFromWindow(dpy, window); ! 538: if (data == NULL) return; ! 539: ! 540: globaldata = *data; ! 541: XtSetValues(resources, XtNumber(resources), args, argCount); ! 542: ! 543: (globaldata.value) = ((globaldata.value) ? TRUE : FALSE); ! 544: ! 545: if (strcmp (data->text, globaldata.text) ! 546: || data->fontstruct != globaldata.fontstruct) { ! 547: XtGeometryReturnCode reply; ! 548: WindowBox reqbox, replybox; ! 549: ! 550: globaldata.text = strcpy( ! 551: XtMalloc ((unsigned) strlen(globaldata.text) + 1), ! 552: globaldata.text); ! 553: XtFree ((char *) data->text); ! 554: ! 555: /* obtain text dimensions and calculate the window size */ ! 556: SetTextWidthAndHeight(&globaldata); ! 557: reqbox.width = (int) globaldata.twidth + 2*globaldata.ibw; ! 558: reqbox.height = (int) globaldata.theight + 2*globaldata.ibh; ! 559: reply = XtMakeGeometryRequest( ! 560: globaldata.dpy, globaldata.window, ! 561: XtgeometryResize, &reqbox, &replybox); ! 562: if (reply == XtgeometryAlmost) { ! 563: reqbox = replybox; ! 564: (void) XtMakeGeometryRequest( ! 565: globaldata.dpy, globaldata.window, ! 566: XtgeometryResize, &reqbox, &replybox); ! 567: } ! 568: } ! 569: ! 570: *data = globaldata; ! 571: Redisplay (data); ! 572: } ! 573: ! 574: /* ! 575: * Get specified arguments from widget ! 576: */ ! 577: ! 578: void XtBooleanGetValues (dpy, window, args, argCount) ! 579: Display *dpy; ! 580: Window window; ! 581: ArgList args; ! 582: int argCount; ! 583: { ! 584: WidgetData data; ! 585: data = DataFromWindow(dpy, window); ! 586: if (data == NULL) return; ! 587: ! 588: globaldata = *data; ! 589: XtGetValues(resources, XtNumber(resources), args, argCount); ! 590: } ! 591:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.