[comp.windows.x] uwm patches. This is shar file 3 of 3

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