/* AmiIviewWindow3.c - Low Level Window Objects for Amiga              */
/* Copyright (c) 1990 by J.K. Lindsey                                  */
/* Additions to XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney     */
/* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz    */
/* You may give out copies of this software; for conditions see the    */
/* file COPYING included with this distribution.                       */

#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <graphics/gfxmacros.h>
#include <exec/memory.h>
#include <string.h>
#include <stdlib.h>
#include "autil2.h"
#include "plot2.h"
#include "xlisp.h"
#include "osdef.h"
#include "xlproto.h"
#include "xlsproto.h"
#include "Stproto.h"
#include "osproto.h"
#include "amivar.h"
#include "xlsvar.h"

/* forward declarations */
void draw_bitmap(StGWWinInfo *,int,int,int,int,char *,int);

/**************************************************************************/
/**                                                                      **/
/**                       Utility Function                               **/
/**                                                                      **/
/**************************************************************************/

static int dbmove(StGWWinInfo *gwinfo,int *x,int *y){
/*printf("left=%d top=%d width=%d height=%d\n",gwinfo->clip_rect.left,gwinfo->clip_rect.top,
gwinfo->clip_rect.width,gwinfo->clip_rect.height);*/
   if(/*!gwinfo->clipped&&*/(*x<0||*y<0||*x>gwinfo->canvasWidth||*y>gwinfo->canvasHeight))return(1);
   else if(!dbflag&&gwinfo->clipped&&(*x<gwinfo->clip_rect.left||*y<gwinfo->clip_rect.top||
   *x>gwinfo->clip_rect.left+gwinfo->clip_rect.width||
   *y>gwinfo->clip_rect.top+gwinfo->clip_rect.height))return(1);
   else if(!dbflag){
      rp=gwinfo->window->RPort; /* necessary for linked windows */
      *x+=gwinfo->window->BorderLeft;
      *y+=gwinfo->window->BorderTop;}
   return(0);}

void scroll_clip(StGWWinInfo *gwinfo,int *x,int *y){
   int width,height;
   StGWGetViewRect(gwinfo,0,0,&width,&height);
   if(gwinfo->hasVscroll&&height<gwinfo->canvasHeight){
      (*y)+=(gwinfo->view_v*(gwinfo->canvasHeight-height))/MAXPOT;}
   if(gwinfo->hasHscroll&&width<gwinfo->canvasWidth){
      (*x)+=(gwinfo->view_h*(gwinfo->canvasWidth-width))/MAXPOT;}}

/**************************************************************************/
/**                                                                      **/
/**                       Initialization Functions                       **/
/**                                                                      **/
/**************************************************************************/

#define NUMSYMBOLS 18
#define SYMROWS     5

typedef struct {
   short left,top,width,height;
   short image[SYMROWS];
   LVAL refcon;}
Symbol;

static Symbol chip Symbols[NUMSYMBOLS];

static void InitSymbol(int sym,int left,int top,int width,int height){
   Symbols[sym].width=width;
   Symbols[sym].height=height;
   Symbols[sym].left=left;
   Symbols[sym].top=top;}

