Navigation Menu

Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Better handling of opening haptics from joysticks.
Browse files Browse the repository at this point in the history
Fixed segfault when opening from joystick.
  • Loading branch information
bobbens committed Jul 17, 2008
1 parent 5bc4415 commit 586a2fb
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/haptic/SDL_haptic.c
Expand Up @@ -274,7 +274,7 @@ SDL_HapticOpenFromJoystick(SDL_Joystick * joystick)
}

/* Initialize the haptic device */
SDL_memset(haptic, 0, (sizeof *haptic));
SDL_memset(haptic, 0, sizeof(SDL_Haptic));
if (SDL_SYS_HapticOpenFromJoystick(haptic,joystick) < 0) {
SDL_free(haptic);
return NULL;
Expand Down
1 change: 0 additions & 1 deletion src/haptic/SDL_syshaptic.h
Expand Up @@ -43,7 +43,6 @@ struct haptic_effect
struct _SDL_Haptic
{
Uint8 index; /* Stores index it is attached to */
const char* name; /* Stores the name of the device */

struct haptic_effect *effects; /* Allocated effects */
int neffects; /* Maximum amount of effects */
Expand Down
76 changes: 60 additions & 16 deletions src/haptic/linux/SDL_syshaptic.c
Expand Up @@ -65,6 +65,7 @@ static struct
struct haptic_hwdata
{
int fd;
char *fname; /* Points to the name in SDL_hapticlist. */
};


Expand Down Expand Up @@ -204,32 +205,43 @@ SDL_SYS_HapticInit(void)
}


/*
* Gets the name from a file descriptor.
*/
static const char *
SDL_SYS_HapticNameFromFD(int fd)
{
static char namebuf[128];

/* We use the evdev name ioctl. */
if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) {
return NULL;
}

return namebuf;
}


/*
* Return the name of a haptic device, does not need to be opened.
*/
const char *
SDL_SYS_HapticName(int index)
{
int fd;
static char namebuf[128];
char *name;
const 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) {

name = SDL_SYS_HapticNameFromFD(fd);
if (name==NULL) {
/* No name found, return device character device */
name = SDL_hapticlist[index].fname;
}
/* Name found, return name. */
else {
name = namebuf;
}
}
close(fd);

Expand All @@ -243,6 +255,8 @@ SDL_SYS_HapticName(int index)
static int
SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd)
{
const char *name;

/* Allocate the hwdata */
haptic->hwdata = (struct haptic_hwdata *)
SDL_malloc(sizeof(*haptic->hwdata));
Expand All @@ -252,7 +266,7 @@ SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd)
}
SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));

/* Set the data */
/* Set the data. */
haptic->hwdata->fd = fd;
haptic->supported = EV_IsHaptic(fd);
haptic->naxes = 2; /* Hardcoded for now, not sure if it's possible to find out. */
Expand Down Expand Up @@ -293,6 +307,7 @@ int
SDL_SYS_HapticOpen(SDL_Haptic * haptic)
{
int fd;
int ret;

/* Open the character device */
fd = open(SDL_hapticlist[haptic->index].fname, O_RDWR, 0);
Expand All @@ -301,8 +316,16 @@ SDL_SYS_HapticOpen(SDL_Haptic * haptic)
SDL_hapticlist[haptic->index], strerror(errno));
return -1;
}

return SDL_SYS_HapticOpenFromFD(haptic,fd);

/* Try to create the haptic. */
ret = SDL_SYS_HapticOpenFromFD(haptic,fd); /* Already closes on error. */
if (ret < 0) {
return -1;
}

/* Set the fname. */
haptic->hwdata->fname = SDL_hapticlist[haptic->index].fname;
return 0;
}


Expand Down Expand Up @@ -353,7 +376,9 @@ SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick)
int
SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
{
if (SDL_strcmp(joystick->name,haptic->name)==0) {
/* We are assuming linux is using evdev which should trump the old
* joystick methods. */
if (SDL_strcmp(joystick->hwdata->fname,haptic->hwdata->fname)==0) {
return 1;
}
return 0;
Expand All @@ -366,9 +391,27 @@ SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
int
SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
{
int i;
int fd;
int ret;

/* Find the joystick in the haptic list. */
for (i=0; i<MAX_HAPTICS; i++) {
if (SDL_hapticlist[i].fname != NULL) {
if (SDL_strcmp(SDL_hapticlist[i].fname, joystick->hwdata->fname)==0) {
haptic->index = i;
}
}
}

fd = open(joystick->hwdata->fname, O_RDWR, 0);
return SDL_SYS_HapticOpenFromFD(haptic,fd);
ret = SDL_SYS_HapticOpenFromFD(haptic,fd); /* Already closes on error. */
if (ret < 0) {
return -1;
}

haptic->hwdata->fname = SDL_hapticlist[haptic->index].fname;
return 0;
}


Expand All @@ -385,10 +428,11 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic)

/* Free */
SDL_free(haptic->hwdata);
haptic->hwdata = NULL;
SDL_free(haptic->effects);
haptic->neffects = 0;
}

/* Clear the rest. */
SDL_memset(haptic, 0, sizeof(SDL_Haptic));
}


Expand Down

0 comments on commit 586a2fb

Please sign in to comment.