home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 13 / 13.iso / s / s001 / 1.ddi / PFC / SRC / KBNEC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-22  |  11.5 KB  |  498 lines

  1. /* 89-03-02 Jahns    _kbbgd() with two parameter            */
  2.  
  3.  
  4.  
  5.  
  6. /* (c) 1985, Phoenix Computer Products Corp. and Novum Organum, Inc. */
  7. /***
  8. * name        kbnec - used by library high level functions to get input.
  9. *        kbrdy  - used by library high level function to check keyboard.
  10. *
  11. * synopsis    key = kbnec()
  12. *        f_hit = kbrdy()    
  13. *        f_hit        flags if a key is waiting at the input.
  14. *
  15. * discussion:    Higher level functions, such as field input, must
  16. *        get keys from the input stream.  When your program
  17. *        begins to run, Kbnec() will be directed through
  18. *        DOS.  
  19. *
  20. * returns:    kbnec()    - a word is returned.
  21. *        The key type is in the upper byte and the key code is in
  22. *        the lower bytes.  Ascii characters are just returned as
  23. *        the character with zero in the upper bytes.
  24. *
  25. *        See 'pfdefs.h' for list of key types.
  26. *
  27. * returns :    kbrdy()    - returns non-zero if a key is waiting at input.
  28. *        kbsetnec- .
  29. ***/
  30. #include "pdefs.h"
  31.  
  32. static kbstdinnec ()
  33. {
  34. FAST    int key;
  35.     /* this is done in case input redirection is being used when system*/
  36.     /* is entered.  so keep using DOS until all initial input eaten    */
  37.     /* then switch to using BIOS functions.                */
  38.     key = RC_EOF;   
  39.     do    {
  40.     if  (kbdoshit())    
  41.         {
  42.         key = kbdosnec();
  43.         if  (KEY_TYPE(key) == KB_ASCII)
  44.         {
  45.         if  (key == LNFEED)    /* eat line feeds         */
  46.             key = RC_EOF;
  47.             else
  48.         if  (key == CPMEOF)/*<control-z> at end of redirection file*/
  49.             {
  50.             key = RC_EOF;
  51.             break;
  52.             }
  53.             }
  54.         }
  55.     else
  56.         break;    /* nothing waiting at DOS, break.        */
  57.     }
  58.     while (key==RC_EOF);
  59.  
  60.     return (key);
  61. }
  62.         
  63. int    kbbiosnec(), kbbioshit();
  64. int    kbdoshit(), kbdosnec();
  65. static    PFI    _kbnec=kbbiosnec, _kbhit=kbbioshit;
  66.  
  67. #ifdef use
  68. static    PFI    _preprc= 0 /*NULLPFI*/; /* CI86 won't take defines */
  69. static  PFI    _wndmov= 0 /*NULLPFI*/;
  70. #endif
  71.  
  72. static kbsetnec (nec, hit)
  73.     PFI    nec, hit;
  74. {
  75.     _kbnec = nec;
  76.     _kbhit = hit;
  77. }
  78.  
  79. #ifdef use
  80.  
  81. PFI    kbpreprc (preprc)
  82.     PFI    preprc;
  83. {
  84.     PFI    prv;
  85.  
  86.     prv = _preprc;
  87.     _preprc = preprc;
  88.     return (prv);
  89. }
  90.  
  91. #endif
  92.  
  93.  
  94. kbrdy()
  95. {
  96.     return ((*_kbhit)());
  97. }
  98.  
  99. int kbsource (source)
  100.     int    source;
  101. {
  102.     switch    (source)
  103.         {
  104.     case KB_DOS:
  105.         kbsetnec(kbdosnec, kbdoshit);
  106.         break;
  107.     case KB_STDIN:
  108.         kbsetnec(kbstdinnec, kbdoshit);
  109.         break;
  110.     default:
  111.     case KB_BIOS:
  112.         kbsetnec(kbbiosnec, kbbioshit);
  113.         break;
  114.         }
  115. }
  116.  
  117.     
  118. kbnec ()
  119. {
  120. FAST    int    key;
  121.  
  122.     do    {
  123.         key = (*_kbnec)();
  124. #ifdef use
  125.         if    (_preprc)
  126.             key = (*_preprc)(key);
  127.             if  ((key) && (_wndmov))
  128.                 key = (*_wndmov)(key);
  129. #endif
  130.             }
  131.     while    (!key);
  132.  
  133.     return (key);
  134. }
  135.  
  136.  
  137. #ifdef use
  138.  
  139. _kbsetwnd( wndmov )
  140.     PFI wndmov;
  141. {
  142.     _wndmov = wndmov;
  143. }
  144.  
  145. #endif
  146.  
  147.  
  148. /*
  149. * name :     kbpeek - peek ahead at the next key waiting at the keyboard.
  150. *
  151. * synopsis :     key = kbpeek()
  152. *
  153. * description :    this function is returns the <type,code> of the next
  154. *        key waiting at the keyboard.  the key is still be returned
  155. *        by the next call to kbnec().  NOTE, uses the BIOS call.
  156. *
  157. * returns    NFAIL if no key is waiting.  Otherwise a word is returned.
  158. *        The key type is in the upper byte and the key code is in
  159. *        the lower bytes.  Ascii characters are just returned as
  160. *        the character with zero in the upper bytes.
  161. *
  162. * version    1.0 (c) novum organum, inc. 1985
  163. **/
  164.  
  165. #define    NO_C_WAITING    -1
  166. #define    BIO_KBGET    0    /* interrupt 0x16 - read keyboard op    */
  167. #define    BIO_KBPEEK    1    /* interrupt 0x16 - peek at keyboard op */
  168. #define    EXTNDD_ASCII    0    /* keyboard returned extended ascii char*/
  169.  
  170.  
  171. int kbpeek()
  172. {
  173.     return (kbbios(BIO_KBPEEK));
  174. }
  175.  
  176. /***
  177. *    kbbios() is the work-horse for the above routines.
  178. *    it calls bioskey() to get the next key and then
  179. *    is     
  180. ***/
  181.  
  182.  
  183. static int kbbios(bioscall)  
  184.         int    bioscall;
  185. {
  186.     int       key;
  187.  
  188.     key = kbgate(bioscall);
  189.  
  190.     if  ((bioscall == BIO_KBPEEK) && (key == NO_C_WAITING))
  191.     key = NOTFND;
  192.     else
  193.     key = _kbencode (key);
  194.     return (key);
  195. }
  196.  
  197. /*
  198. * name :     kbbiosnec - return the next character from the keyboard.
  199. *
  200. * synopsis :     key = kbbiosnec()
  201. *
  202. * description :    this function is returns the <type,code> of the next
  203. *        key waiting at the keyboard.  _kbbgd() will execute
  204. *        background tasks if no key is waiting at the keyboard.
  205. *        NOTE, uses the BIOS call.
  206. *
  207. * returns    Otherwise a word is returned.
  208. *        The key type is in the upper byte and the key code is in
  209. *        the lower bytes.  Ascii characters are just returned as
  210. *        the character with zero in the upper bytes.
  211. *
  212. * version    1.0 (c) novum organum, inc. 1985
  213. **/
  214.  
  215. int kbbiosnec ()
  216. {
  217.     int    kbbioshit();
  218. //    _kbbgd (kbbioshit, 0);             /* execute any background tasks */
  219.     return (kbbios(BIO_KBGET));        /* get input key        */
  220. }
  221.  
  222. /*
  223. * name :     kbbioshit - check if a key is waiting at the keyboard.
  224. *
  225. * synopsis :     f_waiting = kbbioshit();
  226. *
  227. * description :    this function tells if the user has pressed a key
  228. *        and whether that key is waiting at the keyboard.
  229. *
  230. * returns    non-zero    if key is waiting
  231. *        zero        if no key is waiting.
  232. *
  233. * version    1.0 (c) novum organum, inc. 1985
  234. **/
  235.  
  236. int kbbioshit()
  237. {
  238.     return (kbpeek() != NOTFND);
  239. }
  240.  
  241. kbdirect()
  242. {
  243.     return ((kbbioshit()) ? kbbiosnec() : NOTFND);
  244. }
  245.  
  246. static    int _esc_key=ASCII_KEY(ESC);
  247.  
  248. int kbesckey()
  249. {
  250.     return(_esc_key);
  251. }
  252.  
  253. #ifdef use
  254.  
  255. kbsetesckey(key)
  256.     int    key;
  257. {
  258.     _esc_key = key;
  259. }
  260.  
  261. #endif
  262.  
  263.  
  264. int kbhitesc()
  265. {
  266.     return (kbdirect()==_esc_key);    /* ESCAPE pressed ?    */
  267. }
  268. /*
  269. * name :     kbdosnec - get next key from input without echoing it on crt.
  270. *
  271. * synopsis :     key = kbdosnec()
  272. *
  273. * description :    kbdosnec() gets the next character from the input stream,
  274. *        nomally the keyboard, although input can be redirected
  275. *        from another device or from a file.  _kbbgd() executes
  276. *        background tasks if nothing is waiting at the input 
  277. *        stream.
  278. *
  279. * returns    Otherwise a word is returned.
  280. *        The key type is in the upper byte and the key code is in
  281. *        the lower bytes.  Ascii characters are just returned as
  282. *        the character with zero in the upper bytes.
  283. *
  284. * version    1.0 (c) novum organum, inc. 1985
  285. **/
  286.  
  287. /*
  288. * name :     kbdoshit - check if a key is waiting at standard input device,
  289. *            normally the keyboard.
  290. *
  291. * synopsis :     f_waiting = kbdoshit();
  292. *
  293. * description :    this function checks to see if a key is waiting on
  294. *        this input stream read by kbdosnec().  this is normally
  295. *        the keyboard, but may be redirected from another device.
  296. *
  297. * returns    YES    key is waiting.
  298. *        NO    no key is waiting.
  299. *
  300. * version    1.0 (c) novum organum, inc. 1985
  301. **/
  302.  
  303. /***
  304. *    internal function which calls DOS to get the characters.
  305. *    if an extended ascii character is found, _kbencode() is
  306. *    called to get its corresponding <type,code> pair.
  307. ***/
  308.  
  309. #define    DOS_NEC        0x0700  /* dos no-echo character function */
  310.  
  311. static _kbbyte()
  312. {
  313.     REGIS    regs;
  314.  
  315.     regs.ax = DOS_NEC;
  316.     dosgate(®s);
  317.  
  318.     return ((int)(regs.ax & 0xff));    /* get char out of AX regs     */
  319. }
  320.  
  321. static int kbdos()  
  322. {
  323. FAST    int    key;
  324.  
  325.     key = _kbbyte();
  326.  
  327.     if    (key == EXTNDD_ASCII)
  328.         key = TOHIBYTE(_kbbyte());
  329.  
  330.     return (_kbencode(key));
  331. }
  332.  
  333. int kbdosnec ()
  334. {
  335.     int    kbdoshit();
  336.  
  337. //    _kbbgd (kbdoshit, 0);         /* execute any background tasks         */
  338.     return (kbdos());        /* wait until user presses key        */
  339. }
  340.  
  341. int kbdoshit()
  342. {         
  343.     REGIS    regs;
  344.  
  345.     regs.ax = 0x0b00;
  346.     dosgate(®s);
  347.     return ((LOBYTE(regs.ax)) ? YES : NO);
  348. }
  349. /***********************************************************************
  350. *
  351. *   these routines allow input from the keyboard or via
  352. *   a batch file. they also allow the last character input
  353. *   to be pushed back onto a 'one-byte' stack.
  354. *
  355. *   the next character is read.  if the character is a NULL,
  356. *   then it is assumed that the input is part of the extended 
  357. *   ascii codes for the PC.  A second character is read and
  358. *   the key is 'decoded' into a character type and character
  359. *   code.  
  360. *
  361. *   the character type and code are returned.
  362. *
  363. *   key entered    type        code
  364. *
  365. *    ascii code    KB_ASCII (0)    ascii code
  366. *    
  367. *    cursor key    KB_CURS (1) 
  368. *
  369. *     <end>                     1
  370. *     <dn>                      2
  371. *     <pgdn>                    3
  372. *     <lf>                      4
  373. *     <rt>                      6
  374. *     <home>                    7
  375. *     <up>                      8
  376. *     <pgup>                    9
  377. *     <ctl><end>                11
  378. *     <ctl><pgdn>               13
  379. *     <ctl><lf>                    14
  380. *     <ctl><rt>                    16
  381. *     <ctl><home>               17
  382. *     <ctl><pgup>               19
  383. *     <shift><tab>              20
  384. *
  385. *    function key   KB_FNC  (2)    
  386. *         <fi>                 1 to 10
  387. *    <shift><fi>            11 to 20
  388. *    <ctl>  <fi>            21 to 30
  389. *    <alt>  <fi>            31 to 40
  390. *
  391. *     edit key    KB_EDIT (3)
  392. *
  393. *     <ins>                 1
  394. *     <del>                 2
  395. *     <ctl-prtsc>               3
  396. *     <numeric pad '*'>        4
  397. *     <numeric pad '-'>        5
  398. *     <numeric pad '+'>        6
  399. *     <ctl-break>        7
  400. *
  401. *   
  402. *    <alt> <key>    KB_ALT  (4)    <key>
  403. *
  404. *************************************************/
  405.  
  406. #define    NPAD_STAR    0x372a    /* scan code | '*' */
  407. #define    NPAD_MINUS    0x4a2d    /* scan code | '-' */
  408. #define    NPAD_PLUS    0x4e2b    /* scan code | '+' */
  409.  
  410. static    char    *_qwerty = "QWERTYUIOP    ASDFGHJKL     ZXCVBNM";
  411. #define IBMFNCKEYS " ;<=>?@ABCDTUVWXYZ[\\]^_`abcdefghijklmnopq"
  412.  
  413. static    char _otherspecial[]={3,15,
  414.                 71,72,73,75,
  415.                 77,79,80,81,
  416.                 82,83,
  417.                 114,115,116,
  418.                 117,118,119,
  419.                 132,EOS};
  420. static    char _othercodes[] ={0/*NULLVAL*/,    K_SHIFTTAB,  
  421.                 K_HOME,     K_UP,        K_PGUP,     K_LF,
  422.                 K_RT,       K_END,          K_DOWN,       K_PGDOWN,
  423.                 K_INSERT,   K_DEL,
  424.                 K_CTLPRTSC, K_CTLLF,     K_CTLRT,
  425.                 K_CTLEND,   K_CTLPGDOWN, K_CTLHOME,
  426.                 K_CTLPGUP};
  427. static    char _othertyps[]  =     {KB_ASCII,KB_CSR,
  428.                 KB_CSR,  KB_CSR,  KB_CSR,  KB_CSR,
  429.                 KB_CSR,  KB_CSR,  KB_CSR,  KB_CSR,
  430.                 KB_EDIT, KB_EDIT,
  431.                 KB_EDIT, KB_CSR,  KB_CSR,
  432.                 KB_CSR,  KB_CSR,  KB_CSR,
  433.                 KB_CSR};
  434. static    char *_altkeys = "1234567890-=";
  435.  
  436. static _f_redef_esc=NO;    /* if the programmer wants to avoid having    */
  437.             /* input functions perform certain tasks when    */
  438.             /* when the <esc> key is pressed.  he can set    */
  439.             /* the 'no-escape' flag.  <esc>'s are then    */
  440.             /* mapped into function key zero and handled    */
  441.             /* as special keys.                */
  442. kbredefesc (setting)
  443.     int    setting;
  444. {
  445.     _f_redef_esc = setting;
  446. }
  447.  
  448. _kbencode (key)
  449. FAST    int   key;
  450. {
  451.     int    i;
  452.  
  453.     if    (LOBYTE(key)==EXTNDD_ASCII)
  454.         {
  455.     key = TOLOBYTE(key);
  456.  
  457.     if    (key==0)
  458.         key = EDIT_KEY(K_CTL_BRK);
  459.     else
  460.         if  ((i = stridxc (key,IBMFNCKEYS)) > 0) 
  461.         key = FNC_KEY(i);
  462.         else
  463.         if  ((key >= 16) && (key <= 50))    /* <alt> alphabetics */
  464.             key = ALT_KEY(_qwerty[key-16]);/*<alt><A> ==> <KB_ALT,'A'>*/
  465.         else
  466.         if  ((key >= 120) && (key <= 131))    /* <alt> numbers */
  467.             key = ALT_KEY(_altkeys[key - 120]);
  468.         else
  469.             {
  470.             i = stridxc (key, _otherspecial);
  471.             key = (i > NOTFND)
  472.             ? MAKEWORD(_othertyps[i],_othercodes[i])
  473.             : ASCII_KEY(NULLVAL);/* UNDEFINED KEY ! */
  474.         }
  475.     }
  476.     else
  477.         {/* ASCII characters.    */
  478.     switch (key)
  479.         {
  480.     case NPAD_STAR:
  481.         key = EDIT_KEY(K_STAR_NUMPAD);
  482.         break;
  483.     case NPAD_PLUS:
  484.         key = EDIT_KEY(K_PLUS_NUMPAD);
  485.         break;
  486.     case NPAD_MINUS:
  487.         key = EDIT_KEY(K_MINUS_NUMPAD);
  488.         break;
  489.     default:
  490.         key = LOBYTE(key); /* key type is ASCII (0), so zero high byte */
  491.             if  ((key == ESC) && (_f_redef_esc))
  492.             key = FNC_KEY(0);/* make <esc> == <function key zero> */
  493.         break;
  494.         }
  495.         }
  496.     return (key);
  497. }
  498.