/*
 * Windows H19 Terminal Emulator Initialization Module
 * 
 * Written by William S. Hall
 *	      3665 Benton Street, #66
 *	      Santa Clara, CA 95051
 */

#define NOMINMAX
#define NOATOM
#define NOKANJI
#include <windows.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

#include "winasc.h"
#include "winh19.h"
#include "win19d.h"

#if defined(KERMIT)
#include "winkpf.h"
extern krmState;
#endif

/* default lines and columns */
static int lines = H19LINES;
static int columns = H19COLS;

/* local functions */
static void NEAR GetCurrentInstanceData(HANDLE);
static void NEAR GetPrevInstanceData(HANDLE);
static HFONT NEAR GetFontInfo(HANDLE, short *, short *);
static BOOL NEAR RegisterMainWindow(HANDLE);
static BOOL NEAR RegisterTermWindow(HANDLE);
static BOOL NEAR RegisterStatusWindow(HANDLE);
static BOOL NEAR MakeAndShowMainWindow(HANDLE, short);
static BOOL NEAR MakeAndShowTermWindow(HANDLE);
static BOOL NEAR MakeAndShowStatusWindow(HANDLE);
static BOOL NEAR GetDefaultSettings(HANDLE);
static BOOL NEAR OpenAndSetCommPort(HANDLE);
static void NEAR LoadSpecialKeys(HANDLE hInstance, int base, char *key[]);

/* search keystrings for match */
BOOL NEAR SearchKey(char *str, char *key, int len)
{
    int i;
    char *startptr;
    startptr = str;

    for (i = 0; i < len; i++) {
	if (*str++)
	    ;
	else {
	    if (strcmp(key, startptr) == 0)
		return(TRUE);
	    startptr = str;
	}
    }
    return (FALSE);
}

