home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / READKY41.ZIP / READKEY.C next >
C/C++ Source or Header  |  1991-08-14  |  11KB  |  350 lines

  1. /* readkey.c
  2.  * Read a keystroke directly from the keyboard,
  3.  * and return the scan code generated
  4.  */
  5.  
  6. /* Modification On: Tue  06-07-1988   13:18:10
  7.  * -re-compiled to use the June 1, 1988 release of the Windows BOSS
  8.  */
  9.  
  10. /* Modification On: Tue  04-24-1990   13:18:10
  11.  * -added support for enhanced keyboards
  12.  * -used QuickC 2.xx inline assembly to read keyboard
  13.  */
  14.  
  15. /* Modification On: Wed  05-03-1990   19:06:00
  16.  * -recompiled using MSC 6.0
  17.  */
  18.  
  19. /* Modification On: Tues 08-13-1991   18:00:00
  20.  * -added command line switch to ignore enhanced keyboards
  21.  */
  22.  
  23.  
  24. #include <stdio.h>
  25. #include <dos.h>
  26. #include <bios.h>
  27. #include <windows.h>
  28. #include <string.h>
  29.  
  30. #define ESCAPE  27                           /* to detect program exit */
  31. #define CENTERED 0
  32. #define LEFT    -1
  33. #define RIGHT    1
  34.  
  35. /* prototyping statements */
  36.  
  37. void main(int argc, char **argv);
  38. void UpdateScreen(WINDOWPTR, int, int);
  39. void wn_message(WINDOWPTR,int,char *);
  40.  
  41. void main(int argc,char **argv)
  42. {
  43.     unsigned int a = 0,          /* input from user */
  44.                  b = 0;
  45.     int ReadKeyboard   = _KEYBRD_READ;
  46.     int KeyboardReady  = _KEYBRD_READY;
  47.     int KeyboardStatus = _KEYBRD_SHIFTSTATUS;
  48.     int batrib,     /* border attribute */
  49.         watrib,     /* window attribute */
  50.         tatrib,     /* text attribute */
  51.         ratrib;     /* reverse fields */
  52.     int IgnoreEnhancedKeyboard = FALSE;   /* flag, enhanced keyboard detected
  53.                                            * and we want to see it as such
  54.                                            */
  55.  
  56.     WINDOWPTR w1 = NULL,            /* information display */
  57.               w2 = NULL;            /* if enhanced keyboard is detected */
  58.  
  59.     unsigned char row,              /* used to preserve the starting */
  60.                   col,              /* cursor location */
  61.                   VideoPage;        /* current video page in use */
  62.  
  63.     /* use a char array for formatting in printf statements */
  64.     static char format[] = {"%03d Decimal or 0x%02X Hex"};
  65.  
  66.     /* check if a monochrome screen, adjust colours if needed */
  67.     if (((_bios_equiplist() >> 4) & 3) == 3)  /* colours for monochrome system */
  68.     {
  69.         batrib = v_setatr(WHITE,BLACK,0,0);         /* border attribute */
  70.         watrib = v_setatr(BLACK,WHITE,0,BOLD);      /* window attribute */
  71.         tatrib = v_setatr(BLACK,WHITE,0,BOLD);      /* text attribute */
  72.         ratrib = v_setatr(WHITE,BLACK,0,BOLD);      /* reverse fields */
  73.     }
  74.     else                                    /* colours for colours system */
  75.     {
  76.         batrib = v_setatr(RED,YELLOW,0,BOLD);       /* border attribute */
  77.         watrib = v_setatr(BLUE,WHITE,0,BOLD);       /* window attribute */
  78.         tatrib = v_setatr(BLUE,GREEN,0,BOLD);       /* text attribute */
  79.         ratrib = v_setatr(BLACK,RED,0,BOLD);        /* reverse fields */
  80.     }
  81.  
  82.     /* If bit 4 of the byte at 0x0040:0x0096 is set, an enhanced keyboard
  83.      * is present.
  84.      */
  85.     _asm
  86.     {
  87.         push es                         ; we change es, so save it
  88.         mov  ax,40h
  89.         mov  es,ax
  90.         mov  ax,96h
  91.         mov  si,ax
  92.         mov  ax,es:[si]
  93.         and  ax,10h
  94.         jz   EndGetKeyboardType
  95.         mov  ax,_NKEYBRD_READ           ; set values to read the
  96.         mov  ReadKeyboard,ax            ; extended keyboard
  97.         mov  ax,_NKEYBRD_READY
  98.         mov  KeyboardReady,ax
  99.         mov  ax,_NKEYBRD_SHIFTSTATUS
  100.         mov  KeyboardStatus,ax
  101.       EndGetKeyboardType:
  102.         ;
  103.         ; now read and store the current cursor row and column
  104.         ; for later use
  105.         ;
  106.         ; first, we should read the current video page
  107.         ;
  108.         mov  ah,0fh
  109.         int  10h
  110.         mov  VideoPage,bh
  111.         ;
  112.         ; now read and store the row and column
  113.         ; this really helps when faced with a non-25x80 display
  114.         ;
  115.         mov  ah,03h
  116.         mov  bh,VideoPage
  117.         int  10h
  118.         mov  row,dh
  119.         mov  col,dl
  120.         pop  es                         ; retrieve original value in es
  121.     }
  122.  
  123.     /* check and see if enhanced keyboard read is defeated through a
  124.      * command line over-ride
  125.      */
  126.  
  127.     if(argc > 1)        /* is there a command line argument? */
  128.     {
  129.         if((argc > 2) || (argv[1][0] == '?'))    /* only one allowed/ a ? entered  */
  130.         {
  131.             puts("Useage: readkey [?] [-n | -N]\n");
  132.             exit(-1);
  133.         }
  134.         else
  135.         {
  136.             if((strstr(argv[1],"-n") != NULL) || (strstr(argv[1],"-N") != NULL))
  137.             {
  138.                 IgnoreEnhancedKeyboard = TRUE;
  139.             }
  140.         }
  141.     }
  142.  
  143.     /* if an enhanced keyboard is detected, tell the user */
  144.     if(ReadKeyboard == _NKEYBRD_READ)
  145.     {
  146.         if(IgnoreEnhancedKeyboard)
  147.         {
  148.             w2 = wn_open(0,16,24,29,5,watrib,batrib);
  149.             wn_puts(w2,1,1,"Enhanced Keyboard Detected!");
  150.             wn_puts(w2,3,1," Keyboard Override Active.");
  151.             ReadKeyboard   = _KEYBRD_READ;
  152.             KeyboardReady  = _KEYBRD_READY;
  153.             KeyboardStatus = _KEYBRD_SHIFTSTATUS;
  154.         }
  155.         else
  156.         {
  157.             w2 = wn_open(0,16,24,29,3,watrib,batrib);
  158.             wn_puts(w2,1,1,"Enhanced Keyboard Detected!");
  159.         }
  160.     }
  161.  
  162.     /* open a window and display basic screen */
  163.     w1 = wn_open(0,2,13,52,10,watrib,batrib);
  164.  
  165.     /* title for window */
  166.     wn_title(w1,"╡ Display Keyboard Scan Codes 4.10 ╞");
  167.  
  168.     /* message on bottom border of screen */
  169.     wn_message(w1,CENTERED,"╡ Press Any Key to Display Codes, or Esc to Exit ╞");
  170.  
  171.     /* screen titles */
  172.     wn_puts(w1,1,1,"Character :");
  173.     wn_puts(w1,3,1,"Scan Code :");
  174.     wn_puts(w1,5,1,"ASCII Code:");
  175.     wn_puts(w1,7,1,"[LEFT SHIFT]    [CONTROL]   [ALT]    [RIGHT SHIFT]");
  176.     wn_puts(w1,8,1,"[CAPS LOCK] [NUM LOCK] [SCROLL LOCK] [INSERT MODE]");
  177.  
  178.     /* main program loop */
  179.     while((a & 0xff) != ESCAPE)             /* loop until user hits escape */
  180.     {
  181.         /* loop while no keys pressed and update flages at screen bottom */
  182.         while(!_bios_keybrd(KeyboardReady))
  183.             UpdateScreen(w1,ratrib,KeyboardStatus);
  184.  
  185.         UpdateScreen(w1,ratrib,KeyboardStatus);
  186.  
  187.         /* clear data from the screen */
  188.         wn_puts(w1,1,13,"                                    ");
  189.         wn_puts(w1,3,13,"                                    ");
  190.         wn_puts(w1,6,13,"                                    ");
  191.  
  192.         a = _bios_keybrd(ReadKeyboard);     /* get key pressed               */
  193.         b = a >> 8;                         /* use only upper 8 bits         */
  194.         a &= 0xff;                          /* use only lower 8 bits         */
  195.         wn_color(w1,tatrib,batrib);         /* set colours for data display  */
  196.  
  197.         if(!a)                              /* special key pressed           */
  198.             wn_puts(w1,1,13,"Special Key Pressed!");
  199.         else
  200.         {
  201.             switch(a)           /* cover non-printing characers    */
  202.             {
  203.                 case 7:         /* ^G  */
  204.                     wn_puts(w1,1,13,"[Bell]");
  205.                     putchar(7);
  206.                     break;
  207.                 case 8:
  208.                     wn_puts(w1,1,13,"[Backspace]");
  209.                     break;
  210.                 case 9:         /* tab key or control-i */
  211.                     wn_puts(w1,1,13,"[Tab]");
  212.                     break;
  213.                 case 10:        /* control-return key */
  214.                     wn_puts(w1,1,13,"[Code 10]");
  215.                     break;
  216.                 case 13:        /* return key */
  217.                     wn_puts(w1,1,13,"[Return]");
  218.                     break;
  219.                 case 32:        /* space bar */
  220.                     wn_puts(w1,1,13,"[Space]");
  221.                     break;
  222.                 case 127:
  223.                     wn_puts(w1,1,13,"[Control-Backspace]");
  224.                     break;
  225.                 case 255:       /* entered with alt-numeric keys ? */
  226.                     wn_puts(w1,1,13,"[Code 255]");
  227.                     break;
  228.                 default:
  229.                     wn_locate(w1,1,13);
  230.                     wn_printf(w1,"%c",a);
  231.                     break;
  232.             }
  233.         }
  234.         /* actually display the scan and character codes for key pressed */
  235.         wn_locate(w1,3,13);
  236.         wn_printf(w1,format,b,b);
  237.         wn_locate(w1,5,13);
  238.         wn_printf(w1,format,a,a);
  239.         wn_color(w1,watrib,batrib);         /* set colours back to normal */
  240.     }       /* end of while */
  241.  
  242.     if(w1)
  243.         wn_close(w1);
  244.  
  245.     if(w2)
  246.         wn_close(w2);
  247.  
  248.     /* now use row and col to put cursor back where we started from */
  249.     _asm
  250.     {
  251.         mov  ah,02h
  252.         mov  bh,VideoPage
  253.         mov  dh,row
  254.         mov  dl,col
  255.         int  10h
  256.     }
  257.  
  258.     puts("\nThe escape key usually produces a scan code of 1,\nand a character code of 27.");
  259. }   /* end of main() */
  260.  
  261. /* update the display of flags at the bottom of the window */
  262.  
  263. void UpdateScreen(WINDOWPTR window,int attribute,int KeyboardShift)
  264. {
  265.     /* get keyboard status byte */
  266.  
  267.     unsigned int ch = _bios_keybrd(KeyboardShift);
  268.  
  269.     /* check for right shift key pressed */
  270.     if(ch & 1)
  271.         wn_putsa(window,7,38,"[RIGHT SHIFT]",attribute);
  272.     else
  273.         wn_puts(window,7,38,"[RIGHT SHIFT]");
  274.  
  275.     /* check for left shift key pressed */
  276.     if(ch & 2)
  277.         wn_putsa(window,7,1,"[LEFT SHIFT]",attribute);
  278.     else
  279.         wn_puts(window,7,1,"[LEFT SHIFT]");
  280.  
  281.     /* check for control key pressed */
  282.     if(ch & 4)
  283.         wn_putsa(window,7,17,"[CONTROL]",attribute);
  284.     else
  285.         wn_puts(window,7,17,"[CONTROL]");
  286.  
  287.     /* check for alt key pressed */
  288.     if(ch & 8)
  289.         wn_putsa(window,7,29,"[ALT]",attribute);
  290.     else
  291.         wn_puts(window,7,29,"[ALT]");
  292.  
  293.     /* check for scroll lock key on */
  294.     if(ch & 16)
  295.         wn_putsa(window,8,24,"[SCROLL LOCK]",attribute);
  296.     else
  297.         wn_puts(window,8,24,"[SCROLL LOCK]");
  298.  
  299.     /* check for num lock on */
  300.     if(ch & 32)
  301.         wn_putsa(window,8,13,"[NUM LOCK]",attribute);
  302.     else
  303.         wn_puts(window,8,13,"[NUM LOCK]");
  304.  
  305.     /* check for caps lock on */
  306.     if(ch & 64)
  307.         wn_putsa(window,8,1,"[CAPS LOCK]",attribute);
  308.     else
  309.         wn_puts(window,8,1,"[CAPS LOCK]");
  310.  
  311.     /* check for insert mode */
  312.     if(ch & 128)
  313.         wn_putsa(window,8,38,"[INSERT MODE]",attribute);
  314.     else
  315.         wn_puts(window,8,38,"[INSERT MODE]");
  316. }
  317.  
  318. void wn_message(WINDOWPTR w,int place,char *string)
  319. {
  320.     char *p, *p1, *p2;
  321.     int len = strlen(string),
  322.         len2 = len;
  323.     int row = w->uly + w->ysize + w->bsize / 2;
  324.     int col = w->ulx + (w->bsize / 2);
  325.     switch(place)
  326.     {
  327.         case CENTERED:
  328.             col += ((w->xsize - len) / 2);
  329.             break;
  330.         case LEFT:
  331.             col ++;
  332.             break;
  333.         case RIGHT:
  334.             col += (w->xsize - len - 1);
  335.             break;
  336.     }
  337.     p = malloc((len*2)+1);                 /* fetch some memory */
  338.     p1 = p;
  339.     p2 = string;
  340.     while (len--)
  341.     {                        /* build char,,atrib */
  342.       *p1++ = *p2++;                      /* pair */
  343.       *p1++ = (char)w->bstyle;            /* for write */
  344.     }
  345.     *p1 = '\0';
  346.  
  347.     wns_savres(w->page,row,col,len2,row,p,RESTORE);
  348.     free(p);
  349. }
  350.