Blame


1 76193d7c 2003-09-30 devnull #include <u.h>
2 76193d7c 2003-09-30 devnull #include <libc.h>
3 76193d7c 2003-09-30 devnull #include <draw.h>
4 54bebe6a 2012-09-17 rsc #include <mouse.h>
5 76193d7c 2003-09-30 devnull
6 76193d7c 2003-09-30 devnull Display *display;
7 76193d7c 2003-09-30 devnull Font *font;
8 76193d7c 2003-09-30 devnull Image *screen;
9 76193d7c 2003-09-30 devnull int _drawdebug;
10 76193d7c 2003-09-30 devnull
11 76193d7c 2003-09-30 devnull static char deffontname[] = "*default*";
12 76193d7c 2003-09-30 devnull Screen *_screen;
13 76193d7c 2003-09-30 devnull
14 b20f06ab 2004-12-26 devnull int debuglockdisplay = 1;
15 74dc60da 2006-06-25 devnull char *winsize;
16 76193d7c 2003-09-30 devnull
17 54bebe6a 2012-09-17 rsc int visibleclicks = 0;
18 54bebe6a 2012-09-17 rsc Image *mousebuttons;
19 54bebe6a 2012-09-17 rsc Image *mousesave;
20 54bebe6a 2012-09-17 rsc Mouse _drawmouse;
21 54bebe6a 2012-09-17 rsc
22 9e0d3750 2017-01-06 rsc void
23 9e0d3750 2017-01-06 rsc needdisplay(void)
24 9e0d3750 2017-01-06 rsc {
25 9e0d3750 2017-01-06 rsc }
26 9e0d3750 2017-01-06 rsc
27 abe4cd41 2005-07-27 devnull /*
28 76193d7c 2003-09-30 devnull static void
29 76193d7c 2003-09-30 devnull drawshutdown(void)
30 76193d7c 2003-09-30 devnull {
31 76193d7c 2003-09-30 devnull Display *d;
32 76193d7c 2003-09-30 devnull
33 76193d7c 2003-09-30 devnull d = display;
34 76193d7c 2003-09-30 devnull if(d){
35 76193d7c 2003-09-30 devnull display = nil;
36 76193d7c 2003-09-30 devnull closedisplay(d);
37 76193d7c 2003-09-30 devnull }
38 76193d7c 2003-09-30 devnull }
39 abe4cd41 2005-07-27 devnull */
40 76193d7c 2003-09-30 devnull
41 76193d7c 2003-09-30 devnull int
42 74dc60da 2006-06-25 devnull geninitdraw(char *devdir, void(*error)(Display*, char*), char *fontname, char *label, char *windir, int ref)
43 76193d7c 2003-09-30 devnull {
44 76193d7c 2003-09-30 devnull Subfont *df;
45 54bebe6a 2012-09-17 rsc char buf[128], *p;
46 76193d7c 2003-09-30 devnull
47 74dc60da 2006-06-25 devnull if(label == nil)
48 74dc60da 2006-06-25 devnull label = argv0;
49 74dc60da 2006-06-25 devnull display = _initdisplay(error, label);
50 76193d7c 2003-09-30 devnull if(display == nil)
51 76193d7c 2003-09-30 devnull return -1;
52 76193d7c 2003-09-30 devnull
53 76193d7c 2003-09-30 devnull /*
54 76193d7c 2003-09-30 devnull * Set up default font
55 76193d7c 2003-09-30 devnull */
56 76193d7c 2003-09-30 devnull df = getdefont(display);
57 76193d7c 2003-09-30 devnull display->defaultsubfont = df;
58 76193d7c 2003-09-30 devnull if(df == nil){
59 76193d7c 2003-09-30 devnull fprint(2, "imageinit: can't open default subfont: %r\n");
60 76193d7c 2003-09-30 devnull Error:
61 76193d7c 2003-09-30 devnull closedisplay(display);
62 76193d7c 2003-09-30 devnull display = nil;
63 76193d7c 2003-09-30 devnull return -1;
64 76193d7c 2003-09-30 devnull }
65 76193d7c 2003-09-30 devnull if(fontname == nil)
66 74dc60da 2006-06-25 devnull fontname = getenv("font");
67 76193d7c 2003-09-30 devnull
68 76193d7c 2003-09-30 devnull /*
69 76193d7c 2003-09-30 devnull * Build fonts with caches==depth of screen, for speed.
70 76193d7c 2003-09-30 devnull * If conversion were faster, we'd use 0 and save memory.
71 76193d7c 2003-09-30 devnull */
72 76193d7c 2003-09-30 devnull if(fontname == nil){
73 76193d7c 2003-09-30 devnull snprint(buf, sizeof buf, "%d %d\n0 %d\t%s\n", df->height, df->ascent,
74 76193d7c 2003-09-30 devnull df->n-1, deffontname);
75 74dc60da 2006-06-25 devnull //BUG: Need something better for this installsubfont("*default*", df);
76 76193d7c 2003-09-30 devnull font = buildfont(display, buf, deffontname);
77 76193d7c 2003-09-30 devnull if(font == nil){
78 74dc60da 2006-06-25 devnull fprint(2, "imageinit: can't open default font: %r\n");
79 76193d7c 2003-09-30 devnull goto Error;
80 76193d7c 2003-09-30 devnull }
81 76193d7c 2003-09-30 devnull }else{
82 76193d7c 2003-09-30 devnull font = openfont(display, fontname); /* BUG: grey fonts */
83 76193d7c 2003-09-30 devnull if(font == nil){
84 74dc60da 2006-06-25 devnull fprint(2, "imageinit: can't open font %s: %r\n", fontname);
85 76193d7c 2003-09-30 devnull goto Error;
86 76193d7c 2003-09-30 devnull }
87 76193d7c 2003-09-30 devnull }
88 76193d7c 2003-09-30 devnull display->defaultfont = font;
89 76193d7c 2003-09-30 devnull
90 670dd11a 2005-03-18 devnull _screen = allocscreen(display->image, display->white, 0);
91 74dc60da 2006-06-25 devnull display->screenimage = display->image; /* _allocwindow wants screenimage->chan */
92 670dd11a 2005-03-18 devnull screen = _allocwindow(nil, _screen, display->image->r, Refnone, DWhite);
93 74dc60da 2006-06-25 devnull if(screen == nil){
94 74dc60da 2006-06-25 devnull fprint(2, "_allocwindow: %r\n");
95 74dc60da 2006-06-25 devnull goto Error;
96 74dc60da 2006-06-25 devnull }
97 670dd11a 2005-03-18 devnull display->screenimage = screen;
98 7ba8aa0c 2005-07-24 devnull draw(screen, screen->r, display->white, nil, ZP);
99 670dd11a 2005-03-18 devnull flushimage(display, 1);
100 670dd11a 2005-03-18 devnull
101 54bebe6a 2012-09-17 rsc p = getenv("visibleclicks");
102 54bebe6a 2012-09-17 rsc visibleclicks = p != nil && *p == '1';
103 54bebe6a 2012-09-17 rsc if(visibleclicks) {
104 54bebe6a 2012-09-17 rsc Font *f;
105 54bebe6a 2012-09-17 rsc
106 54bebe6a 2012-09-17 rsc f = display->defaultfont;
107 54bebe6a 2012-09-17 rsc mousebuttons = allocimage(display, Rect(0,0,64,22), screen->chan, 0, DWhite);
108 54bebe6a 2012-09-17 rsc border(mousebuttons, mousebuttons->r, 1, display->black, ZP);
109 54bebe6a 2012-09-17 rsc border(mousebuttons, Rect(0, 0, 22, 22), 1, display->black, ZP);
110 54bebe6a 2012-09-17 rsc border(mousebuttons, Rect(42, 0, 64, 22), 1, display->black, ZP);
111 54bebe6a 2012-09-17 rsc string(mousebuttons, Pt(10-stringwidth(display->defaultfont, "1")/2, 11-f->height/2), display->black, ZP, display->defaultfont, "1");
112 54bebe6a 2012-09-17 rsc string(mousebuttons, Pt(21+10-stringwidth(display->defaultfont, "2")/2, 11-f->height/2), display->black, ZP, display->defaultfont, "2");
113 54bebe6a 2012-09-17 rsc string(mousebuttons, Pt(42+10-stringwidth(display->defaultfont, "3")/2, 11-f->height/2), display->black, ZP, display->defaultfont, "3");
114 54bebe6a 2012-09-17 rsc mousesave = allocimage(display, Rect(0,0,64,22), screen->chan, 0, 0);
115 54bebe6a 2012-09-17 rsc }
116 54bebe6a 2012-09-17 rsc
117 abe4cd41 2005-07-27 devnull /*
118 abe4cd41 2005-07-27 devnull * I don't see any reason to go away gracefully,
119 abe4cd41 2005-07-27 devnull * and if some other proc exits holding the display
120 abe4cd41 2005-07-27 devnull * lock, this atexit call never finishes.
121 abe4cd41 2005-07-27 devnull *
122 abe4cd41 2005-07-27 devnull * atexit(drawshutdown);
123 abe4cd41 2005-07-27 devnull */
124 76193d7c 2003-09-30 devnull return 1;
125 74dc60da 2006-06-25 devnull }
126 74dc60da 2006-06-25 devnull
127 74dc60da 2006-06-25 devnull int
128 74dc60da 2006-06-25 devnull initdraw(void (*error)(Display*, char*), char *fontname, char *label)
129 74dc60da 2006-06-25 devnull {
130 74dc60da 2006-06-25 devnull return geninitdraw("/dev", error, fontname, label, "/dev", Refnone);
131 74dc60da 2006-06-25 devnull }
132 74dc60da 2006-06-25 devnull
133 74dc60da 2006-06-25 devnull extern int _freeimage1(Image*);
134 74dc60da 2006-06-25 devnull
135 74dc60da 2006-06-25 devnull static Image*
136 74dc60da 2006-06-25 devnull getimage0(Display *d, Image *image)
137 74dc60da 2006-06-25 devnull {
138 74dc60da 2006-06-25 devnull char info[12*12+1];
139 74dc60da 2006-06-25 devnull uchar *a;
140 74dc60da 2006-06-25 devnull int n;
141 74dc60da 2006-06-25 devnull
142 74dc60da 2006-06-25 devnull /*
143 74dc60da 2006-06-25 devnull * If there's an old screen, it has id 0. The 'J' request below
144 74dc60da 2006-06-25 devnull * will try to install the new screen as id 0, so the old one
145 74dc60da 2006-06-25 devnull * must be freed first.
146 74dc60da 2006-06-25 devnull */
147 74dc60da 2006-06-25 devnull if(image){
148 74dc60da 2006-06-25 devnull _freeimage1(image);
149 74dc60da 2006-06-25 devnull memset(image, 0, sizeof(Image));
150 74dc60da 2006-06-25 devnull }
151 74dc60da 2006-06-25 devnull
152 74dc60da 2006-06-25 devnull a = bufimage(d, 2);
153 74dc60da 2006-06-25 devnull a[0] = 'J';
154 74dc60da 2006-06-25 devnull a[1] = 'I';
155 74dc60da 2006-06-25 devnull if(flushimage(d, 0) < 0){
156 74dc60da 2006-06-25 devnull fprint(2, "cannot read screen info: %r\n");
157 74dc60da 2006-06-25 devnull return nil;
158 74dc60da 2006-06-25 devnull }
159 74dc60da 2006-06-25 devnull
160 74dc60da 2006-06-25 devnull n = _displayrddraw(d, info, sizeof info);
161 74dc60da 2006-06-25 devnull if(n != 12*12){
162 74dc60da 2006-06-25 devnull fprint(2, "short screen info\n");
163 74dc60da 2006-06-25 devnull return nil;
164 74dc60da 2006-06-25 devnull }
165 74dc60da 2006-06-25 devnull
166 74dc60da 2006-06-25 devnull if(image == nil){
167 74dc60da 2006-06-25 devnull image = mallocz(sizeof(Image), 1);
168 74dc60da 2006-06-25 devnull if(image == nil){
169 74dc60da 2006-06-25 devnull fprint(2, "cannot allocate image: %r\n");
170 74dc60da 2006-06-25 devnull return nil;
171 74dc60da 2006-06-25 devnull }
172 74dc60da 2006-06-25 devnull }
173 74dc60da 2006-06-25 devnull
174 74dc60da 2006-06-25 devnull image->display = d;
175 74dc60da 2006-06-25 devnull image->id = 0;
176 74dc60da 2006-06-25 devnull image->chan = strtochan(info+2*12);
177 74dc60da 2006-06-25 devnull image->depth = chantodepth(image->chan);
178 74dc60da 2006-06-25 devnull image->repl = atoi(info+3*12);
179 74dc60da 2006-06-25 devnull image->r.min.x = atoi(info+4*12);
180 74dc60da 2006-06-25 devnull image->r.min.y = atoi(info+5*12);
181 74dc60da 2006-06-25 devnull image->r.max.x = atoi(info+6*12);
182 74dc60da 2006-06-25 devnull image->r.max.y = atoi(info+7*12);
183 74dc60da 2006-06-25 devnull image->clipr.min.x = atoi(info+8*12);
184 74dc60da 2006-06-25 devnull image->clipr.min.y = atoi(info+9*12);
185 74dc60da 2006-06-25 devnull image->clipr.max.x = atoi(info+10*12);
186 74dc60da 2006-06-25 devnull image->clipr.max.y = atoi(info+11*12);
187 d0e07019 2012-11-26 rsc
188 d0e07019 2012-11-26 rsc a = bufimage(d, 3);
189 d0e07019 2012-11-26 rsc a[0] = 'q';
190 d0e07019 2012-11-26 rsc a[1] = 1;
191 d0e07019 2012-11-26 rsc a[2] = 'd';
192 d0e07019 2012-11-26 rsc d->dpi = 100;
193 d0e07019 2012-11-26 rsc if(flushimage(d, 0) >= 0 && _displayrddraw(d, info, 12) == 12)
194 d0e07019 2012-11-26 rsc d->dpi = atoi(info);
195 d0e07019 2012-11-26 rsc
196 74dc60da 2006-06-25 devnull return image;
197 74dc60da 2006-06-25 devnull }
198 74dc60da 2006-06-25 devnull
199 74dc60da 2006-06-25 devnull /*
200 74dc60da 2006-06-25 devnull * Attach, or possibly reattach, to window.
201 74dc60da 2006-06-25 devnull * If reattaching, maintain value of screen pointer.
202 74dc60da 2006-06-25 devnull */
203 74dc60da 2006-06-25 devnull int
204 74dc60da 2006-06-25 devnull getwindow(Display *d, int ref)
205 74dc60da 2006-06-25 devnull {
206 74dc60da 2006-06-25 devnull Image *i, *oi;
207 213fc4f6 2015-02-17 rsc Font *f;
208 74dc60da 2006-06-25 devnull
209 74dc60da 2006-06-25 devnull /* XXX check for destroyed? */
210 74dc60da 2006-06-25 devnull
211 74dc60da 2006-06-25 devnull /*
212 74dc60da 2006-06-25 devnull * Libdraw promises not to change the value of "screen",
213 74dc60da 2006-06-25 devnull * so we have to reuse the image structure
214 74dc60da 2006-06-25 devnull * memory we already have.
215 74dc60da 2006-06-25 devnull */
216 74dc60da 2006-06-25 devnull oi = d->image;
217 74dc60da 2006-06-25 devnull i = getimage0(d, oi);
218 74dc60da 2006-06-25 devnull if(i == nil)
219 74dc60da 2006-06-25 devnull sysfatal("getwindow failed");
220 74dc60da 2006-06-25 devnull d->image = i;
221 74dc60da 2006-06-25 devnull /* fprint(2, "getwindow %p -> %p\n", oi, i); */
222 74dc60da 2006-06-25 devnull
223 74dc60da 2006-06-25 devnull freescreen(_screen);
224 74dc60da 2006-06-25 devnull _screen = allocscreen(i, d->white, 0);
225 74dc60da 2006-06-25 devnull _freeimage1(screen);
226 74dc60da 2006-06-25 devnull screen = _allocwindow(screen, _screen, i->r, ref, DWhite);
227 74dc60da 2006-06-25 devnull d->screenimage = screen;
228 213fc4f6 2015-02-17 rsc
229 213fc4f6 2015-02-17 rsc
230 213fc4f6 2015-02-17 rsc if(d->dpi >= DefaultDPI*3/2) {
231 213fc4f6 2015-02-17 rsc for(f=d->firstfont; f != nil; f=f->next)
232 213fc4f6 2015-02-17 rsc loadhidpi(f);
233 213fc4f6 2015-02-17 rsc } else {
234 213fc4f6 2015-02-17 rsc for(f=d->firstfont; f != nil; f=f->next)
235 213fc4f6 2015-02-17 rsc if(f->lodpi != nil && f->lodpi != f)
236 213fc4f6 2015-02-17 rsc swapfont(f, &f->hidpi, &f->lodpi);
237 213fc4f6 2015-02-17 rsc }
238 213fc4f6 2015-02-17 rsc
239 74dc60da 2006-06-25 devnull return 0;
240 76193d7c 2003-09-30 devnull }
241 76193d7c 2003-09-30 devnull
242 74dc60da 2006-06-25 devnull Display*
243 74dc60da 2006-06-25 devnull _initdisplay(void (*error)(Display*, char*), char *label)
244 74dc60da 2006-06-25 devnull {
245 74dc60da 2006-06-25 devnull Display *disp;
246 74dc60da 2006-06-25 devnull Image *image;
247 74dc60da 2006-06-25 devnull
248 74dc60da 2006-06-25 devnull fmtinstall('P', Pfmt);
249 74dc60da 2006-06-25 devnull fmtinstall('R', Rfmt);
250 74dc60da 2006-06-25 devnull
251 74dc60da 2006-06-25 devnull disp = mallocz(sizeof(Display), 1);
252 74dc60da 2006-06-25 devnull if(disp == nil){
253 74dc60da 2006-06-25 devnull Error1:
254 74dc60da 2006-06-25 devnull return nil;
255 74dc60da 2006-06-25 devnull }
256 74dc60da 2006-06-25 devnull disp->srvfd = -1;
257 74dc60da 2006-06-25 devnull image = nil;
258 74dc60da 2006-06-25 devnull if(0){
259 74dc60da 2006-06-25 devnull Error2:
260 74dc60da 2006-06-25 devnull free(image);
261 74dc60da 2006-06-25 devnull free(disp);
262 74dc60da 2006-06-25 devnull goto Error1;
263 74dc60da 2006-06-25 devnull }
264 74dc60da 2006-06-25 devnull disp->bufsize = 65500;
265 74dc60da 2006-06-25 devnull disp->buf = malloc(disp->bufsize+5); /* +5 for flush message */
266 74dc60da 2006-06-25 devnull disp->bufp = disp->buf;
267 74dc60da 2006-06-25 devnull disp->error = error;
268 74dc60da 2006-06-25 devnull qlock(&disp->qlock);
269 74dc60da 2006-06-25 devnull
270 74dc60da 2006-06-25 devnull if(disp->buf == nil)
271 74dc60da 2006-06-25 devnull goto Error2;
272 74dc60da 2006-06-25 devnull if(0){
273 74dc60da 2006-06-25 devnull Error3:
274 74dc60da 2006-06-25 devnull free(disp->buf);
275 74dc60da 2006-06-25 devnull goto Error2;
276 74dc60da 2006-06-25 devnull }
277 74dc60da 2006-06-25 devnull
278 74dc60da 2006-06-25 devnull if(_displaymux(disp) < 0
279 74dc60da 2006-06-25 devnull || _displayconnect(disp) < 0
280 74dc60da 2006-06-25 devnull || _displayinit(disp, label, winsize) < 0)
281 74dc60da 2006-06-25 devnull goto Error3;
282 74dc60da 2006-06-25 devnull if(0){
283 74dc60da 2006-06-25 devnull Error4:
284 74dc60da 2006-06-25 devnull close(disp->srvfd);
285 74dc60da 2006-06-25 devnull goto Error3;
286 74dc60da 2006-06-25 devnull }
287 74dc60da 2006-06-25 devnull
288 74dc60da 2006-06-25 devnull image = getimage0(disp, nil);
289 74dc60da 2006-06-25 devnull if(image == nil)
290 74dc60da 2006-06-25 devnull goto Error4;
291 74dc60da 2006-06-25 devnull
292 74dc60da 2006-06-25 devnull disp->image = image;
293 74dc60da 2006-06-25 devnull disp->white = allocimage(disp, Rect(0, 0, 1, 1), GREY1, 1, DWhite);
294 74dc60da 2006-06-25 devnull disp->black = allocimage(disp, Rect(0, 0, 1, 1), GREY1, 1, DBlack);
295 74dc60da 2006-06-25 devnull if(disp->white == nil || disp->black == nil){
296 74dc60da 2006-06-25 devnull free(disp->white);
297 74dc60da 2006-06-25 devnull free(disp->black);
298 74dc60da 2006-06-25 devnull goto Error4;
299 74dc60da 2006-06-25 devnull }
300 74dc60da 2006-06-25 devnull
301 74dc60da 2006-06-25 devnull disp->opaque = disp->white;
302 74dc60da 2006-06-25 devnull disp->transparent = disp->black;
303 74dc60da 2006-06-25 devnull
304 74dc60da 2006-06-25 devnull return disp;
305 74dc60da 2006-06-25 devnull }
306 74dc60da 2006-06-25 devnull
307 76193d7c 2003-09-30 devnull /*
308 76193d7c 2003-09-30 devnull * Call with d unlocked.
309 76193d7c 2003-09-30 devnull * Note that disp->defaultfont and defaultsubfont are not freed here.
310 76193d7c 2003-09-30 devnull */
311 76193d7c 2003-09-30 devnull void
312 76193d7c 2003-09-30 devnull closedisplay(Display *disp)
313 76193d7c 2003-09-30 devnull {
314 76193d7c 2003-09-30 devnull int fd;
315 76193d7c 2003-09-30 devnull char buf[128];
316 76193d7c 2003-09-30 devnull
317 76193d7c 2003-09-30 devnull if(disp == nil)
318 76193d7c 2003-09-30 devnull return;
319 76193d7c 2003-09-30 devnull if(disp == display)
320 76193d7c 2003-09-30 devnull display = nil;
321 76193d7c 2003-09-30 devnull if(disp->oldlabel[0]){
322 76193d7c 2003-09-30 devnull snprint(buf, sizeof buf, "%s/label", disp->windir);
323 76193d7c 2003-09-30 devnull fd = open(buf, OWRITE);
324 76193d7c 2003-09-30 devnull if(fd >= 0){
325 76193d7c 2003-09-30 devnull write(fd, disp->oldlabel, strlen(disp->oldlabel));
326 76193d7c 2003-09-30 devnull close(fd);
327 76193d7c 2003-09-30 devnull }
328 76193d7c 2003-09-30 devnull }
329 76193d7c 2003-09-30 devnull
330 76193d7c 2003-09-30 devnull free(disp->devdir);
331 76193d7c 2003-09-30 devnull free(disp->windir);
332 297cded7 2005-12-29 devnull if(disp->white)
333 297cded7 2005-12-29 devnull freeimage(disp->white);
334 297cded7 2005-12-29 devnull if(disp->black)
335 297cded7 2005-12-29 devnull freeimage(disp->black);
336 74dc60da 2006-06-25 devnull if(disp->srvfd >= 0)
337 74dc60da 2006-06-25 devnull close(disp->srvfd);
338 76193d7c 2003-09-30 devnull free(disp);
339 76193d7c 2003-09-30 devnull }
340 76193d7c 2003-09-30 devnull
341 76193d7c 2003-09-30 devnull void
342 76193d7c 2003-09-30 devnull lockdisplay(Display *disp)
343 76193d7c 2003-09-30 devnull {
344 76193d7c 2003-09-30 devnull if(debuglockdisplay){
345 76193d7c 2003-09-30 devnull /* avoid busy looping; it's rare we collide anyway */
346 76193d7c 2003-09-30 devnull while(!canqlock(&disp->qlock)){
347 76193d7c 2003-09-30 devnull fprint(1, "proc %d waiting for display lock...\n", getpid());
348 76193d7c 2003-09-30 devnull sleep(1000);
349 76193d7c 2003-09-30 devnull }
350 76193d7c 2003-09-30 devnull }else
351 76193d7c 2003-09-30 devnull qlock(&disp->qlock);
352 76193d7c 2003-09-30 devnull }
353 76193d7c 2003-09-30 devnull
354 76193d7c 2003-09-30 devnull void
355 76193d7c 2003-09-30 devnull unlockdisplay(Display *disp)
356 76193d7c 2003-09-30 devnull {
357 76193d7c 2003-09-30 devnull qunlock(&disp->qlock);
358 76193d7c 2003-09-30 devnull }
359 76193d7c 2003-09-30 devnull
360 76193d7c 2003-09-30 devnull void
361 76193d7c 2003-09-30 devnull drawerror(Display *d, char *s)
362 76193d7c 2003-09-30 devnull {
363 76193d7c 2003-09-30 devnull char err[ERRMAX];
364 76193d7c 2003-09-30 devnull
365 76193d7c 2003-09-30 devnull if(d->error)
366 76193d7c 2003-09-30 devnull d->error(d, s);
367 76193d7c 2003-09-30 devnull else{
368 76193d7c 2003-09-30 devnull errstr(err, sizeof err);
369 76193d7c 2003-09-30 devnull fprint(2, "draw: %s: %s\n", s, err);
370 76193d7c 2003-09-30 devnull exits(s);
371 76193d7c 2003-09-30 devnull }
372 76193d7c 2003-09-30 devnull }
373 76193d7c 2003-09-30 devnull
374 76193d7c 2003-09-30 devnull static
375 76193d7c 2003-09-30 devnull int
376 76193d7c 2003-09-30 devnull doflush(Display *d)
377 76193d7c 2003-09-30 devnull {
378 76193d7c 2003-09-30 devnull int n;
379 76193d7c 2003-09-30 devnull
380 76193d7c 2003-09-30 devnull n = d->bufp-d->buf;
381 76193d7c 2003-09-30 devnull if(n <= 0)
382 76193d7c 2003-09-30 devnull return 1;
383 76193d7c 2003-09-30 devnull
384 74dc60da 2006-06-25 devnull if(_displaywrdraw(d, d->buf, n) != n){
385 76193d7c 2003-09-30 devnull if(_drawdebug)
386 76193d7c 2003-09-30 devnull fprint(2, "flushimage fail: d=%p: %r\n", d); /**/
387 76193d7c 2003-09-30 devnull d->bufp = d->buf; /* might as well; chance of continuing */
388 76193d7c 2003-09-30 devnull return -1;
389 76193d7c 2003-09-30 devnull }
390 76193d7c 2003-09-30 devnull d->bufp = d->buf;
391 76193d7c 2003-09-30 devnull return 1;
392 76193d7c 2003-09-30 devnull }
393 76193d7c 2003-09-30 devnull
394 76193d7c 2003-09-30 devnull int
395 76193d7c 2003-09-30 devnull flushimage(Display *d, int visible)
396 76193d7c 2003-09-30 devnull {
397 54bebe6a 2012-09-17 rsc if(visible == 1 && visibleclicks && mousebuttons && _drawmouse.buttons) {
398 54bebe6a 2012-09-17 rsc Rectangle r, r1;
399 54bebe6a 2012-09-17 rsc int ret;
400 54bebe6a 2012-09-17 rsc
401 54bebe6a 2012-09-17 rsc r = mousebuttons->r;
402 54bebe6a 2012-09-17 rsc r = rectaddpt(r, _drawmouse.xy);
403 54bebe6a 2012-09-17 rsc r = rectaddpt(r, Pt(-Dx(mousebuttons->r)/2, -Dy(mousebuttons->r)-3));
404 54bebe6a 2012-09-17 rsc drawop(mousesave, mousesave->r, screen, nil, r.min, S);
405 54bebe6a 2012-09-17 rsc
406 54bebe6a 2012-09-17 rsc r1 = rectaddpt(Rect(0, 0, 22, 22), r.min);
407 54bebe6a 2012-09-17 rsc if(_drawmouse.buttons & 1)
408 54bebe6a 2012-09-17 rsc drawop(screen, r1, mousebuttons, nil, ZP, S);
409 54bebe6a 2012-09-17 rsc r1 = rectaddpt(r1, Pt(21, 0));
410 54bebe6a 2012-09-17 rsc if(_drawmouse.buttons & 2)
411 54bebe6a 2012-09-17 rsc drawop(screen, r1, mousebuttons, nil, Pt(21, 0), S);
412 54bebe6a 2012-09-17 rsc r1 = rectaddpt(r1, Pt(21, 0));
413 54bebe6a 2012-09-17 rsc if(_drawmouse.buttons & 4)
414 54bebe6a 2012-09-17 rsc drawop(screen, r1, mousebuttons, nil, Pt(42, 0), S);
415 54bebe6a 2012-09-17 rsc ret = flushimage(d, 2);
416 54bebe6a 2012-09-17 rsc drawop(screen, r, mousesave, nil, ZP, S);
417 54bebe6a 2012-09-17 rsc return ret;
418 54bebe6a 2012-09-17 rsc }
419 54bebe6a 2012-09-17 rsc
420 76193d7c 2003-09-30 devnull if(visible){
421 76193d7c 2003-09-30 devnull *d->bufp++ = 'v'; /* five bytes always reserved for this */
422 76193d7c 2003-09-30 devnull if(d->_isnewdisplay){
423 76193d7c 2003-09-30 devnull BPLONG(d->bufp, d->screenimage->id);
424 76193d7c 2003-09-30 devnull d->bufp += 4;
425 76193d7c 2003-09-30 devnull }
426 76193d7c 2003-09-30 devnull }
427 76193d7c 2003-09-30 devnull return doflush(d);
428 76193d7c 2003-09-30 devnull }
429 76193d7c 2003-09-30 devnull
430 76193d7c 2003-09-30 devnull uchar*
431 76193d7c 2003-09-30 devnull bufimage(Display *d, int n)
432 76193d7c 2003-09-30 devnull {
433 76193d7c 2003-09-30 devnull uchar *p;
434 76193d7c 2003-09-30 devnull
435 148f25d3 2005-11-07 devnull if(n<0 || d == nil || n>d->bufsize){
436 148f25d3 2005-11-07 devnull abort();
437 76193d7c 2003-09-30 devnull werrstr("bad count in bufimage");
438 76193d7c 2003-09-30 devnull return 0;
439 76193d7c 2003-09-30 devnull }
440 76193d7c 2003-09-30 devnull if(d->bufp+n > d->buf+d->bufsize)
441 76193d7c 2003-09-30 devnull if(doflush(d) < 0)
442 76193d7c 2003-09-30 devnull return 0;
443 76193d7c 2003-09-30 devnull p = d->bufp;
444 76193d7c 2003-09-30 devnull d->bufp += n;
445 76193d7c 2003-09-30 devnull return p;
446 76193d7c 2003-09-30 devnull }
447 76193d7c 2003-09-30 devnull
448 9f385187 2012-11-26 rsc int
449 9f385187 2012-11-26 rsc scalesize(Display *d, int n)
450 9f385187 2012-11-26 rsc {
451 9f385187 2012-11-26 rsc if(d == nil || d->dpi <= DefaultDPI)
452 9f385187 2012-11-26 rsc return n;
453 9f385187 2012-11-26 rsc return (n*d->dpi+DefaultDPI/2)/DefaultDPI;
454 9f385187 2012-11-26 rsc }