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