home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / STERM.ZIP / STERMK.C < prev    next >
Text File  |  1991-01-14  |  17KB  |  526 lines

  1.   /* STERMK.C
  2.      Process Key Definition File; filling in the
  3.      provided area with an array of pointers to
  4.      strings: (actually replace pointers with
  5.      new pointers.
  6.   */
  7.   #include <stdlib.h>
  8.   #include <stdio.h>
  9.   #include <string.h>
  10.  
  11.   #define  INCL_SUB
  12.   #define  INCL_DOSDEVICES
  13.   #include <os2kernl.h>
  14.   #include <process.h>
  15.  
  16.   #define  STERMK
  17.   #include "sterm.h"
  18.  
  19.  
  20.   #define VTBOT 0x3B     /* bottom of keytrans tbl */
  21.   #define VTTOP 0x92     /* top of keytrans tbl */
  22.  
  23.   typedef struct {
  24.     char  *keyname; /* name of key */
  25.     char   keysc;  /* scan value for x00 or xe0 char */
  26.     } keydef;
  27.  
  28.  
  29.   /* PC keys available to re-map, try and keep the Alts
  30.      for us (xcept function keys */
  31.   static keydef keyn[ ] = {
  32.       { "F1",       '\x3b' },
  33.       { "F2",       '\x3c' },
  34.       { "F3",       '\x3d' },
  35.       { "F4",       '\x3e' },
  36.       { "F5",       '\x3f' },
  37.       { "F6",       '\x40' },
  38.       { "F7",       '\x41' },
  39.       { "F8",       '\x42' },
  40.       { "F9",       '\x43' },
  41.       { "F10",      '\x44' },
  42.       { "F11",      '\x85' },
  43.       { "F12",      '\x86' },
  44.       { "HOME",     '\x47' },
  45.       { "CENTER",   '\x4c' },
  46.       { "UP->",     '\x48' },
  47.       { "PGUP",     '\x49' },
  48.       { "LEFT->",   '\x4b' },
  49.       { "RIGHT->",  '\x4d' },
  50.       { "END",      '\x4f' },
  51.       { "DOWN->",   '\x50' },
  52.       { "PGDN",     '\x51' },
  53.       { "INS",      '\x52' },
  54.       { "DEL",      '\x53' },
  55.       { "S-F1",     '\x54' },
  56.       { "S-F2",     '\x55' },
  57.       { "S-F3",     '\x56' },
  58.       { "S-F4",     '\x57' },
  59.       { "S-F5",     '\x58' },
  60.       { "S-F6",     '\x59' },
  61.       { "S-F7",     '\x5a' },
  62.       { "S-F8",     '\x5b' },
  63.       { "S-F9",     '\x5c' },
  64.       { "S-F10",    '\x5d' },
  65.       { "S-F11",    '\x87' },
  66.       { "S-F12",    '\x88' },
  67.       { "C-F1",     '\x5e' },
  68.       { "C-F2",     '\x5f' },
  69.       { "C-F3",     '\x60' },
  70.       { "C-F4",     '\x61' },
  71.       { "C-F5",     '\x62' },
  72.       { "C-F6",     '\x63' },
  73.       { "C-F7",     '\x64' },
  74.       { "C-F8",     '\x65' },
  75.       { "C-F9",     '\x66' },
  76.       { "C-F10",    '\x67' },
  77.       { "C-F11",    '\x89' },
  78.       { "C-F12",    '\x8a' },
  79.       { "C-HOME",   '\x77' },
  80.       { "C-UP->",   '\x8d' },
  81.       { "C-PGUP",   '\x84' },
  82.       { "C-KMIN",   '\x8e' },
  83.       { "C-LEFT->", '\x73' },
  84.       { "C-CENTER", '\x8f' },
  85.       { "C-RIGHT->",'\x74' },
  86.       { "C-KPLUS",  '\x90' },
  87.       { "C-END",    '\x75' },
  88.       { "C-DOWN->", '\x91' },
  89.       { "C-INS",    '\x92' },
  90.       { "C-PRTSC",  '\x72' },
  91.       { "A-F1",     '\x68' },
  92.       { "A-F2",     '\x69' },
  93.       { "A-F3",     '\x6a' },
  94.       { "A-F4",     '\x6b' },
  95.       { "A-F5",     '\x6c' },
  96.       { "A-F6",     '\x6d' },
  97.       { "A-F7",     '\x6e' },
  98.       { "A-F8",     '\x6f' },
  99.       { "A-F9",     '\x70' },
  100.       { "A-F10",    '\x71' },
  101.       { "A-F11",    '\x8b' },
  102.       { "A-F12",    '\x8c' },
  103.       { "",         '\0' }
  104.  
  105.     };
  106.  
  107. /* search for a PC key and return its scan code */
  108. static UCHAR fpckey( PUCHAR pcn )
  109.    {
  110.    short ix = 0;
  111.  
  112.    while ( ( keyn[ ix ].keysc != '\0' ) &&
  113.          ( strcmp( keyn[ ix ].keyname, pcn ) != 0 ) )
  114.          ix++;
  115.    return( keyn[ ix ].keysc );
  116.    } /* end fpckey */
  117.  
  118. /* table of 3270 functions and their escape sequences */
  119. typedef struct {
  120.    PCHAR  f3270;  /* 3270 key function */
  121.    PCHAR escseq; /* corresponding esc. seq. */
  122.    } ibmkeys;
  123.  
  124. static ibmkeys k3270[] = {
  125.   {  "PF1", "\x1bOP\r" },      /* PF1: ESC, O, P */
  126.   {  "PF2", "\x1bOQ\r" },      /* PF2: ESC, O, Q */
  127.   {  "PF3", "\x1bOR\r" },      /* PF3: ESC, O, R */
  128.   {  "PF4", "\x1bOw\r" },      /* PF4: ESC, O, w */
  129.   {  "PF5", "\x1bOx\r" },      /* PF5: ESC, O, x */
  130.   {  "PF6", "\x1bOy\r" },      /* PF6: ESC, O, y */
  131.   {  "PF7", "\x1bOt\r" },      /* PF7: ESC, O, t */
  132.   {  "PF8", "\x1bOu\r" },      /* PF8: ESC, O, u */
  133.   {  "PF9", "\x1bOv\r" },      /* PF9: ESC, O, v */
  134.   {  "PF10","\x1bOq\r" },      /* PF10:ESC, O, q */
  135.   /* home  */
  136.   {  "HOME",  "\x1b[H\r" },
  137.   {  "UP",    "\x1b[A" },      /* up:  ESC, [, A */
  138.   {  "LEFT",  "\x1b[D" },      /* left: ESC [ D  */
  139.   {  "RIGHT", "\x1b[C" },      /* right:ESC [ C  */
  140.   {  "DOWN",  "\x1b[B" },      /* down: ESC [ B  */
  141.   {  "INS",   "\x01"   },      /* ins: CTLA      */
  142.   {  "DEL",   "\x02"   },      /* del: CTLB      */
  143.   {  "PF11",  "\x1bOr\r" },    /* PF11: ESC,O,r  */
  144.   {  "PF12",  "\x1bOs\r" },    /* PF12: ESC, O, s  */
  145.   {  "PA3",   "\x1bOl\r" },    /* PA3: ESC,O,l  */
  146.   {  "PA1",   "\x1bOS\r" },    /* PA1: ESC, O, S  */
  147.   {  "PA2",   "\x1bOm\r" },    /* PA2: ESC, O, m  */
  148.   {  "EEOF",  "\x1b\x65\r" },    /* eeof:  ESC e   */
  149.   {  "CLEAR", "\x1bOM\r" },    /* clear: ESC, O, M*/
  150.   {  "",      "" }  /* end table */
  151.   };
  152.  
  153. /* search for an 3270 key and return ptr to esc seq. */
  154. static PUCHAR f3270key( PUCHAR ibmk )
  155.    {
  156.    short ix = 0;
  157.  
  158.  
  159.    while ( ( k3270[ ix ].f3270 != '\0' ) &&
  160.          ( strcmp( k3270[ ix ].f3270, ibmk ) != 0 ) )
  161.          ix++;
  162.    return( k3270[ ix ].escseq );
  163.    } /* end f3270key */
  164.  
  165. /* read file with form
  166.    PCKEY = 3270KEY
  167.    input:  pathname of definition file
  168.    output: ptr to constructed trans tbl */
  169. KREF PUCHAR  prockey( PUCHAR kfn )
  170.   {
  171.   FILE *kf;
  172.   #define KLINE 80
  173.   char kstr[KLINE];  /* input statement */
  174.   char *ibmkey,      /* 3270 function name */
  175.        *pckey;       /* PC key name */
  176.   PUCHAR *outtbl;   /* output tbl of ptrs */
  177.   PUCHAR escseq;     /* esc seq ptr from f3270key */
  178.   char sccode;       /* scan code of PC key */
  179.  
  180.   kf = fopen( kfn, "r" );
  181.   if ( !kf )
  182.      errexit( "No Key Definition File");
  183.  
  184.   /* acquire output table */
  185.   outtbl = calloc( (VTTOP-VTBOT+1), sizeof(outtbl) );
  186.  
  187.   pckey = fgets( kstr, KLINE-1, kf );
  188.  
  189.   while ( pckey )
  190.     {
  191.     if ( pckey[0] != '*' ) /* ignore comment */
  192.        {
  193.        pckey = strtok( kstr, " =" );
  194.        pckey = strupr( pckey );
  195.  
  196.        sccode = fpckey( pckey );
  197.        if ( sccode == '\0' )
  198.           errexit( "Requires PC Keyname" );
  199.  
  200.        ibmkey = strtok( NULL, " \n" );
  201.        if ( ibmkey )
  202.           {
  203.           strupr( ibmkey );
  204.           escseq = f3270key( ibmkey );
  205.           if ( escseq == NULL )
  206.              errexit( "Requires 3270 Key" );
  207.           }
  208.        else
  209.           errexit( "Requires 3270 Key" );
  210.  
  211.        /* place the ptr to escape seq. at the key offset in outtbl */
  212.        outtbl[ sccode-VTBOT ] = escseq;
  213.        }
  214.  
  215.     pckey = fgets( kstr, KLINE-1, kf );
  216.     }
  217.  
  218.   return( (PUCHAR) outtbl );
  219.   } /* end prockey */
  220.  
  221.  
  222. /* table of PC function keys with
  223.    extended scan out 00 or e0 between
  224.    0x3B and 0x92, default SimVT mapping */
  225. KREF PUCHAR vtkey[VTTOP-VTBOT+1] =
  226.   {  "\x1bOP\r",      /* 3b F1: ESC, O, P */
  227.      "\x1bOQ\r",      /* 3c F2: ESC, O, Q */
  228.      "\x1bOR\r",      /* 3d F3: ESC, O, R */
  229.      "\x1bOw\r",      /* 3e F4: ESC, O, w */
  230.      "\x1bOx\r",      /* 3f F5: ESC, O, x */
  231.      "\x1bOy\r",      /* 40 F6: ESC, O, y */
  232.      "\x1bOt\r",      /* 41 F7: ESC, O, t */
  233.      "\x1bOu\r",      /* 42 F8: ESC, O, u */
  234.      "\x1bOv\r",      /* 43 F9: ESC, O, v */
  235.      "\x1bOq\r",      /* 44 F10:ESC, O, q */
  236.      "",              /* 45 n/a */
  237.      "",              /* 46 n/a */
  238.      /* home, */
  239.      "\x1b[H\r",
  240.      "\x1b[A",        /* 48 up:  ESC, [, A */
  241.      "\x1bOt\r",      /* 49 pgup = F7      */
  242.      "",              /* 4A n/a */
  243.      "\x1b[D",        /* 4B left: ESC [ D  */
  244.      "",              /* 4C n/a */
  245.      "\x1b[C",        /* 4D right:ESC [ C  */
  246.      "",              /* 4E n/a */
  247.      "\x1bOR\r",      /* 4F end = PF3      */
  248.      "\x1b[B",        /* 50 down: ESC [ B  */
  249.      "\x1bOu\r",      /* 51 pgdown = PF8   */
  250.      "\x01",          /* 52 ins: CTLA      */
  251.      "\x02",          /* 53 del: CTLB      */
  252.      "\x1bOr\r",      /* 54 shift f1 PF11  */
  253.      "\x1bOs\r",      /* 55 shift f2 PF12  */
  254.      "",              /* 56 shift f3       */
  255.      "",              /* 57 shift f4       */
  256.      "",              /* 58 shift f5       */
  257.      "",              /* 59 shift f6       */
  258.      "",              /* 5A shift f7       */
  259.      "",              /* 5B shift f8       */
  260.      "",              /* 5C shift f9       */
  261.      "",              /* 5D shift f10      */
  262.      "",              /* 5E ctl   f1       */
  263.      "",              /* 5F ctl   f2       */
  264.      "\x1bOl\r",      /* 60 ctl   f3  PA3  */
  265.      "",              /* 61 ctl   f4       */
  266.      "\x1bOS\r",      /* 62 ctl   f5  PA1  */
  267.      "\x1bOm\r",      /* 63 ctl   f6  PA2  */
  268.      "",              /* 64 ctl   f7       */
  269.      "",              /* 65 ctl   f8       */
  270.      "",              /* 66 ctl   f9       */
  271.      "",              /* 67 ctl   f10      */
  272.      "",              /* 68 alt   f1       */
  273.      "",              /* 69 alt   f2       */
  274.      "",              /* 6A alt   f3       */
  275.      "",              /* 6B alt   f4       */
  276.      "",              /* 6C alt   f5       */
  277.      "",              /* 6D alt   f6       */
  278.      "",              /* 6E alt   f7       */
  279.      "",              /* 6F alt   f8       */
  280.      "",              /* 70 alt   f9       */
  281.      "",              /* 71 alt   f10      */
  282.      "",              /* 72 n/a            */
  283.      "",              /* 73 ctl left arr   */
  284.      "",              /* 74 ctl righ arr   */
  285.      "\x1b\x65\r",    /* 75 eeof:  ESC e   */
  286.      "",              /* 76 ctl pgdn       */
  287.      "\x1bOM\r",      /* 77 clear: ctl home*/
  288.      "",              /* 78 n/a            */
  289.      "",              /* 79 n/a            */
  290.      "",              /* 7a n/a            */
  291.      "",              /* 7b n/a            */
  292.      "",              /* 7c n/a            */
  293.      "",              /* 7d n/a            */
  294.      "",              /* 7e n/a            */
  295.      "",              /* 7f n/a            */
  296.      "",              /* 80 n/a            */
  297.      "",              /* 81 n/a            */
  298.      "",              /* 82 n/a            */
  299.      "",              /* 83 n/a            */
  300.      "",              /* 84 n/a            */
  301.      "",              /* 85 n/a            */
  302.      "",              /* 86 n/a            */
  303.      "",              /* 87 n/a            */
  304.      "",              /* 88 n/a            */
  305.      "",              /* 89 n/a            */
  306.      "",              /* 8a n/a            */
  307.      "",              /* 8b n/a            */
  308.      "",              /* 8c n/a            */
  309.      "",              /* 8d n/a            */
  310.      "",              /* 8e n/a            */
  311.      "",              /* 8f n/a            */
  312.      "",              /* 90 n/a            */
  313.      "",              /* 91 n/a            */
  314.      ""               /* 92 n/a            */
  315.   };
  316.  
  317.  
  318. /* translate PC key(s) to SIMVT sequence
  319.    returns length of output */
  320. static int vtkeys( PUCHAR *ostr )
  321.    {
  322.    PUCHAR esp;
  323.  
  324.  
  325.    /* return -1 if key invalid, return 0
  326.       if no translation */
  327.  
  328.    /* if tab, translate here */
  329.    if ( keyi.chChar == '\x09' )
  330.       {
  331.       *ostr = "\x1bOn\r"; return( 4 );
  332.       }
  333.  
  334.    /* c-enter is linefeed aka newline,
  335.       SIM3278 screws this one up;
  336.       ship escseq to go to next line */
  337.    if ( keyi.chChar == '\n' )
  338.       {
  339.       return( 0 );  /* do nothing */
  340.       }
  341.  
  342.    if ( ( keyi.chChar != 0 ) && ( keyi.chChar != 0xe0 ) )
  343.       return( 0 );  /* no translation */
  344.  
  345.    /* may be back tab */
  346.    if ( keyi.chScan == '\x0f' )
  347.       {
  348.       *ostr = "\x1bOp\r"; return( 4 );
  349.       }
  350.  
  351.    if ( ( keyi.chScan < VTBOT ) || ( keyi.chScan > VTTOP ) )
  352.       return ( -1 );  /* invalid character */
  353.  
  354.    esp = Sim3270[keyi.chScan-VTBOT];
  355.    if ( ( (long) esp == 0 ) || ( *esp == '\0' ) )
  356.       return( -1 );  /* unsupported key */
  357.    *ostr = esp;
  358.    return( strlen( esp ) );
  359.    } /* end vtkeys */
  360.  
  361.  
  362. /* Read with KeyBoard Functions
  363.    If Alt-X, signal EOJ */
  364.  
  365. void  kbdin(void)
  366.   {
  367.  
  368.   short wlen;  /* actual written length */
  369.   MsgH  kbmsg;
  370.  
  371.   PUCHAR cmdp;       /* ptr in above */
  372.   PUCHAR vtstr = ""; /* translated key string ptr */
  373.   USHORT nsave = 0;
  374.   USHORT cury = 0, curx = 0;
  375.   UCHAR  cmdbuf[WSLEN];
  376.   #define INPLEN (72*2)
  377.   UCHAR  saveline[INPLEN];
  378.  
  379.   /* set binary keyboard mode */
  380.   keyb.cb = 10;
  381.   KbdGetStatus( (PKBDINFO) &keyb, 0 );
  382.   keyb.fsMask &= 0xffe0;  /* insure shift report off */
  383.   keyb.fsMask |= 0x06;  /* no echo, binary */
  384.   KbdSetStatus( (PKBDINFO) &keyb, 0 );
  385.  
  386.   /* init cmdbuf, in case.. */
  387.   cmdp = cmdbuf;
  388.  
  389.   while ( TRUE )
  390.     {
  391.     /* wait on a keypress */
  392.     KbdCharIn( (PKBDKEYINFO) &keyi, IO_WAIT, 0 );
  393.  
  394.  
  395.     /* filter out special 'alt' keys */
  396.     if ( ( keyi.chChar == 0 ) || ( keyi.chChar == 0xe0 ) )
  397.        switch ( keyi.chScan )
  398.          {
  399.          case EXITKEY:
  400.            {
  401.            /* if main in AWAIT, clear that */
  402.            if ( waitlen )
  403.              {  /* wait for ANY */
  404.              waitlen = 0; waitrc = AWAIT_EOJ;
  405.              DosSemClear( (HSEM) &waitsem );
  406.              }
  407.            DosSemClear( (HSEM) &exitsem ); /* signal main thread */
  408.            _dosendthread();
  409.            }   /* alt-x */
  410.  
  411.          case PLEX:
  412.            {   /* toggle local echo */
  413.            CurP->halfplex = ! CurP->halfplex;
  414.            continue;
  415.            }   /* alt-e */
  416.  
  417.          case CLEARKEY:
  418.            if ( keymode == tty )
  419.               {
  420.               clrscrn();
  421.               continue;
  422.               }
  423.            else
  424.               break;
  425.  
  426.          case CMDKEY:
  427.            {  /* toggle command mode */
  428.            if ( keymode == command )
  429.               {
  430.               keymode = prevmode;
  431.               /* restore screen line */
  432.               VioWrtCellStr( saveline, INPLEN, 0, 0, 0 );
  433.               VioSetCurPos( cury, curx, 0 );
  434.               }
  435.            else
  436.               {
  437.               prevmode = keymode; keymode = command;
  438.               cmdp = cmdbuf;
  439.               /* save screen line */
  440.               nsave = INPLEN;
  441.               VioReadCellStr( saveline, (PUSHORT) &nsave,
  442.                  0, 0, 0 );
  443.               VioGetCurPos( (PUSHORT) &cury, (PUSHORT) &curx, 0 );
  444.               VioSetCurPos( 0, 0, 0 );
  445.               VioWrtNChar( " ", INPLEN/2, 0, 0, 0 );
  446.               VioSetCurPos( 0, 0, 0 );
  447.               }
  448.            continue;
  449.            }
  450.          }  /* end switch on scan char */
  451.  
  452.  
  453.     /* if key data not to be transmitted, just loop */
  454.     if ( keymode == ignore )
  455.        continue;
  456.  
  457.     /* if command being read from keyboard */
  458.     if ( keymode == command )
  459.        {
  460.        if ( keyi.chChar == '\r' )
  461.           { /* process command string */
  462.           *cmdp = '\0';
  463.           /* call cmd handler - STERMP */
  464.           verbex( cmdbuf );
  465.           cmdp = cmdbuf;   /* reset ptr */
  466.           VioSetCurPos( 0, 0, 0 );
  467.           VioWrtNChar( " ", INPLEN/2, 0, 0, 0 );
  468.           VioSetCurPos( 0, 0, 0 );
  469.           }
  470.        else
  471.           {
  472.           /* should display char */
  473.           *cmdp = keyi.chChar;
  474.           VioWrtTTY( cmdp, 1, 0 );
  475.           cmdp++;
  476.           }
  477.  
  478.        continue;
  479.        }
  480.  
  481.     /* if we were AWAITing, stop processing script */
  482.     if ( waitlen )
  483.        {  /* wait for ANY */
  484.        waitlen = 0; waitrc = AWAIT_ENDP;
  485.        DosSemClear( (HSEM) &waitsem );
  486.        }
  487.  
  488.     kbmsg.imdat = keyi.chChar; /* prime for normal case */
  489.     kbmsg.mtype = immed;
  490.     kbmsg.mlen = 1;
  491.     kbmsg.doecho = TRUE;
  492.  
  493.  
  494.     /* if terminal emulation, translate PC key to escape seq. */
  495.     if ( keymode == SIMVT )
  496.        { /* translate PC key to string (if required) */
  497.        kbmsg.mlen = vtkeys( &vtstr );
  498.        if ( kbmsg.mlen < 0 )
  499.           { /* send BEL */
  500.           VioWrtTTY( "\a", 1, 0 );
  501.           continue; /* invalid character */
  502.           }
  503.        /* set insert mode on/off for insert key */
  504.        if ( ( kbmsg.mlen == 1 ) && ( vtstr[0] == '\x01' ) )
  505.           {
  506.           kbmsg.doecho = FALSE;  insmode ^= TRUE;
  507.           }
  508.        if ( kbmsg.mlen >= 1 )
  509.           {
  510.           /* put out hdr, then data */
  511.           if ( vtstr[ kbmsg.mlen-1 ] == '\r' )
  512.              kbmsg.doecho = FALSE;  /* suppress echo for immediate actions */
  513.           kbmsg.mtype = dhead;
  514.           DosWrite( comoW, (PVOID) &kbmsg, sizeof(MsgH), (PUSHORT) &wlen );
  515.           DosWrite( comoW, (PVOID) vtstr, kbmsg.mlen, (PUSHORT) &wlen );
  516.           }
  517.        else
  518.           DosWrite( comoW, (PVOID) &kbmsg, sizeof(MsgH), (PUSHORT) &wlen );
  519.        }
  520.     else
  521.        /* send data key to the interested party */
  522.        DosWrite( comoW, (PVOID) &kbmsg, sizeof(MsgH), (PUSHORT) &wlen );
  523.  
  524.     }   /* end of while */
  525.  
  526.    }