summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xine_frontend_lirc.c93
1 files changed, 66 insertions, 27 deletions
diff --git a/xine_frontend_lirc.c b/xine_frontend_lirc.c
index ccd402c7..87fbbe76 100644
--- a/xine_frontend_lirc.c
+++ b/xine_frontend_lirc.c
@@ -4,9 +4,9 @@
* Forward (local) lirc keys to VDR (server)
*
*
- * Almost directly copied from vdr-1.3.34 (lirc.c : cLircRemote)
+ * Almost directly copied from vdr-1.4.3-2 (lirc.c : cLircRemote)
*
- * $Id: xine_frontend_lirc.c,v 1.3 2006-09-12 14:52:31 phintuka Exp $
+ * $Id: xine_frontend_lirc.c,v 1.4 2006-12-19 08:48:27 phintuka Exp $
*
*/
@@ -15,17 +15,20 @@
#include <sys/socket.h>
#include <sys/un.h>
-#define REPEATLIMIT 20 /* ms */
-#define REPEATDELAY 350 /* ms */
-#define KEYPRESSDELAY 150 /* ms */
+#define REPEATDELAY 350 /* ms */
+#define REPEATFREQ 100 /* ms */
+#define REPEATTIMEOUT 500 /* ms */
+#define RECONNECTDELAY 3000 /* ms */
+
#define LIRC_KEY_BUF 30
#define LIRC_BUFFER_SIZE 128
#define MIN_LIRCD_CMD_LEN 5
/* static data */
-pthread_t lirc_thread;
-volatile char *lirc_device_name = NULL;
+static pthread_t lirc_thread;
+static volatile char *lirc_device_name = NULL;
static volatile int fd_lirc = -1;
+static int lirc_repeat_emu = 0;
static uint64_t time_ms()
{
@@ -40,34 +43,50 @@ static uint64_t elapsed(uint64_t t)
return time_ms() - t;
}
-void *lirc_receiver_thread(void *fe)
+static void lircd_connect(void)
{
struct sockaddr_un addr;
- int timeout = -1;
- uint64_t FirstTime = time_ms();
- uint64_t LastTime = time_ms();
- char buf[LIRC_BUFFER_SIZE];
- char LastKeyName[LIRC_KEY_BUF] = "";
- int repeat = 0;
+
+ if(fd_lirc >= 0) {
+ close(fd_lirc);
+ fd_lirc = -1;
+ }
if(!lirc_device_name) {
LOGDBG("no lirc device given");
- goto out;
+ return;
}
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, (char*)lirc_device_name);
+
if ((fd_lirc = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
LOGERR("lirc error: socket() < 0");
- goto out;
+ return;
}
+
if (connect(fd_lirc, (struct sockaddr *)&addr, sizeof(addr))) {
LOGERR("lirc error: connect(%s) < 0", lirc_device_name);
- goto out;
+ close(fd_lirc);
+ fd_lirc = -1;
+ return;
}
+}
+
+void *lirc_receiver_thread(void *fe)
+{
+ int timeout = -1;
+ uint64_t FirstTime = time_ms();
+ uint64_t LastTime = time_ms();
+ char buf[LIRC_BUFFER_SIZE];
+ char LastKeyName[LIRC_KEY_BUF] = "";
+ int repeat = 0;
LOGMSG("lirc forwarding started");
+ nice(-1);
+ lircd_connect();
+
while(lirc_device_name && fd_lirc >= 0) {
fd_set set;
int ready, ret = -1;
@@ -89,8 +108,10 @@ void *lirc_receiver_thread(void *fe)
if(ready < 0) {
LOGMSG("LIRC connection lost ?");
- goto out;
- } else if(ready) {
+ break;
+ }
+
+ if(ready) {
do {
errno = 0;
@@ -98,26 +119,39 @@ void *lirc_receiver_thread(void *fe)
} while(ret < 0 && errno == EINTR);
if (ret <= 0 ) {
+ /* try reconnecting */
LOGERR("LIRC connection lost");
- break;
+ lircd_connect();
+ while(lirc_device_name && fd_lirc < 0) {
+ sleep(RECONNECTDELAY/1000);
+ lircd_connect();
+ }
+ if(fd_lirc >= 0)
+ LOGMSG("LIRC reconnected");
+ continue;
}
if (ret >= MIN_LIRCD_CMD_LEN) {
unsigned int count;
char KeyName[LIRC_KEY_BUF];
LOGDBG("LIRC: %s", buf);
+
if (sscanf(buf, "%*x %x %29s", &count, KeyName) != 2) {
/* '29' in '%29s' is LIRC_KEY_BUF-1! */
LOGMSG("unparseable lirc command: %s", buf);
continue;
}
+ if(lirc_repeat_emu)
+ if (strcmp(KeyName, LastKeyName) == 0 && elapsed(LastTime) < REPEATDELAY)
+ count = repeat + 1;
+
if (count == 0) {
- if (strcmp(KeyName, LastKeyName) == 0 && elapsed(FirstTime) < KEYPRESSDELAY)
+ if (strcmp(KeyName, LastKeyName) == 0 && elapsed(FirstTime) < REPEATDELAY)
continue; /* skip keys coming in too fast */
if (repeat)
if(find_input((fe_t*)fe))
- process_xine_keypress(((fe_t*)fe)->input, "LIRC", KeyName, 0, 1);
+ process_xine_keypress(((fe_t*)fe)->input, "LIRC", LastKeyName, 0, 1);
/* Put(LastKeyName, false, true); code, repeat, release */
strcpy(LastKeyName, KeyName);
repeat = 0;
@@ -125,8 +159,14 @@ void *lirc_receiver_thread(void *fe)
timeout = -1;
}
else {
- if (elapsed(FirstTime) < REPEATDELAY)
+ if (elapsed(LastTime) < REPEATFREQ)
continue; /* repeat function kicks in after a short delay */
+
+ if (elapsed(FirstTime) < REPEATDELAY) {
+ if(lirc_repeat_emu)
+ LastTime = time_ms();
+ continue; /* skip keys coming in too fast */
+ }
repeat = 1;
timeout = REPEATDELAY;
}
@@ -135,16 +175,16 @@ void *lirc_receiver_thread(void *fe)
if(find_input((fe_t*)fe))
process_xine_keypress(((fe_t*)fe)->input, "LIRC", KeyName, repeat, 0);
-
+
/*Put(KeyName, repeat);*/
}
else if (repeat) { /* the last one was a repeat, so let's generate a release */
- if (elapsed(LastTime) >= REPEATDELAY) {
- /* Put(LastKeyName, false, true); */
+ if (elapsed(LastTime) >= REPEATTIMEOUT) {
if(find_input((fe_t*)fe))
process_xine_keypress(((fe_t*)fe)->input, "LIRC", LastKeyName, 0, 1);
+ /* Put(LastKeyName, false, true); */
repeat = 0;
*LastKeyName = 0;
timeout = -1;
@@ -155,7 +195,6 @@ void *lirc_receiver_thread(void *fe)
}
- out:
if(fd_lirc >= 0)
close(fd_lirc);
fd_lirc = -1;