Mail Archives: djgpp-workers/1998/01/13/05:47:21
Thanks to Eli Zaretski for his comments. Herewith an amended version with
more help:-
------------------------------------------------------------------
extern int (*_djgpp_kbd_callback)(int X); /* initial value == 0 */
///// This line should be inserted in some suitable #insert<***.h> file.
If _djgpp_kbd_callback is nonzero, the function that it points to is
automatically called whenever a keyboard event occurs such as a key being
pressed or released. When it is called:-
X &255 == the keyboard event code
(X>> 8)&255 == keyboard shift status as if from (AH=2, int 16h)
(X>>16)&255 == keyboard extended shift status as if from (AH=12h, int 16h)
If _djgpp_kbd_callback() returns nonzero, that keyboard event is not passed
on to DOS. This would let the user e.g. recognise and intercept `Prt Scr' and
use it for some purpose of his own.
bits of shift status bits of extended shift status
7 Insert active 7 SysReq key pressed
6 CapsLock active 6 CapsLock pressed
5 NumLock active 5 NumLock pressed
4 ScrollLock active 4 ScrollLock pressed
3 Alt key pressed 3 right Alt key pressed
2 Ctrl key pressed 2 right Ctrl key pressed
1 left shift key pressed 1 left Alt key pressed
0 right shift key pressed 0 left Ctrl key pressed
These current values of these two bytes are kept in conventional memory at
addresses 0x417 and 0x418 respectively.
The keyboard keys are numbered between 0 and 127. The code for pressing a
key is as here; the code for releasing that key is 0x80 = 128 higher.
`Numshift' is an imaginary key whose press and release codes are sometimes
manufactured by something in BIOS around some of the `grey key' events. If
`numshift' is treated as an extra shift key, the effect is that those `grey
keys' are shifted by the current Numlock state and not by the two real shift
keys. Don't blame me, blame whoever invented the PC BIOS.
Some of the keys when pressed or released produce two keyboard events, of
which the first is 0xe0, and the second is the key's code (plus 128 on
release). I represent this feature here by adding 0x100 = 256 to the code.
On my PC pressing Pause/Break key produces the sequence `e1 1d 45', and
releasing it produces `e1 9d c5': i.e. `e1' followed by the codes for `left
ctrl' and `numlock' in that order. The `e1 1d' seems to be the functioning
part of the sequence that causes the pausing or the break.
On my PC pressing `Prt Scr'/`Sys Req' key produces `e0 2a' followed by three
`press padstar' sequences; releasing `Prt Scr'/`Sys Req' produces a `release
padstar' sequence followed by `e0 aa'.
Due to wide differences between national keyboard layouts, I have named the
non-alphanumeric printing keys neutrally, e.g. `k_2rof0' means "the key two to
the right of 0" (`=' `+' on UK and USA keyboards). This refers to the layout
on a desktop keyboard. Laptop keys tend to be somewhat differently arranged.
enum{k_esc=1, k_1, k_2, k_3, k_4, k_5, k_6, k_7, k_8, k_9, k_0, k_1rof0,
k_2rof0, k_backspace, k_tab, k_Q, k_W, k_E, k_R, k_T, k_Y, k_U, k_I, k_O, k_P,
k_1rofP, k_2rofP, k_enter, k_lctrl, k_A, k_S, k_D, k_F, k_G, k_H, k_J, k_K,
k_L, k_1rofL, k_2rofL, k_1lof1, k_lshift, k_3rofL, k_Z, k_X, k_C, k_V, k_B,
k_N, k_M, k_1rofM, k_2rofM, k_3rofM, k_rshift, k_padstar, k_lalt, k_space,
k_capslock, k_F1, k_F2, k_F3, k_F4, k_F5, k_F6, k_F7, k_F8, k_F9, k_F10,
k_numlock, k_scrolllock, k_pad7, k_pad8, k_pad9, k_padminus, k_pad4, k_pad5,
k_pad6, k_padplus, k_pad1, k_pad2, k_pad3, k_pad0, k_paddot, k_1lofZ=0x56,
k_F11, k_F12,
k_padenter=0x11c, k_rctrl=0x11d, k_numshift=0x12a, k_padslash=0x135,
k_ralt=0x138, k_home=0x147, k_uparrow=0x148, k_pageup=0x149,
k_leftarrow=0x14b, k_rightarrow=0x14d, k_end=0x14f, k_downarrow=0x150,
k_pagedown=0x151, k_insert=0x152, k_delete=0x153, k_lwin=0x15b, k_rwin=0x15c,
k_menu=0x15d};
==================================================================
Suggested alterations to D:\DJGPPV2\SRC\LIBC\GO32\EXCEPTN.S :-
==================================================================
*** _ex.old Mon Jan 12 14:54:06 1998
--- _ex.s Tue Jan 13 10:33:46 1998
***************
*** 284,292 ****
--- 284,327 ----
iret
.align 4
+ .global __djgpp_kbd_callback
+ __djgpp_kbd_callback: .int 0 /* int (*_djgpp_kbd_callback)(int X); */
+ /* If not 0, the interrupt 9 hook routine will call this function with:- */
+ /* X &255 == keyboard event */
+ /* (X>> 8)&255 == keyboard shift status as if from (AH=2, int 16h) */
+ /* (X>>16)&255 == keyboard extended shift status as if from (AH=12h, int 16h) */
+ _calldjgpp_kbd_callback:
+ xorl %eax,%eax /* must return 0 if no function */
+ pushl %ebx /* save EBX */
+ movl __djgpp_kbd_callback,%ebx
+ testl %ebx,%ebx /* if zero, there is no function */
+ je NOUSERHDLR
+ pushw %fs
+ pushf
+ sti /* disable interrupts */
+ movw __go32_info_block+26,%ax
+ movw %ax,%fs /* FS = _dos_ds */
+ .byte 0x64 /* use segment reg FS */
+ movw 0417,%ax /* [0x417] [0x418] are shift status */
+ sall $8,%eax /* move EAX one byte up */
+ inb $0x60,%al /* read keyboard event into AL */
+ pushl %eax /* parameter for call */
+ call *%ebx /* call the function */
+ popf
+ popw %fs /* don't restore EAX, it's the result */
+ NOUSERHDLR:
+ popl %ebx
+ ret
+
.global ___djgpp_kbd_hdlr
___djgpp_kbd_hdlr:
pushl %eax
+ call _calldjgpp_kbd_callback /* If djgpp_kbd_callback returns */
+ testl %eax,%eax /* nonzero, no default handling of the event */
+ JE CARRYON
+ popl %eax
+ iret
+ CARRYON:
pushl %ds
.byte 0x2e /* CS: */
testb $1, ___djgpp_hwint_flags /* Disable? */
***************
*** 317,322 ****
--- 352,363 ----
.global ___djgpp_kbd_hdlr_pc98
___djgpp_kbd_hdlr_pc98:
pushl %eax
+ call _calldjgpp_kbd_callback /* If djgpp_kbd_callback returns */
+ testl %eax,%eax /* nonzero, no default handling of the event */
+ JE CARRYON2
+ popl %eax
+ iret
+ CARRYON2:
pushl %ds
.byte 0x2e /* CS: */
testb $1, ___djgpp_hwint_flags /* Disable? */
- Raw text -