home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 201_01 / keybd.doc < prev    next >
Text File  |  1979-12-31  |  4KB  |  153 lines

  1.     
  2.     
  3.     Referenced article:  User Wants Inkey () In C Libraries
  4.                  The C Users' Group Newsletter
  5.                  September 1986
  6.     
  7.     I agree with Phillip Emerson that it would be nice if C compiler 
  8.     vendors provided an Inkey type of function in their libraries.  
  9.     However, I would recommend that such an inkey() function allow all 
  10.     possible combinations of keyboard entries, including the NULL or 
  11.     CNTL @ character, whose value is zero.  This can be done by 
  12.     specifying that inkey() return -1, or better yet -129, whenever the 
  13.     keyboard is not ready to send a character.  
  14.     
  15.     Perhaps preferable to inkey(), would be a pair of functions such as 
  16.     kbd_rdy() and kbd_in().  kbd_rdy() would return either TRUE or 
  17.     FALSE, according to whether the keyboard is ready to send a 
  18.     character.  kbd_in() would return a character, looping if necessary 
  19.     until a character became available.
  20.     
  21.     This would result in code such as:
  22.     
  23.         if (kbd_rdy())
  24.             {
  25.             ch = kbd_in();
  26.             /* ready path */
  27.             }
  28.         else
  29.             /* not ready path */
  30.     
  31.     rather than,
  32.     
  33.         #define NOT_RDY    -129
  34.         ...
  35.         
  36.         if ((ch = inkey()) == NOT_RDY)
  37.             /* not ready path */
  38.         else
  39.             /* ready path */
  40.         
  41.     In the first case, "ch" can be a char, but in the latter case, "ch" 
  42.     must be an int to allow for 256 character possibilities in addition 
  43.     to NOT_RDY.  
  44.     
  45.     In cases where the programmer knows there is nothing for the 
  46.     program to do until a character is available, we have:
  47.     
  48.         ch = kbd_in();
  49.         
  50.     rather than,
  51.     
  52.         while ((ch = inkey()) == NOT_RDY)
  53.             {}
  54.         
  55.     kbd_in() and kbd_rdy() can be implemented directly or in terms of 
  56.     inkey().  Here they are in terms of inkey():
  57.     
  58.     #define    NOT_RDY    -129
  59.     
  60.     int    gotten_char;
  61.     int    got_char = FALSE;
  62.     
  63.     kbd_rdy()
  64.     {
  65.     if (got_char)
  66.         return TRUE;
  67.     if ((gotten_char = inkey()) != NOT_RDY)
  68.         got_char = TRUE;
  69.     return got_char;
  70.     }
  71.     
  72.     kbd_in()
  73.     {
  74.     while ( ! kbd_rdy())
  75.         {}
  76.     got_char = FALSE;
  77.     return gotten_char;
  78.     }
  79.     
  80.     The reason -129 is chosen, is that it works both for machines which 
  81.     do sign extension as well as those which do not.  This is for 
  82.     portability.  2's complement representation is assumed in both 
  83.     machine types.
  84.     
  85.     A not-ready indicator of -1 is fine for machines which don't do 
  86.     sign extension, but on those which do, it would collide with a 
  87.     character value of 255.  255 is a signed character with value -1.  
  88.     Extending its sign gives a signed integer of -1.  Signed characters 
  89.     only go as low as -128, hence -129.  
  90.     
  91.     Here are kbd_rdy() and kbd_in() implemented directley (for running 
  92.     under MS-DOS or PC-DOS) using DesMet C (C WARE Corp):
  93.     
  94.         char    gotten_char;
  95.         char    got_char = FALSE;
  96.     
  97.         kbd_rdy()
  98.         {
  99.         if (got_char)
  100.             return TRUE;
  101.         
  102.         /* in-line assembly follows: */
  103.         #asm
  104.             mov    dl,255
  105.             mov    ah,6
  106.             int    21h
  107.             mov    sp,bp
  108.             jz    not_rdy
  109.             mov byte got_char_,1
  110.             mov byte gotten_char_,al
  111.             not_rdy:
  112.         #
  113.         
  114.         return (int) got_char;
  115.         }
  116.     
  117.         kbd_in()
  118.         {
  119.         while ( ! kbd_rdy())
  120.             {}
  121.         got_char = FALSE;
  122.         return (int) gotten_char;
  123.         }
  124.         
  125.     To show that kbd_rdy() and kbd_in() can supplant inkey(), here is 
  126.     inkey() in terms of kbd_in() and kbd_rdy():
  127.     
  128.         #define NOT_RDY -129
  129.         
  130.         inkey()
  131.         {
  132.         return (kbd_rdy() ? kbd_in() : NOT_RDY);
  133.         }
  134.         
  135.     Finally, another useful function is kbd_purge().
  136.     
  137.         kbd_purge()    /* keyboard purge */
  138.         {
  139.         while (kbd_rdy())
  140.             kbd_in();
  141.         }
  142.         
  143.     Following is a program, using the three "kbd" functions.  It 
  144.     illustrates having a "background" process.  The "foreground" 
  145.     process is simply getting and putting keyboard characters to the 
  146.     console.  The "background" process is sending periods to the 
  147.     console, and it is initiated and stopped by typing a period.  The 
  148.     program ends with control C.
  149.     
  150.     Richard Hilburger
  151.     195 S.E. 26th Ave.
  152.     Hillsboro OR 97123
  153.