diff --git a/abs_to_rel.cpp b/abs_to_rel.cpp
index 680ccbb..765f265 100644
--- a/abs_to_rel.cpp
+++ b/abs_to_rel.cpp
@@ -36,7 +36,15 @@ AbsToRel::AbsToRel()
 void
 AbsToRel::on_abs(AbsPortOut* port)
 {
-  rel_port_out[0]->set_state(port->get_state());
+  // Nothing do to, since everything is handled in update
+  //rel_port_out[0]->set_state(port->get_state());
+}
+
+void
+AbsToRel::update(float delta)
+{
+  int s = int(abs_port_in[0]->out_port->get_state() * delta * 0.2f);
+  rel_port_out[0]->set_state(s);
 }
 
 /* EOF */
diff --git a/abs_to_rel.hpp b/abs_to_rel.hpp
index 864b585..bc3867c 100644
--- a/abs_to_rel.hpp
+++ b/abs_to_rel.hpp
@@ -36,7 +36,7 @@ public:
   AbsToRel();
 
   void on_abs(AbsPortOut* port);
-
+  void update(float delta);
 private:
   AbsToRel (const AbsToRel&);
   AbsToRel& operator= (const AbsToRel&);
diff --git a/control.hpp b/control.hpp
index af2ccb9..60d249f 100644
--- a/control.hpp
+++ b/control.hpp
@@ -129,7 +129,7 @@ public:
 
   std::string get_label() { return label; }
   int  get_state() { return state; }
-  void set_state(int s) { if (state != s) { state = s; sig_change(this); } }
+  void set_state(int s) { state = s; sig_change(this); }
 
   void connect(RelPortIn* in);
   void connect(boost::function<void(RelPortOut*)> func);
@@ -201,6 +201,9 @@ public:
 
   RelPortIn*  get_rel_port_in(int idx);
   RelPortOut* get_rel_port_out(int idx);
+
+
+  virtual void update(float delta) {}
 };
 
 #endif
diff --git a/inputdrv.cpp b/inputdrv.cpp
index 728b595..f5e2791 100644
--- a/inputdrv.cpp
+++ b/inputdrv.cpp
@@ -28,6 +28,7 @@
 #include <boost/bind.hpp>
 #include "xbox360_driver.hpp"
 #include "uinput_driver.hpp"
+#include "abs_to_rel.hpp"
 #include "toggle_button.hpp"
 #include "control.hpp"
 #include "inputdrv.hpp"
@@ -44,81 +45,85 @@ void abs_change(AbsPortOut* port)
 
 int main()
 {
-  UInputDriver uinput1;
-  uinput1.add_rel(REL_X);
-  uinput1.add_rel(REL_Y);
-  uinput1.add_abs(ABS_X, -32768, 32767);
-  uinput1.add_abs(ABS_Y, -32768, 32767);
-  uinput1.add_btn(BTN_A);
-  uinput1.add_btn(BTN_B);
-  uinput1.add_btn(BTN_C);
-  uinput1.finish();
-
-  UInputDriver uinput2;
-  uinput2.add_abs(ABS_X, -32768, 32767);
-  uinput2.add_abs(ABS_Y, -32768, 32767);
-  uinput2.add_btn(BTN_A);
-  uinput2.add_btn(BTN_B);
-  uinput2.add_btn(BTN_C);
-  uinput2.finish();
+  UInputDriver* uinput = new UInputDriver();
+  uinput->add_rel(REL_X);
+  uinput->add_rel(REL_Y);
+  uinput->add_rel(REL_HWHEEL);
+  uinput->add_rel(REL_WHEEL);
+  uinput->add_btn(BTN_LEFT);
+  uinput->add_btn(BTN_RIGHT);
+  uinput->add_btn(BTN_MIDDLE);
+  uinput->finish();
 
   // Init USB
   usb_init();
   usb_find_busses();
   usb_find_devices();
 
-  Xbox360Driver xbox360(0);
-  ToggleButton  toggle;
+  std::vector<Control*> controls;
 
-  BtnPortOut* btn_a = xbox360.get_btn_port_out(Xbox360Driver::XBOX360_BTN_A);
-  BtnPortOut* btn_b = xbox360.get_btn_port_out(Xbox360Driver::XBOX360_BTN_B);
-  BtnPortIn*  toggle_in  = toggle.get_btn_port_in(0);
-  BtnPortOut* toggle_out = toggle.get_btn_port_out(0);
+  Xbox360Driver* xbox360 = new Xbox360Driver(0);
+  ToggleButton*  toggle  = new ToggleButton();
+  AbsToRel*      abs_to_rel_x = new AbsToRel();
+  AbsToRel*      abs_to_rel_y = new AbsToRel();
+  AbsToRel*      abs_to_rel_x2 = new AbsToRel();
+  AbsToRel*      abs_to_rel_y2 = new AbsToRel();
 
-  btn_a->connect(btn_change);
-  btn_b->connect(toggle_in);
-
-  toggle_out->connect(xbox360.get_btn_port_in(0));
+  controls.push_back(xbox360);
+  controls.push_back(toggle);
+  controls.push_back(abs_to_rel_x);
+  controls.push_back(abs_to_rel_y);
+  controls.push_back(abs_to_rel_x2);
+  controls.push_back(abs_to_rel_y2);
 
   // ----------------------------
 
-  xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_X1) 
-    ->connect(uinput1.get_abs_port_in(0));
-  xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_Y1) 
-    ->connect(uinput1.get_abs_port_in(1));
+  xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_X1) 
+    ->connect(abs_to_rel_x->get_abs_port_in(0));
+  xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_Y1) 
+    ->connect(abs_to_rel_y->get_abs_port_in(0));
 
