home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
READKY41.ZIP
/
READKEY.C
next >
Wrap
C/C++ Source or Header
|
1991-08-14
|
11KB
|
350 lines
/* readkey.c
* Read a keystroke directly from the keyboard,
* and return the scan code generated
*/
/* Modification On: Tue 06-07-1988 13:18:10
* -re-compiled to use the June 1, 1988 release of the Windows BOSS
*/
/* Modification On: Tue 04-24-1990 13:18:10
* -added support for enhanced keyboards
* -used QuickC 2.xx inline assembly to read keyboard
*/
/* Modification On: Wed 05-03-1990 19:06:00
* -recompiled using MSC 6.0
*/
/* Modification On: Tues 08-13-1991 18:00:00
* -added command line switch to ignore enhanced keyboards
*/
#include <stdio.h>
#include <dos.h>
#include <bios.h>
#include <windows.h>
#include <string.h>
#define ESCAPE 27 /* to detect program exit */
#define CENTERED 0
#define LEFT -1
#define RIGHT 1
/* prototyping statements */
void main(int argc, char **argv);
void UpdateScreen(WINDOWPTR, int, int);
void wn_message(WINDOWPTR,int,char *);
void main(int argc,char **argv)
{
unsigned int a = 0, /* input from user */
b = 0;
int ReadKeyboard = _KEYBRD_READ;
int KeyboardReady = _KEYBRD_READY;
int KeyboardStatus = _KEYBRD_SHIFTSTATUS;
int batrib, /* border attribute */
watrib, /* window attribute */
tatrib, /* text attribute */
ratrib; /* reverse fields */
int IgnoreEnhancedKeyboard = FALSE; /* flag, enhanced keyboard detected
* and we want to see it as such
*/
WINDOWPTR w1 = NULL, /* information display */
w2 = NULL; /* if enhanced keyboard is detected */
unsigned char row, /* used to preserve the starting */
col, /* cursor location */
VideoPage; /* current video page in use */
/* use a char array for formatting in printf statements */
static char format[] = {"%03d Decimal or 0x%02X Hex"};
/* check if a monochrome screen, adjust colours if needed */
if (((_bios_equiplist() >> 4) & 3) == 3) /* colours for monochrome system */
{
batrib = v_setatr(WHITE,BLACK,0,0); /* border attribute */
watrib = v_setatr(BLACK,WHITE,0,BOLD); /* window attribute */
tatrib = v_setatr(BLACK,WHITE,0,BOLD); /* text attribute */
ratrib = v_setatr(WHITE,BLACK,0,BOLD); /* reverse fields */
}
else /* colours for colours system */
{
batrib = v_setatr(RED,YELLOW,0,BOLD); /* border attribute */
watrib = v_setatr(BLUE,WHITE,0,BOLD); /* window attribute */
tatrib = v_setatr(BLUE,GREEN,0,BOLD); /* text attribute */
ratrib = v_setatr(BLACK,RED,0,BOLD); /* reverse fields */
}
/* If bit 4 of the byte at 0x0040:0x0096 is set, an enhanced keyboard
* is present.
*/
_asm
{
push es ; we change es, so save it
mov ax,40h
mov es,ax
mov ax,96h
mov si,ax
mov ax,es:[si]
and ax,10h
jz EndGetKeyboardType
mov ax,_NKEYBRD_READ ; set values to read the
mov ReadKeyboard,ax ; extended keyboard
mov ax,_NKEYBRD_READY
mov KeyboardReady,ax
mov ax,_NKEYBRD_SHIFTSTATUS
mov KeyboardStatus,ax
EndGetKeyboardType:
;
; now read and store the current cursor row and column
; for later use
;
; first, we should read the current video page
;
mov ah,0fh
int 10h
mov VideoPage,bh
;
; now read and store the row and column
; this really helps when faced with a non-25x80 display
;
mov ah,03h
mov bh,VideoPage
int 10h
mov row,dh
mov col,dl
pop es ; retrieve original value in es
}
/* check and see if enhanced keyboard read is defeated through a
* command line over-ride
*/
if(argc > 1) /* is there a command line argument? */
{
if((argc > 2) || (argv[1][0] == '?')) /* only one allowed/ a ? entered */
{
puts("Useage: readkey [?] [-n | -N]\n");
exit(-1);
}
else
{
if((strstr(argv[1],"-n") != NULL) || (strstr(argv[1],"-N") != NULL))
{
IgnoreEnhancedKeyboard = TRUE;
}
}
}
/* if an enhanced keyboard is detected, tell the user */
if(ReadKeyboard == _NKEYBRD_READ)
{
if(IgnoreEnhancedKeyboard)
{
w2 = wn_open(0,16,24,29,5,watrib,batrib);
wn_puts(w2,1,1,"Enhanced Keyboard Detected!");
wn_puts(w2,3,1," Keyboard Override Active.");
ReadKeyboard = _KEYBRD_READ;
KeyboardReady = _KEYBRD_READY;
KeyboardStatus = _KEYBRD_SHIFTSTATUS;
}
else
{
w2 = wn_open(0,16,24,29,3,watrib,batrib);
wn_puts(w2,1,1,"Enhanced Keyboard Detected!");
}
}
/* open a window and display basic screen */
w1 = wn_open(0,2,13,52,10,watrib,batrib);
/* title for window */
wn_title(w1,"╡ Display Keyboard Scan Codes 4.10 ╞");
/* message on bottom border of screen */
wn_message(w1,CENTERED,"╡ Press Any Key to Display Codes, or Esc to Exit ╞");
/* screen titles */
wn_puts(w1,1,1,"Character :");
wn_puts(w1,3,1,"Scan Code :");
wn_puts(w1,5,1,"ASCII Code:");
wn_puts(w1,7,1,"[LEFT SHIFT] [CONTROL] [ALT] [RIGHT SHIFT]");
wn_puts(w1,8,1,"[CAPS LOCK] [NUM LOCK] [SCROLL LOCK] [INSERT MODE]");
/* main program loop */
while((a & 0xff) != ESCAPE) /* loop until user hits escape */
{
/* loop while no keys pressed and update flages at screen bottom */
while(!_bios_keybrd(KeyboardReady))
UpdateScreen(w1,ratrib,KeyboardStatus);
UpdateScreen(w1,ratrib,KeyboardStatus);
/* clear data from the screen */
wn_puts(w1,1,13," ");
wn_puts(w1,3,13," ");
wn_puts(w1,6,13," ");
a = _bios_keybrd(ReadKeyboard); /* get key pressed */
b = a >> 8; /* use only upper 8 bits */
a &= 0xff; /* use only lower 8 bits */
wn_color(w1,tatrib,batrib); /* set colours for data display */
if(!a) /* special key pressed */
wn_puts(w1,1,13,"Special Key Pressed!");
else
{
switch(a) /* cover non-printing characers */
{
case 7: /* ^G */
wn_puts(w1,1,13,"[Bell]");
putchar(7);
break;
case 8:
wn_puts(w1,1,13,"[Backspace]");
break;
case 9: /* tab key or control-i */
wn_puts(w1,1,13,"[Tab]");
break;
case 10: /* control-return key */
wn_puts(w1,1,13,"[Code 10]");
break;
case 13: /* return key */
wn_puts(w1,1,13,"[Return]");
break;
case 32: /* space bar */
wn_puts(w1,1,13,"[Space]");
break;
case 127:
wn_puts(w1,1,13,"[Control-Backspace]");
break;
case 255: /* entered with alt-numeric keys ? */
wn_puts(w1,1,13,"[Code 255]");
break;
default:
wn_locate(w1,1,13);
wn_printf(w1,"%c",a);
break;
}
}
/* actually display the scan and character codes for key pressed */
wn_locate(w1,3,13);
wn_printf(w1,format,b,b);
wn_locate(w1,5,13);
wn_printf(w1,format,a,a);
wn_color(w1,watrib,batrib); /* set colours back to normal */
} /* end of while */
if(w1)
wn_close(w1);
if(w2)
wn_close(w2);
/* now use row and col to put cursor back where we started from */
_asm
{
mov ah,02h
mov bh,VideoPage
mov dh,row
mov dl,col
int 10h
}
puts("\nThe escape key usually produces a scan code of 1,\nand a character code of 27.");
} /* end of main() */
/* update the display of flags at the bottom of the window */
void UpdateScreen(WINDOWPTR window,int attribute,int KeyboardShift)
{
/* get keyboard status byte */
unsigned int ch = _bios_keybrd(KeyboardShift);
/* check for right shift key pressed */
if(ch & 1)
wn_putsa(window,7,38,"[RIGHT SHIFT]",attribute);
else
wn_puts(window,7,38,"[RIGHT SHIFT]");
/* check for left shift key pressed */
if(ch & 2)
wn_putsa(window,7,1,"[LEFT SHIFT]",attribute);
else
wn_puts(window,7,1,"[LEFT SHIFT]");
/* check for control key pressed */
if(ch & 4)
wn_putsa(window,7,17,"[CONTROL]",attribute);
else
wn_puts(window,7,17,"[CONTROL]");
/* check for alt key pressed */
if(ch & 8)
wn_putsa(window,7,29,"[ALT]",attribute);
else
wn_puts(window,7,29,"[ALT]");
/* check for scroll lock key on */
if(ch & 16)
wn_putsa(window,8,24,"[SCROLL LOCK]",attribute);
else
wn_puts(window,8,24,"[SCROLL LOCK]");
/* check for num lock on */
if(ch & 32)
wn_putsa(window,8,13,"[NUM LOCK]",attribute);
else
wn_puts(window,8,13,"[NUM LOCK]");
/* check for caps lock on */
if(ch & 64)
wn_putsa(window,8,1,"[CAPS LOCK]",attribute);
else
wn_puts(window,8,1,"[CAPS LOCK]");
/* check for insert mode */
if(ch & 128)
wn_putsa(window,8,38,"[INSERT MODE]",attribute);
else
wn_puts(window,8,38,"[INSERT MODE]");
}
void wn_message(WINDOWPTR w,int place,char *string)
{
char *p, *p1, *p2;
int len = strlen(string),
len2 = len;
int row = w->uly + w->ysize + w->bsize / 2;
int col = w->ulx + (w->bsize / 2);
switch(place)
{
case CENTERED:
col += ((w->xsize - len) / 2);
break;
case LEFT:
col ++;
break;
case RIGHT:
col += (w->xsize - len - 1);
break;
}
p = malloc((len*2)+1); /* fetch some memory */
p1 = p;
p2 = string;
while (len--)
{ /* build char,,atrib */
*p1++ = *p2++; /* pair */
*p1++ = (char)w->bstyle; /* for write */
}
*p1 = '\0';
wns_savres(w->page,row,col,len2,row,p,RESTORE);
free(p);
}