home *** CD-ROM | disk | FTP | other *** search
- /* 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 */
- };
- */
-