/* init entry */
BOOL FAR InitProgram(hInstance,hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
short cmdShow;
{

    char ch;
    LPSTR lptr;
    int i, len;

    hInst = hInstance;
    hPrevInst = hPrevInstance;
    cid = INT_MIN;
    
    len = 0;
    lptr = lpszCmdLine;
    while (ch = *lptr++)
	if (isspace(ch))
	    break;
	else
	    len++;

    if (hCommandLine = LocalAlloc(LPTR, len + 1)) {
	pCommandLine = LocalLock(hCommandLine);
	for (i = 0; i < len; i++)
	    *(pCommandLine + i) = *(lpszCmdLine + i);
    }
    *(pCommandLine + len) = NUL;

    if (!hPrevInstance) {

	if (LOBYTE(GetVersion()) < (BYTE)2)
	    return FALSE;

	GetCurrentInstanceData(hInstance);

	if ((CD.hScreenFont = 
	         GetFontInfo(hInstance,&TW.CharWidth, &TW.CharHeight)) == NULL)
	    return FALSE;

	if (!RegisterMainWindow(hInstance))
	    return FALSE;

	if (!RegisterTermWindow(hInstance))
	    return FALSE;

	if (!RegisterStatusWindow(hInstance))
	    return FALSE;

  }
    else
	GetPrevInstanceData(hPrevInstance);

    if (!GetDefaultSettings(hInstance))
	return FALSE;

    if (!MakeAndShowMainWindow(hInstance,cmdShow))
	return FALSE;

#if defined(KERMIT)
    if (!krmInit(MW.hWnd, hInstance))
	return FALSE;
#endif

    if (!MakeAndShowTermWindow(hInstance))
	return FALSE;

    if (!MakeAndShowStatusWindow(hInstance))
	return FALSE;

    if (!OpenAndSetCommPort(hInstance))
	return FALSE;

    hWndNext = SetClipboardViewer(MW.hWnd);
    hWndActive = TW.hWnd;

    fpTerminal = (FARPROC)GetClassLong(MW.hWnd, GCL_WNDPROC);

    SetWindowLong(MW.hWnd, GWL_WNDPROC, (LONG)MainWndSubclassProc);
    CD.LineState = IDM_ONLINE;

    CD.BreakFlag = -1;
    SendMessage(MW.hWnd, WM_SETFOCUS, 0, 0L);

    return TRUE;
}

/* get data from resources */
static void NEAR GetCurrentInstanceData(HANDLE hInstance)
{

    LoadString(hInstance,IDS_APPNAME,(LPSTR)szAppName,sizeof(szAppName));
    LoadString(hInstance,IDS_TERMNAME,(LPSTR)szTermName,sizeof(szTermName));
    LoadString(hInstance,IDS_STATNAME,(LPSTR)szStatName,sizeof(szStatName));
    LoadString(hInstance, IDS_OFFLINE, (LPSTR)szOffline,sizeof(szOffline));
    LoadString(hInstance, IDS_ONLINE, (LPSTR)szOnline, sizeof(szOnline));
    LoadString(hInstance, IDS_WINTITLE, (LPSTR)szWinTitle,sizeof(szWinTitle));
    hAccel = LoadAccelerators(hInstance, (LPSTR)szAppName);
}

/* get data from another running instance */
static void NEAR GetPrevInstanceData(HANDLE hPrevInstance)
{

    GetInstanceData(hPrevInstance, (NPSTR)&CD.hScreenFont, sizeof(HFONT));
    GetInstanceData(hPrevInstance, (NPSTR)&TW.CharWidth, sizeof(short));
    GetInstanceData(hPrevInstance, (NPSTR)&TW.CharHeight, sizeof(short));
    GetInstanceData(hPrevInstance, (PSTR)szAppName, sizeof(szAppName));
    GetInstanceData(hPrevInstance, (PSTR)szTermName, sizeof(szTermName));
    GetInstanceData(hPrevInstance, (PSTR)szStatName, sizeof(szStatName));
    GetInstanceData(hPrevInstance, (PSTR)szOffline, sizeof(szOffline));
    GetInstanceData(hPrevInstance, (PSTR)szOnline, sizeof(szOnline));
    GetInstanceData(hPrevInstance, (PSTR)szWinTitle, sizeof(szWinTitle));
    szWinTitle[strlen(szWinTitle) - 5] = NUL;
    GetInstanceData(hPrevInstance, (PSTR)&hAccel, sizeof(hAccel));
}

/* register main window */
static BOOL NEAR RegisterMainWindow(HANDLE hInstance)
{

    HANDLE hTemp;
    PWNDCLASS pWndClass;

    if (hTemp = LocalAlloc(LPTR,sizeof(WNDCLASS))) {
        if (pWndClass = (PWNDCLASS)LocalLock(hTemp)) {
	    pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
	    pWndClass->hIcon = NULL;
	    pWndClass->lpszMenuName = NULL;
            pWndClass->lpszClassName = (LPSTR)szAppName;
            pWndClass->hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
            pWndClass->hInstance = hInstance;
            pWndClass->style = CS_VREDRAW | CS_HREDRAW;
            pWndClass->lpfnWndProc = MainWndProc;
            pWndClass->cbClsExtra = 0;
            pWndClass->cbWndExtra = 0;
	    if (RegisterClass((LPWNDCLASS)pWndClass)) {
	        LocalUnlock(hTemp);
	        LocalFree(hTemp);
	        return TRUE;
	    }
	}
	return FALSE;
    }
    return FALSE;
}

/* register terminal emulator window */
static BOOL NEAR RegisterTermWindow(HANDLE hInstance)
{

    PWNDCLASS pWndClass;
    HANDLE hTemp;

    if (hTemp = LocalAlloc(LPTR,sizeof(WNDCLASS))) {
        if (pWndClass = (PWNDCLASS)LocalLock(hTemp)) {
	    pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
	    pWndClass->hIcon = NULL;
	    pWndClass->lpszMenuName = NULL;
	    pWndClass->lpszClassName = (LPSTR)szTermName;
	    pWndClass->hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	    pWndClass->hInstance = hInstance;
	    pWndClass->style = CS_VREDRAW | CS_HREDRAW | CS_CLASSDC;
	    pWndClass->lpfnWndProc = TermWndProc;
	    pWndClass->cbClsExtra = 0;
	    pWndClass->cbWndExtra = sizeof(struct TermWndData *);
	    if (RegisterClass((LPWNDCLASS)pWndClass)) {
		LocalUnlock(hTemp);
	        LocalFree(hTemp);
	        return TRUE;
	    }
	}
        return FALSE;
     }
     return FALSE;
}

/* register emulator status window */
static BOOL NEAR RegisterStatusWindow(HANDLE hInstance)
{

    PWNDCLASS pWndClass;
    HANDLE hTemp;

    if (hTemp = LocalAlloc(LPTR,sizeof(WNDCLASS))) {
        if (pWndClass = (PWNDCLASS)LocalLock(hTemp)) {
	    pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
	    pWndClass->hIcon = NULL;
	    pWndClass->lpszMenuName = NULL;
	    pWndClass->lpszClassName = (LPSTR)szStatName;
	    pWndClass->hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	    pWndClass->hInstance = hInstance;
	    pWndClass->style = CS_VREDRAW | CS_HREDRAW | CS_CLASSDC;
	    pWndClass->lpfnWndProc = StatWndProc;
	    pWndClass->cbClsExtra = 0;
	    pWndClass->cbWndExtra = sizeof(struct TermWndData *);
	    if (RegisterClass((LPWNDCLASS)pWndClass)) {
		LocalUnlock(hTemp);
		LocalFree(hTemp);
	        return TRUE;
	    }
	}
	return FALSE;
    }
    return FALSE;
}

/* create main window */
static BOOL NEAR MakeAndShowMainWindow(HANDLE hInstance, short cmdShow)
{

    char szDisplayName[8];

    HMENU hMenu;

    RECT scrnrect;
    short left, top, right, bottom, displayheight, displaywidth;
    HDC hIC;

    scrnrect.left = 0;
    scrnrect.top = 0;
    scrnrect.right = TW.CharWidth * columns;
    scrnrect.bottom = TW.CharHeight * (lines + 1);

    AdjustWindowRect((LPRECT)&scrnrect, (LONG)WS_OVERLAPPEDWINDOW, TRUE);

    left = scrnrect.left;
    top = scrnrect.top;
    right = scrnrect.right - left + 1;
    bottom = scrnrect.bottom - scrnrect.top + 1;

    LoadString(hInstance, IDS_DISPLAYNAME,
			 (LPSTR)szDisplayName,sizeof(szDisplayName));
    hIC = CreateIC((LPSTR)szDisplayName,(LPSTR)NULL, (LPSTR)NULL, (LPSTR)NULL);
    displayheight = GetDeviceCaps(hIC, VERTRES);
    displaywidth = GetDeviceCaps(hIC, HORZRES);
    DeleteDC(hIC);

    if (bottom > displayheight)
	bottom = displayheight;

    if (right > displaywidth)
	right = displaywidth;

    hMenu = LoadMenu(hInstance, (LPSTR)szAppName);

    MW.hWnd = CreateWindow((LPSTR)szAppName,
			     (LPSTR)szWinTitle,
			     WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
			     CW_USEDEFAULT,0,right,bottom,
			     (HWND)NULL,
			     (HMENU)hMenu,
			     (HANDLE)hInstance,
			     (LPSTR)NULL);

    if (MW.hWnd != NULL) {
        ShowWindow(MW.hWnd, cmdShow);
        UpdateWindow(MW.hWnd);
        return TRUE;
    }
    return FALSE;
}

/* create terminal emulation window */
static BOOL NEAR MakeAndShowTermWindow(HANDLE hInstance)
{

    short width, height;

    width = columns * TW.CharWidth;
    height = lines * TW.CharHeight;

    TW.hWnd = CreateWindow((LPSTR)szTermName,
		            (LPSTR)NULL,
			    WS_CHILDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS,
			    0,0,
			    width,height,
			    MW.hWnd,
		            (short)0,
			    (HANDLE)hInstance,
			    (LPSTR)&TW);

    if (TW.hWnd && TW.hVidBuffer)
        return TRUE;

    ShowMessage(MW.hWnd, IDS_CANNOTCREATETERM);
    return FALSE;
}

/* create terminal emulation status window */
static BOOL NEAR MakeAndShowStatusWindow(HANDLE hInstance)
{

    short statpos, statheight;

    SW.CharWidth = TW.CharWidth;
    SW.CharHeight = TW.CharHeight;
    
    statpos = TW.Height;
    statheight = TW.CharHeight;
    CD.StatOverlayTerm = FALSE;

    if ((statpos + statheight) > MW.Height) {
	statpos = MW.BottomTextLine + TW.CharHeight;
	statheight = MW.Height - statpos;
    }

    SW.hWnd = CreateWindow((LPSTR)szStatName,
                     (LPSTR)NULL,
	             WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_VISIBLE,
                     0,statpos,
                     TW.Width,statheight,
		     MW.hWnd,
                     (short)1,
                     hInstance,
                     (LPSTR)&SW);

    if (SW.hWnd && SW.hVidBuffer) {
	BringWindowToTop(SW.hWnd);
	return TRUE;
    }

    ShowMessage(MW.hWnd, IDS_CANNOTCREATESTATUS);
    return FALSE;
}

/* load up function key string ids */
static void NEAR LoadSpecialKeys(HANDLE hInstance, int base, char *key[])
{
    int i;
    char szKeyStr[20];
    HANDLE temp;

    for (i = 0; i < 12; i++) {
        LoadString(hInstance, base+i,(LPSTR)szKeyStr,sizeof(szKeyStr));
	if (temp=LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,strlen(szKeyStr) + 1)) {
            key[i] = LocalLock(temp);
	    strcpy(key[i], szKeyStr);
	}
    }
}

