I am trying to map X11 XGetInputFocus
through JNA. The original method signature is
XGetInputFocus(Display *display, Window *focus_return, int *revert_to_return)
Which I assumed could be mapped to the following in Java, using the already defined JNA platform types.
void XGetInputFocus(Display display, Window focus_return, IntByReference revert_to_return);
Which correlates to the recommendation described in the documentation. I now invoke it using the following code
final X11 XLIB = X11.INSTANCE;
Window current = new Window();
Display display = XLIB.XOpenDisplay(null);
if (display != null) {
IntByReference revert_to_return = new IntByReference();
XLIB.XGetInputFocus(display, current, revert_to_return);
}
However, it crashes the JVM with
# Problematic frame:
# C [libX11.so.6+0x285b7] XGetInputFocus+0x57
What am I missing?
In the native X11 function
XGetInputFocus(Display *display, Window *focus_return, int *revert_to_return)
the parameter Window *focus_return
is used to return a Window
.
JNA implemented Window
very much like an immutable type,
because in C language it is defined by typedef XID Window;
.
Therefore type Window*
in C needs to be mapped to WindowByReference
in JNA.
(This is essentially the same reason why int*
in C needed to be mapped
to IntByReference
in JNA.)
Then the extended X11
interface can look like this:
public interface X11Extended extends X11 {
X11Extended INSTANCE = (X11Extended) Native.loadLibrary("X11", X11Extended.class);
void XGetInputFocus(Display display, WindowByReference focus_return, IntByReference revert_to_return);
}
And your code should be modified accordingly:
X11Extended xlib = X11Extended.INSTANCE;
WindowByReference current_ref = new WindowByReference();
Display display = xlib.XOpenDisplay(null);
if (display != null) {
IntByReference revert_to_return = new IntByReference();
xlib.XGetInputFocus(display, current_ref, revert_to_return);
Window current = current_ref.getValue();
System.out.println(current);
}
Now the program doesn't crash anymore.
For me it prints 0x3c00605
.