From 452f724cd54518199c24c0288e48b5940010b301 Mon Sep 17 00:00:00 2001
From: Ingo Ruhnke <grumbel@gmx.de>
Date: Thu, 20 May 2010 06:47:15 +0200
Subject: [PATCH] Moved sync handling into linux_uinput.?pp

---
 src/linux_uinput.cpp | 17 +++++++++++++++--
 src/linux_uinput.hpp |  9 +++++++--
 src/uinput.cpp       | 34 +++++++++++++++++-----------------
 3 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/src/linux_uinput.cpp b/src/linux_uinput.cpp
index 0e017be..aeb40fa 100644
--- a/src/linux_uinput.cpp
+++ b/src/linux_uinput.cpp
@@ -44,7 +44,8 @@ LinuxUinput::LinuxUinput(const std::string& name_, uint16_t vendor_, uint16_t pr
   led_bit(false),
   ff_bit(false),
   ff_handler(0),
-  ff_callback()
+  ff_callback(),
+  needs_sync(true)
 {
   std::fill_n(abs_lst, ABS_CNT, false);
   std::fill_n(rel_lst, REL_CNT, false);
@@ -207,6 +208,8 @@ LinuxUinput::finish()
 void
 LinuxUinput::send(uint16_t type, uint16_t code, int32_t value)
 {
+  needs_sync = true;
+
   struct input_event ev;      
   memset(&ev, 0, sizeof(ev));
 
@@ -221,9 +224,19 @@ LinuxUinput::send(uint16_t type, uint16_t code, int32_t value)
   if (write(fd, &ev, sizeof(ev)) < 0)
     throw std::runtime_error(std::string("uinput:send_button: ") + strerror(errno)); 
 }
+
+void
+LinuxUinput::sync()
+{
+  if (needs_sync)
+  {
+    send(EV_SYN, SYN_REPORT, 0);
+    needs_sync = false;
+  }
+}
 
 void
-LinuxUinput::update(int msec_delta)
+LinuxUinput::update_force_feedback(int msec_delta)
 {
   if (ff_bit)
   {
diff --git a/src/linux_uinput.hpp b/src/linux_uinput.hpp
index 9b9c547..2171e8f 100644
--- a/src/linux_uinput.hpp
+++ b/src/linux_uinput.hpp
@@ -49,6 +49,8 @@ private:
   ForceFeedbackHandler* ff_handler;
   boost::function<void (uint8_t, uint8_t)> ff_callback;
 
+  bool needs_sync;
+
 public:
   LinuxUinput(const std::string& name, uint16_t vendor, uint16_t product);
   ~LinuxUinput();
@@ -67,13 +69,16 @@ public:
 
   void set_ff_callback(const boost::function<void (uint8_t, uint8_t)>& callback);
 
-  /** Finish*/
+  /** Finalized the device creation */
   void finish();
   /*@}*/
 
   void send(uint16_t type, uint16_t code, int32_t value);
 
-  void update(int msec_delta);
+  /** Sends out a sync event if there is a need for it. */
+  void sync();
+
+  void update_force_feedback(int msec_delta);
 
 private:
   LinuxUinput (const LinuxUinput&);
diff --git a/src/uinput.cpp b/src/uinput.cpp
index fd46f27..b3698da 100644
--- a/src/uinput.cpp
+++ b/src/uinput.cpp
@@ -199,9 +199,9 @@ uInput::create_uinput_device(int device_id)
     {
       dev_name << " - Keyboard Emulation";
     }
-    else if (dev_name > 0)
+    else if (device_id > 0)
     {
-      dev_name << " - Joystick " << device_id+1;
+      dev_name << " - 2" << device_id+1;
     }
 
     boost::shared_ptr<LinuxUinput> dev(new LinuxUinput(dev_name.str(), m_dev.idVendor, m_dev.idProduct));
@@ -641,8 +641,6 @@ uInput::send(Xbox360GuitarMsg& msg)
 void
 uInput::update(int msec_delta)
 {
-  bool needs_syncronization = false;
-
   // Relative Motion emulation for axis
   for(std::vector<RelAxisState>::iterator i = rel_axis.begin(); i != rel_axis.end(); ++i)
   {
@@ -650,10 +648,17 @@ uInput::update(int msec_delta)
 
     if (i->time >= i->next_time)
     {
-      get_mouse_uinput()->send(EV_REL, cfg.axis_map[i->axis].code,
-                               static_cast<int>(cfg.axis_map[i->axis].rel.value * axis_state[i->axis]) / 32767);
+      if (i->axis == XBOX_AXIS_TRIGGER)
+      { // dirty little hack, as we can't get the axis range easily by other means
+        get_mouse_uinput()->send(EV_REL, cfg.axis_map[i->axis].code,
+                                 static_cast<int>(cfg.axis_map[i->axis].rel.value * axis_state[i->axis]) / 255);
+      }
+      else
+      {
+        get_mouse_uinput()->send(EV_REL, cfg.axis_map[i->axis].code,
+                                 static_cast<int>(cfg.axis_map[i->axis].rel.value * axis_state[i->axis]) / 32767);
+      }
       i->next_time += cfg.axis_map[i->axis].rel.repeat;
-      needs_syncronization = true;
     }
   }
 
@@ -667,17 +672,15 @@ uInput::update(int msec_delta)
       get_mouse_uinput()->send(EV_REL, cfg.btn_map.lookup(i->button).code, 
                                static_cast<int>(cfg.btn_map.lookup(i->button).rel.value * button_state[i->button]));
       i->next_time += cfg.btn_map.lookup(i->button).rel.repeat;
-      needs_syncronization = true;
     }
   }
 
-  if (needs_syncronization)
-  {
-    get_mouse_uinput()->send(EV_SYN, SYN_REPORT, 0);
-  }
+  get_force_feedback_uinput()->update_force_feedback(msec_delta);
 
-  // Update forcefeedback 
-  get_force_feedback_uinput()->update(msec_delta);
+  for(uInputDevs::iterator i = uinput_devs.begin(); i != uinput_devs.end(); ++i)
+  {
+    i->second->sync();
+  }
 }
 
 void
@@ -744,9 +747,6 @@ uInput::send_key(int device_id, int ev_code, bool value)
   else
   {
     get_uinput(device_id)->send(EV_KEY, ev_code, value);
-
-    // FIXME: should sync only after all buttons are handled
-    get_uinput(device_id)->send(EV_SYN, SYN_REPORT, 0); 
   }
 }