home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / tn3270 / ascii / termin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-26  |  6.9 KB  |  282 lines

  1. /*-
  2.  * Copyright (c) 1988 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)termin.c    4.2 (Berkeley) 4/26/91";
  36. #endif /* not lint */
  37.  
  38. /* this takes characters from the keyboard, and produces 3270 keystroke
  39.     codes
  40.  */
  41.  
  42. #include <stdio.h>
  43. #include <ctype.h>
  44.  
  45. #include "../general/general.h"
  46. #include "../ctlr/function.h"
  47. #include "../ctlr/externs.h"
  48. #include "../ctlr/declare.h"
  49.  
  50. #include "../api/astosc.h"
  51. #include "state.h"
  52.  
  53. #include "../general/globals.h"
  54.  
  55. #define IsControl(c)    (!isprint(c) || (isspace(c) && ((c) != ' ')))
  56.  
  57. #define NextState(x)    (x->next)
  58.  
  59. /* XXX temporary - hard code in the state table */
  60.  
  61. #define MATCH_ANY 0xff            /* actually, match any character */
  62.  
  63.  
  64. static unsigned char
  65.     ourBuffer[100],        /* where we store stuff */
  66.     *ourPHead = ourBuffer,    /* first character in buffer */
  67.     *ourPTail = ourBuffer,    /* where next character goes */
  68.     *TransPointer = 0;    /* For transparent mode data */
  69.  
  70. static int InControl;
  71. static int WaitingForSynch;
  72.  
  73. static struct astosc
  74.     *spacePTR = 0;        /* Space is hard to enter */
  75.  
  76. static state
  77.     *headOfControl = 0;    /* where we enter code state table */
  78.  
  79. #define FullChar    ((ourPTail+5) >= ourBuffer+sizeof ourBuffer)
  80. #define EmptyChar    (ourPTail == ourPHead)
  81.  
  82.  
  83. /*
  84.  * init_keyboard()
  85.  *
  86.  * Initialize the keyboard variables.
  87.  */
  88.  
  89. void
  90. init_keyboard()
  91. {
  92.     ourPHead = ourPTail = ourBuffer;
  93.     InControl = 0;
  94.     WaitingForSynch = 0;
  95. }
  96.  
  97.  
  98. /*
  99.  * Initialize the keyboard mapping file.
  100.  */
  101.  
  102. void
  103. InitMapping()
  104. {
  105.     extern state *InitControl();
  106.     register struct astosc *ptr;
  107.  
  108.     if (!headOfControl) {
  109.     /* need to initialize */
  110.     headOfControl = InitControl((char *)0, 0, ascii_to_index);
  111.     if (!headOfControl) {        /* should not occur */
  112.         quit();
  113.     }
  114.     for (ptr = &astosc[0]; ptr <= &astosc[highestof(astosc)]; ptr++) {
  115.         if (ptr->function == FCN_SPACE) {
  116.         spacePTR = ptr;
  117.         }
  118.     }
  119.     }
  120. }
  121.  
  122.  
  123. /* AddChar - put a function index in our buffer */
  124.  
  125. static void
  126. AddChar(c)
  127. int    c;
  128. {
  129.     if (!FullChar) {
  130.     *ourPTail++ = c;
  131.     } else {
  132.     RingBell("Typeahead buffer full");
  133.     }
  134. }
  135.  
  136. /* FlushChar - put everything where it belongs */
  137.  
  138. static void
  139. FlushChar()
  140. {
  141.     ourPTail = ourBuffer;
  142.     ourPHead = ourBuffer;
  143. }
  144.  
  145. /*ARGSUSED*/
  146. void
  147. TransInput(onoff, mode)
  148. int    mode;            /* Which KIND of transparent input */
  149. int    onoff;            /* Going in, or coming out */
  150. {
  151.     if (onoff) {
  152.     /* Flush pending input */
  153.     FlushChar();
  154.     TransPointer = ourBuffer;
  155.     } else {
  156.     }
  157. }
  158.  
  159. int
  160. TerminalIn()
  161. {
  162.     /* send data from us to next link in stream */
  163.     int work = 0;
  164.     register struct astosc *ptr;
  165.  
  166.     while (!EmptyChar) {            /* send up the link */
  167.     if (*ourPHead == ' ') {
  168.         ptr = spacePTR;
  169.     } else {
  170.         ptr = &astosc[*ourPHead];
  171.     }
  172.     if (AcceptKeystroke(ptr->scancode, ptr->shiftstate) == 1) {
  173.         ourPHead++;
  174.         work = 1;
  175.     } else {
  176.         break;
  177.     }
  178.     }
  179.  
  180.     if (EmptyChar) {
  181.     FlushChar();
  182.     }
  183.     /* return value answers question: "did we do anything useful?" */
  184.     return work;
  185. }
  186.  
  187. int
  188. DataFromTerminal(buffer, count)
  189. register char    *buffer;        /* the data read in */
  190. register int    count;            /* how many bytes in this buffer */
  191. {
  192.     register state *regControlPointer;
  193.     register char c;
  194.     register int result;
  195.     int origCount;
  196.     extern int bellwinup;
  197.     static state *controlPointer;
  198.  
  199.     if (TransPointer) {
  200.     int i;
  201.  
  202.     if ((count+TransPointer) >= (ourBuffer+sizeof ourBuffer)) {
  203.         i = ourBuffer+sizeof ourBuffer-TransPointer;
  204.     } else {
  205.         i = count;
  206.     }
  207.     while (i--) {
  208.         c = (*buffer++)&0x7f;
  209.         *TransPointer++ = c|0x80;
  210.         if (c == '\r') {
  211.         SendTransparent((char *)ourBuffer, TransPointer-ourBuffer);
  212.         TransPointer = 0;        /* Done */
  213.         break;
  214.         }
  215.     }
  216.     return count;
  217.     }
  218.  
  219.     if (bellwinup) {
  220.     void BellOff();
  221.  
  222.     BellOff();
  223.     }
  224.  
  225.     origCount = count;
  226.  
  227.     while (count) {
  228.     c = *buffer++&0x7f;
  229.     count--;
  230.  
  231.     if (!InControl && !IsControl(c)) {
  232.         AddChar(c);            /* add ascii character */
  233.     } else {
  234.         if (!InControl) {        /* first character of sequence */
  235.         InControl = 1;
  236.         controlPointer = headOfControl;
  237.         }
  238.         /* control pointer points to current position in state table */
  239.         for (regControlPointer = controlPointer; ;
  240.             regControlPointer = NextState(regControlPointer)) {
  241.         if (!regControlPointer) {    /* ran off end */
  242.             RingBell("Invalid control sequence");
  243.             regControlPointer = headOfControl;
  244.             InControl = 0;
  245.             count = 0;        /* Flush current input */
  246.             break;
  247.         }
  248.         if ((regControlPointer->match == c) /* hit this character */
  249.             || (regControlPointer->match == MATCH_ANY)) {
  250.             result = regControlPointer->result;
  251.             if (result == STATE_GOTO) {
  252.             regControlPointer = regControlPointer->address;
  253.             break;            /* go to next character */
  254.             }
  255.             if (WaitingForSynch) {
  256.             if (astosc[result].function == FCN_SYNCH) {
  257.                 WaitingForSynch = 0;
  258.             } else {
  259.                 void RingBell();
  260.  
  261.                 RingBell("Need to type synch character");
  262.             }
  263.             }
  264.             else if (astosc[result].function == FCN_FLINP) {
  265.             FlushChar();        /* Don't add FLINP */
  266.             } else {
  267.             if (astosc[result].function == FCN_MASTER_RESET) {
  268.                 FlushChar();
  269.             }
  270.             AddChar(result);        /* add this code */
  271.             }
  272.             InControl = 0;    /* out of control now */
  273.             break;
  274.         }
  275.         }
  276.         controlPointer = regControlPointer;        /* save state */
  277.     }
  278.     }
  279.     (void) TerminalIn();            /* try to send data */
  280.     return(origCount-count);
  281. }
  282.