From 156c8d22dd8f1c9209ddada487f41a4bbbf26bc0 Mon Sep 17 00:00:00 2001 From: bruceperens Date: Fri, 18 Apr 2014 04:14:12 +0000 Subject: [PATCH] Complete enumeration of evdev. git-svn-id: https://svn.code.sf.net/p/freetel/code@1500 01035d8c-6547-0410-b346-abe4f91aad63 --- freedv-server/source/platform/linux/evdev.cpp | 115 +++++++++++++++++- freedv-server/source/platform/linux/evdev.h | 24 ++-- 2 files changed, 129 insertions(+), 10 deletions(-) diff --git a/freedv-server/source/platform/linux/evdev.cpp b/freedv-server/source/platform/linux/evdev.cpp index d23bb5dd..073436ef 100644 --- a/freedv-server/source/platform/linux/evdev.cpp +++ b/freedv-server/source/platform/linux/evdev.cpp @@ -1,14 +1,123 @@ #include "evdev.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -const struct EvDev::device_enumeration * -EvDev::enumerate(std::size_t &) +// Remove extra spaces from string, in place. +char * +clean_string(char * string) { - return 0; + char * s = string; + + while ( *s != 0 ) { + if ( *s == ' ' && s[1] == ' ' ) { + s++; + char * end = s; + while ( *end == ' ' ) + end++; + memmove(s, end, strlen(end) + 1); + } + s++; + } + + const std::size_t length = strlen(string); + + if ( length > 1 && string[length - 1] == ' ' ) + string[length - 1] = '\0'; + + return string; +} + +void +EvDev::delete_enumeration( + EvDev::device_enumeration * data, + std::size_t count) +{ + for ( std::size_t i = 0; i < count; i++ ) { + delete data[i].special_file; + delete data[i].name; + } + delete data; +} + +struct EvDev::device_enumeration * +EvDev::enumerate(std::size_t & count) +{ + struct device_enumeration devices[100]; + + count = 0; + + for ( int i = 0; sizeof(devices) / sizeof(*devices); i++ ) { + std::ostringstream str; + + str << "/dev/input/event" << i; + + const char * const special_file = str.str().c_str(); + + const int fd = open(special_file, O_RDONLY); + + if ( fd >= 0 ) { + if ( enumerate_device(special_file, fd, devices[count]) ) + count++; + close(fd); + } + } + device_enumeration * const r = new device_enumeration[count]; + + memcpy(r, devices, count * sizeof(*r)); + + return r; +} + +bool +EvDev::enumerate_device( + const char * special_file, + int fd, + device_enumeration & device) +{ + char buf[100]; + std::ostringstream str; + + device.special_file = strdup(special_file); + + if ( ioctl(fd, EVIOCGNAME(sizeof(buf)), buf) < 0 + || ioctl(fd, EVIOCGBIT(0, sizeof(device.event_types)), device.event_types) + < 0 ) + return false; + + str << clean_string(buf); + + if ( ioctl(fd, EVIOCGUNIQ(sizeof(buf)), buf) >= 0 ) + str << ' ' << clean_string(buf); + + if ( ioctl(fd, EVIOCGPHYS(sizeof(buf)), buf) >= 0 ) + str << " at " << clean_string(buf); + + device.name = strdup(str.str().c_str()); + + return true; } const char * const * EvDev::EnumerateButtonDevices() { + std::size_t count = 0; + std::size_t length = 0; + device_enumeration * const devices = enumerate(count); + + for ( std::size_t i = 0; i < count; i++ ) { + if ( test_bit(EV_KEY, devices[i].event_types) ) + length++; + } + + delete_enumeration(devices, count); return 0; } diff --git a/freedv-server/source/platform/linux/evdev.h b/freedv-server/source/platform/linux/evdev.h index 3a46be93..e4491ef7 100644 --- a/freedv-server/source/platform/linux/evdev.h +++ b/freedv-server/source/platform/linux/evdev.h @@ -9,20 +9,30 @@ #define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1) class EvDev { +protected: + struct device_enumeration { + const char * special_file; + const char * name; + uint8_t event_types[(EV_MAX + 7) / 8]; + }; + private: EvDev(const EvDev &); EvDev & operator =(const EvDev &); + static bool enumerate_device( + const char * name, + int fd, + struct device_enumeration & device); + protected: - struct device_enumeration { - const char * device; - const char * name; - uint8_t event_types[(EV_MAX + 7) / 8]; - }; + static void delete_enumeration( + device_enumeration * data, + std::size_t count); - static const device_enumeration * - enumerate(std::size_t & size); + static device_enumeration * + enumerate(std::size_t & count); public: static const char * const * -- 2.25.1