/* * Windows H19 Terminal Emulator - less frequently used functions * * Written by William S. Hall * 3665 Benton Street, #66 * Santa Clara, CA 95051 */ #define NOKANJI #define NOATOM #define NOMINMAX #include #include #include #include #include "winasc.h" #include "winh19.h" #include "win19d.h" /* local functions */ static void NEAR LoadBuf(BYTE FAR *dest, BYTE FAR *source, int count); static void NEAR LoadOneLine(BYTE FAR *, BYTE *, short, BOOL); static void NEAR LoadPrefixAndData(int, int, BYTE *, BYTE FAR *, int); static void NEAR TermParamInit(HWND hDlg); static void NEAR TermParamSet(HWND hDlg); static void NEAR SaveCommParams(void); static void NEAR SetDefaultPort(void); static void NEAR StringOp(HWND hDlg, WORD param); /* about box window procedure */ BOOL FAR PASCAL AboutBoxProc(hDlg, message, wParam, lParam) HWND hDlg; unsigned message; WORD wParam; LONG lParam; { switch (message) { case WM_INITDIALOG: break; case WM_COMMAND: switch (wParam) { case IDOK: case IDCANCEL: EndDialog(hDlg,TRUE); break; default: return FALSE; } break; default: return FALSE; } return TRUE; } /* close communications port */ void CloseCommPort(HWND hWnd, short *pCid) { if (*pCid >=0) { if (CloseComm(*pCid) >= 0) *pCid = INT_MIN; else ShowMessage(hWnd, IDS_CANNOTCLOSECOM); } } /* show message box */ void ShowMessage(HWND hWnd, int msgnum) { char szMessage[80]; LoadString(hInst, msgnum, (LPSTR)szMessage,sizeof(szMessage)); MessageBox(hWnd,(LPSTR)szMessage, (LPSTR)szAppName, MB_ICONHAND | MB_OK); } /* reset the terminal to power up */ void ResetTerminal() { BOOL *ptr, *ptr1; int i; SendMessage(hWndActive,WH19_CARETFUNCTION, H19_DESTROYCARET,(LONG)CD.OwnCaret); hWndActive = TW.hWnd; ptr = &CD.BlockCursor; ptr1 = &S402.BlockCursor; for (i = 0; i < 8; i++) *ptr++ = *ptr1++; ProcessResetCommand(1); /* turn off status line */ CD.InverseVideo = FALSE; CD.GraphicsMode = FALSE; CD.ICToggle = FALSE; CD.HoldScreen = FALSE; CD.CursorOff = FALSE; CD.KeyboardDisabled = FALSE; CD.AltKeypad = FALSE; CD.CommandState = NO_COMMAND; CD.CurSaveRow = CD.CurSaveCol = 0; SendMessage(hWndActive, WH19_COMMAND, H19_CLRSCREEN,0L); CommData.BaudRate = S401.BaudRate; CommData.ByteSize = S401.ByteSize; CommData.Parity = S401.Parity; CommData.StopBits = S401.StopBits; if ( SetCommState((DCB FAR *)&CommData) < 0) ShowMessage(MW.hWnd, IDS_NOCOMSET); SendMessage(hWndActive,WH19_CARETFUNCTION, H19_CREATECARET,(LONG)CD.OwnCaret); } /* transmit status line */ void SendStatusLine(PTWND pSW) { BYTE outstr[2]; BYTE FAR *lpgBuf; register short cols = pSW->MaxCols; if ((CD.StatOpen) && (CD.LineState == IDM_ONLINE)) { if (GB.hBuf == NULL) { if (CD.ANSIMode) GB.lBufSize = 10 * cols + 2; else GB.lBufSize = 5 * cols + 2; GB.hBuf = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,GB.lBufSize); if (GB.hBuf != NULL) { GB.lBufHead = GB.lBufTail = 0; lpgBuf = GlobalLock(GB.hBuf); LoadOneLine(lpgBuf, pSW->pVidBuffer, cols, TRUE); outstr[0] = CR; LoadBuf(lpgBuf + GB.lBufTail, (BYTE FAR *)outstr,1); GB.lBufTail += 1; GlobalUnlock(GB.hBuf); } } } MessageBeep(0); } /* transmit screen contents */ void SendScreen(PTWND pTW) { short lines = pTW->MaxLines; register short cols = pTW->MaxCols; BYTE *pBuf = pTW->pVidBuffer; BYTE *lineptr = pBuf + pTW->oTopLine; BYTE *pEnd = pBuf + pTW->oVidLastLine; register int i; BYTE outstr[2]; BYTE FAR *lpgBuf; int state; if (CD.LineState == IDM_ONLINE) { if (GB.hBuf == NULL) { if (CD.ANSIMode) GB.lBufSize = 10 * pTW->ScreenSize + 2; else GB.lBufSize = 5 * pTW->ScreenSize + 2; GB.hBuf = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,GB.lBufSize); if (GB.hBuf != NULL) { GB.lBufHead = GB.lBufTail = 0; lpgBuf = GlobalLock(GB.hBuf); for (i = 0; i < lines; i++) { if (i == 0) state = TRUE; else state = FALSE; LoadOneLine(lpgBuf, lineptr, cols, state); if ((lineptr += cols) >pEnd) lineptr = pBuf; } outstr[0] = CR; LoadBuf(lpgBuf + GB.lBufTail, (BYTE FAR *)outstr,1); GB.lBufTail += 1; GlobalUnlock(GB.hBuf); } } } MessageBeep(0); } /* transmit screen support arrays */ #define NC 0 #define NG 1 #define IC 2 #define IG 3 /* old mode across, new mode down */ static BYTE *ANSITransitionCmd[4][4] = { "", "\033[11m", "\033[m", "\033[11m\033[m", "\033[10m", "", "\033[m\033[10m","\033[m", "\033[7m", "\033[11m\033[7m","", "\033[11m", "\033[10m\033[7m","\033[7m","\033[10m", "", }; static BYTE *HeathTransitionCmd[4][4] = { "", "\033G", "\033q", "\033G\033q", "\033F", "", "\033F\033q", "\033q", "\033p", "\033G\033p", "", "\033G", "\033F\033p","\033p", "\033F", "", }; /* load a line into the global buffer and add escape codes */ static void NEAR LoadOneLine(BYTE FAR *lpgBuf,BYTE *pBuf, short len,BOOL resetflag) { BYTE tBuf[TERMMAXCOLS + 10]; int i = 0; short linewidth = len; register int j; register BYTE ch; static int oldmode, newmode; if (resetflag) newmode = NC; while (i < linewidth) { for (j = 0; j < linewidth - i; j++) { if (((ch = *pBuf) < DEL) && (ch >= SP)) { /* normal */ tBuf[j] = ch; pBuf++; } else break; } if (j > 0) { oldmode = newmode; newmode = NC; LoadPrefixAndData(oldmode, newmode, tBuf, lpgBuf, j); i += j; } for (j = 0; j < linewidth - i; j++) { if (((ch = *pBuf) < 255) && (ch >= 160)) { /* inverse */ tBuf[j] = ch & 0x7f; pBuf++; } else break; } if (j > 0) { oldmode = newmode; newmode = IC; LoadPrefixAndData(oldmode, newmode, tBuf, lpgBuf, j); i += j; } for (j = 0; j < linewidth - i; j++) { /* normal graphics */ if ( (((ch = *pBuf) < SP) && (ch >= 0)) || (ch == DEL)) { tBuf[j] = (ch == DEL ? ch - 1 : ch + 94); pBuf++; } else break; } if (j > 0) { oldmode = newmode; newmode = NG; LoadPrefixAndData(oldmode, newmode, tBuf, lpgBuf, j); i += j; } for (j = 0; j < linewidth - i; j++) { /* inverse graphics */ if ( (((ch = *pBuf) < 160) && (ch > DEL)) || (ch == 255)) { ch &= 0x7f; tBuf[j] = (ch == DEL ? ch - 1 : ch + 94); pBuf++; } else break; } if (j > 0) { oldmode = newmode; newmode = IG; LoadPrefixAndData(oldmode, newmode, tBuf, lpgBuf, j); i += j; } } } /* support routine for load one line */ static void NEAR LoadPrefixAndData(int oldmode, int newmode, BYTE *tBuf, BYTE FAR * lpgBuf, int j) { register short cmdlen; register BYTE *cmdstr; if (CD.ANSIMode) cmdstr = ANSITransitionCmd[newmode][oldmode]; else cmdstr = HeathTransitionCmd[newmode][oldmode]; cmdlen = strlen(cmdstr); LoadBuf(lpgBuf + GB.lBufTail, (BYTE FAR *)cmdstr, cmdlen); GB.lBufTail += cmdlen; LoadBuf(lpgBuf + GB.lBufTail, (BYTE FAR *)tBuf, j); GB.lBufTail += j; } /* long pointer strncpy */ static void NEAR LoadBuf(BYTE FAR *dest, BYTE FAR *source, int count) { register int i; for (i = 0; i < count; i++) *dest++ = *source++; } /* dialog box support variables and functions */ static int bytesizeindex; static int parityindex; static int commportindex; static BOOL NEAR SetCommValues(HWND hDlg); static void NEAR InitCommParams(HWND hDlg); static WORD GetBaudRateID(WORD rate); /* dialog box handler to set communications parameters */ BOOL FAR PASCAL SetCommParams(hDlg, message, wParam, lParam) HWND hDlg; unsigned message; WORD wParam; LONG lParam; { int result; switch (message) { case WM_INITDIALOG: InitCommParams(hDlg); break; case WM_COMMAND: switch (wParam) { case IDD_BAUDRATE: if (HIWORD(lParam) == EN_CHANGE) { result = GetDlgItemInt(hDlg,IDD_BAUDRATE, (LONG)NULL, FALSE); CheckRadioButton(hDlg, IDD_110, IDD_OTHER, GetBaudRateID(result)); } break; case IDOK: result = SetCommValues(hDlg); if (result) EndDialog(hDlg, TRUE); break; case IDCANCEL: EndDialog(hDlg, FALSE); break; case IDD_COM1: case IDD_COM2: CheckRadioButton(hDlg, IDD_COM1, IDD_COM2, wParam); commportindex = wParam; break; case IDD_7BIT: case IDD_8BIT: CheckRadioButton(hDlg, IDD_7BIT, IDD_8BIT, wParam); bytesizeindex = wParam; break; case IDD_NONE: case IDD_ODD: case IDD_EVEN: case IDD_MARK: case IDD_SPACE: parityindex = wParam; CheckRadioButton(hDlg, IDD_NONE, IDD_SPACE, wParam); break; case IDD_110: case IDD_150: case IDD_300: case IDD_600: case IDD_1200: case IDD_1800: case IDD_2000: case IDD_2400: case IDD_3600: case IDD_4800: case IDD_7200: case IDD_9600: case IDD_19200: SetDlgItemInt(hDlg, IDD_BAUDRATE, BaudRateTable[wParam - IDD_110], FALSE); break; case IDD_OTHER: CheckRadioButton(hDlg, IDD_110, IDD_OTHER, wParam); SetFocus(GetDlgItem(hDlg,IDD_BAUDRATE)); break; case IDD_SAVE: case IDD_DEFPORT: if (IsDlgButtonChecked(hDlg, wParam)) CheckDlgButton(hDlg, wParam, FALSE); else CheckDlgButton(hDlg, wParam, TRUE); break; default: return FALSE; } break; default: return FALSE; } return TRUE; } /* set DCB */ static BOOL NEAR SetCommValues(HWND hDlg) { int result; WORD oldbaud; BYTE oldstop; BYTE oldparity; BYTE oldbytesize; BYTE newport, oldport; char comstr[10]; short newcid; char wintitle[WINTITLELEN]; oldbaud = CommData.BaudRate; oldbytesize = CommData.ByteSize; oldparity = CommData.Parity; oldstop = CommData.StopBits; oldport = CommData.Id; newport = (BYTE)(commportindex - IDD_COM1); if (newport != oldport) { LoadString(hInst, IDS_COM1 + newport, (LPSTR)comstr, sizeof(comstr)); newcid = OpenComm((LPSTR)comstr, RXQUESIZE, TXQUESIZE); if (newcid >= 0) { CloseCommPort(hDlg, &cid); if (cid == INT_MIN) { cid = newcid; CommData.Id = (BYTE)cid; LoadString(hInst,IDS_WINTITLE,(LPSTR)wintitle,sizeof(wintitle)); strcat(wintitle,comstr); SetWindowText(MW.hWnd, (LPSTR)wintitle); } else { CloseCommPort(hDlg, &newcid); ShowMessage(hDlg, IDS_CANNOTCHANGEPORT); return FALSE; } } else { ShowMessage(hDlg, IDS_CANNOTCHANGEPORT); return FALSE; } } CommData.BaudRate = GetDlgItemInt(hDlg,IDD_BAUDRATE, (LONG)NULL, FALSE); CommData.ByteSize = (BYTE)(bytesizeindex - IDD_7BIT + 7); CommData.Parity = (BYTE)(parityindex - IDD_NONE); if (CommData.BaudRate <= 110) CommData.StopBits = TWOSTOPBITS; else CommData.StopBits = ONESTOPBIT; result = SetCommState((DCB FAR *)&CommData); if (result == 0) { if (IsDlgButtonChecked(hDlg, IDD_SAVE)) SaveCommParams(); if (IsDlgButtonChecked(hDlg, IDD_DEFPORT)) SetDefaultPort(); return TRUE; } else { CommData.BaudRate = oldbaud; CommData.ByteSize = oldbytesize; CommData.Parity = oldparity; CommData.StopBits = oldstop; SetCommState((DCB FAR *)&CommData); InitCommParams(hDlg); ShowMessage(hDlg, IDS_NOCOMSET); return FALSE; } } /* set up a default port */ static void NEAR SetDefaultPort() { char keystr[10]; char valstr[10]; int val1, val2; if (commportindex == IDD_COM1) { val1 = IDS_COM1; val2 = IDS_COM2; } else { val1 = IDS_COM2; val2 = IDS_COM1; } LoadString(hInst, IDS_FIRSTPORT, (LPSTR)keystr, sizeof(keystr)); LoadString(hInst, val1, (LPSTR)valstr, sizeof(valstr)); WriteProfileString((LPSTR)szAppName,(LPSTR)keystr,(LPSTR)valstr); LoadString(hInst, IDS_SECONDPORT, (LPSTR)keystr, sizeof(keystr)); LoadString(hInst, val2, (LPSTR)valstr, sizeof(valstr)); WriteProfileString((LPSTR)szAppName,(LPSTR)keystr,(LPSTR)valstr); BroadcastWinIniChange(); } /* save parameters to win.ini */ static void NEAR SaveCommParams() { char keystr[10]; char valstr[30]; int portval; S401.BaudRate = CommData.BaudRate; S401.ByteSize = CommData.ByteSize; S401.Parity = CommData.Parity; S401.StopBits = CommData.StopBits; portval = commportindex - IDD_COM1; LoadString(hInst, IDS_COM1 + portval, (LPSTR)keystr, sizeof(keystr)); itoa(CommData.BaudRate, valstr, 10); switch (CommData.Parity) { case EVENPARITY: strcat(valstr, ",e"); break; case ODDPARITY: strcat(valstr, ",o"); break; default: strcat(valstr, ",n"); break; } if (CommData.ByteSize == 8) strcat(valstr, ",8"); else strcat(valstr, ",7"); if (CommData.BaudRate <= 110) strcat(valstr, ",2"); else strcat(valstr, ",1"); WriteProfileString((LPSTR)szAppName,(LPSTR)keystr,(LPSTR)valstr); BroadcastWinIniChange(); } /* initialize comm parameters */ static void NEAR InitCommParams(HWND hDlg) { parityindex = IDD_NONE + CommData.Parity; bytesizeindex = IDD_7BIT + CommData.ByteSize - 7; commportindex = IDD_COM1 + CommData.Id; SetDlgItemInt(hDlg, IDD_BAUDRATE, CommData.BaudRate, FALSE); CheckRadioButton(hDlg, IDD_NONE, IDD_SPACE, parityindex); CheckRadioButton(hDlg, IDD_7BIT, IDD_8BIT, bytesizeindex); CheckRadioButton(hDlg, IDD_COM1, IDD_COM2, commportindex); } /* read baud rate from table */ static WORD GetBaudRateID(WORD rate) { register int i; register WORD id; id = IDD_OTHER; for (i = 0; i < BAUDTABLESIZE; i++) { if (rate == BaudRateTable[i]) { id = IDD_110 + i; break; } } return id; } /* dialog box for setting terminal parameters */ BOOL FAR PASCAL SetTermParams(hDlg, message, wParam, lParam) HWND hDlg; unsigned message; WORD wParam; LONG lParam; { switch (message) { case WM_INITDIALOG: TermParamInit(hDlg); break; case WM_COMMAND: switch (wParam) { case IDOK: TermParamSet(hDlg); EndDialog(hDlg, TRUE); break; case IDCANCEL: EndDialog(hDlg, FALSE); break; case IDD_WRAP: case IDD_LFCR: case IDD_CRLF: case IDD_SAVE: if (IsDlgButtonChecked(hDlg, wParam)) CheckDlgButton(hDlg, wParam, FALSE); else CheckDlgButton(hDlg, wParam, TRUE); break; case IDD_LINE: case IDD_BLOCK: CheckRadioButton(hDlg, IDD_LINE, IDD_BLOCK, wParam); break; case IDD_HALF: case IDD_FULL: CheckRadioButton(hDlg, IDD_HALF, IDD_FULL, wParam); break; case IDD_HEATH: case IDD_ANSI: CheckRadioButton(hDlg, IDD_HEATH, IDD_ANSI, wParam); break; case IDD_NORMAL: case IDD_SHIFTED: CheckRadioButton(hDlg, IDD_NORMAL, IDD_SHIFTED, wParam); break; default: return FALSE; } break; default: return FALSE; } return TRUE; } /* dialog box initialization */ static void NEAR TermParamInit(HWND hDlg) { CheckRadioButton(hDlg, IDD_HALF, IDD_FULL, IDD_HALF + CD.FullDuplex); CheckRadioButton(hDlg, IDD_HEATH, IDD_ANSI, IDD_HEATH + CD.ANSIMode); CheckRadioButton(hDlg,IDD_NORMAL,IDD_SHIFTED,IDD_NORMAL + CD.ShiftedKeypad); CheckRadioButton(hDlg, IDD_LINE, IDD_BLOCK,IDD_LINE + CD.BlockCursor); CheckDlgButton(hDlg, IDD_WRAP, CD.WrapAround); CheckDlgButton(hDlg, IDD_CRLF, CD.CRonLF); CheckDlgButton(hDlg, IDD_LFCR, CD.LFonCR); } /* set terminal parameters */ static void NEAR TermParamSet(HWND hDlg) { int *ptr, *ptr1; int i, index; char szValStr[30], szKeyStr[30]; for (i = IDD_HALF; i <= IDD_FULL; i++) if (SendDlgItemMessage(hDlg,i,BM_GETCHECK,0,0L)) { CD.FullDuplex = i - IDD_HALF; break; } for (i = IDD_HEATH; i <= IDD_ANSI; i++) if (SendDlgItemMessage(hDlg,i,BM_GETCHECK,0,0L)) { CD.ANSIMode = i - IDD_HEATH; break; } for (i = IDD_NORMAL; i <= IDD_SHIFTED; i++) if (SendDlgItemMessage(hDlg,i,BM_GETCHECK,0,0L)) { CD.ShiftedKeypad = i - IDD_NORMAL; break; } for (i = IDD_LINE; i <= IDD_BLOCK; i++) if (SendDlgItemMessage(hDlg,i,BM_GETCHECK,0,0L)) { index = i - IDD_LINE; break; } if (index != CD.BlockCursor) if (index) ProcessSetCommand(4); else ProcessResetCommand(4); CD.WrapAround = IsDlgButtonChecked(hDlg, IDD_WRAP); CD.LFonCR = IsDlgButtonChecked(hDlg, IDD_LFCR); CD.CRonLF = IsDlgButtonChecked(hDlg, IDD_CRLF); if (IsDlgButtonChecked(hDlg, IDD_SAVE)) { ptr = &S402.BlockCursor; ptr1 = &CD.BlockCursor; for (i = 0; i < 8; i++) { itoa(*ptr1,szValStr,sizeof(szValStr)); *ptr++ = *ptr1++; LoadString(hInst,IDS_BLOCKCURSOR+i,(LPSTR)szKeyStr, sizeof(szKeyStr)); WriteProfileString((LPSTR)szAppName,(LPSTR)szKeyStr, (LPSTR)szValStr); } BroadcastWinIniChange(); } } /* dialog box function to edit function key strings */ BOOL FAR PASCAL SetStringParams(hDlg, message, wParam, lParam) HWND hDlg; unsigned message; WORD wParam; LONG lParam; { register int i; switch (message) { case WM_INITDIALOG: CheckRadioButton(hDlg, IDD_F1, IDD_F12, IDD_F1); CheckRadioButton(hDlg,IDD_NOSHIFT,IDD_CTRLSHIFT,IDD_SHIFT); SendDlgItemMessage(hDlg,IDD_STRINGEDIT,EM_LIMITTEXT,80,0L); StringOp(hDlg, IDOK+1); break; case WM_COMMAND: switch (wParam) { case IDD_F1: case IDD_F2: case IDD_F3: case IDD_F4: case IDD_F5: case IDD_F6: case IDD_F7: case IDD_F8: case IDD_F9: case IDD_F10: case IDD_F11: case IDD_F12: CheckRadioButton(hDlg, IDD_F1, IDD_F12, wParam); StringOp(hDlg, wParam); break; case IDD_NOSHIFT: CheckRadioButton(hDlg, IDD_F1, IDD_F12, IDD_F10); CheckRadioButton(hDlg, IDD_NOSHIFT, IDD_CTRLSHIFT, wParam); for (i = IDD_F1; i < IDD_F12; i++) { if (i >= IDD_F10) continue; else EnableWindow(GetDlgItem(hDlg, i), FALSE); } StringOp(hDlg, wParam); break; case IDD_SHIFT: case IDD_CONTROL: case IDD_CTRLSHIFT: CheckRadioButton(hDlg, IDD_NOSHIFT, IDD_CTRLSHIFT, wParam); for (i = IDD_F1; i < IDD_F12; i++) { if (i == IDD_F6) continue; else EnableWindow(GetDlgItem(hDlg, i), TRUE); } StringOp(hDlg, wParam); break; case IDOK: StringOp(hDlg, wParam); break; case IDCANCEL: EndDialog(hDlg, FALSE); break; default: return FALSE; } break; default: return FALSE; } return TRUE; } /* support function for function key edit dialog box */ static void NEAR StringOp(HWND hDlg, WORD param) { register int index, i; char fstring[80]; char *ptr; for (i = IDD_F1; i <= IDD_F12; i++) if (SendDlgItemMessage(hDlg,i,BM_GETCHECK,0,0L)) { index = i - IDD_F1; break; } for (i = IDD_NOSHIFT; i <= IDD_CTRLSHIFT; i++) if (SendDlgItemMessage(hDlg,i,BM_GETCHECK,0,0L)) { switch (i) { case IDD_NOSHIFT: ptr = szFKey[index]; break; case IDD_SHIFT: ptr = szSFKey[index]; break; case IDD_CONTROL: ptr = szCFKey[index]; break; case IDD_CTRLSHIFT: ptr = szCSFKey[index]; break; } break; } if (param == IDOK) { GetDlgItemText(hDlg, IDD_STRINGEDIT, (LPSTR)fstring, 80); WriteProfileString((LPSTR)szAppName,(LPSTR)ptr,(LPSTR)fstring); BroadcastWinIniChange(); SetDlgItemText(hDlg,IDD_STRINGEDIT,(LPSTR)fstring); } else { GetProfileString((LPSTR)szAppName, (LPSTR)ptr,(LPSTR)"",(LPSTR)fstring,80); SetDlgItemText(hDlg,IDD_STRINGEDIT,(LPSTR)fstring); SendDlgItemMessage(hDlg,IDD_STRINGEDIT,EM_SETSEL,0,MAKELONG(0,32767)); } /* SetFocus(GetDlgItem(hDlg,IDD_STRINGEDIT)); */ }