Пытаюсь использовать X Record для отслеживания сообщений X-протокола. Собрал последние libxext и libxtst. Пример взят из блогов Sun.
ctrl_disp = XOpenDisplay(NULL);
data_disp = XOpenDisplay(NULL);
if (!ctrl_disp || !data_disp) {
exit(1);
}
/*
* we must set the ctrl_disp to sync mode, or, when we the enalbe
* context in data_disp, there will be a fatal X error !!!
*/
XSynchronize(ctrl_disp, True);
int major, minor;
if (!XRecordQueryVersion(ctrl_disp, &major, &minor)) {
exit(2);
}
// здесь версия 1.13
printf("RECORD extension is version is %d.%d\n", major, minor);
XRecordRange *rr;
XRecordClientSpec rcs;
XRecordContext rc;
if ( (rr = XRecordAllocRange()) == NULL ) {
exit(3);
}
rr->device_events.first = KeyPress;
rr->device_events.last = MotionNotify;
rcs = XRecordAllClients;
if ( (rc = XRecordCreateContext(ctrl_disp, 0, &rcs, 1, &rr, 1)) == NULL ) {
exit(4);
}
/*
Здесь падает с такой ошибкой:
RECORD extension for local server is version is 1.13
X Error of failed request: XRecordBadContext
Major opcode of failed request: 128 (RECORD)
Minor opcode of failed request: 5 (XRecordEnableContext)
*/
if (!XRecordEnableContextAsync(data_disp, rc, event_callback, NULL)) {
exit(5);
}
Заинтересовался и залез в искодники libxext. Вот что происходит после вызова XRecordEnableContextAsync:
XRecordEnableContextAsync(dpy, context, callback, closure)
Display *dpy;
XRecordContext context;
XRecordInterceptProc callback;
XPointer closure;
{
XExtDisplayInfo *info = find_display (dpy);
register xRecordEnableContextReq *req;
xRecordEnableContextReply rep = {};
struct reply_buffer *reply;
enum parser_return status;
_XAsyncHandler *async;
record_async_state *async_state;
XRecordCheckExtension (dpy, info, 0);
async = (_XAsyncHandler *)Xmalloc(sizeof(_XAsyncHandler) +
sizeof(record_async_state));
if (!async)
return 0;
async_state = (record_async_state *)(async + 1);
LockDisplay(dpy);
GetReq(RecordEnableContext, req);
req->reqType = info->codes->major_opcode;
req->recordReqType = X_RecordEnableContext;
req->context = context;
/* Get the StartOfData reply. */
/* This code should match that in XRecordEnableContext */
_XReply (dpy, (xReply *)&rep, 0, xFalse);
/*
Падает на _XReply
*/
// ...
}
Вообще говоря, не думаю, что дело в примере программы-клиента. Другие программы. юзающие libxext (например xnee) - тоже крешаться.