void initialize_static_globals(void){
   InitSymbol(0, 0, 0, 2, 2);
   Symbols[0].image[0]=0x8000;
   InitSymbol(1, 0, 0, 2, 2);
   Symbols[1].image[0]=0xC000;
   InitSymbol(2, 0, 0, 2, 2);
   Symbols[2].image[0]=0xC000;
   Symbols[2].image[1]=0x8000;
   InitSymbol(3, 0, 0, 2, 2);
   Symbols[3].image[0]=Symbols[3].image[1]=0xC000;
   InitSymbol(4, 2, 2, 4, 4);
   Symbols[4].image[0]=Symbols[4].image[3]=0x6000;
   Symbols[4].image[1]=Symbols[4].image[2]=0x9000;
   InitSymbol(5, 2, 2, 4, 4);
   Symbols[5].image[0]=Symbols[5].image[3]=0x6000;
   Symbols[5].image[1]=Symbols[5].image[2]=0xF000;
   InitSymbol(6, 3, 3, 5, 5);
   Symbols[6].image[0]=Symbols[6].image[4]=0x2000;
   Symbols[6].image[1]=Symbols[6].image[3]=0x5000;
   Symbols[6].image[2]=0x8800;
   InitSymbol(7, 3, 3, 5, 5);
   Symbols[7].image[0]=Symbols[7].image[4]=0x2000;
   Symbols[7].image[1]=Symbols[7].image[3]=0x7000;
   Symbols[7].image[2]=0xF800;
   InitSymbol(8, 3, 3, 5, 5);
   Symbols[8].image[0]=Symbols[8].image[4]=Symbols[8].image[1]=Symbols[8].image[3]=0x2000;
   Symbols[8].image[2]=0xF800;
   InitSymbol(9, 3, 3, 5, 5);
   Symbols[9].image[0]=Symbols[9].image[4]=0x7000;
   Symbols[9].image[1]=Symbols[9].image[3]=0xA800;
   Symbols[9].image[2]=0xF800;
   InitSymbol(10, 2, 2, 4, 4);
   Symbols[10].image[0]=Symbols[10].image[3]=0xF000;
   Symbols[10].image[1]=Symbols[10].image[2]=0x9000;
   InitSymbol(11, 2, 2, 4, 4);
  Symbols[11].image[0]=Symbols[11].image[3]=Symbols[11].image[1]=Symbols[11].image[2]=0xF000;
   InitSymbol(12, 3, 3, 5, 5);
   Symbols[12].image[0]=0x7000;
   Symbols[12].image[1]=Symbols[12].image[2]=0x8800;
   Symbols[12].image[3]=0x5000;
   Symbols[12].image[4]=0x2000;
   InitSymbol(13, 3, 3, 5, 5);
   Symbols[13].image[0]=Symbols[13].image[3]=0x7000;
   Symbols[13].image[1]=Symbols[13].image[2]=0xF800;
   Symbols[13].image[4]=0x2000;
   InitSymbol(14, 3, 3, 5, 5);
   Symbols[14].image[0]=0x2000;
   Symbols[14].image[1]=0x5000;
   Symbols[14].image[2]=Symbols[14].image[3]=0x8800;
   Symbols[14].image[4]=0x7000;
   InitSymbol(15, 3, 3, 5, 5);
   Symbols[15].image[0]=0x2000;
   Symbols[15].image[1]=Symbols[15].image[4]=0x7000;
   Symbols[15].image[2]=Symbols[15].image[3]=0xF800;
   InitSymbol(16, 3, 3, 5, 5);
   Symbols[16].image[2]=0x2000;
   Symbols[16].image[0]=Symbols[16].image[4]=0x8800;
   Symbols[16].image[1]=Symbols[16].image[3]=0x5000;
   InitSymbol(17, 3, 3, 5, 5);
   Symbols[17].image[2]=0x2000;
   Symbols[17].image[0]=Symbols[17].image[4]=Symbols[17].image[1]=Symbols[17].image[3]=0xD800;}

/**************************************************************************/
/**                                                                      **/
/**                  Line and Rectangle Drawing Functions                **/
/**                                                                      **/
/**************************************************************************/

static struct TmpRas tmpRas;
static struct AreaInfo areaInfo;

static void drawline(short a,short b,short c,short d){
   Move(rp,a,b);
   Draw(rp,c,d);}

