From 1540eb40663a7bc58f14d26e70bdf5445d9108e1 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Nov 12 2009 04:09:48 +0000 Subject: - Add devinput mouse event passthru to uinput support from lirc cvs --- diff --git a/lirc-0.8.6-devinput-pass-mouse-events.patch b/lirc-0.8.6-devinput-pass-mouse-events.patch new file mode 100644 index 0000000..f6bcb5f --- /dev/null +++ b/lirc-0.8.6-devinput-pass-mouse-events.patch @@ -0,0 +1,262 @@ +diff -Naurp lirc-0.8.6/daemons/hw_devinput.c~ lirc-0.8.6/daemons/hw_devinput.c +--- lirc-0.8.6/daemons/hw_devinput.c~ 2009/09/07 18:08:00 5.20 ++++ lirc-0.8.6/daemons/hw_devinput.c 2009/10/31 09:37:30 5.21 +@@ -31,8 +31,10 @@ + #include + #include + #include ++#include + + #include ++#include + + #ifndef EV_SYN + /* previous name */ +@@ -44,8 +46,18 @@ + #include "lircd.h" + #include "receive.h" + ++/* from evtest.c - Copyright (c) 1999-2000 Vojtech Pavlik */ ++#define BITS_PER_LONG (sizeof(long) * CHAR_BIT) ++/* NBITS was defined in linux/uinput.h */ ++#undef NBITS ++#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) ++#define OFF(x) ((x)%BITS_PER_LONG) ++#define BIT(x) (1UL<> OFF(bit)) & 1) + + static int devinput_init(); ++static int devinput_init_fwd(); + static int devinput_deinit(void); + static int devinput_decode(struct ir_remote *remote, + ir_code *prep, ir_code *codep, ir_code *postp, +@@ -67,7 +76,7 @@ + 0, /* send_mode */ + LIRC_MODE_LIRCCODE, /* rec_mode */ + 32, /* code_length */ +- devinput_init, /* init_func */ ++ devinput_init_fwd, /* init_func */ + NULL, /* config_func */ + devinput_deinit, /* deinit_func */ + NULL, /* send_func */ +@@ -80,6 +89,141 @@ + + static ir_code code; + static int repeat_flag=0; ++static int exclusive = 0; ++static int uinputfd = -1; ++ ++static int setup_uinputfd(const char *name, int source) ++{ ++ int fd; ++ int key; ++ struct uinput_user_dev dev; ++ long events[NBITS(EV_MAX)]; ++ long bits[NBITS(KEY_MAX)]; ++ ++ if(ioctl(source, EVIOCGBIT(0, EV_MAX), events) == -1) ++ { ++ return -1; ++ } ++ if(!test_bit(EV_REL, events) && !test_bit(EV_ABS, events)) ++ { ++ /* no move events, don't forward anything */ ++ return -1; ++ } ++ fd = open("/dev/input/uinput", O_RDWR); ++ if(fd == -1) ++ { ++ fd = open("/dev/uinput", O_RDWR); ++ if(fd == -1) ++ { ++ fd = open("/dev/misc/uinput", O_RDWR); ++ if(fd == -1) ++ { ++ logprintf(LOG_WARNING, "could not open %s\n", ++ "uinput"); ++ logperror(LOG_WARNING, NULL); ++ return -1; ++ } ++ } ++ } ++ memset(&dev, 0, sizeof(dev)); ++ if(ioctl(source, EVIOCGNAME(sizeof(dev.name)), dev.name) >= 0) ++ { ++ dev.name[sizeof(dev.name)-1] = 0; ++ if(strlen(dev.name) > 0) ++ { ++ strncat(dev.name, " ", sizeof(dev.name) - ++ strlen(dev.name)); ++ dev.name[sizeof(dev.name)-1] = 0; ++ } ++ } ++ strncat(dev.name, name, sizeof(dev.name) - strlen(dev.name)); ++ dev.name[sizeof(dev.name)-1] = 0; ++ ++ if(write(fd, &dev, sizeof(dev)) != sizeof(dev)) ++ { ++ goto setup_error; ++ } ++ ++ if(test_bit(EV_KEY, events)) ++ { ++ if(ioctl(source, EVIOCGBIT(EV_KEY, KEY_MAX), bits) == -1) ++ { ++ goto setup_error; ++ } ++ ++ if(ioctl(fd, UI_SET_EVBIT, EV_KEY) == -1) ++ { ++ goto setup_error; ++ } ++ ++ /* only forward mouse button events */ ++ for(key = BTN_MISC; key <= BTN_GEAR_UP; key++) ++ { ++ if(test_bit(key, bits)) ++ { ++ if(ioctl(fd, UI_SET_KEYBIT, key) == -1) ++ { ++ goto setup_error; ++ } ++ } ++ } ++ } ++ if(test_bit(EV_REL, events)) ++ { ++ if(ioctl(source, EVIOCGBIT(EV_REL, REL_MAX), bits) == -1) ++ { ++ goto setup_error; ++ } ++ if(ioctl(fd, UI_SET_EVBIT, EV_REL) == -1) ++ { ++ goto setup_error; ++ } ++ for(key = 0; key <= REL_MAX; key++) ++ { ++ if(test_bit(key, bits)) ++ { ++ if(ioctl(fd, UI_SET_RELBIT, key) == -1) ++ { ++ goto setup_error; ++ } ++ } ++ } ++ } ++ if(test_bit(EV_ABS, events)) ++ { ++ if(ioctl(source, EVIOCGBIT(EV_ABS, ABS_MAX), bits) == -1) ++ { ++ goto setup_error; ++ } ++ if(ioctl(fd, UI_SET_EVBIT, EV_ABS) == -1) ++ { ++ goto setup_error; ++ } ++ for(key = 0; key <= ABS_MAX; key++) ++ { ++ if(test_bit(key, bits)) ++ { ++ if(ioctl(fd, UI_SET_ABSBIT, key) == -1) ++ { ++ goto setup_error; ++ } ++ } ++ } ++ } ++ ++ ++ if(ioctl(fd, UI_DEV_CREATE) == -1) ++ { ++ goto setup_error; ++ } ++ return fd; ++ ++ setup_error: ++ logprintf(LOG_ERR, "could not setup %s\n", "uinput"); ++ logperror(LOG_ERR, NULL); ++ close(fd); ++ return -1; ++} + + #if 0 + /* using fnmatch */ +@@ -217,13 +361,26 @@ + } + + #ifdef EVIOCGRAB ++ exclusive = 1; + if (ioctl(hw.fd, EVIOCGRAB, 1) == -1) + { ++ exclusive = 0; + logprintf(LOG_WARNING, "can't get exclusive access to events " + "coming from `%s' interface", + hw.device); + } + #endif ++ return 1; ++} ++ ++int devinput_init_fwd() ++{ ++ if(!devinput_init()) return 0; ++ ++ if(exclusive) ++ { ++ uinputfd = setup_uinputfd("(lircd bypass)", hw.fd); ++ } + + return 1; + } +@@ -232,6 +389,12 @@ + int devinput_deinit(void) + { + logprintf(LOG_INFO, "closing '%s'", hw.device); ++ if(uinputfd != -1) ++ { ++ ioctl(uinputfd, UI_DEV_DESTROY); ++ close(uinputfd); ++ uinputfd = -1; ++ } + close(hw.fd); + hw.fd=-1; + return 1; +@@ -271,7 +434,10 @@ + rd = read(hw.fd, &event, sizeof event); + if (rd != sizeof event) { + logprintf(LOG_ERR, "error reading '%s'", hw.device); +- if(rd <= 0 && errno != EINTR) raise(SIGTERM); ++ if(rd <= 0 && errno != EINTR) ++ { ++ devinput_deinit(); ++ } + return 0; + } + +@@ -292,6 +458,25 @@ + + LOGPRINTF(1, "code %.8llx", code); + ++ if(uinputfd != -1) ++ { ++ if(event.type == EV_REL || ++ event.type == EV_ABS || ++ (event.type == EV_KEY && ++ event.code >= BTN_MISC && ++ event.code <= BTN_GEAR_UP) || ++ event.type == EV_SYN) ++ { ++ LOGPRINTF(1, "forwarding: %04x %04x", event.type, event.code); ++ if(write(uinputfd, &event, sizeof(event)) != sizeof(event)) ++ { ++ logprintf(LOG_ERR, "writing to uinput failed"); ++ logperror(LOG_ERR, NULL); ++ } ++ return NULL; ++ } ++ } ++ + /* ignore EV_SYN */ + if(event.type == EV_SYN) return NULL; + diff --git a/lirc.spec b/lirc.spec index 4162985..4d793f0 100644 --- a/lirc.spec +++ b/lirc.spec @@ -18,7 +18,7 @@ Name: lirc Version: 0.8.6 -Release: 1%{?pre:.%{pre}}%{?dist} +Release: 2%{?pre:.%{pre}}%{?dist} Summary: The Linux Infrared Remote Control package Group: System Environment/Daemons @@ -29,10 +29,11 @@ Source0: http://downloads.sourceforge.net/lirc/%{name}-%{version}.tar.bz2 Source1: %{name}.init Source2: %{name}.sysconfig Patch0: lirc-use-new-instead-of-conf-as-filename-suffix.patch +Patch1: lirc-0.8.6-devinput-pass-mouse-events.patch # https://bugzilla.redhat.com/show_bug.cgi?id=457273 # http://thread.gmane.org/gmane.comp.hardware.lirc/6884 -Patch1: lirc-0.8.6-standardized-remote-keycodes.patch -Patch2: lirc-0.8.4-make-remote-names-all-unique.patch +Patch2: lirc-0.8.6-standardized-remote-keycodes.patch +Patch3: lirc-0.8.4-make-remote-names-all-unique.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: %{__perl} @@ -119,6 +120,7 @@ of remote control configuration files. %prep %setup -q -n %{name}-%{version}%{?pre} %patch0 -p1 +%patch1 -p1 chmod 644 contrib/* chmod +x contrib/hal @@ -159,8 +161,8 @@ touch -r aclocal.m4 configure.ac # avoid autofoo re-run # Do this after, as we're touching the remote definitions earlier # Don't create a backup, or the original definitions will get installed -%patch1 -p1 %patch2 -p1 +%patch3 -p1 # Re-run autofoo for new cvs features #autoreconf -i -f #automake @@ -283,6 +285,9 @@ fi %changelog +* Thu Nov 12 2009 Jarod Wilson 0.8.6-2 +- Add devinput mouse event passthru to uinput support from lirc cvs + * Sun Sep 13 2009 Jarod Wilson 0.8.6-1 - Update to lirc 0.8.6 release