aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/newt/native/KeyEvent.h385
-rwxr-xr-xsrc/newt/native/WindowsWindow.c435
-rwxr-xr-xsrc/newt/native/X11Window.c24
3 files changed, 630 insertions, 214 deletions
diff --git a/src/newt/native/KeyEvent.h b/src/newt/native/KeyEvent.h
index e1881366f..1ead0f5e8 100644
--- a/src/newt/native/KeyEvent.h
+++ b/src/newt/native/KeyEvent.h
@@ -6,202 +6,195 @@
#define EVENT_KEY_RELEASED 301
#define EVENT_KEY_TYPED 302
-#define VK_ENTER '\n'
-#define VK_BACK_SPACE '\b'
-#define VK_TAB '\t'
-#define VK_CANCEL 0x03
-#define VK_CLEAR 0x0C
-#define VK_SHIFT 0x10
-#define VK_CONTROL 0x11
-#define VK_ALT 0x12
-#define VK_PAUSE 0x13
-#define VK_CAPS_LOCK 0x14
-#define VK_ESCAPE 0x1B
-#define VK_SPACE 0x20
-#define VK_PAGE_UP 0x21
-#define VK_PAGE_DOWN 0x22
-#define VK_END 0x23
-#define VK_HOME 0x24
-
-#define VK_LEFT 0x25
-
-#define VK_UP 0x26
-
-#define VK_RIGHT 0x27
-
-#define VK_DOWN 0x28
-
-#define VK_COMMA 0x2C
-
-#define VK_MINUS 0x2D
-
-#define VK_PERIOD 0x2E
-
-#define VK_SLASH 0x2F
-
-#define VK_0 0x30
-#define VK_1 0x31
-#define VK_2 0x32
-#define VK_3 0x33
-#define VK_4 0x34
-#define VK_5 0x35
-#define VK_6 0x36
-#define VK_7 0x37
-#define VK_8 0x38
-#define VK_9 0x39
-
-#define VK_SEMICOLON 0x3B
-
-#define VK_EQUALS 0x3D
-
-#define VK_A 0x41
-#define VK_B 0x42
-#define VK_C 0x43
-#define VK_D 0x44
-#define VK_E 0x45
-#define VK_F 0x46
-#define VK_G 0x47
-#define VK_H 0x48
-#define VK_I 0x49
-#define VK_J 0x4A
-#define VK_K 0x4B
-#define VK_L 0x4C
-#define VK_M 0x4D
-#define VK_N 0x4E
-#define VK_O 0x4F
-#define VK_P 0x50
-#define VK_Q 0x51
-#define VK_R 0x52
-#define VK_S 0x53
-#define VK_T 0x54
-#define VK_U 0x55
-#define VK_V 0x56
-#define VK_W 0x57
-#define VK_X 0x58
-#define VK_Y 0x59
-#define VK_Z 0x5A
-
-#define VK_OPEN_BRACKET 0x5B
-
-#define VK_BACK_SLASH 0x5C
-
-#define VK_CLOSE_BRACKET 0x5D
-
-#define VK_NUMPAD0 0x60
-#define VK_NUMPAD1 0x61
-#define VK_NUMPAD2 0x62
-#define VK_NUMPAD3 0x63
-#define VK_NUMPAD4 0x64
-#define VK_NUMPAD5 0x65
-#define VK_NUMPAD6 0x66
-#define VK_NUMPAD7 0x67
-#define VK_NUMPAD8 0x68
-#define VK_NUMPAD9 0x69
-#define VK_MULTIPLY 0x6A
-#define VK_ADD 0x6B
-
-#define VK_SEPARATER 0x6C
-
-#define VK_SEPARATOR VK_SEPARATER
-
-#define VK_SUBTRACT 0x6D
-#define VK_DECIMAL 0x6E
-#define VK_DIVIDE 0x6F
-#define VK_DELETE 0x7F; /* ASCII DEL */
-#define VK_NUM_LOCK 0x90
-#define VK_SCROLL_LOCK 0x91
-
-#define VK_F1 0x70
-
-#define VK_F2 0x71
-
-#define VK_F3 0x72
-
-#define VK_F4 0x73
-
-#define VK_F5 0x74
-
-#define VK_F6 0x75
-
-#define VK_F7 0x76
-
-#define VK_F8 0x77
-
-#define VK_F9 0x78
-
-#define VK_F10 0x79
-
-#define VK_F11 0x7A
-
-#define VK_F12 0x7B
-
-#define VK_F13 0xF000
-
-#define VK_F14 0xF001
-
-#define VK_F15 0xF002
-
-#define VK_F16 0xF003
-
-#define VK_F17 0xF004
-
-#define VK_F18 0xF005
-
-#define VK_F19 0xF006
-
-#define VK_F20 0xF007
-
-#define VK_F21 0xF008
-
-#define VK_F22 0xF009
-
-#define VK_F23 0xF00A
-
-#define VK_F24 0xF00B
-
-#define VK_PRINTSCREEN 0x9A
-#define VK_INSERT 0x9B
-#define VK_HELP 0x9C
-#define VK_META 0x9D
-
-#define VK_BACK_QUOTE 0xC0
-#define VK_QUOTE 0xDE
-
-#define VK_KP_UP 0xE0
-
-#define VK_KP_DOWN 0xE1
-
-#define VK_KP_LEFT 0xE2
-
-#define VK_KP_RIGHT 0xE3
-
-#define VK_AT 0x0200
-
-#define VK_COLON 0x0201
-
-#define VK_CIRCUMFLEX 0x0202
-
-#define VK_DOLLAR 0x0203
-
-#define VK_EURO_SIGN 0x0204
-
-#define VK_EXCLAMATION_MARK 0x0205
-
-#define VK_INVERTED_EXCLAMATION_MARK 0x0206
-
-#define VK_LEFT_PARENTHESIS 0x0207
-
-#define VK_NUMBER_SIGN 0x0208
-
-#define VK_PLUS 0x0209
-
-#define VK_RIGHT_PARENTHESIS 0x020A
-
-#define VK_UNDERSCORE 0x020B
-
-#define VK_WINDOWS 0x020C
-
-#define VK_CONTEXT_MENU 0x020D
+#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
#endif
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index 3f8ba5c87..f76fdf46f 100755
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -84,6 +84,345 @@ static jmethodID sendKeyEventID = NULL;
// This is set by DispatchMessages, below, and cleared when it exits
static JNIEnv* env = NULL;
+typedef struct {
+ UINT javaKey;
+ UINT windowsKey;
+} KeyMapEntry;
+
+// Static table, arranged more or less spatially.
+static KeyMapEntry keyMapTable[] = {
+ // Modifier keys
+ {J_VK_CAPS_LOCK, VK_CAPITAL},
+ {J_VK_SHIFT, VK_SHIFT},
+ {J_VK_CONTROL, VK_CONTROL},
+ {J_VK_ALT, VK_MENU},
+ {J_VK_NUM_LOCK, VK_NUMLOCK},
+
+ // Miscellaneous Windows keys
+ {J_VK_WINDOWS, VK_LWIN},
+ {J_VK_WINDOWS, VK_RWIN},
+ {J_VK_CONTEXT_MENU, VK_APPS},
+
+ // Alphabet
+ {J_VK_A, 'A'},
+ {J_VK_B, 'B'},
+ {J_VK_C, 'C'},
+ {J_VK_D, 'D'},
+ {J_VK_E, 'E'},
+ {J_VK_F, 'F'},
+ {J_VK_G, 'G'},
+ {J_VK_H, 'H'},
+ {J_VK_I, 'I'},
+ {J_VK_J, 'J'},
+ {J_VK_K, 'K'},
+ {J_VK_L, 'L'},
+ {J_VK_M, 'M'},
+ {J_VK_N, 'N'},
+ {J_VK_O, 'O'},
+ {J_VK_P, 'P'},
+ {J_VK_Q, 'Q'},
+ {J_VK_R, 'R'},
+ {J_VK_S, 'S'},
+ {J_VK_T, 'T'},
+ {J_VK_U, 'U'},
+ {J_VK_V, 'V'},
+ {J_VK_W, 'W'},
+ {J_VK_X, 'X'},
+ {J_VK_Y, 'Y'},
+ {J_VK_Z, 'Z'},
+ {J_VK_0, '0'},
+ {J_VK_1, '1'},
+ {J_VK_2, '2'},
+ {J_VK_3, '3'},
+ {J_VK_4, '4'},
+ {J_VK_5, '5'},
+ {J_VK_6, '6'},
+ {J_VK_7, '7'},
+ {J_VK_8, '8'},
+ {J_VK_9, '9'},
+ {J_VK_ENTER, VK_RETURN},
+ {J_VK_SPACE, VK_SPACE},
+ {J_VK_BACK_SPACE, VK_BACK},
+ {J_VK_TAB, VK_TAB},
+ {J_VK_ESCAPE, VK_ESCAPE},
+ {J_VK_INSERT, VK_INSERT},
+ {J_VK_DELETE, VK_DELETE},
+ {J_VK_HOME, VK_HOME},
+ {J_VK_END, VK_END},
+ {J_VK_PAGE_UP, VK_PRIOR},
+ {J_VK_PAGE_DOWN, VK_NEXT},
+ {J_VK_CLEAR, VK_CLEAR}, // NumPad 5
+
+ // NumPad with NumLock off & extended arrows block (triangular)
+ {J_VK_LEFT, VK_LEFT},
+ {J_VK_RIGHT, VK_RIGHT},
+ {J_VK_UP, VK_UP},
+ {J_VK_DOWN, VK_DOWN},
+
+ // NumPad with NumLock on: numbers
+ {J_VK_NUMPAD0, VK_NUMPAD0},
+ {J_VK_NUMPAD1, VK_NUMPAD1},
+ {J_VK_NUMPAD2, VK_NUMPAD2},
+ {J_VK_NUMPAD3, VK_NUMPAD3},
+ {J_VK_NUMPAD4, VK_NUMPAD4},
+ {J_VK_NUMPAD5, VK_NUMPAD5},
+ {J_VK_NUMPAD6, VK_NUMPAD6},
+ {J_VK_NUMPAD7, VK_NUMPAD7},
+ {J_VK_NUMPAD8, VK_NUMPAD8},
+ {J_VK_NUMPAD9, VK_NUMPAD9},
+
+ // NumPad with NumLock on
+ {J_VK_MULTIPLY, VK_MULTIPLY},
+ {J_VK_ADD, VK_ADD},
+ {J_VK_SEPARATOR, VK_SEPARATOR},
+ {J_VK_SUBTRACT, VK_SUBTRACT},
+ {J_VK_DECIMAL, VK_DECIMAL},
+ {J_VK_DIVIDE, VK_DIVIDE},
+
+ // Functional keys
+ {J_VK_F1, VK_F1},
+ {J_VK_F2, VK_F2},
+ {J_VK_F3, VK_F3},
+ {J_VK_F4, VK_F4},
+ {J_VK_F5, VK_F5},
+ {J_VK_F6, VK_F6},
+ {J_VK_F7, VK_F7},
+ {J_VK_F8, VK_F8},
+ {J_VK_F9, VK_F9},
+ {J_VK_F10, VK_F10},
+ {J_VK_F11, VK_F11},
+ {J_VK_F12, VK_F12},
+ {J_VK_F13, VK_F13},
+ {J_VK_F14, VK_F14},
+ {J_VK_F15, VK_F15},
+ {J_VK_F16, VK_F16},
+ {J_VK_F17, VK_F17},
+ {J_VK_F18, VK_F18},
+ {J_VK_F19, VK_F19},
+ {J_VK_F20, VK_F20},
+ {J_VK_F21, VK_F21},
+ {J_VK_F22, VK_F22},
+ {J_VK_F23, VK_F23},
+ {J_VK_F24, VK_F24},
+
+ {J_VK_PRINTSCREEN, VK_SNAPSHOT},
+ {J_VK_SCROLL_LOCK, VK_SCROLL},
+ {J_VK_PAUSE, VK_PAUSE},
+ {J_VK_CANCEL, VK_CANCEL},
+ {J_VK_HELP, VK_HELP},
+
+ // Japanese
+/*
+ {J_VK_CONVERT, VK_CONVERT},
+ {J_VK_NONCONVERT, VK_NONCONVERT},
+ {J_VK_INPUT_METHOD_ON_OFF, VK_KANJI},
+ {J_VK_ALPHANUMERIC, VK_DBE_ALPHANUMERIC},
+ {J_VK_KATAKANA, VK_DBE_KATAKANA},
+ {J_VK_HIRAGANA, VK_DBE_HIRAGANA},
+ {J_VK_FULL_WIDTH, VK_DBE_DBCSCHAR},
+ {J_VK_HALF_WIDTH, VK_DBE_SBCSCHAR},
+ {J_VK_ROMAN_CHARACTERS, VK_DBE_ROMAN},
+*/
+
+ {J_VK_UNDEFINED, 0}
+};
+
+/*
+Dynamic mapping table for OEM VK codes. This table is refilled
+by BuildDynamicKeyMapTable when keyboard layout is switched.
+(see NT4 DDK src/input/inc/vkoem.h for OEM VK_ values).
+*/
+typedef struct {
+ // OEM VK codes known in advance
+ UINT windowsKey;
+ // depends on input langauge (kbd layout)
+ UINT javaKey;
+} DynamicKeyMapEntry;
+
+static DynamicKeyMapEntry dynamicKeyMapTable[] = {
+ {0x00BA, J_VK_UNDEFINED}, // VK_OEM_1
+ {0x00BB, J_VK_UNDEFINED}, // VK_OEM_PLUS
+ {0x00BC, J_VK_UNDEFINED}, // VK_OEM_COMMA
+ {0x00BD, J_VK_UNDEFINED}, // VK_OEM_MINUS
+ {0x00BE, J_VK_UNDEFINED}, // VK_OEM_PERIOD
+ {0x00BF, J_VK_UNDEFINED}, // VK_OEM_2
+ {0x00C0, J_VK_UNDEFINED}, // VK_OEM_3
+ {0x00DB, J_VK_UNDEFINED}, // VK_OEM_4
+ {0x00DC, J_VK_UNDEFINED}, // VK_OEM_5
+ {0x00DD, J_VK_UNDEFINED}, // VK_OEM_6
+ {0x00DE, J_VK_UNDEFINED}, // VK_OEM_7
+ {0x00DF, J_VK_UNDEFINED}, // VK_OEM_8
+ {0x00E2, J_VK_UNDEFINED}, // VK_OEM_102
+ {0, 0}
+};
+
+// Auxiliary tables used to fill the above dynamic table. We first
+// find the character for the OEM VK code using ::MapVirtualKey and
+// then go through these auxiliary tables to map it to Java VK code.
+
+typedef struct {
+ WCHAR c;
+ UINT javaKey;
+} CharToVKEntry;
+
+static const CharToVKEntry charToVKTable[] = {
+ {L'!', J_VK_EXCLAMATION_MARK},
+ {L'"', J_VK_QUOTEDBL},
+ {L'#', J_VK_NUMBER_SIGN},
+ {L'$', J_VK_DOLLAR},
+ {L'&', J_VK_AMPERSAND},
+ {L'\'', J_VK_QUOTE},
+ {L'(', J_VK_LEFT_PARENTHESIS},
+ {L')', J_VK_RIGHT_PARENTHESIS},
+ {L'*', J_VK_ASTERISK},
+ {L'+', J_VK_PLUS},
+ {L',', J_VK_COMMA},
+ {L'-', J_VK_MINUS},
+ {L'.', J_VK_PERIOD},
+ {L'/', J_VK_SLASH},
+ {L':', J_VK_COLON},
+ {L';', J_VK_SEMICOLON},
+ {L'<', J_VK_LESS},
+ {L'=', J_VK_EQUALS},
+ {L'>', J_VK_GREATER},
+ {L'@', J_VK_AT},
+ {L'[', J_VK_OPEN_BRACKET},
+ {L'\\', J_VK_BACK_SLASH},
+ {L']', J_VK_CLOSE_BRACKET},
+ {L'^', J_VK_CIRCUMFLEX},
+ {L'_', J_VK_UNDERSCORE},
+ {L'`', J_VK_BACK_QUOTE},
+ {L'{', J_VK_BRACELEFT},
+ {L'}', J_VK_BRACERIGHT},
+ {0x00A1, J_VK_INVERTED_EXCLAMATION_MARK},
+ {0x20A0, J_VK_EURO_SIGN}, // ????
+ {0,0}
+};
+
+// For dead accents some layouts return ASCII punctuation, while some
+// return spacing accent chars, so both should be listed. NB: MS docs
+// say that conversion routings return spacing accent character, not
+// combining.
+static const CharToVKEntry charToDeadVKTable[] = {
+ {L'`', J_VK_DEAD_GRAVE},
+ {L'\'', J_VK_DEAD_ACUTE},
+ {0x00B4, J_VK_DEAD_ACUTE},
+ {L'^', J_VK_DEAD_CIRCUMFLEX},
+ {L'~', J_VK_DEAD_TILDE},
+ {0x02DC, J_VK_DEAD_TILDE},
+ {0x00AF, J_VK_DEAD_MACRON},
+ {0x02D8, J_VK_DEAD_BREVE},
+ {0x02D9, J_VK_DEAD_ABOVEDOT},
+ {L'"', J_VK_DEAD_DIAERESIS},
+ {0x00A8, J_VK_DEAD_DIAERESIS},
+ {0x02DA, J_VK_DEAD_ABOVERING},
+ {0x02DD, J_VK_DEAD_DOUBLEACUTE},
+ {0x02C7, J_VK_DEAD_CARON}, // aka hacek
+ {L',', J_VK_DEAD_CEDILLA},
+ {0x00B8, J_VK_DEAD_CEDILLA},
+ {0x02DB, J_VK_DEAD_OGONEK},
+ {0x037A, J_VK_DEAD_IOTA}, // ASCII ???
+ {0x309B, J_VK_DEAD_VOICED_SOUND},
+ {0x309C, J_VK_DEAD_SEMIVOICED_SOUND},
+ {0,0}
+};
+
+// ANSI CP identifiers are no longer than this
+#define MAX_ACP_STR_LEN 7
+
+static void BuildDynamicKeyMapTable()
+{
+ HKL hkl = GetKeyboardLayout(0);
+ // Will need this to reset layout after dead keys.
+ UINT spaceScanCode = MapVirtualKeyEx(VK_SPACE, 0, hkl);
+ DynamicKeyMapEntry *dynamic;
+
+ LANGID idLang = LOWORD(GetKeyboardLayout(0));
+ UINT codePage;
+ TCHAR strCodePage[MAX_ACP_STR_LEN];
+ // use the LANGID to create a LCID
+ LCID idLocale = MAKELCID(idLang, SORT_DEFAULT);
+ // get the ANSI code page associated with this locale
+ if (GetLocaleInfo(idLocale, LOCALE_IDEFAULTANSICODEPAGE,
+ strCodePage, sizeof(strCodePage)/sizeof(TCHAR)) > 0 )
+ {
+ codePage = _ttoi(strCodePage);
+ } else {
+ codePage = GetACP();
+ }
+
+ // Entries in dynamic table that maps between Java VK and Windows
+ // VK are built in three steps:
+ // 1. Map windows VK to ANSI character (cannot map to unicode
+ // directly, since ::ToUnicode is not implemented on win9x)
+ // 2. Convert ANSI char to Unicode char
+ // 3. Map Unicode char to Java VK via two auxilary tables.
+
+ for (dynamic = dynamicKeyMapTable; dynamic->windowsKey != 0; ++dynamic)
+ {
+ char cbuf[2] = { '\0', '\0'};
+ WCHAR ucbuf[2] = { L'\0', L'\0' };
+ int nchars;
+ UINT scancode;
+ const CharToVKEntry *charMap;
+ int nconverted;
+ WCHAR uc;
+ BYTE kbdState[256];
+
+ // Defaults to J_VK_UNDEFINED
+ dynamic->javaKey = J_VK_UNDEFINED;
+
+ GetKeyboardState(kbdState);
+
+ kbdState[dynamic->windowsKey] |= 0x80; // Press the key.
+
+ // Unpress modifiers, since they are most likely pressed as
+ // part of the keyboard switching shortcut.
+ kbdState[VK_CONTROL] &= ~0x80;
+ kbdState[VK_SHIFT] &= ~0x80;
+ kbdState[VK_MENU] &= ~0x80;
+
+ scancode = MapVirtualKeyEx(dynamic->windowsKey, 0, hkl);
+ nchars = ToAsciiEx(dynamic->windowsKey, scancode, kbdState,
+ (WORD*)cbuf, 0, hkl);
+
+ // Auxiliary table used to map Unicode character to Java VK.
+ // Will assign a different table for dead keys (below).
+ charMap = charToVKTable;
+
+ if (nchars < 0) { // Dead key
+ char junkbuf[2] = { '\0', '\0'};
+ // Use a different table for dead chars since different layouts
+ // return different characters for the same dead key.
+ charMap = charToDeadVKTable;
+
+ // We also need to reset layout so that next translation
+ // is unaffected by the dead status. We do this by
+ // translating <SPACE> key.
+ kbdState[dynamic->windowsKey] &= ~0x80;
+ kbdState[VK_SPACE] |= 0x80;
+
+ ToAsciiEx(VK_SPACE, spaceScanCode, kbdState,
+ (WORD*)junkbuf, 0, hkl);
+ }
+
+ nconverted = MultiByteToWideChar(codePage, 0,
+ cbuf, 1, ucbuf, 2);
+
+ uc = ucbuf[0];
+ {
+ const CharToVKEntry *map;
+ for (map = charMap; map->c != 0; ++map) {
+ if (uc == map->c) {
+ dynamic->javaKey = map->javaKey;
+ break;
+ }
+ }
+ }
+
+ } // for each VK_OEM_*
+}
+
// Really need to factor this out in to a separate run-time file
static jchar* GetNullTerminatedStringChars(JNIEnv* env, jstring str)
{
@@ -130,6 +469,10 @@ static int WmChar(JNIEnv *env, jobject window, UINT character, UINT repCnt,
return 1;
}
}
+
+ if (character == VK_RETURN) {
+ character = J_VK_ENTER;
+ }
(*env)->CallVoidMethod(env, window, sendKeyEventID,
(jint) EVENT_KEY_TYPED,
GetModifiers(),
@@ -138,6 +481,87 @@ static int WmChar(JNIEnv *env, jobject window, UINT character, UINT repCnt,
return 1;
}
+UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers)
+{
+ int i, j;
+ // for the general case, use a bi-directional table
+ for (i = 0; keyMapTable[i].windowsKey != 0; i++) {
+ if (keyMapTable[i].windowsKey == windowsKey) {
+ return keyMapTable[i].javaKey;
+ }
+ }
+ for (j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
+ if (dynamicKeyMapTable[j].windowsKey == windowsKey) {
+ if (dynamicKeyMapTable[j].javaKey != J_VK_UNDEFINED) {
+ return dynamicKeyMapTable[j].javaKey;
+ } else {
+ break;
+ }
+ }
+ }
+
+ return J_VK_UNDEFINED;
+}
+
+static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
+ UINT flags, BOOL system)
+{
+ UINT modifiers = 0, jkey = 0, character = -1;
+ if (wkey == VK_PROCESSKEY) {
+ return 1;
+ }
+
+ modifiers = GetModifiers();
+ jkey = WindowsKeyToJavaKey(wkey, modifiers);
+
+/*
+ character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
+*/
+
+ (*env)->CallVoidMethod(env, window, sendKeyEventID,
+ (jint) EVENT_KEY_PRESSED,
+ modifiers,
+ (jint) jkey,
+ (jchar) character);
+
+ /* windows does not create a WM_CHAR for the Del key
+ for some reason, so we need to create the KEY_TYPED event on the
+ WM_KEYDOWN.
+ */
+ if (jkey == J_VK_DELETE) {
+ (*env)->CallVoidMethod(env, window, sendKeyEventID,
+ (jint) EVENT_KEY_TYPED,
+ GetModifiers(),
+ (jint) -1,
+ (jchar) '\177');
+ }
+
+ return 0;
+}
+
+static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
+ UINT flags, BOOL system)
+{
+ UINT modifiers = 0, jkey = 0, character = -1;
+ if (wkey == VK_PROCESSKEY) {
+ return 1;
+ }
+
+ modifiers = GetModifiers();
+ jkey = WindowsKeyToJavaKey(wkey, modifiers);
+/*
+ character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
+*/
+
+ (*env)->CallVoidMethod(env, window, sendKeyEventID,
+ (jint) EVENT_KEY_RELEASED,
+ modifiers,
+ (jint) jkey,
+ (jchar) character);
+
+ return 0;
+}
+
static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
@@ -177,15 +601,13 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
break;
case WM_KEYDOWN:
- (*env)->CallVoidMethod(env, window, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
- GetModifiers(), (jint) wParam, (jchar) -1);
- useDefWindowProc = 1;
+ useDefWindowProc = WmKeyDown(env, window, wParam,
+ LOWORD(lParam), HIWORD(lParam), FALSE);
break;
case WM_KEYUP:
- (*env)->CallVoidMethod(env, window, sendKeyEventID, (jint) EVENT_KEY_RELEASED,
- GetModifiers(), (jint) wParam, (jchar) -1);
- useDefWindowProc = 1;
+ useDefWindowProc = WmKeyUp(env, window, wParam,
+ LOWORD(lParam), HIWORD(lParam), FALSE);
break;
case WM_SIZE:
@@ -331,6 +753,7 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_initID
sendKeyEventID == NULL) {
return JNI_FALSE;
}
+ BuildDynamicKeyMapTable();
return JNI_TRUE;
}
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index f06ceda18..ae0895479 100755
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -88,35 +88,35 @@
static jint X11KeySym2NewtVKey(KeySym keySym) {
if(IS_WITHIN(keySym,XK_F1,XK_F12))
- return (keySym-XK_F1)+VK_F1;
+ return (keySym-XK_F1)+J_VK_F1;
switch(keySym) {
case XK_Alt_L:
case XK_Alt_R:
- return VK_ALT;
+ return J_VK_ALT;
case XK_Left:
- return VK_LEFT;
+ return J_VK_LEFT;
case XK_Right:
- return VK_RIGHT;
+ return J_VK_RIGHT;
case XK_Up:
- return VK_UP;
+ return J_VK_UP;
case XK_Down:
- return VK_DOWN;
+ return J_VK_DOWN;
case XK_Page_Up:
- return VK_PAGE_UP;
+ return J_VK_PAGE_UP;
case XK_Page_Down:
- return VK_PAGE_DOWN;
+ return J_VK_PAGE_DOWN;
case XK_Shift_L:
case XK_Shift_R:
- return VK_SHIFT;
+ return J_VK_SHIFT;
case XK_Control_L:
case XK_Control_R:
- return VK_CONTROL;
+ return J_VK_CONTROL;
case XK_Escape:
- return VK_ESCAPE;
+ return J_VK_ESCAPE;
case XK_Delete:
- return VK_DELETE;
+ return J_VK_DELETE;
}
return keySym;
}