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

1.1       root        1: /* $Header: uwm.c,v 1.8 87/08/20 19:17:40 swick Exp $ */
                      2: #include <X11/copyright.h>
                      3: 
                      4: /*
                      5:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
                      6:  *
                      7:  *                         All Rights Reserved
                      8:  *
                      9:  * Permission to use, copy, modify, and distribute this software and its
                     10:  * documentation for any purpose and without fee is hereby granted,
                     11:  * provided that the above copyright notice appear in all copies and that
                     12:  * both that copyright notice and this permission notice appear in
                     13:  * supporting documentation, and that the name of Digital Equipment
                     14:  * Corporation not be used in advertising or publicity pertaining to
                     15:  * distribution of the software without specific, written prior permission.
                     16:  *
                     17:  *
                     18:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     19:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     20:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     21:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     22:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     23:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     24:  * SOFTWARE.
                     25:  */
                     26: 
                     27: 
                     28: /*
                     29:  * MODIFICATION HISTORY
                     30:  *
                     31:  * 000 -- M. Gancarz, DEC Ultrix Engineering Group
                     32:  * 001 -- Loretta Guarino Reid, DEC Ultrix Engineering Group,
                     33:  *  Western Software Lab. Convert to X11.
                     34:  */
                     35: 
                     36: #ifndef lint
                     37: static char *sccsid = "%W%     %G%";
                     38: #endif
                     39: 
