#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;igraphics.index += 4 + length; }