Example #1
0
/*
 * Return true if this joystick is known to have all axes centered at zero
 * This isn't generally needed unless the joystick never generates an initial axis value near zero,
 * e.g. it's emulating axes with digital buttons
 */
static SDL_bool
SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick)
{
    static Uint32 zero_centered_joysticks[] = {
        MAKE_VIDPID(0x0e8f, 0x3013),    /* HuiJia SNES USB adapter */
        MAKE_VIDPID(0x05a0, 0x3232),    /* 8Bitdo Zero Gamepad */
    };

    int i;
    Uint32 id = MAKE_VIDPID(SDL_JoystickGetVendor(joystick),
                            SDL_JoystickGetProduct(joystick));

/*printf("JOYSTICK '%s' VID/PID 0x%.4x/0x%.4x AXES: %d\n", joystick->name, vendor, product, joystick->naxes);*/

    if (joystick->naxes == 2) {
        /* Assume D-pad or thumbstick style axes are centered at 0 */
        return SDL_TRUE;
    }

    for (i = 0; i < SDL_arraysize(zero_centered_joysticks); ++i) {
        if (id == zero_centered_joysticks[i]) {
            return SDL_TRUE;
        }
    }
    return SDL_FALSE;
}
Example #2
0
static SDL_bool SDL_IsJoystickProductFlightStick(Uint32 vidpid)
{
    static Uint32 flightstick_joysticks[] = {
        MAKE_VIDPID(0x044f, 0x0402),    /* HOTAS Warthog Joystick */
        MAKE_VIDPID(0x0738, 0x2221),    /* Saitek Pro Flight X-56 Rhino Stick */
    };
    int i;

    for (i = 0; i < SDL_arraysize(flightstick_joysticks); ++i) {
        if (vidpid == flightstick_joysticks[i]) {
            return SDL_TRUE;
        }
    }
    return SDL_FALSE;
}
Example #3
0
static SDL_bool SDL_IsJoystickProductThrottle(Uint32 vidpid)
{
    static Uint32 throttle_joysticks[] = {
        MAKE_VIDPID(0x044f, 0x0404),    /* HOTAS Warthog Throttle */
        MAKE_VIDPID(0x0738, 0xa221),    /* Saitek Pro Flight X-56 Rhino Throttle */
    };
    int i;

    for (i = 0; i < SDL_arraysize(throttle_joysticks); ++i) {
        if (vidpid == throttle_joysticks[i]) {
            return SDL_TRUE;
        }
    }
    return SDL_FALSE;
}
Example #4
0
static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid)
{
    Uint16 vendor;
    Uint16 product;
    Uint32 vidpid;

    if (guid.data[14] == 'x') {
        /* XInput GUID, get the type based on the XInput device subtype */
        switch (guid.data[15]) {
        case 0x01:  /* XINPUT_DEVSUBTYPE_GAMEPAD */
            return SDL_JOYSTICK_TYPE_GAMECONTROLLER;
        case 0x02:  /* XINPUT_DEVSUBTYPE_WHEEL */
            return SDL_JOYSTICK_TYPE_WHEEL;
        case 0x03:  /* XINPUT_DEVSUBTYPE_ARCADE_STICK */
            return SDL_JOYSTICK_TYPE_ARCADE_STICK;
        case 0x04:  /* XINPUT_DEVSUBTYPE_FLIGHT_STICK */
            return SDL_JOYSTICK_TYPE_FLIGHT_STICK;
        case 0x05:  /* XINPUT_DEVSUBTYPE_DANCE_PAD */
            return SDL_JOYSTICK_TYPE_DANCE_PAD;
        case 0x06:  /* XINPUT_DEVSUBTYPE_GUITAR */
        case 0x07:  /* XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE */
        case 0x0B:  /* XINPUT_DEVSUBTYPE_GUITAR_BASS */
            return SDL_JOYSTICK_TYPE_GUITAR;
        case 0x08:  /* XINPUT_DEVSUBTYPE_DRUM_KIT */
            return SDL_JOYSTICK_TYPE_DRUM_KIT;
        case 0x13:  /* XINPUT_DEVSUBTYPE_ARCADE_PAD */
            return SDL_JOYSTICK_TYPE_ARCADE_PAD;
        default:
            return SDL_JOYSTICK_TYPE_UNKNOWN;
        }
    }

    SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
    vidpid = MAKE_VIDPID(vendor, product);

    if (SDL_IsJoystickProductWheel(vidpid)) {
        return SDL_JOYSTICK_TYPE_WHEEL;
    }

    if (SDL_IsJoystickProductFlightStick(vidpid)) {
        return SDL_JOYSTICK_TYPE_FLIGHT_STICK;
    }

    if (SDL_IsJoystickProductThrottle(vidpid)) {
        return SDL_JOYSTICK_TYPE_THROTTLE;
    }

    return SDL_JOYSTICK_TYPE_UNKNOWN;
}
Example #5
0
static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
{
    static Uint32 wheel_joysticks[] = {
        MAKE_VIDPID(0x046d, 0xc294),    /* Logitech generic wheel */
        MAKE_VIDPID(0x046d, 0xc295),    /* Logitech Momo Force */
        MAKE_VIDPID(0x046d, 0xc298),    /* Logitech Driving Force Pro */
        MAKE_VIDPID(0x046d, 0xc299),    /* Logitech G25 */
        MAKE_VIDPID(0x046d, 0xc29a),    /* Logitech Driving Force GT */
        MAKE_VIDPID(0x046d, 0xc29b),    /* Logitech G27 */
        MAKE_VIDPID(0x046d, 0xc261),    /* Logitech G920 (initial mode) */
        MAKE_VIDPID(0x046d, 0xc262),    /* Logitech G920 (active mode) */
        MAKE_VIDPID(0x044f, 0xb65d),    /* Thrustmaster Wheel FFB */
        MAKE_VIDPID(0x044f, 0xb66d),    /* Thrustmaster Wheel FFB */
        MAKE_VIDPID(0x044f, 0xb677),    /* Thrustmaster T150 */
        MAKE_VIDPID(0x044f, 0xb664),    /* Thrustmaster TX (initial mode) */
        MAKE_VIDPID(0x044f, 0xb669),    /* Thrustmaster TX (active mode) */
    };
    int i;

    for (i = 0; i < SDL_arraysize(wheel_joysticks); ++i) {
        if (vidpid == wheel_joysticks[i]) {
            return SDL_TRUE;
        }
    }
    return SDL_FALSE;
}
Example #6
0
static int
IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *guid)
{
    /* This list is taken from:
       https://raw.githubusercontent.com/denilsonsa/udev-joystick-blacklist/master/generate_rules.py
     */
    static Uint32 joystick_blacklist[] = {
        /* Microsoft Microsoft Wireless Optical Desktop® 2.10 */
        /* Microsoft Wireless Desktop - Comfort Edition */
        MAKE_VIDPID(0x045e, 0x009d),

        /* Microsoft Microsoft® Digital Media Pro Keyboard */
        /* Microsoft Corp. Digital Media Pro Keyboard */
        MAKE_VIDPID(0x045e, 0x00b0),

        /* Microsoft Microsoft® Digital Media Keyboard */
        /* Microsoft Corp. Digital Media Keyboard 1.0A */
        MAKE_VIDPID(0x045e, 0x00b4),

        /* Microsoft Microsoft® Digital Media Keyboard 3000 */
        MAKE_VIDPID(0x045e, 0x0730),

        /* Microsoft Microsoft® 2.4GHz Transceiver v6.0 */
        /* Microsoft Microsoft® 2.4GHz Transceiver v8.0 */
        /* Microsoft Corp. Nano Transceiver v1.0 for Bluetooth */
        /* Microsoft Wireless Mobile Mouse 1000 */
        /* Microsoft Wireless Desktop 3000 */
        MAKE_VIDPID(0x045e, 0x0745),

        /* Microsoft® SideWinder(TM) 2.4GHz Transceiver */
        MAKE_VIDPID(0x045e, 0x0748),

        /* Microsoft Corp. Wired Keyboard 600 */
        MAKE_VIDPID(0x045e, 0x0750),

        /* Microsoft Corp. Sidewinder X4 keyboard */
        MAKE_VIDPID(0x045e, 0x0768),

        /* Microsoft Corp. Arc Touch Mouse Transceiver */
        MAKE_VIDPID(0x045e, 0x0773),

        /* Microsoft® 2.4GHz Transceiver v9.0 */
        /* Microsoft® Nano Transceiver v2.1 */
        /* Microsoft Sculpt Ergonomic Keyboard (5KV-00001) */
        MAKE_VIDPID(0x045e, 0x07a5),

        /* Microsoft® Nano Transceiver v1.0 */
        /* Microsoft Wireless Keyboard 800 */
        MAKE_VIDPID(0x045e, 0x07b2),

        /* Microsoft® Nano Transceiver v2.0 */
        MAKE_VIDPID(0x045e, 0x0800),

        /* List of Wacom devices at: http://linuxwacom.sourceforge.net/wiki/index.php/Device_IDs */
        MAKE_VIDPID(0x056a, 0x0010),  /* Wacom ET-0405 Graphire */
        MAKE_VIDPID(0x056a, 0x0011),  /* Wacom ET-0405A Graphire2 (4x5) */
        MAKE_VIDPID(0x056a, 0x0012),  /* Wacom ET-0507A Graphire2 (5x7) */
        MAKE_VIDPID(0x056a, 0x0013),  /* Wacom CTE-430 Graphire3 (4x5) */
        MAKE_VIDPID(0x056a, 0x0014),  /* Wacom CTE-630 Graphire3 (6x8) */
        MAKE_VIDPID(0x056a, 0x0015),  /* Wacom CTE-440 Graphire4 (4x5) */
        MAKE_VIDPID(0x056a, 0x0016),  /* Wacom CTE-640 Graphire4 (6x8) */
        MAKE_VIDPID(0x056a, 0x0017),  /* Wacom CTE-450 Bamboo Fun (4x5) */
        MAKE_VIDPID(0x056a, 0x0016),  /* Wacom CTE-640 Graphire 4 6x8 */
        MAKE_VIDPID(0x056a, 0x0017),  /* Wacom CTE-450 Bamboo Fun 4x5 */
        MAKE_VIDPID(0x056a, 0x0018),  /* Wacom CTE-650 Bamboo Fun 6x8 */
        MAKE_VIDPID(0x056a, 0x0019),  /* Wacom CTE-631 Bamboo One */
        MAKE_VIDPID(0x056a, 0x00d1),  /* Wacom Bamboo Pen and Touch CTH-460 */

        MAKE_VIDPID(0x09da, 0x054f),  /* A4 Tech Co., G7 750 mouse */
        MAKE_VIDPID(0x09da, 0x3043),  /* A4 Tech Co., Ltd Bloody R8A Gaming Mouse */
        MAKE_VIDPID(0x09da, 0x31b5),  /* A4 Tech Co., Ltd Bloody TL80 Terminator Laser Gaming Mouse */
        MAKE_VIDPID(0x09da, 0x3997),  /* A4 Tech Co., Ltd Bloody RT7 Terminator Wireless */
        MAKE_VIDPID(0x09da, 0x3f8b),  /* A4 Tech Co., Ltd Bloody V8 mouse */
        MAKE_VIDPID(0x09da, 0x51f4),  /* Modecom MC-5006 Keyboard */
        MAKE_VIDPID(0x09da, 0x5589),  /* A4 Tech Co., Ltd Terminator TL9 Laser Gaming Mouse */
        MAKE_VIDPID(0x09da, 0x7b22),  /* A4 Tech Co., Ltd Bloody V5 */
        MAKE_VIDPID(0x09da, 0x7f2d),  /* A4 Tech Co., Ltd Bloody R3 mouse */
        MAKE_VIDPID(0x09da, 0x8090),  /* A4 Tech Co., Ltd X-718BK Oscar Optical Gaming Mouse */
        MAKE_VIDPID(0x09da, 0x9066),  /* A4 Tech Co., Sharkoon Fireglider Optical */
        MAKE_VIDPID(0x09da, 0x9090),  /* A4 Tech Co., Ltd XL-730K / XL-750BK / XL-755BK Laser Mouse */
        MAKE_VIDPID(0x09da, 0x90c0),  /* A4 Tech Co., Ltd X7 G800V keyboard */
        MAKE_VIDPID(0x09da, 0xf012),  /* A4 Tech Co., Ltd Bloody V7 mouse */
        MAKE_VIDPID(0x09da, 0xf32a),  /* A4 Tech Co., Ltd Bloody B540 keyboard */
        MAKE_VIDPID(0x09da, 0xf613),  /* A4 Tech Co., Ltd Bloody V2 mouse */
        MAKE_VIDPID(0x09da, 0xf624),  /* A4 Tech Co., Ltd Bloody B120 Keyboard */

        MAKE_VIDPID(0x1d57, 0xad03),  /* [T3] 2.4GHz and IR Air Mouse Remote Control */

        MAKE_VIDPID(0x1e7d, 0x2e4a),  /* Roccat Tyon Mouse */

        MAKE_VIDPID(0x20a0, 0x422d),  /* Winkeyless.kr Keyboards */

        MAKE_VIDPID(0x2516, 0x001f),  /* Cooler Master Storm Mizar Mouse */
        MAKE_VIDPID(0x2516, 0x0028),  /* Cooler Master Storm Alcor Mouse */
    };
    struct input_id inpid;
    int i;
    Uint32 id;
    Uint16 *guid16 = (Uint16 *)guid->data;

#if !SDL_USE_LIBUDEV
    /* When udev is enabled we only get joystick devices here, so there's no need to test them */
    unsigned long evbit[NBITS(EV_MAX)] = { 0 };
    unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
    unsigned long absbit[NBITS(ABS_MAX)] = { 0 };

    if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
        (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
        (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) {
        return (0);
    }

    if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) &&
          test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit))) {
        return 0;
    }
