lorigin.c 2.9 KB

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