delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/01/14/03:23:34

From: "Anthony.Appleyard" <MCLSSAA2 AT fs2 DOT mt DOT umist DOT ac DOT uk>
Organization: Materials Science Centre
To: djgpp-workers AT delorie DOT com
Date: Wed, 14 Jan 1998 08:20:31 GMT
Subject: MCLSSAA2 AT fs2 DOT mt DOT umist DOT ac DOT uk: Hooking interrupt 9
Reply-to: Anthony DOT Appleyard AT umist DOT ac DOT uk
Message-ID: <27011525706@fs2.mt.umist.ac.uk>

> >   extern int (*_djgpp_kbd_callback)(int X);  /* initial value == 0 */
> > ///// This line should be inserted in some suitable #insert<***.h> file.
> 
> No, decide which file it goes in and supply a patch to put it there. ...
  ==================================================================
  Herewith a DIFF for insert\sys\exceptn.h :-
  ------------------------------------------------------------------
*** exceptn.h	Mon Dec  4 22:39:44 1995
--- exceptn2.h	Tue Jan 13 14:35:24 1998
***************
*** 27,32 ****
--- 27,33 ----
  #define __djgpp_exception_state (*__djgpp_exception_state_ptr)
  #endif
  
+ extern int (*_djgpp_kbd_callback)(int X);
  extern unsigned short __djgpp_our_DS;
  extern unsigned short __djgpp_app_DS;	/* Data selector invalidated by HW ints */
  extern unsigned short __djgpp_ds_alias;	/* Data selector always valid */
***************
*** 38,43 ****
--- 39,150 ----
  void __djgpp_exception_toggle(void);
  int  __djgpp_set_ctrl_c(int enable);	/* On by default */
  
+ enum{        /* numbers of the keys */
+   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,   /* + 0x100 = as second half of an 0xe0 pair */
+   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};
+ 
  #endif /* !_POSIX_SOURCE */
  #endif /* !__STRICT_ANSI__ */
  #endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
  ==================================================================
  Herewith a DIFF for src\libc\go32\exceptn.s :-
  ------------------------------------------------------------------
*** exceptn.s	Mon Jan 12 14:54:06 1998
--- exceptn2.s	Tue Jan 13 15:07:40 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 no_user_hdlr
+ 	pushw %fs
+ 	pushf
+ 	cli				/* 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 */
+ no_user_hdlr:
+ 	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	dont_call_fn
+ 	popl	%eax
+ 	iret
+ dont_call_fn:
  	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	dont_call
+ 	popl	%eax
+ 	iret
+ dont_call:
  	pushl	%ds
     	.byte	0x2e				/* CS: */
  	testb	$1, ___djgpp_hwint_flags	/* Disable? */
  ==================================================================
  Herewith a .TXH file for it, say call it djgppkbh.txh :-
  ------------------------------------------------------------------
@node _djgpp_kbd_callback, stdio
@subheading Syntax

@example
#include <sys/exceptn.h>
extern int (*_djgpp_kbd_callback)(int X);
@end example

@subheading Description

If _djgpp_kbd_callback is not zero, it is a pointer to a user-definable
function which is automatically called whenever a keyboard event occurs such
as a key being pressed or released. They would let the program see the raw
keyboard events. 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(X) 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 instead of DOS handling it.

  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
  The 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 listed in the insert file SYS/EXCEPTN.H; the code for releasing that
key is 0x80 = 128 higher.

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.

`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.

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. In the sequence, the `e1 1d' seems to be
the functioning part 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.

@subheading Return Value

This should be 0 if you want the keyboard event to be processed as usual after
you have processed it, otherwise 1.

@subheading Example

@example
char print_wanted = 0;
  ......
int trap_prscr(int X){
  if((X&0xff) == 0x2a)                    /* if it is left shift or Prt Scr */
    if(!((X>>8)&15))                      /* not if shift or ctrl or alt */
       if(_farpeekb(_dos_ds,0x496)&2)     /* if it is next after 0xe0 event */
          {                               /* then it is a Prt Scr */
            print_wanted = 1; /* leave note to call my own printout routine */
            return 1;         /* no, I DON'T want DOS's method right now */
          }
  return 0;                   /* else default */
}
  ......
int main(){
  ......
_djgpp_kbd_callback = trap_prscr;
  ......
@end example

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019