#include <fcntl.h>
#include <sstream>
+static bool
+bit_set(unsigned int bit, const uint8_t * field)
+{
+ return ((field[bit / 8] & (1 << (bit % 8))) != 0);
+}
+
namespace FreeDV {
// Remove extra spaces from string, in place.
char *
struct EvDev::device_enumeration *
EvDev::enumerate(std::size_t & count)
{
- struct device_enumeration devices[100];
+ struct device_enumeration devices[64];
count = 0;
device.name = strdup(str.str().c_str());
- if ( test_bit(EV_KEY, device.event_types) == 0
+ if ( bit_set(EV_KEY, device.event_types) == 0
|| ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(device.buttons)), device.buttons)
< 0 )
memset(device.buttons, 0, sizeof(device.buttons));
return true;
}
- char * *
- 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++;
- }
-
- char * * names = new char * [length + 1];
-
- std::size_t j = 0;
- for ( std::size_t i = 0; i < count; i++ ) {
- if ( test_bit(EV_KEY, devices[i].event_types) )
- names[j++] = devices[i].name;
- devices[i].name = 0;
- }
- names[j] = 0;
-
- delete_enumeration(devices, count);
- return names;
- }
-
EvDev::EvDev(const char *)
{
}
#include <cstdint>
#include <linux/input.h>
-#define BITS_PER_LONG (sizeof(long) * 8)
-#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
-#define OFF(x) ((x)%BITS_PER_LONG)
-#define BIT(x) (1UL<<OFF(x))
-#define LONG(x) ((x)/BITS_PER_LONG)
-#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
-
namespace FreeDV {
class EvDev {
- protected:
+ public:
struct device_enumeration {
char * special_file;
char * name;
int fd,
struct device_enumeration & device);
- protected:
+ public:
static void delete_enumeration(
device_enumeration * data,
std::size_t count);
static device_enumeration *
enumerate(std::size_t & count);
- public:
- static char * * EnumerateButtonDevices();
-
EvDev(const char * name);
~EvDev();
};
#include <iostream>
#include <stdexcept>
+static bool
+bit_set(unsigned int bit, const uint8_t * field)
+{
+ return ((field[bit / 8] & (1 << (bit % 8))) != 0);
+}
+
namespace FreeDV {
/// PTT driver using Linux evdev.
///
static std::ostream &
PTT_EvDevEnumerator(std::ostream & stream)
{
- char * * devices = EvDev::EnumerateButtonDevices();
-
- char * * d = devices;
-
- while ( *d != 0 )
- stream << "\"evdev:" << *d++ << '\"' << std::endl;
-
- d = devices;
-
- while ( *d != 0 )
- delete *d++;
-
- delete devices;
-
+ std::size_t count = 0;
+ EvDev::device_enumeration * const devices = EvDev::enumerate(count);
+
+ for ( std::size_t i = 0; i < count; i++ ) {
+ if ( bit_set(EV_KEY, devices[i].event_types) ) {
+ int low = -1;
+ int high = -1;
+
+ for ( int j = KEY_F1; j <= KEY_MAX; j++ ) {
+ if ( bit_set(j, devices[i].buttons) ) {
+ low = j;
+ break;
+ }
+ }
+ for ( int j = KEY_MAX; j >= KEY_F1; j-- ) {
+ if ( bit_set(j, devices[i].buttons) ) {
+ high = j;
+ break;
+ }
+ }
+ if ( low >= 0 ) {
+ stream << '\"' << devices[i].name << ',' << low << '\"';
+
+ if ( high > low )
+ stream << " (" << low << '-' << high << ')';
+
+ stream << std::endl;
+ }
+ }
+ }
+
+ EvDev::delete_enumeration(devices, count);
return stream;
}