src/haptic/linux/SDL_syshaptic.c
branchgsoc2008_force_feedback
changeset 2472 3f73c88c9abb
child 2474 3f80bf1528b4
equal deleted inserted replaced
2471:910af9032c73 2472:3f73c88c9abb
       
     1 /*
       
     2     SDL - Simple DirectMedia Layer
       
     3     Copyright (C) 2008 Edgar Simo
       
     4 
       
     5     This library is free software; you can redistribute it and/or
       
     6     modify it under the terms of the GNU Lesser General Public
       
     7     License as published by the Free Software Foundation; either
       
     8     version 2.1 of the License, or (at your option) any later version.
       
     9 
       
    10     This library is distributed in the hope that it will be useful,
       
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13     Lesser General Public License for more details.
       
    14 
       
    15     You should have received a copy of the GNU Lesser General Public
       
    16     License along with this library; if not, write to the Free Software
       
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       
    18 
       
    19     Sam Lantinga
       
    20     slouken@libsdl.org
       
    21 */
       
    22 #include "SDL_config.h"
       
    23 
       
    24 #ifdef SDL_JOYSTICK_LINUX
       
    25 
       
    26 #include "SDL_haptic.h"
       
    27 #include "../SDL_haptic_c.h"
       
    28 #include "../SDL_syshaptic.h"
       
    29 
       
    30 #include <unistd.h> /* close */
       
    31 #include <linux/input.h>
       
    32 #include <sys/ioctl.h>
       
    33 #include <sys/types.h>
       
    34 #include <sys/stat.h>
       
    35 #include <fcntl.h>
       
    36 #include <linux/limits.h>
       
    37 #include <string.h>
       
    38 
       
    39 
       
    40 #include <stdio.h>
       
    41 
       
    42 
       
    43 #define MAX_HAPTICS  32
       
    44 
       
    45 
       
    46 static struct
       
    47 {
       
    48    char *fname;
       
    49    SDL_Haptic *haptic;
       
    50 } SDL_hapticlist[MAX_HAPTICS];
       
    51 
       
    52 struct haptic_hwdata
       
    53 {
       
    54    int fd;
       
    55 };
       
    56 
       
    57 
       
    58 #define test_bit(nr, addr) \
       
    59    (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0)
       
    60 #define EV_TEST(ev,f) \
       
    61    if (test_bit((ev), features)) ret |= (f);
       
    62 static int
       
    63 EV_IsHaptic(int fd)
       
    64 {
       
    65    unsigned int ret;
       
    66    unsigned long features[1 + FF_MAX/sizeof(unsigned long)];
       
    67 
       
    68    ret = 0;
       
    69 
       
    70    ioctl(fd, EVIOCGBIT(EV_FF, sizeof(unsigned long) * 4), features);
       
    71 
       
    72    EV_TEST(FF_CONSTANT,   SDL_HAPTIC_CONSTANT);
       
    73    EV_TEST(FF_PERIODIC,   SDL_HAPTIC_PERIODIC);
       
    74    EV_TEST(FF_RAMP,       SDL_HAPTIC_RAMP);
       
    75    EV_TEST(FF_SPRING,     SDL_HAPTIC_SPRING);
       
    76    EV_TEST(FF_FRICTION,   SDL_HAPTIC_FRICTION);
       
    77    EV_TEST(FF_DAMPER,     SDL_HAPTIC_DAMPER);
       
    78    EV_TEST(FF_RUMBLE,     SDL_HAPTIC_RUMBLE);
       
    79    EV_TEST(FF_INERTIA,    SDL_HAPTIC_INERTIA);
       
    80    EV_TEST(FF_GAIN,       SDL_HAPTIC_GAIN);
       
    81    EV_TEST(FF_AUTOCENTER, SDL_HAPTIC_AUTOCENTER);
       
    82 
       
    83    return ret;
       
    84 }
       
    85 
       
    86 int
       
    87 SDL_SYS_HapticInit(void)
       
    88 {
       
    89    const char joydev_pattern[] = "/dev/input/event%d";
       
    90    dev_t dev_nums[MAX_HAPTICS];
       
    91    char path[PATH_MAX];
       
    92    struct stat sb;
       
    93    int fd;
       
    94    int i, j, k;
       
    95    int duplicate;
       
    96    int numhaptics;
       
    97 
       
    98    numhaptics = 0;
       
    99 
       
   100    i = 0;
       
   101    for (j = 0; j < MAX_HAPTICS; ++j) {
       
   102 
       
   103       snprintf(path, PATH_MAX, joydev_pattern, i++);
       
   104 
       
   105       /* check to see if file exists */
       
   106       if (stat(path,&sb) != 0)
       
   107          break;
       
   108 
       
   109       /* check for duplicates */
       
   110       duplicate = 0;
       
   111       for (k = 0; (k < numhaptics) && !duplicate; ++k) {
       
   112          if (sb.st_rdev == dev_nums[k]) {
       
   113             duplicate = 1;
       
   114          }                                                     
       
   115       }                                                         
       
   116       if (duplicate) {
       
   117          continue;
       
   118       }
       
   119 
       
   120       /* try to open */
       
   121       fd = open(path, O_RDWR, 0);
       
   122       if (fd < 0) continue;
       
   123 
       
   124 #ifdef DEBUG_INPUT_EVENTS
       
   125       printf("Checking %s\n", path);
       
   126 #endif          
       
   127 
       
   128       /* see if it works */
       
   129       if (EV_IsHaptic(fd)!=0) {
       
   130          SDL_hapticlist[numhaptics].fname = SDL_strdup(path);
       
   131          SDL_hapticlist[numhaptics].haptic = NULL;
       
   132          dev_nums[numhaptics] = sb.st_rdev;
       
   133          ++numhaptics;
       
   134       }
       
   135       close(fd);
       
   136    }
       
   137 
       
   138    return numhaptics;
       
   139 }
       
   140 
       
   141 
       
   142 const char *
       
   143 SDL_SYS_HapticName(int index)
       
   144 {
       
   145    int fd;
       
   146    static char namebuf[128];
       
   147    char *name;
       
   148 
       
   149    name = NULL;
       
   150    fd = open(SDL_hapticlist[index].fname, O_RDONLY, 0);
       
   151    if (fd >= 0) {
       
   152       if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) {
       
   153          name = SDL_hapticlist[index].fname;
       
   154       }
       
   155       else {
       
   156          name = namebuf;
       
   157       }
       
   158    }
       
   159    close(fd);
       
   160 
       
   161    return name;
       
   162 }
       
   163 
       
   164 
       
   165 int
       
   166 SDL_SYS_HapticOpen(SDL_Haptic * haptic)
       
   167 {
       
   168    /* TODO finish
       
   169    int fd;
       
   170 
       
   171    fd = open(SDL_hapticlist[haptic->index].fname, O_RDWR, 0);
       
   172    
       
   173    if (fd < 0) {
       
   174       SDL_SetError("Unable to open %s\n", SDL_hapticlist[haptic->index]);
       
   175       return (-1);
       
   176    }
       
   177 
       
   178    
       
   179 
       
   180    return 0;
       
   181    */
       
   182 }
       
   183 
       
   184 
       
   185 #endif /* SDL_HAPTIC_LINUX */