DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 1 | /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. |
Brian Hinz | 776c558 | 2013-03-03 16:53:41 +0000 | [diff] [blame] | 2 | * Copyright (C) 2012-2013 D. R. Commander. All Rights Reserved. |
Brian Hinz | accdd95 | 2013-03-25 20:58:14 +0000 | [diff] [blame] | 3 | * Copyright (C) 2013 Brian P. Hinz |
Brian Hinz | 7b7ad80 | 2013-12-29 17:33:10 +0000 | [diff] [blame^] | 4 | * Copyright (C) 2013 Pierre Ossman <ossman@cendio.se> for Cendio AB |
Brian Hinz | 776c558 | 2013-03-03 16:53:41 +0000 | [diff] [blame] | 5 | * |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 6 | * This is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; either version 2 of the License, or |
| 9 | * (at your option) any later version. |
Brian Hinz | 776c558 | 2013-03-03 16:53:41 +0000 | [diff] [blame] | 10 | * |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 11 | * This software is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. |
Brian Hinz | 776c558 | 2013-03-03 16:53:41 +0000 | [diff] [blame] | 15 | * |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 16 | * You should have received a copy of the GNU General Public License |
| 17 | * along with this software; if not, write to the Free Software |
Brian Hinz | b213da6 | 2012-04-11 22:00:55 +0000 | [diff] [blame] | 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 19 | * USA. |
| 20 | */ |
| 21 | |
| 22 | // |
| 23 | // Keysyms - defines X keysyms for non-character keys. All keysyms |
| 24 | // corresponding to characters should be generated by calling |
Brian Hinz | 2e248ad | 2013-12-29 16:30:32 +0000 | [diff] [blame] | 25 | // UnicodeToKeysym.ucs2keysym(). |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 26 | // |
| 27 | |
| 28 | package com.tigervnc.rfb; |
| 29 | |
Brian Hinz | 2e248ad | 2013-12-29 16:30:32 +0000 | [diff] [blame] | 30 | import java.awt.event.KeyEvent; |
| 31 | import com.tigervnc.vncviewer.VncViewer; |
| 32 | |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 33 | public class Keysyms { |
| 34 | |
Brian Hinz | 2e248ad | 2013-12-29 16:30:32 +0000 | [diff] [blame] | 35 | public static final int VoidSymbol = 0xffffff; |
| 36 | /* |
| 37 | * TTY Functions, cleverly chosen to map to ascii, for convenience of |
| 38 | * programming, but could have been arbitrary (at the cost of lookup |
| 39 | * tables in client code. |
| 40 | */ |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 41 | public static final int BackSpace = 0xFF08; |
| 42 | public static final int Tab = 0xFF09; |
| 43 | public static final int Linefeed = 0xFF0A; |
| 44 | public static final int Clear = 0xFF0B; |
| 45 | public static final int Return = 0xFF0D; |
| 46 | public static final int Pause = 0xFF13; |
| 47 | public static final int Scroll_Lock = 0xFF14; |
| 48 | public static final int Sys_Req = 0xFF15; |
| 49 | public static final int Escape = 0xFF1B; |
| 50 | public static final int Delete = 0xFFFF; |
| 51 | |
Brian Hinz | 2e248ad | 2013-12-29 16:30:32 +0000 | [diff] [blame] | 52 | /* International & multi-key character composition */ |
Brian Hinz | accdd95 | 2013-03-25 20:58:14 +0000 | [diff] [blame] | 53 | public static final int Multi_key = 0xFF20; /* Multi-key character compose */ |
| 54 | public static final int Codeinput = 0xFF37; |
| 55 | public static final int SingleCandidate = 0xFF3C; |
| 56 | public static final int MultipleCandidate = 0xFF3D; |
| 57 | public static final int PreviousCandidate = 0xFF3E; |
| 58 | |
Brian Hinz | 2e248ad | 2013-12-29 16:30:32 +0000 | [diff] [blame] | 59 | /* Japanese keyboard support */ |
Brian Hinz | accdd95 | 2013-03-25 20:58:14 +0000 | [diff] [blame] | 60 | public static final int Kanji = 0xFF21; /* Kanji, Kanji convert */ |
| 61 | public static final int Muhenkan = 0xFF22; /* Cancel Conversion */ |
| 62 | public static final int Henkan_Mode = 0xFF23; /* Start/Stop Conversion */ |
| 63 | public static final int Henkan = 0xFF23; /* Alias for Henkan_Mode */ |
| 64 | public static final int Romaji = 0xFF24; /* to Romaji */ |
| 65 | public static final int Hiragana = 0xFF25; /* to Hiragana */ |
| 66 | public static final int Katakana = 0xFF26; /* to Katakana */ |
| 67 | public static final int Hiragana_Katakana = 0xFF27; /* Hiragana/Katakana toggle */ |
| 68 | public static final int Zenkaku = 0xFF28; /* to Zenkaku */ |
| 69 | public static final int Hankaku = 0xFF29; /* to Hankaku */ |
| 70 | public static final int Zenkaku_Hankaku = 0xFF2A; /* Zenkaku/Hankaku toggle */ |
| 71 | public static final int Touroku = 0xFF2B; /* Add to Dictionary */ |
| 72 | public static final int Massyo = 0xFF2C; /* Delete from Dictionary */ |
| 73 | public static final int Kana_Lock = 0xFF2D; /* Kana Lock */ |
| 74 | public static final int Kana_Shift = 0xFF2E; /* Kana Shift */ |
| 75 | public static final int Eisu_Shift = 0xFF2F; /* Alphanumeric Shift */ |
| 76 | public static final int Eisu_toggle = 0xFF30; /* Alphanumeric toggle */ |
| 77 | public static final int Kanji_Bangou = 0xFF37; /* Codeinput */ |
| 78 | public static final int Zen_Koho = 0xFF3D; /* Multiple/All Candidate(s) */ |
| 79 | public static final int Mae_Koho = 0xFF3E; /* Previous Candidate */ |
| 80 | |
Brian Hinz | 2e248ad | 2013-12-29 16:30:32 +0000 | [diff] [blame] | 81 | /* Cursor control & motion */ |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 82 | public static final int Home = 0xFF50; |
| 83 | public static final int Left = 0xFF51; |
| 84 | public static final int Up = 0xFF52; |
| 85 | public static final int Right = 0xFF53; |
| 86 | public static final int Down = 0xFF54; |
| 87 | public static final int Prior = 0xFF55; |
| 88 | public static final int Page_Up = 0xFF55; |
| 89 | public static final int Next = 0xFF56; |
| 90 | public static final int Page_Down = 0xFF56; |
| 91 | public static final int End = 0xFF57; |
| 92 | public static final int Begin = 0xFF58; |
| 93 | |
Brian Hinz | 2e248ad | 2013-12-29 16:30:32 +0000 | [diff] [blame] | 94 | /* Misc Functions */ |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 95 | public static final int Select = 0xFF60; |
| 96 | public static final int Print = 0xFF61; |
| 97 | public static final int Execute = 0xFF62; |
| 98 | public static final int Insert = 0xFF63; |
| 99 | public static final int Undo = 0xFF65; |
| 100 | public static final int Redo = 0xFF66; |
| 101 | public static final int Menu = 0xFF67; |
| 102 | public static final int Find = 0xFF68; |
| 103 | public static final int Cancel = 0xFF69; |
| 104 | public static final int Help = 0xFF6A; |
| 105 | public static final int Break = 0xFF6B; |
| 106 | public static final int Mode_switch = 0xFF7E; |
| 107 | public static final int script_switch = 0xFF7E; |
| 108 | public static final int Num_Lock = 0xFF7F; |
| 109 | |
Brian Hinz | 2e248ad | 2013-12-29 16:30:32 +0000 | [diff] [blame] | 110 | /* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ |
| 111 | public static final int KP_Enter = 0xFF8D; |
| 112 | public static final int KP_Home = 0xFF95; |
| 113 | public static final int KP_Left = 0xFF96; |
| 114 | public static final int KP_Up = 0xFF97; |
| 115 | public static final int KP_Right = 0xFF98; |
| 116 | public static final int KP_Down = 0xFF99; |
| 117 | public static final int KP_Page_Up = 0xFF9A; |
| 118 | public static final int KP_Page_Down = 0xFF9B; |
| 119 | public static final int KP_End = 0xFF9C; |
| 120 | public static final int KP_Begin = 0xFF9D; |
| 121 | public static final int KP_Insert = 0xFF9E; |
| 122 | public static final int KP_Delete = 0xFF9F; |
| 123 | public static final int KP_Equal = 0xFFBD; |
| 124 | public static final int KP_0 = 0xFFB0; |
| 125 | public static final int KP_1 = 0xFFB1; |
| 126 | public static final int KP_2 = 0xFFB2; |
| 127 | public static final int KP_3 = 0xFFB3; |
| 128 | public static final int KP_4 = 0xFFB4; |
| 129 | public static final int KP_5 = 0xFFB5; |
| 130 | public static final int KP_6 = 0xFFB6; |
| 131 | public static final int KP_7 = 0xFFB7; |
| 132 | public static final int KP_8 = 0xFFB8; |
| 133 | public static final int KP_9 = 0xFFB9; |
| 134 | public static final int KP_Decimal = 0xFFAE; |
| 135 | public static final int KP_Add = 0xFFAB; |
| 136 | public static final int KP_Subtract = 0xFFAD; |
| 137 | public static final int KP_Multiply = 0xFFAA; |
| 138 | public static final int KP_Divide = 0xFFAF; |
| 139 | |
| 140 | /* |
| 141 | * Auxilliary Functions; note the duplicate definitions for left and right |
| 142 | * function keys; Sun keyboards and a few other manufactures have such |
| 143 | * function key groups on the left and/or right sides of the keyboard. |
| 144 | * We've not found a keyboard with more than 35 function keys total. |
| 145 | */ |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 146 | public static final int F1 = 0xFFBE; |
| 147 | public static final int F2 = 0xFFBF; |
| 148 | public static final int F3 = 0xFFC0; |
| 149 | public static final int F4 = 0xFFC1; |
| 150 | public static final int F5 = 0xFFC2; |
| 151 | public static final int F6 = 0xFFC3; |
| 152 | public static final int F7 = 0xFFC4; |
| 153 | public static final int F8 = 0xFFC5; |
| 154 | public static final int F9 = 0xFFC6; |
| 155 | public static final int F10 = 0xFFC7; |
| 156 | public static final int F11 = 0xFFC8; |
| 157 | public static final int F12 = 0xFFC9; |
Brian Hinz | 776c558 | 2013-03-03 16:53:41 +0000 | [diff] [blame] | 158 | public static final int F13 = 0xFFCA; |
Brian Hinz | accdd95 | 2013-03-25 20:58:14 +0000 | [diff] [blame] | 159 | public static final int F14 = 0xFFCB; |
| 160 | public static final int F15 = 0xFFCC; |
| 161 | public static final int F16 = 0xFFCD; |
| 162 | public static final int F17 = 0xFFCE; |
| 163 | public static final int F18 = 0xFFCF; |
| 164 | public static final int F19 = 0xFFD0; |
| 165 | public static final int F20 = 0xFFD1; |
| 166 | public static final int F21 = 0xFFD2; |
| 167 | public static final int F22 = 0xFFD3; |
| 168 | public static final int F23 = 0xFFD4; |
| 169 | public static final int F24 = 0xFFD5; |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 170 | |
Brian Hinz | 2e248ad | 2013-12-29 16:30:32 +0000 | [diff] [blame] | 171 | /* Modifiers */ |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 172 | public static final int Shift_L = 0xFFE1; |
| 173 | public static final int Shift_R = 0xFFE2; |
| 174 | public static final int Control_L = 0xFFE3; |
| 175 | public static final int Control_R = 0xFFE4; |
Brian Hinz | 2e248ad | 2013-12-29 16:30:32 +0000 | [diff] [blame] | 176 | public static final int Caps_Lock = 0xFFE5; |
| 177 | public static final int Shift_Lock = 0xFFE6; |
| 178 | |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 179 | public static final int Meta_L = 0xFFE7; |
| 180 | public static final int Meta_R = 0xFFE8; |
| 181 | public static final int Alt_L = 0xFFE9; |
| 182 | public static final int Alt_R = 0xFFEA; |
Brian Hinz | 776c558 | 2013-03-03 16:53:41 +0000 | [diff] [blame] | 183 | public static final int Super_L = 0xFFEB; |
Brian Hinz | 2e248ad | 2013-12-29 16:30:32 +0000 | [diff] [blame] | 184 | public static final int Super_R = 0xFFEC; |
| 185 | public static final int Hyper_L = 0xFFED; |
| 186 | public static final int Hyper_R = 0xFFEE; |
Brian Hinz | 776c558 | 2013-03-03 16:53:41 +0000 | [diff] [blame] | 187 | |
Brian Hinz | 2e248ad | 2013-12-29 16:30:32 +0000 | [diff] [blame] | 188 | /* |
| 189 | * ISO 9995 Function and Modifier Keys |
| 190 | * Byte 3 = 0xFE |
| 191 | */ |
| 192 | public static final int ISO_Level3_Shift = 0xFE03; |
| 193 | |
| 194 | /* |
| 195 | * Dead Modifier Keys |
| 196 | */ |
| 197 | public static final int Dead_Grave = 0xfe50; /* COMBINING GRAVE ACCENT */ |
| 198 | public static final int Dead_Acute = 0xfe51; /* COMBINING ACUTE ACCENT */ |
| 199 | public static final int Dead_Circumflex = 0xfe52; /* COMBINING CIRCUMFLEX ACCENT */ |
| 200 | public static final int Dead_Tilde = 0xfe53; /* COMBINING TILDE */ |
| 201 | public static final int Dead_Macron = 0xfe54; /* COMBINING MACRON */ |
| 202 | public static final int Dead_Breve = 0xfe55; /* COMBINING BREVE */ |
| 203 | public static final int Dead_AboveDot = 0xfe56; /* COMBINING DOT ABOVE */ |
| 204 | public static final int Dead_Diaeresis = 0xfe57; /* COMBINING DIAERESIS */ |
| 205 | public static final int Dead_AboveRing = 0xfe58; /* COMBINING RING ABOVE */ |
| 206 | public static final int Dead_DoubleAcute = 0xfe59; /* COMBINING DOUBLE ACUTE ACCENT */ |
| 207 | public static final int Dead_Caron = 0xfe5a; /* COMBINING CARON */ |
| 208 | public static final int Dead_Cedilla = 0xfe5b; /* COMBINING CEDILLA */ |
| 209 | public static final int Dead_Ogonek = 0xfe5c; /* COMBINING OGONEK */ |
| 210 | public static final int Dead_Iota = 0xfe5d; /* MODIFIER LETTER SMALL IOTA */ |
| 211 | public static final int Dead_Voiced_Sound = 0xfe5e; /* COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK */ |
| 212 | public static final int Dead_SemiVoiced_Sound = 0xfe5f; /* COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ |
| 213 | public static final int Dead_BelowDot = 0xfe60; /* COMBINING DOT BELOW */ |
| 214 | |
| 215 | private static class KeySymbol { |
| 216 | public KeySymbol(int keycode_, int[] keysym_) { |
| 217 | keycode = keycode_; |
| 218 | keysym = new int[5]; |
| 219 | System.arraycopy(keysym_, 0, keysym, 0, 5); |
| 220 | } |
| 221 | int keycode; |
| 222 | int[] keysym; |
| 223 | } |
| 224 | |
| 225 | private static KeySymbol[] keySymbols = { |
| 226 | /* KEYCODE LOCATION */ |
| 227 | /* UNKNOWN STANDARD LEFT RIGHT NUMPAD */ |
| 228 | new KeySymbol(KeyEvent.VK_BACK_SPACE, new int[]{VoidSymbol, BackSpace, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 229 | new KeySymbol(KeyEvent.VK_TAB, new int[]{VoidSymbol, Tab, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 230 | new KeySymbol(KeyEvent.VK_ENTER, new int[]{VoidSymbol, Return, VoidSymbol, VoidSymbol, KP_Enter}), |
| 231 | new KeySymbol(KeyEvent.VK_ESCAPE, new int[]{VoidSymbol, Escape, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 232 | new KeySymbol(KeyEvent.VK_CONTROL, new int[]{VoidSymbol, Control_L, Control_L, Control_R, VoidSymbol}), |
| 233 | new KeySymbol(KeyEvent.VK_ALT_GRAPH, new int[]{VoidSymbol, ISO_Level3_Shift, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 234 | new KeySymbol(KeyEvent.VK_ALT, new int[]{VoidSymbol, ISO_Level3_Shift, Alt_L, Alt_R, VoidSymbol}), |
| 235 | new KeySymbol(KeyEvent.VK_SHIFT, new int[]{VoidSymbol, Shift_L, Shift_L, Shift_R, VoidSymbol}), |
| 236 | new KeySymbol(KeyEvent.VK_META, new int[]{VoidSymbol, Meta_L, Meta_L, Meta_R, VoidSymbol}), |
| 237 | new KeySymbol(KeyEvent.VK_NUMPAD0, new int[]{VoidSymbol, VoidSymbol, VoidSymbol, VoidSymbol, KP_0}), |
| 238 | new KeySymbol(KeyEvent.VK_NUMPAD1, new int[]{VoidSymbol, VoidSymbol, VoidSymbol, VoidSymbol, KP_1}), |
| 239 | new KeySymbol(KeyEvent.VK_NUMPAD2, new int[]{VoidSymbol, VoidSymbol, VoidSymbol, VoidSymbol, KP_2}), |
| 240 | new KeySymbol(KeyEvent.VK_NUMPAD3, new int[]{VoidSymbol, VoidSymbol, VoidSymbol, VoidSymbol, KP_3}), |
| 241 | new KeySymbol(KeyEvent.VK_NUMPAD4, new int[]{VoidSymbol, VoidSymbol, VoidSymbol, VoidSymbol, KP_4}), |
| 242 | new KeySymbol(KeyEvent.VK_NUMPAD5, new int[]{VoidSymbol, VoidSymbol, VoidSymbol, VoidSymbol, KP_5}), |
| 243 | new KeySymbol(KeyEvent.VK_NUMPAD6, new int[]{VoidSymbol, VoidSymbol, VoidSymbol, VoidSymbol, KP_6}), |
| 244 | new KeySymbol(KeyEvent.VK_NUMPAD7, new int[]{VoidSymbol, VoidSymbol, VoidSymbol, VoidSymbol, KP_7}), |
| 245 | new KeySymbol(KeyEvent.VK_NUMPAD8, new int[]{VoidSymbol, VoidSymbol, VoidSymbol, VoidSymbol, KP_8}), |
| 246 | new KeySymbol(KeyEvent.VK_NUMPAD9, new int[]{VoidSymbol, VoidSymbol, VoidSymbol, VoidSymbol, KP_9}), |
| 247 | new KeySymbol(KeyEvent.VK_DECIMAL, new int[]{VoidSymbol, KP_Decimal, VoidSymbol, VoidSymbol, KP_Decimal}), |
| 248 | new KeySymbol(KeyEvent.VK_ADD, new int[]{VoidSymbol, KP_Add, VoidSymbol, VoidSymbol, KP_Add}), |
| 249 | new KeySymbol(KeyEvent.VK_SUBTRACT, new int[]{VoidSymbol, KP_Subtract, VoidSymbol, VoidSymbol, KP_Subtract}), |
| 250 | new KeySymbol(KeyEvent.VK_MULTIPLY, new int[]{VoidSymbol, KP_Multiply, VoidSymbol, VoidSymbol, KP_Multiply}), |
| 251 | new KeySymbol(KeyEvent.VK_DIVIDE, new int[]{VoidSymbol, KP_Divide, VoidSymbol, VoidSymbol, KP_Divide}), |
| 252 | new KeySymbol(KeyEvent.VK_DELETE, new int[]{VoidSymbol, Delete, VoidSymbol, VoidSymbol, KP_Delete}), |
| 253 | new KeySymbol(KeyEvent.VK_CLEAR, new int[]{VoidSymbol, Clear, VoidSymbol, VoidSymbol, KP_Begin}), |
| 254 | new KeySymbol(KeyEvent.VK_HOME, new int[]{VoidSymbol, Home, VoidSymbol, VoidSymbol, KP_Home}), |
| 255 | new KeySymbol(KeyEvent.VK_END, new int[]{VoidSymbol, End, VoidSymbol, VoidSymbol, KP_End}), |
| 256 | new KeySymbol(KeyEvent.VK_PAGE_UP, new int[]{VoidSymbol, Page_Up, VoidSymbol, VoidSymbol, KP_Page_Up}), |
| 257 | new KeySymbol(KeyEvent.VK_PAGE_DOWN, new int[]{VoidSymbol, Page_Down, VoidSymbol, VoidSymbol, KP_Page_Down}), |
| 258 | new KeySymbol(KeyEvent.VK_UP, new int[]{VoidSymbol, Up, VoidSymbol, VoidSymbol, KP_Up}), |
| 259 | new KeySymbol(KeyEvent.VK_DOWN, new int[]{VoidSymbol, Down, VoidSymbol, VoidSymbol, KP_Down}), |
| 260 | new KeySymbol(KeyEvent.VK_LEFT, new int[]{VoidSymbol, Left, VoidSymbol, VoidSymbol, KP_Left}), |
| 261 | new KeySymbol(KeyEvent.VK_RIGHT, new int[]{VoidSymbol, Right, VoidSymbol, VoidSymbol, KP_Right}), |
| 262 | new KeySymbol(KeyEvent.VK_BEGIN, new int[]{VoidSymbol, Begin, VoidSymbol, VoidSymbol, KP_Begin}), |
| 263 | new KeySymbol(KeyEvent.VK_KP_LEFT, new int[]{VoidSymbol, KP_Left, VoidSymbol, VoidSymbol, KP_Left}), |
| 264 | new KeySymbol(KeyEvent.VK_KP_UP, new int[]{VoidSymbol, KP_Up, VoidSymbol, VoidSymbol, KP_Up}), |
| 265 | new KeySymbol(KeyEvent.VK_KP_RIGHT, new int[]{VoidSymbol, KP_Right, VoidSymbol, VoidSymbol, KP_Right}), |
| 266 | new KeySymbol(KeyEvent.VK_KP_DOWN, new int[]{VoidSymbol, KP_Down, VoidSymbol, VoidSymbol, KP_Down}), |
| 267 | new KeySymbol(KeyEvent.VK_PRINTSCREEN, new int[]{VoidSymbol, Print, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 268 | new KeySymbol(KeyEvent.VK_SCROLL_LOCK, new int[]{VoidSymbol, Scroll_Lock, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 269 | new KeySymbol(KeyEvent.VK_CAPS_LOCK, new int[]{VoidSymbol, Caps_Lock, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 270 | new KeySymbol(KeyEvent.VK_NUM_LOCK, new int[]{VoidSymbol, Num_Lock, VoidSymbol, VoidSymbol, Num_Lock}), |
| 271 | new KeySymbol(KeyEvent.VK_INSERT, new int[]{VoidSymbol, Insert, VoidSymbol, VoidSymbol, KP_Insert}), |
| 272 | new KeySymbol(KeyEvent.VK_AGAIN, new int[]{VoidSymbol, Redo, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 273 | new KeySymbol(KeyEvent.VK_UNDO, new int[]{VoidSymbol, Undo, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 274 | new KeySymbol(KeyEvent.VK_FIND, new int[]{VoidSymbol, Find, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 275 | new KeySymbol(KeyEvent.VK_STOP, new int[]{VoidSymbol, Cancel, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 276 | new KeySymbol(KeyEvent.VK_HELP, new int[]{VoidSymbol, Help, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 277 | new KeySymbol(KeyEvent.VK_WINDOWS, new int[]{VoidSymbol, Super_L, Super_L, Super_R, VoidSymbol}), |
| 278 | new KeySymbol(KeyEvent.VK_CONTEXT_MENU, new int[]{VoidSymbol, Menu, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 279 | new KeySymbol(KeyEvent.VK_KANJI, new int[]{VoidSymbol, Kanji, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 280 | new KeySymbol(KeyEvent.VK_KATAKANA, new int[]{VoidSymbol, Katakana, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 281 | new KeySymbol(KeyEvent.VK_HIRAGANA, new int[]{VoidSymbol, Hiragana, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 282 | new KeySymbol(KeyEvent.VK_PREVIOUS_CANDIDATE, |
| 283 | new int[]{VoidSymbol, PreviousCandidate,VoidSymbol, VoidSymbol, VoidSymbol}), |
| 284 | new KeySymbol(KeyEvent.VK_CODE_INPUT, new int[]{VoidSymbol, Codeinput, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 285 | new KeySymbol(KeyEvent.VK_JAPANESE_ROMAN, |
| 286 | new int[]{VoidSymbol, Romaji, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 287 | new KeySymbol(KeyEvent.VK_KANA_LOCK, new int[]{VoidSymbol, Kana_Lock, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 288 | new KeySymbol(KeyEvent.VK_DEAD_ABOVEDOT,new int[]{VoidSymbol, Dead_AboveDot, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 289 | new KeySymbol(KeyEvent.VK_DEAD_ABOVERING, |
| 290 | new int[]{VoidSymbol, Dead_AboveRing, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 291 | new KeySymbol(KeyEvent.VK_DEAD_ACUTE, new int[]{VoidSymbol, Dead_Acute, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 292 | new KeySymbol(KeyEvent.VK_DEAD_BREVE, new int[]{VoidSymbol, Dead_Breve, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 293 | new KeySymbol(KeyEvent.VK_DEAD_CARON, new int[]{VoidSymbol, Dead_Caron, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 294 | new KeySymbol(KeyEvent.VK_DEAD_CIRCUMFLEX, |
| 295 | new int[]{VoidSymbol, Dead_Circumflex, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 296 | new KeySymbol(KeyEvent.VK_DEAD_DIAERESIS, |
| 297 | new int[]{VoidSymbol, Dead_Diaeresis, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 298 | new KeySymbol(KeyEvent.VK_DEAD_DOUBLEACUTE, |
| 299 | new int[]{VoidSymbol, Dead_DoubleAcute, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 300 | new KeySymbol(KeyEvent.VK_DEAD_GRAVE, new int[]{VoidSymbol, Dead_Grave, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 301 | new KeySymbol(KeyEvent.VK_DEAD_IOTA, new int[]{VoidSymbol, Dead_Iota, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 302 | new KeySymbol(KeyEvent.VK_DEAD_MACRON, new int[]{VoidSymbol, Dead_Macron, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 303 | new KeySymbol(KeyEvent.VK_DEAD_OGONEK, new int[]{VoidSymbol, Dead_Ogonek, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 304 | new KeySymbol(KeyEvent.VK_DEAD_SEMIVOICED_SOUND, |
| 305 | new int[]{VoidSymbol, Dead_SemiVoiced_Sound,VoidSymbol, VoidSymbol, VoidSymbol}), |
| 306 | new KeySymbol(KeyEvent.VK_DEAD_TILDE, new int[]{VoidSymbol, Dead_Tilde, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 307 | new KeySymbol(KeyEvent.VK_DEAD_VOICED_SOUND, |
| 308 | new int[]{VoidSymbol, Dead_Voiced_Sound, VoidSymbol, VoidSymbol, VoidSymbol}), |
| 309 | }; |
| 310 | |
| 311 | public static int translateKeyEvent(KeyEvent ev) { |
| 312 | int location = ev.getKeyLocation(); |
| 313 | int keyCode = ev.getKeyCode(); |
| 314 | |
| 315 | // First check for function keys |
| 316 | if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12) |
| 317 | return Keysyms.F1 + keyCode - KeyEvent.VK_F1; |
| 318 | if (keyCode >= KeyEvent.VK_F13 && keyCode <= KeyEvent.VK_F24) |
| 319 | return Keysyms.F13 + keyCode - KeyEvent.VK_F13; |
| 320 | |
| 321 | // Numpad numbers |
| 322 | if (keyCode >= KeyEvent.VK_0 && keyCode <= KeyEvent.VK_9 && |
| 323 | location == KeyEvent.KEY_LOCATION_NUMPAD) |
| 324 | return Keysyms.KP_0 + keyCode - KeyEvent.VK_0; |
| 325 | |
| 326 | if (VncViewer.os.startsWith("mac os x")) { |
| 327 | // Alt on OS X behaves more like AltGr on other systems, and to get |
| 328 | // sane behaviour we should translate things in that manner for the |
| 329 | // remote VNC server. However that means we lose the ability to use |
| 330 | // Alt as a shortcut modifier. Do what RealVNC does and hijack the |
| 331 | // left command key as an Alt replacement. |
| 332 | switch (keyCode) { |
| 333 | case KeyEvent.VK_META: |
| 334 | if (location == KeyEvent.KEY_LOCATION_LEFT) |
| 335 | return Alt_L; |
| 336 | else |
| 337 | return Super_L; |
| 338 | case KeyEvent.VK_ALT: |
| 339 | if (location == KeyEvent.KEY_LOCATION_LEFT) |
| 340 | return Alt_L; |
| 341 | else |
| 342 | return ISO_Level3_Shift; |
| 343 | } |
| 344 | } |
| 345 | |
| 346 | // Then other special keys |
| 347 | if (keyCode == KeyEvent.VK_PAUSE) |
| 348 | return (ev.isControlDown() ? Break : Pause); |
| 349 | else if (keyCode == KeyEvent.VK_PRINTSCREEN) |
| 350 | return (ev.isControlDown() ? Sys_Req : Print); |
| 351 | else |
| 352 | for(int i = 0; i < keySymbols.length; i++) |
| 353 | if (keySymbols[i].keycode == keyCode) |
| 354 | return (keySymbols[i].keysym)[location]; |
| 355 | |
| 356 | // Unknown special key? |
| 357 | if (KeyEvent.getKeyText(keyCode).isEmpty()) { |
| 358 | vlog.error("Unknown key code:"); |
| 359 | String fmt = ev.paramString().replaceAll("%","%%"); |
| 360 | vlog.error(String.format(fmt.replaceAll(",","%n "))); |
| 361 | return VoidSymbol; |
| 362 | } |
| 363 | |
| 364 | char keyChar = ev.getKeyChar(); |
| 365 | if (!ev.isControlDown() && keyChar != KeyEvent.CHAR_UNDEFINED) |
| 366 | return UnicodeToKeysym.ucs2keysym(Character.toString(keyChar).codePointAt(0)); |
| 367 | |
| 368 | int key = keyChar; |
| 369 | if (ev.isControlDown()) { |
| 370 | // For CTRL-<letter>, CTRL is sent separately, so just send <letter>. |
| 371 | if ((key >= 1 && key <= 26 && !ev.isShiftDown()) || |
| 372 | // CTRL-{, CTRL-|, CTRL-} also map to ASCII 96-127 |
| 373 | (key >= 27 && key <= 29 && ev.isShiftDown())) |
| 374 | key += 96; |
| 375 | // For CTRL-SHIFT-<letter>, send capital <letter> to emulate behavior |
| 376 | // of Linux. For CTRL-@, send @. For CTRL-_, send _. For CTRL-^, |
| 377 | // send ^. |
| 378 | else if (key < 32) |
| 379 | key += 64; |
| 380 | // Windows and Mac sometimes return CHAR_UNDEFINED with CTRL-SHIFT |
| 381 | // combinations, so best we can do is send the key code if it is |
| 382 | // a valid ASCII symbol. |
| 383 | else if (ev.getKeyChar() == KeyEvent.CHAR_UNDEFINED && keyCode >= 0 && |
| 384 | keyCode <= 127) |
| 385 | key = keyCode; |
| 386 | } |
| 387 | return UnicodeToKeysym.ucs2keysym(key); |
| 388 | } |
| 389 | |
| 390 | static LogWriter vlog = new LogWriter("Keysyms"); |
DRC | c5dc038 | 2011-05-13 21:42:14 +0000 | [diff] [blame] | 391 | } |