text: #include <lib9.h>
  #include <image.h>
  #include <memimage.h>
  #include <memlayer.h>
  
  /*
   * Place i so i->r.min = log, i->layer->screenr.min == scr.
  */
  int
  memlorigin(Memimage *i, Point log, Point scr)
  {
  	Memlayer *l;
  	Memscreen *s;
  	Memimage *t, *shad, *nsave;
  	Rectangle x, newr, oldr;
  	Point delta;
  	int overlap, eqlog, eqscr, wasclear;
  
  	l = i->layer;
  	s = l->screen;
  	oldr = l->screenr;
  	newr = Rect(scr.x, scr.y, scr.x+Dx(oldr), scr.y+Dy(oldr));
  	eqscr = eqpt(scr, oldr.min);
  	eqlog = eqpt(log, i->r.min);
  	if(eqscr && eqlog)
  		return 0;
  	nsave = nil;
  	if(eqlog==0 && l->save!=nil){
  		nsave = allocmemimage(Rect(log.x, log.y, log.x+Dx(oldr), log.y+Dy(oldr)), i->ldepth);
  		if(nsave == nil)
  			return -1;
  	}
  
  	/*
  	 * Bring it to front and move logical coordinate system.
  	 */
  	memltofront(i);
  	wasclear = l->clear;
  	if(nsave){
  		if(!wasclear)
  			memimagedraw(nsave, nsave->r, l->save, l->save->r.min, memones, Pt(0,0));
  		freememimage(l->save);
  		l->save = nsave;
  	}
  	delta = subpt(log, i->r.min);
  	i->r = rectaddpt(i->r, delta);
  	i->clipr = rectaddpt(i->clipr, delta);
  	l->delta = subpt(l->screenr.min, i->r.min);
  	if(eqscr)
  		return 0;
  
  	/*
  	 * To clean up old position, make a shadow window there, don't paint it,
  	 * push it behind this one, and (later) delete it.  Because the refresh function
  	 * for this fake window is a no-op, this will cause no graphics action except
  	 * to restore the background and expose the windows previously hidden.
  	 */
  	shad = memlalloc(s, oldr, memlnorefresh, nil, -1);
  	s->frontmost = i;
  	if(s->rearmost == i)
  		s->rearmost = shad;
  	else
  		l->rear->layer->front = shad;
  	shad->layer->front = i;
  	shad->layer->rear = l->rear;
  	l->rear = shad;
  	l->front = nil;
  	shad->layer->clear = 0;
  
  	/*
  	 * Shadow is now holding down the fort at the old position.
  	 * Move the window and hide things obscured by new position.
  	 */
  	for(t=l->rear->layer->rear; t!=nil; t=t->layer->rear){
  		x = newr;
  		overlap = rectclip(&x, t->layer->screenr);
  		if(overlap){
  			memlhide(t, x);
  			t->layer->clear = 0;
  		}
  	}
  	l->screenr = newr;
  	l->delta = subpt(scr, i->r.min);
  	l->clear = rectinrect(newr, l->screen->image->clipr);
  
  	/*
  	 * Everything's covered.  Copy to new position and delete shadow window.
  	 */
  	if(wasclear)
  		memdraw(s->image, newr, s->image, oldr.min, memones, Pt(0,0));
  	else
  		memlexpose(i, newr);
  	memldelete(shad);
  
  	return 1;
  }
  
  void
  memlnorefresh(Memimage *l, Rectangle r, void *v)
  {
  	USED(l);
  	USED(r.min.x);
  	USED(v);
  }
  