Annotation of researchv9/X11/src/X.V11R1/clients/xmh/bbox.c, revision 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.