The following patches to the X11R5 sample server allow an X client to
emulate a user interacting with a window manager, or other interaction
which may trigger another client to issue an X_GrabServer request.  These
patches should be applied to an X11R5 sample server that is already set up
to use the DEC-XTrap extension, either version 3.2 (came out with X11R5)
or version 3.3 (recently came out).  DEC-XTrap is an extension to X which
facilitates user emulation.

The grab server problem has been previously worked around (as of version 3.2
of XTrap) by disabling server grabs entirely.  Before these patches, I have
not been able to work around the grab server problem in an elegant and
publicly available fashion.

With these patches, server grabs behave normally for all clients other than
XTrap controlling clients, yet XTrap controlling clients are not locked out
from making input simulation requests of the X server when another client
issues a grab.

These patches override the XTrap behavior of disabling grabs entirely
with a less-intrusive solution - server grab behavior is not totally disabled,
just slightly less restrictive.

In this fashion, XTrap may still be used in a testing environment where
it may be important to preserve the behavior of clients during server grabs.
Or simply it may be important to emulate a user moving an xclock window
around without getting stray bits as the second hand is updated. (the window
manager grabs the server during a window move operation so that an atomic
copyarea operation may be performed, but with server grabs entirely
disabled, an xclock may update its window at the same instant a rubberband
is drawn through a clock hand, producing unexpected results)

This modified behavior will only be have an effect if an XTrap controlling
client which selects to the special XTrap behavior of disabling server grabs,
and it, or another XTrap controlling client, issues an X request while
another X client has grabbed the X server.

These patches include 2 new routines to be added into server/os/connection.c,
calls to those 2 routines in extensions/server/xtrap/xtrapdi.c, and removing
(by ifdef) 2 lines from server/dix/dispatch.c.

These changes are short enough that I'm posting them to comp.windows.x.
Please feel free to redistribute them as widely and freely as any
contributed X software.

--Robert Chesler				rob@chesler.nashua.nh.us

*** server/os/connection.c.last	Mon Aug 24 14:01:17 1992
--- server/os/connection.c	Tue Oct 13 23:34:59 1992
***************
*** 852,857 ****
--- 852,890 ----
      BITCLEAR(AllSockets, fd);
  }
  
+ /* for new version of XTrap */
+ void
+ AlsoListenToClient(client)
+     ClientPtr client;
+ {
+     if (client && GrabInProgress && (GrabInProgress != client->index))
+     {
+ 	OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ 	int connection = oc->fd;
+ 	BITSET(AllClients, connection);
+ 	BITSET(AllSockets, connection);
+ 	BITSET(LastSelectMask, connection);
+ 	if (GETBIT(SavedClientsWithInput, connection))
+ 	    BITSET(ClientsWithInput, connection);
+     }
+ }
+ 
+ /* for new version of XTrap */
+ void
+ AlsoUnListenToClient(client)
+     ClientPtr client;
+ {
+     if (client && GrabInProgress && (GrabInProgress != client->index))
+     {
+ 	OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ 	int connection = oc->fd;
+ 	BITCLEAR(AllClients, connection);
+ 	BITCLEAR(AllSockets, connection);
+ 	BITCLEAR(LastSelectMask, connection);
+ 	BITCLEAR(ClientsWithInput, connection);
+     }
+ }
+ 
  /*****************
   * OnlyListenToOneClient:
   *    Only accept requests from  one client.  Continue to handle new
*** server/dix/dispatch.c.last	Tue Oct 13 23:44:13 1992
--- server/dix/dispatch.c	Fri Nov 15 22:47:17 1991
***************
*** 221,229 ****
--- 221,231 ----
  		/* KillClient can cause this to happen */
  		continue;
  	    }
+ #ifndef XTRAP	/* new XTRAP */
  	    /* GrabServer activation can cause this to be true */
  	    if (grabbingClient && (client != onlyClient))
  		break;
+ #endif /* new XTRAP */
  	    isItTimeToYield = FALSE;
   
              requestingClient = client;
*** extensions/server/xtrap/xtrapdi.c.last	Mon Sep 14 16:44:02 1992
--- extensions/server/xtrap/xtrapdi.c	Tue Oct 13 23:11:00 1992
***************
*** 1327,1333 ****
--- 1327,1363 ----
      if (ignore_grabs == True &&
          (stuff->reqType == X_GrabServer || stuff->reqType == X_UngrabServer))
      {    /* doesn't want Grab's! Note: this is a "last configured" setting */
+ #ifndef NO_NEW_XTRAP
+ 	int status;
+ 
+ 	if (stuff->reqType == X_GrabServer)
+ 	{
+ 	    ClientList *pclient;
+ 
+ 	    /* first call grab server procedure */
+ 	    status = (*XETrapProcVector[stuff->reqType])(client);
+ 
+ 	    /* then add XTrap controlling clients */
+ 	    for (pclient = &io_clients; pclient; pclient = pclient->next)
+ 		if (pclient->client)
+ 		    AlsoListenToClient(pclient->client);
+ 	}
+ 	else
+ 	{
+ 	    ClientList *pclient;
+ 
+ 	    /* first drop XTrap controlling clients */
+ 	    for (pclient = &io_clients; pclient; pclient = pclient->next)
+ 		if (pclient->client)
+ 		    AlsoUnListenToClient(pclient->client);
+ 
+ 	    /* then call ungrab server procedure */
+ 	    status = (*XETrapProcVector[stuff->reqType])(client);
+ 	}
+ 	return status;
+ #else /* NO_NEW_XTRAP */
          return(Success);
+ #endif /* NO_NEW_XTRAP */
      }
      else
      {