home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
win100.zip
/
win19n.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-20
|
19KB
|
652 lines
/*
* 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;
}
}