mirror of https://github.com/encounter/SDL.git
udev: Factor out SDL_EVDEV_GuessDeviceClass
This works on capability bitfields that can either come from udev or from ioctls, so it is equally applicable to both udev and non-udev input device detection. Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
parent
13e7d1a958
commit
8db3171b98
|
@ -1266,6 +1266,7 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS)
|
|||
endif()
|
||||
|
||||
# Always compiled for Linux, unconditionally:
|
||||
set(SOURCE_FILES ${SOURCE_FILES} "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev_capabilities.c")
|
||||
set(SOURCE_FILES ${SOURCE_FILES} "${SDL2_SOURCE_DIR}/src/core/linux/SDL_threadprio.c")
|
||||
|
||||
# src/core/unix/*.c is included in a generic if(UNIX) section, elsewhere.
|
||||
|
|
|
@ -24838,9 +24838,11 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h
|
|||
fi
|
||||
# Set up files for evdev input
|
||||
if test x$use_input_events = xyes; then
|
||||
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev*.c"
|
||||
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev.c"
|
||||
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev_kbd.c"
|
||||
fi
|
||||
# Set up other core UNIX files
|
||||
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev_capabilities.c"
|
||||
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_threadprio.c"
|
||||
SOURCES="$SOURCES $srcdir/src/core/unix/*.c"
|
||||
;;
|
||||
|
|
|
@ -3658,9 +3658,11 @@ case "$host" in
|
|||
fi
|
||||
# Set up files for evdev input
|
||||
if test x$use_input_events = xyes; then
|
||||
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev*.c"
|
||||
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev.c"
|
||||
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev_kbd.c"
|
||||
fi
|
||||
# Set up other core UNIX files
|
||||
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev_capabilities.c"
|
||||
SOURCES="$SOURCES $srcdir/src/core/linux/SDL_threadprio.c"
|
||||
SOURCES="$SOURCES $srcdir/src/core/unix/*.c"
|
||||
;;
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "SDL_scancode.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../../events/scancodes_linux.h" /* adds linux_scancode_table */
|
||||
#include "../../core/linux/SDL_evdev_capabilities.h"
|
||||
#include "../../core/linux/SDL_udev.h"
|
||||
|
||||
/* These are not defined in older Linux kernel headers */
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 2020 Collabora Ltd.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_evdev_capabilities.h"
|
||||
|
||||
#if HAVE_LIBUDEV_H
|
||||
|
||||
extern int
|
||||
SDL_EVDEV_GuessDeviceClass(unsigned long bitmask_ev[NBITS(EV_MAX)],
|
||||
unsigned long bitmask_abs[NBITS(ABS_MAX)],
|
||||
unsigned long bitmask_key[NBITS(KEY_MAX)],
|
||||
unsigned long bitmask_rel[NBITS(REL_MAX)])
|
||||
{
|
||||
int devclass = 0;
|
||||
unsigned long keyboard_mask;
|
||||
|
||||
if (test_bit(EV_ABS, bitmask_ev) &&
|
||||
test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs)) {
|
||||
if (test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key)) {
|
||||
; /* ID_INPUT_TABLET */
|
||||
} else if (test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key)) {
|
||||
; /* ID_INPUT_TOUCHPAD */
|
||||
} else if (test_bit(BTN_MOUSE, bitmask_key)) {
|
||||
devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */
|
||||
} else if (test_bit(BTN_TOUCH, bitmask_key)) {
|
||||
/* TODO: better determining between touchscreen and multitouch touchpad,
|
||||
see https://github.com/systemd/systemd/blob/master/src/udev/udev-builtin-input_id.c */
|
||||
devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN; /* ID_INPUT_TOUCHSCREEN */
|
||||
}
|
||||
|
||||
if (test_bit(BTN_TRIGGER, bitmask_key) ||
|
||||
test_bit(BTN_A, bitmask_key) ||
|
||||
test_bit(BTN_1, bitmask_key) ||
|
||||
test_bit(ABS_RX, bitmask_abs) ||
|
||||
test_bit(ABS_RY, bitmask_abs) ||
|
||||
test_bit(ABS_RZ, bitmask_abs) ||
|
||||
test_bit(ABS_THROTTLE, bitmask_abs) ||
|
||||
test_bit(ABS_RUDDER, bitmask_abs) ||
|
||||
test_bit(ABS_WHEEL, bitmask_abs) ||
|
||||
test_bit(ABS_GAS, bitmask_abs) ||
|
||||
test_bit(ABS_BRAKE, bitmask_abs)) {
|
||||
devclass |= SDL_UDEV_DEVICE_JOYSTICK; /* ID_INPUT_JOYSTICK */
|
||||
}
|
||||
}
|
||||
|
||||
if (test_bit(EV_REL, bitmask_ev) &&
|
||||
test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel) &&
|
||||
test_bit(BTN_MOUSE, bitmask_key)) {
|
||||
devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */
|
||||
}
|
||||
|
||||
/* the first 32 bits are ESC, numbers, and Q to D; if we have any of
|
||||
* those, consider it a keyboard device; do not test KEY_RESERVED, though */
|
||||
keyboard_mask = 0xFFFFFFFE;
|
||||
if ((bitmask_key[0] & keyboard_mask) != 0)
|
||||
devclass |= SDL_UDEV_DEVICE_KEYBOARD; /* ID_INPUT_KEYBOARD */
|
||||
|
||||
return devclass;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 2020 Collabora Ltd.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_evdev_capabilities_h_
|
||||
#define SDL_evdev_capabilities_h_
|
||||
|
||||
#if HAVE_LIBUDEV_H
|
||||
|
||||
#include <linux/input.h>
|
||||
|
||||
/* A device can be any combination of these classes */
|
||||
typedef enum
|
||||
{
|
||||
SDL_UDEV_DEVICE_UNKNOWN = 0x0000,
|
||||
SDL_UDEV_DEVICE_MOUSE = 0x0001,
|
||||
SDL_UDEV_DEVICE_KEYBOARD = 0x0002,
|
||||
SDL_UDEV_DEVICE_JOYSTICK = 0x0004,
|
||||
SDL_UDEV_DEVICE_SOUND = 0x0008,
|
||||
SDL_UDEV_DEVICE_TOUCHSCREEN = 0x0010
|
||||
} SDL_UDEV_deviceclass;
|
||||
|
||||
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
|
||||
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
|
||||
#define EVDEV_OFF(x) ((x)%BITS_PER_LONG)
|
||||
#define EVDEV_LONG(x) ((x)/BITS_PER_LONG)
|
||||
#define test_bit(bit, array) ((array[EVDEV_LONG(bit)] >> EVDEV_OFF(bit)) & 1)
|
||||
|
||||
extern int SDL_EVDEV_GuessDeviceClass(unsigned long bitmask_ev[NBITS(EV_MAX)],
|
||||
unsigned long bitmask_abs[NBITS(ABS_MAX)],
|
||||
unsigned long bitmask_key[NBITS(KEY_MAX)],
|
||||
unsigned long bitmask_rel[NBITS(REL_MAX)]);
|
||||
|
||||
#endif /* HAVE_LIBUDEV_H */
|
||||
|
||||
#endif /* SDL_evdev_capabilities_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/input.h>
|
||||
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_evdev_capabilities.h"
|
||||
#include "SDL_loadso.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_hints.h"
|
||||
|
@ -291,12 +292,6 @@ SDL_UDEV_LoadLibrary(void)
|
|||
return retval;
|
||||
}
|
||||
|
||||
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
|
||||
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
|
||||
#define OFF(x) ((x)%BITS_PER_LONG)
|
||||
#define LONG(x) ((x)/BITS_PER_LONG)
|
||||
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
|
||||
|
||||
static void get_caps(struct udev_device *dev, struct udev_device *pdev, const char *attr, unsigned long *bitmask, size_t bitmask_len)
|
||||
{
|
||||
const char *value;
|
||||
|
@ -330,13 +325,11 @@ static void get_caps(struct udev_device *dev, struct udev_device *pdev, const ch
|
|||
static int
|
||||
guess_device_class(struct udev_device *dev)
|
||||
{
|
||||
int devclass = 0;
|
||||
struct udev_device *pdev;
|
||||
unsigned long bitmask_ev[NBITS(EV_MAX)];
|
||||
unsigned long bitmask_abs[NBITS(ABS_MAX)];
|
||||
unsigned long bitmask_key[NBITS(KEY_MAX)];
|
||||
unsigned long bitmask_rel[NBITS(REL_MAX)];
|
||||
unsigned long keyboard_mask;
|
||||
|
||||
/* walk up the parental chain until we find the real input device; the
|
||||
* argument is very likely a subdevice of this, like eventN */
|
||||
|
@ -353,48 +346,10 @@ guess_device_class(struct udev_device *dev)
|
|||
get_caps(dev, pdev, "capabilities/rel", bitmask_rel, SDL_arraysize(bitmask_rel));
|
||||
get_caps(dev, pdev, "capabilities/key", bitmask_key, SDL_arraysize(bitmask_key));
|
||||
|
||||
if (test_bit(EV_ABS, bitmask_ev) &&
|
||||
test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs)) {
|
||||
if (test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key)) {
|
||||
; /* ID_INPUT_TABLET */
|
||||
} else if (test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key)) {
|
||||
; /* ID_INPUT_TOUCHPAD */
|
||||
} else if (test_bit(BTN_MOUSE, bitmask_key)) {
|
||||
devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */
|
||||
} else if (test_bit(BTN_TOUCH, bitmask_key)) {
|
||||
/* TODO: better determining between touchscreen and multitouch touchpad,
|
||||
see https://github.com/systemd/systemd/blob/master/src/udev/udev-builtin-input_id.c */
|
||||
devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN; /* ID_INPUT_TOUCHSCREEN */
|
||||
}
|
||||
|
||||
if (test_bit(BTN_TRIGGER, bitmask_key) ||
|
||||
test_bit(BTN_A, bitmask_key) ||
|
||||
test_bit(BTN_1, bitmask_key) ||
|
||||
test_bit(ABS_RX, bitmask_abs) ||
|
||||
test_bit(ABS_RY, bitmask_abs) ||
|
||||
test_bit(ABS_RZ, bitmask_abs) ||
|
||||
test_bit(ABS_THROTTLE, bitmask_abs) ||
|
||||
test_bit(ABS_RUDDER, bitmask_abs) ||
|
||||
test_bit(ABS_WHEEL, bitmask_abs) ||
|
||||
test_bit(ABS_GAS, bitmask_abs) ||
|
||||
test_bit(ABS_BRAKE, bitmask_abs)) {
|
||||
devclass |= SDL_UDEV_DEVICE_JOYSTICK; /* ID_INPUT_JOYSTICK */
|
||||
}
|
||||
}
|
||||
|
||||
if (test_bit(EV_REL, bitmask_ev) &&
|
||||
test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel) &&
|
||||
test_bit(BTN_MOUSE, bitmask_key)) {
|
||||
devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */
|
||||
}
|
||||
|
||||
/* the first 32 bits are ESC, numbers, and Q to D; if we have any of
|
||||
* those, consider it a keyboard device; do not test KEY_RESERVED, though */
|
||||
keyboard_mask = 0xFFFFFFFE;
|
||||
if ((bitmask_key[0] & keyboard_mask) != 0)
|
||||
devclass |= SDL_UDEV_DEVICE_KEYBOARD; /* ID_INPUT_KEYBOARD */
|
||||
|
||||
return devclass;
|
||||
return SDL_EVDEV_GuessDeviceClass(&bitmask_ev[0],
|
||||
&bitmask_abs[0],
|
||||
&bitmask_key[0],
|
||||
&bitmask_rel[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -46,17 +46,6 @@ typedef enum
|
|||
SDL_UDEV_DEVICEREMOVED
|
||||
} SDL_UDEV_deviceevent;
|
||||
|
||||
/* A device can be any combination of these classes */
|
||||
typedef enum
|
||||
{
|
||||
SDL_UDEV_DEVICE_UNKNOWN = 0x0000,
|
||||
SDL_UDEV_DEVICE_MOUSE = 0x0001,
|
||||
SDL_UDEV_DEVICE_KEYBOARD = 0x0002,
|
||||
SDL_UDEV_DEVICE_JOYSTICK = 0x0004,
|
||||
SDL_UDEV_DEVICE_SOUND = 0x0008,
|
||||
SDL_UDEV_DEVICE_TOUCHSCREEN = 0x0010
|
||||
} SDL_UDEV_deviceclass;
|
||||
|
||||
typedef void (*SDL_UDEV_Callback)(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath);
|
||||
|
||||
typedef struct SDL_UDEV_CallbackList {
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "SDL_joystick.h"
|
||||
#include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */
|
||||
#include "../../joystick/linux/SDL_sysjoystick_c.h" /* For joystick hwdata */
|
||||
#include "../../core/linux/SDL_evdev_capabilities.h"
|
||||
#include "../../core/linux/SDL_udev.h"
|
||||
|
||||
#include <unistd.h> /* close */
|
||||
|
@ -86,8 +87,6 @@ static SDL_hapticlist_item *SDL_hapticlist = NULL;
|
|||
static SDL_hapticlist_item *SDL_hapticlist_tail = NULL;
|
||||
static int numhaptics = 0;
|
||||
|
||||
#define test_bit(nr, addr) \
|
||||
(((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0)
|
||||
#define EV_TEST(ev,f) \
|
||||
if (test_bit((ev), features)) ret |= (f);
|
||||
/*
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
#define BTN_DPAD_RIGHT 0x223
|
||||
#endif
|
||||
|
||||
#include "../../core/linux/SDL_evdev_capabilities.h"
|
||||
#include "../../core/linux/SDL_udev.h"
|
||||
|
||||
#if 0
|
||||
|
@ -124,10 +125,6 @@ static int numjoysticks = 0;
|
|||
static Uint32 last_joy_detect_time;
|
||||
static time_t last_input_dir_mtime;
|
||||
|
||||
#define test_bit(nr, addr) \
|
||||
(((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
|
||||
#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
|
||||
|
||||
static void
|
||||
FixupDeviceInfoForMapping(int fd, struct input_id *inpid)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue