bin/83970: [patch] adding a feature to moused: stop mouse drift

Lena Lena at lena.kiev.ua
Sun Jul 24 00:20:12 GMT 2005


>Number:         83970
>Category:       bin
>Synopsis:       [patch] adding a feature to moused: stop mouse drift
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jul 24 00:20:10 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        FreeBSD 5.4-RELEASE-p3 i386
>Organization:
>Environment:
System: FreeBSD bedside.lena.kiev.ua 5.4-RELEASE-p3 FreeBSD 5.4-RELEASE-p3 #0: Tue Jul 12 12:52:26 EEST 2005 toor at bedside.lena.kiev.ua:/usr/obj/usr/src/sys/BEDSIDE i386
with moused.c updated to 1.71 (latest from CVS), moused.8 to 1.54, mouse.h to 1.23.
>Description:
Some slightly defective mice (like my new cheap Chinese "Goodwinn EMC-4005L"
optical PS/2 IntelliMouse, many others too friends told me) cause the
mouse pointer to slowly wander sometimes when physically the mouse is not moved.
Creeping mouse pointer on the console annoys. Attached patches for latest
versions (from CVS) of moused.8 and moused.c  add a feature to stop the drift.
>How-To-Repeat:
>Fix:
--- moused.8.diff begins here ---
*** moused.8	Wed Jul 20 22:29:32 2005
--- moused.8.drift	Sun Jul 24 01:31:33 2005
***************
*** 52,57 ****
--- 52,58 ----
  .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,176 ****
--- 172,187 ----
  .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 .
--- moused.8.diff ends here ---

--- moused.c.diff begins here ---
*** moused.c	Wed Jul 20 22:30:09 2005
--- moused.c.drift	Sat Jul 23 23:18:25 2005
***************
*** 474,479 ****
--- 474,494 ----
  
  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);
***************
*** 525,531 ****
      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)
  	switch(c) {
  
  	case '3':
--- 540,546 ----
      for (i = 0; i < MOUSE_MAXBUTTON; ++i)
  	mstate[i] = &bstate[i];
  
!     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':
***************
*** 715,720 ****
--- 730,753 ----
  	    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;
***************
*** 1104,1109 ****
--- 1137,1181 ----
  		}
  	    }
  
+             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) 
***************
*** 1177,1186 ****
  static void
  usage(void)
  {
!     fprintf(stderr, "%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 <mousetype>] [-l level] [-3 [-E timeout]] -p <port>",
  	"       moused [-d] -i <port|if|type|model|all> -p <port>");
      exit(1);
  }
--- 1249,1259 ----
  static void
  usage(void)
  {
!     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 <mousetype>] [-l level] [-3 [-E timeout]]",
! 	"              [-T distance[,time[,after]]] -p <port>",
  	"       moused [-d] -i <port|if|type|model|all> -p <port>");
      exit(1);
  }
***************
*** 2366,2371 ****
--- 2439,2445 ----
  #endif
  
      gettimeofday(&tv1, NULL);
+     drift_current_tv = tv1;
  
      /* double click threshold */
      tv2.tv_sec = rodent.clickthreshold/1000;
--- moused.c.diff ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list