first commit
authorStefan Huber <shuber2@gmx.at>
Sat, 24 Dec 2011 01:57:04 +0000 (02:57 +0100)
committerStefan Huber <shuber2@gmx.at>
Sat, 24 Dec 2011 01:57:04 +0000 (02:57 +0100)
CMakeLists.txt [new file with mode: 0644]
src/CMakeLists.txt [new file with mode: 0644]
src/config.h.cmake [new file with mode: 0644]
src/main.c [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d2678bc
--- /dev/null
@@ -0,0 +1,20 @@
+cmake_minimum_required (VERSION 2.6)
+project (joydevmap) 
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --std=c99")
+set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG")
+set(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed" )
+
+if(CMAKE_BUILD_TYPE STREQUAL "Release")
+       set(CMAKE_C_FLAGS "-O2 ${CMAKE_C_FLAGS}")
+endif()
+
+set(PACKAGE_STRING joydevmap)
+set(PACKAGE_BUGREPORT shuber2@gmx.at)
+set(PACKAGE_VERSION 1.0)
+
+add_subdirectory(src)
+
+
+
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..940dd33
--- /dev/null
@@ -0,0 +1,13 @@
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic")
+set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror")
+
+
+set( joydevmap_SRC main.c )
+
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+add_executable(joydevmap ${joydevmap_SRC})
+
+
diff --git a/src/config.h.cmake b/src/config.h.cmake
new file mode 100644 (file)
index 0000000..597e3c1
--- /dev/null
@@ -0,0 +1,3 @@
+#define PACKAGE_STRING "@PACKAGE_STRING@"
+#define PACKAGE_VERSION "@PACKAGE_VERSION@"
+#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
diff --git a/src/main.c b/src/main.c
new file mode 100644 (file)
index 0000000..93362df
--- /dev/null
@@ -0,0 +1,333 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+#include <linux/joystick.h>
+
+#include "config.h"
+
+
+#define MAXFN 1024
+#define EXIT_INVARG 1
+#define EXIT_OPEN 2
+#define EXIT_IOCTL 3
+#define EXIT_VERSION 4
+#define EXIT_VALUE 5
+
+
+
+void reportMissingArgument(const char* opt)
+{
+       fprintf(stderr, "Missing argument for option '%s'.\n", opt);
+       exit(EXIT_INVARG);
+}
+
+void printHelp(FILE* out, int argc, char** argv)
+{
+       (void) argc;
+
+       fprintf(out, "Usage:\n"
+                       "  %s -h\n"
+                       "  %s --help\n"
+                       "  %s {commands} --dev <device>\n"
+                       "\n"
+                       "Commands:\n"
+                       "  --list-axismap\n"
+                       "  --list-buttonmap\n"
+                       "  --set-axismap 'id, id, id...'\n"
+                       "  --set-buttonmap 'id, id, id...'\n",
+                       argv[0], argv[0], argv[0]);
+}
+
+
+void listAxismap(int fd)
+{
+       __u8 cnt=0;
+       __u8 map[ABS_CNT] = {-1};
+
+
+       if (ioctl(fd, JSIOCGAXES, &cnt) )
+       {
+               perror(PACKAGE_STRING ": error getting number of axes");
+               exit(EXIT_IOCTL);
+       }
+       printf("Got %d axes:\n", cnt);
+       assert( cnt <= ABS_CNT);
+
+
+       if( ioctl(fd, JSIOCGAXMAP, &map) < 0 )
+       {
+               perror(PACKAGE_STRING ": error getting axis map");
+               exit(1);
+       }
+       
+       for(int i=0; i<cnt; i++)
+               printf("  %d => %d\n", i, map[i] );
+
+       printf("\n");
+       printf("Set this mapping with:\n");
+       printf("  " PACKAGE_STRING " --set-axismap '");
+       for(int i=0; i<cnt; i++)
+       {
+               if( i> 0)
+                       printf(", ");
+               printf("%d", map[i] );
+       }
+       printf("'\n");
+}
+
+
+void listButtonmap(int fd)
+{
+       __u8 cnt=0;
+       __u16 map[KEY_MAX - BTN_MISC + 1] = {-1};
+
+       if (ioctl(fd, JSIOCGBUTTONS, &cnt) )
+       {
+               perror(PACKAGE_STRING ": error getting number of buttons");
+               exit(EXIT_IOCTL);
+       }
+       printf("Got %d buttons:\n", cnt);
+
+
+       if( ioctl(fd, JSIOCGBTNMAP, &map) < 0 )
+       {
+               perror(PACKAGE_STRING ": error getting button map");
+               exit(1);
+       }
+       
+       for(int i=0; i<cnt; i++)
+               printf("  %d => %d\n", i, map[i] );
+
+       printf("\n");
+       printf("Set this mapping with:\n");
+       printf("  " PACKAGE_STRING " --set-buttonmap '");
+       for(int i=0; i<cnt; i++)
+       {
+               if( i> 0)
+                       printf(", ");
+               printf("%d", map[i] );
+       }
+       printf("'\n");
+}
+
+
+void setAxismap(int fd, char* mapstr)
+{
+       __u8 cnt=0;
+       __u8 map[ABS_CNT] = {-1};
+
+
+       if (ioctl(fd, JSIOCGAXES, &cnt) )
+       {
+               perror(PACKAGE_STRING ": error getting number of axes");
+               exit(EXIT_IOCTL);
+       }
+       printf("Setting %d axes.\n", cnt);
+       assert( cnt <= ABS_CNT);
+
+
+       char* s = mapstr;
+       for(unsigned i=0; i<cnt; ++i)
+       {
+               if( !s )
+               {
+                       fprintf(stderr, "Missing value for axis %d.\n", i);
+                       exit(EXIT_VALUE);
+               }
+
+               int val=-1;
+               sscanf(s, "%d", &val);
+               if( val<0 || val>=(1<<8) )
+               {
+                       fprintf(stderr, "Value out of bounds: %d\n", val);
+                       exit(EXIT_VALUE);
+               }
+               map[i] = val;
+
+               s = strstr(s, ",");
+               if(s)
+                       s++;
+       }
+
+       if( s )
+               fprintf(stderr, "Too many values given for the axismap. Ignoring the rest.\n");
+
+
+       printf("Setting the following map:\n"); 
+       for(int i=0; i<cnt; i++)
+               printf("  %d => %d\n", i, map[i] );
+
+
+       if( ioctl(fd, JSIOCSAXMAP, &map) )
+       {
+               perror( PACKAGE_STRING ": error setting axis map");
+               exit(EXIT_IOCTL);
+       }
+}
+
+
+void setButtonmap(int fd, char* mapstr)
+{
+       __u8 cnt=0;
+       __u16 map[KEY_MAX - BTN_MISC + 1] = {-1};
+
+       printf("foo: %d\n", 1<<8);
+
+       if (ioctl(fd, JSIOCGBUTTONS, &cnt) )
+       {
+               perror(PACKAGE_STRING ": error getting number of buttons");
+               exit(EXIT_IOCTL);
+       }
+       printf("Setting %d buttons.\n", cnt);
+
+
+       char* s = mapstr;
+       for(unsigned i=0; i<cnt; ++i)
+       {
+               if( !s )
+               {
+                       fprintf(stderr, "Missing value for axis %d.\n", i);
+                       exit(EXIT_VALUE);
+               }
+
+               int val=-1;
+               sscanf(s, "%d", &val);
+               if( val<0 || val>=(1<<16) )
+               {
+                       fprintf(stderr, "Value out of bounds: %d\n", val);
+                       exit(EXIT_VALUE);
+               }
+               map[i] = val;
+
+               s = strstr(s, ",");
+               if(s)
+                       s++;
+       }
+
+       if( s )
+               fprintf(stderr, "Too many values given for the axismap. Ignoring the rest.\n");
+
+
+       printf("Setting the following map:\n"); 
+       for(int i=0; i<cnt; i++)
+               printf("  %d => %d\n", i, map[i] );
+
+
+       if( ioctl(fd, JSIOCSBTNMAP, &map) )
+       {
+               perror( PACKAGE_STRING ": error setting button map");
+               exit(EXIT_IOCTL);
+       }
+}
+
+
+int main(int argc, char** argv)
+{
+       int argListAxismap=0;
+       int argListButtonmap=0;
+       char* argSetAxismap=0;
+       char* argSetButtonmap=0;
+       char dev[MAXFN+1] = "";
+
+
+
+       for(int i=1; i<argc; ++i)
+       {
+               const char* opt = argv[i];
+
+               if( !strcmp(opt,"--help") || !strcmp(opt,"-h") )
+               {
+                       printHelp(stdout, argc, argv);
+                       return EXIT_SUCCESS;
+               }
+               else if( !strcmp(opt, "--dev") || !strcmp(opt,"-d") )
+               {
+                       i++;
+                       if( i >= argc )                 
+                               reportMissingArgument(opt);
+                       strncpy(dev, argv[i], MAXFN);
+               }
+               else if( !strcmp(opt, "--list-axismap") )
+               {
+                       argListAxismap = 1;
+               }
+               else if( !strcmp(opt, "--list-buttonmap") )
+               {
+                       argListButtonmap = 1;
+               }
+               else if( !strcmp(opt, "--set-axismap") )
+               {
+                       i++;
+                       if( i >= argc )                 
+                               reportMissingArgument(opt);
+                       argSetAxismap = argv[i];
+               }
+               else if( !strcmp(opt, "--set-buttonmap") )
+               {       
+                       i++;
+                       if( i >= argc )                 
+                               reportMissingArgument(opt);
+                       argSetButtonmap = argv[i];
+               }
+               else
+               {
+                       fprintf(stderr, "Invalid option '%s'.\n", opt);
+                       return EXIT_INVARG;
+               }
+       }
+
+
+       if( strcmp("", dev)==0 )
+       {
+               fprintf(stderr, "You need to specify a device.\n");
+               return EXIT_INVARG;
+       }
+
+
+       int fd=-1;
+       if( (fd = open(dev, O_RDONLY)) < 0 )
+       {
+               perror("Cannot open device.");
+               return EXIT_OPEN;
+       }
+
+
+       int version;
+       if( ioctl(fd, JSIOCGVERSION, &version) )
+       {
+               perror( PACKAGE_STRING ": error getting version");
+               exit(EXIT_IOCTL);
+       }
+
+       if( version != JS_VERSION )
+       {
+               fprintf(stderr, PACKAGE_STRING ": compiled with different version %d\n", JS_VERSION);
+               exit(EXIT_VERSION);
+       }
+
+
+       if( argListAxismap )
+               listAxismap(fd);
+
+       if( argListButtonmap )
+               listButtonmap(fd);
+
+       if( argSetAxismap )
+               setAxismap(fd, argSetAxismap);
+
+       if( argSetButtonmap )
+               setButtonmap(fd, argSetButtonmap);
+
+
+       close(fd);
+       return 0;
+}