diff --git a/src/button_event.cpp b/src/button_event.cpp
index 603020a..b8f4145 100644
--- a/src/button_event.cpp
+++ b/src/button_event.cpp
@@ -43,10 +43,16 @@ ButtonEvent::create_abs(int code)
   return ButtonEvent::create(new AbsButtonEventHandler(code));
 }
 
+ButtonEventPtr 
+ButtonEvent::create_key(int device_id, int code)
+{
+  return ButtonEvent::create(new KeyButtonEventHandler(device_id, code));
+}
+
 ButtonEventPtr
 ButtonEvent::create_key(int code)
 {
-  return ButtonEvent::create(new KeyButtonEventHandler(code));
+  return ButtonEvent::create(new KeyButtonEventHandler(DEVICEID_AUTO, code));
 }
 
 ButtonEventPtr
@@ -245,7 +251,7 @@ KeyButtonEventHandler::KeyButtonEventHandler() :
   std::fill_n(m_secondary_codes, MAX_MODIFIER + 1, UIEvent::invalid());
 }
 
-KeyButtonEventHandler::KeyButtonEventHandler(int code) :
+KeyButtonEventHandler::KeyButtonEventHandler(int device_id, int code) :
   m_state(false),
   m_codes(),
   m_secondary_codes(),
@@ -254,7 +260,7 @@ KeyButtonEventHandler::KeyButtonEventHandler(int code) :
 {
   std::fill_n(m_codes, MAX_MODIFIER + 1, UIEvent::invalid());
   std::fill_n(m_secondary_codes, MAX_MODIFIER + 1, UIEvent::invalid());
-  m_codes[0] = UIEvent::create(DEVICEID_AUTO, EV_KEY, code);
+  m_codes[0] = UIEvent::create(device_id, EV_KEY, code);
 }
 
 void
diff --git a/src/button_event.hpp b/src/button_event.hpp
index 04ed5ee..3afd6e0 100644
--- a/src/button_event.hpp
+++ b/src/button_event.hpp
@@ -37,6 +37,7 @@ public:
   static ButtonEventPtr invalid();
   static ButtonEventPtr create(ButtonEventHandler* handler);
   static ButtonEventPtr create_key(int code);
+  static ButtonEventPtr create_key(int device_id, int code);
   static ButtonEventPtr create_key();
   static ButtonEventPtr create_abs(int code);
   static ButtonEventPtr create_rel(int code);
@@ -79,7 +80,7 @@ public:
 
 public:
   KeyButtonEventHandler();
-  KeyButtonEventHandler(int code);
+  KeyButtonEventHandler(int deviceid, int code);
 
   void init(UInput& uinput, int slot, bool extra_devices);
   void send(UInput& uinput, bool value);
diff --git a/src/command_line_options.cpp b/src/command_line_options.cpp
index 57c5aac..a164131 100644
--- a/src/command_line_options.cpp
+++ b/src/command_line_options.cpp
@@ -542,7 +542,7 @@ CommandLineParser::parse_args(int argc, char** argv, Options* options)
         break;
 
       case OPTION_MIMIC_XPAD:
-        opts.get_controller_options().uinput.mimic_xpad();
+        opts.set_mimic_xpad();
         break;
 
       case OPTION_TYPE:
diff --git a/src/options.cpp b/src/options.cpp
index c7e2b6c..ed9a8b6 100644
--- a/src/options.cpp
+++ b/src/options.cpp
@@ -233,6 +233,12 @@ Options::set_force_feedback(const std::string& value)
 void
 Options::set_mimic_xpad()
 {
+  // BTN_BACK is recognized as mouse button, so we have to disallow
+  // automatic allocation
+  extra_devices = false;
+  extra_events  = false;
+
+  set_device_name("Microsoft X-Box 360 pad");
   get_controller_options().uinput.mimic_xpad();
 }
 
diff --git a/src/uinput_options.cpp b/src/uinput_options.cpp
index 0352aea..ddcaad5 100644
--- a/src/uinput_options.cpp
+++ b/src/uinput_options.cpp
@@ -55,42 +55,41 @@ UInputOptions::get_axis_map() const
 void
 UInputOptions::mimic_xpad()
 {
-  // FIXME: need to set this somewhere:
-  // device_name = "Microsoft X-Box 360 pad";
+  // device_name is set in Options::set_mimic_xpad()
 
-  get_btn_map().bind(XBOX_BTN_START, ButtonEvent::create_key(BTN_START));
-  get_btn_map().bind(XBOX_BTN_GUIDE, ButtonEvent::create_key(BTN_MODE));
-  get_btn_map().bind(XBOX_BTN_BACK,  ButtonEvent::create_key(BTN_BACK));
+  get_btn_map().bind(XBOX_BTN_START, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_START));
+  get_btn_map().bind(XBOX_BTN_GUIDE, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_MODE));
+  get_btn_map().bind(XBOX_BTN_BACK,  ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_BACK));
 
-  get_btn_map().bind(XBOX_BTN_A, ButtonEvent::create_key(BTN_A));
-  get_btn_map().bind(XBOX_BTN_B, ButtonEvent::create_key(BTN_B));
-  get_btn_map().bind(XBOX_BTN_X, ButtonEvent::create_key(BTN_X));
-  get_btn_map().bind(XBOX_BTN_Y, ButtonEvent::create_key(BTN_Y));
+  get_btn_map().bind(XBOX_BTN_A, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_A));
+  get_btn_map().bind(XBOX_BTN_B, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_B));
+  get_btn_map().bind(XBOX_BTN_X, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_X));
+  get_btn_map().bind(XBOX_BTN_Y, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_Y));
 
