Bug 18348

Summary: simultaneous push for 3-button emulation is difficult
Product: Base System Reporter: Kouichi Yokoyama <k_yoko>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.0-RELEASE   
Hardware: Any   
OS: Any   

Description Kouichi Yokoyama 2000-05-02 16:50:01 UTC
	<simultaneous push for 3-button emulation is difficult.>

Fix: <
3 button timeout patch for
 "$FreeBSD: src/usr.sbin/moused/moused.c,v 1.37 2000/01/24 10:26:46 yokota Exp $";
 FreeBSD 4.0-RELEASE, moused

A simultaneous push for 3-button emulation is difficult for me.
#notebook computers are usually 2-button mouse!!

So, the following patch was made referring to the code of XFree86.

add "-T timeout" option.

-T timeout
        Set maximun interval in msec between press the left and right
        physical buttons.

thenks.
--------------------------------------
Kouichi Yokoyama <k_yoko@jaist.ac.jp>




------------- end of patch -----------------------
>--uqveem3r1HJvQuVozVy7Yw7ayo6D46yodRTquFzkaI79Tma0
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

diff -c moused.c.orig moused.c
*** moused.c.orig	Mon Jan 24 19:26:46 2000
--- moused.c	Wed May  3 00:01:01 2000
***************
*** 68,73 ****
--- 68,74 ----
  
  #include <sys/types.h>
  #include <sys/time.h>
+ #include <sys/timeb.h>
  #include <sys/socket.h>
  #include <sys/un.h>
  #include <unistd.h>
***************
*** 366,371 ****
--- 367,373 ----
      int mremsfd;		/* mouse remote server file descriptor */
      int mremcfd;		/* mouse remote client file descriptor */
      long clickthreshold;	/* double click speed in msec */
+     long emulate3timeout;	/* Emulate3Buttons timeout msec */
      mousehw_t hw;		/* mouse device hardware information */
      mousemode_t mode;		/* protocol information */
  } rodent = { 
***************
*** 383,388 ****
--- 385,391 ----
      mremsfd : -1,
      mremcfd : -1,
      clickthreshold : 500,	/* 0.5 sec */
+     emulate3timeout : 150,	/* 0.15 sec */
  };
  
  /* button status */
