< prev index next >
src/java.desktop/unix/native/libawt_xawt/awt/awt_Robot.c
Print this page
@@ -43,10 +43,11 @@
#include "robot_common.h"
#include "canvas.h"
#include "wsutils.h"
#include "list.h"
#include "multiVis.h"
+#include "gtk2_interface.h"
#if defined(__linux__) || defined(MACOSX)
#include <sys/socket.h>
#endif
extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
@@ -206,34 +207,97 @@
jobject xgc,
jint x,
jint y,
jint width,
jint height,
- jintArray pixelArray) {
+ jintArray pixelArray,
+ jboolean isGtkSupported) {
XImage *image;
+ XWindowAttributes attr;
jint *ary; /* Array of jints for sending pixel values back
* to parent process.
*/
Window rootWindow;
AwtGraphicsConfigDataPtr adata;
DTRACE_PRINTLN6("RobotPeer: getRGBPixelsImpl(%lx, %d, %d, %d, %d, %x)", xgc, x, y, width, height, pixelArray);
- AWT_LOCK();
-
- /* avoid a lot of work for empty rectangles */
- if ((width * height) == 0) {
- AWT_UNLOCK();
+ if (width <= 0
+ || height <= 0
+ || x < 0
+ || y < 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);
+
+ if (!XGetWindowAttributes(awt_display, rootWindow, &attr)
+ || x >= attr.width
+ || y >= attr.height
+ ) {
+ AWT_UNLOCK();
+ return;
+ }
+
+ width = (x + width > attr.width) ? attr.width - x: width;
+ height = (y + height > attr.height) ? attr.height - y: height;
+
+ gboolean gtk_failed = TRUE;
+ 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);
+
+ 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
+ ) {
+ if (!IS_SAFE_SIZE_MUL(width, height) ||
+ !(ary = (jint *) SAFE_SIZE_ARRAY_ALLOC(malloc, width * height, sizeof (jint))))
+ {
+ (*fp_g_object_unref)(pixbuf);
+ JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
+ return;
+ }
+
+ guchar *p, *pix = (*fp_gdk_pixbuf_get_pixels)(pixbuf);
+ int pb_x, pb_y;
+ for (pb_y = 0; pb_y < height; pb_y++) {
+ for (pb_x = 0; pb_x < width; pb_x++) {
+ p = pix + pb_y * stride + pb_x * nchan;
+ /* convert to Java ARGB pixels */
+ ary[pb_y * width + pb_x] = 0xff000000
+ | (p[0] << 16)
+ | (p[1] << 8)
+ | (p[2]);
+ }
+ }
+ (*env)->SetIntArrayRegion(env, pixelArray, 0, height * width, ary);
+ free(ary);
+ gtk_failed = FALSE;
+ }
+ (*fp_g_object_unref)(pixbuf);
+ }
+ }
+
+ if (gtk_failed) {
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))))
@@ -258,11 +322,11 @@
}
(*env)->SetIntArrayRegion(env, pixelArray, 0, height * width, ary);
free(ary);
XDestroyImage(image);
-
+ }
AWT_UNLOCK();
}
JNIEXPORT void JNICALL
Java_sun_awt_X11_XRobotPeer_keyPressImpl (JNIEnv *env,
< prev index next >