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();
|