static void draw_object(StGWWinInfo *gwinfo,int what,int how,int a,int b,int c,int d){
   static short xy[10]={0,0,0,0,0,0,0,0,0,0};
   static struct Border bd={0,0,0,0,0,5,xy,0};
   struct Window *w;
   PLANEPTR planePtr;
   short areabuffer[5],i;
   int cc,dd;
   if(!gwinfo||!(w=gwinfo->window))return;
/*printf("what = %c how = %c a = %d b = %d c = %d d = %d\n",what,how,a,b,c,d);
printf("clipping=%d dbflag=%d\n",gwinfo->clipped,dbflag);*/
   if(dbmove(gwinfo,&a,&b))return;
   if(what=='R'||what=='O'){
      cc=a+c;
      dd=b+d;
      if(!dbflag){
         cc-=w->BorderLeft;
         dd-=w->BorderTop;}
      if(dbmove(gwinfo,&cc,&dd))return;}
   if(how=='E')SetAPen(rp,gwinfo->backColor);
   switch(what) {
      case 'L': {
         if(dbmove(gwinfo,&c,&d))return;
         drawline((short)a,(short)b,(short)c,(short)d);
         if(gwinfo->lineWidth>1){
            if(a-c<b-d)drawline((short)a,(short)(b+1),(short)c,(short)(d+1));
            else drawline((short)(a+1),(short)b,(short)(c+1),(short)d);
            if(gwinfo->lineWidth>2){
               if(a-c<b-d)drawline((short)a,(short)(b-1),(short)c,(short)(d-1));
               else drawline((short)(a-1),(short)b,(short)(c-1),(short)d);}}
         break;}
      case 'P': {
         WritePixel(rp,(short)a,(short)b);
         break;}
      case 'R': {
         switch (how) {
            case 'E': 
            case 'P': {
               RectFill(rp,(short)a,(short)b,(short)(a+c-1),(short)(b+d-1));
               break;}
            case 'F': {
               bd.LeftEdge=a;
               bd.TopEdge=b;
               bd.FrontPen=gwinfo->drawColor;
               bd.BackPen=gwinfo->backColor;
               bd.DrawMode=gwinfo->drawMode;
               xy[2]=xy[4]=c-1;
               xy[5]=xy[7]=d-1;
               DrawBorder(rp,&bd,0,0);
               if(gwinfo->lineWidth>1){
                  bd.LeftEdge++;
                  bd.TopEdge++;
                  xy[2]=xy[4]=c-3;
                  xy[5]=xy[7]=d-3;
                  DrawBorder(rp,&bd,0,0);
                  if(gwinfo->lineWidth>2){
                     bd.LeftEdge-=2;
                     bd.TopEdge-=2;
                     xy[2]=xy[4]=c+1;
                     xy[5]=xy[7]=d+1;
                     DrawBorder(rp,&bd,0,0);}}
               break;}}
         break;}
      case 'O': {
         switch(how) {
            case 'E':
            case 'P': {
               if(!(planePtr=AllocRaster(screenw,screenh)))xlfail("unable to allocate raster");
               for(i=0;i<5;i++)areabuffer[i]=0;
               InitArea(&areaInfo,areabuffer,2);
               rp->AreaInfo=&areaInfo;
               InitTmpRas(&tmpRas,planePtr,RASSIZE(screenw,screenh));
               rp->TmpRas=&tmpRas;
               AreaEllipse(rp,(short)(a+c/2),(short)(b+d/2),(short)(c/2),(short)(d/2));
               AreaEnd(rp);
               FreeRaster(planePtr,screenw,screenh);
               break;}
            case 'F': {
               SetOPen(rp,gwinfo->drawColor);
               DrawEllipse(rp,(short)(a+c/2),(short)(b+d/2),(short)(c/2),(short)(d/2));
               if(gwinfo->lineWidth>1){
                  DrawEllipse(rp,(short)(a+c/2),(short)(b+d/2),(short)(c/2-1),(short)(d/2-1));
                  if(gwinfo->lineWidth>2){
                     DrawEllipse(rp,(short)(a+c/2),(short)(b+d/2),(short)(c/2+1),(short)(d/2+1));}}
               BNDRYOFF(rp);
               break;}}
         break;}}
   if(how=='E')SetAPen(rp,gwinfo->drawColor);}

static void draw_poly(StGWWinInfo *gwinfo,char how,int n,short *p,int from_origin){
   int i,x,y;
   struct Window *w;
   PLANEPTR planePtr;
   short *areabuffer;
   if(!gwinfo||!(w=gwinfo->window)||n<=0)return;
   x=p[0];
   y=p[1];
   if(dbmove(gwinfo,&x,&y))return;
   p[0]=x;
   p[1]=y;
   for(i=1;i<n;i++){
      x=p[2*i];
      y=p[2*i+1];
      if(dbmove(gwinfo,&x,&y))return;
      p[2*i]=x;
      p[2*i+1]=y;}
   if(how=='E')SetAPen(rp,gwinfo->backColor);
   if(!from_origin)for(i=1;i<n;i++){
      p[2*i]=p[2*i]+p[2*i-2];
      p[2*i+1]=p[2*i+1]+p[2*i-1];}
   switch(how){
      case 'E':
      case 'P': {
         if(!(planePtr=AllocRaster(screenw,screenh)))xlfail("unable to allocate raster");
         if(!(areabuffer=calloc(1,5*n*sizeof(short))))xlfail("unable to allocate raster buffer");
         InitArea(&areaInfo,areabuffer,n);
         rp->AreaInfo=&areaInfo;
         InitTmpRas(&tmpRas,planePtr,RASSIZE(screenw,screenh));
         rp->TmpRas=&tmpRas;
         AreaMove(rp,p[0],p[1]);
         for(i=1;i<n;i++)AreaDraw(rp,p[2*i],p[2*i+1]);
         AreaEnd(rp);
         free(areabuffer);
         FreeRaster(planePtr,screenw,screenh);
         break;}
      case 'F': {
         Move(rp,p[0],p[1]);
         PolyDraw(rp,n,p);
         break;}}
   if(how=='E')SetAPen(rp,gwinfo->drawColor);}

