Annotation of 43BSDTahoe/ucb/tn3270/sys_curses/termout.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[] = "@(#)termout.c  3.3 (Berkeley) 3/31/88";
        !            15: #endif /* not lint */
        !            16: 
        !            17: #if defined(unix)
        !            18: #include <signal.h>
        !            19: #include <sgtty.h>
        !            20: #endif
        !            21: #include <stdio.h>
        !            22: #include <curses.h>
        !            23: 
        !            24: #include "../general/general.h"
        !            25: 
        !            26: #include "terminal.h"
        !            27: 
        !            28: #include "../telnet.ext"
        !            29: 
        !            30: #include "../api/disp_asc.h"
        !            31: 
        !            32: #include "../ctlr/hostctlr.h"
        !            33: #include "../ctlr/inbound.ext"
        !            34: #include "../ctlr/oia.h"
        !            35: #include "../ctlr/options.ext"
        !            36: #include "../ctlr/outbound.ext"
        !            37: #include "../ctlr/screen.h"
        !            38: 
        !            39: #include "../ascii/map3270.ext"
        !            40: 
        !            41: #include "../general/globals.h"
        !            42: 
        !            43: extern void EmptyTerminal();
        !            44: 
        !            45: #define CorrectTerminalCursor() ((TransparentClock == OutputClock)? \
        !            46:                CursorAddress:UnLocked? CursorAddress: HighestScreen())
        !            47: 
        !            48: 
        !            49: static int terminalCursorAddress;      /* where the cursor is on term */
        !            50: static int screenInitd;                /* the screen has been initialized */
        !            51: static int screenStopped;              /* the screen has been stopped */
        !            52: static int max_changes_before_poll;    /* how many characters before looking */
        !            53:                                        /* at terminal and net again */
        !            54: 
        !            55: static int needToRing;                 /* need to ring terinal bell */
        !            56: static char *bellSequence = "\07";     /* bell sequence (may be replaced by
        !            57:                                         * VB during initialization)
        !            58:                                         */
        !            59: static WINDOW *bellwin = 0;            /* The window the bell message is in */
        !            60: int    bellwinup = 0;                  /* Are we up with it or not */
        !            61: 
        !            62: #if    defined(unix)
        !            63: static char *KS, *KE;
        !            64: #endif /* defined(unix) */
        !            65: 
        !            66: 
        !            67: static int inHighlightMode = 0;
        !            68: ScreenImage Terminal[MAXSCREENSIZE];
        !            69: 
        !            70: /* Variables for transparent mode */
        !            71: #if    defined(unix)
        !            72: static int tcflag = -1;                        /* transparent mode command flag */
        !            73: static int savefd[2];                  /* for storing fds during transcom */
        !            74: extern int     tin, tout;              /* file descriptors */
        !            75: #endif /* defined(unix) */
        !            76: 
        !            77: 
        !            78: /*
        !            79:  * init_screen()
        !            80:  *
        !            81:  * Initialize variables used by screen.
        !            82:  */
        !            83: 
        !            84: void
        !            85: init_screen()
        !            86: {
        !            87:     bellwinup = 0;
        !            88:     inHighlightMode = 0;
        !            89:     ClearArray(Terminal);
        !            90: }
        !            91: 
        !            92: 
        !            93: /* OurExitString - designed to keep us from going through infinite recursion */
        !            94: 
        !            95: static void
        !            96: OurExitString(file, string, value)
        !            97: FILE   *file;
        !            98: char   *string;
        !            99: int    value;
        !           100: {
        !           101:     static int recursion = 0;
        !           102: 
        !           103:     if (!recursion) {
        !           104:        recursion = 1;
        !           105:        ExitString(file, string, value);
        !           106:     }
        !           107: }
        !           108: 
        !           109: 
        !           110: /* DoARefresh */
        !           111: 
        !           112: static void
        !           113: DoARefresh()
        !           114: {
        !           115:     if (ERR == refresh()) {
        !           116:        OurExitString(stderr, "ERR from refresh\n", 1);
        !           117:     }
        !           118: }
        !           119: 
        !           120: static void
        !           121: GoAway(from, where)
        !           122: char *from;            /* routine that gave error */
        !           123: int    where;          /* cursor address */
        !           124: {
        !           125:        char foo[100];
        !           126: 
        !           127:        sprintf(foo, "ERR from %s at %d (%d, %d)\n",
        !           128:                from, where, ScreenLine(where), ScreenLineOffset(where));
        !           129:        OurExitString(stderr, foo, 1);
        !           130:        /* NOTREACHED */
        !           131: }
        !           132: 
        !           133: /* What is the screen address of the attribute byte for the terminal */
        !           134: 
        !           135: static int
        !           136: WhereTermAttrByte(p)
        !           137: register int   p;
        !           138: {
        !           139:     register int i;
        !           140: 
        !           141:     i = p;
        !           142: 
        !           143:     do {
        !           144:        if (TermIsStartField(i)) {
        !           145:            return(i);
        !           146:        }
        !           147:        i = ScreenDec(i);
        !           148:     } while (i != p);
        !           149: 
        !           150:     return(LowestScreen());    /* unformatted screen... */
        !           151: }
        !           152: 
        !           153: /*
        !           154:  *     There are two algorithms for updating the screen.
        !           155:  *  The first, SlowScreen() optimizes the line between the
        !           156:  *  computer and the screen (say a 9600 baud line).  To do
        !           157:  *  this, we break out of the loop every so often to look
        !           158:  *  at any pending input from the network (so that successive
        !           159:  *  screens will only partially print until the final screen,
        !           160:  *  the one the user possibly wants to see, is displayed
        !           161:  *  in its entirety).
        !           162:  *
        !           163:  *     The second algorithm tries to optimize CPU time (by
        !           164:  *  being simpler) at the cost of the bandwidth to the
        !           165:  *  screen.
        !           166:  *
        !           167:  *     Of course, curses(3X) gets in here also.
        !           168:  */
        !           169: 
        !           170: 
        !           171: #if    defined(NOT43)
        !           172: static int
        !           173: #else  /* defined(NOT43) */
        !           174: static void
        !           175: #endif /* defined(NOT43) */
        !           176: SlowScreen()
        !           177: {
        !           178:     register int pointer;
        !           179:     register int c;
        !           180:     register int fieldattr;
        !           181:     register int columnsleft;
        !           182: 
        !           183: #   define  SetHighlightMode(p) { \
        !           184:                if (!IsStartField(p) && IsHighlightedAttr(fieldattr)) { \
        !           185:                    if (!inHighlightMode) { \
        !           186:                        inHighlightMode = 1; \
        !           187:                        standout(); \
        !           188:                    } \
        !           189:                } else { \
        !           190:                    if (inHighlightMode) { \
        !           191:                        inHighlightMode = 0; \
        !           192:                        standend(); \
        !           193:                    } \
        !           194:                } \
        !           195:            }
        !           196: 
        !           197: #   define  DoCharacterAt(c,p) { \
        !           198:                SetTerminal(p, c); \
        !           199:                if (p != HighestScreen()) { \
        !           200:                    c = TerminalCharacterAttr(disp_asc[c&0xff], p, \
        !           201:                                                                fieldattr); \
        !           202:                    if (terminalCursorAddress != p) { \
        !           203:                        if (ERR == mvaddch(ScreenLine(p), \
        !           204:                                                ScreenLineOffset(p), c)) {\
        !           205:                            GoAway("mvaddch", p); \
        !           206:                        } \
        !           207:                    } else { \
        !           208:                        if (ERR == addch(c)) {\
        !           209:                            GoAway("addch", p); \
        !           210:                        } \
        !           211:                    } \
        !           212:                    terminalCursorAddress = ScreenInc(p); \
        !           213:                } \
        !           214:            }
        !           215: 
        !           216: 
        !           217:     /* run through screen, printing out non-null lines */
        !           218: 
        !           219:     /* There are two separate reasons for wanting to terminate this
        !           220:      * loop early.  One is to respond to new input (either from
        !           221:      * the terminal or from the network [host]).  For this reason,
        !           222:      * we expect to see 'HaveInput' come true when new input comes in.
        !           223:      *
        !           224:      * The second reason is a bit more difficult (for me) to understand.
        !           225:      * Basically, we don't want to get too far ahead of the characters that
        !           226:      * appear on the screen.  Ideally, we would type out a few characters,
        !           227:      * wait until they appeared on the screen, then type out a few more.
        !           228:      * The reason for this is that the user, on seeing some characters
        !           229:      * appear on the screen may then start to type something.  We would
        !           230:      * like to look at what the user types at about the same 'time'
        !           231:      * (measured by characters being sent to the terminal) that the
        !           232:      * user types them.  For this reason, what we would like to do
        !           233:      * is update a bit, then call curses to do a refresh, flush the
        !           234:      * output to the terminal, then wait until the terminal data
        !           235:      * has been sent.
        !           236:      *
        !           237:      * Note that curses is useful for, among other things, deciding whether
        !           238:      * or not to send :ce: (clear to end of line), so we should call curses
        !           239:      * at end of lines (beginning of next lines).
        !           240:      *
        !           241:      * The problems here are the following:  If we do lots of write(2)s,
        !           242:      * we will be doing lots of context switches, thus lots of overhead
        !           243:      * (which we have already).  Second, if we do a select to wait for
        !           244:      * the output to drain, we have to contend with the fact that NOW
        !           245:      * we are scheduled to run, but who knows what the scheduler will
        !           246:      * decide when the output has caught up.
        !           247:      */
        !           248: 
        !           249:     if (Highest >= HighestScreen()) {  /* Could be > if screen shrunk... */
        !           250:        Highest = ScreenDec(Highest);   /* else, while loop will never end */
        !           251:     }
        !           252:     if (Lowest < LowestScreen()) {
        !           253:        Lowest = LowestScreen();        /* could be -1 in some cases with
        !           254:                                         * unformatted screens.
        !           255:                                         */
        !           256:     }
        !           257:     if (Highest >= (pointer = Lowest)) {
        !           258:                /* if there is anything to do, do it.  We won't terminate
        !           259:                 * the loop until we've gone at least to Highest.
        !           260:                 */
        !           261:        while ((pointer <= Highest) && !HaveInput) {
        !           262: 
        !           263:                /* point at the next place of disagreement */
        !           264:            pointer += (bunequal(Host+pointer, Terminal+pointer,
        !           265:                        (Highest-pointer+1)*sizeof Host[0])/sizeof Host[0]);
        !           266: 
        !           267:                /* how many characters to change until the end of the
        !           268:                 * current line
        !           269:                 */
        !           270:            columnsleft = NumberColumns - ScreenLineOffset(pointer);
        !           271:                /*
        !           272:                 * Make sure we are where we think we are.
        !           273:                 */
        !           274:            move(ScreenLine(pointer), ScreenLineOffset(pointer));
        !           275: 
        !           276:                /* what is the field attribute of the current position */
        !           277:            fieldattr = FieldAttributes(WhereAttrByte(pointer));
        !           278: 
        !           279:            if ((IsStartField(pointer) != TermIsStartField(pointer)) ||
        !           280:                    (IsStartField(pointer) &&
        !           281:                        fieldattr != TermAttributes(pointer))) {
        !           282: 
        !           283:                int oldterm;
        !           284: 
        !           285:                oldterm = TermAttributes(pointer);
        !           286:                if (IsStartField(pointer)) {
        !           287:                    TermNewField(pointer, fieldattr);
        !           288:                    SetTerminal(pointer, 0);
        !           289:                } else {
        !           290:                    TermDeleteField(pointer);
        !           291:                }
        !           292:                    /* We always do the first character in a divergent
        !           293:                     * field, since otherwise the start of a field in
        !           294:                     * the Host structure may leave a highlighted blank
        !           295:                     * on the screen, and the start of a field in the
        !           296:                     * Terminal structure may leave a non-highlighted
        !           297:                     * something in the middle of a highlighted field
        !           298:                     * on the screen.
        !           299:                     */
        !           300:                SetHighlightMode(pointer);
        !           301:                c = GetHost(pointer);
        !           302:                DoCharacterAt(c,pointer);               /* MACRO */
        !           303: 
        !           304:                if (NotVisuallyCompatibleAttributes
        !           305:                                (pointer, fieldattr, oldterm)) {
        !           306:                    int j;
        !           307: 
        !           308:                    j = pointer;
        !           309: 
        !           310:                    pointer = ScreenInc(pointer);
        !           311:                    if (!(--columnsleft)) {
        !           312:                        DoARefresh();
        !           313:                        EmptyTerminal();
        !           314:                        move(ScreenLine(pointer), 0);
        !           315:                        columnsleft = NumberColumns;
        !           316:                    }
        !           317:                    SetHighlightMode(pointer);  /* Turn on highlighting */
        !           318:                    while ((!IsStartField(pointer)) &&
        !           319:                                (!TermIsStartField(pointer))) {
        !           320:                        c = GetHost(pointer);
        !           321:                        DoCharacterAt(c,pointer);       /* MACRO */
        !           322:                        pointer = ScreenInc(pointer);
        !           323:                        if (!(--columnsleft)) {
        !           324:                            DoARefresh();
        !           325:                            EmptyTerminal();
        !           326:                            move(ScreenLine(pointer), 0);
        !           327:                            columnsleft = NumberColumns;
        !           328:                                /* We don't look at HaveInput here, since
        !           329:                                 * if we leave this loop before the end of
        !           330:                                 * the 3270 field, we could have pointer
        !           331:                                 * higher than Highest.  This would cause
        !           332:                                 * us to end the highest "while" loop,
        !           333:                                 * but we may, in fact, need to go around the
        !           334:                                 * screen once again.
        !           335:                                 */
        !           336:                        }
        !           337:                        /*              The loop needs to be protected
        !           338:                         *      from the situation where there had been only
        !           339:                         *      one field on the Terminal, and none on the Host.
        !           340:                         *      In this case, we have just deleted our last
        !           341:                         *      field.  Hence, the break.
        !           342:                         */
        !           343:                        if (j == pointer) {
        !           344:                            break;
        !           345:                        }
        !           346:                    }
        !           347:                    if (IsStartField(pointer) && !TermIsStartField(pointer)) {
        !           348:                            /* Remember what the terminal looked like */
        !           349:                        TermNewField(pointer, oldterm);
        !           350:                            /*
        !           351:                             * The danger here is that the current position may
        !           352:                             * be the start of a Host field.  If so, and the
        !           353:                             * field is highlighted, and our terminal was
        !           354:                             * highlighted, then we will leave a highlighted
        !           355:                             * blank at this position.
        !           356:                             */
        !           357:                        SetHighlightMode(pointer);
        !           358:                        c = GetHost(pointer);
        !           359:                        DoCharacterAt(c,pointer);
        !           360:                    }
        !           361:                        /* We could be in the situation of needing to exit.
        !           362:                         * This could happen if the current field wrapped around
        !           363:                         * the end of the screen.
        !           364:                         */
        !           365:                    if (j > pointer) {
        !           366:                        /*
        !           367:                         * pointer is guaranteed to be higher than Highest...
        !           368:                         */
        !           369:                        pointer = Highest+1;    /* We did the highest thing */
        !           370:                        break;
        !           371:                    }
        !           372:                } else {
        !           373:                    c = GetHost(pointer);
        !           374:                        /* We always do the first character in a divergent
        !           375:                         * field, since otherwise the start of a field in
        !           376:                         * the Host structure may leave a highlighted blank
        !           377:                         * on the screen, and the start of a field in the
        !           378:                         * Terminal structure may leave a non-highlighted
        !           379:                         * something in the middle of a highlighted field
        !           380:                         * on the screen.
        !           381:                         */
        !           382:                    SetHighlightMode(pointer);
        !           383:                    DoCharacterAt(c,pointer);
        !           384:                }
        !           385:            } else {
        !           386:                SetHighlightMode(pointer);
        !           387:                /*
        !           388:                 * The following will terminate at least when we get back
        !           389:                 * to the original 'pointer' location (since we force
        !           390:                 * things to be equal).
        !           391:                 */
        !           392:                while (((c = GetHost(pointer)) != GetTerminal(pointer)) &&
        !           393:                        !IsStartField(pointer) && !TermIsStartField(pointer)) {
        !           394:                    DoCharacterAt(c, pointer);
        !           395:                    pointer = ScreenInc(pointer);
        !           396:                    if (!(--columnsleft)) {
        !           397:                        DoARefresh();
        !           398:                        EmptyTerminal();
        !           399:                        if (HaveInput) {        /* if input came in, take it */
        !           400:                            break;
        !           401:                        }
        !           402:                        move(ScreenLine(pointer), 0);
        !           403:                        columnsleft = NumberColumns;
        !           404:                    }
        !           405:                }
        !           406:            }
        !           407:        }
        !           408:     }
        !           409:     DoARefresh();
        !           410:     Lowest = pointer;
        !           411:     if (Lowest > Highest) {            /* if we finished input... */
        !           412:        Lowest = HighestScreen()+1;
        !           413:        Highest = LowestScreen()-1;
        !           414:        terminalCursorAddress = CorrectTerminalCursor();
        !           415:        if (ERR == move(ScreenLine(terminalCursorAddress),
        !           416:                        ScreenLineOffset(terminalCursorAddress))) {
        !           417:            GoAway("move", terminalCursorAddress);
        !           418:        }
        !           419:        DoARefresh();
        !           420:        if (needToRing) {
        !           421:            StringToTerminal(bellSequence);
        !           422:            needToRing = 0;
        !           423:        }
        !           424:     }
        !           425:     EmptyTerminal();                   /* move data along */
        !           426:     return;
        !           427: }
        !           428: 
        !           429: #if    defined(NOT43)
        !           430: static int
        !           431: #else  /* defined(NOT43) */
        !           432: static void
        !           433: #endif /* defined(NOT43) */
        !           434: FastScreen()
        !           435: {
        !           436: #if    defined(MSDOS)
        !           437: #define        SaveCorner      0
        !           438: #else  /* defined(MSDOS) */
        !           439: #define        SaveCorner      1
        !           440: #endif /* defined(MSDOS) */
        !           441: 
        !           442: #define        DoAttribute(a)      if (IsHighlightedAttr(a)) { \
        !           443:                                standout(); \
        !           444:                            } else { \
        !           445:                                standend(); \
        !           446:                            } \
        !           447:                            if (IsNonDisplayAttr(a)) { \
        !           448:                                a = 0;  /* zero == don't display */ \
        !           449:                            } \
        !           450:                            if (!FormattedScreen()) { \
        !           451:                                a = 1;  /* one ==> do display on unformatted */\
        !           452:                            }
        !           453:     ScreenImage *p, *upper;
        !           454:     int fieldattr;             /* spends most of its time == 0 or 1 */
        !           455: 
        !           456: /* OK.  We want to do this a quickly as possible.  So, we assume we
        !           457:  * only need to go from Lowest to Highest.  However, if we find a
        !           458:  * field in the middle, we do the whole screen.
        !           459:  *
        !           460:  * In particular, we separate out the two cases from the beginning.
        !           461:  */
        !           462:     if ((Highest != HighestScreen()) || (Lowest != LowestScreen())) {
        !           463:        register int columnsleft;
        !           464: 
        !           465:        move(ScreenLine(Lowest), ScreenLineOffset(Lowest));
        !           466:        p = &Host[Lowest];
        !           467: #if    !defined(MSDOS)
        !           468:        if (Highest == HighestScreen()) {
        !           469:            Highest = ScreenDec(Highest);
        !           470:        }
        !           471: #endif /* !defined(MSDOS) */
        !           472:        upper = &Host[Highest];
        !           473:        fieldattr = FieldAttributes(Lowest);
        !           474:        DoAttribute(fieldattr); /* Set standout, non-display status */
        !           475:        columnsleft = NumberColumns-ScreenLineOffset(p-Host);
        !           476: 
        !           477:        while (p <= upper) {
        !           478:            if (IsStartFieldPointer(p)) {       /* New field? */
        !           479:                Highest = HighestScreen();
        !           480:                Lowest = LowestScreen();
        !           481:                FastScreen();           /* Recurse */
        !           482:                return;
        !           483:            } else if (fieldattr) {     /* Should we display? */
        !           484:                            /* Display translated data */
        !           485:                addch(disp_asc[GetTerminalPointer(p)]);
        !           486:            } else {
        !           487:                addch(' ');                     /* Display a blank */
        !           488:            }
        !           489:                        /* If the physical screen is larger than what we
        !           490:                         * are using, we need to make sure that each line
        !           491:                         * starts at the beginning of the line.  Otherwise,
        !           492:                         * we will just string all the lines together.
        !           493:                         */
        !           494:            p++;
        !           495:            if (--columnsleft == 0) {
        !           496:                int i = p-Host;
        !           497: 
        !           498:                move(ScreenLine(i), 0);
        !           499:                columnsleft = NumberColumns;
        !           500:            }
        !           501:        }
        !           502:     } else {           /* Going from Lowest to Highest */
        !           503:        unsigned char tmpbuf[MAXNUMBERCOLUMNS+1];
        !           504:        ScreenImage *End = &Host[ScreenSize]-1-SaveCorner;
        !           505:        register unsigned char *tmp = tmpbuf, *tmpend = tmpbuf+NumberColumns;
        !           506: 
        !           507:        *tmpend = 0;            /* terminate from the beginning */
        !           508:        move(0,0);
        !           509:        p = Host;
        !           510:        fieldattr = FieldAttributes(LowestScreen());
        !           511:        DoAttribute(fieldattr); /* Set standout, non-display status */
        !           512: 
        !           513:        while (p <= End) {
        !           514:            if (IsStartFieldPointer(p)) {       /* New field? */
        !           515:                if (tmp != tmpbuf) {
        !           516:                    *tmp++ = 0;                 /* close out */
        !           517:                    addstr(tmpbuf);
        !           518:                    tmp = tmpbuf;
        !           519:                    tmpend = tmpbuf + NumberColumns - ScreenLineOffset(p-Host);
        !           520:                }
        !           521:                fieldattr = FieldAttributesPointer(p);  /* Get attributes */
        !           522:                DoAttribute(fieldattr); /* Set standout, non-display */
        !           523:                *tmp++ = ' ';
        !           524:            } else {
        !           525:                if (fieldattr) {        /* Should we display? */
        !           526:                                /* Display translated data */
        !           527:                    *tmp++ = disp_asc[GetTerminalPointer(p)];
        !           528:                } else {
        !           529:                    *tmp++ = ' ';
        !           530:                }
        !           531:            }
        !           532:                        /* If the physical screen is larger than what we
        !           533:                         * are using, we need to make sure that each line
        !           534:                         * starts at the beginning of the line.  Otherwise,
        !           535:                         * we will just string all the lines together.
        !           536:                         */
        !           537:            p++;
        !           538:            if (tmp == tmpend) {
        !           539:                int i = p-Host;         /* Be sure the "p++" happened first! */
        !           540: 
        !           541:                *tmp++ = 0;
        !           542:                addstr(tmpbuf);
        !           543:                tmp = tmpbuf;
        !           544:                move(ScreenLine(i), 0);
        !           545:                tmpend = tmpbuf + NumberColumns;
        !           546:            }
        !           547:        }
        !           548:        if (tmp != tmpbuf) {
        !           549:            *tmp++ = 0;
        !           550:            addstr(tmpbuf);
        !           551:            tmp = tmpbuf;
        !           552:        }
        !           553:     }
        !           554:     Lowest = HighestScreen()+1;
        !           555:     Highest = LowestScreen()-1;
        !           556:     terminalCursorAddress = CorrectTerminalCursor();
        !           557:     if (ERR == move(ScreenLine(terminalCursorAddress),
        !           558:                    ScreenLineOffset(terminalCursorAddress))) {
        !           559:        GoAway("move", terminalCursorAddress);
        !           560:     }
        !           561:     DoARefresh();
        !           562:     if (needToRing) {
        !           563:        StringToTerminal(bellSequence);
        !           564:        needToRing = 0;
        !           565:     }
        !           566:     EmptyTerminal();                   /* move data along */
        !           567:     return;
        !           568: }
        !           569: 
        !           570: 
        !           571: /* TryToSend - send data out to user's terminal */
        !           572: 
        !           573: #if    defined(NOT43)
        !           574: int
        !           575: #else  /* defined(NOT43) */
        !           576: void
        !           577: #endif /* defined(NOT43) */
        !           578:        (*TryToSend)() = FastScreen;
        !           579: 
        !           580: void
        !           581: ScreenOIA(oia)
        !           582: OIA *oia;
        !           583: {
        !           584: }
        !           585: 
        !           586: 
        !           587: /* InitTerminal - called to initialize the screen, etc. */
        !           588: 
        !           589: void
        !           590: InitTerminal()
        !           591: {
        !           592: #if defined(unix)
        !           593:     struct sgttyb ourttyb;
        !           594:     static int speeds[] = { 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800,
        !           595:                2400, 4800, 9600 };
        !           596: #endif
        !           597:     
        !           598:     InitMapping();             /* Go do mapping file (MAP3270) first */
        !           599:     if (!screenInitd) {        /* not initialized */
        !           600: #if    defined(unix)
        !           601:        char KSEbuffer[2050];
        !           602:        char *lotsofspace = KSEbuffer;
        !           603:        extern int abort();
        !           604:        extern char *tgetstr();
        !           605: #endif /* defined(unix) */
        !           606: 
        !           607:        ClearArray(Terminal);
        !           608:        terminalCursorAddress = SetBufferAddress(0,0);
        !           609: #if defined(unix)
        !           610:        signal(SIGHUP, abort);
        !           611: #endif
        !           612: 
        !           613:        TryToSend = FastScreen;
        !           614: #if defined(unix)
        !           615:        ioctl(1, TIOCGETP, (char *) &ourttyb);
        !           616:        if ((ourttyb.sg_ospeed < 0) || (ourttyb.sg_ospeed > B9600)) {
        !           617:            max_changes_before_poll = 1920;
        !           618:        } else {
        !           619:            max_changes_before_poll = speeds[ourttyb.sg_ospeed]/10;
        !           620:            if (max_changes_before_poll < 40) {
        !           621:                max_changes_before_poll = 40;
        !           622:            }
        !           623:            TryToSend = SlowScreen;
        !           624:            HaveInput = 1;              /* get signals going */
        !           625:        }
        !           626: #endif /* defined(unix) */
        !           627:        setcommandmode();
        !           628:        /*
        !           629:         * By now, initscr() (in curses) has been called (from telnet.c),
        !           630:         * and the screen has been initialized.
        !           631:         */
        !           632: #if defined(unix)
        !           633:        nonl();
        !           634:                        /* the problem is that curses catches SIGTSTP to
        !           635:                         * be nice, but it messes us up.
        !           636:                         */
        !           637:        signal(SIGTSTP, SIG_DFL);
        !           638:        if ((KS = tgetstr("ks", &lotsofspace)) != 0) {
        !           639:            KS = strsave(KS);
        !           640:            StringToTerminal(KS);
        !           641:        }
        !           642:        if ((KE = tgetstr("ke", &lotsofspace)) != 0) {
        !           643:            KE = strsave(KE);
        !           644:        }
        !           645:        if (tgetstr("md", &lotsofspace) && tgetstr("me", &lotsofspace)) {
        !           646:           SO = strsave(tgetstr("md", &lotsofspace));
        !           647:           SE = strsave(tgetstr("me", &lotsofspace));
        !           648:        }
        !           649: #endif
        !           650:        DoARefresh();
        !           651:        setconnmode();
        !           652:        if (VB && *VB) {
        !           653:            bellSequence = VB;          /* use visual bell */
        !           654:        }
        !           655:        screenInitd = 1;
        !           656:        screenStopped = 0;              /* Not stopped */
        !           657:     }
        !           658: }
        !           659: 
        !           660: 
        !           661: /* StopScreen - called when we are going away... */
        !           662: 
        !           663: void
        !           664: StopScreen(doNewLine)
        !           665: int doNewLine;
        !           666: {
        !           667:     if (screenInitd && !screenStopped) {
        !           668:        move(NumberLines-1, 1);
        !           669:        standend();
        !           670:        inHighlightMode = 0;
        !           671:        DoARefresh();
        !           672:        setcommandmode();
        !           673:        endwin();
        !           674:        setconnmode();
        !           675: #if    defined(unix)
        !           676:        if (KE) {
        !           677:            StringToTerminal(KE);
        !           678:        }
        !           679: #endif /* defined(unix) */
        !           680:        if (doNewLine) {
        !           681:            StringToTerminal("\r\n");
        !           682:        }
        !           683:        EmptyTerminal();
        !           684:        screenStopped = 1;              /* This is stopped */
        !           685:     }
        !           686: }
        !           687: 
        !           688: 
        !           689: /* RefreshScreen - called to cause the screen to be refreshed */
        !           690: 
        !           691: void
        !           692: RefreshScreen()
        !           693: {
        !           694:     clearok(curscr, TRUE);
        !           695:     (*TryToSend)();
        !           696: }
        !           697: 
        !           698: 
        !           699: /* ConnectScreen - called to reconnect to the screen */
        !           700: 
        !           701: void
        !           702: ConnectScreen()
        !           703: {
        !           704:     if (screenInitd) {
        !           705: #if    defined(unix)
        !           706:        if (KS) {
        !           707:            StringToTerminal(KS);
        !           708:        }
        !           709: #endif /* defined(unix) */
        !           710:        RefreshScreen();
        !           711:        (*TryToSend)();
        !           712:        screenStopped = 0;
        !           713:     }
        !           714: }
        !           715: 
        !           716: /* LocalClearScreen() - clear the whole ball of wax, cheaply */
        !           717: 
        !           718: void
        !           719: LocalClearScreen()
        !           720: {
        !           721:     outputPurge();             /* flush all data to terminal */
        !           722:     clear();                   /* clear in curses */
        !           723:     ClearArray(Terminal);
        !           724:     Clear3270();
        !           725:     Lowest = HighestScreen()+1; /* everything in sync... */
        !           726:     Highest = LowestScreen()+1;
        !           727: }
        !           728: 
        !           729: 
        !           730: void
        !           731: BellOff()
        !           732: {
        !           733:     if (bellwinup) {
        !           734:        delwin(bellwin);
        !           735:        bellwin = 0;
        !           736:        bellwinup = 0;
        !           737:        touchwin(stdscr);
        !           738:        DoARefresh();
        !           739:     }
        !           740: }
        !           741: 
        !           742: 
        !           743: void
        !           744: RingBell(s)
        !           745: char *s;
        !           746: {
        !           747:     needToRing = 1;
        !           748:     if (s) {
        !           749:        int len = strlen(s);
        !           750: 
        !           751:        if (len > COLS-2) {
        !           752:            len = COLS-2;
        !           753:        }
        !           754:        if ((bellwin = newwin(3, len+2, LINES/2, 0)) == NULL) {
        !           755:            OurExitString(stderr, "Error from newwin in RingBell", 1);
        !           756:        }
        !           757:        werase(bellwin);
        !           758:        wstandout(bellwin);
        !           759:        box(bellwin, '|', '-');
        !           760:        if (wmove(bellwin, 1, 1) == ERR) {
        !           761:            OurExitString(stderr, "Error from wmove in RingBell", 1);
        !           762:        }
        !           763:        while (len--) {
        !           764:            if (waddch(bellwin, *s++) == ERR) {
        !           765:                OurExitString(stderr, "Error from waddch in RingBell", 1);
        !           766:            }
        !           767:        }
        !           768:        wstandend(bellwin);
        !           769:        if (wrefresh(bellwin) == ERR) {
        !           770:            OurExitString(stderr, "Error from wrefresh in RingBell", 1);
        !           771:        }
        !           772:        bellwinup = 1;
        !           773:     }
        !           774: }
        !           775: 
        !           776: 
        !           777: /* returns a 1 if no more output available (so, go ahead and block),
        !           778:     or a 0 if there is more output available (so, just poll the other
        !           779:     sources/destinations, don't block).
        !           780:  */
        !           781: 
        !           782: int
        !           783: DoTerminalOutput()
        !           784: {
        !           785:        /* called just before a select to conserve IO to terminal */
        !           786:     if (!(screenInitd||screenStopped)) {
        !           787:        return 1;               /* No output if not initialized */
        !           788:     }
        !           789:     if ((Lowest <= Highest) || needToRing ||
        !           790:                        (terminalCursorAddress != CorrectTerminalCursor())) {
        !           791:        (*TryToSend)();
        !           792:     }
        !           793:     if (Lowest > Highest) {
        !           794:        return 1;               /* no more output now */
        !           795:     } else {
        !           796:        return 0;               /* more output for future */
        !           797:     }
        !           798: }
        !           799: 
        !           800: /*
        !           801:  * The following are defined to handle transparent data.
        !           802:  */
        !           803: 
        !           804: void
        !           805: TransStop()
        !           806: {
        !           807: #if    defined(unix)
        !           808:     if (tcflag == 0) {
        !           809:        tcflag = -1;
        !           810:        (void) signal(SIGCHLD, SIG_DFL);
        !           811:     } else if (tcflag > 0) {
        !           812:        setcommandmode();
        !           813:        (void) close(tin);
        !           814:        (void) close(tout);
        !           815:        tin = savefd[0];
        !           816:        tout = savefd[1];
        !           817:        setconnmode();
        !           818:        tcflag = -1;
        !           819:        (void) signal(SIGCHLD, SIG_DFL);
        !           820:     }
        !           821: #endif /* defined(unix) */
        !           822:     RefreshScreen();
        !           823: }
        !           824: 
        !           825: void
        !           826: TransOut(buffer, count, kind, control)
        !           827: unsigned char  *buffer;
        !           828: int            count;
        !           829: int            kind;           /* 0 or 5 */
        !           830: int            control;        /* To see if we are done */
        !           831: {
        !           832: #if    defined(unix)
        !           833:     extern char *transcom;
        !           834:     int inpipefd[2], outpipefd[2], savemode;
        !           835:     void aborttc();
        !           836: #endif /* defined(unix) */
        !           837: 
        !           838:     while (DoTerminalOutput() == 0) {
        !           839: #if defined(unix)
        !           840:        HaveInput = 0;
        !           841: #endif /* defined(unix) */
        !           842:     }
        !           843: #if    defined(unix)
        !           844:     if (transcom && tcflag == -1) {
        !           845:        while (1) {                       /* go thru once */
        !           846:             if (pipe(outpipefd) < 0) {
        !           847:                break;
        !           848:             }
        !           849:             if (pipe(inpipefd) < 0) {
        !           850:                break;
        !           851:             }
        !           852:             if ((tcflag = fork()) == 0) {
        !           853:                (void) close(outpipefd[1]);
        !           854:                (void) close(0);
        !           855:                if (dup(outpipefd[0]) < 0) {
        !           856:                   exit(1);
        !           857:                }
        !           858:                (void) close(outpipefd[0]);
        !           859:                (void) close(inpipefd[0]);
        !           860:                (void) close(1);
        !           861:                if (dup(inpipefd[1]) < 0) {
        !           862:                   exit(1);
        !           863:                }
        !           864:                (void) close(inpipefd[1]);
        !           865:                if (execl("/bin/csh", "csh", "-c", transcom, (char *) 0)) {
        !           866:                    exit(1);
        !           867:                }
        !           868:             }
        !           869:             (void) close(inpipefd[1]);
        !           870:             (void) close(outpipefd[0]);
        !           871:             savefd[0] = tin;
        !           872:             savefd[1] = tout;
        !           873:             setcommandmode();
        !           874:             tin = inpipefd[0];
        !           875:             tout = outpipefd[1];
        !           876:             (void) signal(SIGCHLD, aborttc);
        !           877:             setconnmode();
        !           878:             tcflag = 1;
        !           879:             break;
        !           880:        }
        !           881:        if (tcflag < 1) {
        !           882:          tcflag = 0;
        !           883:        }
        !           884:     }
        !           885: #endif /* defined(unix) */
        !           886:     (void) DataToTerminal(buffer, count);
        !           887:     if (control && (kind == 0)) {              /* Send in AID byte */
        !           888:        SendToIBM();
        !           889:     } else {
        !           890:        TransInput(1, kind);                    /* Go get some data */
        !           891:     }
        !           892: }
        !           893: 
        !           894: 
        !           895: #if    defined(unix)
        !           896: static void
        !           897: aborttc()
        !           898: {
        !           899:        int savemode;
        !           900: 
        !           901:        setcommandmode();
        !           902:        (void) close(tin);
        !           903:        (void) close(tout);
        !           904:        tin = savefd[0];
        !           905:        tout = savefd[1];
        !           906:        setconnmode();
        !           907:        tcflag = 0;
        !           908: }
        !           909: #endif /* defined(unix) */

unix.superglobalmegacorp.com

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