/* read win.ini for default values */
static BOOL NEAR GetDefaultSettings(HANDLE hInstance)
{
#define INITKEYSIZE	1024
#define MAXCOMPORTS	2

    char szKeyStr[80];
    char szMessageStr[80];
    char szDefStr[80];
    HANDLE hInitKeyStr;
    int Initlen;
    char *szInitKeyStr;
    register BOOL WinIniModified = FALSE;
    register int i;
    int reply;
    int *ptr, *ptr1;

    LoadSpecialKeys(hInstance, IDS_SPKEYID1, szFKey);
    LoadSpecialKeys(hInstance, IDS_SSPKEYID1, szSFKey);
    LoadSpecialKeys(hInstance, IDS_CSPKEYID1, szCFKey);
    LoadSpecialKeys(hInstance, IDS_CSSPKEYID1, szCSFKey);

    hInitKeyStr = LocalAlloc(LPTR, INITKEYSIZE);
    if ((szInitKeyStr = LocalLock(hInitKeyStr)) == NULL)
	return FALSE;

    Initlen = GetProfileString(szAppName, (LPSTR)NULL, (LPSTR)"",
			       szInitKeyStr, INITKEYSIZE);
    if (Initlen == 0) {
        LoadString(hInstance,IDS_ADDDEFAULTS,szMessageStr,sizeof(szMessageStr));
        reply = MessageBox(MW.hWnd,szMessageStr,szAppName, 
			   MB_ICONQUESTION | MB_YESNO);
	if (reply == IDNO)
	    return FALSE;
    }

  /* default ports */
    for (i = 0; i < MAXCOMPORTS; i++) {
        LoadString(hInstance,IDS_FIRSTPORT+i,(LPSTR)szKeyStr,sizeof(szKeyStr));
        if (!SearchKey(szInitKeyStr, szKeyStr, Initlen)) {
            LoadString(hInstance,IDS_COM1 + i, szDefStr, sizeof(szDefStr));
	    WinIniModified = TRUE;
	    WriteProfileString(szAppName,szKeyStr,szDefStr);
	}
    }

    for (i = 0; i < MAXCOMPORTS; i++) {
	LoadString(hInstance, IDS_COM1 + i, szKeyStr, sizeof(szKeyStr));
        if (!SearchKey(szInitKeyStr, szKeyStr, Initlen)) {
 	    LoadString(hInstance, IDS_COMMSTR, szDefStr, sizeof(szDefStr));
	    WinIniModified = TRUE;
	    WriteProfileString(szAppName,szKeyStr,szDefStr);
	}
    }

    S402.BlockCursor = FALSE;
    S402.KeyClick = TRUE;
    S402.WrapAround = TRUE;
    S402.LFonCR = FALSE;
    S402.CRonLF = FALSE;
    S402.ANSIMode = FALSE;
    S402.ShiftedKeypad = TRUE;
    S402.FullDuplex = TRUE;

    ptr1 = &S402.BlockCursor;
    ptr = &CD.BlockCursor;
    for (i = 0; i < 8; i++) {
        LoadString(hInstance,IDS_BLOCKCURSOR+i,szKeyStr,sizeof(szKeyStr));
	if (!SearchKey(szInitKeyStr, szKeyStr, Initlen)) {
	    WinIniModified = TRUE;
	    WriteProfileString(szAppName,szKeyStr,itoa(*ptr1,szMessageStr,10));
	}
        *ptr1 = GetProfileInt((LPSTR)szAppName, (LPSTR)szKeyStr, *ptr1);
        *ptr++ = *ptr1++;
    }

    LoadString(hInstance,IDS_LINES,(LPSTR)szKeyStr,sizeof(szKeyStr));
    if (!SearchKey(szInitKeyStr, szKeyStr, Initlen)) {
	WinIniModified = TRUE;
        WriteProfileString(szAppName,szKeyStr,itoa(H19LINES,szMessageStr,10));
    }
    lines = GetProfileInt((LPSTR)szAppName, (LPSTR)szKeyStr, H19LINES);
    lines = min(lines, TERMMAXLINES);

    LoadString(hInstance,IDS_COLUMNS,(LPSTR)szKeyStr,sizeof(szKeyStr));
    if (!SearchKey(szInitKeyStr, szKeyStr, Initlen)) {
	WinIniModified = TRUE;
        WriteProfileString(szAppName,szKeyStr,itoa(H19COLS,szMessageStr,10));
    }
    columns = GetProfileInt((LPSTR)szAppName, (LPSTR)szKeyStr, H19COLS);
    columns = min(columns, TERMMAXCOLS);

    LocalUnlock(hInitKeyStr);
    LocalFree(hInitKeyStr);

    if (WinIniModified)
	BroadcastWinIniChange();

    return TRUE;

}

