Annotation of 43BSDTahoe/ucb/tn3270/ctlr/inbound.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1988 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that this notice is preserved and that due credit is given
                      7:  * to the University of California at Berkeley. The name of the University
                      8:  * may not be used to endorse or promote products derived from this
                      9:  * software without specific prior written permission. This software
                     10:  * is provided ``as is'' without express or implied warranty.
                     11:  */
                     12: 
                     13: #ifndef lint
                     14: static char sccsid[] = "@(#)inbound.c  3.3 (Berkeley) 3/28/88";
                     15: #endif /* not lint */
                     16: #include <stdio.h>
                     17: 
                     18: #include "../general/general.h"
                     19: #include "function.h"
                     20: #include "hostctlr.h"
                     21: #include "oia.h"
                     22: #include "scrnctlr.h"
                     23: #include "screen.h"
                     24: #include "options.h"
                     25: #include "../api/dctype.h"
                     26: #include "../api/ebc_disp.h"
                     27: 
                     28: #include "../general/globals.h"
                     29: #include "inbound.ext"
                     30: #include "outbound.ext"
                     31: #include "../telnet.ext"
                     32: 
                     33: #define EmptyChar()    (ourPTail == ourPHead)
                     34: #define FullChar()     (ourPHead == ourBuffer+sizeof ourBuffer)
                     35: 
                     36: 
                     37: /*
                     38:  * We define something to allow us to to IsProtected() quickly
                     39:  * on unformatted screens (with the current algorithm for fields,
                     40:  * unprotected takes exponential time...).
                     41:  *
                     42:  *     The idea is to call SetXIsProtected() BEFORE the
                     43:  * loop, then use XIsProtected().
                     44:  */
                     45: 
                     46: #define        SetXIsProtected()       (XWasSF = 1)
                     47: #define        XIsProtected(p) (IsStartField(p)? \
                     48:                            XWasSF = 1 : \
                     49:                            (XWasSF? \
                     50:                                (XWasSF = 0, XProtected = IsProtected(p))  : \
                     51:                                XProtected))
                     52: 
                     53: static char    ourBuffer[400];
                     54: 
                     55: static char    *ourPHead = ourBuffer,
                     56:                *ourPTail = ourBuffer;
                     57: 
                     58: static int     HadAid;                 /* Had an AID haven't sent */
                     59: 
                     60: static int InsertMode;                 /* is the terminal in insert mode? */
                     61: 
                     62: static int rememberedshiftstate;       /* Shift (alt) state of terminal */
                     63: #   define HITNUM(s) ((((s)&(SHIFT_CAPS|SHIFT_UPSHIFT))? 1:0) \
                     64:                        + ((((s)&SHIFT_ALT)? 1:0)<<1))
                     65: 
                     66: static int     XWasSF, XProtected;     /* For optimizations */
                     67: #if    !defined(PURE3274)
                     68: extern int TransparentClock, OutputClock;
                     69: #endif /* !defined(PURE3274) */
                     70: 
                     71: #include "kbd.out"             /* Get keyboard mapping function */
                     72: 
                     73: /* the following are global variables */
                     74: 
                     75: extern int UnLocked;           /* keyboard is UnLocked? */
                     76: 
                     77: 
                     78: /*
                     79:  * init_inbound :
                     80:  *
                     81:  * Reset variables to initial state.
                     82:  */
                     83: 
                     84: void
                     85: init_inbound()
                     86: {
                     87:     ourPHead = ourPTail = ourBuffer;
                     88:     HadAid = 0;
                     89:     rememberedshiftstate = 0;
                     90:     InsertMode = 0;
                     91: }
                     92: 
                     93: 
                     94: /* Tab() - sets cursor to the start of the next unprotected field */
                     95: static void
                     96: Tab()
                     97: {
                     98:     register int i, j;
                     99: 
                    100:     i = CursorAddress;
                    101:     j = WhereAttrByte(CursorAddress);
                    102:     do {
                    103:        if (IsStartField(i) && IsUnProtected(ScreenInc(i))) {
                    104:            break;
                    105:        }
                    106:        i = FieldInc(i);
                    107:     } while (i != j);
                    108:     if (IsStartField(i) && IsUnProtected(ScreenInc(i))) {
                    109:        CursorAddress = ScreenInc(i);
                    110:     } else {
                    111:        CursorAddress = SetBufferAddress(0,0);
                    112:     }
                    113: }
                    114: 
                    115: 
                    116: /* BackTab() - sets cursor to the start of the most recent field */
                    117: 
                    118: static void
                    119: BackTab()
                    120: {
                    121:     register int i;
                    122: 
                    123:     i = ScreenDec(CursorAddress);
                    124:     for (;;) {
                    125:        if (IsStartField(ScreenDec(i)) && IsUnProtected(i)) {
                    126:            CursorAddress = i;
                    127:            break;
                    128:        }
                    129:        if (i == CursorAddress) {
                    130:            CursorAddress = SetBufferAddress(0,0);
                    131:            break;
                    132:        }
                    133:        i = ScreenDec(i);
                    134:     }
                    135: }
                    136: 
                    137: /*
                    138:  * ModifyMdt() - Turn a modified data tag bit on or off (watch
                    139:  * out for unformatted screens).
                    140:  */
                    141: 
                    142: ModifyMdt(x,on)
                    143: int x;
                    144: int on;
                    145: {
                    146:     int i = x;
                    147: 
                    148:     if (IsStartField(i)) {     /* If we are at a start field position... */
                    149:        if (on) {
                    150:            ModifyHost(i, |= ATTR_MDT);         /* Turn it on */
                    151:        } else {
                    152:            ModifyHost(i, &= ~ATTR_MDT);        /* Turn it off */
                    153:        }
                    154:     } else {
                    155:        i = WhereAttrByte(i);   /* Find beginning of field */
                    156:        if (IsStartField(i)) {  /* Is there one? */
                    157:            if (on) {
                    158:                ModifyHost(i, |= ATTR_MDT);     /* Turn it on */
                    159:            } else {
                    160:                ModifyHost(i, &= ~ATTR_MDT);    /* Turn it off */
                    161:            }
                    162:        } /* else, don't modify - this is an unformatted screen */
                    163:     }
                    164: }
                    165: 
                    166: 
                    167: /* EraseEndOfField - erase all characters to the end of a field */
                    168: 
                    169: static void
                    170: EraseEndOfField()
                    171: {
                    172:     register int i;
                    173: 
                    174:     if (IsProtected(CursorAddress)) {
                    175:        RingBell("Protected Field");
                    176:     } else {
                    177:        TurnOnMdt(CursorAddress);
                    178:        if (FormattedScreen()) {
                    179:            i = CursorAddress;
                    180:            do {
                    181:                AddHost(i, 0);
                    182:                i = ScreenInc(i);
                    183:            } while ((i != CursorAddress) && !IsStartField(i));
                    184:        } else {                            /* Screen is Unformatted */
                    185:            i = CursorAddress;
                    186:            do {
                    187:                AddHost(i, 0);
                    188:                i = ScreenInc(i);
                    189:            } while (i != HighestScreen());
                    190:        } 
                    191:     }
                    192: }
                    193: 
                    194: /* Delete() - deletes a character from the screen
                    195:  *
                    196:  *     What we want to do is delete the section
                    197:  *     [where, from-1] from the screen,
                    198:  *     filling in with what comes at from.
                    199:  *
                    200:  *     The deleting continues to the end of the field (or
                    201:  *     until the cursor wraps).
                    202:  *
                    203:  *     From can be a start of a field.  We
                    204:  *     check for that.  However, there can't be any
                    205:  *     fields that start between where and from.
                    206:  *     We don't check for that.
                    207:  *
                    208:  *     Also, we assume that the protection status of
                    209:  *     everything has been checked by the caller.
                    210:  *
                    211:  */
                    212: 
                    213: static void
                    214: Delete(where, from)
                    215: register int   where,          /* Where to start deleting from */
                    216:                from;           /* Where to pull back from */
                    217: {
                    218:     register int i;
                    219: 
                    220:     TurnOnMdt(where);                  /* Only do this once in this field */
                    221:     i = where;
                    222:     do {
                    223:        if (IsStartField(from)) {
                    224:            AddHost(i, 0);              /* Stick the edge at the start field */
                    225:        } else {
                    226:            AddHost(i, GetHost(from));
                    227:            from = ScreenInc(from);             /* Move the edge */
                    228:        }
                    229:        i = ScreenInc(i);
                    230:     } while ((!IsStartField(i)) && (i != where));
                    231: }
                    232: 
                    233: static void
                    234: ColBak()
                    235: {
                    236:     register int i;
                    237: 
                    238:     i = ScreenLineOffset(CursorAddress);
                    239:     for (i = i-1; i >= 0; i--) {
                    240:        if (OptColTabs[i]) {
                    241:            break;
                    242:        }
                    243:     }
                    244:     if (i < 0) {
                    245:        i = 0;
                    246:     }
                    247:     CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i);
                    248: }
                    249: 
                    250: static void
                    251: ColTab()
                    252: {
                    253:     register int i;
                    254: 
                    255:     i = ScreenLineOffset(CursorAddress);
                    256:     for (i = i+1; i < NumberColumns; i++) {
                    257:        if (OptColTabs[i]) {
                    258:            break;
                    259:        }
                    260:     }
                    261:     if (i >= NumberColumns) {
                    262:        i = NumberColumns-1;
                    263:     }
                    264:     CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i);
                    265: }
                    266: 
                    267: static void
                    268: Home()
                    269: {
                    270:     register int i;
                    271:     register int j;
                    272: 
                    273:     i = SetBufferAddress(OptHome, 0);
                    274:     j = WhereLowByte(i);
                    275:     do {
                    276:        if (IsUnProtected(i)) {
                    277:            CursorAddress = i;
                    278:            return;
                    279:        }
                    280:            /* the following could be a problem if we got here with an
                    281:             * unformatted screen.  However, this is "impossible", since
                    282:             * with an unformatted screen, the IsUnProtected(i) above
                    283:             * should be true.
                    284:             */
                    285:        i = ScreenInc(FieldInc(i));
                    286:     } while (i != j);
                    287:     CursorAddress = LowestScreen();
                    288: }
                    289: 
                    290: static
                    291: LastOfField(i)
                    292: register int   i;      /* position to start from */
                    293: {
                    294:     register int j;
                    295:     register int k;
                    296: 
                    297:     k = j = i;
                    298:     SetXIsProtected();
                    299:     while (XIsProtected(i) || Disspace(GetHost(i))) {
                    300:        i = ScreenInc(i);
                    301:        if (i == j) {
                    302:            break;
                    303:        }
                    304:     }
                    305:            /* We are now IN a word IN an unprotected field (or wrapped) */
                    306:     while (!XIsProtected(i)) {
                    307:        if (!Disspace(GetHost(i))) {
                    308:            k = i;
                    309:        }
                    310:        i = ScreenInc(i);
                    311:        if (i == j) {
                    312:            break;
                    313:        }
                    314:     }
                    315:     return(k);
                    316: }
                    317: 
                    318: 
                    319: static void
                    320: FlushChar()
                    321: {
                    322:     ourPTail = ourPHead = ourBuffer;
                    323: }
                    324: 
                    325: 
                    326: /*
                    327:  * Add one EBCDIC (NOT display code) character to the buffer.
                    328:  */
                    329: 
                    330: static void
                    331: AddChar(character)
                    332: char   character;
                    333: {
                    334:     if (FullChar()) {
                    335:        ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 0);
                    336:        if (EmptyChar()) {
                    337:            FlushChar();
                    338:        } else {
                    339:            char buffer[100];
                    340: 
                    341:            sprintf(buffer, "File %s, line %d:  No room in network buffer!\n",
                    342:                                __FILE__, __LINE__);
                    343:            ExitString(stderr, buffer, 1);
                    344:            /*NOTREACHED*/
                    345:        }
                    346:     }
                    347:     *ourPHead++ = character;
                    348: }
                    349: 
                    350: 
                    351: static void
                    352: SendUnformatted()
                    353: {
                    354:     register int i, j;
                    355:     register int Nulls;
                    356:     register int c;
                    357: 
                    358:                        /* look for start of field */
                    359:     Nulls = 0;
                    360:     i = j = LowestScreen();
                    361:     do {
                    362:        c = GetHost(i);
                    363:        if (c == 0) {
                    364:            Nulls++;
                    365:        } else {
                    366:            while (Nulls) {
                    367:                Nulls--;
                    368:                AddChar(EBCDIC_BLANK);          /* put in blanks */
                    369:            }
                    370:            AddChar(disp_ebc[c]);
                    371:        }
                    372:        i = ScreenInc(i);
                    373:     } while (i != j);
                    374: }
                    375: 
                    376: static
                    377: SendField(i, command)
                    378: register int i;                        /* where we saw MDT bit */
                    379: int    command;                /* The command code (type of read) */
                    380: {
                    381:     register int j;
                    382:     register int k;
                    383:     register int Nulls;
                    384:     register int c;
                    385: 
                    386:                        /* look for start of field */
                    387:     i = j = WhereLowByte(i);
                    388: 
                    389:                /* On a test_request_read, don't send sba and address */
                    390:     if ((AidByte != AID_TREQ)
                    391:                        || (command == CMD_SNA_READ_MODIFIED_ALL)) {
                    392:        AddChar(ORDER_SBA);             /* set start field */
                    393:        AddChar(BufferTo3270_0(j));     /* set address of this field */
                    394:        AddChar(BufferTo3270_1(j));
                    395:     }
                    396:                /*
                    397:                 * Only on read_modified_all do we return the contents
                    398:                 * of the field when the attention was caused by a
                    399:                 * selector pen.
                    400:                 */
                    401:     if ((AidByte != AID_SELPEN)
                    402:                        || (command == CMD_SNA_READ_MODIFIED_ALL)) {
                    403:        if (!IsStartField(j)) {
                    404:            Nulls = 0;
                    405:            k = ScreenInc(WhereHighByte(j));
                    406:            do {
                    407:                c = GetHost(j);
                    408:                if (c == 0) {
                    409:                    Nulls++;
                    410:                } else {
                    411:                    while (Nulls) {
                    412:                        Nulls--;
                    413:                        AddChar(EBCDIC_BLANK);          /* put in blanks */
                    414:                    }
                    415:                    AddChar(disp_ebc[c]);
                    416:                }
                    417:                j = ScreenInc(j);
                    418:            } while ((j != k) && (j != i));
                    419:        }
                    420:     } else {
                    421:        j = FieldInc(j);
                    422:     }
                    423:     return(j);
                    424: }
                    425: 
                    426: /* Various types of reads... */
                    427: void
                    428: DoReadModified(command)
                    429: int    command;                        /* The command sent */
                    430: {
                    431:     register int i, j;
                    432: 
                    433:     if (AidByte) {
                    434:        if (AidByte != AID_TREQ) {
                    435:            AddChar(AidByte);
                    436:        } else {
                    437:                /* Test Request Read header */
                    438:            AddChar(EBCDIC_SOH);
                    439:            AddChar(EBCDIC_PERCENT);
                    440:            AddChar(EBCDIC_SLASH);
                    441:            AddChar(EBCDIC_STX);
                    442:        }
                    443:     } else {
                    444:        AddChar(AID_NONE);
                    445:     }
                    446:     if (((AidByte != AID_PA1) && (AidByte != AID_PA2)
                    447:            && (AidByte != AID_PA3) && (AidByte != AID_CLEAR))
                    448:            || (command == CMD_SNA_READ_MODIFIED_ALL)) {
                    449:        if ((AidByte != AID_TREQ)
                    450:            || (command == CMD_SNA_READ_MODIFIED_ALL)) {
                    451:                /* Test request read_modified doesn't give cursor address */
                    452:            AddChar(BufferTo3270_0(CursorAddress));
                    453:            AddChar(BufferTo3270_1(CursorAddress));
                    454:        }
                    455:        i = j = WhereAttrByte(LowestScreen());
                    456:        /* Is this an unformatted screen? */
                    457:        if (!IsStartField(i)) {         /* yes, handle separate */
                    458:            SendUnformatted();
                    459:        } else {
                    460:            do {
                    461:                if (HasMdt(i)) {
                    462:                    i = SendField(i, command);
                    463:                } else {
                    464:                    i = FieldInc(i);
                    465:                }
                    466:            } while (i != j);
                    467:        }
                    468:     }
                    469:     ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1);
                    470:     if (EmptyChar()) {
                    471:        FlushChar();
                    472:        HadAid = 0;                     /* killed that buffer */
                    473:     }
                    474: }
                    475: 
                    476: /* A read buffer operation... */
                    477: 
                    478: void
                    479: DoReadBuffer()
                    480: {
                    481:     register int i, j;
                    482: 
                    483:     if (AidByte) {
                    484:        AddChar(AidByte);
                    485:     } else {
                    486:        AddChar(AID_NONE);
                    487:     }
                    488:     AddChar(BufferTo3270_0(CursorAddress));
                    489:     AddChar(BufferTo3270_1(CursorAddress));
                    490:     i = j = LowestScreen();
                    491:     do {
                    492:        if (IsStartField(i)) {
                    493:            AddChar(ORDER_SF);
                    494:            AddChar(BufferTo3270_1(FieldAttributes(i)));
                    495:        } else {
                    496:            AddChar(disp_ebc[GetHost(i)]);
                    497:        }
                    498:        i = ScreenInc(i);
                    499:     } while (i != j);
                    500:     ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1);
                    501:     if (EmptyChar()) {
                    502:        FlushChar();
                    503:        HadAid = 0;                     /* killed that buffer */
                    504:     }
                    505: }
                    506: 
                    507: /* Send some transparent data to the host */
                    508: 
                    509: void
                    510: SendTransparent(buffer, count)
                    511: char *buffer;
                    512: int count;
                    513: {
                    514:     char stuff[3];
                    515: 
                    516:     stuff[0] = AID_NONE_PRINTER;
                    517:     stuff[1] = BufferTo3270_0(count);
                    518:     stuff[2] = BufferTo3270_1(count);
                    519:     DataToNetwork(stuff, sizeof stuff, 0);
                    520:     DataToNetwork(buffer, count, 1);
                    521: }
                    522: 
                    523: 
                    524: /* Try to send some data to host */
                    525: 
                    526: void
                    527: SendToIBM()
                    528: {
                    529: #if    !defined(PURE3274)
                    530:     if (TransparentClock >= OutputClock) {
                    531:        if (HadAid) {
                    532:            AddChar(AidByte);
                    533:            HadAid = 0;
                    534:        } else {
                    535:            AddChar(AID_NONE_PRINTER);
                    536:        }
                    537:        do {
                    538:            ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1);
                    539:        } while (!EmptyChar());
                    540:        FlushChar();
                    541:     } else if (HadAid) {
                    542:        DoReadModified(CMD_READ_MODIFIED);
                    543:     }
                    544: #else  /* !defined(PURE3274) */
                    545:     if (HadAid) {
                    546:        DoReadModified(CMD_READ_MODIFIED);
                    547:     }
                    548: #endif /* !defined(PURE3274) */
                    549: }
                    550: 
                    551: /* This takes in one character from the keyboard and places it on the
                    552:  * screen.
                    553:  */
                    554: 
                    555: static void
                    556: OneCharacter(c, insert)
                    557: int c;                 /* character (Ebcdic) to be shoved in */
                    558: int insert;            /* are we in insert mode? */
                    559: {
                    560:     register int i, j;
                    561: 
                    562:     if (IsProtected(CursorAddress)) {
                    563:        RingBell("Protected Field");
                    564:        return;
                    565:     }
                    566:     if (insert) {
                    567:        /* is the last character in the field a blank or null? */
                    568:        i = ScreenDec(FieldInc(CursorAddress));
                    569:        j = GetHost(i);
                    570:        if (!Disspace(j)) {
                    571:            RingBell("No more room for insert");
                    572:            return;
                    573:        } else {
                    574:            for (j = ScreenDec(i); i != CursorAddress;
                    575:                            j = ScreenDec(j), i = ScreenDec(i)) {
                    576:                AddHost(i, GetHost(j));
                    577:            }
                    578:        }
                    579:     }
                    580:     AddHost(CursorAddress, c);
                    581:     TurnOnMdt(CursorAddress);
                    582:     CursorAddress = ScreenInc(CursorAddress);
                    583:     if (IsStartField(CursorAddress) &&
                    584:                ((FieldAttributes(CursorAddress)&ATTR_AUTO_SKIP_MASK) ==
                    585:                                                        ATTR_AUTO_SKIP_VALUE)) {
                    586:        Tab();
                    587:     }
                    588: }
                    589: 
                    590: /*
                    591:  * AcceptKeystroke()
                    592:  *
                    593:  * Processes one keystroke.
                    594:  *
                    595:  * Returns:
                    596:  *
                    597:  *     0       if this keystroke was NOT processed.
                    598:  *     1       if everything went OK.
                    599:  */
                    600: 
                    601: int
                    602: AcceptKeystroke(scancode, shiftstate)
                    603: int
                    604:     scancode,                  /* 3270 scancode */
                    605:     shiftstate;                        /* The shift state */
                    606: {
                    607:     register int c;
                    608:     register int i;
                    609:     register int j;
                    610:     enum ctlrfcn ctlrfcn;
                    611: 
                    612:     if (scancode >= numberof(hits)) {
                    613:        ExitString(stderr,
                    614:                "Unknown scancode encountered in AcceptKeystroke.\n", 1);
                    615:        /*NOTREACHED*/
                    616:     }
                    617:     ctlrfcn = hits[scancode].hit[HITNUM(shiftstate)].ctlrfcn;
                    618:     c = hits[scancode].hit[HITNUM(shiftstate)].code;
                    619: 
                    620:     if (!UnLocked || HadAid) {
                    621:        if (HadAid) {
                    622:            SendToIBM();
                    623:            if (!EmptyChar()) {
                    624:                return 0;                       /* nothing to do */
                    625:            }
                    626:        }
                    627: #if    !defined(PURE3274)
                    628:        if (!HadAid && EmptyChar()) {
                    629:            if ((ctlrfcn == FCN_RESET) || (ctlrfcn == FCN_MASTER_RESET)) {
                    630:                UnLocked = 1;
                    631:            }
                    632:        }
                    633: #endif /* !defined(PURE3274) */
                    634:        if (!UnLocked) {
                    635:            return 0;
                    636:        }
                    637:     }
                    638: 
                    639:     /* now, either empty, or haven't seen aid yet */
                    640: 
                    641: #if    !defined(PURE3274)
                    642:     /*
                    643:      * If we are in transparent (output) mode, do something special
                    644:      * with keystrokes.
                    645:      */
                    646:     if (TransparentClock == OutputClock) {
                    647:        if (ctlrfcn == FCN_AID) {
                    648:            UnLocked = 0;
                    649:            InsertMode = 0;
                    650:            AidByte = (c);
                    651:            HadAid = 1;
                    652:        } else {
                    653:            switch (ctlrfcn) {
                    654:            case FCN_ESCAPE:
                    655:                StopScreen(1);
                    656:                command(0);
                    657:                if (shell_active == 0) {
                    658:                    ConnectScreen();
                    659:                }
                    660:                break;
                    661: 
                    662:            case FCN_RESET:
                    663:            case FCN_MASTER_RESET:
                    664:                UnLocked = 1;
                    665:                break;
                    666: 
                    667:            default:
                    668:                return 0;
                    669:            }
                    670:        }
                    671:     }
                    672: #endif /* !defined(PURE3274) */
                    673: 
                    674:     if (ctlrfcn == FCN_CHARACTER) {
                    675:                    /* Add the character to the buffer */
                    676:        OneCharacter(c, InsertMode);
                    677:     } else if (ctlrfcn == FCN_AID) {           /* got Aid */
                    678:        if (c == AID_CLEAR) {
                    679:            LocalClearScreen(); /* Side effect is to clear 3270 */
                    680:        }
                    681:        ResetOiaOnlineA(&OperatorInformationArea);
                    682:        SetOiaTWait(&OperatorInformationArea);
                    683:        ResetOiaInsert(&OperatorInformationArea);
                    684:        InsertMode = 0;         /* just like a 3278 */
                    685:        SetOiaSystemLocked(&OperatorInformationArea);
                    686:        SetOiaModified();
                    687:        UnLocked = 0;
                    688:        AidByte = c;
                    689:        HadAid = 1;
                    690:        SendToIBM();
                    691:     } else {
                    692:        switch (ctlrfcn) {
                    693: 
                    694:        case FCN_CURSEL:
                    695:            c = FieldAttributes(CursorAddress)&ATTR_DSPD_MASK;
                    696:            if (!FormattedScreen()
                    697:                    || ((c != ATTR_DSPD_DSPD) && (c != ATTR_DSPD_HIGH))) {
                    698:                RingBell("Cursor not in selectable field");
                    699:            } else {
                    700:                i = ScreenInc(WhereAttrByte(CursorAddress));
                    701:                c = GetHost(i);
                    702:                if (c == DISP_QUESTION) {
                    703:                    AddHost(i, DISP_GREATER_THAN);
                    704:                    TurnOnMdt(i);
                    705:                } else if (c == DISP_GREATER_THAN) {
                    706:                    AddHost(i, DISP_QUESTION);
                    707:                    TurnOffMdt(i);
                    708:                } else if (c == DISP_BLANK || c == DISP_NULL
                    709:                                            || c == DISP_AMPERSAND) {
                    710:                    UnLocked = 0;
                    711:                    InsertMode = 0;
                    712:                    ResetOiaOnlineA(&OperatorInformationArea);
                    713:                    SetOiaTWait(&OperatorInformationArea);
                    714:                    SetOiaSystemLocked(&OperatorInformationArea);
                    715:                    ResetOiaInsert(&OperatorInformationArea);
                    716:                    SetOiaModified();
                    717:                    if (c == DISP_AMPERSAND) {
                    718:                        TurnOnMdt(i);   /* Only for & type */
                    719:                        AidByte = AID_ENTER;
                    720:                    } else {
                    721:                        AidByte = AID_SELPEN;
                    722:                    }
                    723:                    HadAid = 1;
                    724:                    SendToIBM();
                    725:                } else {
                    726:                    RingBell(
                    727:                        "Cursor not in a selectable field (designator)");
                    728:                }
                    729:            }
                    730:            break;
                    731: 
                    732: #if    !defined(PURE3274)
                    733:        case FCN_ERASE:
                    734:            if (IsProtected(ScreenDec(CursorAddress))) {
                    735:                RingBell("Protected Field");
                    736:            } else {
                    737:                CursorAddress = ScreenDec(CursorAddress);
                    738:                Delete(CursorAddress, ScreenInc(CursorAddress));
                    739:            }
                    740:            break;
                    741:        case FCN_WERASE:
                    742:            j = CursorAddress;
                    743:            i = ScreenDec(j);
                    744:            if (IsProtected(i)) {
                    745:                RingBell("Protected Field");
                    746:            } else {
                    747:                SetXIsProtected();
                    748:                while ((!XIsProtected(i) && Disspace(GetHost(i)))
                    749:                                                    && (i != j)) {
                    750:                    i = ScreenDec(i);
                    751:                }
                    752:                /* we are pointing at a character in a word, or
                    753:                 * at a protected position
                    754:                 */
                    755:                while ((!XIsProtected(i) && !Disspace(GetHost(i)))
                    756:                                                    && (i != j)) {
                    757:                    i = ScreenDec(i);
                    758:                }
                    759:                /* we are pointing at a space, or at a protected
                    760:                 * position
                    761:                 */
                    762:                CursorAddress = ScreenInc(i);
                    763:                Delete(CursorAddress, j);
                    764:            }
                    765:            break;
                    766: 
                    767:        case FCN_FERASE:
                    768:            if (IsProtected(CursorAddress)) {
                    769:                RingBell("Protected Field");
                    770:            } else {
                    771:                CursorAddress = ScreenInc(CursorAddress);       /* for btab */
                    772:                BackTab();
                    773:                EraseEndOfField();
                    774:            }
                    775:            break;
                    776: 
                    777:        case FCN_RESET:
                    778:            if (InsertMode) {
                    779:                InsertMode = 0;
                    780:                ResetOiaInsert(&OperatorInformationArea);
                    781:                SetOiaModified();
                    782:            }
                    783:            break;
                    784:        case FCN_MASTER_RESET:
                    785:            if (InsertMode) {
                    786:                InsertMode = 0;
                    787:                ResetOiaInsert(&OperatorInformationArea);
                    788:                SetOiaModified();
                    789:            }
                    790:            RefreshScreen();
                    791:            break;
                    792: #endif /* !defined(PURE3274) */
                    793: 
                    794:        case FCN_UP:
                    795:            CursorAddress = ScreenUp(CursorAddress);
                    796:            break;
                    797: 
                    798:        case FCN_LEFT:
                    799:            CursorAddress = ScreenDec(CursorAddress);
                    800:            break;
                    801: 
                    802:        case FCN_RIGHT:
                    803:            CursorAddress = ScreenInc(CursorAddress);
                    804:            break;
                    805: 
                    806:        case FCN_DOWN:
                    807:            CursorAddress = ScreenDown(CursorAddress);
                    808:            break;
                    809: 
                    810:        case FCN_DELETE:
                    811:            if (IsProtected(CursorAddress)) {
                    812:                RingBell("Protected Field");
                    813:            } else {
                    814:                Delete(CursorAddress, ScreenInc(CursorAddress));
                    815:            }
                    816:            break;
                    817: 
                    818:        case FCN_INSRT:
                    819:            InsertMode = !InsertMode;
                    820:            if (InsertMode) {
                    821:                SetOiaInsert(&OperatorInformationArea);
                    822:            } else {
                    823:                ResetOiaInsert(&OperatorInformationArea);
                    824:            }
                    825:            SetOiaModified();
                    826:            break;
                    827: 
                    828:        case FCN_HOME:
                    829:            Home();
                    830:            break;
                    831: 
                    832:        case FCN_NL:
                    833:            /* The algorithm is to look for the first unprotected
                    834:             * column after column 0 of the following line.  Having
                    835:             * found that unprotected column, we check whether the
                    836:             * cursor-address-at-entry is at or to the right of the
                    837:             * LeftMargin AND the LeftMargin column of the found line
                    838:             * is unprotected.  If this conjunction is true, then
                    839:             * we set the found pointer to the address of the LeftMargin
                    840:             * column in the found line.
                    841:             * Then, we set the cursor address to the found address.
                    842:             */
                    843:            i = SetBufferAddress(ScreenLine(ScreenDown(CursorAddress)), 0);
                    844:            j = ScreenInc(WhereAttrByte(CursorAddress));
                    845:            do {
                    846:                if (IsUnProtected(i)) {
                    847:                    break;
                    848:                }
                    849:                /* Again (see comment in Home()), this COULD be a problem
                    850:                 * with an unformatted screen.
                    851:                 */
                    852:                /* If there was a field with only an attribute byte,
                    853:                 * we may be pointing to the attribute byte of the NEXT
                    854:                 * field, so just look at the next byte.
                    855:                 */
                    856:                if (IsStartField(i)) {
                    857:                    i = ScreenInc(i);
                    858:                } else {
                    859:                    i = ScreenInc(FieldInc(i));
                    860:                }
                    861:            } while (i != j);
                    862:            if (!IsUnProtected(i)) {    /* couldn't find unprotected */
                    863:                i = SetBufferAddress(0,0);
                    864:            }
                    865:            if (OptLeftMargin <= ScreenLineOffset(CursorAddress)) {
                    866:                if (IsUnProtected(SetBufferAddress(ScreenLine(i),
                    867:                                                        OptLeftMargin))) {
                    868:                    i = SetBufferAddress(ScreenLine(i), OptLeftMargin);
                    869:                }
                    870:            }
                    871:            CursorAddress = i;
                    872:            break;
                    873: 
                    874:        case FCN_EINP:
                    875:            if (!FormattedScreen()) {
                    876:                i = CursorAddress;
                    877:                TurnOffMdt(i);
                    878:                do {
                    879:                    AddHost(i, 0);
                    880:                    i = ScreenInc(i);
                    881:                } while (i != CursorAddress);
                    882:            } else {
                    883:                    /*
                    884:                     * The algorithm is:  go through each unprotected
                    885:                     * field on the screen, clearing it out.  When
                    886:                     * we are at the start of a field, skip that field
                    887:                     * if its contents are protected.
                    888:                     */
                    889:                i = j = FieldInc(CursorAddress);
                    890:                do {
                    891:                    if (IsUnProtected(ScreenInc(i))) {
                    892:                        i = ScreenInc(i);
                    893:                        TurnOffMdt(i);
                    894:                        do {
                    895:                           AddHost(i, 0);
                    896:                           i = ScreenInc(i);
                    897:                        } while (!IsStartField(i));
                    898:                    } else {
                    899:                        i = FieldInc(i);
                    900:                    }
                    901:                } while (i != j);
                    902:            }
                    903:            Home();
                    904:            break;
                    905: 
                    906:        case FCN_EEOF:
                    907:            EraseEndOfField();
                    908:            break;
                    909: 
                    910:        case FCN_SPACE:
                    911:            OneCharacter(DISP_BLANK, InsertMode);  /* Add cent */
                    912:            break;
                    913: 
                    914:        case FCN_CENTSIGN:
                    915:            OneCharacter(DISP_CENTSIGN, InsertMode);  /* Add cent */
                    916:            break;
                    917: 
                    918:        case FCN_FM:
                    919:            OneCharacter(DISP_FM, InsertMode);  /* Add field mark */
                    920:            break;
                    921: 
                    922:        case FCN_DP:
                    923:            if (IsProtected(CursorAddress)) {
                    924:                RingBell("Protected Field");
                    925:            } else {
                    926:                OneCharacter(DISP_DUP, InsertMode);/* Add dup character */
                    927:                Tab();
                    928:            }
                    929:            break;
                    930: 
                    931:        case FCN_TAB:
                    932:            Tab();
                    933:            break;
                    934: 
                    935:        case FCN_BTAB:
                    936:            BackTab();
                    937:            break;
                    938: 
                    939: #ifdef NOTUSED                 /* Actually, this is superseded by unix flow
                    940:                             * control.
                    941:                             */
                    942:        case FCN_XOFF:
                    943:            Flow = 0;                   /* stop output */
                    944:            break;
                    945: 
                    946:        case FCN_XON:
                    947:            if (!Flow) {
                    948:                Flow = 1;                       /* turn it back on */
                    949:                DoTerminalOutput();
                    950:            }
                    951:            break;
                    952: #endif /* NOTUSED */
                    953: 
                    954: #if    !defined(PURE3274)
                    955:        case FCN_ESCAPE:
                    956:            /* FlushChar(); do we want to flush characters from before? */
                    957:            StopScreen(1);
                    958:            command(0);
                    959:            if (shell_active == 0) {
                    960:                ConnectScreen();
                    961:            }
                    962:            break;
                    963: 
                    964:        case FCN_DISC:
                    965:            StopScreen(1);
                    966:            suspend();
                    967:            setconnmode();
                    968:            ConnectScreen();
                    969:            break;
                    970: 
                    971:        case FCN_RESHOW:
                    972:            RefreshScreen();
                    973:            break;
                    974: 
                    975:        case FCN_SETTAB:
                    976:            OptColTabs[ScreenLineOffset(CursorAddress)] = 1;
                    977:            break;
                    978: 
                    979:        case FCN_DELTAB:
                    980:            OptColTabs[ScreenLineOffset(CursorAddress)] = 0;
                    981:            break;
                    982: 
                    983:            /*
                    984:             * Clear all tabs, home line, and left margin.
                    985:             */
                    986:        case FCN_CLRTAB:
                    987:            for (i = 0; i < sizeof OptColTabs; i++) {
                    988:                OptColTabs[i] = 0;
                    989:            }
                    990:            OptHome = 0;
                    991:            OptLeftMargin = 0;
                    992:            break;
                    993: 
                    994:        case FCN_COLTAB:
                    995:            ColTab();
                    996:            break;
                    997: 
                    998:        case FCN_COLBAK:
                    999:            ColBak();
                   1000:            break;
                   1001: 
                   1002:        case FCN_INDENT:
                   1003:            ColTab();
                   1004:            OptLeftMargin = ScreenLineOffset(CursorAddress);
                   1005:            break;
                   1006: 
                   1007:        case FCN_UNDENT:
                   1008:            ColBak();
                   1009:            OptLeftMargin = ScreenLineOffset(CursorAddress);
                   1010:            break;
                   1011: 
                   1012:        case FCN_SETMRG:
                   1013:            OptLeftMargin = ScreenLineOffset(CursorAddress);
                   1014:            break;
                   1015: 
                   1016:        case FCN_SETHOM:
                   1017:            OptHome = ScreenLine(CursorAddress);
                   1018:            break;
                   1019: 
                   1020:            /*
                   1021:             * Point to first character of next unprotected word on
                   1022:             * screen.
                   1023:             */
                   1024:        case FCN_WORDTAB:
                   1025:            i = CursorAddress;
                   1026:            SetXIsProtected();
                   1027:            while (!XIsProtected(i) && !Disspace(GetHost(i))) {
                   1028:                i = ScreenInc(i);
                   1029:                if (i == CursorAddress) {
                   1030:                    break;
                   1031:                }
                   1032:            }
                   1033:            /* i is either protected, a space (blank or null),
                   1034:             * or wrapped
                   1035:             */
                   1036:            while (XIsProtected(i) || Disspace(GetHost(i))) {
                   1037:                i =  ScreenInc(i);
                   1038:                if (i == CursorAddress) {
                   1039:                    break;
                   1040:                }
                   1041:            }
                   1042:            CursorAddress = i;
                   1043:            break;
                   1044: 
                   1045:        case FCN_WORDBACKTAB:
                   1046:            i = ScreenDec(CursorAddress);
                   1047:            SetXIsProtected();
                   1048:            while (XIsProtected(i) || Disspace(GetHost(i))) {
                   1049:                i = ScreenDec(i);
                   1050:                if (i == CursorAddress) {
                   1051:                    break;
                   1052:                }
                   1053:            }
                   1054:                /* i is pointing to a character IN an unprotected word
                   1055:                 * (or i wrapped)
                   1056:                 */
                   1057:            while (!Disspace(GetHost(i))) {
                   1058:                i = ScreenDec(i);
                   1059:                if (i == CursorAddress) {
                   1060:                    break;
                   1061:                }
                   1062:            }
                   1063:            CursorAddress = ScreenInc(i);
                   1064:            break;
                   1065: 
                   1066:                    /* Point to last non-blank character of this/next
                   1067:                     * unprotected word.
                   1068:                     */
                   1069:        case FCN_WORDEND:
                   1070:            i = ScreenInc(CursorAddress);
                   1071:            SetXIsProtected();
                   1072:            while (XIsProtected(i) || Disspace(GetHost(i))) {
                   1073:                i = ScreenInc(i);
                   1074:                if (i == CursorAddress) {
                   1075:                    break;
                   1076:                }
                   1077:            }
                   1078:                    /* we are pointing at a character IN an
                   1079:                     * unprotected word (or we wrapped)
                   1080:                     */
                   1081:            while (!Disspace(GetHost(i))) {
                   1082:                i = ScreenInc(i);
                   1083:                if (i == CursorAddress) {
                   1084:                    break;
                   1085:                }
                   1086:            }
                   1087:            CursorAddress = ScreenDec(i);
                   1088:            break;
                   1089: 
                   1090:                    /* Get to last non-blank of this/next unprotected
                   1091:                     * field.
                   1092:                     */
                   1093:        case FCN_FIELDEND:
                   1094:            i = LastOfField(CursorAddress);
                   1095:            if (i != CursorAddress) {
                   1096:                CursorAddress = i;              /* We moved; take this */
                   1097:            } else {
                   1098:                j = FieldInc(CursorAddress);    /* Move to next field */
                   1099:                i = LastOfField(j);
                   1100:                if (i != j) {
                   1101:                    CursorAddress = i;  /* We moved; take this */
                   1102:                }
                   1103:                    /* else - nowhere else on screen to be; stay here */
                   1104:            }
                   1105:            break;
                   1106: #endif /* !defined(PURE3274) */
                   1107: 
                   1108:        default:
                   1109:                                /* We don't handle this yet */
                   1110:            RingBell("Function not implemented");
                   1111:        }
                   1112:     }
                   1113:     return 1;                          /* We did something! */
                   1114: }
                   1115: 
                   1116: 
                   1117: /*
                   1118:  * We get data from the terminal.  We keep track of the shift state
                   1119:  * (including ALT, CONTROL), and then call AcceptKeystroke to actually
                   1120:  * process any non-shift keys.
                   1121:  */
                   1122: 
                   1123: int
                   1124: DataFrom3270(buffer, count)
                   1125: unsigned char  *buffer;                /* where the data is */
                   1126: int            count;                  /* how much data there is */
                   1127: {
                   1128:     int origCount;
                   1129: 
                   1130:     origCount = count;
                   1131: 
                   1132:     while (count) {
                   1133:        if (*buffer >= numberof(hits)) {
                   1134:            ExitString(stderr,
                   1135:                        "Unknown scancode encountered in DataFrom3270.\n", 1);
                   1136:            /*NOTREACHED*/
                   1137:        }
                   1138: 
                   1139:        switch (hits[*buffer].hit[HITNUM(rememberedshiftstate)].ctlrfcn) {
                   1140: 
                   1141:        case FCN_MAKE_SHIFT:
                   1142:            rememberedshiftstate |= (SHIFT_RIGHT|SHIFT_UPSHIFT);
                   1143:            break;
                   1144:        case FCN_BREAK_SHIFT:
                   1145:            rememberedshiftstate &= ~(SHIFT_RIGHT|SHIFT_UPSHIFT);
                   1146:            break;
                   1147:        case FCN_MAKE_ALT:
                   1148:            rememberedshiftstate |= SHIFT_ALT;
                   1149:            break;
                   1150:        case FCN_BREAK_ALT:
                   1151:            rememberedshiftstate &= ~SHIFT_ALT;
                   1152:            break;
                   1153:        default:
                   1154:            if (AcceptKeystroke(*buffer, rememberedshiftstate) == 0) {
                   1155:                return(origCount-count);
                   1156:            }
                   1157:            break;
                   1158:        }
                   1159:        buffer++;
                   1160:        count--;
                   1161:     }
                   1162:     return(origCount-count);
                   1163: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.