Eu tenho uma mesa digitalizadora (ug-1200b) que estou usando com o Ubuntu. Eu escrevi um script (um tanto feio) que usa o libusb para pegar a entrada bruta e o xdotool para emular os movimentos e cliques do mouse. Isso funciona muito bem, mas eu queria saber se havia uma maneira de acessar a resolução mais fina do tablet.
O tablet tem uma resolução de caneta de aproximadamente 144336x8192 e uma resolução de tela de 1024x782, portanto, há & gt; 10 etapas na posição da caneta por pixel. Eu gostaria de relatar isso como movimentos do mouse.
Meu problema é que o xdotool possui um sistema de movimento do mouse baseado em pixels. Estou usando xdo_move_mouse(xdo, X, Y, 0);
, mas isso é limitado a valores inteiros, portanto estou tendo que arredondar e remover a resolução extra.
Existe alguma maneira de contornar este problema?
//compile with g++ myLibusbFile1.cpp -lusb-1.0 -lxdo
//this is a custom "driver" for the ug-1200b tablet.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <usb.h>
#include <libusb-1.0/libusb.h>
extern "C" {
#include <xdo.h>
}
#define CURRENTWINDOW (0)
uint16_t VENDOR = 21827; /* =0x5543 */
uint16_t PRODUCT = 74; /* =0x004a */
int ENDPOINT_IN = 129; /* = 0x81 */
void printData(unsigned char dataIn[]){
for(int i = 0; i < 8; i++){
printf("%d ",dataIn[i]);
}
printf("\n");
}
int main() {
xdo_t *xdo = xdo_new(NULL);
libusb_context *context = NULL;
libusb_device **list = NULL;
ssize_t count = 0;
libusb_device **devs;
libusb_device_handle *device_handle;
int r;
struct libusb_config_descriptor *conf;
printf("intialising\n");
if(libusb_init(&context)<0){
printf("intialisation failed\n");
return 0;
}
printf("getting list of USB's\n");
count = libusb_get_device_list(context, &list);
if(count <= 0) {
printf("could not find USB device");
return 0;
}
bool found_device =false;
for (size_t idx = 0; idx < count && ! found_device; ++idx) {
libusb_device *device = list[idx];
libusb_device_descriptor desc = {0};
libusb_get_device_descriptor(device, &desc);
printf("Vendor:Device = %04x:%04x\n", desc.idVendor, desc.idProduct);
if(desc.idVendor == VENDOR && desc.idProduct == PRODUCT){
if(libusb_open(device, &device_handle) < 0){
printf("failed to open device\n");
return 0;
}
found_device = true;
printf("opened device\n");
}
}
if(! found_device){
printf("Tablet not found");
return 0;
}
//automatically get and re-set kernel interface
if(libusb_set_auto_detach_kernel_driver(device_handle, 1) < 0)
{
printf("failed set auto detach\n");
return 0;
}
//claim interface
if(libusb_claim_interface(device_handle, 0) < 0){
printf("failed to claim interface\n");
libusb_close(device_handle);
return 0;
}
printf("interface claimed\n");
bool mouseIsDown=false;
bool complete = false;
while(!complete){
unsigned char dataIn[8];
int transferred;
if( libusb_interrupt_transfer(device_handle, ENDPOINT_IN, dataIn, 8, &transferred, 0) < 0){
printf("interrupt transfer failed!\n");
complete = true;
} else {
int X = (int) (dataIn[2] | (dataIn[3]) << 8);
int Y = (int) (dataIn[4] | (dataIn[5]) << 8);
int Z = (int) (dataIn[6] | (dataIn[7]) << 8);
X = X / 14;
Y = (Y * 3) / 32;
if((int) dataIn[0] != 9 || !((int) dataIn[1] != 0 ^ Z == 0)){
printData(dataIn);
printf("unfamiliar string!\n");
return 0;
}
xdo_move_mouse(xdo, X, Y, 0);
if(mouseIsDown && Z == 0){
mouseIsDown = false;
xdo_mouse_up(xdo, CURRENTWINDOW, 1);
}
if(!mouseIsDown && Z != 0){
mouseIsDown = true;
xdo_mouse_down(xdo, CURRENTWINDOW, 1);
}
}
}
//close interface and usb, and deinitialise
printf("releasing interface\n");
libusb_release_interface(device_handle,0);
printf("closing device\n");
libusb_close(device_handle);
printf("exiting\n");
libusb_exit(context);
printf("done!\n");
return 0;
}