LINUX.ORG.RU

Сообщения yurich

 

X Record Extension кто-нибудь пользовал?

Форум — Development

Пытаюсь использовать 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) - тоже крешаться.

yurich
()

Протоколирование сообщений иксов

Форум — Development

Хочется иметь возможность вести лог произвольных иксовых сообщений на конкретном терминале (версия иксов X.Org X Server 1.6.0). Первая проблема — не получается ловить сообщения для всех окон, только для какого-то конкретного. Например так:

   Display * d = XOpenDisplay( NULL ); 
   int screen = DefaultScreen(d); 

   attr.event_mask = KeyPressMask | KeyReleaseMask
          | ButtonPressMask | ButtonReleaseMask
          | PointerMotionMask;
  
  Window w = XCreateWindow (dpy, RootWindow (dpy, screen), hints.x, hints.y,
             hints.width, hints.height, borderwidth, 0,
             InputOutput, (Visual *) CopyFromParent, mask, &attr);

  XMapWindow (dpy, w);

  for (done = 0; !done;)
    {
      XEvent event;

      XNextEvent (dpy, &event);

    switch (event.type)
    {
        case KeyPress:
          LOG4CXX_INFO(g_log_XKeylog, "KeyPress event");
          break;
    case KeyRelease:
          LOG4CXX_INFO(g_log_XKeylog, "KeyRelease event");
      break;
        case ButtonPress:
          LOG4CXX_INFO(g_log_XKeylog, "ButtonPress event");
          break;
    case ButtonRelease :
          LOG4CXX_INFO(g_log_XKeylog, "ButtonRelease event");
      break;
        case MotionNotify:
          LOG4CXX_INFO(g_log_XKeylog,"MotionNotify event " );
          break;
    default:
      break;
    }
    }

Если сделать окно Window w = RootWindow (dpy, screen), захват событий не происходит.

Вторая проблема — мне не нужно перехватывать сообщения, нужно только писать в лог. Можно ли прочитать сообщение из очереди, не удаляя его(XPeekEvent - не то)?

Пробовал также захват только клавиатуры/мыши, хотя это немного не то, что надо.

   Display * d = XOpenDisplay( NULL );
   int screen = DefaultScreen(d);
   Window root = RootWindow(d, screen);

//   так почему-то не работает ((
//   XGrabKey(d, AnyKey, AnyModifier, root, True, GrabModeAsync, GrabModeAsync);

   for (int i = min; i <= max; i++) {
     XGrabKey(d, XKeysymToKeycode(d, i), AnyModifier, root, True, GrabModeAsync, GrabModeAsync);
   }

   while(1){
       while ( !XPending(d) ) {
       XEvent event;
       XNextEvent(d, &event);
       Keys_t key;
       switch (event.type) {
       case KeyPress:
           LOG4CXX_INFO(g_log_XKeylog, "Key press " );
           break;
       case KeyRelease:
           LOG4CXX_INFO(g_log_XKeylog, "Key release " );
           break;
       case ButtonPress:
           LOG4CXX_INFO(g_log_XKeylog, "Button press ");
           break;
       case ButtonRelease:
           LOG4CXX_INFO(g_log_XKeylog, "Button release "  );
           break;
        default:
           break;
        }
        }

    }
Та же проблема — сообщения перехватываются и не доходят до окна.

Если можно, также подскажите источник, где популярно описана архитектура иксов, не сталкивался до этого вообще.

yurich
()

RSS подписка на новые темы