slgetkey.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. Copyright (C) 2004, 2005, 2006 John E. Davis
  3. This file is part of the S-Lang Library.
  4. The S-Lang Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8. The S-Lang Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this library; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  15. USA.
  16. */
  17. #include "slinclud.h"
  18. #include "slang.h"
  19. #include "_slang.h"
  20. unsigned int SLang_Input_Buffer_Len = 0;
  21. unsigned char SLang_Input_Buffer [SL_MAX_INPUT_BUFFER_LEN];
  22. int SLang_Abort_Char = 7;
  23. int SLang_Ignore_User_Abort = 0;
  24. /* This has the effect of mapping all characters in the range 128-169 to
  25. * ESC [ something
  26. */
  27. unsigned int SLang_getkey (void)
  28. {
  29. unsigned int imax;
  30. unsigned int ch;
  31. if (SLang_Input_Buffer_Len)
  32. {
  33. ch = (unsigned int) *SLang_Input_Buffer;
  34. SLang_Input_Buffer_Len--;
  35. imax = SLang_Input_Buffer_Len;
  36. SLMEMCPY ((char *) SLang_Input_Buffer,
  37. (char *) (SLang_Input_Buffer + 1), imax);
  38. }
  39. else if (SLANG_GETKEY_ERROR == (ch = _pSLsys_getkey ())) return ch;
  40. #if SLANG_MAP_VTXXX_8BIT
  41. # if !defined(IBMPC_SYSTEM)
  42. if (ch & 0x80)
  43. {
  44. unsigned char i;
  45. i = (unsigned char) (ch & 0x7F);
  46. if (i < ' ')
  47. {
  48. i += 64;
  49. SLang_ungetkey (i);
  50. ch = 27;
  51. }
  52. }
  53. # endif
  54. #endif
  55. return(ch);
  56. }
  57. int SLang_ungetkey_string (unsigned char *s, unsigned int n)
  58. {
  59. register unsigned char *bmax, *b, *b1;
  60. if (SLang_Input_Buffer_Len + n + 3 > SL_MAX_INPUT_BUFFER_LEN)
  61. return -1;
  62. b = SLang_Input_Buffer;
  63. bmax = (b - 1) + SLang_Input_Buffer_Len;
  64. b1 = bmax + n;
  65. while (bmax >= b) *b1-- = *bmax--;
  66. bmax = b + n;
  67. while (b < bmax) *b++ = *s++;
  68. SLang_Input_Buffer_Len += n;
  69. return 0;
  70. }
  71. int SLang_buffer_keystring (unsigned char *s, unsigned int n)
  72. {
  73. if (n + SLang_Input_Buffer_Len + 3 > SL_MAX_INPUT_BUFFER_LEN) return -1;
  74. SLMEMCPY ((char *) SLang_Input_Buffer + SLang_Input_Buffer_Len,
  75. (char *) s, n);
  76. SLang_Input_Buffer_Len += n;
  77. return 0;
  78. }
  79. int SLang_ungetkey (unsigned char ch)
  80. {
  81. return SLang_ungetkey_string(&ch, 1);
  82. }
  83. int SLang_input_pending (int tsecs)
  84. {
  85. int n;
  86. unsigned char c;
  87. if (SLang_Input_Buffer_Len) return (int) SLang_Input_Buffer_Len;
  88. n = _pSLsys_input_pending (tsecs);
  89. if (n <= 0) return 0;
  90. c = (unsigned char) SLang_getkey ();
  91. SLang_ungetkey_string (&c, 1);
  92. return n;
  93. }
  94. void SLang_flush_input (void)
  95. {
  96. int quit = SLKeyBoard_Quit;
  97. SLang_Input_Buffer_Len = 0;
  98. SLKeyBoard_Quit = 0;
  99. while (_pSLsys_input_pending (0) > 0)
  100. {
  101. (void) _pSLsys_getkey ();
  102. /* Set this to 0 because _pSLsys_getkey may stuff keyboard buffer if
  103. * key sends key sequence (OS/2, DOS, maybe VMS).
  104. */
  105. SLang_Input_Buffer_Len = 0;
  106. }
  107. SLKeyBoard_Quit = quit;
  108. }
  109. #ifdef IBMPC_SYSTEM
  110. static int Map_To_ANSI;
  111. int SLgetkey_map_to_ansi (int enable)
  112. {
  113. Map_To_ANSI = enable;
  114. return 0;
  115. }
  116. static int convert_scancode (unsigned int scan,
  117. unsigned int shift,
  118. int getkey,
  119. unsigned int *ret_key)
  120. {
  121. unsigned char buf[16];
  122. unsigned char *b;
  123. unsigned char end;
  124. int is_arrow;
  125. shift &= (_pSLTT_KEY_ALT|_pSLTT_KEY_SHIFT|_pSLTT_KEY_CTRL);
  126. b = buf;
  127. if (_pSLTT_KEY_ALT == shift)
  128. {
  129. shift = 0;
  130. *b++ = 27;
  131. }
  132. *b++ = 27;
  133. *b++ = '[';
  134. is_arrow = 0;
  135. end = '~';
  136. if (shift)
  137. {
  138. if (shift == _pSLTT_KEY_CTRL)
  139. end = '^';
  140. else if (shift == _pSLTT_KEY_SHIFT)
  141. end = '$';
  142. else shift = 0;
  143. }
  144. /* These mappings correspond to what rxvt produces under Linux */
  145. switch (scan & 0xFF)
  146. {
  147. default:
  148. return -1;
  149. case 0x47: /* home */
  150. *b++ = '1';
  151. break;
  152. case 0x48: /* up */
  153. end = 'A';
  154. is_arrow = 1;
  155. break;
  156. case 0x49: /* PgUp */
  157. *b++ = '5';
  158. break;
  159. case 0x4B: /* Left */
  160. end = 'D';
  161. is_arrow = 1;
  162. break;
  163. case 0x4D: /* Right */
  164. end = 'C';
  165. is_arrow = 1;
  166. break;
  167. case 0x4F: /* End */
  168. *b++ = '4';
  169. break;
  170. case 0x50: /* Down */
  171. end = 'B';
  172. is_arrow = 1;
  173. break;
  174. case 0x51: /* PgDn */
  175. *b++ = '6';
  176. break;
  177. case 0x52: /* Insert */
  178. *b++ = '2';
  179. break;
  180. case 0x53: /* Delete */
  181. *b++ = '3';
  182. break;
  183. case ';': /* F1 */
  184. *b++ = '1';
  185. *b++ = '1';
  186. break;
  187. case '<': /* F2 */
  188. *b++ = '1';
  189. *b++ = '2';
  190. break;
  191. case '=': /* F3 */
  192. *b++ = '1';
  193. *b++ = '3';
  194. break;
  195. case '>': /* F4 */
  196. *b++ = '1';
  197. *b++ = '4';
  198. break;
  199. case '?': /* F5 */
  200. *b++ = '1';
  201. *b++ = '5';
  202. break;
  203. case '@': /* F6 */
  204. *b++ = '1';
  205. *b++ = '7';
  206. break;
  207. case 'A': /* F7 */
  208. *b++ = '1';
  209. *b++ = '8';
  210. break;
  211. case 'B': /* F8 */
  212. *b++ = '1';
  213. *b++ = '9';
  214. break;
  215. case 'C': /* F9 */
  216. *b++ = '2';
  217. *b++ = '0';
  218. break;
  219. case 'D': /* F10 */
  220. *b++ = '2';
  221. *b++ = '1';
  222. break;
  223. case 0x57: /* F11 */
  224. *b++ = '2';
  225. *b++ = '3';
  226. break;
  227. case 0x58: /* F12 */
  228. *b++ = '2';
  229. *b++ = '4';
  230. break;
  231. }
  232. if (is_arrow && shift)
  233. {
  234. if (shift == _pSLTT_KEY_CTRL)
  235. end &= 0x1F;
  236. else
  237. end |= 0x20;
  238. }
  239. *b++ = end;
  240. if (getkey)
  241. {
  242. (void) SLang_buffer_keystring (buf + 1, (unsigned int) (b - (buf + 1)));
  243. *ret_key = buf[0];
  244. return 0;
  245. }
  246. (void) SLang_buffer_keystring (buf, (unsigned int) (b - buf));
  247. return 0;
  248. }
  249. unsigned int _pSLpc_convert_scancode (unsigned int scan,
  250. unsigned int shift,
  251. int getkey)
  252. {
  253. unsigned char buf[16];
  254. if (Map_To_ANSI)
  255. {
  256. if (0 == convert_scancode (scan, shift, getkey, &scan))
  257. return scan;
  258. }
  259. if (getkey)
  260. {
  261. buf[0] = scan & 0xFF;
  262. SLang_buffer_keystring (buf, 1);
  263. return (scan >> 8) & 0xFF;
  264. }
  265. buf[0] = (scan >> 8) & 0xFF;
  266. buf[1] = scan & 0xFF;
  267. (void) SLang_buffer_keystring (buf, 2);
  268. return 0;
  269. }
  270. #endif