- Rearrange reactos.dff according to rosapps rearrange.
[reactos.git] / rosapps / mc / pc / key_os2.c
1 /* Keyboard support routines.
2 for OS/2 system.
3
4 20. April 97: Alexander Dong (ado)
5
6 This program 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 program 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 program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 */
21
22 #include <config.h>
23 #ifndef __os2__
24 #error This file is for OS/2 systems.
25 #else
26
27 #define INCL_BASE
28 #define INCL_NOPM
29 #define INCL_VIO
30 #define INCL_KBD
31 #define INCL_DOS
32 #define INCL_DOSERRORS
33 #define INCL_WININPUT
34 #include <os2.h>
35 #include <stdio.h>
36 #include "../src/mouse.h"
37 #include "../src/global.h"
38 #include "../src/main.h"
39 #include "../src/key.h"
40 #include "../vfs/vfs.h"
41 #include "../src/tty.h"
42
43 /* Code to read keystrokes in a separate thread */
44
45 typedef struct kbdcodes {
46 UCHAR ascii;
47 UCHAR scan;
48 USHORT shift; /* .ado: change for mc */
49 } KBDCODES;
50
51 /* Global variables */
52 int old_esc_mode = 0;
53 /* HANDLE hConsoleInput;
54 DWORD dwSaved_ControlState; */
55 Gpm_Event evSaved_Event;
56
57 /* Unused variables */
58 int double_click_speed; /* they are here to keep linker happy */
59 int mou_auto_repeat;
60 int use_8th_bit_as_meta = 0;
61
62 static int VKtoCurses (int vkcode);
63
64 /* -------------------------------------------------------------- */
65 /* DEFINITIONS:
66 Return from SLANG: KeyCode: 0xaaaabbcc
67
68 where: aaaa = Flags
69 bb = Scan code
70 cc = ASCII-code (if available)
71
72 if no flags (CTRL and ALT) is set, cc will be returned.
73 If CTRL is pressed, cc is already the XCTRL(code).
74 case cc is:
75 0xE0: The scan code will be used for the following keys:
76 Insert: 0x52, DEL: 0x53,
77 Page_Up: 0x49, Page_Down: 0x51,
78 Pos1: 0x47, Ende: 0x4F,
79 Up: 0x48, Down: 0x50,
80 Left: 0x4B, Right: 0x4D,
81
82 0x00: The function keys are defined as:
83 F1: 3b00, F2: 3c00 ... F10: 4400, F11: 8500, F12: 8600.
84 With ALT-bit set:
85 ALT(F1): 6800, 6900,... ALT(F10): 7100, ALT(F11): 8b00
86 ALT(F12): 8c00
87
88 Mapping for ALT(key_code):
89 For Mapping with normal keys, only the scan code can be
90 used. (see struct ALT_table)
91
92 Special keys:
93 ENTER (number block): 0xaaaaE00D
94 + (number block): 0xaaaa4E2B Normal: 1B2B
95 - (number block): 0xaaaa4A2D Normal: 352D
96 * (number block): 0xaaaa372A Normal: 1B2A
97 / (number block): 0xaaaaE02F
98 */
99 /* -------------------------------------------------------------- */
100 #define RIGHT_SHIFT_PRESSED 1
101 #define LEFT_SHIFT_PRESSED 2
102 #define CTRL_PRESSED 4
103 #define ALT_PRESSED 8
104 #define SCROLL_LOCK_MODE 16
105 #define NUM_LOCK_MODE 32
106 #define CAPS_LOCK_MODE 64
107 #define INSERT_MODE 128
108 #define LEFT_CTRL_PRESSED 256
109 #define LEFT_ALT_PRESSED 512
110 #define RIGHT_CTRL_PRESSED 1024
111 #define RIGHT_ALT_PRESSED 2048
112 #define SCROLL_LOCK_PRESSED 4096
113 #define NUM_LOCK_PRESSED 8192
114 #define CAPS_LOCK_PRESSED 16384
115 #define SYSREQ 32768
116 /* -------------------------------------------------------------- */
117
118 /* Static Tables */
119 struct {
120 int key_code;
121 int vkcode;
122 } fkt_table [] = {
123 { KEY_F(1), 0x3B },
124 { KEY_F(2), 0x3C },
125 { KEY_F(3), 0x3D },
126 { KEY_F(4), 0x3E },
127 { KEY_F(5), 0x3F },
128 { KEY_F(6), 0x40 },
129 { KEY_F(7), 0x41 },
130 { KEY_F(8), 0x42 },
131 { KEY_F(9), 0x43 },
132 { KEY_F(10), 0x44 },
133 { KEY_F(11), 0x85 },
134 { KEY_F(12), 0x86 },
135 { 0, 0}
136 };
137
138
139 struct {
140 int key_code;
141 int vkcode;
142 } ALT_table [] = {
143 { ALT('a'), 0x1E },
144 { ALT('b'), 0x30 },
145 { ALT('c'), 0x2E },
146 { ALT('d'), 0x20 },
147 { ALT('e'), 0x12 },
148 { ALT('f'), 0x21 },
149 { ALT('g'), 0x22 },
150 { ALT('h'), 0x23 },
151 { ALT('i'), 0x17 },
152 { ALT('j'), 0x24 },
153 { ALT('k'), 0x25 },
154 { ALT('l'), 0x26 },
155 { ALT('m'), 0x32 },
156 { ALT('n'), 0x31 },
157 { ALT('o'), 0x18 },
158 { ALT('p'), 0x19 },
159 { ALT('q'), 0x10 },
160 { ALT('r'), 0x13 },
161 { ALT('s'), 0x1F },
162 { ALT('t'), 0x14 },
163 { ALT('u'), 0x16 },
164 { ALT('v'), 0x2F },
165 { ALT('w'), 0x11 },
166 { ALT('x'), 0x2D },
167 { ALT('y'), 0x15 },
168 { ALT('z'), 0x2C },
169 { ALT('\n'), 0x1c },
170 { ALT('\n'), 0xA6 },
171 { ALT(KEY_F(1)), 0x68 },
172 { ALT(KEY_F(2)), 0x69 },
173 { ALT(KEY_F(3)), 0x6A },
174 { ALT(KEY_F(4)), 0x6B },
175 { ALT(KEY_F(5)), 0x6C },
176 { ALT(KEY_F(6)), 0x6D },
177 { ALT(KEY_F(7)), 0x6E },
178 { ALT(KEY_F(8)), 0x6F },
179 { ALT(KEY_F(9)), 0x70 },
180 { ALT(KEY_F(10)), 0x71 },
181 { ALT(KEY_F(11)), 0x8B },
182 { ALT(KEY_F(12)), 0x8C },
183 { 0, 0}
184 };
185
186
187 struct {
188 int key_code;
189 int vkcode;
190 } movement [] = {
191 { KEY_IC, 0x52 },
192 { KEY_DC, 0x53 },
193 { KEY_PPAGE, 0x49 },
194 { KEY_NPAGE, 0x51 },
195 { KEY_LEFT, 0x4B },
196 { KEY_RIGHT, 0x4D },
197 { KEY_UP, 0x48 },
198 { KEY_DOWN, 0x50 },
199 { KEY_HOME, 0x47 },
200 { KEY_END, 0x4F },
201 { 0, 0}
202 };
203
204
205 /* init_key -- to make linker happy */
206 void init_key (void)
207 {
208 return;
209 }
210
211
212 /* The maximum sequence length (32 + null terminator) */
213 static int seq_buffer[33];
214 static int *seq_append = 0;
215
216 static int push_char (int c)
217 {
218 if (!seq_append)
219 seq_append = seq_buffer;
220
221 if (seq_append == &(seq_buffer [sizeof (seq_buffer)-2]))
222 return 0;
223 *(seq_append++) = c;
224 *seq_append = 0;
225 return 1;
226 }
227
228 int get_key_code (int no_delay)
229 {
230 unsigned int inp_ch;
231
232 if (no_delay) {
233 /* Check if any input pending, otherwise return */
234 nodelay (stdscr, TRUE);
235 inp_ch = SLang_input_pending(0);
236 if (inp_ch == 0) {
237 return 0;
238 }
239 }
240
241 if (no_delay) {
242 return (VKtoCurses(inp_ch));
243 }
244
245 do {
246 inp_ch = SLang_getkey();
247 if (!inp_ch)
248 inp_ch = (SLang_getkey() << 8);
249 if (inp_ch) return (VKtoCurses(inp_ch));
250 } while (!no_delay);
251 return 0;
252 }
253
254 static int VKtoCurses (int a_vkc)
255 {
256 int ctrlState = 0;
257 int altState = 0;
258
259 int fsState;
260 char scanCode;
261 char asciiCode;
262 register int i;
263 int rtnCode = 0;
264
265 fsState = (a_vkc & 0xFFFF0000) >> 16;
266 fsState &= (~INSERT_MODE); /* Ignore Insertion mode */
267
268 scanCode = (char) ((a_vkc & 0x0000FFFF) >> 8);
269 asciiCode = (char) (a_vkc & 0x000000FF);
270
271 ctrlState = (fsState & CTRL_PRESSED);
272 altState = (fsState & ALT_PRESSED);
273
274 rtnCode = asciiCode;
275
276 if (ctrlState) {
277 /* CTRL pressed */
278 rtnCode = XCTRL(asciiCode);
279 }
280
281 if (altState) {
282 /* ALT pressed
283 * rtnCode = ALT(asciiCode);
284 *
285 * With German keyboards, the Values between 7B -> 7D
286 * and 5b, 5d, 40, fd, fc and e6 are only reachable with the AltGr
287 * key. If such a combination is used, asciiCode will not be zero.
288 * With the normal ALT key, the asciiCode will always be zero.
289 */
290 if (asciiCode) {
291 return asciiCode;
292 }
293 }
294
295 /* Scan Movement codes */
296 if (asciiCode == 0) {
297 /* Replace key code with that in table */
298 for (i=0; movement[i].vkcode != 0 || movement[i].key_code != 0; i++)
299 if (scanCode == movement[i].vkcode)
300 return (movement[i].key_code);
301 }
302
303 if (asciiCode == 0) {
304 /* Function-key detected */
305 for (i=0; fkt_table[i].vkcode != 0 || fkt_table[i].key_code != 0; i++)
306 if (scanCode == fkt_table[i].vkcode)
307 return (fkt_table[i].key_code);
308 /* ALT - KEY */
309 /* if (altState) */ {
310 for (i=0; ALT_table[i].vkcode != 0 || ALT_table[i].key_code != 0; i++)
311 if (scanCode == ALT_table[i].vkcode)
312 return (ALT_table[i].key_code);
313 }
314 }
315
316 if (asciiCode == 0x0d) {
317 return '\n';
318 }
319
320 return rtnCode;
321 }
322
323
324 static int getch_with_delay (void)
325 {
326 int c;
327
328 while (1) {
329 /* Try to get a character */
330 c = get_key_code (0);
331 if (c != ERR)
332 break;
333 }
334 /* Success -> return the character */
335 return c;
336 }
337
338 int get_event (Gpm_Event *event, int redo_event, int block)
339 {
340 int c;
341 static int dirty = 3;
342
343 if ((dirty == 1) || is_idle ()){
344 refresh ();
345 doupdate ();
346 dirty = 1;
347 } else
348 dirty++;
349
350 vfs_timeout_handler ();
351
352 c = block ? getch_with_delay () : get_key_code (1);
353 if (!c) {
354 /* Code is 0, so this is a Control key or mouse event */
355 *event = evSaved_Event;
356 return EV_NONE; /* FIXME: when should we return EV_MOUSE ? */
357 }
358
359 return c;
360 }
361
362 /* Returns a key press, mouse events are discarded */
363 int mi_getch ()
364 {
365 Gpm_Event ev;
366 int key;
367
368 while ((key = get_event (&ev, 0, 1)) == 0)
369 ;
370 return key;
371 }
372
373
374 /*
375 is_idle - A function to check if we're idle.
376 It checks for any waiting event (that can be a Key, Mouse event,
377 and other internal events like focus or menu)
378 */
379 int is_idle (void)
380 {
381 return 1;
382 }
383
384 /* get_modifier */
385 int get_modifier()
386 {
387 return 0;
388 }
389
390 int ctrl_pressed ()
391 {
392 return 0;
393 }
394
395
396 /* void functions for UNIX copatibility */
397 void define_sequence (int code, char* vkcode, int action) {}
398 void channels_up() {}
399 void channels_down() {}
400 void init_key_input_fd (void) {}
401 void numeric_keypad_mode (void) {}
402 void application_keypad_mode (void) {}
403
404 /* mouse is not yet supported, sorry */
405 void init_mouse (void) {}
406 void shut_mouse (void) {}
407
408 #endif /* __os2__ */