From 6ded8063af65a8bf1eaf75f7b04ec23b8b2e6dcc Mon Sep 17 00:00:00 2001
From: Ingo Ruhnke <grumbel@gmx.de>
Date: Sat, 29 Jan 2011 05:28:53 +0100
Subject: [PATCH] Added ability to set LED per controller slot instead of just
 globally

---
 NEWS                            |  1 +
 src/command_line_options.cpp    |  4 ++--
 src/controller_slot_options.cpp |  3 ++-
 src/controller_slot_options.hpp |  4 ++++
 src/options.cpp                 |  7 ++++++-
 src/options.hpp                 |  2 +-
 src/xboxdrv.cpp                 |  4 ++--
 src/xboxdrv_daemon.cpp          | 12 ++++++++++--
 src/xboxdrv_daemon.hpp          |  6 ++++++
 9 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/NEWS b/NEWS
index 9732b5d..4e29400 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ xboxdrv 0.7.1 - (??/???/2011)
 * added support for Playstation button names (triangle,
   circle, square, cross, L1, L2, L3, R1, R2, R3)
 * added --on-connect and --on-disconnect to xboxdrv --daemon
+* added ability to set LED per controller slot
 
 
 xboxdrv 0.7.0 - (28/Jan/2011)
diff --git a/src/command_line_options.cpp b/src/command_line_options.cpp
index 706a848..96680a4 100644
--- a/src/command_line_options.cpp
+++ b/src/command_line_options.cpp
@@ -317,7 +317,7 @@ CommandLineParser::init_ini(Options* opts)
     ("silent", &opts->silent)
     ("quiet",  &opts->quiet)
     ("rumble", &opts->rumble)
-    ("led", &opts->led)
+    ("led", boost::bind(&Options::set_led, boost::ref(opts), _1))
     ("rumble-l", &opts->rumble_l)
     ("rumble-r", &opts->rumble_r)
     ("rumble-gain", &opts->rumble_gain)
@@ -706,7 +706,7 @@ CommandLineParser::parse_args(int argc, char** argv, Options* options)
         }
         else
         {
-          opts.led = boost::lexical_cast<int>(opt.argument);
+          opts.set_led(opt.argument);
         }
         break;
 
diff --git a/src/controller_slot_options.cpp b/src/controller_slot_options.cpp
index 6c95d07..9006b68 100644
--- a/src/controller_slot_options.cpp
+++ b/src/controller_slot_options.cpp
@@ -25,7 +25,8 @@
 ControllerSlotOptions::ControllerSlotOptions() :
   m_options(),
   m_match_rules(),
-  m_force_feedback(false)
+  m_force_feedback(false),
+  m_led_status(-1)
 {
 }
 
diff --git a/src/controller_slot_options.hpp b/src/controller_slot_options.hpp
index db84e42..7893592 100644
--- a/src/controller_slot_options.hpp
+++ b/src/controller_slot_options.hpp
@@ -46,10 +46,14 @@ public:
 
   int get_ff_device() const { return 0; }
 
+  int get_led_status() const { return m_led_status; }
+  void set_led_status(int v)  { m_led_status = v; }
+
 private:
   std::map<int, ControllerOptions> m_options;
   std::vector<ControllerMatchRulePtr> m_match_rules;
   bool m_force_feedback;
+  int m_led_status;
 };
 
 #endif
diff --git a/src/options.cpp b/src/options.cpp
index b7e13cc..c9c87b7 100644
--- a/src/options.cpp
+++ b/src/options.cpp
@@ -32,7 +32,6 @@ Options::Options() :
   silent (false),
   quiet  (false),
   rumble (false),
-  led    (-1),
   rumble_l(-1),
   rumble_r(-1),
   rumble_gain(255),
@@ -161,6 +160,12 @@ Options::set_debug()
   g_logger.incr_log_level(Logger::kDebug);
 }
 
