Title: [211263] branches/safari-603-branch/Source/WebCore
Revision
211263
Author
matthew_han...@apple.com
Date
2017-01-27 00:01:59 -0800 (Fri, 27 Jan 2017)

Log Message

Merge r211220. rdar://problem/29578619

Modified Paths

Diff

Modified: branches/safari-603-branch/Source/WebCore/ChangeLog (211262 => 211263)


--- branches/safari-603-branch/Source/WebCore/ChangeLog	2017-01-27 08:01:56 UTC (rev 211262)
+++ branches/safari-603-branch/Source/WebCore/ChangeLog	2017-01-27 08:01:59 UTC (rev 211263)
@@ -1,5 +1,35 @@
 2017-01-26  Matthew Hanson  <matthew_han...@apple.com>
 
+        Merge r211220. rdar://problem/29578619
+
+    2017-01-26  Brady Eidson  <beid...@apple.com>
+
+            Gamepad support shows wrong values for PS4 controllers (D-pad is missing).
+            <rdar://problem/29578619> and https://bugs.webkit.org/show_bug.cgi?id=165588
+
+            Reviewed by Alex Christensen.
+
+            No new tests (Currently unable to test HID backend directly)
+
+            DPads report their HID type as "a button", but their HID usage is "Hatswitch".
+            This patch adds a new element type that maps a "hatswitch" value to 4 additional buttons.
+
+            * platform/gamepad/mac/HIDGamepad.cpp:
+            (WebCore::HIDGamepad::initElements):
+            (WebCore::HIDGamepad::initElementsFromArray):
+            (WebCore::HIDGamepad::maybeAddButton):
+            (WebCore::HIDGamepad::maybeAddDPad):
+            (WebCore::HIDGamepad::maybeAddAxis):
+            (WebCore::fillInButtonValues):
+            (WebCore::HIDGamepad::valueChanged):
+
+            * platform/gamepad/mac/HIDGamepad.h:
+            (WebCore::HIDGamepadElement::isDPad):
+            (WebCore::HIDGamepadDPad::HIDGamepadDPad):
+            (WebCore::HIDGamepadDPad::normalizedValue):
+
+2017-01-26  Matthew Hanson  <matthew_han...@apple.com>
+
         Merge r211201. rdar://problem/30134866
 
     2017-01-25  Ryosuke Niwa  <rn...@webkit.org>

Modified: branches/safari-603-branch/Source/WebCore/platform/gamepad/mac/HIDGamepad.cpp (211262 => 211263)


--- branches/safari-603-branch/Source/WebCore/platform/gamepad/mac/HIDGamepad.cpp	2017-01-27 08:01:56 UTC (rev 211262)
+++ branches/safari-603-branch/Source/WebCore/platform/gamepad/mac/HIDGamepad.cpp	2017-01-27 08:01:59 UTC (rev 211263)
@@ -79,13 +79,16 @@
     });
 
     m_axisValues.resize(m_axes.size());
-    m_buttonValues.resize(m_buttons.size());
+    m_buttonValues.resize(m_buttons.size() + (m_dPads.size() * 4));
 
     for (auto& button : m_buttons)
-        getCurrentValueForElement(*button);
+        getCurrentValueForElement(button.get());
 
+    for (auto& dPad : m_dPads)
+        getCurrentValueForElement(dPad.get());
+
     for (auto& axis : m_axes)
-        getCurrentValueForElement(*axis);
+        getCurrentValueForElement(axis.get());
 }
 
 void HIDGamepad::initElementsFromArray(CFArrayRef elements)
@@ -104,8 +107,12 @@
 
         IOHIDElementType type = IOHIDElementGetType(element);
 
-        if ((type == kIOHIDElementTypeInput_Misc || type == kIOHIDElementTypeInput_Button) && maybeAddButton(element))
-            continue;
+        if ((type == kIOHIDElementTypeInput_Misc || type == kIOHIDElementTypeInput_Button)) {
+            if (maybeAddButton(element))
+                continue;
+            if (maybeAddDPad(element))
+                continue;
+        }
 
         if ((type == kIOHIDElementTypeInput_Misc || type == kIOHIDElementTypeInput_Axis) && maybeAddAxis(element))
             continue;
