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 76193d7c 2003-09-30 devnull
5 76193d7c 2003-09-30 devnull Display *display;
6 76193d7c 2003-09-30 devnull Font *font;
7 76193d7c 2003-09-30 devnull Image *screen;
8 76193d7c 2003-09-30 devnull int _drawdebug;
9 76193d7c 2003-09-30 devnull
10 76193d7c 2003-09-30 devnull static char deffontname[] = "*default*";
11 76193d7c 2003-09-30 devnull Screen *_screen;
12 76193d7c 2003-09-30 devnull
13 b20f06ab 2004-12-26 devnull int debuglockdisplay = 1;
14 76193d7c 2003-09-30 devnull
15 abe4cd41 2005-07-27 devnull /*
16 76193d7c 2003-09-30 devnull static void
17 76193d7c 2003-09-30 devnull drawshutdown(void)
18 76193d7c 2003-09-30 devnull {
19 76193d7c 2003-09-30 devnull Display *d;
20 76193d7c 2003-09-30 devnull
21 76193d7c 2003-09-30 devnull d = display;
22 76193d7c 2003-09-30 devnull if(d){
23 76193d7c 2003-09-30 devnull display = nil;
24 76193d7c 2003-09-30 devnull closedisplay(d);
25 76193d7c 2003-09-30 devnull }
26 76193d7c 2003-09-30 devnull }
27 abe4cd41 2005-07-27 devnull */
28 76193d7c 2003-09-30 devnull
29 76193d7c 2003-09-30 devnull int
30 76193d7c 2003-09-30 devnull initdraw(void (*error)(Display*, char*), char *fontname, char *label)
31 76193d7c 2003-09-30 devnull {
32 76193d7c 2003-09-30 devnull Subfont *df;
33 76193d7c 2003-09-30 devnull char buf[128];
34 76193d7c 2003-09-30 devnull
35 dff99a80 2006-05-20 devnull rfork(RFNOTEG); /* x11-event.c will postnote hangup */
36 76193d7c 2003-09-30 devnull display = _initdisplay(error, label); /* sets screen too */
37 76193d7c 2003-09-30 devnull if(display == nil)
38 76193d7c 2003-09-30 devnull return -1;
39 76193d7c 2003-09-30 devnull
40 b20f06ab 2004-12-26 devnull lockdisplay(display);
41 670dd11a 2005-03-18 devnull display->screenimage = display->image;
42 76193d7c 2003-09-30 devnull
43 76193d7c 2003-09-30 devnull /*
44 76193d7c 2003-09-30 devnull * Set up default font
45 76193d7c 2003-09-30 devnull */
46 76193d7c 2003-09-30 devnull df = getdefont(display);
47 76193d7c 2003-09-30 devnull display->defaultsubfont = df;
48 76193d7c 2003-09-30 devnull if(df == nil){
49 76193d7c 2003-09-30 devnull fprint(2, "imageinit: can't open default subfont: %r\n");
50 76193d7c 2003-09-30 devnull Error:
51 76193d7c 2003-09-30 devnull closedisplay(display);
52 76193d7c 2003-09-30 devnull display = nil;
53 76193d7c 2003-09-30 devnull return -1;
54 76193d7c 2003-09-30 devnull }
55 76193d7c 2003-09-30 devnull if(fontname == nil)
56 76193d7c 2003-09-30 devnull fontname = getenv("font"); /* leak */
57 76193d7c 2003-09-30 devnull
58 76193d7c 2003-09-30 devnull /*
59 76193d7c 2003-09-30 devnull * Build fonts with caches==depth of screen, for speed.
60 76193d7c 2003-09-30 devnull * If conversion were faster, we'd use 0 and save memory.
61 76193d7c 2003-09-30 devnull */
62 76193d7c 2003-09-30 devnull if(fontname == nil){
63 76193d7c 2003-09-30 devnull snprint(buf, sizeof buf, "%d %d\n0 %d\t%s\n", df->height, df->ascent,
64 76193d7c 2003-09-30 devnull df->n-1, deffontname);
65 cbeb0b26 2006-04-01 devnull /*BUG: Need something better for this installsubfont("*default*", df); */
66 76193d7c 2003-09-30 devnull font = buildfont(display, buf, deffontname);
67 76193d7c 2003-09-30 devnull if(font == nil){
68 76193d7c 2003-09-30 devnull fprint(2, "initdraw: can't open default font: %r\n");
69 76193d7c 2003-09-30 devnull goto Error;
70 76193d7c 2003-09-30 devnull }
71 76193d7c 2003-09-30 devnull }else{
72 76193d7c 2003-09-30 devnull font = openfont(display, fontname); /* BUG: grey fonts */
73 76193d7c 2003-09-30 devnull if(font == nil){
74 76193d7c 2003-09-30 devnull fprint(2, "initdraw: can't open font %s: %r\n", fontname);
75 76193d7c 2003-09-30 devnull goto Error;
76 76193d7c 2003-09-30 devnull }
77 76193d7c 2003-09-30 devnull }
78 76193d7c 2003-09-30 devnull display->defaultfont = font;
79 76193d7c 2003-09-30 devnull
80 76193d7c 2003-09-30 devnull display->white = allocimage(display, Rect(0,0,1,1), GREY1, 1, DWhite);
81 76193d7c 2003-09-30 devnull display->black = allocimage(display, Rect(0,0,1,1), GREY1, 1, DBlack);
82 76193d7c 2003-09-30 devnull if(display->white == nil || display->black == nil){
83 76193d7c 2003-09-30 devnull fprint(2, "initdraw: can't allocate white and black");
84 76193d7c 2003-09-30 devnull goto Error;
85 76193d7c 2003-09-30 devnull }
86 76193d7c 2003-09-30 devnull display->opaque = display->white;
87 76193d7c 2003-09-30 devnull display->transparent = display->black;
88 670dd11a 2005-03-18 devnull
89 670dd11a 2005-03-18 devnull _screen = allocscreen(display->image, display->white, 0);
90 670dd11a 2005-03-18 devnull screen = _allocwindow(nil, _screen, display->image->r, Refnone, DWhite);
91 670dd11a 2005-03-18 devnull display->screenimage = screen;
92 7ba8aa0c 2005-07-24 devnull draw(screen, screen->r, display->white, nil, ZP);
93 670dd11a 2005-03-18 devnull flushimage(display, 1);
94 670dd11a 2005-03-18 devnull
95 abe4cd41 2005-07-27 devnull /*
96 abe4cd41 2005-07-27 devnull * I don't see any reason to go away gracefully,
97 abe4cd41 2005-07-27 devnull * and if some other proc exits holding the display
98 abe4cd41 2005-07-27 devnull * lock, this atexit call never finishes.
99 abe4cd41 2005-07-27 devnull *
100 abe4cd41 2005-07-27 devnull * atexit(drawshutdown);
101 abe4cd41 2005-07-27 devnull */
102 76193d7c 2003-09-30 devnull return 1;
103 76193d7c 2003-09-30 devnull }
104 76193d7c 2003-09-30 devnull
105 76193d7c 2003-09-30 devnull /*
106 76193d7c 2003-09-30 devnull * Call with d unlocked.
107 76193d7c 2003-09-30 devnull * Note that disp->defaultfont and defaultsubfont are not freed here.
108 76193d7c 2003-09-30 devnull */
109 76193d7c 2003-09-30 devnull void
110 76193d7c 2003-09-30 devnull closedisplay(Display *disp)
111 76193d7c 2003-09-30 devnull {
112 76193d7c 2003-09-30 devnull int fd;
113 76193d7c 2003-09-30 devnull char buf[128];
114 76193d7c 2003-09-30 devnull
115 76193d7c 2003-09-30 devnull if(disp == nil)
116 76193d7c 2003-09-30 devnull return;
117 76193d7c 2003-09-30 devnull if(disp == display)
118 76193d7c 2003-09-30 devnull display = nil;
119 76193d7c 2003-09-30 devnull if(disp->oldlabel[0]){
120 76193d7c 2003-09-30 devnull snprint(buf, sizeof buf, "%s/label", disp->windir);
121 76193d7c 2003-09-30 devnull fd = open(buf, OWRITE);
122 76193d7c 2003-09-30 devnull if(fd >= 0){
123 76193d7c 2003-09-30 devnull write(fd, disp->oldlabel, strlen(disp->oldlabel));
124 76193d7c 2003-09-30 devnull close(fd);
125 76193d7c 2003-09-30 devnull }
126 76193d7c 2003-09-30 devnull }
127 76193d7c 2003-09-30 devnull
128 76193d7c 2003-09-30 devnull free(disp->devdir);
129 76193d7c 2003-09-30 devnull free(disp->windir);
130 297cded7 2005-12-29 devnull if(disp->white)
131 297cded7 2005-12-29 devnull freeimage(disp->white);
132 297cded7 2005-12-29 devnull if(disp->black)
133 297cded7 2005-12-29 devnull freeimage(disp->black);
134 76193d7c 2003-09-30 devnull free(disp);
135 76193d7c 2003-09-30 devnull }
136 76193d7c 2003-09-30 devnull
137 76193d7c 2003-09-30 devnull void
138 76193d7c 2003-09-30 devnull lockdisplay(Display *disp)
139 76193d7c 2003-09-30 devnull {
140 76193d7c 2003-09-30 devnull if(debuglockdisplay){
141 76193d7c 2003-09-30 devnull /* avoid busy looping; it's rare we collide anyway */
142 76193d7c 2003-09-30 devnull while(!canqlock(&disp->qlock)){
143 76193d7c 2003-09-30 devnull fprint(1, "proc %d waiting for display lock...\n", getpid());
144 76193d7c 2003-09-30 devnull sleep(1000);
145 76193d7c 2003-09-30 devnull }
146 76193d7c 2003-09-30 devnull }else
147 76193d7c 2003-09-30 devnull qlock(&disp->qlock);
148 76193d7c 2003-09-30 devnull }
149 76193d7c 2003-09-30 devnull
150 76193d7c 2003-09-30 devnull void
151 76193d7c 2003-09-30 devnull unlockdisplay(Display *disp)
152 76193d7c 2003-09-30 devnull {
153 76193d7c 2003-09-30 devnull qunlock(&disp->qlock);
154 76193d7c 2003-09-30 devnull }
155 76193d7c 2003-09-30 devnull
156 76193d7c 2003-09-30 devnull void
157 76193d7c 2003-09-30 devnull drawerror(Display *d, char *s)
158 76193d7c 2003-09-30 devnull {
159 76193d7c 2003-09-30 devnull char err[ERRMAX];
160 76193d7c 2003-09-30 devnull
161 76193d7c 2003-09-30 devnull if(d->error)
162 76193d7c 2003-09-30 devnull d->error(d, s);
163 76193d7c 2003-09-30 devnull else{
164 76193d7c 2003-09-30 devnull errstr(err, sizeof err);
165 76193d7c 2003-09-30 devnull fprint(2, "draw: %s: %s\n", s, err);
166 76193d7c 2003-09-30 devnull exits(s);
167 76193d7c 2003-09-30 devnull }
168 76193d7c 2003-09-30 devnull }
169 76193d7c 2003-09-30 devnull
170 76193d7c 2003-09-30 devnull static
171 76193d7c 2003-09-30 devnull int
172 76193d7c 2003-09-30 devnull doflush(Display *d)
173 76193d7c 2003-09-30 devnull {
174 76193d7c 2003-09-30 devnull int n;
175 76193d7c 2003-09-30 devnull
176 76193d7c 2003-09-30 devnull n = d->bufp-d->buf;
177 76193d7c 2003-09-30 devnull if(n <= 0)
178 76193d7c 2003-09-30 devnull return 1;
179 76193d7c 2003-09-30 devnull
180 76193d7c 2003-09-30 devnull if(_drawmsgwrite(d, d->buf, n) != n){
181 76193d7c 2003-09-30 devnull if(_drawdebug)
182 76193d7c 2003-09-30 devnull fprint(2, "flushimage fail: d=%p: %r\n", d); /**/
183 76193d7c 2003-09-30 devnull d->bufp = d->buf; /* might as well; chance of continuing */
184 76193d7c 2003-09-30 devnull return -1;
185 76193d7c 2003-09-30 devnull }
186 76193d7c 2003-09-30 devnull d->bufp = d->buf;
187 76193d7c 2003-09-30 devnull return 1;
188 76193d7c 2003-09-30 devnull }
189 76193d7c 2003-09-30 devnull
190 76193d7c 2003-09-30 devnull int
191 76193d7c 2003-09-30 devnull flushimage(Display *d, int visible)
192 76193d7c 2003-09-30 devnull {
193 76193d7c 2003-09-30 devnull if(visible){
194 76193d7c 2003-09-30 devnull *d->bufp++ = 'v'; /* five bytes always reserved for this */
195 76193d7c 2003-09-30 devnull if(d->_isnewdisplay){
196 76193d7c 2003-09-30 devnull BPLONG(d->bufp, d->screenimage->id);
197 76193d7c 2003-09-30 devnull d->bufp += 4;
198 76193d7c 2003-09-30 devnull }
199 76193d7c 2003-09-30 devnull }
200 76193d7c 2003-09-30 devnull return doflush(d);
201 76193d7c 2003-09-30 devnull }
202 76193d7c 2003-09-30 devnull
203 76193d7c 2003-09-30 devnull uchar*
204 76193d7c 2003-09-30 devnull bufimage(Display *d, int n)
205 76193d7c 2003-09-30 devnull {
206 76193d7c 2003-09-30 devnull uchar *p;
207 76193d7c 2003-09-30 devnull
208 148f25d3 2005-11-07 devnull if(n<0 || d == nil || n>d->bufsize){
209 148f25d3 2005-11-07 devnull abort();
210 76193d7c 2003-09-30 devnull werrstr("bad count in bufimage");
211 76193d7c 2003-09-30 devnull return 0;
212 76193d7c 2003-09-30 devnull }
213 76193d7c 2003-09-30 devnull if(d->bufp+n > d->buf+d->bufsize)
214 76193d7c 2003-09-30 devnull if(doflush(d) < 0)
215 76193d7c 2003-09-30 devnull return 0;
216 76193d7c 2003-09-30 devnull p = d->bufp;
217 76193d7c 2003-09-30 devnull d->bufp += n;
218 76193d7c 2003-09-30 devnull return p;
219 76193d7c 2003-09-30 devnull }
220 76193d7c 2003-09-30 devnull