summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaud Patard <rtp@mageia.org>2011-03-18 21:28:23 +0000
committerArnaud Patard <rtp@mageia.org>2011-03-18 21:28:23 +0000
commiteea2f8ef9ddf7e461702d8fda0b8e98e623694c2 (patch)
treec2730cd4433035feeddb3c00a6cfd5cf9e282c93
parent071f701fb4148c83c8c9c0f121150468fa5a064b (diff)
downloaddrakx-eea2f8ef9ddf7e461702d8fda0b8e98e623694c2.tar
drakx-eea2f8ef9ddf7e461702d8fda0b8e98e623694c2.tar.gz
drakx-eea2f8ef9ddf7e461702d8fda0b8e98e623694c2.tar.bz2
drakx-eea2f8ef9ddf7e461702d8fda0b8e98e623694c2.tar.xz
drakx-eea2f8ef9ddf7e461702d8fda0b8e98e623694c2.zip
- use EVIOCGBIT ioctl instead of trying to parse key field from
/proc/bus/input/devices to avoid issues on 64bit kernel with 32bit userspace
-rwxr-xr-xperl-install/c/stuff.xs.pl34
-rw-r--r--perl-install/detect_devices.pm9
2 files changed, 41 insertions, 2 deletions
diff --git a/perl-install/c/stuff.xs.pl b/perl-install/c/stuff.xs.pl
index cd2c6bf03..b2c4c2512 100755
--- a/perl-install/c/stuff.xs.pl
+++ b/perl-install/c/stuff.xs.pl
@@ -36,6 +36,7 @@ print '
#include <net/route.h>
#include <netinet/in.h>
#include <linux/sockios.h>
+#include <linux/input.h>
// for ethtool structs:
typedef unsigned long long u64;
@@ -485,7 +486,40 @@ strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
}
}
+#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)
+void
+EVIocGBitKey (char *file)
+ PPCODE:
+ int fd;
+ int i;
+ long bitmask[NBITS(KEY_MAX)];
+
+ fd = open (file, O_RDONLY);
+ if (fd < 0) {
+ perror("Cannot open /dev/input/eventX");
+ return;
+ }
+
+ if (ioctl (fd, EVIOCGBIT(EV_KEY, sizeof (bitmask)), bitmask) < 0) {
+ perror ("ioctl EVIOCGBIT failed");
+ close (fd);
+ return;
+ }
+
+ for (i = NBITS(KEY_MAX) - 1; i > 0; i--)
+ if (bitmask[i])
+ break;
+
+ for (; i >= 0; i--) {
+ EXTEND(sp, 1);
+ PUSHs(sv_2mortal(newSViv(bitmask[i])));
+ }
char *
kernel_version()
diff --git a/perl-install/detect_devices.pm b/perl-install/detect_devices.pm
index 89698fd99..40a1b8236 100644
--- a/perl-install/detect_devices.pm
+++ b/perl-install/detect_devices.pm
@@ -456,6 +456,7 @@ sub getTVcards() { probe_category('multimedia/tv') }
sub getInputDevices() {
my (@devices, $device);
+ my $event;
foreach (cat_('/proc/bus/input/devices')) {
if (/^I:/) {
$device = {};
@@ -515,6 +516,7 @@ sub getInputDevices() {
my @l = split(' ', $1);
$device->{driver} = $l[0]; #- keep it for compatibility
$device->{Handlers} = +{ map { (/^(.*?)\d*$/ ? $1 : $_, $_) } split(' ', $1) };
+ $event = $device->{Handlers}{event};
} elsif (/S: Sysfs=(.+)/) {
$device->{sysfs_path} = $1;
} elsif (/P: Phys=(.*)/) {
@@ -537,8 +539,11 @@ sub getInputDevices() {
#- KEY=30000 0 0 0 0 0 0 0 0 #=> BTN_LEFT BTN_RIGHT
#- KEY=70000 0 0 0 0 0 0 0 0 #=> BTN_LEFT BTN_RIGHT BTN_MIDDLE
#- KEY=1f0000 0 0 0 0 0 0 0 0 #=> BTN_LEFT BTN_RIGHT BTN_MIDDLE BTN_SIDE BTN_EXTRA
- my $KEY = hex($1);
- $device->{SIDE} = 1 if $KEY & (1 << 0x13);
+ if (! -f "/dev/input/$event") {
+ devices::make("/dev/input/$event");
+ }
+ my @KEYS = c::EVIocGBitKey("/dev/input/$event");
+ $device->{SIDE} = 1 if $KEYS[0] & (1 << 0x13);
} elsif (/^\s*$/) {
push @devices, $device if $device;