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

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: 
        !            40: #include <sys/time.h>
        !            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:      */
        !           204:     if ((status = fcntl(ConnectionNumber(dpy), F_SETFD, 1)) == -1) {
        !           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.