home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 499.lha / Rxgen_v1.0 / rexx / wbmaster.rexx < prev   
OS/2 REXX Batch file  |  1991-04-08  |  10KB  |  235 lines

  1. /* This file is Copyright(C) 1990 Francois Rouaix and the Software Winery */
  2. /* This file must be distributed unmodified in the RXGEN package          */
  3.  
  4. /* An attempt at using the new features of the 2.0 Workbench library
  5.    Warning, look for comments /* WSHELL */ and /* CLI */ to fix the program
  6.    By default, the script in the distribution is configured for CLI, as
  7.    WShell is not yet distributed with 2.0 ;-)
  8.  
  9.     WSH> WBMASTER -INIT
  10.     WSH> WBMASTER <MENUNAME> <RXCLAUSE>
  11.      ....
  12.     Quit with menu
  13.  
  14.     CLI> rx WBMASTER -INIT
  15.     CLI> rx WBMASTER <MENUNAME> <RXCLAUSE>
  16.      ....
  17.     Quit with menu
  18.  
  19.     The -INIT call will init a "server process", which is called -RUN.
  20.     -RUN will add a QUIT item in the Workbench Tools menu.
  21.     The other kind of call will add an item of name <MENUNAME>. When you
  22.     activate this item, the <RXCLAUSE> will be INTERPRETed by the
  23.     server process.
  24.  
  25. Example:
  26.     rx wbmaster -INIT
  27.     rx wbmaster Editor address command 'new:c/az'
  28.     rx wbmaster Shell  address command 'newshell'
  29.  
  30. WARNING: despite some efforts, there are still problems
  31.     1) if the rxclause (executed when activating a menu) raises
  32.         an error, then you're lost. Try WBMASTER -QUIT to free
  33.         the ressources. However, don't try -QUIT option if -RUN is alive
  34.     2) you can't remove a menu item individually
  35.        but you can patch the action of a menu item by hacking directly
  36.        the clip value WBACTIONi (see source)
  37.     3) you'll have to figure out what king of actions may be taken !
  38.         Easy ones: ADDRESS COMMAND 'cli-detaching-command'
  39.         Easy ones: ADDRESS COMMAND 'run cli-permanent-command'
  40.             use the quotes to avoid syntax errors...
  41.         Try to interpret your clause with rx "INTERPRET <clause>"
  42.             to check before installing as a menu action
  43.         Tricky ones: parameterised actions, using Arexx clipboard as globals
  44.         Hacks: dynamic modification of the server Arexx program ....
  45.     4) I've not really checked if all memory/ressources are freed
  46.         if everything goes wrong
  47.     Remember this is just a hack !
  48. */
  49.  
  50. arg COM PAR
  51.  
  52. /* exec library */
  53. LIBRARIES.exec = '00 00 00 00'x
  54. LIBRARIES.exec.OPENCOUNT = 0
  55. LIBS.exec.FindPort='FE7A'x||S||'200A'x
  56. LIBS.exec.AddPort='FE9E'x||A||'200A'x
  57. LIBS.exec.RemPort='FE98'x||A||'200A'x
  58. LIBS.exec.PutMsg='FE92'x||AA||'20090A'x
  59. LIBS.exec.GetMsg='FE8C'x||A||'2009'x
  60. LIBS.exec.ReplyMsg='FE86'x||A||'200A'x
  61. LIBS.exec.WaitPort='FE80'x||A||'2009'x
  62. LIBS.exec.Wait='FEC2'x||A||'2001'x
  63. LIBS.exec.CreateMsgPort='FD66'x||'20'x
  64. LIBS.exec.DeleteMsgPort='FD60'x||A||'2009'x
  65. LIBS.exec.AllocMem='FF3A'x||IA||'200102'x
  66. LIBS.exec.FreeMem='FF2E'x||AI||'200A01'x
  67.  
  68. /* workbench library */
  69. LIBRARIES.workbench = '00 00 00 00'x
  70. LIBRARIES.workbench.OPENCOUNT = 0
  71. LIBS.workbench.AddAppMenuItem='FFB8'x||IAAA||'200102090A'x
  72. LIBS.workbench.RemoveAppMenuItem='FFB2'x||A||'2009'x
  73.  
  74. PORTNAME='WB-AREXX'
  75. PORTLEN = 9
  76.  
  77. select
  78.     when upper(arg(1)) = '-INIT' then do
  79. /* this is some kind CLI-detach hack for ARexx scripts */
  80. /* note the the MsgPort MUST be created by the task who is going
  81.     to receive the signals (that's because CreateMsgPort initializes
  82.     the port structure according to the caller's task)
  83.    Therefore we reload ourselves asynchronously (ickk) without doing anything
  84. */
  85.         call GenOpenLib("exec",36)
  86.         myport = GenACall("exec","FindPort",PORTNAME)
  87.         if myport = NULL() then
  88.                 /* ADDRESS command 'run rx WBMASTER -RUN' /* this gives IO */ */
  89.                 ADDRESS AREXX 'WBMASTER -RUN'
  90.         else say "WBMASTER already up and running"
  91.         call GenCloseLib("exec")
  92.         end /* end of -INIT */
  93.  
  94.     when upper(arg(1)) = '-RUN' then do
  95.         /* we shouldn't quit but by user control             */
  96.         /* it does not seem to make a difference, but why ?  */
  97.         signal off syntax
  98.         signal off error
  99.         call GenOpenLib("exec",36)
  100.         myport = GenACall("exec","FindPort",PORTNAME)
  101.         if myport = NULL() then do
  102.             myport = GenACall("exec","CreateMsgPort")
  103.             if myport = NULL() then do
  104.                                         say "Can't create port"
  105.                                         exit 1
  106.                                     end
  107.             else do
  108.             /* we MUST initialize the name and priority (RTFM) */
  109.                 copystr = GenACall("exec","AllocMem",PORTLEN,'0001 0001'x)
  110.                 call export(copystr,PORTNAME,PORTLEN)
  111.                 call export(OFFSET(myport,10),copystr,4)
  112.                 call export(OFFSET(myport,9),NULL(),1)
  113.                 call GenACall("exec","AddPort",myport)
  114.                 say "Port " PORTNAME " created"
  115.                 sigbitraw = import(OFFSET(myport,15),1)
  116.                 sigbit = c2d(sigbitraw)
  117.                 say "Signal Bit:" sigbit
  118.                 call setclip('WBINDEX',-1)
  119.                 /* setting quit item: magic ! */
  120.                 /* we add an item with no action, but it MUST be the first */
  121.                 /* there is a special case for this in the server process  */
  122.                 /* 'WBMASTER ' QUIT   /* for use with WSHELL ONLY */ */
  123.                 address command 'rx WBMASTER QUIT'  /* for use with CLI */
  124.                 end
  125.             end
  126.         else do
  127.             say "WBMASTER already up and running"
  128.             exit 1
  129.             end
  130.         do quitloop=0
  131.             msg = GenACall("exec","Wait",bitset(NULL(),sigbit))
  132.             do msgloop=0
  133.                 msg = GenACall("exec","GetMsg",myport)
  134.                 if msg = null() then leave msgloop
  135.                 am_Type     =  c2x(IMPORT(OFFSET(msg,20),2))
  136.                 am_UserData =  c2x(IMPORT(OFFSET(msg,22),4))
  137.                 am_ID       =  c2d(IMPORT(OFFSET(msg,26),4))
  138.                 am_NumArgs  =  c2d(IMPORT(OFFSET(msg,30),4))
  139.                 call GenACall("exec","ReplyMsg",msg)
  140.                 /* I don't know exactly where the output will go...
  141.                   at least if the trace console is open, output will go there
  142.                   in beta versions of 2.0, there used to be gurus, now with
  143.                   2.01, everything runs fine
  144.                 */
  145.                 say "Type:" am_Type  "UserData:" am_UserData "Id:" am_ID "NumArgs:" am_NumArgs
  146.                 if am_ID = 0 then leave quitloop
  147.                 action = getclip('WBACTION'||am_ID)
  148.                 say "Interpreting" action
  149.                 INTERPRET action  /* whoaaaaahhh */
  150.             end  /* of msgloop */
  151.         end /* of quit loop */
  152.         /* normal deallocation follows */
  153.         /* ADDRESS AREXX 'WBMASTER -QUIT' /* pb: ??? when -RUN was launched by addressing AREXX*/ */
  154.         ADDRESS COMMAND 'rx WBMASTER -QUIT'
  155.     end /* end of -RUN */
  156.  
  157.     /* this is the cleanup: this portion of the code should be executed
  158.        by the -RUN process when you quit, but in case something goes wrong,
  159.        we need a cleanup (DON'T RUN THIS IF -RUN IS ALIVE)
  160.     */
  161.     when upper(arg(1)) = '-QUIT' then do
  162.         call GenOpenLib("exec",36)
  163.         myport = GenACall("exec","FindPort",PORTNAME)
  164.         if myport = NULL() then do
  165.                             say "WBMASTER is not running"
  166.                             end
  167.         else do /* first delete the port*/
  168.             call GenACall("exec","RemPort",myport)
  169.             do msgloop=0
  170.                 msg = GenACall("exec","GetMsg",myport)
  171.                 if msg = NULL() then leave msgloop
  172.                 call GenACall("exec","ReplyMsg",msg)
  173.                 end
  174.             call GenACall("exec","FreeMem",IMPORT(OFFSET(myport,10),4),PORTLEN)
  175.             call GenACall("exec","DeleteMsgPort",myport)
  176.             end
  177.         /* cleanup the menu */
  178.         call GenOpenLib("workbench",36)
  179.         do i=0 to getclip('WBINDEX')
  180.             item = getclip('WBITEM'i)
  181.             call GenACall("workbench","RemoveAppMenuItem",item)
  182.             text = getclip('WBTEXT'i)
  183.             textlen = getclip('WBTEXTLEN'i)
  184.             call GenACall("exec","FreeMem",text,textlen)
  185.             end
  186.         call setclip('WBINDEX',-1) /* Avoid multiple FreeMems if run twice*/
  187.         call GenCloseLib("workbench")
  188.         call GenCloseLib("exec")
  189.         end
  190.  
  191.     /* general case: install the menu item */
  192.     otherwise do
  193.         call GenOpenLib("exec",36)
  194.         myport = GenACall("exec","FindPort",PORTNAME)
  195.         if myport = NULL() then do
  196.                                     say "Can't find " PORTNAME
  197.                                     call GenCloseLib("exec")
  198.                                     exit 1
  199.                                 end
  200.         call GenOpenLib("workbench",36)
  201.         index = getclip('WBINDEX')
  202.         index = index+1
  203.         call setclip('WBINDEX',index)
  204.         COM = strip(com)
  205.         par = strip(par)
  206.         /* allocate copy of the string */
  207.         copystr = GenACall("exec","AllocMem",length(COM)+1,'0001 0001'x)
  208.         call export(copystr,COM,length(COM)+1)
  209.  
  210.         item = GenACall("workbench","AddAppMenuItem",index,NULL(),copystr,myport)
  211.         if item = NULL() then do
  212.                                 say "Adding item failed"
  213.                                 exit 1
  214.                                end
  215.         call setclip('WBITEM'index,item)
  216.         call setclip('WBTEXT'index,copystr)
  217.         call setclip('WBTEXTLEN'index,length(COM)+1)
  218.         call setclip('WBACTION'index,PAR)
  219.         call GenCloseLib("workbench")
  220.         call GenCloseLib("exec")
  221.         end /* of otherwise */
  222. end /* of select */
  223. exit 0
  224.  
  225. /* Hm, we need some offsets.
  226. struct AppMessage {
  227.     struct Message am_Message;  /* standard message structure */
  228.     UWORD am_Type;              /* message type */
  229.     ULONG am_UserData;          /* application specific */
  230.     ULONG am_ID;                /* application definable ID */
  231.     LONG am_NumArgs;            /* # of elements in arglist */
  232.     struct WBArg *am_ArgList;   /* the arguements themselves */
  233. };
  234. */
  235.