shithub: cstory

ref: 136de4805728e9baf48582aa9166d934f106b9f6
dir: /src/Backends/Platform/9front.cpp/

View raw version
// Released under the MIT licence.
// See LICENCE.txt for details.

#include "../Misc.h"

#include "../../Attributes.h"

#include <thread.h>
#include <draw.h>
#include <memdraw.h>
#include <keyboard.h>
#include <mouse.h>

static int keyboard_state[BACKEND_KEYBOARD_TOTAL];
static Mousectl *mctl;

int Mark_Rune(int *kbd, Rune r)
{
	if(r >= 'a' && r <= 'z'){
		r -= 'a';
		return kbd[BACKEND_KEYBOARD_A + r] = 1;
	}
	if(r >= '0' && r <= '9'){
		r -= '0';
		return kbd[BACKEND_KEYBOARD_0 + r] = 1;
	}

	switch(r){
	case KF|1:
	case KF|2:
	case KF|3:
	case KF|4:
	case KF|5:
	case KF|6:
	case KF|7:
	case KF|8:
	case KF|9:
	case KF|10:
	case KF|11:
	case KF|12:
		r -= (KF|1);
		return kbd[BACKEND_KEYBOARD_F1 + r] = 1;

	case Kleft:
		return kbd[BACKEND_KEYBOARD_LEFT] = 1;
	case Kright:
		return kbd[BACKEND_KEYBOARD_RIGHT] = 1;
	case Kup:
		return kbd[BACKEND_KEYBOARD_UP] = 1;
	case Kdown:
		return kbd[BACKEND_KEYBOARD_DOWN] = 1;
	case Kesc:
		return kbd[BACKEND_KEYBOARD_ESCAPE] = 1;
	case '`':
		return kbd[BACKEND_KEYBOARD_BACK_QUOTE] = 1;
	case '\t':
		return kbd[BACKEND_KEYBOARD_TAB] = 1;
	case Kshift:
		return kbd[BACKEND_KEYBOARD_LEFT_SHIFT] = 1;
	case Kctl:
		return kbd[BACKEND_KEYBOARD_LEFT_CTRL] = 1;
	case ' ':
		return kbd[BACKEND_KEYBOARD_SPACE] = 1;
	case '\n':
		return kbd[BACKEND_KEYBOARD_ENTER] = 1;
	case Kbs:
		return kbd[BACKEND_KEYBOARD_BACKSPACE] = 1;
	case '-':
		return kbd[BACKEND_KEYBOARD_MINUS] = 1;
	case '=':
		return kbd[BACKEND_KEYBOARD_EQUALS] = 1;
	case '[':
		return kbd[BACKEND_KEYBOARD_LEFT_BRACKET] = 1;
	case ']':
		return kbd[BACKEND_KEYBOARD_RIGHT_BRACKET] = 1;
	case '\\':
		return kbd[BACKEND_KEYBOARD_BACK_SLASH] = 1;
	case ';':
		return kbd[BACKEND_KEYBOARD_SEMICOLON] = 1;
	case '\'':
		return kbd[BACKEND_KEYBOARD_APOSTROPHE] = 1;
	case ',':
		return kbd[BACKEND_KEYBOARD_COMMA] = 1;
	case '.':
		return kbd[BACKEND_KEYBOARD_PERIOD] = 1;
	case '/':
		return kbd[BACKEND_KEYBOARD_FORWARD_SLASH] = 1;
	}
	return 0;

	/* Sorry!
		BACKEND_KEYBOARD_CAPS_LOCK,
		BACKEND_KEYBOARD_LEFT_ALT,
		BACKEND_KEYBOARD_RIGHT_ALT,
		BACKEND_KEYBOARD_RIGHT_CTRL,
		BACKEND_KEYBOARD_RIGHT_SHIFT,
	*/
}

void Key_Proc(void*)
{
	char buf[128], *s;
	int kbfd, n;
	Rune r;

	threadsetname("keyproc");
	kbfd = open("/dev/kbd", OREAD);
	if(kbfd < 0)
		sysfatal("open: %r");
	for(;;){
		n = read(kbfd, buf, sizeof buf-1);
		if(n <= 0)
			return;
		buf[n-1] = 0;
		for(s = buf; s < buf+n; s++){
			if(*s != 'k' && *s != 'K'){
				for(; *s != '\0'; s++)
					;
				continue;
			}

			memset(keyboard_state, 0, sizeof keyboard_state);
			for(s++; *s && s < buf+n;){
				s += chartorune(&r, s);
				Mark_Rune(keyboard_state, r);
			}
		}
	}
}

void Backend_Proc(void*)
{
	enum { Aresize, Amouse, Aend };
	Mouse m;

	Alt a[] = {
		[Amouse] { nil, &m, CHANRCV },
		[Aresize] { nil, nil, CHANRCV },
		[Aend] { nil, nil, CHANEND },
	};
	threadsetname("resizeproc");
	a[Amouse].c = mctl->c;
	a[Aresize].c = mctl->resizec;

	for(;;){
		switch(alt(a)){
		case Aresize:
			getwindow(display, Refnone);
			break;
		}
	}
}

int Backend_Init(void (*drag_and_drop_callback)(const char *path), void (*window_focus_callback)(int focus))
{
	(void)drag_and_drop_callback;
	(void)window_focus_callback;

	memimageinit();
	if(initdraw(nil, nil, "cstory") < 0)
		sysfatal("initdraw: %r");
	mctl = initmouse(nil, screen);
	if(mctl == nil)
		sysfatal("initmouse: %r");

	proccreate(Key_Proc, nil, 8192);
	proccreate(Backend_Proc, nil, 8192);

	return 1;
}

void Backend_Deinit(void)
{
}

void Backend_PostWindowCreation(void)
{
	
}

int Backend_GetPaths(char **module_path, char **data_path)
{
	*module_path = "/sys/games/lib/cstory";
	*data_path = "/sys/games/lib/cstory/data";

	return 1;
}

void Backend_HideMouse(void)
{
	
}

void Backend_SetWindowIcon(const unsigned char *rgb_pixels, size_t width, size_t height)
{
	(void)rgb_pixels;
	(void)width;
	(void)height;
}

void Backend_SetCursor(const unsigned char *rgba_pixels, size_t width, size_t height)
{
	(void)rgba_pixels;
	(void)width;
	(void)height;
}

void Backend_EnableDragAndDrop(void)
{	
}


int Backend_SystemTask(int active)
{
	return 1;
}

void Backend_GetKeyboardState(int *out)
{
	memcpy(out, keyboard_state, sizeof keyboard_state);
}

void Backend_ShowMessageBox(const char *title, const char *message)
{
	Backend_PrintInfo("ShowMessageBox - '%s' - '%s'\n", title, message);
}

ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintError(const char *format, ...)
{
	va_list argumentList;
	va_start(argumentList, format);
	fputs("ERROR: ", stderr);
	vfprintf(stderr, format, argumentList);
	fputc('\n', stderr);
	va_end(argumentList);
}

ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintInfo(const char *format, ...)
{
	va_list argumentList;
	va_start(argumentList, format);
	fputs("INFO: ", stdout);
	vfprintf(stdout, format, argumentList);
	fputc('\n', stdout);
	va_end(argumentList);
}

#define Nmsec 1000000ULL

unsigned long Backend_GetTicks(void)
{
	return npe_nanosec() / Nmsec;
}

void Backend_Delay(unsigned int ticks)
{
	npe_nsleep((uvlong)ticks * Nmsec);
}