***************
*** 425,437 ****
  
  static int kidspad(u_char rxc, mousestatus_t *act);
  
  int
  main(int argc, char *argv[])
  {
      int c;
      int	i;
  
!     while((c = getopt(argc,argv,"3C:DF:I:PRS:cdfhi:l:m:p:r:st:w:z:")) != -1)
  	switch(c) {
  
  	case '3':
--- 428,443 ----
  
  static int kidspad(u_char rxc, mousestatus_t *act);
  
+ void timevaladd(struct timeval *, long);
+ int timevalcomp(struct timeval *, struct timeval *);
+ 
  int
  main(int argc, char *argv[])
  {
      int c;
      int	i;
  
!     while((c = getopt(argc,argv,"3C:DF:I:PRS:cdfhi:l:m:p:r:st:w:z:T:")) != -1)
  	switch(c) {
  
  	case '3':
***************
*** 600,605 ****
--- 606,620 ----
  	    warnx("no such mouse type `%s'", optarg);
  	    usage();
  
+ 	case 'T':
+ 	    rodent.emulate3timeout = atoi(optarg);
+ 	    if ((rodent.emulate3timeout < 0) || 
+ 		(rodent.emulate3timeout > MAX_CLICKTHRESHOLD)) {
+ 		warnx("invalid argument `%s'", optarg);
+ 		usage();
+ 	    }
+ 	    break;
+ 
  	case 'h':
  	case '?':
  	default:
***************
*** 828,836 ****
  static void
  usage(void)
  {
!     fprintf(stderr, "%s\n%s\n%s\n",
  	"usage: moused [-3DRcdfs] [-I file] [-F rate] [-r resolution] [-S baudrate]",
! 	"              [-C threshold] [-m N=M] [-w N] [-z N] [-t <mousetype>] -p <port>",
  	"       moused [-d] -i <info> -p <port>");
      exit(1);
  }
--- 843,852 ----
  static void
  usage(void)
  {
!     fprintf(stderr, "%s\n%s\n%s\n%s\n",
  	"usage: moused [-3DRcdfs] [-I file] [-F rate] [-r resolution] [-S baudrate]",
! 	"              [-C threshold] [-T timeout] [-m N=M] [-w N] [-z N]",
! 	"              [-t <mousetype>] -p <port>",
  	"       moused [-d] -i <info> -p <port>");
      exit(1);
  }
***************
*** 1340,1345 ****
--- 1356,1364 ----
      static int		 on = FALSE;
      int			 x, y;
  
+     /*for emulation 3 button timeout */
+     static struct timeval limit, now;
+ 
      debug("received char 0x%x",(int)rBuf);
      if (rodent.rtype == MOUSE_PROTO_KIDSPAD)
  	return kidspad(rBuf, act) ;
***************
*** 1706,1711 ****
--- 1725,1765 ----
  	| (act->obutton ^ act->button);
  
      if (rodent.flags & Emulate3Button) {
+ 
+ 	/* set limit time(="timeout"+"now"), if press only button 1 or 3 */
+ 	if (((act->flags & (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
+ 	     == MOUSE_BUTTON1DOWN)
+ 	    && ((act->button & (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
+ 		== MOUSE_BUTTON1DOWN)) {
+ 	    gettimeofday(&limit, NULL);
+ 	    timevaladd(&limit, rodent.emulate3timeout);
+ 	}else if (((act->flags & (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
+ 		   == MOUSE_BUTTON3DOWN)
+ 		  && ((act->button & (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
+ 		      == MOUSE_BUTTON3DOWN)) {
+ 	    gettimeofday(&limit, NULL);
+ 	    timevaladd(&limit, rodent.emulate3timeout);
+ 	}
+ 	/* When a button was pushed again whthin the time limit. */
+ 	gettimeofday(&now, NULL);
+ 	if (((act->flags & (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
+ 	     == MOUSE_BUTTON1DOWN)
+ 	    && ((act->button & (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
+ 		== (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
+ 	    && (timevalcomp(&limit, &now)==1)) {
+ 	    gettimeofday(&limit, NULL);
+ 	    act->button &= ~(MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN);
+ 	    act->button |= MOUSE_BUTTON2DOWN;
+ 	}else if (((act->flags & (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
+ 		   == MOUSE_BUTTON3DOWN)
+ 		  && ((act->button & (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
+ 		      == (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
+ 		  && (timevalcomp(&limit, &now)==1)) {
+ 	    gettimeofday(&limit, NULL);
+ 	    act->button &= ~(MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN);
+ 	    act->button |= MOUSE_BUTTON2DOWN;
+ 	}
+ 
  	if (((act->flags & (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
  	        == (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
  	    && ((act->button & (MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN))
***************
*** 2578,2581 ****
--- 2632,2660 ----
      }
  }
  
+ void timevaladd(struct timeval *tp, long millisec){
+     tp->tv_usec += (millisec*1000);
+     tp->tv_sec += tp->tv_usec/1000000;
+     tp->tv_usec = tp->tv_usec%1000000;
+ }
  
+ int timevalcomp(struct timeval *tp1, struct timeval *tp2){
+     /* input  : ret*/
+     /*tp1>tp2 :  1*/
+     /*tp1=tp2 :  0*/
+     /*tp1<tp2 : -1*/
+ 
+     if(tp1->tv_sec > tp2->tv_sec){
+ 	return 1;
+     }else if(tp1->tv_sec < tp2->tv_sec){
+ 	return -1;
+     }
+ 
+     if(tp1->tv_usec > tp2->tv_usec){
+ 	return 1;
+     }else if(tp1->tv_usec < tp2->tv_usec){
+ 	return -1;
+     }
+ 
+     return 0;
+ }
How-To-Repeat: 
	<anytime>
Comment 1 hoek freebsd_committer freebsd_triage 2000-05-11 01:13:09 UTC
Responsible Changed
From-To: gnats-admin->yokota

I'm pretty sure you just fixed this problem.  The PR includes a proposed 
patch. 

Comment 2 iedowse 2001-07-10 17:56:12 UTC
Is this solved by the -E option to moused? The 3-button emulation
has changed significantly since 4.0-release.

Ian
Comment 3 perisa 2002-05-29 00:21:00 UTC
Hi,

it seems, that moused -E fullfils the same as the proposed patch.

 From the man page of moused(8):

     -E timeout
             When the third button emulation is enabled (see above), the
             moused daemon waits timeout msec at most before deciding 
whether
             two buttons are being pressed simultaneously.  The default 
time-
             out is 100 msec.

Please close the PR.

Thanks

Marc
Comment 4 Mark Linimon freebsd_committer freebsd_triage 2004-08-26 04:26:19 UTC
State Changed
From-To: open->feedback

Is this still a problem with modern versions of FreeBSD? 


Comment 5 Mark Linimon freebsd_committer freebsd_triage 2004-08-26 04:26:19 UTC
Responsible Changed
From-To: yokota->freebsd-bugs

With bugmeister hat on, reassign from inactive committer.
Comment 6 Mark Linimon freebsd_committer freebsd_triage 2004-08-26 04:43:37 UTC
State Changed
From-To: feedback->closed

Submitter's email address bounces.