49 #include <sys/socket.h> |
49 #include <sys/socket.h> |
50 #endif |
50 #endif |
51 |
51 |
52 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs; |
52 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs; |
53 |
53 |
54 // 2 would be more correct, however that's how Robot originally worked |
54 extern int32_t getNumButtons(); |
55 // and tests start to fail if this value is changed |
55 |
56 static int32_t num_buttons = 3; |
|
57 static jint * masks; |
56 static jint * masks; |
58 |
57 |
59 static int32_t isXTestAvailable() { |
58 static int32_t isXTestAvailable() { |
60 int32_t major_opcode, first_event, first_error; |
59 int32_t major_opcode, first_event, first_error; |
61 int32_t event_basep, error_basep, majorp, minorp; |
60 int32_t event_basep, error_basep, majorp, minorp; |
88 } |
87 } |
89 |
88 |
90 return isXTestAvailable; |
89 return isXTestAvailable; |
91 } |
90 } |
92 |
91 |
93 static void getNumButtons() { |
|
94 int32_t major_opcode, first_event, first_error; |
|
95 int32_t xinputAvailable; |
|
96 int32_t numDevices, devIdx, clsIdx; |
|
97 XDeviceInfo* devices; |
|
98 XDeviceInfo* aDevice; |
|
99 XButtonInfo* bInfo; |
|
100 |
|
101 /* 4700242: |
|
102 * If XTest is asked to press a non-existant mouse button |
|
103 * (i.e. press Button3 on a system configured with a 2-button mouse), |
|
104 * then a crash may happen. To avoid this, we use the XInput |
|
105 * extension to query for the number of buttons on the XPointer, and check |
|
106 * before calling XTestFakeButtonEvent(). |
|
107 */ |
|
108 xinputAvailable = XQueryExtension(awt_display, INAME, &major_opcode, &first_event, &first_error); |
|
109 DTRACE_PRINTLN3("RobotPeer: XQueryExtension(XINPUT) returns major_opcode = %d, first_event = %d, first_error = %d", |
|
110 major_opcode, first_event, first_error); |
|
111 if (xinputAvailable) { |
|
112 devices = XListInputDevices(awt_display, &numDevices); |
|
113 for (devIdx = 0; devIdx < numDevices; devIdx++) { |
|
114 aDevice = &(devices[devIdx]); |
|
115 if (aDevice->use == IsXPointer) { |
|
116 for (clsIdx = 0; clsIdx < aDevice->num_classes; clsIdx++) { |
|
117 if (aDevice->inputclassinfo[clsIdx].class == ButtonClass) { |
|
118 bInfo = (XButtonInfo*)(&(aDevice->inputclassinfo[clsIdx])); |
|
119 num_buttons = bInfo->num_buttons; |
|
120 DTRACE_PRINTLN1("RobotPeer: XPointer has %d buttons", num_buttons); |
|
121 break; |
|
122 } |
|
123 } |
|
124 break; |
|
125 } |
|
126 } |
|
127 XFreeDeviceList(devices); |
|
128 } |
|
129 else { |
|
130 DTRACE_PRINTLN1("RobotPeer: XINPUT extension is unavailable, assuming %d mouse buttons", num_buttons); |
|
131 } |
|
132 } |
|
133 |
92 |
134 static XImage *getWindowImage(Display * display, Window window, |
93 static XImage *getWindowImage(Display * display, Window window, |
135 int32_t x, int32_t y, |
94 int32_t x, int32_t y, |
136 int32_t w, int32_t h) { |
95 int32_t w, int32_t h) { |
137 XImage *image; |
96 XImage *image; |
239 JNU_ThrowByName(env, "java/awt/AWTException", "java.awt.Robot requires your X server support the XTEST extension version 2.2"); |
198 JNU_ThrowByName(env, "java/awt/AWTException", "java.awt.Robot requires your X server support the XTEST extension version 2.2"); |
240 AWT_UNLOCK(); |
199 AWT_UNLOCK(); |
241 return; |
200 return; |
242 } |
201 } |
243 |
202 |
244 getNumButtons(); |
|
245 finally: |
203 finally: |
246 AWT_UNLOCK(); |
204 AWT_UNLOCK(); |
247 } |
205 } |
248 |
206 |
249 JNIEXPORT jint JNICALL |
|
250 Java_sun_awt_X11_XRobotPeer_getNumberOfButtonsImpl(JNIEnv *env, |
|
251 jclass cls) { |
|
252 // At the moment this routine being called we already should have an initialized num_buttons variable. |
|
253 return num_buttons; |
|
254 } |
|
255 |
207 |
256 JNIEXPORT void JNICALL |
208 JNIEXPORT void JNICALL |
257 Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env, |
209 Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env, |
258 jclass cls, |
210 jclass cls, |
259 jobject xgc, |
211 jobject xgc, |
383 jclass cls, |
335 jclass cls, |
384 jint buttonMask, |
336 jint buttonMask, |
385 Bool isMousePress) |
337 Bool isMousePress) |
386 { |
338 { |
387 AWT_LOCK(); |
339 AWT_LOCK(); |
|
340 |
|
341 int32_t num_buttons = getNumButtons(); //from XToolkit.c |
388 |
342 |
389 DTRACE_PRINTLN1("RobotPeer: mouseAction(%i)", buttonMask); |
343 DTRACE_PRINTLN1("RobotPeer: mouseAction(%i)", buttonMask); |
390 DTRACE_PRINTLN1("RobotPeer: mouseAction, press = %d", isMousePress); |
344 DTRACE_PRINTLN1("RobotPeer: mouseAction, press = %d", isMousePress); |
391 |
345 |
392 if (buttonMask & java_awt_event_InputEvent_BUTTON1_MASK || |
346 if (buttonMask & java_awt_event_InputEvent_BUTTON1_MASK || |