lorigin.c 2.4 KB

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