1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-11-30 01:15:52 +00:00

Add support for DVICO USB remote control.

Submitted by:	grog
Approved by:	Daniel O'Connor (maintainer)
This commit is contained in:
Greg Lehey 2007-03-05 05:04:45 +00:00
parent 61003c5864
commit db4012df9a
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=186549
3 changed files with 180 additions and 2 deletions

View File

@ -40,9 +40,9 @@ PLIST_SUB+= SMODE2="@comment "
.if defined(WITH_IRMAN)
BUILD_DEPENDS+= ${LOCALBASE}/lib/libirman.a:${PORTSDIR}/comms/libirman
CONFIGURE_ARGS+= --with-driver=irman
CONFIGURE_ARGS+= --with-driver=irman --with-driver=dvico
.else
CONFIGURE_ARGS+= --with-driver=any
CONFIGURE_ARGS+= --with-driver=any --with-driver=dvico
.endif
.if ${OSVERSION} >= 500041

View File

@ -0,0 +1,160 @@
--- daemons/hw_hiddev.c.orig Sun Jul 10 18:04:11 2005
+++ daemons/hw_hiddev.c Thu Nov 23 14:41:52 2006
@@ -19,14 +19,19 @@
#include <stdio.h>
#include <sys/fcntl.h>
+#ifdef __FreeBSD__
+#include <usbhid.h>
+#else /* assume Linux */
#include <linux/types.h>
#include <linux/hiddev.h>
+#endif
#include "hardware.h"
#include "ir_remote.h"
#include "lircd.h"
#include "receive.h"
-
+#include <errno.h>
+#include <string.h>
static int hiddev_init();
static int hiddev_deinit(void);
@@ -103,7 +108,11 @@
logprintf(LOG_INFO, "initializing '%s'", hw.device);
if ((hw.fd = open(hw.device, O_RDONLY)) < 0) {
- logprintf(LOG_ERR, "unable to open '%s'", hw.device);
+ logprintf(LOG_ERR,
+ "unable to open '%s': %s (%d)",
+ hw.device,
+ strerror (errno),
+ errno );
return 0;
}
@@ -143,38 +152,117 @@
}
+/*
+ * Read a record from the remote control, decode it and return a
+ * string of the form
+ *
+ * 00010046000042fe 00 start DVICO_MCE
+ *
+ * The first field is the complete event. The second appears to tbe
+ * the repeat flag, the third the name of the the key, and the fourth
+ * some kind of identification. I have no idea how much of this is
+ * used.
+ *
+ * The code below works around the extremely fast repeat holdoff on
+ * the DVICO control. It's difficult to press a key without it
+ * repeating. We work around this by ignoring the first 3 repeats.
+ *
+ * For FreeBSD, we have the problem of a different HID interface.
+ * Linux returns a struct hiddev_event, while FreeBSD returns data
+ * with no specific structure. Part of the Linux structure is the
+ * hid, which FreeBSD doesn't seem to supply. Work around these
+ * issues by reading the FreeBSD data and packing it into a Linux
+ * struct hiddev_event. This requires lying about the hid.
+ */
+
char *hiddev_rec(struct ir_remote *remotes)
{
+#ifdef __FreeBSD__
+#define HIDRECLEN 3 /* get this from hid_init() */
+ char inbuf [HIDRECLEN];
+ struct hiddev_event
+ {
+ unsigned hid;
+ int16_t value;
+ };
+#endif
struct hiddev_event event;
int rd;
/* Remotec Mediamaster specific */
static int wheel_count = 0;
static int x_movement = 0;
+ static int repeat_count = 0;
int y_movement=0;
int x_direction=0;
int y_direction=0;
LOGPRINTF(1, "hiddev_rec");
+#ifdef __FreeBSD__
+ rd = read(hw.fd, inbuf, sizeof inbuf);
+ if (rd != sizeof inbuf) {
+ logprintf(LOG_ERR,
+ "Really read %d bytes from '%s', expected %d",
+ rd,
+ hw.device,
+ sizeof inbuf );
+ return 0;
+ }
+ event.hid = 0x10046; /* XXX not in FreeBSD */
+ event.value = * (int16_t *) (&inbuf [1]);
+ rd = sizeof event; /* to make code happy */
+#else
rd = read(hw.fd, &event, sizeof event);
+#endif
if (rd != sizeof event) {
- logprintf(LOG_ERR, "error reading '%s'", hw.device);
+ logprintf(LOG_ERR,
+ "Read %d bytes from '%s', expected %d",
+ rd,
+ hw.device,
+ sizeof event );
return 0;
}
LOGPRINTF(1, "hid 0x%X value 0x%X", event.hid, event.value);
pre_code = event.hid;
- main_code = event.value;
-
+ main_code = event.value & 0xffff; /* only 16 bits */
/*
* This stuff is probably dvico specific.
* I don't have any other hid devices to test...
*/
- if (event.hid == 0x10046) {
- repeat_flag = (main_code & dvico_repeat_mask);
+ if (pre_code == 0x10046) {
+ if (main_code & dvico_repeat_mask) /* repeated press */
+ repeat_count++; /* count them */
+ else
+ repeat_count = 0; /* reset */
+ repeat_flag = repeat_count > 2; /* real repeat flag */
main_code = (main_code & ~dvico_repeat_mask);
- return decode_all(remotes);
+ /*
+ * Skip this if we're working around the premature
+ * repeat.
+ */
+ if (repeat_flag || (repeat_count == 0))
+ {
+ char *foo;
+
+ foo = decode_all(remotes);
+ /*
+ * XXX Experimental code. Chop off the first 12
+ * bytes of the hex code, which FreeBSD does not
+ * provide, and which I suspect nobody cares
+ * about.
+ *
+ * For some reason, we can get NULL back here,
+ * so we need to check for that before returning
+ * address 0xc.
+ */
+ if (foo)
+ foo = &foo [12]; /* chop off the leading chars. */
+ return foo;
+ }
+ else
+ return 0; /* no data */
}
/* Remotec Mediamaster specific code */
/* Y-Coordinate,

View File

@ -0,0 +1,18 @@
--- daemons/lircd.c.orig Sun Jul 10 18:04:12 2005
+++ daemons/lircd.c Fri Nov 24 14:21:10 2006
@@ -755,9 +755,12 @@
strcpy(serv_addr.sun_path,lircdfile);
if(bind(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))==-1)
{
- fprintf(stderr,"%s: could not assign address to socket\n",
- progname);
- perror(progname);
+ fprintf(stderr,
+ "%s: could not assign address to socket %s: %s (%d)\n",
+ progname,
+ lircdfile,
+ strerror (errno),
+ errno );
goto start_server_failed1;
}