Annotation of pmsdk/samples/pmcomm/pmcomm.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.