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

Defined functions

CheckMenus defined in line 650; used 1 times
ChkMline defined in line 663; used 2 times
Grab_Buttons defined in line 692; used 1 times
InitBindings defined in line 568; used 1 times
Usage defined in line 748; used 1 times
VerifyMenuBindings defined in line 622; used 1 times
XIOError defined in line 757; never used
main defined in line 77; never used
ptrap defined in line 55; used 2 times
yyerror defined in line 738; used 22 times

Defined variables

gray_bits defined in line 63; used 1 times
rcsid_uwm_c defined in line 2; never used
sccsid defined in line 44; never used
sfilename defined in line 71; used 5 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1900
Valid CSS Valid XHTML 1.0 Strict