]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/bcm/screen.c
devdraw: get rid of softscreen==0xa110c hack and make attachscreen() return Memdata*
[plan9front.git] / sys / src / 9 / bcm / screen.c
1 /*
2  * bcm2385 framebuffer
3  */
4
5 #include "u.h"
6 #include "../port/lib.h"
7 #include "mem.h"
8 #include "dat.h"
9 #include "fns.h"
10
11 #define Image   IMAGE
12 #include <draw.h>
13 #include <memdraw.h>
14 #include <cursor.h>
15 #include "screen.h"
16
17 enum {
18         Tabstop         = 4,
19         Scroll          = 8,
20         Wid             = 1024,
21         Ht              = 768,
22         Depth           = 16,
23 };
24
25 Memimage *gscreen;
26
27 static Memdata xgdata;
28
29 static Memimage xgscreen =
30 {
31         { 0, 0, Wid, Ht },      /* r */
32         { 0, 0, Wid, Ht },      /* clipr */
33         Depth,                  /* depth */
34         3,                      /* nchan */
35         RGB16,                  /* chan */
36         nil,                    /* cmap */
37         &xgdata,                /* data */
38         0,                      /* zero */
39         0,                      /* width in words of a single scan line */
40         0,                      /* layer */
41         0,                      /* flags */
42 };
43
44 static Memimage *conscol;
45 static Memimage *back;
46 static Memsubfont *memdefont;
47
48 static Lock screenlock;
49
50 static Point    curpos;
51 static int      h, w;
52 static Rectangle window;
53
54 static void myscreenputs(char *s, int n);
55 static void screenputc(char *buf);
56 static void screenwin(void);
57
58 void
59 cursoron(void)
60 {
61         qlock(&drawlock);
62         lock(&cursor);
63         swcursorhide();
64         swcursordraw(mousexy());
65         unlock(&cursor);
66         qunlock(&drawlock);
67 }
68
69 void
70 cursoroff(void)
71 {
72         qlock(&drawlock);
73         lock(&cursor);
74         swcursorhide();
75         unlock(&cursor);
76         qunlock(&drawlock);
77 }
78
79 /* called from devmouse */
80 void
81 setcursor(Cursor* curs)
82 {
83         swcursorload(curs);
84 }
85
86 int
87 hwdraw(Memdrawparam *par)
88 {
89         Memimage *dst, *src, *mask;
90
91         if((dst=par->dst) == nil || dst->data == nil)
92                 return 0;
93         if((src=par->src) == nil || src->data == nil)
94                 return 0;
95         if((mask=par->mask) == nil || mask->data == nil)
96                 return 0;
97
98         if(dst->data->bdata == xgdata.bdata)
99                 swcursoravoid(par->r);
100         if(src->data->bdata == xgdata.bdata)
101                 swcursoravoid(par->sr);
102         if(mask->data->bdata == xgdata.bdata)
103                 swcursoravoid(par->mr);
104
105         return 0;
106 }
107
108 static int
109 screensize(void)
110 {
111         char *p;
112         char *f[3];
113         int width, height, depth;
114
115         p = getconf("vgasize");
116         if(p == nil || getfields(p, f, nelem(f), 0, "x") != nelem(f) ||
117             (width = atoi(f[0])) < 16 || (height = atoi(f[1])) <= 0 ||
118             (depth = atoi(f[2])) <= 0)
119                 return -1;
120         xgscreen.r.max = Pt(width, height);
121         xgscreen.depth = depth;
122         return 0;
123 }
124
125 void
126 screeninit(void)
127 {
128         uchar *fb;
129         int set;
130         ulong chan;
131
132         set = screensize() == 0;
133         fb = fbinit(set, &xgscreen.r.max.x, &xgscreen.r.max.y, &xgscreen.depth);
134         if(fb == nil){
135                 print("can't initialise %dx%dx%d framebuffer \n",
136                         xgscreen.r.max.x, xgscreen.r.max.y, xgscreen.depth);
137                 return;
138         }
139         xgscreen.clipr = xgscreen.r;
140         switch(xgscreen.depth){
141         default:
142                 print("unsupported screen depth %d\n", xgscreen.depth);
143                 xgscreen.depth = 16;
144                 /* fall through */
145         case 16:
146                 chan = RGB16;
147                 break;
148         case 24:
149                 chan = BGR24;
150                 break;
151         case 32:
152                 chan = ARGB32;
153                 break;
154         }
155         memsetchan(&xgscreen, chan);
156         conf.monitor = 1;
157         xgdata.bdata = fb;
158         xgdata.ref = 1;
159         gscreen = &xgscreen;
160         gscreen->width = wordsperline(gscreen->r, gscreen->depth);
161
162         memimageinit();
163         memdefont = getmemdefont();
164         screenwin();
165         screenputs = myscreenputs;
166         swcursorinit();
167 }
168
169 void
170 flushmemscreen(Rectangle)
171 {
172 }
173
174 Memdata*
175 attachscreen(Rectangle *r, ulong *chan, int* d, int *width, int *softscreen)
176 {
177         if(gscreen == nil)
178                 return nil;
179
180         *r = gscreen->r;
181         *d = gscreen->depth;
182         *chan = gscreen->chan;
183         *width = gscreen->width;
184         *softscreen = 0;
185
186         gscreen->data->ref++;
187         return gscreen->data;
188 }
189
190 void
191 getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb)
192 {
193         USED(p, pr, pg, pb);
194 }
195
196 int
197 setcolor(ulong p, ulong r, ulong g, ulong b)
198 {
199         USED(p, r, g, b);
200         return 0;
201 }
202
203 void
204 blankscreen(int blank)
205 {
206         fbblank(blank);
207 }
208
209 static void
210 myscreenputs(char *s, int n)
211 {
212         int i;
213         Rune r;
214         char buf[4];
215
216         if(!islo()) {
217                 /* don't deadlock trying to print in interrupt */
218                 if(!canlock(&screenlock))
219                         return; 
220         }
221         else
222                 lock(&screenlock);
223
224         while(n > 0){
225                 i = chartorune(&r, s);
226                 if(i == 0){
227                         s++;
228                         --n;
229                         continue;
230                 }
231                 memmove(buf, s, i);
232                 buf[i] = 0;
233                 n -= i;
234                 s += i;
235                 screenputc(buf);
236         }
237         unlock(&screenlock);
238 }
239
240 static void
241 screenwin(void)
242 {
243         char *greet;
244         Memimage *orange;
245         Point p, q;
246         Rectangle r;
247
248         back = memwhite;
249         conscol = memblack;
250
251         orange = allocmemimage(Rect(0, 0, 1, 1), RGB16);
252         orange->flags |= Frepl;
253         orange->clipr = gscreen->r;
254         orange->data->bdata[0] = 0x40;          /* magic: colour? */
255         orange->data->bdata[1] = 0xfd;          /* magic: colour? */
256
257         w = memdefont->info[' '].width;
258         h = memdefont->height;
259
260         r = insetrect(gscreen->r, 4);
261
262         memimagedraw(gscreen, r, memblack, ZP, memopaque, ZP, S);
263         window = insetrect(r, 4);
264         memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP, S);
265
266         memimagedraw(gscreen, Rect(window.min.x, window.min.y,
267                 window.max.x, window.min.y + h + 5 + 6), orange, ZP, nil, ZP, S);
268         freememimage(orange);
269         window = insetrect(window, 5);
270
271         greet = " Plan 9 Console ";
272         p = addpt(window.min, Pt(10, 0));
273         q = memsubfontwidth(memdefont, greet);
274         memimagestring(gscreen, p, conscol, ZP, memdefont, greet);
275         flushmemscreen(r);
276         window.min.y += h + 6;
277         curpos = window.min;
278         window.max.y = window.min.y + ((window.max.y - window.min.y) / h) * h;
279 }
280
281 static void
282 scroll(void)
283 {
284         int o;
285         Point p;
286         Rectangle r;
287
288         o = Scroll*h;
289         r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
290         p = Pt(window.min.x, window.min.y+o);
291         memimagedraw(gscreen, r, gscreen, p, nil, p, S);
292         flushmemscreen(r);
293         r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
294         memimagedraw(gscreen, r, back, ZP, nil, ZP, S);
295         flushmemscreen(r);
296
297         curpos.y -= o;
298 }
299
300 static void
301 screenputc(char *buf)
302 {
303         int w;
304         uint pos;
305         Point p;
306         Rectangle r;
307         static int *xp;
308         static int xbuf[256];
309
310         if (xp < xbuf || xp >= &xbuf[nelem(xbuf)])
311                 xp = xbuf;
312
313         switch (buf[0]) {
314         case '\n':
315                 if (curpos.y + h >= window.max.y)
316                         scroll();
317                 curpos.y += h;
318                 screenputc("\r");
319                 break;
320         case '\r':
321                 xp = xbuf;
322                 curpos.x = window.min.x;
323                 break;
324         case '\t':
325                 p = memsubfontwidth(memdefont, " ");
326                 w = p.x;
327                 if (curpos.x >= window.max.x - Tabstop * w)
328                         screenputc("\n");
329
330                 pos = (curpos.x - window.min.x) / w;
331                 pos = Tabstop - pos % Tabstop;
332                 *xp++ = curpos.x;
333                 r = Rect(curpos.x, curpos.y, curpos.x + pos * w, curpos.y + h);
334                 memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
335                 flushmemscreen(r);
336                 curpos.x += pos * w;
337                 break;
338         case '\b':
339                 if (xp <= xbuf)
340                         break;
341                 xp--;
342                 r = Rect(*xp, curpos.y, curpos.x, curpos.y + h);
343                 memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
344                 flushmemscreen(r);
345                 curpos.x = *xp;
346                 break;
347         case '\0':
348                 break;
349         default:
350                 p = memsubfontwidth(memdefont, buf);
351                 w = p.x;
352
353                 if (curpos.x >= window.max.x - w)
354                         screenputc("\n");
355
356                 *xp++ = curpos.x;
357                 r = Rect(curpos.x, curpos.y, curpos.x + w, curpos.y + h);
358                 memimagedraw(gscreen, r, back, back->r.min, nil, back->r.min, S);
359                 memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf);
360                 flushmemscreen(r);
361                 curpos.x += w;
362                 break;
363         }
364 }