Annotation of GNUtools/emacs/oldXMenu/Internal.c, revision 1.1.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.