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