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 {