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