@@ -128,14 +135,35 @@
     CFIndex min = IOHIDElementGetLogicalMin(element);
     CFIndex max = IOHIDElementGetLogicalMax(element);
 
-    m_buttons.append(std::make_unique<HIDGamepadButton>(usage, min, max, element));
+    m_buttons.append(makeUniqueRef<HIDGamepadButton>(usage, min, max, element));
 
     IOHIDElementCookie cookie = IOHIDElementGetCookie(element);
-    m_elementMap.set(cookie, m_buttons.last().get());
+    m_elementMap.set(cookie, &m_buttons.last().get());
 
     return true;
 }
 
+bool HIDGamepad::maybeAddDPad(IOHIDElementRef element)
+{
+    uint32_t usagePage = IOHIDElementGetUsagePage(element);
+    if (usagePage != kHIDPage_GenericDesktop)
+        return false;
+
+    uint32_t usage = IOHIDElementGetUsage(element);
+    if (!usage || usage != kHIDUsage_GD_Hatswitch)
+        return false;
+
+    CFIndex min = IOHIDElementGetLogicalMin(element);
+    CFIndex max = IOHIDElementGetLogicalMax(element);
+
+    m_dPads.append(makeUniqueRef<HIDGamepadDPad>(min, max, element));
+
+    IOHIDElementCookie cookie = IOHIDElementGetCookie(element);
+    m_elementMap.set(cookie, &m_dPads.last().get());
+
+    return true;
+}
+
 bool HIDGamepad::maybeAddAxis(IOHIDElementRef element)
 {
     uint32_t usagePage = IOHIDElementGetUsagePage(element);
@@ -150,14 +178,46 @@
     CFIndex min = IOHIDElementGetPhysicalMin(element);
     CFIndex max = IOHIDElementGetPhysicalMax(element);
 
-    m_axes.append(std::make_unique<HIDGamepadAxis>(min, max, element));
+    m_axes.append(makeUniqueRef<HIDGamepadAxis>(min, max, element));
 
     IOHIDElementCookie cookie = IOHIDElementGetCookie(element);
-    m_elementMap.set(cookie, m_axes.last().get());
+    m_elementMap.set(cookie, &m_axes.last().get());
 
     return true;
 }
 
