Отображение структуры союза JNA

В JNA, как вы сопоставляете структуру объединения, подобную следующему XEvent из Xlib

typedef union _XEvent {
    int type;    /* must not be changed */
    XAnyEvent xany;
    XKeyEvent xkey;
    XButtonEvent xbutton;
    XMotionEvent xmotion;
    XCrossingEvent xcrossing;
    XFocusChangeEvent xfocus;
    XExposeEvent xexpose;
    XGraphicsExposeEvent xgraphicsexpose;
    XNoExposeEvent xnoexpose;
    XVisibilityEvent xvisibility;
    XCreateWindowEvent xcreatewindow;
    XDestroyWindowEvent xdestroywindow;
    XUnmapEvent xunmap;
    XMapEvent xmap;
    XMapRequestEvent xmaprequest;
    XReparentEvent xreparent;
    XConfigureEvent xconfigure;
    XGravityEvent xgravity;
    XResizeRequestEvent xresizerequest;
    XConfigureRequestEvent xconfigurerequest;
    XCirculateEvent xcirculate;
    XCirculateRequestEvent xcirculaterequest;
    XPropertyEvent xproperty;
    XSelectionClearEvent xselectionclear;
    XSelectionRequestEvent xselectionrequest;
    XSelectionEvent xselection;
    XColormapEvent xcolormap;
    XClientMessageEvent xclient;
    XMappingEvent xmapping;
    XErrorEvent xerror;
    XKeymapEvent xkeymap;
    long pad[24];
} XEvent;

Я хочу иметь возможность позже приводить XEvent в JNA к другим событиям (таким как XKeyEvent, XButtonEvent, XMotionEvent... и т. д.) в зависимости от типа полученного события.

Я не прошу полного сопоставления всех вышеперечисленных структур. Четкого объяснения с небольшим примером, как это сделать, будет достаточно.

Спасибо


person Untitled    schedule 23.06.2010    source источник


Ответы (2)


Используйте сопоставления, определенные во вкладе JNA (com.sun.jna.platform.X11), затем выполните следующие действия:

  1. Получите XEvent, используя любой метод, который вы предпочитаете (например, XNextEvent).
  2. Определите тип события, используя поле типа.
  3. В зависимости от типа вызовите метод readFiled с именем поля (в виде строки) и приведите возвращаемое значение к типу события имени поля.

Пример:

XEvent event = new XEvent();
X11.INSTANCE.XNextEvent(display, event);
if(event.type == X11.KeyPress) {
    XKeyEvent xKey = (XKeyEvent)event.readField("xkey");
    // you can now use xKey.keycode and other fields
}
person temp    schedule 25.06.2010
comment
Ура! Отличный ответ, очень помог мне с моими сопоставлениями SDL2, спасибо. - person serg.nechaev; 31.08.2015

В исходниках для JNA уже есть примеры для xlib.

Это описано здесь. здесь

Реализацию можно найти в исходниках jna в папке contrib.

В частности, для XEvent он определяется как:

    public static class XEvent extends Union {
    public int type;
    public XAnyEvent xany;
    public XKeyEvent xkey;
    public XButtonEvent xbutton;
    public XMotionEvent xmotion;
    public XCrossingEvent xcrossing;
    public XFocusChangeEvent xfocus;
    public XExposeEvent xexpose;
    public XGraphicsExposeEvent xgraphicsexpose;
    public XNoExposeEvent xnoexpose;
    public XVisibilityEvent xvisibility;
    public XCreateWindowEvent xcreatewindow;
    public XDestroyWindowEvent xdestroywindow;
    public XUnmapEvent xunmap;
    public XMapEvent xmap;
    public XMapRequestEvent xmaprequest;
    public XReparentEvent xreparent;
    public XConfigureEvent xconfigure;
    public XGravityEvent xgravity;
    public XResizeRequestEvent xresizerequest;
    public XConfigureRequestEvent xconfigurerequest;
    public XCirculateEvent xcirculate;
    public XCirculateRequestEvent xcirculaterequest;
    public XPropertyEvent xproperty;
    public XSelectionClearEvent xselectionclear;
    public XSelectionRequestEvent xselectionrequest;
    public XSelectionEvent xselection;
    public XColormapEvent xcolormap;
    public XClientMessageEvent xclient;
    public XMappingEvent xmapping;
    public XErrorEvent xerror;
    public XKeymapEvent xkeymap;
    public NativeLong[] pad = new NativeLong[24];
}

Я все еще изучаю JNA, но я считаю, что идея заключается в том, чтобы проверить значение типа, а затем ссылаться только на соответствующее поле события. Остальные должны быть нулевыми. Я не думаю, что это возможно сделать через бросок.

person Aaron    schedule 23.06.2010
comment
Ты это пробовал? Я попробовал код в contrib с XGrabKeyboard с XNextEvent. Он возвращает XEvent и имеет тип KeyPress/KeyRelease, однако, когда я обращаюсь к коду event.xkey.keycode, я всегда получаю ноль, независимо от того, какая клавиша нажата. Если вы попробовали это успешно, то я отмечу ваш ответ как правильный, так как, возможно, проблема где-то еще в моем коде. - person Untitled; 24.06.2010