ref: 4ae0c34b7ed27db5062153219e7e4b49b9013d75
dir: /screen.c/
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <draw.h>
#include <event.h>
#include "fs.h"
Point p; // unused?
Font *ourfont; // VGA
Image *brush; // For drawing the text
Rune *s = L"☺☹σπß"; // for testing
int bwidth = 4; // border width of window
Rune **sbuf, **ebuf; // screen buffer, empty buffer
usize sheight = 25, swidth = 80; // screen height, width
Lock slock; // screen buffer lock
/* Menus */
char *buttons[] = {"exit", 0};
Menu menu = { buttons };
// Render the active buffer on a timer
void
renderbuf(Rune **buf)
{
int i;
lock(&slock);
Point out, p;
Point at = screen->r.min;
for(i = 0; i < sheight; i++){
p = runestringsize(ourfont, buf[i]);
out = runestring(
screen, at, display->black, ZP,
ourfont, buf[i]
);
at.y += p.y;
}
unlock(&slock);
flushimage(display, 1);
}
/* Graphics library requires this function */
void
eresized(int new)
{
if(new && getwindow(display, Refnone) < 0)
sysfatal("can't reattach to window");
/* Store new screen coordinates for collision detection */
p = Pt(Dx(screen->r), Dy(screen->r));
/* Draw the background DWhite */
draw(screen, insetrect(screen->r, bwidth),
allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DWhite),
nil, ZP);
}
// Initialize the screen buffer
void
initbuf(void)
{
int y, x;
ourfont = openfont(display, "/lib/font/bit/vga/unicode.font");
p = runestringsize(ourfont, s);
lock(&slock);
sbuf = calloc(sheight, sizeof (Rune*));
ebuf = calloc(sheight, sizeof (Rune*));
for(y = 0; y < sheight; y++){
sbuf[y] = calloc(swidth+1, sizeof (Rune));
ebuf[y] = calloc(swidth+1, sizeof (Rune));
for(x = 0; x < swidth; x++){
sbuf[y][x] = L'☺';
ebuf[y][x] = L' ';
}
}
unlock(&slock);
}
void
initscreen(void*)
{
Event ev;
int e, timer;
/* Initiate graphics and mouse */
if(initdraw(nil, nil, "cursedfs") < 0)
sysfatal("initdraw failed: %r");
einit(Emouse);
/* Start our timer
* move the ball every 5 milliseconds
* unless there is an Emouse event */
timer = etimer(0, 5);
/* Simulate a resize event to draw the background
* and acquire the screen dimensions */
initbuf();
renderbuf(ebuf);
// Set the screen size (after initbuf)
//echo resize -dx 100 -dy 100 > /dev/wctl
// TODO - broken
int fd;
char *str;
fd = open("/dev/wctl", OWRITE);
usize width = (ourfont->width * swidth) + 2*bwidth +1;
usize height = (ourfont->height * sheight) + 2*bwidth +1;
str = smprint("resize -dx %ld -dy %ld\n", width, height);
int out = write(fd, str, strlen(str));
if(out < 1)
sysfatal("err: /dev/wctl write failed → %r");
close(fd);
free(str);
eresized(0);
/* Main event loop */
for(;;){
e = event(&ev);
/* If there is a mouse event, the rightmost button
* pressed and the first menu option selected
* then exit.. */
if( (e == Emouse) &&
(ev.mouse.buttons & 4) &&
(emenuhit(3, &ev.mouse, &menu) == 0)) threadexitsall(nil);
else
if(e == timer){
// Might not want this
renderbuf(ebuf);
renderbuf(sbuf);
}
}
}