123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include "u.h"
- #include "../port/lib.h"
- #include "mem.h"
- #include "dat.h"
- #include "fns.h"
- #include "io.h"
- #include "../port/error.h"
- #define Image IMAGE
- #include <draw.h>
- #include <memdraw.h>
- #include <cursor.h>
- #include "screen.h"
- static Memimage* back;
- static Memimage *conscol;
- static Point curpos;
- static Rectangle window;
- static int *xp;
- static int xbuf[256];
- Lock vgascreenlock;
- int drawdebug;
- void
- vgaimageinit(uint32_t chan)
- {
- if(back == nil){
- back = allocmemimage(Rect(0,0,1,1), chan); /* RSC BUG */
- if(back == nil)
- panic("back alloc"); /* RSC BUG */
- back->flags |= Frepl;
- back->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
- memfillcolor(back, DBlack);
- }
- if(conscol == nil){
- conscol = allocmemimage(Rect(0,0,1,1), chan); /* RSC BUG */
- if(conscol == nil)
- panic("conscol alloc"); /* RSC BUG */
- conscol->flags |= Frepl;
- conscol->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
- memfillcolor(conscol, DWhite);
- }
- }
- static void
- vgascroll(VGAscr* scr)
- {
- int h, o;
- Point p;
- Rectangle r;
- h = scr->memdefont->height;
- o = 8*h;
- r = Rpt(window.min, Pt(window.max.x, window.max.y-o));
- p = Pt(window.min.x, window.min.y+o);
- memimagedraw(scr->gscreen, r, scr->gscreen, p, nil, p, S);
- r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
- memimagedraw(scr->gscreen, r, back, ZP, nil, ZP, S);
- curpos.y -= o;
- }
- static void
- vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
- {
- Point p;
- int h, w, pos;
- Rectangle r;
- // drawdebug = 1;
- if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
- xp = xbuf;
- h = scr->memdefont->height;
- switch(buf[0]){
- case '\n':
- if(curpos.y+h >= window.max.y){
- vgascroll(scr);
- *flushr = window;
- }
- curpos.y += h;
- vgascreenputc(scr, "\r", flushr);
- break;
- case '\r':
- xp = xbuf;
- curpos.x = window.min.x;
- break;
- case '\t':
- p = memsubfontwidth(scr->memdefont, " ");
- w = p.x;
- if(curpos.x >= window.max.x-4*w)
- vgascreenputc(scr, "\n", flushr);
- pos = (curpos.x-window.min.x)/w;
- pos = 4-(pos%4);
- *xp++ = curpos.x;
- r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
- curpos.x += pos*w;
- break;
- case '\b':
- if(xp <= xbuf)
- break;
- xp--;
- r = Rect(*xp, curpos.y, curpos.x, curpos.y+h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP, S);
- combinerect(flushr, r);
- curpos.x = *xp;
- break;
- case '\0':
- break;
- default:
- p = memsubfontwidth(scr->memdefont, buf);
- w = p.x;
- if(curpos.x >= window.max.x-w)
- vgascreenputc(scr, "\n", flushr);
- *xp++ = curpos.x;
- r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
- memimagestring(scr->gscreen, curpos, conscol, ZP, scr->memdefont, buf);
- combinerect(flushr, r);
- curpos.x += w;
- }
- // drawdebug = 0;
- }
- static void
- vgascreenputs(char* s, int n)
- {
- int i, gotdraw;
- Rune r;
- char buf[4];
- VGAscr *scr;
- Rectangle flushr;
- scr = &vgascreen[0];
- if(!islo()){
- /*
- * Don't deadlock trying to
- * print in an interrupt.
- */
- if(!canlock(&vgascreenlock))
- return;
- }
- else
- lock(&vgascreenlock);
- /*
- * Be nice to hold this, but not going to deadlock
- * waiting for it. Just try and see.
- */
- gotdraw = canqlock(&drawlock);
- flushr = Rect(10000, 10000, -10000, -10000);
- while(n > 0){
- i = chartorune(&r, s);
- if(i == 0){
- s++;
- --n;
- continue;
- }
- memmove(buf, s, i);
- buf[i] = 0;
- n -= i;
- s += i;
- vgascreenputc(scr, buf, &flushr);
- }
- flushmemscreen(flushr);
- if(gotdraw)
- qunlock(&drawlock);
- unlock(&vgascreenlock);
- }
- void
- vgascreenwin(VGAscr* scr)
- {
- int h, w;
- h = scr->memdefont->height;
- w = scr->memdefont->info[' '].width;
- window = insetrect(scr->gscreen->r, 48);
- window.max.x = window.min.x+((window.max.x-window.min.x)/w)*w;
- window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
- curpos = window.min;
- consputs = vgascreenputs;
- }
- /*
- * Supposedly this is the way to turn DPMS
- * monitors off using just the VGA registers.
- * Unfortunately, it seems to mess up the video mode
- * on the cards I've tried.
- */
- void
- vgablank(VGAscr *scr, int blank)
- {
- print("can't blank\n");
- }
- void
- addvgaseg(char *name, uint32_t pa, uint32_t size)
- {
- Physseg seg;
- memset(&seg, 0, sizeof seg);
- seg.attr = SG_PHYSICAL;
- seg.name = name;
- seg.pa = pa;
- seg.size = size;
- addphysseg(&seg);
- }
- void
- cornerstring(char *s)
- {
- int h, w;
- VGAscr *scr;
- Rectangle r;
- Point p;
- scr = &vgascreen[0];
- if(scr->vaddr == nil || consputs != vgascreenputs)
- return;
- p = memsubfontwidth(scr->memdefont, s);
- w = p.x;
- h = scr->memdefont->height;
- r = Rect(0, 0, w, h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
- memimagestring(scr->gscreen, r.min, conscol, ZP, scr->memdefont, s);
- // flushmemscreen(r);
- }
|