XKB: Add debug key actions for grabs & window tree

Add four new private XKB actions for debugging:
    * PrGrbs: print active grabs to the log file
    * Ungrab: ungrab all currently active grabs
    * ClsGrb: 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+(F9-F12) mapped to the above:
 - compat/xfree86:
    interpret XF86LogGrabInfo {
        action = Private(type=0x86, data="PrGrbs");
    };
    interpret XF86Ungrab {
        action = Private(type=0x86, data="Ungrab");
    }
    interpret XF86ClearGrab {
        action = Private(type=0x86, data="ClsGrb");
    }
    interpret XF86LogWindowTree {
        action = Private(type=0x86, data="PrWins");
    }

 - symbols/pc:
    key <FK09> {        type="CTRL+ALT", [ Return, XF86LogGrabInfo      ]   };
    key <FK10> {        type="CTRL+ALT", [ Return, XF86Ungrab           ]   };
    key <FK11> {        type="CTRL+ALT", [ Return, XF86ClearGrab        ]   };
    key <FK12> {        type="CTRL+ALT", [ Return, XF86LogWindowTree    ]   };

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@fooishbar.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Daniel Stone 2010-12-29 12:03:01 +00:00 committed by Peter Hutterer
parent ddf735fd4e
commit 7d2543a3cb
3 changed files with 130 additions and 0 deletions

View File

@ -68,6 +68,118 @@ SOFTWARE.
#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
void
PrintDeviceGrabInfo(DeviceIntPtr dev)
{
ClientPtr client;
LocalClientCredRec *lcc;
int i, j;
GrabInfoPtr devGrab = &dev->deviceGrab;
GrabPtr grab = devGrab->grab;
ErrorF("Active grab 0x%lx (%s) on device '%s' (%d):",
(unsigned long) grab->resource,
(grab->grabtype == GRABTYPE_XI2) ? "xi2" :
((grab->grabtype == GRABTYPE_CORE) ? "core" : "xi1"),
dev->name, dev->id);
client = clients[CLIENT_ID(grab->resource)];
if (client && GetLocalClientCreds(client, &lcc) != -1)
{
ErrorF(" 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
{
ErrorF(" (no client information available)\n");
}
/* XXX is this even correct? */
if (devGrab->sync.other)
ErrorF(" grab ID 0x%lx from paired device\n",
(unsigned long) devGrab->sync.other->resource);
ErrorF(" at %ld (from %s grab)%s (device %s, state %d)\n",
(unsigned long) devGrab->grabTime.milliseconds,
devGrab->fromPassiveGrab ? "passive" : "active",
devGrab->implicitGrab ? " (implicit)" : "",
devGrab->sync.frozen ? "frozen" : "thawed",
devGrab->sync.state);
if (grab->grabtype == GRABTYPE_CORE)
{
ErrorF(" core event mask 0x%lx\n",
(unsigned long) grab->eventMask);
}
else if (grab->grabtype == GRABTYPE_XI)
{
ErrorF(" xi1 event mask 0x%lx\n",
devGrab->implicitGrab ? (unsigned long) grab->deviceMask :
(unsigned long) grab->eventMask);
}
else if (grab->grabtype == GRABTYPE_XI2)
{
for (i = 0; i < EMASKSIZE; i++)
{
int print;
print = 0;
for (j = 0; j < XI2MASKSIZE; j++)
{
if (grab->xi2mask[i][j])
{
print = 1;
break;
}
}
if (!print)
continue;
ErrorF(" xi2 event mask for device %d: 0x", dev->id);
for (j = 0; j < XI2MASKSIZE; j++)
ErrorF("%x", grab->xi2mask[i][j]);
ErrorF("\n");
}
}
if (devGrab->fromPassiveGrab)
{
ErrorF(" passive grab type %d, detail 0x%x, "
"activating key %d\n", grab->type, grab->detail.exact,
devGrab->activatingKey);
}
ErrorF(" owner-events %s, kb %d ptr %d, confine %lx, cursor 0x%lx\n",
grab->ownerEvents ? "true" : "false",
grab->keyboardMode, grab->pointerMode,
grab->confineTo ? (unsigned long) grab->confineTo->drawable.id : 0,
grab->cursor ? (unsigned long) grab->cursor->id : 0);
}
void
UngrabAllDevices(Bool kill_client)
{
DeviceIntPtr dev;
ClientPtr client;
ErrorF("Ungrabbing all devices%s; grabs listed below:\n",
kill_client ? " and killing their owners" : "");
for (dev = inputInfo.devices; dev; dev = dev->next)
{
if (!dev->deviceGrab.grab)
continue;
PrintDeviceGrabInfo(dev);
client = clients[CLIENT_ID(dev->deviceGrab.grab->resource)];
if (!client || client->clientGone)
dev->deviceGrab.DeactivateGrab(dev);
CloseDownClient(client);
}
ErrorF("End list of ungrabbed devices\n");
}
GrabPtr
CreateGrab(
int client,

View File

@ -13,6 +13,7 @@
#define XKBSRV_NEED_FILE_FUNCS
#include <xkbsrv.h>
#include "dixgrabs.h"
#include "os.h"
#include "xf86.h"
@ -29,6 +30,20 @@ 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) {
DeviceIntPtr tmp;
xf86Msg(X_INFO, "Printing all currently active device grabs:\n");
for (tmp = inputInfo.devices; tmp; tmp = tmp->next)
if (tmp->deviceGrab.grab)
PrintDeviceGrabInfo(tmp);
xf86Msg(X_INFO, "End list of active device grabs\n");
}
else if (strcasecmp(msgbuf, "ungrab")==0)
UngrabAllDevices(FALSE);
else if (strcasecmp(msgbuf, "clsgrb")==0)
UngrabAllDevices(TRUE);
else if (strcasecmp(msgbuf, "prwins")==0)
PrintWindowTree();
}
return 0;

View File

@ -28,6 +28,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
struct _GrabParameters;
extern void PrintDeviceGrabInfo(DeviceIntPtr dev);
extern void UngrabAllDevices(Bool kill_client);
extern GrabPtr CreateGrab(
int /* client */,
DeviceIntPtr /* device */,