From bfee0687b06a4870bda2bdc381f64433031522f4 Mon Sep 17 00:00:00 2001
From: Ingo Ruhnke <grumbel@gmx.de>
Date: Thu, 29 Apr 2010 13:41:29 +0200
Subject: [PATCH] Added option to output the device list in the style of xpad.c

---
 src/command_line_options.cpp        |  6 +++++
 src/command_line_options.hpp        |  1 +
 src/usb_read_thread.cpp             |  0
 src/usb_read_thread.hpp             |  0
 src/xbox360_controller.cpp          |  0
 src/xbox360_wireless_controller.cpp |  0
 src/xboxdrv.cpp                     | 39 +++++++++++++++++++++++++++++
 src/xboxdrv.hpp                     |  1 +
 src/xboxmsg.cpp                     | 18 +++++++++++++
 src/xboxmsg.hpp                     |  1 +
 10 files changed, 66 insertions(+)
 mode change 100755 => 100644 src/usb_read_thread.cpp
 mode change 100755 => 100644 src/usb_read_thread.hpp
 mode change 100755 => 100644 src/xbox360_controller.cpp
 mode change 100755 => 100644 src/xbox360_wireless_controller.cpp
 mode change 100755 => 100644 src/xboxdrv.cpp

diff --git a/src/command_line_options.cpp b/src/command_line_options.cpp
index 80747b3..2ae9a56 100644
--- a/src/command_line_options.cpp
+++ b/src/command_line_options.cpp
@@ -70,6 +70,7 @@ enum {
   OPTION_DEVICE_BY_ID,
   OPTION_DEVICE_BY_PATH,
   OPTION_LIST_SUPPORTED_DEVICES,
+  OPTION_LIST_SUPPORTED_DEVICES_XPAD,
   OPTION_LIST_CONTROLLER,
   OPTION_HELP_DEVICES
 };
@@ -123,6 +124,7 @@ CommandLineOptions::CommandLineOptions() :
     .add_option(OPTION_WID,          'w', "wid",     "N", "use wireless controller with wid N (default: 0)")
     .add_option(OPTION_LIST_CONTROLLER, 'L', "list-controller", "", "list available controllers")
     .add_option(OPTION_LIST_SUPPORTED_DEVICES, 0, "list-supported-devices", "", "list supported devices (used by xboxdrv-daemon.py)")
+    .add_option(OPTION_LIST_SUPPORTED_DEVICES_XPAD, 0, "list-supported-devices-xpad", "", "list supported devices (used by xboxdrv-daemon.py)")
     .add_option(OPTION_TEST_RUMBLE,  'R', "test-rumble", "", "map rumbling to LT and RT (for testing only)")
     .add_option(OPTION_NO_UINPUT,     0,  "no-uinput",   "", "do not try to start uinput event dispatching")
     .add_option(OPTION_MIMIC_XPAD,    0,  "mimic-xpad",  "", "Causes xboxdrv to use the same axis and button names as the xpad kernel driver")
@@ -475,6 +477,10 @@ CommandLineOptions::parse_args(int argc, char** argv)
             opts.mode = RUN_LIST_SUPPORTED_DEVICES;
             break;
 
+          case OPTION_LIST_SUPPORTED_DEVICES_XPAD:
+            opts.mode = RUN_LIST_SUPPORTED_DEVICES_XPAD;
+            break;
+
           case OPTION_LIST_CONTROLLER:
             opts.mode = RUN_LIST_CONTROLLER;
             break;
diff --git a/src/command_line_options.hpp b/src/command_line_options.hpp
index c5cb08e..0a803e8 100644
--- a/src/command_line_options.hpp
+++ b/src/command_line_options.hpp
@@ -35,6 +35,7 @@ public:
          RUN_DAEMON, 
          RUN_LIST_CONTROLLER,
          RUN_LIST_SUPPORTED_DEVICES,
+         RUN_LIST_SUPPORTED_DEVICES_XPAD,
          PRINT_VERSION,
          PRINT_HELP,
          PRINT_HELP_DEVICES,
diff --git a/src/usb_read_thread.cpp b/src/usb_read_thread.cpp
old mode 100755
new mode 100644
diff --git a/src/usb_read_thread.hpp b/src/usb_read_thread.hpp
old mode 100755
new mode 100644
diff --git a/src/xbox360_controller.cpp b/src/xbox360_controller.cpp
old mode 100755
new mode 100644
diff --git a/src/xbox360_wireless_controller.cpp b/src/xbox360_wireless_controller.cpp
old mode 100755
new mode 100644
diff --git a/src/xboxdrv.cpp b/src/xboxdrv.cpp
old mode 100755
new mode 100644
index 5fc9e6b..c342b57
--- a/src/xboxdrv.cpp
+++ b/src/xboxdrv.cpp
@@ -19,6 +19,7 @@
 #include <boost/lexical_cast.hpp>
 #include <boost/function.hpp>
 #include <boost/bind.hpp>
