|
|
1.1 ! root 1: /* ! 2: comtalk.c -- Main routines ! 3: Created by Microsoft Corporation, 1989 ! 4: ! 5: This file contains the sources for the dialog box manipulation, and menu ! 6: managment, and other aspects of interfacing with the user. ! 7: */ ! 8: #define INCL_WIN ! 9: #include <os2.h> ! 10: #include "comtalk.h" /* definition of COM from Global, and Resource IDs */ ! 11: #include "avio.h" /* Routines needed to manage AVIO Presentation Space */ ! 12: #include "threads.h" /* Thread initialization and control routines */ ! 13: #include <stdio.h> /* Only needed for file I/O */ ! 14: #include <string.h> /* one strcpy call */ ! 15: /* ! 16: Variables ! 17: */ ! 18: CHAR szCaption[] = ""; ! 19: HAB hAB; ! 20: COM comTerm; ! 21: COM comTemp; ! 22: HWND hWndMenu; ! 23: CLASSINFO clsi; ! 24: PFNWP pfnOldFrameWndProc; ! 25: BOOL fConnected = FALSE; ! 26: BOOL fPaging; ! 27: int iUpdate; ! 28: BOOL fFreeze = TRUE; ! 29: int iError; ! 30: /* ! 31: Macros ! 32: */ ! 33: #define InRange(x, a, b) ((a <= x) && (x <= b)) ! 34: ! 35: /* ! 36: Shorthand for sending messages, querying ! 37: */ ! 38: #define Parent(h) \ ! 39: WinQueryWindow(h, QW_PARENT, FALSE) ! 40: ! 41: #define EnableMenuItem(id) \ ! 42: WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \ ! 43: MPFROM2SHORT(MIA_DISABLED,0)) ! 44: ! 45: #define DisableMenuItem(id) \ ! 46: WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \ ! 47: MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED)) ! 48: ! 49: #define CheckMenuItem(id) \ ! 50: WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \ ! 51: MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED)) ! 52: ! 53: #define UnCheckMenuItem(id) \ ! 54: WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \ ! 55: MPFROM2SHORT(MIA_CHECKED, 0)) ! 56: ! 57: #define PushButton(h, id) \ ! 58: WinSendDlgItemMsg(h, id, BM_SETCHECK, MPFROM2SHORT(TRUE, 0), 0L) ! 59: ! 60: #define Valid(bData, bStop) \ ! 61: (((bData == IDD_FIVE) && (bStop != IDD_TWOSTOP)) \ ! 62: || ((bData != IDD_FIVE) && (bStop != IDD_ONEFIVE))) ! 63: ! 64: #define ErrMsg(h, s) \ ! 65: WinMessageBox(HWND_DESKTOP, h, s, NULL, NULL, MB_OK | MB_ICONEXCLAMATION) ! 66: ! 67: char Ctrl(char ch) { ! 68: return (('a' <= ch) && (ch <= 'z')) ? (ch - 'a' + '\001') : ! 69: ((('A' <= ch) && (ch <= 'Z')) ? (ch - 'A' + '\001') : ch); ! 70: } ! 71: ! 72: /* ! 73: Local/Private routines ! 74: */ ! 75: void ReadOpts(HWND); ! 76: void InitTerm(void); ! 77: void Initialize(HWND); ! 78: void ChangeSystemMenu(HWND); ! 79: BOOL Filter(USHORT, char, USHORT); ! 80: ! 81: void main (void) { ! 82: static CHAR szClientClass[] = "Terminal"; ! 83: HMQ hmq; ! 84: HWND hWndClient, hWndFrame; ! 85: QMSG qmsg; ! 86: ULONG flFrameFlags = FCF_STANDARD | FCF_HORZSCROLL | FCF_VERTSCROLL; ! 87: ULONG flFrameStyle = WS_VISIBLE | FS_SCREENALIGN; ! 88: ! 89: hAB = WinInitialize(0); ! 90: hmq = WinCreateMsgQueue(hAB, 0); ! 91: ! 92: WinRegisterClass(hAB, szClientClass, ClientWndProc, CS_SYNCPAINT, 0); ! 93: ! 94: hWndFrame = WinCreateStdWindow(HWND_DESKTOP, flFrameStyle, ! 95: &flFrameFlags, szClientClass, szCaption, ! 96: 0L, NULL, ID_RESOURCE, &hWndClient); ! 97: ! 98: /* Setup AVIO PS and force a paint */ ! 99: AvioInit(hWndFrame, hWndClient); ! 100: WinSendMsg(hWndClient, WM_PAINT, NULL, NULL); ! 101: ! 102: /* Try to subclass the Frame window... */ ! 103: pfnOldFrameWndProc = WinSubclassWindow(hWndFrame, NewFrameWndProc); ! 104: ! 105: while (WinGetMsg(hAB, &qmsg, NULL, 0, 0)) WinDispatchMsg(hAB, &qmsg); ! 106: ! 107: /* Blast the AVIO PS */ ! 108: AvioClose(); ! 109: ! 110: WinDestroyWindow(hWndFrame); ! 111: WinDestroyMsgQueue(hmq); ! 112: WinTerminate(hAB); ! 113: DosExit(EXIT_PROCESS, 0); ! 114: } ! 115: ! 116: MRESULT CALLBACK ClientWndProc(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) { ! 117: /* ! 118: Window Procedure which traps messages to the Client area ! 119: */ ! 120: switch (msg) { ! 121: case WM_AVIOUPDATE: ! 122: fNoUpdate = AvioUpdateLines(FALSE, &fPaging); ! 123: if (fConnected && fPaging) { ! 124: CheckMenuItem(IDM_PAGING); ! 125: } ! 126: break; ! 127: ! 128: case WM_MSGBOX: ! 129: iUpdate = (int) mp2; ! 130: switch ((int) mp1) { ! 131: case (int) MBE_COMREAD: ! 132: if (iError = iUpdate) EnableMenuItem(IDM_ERRORS); ! 133: iUpdate = 0; ! 134: break; ! 135: ! 136: default: ! 137: ErrMsg(hWnd, aszMessage[(int) mp1]); ! 138: break; ! 139: } ! 140: if (iUpdate) { /* Page down because queue is full */ ! 141: fNoUpdate = AvioUpdateLines(TRUE, &fPaging); ! 142: if (fConnected && fPaging) CheckMenuItem(IDM_PAGING); ! 143: else UnCheckMenuItem(IDM_PAGING); ! 144: ThdReset(); ! 145: } ! 146: break; ! 147: ! 148: case WM_CREATE: ! 149: ChangeSystemMenu(hWnd); ! 150: /* ! 151: Initialize the Dialog Options ! 152: */ ! 153: Initialize(hWnd); ! 154: /* ! 155: Get the Handle so you can enable/disable menu items ! 156: Thanks again to Charles Petzold ! 157: */ ! 158: hWndMenu = WinWindowFromID(Parent(hWnd), FID_MENU); ! 159: /* ! 160: Disable some entries (can do this in the resource file) ! 161: */ ! 162: DisableMenuItem(IDM_CLOSE); ! 163: DisableMenuItem(IDM_BREAK); ! 164: DisableMenuItem(IDM_COMMANDMENU); ! 165: break; ! 166: ! 167: case WM_PAINT: /* Paint the AVIO way! */ ! 168: AvioPaint(hWnd); ! 169: break; ! 170: ! 171: case WM_SIZE: /* Size the AVIO way! */ ! 172: fNoUpdate = AvioUpdateLines(FALSE, &fPaging); ! 173: if (fConnected && fPaging) { ! 174: CheckMenuItem(IDM_PAGING); ! 175: } ! 176: return AvioSize(hWnd, msg, mp1, mp2); ! 177: break; ! 178: ! 179: case WM_HSCROLL: ! 180: AvioScroll(HIUSHORT(mp2), LOUSHORT(mp2), TRUE); ! 181: break; ! 182: ! 183: case WM_VSCROLL: ! 184: AvioScroll(HIUSHORT(mp2), LOUSHORT(mp2), FALSE); ! 185: break; ! 186: ! 187: case WM_ERASEBACKGROUND: ! 188: return 0; ! 189: break; ! 190: ! 191: case WM_COMMAND: ! 192: switch (COMMANDMSG(&msg)->cmd) { ! 193: case IDM_ABOUT: ! 194: WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc, ! 195: NULL, IDD_ABOUT, NULL); ! 196: return 0; ! 197: ! 198: case IDM_HELP: ! 199: WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc, ! 200: NULL, IDD_MAINHELPBOX, NULL); ! 201: return 0; ! 202: ! 203: case IDM_SETTINGS: ! 204: WinDlgBox(HWND_DESKTOP, hWnd, SetDlgProc, ! 205: NULL, IDD_SET, NULL); ! 206: return 0; ! 207: ! 208: case IDM_CONNECT: ! 209: AvioStartup(hWnd); ! 210: ThdInitialize(hWnd, comTerm); /* Spawn 3 threads */ ! 211: /* ! 212: Disable/Enable Menu Items ! 213: */ ! 214: DisableMenuItem(IDM_CONNECT); ! 215: DisableMenuItem(IDM_SETTINGS); ! 216: DisableMenuItem(IDM_ERRORS); ! 217: ! 218: EnableMenuItem(IDM_CLOSE); ! 219: EnableMenuItem(IDM_BREAK); ! 220: EnableMenuItem(IDM_COMMANDMENU); ! 221: fConnected = TRUE; ! 222: return 0; ! 223: ! 224: case IDM_CLOSE: ! 225: fConnected = FALSE; ! 226: ThdTerminate(); /* Might have to wait? */ ! 227: /* ! 228: Update menu items ! 229: */ ! 230: UnCheckMenuItem(IDM_BREAK); ! 231: ! 232: DisableMenuItem(IDM_CLOSE); ! 233: DisableMenuItem(IDM_BREAK); ! 234: DisableMenuItem(IDM_COMMANDMENU); ! 235: ! 236: EnableMenuItem(IDM_CONNECT); ! 237: EnableMenuItem(IDM_SETTINGS); ! 238: ! 239: return 0; ! 240: ! 241: case IDM_BREAK: ! 242: ThdDoBreak(); ! 243: return 0; ! 244: ! 245: case IDM_ERRORS: ! 246: if (iError & 1) ! 247: ErrMsg(hWnd, "Receive Queue Overrun"); ! 248: if (iError & 2) ! 249: ErrMsg(hWnd, "Receive Hardware Overrun"); ! 250: if (iError & 4) ! 251: ErrMsg(hWnd, "Parity Error"); ! 252: if (iError & 8) ! 253: ErrMsg(hWnd, "Framing Error"); ! 254: DisableMenuItem(IDM_ERRORS); ! 255: return 0; ! 256: ! 257: case IDM_PAGE: ! 258: fNoUpdate = AvioUpdateLines(TRUE, &fPaging); ! 259: if (fPaging) CheckMenuItem(IDM_PAGING); ! 260: else UnCheckMenuItem(IDM_PAGING); ! 261: return 0; ! 262: ! 263: case IDM_UP: ! 264: AvioPageUp(); ! 265: return 0; ! 266: ! 267: case IDM_PAGING: ! 268: if (fPaging = !fPaging) { ! 269: CheckMenuItem(IDM_PAGING); ! 270: } else { ! 271: UnCheckMenuItem(IDM_PAGING); ! 272: } ! 273: return 0; ! 274: ! 275: default: return 0; ! 276: } ! 277: ! 278: case WM_CHAR: /* Put characters in typeahead buffer */ ! 279: if (fConnected && !(CHARMSG(&msg)->fs & KC_KEYUP)) ! 280: if (Filter( CHARMSG(&msg)->fs, ! 281: (char) CHARMSG(&msg)->chr, ! 282: CHARMSG(&msg)->vkey)) ! 283: ErrMsg(hWnd, "Error Writing COM Port"); ! 284: break; ! 285: ! 286: case WM_TRACKFRAME: ! 287: AvioTrackFrame(hWnd, mp1); ! 288: break; ! 289: ! 290: case WM_MINMAXFRAME: /* Trap MAXIMIZE messages */ ! 291: AvioMinMax((PSWP) mp1); ! 292: ! 293: default: return WinDefWindowProc(hWnd, msg, mp1, mp2); ! 294: } ! 295: return 0; ! 296: } ! 297: ! 298: MRESULT CALLBACK AboutDlgProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2) { ! 299: /* ! 300: Dialog box control for the ABOUT COMTALK... dialog box ! 301: */ ! 302: switch(msg) { ! 303: case WM_COMMAND: ! 304: switch(COMMANDMSG(&msg)->cmd) { ! 305: case DID_OK: WinDismissDlg(hDlg, TRUE); break; ! 306: default: break; ! 307: } ! 308: default: return WinDefDlgProc(hDlg, msg, mp1, mp2); ! 309: } ! 310: return FALSE; ! 311: } ! 312: ! 313: void WriteOpts(void) { ! 314: /* ! 315: Write Settings to file COMTALK.INI ! 316: */ ! 317: FILE *fp; ! 318: ! 319: fp = fopen("comtalk.ini", "w+"); ! 320: fprintf(fp, "%d %d %d %d %d %d %d %s\n", comTerm.usBaud, comTerm.bParity, ! 321: comTerm.bData, comTerm.bStop, comTerm.fWrap, ! 322: comTerm.fHardware, comTerm.fSoftware, comTerm.szPort); ! 323: fclose(fp); ! 324: } ! 325: ! 326: void ReadOpts(HWND hWnd) { ! 327: /* ! 328: Read Settings from COMTALK.INI ! 329: */ ! 330: FILE *fp; ! 331: ! 332: /* Use InitTerm() if we have reading problems */ ! 333: if ((fp = fopen("comtalk.ini", "r")) == NULL) InitTerm(); ! 334: else if (fscanf(fp, "%d%d%d%d%d%d%d%s", &comTerm.usBaud, &comTerm.bParity, ! 335: &comTerm.bData, &comTerm.bStop, &comTerm.fWrap, ! 336: &comTerm.fHardware, &comTerm.fSoftware, comTerm.szPort) == EOF) ! 337: InitTerm(); ! 338: if (!Valid(comTerm.bData, comTerm.bStop)) { ! 339: ErrMsg(hWnd, "Invalid terminal setting"); ! 340: InitTerm(); ! 341: } ! 342: fclose(fp); ! 343: } ! 344: ! 345: void InitTerm(void) { ! 346: /* ! 347: Initialize the TERM structure to DosDevIOCtl defaults ! 348: */ ! 349: strcpy(comTerm.szPort, "com1"); ! 350: comTerm.usBaud = 9600; comTerm.bParity = IDD_EVENP; ! 351: comTerm.bData = IDD_SEVEN; comTerm.bStop = IDD_ONESTOP; ! 352: comTerm.fWrap = comTerm.fSoftware = TRUE; comTerm.fHardware = FALSE; ! 353: } ! 354: ! 355: MRESULT CALLBACK SetDlgProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2) { ! 356: /* ! 357: The Settings Dialog Box control routine ! 358: */ ! 359: BOOL rc; ! 360: BYTE bTemp; ! 361: ! 362: switch(msg) { ! 363: case WM_INITDLG: ! 364: WinSetDlgItemText(hDlg, IDD_PORT, comTerm.szPort); ! 365: WinSetDlgItemShort(hDlg, IDD_BAUD, comTerm.usBaud, FALSE); ! 366: ! 367: PushButton(hDlg, comTerm.bParity); ! 368: PushButton(hDlg, comTerm.bData); ! 369: PushButton(hDlg, comTerm.bStop); ! 370: if (comTerm.fWrap) PushButton(hDlg, IDD_WRAP); ! 371: if (comTerm.fHardware) PushButton(hDlg, IDD_HW); ! 372: if (comTerm.fSoftware) PushButton(hDlg, IDD_SW); ! 373: ! 374: comTemp.bParity = comTerm.bParity; ! 375: comTemp.bData = comTerm.bData; ! 376: comTemp.bStop = comTerm.bStop; ! 377: comTemp.fWrap = comTerm.fWrap; ! 378: comTemp.fHardware = comTerm.fHardware; ! 379: comTemp.fSoftware = comTerm.fSoftware; ! 380: break; ! 381: ! 382: case WM_HELP: ! 383: WinDlgBox(HWND_DESKTOP, hDlg, AboutDlgProc, ! 384: NULL, IDD_SETHELPBOX, NULL); ! 385: break; ! 386: ! 387: case WM_CONTROL: ! 388: /* ! 389: The fact that these are AutoRadioButtons makes life easy. ! 390: */ ! 391: bTemp = (BYTE) SHORT1FROMMP(mp1); /* Which button pushed? */ ! 392: if InRange(bTemp, IDD_NOP, IDD_SPACEP) { ! 393: comTemp.bParity = bTemp; ! 394: } else if InRange(bTemp, IDD_FIVE, IDD_EIGHT) { ! 395: comTemp.bData = bTemp; ! 396: } else if InRange(bTemp, IDD_ONESTOP, IDD_TWOSTOP) { ! 397: comTemp.bStop = bTemp; ! 398: } else switch (bTemp) { ! 399: case IDD_WRAP: comTemp.fWrap = !comTemp.fWrap; break; ! 400: case IDD_HW : comTemp.fHardware = !comTemp.fHardware; break; ! 401: case IDD_SW : comTemp.fSoftware = !comTemp.fSoftware; break; ! 402: default: break; ! 403: } ! 404: break; ! 405: case WM_COMMAND: /* Ready to exit... */ ! 406: switch(COMMANDMSG(&msg)->cmd) { ! 407: case IDD_SAVE: ! 408: case DID_OK: ! 409: if (!Valid(comTemp.bData, comTemp.bStop)) { ! 410: ErrMsg(hDlg,"Data and Stop Bits Incompatible"); ! 411: break; /* No-op...Dialog not dismissed */ ! 412: } ! 413: WinQueryDlgItemText(hDlg, IDD_PORT, 5, comTerm.szPort); ! 414: WinQueryDlgItemShort(hDlg, IDD_BAUD, &comTerm.usBaud, rc); ! 415: comTerm.bParity = comTemp.bParity; ! 416: comTerm.bData = comTemp.bData; ! 417: comTerm.bStop = comTemp.bStop; ! 418: comTerm.fWrap = comTemp.fWrap; ! 419: comTerm.fHardware = comTemp.fHardware; ! 420: comTerm.fSoftware = comTemp.fSoftware; ! 421: if (COMMANDMSG(&msg)->cmd == IDD_SAVE) WriteOpts(); ! 422: case DID_CANCEL: WinDismissDlg(hDlg, FALSE); ! 423: default: break; ! 424: } ! 425: break; ! 426: default: return WinDefDlgProc(hDlg, msg, mp1, mp2); ! 427: } ! 428: return FALSE; ! 429: } ! 430: ! 431: void Initialize(HWND hWnd) { ! 432: ReadOpts(hWnd); ! 433: fPaging = FALSE; ! 434: } ! 435: ! 436: void ChangeSystemMenu(HWND hWnd) { ! 437: /* ! 438: Insert items into the System Menu (with thanks to Charles Petzold) ! 439: */ ! 440: static CHAR *x[2] = { NULL, "~About ComTalk..." }; /* Items to add */ ! 441: static MENUITEM mi[2] = { /* The RESOURCE definitions */ ! 442: MIT_END, MIS_SEPARATOR, 0x0000, NULL, NULL, NULL, ! 443: MIT_END, MIS_TEXT, 0x0000, IDM_ABOUT, NULL, NULL ! 444: }; ! 445: HWND hSM, hSSM; /* Menu and submenu handles */ ! 446: MENUITEM miSM; /* System Menu Menuitem */ ! 447: SHORT idSM; /* ID of the System Menu */ ! 448: /* ! 449: Get ahold of the system menu ! 450: */ ! 451: hSM = WinWindowFromID(Parent(hWnd), FID_SYSMENU); ! 452: idSM = (SHORT) WinSendMsg(hSM, MM_ITEMIDFROMPOSITION, NULL, NULL); ! 453: WinSendMsg(hSM, MM_QUERYITEM, MPFROM2SHORT(idSM, FALSE), MPFROMP(&miSM)); ! 454: /* ! 455: Manipulate the System SubMenu ! 456: */ ! 457: hSSM = miSM.hwndSubMenu; ! 458: WinSendMsg(hSSM, MM_INSERTITEM, MPFROMP(mi), MPFROMP(x[0])); ! 459: WinSendMsg(hSSM, MM_INSERTITEM, MPFROMP(mi+1), MPFROMP(x[1])); ! 460: } ! 461: ! 462: MRESULT CALLBACK NewFrameWndProc(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) { ! 463: /* ! 464: Force the frame to stay small enough ! 465: */ ! 466: BOOL rc; /* Return code for WM_QueryTrackInfo */ ! 467: ! 468: switch(msg) { ! 469: case WM_ADJUSTWINDOWPOS: /* Calculate, then show scrollbars */ ! 470: AvioAdjustFrame(mp1); ! 471: break; ! 472: case WM_QUERYTRACKINFO: ! 473: rc = (BOOL) (*pfnOldFrameWndProc)(hWnd, msg, mp1, mp2); ! 474: AvioQueryTrackInfo((PTRACKINFO) mp2); ! 475: return rc; ! 476: default: break; ! 477: } ! 478: return (*pfnOldFrameWndProc)(hWnd, msg, mp1, mp2); ! 479: } ! 480: ! 481: BOOL Filter(USHORT fs, char ch, USHORT vkey) { ! 482: BOOL rc = FALSE; ! 483: ! 484: if (fs & KC_VIRTUALKEY) { ! 485: switch(vkey) { ! 486: case VK_HOME: ! 487: if (fs & KC_CTRL) rc = ThdPutString("\033[2J",4); ! 488: return (rc || ThdPutString("\033[H", 3)); ! 489: case VK_UP: ! 490: return ThdPutString("\033[A", 3); ! 491: case VK_DOWN: ! 492: return ThdPutString("\033[B", 3); ! 493: case VK_RIGHT: ! 494: return ThdPutString("\033[C", 3); ! 495: case VK_LEFT: ! 496: return ThdPutString("\033[D", 3); ! 497: default: break; ! 498: } ! 499: } ! 500: ! 501: if (fs & KC_CTRL) { ! 502: switch (ch) { ! 503: case 'l': ! 504: case 'L': AvioRedraw(); ! 505: case '\0': return FALSE; break; ! 506: default: ch = Ctrl(ch); break; ! 507: } ! 508: } else { ! 509: switch (ch) { ! 510: case '\0': return FALSE; break; ! 511: default: break; ! 512: } ! 513: } ! 514: return(rc || ThdPutChar(ch)); ! 515: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.