Annotation of 43BSDTahoe/ucb/tn3270/ctlr/inbound.c, revision 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.