diff --git a/kernel/event.c b/kernel/event.c new file mode 100644 index 0000000..ae14e54 --- /dev/null +++ b/kernel/event.c @@ -0,0 +1,104 @@ + +#include "event.h" +#include "device.h" +#include "keyboard.h" +#include "mouse.h" +#include "interrupt.h" +#include "string.h" +#include "process.h" + +#define EVENT_BUFFER_SIZE 32 + +static struct event buffer[EVENT_BUFFER_SIZE]; + +static int head=0; +static int tail=0; +static int overflow_count=0; + +static struct list queue = LIST_INIT; + +/* INTERRUPT CONTEXT */ + +void event_post( uint16_t type, uint16_t code, int16_t x, int16_t y ) +{ + /* If ring buffer is full, return immediately. */ + int next = (head+1) % EVENT_BUFFER_SIZE; + if(next==tail) { + overflow_count++; + return; + } + + /* Copy event to current buffer position */ + struct event *e = &buffer[head]; + e->type = type; + e->code = code; + e->x = x; + e->y = y; + + /* Advance head pointer and wake up waiting process (if any) */ + head = next; + process_wakeup(&queue); +} + +int event_read_raw( struct event *e, int size, int blocking ) +{ + int total=0; + + if(size=sizeof(struct event)) { + + if(head==tail) { + if(blocking && total==0) { + process_wait(&queue); + continue; + } else { + break; + } + } + + *e = buffer[tail]; + tail = (tail+1) % EVENT_BUFFER_SIZE; + total++; + size -= sizeof(struct event); + } + + interrupt_unblock(); + + return total; +} + +int event_read( struct event *e, int size ) +{ + return event_read_raw(e,size,1); +} + +int event_read_nonblock( struct event *e, int size ) +{ + return event_read_raw(e,size,0); +} + +int event_read_keyboard() +{ + struct event e; + while(event_read(&e,sizeof(e))) { + if(e.type==EVENT_KEY_DOWN) { + return e.code; + } + } + return 'x'; +} + +void event_init() +{ + mouse_init(); + keyboard_init(); + printf("event: ready\n"); +} + + + + +