1*7dd7cddfSDavid du Colombier #include "../lib9.h" 2*7dd7cddfSDavid du Colombier 3*7dd7cddfSDavid du Colombier #include "../libdraw/draw.h" 4*7dd7cddfSDavid du Colombier #include "../libmemdraw/memdraw.h" 5*7dd7cddfSDavid du Colombier #include "../libmemlayer/memlayer.h" 6*7dd7cddfSDavid du Colombier 7*7dd7cddfSDavid du Colombier /* 8*7dd7cddfSDavid du Colombier * Place i so i->r.min = log, i->layer->screenr.min == scr. 9*7dd7cddfSDavid du Colombier */ 10*7dd7cddfSDavid du Colombier int 11*7dd7cddfSDavid du Colombier memlorigin(Memimage *i, Point log, Point scr) 12*7dd7cddfSDavid du Colombier { 13*7dd7cddfSDavid du Colombier Memlayer *l; 14*7dd7cddfSDavid du Colombier Memscreen *s; 15*7dd7cddfSDavid du Colombier Memimage *t, *shad, *nsave; 16*7dd7cddfSDavid du Colombier Rectangle x, newr, oldr; 17*7dd7cddfSDavid du Colombier Point delta; 18*7dd7cddfSDavid du Colombier int overlap, eqlog, eqscr, wasclear; 19*7dd7cddfSDavid du Colombier 20*7dd7cddfSDavid du Colombier l = i->layer; 21*7dd7cddfSDavid du Colombier s = l->screen; 22*7dd7cddfSDavid du Colombier oldr = l->screenr; 23*7dd7cddfSDavid du Colombier newr = Rect(scr.x, scr.y, scr.x+Dx(oldr), scr.y+Dy(oldr)); 24*7dd7cddfSDavid du Colombier eqscr = eqpt(scr, oldr.min); 25*7dd7cddfSDavid du Colombier eqlog = eqpt(log, i->r.min); 26*7dd7cddfSDavid du Colombier if(eqscr && eqlog) 27*7dd7cddfSDavid du Colombier return 0; 28*7dd7cddfSDavid du Colombier nsave = nil; 29*7dd7cddfSDavid du Colombier if(eqlog==0 && l->save!=nil){ 30*7dd7cddfSDavid du Colombier nsave = allocmemimage(Rect(log.x, log.y, log.x+Dx(oldr), log.y+Dy(oldr)), i->chan); 31*7dd7cddfSDavid du Colombier if(nsave == nil) 32*7dd7cddfSDavid du Colombier return -1; 33*7dd7cddfSDavid du Colombier } 34*7dd7cddfSDavid du Colombier 35*7dd7cddfSDavid du Colombier /* 36*7dd7cddfSDavid du Colombier * Bring it to front and move logical coordinate system. 37*7dd7cddfSDavid du Colombier */ 38*7dd7cddfSDavid du Colombier memltofront(i); 39*7dd7cddfSDavid du Colombier wasclear = l->clear; 40*7dd7cddfSDavid du Colombier if(nsave){ 41*7dd7cddfSDavid du Colombier if(!wasclear) 42*7dd7cddfSDavid du Colombier memimagedraw(nsave, nsave->r, l->save, l->save->r.min, nil, Pt(0,0)); 43*7dd7cddfSDavid du Colombier freememimage(l->save); 44*7dd7cddfSDavid du Colombier l->save = nsave; 45*7dd7cddfSDavid du Colombier } 46*7dd7cddfSDavid du Colombier delta = subpt(log, i->r.min); 47*7dd7cddfSDavid du Colombier i->r = rectaddpt(i->r, delta); 48*7dd7cddfSDavid du Colombier i->clipr = rectaddpt(i->clipr, delta); 49*7dd7cddfSDavid du Colombier l->delta = subpt(l->screenr.min, i->r.min); 50*7dd7cddfSDavid du Colombier if(eqscr) 51*7dd7cddfSDavid du Colombier return 0; 52*7dd7cddfSDavid du Colombier 53*7dd7cddfSDavid du Colombier /* 54*7dd7cddfSDavid du Colombier * To clean up old position, make a shadow window there, don't paint it, 55*7dd7cddfSDavid du Colombier * push it behind this one, and (later) delete it. Because the refresh function 56*7dd7cddfSDavid du Colombier * for this fake window is a no-op, this will cause no graphics action except 57*7dd7cddfSDavid du Colombier * to restore the background and expose the windows previously hidden. 58*7dd7cddfSDavid du Colombier */ 59*7dd7cddfSDavid du Colombier shad = memlalloc(s, oldr, memlnorefresh, nil, DNofill); 60*7dd7cddfSDavid du Colombier if(shad == nil) 61*7dd7cddfSDavid du Colombier return -1; 62*7dd7cddfSDavid du Colombier s->frontmost = i; 63*7dd7cddfSDavid du Colombier if(s->rearmost == i) 64*7dd7cddfSDavid du Colombier s->rearmost = shad; 65*7dd7cddfSDavid du Colombier else 66*7dd7cddfSDavid du Colombier l->rear->layer->front = shad; 67*7dd7cddfSDavid du Colombier shad->layer->front = i; 68*7dd7cddfSDavid du Colombier shad->layer->rear = l->rear; 69*7dd7cddfSDavid du Colombier l->rear = shad; 70*7dd7cddfSDavid du Colombier l->front = nil; 71*7dd7cddfSDavid du Colombier shad->layer->clear = 0; 72*7dd7cddfSDavid du Colombier 73*7dd7cddfSDavid du Colombier /* 74*7dd7cddfSDavid du Colombier * Shadow is now holding down the fort at the old position. 75*7dd7cddfSDavid du Colombier * Move the window and hide things obscured by new position. 76*7dd7cddfSDavid du Colombier */ 77*7dd7cddfSDavid du Colombier for(t=l->rear->layer->rear; t!=nil; t=t->layer->rear){ 78*7dd7cddfSDavid du Colombier x = newr; 79*7dd7cddfSDavid du Colombier overlap = rectclip(&x, t->layer->screenr); 80*7dd7cddfSDavid du Colombier if(overlap){ 81*7dd7cddfSDavid du Colombier memlhide(t, x); 82*7dd7cddfSDavid du Colombier t->layer->clear = 0; 83*7dd7cddfSDavid du Colombier } 84*7dd7cddfSDavid du Colombier } 85*7dd7cddfSDavid du Colombier l->screenr = newr; 86*7dd7cddfSDavid du Colombier l->delta = subpt(scr, i->r.min); 87*7dd7cddfSDavid du Colombier l->clear = rectinrect(newr, l->screen->image->clipr); 88*7dd7cddfSDavid du Colombier 89*7dd7cddfSDavid du Colombier /* 90*7dd7cddfSDavid du Colombier * Everything's covered. Copy to new position and delete shadow window. 91*7dd7cddfSDavid du Colombier */ 92*7dd7cddfSDavid du Colombier if(wasclear) 93*7dd7cddfSDavid du Colombier memdraw(s->image, newr, s->image, oldr.min, nil, Pt(0,0)); 94*7dd7cddfSDavid du Colombier else 95*7dd7cddfSDavid du Colombier memlexpose(i, newr); 96*7dd7cddfSDavid du Colombier memldelete(shad); 97*7dd7cddfSDavid du Colombier 98*7dd7cddfSDavid du Colombier return 1; 99*7dd7cddfSDavid du Colombier } 100*7dd7cddfSDavid du Colombier 101*7dd7cddfSDavid du Colombier void 102*7dd7cddfSDavid du Colombier memlnorefresh(Memimage *l, Rectangle r, void *v) 103*7dd7cddfSDavid du Colombier { 104*7dd7cddfSDavid du Colombier USED(l); 105*7dd7cddfSDavid du Colombier USED(r.min.x); 106*7dd7cddfSDavid du Colombier USED(v); 107*7dd7cddfSDavid du Colombier } 108