|
|
1.1 ! root 1: #ifndef lint ! 2: static char rcsid[] = "$Header: Command.c,v 1.24 87/09/13 23:04:23 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: * Command.c - Command button widget ! 29: * ! 30: * Rewritten for beta toolkit ! 31: * Author: Mark Ackerman ! 32: * MIT/Project Athena ! 33: * Date: August 27, 1987 ! 34: * ! 35: * from Command.c (XToolkit, alpha version) ! 36: * Charles Haynes ! 37: * Digital Equipment Corporation ! 38: * Western Research Laboratory ! 39: */ ! 40: ! 41: #define XtStrlen(s) ((s) ? strlen(s) : 0) ! 42: ! 43: /* The following are defined for the reader's convenience. Any ! 44: Xt..Field macro in this code just refers to some field in ! 45: one of the substructures of the WidgetRec. */ ! 46: ! 47: #include <stdio.h> ! 48: #include <string.h> ! 49: #include <ctype.h> ! 50: #include "Intrinsic.h" ! 51: #include "Label.h" ! 52: #include "LabelP.h" ! 53: #include "Command.h" ! 54: #include "CommandP.h" ! 55: #include "CommandInt.h" ! 56: #include "Atoms.h" ! 57: ! 58: /**************************************************************** ! 59: * ! 60: * Full class record constant ! 61: * ! 62: ****************************************************************/ ! 63: ! 64: /* Private Data */ ! 65: ! 66: static char *defaultTranslation[] = { ! 67: "<Btn1Down>: set()", ! 68: "<Btn1Up>: notify() unset()", ! 69: "<EnterWindow>: highlight()", ! 70: "<LeaveWindow>: unhighlight()", ! 71: NULL ! 72: }; ! 73: static caddr_t defaultTranslations = (caddr_t)defaultTranslation; ! 74: static XtResource resources[] = { ! 75: ! 76: {XtNfunction, XtCFunction, XtRFunction, sizeof(XtCallbackProc), ! 77: XtOffset(CommandWidget, command.callback), XtRFunction, (caddr_t)NULL}, ! 78: {XtNparameter, XtCParameter, XtRPointer, sizeof(caddr_t), ! 79: XtOffset(CommandWidget,command.closure), XtRPointer, (caddr_t)NULL}, ! 80: ! 81: {XtNhighlightThickness, XtCThickness, XrmRInt, sizeof(Dimension), ! 82: XtOffset(CommandWidget,command.highlight_thickness), XrmRString,"2"}, ! 83: {XtNtranslations, XtCTranslations, XtRTranslationTable, ! 84: sizeof(_XtTranslations), ! 85: XtOffset(CommandWidget, core.translations),XtRTranslationTable, ! 86: (caddr_t)&defaultTranslations}, ! 87: }; ! 88: ! 89: static XtActionsRec actionsList[] = ! 90: { ! 91: {"set", (caddr_t) Set}, ! 92: {"notify", (caddr_t) Notify}, ! 93: {"highlight", (caddr_t) Highlight}, ! 94: {"unset", (caddr_t) Unset}, ! 95: {"unhighlight", (caddr_t) Unhighlight}, ! 96: }; ! 97: ! 98: /* ...ClassData must be initialized at compile time. Must ! 99: initialize all substructures. (Actually, last two here ! 100: need not be initialized since not used.) ! 101: */ ! 102: CommandClassRec commandClassRec = { ! 103: { ! 104: (WidgetClass) &labelClassRec, /* superclass */ ! 105: "Command", /* class_name */ ! 106: sizeof(CommandRec), /* size */ ! 107: ClassInitialize, /* class initialize */ ! 108: FALSE, /* class_inited */ ! 109: Initialize, /* initialize */ ! 110: Realize, /* realize */ ! 111: actionsList, /* actions */ ! 112: XtNumber(actionsList), ! 113: resources, /* resources */ ! 114: XtNumber(resources), /* resource_count */ ! 115: NULLQUARK, /* xrm_class */ ! 116: FALSE, ! 117: FALSE, ! 118: FALSE, /* visible_interest */ ! 119: Destroy, /* destroy */ ! 120: Resize, /* resize */ ! 121: Redisplay, /* expose */ ! 122: SetValues, /* set_values */ ! 123: NULL, /* accept_focus */ ! 124: }, /* CoreClass fields initialization */ ! 125: { ! 126: 0, /* field not used */ ! 127: }, /* LabelClass fields initialization */ ! 128: { ! 129: 0, /* field not used */ ! 130: }, /* CommandClass fields initialization */ ! 131: }; ! 132: ! 133: /* for public consumption */ ! 134: WidgetClass commandWidgetClass = (WidgetClass) &commandClassRec; ! 135: ! 136: XtCallbackKind activateCommand; /* for public consumption*/ ! 137: /**************************************************************** ! 138: * ! 139: * Private Procedures ! 140: * ! 141: ****************************************************************/ ! 142: ! 143: #ifdef saber_bug ! 144: static Cardinal commandCallbackOffset = ! 145: XtOffset(CommandWidget,command.callback_list); ! 146: static void ClassInitialize() ! 147: { ! 148: activateCommand = XtNewCallbackKind( ! 149: commandWidgetClass, commandCallbackOffset); ! 150: ! 151: } ! 152: #else ! 153: static void ClassInitialize() ! 154: { ! 155: activateCommand = XtNewCallbackKind(commandWidgetClass, ! 156: XtOffset(CommandWidget,command.callback_list)); ! 157: ! 158: } ! 159: #endif ! 160: ! 161: static void Get_inverseGC(cbw) ! 162: CommandWidget cbw; ! 163: { ! 164: XGCValues values; ! 165: ! 166: /* Set up a GC for inverse (set) state */ ! 167: ! 168: values.foreground = ComWforeground; ! 169: values.font = ComWfont->fid; ! 170: values.fill_style = FillSolid; ! 171: ! 172: ComWinverseGC = XtGetGC((Widget)cbw, ! 173: (unsigned) GCForeground | GCFont | GCFillStyle, &values); ! 174: } ! 175: ! 176: static void Get_inverseTextGC(cbw) ! 177: CommandWidget cbw; ! 178: { ! 179: XGCValues values; ! 180: ! 181: /* Set up a GC for inverse (set) state */ ! 182: ! 183: values.foreground = ComWbackground; /* default is White */ ! 184: values.font = ComWfont->fid; ! 185: values.fill_style = FillSolid; ! 186: ! 187: ComWinverseTextGC = XtGetGC((Widget)cbw, ! 188: (unsigned) GCForeground | GCFont | GCFillStyle, &values); ! 189: } ! 190: ! 191: static void Get_highlightGC(cbw) ! 192: CommandWidget cbw; ! 193: { ! 194: XGCValues values; ! 195: ! 196: /* Set up a GC for highlighted state. It has a thicker ! 197: line width for the highlight border */ ! 198: ! 199: values.foreground = ComWforeground; ! 200: values.line_width = ComWhighlightThickness; ! 201: ! 202: ComWhighlightGC = XtGetGC((Widget)cbw, ! 203: (unsigned) GCForeground | GCLineWidth, &values); ! 204: } ! 205: ! 206: ! 207: /* ARGSUSED */ ! 208: static void Initialize(request, new, args, num_args) ! 209: Widget request, new; ! 210: ArgList args; ! 211: Cardinal num_args; ! 212: { ! 213: CommandWidget cbw = (CommandWidget) new; ! 214: ! 215: Get_inverseGC(cbw); ! 216: Get_inverseTextGC(cbw); ! 217: Get_highlightGC(cbw); ! 218: /* Start the callback list if the client specified one in ! 219: the arglist */ ! 220: ComWcallbackList = NULL; ! 221: if (ComWcallback != NULL) ! 222: XtAddCallback((Widget)cbw,activateCommand,ComWcallback,ComWclosure); ! 223: ! 224: /* init flags for state */ ! 225: ComWset = FALSE; ! 226: ComWhighlighted = FALSE; ! 227: ComWdisplayHighlighted = FALSE; ! 228: ComWdisplaySet = FALSE; ! 229: ! 230: } ! 231: ! 232: static void Realize(w, valueMask, attributes) ! 233: /* This is the same as LabelWidget */ ! 234: register Widget w; ! 235: Mask valueMask; ! 236: XSetWindowAttributes *attributes; ! 237: { ! 238: XtCallParentProcedure3Args(realize,w,valueMask,attributes); ! 239: } ! 240: ! 241: ! 242: /*************************** ! 243: * ! 244: * EVENT HANDLERS ! 245: * ! 246: ***************************/ ! 247: ! 248: /* ARGSUSED */ ! 249: static void Set(w,event) ! 250: Widget w; ! 251: XEvent *event; ! 252: { ! 253: CommandWidget cbw = (CommandWidget)w; ! 254: ComWset = TRUE; ! 255: Redisplay(w, event); ! 256: } ! 257: ! 258: /* ARGSUSED */ ! 259: static void Unset(w,event) ! 260: Widget w; ! 261: XEvent *event; ! 262: { ! 263: CommandWidget cbw = (CommandWidget)w; ! 264: ComWset = FALSE; ! 265: Redisplay(w, event); ! 266: } ! 267: ! 268: /* ARGSUSED */ ! 269: static void Highlight(w,event) ! 270: Widget w; ! 271: XEvent *event; ! 272: { ! 273: CommandWidget cbw = (CommandWidget)w; ! 274: ComWhighlighted = TRUE; ! 275: Redisplay(w, event); ! 276: } ! 277: ! 278: /* ARGSUSED */ ! 279: static void Unhighlight(w,event) ! 280: Widget w; ! 281: XEvent *event; ! 282: { ! 283: CommandWidget cbw = (CommandWidget)w; ! 284: ComWhighlighted = FALSE; ! 285: Redisplay(w, event); ! 286: } ! 287: ! 288: /* ARGSUSED */ ! 289: static void Notify(w,event) ! 290: Widget w; ! 291: XEvent *event; ! 292: { ! 293: CommandWidget cbw = (CommandWidget)w; ! 294: XtCallCallbacks((Widget)cbw,activateCommand,NULL); ! 295: } ! 296: /* ! 297: * Repaint the widget window ! 298: */ ! 299: ! 300: /************************ ! 301: * ! 302: * REDISPLAY (DRAW) ! 303: * ! 304: ************************/ ! 305: ! 306: /* ARGSUSED */ ! 307: static void Redisplay(w, event) ! 308: Widget w; ! 309: XEvent *event; ! 310: { ! 311: CommandWidget cbw = (CommandWidget) w; ! 312: XSetWindowAttributes window_attributes; ! 313: ! 314: /* Here's the scoop: If the command button button is normal, ! 315: you show the text. If the command button is highlighted but ! 316: not set, you draw a thick border and show the text. ! 317: If the command button is set, draw the button and text ! 318: in inverse. */ ! 319: ! 320: /* Just to make sure everything is okay, check for sensitivity, ! 321: too. If non-sensitive, then gray out the border. */ ! 322: ! 323: /* Note that Redisplay must remember the state of its last ! 324: draw to determine whether to erase the window before ! 325: redrawing to avoid flicker. If the state is the same, ! 326: the window just needs to redraw (even on an expose). */ ! 327: ! 328: if (!ComWsensitive && ComWdisplaySensitive) ! 329: { ! 330: /* change border to gray */ ! 331: window_attributes.border_pixmap = ComWgrayPixmap; ! 332: XChangeWindowAttributes(XtDisplay(w),XtWindow(w), ! 333: CWBorderPixmap,&window_attributes); ! 334: } ! 335: else if (ComWsensitive && !ComWdisplaySensitive) ! 336: { ! 337: /* change border to black */ ! 338: window_attributes.border_pixel = ComWforeground; ! 339: XChangeWindowAttributes(XtDisplay(w),XtWindow(w), ! 340: CWBorderPixel,&window_attributes); ! 341: } ! 342: ! 343: if ((!ComWhighlighted && ComWdisplayHighlighted) || ! 344: ComWsensitive != ComWdisplaySensitive || ! 345: (!ComWset && ComWdisplaySet)) ! 346: XClearWindow(XtDisplay(w),XtWindow(w)); ! 347: /* Don't clear the window if the button's in a set condition; ! 348: instead, fill it with black to avoid flicker. (Must fil ! 349: with black in case it was an expose */ ! 350: else if (ComWset) /* && ComWdisplaySet) || (ComWset && !ComWdisplaySet))*/ ! 351: XFillRectangle(XtDisplay(w),XtWindow(w), ComWinverseGC, ! 352: 0,0,ComWwidth,ComWheight); ! 353: ! 354: /* check whether border is taken out of size of rectangle or ! 355: is outside of rectangle */ ! 356: if (ComWhighlighted) ! 357: XDrawRectangle(XtDisplay(w),XtWindow(w), ComWhighlightGC, ! 358: 0,0,ComWwidth,ComWheight); ! 359: ! 360: /* draw the string: there are three different "styles" for it, ! 361: all in separate GCs */ ! 362: XDrawString(XtDisplay(w),XtWindow(w), ! 363: (ComWset ? ComWinverseTextGC : ! 364: (ComWsensitive ? ComWnormalGC : ComWgrayGC)), ! 365: ComWlabelX, ComWlabelY, ComWlabel, (int) ComWlabelLen); ! 366: ! 367: ComWdisplayHighlighted = ComWhighlighted; ! 368: ComWdisplaySet = ComWset; ! 369: ComWdisplaySensitive = ComWsensitive; ! 370: } ! 371: ! 372: ! 373: static void Resize(w) ! 374: Widget w; ! 375: { ! 376: /* Nothing changes specific to command. Label must change. */ ! 377: XtCallParentProcedure(resize,w); ! 378: } ! 379: ! 380: static void Destroy(w) ! 381: Widget w; ! 382: { ! 383: /* must free GCs and pixmaps */ ! 384: } ! 385: ! 386: ! 387: /* ! 388: * Set specified arguments into widget ! 389: */ ! 390: static Boolean SetValues (current, request, new, last) ! 391: Widget current, request, new; ! 392: Boolean last; ! 393: { ! 394: CommandWidget cbw = (CommandWidget) current; ! 395: CommandWidget newcbw = (CommandWidget) new; ! 396: ! 397: if (XtLField(newcbw,foreground) != ComWforeground) ! 398: { ! 399: XtDestroyGC(ComWinverseGC); ! 400: Get_inverseGC(newcbw); ! 401: XtDestroyGC(ComWhighlightGC); ! 402: Get_highlightGC(newcbw); ! 403: } ! 404: else ! 405: { ! 406: if (XtCField(newcbw,background_pixel) != ComWbackground || ! 407: XtLField(newcbw,font) != ComWfont) { ! 408: XtDestroyGC(ComWinverseTextGC); ! 409: Get_inverseTextGC(newcbw); ! 410: } ! 411: if (XtCBField(newcbw,highlight_thickness) != ComWhighlightThickness) { ! 412: XtDestroyGC(ComWhighlightGC); ! 413: Get_highlightGC(newcbw); ! 414: } ! 415: } ! 416: ! 417: /* NEED TO RESET PROC AND CLOSURE */ ! 418: ! 419: /* ACTIONS */ ! 420: /* Change Label to remove ClearWindow and Redisplay */ ! 421: /* Change Label to change GCs if foreground, etc */ ! 422: ! 423: return (FALSE); /* actually need to return TRUE if Redisplay is needed! */ ! 424: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.