#include #include "mouse.h" #include "ringbuffer.h" #include "compositor.h" #include "interrupts.h" #include "kernel/kernel.h" #include "log.h" #include "driver/vesa.h" #include "asm_x86.h" static volatile uint8_t mouse_cycle; static volatile uint8_t mouse_byte[3]; static volatile int16_t mouse_x; static volatile int16_t mouse_y; static ringbuffer mouse_in; bool mouse_worker() { bool wake=false; while(ringbuffer_has(&mouse_in)){ mouse_handler(ringbuffer_get(&mouse_in)); wake=true; } return wake; } void mouse_wait(uint8_t a_type) //unsigned char { uint32_t _time_out=100000; //unsigned int if(a_type==0) { while(_time_out--) //Data { if((x86_inb(0x64) & 1)==1) { return; } } return; } else { while(_time_out--) //Signal { if((x86_inb(0x64) & 2)==0) { return; } } return; } } static uint8_t mouse_read() { //Get's response from mouse mouse_wait(0); return x86_inb(0x60); } static void mouse_write(uint8_t a_write) { //Wait to be able to send a command mouse_wait(1); //Tell the mouse we are sending a command x86_outb(0x64, 0xD4); //Wait for the final part mouse_wait(1); //Finally write x86_outb(0x60, a_write); } uint32_t mouse_interrupt(uint32_t esp) { uint8_t b=x86_inb(0x60); ringbuffer_put(&mouse_in,b); return esp; } void mouse_init() { mouse_in=ringbuffer_init(1);// 4096 bytes ringbuffer; uint8_t _status; //unsigned char //Enable the auxiliary mouse device mouse_wait(1); x86_outb(0x64, 0xA8); //Enable the interrupts mouse_wait(1); x86_outb(0x64, 0x20); mouse_wait(0); _status=(x86_inb(0x60) | 2); mouse_wait(1); x86_outb(0x64, 0x60); mouse_wait(1); x86_outb(0x60, _status); //Tell the mouse to use default settings mouse_write(0xF6); mouse_read(); //Acknowledge //Enable the mouse mouse_write(0xF4); mouse_read(); //Acknowledge interrupt_register(INTERRUPT_MOUSE,&mouse_interrupt); } // called as we filled the 3 bytes, everytime. void mouse_action() { //klog("mouse %02x / %02x / %02x ",mouse_byte[0], mouse_byte[1],mouse_byte[2]); //TODO: ignore last packet for 4packets mouse and resync if you get out of sync if(mouse_byte[0]&0x80||mouse_byte[0]&0x40) { klog("mouse overflow, skipping packet"); return; //skip packet on overflow } //OOOMG!!// if(mouse_byte[1]>127){ mouse_x-=256; mouse_x+=mouse_byte[1]; } else { mouse_x+=mouse_byte[1]; } if(mouse_byte[2]>127){ mouse_y-=256; mouse_y+=mouse_byte[2]; } else { mouse_y+=mouse_byte[2]; } if(mouse_x<0)mouse_x=0; if(mouse_y<0)mouse_y=0; if(mouse_x>=1920)mouse_x=1920-1; if(mouse_y>=1080)mouse_y=1080-1; compositor_mouse_handle(mouse_x,1080-mouse_y, mouse_byte[0]); } void mouse_handler(uint8_t byte)//struct regs *a_r) //struct regs *a_r (not used but just there) { // X86_IRQ_BEGIN switch(mouse_cycle) { case 0: mouse_byte[0]=byte; mouse_cycle++; if(!(mouse_byte[0]&0x8)) { klog("mouse out of sync, try resync"); mouse_cycle--; // kpanic("mouse packets out of sync!?"); // this bit is always 1, otherwise panic! } break; case 1: mouse_byte[1]=byte; mouse_cycle++; break; case 2: mouse_byte[2]=byte; mouse_cycle=0; mouse_action(); break; } // X86_IRQ_END }