[PATCH 2/2] XKB: Add debug key actions for grabs & window tree
Peter Hutterer
peter.hutterer at who-t.net
Wed Jun 15 18:01:58 PDT 2011
On Tue, Jun 14, 2011 at 07:30:49PM +0100, Daniel Stone wrote:
> Add four new private XKB actions for debugging:
> * PrGrbs: print active grabs to the log file
> * DeaGrb: deactivate active grabs
compat/xfree86 still has the stuff for "Ungrab" and "ClsGrab".
#define XF86XK_Ungrab 0x1008FE20 /* force ungrab */
#define XF86XK_ClearGrab 0x1008FE21 /* kill application with grab */
we should keep using them if possible.
Also, everywhere in the protocol and man pages we use "Ungrab" instead of
"deactivate", it'd be better to use that terminology here too anyway.
> * KilGrb: kill clients with active grabs
> * PrWins: dump the current window tree to the log file
>
> To use these, you need to modify your XKB maps, e.g. the following to
> have Ctrl+Alt+Enter print all currently active grabs:
> - compat/xfree86:
> interpret XF86DOS {
> action = Private(type=0x86, data="PrGrbs");
> };
>
> - symbols/pc:
> key <RTRN> { type="CTRL+ALT", [ Return, XF86DOS ] };
>
> (Or any other unused keysym in place of XFDOS.)
>
> At the moment, this only works if the grabbing client continues to call
> AllowEvents, as the server does no event processing at all when a device
> is frozen.
>
> Signed-off-by: Daniel Stone <daniel at fooishbar.org>
> ---
> dix/grabs.c | 132 +++++++++++++++++++++++++++++++++++++++
> hw/xfree86/dixmods/xkbPrivate.c | 9 +++
> include/dixgrabs.h | 4 +
> 3 files changed, 145 insertions(+), 0 deletions(-)
>
> diff --git a/dix/grabs.c b/dix/grabs.c
> index 69c58df..d65c76f 100644
> --- a/dix/grabs.c
> +++ b/dix/grabs.c
> @@ -68,6 +68,138 @@ SOFTWARE.
> #define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
> #define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
>
> +void
> +PrintGrabInfo(void)
> +{
> + DeviceIntPtr dev;
> + ClientPtr client;
> + LocalClientCredRec *lcc;
> + int i, j;
A "Printing active grabs" here would be nice. It would tell us whether there
simply are no grabs or whether this function isn't actually called.
> +
> + for (dev = inputInfo.devices; dev; dev = dev->next)
> + {
> + if (!dev->deviceGrab.grab)
> + continue;
using a tmp variable for dev->deviceGrab would be good here
> +
> + DebugF("[dix] Active grab 0x%lx (%s) on device '%s' (%d):",
any reason you use DebugF here but ErrorF in the print window tree patch?
it's unlikely that users reporting stuck grabs will have debugging enabled.
> + (unsigned long) dev->deviceGrab.grab->resource,
> + (dev->deviceGrab.grab->grabtype == GRABTYPE_XI2) ? "xi2" :
> + ((dev->deviceGrab.grab->grabtype == GRABTYPE_CORE) ? "core" :
> + "xi1"),
> + dev->name,
> + dev->id);
> +
> + client = clients[CLIENT_ID(dev->deviceGrab.grab->resource)];
> + if (client && GetLocalClientCreds(client, &lcc) != -1)
> + {
> + DebugF(" client pid %ld uid %ld gid %ld\n",
> + (lcc->fieldsSet & LCC_PID_SET) ? (long) lcc->pid : 0,
> + (lcc->fieldsSet & LCC_UID_SET) ? (long) lcc->euid : 0,
> + (lcc->fieldsSet & LCC_GID_SET) ? (long) lcc->egid : 0);
> + FreeLocalClientCreds(lcc);
> + }
> + else
> + {
> + DebugF(" (no client information available)\n");
> + }
> +
> + /* XXX is this even correct? */
> + if (dev->deviceGrab.sync.other)
> + DebugF(" grab ID 0x%lx from paired device\n",
> + (unsigned long) dev->deviceGrab.sync.other->resource);
> +
> + DebugF(" at %ld (from %s grab)%s (device %s, state %d)\n",
> + dev->deviceGrab.grabTime,
> + dev->deviceGrab.fromPassiveGrab ? "passive" : "active",
> + dev->deviceGrab.implicitGrab ? " (implicit)" : "",
> + dev->deviceGrab.sync.frozen ? "frozen" : "thawed",
> + dev->deviceGrab.sync.state);
> + DebugF(" grab type %s\n",
> + ((dev->deviceGrab.grab->grabtype == GRABTYPE_CORE) ? "core" :
> + (dev->deviceGrab.grab->grabtype == GRABTYPE_XI) ? "xi1" :
> + "xi2"));
> + DebugF(" core event mask 0x%lx\n",
> + dev->deviceGrab.grab->eventMask);
> + if (dev->deviceGrab.grab->deviceMask)
> + DebugF(" xi1 event mask 0x%lx\n",
> + dev->deviceGrab.grab->deviceMask);
only for implicit passive grabs, otherwise eventMask is the device's grab
mask see the massive comment above struct _GrabRec in inputstr.h
> + for (i = 0; i < EMASKSIZE; i++)
> + {
> + int print;
> + print = 0;
> + for (j = 0; j < XI2MASKSIZE; j++)
> + {
> + if (dev->deviceGrab.grab->xi2mask[i][j])
> + {
> + print = 1;
> + break;
> + }
> + }
> + if (!print)
> + continue;
> + DebugF(" xi2 event mask for device %d: 0x", dev->id);
> + for (j = 0; j < XI2MASKSIZE; j++)
> + DebugF("%x", dev->deviceGrab.grab->xi2mask[i][j]);
> + DebugF("\n");
> + }
> +
> + if (dev->deviceGrab.fromPassiveGrab)
> + {
> + DebugF(" passive grab type %d, detail 0x%lx, "
> + "activating key %d\n",
> + dev->deviceGrab.grab->type,
> + dev->deviceGrab.grab->detail.exact,
> + dev->deviceGrab.activatingKey);
> + }
> +
> + DebugF(" owner-events %s, kb %d ptr %d, confine %x, cursor 0x%x\n",
> + dev->deviceGrab.grab->ownerEvents ? "true" : "false",
> + dev->deviceGrab.grab->keyboardMode,
> + dev->deviceGrab.grab->pointerMode,
> + dev->deviceGrab.grab->confineTo ?
> + dev->deviceGrab.grab->confineTo->drawable.id :
> + 0,
> + dev->deviceGrab.grab->cursor ?
> + dev->deviceGrab.grab->cursor->id :
> + 0);
using a tmp variable for dev->deviceGrab.grab would be nice.
> + }
> +}
> +
> +void
> +DeactivateAllGrabs(void)
> +{
> + DeviceIntPtr dev;
> +
> + DebugF("[dix] Deactivating all active grabs, listed below:\n");
> + PrintGrabInfo();
> +
> + for (dev = inputInfo.devices; dev; dev = dev->next)
> + {
> + if (dev->deviceGrab.grab)
> + dev->deviceGrab.DeactivateGrab(dev);
> + }
> +}
> +
> +void
> +KillGrabbingClients(void)
> +{
> + DeviceIntPtr dev;
> + ClientPtr client;
> +
> + DebugF("[dix] Killing all clients with active grabs, listed below:\n");
these really needs to be ErrorF. same with the one above. both
cause weird behaviour in applications so a little warning is always nice to
have.
> + PrintGrabInfo();
> +
> + for (dev = inputInfo.devices; dev; dev = dev->next)
> + {
> + if (!dev->deviceGrab.grab)
> + continue;
> + client = clients[CLIENT_ID(dev->deviceGrab.grab->resource)];
> + if (!client || client->clientGone)
> + continue;
> + CloseDownClient(client);
> + }
> +}
> +
> GrabPtr
> CreateGrab(
> int client,
> diff --git a/hw/xfree86/dixmods/xkbPrivate.c b/hw/xfree86/dixmods/xkbPrivate.c
> index 9742eaf..381044f 100644
> --- a/hw/xfree86/dixmods/xkbPrivate.c
> +++ b/hw/xfree86/dixmods/xkbPrivate.c
> @@ -13,6 +13,7 @@
> #define XKBSRV_NEED_FILE_FUNCS
> #include <xkbsrv.h>
>
> +#include "dixgrabs.h"
> #include "os.h"
> #include "xf86.h"
>
> @@ -29,6 +30,14 @@ XkbDDXPrivate(DeviceIntPtr dev,KeyCode key,XkbAction *act)
> xf86ProcessActionEvent(ACTION_PREV_MODE, NULL);
> else if (strcasecmp(msgbuf, "+vmode")==0)
> xf86ProcessActionEvent(ACTION_NEXT_MODE, NULL);
> + else if (strcasecmp(msgbuf, "prgrbs")==0)
> + PrintGrabInfo();
> + else if (strcasecmp(msgbuf, "deagrb")==0)
s/deagrb/ungrab/
> + DeactivateAllGrabs();
> + else if (strcasecmp(msgbuf, "kilgrb")==0)
s/kilgrb/clsgrb/
so we can re-use the existing ones
Cheers,
Peter
> + KillGrabbingClients();
> + else if (strcasecmp(msgbuf, "prwins")==0)
> + PrintWindowTree();
> }
>
> return 0;
> diff --git a/include/dixgrabs.h b/include/dixgrabs.h
> index 3b2a46d..3f031a5 100644
> --- a/include/dixgrabs.h
> +++ b/include/dixgrabs.h
> @@ -28,6 +28,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>
> struct _GrabParameters;
>
> +extern void PrintGrabInfo(void);
> +extern void DeactivateAllGrabs(void);
> +extern void KillGrabbingClients(void);
> +
> extern GrabPtr CreateGrab(
> int /* client */,
> DeviceIntPtr /* device */,
> --
> 1.7.5.3
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
>
More information about the xorg-devel
mailing list