Changeset 265156 in webkit


Ignore:
Timestamp:
Jul 31, 2020 12:50:33 PM (4 years ago)
Author:
beidson@apple.com
Message:

Special HID mapping for the Dualshock 3 controller
<rdar://problem/66255198> and https://bugs.webkit.org/show_bug.cgi?id=214911

Reviewed by Tim Horton.

Source/WebCore:

Covered by API tests.

  • Move GamepadButtons into a GamepadConstants header
  • Add a "KnownGamepads" header to hold all vendor/product pairs that WebKit knows about
  • Add a Dualshock3 controller mapping based on its HID report
  • Add a basic DS3 test based on the HID report
  • Sources.txt:
  • SourcesCocoa.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • platform/gamepad/GamepadConstants.cpp: Copied from Source/WebCore/platform/gamepad/mac/GenericHIDGamepad.h.

(WebCore::standardGamepadMappingString):

  • platform/gamepad/GamepadConstants.h: Added.
  • platform/gamepad/KnownGamepads.h: Copied from Source/WebCore/platform/gamepad/mac/GenericHIDGamepad.h.
  • platform/gamepad/cocoa/GameControllerGamepad.mm:

(WebCore::GameControllerGamepad::setupAsExtendedGamepad):

  • platform/gamepad/mac/Dualshock3HIDGamepad.cpp: Added.

(WebCore::Dualshock3HIDGamepad::Dualshock3HIDGamepad):

  • platform/gamepad/mac/Dualshock3HIDGamepad.h: Copied from Source/WebCore/platform/gamepad/mac/GenericHIDGamepad.h.
  • platform/gamepad/mac/GenericHIDGamepad.cpp:

(WebCore::GenericHIDGamepad::GenericHIDGamepad):
(WebCore::GenericHIDGamepad::id): Deleted.

  • platform/gamepad/mac/GenericHIDGamepad.h:
  • platform/gamepad/mac/HIDGamepad.cpp:

(WebCore::HIDGamepad::create):
(WebCore::HIDGamepad::HIDGamepad):
(WebCore::HIDGamepad::initialize):

  • platform/gamepad/mac/HIDGamepad.h:
  • platform/mac/HIDDevice.h:

(WebCore::HIDDevice::fullProductIdentifier const):

  • platform/mac/HIDElement.h:

(WebCore::HIDElement::fullUsage const):

Tools:

Add a virtual Dualshock3 and verify a few attributes about it.

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/mac/HIDGamepads.mm:
  • TestWebKitAPI/mac/GamepadMappings/SonyDualShock3.mm: Added.

(TestWebKitAPI::publishReportCallback):
(TestWebKitAPI::VirtualGamepad::sonyDualshock3Mapping):

  • TestWebKitAPI/mac/VirtualGamepad.h:
