Blob
1 #include <u.h>2 #include <libc.h>3 #include <draw.h>5 typedef struct Memimage Memimage;7 static int screenid;9 Screen*10 allocscreen(Image *image, Image *fill, int public)11 {12 uchar *a;13 Screen *s;14 int id, try;15 Display *d;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 SET(id);26 for(try=0; try<25; try++){27 /* loop until find a free id */28 a = bufimage(d, 1+4+4+4+1);29 if(a == 0){30 free(s);31 return 0;32 }33 id = ++screenid;34 a[0] = 'A';35 BPLONG(a+1, id);36 BPLONG(a+5, image->id);37 BPLONG(a+9, fill->id);38 a[13] = public;39 if(flushimage(d, 0) != -1)40 break;41 }42 s->display = d;43 s->id = id;44 s->image = image;45 assert(s->image && s->image->chan != 0);47 s->fill = fill;48 return s;49 }51 Screen*52 publicscreen(Display *d, int id, u32int chan)53 {54 uchar *a;55 Screen *s;57 s = malloc(sizeof(Screen));58 if(s == 0)59 return 0;60 a = bufimage(d, 1+4+4);61 if(a == 0){62 Error:63 free(s);64 return 0;65 }66 a[0] = 'S';67 BPLONG(a+1, id);68 BPLONG(a+5, chan);69 if(flushimage(d, 0) < 0)70 goto Error;72 s->display = d;73 s->id = id;74 s->image = 0;75 s->fill = 0;76 return s;77 }79 int80 freescreen(Screen *s)81 {82 uchar *a;83 Display *d;85 if(s == 0)86 return 0;87 d = s->display;88 a = bufimage(d, 1+4);89 if(a == 0)90 return -1;91 a[0] = 'F';92 BPLONG(a+1, s->id);93 /*94 * flush(1) because screen is likely holding last reference to95 * window, and want it to disappear visually.96 */97 if(flushimage(d, 1) < 0)98 return -1;99 free(s);100 return 1;101 }103 Image*104 allocwindow(Screen *s, Rectangle r, int ref, u32int val)105 {106 return _allocwindow(nil, s, r, ref, val);107 }109 Image*110 _allocwindow(Image *i, Screen *s, Rectangle r, int ref, u32int val)111 {112 Display *d;114 d = s->display;115 i = _allocimage(i, d, r, d->screenimage->chan, 0, val, s->id, ref);116 if(i == 0)117 return 0;118 i->screen = s;119 i->next = s->display->windows;120 s->display->windows = i;121 return i;122 }124 static125 void126 topbottom(Image **w, int n, int top)127 {128 int i;129 uchar *b;130 Display *d;132 if(n < 0){133 Ridiculous:134 fprint(2, "top/bottom: ridiculous number of windows\n");135 return;136 }137 if(n == 0)138 return;139 if(n > (w[0]->display->bufsize-100)/4)140 goto Ridiculous;141 /*142 * this used to check that all images were on the same screen.143 * we don't know the screen associated with images we acquired144 * by name. instead, check that all images are on the same display.145 * the display will check that they are all on the same screen.146 */147 d = w[0]->display;148 for(i=1; i<n; i++)149 if(w[i]->display != d){150 fprint(2, "top/bottom: windows not on same screen\n");151 return;152 }154 if(n==0)155 return;156 b = bufimage(d, 1+1+2+4*n);157 b[0] = 't';158 b[1] = top;159 BPSHORT(b+2, n);160 for(i=0; i<n; i++)161 BPLONG(b+4+4*i, w[i]->id);162 }164 void165 bottomwindow(Image *w)166 {167 if(w->screen == 0)168 return;169 topbottom(&w, 1, 0);170 }172 void173 topwindow(Image *w)174 {175 if(w->screen == 0)176 return;177 topbottom(&w, 1, 1);178 }180 void181 bottomnwindows(Image **w, int n)182 {183 topbottom(w, n, 0);184 }186 void187 topnwindows(Image **w, int n)188 {189 topbottom(w, n, 1);190 }192 int193 originwindow(Image *w, Point log, Point scr)194 {195 uchar *b;196 Point delta;198 flushimage(w->display, 0);199 b = bufimage(w->display, 1+4+2*4+2*4);200 if(b == nil)201 return 0;202 b[0] = 'o';203 BPLONG(b+1, w->id);204 BPLONG(b+5, log.x);205 BPLONG(b+9, log.y);206 BPLONG(b+13, scr.x);207 BPLONG(b+17, scr.y);208 if(flushimage(w->display, 1) < 0)209 return -1;210 delta = subpt(log, w->r.min);211 w->r = rectaddpt(w->r, delta);212 w->clipr = rectaddpt(w->clipr, delta);213 return 1;214 }