Blame 8150954-pr2866-rh1176206-screenshot-xcomposite-jdk.patch

Severin Gehwolf 63b65f3
Severin Gehwolf 63b65f3
# HG changeset patch
Severin Gehwolf 63b65f3
# User neugens
Severin Gehwolf 63b65f3
# Date 1532089120 -7200
Severin Gehwolf 63b65f3
# Node ID 7b30bb9b05bd2e8045bc693ea5be353ce6326396
Severin Gehwolf 63b65f3
# Parent  3d8011a1e02179e5658110981e30274c605ceac8
Severin Gehwolf 63b65f3
8150954: Taking screenshots on x11 composite desktop produce wrong result
Severin Gehwolf 63b65f3
Summary: The AWT Robot X11 code that takes screenshots uses the default root window, which may not contain the final composited desktop.
Severin Gehwolf 63b65f3
Reviewed-by: alexsch, ssadetsky, prr, dbuck
Severin Gehwolf 63b65f3
Severin Gehwolf 63b65f3
diff -r 3d8011a1e021 -r 7b30bb9b05bd make/mapfiles/libawt_xawt/mapfile-vers
Severin Gehwolf 63b65f3
--- openjdk/jdk/make/mapfiles/libawt_xawt/mapfile-vers	Thu Jul 19 03:31:37 2018 +0100
Severin Gehwolf 63b65f3
+++ openjdk/jdk/make/mapfiles/libawt_xawt/mapfile-vers	Fri Jul 20 14:18:40 2018 +0200
Severin Gehwolf 63b65f3
@@ -158,6 +158,7 @@
Severin Gehwolf 63b65f3
         Java_sun_awt_X11_XRobotPeer_mouseReleaseImpl;
Severin Gehwolf 63b65f3
         Java_sun_awt_X11_XRobotPeer_mouseWheelImpl;
Severin Gehwolf 63b65f3
         Java_sun_awt_X11_XRobotPeer_setup;
Severin Gehwolf 63b65f3
+        Java_sun_awt_X11_XRobotPeer_loadNativeLibraries;
Severin Gehwolf 63b65f3
         Java_sun_awt_X11_XToolkit_getNumberOfButtonsImpl;
Severin Gehwolf 63b65f3
         Java_java_awt_Component_initIDs;
Severin Gehwolf 63b65f3
         Java_java_awt_Container_initIDs;
Severin Gehwolf 63b65f3
diff -r 3d8011a1e021 -r 7b30bb9b05bd src/solaris/classes/sun/awt/X11/XRobotPeer.java
Severin Gehwolf 63b65f3
--- openjdk/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java	Thu Jul 19 03:31:37 2018 +0100
Severin Gehwolf 63b65f3
+++ openjdk/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java	Fri Jul 20 14:18:40 2018 +0200
Severin Gehwolf 63b65f3
@@ -34,6 +34,10 @@
Severin Gehwolf 63b65f3
 
