home *** CD-ROM | disk | FTP | other *** search
- /*
- kbrecord.c 8/04/87 jmd
-
- % kb_Record
-
- keystroke recorder.
-
- OWL 1.2
- Copyright (c) 1988, 1989 by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 9/11/88 jmd Added support for GREYPLUS and GREYMINUS
- 10/05/88 jmd Added support for kb_Check
- 11/07/88 jmd fixed support for kb_Check, added assert
- 12/01/88 jmd modified for new KeyReadEvent
-
- 1/09/88 jmd changed if (mode != KB_STOP) to if (key_mode ...
- 7/07/89 gam changed NULL to FNULL where applicable
- 8/14/89 jmd added evcheck support and MOUSE support
- 8/23/89 jmd changed {MOUSE} to {M}, removed use of fprintf return value
-
- 3/28/90 jmd ansi-fied
- 5/12/90 jmd changed scancodes to ints
- 8/15/90 jdc combined kb_Macro stuff
- 10/04/90 jmd added call to kb_Clear for PROMPT case
- 10/28/90 jmd pressing ESC in PROMPT case stops the playback
- 10/31/90 ted added code to check for EOF return from fgetc().
-
- Key File Rules:
- ---------------
-
- Regular letters are printed out verbatim
- Special keys are printed out as scancode.h string
- e.g., {ENTER} {ESC} {FN1}
-
- '{' is quoted as '{}'
- Carriage returns are ignored in the key file
- the {PAUSE} command can be used to indicate a delay.
- the {PROMPT} waits for a real key stroke.
- if ESC is pressed stops the playback
-
- the {MOUSE} command is followed by 3 numbers:
- mouse x position, mouse y position, mouse event (button state)
-
- Note: key_col is used to make the output file look nice. Its
- value is not necessarily religiously maintained.
- */
-
- #include "oakhead.h"
- #include "disppriv.h"
-
- #include "strdecl.h" /* for ascii() */
- #include "scancode.h"
- #include "kbrecord.h"
-
- #include <ctype.h>
-
- OSTATIC int krec_Check(unsigned wait);
- OSTATIC int krec_Read(moupos_struct *mposp);
-
- OSTATIC char *key_FindName(int key);
- OSTATIC int key_FindVal(char *name);
-
- #define KEY_WIDTH 70 /* width of key file */
-
- /** static data **/
-
- static int key_mode = KB_STOP;
- static int key_col = 0; /* column in key file */
- static int key_delay = 0;
-
- static boolean key_evcheck = TRUE; /* old state of evcheck flag */
-
- static FILE *keyfile;
-
- static dig_hReadEvent_func ((*hReadEventFptr)) = FNULL;
- static dig_hCheckEvent_func ((*hCheckEventFptr)) = FNULL;
- /* -------------------------------------------------------------------------- */
-
- void kb_Record(FILE *fp, int mode, int delay)
- /*
- Starts up memory key handler.
-
- mode determines the operating mode.
-
- KB_RECORD records keystrokes to fp.
- KB_PLAY playsback keystrokes from fp
- KB_STOP stops operation (play or learn)
-
- fp must be an open file (for writing if KB_RECORD, reading if KB_PLAY)
-
- delay determines how much to pause between keystrokes.
- */
- {
- owl_Assert(disp_Ok(), OE_KR_DISP);
-
- if (mode == KB_STOP) {
- if (key_mode != KB_STOP) {
- /* restore keybord handler */
- key_mode = KB_STOP;
- key_col = 0;
- key_delay = 0;
- keyfile = NULL;
-
- disp_SetEvCheck(key_evcheck);
-
- curr_dmgr->disp.dig.hReadEvent = hReadEventFptr;
- curr_dmgr->disp.dig.hCheckEvent = hCheckEventFptr;
- }
- }
- else {
- key_col = 0;
- key_mode = mode;
- key_delay = delay;
- keyfile = fp;
-
- key_evcheck = disp_EvCheck();
-
- rewind(keyfile);
-
- /* save old keyboard handler */
- hReadEventFptr = curr_dmgr->disp.dig.hReadEvent;
- hCheckEventFptr = curr_dmgr->disp.dig.hCheckEvent;
-
- /* set new keyboard handler */
- curr_dmgr->disp.dig.hReadEvent = krec_Read;
- curr_dmgr->disp.dig.hCheckEvent = krec_Check;
-
- /* we're not supporting kb_Check anymore, turn off evcheck flag */
- disp_SetEvCheck(FALSE);
- }
- }
- /* -------------------------------------------------------------------------- */
-
- static int krec_Check(unsigned wait)
- /*
- Substitute kb_Check handler
- Always returns TRUE.
- */
- {
- oak_notused(wait);
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- static int krec_Read(moupos_struct *mposp)
- /*
- effects: reads next key from keyboard buffer.
- returns: ASCII value of character in bits 0-7,
- and the scan code of the character in
- bits 8-15.
-
- In KB_RECORD mode saves the scancode in the keyfile.
-
- In KB_PLAY mode returns the scancodes from the keyfile.
- */
- {
- int scancode;
- int key, gotkey, tkey;
- char *p, name[22];
-
- if (key_mode == KB_PLAY) {
-
- gotkey = 0;
- while(!gotkey) {
- gotkey = 1;
-
- if ((key = fgetc(keyfile)) == EOF) {
- key_mode = KB_STOP;
- scancode = (*hReadEventFptr)(mposp);
- }
- else if (key == '\n') {
- /* skip newline */
- gotkey = 0;
- }
- else if (key == '{') {
- p = name;
- while ((p - name) < 20) {
- tkey = fgetc(keyfile);
- *p = (char) tkey;
- if (tkey == EOF) {
- key_mode = KB_STOP;
- scancode = (*hReadEventFptr)(mposp);
- break;
- }
- else if (*p == '}') {
- if (p == name) {
- /* "{}" is quoted '{' */
- scancode = '{';
- }
- else {
- *p = '\0';
- /* look up scancode, test for commands */
- switch (scancode = key_FindVal(name)) {
- case HARD_MEV:
- /* get mouse event information */
- fscanf(keyfile, "(%d,%d,%u)",
- &(mposp->x), &(mposp->y), &(mposp->event));
- break;
-
- case KEY_PAUSE:
- /* pause command (alway pause for fixed amount?) */
- if (key_delay > 0) {
- hard_Pause(key_delay);
- }
- gotkey = 0;
- break;
-
- case KEY_PROMPT:
- /* prompt: wait for a real keystroke */
- /* quit if ESC pressed */
-
- /* clear keyboard buffer first */
- kb_Clear();
- while ((key = (*hReadEventFptr)(mposp)) == HARD_MEV) {
- ;
- }
- if (key == ESC) {
- /* stop playback */
- key_mode = KB_STOP;
- scancode = (*hReadEventFptr)(mposp);
- }
- else {
- gotkey = 0;
- }
- break;
-
- default:
- break;
- }
- }
- break; /* while ((p - name) < 20) */
- }
- p++;
- }
- }
- else {
- scancode = ascii(key);
- }
- }
- /* delay */
- if (key_delay > 0) {
- hard_Pause(key_delay);
- }
- }
- else if (key_mode == KB_RECORD) {
- scancode = (*hReadEventFptr)(mposp);
- if (ascii(scancode) == '{') {
- /* quote '{' character */
- fprintf(keyfile, "{}");
- key_col += 2;
- }
- else if (scancode == GREYPLUS || scancode == GREYMINUS) {
- /* Handle these separately to distinguish from regular + and - */
- fprintf(keyfile, "{%s}", key_FindName(scancode));
- key_col += 8;
- }
- else if (isprint(ascii(scancode))) {
- fprintf(keyfile, "%c", ascii(scancode));
- key_col++;
- }
- else {
- p = key_FindName(scancode);
- /* Skip unnamed keystrokes */
- if (*p != '\0') {
- fprintf(keyfile, "{%s}", p);
- key_col += 7;
- if (scancode == HARD_MEV) {
- /* tack on additional mouse information (x,y,event) */
- fprintf(keyfile, "(%d,%d,%u)", mposp->x, mposp->y, mposp->event);
- key_col += 8;
- }
- }
- }
-
- /* wrap key file for readability */
- if (key_col > KEY_WIDTH) {
- key_col = 0;
- fprintf(keyfile, "\n");
- }
- }
- else {
- /* not recording or playing */
- scancode = (*hReadEventFptr)(mposp);
- }
-
- return(scancode);
- }
- /* -------------------------------------------------------------------------- */
-
- static char *key_FindName(int key)
- /*
- Given a key value, lookup the key's name
- */
- {
- int i;
-
- for (i = 0; kb_keylist[i].scan != 0; i++) {
- if (kb_keylist[i].scan == key) {
- break;
- }
- }
-
- return(kb_keylist[i].name);
- }
- /* -------------------------------------------------------------------------- */
-
- static int key_FindVal(char *name)
- /*
- Given a key name, lookup the key's value
- If name is a command such as PAUSE
- then PAUSE is returned.
- */
- {
- int i;
-
- for (i = 0; kb_keylist[i].scan != 0; i++) {
- if (strcmp(kb_keylist[i].name, name) == 0) {
- break;
- }
- }
-
- return(kb_keylist[i].scan);
- }
-