This chapter describes the modifications or changes that need to be made to Rexx programs to enable them to run in the Rexx Plug-in. First the changes are described in the Requirements for All Rexx Programs section. Then specific examples and tips are given for each type of Rexx program in the sections that follow.
What do you have to do to a Rexx program to make it run in the plug-in? The answer ranges from nothing at all, to some minor modifications, depending on the type of Rexx program and what you want to do.
Rexx applications that run in their own window and do not use any services of the plug-in, do not need any modifications. These include both visual and command line type programs. Programmers writing those types of programs can skip the rest of this document and skip the Programming Reference document.
Rexx programs that need to interface with the plug-in, because they need to issue plug-in commands, get notification of plug-in window events, or because they are running as an applet, must be slightly modified to run in the plug-in. The following steps delineate the modifications that must be done, along with a few things to keep in mind as you are writing your Rexx programs.
This only applies to visual type Rexx programs that run as an applet of the plug-in.
Rexx programs that run as applets must be cognizant of how the
application will appear on the HTML page. The Rexx application running
as an applet is assigned an area on the HTML. That area is defined by
the height and width parameters of the
EMBED tag. The
area does not change size when the browser window is resized. If the
browser window is sized smaller than the plug-in area the browser
creates scroll bars so that the plug-in area can be scrolled. Since
the plug-in area is part of the HTML page, the plug-in area, and hence
the Rexx application running in that area, is controlled by the
browser: when the browser window is moved the plug-in area (Rexx
application) is moved, when the browser window is minimized the Rexx
application is minimized, when the browser window is closed the Rexx
application is terminated, etc.
Therefor you must remove the controls from the Rexx application that allow the user to move, size, minimize or maximize, and terminate the application window. Those tasks are handled through the browser window. This means that Rexx applications running as an applet should not have
The Rexx Plug-in takes care of removing the entry for the Rexx application from the OS/2 window switch list.
This step only applies to Rexx programs that run in a separate session.
Rexx programs that run in a separate session use the plug-in functions in the wdPlugin.dll module. (Rexx programs that run as macros use those same functions built-in to the plug-in and the Rexx functions are registered for them automatically by the plug-in.) The plug-in functions must be registered before they can be called by the Rexx program. The plug-in provides a function, wdPluginLoad(), that will register all the other plug-in functions, as shown in the example below.
While it is not necessary for Rexx programs that run as a macro of the plug-in to register the plug-in functions it will not do any harm if the functions are registered by a Rexx program running as a macro. The wdPluginLoad() function is smart enough to know what type of Rexx program is calling it and to adjust itself appropriately.
Generally you should not deregister the Rexx functions at the end of your program because there may be other programs currently running in the plug-in that are using the functions. You can use the query instances command to determine if any other Rexx programs are running. The instance count (or instances) is the count of the number of instances of the plug-in that are currently running. If instance=1 when you query instances you know that you are the only running Rexx program.
This step applies to all Rexx programs.
All Rexx programs that need to communicate with the plug-in must execute the wdParseArgs() function at the beginning of the Rexx program. The function wdParseArgs() initializes the plug-in Rexx environment and creates two Rexx stem variables: wdMainArgs. and wdEmbed. The example below shows how to call the wdParseArgs() function and how to check for errors.
GPF Rexx programs call wdParseArgs() in a different manner, as described below.
This only applies to visual type Rexx programs that run as an applet of the plug-in.
The Rexx Plug-in provides the dimensions of the plug-in area to the Rexx application in the Rexx stem variable wdMainArgs., which is created in the Rexx program by the function wdParseArgs(). These dimensions are used to size the Rexx application window.
This only applies to visual type Rexx programs that run as an applet of the plug-in.
Any Rexx programs that need to have the plug-in control its window, or to receive messages from the plug-in, must link to the plug-in using the Link command, as shown below.
The plug-in environment for Rexx is stored in the Rexx stem variable wdMainArgs. , which is created by the wdParseArgs() function. This Rexx variable must be visible at all times in Rexx. Normally this is not a problem since Rexx variables are by default global to all routines in a single source file. The problems arise in
The solution to the first problem, the PROCEDURE, is to EXPOSE the wdMainArgs. stem variable, making sure the include the trailing period at the end of the name. For example
The solution to the second problem, Rexx code in a separate source file, is to call the plug-in Rexx function wdExposeArgs() at the top of the Rexx routine in the separate file. This exposes the wdMainArgs. and wdEmbed. Rexx variables to the routine. The wdPlugin. variable must be passed in manually, if it is needed. The example below shows how to do this.
Main program
MYROUTINE.COM
The value in wdMainArgs.environment is required by the function wdExposeArgs() in order to find the variables and set them in the variable pool. You must pass wdMainArgs.environment as one of the arguments to the routine in the external file in order to supply it to the wdExposeArgs() function.
The Rexx function wdCommand() can only be used on the main thread of your Rexx program. If the program is multi-threaded you must insure that wdCommand() is not called on any of the secondary threads. If you need to multitask routines that require plug-in commands put them in a separate Rexx program and start another plug-in instance to run that Rexx program. You can then use the interprocess communication facilities provided by the plug-in to communication between the two programs/plug-in instances.
Command line type Rexx programs can run either as a macro of the
plug-in, or in a separate Command Prompt window that is run as a
separate session.
The MIME-Type value assigned to the
Type parameter of the
EMBED HTML tag determines whether the Rexx program runs
as a macro of the plug-in or in a separate Command Prompt window.
A value of
x-warpdoctor/rexx runs the program as a macro of the plug-in.
A value of
x-warpdoctor/cmdrexx runs the program in a separate session,
in a Command Prompt window.
The preferred method for running command line type Rexx programs is to run the program as a macro because the program output is integrated into the plug-in window and because the Rexx program can utilize more facilities of the plug-in for input and output. However certain types of Rexx command line programs must run in a Command Prompt window: for example Rexx programs that utilizes screen control functions such as SysTextScreenRead(), SysTextScreenSize(), SysCls(), etc.
When a Rexx program runs as a macro of the plug-in the plug-in
creates an output window in the plug-in area of the HTML page to
handle input and output display for the Rexx program.
Output from the Rexx program, either by the Rexx SAY statement or with
CHAR() or LINEOUT() statements routed to STDOUT, appear in the output
window as shown below.
Output from Rexx program Displayed in Output Window
The output window is sized and positioned to match the plug-in area
specified in the height and width tags of
the EMBED HTML tag. The foreground and background colors
used in the output window can be specified with the
FGColor and
BGColor parameters
of the EMBED tag, or they can be set in the Rexx program
using the
Set command.
Input to the Rexx program from the PULL statement can be handled three ways:
When the plug-in encounters a PULL statement it sets the focus to the output window and changes the window from read-only to read/write. The user types the response directly into the output window. When the user presses the Enter key, the window changes back to read-only and the typed response is returned as the Rexx variable specified in the PULL statement.
The plug-in SayPrompt command works like the normal Rexx SAY command except that a carriage return and line feed are not output at the end of the text. This places the cursor at the end of the text in the SayPrompt command when the user starts typing a response.
The plug-in Prompt command displays a prompt dialog where the user types in the response. The text typed in the prompt dialog is returned in the return value from the command.
The behavior of the Rexx PULL statement can be altered by setting
the PullAsPrompt plug-in variable. When
PullAsPrompt=0 the PULL statement works as described
above. When PullAsPrompt=1 or YES, the PULL statement
causes the Prompt Dialog to be displayed for input; input typed in the
dialog is returned in the Rexx variable specified in the PULL
statement. The title in the prompt dialog is Input. When
PullAsPrompt=2 the prompt dialog is displayed for the
PULL statement, but the title in the prompt dialog is the text from
the last SAY statement. For example:
displays the following prompt dialog
PullAsPrompt is also an
HTML EMBED tag parameter
and
can be set in the HTML EMBED tag that starts the Rexx
program.
The output window can be disabled or "turned off" by setting the
RexxOutputWindow=NO
parameter in the EMBED HTML tag. This replaces the
multiline edit control used for the output window with a blank rectangle
of the same size.
When the output
window is turned off all SAY statements and STDOUT and STDERR output
is discarded. PULL statements are handled as if PullAsPrompt=2,
meaning that a PULL statement displays the prompt dialog for input
with the last SAY statement used as the title to the dialog. Turning
the output window off is not recommended for Rexx as macro programs
but there are circumstances when it makes sense for Rexx as Command Prompt
type programs.
The plug-in runs x-warpdoctor/cmdrexx MIME-Type
programs in a separate Command Prompt window by starting
CMD.EXE and passing the name of the Rexx program. In addition to the
separate Command Prompt window that is opened to run the Rexx program,
the output window is also created in the plug-in area, as you can
see in the figure below.
Command Prompt Window, with Rexx Output Window in the
Background
The output window appears in the HTML page that contains the
EMBED tag that starts the Rexx program/plug-in instance.
That page/window must remain open the entire time the Rexx program is
running; when the HTML page containing the EMBED tag
is closed or destroyed the Rexx program is terminated
and the Command Prompt window is closed. The page can be destroyed
by the user clicking the Back button on the browser, or by typing
a new URL.
Rexx input and output works as normal for Rexx programs running in the Command Prompt window, meaning for example that SAY statements are output in the Command Prompt window and the user types input for the PULL statement in the Command Prompt window. The output window on the HTML page, in the browser window that started the Rexx program/plug-in instance is displayed but generally will have no text in the window. The Command Prompt Rexx program can however output text in the output window using the plug-in SayToWin command. This could be used, for instance, to display a message in the output window telling the user to close that window when the Command Prompt Rexx program finishes running, as done in the Command Prompt example program.
It can be confusing to the user to have an output window displayed
while the Rexx program runs in a separate window. To help avoid the
confusion you can minimize the area allocated to the output window
by sizing the output window
to be very small by adjusting the
height and width parameters of the
EMBED tag to small values.
(Note: the width and height values cannot be adjusted
to less than 10 or the program will not run at all on some browsers.)
Alternately you can set the EMBED tag parameter
RexxOutputWindow=NO
to prevent the MLE control from appearing and use the
BGColor parameter
of the EMBED tag to make the plug-in area blend into the
background of the HTML page, essentially making the area invisible.
To do this use the same setting for the BGColor parameter of the
EMBED HTML tag that you use for the
BGCOLOR of the HTML BODY tag. An example
of this is shown below.
<html> <BODY bgcolor="#A6CAF0"> <br> <h3>Rexx Cmd Execution</h3> <embed type='x-warpdoctor/cmdrexx' height=10 width=10 src='http://www.warpdoctor.org/helloWorld2.rex' RexxOutputWindow=NO bgcolor='#A6CAF0' > </embed> </body> <html>
This example sizes the plug-in area to be 10 pixels by 10 pixels, turns off the output window, and sets the background color of the output window to the background color of the browser window (actually the HTML document in the browser window.)
Please note that this technique will only work when specifying colors in hexadecimal values; it will not work when specifying colors by name. The hexadecimal values for colors can be found in the Presentation Manager documentation or in HTML documentation. You can also determine the hex value for a color by using the Query Colors example program. With this example program you can drop a color from the Solid Color Palette (in the OS/2 Setup folder) on the output window and the program will return the corresponding hexadecimal value.
When the Rexx program finishes running the Command Prompt window
(but not the HTML page containing the EMBED tag that
started the Rexx program) is
immediately closed, which can make it difficult for the user to read
any output the Rexx program may have written to the window. You can
set the
CloseOnExit=NO plug-in variable from the Rexx program to prevent
the Command Prompt window from closing when the Rexx program finishes
running. CloseOnExit is also a parameter of the
EMBED HTML tag and can be set from the HTML that
starts the Rexx program/plug-in.
If you want the Rexx program to close the browser window containing the HTML page that started the program when the Rexx program is done, you can issue a CloseWindow command as the last line of the Rexx program. It only makes sense to do this if the plug-in instance is started in its own browser window, plus you must know the name of the browser window you want to close. See the Windows section below for more details on opening and closing browser windows.
Since Rexx programs that run in a Command Prompt window run in a separate session they use the plug-in Rexx functions contained in wdPlugin.dll, which means the functions must be registered before they can be used. The plug-in Rexx function wdPluginLoad() is provided to register all the other plug-in functions. The following code snippet shows how to load the plug-in Rexx functions
DrRexx programs run well in the Rexx Plug-in. The major difficulty in writing DrRexx programs is handling the sizing of the application window(s), and passing focus notification back to the browser window when the DrRexx application receives the focus. Both issues are addressed below.
DrRexx applications are identified to the Rexx
Plug-in by a
MIME-Type value of
x-warpdoctor/drrexx in the
Type parameter of the
EMBED HTML tag.
The plug-in starts DrRexx.exe in a separate session passing the name
of the downloaded Rexx program as a parameter. Since DrRexx programs
run in a separate session they use the plug-in Rexx functions
contained in wdPlugin.dll. Both DrRexx.exe and wdPlugin.dll are
included in the standard Rexx Plug-in installation package, so both
files should be present on all client machines running the plug-in.
The existence of both files is checked by the plug-in before the
plug-in starts to run any DrRexx application.
Since DrRexx applications run in a separate session they must use the plug-in Rexx functions contained in the separate DLL (wdPlugin.dll) which means the functions must be registered before they can be used. The plug-in Rexx function wdPluginLoad() is provided to register all the other plug-in functions. The following code snippet shows how to load the plug-in Rexx functions
In addition (just as with all types of Rexx programs running in the
plug-in) the wdParseArgs()
function must be called before any other plug-in Rexx function.
The best place to put initialization code like this is to create a
DrRexx global procedure called INIT, which is called when the
application starts, before any other procedure is run, as shown below.
DrRexx Global INIT Procedure
If the DrRexx application is to run as an applet on the HTML page
the main window of the application must eliminate all the controls
which can be used by a user to control the window. This means the
title bar, system menu, minimize and maximize buttons must be removed, and the
border changed from a sizing border to one which cannot be sized by
the user. This is all done from the Style pop-up dialog for the main
window.
Style Dialog
Removing the Sizing border from a DrRexx application is something of a catch-22 situation. DrRexx uses the presence or absence of the sizing border to determine whether it should automatically reposition and resize all the controls within a window: if a window has a Sizing border and there is no SIZE event code for that window DrRexx will reposition and resize the controls within the window. If the border is some type other than a sizing border, or if any Rexx code exists in the SIZE event for that window then DrRexx will not reposition or resize controls for that window. This means that if you remove the Sizing border to prevent users from trying to resize the application window you are obligated to handle all the resizing and reposition tasks yourself. You have three choices:
EMBED tag height and width
parameters. Then you do not have a resize issue since all the sizes
match up to start with.
The figures below shows the Rexx code that handles resizing for the Message Pipe example program.
This figure shows the main window for the Message Pipe program.
Notice that the text box under the cursor is named tb1. You can
see this in the status line in the figure. All the text boxes are
named td1, td2,td3, and the list box is named
msgList. The main dialog window is called main
Message Pipe Example Program Main Window
This figure shows the Rexx code that handles Size events. The first
line gets the current position and width and height of the main window
into the variable x, y, width and height.
Those values are then used to position and size the three text boxes
and the list box. Position() is a DrRexx function that sets the
current size and position of the control, or returns the size and
position of a control if no arguments are passed.
Message Pipe Example Size Event Code
This figure shows how the Message Pipe example program looks in a
on an HTML page.
Message Pipe Example Size Event Code
The other catch-22 associated with the Sizing border is that the Size event does not get fired when the plug-in initially sizes the application window to fit the plug-in area. The work-around for this is to size the main window manually, using values that are passed to the DrRexx application when the application starts.
The plug-in Rexx function wdParseArgs() decodes and parses a number of values passed to the Rexx program into the Rexx stem variable wdMainArgs. Among the values placed into wdMainArgs. are the position and size of the plug-in area, which can be used to size the DrRexx application main window. The follow statement shows how to do that, assuming the name of the main window is main
This statement is best placed in the Init event for the main window. The Init event for a window gets executed when the window is created before any other event for that window.
Since DrRexx applications run a separate process from the browser
window events are not passed up the window chain from the DrRexx
window to the browser. (Events are passed down the chain
correctly by
virtue of the parent-child relationship established by the plug-in to
the DrRexx window and through PM window messages sent to the DrRexx
window by the plug-in.) The most obvious manifestation of this appears
when the application window is partly obscured by another window.
Clicking in the application window does not bring the application (and
browser) window above the obscuring window, because the application is
a child of the browser window but the browser window never gets the
focus event. (Clicking on the browser window frame, or any part of the
browser window that is not in the plug-in area does move the browser
window and application to the top of the z-order.)
Plug-in Application Obscured by Another Window
The work-around is to issue the plug-in command
GotFocus
command every time the the DrRexx application gets the focus. The
figure below shows the GotFocus command in the DrRexx FOCUS event.
Plug-in GotFocus Command in Focus Event
This focus problem is not exclusive to DrRexx but also happens with GPF Rexx applications. VX-Rexx applications handle the focus event correctly.
When running a DrRexx application as an applet, the application needs to be "linked" to the Rexx Plug-in with the plug-in Link DrRexx command. Linking the application to the plug-in tells the plug-in that the application is running as an applet and that it needs additional processing by the plug-in. The plug-in changes the parent of the DrRexx application from the desktop to the plug-in, and starts sending the DrRexx application window messages when needed. The Link command should be placed in the Init or Open event for the main window.
GPF Rexx programs run well in the Rexx Plug-in. The major drawback to using GPF Rexx for plug-in programs is that the programs can only be packaged as executables, adding approximately 25K to the size of the file that has to be downloaded. This can be partly mitigated by compressing the executable file.
GPF Rexx applications are identified to the Rexx
Plug-in by a
MIME-Type value of
x-warpdoctor/gpfrexx in the
Type parameter of the
EMBED HTML tag.
The plug-in starts the Rexx program executable (created by GPF) in
a separate session.
Since GPF Rexx programs
run in a separate session they use the plug-in Rexx functions
contained in wdPlugin.dll. In addition the size of the
executable created by GPF Rexx can be reduced by specifying that the
program use a run-time DLL - GPFRRT01.DLL. The existence of this DLL,
along with wdPlugin.dll, are checked on the client machine before
the plug-in starts the GPF Rexx program. If you choose to not use the
GPF Rexx run-time when you create your Rexx executable you need to run
the GPF program as MIME-Type x-warpdoctor/generic, which
will bypass the check for GPFRRT01.DLL by the plug-in.
Specifying the Run-Time When Building Executable
If the GPF Rexx application is running as an applet the programmer must initially size and position the main window of the application, and remove all the controls that can be used to size, move or close that window.
The minimize, maximize, system menu, and title bar controls, along
with the type
of border can all be specified from this dialog for the main window.
This screen is also where you create a "user function object" that
is called when the main window is initialized. A "user function
object" is really a Rexx routine that is called when the Init action
(event) happens. Pressing the Action button brings up a list of all
the actions (or events) associated with the window. You can highlight
an action and click on the add button to create a "user function
object" (rexx routine). In that routine is where we will register the
plug-in Rexx functions, initialize the plug-in environment and size
the main window.
GPF Rexx applications are run in a separate session so they must
use the plug-in Rexx functions contained in the DLL
wdPlugin.dll. The functions
must be registered before they can be used. The plug-in Rexx function
wdPluginLoad() is provided to register all the other plug-in
functions. The following code snippet shows how to load the plug-in
Rexx functions
The plug-in function wdParseArgs()
must be called before any other
plug-in functions, and before using any of the plug-in provided Rexx
variables. Since GPF Rexx handles arguments passed to the program
differently than the "normal" Rexx standard, wdParseArgs() must be
called differently for GPF. Normally wdParseArgs() will get the
argument(s) passed to the Rexx program and parse that argument into
the wdMainArgs. stem variable. In GPF Rexx the argument(s) passed to
the executable must be obtained using the GPF provided function
In the example above we are calling queryArgs() passing in the Rexx
variable argvar.. GPF Rexx populates that stem variable with a
number of values, the one of interest to us is in argvar.2
since it contains the value of the first (and only) argument passed to
the GPF Rexx program from the plug-in. We then call wdParseArgs()
passing in the argument string contained in argvar.2, check for
errors and call the GPF supplied sendMsg() function to display any
error message.
GPF Rexx applications are not sized automatically by the plug-in
when they start up. Instead you must size the main window using
values from the
wdMainArgs. Rexx variable. That variable is created by the
wdParseArgs() plug-in Rexx function. The code for setting the window
size and position is shown below, assuming the main window is called
MainWindow
Finally we need to link the GPF application to the plug-in so that
the plug-in can control the GPF application main window. We use the
plug-in command
Link GPF to tell the
plug-in that the GPF application is running as an applet and to allow
the plug-in to control the GPF application main window.
Rexx/TK is a library of functions that provides an interface
between Rexx and the TK graphical library. The TK graphical library is
designed to run with the TCL language, and is normally known as
TCL/TK. The Rexx/TK basically replaces most of the TCL language part
of the TK interface with a Rexx interface. In order to run Rexx/TK you
need both the Rexx functions DLL (rexxtk.dll) and the OS/2 Tcl/TK
package installed on the client machines.
The TK library, as implemented in OS/2, has no provision for
removing the title bar, system menu and minimize/maximize buttons from
windows created with the library. Therefor RexxTK applications cannot
run as applets in the plug-in. However they can run in the
plug-in in a separate window.
Because the Rexx/TK application runs in a separate window the
plug-in does not have a MIME-Type for Rexx/TK. You use either
x-warpdoctor/rexx (recommended) or
x-warpdoctor/cmdrexx.
VRexx2 (also known as VRexx) is a library of functions which can be
used to create
Presentation Manager windows and dialog boxes. VRexx2
windows/applications cannot be run as applets in the plug-in because
VRexx2 windows cannot be precisely positioned; the VRexx function to
create the window takes arguments to position the window as
percentages of the screen size. Because of this it is impossible to
position the VRexx2 window in the plug-in area of an HTML page.
While VRexx2 applications cannot run as an applet in the
plug-in, they can run in the plug-in in a separate window. Since the
VRexx2 application is running in a separate window there is no
special MIME-Type for the VRexx2 application; use either
x-warpdoctor/rexx (recommended) or
x-warpdoctor/cmdrexx.
VX-Rexx applications are identified to the Rexx
Plug-in by a
MIME-Type value of
x-warpdoctor/vxrexx, or
x-warpdoctor/vx-rexx
in the
Type parameter of the
Applications made
with VX-Rexx to run in the plug-in must be "packaged" by VX-Rexx as
"macros" using the File - Make Macro menu option, which saves about
23K of size from the file(s) that must be downloaded.
When you use the Make Macro menu option in VX-Rexx two files are created:
a *.VRM "macro" file and a *.VRW "window" file. Additional *.VRM files
may be created by VX-Rexx, for instance if the application has a
secondary thread the secondary thread will be put into its own *.VRM
file.
The *.VRM and *.VRW files must be placed in the same location on
the web server. The *.VRM file is specified in the
SRC parameter of the
If there are multiple *.VRM files, or multiple *.VRW files for a
single VX-Rexx application, you must zip all the files together into
an archive and specify
the archive file name in the
SRC parameter. See the
Packaging section for more specifics.
VX-Rexx applications should have the STDIO redirection turned off
when running in the plug-in. If STDIO is not redirected and a Rexx SAY
command is issued, a separate window is displayed by the VX-Rexx
application. This second window prevents the application from being
closed by the plug-in when the browser window or HTML page is
destroyed.
VX-Rexx applications that run in a separate session, i.e. MIME-Type
x-warpdoctor/vx-rexx, must register the plug-in Rexx functions.
VX-Rexx applications that run as a macro of the plug-in
( LInking the Rexx application to the plug-in tells the plug-in the
handle of the application's main window, and allows the plug-in to
control the application window so that the application functions as an
applet. For VX-Rexx applications this is done by
calling Link
and
passing the parameters VXREXX (or VX-REXX) and the window handle. The
window handle is returned by the
VX-Rexx function VX-Rexx application correctly bring the browser window to the top of the z-order when
the application window gets focus; there is no need to use the GotFocus() plug-in command.
When the browser encounters an In the case of the Rexx Plug-in the Packaging the Rexx program means placing the file or files needed
for the program to run in a location the web server can access, and
specifying the correct file name on the Visual Rexx application built with DrDialog and VX-Rexx can be
packaged either as an executable file, or as a "project" or
macro type file.
Visual Rexx applications built with GPF Rexx can only be packaged as
an executable file. The file that you want to specify in the
SRC parameter of the
The file name, or more specifically the file name extension, has an
important impact on how the program runs. This is caused by situations
where the browser loads a plug-in to handle a file (or data stream)
when no The way browsers should work is that they should use the
MIME-Type
specified for a data stream in the header of the HTTP message. The way
browsers really work is that they use the extension of a file
name in order to determine what MIME-Type the file contains when there
is no MIME-Type specified. Or in the case of Mozilla the browser uses
the file extension regardless of the MIME-Type specified in the HTTP
message header - which is a bug.
Therefor it is important to use file name extensions for the
Rexx program file that will not
be confused with another MIME-Type or another plug-in by the browser.
Likewise it is important for the Rexx Plug-in to register only file
extensions that will not cause conflicts with other plug-ins or with
other actions the user wants to perform on a file. To that end the
Rexx Plug-in registers the file extension .WRP for its use for
all MIME-Types handled by the plug-in. This file extension is not
known to be used by an other application or plug-in. The Rexx Plug-in
also exclusively uses the MIME-Type specified in the It is recommended that you rename all program source files to an
extension of .WRP when saving them to the web server, which
(hopefully) avoids any conflict with other applications or plug-ins.
Alternately you could compress the program source file into a zipped
archive file which hides the program file extension from view of the
browser and web server.
Rexx program file(s) can be compressed into a zipped archive file
using any industry standard zip.exe program; we recommend
Info-Zip's zip.exe. Compressing the file into a zip archive file not
only hides the program file extension, it also
significantly speeds up the download of the file to the client
machine.
The program source files in the zipped
archive should retain their original file names and extensions. The
zipped archive file name extension however should be changed from
.ZIP to .ZPP or .WRP. This prevents conflicts
with browsers that treat *.ZIP files specially, and bugs in certain
browsers.
The main name of the zip file - the part of the file name before
the extension
- must be the same as the source file contained
within the archive. For example if you are zipping the DrRexx
source file
drives.res the zip file name must be drives.zpp or
drives.wrp.
When you zip the program file(s) you must specify to the
plug-in that the file is zipped. You do this by adding the
ZippedFlag=1 parameter
to the Visual Rexx type programs that use graphics - icons, bitmaps and
such - must insure that the graphics are on the client machine. This
can be done by the application downloading the graphics file(s) when
it starts with the
GetURL command, or it can
be done by including the graphic file(s) in the same zipped archive
file that contains the source or program file. When the plug-in
downloads a zipped archive file specified in the
SRC parameter
it unzips the entire contents of the archive file in the
temporary directory
of the client machine before it starts the Rexx program. The Rexx
program, when it starts, can utilize the graphics files
from the temporary directory. To find out what the temporary directory
is (where the graphic file(s) were unzipped) the Rexx program can
either:
Rexx applications need to be careful when using the
Query TEMPDIR command,
since the location of the temporary directory can be changed by the
program using the
Set TEMPDIR command. If
the temporary directory is changed the
Query TEMPDIR command
will no longer point to the location of the files from the zipped
archive. The PARSE SOURCE Rexx statement will always point to the
location of the files unzipped from the archive.
The example below shows how to use the PARSE SOURCE statement to
find the location of a graphics file, and to tell the application
to use that graphics file. The example is from the VX-Rexx
Bouncing Global
example program.
The line
The line
The line
The line
Please note that deleting files that were extracted from the zipped
archive does not delete the zipped archive file that was downloaded.
That will remain in the browser's cache until the cache is cleared,
which normally is the what you want. The zipped file is cached so that
the next time the user executes the program the file will not have to
be re-downloaded. If for some reason you do not want the zipped file,
or the program file, to remain in the cache when the plug-in instance
terminates you can specify the
EraseOnExit=YES
parameter on the In order to run your Rexx application on a client browser you must
create a HTML page with an When the browser reads an If the MIME-Type is not found in the list of registered MIME-Types
what happens depends on the browser.
Netscape and Mozilla based browsers output the "install plug-in"
graphic
If the
PluginsPage
parameter has been set to a URL, when the user clicks on the graphic
the URL is displayed. The setting
PluginsPage='http://www.warpdoctor.org/plugin_install.html'
can be used to display the install page for the Rexx Plug-in.
When using Opera and the MIME-Type is not found what happens depends on the
version of Opera being used, or rather on the build number since the only version
of Opera available for OS/2 is version 5.12. For earlier builds of Opera, when
the browser encounters a MIME-Type not found in the list of MIME-Types associated with
plug-ins the browser just
stops, it does not
display the "click here to get the plugin" graphic. When using later builds, e.g. build 31,
Opera displays a dialog box prompting the user to get the plug-in.
Perhaps the best way to
handle Opera browsers without writing overly complex HTML/JavaScript code
is to use JavaScript to detect if the plug-in is
installed and if Opera is being used to display the page. The
following two lines, along with the file plugin_opera.js, will
handle
detecting whether the plug-in is installed, detecting if Opera is
being used, and displaying an HTML with a link to install the plug-in
or to cancel.
The example below adds the
PluginsPage
parameter and JavaScript code for handling Netscape, Mozilla based and
Opera browsers.
When the browser starts a plug-in instance to handle the
Once the plug-in instance is started the browser retrieves the file
or URL specified in the
SRC parameter of the
When non-zipped files are downloaded and saved to disk the file
name assigned to the diskfile is a randomly generated name. The files
are downloaded to the browser's cache so the browser assigns the file
name to fit its caching scheme. When necessary the plug-in will fix
the file name extension to make sure the file will execute correctly,
but the main part of the file name is not changed. Normally this is
not an issue, since most (Rexx) programs don't care, or even know,
what their file name is. There are certain, rare occasions when it is
important for the name of the file downloaded to the client's hard
drive to match the name of the file on the server. For example the
WarpIN install script for the Rexx Plug-in uses the WarpIn install
file name to turn on or off install options depending on which
browsers are on the user's machine. For this situations the
MakeNameSame=YES
The Rexx Plug-in parses the URL in the
SRC parameter
to obtain the default value for the
CGIURL variable.
The Each The Rexx Plug-in has a limit of 24 concurrent instances that can
run at the same time.
Before the Rexx Plug-in starts a Rexx program it checks the
security configuration file to see if the program has
permission
to run on the client. The URL value from the
SRC parameter
is parsed into a
SiteURL that contains
the site identity, and that site identity is compared to the approved
sites from the security configuration file. If a match is not
found the plug-in displays a dialog prompting the user for a
determination of how to handle the program: cancel the program, run
the program or run the program and add its site to the approved site
list. The SiteURL
is obtained from the Once the file in the
SRC URL is downloaded the
Rexx Plug-in executes the program.
The method used by the Rexx Plug-in to run the
program varies
depending on the type of Rexx program. The type of the Rexx program
is determined by the MIME-Type specified in the
TYPE parameter. Some
types of Rexx program are run directly by the plug-in as a macro of
the plug-in, meaning the plug-in executes the RexxStart() function
passing in the name of the downloaded file to the function. Other
types of Rexx programs are run by starting a separate session
and running the Rexx program in that session. For WarpIN programs
(
TYPE=x-warpdoctor/warpin) the plug-in loads the WarpIN DLL and
starts WarpIn.exe in a separate session and passes the downloaded file
name as an argument.
When the HTML page is destroyed - by the user loading a new URL in
the browser window or closing the browser window - the plug-in
instance is destroyed and the
Rexx program is stopped. (However when the Rexx program finishes the
HTML page remains displayed - see the next paragraph.) If the Rexx
program is running as a macro of
the plug-in, the plug-in issues a HALT instruction for the program; if
the program is running in a separate session the plug-in sends a
WM_QUIT message to the application (if it is a visual application) and
closes the session. The Rexx programmer can control how long the delay
is between the plug-in sending the WM_QUIT message and closing the
session by setting the ShutDownDelay value. ShutDownDelay is both an
When the Rexx program terminates or finishes running, the HTML page
containing the Each type of Rexx application has a
window on the HTML page.
For visual Rexx
applications that run as an applet
the application's main window is sized and positioned to fit in the
plug-in area allocated on the HTML page. For command line type
applications ( The Rexx Plug-in provides a number of
Rexx functions
for the
program to communication with the plug-in. The vast majority of Rexx
program will utilize just three of those functions:
wdPluginLoad() is called by Rexx programs running in a separate
session in order to register the other plug-in Rexx functions.
Registering the functions make the function available to be used by
the program. Rexx programs that run as a macro of the plug-in do not
need to call wdPluginLoad() since the functions are registered
automatically by the plug-in before it starts the program. Calling
wdPluginLoad() from a Rexx program running as a macro will not cause
any harm since wdPluginLoad() is written to recognize what type of
program is executing it. This allows a Rexx program to be run either
as a macro (x-warpdoctor/rexx, x-warpdoctor/vxrexx) or in a separate
session (x-warpdoctor/cmdrexx, x-warpdoctor/vx-rexx) without being
rewritten.
All the functions return an error string to indicate a failure or
error in the function. The traditional way of programming is to check
the return value of each function call for the error string indicator.
All error return strings begin with the characters # Error .
The Rexx program can simply check if the first character of the return
string = '#' to determine if an error has occurred, as shown in the
example below
An alternate method of error handling that requires less coding by
the Rexx programmer is to instruct the plug-in Rexx functions to throw
a syntax error if an error occurs and to pick up the error with a
SIGNAL ON Rexx statement, as shown in the code snippet below.
The Rexx variable wdPlugin.errorSwitch is used to control
the
error handling of the functions. When wdPlugin.errorSwitch=0
the functions return
errors in the return value of the function - the normal, default
behavior. When wdPlugin.errorSwitch=1 and an error in any of
the functions causes the function to:
In the above example the line
You can alter the error handling at any point in the Rexx program
by changing the value of the wdPlugin.errorSwitch variable.
The Rexx Plug-in provides a number of commands for opening and
closing browser windows. Since the Netscape Plug-in API provides a
very limited feature set for manipulating browser windows the Rexx
Plug-in uses JavaScript to do the window manipulation. However the
Rexx Plug-in does not use the Netscape Live Connect feature for
calling JavaScript from the plug-in, but rather implements its own
interface. The Live Connect feature is not implemented in many other
browsers and is not supported in Mozilla based
versions of Netscape.
The Rexx Plug-in implements its JavaScript interface by creating a
file
containing an HTML page with the needed JavaScript code on the page,
and opening the page in a browser window. The browser executes the
JavaScript code as it is reading the page. The browser window is then
immediately closed, since it is no longer needed. The advantage to
this method is that it works with all browsers on all platforms. The
disadvantage is that a browser window flashes on the screen while the
browser is reading the HTML page.
The flashing can be
eliminated by specifying to the plug-in a browser window to use for
displaying/reading the temporary HTML pages with the
WorkWindowName
The two examples above create a window as shown below. Notice the
very small figure at the lower right corner of the window. This is the
scroll bars that Netscape is attempting to display for the lower
window frame - the "work window".
The Rexx Plug-in provides 6 commands that open new browser windows
or change the contents displayed in an already open window. The
commands are
The Rexx program knows the "name" of a browser window
CloseWindow
command can be used to close that window.
CloseWindow
can also be used to close the current window, but doing so will
destroy the running plug-in instance and terminate the Rexx program.
Likewise the
GetURL command
can be used to load a different page (a URL) into another window,
providing the program knows the window name, or to load a different
page into the current window, which will also destroy the running
plug-in instance.
Alternately the The second to the last example above replaces the current page with
the text Done with Install when the program terminates. The
last example replaces the current page with the same text but after
displaying the text for 10 seconds the browser window is closed.
There are two protocols that can be used for transferring files
from a sever to the client: HTTP and FTP. Of the two, FTP is the most
reliable for binary files. Our experience has been that browsers
mangle binary files when transferring with HTTP unless the browser
is aware that the file is a binary file. (This may not be true on UNIX
but it is true on OS/2 and Windows.)
The Rexx Plug-in provides two commands for transferring files from
a server to the client.
GetURL
can transfer
using either HTTP or FTP.
GetFile transfers only
using HTTP. However
GetFile is capable of
telling the browser that the file being transferred is binary; with
GetURL there is no
reliable way of insuring that binary files
transferred with HTTP are not mangled.
The
GetURL
command can be used to download a file using either FTP
or HTTP. The syntax of the command is
If an HTTP type URL is specified as the url argument the
file is
transferred using HTTP. If a FTP URL is specified as the
url argument the file is transferred using FTP.
When downloading a file the target argument must be
_file. This tells the command to route the data stream to a
disk file rather than to a window. If the fileName argument is
not specified the plug-in will create a random file name
automatically; if a file name is specified that name will be used for
the disk file that is created. In either case if the command is
successful the name of the disk file will be the return value.
When using HTTP do download binary files the transfer is reliable
with zipped data. For non-zipped binary data we have observed mangled
data using Opera, Netscape and Mozilla. For complete reliability with
non-zipped binary data we advise using the FTP protocol, even though
that involves setting up an FTP server to handle the requests.
Alternately for non-zipped binary data you can use the
GetFile
command
for reliable HTTP transfers.
The
GetFile
command downloads files using the HTTP protocol. The
syntax is
GetFile
requires the
CGI program wdPluginCgi.exe on the web
server. (The CGIURL
variable/parameter must be set correctly for this command to work. If
the default value set by the plug-in is not correct the Rexx program
must specify the correct value in the The only reliable protocol for uploading binary files to a server
is FTP.
The HTTP protocol cannot be reliably used with Netscape browsers on
the OS/2 or
Windows platform. The Rexx Plug-in provides two commands for uploading
a file to a FTP server:
CopyFileToServer and
MoveFileToServer. Both use the FTP protocol and require an FTP
server at the server end. The different between the two is that the
CopyFileToServer leaves the original file on the client, where the
MoveFileToServer command removes the file from the client.
Unfortunately both
CopyFileToServer and
MoveFileToServer only work on Netscape browsers. Mozilla based browsers,
including IBM Web Browser, and Opera browsers do not handle the upload correctly.
The commands appear to work but the file never makes it to the server. Therefor
if your program is running in one of those browsers you need to use FTP directly
to upload files to a server. Luckily the Rexx/FTP utility package is complete and
easy to use. You can also be fairly certain that the package on in the client machine
since the client is using TCP/IP to connect to the web server.
The example below shows a small program that uploads a file using the Rexx/FTP package.
The CopyFileToServer command copies the source file to a temporary
file name, and uploads the temporary file to the FTP server. The
temporary file name is made up of a randomly generated name plus the
user's IP address as it appears to the web server. This helps to
insure that the file name will be unique when it gets to the FTP
server. The command returns when the file transfer is complete. The
return value is the file name used for the transfer, i.e. the name of
the file on the FTP server.
If you want to specify what the name of the file will be on the FTP
server use the
MoveFileToServer command. If needed you can use the
CopyFile command to create a copy of the file on the client before
it is "moved", so that the original will not be destroyed.
The MoveFileToServer command moves the file from the client to the
FTP server. When the command returns the file is no longer on the
client. The name of the file on the FTP server is the same as the name
of the file on the client.
The Rexx Plug-in provides a number of commands for working with or
querying local files and directories. Some of these actions could
also be accomplished in a Rexx program by the program passing a
command to the OS/2 Command Processor, which is the default
"environment"
for unrecognized Rexx commands. The advantage to using the plug-in
command is that error messages are returned in the return value rather
than displayed using STDOUT, as they are when using commands passed to
the OS/2 Command Processor.
The commands
AppendFile,
CopyFile,
DeleteFile, and
MoveFile are all
interfaces to operating system functions. If the command is successful
the command returns a zero as the return value. If the command is not
successful the command returns a string starting with
# Error - rc message
where rc is the operating system
return code and message is that return code translated into
text. The OS return code is always the fourth word in the
return string; you can use the Rexx word() function to retrieve
that return value, if needed. Please note that while the return code
will have a different numeric value on different operating systems
for the same type of error, a value of zero will always be returned
for success regardless of the operating system.
The Rexx Plug-in can install WarpIN type install packages with a
single click by the user of a link on an HTML page. This capability,
coupled with the Rexx Plug-in's interface to FTP for downloading,
enables the Rexx Plug-in to reliably and successfully download and
install WarpIN install packages. To use this feature of the plug-in
the web page designer must take certain design steps to enable the
plug-in operation.
The Rexx Plug-in treats *.WPI type WarpIN install packages just the
same as it
does Rexx programs, except that instead of executing the Rexx program
the plug-in executes WarpIN on the client machine, passing the name of
the downloaded install package. To use the WarpIN install feature:
Six additional The example below shows how to run the WarpIN plug-in instance in a
separate window. The first figure is the HTML page that runs the
WarpIN install - plugin_warpin1.html
The next figure is the HTML that provides the link the user clicks
on to start the install. When the link is clicked a second browser
window is opened with plugin_warpin1.html loaded in the
window.
The figure below shows the window with the link.
When you click on the link, this is the window that is opened - the
window with page plugin_warpin1.html.
The default setting of
MakeNameSame=YES for
x-warpdoctor/rexx programs allows you to write self-referencing
WarpIN install scripts, which would not be possible if the name
of the install file on the client was not known to the script.
The code snippet below is from the WarpIN install script for the
Rexx Plug-in. The install script checks if the IBM Web Browser is
installed on the client machine. If it is, a "package" is displayed on
the WarpIN screen for installing the plug-in for that browser. If the
browser is not installed, the "package" is not shown on the WarpIn
screen. The install script relies on the name of the install file
being wdRexxin.wpi in order to work.
The EXTERNAL keyword of the package 3 (PCK INDEX=3) checks
if the file name on the right side of the equal sign exists. It if
exists the package is shown on the screen. If the file doesn't exist
the package is not shown. The EXTERNAL keyword is using a facility of
WarpIN where the return value from a Rexx script can be used in place
of a value. The Rexx script checks if the IBM Web Browser has an entry
in the OS2USER.INI file. If it does the Rexx script returns the value
wdRexxIn.wpi, which is the name of the currently running
install program. If there is no entry in OS2USER.INI for the browser
the Rexx script returns a name that is known to not exist -
NoInstall.wpi.
Self-contained WarpIN install files, i.e. executable files with
WarpIN bundled in the install file, must be specified as
type=x-warpdoctor/generic, and the
SRC parameter
changed to the executable install file.
All the other parameters should stay the
same. The
x-warpdoctor/generic
MIME-Type will run any executable file, including self-contained
executable WarpIN install files. The example below shows the
Using the plug-in makes installing packages easier for the user,
but makes life more difficult for the web administrator. The web
administrator cannot simply write an The Rexx Plug-in includes the MIME-Type
x-warpdoctor/generic
which is designed for running three types of
executables
All three of these types of programs use the
type=x-warpdoctor/generic parameter in the What arguments are passed to the executable program and how the
arguments are passed are
determined by the
GenericArgsFlag parameter of the
Applications not written in Rexx can still use the full facilities
of the Rexx Plug-in because all communication between the
plug-in and Rexx programs running in a separate session is handled
through named pipes. (Communication between the plug-in and a Rexx
program running as a macro of the plug-in is handled differently and
does not use named pipes.) The plug-in was designed this way to allow
non-Rexx programs to communication with the plug-in in hopes that some
vendors (say for example Sundial Systems) would convert their
applications (say for example Mesa/2) to run as applets in the
plug-in.
Each Rexx Plug-in instance creates a unique named pipe with a name
of \PIPE\WDPLUGIN\instanceHandle. The pipe is a message based
pipe with a buffer size of 64K. When the Rexx program calls
the function
wdParseArgs()
the client end of the pipe is opened with a DosOpen() command.
Each time
wdCommand()
is called the arguments are concatenated together (separated by a
space) and written to
to the pipe with a DosWrite(). The pipe is then read with
with a DosRead() and the result string from the pipe is the return
value for the function. Every command (DosWrite() ) has a return value
(DosRead() ). Everything that passes through the pipe is a
string value, just as all values stored in Rexx variables are string
values.
This means any program that can work with character strings
(with or without a terminating NULL) and can call
DosRead() and DosWrite() can sends commands to the Rexx Plug-in.
Strings sent to the plug-in do not need a terminating null character;
result strings sent by the plug-in always have a terminating null
character.
Any program that can send commands to the plug-in can also run as
an applet of the plug-in, provided the program meets the same
requirements for running as an applet that Rexx programs do, namely:
all controls must be removed from the main window of the program that
allow the user to size, move, close, minimize or maximize the main
window. The program must initially size and position its main window
to fit the plug-in from arguments passed to the program when it is
started. And the program must
use one of two
Link commands to establish a
parent-child relationship between the program and the plug-in window.
The Link
findHandle command
causes the plug-in search for a window appearing on the desktop
with a PID that
matches the PID of the session started to run the program. This is the
same method used to link DrRexx applications to the plug-in. With
Link Handle handle
command the program supplies the window handle of the main window to
the plug-in as an argument of the command. The handle value must be a
in base 10 ASCII format.
A Common Gateway Interface (CGI) program is a program on the web
server that is called by the web server to perform processing beyond
what the web server can do. Rexx programs can use the
PostURL command
to execute CGI programs on the web server and pass parameters to those
programs.
The web server passes parameters to the CGI program when it calls
the program. The parameters passed in the first example are everything
past the question mark, which separates the program name from the
parameters. The parameter passed in the second example is the name and
value for the input field input1; forms pass a parameter for
each input field on the form.
The parameters are passed by the web server to the CGI program
using three different methods:
The environmental variable REQUEST_METHOD is set by the web server
before it calls the CGI program
to a value of POST or GET to indicate to the program which method it
is using to pass parameters to the program.
The CGI program communicates with the browser by sending output to
STDOUT. The web server picks up the CGI program's output and routes it
to the browser that caused the program to be executed, when the CGI
program finishes executing. Before routing the output to the browser,
the web server first examines the output and applies HTTP headers to
the output, unless instructed not to.
The Rexx Plug-in provides a way of calling CGI programs and passing
parameters with the
PostURL command. This
command executes a CGI program on the web server using the POST method
of passing parameters.
The
PostURL
command is the only plug-in command that
is broken into
"subcommands", the subcommand being the first argument to
PostURL.
The four subcommands:
The TARGET and VAR subcommands can be issued in any
order, and other plug-in commands can be issued between the URL
and POST subcommands.
The
PostURL
command enables cooperative processing between the Rexx program
running in the plug-in and CGI programs on the web server. The most
common way for this to take place is for the Rexx program to direct
the output of the CGI program to a file and read the file to process
the data returned by the program. Alternately, for smaller results
(64K or less) the Rexx program can direct the output from the CGI
program to the return value of the POST subcommand. This is
the method used by the plug-in to ascertain the user's IP address on
the web server. The example below emulates in Rexx how the plug-in gets the
remote IP address for the
Query IPAddress
command.
The above Rexx program produces the output below.
The CGI program wdPluginCgi looks for an variable called
action and performs some action based on the value of that
variable. The C++ code snippet below show the section that handles the
IP Address request. REMOTE_ADDR is an environment variable set by the
web browser to the IP address of the requester before executing a CGI
program.
The Rexx Plug-in provides a limited interface between JavaScript
and Rexx. The interface allows a Rexx program to execute JavaScript
commands and functions, a JavaScript routine to start a Rexx program, a Rexx program to set
JavaScript variables (in Netscape and Mozilla based browsers), and a JavaScript
routine to set plug-in variables that a Rexx program can access.
This chapter is divided into two sections:
JavaScript to Rexx features, and Rexx to JavaScript
features
JavaScript to Rexx interface breaks down into two basic scenarios:
Each scenario is covered is its own section below.
When we say passing values/parameters from JavaScript to Rexx we
are refering to both JavaScript variables and HTML "fields"
defined in an HTML runDate and tempStr are JavaScript variables. HTML
"fields" are defined between the
A JavaScript routine can start a new Rexx program by writing out
a The Rexx program sees the parameters two ways:
Parameters are not case sensitive when queried with the
Query ParmValue
command or when set into the
wdEmbed. stem
variable.
The JavaScript commands to create an An alternative to hand-coding the JavaScript needed to start a Rexx
program and pass values to the program, is to use the
plugin_form2embed.html file or the
form2embed()
JavaScript function provided in the WarpDoctor web site. Using either
the HTML file or the JavaScript function requires a small amount of
JavaScript in your HTML page, but the JavaScript is very simple
compared with writing your own routine to create the
The way the
plugin_form2embed.html file
works is that it looks for
JavaScript variables that match any
HTML Standard and Plug-in
Standard parameters and output those in the Parsing the Argument String
queryArg(), passing in the name of a Rexx stem variable
to hold the argument(s). One of the tail variables of the stem passed
into the queryArg() is then passed to wdParseArgs(), as shown below.
Linking the GPF Application to the Plug-in
Rexx/TK
VRexx
VX-Rexx
EMBED HTML tag, depending on how the application is to be
run by the plug-in.
When using the x-warpdoctor/vx-rexx
MIME-Type the plug-in starts wdRunRx.exe in a separate session, which
in turn runs the VX-Rexx application. When using the
x-warpdoctor/vx-rexx MIME-Type the plug-in runs the
application as a macro of the plug-in, meaning the plug-in itself
runs the application. Running the VX-Rexx application
as a macro of the plug-in is better than running it in a separate
session; however there are certain VX-Rexx applications which do
not
terminate cleanly when run as a macro. For those applications you will
have to run the application in a separate session, i.e. use the
x-warpdoctor/vx-rexx MIME-Type. The main symptom for an
application that does not terminate cleanly is for the VX-Rexx
application to crash the browser when the application is terminated.
Packaging a VX-Rexx Application as a Macro
EMBED tag. The plug-in automatically retrieves the *.VRW
file associated with the *.VRM file from the same location on the
web server as the *.VRM file.
Main Window
VX-Rexx applications that run as an applet of the plug-in must have
all the controls removed from the main window that allow the user to
move, size, close, minimize or maximize the window. That is done in
VX-Rexx from the properties notebook for the window, on the
Frame tab, as shown below. Notice that all the check boxes are
unchecked.
Properties for the Main Window
x-warpdoctor/vxrexx) do not need to register the plug-in
Rexx functions; however it does no harm to register the functions when
not needed since the wdPluginLoad() function is smart enough to handle
both situations correctly. The best place to put these Rexx statements
is in the INIT section of the main window. The code example below
shows the INIT section from the Calc example program; the
additions required by the plug-in are shown in red.
/*:VRX */
Init:
call VRRedirectStDIO "OFF"
call RxFuncAdd "wdPluginLoad","wdplugin","wdpluginLoad"
call wdPluginLoad
call wdParseArgs
/* Clear the calculator memory
*/
memory_total = 0
call pb_c_Click
/* Create the window
*/
window = VRWindow()
/**
call VRMethod window, 'CenterWindow'
**/
call vrset "window1" , "left" , wdmainargs.winx||"P"
call vrset "window1" , "top" , wdmainargs.winy-wdmainargs.winHeight||"P"
call vrset "window1" , "width" , wdmainargs.winWidth||"P"
call vrset "window1" , "height" , wdmainargs.winHeight||"P"
numeric digits 12
call wdCommand "link vxrexx "|| x2d(substr(vrget("window1","hwnd"),6),10)
call VRSet window, 'Visible', '1'
call VRMethod window, 'Activate'
drop window
What the code example shows is:
call VRRedirectStDIO "OFF"
call RxFuncAdd "wdPluginLoad","wdplugin","wdpluginLoad"
call wdPluginLoad
EMBED tag.
call wdParseArgs
call vrset "window1" , "left" , wdmainargs.winx||"P"
call vrset "window1" , "top" , wdmainargs.winy-wdmainargs.winHeight||"P"
call vrset "window1" , "width" , wdmainargs.winWidth||"P"
call vrset "window1" , "height" , wdmainargs.winHeight||"P"
numeric digits 12
call wdCommand "link vxrexx ", x2d(substr(vrget("window1","hwnd"),6),10)
Linking the VX-Rexx Application to the
Plug-in
vrget("window1","hwnd"), but the handle is returned
in hexadecimal;
the Link command wants the value in decimal. The Rexx function x2d() converts the hexadecimal
into decimal. but we have to use the numeric digits 12 statement to prevent
the value from being truncated. The two statements below show how this
is done, assuming the main window is called window1.
numeric digits 12
call wdCommand "link vxrexx "|| x2d(substr(vrget("window1","hwnd"),6),10)
Focus Issue
Packaging the Rexx Application
EMBED HTML tag on a
page of HTML the browser searches the tag for the
Type and the
Src parameters. The
TYPE parameter specifies the MIME-Type associated with
the EMBED tag which the browser uses to determine which
plug-in to load for the tag. The SRC parameter specifies
the file that is to be streamed to the plug-in.
TYPE parameter
tells the plug-in what type of Rexx program it is going to run:
DrRexx, command line in a Command Prompt window, GPF Rexx, etc.
The Rexx plug-in then executes the program streamed to it by the
browser (from the SRC parameter) when the program is
finished downloading. The method used by the plug-in to execute the
program depends on the type of Rexx program being run.
SRC parameter of
the EMBED tag, along with the correct TYPE.
Creating the EMBED tag is covered in the
following section. This section discusses
packaging the program: which file to use for the program, what name to
use for that
file, and optionally compressing the file or files that make up the
Rexx program.
EMBED tag is shown in the table below for each type of
Rexx program.
Rexx Application Type Program Source File
Command Rexx
The file containing the Rexx
source code, the *.CMD file
Rexx
The file containing the Rexx source code, the *.CMD file
DrRexx The DrDialog project file,
*.RES
GPF Rexx The executable file created with the
Toolkit - Builder - Build .Exe menu option of the Interface
Builder
Rexx/TK The file containing the Rexx source code,
usually a *.CMD file.
VRexx2
The file containing the Rexx source code, the *.CMD file
VX-Rexx The files created with the File - Make
Macro menu option, the *.VRM & *.VRW files.
WarpIN The *.WPI file.
WarpIn is covered in
Installing WarpIN Archives below.
File Extensions
EMBED has appeared in an HTML page. This
happens, for example, when a use clicks on a link that points simply
to a non-HTML file.
TYPE
parameter of the EMBED regardless of the MIME-Type
designated by the browser when streaming the data to the plug-in. This
avoids potential conflicts with other files and it gets around the
Mozilla bug of ignoring the TYPE parameter when
ascertaining the MIME-Type. When necessary the plug-in renames a file
to the correct
extension when it is saved to the client disk based
the type of Rexx program being run, i.e. based on the MIME-Type
specified in the TYPE parameter.
Compressing Rexx Sources
EMBED tag. When the Rexx Plug-in sees the
zippedflag=1 parameter it unzips the streamed file (the
file specified in the SRC parameter) in the client's
temporary directory and executes the source file from the temporary
directory with the name matching the archive file.
EMBED tag.
Starting the Rexx Plug-in
EMBED HTML tag in the page.
The parameters to the EMBED specify the Rexx program
file, the type of Rexx program, the size of the area allocated on the
page to the plug-in (the plug-in window size), and other items that
control how the plug-in area looks on the page and how the plug-in
runs the Rexx program.
The example below is a complete HTML page, including
the EMBED tag, from the
calculator example program.
<html>
<BODY bgcolor="white">
<br>
<h3>VX-Rexx Calculator</h3>
<embed
type='x-warpdoctor/vxrexx'
height=350
width=310
src='http://www.warpdoctor.org/calc.zpp'
title='Calculator Sample Program'
zippedFlag=1
>
</embed>
</body>
<html>
EMBED tag it searches for
the TYPE parameter
containing the MIME-Type. The browser then searches its list of
registered MIME-Types/plug-ins to find the first entry that matches.
The browser then loads the plug-in DLL, if it is not already loaded,
and starts an instance of the plug-in. (Opera browsers load the
plug-in DLL when the browser starts.)
<script language="JavaScript" src="http://www.warpdoctor.org/plugin_install.js"></script>
<script>checkPlugin();</script>
The file plugin_install.js can be called from the WarpDoctor site, or
you can copy the contents shown below to a file on your own site. Be
sure to place the file in same location as your HTML files.
<html>
<BODY bgcolor="white">
<script language="JavaScript" src="http://www.warpdoctor.org/plugin_install.js"></script>
<script>checkPlugin();</script>
<br>
<h3>VX-Rexx Calculator</h3>
<embed
type='x-warpdoctor/vxrexx'
height=350
width=310
src='http://www.warpdoctor.org/calc.zpp'
title='Calculator Sample Program'
zippedFlag=1
PluginsPage='http://www.warpdoctor.org/plugin_install.html'
>
</embed>
</body>
<html>
EMBED tag/area it passes to that instance all the
parameters specified for the EMBED tag. Some of those
parameters have special meaning to the browser: for instance the
height and width parameters tell the browser
how big to make the plug-in area on the HTML page, the
border parameter tells the browser what kind of border to
draw around the plug-in area, etc. The parameter that do not have
meaning to the browser - those that are not in the HTML specification
- are ignored by the browser. This allows parameters of the
EMBED tag to be used to pass arguments to the Rexx
program. The Rexx Plug-in makes the EMBED tag parameters
available to the Rexx program
two different ways.
EMBED tag and streams the data to the plug-in.
The URL must
be a fully qualified URL rather than a relative URL, meaning that the
URL must begin with http://, ftp://, or file://;
the Rexx Plug-in will only run Rexx programs from http, ftp, or file
type URLs.
The data streamed to the plug-in from the URL specified in the
SRC parameter
is the Rexx program that is executed by the plug-in, or the WarpIN
install file that is installed by the plug-in. The Rexx Plug-in
always saves the initial data stream to a disk file on the client.
If the data stream is not compressed
the Rexx Plug-in executes the file; if the data stream is compressed
(as determined by the
ZippedFlag
parameter)
the plug-in unzips the archive file and executes the program
file extracted from the archive file.
EMBED parameter should be set to force the name on the
client to be the same as the name on the server.
MakeNameSame=YES
is the default for
x-warpdoctor/warpin programs,
MakeNameSame=NO
is the default for all other types of programs.
CGIURL variable defines the URL of the CGI program
wdPluginCgi.exe on the web server. The wdPluginCgi.exe
CGI program is used by the plug-in to implement a number of
commands and the plug-in must be able to execute
wdPluginCgi.exe
in order to function correctly. The plug-in sets the CGIURL value by
parsing the domain out of the SRC
URL
and appending /cgi-bin/wdPluginCgi.exe to the domain. The
domain is
the part of the URL up to the first forward slash: for example the URL
http://www.wonderfulSite.org/bigdir/myRexxProgram.cmd is parsed
into
http://www.wonderfulSite.org/cgi-bin/wdPluginCgi.exe. If the
default value
is not correct you must specify the
CGIURL parameter with
the correct value.
EMBED tag read by the browser causes the browser
to start a unique plug-in instance to handle that tag. If multiple
EMBED tags exist on a single page, or if the user opens
multiple pages at the same time that have a EMBED tag,
multiple instances of the plug-in will be running concurrently.
If more than one of the EMBED tags specifies the same
URL in the
SRC parameter, multiple
copies of the same Rexx program can be running concurrently. You can
use the
RunExclusive parameter
to prohibit multiple copies of the same Rexx program from concurrently
running, or to prevent other programs (URLs) from running while the
program runs.
SRC URL by truncating the URL at the
last forward slash. For example the SRC URL
http://www.wonderfulSite.org/bigdir/myRexxProgram.cmd
becomes the SiteURL
http://www.wonderfulSite.org/bigdir. If the Rexx program needs
to retrieve additional files from the web server it should use the
SiteURL to generate the
URL of the file it needs to retrieve, for example the line below
from a Rexx program
EMBED
parameter
and a
plug-in variable.
Rexx programs can also get notification of impending termination by
opening a
message pipe to the plug-in and listening
for the shutdown message.
EMBED tag remains displayed.
The Rexx program can close the window at the very end of the program
with the
CloseWindow
command, or load a new URL into the window with the
GetURL
command. The
AutoCloseWindow EMBED parameter can also be used to
instruct the plug-in to close the window or load a new URL when the
program terminates. See Closing Windows below
for details.
Plug-in Window
x-warpdoctor/rexx and
x-warpdoctor/cmdrexx) the plug-in creates an output
window in the plug-in area for displaying the output from the Rexx
program. Command line programs can suppress the output window with the
parameter
RexxOutputWindow=NO. The plug-in area is still allocated on the
page but a multiline edit control is not created in that area for
displaying output. To make
the area blend into the background of the page
set the background color of the plug-in
area equal to the background color of the body of the HTML page, with
the
BGColor
parameter. The plug-in area can also be sized small to make it less
noticeable, but the size should not be less than 10 pixels for either
height or width, or the plug-in will not run on some browsers.
Plug-in Rexx Functions
Error Handling
query zersion command.
Control jumps to the BadJuju: label where the error
message is displayed by the
Manipulating Browser Windows
EMBED parameter. The browser window so specified should
already exist and be sized very small so that the user cannot see the
window. The best way to do this is to use frames, with
one
frame sized very small (.25 pixels high for example) used as the "work
window", and
the other frame sized to fill the rest of the window used as the main
display window. The example below shows how to do this.
<html>
<FRAMESET rows="*,.25" border=0 >
<FRAME NAME="cmd" SRC="plugin_cmdProcessor.html">
<FRAME NAME="workwincmd" SRC="javascript:'<html><body></body></html>'">
</FRAMESET>
</html>
The line
<FRAMESET rows="*,.25" border=0 >
creates vertical frameset with two frames, one above the other.
Each frame spans the entire width of the page. The rows="*,.25"
sizes the bottom frame .25 pixels high, and th top frame to occupy the
remaining area of the browser window. The line
<FRAME NAME="cmd" SRC="plugin_cmdProcessor.html">
loads the file plugin_cmdProcessor.html into the top frame and names
that frame/window cmd. The line
<FRAME NAME="workwincmd" SRC="javascript:'<html><body></body></html>'">
creates a blank document in the bottom frame/window and names that
frame/window <b>workwincmd</b>. The plugin_cmdProcessor.html file,
shown below, then sets the
<a href='plugindoc_embedParms.html#WORKWINDOWNAME'>WorkWindowName</a>
to <b>workwincmd</b> so that the plug-in will use the bottom frame
when creating and displaying HTML pages with JavaScript.
<html>
<head>
<body bgcolor='white'>
<br>
<h3>WD Plug-in Command Processor</h3>
<embed
type='x-warpdoctor/drrexx'
height=550
width=750
src='http://www.warpdoctor.org/plugin_CmdProcessor.res'
workwindowname=workwincmd
>
</embed>
</body>
<html>
Main Window with a Hidden Lower Work Window
Opening Windows
To specify an already open window as a target to the
CreatePage, GetURL, or PostURL commands you must know the name of the
window. The only way to know the name of the window is to create the
window in HTML using a FRAME tag, or with JavaScript using the
window.open() method. The commands
OpenWindow
andOpenURL
provide a
way to create a window and specify the name of the window, allowing
you to use that window as a target of other commands.
Closing Windows
EMBED parameter
AutoCloseWindow can be used to instruct the plug-in to close the
browser window,
load a different URL, or display a text message in the window when the
Rexx program is terminates. If
AutoCloseWindow
is set to YES the current window is closed when the Rexx
program terminates. If set to a URL the page in the current window is
replaced with the URL when the program terminates. If set to any other
value, the value is considered a text string and the page in the
current window is replaced with the text string. The text string can
include an argument to
specify a number of seconds to to leave the window open
before automatically closing the window. Some examples are shown
below.
autoCloseWindow="YES"
autoCloseWindow="http://www.warpdoctor.org/newPage.html"
autoCloseWindow="<p><p><p><center><h1>Done with Install"
autoCloseWindow="#10#<p><p><p><center><h1>Done with Install"
Downloading Files
GetURL
getUrl url [target] [NOWAIT | fileName]
GetFile
getfile url target
where url is an HTTP URL only, target is the name the
file will have on disk at the client.
EMBED parameter.)
The CGI program compresses the file using gzip and sends the
file with a Content-Encoding: gzip header. This notifies the
browser that the file contains binary data. With Opera and Mozilla
based browsers
the contents of the data stream (the file) are decompressed
automatically by the browser; for Netscape browsers the plug-in
decompresses the file before returning from the command.
Uploading Files
/* rexx ftp upload */
call wdParseArgs
rc = rxFuncAdd('FTPLoadFuncs','rxFtp','FtpLoadFuncs')
rc = FtpLoadFuncs()
rc = ftpsetuser('www.hometown.org','uploadUser','uploadPassword');
rc = ftpput("f:\temp\a.cmd",a.cmd,"BINARY");
exit
CopyFileToServer
The
syntax is.
CopyFileToServer url filename
MoveFileToServer
The syntax of the command is
MoveFileToServer url filename
Local File Operations
Installing WarpIN Archives
EMBED tag for the WarpIN
install file.
EMBED tag must specify a
Type=x-warpdoctor/warpin
or
Type=x-warpdoctor/generic
parameter. The x-warpdoctor/warpin MIME-Type is used for
*.WPI type WarpIN packages; the
x-warpdoctor/generic MIME-Type is used for *.EXE type
"self-contained" WarpIN install packages, i.e. where WarpIN
executable code is include in the install file so that it can be
installed on machines that do not already have WarpIN.
EMBED tag
SRC parameter must be a
URL that contains the *.WPI or *.EXE install file. It is
strongly advised to use a FTP URL for *.WPI files to insure
that the file is downloaded without being mangled. FTP also works well
for *.EXE type files, although those are downloaded reliably by
browsers using a HTTP URL.
EMBED parameters are recommended
for WarpIN installations, but not required:
<html>
<head>
<BODY bgcolor="white">
<br>
<h3>WarpIN Install Demo</h3>
<p><b>Do not close this window until the install is complete</b>
<br>
<embed
type='x-warpdoctor/warpin'
height=10
width=10
src='ftp://www.warpdoctor.org/wdRexxIn.wpi'
title='WarpIN Demo Install - Installs the Rexx Plug-in"
bgcolor='white'
eraseOnExit=YES
saveprompt=yes
autoCloseWindow=yes
runExclusive='ftp://www.warpdoctor.org/wdRexxIn.exe ftp://www.warpdoctor.org/wdRexxIn.wpi' >
</embed>
</body>
<html>
<html>
<script>
function openWin()
{
window.open('plugin_warpin1.html','instWin','outerheight=300,outerwidt h=500')
}
</script>
<body>
Click <a href="javascript:openWin()">here</a>
to install the Rexx Plug-in
</body>
</html>
EMBED tag for the self-contained version of the Rexx
Plug-in install file.
Detecting the Plug-in
EMBED tag for the
install package, because then users without the plug-in would not be
able to download the install file. If the web administrator does not
write the EMBED tag the plug-in will never get called.
The answer for is to include a little JavaScript routine that detects
the presence of the plug-in: if the plug-in is installed the page with
the EMBED tag is called, if the plug-in does not exist
the install file is simply downloaded. The example modifies our
previous example to include detection of the plug-in. If the plug-in
is detected (foundFlag=1) another window is opened that runs the
plug-in instance, If foundFlag=0 the file is simply downloaded using
FTP.
<html>
<script>
function openWin()
{
var numPlugins = navigator.plugins.length;
var foundFlag = 0
for (var i = 0; i < numPlugins; i++)
{
aa = navigator.plugins[i].filename.toUpperCase().split('\\');
if (aa[aa.length-1] == 'NPWRPDOC.DLL') foundFlag = 1
}
if (foundFlag==1) window.open('plugin_warpin1.html','instWin','outerheight=300,outerwidth=500')
else window.location.href='ftp://www.warpdoctor.org/wdRexxIn.wpi'
}
</script>
<body>
Click <a href="javascript:openWin()">here</a>
to install the Rexx Plug-in
</body>
</html>
Running Generic Executables
EMBED tag.
All three are executed by the plug-in in a separate session. The
difference between the three types of programs are the arguments
passed to the program when it is started by the plug-in, and actions
taken by the program to communicate with the plug-in.
EMBED tag.
EMBED tag parameter is passed as an argument in the form
of name=value. This allows the web developer to run any
executable program using the plug-in and to pass arguments to the
program by using parameters in the EMBED tag.
EMBED tag
EMBED parameters as long as the names are valid names.
pipeName x-desktop y-desktop width height x-window y-window
where
pipeName
Is the name of the "command" named pipe, the pipe used by the plug-in
Rexx function
wdCommand()
for communicating with the plug-in
x-desktop
The lower left position of the plug-in window relative to the desktop,
in pixels.
y-desktop
The lower left position of the plug-in window relative to the desktop,
in pixels.
width
The width of the plug-in window in pixels.
height
The height of the plug-in window in pixels.
x-window
The lower left position of the plug-in window relative to the
browser window containing the page that has the plug-in instance, in pixels.
y-window
The lower left position of the plug-in window relative to the
browser window containing the page that has the plug-in instance, in pixels.
Executing CGI Programs on the Server
Background
A CGI program is called when the user
<html>
<body>
<form method='POST' name='myform' action='cgi-bin/myProgram'>
<input type='text' name='input1'>
...
</form>
PostURL
Rexx and JavaScript
JavaScript to Rexx
FORM tag. JavaScript variables
are those that are defined within
<SCRIPT> </SCRIPT> tags, as shown below
<html>
<script>
var rundate
var tempStr = ''
</script>
<FORM> </FORM> tags, and would be called
window "controls" in OS/2 and Windows programming, or widgets in the
Unix world. The example below shows two HTML "fields":
birthdate and lastname. The field/input control
birthdate is visible on the screen, the field
lastname is invisible to the user.
<html>
<body>
<form>
Enter your birth date: <input type='text' name='birthdate'>
<input type='hidden' name='lastname' value='smith'>
</form>
</body>
</html>
Starting a New Rexx Program
EMBED tag and its parameters to an HTML page. (New
program here means a Rexx program that is not already running the
plug-in.) Parameters or values are passed to the Rexx program as
user defined parameters of the EMBED. When the page
is finished being created (written to) by JavaScript it is read by the
browser and the Rexx program specified in the
Type and
Src parameters is started.
EMBED
tag.
EMBED tag on a new page
can be somewhat complex, depending on where the values are coming from for
the parameters of the EMBED tag. The example below shows a
JavaScript function that creates an HTML page containing
an EMBED tag. The page is created in a
work window so it is essentially invisible.
The EMBED tag parameters come from HTML fields,
JavaScript variables and literal text.
function passValues()
{
parent.workWin.document.write("<html><body>")
parent.workWin.document.write("<embed")
parent.workWin.document.write(" type='x-warpdoctor/rexx'")
parent.workWin.document.write(" src='http://192.168.32.100/doThis.rex'")
parent.workWin.document.write(" libpath='",document.sform.libpathList[document.sform.libpathList.selectedIndex].text,"'")
parent.workWin.document.write(" path='",document.sform.pathList[document.sform.pathList.selectedIndex].text,"'")
parent.workWin.document.write(" width=",xwidth);
parent.workWin.document.write(" height=",xheight);
parent.workWin.document.write(" rexxOutputWindow=NO");
parent.workWin.document.write(" >")
parent.workWin.document.write("</embed></body></html>")
}
EMBED tag. The example below shows a very simple, one
field, HTML form and the JavaScript needed to use the
plugin_form2embed.html file, which appears in red.
<html>
<head>
</head>
<body>
<form name='form1'>
Mother's name: <input type='text' name='mom'>
<br>
<input type='button' value='Run Rexx' onClick='makeEmbed()'>
</form>
</body>
<script>
var type = 'x-warpdoctor/rexx'
var src = 'http://www.warpdoctor.org/plugin_form2rexx.rex'
var width = 400
var height = 600
var title='Test Form 2 Rexx'
function makeEmbed()
{
win = window.open("plugin_form2embed.html","win1")
}
</script>
</html>
EMBED. It
then looks for HTML "fields" in the form