Check my previous posts tagged with Xlib and X11 for reference material. If you've never used JNI before, you're probably going to need to do some basic tutorials first - again, previous posts here may help.
Let's get started! The first thing you're going to need is the X11 development headers. On my machine:
apt-cache search libx11-dev
libx11-dev - X11 client-side library (development headers)
apt-get install libx11-dev
Your java source is your own to deal with, seeing as all that's relevant here is the method and class name. We'll use String JXTest.doSomething();
JXTest.cpp:
#include "/usr/include/X11/Xlib.h"
#include "JXTest.h"
// open the current display. NULL means check the DISPLAY shell variable
Display *display = XOpenDisplay(NULL);
Window hwnd;
int revert_to;
char title[80];
JNIEXPORT jstring JNICALL Java_JXTest_doSomething(JNIEnv *env, jobject obj){
// make sure we're connected to an X display
if(display == NULL){
printf("Could not open display\n");
return NULL;
}
// now we get to do stuff!
// let's keep with previous posts, and go with getting the focused window's title
// check the reference pages on these functions for more information
XGetInputFocus(display, &hwnd, &revert_to);
char* retval;
if(XFetchName(display, hwnd, &retval)) != 0){
// we have to free the string, so let's copy it into our own
// note that title is global so that we're not allocating new memory each time
strcpy(title, retval);
XFree(retval);
printf("Our window title is %s\n", title);
// as per a previous post, NewStringUTF does not preserve the pointer, so we can reuse title later
return env->NewStringUTF(title);
}
printf("Could not get window title!\n");
return null;
}
g++ -lX11 -shared -o libtestlibrary.so -I/usr/lib/jvm/java-6-sun-1.6.0.00/include/ -I/usr/lib/jvm/java-6-sun-1.6.0.00/include/linux -I/usr/includes/X11/ nimbusLinux.cpp
-lX11 links the library to X11 and includes the X11 headers
-o is the output file name - remember that System.loadLbrary translates "testlibrary" to "libtestlibrary.so" automatically
-I are include paths - you'll probably hae to modify these to suit your own system
If all goes well, you should now have a program that interacts with X to get the currently-focused window's title!
Note that under some window managers the currently-focused window has an invisible "FocusProxy" over it - see my post here for information on that and a couple other issues.
One last note: on Linux, I've had issues with library loading with System.loadLibrary. This should help, and it's cross-platform:
static {
try{
File pwd = new File(".");
System.load(pwd.getCanonicalPath() + "/" + System.mapLibraryName("libraryname"));
}catch(Exception e){
e.printStackTrace();
System.exit(1);
}
}
No comments:
Post a Comment