+static void fillInButtonValues(int value, double& button0, double& button1, double& button2, double& button3)
+{
+    // Standard DPads have 8 possible position values, moving around a circle:
+    // 0 - Up
+    // 1 - Up + right
+    // 2 - Right
+    // 3 - Down + right
+    // 4 - Down
+    // 5 - Down + left
+    // 6 - Left
+    // 7 - Up and Left
+    // These 8 positions are mapped on to 4 button positions:
+    // 0 - Up
+    // 1 - Down
+    // 2 - Left
+    // 3 - Right
+
+    if (value < 0 || value > 7) {
+        // Handle an invalid input value that we don't know how to interpret.
+        button0 = 0.0;
+        button1 = 0.0;
+        button2 = 0.0;
+        button3 = 0.0;
+        return;
+    }
+
+    button0 = value < 2 || value == 7 ? 1.0 : 0.0;
+    button1 = value > 2 && value < 6 ? 1.0 : 0.0;
+    button2 = value > 4 ? 1.0 : 0.0;
+    button3 = value > 0 && value < 4 ? 1.0 : 0.0;
+}
+
 HIDInputType HIDGamepad::valueChanged(IOHIDValueRef value)
 {
     IOHIDElementCookie cookie = IOHIDElementGetCookie(IOHIDValueGetElement(value));
@@ -171,14 +231,31 @@
 
     if (element->isButton()) {
         for (unsigned i = 0; i < m_buttons.size(); ++i) {
-            if (m_buttons[i].get() == element)
+            if (&m_buttons[i].get() == element) {
                 m_buttonValues[i] = element->normalizedValue();
+                break;
+            }
         }
     } else if (element->isAxis()) {
         for (unsigned i = 0; i < m_axes.size(); ++i) {
-            if (m_axes[i].get() == element)
+            if (&m_axes[i].get() == element) {
                 m_axisValues[i] = element->normalizedValue();
+                break;
+            }
         }
+    } else if (element->isDPad()) {
+        int intValue = IOHIDValueGetIntegerValue(value) - element->min;
+        for (unsigned i = 0; i < m_dPads.size(); ++i) {
+            if (&m_dPads[i].get() != element)
+                continue;
+
+            // Each DPad represents 4 button values which are tacked on to the end of the values from non-DPad buttons.
+            unsigned firstButtonValue = m_buttons.size() + i * 4;
+
+            ASSERT(m_buttonValues.size() > firstButtonValue + 3);
+
+            fillInButtonValues(intValue, m_buttonValues[firstButtonValue], m_buttonValues[firstButtonValue + 1], m_buttonValues[firstButtonValue + 2], m_buttonValues[firstButtonValue + 3]);
+        }
     } else
         ASSERT_NOT_REACHED();
 

Modified: branches/safari-603-branch/Source/WebCore/platform/gamepad/mac/HIDGamepad.h (211262 => 211263)


--- branches/safari-603-branch/Source/WebCore/platform/gamepad/mac/HIDGamepad.h	2017-01-27 08:01:56 UTC (rev 211262)
+++ branches/safari-603-branch/Source/WebCore/platform/gamepad/mac/HIDGamepad.h	2017-01-27 08:01:59 UTC (rev 211263)
@@ -31,6 +31,7 @@
 #include <IOKit/hid/IOHIDDevice.h>
 #include <wtf/HashMap.h>
 #include <wtf/RetainPtr.h>
+#include <wtf/UniqueRef.h>
 
 namespace WebCore {
 
@@ -54,6 +55,7 @@
 
     virtual bool isButton() const { return false; }
     virtual bool isAxis() const { return false; }
+    virtual bool isDPad() const { return false; }
 
     virtual double normalizedValue() = 0;
 };
@@ -67,7 +69,7 @@
 
     uint32_t priority;
 
-    bool isButton() const override { return true; }
+    bool isButton() const final { return true; }
 
     // Buttons normalize to the range (0.0) - (1.0)
     double normalizedValue() override
@@ -82,7 +84,7 @@
     {
     }
 
-    bool isAxis() const override { return true; }
+    bool isAxis() const final { return true; }
 
     // Axes normalize to the range (-1.0) - (1.0)
     double normalizedValue() override
@@ -91,6 +93,17 @@
     }
 };
 
+struct HIDGamepadDPad : HIDGamepadElement {
+    HIDGamepadDPad(double min, double max, IOHIDElementRef element)
+        : HIDGamepadElement(min, max, element)
+    {
+    }
+
+    bool isDPad() const final { return true; }
+
+    virtual double normalizedValue() { RELEASE_ASSERT_NOT_REACHED(); }
+};
+
 enum class HIDInputType {
     ButtonPress,
     NotAButtonPress,
@@ -112,6 +125,7 @@
     void initElementsFromArray(CFArrayRef);
 
     bool maybeAddButton(IOHIDElementRef);
+    bool maybeAddDPad(IOHIDElementRef);
     bool maybeAddAxis(IOHIDElementRef);
 
     void getCurrentValueForElement(const HIDGamepadElement&);
@@ -120,8 +134,9 @@
 
     HashMap<IOHIDElementCookie, HIDGamepadElement*> m_elementMap;
 
-    Vector<std::unique_ptr<HIDGamepadButton>> m_buttons;
-    Vector<std::unique_ptr<HIDGamepadAxis>> m_axes;
+    Vector<UniqueRef<HIDGamepadButton>> m_buttons;
+    Vector<UniqueRef<HIDGamepadAxis>> m_axes;
+    Vector<UniqueRef<HIDGamepadDPad>> m_dPads;
     Vector<double> m_buttonValues;
     Vector<double> m_axisValues;
 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to