From 6d6bb88a0215b87a4a47ed86a84ae3c75d399962 Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Sun, 24 Apr 2016 18:05:02 -0400 Subject: Initial import of 5.0 source code with minor changes to use termios on Linux. --- vdu.c | 790 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 790 insertions(+) create mode 100644 vdu.c (limited to 'vdu.c') diff --git a/vdu.c b/vdu.c new file mode 100644 index 0000000..f08ff57 --- /dev/null +++ b/vdu.c @@ -0,0 +1,790 @@ +/*Copyright (c) Anker Berg-Sonne, 1985,1986,1987*/ +/* + Program Logic + + VDU implements an algorithm for minimizing character +transmission to ANSI VDU terminals. This is acheived by using a +database of prior output to the screen and eliminating +repainting. Cursor positioning is also made carefully to avoid +unnecessary character output. +*/ + +#include "proto.h" + +#if (defined(DOS) & !defined(Windows)) | defined(OS2) +#define reverse 1 +#define nobold 2 +#define nounderscore 4 +#define noblink 8 +#endif + +/*Functions*/ + +/* Output a single character to the screen. The character is buffered + and a call to Out_Zap need to be made to ensure that it is physically + written. +*/ +void Fast Out_C(char C) +{if (Out_Count==Out_Size-1) + Out_Zap(); + Out_String[Out_Count++]=C; +} + +/* Output and integer to the screen. The output is made by calls to + Out_C. +*/ +void Fast Out_I(int I) +{if (I>=10) + {Out_I(I/10); + Out_C((char)('0'+I%10)); + } else + if (I>0) + Out_C((char)('0'+I)); +} + +/* Output a null terminated string to the screen. The characters are + buffered and a call to Out_Zap needs to be made to ensure that the + output is physically writtem. +*/ +void Fast Out_S(char *S) +{char C; + while ((C=(*S++))!=0) + {if (Out_Count==Out_Size-1) + Out_Zap(); + Out_String[Out_Count++]=C; + } +} + +/* Ensure that all output is physically written. In several + implementations there are two output streams. One by video firmware + calls and the other through normal character output routines. +*/ +void Fast Out_Zap() +{ +#if defined(DOS) & !(defined(Windows) | defined(TV)) + if (Zap_Count) + { +#if defined(PC100) + High_Out(St_Line,St_Col,Output,Attr,Zap_Count); +#else + if (Dir_Video) + Dir_Out(Top_Row+Sub_X+St_Line-1,Left_Col+Sub_Y+St_Col-1,(char far *)Output, + Attab[His_Attributes],Zap_Count); else + {register char *S; + S=Output; + while (Zap_Count--) + {IBMcursor(Top_Row+Sub_X+St_Line-1,Left_Col+Sub_Y+(St_Col++)-1); + IBMcout(1,*(S++),Attab[His_Attributes]); + } + IBMcursor(Top_Row+Sub_X+His_Line-1,Left_Col+Sub_Y+His_Col-1); + } +#endif + St_Line=St_Col=Zap_Col=Zap_Line=Zap_Count=0; + } +#endif +#if defined(OS2) + if (Zap_Count) + {VioWrtCharStrAtt((char far *)Output,Zap_Count,Sub_X+St_Line-1+Top_Row, + Sub_Y+St_Col-1+Left_Col,(char far *)Attab+His_Attributes,0); + St_Line=St_Col=Zap_Col=Zap_Line=Zap_Count=0; + } +#endif + if (Out_Count) + { +#if (defined(DOS) & ! (defined(Windows) | defined(TV))) | defined(OS2) + Out_String[Out_Count]=0; + fputs(Out_String,stdout); +#endif +#if defined(UNIX) + Out_String[Out_Count]=0; +#if defined(TERMCAP) + fputs(Out_String,stdout); + fflush(stdout); +#else + addstr(Out_String); +#endif +#endif +#if defined(MPE) + FWRITE(mpe_stdout,Out_String,-Out_Count,0320); +#endif +#if defined(ATARI) +#if ! defined(GEM) + {register int I; + register char *S; + S=Out_String; + I=Out_Count; + while (I--) + Bconout(2,*(S++)); + } +#else + Out_String[Out_Count]=0; + GEM_Text(S_Line,S_Col,Out_String,His_Attributes); +#endif +#endif +#if (defined(DOS) | defined(NT)) & defined(Windows) + Out_String[Out_Count]=0; + WinText(S_Line,S_Col,Out_String,His_Attributes); +#endif +#if defined(DOS) & defined(TV) + Out_String[Out_Count]=0; + TV_Text(S_Line,S_Col,Out_String,Attab[His_Attributes]); +#endif +#if defined(VMS) + T$Put(Out_String,Out_Count); +#endif + Out_Count=0; + } +} + +/* Initialize the screen optimization database and clear the screen. +*/ +void Fast Opt_Init() +{ + {register int Line; + for (Line=1;Line<=Scr_Length;++Line) + { +#if defined(VMS) | defined(ATARI) | defined(UNIX) | defined(MPE) + Space_Fill(My_Screen[Line+Top_Row]+1+Left_Col,Scr_Width); + Zero_Fill(My_Attributes[Line+Top_Row]+1+Left_Col,Scr_Width); + Lst_Col[Line+Top_Row]=0; +#else + Lst_Col[Line]=0; +#endif + } + } +#if defined(DOS) & !(defined(Windows) | defined(TV)) & !defined(PC100) + IBMpage(0); +#endif +#if (defined(DOS) & !defined(Windows)) | defined(OS2) +#if !defined(TV) + St_Line=St_Col=Zap_Col=Zap_Line=Zap_Count=0; +#endif + {register int I, At; + for (I=0;I<16;I++) + if (Attab[I]==0) + { +#if !(defined(PC100) | defined(TV)) + if (I&A_Reverse) + {if (I&A_Bold) + {if (I&A_Underline) + At=Color?113:112; else + At=Color?113:112; + } else + {if (I&A_Underline) + At=Color?33:120; else + At=Color?33:120; + } + } else + {if (I&A_Bold) + {if (I&A_Underline) + At=Color?31:9; else + At=Color?31:15; + } else + {if (I&A_Underline) + At=Color?23:1; else + At=Color?23:7; + } + } + if (I&A_Blink) + At+=128; +#elif defined(TV) + if (I&A_Reverse) + {if (I&A_Bold) + {if (I&A_Underline) + At=7; else + At=7; + } else + {if (I&A_Underline) + At=7; else + At=7; + } + } else + {if (I&A_Bold) + {if (I&A_Underline) + At=6; else + At=6; + } else + {if (I&A_Underline) + At=6; else + At=6; + } + } +#else + At=0; + if (I&A_Reverse) + At=reverse; + if (!(I&A_Bold)) + At+=nobold; + if (!(I&A_Underline)) + At+=nounderscore; + if (!(I&A_Blink)) + At+=noblink; +#endif + Attab[I]=At; + } + } +#endif + Clr_Screen(); + Set_Cursor(1,1); + Set_Scroll(1,Scr_Length); + Opt_Force_Attributes((char)(Cur_Attributes=0)); +} + +#if defined(Noasm) | defined(DOS) | defined(NT) | defined(ATARI) | defined(OS2) | defined(UNIX) | defined(MPE) +/* Fill the area pointed to by Cp by N spaces. +*/ +void Fast Space_Fill(char *Cp,int N) +{ +#if !defined(Noasm) +#if defined(DOS) | defined(NT) | defined(OS2) | defined(UNIX) + memset(Cp,' ',N); +#endif +#if defined(ATARI) | defined(MPE) + setmem(Cp,N,' '); +#endif +#else + register char *L_Cp; + L_Cp=Cp; + N++; + while (--N) + (*L_Cp++)=' '; +#endif +} + +/* Fill the area pointed to by Cp with N null characters. +*/ +void Fast Zero_Fill(char *Cp,int N) +{ +#if !defined(Noasm) +#if defined(DOS) | defined(NT) | defined(OS2) | defined(UNIX) + memset(Cp,0,N); +#endif +#if defined(ATARI) | defined(MPE) + setmem(Cp,N,0); +#endif +#else + register char *L_Cp; + L_Cp=Cp; + N++; + while (--N) + (*L_Cp++)=0; +#endif +} +#endif + +/* Set the virtual cursor position to Line and Col. +*/ +void Fast Opt_Cursor(int Line,long Col) +{My_Line=Line; + My_Col=Col; +} + +/* Output a character to the screen and update the cursor position. This + routine can only be used for printable characters. +*/ +void Fast Put_Char(char C) +{if (Out_Count==Out_Size-1) + Out_Zap(); + Out_String[Out_Count++]=C; + His_Col++; +#if defined(UNIX) + if (His_Col>Scr_Width) + Set_Cursor(His_Line,--His_Col); +#endif +} + +/* Move the physical cursor to Line and Col. The move is made with as few + characters output as possible. +*/ +void Fast Opt_Move_Cursor(int Line,long Col) +{ +#if !((defined(ATARI) & defined(GEM)) | defined(MPE)) +#if !(defined(DOS) | defined(NT) | defined(OS2)) + char *Scr, *Atr; +#endif + if (Col<=Scr_Shift) + Col=1; else + Col-=Scr_Shift; + if (Col>Scr_Width) + Col=Scr_Width; +#if !(defined(DOS) | defined(NT) | defined(OS2) | (defined(UNIX) & !defined(TERMCAP))) + Scr=(&My_Screen[His_Line+Top_Row][His_Col+Left_Col]); + Atr=(&My_Attributes[His_Line+Top_Row][His_Col+Left_Col]); + if (Line==His_Line) + {if (Col>His_Col) + {if (Col-His_Col<4) + {while (His_Col!=Col) + {if (*Atr!=His_Attributes) + {Move_Right((int)Col); + break; + } else + Put_Char(*Scr); + Scr++; + Atr++; + } + } else + Move_Right((int)Col); + } else + if (ColScr_Width) + Set_Cursor(Line,(int)Col); else + if (His_Col-Col<4) + {do + Out_C('\b'); + while ((--His_Col)!=Col); + } else + Move_Left((int)Col); + } + } else + if (Line==His_Line+1&&His_Line!=Scl_Bottom) + {if (Zoomed&&Col<6) + {Out_C(10); + Out_C(13); + His_Line=Line; + His_Col=1; + Scr=(&My_Screen[His_Line+Top_Row][His_Col+Left_Col]); + Atr=(&My_Attributes[His_Line+Top_Row][His_Col+Left_Col]); + while (His_Col!=Col) + {if (*Atr!=His_Attributes) + {Move_Right((int)Col); + break; + } else + Put_Char(*Scr); + Scr++; + Atr++; + } + } else + Set_Cursor(Line,(int)Col); + } else + Set_Cursor(Line,(int)Col); +#else + Set_Cursor(Line,(int)Col); +#endif +#else + if (Col<=Scr_Shift) + Col=1; else + Col-=Scr_Shift; + if (Col>Scr_Width) + Col=Scr_Width; + Set_Cursor(Line,(int)Col); +#endif +} + +/* Insert a character into the screen database at the virtual cursor + position. Whether the character is physically written depends on + the current contents of the physical screen. +*/ +void Fast Opt_Char(char C) +/*Put a single character on the screen*/ +{int Sav_Attributes; + long Sav_Col; +#if defined(VMS) | defined(ATARI) | defined(UNIX) | defined(MPE) + register char *Scr, *Atr; + if (!Update_Flag) + {My_Col++; + return; + } + Sav_Attributes=Cur_Attributes; + if ((Scr_Col=My_Col-Scr_Shift)<1) + {My_Col++; + return; + } + if (Scr_Col+Left_Col>=Phys_Width&&My_Line+Top_Row==Phys_Length) + {My_Col++; + return; + } + if (Scr_Col>Scr_Width) + {if (Scr_Col==Scr_Width+1) + {Sav_Col=My_Col; + My_Col=Scr_Width+Scr_Shift; + Cur_Attributes=A_Reverse; + Opt_Char('>'); + My_Col=Sav_Col; + Cur_Attributes=Sav_Attributes; + } + My_Col++; + return; + } + Scr=(&My_Screen[My_Line+Top_Row][Scr_Col+Left_Col]); + Atr=(&My_Attributes[My_Line+Top_Row][Scr_Col+Left_Col]); + if (*Scr!=C||*Atr!=Cur_Attributes) + {if ((Scr_Col!=His_Col)||(My_Line!=His_Line)) + Opt_Move_Cursor(My_Line,My_Col); + if (His_Attributes!=Cur_Attributes) + Opt_Force_Attributes(Cur_Attributes); + if (Out_Count==Out_Size-1) + Out_Zap(); +#if defined(ATARI) & defined(GEM) + if (Out_Count==0) + {S_Line=My_Line; + S_Col=Scr_Col; + } +#endif + Out_String[Out_Count++]=(*Scr)=C; + (*Atr)=Cur_Attributes; + if (C!=' '||Cur_Attributes) + {if (Scr_Shift) + {if (Lst_Col[My_Line+Top_Row]Scr_Shift) + Lst_Col[My_Line+Top_Row]=My_Col-Scr_Shift; + } else + {if (Lst_Col[My_Line+Top_Row]Scr_Width) + Set_Cursor(His_Line,His_Col=Scr_Width); + } +#endif +#if (defined(DOS) | defined(NT)) & defined(Windows) + if (!Update_Flag) + {My_Col++; + return; + } + Sav_Attributes=Cur_Attributes; + if ((Scr_Col=My_Col-Scr_Shift)<1) + {My_Col++; + return; + } + if (Scr_Col>Scr_Width) + {if (Scr_Col==Scr_Width+1) + {Sav_Col=My_Col; + My_Col=Scr_Width+Scr_Shift; + Cur_Attributes=A_Reverse; + Opt_Char('>'); + My_Col=Sav_Col; + Cur_Attributes=Sav_Attributes; + } + My_Col++; + return; + } + if ((Scr_Col!=His_Col)||(My_Line!=His_Line)) + Opt_Move_Cursor(My_Line,My_Col); + if (His_Attributes!=Cur_Attributes) + Opt_Force_Attributes((char)Cur_Attributes); + if (Out_Count==Out_Size-1) + Out_Zap(); + if (Out_Count==0) + {S_Line=My_Line; + S_Col=Scr_Col; + } + Out_String[Out_Count++]=C; + if (C!=' '||Cur_Attributes) + {if (Scr_Shift) + {if (Lst_Col[My_Line]Scr_Shift) + Lst_Col[My_Line]=My_Col-Scr_Shift; + } else + {if (Lst_Col[My_Line]Scr_Width) + {if (Scr_Col==Scr_Width+1) + {Sav_Col=My_Col; + My_Col=Scr_Width+Scr_Shift; + Cur_Attributes=A_Reverse; + Opt_Char('>'); + My_Col=Sav_Col; + Cur_Attributes=Sav_Attributes; + } + My_Col++; + return; + } + Scr=(&My_Screen[My_Line+Top_Row][Scr_Col+Left_Col]); + Atr=(&My_Attributes[My_Line+Top_Row][Scr_Col+Left_Col]); + if ((Scr_Col!=His_Col)||(My_Line!=His_Line)) + Opt_Move_Cursor(My_Line,My_Col); + if (His_Attributes!=Cur_Attributes) + Opt_Force_Attributes((char)Cur_Attributes); + if (Out_Count==Out_Size-1) + Out_Zap(); + if (Out_Count==0) + {S_Line=My_Line; + S_Col=Scr_Col; + } + *Scr=Out_String[Out_Count++]=C; + *Atr=Cur_Attributes; + if (C!=' '||Cur_Attributes) + {if (Scr_Shift) + {if (Lst_Col[My_Line]Scr_Shift) + Lst_Col[My_Line]=My_Col-Scr_Shift; + } else + {if (Lst_Col[My_Line]Scr_Width) + {if (Scr_Col==Scr_Width+1) + {Sav_Col=My_Col; + My_Col=Scr_Width+Scr_Shift; + Cur_Attributes=A_Reverse; + Opt_Char('>'); + My_Col=Sav_Col; + Cur_Attributes=Sav_Attributes; + } + My_Col++; + return; + } +#if defined(PC100) + if (!Dir_Video) + {if ((Scr_Col!=His_Col)||(My_Line!=His_Line)) + Opt_Move_Cursor(My_Line,My_Col); + if (Cur_Attributes!=His_Attributes) + Opt_Force_Attributes(Cur_Attributes); + Out_C(C); + His_Col++; + if (C!=' '||Cur_Attributes) + {if (Scr_Shift) + {if (Lst_Col[My_Line]Scr_Shift) + Lst_Col[My_Line]=My_Col-Scr_Shift; + } else + {if (Lst_Col[My_Line]Scr_Shift) + Lst_Col[My_Line]=My_Col-Scr_Shift; + } else + {if (Lst_Col[My_Line]Scr_Shift) + Lst_Col[My_Line]=My_Col-Scr_Shift; + } else + {if (Lst_Col[My_Line]Scr_Width) + {if (Scr_Col==Scr_Width+1) + {Sav_Col=My_Col; + My_Col=Scr_Width+Scr_Shift; + Cur_Attributes=A_Reverse; + Opt_Char('>'); + My_Col=Sav_Col; + Cur_Attributes=Sav_Attributes; + } + My_Col++; + return; + } + if (Cur_Attributes!=His_Attributes) + Opt_Force_Attributes(Cur_Attributes); + if (Out_Count) + Out_Zap(); + if (!Zap_Count) + {St_Line=My_Line; + St_Col=Zap_Col=Scr_Col; + Zap_Line=My_Line; + } else + if (Zap_Col!=Scr_Col||Zap_Line!=My_Line||Zap_Count==132) + {Out_Zap(); + St_Line=My_Line; + St_Col=Zap_Col=Scr_Col; + Zap_Line=My_Line; + } + Output[Zap_Count]=C; + Attr[Zap_Count++]=Attab[Cur_Attributes]; + if (C!=' '||Cur_Attributes) + {if (Scr_Shift) + {if (Lst_Col[My_Line]Scr_Shift) + Lst_Col[My_Line]=My_Col-Scr_Shift; + } else + {if (Lst_Col[My_Line]Scr_Shift) + Lst_Col[My_Line+Top_Row]=My_Col-Scr_Shift; + } + His_Col++; + My_Col++; + } +} +#endif + +/* Output a null terminated string to the virtual screen. +*/ +void Fast Opt_String(char *S) +{register char C; + if (S==NULL) + return; + while ((C=(*S++))!=0) + Opt_Char(C); +} + +/* Erase the virtual screen from the current virtual cursor position + to the end of the line. +*/ +void Fast Opt_Erase_Line() +/*Erases from cursor to end of line*/ +{register int This_Last; + char Sav_Attributes; + if (!Update_Flag) + return; + Sav_Attributes=Cur_Attributes; + Cur_Attributes=0; +#if defined(VMS) | defined(UNIX) | defined(ATARI) | defined(MPE) + if ((This_Last=Lst_Col[My_Line+Top_Row])>=My_Col-Scr_Shift) +#else + if ((This_Last=Lst_Col[My_Line])>=My_Col-Scr_Shift) +#endif + {if (This_Last>0) + {Scr_Col=My_Col-Scr_Shift; + if (Scr_Col<1) + Scr_Col=1; + Del_To_End_Line(); +#if defined(VMS) | defined(ATARI) | defined(UNIX) | (defined(DOS) & defined(TV)) | defined(MPE) + Space_Fill(My_Screen[My_Line+Top_Row]+Scr_Col+Left_Col,This_Last-Scr_Col+1); + Zero_Fill(My_Attributes[My_Line+Top_Row]+Scr_Col+Left_Col, + This_Last-Scr_Col+1); +#endif + } +#if defined(VMS) | defined(UNIX) | defined(ATARI) | defined(MPE) + if ((Lst_Col[My_Line+Top_Row]=My_Col-Scr_Shift-1)<0) + Lst_Col[My_Line+Top_Row]=0; +#else + if ((Lst_Col[My_Line]=My_Col-Scr_Shift-1)<0) + Lst_Col[My_Line]=0; +#endif + } + Cur_Attributes=Sav_Attributes; +} + +#if defined(DOS) +void Fast Get_Type() +{if (Call_Type==0) + { +#if defined(Windows) + Call_Type=0xFC; + Call_Model=0x1; +#else + Call_Type=GETTYP(); + if (Call_Type==0xFC&&Call_Model==0) + Call_Model=pc_sys_type()>>8; +#endif + } +} +#endif + +#if defined(OS2) +void Get_Type() +{unsigned char Item; + struct _VIOMODEINFO Mode_Data; + if (Call_Type==0) + {DosDevConfig((PVOID)&Item,5,0); + Call_Type=Item; + } + if (Call_Model==0) + {DosDevConfig((unsigned char far *)&Item,4,0); + Call_Model=Item; + } + if (Call_Color==0) + {DosDevConfig((unsigned char far *)&Item,6,0); + Call_Color=Item+1; + } + Color=Call_Color==2; + Mode_Data.cb=12; + VioGetMode((PVIOMODEINFO)&Mode_Data,0); + Scr_Length=Mode_Data.row; +} +#endif -- cgit v1.2.3