window.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. typedef struct Memimage Memimage;
  5. static int screenid;
  6. Screen*
  7. allocscreen(Image *image, Image *fill, int public)
  8. {
  9. uchar *a;
  10. Screen *s;
  11. int id, try;
  12. Display *d;
  13. d = image->display;
  14. if(d != fill->display){
  15. werrstr("allocscreen: image and fill on different displays");
  16. return 0;
  17. }
  18. s = malloc(sizeof(Screen));
  19. if(s == 0)
  20. return 0;
  21. SET(id);
  22. for(try=0; try<25; try++){
  23. /* loop until find a free id */
  24. a = bufimage(d, 1+4+4+4+1);
  25. if(a == 0){
  26. free(s);
  27. return 0;
  28. }
  29. id = ++screenid;
  30. a[0] = 'A';
  31. BPLONG(a+1, id);
  32. BPLONG(a+5, image->id);
  33. BPLONG(a+9, fill->id);
  34. a[13] = public;
  35. if(flushimage(d, 0) != -1)
  36. break;
  37. }
  38. s->display = d;
  39. s->id = id;
  40. s->image = image;
  41. assert(s->image && s->image->chan != 0);
  42. s->fill = fill;
  43. return s;
  44. }
  45. Screen*
  46. publicscreen(Display *d, int id, ulong chan)
  47. {
  48. uchar *a;
  49. Screen *s;
  50. s = malloc(sizeof(Screen));
  51. if(s == 0)
  52. return 0;
  53. a = bufimage(d, 1+4+4);
  54. if(a == 0){
  55. Error:
  56. free(s);
  57. return 0;
  58. }
  59. a[0] = 'S';
  60. BPLONG(a+1, id);
  61. BPLONG(a+5, chan);
  62. if(flushimage(d, 0) < 0)
  63. goto Error;
  64. s->display = d;
  65. s->id = id;
  66. s->image = 0;
  67. s->fill = 0;
  68. return s;
  69. }
  70. int
  71. freescreen(Screen *s)
  72. {
  73. uchar *a;
  74. Display *d;
  75. if(s == 0)
  76. return 0;
  77. d = s->display;
  78. a = bufimage(d, 1+4);
  79. if(a == 0)
  80. return -1;
  81. a[0] = 'F';
  82. BPLONG(a+1, s->id);
  83. /*
  84. * flush(1) because screen is likely holding last reference to
  85. * window, and want it to disappear visually.
  86. */
  87. if(flushimage(d, 1) < 0)
  88. return -1;
  89. free(s);
  90. return 1;
  91. }
  92. Image*
  93. allocwindow(Screen *s, Rectangle r, int ref, ulong val)
  94. {
  95. return _allocwindow(nil, s, r, ref, val);
  96. }
  97. Image*
  98. _allocwindow(Image *i, Screen *s, Rectangle r, int ref, ulong val)
  99. {
  100. Display *d;
  101. d = s->display;
  102. i = _allocimage(i, d, r, d->screenimage->chan, 0, val, s->id, ref);
  103. if(i == 0)
  104. return 0;
  105. i->screen = s;
  106. i->next = s->display->windows;
  107. s->display->windows = i;
  108. return i;
  109. }
  110. static
  111. void
  112. topbottom(Image **w, int n, int top)
  113. {
  114. int i;
  115. uchar *b;
  116. Display *d;
  117. if(n < 0){
  118. Ridiculous:
  119. fprint(2, "top/bottom: ridiculous number of windows\n");
  120. return;
  121. }
  122. if(n == 0)
  123. return;
  124. if(n > (w[0]->display->bufsize-100)/4)
  125. goto Ridiculous;
  126. /*
  127. * this used to check that all images were on the same screen.
  128. * we don't know the screen associated with images we acquired
  129. * by name. instead, check that all images are on the same display.
  130. * the display will check that they are all on the same screen.
  131. */
  132. d = w[0]->display;
  133. for(i=1; i<n; i++)
  134. if(w[i]->display != d){
  135. fprint(2, "top/bottom: windows not on same screen\n");
  136. return;
  137. }
  138. if(n==0)
  139. return;
  140. b = bufimage(d, 1+1+2+4*n);
  141. b[0] = 't';
  142. b[1] = top;
  143. BPSHORT(b+2, n);
  144. for(i=0; i<n; i++)
  145. BPLONG(b+4+4*i, w[i]->id);
  146. }
  147. void
  148. bottomwindow(Image *w)
  149. {
  150. if(w->screen == 0)
  151. return;
  152. topbottom(&w, 1, 0);
  153. }
  154. void
  155. topwindow(Image *w)
  156. {
  157. if(w->screen == 0)
  158. return;
  159. topbottom(&w, 1, 1);
  160. }
  161. void
  162. bottomnwindows(Image **w, int n)
  163. {
  164. topbottom(w, n, 0);
  165. }
  166. void
  167. topnwindows(Image **w, int n)
  168. {
  169. topbottom(w, n, 1);
  170. }
  171. int
  172. originwindow(Image *w, Point log, Point scr)
  173. {
  174. uchar *b;
  175. Point delta;
  176. flushimage(w->display, 0);
  177. b = bufimage(w->display, 1+4+2*4+2*4);
  178. if(b == nil)
  179. return 0;
  180. b[0] = 'o';
  181. BPLONG(b+1, w->id);
  182. BPLONG(b+5, log.x);
  183. BPLONG(b+9, log.y);
  184. BPLONG(b+13, scr.x);
  185. BPLONG(b+17, scr.y);
  186. if(flushimage(w->display, 1) < 0)
  187. return -1;
  188. delta = subpt(log, w->r.min);
  189. w->r = rectaddpt(w->r, delta);
  190. w->clipr = rectaddpt(w->clipr, delta);
  191. return 1;
  192. }