181 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
 | |
| #include "kernel/gfxstream.h"
 | |
| #include "kernel/types.h"
 | |
| #include "kernel/events.h"
 | |
| #include "library/nwindow.h"
 | |
| #include "library/syscalls.h"
 | |
| 
 | |
| #include "library/string.h"
 | |
| #include "library/malloc.h"
 | |
| #include "library/stdio.h"
 | |
| 
 | |
| struct nwindow {
 | |
| 	int fd;
 | |
| 	int x, y;
 | |
| 	int width, height;
 | |
| 	struct {
 | |
| 		int *buffer;
 | |
| 		int length;
 | |
| 		int index;
 | |
| 	} graphics;
 | |
| };
 | |
| 
 | |
| struct nwindow * nw_create_fd( int fd )
 | |
| {
 | |
| 	struct nwindow *w = malloc(sizeof(*w));
 | |
| 	w->fd = fd;
 | |
| 	w->x = 0;
 | |
| 	w->y = 0;
 | |
| 	w->graphics.buffer = malloc(PAGE_SIZE);
 | |
| 	w->graphics.length = PAGE_SIZE;
 | |
| 	w->graphics.index = 0;
 | |
| 
 | |
| 	int dims[2];
 | |
| 	syscall_object_size(fd,dims,2);
 | |
| 	w->width = dims[0];
 | |
| 	w->height = dims[1];
 | |
| 
 | |
| 	return w;
 | |
| }
 | |
| 
 | |
| struct nwindow * nw_create_default()
 | |
| {
 | |
| 	return nw_create_fd(KNO_STDWIN);
 | |
| }
 | |
| 
 | |
| struct nwindow * nw_create_child( struct nwindow *parent, int x, int y, int width, int height )
 | |
| {
 | |
| 	int fd = syscall_open_window(parent->fd,x,y,width,height);
 | |
| 	struct nwindow *nw = nw_create_fd(fd);
 | |
| 	nw->x = x;
 | |
| 	nw->y = y;
 | |
| 	nw->width = width;
 | |
| 	nw->height = height;
 | |
| 	return nw;
 | |
| }
 | |
| 
 | |
| int nw_width( struct nwindow *nw )
 | |
| {
 | |
| 	return nw->width;
 | |
| }
 | |
| 
 | |
| int nw_height( struct nwindow *nw )
 | |
| {
 | |
| 	return nw->height;
 | |
| }
 | |
| 
 | |
| int nw_next_event( struct nwindow *nw, struct event *e )
 | |
| {
 | |
| 	int r = syscall_object_read(nw->fd,e,sizeof(*e),0);
 | |
| 	return r>0;
 | |
| }
 | |
| 
 | |
| int nw_read_events( struct nwindow *nw, struct event *e, int count, int blocking )
 | |
| {
 | |
| 	int r = syscall_object_read(nw->fd,e,sizeof(*e)*count,blocking==0 ? KERNEL_IO_NONBLOCK : 0);
 | |
| 	return r>0 ? r : 0;
 | |
| }
 | |
| 
 | |
| int nw_post_events( struct nwindow *nw, const struct event *e, int count )
 | |
| {
 | |
| 	return syscall_object_write(nw->fd,e,sizeof(*e)*count,KERNEL_IO_POST);
 | |
| }
 | |
| 
 | |
| 
 | |
| char nw_getchar( struct nwindow *nw, int blocking )
 | |
| {
 | |
| 	struct event e;
 | |
| 	while(1) {
 | |
| 		int r = nw_read_events(nw,&e,sizeof(e),blocking);
 | |
| 		if(r<=0) return 0;
 | |
| 		if(e.type==EVENT_KEY_DOWN) {
 | |
| 			return e.code;
 | |
|        		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| int nw_fd( struct nwindow *w )
 | |
| {
 | |
| 	return w->fd;
 | |
| }
 | |
| 
 | |
| static void nw_draw3( struct nwindow *nw, int t, int a0, int a1, int a2 )
 | |
| {
 | |
| 	if(nw->graphics.length-nw->graphics.index<4) {
 | |
| 		nw_flush(nw);
 | |
| 	}
 | |
| 	int *p = &nw->graphics.buffer[nw->graphics.index];
 | |
| 	*p++ = t;
 | |
| 	*p++ = a0;
 | |
| 	*p++ = a1;
 | |
| 	*p++ = a2;
 | |
| 	nw->graphics.index += 4;
 | |
| }
 | |
| 
 | |
| static void nw_draw4( struct nwindow *nw, int t, int a0, int a1, int a2, int a3 )
 | |
| {
 | |
| 	if(nw->graphics.length-nw->graphics.index<5) {
 | |
| 		nw_flush(nw);
 | |
| 	}
 | |
| 	int *p = &nw->graphics.buffer[nw->graphics.index];
 | |
| 	*p++ = t;
 | |
| 	*p++ = a0;
 | |
| 	*p++ = a1;
 | |
| 	*p++ = a2;
 | |
| 	*p++ = a3;
 | |
| 	nw->graphics.index += 5;
 | |
| }
 | |
| 
 | |
| void nw_flush( struct nwindow *nw )
 | |
| {
 | |
| 	syscall_object_write(nw->fd, nw->graphics.buffer, nw->graphics.index, 0);
 | |
| 	nw->graphics.index = 0;
 | |
| }
 | |
| 
 | |
| void nw_fgcolor( struct nwindow *nw, int r, int g, int b)
 | |
| {
 | |
| 	nw_draw3(nw,GRAPHICS_FGCOLOR, r, g, b);
 | |
| }
 | |
| 
 | |
| void nw_bgcolor( struct nwindow *nw, int r, int g, int b)
 | |
| {
 | |
| 	nw_draw3(nw,GRAPHICS_BGCOLOR, r, g, b);
 | |
| }
 | |
| 
 | |
| void nw_rect( struct nwindow *nw, int x, int y, int w, int h)
 | |
| {
 | |
| 	nw_draw4(nw,GRAPHICS_RECT, x, y, w, h);
 | |
| }
 | |
| 
 | |
| void nw_clear( struct nwindow *nw, int x, int y, int w, int h)
 | |
| {
 | |
| 	nw_draw4(nw,GRAPHICS_CLEAR, x, y, w, h);
 | |
| }
 | |
| 
 | |
| void nw_line( struct nwindow *nw, int x, int y, int w, int h)
 | |
| {
 | |
| 	nw_draw4(nw,GRAPHICS_LINE, x, y, w, h);
 | |
| }
 | |
| 
 | |
| void nw_string( struct nwindow *nw, int x, int y, const char *s )
 | |
| {
 | |
| 	int length = strlen(s);
 | |
| 
 | |
| 	if(nw->graphics.length-nw->graphics.index < (length+4) ) {
 | |
| 		nw_flush(nw);
 | |
| 	}
 | |
| 
 | |
| 	int *p = &nw->graphics.buffer[nw->graphics.index];
 | |
| 	*p++ = GRAPHICS_TEXT;
 | |
| 	*p++ = x;
 | |
| 	*p++ = y;
 | |
| 	*p++ = length;
 | |
| 
 | |
| 	int i;
 | |
| 	for(i=0;i<length;i++) {
 | |
| 		*p++ = s[i];
 | |
| 	}
 | |
| 
 | |
| 	nw->graphics.index += 4 + length;
 | |
| }
 |