From e6ffae508a0dd4902e97aede0b345000cfabf9ec Mon Sep 17 00:00:00 2001 From: Edgar Simo Date: Thu, 10 Jul 2008 08:38:08 +0000 Subject: [PATCH] Improved some ioctl handling. Implemented SDL_MouseIsHaptic and SDL_HapticOpenFromMouse. More code comments. --- include/SDL_haptic.h | 24 +++++++++++ src/haptic/SDL_haptic.c | 33 ++++++++++++++- src/haptic/SDL_syshaptic.h | 12 +++++- src/haptic/dummy/SDL_syshaptic.c | 7 +++ src/haptic/linux/SDL_syshaptic.c | 73 ++++++++++++++++++++++++++++++-- 5 files changed, 144 insertions(+), 5 deletions(-) diff --git a/include/SDL_haptic.h b/include/SDL_haptic.h index 4c2745f05..5a1393e59 100644 --- a/include/SDL_haptic.h +++ b/include/SDL_haptic.h @@ -638,6 +638,7 @@ extern DECLSPEC const char *SDLCALL SDL_HapticName(int device_index); * \return Device identifier or NULL on error. * * \sa SDL_HapticIndex + * \sa SDL_HapticOpenFromMouse * \sa SDL_HapticOpenFromJoystick * \sa SDL_HapticClose * \sa SDL_HapticSetGain @@ -671,6 +672,29 @@ extern DECLSPEC int SDL_HapticOpened(int device_index); */ extern DECLSPEC int SDL_HapticIndex(SDL_Haptic * haptic); +/** + * \fn int SDL_MouseIsHaptic(void) + * + * \brief Gets whether or not the current mouse has haptic capabilities. + * + * \return SDL_TRUE if the mouse is haptic, SDL_FALSE if it isn't. + * + * \sa SDL_HapticOpenFromMouse + */ +extern DECLSPEC SDL_MouseIsHaptic(void); + +/** + * \fn SDL_Haptic * SDL_HapticOpenFromMouse(void) + * + * \brief Tries to open a haptic device from the current mouse. + * + * \return The haptic device identifier or NULL on error. + * + * \sa SDL_MouseIsHaptic + * \sa SDL_HapticOpen + */ +extern DECLSPEC SDL_Haptic * SDL_HapticOpenFromMouse(void); + /** * \fn int SDL_JoystickIsHaptic(SDL_Joystick * joystick) * diff --git a/src/haptic/SDL_haptic.c b/src/haptic/SDL_haptic.c index c04144319..a703544e1 100644 --- a/src/haptic/SDL_haptic.c +++ b/src/haptic/SDL_haptic.c @@ -25,7 +25,7 @@ #include "../joystick/SDL_joystick_c.h" /* For SDL_PrivateJoystickValid */ -static Uint8 SDL_numhaptics = 0; +Uint8 SDL_numhaptics = 0; SDL_Haptic **SDL_haptics = NULL; static SDL_Haptic *default_haptic = NULL; @@ -187,6 +187,37 @@ SDL_HapticIndex(SDL_Haptic * haptic) } +/* + * Returns SDL_TRUE if mouse is haptic, SDL_FALSE if it isn't. + */ +int +SDL_MouseIsHaptic(void) +{ + if (SDL_SYS_HapticMouse() < 0) + return SDL_FALSE; + return SDL_TRUE; +} + + +/* + * Returns the haptic device if mouse is haptic or NULL elsewise. + */ +SDL_Haptic * +SDL_HapticOpenFromMouse(void) +{ + int device_index; + + device_index = SDL_SYS_HapticMouse(); + + if (device_index < 0) { + SDL_SetError("Mouse isn't a haptic device."); + return NULL; + } + + return SDL_HapticOpen(device_index); +} + + /* * Returns SDL_TRUE if joystick has haptic features. */ diff --git a/src/haptic/SDL_syshaptic.h b/src/haptic/SDL_syshaptic.h index 3c4d7a296..55ee2f6fa 100644 --- a/src/haptic/SDL_syshaptic.h +++ b/src/haptic/SDL_syshaptic.h @@ -25,6 +25,12 @@ #include "SDL_haptic.h" +/* + * Number of haptic devices on the system. + */ +extern Uint8 SDL_numhaptics; + + struct haptic_effect { SDL_HapticEffect effect; /* The current event */ @@ -67,6 +73,11 @@ extern const char * SDL_SYS_HapticName(int index); */ extern int SDL_SYS_HapticOpen(SDL_Haptic * haptic); +/* + * Returns the index of the haptic core pointer or -1 if none is found. + */ +int SDL_SYS_HapticMouse(void); + /* * Checks to see if the joystick has haptic capabilities. * @@ -83,7 +94,6 @@ extern int SDL_JoystickIsHaptic(SDL_Joystick * joystick); */ extern int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick); - /* * Checks to see if haptic device and joystick device are the same. * diff --git a/src/haptic/dummy/SDL_syshaptic.c b/src/haptic/dummy/SDL_syshaptic.c index f1017bce5..0b9767623 100644 --- a/src/haptic/dummy/SDL_syshaptic.c +++ b/src/haptic/dummy/SDL_syshaptic.c @@ -50,6 +50,13 @@ SDL_SYS_HapticOpen(SDL_Haptic * haptic) } +int +SDL_SYS_HapticMouse(void) +{ + return -1; +} + + int SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick) { diff --git a/src/haptic/linux/SDL_syshaptic.c b/src/haptic/linux/SDL_syshaptic.c index 50c3e45e2..c97263665 100644 --- a/src/haptic/linux/SDL_syshaptic.c +++ b/src/haptic/linux/SDL_syshaptic.c @@ -91,13 +91,14 @@ EV_IsHaptic(int fd) unsigned int ret; unsigned long features[1 + FF_MAX/sizeof(unsigned long)]; + /* Ask device for what it has. */ ret = 0; - - if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(unsigned long) * 4), features) < 0) { + if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(features)), features) < 0) { SDL_SetError("Unable to get device's haptic abilities: %s", strerror(errno)); return -1; } + /* Convert supported features to SDL_HAPTIC platform-neutral features. */ EV_TEST(FF_CONSTANT, SDL_HAPTIC_CONSTANT); EV_TEST(FF_PERIODIC, SDL_HAPTIC_SINE | SDL_HAPTIC_SQUARE | @@ -113,9 +114,32 @@ EV_IsHaptic(int fd) EV_TEST(FF_GAIN, SDL_HAPTIC_GAIN); EV_TEST(FF_AUTOCENTER, SDL_HAPTIC_AUTOCENTER); + /* Return what it supports. */ return ret; } + +/* + * Tests whether a device is a mouse or not. + */ +static int +EV_IsMouse(int fd) +{ + unsigned long argp[40]; + + /* Ask for supported features. */ + if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(argp)), argp) < 0) { + return -1; + } + + /* Currently we only test for BTN_MOUSE which can give fake positives. */ + if (test_bit(BTN_MOUSE,argp) != 0) { + return 1; + } + + return 0; +} + /* * Initializes the haptic subsystem by finding available devices. */ @@ -133,6 +157,10 @@ SDL_SYS_HapticInit(void) numhaptics = 0; + /* + * Limit amount of checks to MAX_HAPTICS since we may or may not have + * permission to some or all devices. + */ i = 0; for (j = 0; j < MAX_HAPTICS; ++j) { @@ -185,12 +213,19 @@ SDL_SYS_HapticName(int index) static char namebuf[128]; char *name; + /* Open the haptic device. */ name = NULL; fd = open(SDL_hapticlist[index].fname, O_RDONLY, 0); + if (fd >= 0) { + + /* Check for name ioctl. */ if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) { + + /* No name found, return device character device */ name = SDL_hapticlist[index].fname; } + /* Name found, return name. */ else { name = namebuf; } @@ -215,6 +250,7 @@ SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd) goto open_err; } SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata)); + /* Set the data */ haptic->hwdata->fd = fd; haptic->supported = EV_IsHaptic(fd); @@ -264,7 +300,38 @@ SDL_SYS_HapticOpen(SDL_Haptic * haptic) } return SDL_SYS_HapticOpenFromFD(haptic,fd); -} +} + + +/* + * Opens a haptic device from first mouse it finds for usage. + */ +int +SDL_SYS_HapticMouse(void) +{ + int fd; + int i; + + for (i=0; i