|
|
1.1 root 1: /*-----------------------------------------------------------
2: PMCOMM.C -- PM Communications program.
3: Created by Microsoft Corp., 1988
4: -----------------------------------------------------------*/
5:
6: #include <os2def.h>
7:
8: #define INCL_DOSDEVICES
9: #define INCL_DOSPROCESS
10: #include <bsedos.h> /* for threads */
11:
12: #define INCL_WIN
13: #define INCL_GPI
14: #include <pm.h>
15:
16: #include <stdio.h> /* for filelength () and sprintf */
17: #include <stdlib.h> /* for min max */
18: #include <string.h> /* for strcpy strcat */
19: #include "pmcomm.h"
20:
21: #define MAXWIDTH 80 /* # characters wide. */
22: #define MAXLINES 20 /* # lines. */
23: #define BUFFERMAX (MAXWIDTH * MAXLINES)
24: #define MAXFILESIZE BUFFERMAX-1
25: #define WM_BLAST (WM_USER+1)
26:
27: #define FILLBUF(x,y) (cDisplayBuf[(y * MAXWIDTH)+x])
28:
29: CHAR szClassName [10] ;
30: CHAR szTitleBar [40] ;
31: CHAR szINIFile [20] ;
32: CHAR szUnTitled [14] ;
33:
34: BYTE bSaveXONChar; /* from DCB structure */
35:
36: char cInBuffer[INBUFLENGTH]; /* comm input buffer */
37: char cTempBuf[INBUFLENGTH]; /* temp buf from comm to display buf. */
38: char cDisplayBuf[BUFFERMAX]; /* buffer to hold contents. */
39: char cCaptionBuf[40]; /* buffer for caption bar. */
40: char *pBlastString;
41: char *pTempBuf;
42: char *pTempPt;
43:
44: char *pStartLine[MAXLINES]; /* # of pointers to make */
45: int iLineLength[MAXLINES]; /* line length of each row */
46: int iMaxLines;
47: int iMaxWidth; /* used to see if you overflow line */
48: SHORT xCursor, yCursor; /* cursor location for buffer & screen */
49: SHORT xPause, yPause; /* save currsor position during pause */
50: SHORT xChar, yChar; /* size of character for display */
51:
52: int iBufPos; /* current buffer position */
53:
54: HAB hab ;
55: char *pFile; /* pointer to provided file */
56: BOOL bGotSettings; /* do we have the settings? */
57: BOOL bSettingsChanged; /* did the settings change? */
58: BOOL bTestOn; /* flag to flip test on or off */
59: BOOL bEchoOn; /* flag to set echo on or off */
60: BOOL bPauseOn; /* flag to set pause on or off */
61: BOOL bCaptureOn; /* flag to set capture on |off */
62: BOOL bCommOpen; /* flag to set if comm is open */
63: BOOL bWordWrap; /* flag to set word wrap */
64: BOOL bScroll; /* if scroll occured skip paint*/
65: BOOL bResult;
66: BOOL bOverFlow; /* flag for circular buffer */
67: BOOL bExitReadThread; /* flag to exit ReadComm thread*/
68: int i; /* global use of a temp int */
69: int iToFormat; /* # of bytes formated */
70:
71: HWND hGWnd ; /* Global handle to window */
72: HWND hGMenuWnd ; /* Global handle to menu */
73: HWND hWndFrame ; /* Global handle to frame */
74: HWND hwndHscroll, hwndVscroll ;
75:
76: USHORT uCommHandle = NULL; /* COM port file handle */
77:
78: USHORT usRetCode, /* return code, value not to be saved */
79: uStatus,
80: Result = TRUE;
81:
82: USHORT uTempParity, uTempStopBits, uTempDataBits;
83:
84: char cSaveFile[24]; /* string to hold capture file name */
85:
86: struct CommRecord {
87: USHORT uPortName,
88: uBaudRate,
89: uDataBits,
90: uStopBits,
91: uParity,
92: uConnect,
93: uDialType,
94: uWaitTone,
95: uWaitCarrier;
96: char cString[24];
97: } CommSpec;
98:
99: /* ------------ thread related variables -------------- */
100:
101: LONG lReadSemTrigger;
102: TID idThread;
103: UCHAR cReadThreadStack[4096];
104:
105: /* ------------ Forward references & type checking -------- */
106:
107: BOOL ReadINIFile(char *);
108: void InitBuffers(void); /* Start the comm session */
109: BOOL InitCommPort(void); /* Initialise comm port */
110: void BuildCaption(int); /* build caption bar with file name */
111: void CloseComm(void); /* close modem connection & com port */
112: void GetLines(void); /* Gets pointer to each line & length */
113: void Error(int, int); /* Display error message */
114: void FAR PASCAL ReadCommThread();
115: void WriteCommPort(USHORT); /* write char to comm port */
116: void TestComm(void); /* write char to comm port */
117: void Dump();
118:
119: MRESULT EXPENTRY PMCommWndProc (HWND, USHORT, MPARAM, MPARAM);
120:
121: /* ===================== MAIN ========================== */
122: main (argc, argv)
123: int argc ;
124: char *argv [] ;
125: {
126: HMQ hmq ;
127: HWND hwndPMComm;
128: QMSG qmsg ;
129: ULONG flCreate;
130:
131: hab = WinInitialize (0);
132: hmq = WinCreateMsgQueue (hab, 0);
133:
134: WinLoadString (hab, NULL, IDS_CLASS, sizeof szClassName, szClassName);
135: WinLoadString (hab, NULL, IDS_TITLE, sizeof szTitleBar, szTitleBar);
136: WinLoadString (hab, NULL, IDS_INIFILE, sizeof szINIFile, szINIFile);
137: WinLoadString (hab, NULL, IDS_UNTITLED,sizeof szUnTitled, szUnTitled);
138:
139: WinRegisterClass (hab, szClassName, PMCommWndProc, 0L, 0);
140:
141: flCreate = FCF_STANDARD | FCF_VERTSCROLL | FCF_HORZSCROLL;
142: hWndFrame = WinCreateStdWindow (HWND_DESKTOP,
143: WS_VISIBLE | FS_ICON | FS_ACCELTABLE,
144: &flCreate, szClassName, szTitleBar,
145: 0L, NULL, ID_RESOURCE, &hwndPMComm);
146:
147: hGMenuWnd = WinWindowFromID ( hWndFrame, FID_MENU);
148:
149: if (argc > 1)
150: pFile = argv[1]; /* pass pointer to file */
151: else
152: pFile = NULL;
153:
154: bResult = ReadINIFile(pFile);
155:
156: while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
157: WinDispatchMsg (hab, &qmsg);
158:
159: DosSuspendThread (idThread);
160:
161: WinDestroyWindow (hWndFrame);
162: WinDestroyMsgQueue (hmq);
163: WinTerminate (hab);
164: return 0 ;
165: }
166:
167:
168: /* -----------------------------------------------
169: ReadINIFile
170:
171: Read in a file if one is provided
172: else try the default file.
173: If it is provided then gather the comm settings.
174:
175: ----------------------------------------------- */
176: BOOL ReadINIFile(pFile)
177: char *pFile;
178: {
179: FILE *fp ;
180: USHORT uBytesRead ;
181:
182: bGotSettings = FALSE;
183: bSettingsChanged = FALSE;
184:
185: if (pFile != NULL ) { /* read file name that is provided */
186: if ( (fp = fopen(pFile, "r")) == NULL) {
187: WinMessageBox (HWND_DESKTOP, hGWnd, pFile, "File not found", NULL, MB_OK);
188: BuildCaption( 2 ); /* untitled */
189: }
190: }
191: else /* read default file settings */
192: if ( (fp = fopen(szINIFile, "r")) == NULL) {
193: BuildCaption( 2 ); /* untitled */
194: }
195:
196: if (fp) {
197: uBytesRead = fread( &CommSpec, 1, sizeof(CommSpec), fp );
198: fclose(fp);
199: if (uBytesRead == sizeof(CommSpec)) {
200: bGotSettings = TRUE;
201: BuildCaption( (pFile ? 1 : 0) );
202: }
203: else {
204: WinMessageBox (HWND_DESKTOP, hGWnd, "Reading file.", NULL, NULL, MB_OK);
205: return FALSE;
206: }
207:
208: bResult = WinMessageBox (HWND_DESKTOP, hGWnd, "Do you wish to connect?",
209: "PM COMM", NULL, MB_YESNO);
210: if (bResult == MBID_YES)
211: WinPostMsg( hGWnd, WM_COMMAND, MPFROM2SHORT (IDM_START, 0), 0L );
212: }
213: return TRUE;
214:
215: }
216:
217:
218: /* -------------------------------------------------- */
219: /* This routine builds the caption bar.
220: */
221: void BuildCaption(iCaptionType)
222: int iCaptionType;
223: {
224:
225: /* always starts off "PM Terminal [ ] - " */
226: strcpy(cCaptionBuf, szTitleBar);
227: switch (iCaptionType) {
228: case 0:
229: strcat( cCaptionBuf, szINIFile ); /* default file name */
230: break;
231: case 1:
232: strcat( cCaptionBuf, pFile ); /* provided file name */
233: break;
234: default:
235: strcat( cCaptionBuf, szUnTitled ); /* untitled used */
236: break;
237: }
238:
239: WinSetWindowText( WinQueryWindow (hGWnd, QW_PARENT, FALSE), cCaptionBuf );
240:
241: }
242:
243:
244:
245: /* -------------------------------------------------
246: Set up everything for the comm session.
247: ------------------------------------------------- */
248: void InitBuffers()
249: {
250: int i;
251:
252: for ( i=0 ; i<BUFFERMAX ; i++ ) /* clear Display buffer */
253: cDisplayBuf[i] = 0;
254:
255: pTempBuf = cTempBuf;
256: for ( i=0 ; i<INBUFLENGTH ; i++ ) /* clear temp buffer */
257: *pTempBuf++ = 0;
258:
259: for ( i=0 ; i<MAXLINES ; i++ ) /* set line lenghts to 0 */
260: iLineLength[i] = 0;
261:
262: for ( i=0 ; i<MAXLINES ; i++ ) /* set ptr to each line */
263: pStartLine[i] = (&cDisplayBuf[0])+(i*MAXWIDTH);
264:
265: iMaxLines = 0;
266:
267: iBufPos = 0; /* set current buffer position */
268: xCursor = 0; /* set cursor position */
269: yCursor = 0;
270:
271: bEchoOn = FALSE; /* see what you type. */
272: bScroll = FALSE; /* set scroll so paint will work */
273: bOverFlow = FALSE; /* clear buffer overflow */
274: bCaptureOn = FALSE; /* capture input to a file. */
275:
276: bPauseOn = FALSE; /* allows you to pause a session */
277:
278: /* hide scroll bars */
279: WinSetParent(hwndHscroll, HWND_OBJECT, FALSE);
280: WinSetParent(hwndVscroll, HWND_OBJECT, FALSE);
281:
282: }
283:
284:
285: /* ------------------------------------------------- */
286: BOOL InitCommPort() /* initialise com port */
287: {
288:
289: USHORT ActionTaken; /* action: returned by OS/2 */
290: char cPortName[5]; /* port name with appended com # */
291:
292: char FlushData, /* data returned by flush IOCTL function */
293: FlushParm = FLUSH_CMDINFO; /* param to flush IOCTL function */
294:
295: struct LineChar { /* line characteristics */
296: BYTE bDataBits;
297: BYTE bParity;
298: BYTE bStopBits;
299: } sLineChar;
300:
301: struct DCB { /* device control block information */
302: USHORT usWriteTimeout;
303: USHORT usReadTimeout;
304: BYTE bFlags1;
305: BYTE bFlags2;
306: BYTE bFlags3;
307: BYTE bErrorReplacementChar;
308: BYTE bBreakReplacementChar;
309: BYTE bXONChar;
310: BYTE bXOFFChar;
311: } sDCB;
312:
313: /* open the com port */
314: sprintf( cPortName, "COM%d", CommSpec.uPortName );
315: if ((usRetCode = DosOpen( cPortName, &uCommHandle, &ActionTaken,
316: 0L, 0, 0x0001, 0x0042, 0L)) != 0) {
317: Error(ERR_DOSOPEN, usRetCode);
318: return FALSE;
319: }
320: /* set the baud rate */
321: if ((usRetCode = DosDevIOCtl(0L, &(CommSpec.uBaudRate),
322: SETBAUD, SERIAL, uCommHandle)) != 0) {
323: Error(ERR_IOCTLSETBAUD, usRetCode);
324: return FALSE;
325: }
326:
327: /* set Data Bits, Stop Bits, Parity */
328:
329: sLineChar.bDataBits = (BYTE) CommSpec.uDataBits;
330: sLineChar.bParity = (BYTE)(CommSpec.uParity ? 0 : 2);
331: sLineChar.bStopBits = (BYTE) CommSpec.uStopBits;
332:
333: if ((usRetCode = DosDevIOCtl(0L, &sLineChar, SETLINECHAR,
334: SERIAL, uCommHandle)) != 0) {
335: Error(ERR_IOCTLSETLINECHAR, usRetCode);
336: return FALSE;
337: }
338:
339: /* get device control block info */
340: if ((usRetCode = DosDevIOCtl( &sDCB, 0L, GETDCB, SERIAL,
341: uCommHandle)) != 0) {
342: Error(ERR_IOCTLGETDCB, usRetCode);
343: return FALSE;
344: }
345:
346: bSaveXONChar = sDCB.bXONChar;
347:
348: sDCB.bFlags2 |= 0x03; /* enable auto Xmit and recv flow control */
349: sDCB.bFlags3 &= 0xf9; /* clear read timeout flags */
350: sDCB.bFlags3 |= 0x04; /* set wait for something read timeout */
351: sDCB.usReadTimeout = READTIMEOUT; /* set read timout value */
352:
353: /* set device control block info */
354: if ((usRetCode = DosDevIOCtl(0L, (char *) &sDCB, SETDCB, SERIAL,
355: uCommHandle)) != 0) {
356: Error(ERR_IOCTLSETDCB, usRetCode);
357: return FALSE;
358: }
359:
360: /* flush transmit/receive queues */
361: if ((usRetCode = DosDevIOCtl(&FlushData, &FlushParm,
362: FLUSHINPUT, GENERIC, uCommHandle)) != 0)
363: Error(ERR_IOCTLFLUSHQUE, usRetCode);
364:
365: if ((usRetCode = DosDevIOCtl(&FlushData, &FlushParm,
366: FLUSHOUTPUT, GENERIC, uCommHandle)) != 0)
367: Error(ERR_IOCTLFLUSHQUE, usRetCode);
368:
369: return TRUE;
370:
371: }
372:
373:
374: /* -------------------------------------------------
375: ReadCommPort
376:
377: This routine is executed by a thread. It loops continuously
378: waiting to receive data from the comm port and writing it out
379: to a tempoary buffer. The loop waits under three conditions:
380: 1] The person selected the STOP menu item,
381: 2] The person selected the PAUSE menu item,
382: 3] The routine to display the characters in the current
383: input queue is not finished.
384: This thread terminates when the user exits the program.
385:
386: Suggestions/To do list:
387: o Make a circular buffer to have DosRead into, cInBuffer.
388: o Make another thread to take characters out of the
389: cInBuffer, and format them correctly into the DisplayBuffer.
390: ----------------------------------------------------*/
391:
392: void FAR PASCAL ReadCommThread()
393: {
394: USHORT usNumBytes; /* number of bytes actually read */
395: PUSHORT pfCommErr; /* pointer to variable to receive error */
396:
397: while ( !bExitReadThread ) {
398:
399: DosSemWait (&lReadSemTrigger, -1L); /* to allow for PAUSE */
400:
401:
402: if (bTestOn) {
403: if ((usRetCode = DosDevIOCtl( &pfCommErr, 0L, GETCOMERROR,
404: SERIAL, uCommHandle)) != 0)
405: Error(ERR_IOCTLGETCOMERROR, usRetCode);
406: }
407:
408: if ((usRetCode = DosRead(uCommHandle, cInBuffer, 1024, &usNumBytes)) != 0)
409: Error(ERR_DOSREAD, usRetCode);
410:
411: if (usNumBytes) {
412: DosSemSet (&lReadSemTrigger);
413: if (bCaptureOn) {
414:
415: FILE *fp ;
416:
417: if ((fp = fopen( "f:readcomm.dmp", "ab")) != NULL) {
418: fwrite( cInBuffer, 1, usNumBytes, fp );
419: fclose(fp);
420: }
421: }
422:
423: WinPostMsg( hGWnd, WM_BLAST, MPFROM2SHORT (0, usNumBytes), (MPARAM)0 );
424: /* pTempBuf = cInBuffer; */ /* may cause timing problem w/ word wrap */
425: }
426:
427: } /* end while */
428: DosExit(0,0);
429: }
430:
431:
432: /* ----------------------------------------------------
433: Write one character at a time to the Comm Port.
434:
435: Suggestions/To do list:
436: Make this a separate thread. Put the characters in a
437: circular buffer and put the characters out when it's ready.
438: ----------------------------------------------------*/
439: void WriteCommPort(usCharOut)
440: USHORT usCharOut;
441: {
442: USHORT uNumBytes; /* number of bytes actually written */
443:
444: if ((usRetCode = DosWrite(uCommHandle, &usCharOut, 1, &uNumBytes )) != 0)
445: Error(ERR_DOSWRITE, usRetCode);
446: }
447:
448:
449: /* ---------------------------------------------------- */
450: void CloseComm()
451: {
452:
453: FILE *fp ;
454:
455: char FlushData, /* data returned by flush IOCTL function */
456: FlushParm = FLUSH_CMDINFO; /* param to flush IOCTL function */
457:
458: if ( DosSemSet(&lReadSemTrigger) != 0)
459: WinMessageBox ( HWND_DESKTOP, hGWnd,
460: "Setting Sem ReadSem." , NULL, NULL, MB_OK);
461:
462: /* flush transmit/receive queues */
463: if ((usRetCode = DosDevIOCtl(&FlushData, &FlushParm,
464: FLUSHINPUT, GENERIC, uCommHandle)) != 0)
465: Error(ERR_IOCTLFLUSHQUE, usRetCode);
466:
467: if ((usRetCode = DosDevIOCtl(&FlushData, &FlushParm,
468: FLUSHOUTPUT, GENERIC, uCommHandle)) != 0)
469: Error(ERR_IOCTLFLUSHQUE, usRetCode);
470:
471: if ((usRetCode = DosClose(uCommHandle)) != 0)
472: WinMessageBox ( HWND_DESKTOP, hGWnd,
473: "Closing Comm Port" , NULL, NULL, MB_OK);
474: bCommOpen = FALSE;
475:
476: if ( bSettingsChanged ) {
477: bResult = WinMessageBox (HWND_DESKTOP, hGWnd, "Do you wish to Save?",
478: "Settings changed.", NULL, MB_YESNO);
479: if (bResult == MBID_YES) {
480: if ((fp = fopen( (pFile ? pFile : szINIFile), "w")) != NULL) {
481: fwrite( &CommSpec, 1, sizeof(CommSpec), fp );
482: fclose(fp);
483: }
484: }
485: bSettingsChanged = FALSE;
486: }
487: }
488:
489:
490:
491: /* ----------------------------------------------- */
492: MRESULT EXPENTRY AboutDlgProc (hDlg, msg, mp1, mp2)
493: HWND hDlg ;
494: USHORT msg ;
495: MPARAM mp1 ;
496: MPARAM mp2 ;
497: {
498: switch (msg) {
499: case WM_COMMAND:
500:
501: switch (COMMANDMSG(&msg)->cmd) {
502: case DID_OK:
503: case DID_CANCEL:
504: WinDismissDlg (hDlg, TRUE);
505: break ;
506:
507: default:
508: break ;
509: }
510: break ;
511:
512: default:
513: return WinDefDlgProc (hDlg, msg, mp1, mp2);
514: }
515: return FALSE ;
516: }
517:
518:
519: /* ----------------------------------------------- */
520: MRESULT EXPENTRY GetFileDlgProc (hDlg, msg, mp1, mp2)
521: HWND hDlg ;
522: USHORT msg ;
523: MPARAM mp1 ;
524: MPARAM mp2 ;
525: {
526: switch (msg) {
527: case WM_COMMAND:
528:
529: switch (COMMANDMSG(&msg)->cmd) {
530: case DID_OK:
531: WinQueryDlgItemText( hDlg, DB_FILENAME, 24, cSaveFile );
532: bCaptureOn = TRUE;
533: WinDismissDlg (hDlg, TRUE);
534:
535: case DID_CANCEL:
536: WinDismissDlg (hDlg, FALSE);
537: break ;
538:
539: default:
540: break ;
541: }
542: break ;
543:
544: default:
545: return WinDefDlgProc (hDlg, msg, mp1, mp2);
546: }
547: return FALSE ;
548: }
549:
550:
551: /* ----------------------------------------------- */
552: MRESULT EXPENTRY SettingsDlgProc (hDlg, msg, mp1, mp2)
553: HWND hDlg ;
554: USHORT msg ;
555: MPARAM mp1 ;
556: MPARAM mp2 ;
557: {
558: BOOL fResult;
559:
560: switch (msg) {
561:
562: case WM_INITDLG:
563: if (bGotSettings) {
564: WinSetDlgItemShort( hDlg, DB_PORT, CommSpec.uPortName, FALSE );
565: WinSetDlgItemShort( hDlg, DB_BAUD, CommSpec.uBaudRate, FALSE );
566: WinSetDlgItemText( hDlg, DB_STRING, CommSpec.cString );
567:
568: uTempParity = CommSpec.uParity + DB_PARITY;
569: uTempStopBits = CommSpec.uStopBits + DB_STOPBITS;
570: uTempDataBits = CommSpec.uDataBits + (DB_DATABITS-7);
571: }
572: else { /* set the defaults */
573: uTempParity = DB_PARITY+1; /* odd is default */
574: uTempStopBits = DB_STOPBITS; /* 1 is default */
575: uTempDataBits = DB_DATABITS+1; /* 8 is default */
576: }
577:
578: WinSendDlgItemMsg( hDlg, uTempParity, BM_SETCHECK,
579: MPFROM2SHORT(TRUE, 0), 0L );
580: WinSendDlgItemMsg( hDlg, uTempStopBits, BM_SETCHECK,
581: MPFROM2SHORT(TRUE, 0), 0L );
582: WinSendDlgItemMsg( hDlg, uTempDataBits, BM_SETCHECK,
583: MPFROM2SHORT(TRUE, 0), 0L );
584: break;
585:
586: case WM_CONTROL:
587:
588: if ( SHORT1FROMMP (mp1) >= DB_PARITY &&
589: SHORT1FROMMP (mp1) <= DB_PARITY+2 )
590: uTempParity = SHORT1FROMMP (mp1);
591:
592: if ( SHORT1FROMMP (mp1) >= DB_STOPBITS &&
593: SHORT1FROMMP (mp1) <= DB_STOPBITS+2 )
594: uTempStopBits = SHORT1FROMMP (mp1);
595:
596: if ( SHORT1FROMMP (mp1) >= DB_DATABITS &&
597: SHORT1FROMMP (mp1) <= DB_DATABITS+1 )
598: uTempDataBits = SHORT1FROMMP (mp1);
599:
600: break;
601:
602: case WM_COMMAND:
603:
604: switch (COMMANDMSG(&msg)->cmd) {
605: case DID_OK:
606:
607: WinQueryDlgItemShort( hDlg, DB_PORT, &CommSpec.uPortName, fResult);
608: WinQueryDlgItemShort( hDlg, DB_BAUD, &CommSpec.uBaudRate, fResult);
609: WinQueryDlgItemText( hDlg, DB_STRING, 24, CommSpec.cString );
610:
611: CommSpec.uParity = uTempParity - DB_PARITY;
612: CommSpec.uStopBits = uTempStopBits - DB_STOPBITS;
613: CommSpec.uDataBits = (uTempDataBits - DB_DATABITS)+7;
614:
615: bGotSettings = TRUE;
616: bSettingsChanged = TRUE;
617:
618: WinDismissDlg (hDlg, TRUE);
619: break ;
620:
621: case DID_CANCEL:
622: uTempParity = CommSpec.uParity + DB_PARITY;
623: uTempStopBits = CommSpec.uStopBits + DB_STOPBITS;
624: uTempDataBits = CommSpec.uDataBits + (DB_DATABITS-7);
625:
626: WinDismissDlg (hDlg, FALSE);
627: break ;
628: default:
629: break ;
630: }
631: break ;
632:
633: default:
634: return WinDefDlgProc (hDlg, msg, mp1, mp2);
635: }
636: return FALSE ;
637: }
638:
639:
640:
641: /* ----------------------------------------------- */
642: MRESULT EXPENTRY PMCommWndProc (hwnd, msg, mp1, mp2)
643: HWND hwnd ;
644: USHORT msg ;
645: MPARAM mp1 ;
646: MPARAM mp2 ;
647: {
648: static SEL selMemBlock ;
649: static SHORT iHscrollMax, iVscrollMax, iHscrollPos, iVscrollPos,
650: yDesc, xClient, yClient, xMax, yMax;
651:
652: static int iBytesRead; /* # of bytes read in comm buf */
653: FONTMETRICS fm ;
654: HPS hps ;
655: POINTL ptl ;
656: SHORT iPaintBegin, iPaintEnd, iHscrollInc, iVscrollInc ;
657: int iSpaces, j, iCount, iPaintBegin1 ;
658: RECTL rclInvalid ;
659: LONG lStyle ;
660:
661: QMSG qmsg ;
662:
663: hGWnd = hwnd; /* Set global window handle. */
664: switch (msg) {
665:
666: case WM_CREATE:
667:
668: /*----------------------
669: Query character size
670: ----------------------*/
671:
672: hps = WinGetPS (hwnd);
673:
674: GpiQueryFontMetrics (hps, (LONG) sizeof fm, &fm);
675: xChar = (SHORT) fm.lAveCharWidth ;
676: yChar = (SHORT) fm.lMaxBaselineExt ;
677: yDesc = (SHORT) fm.lMaxDescender ;
678:
679: WinReleasePS (hps);
680:
681: hwndHscroll = WinWindowFromID (
682: WinQueryWindow (hwnd, QW_PARENT, FALSE),
683: FID_HORZSCROLL);
684:
685: hwndVscroll = WinWindowFromID (
686: WinQueryWindow (hwnd, QW_PARENT, FALSE),
687: FID_VERTSCROLL);
688:
689: bPauseOn = FALSE;
690: WinEnableWindow (hwndHscroll, FALSE);
691: WinEnableWindow (hwndVscroll, FALSE);
692:
693: /* hide scroll bars */
694: WinSetParent(hwndHscroll, HWND_OBJECT, FALSE);
695: WinSetParent(hwndVscroll, HWND_OBJECT, FALSE);
696:
697: bExitReadThread = FALSE;
698:
699: DosSemSet (&lReadSemTrigger);
700: if ( DosCreateThread (ReadCommThread, &idThread,
701: cReadThreadStack + sizeof cReadThreadStack))
702: WinAlarm (HWND_DESKTOP, WA_ERROR);
703:
704: break ;
705:
706: case WM_DESTROY:
707:
708: if (bCommOpen)
709: CloseComm();
710:
711: bExitReadThread = TRUE;
712:
713: /* make sure these belong to the Frame before ending */
714: /* or you could also use a WinDestroyWindow on these. */
715:
716: if (!bPauseOn) {
717: WinSetParent(hwndHscroll, hWndFrame, FALSE);
718: WinSetParent(hwndVscroll, hWndFrame, FALSE);
719: }
720: break ;
721:
722:
723: case WM_SETFOCUS:
724:
725: if (LONGFROMMP (mp2))
726: {
727: WinCreateCursor (hwnd, xChar * xCursor,
728: yClient - yChar * (1 + yCursor),
729: xChar, yChar, CURSOR_SOLID, NULL);
730:
731: WinShowCursor (hwnd, xMax > 0 && yMax > 0);
732: }
733: else
734: WinDestroyCursor (hwnd);
735: break ;
736:
737:
738: case WM_INITMENU: /* Set menu state before displaying. */
739: /* ------------- Echo ----------- */
740: WinSendMsg (hGMenuWnd, MM_SETITEMATTR,
741: MPFROM2SHORT (IDM_ECHO, TRUE),
742: MPFROM2SHORT (MIA_CHECKED,
743: bEchoOn ? MIA_CHECKED : 0 ));
744: /* ------------- Word Wrap ----------- */
745: WinSendMsg (hGMenuWnd, MM_SETITEMATTR,
746: MPFROM2SHORT (IDM_WRAP, TRUE),
747: MPFROM2SHORT (MIA_CHECKED,
748: bWordWrap ? MIA_CHECKED : 0 ));
749: /* ------------- Pause ----------- */
750: WinSendMsg (hGMenuWnd, MM_SETITEMATTR,
751: MPFROM2SHORT (IDM_PAUSE, TRUE),
752: MPFROM2SHORT (MIA_CHECKED,
753: bPauseOn ? MIA_CHECKED : 0 ));
754: /* ------------- Capture ----------- */
755: WinSendMsg (hGMenuWnd, MM_SETITEMATTR,
756: MPFROM2SHORT (IDM_CAPTURE, TRUE),
757: MPFROM2SHORT (MIA_CHECKED,
758: bCaptureOn ? MIA_CHECKED : 0 ));
759: /* ------------- Test ----------- */
760: WinSendMsg (hGMenuWnd, MM_SETITEMATTR,
761: MPFROM2SHORT (IDM_TEST, TRUE),
762: MPFROM2SHORT (MIA_CHECKED,
763: bTestOn ? MIA_CHECKED : 0 ));
764: /* ------------- Settings ----------- */
765: WinSendMsg (hGMenuWnd, MM_SETITEMATTR,
766: MPFROM2SHORT (IDM_SETTINGS, TRUE),
767: MPFROM2SHORT (MIA_CHECKED,
768: bGotSettings ? MIA_CHECKED : 0 ));
769:
770: /* ------------- Comm Open ----------- */
771:
772: WinSendMsg (hGMenuWnd, MM_SETITEMATTR,
773: MPFROM2SHORT (IDM_START, TRUE),
774: MPFROM2SHORT (MIA_DISABLED,
775: (bCommOpen && bGotSettings) ? MIA_DISABLED : 0 ));
776:
777: WinSendMsg (hGMenuWnd, MM_SETITEMATTR,
778: MPFROM2SHORT (IDM_STOP, TRUE),
779: MPFROM2SHORT (MIA_DISABLED,
780: bCommOpen ? 0 : MIA_DISABLED ));
781:
782: WinSendMsg (hGMenuWnd, MM_SETITEMATTR,
783: MPFROM2SHORT (IDM_CAPTURE, TRUE),
784: MPFROM2SHORT (MIA_DISABLED,
785: bCommOpen ? 0 : MIA_DISABLED ));
786:
787: WinSendMsg (hGMenuWnd, MM_SETITEMATTR,
788: MPFROM2SHORT (IDM_BREAK, TRUE),
789: MPFROM2SHORT (MIA_DISABLED,
790: bCommOpen ? 0 : MIA_DISABLED ));
791:
792: break ;
793:
794:
795: case WM_BLAST:
796:
797: pTempBuf = cInBuffer; /* set pointer to comm input buffer */
798: iBytesRead = SHORT2FROMMP (mp1);
799:
800: if (bCaptureOn && iBytesRead > 0 ) {
801:
802: FILE *fp ;
803:
804: if ((fp = fopen( cSaveFile, "ab")) != NULL) {
805: fwrite( pTempBuf, 1, iBytesRead, fp );
806: fclose(fp);
807: }
808: }
809:
810: WinShowCursor (hwnd, FALSE);
811: for ( iToFormat=0 ; iToFormat<iBytesRead ; iToFormat++, pTempBuf++ ) {
812:
813: switch (*pTempBuf) {
814: case '\b': /* backspace */
815: iLineLength[iMaxLines]--;
816: xCursor--;
817: iBufPos--;
818:
819: break;
820: case '\r':
821: break;
822: case '\n':
823:
824: if ( (yCursor >= (yMax - 1)) ) {
825: WinScrollWindow (hwnd, 0, yChar * 1,
826: NULL, NULL, NULL, NULL,
827: SW_INVALIDATERGN); /* send Paint msg */
828: bScroll = TRUE;
829: WinUpdateWindow (hwnd);
830:
831: }
832: else {
833: yCursor++;
834: }
835: if (iMaxLines +1 >= MAXLINES)
836: bOverFlow = TRUE;
837:
838: iMaxLines = (iMaxLines + 1) % MAXLINES ;
839: iBufPos = iMaxLines * MAXWIDTH;
840: iMaxWidth = iBufPos + MAXWIDTH;
841:
842: /* clear next line. This is not necessary because
843: line length is kept. */
844: for ( i=iBufPos ; i<iBufPos+MAXWIDTH ; i++ )
845: cDisplayBuf[i] = ' ';
846:
847: iLineLength[iMaxLines] = 0;
848: xCursor = 0 ; /* move under \r */
849:
850: break;
851:
852: case '\t':
853:
854: iSpaces = min (8 - xCursor % 8, xMax - xCursor);
855:
856: iLineLength[iMaxLines] += iSpaces;
857: xCursor += iSpaces;
858: iBufPos += iSpaces;
859:
860: break ;
861:
862: default: /* format & fill display buffer */
863:
864: j=0; pBlastString = &cDisplayBuf[iBufPos];
865: while ( iToFormat < iBytesRead &&
866: *pTempBuf != '\b' &&
867: *pTempBuf != '\r' &&
868: *pTempBuf != '\n' &&
869: *pTempBuf != '\t' ) {
870:
871: cDisplayBuf[iBufPos] = *pTempBuf;
872: cDisplayBuf[iBufPos] = cInBuffer[iToFormat];
873:
874: iBufPos++; iToFormat++; j++; pTempBuf++;
875:
876: /* the next few lines are used to allow word wrap
877: by forcing a \n as the next character.
878: This is safe to do since the 80th char is
879: already in the Display Buffer.
880: */
881:
882: if (iBufPos >= iMaxWidth ) {
883: if (bWordWrap) { /* simulate a line feed */
884: iToFormat--;
885: pTempBuf--;
886: cInBuffer[iToFormat] = '\n';
887: }
888: else { /* truncate rest of line. */
889: while ( iToFormat < iBytesRead &&
890: *pTempBuf != '\r' &&
891: *pTempBuf != '\n' ) {
892:
893: iToFormat++; pTempBuf++;
894: }
895: }
896: break;
897: }
898: /* end of word wrap section */
899: }
900:
901: /* the next few lines are used to compensate
902: for the increment in the for loop */
903: if (iToFormat != iBytesRead) {
904: iToFormat--;
905: pTempBuf--;
906: }
907: iLineLength[iMaxLines] += j;
908:
909: hps = WinGetPS (hwnd);
910: ptl.x = xCursor * xChar ;
911: ptl.y = yClient - yChar * (yCursor + 1) + yDesc ;
912: GpiSetBackMix (hps, BM_OVERPAINT);
913: GpiCharStringAt (hps, &ptl, (long)j, pBlastString);
914: GpiRestorePS (hps, -1L); /* fix 2 */
915: WinReleasePS (hps);
916:
917: xCursor += j;
918: break;
919:
920: } /* end switch */
921: } /* end for */
922:
923: iToFormat = 0;
924:
925: WinCreateCursor (hwnd, xChar * xCursor,
926: yClient - yChar * (1 + yCursor),
927: 0, 0, CURSOR_SETPOS, NULL);
928: WinShowCursor (hwnd, TRUE);
929:
930: DosSemClear (&lReadSemTrigger);
931:
932: break ;
933:
934:
935:
936: case WM_PAINT:
937: hps = WinBeginPaint (hwnd, NULL, &rclInvalid);
938:
939: WinShowCursor (hwnd, FALSE);
940:
941: GpiErase (hps);
942:
943: iCount = 0;
944:
945: if (bScroll) {
946: iPaintBegin = iMaxLines; /* skip painting */
947: bScroll = FALSE;
948: }
949: else
950: if ( (iMaxLines+1) <= yMax) {
951: iPaintBegin = 0;
952: yCursor = iMaxLines; /* yMax-1 */
953: if (bOverFlow) {
954: iCount = yMax - (iMaxLines+1);
955: iPaintBegin1 = (MAXLINES - iCount);
956: yCursor = yMax-1;
957: }
958: }
959: else {
960: if ( (iMaxLines+1) > yMax) {
961: iPaintBegin = (iMaxLines+1) - yMax;
962: yCursor = yMax-1;
963: }
964: }
965: ptl.x = 0;
966:
967: for ( i=0 ; i<iCount ; i++,iPaintBegin1++) {
968: ptl.y = (yClient - (yChar * (i + 1 ))) + yDesc ;
969: GpiCharStringAt (hps, &ptl, (LONG) iLineLength[iPaintBegin1],
970: pStartLine[iPaintBegin1] );
971: }
972: while ( usRetCode = (USHORT)WinQueryQueueStatus(hab) ) {
973: WinPeekMsg (hab, &qmsg, NULL, 0, 0, PM_NOREMOVE);
974: if ( qmsg.msg == WM_QUIT ) return TRUE;
975: WinGetMsg (hab, &qmsg, NULL, 0, 0);
976: WinDispatchMsg (hab, &qmsg);
977: }
978: for ( i=0 ; iPaintBegin<=iMaxLines ; i++,iPaintBegin++) {
979: ptl.y = (yClient - (yChar * (iCount + i + 1 ))) + yDesc ;
980: GpiCharStringAt (hps, &ptl, (LONG) iLineLength[iPaintBegin],
981: pStartLine[iPaintBegin] );
982: }
983: GpiRestorePS (hps, -1L); /* fix 2 */
984: WinEndPaint (hps);
985:
986: WinCreateCursor (hwnd, xChar*xCursor, yClient - yChar * (1 + yCursor),
987: 0, 0, CURSOR_SETPOS, NULL);
988: WinShowCursor (hwnd, TRUE);
989:
990: break ;
991:
992:
993:
994: case WM_SIZE:
995: xClient = SHORT1FROMMP (mp2);
996: yClient = SHORT2FROMMP (mp2);
997:
998: xMax = min (MAXWIDTH, xClient / xChar);
999: yMax = min (MAXLINES, yClient / yChar);
1000:
1001: iHscrollMax = max (0, MAXWIDTH + 2 - xClient / xChar);
1002: iHscrollPos = min (iHscrollPos, iHscrollMax);
1003:
1004: iVscrollMax = max (0, iMaxLines - yClient / yChar);
1005: iVscrollPos = min (iVscrollPos, iVscrollMax);
1006:
1007: if (hwndHscroll) {
1008: WinSendMsg (hwndHscroll, SBM_SETSCROLLBAR,
1009: MPFROM2SHORT (iHscrollPos, 0),
1010: MPFROM2SHORT (0, iHscrollMax));
1011:
1012: WinSendMsg (hwndVscroll, SBM_SETSCROLLBAR,
1013: MPFROM2SHORT (iVscrollPos, 0),
1014: MPFROM2SHORT (0, iVscrollMax));
1015: }
1016:
1017: if ( bPauseOn ) {
1018: WinEnableWindow (hwndHscroll, iHscrollMax ? TRUE : FALSE);
1019: WinEnableWindow (hwndVscroll, iVscrollMax ? TRUE : FALSE);
1020: }
1021:
1022: /* this changes the clipping region of the cursor */
1023: WinDestroyCursor (hwnd);
1024: WinCreateCursor (hwnd, xChar * xCursor,
1025: yClient - yChar * (1 + yCursor),
1026: xChar, 0, CURSOR_SOLID | CURSOR_FLASH, NULL);
1027:
1028: WinShowCursor (hwnd, xMax > 0 && yMax > 0);
1029:
1030: break ;
1031:
1032:
1033: case WM_COMMAND:
1034:
1035: switch (COMMANDMSG(&msg)->cmd) {
1036: case IDM_ABOUT:
1037: WinDlgBox (HWND_DESKTOP, hwnd, AboutDlgProc,
1038: NULL, IDD_ABOUT, NULL);
1039: break ;
1040:
1041: case IDM_CTRLC:
1042: WriteCommPort( 0x03 );
1043:
1044: break ;
1045:
1046: case IDM_DATE:
1047: TestComm(); /* display date */
1048:
1049: break ;
1050:
1051: case IDM_SETTINGS:
1052: WinDlgBox (HWND_DESKTOP, hwnd, SettingsDlgProc,
1053: NULL, IDD_SETTINGS, NULL);
1054: break ;
1055:
1056: case IDM_START:
1057: if (bGotSettings) {
1058:
1059: InitBuffers();
1060:
1061: bResult = InitCommPort(); /* init and open COMM port */
1062: if (bResult == TRUE) {
1063: bCommOpen = TRUE;
1064: DosSemClear (&lReadSemTrigger);
1065: WinInvalidateRect( hGWnd, NULL, FALSE );
1066: WinSetFocus( HWND_DESKTOP, hGWnd);
1067: }
1068:
1069: /* make modem connection if requested */
1070: /* if (modem())
1071: * Result = make_modem_conn();
1072: */
1073: }
1074: else
1075: WinMessageBox ( HWND_DESKTOP, hwnd,
1076: "Comm settings must be set first.", NULL, NULL, MB_OK);
1077: break ;
1078:
1079: case IDM_STOP:
1080: if (bCommOpen)
1081: CloseComm();
1082: bCommOpen = FALSE;
1083: bCaptureOn = FALSE;
1084:
1085: break ;
1086:
1087: case IDM_ECHO:
1088: bEchoOn = !bEchoOn;
1089: break ;
1090:
1091: case IDM_WRAP:
1092: bWordWrap = !bWordWrap;
1093: break ;
1094:
1095: case IDM_CAPTURE:
1096:
1097: if ( bCaptureOn == FALSE ) { /* get capture file name */
1098: WinDlgBox (HWND_DESKTOP, hwnd, GetFileDlgProc,
1099: NULL, IDD_GETFILE, NULL);
1100: }
1101: else
1102: bCaptureOn = FALSE;
1103:
1104: WinQueryWindowText( WinQueryWindow (hGWnd, QW_PARENT, FALSE),
1105: 40, cCaptionBuf );
1106:
1107: pTempPt = cCaptionBuf;
1108:
1109: while (*pTempPt != ']')
1110: pTempPt++;
1111:
1112: pTempPt--;
1113: *pTempPt = (char)(bCaptureOn ? 'C' : ' ');
1114: WinSetWindowText( WinQueryWindow (hGWnd, QW_PARENT, FALSE),
1115: cCaptionBuf );
1116:
1117: break ;
1118:
1119: case IDM_TEST:
1120: bTestOn = !bTestOn;
1121:
1122: Dump();
1123:
1124: break ;
1125:
1126: case IDM_BREAK :/* send BREAK to the com port */
1127: /* break = 0x7F, DEC 127 */
1128: if ((usRetCode = DosDevIOCtl(&uStatus, 0L,
1129: SETBREAKON, SERIAL, uCommHandle)) != 0)
1130: Error(ERR_IOCTLSETBREAKON, usRetCode);
1131: DosSleep(1L);
1132: if ((usRetCode = DosDevIOCtl(&uStatus, 0L,
1133: SETBREAKOFF, SERIAL, uCommHandle)) != 0)
1134: Error(ERR_IOCTLSETBREAKOFF, usRetCode);
1135: break;
1136:
1137:
1138: case IDM_PAUSE:
1139: bPauseOn = !bPauseOn;
1140:
1141: WinMessageBox (HWND_DESKTOP, hGWnd,
1142: "Due to time,\nPause has not been implemented",
1143: "WARNING!", NULL, MB_OK);
1144:
1145: if (bPauseOn) { /* un-hide scroll bars */
1146: WinSetParent(hwndHscroll, hWndFrame, FALSE);
1147: WinSetParent(hwndVscroll, hWndFrame, FALSE);
1148: /* send control S to host? */
1149:
1150: }
1151: else { /* hide scroll bars */
1152: WinSetParent(hwndHscroll, HWND_OBJECT, FALSE);
1153: WinSetParent(hwndVscroll, HWND_OBJECT, FALSE);
1154: /* send control S to host? */
1155:
1156: }
1157:
1158: WinEnableWindow (hwndHscroll, bPauseOn ? TRUE : FALSE);
1159: WinEnableWindow (hwndVscroll, bPauseOn ? TRUE : FALSE);
1160:
1161: WinPostMsg (hWndFrame, WM_UPDATEFRAME, 0L, 0L);
1162: /* make this smarter */
1163: WinInvalidateRect( hGWnd, NULL, FALSE );
1164:
1165: break ;
1166:
1167: default:
1168: break ;
1169: } /* end switch */
1170: break ; /* break WM_COMMAND */
1171:
1172:
1173: case WM_HSCROLL:
1174: switch (SHORT2FROMMP (mp2))
1175: {
1176: case SB_LINELEFT:
1177: iHscrollInc = -1 ;
1178: break ;
1179:
1180: case SB_LINERIGHT:
1181: iHscrollInc = 1 ;
1182: break ;
1183:
1184: case SB_PAGELEFT:
1185: iHscrollInc = -8 ;
1186: break ;
1187:
1188: case SB_PAGERIGHT:
1189: iHscrollInc = 8 ;
1190: break ;
1191:
1192: case SB_SLIDERPOSITION:
1193: iHscrollInc = SHORT1FROMMP (mp2) - iHscrollPos;
1194: break ;
1195:
1196: default:
1197: iHscrollInc = 0 ;
1198: break ;
1199: }
1200:
1201: if (iHscrollInc = max (-iHscrollPos,
1202: min (iHscrollInc, iHscrollMax - iHscrollPos)))
1203: {
1204: iHscrollPos += iHscrollInc ;
1205: WinScrollWindow (hwnd, -xChar * iHscrollInc, 0,
1206: NULL, NULL, NULL, NULL, SW_INVALIDATERGN);
1207:
1208: WinSendMsg (hwndHscroll, SBM_SETPOS,
1209: MPFROM2SHORT (iHscrollPos, 0L), NULL);
1210: }
1211: break ;
1212:
1213:
1214: case WM_VSCROLL:
1215: switch (SHORT2FROMMP (mp2)) {
1216: case SB_LINEUP:
1217: iVscrollInc = -1 ;
1218: break ;
1219:
1220: case SB_LINEDOWN:
1221: iVscrollInc = 1 ;
1222: break ;
1223:
1224: case SB_PAGEUP:
1225: iVscrollInc = min (-1, -yClient / yChar);
1226: break ;
1227:
1228: case SB_PAGEDOWN:
1229: iVscrollInc = max (1, yClient / yChar);
1230: break ;
1231:
1232: case SB_SLIDERTRACK:
1233: iVscrollInc = SHORT1FROMMP (mp2) - iVscrollPos;
1234: break ;
1235:
1236: default:
1237: iVscrollInc = 0 ;
1238: break ;
1239: }
1240: if ( yCursor ) {
1241: WinScrollWindow (hwnd, 0, yChar * iVscrollInc,
1242: NULL, NULL, NULL, NULL,
1243: SW_INVALIDATERGN); /* send Paint msg */
1244: bScroll = TRUE;
1245: WinUpdateWindow (hwnd);
1246: }
1247: break ;
1248:
1249:
1250: case WM_CHAR:
1251:
1252: if (xMax == 0 || yMax == 0)
1253: break ;
1254:
1255: if (CHARMSG(&msg)->fs & KC_KEYUP)
1256: break ;
1257:
1258: for (i = 0 ; i < CHARMSG(&msg)->cRepeat ; i++) {
1259: ptl.x = xCursor * xChar ;
1260: ptl.y = yClient - yChar * (yCursor + 1) + yDesc ;
1261:
1262: /*------------------------
1263: Process character keys
1264: ------------------------*/
1265:
1266: if (CHARMSG(&msg)->fs & KC_CHAR) {
1267:
1268: switch (CHARMSG(&msg)->chr) {
1269:
1270: /*---------------
1271: Backspace key
1272: ---------------*/
1273: case '\b':
1274:
1275: if (xCursor == 0)
1276: break ;
1277:
1278: if (bEchoOn) {
1279: WinShowCursor (hwnd, FALSE);
1280: WinSendMsg (hwnd, WM_CHAR,
1281: MPFROM2SHORT (KC_VIRTUALKEY, 1),
1282: MPFROM2SHORT (0, VK_LEFT));
1283:
1284: WinSendMsg (hwnd, WM_CHAR,
1285: MPFROM2SHORT (KC_VIRTUALKEY, 1),
1286: MPFROM2SHORT (0, VK_DELETE));
1287:
1288: /* this should go in VK_DEL section */
1289:
1290: xCursor--;
1291: iBufPos--;
1292: cDisplayBuf[iBufPos] = ' ';
1293: iLineLength[iMaxLines]--;
1294: }
1295:
1296: if (bCommOpen)
1297: WriteCommPort( LOUSHORT(mp2) );
1298:
1299: break ;
1300:
1301: /*---------
1302: Tab key
1303: ---------*/
1304: case '\t':
1305:
1306: if (bEchoOn) {
1307: i = min (8 - xCursor % 8, xMax - xCursor);
1308:
1309: WinSendMsg (hwnd, WM_CHAR,
1310: MPFROM2SHORT (KC_CHAR, i),
1311: MPFROM2SHORT ((USHORT) ' ', 0));
1312: }
1313:
1314: if (bCommOpen)
1315: WriteCommPort( LOUSHORT(mp2) );
1316:
1317: break ;
1318:
1319: /*-----------------------
1320: Enter (or Return) key
1321: -----------------------*/
1322: case '\r':
1323:
1324: if (bEchoOn) {
1325:
1326: if ( (yCursor >= (yMax - 1)) ) {
1327: WinSendMsg (hwnd, WM_VSCROLL, 0L,
1328: MPFROM2SHORT(0,SB_LINEDOWN) );
1329: WinShowCursor (hwnd, FALSE);
1330: }
1331: else {
1332: yCursor++;
1333: }
1334: if (iMaxLines +1 >= MAXLINES)
1335: bOverFlow = TRUE;
1336:
1337: iMaxLines = (iMaxLines + 1) % MAXLINES ;
1338:
1339: iLineLength[iMaxLines] = 0;
1340:
1341: iBufPos = iMaxLines * MAXWIDTH;
1342:
1343: xCursor = 0 ;
1344: }
1345:
1346: if (bCommOpen) {
1347: WriteCommPort( '\r' );
1348: /* WriteCommPort( '\n' ); */
1349: }
1350: break ;
1351:
1352: case '\n': /* this must be \n for enter to work */
1353: break ;
1354:
1355: /*-------------------
1356: Normal characters
1357: -------------------*/
1358: default:
1359:
1360: cDisplayBuf[iBufPos] = (char)(LOUSHORT(mp2));
1361: /*
1362: FILLBUF (xCursor, yCursor) =
1363: (CHAR) CHARMSG(&msg)->chr ;
1364: */
1365:
1366: if (bEchoOn) {
1367: WinShowCursor (hwnd, FALSE);
1368:
1369: xCursor++;
1370: iBufPos++;
1371:
1372: iLineLength[iMaxLines]++;
1373:
1374: hps = WinGetPS (hwnd);
1375:
1376: GpiSetBackMix (hps, BM_OVERPAINT);
1377: GpiCharStringAt (hps, &ptl, 1L,
1378: (CHAR *) & CHARMSG(&msg)->chr);
1379: GpiRestorePS (hps, -1L); /* fix 2 */
1380:
1381: WinReleasePS (hps);
1382:
1383: WinShowCursor (hwnd, TRUE);
1384: }
1385:
1386: if (bCommOpen)
1387: WriteCommPort( LOUSHORT(mp2) );
1388: break ;
1389: }
1390: }
1391: /*---------------------------
1392: Process noncharacter keys
1393: ---------------------------*/
1394:
1395: else if ( CHARMSG(&msg)->fs & KC_VIRTUALKEY
1396: && bPauseOn == TRUE )
1397: {
1398: switch (CHARMSG(&msg)->vkey) {
1399: /*----------------------
1400: Cursor movement keys
1401: ----------------------*/
1402:
1403: case VK_LEFT:
1404:
1405: xCursor = (xCursor - 1 + xMax) % xMax ;
1406:
1407: if (xCursor == xMax - 1)
1408: yCursor = (yCursor - 1 + yMax) % yMax ;
1409: break ;
1410:
1411: case VK_RIGHT:
1412:
1413: if (0 == (xCursor = (xCursor + 1) % xMax))
1414: yCursor = (yCursor + 1) % yMax ;
1415: break ;
1416:
1417: case VK_UP:
1418:
1419: yCursor = (yCursor - 1 + yMax) % yMax ;
1420:
1421: if (yCursor == yMax - 1)
1422: xCursor = (xCursor - 1 + xMax) % xMax ;
1423: break ;
1424:
1425: case VK_DOWN:
1426:
1427: if (0 == (yCursor = (yCursor + 1) % yMax))
1428: xCursor = (xCursor + 1) % xMax ;
1429: break ;
1430:
1431: case VK_PAGEUP:
1432:
1433: yCursor = 0 ;
1434: break ;
1435:
1436: case VK_PAGEDOWN:
1437:
1438: yCursor = yMax - 1 ;
1439: break ;
1440:
1441: case VK_HOME:
1442:
1443: xCursor = 0 ;
1444: break ;
1445:
1446: case VK_END:
1447:
1448: xCursor = min (iLineLength[iMaxLines]+1, xMax - 1);
1449: break ;
1450:
1451: default:
1452: return FALSE ;
1453: }
1454: }
1455:
1456: else
1457: if ( CHARMSG(&msg)->fs & KC_VIRTUALKEY &&
1458: CHARMSG(&msg)->vkey == VK_DELETE ) {
1459:
1460: if (bCommOpen)
1461: WriteCommPort( 0x7F );
1462: break ;
1463: }
1464: else
1465: return FALSE ;
1466: }
1467: /* this test was put here if a delete key was pressed during the
1468: painting process. */
1469: if (iToFormat >= iBytesRead ) {
1470: WinCreateCursor (hwnd, xChar * xCursor,
1471: yClient - yChar * (1 + yCursor),
1472: 0, 0, CURSOR_SETPOS, NULL);
1473: WinShowCursor (hwnd, TRUE);
1474: }
1475: return TRUE ;
1476:
1477:
1478: case WM_ERASEBACKGROUND:
1479: return TRUE ;
1480:
1481: default:
1482: return WinDefWindowProc (hwnd, msg, mp1, mp2);
1483: }
1484: return FALSE ;
1485: }
1486:
1487:
1488:
1489: /* ------------------------------------------------
1490: Dump the current contents of Display Buffer
1491: to a file to examine
1492: ------------------------------------------------ */
1493: void Dump()
1494: {
1495: FILE *fp ;
1496: USHORT i;
1497:
1498: if ((fp = fopen("f:display.dmp", "w")) != NULL) {
1499: i = fwrite( pStartLine[0], 1, BUFFERMAX, fp );
1500: for ( i=0 ; i<MAXLINES ; i++ )
1501: fprintf(fp, "\n Bytes: %d,%s ", iLineLength[i], pStartLine[i] );
1502: fclose(fp);
1503: }
1504: }
1505:
1506:
1507:
1508: /* ---------------------------------------------------- */
1509: void TestComm()
1510: {
1511: USHORT uNumBytes; /* return # of bytes actually written */
1512: char cTestString[9];
1513:
1514: cTestString[0] = 'c';
1515: cTestString[1] = 'a';
1516: cTestString[2] = 'l';
1517: cTestString[3] = ' ';
1518: cTestString[4] = '1';
1519: cTestString[5] = '9';
1520: cTestString[6] = '8';
1521: cTestString[7] = '8';
1522: cTestString[8] = '\r';
1523:
1524: if ((usRetCode = DosWrite(uCommHandle, cTestString, 9, &uNumBytes )) != 0)
1525: Error(ERR_DOSWRITE, usRetCode);
1526:
1527: }
1528:
1529: /* ---------------------------------------------------- */
1530: void Error( iErrNum, iRetCode)
1531: int iErrNum;
1532: int iRetCode;
1533: {
1534: WinMessageBox ( HWND_DESKTOP, hGWnd, ErrMsg[iErrNum] , NULL, NULL, MB_OK);
1535: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.