diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 30 | ||||
-rw-r--r-- | common.h | 17 | ||||
-rw-r--r-- | config.mk | 1 | ||||
-rw-r--r-- | libgamepad.h | 87 | ||||
-rw-r--r-- | libgamepad_absolute_axis_names__.c | 7 | ||||
-rw-r--r-- | libgamepad_button_names__.c | 7 | ||||
-rw-r--r-- | libgamepad_construct_force_feedback_effect__.c | 2 | ||||
-rw-r--r-- | libgamepad_get_absolute_axis_by_name.c | 29 | ||||
-rw-r--r-- | libgamepad_get_absolute_axis_info.c | 6 | ||||
-rw-r--r-- | libgamepad_get_absolute_axis_name.c | 10 | ||||
-rw-r--r-- | libgamepad_get_button_by_name.c | 50 | ||||
-rw-r--r-- | libgamepad_get_button_is_pressed.c | 6 | ||||
-rw-r--r-- | libgamepad_get_button_name.c | 10 | ||||
-rw-r--r-- | libgamepad_get_relative_axis_by_name.c | 29 | ||||
-rw-r--r-- | libgamepad_get_relative_axis_name.c | 10 | ||||
-rw-r--r-- | libgamepad_relative_axis_names__.c | 7 | ||||
-rwxr-xr-x | names.sh | 53 | ||||
-rw-r--r-- | test-details.c | 8 | ||||
-rw-r--r-- | test-input.c | 6 | ||||
-rw-r--r-- | test-visual.c | 6 |
21 files changed, 331 insertions, 52 deletions
@@ -12,5 +12,7 @@ *.gcov *.gcno *.gcda +*.names +*.count /test-* !/test-*.c @@ -17,6 +17,8 @@ LIB_NAME = gamepad OBJ =\ + libgamepad_absolute_axis_names__.o\ + libgamepad_button_names__.o\ libgamepad_close_device.o\ libgamepad_close_superdevice.o\ libgamepad_construct_constant_force_feedback_effect.o\ @@ -32,12 +34,15 @@ OBJ =\ libgamepad_destroy_attachment_monitor.o\ libgamepad_disable_force_feedback_autocenter.o\ libgamepad_find_sound_devices.o\ + libgamepad_get_absolute_axis_by_name.o\ libgamepad_get_absolute_axis_info.o\ libgamepad_get_absolute_axis_name.o\ libgamepad_get_attachment_event.o\ + libgamepad_get_button_by_name.o\ libgamepad_get_button_is_pressed.o\ libgamepad_get_button_name.o\ libgamepad_get_force_feedback_max_concurrency.o\ + libgamepad_get_relative_axis_by_name.o\ libgamepad_get_relative_axis_name.o\ libgamepad_grab.o\ libgamepad_install_force_feedback_effect.o\ @@ -47,6 +52,7 @@ OBJ =\ libgamepad_open_device.o\ libgamepad_open_superdevice.o\ libgamepad_play_force_feedback_effect.o\ + libgamepad_relative_axis_names__.o\ libgamepad_set_clock.o\ libgamepad_set_force_feedback_autocenter.o\ libgamepad_set_force_feedback_master_gain.o\ @@ -57,7 +63,10 @@ OBJ =\ HDR =\ common.h\ - libgamepad.h + libgamepad.h\ + button.count\ + absolute-axis.count\ + relative-axis.count TESTS =\ test-attachments\ @@ -74,6 +83,21 @@ $(OBJ): $(HDR) $(LOBJ): $(HDR) $(TESTS:=.o): $(HDR) $(TESTS): libgamepad.a +libgamepad_button_names__.o: button.names +libgamepad_absolute_axis_names__.o: absolute-axis.names +libgamepad_relative_axis_names__.o: relative-axis.names + +button.names: names.sh + printf '%s\n' '#include <linux/input.h>' | $(CPP) -dM | ./names.sh BTN KEY > $@ + +absolute-axis.names: names.sh + printf '%s\n' '#include <linux/input.h>' | $(CPP) -dM | ./names.sh ABS > $@ + +relative-axis.names: names.sh + printf '%s\n' '#include <linux/input.h>' | $(CPP) -dM | ./names.sh REL > $@ + +.names.count: + wc -l < $< > $@ .c.o: $(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) $(LIBS_CFLAGS) @@ -110,10 +134,10 @@ uninstall: -rm -f -- "$(DESTDIR)$(PREFIX)/include/libgamepad.h" clean: - -rm -f -- *.o *.a *.lo *.su *.so *.so.* *.dll *.dylib + -rm -f -- *.o *.a *.lo *.su *.so *.so.* *.dll *.dylib *.names *.count -rm -f -- *.gch *.gcov *.gcno *.gcda *.$(LIBEXT) $(TESTS) .SUFFIXES: -.SUFFIXES: .lo .o .c +.SUFFIXES: .lo .o .c .names .count .PHONY: all install uninstall clean @@ -13,6 +13,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <strings.h> #include <time.h> #include <unistd.h> @@ -20,7 +21,23 @@ #include <libudev.h> +#define ELEMSOF(A) (sizeof(A) / sizeof(*(A))) + + struct libgamepad_attachment_monitor { struct udev *udev; struct udev_monitor *monitor; }; + + +extern const char *libgamepad_button_names__[ +#include "button.count" +]; + +extern const char *libgamepad_absolute_axis_names__[ +#include "absolute-axis.count" +]; + +extern const char *libgamepad_relative_axis_names__[ +#include "relative-axis.count" +]; @@ -2,6 +2,7 @@ PREFIX = /usr MANPREFIX = $(PREFIX)/share/man CC = c99 +CPP = cpp CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE CFLAGS = -Wall -g diff --git a/libgamepad.h b/libgamepad.h index a6002fe..d039082 100644 --- a/libgamepad.h +++ b/libgamepad.h @@ -1503,65 +1503,86 @@ int libgamepad_next_event(struct libgamepad_device *, struct libgamepad_input_ev /** * Get the name of a button/key * - * @param code The button/key - * @return The button/key's name + * @param device If `NULL`, a generic name will be returned, + * otherwise the canonical name for the button/key + * on the specific device will be returned + * (`NULL` if not information is unavailable) + * @param code The button/key + * @return The button/key's name, `NULL` if not found */ -inline const char * -libgamepad_get_button_name(uint16_t code) -{ - return libevdev_event_code_get_name(EV_KEY, (unsigned int)code); -} +const char *libgamepad_get_button_name(const struct libgamepad_device *, uint16_t); /** * Get the name of an absolute axis * - * @param code The axis - * @return The axis' name + * @param device If `NULL`, a generic name will be returned, + * otherwise the canonical name for the axis + * on the specific device will be returned + * (`NULL` if not information is unavailable) + * @param code The axis + * @return The axis' name, `NULL` if not found */ -inline const char * -libgamepad_get_absolute_axis_name(uint16_t code) -{ - return libevdev_event_code_get_name(EV_ABS, (unsigned int)code); -} +const char *libgamepad_get_absolute_axis_name(const struct libgamepad_device *, uint16_t); /** * Get the name of a relative axis * - * @param code The axis - * @return The axis' name + * @param device If `NULL`, a generic name will be returned, + * otherwise the canonical name for the axis + * on the specific device will be returned + * (`NULL` if not information is unavailable) + * @param code The axis + * @return The axis' name, `NULL` if not found */ -inline const char * -libgamepad_get_relative_axis_name(uint16_t code) -{ - return libevdev_event_code_get_name(EV_REL, (unsigned int)code); -} +const char *libgamepad_get_relative_axis_name(const struct libgamepad_device *, uint16_t); + +/** + * Get a button/key code from it's name + * + * @param name The button/key's name or textual + * representation of its code number + * @return The button/key, -1 if not found + */ +int16_t libgamepad_get_button_by_name(const char *); + +/** + * Get a absolute axis code from it's name + * + * @param name The absolute axis' name or textual + * representation of its code number + * @return The absolute axis, -1 if not found + */ +int16_t libgamepad_get_absolute_axis_by_name(const char *); + +/** + * Get a relative axis code from it's name + * + * @param name The relative axis' name or textual + * representation of its code number + * @return The relative axis, -1 if not found + */ +int16_t libgamepad_get_relative_axis_by_name(const char *); + /** * Get whether a button/key is pressed down or not - * + * * @param device The device to retrieve the information for * @param code The button/key * @return 1 if the button/key is pressed down, * 0 otherwise */ -inline int -libgamepad_get_button_is_pressed(struct libgamepad_device *device, uint16_t code) -{ - return libevdev_get_event_value(device->dev, EV_KEY, (unsigned int)code); -} +int libgamepad_get_button_is_pressed(struct libgamepad_device *, uint16_t); /** * Get information about an absolute axis - * + * * @param device The device to retrieve the information for * @param code The axis * @return Information about the axis */ -inline const struct input_absinfo * /* `struct input_absinfo` is defined in <linux/input.h> */ -libgamepad_get_absolute_axis_info(struct libgamepad_device *device, uint16_t code) -{ - return libevdev_get_abs_info(device->dev, (unsigned int)code); -} +const struct input_absinfo *libgamepad_get_absolute_axis_info(struct libgamepad_device *, uint16_t); +/* `struct input_absinfo` is defined in <linux/input.h> */ /** diff --git a/libgamepad_absolute_axis_names__.c b/libgamepad_absolute_axis_names__.c new file mode 100644 index 0000000..f5068b0 --- /dev/null +++ b/libgamepad_absolute_axis_names__.c @@ -0,0 +1,7 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +const char *libgamepad_absolute_axis_names__[] = { +#include "absolute-axis.names" +}; diff --git a/libgamepad_button_names__.c b/libgamepad_button_names__.c new file mode 100644 index 0000000..9efe622 --- /dev/null +++ b/libgamepad_button_names__.c @@ -0,0 +1,7 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +const char *libgamepad_button_names__[] = { +#include "button.names" +}; diff --git a/libgamepad_construct_force_feedback_effect__.c b/libgamepad_construct_force_feedback_effect__.c index f84314d..5c99a13 100644 --- a/libgamepad_construct_force_feedback_effect__.c +++ b/libgamepad_construct_force_feedback_effect__.c @@ -13,7 +13,7 @@ libgamepad_construct_force_feedback_effect__(struct ff_effect *effectp, const st memset(effectp, 0, sizeof(*effectp)); effectp->id = -1; } - direction += 0.5; + direction += (double)1 / 2; fmod(direction, 1); if (direction < 0) direction = 1 - direction; diff --git a/libgamepad_get_absolute_axis_by_name.c b/libgamepad_get_absolute_axis_by_name.c new file mode 100644 index 0000000..4d5aaa4 --- /dev/null +++ b/libgamepad_get_absolute_axis_by_name.c @@ -0,0 +1,29 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +int16_t +libgamepad_get_absolute_axis_by_name(const char *name) +{ + size_t code; + int saved_errno; + char *end; + if (!name || !*name) + return -1; + if (isdigit(*name)) { + saved_errno = errno; + errno = 0; + code = (size_t)strtoul(name, &end, 0); + if (errno || *end || code > (size_t)ABS_MAX) { + errno = saved_errno; + return -1; + } + errno = saved_errno; + return (int16_t)code; + } else { + for (code = 0; code < ELEMSOF(libgamepad_absolute_axis_names__); code++) + if (!strcasecmp(name, libgamepad_absolute_axis_names__[code])) + return (int16_t)code; + return -1; + } +} diff --git a/libgamepad_get_absolute_axis_info.c b/libgamepad_get_absolute_axis_info.c index a6f8220..307d85a 100644 --- a/libgamepad_get_absolute_axis_info.c +++ b/libgamepad_get_absolute_axis_info.c @@ -2,4 +2,8 @@ #include "common.h" -extern inline const struct input_absinfo *libgamepad_get_absolute_axis_info(struct libgamepad_device *, uint16_t); +const struct input_absinfo * +libgamepad_get_absolute_axis_info(struct libgamepad_device *device, uint16_t code) +{ + return libevdev_get_abs_info(device->dev, (unsigned int)code); +} diff --git a/libgamepad_get_absolute_axis_name.c b/libgamepad_get_absolute_axis_name.c index 2146c8a..79f216c 100644 --- a/libgamepad_get_absolute_axis_name.c +++ b/libgamepad_get_absolute_axis_name.c @@ -2,4 +2,12 @@ #include "common.h" -extern inline const char *libgamepad_get_absolute_axis_name(uint16_t); +const char * +libgamepad_get_absolute_axis_name(const struct libgamepad_device *device, uint16_t code) /* will not be pure */ +{ + if (device) + return NULL; + if ((size_t)code > ELEMSOF(libgamepad_absolute_axis_names__)) + return NULL; + return libgamepad_absolute_axis_names__[code]; +} diff --git a/libgamepad_get_button_by_name.c b/libgamepad_get_button_by_name.c new file mode 100644 index 0000000..2b37e93 --- /dev/null +++ b/libgamepad_get_button_by_name.c @@ -0,0 +1,50 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +#define LIST_ALIASES(X)\ + X(KEY_HANGUEL)\ + X(KEY_SCREENLOCK)\ + X(KEY_DIRECTION)\ + X(KEY_DASHBOARD)\ + X(KEY_BRIGHTNESS_ZERO)\ + X(KEY_WIMAX)\ + X(BTN_A)\ + X(BTN_B)\ + X(BTN_X)\ + X(BTN_Y)\ + X(KEY_ZOOM)\ + X(KEY_SCREEN)\ + X(KEY_BRIGHTNESS_TOGGLE) + + +int16_t +libgamepad_get_button_by_name(const char *name) +{ + size_t code; + int saved_errno; + char *end; + if (!name || !*name) + return -1; + if (isdigit(*name)) { + saved_errno = errno; + errno = 0; + code = (size_t)strtoul(name, &end, 0); + if (errno || *end || code > (size_t)KEY_MAX) { + errno = saved_errno; + return -1; + } + errno = saved_errno; + return (int16_t)code; + } else { + for (code = 0; code < ELEMSOF(libgamepad_button_names__); code++) + if (!strcasecmp(name, libgamepad_button_names__[code])) + return (int16_t)code; +#define X(NAME)\ + if (!strcasecmp(name, #NAME))\ + return (int16_t)NAME; + LIST_ALIASES(X) +#undef X + return -1; + } +} diff --git a/libgamepad_get_button_is_pressed.c b/libgamepad_get_button_is_pressed.c index 7ec2f73..2e61297 100644 --- a/libgamepad_get_button_is_pressed.c +++ b/libgamepad_get_button_is_pressed.c @@ -2,4 +2,8 @@ #include "common.h" -extern inline int libgamepad_get_button_is_pressed(struct libgamepad_device *, uint16_t); +int +libgamepad_get_button_is_pressed(struct libgamepad_device *device, uint16_t code) +{ + return libevdev_get_event_value(device->dev, EV_KEY, (unsigned int)code); +} diff --git a/libgamepad_get_button_name.c b/libgamepad_get_button_name.c index 8e7a07f..031e528 100644 --- a/libgamepad_get_button_name.c +++ b/libgamepad_get_button_name.c @@ -2,4 +2,12 @@ #include "common.h" -extern inline const char *libgamepad_get_button_name(uint16_t); +const char * +libgamepad_get_button_name(const struct libgamepad_device *device, uint16_t code) /* will not be pure */ +{ + if (device) + return NULL; + if ((size_t)code > ELEMSOF(libgamepad_button_names__)) + return NULL; + return libgamepad_button_names__[code]; +} diff --git a/libgamepad_get_relative_axis_by_name.c b/libgamepad_get_relative_axis_by_name.c new file mode 100644 index 0000000..f7f2a72 --- /dev/null +++ b/libgamepad_get_relative_axis_by_name.c @@ -0,0 +1,29 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +int16_t +libgamepad_get_relative_axis_by_name(const char *name) +{ + size_t code; + int saved_errno; + char *end; + if (!name || !*name) + return -1; + if (isdigit(*name)) { + saved_errno = errno; + errno = 0; + code = (size_t)strtoul(name, &end, 0); + if (errno || *end || code > (size_t)REL_MAX) { + errno = saved_errno; + return -1; + } + errno = saved_errno; + return (int16_t)code; + } else { + for (code = 0; code < ELEMSOF(libgamepad_relative_axis_names__); code++) + if (!strcasecmp(name, libgamepad_relative_axis_names__[code])) + return (int16_t)code; + return -1; + } +} diff --git a/libgamepad_get_relative_axis_name.c b/libgamepad_get_relative_axis_name.c index f3e4a46..5a16945 100644 --- a/libgamepad_get_relative_axis_name.c +++ b/libgamepad_get_relative_axis_name.c @@ -2,4 +2,12 @@ #include "common.h" -extern inline const char *libgamepad_get_relative_axis_name(uint16_t); +const char * +libgamepad_get_relative_axis_name(const struct libgamepad_device *device, uint16_t code) /* will not be pure */ +{ + if (device) + return NULL; + if ((size_t)code > ELEMSOF(libgamepad_relative_axis_names__)) + return NULL; + return libgamepad_relative_axis_names__[code]; +} diff --git a/libgamepad_relative_axis_names__.c b/libgamepad_relative_axis_names__.c new file mode 100644 index 0000000..2a9ceec --- /dev/null +++ b/libgamepad_relative_axis_names__.c @@ -0,0 +1,7 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +const char *libgamepad_relative_axis_names__[] = { +#include "relative-axis.names" +}; diff --git a/names.sh b/names.sh new file mode 100755 index 0000000..40ed998 --- /dev/null +++ b/names.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +prefix="$(printf '%s\\|' "$@" | sed 's/..$//')" + +definitions_with_max="$(sed -n 's/^\s*#\s*define\s\+\(\('"$prefix"'\)_[A-Za-z0-9_]*\)\s\+\(0[xX][0-9A-Fa-f]\+\|[0-9]\+\)\(.*\)$/\3 \1/p')" + +definitions="$(echo "$definitions_with_max" | sed '/ \('"$prefix"'\)_MAX$/d')" +max=$(printf '%u\n' $(echo "$definitions_with_max" | sed -n 's/^\(.*\) \('"$prefix"'\)_MAX$/\1/p')) + +nonunique="$(echo "$definitions" | while read num name; do printf '0x%03X\n' $num; done | sort | uniq -d)" + +(echo "$definitions" | + while read line; do + printf '0x%03X %s\n' $line + done | + sed '/^\('"$(echo "$nonunique" | tr '\n' '|' | sed 's/|$/\n/' | sed 's/|/\\|/g')"'\) /d' + + last_num=x + last_name=x + while read num name; do + num=$(printf '0x%03X\n' $num) + if ! test $last_num = $num && ! test $last_num = x; then + printf '%s %s\n' $last_num $last_name + fi + last_num=$num + last_name=$name + done + if ! test $last_num = x; then + printf '%s %s\n' $last_num $last_name + fi +) | +sort | +while read num name; do + printf '%s %u\n' $name $num; +done | +uniq -f 1 | +awk ' +BEGIN {num = 0} +{ + while ($2 != num) { + printf "\"0x%03X\",\n", num + num += 1 + } + printf "\"%s\",\n", $1 + num += 1 +} +END { + while (num <= '"$max"') { + printf "\"0x%03X\",\n", num + num += 1 + } +}' | +sed '$s/,$//' diff --git a/test-details.c b/test-details.c index 420e007..e834819 100644 --- a/test-details.c +++ b/test-details.c @@ -38,7 +38,7 @@ main(int argc, char *argv[]) assert(gamepad.buttons[i] < ELEMSOF(gamepad.button_map)); assert(gamepad.button_map[gamepad.buttons[i]] == (int16_t)i); printf("\t%s [pressed=%i]\n", - libgamepad_get_button_name(gamepad.buttons[i]), + libgamepad_get_button_name(NULL, gamepad.buttons[i]), libgamepad_get_button_is_pressed(&gamepad, gamepad.buttons[i])); } n = 0; @@ -59,10 +59,10 @@ main(int argc, char *argv[]) assert(gamepad.absolute_axis_map[gamepad.absolute_axes[i]] == (int16_t)i); absinfo = libgamepad_get_absolute_axis_info(&gamepad, gamepad.absolute_axes[i]); if (!absinfo) { - printf("\t%s\n", libgamepad_get_absolute_axis_name(gamepad.absolute_axes[i])); + printf("\t%s\n", libgamepad_get_absolute_axis_name(NULL, gamepad.absolute_axes[i])); } else { printf("\t%s [value=%i, min=%i, max=%i, fuzz=%i, flat=%i, resolution=%i]\n", - libgamepad_get_absolute_axis_name(gamepad.absolute_axes[i]), + libgamepad_get_absolute_axis_name(NULL, gamepad.absolute_axes[i]), absinfo->value, absinfo->minimum, absinfo->maximum, absinfo->fuzz, absinfo->flat, absinfo->resolution); } @@ -83,7 +83,7 @@ main(int argc, char *argv[]) assert(gamepad.relative_axes); assert(gamepad.relative_axes[i] < ELEMSOF(gamepad.relative_axis_map)); assert(gamepad.relative_axis_map[gamepad.relative_axes[i]] == (int16_t)i); - printf("\t%s\n", libgamepad_get_relative_axis_name(gamepad.relative_axes[i])); + printf("\t%s\n", libgamepad_get_relative_axis_name(NULL, gamepad.relative_axes[i])); } n = 0; for (i = 0; i < ELEMSOF(gamepad.relative_axis_map); i++) { diff --git a/test-input.c b/test-input.c index 1fd5c4c..d74e684 100644 --- a/test-input.c +++ b/test-input.c @@ -65,12 +65,12 @@ main(int argc, char *argv[]) if (event.sync_event) printf("[sync] "); if (event.type == LIBGAMEPAD_BUTTON) { - printf("%s ", libgamepad_get_button_name(event.code)); + printf("%s ", libgamepad_get_button_name(NULL, event.code)); } else if (event.type == LIBGAMEPAD_ABSOLUTE_AXIS) { - printf("%s ", libgamepad_get_absolute_axis_name(event.code)); + printf("%s ", libgamepad_get_absolute_axis_name(NULL, event.code)); } else { assert(event.type == LIBGAMEPAD_RELATIVE_AXIS); - printf("%s ", libgamepad_get_relative_axis_name(event.code)); + printf("%s ", libgamepad_get_relative_axis_name(NULL, event.code)); } printf("%lli\n", (long long int)event.value); } diff --git a/test-visual.c b/test-visual.c index 316299c..9743006 100644 --- a/test-visual.c +++ b/test-visual.c @@ -90,7 +90,7 @@ main(int argc, char *argv[]) return 1; } for (i = 0; i < gamepad.nbuttons; i++) { - button_names[i] = libgamepad_get_button_name(gamepad.buttons[i]); + button_names[i] = libgamepad_get_button_name(NULL, gamepad.buttons[i]); len = strlen(button_names[i]); max_button_name_len = max_button_name_len > len ? max_button_name_len : len; } @@ -106,7 +106,7 @@ main(int argc, char *argv[]) return 1; } for (i = 0; i < gamepad.nabsolute_axes; i++) { - len = strlen(libgamepad_get_absolute_axis_name(gamepad.absolute_axes[i])); + len = strlen(libgamepad_get_absolute_axis_name(NULL, gamepad.absolute_axes[i])); max_abs_axis_name_len = max_abs_axis_name_len > len ? max_abs_axis_name_len : len; absinfo = libgamepad_get_absolute_axis_info(&gamepad, gamepad.absolute_axes[i]); assert(absinfo); @@ -144,7 +144,7 @@ main(int argc, char *argv[]) printf("\033[%zuH", button_rows + 1); for (i = 0; i < gamepad.nabsolute_axes; i++) { printf("\n%-*s ¿\033[7m%s?", (int)max_abs_axis_name_len, - libgamepad_get_absolute_axis_name(gamepad.absolute_axes[i]), + libgamepad_get_absolute_axis_name(NULL, gamepad.absolute_axes[i]), draw_axis(buffer, &abs_axes[i], axis_len)); } |