De-fuzzyed some msgs...
[midnight-commander.git] / pc / key_os2.c
blobd50c0db11e7bf7e589c86f86c8dd2feca4a88fcc
1 /* Keyboard support routines.
2 for OS/2 system.
4 20. April 97: Alexander Dong (ado)
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include <config.h>
23 #ifndef __os2__
24 #error "This file is for OS/2 systems only"
25 #else
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"
43 /* Code to read keystrokes in a separate thread */
45 typedef struct kbdcodes {
46 UCHAR ascii;
47 UCHAR scan;
48 USHORT shift; /* .ado: change for mc */
49 } KBDCODES;
51 /* Global variables */
52 int old_esc_mode = 0;
53 /* HANDLE hConsoleInput;
54 DWORD dwSaved_ControlState; */
55 Gpm_Event evSaved_Event;
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;
62 static int VKtoCurses (int vkcode);
64 /* -------------------------------------------------------------- */
65 /* DEFINITIONS:
66 Return from SLANG: KeyCode: 0xaaaabbcc
68 where: aaaa = Flags
69 bb = Scan code
70 cc = ASCII-code (if available)
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,
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
88 Mapping for ALT(key_code):
89 For Mapping with normal keys, only the scan code can be
90 used. (see struct ALT_table)
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
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 /* -------------------------------------------------------------- */
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}
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}
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}
205 /* init_key -- to make linker happy */
206 void init_key (void)
208 return;
212 /* The maximum sequence length (32 + null terminator) */
213 static int seq_buffer[33];
214 static int *seq_append = 0;
216 static int push_char (int c)
218 if (!seq_append)
219 seq_append = seq_buffer;
221 if (seq_append == &(seq_buffer [sizeof (seq_buffer)-2]))
222 return 0;
223 *(seq_append++) = c;
224 *seq_append = 0;
225 return 1;
228 int get_key_code (int no_delay)
230 unsigned int inp_ch;
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;
241 if (no_delay) {
242 return (VKtoCurses(inp_ch));
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;
254 static int VKtoCurses (int a_vkc)
256 int ctrlState = 0;
257 int altState = 0;
259 int fsState;
260 char scanCode;
261 char asciiCode;
262 register int i;
263 int rtnCode = 0;
265 fsState = (a_vkc & 0xFFFF0000) >> 16;
266 fsState &= (~INSERT_MODE); /* Ignore Insertion mode */
268 scanCode = (char) ((a_vkc & 0x0000FFFF) >> 8);
269 asciiCode = (char) (a_vkc & 0x000000FF);
271 ctrlState = (fsState & CTRL_PRESSED);
272 altState = (fsState & ALT_PRESSED);
274 rtnCode = asciiCode;
276 if (ctrlState) {
277 /* CTRL pressed */
278 rtnCode = XCTRL(asciiCode);
281 if (altState) {
282 /* ALT pressed
283 * rtnCode = ALT(asciiCode);
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.
290 if (asciiCode) {
291 return asciiCode;
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);
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);
316 if (asciiCode == 0x0d) {
317 return '\n';
320 return rtnCode;
324 static int getch_with_delay (void)
326 int c;
328 while (1) {
329 /* Try to get a character */
330 c = get_key_code (0);
331 if (c != ERR)
332 break;
334 /* Success -> return the character */
335 return c;
338 int get_event (Gpm_Event *event, int redo_event, int block)
340 int c;
341 static int dirty = 3;
343 if ((dirty == 1) || is_idle ()){
344 refresh ();
345 doupdate ();
346 dirty = 1;
347 } else
348 dirty++;
350 vfs_timeout_handler ();
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 ? */
359 return c;
362 /* Returns a key press, mouse events are discarded */
363 int mi_getch ()
365 Gpm_Event ev;
366 int key;
368 while ((key = get_event (&ev, 0, 1)) == 0)
370 return key;
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)
379 int is_idle (void)
381 return 1;
384 /* get_modifier */
385 int get_modifier()
387 return 0;
390 int ctrl_pressed ()
392 return 0;
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) {}
404 /* mouse is not yet supported, sorry */
405 void init_mouse (void) {}
406 void shut_mouse (void) {}
408 #endif /* __os2__ */