/* * Windows H19 Terminal Emulator * * Written by William S. Hall * 3665 Benton Street, #66 * Santa Clara, CA 95051 * * Program entry module */ #define NOKANJI #define NOATOM #include #include #define EXTERN #define INITIALIZE #include "winasc.h" #include "winh19.h" #include "win19d.h" #if defined(KERMIT) #include "winkpf.h" extern krmState; #endif static BOOL NEAR OutputKeydown(BYTE str[], int *plen, WORD wparam); static void NEAR ScanForEscapes(BYTE *str, int *len); static void NEAR SetScrollState(void); /* Entry point */ int FAR PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow) HANDLE hInstance, hPrevInstance; LPSTR lpszCmdLine; short cmdShow; { if (!InitProgram(hInstance,hPrevInstance, lpszCmdLine, cmdShow)) return FALSE; while (TRUE) if (!DoMessage()) ProcessComm(); } /* Main window procedure */ long FAR PASCAL MainWndProc(hWnd,message,wParam,lParam) HWND hWnd; unsigned message; WORD wParam; LONG lParam; { PAINTSTRUCT ps; switch(message) { case WM_CHANGECBCHAIN: if (wParam == hWndNext) hWndNext = LOWORD(lParam); SendMessage(hWndNext, message, wParam, lParam); break; case WM_DRAWCLIPBOARD: if (IsWindow(hWndNext)) SendMessage(hWndNext, message, wParam, lParam); if (OpenClipboard(hWnd)) { HMENU hMenu = GetMenu(hWnd); hClipData = GetClipboardData(CF_TEXT); if (hClipData != NULL) EnableMenuItem(hMenu, IDM_PASTE, MF_ENABLED); else EnableMenuItem(hMenu, IDM_PASTE, MF_GRAYED); CloseClipboard(); } break; case WM_CREATE: MainWndCreate(hWnd,lParam); break; case WM_KEYDOWN: if (!CD.KeyboardDisabled) H19LocalKeyDown(wParam); break; case WM_CHAR: if (!CD.KeyboardDisabled) H19StringInput((BYTE *)&wParam,(short)1); break; case WM_SETFOCUS: CD.OwnCaret = TRUE; if (IsWindowEnabled(hWnd) && IsWindow(hWndActive)) { SendMessage(hWndActive, WH19_CARETFUNCTION, H19_CREATECARET, (LONG)CD.OwnCaret); } break; case WM_KILLFOCUS: if (IsWindow(hWndActive)) { SendMessage(hWndActive,WH19_CARETFUNCTION,H19_DESTROYCARET, (LONG)CD.OwnCaret); } CD.OwnCaret = FALSE; break; case WM_COMMAND: WndCommand(hWnd, wParam, lParam); break; case WM_MOVE: MW.SCTopTextLine = HIWORD(lParam); MW.SCBottomTextLine = MW.SCTopTextLine + MW.BottomTextLine; break; case WM_SIZE: SizeWindow(LOWORD(lParam), HIWORD(lParam), wParam); break; case WM_CLOSE: CloseCommPort(hWnd, &cid); ChangeClipboardChain(hWnd, hWndNext); DestroyWindow(hWnd); break; case WM_ENDSESSION: if (wParam) CloseCommPort(hWnd, &cid); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: BeginPaint(hWnd, (LPPAINTSTRUCT)&ps); MainWndPaint(hWnd, ps.hdc); EndPaint(hWnd, (LPPAINTSTRUCT)&ps); break; case WM_SYSCOMMAND: return((long)MainSysCommand(hWnd, message, wParam,lParam)); default: return ((long)DefWindowProc(hWnd,message,wParam,lParam)); } return(0L); } /* Subclass window procedure */ LONG FAR PASCAL MainWndSubclassProc(hWnd, message, wParam, lParam) HWND hWnd; unsigned message; WORD wParam; LONG lParam; { BYTE outstr[80]; int len = 0; register BOOL CheckForControl = FALSE; switch(message) { case WM_CHAR: #if defined(KERMIT) if (!(CD.KeyboardDisabled || krmState)) #else if (!CD.KeyboardDisabled) #endif outstr[len++] = (BYTE)wParam; break; case WM_KEYDOWN: if (wParam == VK_CANCEL) { if (CD.BreakFlag == -1) CD.BreakFlag = SetCommBreak(cid); break; } else if (wParam == VK_SCROLL) { SetScrollState(); break; } #if defined(KERMIT) if (!(CD.KeyboardDisabled || krmState)) { #else if (!CD.KeyboardDisabled) { #endif switch(wParam) { case VK_BACK: if (GetKeyState(VK_CONTROL) & 0x8000) outstr[len++] = DEL; break; default: CheckForControl = OutputKeydown(outstr, &len, wParam); break; } } break; case WM_COMMAND: if ((wParam >= IDM_F1) && (wParam <= IDM_CSF12)) { #if defined(KERMIT) if (!(CD.KeyboardDisabled || krmState)) { #else if (!CD.KeyboardDisabled) { #endif char *tptr; int sparam, index; sparam = (wParam /100) * 100; index = wParam - sparam; switch (sparam) { case IDM_F1: tptr = szFKey[index]; break; case IDM_SF1: tptr = szSFKey[index]; break; case IDM_CF1: tptr = szCFKey[index]; break; case IDM_CSF1: tptr = szCSFKey[index]; break; } len = GetProfileString((LPSTR)szAppName,(LPSTR)tptr, (LPSTR)"",(LPSTR)outstr,80); ScanForEscapes(outstr, &len); break; } break; } return(CallWindowProc(fpTerminal,hWnd,message,wParam,lParam)); case WM_KEYUP: if (wParam == VK_CANCEL) { ClearCommBreak(cid); CD.BreakFlag = -1; break; } default: return(CallWindowProc(fpTerminal,hWnd,message,wParam,lParam)); } if (CheckForControl) if (GetKeyState(VK_CONTROL) & 0x8000) return(CallWindowProc(fpTerminal,hWnd,message,wParam,lParam)); if (len) { WriteToPort(cid, (BYTE FAR *)outstr, len); if (!CD.FullDuplex) return(CallWindowProc(fpTerminal,hWnd,message,wParam,lParam)); } return 0L; } static BOOL NEAR OutputKeydown(BYTE str[], int *plen, WORD wparam) { register BOOL result = FALSE; register int index; str[(*plen)++] = ESC; if (CD.ANSIMode) str[(*plen)++] = '['; switch(wparam) { case VK_UP: str[(*plen)++] = 'A'; result = TRUE; break; case VK_DOWN: str[(*plen)++] = 'B'; result = TRUE; break; case VK_RIGHT: str[(*plen)++] = 'C'; result = TRUE; break; case VK_LEFT: str[(*plen)++] = 'D'; result = TRUE; break; case VK_HOME: if (CD.ANSIMode) { str[(*plen)++] = '4'; if (CD.ICToggle) str[(*plen)++] = 'l'; else str[(*plen)++] = 'h'; } else { if (CD.ICToggle) str[(*plen)++] = 'O'; else str[(*plen)++] = '@'; } result = TRUE; break; case VK_END: str[(*plen)++] = 'L'; result = TRUE; break; case VK_PRIOR: if (CD.ANSIMode) str[(*plen)++] = 'P'; else str[(*plen)++] = 'N'; result = TRUE; break; case VK_NEXT: str[(*plen)++] = 'M'; result = TRUE; break; case VK_CLEAR: str[(*plen)++] = 'H'; result = TRUE; break; case VK_F1: case VK_F2: case VK_F3: case VK_F4: case VK_F5: case VK_F7: case VK_F8: case VK_F9: if (wparam >= VK_F7) index = 'P' + wparam - VK_F7; else index = 'S' + wparam - VK_F1; if (CD.ANSIMode) str[*plen - 1] = 'O'; str[(*plen)++] = (BYTE)index; break; case VK_F6: if (GetKeyState(VK_SHIFT) & 0x8000) { if (CD.ANSIMode) { str[(*plen)++] = '2'; str[(*plen)++] = 'J'; } else str[(*plen)++] = 'E'; } else str[(*plen)++] = 'J'; result = TRUE; break; case VK_NUMPAD0: case VK_NUMPAD1: case VK_NUMPAD2: case VK_NUMPAD3: case VK_NUMPAD4: case VK_NUMPAD5: case VK_NUMPAD6: case VK_NUMPAD7: case VK_NUMPAD8: case VK_NUMPAD9: case VK_DECIMAL: if (CD.AltKeypad) { if (CD.ANSIMode) str[*plen - 1] = 'O'; else str[(*plen)++] = '?'; if (wparam == VK_DECIMAL) str[(*plen)++] = 'n'; else str[(*plen)++] = (BYTE)('p' + (wparam - VK_NUMPAD0)); } else *plen = 0; break; default: *plen = 0; break; } return(result); } static void NEAR ScanForEscapes(BYTE *str, int *len) { register int i, j; int inlen = min(*len, 79); BYTE buf[80], ch; for (i = 0, j = 0; i < inlen; i++) { if ((ch = str[i]) == '\\') { ch = str[++i]; if (('@' <= ch) && (ch <= '[')) ch ^= 64; } buf[j++] = ch; } buf[j] = NUL; strcpy(str, buf); *len = j; } static void NEAR SetScrollState() { CD.ScrollLock = GetKeyState(VK_SCROLL) & 1; if (GetKeyState(VK_SHIFT) & 0x8000) CD.ReleaseCount = TW.MaxLines - 1; else CD.ReleaseCount = 0; } void BroadcastWinIniChange() { SendMessage((HWND)-1, WM_WININICHANGE, 0, (LONG)(LPSTR)szAppName); }