basekernel/library/nwindow.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;
}