home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / COMTALK.ZIP / COMTALK.C < prev    next >
C/C++ Source or Header  |  1989-02-08  |  14KB  |  513 lines

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