Annotation of GNUtools/emacs/oldXMenu/Internal.c, revision 1.1

1.1     ! root        1: #include "copyright.h"
        !             2: 
        !             3: /* $Header: Internal.c,v 1.12 87/12/20 12:05:22 rws Exp $ */
        !             4: /* Copyright    Massachusetts Institute of Technology    1985  */
        !             5: 
        !             6: /*
        !             7:  * XMenu:      MIT Project Athena, X Window system menu package
        !             8:  *
        !             9:  *     XMenuInternal.c - XMenu internal (not user visable) routines.
        !            10:  *
        !            11:  *     Author:         Tony Della Fera, DEC
        !            12:  *                     November, 1985
        !            13:  *
        !            14:  */
        !            15: 
        !            16: #include "XMenuInt.h"
        !            17: 
        !            18: /*
        !            19:  * Toggle color macro.
        !            20:  */
        !            21: #define toggle_color(x) \
        !            22:        ((x) == menu->bkgnd_color ? menu->s_frg_color : menu->bkgnd_color)
        !            23: 
        !            24: /*
        !            25:  * Internal Window creation queue sizes.
        !            26:  */
        !            27: #define S_QUE_SIZE     300
        !            28: #define P_QUE_SIZE     20
        !            29: #define BUFFER_SIZE    (S_QUE_SIZE >= P_QUE_SIZE ? S_QUE_SIZE : P_QUE_SIZE)
        !            30: 
        !            31: 
        !            32: /*
        !            33:  * XMWinQue - Internal window creation queue datatype.
        !            34:  */
        !            35: typedef struct _xmwinquedef {
        !            36:     int sq_size;
        !            37:     XMSelect *sq[S_QUE_SIZE];
        !            38:     XMSelect **sq_ptr;
        !            39:     int pq_size;
        !            40:     XMPane *pq[P_QUE_SIZE];
        !            41:     XMPane **pq_ptr;
        !            42: } XMWinQue;
        !            43: 
        !            44: /*
        !            45:  * _XMWinQue - Internal static window creation queue.
        !            46:  */
        !            47: static Bool _XMWinQueIsInit = False;
        !            48: static XMWinQue _XMWinQue;
        !            49: 
        !            50: /*
        !            51:  * _XMErrorCode - Global XMenu error code.
        !            52:  */
        !            53: int _XMErrorCode = XME_NO_ERROR; 
        !            54: /*
        !            55:  * _XMErrorList - Global XMenu error code discription strings.
        !            56:  */
        !            57: char *
        !            58: _XMErrorList[XME_CODE_COUNT] = {
        !            59:     "No error",                                /* XME_NO_ERROR */
        !            60:     "Menu not initialized",            /* XME_NOT_INIT */
        !            61:     "Argument out of bounds",          /* XME_ARG_BOUNDS */
        !            62:     "Pane not found",                  /* XME_P_NOT_FOUND */
        !            63:     "Selection not found",             /* XME_S_NOT_FOUND */
        !            64:     "Invalid menu style parameter",    /* XME_STYLE_PARAM */
        !            65:     "Unable to grab mouse",            /* XME_GRAB_MOUSE */
        !            66:     "Unable to interpret locator",     /* XME_INTERP_LOC */
        !            67:     "Unable to calloc memory",         /* XME_CALLOC */
        !            68:     "Unable to create XAssocTable",    /* XME_CREATE_ASSOC */
        !            69:     "Unable to store bitmap",          /* XME_STORE_BITMAP */
        !            70:     "Unable to make tile pixmaps",     /* XME_MAKE_TILES */
        !            71:     "Unable to make pixmap",           /* XME_MAKE_PIXMAP */
        !            72:     "Unable to create cursor",         /* XME_CREATE_CURSOR */
        !            73:     "Unable to open font",             /* XME_OPEN_FONT */
        !            74:     "Unable to create windows",                /* XME_CREATE_WINDOW */
        !            75:     "Unable to create transparencies", /* XME_CREATE_TRANSP */
        !            76: };
        !            77: 
        !            78: /*
        !            79:  * _XMEventHandler - Internal event handler variable.
        !            80:  */
        !            81: int (*_XMEventHandler)() = NULL;
        !            82: 
        !            83: 
        !            84: 
        !            85: /*
        !            86:  * _XMWinQueInit - Internal routine to initialize the window
        !            87:  *                queue.
        !            88:  */
        !            89: _XMWinQueInit()
        !            90: {
        !            91:     /*
        !            92:      * If the queue is not initialized initialize it.
        !            93:      */
        !            94:     if (!_XMWinQueIsInit) {
        !            95:        /*
        !            96:         * Blank the queue structure.
        !            97:         */
        !            98:        bzero(&_XMWinQue, sizeof(XMWinQue));
        !            99: 
        !           100:        /*
        !           101:         * Initialize the next free location pointers.
        !           102:         */
        !           103:        _XMWinQue.sq_ptr = _XMWinQue.sq;
        !           104:        _XMWinQue.pq_ptr = _XMWinQue.pq;
        !           105:     }
        !           106: }
        !           107: 
        !           108: 
        !           109: 
        !           110: /*
        !           111:  * _XMWinQueAddPane - Internal routine to add a pane to the pane
        !           112:  *                   window queue.
        !           113:  */
        !           114: int
        !           115: _XMWinQueAddPane(display, menu, p_ptr)
        !           116:     register Display *display;
        !           117:     register XMenu *menu;      /* Menu being manipulated. */
        !           118:     register XMPane *p_ptr;    /* XMPane being queued. */
        !           119: {
        !           120:     /*
        !           121:      * If the queue is currently full then flush it.
        !           122:      */
        !           123:     if (_XMWinQue.pq_size == P_QUE_SIZE) {
        !           124:        if (_XMWinQueFlush(display, menu, 0, 0) == _FAILURE) return(_FAILURE);
        !           125:     }
        !           126: 
        !           127:     /*
        !           128:      * Insert the new XMPane pointer and increment the queue pointer
        !           129:      * and the queue size.
        !           130:      */
        !           131:     *_XMWinQue.pq_ptr = p_ptr;
        !           132:     _XMWinQue.pq_ptr++;
        !           133:     _XMWinQue.pq_size++;
        !           134: 
        !           135:     /*
        !           136:      * All went well, return successfully.
        !           137:      */
        !           138:     _XMErrorCode = XME_NO_ERROR;
        !           139:     return(_SUCCESS);
        !           140: }
        !           141: 
        !           142: 
        !           143: 
        !           144: /*
        !           145:  * _XMWinQueAddSelection - Internal routine to add a selection to
        !           146:  *                        the selection window queue.
        !           147:  */
        !           148: int
        !           149: _XMWinQueAddSelection(display, menu, s_ptr)
        !           150:     register Display *display;
        !           151:     register XMenu *menu;      /* Menu being manipulated. */
        !           152:     register XMSelect *s_ptr;  /* XMSelection being queued. */
        !           153: {
        !           154:     /*
        !           155:      * If this entry will overflow the queue then flush it.
        !           156:      */
        !           157:     if (_XMWinQue.sq_size == S_QUE_SIZE) {
        !           158:        if (_XMWinQueFlush(display, menu, 0, 0) == _FAILURE) return(_FAILURE);
        !           159:     }
        !           160: 
        !           161:     /*
        !           162:      * Insert the new XMSelect pointer and increment the queue pointer
        !           163:      * and the queue size.
        !           164:      */
        !           165:     *_XMWinQue.sq_ptr = s_ptr;
        !           166:     _XMWinQue.sq_ptr++;
        !           167:     _XMWinQue.sq_size++;
        !           168: 
        !           169:     /*
        !           170:      * All went well, return successfully.
        !           171:      */
        !           172:     _XMErrorCode = XME_NO_ERROR;
        !           173:     return(_SUCCESS);
        !           174: }
        !           175: 
        !           176: 
        !           177: 
        !           178: /*
        !           179:  * _XMWinQueFlush - Internal routine to flush the pane and
        !           180:  *                 selection window queues.
        !           181:  */
        !           182: int
        !           183: _XMWinQueFlush(display, menu, pane, select)
        !           184:     register Display *display;
        !           185:     register XMenu *menu;              /* Menu being manipulated. */
        !           186:     register XMPane *pane;             /* Current pane. */
        !           187: {
        !           188:     register int pq_index;             /* Pane queue index. */
        !           189:     register int sq_index;             /* Selection queue index. */
        !           190:     register XMPane *p_ptr;            /* XMPane pointer. */
        !           191:     register XMSelect *s_ptr;          /* XMSelect pointer. */
        !           192:     unsigned long valuemask;           /* Which attributes to set. */
        !           193:     XSetWindowAttributes *attributes;  /* Attributes to be set. */
        !           194: 
        !           195:     /*
        !           196:      * If the pane window queue is not empty...
        !           197:      */
        !           198:     
        !           199:     if (_XMWinQue.pq_size > 0) {
        !           200:        /*
        !           201:         * set up attributes for pane window to be created.
        !           202:         */
        !           203:        valuemask = (CWBackPixmap | CWBorderPixel | CWOverrideRedirect);
        !           204:        attributes = (XSetWindowAttributes *)malloc(sizeof(XSetWindowAttributes));
        !           205:        attributes->border_pixel = menu->p_bdr_color;
        !           206:        attributes->background_pixmap = menu->inact_pixmap;
        !           207:        attributes->override_redirect = True;
        !           208:        
        !           209:        /*
        !           210:         * Create all the pending panes in order, so that the
        !           211:         * current pane will be on top, with the others
        !           212:         * stacked appropriately under it.
        !           213:         */
        !           214:        for (pq_index = _XMWinQue.pq_size - 1;
        !           215:             pq_index >= 0;
        !           216:             pq_index--) 
        !           217:          {
        !           218:              p_ptr = _XMWinQue.pq[pq_index];  /* Retrieve next pane. */
        !           219:              if (p_ptr == pane) break;
        !           220:              p_ptr->window = XCreateWindow(display,
        !           221:                                            menu->parent,
        !           222:                                            p_ptr->window_x,
        !           223:                                            p_ptr->window_y,
        !           224:                                            p_ptr->window_w,
        !           225:                                            p_ptr->window_h,
        !           226:                                            menu->p_bdr_width,
        !           227:                                            CopyFromParent,
        !           228:                                            InputOutput,
        !           229:                                            CopyFromParent,
        !           230:                                            valuemask,
        !           231:                                            attributes);
        !           232:              XMakeAssoc(display, menu->assoc_tab, p_ptr->window, p_ptr);
        !           233:              XSelectInput(display, p_ptr->window, menu->p_events);
        !           234:          }
        !           235:        for (pq_index = 0;
        !           236:             pq_index < _XMWinQue.pq_size;
        !           237:             pq_index++) 
        !           238:          {
        !           239:              p_ptr = _XMWinQue.pq[pq_index];   /* Retrieve next pane. */
        !           240:              p_ptr->window = XCreateWindow(display,
        !           241:                                            menu->parent,
        !           242:                                            p_ptr->window_x,
        !           243:                                            p_ptr->window_y,
        !           244:                                            p_ptr->window_w,
        !           245:                                            p_ptr->window_h,
        !           246:                                            menu->p_bdr_width,
        !           247:                                            CopyFromParent,
        !           248:                                            InputOutput,
        !           249:                                            CopyFromParent,
        !           250:                                            valuemask,
        !           251:                                            attributes);
        !           252:              XMakeAssoc(display, menu->assoc_tab, p_ptr->window, p_ptr);
        !           253:              XSelectInput(display, p_ptr->window, menu->p_events);
        !           254:              if (p_ptr == pane) break;
        !           255:        }
        !           256: 
        !           257:        /*
        !           258:         * Reset the pane queue pointer and size.
        !           259:         */
        !           260:        _XMWinQue.pq_size = 0;
        !           261:        _XMWinQue.pq_ptr = _XMWinQue.pq;
        !           262:     }
        !           263: 
        !           264:     /*
        !           265:      * If the selection window queue is not empty...
        !           266:      */
        !           267:     
        !           268:     if (_XMWinQue.sq_size > 0) {
        !           269: 
        !           270:        for (sq_index = 0; sq_index < _XMWinQue.sq_size; sq_index++) {
        !           271:            /*
        !           272:             * Retrieve the XMSelect pointer.
        !           273:             */
        !           274:            s_ptr = _XMWinQue.sq[sq_index];
        !           275:            s_ptr->window = XCreateWindow(display,
        !           276:                                   s_ptr->parent_p->window,
        !           277:                                   s_ptr->window_x,
        !           278:                                   s_ptr->window_y,
        !           279:                                   s_ptr->window_w,
        !           280:                                   s_ptr->window_h,
        !           281:                                   0,                /* border width*/
        !           282:                                   CopyFromParent,
        !           283:                                   InputOnly,
        !           284:                                   CopyFromParent,
        !           285:                                   0,
        !           286:                                   attributes);
        !           287:            
        !           288:            /*
        !           289:             * Insert the new window id and its
        !           290:             * associated XMSelect structure into the 
        !           291:             * assoction table.
        !           292:             */
        !           293:            XMakeAssoc(display, menu->assoc_tab, s_ptr->window, s_ptr);
        !           294:            XSelectInput(display, s_ptr->window, menu->s_events);
        !           295:        }
        !           296: 
        !           297:        /*
        !           298:         * Reset the selection queue pointer and size.
        !           299:         */
        !           300:        _XMWinQue.sq_size = 0;
        !           301:        _XMWinQue.sq_ptr = _XMWinQue.sq;
        !           302:     }
        !           303: 
        !           304:     /*
        !           305:      * Flush X's internal queues.
        !           306:      */
        !           307:     XFlush(display);
        !           308: 
        !           309:     /*
        !           310:      * All went well, return successfully.
        !           311:      */
        !           312:     _XMErrorCode = XME_NO_ERROR;
        !           313:     return(_SUCCESS);
        !           314: }
        !           315: 
        !           316: 
        !           317: 
        !           318: /*
        !           319:  * _XMGetPanePtr -     Given a menu pointer and a pane index number, return
        !           320:  *                     a pane pointer that points to the indexed pane.
        !           321:  */
        !           322: XMPane *
        !           323: _XMGetPanePtr(menu, p_num)
        !           324:     register XMenu *menu;      /* Menu to find the pane in. */
        !           325:     register int p_num;                /* Index number of pane to find. */
        !           326: {
        !           327:     register XMPane *p_ptr;    /* Pane pointer to be returned. */
        !           328:     register int i;            /* Loop counter. */
        !           329: 
        !           330:     /*
        !           331:      * Is the pane number out of range?
        !           332:      */
        !           333:     if ((p_num < 0) || (p_num > (menu->p_count - 1))) {
        !           334:        _XMErrorCode = XME_P_NOT_FOUND;
        !           335:        return(NULL);
        !           336:     }
        !           337: 
        !           338:     /*
        !           339:      * Find the right pane.
        !           340:      */
        !           341:     p_ptr = menu->p_list->next;
        !           342:     for (i = 0; i < p_num; i++) p_ptr = p_ptr->next;
        !           343: 
        !           344:     /*
        !           345:      * Return successfully.
        !           346:      */
        !           347:     _XMErrorCode = XME_NO_ERROR;
        !           348:     return(p_ptr);
        !           349: }
        !           350: 
        !           351: 
        !           352: 
        !           353: /*
        !           354:  * _XMGetSelectionPtr -        Given pane pointer and a selection index number,
        !           355:  *                     return a selection pointer that points to the
        !           356:  *                     indexed selection.
        !           357:  */
        !           358: XMSelect *
        !           359: _XMGetSelectionPtr(p_ptr, s_num)
        !           360:     register XMPane *p_ptr;    /* Pane to find the selection in. */
        !           361:     register int s_num;                /* Index number of the selection to find. */
        !           362: {
        !           363:     register XMSelect *s_ptr;  /* Selection pointer to be returned. */
        !           364:     register int i;            /* Loop counter. *./
        !           365:     
        !           366:     /*
        !           367:      * Is the selection number out of range?
        !           368:      */
        !           369:     if ((s_num < 0) || (s_num > (p_ptr->s_count - 1))) {
        !           370:        _XMErrorCode = XME_S_NOT_FOUND;
        !           371:        return(NULL);
        !           372:     }
        !           373: 
        !           374:     /*
        !           375:      * Find the right selection.
        !           376:      */
        !           377:     s_ptr = p_ptr->s_list->next;
        !           378:     for (i = 0; i < s_num; i++) s_ptr = s_ptr->next;
        !           379: 
        !           380:     /*
        !           381:      * Return successfully.
        !           382:      */
        !           383:     _XMErrorCode = XME_NO_ERROR;
        !           384:     return(s_ptr);
        !           385: }
        !           386: 
        !           387: 
        !           388: 
        !           389: /*
        !           390:  * _XMRecomputeGlobals - Internal subroutine to recompute menu wide
        !           391:  *                      global values.
        !           392:  */
        !           393: _XMRecomputeGlobals(display, menu)
        !           394:     register Display *display; /*X11 display variable. */      
        !           395:     register XMenu *menu;      /* Menu object to compute from. */
        !           396: {
        !           397:     register XMPane *p_ptr;    /* Pane pointer. */
        !           398:     register XMSelect *s_ptr;  /* Selection pointer. */
        !           399: 
        !           400:     register int max_p_label = 0;      /* Maximum pane label width. */
        !           401:     register int max_s_label = 0;      /* Maximum selection label width. */
        !           402:     register int s_count = 0;          /* Maximum selection count. */
        !           403: 
        !           404:     int p_s_pad;               /* Pane <-> selection padding. */
        !           405:     int p_s_diff;              /* Pane <-> selection seperation. */
        !           406: 
        !           407:     int p_height;              /* Pane window height. */
        !           408:     int p_width;               /* Pane window width. */
        !           409:     int s_width;               /* Selection window width. */
        !           410: 
        !           411:     int screen;                        /* DefaultScreen holder. */
        !           412:     
        !           413:     /*
        !           414:      * For each pane...
        !           415:      */
        !           416:     for (
        !           417:        p_ptr = menu->p_list->next;
        !           418:        p_ptr != menu->p_list;
        !           419:        p_ptr = p_ptr->next
        !           420:     ){
        !           421:        
        !           422:        /*
        !           423:         * Recompute maximum pane label width.
        !           424:         */
        !           425:        max_p_label = max(max_p_label, p_ptr->label_width);
        !           426: 
        !           427:        /*
        !           428:         * Recompute maximum selection count. 
        !           429:         */
        !           430:        s_count = max(s_count, p_ptr->s_count);
        !           431: 
        !           432:        /*
        !           433:         * For each selection in the current pane...
        !           434:         */
        !           435:        for (
        !           436:            s_ptr = p_ptr->s_list->next;
        !           437:            s_ptr != p_ptr->s_list;
        !           438:            s_ptr = s_ptr->next
        !           439:        ){
        !           440: 
        !           441:            /*
        !           442:             * Recompute maximum selection label width.
        !           443:             */
        !           444:            max_s_label = max(max_s_label, s_ptr->label_width);
        !           445:        }
        !           446:     }
        !           447: 
        !           448:     /*
        !           449:      * Recompute pane height.
        !           450:      */
        !           451:     p_height = (menu->flag_height << 1) + (menu->s_y_off * s_count);
        !           452: 
        !           453:     /*
        !           454:      * Recompute horizontal padding between the pane window and the
        !           455:      * selection windows.
        !           456:      */
        !           457:     p_s_pad = menu->p_x_off << 1;
        !           458: 
        !           459:     /*
        !           460:      * Recompute pane and selection window widths.
        !           461:      * This is done by first computing the window sizes from the maximum
        !           462:      * label widths.  If the spacing between the selection window and the
        !           463:      * containing pane window is less than the pane selection padding value
        !           464:      * (twice the pane X offset) then change the size of the pane to be
        !           465:      * the size of the selection window plus the padding.  If, however the
        !           466:      * spacing between the selection window and the containing pane window
        !           467:      * is more than the pane selection padding value increase the size of
        !           468:      * the selection to its maximum possible value (the pane width minus
        !           469:      * the pane selection padding value).
        !           470:      */
        !           471:     p_width = max_p_label + p_s_pad;
        !           472:     s_width = max_s_label + (menu->s_fnt_pad << 1) + (menu->s_bdr_width << 1);
        !           473:     p_s_diff = p_width - s_width;
        !           474:     if (p_s_diff < p_s_pad) {
        !           475:        p_width = s_width + p_s_pad;
        !           476:     }
        !           477:     else if (p_s_diff > p_s_pad) {
        !           478:        s_width = p_width - p_s_pad;
        !           479:     }
        !           480: 
        !           481:     /*
        !           482:      * Reset menu wide global values.
        !           483:      */
        !           484:     menu->s_count = s_count;
        !           485:     menu->p_height = p_height;
        !           486:     menu->p_width = p_width;
        !           487:     menu->s_width = s_width;
        !           488: 
        !           489:     /* 
        !           490:      * Ensure that the origin of the menu is placed so that
        !           491:      * None of the panes ore selections are off the screen.
        !           492:      */
        !           493:     screen = DefaultScreen(display);
        !           494:     if (menu->x_pos + menu->width > DisplayWidth(display, screen))
        !           495:            menu->x_pos = DisplayWidth(display, screen) - menu->width;
        !           496:     else if (menu->x_pos < 0) menu->x_pos = 0;
        !           497:     if(menu->y_pos + menu->height > DisplayHeight(display, screen))
        !           498:            menu->y_pos = DisplayHeight(display, screen) - menu->height;
        !           499:     else if (menu->y_pos < 0) menu->y_pos = 0;
        !           500: }
        !           501: 
        !           502: 
        !           503: /*
        !           504:  * _XMRecomputePane - Internal subroutine to recompute pane
        !           505:  *                   window dependencies.
        !           506:  */
        !           507: int
        !           508: _XMRecomputePane(display, menu, p_ptr, p_num)
        !           509:     register Display *display; /* Standard X display variable. */
        !           510:     register XMenu *menu;      /* Menu object being recomputed. */
        !           511:     register XMPane *p_ptr;    /* Pane pointer. */
        !           512:     register int p_num;                /* Pane sequence number. */
        !           513: {
        !           514:     register int window_x;     /* Recomputed window X coordinate. */
        !           515:     register int window_y;     /* Recomputed window Y coordinate. */
        !           516:     
        !           517:     unsigned long change_mask; /* Value mask to reconfigure window. */
        !           518:     XWindowChanges *changes;   /* Values to use in configure window. */
        !           519:     
        !           520:     register Bool config_p = False;    /* Reconfigure pane window? */
        !           521: 
        !           522:     /*
        !           523:      * Update the pane serial number.
        !           524:      */
        !           525:     p_ptr->serial = p_num;
        !           526: 
        !           527:     /*
        !           528:      * Recompute window X and Y coordinates.
        !           529:      */
        !           530:     switch (menu->menu_style) {
        !           531:        case LEFT:
        !           532:            window_x = menu->p_x_off * ((menu->p_count - 1) - p_num);
        !           533:            window_y = menu->p_y_off * ((menu->p_count - 1) - p_num);
        !           534:            break;
        !           535:        case RIGHT:
        !           536:            window_x = menu->p_x_off * p_num;
        !           537:            window_y = menu->p_y_off * ((menu->p_count - 1) - p_num);
        !           538:            break;
        !           539:        case CENTER:
        !           540:            window_x = 0;
        !           541:            window_y = menu->p_y_off * ((menu->p_count - 1) - p_num);
        !           542:            break;
        !           543:        default:
        !           544:            /* Error! Invalid style parameter. */
        !           545:            _XMErrorCode = XME_STYLE_PARAM;
        !           546:            return(_FAILURE);
        !           547:     }
        !           548:     window_x += menu->x_pos;
        !           549:     window_y += menu->y_pos;
        !           550: 
        !           551:     /*
        !           552:      * If the newly compute pane coordinates differ from the 
        !           553:      * current coordinates, reset the current coordinates and
        !           554:      * reconfigure the pane.
        !           555:      */
        !           556:     if (
        !           557:        (window_x != p_ptr->window_x) ||
        !           558:        (window_y != p_ptr->window_y)
        !           559:     ){
        !           560:        /*
        !           561:         * Reset the coordinates and schedule
        !           562:         * the pane for reconfiguration.
        !           563:         */
        !           564:        p_ptr->window_x = window_x;
        !           565:        p_ptr->window_y = window_y;
        !           566:        config_p = True;
        !           567:     }
        !           568: 
        !           569:     /*
        !           570:      * If the local pane width and height differs from the
        !           571:      * menu pane width and height, reset the local values.
        !           572:      */
        !           573:     if (
        !           574:        (p_ptr->window_w != menu->p_width) ||
        !           575:        (p_ptr->window_h != menu->p_height)
        !           576:     ){
        !           577:        /*
        !           578:         * Reset window width and height and schedule
        !           579:         * the pane for reconfiguration.
        !           580:         */
        !           581:        p_ptr->window_w = menu->p_width;
        !           582:        p_ptr->window_h = menu->p_height;
        !           583:        config_p = True;
        !           584:     }
        !           585: 
        !           586:     /*
        !           587:      * If we need to reconfigure the pane window do it now.
        !           588:      */
        !           589:     if (config_p == True) {
        !           590:        /*
        !           591:         * If the pane window has already been created then
        !           592:         * reconfigure the existing window, otherwise queue
        !           593:         * it for creation with the new configuration.
        !           594:         */
        !           595:        if (p_ptr->window) {
        !           596:            change_mask = (CWX | CWY | CWWidth | CWHeight);
        !           597:            changes = (XWindowChanges *)malloc(sizeof(XWindowChanges));
        !           598:            changes->x = p_ptr->window_x;
        !           599:            changes->y = p_ptr->window_y;
        !           600:            changes->width = p_ptr->window_w;
        !           601:            changes->height = p_ptr->window_h;
        !           602:            
        !           603:            XConfigureWindow(
        !           604:                             display,
        !           605:                             p_ptr->window,
        !           606:                             change_mask,
        !           607:                             changes
        !           608:                             );
        !           609:            free(changes);
        !           610:            
        !           611:        }
        !           612:        else {
        !           613:            if (_XMWinQueAddPane(display, menu, p_ptr) == _FAILURE) {
        !           614:                return(_FAILURE);
        !           615:            }
        !           616:        }
        !           617:     }
        !           618:  
        !           619:     /*
        !           620:      * Recompute label X position.
        !           621:      */
        !           622:     switch (menu->p_style) {
        !           623:        case LEFT:
        !           624:            p_ptr->label_x = menu->p_x_off + menu->p_fnt_pad;
        !           625:            break;
        !           626:        case RIGHT:
        !           627:            p_ptr->label_x = menu->p_width -
        !           628:                (p_ptr->label_width + menu->p_x_off + menu->p_fnt_pad);
        !           629:            break;
        !           630:        case CENTER:
        !           631:            p_ptr->label_x = (menu->p_width - p_ptr->label_width) >> 1;
        !           632:            break;
        !           633:        default:
        !           634:            /* Error! Invalid style parameter. */
        !           635:            _XMErrorCode = XME_STYLE_PARAM;
        !           636:            return(_FAILURE);
        !           637:     }
        !           638:     /*
        !           639:      * Recompute label Y positions.
        !           640:      */
        !           641:     p_ptr->label_uy = menu->p_fnt_pad + menu->p_fnt_info->max_bounds.ascent;
        !           642:     p_ptr->label_ly = (menu->p_height - menu->p_fnt_pad - menu->p_fnt_info->max_bounds.descent);
        !           643: 
        !           644:     /*
        !           645:      * All went well, return successfully.
        !           646:      */
        !           647:     _XMErrorCode = XME_NO_ERROR;
        !           648:     return(_SUCCESS);
        !           649: }
        !           650: 
        !           651: 
        !           652: 
        !           653: /*
        !           654:  * _XMRecomputeSelection - Internal subroutine to recompute
        !           655:  *                        selection window dependencies.
        !           656:  */
        !           657: int
        !           658: _XMRecomputeSelection(display, menu, s_ptr, s_num)
        !           659:     register Display *display;
        !           660:     register XMenu *menu;      /* Menu object being recomputed. */
        !           661:     register XMSelect *s_ptr;  /* Selection pointer. */
        !           662:     register int s_num;                /* Selection sequence number. */
        !           663: {
        !           664:     register Bool config_s = False;    /* Reconfigure selection window? */
        !           665:     XWindowChanges *changes;           /* Values to change in configure. */
        !           666:     unsigned long change_mask;         /* Value mask for XConfigureWindow. */
        !           667:     
        !           668:     /*
        !           669:      * If the selection serial numbers are out of order, begin
        !           670:      * resequencing selections.  Recompute selection window coordinates
        !           671:      * and serial number.
        !           672:      *
        !           673:      * When selections are created they are given a serial number of
        !           674:      * -1, this causes this routine to give a new selection
        !           675:      * its initial coordinates and serial number.
        !           676:      */
        !           677:     if (s_ptr->serial != s_num) {
        !           678:        /*
        !           679:         * Fix the sequence number.
        !           680:         */
        !           681:        s_ptr->serial = s_num;
        !           682:        /*
        !           683:         * Recompute window X and Y coordinates.
        !           684:         */
        !           685:        s_ptr->window_x = menu->s_x_off;
        !           686:        s_ptr->window_y = menu->flag_height + (menu->s_y_off * s_num);
        !           687:        /*
        !           688:         * We must reconfigure the window.
        !           689:         */
        !           690:        config_s = True;
        !           691:     }
        !           692: 
        !           693:     /*
        !           694:      * If the local selection width and height differs from the
        !           695:      * menu selection width and height, reset the local values.
        !           696:      */
        !           697:     if (
        !           698:        (s_ptr->window_w != menu->s_width) ||
        !           699:        (s_ptr->window_h != menu->s_height)
        !           700:     ){
        !           701:        /*
        !           702:         * We must reconfigure the window.
        !           703:         */
        !           704:        config_s = True;
        !           705:        /*
        !           706:         * Reset window width and height.
        !           707:         */
        !           708:        s_ptr->window_w = menu->s_width;
        !           709:        s_ptr->window_h = menu->s_height;
        !           710:     }
        !           711: 
        !           712:     /*
        !           713:      * If we need to reconfigure the selection window do it now.
        !           714:      */
        !           715:     if (config_s == True) {
        !           716:        /*
        !           717:         * If the selection window has already been created then
        !           718:         * reconfigure the existing window, otherwise queue it
        !           719:         * for creation with the new configuration.
        !           720:         */
        !           721:        if (s_ptr->window) {
        !           722:            changes = (XWindowChanges *)malloc(sizeof(XWindowChanges));
        !           723:            change_mask = (CWX | CWY | CWWidth | CWHeight);
        !           724:            changes = (XWindowChanges *)malloc(sizeof(XWindowChanges));
        !           725:            changes->x = s_ptr->window_x;
        !           726:            changes->y = s_ptr->window_y;
        !           727:            changes->width = s_ptr->window_w;
        !           728:            changes->height = s_ptr->window_h;
        !           729:            
        !           730:            XConfigureWindow(
        !           731:                             display,
        !           732:                             s_ptr->window,
        !           733:                             change_mask,
        !           734:                             changes
        !           735:                             );
        !           736:            free(changes);
        !           737:            
        !           738:        }
        !           739:        else {
        !           740:            if (_XMWinQueAddSelection(display, menu, s_ptr) == _FAILURE) {
        !           741:                return(_FAILURE);
        !           742:            }
        !           743:        }
        !           744:     }
        !           745: 
        !           746:     /*
        !           747:      * Recompute label X position.
        !           748:      */
        !           749:     switch (menu->s_style) {
        !           750:        case LEFT:
        !           751:            s_ptr->label_x = menu->s_bdr_width + menu->s_fnt_pad + s_ptr->window_x;
        !           752:            break;
        !           753:        case RIGHT:
        !           754:            s_ptr->label_x = s_ptr->window_x + menu->s_width -
        !           755:                (s_ptr->label_width + menu->s_bdr_width + menu->s_fnt_pad);
        !           756:            break;
        !           757:        case CENTER:
        !           758:            s_ptr->label_x = s_ptr->window_x + ((menu->s_width - s_ptr->label_width) >> 1);
        !           759:            break;
        !           760:        default:
        !           761:            /* Error! Invaild style parameter. */
        !           762:            _XMErrorCode = XME_STYLE_PARAM;
        !           763:            return(_FAILURE);
        !           764:     }
        !           765:     /*
        !           766:      * Recompute label Y position.
        !           767:      */
        !           768:     s_ptr->label_y = s_ptr->window_y + menu->s_fnt_info->max_bounds.ascent + menu->s_fnt_pad + menu->s_bdr_width;
        !           769:     
        !           770:     /*
        !           771:      * All went well, return successfully.
        !           772:      */
        !           773:     _XMErrorCode = XME_NO_ERROR;
        !           774:     return(_SUCCESS);
        !           775: }
        !           776: 
        !           777: 
        !           778: 
        !           779: /*
        !           780:  * _XMTransToOrigin - Internal subroutine to translate the point at
        !           781:  *                   the center of the current pane and selection to the 
        !           782:  *                   the menu origin.
        !           783:  *
        !           784:  *     WARNING! ****** Be certain that all menu depencies have been
        !           785:  *                     recomputed before calling this routine or
        !           786:  *                     unpredictable results will follow.
        !           787:  */
        !           788: _XMTransToOrigin(display, menu, p_ptr, s_ptr, x_pos, y_pos, orig_x, orig_y)
        !           789:     Display *display;          /* Not used. Included for consistency. */
        !           790:     register XMenu *menu;      /* Menu being computed against. */
        !           791:     register XMPane *p_ptr;    /* Current pane pointer. */
        !           792:     register XMSelect *s_ptr;  /* Current selection pointer. */
        !           793:     int x_pos;                 /* X coordinate of point to translate. */
        !           794:     int y_pos;                 /* Y coordinate of point to translate. */
        !           795:     int *orig_x;               /* Return value X coord. of the menu origin. */
        !           796:     int *orig_y;               /* Return value Y coord. of the menu origin. */
        !           797: {
        !           798:     register int l_orig_x;     /* Local X coordinate of the menu origin. */
        !           799:     register int l_orig_y;     /* Local Y coordinate of the menu origin. */
        !           800:     
        !           801:     /*
        !           802:      * Translate the menu origin such that the cursor hot point will be in the
        !           803:      * center of the desired current selection and pane.
        !           804:      * If the current selection pointer is NULL then assume that the hot point
        !           805:      * will be in the center of the current pane flag.
        !           806:      */
        !           807: 
        !           808:     if (s_ptr == NULL) {
        !           809:        /*
        !           810:         * Translate from the center of the pane flag to the upper left
        !           811:         * of the current pane window.
        !           812:         */
        !           813:        l_orig_x = x_pos - (menu->p_width >> 1) - menu->p_bdr_width;
        !           814:        l_orig_y = y_pos - (menu->flag_height >> 1) - menu->p_bdr_width;
        !           815:     }
        !           816:     else {
        !           817:        /*
        !           818:         * First translate from the center of the current selection
        !           819:         * to the upper left of the current selection window.
        !           820:         */
        !           821:        l_orig_x = x_pos - (menu->s_width >> 1);
        !           822:        l_orig_y = y_pos - (menu->s_height >> 1);
        !           823: 
        !           824:        /*
        !           825:         * Then translate to the upper left of the current pane window.
        !           826:         */
        !           827:        l_orig_x -= (s_ptr->window_x + menu->p_bdr_width);
        !           828:        l_orig_y -= (s_ptr->window_y + menu->p_bdr_width);
        !           829:     }
        !           830: 
        !           831:     /*
        !           832:      * Finally translate to the upper left of the menu.
        !           833:      */
        !           834:     l_orig_x -= (p_ptr->window_x - menu->x_pos);
        !           835:     l_orig_y -= (p_ptr->window_y - menu->y_pos);
        !           836: 
        !           837:     /*
        !           838:      * Set the return values.
        !           839:      */
        !           840:     *orig_x = l_orig_x;
        !           841:     *orig_y = l_orig_y;
        !           842: }
        !           843: 
        !           844: /*
        !           845:  * _XMRefreshPane - Internal subroutine to completely refresh
        !           846:  *                 the contents of a pane.
        !           847:  */
        !           848: _XMRefreshPane(display, menu, pane)
        !           849:     register Display *display;
        !           850:     register XMenu *menu;
        !           851:     register XMPane *pane;
        !           852: {
        !           853:     register XMSelect *s_list = pane->s_list;
        !           854:     register XMSelect *s_ptr;
        !           855: 
        !           856:     /*
        !           857:      * First clear the pane. 
        !           858:      */
        !           859:     XClearWindow(display, pane->window);
        !           860:     if (!pane->activated) {
        !           861:        XFillRectangle(display,
        !           862:                       pane->window,
        !           863:                       menu->inverse_select_GC,
        !           864:                       pane->label_x - menu->p_fnt_pad,
        !           865:                       pane->label_uy - menu->p_fnt_info->max_bounds.ascent - menu->p_fnt_pad,
        !           866:                       pane->label_width + (menu->p_fnt_pad << 1),
        !           867:                       menu->flag_height);
        !           868: 
        !           869:        XFillRectangle(display,
        !           870:                       pane->window,
        !           871:                       menu->inverse_select_GC,
        !           872:                       pane->label_x - menu->p_fnt_pad,
        !           873:                       pane->label_ly - menu->p_fnt_info->max_bounds.ascent - menu->p_fnt_pad,
        !           874:                       pane->label_width + (menu->p_fnt_pad << 1),
        !           875:                       menu->flag_height);
        !           876:     }
        !           877:     if (!pane->active) {
        !           878:        XDrawString(display,
        !           879:                    pane->window,
        !           880:                    menu->inact_GC,
        !           881:                    pane->label_x, pane->label_uy,
        !           882:                    pane->label, pane->label_length);
        !           883:        XDrawString(display,
        !           884:                    pane->window,
        !           885:                    menu->inact_GC,
        !           886:                    pane->label_x, pane->label_ly,
        !           887:                    pane->label, pane->label_length);
        !           888:     }
        !           889:     else {
        !           890:        XDrawString(display,
        !           891:                         pane->window,
        !           892:                         menu->pane_GC,
        !           893:                         pane->label_x, pane->label_uy,
        !           894:                         pane->label, pane->label_length);
        !           895:        XDrawString(display,
        !           896:                         pane->window,
        !           897:                         menu->pane_GC,
        !           898:                         pane->label_x, pane->label_ly,
        !           899:                         pane->label, pane->label_length);
        !           900: 
        !           901:        /*
        !           902:         * Finally refresh each selection if the pane is activated.
        !           903:         */
        !           904:        if (pane->activated) {
        !           905:            for (s_ptr = s_list->next; s_ptr != s_list; s_ptr = s_ptr->next)
        !           906:                _XMRefreshSelection(display, menu, s_ptr);
        !           907:        }
        !           908:     }
        !           909: }
        !           910:     
        !           911:     
        !           912: 
        !           913: 
        !           914: /*
        !           915:  * _XMRefreshSelection - Internal subroutine that refreshes 
        !           916:  *                      a single selection window.
        !           917:  */
        !           918: _XMRefreshSelection(display, menu, select)
        !           919:     register Display *display;
        !           920:     register XMenu *menu;
        !           921:     register XMSelect *select;
        !           922: {
        !           923:     register int width = select->window_w;
        !           924:     register int height = select->window_h;
        !           925:     register int bdr_width = menu->s_bdr_width;
        !           926:     
        !           927:     if (select->activated) {
        !           928:        if (menu->menu_mode == INVERT) {
        !           929:            XFillRectangle(display, 
        !           930:                           select->parent_p->window,
        !           931:                           menu->normal_select_GC,
        !           932:                           select->window_x, select->window_y,
        !           933:                           width, height); 
        !           934:            XDrawString(display,
        !           935:                        select->parent_p->window,
        !           936:                        menu->inverse_select_GC,
        !           937:                        select->label_x,
        !           938:                        select->label_y,
        !           939:                        select->label, select->label_length);
        !           940:        }
        !           941:         else {
        !           942:             /*
        !           943:             * Using BOX mode.
        !           944:              * Since most drawing routines with arbitrary width lines
        !           945:             * are slow compared to raster-ops lets use a raster-op to
        !           946:             * draw the boxes.
        !           947:              */
        !           948:            
        !           949:            XDrawRectangle(display,
        !           950:                           select->parent_p->window,
        !           951:                           menu->normal_select_GC,
        !           952:                           select->window_x + (bdr_width >> 1),
        !           953:                           select->window_y + (bdr_width >> 1 ),
        !           954:                           width - bdr_width,
        !           955:                           height - bdr_width);
        !           956:            XDrawString(display,
        !           957:                        select->parent_p->window,
        !           958:                        menu->normal_select_GC,
        !           959:                        select->label_x,
        !           960:                        select->label_y,
        !           961:                        select->label, select->label_length);
        !           962:         }
        !           963:     }
        !           964:     else {
        !           965:        XClearArea(display, 
        !           966:                   select->parent_p->window,
        !           967:                   select->window_x, select->window_y,
        !           968:                   width, height,
        !           969:                   False);
        !           970:        if (select->active) {
        !           971:            XDrawString(display,
        !           972:                        select->parent_p->window,
        !           973:                        menu->normal_select_GC,
        !           974:                        select->label_x,
        !           975:                        select->label_y,
        !           976:                        select->label, select->label_length);
        !           977:        }
        !           978:        else {
        !           979:            XDrawString(display,
        !           980:                        select->parent_p->window,
        !           981:                        menu->inact_GC,
        !           982:                        select->label_x,
        !           983:                        select->label_y,
        !           984:                        select->label, select->label_length);
        !           985:        }
        !           986:     }
        !           987: }
        !           988: 

unix.superglobalmegacorp.com

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