#endif

    if (ioctl(fd, EVIOCGNAME(namebuflen), namebuf) < 0) {
        return 0;
    }

    if (ioctl(fd, EVIOCGID, &inpid) < 0) {
        return 0;
    }

    /* Check the joystick blacklist */
    id = MAKE_VIDPID(inpid.vendor, inpid.product);
    for (i = 0; i < SDL_arraysize(joystick_blacklist); ++i) {
        if (id == joystick_blacklist[i]) {
            return 0;
        }
    }

#ifdef DEBUG_JOYSTICK
    printf("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", namebuf, inpid.bustype, inpid.vendor, inpid.product, inpid.version);
#endif

    SDL_memset(guid->data, 0, sizeof(guid->data));

    /* We only need 16 bits for each of these; space them out to fill 128. */
    /* Byteswap so devices get same GUID on little/big endian platforms. */
    *guid16++ = SDL_SwapLE16(inpid.bustype);
    *guid16++ = 0;

    if (inpid.vendor && inpid.product) {
        *guid16++ = SDL_SwapLE16(inpid.vendor);
        *guid16++ = 0;
        *guid16++ = SDL_SwapLE16(inpid.product);
        *guid16++ = 0;
        *guid16++ = SDL_SwapLE16(inpid.version);
        *guid16++ = 0;
    } else {
        SDL_strlcpy((char*)guid16, namebuf, sizeof(guid->data) - 4);
    }

    if (SDL_IsGameControllerNameAndGUID(namebuf, *guid) &&
        SDL_ShouldIgnoreGameController(namebuf, *guid)) {
        return 0;
    }
    return 1;
}