void StGWDrawLine(StGWWinInfo *gwinfo,int x1,int y1,int x2,int y2){
  draw_object(gwinfo,'L','0',x1,y1,x2,y2);}

void StGWDrawPoint(StGWWinInfo *gwinfo,int x,int y){
  draw_object(gwinfo,'P','0',x,y,0,0);}

void StGWEraseRect(StGWWinInfo *gwinfo,int left,int top,int width,int height){
   draw_object(gwinfo,'R','E',left,top,width,height);}

void StGWFrameRect(StGWWinInfo *gwinfo,int left,int top,int width,int height){
  draw_object(gwinfo,'R','F',left,top,width,height);} 

void StGWPaintRect(StGWWinInfo *gwinfo,int left,int top,int width,int height){
  draw_object(gwinfo,'R','P',left,top,width,height);}

void StGWEraseOval(StGWWinInfo *gwinfo,int left,int top,int width,int height){
  draw_object(gwinfo,'O','E',left,top,width,height);}

void StGWFrameOval(StGWWinInfo *gwinfo,int left,int top,int width,int height){
  draw_object(gwinfo,'O','F',left,top,width,height);}

void StGWPaintOval(StGWWinInfo *gwinfo,int left,int top,int width,int height){
  draw_object(gwinfo,'O','P',left,top,width,height);}

void StGWEraseArc(StGWWinInfo *gwinfo,int left,int top,int width,int height,double angle1,double angle2){
   /*draw_arc(gwinfo,'E',left,top,width,height,angle1,angle2);}*/
   xlfail("not supported 25"); }

void StGWFrameArc(StGWWinInfo *gwinfo,int left,int top,int width,int height,double angle1,double angle2){
   /*draw_arc(gwinfo,'F',left,top,width,height,angle1,angle2);}*/
   xlfail("not supported 26"); }

void StGWPaintArc(StGWWinInfo *gwinfo,int left,int top,int width,int height,double angle1,double angle2){
   /*draw_arc(gwinfo,'P',left,top,width,height,angle1,angle2);}*/
   xlfail("not supported 24"); }

void StGWErasePoly(StGWWinInfo *gwinfo,int n,short *p,int from_origin){
   draw_poly(gwinfo,'E',n,p,from_origin);}

void StGWFramePoly(StGWWinInfo *gwinfo,int n,short *p,int from_origin){
   draw_poly(gwinfo,'F',n,p,from_origin);}

void StGWPaintPoly(StGWWinInfo *gwinfo,int n,short *p,int from_origin){
   draw_poly(gwinfo,'P',n,p,from_origin);}

/**************************************************************************/
/**                                                                      **/
/**                            Text Functions                            **/
/**                                                                      **/
/**************************************************************************/

int StGWTextAscent(StGWWinInfo *gwinfo){
   return((int)window->RPort->TxBaseline);}

int StGWTextDescent(StGWWinInfo *gwinfo){
   return((int)(window->RPort->TxHeight-window->RPort->TxBaseline));}

int StGWTextWidth(StGWWinInfo *gwinfo,char *text){
   return((int)TextLength(window->RPort,text,strlen(text)));}

void StGWDrawString(StGWWinInfo *gwinfo,char *s,int x,int y){
   struct Window *w;
   if(!s||!gwinfo||!(w=gwinfo->window))return;
   if(dbmove(gwinfo,&x,&y))return;
/*printf("x=%d y=%d s=%s\n",x,y,s);*/
   Move(rp,(short)x,(short)(y+1));
   Text(rp,s,strlen(s));}