-  xbox360.get_btn_port_out(Xbox360Driver::XBOX360_BTN_A) 
-    ->connect(uinput1.get_btn_port_in(0));
-  xbox360.get_btn_port_out(Xbox360Driver::XBOX360_BTN_B) 
-    ->connect(uinput1.get_btn_port_in(1));
-  xbox360.get_btn_port_out(Xbox360Driver::XBOX360_BTN_X) 
-    ->connect(uinput1.get_btn_port_in(2));
+  xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_X2) 
+    ->connect(abs_to_rel_x2->get_abs_port_in(0));
+  xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_Y2) 
+    ->connect(abs_to_rel_y2->get_abs_port_in(0));
+
+  abs_to_rel_x->get_rel_port_out(0)
+    ->connect(uinput->get_rel_port_in(0));
+  abs_to_rel_y->get_rel_port_out(0)
+    ->connect(uinput->get_rel_port_in(1));
+  abs_to_rel_x2->get_rel_port_out(0)
+    ->connect(uinput->get_rel_port_in(2));
+  abs_to_rel_y2->get_rel_port_out(0)
+    ->connect(uinput->get_rel_port_in(3));
+
+  xbox360->get_btn_port_out(Xbox360Driver::XBOX360_BTN_A) 
+    ->connect(uinput->get_btn_port_in(0));
+  xbox360->get_btn_port_out(Xbox360Driver::XBOX360_BTN_B) 
+    ->connect(uinput->get_btn_port_in(1));
+  xbox360->get_btn_port_out(Xbox360Driver::XBOX360_BTN_X) 
+    ->connect(uinput->get_btn_port_in(2));
   
   // ----------------------------
 
-  xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_X2) 
-    ->connect(uinput2.get_abs_port_in(0));
-  xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_Y2) 
-    ->connect(uinput2.get_abs_port_in(1));
+  xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_LT) 
+    ->connect(xbox360->get_abs_port_in(Xbox360Driver::ABS_PORT_IN_RUMBLE_L));
 
-  xbox360.get_btn_port_out(Xbox360Driver::XBOX360_DPAD_DOWN) 
-    ->connect(uinput2.get_btn_port_in(0));
-  xbox360.get_btn_port_out(Xbox360Driver::XBOX360_DPAD_LEFT) 
-    ->connect(uinput2.get_btn_port_in(1));
-  xbox360.get_btn_port_out(Xbox360Driver::XBOX360_DPAD_RIGHT) 
-    ->connect(uinput2.get_btn_port_in(2));
-  
-  // ----------------------------
+  xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_RT)
+    ->connect(xbox360->get_abs_port_in(Xbox360Driver::ABS_PORT_IN_RUMBLE_R));
 
-  xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_LT) 
-    ->connect(xbox360.get_abs_port_in(Xbox360Driver::ABS_PORT_IN_RUMBLE_L));
+  xbox360->get_btn_port_out(Xbox360Driver::XBOX360_BTN_Y)->connect(btn_change);
 
