< prev index next >
src/java.desktop/unix/native/libawt_xawt/awt/awt_Robot.c
Print this page
@@ -25,10 +25,13 @@
#ifdef HEADLESS
#error This file should not be included in headless library
#endif
+#include "jvm_md.h"
+#include <dlfcn.h>
+
#include "awt_p.h"
#include "awt_GraphicsEnv.h"
#define XK_MISCELLANY
#include <X11/keysymdef.h>
#include <X11/Xutil.h>
@@ -48,15 +51,50 @@
#if defined(__linux__) || defined(MACOSX)
#include <sys/socket.h>
#endif
+static Bool (*compositeQueryExtension) (Display*, int*, int*);
+static Status (*compositeQueryVersion) (Display*, int*, int*);
+static Window (*compositeGetOverlayWindow) (Display *, Window);
+
extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
static jint * masks;
static jint num_buttons;
+static void *xCompositeHandle;
+
+static const char* XCOMPOSITE = JNI_LIB_NAME("Xcomposite");
+static const char* XCOMPOSITE_VERSIONED = VERSIONED_JNI_LIB_NAME("Xcomposite", "1");
+
+static Bool checkXCompositeFunctions(void) {
+ return (compositeQueryExtension != NULL &&
+ compositeQueryVersion != NULL &&
+ compositeGetOverlayWindow != NULL);
+}
+
+static void initXCompositeFunctions(void) {
+
+ if (xCompositeHandle == NULL) {
+ xCompositeHandle = dlopen(XCOMPOSITE, RTLD_LAZY | RTLD_GLOBAL);
+ if (xCompositeHandle == NULL) {
+ xCompositeHandle = dlopen(XCOMPOSITE_VERSIONED, RTLD_LAZY | RTLD_GLOBAL);
+ }
+ }
+ //*(void **)(&asyncGetCallTraceFunction)
+ if (xCompositeHandle != NULL) {
+ *(void **)(&compositeQueryExtension) = dlsym(xCompositeHandle, "XCompositeQueryExtension");
+ *(void **)(&compositeQueryVersion) = dlsym(xCompositeHandle, "XCompositeQueryVersion");
+ *(void **)(&compositeGetOverlayWindow) = dlsym(xCompositeHandle, "XCompositeGetOverlayWindow");
+ }
+
+ if (xCompositeHandle && !checkXCompositeFunctions()) {
+ dlclose(xCompositeHandle);
+ }
+}
+
static int32_t isXTestAvailable() {
int32_t major_opcode, first_event, first_error;
int32_t event_basep, error_basep, majorp, minorp;
int32_t isXTestAvailable;
@@ -87,10 +125,39 @@
}
return isXTestAvailable;
}
+static Bool hasXCompositeOverlayExtension(Display *display) {
+
+ int xoverlay = False;
+ int eventBase, errorBase;
+ if (checkXCompositeFunctions() &&
+ compositeQueryExtension(display, &eventBase, &errorBase))
+ {
+ int major = 0;
+ int minor = 0;
+
+ compositeQueryVersion(display, &major, &minor);
+ if (major > 0 || minor >= 3) {
+ xoverlay = True;
+ }
+ }
+
+ return xoverlay;
+}
+
+static jboolean isXCompositeDisplay(Display *display, int screenNumber) {
+
+ char NET_WM_CM_Sn[25];
+ snprintf(NET_WM_CM_Sn, sizeof(NET_WM_CM_Sn), "_NET_WM_CM_S%d\0", screenNumber);
+
+ Atom managerSelection = XInternAtom(display, NET_WM_CM_Sn, 0);
+ Window owner = XGetSelectionOwner(display, managerSelection);
+
+ return owner != 0;
+}
static XImage *getWindowImage(Display * display, Window window,
int32_t x, int32_t y,
int32_t w, int32_t h) {
XImage *image;
@@ -209,11 +276,11 @@
jint jy,
jint jwidth,
jint jheight,
jint scale,
jintArray pixelArray,
- jboolean isGtkSupported) {
+ jboolean useGtk) {
XImage *image;
jint *ary; /* Array of jints for sending pixel values back
* to parent process.
*/
Window rootWindow;
@@ -236,10 +303,18 @@
jint swidth = jwidth * scale;
jint sheight = jheight * scale;
rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen);
+ if (!useGtk) {
+ if (hasXCompositeOverlayExtension(awt_display) &&
+ isXCompositeDisplay(awt_display, adata->awt_visInfo.screen))
+ {
+ rootWindow = compositeGetOverlayWindow(awt_display, rootWindow);
+ }
+ }
+
if (!XGetWindowAttributes(awt_display, rootWindow, &attr)
|| sx + swidth <= attr.x
|| attr.x + attr.width <= sx
|| sy + sheight <= attr.y
|| attr.y + attr.height <= sy) {
@@ -260,11 +335,11 @@
int dx = attr.x > sx ? attr.x - sx : 0;
int dy = attr.y > sy ? attr.y - sy : 0;
int index;
- if (isGtkSupported) {
+ if (useGtk) {
gtk->gdk_threads_enter();
gtk_failed = gtk->get_drawable_data(env, pixelArray, x, y, width,
height, jwidth, dx, dy, scale);
gtk->gdk_threads_leave();
}
@@ -452,5 +527,10 @@
}
XSync(awt_display, False);
AWT_UNLOCK();
}
+
+JNIEXPORT void JNICALL
+Java_sun_awt_X11_XRobotPeer_loadNativeLibraries (JNIEnv *env, jclass cls) {
+ initXCompositeFunctions();
+}
< prev index next >