Newer
Older
Microsoft / screendoor / SD2 / SD2_KEYI.C
@tundra tundra on 24 May 2012 6 KB Initial revision
/*  SD2_KEYIN.C -   ScreenDoor II Keystroke Capture & Mapping Routines
                    This Code Captures A Keystroke And Maps It According
                            To The Global Key Value Maps.

                    Last Modified: 08-02-88
                    Copyright (C) 1988, T.A. Daneliuk


        Input keystrokes are translated two ways.  First, a keystroke is
        checked to see if it might be the beginning of a system specific
        control key sequence.  If so, additional keystrokes are read and
        if a sequence of keystrokes matches one of the entries in
        the control key mapping table (ctrl_xlate), an internal ScreenDoor
        control code is returned.  (This value is found in sd2_ctrl_codes.)
        If after examining CTRL_SIZE number of keystrokes no entry has
        been found in ctrl_xlate, those keystrokes are thrown away.

        If an input is seen as data, it is translated via the key_xlate array.
        This allows one-for-one character mapping.

        The idea behind this is that all of the internal code representations
        and key bindings can be modified at init time via sd2_init().

*/

#include    <stdio.h>
#include    <sd2_defs.h>

#if ANSI
static BOOL match(unsigned x, unsigned y);
#else
static BOOL match();
#endif


/*============ Global Control And Keystroke Translation Tables ===============*/

KEYSTR          sd2_ctrl_codes[C_XLATE];    /* Intialized By sd2_init() !!!   */


#if     PCDOS & PC_BIOS /* Ctrl. Table Must Be Redefined For Each Environment */

struct CXLATE ctrl_xlate[CTRL_ENTRY] =     {2,  0, 80, NXT_FLD, /* Dn. Arrow  */
                                            1,  9,  0, NXT_FLD, /* Tab        */
                                            2,  0, 15, PRV_FLD, /* Back Tab   */
                                            2,  0, 72, PRV_FLD, /* Up Arrow   */
                                            2,  0, 73, FST_FLD, /* PgUp       */
                                            2,  0, 81, LST_FLD, /* PgDn       */
                                            2,  0, 75, CUR_LFT, /* Lft. Arrow */
                                            2,  0, 77, CUR_RGT, /* Rt. Arrow  */
                                            2,  0, 71, BEG_FLD, /* Home       */
                                            2,  0, 79, END_FLD, /* End        */
                                            1, 10,  0, CLR_FLD, /* Ctrl-Enter */
                                            2, 0, 117, CLR_END, /* Ctrl-End   */
                                            1, 13,  0, EXT_FLD, /* Enter      */
                                            2,  0, 82, INS,     /* Ins        */
                                            2,  0, 83, DEL,     /* Del        */
                                            1,  8, 00, BS,      /* Backspace  */
                                            2,  0, 59, HELP,    /* Fn. 1      */
                                            1, 27,  0, EXT_SCR  /* Esc        */
                                           };
#endif

KEYSTR      key_xlate[K_XLATE];             /* Initialized By sd2_init() !!!  */


/*====================== Get And Map Keyboard Input ==========================*/


static  KEYSTR   work[CTRL_SIZE];       /* Working Buffer For Ctrl. Sequences */

static BOOL match();



KEYSTR  sd2_keyin()

{
    BOOL     in_ctrl;                   /* TRUE = Now Parsing Ctrl. String    */
    unsigned first_ctrl;                /* Index Of 1st Possible Ctrl. Match  */
    unsigned index;                     /* Index Into Control String Itself   */
    KEYSTR   key;
    unsigned    x;                      /* Working Variable                   */

    in_ctrl     = FALSE;
    first_ctrl  = 0;
    index       = 1;

    key = sd2_getc();                   /* Get A Character */

    first_ctrl = 0;                     /* See If It Might Be A Ctrl. String  */

    while ((first_ctrl < CTRL_ENTRY) && (in_ctrl == FALSE))
        {
        if ((ctrl_xlate[first_ctrl].length > 0) &&
            (ctrl_xlate[first_ctrl].ctrlin[0] == key))
            {
            in_ctrl = TRUE;             /* 1st Char Matches                   */
            work[0] = key;              /* So Save It                         */
            }
        first_ctrl++;
        }

    if (in_ctrl == FALSE)                   /* Not A Control String           */
        key = key_xlate[(unsigned) key];    /* So Translate The Character     */

    else                                    /* Match/Xlate Control String     */
        {
        first_ctrl--;                       /* Adjust To Point To Real Field  */
        while (in_ctrl == TRUE)             /* Go 'Till Match Or Miss         */
            {
            x = first_ctrl;
            while ((x < CTRL_ENTRY) && (in_ctrl == TRUE))
                {
                if (match(x, index) == TRUE)
                    {
                    in_ctrl = FALSE;
                    key = sd2_ctrl_codes[ctrl_xlate[x].sd_ctrl];
                    }
                x++;                  /* Check From first_ctrl On For Match   */
                }
            if (in_ctrl == TRUE)        /* Still No Match                     */
                {
                if  (index == CTRL_SIZE)    /* Max. Length Input String       */
                    {
                    key = sd2_ctrl_codes[IEBAD_CTRL]; /* Bad Control String   */
                    in_ctrl = FALSE;                /* We're Done             */
                    }
                else
                    {
                    key = sd2_getc();               /* Get Another Keystroke  */
                    work[index] = key;
                    index++;
                    }
                }
            }
        }

    return(key);
}


/*=========See If Control String So Far Matches A Translation Entry ==========*/

static BOOL match(x, y)
unsigned    x, y;

{

    BOOL        flag;
    unsigned    z, len;
    z = 0;
    len = ctrl_xlate[x].length;

    if (y != len)                               /* String Lengths Don't Match */
        flag = FALSE;
    else                                        /* Lengths The Same           */
        {
        while ((work[z] == ctrl_xlate[x].ctrlin[z]) && (z < len))
            z++;
        if (z == len)                           /* All Chars Matched          */
            flag = TRUE;
        else
            flag = FALSE;
        }

    return (flag);

}