home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
dirs
/
rxgen_459.lzh
/
Rxgen
/
rexx
/
wbmaster.rexx
< prev
Wrap
OS/2 REXX Batch file
|
1991-02-18
|
10KB
|
235 lines
/* This file is Copyright(C) 1990 Francois Rouaix and the Software Winery */
/* This file must be distributed unmodified in the RXGEN package */
/* An attempt at using the new features of the 2.0 Workbench library
Warning, look for comments /* WSHELL */ and /* CLI */ to fix the program
By default, the script in the distribution is configured for CLI, as
WShell is not yet distributed with 2.0 ;-)
WSH> WBMASTER -INIT
WSH> WBMASTER <MENUNAME> <RXCLAUSE>
....
Quit with menu
CLI> rx WBMASTER -INIT
CLI> rx WBMASTER <MENUNAME> <RXCLAUSE>
....
Quit with menu
The -INIT call will init a "server process", which is called -RUN.
-RUN will add a QUIT item in the Workbench Tools menu.
The other kind of call will add an item of name <MENUNAME>. When you
activate this item, the <RXCLAUSE> will be INTERPRETed by the
server process.
Example:
rx wbmaster -INIT
rx wbmaster Editor address command 'new:c/az'
rx wbmaster Shell address command 'newshell'
WARNING: despite some efforts, there are still problems
1) if the rxclause (executed when activating a menu) raises
an error, then you're lost. Try WBMASTER -QUIT to free
the ressources. However, don't try -QUIT option if -RUN is alive
2) you can't remove a menu item individually
but you can patch the action of a menu item by hacking directly
the clip value WBACTIONi (see source)
3) you'll have to figure out what king of actions may be taken !
Easy ones: ADDRESS COMMAND 'cli-detaching-command'
Easy ones: ADDRESS COMMAND 'run cli-permanent-command'
use the quotes to avoid syntax errors...
Try to interpret your clause with rx "INTERPRET <clause>"
to check before installing as a menu action
Tricky ones: parameterised actions, using Arexx clipboard as globals
Hacks: dynamic modification of the server Arexx program ....
4) I've not really checked if all memory/ressources are freed
if everything goes wrong
Remember this is just a hack !
*/
arg COM PAR
/* exec library */
LIBRARIES.exec = '00 00 00 00'x
LIBRARIES.exec.OPENCOUNT = 0
LIBS.exec.FindPort='FE7A'x||S||'200A'x
LIBS.exec.AddPort='FE9E'x||A||'200A'x
LIBS.exec.RemPort='FE98'x||A||'200A'x
LIBS.exec.PutMsg='FE92'x||AA||'20090A'x
LIBS.exec.GetMsg='FE8C'x||A||'2009'x
LIBS.exec.ReplyMsg='FE86'x||A||'200A'x
LIBS.exec.WaitPort='FE80'x||A||'2009'x
LIBS.exec.Wait='FEC2'x||A||'2001'x
LIBS.exec.CreateMsgPort='FD66'x||'20'x
LIBS.exec.DeleteMsgPort='FD60'x||A||'2009'x
LIBS.exec.AllocMem='FF3A'x||IA||'200102'x
LIBS.exec.FreeMem='FF2E'x||AI||'200A01'x
/* workbench library */
LIBRARIES.workbench = '00 00 00 00'x
LIBRARIES.workbench.OPENCOUNT = 0
LIBS.workbench.AddAppMenuItem='FFB8'x||IAAA||'200102090A'x
LIBS.workbench.RemoveAppMenuItem='FFB2'x||A||'2009'x
PORTNAME='WB-AREXX'
PORTLEN = 9
select
when upper(arg(1)) = '-INIT' then do
/* this is some kind CLI-detach hack for ARexx scripts */
/* note the the MsgPort MUST be created by the task who is going
to receive the signals (that's because CreateMsgPort initializes
the port structure according to the caller's task)
Therefore we reload ourselves asynchronously (ickk) without doing anything
*/
call GenOpenLib("exec",36)
myport = GenACall("exec","FindPort",PORTNAME)
if myport = NULL() then
/* ADDRESS command 'run rx WBMASTER -RUN' /* this gives IO */ */
ADDRESS AREXX 'WBMASTER -RUN'
else say "WBMASTER already up and running"
call GenCloseLib("exec")
end /* end of -INIT */
when upper(arg(1)) = '-RUN' then do
/* we shouldn't quit but by user control */
/* it does not seem to make a difference, but why ? */
signal off syntax
signal off error
call GenOpenLib("exec",36)
myport = GenACall("exec","FindPort",PORTNAME)
if myport = NULL() then do
myport = GenACall("exec","CreateMsgPort")
if myport = NULL() then do
say "Can't create port"
exit 1
end
else do
/* we MUST initialize the name and priority (RTFM) */
copystr = GenACall("exec","AllocMem",PORTLEN,'0001 0001'x)
call export(copystr,PORTNAME,PORTLEN)
call export(OFFSET(myport,10),copystr,4)
call export(OFFSET(myport,9),NULL(),1)
call GenACall("exec","AddPort",myport)
say "Port " PORTNAME " created"
sigbitraw = import(OFFSET(myport,15),1)
sigbit = c2d(sigbitraw)
say "Signal Bit:" sigbit
call setclip('WBINDEX',-1)
/* setting quit item: magic ! */
/* we add an item with no action, but it MUST be the first */
/* there is a special case for this in the server process */
/* 'WBMASTER ' QUIT /* for use with WSHELL ONLY */ */
address command 'rx WBMASTER QUIT' /* for use with CLI */
end
end
else do
say "WBMASTER already up and running"
exit 1
end
do quitloop=0
msg = GenACall("exec","Wait",bitset(NULL(),sigbit))
do msgloop=0
msg = GenACall("exec","GetMsg",myport)
if msg = null() then leave msgloop
am_Type = c2x(IMPORT(OFFSET(msg,20),2))
am_UserData = c2x(IMPORT(OFFSET(msg,22),4))
am_ID = c2d(IMPORT(OFFSET(msg,26),4))
am_NumArgs = c2d(IMPORT(OFFSET(msg,30),4))
call GenACall("exec","ReplyMsg",msg)
/* I don't know exactly where the output will go...
at least if the trace console is open, output will go there
in beta versions of 2.0, there used to be gurus, now with
2.01, everything runs fine
*/
say "Type:" am_Type "UserData:" am_UserData "Id:" am_ID "NumArgs:" am_NumArgs
if am_ID = 0 then leave quitloop
action = getclip('WBACTION'||am_ID)
say "Interpreting" action
INTERPRET action /* whoaaaaahhh */
end /* of msgloop */
end /* of quit loop */
/* normal deallocation follows */
/* ADDRESS AREXX 'WBMASTER -QUIT' /* pb: ??? when -RUN was launched by addressing AREXX*/ */
ADDRESS COMMAND 'rx WBMASTER -QUIT'
end /* end of -RUN */
/* this is the cleanup: this portion of the code should be executed
by the -RUN process when you quit, but in case something goes wrong,
we need a cleanup (DON'T RUN THIS IF -RUN IS ALIVE)
*/
when upper(arg(1)) = '-QUIT' then do
call GenOpenLib("exec",36)
myport = GenACall("exec","FindPort",PORTNAME)
if myport = NULL() then do
say "WBMASTER is not running"
end
else do /* first delete the port*/
call GenACall("exec","RemPort",myport)
do msgloop=0
msg = GenACall("exec","GetMsg",myport)
if msg = NULL() then leave msgloop
call GenACall("exec","ReplyMsg",msg)
end
call GenACall("exec","FreeMem",IMPORT(OFFSET(myport,10),4),PORTLEN)
call GenACall("exec","DeleteMsgPort",myport)
end
/* cleanup the menu */
call GenOpenLib("workbench",36)
do i=0 to getclip('WBINDEX')
item = getclip('WBITEM'i)
call GenACall("workbench","RemoveAppMenuItem",item)
text = getclip('WBTEXT'i)
textlen = getclip('WBTEXTLEN'i)
call GenACall("exec","FreeMem",text,textlen)
end
call setclip('WBINDEX',-1) /* Avoid multiple FreeMems if run twice*/
call GenCloseLib("workbench")
call GenCloseLib("exec")
end
/* general case: install the menu item */
otherwise do
call GenOpenLib("exec",36)
myport = GenACall("exec","FindPort",PORTNAME)
if myport = NULL() then do
say "Can't find " PORTNAME
call GenCloseLib("exec")
exit 1
end
call GenOpenLib("workbench",36)
index = getclip('WBINDEX')
index = index+1
call setclip('WBINDEX',index)
COM = strip(com)
par = strip(par)
/* allocate copy of the string */
copystr = GenACall("exec","AllocMem",length(COM)+1,'0001 0001'x)
call export(copystr,COM,length(COM)+1)
item = GenACall("workbench","AddAppMenuItem",index,NULL(),copystr,myport)
if item = NULL() then do
say "Adding item failed"
exit 1
end
call setclip('WBITEM'index,item)
call setclip('WBTEXT'index,copystr)
call setclip('WBTEXTLEN'index,length(COM)+1)
call setclip('WBACTION'index,PAR)
call GenCloseLib("workbench")
call GenCloseLib("exec")
end /* of otherwise */
end /* of select */
exit 0
/* Hm, we need some offsets.
struct AppMessage {
struct Message am_Message; /* standard message structure */
UWORD am_Type; /* message type */
ULONG am_UserData; /* application specific */
ULONG am_ID; /* application definable ID */
LONG am_NumArgs; /* # of elements in arglist */
struct WBArg *am_ArgList; /* the arguements themselves */
};
*/