#include #include #include #include #include #include #include #include static int fd; struct coords { int x; int y; }; void close_pointer() { ioctl(fd, UI_DEV_DESTROY); close(fd); } // Close stuff nicely in case of issues void ex_program(int sig) { close_pointer(); printf("Terminated signal: %d\n", sig); (void) signal(SIGINT, SIG_DFL); exit(-1); } // Wrapper to send cool stuff over the wire int send_event(int fd, __u16 type, __u16 code, __s32 value) { struct input_event event; memset(&event, 0, sizeof(event)); event.type = type; event.code = code; event.value = value; gettimeofday(&event.time, NULL); if (write(fd, &event, sizeof(event)) != sizeof(event)) { fprintf(stderr, "Error on send_event"); return -1; } return 0; } //XXX: Make me more effient struct coords get_coords() { Display *dsp = XOpenDisplay( NULL ); struct coords xy_current = { -1, -1 }; if( !dsp ){ return xy_current; } int screenNumber = DefaultScreen(dsp); XEvent event; /* get info about current pointer position */ XQueryPointer(dsp, RootWindow(dsp, screenNumber), &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state); printf("Mouse Coordinates: %d %d\n", event.xbutton.x, event.xbutton.y); XCloseDisplay( dsp ); xy_current.x = event.xbutton.x; xy_current.y = event.xbutton.y; return(xy_current); } // Set the pointer to a certain location int init_pointer() { int i; struct uinput_user_dev device; memset(&device, 0, sizeof device); fd=open("/dev/uinput",O_WRONLY | O_NDELAY); strcpy(device.name,"test mouse"); device.id.bustype=BUS_USB; device.id.vendor= 0x0001; device.id.product=0x0001; device.id.version=UINPUT_VERSION; //for (i=0; i < ABS_MAX; i++) { // device.absmax[i] = -1; // device.absmin[i] = -1; // device.absfuzz[i] = -1; // device.absflat[i] = -1; //} if (write(fd,&device,sizeof(device)) != sizeof(device)) { fprintf(stderr, "error setup\n"); return -1; } (void) signal(SIGINT, ex_program); /* mousedev only recognize our device as a mouse * if it has at least two axis and one left button. * Also, mouse buttons have to send sync events. */ //ioctl(fd, UI_SET_EVBIT, EV_KEY); ioctl(fd, UI_SET_EVBIT, EV_REL); ioctl(fd, UI_SET_EVBIT, EV_SYN); ioctl(fd, UI_SET_RELBIT, REL_X); ioctl(fd, UI_SET_RELBIT, REL_Y); //ioctl(fd, UI_SET_RELBIT, REL_WHEEL); ioctl(fd, UI_SET_KEYBIT, BTN_LEFT); //ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT); //ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE); //for (i=0; i < 256; i++) { // ioctl(fd, UI_SET_KEYBIT, i); //} ioctl(fd, UI_DEV_CREATE, NULL); } int set_pointer(const struct coords xy_target) { struct coords xy_diff, xy_prev; struct coords xy_current = { -1 , -1 }; // Bogus inital value char c; // Force pointer to absolute location on the screen while ( 1 ) { //XXX: Screen pointer get updated really slow xy_prev.x = xy_current.x; xy_prev.y = xy_current.y; while ( 1 ) { xy_current = get_coords(); // Found ourself an update printf("old->new coordinates %ix%i -> %ix%i\n", xy_prev.x,xy_prev.y, xy_current.x,xy_current.y); if (xy_prev.x != xy_current.x || xy_prev.y != xy_current.y) { //ex_program(1); break; } usleep(200000); } xy_diff.x = (xy_target.x - xy_current.x); xy_diff.y = (xy_target.y - xy_current.y); if (xy_diff.x == 0 && xy_diff.y == 0) { printf("Location %ix%i\n", xy_current.x, xy_current.y); break; } else { printf("Trying to sync current:%ix%i target:%ix%i diff:%ix%i\n", xy_current.x, xy_current.y, xy_target.x, xy_target.y, xy_diff.x, xy_diff.y); send_event(fd, EV_REL, REL_X, xy_diff.x); send_event(fd, EV_REL, REL_Y, xy_diff.y); send_event(fd, EV_SYN, SYN_REPORT, 0); // Wait some small period of time to get it populated (and the screen get updated) usleep(200000); } } } int main() { struct coords xy_target = { 200,200 }; init_pointer(); set_pointer(xy_target); xy_target.x = 500; xy_target.y = 500; set_pointer(xy_target); close_pointer(); return(0); }