home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk11 / tk3 / comtalk / comtalk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-20  |  14.0 KB  |  516 lines

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