Annotation of 43BSDTahoe/ucb/tn3270/sys_dos/termout.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1988 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that this notice is preserved and that due credit is given
                      7:  * to the University of California at Berkeley. The name of the University
                      8:  * may not be used to endorse or promote products derived from this
                      9:  * software without specific prior written permission. This software
                     10:  * is provided ``as is'' without express or implied warranty.
                     11:  */
                     12: 
                     13: #ifndef lint
                     14: static char sccsid[] = "@(#)termout.c  3.2 (Berkeley) 3/28/88";
                     15: #endif /* not lint */
                     16: 
                     17: #include <stdio.h>
                     18: #include <dos.h>
                     19: #include "../general/general.h"
                     20: 
                     21: #include "../telnet.ext"
                     22: 
                     23: #include "../api/disp_asc.h"
                     24: #include "../ascii/map3270.ext"
                     25: 
                     26: #include "../ctlr/hostctlr.h"
                     27: #include "../ctlr/inbound.ext"
                     28: #include "../ctlr/oia.h"
                     29: #include "../ctlr/options.ext"
                     30: #include "../ctlr/outbound.ext"
                     31: #include "../ctlr/screen.h"
                     32: 
                     33: #include "../general/globals.h"
                     34: 
                     35: #include "video.h"
                     36: 
                     37: extern void EmptyTerminal();
                     38: 
                     39: #define CorrectTerminalCursor() ((TransparentClock == OutputClock)? \
                     40:                terminalCursorAddress:UnLocked? CursorAddress: HighestScreen())
                     41: 
                     42: 
                     43: static int terminalCursorAddress;      /* where the cursor is on term */
                     44: static int screenInitd;                /* the screen has been initialized */
                     45: static int screenStopped;              /* the screen has been stopped */
                     46: 
                     47: static int needToRing;                 /* need to ring terinal bell */
                     48: 
                     49: typedef struct {
                     50:     char
                     51:        data,           /* The data for this position */
                     52:        attr;           /* The attributes for this position */
                     53: } ScreenBuffer;
                     54: 
                     55: ScreenBuffer Screen[MAXNUMBERLINES*MAXNUMBERCOLUMNS];
                     56: ScreenBuffer saveScreen[sizeof Screen/sizeof Screen[0]];
                     57: 
                     58: /* OurExitString - designed to keep us from going through infinite recursion */
                     59: 
                     60: static void
                     61: OurExitString(file, string, value)
                     62: FILE   *file;
                     63: char   *string;
                     64: int    value;
                     65: {
                     66:     static int recursion = 0;
                     67: 
                     68:     if (!recursion) {
                     69:        recursion = 1;
                     70:        ExitString(file, string, value);
                     71:     }
                     72: }
                     73: 
                     74: 
                     75: static void
                     76: GoAway(from, where)
                     77: char *from;            /* routine that gave error */
                     78: int    where;          /* cursor address */
                     79: {
                     80:        char foo[100];
                     81: 
                     82:        sprintf(foo, "ERR from %s at %d (%d, %d)\n",
                     83:                from, where, ScreenLine(where), ScreenLineOffset(where));
                     84:        OurExitString(stderr, foo, 1);
                     85:        /* NOTREACHED */
                     86: }
                     87: 
                     88: /*
                     89:  * Routines to deal with the screen.  These routines are lifted
                     90:  * from mskermit.
                     91:  */
                     92: 
                     93: #define        CRT_STATUS      0x3da           /* Color card */
                     94: #define        DISPLAY_ENABLE  0x08            /* Enable */
                     95: #define        scrseg()        ((crt_mode == 7)? 0xb000 : 0xb800)
                     96: #define        scrwait()       if (crt_mode != 7) { \
                     97:                            while ((inp(CRT_STATUS)&DISPLAY_ENABLE) == 0) { \
                     98:                                ; \
                     99:                            } \
                    100:                        }
                    101: static int
                    102:                crt_mode,
                    103:                crt_cols,
                    104:                crt_lins,
                    105:                curpage;
                    106: 
                    107: /*
                    108:  * Set the cursor position to where it belongs.
                    109:  */
                    110: 
                    111: static void
                    112: setcursor(row, column, page)
                    113: int
                    114:     row,
                    115:     column,
                    116:     page;
                    117: {
                    118:     union REGS inregs, outregs;
                    119: 
                    120:     inregs.h.dh = row;
                    121:     inregs.h.dl = column;
                    122:     inregs.h.bh = page;
                    123:     inregs.h.ah = SetCursorPosition;
                    124: 
                    125:     int86(BIOS_VIDEO, &inregs, &outregs);
                    126: }
                    127: /*
                    128:  * Read the state of the video system.  Put the cursor somewhere
                    129:  * reasonable.
                    130:  */
                    131: 
                    132: static void
                    133: scrini()
                    134: {
                    135:     union REGS inregs, outregs;
                    136: 
                    137:     inregs.h.ah = CurrentVideoState;
                    138:     int86(BIOS_VIDEO, &inregs, &outregs);
                    139: 
                    140:     crt_mode = outregs.h.al;
                    141:     crt_cols = outregs.h.ah;
                    142:     crt_lins = 25;
                    143:     curpage = outregs.h.bh;
                    144: 
                    145:     inregs.h.ah = ReadCursorPosition;
                    146:     inregs.h.bh = curpage;
                    147: 
                    148:     int86(BIOS_VIDEO, &inregs, &outregs);
                    149: 
                    150:     if (outregs.h.dh > crt_lins) {
                    151:        outregs.h.dh = crt_lins;
                    152:     }
                    153:     if (outregs.h.dl > crt_cols) {
                    154:        outregs.h.dl = crt_cols;
                    155:     }
                    156:     inregs.h.dh = outregs.h.dh;
                    157:     inregs.h.dl = outregs.h.dl;
                    158:     inregs.h.bh = curpage;
                    159: 
                    160:     inregs.h.ah = SetCursorPosition;
                    161:     int86(BIOS_VIDEO, &inregs, &outregs);
                    162: }
                    163: 
                    164: 
                    165: static void
                    166: scrwrite(source, length, offset)
                    167: ScreenBuffer *source;
                    168: int
                    169:        length,
                    170:        offset;
                    171: {
                    172:     struct SREGS segregs;
                    173: 
                    174:     segread(&segregs);         /* read the current segment register */
                    175: 
                    176:     scrwait();
                    177:     movedata(segregs.ds, source, scrseg(), sizeof *source*offset,
                    178:                                                sizeof *source*length);
                    179: }
                    180: 
                    181: static void
                    182: scrsave(buffer)
                    183: ScreenBuffer *buffer;
                    184: {
                    185:     struct SREGS segregs;
                    186: 
                    187:     segread(&segregs);         /* read the current segment register */
                    188: 
                    189:     scrwait();
                    190:     movedata(scrseg(), 0, segregs.ds, buffer, crt_cols*crt_lins*2);
                    191: }
                    192: 
                    193: static void
                    194: scrrest(buffer)
                    195: ScreenBuffer *buffer;
                    196: {
                    197:     scrwrite(buffer, crt_cols*crt_lins, 0);
                    198: }
                    199: 
                    200: static void
                    201: TryToSend()
                    202: {
                    203: #define        STANDOUT        0x0a    /* Highlighted mode */
                    204: #define        NORMAL          0x02    /* Normal mode */
                    205: #define        NONDISPLAY      0x00    /* Don't display */
                    206: 
                    207: #define        DoAttribute(a)      \
                    208:                            if (screenIsFormatted) { \
                    209:                                if (IsNonDisplayAttr(a)) { \
                    210:                                    a = NONDISPLAY;     /* don't display */ \
                    211:                                } else if (IsHighlightedAttr(a)) { \
                    212:                                    a = STANDOUT; \
                    213:                                } else { \
                    214:                                    a = NORMAL; \
                    215:                                } \
                    216:                            } else  { \
                    217:                                a = NORMAL;     /* do display on unformatted */\
                    218:                            }
                    219:     ScreenImage *p, *upper;
                    220:     ScreenBuffer *sp;
                    221:     int fieldattr;             /* spends most of its time == 0 or 1 */
                    222:     int screenIsFormatted = FormattedScreen();
                    223: 
                    224: /* OK.  We want to do this a quickly as possible.  So, we assume we
                    225:  * only need to go from Lowest to Highest.  However, if we find a
                    226:  * field in the middle, we do the whole screen.
                    227:  *
                    228:  * In particular, we separate out the two cases from the beginning.
                    229:  */
                    230:     if ((Highest != HighestScreen()) || (Lowest != LowestScreen())) {
                    231:        sp = &Screen[Lowest];
                    232:        p = &Host[Lowest];
                    233:        upper = &Host[Highest];
                    234:        fieldattr = FieldAttributes(Lowest);
                    235:        DoAttribute(fieldattr); /* Set standout, non-display status */
                    236: 
                    237:        while (p <= upper) {
                    238:            if (IsStartFieldPointer(p)) {       /* New field? */
                    239:                Highest = HighestScreen();
                    240:                Lowest = LowestScreen();
                    241:                TryToSend();            /* Recurse */
                    242:                return;
                    243:            } else if (fieldattr) {     /* Should we display? */
                    244:                                /* Display translated data */
                    245:                sp->data = disp_asc[GetHostPointer(p)];
                    246:            } else {
                    247:                sp->data = ' ';
                    248:            }
                    249:            sp->attr = fieldattr;
                    250:            p++;
                    251:            sp++;
                    252:        }
                    253:     } else {           /* Going from Lowest to Highest */
                    254:        ScreenImage *End = &Host[ScreenSize]-1;
                    255: 
                    256:        sp = Screen;
                    257:        p = Host;
                    258:        fieldattr = FieldAttributes(LowestScreen());
                    259:        DoAttribute(fieldattr); /* Set standout, non-display status */
                    260: 
                    261:        while (p <= End) {
                    262:            if (IsStartFieldPointer(p)) {       /* New field? */
                    263:                fieldattr = FieldAttributesPointer(p);  /* Get attributes */
                    264:                DoAttribute(fieldattr); /* Set standout, non-display */
                    265:            }
                    266:            if (fieldattr) {    /* Should we display? */
                    267:                            /* Display translated data */
                    268:                sp->data = disp_asc[GetHostPointer(p)];
                    269:            } else {
                    270:                sp->data = ' ';
                    271:            }
                    272:            sp->attr = fieldattr;
                    273:            p++;
                    274:            sp++;
                    275:        }
                    276:     }
                    277:     terminalCursorAddress = CorrectTerminalCursor();
                    278:     /*
                    279:      * We might be here just to update the cursor address.
                    280:      */
                    281:     if (Highest >= Lowest) {
                    282:        scrwrite(Screen+Lowest, (1+Highest-Lowest), Lowest);
                    283:     }
                    284:     setcursor(ScreenLine(terminalCursorAddress),
                    285:                    ScreenLineOffset(terminalCursorAddress), 0);
                    286:     Lowest = HighestScreen()+1;
                    287:     Highest = LowestScreen()-1;
                    288:     if (needToRing) {
                    289:        DataToTerminal("\7", 1);
                    290:        needToRing = 0;
                    291:     }
                    292:     return;
                    293: }
                    294: 
                    295: /* InitTerminal - called to initialize the screen, etc. */
                    296: 
                    297: void
                    298: InitTerminal()
                    299: {
                    300:     InitMapping();             /* Go do mapping file (MAP3270) first */
                    301:     if (!screenInitd) {        /* not initialized */
                    302:        MaxNumberLines = 24;    /* XXX */
                    303:        MaxNumberColumns = 80;  /* XXX */
                    304:        scrini();
                    305:        scrsave(saveScreen);    /* Save the screen buffer away */
                    306:        ClearArray(Screen);
                    307:        terminalCursorAddress = SetBufferAddress(0,0);
                    308:        screenInitd = 1;
                    309:        screenStopped = 0;              /* Not stopped */
                    310:     }
                    311: }
                    312: 
                    313: 
                    314: /* StopScreen - called when we are going away... */
                    315: 
                    316: void
                    317: StopScreen(doNewLine)
                    318: int doNewLine;
                    319: {
                    320:     if (screenInitd && !screenStopped) {
                    321:        scrrest(saveScreen);
                    322:        setcursor(NumberLines-1, 1, 0);
                    323:        if (doNewLine) {
                    324:            StringToTerminal("\r\n");
                    325:        }
                    326:        EmptyTerminal();
                    327:        screenStopped = 1;
                    328:     }
                    329: }
                    330: 
                    331: 
                    332: /* RefreshScreen - called to cause the screen to be refreshed */
                    333: 
                    334: void
                    335: RefreshScreen()
                    336: {
                    337:     Highest = HighestScreen();
                    338:     Lowest = LowestScreen();
                    339:     TryToSend();
                    340: }
                    341: 
                    342: 
                    343: /* ConnectScreen - called to reconnect to the screen */
                    344: 
                    345: void
                    346: ConnectScreen()
                    347: {
                    348:     if (screenInitd) {
                    349:        RefreshScreen();
                    350:        screenStopped = 0;
                    351:     }
                    352: }
                    353: 
                    354: /* LocalClearScreen() - clear the whole ball of wax, cheaply */
                    355: 
                    356: void
                    357: LocalClearScreen()
                    358: {
                    359:     Clear3270();
                    360:     Lowest = LowestScreen(); /* everything in sync... */
                    361:     Highest = HighestScreen();
                    362:     TryToSend();
                    363: }
                    364: 
                    365: /*
                    366:  * Implement the bell/error message function.
                    367:  */
                    368: 
                    369: int
                    370:        bellwinup = 0;          /* If != 0, length of bell message */
                    371: static int
                    372:        bell_len = 0;           /* Length of error message */
                    373: 
                    374: 
                    375: void
                    376: BellOff()
                    377: {
                    378:     ScreenBuffer a[100];
                    379:     int i;
                    380: 
                    381:     if (bellwinup) {
                    382:        unsigned char blank = ' ';
                    383: 
                    384:        for (i = 0; i < bell_len; i++) {
                    385:            a[i].attr = NORMAL;
                    386:            a[i].data = ' ';
                    387:        }
                    388:     }
                    389:     scrwrite(a, bell_len, 24*80);              /* XXX */
                    390: }
                    391: 
                    392: 
                    393: void
                    394: RingBell(s)
                    395: char *s;
                    396: {
                    397:     needToRing = 1;
                    398:     if (s) {
                    399:        int i;
                    400:        ScreenBuffer bellstring[100];
                    401: 
                    402:        bell_len = strlen(s);
                    403:        bellwinup = 1;
                    404:        if (bell_len > sizeof bellstring-1) {
                    405:            OurExitString(stderr, "Bell string too long.", 1);
                    406:        }
                    407:        for (i = 0; i < bell_len; i++) {
                    408:            bellstring[i].attr = STANDOUT;
                    409:            bellstring[i].data = s[i];
                    410:        }
                    411:        scrwrite(bellstring, bell_len, 24*80);          /* XXX */
                    412:     }
                    413: }
                    414: 
                    415: /*
                    416:  * Update the OIA area.
                    417:  */
                    418: 
                    419: void
                    420: ScreenOIA(oia)
                    421: OIA *oia;
                    422: {
                    423: }
                    424: 
                    425: 
                    426: /* returns a 1 if no more output available (so, go ahead and block),
                    427:     or a 0 if there is more output available (so, just poll the other
                    428:     sources/destinations, don't block).
                    429:  */
                    430: 
                    431: int
                    432: DoTerminalOutput()
                    433: {
                    434:        /* called just before a select to conserve IO to terminal */
                    435:     if (!(screenInitd||screenStopped)) {
                    436:        return 1;               /* No output if not initialized */
                    437:     }
                    438:     if ((Lowest <= Highest) || needToRing ||
                    439:                        (terminalCursorAddress != CorrectTerminalCursor())) {
                    440:        TryToSend();
                    441:     }
                    442:     if (Lowest > Highest) {
                    443:        return 1;               /* no more output now */
                    444:     } else {
                    445:        return 0;               /* more output for future */
                    446:     }
                    447: }
                    448: 
                    449: /*
                    450:  * The following are defined to handle transparent data.
                    451:  */
                    452: 
                    453: void
                    454: TransStop()
                    455: {
                    456:     RefreshScreen();
                    457: }
                    458: 
                    459: void
                    460: TransOut(buffer, count, kind, control)
                    461: unsigned char  *buffer;
                    462: int            count;
                    463: int            kind;           /* 0 or 5 */
                    464: int            control;        /* To see if we are done */
                    465: {
                    466:     char *ptr;
                    467: 
                    468:     while (DoTerminalOutput() == 0) {
                    469:        ;
                    470:     }
                    471:     for (ptr = buffer; ptr < buffer+count; ptr++) {
                    472:        *ptr &= 0x7f;           /* Turn off parity bit */
                    473:     }
                    474:     (void) DataToTerminal(buffer, count);
                    475:     if (control && (kind == 0)) {              /* Send in AID byte */
                    476:        SendToIBM();
                    477:     } else {
                    478:        TransInput(1, kind);                    /* Go get some data */
                    479:     }
                    480: }
                    481: 
                    482: /*
                    483:  * init_screen()
                    484:  *
                    485:  * Initialize variables used by screen.
                    486:  */
                    487: 
                    488: void
                    489: init_screen()
                    490: {
                    491:     bellwinup = 0;
                    492: }
                    493: 
                    494: 

unix.superglobalmegacorp.com

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