105 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
 | |
| #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)) return KERROR_INVALID_REQUEST;
 | |
| 
 | |
| 	interrupt_block();
 | |
| 
 | |
| 	while(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");
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 |