/* set up comm port */
static BOOL NEAR OpenAndSetCommPort(HANDLE hInstance)
{

    char defcom[6];
    char modestr[20];
    char commstr[30];
    char keystring[20];

    LoadString(hInstance, IDS_FIRSTPORT, (LPSTR)keystring, sizeof(keystring));
    LoadString(hInstance, IDS_COM1, (LPSTR)defcom, sizeof(defcom));
    GetProfileString((LPSTR)szAppName,(LPSTR)keystring, (LPSTR)defcom,
				(LPSTR)commstr,sizeof(commstr));

    if ((cid = OpenComm((LPSTR)commstr,RXQUESIZE,TXQUESIZE)) < 0) {
	LoadString(hInstance,IDS_SECONDPORT,(LPSTR)keystring,sizeof(keystring));
    	LoadString(hInstance, IDS_COM2, (LPSTR)defcom, sizeof(defcom));
        GetProfileString((LPSTR)szAppName,(LPSTR)keystring, (LPSTR)defcom,
				(LPSTR)commstr,sizeof(commstr));
	if ((cid = OpenComm((LPSTR)commstr,RXQUESIZE,TXQUESIZE)) < 0) {
	    ShowMessage(MW.hWnd, IDS_NOCOMOPEN);
	    return FALSE;
	}
    }

    strcat(szWinTitle, commstr);
    SetWindowText(MW.hWnd, (LPSTR)szWinTitle);        

    if (GetCommState(cid, (DCB FAR *)&CommData) >= 0) {
        GetProfileString((LPSTR)szAppName,(LPSTR)commstr,(LPSTR)NULL,
				(LPSTR)modestr,sizeof(modestr));
	strcat(commstr, modestr);
        if (BuildCommDCB((LPSTR)commstr, (DCB FAR *)&CommData) >= 0) {
	    S401.BaudRate = CommData.BaudRate;
	    S401.ByteSize = CommData.ByteSize;
	    S401.Parity = CommData.Parity;
	    S401.StopBits = CommData.StopBits;
	    CommData.XonLim = RXQUESIZE / 8;
	    CommData.XoffLim = RXQUESIZE / 8;
	    CommData.fNull = TRUE; 
	    CommData.XonChar = XON;
	    CommData.XoffChar = XOFF;
	    CommData.fOutX = TRUE; 
	    CommData.fInX = TRUE; 
	    if (SetCommState((DCB FAR *)&CommData) >=0)
	        return TRUE;
	}
    }
    ShowMessage(MW.hWnd,IDS_NOCOMSET);
    CloseComm(cid);
    return FALSE;
}

