17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier
57dd7cddfSDavid du Colombier typedef struct Memimage Memimage;
67dd7cddfSDavid du Colombier
77dd7cddfSDavid du Colombier static int screenid;
87dd7cddfSDavid du Colombier
97dd7cddfSDavid du Colombier Screen*
allocscreen(Image * image,Image * fill,int public)107dd7cddfSDavid du Colombier allocscreen(Image *image, Image *fill, int public)
117dd7cddfSDavid du Colombier {
127dd7cddfSDavid du Colombier uchar *a;
137dd7cddfSDavid du Colombier Screen *s;
147dd7cddfSDavid du Colombier int id, try;
157dd7cddfSDavid du Colombier Display *d;
167dd7cddfSDavid du Colombier
177dd7cddfSDavid du Colombier d = image->display;
187dd7cddfSDavid du Colombier if(d != fill->display){
197dd7cddfSDavid du Colombier werrstr("allocscreen: image and fill on different displays");
207dd7cddfSDavid du Colombier return 0;
217dd7cddfSDavid du Colombier }
227dd7cddfSDavid du Colombier s = malloc(sizeof(Screen));
237dd7cddfSDavid du Colombier if(s == 0)
247dd7cddfSDavid du Colombier return 0;
257dd7cddfSDavid du Colombier SET(id);
267dd7cddfSDavid du Colombier for(try=0; try<25; try++){
277dd7cddfSDavid du Colombier /* loop until find a free id */
287dd7cddfSDavid du Colombier a = bufimage(d, 1+4+4+4+1);
297dd7cddfSDavid du Colombier if(a == 0){
307dd7cddfSDavid du Colombier free(s);
317dd7cddfSDavid du Colombier return 0;
327dd7cddfSDavid du Colombier }
337dd7cddfSDavid du Colombier id = ++screenid;
347dd7cddfSDavid du Colombier a[0] = 'A';
357dd7cddfSDavid du Colombier BPLONG(a+1, id);
367dd7cddfSDavid du Colombier BPLONG(a+5, image->id);
377dd7cddfSDavid du Colombier BPLONG(a+9, fill->id);
387dd7cddfSDavid du Colombier a[13] = public;
397dd7cddfSDavid du Colombier if(flushimage(d, 0) != -1)
407dd7cddfSDavid du Colombier break;
417dd7cddfSDavid du Colombier }
427dd7cddfSDavid du Colombier s->display = d;
437dd7cddfSDavid du Colombier s->id = id;
447dd7cddfSDavid du Colombier s->image = image;
457dd7cddfSDavid du Colombier assert(s->image && s->image->chan != 0);
467dd7cddfSDavid du Colombier
477dd7cddfSDavid du Colombier s->fill = fill;
487dd7cddfSDavid du Colombier return s;
497dd7cddfSDavid du Colombier }
507dd7cddfSDavid du Colombier
517dd7cddfSDavid du Colombier Screen*
publicscreen(Display * d,int id,ulong chan)527dd7cddfSDavid du Colombier publicscreen(Display *d, int id, ulong chan)
537dd7cddfSDavid du Colombier {
547dd7cddfSDavid du Colombier uchar *a;
557dd7cddfSDavid du Colombier Screen *s;
567dd7cddfSDavid du Colombier
577dd7cddfSDavid du Colombier s = malloc(sizeof(Screen));
587dd7cddfSDavid du Colombier if(s == 0)
597dd7cddfSDavid du Colombier return 0;
607dd7cddfSDavid du Colombier a = bufimage(d, 1+4+4);
617dd7cddfSDavid du Colombier if(a == 0){
627dd7cddfSDavid du Colombier Error:
637dd7cddfSDavid du Colombier free(s);
647dd7cddfSDavid du Colombier return 0;
657dd7cddfSDavid du Colombier }
667dd7cddfSDavid du Colombier a[0] = 'S';
677dd7cddfSDavid du Colombier BPLONG(a+1, id);
687dd7cddfSDavid du Colombier BPLONG(a+5, chan);
697dd7cddfSDavid du Colombier if(flushimage(d, 0) < 0)
707dd7cddfSDavid du Colombier goto Error;
717dd7cddfSDavid du Colombier
727dd7cddfSDavid du Colombier s->display = d;
737dd7cddfSDavid du Colombier s->id = id;
747dd7cddfSDavid du Colombier s->image = 0;
757dd7cddfSDavid du Colombier s->fill = 0;
767dd7cddfSDavid du Colombier return s;
777dd7cddfSDavid du Colombier }
787dd7cddfSDavid du Colombier
797dd7cddfSDavid du Colombier int
freescreen(Screen * s)807dd7cddfSDavid du Colombier freescreen(Screen *s)
817dd7cddfSDavid du Colombier {
827dd7cddfSDavid du Colombier uchar *a;
837dd7cddfSDavid du Colombier Display *d;
847dd7cddfSDavid du Colombier
857dd7cddfSDavid du Colombier if(s == 0)
867dd7cddfSDavid du Colombier return 0;
877dd7cddfSDavid du Colombier d = s->display;
887dd7cddfSDavid du Colombier a = bufimage(d, 1+4);
897dd7cddfSDavid du Colombier if(a == 0)
907dd7cddfSDavid du Colombier return -1;
917dd7cddfSDavid du Colombier a[0] = 'F';
927dd7cddfSDavid du Colombier BPLONG(a+1, s->id);
937dd7cddfSDavid du Colombier /*
947dd7cddfSDavid du Colombier * flush(1) because screen is likely holding last reference to
957dd7cddfSDavid du Colombier * window, and want it to disappear visually.
967dd7cddfSDavid du Colombier */
977dd7cddfSDavid du Colombier if(flushimage(d, 1) < 0)
987dd7cddfSDavid du Colombier return -1;
997dd7cddfSDavid du Colombier free(s);
1007dd7cddfSDavid du Colombier return 1;
1017dd7cddfSDavid du Colombier }
1027dd7cddfSDavid du Colombier
1037dd7cddfSDavid du Colombier Image*
allocwindow(Screen * s,Rectangle r,int ref,ulong val)1047dd7cddfSDavid du Colombier allocwindow(Screen *s, Rectangle r, int ref, ulong val)
1057dd7cddfSDavid du Colombier {
1067dd7cddfSDavid du Colombier return _allocwindow(nil, s, r, ref, val);
1077dd7cddfSDavid du Colombier }
1087dd7cddfSDavid du Colombier
1097dd7cddfSDavid du Colombier Image*
_allocwindow(Image * i,Screen * s,Rectangle r,int ref,ulong val)1107dd7cddfSDavid du Colombier _allocwindow(Image *i, Screen *s, Rectangle r, int ref, ulong val)
1117dd7cddfSDavid du Colombier {
1127dd7cddfSDavid du Colombier Display *d;
1137dd7cddfSDavid du Colombier
1147dd7cddfSDavid du Colombier d = s->display;
115*9a747e4fSDavid du Colombier i = _allocimage(i, d, r, d->screenimage->chan, 0, val, s->id, ref);
1167dd7cddfSDavid du Colombier if(i == 0)
1177dd7cddfSDavid du Colombier return 0;
1187dd7cddfSDavid du Colombier i->screen = s;
1197dd7cddfSDavid du Colombier i->next = s->display->windows;
1207dd7cddfSDavid du Colombier s->display->windows = i;
1217dd7cddfSDavid du Colombier return i;
1227dd7cddfSDavid du Colombier }
1237dd7cddfSDavid du Colombier
1247dd7cddfSDavid du Colombier static
1257dd7cddfSDavid du Colombier void
topbottom(Image ** w,int n,int top)1267dd7cddfSDavid du Colombier topbottom(Image **w, int n, int top)
1277dd7cddfSDavid du Colombier {
1287dd7cddfSDavid du Colombier int i;
1297dd7cddfSDavid du Colombier uchar *b;
130*9a747e4fSDavid du Colombier Display *d;
1317dd7cddfSDavid du Colombier
132*9a747e4fSDavid du Colombier if(n < 0){
133*9a747e4fSDavid du Colombier Ridiculous:
134*9a747e4fSDavid du Colombier fprint(2, "top/bottom: ridiculous number of windows\n");
1357dd7cddfSDavid du Colombier return;
1367dd7cddfSDavid du Colombier }
137*9a747e4fSDavid du Colombier if(n == 0)
138*9a747e4fSDavid du Colombier return;
139*9a747e4fSDavid du Colombier if(n > (w[0]->display->bufsize-100)/4)
140*9a747e4fSDavid du Colombier goto Ridiculous;
141*9a747e4fSDavid du Colombier /*
142*9a747e4fSDavid du Colombier * this used to check that all images were on the same screen.
143*9a747e4fSDavid du Colombier * we don't know the screen associated with images we acquired
144*9a747e4fSDavid du Colombier * by name. instead, check that all images are on the same display.
145*9a747e4fSDavid du Colombier * the display will check that they are all on the same screen.
146*9a747e4fSDavid du Colombier */
147*9a747e4fSDavid du Colombier d = w[0]->display;
1487dd7cddfSDavid du Colombier for(i=1; i<n; i++)
149*9a747e4fSDavid du Colombier if(w[i]->display != d){
150*9a747e4fSDavid du Colombier fprint(2, "top/bottom: windows not on same screen\n");
1517dd7cddfSDavid du Colombier return;
1527dd7cddfSDavid du Colombier }
1537dd7cddfSDavid du Colombier
154*9a747e4fSDavid du Colombier if(n==0)
1557dd7cddfSDavid du Colombier return;
156*9a747e4fSDavid du Colombier b = bufimage(d, 1+1+2+4*n);
1577dd7cddfSDavid du Colombier b[0] = 't';
1587dd7cddfSDavid du Colombier b[1] = top;
1597dd7cddfSDavid du Colombier BPSHORT(b+2, n);
1607dd7cddfSDavid du Colombier for(i=0; i<n; i++)
1617dd7cddfSDavid du Colombier BPLONG(b+4+4*i, w[i]->id);
1627dd7cddfSDavid du Colombier }
1637dd7cddfSDavid du Colombier
1647dd7cddfSDavid du Colombier void
bottomwindow(Image * w)1657dd7cddfSDavid du Colombier bottomwindow(Image *w)
1667dd7cddfSDavid du Colombier {
1677dd7cddfSDavid du Colombier if(w->screen == 0)
1687dd7cddfSDavid du Colombier return;
1697dd7cddfSDavid du Colombier topbottom(&w, 1, 0);
1707dd7cddfSDavid du Colombier }
1717dd7cddfSDavid du Colombier
1727dd7cddfSDavid du Colombier void
topwindow(Image * w)1737dd7cddfSDavid du Colombier topwindow(Image *w)
1747dd7cddfSDavid du Colombier {
1757dd7cddfSDavid du Colombier if(w->screen == 0)
1767dd7cddfSDavid du Colombier return;
1777dd7cddfSDavid du Colombier topbottom(&w, 1, 1);
1787dd7cddfSDavid du Colombier }
1797dd7cddfSDavid du Colombier
1807dd7cddfSDavid du Colombier void
bottomnwindows(Image ** w,int n)1817dd7cddfSDavid du Colombier bottomnwindows(Image **w, int n)
1827dd7cddfSDavid du Colombier {
1837dd7cddfSDavid du Colombier topbottom(w, n, 0);
1847dd7cddfSDavid du Colombier }
1857dd7cddfSDavid du Colombier
1867dd7cddfSDavid du Colombier void
topnwindows(Image ** w,int n)1877dd7cddfSDavid du Colombier topnwindows(Image **w, int n)
1887dd7cddfSDavid du Colombier {
1897dd7cddfSDavid du Colombier topbottom(w, n, 1);
1907dd7cddfSDavid du Colombier }
1917dd7cddfSDavid du Colombier
1927dd7cddfSDavid du Colombier int
originwindow(Image * w,Point log,Point scr)1937dd7cddfSDavid du Colombier originwindow(Image *w, Point log, Point scr)
1947dd7cddfSDavid du Colombier {
1957dd7cddfSDavid du Colombier uchar *b;
1967dd7cddfSDavid du Colombier Point delta;
1977dd7cddfSDavid du Colombier
1987dd7cddfSDavid du Colombier flushimage(w->display, 0);
1997dd7cddfSDavid du Colombier b = bufimage(w->display, 1+4+2*4+2*4);
2007dd7cddfSDavid du Colombier if(b == nil)
2017dd7cddfSDavid du Colombier return 0;
2027dd7cddfSDavid du Colombier b[0] = 'o';
2037dd7cddfSDavid du Colombier BPLONG(b+1, w->id);
2047dd7cddfSDavid du Colombier BPLONG(b+5, log.x);
2057dd7cddfSDavid du Colombier BPLONG(b+9, log.y);
2067dd7cddfSDavid du Colombier BPLONG(b+13, scr.x);
2077dd7cddfSDavid du Colombier BPLONG(b+17, scr.y);
2087dd7cddfSDavid du Colombier if(flushimage(w->display, 1) < 0)
2097dd7cddfSDavid du Colombier return -1;
2107dd7cddfSDavid du Colombier delta = subpt(log, w->r.min);
2117dd7cddfSDavid du Colombier w->r = rectaddpt(w->r, delta);
2127dd7cddfSDavid du Colombier w->clipr = rectaddpt(w->clipr, delta);
2137dd7cddfSDavid du Colombier return 1;
2147dd7cddfSDavid du Colombier }
215