lorigin.c 2.4 KB

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