Add $ and ` for escaping and reorder it according to the ascii values
[midnight-commander.git] / slang / slgetkey.c
blob48ae3e1fbedfc72f62db97a01c85e389e3c19c25
1 /*
2 Copyright (C) 2004, 2005, 2006 John E. Davis
4 This file is part of the S-Lang Library.
6 The S-Lang Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
11 The S-Lang Library 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 GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 USA.
22 #include "slinclud.h"
24 #include "slang.h"
25 #include "_slang.h"
27 unsigned int SLang_Input_Buffer_Len = 0;
28 unsigned char SLang_Input_Buffer [SL_MAX_INPUT_BUFFER_LEN];
30 int SLang_Abort_Char = 7;
31 int SLang_Ignore_User_Abort = 0;
33 /* This has the effect of mapping all characters in the range 128-169 to
34 * ESC [ something
37 unsigned int SLang_getkey (void)
39 unsigned int imax;
40 unsigned int ch;
42 if (SLang_Input_Buffer_Len)
44 ch = (unsigned int) *SLang_Input_Buffer;
45 SLang_Input_Buffer_Len--;
46 imax = SLang_Input_Buffer_Len;
48 SLMEMCPY ((char *) SLang_Input_Buffer,
49 (char *) (SLang_Input_Buffer + 1), imax);
51 else if (SLANG_GETKEY_ERROR == (ch = _pSLsys_getkey ())) return ch;
53 #if SLANG_MAP_VTXXX_8BIT
54 # if !defined(IBMPC_SYSTEM)
55 if (ch & 0x80)
57 unsigned char i;
58 i = (unsigned char) (ch & 0x7F);
59 if (i < ' ')
61 i += 64;
62 SLang_ungetkey (i);
63 ch = 27;
66 # endif
67 #endif
68 return(ch);
71 int SLang_ungetkey_string (unsigned char *s, unsigned int n)
73 register unsigned char *bmax, *b, *b1;
74 if (SLang_Input_Buffer_Len + n + 3 > SL_MAX_INPUT_BUFFER_LEN)
75 return -1;
77 b = SLang_Input_Buffer;
78 bmax = (b - 1) + SLang_Input_Buffer_Len;
79 b1 = bmax + n;
80 while (bmax >= b) *b1-- = *bmax--;
81 bmax = b + n;
82 while (b < bmax) *b++ = *s++;
83 SLang_Input_Buffer_Len += n;
84 return 0;
87 int SLang_buffer_keystring (unsigned char *s, unsigned int n)
90 if (n + SLang_Input_Buffer_Len + 3 > SL_MAX_INPUT_BUFFER_LEN) return -1;
92 SLMEMCPY ((char *) SLang_Input_Buffer + SLang_Input_Buffer_Len,
93 (char *) s, n);
94 SLang_Input_Buffer_Len += n;
95 return 0;
98 int SLang_ungetkey (unsigned char ch)
100 return SLang_ungetkey_string(&ch, 1);
103 int SLang_input_pending (int tsecs)
105 int n;
106 unsigned char c;
107 if (SLang_Input_Buffer_Len) return (int) SLang_Input_Buffer_Len;
109 n = _pSLsys_input_pending (tsecs);
111 if (n <= 0) return 0;
113 c = (unsigned char) SLang_getkey ();
114 SLang_ungetkey_string (&c, 1);
116 return n;
119 void SLang_flush_input (void)
121 int quit = SLKeyBoard_Quit;
123 SLang_Input_Buffer_Len = 0;
124 SLKeyBoard_Quit = 0;
125 while (_pSLsys_input_pending (0) > 0)
127 (void) _pSLsys_getkey ();
128 /* Set this to 0 because _pSLsys_getkey may stuff keyboard buffer if
129 * key sends key sequence (OS/2, DOS, maybe VMS).
131 SLang_Input_Buffer_Len = 0;
133 SLKeyBoard_Quit = quit;
136 #ifdef IBMPC_SYSTEM
137 static int Map_To_ANSI;
138 int SLgetkey_map_to_ansi (int enable)
140 Map_To_ANSI = enable;
141 return 0;
144 static int convert_scancode (unsigned int scan,
145 unsigned int shift,
146 int getkey,
147 unsigned int *ret_key)
149 unsigned char buf[16];
150 unsigned char *b;
151 unsigned char end;
152 int is_arrow;
154 shift &= (_pSLTT_KEY_ALT|_pSLTT_KEY_SHIFT|_pSLTT_KEY_CTRL);
156 b = buf;
157 if (_pSLTT_KEY_ALT == shift)
159 shift = 0;
160 *b++ = 27;
162 *b++ = 27;
163 *b++ = '[';
165 is_arrow = 0;
166 end = '~';
167 if (shift)
169 if (shift == _pSLTT_KEY_CTRL)
170 end = '^';
171 else if (shift == _pSLTT_KEY_SHIFT)
172 end = '$';
173 else shift = 0;
176 /* These mappings correspond to what rxvt produces under Linux */
177 switch (scan & 0xFF)
179 default:
180 return -1;
182 case 0x47: /* home */
183 *b++ = '1';
184 break;
185 case 0x48: /* up */
186 end = 'A';
187 is_arrow = 1;
188 break;
189 case 0x49: /* PgUp */
190 *b++ = '5';
191 break;
192 case 0x4B: /* Left */
193 end = 'D';
194 is_arrow = 1;
195 break;
196 case 0x4D: /* Right */
197 end = 'C';
198 is_arrow = 1;
199 break;
200 case 0x4F: /* End */
201 *b++ = '4';
202 break;
203 case 0x50: /* Down */
204 end = 'B';
205 is_arrow = 1;
206 break;
207 case 0x51: /* PgDn */
208 *b++ = '6';
209 break;
210 case 0x52: /* Insert */
211 *b++ = '2';
212 break;
213 case 0x53: /* Delete */
214 *b++ = '3';
215 break;
216 case ';': /* F1 */
217 *b++ = '1';
218 *b++ = '1';
219 break;
220 case '<': /* F2 */
221 *b++ = '1';
222 *b++ = '2';
223 break;
224 case '=': /* F3 */
225 *b++ = '1';
226 *b++ = '3';
227 break;
229 case '>': /* F4 */
230 *b++ = '1';
231 *b++ = '4';
232 break;
234 case '?': /* F5 */
235 *b++ = '1';
236 *b++ = '5';
237 break;
239 case '@': /* F6 */
240 *b++ = '1';
241 *b++ = '7';
242 break;
244 case 'A': /* F7 */
245 *b++ = '1';
246 *b++ = '8';
247 break;
249 case 'B': /* F8 */
250 *b++ = '1';
251 *b++ = '9';
252 break;
254 case 'C': /* F9 */
255 *b++ = '2';
256 *b++ = '0';
257 break;
259 case 'D': /* F10 */
260 *b++ = '2';
261 *b++ = '1';
262 break;
264 case 0x57: /* F11 */
265 *b++ = '2';
266 *b++ = '3';
267 break;
269 case 0x58: /* F12 */
270 *b++ = '2';
271 *b++ = '4';
272 break;
275 if (is_arrow && shift)
277 if (shift == _pSLTT_KEY_CTRL)
278 end &= 0x1F;
279 else
280 end |= 0x20;
282 *b++ = end;
284 if (getkey)
286 (void) SLang_buffer_keystring (buf + 1, (unsigned int) (b - (buf + 1)));
287 *ret_key = buf[0];
288 return 0;
291 (void) SLang_buffer_keystring (buf, (unsigned int) (b - buf));
292 return 0;
296 unsigned int _pSLpc_convert_scancode (unsigned int scan,
297 unsigned int shift,
298 int getkey)
300 unsigned char buf[16];
302 if (Map_To_ANSI)
304 if (0 == convert_scancode (scan, shift, getkey, &scan))
305 return scan;
308 if (getkey)
310 buf[0] = scan & 0xFF;
311 SLang_buffer_keystring (buf, 1);
312 return (scan >> 8) & 0xFF;
314 buf[0] = (scan >> 8) & 0xFF;
315 buf[1] = scan & 0xFF;
316 (void) SLang_buffer_keystring (buf, 2);
317 return 0;
320 #endif