/* read special font information */
static HFONT NEAR GetFontInfo(hInstance, width, height)
HANDLE hInstance;
short *width, *height;
{

    TEXTMETRIC TM;
    HDC hIC;
    LOGFONT h19font;
    HFONT hFont;
    char szString[20];

    *width = *height = 0;

    h19font.lfHeight = 0;
    h19font.lfWidth = 0;
    h19font.lfEscapement = 0;
    h19font.lfOrientation = 0;
    h19font.lfWeight = 0;
    h19font.lfItalic = 0;
    h19font.lfUnderline = 0;
    h19font.lfStrikeOut = 0;
    h19font.lfCharSet = OEM_CHARSET;
    h19font.lfOutPrecision = OUT_DEFAULT_PRECIS;
    h19font.lfClipPrecision = CLIP_DEFAULT_PRECIS;
    h19font.lfQuality = DEFAULT_QUALITY;
    h19font.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
    LoadString(hInstance, IDS_TERMINAL,(LPSTR)szString,sizeof(szString));
    strncpy(h19font.lfFaceName, szString, LF_FACESIZE-1);
    hFont = CreateFontIndirect((LPLOGFONT)&h19font);
    LoadString(hInstance, IDS_DISPLAYNAME,(LPSTR)szString,sizeof(szString));
    hIC = CreateIC((LPSTR)szString,(LPSTR)NULL, (LPSTR)NULL, (LPSTR)NULL);
    if ((hIC != NULL) && (hFont != NULL)) {
        SelectObject(hIC, hFont);
        GetTextMetrics(hIC, (TEXTMETRIC FAR *)&TM);
        DeleteDC(hIC);
        *width = TM.tmAveCharWidth;
        *height = TM.tmHeight + TM.tmExternalLeading;
    }
    return ((HFONT)hFont);
}

