diff --git a/library/nwindow.c b/library/nwindow.c new file mode 100644 index 0000000..b73e7af --- /dev/null +++ b/library/nwindow.c @@ -0,0 +1,180 @@ + +#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; +}