-  xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_RT)
-    ->connect(xbox360.get_abs_port_in(Xbox360Driver::ABS_PORT_IN_RUMBLE_R));
-
-  xbox360.get_btn_port_out(Xbox360Driver::XBOX360_BTN_Y)->connect(btn_change);
-
-  xbox360.run();
+  bool quit = false;
+  while(!quit)
+    {
+      for(std::vector<Control*>::iterator i = controls.begin(); i != controls.end(); ++i)
+        {
+          (*i)->update(0.001f);
+        }
+      //std::cout << "." << std::flush;
+      //usleep(1000); // 0.001sec or 1msec
+    }
 
   return 0;
 }
diff --git a/uinput_driver.cpp b/uinput_driver.cpp
index 115b424..cfa277f 100644
--- a/uinput_driver.cpp
+++ b/uinput_driver.cpp
@@ -132,15 +132,27 @@ UInputDriver::add_btn(uint16_t code)
 void
 UInputDriver::on_rel(RelPortOut* port, uint16_t code)
 {
-  struct input_event ev;      
-  memset(&ev, 0, sizeof(ev));
+  if (port->get_state() != 0)
+    {
+      struct input_event ev;      
+      memset(&ev, 0, sizeof(ev));
 
-  gettimeofday(&ev.time, NULL);
-  ev.type  = EV_REL;
-  ev.code  = code;
-  ev.value = port->get_state();
+      gettimeofday(&ev.time, NULL);
+      ev.type  = EV_REL;
+      ev.code  = code;
+      ev.value = port->get_state();
 
- write(fd, &ev, sizeof(ev));  
+      write(fd, &ev, sizeof(ev));  
+
+      // Mouse Dev need these to send out events
+      memset(&ev, 0, sizeof(ev));
+
+      gettimeofday(&ev.time, NULL);
+      ev.type  = EV_SYN;
+      ev.code  = SYN_REPORT;
+
+      write(fd, &ev, sizeof(ev));  
+    }
 }
 
 void
@@ -154,7 +166,7 @@ UInputDriver::on_abs(AbsPortOut* port, uint16_t code)
   ev.code  = code;
   ev.value = port->get_state();
 
- write(fd, &ev, sizeof(ev)); 
+  write(fd, &ev, sizeof(ev)); 
 }
 
 void
@@ -168,7 +180,16 @@ UInputDriver::on_btn(BtnPortOut* port, uint16_t code)
   ev.code  = code;
   ev.value = port->get_state();
 
- write(fd, &ev, sizeof(ev)); 
+  write(fd, &ev, sizeof(ev)); 
+
+  // Mouse Dev need these to send out events
+  memset(&ev, 0, sizeof(ev));
+
+  gettimeofday(&ev.time, NULL);
+  ev.type  = EV_SYN;
+  ev.code  = SYN_REPORT;
+
+  write(fd, &ev, sizeof(ev));  
 }
 
 void
diff --git a/xbox360_driver.cpp b/xbox360_driver.cpp
index 74927d4..bfdad2b 100644
--- a/xbox360_driver.cpp
+++ b/xbox360_driver.cpp
@@ -24,6 +24,8 @@
 */
 
 #include <usb.h>
+#include <errno.h>
+#include <sstream>
 #include <iostream>
 #include <boost/format.hpp>
 #include <boost/bind.hpp>
@@ -166,66 +168,60 @@ Xbox360Driver::close_dev()
 }
 
 void
