home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / os2pm / shell.mod < prev    next >
Text File  |  2020-01-01  |  29KB  |  871 lines

  1. IMPLEMENTATION MODULE Shell;
  2.  
  3.    FROM SYSTEM IMPORT
  4.       ADDRESS, ADR;
  5.  
  6.    IMPORT ASCII;
  7.  
  8.    FROM OS2DEF IMPORT
  9.       HWND, HDC, HPS, RECTL, USHORT, NULL, ULONG;
  10.  
  11.    FROM Term IMPORT
  12.       WM_TERM, WM_TERMQUIT,
  13.       Dir, TermThrProc, InitTerm, PutKbdChar, PutPortChar;
  14.  
  15.    FROM PAD IMPORT
  16.       WM_PAD, PAD_Quit, PAD_Error, DoPADMsg, Aborted, sFname, Send, Receive;
  17.  
  18.    FROM DataLink IMPORT
  19.       WM_DL, DoDLMsg;
  20.  
  21.    FROM Screen IMPORT
  22.       hvps, ColorSet, White, Green, Amber, Color1, Color2, ClrScr, WriteLn;
  23.  
  24.    FROM DosCalls IMPORT
  25.       DosCreateThread, DosSuspendThread, DosResumeThread, DosSleep;
  26.  
  27.    FROM PMAVIO IMPORT
  28.       VioCreatePS, VioAssociate, VioDestroyPS, VioShowPS, WinDefAVioWindowProc,
  29.       FORMAT_CGA, HVPS;
  30.  
  31.    FROM PMWIN IMPORT
  32.       MPARAM, MRESULT, SWP, PSWP,
  33.       WS_VISIBLE, FCF_TITLEBAR, FCF_SIZEBORDER, FCF_SHELLPOSITION,
  34.       WM_SYSCOMMAND, WM_MINMAXFRAME, SWP_MINIMIZE, HWND_DESKTOP,
  35.       WM_PAINT, WM_QUIT, WM_COMMAND, WM_INITDLG, WM_CONTROL, WM_HELP,
  36.       WM_INITMENU, WM_SIZE, WM_DESTROY, WM_CREATE, WM_CHAR,
  37.       BM_SETCHECK, MBID_OK, MB_OK, MB_OKCANCEL,
  38.       KC_CHAR, KC_CTRL, KC_VIRTUALKEY, KC_KEYUP,
  39.       SWP_SIZE, SWP_MOVE, SWP_MAXIMIZE, SWP_RESTORE,
  40.       MB_ICONQUESTION, MB_ICONASTERISK, MB_ICONEXCLAMATION,
  41.       FID_MENU, MM_SETITEMATTR, MM_QUERYITEMATTR, MIA_DISABLED, MIA_CHECKED,
  42.       WinCreateStdWindow, WinDestroyWindow,
  43.       WinOpenWindowDC, WinSendMsg, WinQueryDlgItemText, WinInvalidateRect,
  44.       WinDefWindowProc, WinBeginPaint, WinEndPaint, WinQueryWindowRect,
  45.       WinSetWindowText, WinSetFocus, WinDlgBox, WinDefDlgProc, WinDismissDlg,
  46.       WinMessageBox, WinPostMsg, WinWindowFromID, WinSendDlgItemMsg,
  47.       WinSetWindowPos, WinSetActiveWindow;
  48.  
  49.    FROM PMGPI IMPORT
  50.       GpiErase;
  51.  
  52.    FROM KH IMPORT
  53.       IDM_KERMIT, IDM_FILE, IDM_OPTIONS, IDM_SENDFN, ID_SENDFN,
  54.       IDM_DIR, IDM_CONNECT, IDM_SEND, IDM_REC, IDM_DIRPATH, ID_DIRPATH,
  55.       IDM_DIREND, IDM_QUIT, IDM_ABOUT, IDM_HELPMENU, IDM_TERMHELP,
  56.       IDM_COMPORT, IDM_BAUDRATE, IDM_DATABITS, IDM_STOPBITS, IDM_PARITY,
  57.       COM_OFF, ID_COM1, ID_COM2, PARITY_OFF, ID_EVEN, ID_ODD, ID_NONE,
  58.       DATA_OFF, ID_DATA7, ID_DATA8, STOP_OFF, ID_STOP1, ID_STOP2,
  59.       BAUD_OFF, ID_B110, ID_B150, ID_B300, ID_B600, ID_B1200, ID_B2400,
  60.       ID_B4800, ID_B9600, ID_B19K2,
  61.       IDM_COLORS, IDM_WHITE, IDM_GREEN, IDM_AMBER, IDM_C1, IDM_C2;
  62.  
  63.    FROM CommPort IMPORT
  64.       CommStatus, BaudRate, DataBits, StopBits, Parity, InitPort,
  65.       StartReceiving, StopReceiving;
  66.  
  67.    FROM Strings IMPORT
  68.       Assign, Append, AppendChar;
  69.  
  70.  
  71.    CONST
  72.       WM_SETMAX = 7000H;
  73.       WM_SETFULL = 7001H;
  74.       WM_SETRESTORE = 7002H;
  75.       NONE = 0;   (* no port yet initialized *)
  76.       STKSIZE = 4096;
  77.       BUFSIZE = 4096;   (* Port receive buffers: room for two full screens *)
  78.       PortError = "Port Is Already In Use -- EXIT? (Cancel Trys Another Port)";
  79.       ESC = 33C;
  80.  
  81.  
  82.    VAR
  83.       FrameFlags : ULONG;
  84.       TermStack : ARRAY [1..STKSIZE] OF CHAR;
  85.       Stack : ARRAY [1..STKSIZE] OF CHAR;
  86.       TermThr : CARDINAL;
  87.       Thr : CARDINAL;
  88.       hdc : HDC;
  89.       frame_hvps, child_hvps : HVPS;
  90.       TermMode : BOOLEAN;
  91.       Path : ARRAY [0..60] OF CHAR;
  92.       Banner : ARRAY [0..40] OF CHAR;
  93.       PrevComPort : CARDINAL;
  94.       Settings : ARRAY [0..1] OF RECORD
  95.                                     baudrate : CARDINAL;
  96.                                     databits : CARDINAL;
  97.                                     parity : CARDINAL;
  98.                                     stopbits : CARDINAL;
  99.                                  END;
  100.       MP1, MP2 : MPARAM;
  101.  
  102.  
  103.    PROCEDURE SetFull;
  104.    (* Changes window to full size *)
  105.       BEGIN
  106.          WinSetWindowPos (FrameWindow, 0,
  107.             Pos.x + 3, Pos.y + 3, Pos.cx - 6, Pos.cy - 6,
  108.             SWP_MOVE + SWP_SIZE);
  109.       END SetFull;
  110.  
  111.  
  112.    PROCEDURE SetRestore;
  113.    (* Changes window to full size FROM maximized *)
  114.       BEGIN
  115.          WinSetWindowPos (FrameWindow, 0,
  116.             Pos.x + 3, Pos.y + 3, Pos.cx - 6, Pos.cy - 6,
  117.             SWP_MOVE + SWP_SIZE + SWP_RESTORE);
  118.       END SetRestore;
  119.  
  120.  
  121.    PROCEDURE SetMax;
  122.    (* Changes window to maximized *)
  123.       BEGIN
  124.          WinSetWindowPos (FrameWindow, 0,
  125.             Pos.x + 3, Pos.y + 3, Pos.cx - 6, Pos.cy - 6,
  126.             SWP_MOVE + SWP_SIZE + SWP_MAXIMIZE);
  127.       END SetMax;
  128.  
  129.  
  130.    PROCEDURE SetBanner;
  131.    (* Displays Abbreviated Program Title + Port Settings in Title Bar *)
  132.  
  133.       CONST
  134.          PortName : ARRAY [0..1] OF ARRAY [0..5] OF CHAR =
  135.             [["COM1:", 0C], ["COM2:", 0C]];
  136.          BaudName : ARRAY [0..8] OF ARRAY [0..5] OF CHAR =
  137.             [["110", 0C], ["150", 0C], ["300", 0C],
  138.              ["600", 0C], ["1200", 0C], ["2400", 0C],
  139.              ["4800", 0C], ["9600", 0C], ["19200", 0C]];
  140.          ParityName : ARRAY [0..2] OF CHAR = ['E', 'O', 'N'];
  141.  
  142.       BEGIN
  143.          WITH Settings[comport - COM_OFF] DO
  144.             Assign (Class, Banner);
  145.             Append (Banner, " -- ");
  146.             Append (Banner, PortName[comport - COM_OFF]);
  147.             Append (Banner, BaudName[baudrate - BAUD_OFF]);
  148.             AppendChar (Banner, ',');
  149.             AppendChar (Banner, ParityName[parity - PARITY_OFF]);
  150.             AppendChar (Banner, ',');
  151.             AppendChar (Banner, CHR ((databits - DATA_OFF) + 30H));
  152.             AppendChar (Banner, ',');
  153.             AppendChar (Banner, CHR ((stopbits - STOP_OFF) + 30H));
  154.             WinSetWindowText (FrameWindow, ADR (Banner));
  155.          END;
  156.       END SetBanner;
  157.  
  158.  
  159.    PROCEDURE SetPort;
  160.    (* Sets The Communications Parameters Chosen By User *)
  161.  
  162.       VAR
  163.          status : CommStatus;
  164.          rc : USHORT;
  165.  
  166.       BEGIN
  167.          IF PrevComPort # NONE THEN
  168.             StopReceiving (PrevComPort - COM_OFF);
  169.          END;
  170.  
  171.          WITH Settings[comport - COM_OFF] DO
  172.             status := InitPort (
  173.                comport - COM_OFF,
  174.                BaudRate (baudrate - BAUD_OFF),
  175.                DataBits (databits - DATA_OFF),
  176.                StopBits (stopbits - STOP_OFF),
  177.                Parity (parity - PARITY_OFF),
  178.             );
  179.          END;
  180.  
  181.          IF status = Success THEN
  182.             StartReceiving (comport - COM_OFF, BUFSIZE);
  183.             PrevComPort := comport;
  184.          ELSE
  185.             rc := WinMessageBox (HWND_DESKTOP, FrameWindow, ADR (PortError),
  186.                                  0, 0, MB_OKCANCEL + MB_ICONEXCLAMATION);
  187.             IF rc = MBID_OK THEN
  188.                WinPostMsg (FrameWindow, WM_QUIT, MPARAM (0), MPARAM (0));
  189.             ELSE   (* try the other port *)
  190.                IF comport = ID_COM1 THEN
  191.                   comport := ID_COM2;
  192.                ELSE
  193.                   comport := ID_COM1;
  194.                END;
  195.                SetPort;   (* recursive call for retry *)
  196.             END;
  197.          END;
  198.          SetBanner;
  199.       END SetPort;
  200.  
  201.  
  202.    PROCEDURE MakeChild (msg : ARRAY OF CHAR);
  203.    (* Creates a child window for use by send or receive threads *)
  204.  
  205.       VAR
  206.          c_hdc : HDC;
  207.  
  208.       BEGIN
  209.          WinPostMsg (FrameWindow, WM_SETFULL, MPARAM (0), MPARAM (0));
  210.  
  211.          Disable (IDM_CONNECT);
  212.          Disable (IDM_SEND);
  213.          Disable (IDM_REC);
  214.          Disable (IDM_DIR);
  215.          Disable (IDM_OPTIONS);
  216.          Disable (IDM_COLORS);
  217.  
  218.          (* Create a client window *)
  219.          FrameFlags := FCF_TITLEBAR + FCF_SIZEBORDER;
  220.  
  221.          ChildFrameWindow := WinCreateStdWindow (
  222.                 ClientWindow,        (* handle of the parent window *)
  223.                 WS_VISIBLE,          (* the window style *)
  224.                 FrameFlags,          (* the window flags *)
  225.                 ADR(Child),          (* the window class *)
  226.                 NULL,                (* the title bar text *)
  227.                 WS_VISIBLE,          (* client window style *)
  228.                 NULL,                (* handle of resource module *)
  229.                 IDM_KERMIT,          (* resource id *)
  230.                 ChildClientWindow    (* returned client window handle *)
  231.          );
  232.  
  233.          WinSetWindowPos (ChildFrameWindow, 0,
  234.             Pos.cx DIV 4, Pos.cy DIV 4,
  235.             Pos.cx DIV 2, Pos.cy DIV 2 - 3,
  236.             SWP_MOVE + SWP_SIZE);
  237.  
  238.          WinSetWindowText (ChildFrameWindow, ADR (msg));
  239.  
  240.          WinSetActiveWindow (HWND_DESKTOP, ChildFrameWindow);
  241.  
  242.          c_hdc := WinOpenWindowDC (ChildClientWindow);
  243.          hvps := child_hvps;
  244.          VioAssociate (c_hdc, hvps);
  245.          ClrScr;     (* clear the hvio window *)
  246.       END MakeChild;
  247.  
  248.  
  249.    PROCEDURE Disable (item : USHORT);
  250.    (* Disables and "GREYS" a menu item *)
  251.  
  252.       VAR
  253.          h : HWND;
  254.  
  255.       BEGIN
  256.          h := WinWindowFromID (FrameWindow, FID_MENU);
  257.          MP1.W1 := item;   MP1.W2 := 1;
  258.          MP2.W1 := MIA_DISABLED;   MP2.W2 := MIA_DISABLED;
  259.          WinSendMsg (h, MM_SETITEMATTR, MP1, MP2);
  260.       END Disable;
  261.  
  262.  
  263.    PROCEDURE Enable (item : USHORT);
  264.    (* Enables a menu item *)
  265.  
  266.       VAR
  267.          h : HWND;
  268.          atr : USHORT;
  269.  
  270.       BEGIN
  271.          h := WinWindowFromID (FrameWindow, FID_MENU);
  272.          MP1.W1 := item;   MP1.W2 := 1;
  273.          MP2.W1 := MIA_DISABLED;   MP2.W2 := MIA_DISABLED;
  274.          atr := USHORT (WinSendMsg (h, MM_QUERYITEMATTR, MP1, MP2));
  275.          atr := USHORT (BITSET (atr) * (BITSET (MIA_DISABLED) / BITSET (-1)));
  276.          MP1.W1 := item;   MP1.W2 := 1;
  277.          MP2.W1 := MIA_DISABLED;   MP2.W2 := atr;
  278.          WinSendMsg (h, MM_SETITEMATTR, MP1, MP2);
  279.       END Enable;
  280.  
  281.  
  282.    PROCEDURE Check (item : USHORT);
  283.    (* Checks a menu item -- indicates that it is selected *)
  284.  
  285.       VAR
  286.          h : HWND;
  287.  
  288.       BEGIN
  289.          h := WinWindowFromID (FrameWindow, FID_MENU);
  290.          MP1.W1 := item;   MP1.W2 := 1;
  291.          MP2.W1 := MIA_CHECKED;   MP2.W2 := MIA_CHECKED;
  292.          WinSendMsg (h, MM_SETITEMATTR, MP1, MP2);
  293.       END Check;
  294.  
  295.  
  296.    PROCEDURE UnCheck (item : USHORT);
  297.    (* Remove check from a menu item *)
  298.  
  299.       VAR
  300.          h : HWND;
  301.          atr : USHORT;
  302.  
  303.       BEGIN
  304.          h := WinWindowFromID (FrameWindow, FID_MENU);
  305.          MP1.W1 := item;   MP1.W2 := 1;
  306.          MP2.W1 := MIA_CHECKED;   MP2.W2 := MIA_CHECKED;
  307.          atr := USHORT (WinSendMsg (h, MM_QUERYITEMATTR, MP1, MP2));
  308.          atr := USHORT (BITSET (atr) * (BITSET (MIA_CHECKED) / BITSET (-1)));
  309.          MP1.W1 := item;   MP1.W2 := 1;
  310.          MP2.W1 := MIA_CHECKED;   MP2.W2 := atr;
  311.          WinSendMsg (h, MM_SETITEMATTR, MP1, MP2);
  312.       END UnCheck;
  313.  
  314.  
  315.    PROCEDURE DoMenu (hwnd : HWND; item [VALUE] : MPARAM);
  316.    (* Processes Most Menu Interactions *)
  317.  
  318.       VAR
  319.          rcl : RECTL;
  320.          rc : USHORT;
  321.  
  322.       BEGIN
  323.          CASE CARDINAL (item.W1) OF
  324.             IDM_DIR:
  325.                SetFull;
  326.                WinQueryWindowRect (hwnd, rcl);
  327.                WinDlgBox (HWND_DESKTOP, hwnd, PathDlgProc, 0, IDM_DIRPATH, 0);
  328.                hvps := frame_hvps;
  329.                VioAssociate (hdc, hvps);
  330.                Dir (Path);
  331.                WinDlgBox (HWND_DESKTOP, hwnd, DirEndDlgProc, 0, IDM_DIREND, 0);
  332.                VioAssociate (0, hvps);
  333.                WinInvalidateRect (hwnd, rcl, 0);
  334.          |  IDM_CONNECT:
  335.                TermMode := TRUE;
  336.                Disable (IDM_CONNECT);
  337.                Disable (IDM_SEND);
  338.                Disable (IDM_REC);
  339.                Disable (IDM_DIR);
  340.                Disable (IDM_OPTIONS);
  341.                Disable (IDM_COLORS);
  342.                (* MAXIMIZE Window -- Required for Terminal Emulation *)
  343.                SetMax;
  344.                hvps := frame_hvps;
  345.                VioAssociate (hdc, hvps);
  346.                DosResumeThread (TermThr);
  347.                InitTerm;
  348.          |  IDM_SEND:
  349.                WinDlgBox (HWND_DESKTOP, hwnd, SendFNDlgProc, 0, IDM_SENDFN, 0);
  350.                MakeChild ("Send a File");
  351.                DosCreateThread (Send, Thr, ADR (Stack[STKSIZE]));
  352.          |  IDM_REC:
  353.                MakeChild ("Receive a File");
  354.                DosCreateThread (Receive, Thr, ADR (Stack[STKSIZE]));
  355.          |  IDM_QUIT:
  356.                rc := WinMessageBox (HWND_DESKTOP, ClientWindow,
  357.                         ADR ("Do You Really Want To EXIT PCKermit?"),
  358.                         ADR ("End Session"), 0, MB_OKCANCEL + MB_ICONQUESTION);
  359.                IF rc = MBID_OK THEN
  360.                   StopReceiving (comport - COM_OFF);
  361.                   WinPostMsg (hwnd, WM_QUIT, MPARAM (0), MPARAM (0));
  362.                END;
  363.          |  IDM_COMPORT:
  364.                WinDlgBox (HWND_DESKTOP, hwnd, ComDlgProc, 0, IDM_COMPORT, 0);
  365.                SetPort;
  366.          |  IDM_BAUDRATE:
  367.                WinDlgBox (HWND_DESKTOP, hwnd, BaudDlgProc, 0, IDM_BAUDRATE, 0);
  368.                SetPort;
  369.          |  IDM_DATABITS:
  370.                WinDlgBox (HWND_DESKTOP, hwnd, DataDlgProc, 0, IDM_DATABITS, 0);
  371.                SetPort;
  372.          |  IDM_STOPBITS:
  373.                WinDlgBox (HWND_DESKTOP, hwnd, StopDlgProc, 0, IDM_STOPBITS, 0);
  374.                SetPort;
  375.          |  IDM_PARITY:
  376.                WinDlgBox (HWND_DESKTOP, hwnd, ParityDlgProc, 0, IDM_PARITY, 0);
  377.                SetPort;
  378.          |  IDM_WHITE:
  379.                UnCheck (ColorSet);
  380.                ColorSet := IDM_WHITE;
  381.                Check (ColorSet);
  382.                White;
  383.          |  IDM_GREEN:
  384.                UnCheck (ColorSet);
  385.                ColorSet := IDM_GREEN;
  386.                Check (ColorSet);
  387.                Green;
  388.          |  IDM_AMBER:
  389.                UnCheck (ColorSet);
  390.                ColorSet := IDM_AMBER;
  391.                Check (ColorSet);
  392.                Amber;
  393.          |  IDM_C1:
  394.                UnCheck (ColorSet);
  395.                ColorSet := IDM_C1;
  396.                Check (ColorSet);
  397.                Color1;
  398.          |  IDM_C2:
  399.                UnCheck (ColorSet);
  400.                ColorSet := IDM_C2;
  401.                Check (ColorSet);
  402.                Color2;
  403.          |  IDM_ABOUT:
  404.                WinDlgBox (HWND_DESKTOP, hwnd, AboutDlgProc, 0, IDM_ABOUT, 0);
  405.          ELSE
  406.             (* Don't do anything... *)
  407.          END;
  408.       END DoMenu;
  409.  
  410.  
  411.    PROCEDURE ComDlgProc ['ComDlgProc'] (
  412.    (* Process Dialog Box for choosing COM1/COM2 *)
  413.          hwnd  : HWND;
  414.          msg   : USHORT;
  415.          mp1   [VALUE] : MPARAM;
  416.          mp2   [VALUE] : MPARAM) : MRESULT [LONG, WINDOWS];
  417.       BEGIN
  418.          CASE msg OF
  419.             WM_INITDLG:
  420.                WinSendDlgItemMsg (hwnd, comport, BM_SETCHECK,
  421.                MPARAM (1), MPARAM (0));
  422.                WinSetFocus (HWND_DESKTOP, WinWindowFromID (hwnd, comport));
  423.                RETURN 1;
  424.          |  WM_CONTROL:
  425.                comport := mp1.W1;
  426.                RETURN 0;
  427.          |  WM_COMMAND:
  428.                WinDismissDlg (hwnd, 1);
  429.                RETURN 0;
  430.          ELSE
  431.             RETURN WinDefDlgProc (hwnd, msg, mp1, mp2);
  432.          END;
  433.       END ComDlgProc;
  434.  
  435.  
  436.    PROCEDURE BaudDlgProc ['BaudDlgProc'] (
  437.    (* Process Dialog Box for choosing Baud Rate *)
  438.          hwnd  : HWND;
  439.          msg   : USHORT;
  440.          mp1   [VALUE] : MPARAM;
  441.          mp2   [VALUE] : MPARAM) : MRESULT [LONG, WINDOWS];
  442.       BEGIN
  443.          WITH Settings[comport - COM_OFF] DO
  444.             CASE msg OF
  445.                WM_INITDLG:
  446.                   WinSendDlgItemMsg (hwnd, baudrate, BM_SETCHECK,
  447.                                        MPARAM (1), MPARAM (0));
  448.                   WinSetFocus (HWND_DESKTOP, WinWindowFromID (hwnd, baudrate));
  449.                   RETURN 1;
  450.             |  WM_CONTROL:
  451.                   baudrate := mp1.W1;
  452.                   RETURN 0;
  453.             |  WM_COMMAND:
  454.                   WinDismissDlg (hwnd, 1);
  455.                   RETURN 0;
  456.             ELSE
  457.                RETURN WinDefDlgProc (hwnd, msg, mp1, mp2);
  458.             END;
  459.          END;
  460.       END BaudDlgProc;
  461.  
  462.  
  463.    PROCEDURE DataDlgProc ['DataDlgProc'] (
  464.    (* Process Dialog Box for choosing 7 or 8 data bits *)
  465.          hwnd  : HWND;
  466.          msg   : USHORT;
  467.          mp1   [VALUE] : MPARAM;
  468.          mp2   [VALUE] : MPARAM) : MRESULT [LONG, WINDOWS];
  469.       BEGIN
  470.          WITH Settings[comport - COM_OFF] DO
  471.             CASE msg OF
  472.                WM_INITDLG:
  473.                   WinSendDlgItemMsg (hwnd, databits, BM_SETCHECK,
  474.                                        MPARAM (1), MPARAM (0));
  475.                   WinSetFocus (HWND_DESKTOP, WinWindowFromID (hwnd, databits));
  476.                   RETURN 1;
  477.             |  WM_CONTROL:
  478.                   databits := mp1.W1;
  479.                   RETURN 0;
  480.             |  WM_COMMAND:
  481.                   WinDismissDlg (hwnd, 1);
  482.                   RETURN 0;
  483.             ELSE
  484.                RETURN WinDefDlgProc (hwnd, msg, mp1, mp2);
  485.             END;
  486.          END;
  487.       END DataDlgProc;
  488.  
  489.  
  490.    PROCEDURE StopDlgProc ['StopDlgProc'] (
  491.    (* Process Dialog Box for choosing 1 or 2 stop bits *)
  492.          hwnd  : HWND;
  493.          msg   : USHORT;
  494.          mp1   [VALUE] : MPARAM;
  495.          mp2   [VALUE] : MPARAM) : MRESULT [LONG, WINDOWS];
  496.       BEGIN
  497.          WITH Settings[comport - COM_OFF] DO
  498.             CASE msg OF
  499.                WM_INITDLG:
  500.                   WinSendDlgItemMsg (hwnd, stopbits, BM_SETCHECK,
  501.                                  MPARAM (1), MPARAM (0));
  502.                   WinSetFocus (HWND_DESKTOP, WinWindowFromID (hwnd, stopbits));
  503.                   RETURN 1;
  504.             |  WM_CONTROL:
  505.                   stopbits := mp1.W1;
  506.                   RETURN 0;
  507.             |  WM_COMMAND:
  508.                   WinDismissDlg (hwnd, 1);
  509.                   RETURN 0;
  510.             ELSE
  511.                RETURN WinDefDlgProc (hwnd, msg, mp1, mp2);
  512.             END;
  513.          END;
  514.       END StopDlgProc;
  515.  
  516.  
  517.    PROCEDURE ParityDlgProc ['ParityDlgProc'] (
  518.    (* Process Dialog Box for choosing odd, even, or no parity *)
  519.          hwnd  : HWND;
  520.          msg   : USHORT;
  521.          mp1   [VALUE] : MPARAM;
  522.          mp2   [VALUE] : MPARAM) : MRESULT [LONG, WINDOWS];
  523.       BEGIN
  524.          WITH Settings[comport - COM_OFF] DO
  525.             CASE msg OF
  526.                WM_INITDLG:
  527.                   WinSendDlgItemMsg (hwnd, parity, BM_SETCHECK,
  528.                                        MPARAM (1), MPARAM (0));
  529.                   WinSetFocus (HWND_DESKTOP, WinWindowFromID (hwnd, parity));
  530.                   RETURN 1;
  531.             |  WM_CONTROL:
  532.                   parity := mp1.W1;
  533.                   RETURN 0;
  534.             |  WM_COMMAND:
  535.                   WinDismissDlg (hwnd, 1);
  536.                   RETURN 0;
  537.             ELSE
  538.                RETURN WinDefDlgProc (hwnd, msg, mp1, mp2);
  539.             END;
  540.          END;
  541.       END ParityDlgProc;
  542.  
  543.  
  544.    PROCEDURE AboutDlgProc ['AboutDlgProc'] (
  545.    (* Process "About" Dialog Box *)
  546.          hwnd  : HWND;
  547.          msg   : USHORT;
  548.          mp1   [VALUE] : MPARAM;
  549.          mp2   [VALUE] : MPARAM) : MRESULT [LONG, WINDOWS];
  550.       BEGIN
  551.          IF msg = WM_COMMAND THEN
  552.             WinDismissDlg (hwnd, 1);
  553.             RETURN 0;
  554.          ELSE
  555.             RETURN WinDefDlgProc (hwnd, msg, mp1, mp2);
  556.          END;
  557.       END AboutDlgProc;
  558.  
  559.  
  560.    PROCEDURE SendFNDlgProc ['SendFNDlgProc'] (
  561.    (* Process Dialog Box that obtains send filename from user *)
  562.          hwnd  : HWND;
  563.          msg   : USHORT;
  564.          mp1   [VALUE] : MPARAM;
  565.          mp2   [VALUE] : MPARAM) : MRESULT [LONG, WINDOWS];
  566.       BEGIN
  567.          CASE msg OF
  568.             WM_INITDLG:
  569.                WinSetFocus (HWND_DESKTOP, WinWindowFromID (hwnd, ID_SENDFN));
  570.                RETURN 1;
  571.          |  WM_COMMAND:
  572.                WinQueryDlgItemText (hwnd, ID_SENDFN, 20, ADR (sFname));
  573.                WinDismissDlg (hwnd, 1);
  574.                RETURN 0;
  575.          ELSE
  576.             RETURN WinDefDlgProc (hwnd, msg, mp1, mp2);
  577.          END;
  578.       END SendFNDlgProc;
  579.  
  580.  
  581.    PROCEDURE PathDlgProc ['PathDlgProc'] (
  582.    (* Process Dialog Box that obtains directory path from user *)
  583.          hwnd  : HWND;
  584.          msg   : USHORT;
  585.          mp1   [VALUE] : MPARAM;
  586.          mp2   [VALUE] : MPARAM) : MRESULT [LONG, WINDOWS];
  587.       BEGIN
  588.          CASE msg OF
  589.             WM_INITDLG:
  590.                WinSetFocus (HWND_DESKTOP, WinWindowFromID (hwnd, ID_DIRPATH));
  591.                RETURN 1;
  592.          |  WM_COMMAND:
  593.                WinQueryDlgItemText (hwnd, ID_DIRPATH, 60, ADR (Path));
  594.                WinDismissDlg (hwnd, 1);
  595.                RETURN 0;
  596.          ELSE
  597.             RETURN WinDefDlgProc (hwnd, msg, mp1, mp2);
  598.          END;
  599.       END PathDlgProc;
  600.  
  601.  
  602.    PROCEDURE DirEndDlgProc ['DirEndDlgProc'] (
  603.    (* Process Dialog Box to allow user to cancel directory *)
  604.          hwnd  : HWND;
  605.          msg   : USHORT;
  606.          mp1   [VALUE] : MPARAM;
  607.          mp2   [VALUE] : MPARAM) : MRESULT [LONG, WINDOWS];
  608.       BEGIN
  609.          IF msg = WM_COMMAND THEN
  610.             WinDismissDlg (hwnd, 1);
  611.             RETURN 0;
  612.          ELSE
  613.             RETURN WinDefDlgProc (hwnd, msg, mp1, mp2);
  614.          END;
  615.       END DirEndDlgProc;
  616.  
  617.  
  618.    PROCEDURE HelpDlgProc ['HelpDlgProc'] (
  619.    (* Process Dialog Boxes for the HELP *)
  620.          hwnd  : HWND;
  621.          msg   : USHORT;
  622.          mp1   [VALUE] : MPARAM;
  623.          mp2   [VALUE] : MPARAM) : MRESULT [LONG, WINDOWS];
  624.       BEGIN
  625.          IF msg = WM_COMMAND THEN
  626.             WinDismissDlg (hwnd, 1);
  627.             RETURN 0;
  628.          ELSE
  629.             RETURN WinDefDlgProc (hwnd, msg, mp1, mp2);
  630.          END;
  631.       END HelpDlgProc;
  632.  
  633.  
  634.    PROCEDURE KeyTranslate (mp1, mp2 [VALUE] : MPARAM; VAR c1, c2 : CHAR) : BOOLEAN;
  635.    (* Translates WM_CHAR message into ascii keystroke *)
  636.  
  637.       VAR
  638.             code : CARDINAL;
  639.             fs : BITSET;
  640.             VK, KU, CH, CT : BOOLEAN;
  641.  
  642.       BEGIN
  643.          fs := BITSET (mp1.W1);     (* flags *)
  644.          VK := (fs * BITSET (KC_VIRTUALKEY)) # {};
  645.          KU := (fs * BITSET (KC_KEYUP)) # {};
  646.          CH := (fs * BITSET (KC_CHAR)) # {};
  647.          CT := (fs * BITSET (KC_CTRL)) # {};
  648.          IF (NOT KU) THEN
  649.             code := mp2.W1;    (* character code *)
  650.             c1 := CHR (code);
  651.             c2 := CHR (code DIV 256);
  652.             IF ORD (c1) = 0E0H THEN      (* function *)
  653.                c1 := 0C;
  654.             END;
  655.             IF CT AND (NOT CH) AND (NOT VK) AND (code # 0) THEN
  656.                c1 := CHR (CARDINAL ((BITSET (ORD (c1)) * BITSET (1FH))));
  657.             END;
  658.             RETURN TRUE;
  659.          ELSE
  660.             RETURN FALSE;
  661.          END;
  662.       END KeyTranslate;
  663.  
  664.  
  665.    PROCEDURE WindowProc ['WindowProc'] (
  666.    (* Main Window Procedure -- Handles message from PM and elsewhere *)
  667.          hwnd  : HWND;
  668.          msg   : USHORT;
  669.          mp1   [VALUE] : MPARAM;
  670.          mp2   [VALUE] : MPARAM) : MRESULT [LONG, WINDOWS];
  671.  
  672.       VAR
  673.          ch : CHAR;
  674.          hps       : HPS;
  675.          pswp      : PSWP;
  676.          c1, c2    : CHAR;
  677.          NullRectl [0:0] : RECTL;
  678.  
  679.       BEGIN
  680.          CASE msg OF
  681.             WM_HELP:
  682.                IF TermMode THEN
  683.                   WinDlgBox (HWND_DESKTOP, hwnd, HelpDlgProc,
  684.                              0, IDM_TERMHELP, 0);
  685.                ELSE
  686.                   WinDlgBox (HWND_DESKTOP, hwnd, HelpDlgProc,
  687.                              0, IDM_HELPMENU, 0);
  688.                END;
  689.                RETURN 0;
  690.          |  WM_SETFULL:
  691.                SetFull;
  692.                RETURN 0;
  693.          |  WM_SETRESTORE:
  694.                SetRestore;
  695.                RETURN 0;
  696.          |  WM_SETMAX:
  697.                SetMax;
  698.                RETURN 0;
  699.          |  WM_MINMAXFRAME:
  700.                pswp := PSWP (mp1);
  701.                IF BITSET (pswp^.fs) * BITSET (SWP_MINIMIZE) # {} THEN
  702.                   (* Don't Display Port Settings While Minimized *)
  703.                   WinSetWindowText (FrameWindow, ADR (Title));
  704.                ELSE
  705.                   WinSetWindowText (FrameWindow, ADR (Banner));
  706.                   IF TermMode AND
  707.                    (BITSET (pswp^.fs) * BITSET (SWP_RESTORE) # {}) THEN
  708.                      (* Force window to be maximized in terminal mode *)
  709.  
  710.                      WinPostMsg (FrameWindow, WM_SETMAX,
  711.                                  MPARAM (0), MPARAM (0));
  712.                   ELSIF (NOT TermMode) AND
  713.                    (BITSET (pswp^.fs) * BITSET (SWP_MAXIMIZE) # {}) THEN
  714.                      (* Prevent maximized window EXCEPT in terminal mode *)
  715.                      WinPostMsg (FrameWindow, WM_SETRESTORE,
  716.                                  MPARAM (0), MPARAM (0));
  717.                   ELSE
  718.                      (* Do Nothing *)
  719.                   END;
  720.                END;
  721.                RETURN WinDefWindowProc (hwnd, msg, mp1, mp2);
  722.          |  WM_CREATE:
  723.                hdc := WinOpenWindowDC (hwnd);
  724.                VioCreatePS (frame_hvps, 25, 80, 0, FORMAT_CGA, 0);
  725.                VioCreatePS (child_hvps, 16, 40, 0, FORMAT_CGA, 0);
  726.                DosCreateThread (TermThrProc, TermThr, ADR (TermStack[STKSIZE]));
  727.                DosSuspendThread (TermThr);
  728.                RETURN 0;
  729.          |  WM_INITMENU:
  730.                Check (ColorSet);
  731.                RETURN 0;
  732.          |  WM_COMMAND:
  733.                DoMenu (hwnd, mp1);
  734.                RETURN 0;
  735.          |  WM_TERMQUIT:
  736.                TermMode := FALSE;
  737.                DosSuspendThread (TermThr);
  738.                VioAssociate (0, hvps);
  739.                (* Restore The Window *)
  740.                SetRestore;
  741.                Enable (IDM_CONNECT);
  742.                Enable (IDM_SEND);
  743.                Enable (IDM_REC);
  744.                Enable (IDM_DIR);
  745.                Enable (IDM_OPTIONS);
  746.                Enable (IDM_COLORS);
  747.                RETURN 0;
  748.          |  WM_TERM:
  749.                PutPortChar (CHR (mp1.W1));   (* To Screen *)
  750.                RETURN 0;
  751.          |  WM_CHAR:
  752.                IF TermMode THEN
  753.                   IF KeyTranslate (mp1, mp2, c1, c2) THEN
  754.                      PutKbdChar (c1, c2);   (* To Port *)
  755.                      RETURN 0;
  756.                   ELSE
  757.                      RETURN WinDefAVioWindowProc (hwnd, msg, mp1, mp2);
  758.                   END;
  759.                ELSE
  760.                   RETURN WinDefWindowProc (hwnd, msg, mp1, mp2);
  761.                END;
  762.          |  WM_PAINT:
  763.                hps := WinBeginPaint (hwnd, NULL, NullRectl);
  764.                GpiErase (hps);
  765.                VioShowPS (25, 80, 0, hvps);
  766.                WinEndPaint (hps);
  767.                RETURN 0;
  768.          |  WM_SIZE:
  769.                IF TermMode THEN
  770.                   RETURN WinDefAVioWindowProc (hwnd, msg, mp1, mp2);
  771.                ELSE
  772.                   RETURN WinDefWindowProc (hwnd, msg, mp1, mp2);
  773.                END;
  774.          |  WM_DESTROY:
  775.                VioDestroyPS (frame_hvps);
  776.                VioDestroyPS (child_hvps);
  777.                RETURN 0;
  778.          ELSE
  779.             RETURN WinDefWindowProc (hwnd, msg, mp1, mp2);
  780.          END;
  781.       END WindowProc;
  782.  
  783.  
  784.    PROCEDURE ChildWindowProc ['ChildWindowProc'] (
  785.    (* Window Procedure for Send/Receive child windows *)
  786.       hwnd : HWND;
  787.       msg  : USHORT;
  788.       mp1  [VALUE] : MPARAM;
  789.       mp2  [VALUE] : MPARAM) : MRESULT [LONG, WINDOWS];
  790.  
  791.       VAR
  792.          mp : USHORT;
  793.          hps : HPS;
  794.          c1, c2 : CHAR;
  795.          NullRectl [0:0] : RECTL;
  796.  
  797.       BEGIN
  798.          CASE msg OF
  799.             WM_PAINT:
  800.                hps := WinBeginPaint (hwnd, NULL, NullRectl);
  801.                GpiErase (hps);
  802.                VioShowPS (16, 40, 0, hvps);
  803.                WinEndPaint (hps);
  804.                RETURN 0;
  805.          |  WM_CHAR:
  806.                IF KeyTranslate (mp1, mp2, c1, c2) AND (c1 = ESC) THEN
  807.                   Aborted := TRUE;
  808.                   RETURN 0;
  809.                ELSE
  810.                   RETURN WinDefWindowProc (hwnd, msg, mp1, mp2);
  811.                END;
  812.          |  WM_PAD:
  813.                mp := mp1.W1;
  814.                IF (mp = PAD_Error) OR (mp = PAD_Quit) THEN
  815.                   WriteLn;
  816.                   IF mp = PAD_Error THEN
  817.                      WinMessageBox (HWND_DESKTOP, hwnd,
  818.                                     ADR ("File Transfer Aborted"),
  819.                                     ADR (Class), 0, MB_OK + MB_ICONEXCLAMATION);
  820.                   ELSE
  821.                      WinMessageBox (HWND_DESKTOP, hwnd,
  822.                                        ADR ("File Transfer Completed"),
  823.                                        ADR (Class), 0, MB_OK + MB_ICONASTERISK);
  824.                   END;
  825.                   DosSleep (2000);
  826.                   VioAssociate (0, hvps);
  827.                   WinDestroyWindow(ChildFrameWindow);
  828.                   Enable (IDM_CONNECT);
  829.                   Enable (IDM_SEND);
  830.                   Enable (IDM_REC);
  831.                   Enable (IDM_DIR);
  832.                   Enable (IDM_OPTIONS);
  833.                   Enable (IDM_COLORS);
  834.                ELSE
  835.                   DoPADMsg (mp1, mp2);
  836.                END;
  837.                RETURN 0;
  838.          |  WM_DL:
  839.                DoDLMsg (mp1, mp2);
  840.                RETURN 0;
  841.          |  WM_SIZE:
  842.                WinSetWindowPos (ChildFrameWindow, 0,
  843.                   Pos.cx DIV 4, Pos.cy DIV 4,
  844.                   Pos.cx DIV 2, Pos.cy DIV 2 - 3,
  845.                   SWP_MOVE + SWP_SIZE);
  846.                RETURN WinDefAVioWindowProc (hwnd, msg, mp1, mp2);
  847.          ELSE
  848.             RETURN WinDefWindowProc (hwnd, msg, mp1, mp2);
  849.          END;
  850.       END ChildWindowProc;
  851.  
  852.  
  853. BEGIN   (* Module Initialization *)
  854.     WITH Settings[ID_COM1 - COM_OFF] DO
  855.        baudrate := ID_B1200;
  856.        parity := ID_EVEN;
  857.        databits := ID_DATA7;
  858.        stopbits := ID_STOP1;
  859.     END;
  860.  
  861.     WITH Settings[ID_COM2 - COM_OFF] DO
  862.        baudrate := ID_B19K2;
  863.        parity := ID_EVEN;
  864.        databits := ID_DATA7;
  865.        stopbits := ID_STOP1;
  866.     END;
  867.     PrevComPort := NONE;
  868.     comport := ID_COM1;
  869.     TermMode := FALSE;   (* Not Initially in Terminal Emulation Mode *)
  870. END Shell.
  871.