STDWIN 0.9.6 patches, part 4/5

Guido van Rossum guido at cwi.nl
Fri Jun 7 23:32:07 AEST 1991


Archive-name: stdwin0.9.6/patch4

*** 0.9.5/Ports/x11/event.c	Thu Oct 18 13:58:41 1990
--- stdwin/Ports/x11/event.c	Tue May 28 23:04:26 1991
***************
*** 98,106 ****
  	for (;;) {
  		if (_w_close_this != NULL) {
  			/* WM_DELETE_WINDOW detected */
! 			ep->type = WE_COMMAND;
  			ep->window = _w_close_this;
- 			ep->u.command = WC_CLOSE;
  			_w_close_this = NULL;
  			break;
  		}
--- 98,105 ----
  	for (;;) {
  		if (_w_close_this != NULL) {
  			/* WM_DELETE_WINDOW detected */
! 			ep->type = WE_CLOSE;
  			ep->window = _w_close_this;
  			_w_close_this = NULL;
  			break;
  		}
*** 0.9.5/Ports/x11/general.c	Thu Feb 28 10:42:43 1991
--- stdwin/Ports/x11/general.c	Mon Apr 15 22:36:37 1991
***************
*** 133,141 ****
--- 133,143 ----
  {"-iconmask",		".iconMask",		XrmoptionSepArg, NULL},
  
  {"-menubackground",	".menuBackground",	XrmoptionSepArg, NULL},
+ {"-menubg",		".menuBackground",	XrmoptionSepArg, NULL},
  {"-menufont",		".menuFont",		XrmoptionSepArg, NULL},
  {"-menufn",		".menuFont",		XrmoptionSepArg, NULL},
  {"-menuforeground",	".menuForeground",	XrmoptionSepArg, NULL},
+ {"-menufg",		".menuForeground",	XrmoptionSepArg, NULL},
  
  {"-reversevideo",	".reverse",		XrmoptionNoArg,  "on"},
  {"-rv",			".reverse",		XrmoptionNoArg,  "on"},
***************
*** 214,220 ****
--- 216,224 ----
  	
  	if ((value= getoption(db, "debugLevel", "DebugLevel")) != NULL) {
  		_wtracelevel= _wdebuglevel= atoi(value);
+ #ifndef SYSV
  		setlinebuf(stderr);
+ #endif
  		_wwarning("wargs: -debuglevel %d", _wdebuglevel, value);
  	}
  	
***************
*** 340,345 ****
--- 344,353 ----
  	/* Initialize font list */
  	
  	_winitfonts();
+ 
+ 	/* Initialize colors */
+ 
+ 	_w_initcolors();
  	
  #ifdef PIPEHACK
  	/* Create the pipe used to communicate wungetevent calls
***************
*** 482,488 ****
  	int def;
  {
  	register char *value;
! 	static struct flags {
  		char *name;
  		int value;
  	};
--- 490,496 ----
  	int def;
  {
  	register char *value;
! 	struct flags {
  		char *name;
  		int value;
  	};
*** 0.9.5/Ports/x11/llevent.c	Thu Oct 18 13:58:43 1990
--- stdwin/Ports/x11/llevent.c	Tue May 28 23:03:37 1991
***************
*** 276,282 ****
  			if (!isdclick)
  				_w_bs.clicks= 0;
  			++_w_bs.clicks;
! 			_w_bs.mask= e->state / Button1Mask; /* XXX */
  			_w_bs.button= e->button;
  			_w_bs.time= e->time;
  			_w_bs.win= win;
--- 276,282 ----
  			if (!isdclick)
  				_w_bs.clicks= 0;
  			++_w_bs.clicks;
! 			_w_bs.mask= e->state;
  			_w_bs.button= e->button;
  			_w_bs.time= e->time;
  			_w_bs.win= win;
***************
*** 312,318 ****
  			_w_bs_changed= TRUE;
  		}
  		else {
! 			_w_bs.mask= e->state / Button1Mask; /* XXX */
  			_w_bs.x= e->x;
  			_w_bs.y= e->y;
  			_w_bs.time= e->time;
--- 312,318 ----
  			_w_bs_changed= TRUE;
  		}
  		else {
! 			_w_bs.mask= e->state;
  			_w_bs.x= e->x;
  			_w_bs.y= e->y;
  			_w_bs.time= e->time;
*** 0.9.5/Ports/x11/menu.c	Thu Oct 18 13:58:44 1990
--- stdwin/Ports/x11/menu.c	Tue May 28 23:04:00 1991
***************
*** 224,230 ****
  	int i;
  	int x;
  	int y;
! 	
  	_wmenusetup();
  	x= titledist;
  	y= baseline - 1 + (win->mbar.height - lineheight) / 2;
--- 224,232 ----
  	int i;
  	int x;
  	int y;
! 
! 	if (win->mbar.wid == None)
! 		return;
  	_wmenusetup();
  	x= titledist;
  	y= baseline - 1 + (win->mbar.height - lineheight) / 2;
***************
*** 440,447 ****
  		XFlush(_wd); /* Show it right now */
  		if (it >= 0) {
  			if (mp->id == 0) {
! 				ep->type= WE_COMMAND;
! 				ep->u.command= WC_CLOSE;
  				ep->window= win;
  			}
  			else {
--- 442,448 ----
  		XFlush(_wd); /* Show it right now */
  		if (it >= 0) {
  			if (mp->id == 0) {
! 				ep->type= WE_CLOSE;
  				ep->window= win;
  			}
  			else {
*** 0.9.5/Ports/x11/scroll.c	Thu Oct 18 13:58:44 1990
--- stdwin/Ports/x11/scroll.c	Wed Apr  3 22:13:53 1991
***************
*** 22,27 ****
--- 22,29 ----
  _wdrawhbar(win)
  	WINDOW *win;
  {
+ 	if (win->hbar.wid == None)
+ 		return;
  	_wdebug(3, "draw hbar");
  	XClearWindow(_wd, win->hbar.wid);
  	if (win->doc.width > win->wi.width) {
***************
*** 38,43 ****
--- 40,47 ----
  _wdrawvbar(win)
  	WINDOW *win;
  {
+ 	if (win->vbar.wid == None)
+ 		return;
  	_wdebug(3, "draw vbar");
  	XClearWindow(_wd, win->vbar.wid);
  	if (win->doc.height > win->wi.height) {
*** 0.9.5/Ports/x11/selection.c	Sun Oct 21 13:02:31 1990
--- stdwin/Ports/x11/selection.c	Wed Apr  3 22:14:11 1991
***************
*** 22,27 ****
--- 22,31 ----
  #include "x11.h"
  #include "llevent.h" /* For _w_lasttime; */
  
+ #ifdef _IBMR2
+ #include <sys/select.h>
+ #endif
+ 
  
  #ifndef AMOEBA
  
*** 0.9.5/Ports/x11/window.c	Thu Feb 28 10:42:44 1991
--- stdwin/Ports/x11/window.c	Tue May 28 23:02:48 1991
***************
*** 14,22 ****
  #define TMARGIN		18
  #define RMARGIN		0
  #define BMARGIN		16
- #define IMARGIN		2
  
  
  /* Event masks */
  
  /* Mask for 'wo' */
--- 14,32 ----
  #define TMARGIN		18
  #define RMARGIN		0
  #define BMARGIN		16
  
+ #define IMARGIN		5	/* Extra left/right margin in inner window */
  
+ 
+ /* Size of outer window border */
+ 
+ #define OBORDER		2
+ 
+ 
+ /* XXX IMARGIN and OBORDER should be settable with properties and command
+    line options.  Maybe the other margins as well. */
+ 
+ 
  /* Event masks */
  
  /* Mask for 'wo' */
***************
*** 37,47 ****
  	
  /* Private globals */
  
! static int def_h, def_v;
! static int def_width, def_height;
  
! #define DEF_WIDTH (def_width > 0 ? def_width : 80*wcharwidth('n'))
! #define DEF_HEIGHT (def_height > 0 ? def_height : 22*wlineheight())
  
  
  /* WINDOW list.
--- 47,60 ----
  	
  /* Private globals */
  
! static int def_h = 0, def_v = 0;
! static int def_width = 0, def_height = 0;
! static int def_hbar = 0;
! static int def_vbar = 1;
! static int def_mbar = 1;
  
! #define DEF_WIDTH (def_width > 0 ? def_width : 40*wtextwidth("in", 2))
! #define DEF_HEIGHT (def_height > 0 ? def_height : 24*wlineheight())
  
  
  /* WINDOW list.
***************
*** 48,55 ****
     Each WINDOW must be registered here, so it can be found back
     by _whichwin */
  
! static WINDOW **winlist;
! static int nwins;
  
  
  /* Find a WINDOW pointer, given a Window.
--- 61,68 ----
     Each WINDOW must be registered here, so it can be found back
     by _whichwin */
  
! static WINDOW **winlist = 0;
! static int nwins = 0;
  
  
  /* Find a WINDOW pointer, given a Window.
***************
*** 62,71 ****
  {
  	register int i;
  	
! 	for (i= nwins; --i >= 0; ) {
! 		register WINDOW *win= winlist[i];
  		register int j;
! 		for (j= NSUBS; --j >= 0; ) {
  			if (w == win->subw[j].wid)
  				return win;
  		}
--- 75,84 ----
  {
  	register int i;
  	
! 	for (i = nwins; --i >= 0; ) {
! 		register WINDOW *win = winlist[i];
  		register int j;
! 		for (j = NSUBS; --j >= 0; ) {
  			if (w == win->subw[j].wid)
  				return win;
  		}
***************
*** 88,93 ****
--- 101,107 ----
  
  /* Set the max size of windows created later (ignored for now) */
  
+ /*ARGSUSED*/
  void
  wsetmaxwinsize(width, height)
  	int width, height;
***************
*** 101,120 ****
  wsetdefwinsize(width, height)
  	int width, height;
  {
! 	if (width <= 0)
! 		def_width= 0;
! 	else {
! 		CLIPMAX(width, WidthOfScreen(_ws) - 40 - LMARGIN - RMARGIN);
! 		CLIPMIN(width, 40);
! 		def_width= width;
! 	}
! 	if (height <= 0)
! 		def_height= 0;
! 	else {
! 		CLIPMAX(height, HeightOfScreen(_ws) - 40 - TMARGIN - BMARGIN);
! 		CLIPMIN(height, 40);
! 		def_height= height;
! 	}
  }
  
  void
--- 115,122 ----
  wsetdefwinsize(width, height)
  	int width, height;
  {
! 	def_width = width;
! 	def_height = height;
  }
  
  void
***************
*** 132,141 ****
  wsetdefwinpos(h, v)
  	int h, v;
  {
! 	CLIPMIN(h, 0);
! 	CLIPMIN(v, 0);
! 	def_h= h;
! 	def_v= v;
  }
  
  void
--- 134,141 ----
  wsetdefwinpos(h, v)
  	int h, v;
  {
! 	def_h = h;
! 	def_v = v;
  }
  
  void
***************
*** 147,152 ****
--- 147,171 ----
  }
  
  
+ /* Set the scroll bar options */
+ 
+ void
+ wsetdefscrollbars(need_hbar, need_vbar)
+ 	int need_hbar, need_vbar;
+ {
+ 	def_hbar = need_hbar;
+ 	def_vbar = need_vbar;
+ }
+ 
+ void
+ wgetdefscrollbars(phbar, pvbar)
+ 	int *phbar, *pvbar;
+ {
+ 	*phbar = def_hbar;
+ 	*pvbar = def_vbar;
+ }
+ 
+ 
  /* Read a Bitmap from a file and convert it to a Pixmap.
     XXX Actually I don't convert it to a Pixmap; this may mean that perhaps
     you won't be able to set an icon on a color display, depending
***************
*** 165,171 ****
  	unsigned int width, height;
  	int xhot, yhot;
  	Pixmap bitmap;
! 	int err= XReadBitmapFile(_wd, RootWindowOfScreen(_ws), filename,
  		&width, &height, &bitmap, &xhot, &yhot);
  	if (err != BitmapSuccess) {
  		_wwarning("can't read bitmap file %s, error code %d",
--- 184,190 ----
  	unsigned int width, height;
  	int xhot, yhot;
  	Pixmap bitmap;
! 	int err = XReadBitmapFile(_wd, RootWindowOfScreen(_ws), filename,
  		&width, &height, &bitmap, &xhot, &yhot);
  	if (err != BitmapSuccess) {
  		_wwarning("can't read bitmap file %s, error code %d",
***************
*** 176,181 ****
--- 195,204 ----
  }
  
  
+ /* Forward */
+ static bool _wmakesubwins _ARGS((WINDOW *win));
+ 
+ 
  /* Open a WINDOW.
     Some defaults should only be used for the first window opened,
     e.g., window geometry (otherwise all windows would overlay each other!)
***************
*** 189,206 ****
  	static bool used_defaults;
  	WINDOW *win;
  	XSizeHints sizehints;
  	
  	/* Allocate zeroed storage for the WINDOW structure
  	   and fill in the easy non-zero values */
! 	win= (WINDOW*) calloc(sizeof(WINDOW), 1);
  	if (win == NULL) {
  		_werror("wopen: can't alloc storage for window");
  		return NULL;
  	}
! 	win->drawproc= drawproc;
! 	win->careth= win->caretv= -1;
! 	win->attr= wattr;
! 	
  	/* Parse user-specified geometry default.
  	   This overrides what the application specified.
  	   Note that the x and y stored internally are exclusive or borders,
--- 212,253 ----
  	static bool used_defaults;
  	WINDOW *win;
  	XSizeHints sizehints;
+ 	char *geom;
  	
  	/* Allocate zeroed storage for the WINDOW structure
  	   and fill in the easy non-zero values */
! 	win = (WINDOW*) calloc(sizeof(WINDOW), 1);
  	if (win == NULL) {
  		_werror("wopen: can't alloc storage for window");
  		return NULL;
  	}
! 	win->drawproc = drawproc;
! 	win->careth = win->caretv = -1;
! 	win->attr = wattr;
! 	win->tmargin = def_mbar ? TMARGIN : 0;
! 	win->rmargin = RMARGIN;
! 	win->bmargin = def_hbar ? BMARGIN : 0;
! 	win->lmargin = def_vbar ? LMARGIN : 0;
! 
! 	sizehints.x = def_h <= 0 ? 0 : def_h - win->lmargin - OBORDER;
! 	sizehints.y = def_v <= 0 ? 0 : def_v - win->tmargin - OBORDER;
! 	sizehints.width = DEF_WIDTH + win->lmargin + win->rmargin
! 			 + 2*IMARGIN;
! 	sizehints.height = DEF_HEIGHT + win->tmargin + win->bmargin;
! 	sizehints.flags = PSize;
! 	if (def_h > 0 || def_v > 0)
! 		sizehints.flags |= PPosition | USPosition;
! 		/* USPosition added to fool twm */
! 
! #ifndef PRE_R4
! 	/* Set base size and resize increment */
! 	sizehints.base_width = win->lmargin + win->rmargin + 2*IMARGIN;
! 	sizehints.base_height = win->tmargin + win->bmargin;
! 	sizehints.width_inc = 1;
! 	sizehints.height_inc = 1;
! 	sizehints.flags |= PBaseSize | PResizeInc;
! #endif
! 
  	/* Parse user-specified geometry default.
  	   This overrides what the application specified.
  	   Note that the x and y stored internally are exclusive or borders,
***************
*** 207,314 ****
  	   while X geometries specify x and y including the border.
  	   XXX Also note that the obsolete sizehints members x, y, width and
  	   height are used later to actually create the window. */
! 	{
! 		char *geom;
! 		sizehints.x= def_h <= 0 ? 0 : def_h - 2*IBORDER;
! 		sizehints.y= def_v <= 0 ? 0 : def_v - 2*IBORDER;
! 		sizehints.width= DEF_WIDTH + LMARGIN + RMARGIN;
! 		sizehints.height= DEF_HEIGHT + TMARGIN + BMARGIN;
! 		sizehints.flags= PSize;
! 		if (def_h > 0 || def_v > 0)
! 			sizehints.flags |= PPosition | USPosition;
! 			/* USPosition added to fool twm */
! 		if (!used_defaults &&
! 			(geom= _wgetdefault("geometry", "Geometry")) != NULL){
! 			unsigned int width, height;
! 			int flags= XParseGeometry(geom,
! 				&sizehints.x, &sizehints.y, &width, &height);
! 			if (flags & WidthValue)
! 				sizehints.width = width;
! 			if (flags & HeightValue)
! 				sizehints.height = height;
! 			if (flags & XNegative)
! 				sizehints.x=
! 					WidthOfScreen(_ws) + sizehints.x
! 					- sizehints.width - 2*IBORDER;
! 			if (flags & YNegative)
! 				sizehints.y=
! 					HeightOfScreen(_ws) + sizehints.y
! 					- sizehints.height - 2*IBORDER;
! 			
! 			/* Use the user-specified size as the default
! 			   size for future windows */
! 			
! 			if (flags & WidthValue)
! 				def_width=
! 					sizehints.width - LMARGIN - RMARGIN;
! 			if (flags & HeightValue)
! 				def_height=
! 					sizehints.height - TMARGIN - BMARGIN;
! 			
! 			/* If the user has given as position,
! 			   pretend a size is also given, otherwise
! 			   UWM will still ask for interactive
! 			   window placement.  I'm in good company:
! 			   "the" Toolkit also does this. */
! 			
! 			if (flags & (XValue|YValue))
! 				sizehints.flags |= USPosition|USSize;
! 			else if (flags & (WidthValue|HeightValue))
! 				sizehints.flags |= USSize;
! 			
! #if 1
! 			/* XXX This doesn't compile in R3.
! 			   It's safe to take it out. */
! 			
! 			/* Derive the gravity hint from the geometry */
! 			
! 			if ((flags & XNegative) || (flags & YNegative)) {
! 				sizehints.flags |= PWinGravity;
! 				if (flags & XNegative) {
! 					if (flags & YNegative)
! 						sizehints.win_gravity =
! 							SouthEastGravity;
! 					else
! 						sizehints.win_gravity =
! 							NorthEastGravity;
! 				}
  				else
  					sizehints.win_gravity =
! 						SouthWestGravity;
  			}
! #endif			
! 			/* XXX Do we need a resource to specify the min
! 			   size (or base size), max size and size
! 			   increment?  Better to let the application
! 			   decide based upon the font used? */
  		}
  	}
  	
  	/* Set the initial geometry from the size hints just computed */
! 	win->wo.border= 2*IBORDER;
! 	win->wo.x= sizehints.x + win->wo.border;
! 	win->wo.y= sizehints.y + win->wo.border;
! 	win->wo.width= sizehints.width;
! 	win->wo.height= sizehints.height;
  	
  	/* Set the foreground and background pixel values */
! 	win->fga= _wgetpixel("foreground", "Foreground",
! 						BlackPixelOfScreen(_ws));
! 	win->bga= _wgetpixel("background", "Background",
! 						WhitePixelOfScreen(_ws));
! 	win->fgo= _wgetpixel("menuForeground", "Foreground", win->fga);
! 	win->bgo= _wgetpixel("menuBackground", "Background", win->bga);
  	
- 	/* Swap the pixel values if 'reverse' specified */
- 	if (_wgetbool("reverse", "Reverse", 0)) {
- 		unsigned long temp= win->fga;
- 		win->fga= win->bga;
- 		win->bga= temp;
- 		temp= win->fgo;
- 		win->fgo= win->bgo;
- 		win->bgo= temp;
- 	}
- 	
  	/* Create the outer Window */
  	if (!_wcreate(&win->wo, RootWindowOfScreen(_ws), 0, FALSE,
  		win->fgo, win->bgo)) {
--- 254,334 ----
  	   while X geometries specify x and y including the border.
  	   XXX Also note that the obsolete sizehints members x, y, width and
  	   height are used later to actually create the window. */
! 
! 	if (!used_defaults &&
! 		(geom = _wgetdefault("geometry", "Geometry")) != NULL) {
! 		unsigned int width, height;
! 
! 		int flags = XParseGeometry(geom,
! 			&sizehints.x, &sizehints.y, &width, &height);
! 		if (flags & WidthValue)
! 			sizehints.width = width
! 				+ win->lmargin + win->rmargin
! 				+ 2*IMARGIN;
! 		if (flags & HeightValue)
! 			sizehints.height = height
! 				+ win->tmargin + win->bmargin;
! 		if (flags & XNegative)
! 			sizehints.x =
! 				WidthOfScreen(_ws) + sizehints.x
! 				- sizehints.width - OBORDER;
! 		if (flags & YNegative)
! 			sizehints.y =
! 				HeightOfScreen(_ws) + sizehints.y
! 				- sizehints.height - OBORDER;
! 
! 		/* Use the user-specified size as the default
! 		   size for future windows */
! 
! 		if (flags & WidthValue)
! 			def_width = width;
! 		if (flags & HeightValue)
! 			def_height = height;
! 
! 		/* If the user has given as position,
! 		   pretend a size is also given, otherwise
! 		   UWM will still ask for interactive
! 		   window placement.  I'm in good company:
! 		   "the" Toolkit also does this. */
! 
! 		if (flags & (XValue|YValue))
! 			sizehints.flags |= USPosition|USSize;
! 		else if (flags & (WidthValue|HeightValue))
! 			sizehints.flags |= USSize;
! 
! #ifndef PRE_R4
! 		/* Derive the gravity hint from the geometry */
! 
! 		if ((flags & XNegative) || (flags & YNegative)) {
! 			sizehints.flags |= PWinGravity;
! 			if (flags & XNegative) {
! 				if (flags & YNegative)
! 					sizehints.win_gravity =
! 						SouthEastGravity;
  				else
  					sizehints.win_gravity =
! 						NorthEastGravity;
  			}
! 			else
! 				sizehints.win_gravity =
! 					SouthWestGravity;
  		}
+ #endif			
  	}
  	
  	/* Set the initial geometry from the size hints just computed */
! 	win->wo.border = OBORDER;
! 	win->wo.x = sizehints.x + win->wo.border;
! 	win->wo.y = sizehints.y + win->wo.border;
! 	win->wo.width = sizehints.width;
! 	win->wo.height = sizehints.height;
  	
  	/* Set the foreground and background pixel values */
! 	win->fga = _w_fgcolor;
! 	win->bga = _w_bgcolor;
! 	win->fgo = _wgetpixel("menuForeground", "MenuForeground", _w_fgcolor);
! 	win->bgo = _wgetpixel("menuBackground", "MenuBackground", _w_bgcolor);
  	
  	/* Create the outer Window */
  	if (!_wcreate(&win->wo, RootWindowOfScreen(_ws), 0, FALSE,
  		win->fgo, win->bgo)) {
***************
*** 323,337 ****
  	}
  	
  	/* Create the Graphics Contexts */
! 	win->gc= _wgcreate(win->wo.wid, _wmf->fid, win->fgo, win->bgo);
! 	win->gca= _wgcreate(win->wa.wid, _wf->fid, win->fga, win->bga);
! 	
  	/* Change selected Window properties */
  	_wsetmasks(win);
  	_w_setgrayborder(win);
  	
  	/* Set the "invalid" region to empty (rely on Expose events) */
! 	win->inval= XCreateRegion();
  	
  	/* Initialize the menu bar stuff */
  	_waddmenus(win);
--- 343,360 ----
  	}
  	
  	/* Create the Graphics Contexts */
! 	win->gc = _wgcreate(win->wo.wid, _wmf->fid, win->fgo, win->bgo);
! 	win->gca = _wgcreate(win->wa.wid, _wf->fid, win->fga, win->bga);
! 
! 	/* Set the plane mask so _winvert keeps working... */
! 	XSetPlaneMask(_wd, win->gc, win->fgo ^ win->bgo);
! 
  	/* Change selected Window properties */
  	_wsetmasks(win);
  	_w_setgrayborder(win);
  	
  	/* Set the "invalid" region to empty (rely on Expose events) */
! 	win->inval = XCreateRegion();
  	
  	/* Initialize the menu bar stuff */
  	_waddmenus(win);
***************
*** 367,397 ****
  		   of a given client has this property.  Later. */
  	
  	/* Set normal size hints (computed above) */
  	XSetNormalHints(_wd, win->wo.wid, &sizehints);
  	
  	/* Set WM Hints */
  	{
  		XWMHints wmhints;
  		char *value;
! 		wmhints.flags= InputHint | StateHint;
! 		wmhints.input= _wgetbool("input", "Input", 1);
  		if (!used_defaults &&
  			_wgetbool("iconic", "Iconic", 0))
! 			wmhints.initial_state= IconicState;
  		else
! 			wmhints.initial_state= NormalState;
! 		if (!used_defaults && (value=
  			_wgetdefault("iconGeometry", "IconGeometry"))
  				!= NULL) {
  			unsigned int width, height;
! 			int flags= XParseGeometry(value,
  				&wmhints.icon_x, &wmhints.icon_y,
  				&width, &height);
  			if (flags & XNegative)
! 				wmhints.icon_x=
  					WidthOfScreen(_ws) - wmhints.icon_x;
  			if (flags & YNegative)
! 				wmhints.icon_y=
  					HeightOfScreen(_ws) - wmhints.icon_y;
  			if (flags & (XValue|YValue)) {
  				wmhints.flags |= IconPositionHint;
--- 390,429 ----
  		   of a given client has this property.  Later. */
  	
  	/* Set normal size hints (computed above) */
+ #ifdef PRE_R4
  	XSetNormalHints(_wd, win->wo.wid, &sizehints);
+ #else
+ 	/* XSetNormalHints carefully masks away the base size and
+ 	   window gravity, so we must call XChangeProperty directly. */
+ 	/* XXX This is not correct on machines where int != long. Sigh. */
+ 	XChangeProperty(_wd, win->wo.wid,
+ 		XA_WM_NORMAL_HINTS, XA_WM_SIZE_HINTS, 32, PropModeReplace,
+ 		(unsigned char *) &sizehints, sizeof sizehints / 4);
+ #endif
  	
  	/* Set WM Hints */
  	{
  		XWMHints wmhints;
  		char *value;
! 		wmhints.flags = InputHint | StateHint;
! 		wmhints.input = _wgetbool("input", "Input", 1);
  		if (!used_defaults &&
  			_wgetbool("iconic", "Iconic", 0))
! 			wmhints.initial_state = IconicState;
  		else
! 			wmhints.initial_state = NormalState;
! 		if (!used_defaults && (value =
  			_wgetdefault("iconGeometry", "IconGeometry"))
  				!= NULL) {
  			unsigned int width, height;
! 			int flags = XParseGeometry(value,
  				&wmhints.icon_x, &wmhints.icon_y,
  				&width, &height);
  			if (flags & XNegative)
! 				wmhints.icon_x =
  					WidthOfScreen(_ws) - wmhints.icon_x;
  			if (flags & YNegative)
! 				wmhints.icon_y =
  					HeightOfScreen(_ws) - wmhints.icon_y;
  			if (flags & (XValue|YValue)) {
  				wmhints.flags |= IconPositionHint;
***************
*** 401,415 ****
  			else
  				_wdebug(1, "no icon pos");
  		}
! 		value= _wgetdefault("iconBitmap", "IconBitmap");
  		if (value != NULL)  {
! 			wmhints.icon_pixmap= readpixmap(value);
  			if (wmhints.icon_pixmap != None)
  				wmhints.flags |= IconPixmapHint;
  		}
! 		value= _wgetdefault("iconMask", "IconMask");
  		if (value != NULL)  {
! 			wmhints.icon_mask= readbitmap(value);
  			if (wmhints.icon_mask != None)
  				wmhints.flags |= IconMaskHint;
  		}
--- 433,447 ----
  			else
  				_wdebug(1, "no icon pos");
  		}
! 		value = _wgetdefault("iconBitmap", "IconBitmap");
  		if (value != NULL)  {
! 			wmhints.icon_pixmap = readpixmap(value);
  			if (wmhints.icon_pixmap != None)
  				wmhints.flags |= IconPixmapHint;
  		}
! 		value = _wgetdefault("iconMask", "IconMask");
  		if (value != NULL)  {
! 			wmhints.icon_mask = readbitmap(value);
  			if (wmhints.icon_mask != None)
  				wmhints.flags |= IconMaskHint;
  		}
***************
*** 420,427 ****
  	/* Set class (same as strings used by _wgetdefault() */
  	{
  		XClassHint classhint;
! 		classhint.res_name= _wprogname;
! 		classhint.res_class= "Stdwin";
  		XSetClassHint(_wd, win->wo.wid, &classhint);
  	}
  	
--- 452,459 ----
  	/* Set class (same as strings used by _wgetdefault() */
  	{
  		XClassHint classhint;
! 		classhint.res_name = _wprogname;
! 		classhint.res_class = "Stdwin";
  		XSetClassHint(_wd, win->wo.wid, &classhint);
  	}
  	
***************
*** 449,455 ****
  	XMapRaised(_wd, win->wo.wid);
  	
  	/* Note that we've used the once-only defaults */
! 	used_defaults= TRUE;
  	
  	/* Don't forget to return the WINDOW pointer */
  	return win;
--- 481,487 ----
  	XMapRaised(_wd, win->wo.wid);
  	
  	/* Note that we've used the once-only defaults */
! 	used_defaults = TRUE;
  	
  	/* Don't forget to return the WINDOW pointer */
  	return win;
***************
*** 471,476 ****
--- 503,518 ----
  }
  
  
+ /* Fetch a color, by name */
+ 
+ COLOR
+ wfetchcolor(cname)
+ 	char *cname;
+ {
+ 	return (COLOR) _w_fetchpixel(cname, BlackPixelOfScreen(_ws));
+ }
+ 
+ 
  /* Get a pixel value from the resource database */
  
  unsigned long
***************
*** 483,497 ****
  	Colormap cmap;
  	XColor hard, exact;
  	
! 	cname= _wgetdefault(resname, resclassname);
  	if (cname == NULL)
  		return defpixel;
! 	cmap= DefaultColormapOfScreen(_ws);
  	if (!XParseColor(_wd, cmap, cname, &exact)) {
  		_wwarning("%s: no such color", cname);
  		return defpixel;
  	}
! 	hard= exact;
  	if (!XAllocColor(_wd, cmap, &hard)) {
  		_wwarning("%s: can't allocate color cell", cname);
  		return defpixel;
--- 525,553 ----
  	Colormap cmap;
  	XColor hard, exact;
  	
! 	cname = _wgetdefault(resname, resclassname);
  	if (cname == NULL)
  		return defpixel;
! 	return _w_fetchpixel(cname, defpixel);
! }
! 
! 
! /* Translate a color name or #RGB spec into a pixel value */
! 
! unsigned long
! _w_fetchpixel(cname, defpixel)
! 	char *cname;
! 	unsigned long defpixel;
! {
! 	Colormap cmap;
! 	XColor hard, exact;
! 	
! 	cmap = DefaultColormapOfScreen(_ws);
  	if (!XParseColor(_wd, cmap, cname, &exact)) {
  		_wwarning("%s: no such color", cname);
  		return defpixel;
  	}
! 	hard = exact;
  	if (!XAllocColor(_wd, cmap, &hard)) {
  		_wwarning("%s: can't allocate color cell", cname);
  		return defpixel;
***************
*** 510,516 ****
  	static Pixmap gray;
  	
  	if (gray == 0) {
! 		gray= XCreatePixmapFromBitmapData(_wd,
  			RootWindowOfScreen(_ws),
  			gray_bits, gray_width, gray_height,
  			BlackPixelOfScreen(_ws),
--- 566,572 ----
  	static Pixmap gray;
  	
  	if (gray == 0) {
! 		gray = XCreatePixmapFromBitmapData(_wd,
  			RootWindowOfScreen(_ws),
  			gray_bits, gray_width, gray_height,
  			BlackPixelOfScreen(_ws),
***************
*** 532,545 ****
  }
  
  
! /* Create a Graphics Context using the given Window and Font ids.
!    Don't set the font if Font id is zero.
!    The plane mask is set to the XOR of the fg and bg colors;
!    if the window bg color is the same as the GC bg color,
!    this makes painting, erasing and XOR'ing possible
!    on color displays.  (On monochrome displays, one of the colors
!    is 1, one is 0, so the XOR is 1, which means all the planes we have.
! */
  
  GC
  _wgcreate(wid, fid, fg, bg)
--- 588,595 ----
  }
  
  
! /* Create a Graphics Context using the given Window and Font ids and colors.
!    Don't set the font if Font id is zero. */
  
  GC
  _wgcreate(wid, fid, fg, bg)
***************
*** 547,560 ****
  	Font fid;
  	unsigned long fg, bg;
  {
! 	int mask= GCForeground|GCBackground|GCPlaneMask;
  	XGCValues v;
  	
! 	v.plane_mask= fg ^ bg;
! 	v.foreground= fg;
! 	v.background= bg;
  	if (fid != 0) {
! 		v.font= fid;
  		mask |= GCFont;
  	}
  	return XCreateGC(_wd, wid, mask, &v);
--- 597,609 ----
  	Font fid;
  	unsigned long fg, bg;
  {
! 	int mask = GCForeground|GCBackground;
  	XGCValues v;
  	
! 	v.foreground = fg;
! 	v.background = bg;
  	if (fid != 0) {
! 		v.font = fid;
  		mask |= GCFont;
  	}
  	return XCreateGC(_wd, wid, mask, &v);
***************
*** 575,597 ****
  	bool nowm;
  {
  	XSetWindowAttributes attributes;
! 	unsigned long valuemask=
! 		CWBackPixel|CWBorderPixel|CWBitGravity|CWBackingStore;
! 	
! 	attributes.background_pixel= bg;
! 	attributes.border_pixel= fg;
! 	attributes.bit_gravity= NorthWestGravity;
  	if (nowm) {
  		attributes.override_redirect = 1;
  		valuemask |= CWOverrideRedirect;
  	}
! /*
! 	attributes.backing_store= WhenMapped;
! */
! 	attributes.backing_store= NotUseful; /* Seems to be Harmful... */
  
  	if (cursor > 0) {
! 		attributes.cursor= XCreateFontCursor(_wd, cursor);
  		valuemask |= CWCursor;
  	}
  	
--- 624,649 ----
  	bool nowm;
  {
  	XSetWindowAttributes attributes;
! 	unsigned long valuemask;
! 
! 	/* Don't create empty windows */
! 	if (wp->width == 0 || wp->height == 0) {
! 		wp->wid = None;
! 		return TRUE;
! 	}
! 
! 	valuemask = CWBackPixel|CWBorderPixel|CWBitGravity|CWBackingStore;
! 	attributes.background_pixel = bg;
! 	attributes.border_pixel = fg;
! 	attributes.bit_gravity = NorthWestGravity;
  	if (nowm) {
  		attributes.override_redirect = 1;
  		valuemask |= CWOverrideRedirect;
  	}
! 	attributes.backing_store = NotUseful; /* Seems to be Harmful... */
  
  	if (cursor > 0) {
! 		attributes.cursor = XCreateFontCursor(_wd, cursor);
  		valuemask |= CWCursor;
  	}
  	
***************
*** 599,605 ****
  	   passing them to WCreateSimpleWindow, since
  	   they refer to the upper left corner of the border! */
  	
! 	wp->wid= XCreateWindow(
  			_wd,
  			parent,
  			wp->x - wp->border,	/* x */
--- 651,657 ----
  	   passing them to WCreateSimpleWindow, since
  	   they refer to the upper left corner of the border! */
  	
! 	wp->wid = XCreateWindow(
  			_wd,
  			parent,
  			wp->x - wp->border,	/* x */
***************
*** 620,626 ****
  	_wdebug(2, "_wcreate: wid=0x%x", wp->wid);
  	if (map)
  		XMapWindow(_wd, wp->wid);
! 	wp->dirty= FALSE;
  	return TRUE;
  }
  
--- 672,678 ----
  	_wdebug(2, "_wcreate: wid=0x%x", wp->wid);
  	if (map)
  		XMapWindow(_wd, wp->wid);
! 	wp->dirty = FALSE;
  	return TRUE;
  }
  
***************
*** 634,639 ****
--- 686,694 ----
  {
  	static int saveUnder = -1;
  	XSetWindowAttributes attrs;
+ 
+ 	if (wp->wid == None)
+ 		return;
  	
  	/* The user may explicitly turn off save-unders by specifying
  		Stdwin*SaveUnder: off
***************
*** 649,655 ****
  	if (!saveUnder)
  		return;
  	
! 	attrs.save_under= flag;
  	XChangeWindowAttributes(_wd, wp->wid, CWSaveUnder, &attrs);
  }
  
--- 704,710 ----
  	if (!saveUnder)
  		return;
  	
! 	attrs.save_under = flag;
  	XChangeWindowAttributes(_wd, wp->wid, CWSaveUnder, &attrs);
  }
  
***************
*** 662,668 ****
  	int grav;
  {
  	XSetWindowAttributes attrs;
! 	attrs.win_gravity= grav;
  	XChangeWindowAttributes(_wd, wp->wid, CWWinGravity, &attrs);
  }
  
--- 717,725 ----
  	int grav;
  {
  	XSetWindowAttributes attrs;
! 	if (wp->wid == None)
! 		return;
! 	attrs.win_gravity = grav;
  	XChangeWindowAttributes(_wd, wp->wid, CWWinGravity, &attrs);
  }
  
***************
*** 673,678 ****
--- 730,737 ----
  _wmove(wp)
  	struct windata *wp;
  {
+ 	if (wp->wid == None)
+ 		return;
  	XMoveResizeWindow(_wd, wp->wid,
  	    wp->x - wp->border, wp->y - wp->border, wp->width, wp->height);
  }
***************
*** 679,685 ****
  
  
  /* (Re)compute the sizes and positions of all subwindows.
-    If aflag is set, the application subwindow is resized as well.
     Note a check (in SZ) to prevent windows ever to get a size <= 0 */
  
  static
--- 738,743 ----
***************
*** 686,712 ****
  _wsizesubwins(win)
  	WINDOW *win;
  {
! 	int bmargin= win->wi.height - win->doc.height - win->wa.y;
! 	int rmargin= win->wi.width - win->doc.width - win->wa.x;
  
  #define SZ(elem, nx, ny, nw, nh, nb) \
! 		(win->elem.x= (nx), \
! 		win->elem.y= (ny), \
! 		win->elem.width= (nw) > 0 ? (nw) : 1, \
! 		win->elem.height= (nh) > 0 ? (nh) : 1, \
! 		win->elem.border= (nb))
  
  	/* Interior window in the middle */
! 	SZ(wi, LMARGIN, TMARGIN,
! 		win->wo.width - LMARGIN - RMARGIN,
! 		win->wo.height - TMARGIN - BMARGIN, 0);
  	/* Menu bar at the top */
! 	SZ(mbar, 0, 0, win->wo.width, TMARGIN - IBORDER, IBORDER);
  	/* Vbar left */
! 	SZ(vbar, 0, win->wi.y, LMARGIN - IBORDER, win->wi.height, IBORDER);
! 	/* Hbar at bottom (top would be ugly because of mbar) */
! 	SZ(hbar, win->wi.x, win->wo.height - BMARGIN + IBORDER,
! 		win->wi.width, BMARGIN - IBORDER, IBORDER);
  
  #undef SZ
  	
--- 744,780 ----
  _wsizesubwins(win)
  	WINDOW *win;
  {
! 	int bmargin = win->wi.height - win->doc.height - win->wa.y;
! 	int rmargin = win->wi.width - IMARGIN - win->doc.width - win->wa.x;
  
  #define SZ(elem, nx, ny, nw, nh, nb) \
! 		(win->elem.x = (nx), \
! 		win->elem.y = (ny), \
! 		win->elem.width = (nw) > 0 ? (nw) : 1, \
! 		win->elem.height = (nh) > 0 ? (nh) : 1, \
! 		win->elem.border = (nb))
  
  	/* Interior window in the middle */
! 	SZ(wi, win->lmargin, win->tmargin,
! 		win->wo.width - win->lmargin - win->rmargin,
! 		win->wo.height - win->tmargin - win->bmargin, 0);
  	/* Menu bar at the top */
! 	if (win->tmargin)
! 		SZ(mbar, 0, 0, win->wo.width, win->tmargin - IBORDER, IBORDER);
! 	else
! 		SZ(mbar, 0, 0, 0, 0, 0);
  	/* Vbar left */
! 	if (win->lmargin)
! 		SZ(vbar, 0, win->wi.y, win->lmargin - IBORDER,
! 		   win->wi.height, IBORDER);
! 	else
! 		SZ(vbar, 0, 0, 0, 0, 0);
! 	/* Hbar at the bottom */
! 	if (win->bmargin)
! 		SZ(hbar, win->wi.x, win->wo.height - win->bmargin + IBORDER,
! 		   win->wi.width, win->bmargin - IBORDER, IBORDER);
! 	else
! 		SZ(hbar, 0, 0, 0, 0, 0);
  
  #undef SZ
  	
***************
*** 716,743 ****
  	   Otherwise, it is moved so that the window never shows more
  	   outside it than before (if at all possible). */
  	
! 	if (win->doc.width <= win->wi.width) {
! 		win->wa.x= IMARGIN;
! 		win->wa.width= win->wi.width;
  	}
  	else {
  		CLIPMIN(rmargin, IMARGIN);
  		CLIPMIN(win->wa.x, win->wi.width - win->wa.width - rmargin);
  		CLIPMAX(win->wa.x, IMARGIN);
! 		win->wa.width= win->doc.width;
  		CLIPMIN(win->wa.width, win->wi.width - win->wa.x);
  	}
  	if (win->doc.height <= win->wi.height) {
! 		win->wa.y= 0;
! 		win->wa.height= win->wi.height;
  	}
  	else {
  		CLIPMIN(bmargin, 0);
  		CLIPMIN(win->wa.y, win->wi.height - win->wa.height - bmargin);
  		CLIPMAX(win->wa.y, 0);
! 		win->wa.height= win->doc.height;
  		CLIPMIN(win->wa.height, win->wi.height - win->wa.y);
  	}
  }
  
  
--- 784,812 ----
  	   Otherwise, it is moved so that the window never shows more
  	   outside it than before (if at all possible). */
  	
! 	if (win->doc.width <= win->wi.width - 2*IMARGIN) {
! 		win->wa.x = IMARGIN;
! 		win->wa.width = win->wi.width - 2*IMARGIN;
  	}
  	else {
  		CLIPMIN(rmargin, IMARGIN);
  		CLIPMIN(win->wa.x, win->wi.width - win->wa.width - rmargin);
  		CLIPMAX(win->wa.x, IMARGIN);
! 		win->wa.width = win->doc.width;
  		CLIPMIN(win->wa.width, win->wi.width - win->wa.x);
  	}
  	if (win->doc.height <= win->wi.height) {
! 		win->wa.y = 0;
! 		win->wa.height = win->wi.height;
  	}
  	else {
  		CLIPMIN(bmargin, 0);
  		CLIPMIN(win->wa.y, win->wi.height - win->wa.height - bmargin);
  		CLIPMAX(win->wa.y, 0);
! 		win->wa.height = win->doc.height;
  		CLIPMIN(win->wa.height, win->wi.height - win->wa.y);
  	}
+ 	win->wa.border = IMARGIN;
  }
  
  
***************
*** 750,757 ****
  _wmakesubwins(win)
  	WINDOW *win;
  {
! 	Window w= win->wo.wid;
! 	unsigned long fg= win->fgo, bg= win->bgo;
  	
  	_wsizesubwins(win);
  	if (!(	_wcreate(&win->mbar, w, XC_arrow, TRUE, fg, bg) &&
--- 819,826 ----
  _wmakesubwins(win)
  	WINDOW *win;
  {
! 	Window w = win->wo.wid;
! 	unsigned long fg = win->fgo, bg = win->bgo;
  	
  	_wsizesubwins(win);
  	if (!(	_wcreate(&win->mbar, w, XC_arrow, TRUE, fg, bg) &&
***************
*** 759,765 ****
  		_wcreate(&win->hbar, w, XC_sb_h_double_arrow, TRUE, fg, bg) &&
  		_wcreate(&win->wi, w, 0, TRUE, fg, bg) &&
  		_wcreate(&win->wa, win->wi.wid, XC_crosshair, TRUE,
! 			fg, win->bga)))
  		return FALSE;
  	_wgravity(&win->hbar, SouthWestGravity);
  	return TRUE;
--- 828,834 ----
  		_wcreate(&win->hbar, w, XC_sb_h_double_arrow, TRUE, fg, bg) &&
  		_wcreate(&win->wi, w, 0, TRUE, fg, bg) &&
  		_wcreate(&win->wa, win->wi.wid, XC_crosshair, TRUE,
! 			win->bga, win->bga)))
  		return FALSE;
  	_wgravity(&win->hbar, SouthWestGravity);
  	return TRUE;
***************
*** 778,788 ****
  	int i;
  	_wsizesubwins(win);
  	
! 	for (i= 1; i <= WA; ++i)
  		_wmove(&win->subw[i]);
  	
  	/* Invalidate scroll bars after a resize */
! 	win->hbar.dirty= win->vbar.dirty= _w_dirty= TRUE;
  }
  
  
--- 847,857 ----
  	int i;
  	_wsizesubwins(win);
  	
! 	for (i = 1; i <= WA; ++i)
  		_wmove(&win->subw[i]);
  	
  	/* Invalidate scroll bars after a resize */
! 	win->hbar.dirty = win->vbar.dirty = _w_dirty = TRUE;
  }
  
  
***************
*** 795,801 ****
  	int i;
  	
  	XSelectInput(_wd, win->wo.wid, OUTER_MASK);
! 	for (i= 1; i <= WA; ++i) {
  		if (win->subw[i].wid != 0)
  			XSelectInput(_wd, win->subw[i].wid,
  				(i == WI) ? NoEventMask : OTHER_MASK);
--- 864,870 ----
  	int i;
  	
  	XSelectInput(_wd, win->wo.wid, OUTER_MASK);
! 	for (i = 1; i <= WA; ++i) {
  		if (win->subw[i].wid != 0)
  			XSelectInput(_wd, win->subw[i].wid,
  				(i == WI) ? NoEventMask : OTHER_MASK);
***************
*** 811,832 ****
  {
  	int i;
  
! 	for (i= nwins; --i >= 0; ) {
! 		WINDOW *win= winlist[i];
  		if (win->resized) {
! 			win->resized= FALSE;
! 			ep->type= WE_SIZE;
! 			ep->window= win;
  			if (i == 0)
! 				_w_resized= FALSE;
  			return TRUE;
  		}
  	}
! 	_w_resized= FALSE;
  	return FALSE;
  }
  
  
  /* Perform any pending window updates.
     If the application subwindow needs an update,
     either call its draw procedure or generate a WE_DRAW event
--- 880,905 ----
  {
  	int i;
  
! 	for (i = nwins; --i >= 0; ) {
! 		WINDOW *win = winlist[i];
  		if (win->resized) {
! 			win->resized = FALSE;
! 			ep->type = WE_SIZE;
! 			ep->window = win;
  			if (i == 0)
! 				_w_resized = FALSE;
  			return TRUE;
  		}
  	}
! 	_w_resized = FALSE;
  	return FALSE;
  }
  
  
+ /* Forward */
+ static bool update _ARGS((WINDOW *win, EVENT *ep));
+ 
+ 
  /* Perform any pending window updates.
     If the application subwindow needs an update,
     either call its draw procedure or generate a WE_DRAW event
***************
*** 839,852 ****
  {
  	int i;
  
! 	for (i= nwins; --i >= 0; ) {
  		if (update(winlist[i], ep)) {
  			if (i == 0)
! 				_w_dirty= FALSE;
  			return TRUE;
  		}
  	}
! 	_w_dirty= FALSE;
  	return FALSE;
  }
  
--- 912,925 ----
  {
  	int i;
  
! 	for (i = nwins; --i >= 0; ) {
  		if (update(winlist[i], ep)) {
  			if (i == 0)
! 				_w_dirty = FALSE;
  			return TRUE;
  		}
  	}
! 	_w_dirty = FALSE;
  	return FALSE;
  }
  
***************
*** 867,873 ****
  	WINDOW *win;
  	EVENT *ep;
  {
! 	bool ret= FALSE;
  	
  	if (win->mbar.dirty)
  		_wdrawmbar(win);
--- 940,946 ----
  	WINDOW *win;
  	EVENT *ep;
  {
! 	bool ret = FALSE;
  	
  	if (win->mbar.dirty)
  		_wdrawmbar(win);
***************
*** 875,881 ****
  		_wdrawhbar(win);
  	if (win->vbar.dirty)
  		_wdrawvbar(win);
! 	win->mbar.dirty= win->hbar.dirty= win->vbar.dirty= FALSE;
  	/* wi and wo have nothing that can be drawn! */
  	
  	if (win->wa.dirty && (win->drawproc != NULL || ep != NULL)) {
--- 948,954 ----
  		_wdrawhbar(win);
  	if (win->vbar.dirty)
  		_wdrawvbar(win);
! 	win->mbar.dirty = win->hbar.dirty = win->vbar.dirty = FALSE;
  	/* wi and wo have nothing that can be drawn! */
  	
  	if (win->wa.dirty && (win->drawproc != NULL || ep != NULL)) {
***************
*** 882,891 ****
  		XRectangle clip;
  		int left, top, right, bottom;
  		XClipBox(win->inval, &clip);
! 		left= clip.x;
! 		top= clip.y;
! 		right= left + clip.width;
! 		bottom= top + clip.height;
  		CLIPMIN(left, -win->wa.x);
  		CLIPMIN(top, -win->wa.y);
  		CLIPMAX(right, win->wi.width - win->wa.x);
--- 955,964 ----
  		XRectangle clip;
  		int left, top, right, bottom;
  		XClipBox(win->inval, &clip);
! 		left = clip.x;
! 		top = clip.y;
! 		right = left + clip.width;
! 		bottom = top + clip.height;
  		CLIPMIN(left, -win->wa.x);
  		CLIPMIN(top, -win->wa.y);
  		CLIPMAX(right, win->wi.width - win->wa.x);
***************
*** 897,903 ****
  			if (win->drawproc != NULL) {
  				/* A bug in X11R2 XSetRegion prevents this
  				   from working: */
! #ifndef R2
  				/* Version for R3 or later */
  				XSetRegion(_wd, win->gca, win->inval);
  #else
--- 970,976 ----
  			if (win->drawproc != NULL) {
  				/* A bug in X11R2 XSetRegion prevents this
  				   from working: */
! #ifndef PRE_R3
  				/* Version for R3 or later */
  				XSetRegion(_wd, win->gca, win->inval);
  #else
***************
*** 916,934 ****
  				XClearArea(_wd, win->wa.wid,
  					clip.x, clip.y,
  					clip.width, clip.height, FALSE);
! 				ep->type= WE_DRAW;
! 				ep->window= win;
! 				ep->u.area.left= left;
! 				ep->u.area.top= top;
! 				ep->u.area.right= right;
! 				ep->u.area.bottom= bottom;
! 				ret= TRUE;
  			}
  			_wshowcaret(win);
  		}
  		XDestroyRegion(win->inval);
! 		win->inval= XCreateRegion();
! 		win->wa.dirty= FALSE;
  	}
  	return ret;
  }
--- 989,1007 ----
  				XClearArea(_wd, win->wa.wid,
  					clip.x, clip.y,
  					clip.width, clip.height, FALSE);
! 				ep->type = WE_DRAW;
! 				ep->window = win;
! 				ep->u.area.left = left;
! 				ep->u.area.top = top;
! 				ep->u.area.right = right;
! 				ep->u.area.bottom = bottom;
! 				ret = TRUE;
  			}
  			_wshowcaret(win);
  		}
  		XDestroyRegion(win->inval);
! 		win->inval = XCreateRegion();
! 		win->wa.dirty = FALSE;
  	}
  	return ret;
  }
***************
*** 941,947 ****
  	WINDOW *win;
  {
  	int i;
! 	for (i= 0; i < nwins; ++i) {
  		if (winlist[i] == win)
  			break;
  	}
--- 1014,1020 ----
  	WINDOW *win;
  {
  	int i;
! 	for (i = 0; i < nwins; ++i) {
  		if (winlist[i] == win)
  			break;
  	}
***************
*** 968,973 ****
--- 1041,1047 ----
  	char *title;
  {
  	XStoreName(_wd, win->wo.wid, title);
+ 	XFlush(_wd); /* Make the effect immediate */
  	/* The icon name will not change */
  }
  
***************
*** 1026,1033 ****
  	WINDOW *win;
  	int *pwidth, *pheight;
  {
! 	*pwidth= win->wi.width - IMARGIN;
! 	*pheight= win->wi.height;
  }
  
  
--- 1100,1107 ----
  	WINDOW *win;
  	int *pwidth, *pheight;
  {
! 	*pwidth = win->wi.width - 2*IMARGIN;
! 	*pheight = win->wi.height;
  }
  
  
***************
*** 1041,1049 ****
  	Window child;
  	
  	if (!XTranslateCoordinates(	_wd,
! 					win->wo.wid,
  					RootWindowOfScreen(_ws),
! 					0, 0,
  					ph, pv,
  					&child)) {
  		
--- 1115,1123 ----
  	Window child;
  	
  	if (!XTranslateCoordinates(	_wd,
! 					win->wi.wid,
  					RootWindowOfScreen(_ws),
! 					IMARGIN, 0,
  					ph, pv,
  					&child)) {
  		
***************
*** 1064,1076 ****
  	_wdebug(3, "wchange: %d %d %d %d", left, top, right, bottom);
  	if (left < right && top < bottom) {
  		XRectangle r;
! 		r.x= left;
! 		r.y= top;
! 		r.width= right - left;
! 		r.height= bottom - top;
  		XUnionRectWithRegion(&r, win->inval, win->inval);
! 		win->wa.dirty= TRUE;
! 		_w_dirty= TRUE;
  	}
  }
  
--- 1138,1150 ----
  	_wdebug(3, "wchange: %d %d %d %d", left, top, right, bottom);
  	if (left < right && top < bottom) {
  		XRectangle r;
! 		r.x = left;
! 		r.y = top;
! 		r.width = right - left;
! 		r.height = bottom - top;
  		XUnionRectWithRegion(&r, win->inval, win->inval);
! 		win->wa.dirty = TRUE;
! 		_w_dirty = TRUE;
  	}
  }
  
***************
*** 1085,1096 ****
  	int left, top, right, bottom;
  	int dh, dv;
  {
! 	int src_x= left, src_y= top;
! 	int dest_x= left, dest_y= top;
! 	int width= right - left - ABS(dh);
! 	int height= bottom - top - ABS(dv);
  	
! 	if (dh == 0 && dv == 0)
  		return;
  	
  	if (dh < 0)
--- 1159,1170 ----
  	int left, top, right, bottom;
  	int dh, dv;
  {
! 	int src_x = left, src_y = top;
! 	int dest_x = left, dest_y = top;
! 	int width = right - left - ABS(dh);
! 	int height = bottom - top - ABS(dv);
  	
! 	if (dh == 0 && dv == 0 || left >= right || top >= bottom)
  		return;
  	
  	if (dh < 0)
***************
*** 1104,1113 ****
  	
  	_wdebug(2, "wscroll: src(%d,%d)size(%d,%d)dest(%d,%d)",
  		src_x, src_y, width, height, dest_x, dest_y);
! 	_whidecaret(win);
! 	XCopyArea(_wd, win->wa.wid, win->wa.wid, win->gca,
! 		src_x, src_y, width, height, dest_x, dest_y);
! 	_wshowcaret(win);
  	
  	if (XRectInRegion(win->inval, left, top, right-left, bottom-top)
  							!= RectangleOut) {
--- 1178,1189 ----
  	
  	_wdebug(2, "wscroll: src(%d,%d)size(%d,%d)dest(%d,%d)",
  		src_x, src_y, width, height, dest_x, dest_y);
! 	if (width > 0 && height > 0) {
! 		_whidecaret(win);
! 		XCopyArea(_wd, win->wa.wid, win->wa.wid, win->gca,
! 			  src_x, src_y, width, height, dest_x, dest_y);
! 		_wshowcaret(win);
! 	}
  	
  	if (XRectInRegion(win->inval, left, top, right-left, bottom-top)
  							!= RectangleOut) {
***************
*** 1166,1185 ****
  	WINDOW *win;
  	int orgh, orgv;
  {
! 	bool moveit= FALSE;
  	
  	CLIPMIN(orgh, 0);
  	CLIPMIN(orgv, 0);
! 	if (win->wa.x != -orgh) {
! 		win->hbar.dirty= moveit= TRUE;
! 		win->wa.x= -orgh;
  	}
  	if (win->wa.y != -orgv) {
! 		win->vbar.dirty= moveit= TRUE;
! 		win->wa.y= -orgv;
  	}
  	if (moveit)
! 		XMoveWindow(_wd, win->wa.wid, -orgh, -orgv);
  }
  
  
--- 1242,1263 ----
  	WINDOW *win;
  	int orgh, orgv;
  {
! 	bool moveit = FALSE;
  	
  	CLIPMIN(orgh, 0);
  	CLIPMIN(orgv, 0);
! 	if (win->wa.x != IMARGIN - orgh) {
! 		win->hbar.dirty = moveit = TRUE;
! 		win->wa.x = IMARGIN - orgh;
  	}
  	if (win->wa.y != -orgv) {
! 		win->vbar.dirty = moveit = TRUE;
! 		win->wa.y = -orgv;
  	}
  	if (moveit)
! 		XMoveWindow(_wd, win->wa.wid,
! 			    IMARGIN - orgh - win->wa.border,
! 			    -orgv - win->wa.border);
  }
  
  
***************
*** 1190,1198 ****
  	WINDOW *win;
  	int *ph, *pv;
  {
! 	*ph= -win->wa.x;
! 	CLIPMIN(*ph, 0);
! 	*pv= -win->wa.y;
  }
  
  
--- 1268,1275 ----
  	WINDOW *win;
  	int *ph, *pv;
  {
! 	*ph = IMARGIN - win->wa.x;
! 	*pv = -win->wa.y;
  }
  
  
***************
*** 1203,1237 ****
  	WINDOW *win;
  	int width, height;
  {
! 	bool dirty= FALSE;
  	
  	CLIPMIN(width, 0);
  	CLIPMIN(height, 0);
  	if (win->doc.width != width) {
! 		win->doc.width= width;
  		if (width <= win->wo.width - IMARGIN) {
! 			win->wa.x= IMARGIN;
! 			win->wa.width= win->wi.width;
  		}
  		else {
! 			win->wa.width= width;
  			CLIPMIN(win->wa.width, win->wi.width - win->wa.x);
  		}
! 		win->hbar.dirty= dirty= TRUE;
  	}
  	if (win->doc.height != height) {
! 		win->doc.height= height;
  		if (height <= win->wo.height) {
! 			win->wa.y= 0;
! 			win->wa.height= win->wi.height;
  		}
  		else {
! 			win->wa.height= height;
  		}
! 		win->vbar.dirty= dirty= TRUE;
  	}
  	if (dirty) {
! 		_w_dirty= TRUE;
  		_wmove(&win->wa);
  	}
  }
--- 1280,1314 ----
  	WINDOW *win;
  	int width, height;
  {
! 	bool dirty = FALSE;
  	
  	CLIPMIN(width, 0);
  	CLIPMIN(height, 0);
  	if (win->doc.width != width) {
! 		win->doc.width = width;
  		if (width <= win->wo.width - IMARGIN) {
! 			win->wa.x = IMARGIN;
! 			win->wa.width = win->wi.width;
  		}
  		else {
! 			win->wa.width = width;
  			CLIPMIN(win->wa.width, win->wi.width - win->wa.x);
  		}
! 		win->hbar.dirty = dirty = TRUE;
  	}
  	if (win->doc.height != height) {
! 		win->doc.height = height;
  		if (height <= win->wo.height) {
! 			win->wa.y = 0;
! 			win->wa.height = win->wi.height;
  		}
  		else {
! 			win->wa.height = height;
  		}
! 		win->vbar.dirty = dirty = TRUE;
  	}
  	if (dirty) {
! 		_w_dirty = TRUE;
  		_wmove(&win->wa);
  	}
  }
***************
*** 1261,1267 ****
  		c = None;
  	else
  		c = (Cursor) cursor;
! 	XDefineCursor(_wd, win->wa.wid, c);
  }
  
  
--- 1338,1344 ----
  		c = None;
  	else
  		c = (Cursor) cursor;
! 	XDefineCursor(_wd, win->wi.wid, c);
  }
  
  
***************
*** 1273,1285 ****
  	WINDOW *win;
  	int left, top, right, bottom;
  {
! 	int orgh= -win->wa.x;
! 	int orgv= -win->wa.y;
  	int winwidth, winheight;
  	int extrah, extrav;
  	
  	_wdebug(3, "wshow: %d %d %d %d", left, top, right, bottom);
! 	
  	wgetwinsize(win, &winwidth, &winheight);
  	
  	if (left >= orgh &&
--- 1350,1362 ----
  	WINDOW *win;
  	int left, top, right, bottom;
  {
! 	int orgh, orgv;
  	int winwidth, winheight;
  	int extrah, extrav;
  	
  	_wdebug(3, "wshow: %d %d %d %d", left, top, right, bottom);
! 
! 	wgetorigin(win, &orgh, &orgv);
  	wgetwinsize(win, &winwidth, &winheight);
  	
  	if (left >= orgh &&
***************
*** 1288,1304 ****
  		bottom <= orgv + winheight)
  		return; /* Already visible */
  	
! 	extrah= (winwidth - (right - left)) / 2;
  	CLIPMAX(extrah, win->doc.width - right);
  	CLIPMIN(extrah, 0);
! 	orgh= right + extrah - winwidth;
  	CLIPMAX(orgh, left);
  	CLIPMIN(orgv, 0);
  	
! 	extrav= (winheight - (bottom - top)) / 2;
  	CLIPMAX(extrav, win->doc.height - bottom);
  	CLIPMIN(extrav, 0);
! 	orgv= bottom + extrav - winheight;
  	CLIPMAX(orgv, top);
  	CLIPMIN(orgv, 0);
  	
--- 1365,1381 ----
  		bottom <= orgv + winheight)
  		return; /* Already visible */
  	
! 	extrah = (winwidth - (right - left)) / 2;
  	CLIPMAX(extrah, win->doc.width - right);
  	CLIPMIN(extrah, 0);
! 	orgh = right + extrah - winwidth;
  	CLIPMAX(orgh, left);
  	CLIPMIN(orgv, 0);
  	
! 	extrav = (winheight - (bottom - top)) / 2;
  	CLIPMAX(extrav, win->doc.height - bottom);
  	CLIPMIN(extrav, 0);
! 	orgv = bottom + extrav - winheight;
  	CLIPMAX(orgv, top);
  	CLIPMIN(orgv, 0);
  	
***************
*** 1322,1328 ****
  {
  	int i;
  	
! 	for (i= nwins; --i >= 0; )
  		wmenuattach(winlist[i], mp);
  }
  
--- 1399,1405 ----
  {
  	int i;
  	
! 	for (i = nwins; --i >= 0; )
  		wmenuattach(winlist[i], mp);
  }
  
***************
*** 1332,1338 ****
  {
  	int i;
  	
! 	for (i= nwins; --i >= 0; )
  		wmenudetach(winlist[i], mp);
  }
  
--- 1409,1415 ----
  {
  	int i;
  	
! 	for (i = nwins; --i >= 0; )
  		wmenudetach(winlist[i], mp);
  }
  
***************
*** 1343,1356 ****
  _wnexttimer()
  {
  	int i;
! 	WINDOW *cand= NULL;
  	
! 	for (i= nwins; --i >= 0; ) {
! 		WINDOW *win= winlist[i];
! 		long t= win->timer;
  		if (t != 0) {
  			if (cand == NULL || t < cand->timer)
! 				cand= win;
  		}
  	}
  	return cand;
--- 1420,1433 ----
  _wnexttimer()
  {
  	int i;
! 	WINDOW *cand = NULL;
  	
! 	for (i = nwins; --i >= 0; ) {
! 		WINDOW *win = winlist[i];
! 		long t = win->timer;
  		if (t != 0) {
  			if (cand == NULL || t < cand->timer)
! 				cand = win;
  		}
  	}
  	return cand;
*** 0.9.5/Ports/x11/x11.h	Sun Oct 21 13:02:55 1990
--- stdwin/Ports/x11/x11.h	Wed Apr  3 22:16:01 1991
***************
*** 75,80 ****
--- 75,83 ----
  	int curitem;
  	
  	tbool resized;		/* True if WE_SIZE event pending */
+ 
+ 	/* Margins around inner window */
+ 	int lmargin, tmargin, rmargin, bmargin;
  }; /* == WINDOW from <stdwin.h> */
  
  /* Shorthands for subwindow array access.
***************
*** 118,123 ****
--- 121,128 ----
  extern char *_wprogname;	/* general.c */
  extern int _wdebuglevel;	/* errors.c */
  extern int _wtracelevel;	/* errors.c */
+ extern COLOR _w_fgcolor;	/* draw.c */
+ extern COLOR _w_bgcolor;	/* draw.c */
  
  /* Interned atoms */
  extern Atom _wm_protocols;
***************
*** 135,140 ****
--- 140,146 ----
  WINDOW *_wnexttimer();		/* window.c */
  GC _wgcreate();			/* window.c */
  unsigned long _wgetpixel();	/* window.c */
+ unsigned long _w_fetchpixel();	/* window.c */
  WINDOW *_w_get_last_active();	/* event.c */
  WINDOW *_w_somewin();		/* window.c */
  Pixmap _w_gray();		/* window.c */
***************
*** 141,146 ****
--- 147,153 ----
  char *_wgetdefault();		/* general.c */
  void _w_setgrayborder();	/* window.c */
  void _wsetmasks();		/* window.c */
+ void _w_initcolors();		/* draw.c */
  
  /* Function _wcreate has an extra parameter now */
  #define _wcreate(wp, parent, cursor, map, fg, bg) \



More information about the Alt.sources mailing list