home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c185 / 2.ddi / OWLSRC.EXE / CSCAPE / SOURCE / KBRECORD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-07  |  11.4 KB  |  468 lines

  1. /*
  2.       kbrecord.c    8/04/87 jmd        
  3.  
  4.     % kb_Record
  5.  
  6.     keystroke recorder.
  7.  
  8.     OWL 1.1
  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.     Key File Rules:
  25.     ---------------
  26.  
  27.     Regular letters are printed out verbatim
  28.     Special keys are printed out as scancode.h string
  29.         e.g., {ENTER} {ESC} {FN1}
  30.  
  31.     '{' is quoted as '{}'
  32.     Carriage returns are ignored in the key file
  33.     the {PAUSE} command can be used to indicate a delay.
  34.     the {PROMPT} waits for a real key stroke.
  35.  
  36.     the {MOUSE} command is followed by 3 numbers:
  37.         mouse x position, mouse y position, mouse event (button state)
  38.  
  39.     Note:  key_col is used to make the output file look nice.  Its
  40.     value is not necessarily religiously maintained.
  41. */
  42.  
  43. #include "oakhead.h"
  44. #include "disppriv.h"
  45.  
  46. #include "strdecl.h"    /* for ascii() */
  47. #include "scancode.h"
  48. #include "kbrecord.h"
  49.  
  50. #include <ctype.h>
  51.  
  52. struct key_name {
  53.     unsigned    val;
  54.     char          *name;    
  55. };
  56.  
  57. static struct key_name keylist[] = {
  58.     { HOME,                "HOME" },
  59.     { END,                "END" },
  60.     { LEFT,                "LEFT" },
  61.     { RIGHT,            "RIGHT" },
  62.     { UP,                "UP" },
  63.     { DOWN,                "DOWN" },
  64.     { PGUP,                "PGUP" },
  65.     { PGDN,                "PGDN" },
  66.     { INS,                "INS" },
  67.     { DEL,                "DEL" },
  68.     { TAB,                "TAB" },
  69.     { BACKSPACE,        "BACKSPACE" },
  70.     { ENTER,            "ENTER" },
  71.     { ESC,                "ESC" },
  72.     { PRTSC,            "PRTSC" },
  73.     { GREYPLUS,            "GREYPLUS" },
  74.     { GREYMINUS,        "GREYMINUS" },
  75.     { CTRL_HOME,        "CTRL_HOME" },
  76.     { CTRL_END,            "CTRL_END" },
  77.     { CTRL_LEFT,        "CTRL_LEFT" },
  78.     { CTRL_RIGHT,        "CTRL_RIGHT" },
  79.     { CTRL_PGUP,        "CTRL_PGUP" },
  80.     { CTRL_PGDN,        "CTRL_PGDN" },
  81.     { CTRL_BACKSPACE,    "CTRL_BACKSPACE" },
  82.     { CTRL_PRTSC,        "CTRL_PRTSC" },
  83.     { SHFT_HOME,        "SHFT_HOME" },
  84.     { SHFT_END,            "SHFT_END" },
  85.     { SHFT_LEFT,        "SHFT_LEFT" },
  86.     { SHFT_RIGHT,        "SHFT_RIGHT" },
  87.     { SHFT_UP,            "SHFT_UP" },
  88.     { SHFT_DOWN,        "SHFT_DOWN" },
  89.     { SHFT_PGUP,        "SHFT_PGUP" },
  90.     { SHFT_PGDN,        "SHFT_PGDN" },
  91.     { SHFT_INS,            "SHFT_INS" },
  92.     { SHFT_DEL,            "SHFT_DEL" },
  93.     { SHFT_TAB,            "SHFT_TAB" },
  94.     { FN1,                "FN1" },
  95.     { FN2,                "FN2" },
  96.     { FN3,                "FN3" },
  97.     { FN4,                "FN4" },
  98.     { FN5,                "FN5" },
  99.     { FN6,                "FN6" },
  100.     { FN7,                "FN7" },
  101.     { FN8,                "FN8" },
  102.     { FN9,                "FN9" },
  103.     { FN10,                "FN10" },
  104.     { SHFT_FN1,            "SHFT_FN1" },
  105.     { SHFT_FN2,            "SHFT_FN2" },
  106.     { SHFT_FN3,            "SHFT_FN3" },
  107.     { SHFT_FN4,            "SHFT_FN4" },
  108.     { SHFT_FN5,            "SHFT_FN5" },
  109.     { SHFT_FN6,            "SHFT_FN6" },
  110.     { SHFT_FN7,            "SHFT_FN7" },
  111.     { SHFT_FN8,            "SHFT_FN8" },
  112.     { SHFT_FN9,            "SHFT_FN9" },
  113.     { SHFT_FN10,          "SHFT_FN10" },
  114.     { CTRL_FN1,            "CTRL_FN1" },
  115.     { CTRL_FN2,            "CTRL_FN2" },
  116.     { CTRL_FN3,            "CTRL_FN3" },
  117.     { CTRL_FN5,            "CTRL_FN5" },
  118.     { CTRL_FN6,            "CTRL_FN6" },
  119.     { CTRL_FN7,            "CTRL_FN7" },
  120.     { CTRL_FN8,            "CTRL_FN8" },
  121.     { CTRL_FN9,            "CTRL_FN9" },
  122.     { CTRL_FN10,          "CTRL_FN10" },
  123.     { ALT_FN1,            "ALT_FN1" },
  124.     { ALT_FN2,            "ALT_FN2" },
  125.     { ALT_FN3,            "ALT_FN3" },
  126.     { ALT_FN4,            "ALT_FN4" },
  127.     { ALT_FN5,            "ALT_FN5" },
  128.     { ALT_FN6,            "ALT_FN6" },
  129.     { ALT_FN7,            "ALT_FN7" },
  130.     { ALT_FN8,            "ALT_FN8" },
  131.     { ALT_FN9,            "ALT_FN9" },
  132.     { ALT_FN10,            "ALT_FN10" },
  133.     { CTRL_2,            "CTRL_2" },
  134.     { CTRL_6,            "CTRL_6" },
  135.     { CTRL_HYPHEN,        "CTRL_HYPHEN" },
  136.     { CTRL_BS,            "CTRL_BS" },
  137.     { CTRL_A,            "CTRL_A" },
  138.     { CTRL_B,            "CTRL_B" },
  139.     { CTRL_C,            "CTRL_C" },
  140.     { CTRL_D,            "CTRL_D" },
  141.     { CTRL_E,            "CTRL_E" },
  142.     { CTRL_F,            "CTRL_F" },
  143.     { CTRL_G,            "CTRL_G" },
  144.     { CTRL_H,            "CTRL_H" },
  145.     { CTRL_I,            "CTRL_I" },
  146.     { CTRL_J,            "CTRL_J" },
  147.     { CTRL_K,            "CTRL_K" },
  148.     { CTRL_L,            "CTRL_L" },
  149.     { CTRL_M,            "CTRL_M" },
  150.     { CTRL_N,            "CTRL_N" },
  151.     { CTRL_O,            "CTRL_O" },
  152.     { CTRL_P,            "CTRL_P" },
  153.     { CTRL_Q,            "CTRL_Q" },
  154.     { CTRL_R,            "CTRL_R" },
  155.     { CTRL_S,            "CTRL_S" },
  156.     { CTRL_T,            "CTRL_T" },
  157.     { CTRL_U,            "CTRL_U" },
  158.     { CTRL_V,            "CTRL_V" },
  159.     { CTRL_W,            "CTRL_W" },
  160.     { CTRL_X,            "CTRL_X" },
  161.     { CTRL_Y,            "CTRL_Y" },
  162.     { CTRL_Z,            "CTRL_Z" },
  163.     { ALT_1,            "ALT_1" },
  164.     { ALT_2,            "ALT_2" },
  165.     { ALT_3,            "ALT_3" },
  166.     { ALT_4,            "ALT_4" },
  167.     { ALT_5,            "ALT_5" },
  168.     { ALT_6,            "ALT_6" },
  169.     { ALT_7,            "ALT_7" },
  170.     { ALT_8,            "ALT_8" },
  171.     { ALT_9,            "ALT_9" },
  172.     { ALT_0,            "ALT_0" },
  173.     { ALT_HYPHEN,        "ALT_HYPHEN" },
  174.     { ALT_EQUALS,        "ALT_EQUALS" },
  175.     { ALT_A,            "ALT_A" },
  176.     { ALT_B,            "ALT_B" },
  177.     { ALT_C,            "ALT_C" },
  178.     { ALT_D,            "ALT_D" },
  179.     { ALT_E,            "ALT_E" },
  180.     { ALT_F,            "ALT_F" },
  181.     { ALT_G,            "ALT_G" },
  182.     { ALT_H,            "ALT_H" },
  183.     { ALT_I,            "ALT_I" },
  184.     { ALT_J,            "ALT_J" },
  185.     { ALT_K,            "ALT_K" },
  186.     { ALT_L,            "ALT_L" },
  187.     { ALT_M,            "ALT_M" },
  188.     { ALT_N,            "ALT_N" },
  189.     { ALT_O,            "ALT_O" },
  190.     { ALT_P,            "ALT_P" },
  191.     { ALT_Q,            "ALT_Q" },
  192.     { ALT_R,            "ALT_R" },
  193.     { ALT_S,            "ALT_S" },
  194.     { ALT_T,            "ALT_T" },
  195.     { ALT_U,            "ALT_U" },
  196.     { ALT_V,            "ALT_V" },
  197.     { ALT_W,            "ALT_W" },
  198.     { ALT_X,            "ALT_X" },
  199.     { ALT_Y,            "ALT_Y" },
  200.     { ALT_Z,            "ALT_Z" },
  201.     { HARD_MEV,            "M" },                /* mouse event */
  202.     { KEY_PAUSE,        "PAUSE" },            /* pause command */
  203.     { KEY_PROMPT,        "PROMPT" },            /* prompt command */
  204.     { 0,                "" }                /* End of list, ignore keystroke */
  205. };
  206.  
  207. OSTATIC unsigned krec_Read(_arg1(moupos_struct *));
  208. OSTATIC unsigned krec_Check(_arg1(unsigned));
  209. OSTATIC char    *key_FindName(_arg1(unsigned));
  210. OSTATIC unsigned key_FindVal(_arg1(char *));
  211.  
  212. #define KEY_WIDTH    70                    /* width of key file */
  213.  
  214. /** static data **/
  215.  
  216. static int key_mode = KB_STOP;
  217. static int key_col = 0;                    /* column in key file */
  218. static int key_delay = 0;
  219.  
  220. static boolean key_evcheck = TRUE;         /* old state of evcheck flag */
  221.  
  222. static FILE *keyfile;
  223.  
  224. static dig_hReadEvent_func    ((*hReadEventFptr)) = FNULL;
  225. static dig_hCheckEvent_func    ((*hCheckEventFptr)) = FNULL;
  226. /* -------------------------------------------------------------------------- */
  227.  
  228. void kb_Record(fp, mode, delay)
  229.     FILE *fp;
  230.     int mode;
  231.     int delay;
  232. /*
  233.     Starts up memory key handler.
  234.  
  235.     mode determines the operating mode.
  236.  
  237.     KB_RECORD    records keystrokes to fp.
  238.     KB_PLAY        playsback keystrokes from fp
  239.     KB_STOP        stops operation (play or learn)
  240.  
  241.     fp must be an open file (for writing if KB_RECORD, reading if KB_PLAY)
  242.  
  243.     delay determines how much to pause between keystrokes.
  244. */
  245. {
  246.     owl_Assert(disp_Ok(), OE_KR_DISP);
  247.  
  248.     if (mode == KB_STOP) {
  249.         if (key_mode != KB_STOP) {
  250.             /* restore keybord handler */
  251.             key_mode = KB_STOP;
  252.             key_col = 0;
  253.             key_delay = 0;
  254.             keyfile = NULL;
  255.  
  256.             disp_SetEvCheck(key_evcheck);
  257.  
  258.             curr_dmgr->disp.dig.hReadEvent = hReadEventFptr;
  259.             curr_dmgr->disp.dig.hCheckEvent = hCheckEventFptr;
  260.         }
  261.     }
  262.     else {
  263.         key_col = 0;
  264.         key_mode = mode;
  265.         key_delay = delay;
  266.         keyfile = fp;
  267.  
  268.         key_evcheck = disp_EvCheck();
  269.     
  270.         rewind(keyfile);
  271.  
  272.         /* save old keyboard handler */
  273.         hReadEventFptr = curr_dmgr->disp.dig.hReadEvent;
  274.         hCheckEventFptr = curr_dmgr->disp.dig.hCheckEvent;
  275.  
  276.         /* set new keyboard handler */
  277.         curr_dmgr->disp.dig.hReadEvent = krec_Read;
  278.         curr_dmgr->disp.dig.hCheckEvent = krec_Check;
  279.  
  280.         /* we're not supporting kb_Check anymore, turn off evcheck flag */
  281.         disp_SetEvCheck(FALSE);
  282.     }
  283. }
  284. /* -------------------------------------------------------------------------- */
  285.  
  286. static unsigned krec_Check(wait)
  287.     unsigned wait;
  288. /*
  289.     Substitute kb_Check handler
  290.     Always returns TRUE.
  291. */
  292. {
  293.     oak_notused(wait);
  294.     return(TRUE);
  295. }
  296. /* -------------------------------------------------------------------------- */
  297.  
  298. static unsigned krec_Read(mposp)
  299.     moupos_struct *mposp;
  300. /*
  301.     effects:    reads next key from keyboard buffer.
  302.     returns:    ASCII value of character in bits 0-7,
  303.                 and the scan code of the character in
  304.                 bits 8-15.
  305.  
  306.     In KB_RECORD mode saves the scancode in the keyfile.
  307.  
  308.     In KB_PLAY mode returns the scancodes from the keyfile.
  309. */
  310. {
  311.     unsigned scancode;
  312.     int     key, gotkey;
  313.     char   *p, name[22];
  314.  
  315.     if (key_mode == KB_PLAY) {
  316.  
  317.         gotkey = 0;
  318.         while(!gotkey) {
  319.             gotkey = 1;
  320.  
  321.             if ((key = fgetc(keyfile)) == EOF) {
  322.                 key_mode = KB_STOP;
  323.                 scancode = (*hReadEventFptr)(mposp);
  324.             }
  325.             else if (key ==  '\n') {
  326.                 /* skip newline */
  327.                 gotkey = 0;
  328.             }
  329.             else if (key ==  '{') {
  330.                 p = name;
  331.                 while ((p - name) < 20) {
  332.                     if ((*p = (char) fgetc(keyfile)) == EOF) {
  333.                         key_mode = KB_STOP;
  334.                         scancode = (*hReadEventFptr)(mposp);
  335.                         break;
  336.                     }
  337.                     else if (*p == '}') {
  338.                         if (p == name) {
  339.                             /* "{}" is quoted '{' */
  340.                             scancode = '{';
  341.                         }
  342.                         else {
  343.                             *p = '\0';
  344.                             /* look up scancode, test for commands */
  345.                             switch (scancode = key_FindVal(name)) {
  346.                                 case HARD_MEV:
  347.                                     /* get mouse event information */
  348.                                     fscanf(keyfile, "(%d,%d,%u)", 
  349.                                         &(mposp->x), &(mposp->y), &(mposp->event));
  350.                                     break;
  351.  
  352.                                 case KEY_PAUSE:
  353.                                     /* pause command (alway pause for fixed amount?) */
  354.                                     if (key_delay > 0) {
  355.                                         hard_Pause(key_delay);
  356.                                     }
  357.                                     gotkey = 0;
  358.                                     break;
  359.  
  360.                                 case KEY_PROMPT:
  361.                                     /* prompt: wait for a real keystroke */
  362.                                     while ((*hReadEventFptr)(mposp) == HARD_MEV) {
  363.                                         ;
  364.                                     }
  365.                                     gotkey = 0;
  366.                                     break;
  367.  
  368.                                 default:
  369.                                     break;
  370.                             }
  371.                         }
  372.                         break;    /* while ((p - name) < 20) */
  373.                     }
  374.                     p++;
  375.                 }
  376.             }
  377.             else {
  378.                 scancode = (unsigned) ascii(key);
  379.             }
  380.         }
  381.         /* delay */
  382.         if (key_delay > 0) {
  383.             hard_Pause(key_delay);
  384.         }
  385.     }
  386.     else if (key_mode == KB_RECORD) {
  387.         scancode = (*hReadEventFptr)(mposp);
  388.         if (ascii(scancode) == '{') {
  389.             /* quote '{' character */
  390.             fprintf(keyfile, "{}");
  391.             key_col += 2;
  392.         }
  393.         else if (scancode == GREYPLUS || scancode == GREYMINUS) {
  394.             /* Handle these separately to distinguish from regular + and - */
  395.             fprintf(keyfile, "{%s}", key_FindName(scancode));
  396.             key_col += 8;
  397.         }
  398.         else if (isprint(ascii(scancode))) {
  399.             fprintf(keyfile, "%c", ascii(scancode));
  400.             key_col++;
  401.         }
  402.         else {
  403.             p = key_FindName(scancode);
  404.             /* Skip unnamed keystrokes */
  405.             if (*p != '\0') {
  406.                 fprintf(keyfile, "{%s}", p);
  407.                 key_col += 7;
  408.                 if (scancode == HARD_MEV) {
  409.                     /* tack on additional mouse information (x,y,event) */
  410.                     fprintf(keyfile, "(%d,%d,%u)", mposp->x, mposp->y, mposp->event);
  411.                     key_col += 8;
  412.                 }
  413.             }
  414.         }
  415.  
  416.         /* wrap key file for readability */
  417.         if (key_col > KEY_WIDTH) {
  418.             key_col = 0;
  419.             fprintf(keyfile, "\n");
  420.         }
  421.     }
  422.     else {
  423.         scancode = (*hReadEventFptr)(mposp);
  424.     }
  425.  
  426.     return(scancode);
  427. }
  428. /* -------------------------------------------------------------------------- */
  429.  
  430. static char *key_FindName(key)
  431.     unsigned key;
  432. /*
  433.     Given a key value, lookup the key's name
  434. */
  435. {
  436.     int i;
  437.     
  438.     for(i = 0; keylist[i].val != 0;i++) {
  439.         if (keylist[i].val == key) {
  440.             break;
  441.         }
  442.     }
  443.  
  444.     return(keylist[i].name);
  445. }
  446. /* -------------------------------------------------------------------------- */
  447.  
  448. static unsigned key_FindVal(name)
  449.     char *name;
  450. /*
  451.     Given a key name, lookup the key's value
  452.     If name is a command such as PAUSE
  453.     then PAUSE is returned.
  454. */
  455. {
  456.     int i;
  457.     
  458.     for(i = 0; keylist[i].val != 0;i++) {
  459.         if (strcmp(keylist[i].name, name) == 0) {
  460.             break;
  461.         }
  462.     }
  463.  
  464.     return(keylist[i].val);
  465. }
  466. /* -------------------------------------------------------------------------- */
  467.  
  468.