jkh@COGSCI.BERKELEY.EDU (Jordan K. Hubbard) (12/13/87)
# This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # uwm.patches.2 # This is archive 3 of 3. Apply with patch -p # echo x - uwm.patches.2 sed 's/^ //' > "uwm.patches.2" << '//E*O*F uwm.patches.2//' *** uwm.new/uwm.c Mon Dec 7 00:59:43 1987 --- uwm.new/uwm.c Sat Dec 12 19:20:26 1987 *************** *** 31,36 * 000 -- M. Gancarz, DEC Ultrix Engineering Group * 001 -- Loretta Guarino Reid, DEC Ultrix Engineering Group, * Western Software Lab. Convert to X11. */ #ifndef lint --- 31,37 ----- * 000 -- M. Gancarz, DEC Ultrix Engineering Group * 001 -- Loretta Guarino Reid, DEC Ultrix Engineering Group, * Western Software Lab. Convert to X11. + * 002 -- Jordan Hubbard, U.C. Berkeley. Add title bar context stuff. */ #ifndef lint *************** *** 38,43 #endif #include <sys/time.h> #include "uwm.h" #ifdef PROFIL --- 39,45 ----- #endif #include <sys/time.h> + #include <signal.h> #include "uwm.h" #ifdef PROFIL *************** *** 47,53 */ ptrap() { ! exit(0); } #endif --- 49,55 ----- */ ptrap() { ! exit(0); } #endif *************** *** 56,66 #define gray_width 16 #define gray_height 16 static char gray_bits[] = { ! 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, ! 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, ! 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, ! 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa ! }; --- 58,68 ----- #define gray_width 16 #define gray_height 16 static char gray_bits[] = { ! 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, ! 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, ! 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, ! 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa ! }; *************** *** 68,73 Bool ChkMline(); char *sfilename; extern FILE *yyin; /* * Main program. --- 70,76 ----- Bool ChkMline(); char *sfilename; extern FILE *yyin; + TitleData *dat; /* * Main program. *************** *** 77,112 char **argv; char **environ; { ! int hi; /* Button event high detail. */ ! int lo; /* Button event low detail. */ ! int x, y; /* Mouse X and Y coordinates. */ ! int root_x, root_y; /* Mouse root X and Y coordinates. */ ! int cur_x, cur_y; /* Current mouse X and Y coordinates. */ ! int down_x, down_y; /* mouse X and Y at ButtonPress. */ ! int str_width; /* Width in pixels of output string. */ ! int pop_width, pop_height; /* Pop up window width and height. */ ! int context; /* Root, window, or icon context. */ ! int ptrmask; /* for QueryPointer */ ! Bool func_stat; /* If true, function swallowed a ButtonUp. */ ! Bool delta_done; /* If true, then delta functions are done. */ ! Bool local; /* If true, then do not use system defaults. */ ! register Binding *bptr; /* Pointer to Bindings list. */ ! char *root_name; /* Root window name. */ ! char *display = NULL; /* Display name pointer. */ ! char message[128]; /* Error message buffer. */ ! char *rc_file; /* Pointer to $HOME/.uwmrc. */ ! Window event_win; /* Event window. */ ! Window sub_win; /* Subwindow for XUpdateMouse calls. */ ! Window root; /* Root window for QueryPointer. */ ! XWindowAttributes event_info; /* Event window info. */ ! XEvent button_event; /* Button input event. */ ! GC gc; /* graphics context for gray background */ ! XImage grayimage; /* for gray background */ ! XGCValues xgc; /* to create font GCs */ ! char *malloc(); ! Bool fallbackMFont = False, /* using default GC font for menus, */ ! fallbackPFont = False, /* popups, */ ! fallbackIFont = False; /* icons */ #ifdef PROFIL signal(SIGTERM, ptrap); --- 80,115 ----- char **argv; char **environ; { ! int hi; /* Button event high detail. */ ! int lo; /* Button event low detail. */ ! int x, y; /* Mouse X and Y coordinates. */ ! int root_x, root_y; /* Mouse root X and Y coordinates. */ ! int cur_x, cur_y; /* Current mouse X and Y coordinates. */ ! int down_x, down_y; /* mouse X and Y at ButtonPress. */ ! int str_width; /* Width in pixels of output string. */ ! int pop_width, pop_height; /* Pop up window width and height. */ ! int context; /* Root, window, or icon context. */ ! int ptrmask; /* for QueryPointer */ ! Bool func_stat; /* If true, function swallowed a ButtonUp. */ ! Bool delta_done; /* If true, then delta functions are done. */ ! Bool local; /* If true, then do not use system defaults. */ ! register Binding *bptr; /* Pointer to Bindings list. */ ! char *root_name; /* Root window name. */ ! char *display = NULL; /* Display name pointer. */ ! char message[128]; /* Error message buffer. */ ! char *rc_file; /* Pointer to $HOME/.uwmrc. */ ! Window event_win; /* Event window. */ ! Window sub_win; /* Subwindow for XUpdateMouse calls. */ ! Window root; /* Root window for QueryPointer. */ ! XWindowAttributes event_info; /* Event window info. */ ! XEvent button_event; /* Button input event. */ ! GC gc; /* graphics context for gray background */ ! XImage grayimage; /* for gray background */ ! XGCValues xgc; /* to create font GCs */ ! char *malloc(); ! Bool fallbackMFont = False, /* using default GC font for menus, */ ! fallbackPFont = False, /* popups, */ ! fallbackIFont = False; /* icons */ /* next three variables are for XQueryWindow */ Window junk; *************** *** 108,113 fallbackPFont = False, /* popups, */ fallbackIFont = False; /* icons */ #ifdef PROFIL signal(SIGTERM, ptrap); #endif --- 111,123 ----- fallbackPFont = False, /* popups, */ fallbackIFont = False; /* icons */ + /* next three variables are for XQueryWindow */ + Window junk; + Window *kiddies; + unsigned int nkids; + + extern int Fheight; + #ifdef PROFIL signal(SIGTERM, ptrap); #endif *************** *** 109,115 fallbackIFont = False; /* icons */ #ifdef PROFIL ! signal(SIGTERM, ptrap); #endif /* --- 119,125 ----- extern int Fheight; #ifdef PROFIL ! signal(SIGTERM, ptrap); #endif /* *************** *** 111,116 #ifdef PROFIL signal(SIGTERM, ptrap); #endif /* * Set up internal defaults. --- 121,481 ----- #ifdef PROFIL signal(SIGTERM, ptrap); #endif + + /* + * Set up internal defaults. + */ + SetVarDefaults(); + + /* + * Parse the command line arguments. + */ + Argv = argv; + Environ = environ; + argc--, argv++; + while (argc) { + if (**argv == '-') { + if (!(strcmp(*argv, "-f"))) { + argc--, argv++; + if ((argc == 0) || (Startup_File[0] != '\0')) + Usage(); + strncpy(Startup_File, *argv, NAME_LEN); + } + else if (!(strcmp(*argv, "-b"))) + local = TRUE; + else Usage(); + } + else display = *argv; + argc--, argv++; + } + + /* + * Initialize the default bindings. + */ + if (!local) + InitBindings(); + + /* + * Read in and parse $HOME/.uwmrc, if it exists. + */ + sfilename = rc_file = malloc(NAME_LEN); + sprintf(rc_file, "%s/.uwmrc", getenv("HOME")); + if ((yyin = fopen(rc_file, "r")) != NULL) { + Lineno = 1; + yyparse(); + fclose(yyin); + if (Startup_File_Error) + Error("Bad .uwmrc file...aborting"); + } + + /* + * Read in and parse the startup file from the command line, if + * specified. + */ + if (Startup_File[0] != '\0') { + sfilename = Startup_File; + if ((yyin = fopen(Startup_File, "r")) == NULL) { + sprintf(message, "Cannot open startup file '%s'", Startup_File); + Error(message); + } + Lineno = 1; + yyparse(); + fclose(yyin); + if (Startup_File_Error) + Error("Bad startup file...aborting"); + } + + /* + * Verify the menu bindings. + */ + VerifyMenuBindings(); + if (Startup_File_Error) + Error("Bad startup file...aborting"); + + /* + * Open the display. + */ + if ((dpy = XOpenDisplay(display)) == NULL) + Error("Unable to open display"); + scr = DefaultScreen(dpy); + XSynchronize(dpy, 1); + + /* + * Set XErrorFunction to be non-terminating. + */ + XSetErrorHandler(XError); + + + /* + * Force child processes to disinherit the TCP file descriptor. + * This helps shell commands forked and exec'ed from menus + * to work properly. + */ + if ((status = fcntl(ConnectionNumber(dpy), F_SETFD, 1)) == -1) { + perror("uwm: child cannot disinherit TCP fd"); + Error("TCP file descriptor problems"); + } + /* + * Catch some of the basic signals so we don't get rudely killed without + * cleaning up first. + */ + signal(SIGHUP, Quit); + signal(SIGTERM, Quit); + /* + * If the root window has not been named, name it. + */ + status = XFetchName(dpy, RootWindow(dpy, scr), &root_name); + if (root_name == NULL) + XStoreName(dpy, RootWindow(dpy, scr), " X Root Window "); + else free(root_name); + + + ScreenHeight = DisplayHeight(dpy, scr); + ScreenWidth = DisplayWidth(dpy, scr); + + /* + * Create and store the icon background pixmap. + */ + GrayPixmap = (Pixmap)XCreatePixmap(dpy, RootWindow(dpy, scr), + gray_width, gray_height, DefaultDepth(dpy,scr)); + xgc.foreground = BlackPixel(dpy, scr); + xgc.background = WhitePixel(dpy, scr); + gc = XCreateGC(dpy, GrayPixmap, GCForeground+GCBackground, &xgc); + grayimage.height = gray_width; + grayimage.width = gray_height; + grayimage.xoffset = 0; + grayimage.format = XYBitmap; + grayimage.data = (char *)gray_bits; + grayimage.byte_order = LSBFirst; + grayimage.bitmap_unit = 8; + grayimage.bitmap_bit_order = LSBFirst; + grayimage.bitmap_pad = 16; + grayimage.bytes_per_line = 2; + grayimage.depth = 1; + XPutImage(dpy, GrayPixmap, gc, &grayimage, 0, 0, + 0, 0, gray_width, gray_height); + XFreeGC(dpy, gc); + + + /* + * Set up icon window, icon cursor and pop-up window color parameters. + */ + if (Reverse) { + IBorder = WhitePixel(dpy, scr); + IBackground = GrayPixmap; + ITextForground = WhitePixel(dpy, scr); + ITextBackground = BlackPixel(dpy, scr); + PBorder = BlackPixel(dpy, scr); + PBackground = WhitePixel(dpy, scr); + PTextForground = BlackPixel(dpy, scr); + PTextBackground = WhitePixel(dpy, scr); + MBorder = WhitePixel(dpy, scr); + MBackground = BlackPixel(dpy, scr); + MTextForground = WhitePixel(dpy, scr); + MTextBackground = BlackPixel(dpy, scr); + } + else { + IBorder = BlackPixel(dpy, scr); + IBackground = GrayPixmap; + ITextForground = BlackPixel(dpy, scr); + ITextBackground = WhitePixel(dpy, scr); + PBorder = WhitePixel(dpy, scr); + PBackground = BlackPixel(dpy, scr); + PTextForground = WhitePixel(dpy, scr); + PTextBackground = BlackPixel(dpy, scr); + MBorder = BlackPixel(dpy, scr); + MBackground = WhitePixel(dpy, scr); + MTextForground = BlackPixel(dpy, scr); + MTextBackground = WhitePixel(dpy, scr); + } + + /* + * Store all the cursors. + */ + StoreCursors(); + + /* + * grab the mouse buttons according to the map structure + */ + Grab_Buttons(); + + /* + * Initialize titlebar data. + */ + if (Titles) + Init_Titles(); + /* + * Set initial focus to PointerRoot. + */ + XSetInputFocus(dpy, PointerRoot, None, CurrentTime); + + /* + * watch for initial window mapping and window destruction + */ + XSelectInput(dpy, RootWindow(dpy, scr), + SubstructureNotifyMask|SubstructureRedirectMask|FocusChangeMask| + (NeedRootInput ? EVENTMASK|OwnerGrabButtonMask : 0)); + + /* + * Retrieve the information structure for the specifed fonts and + * set the global font information pointers. + */ + IFontInfo = XLoadQueryFont(dpy, IFontName); + if (IFontInfo == NULL) { + fprintf(stderr, "uwm: Unable to open icon font '%s', using server default.\n", + IFontName); + IFontInfo = XQueryFont(dpy, DefaultGC(dpy, scr)->gid); + fallbackIFont = True; + } + PFontInfo = XLoadQueryFont(dpy, PFontName); + if (PFontInfo == NULL) { + fprintf(stderr, "uwm: Unable to open resize font '%s', using server default.\n", + PFontName); + if (fallbackIFont) + PFontInfo = IFontInfo; + else + PFontInfo = XQueryFont(dpy, DefaultGC(dpy, scr)->gid); + fallbackPFont = True; + } + MFontInfo = XLoadQueryFont(dpy, MFontName); + if (MFontInfo == NULL) { + fprintf(stderr, "uwm: Unable to open menu font '%s', using server default.\n", + MFontName); + if (fallbackIFont || fallbackPFont) + MFontInfo = fallbackPFont ? PFontInfo : IFontInfo; + else + MFontInfo = XQueryFont(dpy, DefaultGC(dpy, scr)->gid); + fallbackMFont = True; + } + + /* + * Before we go creating more windows, we buzz through the ones that + * are currently mapped and reparent and/or select on them as necessary + * (for autoraise and titles). + */ + + if (XQueryTree(dpy, DefaultRootWindow(dpy), &junk, &junk, &kiddies, &nkids) + != BadWindow) { + unsigned int i; + + for (i = 0; i < nkids; i++) { + XWindowAttributes xwa; + Window transient; + + XGetWindowAttributes(dpy, kiddies[i], &xwa); + + /* check to see if it's a popup or something */ + XGetTransientForHint(dpy, kiddies[i], &transient); + if (xwa.class == InputOutput && xwa.map_state == + IsViewable && xwa.override_redirect == False && + transient == None) { + if (Titles) /* add title to this window */ + AddTitle(kiddies[i], True); + XSelectInput(dpy, kiddies[i], (EnterWindowMask | + LeaveWindowMask)); + } + } + XFree(kiddies); + } + /* + * Calculate size of the resize pop-up window. + */ + str_width = XTextWidth(PFontInfo, PText, strlen(PText)); + pop_width = str_width + (PPadding << 1); + PWidth = pop_width + (PBorderWidth << 1); + pop_height = PFontInfo->ascent + PFontInfo->descent + (PPadding << 1); + PHeight = pop_height + (PBorderWidth << 1); + + /* + * Create the pop-up window. Create it at (0, 0) for now. We will + * move it where we want later. + */ + Pop = XCreateSimpleWindow(dpy, RootWindow(dpy, scr), + 0, 0, + pop_width, pop_height, + PBorderWidth, + PBorder, PBackground); + if (Pop == FAILURE) Error("Can't create pop-up dimension display window."); + + /* + * Create the menus for later use. + */ + CreateMenus(); + + /* + * Create graphics context. + */ + xgc.foreground = ITextForground; + xgc.background = ITextBackground; + xgc.font = IFontInfo->fid; + xgc.graphics_exposures = FALSE; + IconGC = XCreateGC(dpy, + RootWindow(dpy, scr), + GCForeground+GCBackground+GCGraphicsExposures + +(fallbackIFont ? 0 : GCFont), &xgc); + xgc.foreground = MTextForground; + xgc.background = MTextBackground; + xgc.font = MFontInfo->fid; + MenuGC = XCreateGC(dpy, + RootWindow(dpy, scr), + GCForeground+GCBackground+(fallbackMFont ? 0 : GCFont), &xgc); + xgc.function = GXinvert; + xgc.plane_mask = MTextForground ^ MTextBackground; + MenuInvGC = XCreateGC(dpy, + RootWindow(dpy, scr), GCForeground+GCFunction+GCPlaneMask, &xgc); + xgc.foreground = PTextForground; + xgc.background = PTextBackground; + xgc.font = PFontInfo->fid; + PopGC = XCreateGC(dpy, + RootWindow(dpy, scr), + GCForeground+GCBackground+(fallbackPFont ? 0 : GCFont), &xgc); + xgc.line_width = DRAW_WIDTH; + xgc.foreground = DRAW_VALUE; + xgc.function = DRAW_FUNC; + xgc.subwindow_mode = IncludeInferiors; + DrawGC = XCreateGC(dpy, RootWindow(dpy, scr), + GCLineWidth+GCForeground+GCFunction+GCSubwindowMode, &xgc); + + + /* + * Tell the user we're alive and well. + */ + XBell(dpy, VOLUME_PERCENTAGE(Volume)); + + /* + * Main command loop. + */ + while (TRUE) { + + delta_done = func_stat = FALSE; + + /* + * Get the next mouse button event. Spin our wheels until + * a ButtonPressed event is returned. + * Note that mouse events within an icon window are handled + * in the "GetButton" function or by the icon's owner if + * it is not uwm. + */ + while (TRUE) { + if (!GetButton(&button_event)) + continue; + else if (button_event.type == ButtonPress) + break; + } + /* save mouse coords in case we want them later for a delta action */ + down_x = ((XButtonPressedEvent *)&button_event)->x; + down_y = ((XButtonPressedEvent *)&button_event)->y; + /* + * Okay, determine the event window and mouse coordinates. + */ + status = XTranslateCoordinates(dpy, + RootWindow(dpy, scr), RootWindow(dpy, scr), + ((XButtonPressedEvent *)&button_event)->x, + ((XButtonPressedEvent *)&button_event)->y, + &x, &y, + &event_win); + if (status == BadWindow) + continue; /* Kludge to get around bug in XTranslateCoordinates */ if (!event_win && button_event.xbutton.window != RootWindow(dpy, scr)) *************** *** 112,121 signal(SIGTERM, ptrap); #endif ! /* ! * Set up internal defaults. ! */ ! SetVarDefaults(); /* * Parse the command line arguments. --- 477,514 ----- if (status == BadWindow) continue; ! /* Kludge to get around bug in XTranslateCoordinates */ ! if (!event_win && button_event.xbutton.window != RootWindow(dpy, scr)) ! event_win = button_event.xbutton.window; ! ! /* ! * Determine the event window and context. ! */ ! if (!event_win) { ! event_win = RootWindow(dpy, scr); ! context = ROOT; ! } ! else { ! if (IsIcon(event_win, 0, 0, FALSE, NULL)) ! context = ICON; ! else if ((dat = GetTitleInfo(event_win)) != NULL) { ! #ifdef DEBUG ! prt_info(&button_event); ! #endif ! if (dat->title == event_win) { ! Window root; ! int junk; ! XQueryPointer(dpy, RootWindow(dpy, scr), &root, &junk, ! &x, &y, &down_x, &down_y, &junk); ! if (event_win == dat->title) ! context = TITLE; ! } ! else ! context = WINDOW; ! } ! else ! context = WINDOW; ! } /* * Get the button event detail. *************** *** 117,416 */ SetVarDefaults(); ! /* ! * Parse the command line arguments. ! */ ! Argv = argv; ! Environ = environ; ! argc--, argv++; ! while (argc) { ! if (**argv == '-') { ! if (!(strcmp(*argv, "-f"))) { ! argc--, argv++; ! if ((argc == 0) || (Startup_File[0] != '\0')) ! Usage(); ! strncpy(Startup_File, *argv, NAME_LEN); ! } ! else if (!(strcmp(*argv, "-b"))) ! local = TRUE; ! else Usage(); ! } ! else display = *argv; ! argc--, argv++; ! } ! ! /* ! * Initialize the default bindings. ! */ ! if (!local) ! InitBindings(); ! ! /* ! * Read in and parse $HOME/.uwmrc, if it exists. ! */ ! sfilename = rc_file = malloc(NAME_LEN); ! sprintf(rc_file, "%s/.uwmrc", getenv("HOME")); ! if ((yyin = fopen(rc_file, "r")) != NULL) { ! Lineno = 1; ! yyparse(); ! fclose(yyin); ! if (Startup_File_Error) ! Error("Bad .uwmrc file...aborting"); ! } ! ! /* ! * Read in and parse the startup file from the command line, if ! * specified. ! */ ! if (Startup_File[0] != '\0') { ! sfilename = Startup_File; ! if ((yyin = fopen(Startup_File, "r")) == NULL) { ! sprintf(message, "Cannot open startup file '%s'", Startup_File); ! Error(message); ! } ! Lineno = 1; ! yyparse(); ! fclose(yyin); ! if (Startup_File_Error) ! Error("Bad startup file...aborting"); ! } ! ! /* ! * Verify the menu bindings. ! */ ! VerifyMenuBindings(); ! if (Startup_File_Error) ! Error("Bad startup file...aborting"); ! ! /* ! * Open the display. ! */ ! if ((dpy = XOpenDisplay(display)) == NULL) ! Error("Unable to open display"); ! scr = DefaultScreen(dpy); ! /* XSynchronize(dpy, 1); */ ! ! /* ! * Set XErrorFunction to be non-terminating. ! */ ! XSetErrorHandler(XError); ! ! ! /* ! * Force child processes to disinherit the TCP file descriptor. ! * This helps shell commands forked and exec'ed from menus ! * to work properly. ! */ ! if ((status = fcntl(ConnectionNumber(dpy), F_SETFD, 1)) == -1) { ! perror("uwm: child cannot disinherit TCP fd"); ! Error("TCP file descriptor problems"); ! } ! ! /* ! * If the root window has not been named, name it. ! */ ! status = XFetchName(dpy, RootWindow(dpy, scr), &root_name); ! if (root_name == NULL) ! XStoreName(dpy, RootWindow(dpy, scr), " X Root Window "); ! else free(root_name); ! ! ! ScreenHeight = DisplayHeight(dpy, scr); ! ScreenWidth = DisplayWidth(dpy, scr); ! ! /* ! * Create and store the icon background pixmap. ! */ ! GrayPixmap = (Pixmap)XCreatePixmap(dpy, RootWindow(dpy, scr), ! gray_width, gray_height, DefaultDepth(dpy,scr)); ! xgc.foreground = BlackPixel(dpy, scr); ! xgc.background = WhitePixel(dpy, scr); ! gc = XCreateGC(dpy, GrayPixmap, GCForeground+GCBackground, &xgc); ! grayimage.height = gray_width; ! grayimage.width = gray_height; ! grayimage.xoffset = 0; ! grayimage.format = XYBitmap; ! grayimage.data = (char *)gray_bits; ! grayimage.byte_order = LSBFirst; ! grayimage.bitmap_unit = 8; ! grayimage.bitmap_bit_order = LSBFirst; ! grayimage.bitmap_pad = 16; ! grayimage.bytes_per_line = 2; ! grayimage.depth = 1; ! XPutImage(dpy, GrayPixmap, gc, &grayimage, 0, 0, ! 0, 0, gray_width, gray_height); ! XFreeGC(dpy, gc); ! ! ! /* ! * Set up icon window, icon cursor and pop-up window color parameters. ! */ ! if (Reverse) { ! IBorder = WhitePixel(dpy, scr); ! IBackground = GrayPixmap; ! ITextForground = WhitePixel(dpy, scr); ! ITextBackground = BlackPixel(dpy, scr); ! PBorder = BlackPixel(dpy, scr); ! PBackground = WhitePixel(dpy, scr); ! PTextForground = BlackPixel(dpy, scr); ! PTextBackground = WhitePixel(dpy, scr); ! MBorder = WhitePixel(dpy, scr); ! MBackground = BlackPixel(dpy, scr); ! MTextForground = WhitePixel(dpy, scr); ! MTextBackground = BlackPixel(dpy, scr); ! } ! else { ! IBorder = BlackPixel(dpy, scr); ! IBackground = GrayPixmap; ! ITextForground = BlackPixel(dpy, scr); ! ITextBackground = WhitePixel(dpy, scr); ! PBorder = WhitePixel(dpy, scr); ! PBackground = BlackPixel(dpy, scr); ! PTextForground = WhitePixel(dpy, scr); ! PTextBackground = BlackPixel(dpy, scr); ! MBorder = BlackPixel(dpy, scr); ! MBackground = WhitePixel(dpy, scr); ! MTextForground = BlackPixel(dpy, scr); ! MTextBackground = WhitePixel(dpy, scr); ! } ! ! /* ! * Store all the cursors. ! */ ! StoreCursors(); ! ! /* ! * grab the mouse buttons according to the map structure ! */ ! Grab_Buttons(); ! ! /* ! * Set initial focus to PointerRoot. ! */ ! XSetInputFocus(dpy, PointerRoot, None, CurrentTime); ! ! /* ! * watch for initial window mapping and window destruction ! */ ! XSelectInput(dpy, RootWindow(dpy, scr), ! SubstructureNotifyMask|SubstructureRedirectMask|FocusChangeMask| ! (NeedRootInput ? EVENTMASK|OwnerGrabButtonMask : 0)); ! ! /* ! * Retrieve the information structure for the specifed fonts and ! * set the global font information pointers. ! */ ! IFontInfo = XLoadQueryFont(dpy, IFontName); ! if (IFontInfo == NULL) { ! fprintf(stderr, "uwm: Unable to open icon font '%s', using server default.\n", ! IFontName); ! IFontInfo = XQueryFont(dpy, DefaultGC(dpy, scr)->gid); ! fallbackIFont = True; ! } ! PFontInfo = XLoadQueryFont(dpy, PFontName); ! if (PFontInfo == NULL) { ! fprintf(stderr, "uwm: Unable to open resize font '%s', using server default.\n", ! PFontName); ! if (fallbackIFont) ! PFontInfo = IFontInfo; ! else ! PFontInfo = XQueryFont(dpy, DefaultGC(dpy, scr)->gid); ! fallbackPFont = True; ! } ! MFontInfo = XLoadQueryFont(dpy, MFontName); ! if (MFontInfo == NULL) { ! fprintf(stderr, "uwm: Unable to open menu font '%s', using server default.\n", ! MFontName); ! if (fallbackIFont || fallbackPFont) ! MFontInfo = fallbackPFont ? PFontInfo : IFontInfo; ! else ! MFontInfo = XQueryFont(dpy, DefaultGC(dpy, scr)->gid); ! fallbackMFont = True; ! } ! ! /* ! * Calculate size of the resize pop-up window. ! */ ! str_width = XTextWidth(PFontInfo, PText, strlen(PText)); ! pop_width = str_width + (PPadding << 1); ! PWidth = pop_width + (PBorderWidth << 1); ! pop_height = PFontInfo->ascent + PFontInfo->descent + (PPadding << 1); ! PHeight = pop_height + (PBorderWidth << 1); ! ! /* ! * Create the pop-up window. Create it at (0, 0) for now. We will ! * move it where we want later. ! */ ! Pop = XCreateSimpleWindow(dpy, RootWindow(dpy, scr), ! 0, 0, ! pop_width, pop_height, ! PBorderWidth, ! PBorder, PBackground); ! if (Pop == FAILURE) Error("Can't create pop-up dimension display window."); ! ! /* ! * Create the menus for later use. ! */ ! CreateMenus(); ! ! /* ! * Create graphics context. ! */ ! xgc.foreground = ITextForground; ! xgc.background = ITextBackground; ! xgc.font = IFontInfo->fid; ! xgc.graphics_exposures = FALSE; ! IconGC = XCreateGC(dpy, ! RootWindow(dpy, scr), ! GCForeground+GCBackground+GCGraphicsExposures ! +(fallbackIFont ? 0 : GCFont), &xgc); ! xgc.foreground = MTextForground; ! xgc.background = MTextBackground; ! xgc.font = MFontInfo->fid; ! MenuGC = XCreateGC(dpy, ! RootWindow(dpy, scr), ! GCForeground+GCBackground+(fallbackMFont ? 0 : GCFont), &xgc); ! xgc.function = GXinvert; ! xgc.plane_mask = MTextForground ^ MTextBackground; ! MenuInvGC = XCreateGC(dpy, ! RootWindow(dpy, scr), GCForeground+GCFunction+GCPlaneMask, &xgc); ! xgc.foreground = PTextForground; ! xgc.background = PTextBackground; ! xgc.font = PFontInfo->fid; ! PopGC = XCreateGC(dpy, ! RootWindow(dpy, scr), ! GCForeground+GCBackground+(fallbackPFont ? 0 : GCFont), &xgc); ! xgc.line_width = DRAW_WIDTH; ! xgc.foreground = DRAW_VALUE; ! xgc.function = DRAW_FUNC; ! xgc.subwindow_mode = IncludeInferiors; ! DrawGC = XCreateGC(dpy, RootWindow(dpy, scr), ! GCLineWidth+GCForeground+GCFunction+GCSubwindowMode, &xgc); ! ! ! /* ! * Tell the user we're alive and well. ! */ ! XBell(dpy, VOLUME_PERCENTAGE(Volume)); ! ! /* ! * Main command loop. ! */ ! while (TRUE) { ! ! delta_done = func_stat = FALSE; ! ! /* ! * Get the next mouse button event. Spin our wheels until ! * a ButtonPressed event is returned. ! * Note that mouse events within an icon window are handled ! * in the "GetButton" function or by the icon's owner if ! * it is not uwm. ! */ ! while (TRUE) { ! if (!GetButton(&button_event)) continue; ! if (button_event.type == ButtonPress) break; ! } /* save mouse coords in case we want them later for a delta action */ down_x = ((XButtonPressedEvent *)&button_event)->x; --- 510,584 ----- context = WINDOW; } ! /* ! * Get the button event detail. ! */ ! lo = ((XButtonPressedEvent *)&button_event)->button; ! hi = ((XButtonPressedEvent *)&button_event)->state; ! ! /* ! * Determine which function was selected and invoke it. ! */ ! for(bptr = Blist; bptr; bptr = bptr->next) { ! if ((bptr->button != lo) || ! (((int)bptr->mask & ModMask) != hi)) ! continue; ! ! if (bptr->context != context) ! continue; ! ! if (!(bptr->mask & ButtonDown)) ! continue; ! ! /* ! * Found a match! Invoke the function. ! */ ! if ((*bptr->func)((context == TITLE ? dat->parent : event_win), ! (int)bptr->mask & ModMask, ! bptr->button, ! x, y, ! bptr->menu)) { ! func_stat = TRUE; ! } ! } ! ! /* ! * If the function ate the ButtonUp event, then restart the loop. ! */ ! if (func_stat) continue; ! ! while(TRUE) { ! /* ! * Wait for the next button event. ! */ ! if (XPending(dpy) && GetButton(&button_event)) { ! ! /* ! * If it's not a release of the same button that was pressed, ! * don't do the function bound to 'ButtonUp'. ! */ ! if (button_event.type != ButtonRelease) ! break; ! if (lo != ((XButtonReleasedEvent *)&button_event)->button) ! break; ! if ((hi|ButtonMask(lo)) != ! ((XButtonReleasedEvent *)&button_event)->state) ! break; ! ! /* ! * Okay, determine the event window and mouse coordinates. ! */ ! status = XTranslateCoordinates(dpy, ! RootWindow(dpy, scr), RootWindow(dpy, scr), ! ((XButtonReleasedEvent *)&button_event)->x, ! ((XButtonReleasedEvent *)&button_event)->y, ! &x, &y, ! &event_win); ! if (status == BadWindow) ! break; ! ! if (!event_win && button_event.xbutton.window != RootWindow(dpy, scr)) ! event_win = button_event.xbutton.window; if (!event_win) { event_win = RootWindow(dpy, scr); *************** *** 412,429 if (button_event.type == ButtonPress) break; } ! /* save mouse coords in case we want them later for a delta action */ ! down_x = ((XButtonPressedEvent *)&button_event)->x; ! down_y = ((XButtonPressedEvent *)&button_event)->y; ! /* ! * Okay, determine the event window and mouse coordinates. ! */ ! status = XTranslateCoordinates(dpy, ! RootWindow(dpy, scr), RootWindow(dpy, scr), ! ((XButtonPressedEvent *)&button_event)->x, ! ((XButtonPressedEvent *)&button_event)->y, ! &x, &y, ! &event_win); if (status == FAILURE) continue; --- 580,601 ----- if (!event_win && button_event.xbutton.window != RootWindow(dpy, scr)) event_win = button_event.xbutton.window; ! if (!event_win) { ! event_win = RootWindow(dpy, scr); ! context = ROOT; ! } ! else { ! if (IsIcon(event_win, 0, 0, FALSE, NULL)) ! context = ICON; ! else if ((dat = GetTitleInfo(event_win)) != NULL) { ! if (dat->title == event_win) ! context = TITLE; ! else ! context = WINDOW; ! } ! else ! context = WINDOW; ! } /* * Determine which function was selected and invoke it. *************** *** 425,431 &x, &y, &event_win); ! if (status == FAILURE) continue; /* * Determine the event window and context. --- 597,647 ----- context = WINDOW; } ! /* ! * Determine which function was selected and invoke it. ! */ ! for(bptr = Blist; bptr; bptr = bptr->next) { ! ! if ((bptr->button != lo) || ! (((int)bptr->mask & ModMask) != hi)) ! continue; ! ! if (bptr->context != context) ! continue; ! ! if (!(bptr->mask & ButtonUp)) ! continue; ! ! /* ! * Found a match! Invoke the function. ! */ ! (*bptr->func)((context == TITLE ? dat->parent : event_win), ! (int)bptr->mask & ModMask, ! bptr->button, ! x, y, ! bptr->menu); ! } ! break; ! } ! ! XQueryPointer(dpy, RootWindow(dpy, scr), ! &root, &junk, &root_x, &root_y, &cur_x, &cur_y, &ptrmask); ! if (!delta_done && ! ((abs(cur_x - x) > Delta) || (abs(cur_y - y) > Delta))) { ! /* ! * Delta functions are done once (and only once.) ! */ ! delta_done = TRUE; ! ! /* ! * Determine the new event window's coordinates from the original ButtonPress ! * event. ! */ ! status = XTranslateCoordinates(dpy, RootWindow(dpy, scr), ! RootWindow(dpy, scr), ! down_x, down_y, &x, &y, &junk); ! if (status == BadWindow) ! break; if (!event_win && button_event.xbutton.window != RootWindow(dpy, scr)) event_win = button_event.xbutton.window; *************** *** 427,557 if (status == FAILURE) continue; ! /* ! * Determine the event window and context. ! */ ! if (event_win == 0) { ! event_win = RootWindow(dpy, scr); ! context = ROOT; ! } else { ! if (IsIcon(event_win, 0, 0, FALSE, NULL)) ! context = ICON; ! else context = WINDOW; ! } ! ! /* ! * Get the button event detail. ! */ ! lo = ((XButtonPressedEvent *)&button_event)->button; ! hi = ((XButtonPressedEvent *)&button_event)->state; ! ! /* ! * Determine which function was selected and invoke it. ! */ ! for(bptr = Blist; bptr; bptr = bptr->next) { ! ! if ((bptr->button != lo) || ! (((int)bptr->mask & ModMask) != hi)) ! continue; ! ! if (bptr->context != context) ! continue; ! ! if (!(bptr->mask & ButtonDown)) ! continue; ! ! /* ! * Found a match! Invoke the function. ! */ ! if ((*bptr->func)(event_win, ! (int)bptr->mask & ModMask, ! bptr->button, ! x, y, ! bptr->menu)) { ! func_stat = TRUE; ! break; ! } ! } ! ! /* ! * If the function ate the ButtonUp event, then restart the loop. ! */ ! if (func_stat) continue; ! ! while(TRUE) { ! /* ! * Wait for the next button event. ! */ ! if (XPending(dpy) && GetButton(&button_event)) { ! ! /* ! * If it's not a release of the same button that was pressed, ! * don't do the function bound to 'ButtonUp'. ! */ ! if (button_event.type != ButtonRelease) ! break; ! if (lo != ((XButtonReleasedEvent *)&button_event)->button) ! break; ! if ((hi|ButtonMask(lo)) != ! ((XButtonReleasedEvent *)&button_event)->state) ! break; ! ! /* ! * Okay, determine the event window and mouse coordinates. ! */ ! status = XTranslateCoordinates(dpy, ! RootWindow(dpy, scr), RootWindow(dpy, scr), ! ((XButtonReleasedEvent *)&button_event)->x, ! ((XButtonReleasedEvent *)&button_event)->y, ! &x, &y, ! &event_win); ! ! if (status == FAILURE) break; ! ! if (event_win == 0) { ! event_win = RootWindow(dpy, scr); ! context = ROOT; ! } else { ! if (IsIcon(event_win, 0, 0, FALSE, NULL)) ! context = ICON; ! else context = WINDOW; ! } ! ! /* ! * Determine which function was selected and invoke it. ! */ ! for(bptr = Blist; bptr; bptr = bptr->next) { ! ! if ((bptr->button != lo) || ! (((int)bptr->mask & ModMask) != hi)) ! continue; ! ! if (bptr->context != context) ! continue; ! ! if (!(bptr->mask & ButtonUp)) ! continue; ! ! /* ! * Found a match! Invoke the function. ! */ ! (*bptr->func)(event_win, ! (int)bptr->mask & ModMask, ! bptr->button, ! x, y, ! bptr->menu); ! } ! break; ! } ! ! XQueryPointer(dpy, RootWindow(dpy, scr), ! &root, &event_win, &root_x, &root_y, &cur_x, &cur_y, &ptrmask); ! if (!delta_done && ! ((abs(cur_x - x) > Delta) || (abs(cur_y - y) > Delta))) { ! /* ! * Delta functions are done once (and only once.) ! */ ! delta_done = TRUE; /* * Determine the new event window's coordinates. --- 643,707 ----- if (status == BadWindow) break; ! if (!event_win && button_event.xbutton.window != RootWindow(dpy, scr)) ! event_win = button_event.xbutton.window; ! /* ! * Determine the event window and context. ! */ ! ! if (!event_win) { ! event_win = RootWindow(dpy, scr); ! context = ROOT; ! } ! else { ! if (IsIcon(event_win, 0, 0, FALSE, NULL)) ! context = ICON; ! else if ((dat = GetTitleInfo(event_win)) != NULL) { ! if (dat->title == event_win) ! context = TITLE; ! else ! context = WINDOW; ! } ! else ! context = WINDOW; ! } ! ! /* ! * Determine which function was selected and invoke it. ! */ ! for(bptr = Blist; bptr; bptr = bptr->next) { ! ! if ((bptr->button != lo) || ! (((int)bptr->mask & ModMask) != hi)) ! continue; ! ! if (bptr->context != context) ! continue; ! ! if (!(bptr->mask & DeltaMotion)) ! continue; ! ! /* ! * Found a match! Invoke the function. ! */ ! if ((*bptr->func)((context == TITLE ? dat->parent : event_win), ! (int)bptr->mask & ModMask, ! bptr->button, ! x, y, ! bptr->menu)) { ! func_stat = TRUE; ! break; ! } ! } ! /* ! * If the function ate the ButtonUp event, ! * then restart the loop. ! */ ! if (func_stat) break; ! } ! } ! } ! } /* * Initialize the default bindings. First, write the character array *************** *** 553,617 */ delta_done = TRUE; ! /* ! * Determine the new event window's coordinates. ! * from the original ButtonPress event ! */ ! status = XTranslateCoordinates(dpy, ! RootWindow(dpy, scr), RootWindow(dpy, scr), ! down_x, down_y, &x, &y, &event_win); ! if (status == FAILURE) break; ! ! /* ! * Determine the event window and context. ! */ ! if (event_win == 0) { ! event_win = RootWindow(dpy, scr); ! context = ROOT; ! } else { ! if (IsIcon(event_win, 0, 0, FALSE, NULL)) ! context = ICON; ! else context = WINDOW; ! } ! ! /* ! * Determine which function was selected and invoke it. ! */ ! for(bptr = Blist; bptr; bptr = bptr->next) { ! ! if ((bptr->button != lo) || ! (((int)bptr->mask & ModMask) != hi)) ! continue; ! ! if (bptr->context != context) ! continue; ! ! if (!(bptr->mask & DeltaMotion)) ! continue; ! ! /* ! * Found a match! Invoke the function. ! */ ! if ((*bptr->func)(event_win, ! (int)bptr->mask & ModMask, ! bptr->button, ! x, y, ! bptr->menu)) { ! func_stat = TRUE; ! break; ! } ! } ! /* ! * If the function ate the ButtonUp event, ! * then restart the loop. ! */ ! if (func_stat) break; ! } ! } ! } ! } ! ! /* * Initialize the default bindings. First, write the character array * out to a temp file, then point the parser to it and read it in. * Afterwards, we unlink the temp file. --- 703,709 ----- } } ! /* * Initialize the default bindings. First, write the character array * out to a temp file, then point the parser to it and read it in. * Afterwards, we unlink the temp file. *************** *** 618,667 */ InitBindings() { ! char *mktemp(); ! char *tempfile = TEMPFILE; /* Temporary filename. */ ! register FILE *fp; /* Temporary file pointer. */ ! register char **ptr; /* Default bindings string array pointer. */ ! ! /* ! * Create and write the temp file. ! */ ! sfilename = mktemp(tempfile); ! if ((fp = fopen(tempfile, "w")) == NULL) { ! perror("uwm: cannot create temp file"); ! exit(1); ! } ! for (ptr = DefaultBindings; *ptr; ptr++) { ! fputs(*ptr, fp); ! fputc('\n', fp); ! } ! fclose(fp); ! ! /* ! * Read in the bindings from the temp file and parse them. ! */ ! if ((yyin = fopen(tempfile, "r")) == NULL) { ! perror("uwm: cannot open temp file"); ! exit(1); ! } ! Lineno = 1; ! yyparse(); ! fclose(yyin); ! unlink(tempfile); ! if (Startup_File_Error) ! Error("Bad default bindings...aborting"); ! ! /* ! * Parse the system startup file, if one exists. ! */ ! if ((yyin = fopen(SYSFILE, "r")) != NULL) { ! sfilename = SYSFILE; ! Lineno = 1; ! yyparse(); ! fclose(yyin); ! if (Startup_File_Error) ! Error("Bad system startup file...aborting"); ! } } /* --- 710,759 ----- */ InitBindings() { ! char *mktemp(); ! char *tempfile = TEMPFILE; /* Temporary filename. */ ! register FILE *fp; /* Temporary file pointer. */ ! register char **ptr; /* Default bindings string array pointer. */ ! ! /* ! * Create and write the temp file. ! */ ! sfilename = mktemp(tempfile); ! if ((fp = fopen(tempfile, "w")) == NULL) { ! perror("uwm: cannot create temp file"); ! exit(1); ! } ! for (ptr = DefaultBindings; *ptr; ptr++) { ! fputs(*ptr, fp); ! fputc('\n', fp); ! } ! fclose(fp); ! ! /* ! * Read in the bindings from the temp file and parse them. ! */ ! if ((yyin = fopen(tempfile, "r")) == NULL) { ! perror("uwm: cannot open temp file"); ! exit(1); ! } ! Lineno = 1; ! yyparse(); ! fclose(yyin); ! unlink(tempfile); ! if (Startup_File_Error) ! Error("Bad default bindings...aborting"); ! ! /* ! * Parse the system startup file, if one exists. ! */ ! if ((yyin = fopen(SYSFILE, "r")) != NULL) { ! sfilename = SYSFILE; ! Lineno = 1; ! yyparse(); ! fclose(yyin); ! if (Startup_File_Error) ! Error("Bad system startup file...aborting"); ! } } /* *************** *** 672,698 */ VerifyMenuBindings() { ! Binding *bptr; ! MenuLink *mptr; ! ! for(bptr = Blist; bptr; bptr = bptr->next) { ! if (bptr->func == Menu) { ! for(mptr = Menus; mptr; mptr = mptr->next) { ! if(!(strcmp(bptr->menuname, mptr->menu->name))) { ! bptr->menu = mptr->menu; ! break; ! } ! } ! if (mptr == NULL) { ! fprintf(stderr, ! "uwm: non-existent menu reference: \"%s\"\n", ! bptr->menuname); ! Startup_File_Error = TRUE; ! } ! } ! } ! CheckMenus(); ! } /* * Check nested menu consistency by verifying that every menu line that --- 764,790 ----- */ VerifyMenuBindings() { ! Binding *bptr; ! MenuLink *mptr; ! ! for(bptr = Blist; bptr; bptr = bptr->next) { ! if (bptr->func == Menu) { ! for(mptr = Menus; mptr; mptr = mptr->next) { ! if(!(strcmp(bptr->menuname, mptr->menu->name))) { ! bptr->menu = mptr->menu; ! break; ! } ! } ! if (mptr == NULL) { ! fprintf(stderr, ! "uwm: non-existent menu reference: \"%s\"\n", ! bptr->menuname); ! Startup_File_Error = TRUE; ! } ! } ! } ! CheckMenus(); ! } /* * Check nested menu consistency by verifying that every menu line that *************** *** 700,714 */ CheckMenus() { ! MenuLink *ptr; ! Bool errflag = FALSE; ! ! for(ptr = Menus; ptr; ptr = ptr->next) { ! if (ChkMline(ptr->menu)) ! errflag = TRUE; ! } ! if (errflag) ! Error("Nested menu inconsistency"); } Bool ChkMline(menu) --- 792,806 ----- */ CheckMenus() { ! MenuLink *ptr; ! Bool errflag = FALSE; ! ! for(ptr = Menus; ptr; ptr = ptr->next) { ! if (ChkMline(ptr->menu)) ! errflag = TRUE; ! } ! if (errflag) ! Error("Nested menu inconsistency"); } Bool ChkMline(menu) *************** *** 714,741 Bool ChkMline(menu) MenuInfo *menu; { ! MenuLine *ptr; ! MenuLink *lptr; ! Bool errflag = FALSE; ! ! for(ptr = menu->line; ptr; ptr = ptr->next) { ! if (ptr->type == IsMenuFunction) { ! for(lptr = Menus; lptr; lptr = lptr->next) { ! if(!(strcmp(ptr->text, lptr->menu->name))) { ! ptr->menu = lptr->menu; ! break; ! } ! } ! if (lptr == NULL) { ! fprintf(stderr, ! "uwm: non-existent menu reference: \"%s\"\n", ! ptr->text); ! errflag = TRUE; ! } ! } ! } ! return(errflag); ! } /* * Grab the mouse buttons according to the bindings list. --- 806,833 ----- Bool ChkMline(menu) MenuInfo *menu; { ! MenuLine *ptr; ! MenuLink *lptr; ! Bool errflag = FALSE; ! ! for(ptr = menu->line; ptr; ptr = ptr->next) { ! if (ptr->type == IsMenuFunction) { ! for(lptr = Menus; lptr; lptr = lptr->next) { ! if(!(strcmp(ptr->text, lptr->menu->name))) { ! ptr->menu = lptr->menu; ! break; ! } ! } ! if (lptr == NULL) { ! fprintf(stderr, ! "uwm: non-existent menu reference: \"%s\"\n", ! ptr->text); ! errflag = TRUE; ! } ! } ! } ! return(errflag); ! } /* * Grab the mouse buttons according to the bindings list. *************** *** 742,761 */ Grab_Buttons() { ! Binding *bptr; ! ! for(bptr = Blist; bptr; bptr = bptr->next) ! if ((bptr->context & (WINDOW | ICON | ROOT)) == ROOT) { ! ! /* don't grab buttons if you don't have to - allow application ! access to buttons unless context includes window or icon */ ! ! NeedRootInput = TRUE; ! } ! else { ! /* context includes a window, so must grab */ ! Grab(bptr->mask); ! } } /* --- 834,853 ----- */ Grab_Buttons() { ! Binding *bptr; ! ! for(bptr = Blist; bptr; bptr = bptr->next) ! if ((bptr->context & (WINDOW | ICON | ROOT | TITLE)) == ROOT) { ! ! /* don't grab buttons if you don't have to - allow application ! access to buttons unless context includes window or icon */ ! ! NeedRootInput = TRUE; ! } ! else if (bptr->context != TITLE) { ! /* It's not just on title bars */ ! Grab(bptr->mask, RootWindow(dpy, scr)); ! } } /* *************** *** 761,767 /* * Grab a mouse button according to the given mask. */ ! Grab(mask) unsigned int mask; { unsigned int m = LeftMask | MiddleMask | RightMask; --- 853,859 ----- /* * Grab a mouse button according to the given mask. */ ! Grab(mask, w) unsigned int mask; Window w; { *************** *** 763,768 */ Grab(mask) unsigned int mask; { unsigned int m = LeftMask | MiddleMask | RightMask; --- 855,861 ----- */ Grab(mask, w) unsigned int mask; + Window w; { unsigned int m = LeftMask | MiddleMask | RightMask; *************** *** 764,790 Grab(mask) unsigned int mask; { ! unsigned int m = LeftMask | MiddleMask | RightMask; ! ! switch (mask & m) { ! case LeftMask: ! XGrabButton(dpy, LeftButton, mask & ModMask, ! RootWindow(dpy, scr), TRUE, EVENTMASK, ! GrabModeAsync, GrabModeAsync, None, LeftButtonCursor); ! break; ! ! case MiddleMask: ! XGrabButton(dpy, MiddleButton, mask & ModMask, ! RootWindow(dpy, scr), TRUE, EVENTMASK, ! GrabModeAsync, GrabModeAsync, None, MiddleButtonCursor); ! break; ! ! case RightMask: ! XGrabButton(dpy, RightButton, mask & ModMask, ! RootWindow(dpy, scr), TRUE, EVENTMASK, ! GrabModeAsync, GrabModeAsync, None, RightButtonCursor); ! break; ! } } /* --- 857,880 ----- unsigned int mask; Window w; { ! unsigned int m = LeftMask | MiddleMask | RightMask; ! ! switch (mask & m) { ! case LeftMask: ! XGrabButton(dpy, LeftButton, mask & ModMask, w, TRUE, EVENTMASK, ! GrabModeAsync, GrabModeAsync, None, LeftButtonCursor); ! break; ! ! case MiddleMask: ! XGrabButton(dpy, MiddleButton, mask & ModMask, w, TRUE, EVENTMASK, ! GrabModeAsync, GrabModeAsync, None, MiddleButtonCursor); ! break; ! ! case RightMask: ! XGrabButton(dpy, RightButton, mask & ModMask, w, TRUE, EVENTMASK, ! GrabModeAsync, GrabModeAsync, None, RightButtonCursor); ! break; ! } } /* *************** *** 793,815 ResetCursor(button) int button; { ! ! switch (button) { ! case LeftButton: ! XChangeActivePointerGrab( ! dpy, EVENTMASK, LeftButtonCursor, CurrentTime); ! break; ! ! case MiddleButton: ! XChangeActivePointerGrab( ! dpy, EVENTMASK, MiddleButtonCursor, CurrentTime); ! break; ! ! case RightButton: ! XChangeActivePointerGrab( ! dpy, EVENTMASK, RightButtonCursor, CurrentTime); ! break; ! } } /* --- 883,905 ----- ResetCursor(button) int button; { ! ! switch (button) { ! case LeftButton: ! XChangeActivePointerGrab( ! dpy, EVENTMASK, LeftButtonCursor, CurrentTime); ! break; ! ! case MiddleButton: ! XChangeActivePointerGrab( ! dpy, EVENTMASK, MiddleButtonCursor, CurrentTime); ! break; ! ! case RightButton: ! XChangeActivePointerGrab( ! dpy, EVENTMASK, RightButtonCursor, CurrentTime); ! break; ! } } /* *************** *** 818,825 yyerror(s) char*s; { ! fprintf(stderr, "uwm: %s: %d: %s\n", sfilename, Lineno, s); ! Startup_File_Error = TRUE; } /* --- 908,915 ----- yyerror(s) char*s; { ! fprintf(stderr, "uwm: %s: %d: %s\n", sfilename, Lineno, s); ! Startup_File_Error = TRUE; } /* *************** *** 827,836 */ Usage() { ! fputs("Usage: uwm [-b] [-f <file>] [<host>:<display>]\n\n", stderr); ! fputs("The -b option bypasses system and default bindings\n", stderr); ! fputs("The -f option specifies an additional startup file\n", stderr); ! exit(1); } /* --- 917,926 ----- */ Usage() { ! fputs("Usage: uwm [-b] [-f <file>] [<host>:<display>]\n\n", stderr); ! fputs("The -b option bypasses system and default bindings\n", stderr); ! fputs("The -f option specifies an additional startup file\n", stderr); ! exit(1); } /* *************** *** 839,846 XIOError(dsp) Display *dsp; { ! perror("uwm"); ! exit(3); } SetVarDefaults() --- 929,936 ----- XIOError(dsp) Display *dsp; { ! perror("uwm"); ! exit(3); } SetVarDefaults() *************** *** 845,863 SetVarDefaults() { ! strcpy(IFontName, DEF_FONT); ! strcpy(PFontName, DEF_FONT); ! strcpy(MFontName, DEF_FONT); ! Delta = DEF_DELTA; ! IBorderWidth = DEF_ICON_BORDER_WIDTH; ! HIconPad = DEF_ICON_PADDING; ! VIconPad = DEF_ICON_PADDING; ! PBorderWidth = DEF_POP_BORDER_WIDTH; ! PPadding = DEF_POP_PADDING; ! MBorderWidth = DEF_MENU_BORDER_WIDTH; ! HMenuPad = DEF_MENU_PADDING; ! VMenuPad = DEF_MENU_PADDING; ! Volume = DEF_VOLUME; ! Pushval = DEF_PUSH; ! FocusSetByUser = FALSE; } --- 935,955 ----- SetVarDefaults() { ! strcpy(IFontName, DEF_FONT); ! strcpy(PFontName, DEF_FONT); ! strcpy(MFontName, DEF_FONT); ! Delta = DEF_DELTA; ! IBorderWidth = DEF_ICON_BORDER_WIDTH; ! HIconPad = DEF_ICON_PADDING; ! VIconPad = DEF_ICON_PADDING; ! PBorderWidth = DEF_POP_BORDER_WIDTH; ! PPadding = DEF_POP_PADDING; ! MBorderWidth = DEF_MENU_BORDER_WIDTH; ! HMenuPad = DEF_MENU_PADDING; ! VMenuPad = DEF_MENU_PADDING; ! Volume = DEF_VOLUME; ! Pushval = DEF_PUSH; ! FocusSetByUser = FALSE; } #ifdef DEBUG *************** *** 861,863 Pushval = DEF_PUSH; FocusSetByUser = FALSE; } --- 951,965 ----- Pushval = DEF_PUSH; FocusSetByUser = FALSE; } + + #ifdef DEBUG + prt_info(ev) + XButtonEvent *ev; + { + fprintf(stderr, "EVENT_DETAIL: win: %x, subwin: %x, xy: (%d, %d)\n", + ev->window, ev->subwindow, ev->x, ev->y); + if ((dat = GetTitleInfo(ev->window)) != NULL) + fprintf(stderr, "Event window is TITLED: frame: %x, title: %x, subwin: %x\n", + dat->parent, dat->title, dat->subwin); + } + #endif *** uwm.new/uwm.h Mon Dec 7 00:59:43 1987 --- uwm.new/uwm.h Sat Dec 12 12:16:53 1987 *************** *** 84,89 #define ROOT 0x1 #define WINDOW 0x2 #define ICON 0x4 #define FAILURE 0 #define NAME_LEN 256 /* Maximum length of filenames. */ --- 84,90 ----- #define ROOT 0x1 #define WINDOW 0x2 #define ICON 0x4 + #define TITLE 0x8 #define FAILURE 0 #define NAME_LEN 256 /* Maximum length of filenames. */ *************** *** 93,98 #define DrawZap() XDrawSegments(dpy, RootWindow(dpy, scr),DrawGC,zap,num_vectors) /* * Keyword table entry. */ typedef struct _keyword { --- 94,108 ----- #define DrawZap() XDrawSegments(dpy, RootWindow(dpy, scr),DrawGC,zap,num_vectors) /* + * All one needs to know about a title bar.. (so far...) + */ + typedef struct _title { + Window title, subwin, parent; + char *name; + unsigned int border_width; + } TitleData; + + /* * Keyword table entry. */ typedef struct _keyword { *************** *** 206,211 int type; /* IsShellCommand, IsText, IsTextNL... */ Window w; /* Subwindow for this line. */ char *text; /* Text string to be acted upon. */ Bool (*func)(); /* Window manager function to be invoked. */ struct _menuinfo *menu; /* Menu to be invoked. */ char *foreground; /* Name of foreground color. */ --- 216,222 ----- int type; /* IsShellCommand, IsText, IsTextNL... */ Window w; /* Subwindow for this line. */ char *text; /* Text string to be acted upon. */ + char *aux; /* Points to aux data if there is any */ Bool (*func)(); /* Window manager function to be invoked. */ struct _menuinfo *menu; /* Menu to be invoked. */ char *foreground; /* Name of foreground color. */ *************** *** 223,228 #define IsUwmFunction 4 #define IsMenuFunction 5 #define IsImmFunction 6 /* Immediate (context-less) function. */ /* * Menu Link data type. Used by the parser when creating a linked list --- 234,240 ----- #define IsUwmFunction 4 #define IsMenuFunction 5 #define IsImmFunction 6 /* Immediate (context-less) function. */ + #define IsVar 7 /* we're setting a variable */ /* * Menu Link data type. Used by the parser when creating a linked list *************** *** 244,249 extern XFontStruct *IFontInfo; /* Icon text font information. */ extern XFontStruct *PFontInfo; /* Pop-up text font information. */ extern XFontStruct *MFontInfo; /* Menu text font information. */ extern Pixmap GrayPixmap; /* Gray pixmap. */ extern Pixel IBorder; /* Icon window border pixmap. */ extern Pixmap IBackground; /* Icon window background pixmap. */ --- 256,263 ----- extern XFontStruct *IFontInfo; /* Icon text font information. */ extern XFontStruct *PFontInfo; /* Pop-up text font information. */ extern XFontStruct *MFontInfo; /* Menu text font information. */ + extern XFontStruct *TFontInfo; /* Title text font information. */ + extern XFontStruct *TFontBoldInfo;/* Title text (bold) font information. */ extern Pixmap GrayPixmap; /* Gray pixmap. */ extern Pixel IBorder; /* Icon window border pixmap. */ extern Pixmap IBackground; /* Icon window background pixmap. */ *************** *** 282,287 extern int VMenuPad; /* Menu vertical padding. */ extern int MaxColors; /* Maximum number of colors to use. */ extern int Pushval; /* Number of pixels to push window by. */ extern int Volume; /* Audible alarm volume. */ extern int status; /* Routine return status. */ extern int Maxfd; /* Maximum file descriptors for select(2). */ --- 296,302 ----- extern int VMenuPad; /* Menu vertical padding. */ extern int MaxColors; /* Maximum number of colors to use. */ extern int Pushval; /* Number of pixels to push window by. */ + extern int RaiseDelay; /* Delay in milliseconds before autoraising windows */ extern int Volume; /* Audible alarm volume. */ extern int status; /* Routine return status. */ extern int Maxfd; /* Maximum file descriptors for select(2). */ *************** *** 292,297 extern GC MenuInvGC; /* graphics context for menu background */ extern GC DrawGC; /* graphics context for zap */ extern Bool Autoselect; /* Warp mouse to default menu selection? */ extern Bool Freeze; /* Freeze server during move/resize? */ extern Bool Grid; /* Should the m/r box contain a 9 seg. grid. */ --- 307,313 ----- extern GC MenuInvGC; /* graphics context for menu background */ extern GC DrawGC; /* graphics context for zap */ + extern Bool Autoraise; /* Raise window on input focus? */ extern Bool Autoselect; /* Warp mouse to default menu selection? */ extern Bool Freeze; /* Freeze server during move/resize? */ extern Bool Grid; /* Should the m/r box contain a 9 seg. grid. */ *************** *** 295,300 extern Bool Autoselect; /* Warp mouse to default menu selection? */ extern Bool Freeze; /* Freeze server during move/resize? */ extern Bool Grid; /* Should the m/r box contain a 9 seg. grid. */ extern Bool NWindow; /* Normalize windows? */ extern Bool NIcon; /* Normalize icons? */ extern Bool Push; /* Relative=TRUE, Absolute=FALSE. */ --- 311,317 ----- extern Bool Autoselect; /* Warp mouse to default menu selection? */ extern Bool Freeze; /* Freeze server during move/resize? */ extern Bool Grid; /* Should the m/r box contain a 9 seg. grid. */ + extern Bool Hilite; /* Should we highlight borders on focus? */ extern Bool NWindow; /* Normalize windows? */ extern Bool NIcon; /* Normalize icons? */ extern Bool RootResizeBox; /* Should resize box obscure window? */ *************** *** 297,302 extern Bool Grid; /* Should the m/r box contain a 9 seg. grid. */ extern Bool NWindow; /* Normalize windows? */ extern Bool NIcon; /* Normalize icons? */ extern Bool Push; /* Relative=TRUE, Absolute=FALSE. */ extern Bool Reverse; /* Reverse video? */ extern Bool WarpOnRaise; /* Warp to upper right corner on raise. */ --- 314,320 ----- extern Bool Hilite; /* Should we highlight borders on focus? */ extern Bool NWindow; /* Normalize windows? */ extern Bool NIcon; /* Normalize icons? */ + extern Bool RootResizeBox; /* Should resize box obscure window? */ extern Bool Push; /* Relative=TRUE, Absolute=FALSE. */ extern Bool Reverse; /* Reverse video? */ extern Bool Titles; /* Title bars on windows? */ *************** *** 299,304 extern Bool NIcon; /* Normalize icons? */ extern Bool Push; /* Relative=TRUE, Absolute=FALSE. */ extern Bool Reverse; /* Reverse video? */ extern Bool WarpOnRaise; /* Warp to upper right corner on raise. */ extern Bool WarpOnIconify; /* Warp to icon center on iconify. */ extern Bool WarpOnDeIconify; /* Warp to upper right corner on de-iconify. */ --- 317,323 ----- extern Bool RootResizeBox; /* Should resize box obscure window? */ extern Bool Push; /* Relative=TRUE, Absolute=FALSE. */ extern Bool Reverse; /* Reverse video? */ + extern Bool Titles; /* Title bars on windows? */ extern Bool WarpOnRaise; /* Warp to upper right corner on raise. */ extern Bool WarpOnIconify; /* Warp to icon center on iconify. */ extern Bool WarpOnDeIconify; /* Warp to upper right corner on de-iconify. */ *************** *** 314,319 extern char IFontName[]; /* Icon font name. */ extern char PFontName[]; /* Pop-up font name. */ extern char MFontName[]; /* Menu font name. */ extern char **Argv; /* Pointer to command line parameters. */ extern char **Environ; /* Pointer to environment. */ --- 333,340 ----- extern char IFontName[]; /* Icon font name. */ extern char PFontName[]; /* Pop-up font name. */ extern char MFontName[]; /* Menu font name. */ + extern char TFontName[]; /* Title font name. */ + extern char TFontBoldName[]; /* Bold Title font name. */ extern char **Argv; /* Pointer to command line parameters. */ extern char **Environ; /* Pointer to environment. */ *************** *** 360,365 extern Bool ResetVariables(); extern Bool Resize(); extern Bool Restart(); extern int StoreCursors(); extern int StoreBox(); extern int StoreGridBox(); --- 381,389 ----- extern Bool ResetVariables(); extern Bool Resize(); extern Bool Restart(); + extern int FDestroyTitle(); + extern int FAddTitle(); + extern int DestroyWindow(); extern int StoreCursors(); extern int StoreBox(); extern int StoreGridBox(); *************** *** 367,372 extern int Error(); extern int XError(); extern int CreateMenus(); ! extern char *stash(); extern char *GetIconName(); --- 391,397 ----- extern int Error(); extern int XError(); extern int CreateMenus(); ! extern Window AddTitle(); ! extern TitleData *GetTitleInfo(); extern char *stash(); extern char *GetIconName(); *** uwm.new/uwm.man Mon Dec 7 00:59:43 1987 --- uwm.new/uwm.man Sat Dec 12 09:53:59 1987 *************** *** 68,74 out of the server during certain window manager tasks, such as move and resize. .IP \fBgrid\fP/\fBnogrid\fP ! displays a finely-ruled grid to help you position an icon or window during resize or move operations. .IP "\fBhiconpad\fP=\fIn\fP" indicates the number of pixels to pad an icon horizontally. --- 68,74 ----- out of the server during certain window manager tasks, such as move and resize. .IP \fBgrid\fP/\fBnogrid\fP ! displays a finely-ruled grid to help you position an icon or window during resize or move operations. .IP \fBtitle\fP/\fBnotitle\fP puts title bars on all windows. See also: f.title. *************** *** 70,75 .IP \fBgrid\fP/\fBnogrid\fP displays a finely-ruled grid to help you position an icon or window during resize or move operations. .IP "\fBhiconpad\fP=\fIn\fP" indicates the number of pixels to pad an icon horizontally. The default is five pixels. --- 70,85 ----- .IP \fBgrid\fP/\fBnogrid\fP displays a finely-ruled grid to help you position an icon or window during resize or move operations. + .IP \fBtitle\fP/\fBnotitle\fP + puts title bars on all windows. See also: f.title. + .IP \fBhilite\fP/\fBnohilite\fP + flips window borders between white and grey as they contain (and lose) the window focus. + Also changes title bar contents, if present. See also: titlefont, titlebold. + .IP \fBautoraise\fP/\fBnoautoraise\fP + raise windows on focus. See also: raisedelay. + .IP \fBrootresizebox\fB/\fBnorootresizebox\fP + place the resize box in the upper left corner of the RootWindow or in the resized window. This prevents + potentially expensive double exposures when set. .IP "\fBhiconpad\fP=\fIn\fP" indicates the number of pixels to pad an icon horizontally. The default is five pixels. *************** *** 76,81 .IP "\fBhmenupad\fP=\fIn\fP" indicates the amount of space in pixels, that each menu item is padded above and below the text. .IP "\fBiconfont\fP=\fIfontname\fP" names the font that is displayed within icons. Font names are listed in the font directory, \fI/usr/new/lib/X/font\fP. --- 86,101 ----- .IP "\fBhmenupad\fP=\fIn\fP" indicates the amount of space in pixels, that each menu item is padded above and below the text. + .IP "\fBraisedelay\fP=\fIn\fP" + wait \fIn\fP milliseconds after focus enters window before autoraising. This prevents + potentially annoying "raise loops". + .IP "\fBtitlefont\fP=\fIfontname\fP" + names the font that is displayed within titles. This is also the font displayed when focus + is out and hilite is set. See also: hilite + .IP "\fBtitlebold\fP\=\fIfontname\fP" + names the font that is displayed when focus is in and hiliting is set. This variable is meaningless + if hilighting is not on. If hilighting is on, and this font is not specified, then the \fBtitlefont\fP + is displayed in inverse video. .IP "\fBiconfont\fP=\fIfontname\fP" names the font that is displayed within icons. Font names are listed in the font directory, \fI/usr/new/lib/X/font\fP. *************** *** 220,225 causes the window manager application to restart, retracing the \fIuwm\fP search path and initializing the variables it finds. .PP .SH Control Keys .PP --- 240,254 ----- causes the window manager application to restart, retracing the \fIuwm\fP search path and initializing the variables it finds. + .IP \fBf.destroy\fP + calls XDestroyWindow on the selected window. Use with caution!! Binding it to + naked mouse buttons is probably not a good idea! + .IP \fBf.title\fP + puts a title bar on the selected window. Use the \fBtitle\fP variable to put titles + on all windows. This function is intended for those that don't want titles on everything, + just selected windows. + .IP \fBf.notitle\fP + removes a titlebar from the selected window. This does not effect the setting of \fBtitle\fP. .PP .SH Control Keys .PP *************** *** 245,251 cursor must be in that context or the function will not be activated. The window manager recognizes the following four contexts: ! icon, window, root, (null). .PP The root context refers to the root, or background window, A (null) context is indicated when the context field is left blank, --- 274,280 ----- cursor must be in that context or the function will not be activated. The window manager recognizes the following four contexts: ! icon, window, root, title, (null). .PP The root context refers to the root, or background window, A (null) context is indicated when the context field is left blank, *************** *** 250,255 The root context refers to the root, or background window, A (null) context is indicated when the context field is left blank, and allows a function to be invoked from any screen location. Combine contexts using the bar (|) character. .PP .SH Mouse Buttons --- 279,286 ----- The root context refers to the root, or background window, A (null) context is indicated when the context field is left blank, and allows a function to be invoked from any screen location. + The title context refers to the titlebar area of a window, if + one exists. Combine contexts using the bar (|) character. .PP .SH Mouse Buttons *************** *** 312,318 up arrow (^), which is stripped during the copy operation. .IP Strings without a new line must begin with the bar character (|), ! which is stripped during the copy operation. .PP .SH Color Menus .PP --- 343,351 ----- up arrow (^), which is stripped during the copy operation. .IP Strings without a new line must begin with the bar character (|), ! which is stripped during the copy operation. ! .IP "Booleans" ! Any boolean variable previously described. E.g., \fBnohilite\fP or \fBautoraise\fP. .PP .SH Color Menus .PP *************** *** 456,459 M. Gancarz, DEC Ultrix Engineering Group, Merrimack, New Hampshire, using some algorithms originally by Bob Scheifler, MIT Laboratory for Computer Science ! --- 489,496 ----- M. Gancarz, DEC Ultrix Engineering Group, Merrimack, New Hampshire, using some algorithms originally by Bob Scheifler, MIT Laboratory for Computer Science ! .PP ! J. Hubbard, ! Various modifications and enhancements of questionable value. No express or ! implied warrantee is given by the author, the University of California, Berkeley, ! Dana Computer Corp, or anyone else for that matter. You're on your own, Jack! //E*O*F uwm.patches.2// exit 0