home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / applications / xlispstat / src / src1.lzh / Amiga / amistuff.c < prev    next >
C/C++ Source or Header  |  1990-10-11  |  18KB  |  595 lines

  1. /* AmiStuff.c - Amiga specific routines                                */
  2. /* Copyright (c) 1990 by J.K. Lindsey                                  */
  3. /* Additions to XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney     */
  4. /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz    */
  5. /* You may give out copies of this software; for conditions see the    */
  6. /* file COPYING included with this distribution.                       */
  7.  
  8. #include <proto/exec.h>
  9. #include <proto/dos.h>
  10. #include <proto/intuition.h>
  11. #include <proto/graphics.h>
  12. #include <graphics/gfxbase.h>
  13. #include <graphics/display.h>
  14. #include <libraries/dosextens.h>
  15. #include <rexx/rxslib.h>
  16. #include <rexx/simplerexx.h>
  17. #include <math.h>
  18. #include <time.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include "autil2.h"
  22. #include "version.h"
  23. #include "xlisp.h"
  24. #include "osdef.h"
  25. #include "xlproto.h"
  26. #include "xlsproto.h"
  27. #include "iviewproto.h"
  28. #include "Stproto.h"
  29. #include "osproto.h"
  30. #include "xlvar.h"
  31. #include "xlsvar.h"
  32. #define extern
  33. #include "amivar.h"
  34. #undef extern
  35.  
  36. /* input buffer allows about 20 lines of text from ARexx */
  37. #define LBSIZE 1600
  38.  
  39. char deftool[100]="";
  40.  
  41. /* line buffer variables */
  42. static char lbuf[LBSIZE];
  43. static char rexxerror[]="Commands truncated (too large for buffer).";
  44. static int  lpos[LBSIZE],lindex,lcount,lposition,start_time,numparen=0;
  45.  
  46. static struct FileHandle *fh=0;
  47. static struct IOStdReq *OutConWM,*OutConRM;
  48. static struct MsgPort *wport,*rport;
  49. static struct BitMap bm,bm1,bm2;
  50. static struct TextAttr StdFont={
  51.    "topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT};
  52. static short hch,wch;
  53. static unsigned long rportsig,rexxsig;
  54. static unsigned short colormap[]={
  55.    RWHITE,RBLACK,RRED,RGREEN,RBLUE,RCYAN,RMAGENTA,RYELLOW,RBLUE,RGREEN,
  56.    RRED,RYELLOW,RMAGENTA,RCYAN,RWHITE,RBLACK};
  57. static char ch;
  58. static AREXXCONTEXT RexxStuff;
  59.  
  60. /* forward declarations */
  61. void xputc(int),xflush(void);
  62. int xgetc(void),xcheck(void),dokeys(void),dorexx(void),
  63.     DeadKeyConvert(unsigned short,unsigned short,char **,char *,int);
  64. LVAL get_menu_by_id(int);
  65.  
  66. /* disable Lattice ctrl-C */
  67. int CXBRK(void){return(0);}
  68. int chkabort(void){return(0);}
  69.  
  70. /* osinit - initialize */
  71. void osinit(char *banner){
  72.    struct NewScreen ns;
  73.    struct NewWindow nw;
  74.    struct RastPort *orp;
  75.    unsigned long clock[2];
  76.    char buffer[80],*b;
  77.    int i;
  78.    timer(clock);
  79.    start_time=clock[0];
  80.  
  81.    /* open custom screen */
  82.    screen=0;
  83.    screentype=CUSTOMSCREEN;
  84.    OutConWM=OutConRM=0;
  85.    rport=wport=0;
  86.    if(openlibs())xlfatal("cannot open libraries");
  87.    screenw=GfxBase->NormalDisplayColumns;
  88.    screenh=2*GfxBase->NormalDisplayRows;
  89.    ns.LeftEdge=0;
  90.    ns.TopEdge=0;
  91.    ns.Width=screenw;
  92.    ns.Height=screenh;
  93.    ns.Depth=PLANES;
  94.    ns.DetailPen=WHITE;
  95.    ns.BlockPen=BLACK;
  96.    ns.ViewModes=HIRES|INTERLACE;
  97.    ns.Type=screentype;
  98.    ns.Font=&StdFont;
  99.    ns.DefaultTitle="Xlisp-Stat by Luke Tierney";
  100.    ns.Gadgets=0;
  101.    ns.CustomBitMap=0;
  102.    if(!(screen=OpenScreen(&ns)))xlfatal("cannot open xlisp screen");
  103.    LoadRGB4(&screen->ViewPort,colormap,16);
  104.  
  105.    /* open backdrop window */
  106.    nw.LeftEdge=0;
  107.    nw.TopEdge=11;
  108.    nw.Width=screenw;
  109.    nw.Height=screenh-11;
  110.    nw.DetailPen=WHITE;
  111.    nw.BlockPen=BLACK;
  112.    nw.IDCMPFlags=GADGETUP|MENUPICK;
  113.    nw.Flags=SMART_REFRESH|ACTIVATE|BACKDROP|BORDERLESS|NOCAREREFRESH;
  114.    nw.FirstGadget=0;
  115.    nw.CheckMark=0;
  116.    nw.Title=0;
  117.    nw.Screen=screen;
  118.    nw.BitMap=0;
  119.    nw.MinWidth=100;
  120.    nw.MinHeight=50;
  121.    nw.MaxWidth=0;
  122.    nw.MaxHeight=0;
  123.    nw.Type=screentype;
  124.    if(!(window=OpenWindow(&nw)))xlfatal("cannot open xlisp window");
  125.    screen->FirstWindow->UserData=0;
  126.    
  127.    /* initialize double buffering raster */
  128.    orp=screen->FirstWindow->RPort;
  129.    dbsize=screenh>screenw?screenh:screenw;
  130.    InitBitMap(&bm,PLANES,dbsize,dbsize);
  131.    for(i=0;i<PLANES;i++){
  132.       if(!(bm.Planes[i]=(PLANEPTR)AllocRaster(dbsize,dbsize)))xlfatal("raster allocation failed");}
  133.    InitRastPort(&dbrp);
  134.    dbrp.BitMap=&bm;
  135.    dbrp.Font=orp->Font;
  136.    dbrp.TxFlags=orp->TxFlags;
  137.    dbrp.TxHeight=orp->TxHeight;
  138.    dbrp.TxWidth=orp->TxWidth;
  139.    dbrp.TxBaseline=orp->TxBaseline;
  140.    dbrp.TxSpacing=orp->TxSpacing;
  141.    dbflag=0;
  142.  
  143.    /* initialize rasters for writing vertical text */
  144.    wch=16;
  145.    hch=16;
  146.    InitBitMap(&bm1,PLANES,wch,hch);
  147.    InitBitMap(&bm2,PLANES,hch,wch);
  148.    for(i=0;i<PLANES;i++){
  149.       if(!(bm1.Planes[i]=(PLANEPTR)AllocRaster(wch,hch)))xlfatal("raster allocation failed");
  150.       if(!(bm2.Planes[i]=(PLANEPTR)AllocRaster(hch,wch)))xlfatal("raster allocation failed");}
  151.    InitRastPort(&rp1);
  152.    InitRastPort(&rp2);
  153.    rp1.BitMap=&bm1;
  154.    rp2.BitMap=&bm2;
  155.    rp1.Font=orp->Font;
  156.    rp1.TxFlags=orp->TxFlags;
  157.    rp1.TxHeight=hch;
  158.    rp1.TxWidth=wch;
  159.    rp1.TxBaseline=orp->TxBaseline;
  160.    rp1.TxSpacing=orp->TxSpacing;
  161.  
  162.    RexxStuff=InitARexx("XLisp",0);
  163.    rexxsig=ARexxSignal(RexxStuff);
  164.    if(OpenConsole(&OutConWM,&OutConRM,&wport,&rport,0,0,screen->FirstWindow))xlfatal("cannot open console");
  165.    rportsig=1<<rport->mp_SigBit;
  166.    QueueRead(OutConRM,&ch);
  167.    while(*banner!='\000')xputc(*banner++);
  168.    xputc('\n');
  169.    sprintf(buffer, "XLISP-STAT version %s, Copyright (c) 1989, by Luke Tierney.",
  170.    XLISPSTAT_VERSION);
  171.    b=buffer;
  172.    while(*b!='\000')xputc(*b++);
  173.    xputc('\n');
  174.    strcpy(buffer,"Several files will be loaded; this may take a few minutes.");
  175.    b=buffer;
  176.    while(*b!='\000')xputc(*b++);
  177.    xputc('\n');
  178.    xputc('\n');
  179.    lposition=lindex=lcount=0;
  180.    Menu_Ptr=0;}
  181.  
  182. void osfinish (void){
  183.    struct Window *l,*ll;
  184.    int i;
  185.    if(fh&&fh!=(struct FileHandle *)Output())Close((BPTR)fh);
  186.    for(i=0;i<PLANES;i++){
  187.       FreeRaster(bm.Planes[i],dbsize,dbsize);
  188.       FreeRaster(bm1.Planes[i],wch,hch);
  189.       FreeRaster(bm2.Planes[i],hch,wch);}
  190.    FreeARexx(RexxStuff);
  191.    if(OutConWM)DelConsole(OutConWM,OutConRM,wport,rport);
  192.    l=screen->FirstWindow;
  193.    while(ll=l){
  194.       l=l->NextWindow;
  195.       if(ll!=window)StGWRemove((StGWWinInfo *)ll->UserData);}
  196.    ClearMenuStrip(screen->FirstWindow);
  197.    CloseWindow(screen->FirstWindow);
  198.    if(screen)CloseScreen(screen);
  199.    closelibs();}
  200.  
  201. /* osrand - return a random number between 0 and n-1 */
  202. int osrand(unsigned n){
  203.    return((int)(rand()%n));}
  204.  
  205.  
  206. /* oscheck - check for control characters during execution */
  207. void oscheck(void){
  208.    int ch;
  209.    if(ch=xcheck())switch (ch) {
  210.       case '\002': osflush(); xlbreak("BREAK",s_unbound); break;
  211.       case '\004': osflush(); xltoplevel();               break;}}
  212.  
  213. /* osflush - flush the input line buffer */
  214. void osflush(void){
  215.    lindex=lcount=0;}
  216.  
  217. /* xgetc - get a character from the terminal without echo */
  218. static int xgetc(void){
  219.    register temp;
  220.    struct IOStdReq *readreq;
  221.    if(!(readreq=(struct IOStdReq *)GetMsg(rport)))return(-1);
  222.    temp=ch;
  223.    QueueRead(readreq,&ch);
  224.    return(temp&0xFF);}
  225.  
  226. /* xputc - put a character to the terminal */
  227. static void xputc(int ch){
  228.    char chout;
  229.    chout=ch;
  230.    ConsoleWrite(OutConWM,&chout,1);}
  231.  
  232. /* xcheck - check for a character */
  233. static int xcheck(void){
  234.    int c;
  235.    if((c=ConsoleMayRead(rport,&ch))==-1)return(0);
  236.    return (c&0xFF);}
  237.  
  238. /* osclose - close a file */
  239. int osclose(FILE *fp){
  240.    return (fclose(fp));}
  241.  
  242. /* ostputc - put a character to the terminal */
  243. int ostputc(int ch){
  244.    /* check for control characters */
  245.    oscheck();
  246.  
  247.    /* output the character */
  248.    if(ch=='\n') {
  249.       xputc('\r');
  250.       xputc('\n');
  251.       lposition=0;}
  252.    else {
  253.       xputc(ch);
  254.       lposition++;}
  255.  
  256.    /* output the character to the transcript file */
  257.    if(tfp)osaputc(ch,tfp);
  258.    return(0);}
  259.  
  260. /* ostgetc - get a character from the terminal */
  261. int ostgetc(void){
  262.    struct IntuiMessage *message;
  263.    struct MenuItem *item;
  264.    struct Window *w;
  265.    struct Gadget *address;
  266.    StGWWinInfo *gwinfo;
  267.    int mn,in,active;
  268. #ifdef RMOUSE
  269.    int x,y;
  270. #endif RMOUSE
  271.    unsigned long wsig,signal,class,iflags;
  272.    unsigned short code,qualifier;
  273.  
  274.    /* check for a buffered character */
  275.    if(lcount--){
  276. /*printf("lcount=%d lindex=%d %c\n",lcount,lindex,lbuf[lindex]);*/
  277.         return((int)lbuf[lindex++]);}
  278.  
  279.    /* get an input event */
  280.    for(message=0,lcount=0;;){
  281. /*printf("\nready for event\n");*/
  282.       for(active=0;;){  /* not friendly to other tasks, but I haven't found */
  283.          if(window->Flags&WINDOWACTIVE)break;       /* another way to do it */
  284.          w=screen->FirstWindow;
  285.          while(w){
  286.             if(!(gwinfo=(StGWWinInfo *)w->UserData)){
  287.                w=w->NextWindow;
  288.                continue;}
  289.             if(w->Flags&WINDOWACTIVE&&!dialog_p(gwinfo->Object)){
  290.                active=1;
  291.                ami_do_cursor(gwinfo);
  292.                for(;;){
  293. #ifdef RMOUSE
  294.                   StGWObDoIdle(gwinfo->Object);
  295. #else
  296.                   idle_action(gwinfo);
  297. #endif RMOUSE
  298.                   if(message=(struct IntuiMessage *)GetMsg(w->UserPort))goto S1;}}
  299.             else if(dialog_p(gwinfo->Object)&&(message=(struct IntuiMessage *)GetMsg(w->UserPort)))goto S1;
  300.             w=w->NextWindow;}
  301.          if(!active)break;}
  302. S1:   if(!message){
  303.          w=screen->FirstWindow; /* must be inside loop in case   */
  304.          wsig=0;                /* windows are created or closed */
  305.          while(w){
  306.             wsig|=1<<w->UserPort->mp_SigBit;
  307.             w=w->NextWindow;}
  308.          signal=Wait(rexxsig|rportsig|wsig);
  309. /*printf("message received\n");*/
  310.          if(signal&rportsig){
  311.             if((in=dokeys())!=-1&&in!=-2)return(in);}
  312.          else if((signal&rexxsig)&&(in=dorexx()))return(in);
  313.          else if(signal&wsig){
  314.             w=screen->FirstWindow;
  315.             while(w){
  316.                if(signal&(1<<w->UserPort->mp_SigBit))break;
  317.                w=w->NextWindow;}}}
  318.       if(message||signal&wsig)for(;;){
  319.          if(!message)message=(struct IntuiMessage *)GetMsg(w->UserPort);
  320.          if(message){
  321. #ifdef RMOUSE
  322.             ReportMouse(w,0);
  323. #endif RMOUSE
  324.             class=message->Class;
  325.             code=message->Code;
  326.             address=(struct Gadget *)message->IAddress;
  327.             qualifier=message->Qualifier;
  328. #ifdef RMOUSE
  329.             x=message->MouseX;
  330.             y=message->MouseY;
  331. #endif RMOUSE
  332.             ReplyMsg((struct Message *)message);
  333.             message=0;
  334.             if((w!=window)&&!(gwinfo=(StGWWinInfo *)w->UserData))continue;
  335.             iflags=w->IDCMPFlags;
  336.             switch(class){
  337. #ifdef RMOUSE
  338.                case MOUSEMOVE: {
  339.                   StGWObDoMouse(gwinfo->Object,x-w->BorderLeft,y-w->BorderTop,MouseMove,0);
  340.                   break;}
  341. #endif RMOUSE
  342.                case INACTIVEWINDOW:
  343.                case ACTIVEWINDOW: {
  344.                   send_message_1L(gwinfo->Object,sk_activate,class==ACTIVEWINDOW?s_true:0);
  345.                   break;}
  346.                case VANILLAKEY: {
  347.                   key_action(gwinfo,(char)code,qualifier);
  348.                   break;}
  349.                case GADGETDOWN:
  350.                case GADGETUP: {
  351.                   if(dialog_p(gwinfo->Object)){
  352.                      Dodo(w,0);
  353.                      doDialog(address->GadgetID,w);
  354.                      Dodo(w,iflags);}
  355.                   else if(gwinfo->hasVscroll||gwinfo->hasHscroll){
  356.                      scroll_action(gwinfo,address->GadgetID);}
  357.                   break;}
  358.                case MOUSEBUTTONS: {
  359.                   if(code==SELECTDOWN&&!dialog_p(gwinfo->Object))mouse_action(gwinfo,qualifier);
  360.                   break;}
  361.                case CLOSEWINDOW: {
  362.                   if(dialog_p(gwinfo->Object))DialogRemove(GetDialogObject(w));
  363.                   else send_message(gwinfo->Object,sk_close);
  364.                   break;}
  365.                case NEWSIZE: {
  366.                   Dodo(w,0);
  367.                   send_message_1L(gwinfo->Object,sk_update,s_true);
  368.                   Dodo(w,iflags);
  369.                   break;}
  370.                case MENUPICK: {
  371.                   while(code!=MENUNULL){
  372.                      item=ItemAddress(mymenu,code);
  373.                      mn=MENUNUM(code);
  374.                      in=ITEMNUM(code);
  375.                      code=item->NextSelect;
  376.                      send_message1(get_menu_by_id(mn),sk_select,in+1);}
  377.                   break;}}}
  378.          else break;
  379.          if(class==CLOSEWINDOW||class==MENUPICK)break;}
  380. #ifdef RMOUSE
  381.       ReportMouse(w,1);
  382. #endif RMOUSE
  383.       }}
  384.  
  385. /* xflush - flush the input line buffer */
  386. static void xflush(void){
  387.    ostputc('\n');
  388.    osflush();}
  389.  
  390. /* osaopen - open an ascii file */
  391. #include "icon.h"
  392. void wfile(char *fname){
  393.    static struct IntuiText ptext={0,1,JAM2,5,3,&StdFont,"OK",0},
  394.    ntext={0,1,JAM2,5,3,&StdFont,"CANCEL",0},
  395.    btext={0,1,JAM2,5,15,&StdFont,"File exists! OverWrite?",0};
  396.    BPTR lock;
  397.    if(lock=Lock(fname,ACCESS_WRITE)){
  398.       UnLock(lock);
  399.       if(!AutoRequest(window,&btext,&ptext,&ntext,0,0,215,70))xlfail("file open cancelled");}
  400.    MakeIcon(icon,80,42,deftool,fname,20000);}
  401.    
  402. FILE *osaopen(char *name,char *mode){
  403.    char buffer[120],*m;
  404.    strcpy(buffer,name);
  405.    if(mode[0]=='w'){
  406.       if(stcpm(buffer,".lsp",&m)!=4)strcat(buffer,".lsp");
  407.       wfile(buffer);}
  408.    return(fopen(buffer,mode));}
  409.  
  410. /* oserror - print an error message */
  411. void oserror(char *msg){
  412.    printf("error: %s\n",msg);}
  413.  
  414. /* xsystem - the built-in function 'system' */
  415. LVAL xsystem(void){
  416.    char *str;
  417.    int result;
  418.  
  419.    /* get the command string */
  420.    str=getstring(xlgastring());
  421.    xllastarg();
  422.    if(!fh&&!(fh=(struct FileHandle *)Output())&&
  423.    !(fh=(struct FileHandle *)Open("CON:0/10/640/100/XLisp CLI",MODE_NEWFILE)))
  424.    xlfail("unable to open CLI");
  425.    result=Execute(str,0,(BPTR)fh);
  426.    return(cvfixnum((FIXTYPE)result));}
  427.  
  428. /* xarexx - the built-in function 'arexx' */
  429. LVAL xarexx(void){
  430.    char *str;
  431.    int result;
  432.  
  433.    /* get the command string */
  434.    str=getstring(xlgastring());
  435.    xllastarg();
  436.    if(!RexxStuff)xlfail("no AREXX port");
  437.    result=SendARexxMsg(RexxStuff,str,0);
  438.    return(cvfixnum((FIXTYPE)result));}
  439.  
  440. /* osagetc - get a character from an ascii file */
  441. int osagetc(FILE *fp){
  442.    return(getc(fp));}
  443.  
  444. /* osaputc - put a character to an ascii file */
  445. int osaputc(int ch,FILE *fp){
  446.    return(putc(ch,fp));}
  447.  
  448. /* ossymbols - lookup important symbols */
  449. void ossymbols(void){
  450.    statsymbols();}
  451.  
  452. unsigned long run_tick_count(void){
  453.    unsigned int clock[2];
  454.    timer(clock);
  455.    return((unsigned long)(6e-5*(1e6*(clock[0]-start_time)+clock[1])));}
  456.  
  457. #ifndef HZ
  458. #define HZ 60
  459. #endif
  460.  
  461. unsigned long real_tick_count(void){
  462.    return((unsigned long)(HZ*(time((unsigned long *)NULL)-time_stamp)));}
  463.  
  464. unsigned long ticks_per_second(void){
  465.    return((unsigned long)HZ);}
  466.  
  467. void SysBeep(int n){
  468.    DisplayBeep(0);}
  469.  
  470. void bzero(char *p,int n){
  471.    while(n-->0)*p++=0;}
  472.  
  473. void osfinit(void){
  474.    statfinit();}
  475.  
  476. void osreset(void){
  477.    }
  478.  
  479. FILE *osbopen(char *name,char *mode){
  480.    char nmode[4];
  481.    strcpy(nmode,mode);
  482.    strcat(nmode,"b");
  483.    return(fopen(name,nmode));}
  484.  
  485. int osbgetc(FILE *fp){
  486.     return(getc(fp));}
  487.  
  488. int osbputc(int ch,FILE *fp){
  489.     return(putc(ch,fp));}
  490.  
  491. extern unsigned short bag[];
  492. void set_gc_cursor(int on){
  493.    struct Window *w;
  494.    w=screen->FirstWindow;
  495.    while(w){
  496.       if(w->Flags&WINDOWACTIVE)break;
  497.       w=w->NextWindow;}
  498.    if(w){
  499.       if(on){
  500.          SetPointer(w,bag,16,16,-2,-1);}
  501.       else {
  502.          if(w==window)SetPointer(w,0,0,0,0,0);
  503.          else ami_do_cursor((StGWWinInfo *)*w->UserData);}}}
  504.  
  505. /* find lisp menu with a specified Amiga ID */
  506. static LVAL get_menu_by_id(int m){
  507.    struct SuperMenu *this;
  508.    int i;
  509.    this=Menu_Ptr;
  510.    i=0;
  511.    while(this&&i!=m){
  512.       i++;
  513.       this=this->Next;}
  514.    if(!this)xlfail("menu not found");
  515.    return(get_menu_by_hardware((IVIEW_MENU)this));}
  516.  
  517. static int dokeys(void){
  518.    int ch,i;
  519.    if((ch=xgetc())!=-1)switch(ch){
  520.       case '\r': {
  521.          lbuf[lcount]='\n';
  522.          xputc('\r');
  523.          xputc('\n');
  524.          lposition=0;
  525.          if(tfp)for(lindex=0;lindex<lcount+1;lindex++)osaputc(lbuf[lindex],tfp);
  526.          lindex=1;
  527.          return((int)lbuf[0]);}
  528.       case '\010':
  529.       case '\177': {
  530.          if(lcount){
  531.             lcount--;
  532.             while(lposition>lpos[lcount]){
  533.                xputc('\010');
  534.                xputc(' ');
  535.                xputc('\010');
  536.                lposition--;}}
  537.          return(-2);}
  538.       default: {
  539.          if(ch=='(')numparen++;
  540.          else if(ch==')'&&numparen>0)numparen--;
  541.          if(ch=='\t'||(ch>=0x20&&ch<0x7F)){
  542.             lbuf[lcount]=ch;
  543.             lpos[lcount]=lposition;
  544.             if(ch=='\t'){
  545.                if(!lposition)for(i=0;i<3*numparen;lposition++,i++)xputc(' ');
  546.                else do {
  547.                   xputc(' ');}
  548.                while(++lposition&7);}
  549.             else {
  550.                xputc(ch);
  551.                lposition++;}
  552.             lcount++;
  553.             return(-2);}
  554.          else {
  555.             numparen=0;
  556.             xflush();
  557.             switch (ch) {
  558.                case '\003': xltoplevel();  /*  control-c */
  559.                case '\007': xlcleanup();   /*  control-g */
  560.                case '\020': xlcontinue();  /*  control-p */
  561.                case '\032': return(EOF);   /*  control-z */
  562.                default:     return(-2);}}}}
  563.    else return(ch);}
  564.  
  565. static int dorexx(void){
  566.    struct RexxMsg *rmsg;
  567.    char *nc,*error=0;
  568.    int errlevel=0;
  569.    if(rmsg=GetARexxMsg(RexxStuff)){
  570.       if(strlen(ARG0(rmsg))>LBSIZE){
  571.          errlevel=5;
  572.          error=rexxerror;}
  573.       lcount=stccpy(lbuf,ARG0(rmsg),LBSIZE)-1;
  574.       if(error)SetARexxLastError(RexxStuff,rmsg,error);
  575.       ReplyARexxMsg(RexxStuff,rmsg,0,errlevel);
  576.       nc=lbuf;
  577.       while(*nc)xputc(*nc++);
  578.       xputc('\r');
  579.       xputc('\n');
  580.       lposition=0;
  581.       lbuf[lcount]='\n';
  582.       if(tfp)for(lindex=0;lindex<lcount+1;lindex++)osaputc(lbuf[lindex],tfp);
  583.       lindex=1;
  584.       return((int)lbuf[0]);}
  585.    else return(0);}
  586.  
  587. extern unsigned short snooze[];
  588. void Dodo(struct Window *w,unsigned long iflags){
  589.    if(iflags){
  590.       ClearPointer(w);
  591.       ModifyIDCMP(w,iflags);}
  592.    else {
  593.       ModifyIDCMP(w,0);
  594.       SetPointer(w,snooze,22,16,-7,-8);}}
  595.