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