Annotation of researchv9/X11/src/X.V11R1/clients/xmh/bbox.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char rcs_id[] = "$Header: bbox.c,v 1.12 87/09/11 08:19:05 toddb Exp $";
                      3: #endif lint
                      4: /*
                      5:  *                       COPYRIGHT 1987
                      6:  *                DIGITAL EQUIPMENT CORPORATION
                      7:  *                    MAYNARD, MASSACHUSETTS
                      8:  *                     ALL RIGHTS RESERVED.
                      9:  *
                     10:  * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
                     11:  * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
                     12:  * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
                     13:  * ANY PURPOSE.  IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
                     14:  *
                     15:  * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
                     16:  * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
                     17:  * SET FORTH ABOVE.
                     18:  *
                     19:  *
                     20:  * Permission to use, copy, modify, and distribute this software and its
                     21:  * documentation for any purpose and without fee is hereby granted, provided
                     22:  * that the above copyright notice appear in all copies and that both that
                     23:  * copyright notice and this permission notice appear in supporting documentation,
                     24:  * and that the name of Digital Equipment Corporation not be used in advertising
                     25:  * or publicity pertaining to distribution of the software without specific,
                     26:  * written prior permission.
                     27:  */
                     28: 
                     29: /* bbox.c -- management of buttons and buttonbox's. */
                     30: 
                     31: /* This module implements a simple interface to buttonboxes, allowing a client
                     32:    to create new buttonboxes and manage their contents.  It is a layer hiding
                     33:    the toolkit interfaces. */
                     34: 
                     35: #include "xmh.h"
                     36: #include "bboxint.h"
                     37: 
                     38: 
                     39: /* Free the storage for the given button. */
                     40: 
                     41: FreeButton(button)
                     42: Button button;
                     43: {
                     44:     XtFree(button->name);
                     45:     XtFree((char *) button);
                     46: }
                     47: 
                     48: 
                     49: 
                     50: /* Handle a buttonbox getting resized.  In particular, tell the VPane widget
                     51:    the new range of legal sizes for this buttonbox. */
                     52: 
                     53: #ifdef X11
                     54: static XtEventReturnCode HandleBBoxResize(event, buttonbox)
                     55: XEvent *event;
                     56: ButtonBox buttonbox;
                     57: {
                     58:     switch (event->type) {
                     59:       case ConfigureNotify:
                     60:        if (event->xconfigure.height != buttonbox->maxheight) {
                     61:            buttonbox->maxheight = event->xconfigure.height;
                     62:            XtVPanedSetMinMax(DISPLAY buttonbox->scrn->window,
                     63:                              buttonbox->outer,
                     64:                              buttonbox->fullsized ? buttonbox->maxheight : 5,
                     65:                              buttonbox->maxheight);
                     66:        }
                     67:        return XteventHandled;
                     68:       case DestroyNotify:
                     69:        XtFree((char *) buttonbox->button);
                     70:        XtFree((char *) buttonbox);
                     71:        return XteventHandled;
                     72:     }
                     73:     return XteventNotHandled;
                     74: }
                     75: #endif X11
                     76: 
                     77: #ifdef X10
                     78: static XtEventReturnCode HandleBBoxResize(event, buttonbox)
                     79: XExposeEvent *event;
                     80: ButtonBox buttonbox;
                     81: {
                     82:     switch (event->type) {
                     83:       case ResizeWindow:
                     84:        if (event->height != buttonbox->maxheight) {
                     85:            buttonbox->maxheight = event->height;
                     86:            XtVPanedSetMinMax(DISPLAY buttonbox->scrn->window,
                     87:                              buttonbox->outer,
                     88:                              buttonbox->fullsized ? buttonbox->maxheight : 5,
                     89:                              buttonbox->maxheight);
                     90:        }
                     91:        return XteventHandled;
                     92:       case DestroyWindow:
                     93:        XtFree((char *) buttonbox->button);
                     94:        XtFree((char *) buttonbox);
                     95:        return XteventHandled;
                     96:     }
                     97:     return XteventNotHandled;
                     98: }
                     99: #endif X10    
                    100: 
                    101: 
                    102: /* Create a new button box.  The window for it will be a child of the given
                    103:    scrn's window, and it will be added to the scrn's vpane. */
                    104: 
                    105: ButtonBox BBoxRadioCreate(scrn, position, name, radio)
                    106:   Scrn scrn;
                    107:   int position;                        /* Position to put it in the vpane. */
                    108:   char *name;                  /* Name of the buttonbox widget. */
                    109:   Button *radio;               /* Pointer to place to store which radio
                    110:                                   button is active. */
                    111: {
                    112:     static Arg arglist[] = {
                    113:        {XtNname, (XtArgVal)NULL},
                    114:        {XtNwidth, NULL},
                    115:        {XtNinnerWidth, NULL},
                    116:        {XtNallowVert, (XtArgVal)TRUE},
                    117:     };
                    118:     static Arg arglist2[] = {
                    119:        {XtNwidth, NULL},
                    120:     };
                    121:     int width, height;
                    122:     ButtonBox buttonbox;
                    123: 
                    124:     arglist[0].value = (XtArgVal)name;
                    125:     GetWindowSize(scrn->window, &width, &height);
                    126:     arglist[1].value = arglist[2].value = arglist2[0].value = (XtArgVal) width;
                    127:     buttonbox = (ButtonBox) XtMalloc(sizeof(ButtonBoxRec));
                    128:     bzero((char *)buttonbox, sizeof(ButtonBoxRec));
                    129:     buttonbox->updatemode = TRUE;
                    130:     buttonbox->scrn = scrn;
                    131:     buttonbox->outer = XtScrolledWindowCreate(DISPLAY scrn->window, arglist,
                    132:                                              XtNumber(arglist));
                    133:     buttonbox->inner =
                    134:        XtButtonBoxCreate(DISPLAY XtScrolledWindowGetFrame(DISPLAY
                    135:                                                           buttonbox->outer),
                    136:                          arglist2, XtNumber(arglist2));
                    137:     XtScrolledWindowSetChild(DISPLAY buttonbox->outer, buttonbox->inner);
                    138:     buttonbox->numbuttons = 0;
                    139:     buttonbox->button = (Button *) XtMalloc(1);
                    140:     XtVPanedWindowAddPane(DISPLAY scrn->window, buttonbox->outer, position, 5,
                    141:                          5, FALSE);
                    142:     buttonbox->maxheight = 5;
                    143:     buttonbox->radio = radio;
                    144:     if (radio) *radio = NULL;
                    145:     XtSetEventHandler(DISPLAY buttonbox->inner, HandleBBoxResize,
                    146: #ifdef X11
                    147:                      StructureNotifyMask,
                    148: #endif
                    149: #ifdef X10
                    150:                      ExposeWindow,
                    151: #endif
                    152:                      (caddr_t) buttonbox);
                    153:     return buttonbox;
                    154: }
                    155: 
                    156: 
                    157: 
                    158: /* Create a new buttonbox which does not manage radio buttons. */
                    159: 
                    160: ButtonBox BBoxCreate(scrn, position, name)
                    161:   Scrn scrn;
                    162:   int position;
                    163:   char *name;
                    164: {
                    165:     return BBoxRadioCreate(scrn, position, name, (Button *)NULL);
                    166: }
                    167: 
                    168: 
                    169: 
                    170: /* Set the current button in a radio buttonbox. */
                    171: 
                    172: void BBoxSetRadio(buttonbox, button)
                    173: ButtonBox buttonbox;
                    174: Button button;
                    175: {
                    176:     if (buttonbox->radio && *(buttonbox->radio) != button) {
                    177:        if (*(buttonbox->radio)) FlipColors(*(buttonbox->radio));
                    178:        FlipColors(button);
                    179:        *(buttonbox->radio) = button;
                    180:     }
                    181: }
                    182: 
                    183: 
                    184: 
                    185: /* Some buttons have been added to the buttonbox structure; go and actually
                    186:    add the button widgets to the buttonbox widget.  (It is much more
                    187:    efficient to add several buttons at once rather than one at a time.) */
                    188: 
                    189: static ProcessAddedButtons(buttonbox)
                    190: ButtonBox buttonbox;
                    191: {
                    192:     int i, position, index;
                    193:     ArgList arglist, ptr;
                    194:     Button button;
                    195:     if (buttonbox->updatemode == FALSE) {
                    196:        buttonbox->needsadding = TRUE;
                    197:        return;
                    198:     }
                    199:     position = 0;
                    200:     ptr = arglist = (ArgList)
                    201:        XtMalloc((unsigned)sizeof(Arg) * (buttonbox->numbuttons + 1));
                    202:     for (i=0 ; i<buttonbox->numbuttons ; i++) {
                    203:        button = buttonbox->button[i];
                    204:        if (button->needsadding) {
                    205:            if (ptr == arglist) {
                    206:                ptr->name = XtNindex;
                    207:                index = position;
                    208:                ptr->value = (XtArgVal)index;
                    209:                ptr++;
                    210:            }
                    211:            ptr->name = XtNwindow;
                    212:            ptr->value = (XtArgVal)(button->window);
                    213:            ptr++;
                    214:            button->needsadding = FALSE;
                    215:        } else if (ptr != arglist) {
                    216:            (void)XtButtonBoxAddButton(DISPLAY buttonbox->inner,
                    217:                                       arglist, ptr-arglist);
                    218:            ptr = arglist;
                    219:        }
                    220:        position++;
                    221:     }
                    222:     if (ptr != arglist) {
                    223:        (void)XtButtonBoxAddButton(DISPLAY buttonbox->inner,
                    224:                                   arglist, ptr-arglist);
                    225:     }
                    226:     XtFree((char *) arglist);
                    227:     buttonbox->needsadding = FALSE;
                    228: }
                    229: 
                    230: 
                    231: 
                    232: /* Create a new button, and add it to a buttonbox. */
                    233: 
                    234: void BBoxAddButton(buttonbox, name, func, position, enabled)
                    235:   ButtonBox buttonbox;
                    236:   char *name;                  /* Name of button. */
                    237:   void (*func)();              /* Func to call when button pressed. */
                    238:   int position;                        /* Position to put button in box. */
                    239:   int enabled;                 /* Whether button is initially enabled. */
                    240: {
                    241:     extern void DoButtonPress();
                    242:     Button button;
                    243:     int i;
                    244:     static Arg arglist[] = {
                    245:        {XtNname, NULL},
                    246:        {XtNfunction, (XtArgVal)DoButtonPress},
                    247:        {XtNparameter, NULL},
                    248:     };
                    249:     if (position > buttonbox->numbuttons) position = buttonbox->numbuttons;
                    250:     buttonbox->numbuttons++;
                    251:     buttonbox->button = (Button *)
                    252:        XtRealloc((char *) buttonbox->button,
                    253:                  (unsigned) buttonbox->numbuttons * sizeof(Button));
                    254:     for (i=buttonbox->numbuttons-1 ; i>position ; i--)
                    255:        buttonbox->button[i] = buttonbox->button[i-1];
                    256:     button = buttonbox->button[position] =
                    257:        (Button) XtMalloc(sizeof(ButtonRec));
                    258:     bzero((char *) button, sizeof(ButtonRec));
                    259:     arglist[0].value = (XtArgVal)name;
                    260:     arglist[2].value = (XtArgVal)button;
                    261:     button->buttonbox = buttonbox;
                    262:     button->name = MallocACopy(name);
                    263:     button->window = XtCommandCreate(DISPLAY buttonbox->inner, arglist,
                    264:                                     XtNumber(arglist));
                    265:     button->func = func;
                    266:     button->needsadding = TRUE;
                    267:     button->enabled = TRUE;
                    268:     if (!enabled) BBoxDisable(button);
                    269:     ProcessAddedButtons(buttonbox);
                    270:     if (buttonbox->radio && *(buttonbox->radio) == NULL) {
                    271:        *(buttonbox->radio) = button;
                    272:        FlipColors(button);
                    273:     }
                    274: }
                    275: 
                    276: 
                    277: 
                    278: /* Remove the given button from its buttonbox.  The button widget is
                    279:    destroyed.  If it was the current button in a radio buttonbox, then the
                    280:    current button becomes the first button in the box. */
                    281: 
                    282: void BBoxDeleteButton(button)
                    283: Button button;
                    284: {
                    285:     ButtonBox buttonbox = button->buttonbox;
                    286:     int i, found, reradio;
                    287:     static Arg arglist[] = {
                    288:        {XtNwindow, (XtArgVal)NULL}
                    289:     };
                    290:     found = FALSE;
                    291:     for (i=0 ; i<buttonbox->numbuttons; i++) {
                    292:        if (found) buttonbox->button[i-1] = buttonbox->button[i];
                    293:        else if (buttonbox->button[i] == button) {
                    294:            found = TRUE;
                    295:            arglist[0].value = (XtArgVal) button->window;
                    296:            (void)XtButtonBoxDeleteButton(DISPLAY buttonbox->inner,
                    297:                                          arglist, XtNumber(arglist));
                    298:            QXDestroyWindow(theDisplay, button->window);
                    299:            (void) XtSendDestroyNotify(DISPLAY button->window);
                    300:            reradio = (buttonbox->radio && *(buttonbox->radio) == button);
                    301:            FreeButton(button);
                    302:        }
                    303:     }
                    304:     if (found) {
                    305:        buttonbox->numbuttons--;
                    306:        if (reradio) {
                    307:            *(buttonbox->radio) = NULL;
                    308:            if (buttonbox->numbuttons)
                    309:                BBoxSetRadio(buttonbox, buttonbox->button[0]);
                    310:        }
                    311:     }
                    312: }
                    313:            
                    314: 
                    315: 
                    316: /* Enable or disable the given command button widget. */
                    317: 
                    318: static void SendEnableMsg(window, value)
                    319: Window window;
                    320: int value;                     /* TRUE for enable, FALSE for disable. */
                    321: {
                    322:     static Arg arglist[] = {XtNsensitive, NULL};
                    323:     arglist[0].value = (XtArgVal) value;
                    324:     XtCommandSetValues(DISPLAY window, arglist, XtNumber(arglist));
                    325: }
                    326: 
                    327: 
                    328: 
                    329: /* Enable the given button (if it's not already). */
                    330: 
                    331: void BBoxEnable(button)
                    332: Button button;
                    333: {
                    334:     if (!button->enabled) {
                    335:        button->enabled = TRUE;
                    336:        SendEnableMsg(button->window, TRUE);
                    337:     }
                    338: }
                    339: 
                    340: 
                    341: 
                    342: /* Disable the given button (if it's not already). */
                    343: 
                    344: void BBoxDisable(button)
                    345: Button button;
                    346: {
                    347:     if (button->enabled) {
                    348:        button->enabled = FALSE;
                    349:        SendEnableMsg(button->window, FALSE);
                    350:     }
                    351: }
                    352: 
                    353: 
                    354: /* Given a buttonbox and a button name, find the button in the box with that
                    355:    short name. */
                    356: 
                    357: Button BBoxFindButtonNamed(buttonbox, name)
                    358: ButtonBox buttonbox;
                    359: char *name;
                    360: {
                    361:     int i;
                    362:     for (i=0 ; i<buttonbox->numbuttons; i++)
                    363:        if (strcmp(name, buttonbox->button[i]->name) == 0)
                    364:            return buttonbox->button[i];
                    365:     return NULL;
                    366: }
                    367: 
                    368: 
                    369: 
                    370: /* Return the nth button in the given buttonbox. */
                    371: 
                    372: Button BBoxButtonNumber(buttonbox, n)
                    373: ButtonBox buttonbox;
                    374: int n;
                    375: {
                    376:     return buttonbox->button[n];
                    377: }
                    378: 
                    379: 
                    380: 
                    381: /* Return how many buttons are in a buttonbox. */
                    382: 
                    383: int BBoxNumButtons(buttonbox)
                    384: ButtonBox buttonbox;
                    385: {
                    386:     return buttonbox->numbuttons;
                    387: }
                    388: 
                    389: 
                    390: /* Given a button, return its name. */
                    391: 
                    392: char *BBoxNameOfButton(button)
                    393: Button button;
                    394: {
                    395:     return button->name;
                    396: }
                    397: 
                    398: 
                    399: 
                    400: /* The client calls this routine before doing massive updates to a buttonbox.
                    401:    It then must call BBoxStartUpdate when it's finished.  This allows us to
                    402:    optimize things.  Right now, the only optimization performed is to batch
                    403:    together requests to add buttons to a buttonbox. */
                    404: 
                    405: void BBoxStopUpdate(buttonbox)
                    406: ButtonBox buttonbox;
                    407: {
                    408:     buttonbox->updatemode = FALSE;
                    409: }
                    410: 
                    411: 
                    412: 
                    413: /* The client has finished its massive updates; go and handle any batched
                    414:    requests. */
                    415: 
                    416: void BBoxStartUpdate(buttonbox)
                    417: ButtonBox buttonbox;
                    418: {
                    419:     buttonbox->updatemode = TRUE;
                    420:     if (buttonbox->needsadding) ProcessAddedButtons(buttonbox);
                    421: }
                    422: 
                    423: 
                    424: 
                    425: /* Set things to always display the entire contents of this buttonbox.  In
                    426:    otherwords, tells the VPane to not let the user make this pane any smaller
                    427:    than the buttonbox. */
                    428: 
                    429: void BBoxForceFullSize(buttonbox)
                    430: ButtonBox buttonbox;
                    431: {
                    432: #ifdef X10     /* X10 toolkit doesn't have magic configurenotify events */
                    433:     WindowInfo info;
                    434:     XQueryWindow(buttonbox->inner, &info);
                    435:     buttonbox->maxheight = info.height;
                    436: #endif
                    437:     XtVPanedSetMinMax(DISPLAY buttonbox->scrn->window, buttonbox->outer, 
                    438:                      buttonbox->maxheight, buttonbox->maxheight);
                    439:     buttonbox->fullsized = TRUE;
                    440: }
                    441: 
                    442: 
                    443: /* Set things to allow the user to show only part of a buttonbox.  This is the
                    444:    default action. */
                    445: 
                    446: void BBoxAllowAnySize(buttonbox)
                    447: ButtonBox buttonbox;
                    448: {
                    449: #ifdef X10
                    450:     BBoxForceFullSize(buttonbox); /* VERY hackish; works only because of the
                    451:                                     limited way I use BBoxForceFullSize.%%% */
                    452: #endif
                    453:     XtVPanedSetMinMax(DISPLAY buttonbox->scrn->window, buttonbox->outer, 
                    454:                      5, buttonbox->maxheight);
                    455:     buttonbox->fullsized = FALSE;
                    456: }
                    457: 
                    458: 
                    459: 
                    460: /* Destroy the given buttonbox. */
                    461: 
                    462: void BBoxDeleteBox(buttonbox)
                    463: ButtonBox buttonbox;
                    464: {
                    465:     if (buttonbox->radio) *(buttonbox->radio) = NULL;
                    466:     QXDestroyWindow(theDisplay, buttonbox->outer);
                    467:     (void) XtSendDestroyNotify(DISPLAY buttonbox->outer);
                    468: }
                    469: 
                    470: 
                    471: 
                    472: /* Change the borderwidth of the given button. */
                    473: 
                    474: void BBoxChangeBorderWidth(button, borderWidth)
                    475: Button button;
                    476: unsigned int borderWidth;
                    477: {
                    478: #ifdef X11
                    479:     XSetWindowBorderWidth(DISPLAY button->window, borderWidth);
                    480: #endif
                    481: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.