16 #ifdef HAVE_SYS_SELECT_H
17 #include <sys/select.h>
20 #ifdef HAVE_LINUX_KD_H
21 #define HAVE_RAW_KEYBOARD
25 #ifdef HAVE_LINUX_VT_H
26 #define HAVE_VT_SWITCH
32 #define INCL_DOSERRORS
33 #define INCL_DOSMONITORS
36 #define HAVE_OS2_KEYBOARD
45 #define KBD_BUFFER_SIZE 256 /* size of buffer for incoming keys */
47 #ifdef HAVE_RAW_KEYBOARD
48 static int oldkbmode
; /* original keyboard mode */
52 /* RAW-MODE KEYBOARD */
53 /* keyboard bitmaps: current and previous */
54 static unsigned char keyboard
[128]; /* 0=not pressed, !0=pressed */
55 static unsigned char old_keyboard
[128]; /* 0=not pressed, !0=pressed */
57 /* NON-RAW KEYBOARD: */
61 #ifdef HAVE_OS2_KEYBOARD
63 #define OS2_ALIGN(var) (_THUNK_PTR_STRUCT_OK(&var##1) ? &var##1 : &var##2)
67 struct os2_key_packet
{
80 struct os2_key_packet packet
;
84 struct os2_key_packet
*os2_key
;
85 struct os2_buffer
*os2_in
;
86 struct os2_buffer
*os2_out
;
88 int os2_read_mon(unsigned char *data
, int len
)
90 static int prefix
= 0;
93 USHORT count
= sizeof(struct os2_key_packet
);
94 while (bytes_read
< len
) {
96 r
= DosMonRead((void *)os2_in
, IO_NOWAIT
, (void *)os2_key
, &count
);
97 if (r
== ERROR_MON_BUFFER_EMPTY
) break;
99 fprintf(stderr
, "DosMonRead: %d\n", r
);
103 /*fprintf(stderr, "monflag: %04x, scan %02x, shift %04x\n", os2_key->mon_flag, os2_key->scan, os2_key->shift_state);*/
104 scan
= os2_key
->mon_flag
>> 8;
105 /*fprintf(stderr, "scan: %02x\n", scan); fflush(stderr);*/
112 switch (scan
& 0x7f) {
113 case 29: scan
= scan
& 0x80 | 97; break;
114 case 71: scan
= scan
& 0x80 | 102; break;
115 case 72: scan
= scan
& 0x80 | 103; break;
116 case 73: scan
= scan
& 0x80 | 104; break;
117 case 75: scan
= scan
& 0x80 | 105; break;
118 case 77: scan
= scan
& 0x80 | 106; break;
119 case 79: scan
= scan
& 0x80 | 107; break;
120 case 80: scan
= scan
& 0x80 | 108; break;
121 case 81: scan
= scan
& 0x80 | 109; break;
122 case 82: scan
= scan
& 0x80 | 110; break;
123 case 83: scan
= scan
& 0x80 | 111; break;
125 /*fprintf(stderr, "scan: %02x\n", scan); fflush(stderr);*/
129 data
[bytes_read
++] = scan
;
136 /* reads byte from input */
146 /* test if there's something on input */
157 return !!(select(1,&fds
,NULL
,NULL
,&tv
));
161 void test_shift(int k
)
217 /* non-raw keyboard */
285 /* on error returns 1 */
288 #ifdef HAVE_RAW_KEYBOARD
290 keyboard_type
=KBD_RAW
;
293 if (ioctl(0,KDGKBMODE
,&oldkbmode
))goto std
;
294 if (ioctl(0,KDSKBMODE
,K_MEDIUMRAW
))goto std
;
296 /* GREAT EXPLANATION TO A SMALL FCNTL: */
297 /* ----------------------------------- */
299 /* this fcntl is a great cheat */
300 /* it switches STDOUT!!!!! to noblocking mode */
301 /* as i know 0 is STDIN so why it changes STDOUT settings?????? */
302 /* (does anyone know why???? (if you know send me a mail - you win million:-) (stupid joke...))) */
303 /* it causes scrambled picture on xterm and telnet */
304 /* because terminal doesn't manage and loses characters */
305 /* fortunatelly this fcntl is necessary only with raw keyboard */
306 /* and to switch keyboard to raw mode you must physically sit on the machine */
307 /* and when you sit on the machine, terminal is fast enough to manage ;-) */
308 fcntl(0,F_SETFL
,fcntl(0,F_GETFL
)|O_NONBLOCK
);
310 memset(keyboard
,0,128);
311 memset(old_keyboard
,0,128);
316 #ifdef HAVE_OS2_KEYBOARD
317 keyboard_type
=KBD_RAW
;
319 static struct os2_key_packet os2_key1
, os2_key2
;
320 static struct os2_buffer os2_in1
, os2_in2
, os2_out1
, os2_out2
;
322 if ((r
= DosMonOpen("KBD$", &os2_hmon
))) {
323 fprintf(stderr
, "DosMonOpen: %d\n", r
);
327 os2_key
= OS2_ALIGN(os2_key
);
328 os2_in
= OS2_ALIGN(os2_in
);
329 os2_out
= OS2_ALIGN(os2_out
);
330 os2_in
->cb
= sizeof(struct os2_buffer
) - sizeof(USHORT
);
331 os2_out
->cb
= sizeof(struct os2_buffer
) - sizeof(USHORT
);
332 if ((r
= DosMonReg(os2_hmon
, (void *)os2_in
, (void *)os2_out
, MONITOR_END
, -1))) {
333 if (r
= ERROR_MONITORS_NOT_SUPPORTED
) {
334 fprintf(stderr
, "RAW keyboard is disabled. Please run 0verkill in full-screen session.%c%c%c", (char)7, (char)7, (char)7);
337 fprintf(stderr
, "DosMonReg: %d\n", r
);
343 memset(keyboard
,0,128);
344 memset(old_keyboard
,0,128);
346 std1
: DosMonClose(os2_hmon
);
350 /* standard keyboard */
351 keyboard_type
=KBD_STD
;
352 /* nothing to initialize */
360 switch(keyboard_type
)
362 #ifdef HAVE_RAW_KEYBOARD
364 ioctl(0,KDSKBMODE
,oldkbmode
);
368 #ifdef HAVE_OS2_KEYBOARD
370 DosMonClose(os2_hmon
);
375 /* nothing to close */
381 /* convert key from scancode to key constant */
384 int remap_table
[128]={
385 0,K_ESCAPE
,'1','2','3','4','5','6','7','8','9','0','-','=',K_BACKSPACE
,K_TAB
,
386 'q','w','e','r','t','y','u','i','o','p','[',']',K_ENTER
,K_LEFT_CTRL
,'a','s',
387 'd','f','g','h','j','k','l',';','\'','`',K_LEFT_SHIFT
,'\\','z','x','c','v',
388 'b','n','m',',','.','/',K_RIGHT_SHIFT
,K_NUM_ASTERISK
,K_LEFT_ALT
,' ',K_CAPS_LOCK
,K_F1
,K_F2
,K_F3
,K_F4
,K_F5
,
389 K_F6
,K_F7
,K_F8
,K_F9
,K_F10
,K_NUM_LOCK
,K_SCROLL_LOCK
,K_NUM7
,K_NUM8
,K_NUM9
,K_NUM_MINUS
,K_NUM4
,K_NUM5
,K_NUM6
,K_NUM_PLUS
,K_NUM1
,
390 K_NUM2
,K_NUM3
,K_NUM0
,K_NUM_DOT
,0,0,0,K_F11
,K_F12
,0,0,0,0,0,0,0,
391 K_NUM_ENTER
,K_RIGHT_CTRL
,K_NUM_SLASH
,K_SYSRQ
,K_RIGHT_ALT
,0,K_HOME
,K_UP
,K_PGUP
,K_LEFT
,K_RIGHT
,K_END
,K_DOWN
,K_PGDOWN
,K_INSERT
,K_DELETE
,
392 0,0,0,0,0,0,0,K_PAUSE
,0,0,0,0,0,0,0,0
395 return remap_table
[k
];
399 /* convert key constant to scancode */
404 case K_ESCAPE
: return 1;
417 case K_BACKSPACE
: return 14;
418 case K_TAB
: return 15;
431 case K_ENTER
: return 28;
432 case K_LEFT_CTRL
: return 29;
443 case '\'': return 40;
445 case K_LEFT_SHIFT
: return 42;
446 case '\\': return 43;
457 case K_RIGHT_SHIFT
: return 54;
458 case K_NUM_ASTERISK
: return 55;
459 case K_LEFT_ALT
: return 56;
461 case K_CAPS_LOCK
: return 58;
462 case K_F1
: return 59;
463 case K_F2
: return 60;
464 case K_F3
: return 61;
465 case K_F4
: return 62;
466 case K_F5
: return 63;
467 case K_F6
: return 64;
468 case K_F7
: return 65;
469 case K_F8
: return 66;
470 case K_F9
: return 67;
471 case K_F10
: return 68;
472 case K_NUM_LOCK
: return 69;
473 case K_SCROLL_LOCK
: return 70;
474 case K_NUM7
: return 71;
475 case K_NUM8
: return 72;
476 case K_NUM9
: return 73;
477 case K_NUM_MINUS
: return 74;
478 case K_NUM4
: return 75;
479 case K_NUM5
: return 76;
480 case K_NUM6
: return 77;
481 case K_NUM_PLUS
: return 78;
482 case K_NUM1
: return 79;
483 case K_NUM2
: return 80;
484 case K_NUM3
: return 81;
485 case K_NUM0
: return 82;
486 case K_NUM_DOT
: return 83;
487 case K_F11
: return 87;
488 case K_F12
: return 88;
489 case K_NUM_ENTER
: return 96;
490 case K_RIGHT_CTRL
: return 97;
491 case K_NUM_SLASH
: return 98;
492 case K_SYSRQ
: return 99;
493 case K_RIGHT_ALT
: return 100;
494 case K_HOME
: return 102;
495 case K_UP
: return 103;
496 case K_PGUP
: return 104;
497 case K_LEFT
: return 105;
498 case K_RIGHT
: return 106;
499 case K_END
: return 107;
500 case K_DOWN
: return 108;
501 case K_PGDOWN
: return 109;
502 case K_INSERT
: return 110;
503 case K_DELETE
: return 111;
504 case K_PAUSE
: return 119;
511 /* returns zero if nothing was read, non-zero otherwise */
514 unsigned char buffer
[KBD_BUFFER_SIZE
];
517 switch(keyboard_type
)
520 memcpy(old_keyboard
,keyboard
,128);
521 #ifndef HAVE_OS2_KEYBOARD
522 bytesread
=read(0,buffer
,KBD_BUFFER_SIZE
);
524 bytesread
=os2_read_mon(buffer
, KBD_BUFFER_SIZE
);
526 if (bytesread
<=0)return 0;
528 for (a
=0;a
<bytesread
;a
++)
529 keyboard
[(buffer
[a
])&127]=!((buffer
[a
])&128);
530 if (bytesread
==KBD_BUFFER_SIZE
)
532 #ifndef HAVE_OS2_KEYBOARD
533 bytesread
=read(0,buffer
,KBD_BUFFER_SIZE
);
535 bytesread
=os2_read_mon(buffer
, KBD_BUFFER_SIZE
);
537 if (bytesread
<=0)return 1;
542 if ((keyboard
[29]||keyboard
[97])&&keyboard
[46])
545 #ifdef HAVE_VT_SWITCH
546 /* console switching */
547 if (keyboard
[56]||keyboard
[100]) /* alt */
549 for(a
=59;a
<=68;a
++) /* function keys */
552 memset(keyboard
,0,128); /* terminal is inactive=>keys can't be pressed */
553 memset(old_keyboard
,0,128); /* terminal is inactive=>keys can't be pressed */
554 ioctl(0,VT_ACTIVATE
,a
-58); /* VT switch */
559 memset(keyboard
,0,128); /* terminal is inactive=>keys can't be pressed */
560 memset(old_keyboard
,0,128); /* terminal is inactive=>keys can't be pressed */
561 ioctl(0,VT_ACTIVATE
,11); /* VT switch */
563 else if (keyboard
[88])
565 memset(keyboard
,0,128); /* terminal is inactive=>keys can't be pressed */
566 memset(old_keyboard
,0,128); /* terminal is inactive=>keys can't be pressed */
567 ioctl(0,VT_ACTIVATE
,12); /* VT switch */
575 if (!kbhit())return 0;
576 current_key
=getkey();
583 /* returns 1 if given key is pressed, 0 otherwise */
584 int kbd_is_pressed(int key
)
586 switch(keyboard_type
)
589 return keyboard
[remap_in(key
)];
592 if (key
==K_LEFT_SHIFT
||key
==K_RIGHT_SHIFT
)return shift_pressed
;
593 return (current_key
==key
);
599 /* same as kbd_is_pressed but tests rising edge of the key */
600 int kbd_was_pressed(int key
)
602 switch(keyboard_type
)
605 return !old_keyboard
[remap_in(key
)]&&keyboard
[remap_in(key
)];
608 return kbd_is_pressed(key
);
614 void kbd_wait_for_key(void)
619 if (keyboard_type
== KBD_RAW
) return;
623 select(1,&fds
,NULL
,NULL
,0);