[gnome-games] gamepad: Support gamepads without a mapping



commit 327986654c4c2dbec513f862ee4ad29519ba72f7
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Sat Aug 13 10:07:07 2016 +0200

    gamepad: Support gamepads without a mapping
    
    Support gamepads sending proper gamepad events (buttons A, B, X, Y...)
    even if they don't have a mapping.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=769836

 src/gamepad/gamepad.vala                 |   34 ++++++++++++++++++++++++++-
 src/gamepad/linux/linux-raw-gamepad.vala |   37 +++++++++++++++++++++++++++++-
 src/gamepad/raw-gamepad.vala             |    2 +
 3 files changed, 71 insertions(+), 2 deletions(-)
---
diff --git a/src/gamepad/gamepad.vala b/src/gamepad/gamepad.vala
index d06bdf9..0082dee 100644
--- a/src/gamepad/gamepad.vala
+++ b/src/gamepad/gamepad.vala
@@ -33,14 +33,27 @@ private class Games.Gamepad : Object {
                this.raw_gamepad = raw_gamepad;
                var guid = raw_gamepad.guid;
                var mappings_manager = GamepadMappingsManager.get_instance ();
-               mapping = new GamepadMapping.from_sdl_string (mappings_manager.get_mapping (guid));
+               try {
+                       mapping = new GamepadMapping.from_sdl_string (mappings_manager.get_mapping (guid));
+               }
+               catch (Error e) {
+                       debug (e.message);
+               }
+               raw_gamepad.standard_button_event.connect (on_standard_button_event);
                raw_gamepad.button_event.connect (on_raw_button_event);
                raw_gamepad.axis_event.connect (on_raw_axis_event);
                raw_gamepad.dpad_event.connect (on_raw_dpad_event);
                raw_gamepad.unplugged.connect (() => unplugged ());
        }
 
+       private void on_standard_button_event (StandardGamepadButton button, bool value) {
+               button_event (button, value);
+       }
+
        private void on_raw_button_event (int button, bool value) {
+               if (mapping == null)
+                       return;
+
                var event = mapping.get_button_mapping (button);
                switch (event.type) {
                case GamepadInputType.AXIS:
@@ -55,6 +68,9 @@ private class Games.Gamepad : Object {
        }
 
        private void on_raw_axis_event (int axis, double value) {
+               if (mapping == null)
+                       return;
+
                var event = mapping.get_axis_mapping (axis);
                switch (event.type) {
                case GamepadInputType.AXIS:
@@ -69,6 +85,22 @@ private class Games.Gamepad : Object {
        }
 
        private void on_raw_dpad_event (int dpad_index, int axis, int value) {
+               if (mapping == null) {
+                       if (dpad_index != 0)
+                               return;
+
+                       if (axis == 0) {
+                               button_event (StandardGamepadButton.DPAD_LEFT, value < 0);
+                               button_event (StandardGamepadButton.DPAD_RIGHT, value > 0);
+                       }
+                       else if (axis == 1) {
+                               button_event (StandardGamepadButton.DPAD_UP, value < 0);
+                               button_event (StandardGamepadButton.DPAD_DOWN, value > 0);
+                       }
+
+                       return;
+               }
+
                var event = mapping.get_dpad_mapping (dpad_index, axis, value);
                switch (event.type) {
                case GamepadInputType.AXIS:
diff --git a/src/gamepad/linux/linux-raw-gamepad.vala b/src/gamepad/linux/linux-raw-gamepad.vala
index 8a6bfaf..65dd850 100644
--- a/src/gamepad/linux/linux-raw-gamepad.vala
+++ b/src/gamepad/linux/linux-raw-gamepad.vala
@@ -135,7 +135,9 @@ private class Games.LinuxRawGamepad : Object, RawGamepad {
                int code = event.code;
                switch (event.type) {
                case Linux.Input.EV_KEY:
-                       if (code >= Linux.Input.BTN_MISC)
+                       if ((code & Linux.Input.BTN_GAMEPAD) == Linux.Input.BTN_GAMEPAD)
+                               standard_button_event (button_to_standard_button (code), (bool) event.value);
+                       else if ((code & Linux.Input.BTN_MISC) == Linux.Input.BTN_MISC)
                                button_event (key_map[code - Linux.Input.BTN_MISC], (bool) event.value);
 
                        break;
@@ -190,6 +192,39 @@ private class Games.LinuxRawGamepad : Object, RawGamepad {
 
                return builder.str;
        }
+
+       private StandardGamepadButton button_to_standard_button (int code) {
+               switch (code) {
+               case Linux.Input.BTN_A:
+                       return StandardGamepadButton.A;
+               case Linux.Input.BTN_B:
+                       return StandardGamepadButton.B;
+               case Linux.Input.BTN_X:
+                       return StandardGamepadButton.Y;
+               case Linux.Input.BTN_Y:
+                       return StandardGamepadButton.X;
+               case Linux.Input.BTN_TL:
+                       return StandardGamepadButton.SHOULDER_L;
+               case Linux.Input.BTN_TR:
+                       return StandardGamepadButton.SHOULDER_R;
+               case Linux.Input.BTN_TL2:
+                       return StandardGamepadButton.TRIGGER_L;
+               case Linux.Input.BTN_TR2:
+                       return StandardGamepadButton.TRIGGER_R;
+               case Linux.Input.BTN_SELECT:
+                       return StandardGamepadButton.SELECT;
+               case Linux.Input.BTN_START:
+                       return StandardGamepadButton.START;
+               case Linux.Input.BTN_MODE:
+                       return StandardGamepadButton.HOME;
+               case Linux.Input.BTN_THUMBL:
+                       return StandardGamepadButton.STICK_L;
+               case Linux.Input.BTN_THUMBR:
+                       return StandardGamepadButton.STICK_R;
+               default:
+                       return StandardGamepadButton.UNKNOWN;
+               }
+       }
 }
 
 #endif
diff --git a/src/gamepad/raw-gamepad.vala b/src/gamepad/raw-gamepad.vala
index 4a1f24c..8b5530e 100644
--- a/src/gamepad/raw-gamepad.vala
+++ b/src/gamepad/raw-gamepad.vala
@@ -8,6 +8,8 @@
  * with number of buttons, axes and dpads.
  */
 private interface Games.RawGamepad : Object {
+       public abstract signal void standard_button_event (StandardGamepadButton button, bool value);
+
        /**
         * Emitted when a button is pressed/released
         * @param  code          The button code from 0 to buttons_number


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]