home *** CD-ROM | disk | FTP | other *** search
- /*
- /* --- term.c ---
- **
- ** This example code is a Windows terminal emulator. It can transfer
- ** files using ASCII, XMODEM, and YMODEM protocols. This program is
- ** provided as an axample of the use of the PCL4W library.
- **
- ** In order to compile TERM, you will need PCL4W.LIB, PCL4W.DLL, and
- ** PCL4W.H from the PCL4W distribution disk. All source files for TERM
- ** are provided except for the drivers for XMODEM and YMODEM (which are
- ** provided in the registered product).
- **
- ** For a list of files that comprise the TERM application, see
- ** TERM._M_ or TERM._B_ (Microsoft & Borland makefiles).
- **
- */
-
- #include "windows.h"
- #include "commdlg.h"
- #include "term.h"
- #include "info.h"
- #include "pcl4w.h"
- #include "sioerror.h"
- #include "ascii.h"
- #include "term_io.h"
- #include "asdriver.h"
- #include "xydriver.h"
- #include "expect.h"
- #include "config.h"
- #include "paint.h"
- #include "line.h"
- #include "modem_io.h"
- #include "miscell.h"
- #include "about.h"
-
- /* public globals */
- HWND hMainWnd; /* main window handle */
- HWND hInfoWnd; /* popup handle */
- HANDLE hInstance; /* program instance */
- int OnLineFlag = FALSE; /* TRUE: online */
- int FatalFlag = FALSE; /* TRUE: fatal error */
- char XferState = ' '; /* 'X' = XMODEM */
- /* 'Y' = YMODEM */
- /* 'M' = SendToModem */
- /* 'A' = ASCII transfer */
- /* miscellaneous functions */
- void ErrorCheck(int);
-
- #define MAXFILENAME 256
- #define POPWIDTH 200
- #define POPHEIGHT 100
-
- /* private */
- static int ShowDebugFlag = FALSE;
- static int DebugValue = 0;
- static char NCGchar = 'C';
- static int LastPacket;
- static int LastNAKcount = 0;
- static long HideTime = 0L;
- static RECT MainRect;
- static OPENFILENAME ofn;
- static char szFilterSpec[128] = "All Files (*.*)\0*.*\0";
- static char szFileName[MAXFILENAME];
- static char szFileTitle[MAXFILENAME];
-
- /*
- ** PostMainHandle() is required only for the
- ** Shareware version of PCL4W.
- */
-
- #if __cplusplus
- extern "C" void FAR PASCAL PostMainHandle(HWND);
- #else
- extern void FAR PASCAL PostMainHandle(HWND);
- #endif
-
- int PASCAL WinMain(HANDLE hInst,HANDLE hPrevInstance,
- LPSTR lpCmdLine,int nCmdShow)
- {WNDCLASS wc1, wc2;
- MSG msg;
- BOOL Result1;
- BOOL Result2;
- if(!hPrevInstance)
- {/* register main window class */
- wc1.style = CS_HREDRAW | CS_VREDRAW;
- wc1.lpfnWndProc = MainWndProc;
- wc1.cbClsExtra = 0;
- wc1.cbWndExtra = 0;
- wc1.hInstance = hInst;
- wc1.hIcon = LoadIcon(hInst, "TermIcon");
- wc1.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc1.hbrBackground = GetStockObject(WHITE_BRUSH);
- wc1.lpszMenuName = "TermMenu";
- wc1.lpszClassName = "TermWClass";
- Result1 = RegisterClass(&wc1);
-
- /* register popup window class */
- wc2.style = CS_HREDRAW | CS_VREDRAW | CS_PARENTDC;
- wc2.lpfnWndProc = InfoWndProc;
- wc2.cbClsExtra = 0;
- wc2.cbWndExtra = 0;
- wc2.hInstance = hInst;
- wc2.hIcon = NULL;
- wc2.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc2.hbrBackground = GetStockObject(WHITE_BRUSH);
- wc2.lpszMenuName = NULL;
- wc2.lpszClassName = "InfoWClass";
- Result2 = RegisterClass(&wc2);
-
- if((!Result1)||(!Result2)) return FALSE;
- }
-
- /* create main window */
- hInstance = hInst;
- hMainWnd = CreateWindow(
- "TermWClass", "Term", WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL,
- hInstance, NULL);
-
- /* fill in non-variant fields of OPENFILENAME struct. */
- ofn.lStructSize = sizeof(OPENFILENAME);
- ofn.hwndOwner = hMainWnd;
- ofn.lpstrFilter = szFilterSpec;
- ofn.lpstrCustomFilter = NULL;
- ofn.nMaxCustFilter = 0;
- ofn.nFilterIndex = 1;
- ofn.lpstrFile = szFileName;
- ofn.nMaxFile = MAXFILENAME;
- ofn.lpstrInitialDir = NULL;
- ofn.lpstrFileTitle = szFileTitle;
- ofn.nMaxFileTitle = MAXFILENAME;
- ofn.lpstrTitle = NULL;
- ofn.lpstrDefExt = "TXT";
- ofn.Flags = 0;
-
- ShowWindow(hMainWnd, nCmdShow);
- UpdateWindow(hMainWnd);
-
- /* window control loop */
-
- while(GetMessage(&msg,NULL,NULL,NULL))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return (msg.wParam);
- } /* end WinMain */
-
- long FAR PASCAL MainWndProc(HWND hWindow,UINT message,
- WPARAM wParam,LPARAM lParam)
- {
- UINT idTimer;
- HDC hDC;
- PAINTSTRUCT ps;
- int i;
- int KeyChar;
- int TheChar;
- int ThisPacket;
- int ThisNAKcount;
- long ThisByteCount;
- char Temp[82];
- HMENU hMenu;
- int Count;
- static FARPROC lpProcAbout;
- static int ThePort;
-
- hMainWnd = hWindow;
- switch (message)
- {
- case WM_COMMAND:
- switch(wParam)
- {case MSG_ABOUT:
- DialogBox(hInstance,"AboutBox",hMainWnd,lpProcAbout);
- break;
-
- case MSG_BREAK:
- MessageBeep(0);
- switch(XferState)
- {case 'A':
- case 'X':
- case 'Y':
- InfoStatus("Aborting");
- ShowWindow(hInfoWnd,SW_SHOW);
- SendMessage(hInfoWnd,WM_USER,0,0L);
- xyAbort();
- /* window will hide after 3 seconds */
- HideTime = GetTickCount() + 2000L;
- break;
- case 'M':
- DisableBreakButton();
- break;
- default:
- break;
- }
- XferState = ' ';
- break;
-
- case MSG_LOAD:
- if(!ExpectNoXfer()) break;
- if(!ExpectOffLine()) break;
- LoadConfig();
- break;
-
- case MSG_SAVE:
- if(!ExpectNoXfer()) break;
- if(!ExpectOffLine()) break;
- SaveConfig();
- SetTitle();
- break;
-
- case MSG_ONLINE:
- if(!ExpectOffLine()) break;
- if(FatalFlag) ErrorMessage("Fatal Error");
- else
- {/* try to go on-line */
-
- /*
- ** You must call PostMainHandle() before attemping to go online.
- ** This is required only for the Shareware version of PCL4W.
- */
- PostMainHandle(hMainWnd);
-
- GoOnLine();
- if(!OnLineFlag) break;
- ThePort = GetPort();
- }
- break;
-
- case MSG_INIT_MODEM:
- if(!ExpectOnLine()) break;
- if(FatalFlag) ErrorMessage("Fatal Error");
- else
- {
- EnableBreakButton();
- #if AT_COMMAND_SET
- /* initialize modem */
- InitModem(ThePort,"!!AT E1 S7=60 S11=60 V1 X1 Q0 S0=1!!");
- /* start SendToModem function */
- XferState = 'M';
- #endif
- }
- break;
- case MSG_OFFLINE:
- if(!ExpectNoXfer()) break;
- GoOffLine();
- break;
-
- case MSG_EXIT:
- if(!ExpectNoXfer()) break;
- GoOffLine();
- KillTimer(hMainWnd,idTimer);
- TermDone();
- PostQuitMessage(0);
- break;
-
- case MSG_1200:
- SetBaud(Baud1200);
- break;
-
- case MSG_2400:
- SetBaud(Baud2400);
- break;
-
- case MSG_4800:
- SetBaud(Baud4800);
- break;
-
- case MSG_9600:
- SetBaud(Baud9600);
- break;
-
- case MSG_19200:
- SetBaud(Baud19200);
- break;
-
- case MSG_38400:
- SetBaud(Baud38400);
- break;
-
- case MSG_57600:
- SetBaud(Baud57600);
- break;
-
- case MSG_115200:
- SetBaud(Baud115200);
- break;
-
- case MSG_COM1:
- SetPort(COM1);
- break;
-
- case MSG_COM2:
- SetPort(COM2);
- break;
-
- case MSG_COM3:
- SetPort(COM3);
- break;
-
- case MSG_COM4:
- SetPort(COM4);
- break;
-
- case MSG_DEBUG:
- DebugValue = SioDebug(0);
- ShowDebugFlag = TRUE;
- InvalidateRect(hMainWnd,NULL,TRUE);
- break;
-
- case MSG_NONE:
- SetParity(NoParity);
- break;
-
- case MSG_EVEN:
- SetParity(EvenParity);
- break;
-
- case MSG_ODD:
- SetParity(OddParity);
- break;
-
- case MSG_1_SB:
- SetStopBits(OneStopBit);
- break;
-
- case MSG_2_SB:
- SetStopBits(TwoStopBits);
- break;
-
- case MSG_7_DB:
- SetWordLength(WordLength7);
- break;
-
- case MSG_8_DB:
- SetWordLength(WordLength8);
- break;
-
- case MSG_ASCII_TX:
- if(!ExpectNoXfer()) break;
- if(!ExpectOnLine()) break;
- if(GetOpenFileName ((LPOPENFILENAME)&ofn))
- {
- /* initialize xyDriver */
- ascInit(ThePort);
- ascStartTx(szFileName,5,ESC,TRUE);
- CommonAS(szFileName);
- XferState = 'A';
- SetWindowText(hInfoWnd,"ASCII Send");
- break;
- }
- break;
-
- case MSG_ASCII_RX:
- if(!ExpectNoXfer()) break;
- if(!ExpectOnLine()) break;
- if(GetOpenFileName ((LPOPENFILENAME)&ofn))
- {/* initialize xyDriver */
- ascInit(ThePort);
- ascStartRx(szFileName,(2<<(3+RXBUFFERCODE)),ESC,TRUE);
- CommonAS(szFileName);
- XferState = 'A';
- SetWindowText(hInfoWnd,"ASCII Receive");
- break;
- }
- break;
-
- case MSG_XMODEM_TX:
- if(!ExpectNoXfer()) break;
- if(!ExpectOnLine()) break;
- if(GetOpenFileName ((LPOPENFILENAME)&ofn))
- {
- /* initialize xyDriver */
- xyInit(ThePort);
- xyStartTx(szFileName,FALSE,FALSE);
- CommonXY(szFileName,&LastPacket,&LastNAKcount);
- XferState = 'X';
- SetWindowText(hInfoWnd,"XMODEM Send");
- break;
- }
- break;
-
- case MSG_XMODEM_RX:
- if(!ExpectNoXfer()) break;
- if(!ExpectOnLine()) break;
- if(GetOpenFileName ((LPOPENFILENAME)&ofn))
- {/* initialize xyDriver */
- xyInit(ThePort);
- xyStartRx(szFileName,NCGchar,FALSE);
- CommonXY(szFileName,&LastPacket,&LastNAKcount);
- XferState = 'X';
- SetWindowText(hInfoWnd,"XMODEM Receive");
- break;
- }
- break;
-
- case MSG_YMODEM_TX:
- if(!ExpectNoXfer()) break;
- if(!ExpectOnLine()) break;
- if(GetOpenFileName ((LPOPENFILENAME)&ofn))
- {/* initialize xyDriver */
- xyInit(ThePort);
- xyStartTx(szFileName,TRUE,TRUE);
- CommonXY(szFileName,&LastPacket,&LastNAKcount);
- XferState = 'Y';
- SetWindowText(hInfoWnd,"YMODEM Send");
- break;
- }
- break;
-
- case MSG_YMODEM_RX:
- if(!ExpectNoXfer()) break;
- if(!ExpectOnLine()) break;
- /* don't need filename for YMODEM receive */
- xyInit(ThePort);
- xyStartRx("",NCGchar,TRUE);
- CommonXY("",&LastPacket,&LastNAKcount);
- XferState = 'Y';
- SetWindowText(hInfoWnd,"YMODEM Receive");
- break;
-
- default:
- return (DefWindowProc(hMainWnd, message, wParam, lParam));
- }
- break;
-
- case WM_CREATE:
-
- /* create popup Info window */
- GetWindowRect(hMainWnd,&MainRect);
- hInfoWnd = CreateWindow(
- "InfoWClass", "Info",
- WS_POPUP | WS_BORDER | WS_CAPTION | WS_THICKFRAME,
- MainRect.left + (MainRect.right-MainRect.left-POPWIDTH)/2,
- MainRect.top + (MainRect.bottom-MainRect.top-POPHEIGHT)/2,
- POPWIDTH, POPHEIGHT,
- hMainWnd, NULL,
- hInstance, NULL);
- UpdateWindow(hInfoWnd);
- /* check "OFFLINE" menu item */
- hMenu = GetMenu(hMainWnd);
- CheckMenuItem(hMenu,MSG_OFFLINE,MF_BYCOMMAND | MF_CHECKED);
- /* create AboutDlgProc() thunk */
- lpProcAbout = MakeProcInstance(AboutDlgProc, hInstance);
- /* grey the BREAK button */
- EnableMenuItem(hMenu,MSG_BREAK,MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
- /* init configuration */
- InitConfig();
- LoadConfig();
- /* initialize paint module */
- InitPaint();
- /* start timer */
- idTimer = SetTimer(hMainWnd,1,125,NULL);
- if(idTimer==0)
- {ErrorMessage("No timers remaining !");
- FatalFlag = TRUE;
- }
-
- #if 1
- /*** Custom Configuration: DigiBoard PC/8 for COM3 - COM10 ***/
- /* use 0x140 for odd IRQs & 0x141 for even IRQs */
- SioPorts(10,COM3,0x140);
- /* set DigiBoard UART addresses for COM3 to COM10 */
- for(i=0;i<8;i++)
- {/* set DigiBoard port address */
- ErrorCheck(SioUART(COM3+i,0x100+8*i) );
- /* set DigiBoard for IRQ5 */
- ErrorCheck(SioIRQ(COM3+i,IRQ5) );
- }
- #endif
- TermInit();
-
- break;
-
- case WM_CHAR:
- if(OnLineFlag&&(XferState==' '))
- {KeyChar = wParam;
- PutChar(ThePort, (char)KeyChar);
- }
- break;
-
- case WM_TIMER:
- /* time to hide the popup window ? */
- if(HideTime!=0L)
- {if(GetTickCount() > HideTime)
- {HideTime = 0L;
- MessageBeep(0);
- ShowWindow(hInfoWnd,SW_HIDE);
- DisableBreakButton();
- }
- }
- /* fatal error ? */
- if(FatalFlag)
- {xyAbort();
- XferState = ' ';
- break;
- }
- /* xfer in progess ? */
- switch(XferState)
- {case 'A':
- if(ascDriver())
- {/* asDriver is idle */
- MessageBeep(0);
- XferState = ' ';
- InfoStatus("Completed");
- SendMessage(hInfoWnd,WM_USER,0,0L);
- HideTime = GetTickCount() + 2000L;
- SetCharWait(0);
- }
- else
- {/* update # bytes */
- ThisByteCount = ascGetCharCount();
- ThisPacket = (int) (ThisByteCount / 100L);
- if(ThisPacket!=LastPacket)
- {LastPacket = ThisPacket;
- InfoBytes((int)ThisByteCount);
- SendMessage(hInfoWnd,WM_USER,0,0L);
- }
- }
- break;
- case 'X':
- case 'Y':
- if(xyDriver())
- {/* xyDriver is idle */
- MessageBeep(0);
- XferState = ' ';
- InfoStatus("Completed");
- SendMessage(hInfoWnd,WM_USER,0,0L);
- HideTime = GetTickCount() + 3000L;
- SetCharWait(0);
- }
- else
- {/* update packet number */
- ThisPacket = xyGetPacket();
- if(ThisPacket!=LastPacket)
- {LastPacket = ThisPacket;
- InfoPacket(ThisPacket);
- SendMessage(hInfoWnd,WM_USER,0,0L);
- }
- /* update error count */
- ThisNAKcount = xyGetNAKs();
- if(ThisNAKcount != LastNAKcount)
- {LastNAKcount = ThisNAKcount;
- InfoErrors(ThisNAKcount);
- SendMessage(hInfoWnd,WM_USER,0,0L);
- }
- }
- break;
- case 'M': /* SendToModem */
- if(SendToModem())
- {/* initialization string sent */
- XferState = ' ';
- DisableBreakButton();
- }
- break;
- default:
- /* NOT doing xfer */
- if(!OnLineFlag) break;
- /* fetch line of up to 82 chars */
- Count = 0;
- for(i=0;i<82;i++)
- {TheChar = GetChar(ThePort);
- /* character available ? */
- if(TheChar==-1) break;
- Temp[Count++] = TheChar;
- if((char)TheChar==(char)LF) break;
- } /* end while */
- if(Count>0) WriteTheString(Temp,Count);
- break;
- } /* end switch */
- break;
-
- case WM_SETFOCUS:
- /* create client area caret */
- CreateCaret(hMainWnd,NULL,3,10);
- SetCaretPos(GetXposition(),GetYposition());
- ShowCaret(hMainWnd);
- ShowCaret(hMainWnd);
- break;
-
- case WM_KILLFOCUS:
- DestroyCaret();
- break;
-
- case WM_PAINT:
- HideCaret(hMainWnd);
- hDC = BeginPaint(hMainWnd, &ps);
- SetMapMode(hDC,MM_ANISOTROPIC);
- SelectObject(hDC, GetStockObject(OEM_FIXED_FONT) );
- PaintMain(hDC,&ps);
- EndPaint(hMainWnd,&ps);
- SetCaretPos(GetXposition(),GetYposition());
- ShowCaret(hMainWnd);
- break;
-
- case WM_DESTROY:
- GoOffLine();
- if(idTimer) KillTimer(hMainWnd,idTimer);
- PostQuitMessage(0);
- break;
-
- default:
- return (DefWindowProc(hMainWnd, message, wParam, lParam));
- }
- return (NULL);
- } /* end MainWndProc */
-
- void ErrorCheck(int Code)
- {/* trap PCL error codes */
- if(Code<0)
- {SioDone(GetPort());
- FatalFlag = TRUE;
- }
- } /* end ErrorCheck */