home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / windows / winterm / term.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  17.9 KB  |  616 lines

  1. /*
  2. /*                    --- term.c ---
  3. **
  4. **  This example code is a Windows terminal emulator. It can transfer
  5. **  files using ASCII, XMODEM, and YMODEM protocols. This program is
  6. **  provided as an axample of the use of the PCL4W library.
  7. **
  8. **  In order to compile TERM, you will need PCL4W.LIB, PCL4W.DLL, and
  9. **  PCL4W.H from the PCL4W distribution disk. All source files for TERM
  10. **  are provided except for the drivers for XMODEM and YMODEM (which are
  11. **  provided in the registered product).
  12. **
  13. **  For a list of files that comprise the TERM application, see
  14. **  TERM._M_ or TERM._B_  (Microsoft & Borland makefiles).
  15. **
  16. */
  17.  
  18. #include "windows.h"
  19. #include "commdlg.h"
  20. #include "term.h"
  21. #include "info.h"
  22. #include "pcl4w.h"
  23. #include "sioerror.h"
  24. #include "ascii.h"
  25. #include "term_io.h"
  26. #include "asdriver.h"
  27. #include "xydriver.h"
  28. #include "expect.h"
  29. #include "config.h"
  30. #include "paint.h"
  31. #include "line.h"
  32. #include "modem_io.h"
  33. #include "miscell.h"
  34. #include "about.h"
  35.  
  36. /* public globals */
  37. HWND hMainWnd;            /* main window handle */
  38. HWND hInfoWnd;            /* popup handle */
  39. HANDLE hInstance;         /* program instance */
  40. int OnLineFlag = FALSE;   /* TRUE: online */
  41. int FatalFlag = FALSE;    /* TRUE: fatal error */
  42. char XferState = ' ';     /* 'X' = XMODEM */
  43.                           /* 'Y' = YMODEM */
  44.                           /* 'M' = SendToModem */
  45.                           /* 'A' = ASCII transfer */
  46. /* miscellaneous functions */
  47. void ErrorCheck(int);
  48.  
  49. #define MAXFILENAME 256
  50. #define POPWIDTH    200
  51. #define POPHEIGHT   100
  52.  
  53. /* private */
  54. static int ShowDebugFlag = FALSE;
  55. static int DebugValue = 0;
  56. static char NCGchar = 'C';
  57. static int LastPacket;
  58. static int LastNAKcount = 0;
  59. static long HideTime = 0L;
  60. static RECT MainRect;
  61. static OPENFILENAME ofn;
  62. static char szFilterSpec[128] = "All Files (*.*)\0*.*\0";
  63. static char szFileName[MAXFILENAME];
  64. static char szFileTitle[MAXFILENAME];
  65.  
  66. /*
  67. ** PostMainHandle() is required only for the
  68. ** Shareware version of PCL4W.
  69. */
  70.  
  71. #if __cplusplus
  72. extern "C" void FAR PASCAL PostMainHandle(HWND);
  73. #else
  74. extern void FAR PASCAL PostMainHandle(HWND);
  75. #endif
  76.  
  77. int PASCAL WinMain(HANDLE hInst,HANDLE hPrevInstance,
  78.                    LPSTR lpCmdLine,int nCmdShow)
  79. {WNDCLASS  wc1, wc2;
  80.  MSG msg;
  81.  BOOL Result1;
  82.  BOOL Result2;
  83.  if(!hPrevInstance)
  84.    {/* register main window class */
  85.     wc1.style = CS_HREDRAW | CS_VREDRAW;
  86.     wc1.lpfnWndProc = MainWndProc;
  87.     wc1.cbClsExtra = 0;
  88.     wc1.cbWndExtra = 0;
  89.     wc1.hInstance = hInst;
  90.     wc1.hIcon = LoadIcon(hInst, "TermIcon");
  91.     wc1.hCursor = LoadCursor(NULL, IDC_ARROW);
  92.     wc1.hbrBackground = GetStockObject(WHITE_BRUSH);
  93.     wc1.lpszMenuName =  "TermMenu";
  94.     wc1.lpszClassName = "TermWClass";
  95.     Result1 = RegisterClass(&wc1);
  96.  
  97.     /* register popup window class */
  98.     wc2.style = CS_HREDRAW | CS_VREDRAW | CS_PARENTDC;
  99.     wc2.lpfnWndProc = InfoWndProc;
  100.     wc2.cbClsExtra = 0;
  101.     wc2.cbWndExtra = 0;
  102.     wc2.hInstance = hInst;
  103.     wc2.hIcon = NULL;
  104.     wc2.hCursor = LoadCursor(NULL, IDC_ARROW);
  105.     wc2.hbrBackground = GetStockObject(WHITE_BRUSH);
  106.     wc2.lpszMenuName =  NULL;
  107.     wc2.lpszClassName = "InfoWClass";
  108.     Result2 = RegisterClass(&wc2);
  109.  
  110.     if((!Result1)||(!Result2)) return FALSE;
  111.    }
  112.  
  113.  /* create main window */
  114.  hInstance = hInst;
  115.  hMainWnd = CreateWindow(
  116.         "TermWClass",     "Term",          WS_OVERLAPPEDWINDOW,
  117.         CW_USEDEFAULT,    CW_USEDEFAULT,
  118.         CW_USEDEFAULT,    CW_USEDEFAULT,
  119.         NULL,             NULL,
  120.         hInstance,        NULL);
  121.  
  122.  /* fill in non-variant fields of OPENFILENAME struct. */
  123.  ofn.lStructSize       = sizeof(OPENFILENAME);
  124.  ofn.hwndOwner         = hMainWnd;
  125.  ofn.lpstrFilter       = szFilterSpec;
  126.  ofn.lpstrCustomFilter = NULL;
  127.  ofn.nMaxCustFilter    = 0;
  128.  ofn.nFilterIndex      = 1;
  129.  ofn.lpstrFile         = szFileName;
  130.  ofn.nMaxFile          = MAXFILENAME;
  131.  ofn.lpstrInitialDir   = NULL;
  132.  ofn.lpstrFileTitle    = szFileTitle;
  133.  ofn.nMaxFileTitle     = MAXFILENAME;
  134.  ofn.lpstrTitle        = NULL;
  135.  ofn.lpstrDefExt       = "TXT";
  136.  ofn.Flags             = 0;
  137.  
  138.  ShowWindow(hMainWnd, nCmdShow);
  139.  UpdateWindow(hMainWnd);
  140.  
  141.  /* window control loop */
  142.  
  143.  while(GetMessage(&msg,NULL,NULL,NULL))
  144.    {
  145.     TranslateMessage(&msg);
  146.     DispatchMessage(&msg);
  147.    }
  148.  return (msg.wParam);
  149. } /* end WinMain */
  150.  
  151. long FAR PASCAL MainWndProc(HWND hWindow,UINT message,
  152.   WPARAM wParam,LPARAM lParam)
  153. {
  154.  UINT idTimer;
  155.  HDC hDC;
  156.  PAINTSTRUCT ps;
  157.  int i;
  158.  int KeyChar;
  159.  int TheChar;
  160.  int ThisPacket;
  161.  int ThisNAKcount;
  162.  long ThisByteCount;
  163.  char Temp[82];
  164.  HMENU hMenu;
  165.  int Count;
  166.  static FARPROC lpProcAbout;
  167.  static int ThePort;
  168.  
  169.  hMainWnd = hWindow;
  170.  switch (message)
  171.     {
  172.      case WM_COMMAND:
  173.          switch(wParam)
  174.            {case MSG_ABOUT:
  175.               DialogBox(hInstance,"AboutBox",hMainWnd,lpProcAbout);
  176.               break;
  177.  
  178.             case MSG_BREAK:
  179.               MessageBeep(0);
  180.               switch(XferState)
  181.                 {case 'A':
  182.                  case 'X':
  183.                  case 'Y':
  184.                    InfoStatus("Aborting");
  185.                    ShowWindow(hInfoWnd,SW_SHOW);
  186.                    SendMessage(hInfoWnd,WM_USER,0,0L);
  187.                    xyAbort();
  188.                    /* window will hide after 3 seconds */
  189.                    HideTime = GetTickCount() + 2000L;
  190.                    break;
  191.                  case 'M':
  192.                    DisableBreakButton();
  193.                    break;
  194.                  default:
  195.                    break;
  196.                 }
  197.               XferState = ' ';
  198.               break;
  199.  
  200.             case MSG_LOAD:
  201.               if(!ExpectNoXfer()) break;
  202.               if(!ExpectOffLine()) break;
  203.               LoadConfig();
  204.               break;
  205.  
  206.             case MSG_SAVE:
  207.               if(!ExpectNoXfer()) break;
  208.               if(!ExpectOffLine()) break;
  209.               SaveConfig();
  210.               SetTitle();
  211.               break;
  212.  
  213.             case MSG_ONLINE:
  214.               if(!ExpectOffLine()) break;
  215.               if(FatalFlag) ErrorMessage("Fatal Error");
  216.               else
  217.                 {/* try to go on-line */
  218.  
  219. /*
  220. ** You must call PostMainHandle() before attemping to go online.
  221. ** This is required only for the Shareware version of PCL4W.
  222. */
  223.                  PostMainHandle(hMainWnd);
  224.  
  225.                  GoOnLine();
  226.                  if(!OnLineFlag) break;
  227.                  ThePort = GetPort();
  228.                 }
  229.               break;
  230.  
  231.             case MSG_INIT_MODEM:
  232.               if(!ExpectOnLine()) break;
  233.               if(FatalFlag) ErrorMessage("Fatal Error");
  234.               else
  235.                 {
  236.                  EnableBreakButton();
  237. #if AT_COMMAND_SET
  238.                  /* initialize modem */
  239.                  InitModem(ThePort,"!!AT E1 S7=60 S11=60 V1 X1 Q0 S0=1!!");
  240.                  /* start SendToModem function */
  241.                  XferState = 'M';
  242. #endif
  243.                 }
  244.               break;
  245.             case MSG_OFFLINE:
  246.               if(!ExpectNoXfer()) break;
  247.               GoOffLine();
  248.               break;
  249.  
  250.             case MSG_EXIT:
  251.               if(!ExpectNoXfer()) break;
  252.               GoOffLine();
  253.               KillTimer(hMainWnd,idTimer);
  254.               TermDone();
  255.               PostQuitMessage(0);
  256.               break;
  257.  
  258.             case MSG_1200:
  259.               SetBaud(Baud1200);
  260.               break;
  261.  
  262.             case MSG_2400:
  263.               SetBaud(Baud2400);
  264.               break;
  265.  
  266.             case MSG_4800:
  267.               SetBaud(Baud4800);
  268.               break;
  269.  
  270.             case MSG_9600:
  271.               SetBaud(Baud9600);
  272.               break;
  273.  
  274.             case MSG_19200:
  275.               SetBaud(Baud19200);
  276.               break;
  277.  
  278.             case MSG_38400:
  279.               SetBaud(Baud38400);
  280.               break;
  281.  
  282.             case MSG_57600:
  283.               SetBaud(Baud57600);
  284.               break;
  285.  
  286.             case MSG_115200:
  287.               SetBaud(Baud115200);
  288.               break;
  289.  
  290.             case MSG_COM1:
  291.               SetPort(COM1);
  292.               break;
  293.  
  294.             case MSG_COM2:
  295.               SetPort(COM2);
  296.               break;
  297.  
  298.             case MSG_COM3:
  299.               SetPort(COM3);
  300.               break;
  301.  
  302.             case MSG_COM4:
  303.               SetPort(COM4);
  304.               break;
  305.  
  306.             case MSG_DEBUG:
  307.               DebugValue = SioDebug(0);
  308.               ShowDebugFlag = TRUE;
  309.               InvalidateRect(hMainWnd,NULL,TRUE);
  310.               break;
  311.  
  312.             case MSG_NONE:
  313.               SetParity(NoParity);
  314.               break;
  315.  
  316.             case MSG_EVEN:
  317.               SetParity(EvenParity);
  318.               break;
  319.  
  320.             case MSG_ODD:
  321.               SetParity(OddParity);
  322.               break;
  323.  
  324.             case MSG_1_SB:
  325.               SetStopBits(OneStopBit);
  326.               break;
  327.  
  328.             case MSG_2_SB:
  329.               SetStopBits(TwoStopBits);
  330.               break;
  331.  
  332.             case MSG_7_DB:
  333.               SetWordLength(WordLength7);
  334.               break;
  335.  
  336.             case MSG_8_DB:
  337.               SetWordLength(WordLength8);
  338.               break;
  339.  
  340.             case MSG_ASCII_TX:
  341.               if(!ExpectNoXfer()) break;
  342.               if(!ExpectOnLine()) break;
  343.               if(GetOpenFileName ((LPOPENFILENAME)&ofn))
  344.                 {
  345.                  /* initialize xyDriver */
  346.                  ascInit(ThePort);
  347.                  ascStartTx(szFileName,5,ESC,TRUE);
  348.                  CommonAS(szFileName);
  349.                  XferState = 'A';
  350.                  SetWindowText(hInfoWnd,"ASCII Send");
  351.                  break;
  352.                 }
  353.               break;
  354.  
  355.             case MSG_ASCII_RX:
  356.               if(!ExpectNoXfer()) break;
  357.               if(!ExpectOnLine()) break;
  358.               if(GetOpenFileName ((LPOPENFILENAME)&ofn))
  359.                 {/* initialize xyDriver */
  360.                  ascInit(ThePort);
  361.                  ascStartRx(szFileName,(2<<(3+RXBUFFERCODE)),ESC,TRUE);
  362.                  CommonAS(szFileName);
  363.                  XferState = 'A';
  364.                  SetWindowText(hInfoWnd,"ASCII Receive");
  365.                  break;
  366.                 }
  367.               break;
  368.  
  369.             case MSG_XMODEM_TX:
  370.               if(!ExpectNoXfer()) break;
  371.               if(!ExpectOnLine()) break;
  372.               if(GetOpenFileName ((LPOPENFILENAME)&ofn))
  373.                 {
  374.                  /* initialize xyDriver */
  375.                  xyInit(ThePort);
  376.                  xyStartTx(szFileName,FALSE,FALSE);
  377.                  CommonXY(szFileName,&LastPacket,&LastNAKcount);
  378.                  XferState = 'X';
  379.                  SetWindowText(hInfoWnd,"XMODEM Send");
  380.                  break;
  381.                 }
  382.               break;
  383.  
  384.             case MSG_XMODEM_RX:
  385.               if(!ExpectNoXfer()) break;
  386.               if(!ExpectOnLine()) break;
  387.               if(GetOpenFileName ((LPOPENFILENAME)&ofn))
  388.                 {/* initialize xyDriver */
  389.                  xyInit(ThePort);
  390.                  xyStartRx(szFileName,NCGchar,FALSE);
  391.                  CommonXY(szFileName,&LastPacket,&LastNAKcount);
  392.                  XferState = 'X';
  393.                  SetWindowText(hInfoWnd,"XMODEM Receive");
  394.                  break;
  395.                 }
  396.               break;
  397.  
  398.             case MSG_YMODEM_TX:
  399.               if(!ExpectNoXfer()) break;
  400.               if(!ExpectOnLine()) break;
  401.               if(GetOpenFileName ((LPOPENFILENAME)&ofn))
  402.                 {/* initialize xyDriver */
  403.                  xyInit(ThePort);
  404.                  xyStartTx(szFileName,TRUE,TRUE);
  405.                  CommonXY(szFileName,&LastPacket,&LastNAKcount);
  406.                  XferState = 'Y';
  407.                  SetWindowText(hInfoWnd,"YMODEM Send");
  408.                  break;
  409.                 }
  410.               break;
  411.  
  412.             case MSG_YMODEM_RX:
  413.               if(!ExpectNoXfer()) break;
  414.               if(!ExpectOnLine()) break;
  415.               /* don't need filename for YMODEM receive */
  416.               xyInit(ThePort);
  417.               xyStartRx("",NCGchar,TRUE);
  418.               CommonXY("",&LastPacket,&LastNAKcount);
  419.               XferState = 'Y';
  420.               SetWindowText(hInfoWnd,"YMODEM Receive");
  421.               break;
  422.  
  423.             default:
  424.               return (DefWindowProc(hMainWnd, message, wParam, lParam));
  425.            }
  426.          break;
  427.  
  428.     case WM_CREATE:
  429.  
  430.        /* create popup Info window */
  431.        GetWindowRect(hMainWnd,&MainRect);
  432.        hInfoWnd = CreateWindow(
  433.           "InfoWClass", "Info",
  434.           WS_POPUP | WS_BORDER | WS_CAPTION | WS_THICKFRAME,
  435.           MainRect.left + (MainRect.right-MainRect.left-POPWIDTH)/2,
  436.           MainRect.top + (MainRect.bottom-MainRect.top-POPHEIGHT)/2,
  437.           POPWIDTH, POPHEIGHT,
  438.           hMainWnd,  NULL,
  439.           hInstance, NULL);
  440.       UpdateWindow(hInfoWnd);
  441.       /* check "OFFLINE" menu item */
  442.       hMenu = GetMenu(hMainWnd);
  443.       CheckMenuItem(hMenu,MSG_OFFLINE,MF_BYCOMMAND | MF_CHECKED);
  444.       /* create AboutDlgProc() thunk */
  445.       lpProcAbout = MakeProcInstance(AboutDlgProc, hInstance);
  446.       /* grey the BREAK button */
  447.       EnableMenuItem(hMenu,MSG_BREAK,MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
  448.       /* init configuration */
  449.       InitConfig();
  450.       LoadConfig();
  451.       /* initialize paint module */
  452.       InitPaint();
  453.       /* start timer */
  454.       idTimer = SetTimer(hMainWnd,1,125,NULL);
  455.       if(idTimer==0)
  456.          {ErrorMessage("No timers remaining !");
  457.           FatalFlag = TRUE;
  458.          }
  459.  
  460. #if 1
  461.  /*** Custom Configuration: DigiBoard PC/8 for COM3 - COM10 ***/
  462.  /* use 0x140 for odd IRQs & 0x141 for even IRQs */
  463.  SioPorts(10,COM3,0x140);
  464.  /* set DigiBoard UART addresses for COM3 to COM10 */
  465.  for(i=0;i<8;i++)
  466.    {/* set DigiBoard port address */
  467.     ErrorCheck(SioUART(COM3+i,0x100+8*i) );
  468.     /* set DigiBoard for IRQ5 */
  469.     ErrorCheck(SioIRQ(COM3+i,IRQ5) );
  470.    }
  471. #endif
  472.       TermInit();
  473.  
  474.       break;
  475.  
  476.     case WM_CHAR:
  477.       if(OnLineFlag&&(XferState==' '))
  478.         {KeyChar = wParam;
  479.          PutChar(ThePort, (char)KeyChar);
  480.         }
  481.       break;
  482.  
  483.     case WM_TIMER:
  484.       /* time to hide the popup window ? */
  485.       if(HideTime!=0L)
  486.         {if(GetTickCount() > HideTime)
  487.           {HideTime = 0L;
  488.            MessageBeep(0);
  489.            ShowWindow(hInfoWnd,SW_HIDE);
  490.            DisableBreakButton();
  491.           }
  492.         }
  493.       /* fatal error ? */
  494.       if(FatalFlag)
  495.         {xyAbort();
  496.          XferState = ' ';
  497.          break;
  498.         }
  499.       /* xfer in progess ? */
  500.       switch(XferState)
  501.         {case 'A':
  502.            if(ascDriver())
  503.              {/* asDriver is idle */
  504.               MessageBeep(0);
  505.               XferState = ' ';
  506.               InfoStatus("Completed");
  507.               SendMessage(hInfoWnd,WM_USER,0,0L);
  508.               HideTime = GetTickCount() + 2000L;
  509.               SetCharWait(0);
  510.              }
  511.            else
  512.              {/* update # bytes */
  513.               ThisByteCount = ascGetCharCount();
  514.               ThisPacket = (int) (ThisByteCount / 100L);
  515.               if(ThisPacket!=LastPacket)
  516.                 {LastPacket = ThisPacket;
  517.                  InfoBytes((int)ThisByteCount);
  518.                  SendMessage(hInfoWnd,WM_USER,0,0L);
  519.                 }
  520.              }
  521.            break;
  522.          case 'X':
  523.          case 'Y':
  524.            if(xyDriver())
  525.              {/* xyDriver is idle */
  526.               MessageBeep(0);
  527.               XferState = ' ';
  528.               InfoStatus("Completed");
  529.               SendMessage(hInfoWnd,WM_USER,0,0L);
  530.               HideTime = GetTickCount() + 3000L;
  531.               SetCharWait(0);
  532.              }
  533.            else
  534.              {/* update packet number */
  535.               ThisPacket = xyGetPacket();
  536.               if(ThisPacket!=LastPacket)
  537.                 {LastPacket = ThisPacket;
  538.                  InfoPacket(ThisPacket);
  539.                  SendMessage(hInfoWnd,WM_USER,0,0L);
  540.                 }
  541.               /* update error count */
  542.               ThisNAKcount = xyGetNAKs();
  543.               if(ThisNAKcount != LastNAKcount)
  544.                 {LastNAKcount = ThisNAKcount;
  545.                  InfoErrors(ThisNAKcount);
  546.                  SendMessage(hInfoWnd,WM_USER,0,0L);
  547.                 }
  548.              }
  549.            break;
  550.          case 'M':  /* SendToModem */
  551.            if(SendToModem())
  552.              {/* initialization string sent */
  553.               XferState = ' ';
  554.               DisableBreakButton();
  555.              }
  556.            break;
  557.          default:
  558.            /* NOT doing xfer */
  559.            if(!OnLineFlag) break;
  560.            /* fetch line of up to 82 chars */
  561.            Count = 0;
  562.            for(i=0;i<82;i++)
  563.              {TheChar = GetChar(ThePort);
  564.               /* character available ? */
  565.               if(TheChar==-1) break;
  566.               Temp[Count++] = TheChar;
  567.               if((char)TheChar==(char)LF) break;
  568.              } /* end while */
  569.            if(Count>0) WriteTheString(Temp,Count);
  570.            break;
  571.        } /* end switch */
  572.       break;
  573.  
  574.     case WM_SETFOCUS:
  575.       /* create client area caret */
  576.       CreateCaret(hMainWnd,NULL,3,10);
  577.       SetCaretPos(GetXposition(),GetYposition());
  578.       ShowCaret(hMainWnd);
  579.       ShowCaret(hMainWnd);
  580.       break;
  581.  
  582.     case WM_KILLFOCUS:
  583.       DestroyCaret();
  584.       break;
  585.  
  586.     case WM_PAINT:
  587.       HideCaret(hMainWnd);
  588.       hDC = BeginPaint(hMainWnd, &ps);
  589.       SetMapMode(hDC,MM_ANISOTROPIC);
  590.       SelectObject(hDC, GetStockObject(OEM_FIXED_FONT) );
  591.       PaintMain(hDC,&ps);
  592.       EndPaint(hMainWnd,&ps);
  593.       SetCaretPos(GetXposition(),GetYposition());
  594.       ShowCaret(hMainWnd);
  595.       break;
  596.  
  597.     case WM_DESTROY:
  598.       GoOffLine();
  599.       if(idTimer) KillTimer(hMainWnd,idTimer);
  600.       PostQuitMessage(0);
  601.       break;
  602.  
  603.     default:
  604.       return (DefWindowProc(hMainWnd, message, wParam, lParam));
  605.    }
  606.  return (NULL);
  607. } /* end MainWndProc */
  608.  
  609. void ErrorCheck(int Code)
  610. {/* trap PCL error codes */
  611.  if(Code<0)
  612.      {SioDone(GetPort());
  613.       FatalFlag = TRUE;
  614.      }
  615. } /* end ErrorCheck */
  616.