window.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #include "lib9.h"
  2. #include "draw.h"
  3. #include "kernel.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. kwerrstr("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, s->image->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 || n>(Displaybufsize-100)/4){
  118. _drawprint(2, "top/bottom: ridiculous number of windows\n");
  119. return;
  120. }
  121. if(n==0)
  122. return;
  123. /* check that all images are on the same display; only it can check the screens */
  124. d = w[0]->display;
  125. for(i=1; i<n; i++)
  126. if(w[i]->display != d){
  127. _drawprint(2, "top/bottom: windows not on same display\n");
  128. return;
  129. }
  130. b = bufimage(d, 1+1+2+4*n);
  131. if (b == 0) {
  132. _drawprint(2, "top/bottom: no bufimage\n");
  133. return;
  134. }
  135. b[0] = 't';
  136. b[1] = top;
  137. BPSHORT(b+2, n);
  138. for(i=0; i<n; i++)
  139. BPLONG(b+4+4*i, w[i]->id);
  140. }
  141. void
  142. bottomwindow(Image *w)
  143. {
  144. topbottom(&w, 1, 0);
  145. }
  146. void
  147. topwindow(Image *w)
  148. {
  149. topbottom(&w, 1, 1);
  150. }
  151. void
  152. bottomnwindows(Image **w, int n)
  153. {
  154. topbottom(w, n, 0);
  155. }
  156. void
  157. topnwindows(Image **w, int n)
  158. {
  159. topbottom(w, n, 1);
  160. }
  161. int
  162. originwindow(Image *w, Point log, Point scr)
  163. {
  164. uchar *b;
  165. Point delta;
  166. flushimage(w->display, 0);
  167. b = bufimage(w->display, 1+4+2*4+2*4);
  168. if(b == nil)
  169. return 0;
  170. b[0] = 'o';
  171. BPLONG(b+1, w->id);
  172. BPLONG(b+5, log.x);
  173. BPLONG(b+9, log.y);
  174. BPLONG(b+13, scr.x);
  175. BPLONG(b+17, scr.y);
  176. if(flushimage(w->display, 1) < 0)
  177. return -1;
  178. delta = subpt(log, w->r.min);
  179. w->r = rectaddpt(w->r, delta);
  180. w->clipr = rectaddpt(w->clipr, delta);
  181. return 1;
  182. }