void StGWDrawText(StGWWinInfo *gwinfo,char *text,int x,int y,int h,int v){
   int FontAscent,string_width;
   if(!text||!gwinfo)return;
   FontAscent=StGWTextAscent(gwinfo);
   string_width=StGWTextWidth(gwinfo,text);
   if(v==1)y+=FontAscent;
   if(h==1)x-=string_width/2;
   if(h==2)x-=string_width;
   StGWDrawString(gwinfo,text,x,y);}

static void DrawCharUp(struct Window *w,char myChar,int x,int y){
   short i,j,hch,wch;
   char dc,bc;
   StGWWinInfo *gwinfo;
   gwinfo=(StGWWinInfo *)w->UserData;
   dc=gwinfo->drawColor;
   bc=gwinfo->backColor;
   if(dbmove(gwinfo,&x,&y))return;
   hch=rp->TxHeight;
   wch=rp->TxWidth;
   SetAPen(&rp1,dc);
   SetAPen(&rp2,dc);
   SetBPen(&rp1,bc);
   SetDrMd(&rp1,w->RPort->DrawMode);
   SetDrMd(&rp2,w->RPort->DrawMode);
   SetRast(&rp1,bc);
   SetRast(&rp2,bc);
   Move(&rp1,0,rp->TxBaseline);
   Text(&rp1,&myChar,1);
   for(i=0;i<wch;i++)for(j=0;j<hch;j++)if(ReadPixel(&rp1,i,j)==dc)WritePixel(&rp2,j,8-i);
   ClipBlit(&rp2,0,0,rp,x,y-wch,hch,wch,0xC0);}

void StGWDrawStringUp(StGWWinInfo *gwinfo,char *s,int x,int y){
   struct Window *w;
   char str[2];
   int n;
   if(!s||!gwinfo||!(w=gwinfo->window))return;
   str[1] = '\0';
   for(n=strlen(s);n>0;n--,s++){
      DrawCharUp(w,*s,x,y);
      str[0]=*s;
  	   y-=StGWTextWidth(gwinfo,str);}}
 
void StGWDrawTextUp(StGWWinInfo *gwinfo,char *text,int x,int y,int h,int v){
   int FontAscent,string_width;
   if(!text||!gwinfo)return;
   FontAscent=StGWTextAscent(gwinfo);
   string_width=StGWTextWidth(gwinfo,text);
   if(v==1)x+=FontAscent;
   if(h==1)y+=string_width/2;
   if(h==2)y+=string_width;
   StGWDrawStringUp(gwinfo,text,x,y);}

/**************************************************************************/
/**                                                                      **/
/**                           Symbol Functions                           **/
/**                                                                      **/
/**************************************************************************/

void StGWSetSymRefCon(int index,LVAL rc){
   if(index<NUMSYMBOLS)Symbols[index].refcon=rc;}

LVAL StGWGetSymRefCon(int index){
   if(index<NUMSYMBOLS)return(Symbols[index].refcon);
   else return(0);}

void StGWGetSymbolSize(int sym,int *width,int *height){
   *width=Symbols[sym].width;
   *height=Symbols[sym].height;}

void StGWDrawSymbol(StGWWinInfo *gwinfo,int sym,int x,int y){
   if(sym<0||sym>=NUMSYMBOLS)return;
   draw_bitmap(gwinfo,x-(int)Symbols[sym].left,y-(int)Symbols[sym].top,
   Symbols[sym].width,Symbols[sym].height,(char *)Symbols[sym].image,2);}

void StGWReplaceSymbol(StGWWinInfo *gwinfo,int oldsym,int newsym,int x,int y){
   int oldwidth,oldheight,newwidth,newheight;
   if(oldsym>=NUMSYMBOLS||newsym>=NUMSYMBOLS)return;
   StGWGetSymbolSize(oldsym,&oldwidth,&oldheight);
   StGWGetSymbolSize(newsym,&newwidth,&newheight);
   if(oldwidth>newwidth||oldheight>newheight){
      StGWEraseRect(gwinfo,x-Symbols[oldsym].left,y-Symbols[oldsym].top,
      oldwidth,oldheight);}
   StGWDrawSymbol(gwinfo,newsym,x,y);}

/**************************************************************************/
/**                                                                      **/
/**                           Bitmap Functions                           **/
/**                                                                      **/
/**************************************************************************/

