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
23 * questions.
24 */
25
26
27 #import "jni_util.h"
28
29 #import <JavaNativeFoundation/JavaNativeFoundation.h>
30 #import <ApplicationServices/ApplicationServices.h>
31
32 #import "LWCToolkit.h"
33 #import "sun_lwawt_macosx_CRobot.h"
34 #import "java_awt_event_InputEvent.h"
35 #import "sizecalc.h"
36
37
38 // Starting number for event numbers generated by Robot.
39 // Apple docs don't mention at all what are the requirements
40 // for these numbers. It seems that they must be higher
41 // than event numbers from real events, which start at some
42 // value close to zero. There is no API for obtaining current
43 // event number, so we have to start from some random number.
44 // 32000 as starting value works for me, let's hope that it will
45 // work for others as well.
46 #define ROBOT_EVENT_NUMBER_START 32000
47
48 #define k_JAVA_ROBOT_WHEEL_COUNT 1
49
50 #if !defined(kCGBitmapByteOrder32Host)
51 #define kCGBitmapByteOrder32Host 0
52 #endif
53
54 // In OS X, left and right mouse button share the same click count.
55 // That is, if one starts clicking the left button rapidly and then
56 // switches to the right button, then the click count will continue
337
338 JNF_COCOA_EXIT(env);
339 }
340
341 /****************************************************
342 * Helper methods
343 ****************************************************/
344
345 static void PostMouseEvent(const CGPoint point, CGMouseButton button,
346 CGEventType type, int clickCount, int eventNumber)
347 {
348 CGEventRef mouseEvent = CGEventCreateMouseEvent(NULL, type, point, button);
349 if (mouseEvent != NULL) {
350 CGEventSetIntegerValueField(mouseEvent, kCGMouseEventClickState, clickCount);
351 CGEventSetIntegerValueField(mouseEvent, kCGMouseEventNumber, eventNumber);
352 CGEventPost(kCGSessionEventTap, mouseEvent);
353 CFRelease(mouseEvent);
354 }
355 }
356
357 // NOTE: Don't modify this table directly. It is machine generated. See below.
358 static const unsigned char javaToMacKeyCode[] = {
359 127, // 0 0 VK_UNDEFINED No_Equivalent
360 127, // 1 0x1 Not_Used
361 127, // 2 0x2 Not_Used
362 127, // 3 0x3 VK_CANCEL No_Equivalent
363 127, // 4 0x4 Not_Used
364 127, // 5 0x5 Not_Used
365 127, // 6 0x6 Not_Used
366 127, // 7 0x7 Not_Used
367 51, // 8 0x8 VK_BACK_SPACE
368 48, // 9 0x9 VK_TAB
369 36, // 10 0xa VK_ENTER
370 127, // 11 0xb Not_Used
371 71, // 12 0xc VK_CLEAR
372 127, // 13 0xd Not_Used
373 127, // 14 0xe Not_Used
374 127, // 15 0xf Not_Used
375 56, // 16 0x10 VK_SHIFT
376 59, // 17 0x11 VK_CONTROL
377 58, // 18 0x12 VK_ALT
378 113, // 19 0x13 VK_PAUSE
379 57, // 20 0x14 VK_CAPS_LOCK
380 127, // 21 0x15 VK_KANA No_Equivalent
381 127, // 22 0x16 Not_Used
382 127, // 23 0x17 Not_Used
383 127, // 24 0x18 VK_FINAL No_Equivalent
384 127, // 25 0x19 VK_KANJI No_Equivalent
385 127, // 26 0x1a Not_Used
386 53, // 27 0x1b VK_ESCAPE
387 127, // 28 0x1c VK_CONVERT No_Equivalent
388 127, // 29 0x1d VK_NONCONVERT No_Equivalent
389 127, // 30 0x1e VK_ACCEPT No_Equivalent
390 127, // 31 0x1f VK_MODECHANGE No_Equivalent
391 49, // 32 0x20 VK_SPACE
392 116, // 33 0x21 VK_PAGE_UP
393 121, // 34 0x22 VK_PAGE_DOWN
394 119, // 35 0x23 VK_END
395 115, // 36 0x24 VK_HOME
396 123, // 37 0x25 VK_LEFT
397 126, // 38 0x26 VK_UP
398 124, // 39 0x27 VK_RIGHT
399 125, // 40 0x28 VK_DOWN
400 127, // 41 0x29 Not_Used
401 127, // 42 0x2a Not_Used
402 127, // 43 0x2b Not_Used
403 43, // 44 0x2c VK_COMMA
404 27, // 45 0x2d VK_MINUS
405 47, // 46 0x2e VK_PERIOD
406 44, // 47 0x2f VK_SLASH
407 29, // 48 0x30 VK_0
408 18, // 49 0x31 VK_1
409 19, // 50 0x32 VK_2
410 20, // 51 0x33 VK_3
411 21, // 52 0x34 VK_4
412 23, // 53 0x35 VK_5
413 22, // 54 0x36 VK_6
414 26, // 55 0x37 VK_7
415 28, // 56 0x38 VK_8
416 25, // 57 0x39 VK_9
417 127, // 58 0x3a Not_Used
418 41, // 59 0x3b VK_SEMICOLON
419 127, // 60 0x3c Not_Used
420 24, // 61 0x3d VK_EQUALS
421 127, // 62 0x3e Not_Used
422 127, // 63 0x3f Not_Used
423 127, // 64 0x40 Not_Used
424 0, // 65 0x41 VK_A
425 11, // 66 0x42 VK_B
426 8, // 67 0x43 VK_C
427 2, // 68 0x44 VK_D
428 14, // 69 0x45 VK_E
429 3, // 70 0x46 VK_F
430 5, // 71 0x47 VK_G
431 4, // 72 0x48 VK_H
432 34, // 73 0x49 VK_I
433 38, // 74 0x4a VK_J
434 40, // 75 0x4b VK_K
435 37, // 76 0x4c VK_L
436 46, // 77 0x4d VK_M
437 45, // 78 0x4e VK_N
438 31, // 79 0x4f VK_O
439 35, // 80 0x50 VK_P
440 12, // 81 0x51 VK_Q
441 15, // 82 0x52 VK_R
442 1, // 83 0x53 VK_S
443 17, // 84 0x54 VK_T
444 32, // 85 0x55 VK_U
445 9, // 86 0x56 VK_V
446 13, // 87 0x57 VK_W
447 7, // 88 0x58 VK_X
448 16, // 89 0x59 VK_Y
449 6, // 90 0x5a VK_Z
450 33, // 91 0x5b VK_OPEN_BRACKET
451 42, // 92 0x5c VK_BACK_SLASH
452 30, // 93 0x5d VK_CLOSE_BRACKET
453 127, // 94 0x5e Not_Used
454 127, // 95 0x5f Not_Used
455 82, // 96 0x60 VK_NUMPAD0
456 83, // 97 0x61 VK_NUMPAD1
457 84, // 98 0x62 VK_NUMPAD2
458 85, // 99 0x63 VK_NUMPAD3
459 86, // 100 0x64 VK_NUMPAD4
460 87, // 101 0x65 VK_NUMPAD5
461 88, // 102 0x66 VK_NUMPAD6
462 89, // 103 0x67 VK_NUMPAD7
463 91, // 104 0x68 VK_NUMPAD8
464 92, // 105 0x69 VK_NUMPAD9
465 67, // 106 0x6a VK_MULTIPLY
466 69, // 107 0x6b VK_ADD
467 127, // 108 0x6c VK_SEPARATER No_Equivalent
468 78, // 109 0x6d VK_SUBTRACT
469 65, // 110 0x6e VK_DECIMAL
470 75, // 111 0x6f VK_DIVIDE
471 122, // 112 0x70 VK_F1
472 120, // 113 0x71 VK_F2
473 99, // 114 0x72 VK_F3
474 118, // 115 0x73 VK_F4
475 96, // 116 0x74 VK_F5
476 97, // 117 0x75 VK_F6
477 98, // 118 0x76 VK_F7
478 100, // 119 0x77 VK_F8
479 101, // 120 0x78 VK_F9
480 109, // 121 0x79 VK_F10
481 103, // 122 0x7a VK_F11
482 111, // 123 0x7b VK_F12
483 127, // 124 0x7c Not_Used
484 127, // 125 0x7d Not_Used
485 127, // 126 0x7e Not_Used
486 117, // 127 0x7f VK_DELETE
487 127, // 128 0x80 VK_DEAD_GRAVE No_Equivalent
488 127, // 129 0x81 VK_DEAD_ACUTE No_Equivalent
489 127, // 130 0x82 VK_DEAD_CIRCUMFLEX No_Equivalent
490 127, // 131 0x83 VK_DEAD_TILDE No_Equivalent
491 127, // 132 0x84 VK_DEAD_MACRON No_Equivalent
492 127, // 133 0x85 VK_DEAD_BREVE No_Equivalent
493 127, // 134 0x86 VK_DEAD_ABOVEDOT No_Equivalent
494 127, // 135 0x87 VK_DEAD_DIAERESIS No_Equivalent
495 127, // 136 0x88 VK_DEAD_ABOVERING No_Equivalent
496 127, // 137 0x89 VK_DEAD_DOUBLEACUTE No_Equivalent
497 127, // 138 0x8a VK_DEAD_CARON No_Equivalent
498 127, // 139 0x8b VK_DEAD_CEDILLA No_Equivalent
499 127, // 140 0x8c VK_DEAD_OGONEK No_Equivalent
500 127, // 141 0x8d VK_DEAD_IOTA No_Equivalent
501 127, // 142 0x8e VK_DEAD_VOICED_SOUND No_Equivalent
502 127, // 143 0x8f VK_DEAD_SEMIVOICED_SOUND No_Equivalent
503 127, // 144 0x90 VK_NUM_LOCK No_Equivalent
504 107, // 145 0x91 VK_SCROLL_LOCK
505 127, // 146 0x92 Not_Used
506 127, // 147 0x93 Not_Used
507 127, // 148 0x94 Not_Used
508 127, // 149 0x95 Not_Used
509 127, // 150 0x96 VK_AMPERSAND No_Equivalent
510 127, // 151 0x97 VK_ASTERISK No_Equivalent
511 127, // 152 0x98 VK_QUOTEDBL No_Equivalent
512 127, // 153 0x99 VK_LESS No_Equivalent
513 105, // 154 0x9a VK_PRINTSCREEN
514 127, // 155 0x9b VK_INSERT No_Equivalent
515 114, // 156 0x9c VK_HELP
516 55, // 157 0x9d VK_META
517 127, // 158 0x9e Not_Used
518 127, // 159 0x9f Not_Used
519 127, // 160 0xa0 VK_GREATER No_Equivalent
520 127, // 161 0xa1 VK_BRACELEFT No_Equivalent
521 127, // 162 0xa2 VK_BRACERIGHT No_Equivalent
522 127, // 163 0xa3 Not_Used
523 127, // 164 0xa4 Not_Used
524 127, // 165 0xa5 Not_Used
525 127, // 166 0xa6 Not_Used
526 127, // 167 0xa7 Not_Used
527 127, // 168 0xa8 Not_Used
528 127, // 169 0xa9 Not_Used
529 127, // 170 0xaa Not_Used
530 127, // 171 0xab Not_Used
531 127, // 172 0xac Not_Used
532 127, // 173 0xad Not_Used
533 127, // 174 0xae Not_Used
534 127, // 175 0xaf Not_Used
535 127, // 176 0xb0 Not_Used
536 127, // 177 0xb1 Not_Used
537 127, // 178 0xb2 Not_Used
538 127, // 179 0xb3 Not_Used
539 127, // 180 0xb4 Not_Used
540 127, // 181 0xb5 Not_Used
541 127, // 182 0xb6 Not_Used
542 127, // 183 0xb7 Not_Used
543 127, // 184 0xb8 Not_Used
544 127, // 185 0xb9 Not_Used
545 127, // 186 0xba Not_Used
546 127, // 187 0xbb Not_Used
547 127, // 188 0xbc Not_Used
548 127, // 189 0xbd Not_Used
549 127, // 190 0xbe Not_Used
550 127, // 191 0xbf Not_Used
551 50, // 192 0xc0 VK_BACK_QUOTE
552 127, // 193 0xc1 Not_Used
553 127, // 194 0xc2 Not_Used
554 127, // 195 0xc3 Not_Used
555 127, // 196 0xc4 Not_Used
556 127, // 197 0xc5 Not_Used
557 127, // 198 0xc6 Not_Used
558 127, // 199 0xc7 Not_Used
559 127, // 200 0xc8 Not_Used
560 127, // 201 0xc9 Not_Used
561 127, // 202 0xca Not_Used
562 127, // 203 0xcb Not_Used
563 127, // 204 0xcc Not_Used
564 127, // 205 0xcd Not_Used
565 127, // 206 0xce Not_Used
566 127, // 207 0xcf Not_Used
567 127, // 208 0xd0 Not_Used
568 127, // 209 0xd1 Not_Used
569 127, // 210 0xd2 Not_Used
570 127, // 211 0xd3 Not_Used
571 127, // 212 0xd4 Not_Used
572 127, // 213 0xd5 Not_Used
573 127, // 214 0xd6 Not_Used
574 127, // 215 0xd7 Not_Used
575 127, // 216 0xd8 Not_Used
576 127, // 217 0xd9 Not_Used
577 127, // 218 0xda Not_Used
578 127, // 219 0xdb Not_Used
579 127, // 220 0xdc Not_Used
580 127, // 221 0xdd Not_Used
581 39 // 222 0xde VK_QUOTE
582 };
583
584 // NOTE: All values above 222 don't have an equivalent on MacOSX.
585 static inline CGKeyCode GetCGKeyCode(jint javaKeyCode)
586 {
587 if (javaKeyCode > 222) {
588 return 127;
589 } else {
590 return javaToMacKeyCode[javaKeyCode];
591 }
592 }
593
594 static int GetClickCount(BOOL isDown) {
595 NSTimeInterval now = [[NSDate date] timeIntervalSinceReferenceDate];
596 NSTimeInterval clickInterval = now - gsLastClickTime;
597 BOOL isWithinTreshold = clickInterval < [NSEvent doubleClickInterval];
598
599 if (isDown) {
600 if (isWithinTreshold) {
601 gsClickCount++;
602 } else {
603 gsClickCount = 1;
604 }
605
606 gsLastClickTime = now;
607 } else {
608 // In OS X, a mouse up has the click count of the last mouse down
609 // if an interval between up and down is within the double click
610 // threshold, and 0 otherwise.
611 if (!isWithinTreshold) {
|
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
23 * questions.
24 */
25
26
27 #import "jni_util.h"
28
29 #import <JavaNativeFoundation/JavaNativeFoundation.h>
30 #import <ApplicationServices/ApplicationServices.h>
31
32 #import "LWCToolkit.h"
33 #import "sun_lwawt_macosx_CRobot.h"
34 #import "java_awt_event_InputEvent.h"
35 #import "sizecalc.h"
36 #import "CRobotKeyCode.h"
37
38 // Starting number for event numbers generated by Robot.
39 // Apple docs don't mention at all what are the requirements
40 // for these numbers. It seems that they must be higher
41 // than event numbers from real events, which start at some
42 // value close to zero. There is no API for obtaining current
43 // event number, so we have to start from some random number.
44 // 32000 as starting value works for me, let's hope that it will
45 // work for others as well.
46 #define ROBOT_EVENT_NUMBER_START 32000
47
48 #define k_JAVA_ROBOT_WHEEL_COUNT 1
49
50 #if !defined(kCGBitmapByteOrder32Host)
51 #define kCGBitmapByteOrder32Host 0
52 #endif
53
54 // In OS X, left and right mouse button share the same click count.
55 // That is, if one starts clicking the left button rapidly and then
56 // switches to the right button, then the click count will continue
337
338 JNF_COCOA_EXIT(env);
339 }
340
341 /****************************************************
342 * Helper methods
343 ****************************************************/
344
345 static void PostMouseEvent(const CGPoint point, CGMouseButton button,
346 CGEventType type, int clickCount, int eventNumber)
347 {
348 CGEventRef mouseEvent = CGEventCreateMouseEvent(NULL, type, point, button);
349 if (mouseEvent != NULL) {
350 CGEventSetIntegerValueField(mouseEvent, kCGMouseEventClickState, clickCount);
351 CGEventSetIntegerValueField(mouseEvent, kCGMouseEventNumber, eventNumber);
352 CGEventPost(kCGSessionEventTap, mouseEvent);
353 CFRelease(mouseEvent);
354 }
355 }
356
357 static inline CGKeyCode GetCGKeyCode(jint javaKeyCode)
358 {
359 int retval;
360
361 CRobotKeyCodeMapping *objCRobotKeyCodeMapping = [CRobotKeyCodeMapping sharedInstance];
362 retval = [objCRobotKeyCodeMapping getOSXKeyCodeForJavaKey:javaKeyCode];
363
364 return retval;
365 }
366
367 static int GetClickCount(BOOL isDown) {
368 NSTimeInterval now = [[NSDate date] timeIntervalSinceReferenceDate];
369 NSTimeInterval clickInterval = now - gsLastClickTime;
370 BOOL isWithinTreshold = clickInterval < [NSEvent doubleClickInterval];
371
372 if (isDown) {
373 if (isWithinTreshold) {
374 gsClickCount++;
375 } else {
376 gsClickCount = 1;
377 }
378
379 gsLastClickTime = now;
380 } else {
381 // In OS X, a mouse up has the click count of the last mouse down
382 // if an interval between up and down is within the double click
383 // threshold, and 0 otherwise.
384 if (!isWithinTreshold) {
|