summaryrefslogtreecommitdiffstats
path: root/src/newt/native
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/native')
-rw-r--r--src/newt/native/KeyEvent.h389
-rw-r--r--src/newt/native/NewtCommon.c9
-rw-r--r--src/newt/native/NewtCommon.h2
-rw-r--r--src/newt/native/NewtMacWindow.m158
-rw-r--r--src/newt/native/WindowsWindow.c36
-rw-r--r--src/newt/native/X11Display.c113
-rw-r--r--src/newt/native/X11Window.c4
7 files changed, 422 insertions, 289 deletions
diff --git a/src/newt/native/KeyEvent.h b/src/newt/native/KeyEvent.h
index 0f7b1606b..7a63b19ce 100644
--- a/src/newt/native/KeyEvent.h
+++ b/src/newt/native/KeyEvent.h
@@ -33,195 +33,206 @@
#define EVENT_KEY_RELEASED 301
#define EVENT_KEY_TYPED 302
-#define J_CHAR_UNDEFINED 0xFFFF;
-#define J_VK_ENTER '\n'
-#define J_VK_BACK_SPACE '\b'
-#define J_VK_TAB '\t'
-#define J_VK_CANCEL 0x03
-#define J_VK_CLEAR 0x0C
-#define J_VK_SHIFT 0x10
-#define J_VK_CONTROL 0x11
-#define J_VK_ALT 0x12
-#define J_VK_PAUSE 0x13
-#define J_VK_CAPS_LOCK 0x14
-#define J_VK_ESCAPE 0x1B
-#define J_VK_SPACE 0x20
-#define J_VK_PAGE_UP 0x21
-#define J_VK_PAGE_DOWN 0x22
-#define J_VK_END 0x23
-#define J_VK_HOME 0x24
-#define J_VK_LEFT 0x25
-#define J_VK_UP 0x26
-#define J_VK_RIGHT 0x27
-#define J_VK_DOWN 0x28
-#define J_VK_COMMA 0x2C
-#define J_VK_MINUS 0x2D
-#define J_VK_PERIOD 0x2E
-#define J_VK_SLASH 0x2F
-#define J_VK_0 0x30
-#define J_VK_1 0x31
-#define J_VK_2 0x32
-#define J_VK_3 0x33
-#define J_VK_4 0x34
-#define J_VK_5 0x35
-#define J_VK_6 0x36
-#define J_VK_7 0x37
-#define J_VK_8 0x38
-#define J_VK_9 0x39
-#define J_VK_SEMICOLON 0x3B
-#define J_VK_EQUALS 0x3D
-#define J_VK_A 0x41
-#define J_VK_B 0x42
-#define J_VK_C 0x43
-#define J_VK_D 0x44
-#define J_VK_E 0x45
-#define J_VK_F 0x46
-#define J_VK_G 0x47
-#define J_VK_H 0x48
-#define J_VK_I 0x49
-#define J_VK_J 0x4A
-#define J_VK_K 0x4B
-#define J_VK_L 0x4C
-#define J_VK_M 0x4D
-#define J_VK_N 0x4E
-#define J_VK_O 0x4F
-#define J_VK_P 0x50
-#define J_VK_Q 0x51
-#define J_VK_R 0x52
-#define J_VK_S 0x53
-#define J_VK_T 0x54
-#define J_VK_U 0x55
-#define J_VK_V 0x56
-#define J_VK_W 0x57
-#define J_VK_X 0x58
-#define J_VK_Y 0x59
-#define J_VK_Z 0x5A
-#define J_VK_OPEN_BRACKET 0x5B
-#define J_VK_BACK_SLASH 0x5C
-#define J_VK_CLOSE_BRACKET 0x5D
-#define J_VK_NUMPAD0 0x60
-#define J_VK_NUMPAD1 0x61
-#define J_VK_NUMPAD2 0x62
-#define J_VK_NUMPAD3 0x63
-#define J_VK_NUMPAD4 0x64
-#define J_VK_NUMPAD5 0x65
-#define J_VK_NUMPAD6 0x66
-#define J_VK_NUMPAD7 0x67
-#define J_VK_NUMPAD8 0x68
-#define J_VK_NUMPAD9 0x69
-#define J_VK_MULTIPLY 0x6A
-#define J_VK_ADD 0x6B
-#define J_VK_SEPARATOR 0x6C
-#define J_VK_SUBTRACT 0x6D
-#define J_VK_DECIMAL 0x6E
-#define J_VK_DIVIDE 0x6F
-#define J_VK_DELETE 0x7F /* ASCII DEL */
-#define J_VK_NUM_LOCK 0x90
-#define J_VK_SCROLL_LOCK 0x91
-#define J_VK_F1 0x70
-#define J_VK_F2 0x71
-#define J_VK_F3 0x72
-#define J_VK_F4 0x73
-#define J_VK_F5 0x74
-#define J_VK_F6 0x75
-#define J_VK_F7 0x76
-#define J_VK_F8 0x77
-#define J_VK_F9 0x78
-#define J_VK_F10 0x79
-#define J_VK_F11 0x7A
-#define J_VK_F12 0x7B
-#define J_VK_F13 0xF000
-#define J_VK_F14 0xF001
-#define J_VK_F15 0xF002
-#define J_VK_F16 0xF003
-#define J_VK_F17 0xF004
-#define J_VK_F18 0xF005
-#define J_VK_F19 0xF006
-#define J_VK_F20 0xF007
-#define J_VK_F21 0xF008
-#define J_VK_F22 0xF009
-#define J_VK_F23 0xF00A
-#define J_VK_F24 0xF00B
-#define J_VK_PRINTSCREEN 0x9A
-#define J_VK_INSERT 0x9B
-#define J_VK_HELP 0x9C
-#define J_VK_META 0x9D
-#define J_VK_BACK_QUOTE 0xC0
-#define J_VK_QUOTE 0xDE
-#define J_VK_KP_UP 0xE0
-#define J_VK_KP_DOWN 0xE1
-#define J_VK_KP_LEFT 0xE2
-#define J_VK_KP_RIGHT 0xE3
-#define J_VK_DEAD_GRAVE 0x80
-#define J_VK_DEAD_ACUTE 0x81
-#define J_VK_DEAD_CIRCUMFLEX 0x82
-#define J_VK_DEAD_TILDE 0x83
-#define J_VK_DEAD_MACRON 0x84
-#define J_VK_DEAD_BREVE 0x85
-#define J_VK_DEAD_ABOVEDOT 0x86
-#define J_VK_DEAD_DIAERESIS 0x87
-#define J_VK_DEAD_ABOVERING 0x88
-#define J_VK_DEAD_DOUBLEACUTE 0x89
-#define J_VK_DEAD_CARON 0x8a
-#define J_VK_DEAD_CEDILLA 0x8b
-#define J_VK_DEAD_OGONEK 0x8c
-#define J_VK_DEAD_IOTA 0x8d
-#define J_VK_DEAD_VOICED_SOUND 0x8e
-#define J_VK_DEAD_SEMIVOICED_SOUND 0x8f
-#define J_VK_AMPERSAND 0x96
-#define J_VK_ASTERISK 0x97
-#define J_VK_QUOTEDBL 0x98
-#define J_VK_LESS 0x99
-#define J_VK_GREATER 0xa0
-#define J_VK_BRACELEFT 0xa1
-#define J_VK_BRACERIGHT 0xa2
-#define J_VK_AT 0x0200
-#define J_VK_COLON 0x0201
-#define J_VK_CIRCUMFLEX 0x0202
-#define J_VK_DOLLAR 0x0203
-#define J_VK_EURO_SIGN 0x0204
-#define J_VK_EXCLAMATION_MARK 0x0205
-#define J_VK_INVERTED_EXCLAMATION_MARK 0x0206
-#define J_VK_LEFT_PARENTHESIS 0x0207
-#define J_VK_NUMBER_SIGN 0x0208
-#define J_VK_PLUS 0x0209
-#define J_VK_RIGHT_PARENTHESIS 0x020A
-#define J_VK_UNDERSCORE 0x020B
-#define J_VK_WINDOWS 0x020C
-#define J_VK_CONTEXT_MENU 0x020D
-#define J_VK_FINAL 0x0018
-#define J_VK_CONVERT 0x001C
-#define J_VK_NONCONVERT 0x001D
-#define J_VK_ACCEPT 0x001E
-#define J_VK_MODECHANGE 0x001F
-#define J_VK_KANA 0x0015
-#define J_VK_KANJI 0x0019
-#define J_VK_ALPHANUMERIC 0x00F0
-#define J_VK_KATAKANA 0x00F1
-#define J_VK_HIRAGANA 0x00F2
-#define J_VK_FULL_WIDTH 0x00F3
-#define J_VK_HALF_WIDTH 0x00F4
-#define J_VK_ROMAN_CHARACTERS 0x00F5
-#define J_VK_ALL_CANDIDATES 0x0100
-#define J_VK_PREVIOUS_CANDIDATE 0x0101
-#define J_VK_CODE_INPUT 0x0102
-#define J_VK_JAPANESE_KATAKANA 0x0103
-#define J_VK_JAPANESE_HIRAGANA 0x0104
-#define J_VK_JAPANESE_ROMAN 0x0105
-#define J_VK_KANA_LOCK 0x0106
-#define J_VK_INPUT_METHOD_ON_OFF 0x0107
-#define J_VK_CUT 0xFFD1
-#define J_VK_COPY 0xFFCD
-#define J_VK_PASTE 0xFFCF
-#define J_VK_UNDO 0xFFCB
-#define J_VK_AGAIN 0xFFC9
-#define J_VK_FIND 0xFFD0
-#define J_VK_PROPS 0xFFCA
-#define J_VK_STOP 0xFFC8
-#define J_VK_COMPOSE 0xFF20
-#define J_VK_ALT_GRAPH 0xFF7E
-#define J_VK_BEGIN 0xFF58
-#define J_VK_UNDEFINED 0x0
+#define J_VK_UNDEFINED ( 0x0U )
+#define J_VK_HOME ( 0x02U )
+#define J_VK_END ( 0x03U )
+#define J_VK_FINAL ( 0x04U )
+#define J_VK_PRINTSCREEN ( 0x05U )
+#define J_VK_BACK_SPACE ( 0x08U )
+#define J_VK_TAB ( 0x09U )
+#define J_VK_ENTER ( 0x0AU )
+#define J_VK_PAGE_DOWN ( 0x0BU )
+#define J_VK_CLEAR ( 0x0CU )
+#define J_VK_SHIFT ( 0x0FU )
+#define J_VK_PAGE_UP ( 0x10U )
+#define J_VK_CONTROL ( 0x11U )
+#define J_VK_ALT ( 0x12U )
+#define J_VK_ALT_GRAPH ( 0x13U )
+#define J_VK_CAPS_LOCK ( 0x14U )
+#define J_VK_PAUSE ( 0x16U )
+#define J_VK_SCROLL_LOCK ( 0x17U )
+#define J_VK_CANCEL ( 0x18U )
+#define J_VK_INSERT ( 0x1AU )
+#define J_VK_ESCAPE ( 0x1BU )
+#define J_VK_CONVERT ( 0x1CU )
+#define J_VK_NONCONVERT ( 0x1DU )
+#define J_VK_ACCEPT ( 0x1EU )
+#define J_VK_MODECHANGE ( 0x1FU )
+
+//
+// Unicode: Printable [0x20 - 0x7E]
+//
+
+#define J_VK_SPACE ( 0x20U )
+#define J_VK_EXCLAMATION_MARK ( 0x21U )
+#define J_VK_QUOTEDBL ( 0x22U )
+#define J_VK_NUMBER_SIGN ( 0x23U )
+#define J_VK_DOLLAR ( 0x24U )
+#define J_VK_PERCENT ( 0x25U )
+#define J_VK_AMPERSAND ( 0x26U )
+#define J_VK_QUOTE ( 0x27U )
+#define J_VK_LEFT_PARENTHESIS ( 0x28U )
+#define J_VK_RIGHT_PARENTHESIS ( 0x29U )
+#define J_VK_ASTERISK ( 0x2AU )
+#define J_VK_PLUS ( 0x2BU )
+#define J_VK_COMMA ( 0x2CU )
+#define J_VK_MINUS ( 0x2DU )
+#define J_VK_PERIOD ( 0x2EU )
+#define J_VK_SLASH ( 0x2FU )
+#define J_VK_0 ( 0x30U )
+#define J_VK_1 ( 0x31U )
+#define J_VK_2 ( 0x32U )
+#define J_VK_3 ( 0x33U )
+#define J_VK_4 ( 0x34U )
+#define J_VK_5 ( 0x35U )
+#define J_VK_6 ( 0x36U )
+#define J_VK_7 ( 0x37U )
+#define J_VK_8 ( 0x38U )
+#define J_VK_9 ( 0x39U )
+#define J_VK_COLON ( 0x3AU )
+#define J_VK_SEMICOLON ( 0x3BU )
+#define J_VK_LESS ( 0x3CU )
+#define J_VK_EQUALS ( 0x3DU )
+#define J_VK_GREATER ( 0x3EU )
+#define J_VK_QUESTIONMARK ( 0x3FU )
+#define J_VK_AT ( 0x40U )
+#define J_VK_A ( 0x41U )
+#define J_VK_B ( 0x42U )
+#define J_VK_C ( 0x43U )
+#define J_VK_D ( 0x44U )
+#define J_VK_E ( 0x45U )
+#define J_VK_F ( 0x46U )
+#define J_VK_G ( 0x47U )
+#define J_VK_H ( 0x48U )
+#define J_VK_I ( 0x49U )
+#define J_VK_J ( 0x4AU )
+#define J_VK_K ( 0x4BU )
+#define J_VK_L ( 0x4CU )
+#define J_VK_M ( 0x4DU )
+#define J_VK_N ( 0x4EU )
+#define J_VK_O ( 0x4FU )
+#define J_VK_P ( 0x50U )
+#define J_VK_Q ( 0x51U )
+#define J_VK_R ( 0x52U )
+#define J_VK_S ( 0x53U )
+#define J_VK_T ( 0x54U )
+#define J_VK_U ( 0x55U )
+#define J_VK_V ( 0x56U )
+#define J_VK_W ( 0x57U )
+#define J_VK_X ( 0x58U )
+#define J_VK_Y ( 0x59U )
+#define J_VK_Z ( 0x5AU )
+#define J_VK_OPEN_BRACKET ( 0x5BU )
+#define J_VK_BACK_SLASH ( 0x5CU )
+#define J_VK_CLOSE_BRACKET ( 0x5DU )
+#define J_VK_CIRCUMFLEX ( 0x5EU )
+#define J_VK_UNDERSCORE ( 0x5FU )
+#define J_VK_BACK_QUOTE ( 0x60U )
+#define J_VK_F1 ( 0x60U+ 1U )
+#define J_VK_F2 ( 0x60U+ 2U )
+#define J_VK_F3 ( 0x60U+ 3U )
+#define J_VK_F4 ( 0x60U+ 4U )
+#define J_VK_F5 ( 0x60U+ 5U )
+#define J_VK_F6 ( 0x60U+ 6U )
+#define J_VK_F7 ( 0x60U+ 7U )
+#define J_VK_F8 ( 0x60U+ 8U )
+#define J_VK_F9 ( 0x60U+ 9U )
+#define J_VK_F10 ( 0x60U+10U )
+#define J_VK_F11 ( 0x60U+11U )
+#define J_VK_F12 ( 0x60U+12U )
+#define J_VK_F13 ( 0x60U+13U )
+#define J_VK_F14 ( 0x60U+14U )
+#define J_VK_F15 ( 0x60U+15U )
+#define J_VK_F16 ( 0x60U+16U )
+#define J_VK_F17 ( 0x60U+17U )
+#define J_VK_F18 ( 0x60U+18U )
+#define J_VK_F19 ( 0x60U+19U )
+#define J_VK_F20 ( 0x60U+20U )
+#define J_VK_F21 ( 0x60U+21U )
+#define J_VK_F22 ( 0x60U+22U )
+#define J_VK_F23 ( 0x60U+23U )
+#define J_VK_F24 ( 0x60U+24U )
+#define J_VK_LEFT_BRACE ( 0x7BU )
+#define J_VK_PIPE ( 0x7CU )
+#define J_VK_RIGHT_BRACE ( 0x7DU )
+#define J_VK_TILDE ( 0x7EU )
+
+//
+// Unicode: Non printable controls: [0x7F - 0x9F]
+//
+
+#define J_VK_DELETE ( 0x7FU )
+#define J_VK_NUMPAD0 ( 0x80U )
+#define J_VK_NUMPAD1 ( 0x81U )
+#define J_VK_NUMPAD2 ( 0x82U )
+#define J_VK_NUMPAD3 ( 0x83U )
+#define J_VK_NUMPAD4 ( 0x84U )
+#define J_VK_NUMPAD5 ( 0x85U )
+#define J_VK_NUMPAD6 ( 0x86U )
+#define J_VK_NUMPAD7 ( 0x87U )
+#define J_VK_NUMPAD8 ( 0x88U )
+#define J_VK_NUMPAD9 ( 0x89U )
+#define J_VK_DECIMAL ( 0x8AU )
+#define J_VK_SEPARATOR ( 0x8BU )
+#define J_VK_ADD ( 0x8CU )
+#define J_VK_SUBTRACT ( 0x8DU )
+#define J_VK_MULTIPLY ( 0x8EU )
+#define J_VK_DIVIDE ( 0x8FU )
+#define J_VK_NUM_LOCK ( 0x90U )
+#define J_VK_KP_LEFT ( 0x91U )
+#define J_VK_KP_UP ( 0x92U )
+#define J_VK_KP_RIGHT ( 0x93U )
+#define J_VK_KP_DOWN ( 0x94U )
+#define J_VK_LEFT ( 0x95U )
+#define J_VK_UP ( 0x96U )
+#define J_VK_RIGHT ( 0x97U )
+#define J_VK_DOWN ( 0x98U )
+#define J_VK_CONTEXT_MENU ( 0x99U )
+#define J_VK_WINDOWS ( 0x9AU )
+#define J_VK_META ( 0x9BU )
+#define J_VK_HELP ( 0x9CU )
+#define J_VK_COMPOSE ( 0x9DU )
+#define J_VK_BEGIN ( 0x9EU )
+#define J_VK_STOP ( 0x9FU )
+
+
+//
+// Unicode: Printable [0x00A0 - 0xDFFF]
+//
+
+#define J_VK_INVERTED_EXCLAMATION_MARK ( 0xA1U )
+#define J_VK_EURO_SIGN ( 0x20ACU )
+
+//
+// Unicode: Private 0xE000 - 0xF8FF (Marked Non-Printable)
+//
+
+/* for Sun keyboards */
+#define J_VK_CUT ( 0xF879U )
+#define J_VK_COPY ( 0xF87AU )
+#define J_VK_PASTE ( 0xF87BU )
+#define J_VK_UNDO ( 0xF87CU )
+#define J_VK_AGAIN ( 0xF87DU )
+#define J_VK_FIND ( 0xF87EU )
+#define J_VK_PROPS ( 0xF87FU )
+
+/* for input method support on Asian Keyboards */
+#define J_VK_INPUT_METHOD_ON_OFF ( 0xF890U )
+#define J_VK_CODE_INPUT ( 0xF891U )
+#define J_VK_ROMAN_CHARACTERS ( 0xF892U )
+#define J_VK_ALL_CANDIDATES ( 0xF893U )
+#define J_VK_PREVIOUS_CANDIDATE ( 0xF894U )
+#define J_VK_ALPHANUMERIC ( 0xF895U )
+#define J_VK_KATAKANA ( 0xF896U )
+#define J_VK_HIRAGANA ( 0xF897U )
+#define J_VK_FULL_WIDTH ( 0xF898U )
+#define J_VK_HALF_WIDTH ( 0xF89AU )
+#define J_VK_JAPANESE_KATAKANA ( 0xF89BU )
+#define J_VK_JAPANESE_HIRAGANA ( 0xF89CU )
+#define J_VK_JAPANESE_ROMAN ( 0xF89DU )
+#define J_VK_KANA_LOCK ( 0xF89FU )
+
+#define J_VK_KEYBOARD_INVISIBLE ( 0xF8FFU )
#endif
diff --git a/src/newt/native/NewtCommon.c b/src/newt/native/NewtCommon.c
index 7f070e7d3..c294b6e0b 100644
--- a/src/newt/native/NewtCommon.c
+++ b/src/newt/native/NewtCommon.c
@@ -72,7 +72,7 @@ jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str)
return strChars;
}
-JNIEnv* NewtCommon_GetJNIEnv(JavaVM * jvmHandle, int jvmVersion, int * shallBeDetached) {
+JNIEnv* NewtCommon_GetJNIEnv(JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached) {
JNIEnv* curEnv = NULL;
JNIEnv* newEnv = NULL;
int envRes;
@@ -81,7 +81,12 @@ JNIEnv* NewtCommon_GetJNIEnv(JavaVM * jvmHandle, int jvmVersion, int * shallBeDe
envRes = (*jvmHandle)->GetEnv(jvmHandle, (void **) &curEnv, jvmVersion) ;
if( JNI_EDETACHED == envRes ) {
// detached thread - attach to JVM
- if( JNI_OK != ( envRes = (*jvmHandle)->AttachCurrentThread(jvmHandle, (void**) &newEnv, NULL) ) ) {
+ if( asDaemon ) {
+ envRes = (*jvmHandle)->AttachCurrentThreadAsDaemon(jvmHandle, (void**) &newEnv, NULL);
+ } else {
+ envRes = (*jvmHandle)->AttachCurrentThread(jvmHandle, (void**) &newEnv, NULL);
+ }
+ if( JNI_OK != envRes ) {
fprintf(stderr, "JNIEnv: can't attach thread: %d\n", envRes);
return NULL;
}
diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h
index 9a4e5ac70..9cc9e93a6 100644
--- a/src/newt/native/NewtCommon.h
+++ b/src/newt/native/NewtCommon.h
@@ -76,6 +76,6 @@ void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...);
(*jvmHandle)->DetachCurrentThread(jvmHandle);
}
*/
-JNIEnv* NewtCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int * shallBeDetached);
+JNIEnv* NewtCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached);
#endif
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index d7b357349..005e82d72 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -36,6 +36,9 @@
#import "KeyEvent.h"
#import "MouseEvent.h"
+#include <CoreFoundation/CoreFoundation.h>
+#include <Carbon/Carbon.h> /* For kVK_ constants, and TIS functions. */
+
#include <math.h>
static jfloat GetDelta(NSEvent *event, jint javaMods[]) {
@@ -82,9 +85,7 @@ static jfloat GetDelta(NSEvent *event, jint javaMods[]) {
}
static jmethodID enqueueMouseEventID = NULL;
-static jmethodID sendMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
-static jmethodID sendKeyEventID = NULL;
static jmethodID requestFocusID = NULL;
static jmethodID insetsChangedID = NULL;
@@ -95,13 +96,11 @@ static jmethodID focusChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowRepaintID = NULL;
-// Can't use USE_SENDIO_DIRECT, ie w/o enqueueing to EDT,
+// Need to enqueue all events to EDT,
// since we may operate on AWT-AppKit (Main Thread)
// and direct issuing 'requestFocus()' would deadlock:
// AWT-AppKit
// AWT-EventQueue-0
-//
-// #define USE_SENDIO_DIRECT 1
@implementation NewtView
@@ -286,7 +285,7 @@ static jmethodID windowRepaintID = NULL;
return;
}
int shallBeDetached = 0;
- JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached);
if(NULL==env) {
DBG_PRINT("drawRect: null JNIEnv\n");
return;
@@ -298,9 +297,9 @@ static jmethodID windowRepaintID = NULL;
dirtyRect.origin.x, viewFrame.size.height - dirtyRect.origin.y,
dirtyRect.size.width, dirtyRect.size.height);
- if (shallBeDetached) {
+ /* if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
+ } */
}
- (void) viewDidHide
@@ -310,7 +309,7 @@ static jmethodID windowRepaintID = NULL;
return;
}
int shallBeDetached = 0;
- JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached);
if(NULL==env) {
DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
@@ -318,9 +317,9 @@ static jmethodID windowRepaintID = NULL;
(*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_FALSE);
- if (shallBeDetached) {
+ /* if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
+ } */
[super viewDidHide];
}
@@ -332,7 +331,7 @@ static jmethodID windowRepaintID = NULL;
return;
}
int shallBeDetached = 0;
- JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached);
if(NULL==env) {
DBG_PRINT("viewDidUnhide: null JNIEnv\n");
return;
@@ -340,9 +339,9 @@ static jmethodID windowRepaintID = NULL;
(*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_TRUE);
- if (shallBeDetached) {
+ /* if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
+ } */
[super viewDidUnhide];
}
@@ -354,14 +353,71 @@ static jmethodID windowRepaintID = NULL;
@end
+static CFStringRef CKCH_CreateStringForKey(CGKeyCode keyCode, const UCKeyboardLayout *keyboardLayout) {
+ UInt32 keysDown = 0;
+ UniChar chars[4];
+ UniCharCount realLength;
+
+ UCKeyTranslate(keyboardLayout, keyCode,
+ kUCKeyActionDisplay, 0,
+ LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit,
+ &keysDown, sizeof(chars) / sizeof(chars[0]), &realLength, chars);
+
+ return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1);
+}
+
+static CFMutableDictionaryRef CKCH_CreateCodeToCharDict(TISInputSourceRef keyboard) {
+ CFDataRef layoutData = (CFDataRef) TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData);
+ const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
+
+ CFMutableDictionaryRef codeToCharDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 128, NULL, NULL);
+ if ( NULL != codeToCharDict ) {
+ intptr_t i;
+ for (i = 0; i < 128; ++i) {
+ CFStringRef string = CKCH_CreateStringForKey((CGKeyCode)i, keyboardLayout);
+ if( NULL != string ) {
+ CFIndex stringLen = CFStringGetLength (string);
+ if ( 0 < stringLen ) {
+ UniChar character = CFStringGetCharacterAtIndex(string, 0);
+ DBG_PRINT("CKCH: MAP 0x%X -> %c\n", (int)i, character);
+ CFDictionaryAddValue(codeToCharDict, (const void *)i, (const void *)(intptr_t)character);
+ }
+ CFRelease(string);
+ }
+ }
+ }
+ return codeToCharDict;
+}
+
+static CFMutableDictionaryRef CKCH_USCodeToNNChar = NULL;
+
+static void CKCH_CreateDictionaries() {
+ TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+ CKCH_USCodeToNNChar = CKCH_CreateCodeToCharDict(currentKeyboard);
+ CFRelease(currentKeyboard);
+}
+
+static UniChar CKCH_CharForKeyCode(jshort keyCode) {
+ UniChar rChar = 0;
+
+ if ( NULL != CKCH_USCodeToNNChar ) {
+ intptr_t code = (intptr_t) keyCode;
+ intptr_t character = 0;
+
+ if ( CFDictionaryGetValueIfPresent(CKCH_USCodeToNNChar, (void *)code, (const void **)&character) ) {
+ rChar = (UniChar) character;
+ DBG_PRINT("CKCH: OK 0x%X -> 0x%X\n", (int)keyCode, (int)rChar);
+ }
+ }
+ return rChar;
+}
+
@implementation NewtMacWindow
+ (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz
{
enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZSIIISF)V");
- sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(SIIISF)V");
- enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISSC)V");
- sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(SISSC)V");
+ enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISCC)V");
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
@@ -370,9 +426,10 @@ static jmethodID windowRepaintID = NULL;
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
- if (enqueueMouseEventID && sendMouseEventID && enqueueKeyEventID && sendKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID &&
+ if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID &&
positionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
{
+ CKCH_CreateDictionaries();
return YES;
}
return NO;
@@ -675,7 +732,7 @@ static jint mods2JavaMods(NSUInteger mods)
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
- JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
if(NULL==env) {
DBG_PRINT("sendKeyEvent: null JNIEnv\n");
return;
@@ -689,36 +746,27 @@ static jint mods2JavaMods(NSUInteger mods)
// printable chars
for (i = 0; i < len; i++) {
// Note: the key code in the NSEvent does not map to anything we can use
- jchar keyChar = (jchar) [chars characterAtIndex: i];
+ UniChar keyChar = (UniChar) [chars characterAtIndex: i];
+ UniChar keySymChar = CKCH_CharForKeyCode(keyCode);
- DBG_PRINT("sendKeyEvent: %d/%d char 0x%X, code 0x%X\n", i, len, (int)keyChar, (int)keyCode);
+ DBG_PRINT("sendKeyEvent: %d/%d code 0x%X, char 0x%X -> keySymChar 0x%X\n", i, len, (int)keyCode, (int)keyChar, (int)keySymChar);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
- evType, javaMods, keyCode, keyCode, keyChar);
- #else
(*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
- evType, javaMods, keyCode, keyCode, keyChar);
- #endif
+ evType, javaMods, keyCode, (jchar)keyChar, (jchar)keySymChar);
}
} else {
// non-printable chars
- jchar keyChar = (jchar) -1;
+ jchar keyChar = (jchar) 0;
DBG_PRINT("sendKeyEvent: code 0x%X\n", (int)keyCode);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
- evType, javaMods, keyCode, keyCode, keyChar);
- #else
(*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
- evType, javaMods, keyCode, keyCode, keyChar);
- #endif
+ evType, javaMods, keyCode, keyChar, keyChar);
}
- if (shallBeDetached) {
+ /* if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
+ } */
}
- (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType
@@ -735,7 +783,7 @@ static jint mods2JavaMods(NSUInteger mods)
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
- JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
if(NULL==env) {
DBG_PRINT("sendMouseEvent: null JNIEnv\n");
return;
@@ -780,21 +828,14 @@ static jint mods2JavaMods(NSUInteger mods)
NSPoint location = [self screenPos2NewtClientWinPos: [NSEvent mouseLocation]];
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, javaWindowObject, sendMouseEventID,
- evType, javaMods[0],
- (jint) location.x, (jint) location.y,
- javaButtonNum, scrollDeltaY);
- #else
(*env)->CallVoidMethod(env, javaWindowObject, enqueueMouseEventID, JNI_FALSE,
evType, javaMods[0],
(jint) location.x, (jint) location.y,
javaButtonNum, scrollDeltaY);
- #endif
- if (shallBeDetached) {
+ /* if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
+ } */
}
- (void) focusChanged: (BOOL) gained
@@ -812,7 +853,7 @@ static jint mods2JavaMods(NSUInteger mods)
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
- JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
if(NULL==env) {
DBG_PRINT("focusChanged: null JNIEnv\n");
return;
@@ -820,9 +861,9 @@ static jint mods2JavaMods(NSUInteger mods)
(*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE);
- if (shallBeDetached) {
+ /* if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
+ } */
}
- (BOOL) becomeFirstResponder
@@ -1010,7 +1051,7 @@ static jint mods2JavaMods(NSUInteger mods)
javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject != NULL) {
jvmHandle = [view getJVMHandle];
- env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
}
}
@@ -1025,9 +1066,9 @@ static jint mods2JavaMods(NSUInteger mods)
(jint) contentRect.size.width,
(jint) contentRect.size.height, JNI_FALSE);
- if (shallBeDetached) {
+ /* if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
+ } */
}
}
@@ -1045,7 +1086,7 @@ static jint mods2JavaMods(NSUInteger mods)
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
- JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
if(NULL==env) {
DBG_PRINT("windowDidMove: null JNIEnv\n");
return;
@@ -1055,9 +1096,9 @@ static jint mods2JavaMods(NSUInteger mods)
p0 = [self getLocationOnScreen: p0];
(*env)->CallVoidMethod(env, javaWindowObject, positionChangedID, JNI_FALSE, (jint) p0.x, (jint) p0.y);
- if (shallBeDetached) {
+ /* if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
+ } */
}
- (BOOL)windowShouldClose: (id) sender
@@ -1092,7 +1133,7 @@ static jint mods2JavaMods(NSUInteger mods)
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
- JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached);
if(NULL==env) {
DBG_PRINT("windowWillClose: null JNIEnv\n");
return NO;
@@ -1105,9 +1146,9 @@ static jint mods2JavaMods(NSUInteger mods)
[view setDestroyNotifySent: false];
}
- if (shallBeDetached) {
+ /* if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
+ } */
DBG_PRINT( "*************** windowWillClose.X: %p, closed %d\n", (void *)(intptr_t)javaWindowObject, (int)closed);
} else {
DBG_PRINT( "*************** windowWillClose (skip)\n");
@@ -1117,3 +1158,4 @@ static jint mods2JavaMods(NSUInteger mods)
}
@end
+
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index ae09490f8..eecc2e075 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -162,7 +162,7 @@ static KeyMapEntry keyMapTable[] = {
{J_VK_CONTROL, VK_RCONTROL, 0},
{J_VK_ALT, VK_MENU, 0},
{J_VK_ALT, VK_LMENU, 0},
- {J_VK_ALT, VK_RMENU, 0},
+ {J_VK_ALT_GRAPH, VK_RMENU, 0},
{J_VK_NUM_LOCK, VK_NUMLOCK, 0},
// Miscellaneous Windows keys
@@ -432,7 +432,7 @@ static void ParseWmVKeyAndScanCode(USHORT winVKey, BYTE winScanCode, BYTE flags,
#endif
}
-static jint GetModifiers(BOOL altKeyFlagged, USHORT jkey) {
+static jint GetModifiers(USHORT jkey) {
jint modifiers = 0;
// have to do &0xFFFF to avoid runtime assert caused by compiling with
// /RTCcsu
@@ -442,9 +442,12 @@ static jint GetModifiers(BOOL altKeyFlagged, USHORT jkey) {
if ( HIBYTE((GetKeyState(VK_SHIFT) & 0xFFFF)) != 0 || J_VK_SHIFT == jkey ) {
modifiers |= EVENT_SHIFT_MASK;
}
- if ( altKeyFlagged || HIBYTE((GetKeyState(VK_MENU) & 0xFFFF)) != 0 || J_VK_ALT == jkey ) {
+ if ( HIBYTE((GetKeyState(VK_LMENU) & 0xFFFF)) != 0 || J_VK_ALT == jkey ) {
modifiers |= EVENT_ALT_MASK;
}
+ if ( HIBYTE((GetKeyState(VK_RMENU) & 0xFFFF)) != 0 || (USHORT)J_VK_ALT_GRAPH == jkey ) {
+ modifiers |= EVENT_ALT_GRAPH_MASK;
+ }
if ( HIBYTE((GetKeyState(VK_LBUTTON) & 0xFFFF)) != 0 ) {
modifiers |= EVENT_BUTTON1_MASK;
}
@@ -458,11 +461,12 @@ static jint GetModifiers(BOOL altKeyFlagged, USHORT jkey) {
return modifiers;
}
+/**
static BOOL IsAltKeyDown(BYTE flags, BOOL system) {
// The Alt modifier is reported in the 29th bit of the lParam,
// i.e., it is the 5th bit of `flags' (which is HIBYTE(HIWORD(lParam))).
return system && ( flags & (1<<5) ) != 0;
-}
+} */
static int WmKeyDown(JNIEnv *env, jobject window, USHORT wkey, WORD repCnt, BYTE scanCode, BYTE flags, BOOL system) {
UINT modifiers = 0;
@@ -473,7 +477,7 @@ static int WmKeyDown(JNIEnv *env, jobject window, USHORT wkey, WORD repCnt, BYTE
ParseWmVKeyAndScanCode(wkey, scanCode, flags, &javaVKeyUS, &javaVKeyXX, &utf16Char);
- modifiers = GetModifiers( IsAltKeyDown(flags, system), javaVKeyXX );
+ modifiers = GetModifiers( javaVKeyUS );
(*env)->CallVoidMethod(env, window, sendKeyEventID,
(jshort) EVENT_KEY_PRESSED,
@@ -491,7 +495,7 @@ static int WmKeyUp(JNIEnv *env, jobject window, USHORT wkey, WORD repCnt, BYTE s
ParseWmVKeyAndScanCode(wkey, scanCode, flags, &javaVKeyUS, &javaVKeyXX, &utf16Char);
- modifiers = GetModifiers( IsAltKeyDown(flags, system), javaVKeyXX );
+ modifiers = GetModifiers( javaVKeyUS );
(*env)->CallVoidMethod(env, window, sendKeyEventID,
(jshort) EVENT_KEY_RELEASED,
@@ -860,7 +864,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jshort) EVENT_MOUSE_PRESSED,
- GetModifiers( FALSE, 0 ),
+ GetModifiers( 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jshort) 1, (jfloat) 0.0f);
useDefWindowProc = 1;
@@ -869,7 +873,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
case WM_LBUTTONUP:
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jshort) EVENT_MOUSE_RELEASED,
- GetModifiers( FALSE, 0 ),
+ GetModifiers( 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jshort) 1, (jfloat) 0.0f);
useDefWindowProc = 1;
@@ -880,7 +884,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jshort) EVENT_MOUSE_PRESSED,
- GetModifiers( FALSE, 0 ),
+ GetModifiers( 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jshort) 2, (jfloat) 0.0f);
useDefWindowProc = 1;
@@ -889,7 +893,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
case WM_MBUTTONUP:
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jshort) EVENT_MOUSE_RELEASED,
- GetModifiers( FALSE, 0 ),
+ GetModifiers( 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jshort) 2, (jfloat) 0.0f);
useDefWindowProc = 1;
@@ -900,7 +904,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jshort) EVENT_MOUSE_PRESSED,
- GetModifiers( FALSE, 0 ),
+ GetModifiers( 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jshort) 3, (jfloat) 0.0f);
useDefWindowProc = 1;
@@ -909,17 +913,17 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
case WM_RBUTTONUP:
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jshort) EVENT_MOUSE_RELEASED,
- GetModifiers( FALSE, 0 ),
+ GetModifiers( 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jshort) 3, (jfloat) 0.0f);
useDefWindowProc = 1;
break;
case WM_MOUSEMOVE:
- DBG_PRINT("*** WindowsWindow: WM_MOUSEMOVE %d/%d\n", (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam));
+ // DBG_PRINT("*** WindowsWindow: WM_MOUSEMOVE %d/%d\n", (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam));
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jshort) EVENT_MOUSE_MOVED,
- GetModifiers( FALSE, 0 ),
+ GetModifiers( 0 ),
(jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jshort) 0, (jfloat) 0.0f);
useDefWindowProc = 1;
@@ -937,7 +941,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
case WM_HSCROLL: { // Only delivered if windows has WS_HSCROLL, hence dead code!
int sb = LOWORD(wParam);
- int modifiers = GetModifiers( FALSE, 0 ) | EVENT_SHIFT_MASK;
+ int modifiers = GetModifiers( 0 ) | EVENT_SHIFT_MASK;
float rotation;
switch(sb) {
case SB_LINELEFT:
@@ -967,7 +971,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
// need to convert the coordinates to component-relative
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
- int modifiers = GetModifiers( FALSE, 0 );
+ int modifiers = GetModifiers( 0 );
float rotationOrTilt = (float)(GET_WHEEL_DELTA_WPARAM(wParam))/WHEEL_DELTAf;
int vKeys = GET_KEYSTATE_WPARAM(wParam);
POINT eventPt;
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
index 9b11ff0dd..56b7251d2 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Display.c
@@ -28,6 +28,8 @@
#include "X11Common.h"
+// #include <X11/XKBlib.h> // XKB disabled for now
+
jclass X11NewtWindowClazz = NULL;
jmethodID insetsChangedID = NULL;
jmethodID visibleChangedID = NULL;
@@ -52,9 +54,11 @@ static jmethodID requestFocusID = NULL;
* Keycode
*/
+// #define DEBUG_KEYS 1
+
#define IS_WITHIN(k,a,b) ((a)<=(k)&&(k)<=(b))
-static jint X11KeySym2NewtVKey(KeySym keySym) {
+static short X11KeySym2NewtVKey(KeySym keySym) {
if( IS_WITHIN( keySym, XK_a, XK_z ) ) {
return ( keySym - XK_a ) + J_VK_A ;
}
@@ -89,8 +93,14 @@ static jint X11KeySym2NewtVKey(KeySym keySym) {
case XK_Control_R:
return J_VK_CONTROL;
case XK_Alt_L:
- case XK_Alt_R:
return J_VK_ALT;
+ case XK_Alt_R:
+ return J_VK_ALT_GRAPH;
+ case XK_Super_L:
+ case XK_Super_R:
+ return J_VK_WINDOWS;
+ case XK_Menu:
+ return J_VK_CONTEXT_MENU;
case XK_Pause:
return J_VK_PAUSE;
case XK_Caps_Lock:
@@ -158,7 +168,11 @@ static jint X11KeySym2NewtVKey(KeySym keySym) {
return keySym;
}
-static jint X11InputState2NewtModifiers(unsigned int xstate, int javaVKey) {
+#define ShiftCtrlModMask ( ShiftMask | ControlMask | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask )
+
+static jboolean altGraphDown = JNI_FALSE;
+
+static jint X11InputState2NewtModifiers(unsigned int xstate, jshort javaVKey, jboolean keyDown) {
jint modifiers = 0;
if ( (ControlMask & xstate) != 0 || J_VK_CONTROL == javaVKey ) {
modifiers |= EVENT_CTRL_MASK;
@@ -166,8 +180,15 @@ static jint X11InputState2NewtModifiers(unsigned int xstate, int javaVKey) {
if ( (ShiftMask & xstate) != 0 || J_VK_SHIFT == javaVKey ) {
modifiers |= EVENT_SHIFT_MASK;
}
- if ( (Mod1Mask & xstate) != 0 || J_VK_ALT == javaVKey ) {
+ if ( J_VK_ALT == javaVKey ) {
+ altGraphDown = JNI_FALSE;
modifiers |= EVENT_ALT_MASK;
+ } else if ( (short)J_VK_ALT_GRAPH == javaVKey ) {
+ altGraphDown = keyDown;
+ modifiers |= EVENT_ALT_GRAPH_MASK;
+ } else if ( (Mod1Mask & xstate) != 0 ) {
+ // XK_Alt_L or XK_Alt_R
+ modifiers |= altGraphDown ? EVENT_ALT_GRAPH_MASK : EVENT_ALT_MASK;
}
if ( (Button1Mask & xstate) != 0 ) {
modifiers |= EVENT_BUTTON1_MASK;
@@ -211,6 +232,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
}
}
+ // displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJJ)V"); // Variant using XKB
displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V");
getCurrentThreadNameID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "getCurrentThreadName", "()Ljava/lang/String;");
dumpStackID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "dumpStack", "()V");
@@ -223,7 +245,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "(Z)Z");
windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V");
sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(SIIISF)V");
- sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSC)V");
+ sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSCLjava/lang/String;)V");
requestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "requestFocus", "(Z)V");
if (displayCompletedID == NULL ||
@@ -258,6 +280,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay
Display * dpy = (Display *)(intptr_t)display;
jlong javaObjectAtom;
jlong windowDeleteAtom;
+ // jlong kbdHandle; // XKB disabled for now
if(dpy==NULL) {
NewtCommon_FatalError(env, "invalid display connection..");
@@ -276,10 +299,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay
}
// XSetCloseDownMode(dpy, RetainTemporary); // Just a try ..
+ // kbdHandle = (jlong) (intptr_t) XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd); // XKB disabled for now
DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy);
- (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom);
+ (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom /*, kbdHandle*/); // XKB disabled for now
}
/*
@@ -288,11 +312,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay
* Signature: (JJJ)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0
- (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
+ (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/)
{
Display * dpy = (Display *)(intptr_t)display;
Atom wm_javaobject_atom = (Atom)javaObjectAtom;
Atom wm_delete_atom = (Atom)windowDeleteAtom;
+ // XkbDescPtr kbdDesc = (XkbDescPtr)(intptr_t)kbdHandle; // XKB disabled for now
if(dpy==NULL) {
NewtCommon_FatalError(env, "invalid display connection..");
@@ -302,6 +327,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0
(void) wm_javaobject_atom;
(void) wm_delete_atom;
+ // XkbFreeKeyboard(kbdDesc, XkbAllNamesMask, True); // XKB disabled for now
+
XSync(dpy, True); // discard all pending events
DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy);
}
@@ -309,13 +336,14 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0
/*
* Class: jogamp_newt_driver_x11_DisplayDriver
* Method: DispatchMessages
- * Signature: (JIJJ)V
+ * Signature: (JJJ)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0
- (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
+ (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/)
{
Display * dpy = (Display *) (intptr_t) display;
Atom wm_delete_atom = (Atom)windowDeleteAtom;
+ // XkbDescPtr kbdDesc = (XkbDescPtr)(intptr_t)kbdHandle; // XKB disabled for now
int num_events = 100;
int autoRepeatModifiers = 0;
@@ -323,6 +351,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
return;
}
+ /** XKB disabled for now
+ if( NULL == kbdDesc) {
+ NewtCommon_throwNewRuntimeException(env, "NULL kbd handle, bail out!");
+ return;
+ } */
+
// Periodically take a break
while( num_events > 0 ) {
jobject jwindow = NULL;
@@ -332,7 +366,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
jshort javaVKeyUS = 0;
jshort javaVKeyNN = 0;
jint modifiers = 0;
- char keyChar = 0;
+ uint16_t keyChar = 0;
+ jstring keyString = NULL;
char text[255];
// XEventsQueued(dpy, X):
@@ -391,27 +426,59 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
// fall through intended
case KeyPress: {
KeySym shiftedKeySym; // layout depending keySym w/ SHIFT
+ KeySym unShiftedKeySym; // layout depending keySym w/o SHIFT
+ unsigned int xkey_state = evt.xkey.state;
keyCode = evt.xkey.keycode;
- keySym = XkbKeycodeToKeysym(dpy, keyCode, 0 /* group */, 0 /* shift level */); // layout depending keySym w/o SHIFT
- if( XLookupString(&evt.xkey, text, 255, &shiftedKeySym, 0) == 1 ) {
- keyChar=text[0];
+ // Layout depending keySym w/o SHIFT,
+ // using fixed group 0 (US default layout)
+ //
+ // unsigned int mods_rtrn = 0;
+ // Bool res = XkbTranslateKeyCode (kbdDesc, keyCode, 0, &mods_rtrn, &keySym); // XKB disabled for now
+ // if( !res ) {
+ keySym = XkbKeycodeToKeysym(dpy, keyCode, 0 /* group */, 0 /* shift level */);
+ // }
+
+ text[0] = 0; text[1] = 0; text[2] = 0;
+ int charCount = XLookupString(&evt.xkey, text, 2, &shiftedKeySym, NULL);
+ if( 1 == charCount ) {
+ keyChar = 0x00FF & (uint16_t) (text[0]);
+ } else if( 2 == charCount ) {
+ // Example: UTF-16: 00DF, UTF-8: c3 9f, LATIN SMALL LETTER SHARP S
+ keyChar = ( 0x00FF & (uint16_t)(text[0]) ) << 8 | ( 0x00FF & (uint16_t)(text[1]) ); // UTF-16BE
+ keyString = (*env)->NewStringUTF(env, text);
}
- javaVKeyNN = X11KeySym2NewtVKey(keySym);
- javaVKeyUS = javaVKeyNN; // FIXME!
- modifiers |= X11InputState2NewtModifiers(evt.xkey.state, javaVKeyNN) | autoRepeatModifiers;
+ if( 0 == keyChar ) {
+ // Use keyCode's keySym for dead-key (aka modifiers, etc)
+ unShiftedKeySym = keySym;
+ } else if( 0 == ( evt.xkey.state & ShiftCtrlModMask ) ) {
+ // Use non modded keySym
+ unShiftedKeySym = shiftedKeySym;
+ } else {
+ evt.xkey.state = evt.xkey.state & ~ShiftCtrlModMask; // clear shift, ctrl and Mod*
+ XLookupString(&evt.xkey, text, 0, &unShiftedKeySym, NULL);
+ // unShiftedKeySym = XLookupKeysym(&evt.xkey, 0 /* index ? */);
+ }
- fprintf(stderr, "NEWT X11 Key: keyCode 0x%X keySym 0x%X (shifted: 0x%X), keyChar '%c', javaVKey[US 0x%X, NN 0x%X]\n",
- (int)keyCode, (int)keySym, (int)shiftedKeySym, (int)keyChar, (int)javaVKeyUS, (int)javaVKeyNN);
+ javaVKeyNN = X11KeySym2NewtVKey(unShiftedKeySym);
+ javaVKeyUS = X11KeySym2NewtVKey(keySym);
+ modifiers |= X11InputState2NewtModifiers(xkey_state, javaVKeyNN, evt.type == KeyPress) | autoRepeatModifiers;
+
+ #ifdef DEBUG_KEYS
+ fprintf(stderr, "NEWT X11 Key: keyCode 0x%X keySym 0x%X, (0x%X, shifted: 0x%X), keyChar '%c' 0x%X %d, javaVKey[US 0x%X, NN 0x%X], xstate 0x%X %u, jmods 0x%X\n",
+ (int)keyCode, (int)keySym, (int) unShiftedKeySym, (int)shiftedKeySym, keyChar, keyChar, charCount,
+ (int)javaVKeyUS, (int)javaVKeyNN,
+ (int)xkey_state, (int)xkey_state, (int)modifiers);
+ #endif
}
break;
case ButtonPress:
case ButtonRelease:
case MotionNotify:
- modifiers |= X11InputState2NewtModifiers(evt.xbutton.state, 0);
+ modifiers |= X11InputState2NewtModifiers(evt.xbutton.state, 0, JNI_FALSE);
break;
default:
@@ -447,13 +514,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
modifiers,
(jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
break;
+ case MappingNotify:
+ DBG_PRINT( "X11: event . MappingNotify call %p type %d\n", (void*)evt.xmapping.window, evt.xmapping.type);
+ XRefreshKeyboardMapping(&evt.xmapping);
+ break;
case KeyPress:
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jshort) EVENT_KEY_PRESSED,
- modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar);
+ modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar, keyString);
break;
case KeyRelease:
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jshort) EVENT_KEY_RELEASED,
- modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar);
+ modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar, keyString);
break;
case DestroyNotify:
DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n",
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 202ad6fff..9e96169f5 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -671,7 +671,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0
- (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong windowDeleteAtom)
+ (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/) // XKB disabled for now
{
Display * dpy = (Display *) (intptr_t) display;
Window w = (Window)window;
@@ -698,7 +698,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0
XUnmapWindow(dpy, w);
// Drain all events related to this window ..
- Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom);
+ Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now
XDestroyWindow(dpy, w);
XSync(dpy, True); // discard all events now, no more handler