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

unix.superglobalmegacorp.com

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