--- old/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m 2017-08-22 13:53:08.236877700 +0530 +++ new/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m 2017-08-22 13:53:07.427124900 +0530 @@ -260,8 +260,16 @@ (JNIEnv *env, jobject peer, jint javaKeyCode, jboolean keyPressed) { CGKeyCode keyCode = GetCGKeyCode(javaKeyCode); + CGEventRef event; + + if(keyCode != OSX_Undefined) { + event = CGEventCreateKeyboardEvent(NULL, keyCode, keyPressed); + } else { + UniChar uCh = javaKeyCode; + event = CGEventCreateKeyboardEvent(NULL, 0, keyPressed); + CGEventKeyboardSetUnicodeString(event, 1, uCh); + } - CGEventRef event = CGEventCreateKeyboardEvent(NULL, keyCode, keyPressed); if (event != NULL) { CGEventPost(kCGSessionEventTap, event); CFRelease(event); @@ -286,7 +294,7 @@ jint picHeight = height; CGRect screenRect = CGRectMake(picX / scale, picY / scale, - picWidth / scale, picHeight / scale); + picWidth / scale, picHeight / scale); CGImageRef screenPixelsImage = CGWindowListCreateImage(screenRect, kCGWindowListOptionOnScreenOnly, kCGNullWindowID, kCGWindowImageBestResolution); --- old/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp 2017-08-22 13:53:12.908880200 +0530 +++ new/src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp 2017-08-22 13:53:12.109023500 +0530 @@ -316,9 +316,25 @@ // convert Java key into Windows key (and modifiers too) AwtComponent::JavaKeyToWindowsKey(jkey, &vkey, &modifiers); + if (vkey == 0) { - // no equivalent Windows key found for given Java keycode - JNU_ThrowIllegalArgumentException(env, "Invalid key code"); + /* vkey would be 0 for all non-ascii inputs. If non-ascii + then we assume they are unicode characters and will + supply such input to SendInput() which can handle unicode + characters as well as ascii chars. Windows provides api's to + handle ascii and unicode characters. All ascii characters + (both OEM and standard ascii) would be supplied to keybd_event(). + + HandleUnicodeKeys() returns the status of the SendInput() + which returns 0 if there is a fail else non-zero. + The status 0 tells that the SendInput() in unable to interpret + the supplied input upon which the illegal argument exception + would be raised. + */ + if(!HandleUnicodeKeys(jkey, dwFlags)) { + // no equivalent Windows key found for given Java keycode + JNU_ThrowIllegalArgumentException(env, "Invalid key code"); + } } else { // get the scancode from the virtual key scancode = ::MapVirtualKey(vkey, 0); @@ -339,6 +355,17 @@ } } +UINT AwtRobot::HandleUnicodeKeys(jint key, DWORD dwFlags) +{ + NSWinInput::INPUT ip; + ip.type = 1; //INPUT_KEYBOARD; + ip.ki.wVk = 0; + ip.ki.wScan = key; + ip.ki.dwFlags = (DWORD)(dwFlags | 4); //KEYEVENTF_UNICODE(4) + ip.ki.dwExtraInfo = 0; + return SendInput(1, (LPINPUT)&ip, sizeof(INPUT)); +} + // // utility function to get the C++ object from the Java one // --- old/src/java.desktop/windows/native/libawt/windows/awt_Robot.h 2017-08-22 13:53:17.560384200 +0530 +++ new/src/java.desktop/windows/native/libawt/windows/awt_Robot.h 2017-08-22 13:53:16.727478900 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2017, 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 @@ -31,6 +31,40 @@ #include "sun_awt_windows_WRobotPeer.h" #include "jlong.h" +namespace NSWinInput { + typedef struct tagHARDWAREINPUT { + DWORD uMsg; + WORD wParamL; + WORD wParamH; + } HARDWAREINPUT; + + typedef struct tagMOUSEINPUT { + LONG dx; + LONG dy; + DWORD mouseData; + DWORD dwFlags; + DWORD time; + ULONG_PTR dwExtraInfo; + } MOUSEINPUT; + + typedef struct tagKEYBDINPUT { + WORD wVk; + WORD wScan; + DWORD dwFlags; + DWORD time; + ULONG_PTR dwExtraInfo; + } KEYBDINPUT; + + typedef struct tagINPUT { + DWORD type; + union { + MOUSEINPUT mi; + KEYBDINPUT ki; + HARDWAREINPUT hi; + }; + } INPUT; +} + class AwtRobot : public AwtObject { public: @@ -52,6 +86,7 @@ private: void DoKeyEvent( jint jkey, DWORD dwFlags ); + UINT HandleUnicodeKeys(jint key, DWORD dwFlags); static jint WinToJavaPixel(USHORT r, USHORT g, USHORT b); };