Annotation of pmsdk/samples/pmcomm/pmcomm.c, revision 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.