[PATCH 2/2] XKB: Add debug key actions for grabs & window tree

Daniel Stone daniel at fooishbar.org
Tue Jun 14 11:30:49 PDT 2011


Add four new private XKB actions for debugging:
    * PrGrbs: print active grabs to the log file
    * DeaGrb: deactivate active grabs
    * 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;
+
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+        if (!dev->deviceGrab.grab)
+            continue;
+
+        DebugF("[dix] Active grab 0x%lx (%s) on device '%s' (%d):",
+               (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);
+        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);
+    }
+}
+
+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");
+    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)
+            DeactivateAllGrabs();
+        else if (strcasecmp(msgbuf, "kilgrb")==0)
+            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



More information about the xorg-devel mailing list