fix
[midnight-commander.git] / slang / slgetkey.c
blob4795f0e14528d3329ccdc4b5aaf7c73033cfb08d
1 /* Copyright (c) 1992, 1999, 2001, 2002 John E. Davis
2 * This file is part of the S-Lang library.
4 * You may distribute under the terms of either the GNU General Public
5 * License or the Perl Artistic License.
6 */
8 #include "slinclud.h"
10 #include "slang.h"
11 #include "_slang.h"
13 unsigned int SLang_Input_Buffer_Len = 0;
14 unsigned char SLang_Input_Buffer [SL_MAX_INPUT_BUFFER_LEN];
16 int SLang_Abort_Char = 7;
17 int SLang_Ignore_User_Abort = 0;
19 /* This has the effect of mapping all characters in the range 128-169 to
20 * ESC [ something
23 unsigned int SLang_getkey (void)
25 unsigned int imax;
26 unsigned int ch;
28 if (SLang_Input_Buffer_Len)
30 ch = (unsigned int) *SLang_Input_Buffer;
31 SLang_Input_Buffer_Len--;
32 imax = SLang_Input_Buffer_Len;
34 SLMEMCPY ((char *) SLang_Input_Buffer,
35 (char *) (SLang_Input_Buffer + 1), imax);
37 else if (SLANG_GETKEY_ERROR == (ch = _SLsys_getkey ())) return ch;
39 #if _SLANG_MAP_VTXXX_8BIT
40 # if !defined(IBMPC_SYSTEM)
41 if (ch & 0x80)
43 unsigned char i;
44 i = (unsigned char) (ch & 0x7F);
45 if (i < ' ')
47 i += 64;
48 SLang_ungetkey (i);
49 ch = 27;
52 # endif
53 #endif
54 return(ch);
57 int SLang_ungetkey_string (unsigned char *s, unsigned int n)
59 register unsigned char *bmax, *b, *b1;
60 if (SLang_Input_Buffer_Len + n + 3 > SL_MAX_INPUT_BUFFER_LEN)
61 return -1;
63 b = SLang_Input_Buffer;
64 bmax = (b - 1) + SLang_Input_Buffer_Len;
65 b1 = bmax + n;
66 while (bmax >= b) *b1-- = *bmax--;
67 bmax = b + n;
68 while (b < bmax) *b++ = *s++;
69 SLang_Input_Buffer_Len += n;
70 return 0;
73 int SLang_buffer_keystring (unsigned char *s, unsigned int n)
76 if (n + SLang_Input_Buffer_Len + 3 > SL_MAX_INPUT_BUFFER_LEN) return -1;
78 SLMEMCPY ((char *) SLang_Input_Buffer + SLang_Input_Buffer_Len,
79 (char *) s, n);
80 SLang_Input_Buffer_Len += n;
81 return 0;
84 int SLang_ungetkey (unsigned char ch)
86 return SLang_ungetkey_string(&ch, 1);
89 int SLang_input_pending (int tsecs)
91 int n;
92 unsigned char c;
93 if (SLang_Input_Buffer_Len) return (int) SLang_Input_Buffer_Len;
95 n = _SLsys_input_pending (tsecs);
97 if (n <= 0) return 0;
99 c = (unsigned char) SLang_getkey ();
100 SLang_ungetkey_string (&c, 1);
102 return n;
105 void SLang_flush_input (void)
107 int quit = SLKeyBoard_Quit;
109 SLang_Input_Buffer_Len = 0;
110 SLKeyBoard_Quit = 0;
111 while (_SLsys_input_pending (0) > 0)
113 (void) _SLsys_getkey ();
114 /* Set this to 0 because _SLsys_getkey may stuff keyboard buffer if
115 * key sends key sequence (OS/2, DOS, maybe VMS).
117 SLang_Input_Buffer_Len = 0;
119 SLKeyBoard_Quit = quit;
122 #ifdef IBMPC_SYSTEM
123 static int Map_To_ANSI;
124 int SLgetkey_map_to_ansi (int enable)
126 Map_To_ANSI = enable;
127 return 0;
130 static int convert_scancode (unsigned int scan,
131 unsigned int shift,
132 int getkey,
133 unsigned int *ret_key)
135 unsigned char buf[16];
136 unsigned char *b;
137 unsigned char end;
138 int is_arrow;
140 shift &= (_SLTT_KEY_ALT|_SLTT_KEY_SHIFT|_SLTT_KEY_CTRL);
142 b = buf;
143 if (_SLTT_KEY_ALT == shift)
145 shift = 0;
146 *b++ = 27;
148 *b++ = 27;
149 *b++ = '[';
151 is_arrow = 0;
152 end = '~';
153 if (shift)
155 if (shift == _SLTT_KEY_CTRL)
156 end = '^';
157 else if (shift == _SLTT_KEY_SHIFT)
158 end = '$';
159 else shift = 0;
162 /* These mappings correspond to what rxvt produces under Linux */
163 switch (scan & 0xFF)
165 default:
166 return -1;
168 case 0x47: /* home */
169 *b++ = '1';
170 break;
171 case 0x48: /* up */
172 end = 'A';
173 is_arrow = 1;
174 break;
175 case 0x49: /* PgUp */
176 *b++ = '5';
177 break;
178 case 0x4B: /* Left */
179 end = 'D';
180 is_arrow = 1;
181 break;
182 case 0x4D: /* Right */
183 end = 'C';
184 is_arrow = 1;
185 break;
186 case 0x4F: /* End */
187 *b++ = '4';
188 break;
189 case 0x50: /* Down */
190 end = 'B';
191 is_arrow = 1;
192 break;
193 case 0x51: /* PgDn */
194 *b++ = '6';
195 break;
196 case 0x52: /* Insert */
197 *b++ = '2';
198 break;
199 case 0x53: /* Delete */
200 *b++ = '3';
201 break;
202 case ';': /* F1 */
203 *b++ = '1';
204 *b++ = '1';
205 break;
206 case '<': /* F2 */
207 *b++ = '1';
208 *b++ = '2';
209 break;
210 case '=': /* F3 */
211 *b++ = '1';
212 *b++ = '3';
213 break;
215 case '>': /* F4 */
216 *b++ = '1';
217 *b++ = '4';
218 break;
220 case '?': /* F5 */
221 *b++ = '1';
222 *b++ = '5';
223 break;
225 case '@': /* F6 */
226 *b++ = '1';
227 *b++ = '7';
228 break;
230 case 'A': /* F7 */
231 *b++ = '1';
232 *b++ = '8';
233 break;
235 case 'B': /* F8 */
236 *b++ = '1';
237 *b++ = '9';
238 break;
240 case 'C': /* F9 */
241 *b++ = '2';
242 *b++ = '0';
243 break;
245 case 'D': /* F10 */
246 *b++ = '2';
247 *b++ = '1';
248 break;
250 case 0x57: /* F11 */
251 *b++ = '2';
252 *b++ = '3';
253 break;
255 case 0x58: /* F12 */
256 *b++ = '2';
257 *b++ = '4';
258 break;
261 if (is_arrow && shift)
263 if (shift == _SLTT_KEY_CTRL)
264 end &= 0x1F;
265 else
266 end |= 0x20;
268 *b++ = end;
270 if (getkey)
272 (void) SLang_buffer_keystring (buf + 1, (unsigned int) (b - (buf + 1)));
273 *ret_key = buf[0];
274 return 0;
277 (void) SLang_buffer_keystring (buf, (unsigned int) (b - buf));
278 return 0;
282 unsigned int _SLpc_convert_scancode (unsigned int scan,
283 unsigned int shift,
284 int getkey)
286 unsigned char buf[16];
288 if (Map_To_ANSI)
290 if (0 == convert_scancode (scan, shift, getkey, &scan))
291 return scan;
294 if (getkey)
296 buf[0] = scan & 0xFF;
297 SLang_buffer_keystring (buf, 1);
298 return (scan >> 8) & 0xFF;
300 buf[0] = (scan >> 8) & 0xFF;
301 buf[1] = scan & 0xFF;
302 (void) SLang_buffer_keystring (buf, 2);
303 return 0;
306 #endif