Annotation of 43BSD/contrib/X/uwm/uwm.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *rcsid_uwm_c = "$Header: uwm.c,v 10.4 86/02/01 16:24:27 tony Rel $";
                      3: #endif lint
                      4: 
                      5: /************************************************************************
                      6:  *                                                                     *
                      7:  *                     Copyright (c) 1986 by                           *
                      8:  *             Digital Equipment Corporation, Maynard, MA              *
                      9:  *                      All Rights Reserved.                           *
                     10:  *                                                                     *
                     11:  *     Permission to use, copy, modify, and distribute this software   *
                     12:  *     and its documentation is hereby granted only to licensees of    *
                     13:  *     The Regents of the University of California pursuant to their   *
                     14:  *     license agreement for the Berkeley Software Distribution        *
                     15:  *     provided that the following appears on all copies.              *
                     16:  *                                                                     *
                     17:  *            "LICENSED FROM DIGITAL EQUIPMENT CORPORATION             *
                     18:  *                      COPYRIGHT (C) 1986                             *       
                     19:  *                 DIGITAL EQUIPMENT CORPORATION                       *
                     20:  *                         MAYNARD, MA                                 *
                     21:  *                     ALL RIGHTS RESERVED.                            *
                     22:  *                                                                     *
                     23:  *      THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  * 
                     24:  *     NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL   *
                     25:  *     EQUIPMENT CORPORATION.  DIGITAL MAKES NO REPRESENTATIONS        *
                     26:  *     ABOUT SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS       *
                     27:  *     SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.           *
                     28:  *                                                                     *       
                     29:  *     IF THE UNIVERSITY OF CALIFORNIA OR ITS LICENSEES MODIFY         *       
                     30:  *     THE SOFTWARE IN A MANNER CREATING DERIVATIVE COPYRIGHT          *       
                     31:  *     RIGHTS APPROPRIATE COPYRIGHT LEGENDS MAY BE PLACED ON THE       *
                     32:  *     DERIVATIVE WORK IN ADDITION TO THAT SET FORTH ABOVE."           *       
                     33:  *                                                                     *
                     34:  ************************************************************************/
                     35:  
                     36: 
                     37: /*
                     38:  * MODIFICATION HISTORY
                     39:  *
                     40:  * 000 -- M. Gancarz, DEC Ultrix Engineering Group
                     41:  */
                     42: 
                     43: #ifndef lint
                     44: static char *sccsid = "@(#)uwm.c       3.8     1/24/86";
                     45: #endif
                     46: 
                     47: #include <sys/time.h>
                     48: #include "uwm.h"
                     49: 
                     50: #ifdef PROFIL
                     51: #include <signal.h>
                     52: /*
                     53:  * Dummy handler for profiling.
                     54:  */
                     55: ptrap()
                     56: {
                     57:     exit(0);
                     58: }
                     59: #endif
                     60: 
                     61: #include <fcntl.h>
                     62: 
                     63: static short gray_bits[16] = {
                     64:     0xaaaa, 0x5555, 0xaaaa, 0x5555,
                     65:     0xaaaa, 0x5555, 0xaaaa, 0x5555,
                     66:     0xaaaa, 0x5555, 0xaaaa, 0x5555,
                     67:     0xaaaa, 0x5555, 0xaaaa, 0x5555
                     68: };
                     69: 
                     70: Bool ChkMline();
                     71: char *sfilename;
                     72: extern FILE *yyin;
                     73: 
                     74: /*
                     75:  * Main program.
                     76:  */
                     77: main(argc, argv, environ)
                     78: int argc;
                     79: char **argv;
                     80: char **environ;
                     81: {
                     82:     short hi;                  /* Button event high detail. */
                     83:     short lo;                  /* Button event low detail. */
                     84:     int x, y;                   /* Mouse X and Y coordinates. */
                     85:     int cur_x, cur_y;          /* Current mouse X and Y coordinates. */
                     86:     int str_width;              /* Width in pixels of output string. */
                     87:     int pop_width, pop_height;  /* Pop up window width and height. */
                     88:     int context;               /* Root, window, or icon context. */
                     89:     Bool func_stat;            /* If true, function swallowed a ButtonUp. */
                     90:     Bool delta_done;           /* If true, then delta functions are done. */
                     91:     register Binding *bptr;    /* Pointer to Bindings list. */
                     92:     char *root_name;           /* Root window name. */
                     93:     char *display = NULL;      /* Display name pointer. */
                     94:     char message[128];         /* Error message buffer. */
                     95:     char *rc_file;             /* Pointer to $HOME/.uwmrc. */
                     96:     Bitmap gray_bitmap;                /* Gray bitmap used for gray pixmap. */
                     97:     Display *dpy;              /* Display info pointer. */
                     98:     Window event_win;           /* Event window. */
                     99:     Window sub_win;            /* Subwindow for XUpdateMouse calls. */
                    100:     WindowInfo root_info;      /* Root window info. */
                    101:     WindowInfo event_info;     /* Event window info. */
                    102:     XButtonEvent button_event;  /* Button input event. */
                    103:     char *malloc();
                    104: 
                    105: 
                    106: #ifdef PROFIL
                    107:     signal(SIGTERM, ptrap);
                    108: #endif
                    109: 
                    110:     /*
                    111:      * Set up internal defaults.
                    112:      */
                    113:     strcpy(IFontName, DEF_FONT);
                    114:     strcpy(PFontName, DEF_FONT);
                    115:     strcpy(MFontName, DEF_FONT);
                    116:     CursorFunc = DEF_FUNC;
                    117:     Delta = DEF_DELTA;
                    118:     IBorderWidth = DEF_ICON_BORDER_WIDTH;
                    119:     HIconPad = DEF_ICON_PADDING;
                    120:     VIconPad = DEF_ICON_PADDING;
                    121:     PBorderWidth = DEF_POP_BORDER_WIDTH;
                    122:     PPadding = DEF_POP_PADDING;
                    123:     MBorderWidth = DEF_MENU_BORDER_WIDTH;
                    124:     HMenuPad = DEF_MENU_PADDING;
                    125:     VMenuPad = DEF_MENU_PADDING;
                    126:     Volume = DEF_VOLUME;
                    127: 
                    128:     /*
                    129:      * Set XErrorFunction to be non-terminating.
                    130:      */
                    131:     XErrorHandler(XError);
                    132: 
                    133:     /* 
                    134:      * Parse the command line arguments.
                    135:      */
                    136:     Argv = argv;
                    137:     Environ = environ;
                    138:     argc--, argv++;
                    139:     while (argc) {
                    140:         if (!(strcmp(*argv, "-f"))) {
                    141:             argc--, argv++;
                    142:             if ((argc == 0) || (Startup_File[0] != '\0'))
                    143:                 Usage();
                    144:             strncpy(Startup_File, *argv, NAME_LEN);
                    145:         }
                    146:         else display = *argv;
                    147:        argc--, argv++;
                    148:     }
                    149: 
                    150:     /*
                    151:      * Initialize the default bindings.
                    152:      */
                    153:     InitBindings();
                    154: 
                    155:     /*
                    156:      * Read in and parse $HOME/.uwmrc, if it exists.
                    157:      */
                    158:     sfilename = rc_file = malloc(NAME_LEN);
                    159:     sprintf(rc_file, "%s/.uwmrc", getenv("HOME"));
                    160:     if ((yyin = fopen(rc_file, "r")) != NULL) {
                    161:         Lineno = 1;
                    162:         yyparse();
                    163:         fclose(yyin);
                    164:         if (Startup_File_Error)
                    165:             Error("Bad .uwmrc file...aborting");
                    166:     }
                    167: 
                    168:     /* 
                    169:      * Read in and parse the startup file from the command line, if
                    170:      * specified.
                    171:      */
                    172:     if (Startup_File[0] != '\0') {
                    173:         sfilename = Startup_File;
                    174:         if ((yyin = fopen(Startup_File, "r")) == NULL) {
                    175:        sprintf(message, "Cannot open startup file '%s'", Startup_File);
                    176:             Error(message);
                    177:         }
                    178:         Lineno = 1;
                    179:         yyparse();
                    180:         fclose(yyin);
                    181:         if (Startup_File_Error)
                    182:             Error("Bad startup file...aborting");
                    183:     }
                    184: 
                    185:     /*
                    186:      * Verify the menu bindings.
                    187:      */
                    188:     VerifyMenuBindings();
                    189:     if (Startup_File_Error)
                    190:         Error("Bad startup file...aborting");
                    191: 
                    192:     /* 
                    193:      * Open the display.
                    194:      */
                    195:     if ((dpy = XOpenDisplay(display)) == NULL)
                    196:         Error("Unable to open display");
                    197: 
                    198:     /*
                    199:      * Force child processes to disinherit the TCP file descriptor.
                    200:      * This helps shell commands forked and exec'ed from menus
                    201:      * to work properly.
                    202:      */
                    203:     if ((status = fcntl(dpyno(), F_SETFD, 1)) == -1) {
                    204:         perror("uwm: child cannot disinherit TCP fd");
                    205:         Error("TCP file descriptor problems");
                    206:     }
                    207: 
                    208:     /*
                    209:      * If the root window has not been named, name it.
                    210:      */
                    211:     status = XFetchName(RootWindow, &root_name);
                    212:     if (status == FAILURE) Error("Can't fetch Root Window name string");
                    213:     if (root_name == NULL) XStoreName(RootWindow, " X Root Window ");
                    214:     if (root_name) free(root_name);
                    215: 
                    216:     /*
                    217:      * Gather information about the root window.
                    218:      */
                    219:     status = XQueryWindow(RootWindow, &root_info);
                    220:     if (status == FAILURE)
                    221:         Error("Can't acquire root window information from X server");
                    222: 
                    223:     ScreenHeight = root_info.height;   /* True height of entire screen */
                    224:     ScreenWidth = root_info.width;     /* True width of entire screen */
                    225: 
                    226:     /*
                    227:      * Create and store the icon background pixmap.
                    228:      */
                    229:     gray_bitmap = XStoreBitmap(16, 16, gray_bits);
                    230:     GrayPixmap = XMakePixmap(gray_bitmap, BlackPixel, WhitePixel);
                    231: 
                    232:     /*
                    233:      * Set up icon window, icon cursor and pop-up window color parameters.
                    234:      */
                    235:     if (Reverse) {
                    236:         IconCursorFunc = GXcopyInverted;
                    237:         IBorder = WhitePixmap;
                    238:         IBackground = GrayPixmap;
                    239:         ITextForground = WhitePixel;
                    240:         ITextBackground = BlackPixel;
                    241:         PBorder = BlackPixmap;
                    242:         PBackground = WhitePixmap;
                    243:         PTextForground = BlackPixel;
                    244:         PTextBackground = WhitePixel;
                    245:         MBorder = WhitePixmap;
                    246:         MBackground = BlackPixmap;
                    247:         MTextForground = WhitePixel;
                    248:         MTextBackground = BlackPixel;
                    249:     }
                    250:     else {
                    251:         IconCursorFunc = GXcopy;
                    252:         IBorder = BlackPixmap;
                    253:         IBackground = GrayPixmap;
                    254:         ITextForground = BlackPixel;
                    255:         ITextBackground = WhitePixel;
                    256:         PBorder = WhitePixmap;
                    257:         PBackground = BlackPixmap;
                    258:         PTextForground = WhitePixel;
                    259:         PTextBackground = BlackPixel;
                    260:         MBorder = BlackPixmap;
                    261:         MBackground = WhitePixmap;
                    262:         MTextForground = BlackPixel;
                    263:         MTextBackground = WhitePixel;
                    264:     }
                    265: 
                    266:     /*
                    267:      * Store all the cursors.
                    268:      */
                    269:     StoreCursors();
                    270: 
                    271:     /* 
                    272:      * grab the mouse buttons according to the map structure
                    273:      */
                    274:     Grab_Buttons();
                    275: 
                    276:     /*
                    277:      * Load the selected fonts.
                    278:      */
                    279:     IFont = XGetFont(IFontName);
                    280:     if (IFont == FAILURE) {
                    281:         sprintf(message, "Unable to get font '%s'.", IFontName);
                    282:         Error(message);
                    283:     }
                    284:     PFont = XGetFont(PFontName);
                    285:     if (PFont == FAILURE) {
                    286:         sprintf(message, "Unable to get font '%s'.", PFontName);
                    287:         Error(message);
                    288:     }
                    289:     MFont = XGetFont(MFontName);
                    290:     if (MFont == FAILURE) {
                    291:         sprintf(message, "Unable to get font '%s'.", MFontName);
                    292:         Error(message);
                    293:     }
                    294: 
                    295:     /*
                    296:      * Retrieve the information structure for the specifed fonts and
                    297:      * set the global font information pointers.
                    298:      */
                    299:     status = XQueryFont(IFont, &IFontInfo);
                    300:     if (status == FAILURE) {
                    301:         sprintf(message, "Unable to query X server for info on font '%s'.",
                    302:                 IFontName);
                    303:         Error(message);
                    304:     }
                    305:     status = XQueryFont(PFont, &PFontInfo);
                    306:     if (status == FAILURE) {
                    307:         sprintf(message, "Unable to query X server for info on font '%s'.",
                    308:                 PFontName);
                    309:         Error(message);
                    310:     }
                    311:     status = XQueryFont(MFont, &MFontInfo);
                    312:     if (status == FAILURE) {
                    313:         sprintf(message, "Unable to query X server for info on font '%s'.",
                    314:                 MFontName);
                    315:         Error(message);
                    316:     }
                    317: 
                    318:     /*
                    319:      * Calculate size of the resize pop-up window.
                    320:      */
                    321:     str_width = XQueryWidth(PText, PFont);
                    322:     pop_width = str_width + (PPadding << 1);
                    323:     PWidth = pop_width + (PBorderWidth << 1);
                    324:     pop_height = PFontInfo.height + (PPadding << 1);
                    325:     PHeight = pop_height + (PBorderWidth << 1);
                    326: 
                    327:     /*
                    328:      * Create the pop-up window.  Create it at (0, 0) for now.  We will
                    329:      * move it where we want later.
                    330:      */
                    331:     Pop = XCreateWindow(RootWindow,
                    332:                         0, 0,
                    333:                         pop_width, pop_height,
                    334:                         PBorderWidth,
                    335:                         PBorder, PBackground);
                    336:     if (Pop == FAILURE) Error("Can't create pop-up dimension display window.");
                    337: 
                    338:     /*
                    339:      * Create the menus for later use.
                    340:      */
                    341:     CreateMenus();
                    342: 
                    343:     /*
                    344:      * Tell the user we're alive and well.
                    345:      */
                    346:     XFeep(Volume);
                    347: 
                    348:     /* 
                    349:      * Main command loop.
                    350:      */
                    351:     while (TRUE) {
                    352: 
                    353:         delta_done = func_stat = FALSE;
                    354: 
                    355:         /*
                    356:          * Get the next mouse button event.  Spin our wheels until
                    357:          * a ButtonPressed event is returned.
                    358:          * Note that mouse events within an icon window are handled
                    359:          * in the "GetButton" function or by the icon's owner if
                    360:          * it is not uwm.
                    361:          */
                    362:         while (TRUE) {
                    363:             if (!GetButton(&button_event)) continue;
                    364:             if (button_event.type == ButtonPressed) break;
                    365:         }
                    366: 
                    367:         /*
                    368:          * Okay, determine the event window and mouse coordinates.
                    369:          */
                    370:         status = XInterpretLocator(RootWindow,
                    371:                                     &x, &y,
                    372:                                     &event_win,
                    373:                                     button_event.location);
                    374: 
                    375:         if (status == FAILURE) continue;
                    376: 
                    377:         /*
                    378:          * Determine the event window and context.
                    379:          */
                    380:         if (event_win == 0) {
                    381:                 event_win = RootWindow;
                    382:                 context = ROOT;
                    383:         } else {
                    384:             status = XQueryWindow(event_win, &event_info);
                    385:             if (status == FAILURE) continue;
                    386:             if (event_info.type & IsIcon)
                    387:                 context = ICON;
                    388:             else context = WINDOW;
                    389:         }
                    390: 
                    391:         /*
                    392:          * Get the button event detail.
                    393:          */
                    394:         lo = (button_event.detail & ValueMask);
                    395:         hi = KeyMask(button_event.detail);
                    396: 
                    397:         /*
                    398:          * Determine which function was selected and invoke it.
                    399:          */
                    400:         for(bptr = Blist; bptr; bptr = bptr->next) {
                    401: 
                    402:             if ((bptr->button != lo) ||
                    403:                 (KeyMask(bptr->mask) != hi))
                    404:                 continue;
                    405: 
                    406:             if (bptr->context != context)
                    407:                 continue;
                    408: 
                    409:             if (!(bptr->mask & ButtonDown))
                    410:                 continue;
                    411: 
                    412:             /*
                    413:              * Found a match! Invoke the function.
                    414:              */
                    415:             if ((*bptr->func)(event_win,
                    416:                               (int)bptr->mask & ~ButtonMods,
                    417:                               bptr->button,
                    418:                               x, y,
                    419:                               bptr->menu)) {
                    420:                 func_stat = TRUE;
                    421:                 break;
                    422:             }
                    423:         }
                    424: 
                    425:         /*
                    426:          * If the function ate the ButtonUp event, then restart the loop.
                    427:          */
                    428:         if (func_stat) continue;
                    429: 
                    430:         while(TRUE) {
                    431:             /*
                    432:              * Wait for the next button event.
                    433:              */
                    434:             if (XPending() && GetButton(&button_event)) {
                    435:     
                    436:                 /*
                    437:                  * If it's not a release of the same button that was pressed,
                    438:                  * don't do the function bound to 'ButtonUp'.
                    439:                  */
                    440:                 if (button_event.type != ButtonReleased)
                    441:                     break;
                    442:                 if (lo != (button_event.detail & ValueMask))
                    443:                     break;
                    444:                 if (hi != KeyMask(button_event.detail))
                    445:                     break;
                    446:         
                    447:                 /*
                    448:                  * Okay, determine the event window and mouse coordinates.
                    449:                  */
                    450:                 status = XInterpretLocator(RootWindow,
                    451:                                            &x, &y,
                    452:                                            &event_win,
                    453:                                            button_event.location);
                    454: 
                    455:                 if (status == FAILURE) break;
                    456: 
                    457:                 if (event_win == 0) {
                    458:                         event_win = RootWindow;
                    459:                         context = ROOT;
                    460:                 } else {
                    461:                     status = XQueryWindow(event_win, &event_info);
                    462:                     if (status == FAILURE) break;
                    463:                     if (event_info.type & IsIcon)
                    464:                         context = ICON;
                    465:                     else context = WINDOW;
                    466:                 }
                    467:         
                    468:                 /*
                    469:                  * Determine which function was selected and invoke it.
                    470:                  */
                    471:                 for(bptr = Blist; bptr; bptr = bptr->next) {
                    472:         
                    473:                     if ((bptr->button != lo) ||
                    474:                         (KeyMask(bptr->mask) != hi))
                    475:                         continue;
                    476:         
                    477:                     if (bptr->context != context)
                    478:                         continue;
                    479:         
                    480:                     if (!(bptr->mask & ButtonUp))
                    481:                         continue;
                    482:         
                    483:                     /*
                    484:                      * Found a match! Invoke the function.
                    485:                      */
                    486:                     (*bptr->func)(event_win,
                    487:                                   (int)bptr->mask & ~ButtonMods,
                    488:                                   bptr->button,
                    489:                                   x, y,
                    490:                                   bptr->menu);
                    491:                 }
                    492:                 break;
                    493:             }
                    494:     
                    495:             XUpdateMouse(RootWindow, &cur_x, &cur_y, &sub_win);
                    496:             if (!delta_done &&
                    497:                 ((abs(cur_x - x) > Delta) || (abs(cur_y - y) > Delta))) {
                    498:                 /*
                    499:                  * Delta functions are done once (and only once.)
                    500:                  */
                    501:                 delta_done = TRUE;
                    502: 
                    503:                 /*
                    504:                  * Determine the new event window's coordinates.
                    505:                  */
                    506:                 status = XInterpretLocator(RootWindow,
                    507:                                             &x, &y,
                    508:                                             &event_win,
                    509:                                             button_event.location);
                    510:                 if (status == FAILURE) break;
                    511: 
                    512:                 /*
                    513:                  * Determine the event window and context.
                    514:                  */
                    515:                 if (event_win == 0) {
                    516:                         event_win = RootWindow;
                    517:                         context = ROOT;
                    518:                 } else {
                    519:                     status = XQueryWindow(event_win, &event_info);
                    520:                     if (status == FAILURE) break;
                    521:                     if (event_info.type & IsIcon)
                    522:                         context = ICON;
                    523:                     else context = WINDOW;
                    524:                 }
                    525:     
                    526:                 /*
                    527:                  * Determine which function was selected and invoke it.
                    528:                  */
                    529:                 for(bptr = Blist; bptr; bptr = bptr->next) {
                    530:         
                    531:                     if ((bptr->button != lo) ||
                    532:                         (KeyMask(bptr->mask) != hi))
                    533:                         continue;
                    534:         
                    535:                     if (bptr->context != context)
                    536:                         continue;
                    537:         
                    538:                     if (!(bptr->mask & DeltaMotion))
                    539:                         continue;
                    540:         
                    541:                     /*
                    542:                      * Found a match! Invoke the function.
                    543:                      */
                    544:                     if ((*bptr->func)(event_win,
                    545:                                       (int)bptr->mask & ~ButtonMods,
                    546:                                       bptr->button,
                    547:                                       x, y,
                    548:                                       bptr->menu)) {
                    549:                         func_stat = TRUE;
                    550:                         break;
                    551:                     }
                    552:                 }
                    553:                 /*
                    554:                  * If the function ate the ButtonUp event,
                    555:                  * then restart the loop.
                    556:                  */
                    557:                 if (func_stat) break;
                    558:             }
                    559:         }
                    560:     }
                    561: }
                    562: 
                    563: /*
                    564:  * Initialize the default bindings.  First, write the character array
                    565:  * out to a temp file, then point the parser to it and read it in.
                    566:  * Afterwards, we unlink the temp file.
                    567:  */
                    568: InitBindings()
                    569: {
                    570:     char *mktemp();
                    571:     char *tempfile = TEMPFILE; /* Temporary filename. */
                    572:     register FILE *fp;         /* Temporary file pointer. */
                    573:     register char **ptr;       /* Default bindings string array pointer. */
                    574: 
                    575:     /*
                    576:      * Create and write the temp file.
                    577:      */
                    578:     sfilename = mktemp(tempfile);
                    579:     if ((fp = fopen(tempfile, "w")) == NULL) {
                    580:         perror("uwm: cannot create temp file");
                    581:         exit(1);
                    582:     }
                    583:     for (ptr = DefaultBindings; *ptr; ptr++) {
                    584:         fputs(*ptr, fp);
                    585:         fputc('\n', fp);
                    586:     }
                    587:     fclose(fp);
                    588: 
                    589:     /*
                    590:      * Read in the bindings from the temp file and parse them.
                    591:      */
                    592:     if ((yyin = fopen(tempfile, "r")) == NULL) {
                    593:         perror("uwm: cannot open temp file");
                    594:         exit(1);
                    595:     }
                    596:     Lineno = 1;
                    597:     yyparse();
                    598:     fclose(yyin);
                    599:     unlink(tempfile);
                    600:     if (Startup_File_Error)
                    601:         Error("Bad default bindings...aborting");
                    602: 
                    603:     /*
                    604:      * Parse the system startup file, if one exists.
                    605:      */
                    606:     if ((yyin = fopen(SYSFILE, "r")) != NULL) {
                    607:         sfilename = SYSFILE;
                    608:         Lineno = 1;
                    609:         yyparse();
                    610:         fclose(yyin);
                    611:         if (Startup_File_Error)
                    612:             Error("Bad system startup file...aborting");
                    613:     }
                    614: }
                    615: 
                    616: /*
                    617:  * Verify menu bindings by checking that a menu that is mapped actually
                    618:  * exists.  Stash a pointer in the binding to the relevant menu info data
                    619:  * structure.
                    620:  * Check nested menu consistency.
                    621:  */
                    622: VerifyMenuBindings()
                    623: {
                    624:     Binding *bptr;
                    625:     MenuLink *mptr;
                    626: 
                    627:     for(bptr = Blist; bptr; bptr = bptr->next) {
                    628:         if (bptr->func == Menu) {
                    629:             for(mptr = Menus; mptr; mptr = mptr->next) {
                    630:                 if(!(strcmp(bptr->menuname, mptr->menu->name))) {
                    631:                     bptr->menu = mptr->menu;
                    632:                     break;
                    633:                 }
                    634:             }
                    635:             if (mptr == NULL) {
                    636:                 fprintf(stderr,
                    637:                         "uwm: non-existent menu reference: \"%s\"\n",
                    638:                         bptr->menuname);
                    639:                 Startup_File_Error = TRUE;
                    640:             }
                    641:         }
                    642:     }
                    643:     CheckMenus();
                    644: }
                    645: 
                    646: /*
                    647:  * Check nested menu consistency by verifying that every menu line that
                    648:  * calls another menu references a menu that actually exists.
                    649:  */
                    650: CheckMenus()
                    651: {
                    652:     MenuLink *ptr;
                    653:     Bool errflag = FALSE;
                    654: 
                    655:     for(ptr = Menus; ptr; ptr = ptr->next) {
                    656:         if (ChkMline(ptr->menu))
                    657:             errflag = TRUE;
                    658:     }
                    659:     if (errflag)
                    660:         Error("Nested menu inconsistency");
                    661: }
                    662: 
                    663: Bool ChkMline(menu)
                    664: MenuInfo *menu;
                    665: {
                    666:     MenuLine *ptr;
                    667:     MenuLink *lptr;
                    668:     Bool errflag = FALSE;
                    669: 
                    670:     for(ptr = menu->line; ptr; ptr = ptr->next) {
                    671:         if (ptr->type == IsMenuFunction) {
                    672:             for(lptr = Menus; lptr; lptr = lptr->next) {
                    673:                 if(!(strcmp(ptr->text, lptr->menu->name))) {
                    674:                     ptr->menu = lptr->menu;
                    675:                     break;
                    676:                 }
                    677:             }
                    678:             if (lptr == NULL) {
                    679:                 fprintf(stderr,
                    680:                         "uwm: non-existent menu reference: \"%s\"\n",
                    681:                         ptr->text);
                    682:                 errflag = TRUE;
                    683:             }
                    684:         }
                    685:     }
                    686:     return(errflag);
                    687: }
                    688: 
                    689: /*
                    690:  * Grab the mouse buttons according to the bindings list.
                    691:  */
                    692: Grab_Buttons()
                    693: {
                    694:     Binding *bptr;
                    695: 
                    696:     for(bptr = Blist; bptr; bptr = bptr->next)
                    697:         Grab(bptr->mask);
                    698: }
                    699: 
                    700: /*
                    701:  * Grab a mouse button according to the given mask.
                    702:  */
                    703: Grab(mask)
                    704: short mask;
                    705: {
                    706:     short m = LeftMask | MiddleMask | RightMask;
                    707: 
                    708:     switch (mask & m) {
                    709:     case LeftMask:
                    710:         status = XGrabButton(RootWindow, LeftButtonCursor,
                    711:                              mask & ~ButtonMods,
                    712:                              EVENTMASK);
                    713:         if (status == FAILURE)
                    714:             Error("Can't grab left mouse button.");
                    715:         break;
                    716: 
                    717:     case MiddleMask:
                    718:         status = XGrabButton(RootWindow, MiddleButtonCursor,
                    719:                              mask & ~ButtonMods,
                    720:                              EVENTMASK);
                    721:         if (status == FAILURE)
                    722:             Error("Can't grab middle mouse button.");
                    723:         break;
                    724: 
                    725:     case RightMask:
                    726:         status = XGrabButton(RootWindow, RightButtonCursor,
                    727:                              mask & ~ButtonMods,
                    728:                              EVENTMASK);
                    729:         if (status == FAILURE)
                    730:             Error("Can't grab right mouse button.");
                    731:         break;
                    732:     }
                    733: }
                    734: 
                    735: /*
                    736:  * error routine for .uwmrc parser
                    737:  */
                    738: yyerror(s)
                    739: char*s;
                    740: {
                    741:     fprintf(stderr, "uwm: %s: %d: %s\n", sfilename, Lineno, s);
                    742:     Startup_File_Error = TRUE;
                    743: }
                    744: 
                    745: /*
                    746:  * Print usage message and quit.
                    747:  */
                    748: Usage()
                    749: {
                    750:     fputs("Usage:  uwm [-f <file>] [<host>:<display>]\n", stderr);
                    751:     exit(1);
                    752: }
                    753: 
                    754: /*
                    755:  * error handler for X I/O errors
                    756:  */
                    757: XIOError(dsp)
                    758: Display *dsp;
                    759: {
                    760:     perror("uwm");
                    761:     exit(3);
                    762: }

unix.superglobalmegacorp.com

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