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