Subject: My patches

From: Chris Siebenmann <cks>
Date: Wed, 18 Nov 1992 20:42:01 -0500

Here are my patches (and my readme for them). All diffs are relative
to the current source on research.att.com.

README.cks:
 I've made various modifications to the sam source in these directories,
originally from research.att.com:/dist/sam. This is an attempt to sort of
describe them.

libXg:
	- sweeping out a rectangle will now grab the pointer from the
	  X server; this means that you can swipe from outside the sam
	  window, making sure your windows line up neatly with the
	  boundary of the sam window.
	- sam (more properly, samterm) will now attempt to use both old
	  and new style X selections; it always writes to both new and
	  old-style, and attempts to read from the old-style selection
	  if the new-style one is empty.
	- menus no longer force the mouse to center on them; the pointer
	  stays where it was when you selected the menu.
libframe:
	- some small diddling to work with Ultrix better
	- u.h's exits() and _exits() macros fixed to a form more
	  palatable to the Sun ANSI compiler (v!=0 checks vs (v)).
	- u.h: map exec() to execvp(), not execv(), so our
	  $PATH will get searched if necessary
samterm:
	- change to mesg.c to center a searched-for selection in the
	  window (change by Byron)

I don't think there are any other bugs or real problems left in sam
and/or samterm, but I haven't used it TOO much.

Patches:
*** /tmp/,RCSt1a09176	Wed Nov 18 20:21:28 1992
--- libXg/getrect.c	Mon Nov 16 17:44:04 1992
***************
*** 20,29 ****
--- 20,30 ----
  
  	but = 1<<(but-1);
  	cursorswitch(&sweep);
  	while(m->buttons)
  		*m = emouse();
+ 	_grabpointer();
  	while(!(m->buttons & but)){
  		*m = emouse();
  		if(m->buttons & (7^but))
  			goto Return;
  	}
***************
*** 42,48 ****
--- 43,50 ----
  	if(m->buttons & (7^but)){
  		rc.min.x = rc.max.x = 0;
  		while(m->buttons)
  			*m = emouse();
  	}
+ 	_ungrabpointer();
  	return rc;
  }
*** /tmp/,RCSt1a09176	Wed Nov 18 20:21:29 1992
--- libXg/libgint.h	Mon Nov 16 17:44:05 1992
***************
*** 35,44 ****
--- 35,48 ----
  extern GC	_getcopygc(Fcode, Bitmap*, Bitmap*, int*);
  
  /* balloc without zero init (which uses a gc!) */
  extern Bitmap	*_balloc(Rectangle, int);
  
+ /* grab and ungrab the pointer. might be safe to make externally visible,
+    but really only around for getrect(). */
+ extern void	_grabpointer(void), _ungrabpointer(void);
+ 
  /* X Display for this application's connection */
  extern Display	*_dpy;
  
  /* screen depth foreground and background for this application */
  extern unsigned long	_fgpixel, _bgpixel;
*** /tmp/,RCSt1a09176	Wed Nov 18 20:21:30 1992
--- libXg/menuhit.c	Mon Nov 16 17:44:05 1992
***************
*** 76,86 ****
  			font, item, S);
  	}
  	bflush();
  	lasti = menusel(menur, m->xy);
  	r = menurect(menur, menu->lasthit);
! 	cursorset(divpt(add(r.min, sub(r.max, Pt(0,Vspacing))), 2));
  	bitblt(&screen, r.min, &screen, r, F&~D);
  	for(;;){
  		*m = emouse();
  		if(!(m->buttons & (1<<(but-1))))
  			break;
--- 76,86 ----
  			font, item, S);
  	}
  	bflush();
  	lasti = menusel(menur, m->xy);
  	r = menurect(menur, menu->lasthit);
! 	/* cursorset(divpt(add(r.min, sub(r.max, Pt(0,Vspacing))), 2)); */
  	bitblt(&screen, r.min, &screen, r, F&~D);
  	for(;;){
  		*m = emouse();
  		if(!(m->buttons & (1<<(but-1))))
  			break;
*** /tmp/,RCSt1a09176	Wed Nov 18 20:21:31 1992
--- libXg/xtbinit.c	Mon Nov 16 17:44:04 1992
***************
*** 642,651 ****
--- 642,659 ----
  
  int
  snarfswap(char *s, int n, char **t)
  {
  	*t = GwinSelectionSwap(widg, s);
+ 	if ((*t && strlen(*t) == 0) || !*t) {
+ 		int l;
+ 		/* Might be using old-style selections. */
+ 		*t = XFetchBytes(_dpy, &l);
+ 	}
+ 	/* Cope with really old clients: write into old selection
+ 	   buffer too. */
+ 	XStoreBytes(_dpy, s, n);
  	if (*t)
  		return strlen(*t);
  	return 0;
  }
  
***************
*** 662,666 ****
--- 670,690 ----
  		v.foreground, v.background, v.function, v.fill_style,
  		v.font, v.tile, v.stipple);
  }
  #endif
  
+ void
+ _grabpointer(void)
+ {
+ 	/* Grab X server with an iron hand. */
+ 	while (XGrabPointer(_dpy, XtWindow(widg), False,
+ 			ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|
+ 			StructureNotifyMask|ExposureMask|KeyPressMask,
+ 			GrabModeAsync, GrabModeAsync, None, None, CurrentTime)
+ 		!= GrabSuccess)
+ 		(void) sleep(2);
+ }
+ void
+ _ungrabpointer(void)
+ {
+ 	XUngrabPointer(_dpy, CurrentTime);
+ }
*** /tmp/,RCSt1a09176	Wed Nov 18 20:21:32 1992
--- libframe/u.h	Mon Nov 16 17:44:05 1992
***************
*** 91,100 ****
--- 91,105 ----
  #define	WEXITSTATUS(s)			(((s)>>8)&0xFF)
  #define	NEEDMEMMOVE
  #define	NEEDSTDARG
  #endif  /* DYNIX */
  
