|
|
1.1 ! root 1: /* $Header: ButtonBox.c,v 1.1 87/09/11 07:57:18 toddb Exp $ */ ! 2: #ifndef lint ! 3: static char *sccsid = "@(#)ButtonBox.c 1.14 2/26/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: /* ! 31: * ButtonBox.c - Button box composite widget ! 32: * ! 33: * Author: haynes ! 34: * Digital Equipment Corporation ! 35: * Western Research Laboratory ! 36: * Date: Sat Jan 24 1987 ! 37: */ ! 38: ! 39: #include "Xlib.h" ! 40: #include "Intrinsic.h" ! 41: #include "ButtonBox.h" ! 42: #include "Atoms.h" ! 43: ! 44: #define MAXHEIGHT ((1 << 31)-1) ! 45: #define MAXWIDTH ((1 << 31)-1) ! 46: ! 47: #define max(x, y) (((x) > (y)) ? (x) : (y)) ! 48: #define min(x, y) (((x) < (y)) ? (x) : (y)) ! 49: #define assignmax(x, y) if ((y) > (x)) x = (y) ! 50: #define assignmin(x, y) if ((y) < (x)) x = (y) ! 51: ! 52: /**************************************************************** ! 53: * ! 54: * Private Types ! 55: * ! 56: ****************************************************************/ ! 57: ! 58: typedef struct _WidgetDataRec { ! 59: Display *dpy; /* widget display connection */ ! 60: Window w; /* widget window */ ! 61: Position x, y; /* widget window location */ ! 62: Dimension width, height; /* widget window width and height */ ! 63: Dimension borderWidth; /* widget window border width */ ! 64: Pixel borderpixel; /* widget window border color */ ! 65: Pixel bgpixel; /* widget window background color */ ! 66: Dimension hspace, vspace; /* spacing between buttons */ ! 67: int numbuttons; /* number of managed buttons */ ! 68: WindowLugPtr buttons; /* list of managed buttons */ ! 69: Boolean allowresize; /* reconfigure on notify */ ! 70: } WidgetDataRec, *WidgetData; ! 71: ! 72: ! 73: /**************************************************************** ! 74: * ! 75: * Private Data ! 76: * ! 77: ****************************************************************/ ! 78: ! 79: static int index; /* index into button list to add/delete window */ ! 80: ! 81: static WidgetDataRec globaldata; ! 82: static WidgetDataRec globalinit = { ! 83: NULL, /* Display dpy; */ ! 84: NULL, /* Window w; */ ! 85: 0, 0, /* Position x, y; */ ! 86: 0, 0, /* Dimension width, height; */ ! 87: 1, /* Dimension borderWidth; */ ! 88: NULL, /* Pixmap borderpixel; */ ! 89: NULL, /* Pixmap bgpixel; */ ! 90: 4, 4, /* int hspace, vspace; */ ! 91: 0, /* int numbuttons; */ ! 92: NULL, /* WindowLugPtr buttons; */ ! 93: TRUE /* resizable */ ! 94: }; ! 95: ! 96: static Resource resources[] = { ! 97: {XtNwindow, XtCWindow, XrmRWindow, sizeof(Window), ! 98: (caddr_t)&globaldata.w, (caddr_t)NULL}, ! 99: {XtNx, XtCX, XrmRInt, sizeof(int), ! 100: (caddr_t)&globaldata.x, (caddr_t)NULL}, ! 101: {XtNy, XtCY, XrmRInt, sizeof(int), ! 102: (caddr_t)&globaldata.y, (caddr_t)NULL}, ! 103: {XtNwidth, XtCWidth, XrmRInt, sizeof(int), ! 104: (caddr_t)&globaldata.width, (caddr_t)NULL}, ! 105: {XtNheight, XtCHeight, XrmRInt, sizeof(int), ! 106: (caddr_t)&globaldata.height, (caddr_t)NULL}, ! 107: {XtNborderWidth, XtCBorderWidth, XrmRInt, sizeof(int), ! 108: (caddr_t)&globaldata.borderWidth, (caddr_t)NULL}, ! 109: {XtNborder, XtCColor, XrmRPixel, sizeof(int), ! 110: (caddr_t)&globaldata.borderpixel, (caddr_t)&XtDefaultFGPixel}, ! 111: {XtNbackground, XtCColor, XrmRPixel, sizeof(int), ! 112: (caddr_t)&globaldata.bgpixel, (caddr_t)&XtDefaultBGPixel}, ! 113: {XtNhSpace, XtCHSpace, XrmRInt, sizeof(int), ! 114: (caddr_t)&globaldata.hspace, (caddr_t)NULL}, ! 115: {XtNvSpace, XtCVSpace, XrmRInt, sizeof(int), ! 116: (caddr_t)&globaldata.vspace, (caddr_t)NULL}, ! 117: {XtNresizable, XtCBoolean, XrmRBoolean, sizeof(Boolean), ! 118: (caddr_t)&globaldata.allowresize, (caddr_t) NULL} ! 119: }; ! 120: ! 121: ! 122: static int indexinit = -1; ! 123: static Resource parmResources[] = { ! 124: {XtNindex, XtCIndex, XrmRInt, ! 125: sizeof(int), (caddr_t)&index, (caddr_t)&indexinit}, ! 126: }; ! 127: ! 128: /**************************************************************** ! 129: * ! 130: * Private Routines ! 131: * ! 132: ****************************************************************/ ! 133: ! 134: static Boolean initialized = FALSE; ! 135: ! 136: static XContext widgetContext; ! 137: ! 138: static void ButtonBoxInitialize() ! 139: { ! 140: if (initialized) ! 141: return; ! 142: initialized = TRUE; ! 143: ! 144: widgetContext = XUniqueContext(); ! 145: } ! 146: ! 147: /* ! 148: * Given a display and window, get the widget data. ! 149: */ ! 150: ! 151: static WidgetData DataFromWindow(dpy, window) ! 152: Display *dpy; ! 153: Window window; ! 154: { ! 155: WidgetData result; ! 156: if (XFindContext(dpy, window, widgetContext, (caddr_t *)&result)) ! 157: return NULL; ! 158: return result; ! 159: } ! 160: ! 161: /* ! 162: * ! 163: * Do a layout, either actually assigning positions, or just calculating size. ! 164: * Returns 1 on success; 0 if it couldn't make things fit. ! 165: * ! 166: */ ! 167: ! 168: static int DoLayout(data, width, height, box, position) ! 169: WidgetData data; ! 170: Dimension width, height; ! 171: WindowBox *box; /* RETURN */ ! 172: Boolean position; /* actually reposition the windows? */ ! 173: { ! 174: int i; ! 175: int w, h, lw, lh, count; ! 176: ! 177: w = data->hspace; ! 178: if ((w > width) && !position) return (0); ! 179: h = data->vspace; ! 180: if ((h > height) && !position) return (0); ! 181: ! 182: for (i = 0; i < data->numbuttons; ) { ! 183: count = 0; ! 184: lh = 0; ! 185: lw = data->hspace; ! 186: /* compute one line worth */ ! 187: for ( ; (i < data->numbuttons); i++) { ! 188: int tw, th; ! 189: tw = lw ! 190: + data->buttons[i].wb.width ! 191: + 2*data->buttons[i].wb.borderWidth ! 192: + data->hspace; ! 193: if (tw > width) { ! 194: if (!position) break; ! 195: if (count > 0) break; ! 196: } ! 197: if (position && ! 198: (lw != data->buttons[i].wb.x || h != data->buttons[i].wb.y)) { ! 199: XMoveWindow(data->dpy, data->buttons[i].w, lw, h); ! 200: data->buttons[i].wb.x = lw; ! 201: data->buttons[i].wb.y = h; ! 202: (void) XtSendConfigureNotify(data->dpy, data->buttons[i].w, ! 203: &(data->buttons[i].wb)); ! 204: } ! 205: lw = tw; ! 206: th = data->buttons[i].wb.height + 2*data->buttons[i].wb.borderWidth; ! 207: assignmax(lh, th); ! 208: count++; ! 209: } ! 210: if (count == 0) return (0); ! 211: assignmax(w, lw); ! 212: h += lh+data->vspace; ! 213: if ((h > height) && !position) return (0); ! 214: } ! 215: ! 216: if (box != NULL) { ! 217: box->width = w; ! 218: box->height = h; ! 219: } ! 220: return (1); ! 221: } ! 222: ! 223: /* ! 224: * ! 225: * Calculate preferred size, given constraining box ! 226: * ! 227: */ ! 228: ! 229: static int PreferredSize(data, width, height, box) ! 230: WidgetData data; ! 231: Dimension width, height; ! 232: WindowBox *box; /* RETURN */ ! 233: { ! 234: return DoLayout(data, width, height, box, FALSE); ! 235: } ! 236: ! 237: /* ! 238: * ! 239: * Compute the layout of the button box ! 240: * ! 241: */ ! 242: ! 243: static void Layout(data) ! 244: WidgetData data; ! 245: { ! 246: (void) DoLayout(data, data->width, data->height, (WindowBox *)NULL, TRUE); ! 247: } ! 248: ! 249: /* ! 250: * ! 251: * Main buttonbox event handler ! 252: * ! 253: */ ! 254: ! 255: static XtEventReturnCode EventHandler(event, eventdata) ! 256: XEvent *event; ! 257: caddr_t eventdata; ! 258: { ! 259: WidgetData data = (WidgetData) eventdata; ! 260: void Destroy(); ! 261: ! 262: switch (event->type) { ! 263: case ConfigureNotify: { ! 264: data->x = event->xconfigure.x; ! 265: data->y = event->xconfigure.y; ! 266: data->borderWidth = event->xconfigure.border_width; ! 267: if (data->allowresize) { ! 268: if (data->height != event->xconfigure.height || ! 269: data->width != event->xconfigure.width) { ! 270: data->height = event->xconfigure.height; ! 271: data->width = event->xconfigure.width; ! 272: (void) TryLayout(data, data->width, MAXHEIGHT); ! 273: Layout(data); ! 274: } ! 275: } ! 276: break; ! 277: } ! 278: ! 279: case DestroyNotify: Destroy(data); break; ! 280: } ! 281: ! 282: return (XteventHandled); ! 283: } ! 284: ! 285: ! 286: /* ! 287: * ! 288: * Handle events on subwidgets ! 289: * ! 290: */ ! 291: ! 292: static XtEventReturnCode SubEventHandler(event, eventdata) ! 293: XEvent *event; ! 294: caddr_t eventdata; ! 295: { ! 296: WidgetData data = (WidgetData) eventdata; ! 297: int i; ! 298: if (event->type == DestroyNotify) { ! 299: for (i=0 ; i<data->numbuttons; i++) ! 300: if (data->buttons[i].w == event->xany.window) { ! 301: DeleteButton(data, i); ! 302: (void) TryNewLayout(data); ! 303: Layout(data); ! 304: break; ! 305: } ! 306: } ! 307: } ! 308: ! 309: /* ! 310: * ! 311: * Destroy the buttonbox ! 312: * ! 313: */ ! 314: ! 315: static void Destroy(data) ! 316: WidgetData data; ! 317: { ! 318: int i; ! 319: /* send destroy messages to all my subwindows */ ! 320: for (i=0; i < data->numbuttons; i++) ! 321: (void) XtSendDestroyNotify(data->dpy, data->buttons[i].w); ! 322: XtFree((char *) data->buttons); ! 323: ! 324: XtClearEventHandlers(data->dpy, data->w); ! 325: (void) XDeleteContext(data->dpy, data->w, widgetContext); ! 326: XtFree ((char *) data); ! 327: } ! 328: ! 329: /* ! 330: * ! 331: * Find Button ! 332: * ! 333: */ ! 334: ! 335: static WindowLugPtr FindButton(data, w) ! 336: WidgetData data; ! 337: Window w; ! 338: { ! 339: int i; ! 340: ! 341: for (i=0; i<data->numbuttons; i++) ! 342: if (data->buttons[i].w == w) return &(data->buttons[i]); ! 343: ! 344: return NULL; ! 345: } ! 346: ! 347: /* ! 348: * ! 349: * Try to do a new layout within a particular width and height ! 350: * ! 351: */ ! 352: ! 353: static int TryLayout(data, width, height) ! 354: WidgetData data; ! 355: Dimension width, height; ! 356: { ! 357: WindowBox box, rbox; ! 358: ! 359: if (!PreferredSize(data, width, height, &box)) return (0); ! 360: ! 361: /* let's see if our parent will go for it. */ ! 362: switch (XtMakeGeometryRequest( ! 363: data->dpy, data->w, XtgeometryResize, &box, &rbox)) { ! 364: ! 365: case XtgeometryNoManager: ! 366: XResizeWindow(data->dpy, data->w, box.width, box.height); ! 367: /* fall through to "yes" */ ! 368: ! 369: case XtgeometryYes: ! 370: data->width = box.width; ! 371: data->height = box.height; ! 372: return (1); ! 373: ! 374: ! 375: case XtgeometryNo: ! 376: return (0); ! 377: ! 378: ! 379: case XtgeometryAlmost: ! 380: if (! PreferredSize(data, rbox.width, rbox.height, ! 381: (WindowBox *) NULL)) ! 382: return (0); ! 383: box = rbox; ! 384: (void) XtMakeGeometryRequest(data->dpy, data->w, XtgeometryResize, &box, &rbox); ! 385: data->width = box.width; ! 386: data->height = box.height; ! 387: return (1); ! 388: ! 389: } ! 390: return (0); ! 391: } ! 392: ! 393: /* ! 394: * ! 395: * Try to do a new layout ! 396: * ! 397: */ ! 398: ! 399: static int TryNewLayout(data) ! 400: WidgetData data; ! 401: { ! 402: if (TryLayout(data, data->width, data->height)) return (1); ! 403: if (TryLayout(data, data->width, MAXHEIGHT)) return (1); ! 404: if (TryLayout(data, MAXWIDTH, MAXHEIGHT)) return(1); ! 405: return (0); ! 406: } ! 407: ! 408: /* ! 409: * ! 410: * Button Resize Request ! 411: * ! 412: */ ! 413: ! 414: /*ARGSUSED*/ ! 415: static XtGeometryReturnCode ResizeButtonRequest(data, w, reqBox, replBox) ! 416: WidgetData data; ! 417: Window w; ! 418: WindowBox *reqBox; ! 419: WindowBox *replBox; /* RETURN */ ! 420: ! 421: { ! 422: WindowLugPtr b; ! 423: WindowLug oldb; ! 424: ! 425: b = FindButton(data, w); ! 426: if (b == NULL) return (XtgeometryNo); ! 427: oldb = *b; ! 428: b->wb = *reqBox; ! 429: b->wb.borderWidth = oldb.wb.borderWidth; ! 430: /* HACK -- maybe we need a "change borderWidth" command? */ ! 431: ! 432: if ((reqBox->width <= oldb.wb.width && reqBox->height <= oldb.wb.height) || ! 433: /* making the button smaller always works */ ! 434: (PreferredSize(data, data->width, data->height, (WindowBox *) NULL)) || ! 435: /* will it fit inside old dims? */ ! 436: (TryNewLayout(data))) ! 437: /* can we make it fit at all? */ ! 438: { ! 439: XResizeWindow(data->dpy, b->w, b->wb.width, b->wb.height); ! 440: (void) XtSendConfigureNotify(data->dpy, b->w, &(b->wb)); ! 441: Layout(data); ! 442: return XtgeometryYes; ! 443: } ! 444: *b = oldb; ! 445: return (XtgeometryNo); ! 446: } ! 447: ! 448: /* ! 449: * ! 450: * Button Box Geometry Manager ! 451: * ! 452: */ ! 453: ! 454: static XtGeometryReturnCode ButtonBoxGeometryManager( ! 455: dpy, w, req, reqBox, replBox) ! 456: Display *dpy; ! 457: Window w; ! 458: XtGeometryRequest req; ! 459: WindowBox *reqBox; ! 460: WindowBox *replBox; /* RETURN */ ! 461: { ! 462: WidgetData data; ! 463: ! 464: if (XFindContext(dpy, w, widgetContext, (caddr_t *)&data) == XCNOENT) ! 465: return (XtgeometryYes); ! 466: /* requests: move, resize, top, bottom */ ! 467: switch (req) { ! 468: case XtgeometryTop : return (XtgeometryYes); ! 469: case XtgeometryBottom : return (XtgeometryYes); ! 470: case XtgeometryMove : return (XtgeometryNo); ! 471: case XtgeometryResize : ! 472: return (ResizeButtonRequest(data, w, reqBox, replBox)); ! 473: } ! 474: return (XtgeometryNo); ! 475: } ! 476: ! 477: static XtStatus AddButton(data, w, index) ! 478: WidgetData data; ! 479: Window w; ! 480: int index; ! 481: { ! 482: int i; ! 483: WindowLug b; ! 484: ! 485: b.w = w; ! 486: if (XtGetWindowSize(data->dpy, w, &b.wb.width, &b.wb.height, ! 487: &b.wb.borderWidth)) ! 488: return (0); ! 489: ! 490: if (FindButton(data, b.w) != NULL) return (0); ! 491: ! 492: data->numbuttons++; ! 493: if (data->numbuttons == 1) { ! 494: data->buttons = (WindowLugPtr) XtCalloc(1, sizeof(WindowLug)); ! 495: } else { ! 496: data->buttons = (WindowLugPtr) XtRealloc( ! 497: (char *)data->buttons, ! 498: (unsigned) data->numbuttons*sizeof(WindowLug)); ! 499: } ! 500: ! 501: for (i=data->numbuttons-1; i > index; i--) ! 502: data->buttons[i] = data->buttons[i-1]; ! 503: ! 504: b.wb.x = b.wb.y = -99; ! 505: data->buttons[index] = b; ! 506: (void) XSaveContext(data->dpy, b.w, widgetContext, (caddr_t)data); ! 507: (void) XtSetGeometryHandler( ! 508: data->dpy, b.w, (XtGeometryHandler) ButtonBoxGeometryManager); ! 509: XtSetEventHandler(data->dpy, b.w, SubEventHandler, StructureNotifyMask, ! 510: (caddr_t)data); ! 511: ! 512: return(1); ! 513: } ! 514: ! 515: static DeleteButton(data, index) ! 516: WidgetData data; ! 517: int index; ! 518: { ! 519: (void) XDeleteContext(data->dpy, data->buttons[index].w, widgetContext); ! 520: (void) XtClearGeometryHandler(data->dpy, data->buttons[index].w); ! 521: XtDeleteEventHandler(data->dpy, data->buttons[index].w, SubEventHandler); ! 522: ! 523: for (index++; index<data->numbuttons; index++) ! 524: data->buttons[index-1] = data->buttons[index]; ! 525: ! 526: data->numbuttons--; ! 527: data->buttons = (WindowLugPtr) XtRealloc( ! 528: (char *)data->buttons, ! 529: (unsigned) data->numbuttons*sizeof(WindowLug)); ! 530: } ! 531: ! 532: /**************************************************************** ! 533: * ! 534: * Public Routines ! 535: * ! 536: ****************************************************************/ ! 537: ! 538: Window XtButtonBoxCreate(dpy, parent, args, argCount) ! 539: Display *dpy; ! 540: Window parent; ! 541: ArgList args; ! 542: int argCount; ! 543: { ! 544: WidgetData data; ! 545: XrmNameList names; ! 546: XrmClassList classes; ! 547: unsigned long valuemask; ! 548: XSetWindowAttributes wvals; ! 549: Boolean found; ! 550: ! 551: if (!initialized) ButtonBoxInitialize(); ! 552: ! 553: data = (WidgetData) XtMalloc(sizeof(WidgetDataRec)); ! 554: ! 555: globaldata = globalinit; ! 556: globaldata.dpy = dpy; ! 557: XtGetResources(dpy, resources, XtNumber(resources), args, argCount, parent, ! 558: "buttonBox", "ButtonBox", &names, &classes); ! 559: *data = globaldata; ! 560: if (data->width == 0) ! 561: data->width = ((data->hspace != 0) ? data->hspace : 10); ! 562: if (data->height == 0) ! 563: data->height = ((data->vspace != 0) ? data->vspace : 10); ! 564: ! 565: wvals.background_pixel = data->bgpixel; ! 566: wvals.border_pixel = data->borderpixel; ! 567: wvals.bit_gravity = NorthWestGravity; ! 568: valuemask = CWBackPixel | CWBorderPixel | CWBitGravity; ! 569: ! 570: if (data->w != NULL) { ! 571: Drawable root; ! 572: Position x, y; ! 573: unsigned int depth; ! 574: ! 575: /* set global data from window parameters */ ! 576: if (!XGetGeometry(data->dpy, data->w, &root, &x, &y, ! 577: &(data->width), &(data->height), ! 578: &(data->borderWidth), &depth)) { ! 579: data->w = NULL; ! 580: } else { ! 581: /* set window according to args */ ! 582: XChangeWindowAttributes(data->dpy, data->w, valuemask, &wvals); ! 583: } ! 584: } ! 585: if (data->w == NULL) { ! 586: data->w = XCreateWindow(data->dpy, parent, data->x, data->y, ! 587: data->width, data->height, data->borderWidth, ! 588: 0, InputOutput, (Visual *)CopyFromParent, ! 589: valuemask, &wvals); ! 590: } ! 591: ! 592: XtSetNameAndClass(data->dpy, data->w, names, classes); ! 593: XrmFreeNameList(names); ! 594: XrmFreeClassList(classes); ! 595: ! 596: /* set handler for message and destroy events */ ! 597: XtSetEventHandler(dpy, ! 598: data->w, (XtEventHandler)EventHandler, StructureNotifyMask, ! 599: (caddr_t) data); ! 600: ! 601: (void) XSaveContext(data->dpy, data->w, widgetContext, (caddr_t)data); ! 602: ! 603: /* batch add initial buttons */ ! 604: if (argCount) { ! 605: found = FALSE; ! 606: for ( ; --argCount >= 0; args++) { ! 607: if (XrmAtomsEqual(args->name, XtNbutton)) { ! 608: (void) AddButton( ! 609: data, (Window)args->value, data->numbuttons); ! 610: found = TRUE; ! 611: } ! 612: } ! 613: if (found) { ! 614: (void) TryNewLayout(data); ! 615: Layout(data); ! 616: XMapSubwindows(data->dpy, data->w); ! 617: } ! 618: } ! 619: ! 620: return (data->w); ! 621: } ! 622: ! 623: XtStatus XtButtonBoxAddButton(dpy, parent, args, argCount) ! 624: Display *dpy; ! 625: Window parent; ! 626: ArgList args; ! 627: int argCount; ! 628: { ! 629: WidgetData data; ! 630: ! 631: (void) XFindContext(dpy, parent, widgetContext, (caddr_t *)&data); ! 632: index = -1; ! 633: XtSetValues(parmResources, XtNumber(parmResources), args, argCount); ! 634: if ((index < -1) || (index > data->numbuttons)) return (0); ! 635: ! 636: /* batch add buttons */ ! 637: if (argCount) { ! 638: for ( ; --argCount >= 0; args++) { ! 639: if (XrmAtomsEqual(args->name, XtNwindow)) { ! 640: (void) AddButton( ! 641: data, ! 642: (Window)args->value, ! 643: ((index < 0) ? data->numbuttons : index)); ! 644: if (index >= 0) index++; ! 645: } ! 646: } ! 647: (void) TryNewLayout(data); ! 648: Layout(data); ! 649: XMapSubwindows(data->dpy, data->w); ! 650: } ! 651: /* ! 652: if (!AddButton(data, parms.w, index)) return(0); ! 653: ! 654: if (!TryNewLayout(data)) return(0); ! 655: Layout(data); ! 656: */ ! 657: return (1); ! 658: } ! 659: ! 660: XtStatus XtButtonBoxDeleteButton(dpy, parent, args, argCount) ! 661: Display *dpy; ! 662: Window parent; ! 663: ArgList args; ! 664: int argCount; ! 665: { ! 666: WidgetData data; ! 667: Boolean foundOne = FALSE; ! 668: int i; ! 669: ! 670: (void) XFindContext(dpy, parent, widgetContext, (caddr_t *) &data); ! 671: ! 672: index = -1; ! 673: XtSetValues(parmResources, XtNumber(parmResources), args, argCount); ! 674: if ((index < -1) || (index >= data->numbuttons)) return(0); ! 675: ! 676: if (index >= 0) { ! 677: DeleteButton(data, index); ! 678: foundOne = TRUE; ! 679: } else if (argCount) { ! 680: for ( ; --argCount >= 0; args++) { ! 681: if (XrmAtomsEqual(args->name, XtNwindow)) { ! 682: for (i=0; i<data->numbuttons; i++) { ! 683: if (data->buttons[i].w == (Window)args->value) { ! 684: DeleteButton(data, i); ! 685: foundOne = TRUE; ! 686: break; ! 687: } ! 688: } ! 689: } ! 690: } ! 691: } ! 692: ! 693: if (! foundOne) return(0); ! 694: ! 695: (void) TryNewLayout(data); /* We may want to SHRINK things! */ ! 696: Layout(data); ! 697: return (1); ! 698: } ! 699: ! 700: /* ! 701: * ! 702: * Get Attributes ! 703: * ! 704: */ ! 705: ! 706: void XtButtonBoxGetValues (dpy, window, args, argCount) ! 707: Display *dpy; ! 708: Window window; ! 709: ArgList args; ! 710: int argCount; ! 711: { ! 712: WidgetData data; ! 713: data = DataFromWindow(dpy, window); ! 714: if (data == NULL) return; ! 715: globaldata = *data; ! 716: XtGetValues(resources, XtNumber(resources), args, argCount); ! 717: } ! 718: ! 719: /* ! 720: * ! 721: * Set Attributes ! 722: * ! 723: */ ! 724: ! 725: void XtButtonBoxSetValues (dpy, window, args, argCount) ! 726: Display *dpy; ! 727: Window window; ! 728: ArgList args; ! 729: int argCount; ! 730: { ! 731: WidgetData data; ! 732: data = DataFromWindow(dpy, window); ! 733: if (data == NULL) return; ! 734: globaldata = *data; ! 735: XtSetValues(resources, XtNumber(resources), args, argCount); ! 736: *data = globaldata; ! 737: } ! 738:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.