|
|
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.