From d5f2946a42361a7c454299f4fe674b2133b71e11 Mon Sep 17 00:00:00 2001 From: Philip Paeps Date: Mon, 19 Sep 2005 06:58:39 +0000 Subject: [PATCH] Add an option to stop 'mouse drift' in some defective/cheap mice. This stops the pointer slowly wandering away on its own in an annoying way when the mouse isn't physically moved. PR: bin/83970 Submitted by: Lena -at- lena.kiev.ua X-MFC after: 6.0-RELEASE --- usr.sbin/moused/moused.8 | 11 ++++++ usr.sbin/moused/moused.c | 82 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/usr.sbin/moused/moused.8 b/usr.sbin/moused/moused.8 index ae530874f09b..7fe7e1c9f3cb 100644 --- a/usr.sbin/moused/moused.8 +++ b/usr.sbin/moused/moused.8 @@ -52,6 +52,7 @@ .Op Fl t Ar mousetype .Op Fl l Ar level .Op Fl 3 Op Fl E Ar timeout +.Op Fl T Ar distance Ns Op , Ns Ar time Ns Op , Ns Ar after .Fl p Ar port .Pp .Nm @@ -171,6 +172,16 @@ mode. .It Fl S Ar baudrate Select the baudrate for the serial port (1200 to 9600). Not all serial mice support this option. +.It Fl T Ar distance Ns Op , Ns Ar time Ns Op , Ns Ar after +Terminate drifT. +Use this option if mouse pointer slowly wanders when mouse is not moved. +Movements up to +.Ar distance +(for example 4) pixels (X+Y) in +.Ar time +msec (default 500) are ignored, except during +.Ar after +msec (default 4000) since last real mouse movement. .It Fl V Enable .Dq Virtual Scrolling . diff --git a/usr.sbin/moused/moused.c b/usr.sbin/moused/moused.c index 39efac186297..0ad46bd18fbe 100644 --- a/usr.sbin/moused/moused.c +++ b/usr.sbin/moused/moused.c @@ -476,6 +476,21 @@ static int mouse_move_delayed; static jmp_buf env; +static int drift_distance = 4; /* max steps X+Y */ +static int drift_time = 500; /* in 0.5 sec */ +static struct timeval drift_time_tv; +static struct timeval drift_2time_tv; /* 2*drift_time */ +static int drift_after = 4000; /* 4 sec */ +static struct timeval drift_after_tv; +static int drift_terminate = FALSE; +static struct timeval drift_current_tv; +static struct timeval drift_tmp; +static struct timeval drift_last_activity = {0,0}; +static struct drift_xy { + int x; int y; } drift_last = {0,0}; /* steps in last drift_time */ +static struct timeval drift_since = {0,0}; +static struct drift_xy drift_previous={0,0}; /* steps in previous drift_time */ + /* function prototypes */ static void moused(void); @@ -527,7 +542,7 @@ main(int argc, char *argv[]) for (i = 0; i < MOUSE_MAXBUTTON; ++i) mstate[i] = &bstate[i]; - while ((c = getopt(argc, argv, "3C:DE:F:HI:PRS:VU:a:cdfhi:l:m:p:r:st:w:z:")) != -1) + while ((c = getopt(argc, argv, "3C:DE:F:HI:PRS:T:VU:a:cdfhi:l:m:p:r:st:w:z:")) != -1) switch(c) { case '3': @@ -717,6 +732,24 @@ main(int argc, char *argv[]) debug("rodent baudrate %d", rodent.baudrate); break; + case 'T': + drift_terminate = TRUE; + sscanf(optarg, "%d,%d,%d", &drift_distance, &drift_time, + &drift_after); + if (drift_distance <= 0 || drift_time <= 0 || drift_after <= 0) { + warnx("invalid argument `%s'", optarg); + usage(); + } + debug("terminate drift: distance %d, time %d, after %d", + drift_distance, drift_time, drift_after); + drift_time_tv.tv_sec = drift_time/1000; + drift_time_tv.tv_usec = (drift_time%1000)*1000; + drift_2time_tv.tv_sec = (drift_time*=2)/1000; + drift_2time_tv.tv_usec = (drift_time%1000)*1000; + drift_after_tv.tv_sec = drift_after/1000; + drift_after_tv.tv_usec = (drift_after%1000)*1000; + break; + case 't': if (strcmp(optarg, "auto") == 0) { rodent.rtype = MOUSE_PROTO_UNKNOWN; @@ -1111,6 +1144,45 @@ moused(void) } } + if (drift_terminate) { + if (flags != MOUSE_POSCHANGED || action.dz || action2.dz) + drift_last_activity = drift_current_tv; + else { + /* X or/and Y movement only - possibly drift */ + timersub(&drift_current_tv,&drift_last_activity,&drift_tmp); + if (timercmp(&drift_tmp, &drift_after_tv, >)) { + timersub(&drift_current_tv, &drift_since, &drift_tmp); + if (timercmp(&drift_tmp, &drift_time_tv, <)) { + drift_last.x += action2.dx; + drift_last.y += action2.dy; + } else { + /* discard old accumulated steps (drift) */ + if (timercmp(&drift_tmp, &drift_2time_tv, >)) + drift_previous.x = drift_previous.y = 0; + else + drift_previous = drift_last; + drift_last.x = action2.dx; + drift_last.y = action2.dy; + drift_since = drift_current_tv; + } + if (abs(drift_last.x) + abs(drift_last.y) + > drift_distance) { + /* real movement, pass all accumulated steps */ + action2.dx = drift_previous.x + drift_last.x; + action2.dy = drift_previous.y + drift_last.y; + /* and reset accumulators */ + timerclear(&drift_since); + drift_last.x = drift_last.y = 0; + /* drift_previous will be cleared at next movement*/ + drift_last_activity = drift_current_tv; + } else { + continue; /* don't pass current movement to + * console driver */ + } + } + } + } + if (extioctl) { /* Defer clicks until we aren't VirtualScroll'ing. */ if (scroll_state == SCROLL_NOTSCROLLING) @@ -1184,10 +1256,11 @@ cleanup(int sig) static void usage(void) { - fprintf(stderr, "%s\n%s\n%s\n%s\n", + fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n", "usage: moused [-DRcdfs] [-I file] [-F rate] [-r resolution] [-S baudrate]", - " [-VH [-U threshold]] [-a X [,Y]] [-C threshold] [-m N=M] [-w N]", - " [-z N] [-t ] [-l level] [-3 [-E timeout]] -p ", + " [-VH [-U threshold]] [-a X[,Y]] [-C threshold] [-m N=M] [-w N]", + " [-z N] [-t ] [-l level] [-3 [-E timeout]]", + " [-T distance[,time[,after]]] -p ", " moused [-d] -i -p "); exit(1); } @@ -2373,6 +2446,7 @@ r_timestamp(mousestatus_t *act) #endif gettimeofday(&tv1, NULL); + drift_current_tv = tv1; /* double click threshold */ tv2.tv_sec = rodent.clickthreshold/1000;