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