< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  28 #endif
  29 
  30 #include "awt_p.h"
  31 #include "awt_GraphicsEnv.h"
  32 #define XK_MISCELLANY
  33 #include <X11/keysymdef.h>
  34 #include <X11/Intrinsic.h>
  35 #include <X11/Xutil.h>
  36 #include <X11/Xmd.h>
  37 #include <X11/extensions/xtestext1.h>
  38 #include <X11/extensions/XTest.h>
  39 #include <X11/extensions/XInput.h>
  40 #include <X11/extensions/XI.h>
  41 #include <jni.h>
  42 #include <sizecalc.h>
  43 #include "robot_common.h"
  44 #include "canvas.h"
  45 #include "wsutils.h"
  46 #include "list.h"
  47 #include "multiVis.h"


  48 #if defined(__linux__) || defined(MACOSX)
  49 #include <sys/socket.h>
  50 #endif
  51 
  52 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
  53 
  54 static jint * masks;
  55 static jint num_buttons;
  56 
  57 static int32_t isXTestAvailable() {
  58     int32_t major_opcode, first_event, first_error;
  59     int32_t  event_basep, error_basep, majorp, minorp;
  60     int32_t isXTestAvailable;
  61 
  62     /* check if XTest is available */
  63     isXTestAvailable = XQueryExtension(awt_display, XTestExtensionName, &major_opcode, &first_event, &first_error);
  64     DTRACE_PRINTLN3("RobotPeer: XQueryExtension(XTEST) returns major_opcode = %d, first_event = %d, first_error = %d",
  65                     major_opcode, first_event, first_error);
  66     if (isXTestAvailable) {
  67         /* check if XTest version is OK */


 187     for (i = 0; i < num_buttons; i++) {
 188         masks[i] = tmp[i];
 189     }
 190     (*env)->ReleaseIntArrayElements(env, buttonDownMasks, tmp, 0);
 191 
 192     AWT_LOCK();
 193     xtestAvailable = isXTestAvailable();
 194     DTRACE_PRINTLN1("RobotPeer: XTest available = %d", xtestAvailable);
 195     if (!xtestAvailable) {
 196         JNU_ThrowByName(env, "java/awt/AWTException", "java.awt.Robot requires your X server support the XTEST extension version 2.2");
 197     }
 198 
 199     AWT_UNLOCK();
 200 }
 201 
 202 
 203 JNIEXPORT void JNICALL
 204 Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env,
 205                              jclass cls,
 206                              jobject xgc,
 207                              jint x,
 208                              jint y,
 209                              jint width,
 210                              jint height,
 211                              jintArray pixelArray) {
 212 
 213     XImage *image;
 214     jint *ary;               /* Array of jints for sending pixel values back
 215                               * to parent process.
 216                               */
 217     Window rootWindow;

 218     AwtGraphicsConfigDataPtr adata;
 219 
 220     DTRACE_PRINTLN6("RobotPeer: getRGBPixelsImpl(%lx, %d, %d, %d, %d, %x)", xgc, x, y, width, height, pixelArray);
 221 
 222     AWT_LOCK();
 223 
 224     /* avoid a lot of work for empty rectangles */
 225     if ((width * height) == 0) {
 226         AWT_UNLOCK();
 227         return;
 228     }
 229     DASSERT(width * height > 0); /* only allow positive size */
 230 
 231     adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, xgc, x11GraphicsConfigIDs.aData);
 232     DASSERT(adata != NULL);
 233 


 234     rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen);
 235     image = getWindowImage(awt_display, rootWindow, x, y, width, height);









 236 
 237     /* Array to use to crunch around the pixel values */
 238     if (!IS_SAFE_SIZE_MUL(width, height) ||
 239         !(ary = (jint *) SAFE_SIZE_ARRAY_ALLOC(malloc, width * height, sizeof (jint))))
 240     {
 241         JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
 242         XDestroyImage(image);
 243         AWT_UNLOCK();

 244         return;
 245     }
























































 246     /* convert to Java ARGB pixels */
 247     for (y = 0; y < height; y++) {
 248         for (x = 0; x < width; x++) {
 249             jint pixel = (jint) XGetPixel(image, x, y); /* Note ignore upper
 250                                                          * 32-bits on 64-bit
 251                                                          * OSes.
 252                                                          */
 253 
 254             pixel |= 0xff000000; /* alpha - full opacity */
 255 
 256             ary[(y * width) + x] = pixel;

 257         }
 258     }
 259     (*env)->SetIntArrayRegion(env, pixelArray, 0, height * width, ary);
 260     free(ary);
 261 
 262     XDestroyImage(image);

 263 

 264     AWT_UNLOCK();
 265 }
 266 
 267 JNIEXPORT void JNICALL
 268 Java_sun_awt_X11_XRobotPeer_keyPressImpl (JNIEnv *env,
 269                          jclass cls,
 270                          jint keycode) {
 271 
 272     AWT_LOCK();
 273 
 274     DTRACE_PRINTLN1("RobotPeer: keyPressImpl(%i)", keycode);
 275 
 276     XTestFakeKeyEvent(awt_display,
 277                       XKeysymToKeycode(awt_display, awt_getX11KeySym(keycode)),
 278                       True,
 279                       CurrentTime);
 280 
 281     XSync(awt_display, False);
 282 
 283     AWT_UNLOCK();


   1 /*
   2  * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  28 #endif
  29 
  30 #include "awt_p.h"
  31 #include "awt_GraphicsEnv.h"
  32 #define XK_MISCELLANY
  33 #include <X11/keysymdef.h>
  34 #include <X11/Intrinsic.h>
  35 #include <X11/Xutil.h>
  36 #include <X11/Xmd.h>
  37 #include <X11/extensions/xtestext1.h>
  38 #include <X11/extensions/XTest.h>
  39 #include <X11/extensions/XInput.h>
  40 #include <X11/extensions/XI.h>
  41 #include <jni.h>
  42 #include <sizecalc.h>
  43 #include "robot_common.h"
  44 #include "canvas.h"
  45 #include "wsutils.h"
  46 #include "list.h"
  47 #include "multiVis.h"
  48 #include "gtk2_interface.h"
  49 
  50 #if defined(__linux__) || defined(MACOSX)
  51 #include <sys/socket.h>
  52 #endif
  53 
  54 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
  55 
  56 static jint * masks;
  57 static jint num_buttons;
  58 
  59 static int32_t isXTestAvailable() {
  60     int32_t major_opcode, first_event, first_error;
  61     int32_t  event_basep, error_basep, majorp, minorp;
  62     int32_t isXTestAvailable;
  63 
  64     /* check if XTest is available */
  65     isXTestAvailable = XQueryExtension(awt_display, XTestExtensionName, &major_opcode, &first_event, &first_error);
  66     DTRACE_PRINTLN3("RobotPeer: XQueryExtension(XTEST) returns major_opcode = %d, first_event = %d, first_error = %d",
  67                     major_opcode, first_event, first_error);
  68     if (isXTestAvailable) {
  69         /* check if XTest version is OK */


 189     for (i = 0; i < num_buttons; i++) {
 190         masks[i] = tmp[i];
 191     }
 192     (*env)->ReleaseIntArrayElements(env, buttonDownMasks, tmp, 0);
 193 
 194     AWT_LOCK();
 195     xtestAvailable = isXTestAvailable();
 196     DTRACE_PRINTLN1("RobotPeer: XTest available = %d", xtestAvailable);
 197     if (!xtestAvailable) {
 198         JNU_ThrowByName(env, "java/awt/AWTException", "java.awt.Robot requires your X server support the XTEST extension version 2.2");
 199     }
 200 
 201     AWT_UNLOCK();
 202 }
 203 
 204 
 205 JNIEXPORT void JNICALL
 206 Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env,
 207                              jclass cls,
 208                              jobject xgc,
 209                              jint jx,
 210                              jint jy,
 211                              jint jwidth,
 212                              jint jheight,
 213                              jintArray pixelArray,
 214                              jboolean isGtkSupported) {
 215     XImage *image;
 216     jint *ary;               /* Array of jints for sending pixel values back
 217                               * to parent process.
 218                               */
 219     Window rootWindow;
 220     XWindowAttributes attr;
 221     AwtGraphicsConfigDataPtr adata;
 222 
 223     DTRACE_PRINTLN6("RobotPeer: getRGBPixelsImpl(%lx, %d, %d, %d, %d, %x)", xgc, jx, jy, jwidth, jheight, pixelArray);


 224 
 225     if (jwidth <= 0 || jheight <= 0) {


 226         return;
 227     }

 228 
 229     adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, xgc, x11GraphicsConfigIDs.aData);
 230     DASSERT(adata != NULL);
 231 
 232     AWT_LOCK();
 233 
 234     rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen);
 235 
 236     if (!XGetWindowAttributes(awt_display, rootWindow, &attr)
 237             || jx + jwidth <= attr.x
 238             || attr.x + attr.width <= jx
 239             || jy + jheight <= attr.y
 240             || attr.y + attr.height <= jy) {
 241 
 242         AWT_UNLOCK();
 243         return; // Does not intersect with root window
 244     }
 245 
 246     /* Array to use to crunch around the pixel values */
 247     if (!IS_SAFE_SIZE_MUL(jwidth, jheight)
 248             || !IS_SAFE_SIZE_MUL(jwidth * jheight, sizeof (jint))
 249             || !(ary = (jint *) calloc(jwidth * jheight, sizeof (jint)))) {


 250         AWT_UNLOCK();
 251         JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
 252         return;
 253     }
 254 
 255     gboolean gtk_failed = TRUE;
 256     jint _x, _y;
 257 
 258     jint x = MAX(jx, attr.x);
 259     jint y = MAX(jy, attr.y);
 260     jint width = MIN(jx + jwidth, attr.x + attr.width) - x;
 261     jint height = MIN(jy + jheight, attr.y + attr.height) - y;
 262 
 263 
 264     int dx = attr.x > jx ? attr.x - jx : 0;
 265     int dy = attr.y > jy ? attr.y - jy : 0;
 266 
 267     int index;
 268 
 269     if (isGtkSupported) {
 270         GdkPixbuf *pixbuf;
 271         GdkWindow *root = fp_gdk_get_default_root_window ();
 272 
 273         pixbuf = (*fp_gdk_pixbuf_get_from_drawable)(NULL, root, NULL,
 274                                                     x, y, 0, 0, width, height);
 275 
 276         if (pixbuf) {
 277             int nchan = (*fp_gdk_pixbuf_get_n_channels)(pixbuf);
 278             int stride = (*fp_gdk_pixbuf_get_rowstride)(pixbuf);
 279 
 280             if ((*fp_gdk_pixbuf_get_width)(pixbuf) == width
 281                     && (*fp_gdk_pixbuf_get_height)(pixbuf) == height
 282                     && (*fp_gdk_pixbuf_get_bits_per_sample)(pixbuf) == 8
 283                     && (*fp_gdk_pixbuf_get_colorspace)(pixbuf) == GDK_COLORSPACE_RGB
 284                     && nchan >= 3
 285                     ) {
 286                 guchar *p, *pix = (*fp_gdk_pixbuf_get_pixels)(pixbuf);
 287 
 288                 for (_y = 0; _y < height; _y++) {
 289                     for (_x = 0; _x < width; _x++) {
 290                         p = pix + _y * stride + _x * nchan;
 291 
 292                         index = (_y + dy) * jwidth + (_x + dx);
 293                         ary[index] = 0xff000000
 294                                         | (p[0] << 16)
 295                                         | (p[1] << 8)
 296                                         | (p[2]);
 297 
 298                     }
 299                 }
 300                 (*env)->SetIntArrayRegion(env, pixelArray, 0, jheight * jwidth, ary);
 301                 gtk_failed = FALSE;
 302             }
 303             (*fp_g_object_unref)(pixbuf);
 304         }
 305     }
 306 
 307     if (gtk_failed) {
 308         image = getWindowImage(awt_display, rootWindow, x, y, width, height);
 309 
 310         /* convert to Java ARGB pixels */
 311         for (_y = 0; _y < height; _y++) {
 312             for (_x = 0; _x < width; _x++) {
 313                 jint pixel = (jint) XGetPixel(image, _x, _y); /* Note ignore upper
 314                                                                * 32-bits on 64-bit
 315                                                                * OSes.
 316                                                                */

 317                 pixel |= 0xff000000; /* alpha - full opacity */
 318 
 319                 index = (_y + dy) * jwidth + (_x + dx);
 320                 ary[index] = pixel;
 321             }
 322         }
 323         (*env)->SetIntArrayRegion(env, pixelArray, 0, jheight * jwidth, ary);

 324 
 325         XDestroyImage(image);
 326     }
 327 
 328     free(ary);
 329     AWT_UNLOCK();
 330 }
 331 
 332 JNIEXPORT void JNICALL
 333 Java_sun_awt_X11_XRobotPeer_keyPressImpl (JNIEnv *env,
 334                          jclass cls,
 335                          jint keycode) {
 336 
 337     AWT_LOCK();
 338 
 339     DTRACE_PRINTLN1("RobotPeer: keyPressImpl(%i)", keycode);
 340 
 341     XTestFakeKeyEvent(awt_display,
 342                       XKeysymToKeycode(awt_display, awt_getX11KeySym(keycode)),
 343                       True,
 344                       CurrentTime);
 345 
 346     XSync(awt_display, False);
 347 
 348     AWT_UNLOCK();


< prev index next >