Annotation of researchv9/X11/src/X.V11R1/clients/xterm/menu.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     $Source: /u1/X11/clients/xterm/RCS/menu.c,v $
        !             3:  *     $Header: menu.c,v 1.28 87/09/11 22:31:28 rws Exp $
        !             4:  */
        !             5: 
        !             6: #include <X11/copyright.h>
        !             7: 
        !             8: /*
        !             9:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
        !            10:  *
        !            11:  *                         All Rights Reserved
        !            12:  *
        !            13:  * Permission to use, copy, modify, and distribute this software and its
        !            14:  * documentation for any purpose and without fee is hereby granted,
        !            15:  * provided that the above copyright notice appear in all copies and that
        !            16:  * both that copyright notice and this permission notice appear in
        !            17:  * supporting documentation, and that the name of Digital Equipment
        !            18:  * Corporation not be used in advertising or publicity pertaining to
        !            19:  * distribution of the software without specific, written prior permission.
        !            20:  *
        !            21:  *
        !            22:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
        !            23:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
        !            24:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
        !            25:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
        !            26:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
        !            27:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
        !            28:  * SOFTWARE.
        !            29:  */
        !            30: 
        !            31: #include <stdio.h>
        !            32: #ifdef MODEMENU
        !            33: #include <X11/Xlib.h>
        !            34: #include <X11/Intrinsic.h>
        !            35: #include <X11/Xutil.h>
        !            36: #include <X11/Xatom.h>
        !            37: #include <X11/cursorfont.h>
        !            38: #include <X11/Xtlib.h>
        !            39: #include "menu.h"
        !            40: #include <setjmp.h>
        !            41: #include "ptyx.h"
        !            42: #include "data.h"
        !            43: 
        !            44: #ifndef lint
        !            45: static char rcs_id[] = "$Header: menu.c,v 1.28 87/09/11 22:31:28 rws Exp $";
        !            46: #endif lint
        !            47: 
        !            48: #define DEFMENUBORDER  2
        !            49: #define DEFMENUPAD     3
        !            50: 
        !            51: #define  XtNxterm                "xterm"
        !            52: #define  XtCApp                  "App"
        !            53: 
        !            54: #define XOR(a,b)       ((a&(~b)) | ((~a)&b))
        !            55: 
        !            56: #define        SetStateFlags(item)     item->itemFlags = (item->itemFlags &\
        !            57:                                 ~(itemStateMask | itemChanged)) |\
        !            58:                                 ((item->itemFlags & itemSetMask) >>\
        !            59:                                 itemSetMaskShift)
        !            60: 
        !            61: 
        !            62: static char Check_MarkBits[] = {
        !            63:    0x00, 0x01, 0x80, 0x01, 0xc0, 0x00, 0x60, 0x00,
        !            64:    0x31, 0x00, 0x1b, 0x00, 0x0e, 0x00, 0x04, 0x00
        !            65: };
        !            66: static char Default_CursorBits[] = {
        !            67:    0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0e, 0x00,
        !            68:    0x1e, 0x00, 0x3e, 0x00, 0x7e, 0x00, 0xfe, 0x00,
        !            69:    0xfe, 0x01, 0x3e, 0x00, 0x36, 0x00, 0x62, 0x00,
        !            70:    0x60, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0x00, 0x00
        !            71: };
        !            72: static char Default_MaskBits[] = {
        !            73:    0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00,
        !            74:    0x3f, 0x00, 0x7f, 0x00, 0xff, 0x00, 0xff, 0x01,
        !            75:    0xff, 0x03, 0xff, 0x07, 0x7f, 0x00, 0xf7, 0x00,
        !            76:    0xf3, 0x00, 0xe1, 0x01, 0xe0, 0x01, 0xc0, 0x01
        !            77: };
        !            78: 
        !            79: static GC MenuGC, MenuInverseGC, MenuInvertGC, MenuGrayGC;
        !            80: static int gotGCs = FALSE;
        !            81: 
        !            82: Pixmap Gray_Tile, Check_Tile;
        !            83: Menu Menu_Default;
        !            84: Cursor Menu_DefaultCursor;
        !            85: char *Menu_DefaultFont;
        !            86: 
        !            87: extern XrmNameList nameList;
        !            88: extern XrmClassList classList;
        !            89: extern EventDoNothing();
        !            90: 
        !            91: static int default_menuBorder = DEFMENUBORDER;
        !            92: static int default_menuPad = DEFMENUPAD;
        !            93: static char *defaultNULL = NULL;
        !            94: 
        !            95: static Resource resourceList[] = {
        !            96:   {"menuBorder", "MenuBorder", XrmRInt, sizeof(int),
        !            97:      (caddr_t) &Menu_Default.menuBorderWidth, (caddr_t) &default_menuBorder},
        !            98:   {"menuFont", XtCFont, XrmRString, sizeof(char *),
        !            99:      (caddr_t) &Menu_DefaultFont, (caddr_t) &defaultNULL},
        !           100:   {"menuPad", "MenuPad", XrmRInt, sizeof(int),
        !           101:      (caddr_t) &Menu_Default.menuItemPad, (caddr_t) &default_menuPad}
        !           102: };
        !           103: 
        !           104: /*
        !           105:  * AddMenuItem() adds a menu item to an existing menu, at the end of the
        !           106:  * list, which are number sequentially from zero.  The menuitem index is
        !           107:  * return, or -1 if failed.
        !           108:  */
        !           109: 
        !           110: AddMenuItem(menu, text)
        !           111: register Menu *menu;
        !           112: register char *text;
        !           113: {
        !           114:        register MenuItem *menuitem, **next;
        !           115:        register int i;
        !           116:        extern char *malloc();
        !           117: 
        !           118:        if(!menu || !text || (menuitem = (MenuItem *)malloc(sizeof(MenuItem)))
        !           119:         == (MenuItem *)0)
        !           120:                return(-1);
        !           121:        bzero((char *)menuitem, sizeof(MenuItem));
        !           122:        menuitem->itemText = text;
        !           123:        menuitem->itemTextLength = strlen(text);
        !           124:        for(i = 0, next = &menu->menuItems ; *next ; i++)
        !           125:                next = &(*next)->nextItem;
        !           126:        *next = menuitem;
        !           127:        menu->menuFlags |= menuChanged;
        !           128:        return(i);
        !           129: }
        !           130: 
        !           131: /*
        !           132:  * DisposeItem() releases the memory allocated for the given indexed
        !           133:  * menuitem.  Nonzero is returned if an item was actual disposed of.
        !           134:  */
        !           135: DisposeItem(menu, i)
        !           136: register Menu *menu;
        !           137: register int i;
        !           138: {
        !           139:        register MenuItem **next, **last, *menuitem;
        !           140: 
        !           141:        if(!menu || i < 0)
        !           142:                return(0);
        !           143:        next = &menu->menuItems;
        !           144:        do {
        !           145:                if(!*next)
        !           146:                        return(0);
        !           147:                last = next;
        !           148:                next = &(*next)->nextItem;
        !           149:        } while(i-- > 0);
        !           150:        menuitem = *last;
        !           151:        *last = *next;
        !           152:        free(menuitem);
        !           153:        return(1);
        !           154: }
        !           155: 
        !           156: /*
        !           157:  * DisposeMenu() releases the memory allocated for the given menu.
        !           158:  */
        !           159: DisposeMenu(menu)
        !           160: register Menu *menu;
        !           161: {
        !           162:        register TScreen *screen = &term.screen;
        !           163:        static Unmap_Menu();
        !           164: 
        !           165:        if(!menu)
        !           166:                return;
        !           167:        if(menu->menuFlags & menuMapped)
        !           168:                Unmap_Menu(menu);
        !           169:        while(DisposeItem(menu, 0));
        !           170:        if(menu->menuWindow)
        !           171:                XDestroyWindow(screen->display, menu->menuWindow);
        !           172:        if(menu->menuSaved)
        !           173:                XFreePixmap(screen->display, menu->menuSaved);
        !           174:        free(menu);
        !           175: }
        !           176: 
        !           177: InitMenu(name)
        !           178: register char *name;
        !           179: {
        !           180:        register TScreen *screen = &term.screen;
        !           181:        register char *cp;
        !           182:        extern Pixmap make_gray();
        !           183:        Display *dpy = screen->display;
        !           184: 
        !           185:        /*
        !           186:         * If the gray tile hasn't been set up, do it now.
        !           187:         */
        !           188:        if(!Gray_Tile) 
        !           189:                Gray_Tile = make_gray(WhitePixel(dpy, DefaultScreen(dpy)), 
        !           190:                BlackPixel(dpy, DefaultScreen(dpy)), 1);
        !           191:        if (!Check_Tile) {
        !           192:                Check_Tile = Make_tile(checkMarkWidth, checkMarkHeight,
        !           193:                  Check_MarkBits, BlackPixel(dpy, DefaultScreen(dpy)),
        !           194:                  WhitePixel(dpy, DefaultScreen(dpy)),
        !           195:                  DefaultDepth(dpy, DefaultScreen(dpy)));
        !           196:         }
        !           197:        Menu_Default.menuFlags = menuChanged;
        !           198: /*     if((cp = XGetDefault(dpy, name, "MenuFreeze")) && XStrCmp(cp, "on") == 0)
        !           199:                Menu_Default.menuFlags |= menuFreeze;
        !           200:        if((cp = XGetDefault(dpy, name, "MenuSave")) && XStrCmp(cp, "on") == 0)
        !           201:                Menu_Default.menuFlags |= menuSaveMenu;
        !           202: */
        !           203:        Menu_Default.menuInitialItem = -1;
        !           204:        XtGetResources( dpy, resourceList, XtNumber(resourceList),
        !           205:                        (ArgList) NULL, 0, DefaultRootWindow(dpy),
        !           206:                        XtNxterm, XtCApp, &nameList, &classList );
        !           207: 
        !           208:        /* would be nice if (Xrm)CvtStringToFontStruct didn't complain
        !           209:         * when the font didn't exist! */
        !           210:        if (Menu_DefaultFont != NULL) {
        !           211:            Menu_Default.menuFontInfo = XLoadQueryFont(dpy, Menu_DefaultFont);
        !           212:            if (!Menu_Default.menuFontInfo)
        !           213:                Menu_DefaultFont = NULL;
        !           214:        }
        !           215: 
        !           216:        /* actually, we need to know whether the fid is valid anyway */
        !           217:        if (Menu_DefaultFont == NULL) {
        !           218:            Menu_Default.menuFontInfo = screen->fnt_norm;
        !           219:            MenugcFontMask = VTgcFontMask;
        !           220:        }
        !           221: };
        !           222: 
        !           223: /*
        !           224:  * ItemFlags returns the state of item "n" of the menu.
        !           225:  */
        !           226: ItemFlags(menu, n)
        !           227: register Menu *menu;
        !           228: register int n;
        !           229: {
        !           230:        register MenuItem *item;
        !           231: 
        !           232:        if(!menu || !menu->menuItems || n < 0)
        !           233:                return(-1);
        !           234:        for(item = menu->menuItems ; n > 0 ; n--)
        !           235:                if(!(item = item->nextItem))
        !           236:                        return(0);
        !           237:        return((item->itemFlags & itemSetMask) >> itemSetMaskShift);
        !           238: }
        !           239: 
        !           240: /*
        !           241:  * ItemText changes the text of item "n" of the menu.
        !           242:  */
        !           243: ItemText(menu, n, text)
        !           244: register Menu *menu;
        !           245: register int n;
        !           246: char *text;
        !           247: {
        !           248:        register MenuItem *item;
        !           249: 
        !           250:        if(!menu || !menu->menuItems || n < 0 || !text)
        !           251:                return(0);
        !           252:        for(item = menu->menuItems ; n > 0 ; n--)
        !           253:                if(!(item = item->nextItem))
        !           254:                        return(0);
        !           255:        item->itemText = text;
        !           256:        menu->menuFlags |= menuChanged;
        !           257:        return(1);
        !           258: }
        !           259: 
        !           260: /*
        !           261:  * NewMenu() returns a pointer to an initialized new Menu structure, or NULL
        !           262:  * if failed.
        !           263:  *
        !           264:  * The Menu structure _menuDefault contains the default menu settings.
        !           265:  */
        !           266: Menu *NewMenu(name, reverse)
        !           267: char *name;
        !           268: int reverse;
        !           269: {
        !           270:        register Menu *menu;
        !           271:        register int fg, bg;
        !           272:        register TScreen *screen = &term.screen;
        !           273:        XGCValues xgc;
        !           274:        extern char *malloc();
        !           275:        extern XFontStruct *XLoadQueryFont();
        !           276:        register Display *dpy = screen->display;
        !           277: 
        !           278:        /*
        !           279:         * If the GrayTile hasn't been defined, InitMenu() was never
        !           280:         * run, so exit.
        !           281:         */
        !           282:        if(!Gray_Tile)
        !           283:                return((Menu *)0);
        !           284:        /*
        !           285:         * Allocate the memory for the menu structure.
        !           286:         */
        !           287:        if((menu = (Menu *)malloc(sizeof(Menu))) == (Menu *)0)
        !           288:                return((Menu *)0);
        !           289:        /*
        !           290:         * Initialize to default values.
        !           291:         */
        !           292:        *menu = Menu_Default;
        !           293:        /*
        !           294:         * If the menu cursor hasn't been given, make a default one.
        !           295:         */
        !           296:        if(!menu->menuCursor) {
        !           297:                if(!Menu_DefaultCursor) {
        !           298:                        if(reverse) {
        !           299:                                fg = WhitePixel(dpy, 
        !           300:                                        DefaultScreen(dpy));
        !           301:                                bg = BlackPixel(dpy, 
        !           302:                                        DefaultScreen(dpy));
        !           303:                        } else {
        !           304:                                fg = BlackPixel(dpy, 
        !           305:                                        DefaultScreen(dpy));
        !           306:                                bg = WhitePixel(dpy, 
        !           307:                                        DefaultScreen(dpy));
        !           308:                        }
        !           309:                        if(!(Menu_DefaultCursor =
        !           310:                           XCreateFontCursor(dpy, XC_left_ptr)))
        !           311:                                return((Menu *)0);
        !           312:                }
        !           313:                menu->menuCursor = Menu_DefaultCursor;
        !           314:        }
        !           315:        /*
        !           316:         * Initialze the default background and border pixmaps and foreground
        !           317:         * and background colors (black and white).
        !           318:         */
        !           319:        if(reverse) {
        !           320:                menu->menuFgColor = WhitePixel(dpy, 
        !           321:                        DefaultScreen(dpy));
        !           322:                menu->menuBgColor = BlackPixel(dpy, 
        !           323:                        DefaultScreen(dpy));
        !           324:        } else {
        !           325:                menu->menuFgColor = BlackPixel(dpy, 
        !           326:                        DefaultScreen(dpy));
        !           327:                menu->menuBgColor = WhitePixel(dpy, 
        !           328:                        DefaultScreen(dpy));
        !           329:        }
        !           330:        if(!gotGCs) {
        !           331:                xgc.foreground = menu->menuFgColor;
        !           332:                xgc.function = GXinvert;
        !           333:                xgc.plane_mask = XOR(menu->menuFgColor, menu->menuBgColor);
        !           334:                MenuInvertGC = XCreateGC(dpy, DefaultRootWindow(dpy),
        !           335:                  GCForeground+GCFunction+GCPlaneMask, &xgc);
        !           336:                xgc.foreground = menu->menuFgColor;
        !           337:                xgc.background = menu->menuBgColor;
        !           338:                xgc.font = menu->menuFontInfo->fid;
        !           339:                xgc.function = GXcopy;
        !           340:                xgc.fill_style = FillSolid;
        !           341:                MenuGC = XCreateGC(dpy, DefaultRootWindow(dpy),
        !           342:                 MenugcFontMask+GCForeground+GCBackground+GCFunction+GCFillStyle,
        !           343:                 &xgc);
        !           344:                xgc.foreground = menu->menuBgColor;
        !           345:                xgc.background = menu->menuFgColor;
        !           346:                xgc.font = menu->menuFontInfo->fid;
        !           347:                xgc.function = GXcopy;
        !           348:                xgc.fill_style = FillSolid;
        !           349:                MenuInverseGC = XCreateGC(dpy, DefaultRootWindow(dpy),
        !           350:                 MenugcFontMask+GCForeground+GCBackground+GCFunction+GCFillStyle,
        !           351:                 &xgc);
        !           352:                xgc.foreground = menu->menuFgColor;
        !           353:                xgc.background = menu->menuBgColor;
        !           354:                xgc.function = menu->menuFgColor ? GXor : GXand;
        !           355: /*             xgc.function = GXcopy;*/
        !           356:                xgc.stipple = Gray_Tile;
        !           357:                xgc.fill_style = FillStippled;
        !           358:                MenuGrayGC = XCreateGC(dpy, DefaultRootWindow(dpy),
        !           359:                 GCStipple+GCFillStyle+MenugcFontMask
        !           360:                                       +GCForeground+GCBackground+GCFunction, 
        !           361:                 &xgc);
        !           362:                gotGCs = TRUE;
        !           363:        }
        !           364:        /*
        !           365:         * Set the menu title.  If name is NULL or is an empty string, no
        !           366:         * title will be displayed.
        !           367:         */
        !           368:        if(name && *name) {
        !           369:                menu->menuTitleLength = strlen(menu->menuTitle = name);
        !           370:                menu->menuTitleWidth = XTextWidth(menu->menuFontInfo, name, 
        !           371:                 menu->menuTitleLength);
        !           372:                menu->menuItemTop = menu->menuFontInfo->ascent + 
        !           373:                 menu->menuFontInfo->descent + 2 * menu->menuItemPad + 1;
        !           374:        } else
        !           375:                menu->menuTitleLength = menu->menuTitleWidth =
        !           376:                 menu->menuItemTop = 0;
        !           377:        return(menu);
        !           378: }
        !           379: 
        !           380: /*
        !           381:  * SetItemCheck sets the check state of item "n" of the menu to "state".
        !           382:  */
        !           383: SetItemCheck(menu, n, state)
        !           384: register Menu *menu;
        !           385: register int n;
        !           386: int state;
        !           387: {
        !           388:        register MenuItem *item;
        !           389: 
        !           390:        if(!menu || !menu->menuItems || n < 0)
        !           391:                return(0);
        !           392:        for(item = menu->menuItems ; n > 0 ; n--)
        !           393:                if(!(item = item->nextItem))
        !           394:                        return(0);
        !           395:        if(state)
        !           396:                item->itemFlags |= itemSetChecked;
        !           397:        else
        !           398:                item->itemFlags &= ~itemSetChecked;
        !           399:        if(((item->itemFlags & itemSetMask) >> itemSetMaskShift) !=
        !           400:         (item->itemFlags & itemStateMask)) {
        !           401:                item->itemFlags |= itemChanged;
        !           402:                menu->menuFlags |= menuItemChanged;
        !           403:        } else
        !           404:                item->itemFlags &= ~itemChanged;
        !           405:        return(1);
        !           406: }
        !           407: 
        !           408: /*
        !           409:  * SetItemDisable sets the disable state of item "n" of the menu to "state".
        !           410:  */
        !           411: SetItemDisable(menu, n, state)
        !           412: register Menu *menu;
        !           413: register int n;
        !           414: int state;
        !           415: {
        !           416:        register MenuItem *item;
        !           417: 
        !           418:        if(!menu || !menu->menuItems || n < 0)
        !           419:                return(0);
        !           420:        for(item = menu->menuItems ; n > 0 ; n--)
        !           421:                if(!(item = item->nextItem))
        !           422:                        return(0);
        !           423:        if(state)
        !           424:                item->itemFlags |= itemSetDisabled;
        !           425:        else
        !           426:                item->itemFlags &= ~itemSetDisabled;
        !           427:        if(((item->itemFlags & itemSetMask) >> itemSetMaskShift) !=
        !           428:         (item->itemFlags & itemStateMask)) {
        !           429:                item->itemFlags |= itemChanged;
        !           430:                menu->menuFlags |= menuItemChanged;
        !           431:        } else
        !           432:                item->itemFlags &= ~itemChanged;
        !           433:        return(1);
        !           434: }
        !           435: 
        !           436: static Menu *menu;
        !           437: static MenuItem *item;
        !           438: static int i;
        !           439: static MenuItem *hilited_item;
        !           440: static int drawn;
        !           441: static int changed;
        !           442: int y, n, hilited_y, hilited_n, in_window;
        !           443: static MenuItem *Mouse_InItem(), *Y_InItem();
        !           444: static Unmap_Menu();
        !           445: 
        !           446: XtEventReturnCode MenuExposeWindow(event, eventdata)
        !           447: register XEvent *event;
        !           448: caddr_t eventdata;
        !           449: {
        !           450:        register TScreen *screen = &term.screen;
        !           451:        /*
        !           452:         * If we have a saved pixmap, display it.  Otherwise
        !           453:         * redraw the menu and save it away.
        !           454:         */
        !           455:        if (event->type == NoExpose) return;
        !           456:        if(menu->menuSaved) {
        !           457:                XCopyArea(screen->display, menu->menuSaved, menu->menuWindow, 
        !           458:                 MenuGC, 0, 0,
        !           459:                 menu->menuWidth, menu->menuHeight, 0, 0);
        !           460:                /*
        !           461:                 * If the menuItemChanged flag is still set,
        !           462:                 * then we need to redraw certain menu items.
        !           463:                 * ("i" is the vertical position of the top
        !           464:                 * of the current item.)
        !           465:                 */
        !           466:                if(changed & menuItemChanged) {
        !           467:                        i = menu->menuItemTop;
        !           468:                        for(item = menu->menuItems ; item ;
        !           469:                         item = item->nextItem) {
        !           470:                                if(item->itemFlags & itemChanged)
        !           471:                                        Modify_Item(menu, item, i);
        !           472:                                i += item->itemHeight;
        !           473:                        }
        !           474:                }
        !           475:        } else
        !           476:                Draw_Menu(menu);
        !           477:        /*
        !           478:         * If the menu has changed in any way and we want to
        !           479:         * save the menu, throw away any existing save menu
        !           480:         * image and make a new one.
        !           481:         */
        !           482:        XFlush(screen->display);
        !           483:        if(changed && (menu->menuFlags & menuSaveMenu)) {
        !           484:                if(menu->menuSaved)
        !           485:                        XFreePixmap(screen->display, menu->menuSaved);
        !           486: /*             menu->menuSaved = XPixmapSave(screen->display, 
        !           487:                 menu->menuWindow, 0, 0, menu->menuWidth, menu->menuHeight);
        !           488: */
        !           489:        }
        !           490:        /*
        !           491:         * See which item the cursor may currently be in.  If
        !           492:         * it is in a non-disabled item, hilite it.
        !           493:         */
        !           494:        if(hilited_item = Mouse_InItem(menu, &hilited_y, &hilited_n))
        !           495:                XFillRectangle(screen->display, menu->menuWindow, 
        !           496:                 MenuInvertGC, 0, hilited_y,
        !           497:                 menu->menuWidth, hilited_item->itemHeight);
        !           498:        drawn++;
        !           499:        return (XteventHandled);
        !           500: }
        !           501: 
        !           502: XtEventReturnCode MenuMouseMoved(event, eventdata)
        !           503: XButtonEvent *event;
        !           504: caddr_t eventdata;
        !           505: {
        !           506:        register TScreen *screen = &term.screen;
        !           507:        if(!drawn || !in_window)
        !           508:                return;
        !           509:        /*
        !           510:         * See which item the cursor may currently be in.  If
        !           511:         * the item has changed, unhilite the old one and
        !           512:         * then hilited the new one.
        !           513:         */
        !           514:        y = event->y;
        !           515:        if((item = Y_InItem(menu, &y, &n)) != hilited_item) {
        !           516:                if(hilited_item)
        !           517:                        XFillRectangle(screen->display, menu->menuWindow, 
        !           518:                         MenuInvertGC, 0, hilited_y,
        !           519:                         menu->menuWidth, hilited_item->itemHeight);
        !           520:                if(hilited_item = item) {
        !           521:                        XFillRectangle(screen->display, menu->menuWindow, 
        !           522:                         MenuInvertGC, 0,
        !           523:                         hilited_y = y, menu->menuWidth, item->itemHeight);
        !           524:                        hilited_n = n;
        !           525:                }
        !           526:        }
        !           527:        return (XteventHandled);
        !           528: }
        !           529: 
        !           530: XtEventReturnCode MenuEnterWindow(event, eventdata)
        !           531: XEvent *event;
        !           532: caddr_t eventdata;
        !           533: {
        !           534:        in_window = TRUE;
        !           535:        return (MenuMouseMoved(event, eventdata));
        !           536: }
        !           537: 
        !           538: XtEventReturnCode MenuLeaveWindow(event, eventdata)
        !           539: XEvent *event;
        !           540: caddr_t eventdata;
        !           541: {
        !           542:        register TScreen *screen = &term.screen;
        !           543:        if(!drawn)
        !           544:                return (XteventHandled);
        !           545:        /*
        !           546:         * Unhilite any window that is currently hilited.
        !           547:         */
        !           548:        if(hilited_item) {
        !           549:                XFillRectangle(screen->display, menu->menuWindow, 
        !           550:                 MenuInvertGC, 0, hilited_y,
        !           551:                 menu->menuWidth, hilited_item->itemHeight);
        !           552:                hilited_item = (MenuItem *)0;
        !           553:        }
        !           554:        in_window = FALSE;
        !           555:        return (XteventHandled);
        !           556: }
        !           557: 
        !           558: XtEventReturnCode MenuButtonReleased(event, eventdata)
        !           559: XButtonEvent *event;
        !           560: caddr_t eventdata;
        !           561: {
        !           562:        register TScreen *screen = &term.screen;
        !           563:        extern FinishModeMenu();
        !           564: 
        !           565:        /*
        !           566:         * return the index number of any selected menu
        !           567:         * item.
        !           568:         */
        !           569: 
        !           570:        if (! AllButtonsUp(event->state, event->button))
        !           571:                return(XteventHandled);
        !           572: 
        !           573:        XUngrabPointer(screen->display, CurrentTime);
        !           574:        
        !           575:        if(in_window) {
        !           576:                y = event->y;
        !           577:                if((item = Y_InItem(menu, &y, &n)) != hilited_item) {
        !           578:                    if(hilited_item)
        !           579:                        XFillRectangle(screen->display, menu->menuWindow, 
        !           580:                         MenuInvertGC, 0,
        !           581:                         hilited_y, menu->menuWidth,
        !           582:                         hilited_item->itemHeight);
        !           583:                    if(hilited_item = item) {
        !           584:                        XFillRectangle(screen->display, menu->menuWindow, 
        !           585:                         MenuInvertGC, 0,
        !           586:                         hilited_y = y, menu->menuWidth,
        !           587:                         hilited_item->itemHeight);
        !           588:                        hilited_n = n;
        !           589:                    }
        !           590:                }
        !           591:        }
        !           592:        XFlush(screen->display);
        !           593:        menu->menuFlags &= ~(menuChanged | menuItemChanged);
        !           594:        Unmap_Menu(menu);
        !           595:        drawn = 0;
        !           596:        if(hilited_item)
        !           597:                FinishModeMenu(menu->menuInitialItem = hilited_n);
        !           598:        else
        !           599:                FinishModeMenu(-1);
        !           600:        return (XteventHandled);
        !           601: }
        !           602: 
        !           603: /*
        !           604:  * TrackMenu does most of the work of displaying the menu and tracking the
        !           605:  * mouse.
        !           606:  */
        !           607: TrackMenu(lmenu, event)
        !           608: register Menu *lmenu;
        !           609: register XButtonPressedEvent *event;
        !           610: {
        !           611:        register TScreen *screen = &term.screen;
        !           612:        XButtonReleasedEvent ev;
        !           613:        XSetWindowAttributes attr;
        !           614: 
        !           615:        menu = lmenu;
        !           616:        hilited_item = (MenuItem *)0;
        !           617:        /*
        !           618:         * Check that things are reasonable.
        !           619:         */
        !           620:        if(!menu || !event || !menu->menuItems || event->type != ButtonPress)
        !           621:                return(-1);
        !           622:        /*
        !           623:         * Set the changed flag and clear the menu changed flags.
        !           624:         */
        !           625:        changed = menu->menuFlags & (menuChanged | menuItemChanged);
        !           626:        /*
        !           627:         * If the entire menu has changed, throw away any saved pixmap and
        !           628:         * then call RecalcMenu().
        !           629:         */
        !           630:        if(changed & menuChanged) {
        !           631:                if(menu->menuSaved)
        !           632:                        XFreePixmap(screen->display, menu->menuSaved);
        !           633:                menu->menuSaved = (Pixmap)0;
        !           634:                if(!Recalc_Menu(menu))
        !           635:                        return(-1);
        !           636:                changed &= ~menuItemChanged;
        !           637:        }
        !           638:        /*
        !           639:         * Now if the window was never created, go ahead and make it.  Otherwise
        !           640:         * if the menu has changed, resize the window.
        !           641:         */
        !           642:        if(!menu->menuWindow) {
        !           643:                attr.override_redirect = TRUE;
        !           644:                attr.border_pixmap = make_gray(
        !           645:                  WhitePixel(screen->display, DefaultScreen(screen->display)), 
        !           646:                  BlackPixel(screen->display, DefaultScreen(screen->display)), 
        !           647:                  DefaultDepth(screen->display, DefaultScreen(screen->display)));
        !           648:                attr.background_pixel = menu->menuBgColor;
        !           649:                attr.cursor = menu->menuCursor;
        !           650:                if((menu->menuWindow = XCreateWindow(screen->display, 
        !           651:                 DefaultRootWindow(screen->display), 0, 0,
        !           652:                 menu->menuWidth, menu->menuHeight, menu->menuBorderWidth,
        !           653:                 0, CopyFromParent, CopyFromParent, 
        !           654:                 CWBorderPixmap+CWBackPixel+CWOverrideRedirect+CWCursor, 
        !           655:                 &attr)) == (Window)0)
        !           656:                        return(-1);
        !           657: 
        !           658: 
        !           659:                XtSetEventHandler(screen->display, menu->menuWindow,
        !           660:                 (XtEventHandler) MenuExposeWindow, ExposureMask, 
        !           661:                 (caddr_t)NULL);
        !           662:                XtSetEventHandler(screen->display, menu->menuWindow,
        !           663:                 (XtEventHandler) MenuEnterWindow, EnterWindowMask, 
        !           664:                 (caddr_t)NULL);
        !           665:                XtSetEventHandler(screen->display, menu->menuWindow,
        !           666:                 (XtEventHandler) MenuLeaveWindow, LeaveWindowMask, 
        !           667:                 (caddr_t)NULL);
        !           668:                XtSetEventHandler(screen->display, menu->menuWindow,
        !           669:                 (XtEventHandler) MenuMouseMoved, PointerMotionMask, 
        !           670:                 (caddr_t)NULL);
        !           671:                XtSetEventHandler(screen->display, menu->menuWindow,
        !           672:                 (XtEventHandler) MenuButtonReleased, ButtonReleaseMask,
        !           673:                 (caddr_t)NULL);
        !           674:                XtSetEventHandler(screen->display, menu->menuWindow,
        !           675:                 (XtEventHandler) EventDoNothing, ButtonPressMask, 
        !           676:                 (caddr_t)NULL);
        !           677:        } else if(changed & menuChanged)
        !           678:                XResizeWindow(screen->display, menu->menuWindow, 
        !           679:                 menu->menuWidth, menu->menuHeight);
        !           680:        /*
        !           681:         * Figure out where the menu is supposed to go, from the initial button
        !           682:         * press, and move the window there.  Then map the menu.
        !           683:         */
        !           684:        if(!Move_Menu(menu, event) || !Map_Menu(menu))
        !           685:                return(-1);
        !           686: 
        !           687:        menuWindow = menu->menuWindow;
        !           688:        in_window = TRUE;
        !           689:        XGrabPointer(screen->display, menu->menuWindow, FALSE,
        !           690:         ExposureMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask
        !           691:         | ButtonReleaseMask | ButtonPressMask,
        !           692:         GrabModeAsync, GrabModeAsync, None, menu->menuCursor, CurrentTime
        !           693:         );
        !           694: }
        !           695: 
        !           696: /*
        !           697:  * Recalculate all of the various menu and item variables.
        !           698:  */
        !           699: static Recalc_Menu(menu)
        !           700: register Menu *menu;
        !           701: {
        !           702:        register MenuItem *item;
        !           703:        register int max, i, height, fontheight;
        !           704: 
        !           705:        /*
        !           706:         * We must have already gotten the menu font.
        !           707:         */
        !           708:        if(!menu->menuFontInfo)
        !           709:                return(0);
        !           710:        /*
        !           711:         * Initialize the various max width variables.
        !           712:         */
        !           713:        fontheight = menu->menuFontInfo->ascent + menu->menuFontInfo->descent;
        !           714:        height = menu->menuItemTop;
        !           715:        menu->menuMaxTextWidth = menu->menuTitleWidth;
        !           716:        /*
        !           717:         * The item height is the maximum of the font height and the
        !           718:         * checkbox height.
        !           719:         */
        !           720:        max = fontheight;
        !           721:        if(checkMarkHeight > max)
        !           722:                max = checkMarkHeight;
        !           723:        /*
        !           724:         * Go through the menu item list.
        !           725:         */
        !           726:        for(item = menu->menuItems ; item ; item = item->nextItem) {
        !           727:                /*
        !           728:                 * If the item text is a single dash, we assume this is
        !           729:                 * a line separator and treat it special.
        !           730:                 */
        !           731:                if(XStrCmp(item->itemText, "-") == 0)
        !           732:                        height += (item->itemHeight = lineSeparatorHeight);
        !           733:                else {
        !           734:                        height += (item->itemHeight = max);
        !           735:                        /*
        !           736:                         * Check the text width with the max value stored in
        !           737:                         * menu.
        !           738:                         */
        !           739:                        if((item->itemTextWidth = XTextWidth(
        !           740:                          menu->menuFontInfo, item->itemText,
        !           741:                          strlen(item->itemText))) > menu->menuMaxTextWidth)
        !           742:                                menu->menuMaxTextWidth = item->itemTextWidth;
        !           743:                }
        !           744:                /*
        !           745:                 * If the itemChanged flag is set, set the state bits.
        !           746:                 */
        !           747:                if(item->itemFlags & itemChanged) {
        !           748:                        item->itemFlags = (item->itemFlags & ~itemStateMask) |
        !           749:                         ((item->itemFlags & itemSetMask) >> itemSetMaskShift);
        !           750:                        item->itemFlags &= ~itemChanged;
        !           751:                }
        !           752:        }
        !           753:        /*
        !           754:         * Set the menu height and then set the menu width.
        !           755:         */
        !           756:        menu->menuHeight = height;
        !           757:        menu->menuWidth = 3 * menu->menuItemPad + menu->menuMaxTextWidth +
        !           758:         checkMarkWidth;
        !           759:        return(1);
        !           760: }
        !           761: 
        !           762: /*
        !           763:  * Figure out where to popup the menu, relative to the where the button was
        !           764:  * pressed.
        !           765:  */
        !           766: static Move_Menu(menu, ev)
        !           767: register Menu *menu;
        !           768: XButtonPressedEvent *ev;
        !           769: {
        !           770:        register MenuItem *item;
        !           771:        register int n, x, y;
        !           772:        register TScreen *screen = &term.screen;
        !           773:        int total_width;
        !           774:        Window subw;
        !           775:        /*
        !           776:         * Try to popup the menu so that the cursor is centered within the
        !           777:         * width of the menu, but compensate if that would run it outside
        !           778:         * the display area.
        !           779:         */
        !           780:        total_width = menu->menuWidth + 2 * menu->menuBorderWidth;
        !           781:        if((x = ev->x_root - total_width / 2) < 0)
        !           782:                x = 0;
        !           783:        else if(x + total_width > DisplayWidth(screen->display,
        !           784:                                               DefaultScreen(screen->display)))
        !           785:                x = DisplayWidth(screen->display,
        !           786:                                 DefaultScreen(screen->display)) - total_width;
        !           787:        /*
        !           788:         * If the menu extends above outside of the display, warp
        !           789:         * the mouse vertically so the menu will all show up.
        !           790:         */
        !           791:        if((y = ev->y_root) < 0) {
        !           792: /* don't bother warping pointer 
        !           793:                XWarpPointer(screen->display, None, 
        !           794:                  DefaultRootWindow(screen->display), 0, 0, 0, 0, ev->x_root, 
        !           795:                    0);
        !           796: */
        !           797:                y = 0;
        !           798:        } else if((n = y + menu->menuHeight + 2 * menu->menuBorderWidth - 
        !           799:          DisplayHeight(screen->display, DefaultScreen(screen->display))) > 0) {
        !           800: /* don't bother warping pointer 
        !           801:                XWarpPointer(screen->display, None,
        !           802:                 DefaultRootWindow(screen->display), 0, 0, 0, 0, ev->x_root, 
        !           803:                  ev->y_root - n);
        !           804: */
        !           805:                y -= n;
        !           806:        }
        !           807:        XMoveWindow(screen->display, menu->menuWindow, x, y);
        !           808:        /*
        !           809:         * If we are in freeze mode, save what will be the coordinates of
        !           810:         * the save image.
        !           811:         */
        !           812:        if(menu->menuFlags & menuFreeze) {
        !           813:                menu->menuSavedImageX = x;
        !           814:                menu->menuSavedImageY = y;
        !           815:        }
        !           816:        return(1);
        !           817: }
        !           818: 
        !           819: /*
        !           820:  * Map the menu window.
        !           821:  */
        !           822: static Map_Menu(menu)
        !           823: register Menu *menu;
        !           824: {
        !           825:        register int i;
        !           826:        register TScreen *screen = &term.screen;
        !           827: 
        !           828:        /*
        !           829:         * If we are in freeze mode, save the pixmap underneath where the menu
        !           830:         * will be (including the border).
        !           831:         */
        !           832:        if(menu->menuFlags & menuFreeze) {
        !           833:                XGrabServer(screen->display);
        !           834:                i = 2 * menu->menuBorderWidth;
        !           835: /*             if((menu->menuSavedImage = XPixmapSave(screen->display,
        !           836:                 DefaultRootWindow(screen->display),
        !           837:                 menu->menuSavedImageX, menu->menuSavedImageY, menu->menuWidth
        !           838:                 + i, menu->menuHeight + i)) == (Pixmap)0)
        !           839: */
        !           840:                        return(0);
        !           841:        }
        !           842:        /*
        !           843:         * Actually map the window.
        !           844:         */
        !           845:        XMapRaised(screen->display, menu->menuWindow);
        !           846:        menu->menuFlags |= menuMapped;
        !           847:        return(1);
        !           848: }
        !           849: 
        !           850: /*
        !           851:  * Draw the entire menu in the blank window.
        !           852:  */
        !           853: static Draw_Menu(menu)
        !           854: register Menu *menu;
        !           855: {
        !           856:        register MenuItem *item;
        !           857:        register int top = menu->menuItemTop;
        !           858:        register int x = menu->menuItemPad;
        !           859:        register int y, dim;
        !           860:        register TScreen *screen = &term.screen;
        !           861: 
        !           862:        /*
        !           863:         * If we have a menu title, draw it first, centered and hilited.
        !           864:         */
        !           865:        if(menu->menuTitleLength) {
        !           866:                XFillRectangle(screen->display, menu->menuWindow, 
        !           867:                 MenuGC, 0, 0, menu->menuWidth, top - 1);
        !           868:                XDrawImageString(screen->display, menu->menuWindow, 
        !           869:                 MenuInverseGC, (menu->menuWidth -
        !           870:                 menu->menuTitleWidth) / 2, 
        !           871:                 menu->menuItemPad+menu->menuFontInfo->ascent, 
        !           872:                 menu->menuTitle, menu->menuTitleLength);
        !           873:        }
        !           874:        /*
        !           875:         * For each item in the list, first draw any check mark and then
        !           876:         * draw the rest of it.
        !           877:         */
        !           878:        for(item = menu->menuItems ; item ; item = item->nextItem) {
        !           879:                SetStateFlags(item);
        !           880:                dim = (item->itemFlags & itemDisabled);
        !           881:                /*
        !           882:                 * Draw the check mark, possibly dimmed, wherever is necessary.
        !           883:                 */
        !           884:                if(item->itemFlags & itemChecked) {
        !           885:                        XCopyArea(screen->display, 
        !           886:                         Check_Tile, menu->menuWindow, 
        !           887:                         dim ? MenuGrayGC : MenuGC,
        !           888:                         0, 0, checkMarkWidth, checkMarkHeight, x, 
        !           889:                         y = top + (item->itemHeight - checkMarkHeight) / 2);
        !           890:                }
        !           891:                /*
        !           892:                 * Draw the item, possibly dimmed.
        !           893:                 */
        !           894:                Draw_Item(menu, item, top, dim);
        !           895:                top += item->itemHeight;
        !           896:        }
        !           897: }
        !           898: 
        !           899: /*
        !           900:  * Modify the item at vertical position y.  This routine is table driven and
        !           901:  * the state and set bits are each 2 bits long, contiguous, the least
        !           902:  * significant bits in the flag word and with the state bits in bits 0 & 1.
        !           903:  */
        !           904: 
        !           905: #define        drawCheck       0x10
        !           906: #define        removeCheck     0x08
        !           907: #define        dimCheck        0x04
        !           908: #define        drawItem        0x02
        !           909: #define        dimItem         0x01
        !           910: 
        !           911: static char Modify_Table[] = {
        !           912:        0x00, 0x02, 0x08, 0x0a, 0x01, 0x00, 0x09, 0x08,
        !           913:        0x10, 0x12, 0x00, 0x12, 0x15, 0x14, 0x05, 0x00
        !           914: };
        !           915:        
        !           916: static Modify_Item(menu, item, top)
        !           917: register Menu *menu;
        !           918: register MenuItem *item;
        !           919: int top;
        !           920: {
        !           921:        register int x = menu->menuItemPad;
        !           922:        register int y;
        !           923:        register int center = top + item->itemHeight / 2;
        !           924:        register int func = Modify_Table[item->itemFlags &
        !           925:         (itemStateMask | itemSetMask)];
        !           926:        register TScreen *screen = &term.screen;
        !           927: 
        !           928:        /*
        !           929:         * If we really won't be making a change, return.
        !           930:         */
        !           931:        if(func == 0)
        !           932:                return;
        !           933:        /*
        !           934:         * Draw the check mark if needed, possibly dimmed.
        !           935:         */
        !           936:        y = center - (checkMarkHeight / 2);
        !           937:        if(func & (drawCheck | dimCheck))
        !           938:                XCopyArea(screen->display, 
        !           939:                 Check_Tile, menu->menuWindow, 
        !           940:                 (func & dimCheck) ? MenuGrayGC : MenuGC,
        !           941:                 0, 0, checkMarkWidth, checkMarkHeight, x, 
        !           942:                  y = top + (item->itemHeight - checkMarkHeight) / 2);
        !           943:        /*
        !           944:         * Remove the check mark if needed.
        !           945:         */
        !           946:        if(func & removeCheck)
        !           947:                XClearArea(screen->display, menu->menuWindow, 
        !           948:                 x, y, checkMarkWidth, checkMarkHeight);
        !           949:        /*
        !           950:         * Call Draw_Item if we need to draw or dim the item.
        !           951:         */
        !           952:        if((x = func & dimItem) || (func & drawItem))
        !           953:                Draw_Item(menu, item, top, x);
        !           954:        /*
        !           955:         * Update state flags.
        !           956:         */
        !           957:        SetStateFlags(item);
        !           958: }
        !           959: 
        !           960: /*
        !           961:  * Draw the item (less check mark) at vertical position y.
        !           962:  * Dim the item if "dim" is set.
        !           963:  */
        !           964: static Draw_Item(menu, item, y, dim)
        !           965: register Menu *menu;
        !           966: register MenuItem *item;
        !           967: register int y;
        !           968: int  dim;
        !           969: {
        !           970:        register int x = 2 * menu->menuItemPad + checkMarkWidth;
        !           971:        register int center = y + item->itemHeight / 2;
        !           972:        register TScreen *screen = &term.screen;
        !           973: 
        !           974:        /*
        !           975:         * If the item text is a single dash, draw a separating line.
        !           976:         */
        !           977:        if(XStrCmp(item->itemText, "-") == 0) {
        !           978:                XDrawLine(screen->display, menu->menuWindow,  MenuGC,
        !           979:                 0, center, menu->menuWidth, center);
        !           980:                return;
        !           981:        }
        !           982:        /*
        !           983:         * Draw and/or dim the text, centered vertically.
        !           984:         */
        !           985:        y = center - 
        !           986:         ((menu->menuFontInfo->ascent + menu->menuFontInfo->descent)/ 2);
        !           987:        if(dim) {
        !           988:                XDrawString(screen->display, menu->menuWindow, MenuGrayGC,
        !           989:                 x, y+menu->menuFontInfo->ascent, 
        !           990:                 item->itemText, item->itemTextLength);
        !           991:        } else
        !           992:                XDrawImageString(screen->display, menu->menuWindow, 
        !           993:                 MenuGC, x, y+menu->menuFontInfo->ascent, 
        !           994:                 item->itemText, item->itemTextLength);
        !           995: }
        !           996: 
        !           997: /*
        !           998:  * Determine which enabled menu item the mouse is currently in.  Return the
        !           999:  * top position of this item and its item number.  Set inwindow to whether
        !          1000:  * we are or not.
        !          1001:  */
        !          1002: static MenuItem *Mouse_InItem(menu, top, n)
        !          1003: register Menu *menu;
        !          1004: int *top, *n;
        !          1005: {
        !          1006:        int x, y, rootx, rooty, mask;
        !          1007:        Window subw, root;
        !          1008:        static MenuItem *Y_InItem();
        !          1009:        register TScreen *screen = &term.screen;
        !          1010: 
        !          1011:        /*
        !          1012:         * Find out where the mouse is.  If its not in the menu window,
        !          1013:         * return NULL.
        !          1014:         */
        !          1015:        XQueryPointer(screen->display, menu->menuWindow, 
        !          1016:        &root, &subw, &rootx, &rooty, &x, &y, &mask);
        !          1017:        if((x <0) || (y < 0) || 
        !          1018:           (x > menu->menuWidth) || (y > menu->menuHeight)) {
        !          1019:                return((MenuItem *)0);
        !          1020:        }
        !          1021:        /*
        !          1022:         * Call Y_InItem().
        !          1023:         */
        !          1024:        *top = y;
        !          1025:        return(Y_InItem(menu, top, n));
        !          1026: }
        !          1027: 
        !          1028: /*
        !          1029:  * Return which enabled item the locator is in.  Also return the
        !          1030:  * top position of this item and its item number.  Initial y passed
        !          1031:  * in top.
        !          1032:  */
        !          1033: static MenuItem *Y_InItem(menu, top, n)
        !          1034: register Menu *menu;
        !          1035: int *top, *n;
        !          1036: {
        !          1037:        register MenuItem *item;
        !          1038:        register int t, i;
        !          1039:        register int y = *top;
        !          1040:        Window subw;
        !          1041: 
        !          1042:        /*
        !          1043:         * Go through the item list.  "t" is the vertical position of the
        !          1044:         * current item and "i" is its item number.
        !          1045:         */
        !          1046:        t = menu->menuItemTop;
        !          1047:        /*
        !          1048:         * If the mouse is before the first item, return.
        !          1049:         */
        !          1050:        if(y < t)
        !          1051:                return((MenuItem *)0);
        !          1052:        for(i = 0, item = menu->menuItems ; item ; i++, item = item->nextItem) {
        !          1053:                /*
        !          1054:                 * If the y coordinate is within this menu item, then return.
        !          1055:                 * But don't return disable items.
        !          1056:                 */
        !          1057:                if(t + item->itemHeight > y) {
        !          1058:                        if(item->itemFlags & itemDisabled)
        !          1059:                                return((MenuItem *)0);
        !          1060:                        *top = t;
        !          1061:                        *n = i;
        !          1062:                        return(item);
        !          1063:                }
        !          1064:                t += item->itemHeight;
        !          1065:        }
        !          1066:        /*
        !          1067:         * Should never get here.
        !          1068:         */
        !          1069:        return((MenuItem *)0);
        !          1070: }
        !          1071: 
        !          1072: /*
        !          1073:  * Unmap_Menu() unmaps a menu, if it is currently mapped.
        !          1074:  */
        !          1075: static Unmap_Menu(menu)
        !          1076: register Menu *menu;
        !          1077: {
        !          1078:        register int i;
        !          1079:        register TScreen *screen = &term.screen;
        !          1080: 
        !          1081:        if(!menu || !(menu->menuFlags & menuMapped))
        !          1082:                return;
        !          1083:        if(menu->menuFlags & menuFreeze) {
        !          1084:                XUnmapWindow(screen->display, menu->menuWindow);
        !          1085:                i = 2 * menu->menuBorderWidth;
        !          1086:                XCopyArea(screen->display, 
        !          1087:                 menu->menuSavedImage, DefaultRootWindow(screen->display), 
        !          1088:                 MenuGC, 0, 0, menu->menuWidth + i,
        !          1089:                 menu->menuHeight + i, menu->menuSavedImageX, 
        !          1090:                 menu->menuSavedImageY);
        !          1091:                XFreePixmap(screen->display, menu->menuSavedImage);
        !          1092:                XUngrabServer(screen->display);
        !          1093:        } else
        !          1094:                XUnmapWindow(screen->display, menu->menuWindow);
        !          1095:        menu->menuFlags &= ~menuMapped;
        !          1096: }
        !          1097: #endif MODEMENU

unix.superglobalmegacorp.com

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