#include "Input.h" #include "Core.h" #include "Utils.h" #include #include #include #include #include #include #include #include #include //Deprecated #define STYLUS_DEVICE_ID 0x02 #define TOUCH_DEVICE_ID 0x03 #define CURSOR_DEVICE_ID 0x06 #define ERASER_DEVICE_ID 0x0A #define PAD_DEVICE_ID 0x0F #define DEBUG 0 using namespace std; using namespace net::lliurex::mrpdi::input; using namespace net::lliurex::mrpdi; /** * Constructor */ InputHandler::InputHandler() { this->calibration_step=-1; } /** * Destructor */ InputHandler::~InputHandler() { } /** * This method is call with drivers callback events */ void InputHandler::pointer_callback(driver_event event) { switch(event.type) { case EVENT_POINTER: if(calibration_step==-1) { for(int n=0;nget_address()==event.address) { if(devices[n]->get_pointer()==event.pointer.pointer) { devices[n]->set_position(event.pointer.x,event.pointer.y); devices[n]->set_pressure(event.pointer.z); devices[n]->set_button(0,event.pointer.button & 0x01); devices[n]->set_button(1,(event.pointer.button & 0x02)>>1); devices[n]->set_button(2,(event.pointer.button & 0x04)>>2); devices[n]->update(); break; } } } } else { for(int n=0;nget_address()==calibration_address) { if(devices[n]->get_pointer()==event.pointer.pointer) { if((event.pointer.button & 0x01)==0 && calibration_press==1) { #if DEBUG cout<<"Calibration STEP:"<step(calibration_step); } calibration_press=(event.pointer.button & 0x01); if(calibration_step==4) { #if DEBUG cout<<"Calibration completed!"<get_address()==calibration_address) { devices[m]->set_calibration(calibration_points); } } CalibrationScreen::destroy(); calibration_step=-1; } else { //NAN } } } } } break; case EVENT_KEY: #if DEBUG cout<<"Key CALLBACK:"< param_list; unsigned int num_pointers=0; unsigned int calibrate=0; unsigned int pressure=0; unsigned int flags = 0; Core::getCore()->get_parameter_list(id,¶m_list); for(int n=0;nget_parameter(id,param_list[n].c_str(),&num_pointers); } if(param_list[n].find(".calibrate")!=string::npos) { Core::getCore()->get_parameter(id,param_list[n].c_str(),&calibrate); } if(param_list[n].find(".pressure")!=string::npos) { Core::getCore()->get_parameter(id,param_list[n].c_str(),&pressure); } } if(num_pointers>0) { #if DEBUG cout<<"InputHandler: Available pointers-> "<start(); } if(calibrate==1) { #if DEBUG cout<<"InputHandler: Device requested calibration"<calibrate(address); } } } /** * Call when a device is stoped, so uinput device can be disabled too * @param id target device id, 0xvendorproduct * @param address target device usb address */ void InputHandler::stop(unsigned int id,unsigned int address) { #if DEBUG cout<<"InputHandler::stop"< backvector; for(int n=0;nget_address()!=address) { backvector.push_back(devices[n]); } else { devices[n]->stop(); delete devices[n]; } } devices=backvector; } /** * Starts a calibration process * @param address Target device usb address */ void InputHandler::calibrate(unsigned int address) { #if DEBUG cout<<"[InputHandler]::calibrate()"<step(0); //NOTE: This order is important, to avoid callback event to instance a second calibration screen this->calibration_press=0; this->calibration_address=address; this->calibration_step=0; } AbsolutePointer::AbsolutePointer(string name,unsigned int address,unsigned char pointer,unsigned int flags) { #if DEBUG cout<<"AbsolutePointer()"<name=name; this->address=address; this->pointer=pointer; this->calibration[0]=0.0f; this->calibration[1]=0.0f; this->calibration[2]=1.0f; this->calibration[3]=0.0f; this->calibration[4]=1.0f; this->calibration[5]=1.0f; this->calibration[6]=0.0f; this->calibration[7]=1.0f; this->use_calibration=false; if( (flags & PointerFlags::Pressure)==PointerFlags::Pressure) this->has_pressure=true; else this->has_pressure=false; } AbsolutePointer::~AbsolutePointer() { #if DEBUG cout<<"~AbsolutePointer()"<has_pressure) { uidev.absmin[ABS_Z]=0x0; uidev.absmax[ABS_Z]=0x0300; set_uinput(UI_SET_ABSBIT, ABS_Z); } //creating device if(write(fd_uinput, &uidev, sizeof(uidev))<0) { cerr<<"Error sending device descriptor"<use_calibration) { Utils::inverse_interpolation(x,y,this->calibration,&this->x,&this->y); } else { this->x=x; this->y=y; } } void AbsolutePointer::set_button(int num,int state) { this->button_state[num]=this->button[num]; this->button[num]=state; } void AbsolutePointer::update() { struct input_event ev; memset(&ev, 0, sizeof(ev)); gettimeofday(&ev.time, NULL); //x ev.type = EV_ABS; ev.code = ABS_X; ev.value = 0x0FFF*x; send_uinput(&ev); //y ev.type = EV_ABS; ev.code = ABS_Y; ev.value = 0x0FFF*y; send_uinput(&ev); //z if(this->has_pressure) { ev.type = EV_ABS; ev.code = ABS_Z; ev.value = 0x0300*z; send_uinput(&ev); } //left button press if(button_state[0]==0 && button[0]==1) { ev.type = EV_KEY; ev.code = BTN_LEFT; ev.value = 1; send_uinput(&ev); } //left button release if(button_state[0]==1 && button[0]==0) { ev.type = EV_KEY; ev.code = BTN_LEFT; ev.value = 0; send_uinput(&ev); } //right button press if(button_state[1]==0 && button[1]==1) { ev.type = EV_KEY; ev.code = BTN_RIGHT; ev.value = 1; send_uinput(&ev); } //right button release if(button_state[1]==1 && button[1]==0) { ev.type = EV_KEY; ev.code = BTN_RIGHT; ev.value = 0; send_uinput(&ev); } //sync ev.type = EV_SYN; ev.code = SYN_REPORT; ev.value = 0; send_uinput(&ev); } int AbsolutePointer::set_uinput(unsigned long int property,unsigned int value) { int res; res=ioctl(fd_uinput, property, value); if(res<0) cerr<<"Error ioctl uinput:"<address; } unsigned char AbsolutePointer::get_pointer() { return this->pointer; } void AbsolutePointer::set_calibration(float * calibration) { for(int n=0;n<8;n++) { this->calibration[n]=calibration[n]; } this->use_calibration=true; } void AbsolutePointer::set_pressure(float z) { this->z=z; }