shithub: cursedfs

ref: 4ae0c34b7ed27db5062153219e7e4b49b9013d75
dir: /screen.c/

View raw version
#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);
			}
	}
}