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;
|
||
|
}
|