+#include <boost/scoped_array.hpp>
 #include <sys/time.h>
 #include <ctype.h>
 #include <time.h>
@@ -660,6 +661,40 @@ Xboxdrv::run_list_supported_devices()
     }    
 }
 
+bool xpad_device_sorter(const XPadDevice& lhs, const XPadDevice& rhs)
+{
+  if (lhs.idVendor < rhs.idVendor)
+  {
+    return true;
+  }
+  else if (lhs.idVendor == rhs.idVendor)
+  {
+    return lhs.idProduct < rhs.idProduct;
+  }
+  else
+  {
+    return false;
+  }
+}
+
+void
+Xboxdrv::run_list_supported_devices_xpad()
+{
+  boost::scoped_array<XPadDevice> sorted_devices(new XPadDevice[xpad_devices_count]);
+  memcpy(sorted_devices.get(), xpad_devices, sizeof(XPadDevice) * xpad_devices_count);
+
+  std::sort(sorted_devices.get(), sorted_devices.get() + xpad_devices_count, xpad_device_sorter);
+
+  for(int i = 0; i < xpad_devices_count; ++i)
+    {
+      std::cout << boost::format("{ 0x%04x, 0x%04x, \"%s\", %s },\n")
+        % int(sorted_devices[i].idVendor)
+        % int(sorted_devices[i].idProduct)
+        % sorted_devices[i].name
+        % gamepadtype_to_macro_string(sorted_devices[i].type);
+    }    
+}
+
 void
 Xboxdrv::run_help_devices()
 {
@@ -715,6 +750,10 @@ Xboxdrv::main(int argc, char** argv)
             run_list_supported_devices();
             break;
 
+          case CommandLineOptions::RUN_LIST_SUPPORTED_DEVICES_XPAD:
+            run_list_supported_devices_xpad();
+            break;
+
           case CommandLineOptions::PRINT_VERSION:
             opts.print_version();
             break;
diff --git a/src/xboxdrv.hpp b/src/xboxdrv.hpp
index b42fab4..b6b0424 100644
--- a/src/xboxdrv.hpp
+++ b/src/xboxdrv.hpp
@@ -31,6 +31,7 @@ private:
   void run_main(const CommandLineOptions& opts);
   void run_daemon(const CommandLineOptions& opts);
   void run_list_supported_devices();
+  void run_list_supported_devices_xpad();
   void run_help_devices();
   void run_list_controller();
 
diff --git a/src/xboxmsg.cpp b/src/xboxmsg.cpp
index d56b148..ceb37c7 100644
--- a/src/xboxmsg.cpp
+++ b/src/xboxmsg.cpp
@@ -58,6 +58,24 @@ std::string gamepadtype_to_string(const GamepadType& type)
     }
 }
 
+
+std::string gamepadtype_to_macro_string(const GamepadType& type)
+{
+  switch (type)
+    {
+      case GAMEPAD_XBOX360: return "GAMEPAD_XBOX360";
+      case GAMEPAD_XBOX360_WIRELESS: return "GAMEPAD_XBOX360_WIRELESS";
+      case GAMEPAD_XBOX: return "GAMEPAD_XBOX";
+      case GAMEPAD_XBOX_MAT: return "GAMEPAD_XBOX_MAT";
+      case GAMEPAD_XBOX360_GUITAR: return "GAMEPAD_XBOX360_GUITAR";
+      case GAMEPAD_FIRESTORM: return "GAMEPAD_FIRESTORM";
+      case GAMEPAD_FIRESTORM_VSB: return "GAMEPAD_FIRESTORM_VSB";
+      case GAMEPAD_SAITEK_P2500: return "GAMEPAD_SAITEK_P2500";
+      default:
+        assert(!"Unknown gamepad type supplied");
+    }
+}
+
 std::ostream& operator<<(std::ostream& out, const GamepadType& type) 
 {
   switch (type)
diff --git a/src/xboxmsg.hpp b/src/xboxmsg.hpp
index c073d0b..4dec543 100644
--- a/src/xboxmsg.hpp
+++ b/src/xboxmsg.hpp
@@ -256,6 +256,7 @@ std::string btn2string(XboxButton btn);
 std::string axis2string(XboxAxis axis);
 
 std::string gamepadtype_to_string(const GamepadType& type);
+std::string gamepadtype_to_macro_string(const GamepadType& type);
 
 #endif