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

unix.superglobalmegacorp.com

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