-Xbox360Driver::run()
-{ // Run this in a seperate Thread
-  bool quit = false;
-  uint8_t old_data[20];
-  memset(old_data, 0, 20);
-  while(!quit)
-    {
-      uint8_t data[20];
+Xbox360Driver::update(float delta)
+{ // Run this in a seperate Thread 
+  
+  uint8_t data[20];
 
-      int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, 20, 0 /*Timeout*/);
+  int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, 20, 5 /*Timeout*/);
 
-      if (ret < 0)
-        { // Error
-          std::cout << "USBError: " << ret << "\n" << usb_strerror() << std::endl;
-          std::cout << "Shutting down" << std::endl;
-          quit = true;
-        }
-      else if (ret == 0) // ignore
-        {
-          // happen with the Xbox360 every now and then, just
-          // ignore, seems harmless
-        }
-      else if (ret == 3) // ignore
-        {
-          // This data gets send when the controller is accessed the
-          // first time after being connected to the USB bus, no idea
-          // what it means, it seems to be identical for different
-          // controllers, we just ignore it
-          //
-          // len: 3 Data: 0x01 0x03 0x0e
-          // len: 3 Data: 0x02 0x03 0x00
-          // len: 3 Data: 0x03 0x03 0x03
-          // len: 3 Data: 0x08 0x03 0x00
-          // len: 3 Data: 0x01 0x03 0x00
-        }
-      else if (ret == 20 && data[0] == 0x00 && data[1] == 0x14)
-        {
-          if (memcmp(data, old_data, 20) == 0)
-            {
-              // Ignore the data, since nothing has changed
-            }                
-          else
-            {
-              memcpy(old_data, data, 20);
-              Xbox360Msg& msg = (Xbox360Msg&)data;
-              update(msg);
-            }                  
+  if (ret < 0)
+    { 
+      if (ret == -ETIMEDOUT)
+        { // ok
         }
       else
-        {
-          std::cout << "Unknown data: bytes: " << ret << " Data: ";
-          for(int j = 0; j < ret; ++j)
-            std::cout << boost::format("0x%02x ") % int(data[j]);
-          std::cout << std::endl;
-        } 
+        { // Error
+          std::ostringstream str;
+          str << "USBError: " << ret << "\n" << usb_strerror() << std::endl;
+          str << "Shutting down" << std::endl;
+          throw std::runtime_error(str.str());
+        }
     }
+  else if (ret == 0) // ignore
+    {
+      // happen with the Xbox360 every now and then, just
+      // ignore, seems harmless
+    }
+  else if (ret == 3) // ignore
+    {
+      // This data gets send when the controller is accessed the
+      // first time after being connected to the USB bus, no idea
+      // what it means, it seems to be identical for different
+      // controllers, we just ignore it
+      //
+      // len: 3 Data: 0x01 0x03 0x0e
+      // len: 3 Data: 0x02 0x03 0x00
+      // len: 3 Data: 0x03 0x03 0x03
+      // len: 3 Data: 0x08 0x03 0x00
+      // len: 3 Data: 0x01 0x03 0x00
+    }
+  else if (ret == 20 && data[0] == 0x00 && data[1] == 0x14)
+    {
+      Xbox360Msg& msg = (Xbox360Msg&)data;
+      process_msg(msg);
+    }
+  else
+    {
+      std::cout << "Unknown data: bytes: " << ret << " Data: ";
+      for(int j = 0; j < ret; ++j)
+        std::cout << boost::format("0x%02x ") % int(data[j]);
+      std::cout << std::endl;
+    } 
 }
 
 void
-Xbox360Driver::update(const Xbox360Msg& msg)
+Xbox360Driver::process_msg(const Xbox360Msg& msg)
 {
   btn_port_out[XBOX360_DPAD_UP]   ->set_state(msg.dpad_up);
   btn_port_out[XBOX360_DPAD_DOWN] ->set_state(msg.dpad_down);
@@ -248,10 +244,10 @@ Xbox360Driver::update(const Xbox360Msg& msg)
   btn_port_out[XBOX360_BTN_GUIDE]->set_state(msg.guide);
 
   abs_port_out[XBOX360_AXIS_X1]->set_state(msg.x1);
-  abs_port_out[XBOX360_AXIS_Y1]->set_state(msg.y1);
+  abs_port_out[XBOX360_AXIS_Y1]->set_state(-msg.y1);
 
   abs_port_out[XBOX360_AXIS_X2]->set_state(msg.x2);
-  abs_port_out[XBOX360_AXIS_Y2]->set_state(msg.y2);
+  abs_port_out[XBOX360_AXIS_Y2]->set_state(-msg.y2);
 
   abs_port_out[XBOX360_AXIS_LT]->set_state(msg.lt);
   abs_port_out[XBOX360_AXIS_RT]->set_state(msg.rt);
diff --git a/xbox360_driver.hpp b/xbox360_driver.hpp
index e9da6f9..ce9b00c 100644
--- a/xbox360_driver.hpp
+++ b/xbox360_driver.hpp
@@ -100,13 +100,13 @@ public:
   void on_rumble_left_abs(AbsPortOut* abs);
   void on_rumble_right_abs(AbsPortOut* abs);
 
-  void run();
+  void update(float delta);
 
 private:
   void init();
   void open_dev();
   void close_dev();
-  void update(const Xbox360Msg& msg);
+  void process_msg(const Xbox360Msg& msg);
 
   Xbox360Driver (const Xbox360Driver&);
   Xbox360Driver& operator= (const Xbox360Driver&);