Annotation of 43BSDTahoe/new/X/XMenu/XMenuInternal.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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