-  get_btn_map().bind(XBOX_BTN_LB, ButtonEvent::create_key(BTN_TL));
-  get_btn_map().bind(XBOX_BTN_RB, ButtonEvent::create_key(BTN_TR));
+  get_btn_map().bind(XBOX_BTN_LB, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_TL));
+  get_btn_map().bind(XBOX_BTN_RB, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_TR));
             
-  get_btn_map().bind(XBOX_BTN_LT, ButtonEvent::create_key(BTN_TL2));
-  get_btn_map().bind(XBOX_BTN_RT, ButtonEvent::create_key(BTN_TR2));
+  get_btn_map().bind(XBOX_BTN_LT, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_TL2));
+  get_btn_map().bind(XBOX_BTN_RT, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_TR2));
             
-  get_btn_map().bind(XBOX_BTN_THUMB_L, ButtonEvent::create_key(BTN_THUMBL));
-  get_btn_map().bind(XBOX_BTN_THUMB_R, ButtonEvent::create_key(BTN_THUMBR));
+  get_btn_map().bind(XBOX_BTN_THUMB_L, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_THUMBL));
+  get_btn_map().bind(XBOX_BTN_THUMB_R, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_THUMBR));
             
-  get_btn_map().bind(XBOX_DPAD_UP,    ButtonEvent::create_key(BTN_BASE));
-  get_btn_map().bind(XBOX_DPAD_DOWN,  ButtonEvent::create_key(BTN_BASE2));
-  get_btn_map().bind(XBOX_DPAD_LEFT,  ButtonEvent::create_key(BTN_BASE3));
-  get_btn_map().bind(XBOX_DPAD_RIGHT, ButtonEvent::create_key(BTN_BASE4));
+  get_btn_map().bind(XBOX_DPAD_UP,    ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_BASE));
+  get_btn_map().bind(XBOX_DPAD_DOWN,  ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_BASE2));
+  get_btn_map().bind(XBOX_DPAD_LEFT,  ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_BASE3));
+  get_btn_map().bind(XBOX_DPAD_RIGHT, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_BASE4));
 
   // Axis Mapping
-  get_axis_map().bind(XBOX_AXIS_X1,      AxisEvent::create_abs(DEVICEID_AUTO, ABS_X,  -32768, 32767, 16, 128));
-  get_axis_map().bind(XBOX_AXIS_Y1,      AxisEvent::create_abs(DEVICEID_AUTO, ABS_Y,  -32768, 32767, 16, 128));
-  get_axis_map().bind(XBOX_AXIS_X2,      AxisEvent::create_abs(DEVICEID_AUTO, ABS_RX, -32768, 32767, 16, 128));
-  get_axis_map().bind(XBOX_AXIS_Y2,      AxisEvent::create_abs(DEVICEID_AUTO, ABS_RY, -32768, 32767, 16, 128));
-  get_axis_map().bind(XBOX_AXIS_LT,      AxisEvent::create_abs(DEVICEID_AUTO, ABS_Z,  0, 255, 0, 0));
-  get_axis_map().bind(XBOX_AXIS_RT,      AxisEvent::create_abs(DEVICEID_AUTO, ABS_RZ, 0, 255, 0, 0));
-  get_axis_map().bind(XBOX_AXIS_TRIGGER, AxisEvent::create_abs(DEVICEID_AUTO, ABS_Z, -255, 255, 0, 0));
-  get_axis_map().bind(XBOX_AXIS_DPAD_X,  AxisEvent::create_abs(DEVICEID_AUTO, ABS_HAT0X, -1, 1, 0, 0));
-  get_axis_map().bind(XBOX_AXIS_DPAD_Y,  AxisEvent::create_abs(DEVICEID_AUTO, ABS_HAT0Y, -1, 1, 0, 0));
+  get_axis_map().bind(XBOX_AXIS_X1,      AxisEvent::create_abs(DEVICEID_JOYSTICK, ABS_X,  -32768, 32767, 16, 128));
+  get_axis_map().bind(XBOX_AXIS_Y1,      AxisEvent::create_abs(DEVICEID_JOYSTICK, ABS_Y,  -32768, 32767, 16, 128));
+  get_axis_map().bind(XBOX_AXIS_X2,      AxisEvent::create_abs(DEVICEID_JOYSTICK, ABS_RX, -32768, 32767, 16, 128));
+  get_axis_map().bind(XBOX_AXIS_Y2,      AxisEvent::create_abs(DEVICEID_JOYSTICK, ABS_RY, -32768, 32767, 16, 128));
+  get_axis_map().bind(XBOX_AXIS_LT,      AxisEvent::create_abs(DEVICEID_JOYSTICK, ABS_Z,  0, 255, 0, 0));
+  get_axis_map().bind(XBOX_AXIS_RT,      AxisEvent::create_abs(DEVICEID_JOYSTICK, ABS_RZ, 0, 255, 0, 0));
+  get_axis_map().bind(XBOX_AXIS_TRIGGER, AxisEvent::create_abs(DEVICEID_JOYSTICK, ABS_Z, -255, 255, 0, 0));
+  get_axis_map().bind(XBOX_AXIS_DPAD_X,  AxisEvent::create_abs(DEVICEID_JOYSTICK, ABS_HAT0X, -1, 1, 0, 0));
+  get_axis_map().bind(XBOX_AXIS_DPAD_Y,  AxisEvent::create_abs(DEVICEID_JOYSTICK, ABS_HAT0Y, -1, 1, 0, 0));
 }
 
 void