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