+ #ifdef	__ultrix
+ typedef unsigned long	ulong;
+ #define	NEEDSTDARG
+ #endif
+ 
  #ifdef	v10
  typedef	unsigned short	ushort;
  typedef unsigned long	ulong;
  #endif
  
***************
*** 105,120 ****
  
  #define	sprint				sprintf
  #define	dup(a,b)			dup2(a,b)
  #define	seek(a,b,c)			lseek(a,b,c)
  #define	create(name, mode, perm)	creat(name, perm)
! #define	exec(a,b)			execv(a,b)
  #define	USED(a)
  #define SET(a)
  
! #define	exits(v)			if (v) exit(1); else exit(0)
! #define	_exits(v)			if (v) _exit(1); else _exit(0)
  
  enum
  {
  	OREAD	=	0,		/* open for read */
  	OWRITE	=	1,		/* open for write */
--- 110,125 ----
  
  #define	sprint				sprintf
  #define	dup(a,b)			dup2(a,b)
  #define	seek(a,b,c)			lseek(a,b,c)
  #define	create(name, mode, perm)	creat(name, perm)
! #define	exec(a,b)			execvp(a,b)
  #define	USED(a)
  #define SET(a)
  
! #define	exits(v)			if (v!=0) exit(1); else exit(0)
! #define	_exits(v)			if (v!=0) _exit(1); else _exit(0)
  
  enum
  {
  	OREAD	=	0,		/* open for read */
  	OWRITE	=	1,		/* open for write */
*** /tmp/,RCSt1a09176	Wed Nov 18 20:21:33 1992
--- samterm/mesg.c	Wed Nov 18 15:16:57 1992
***************
*** 492,502 ****
  {
  	Text *t = whichtext(m);
  	Flayer *l = &t->l[t->front];
  
  	if(p0<l->origin || p0-l->origin>l->f.nchars*9/10)
! 		outTsll(Torigin, m, p0, 2L);
  }
  
  void
  hcheck(int m)
  {
--- 492,502 ----
  {
  	Text *t = whichtext(m);
  	Flayer *l = &t->l[t->front];
  
  	if(p0<l->origin || p0-l->origin>l->f.nchars*9/10)
! 		outTsll(Torigin, m, p0, l->f.nlines / 2L);
  }
  
  void
  hcheck(int m)
  {

---

From: John (For the colours are many, but the light is one.) Mackin <john@ civil.su.oz.au>
Date: Wed, 18 Nov 1992 21:12:05 -0500

Thanks for creating this list.  One day perhaps I will have time to
do something with the new sam.  If anyone _does_ do scrolling menus
please let me know, else I will have to do it myself, in my copious
spare time.

Should an article advertising the existence of this list be posted
to comp.editors?

Now, finally, I have an audience to ask a question that has been
bothering me for YEARS.  Historical background: I first used sam
on a Jerq in 1989, hosted by a VAX-11/780 running Eighth Edition.
That version of sam (the `Pike original') didn't have what I call
`tagged REs'; you could use parentheses as you liked as grouping
operators in REs, but that was _all_ they did.  You could not use
\<digit> on the right hand side of an s command to represent `what
the n'th paren part matched.'

I have always wanted to believe that Pike designed the command language
of sam (composition of structural REs) with great precision, and I was
disturbed to find, in the V8 days, that there appeared to be absolutely
no way to accomplish the standard two-column interchange of ed: suppose
you have a file with two words per line separated by one space, and
you want to exchange them on each line, you

[[NOTE, this is an _ed_ command]]

1,$s/\(.*\) \(.*\)/\2 \1/

I found that literally _impossible_ in the Pike original sam.  I tried
hard, but always ended up with the dread "changes out of sequence".

The further history of this is that my friend and colleague Noel Hunt
(you on this list, Noel?  If not, you should be!) decided that he was
going to add tagged REs to sam, and he did it.  That code got sent back
to Pike, and it appears now in the version of sam that they've distributed.
I have always wondered (but never been brave enough to bother Pike)
what the full story is.  Challenge: can anyone find a sam command
to accomplish the exchange _without_ using \<digit> on the right
side of an s command?  (Note: please don't mail me any _theories_ about
this; I worked at it for some days, and have already tried whatever
you have theorised.  I'm only interested if you have tested it in
sam and it worked.)

OK,
John.

---

From: Scott Schwartz <[email-masked]>
Date: Thu, 19 Nov 1992 17:21:05 -0500

|  Here are my patches (and my readme for them). All diffs are relative
| to the current source on research.att.com.

| libXg:
| 	- sweeping out a rectangle will now grab the pointer from the
| 	  X server; this means that you can swipe from outside the sam
| 	  window, making sure your windows line up neatly with the
| 	  boundary of the sam window.

Something in there makes my server unhappy: (MIT R5, twm)

; ./sam -t ./samterm
(type B ../sam/sam.c)
X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  26 (X_GrabPointer)
  Value in failed request:  0xa00d
  Serial number of failed request:  338
  Current serial number in output stream:  338

| 	- menus no longer force the mouse to center on them; the pointer
| 	  stays where it was when you selected the menu.

That looks kind of ugly, IMHO.