/* * 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 #include #include #include #include #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; } }