Reviewed by: Amancio

Submitted by:	Randall Hopper <rhh@ct.picker.com>
    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 <machine/mouse.h>) 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
This commit is contained in:
Amancio Hasty 1998-06-14 20:05:27 +00:00
parent c619155f0e
commit 6797869271
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=36991
6 changed files with 142 additions and 6 deletions

View File

@ -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

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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

View File

@ -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 <err.h>
@ -68,6 +68,8 @@ static const char rcsid[] =
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#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;
}
}