* Copyright (c) 1984, 1985, 1986 by the Regents of the
* University of California and by Gregory Glenn Minshall.
* Permission to use, copy, modify, and distribute these
* programs and their documentation for any purpose and
* without fee is hereby granted, provided that this
* copyright and permission appear on all copies and
* supporting documentation, the name of the Regents of
* the University of California not be used in advertising
* or publicity pertaining to distribution of the programs
* without specific prior permission, and notice be given in
* supporting documentation that copying and distribution is
* by permission of the Regents of the University of California
* and by Gregory Glenn Minshall. Neither the Regents of the
* University of California nor Gregory Glenn Minshall make
* representations about the suitability of this software
* for any purpose. It is provided "as is" without
* express or implied warranty.
static char sccsid
[] = "@(#)outbound.c 3.1 10/29/86";
#include "../general/general.h"
#include "../ascii/disp_asc.h"
#include "../ascii/map3270.ext"
#include "../ctlr/hostctlr.h"
#include "../ctlr/inbound.ext"
#include "../ctlr/options.ext"
#include "../ctlr/outbound.ext"
#include "../ctlr/screen.h"
#include "../general/globals.h"
extern void EmptyTerminal();
#define CorrectTerminalCursor() ((TransparentClock == OutputClock)? \
terminalCursorAddress:UnLocked? CursorAddress: HighestScreen())
static int terminalCursorAddress
; /* where the cursor is on term */
static int screenInitd
; /* the screen has been initialized */
static int screenStopped
; /* the screen has been stopped */
static int needToRing
; /* need to ring terinal bell */
data
, /* The data for this position */
attr
; /* The attributes for this position */
ScreenBuffer Screen
[MAXNUMBERLINES
*MAXNUMBERCOLUMNS
];
ScreenBuffer saveScreen
[sizeof Screen
/sizeof Screen
[0]];
/* OurExitString - designed to keep us from going through infinite recursion */
OurExitString(file
, string
, value
)
static int recursion
= 0;
ExitString(file
, string
, value
);
char *from
; /* routine that gave error */
int where
; /* cursor address */
sprintf(foo
, "ERR from %s at %d (%d, %d)\n",
from
, where
, ScreenLine(where
), ScreenLineOffset(where
));
OurExitString(stderr
, foo
, 1);
* Routines to deal with the screen. These routines are lifted
#define CRT_STATUS 0x3da /* Color card */
#define DISPLAY_ENABLE 0x08 /* Enable */
#define scrseg() ((crt_mode == 7)? 0xb000 : 0xb800)
#define scrwait() if (crt_mode != 7) { \
while ((inp(CRT_STATUS)&DISPLAY_ENABLE) == 0) { \
* Set the cursor position to where it belongs.
setcursor(row
, column
, page
)
union REGS inregs
, outregs
;
inregs
.h
.ah
= SetCursorPosition
;
int86(BIOS_VIDEO
, &inregs
, &outregs
);
* Read the state of the video system. Put the cursor somewhere
union REGS inregs
, outregs
;
inregs
.h
.ah
= CurrentVideoState
;
int86(BIOS_VIDEO
, &inregs
, &outregs
);
inregs
.h
.ah
= ReadCursorPosition
;
int86(BIOS_VIDEO
, &inregs
, &outregs
);
if (outregs
.h
.dh
> crt_lins
) {
if (outregs
.h
.dl
> crt_cols
) {
inregs
.h
.dh
= outregs
.h
.dh
;
inregs
.h
.dl
= outregs
.h
.dl
;
inregs
.h
.ah
= SetCursorPosition
;
int86(BIOS_VIDEO
, &inregs
, &outregs
);
scrwrite(source
, length
, offset
)
segread(&segregs
); /* read the current segment register */
movedata(segregs
.ds
, source
, scrseg(), sizeof *source
*offset
,
segread(&segregs
); /* read the current segment register */
movedata(scrseg(), 0, segregs
.ds
, buffer
, crt_cols
*crt_lins
*2);
scrwrite(buffer
, crt_cols
*crt_lins
, 0);
#define STANDOUT 0x0a /* Highlighted mode */
#define NORMAL 0x02 /* Normal mode */
#define NONDISPLAY 0x00 /* Don't display */
if (screenIsFormatted) { \
if (IsNonDisplayAttr(a)) { \
a = NONDISPLAY; /* don't display */ \
} else if (IsHighlightedAttr(a)) { \
a = NORMAL; /* do display on unformatted */\
int fieldattr
; /* spends most of its time == 0 or 1 */
int screenIsFormatted
= FormattedScreen();
/* OK. We want to do this a quickly as possible. So, we assume we
* only need to go from Lowest to Highest. However, if we find a
* field in the middle, we do the whole screen.
* In particular, we separate out the two cases from the beginning.
if ((Highest
!= HighestScreen()) || (Lowest
!= LowestScreen())) {
fieldattr
= FieldAttributes(Lowest
);
DoAttribute(fieldattr
); /* Set standout, non-display status */
if (IsStartFieldPointer(p
)) { /* New field? */
Highest
= HighestScreen();
TryToSend(); /* Recurse */
} else if (fieldattr
) { /* Should we display? */
/* Display translated data */
sp
->data
= disp_asc
[GetHostPointer(p
)];
} else { /* Going from Lowest to Highest */
ScreenImage
*End
= &Host
[ScreenSize
]-1;
fieldattr
= FieldAttributes(LowestScreen());
DoAttribute(fieldattr
); /* Set standout, non-display status */
if (IsStartFieldPointer(p
)) { /* New field? */
fieldattr
= FieldAttributesPointer(p
); /* Get attributes */
DoAttribute(fieldattr
); /* Set standout, non-display */
if (fieldattr
) { /* Should we display? */
/* Display translated data */
sp
->data
= disp_asc
[GetHostPointer(p
)];
terminalCursorAddress
= CorrectTerminalCursor();
* We might be here just to update the cursor address.
scrwrite(Screen
+Lowest
, (1+Highest
-Lowest
), Lowest
);
setcursor(ScreenLine(terminalCursorAddress
),
ScreenLineOffset(terminalCursorAddress
), 0);
Lowest
= HighestScreen()+1;
Highest
= LowestScreen()-1;
/* InitTerminal - called to initialize the screen, etc. */
InitMapping(); /* Go do mapping file (MAP3270) first */
if (!screenInitd
) { /* not initialized */
MaxNumberLines
= 24; /* XXX */
MaxNumberColumns
= 80; /* XXX */
scrsave(saveScreen
); /* Save the screen buffer away */
terminalCursorAddress
= SetBufferAddress(0,0);
screenStopped
= 0; /* Not stopped */
/* StopScreen - called when we are going away... */
if (screenInitd
&& !screenStopped
) {
setcursor(NumberLines
-1, 1, 0);
StringToTerminal("\r\n");
/* RefreshScreen - called to cause the screen to be refreshed */
Highest
= HighestScreen();
/* ConnectScreen - called to reconnect to the screen */
/* LocalClearScreen() - clear the whole ball of wax, cheaply */
Lowest
= LowestScreen(); /* everything in sync... */
Highest
= HighestScreen();
* Implement the bell/error message function.
bellwinup
= 0; /* If != 0, length of bell message */
bellpos0
= 0; /* Where error message goes */
static char bellstring
[100];/* Where message goes */
#define BELL_SPACES 2 /* 2 spaces between border and bell */
#define BELL_HIGH_LOW(h,l) { \
h = bellpos0+2*NumberColumns+bellwinup+BELL_SPACES*2; \
BELL_HIGH_LOW(Highest
,Lowest
);
if (len
> sizeof bellstring
-1) {
OurExitString(stderr
, "Bell string too long.", 1);
memcpy(bellstring
, s
, len
+1);
BELL_HIGH_LOW(Highest
,Lowest
);
/* returns a 1 if no more output available (so, go ahead and block),
or a 0 if there is more output available (so, just poll the other
sources/destinations, don't block).
/* called just before a select to conserve IO to terminal */
if (!(screenInitd
||screenStopped
)) {
return 1; /* No output if not initialized */
if ((Lowest
<= Highest
) || needToRing
||
(terminalCursorAddress
!= CorrectTerminalCursor())) {
return 1; /* no more output now */
return 0; /* more output for future */
* The following are defined to handle transparent data.
while (DoTerminalOutput() == 0) {
(void) DataToTerminal(buffer
, count
);
* Initialize variables used by screen.