Annotation of researchv9/X11/src/X.V11R1/clients/uwm/Menu.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *rcsid_Menu_c = "$Header: Menu.c,v 1.11 87/08/03 13:08:09 swick Exp $";
                      3: #endif lint
                      4: 
                      5: #include <X11/copyright.h>
                      6: 
                      7: /*
                      8:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
                      9:  *
                     10:  *                         All Rights Reserved
                     11:  *
                     12:  * Permission to use, copy, modify, and distribute this software and its
                     13:  * documentation for any purpose and without fee is hereby granted,
                     14:  * provided that the above copyright notice appear in all copies and that
                     15:  * both that copyright notice and this permission notice appear in
                     16:  * supporting documentation, and that the name of Digital Equipment
                     17:  * Corporation not be used in advertising or publicity pertaining to
                     18:  * distribution of the software without specific, written prior permission.
                     19:  *
                     20:  *
                     21:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     22:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     23:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     24:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     25:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     26:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     27:  * SOFTWARE.
                     28:  */
                     29: 
                     30: 
                     31: 
                     32: /*
                     33:  * MODIFICATION HISTORY
                     34:  *
                     35:  * 000 -- M. Gancarz, DEC Ultrix Engineering Group
                     36:  * 001 -- L. Guarino Reid, DEC Ultrix Engineering Group, Western Software Lab
                     37:  *       February 16, 1987
                     38:  *       Change menu implementation so that it uses EnterWindow, LeaveWindow,
                     39:  *       and MouseMotion events to track the mouse, instead of polling.
                     40:  * 002 -- L. Guarino Reid, DEC Ultrix Engineering Group, Western Software Lab
                     41:  *       April 30, 1987. Convert to X11.
                     42:  * 003 -- L. Guarino Reid, DEC Ultrix Engineering Group, Western Software Lab
                     43:  *       June 18, 1987. Change call to system to handle signals move smoothly.
                     44:  */
                     45: 
                     46: #ifndef lint
                     47: static char *sccsid = "@(#)Menu.c      3.8     1/24/86";
                     48: #endif
                     49: 
                     50: #include <signal.h>
                     51: #include "uwm.h"
                     52: 
                     53: Bool alternateGC;              /* true if only 2 colors are used */
                     54: 
                     55: #define DisplayLine(w, pane, width, height, str, fg, bg, inv) \
                     56:          if (alternateGC) { \
                     57:             if (inv) \
                     58:                 XFillRectangle(dpy, w, MenuInvGC, 0, pane, width, height); \
                     59:             else \
                     60:                  XDrawString(dpy, w, MenuGC, HMenuPad, pane + VMenuPad + MFontInfo->ascent, str, strlen(str)); \
                     61:          } else { \
                     62:              XSetForeground(dpy, MenuGC, bg); \
                     63:             XFillRectangle(dpy, w, MenuGC, 0, pane, width, height); \
                     64:              XSetForeground(dpy, MenuGC, fg); \
                     65:              XDrawString(dpy, w, MenuGC, HMenuPad, pane + VMenuPad + MFontInfo->ascent, str, strlen(str)); \
                     66:          }
                     67: 
                     68: /* the following procedure is a copy of the implementation of system, 
                     69:  * modified to reset the handling of SIGINT, SIGQUIT, and SIGHUP before
                     70:  * exec-ing
                     71:  */
                     72: execute(s)
                     73: char *s;
                     74: {
                     75:        int status, pid, w;
                     76:        register int (*istat)(), (*qstat)();
                     77: 
                     78:        if ((pid = vfork()) == 0) {
                     79:                signal(SIGINT, SIG_DFL);
                     80:                signal(SIGQUIT, SIG_DFL);
                     81:                signal(SIGHUP, SIG_DFL);
                     82:                execl("/bin/sh", "sh", "-c", s, 0);
                     83:                _exit(127);
                     84:        }
                     85:        istat = signal(SIGINT, SIG_IGN);
                     86:        qstat = signal(SIGQUIT, SIG_IGN);
                     87:        while ((w = wait(&status)) != pid && w != -1)
                     88:                ;
                     89:        if (w == -1)
                     90:                status = -1;
                     91:        signal(SIGINT, istat);
                     92:        signal(SIGQUIT, qstat);
                     93:        return(status);
                     94: }
                     95: 
                     96: Bool Menu(window, mask, button, x, y, menu)
                     97: Window window;                         /* Event window. */
                     98: int mask;                              /* Button/key mask. */
                     99: int button;                            /* Button event detail. */
                    100: int x, y;                              /* Event mouse position. */
                    101: MenuInfo *menu;
                    102: {
                    103:     XEvent button_event;               /* Button event packet. */
                    104:     int event_x, event_y;              /* location of button event */
                    105:     Bool func_stat;                    /* Function status return. */
                    106:     Window sub_window;                 /* Current subwindow. */
                    107:     int cur_item = 0;                  /* Current menu item. */
                    108:     int hi_lite = 0;                   /* Current highlighted item. */
                    109:     int i;                             /* Iteration counter. */
                    110:     int hlfg, hlbg;                    /* Hi-liter pixels. */
                    111:     MenuLine *ml;                      /* Menu lines pointer. */
                    112:     char *hlname;                      /* Pointer to hi-liter name. */
                    113:     char *strbuf;                      /* String buffer for IsTextNL. */
                    114:     char *malloc();
                    115: 
                    116:     /*
                    117:      * Change the cursor.
                    118:      */
                    119:     XChangeActivePointerGrab(dpy, EVENTMASK, MenuCursor, CurrentTime);
                    120: 
                    121:     /*
                    122:      * Map the menu.
                    123:      */
                    124:     MapMenu(menu, x, y);
                    125:     if (Autoselect) {
                    126:         event_x = (menu->width >> 2) * 3;
                    127:         event_y = (menu->iheight >> 1);
                    128:         XWarpPointer(dpy, None, menu->w, 0, 0, 0, 0, event_x, event_y);
                    129:        goto hilite;
                    130:     }
                    131:     else {
                    132:         XWarpPointer(dpy, None, menu->w, 0, 0, 0, 0, 
                    133:                (menu->width >> 2) * 3, menu->iheight >> 1);
                    134:         XFlush(dpy);
                    135:     }
                    136: 
                    137:     /*
                    138:      * Main loop.
                    139:      */
                    140:     while (TRUE) {
                    141: 
                    142:         /*
                    143:          *  Get next event for menu.
                    144:          */
                    145:         if (!GetButton(&button_event)) continue;
                    146:        switch (button_event.type) {
                    147: 
                    148:             case LeaveNotify:
                    149:                /*
                    150:                 * If the mouse has moved out of the menu sideways, abort
                    151:                 * the menu operation. Reset the cursor and unmap the menu.
                    152:                 */
                    153:                event_x = ((XLeaveWindowEvent * )&button_event)->x;
                    154:                event_y = ((XLeaveWindowEvent * )&button_event)->y;
                    155:                if (event_x < 0 || event_x > menu->width) {
                    156:                   ResetCursor(button);
                    157:                   UnmapMenu(menu);
                    158:                   return(FALSE);
                    159:                }
                    160:                goto hilite;
                    161: 
                    162:             case EnterNotify:
                    163:                event_x = ((XEnterWindowEvent * )&button_event)->x;
                    164:                event_y = ((XEnterWindowEvent * )&button_event)->y;
                    165:                goto hilite;
                    166:             case MotionNotify:
                    167:                {
                    168:                event_x = ((XPointerMovedEvent * )&button_event)->x;
                    169:                event_y = ((XPointerMovedEvent * )&button_event)->y;
                    170: hilite:
                    171:                /*
                    172:                * If the mouse has moved below or above the menu, but is still
                    173:                * within the same vertical plane, then simply adjust the values
                    174:                * so the user doesn't fall off the edge.
                    175:                */
                    176:                if (event_y >= menu->height) 
                    177:                  event_y = menu->height - 1;
                    178:                else if (event_y < 0) 
                    179:                  event_y = 0;
                    180:                  
                    181:                /*
                    182:                * If the mouse has moved to another item in the menu,
                    183:                * highlight the new item.
                    184:                */
                    185:                cur_item = event_y / menu->iheight;
                    186:                if (cur_item != hi_lite) {
                    187: 
                    188:                /*
                    189:                * Remove highlighting on old item.
                    190:                */
                    191:                if (hi_lite) {
                    192:                        DisplayLine(menu->w, hi_lite * menu->iheight,
                    193:                             menu->width, menu->iheight, hlname,
                    194:                             hlfg, hlbg, 1);
                    195:                        XFlush(dpy);
                    196:                }
                    197: 
                    198:                /*
                    199:                * Highlight new item.
                    200:                */
                    201:                hi_lite = cur_item;
                    202:                if (cur_item) {
                    203:                        for(i = 1, ml = menu->line; ml; i++, ml = ml->next) {
                    204:                                if (i == cur_item) break;
                    205:                                }
                    206:                        DisplayLine(menu->w, cur_item * menu->iheight,
                    207:                             menu->width, menu->iheight, ml->name,
                    208:                             menu->hlfg.pixel, menu->hlbg.pixel, 1);
                    209: /*                     XSetForeground(dpy, MenuGC, menu->hlfg.pixel );
                    210:                        XDrawRectangle(dpy, menu->w, MenuGC, 1, 
                    211:                                cur_item * menu->iheight + 1, 
                    212:                                menu->width - 3, menu->iheight - 3);
                    213: */
                    214:                        XFlush(dpy);
                    215:                        hlfg = ml->fg.pixel;
                    216:                        hlbg = ml->bg.pixel;
                    217:                        hlname = ml->name;
                    218:                }
                    219:                }
                    220:                break;
                    221: 
                    222:             case ButtonRelease:
                    223:                /* have we released the invoking button? */
                    224:                if (((XButtonReleasedEvent *)&button_event)->button == button) {
                    225:                    /*
                    226:                     * If no item was selected, simply close the menu and return.
                    227:                     */
                    228:                    if (!cur_item) {
                    229:                         ResetCursor(button);
                    230:                         UnmapMenu(menu);
                    231:                         return(TRUE);
                    232:                     }
                    233: 
                    234:                     /*
                    235:                      * Get a pointer to the menu line selected.
                    236:                      */
                    237:                     --cur_item;
                    238:                     for(i = 0, ml = menu->line; ml; i++, ml = ml->next) {
                    239:                         if (i == cur_item) break;
                    240:                     }
                    241: 
                    242:                     /*
                    243:                      * Perform the selected menu line action.
                    244:                      */
                    245:                     switch (ml->type) {
                    246: 
                    247:                         case IsShellCommand:
                    248:                             UnmapMenu(menu);
                    249:                             execute(ml->text);
                    250:                             break;
                    251: 
                    252:                         case IsText:
                    253:                             UnmapMenu(menu);
                    254:                             XStoreBytes(dpy, ml->text, strlen(ml->text));
                    255:                             break;
                    256: 
                    257:                         case IsTextNL:
                    258:                             UnmapMenu(menu);
                    259:                             strbuf = (char *)malloc(strlen(ml->text) + 2);
                    260:                             strcpy(strbuf, ml->text);
                    261:                             strcat(strbuf, "\n");
                    262:                             XStoreBytes(dpy, strbuf, strlen(strbuf));
                    263:                             free(strbuf);
                    264:                             break;
                    265: 
                    266:                         case IsUwmFunction:
                    267:                             /* change cursor and grab next button event
                    268:                              * to select the target window */
                    269:                             if (XGrabPointer( dpy, RootWindow(dpy, scr),
                    270:                                               TRUE, EVENTMASK, GrabModeAsync,
                    271:                                               GrabModeAsync, None,
                    272:                                               TargetCursor, CurrentTime )
                    273:                                   != GrabSuccess )
                    274:                                 Error( "Could not grab pointer" );
                    275:                             GetContext(
                    276:                               &sub_window, &event_x, &event_y);
                    277:                             UnmapMenu(menu);
                    278:                             if (sub_window != menu->w)
                    279:                               func_stat =
                    280:                                 (*ml->func) (
                    281:                                   sub_window, mask, button, event_x, 
                    282:                                   event_y);
                    283:                             else func_stat = FALSE;
                    284:                             if (!func_stat) {
                    285:                               /* eat the next ButtonRelease */
                    286:                               while (TRUE) {
                    287:                                   if (GetButton(&button_event) &&
                    288:                                       button_event.type == ButtonRelease)
                    289:                                     break;
                    290:                               }
                    291:                             }
                    292:                             XUngrabPointer( dpy, CurrentTime );
                    293:                             break;
                    294: 
                    295:                         case IsImmFunction:
                    296:                             UnmapMenu(menu);
                    297:                            (*ml->func) (
                    298:                              sub_window, mask, button, event_x, 
                    299:                              event_y);
                    300:                             break;
                    301:                 
                    302:                         case IsMenuFunction:
                    303:                             while (TRUE) {
                    304:                                if (!GetButton(&button_event)) continue;
                    305:                                if (button_event.type != ButtonPress) continue;
                    306:                                if ((((XButtonPressedEvent *)&button_event)->state != mask) 
                    307:                                 || (((XButtonPressedEvent *)&button_event)->button != button)) 
                    308:                                 {
                    309:                                     UnmapMenu(menu);
                    310:                                     return(TRUE);
                    311:                                 }
                    312:                                 break;
                    313:                             }
                    314:                             UnmapMenu(menu);
                    315:                             func_stat = 
                    316:                                Menu(menu->w, mask, button, x, y, ml->menu);
                    317:                             return(func_stat);
                    318:                             break;
                    319: 
                    320:                         default:
                    321:                            Error("Menu -> Internal type error.");
                    322:                     }
                    323:                     return(TRUE);
                    324:                  
                    325:                  } 
                    326:                 /* else a different button was released. Fall through: */
                    327:             default:
                    328:                     /*
                    329:                      * Some other button event occurred, so abort the menu
                    330:                      * operation.
                    331:                      */
                    332:                    ResetCursor(button);
                    333:                     UnmapMenu(menu);
                    334:                     return(TRUE);
                    335:                
                    336:        }
                    337:      }
                    338:   }
                    339: }
                    340: 
                    341: 
                    342: /*
                    343:  * Create the menu windows for later use.
                    344:  */
                    345: CreateMenus()
                    346: {
                    347:     MenuLink *ptr;
                    348: 
                    349:     /*
                    350:      * If MaxColors isn't set, then jam it to an impossibly high
                    351:      * number.
                    352:      */
                    353:     if (MaxColors == 0)
                    354:         MaxColors = 25000;
                    355: 
                    356:     for(ptr = Menus; ptr; ptr = ptr->next)
                    357:         InitMenu(ptr->menu);
                    358: }
                    359: 
                    360: /*
                    361:  * Initialize a menu.
                    362:  */
                    363: InitMenu(menu)
                    364: MenuInfo *menu;
                    365: {
                    366:     MenuLine *ml;              /* Menu lines pointer. */
                    367:     int width;                 /* Width of an item name. */
                    368:     int maxwidth;              /* Maximum width of item names. */
                    369:     int len;                   /* Length of an item name. */
                    370:     int count = 1;             /* Number of items + 1 for name. */
                    371: 
                    372:     /*
                    373:      * Determine the name of the longest menu item.
                    374:      */
                    375:     maxwidth = XTextWidth(MFontInfo, menu->name, strlen(menu->name));
                    376:     if (maxwidth == 0)
                    377:         Error("InitMenu -> Couldn't get length of menu name");
                    378: 
                    379:     for(ml = menu->line; ml; ml = ml->next) {
                    380:         if ((len = strlen(ml->name)) == 0)
                    381:             break;
                    382:         width = XTextWidth(MFontInfo, ml->name, strlen(ml->name));
                    383:         if (width == 0) 
                    384:          Error("InitMenu -> Couldn't get length of menu item name");
                    385:         if (width > maxwidth) maxwidth = width;
                    386:         count++;
                    387:     }
                    388: 
                    389:     /*
                    390:      * Get the color cells for the menu items.
                    391:      */
                    392:     GetMenuColors(menu);
                    393: 
                    394:     /*
                    395:      * Stash the menu parameters in the menu info structure.
                    396:      */
                    397:     menu->iheight = MFontInfo->ascent + MFontInfo->descent + (VMenuPad << 1);
                    398:     menu->height = menu->iheight * count;
                    399:     menu->width = maxwidth + (HMenuPad << 1);
                    400:     menu->image = NULL;
                    401: 
                    402:     /*
                    403:      * Create the menu window.
                    404:      */
                    405:     menu->w = XCreateSimpleWindow(dpy, RootWindow(dpy, scr),
                    406:                             0, 0,
                    407:                             menu->width,
                    408:                             menu->height,
                    409:                             MBorderWidth,
                    410:                             MBorder, MBackground);
                    411:     if (menu->w == NULL) Error("InitMenu -> Couldn't create menu window");
                    412: 
                    413:     /*
                    414:      * Store the window name.
                    415:      */
                    416:     XStoreName(dpy, menu->w, menu->name);
                    417: 
                    418:     /*
                    419:      * Define a cursor for the window.
                    420:      */
                    421:     XDefineCursor(dpy, menu->w, MenuCursor);
                    422: 
                    423:     /*
                    424:      * We want enter, leave, and mouse motion events for menus.
                    425:      */
                    426:     XSelectInput(dpy, menu->w, 
                    427:        (EnterWindowMask | LeaveWindowMask | PointerMotionMask));
                    428: }
                    429: 
                    430: /*
                    431:  * Map a menu.
                    432:  */
                    433: MapMenu(menu, x, y)
                    434: MenuInfo *menu;
                    435: int x, y;
                    436: {
                    437:     int item;
                    438:     Window w;
                    439:     MenuLine *ml;
                    440:     XWindowChanges values;
                    441: 
                    442:     w = menu->w;
                    443: 
                    444:     /*
                    445:      * Move the menu into place, normalizing the coordinates, if necessary;
                    446:      * then map it.
                    447:      */
                    448:     x -= (menu->width >> 1);
                    449:     if (x < 0) x = 0;
                    450:     else if (x + menu->width >= ScreenWidth)
                    451:         x = ScreenWidth - menu->width - (MBorderWidth << 1);
                    452:     if (y < 0) y = 0;
                    453:     else if (y + menu->height >= ScreenHeight)
                    454:         y = ScreenHeight - menu->height - (MBorderWidth << 1);
                    455:     values.x = x;
                    456:     values.y = y;
                    457:     values.stack_mode = Above;
                    458:     XConfigureWindow(dpy, w, CWX|CWY|CWStackMode, &values);
                    459: 
                    460:     /*
                    461:      * Map the window and draw the text items.
                    462:      */
                    463:     XMapWindow(dpy, w);
                    464:     DisplayLine(w, 0, menu->width, menu->iheight, menu->name,
                    465:                 menu->bg.pixel, menu->fg.pixel, 0);
                    466: 
                    467:     if (alternateGC) {
                    468:         XFillRectangle(dpy, menu->w, MenuInvGC, 0, 0,
                    469:                       menu->width, menu->iheight);
                    470:         XDrawRectangle(dpy, menu->w, MenuInvGC, 1, 1,
                    471:                       menu->width - 3, menu->iheight - 3);
                    472:     } else {
                    473:         XSetForeground(dpy, MenuGC, menu->bg.pixel );
                    474:         XDrawRectangle(dpy, menu->w, MenuGC, 1, 1, menu->width - 3, 
                    475:                       menu->iheight - 3);
                    476:     }
                    477: 
                    478:     item = menu->iheight;
                    479:     for(ml = menu->line; ml; ml = ml->next) {
                    480:         DisplayLine(w, item, menu->width, menu->iheight, ml->name,
                    481:                     ml->fg.pixel, ml->bg.pixel, 0);
                    482:         item += menu->iheight;
                    483:     }
                    484: 
                    485:     /*
                    486:      * Position the mouse cursor in the menu header (or in the first item
                    487:      * if "autoselect" is set).
                    488:      */
                    489: 
                    490:     XFlush(dpy);
                    491: }
                    492: 
                    493: /*
                    494:  * Unmap a menu, restoring the contents of the screen underneath
                    495:  * if necessary. (Restore portion is a future.)
                    496:  */
                    497: UnmapMenu(menu)
                    498: MenuInfo *menu;
                    499: {
                    500:     /*
                    501:      * Unmap and flush.
                    502:      */
                    503:     XUnmapWindow(dpy, menu->w);
                    504:     XFlush(dpy);
                    505: }
                    506: 
                    507: /*
                    508:  * Get the context for invoking a window manager function.
                    509:  */
                    510: GetContext(w, x, y)
                    511: Window *w;
                    512: int *x, *y;
                    513: {
                    514:     XEvent button_event;  /* Button input event. */
                    515: 
                    516:     while (TRUE) {
                    517: 
                    518:         /*
                    519:          * Get the next mouse button event.  Spin our wheels until
                    520:          * a button event is returned (ie. GetButton == TRUE).
                    521:          * Note that mouse events within an icon window are handled
                    522:          * in the "GetButton" function or by the icon's owner if
                    523:          * it is not uwm.
                    524:          */
                    525:         if (!GetButton(&button_event)) continue;
                    526: 
                    527:         /*
                    528:          * If the button event received is not a ButtonPress event
                    529:          * then continue until we find one.
                    530:          */
                    531:         if (button_event.type != ButtonPress) continue;
                    532: 
                    533:         /*
                    534:          * Okay, determine the event window and mouse coordinates.
                    535:          */
                    536:         status = XTranslateCoordinates(dpy, 
                    537:                                    RootWindow(dpy, scr), 
                    538:                                    RootWindow(dpy, scr),
                    539:                                     ((XButtonPressedEvent *)&button_event)->x, 
                    540:                                     ((XButtonPressedEvent *)&button_event)->y, 
                    541:                                     x, y,
                    542:                                     w);
                    543: 
                    544:         if (status == FAILURE) continue;
                    545: 
                    546:         if (*w == 0)
                    547:             *w = RootWindow(dpy, scr);
                    548: 
                    549:         return;
                    550:     }
                    551: }
                    552: 
                    553: /*
                    554:  * Get the color cells for a menu.  This function is slightly brain-damaged
                    555:  * in that once MaxColors <= 1, then it refuses to even try to allocate any
                    556:  * more colors, even though the colors may have already been allocated.  It
                    557:  * probably ought to be done right someday.
                    558:  */
                    559: GetMenuColors(menu)
                    560: MenuInfo *menu;
                    561: {
                    562:     register MenuLine *ml;             /* Menu lines pointer. */
                    563: 
                    564:     /*
                    565:      * If we have more than 2 colors available, then attempt to get
                    566:      * the color map entries requested by the user.
                    567:      * Otherwise, default to standard black and white.
                    568:      */
                    569:     alternateGC = TRUE;                        /* assume the best */
                    570:     if (DisplayCells(dpy, scr) > 2) {
                    571:         /*
                    572:          * Get the menu header colors first.
                    573:          */
                    574:         if (!(menu->foreground && menu->background && MaxColors > 1 &&
                    575:               XParseColor(dpy, DefaultColormap(dpy, scr), menu->foreground, &menu->fg) &&
                    576:               XAllocColor(dpy, DefaultColormap(dpy, scr), &menu->fg) &&
                    577:               XParseColor(dpy, DefaultColormap(dpy, scr), menu->background, &menu->bg) &&
                    578:               XAllocColor(dpy, DefaultColormap(dpy, scr), &menu->bg))) {
                    579:             menu->fg.pixel = MTextForground;
                    580:             menu->bg.pixel = MTextBackground;
                    581:         } else {
                    582:             AdjustMaxColors(menu->fg.pixel);
                    583:             AdjustMaxColors(menu->bg.pixel);
                    584:            alternateGC = FALSE;
                    585:         }
                    586: 
                    587:         /*
                    588:          * Get the menu highlight colors.
                    589:          */
                    590:         if (!(menu->fghighlight && menu->bghighlight && MaxColors > 1 &&
                    591:               XParseColor(
                    592:                dpy, DefaultColormap(dpy, scr), menu->fghighlight, &menu->hlfg) &&
                    593:               XAllocColor(dpy, DefaultColormap(dpy, scr), &menu->hlfg) &&
                    594:               XParseColor(
                    595:                dpy, DefaultColormap(dpy, scr), menu->bghighlight, &menu->hlbg) &&
                    596:               XAllocColor(dpy, DefaultColormap(dpy, scr), &menu->hlbg))) {
                    597:             menu->hlfg.pixel = MTextBackground;
                    598:             menu->hlbg.pixel = MTextForground;
                    599:         } else {
                    600:             AdjustMaxColors(menu->hlfg.pixel);
                    601:             AdjustMaxColors(menu->hlbg.pixel);
                    602:            alternateGC = FALSE;
                    603:         }
                    604: 
                    605:         /*
                    606:          * Get the menu item colors.
                    607:          */
                    608:         for(ml = menu->line; ml; ml = ml->next) {
                    609:             if (!(ml->foreground && ml->background && MaxColors > 1 &&
                    610:                   XParseColor(dpy, DefaultColormap(dpy, scr), ml->foreground, &ml->fg) &&
                    611:                   XAllocColor(dpy, DefaultColormap(dpy, scr), &ml->fg) &&
                    612:                   XParseColor(dpy, DefaultColormap(dpy, scr), ml->background, &ml->bg) &&
                    613:                   XAllocColor(dpy, DefaultColormap(dpy, scr), &ml->bg))) {
                    614:                 ml->fg.pixel = MTextForground;
                    615:                 ml->bg.pixel = MTextBackground;
                    616:             } else {
                    617:                 AdjustMaxColors(ml->fg.pixel);
                    618:                 AdjustMaxColors(ml->bg.pixel);
                    619:                alternateGC = FALSE;
                    620:             }
                    621:         }
                    622: 
                    623:     } else {
                    624: 
                    625:         /*
                    626:          * Only 2 colors available, so default to standard black and white.
                    627:          */
                    628:         menu->fg.pixel = MTextForground;
                    629:         menu->bg.pixel = MTextBackground;
                    630:         menu->hlfg.pixel = MTextBackground;
                    631:         menu->hlbg.pixel = MTextForground;
                    632:         for(ml = menu->line; ml; ml = ml->next) {
                    633:             ml->fg.pixel = MTextForground;
                    634:             ml->bg.pixel = MTextBackground;
                    635:         }
                    636:     }
                    637: }
                    638: 
                    639: /*
                    640:  * Decrement "MaxColors" if this pixel value has never been used in a
                    641:  * menu before.
                    642:  */
                    643: AdjustMaxColors(pixel)
                    644: int pixel;
                    645: {
                    646:     register MenuLink *mptr;
                    647:     register MenuLine *lptr;
                    648:     int count = 0;
                    649: 
                    650:     for(mptr = Menus; mptr; mptr = mptr->next) {
                    651:         if (mptr->menu->fg.pixel == pixel) ++count;
                    652:         if (mptr->menu->bg.pixel == pixel) ++count;
                    653:         if (mptr->menu->hlfg.pixel == pixel) ++count;
                    654:         if (mptr->menu->hlbg.pixel == pixel) ++count;
                    655:         for(lptr = mptr->menu->line; lptr; lptr = lptr->next) {
                    656:             if (lptr->fg.pixel == pixel) ++count;
                    657:             if (lptr->bg.pixel == pixel) ++count;
                    658:         }
                    659:         if (count > 1) return;
                    660:     }
                    661:     --MaxColors;
                    662: }
                    663: 

unix.superglobalmegacorp.com

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