1.1.1.2 ! root       40: #include <sys/ioctl.h>
1.1       root       41: #include "uwm.h"
                     42: 
                     43: #ifdef PROFIL
                     44: #include <signal.h>
                     45: /*
                     46:  * Dummy handler for profiling.
                     47:  */
                     48: ptrap()
                     49: {
                     50:     exit(0);
                     51: }
                     52: #endif
                     53: 
                     54: #include <fcntl.h>
                     55: 
                     56: #define gray_width 16
                     57: #define gray_height 16
                     58: static char gray_bits[] = {
                     59:    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
                     60:    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
                     61:    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
                     62:    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa
                     63: };
                     64: 
                     65: 
                     66: 
                     67: Bool NeedRootInput=FALSE;
                     68: Bool ChkMline();
                     69: char *sfilename;
                     70: extern FILE *yyin;
                     71: 
                     72: /*
                     73:  * Main program.
                     74:  */
                     75: main(argc, argv, environ)
                     76: int argc;
                     77: char **argv;
                     78: char **environ;
                     79: {
                     80:     int hi;                    /* Button event high detail. */
                     81:     int lo;                    /* Button event low detail. */
                     82:     int x, y;                   /* Mouse X and Y coordinates. */
                     83:     int root_x, root_y;         /* Mouse root X and Y coordinates. */
                     84:     int cur_x, cur_y;          /* Current mouse X and Y coordinates. */
                     85:     int down_x, down_y;                /* mouse X and Y at ButtonPress. */
                     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:     int ptrmask;               /* for QueryPointer */
                     90:     Bool func_stat;            /* If true, function swallowed a ButtonUp. */
                     91:     Bool delta_done;           /* If true, then delta functions are done. */
                     92:     Bool local;                        /* If true, then do not use system defaults. */
                     93:     register Binding *bptr;    /* Pointer to Bindings list. */
                     94:     char *root_name;           /* Root window name. */
                     95:     char *display = NULL;      /* Display name pointer. */
                     96:     char message[128];         /* Error message buffer. */
                     97:     char *rc_file;             /* Pointer to $HOME/.uwmrc. */
                     98:     Window event_win;           /* Event window. */
                     99:     Window sub_win;            /* Subwindow for XUpdateMouse calls. */
                    100:     Window root;               /* Root window for QueryPointer. */
                    101:     XWindowAttributes event_info;      /* Event window info. */
                    102:     XEvent button_event;        /* Button input event. */
                    103:     GC gc;                     /* graphics context for gray background */
                    104:     XImage grayimage;          /* for gray background */
                    105:     XGCValues xgc;             /* to create font GCs */
                    106:     char *malloc();
                    107:     Bool fallbackMFont = False,        /* using default GC font for menus, */
                    108:          fallbackPFont = False,        /* popups, */
                    109:          fallbackIFont = False;        /* icons */
                    110: 
                    111: #ifdef PROFIL
                    112:     signal(SIGTERM, ptrap);
                    113: #endif
                    114: 
                    115:     /*
                    116:      * Set up internal defaults.
                    117:      */
                    118:     SetVarDefaults();
                    119: 
                    120:     /* 
                    121:      * Parse the command line arguments.
                    122:      */
                    123:     Argv = argv;
                    124:     Environ = environ;
                    125:     argc--, argv++;
                    126:     while (argc) {
                    127:         if (**argv == '-') {
                    128:             if (!(strcmp(*argv, "-f"))) {
                    129:                 argc--, argv++;
                    130:                 if ((argc == 0) || (Startup_File[0] != '\0'))
                    131:                     Usage();
                    132:                 strncpy(Startup_File, *argv, NAME_LEN);
                    133:             }
                    134:             else if (!(strcmp(*argv, "-b")))
                    135:                 local = TRUE;
                    136:             else Usage();
                    137:         }
                    138:         else display = *argv;
                    139:        argc--, argv++;
                    140:     }
                    141: 
                    142:     /*
                    143:      * Initialize the default bindings.
                    144:      */
                    145:     if (!local)
                    146:         InitBindings();
                    147: 
                    148:     /*
                    149:      * Read in and parse $HOME/.uwmrc, if it exists.
                    150:      */
                    151:     sfilename = rc_file = malloc(NAME_LEN);
                    152:     sprintf(rc_file, "%s/.uwmrc", getenv("HOME"));
                    153:     if ((yyin = fopen(rc_file, "r")) != NULL) {
                    154:         Lineno = 1;
                    155:         yyparse();
                    156:         fclose(yyin);
                    157:         if (Startup_File_Error)
                    158:             Error("Bad .uwmrc file...aborting");
                    159:     }
                    160: 
                    161:     /* 
                    162:      * Read in and parse the startup file from the command line, if
                    163:      * specified.
                    164:      */
                    165:     if (Startup_File[0] != '\0') {
                    166:         sfilename = Startup_File;
                    167:         if ((yyin = fopen(Startup_File, "r")) == NULL) {
                    168:        sprintf(message, "Cannot open startup file '%s'", Startup_File);
                    169:             Error(message);
                    170:         }
                    171:         Lineno = 1;
                    172:         yyparse();
                    173:         fclose(yyin);
                    174:         if (Startup_File_Error)
                    175:             Error("Bad startup file...aborting");
                    176:     }
                    177: 
                    178:     /*
                    179:      * Verify the menu bindings.
                    180:      */
                    181:     VerifyMenuBindings();
                    182:     if (Startup_File_Error)
                    183:         Error("Bad startup file...aborting");
                    184: 
                    185:     /* 
                    186:      * Open the display.
                    187:      */
                    188:     if ((dpy = XOpenDisplay(display)) == NULL)
                    189:         Error("Unable to open display");
                    190:     scr = DefaultScreen(dpy); 
                    191: /*    XSynchronize(dpy, 1); */
                    192: 
                    193:     /*
                    194:      * Set XErrorFunction to be non-terminating.
                    195:      */
                    196:     XSetErrorHandler(XError);
                    197: 
                    198: 
                    199:     /*
                    200:      * Force child processes to disinherit the TCP file descriptor.
                    201:      * This helps shell commands forked and exec'ed from menus
                    202:      * to work properly.
                    203:      */
1.1.1.2 ! root      204:     if ((status = ioctl(ConnectionNumber(dpy), FIOCLEX, 0)) == -1) {
1.1       root      205:         perror("uwm: child cannot disinherit TCP fd");
                    206:         Error("TCP file descriptor problems");
                    207:     }
                    208: 
                    209:     /*
                    210:      * If the root window has not been named, name it.
                    211:      */
                    212:     status = XFetchName(dpy, RootWindow(dpy, scr), &root_name);
                    213:     if (root_name == NULL) 
                    214:        XStoreName(dpy, RootWindow(dpy, scr), " X Root Window ");
                    215:     else free(root_name);
                    216: 
                    217: 
                    218:     ScreenHeight = DisplayHeight(dpy, scr);
                    219:     ScreenWidth = DisplayWidth(dpy, scr);
                    220: 
                    221:     /*
                    222:      * Create and store the icon background pixmap.
                    223:      */
                    224:     GrayPixmap = (Pixmap)XCreatePixmap(dpy, RootWindow(dpy, scr), 
                    225:        gray_width, gray_height, DefaultDepth(dpy,scr));
                    226:     xgc.foreground = BlackPixel(dpy, scr);
                    227:     xgc.background = WhitePixel(dpy, scr);
                    228:     gc = XCreateGC(dpy, GrayPixmap, GCForeground+GCBackground, &xgc);
                    229:     grayimage.height = gray_width;
                    230:     grayimage.width = gray_height;
                    231:     grayimage.xoffset = 0;
                    232:     grayimage.format = XYBitmap;
                    233:     grayimage.data = (char *)gray_bits;
                    234:     grayimage.byte_order = LSBFirst;
                    235:     grayimage.bitmap_unit = 8;
                    236:     grayimage.bitmap_bit_order = LSBFirst;
                    237:     grayimage.bitmap_pad = 16;
                    238:     grayimage.bytes_per_line = 2;
                    239:     grayimage.depth = 1;
                    240:     XPutImage(dpy, GrayPixmap, gc, &grayimage, 0, 0,
                    241:         0, 0, gray_width, gray_height);
                    242:     XFreeGC(dpy, gc);
                    243:     
                    244: 
                    245:     /*
                    246:      * Set up icon window, icon cursor and pop-up window color parameters.
                    247:      */
                    248:     if (Reverse) {
                    249:         IBorder = WhitePixel(dpy, scr);
                    250:         IBackground =  GrayPixmap;
                    251:         ITextForground = WhitePixel(dpy, scr);
                    252:         ITextBackground = BlackPixel(dpy, scr);
                    253:         PBorder = BlackPixel(dpy, scr);
                    254:         PBackground = WhitePixel(dpy, scr);
                    255:         PTextForground = BlackPixel(dpy, scr);
                    256:         PTextBackground = WhitePixel(dpy, scr);
                    257:         MBorder = WhitePixel(dpy, scr);
                    258:         MBackground = BlackPixel(dpy, scr);
                    259:         MTextForground = WhitePixel(dpy, scr);
                    260:         MTextBackground = BlackPixel(dpy, scr);
                    261:     }
                    262:     else {
                    263:         IBorder = BlackPixel(dpy, scr);
                    264:         IBackground = GrayPixmap;
                    265:         ITextForground = BlackPixel(dpy, scr);
                    266:         ITextBackground = WhitePixel(dpy, scr);
                    267:         PBorder = WhitePixel(dpy, scr);
                    268:         PBackground = BlackPixel(dpy, scr);
                    269:         PTextForground = WhitePixel(dpy, scr);
                    270:         PTextBackground = BlackPixel(dpy, scr);
                    271:         MBorder = BlackPixel(dpy, scr);
                    272:         MBackground = WhitePixel(dpy, scr);
                    273:         MTextForground = BlackPixel(dpy, scr);
                    274:         MTextBackground = WhitePixel(dpy, scr);
                    275:     }
                    276: 
                    277:     /*
                    278:      * Store all the cursors.
                    279:      */
                    280:     StoreCursors();
                    281: 
                    282:     /* 
                    283:      * grab the mouse buttons according to the map structure
                    284:      */
                    285:     Grab_Buttons();
                    286: 
                    287:     /*
                    288:      * Set initial focus to PointerRoot.
                    289:      */
                    290:     XSetInputFocus(dpy, PointerRoot, None, CurrentTime);
                    291: 
                    292:     /* 
                    293:      * watch for initial window mapping and window destruction
                    294:      */
                    295:     XSelectInput(dpy, RootWindow(dpy, scr), 
                    296:       SubstructureNotifyMask|SubstructureRedirectMask|FocusChangeMask|
                    297:       (NeedRootInput ? EVENTMASK|OwnerGrabButtonMask : 0));
                    298: 
                    299:     /*
                    300:      * Retrieve the information structure for the specifed fonts and
                    301:      * set the global font information pointers.
                    302:      */
                    303:     IFontInfo = XLoadQueryFont(dpy, IFontName);
                    304:     if (IFontInfo == NULL) {
                    305:         fprintf(stderr, "uwm: Unable to open icon font '%s', using server default.\n",
                    306:                 IFontName);
                    307:        IFontInfo = XQueryFont(dpy, DefaultGC(dpy, scr)->gid);
                    308:        fallbackIFont = True;
                    309:     }
                    310:     PFontInfo = XLoadQueryFont(dpy, PFontName);
                    311:     if (PFontInfo == NULL) {
                    312:         fprintf(stderr, "uwm: Unable to open resize font '%s', using server default.\n",
                    313:                 PFontName);
                    314:        if (fallbackIFont)
                    315:            PFontInfo = IFontInfo;
                    316:        else
                    317:            PFontInfo = XQueryFont(dpy, DefaultGC(dpy, scr)->gid);
                    318:        fallbackPFont = True;
                    319:     }
                    320:     MFontInfo = XLoadQueryFont(dpy, MFontName);
                    321:     if (MFontInfo == NULL) {
                    322:         fprintf(stderr, "uwm: Unable to open menu font '%s', using server default.\n",
                    323:                 MFontName);
                    324:        if (fallbackIFont || fallbackPFont)
                    325:            MFontInfo = fallbackPFont ? PFontInfo : IFontInfo;
                    326:        else
                    327:            MFontInfo = XQueryFont(dpy, DefaultGC(dpy, scr)->gid);
                    328:        fallbackMFont = True;
                    329:     }
                    330: 
                    331:     /*
                    332:      * Calculate size of the resize pop-up window.
                    333:      */
                    334:     str_width = XTextWidth(PFontInfo, PText, strlen(PText));
                    335:     pop_width = str_width + (PPadding << 1);
                    336:     PWidth = pop_width + (PBorderWidth << 1);
                    337:     pop_height = PFontInfo->ascent + PFontInfo->descent + (PPadding << 1);
                    338:     PHeight = pop_height + (PBorderWidth << 1);
                    339: 
                    340:     /*
                    341:      * Create the pop-up window.  Create it at (0, 0) for now.  We will
                    342:      * move it where we want later.
                    343:      */
                    344:     Pop = XCreateSimpleWindow(dpy, RootWindow(dpy, scr),
                    345:                         0, 0,
                    346:                         pop_width, pop_height,
                    347:                         PBorderWidth,
                    348:                         PBorder, PBackground);
                    349:     if (Pop == FAILURE) Error("Can't create pop-up dimension display window.");
                    350: 
                    351:     /*
                    352:      * Create the menus for later use.
                    353:      */
                    354:     CreateMenus();
                    355: 
                    356:     /*
                    357:      * Create graphics context.
                    358:      */
                    359:     xgc.foreground = ITextForground;
                    360:     xgc.background = ITextBackground;
                    361:     xgc.font = IFontInfo->fid;
                    362:     xgc.graphics_exposures = FALSE;
                    363:     IconGC = XCreateGC(dpy, 
                    364:        RootWindow(dpy, scr),
                    365:        GCForeground+GCBackground+GCGraphicsExposures
                    366:                       +(fallbackIFont ? 0 : GCFont), &xgc);
                    367:     xgc.foreground = MTextForground;
                    368:     xgc.background = MTextBackground;
                    369:     xgc.font = MFontInfo->fid;
                    370:     MenuGC = XCreateGC(dpy, 
                    371:        RootWindow(dpy, scr),
                    372:        GCForeground+GCBackground+(fallbackMFont ? 0 : GCFont), &xgc);
                    373:     xgc.function = GXinvert;
                    374:     xgc.plane_mask = MTextForground ^ MTextBackground;
                    375:     MenuInvGC = XCreateGC(dpy, 
                    376:        RootWindow(dpy, scr), GCForeground+GCFunction+GCPlaneMask, &xgc);
                    377:     xgc.foreground = PTextForground;
                    378:     xgc.background = PTextBackground;
                    379:     xgc.font = PFontInfo->fid;
                    380:     PopGC = XCreateGC(dpy, 
                    381:        RootWindow(dpy, scr),
                    382:        GCForeground+GCBackground+(fallbackPFont ? 0 : GCFont), &xgc);
                    383:     xgc.line_width = DRAW_WIDTH;
                    384:     xgc.foreground = DRAW_VALUE;
                    385:     xgc.function = DRAW_FUNC;
                    386:     xgc.subwindow_mode = IncludeInferiors;
                    387:     DrawGC = XCreateGC(dpy, RootWindow(dpy, scr), 
                    388:       GCLineWidth+GCForeground+GCFunction+GCSubwindowMode, &xgc);
                    389: 
                    390: 
                    391:     /*
                    392:      * Tell the user we're alive and well.
                    393:      */
                    394:     XBell(dpy, VOLUME_PERCENTAGE(Volume));
                    395: 
                    396:     /* 
                    397:      * Main command loop.
                    398:      */
                    399:     while (TRUE) {
                    400: 
                    401:         delta_done = func_stat = FALSE;
                    402: 
                    403:         /*
                    404:          * Get the next mouse button event.  Spin our wheels until
                    405:          * a ButtonPressed event is returned.
                    406:          * Note that mouse events within an icon window are handled
                    407:          * in the "GetButton" function or by the icon's owner if
                    408:          * it is not uwm.
                    409:          */
                    410:         while (TRUE) {
                    411:             if (!GetButton(&button_event)) continue;
                    412:             if (button_event.type == ButtonPress) break;
                    413:         }
                    414: 
                    415:        /* save mouse coords in case we want them later for a delta action */
                    416:        down_x = ((XButtonPressedEvent *)&button_event)->x;
                    417:        down_y = ((XButtonPressedEvent *)&button_event)->y;
                    418:         /*
                    419:          * Okay, determine the event window and mouse coordinates.
                    420:          */
                    421:         status = XTranslateCoordinates(dpy, 
                    422:                                    RootWindow(dpy, scr), RootWindow(dpy, scr),
                    423:                                     ((XButtonPressedEvent *)&button_event)->x, 
                    424:                                    ((XButtonPressedEvent *)&button_event)->y,
                    425:                                     &x, &y,
                    426:                                     &event_win);
                    427: 
                    428:         if (status == FAILURE) continue;
                    429: 
                    430:         /*
                    431:          * Determine the event window and context.
                    432:          */
                    433:         if (event_win == 0) {
                    434:                 event_win = RootWindow(dpy, scr);
                    435:                 context = ROOT;
                    436:         } else {
                    437:             if (IsIcon(event_win, 0, 0, FALSE, NULL))
                    438:                 context = ICON;
                    439:             else context = WINDOW;
                    440:         }
                    441: 
                    442:         /*
                    443:          * Get the button event detail.
                    444:          */
                    445:         lo = ((XButtonPressedEvent *)&button_event)->button;
                    446:         hi = ((XButtonPressedEvent *)&button_event)->state;
                    447: 
                    448:         /*
                    449:          * Determine which function was selected and invoke it.
                    450:          */
                    451:         for(bptr = Blist; bptr; bptr = bptr->next) {
                    452: 
                    453:             if ((bptr->button != lo) ||
                    454:                 (((int)bptr->mask & ModMask) != hi))
                    455:                 continue;
                    456: 
                    457:             if (bptr->context != context)
                    458:                 continue;
                    459: 
                    460:             if (!(bptr->mask & ButtonDown))
                    461:                 continue;
                    462: 
                    463:             /*
                    464:              * Found a match! Invoke the function.
                    465:              */
                    466:             if ((*bptr->func)(event_win,
                    467:                               (int)bptr->mask & ModMask,
                    468:                               bptr->button,
                    469:                               x, y,
                    470:                               bptr->menu)) {
                    471:                 func_stat = TRUE;
                    472:                 break;
                    473:             }
                    474:         }
                    475: 
                    476:         /*
                    477:          * If the function ate the ButtonUp event, then restart the loop.
                    478:          */
                    479:         if (func_stat) continue;
                    480: 
                    481:         while(TRUE) {
                    482:             /*
                    483:              * Wait for the next button event.
                    484:              */
                    485:             if (XPending(dpy) && GetButton(&button_event)) {
                    486:     
                    487:                 /*
                    488:                  * If it's not a release of the same button that was pressed,
                    489:                  * don't do the function bound to 'ButtonUp'.
                    490:                  */
                    491:                 if (button_event.type != ButtonRelease)
                    492:                     break;
                    493:                 if (lo != ((XButtonReleasedEvent *)&button_event)->button)
                    494:                     break;
                    495:                 if ((hi|ButtonMask(lo)) != 
                    496:                     ((XButtonReleasedEvent *)&button_event)->state)
                    497:                     break;
                    498:         
                    499:                 /*
                    500:                  * Okay, determine the event window and mouse coordinates.
                    501:                  */
                    502:                 status = XTranslateCoordinates(dpy, 
                    503:                                    RootWindow(dpy, scr), RootWindow(dpy, scr),
                    504:                                     ((XButtonReleasedEvent *)&button_event)->x,
                    505:                                    ((XButtonReleasedEvent *)&button_event)->y,
                    506:                                     &x, &y,
                    507:                                     &event_win);
                    508: 
                    509:                 if (status == FAILURE) break;
                    510: 
                    511:                 if (event_win == 0) {
                    512:                         event_win = RootWindow(dpy, scr);
                    513:                         context = ROOT;
                    514:                 } else {
                    515:                     if (IsIcon(event_win, 0, 0, FALSE, NULL))
                    516:                         context = ICON;
                    517:                     else context = WINDOW;
                    518:                 }
                    519:         
                    520:                 /*
                    521:                  * Determine which function was selected and invoke it.
                    522:                  */
                    523:                 for(bptr = Blist; bptr; bptr = bptr->next) {
                    524:         
                    525:                     if ((bptr->button != lo) ||
                    526:                         (((int)bptr->mask & ModMask) != hi))
                    527:                         continue;
                    528:         
                    529:                     if (bptr->context != context)
                    530:                         continue;
                    531:         
                    532:                     if (!(bptr->mask & ButtonUp))
                    533:                         continue;
                    534:         
                    535:                     /*
                    536:                      * Found a match! Invoke the function.
                    537:                      */
                    538:                     (*bptr->func)(event_win,
                    539:                                   (int)bptr->mask & ModMask,
                    540:                                   bptr->button,
                    541:                                   x, y,
                    542:                                   bptr->menu);
                    543:                 }
                    544:                 break;
                    545:             }
                    546:     
                    547:             XQueryPointer(dpy, RootWindow(dpy, scr), 
                    548:                &root, &event_win, &root_x, &root_y, &cur_x, &cur_y, &ptrmask);
                    549:             if (!delta_done &&
                    550:                 ((abs(cur_x - x) > Delta) || (abs(cur_y - y) > Delta))) {
                    551:                 /*
                    552:                  * Delta functions are done once (and only once.)
                    553:                  */
                    554:                 delta_done = TRUE;
                    555: 
                    556:                 /*
                    557:                  * Determine the new event window's coordinates.
                    558:                 * from the original ButtonPress event
                    559:                  */
                    560:                 status = XTranslateCoordinates(dpy, 
                    561:                          RootWindow(dpy, scr), RootWindow(dpy, scr),
                    562:                          down_x, down_y, &x, &y, &event_win);
                    563:                 if (status == FAILURE) break;
                    564: 
                    565:                 /*
                    566:                  * Determine the event window and context.
                    567:                  */
                    568:                 if (event_win == 0) {
                    569:                         event_win = RootWindow(dpy, scr);
                    570:                         context = ROOT;
                    571:                 } else {
                    572:                     if (IsIcon(event_win, 0, 0, FALSE, NULL))
                    573:                         context = ICON;
                    574:                     else context = WINDOW;
                    575:                 }
                    576:     
                    577:                 /*
                    578:                  * Determine which function was selected and invoke it.
                    579:                  */
                    580:                 for(bptr = Blist; bptr; bptr = bptr->next) {
                    581:         
                    582:                     if ((bptr->button != lo) ||
                    583:                         (((int)bptr->mask & ModMask) != hi))
                    584:                         continue;
                    585:         
                    586:                     if (bptr->context != context)
                    587:                         continue;
                    588:         
                    589:                     if (!(bptr->mask & DeltaMotion))
                    590:                         continue;
                    591:         
                    592:                     /*
                    593:                      * Found a match! Invoke the function.
                    594:                      */
                    595:                     if ((*bptr->func)(event_win,
                    596:                                       (int)bptr->mask & ModMask,
                    597:                                       bptr->button,
                    598:                                       x, y,
                    599:                                       bptr->menu)) {
                    600:                         func_stat = TRUE;
                    601:                         break;
                    602:                     }
                    603:                 }
                    604:                 /*
                    605:                  * If the function ate the ButtonUp event,
                    606:                  * then restart the loop.
                    607:                  */
                    608:                 if (func_stat) break;
                    609:             }
                    610:         }
                    611:     }
                    612: }
                    613: 
                    614: /*
                    615:  * Initialize the default bindings.  First, write the character array
                    616:  * out to a temp file, then point the parser to it and read it in.
                    617:  * Afterwards, we unlink the temp file.
                    618:  */
                    619: InitBindings()
                    620: {
                    621:     char *mktemp();
                    622:     char *tempfile = TEMPFILE; /* Temporary filename. */
                    623:     register FILE *fp;         /* Temporary file pointer. */
                    624:     register char **ptr;       /* Default bindings string array pointer. */
                    625: 
                    626:     /*
                    627:      * Create and write the temp file.
                    628:      */
                    629:     sfilename = mktemp(tempfile);
                    630:     if ((fp = fopen(tempfile, "w")) == NULL) {
                    631:         perror("uwm: cannot create temp file");
                    632:         exit(1);
                    633:     }
                    634:     for (ptr = DefaultBindings; *ptr; ptr++) {
                    635:         fputs(*ptr, fp);
                    636:         fputc('\n', fp);
                    637:     }
                    638:     fclose(fp);
                    639: 
                    640:     /*
                    641:      * Read in the bindings from the temp file and parse them.
                    642:      */
                    643:     if ((yyin = fopen(tempfile, "r")) == NULL) {
                    644:         perror("uwm: cannot open temp file");
                    645:         exit(1);
                    646:     }
                    647:     Lineno = 1;
                    648:     yyparse();
                    649:     fclose(yyin);
                    650:     unlink(tempfile);
                    651:     if (Startup_File_Error)
                    652:         Error("Bad default bindings...aborting");
                    653: 
                    654:     /*
                    655:      * Parse the system startup file, if one exists.
                    656:      */
                    657:     if ((yyin = fopen(SYSFILE, "r")) != NULL) {
                    658:         sfilename = SYSFILE;
                    659:         Lineno = 1;
                    660:         yyparse();
                    661:         fclose(yyin);
                    662:         if (Startup_File_Error)
                    663:             Error("Bad system startup file...aborting");
                    664:     }
                    665: }
                    666: 
                    667: /*
                    668:  * Verify menu bindings by checking that a menu that is mapped actually
                    669:  * exists.  Stash a pointer in the binding to the relevant menu info data
                    670:  * structure.
                    671:  * Check nested menu consistency.
                    672:  */
                    673: VerifyMenuBindings()
                    674: {
                    675:     Binding *bptr;
                    676:     MenuLink *mptr;
                    677: 
                    678:     for(bptr = Blist; bptr; bptr = bptr->next) {
                    679:         if (bptr->func == Menu) {
                    680:             for(mptr = Menus; mptr; mptr = mptr->next) {
                    681:                 if(!(strcmp(bptr->menuname, mptr->menu->name))) {
                    682:                     bptr->menu = mptr->menu;
                    683:                     break;
                    684:                 }
                    685:             }
                    686:             if (mptr == NULL) {
                    687:                 fprintf(stderr,
                    688:                         "uwm: non-existent menu reference: \"%s\"\n",
                    689:                         bptr->menuname);
                    690:                 Startup_File_Error = TRUE;
                    691:             }
                    692:         }
                    693:     }
                    694:     CheckMenus();
                    695: }
                    696: 
                    697: /*
                    698:  * Check nested menu consistency by verifying that every menu line that
                    699:  * calls another menu references a menu that actually exists.
                    700:  */
                    701: CheckMenus()
                    702: {
                    703:     MenuLink *ptr;
                    704:     Bool errflag = FALSE;
                    705: 
                    706:     for(ptr = Menus; ptr; ptr = ptr->next) {
                    707:         if (ChkMline(ptr->menu))
                    708:             errflag = TRUE;
                    709:     }
                    710:     if (errflag)
                    711:         Error("Nested menu inconsistency");
                    712: }
                    713: 
                    714: Bool ChkMline(menu)
                    715: MenuInfo *menu;
                    716: {
                    717:     MenuLine *ptr;
                    718:     MenuLink *lptr;
                    719:     Bool errflag = FALSE;
                    720: 
                    721:     for(ptr = menu->line; ptr; ptr = ptr->next) {
                    722:         if (ptr->type == IsMenuFunction) {
                    723:             for(lptr = Menus; lptr; lptr = lptr->next) {
                    724:                 if(!(strcmp(ptr->text, lptr->menu->name))) {
                    725:                     ptr->menu = lptr->menu;
                    726:                     break;
                    727:                 }
                    728:             }
                    729:             if (lptr == NULL) {
                    730:                 fprintf(stderr,
                    731:                         "uwm: non-existent menu reference: \"%s\"\n",
                    732:                         ptr->text);
                    733:                 errflag = TRUE;
                    734:             }
                    735:         }
                    736:     }
                    737:     return(errflag);
                    738: }
                    739: 
                    740: /*
                    741:  * Grab the mouse buttons according to the bindings list.
                    742:  */
                    743: Grab_Buttons()
                    744: {
                    745:     Binding *bptr;
                    746: 
                    747:     for(bptr = Blist; bptr; bptr = bptr->next)
                    748:         if ((bptr->context & (WINDOW | ICON | ROOT)) == ROOT) {
                    749: 
                    750:            /* don't grab buttons if you don't have to - allow application
                    751:            access to buttons unless context includes window or icon */
                    752: 
                    753:            NeedRootInput = TRUE;
                    754:        }
                    755:        else { 
                    756:            /* context includes a window, so must grab */
                    757:            Grab(bptr->mask);
                    758:        }
                    759: }
                    760: 
                    761: /*
                    762:  * Grab a mouse button according to the given mask.
                    763:  */
                    764: Grab(mask)
                    765: unsigned int mask;
                    766: {
                    767:     unsigned int m = LeftMask | MiddleMask | RightMask;
                    768: 
                    769:     switch (mask & m) {
                    770:     case LeftMask:
                    771:         XGrabButton(dpy, LeftButton,  mask & ModMask,
                    772:                RootWindow(dpy, scr), TRUE, EVENTMASK,
                    773:                GrabModeAsync, GrabModeAsync, None, LeftButtonCursor);
                    774:         break;
                    775: 
                    776:     case MiddleMask:
                    777:         XGrabButton(dpy, MiddleButton,  mask & ModMask,
                    778:                RootWindow(dpy, scr), TRUE, EVENTMASK,
                    779:                GrabModeAsync, GrabModeAsync, None, MiddleButtonCursor);
                    780:         break;
                    781: 
                    782:     case RightMask:
                    783:         XGrabButton(dpy, RightButton,  mask & ModMask,
                    784:                RootWindow(dpy, scr), TRUE, EVENTMASK,
                    785:                GrabModeAsync, GrabModeAsync, None, RightButtonCursor);
                    786:         break;
                    787:     }
                    788: }
                    789: 
                    790: /*
                    791:  * Restore cursor to normal state.
                    792:  */
                    793: ResetCursor(button)
                    794: int button;
                    795: {
                    796: 
                    797:     switch (button) {
                    798:     case LeftButton:
                    799:         XChangeActivePointerGrab(
                    800:                dpy, EVENTMASK, LeftButtonCursor, CurrentTime);
                    801:         break;
                    802: 
                    803:     case MiddleButton:
                    804:         XChangeActivePointerGrab(
                    805:                dpy, EVENTMASK, MiddleButtonCursor, CurrentTime);
                    806:         break;
                    807: 
                    808:     case RightButton:
                    809:         XChangeActivePointerGrab(
                    810:                dpy, EVENTMASK, RightButtonCursor, CurrentTime);
                    811:         break;
                    812:     }
                    813: }
                    814: 
                    815: /*
                    816:  * error routine for .uwmrc parser
                    817:  */
                    818: yyerror(s)
                    819: char*s;
                    820: {
                    821:     fprintf(stderr, "uwm: %s: %d: %s\n", sfilename, Lineno, s);
                    822:     Startup_File_Error = TRUE;
                    823: }
                    824: 
                    825: /*
                    826:  * Print usage message and quit.
                    827:  */
                    828: Usage()
                    829: {
                    830:     fputs("Usage:  uwm [-b] [-f <file>] [<host>:<display>]\n\n", stderr);
                    831:     fputs("The -b option bypasses system and default bindings\n", stderr);
                    832:     fputs("The -f option specifies an additional startup file\n", stderr);
                    833:     exit(1);
                    834: }
                    835: 
                    836: /*
                    837:  * error handler for X I/O errors
                    838:  */
                    839: XIOError(dsp)
                    840: Display *dsp;
                    841: {
                    842:     perror("uwm");
                    843:     exit(3);
                    844: }
                    845: 
                    846: SetVarDefaults()
                    847: {
                    848:     strcpy(IFontName, DEF_FONT);
                    849:     strcpy(PFontName, DEF_FONT);
                    850:     strcpy(MFontName, DEF_FONT);
                    851:     Delta = DEF_DELTA;
                    852:     IBorderWidth = DEF_ICON_BORDER_WIDTH;
                    853:     HIconPad = DEF_ICON_PADDING;
                    854:     VIconPad = DEF_ICON_PADDING;
                    855:     PBorderWidth = DEF_POP_BORDER_WIDTH;
                    856:     PPadding = DEF_POP_PADDING;
                    857:     MBorderWidth = DEF_MENU_BORDER_WIDTH;
                    858:     HMenuPad = DEF_MENU_PADDING;
                    859:     VMenuPad = DEF_MENU_PADDING;
                    860:     Volume = DEF_VOLUME;
                    861:     Pushval = DEF_PUSH;
                    862:     FocusSetByUser = FALSE;
                    863: }

unix.superglobalmegacorp.com

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