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