key_nt.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /* Keyboard support routines.
  2. for Windows NT system.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. Bugs:
  15. Have trouble with non-US keyboards, "Alt-gr"+keys (API tells CTRL-ALT is pressed)
  16. */
  17. #include <config.h>
  18. #ifndef NATIVE_WIN32
  19. #error "This file is for Win32 systems only"
  20. #else
  21. #include <stdio.h>
  22. #include "../src/global.h"
  23. #include "../src/mouse.h"
  24. #include "../src/main.h"
  25. #include "../src/key.h"
  26. #include "../vfs/vfs.h"
  27. #include "../src/tty.h"
  28. #include "trace_nt.h"
  29. /* Global variables */
  30. int old_esc_mode = 0;
  31. HANDLE hConsoleInput;
  32. DWORD dwSaved_ControlState;
  33. Gpm_Event evSaved_Event;
  34. /* Unused variables */
  35. int double_click_speed; /* they are here to keep linker happy */
  36. int mou_auto_repeat;
  37. int use_8th_bit_as_meta = 0;
  38. /* Static Tables */
  39. struct {
  40. int key_code;
  41. int vkcode;
  42. } fkt_table [] = {
  43. { KEY_F(1), VK_F1 },
  44. { KEY_F(2), VK_F2 },
  45. { KEY_F(3), VK_F3 },
  46. { KEY_F(4), VK_F4 },
  47. { KEY_F(5), VK_F5 },
  48. { KEY_F(6), VK_F6 },
  49. { KEY_F(7), VK_F7 },
  50. { KEY_F(8), VK_F8 },
  51. { KEY_F(9), VK_F9 },
  52. { KEY_F(10), VK_F10 },
  53. { KEY_F(11), VK_F11 },
  54. { KEY_F(12), VK_F12 },
  55. { KEY_F(13), VK_F13 },
  56. { KEY_F(14), VK_F14 },
  57. { KEY_F(15), VK_F15 },
  58. { KEY_F(16), VK_F16 },
  59. { KEY_F(17), VK_F17 },
  60. { KEY_F(18), VK_F18 },
  61. { KEY_F(19), VK_F19 },
  62. { KEY_F(20), VK_F20 },
  63. { KEY_IC, VK_INSERT },
  64. { KEY_DC, VK_DELETE },
  65. { KEY_BACKSPACE, VK_BACK },
  66. { KEY_PPAGE, VK_PRIOR },
  67. { KEY_NPAGE, VK_NEXT },
  68. { KEY_LEFT, VK_LEFT },
  69. { KEY_RIGHT, VK_RIGHT },
  70. { KEY_UP, VK_UP },
  71. { KEY_DOWN, VK_DOWN },
  72. { KEY_HOME, VK_HOME },
  73. { KEY_END, VK_END },
  74. { ALT('*'), VK_MULTIPLY },
  75. { ALT('+'), VK_ADD },
  76. { ALT('-'), VK_SUBTRACT },
  77. { ALT('\t'), VK_PAUSE }, /* Added to make Complete work press Pause */
  78. { ESC_CHAR, VK_ESCAPE },
  79. { 0, 0}
  80. };
  81. /* init_key - Called in main.c to initialize ourselves
  82. Get handle to console input
  83. */
  84. void init_key (void)
  85. {
  86. win32APICALL_HANDLE (hConsoleInput, GetStdHandle (STD_INPUT_HANDLE));
  87. }
  88. int ctrl_pressed ()
  89. {
  90. if(dwSaved_ControlState & RIGHT_ALT_PRESSED) return 0;
  91. /* The line above fixes the BUG with the AltGr Keys*/
  92. return dwSaved_ControlState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED);
  93. }
  94. int shift_pressed ()
  95. {
  96. return dwSaved_ControlState & SHIFT_PRESSED;
  97. }
  98. int alt_pressed ()
  99. {
  100. return dwSaved_ControlState & (/* RIGHT_ALT_PRESSED |*/ LEFT_ALT_PRESSED );
  101. }
  102. static int VKtoCurses (int a_vkc)
  103. {
  104. int i;
  105. for (i = 0; fkt_table[i].vkcode != 0; i++)
  106. if (a_vkc == fkt_table[i].vkcode) {
  107. return fkt_table[i].key_code;
  108. }
  109. return 0;
  110. }
  111. static int translate_key_code(int asc, int scan)
  112. {
  113. int c;
  114. switch(scan){
  115. case 106: /* KP_MULT*/
  116. return ALT('*');
  117. case 107: /* KP_PLUS*/
  118. return ALT('+');
  119. case 109: /* KP_MINUS*/
  120. return ALT('-');
  121. }
  122. c = VKtoCurses (scan);
  123. if (!asc && !c)
  124. return 0;
  125. if (asc && c)
  126. return c;
  127. if (!asc || asc=='\t' )
  128. {
  129. if (shift_pressed() && (c >= KEY_F(1)) && (c <= KEY_F(10)))
  130. c += 10;
  131. if (alt_pressed() && (c >= KEY_F(1)) && (c <= KEY_F(2)))
  132. c += 10;
  133. if (alt_pressed() && (c == KEY_F(7)))
  134. c = ALT('?');
  135. if (asc == '\t'){
  136. if(ctrl_pressed())c = ALT('\t');
  137. else c=asc;
  138. }
  139. return c;
  140. }
  141. if (ctrl_pressed())
  142. return XCTRL(asc);
  143. if (alt_pressed())
  144. return ALT(asc);
  145. if (asc == 13)
  146. return 10;
  147. return asc;
  148. }
  149. int get_key_code (int no_delay)
  150. {
  151. INPUT_RECORD ir; /* Input record */
  152. DWORD dw; /* number of records actually read */
  153. int ch, vkcode, j;
  154. if (no_delay) {
  155. /* Check if any input pending, otherwise return */
  156. nodelay (stdscr, TRUE);
  157. win32APICALL(PeekConsoleInput(hConsoleInput, &ir, 1, &dw));
  158. if (!dw)
  159. return 0;
  160. }
  161. do {
  162. win32APICALL(ReadConsoleInput(hConsoleInput, &ir, 1, &dw));
  163. switch (ir.EventType) {
  164. case KEY_EVENT:
  165. if (!ir.Event.KeyEvent.bKeyDown) /* Process key just once: when pressed */
  166. break;
  167. vkcode = ir.Event.KeyEvent.wVirtualKeyCode;
  168. //#ifndef __MINGW32__
  169. ch = ir.Event.KeyEvent.uChar.AsciiChar;
  170. //#else
  171. // ch = ir.Event.KeyEvent.AsciiChar;
  172. //#endif
  173. dwSaved_ControlState = ir.Event.KeyEvent.dwControlKeyState;
  174. j = translate_key_code (ch, vkcode);
  175. if (j)
  176. return j;
  177. break;
  178. case MOUSE_EVENT:
  179. /* Save event as a GPM-like event */
  180. evSaved_Event.x = ir.Event.MouseEvent.dwMousePosition.X;
  181. evSaved_Event.y = ir.Event.MouseEvent.dwMousePosition.Y+1;
  182. evSaved_Event.buttons = ir.Event.MouseEvent.dwButtonState;
  183. switch (ir.Event.MouseEvent.dwEventFlags) {
  184. case 0:
  185. evSaved_Event.type = GPM_DOWN | GPM_SINGLE;
  186. break;
  187. case MOUSE_MOVED:
  188. evSaved_Event.type = GPM_MOVE;
  189. break;
  190. case DOUBLE_CLICK:
  191. evSaved_Event.type = GPM_DOWN | GPM_DOUBLE;
  192. break;
  193. };
  194. return 0;
  195. }
  196. } while (!no_delay);
  197. return 0;
  198. }
  199. static int getch_with_delay (void)
  200. {
  201. int c;
  202. while (1) {
  203. /* Try to get a character */
  204. c = get_key_code (0);
  205. if (c != ERR)
  206. break;
  207. }
  208. /* Success -> return the character */
  209. return c;
  210. }
  211. /* Returns a character read from stdin with appropriate interpretation */
  212. int get_event (Gpm_Event *event, int redo_event, int block)
  213. {
  214. int c;
  215. static int flag; /* Return value from select */
  216. static int dirty = 3;
  217. if ((dirty == 1) || is_idle ()){
  218. refresh ();
  219. doupdate ();
  220. dirty = 1;
  221. } else
  222. dirty++;
  223. vfs_timeout_handler ();
  224. c = block ? getch_with_delay () : get_key_code (1);
  225. if (!c) {
  226. /* Code is 0, so this is a Control key or mouse event */
  227. return EV_NONE; /* FIXME: mouse not supported */
  228. }
  229. return c;
  230. }
  231. /* Returns a key press, mouse events are discarded */
  232. int mi_getch ()
  233. {
  234. Gpm_Event ev;
  235. int key;
  236. while ((key = get_event (&ev, 0, 1)) == 0)
  237. ;
  238. return key;
  239. }
  240. /*
  241. is_idle - A function to check if we're idle.
  242. It checks for any waiting event (that can be a Key, Mouse event,
  243. and other internal events like focus or menu)
  244. */
  245. int is_idle (void)
  246. {
  247. DWORD dw;
  248. if (GetNumberOfConsoleInputEvents (hConsoleInput, &dw))
  249. if (dw > 15)
  250. return 0;
  251. return 1;
  252. }
  253. /* get_modifier */
  254. int get_modifier()
  255. {
  256. int retval = 0;
  257. if (dwSaved_ControlState & LEFT_ALT_PRESSED) /* code is not clean, because we return Linux-like bitcodes*/
  258. retval |= ALTL_PRESSED;
  259. if (dwSaved_ControlState & RIGHT_ALT_PRESSED)
  260. retval |= ALTR_PRESSED;
  261. if (dwSaved_ControlState & RIGHT_CTRL_PRESSED ||
  262. dwSaved_ControlState & LEFT_CTRL_PRESSED)
  263. retval |= CONTROL_PRESSED;
  264. if (dwSaved_ControlState & SHIFT_PRESSED)
  265. retval |= SHIFT_PRESSED;
  266. return retval;
  267. }
  268. /* void functions for UNIX compatibility */
  269. int define_sequence (int code, char* vkcode, int action) { return 1; }
  270. void channels_up() {}
  271. void channels_down() {}
  272. void init_key_input_fd (void) {}
  273. void numeric_keypad_mode (void) {}
  274. void application_keypad_mode (void) {}
  275. /* mouse is not yet supported, sorry */
  276. void init_mouse (void) {}
  277. void shut_mouse (void) {}
  278. #endif /* NATIVE_WIN32 */