Location:
trunk
Files:
2 added
16 edited
5 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r265155 r265156  
     12020-07-31  Brady Eidson  <beidson@apple.com>
     2
     3        Special HID mapping for the Dualshock 3 controller
     4        <rdar://problem/66255198> and https://bugs.webkit.org/show_bug.cgi?id=214911
     5
     6        Reviewed by Tim Horton.
     7
     8        Covered by API tests.
     9
     10        - Move GamepadButtons into a GamepadConstants header
     11        - Add a "KnownGamepads" header to hold all vendor/product pairs that WebKit knows about
     12        - Add a Dualshock3 controller mapping based on its HID report
     13        - Add a basic DS3 test based on the HID report
     14       
     15        * Sources.txt:
     16        * SourcesCocoa.txt:
     17        * WebCore.xcodeproj/project.pbxproj:
     18
     19        * platform/gamepad/GamepadConstants.cpp: Copied from Source/WebCore/platform/gamepad/mac/GenericHIDGamepad.h.
     20        (WebCore::standardGamepadMappingString):
     21        * platform/gamepad/GamepadConstants.h: Added.
     22
     23        * platform/gamepad/KnownGamepads.h: Copied from Source/WebCore/platform/gamepad/mac/GenericHIDGamepad.h.
     24
     25        * platform/gamepad/cocoa/GameControllerGamepad.mm:
     26        (WebCore::GameControllerGamepad::setupAsExtendedGamepad):
     27
     28        * platform/gamepad/mac/Dualshock3HIDGamepad.cpp: Added.
     29        (WebCore::Dualshock3HIDGamepad::Dualshock3HIDGamepad):
     30        * platform/gamepad/mac/Dualshock3HIDGamepad.h: Copied from Source/WebCore/platform/gamepad/mac/GenericHIDGamepad.h.
     31
     32        * platform/gamepad/mac/GenericHIDGamepad.cpp:
     33        (WebCore::GenericHIDGamepad::GenericHIDGamepad):
     34        (WebCore::GenericHIDGamepad::id): Deleted.
     35        * platform/gamepad/mac/GenericHIDGamepad.h:
     36
     37        * platform/gamepad/mac/HIDGamepad.cpp:
     38        (WebCore::HIDGamepad::create):
     39        (WebCore::HIDGamepad::HIDGamepad):
     40        (WebCore::HIDGamepad::initialize):
     41        * platform/gamepad/mac/HIDGamepad.h:
     42
     43        * platform/mac/HIDDevice.h:
     44        (WebCore::HIDDevice::fullProductIdentifier const):
     45        * platform/mac/HIDElement.h:
     46        (WebCore::HIDElement::fullUsage const):
     47
    1482020-07-31  Alex Christensen  <achristensen@webkit.org>
    249
  • trunk/Source/WebCore/Sources.txt

    r265152 r265156  
    18171817platform/encryptedmedia/CDMProxy.cpp
    18181818platform/gamepad/EmptyGamepadProvider.cpp
     1819platform/gamepad/GamepadConstants.cpp
    18191820platform/gamepad/GamepadProvider.cpp
    18201821platform/graphics/ANGLEWebKitBridge.cpp
  • trunk/Source/WebCore/SourcesCocoa.txt

    r265095 r265156  
    258258platform/gamepad/cocoa/GameControllerGamepad.mm
    259259platform/gamepad/cocoa/GameControllerGamepadProvider.mm
     260platform/gamepad/mac/Dualshock3HIDGamepad.cpp
    260261platform/gamepad/mac/GenericHIDGamepad.cpp
    261262platform/gamepad/mac/HIDGamepad.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r265152 r265156  
    14031403                510A91EA24D004C300BFD89C /* HIDElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 510A91E324CFCC1800BFD89C /* HIDElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
    14041404                510A91EB24D004C800BFD89C /* HIDDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 510A91E224CFCC1800BFD89C /* HIDDevice.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1405                510A91F624D32DDC00BFD89C /* Dualshock3HIDGamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = 510A91F424D324FF00BFD89C /* Dualshock3HIDGamepad.h */; };
     1406                510A91FD24D3C16200BFD89C /* GamepadConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 51715FE924CD05DD002C97E6 /* GamepadConstants.h */; };
     1407                510A91FE24D3C16700BFD89C /* GamepadConstantsMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 510A91FB24D3C0FD00BFD89C /* GamepadConstantsMac.h */; };
    14051408                510D4A34103165EE0049EA54 /* SocketStreamError.h in Headers */ = {isa = PBXBuildFile; fileRef = 510D4A2E103165EE0049EA54 /* SocketStreamError.h */; settings = {ATTRIBUTES = (Private, ); }; };
    14061409                510D4A37103165EE0049EA54 /* SocketStreamHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 510D4A31103165EE0049EA54 /* SocketStreamHandle.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    82298232                510A91E724CFEA1700BFD89C /* GenericHIDGamepad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GenericHIDGamepad.cpp; sourceTree = "<group>"; };
    82308233                510A91E924CFEA3200BFD89C /* GenericHIDGamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericHIDGamepad.h; sourceTree = "<group>"; };
     8234                510A91F224D324C600BFD89C /* KnownGamepads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KnownGamepads.h; sourceTree = "<group>"; };
     8235                510A91F424D324FF00BFD89C /* Dualshock3HIDGamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dualshock3HIDGamepad.h; sourceTree = "<group>"; };
     8236                510A91F524D3250000BFD89C /* Dualshock3HIDGamepad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Dualshock3HIDGamepad.cpp; sourceTree = "<group>"; };
     8237                510A91FB24D3C0FD00BFD89C /* GamepadConstantsMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GamepadConstantsMac.h; sourceTree = "<group>"; };
    82318238                510D4A2E103165EE0049EA54 /* SocketStreamError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketStreamError.h; sourceTree = "<group>"; };
    82328239                510D4A30103165EE0049EA54 /* SocketStreamHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SocketStreamHandle.cpp; sourceTree = "<group>"; };
     
    1966919676                                515BE18B1D54F5F600DD7C68 /* GamepadProvider.h */,
    1967019677                                515BE18C1D54F5F600DD7C68 /* GamepadProviderClient.h */,
     19678                                510A91F224D324C600BFD89C /* KnownGamepads.h */,
    1967119679                                515BE18E1D54F5F600DD7C68 /* PlatformGamepad.h */,
    1967219680                                510A91DB24CF441800BFD89C /* SharedGamepadValue.h */,
     
    1967819686                        isa = PBXGroup;
    1967919687                        children = (
     19688                                510A91F524D3250000BFD89C /* Dualshock3HIDGamepad.cpp */,
     19689                                510A91F424D324FF00BFD89C /* Dualshock3HIDGamepad.h */,
     19690                                510A91FB24D3C0FD00BFD89C /* GamepadConstantsMac.h */,
    1968019691                                510A91E724CFEA1700BFD89C /* GenericHIDGamepad.cpp */,
    1968119692                                510A91E924CFEA3200BFD89C /* GenericHIDGamepad.h */,
     
    3076630777                                1AF5E4D91E5677A9004A1F01 /* DragItem.h in Headers */,
    3076730778                                81F65FF613788FAA00FF6F2D /* DragState.h in Headers */,
     30779                                510A91F624D32DDC00BFD89C /* Dualshock3HIDGamepad.h in Headers */,
    3076830780                                E1BA66F11742BD8600C20251 /* DynamicLinkerInterposing.h in Headers */,
    3076930781                                FD6ED2C8136B8E66003CF072 /* DynamicsCompressor.h in Headers */,
     
    3099131003                                51E399001D6E4750009C8831 /* GameControllerGamepad.h in Headers */,
    3099231004                                51E399021D6E4750009C8831 /* GameControllerGamepadProvider.h in Headers */,
     31005                                510A91FD24D3C16200BFD89C /* GamepadConstants.h in Headers */,
     31006                                510A91FE24D3C16700BFD89C /* GamepadConstantsMac.h in Headers */,
    3099331007                                516C62211950D48700337E75 /* GamepadEvent.h in Headers */,
    3099431008                                51A9D9EA195B931F001B2B5C /* GamepadManager.h in Headers */,
  • trunk/Source/WebCore/platform/gamepad/GamepadConstants.cpp

    r265155 r265156  
    2424 */
    2525
    26 #pragma once
     26#include "config.h"
     27#include "GamepadConstants.h"
    2728
    28 #if ENABLE(GAMEPAD) && PLATFORM(MAC)
     29#if ENABLE(GAMEPAD)
    2930
    30 #include "HIDGamepad.h"
     31#import <wtf/NeverDestroyed.h>
     32#import <wtf/text/WTFString.h>
    3133
    3234namespace WebCore {
    3335
    34 class GenericHIDGamepad final : public HIDGamepad {
    35 public:
    36     GenericHIDGamepad(HIDDevice&&, unsigned index);
     36const GamepadButtonRole maximumGamepadButton = GamepadButtonRole::CenterClusterCenter;
     37const size_t numberOfStandardGamepadButtonsWithoutHomeButton = static_cast<size_t>(maximumGamepadButton);
     38const size_t numberOfStandardGamepadButtonsWithHomeButton = numberOfStandardGamepadButtonsWithoutHomeButton + 1;
    3739
    38 private:
    39     String id() final;
     40const WTF::String& standardGamepadMappingString()
     41{
     42    static NeverDestroyed<String> standardGamepadMapping = "standard";
     43    return standardGamepadMapping;
     44}
    4045
    41     void maybeAddGenericDesktopElement(HIDElement&);
    42     void maybeAddButtonElement(HIDElement&);
    43 };
    4446
    4547} // namespace WebCore
    4648
    47 #endif // ENABLE(GAMEPAD) && PLATFORM(MAC)
     49#endif // ENABLE(GAMEPAD)
  • trunk/Source/WebCore/platform/gamepad/GamepadConstants.h

    r265155 r265156  
    2626#pragma once
    2727
    28 #if PLATFORM(MAC)
     28#if ENABLE(GAMEPAD)
    2929
    30 #include <IOKit/hid/IOHIDDevice.h>
    31 #include <wtf/RetainPtr.h>
     30namespace WTF {
     31class String;
     32};
    3233
    3334namespace WebCore {
    3435
    35 class HIDElement {
    36     WTF_MAKE_FAST_ALLOCATED;
    37 public:
    38     explicit HIDElement(IOHIDElementRef);
    39 
    40     IOHIDElementRef rawElement() const { return m_rawElement.get(); }
    41 
    42     CFIndex physicalMin() const { return m_physicalMin; }
    43     CFIndex physicalMax() const { return m_physicalMax; }
    44     CFIndex physicalValue() const { return m_physicalValue; }
    45     uint32_t usage() const { return m_usage; }
    46     uint32_t usagePage() const { return m_usagePage; }
    47     IOHIDElementCookie cookie() const { return m_cookie; }
    48 
    49     void valueChanged(IOHIDValueRef);
    50 
    51 private:
    52     CFIndex m_physicalMin;
    53     CFIndex m_physicalMax;
    54     CFIndex m_physicalValue;
    55     uint32_t m_usage;
    56     uint32_t m_usagePage;
    57     IOHIDElementCookie m_cookie;
    58     RetainPtr<IOHIDElementRef> m_rawElement;
     36// Buttons in the "standard" gamepad layout in the Web Gamepad spec
     37// https://www.w3.org/TR/gamepad/#dfn-standard-gamepad-layout
     38enum class GamepadButtonRole : uint8_t {
     39    RightClusterBottom = 0,
     40    RightClusterRight = 1,
     41    RightClusterLeft = 2,
     42    RightClusterTop = 3,
     43    LeftShoulderFront = 4,
     44    RightShoulderFront = 5,
     45    LeftShoulderBack = 6,
     46    RightShoulderBack = 7,
     47    CenterClusterLeft = 8,
     48    CenterClusterRight = 9,
     49    LeftStick = 10,
     50    RightStick = 11,
     51    LeftClusterTop = 12,
     52    LeftClusterBottom = 13,
     53    LeftClusterLeft = 14,
     54    LeftClusterRight = 15,
     55    CenterClusterCenter = 16,
    5956};
    6057
     58extern const size_t numberOfStandardGamepadButtonsWithoutHomeButton;
     59extern const size_t numberOfStandardGamepadButtonsWithHomeButton;
     60extern const GamepadButtonRole maximumGamepadButton;
     61
     62const WTF::String& standardGamepadMappingString();
    6163
    6264} // namespace WebCore
    6365
    64 #endif // PLATFORM(MAC)
     66#endif // ENABLE(GAMEPAD)
  • trunk/Source/WebCore/platform/gamepad/KnownGamepads.h

    r265155 r265156  
    2626#pragma once
    2727
    28 #if ENABLE(GAMEPAD) && PLATFORM(MAC)
    29 
    30 #include "HIDGamepad.h"
     28#if ENABLE(GAMEPAD)
    3129
    3230namespace WebCore {
    3331
    34 class GenericHIDGamepad final : public HIDGamepad {
    35 public:
    36     GenericHIDGamepad(HIDDevice&&, unsigned index);
    37 
    38 private:
    39     String id() final;
    40 
    41     void maybeAddGenericDesktopElement(HIDElement&);
    42     void maybeAddButtonElement(HIDElement&);
     32enum KnownGamepad {
     33    Nimbus1 = 0x01111420,
     34    Nimbus2 = 0x10381420,
     35    StratusXL1 = 0x01111418,
     36    StratusXL2 = 0x10381418,
     37    StratusXL3 = 0x01111419,
     38    StratusXL4 = 0x10381419,
     39    HoripadUltimate = 0x0f0d0090,
     40    GamesirM2 = 0x0ec20475,
     41    XboxOne1 = 0x045e02e0,
     42    XboxOne2 = 0x045e02ea,
     43    XboxOne3 = 0x045e02fd,
     44    Dualshock3 = 0x054c0268,
     45    Dualshock4_1 = 0x054c05c4,
     46    Dualshock4_2 = 0x054c09cc,
    4347};
    4448
    4549} // namespace WebCore
    4650
    47 #endif // ENABLE(GAMEPAD) && PLATFORM(MAC)
     51#endif // ENABLE(GAMEPAD)
  • trunk/Source/WebCore/platform/gamepad/cocoa/GameControllerGamepad.mm

    r265079 r265156  
    2828#if ENABLE(GAMEPAD)
    2929#import "GameControllerGamepadProvider.h"
     30#import "GamepadConstants.h"
     31#import <GameController/GameController.h>
     32
    3033#import "GameControllerSoftLink.h"
    31 #import <GameController/GameController.h>
    3234
    3335namespace WebCore {
    34 
    35 // Buttons in the "standard" gamepad layout in the Web Gamepad spec
    36 // https://www.w3.org/TR/gamepad/#dfn-standard-gamepad-layout
    37 enum class GamepadButtons : uint8_t {
    38     RightClusterBottom = 0,
    39     RightClusterRight = 1,
    40     RightClusterLeft = 2,
    41     RightClusterTop = 3,
    42     LeftShoulderFront = 4,
    43     RightShoulderFront = 5,
    44     LeftShoulderBack = 6,
    45     RightShoulderBack = 7,
    46     CenterClusterLeft = 8,
    47     CenterClusterRight = 9,
    48     LeftStick = 10,
    49     RightStick = 11,
    50     LeftClusterTop = 12,
    51     LeftClusterBottom = 13,
    52     LeftClusterLeft = 14,
    53     LeftClusterRight = 15,
    54     CenterClusterCenter = 16,
    55 };
    56 
    57 static constexpr auto numGamepadButtonsWithoutHomeButton = static_cast<size_t>(GamepadButtons::CenterClusterCenter);
    58 static constexpr auto numGamepadButtonsWithHomeButton = static_cast<size_t>(GamepadButtons::CenterClusterCenter) + 1;
    5936
    6037GameControllerGamepad::GameControllerGamepad(GCController *controller, unsigned index)
     
    9976
    10077    m_id = makeString(String(m_gcController.get().vendorName), " Extended Gamepad"_s);
    101     m_mapping = String("standard");
     78    m_mapping = standardGamepadMappingString();
    10279
    10380    auto *homeButton = homeButtonFromExtendedGamepad(m_extendedGamepad.get());
    104     m_buttonValues.resize(homeButton ? numGamepadButtonsWithHomeButton : numGamepadButtonsWithoutHomeButton);
     81    m_buttonValues.resize(homeButton ? numberOfStandardGamepadButtonsWithHomeButton : numberOfStandardGamepadButtonsWithoutHomeButton);
    10582
    10683    m_extendedGamepad.get().valueChangedHandler = ^(GCExtendedGamepad *, GCControllerElement *) {
     
    11087    };
    11188
    112     auto bindButton = ^(GCControllerButtonInput *button, GamepadButtons index) {
     89    auto bindButton = ^(GCControllerButtonInput *button, GamepadButtonRole index) {
    11390        m_buttonValues[(size_t)index].setValue(button.value);
    11491        button.valueChangedHandler = ^(GCControllerButtonInput *, float value, BOOL pressed) {
     
    12097
    12198    // Button Pad
    122     bindButton(m_extendedGamepad.get().buttonA, GamepadButtons::RightClusterBottom);
    123     bindButton(m_extendedGamepad.get().buttonB, GamepadButtons::RightClusterRight);
    124     bindButton(m_extendedGamepad.get().buttonX, GamepadButtons::RightClusterLeft);
    125     bindButton(m_extendedGamepad.get().buttonY, GamepadButtons::RightClusterTop);
     99    bindButton(m_extendedGamepad.get().buttonA, GamepadButtonRole::RightClusterBottom);
     100    bindButton(m_extendedGamepad.get().buttonB, GamepadButtonRole::RightClusterRight);
     101    bindButton(m_extendedGamepad.get().buttonX, GamepadButtonRole::RightClusterLeft);
     102    bindButton(m_extendedGamepad.get().buttonY, GamepadButtonRole::RightClusterTop);
    126103
    127104    // Shoulders, Triggers
    128     bindButton(m_extendedGamepad.get().leftShoulder, GamepadButtons::LeftShoulderFront);
    129     bindButton(m_extendedGamepad.get().rightShoulder, GamepadButtons::RightShoulderFront);
    130     bindButton(m_extendedGamepad.get().leftTrigger, GamepadButtons::LeftShoulderBack);
    131     bindButton(m_extendedGamepad.get().rightTrigger, GamepadButtons::RightShoulderBack);
     105    bindButton(m_extendedGamepad.get().leftShoulder, GamepadButtonRole::LeftShoulderFront);
     106    bindButton(m_extendedGamepad.get().rightShoulder, GamepadButtonRole::RightShoulderFront);
     107    bindButton(m_extendedGamepad.get().leftTrigger, GamepadButtonRole::LeftShoulderBack);
     108    bindButton(m_extendedGamepad.get().rightTrigger, GamepadButtonRole::RightShoulderBack);
    132109
    133110    // D Pad
    134     bindButton(m_extendedGamepad.get().dpad.up, GamepadButtons::LeftClusterTop);
    135     bindButton(m_extendedGamepad.get().dpad.down, GamepadButtons::LeftClusterBottom);
    136     bindButton(m_extendedGamepad.get().dpad.left, GamepadButtons::LeftClusterLeft);
    137     bindButton(m_extendedGamepad.get().dpad.right, GamepadButtons::LeftClusterRight);
     111    bindButton(m_extendedGamepad.get().dpad.up, GamepadButtonRole::LeftClusterTop);
     112    bindButton(m_extendedGamepad.get().dpad.down, GamepadButtonRole::LeftClusterBottom);
     113    bindButton(m_extendedGamepad.get().dpad.left, GamepadButtonRole::LeftClusterLeft);
     114    bindButton(m_extendedGamepad.get().dpad.right, GamepadButtonRole::LeftClusterRight);
    138115
    139116    if (homeButton)
    140         bindButton(homeButton, GamepadButtons::CenterClusterCenter);
     117        bindButton(homeButton, GamepadButtonRole::CenterClusterCenter);
    141118
    142119    // Select, Start
    143120#if HAVE(GCEXTENDEDGAMEPAD_BUTTONS_OPTIONS_MENU)
    144     bindButton(m_extendedGamepad.get().buttonOptions, GamepadButtons::CenterClusterLeft);
    145     bindButton(m_extendedGamepad.get().buttonMenu, GamepadButtons::CenterClusterRight);
     121    bindButton(m_extendedGamepad.get().buttonOptions, GamepadButtonRole::CenterClusterLeft);
     122    bindButton(m_extendedGamepad.get().buttonMenu, GamepadButtonRole::CenterClusterRight);
    146123#endif
    147124
     
    152129#pragma clang diagnostic ignored "-Wunguarded-availability"
    153130    if ([m_extendedGamepad.get() respondsToSelector:@selector(leftThumbstickButton)]) {
    154         bindButton(m_extendedGamepad.get().leftThumbstickButton, GamepadButtons::LeftStick);
    155         bindButton(m_extendedGamepad.get().rightThumbstickButton, GamepadButtons::RightStick);
     131        bindButton(m_extendedGamepad.get().leftThumbstickButton, GamepadButtonRole::LeftStick);
     132        bindButton(m_extendedGamepad.get().rightThumbstickButton, GamepadButtonRole::RightStick);
    156133    }
    157134#pragma clang diagnostic pop
  • trunk/Source/WebCore/platform/gamepad/cocoa/GameControllerGamepadProvider.mm

    r264887 r265156  
    3131#import "GameControllerGamepad.h"
    3232#import "GamepadProviderClient.h"
     33#import "KnownGamepads.h"
    3334#import "Logging.h"
    3435#import <GameController/GameController.h>
     
    4546    // Check the vendor/product IDs agains a hard coded list of controllers we expect to work well with
    4647    // GameController.framework on 10.15.
    47     enum GameControllerCompatible {
    48         Nimbus1 = 0x01111420,
    49         Nimbus2 = 0x10381420,
    50         StratusXL1 = 0x01111418,
    51         StratusXL2 = 0x10381418,
    52         StratusXL3 = 0x01111419,
    53         StratusXL4 = 0x10381419,
    54         HoripadUltimate = 0x0f0d0090,
    55         GamesirM2 = 0x0ec20475,
    56         XboxOne1 = 0x045e02e0,
    57         XboxOne2 = 0x045e02ea,
    58         XboxOne3 = 0x045e02fd,
    59         Dualshock4_1 = 0x054c05c4,
    60         Dualshock4_2 = 0x054c09cc,
    61     };
    62 
    63     GameControllerCompatible fullProductID = (GameControllerCompatible)((vendorID << 16) | (productID & 0xFFFF));
    64 
    65     switch (fullProductID) {
    66     case Nimbus1:
    67     case Nimbus2:
    68     case StratusXL1:
    69     case StratusXL2:
    70     case StratusXL3:
    71     case StratusXL4:
    72     case HoripadUltimate:
    73     case GamesirM2:
    74     case XboxOne1:
    75     case XboxOne2:
    76     case XboxOne3:
    77     case Dualshock4_1:
    78     case Dualshock4_2:
    79         return true;
    80     default:
    81         return false;
    82     }
     48    static NeverDestroyed<HashSet<uint32_t>> gameControllerCompatibleGamepads;
     49
     50    static std::once_flag onceFlag;
     51    std::call_once(onceFlag, [] {
     52        gameControllerCompatibleGamepads->add(Nimbus1);
     53        gameControllerCompatibleGamepads->add(Nimbus2);
     54        gameControllerCompatibleGamepads->add(StratusXL1);
     55        gameControllerCompatibleGamepads->add(StratusXL2);
     56        gameControllerCompatibleGamepads->add(StratusXL3);
     57        gameControllerCompatibleGamepads->add(StratusXL4);
     58        gameControllerCompatibleGamepads->add(HoripadUltimate);
     59        gameControllerCompatibleGamepads->add(GamesirM2);
     60        gameControllerCompatibleGamepads->add(XboxOne1);
     61        gameControllerCompatibleGamepads->add(XboxOne2);
     62        gameControllerCompatibleGamepads->add(XboxOne3);
     63        gameControllerCompatibleGamepads->add(Dualshock4_1);
     64        gameControllerCompatibleGamepads->add(Dualshock4_2);
     65    });
     66
     67    uint32_t fullProductID = (((uint32_t)vendorID) << 16) | productID;
     68    return gameControllerCompatibleGamepads->contains(fullProductID);
    8369}
    8470#endif // !HAVE(GCCONTROLLER_HID_DEVICE_CHECK)
  • trunk/Source/WebCore/platform/gamepad/mac/Dualshock3HIDGamepad.h

    r265155 r265156  
    3232namespace WebCore {
    3333
    34 class GenericHIDGamepad final : public HIDGamepad {
     34class Dualshock3HIDGamepad final : public HIDGamepad {
     35    WTF_MAKE_FAST_ALLOCATED;
    3536public:
    36     GenericHIDGamepad(HIDDevice&&, unsigned index);
    37 
    38 private:
    39     String id() final;
    40 
    41     void maybeAddGenericDesktopElement(HIDElement&);
    42     void maybeAddButtonElement(HIDElement&);
     37    Dualshock3HIDGamepad(HIDDevice&&, unsigned index);
    4338};
    4439
  • trunk/Source/WebCore/platform/gamepad/mac/GamepadConstantsMac.h

    r265155 r265156  
    2828#if ENABLE(GAMEPAD) && PLATFORM(MAC)
    2929
    30 #include "HIDGamepad.h"
     30#import <IOKit/hid/IOHIDUsageTables.h>
    3131
    3232namespace WebCore {
    3333
    34 class GenericHIDGamepad final : public HIDGamepad {
    35 public:
    36     GenericHIDGamepad(HIDDevice&&, unsigned index);
    37 
    38 private:
    39     String id() final;
    40 
    41     void maybeAddGenericDesktopElement(HIDElement&);
    42     void maybeAddButtonElement(HIDElement&);
    43 };
     34constexpr const uint64_t hidPointerFullUsage = ((uint64_t)kHIDPage_GenericDesktop) << 32 | kHIDUsage_GD_Pointer;
     35constexpr const uint64_t hidXAxisFullUsage = ((uint64_t)kHIDPage_GenericDesktop) << 32 | kHIDUsage_GD_X;
     36constexpr const uint64_t hidYAxisFullUsage = ((uint64_t)kHIDPage_GenericDesktop) << 32 | kHIDUsage_GD_Y;
     37constexpr const uint64_t hidZAxisFullUsage = ((uint64_t)kHIDPage_GenericDesktop) << 32 | kHIDUsage_GD_Z;
     38constexpr const uint64_t hidRzAxisFullUsage = ((uint64_t)kHIDPage_GenericDesktop) << 32 | kHIDUsage_GD_Rz;
     39constexpr const uint64_t hidButton1FullUsage = ((uint64_t)kHIDPage_Button) << 32 | kHIDUsage_Button_1;
     40constexpr const uint64_t hidButton2FullUsage = ((uint64_t)kHIDPage_Button) << 32 | (kHIDUsage_Button_1 + 1);
     41constexpr const uint64_t hidButton3FullUsage = ((uint64_t)kHIDPage_Button) << 32 | (kHIDUsage_Button_1 + 2);
     42constexpr const uint64_t hidButton4FullUsage = ((uint64_t)kHIDPage_Button) << 32 | (kHIDUsage_Button_1 + 3);
     43constexpr const uint64_t hidButton17FullUsage = ((uint64_t)kHIDPage_Button) << 32 | (kHIDUsage_Button_1 + 16);
    4444
    4545} // namespace WebCore
  • trunk/Source/WebCore/platform/gamepad/mac/GenericHIDGamepad.cpp

    r265079 r265156  
    3737    : HIDGamepad(WTFMove(device), index)
    3838{
     39    LOG(Gamepad, "Creating GenericHIDGamepad %p", this);
     40
    3941    auto inputElements = hidDevice().uniqueInputElementsInDeviceTreeOrder();
    4042
     
    5153        }
    5254    }
    53 }
    54 
    55 String GenericHIDGamepad::id()
    56 {
    57     // Currently the spec has no formatting for the id string.
    58     // This string formatting matches Firefox.
    59     return makeString(hex(hidDevice().vendorID(), Lowercase), '-', hex(hidDevice().productID(), Lowercase), '-', hidDevice().productName());
    6055}
    6156
  • trunk/Source/WebCore/platform/gamepad/mac/GenericHIDGamepad.h

    r265079 r265156  
    3737
    3838private:
    39     String id() final;
    40 
    4139    void maybeAddGenericDesktopElement(HIDElement&);
    4240    void maybeAddButtonElement(HIDElement&);
  • trunk/Source/WebCore/platform/gamepad/mac/HIDGamepad.cpp

    r265079 r265156  
    2929#if ENABLE(GAMEPAD) && PLATFORM(MAC)
    3030
     31#include "Dualshock3HIDGamepad.h"
    3132#include "GenericHIDGamepad.h"
     33#include "KnownGamepads.h"
    3234#include "Logging.h"
    3335#include <IOKit/hid/IOHIDElement.h>
     
    4345    auto device = HIDDevice { rawDevice };
    4446
    45     // When we support specific mapping for a particular device, here is where we'll decide what kind of HIDGamepad to make.
    46     // For now, it's only the GenericHIDGamepad
    47     auto newGamepad = makeUnique<GenericHIDGamepad>(WTFMove(device), index);
     47    std::unique_ptr<HIDGamepad> newGamepad;
     48
     49    switch ((KnownGamepad)device.fullProductIdentifier()) {
     50    case Dualshock3:
     51        newGamepad = makeUnique<Dualshock3HIDGamepad>(WTFMove(device), index);
     52        break;
     53    default:
     54        newGamepad = makeUnique<GenericHIDGamepad>(WTFMove(device), index);
     55    }
    4856
    4957    newGamepad->initialize();
    50     return WTFMove(newGamepad);
     58    return newGamepad;
    5159}
    5260
     
    5664{
    5765    m_connectTime = m_lastUpdateTime = MonotonicTime::now();
     66
     67    // Currently the spec has no formatting for the id string.
     68    // This string formatting matches Firefox.
     69    m_id = makeString(hex(m_device.vendorID(), Lowercase), '-', hex(m_device.productID(), Lowercase), '-', m_device.productName());
    5870}
    5971
    6072void HIDGamepad::initialize()
    6173{
    62     m_id = id();
    63 
    6474    for (auto& element : m_elementMap.values())
    6575        element->refreshCurrentValue();
  • trunk/Source/WebCore/platform/gamepad/mac/HIDGamepad.h

    r265079 r265156  
    5353    HIDGamepad(HIDDevice&&, unsigned index);
    5454
    55     virtual String id() = 0;
    56 
    5755    HashMap<IOHIDElementCookie, std::unique_ptr<HIDGamepadElement>> m_elementMap;
    5856    Vector<SharedGamepadValue> m_buttonValues;
  • trunk/Source/WebCore/platform/mac/HIDDevice.h

    r265079 r265156  
    5151    uint16_t vendorID() const { return m_vendorID; }
    5252    uint16_t productID() const { return m_productID; }
     53    uint32_t fullProductIdentifier() const { return m_vendorID << 16 | m_productID; }
    5354    const String& productName() const { return m_productName; }
    5455
  • trunk/Source/WebCore/platform/mac/HIDElement.h

    r265079 r265156  
    4545    uint32_t usage() const { return m_usage; }
    4646    uint32_t usagePage() const { return m_usagePage; }
     47    uint64_t fullUsage() const { return ((uint64_t)m_usagePage) << 32 | m_usage; }
    4748    IOHIDElementCookie cookie() const { return m_cookie; }
    4849
  • trunk/Tools/ChangeLog

    r265150 r265156  
     12020-07-31  Brady Eidson  <beidson@apple.com>
     2
     3        Special HID mapping for the Dualshock 3 controller
     4        <rdar://problem/66255198> and https://bugs.webkit.org/show_bug.cgi?id=214911
     5
     6        Reviewed by Tim Horton.
     7
     8        Add a virtual Dualshock3 and verify a few attributes about it.
     9       
     10        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     11        * TestWebKitAPI/Tests/mac/HIDGamepads.mm:
     12        * TestWebKitAPI/mac/GamepadMappings/SonyDualShock3.mm: Added.
     13        (TestWebKitAPI::publishReportCallback):
     14        (TestWebKitAPI::VirtualGamepad::sonyDualshock3Mapping):
     15        * TestWebKitAPI/mac/VirtualGamepad.h:
     16
    1172020-07-31  Youenn Fablet  <youenn@apple.com>
    218
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r265115 r265156  
    277277                510477771D298E72009747EB /* IDBDeleteRecovery.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 510477761D298E57009747EB /* IDBDeleteRecovery.html */; };
    278278                510477781D29923B009747EB /* IDBDeleteRecovery.mm in Sources */ = {isa = PBXBuildFile; fileRef = 510477751D298E03009747EB /* IDBDeleteRecovery.mm */; };
     279                510A91F824D3622100BFD89C /* SonyDualShock3.mm in Sources */ = {isa = PBXBuildFile; fileRef = 510A91F724D3621900BFD89C /* SonyDualShock3.mm */; };
    279280                5110FCF11E01CD64006F8D0B /* IDBIndexUpgradeToV2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5110FCF01E01CD53006F8D0B /* IDBIndexUpgradeToV2.html */; };
    280281                5110FCF61E01CD83006F8D0B /* IndexUpgrade.sqlite3 in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5110FCF31E01CD77006F8D0B /* IndexUpgrade.sqlite3 */; };
     
    19721973                510477751D298E03009747EB /* IDBDeleteRecovery.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IDBDeleteRecovery.mm; sourceTree = "<group>"; };
    19731974                510477761D298E57009747EB /* IDBDeleteRecovery.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = IDBDeleteRecovery.html; sourceTree = "<group>"; };
     1975                510A91F724D3621900BFD89C /* SonyDualShock3.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SonyDualShock3.mm; sourceTree = "<group>"; };
    19741976                5110FCEF1E01CBAA006F8D0B /* IDBIndexUpgradeToV2.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IDBIndexUpgradeToV2.mm; sourceTree = "<group>"; };
    19751977                5110FCF01E01CD53006F8D0B /* IDBIndexUpgradeToV2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = IDBIndexUpgradeToV2.html; sourceTree = "<group>"; };
     
    34693471                                51EB126024CA6B5F000CB030 /* MicrosoftXboxOne.mm */,
    34703472                                51EB125E24CA6B5F000CB030 /* ShenzhenLongshengweiTechnologyGamepad.mm */,
     3473                                510A91F724D3621900BFD89C /* SonyDualShock3.mm */,
    34713474                                51EB125F24CA6B5F000CB030 /* SonyDualShock4.mm */,
    34723475                                51EB126124CA6B5F000CB030 /* SteelSeriesNimbus.mm */,
     
    53185321                                2DFF7B6D1DA487AF00814614 /* SnapshotStore.mm in Sources */,
    53195322                                0F4FFA9E1ED3AA8500F7111F /* SnapshotViaRenderInContext.mm in Sources */,
     5323                                510A91F824D3622100BFD89C /* SonyDualShock3.mm in Sources */,
    53205324                                51EB126424CA6B66000CB030 /* SonyDualShock4.mm in Sources */,
    53215325                                7CCE7F151A411AE600447C4C /* SpacebarScrolling.cpp in Sources */,
  • trunk/Tools/TestWebKitAPI/Tests/mac/HIDGamepads.mm

    r265079 r265156  
    359359}
    360360
     361TEST(Gamepad, Dualshock3Basic)
     362{
     363    auto keyWindowSwizzler = makeUnique<InstanceMethodSwizzler>([NSApplication class], @selector(keyWindow), reinterpret_cast<IMP>(getKeyWindowForTesting));
     364
     365    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     366    auto messageHandler = adoptNS([[GamepadMessageHandler alloc] init]);
     367    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"gamepad"];
     368
     369    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
     370    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"gamepad"];
     371
     372    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
     373        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil]);
     374        [task didReceiveResponse:response.get()];
     375        [task didReceiveData:[NSData dataWithBytes:mainBytes length:strlen(mainBytes)]];
     376        [task didFinish];
     377    }];
     378
     379    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     380    keyWindowForTesting = [webView window];
     381    [webView synchronouslyLoadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"gamepad://host/main.html"]]];
     382
     383    [[webView window] makeFirstResponder:webView.get()];
     384
     385    // Resigning/reinstating the key window state triggers the "key window did change" notification that WKWebView currently
     386    // needs to convince it to monitor gamepad devices
     387    [[webView window] resignKeyWindow];
     388    [[webView window] makeKeyWindow];
     389
     390    // Connect a gamepad and make it visible to the page
     391    auto gamepad = makeUnique<VirtualGamepad>(VirtualGamepad::sonyDualshock3Mapping());
     392    while (![webView.get().configuration.processPool _numberOfConnectedGamepadsForTesting])
     393        Util::sleep(0.01);
     394
     395    EXPECT_EQ([webView.get().configuration.processPool _numberOfConnectedHIDGamepadsForTesting], 1u);
     396    EXPECT_EQ([webView.get().configuration.processPool _numberOfConnectedGameControllerFrameworkGamepadsForTesting], 0u);
     397
     398    gamepad->setButtonValue(0, 0.75);
     399    gamepad->publishReport();
     400
     401    // Wait for the page to tell us a gamepad connected
     402    Util::run(&didReceiveMessage);
     403    didReceiveMessage = false;
     404
     405    EXPECT_EQ(messageHandler.get().messages.size(), 1u);
     406    EXPECT_TRUE([messageHandler.get().messages[0] isEqualToString:@"\"54c-268-Virtual Dualshock3\""]);
     407
     408    bool done = false;
     409    auto resultBlock = [&] (id result, NSError *error) {
     410        EXPECT_NULL(error);
     411        EXPECT_TRUE([result[@"gamepadCount"] isEqualToNumber:@(1)]);
     412        EXPECT_EQ(((NSArray *)result[@"gamepadButtons"][0]).count, 17u);
     413        EXPECT_EQ(((NSArray *)result[@"gamepadAxes"][0]).count, 4u);
     414
     415        done = true;
     416    };
     417
     418    [webView callAsyncJavaScript:@(pollGamepadStateFunction) arguments:nil inFrame:nil inContentWorld:WKContentWorld.pageWorld completionHandler:resultBlock];
     419
     420    Util::run(&done);
     421    didReceiveMessage = true;
     422}
     423
    361424} // namespace TestWebKitAPI
    362425
  • trunk/Tools/TestWebKitAPI/mac/VirtualGamepad.h

    r264874 r265156  
    6161    XboxOne2 = 0x02e0,
    6262    XboxOne3 = 0x02fd,
     63    Dualshock3 = 0x0268,
    6364    Dualshock4_1 = 0x05c4,
    6465    Dualshock4_2 = 0x09cc,
     
    8384    static GamepadMapping microsoftXboxOneMapping();
    8485    static GamepadMapping shenzhenLongshengweiTechnologyGamepadMapping();
     86    static GamepadMapping sonyDualshock3Mapping();
    8587    static GamepadMapping sonyDualshock4Mapping();
    8688    static GamepadMapping steelSeriesNimbusMapping();
Note: See TracChangeset for help on using the changeset viewer.