--- sys/i386/include/ORIG/mouse.h Sun Dec 7 11:14:03 1997 +++ sys/i386/include/mouse.h Thu May 28 22:25:50 1998 @@ -139,6 +139,7 @@ #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 @@ -256,5 +257,8 @@ #define MOUSE_SYS_MAXBUTTON 10 #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_ */ --- share/man/man5/ORIG/rc.conf.5 Wed May 6 22:14:22 1998 +++ share/man/man5/rc.conf.5 Thu May 28 21:34:29 1998 @@ -686,6 +686,7 @@ 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 --- sys/usr.sbin/moused/ORIG/moused.8 Mon Mar 23 11:30:38 1998 +++ sys/usr.sbin/moused/moused.8 Fri May 29 17:12:37 1998 @@ -257,6 +257,8 @@ 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 @@ 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 --- sys/usr.sbin/moused/ORIG/moused.c Thu Mar 12 23:23:17 1998 +++ sys/usr.sbin/moused/moused.c Fri May 29 17:00:45 1998 @@ -68,6 +68,8 @@ #include #include +#include +#include #include #define MAX_CLICKTHRESHOLD 2000 /* 2 seconds */ @@ -184,6 +186,7 @@ "intellimouse", "thinkingmouse", "sysmouse", + "x10mouseremote", #if notyet "mariqua", #endif @@ -322,6 +325,7 @@ (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 @@ 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 @@ zmap: 0, mfd : -1, cfd : -1, + mremsfd : -1, + mremcfd : -1, clickthreshold : 500, /* 0.5 sec */ }; @@ -367,6 +375,7 @@ 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 *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 @@ 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 @@ 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 @@ longjmp(env, 1); } +static void +cleanup(int sig) +{ + if (rodent.rtype == MOUSE_PROTO_X10MOUSEREM) + unlink(_PATH_MOUSEREMOTE); + exit(0); +} + /** ** usage ** @@ -825,6 +863,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 @@ 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 @@ { 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 @@ 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 @@ } 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; + } +} + +