home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / OWLSCR / KBRECORD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-01  |  7.9 KB  |  327 lines

  1. /*
  2.       kbrecord.c    8/04/87 jmd        
  3.  
  4.     % kb_Record
  5.  
  6.     keystroke recorder.
  7.  
  8.     OWL 1.2
  9.     Copyright (c) 1988, 1989 by Oakland Group, Inc.
  10.     ALL RIGHTS RESERVED.
  11.  
  12.     Revision History:
  13.     -----------------
  14.      9/11/88 jmd    Added support for GREYPLUS and GREYMINUS
  15.     10/05/88 jmd    Added support for kb_Check
  16.     11/07/88 jmd    fixed support for kb_Check, added assert
  17.     12/01/88 jmd    modified for new KeyReadEvent
  18.  
  19.      1/09/88 jmd    changed if (mode != KB_STOP) to if (key_mode ...
  20.      7/07/89 gam    changed NULL to FNULL where applicable
  21.      8/14/89 jmd    added evcheck support and MOUSE support
  22.      8/23/89 jmd    changed {MOUSE} to {M}, removed use of fprintf return value
  23.  
  24.      3/28/90 jmd    ansi-fied
  25.      5/12/90 jmd     changed scancodes to ints
  26.      8/15/90 jdc    combined kb_Macro stuff
  27.     10/04/90 jmd    added call to kb_Clear for PROMPT case
  28.     10/28/90 jmd    pressing ESC in PROMPT case stops the playback
  29.     10/31/90 ted    added code to check for EOF return from fgetc().
  30.  
  31.     Key File Rules:
  32.     ---------------
  33.  
  34.     Regular letters are printed out verbatim
  35.     Special keys are printed out as scancode.h string
  36.         e.g., {ENTER} {ESC} {FN1}
  37.  
  38.     '{' is quoted as '{}'
  39.     Carriage returns are ignored in the key file
  40.     the {PAUSE} command can be used to indicate a delay.
  41.     the {PROMPT} waits for a real key stroke.
  42.         if ESC is pressed stops the playback
  43.  
  44.     the {MOUSE} command is followed by 3 numbers:
  45.         mouse x position, mouse y position, mouse event (button state)
  46.  
  47.     Note:  key_col is used to make the output file look nice.  Its
  48.     value is not necessarily religiously maintained.
  49. */
  50.  
  51. #include "oakhead.h"
  52. #include "disppriv.h"
  53.  
  54. #include "strdecl.h"    /* for ascii() */
  55. #include "scancode.h"
  56. #include "kbrecord.h"
  57.  
  58. #include <ctype.h>
  59.  
  60. OSTATIC int        krec_Check(unsigned wait);
  61. OSTATIC int        krec_Read(moupos_struct *mposp);
  62.  
  63. OSTATIC char     *key_FindName(int key);
  64. OSTATIC int        key_FindVal(char *name);
  65.  
  66. #define KEY_WIDTH    70                    /* width of key file */
  67.  
  68. /** static data **/
  69.  
  70. static int key_mode = KB_STOP;
  71. static int key_col = 0;                    /* column in key file */
  72. static int key_delay = 0;
  73.  
  74. static boolean key_evcheck = TRUE;         /* old state of evcheck flag */
  75.  
  76. static FILE *keyfile;
  77.  
  78. static dig_hReadEvent_func    ((*hReadEventFptr)) = FNULL;
  79. static dig_hCheckEvent_func    ((*hCheckEventFptr)) = FNULL;
  80. /* -------------------------------------------------------------------------- */
  81.  
  82. void kb_Record(FILE *fp, int mode, int delay)
  83. /*
  84.     Starts up memory key handler.
  85.  
  86.     mode determines the operating mode.
  87.  
  88.     KB_RECORD    records keystrokes to fp.
  89.     KB_PLAY        playsback keystrokes from fp
  90.     KB_STOP        stops operation (play or learn)
  91.  
  92.     fp must be an open file (for writing if KB_RECORD, reading if KB_PLAY)
  93.  
  94.     delay determines how much to pause between keystrokes.
  95. */
  96. {
  97.     owl_Assert(disp_Ok(), OE_KR_DISP);
  98.  
  99.     if (mode == KB_STOP) {
  100.         if (key_mode != KB_STOP) {
  101.             /* restore keybord handler */
  102.             key_mode = KB_STOP;
  103.             key_col = 0;
  104.             key_delay = 0;
  105.             keyfile = NULL;
  106.  
  107.             disp_SetEvCheck(key_evcheck);
  108.  
  109.             curr_dmgr->disp.dig.hReadEvent = hReadEventFptr;
  110.             curr_dmgr->disp.dig.hCheckEvent = hCheckEventFptr;
  111.         }
  112.     }
  113.     else {
  114.         key_col = 0;
  115.         key_mode = mode;
  116.         key_delay = delay;
  117.         keyfile = fp;
  118.  
  119.         key_evcheck = disp_EvCheck();
  120.     
  121.         rewind(keyfile);
  122.  
  123.         /* save old keyboard handler */
  124.         hReadEventFptr = curr_dmgr->disp.dig.hReadEvent;
  125.         hCheckEventFptr = curr_dmgr->disp.dig.hCheckEvent;
  126.  
  127.         /* set new keyboard handler */
  128.         curr_dmgr->disp.dig.hReadEvent = krec_Read;
  129.         curr_dmgr->disp.dig.hCheckEvent = krec_Check;
  130.  
  131.         /* we're not supporting kb_Check anymore, turn off evcheck flag */
  132.         disp_SetEvCheck(FALSE);
  133.     }
  134. }
  135. /* -------------------------------------------------------------------------- */
  136.  
  137. static int krec_Check(unsigned wait)
  138. /*
  139.     Substitute kb_Check handler
  140.     Always returns TRUE.
  141. */
  142. {
  143.     oak_notused(wait);
  144.     return(TRUE);
  145. }
  146. /* -------------------------------------------------------------------------- */
  147.  
  148. static int krec_Read(moupos_struct *mposp)
  149. /*
  150.     effects:    reads next key from keyboard buffer.
  151.     returns:    ASCII value of character in bits 0-7,
  152.                 and the scan code of the character in
  153.                 bits 8-15.
  154.  
  155.     In KB_RECORD mode saves the scancode in the keyfile.
  156.  
  157.     In KB_PLAY mode returns the scancodes from the keyfile.
  158. */
  159. {
  160.     int        scancode;
  161.     int     key, gotkey, tkey;
  162.     char   *p, name[22];
  163.  
  164.     if (key_mode == KB_PLAY) {
  165.  
  166.         gotkey = 0;
  167.         while(!gotkey) {
  168.             gotkey = 1;
  169.  
  170.             if ((key = fgetc(keyfile)) == EOF) {
  171.                 key_mode = KB_STOP;
  172.                 scancode = (*hReadEventFptr)(mposp);
  173.             }
  174.             else if (key ==  '\n') {
  175.                 /* skip newline */
  176.                 gotkey = 0;
  177.             }
  178.             else if (key ==  '{') {
  179.                 p = name;
  180.                 while ((p - name) < 20) {
  181.                     tkey = fgetc(keyfile);
  182.                     *p = (char) tkey;
  183.                     if (tkey == EOF) {
  184.                         key_mode = KB_STOP;
  185.                         scancode = (*hReadEventFptr)(mposp);
  186.                         break;
  187.                     }
  188.                     else if (*p == '}') {
  189.                         if (p == name) {
  190.                             /* "{}" is quoted '{' */
  191.                             scancode = '{';
  192.                         }
  193.                         else {
  194.                             *p = '\0';
  195.                             /* look up scancode, test for commands */
  196.                             switch (scancode = key_FindVal(name)) {
  197.                                 case HARD_MEV:
  198.                                     /* get mouse event information */
  199.                                     fscanf(keyfile, "(%d,%d,%u)", 
  200.                                         &(mposp->x), &(mposp->y), &(mposp->event));
  201.                                     break;
  202.  
  203.                                 case KEY_PAUSE:
  204.                                     /* pause command (alway pause for fixed amount?) */
  205.                                     if (key_delay > 0) {
  206.                                         hard_Pause(key_delay);
  207.                                     }
  208.                                     gotkey = 0;
  209.                                     break;
  210.  
  211.                                 case KEY_PROMPT:
  212.                                     /* prompt: wait for a real keystroke */
  213.                                     /* quit if ESC pressed */
  214.  
  215.                                     /* clear keyboard buffer first */
  216.                                     kb_Clear();
  217.                                     while ((key = (*hReadEventFptr)(mposp)) == HARD_MEV) {
  218.                                         ;
  219.                                     }
  220.                                     if (key == ESC) {
  221.                                         /* stop playback */
  222.                                         key_mode = KB_STOP;
  223.                                         scancode = (*hReadEventFptr)(mposp);
  224.                                     }
  225.                                     else {
  226.                                         gotkey = 0;
  227.                                     }
  228.                                     break;
  229.  
  230.                                 default:
  231.                                     break;
  232.                             }
  233.                         }
  234.                         break;    /* while ((p - name) < 20) */
  235.                     }
  236.                     p++;
  237.                 }
  238.             }
  239.             else {
  240.                 scancode = ascii(key);
  241.             }
  242.         }
  243.         /* delay */
  244.         if (key_delay > 0) {
  245.             hard_Pause(key_delay);
  246.         }
  247.     }
  248.     else if (key_mode == KB_RECORD) {
  249.         scancode = (*hReadEventFptr)(mposp);
  250.         if (ascii(scancode) == '{') {
  251.             /* quote '{' character */
  252.             fprintf(keyfile, "{}");
  253.             key_col += 2;
  254.         }
  255.         else if (scancode == GREYPLUS || scancode == GREYMINUS) {
  256.             /* Handle these separately to distinguish from regular + and - */
  257.             fprintf(keyfile, "{%s}", key_FindName(scancode));
  258.             key_col += 8;
  259.         }
  260.         else if (isprint(ascii(scancode))) {
  261.             fprintf(keyfile, "%c", ascii(scancode));
  262.             key_col++;
  263.         }
  264.         else {
  265.             p = key_FindName(scancode);
  266.             /* Skip unnamed keystrokes */
  267.             if (*p != '\0') {
  268.                 fprintf(keyfile, "{%s}", p);
  269.                 key_col += 7;
  270.                 if (scancode == HARD_MEV) {
  271.                     /* tack on additional mouse information (x,y,event) */
  272.                     fprintf(keyfile, "(%d,%d,%u)", mposp->x, mposp->y, mposp->event);
  273.                     key_col += 8;
  274.                 }
  275.             }
  276.         }
  277.  
  278.         /* wrap key file for readability */
  279.         if (key_col > KEY_WIDTH) {
  280.             key_col = 0;
  281.             fprintf(keyfile, "\n");
  282.         }
  283.     }
  284.     else {
  285.         /* not recording or playing */
  286.         scancode = (*hReadEventFptr)(mposp);
  287.     }
  288.  
  289.     return(scancode);
  290. }
  291. /* -------------------------------------------------------------------------- */
  292.  
  293. static char *key_FindName(int key)
  294. /*
  295.     Given a key value, lookup the key's name
  296. */
  297. {
  298.     int i;
  299.     
  300.     for (i = 0; kb_keylist[i].scan != 0; i++) {
  301.         if (kb_keylist[i].scan == key) {
  302.             break;
  303.         }
  304.     }
  305.  
  306.     return(kb_keylist[i].name);
  307. }
  308. /* -------------------------------------------------------------------------- */
  309.  
  310. static int key_FindVal(char *name)
  311. /*
  312.     Given a key name, lookup the key's value
  313.     If name is a command such as PAUSE
  314.     then PAUSE is returned.
  315. */
  316. {
  317.     int i;
  318.     
  319.     for (i = 0; kb_keylist[i].scan != 0; i++) {
  320.         if (strcmp(kb_keylist[i].name, name) == 0) {
  321.             break;
  322.         }
  323.     }
  324.  
  325.     return(kb_keylist[i].scan);
  326. }
  327.