static void draw_bitmap(StGWWinInfo *gwinfo,int left,int top,int width,int height,char *image,int modulus){
   struct Window *w;
   if(!gwinfo||!(w=gwinfo->window))return;
/*printf("bitmap left=%d top=%d width=%d height=%d\n",left,top,width,height);*/
   if(dbmove(gwinfo,&left,&top))return;
   SetDrMd(rp,gwinfo->symbolMode);
   BltTemplate(image,0,modulus,rp,left,top,width,height);   SetBPen(rp,gwinfo->backColor);
   SetDrMd(rp,gwinfo->drawMode);}

void StGWDrawBitmap(StGWWinInfo *gwinfo,int left,int top,int width,int height,char *image){
   unsigned short *im;
   int rowwords,i,j,l,m;
   rowwords=width/16+1;
   if(rowwords*height<=0)return;
   if(!(im=AllocMem(rowwords*height*2,MEMF_CHIP|MEMF_CLEAR)))return;
   for(i=0;i<height;i++)for(j=0;j<rowwords;j++){
      for(l=0;l<16;l++){
         m=j*16+l;
         if(m<width&&image[i*width+m])im[i*rowwords+j]|=(1<<(15-l));}}
   draw_bitmap(gwinfo,left,top,width,height,(char *)im,2*rowwords);
   FreeMem(im,rowwords*height*2);}


/**************************************************************************/
/**                                                                      **/
/**                         Buffering Functions                          **/
/**                                                                      **/
/**************************************************************************/

static int bufflevel=0;

void StGWStartBuffering(StGWWinInfo *gwinfo){
   if(!gwinfo||!gwinfo->window)return;
   bufflevel++;
   if(dbflag)return;
   dbflag=1;
   rp=&dbrp;
   SetRast(rp,gwinfo->backColor);}
/*
void StGWBufferToScreen(StGWWinInfo *gwinfo,int left,int top,int width,int height){
   struct Window *w;
   if(!gwinfo||!(w=gwinfo->window))return;
   if(bufflevel>0)bufflevel--;
   if(bufflevel>0)return;
   if(dbflag){
      left+=w->BorderLeft;
      top+=w->BorderTop;
      ClipBlit(&dbrp,left,top,w->RPort,left,top,width,height,0xC0);
      dbflag=0;
      rp=w->RPort;}}
*/
void StGWBufferToScreen(StGWWinInfo *gwinfo,int left,int top,int width,int height){
   struct Window *w;
   int vwidth,vheight,bleft,btop;
   if(!gwinfo||!(w=gwinfo->window))return;
   if(bufflevel>0)bufflevel--;
   if(bufflevel>0)return;
   if(dbflag){
      dbflag=0;
      rp=w->RPort;
      if(left>=0&&top>=0){
         bleft=left;
         btop=top;
         StGWGetViewRect(gwinfo,0,0,&vwidth,&vheight);
/*printf("buffer left=%d top=%d width=%d height=%d\n",left,top,width,height);*/
         if(gwinfo->hasHscroll&&vwidth<gwinfo->canvasWidth){
            bleft+=(gwinfo->view_h*(gwinfo->canvasWidth-vwidth))/MAXPOT;}
         if(gwinfo->hasVscroll&&vheight<gwinfo->canvasHeight){
            btop+=(gwinfo->view_v*(gwinfo->canvasHeight-vheight))/MAXPOT;}
         ClipBlit(&dbrp,bleft,btop,rp,left+(int)w->BorderLeft,
         top+(int)w->BorderTop,width,height,0xC0);}}}

/**************************************************************************/
/**                                                                      **/
/**                         Miscellaneous Functions                      **/
/**                                                                      **/
/**************************************************************************/

extern unsigned short icon[];

void StGWDumpImage(StGWWinInfo *gwinfo,char *fname,double scale){
   struct Window *w;
   unsigned long flags;
   int test;
   if(gwinfo&&(w=gwinfo->window)){
      WindowToFront(w);
      flags=w->IDCMPFlags;
      Dodo(w,0);
      wfile(fname);
      test=SaveWindow(w,fname,w->BorderLeft,w->BorderTop,
      w->Width-w->BorderRight-w->BorderLeft,w->Height-w->BorderTop-w->BorderBottom);
      Dodo(w,flags);
      if(test)xlfail("IFF save failed");}}

void StGWResetBuffer(){
   bufflevel=dbflag=0;}

