From 679786927141ddfbf62b73a4531ff128aeb869b2 Mon Sep 17 00:00:00 2001 From: Amancio Hasty Date: Sun, 14 Jun 1998 20:05:27 +0000 Subject: [PATCH] Reviewed by: Amancio Submitted by: Randall Hopper The patch supports using the X10 Mouse Remote in both stand-alone and pass-through configurations, so you can plug your mouse and remote into the same serial port, use the mouse for X, and use the remote for other apps like Fxtv. For instance, we can now control fxtv via the remote control just like a TV : change channels, mute, increase volume, zoom video, freeze frame 8) The mouse events are channeled through the syscons/sysmouse I/F like normal, and the remote buttons are "syphoned off" to a UNIX-domain stream socket (defined as _PATH_MOUSEREMOTE in ) for a remote-aware app to grab and use. For further info on the X10 Mouse Remote see: http://www.x10.com/products/x10_mk19a.htm --- share/man/man5/rc.conf.5 | 3 +- sys/alpha/include/mouse.h | 6 +- sys/i386/include/mouse.h | 6 +- sys/sys/mouse.h | 6 +- usr.sbin/moused/moused.8 | 6 +- usr.sbin/moused/moused.c | 121 +++++++++++++++++++++++++++++++++++++- 6 files changed, 142 insertions(+), 6 deletions(-) diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index b54806d7f5f4..a147abc89393 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: rc.conf.5,v 1.18 1998/05/06 17:26:48 andreas Exp $ +.\" $Id: rc.conf.5,v 1.19 1998/05/06 17:36:16 andreas Exp $ .\" .Dd April 26, 1997 .Dt RC.CONF 5 @@ -686,6 +686,7 @@ glidepoint ALPS GlidePoint thinkingmouse Kensignton ThinkingMouse ps/2 PS/2 mouse mmhittab MM HitTablet +x10mouseremote X10 MouseRemote .Ed Even if your mouse is not in the above list, it may be compatible diff --git a/sys/alpha/include/mouse.h b/sys/alpha/include/mouse.h index d0eecefd4b01..27ec8e1fe94a 100644 --- a/sys/alpha/include/mouse.h +++ b/sys/alpha/include/mouse.h @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: mouse.h,v 1.8 1997/10/19 10:44:02 yokota Exp $ + * $Id: mouse.h,v 1.9 1997/12/07 08:08:50 yokota Exp $ */ #ifndef _MACHINE_MOUSE_H_ @@ -139,6 +139,7 @@ typedef struct mousemode { #define MOUSE_PROTO_INTELLI 10 /* MS IntelliMouse, 4 bytes */ #define MOUSE_PROTO_THINK 11 /* Kensignton Thinking Mouse, 3/4 bytes */ #define MOUSE_PROTO_SYSMOUSE 12 /* /dev/sysmouse */ +#define MOUSE_PROTO_X10MOUSEREM 13 /* X10 MouseRemote, 3 bytes */ #define MOUSE_RES_UNKNOWN (-1) #define MOUSE_RES_DEFAULT 0 @@ -257,4 +258,7 @@ typedef struct mousevar { #define MOUSE_SYS_STDBUTTONS 0x07 #define MOUSE_SYS_EXTBUTTONS 0x7f /* the others */ +/* Mouse remote socket */ +#define _PATH_MOUSEREMOTE "/var/run/MouseRemote" + #endif /* _MACHINE_MOUSE_H_ */ diff --git a/sys/i386/include/mouse.h b/sys/i386/include/mouse.h index d0eecefd4b01..27ec8e1fe94a 100644 --- a/sys/i386/include/mouse.h +++ b/sys/i386/include/mouse.h @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: mouse.h,v 1.8 1997/10/19 10:44:02 yokota Exp $ + * $Id: mouse.h,v 1.9 1997/12/07 08:08:50 yokota Exp $ */ #ifndef _MACHINE_MOUSE_H_ @@ -139,6 +139,7 @@ typedef struct mousemode { #define MOUSE_PROTO_INTELLI 10 /* MS IntelliMouse, 4 bytes */ #define MOUSE_PROTO_THINK 11 /* Kensignton Thinking Mouse, 3/4 bytes */ #define MOUSE_PROTO_SYSMOUSE 12 /* /dev/sysmouse */ +#define MOUSE_PROTO_X10MOUSEREM 13 /* X10 MouseRemote, 3 bytes */ #define MOUSE_RES_UNKNOWN (-1) #define MOUSE_RES_DEFAULT 0 @@ -257,4 +258,7 @@ typedef struct mousevar { #define MOUSE_SYS_STDBUTTONS 0x07 #define MOUSE_SYS_EXTBUTTONS 0x7f /* the others */ +/* Mouse remote socket */ +#define _PATH_MOUSEREMOTE "/var/run/MouseRemote" + #endif /* _MACHINE_MOUSE_H_ */ diff --git a/sys/sys/mouse.h b/sys/sys/mouse.h index d0eecefd4b01..27ec8e1fe94a 100644 --- a/sys/sys/mouse.h +++ b/sys/sys/mouse.h @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: mouse.h,v 1.8 1997/10/19 10:44:02 yokota Exp $ + * $Id: mouse.h,v 1.9 1997/12/07 08:08:50 yokota Exp $ */ #ifndef _MACHINE_MOUSE_H_ @@ -139,6 +139,7 @@ typedef struct mousemode { #define MOUSE_PROTO_INTELLI 10 /* MS IntelliMouse, 4 bytes */ #define MOUSE_PROTO_THINK 11 /* Kensignton Thinking Mouse, 3/4 bytes */ #define MOUSE_PROTO_SYSMOUSE 12 /* /dev/sysmouse */ +#define MOUSE_PROTO_X10MOUSEREM 13 /* X10 MouseRemote, 3 bytes */ #define MOUSE_RES_UNKNOWN (-1) #define MOUSE_RES_DEFAULT 0 @@ -257,4 +258,7 @@ typedef struct mousevar { #define MOUSE_SYS_STDBUTTONS 0x07 #define MOUSE_SYS_EXTBUTTONS 0x7f /* the others */ +/* Mouse remote socket */ +#define _PATH_MOUSEREMOTE "/var/run/MouseRemote" + #endif /* _MACHINE_MOUSE_H_ */ diff --git a/usr.sbin/moused/moused.8 b/usr.sbin/moused/moused.8 index 3e8a51c9f90b..ebc1d7c2f6af 100644 --- a/usr.sbin/moused/moused.8 +++ b/usr.sbin/moused/moused.8 @@ -28,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: moused.8,v 1.13 1998/03/23 08:24:24 charnier Exp $ +.\" $Id: moused.8,v 1.14 1998/06/13 18:55:55 steve Exp $ .\" .Dd December 3, 1997 .Dt MOUSED 8 @@ -257,6 +257,8 @@ ALPS GlidePoint protocol. Kensington ThinkingMouse protocol. .It Ar mmhittab Hitachi tablet protocol. +.It Ar x10mouseremote +X10 MouseRemote. .El .Pp For the bus and InPort mouse: @@ -448,6 +450,8 @@ virtual consoles process id of the currently running .Nm daemon +.It Pa /var/run/MouseRemote +UNIX-domain stream socket for X10 MouseRemote events .El .Sh EXAMPLE .Pp diff --git a/usr.sbin/moused/moused.c b/usr.sbin/moused/moused.c index cba99139c195..f35efd9058f6 100644 --- a/usr.sbin/moused/moused.c +++ b/usr.sbin/moused/moused.c @@ -46,7 +46,7 @@ #ifndef lint static const char rcsid[] = - "$Id: moused.c,v 1.17 1998/03/07 09:03:43 jkh Exp $"; + "$Id: moused.c,v 1.18 1998/03/12 15:00:06 yokota Exp $"; #endif /* not lint */ #include @@ -68,6 +68,8 @@ static const char rcsid[] = #include #include +#include +#include #include #define MAX_CLICKTHRESHOLD 2000 /* 2 seconds */ @@ -184,6 +186,7 @@ static char *rnames[] = { "intellimouse", "thinkingmouse", "sysmouse", + "x10mouseremote", #if notyet "mariqua", #endif @@ -322,6 +325,7 @@ static unsigned short rodentcflags[] = (CS7 | CREAD | CLOCAL | HUPCL ), /* IntelliMouse */ (CS7 | CREAD | CLOCAL | HUPCL ), /* Thinking Mouse */ (CS8 | CSTOPB | CREAD | CLOCAL | HUPCL ), /* sysmouse */ + (CS7 | CREAD | CLOCAL | HUPCL ), /* X10 MouseRemote */ #if notyet (CS8 | CSTOPB | CREAD | CLOCAL | HUPCL ), /* Mariqua */ #endif @@ -338,6 +342,8 @@ static struct rodentparam { int zmap; /* MOUSE_{X|Y}AXIS or a button number */ int mfd; /* mouse file descriptor */ int cfd; /* /dev/consolectl file descriptor */ + int mremsfd; /* mouse remote server file descriptor */ + int mremcfd; /* mouse remote client file descriptor */ long clickthreshold; /* double click speed in msec */ mousehw_t hw; /* mouse device hardware information */ mousemode_t mode; /* protocol information */ @@ -352,6 +358,8 @@ static struct rodentparam { zmap: 0, mfd : -1, cfd : -1, + mremsfd : -1, + mremcfd : -1, clickthreshold : 500, /* 0.5 sec */ }; @@ -367,6 +375,7 @@ static jmp_buf env; static void moused(void); static void hup(int sig); +static void cleanup(int sig); static void usage(void); static int r_identify(void); @@ -387,6 +396,9 @@ static symtab_t *pnpproto(pnpid_t *id); static symtab_t *gettoken(symtab_t *tab, char *s, int len); static char *gettokenname(symtab_t *tab, int val); +static void mremote_serversetup(); +static void mremote_clientchg(int add); + void main(int argc, char *argv[]) { @@ -586,6 +598,9 @@ main(int argc, char *argv[]) for (;;) { if (setjmp(env) == 0) { signal(SIGHUP, hup); + signal(SIGINT , cleanup); + signal(SIGQUIT, cleanup); + signal(SIGTERM, cleanup); if ((rodent.mfd = open(rodent.portname, O_RDWR | O_NONBLOCK, 0)) == -1) logerr(1, "unable to open %s", rodent.portname); @@ -682,9 +697,24 @@ moused(void) FD_ZERO(&fds); FD_SET(rodent.mfd, &fds); + if (rodent.mremsfd >= 0) FD_SET(rodent.mremsfd, &fds); + if (rodent.mremcfd >= 0) FD_SET(rodent.mremcfd, &fds); + if (select(FD_SETSIZE, &fds, NULL, NULL, NULL) <= 0) logwarn("failed to read from mouse", 0); + /* MouseRemote client connect/disconnect */ + if ((rodent.mremsfd >= 0) && FD_ISSET(rodent.mremsfd, &fds)) { + mremote_clientchg(TRUE); + continue; + } + + if ((rodent.mremcfd >= 0) && FD_ISSET(rodent.mremcfd, &fds)) { + mremote_clientchg(FALSE); + continue; + } + + /* mouse event */ read(rodent.mfd, &b, 1); if (r_protocol(b, &action)) { /* handler detected action */ r_map(&action, &action2); @@ -745,6 +775,14 @@ hup(int sig) longjmp(env, 1); } +static void +cleanup(int sig) +{ + if (rodent.rtype == MOUSE_PROTO_X10MOUSEREM) + unlink(_PATH_MOUSEREMOTE); + exit(0); +} + /** ** usage ** @@ -825,6 +863,7 @@ static unsigned char proto[][7] = { { 0x40, 0x40, 0x40, 0x00, 3, ~0x3f, 0x00 }, /* IntelliMouse */ { 0x40, 0x40, 0x40, 0x00, 3, ~0x33, 0x00 }, /* ThinkingMouse */ { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff }, /* sysmouse */ + { 0x40, 0x40, 0x40, 0x00, 3, ~0x23, 0x00 }, /* X10 MouseRem */ #if notyet { 0xf8, 0x80, 0x00, 0x00, 5, ~0x2f, 0x10 }, /* Mariqua */ #endif @@ -1130,6 +1169,12 @@ r_init(void) ioctl(rodent.mfd, MOUSE_SETMODE, &rodent.mode); break; + case MOUSE_PROTO_X10MOUSEREM: + mremote_serversetup(); + setmousespeed(1200, rodent.baudrate, rodentcflags[rodent.rtype]); + break; + + default: setmousespeed(1200, rodent.baudrate, rodentcflags[rodent.rtype]); break; @@ -1349,6 +1394,7 @@ r_protocol(u_char rBuf, mousestatus_t *act) { case MOUSE_PROTO_MS: /* Microsoft */ case MOUSE_PROTO_LOGIMOUSEMAN: /* MouseMan/TrackMan */ + case MOUSE_PROTO_X10MOUSEREM: /* X10 MouseRemote */ act->button = act->obutton & MOUSE_BUTTON4DOWN; if (rodent.flags & ChordMiddle) act->button |= ((pBuf[0] & MOUSE_MSS_BUTTONS) == MOUSE_MSS_BUTTONS) @@ -1357,6 +1403,18 @@ r_protocol(u_char rBuf, mousestatus_t *act) else act->button |= (act->obutton & MOUSE_BUTTON2DOWN) | butmapmss[(pBuf[0] & MOUSE_MSS_BUTTONS) >> 4]; + + /* Send X10 btn events to remote client (ensure -128-+127 range) */ + if ((rodent.rtype == MOUSE_PROTO_X10MOUSEREM) && + ((pBuf[0] & 0xFC) == 0x44) && (pBuf[2] == 0x3F)) { + if (rodent.mremcfd >= 0) { + unsigned char key = (signed char)(((pBuf[0] & 0x03) << 6) | + (pBuf[1] & 0x3F)); + write( rodent.mremcfd, &key, 1 ); + } + return 0; + } + act->dx = (char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F)); act->dy = (char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F)); break; @@ -2113,3 +2171,64 @@ gettokenname(symtab_t *tab, int val) } return NULL; } + +static void +mremote_serversetup() +{ + struct sockaddr_un ad; + + /* Open a UNIX domain stream socket to listen for mouse remote clients */ + unlink(_PATH_MOUSEREMOTE); + + if ( (rodent.mremsfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + logerrx(1, "unable to create unix domain socket %s",_PATH_MOUSEREMOTE); + + umask(0111); + + bzero(&ad, sizeof(ad)); + ad.sun_family = AF_UNIX; + strcpy(ad.sun_path, _PATH_MOUSEREMOTE); +#ifndef SUN_LEN +#define SUN_LEN(unp) ( ((char *)(unp)->sun_path - (char *)(unp)) + \ + strlen((unp)->path) ) +#endif + if (bind(rodent.mremsfd, (struct sockaddr *) &ad, SUN_LEN(&ad)) < 0) + logerrx(1, "unable to bind unix domain socket %s", _PATH_MOUSEREMOTE); + + listen(rodent.mremsfd, 1); +} + +static void +mremote_clientchg(int add) +{ + struct sockaddr_un ad; + int ad_len, fd; + + if (rodent.rtype != MOUSE_PROTO_X10MOUSEREM) + return; + + if ( add ) { + /* Accept client connection, if we don't already have one */ + ad_len = sizeof(ad); + fd = accept(rodent.mremsfd, (struct sockaddr *) &ad, &ad_len); + if (fd < 0) + logwarnx("failed accept on mouse remote socket"); + + if ( rodent.mremcfd < 0 ) { + rodent.mremcfd = fd; + debug("remote client connect...accepted"); + } + else { + close(fd); + debug("another remote client connect...disconnected"); + } + } + else { + /* Client disconnected */ + debug("remote client disconnected"); + close( rodent.mremcfd ); + rodent.mremcfd = -1; + } +} + +