#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_current, xy_diff; // Force pointer to absolute location on the screen while ( 1 ) { xy_current = get_coords(); xy_diff.x = -(xy_current.x - xy_target.x); xy_diff.y = -(xy_current.y - xy_target.y); if (xy_diff.x == 0 && xy_diff.y == 0) { 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(2000000); break; } } } int main() { struct coords xy_target = { 500,500 }; init_pointer(); set_pointer(xy_target); xy_target.x = 700; xy_target.y = 700; set_pointer(xy_target); close_pointer(); return(0); }