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