#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <asm/types.h>
#include <X11/Xlib.h>
#include <linux/joystick.h>

#define DEBUG 0

/*
   compile with:
   gcc -o jsmouse jsmouse.c -l/usr/X11R6/lib -lX11
*/

static Display *display;
Window window, child, ochild, root_ret;


int main(int argc, char **argv)
{
	struct js_event e;
	XEvent event1;
	uint time0, time1, val0, val1, lasttime = 0, posx, posy;
	uint keybuttons;
	int rootx, rooty, winx, winy;
	int fd;
	int	click_flag = 0;

	if (!(fd = open("/dev/input/js0", O_RDONLY))) {
		fprintf(stderr, "cannot open /dev/input/js0\n");
		exit(1);
	}        

	if ((display = XOpenDisplay(NULL)) ==NULL){
		fprintf(stderr,"push_mouse: Display can't open.");  
		exit(1);
	}
	window = DefaultRootWindow(display);

	lasttime = 0;
	while(1){
		read (fd, &e, sizeof(struct js_event));
#if DEBUG
		printf("time %d num %d value %d type %d\n",  
				e.time, e.number, e.value, e.type);
#endif

		if (e.type == JS_EVENT_AXIS) {
			if (e.number == 0){
				val0 = e.value;
				time0 = e.time;
				if (!lasttime) lasttime = time0;
			}
			if (e.number == 1){
				val1 = e.value;
				time1 = e.time;
			}
		
			if (time1 > lasttime && time1 == time0){
				posx = (float)((32768 + val0) / 65536.0) * 800;        
				posy = (float)((32768 + val1) / 65536.0) * 600;        
				XWarpPointer(display, None, window, 0, 0, 0, 0, posx, posy);
				XFlush(display);
				lasttime = time1;
			}
		}

		else if (e.type == JS_EVENT_BUTTON) {
			child = window;
			while(child) {
				ochild = child;
				XQueryPointer(display, child, &root_ret, &child,
						&rootx, &rooty, &winx, &winy, &keybuttons);
			}

			event1.type = ButtonRelease;
			event1.xbutton.state = 0;
			event1.xbutton.serial = 0;
			event1.xbutton.send_event = True;
			event1.xbutton.button = Button1;
			event1.xbutton.display = display;
			event1.xbutton.window = ochild;
			event1.xbutton.root = window;
			event1.xbutton.subwindow = None;
			event1.xbutton.x = winx;
			event1.xbutton.y = winy;
			event1.xbutton.x_root = rootx;
			event1.xbutton.y_root = rooty;
			event1.xbutton.same_screen = True;
			event1.xbutton.time = e.time;
			event1.xbutton.state = keybuttons;


			if(!click_flag)	{
				event1.type = ButtonPress;
				XSendEvent(display,
						ochild, True, ButtonPressMask, &event1);
				XFlush(display);
#if DEBUG
				fprintf(stdout,"clicked\n");
#endif
				click_flag = 1;
			}
			else {
				event1.type = ButtonRelease;
				XSendEvent(display,
						ochild, True, ButtonReleaseMask, &event1);
				XFlush(display);
#if DEBUG
				fprintf(stdout,"released\n");
#endif
				click_flag = 0;
			}
		}
		
		else {	// Init flag
			click_flag = 0;
		}
	}
}