/* called when the main window is created */
void MainWndCreate(HWND hWnd, LONG lParam)
{

    HMENU hMenu;
    char szAbout[10];

    hMenu = GetSystemMenu(hWnd, FALSE);

    ChangeMenu(hMenu, 0, (LPSTR)NULL, -1, MF_APPEND | MF_SEPARATOR);
    LoadString(hInst, IDS_ABOUT, (LPSTR)szAbout,10);
    ChangeMenu(hMenu,0, (LPSTR)szAbout, IDM_ABOUT, MF_APPEND | MF_STRING);

}

/* called when the terminal or stat window is created */
void TermWndCreate(HWND hWnd, LONG lParam)
{

    CREATESTRUCT FAR *pCS;
    struct TermWndData *pTW;

    pCS = (CREATESTRUCT FAR *)lParam;
    pTW = (struct TermWndData *)LOWORD(pCS->lpCreateParams);

    pTW->MaxCols = pCS->cx/pTW->CharWidth;
    pTW->MaxLines = pCS->cy/pTW->CharHeight;
    if (pTW->MaxLines < 1)
	pTW->MaxLines = 1;
    pTW->ScreenSize = pTW->MaxCols * pTW->MaxLines;
    pTW->Width = pTW->MaxCols * pTW->CharWidth;
    pTW->Height = pTW->MaxLines * pTW->CharHeight;    
    SetWindowWord(hWnd, 0, (WORD)pTW);

    pTW->hVidBuffer = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, pTW->ScreenSize);
    if (pTW->hVidBuffer != NULL) {
	pTW->pVidBuffer = LocalLock(pTW->hVidBuffer);
	pTW->oVidLastLine = pTW->MaxCols * (pTW->MaxLines - 1);
        pTW->hDC = GetDC(hWnd);
        if (!hPrevInst)
	    SelectObject(pTW->hDC, CD.hScreenFont);
	pTW->TabLimit = max(pTW->MaxCols - DEF_TABSTOP,0);
	memset(pTW->pVidBuffer, SP, pTW->ScreenSize);
	pTW->oTopLine = pTW->oCurrentLine = pTW->CurLineOffset = 0;
	pTW->oBottomLine = pTW->oVidLastLine;
	pTW->Xpos = pTW->Ypos = 0;
    }
}
