Index: /liacs/mss/project/uinput.c
===================================================================
--- /liacs/mss/project/uinput.c	(revision 16)
+++ /liacs/mss/project/uinput.c	(revision 16)
@@ -0,0 +1,165 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <linux/input.h>
+#include <linux/uinput.h>
+#include <signal.h>
+#include <X11/Xlib.h>
+
+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);
+}