+void
+Options::set_led(const std::string& value)
+{
+  get_controller_slot().set_led_status(boost::lexical_cast<int>(value));
+}
+
 void
 Options::set_device_name(const std::string& name)
 {
diff --git a/src/options.hpp b/src/options.hpp
index 335c5a6..45f0894 100644
--- a/src/options.hpp
+++ b/src/options.hpp
@@ -58,7 +58,6 @@ public:
   bool silent;
   bool quiet;
   bool rumble;
-  int  led;
   int  rumble_l;
   int  rumble_r;
   int  rumble_gain;
@@ -135,6 +134,7 @@ public:
   void set_debug();
   void set_quiet();
 
+  void set_led(const std::string& value);
   void set_device_name(const std::string& name);
   void set_mouse();
   void set_guitar();
diff --git a/src/xboxdrv.cpp b/src/xboxdrv.cpp
index a29d1d0..f5bf1ad 100644
--- a/src/xboxdrv.cpp
+++ b/src/xboxdrv.cpp
@@ -418,10 +418,10 @@ Xboxdrv::run_main(const Options& opts)
   int jsdev_number = find_jsdev_number();
   int evdev_number = find_evdev_number();
 
-  if (opts.led == -1)
+  if (opts.get_controller_slot().get_led_status() == -1)
     controller->set_led(2 + jsdev_number % 4);
   else
-    controller->set_led(opts.led);
+    controller->set_led(opts.get_controller_slot().get_led_status());
 
   if (opts.rumble_l != -1 && opts.rumble_r != -1)
   { // Only set rumble when explicitly requested
diff --git a/src/xboxdrv_daemon.cpp b/src/xboxdrv_daemon.cpp
index e505e95..51e21e8 100644
--- a/src/xboxdrv_daemon.cpp
+++ b/src/xboxdrv_daemon.cpp
@@ -219,7 +219,8 @@ XboxdrvDaemon::init_uinput(const Options& opts)
                                                   ControllerSlotConfig::create(*m_uinput, slot_count,
                                                                                opts.extra_devices,
                                                                                controller->second),
-                                                  controller->second.get_match_rules()));
+                                                  controller->second.get_match_rules(),
+                                                  controller->second.get_led_status()));
       slot_count += 1;
     }
 
@@ -482,7 +483,14 @@ XboxdrvDaemon::launch_xboxdrv(const XPadDevice& dev_type, const Options& opts,
   {
     std::auto_ptr<XboxGenericController> controller = XboxControllerFactory::create(dev_type, dev, opts);
 
-    controller->set_led(2 + (slot.id % 4));
+    if (slot.led_status == -1)
+    {
+      controller->set_led(2 + (slot.id % 4));
+    }
+    else
+    {
+      controller->set_led(slot.led_status);
+    }
 
     std::auto_ptr<MessageProcessor> message_proc;
     if (m_uinput.get())
diff --git a/src/xboxdrv_daemon.hpp b/src/xboxdrv_daemon.hpp
index 8d38a8e..3931e2f 100644
--- a/src/xboxdrv_daemon.hpp
+++ b/src/xboxdrv_daemon.hpp
@@ -40,22 +40,26 @@ private:
     int id;
     ControllerSlotConfigPtr config;
     std::vector<ControllerMatchRulePtr> rules;
+    int led_status;
     XboxdrvThread* thread;
     
     ControllerSlot() :
       id(),
       config(),
       rules(),
+      led_status(-1),
       thread(0)
     {}
 
     ControllerSlot(int id_,
                    ControllerSlotConfigPtr config_,
                    std::vector<ControllerMatchRulePtr> rules_,
+                   int led_status_,
                    XboxdrvThread* thread_ = 0) :
       id(id_),
       config(config_),
       rules(rules_),
+      led_status(led_status_),
       thread(thread_)
     {}
 
@@ -63,6 +67,7 @@ private:
       id(rhs.id),
       config(rhs.config),
       rules(rhs.rules),
+      led_status(rhs.led_status),
       thread(rhs.thread)
     {}
 
@@ -73,6 +78,7 @@ private:
         id     = rhs.id;
         config = rhs.config;
         rules  = rhs.rules;
+        led_status = rhs.led_status;
         thread = rhs.thread;
       }
       return *this;