You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Keysyms.java 22KB

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