Severin Gehwolf 63b65f3
 class XRobotPeer implements RobotPeer {
Severin Gehwolf 63b65f3
 
Severin Gehwolf 63b65f3
+    static {
Severin Gehwolf 63b65f3
+        loadNativeLibraries();
Severin Gehwolf 63b65f3
+    }
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
     private X11GraphicsConfig   xgc = null;
Severin Gehwolf 63b65f3
     /*
Severin Gehwolf 63b65f3
      * native implementation uses some static shared data (pipes, processes)
Severin Gehwolf 63b65f3
@@ -98,4 +102,5 @@
Severin Gehwolf 63b65f3
     private static native synchronized void keyReleaseImpl(int keycode);
Severin Gehwolf 63b65f3
 
Severin Gehwolf 63b65f3
     private static native synchronized void getRGBPixelsImpl(X11GraphicsConfig xgc, int x, int y, int width, int height, int pixelArray[]);
Severin Gehwolf 63b65f3
+    private static native void loadNativeLibraries();
Severin Gehwolf 63b65f3
 }
Severin Gehwolf 63b65f3
diff -r 3d8011a1e021 -r 7b30bb9b05bd src/solaris/native/sun/awt/awt_Robot.c
Severin Gehwolf 63b65f3
--- openjdk/jdk/src/solaris/native/sun/awt/awt_Robot.c	Thu Jul 19 03:31:37 2018 +0100
Severin Gehwolf 63b65f3
+++ openjdk/jdk/src/solaris/native/sun/awt/awt_Robot.c	Fri Jul 20 14:18:40 2018 +0200
Severin Gehwolf 63b65f3
@@ -27,6 +27,9 @@
Severin Gehwolf 63b65f3
     #error This file should not be included in headless library
Severin Gehwolf 63b65f3
 #endif
Severin Gehwolf 63b65f3
 
Severin Gehwolf 63b65f3
+#include "jvm_md.h"
Severin Gehwolf 63b65f3
+#include <dlfcn.h>
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
 #include "awt_p.h"
Severin Gehwolf 63b65f3
 #include "awt_GraphicsEnv.h"
Severin Gehwolf 63b65f3
 #define XK_MISCELLANY
Severin Gehwolf 63b65f3
@@ -49,11 +52,46 @@
Severin Gehwolf 63b65f3
 #include <sys/socket.h>
Severin Gehwolf 63b65f3
 #endif
Severin Gehwolf 63b65f3
 
Severin Gehwolf 63b65f3
+static Bool   (*compositeQueryExtension)   (Display*, int*, int*);
Severin Gehwolf 63b65f3
+static Status (*compositeQueryVersion)     (Display*, int*, int*);
Severin Gehwolf 63b65f3
+static Window (*compositeGetOverlayWindow) (Display *, Window);
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
Severin Gehwolf 63b65f3
 
Severin Gehwolf 63b65f3
 static jint * masks;
Severin Gehwolf 63b65f3
 static jint num_buttons;
Severin Gehwolf 63b65f3
 
Severin Gehwolf 63b65f3
+static void *xCompositeHandle;
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+static const char* XCOMPOSITE = JNI_LIB_NAME("Xcomposite");
Severin Gehwolf 63b65f3
+static const char* XCOMPOSITE_VERSIONED = VERSIONED_JNI_LIB_NAME("Xcomposite", "1");
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+static Bool checkXCompositeFunctions(void) {
Severin Gehwolf 63b65f3
+    return (compositeQueryExtension   != NULL   &&
Severin Gehwolf 63b65f3
+            compositeQueryVersion     != NULL   &&
Severin Gehwolf 63b65f3
+            compositeGetOverlayWindow != NULL);
Severin Gehwolf 63b65f3
+}
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+static void initXCompositeFunctions(void) {
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+    if (xCompositeHandle == NULL) {
Severin Gehwolf 63b65f3
+        xCompositeHandle = dlopen(XCOMPOSITE, RTLD_LAZY | RTLD_GLOBAL);
Severin Gehwolf 63b65f3
+        if (xCompositeHandle == NULL) {
Severin Gehwolf 63b65f3
+            xCompositeHandle = dlopen(XCOMPOSITE_VERSIONED, RTLD_LAZY | RTLD_GLOBAL);
Severin Gehwolf 63b65f3
+        }
Severin Gehwolf 63b65f3
+    }
Severin Gehwolf 63b65f3
+    //*(void **)(&asyncGetCallTraceFunction)
Severin Gehwolf 63b65f3
+    if (xCompositeHandle != NULL) {
Severin Gehwolf 63b65f3
+        *(void **)(&compositeQueryExtension) = dlsym(xCompositeHandle, "XCompositeQueryExtension");
Severin Gehwolf 63b65f3
+        *(void **)(&compositeQueryVersion) = dlsym(xCompositeHandle, "XCompositeQueryVersion");
Severin Gehwolf 63b65f3
+        *(void **)(&compositeGetOverlayWindow) = dlsym(xCompositeHandle, "XCompositeGetOverlayWindow");
Severin Gehwolf 63b65f3
+    }
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+    if (xCompositeHandle && !checkXCompositeFunctions()) {
Severin Gehwolf 63b65f3
+        dlclose(xCompositeHandle);
Severin Gehwolf 63b65f3
+    }
Severin Gehwolf 63b65f3
+}
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
 static int32_t isXTestAvailable() {
Severin Gehwolf 63b65f3
     int32_t major_opcode, first_event, first_error;
Severin Gehwolf 63b65f3
     int32_t  event_basep, error_basep, majorp, minorp;
Severin Gehwolf 63b65f3
@@ -88,6 +126,35 @@
Severin Gehwolf 63b65f3
     return isXTestAvailable;
Severin Gehwolf 63b65f3
 }
Severin Gehwolf 63b65f3
 
Severin Gehwolf 63b65f3
+static Bool hasXCompositeOverlayExtension(Display *display) {
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+    int xoverlay = False;
Severin Gehwolf 63b65f3
+    int eventBase, errorBase;
Severin Gehwolf 63b65f3
+    if (checkXCompositeFunctions() &&
Severin Gehwolf 63b65f3
+        compositeQueryExtension(display, &eventBase, &errorBase))
Severin Gehwolf 63b65f3
+    {
Severin Gehwolf 63b65f3
+        int major = 0;
Severin Gehwolf 63b65f3
+        int minor = 0;
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+        compositeQueryVersion(display, &major, &minor);
Severin Gehwolf 63b65f3
+        if (major > 0 || minor >= 3) {
Severin Gehwolf 63b65f3
+            xoverlay = True;
Severin Gehwolf 63b65f3
+        }
Severin Gehwolf 63b65f3
+    }
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+    return xoverlay;
Severin Gehwolf 63b65f3
+}
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+static jboolean isXCompositeDisplay(Display *display, int screenNumber) {
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+    char NET_WM_CM_Sn[25];
Severin Gehwolf 63b65f3
+    snprintf(NET_WM_CM_Sn, sizeof(NET_WM_CM_Sn), "_NET_WM_CM_S%d\0", screenNumber);
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+    Atom managerSelection = XInternAtom(display, NET_WM_CM_Sn, 0);
Severin Gehwolf 63b65f3
+    Window owner = XGetSelectionOwner(display, managerSelection);
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+    return owner != 0;
Severin Gehwolf 63b65f3
+}
Severin Gehwolf 63b65f3
 
Severin Gehwolf 63b65f3
 static XImage *getWindowImage(Display * display, Window window,
Severin Gehwolf 63b65f3
                               int32_t x, int32_t y,
Severin Gehwolf 63b65f3
@@ -232,6 +299,12 @@
Severin Gehwolf 63b65f3
     DASSERT(adata != NULL);
Severin Gehwolf 63b65f3
 
Severin Gehwolf 63b65f3
     rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen);
Severin Gehwolf 63b65f3
+    if (hasXCompositeOverlayExtension(awt_display) &&
Severin Gehwolf 63b65f3
+        isXCompositeDisplay(awt_display, adata->awt_visInfo.screen))
Severin Gehwolf 63b65f3
+    {
Severin Gehwolf 63b65f3
+        rootWindow = compositeGetOverlayWindow(awt_display, rootWindow);
Severin Gehwolf 63b65f3
+    }
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
     image = getWindowImage(awt_display, rootWindow, x, y, width, height);
Severin Gehwolf 63b65f3
 
Severin Gehwolf 63b65f3
     /* Array to use to crunch around the pixel values */
Severin Gehwolf 63b65f3
@@ -412,3 +485,8 @@
Severin Gehwolf 63b65f3
 
Severin Gehwolf 63b65f3
     AWT_UNLOCK();
Severin Gehwolf 63b65f3
 }
Severin Gehwolf 63b65f3
+
Severin Gehwolf 63b65f3
+JNIEXPORT void JNICALL
Severin Gehwolf 63b65f3
+Java_sun_awt_X11_XRobotPeer_loadNativeLibraries (JNIEnv *env, jclass cls) {
Severin Gehwolf 63b65f3
+    initXCompositeFunctions();
Severin Gehwolf 63b65f3
+}
Severin Gehwolf 63b65f3