< prev index next >

src/java.desktop/unix/native/libawt_xawt/awt/awt_Robot.c

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1999, 2014, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 43,52 **** --- 43,54 ---- #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;
*** 202,268 **** JNIEXPORT void JNICALL Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env, jclass cls, jobject xgc, ! jint x, ! jint y, ! jint width, ! jint height, ! jintArray pixelArray) { ! XImage *image; 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(); return; } - DASSERT(width * height > 0); /* only allow positive size */ adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, xgc, x11GraphicsConfigIDs.aData); DASSERT(adata != NULL); 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); AWT_UNLOCK(); return; } /* 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 */ ! ary[(y * width) + x] = pixel; } } ! (*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, --- 204,333 ---- JNIEXPORT void JNICALL Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env, jclass cls, jobject xgc, ! 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, jx, jy, jwidth, jheight, pixelArray); ! if (jwidth <= 0 || jheight <= 0) { return; } 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) ! || jx + jwidth <= attr.x ! || attr.x + attr.width <= jx ! || jy + jheight <= attr.y ! || attr.y + attr.height <= jy) { ! ! AWT_UNLOCK(); ! return; // Does not intersect with root window ! } /* Array to use to crunch around the pixel values */ ! if (!IS_SAFE_SIZE_MUL(jwidth, jheight) ! || !IS_SAFE_SIZE_MUL(jwidth * jheight, sizeof (jint)) ! || !(ary = (jint *) calloc(jwidth * jheight, sizeof (jint)))) { AWT_UNLOCK(); + JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); return; } + + 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); + + 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); + + 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)->SetIntArrayRegion(env, pixelArray, 0, jheight * jwidth, ary); + gtk_failed = FALSE; + } + (*fp_g_object_unref)(pixbuf); + } + } + + if (gtk_failed) { + image = getWindowImage(awt_display, rootWindow, x, y, width, height); + /* 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; } } ! (*env)->SetIntArrayRegion(env, pixelArray, 0, jheight * jwidth, ary); XDestroyImage(image); + } + free(ary); AWT_UNLOCK(); } JNIEXPORT void JNICALL Java_sun_awt_X11_XRobotPeer_keyPressImpl (JNIEnv *env,
< prev index next >