--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java Mon Aug 10 14:42:07 2015 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java Tue Aug 11 16:32:13 2015 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,15 +25,16 @@
package sun.awt.X11;
import java.awt.*;
-import java.awt.event.InputEvent;
import java.awt.peer.*;
import sun.awt.AWTAccessor;
import sun.awt.SunToolkit;
+import sun.awt.UNIXToolkit;
import sun.awt.X11GraphicsConfig;
class XRobotPeer implements RobotPeer {
+ private static volatile boolean isGtkSupported;
private X11GraphicsConfig xgc = null;
/*
* native implementation uses some static shared data (pipes, processes)
@@ -44,46 +45,65 @@
XRobotPeer(GraphicsConfiguration gc) {
this.xgc = (X11GraphicsConfig)gc;
SunToolkit tk = (SunToolkit)Toolkit.getDefaultToolkit();
- setup(tk.getNumberOfButtons(), AWTAccessor.getInputEventAccessor().getButtonDownMasks());
+ setup(tk.getNumberOfButtons(),
+ AWTAccessor.getInputEventAccessor().getButtonDownMasks());
+
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+ if (!isGtkSupported) {
+ if (toolkit instanceof UNIXToolkit
+ && ((UNIXToolkit) toolkit).loadGTK()) {
+ isGtkSupported = true;
+ }
+ }
}
+ @Override
public void dispose() {
// does nothing
}
+ @Override
public void mouseMove(int x, int y) {
mouseMoveImpl(xgc, x, y);
}
+ @Override
public void mousePress(int buttons) {
mousePressImpl(buttons);
}
+ @Override
public void mouseRelease(int buttons) {
mouseReleaseImpl(buttons);
}
+ @Override
public void mouseWheel(int wheelAmt) {
- mouseWheelImpl(wheelAmt);
+ mouseWheelImpl(wheelAmt);
}
+ @Override
public void keyPress(int keycode) {
keyPressImpl(keycode);
}
+ @Override
public void keyRelease(int keycode) {
keyReleaseImpl(keycode);
}
+ @Override
public int getRGBPixel(int x, int y) {
int pixelArray[] = new int[1];
- getRGBPixelsImpl(xgc, x, y, 1, 1, pixelArray);
+ getRGBPixelsImpl(xgc, x, y, 1, 1, pixelArray, isGtkSupported);
return pixelArray[0];
}
+ @Override
public int [] getRGBPixels(Rectangle bounds) {
int pixelArray[] = new int[bounds.width*bounds.height];
- getRGBPixelsImpl(xgc, bounds.x, bounds.y, bounds.width, bounds.height, pixelArray);
+ getRGBPixelsImpl(xgc, bounds.x, bounds.y, bounds.width, bounds.height,
+ pixelArray, isGtkSupported);
return pixelArray;
}
@@ -97,5 +117,6 @@
private static native synchronized void keyPressImpl(int keycode);
private static native synchronized void keyReleaseImpl(int keycode);
- private static native synchronized void getRGBPixelsImpl(X11GraphicsConfig xgc, int x, int y, int width, int height, int pixelArray[]);
+ private static native synchronized void getRGBPixelsImpl(X11GraphicsConfig xgc,
+ int x, int y, int width, int height, int pixelArray[], boolean isGtkSupported);
}
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_Robot.c Mon Aug 10 14:42:07 2015 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_Robot.c Tue Aug 11 16:32:13 2015 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,8 @@
#include "wsutils.h"
#include "list.h"
#include "multiVis.h"
+#include "gtk2_interface.h"
+
#if defined(__linux__) || defined(MACOSX)
#include <sys/socket.h>
#endif
@@ -204,63 +206,135 @@
Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env,
jclass cls,
jobject xgc,
- jint x,
- jint y,
- jint width,
- jint height,
- jintArray pixelArray) {
-
+ jint jx,
+ jint jy,
+ jint jwidth,
+ jint jheight,
+ jintArray pixelArray,
+ jboolean isGtkSupported) {
XImage *image;
jint *ary; /* Array of jints for sending pixel values back
* to parent process.
*/
Window rootWindow;
+ XWindowAttributes attr;
AwtGraphicsConfigDataPtr adata;
- DTRACE_PRINTLN6("RobotPeer: getRGBPixelsImpl(%lx, %d, %d, %d, %d, %x)", xgc, x, y, width, height, pixelArray);
-
- AWT_LOCK();
+ DTRACE_PRINTLN6("RobotPeer: getRGBPixelsImpl(%lx, %d, %d, %d, %d, %x)", xgc, jx, jy, jwidth, jheight, pixelArray);
- /* avoid a lot of work for empty rectangles */
- if ((width * height) == 0) {
- AWT_UNLOCK();
+ if (jwidth <= 0 || jheight <= 0) {
return;
}
- DASSERT(width * height > 0); /* only allow positive size */
adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, xgc, x11GraphicsConfigIDs.aData);
DASSERT(adata != NULL);
+ AWT_LOCK();
+
rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen);
- image = getWindowImage(awt_display, rootWindow, x, y, width, height);
- /* Array to use to crunch around the pixel values */
- if (!IS_SAFE_SIZE_MUL(width, height) ||
- !(ary = (jint *) SAFE_SIZE_ARRAY_ALLOC(malloc, width * height, sizeof (jint))))
- {
- JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
- XDestroyImage(image);
+ if (!XGetWindowAttributes(awt_display, rootWindow, &attr)
+ || jx + jwidth <= attr.x
+ || attr.x + attr.width <= jx
+ || jy + jheight <= attr.y
+ || attr.y + attr.height <= jy) {
+
AWT_UNLOCK();
- return;
+ return; // Does not intersect with root window
}
- /* convert to Java ARGB pixels */
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- jint pixel = (jint) XGetPixel(image, x, y); /* Note ignore upper
- * 32-bits on 64-bit
- * OSes.
- */
+
+ gboolean gtk_failed = TRUE;
+ jint _x, _y;
+
+ jint x = MAX(jx, attr.x);
+ jint y = MAX(jy, attr.y);
+ jint width = MIN(jx + jwidth, attr.x + attr.width) - x;
+ jint height = MIN(jy + jheight, attr.y + attr.height) - y;
+
+
+ int dx = attr.x > jx ? attr.x - jx : 0;
+ int dy = attr.y > jy ? attr.y - jy : 0;
+
+ int index;
+
+ if (isGtkSupported) {
+ GdkPixbuf *pixbuf;
+ GdkWindow *root = (*fp_gdk_get_default_root_window)();
+
+ pixbuf = (*fp_gdk_pixbuf_get_from_drawable)(NULL, root, NULL,
+ x, y, 0, 0, width, height);
+
+ if (pixbuf) {
+ int nchan = (*fp_gdk_pixbuf_get_n_channels)(pixbuf);
+ int stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf);
- pixel |= 0xff000000; /* alpha - full opacity */
+ if ((*fp_gdk_pixbuf_get_width)(pixbuf) == width
+ && (*fp_gdk_pixbuf_get_height)(pixbuf) == height
+ && (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf) == 8
+ && (*fp_gdk_pixbuf_get_colorspace)(pixbuf) == GDK_COLORSPACE_RGB
+ && nchan >= 3
+ ) {
+ guchar *p, *pix = (*fp_gdk_pixbuf_get_pixels)(pixbuf);
+
+ ary = (*env)->GetPrimitiveArrayCritical(env, pixelArray, NULL);
+ if (!ary) {
+ (*fp_g_object_unref)(pixbuf);
+ AWT_UNLOCK();
+ return;
+ }
- ary[(y * width) + x] = pixel;
+ for (_y = 0; _y < height; _y++) {
+ for (_x = 0; _x < width; _x++) {
+ p = pix + _y * stride + _x * nchan;
+
+ index = (_y + dy) * jwidth + (_x + dx);
+ ary[index] = 0xff000000
+ | (p[0] << 16)
+ | (p[1] << 8)
+ | (p[2]);
+
+ }
+ }
+ (*env)->ReleasePrimitiveArrayCritical(env, pixelArray, ary, 0);
+ if ((*env)->ExceptionCheck(env)) {
+ (*fp_g_object_unref)(pixbuf);
+ AWT_UNLOCK();
+ return;
+ }
+ gtk_failed = FALSE;
+ }
+ (*fp_g_object_unref)(pixbuf);
}
}
- (*env)->SetIntArrayRegion(env, pixelArray, 0, height * width, ary);
- free(ary);
+
+ if (gtk_failed) {
+ image = getWindowImage(awt_display, rootWindow, x, y, width, height);
+
+ ary = (*env)->GetPrimitiveArrayCritical(env, pixelArray, NULL);
+
+ if (!ary) {
+ XDestroyImage(image);
+ AWT_UNLOCK();
+ return;
+ }
- XDestroyImage(image);
+ /* convert to Java ARGB pixels */
+ for (_y = 0; _y < height; _y++) {
+ for (_x = 0; _x < width; _x++) {
+ jint pixel = (jint) XGetPixel(image, _x, _y); /* Note ignore upper
+ * 32-bits on 64-bit
+ * OSes.
+ */
+ pixel |= 0xff000000; /* alpha - full opacity */
+ index = (_y + dy) * jwidth + (_x + dx);
+ ary[index] = pixel;
+ }
+ }
+
+ XDestroyImage(image);
+ (*env)->ReleasePrimitiveArrayCritical(env, pixelArray, ary, 0);
+ }
AWT_UNLOCK();
}
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c Mon Aug 10 14:42:07 2015 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c Tue Aug 11 16:32:13 2015 +0300
@@ -203,9 +203,6 @@
gint, gint, gint, gint);
static GdkPixbuf *(*fp_gdk_pixbuf_new)(GdkColorspace colorspace,
gboolean has_alpha, int bits_per_sample, int width, int height);
-static GdkPixbuf *(*fp_gdk_pixbuf_get_from_drawable)(GdkPixbuf *dest,
- GdkDrawable *src, GdkColormap *cmap, int src_x, int src_y,
- int dest_x, int dest_y, int width, int height);
static void (*fp_gdk_drawable_get_size)(GdkDrawable *drawable,
gint* width, gint* height);
@@ -646,6 +643,8 @@
fp_g_object_set = dl_symbol("g_object_set");
/* GDK */
+ fp_gdk_get_default_root_window =
+ dl_symbol("gdk_get_default_root_window");
fp_gdk_pixmap_new = dl_symbol("gdk_pixmap_new");
fp_gdk_pixbuf_get_from_drawable =
dl_symbol("gdk_pixbuf_get_from_drawable");
@@ -670,6 +669,8 @@
dl_symbol("gdk_pixbuf_get_bits_per_sample");
fp_gdk_pixbuf_get_n_channels =
dl_symbol("gdk_pixbuf_get_n_channels");
+ fp_gdk_pixbuf_get_colorspace =
+ dl_symbol("gdk_pixbuf_get_colorspace");
/* GTK painting */
fp_gtk_init_check = dl_symbol("gtk_init_check");
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h Mon Aug 10 14:42:07 2015 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h Tue Aug 11 16:32:13 2015 +0300
@@ -772,6 +772,8 @@
void (*fp_g_free)(gpointer mem);
void (*fp_g_object_unref)(gpointer object);
+GdkWindow *(*fp_gdk_get_default_root_window) (void);
+
int (*fp_gdk_pixbuf_get_bits_per_sample)(const GdkPixbuf *pixbuf);
guchar *(*fp_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf);
gboolean (*fp_gdk_pixbuf_get_has_alpha)(const GdkPixbuf *pixbuf);
@@ -780,6 +782,13 @@
int (*fp_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf);
int (*fp_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf);
GdkPixbuf *(*fp_gdk_pixbuf_new_from_file)(const char *filename, GError **error);
+GdkColorspace (*fp_gdk_pixbuf_get_colorspace)(const GdkPixbuf *pixbuf);
+
+GdkPixbuf *(*fp_gdk_pixbuf_get_from_drawable)(GdkPixbuf *dest,
+ GdkDrawable *src, GdkColormap *cmap, int src_x, int src_y,
+ int dest_x, int dest_y, int width, int height);
+
+
void (*fp_gtk_widget_destroy)(GtkWidget *widget);
void (*fp_gtk_window_present)(GtkWindow *window);
void (*fp_gtk_window_move)(GtkWindow *window, gint x, gint y);
--- a/jdk/test/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java Mon Aug 10 14:42:07 2015 +0200
+++ b/jdk/test/java/awt/Frame/ShapeNotSetSometimes/ShapeNotSetSometimes.java Tue Aug 11 16:32:13 2015 +0300
@@ -46,11 +46,8 @@
private static Robot robot;
public ShapeNotSetSometimes() throws Exception {
- EventQueue.invokeAndWait(new Runnable() {
- public void run() {
- initializeGUI();
- }
- });
+ EventQueue.invokeAndWait(this::initializeGUI);
+ robot.waitForIdle();
}
private void initializeGUI() {
@@ -119,7 +116,7 @@
public static void main(String[] args) throws Exception {
robot = new Robot();
- for(int i = 0; i < 100; i++) {
+ for(int i = 0; i < 50; i++) {
System.out.println("Attempt " + i);
new ShapeNotSetSometimes().doTest();
}
@@ -134,11 +131,7 @@
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
robot.delay(500);
- EventQueue.invokeAndWait(new Runnable() {
- public void run() {
- window.requestFocus();
- }
- });
+ EventQueue.invokeAndWait(window::requestFocus);
robot.waitForIdle();
try {
--- a/jdk/test/java/awt/Window/TranslucentJAppletTest/TranslucentJAppletTest.java Mon Aug 10 14:42:07 2015 +0200
+++ b/jdk/test/java/awt/Window/TranslucentJAppletTest/TranslucentJAppletTest.java Tue Aug 11 16:32:13 2015 +0300
@@ -100,12 +100,10 @@
if (!paintComponentCalled) {
throw new RuntimeException("Test FAILED: panel's paintComponent() method is not called");
}
+ Thread.sleep(1500);
Color newColor1 = r.getPixelColor(100, 100);
- // unfortunately, robot.getPixelColor() doesn't work for some unknown reason
- // Color newColor2 = r.getPixelColor(200, 200);
- BufferedImage bim = r.createScreenCapture(new Rectangle(200, 200, 1, 1));
- Color newColor2 = new Color(bim.getRGB(0, 0));
+ Color newColor2 = r.getPixelColor(200, 200);
// Frame must be transparent at (100, 100) in screen coords
if (!color1.equals(newColor1)) {
--- a/jdk/test/javax/swing/JComponent/6683775/bug6683775.java Mon Aug 10 14:42:07 2015 +0200
+++ b/jdk/test/javax/swing/JComponent/6683775/bug6683775.java Tue Aug 11 16:32:13 2015 +0300
@@ -31,13 +31,15 @@
*/
import com.sun.awt.AWTUtilities;
-import sun.awt.SunToolkit;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class bug6683775 {
+ static final int LOC = 100,
+ SIZE = 200;
+
public static void main(String[] args) throws Exception {
GraphicsConfiguration gc = getGC();
if (!AWTUtilities.isTranslucencySupported(
@@ -45,39 +47,37 @@
|| gc == null) {
return;
}
- SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
Robot robot = new Robot();
final JFrame testFrame = new JFrame(gc);
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- JFrame backgroundFrame = new JFrame("Background frame");
- backgroundFrame.setUndecorated(true);
- JPanel panel = new JPanel();
- panel.setBackground(Color.RED);
- backgroundFrame.add(panel);
- backgroundFrame.setSize(200, 200);
- backgroundFrame.setVisible(true);
+ SwingUtilities.invokeAndWait(() -> {
+ JFrame backgroundFrame = new JFrame("Background frame");
+ backgroundFrame.setUndecorated(true);
+ JPanel panel = new JPanel();
+ panel.setBackground(Color.RED);
+ backgroundFrame.add(panel);
+ backgroundFrame.setBounds(LOC, LOC, SIZE, SIZE);
+ backgroundFrame.setVisible(true);
- testFrame.setUndecorated(true);
- JPanel p = new JPanel();
- p.setOpaque(false);
- testFrame.add(p);
- AWTUtilities.setWindowOpaque(testFrame, false);
- testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- testFrame.setSize(400, 400);
- testFrame.setLocation(0, 0);
- testFrame.setVisible(true);
- }
+ testFrame.setUndecorated(true);
+ JPanel p = new JPanel();
+ p.setOpaque(false);
+ testFrame.add(p);
+ AWTUtilities.setWindowOpaque(testFrame, false);
+ testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ testFrame.setBounds(LOC, LOC, SIZE, SIZE);
+ testFrame.setVisible(true);
});
- toolkit.realSync();
+ robot.waitForIdle();
+ Thread.sleep(1500);
//robot.getPixelColor() didn't work right for some reason
- BufferedImage capture = robot.createScreenCapture(new Rectangle(100, 100));
+ BufferedImage capture =
+ robot.createScreenCapture(new Rectangle(LOC, LOC, SIZE, SIZE));
int redRGB = Color.RED.getRGB();
- if (redRGB != capture.getRGB(10, 10)) {
+ if (redRGB != capture.getRGB(SIZE/2, SIZE/2)) {
throw new RuntimeException("Transparent frame is not transparent!");
}
}