unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Subject: w32 mouse wheel handling
@ 2003-05-23 14:47 David PONCE
  2003-05-25  4:17 ` Michael Welsh Duggan
  2003-05-27  7:21 ` Jason Rumney
  0 siblings, 2 replies; 20+ messages in thread
From: David PONCE @ 2003-05-23 14:47 UTC (permalink / raw)


Hi All,

With latest CVS version of NT Emacs (and 21.3.1 too) , I noticed a
scroll performance problem with relatively big files, when using the
mouse wheel and there is a header line displayed.  I use:

GNU Emacs 21.3.50.1 (i386-mingw-nt4.0.1381)
 of 2003-05-23 on EBAT311
configured using `configure --with-gcc (3.2)'

on Windows NT4 SP6a Workstation.

Here is a small test case, editing the Emacs src/ChangeLog file:

emacs -q -no-site-file
M-x mouse-wheel-mode
C-x C-f emacs/src/ChangeLog

Using the mouse wheel to scroll up/down works as expected.

Then setup a very basic header line:

M-: (setq header-line-format "TEST")

Now use again the mouse wheel to scroll up/down: you should notice an
important performance degradation!

After some investigation, I discovered that, when there is an header
line, mouse wheel events seems to be queued by Emacs, instead of being
processed as they appears.  Then, while Emacs process the queue of
mouse-wheel events, it eats a lot of CPU and the display isn't
refreshed, so the observed slow down.

Someone else observed that too?

I must admit that I didn't found why, when there is an header line,
mouse wheel events are deferred.

Another annoying thing with the way mouse wheel events are handled in
NT Emacs, is that it is impossible to directly bind commands to scroll
up or down events, nor to bind commands to mouse wheel events on the
mode line or header line only, like in X.  For example, I can't do
something like this ;-)

(global-set-key [mode-line mouse-4] 'mode-line-unbury-buffer)
(global-set-key [mode-line mouse-5] 'mode-line-bury-buffer)

I submit you the following patch to handle mouse wheel events in NT
Emacs like in X, that is as mouse click events.  Scrolling the wheel
up produces mouse-4 events, and scrolling the wheel down produces
mouse-5 events, eventually prefixed by header or mode line depending
on the mouse location :-)

Finally, handling all mouse events in an uniform way seems to have
fixed the performance problem mentioned above :-)

What do you think?

Sincerely,
David

Index: src/keyboard.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/keyboard.c,v
retrieving revision 1.744
diff -c -r1.744 keyboard.c
*** src/keyboard.c	15 May 2003 21:20:52 -0000	1.744
--- src/keyboard.c	23 May 2003 11:26:39 -0000
***************
*** 5517,5523 ****
  	}
        }
  #endif /* WINDOWSNT */
! #if defined(WINDOWSNT) || defined(MAC_OSX)
      case MOUSE_WHEEL_EVENT:
        {
  	enum window_part part;
--- 5517,5523 ----
  	}
        }
  #endif /* WINDOWSNT */
! #if defined(MAC_OSX)
      case MOUSE_WHEEL_EVENT:
        {
  	enum window_part part;
***************
*** 5589,5595 ****
  					     Qnil))));
  	}
        }
! #endif /* WINDOWSNT || MAC_OSX */
  
      case DRAG_N_DROP_EVENT:
        {
--- 5589,5595 ----
  					     Qnil))));
  	}
        }
! #endif /* MAC_OSX */
  
      case DRAG_N_DROP_EVENT:
        {
Index: src/w32term.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32term.c,v
retrieving revision 1.188
diff -c -r1.188 w32term.c
*** src/w32term.c	4 Apr 2003 21:15:53 -0000	1.188
--- src/w32term.c	23 May 2003 11:26:40 -0000
***************
*** 2913,2920 ****
       struct frame *f;
  {
    POINT p;
!   result->kind = MOUSE_WHEEL_EVENT;
!   result->code = (short) HIWORD (msg->msg.wParam);
    result->timestamp = msg->msg.time;
    result->modifiers = msg->dwModifiers;
    p.x = LOWORD (msg->msg.lParam);
--- 2913,2920 ----
       struct frame *f;
  {
    POINT p;
!   result->kind = MOUSE_CLICK_EVENT;
!   result->code = ( GET_WHEEL_DELTA_WPARAM (msg->msg.wParam) < 0 )? 4 : 3;
    result->timestamp = msg->msg.time;
    result->modifiers = msg->dwModifiers;
    p.x = LOWORD (msg->msg.lParam);
***************
*** 4385,4410 ****
  	  }
  
        case WM_MOUSEWHEEL:
!           if (dpyinfo->grabbed && last_mouse_frame
!               && FRAME_LIVE_P (last_mouse_frame))
!             f = last_mouse_frame;
!           else
!             f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
! 
!           if (f)
!             {
!               if ((!dpyinfo->w32_focus_frame
!                    || f == dpyinfo->w32_focus_frame)
!                   && (numchars >= 1))
!                 {
!                   construct_mouse_wheel (bufp, &msg, f);
!                   bufp++;
!                   count++;
!                   numchars--;
!                 }
!             }
! 	  break;
! 
  	case WM_DROPFILES:
  	  f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
  
--- 4385,4475 ----
  	  }
  
        case WM_MOUSEWHEEL:
! 	{
! 	  /* Convert each Windows mouse wheel event in a couple of
! 	     Emacs mouse click down/up events.	Scrolling the wheel up
! 	     is associated to mouse button 4 and scrolling the wheel
! 	     down to the mouse button 5.  */
! 	  int button;
! 	  int up;
! 	  
! 	  up = msg.dwModifiers & up_modifier;
! 	  
! 	  if (dpyinfo->grabbed && last_mouse_frame
! 	      && FRAME_LIVE_P (last_mouse_frame))
! 	    f = last_mouse_frame;
! 	  else
! 	    f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
! 	  
! 	  if (f)
! 	    {
! 	      Lisp_Object window;
! 	      POINT p;
! 	      int x, y;
! 	      
! 	      p.x = LOWORD (msg.msg.lParam);
! 	      p.y = HIWORD (msg.msg.lParam);
! 	      ScreenToClient (msg.msg.hwnd, &p);
! 	      x = XFASTINT (p.x);
! 	      y = XFASTINT (p.y);
! 	      
! 	      window = window_from_coordinates (f, x, y, 0, 0);
! 	      
! 	      /* Ignore mouse wheel events not in a window.  */
! 	      if (!WINDOWP(window))
! 		break;
! 	      
! 	      if ((!dpyinfo->w32_focus_frame
! 		   || f == dpyinfo->w32_focus_frame)
! 		  && (numchars >= 1))
! 		{
! 		  if ( !up )
! 		    {
! 		      /* Emit an Emacs mouse down message.	 */
! 		      msg.dwModifiers |= down_modifier;
! 		      construct_mouse_wheel (bufp, &msg, f);
! 		      bufp++;
! 		      count++;
! 		      numchars--;
! 		      
! 		      /* Push a simulated WM_MOUSEWHEEL up message.  */
! 		      msg.dwModifiers &= ~down_modifier;
! 		      msg.dwModifiers |= up_modifier;
! 		      prepend_msg (&msg);
! 		    }
! 		  else
! 		    {
! 		      /* Emit an Emacs mouse up message.  */
! 		      construct_mouse_wheel (bufp, &msg, f);
! 		      bufp++;
! 		      count++;
! 		      numchars--;
! 		    }
! 		}
! 	    }
! 	  
! 	  button = ( GET_WHEEL_DELTA_WPARAM (msg.msg.wParam) < 0 )? 4 : 3;
! 	  
! 	  if (up)
! 	    {
! 	      dpyinfo->grabbed &= ~ (1 << button);
! 	    }
! 	  else
! 	    {
! 	      dpyinfo->grabbed |= (1 << button);
! 	      last_mouse_frame = f;
! 	      /* Ignore any mouse motion that happened
! 		 before this event; any subsequent mouse-movement
! 		 Emacs events should reflect only motion after
! 		 the ButtonPress.  */
! 	      if (f != 0)
! 		f->mouse_moved = 0;
! 	      
! 	      last_tool_bar_item = -1;
! 	    }
! 	}
! 	break;
! 	
  	case WM_DROPFILES:
  	  f = x_window_to_frame (dpyinfo, msg.msg.hwnd);

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-23 14:47 David PONCE
@ 2003-05-25  4:17 ` Michael Welsh Duggan
  2003-05-25  8:34   ` David Ponce
                     ` (2 more replies)
  2003-05-27  7:21 ` Jason Rumney
  1 sibling, 3 replies; 20+ messages in thread
From: Michael Welsh Duggan @ 2003-05-25  4:17 UTC (permalink / raw)
  Cc: emacs-devel

David PONCE <david.ponce@wanadoo.fr> writes:

> Another annoying thing with the way mouse wheel events are handled in
> NT Emacs, is that it is impossible to directly bind commands to scroll
> up or down events, nor to bind commands to mouse wheel events on the
> mode line or header line only, like in X.  For example, I can't do
> something like this ;-)
>
> (global-set-key [mode-line mouse-4] 'mode-line-unbury-buffer)
> (global-set-key [mode-line mouse-5] 'mode-line-bury-buffer)
>
> I submit you the following patch to handle mouse wheel events in NT
> Emacs like in X, that is as mouse click events.  Scrolling the wheel
> up produces mouse-4 events, and scrolling the wheel down produces
> mouse-5 events, eventually prefixed by header or mode line depending
> on the mouse location :-)
>
> Finally, handling all mouse events in an uniform way seems to have
> fixed the performance problem mentioned above :-)

I would agree with this.  When I wrote the original mouse wheel
support (now long since changed to better implementations), I created
the mouse-wheel event because (to the best of my knowlede, at the
time at least) these events hadn't been standardized into a
mouse-4/mouse-5 event at that time in X.

-- 
Michael Welsh Duggan
(md5i@cs.cmu.edu)

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-25  4:17 ` Michael Welsh Duggan
@ 2003-05-25  8:34   ` David Ponce
  2003-05-25 15:19   ` Stefan Monnier
  2003-05-26 13:30   ` Jason Rumney
  2 siblings, 0 replies; 20+ messages in thread
From: David Ponce @ 2003-05-25  8:34 UTC (permalink / raw)
  Cc: emacs-devel

Hi Michael,

[...]
 > I would agree with this.  When I wrote the original mouse wheel
 > support (now long since changed to better implementations), I created
 > the mouse-wheel event because (to the best of my knowlede, at the
 > time at least) these events hadn't been standardized into a
 > mouse-4/mouse-5 event at that time in X.

Thanks for your feedback!

Here is an updated patch following Kim's latest changes.
Also it should work on W95 too (it would be nice if a W32 guru could
review it ;-).

Sincerely,
David

Index: src/keyboard.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/keyboard.c,v
retrieving revision 1.746
diff -c -r1.746 keyboard.c
*** src/keyboard.c	24 May 2003 21:59:25 -0000	1.746
--- src/keyboard.c	25 May 2003 08:24:31 -0000
***************
*** 5514,5520 ****
   	}
         }
   #endif /* WINDOWSNT */
! #if defined(WINDOWSNT) || defined(MAC_OSX)
       case MOUSE_WHEEL_EVENT:
         {
   	enum window_part part;
--- 5514,5520 ----
   	}
         }
   #endif /* WINDOWSNT */
! #if defined(MAC_OSX)
       case MOUSE_WHEEL_EVENT:
         {
   	enum window_part part;
***************
*** 5587,5593 ****
   					     Qnil))));
   	}
         }
! #endif /* WINDOWSNT || MAC_OSX */

       case DRAG_N_DROP_EVENT:
         {
--- 5587,5593 ----
   					     Qnil))));
   	}
         }
! #endif /* MAC_OSX */

       case DRAG_N_DROP_EVENT:
         {
Index: src/w32term.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32term.c,v
retrieving revision 1.189
diff -c -r1.189 w32term.c
*** src/w32term.c	24 May 2003 22:06:19 -0000	1.189
--- src/w32term.c	25 May 2003 08:24:42 -0000
***************
*** 2911,2918 ****
        struct frame *f;
   {
     POINT p;
!   result->kind = MOUSE_WHEEL_EVENT;
!   result->code = (short) HIWORD (msg->msg.wParam);
     result->timestamp = msg->msg.time;
     result->modifiers = msg->dwModifiers;
     p.x = LOWORD (msg->msg.lParam);
--- 2911,2918 ----
        struct frame *f;
   {
     POINT p;
!   result->kind = MOUSE_CLICK_EVENT;
!   result->code = ( GET_WHEEL_DELTA_WPARAM (msg->msg.wParam) < 0 )? 4 : 3;
     result->timestamp = msg->msg.time;
     result->modifiers = msg->dwModifiers;
     p.x = LOWORD (msg->msg.lParam);
***************
*** 4383,4408 ****
   	  }

         case WM_MOUSEWHEEL:
!           if (dpyinfo->grabbed && last_mouse_frame
!               && FRAME_LIVE_P (last_mouse_frame))
!             f = last_mouse_frame;
!           else
!             f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
!
!           if (f)
!             {
!               if ((!dpyinfo->w32_focus_frame
!                    || f == dpyinfo->w32_focus_frame)
!                   && (numchars >= 1))
!                 {
!                   construct_mouse_wheel (bufp, &msg, f);
!                   bufp++;
!                   count++;
!                   numchars--;
!                 }
!             }
! 	  break;
!
   	case WM_DROPFILES:
   	  f = x_window_to_frame (dpyinfo, msg.msg.hwnd);

--- 4383,4473 ----
   	  }

         case WM_MOUSEWHEEL:
! 	{
! 	  /* Convert each Windows mouse wheel event in a couple of
! 	     Emacs mouse click down/up events.	Scrolling the wheel up
! 	     is associated to mouse button 4 and scrolling the wheel
! 	     down to the mouse button 5.  */
! 	  int button;
! 	  int up;
! 	
! 	  up = msg.dwModifiers & up_modifier;
! 	
! 	  if (dpyinfo->grabbed && last_mouse_frame
! 	      && FRAME_LIVE_P (last_mouse_frame))
! 	    f = last_mouse_frame;
! 	  else
! 	    f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
! 	
! 	  if (f)
! 	    {
! 	      Lisp_Object window;
! 	      POINT p;
! 	      int x, y;
! 	
! 	      p.x = LOWORD (msg.msg.lParam);
! 	      p.y = HIWORD (msg.msg.lParam);
! 	      ScreenToClient (msg.msg.hwnd, &p);
! 	      x = XFASTINT (p.x);
! 	      y = XFASTINT (p.y);
! 	
! 	      window = window_from_coordinates (f, x, y, 0, 0, 0, 0);
! 	
! 	      /* Ignore mouse wheel events not in a window.  */
! 	      if (!WINDOWP(window))
! 		break;
! 	
! 	      if ((!dpyinfo->w32_focus_frame
! 		   || f == dpyinfo->w32_focus_frame)
! 		  && (numchars >= 1))
! 		{
! 		  if ( !up )
! 		    {
! 		      /* Emit an Emacs mouse down message.	 */
! 		      msg.dwModifiers |= down_modifier;
! 		      construct_mouse_wheel (bufp, &msg, f);
! 		      bufp++;
! 		      count++;
! 		      numchars--;
! 		
! 		      /* Push a simulated WM_MOUSEWHEEL up message.  */
! 		      msg.dwModifiers &= ~down_modifier;
! 		      msg.dwModifiers |= up_modifier;
! 		      prepend_msg (&msg);
! 		    }
! 		  else
! 		    {
! 		      /* Emit an Emacs mouse up message.  */
! 		      construct_mouse_wheel (bufp, &msg, f);
! 		      bufp++;
! 		      count++;
! 		      numchars--;
! 		    }
! 		}
! 	    }
! 	
! 	  button = ( GET_WHEEL_DELTA_WPARAM (msg.msg.wParam) < 0 )? 4 : 3;
! 	
! 	  if (up)
! 	    {
! 	      dpyinfo->grabbed &= ~ (1 << button);
! 	    }
! 	  else
! 	    {
! 	      dpyinfo->grabbed |= (1 << button);
! 	      last_mouse_frame = f;
! 	      /* Ignore any mouse motion that happened
! 		 before this event; any subsequent mouse-movement
! 		 Emacs events should reflect only motion after
! 		 the ButtonPress.  */
! 	      if (f != 0)
! 		f->mouse_moved = 0;
! 	
! 	      last_tool_bar_item = -1;
! 	    }
! 	}
! 	break;
! 	
   	case WM_DROPFILES:
   	  f = x_window_to_frame (dpyinfo, msg.msg.hwnd);

***************
*** 4749,4772 ****
   	  /* Check for messages registered at runtime. */
   	  if (msg.msg.message == msh_mousewheel)
   	    {
! 	      if (dpyinfo->grabbed && last_mouse_frame
! 		  && FRAME_LIVE_P (last_mouse_frame))
! 		f = last_mouse_frame;
! 	      else
! 		f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
!
! 	      if (f)
! 		{
! 		  if ((!dpyinfo->w32_focus_frame
! 		       || f == dpyinfo->w32_focus_frame)
! 		      && (numchars >= 1))
! 		    {
! 		      construct_mouse_wheel (bufp, &msg, f);
! 		      bufp++;
! 		      count++;
! 		      numchars--;
! 		    }
! 		}
   	    }
   	  break;
   	}
--- 4814,4822 ----
   	  /* Check for messages registered at runtime. */
   	  if (msg.msg.message == msh_mousewheel)
   	    {
!               /* Forward MSH_MOUSEWHEEL as WM_MOUSEWHEEL.  */
!               msg.msg.message == WM_MOUSEWHEEL;
!               prepend_msg (&msg);
   	    }
   	  break;
   	}

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-25  4:17 ` Michael Welsh Duggan
  2003-05-25  8:34   ` David Ponce
@ 2003-05-25 15:19   ` Stefan Monnier
  2003-05-25 23:22     ` Kim F. Storm
  2003-05-26 13:30   ` Jason Rumney
  2 siblings, 1 reply; 20+ messages in thread
From: Stefan Monnier @ 2003-05-25 15:19 UTC (permalink / raw)
  Cc: emacs-devel

> > Another annoying thing with the way mouse wheel events are handled in
> > NT Emacs, is that it is impossible to directly bind commands to scroll
> > up or down events, nor to bind commands to mouse wheel events on the
> > mode line or header line only, like in X.  For example, I can't do
> > something like this ;-)
> >
> > (global-set-key [mode-line mouse-4] 'mode-line-unbury-buffer)
> > (global-set-key [mode-line mouse-5] 'mode-line-bury-buffer)
> >
> > I submit you the following patch to handle mouse wheel events in NT
> > Emacs like in X, that is as mouse click events.  Scrolling the wheel
> > up produces mouse-4 events, and scrolling the wheel down produces
> > mouse-5 events, eventually prefixed by header or mode line depending
> > on the mouse location :-)
> >
> > Finally, handling all mouse events in an uniform way seems to have
> > fixed the performance problem mentioned above :-)
> 
> I would agree with this.  When I wrote the original mouse wheel
> support (now long since changed to better implementations), I created
> the mouse-wheel event because (to the best of my knowlede, at the
> time at least) these events hadn't been standardized into a
> mouse-4/mouse-5 event at that time in X.

I agree on the principle, but I think using mouse-4 and mouse-5 is
not correct.  It's just an X11 hack.  I'd rather create new events
like wheel-up and wheel-down and then have a function-key-map to
translate mouse-4 and mouse-5 to wheel-up and wheel-down (on X).
The only problem with it is that xterm-mouse-mode already uses
the function-key-map to generate mouse-4 and mouse-5, so we'd
have to change xterm-mouse-mode to manually pass its output through
function-key-map.

I don't know what mouse-wheel events look like under W32 (or
under MacOS for that matter), so I'm not sure whether such an interface
would be limiting.


	Stefan

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-25 15:19   ` Stefan Monnier
@ 2003-05-25 23:22     ` Kim F. Storm
  2003-05-26  5:09       ` Kai Großjohann
  0 siblings, 1 reply; 20+ messages in thread
From: Kim F. Storm @ 2003-05-25 23:22 UTC (permalink / raw)
  Cc: Michael Welsh Duggan

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

> I agree on the principle, but I think using mouse-4 and mouse-5 is
> not correct.  It's just an X11 hack.  I'd rather create new events
> like wheel-up and wheel-down and then have a function-key-map to
> translate mouse-4 and mouse-5 to wheel-up and wheel-down (on X).

I agree 100%, that we should not use the mouse-4 and mouse-5 names.  

But I'm less certain about the names for the wheel events though.

I think the wheel-up and wheel-down names are a bit confusing when
compated to existing mouse events like down-mouse-1 and up-mouse-2.

Also, if you look at a typical mouse wheel, it has two directions:
"upwards" (turn the wheel away from yourself) and "downwards" (turn
the wheel towards yourself).  So in the "human context", these should
then correspond to the events wheel-up and wheel-down.  

But inside emacs, the event which scrolls the mouse "away from you"
would be bound to scroll-down and "towards you" to scroll-up, so in
the "emacs context" we could just as well justify to assign the
wheel-up and wheel-down events in the "opposite direction".

So "wheel-up" and "wheel-down" are not really unambiguous.

Furthermore, I have seen mice with two scroll wheels, some of these
have two up/down wheels, others have both up/down and left/right
wheels, and I think our naming of wheel events should be prepared for
this.

So maybe we could simply use names like wheel-1, wheel-2 (first mouse
wheel), mouse-3, mouse-4 (second mouse wheel), etc.

Or we could have wheel-forward-1, wheel-backward-1, etc.

Or wheel+1, wheel-1, wheel+2, wheel-2, etc.

-- 
Kim F. Storm <storm@cua.dk> http://www.cua.dk

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-25 23:22     ` Kim F. Storm
@ 2003-05-26  5:09       ` Kai Großjohann
  2003-05-27 12:44         ` Richard Stallman
  0 siblings, 1 reply; 20+ messages in thread
From: Kai Großjohann @ 2003-05-26  5:09 UTC (permalink / raw)


storm@cua.dk (Kim F. Storm) writes:

> I think the wheel-up and wheel-down names are a bit confusing when
> compated to existing mouse events like down-mouse-1 and up-mouse-2.

How about north and south?  That extends to east and west easily for
multi-wheel mice.
-- 
This line is not blank.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-25  4:17 ` Michael Welsh Duggan
  2003-05-25  8:34   ` David Ponce
  2003-05-25 15:19   ` Stefan Monnier
@ 2003-05-26 13:30   ` Jason Rumney
  2 siblings, 0 replies; 20+ messages in thread
From: Jason Rumney @ 2003-05-26 13:30 UTC (permalink / raw)
  Cc: emacs-devel

On 1271 December 1999, Michael Welsh Duggan wrote:

> I would agree with this.  When I wrote the original mouse wheel
> support (now long since changed to better implementations), I created
> the mouse-wheel event because (to the best of my knowlede, at the
> time at least) these events hadn't been standardized into a
> mouse-4/mouse-5 event at that time in X.

They still haven't been standardized as mouse-4/mouse-5, that is a
common kludge for programs that do not have proper Z-Axis handling.

I think it would be better if the events were mouse-wheel-up and
mouse-wheel-down. Then if consistency is desired, someone will be
motivated to write Z-Axis support for X.

I do agree that two seperate events would be easier for the end-user
to use than the current single mouse-wheel event.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-23 14:47 David PONCE
  2003-05-25  4:17 ` Michael Welsh Duggan
@ 2003-05-27  7:21 ` Jason Rumney
  1 sibling, 0 replies; 20+ messages in thread
From: Jason Rumney @ 2003-05-27  7:21 UTC (permalink / raw)
  Cc: emacs-devel

David PONCE <david.ponce@wanadoo.fr> writes:

> I submit you the following patch to handle mouse wheel events in NT
> Emacs like in X, that is as mouse click events.  Scrolling the wheel
> up produces mouse-4 events, and scrolling the wheel down produces
> mouse-5 events, eventually prefixed by header or mode line depending
> on the mouse location :-)

I see the patch has been committed despite several people objecting
to the use of mouse-4 and mouse-5. I am not sure what will happen now
with my 5-button mouse, probably buttons 4 and 5 will be
indistinguishable from the wheel, since the values are hard-coded.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
@ 2003-05-27  8:12 David PONCE
  2003-05-27  8:29 ` Juanma Barranquero
  0 siblings, 1 reply; 20+ messages in thread
From: David PONCE @ 2003-05-27  8:12 UTC (permalink / raw)
  Cc: emacs-devel

Hi Jason,

> I see the patch has been committed despite several people objecting
> to the use of mouse-4 and mouse-5. I am not sure what will happen now
> with my 5-button mouse, probably buttons 4 and 5 will be
> indistinguishable from the wheel, since the values are hard-coded.

I not decided to commit that patch.
Juanma asked me for a Changelog to commit the patch, so I thought it
was fine with other people.

Feel free to revert the changes, until a better solution is found.

Sincerely,
David

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-27  8:12 Subject: w32 mouse wheel handling David PONCE
@ 2003-05-27  8:29 ` Juanma Barranquero
  2003-05-27  8:45   ` Jason Rumney
  2003-05-27 14:28   ` Stefan Monnier
  0 siblings, 2 replies; 20+ messages in thread
From: Juanma Barranquero @ 2003-05-27  8:29 UTC (permalink / raw)
  Cc: emacs-devel


On Tue, 27 May 2003 10:12:49 +0200 (CEST)
David PONCE <david.ponce@wanadoo.fr> wrote:

> I not decided to commit that patch.
> Juanma asked me for a Changelog to commit the patch, so I thought it
> was fine with other people.

I routinely commit other people's patches, when RMS asks me to do so. I
suppose he wasn't aware there where objections to this one. I wasn't (I
didn't follow this particular thread).

> Feel free to revert the changes, until a better solution is found.

I agree. If no one does it before, I'll do in about twelve hours.

                                                                Juanma

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-27  8:29 ` Juanma Barranquero
@ 2003-05-27  8:45   ` Jason Rumney
  2003-05-27  8:49     ` Juanma Barranquero
  2003-05-27 22:41     ` Richard Stallman
  2003-05-27 14:28   ` Stefan Monnier
  1 sibling, 2 replies; 20+ messages in thread
From: Jason Rumney @ 2003-05-27  8:45 UTC (permalink / raw)
  Cc: emacs-devel

Juanma Barranquero wrote:
> On Tue, 27 May 2003 10:12:49 +0200 (CEST)
> David PONCE <david.ponce@wanadoo.fr> wrote:
> 
>>Feel free to revert the changes, until a better solution is found.
> 
> I agree. If no one does it before, I'll do in about twelve hours.

I think the only objection was the naming of the events. This is a
minor change to the patched version, so there is no real harm in
leaving the patch in place until the naming is decided. As long as
the issue is not forgotten about.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-27  8:45   ` Jason Rumney
@ 2003-05-27  8:49     ` Juanma Barranquero
  2003-05-27 22:41     ` Richard Stallman
  1 sibling, 0 replies; 20+ messages in thread
From: Juanma Barranquero @ 2003-05-27  8:49 UTC (permalink / raw)
  Cc: emacs-devel


On Tue, 27 May 2003 09:45:31 +0100
Jason Rumney <jasonr@gnu.org> wrote:

> so there is no real harm in
> leaving the patch in place until the naming is decided. As long as
> the issue is not forgotten about.

Ok.


                                                                Juanma

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-26  5:09       ` Kai Großjohann
@ 2003-05-27 12:44         ` Richard Stallman
  2003-05-28 22:18           ` David Ponce
  0 siblings, 1 reply; 20+ messages in thread
From: Richard Stallman @ 2003-05-27 12:44 UTC (permalink / raw)
  Cc: emacs-devel

    > I think the wheel-up and wheel-down names are a bit confusing when
    > compated to existing mouse events like down-mouse-1 and up-mouse-2.

    How about north and south?  That extends to east and west easily for
    multi-wheel mice.

`wheel-up' and `wheel-down' are better because they are similar to the
names of the vertical arrow keys, which are `up' and `down'.  I don't
think people will confuse this with the `down-' prefix for mouse keys.
(There is no `up-' prefix.)

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-27  8:29 ` Juanma Barranquero
  2003-05-27  8:45   ` Jason Rumney
@ 2003-05-27 14:28   ` Stefan Monnier
  1 sibling, 0 replies; 20+ messages in thread
From: Stefan Monnier @ 2003-05-27 14:28 UTC (permalink / raw)
  Cc: emacs-devel

> > I not decided to commit that patch.
> > Juanma asked me for a Changelog to commit the patch, so I thought it
> > was fine with other people.
> 
> I routinely commit other people's patches, when RMS asks me to do so. I
> suppose he wasn't aware there where objections to this one. I wasn't (I
> didn't follow this particular thread).
> 
> > Feel free to revert the changes, until a better solution is found.
> 
> I agree. If no one does it before, I'll do in about twelve hours.

Why not fix it instead of reverting it.  After all nobody objected to
the basic idea.  Le'ts just change it to mouse-wheel-up
and mouse-wheel-down.
[ If people really really care about the naming and prefer wheel-up/wheel-down
  or wheel-north/wheel-south or wheel-forward/wheel-backward or ... I have
  no objection against any naming and I don't think anybody should either,
  so whoever does the commit gets to choose. ]


	Stefan

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-27  8:45   ` Jason Rumney
  2003-05-27  8:49     ` Juanma Barranquero
@ 2003-05-27 22:41     ` Richard Stallman
  2003-05-28  7:50       ` Oliver Scholz
  1 sibling, 1 reply; 20+ messages in thread
From: Richard Stallman @ 2003-05-27 22:41 UTC (permalink / raw)
  Cc: jmbarranquero

If we can choose whatever names we want for these events,
let's call them wheel-up and wheel-down.

(It seems to me that the wheel is logically separate from the mouse.)

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-27 22:41     ` Richard Stallman
@ 2003-05-28  7:50       ` Oliver Scholz
  0 siblings, 0 replies; 20+ messages in thread
From: Oliver Scholz @ 2003-05-28  7:50 UTC (permalink / raw)


Richard Stallman <rms@gnu.org> writes:

> If we can choose whatever names we want for these events,
> let's call them wheel-up and wheel-down.
>
> (It seems to me that the wheel is logically separate from the mouse.)

FYI, it sometimes is even physically separate. I own a keyboard with a
"mouse" wheel, for example.

    Oliver
-- 
9 Prairial an 211 de la Révolution
Liberté, Egalité, Fraternité!

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-27 12:44         ` Richard Stallman
@ 2003-05-28 22:18           ` David Ponce
  2003-05-29  7:33             ` Jason Rumney
  2003-05-30  0:50             ` Richard Stallman
  0 siblings, 2 replies; 20+ messages in thread
From: David Ponce @ 2003-05-28 22:18 UTC (permalink / raw)


[...]
> `wheel-up' and `wheel-down' are better because they are similar to the
> names of the vertical arrow keys, which are `up' and `down'.  I don't
> think people will confuse this with the `down-' prefix for mouse keys.
> (There is no `up-' prefix.)

Hi,

Following above suggestion to produce wheel-up/down Lisp events from
mouse wheel, I propose you an implementation :-)

Here is an overview:

I introduced the new event type WHEEL_EVENT which results in
wheel-up/down Lisp events (kind of mouse click events), depending on
the setting of the up_modifier or down_modifier.

Like with mouse buttons, it will be possible to handle several wheels:
wheel-up-1 and wheel-down-1 events are associated to the first wheel,
wheel-up-2 and wheel-down-2 to the second wheel, etc..

Depending on the speed the wheel is moved, wheel-up/down events can
get a double- or triple- modifier with `event-click-count' set.  For
example, `mwheel-scroll' uses that information to implement
`mouse-wheel-progessive-speed'.

For now I updated w32term.c to generate WHEEL_EVENTs from
w32 WM_MOUSEWHEEL events.  This result in wheel-up-1/wheel-down-1
Lisp events (as there is only one mouse wheel button).

My X and MAC skills are too limited, so I didn't updated xterm.c and
macterm.c.  Sorry.

To try the new code with mwheel.el, you need to customize
`mouse-wheel-down-event' and `mouse-wheel-up-event' to be respectively
wheel-down-1 and wheel-up-1.

Following is the change log and the patch.

Hope it will help.

Sincerely,
David

2003-05-28  David Ponce  <david@dponce.com>

         * termhooks.h (enum event_kind): Added new WHEEL_EVENT event.

         * keyboard.c (Qmouse_wheel): Declare only if MAC_OSX defined.
         (mouse_wheel_syms, lispy_mouse_wheel_names): Likewise.
         (discard_mouse_events): Discard WHEEL_EVENT events too.
         (Vlispy_wheel_up_stem, Vlispy_wheel_down_stem)
         (wheel_up_syms, wheel_down_syms): New.
         (syms_of_keyboard): Init and staticpro them.  Init and staticpro
         Qmouse_wheel and mouse_wheel_syms only if MAC_OSX defined.
         (make_lispy_event): Added WHEEL_EVENT handler.

         * w32term.c (construct_mouse_wheel): Construct WHEEL_EVENT.
         (w32_read_socket): Map w32 WM_MOUSEWHEEL events to Emacs
         WHEEL_EVENT events.

Index: src/keyboard.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/keyboard.c,v
retrieving revision 1.747
diff -c -r1.747 keyboard.c
*** src/keyboard.c	26 May 2003 22:55:45 -0000	1.747
--- src/keyboard.c	28 May 2003 22:04:11 -0000
***************
*** 547,553 ****
   /* Symbols to denote kinds of events.  */
   Lisp_Object Qfunction_key;
   Lisp_Object Qmouse_click;
! #if defined(WINDOWSNT) || defined(MAC_OSX)
   Lisp_Object Qmouse_wheel;
   #endif
   #ifdef WINDOWSNT
--- 547,553 ----
   /* Symbols to denote kinds of events.  */
   Lisp_Object Qfunction_key;
   Lisp_Object Qmouse_click;
! #if defined(MAC_OSX)
   Lisp_Object Qmouse_wheel;
   #endif
   #ifdef WINDOWSNT
***************
*** 3737,3742 ****
--- 3737,3743 ----
   	sp = kbd_buffer;

         if (sp->kind == MOUSE_CLICK_EVENT
+           || sp->kind == WHEEL_EVENT
   #ifdef WINDOWSNT
   	  || sp->kind == W32_SCROLL_BAR_CLICK_EVENT
   #endif
***************
*** 4436,4442 ****
   static Lisp_Object accent_key_syms;
   static Lisp_Object func_key_syms;
   static Lisp_Object mouse_syms;
! #if defined(WINDOWSNT) || defined(MAC_OSX)
   static Lisp_Object mouse_wheel_syms;
   #endif
   static Lisp_Object drag_n_drop_syms;
--- 4437,4445 ----
   static Lisp_Object accent_key_syms;
   static Lisp_Object func_key_syms;
   static Lisp_Object mouse_syms;
! static Lisp_Object wheel_up_syms;
! static Lisp_Object wheel_down_syms;
! #if defined(MAC_OSX)
   static Lisp_Object mouse_wheel_syms;
   #endif
   static Lisp_Object drag_n_drop_syms;
***************
*** 4891,4898 ****
   #endif /* not HAVE_NTGUI */

   Lisp_Object Vlispy_mouse_stem;

! #if defined(WINDOWSNT) || defined(MAC_OSX)
   /* mouse-wheel events are generated by the wheel on devices such as
      the MS Intellimouse.  The wheel sits in between the left and right
      mouse buttons, and is typically used to scroll or zoom the window
--- 4894,4903 ----
   #endif /* not HAVE_NTGUI */

   Lisp_Object Vlispy_mouse_stem;
+ Lisp_Object Vlispy_wheel_up_stem;
+ Lisp_Object Vlispy_wheel_down_stem;

! #if defined(MAC_OSX)
   /* mouse-wheel events are generated by the wheel on devices such as
      the MS Intellimouse.  The wheel sits in between the left and right
      mouse buttons, and is typically used to scroll or zoom the window
***************
*** 5416,5421 ****
--- 5421,5623 ----
   	}
         }

+     case WHEEL_EVENT:
+       {
+ 	int button = event->code;
+ 	int is_double;
+ 	Lisp_Object position;
+ 	Lisp_Object window;
+         Lisp_Object head;
+
+ 	position = Qnil;
+
+ 	/* Build the position as appropriate for this mouse click.  */
+         enum window_part part;
+         struct frame *f = XFRAME (event->frame_or_window);
+         Lisp_Object posn;
+         Lisp_Object string_info = Qnil;
+         int row, column;
+         int wx, wy;
+
+         /* Ignore mouse events that were made on frame that
+            have been deleted.  */
+         if (! FRAME_LIVE_P (f))
+           return Qnil;
+
+         /* EVENT->x and EVENT->y are frame-relative pixel
+            coordinates at this place.  Under old redisplay, COLUMN
+            and ROW are set to frame relative glyph coordinates
+            which are then used to determine whether this click is
+            in a menu (non-toolkit version).  */
+         pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
+                                &column, &row, NULL, 1);
+
+         /* Set `window' to the window under frame pixel coordinates
+            event->x/event->y.  */
+         window = window_from_coordinates (f, XINT (event->x),
+                                           XINT (event->y),
+                                           &part, &wx, &wy, 0);
+
+         if (!WINDOWP (window))
+           {
+             window = event->frame_or_window;
+             posn = Qnil;
+           }
+         else
+           {
+             /* It's a click in window window at frame coordinates
+                event->x/ event->y.  */
+             struct window *w = XWINDOW (window);
+
+             /* Set event coordinates to window-relative coordinates
+                for constructing the Lisp event below.  */
+             XSETINT (event->x, wx);
+             XSETINT (event->y, wy);
+
+             if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
+               {
+                 /* Mode line or header line.  Look for a string under
+                    the mouse that may have a `local-map' property.  */
+                 Lisp_Object string;
+                 int charpos;
+
+                 posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line;
+                 string = mode_line_string (w, wx, wy, part, &charpos);
+                 if (STRINGP (string))
+                   string_info = Fcons (string, make_number (charpos));
+               }
+             else if (part == ON_VERTICAL_BORDER)
+               posn = Qvertical_line;
+             else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
+               {
+                 int charpos;
+                 Lisp_Object object = marginal_area_string (w, wx, wy, part,
+                                                            &charpos);
+                 posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
+                 if (STRINGP (object))
+                   string_info = Fcons (object, make_number (charpos));
+               }
+             else
+               {
+                 Lisp_Object object;
+                 struct display_pos p;
+                 buffer_posn_from_coords (w, &wx, &wy, &object, &p);
+                 posn = make_number (CHARPOS (p.pos));
+                 if (STRINGP (object))
+                   string_info
+                     = Fcons (object,
+                              make_number (CHARPOS (p.string_pos)));
+               }
+           }
+
+         position
+           = Fcons (window,
+                    Fcons (posn,
+                           Fcons (Fcons (event->x, event->y),
+                                  Fcons (make_number (event->timestamp),
+                                         (NILP (string_info)
+                                          ? Qnil
+                                          : Fcons (string_info, Qnil))))));
+
+         /* Set double or triple modifiers to indicate the wheel speed.  */
+ 	{
+ 	  /* On window-system frames, use the value of
+ 	     double-click-fuzz as is.  On other frames, interpret it
+ 	     as a multiple of 1/8 characters.  */
+ 	  struct frame *f;
+ 	  int fuzz;
+
+ 	  if (WINDOWP (event->frame_or_window))
+ 	    f = XFRAME (XWINDOW (event->frame_or_window)->frame);
+ 	  else if (FRAMEP (event->frame_or_window))
+ 	    f = XFRAME (event->frame_or_window);
+ 	  else
+ 	    abort ();
+
+ 	  if (FRAME_WINDOW_P (f))
+ 	    fuzz = double_click_fuzz;
+ 	  else
+ 	    fuzz = double_click_fuzz / 8;
+
+ 	  is_double = ((-button - 1) == last_mouse_button
+ 		       && (abs (XINT (event->x) - last_mouse_x) <= fuzz)
+ 		       && (abs (XINT (event->y) - last_mouse_y) <= fuzz)
+ 		       && button_down_time != 0
+ 		       && (EQ (Vdouble_click_time, Qt)
+ 			   || (INTEGERP (Vdouble_click_time)
+ 			       && ((int)(event->timestamp - button_down_time)
+ 				   < XINT (Vdouble_click_time)))));
+ 	}
+
+         if (is_double)
+           {
+             double_click_count++;
+             event->modifiers |= ((double_click_count > 2)
+                                  ? triple_modifier
+                                  : double_modifier);
+           }
+         else
+           {
+             double_click_count = 1;
+             event->modifiers |= click_modifier;
+           }
+         button_down_time = event->timestamp;
+         /* Use a negative value to distinguish wheel from mouse button.  */
+ 	last_mouse_button = -button - 1;
+ 	last_mouse_x = XINT (event->x);
+ 	last_mouse_y = XINT (event->y);
+
+ 	/* This is a wheel-down event.  */
+ 	if (event->modifiers & down_modifier)
+ 	  {
+ 	    event->modifiers &= ~down_modifier;
+
+             if (button >= ASIZE (wheel_down_syms))
+               wheel_down_syms = larger_vector (wheel_down_syms, button + 1, Qnil);
+
+             /* Get the symbol we should use for the wheel event.  */
+             head = modify_event_symbol (button,
+                                         event->modifiers,
+                                         Qmouse_click,
+                                         Vlispy_wheel_down_stem,
+                                         NULL,
+                                         &wheel_down_syms,
+                                         ASIZE (wheel_down_syms));
+ 	  }
+
+ 	/* This is a wheel-up event.  */
+ 	else if (event->modifiers & up_modifier)
+ 	  {
+ 	    event->modifiers &= ~up_modifier;
+
+             if (button >= ASIZE (wheel_up_syms))
+               wheel_up_syms = larger_vector (wheel_up_syms, button + 1, Qnil);
+
+             /* Get the symbol we should use for the wheel event.  */
+             head = modify_event_symbol (button,
+                                         event->modifiers,
+                                         Qmouse_click,
+                                         Vlispy_wheel_up_stem,
+                                         NULL,
+                                         &wheel_up_syms,
+                                         ASIZE (wheel_up_syms));
+           }
+ 	else
+ 	  /* Every wheel event should either have the down_modifier or
+              the up_modifier set.  */
+ 	  abort ();
+
+         if (event->modifiers & (double_modifier | triple_modifier))
+           return Fcons (head,
+                         Fcons (position,
+                                Fcons (make_number (double_click_count),
+                                       Qnil)));
+         else
+           return Fcons (head,
+                         Fcons (position,
+                                Qnil));
+       }
+
   #ifdef USE_TOOLKIT_SCROLL_BARS

         /* We don't have down and up events if using toolkit scroll bars,
***************
*** 10616,10621 ****
--- 10818,10827 ----

     Vlispy_mouse_stem = build_string ("mouse");
     staticpro (&Vlispy_mouse_stem);
+   Vlispy_wheel_up_stem = build_string ("wheel-up");
+   staticpro (&Vlispy_wheel_up_stem);
+   Vlispy_wheel_down_stem = build_string ("wheel-down");
+   staticpro (&Vlispy_wheel_down_stem);

     /* Tool-bars.  */
     QCimage = intern (":image");
***************
*** 10675,10681 ****
     staticpro (&Qfunction_key);
     Qmouse_click = intern ("mouse-click");
     staticpro (&Qmouse_click);
! #if defined(WINDOWSNT) || defined(MAC_OSX)
     Qmouse_wheel = intern ("mouse-wheel");
     staticpro (&Qmouse_wheel);
   #endif
--- 10881,10887 ----
     staticpro (&Qfunction_key);
     Qmouse_click = intern ("mouse-click");
     staticpro (&Qmouse_click);
! #if defined(MAC_OSX)
     Qmouse_wheel = intern ("mouse-wheel");
     staticpro (&Qmouse_wheel);
   #endif
***************
*** 10793,10798 ****
--- 10999,11008 ----
     staticpro (&button_down_location);
     mouse_syms = Fmake_vector (make_number (1), Qnil);
     staticpro (&mouse_syms);
+   wheel_down_syms = Fmake_vector (make_number (1), Qnil);
+   staticpro (&wheel_down_syms);
+   wheel_up_syms = Fmake_vector (make_number (1), Qnil);
+   staticpro (&wheel_up_syms);

     {
       int i;
***************
*** 10827,10838 ****
     func_key_syms = Qnil;
     staticpro (&func_key_syms);

! #if defined(WINDOWSNT) || defined(MAC_OSX)
     mouse_wheel_syms = Qnil;
     staticpro (&mouse_wheel_syms);
     drag_n_drop_syms = Qnil;
     staticpro (&drag_n_drop_syms);
- #endif

     unread_switch_frame = Qnil;
     staticpro (&unread_switch_frame);
--- 11037,11048 ----
     func_key_syms = Qnil;
     staticpro (&func_key_syms);

! #if defined(MAC_OSX)
     mouse_wheel_syms = Qnil;
     staticpro (&mouse_wheel_syms);
+ #endif
     drag_n_drop_syms = Qnil;
     staticpro (&drag_n_drop_syms);

     unread_switch_frame = Qnil;
     staticpro (&unread_switch_frame);
Index: src/termhooks.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/termhooks.h,v
retrieving revision 1.62
diff -c -r1.62 termhooks.h
*** src/termhooks.h	4 Feb 2003 14:03:13 -0000	1.62
--- src/termhooks.h	28 May 2003 22:04:13 -0000
***************
*** 240,245 ****
--- 240,255 ----
   				   the mouse click occurred in.
   				   .timestamp gives a timestamp (in
   				   milliseconds) for the click.  */
+   WHEEL_EVENT,			/* The wheel number is in .code; it must
+ 				   be >= 0.
+ 				   .modifiers holds the state of the
+ 				   modifier keys.
+ 				   .x and .y give the mouse position,
+ 				   in characters, within the window.
+ 				   .frame_or_window gives the frame
+ 				   the wheel event occurred in.
+ 				   .timestamp gives a timestamp (in
+ 				   milliseconds) for the event.  */
   #if defined(WINDOWSNT) || defined(MAC_OSX)
     MOUSE_WHEEL_EVENT,		/* A mouse-wheel event is generated
   				   on WINDOWSNT or MAC_OSX by a
Index: src/w32term.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32term.c,v
retrieving revision 1.192
diff -c -r1.192 w32term.c
*** src/w32term.c	27 May 2003 22:34:58 -0000	1.192
--- src/w32term.c	28 May 2003 22:04:50 -0000
***************
*** 2910,2925 ****
   }

   static Lisp_Object
! construct_mouse_wheel (result, msg, f)
        struct input_event *result;
        W32Msg *msg;
        struct frame *f;
   {
     POINT p;
!   result->kind = MOUSE_CLICK_EVENT;
!   result->code = (GET_WHEEL_DELTA_WPARAM (msg->msg.wParam) < 0) ? 4 : 3;
     result->timestamp = msg->msg.time;
!   result->modifiers = msg->dwModifiers;
     p.x = LOWORD (msg->msg.lParam);
     p.y = HIWORD (msg->msg.lParam);
     ScreenToClient (msg->msg.hwnd, &p);
--- 2910,2933 ----
   }

   static Lisp_Object
! construct_mouse_wheel (result, msg, f, button)
        struct input_event *result;
        W32Msg *msg;
        struct frame *f;
+      int button;
   {
     POINT p;
!   int scroll_dir;
!
!   result->kind = WHEEL_EVENT;
!   result->code = button;
     result->timestamp = msg->msg.time;
!   /* Use the up and down modifiers to indicate if the wheel was
!      scrolled up or down.  */
!   scroll_dir = (GET_WHEEL_DELTA_WPARAM (msg->msg.wParam) < 0) ?
!     up_modifier : down_modifier;
!
!   result->modifiers = (msg->dwModifiers | scroll_dir);
     p.x = LOWORD (msg->msg.lParam);
     p.y = HIWORD (msg->msg.lParam);
     ScreenToClient (msg->msg.hwnd, &p);
***************
*** 4389,4402 ****

   	case WM_MOUSEWHEEL:
   	  {
! 	    /* Convert each Windows mouse wheel event in a couple of
! 	       Emacs mouse click down/up events.  Scrolling the wheel up
! 	       is associated to mouse button 4 and scrolling the wheel
! 	       down to the mouse button 5.  */
! 	    int button;
! 	    int up;
!
! 	    up = msg.dwModifiers & up_modifier;

   	    if (dpyinfo->grabbed && last_mouse_frame
   		&& FRAME_LIVE_P (last_mouse_frame))
--- 4397,4409 ----

   	case WM_MOUSEWHEEL:
   	  {
! 	    /* Map each Windows mouse wheel event to an Emacs
! 	       wheel-up-1/down-1 event.
! 	       Assume there is only one mouse wheel button for now.  */
!
!             int button;
!
! 	    button = 0;

   	    if (dpyinfo->grabbed && last_mouse_frame
   		&& FRAME_LIVE_P (last_mouse_frame))
***************
*** 4426,4475 ****
   		     || f == dpyinfo->w32_focus_frame)
   		    && (numchars >= 1))
   		  {
! 		    if ( !up )
! 		      {
! 			/* Emit an Emacs mouse down message.  */
! 			msg.dwModifiers |= down_modifier;
! 			construct_mouse_wheel (bufp, &msg, f);
! 			bufp++;
! 			count++;
! 			numchars--;
!
! 			/* Push a simulated WM_MOUSEWHEEL up message.  */
! 			msg.dwModifiers &= ~down_modifier;
! 			msg.dwModifiers |= up_modifier;
! 			prepend_msg (&msg);
! 		      }
! 		    else
! 		      {
! 			/* Emit an Emacs mouse up message.  */
! 			construct_mouse_wheel (bufp, &msg, f);
! 			bufp++;
! 			count++;
! 			numchars--;
! 		      }
! 		  }
! 	      }
!
! 	    button = (GET_WHEEL_DELTA_WPARAM (msg.msg.wParam) < 0)? 4 : 3;
!
! 	    if (up)
! 	      {
! 		dpyinfo->grabbed &= ~ (1 << button);
! 	      }
! 	    else
! 	      {
! 		dpyinfo->grabbed |= (1 << button);
! 		last_mouse_frame = f;
! 		/* Ignore any mouse motion that happened
! 		   before this event; any subsequent mouse-movement
! 		   Emacs events should reflect only motion after
! 		   the ButtonPress.  */
! 		if (f != 0)
! 		  f->mouse_moved = 0;
!
! 		last_tool_bar_item = -1;
! 	      }
   	  }
   	  break;

--- 4433,4455 ----
   		     || f == dpyinfo->w32_focus_frame)
   		    && (numchars >= 1))
   		  {
!                     construct_mouse_wheel (bufp, &msg, f, button);
!                     bufp++;
!                     count++;
!                     numchars--;
!                   }
!               }
!
!             dpyinfo->grabbed |= (1 << button);
!             last_mouse_frame = f;
!             /* Ignore any mouse motion that happened
!                before this event; any subsequent mouse-movement
!                Emacs events should reflect only motion after
!                the ButtonPress.  */
!             if (f != 0)
!               f->mouse_moved = 0;
!
!             last_tool_bar_item = -1;
   	  }
   	  break;

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-28 22:18           ` David Ponce
@ 2003-05-29  7:33             ` Jason Rumney
  2003-05-30  0:50             ` Richard Stallman
  1 sibling, 0 replies; 20+ messages in thread
From: Jason Rumney @ 2003-05-29  7:33 UTC (permalink / raw)
  Cc: emacs-devel

David Ponce <david.ponce@wanadoo.fr> writes:

> My X and MAC skills are too limited, so I didn't updated xterm.c and
> macterm.c.  Sorry.

I think the best way to update the X implementation is to implement
Z-axis handling. Arbritrarily mapping mouse-4 and mouse-5 to wheel
events is likely to lose on some setups.

lisp/term/w32-win.el needs updating for the new events too. Once
Z-axis is implemented for X, mwheel.el can be updated for the new
events and the special case code in w32-win.el can disappear.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-28 22:18           ` David Ponce
  2003-05-29  7:33             ` Jason Rumney
@ 2003-05-30  0:50             ` Richard Stallman
  2003-05-30 12:14               ` David Ponce
  1 sibling, 1 reply; 20+ messages in thread
From: Richard Stallman @ 2003-05-30  0:50 UTC (permalink / raw)
  Cc: emacs-devel

    Like with mouse buttons, it will be possible to handle several wheels:
    wheel-up-1 and wheel-down-1 events are associated to the first wheel,
    wheel-up-2 and wheel-down-2 to the second wheel, etc..

I'd rather not add this complexity unless someone would actually want
it.  Emacs is already very complex; we should avoid adding any
complexity that isn't really needed.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Subject: w32 mouse wheel handling
  2003-05-30  0:50             ` Richard Stallman
@ 2003-05-30 12:14               ` David Ponce
  0 siblings, 0 replies; 20+ messages in thread
From: David Ponce @ 2003-05-30 12:14 UTC (permalink / raw)
  Cc: emacs-devel

Hi,

 >     Like with mouse buttons, it will be possible to handle several wheels:
 >     wheel-up-1 and wheel-down-1 events are associated to the first wheel,
 >     wheel-up-2 and wheel-down-2 to the second wheel, etc..
 >
 > I'd rather not add this complexity unless someone would actually want
 > it.  Emacs is already very complex; we should avoid adding any
 > complexity that isn't really needed.

OK, here is a new patch that introduce only the wheel-up and
wheel-down events.

I updated w32term.c to generate Emacs WHEEL_EVENTs from w32
WM_MOUSEWHEEL events.  I let MACOS and X gurus update macterm.c and
xterm.c ;-)

For now, to try the new code with mwheel, you need to customize
`mouse-wheel-down-event' and `mouse-wheel-up-event' to be respectively
wheel-up and wheel-down.

It appears there is a little inconsistency here, because mwheel seems
to assume that wheel events are scroll events.  IMO it don't make
sense to generate a wheel-down event when the wheel is rotated up and
a wheel-up event when the wheel is rotated down.

Perhaps `mwheel-scroll' could be changed to handle wheel-up/down
events more consistently?  That is scroll up on wheel-down and scroll
down on wheel-up.

Following is the change log and the patch.

Hope it will help.

Sincerely,
David

2003-05-30  David Ponce  <david@dponce.com>

	* termhooks.h (enum event_kind): Added new WHEEL_EVENT event.
	Declare MOUSE_WHEEL_EVENT only if MAC_OSX defined.

	* keyboard.c (Qmouse_wheel): Declare only if MAC_OSX defined.
	(mouse_wheel_syms, lispy_mouse_wheel_names): Likewise.
	(discard_mouse_events): Discard WHEEL_EVENT events too.
	(lispy_wheel_names, wheel_syms): New.
	(syms_of_keyboard): Init and staticpro `wheel_syms'.  Init and
	staticpro `Qmouse_wheel' and `mouse_wheel_syms' only if MAC_OSX
	defined.
	(make_lispy_event): Added WHEEL_EVENT handler.

	* w32term.c (construct_mouse_wheel): Construct WHEEL_EVENT.
	(w32_read_socket): Map w32 WM_MOUSEWHEEL events to Emacs
	WHEEL_EVENT events.

Index: src/keyboard.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/keyboard.c,v
retrieving revision 1.747
diff -c -r1.747 keyboard.c
*** src/keyboard.c	26 May 2003 22:55:45 -0000	1.747
--- src/keyboard.c	30 May 2003 11:43:25 -0000
***************
*** 547,553 ****
   /* Symbols to denote kinds of events.  */
   Lisp_Object Qfunction_key;
   Lisp_Object Qmouse_click;
! #if defined(WINDOWSNT) || defined(MAC_OSX)
   Lisp_Object Qmouse_wheel;
   #endif
   #ifdef WINDOWSNT
--- 547,553 ----
   /* Symbols to denote kinds of events.  */
   Lisp_Object Qfunction_key;
   Lisp_Object Qmouse_click;
! #if defined(MAC_OSX)
   Lisp_Object Qmouse_wheel;
   #endif
   #ifdef WINDOWSNT
***************
*** 3737,3742 ****
--- 3737,3743 ----
   	sp = kbd_buffer;

         if (sp->kind == MOUSE_CLICK_EVENT
+           || sp->kind == WHEEL_EVENT
   #ifdef WINDOWSNT
   	  || sp->kind == W32_SCROLL_BAR_CLICK_EVENT
   #endif
***************
*** 4436,4442 ****
   static Lisp_Object accent_key_syms;
   static Lisp_Object func_key_syms;
   static Lisp_Object mouse_syms;
! #if defined(WINDOWSNT) || defined(MAC_OSX)
   static Lisp_Object mouse_wheel_syms;
   #endif
   static Lisp_Object drag_n_drop_syms;
--- 4437,4444 ----
   static Lisp_Object accent_key_syms;
   static Lisp_Object func_key_syms;
   static Lisp_Object mouse_syms;
! static Lisp_Object wheel_syms;
! #if defined(MAC_OSX)
   static Lisp_Object mouse_wheel_syms;
   #endif
   static Lisp_Object drag_n_drop_syms;
***************
*** 4892,4898 ****

   Lisp_Object Vlispy_mouse_stem;

! #if defined(WINDOWSNT) || defined(MAC_OSX)
   /* mouse-wheel events are generated by the wheel on devices such as
      the MS Intellimouse.  The wheel sits in between the left and right
      mouse buttons, and is typically used to scroll or zoom the window
--- 4894,4905 ----

   Lisp_Object Vlispy_mouse_stem;

! static char *lispy_wheel_names[] =
! {
!   "wheel-up", "wheel-down"
! };
!
! #if defined(MAC_OSX)
   /* mouse-wheel events are generated by the wheel on devices such as
      the MS Intellimouse.  The wheel sits in between the left and right
      mouse buttons, and is typically used to scroll or zoom the window
***************
*** 5416,5421 ****
--- 5423,5614 ----
   	}
         }

+     case WHEEL_EVENT:
+       {
+ 	Lisp_Object position;
+ 	Lisp_Object window;
+ 	Lisp_Object head;
+
+ 	position = Qnil;
+
+ 	/* Build the position as appropriate for this mouse click.  */
+ 	enum window_part part;
+ 	struct frame *f = XFRAME (event->frame_or_window);
+ 	Lisp_Object posn;
+ 	Lisp_Object string_info = Qnil;
+ 	int row, column;
+ 	int wx, wy;
+
+ 	/* Ignore wheel events that were made on frame that have been
+ 	   deleted.  */
+ 	if (! FRAME_LIVE_P (f))
+ 	  return Qnil;
+ 	
+ 	/* EVENT->x and EVENT->y are frame-relative pixel
+ 	   coordinates at this place.  Under old redisplay, COLUMN
+ 	   and ROW are set to frame relative glyph coordinates
+ 	   which are then used to determine whether this click is
+ 	   in a menu (non-toolkit version).  */
+ 	pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
+ 			       &column, &row, NULL, 1);
+
+ 	/* Set `window' to the window under frame pixel coordinates
+ 	   event->x/event->y.  */
+ 	window = window_from_coordinates (f, XINT (event->x),
+ 					  XINT (event->y),
+ 					  &part, &wx, &wy, 0);
+
+ 	if (!WINDOWP (window))
+ 	  {
+ 	    window = event->frame_or_window;
+ 	    posn = Qnil;
+ 	  }
+ 	else
+ 	  {
+ 	    /* It's a click in window window at frame coordinates
+ 	       event->x/ event->y.  */
+ 	    struct window *w = XWINDOW (window);
+ 	
+ 	    /* Set event coordinates to window-relative coordinates
+ 	       for constructing the Lisp event below.  */
+ 	    XSETINT (event->x, wx);
+ 	    XSETINT (event->y, wy);
+ 	
+ 	    if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
+ 	      {
+ 		/* Mode line or header line.  Look for a string under
+ 		   the mouse that may have a `local-map' property.  */
+ 		Lisp_Object string;
+ 		int charpos;
+ 		
+ 		posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line;
+ 		string = mode_line_string (w, wx, wy, part, &charpos);
+ 		if (STRINGP (string))
+ 		  string_info = Fcons (string, make_number (charpos));
+ 	      }
+ 	    else if (part == ON_VERTICAL_BORDER)
+ 	      posn = Qvertical_line;
+ 	    else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
+ 	      {
+ 		int charpos;
+ 		Lisp_Object object = marginal_area_string (w, wx, wy, part,
+ 							   &charpos);
+ 		posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
+ 		if (STRINGP (object))
+ 		  string_info = Fcons (object, make_number (charpos));
+ 	      }
+ 	    else
+ 	      {
+ 		Lisp_Object object;
+ 		struct display_pos p;
+ 		buffer_posn_from_coords (w, &wx, &wy, &object, &p);
+ 		posn = make_number (CHARPOS (p.pos));
+ 		if (STRINGP (object))
+ 		  string_info
+ 		    = Fcons (object,
+ 			     make_number (CHARPOS (p.string_pos)));
+ 	      }
+ 	  }
+ 	
+ 	position
+ 	  = Fcons (window,
+ 		   Fcons (posn,
+ 			  Fcons (Fcons (event->x, event->y),
+ 				 Fcons (make_number (event->timestamp),
+ 					(NILP (string_info)
+ 					 ? Qnil
+ 					 : Fcons (string_info, Qnil))))));
+
+ 	/* Set double or triple modifiers to indicate the wheel speed.	*/
+ 	{
+ 	  /* On window-system frames, use the value of
+ 	     double-click-fuzz as is.  On other frames, interpret it
+ 	     as a multiple of 1/8 characters.  */
+ 	  struct frame *f;
+ 	  int fuzz;
+ 	  int is_double;
+
+ 	  if (WINDOWP (event->frame_or_window))
+ 	    f = XFRAME (XWINDOW (event->frame_or_window)->frame);
+ 	  else if (FRAMEP (event->frame_or_window))
+ 	    f = XFRAME (event->frame_or_window);
+ 	  else
+ 	    abort ();
+
+ 	  if (FRAME_WINDOW_P (f))
+ 	    fuzz = double_click_fuzz;
+ 	  else
+ 	    fuzz = double_click_fuzz / 8;
+
+ 	  is_double = (last_mouse_button < 0
+ 		       && (abs (XINT (event->x) - last_mouse_x) <= fuzz)
+ 		       && (abs (XINT (event->y) - last_mouse_y) <= fuzz)
+ 		       && button_down_time != 0
+ 		       && (EQ (Vdouble_click_time, Qt)
+ 			   || (INTEGERP (Vdouble_click_time)
+ 			       && ((int)(event->timestamp - button_down_time)
+ 				   < XINT (Vdouble_click_time)))));
+ 	  if (is_double)
+ 	    {
+ 	      double_click_count++;
+ 	      event->modifiers |= ((double_click_count > 2)
+ 				   ? triple_modifier
+ 				   : double_modifier);
+ 	    }
+ 	  else
+ 	    {
+ 	      double_click_count = 1;
+ 	      event->modifiers |= click_modifier;
+ 	    }
+ 	
+ 	  button_down_time = event->timestamp;
+ 	  /* Use a negative value to distinguish wheel from mouse button.  */
+ 	  last_mouse_button = -1;
+ 	  last_mouse_x = XINT (event->x);
+ 	  last_mouse_y = XINT (event->y);
+ 	}
+ 	
+ 	{
+ 	  int symbol_num;
+ 	
+ 	  if (event->modifiers & up_modifier)
+ 	    {
+ 	      /* Emit a wheel-up event.	 */
+ 	      event->modifiers &= ~up_modifier;
+ 	      symbol_num = 0;
+ 	    }
+ 	  else if (event->modifiers & down_modifier)
+ 	    {
+ 	      /* Emit a wheel-down event.  */
+ 	      event->modifiers &= ~down_modifier;
+ 	      symbol_num = 1;
+ 	    }
+ 	  else
+ 	    /* Every wheel event should either have the down_modifier or
+ 	       the up_modifier set.  */
+ 	    abort ();
+ 	
+ 	  /* Get the symbol we should use for the wheel event.	*/
+ 	  head = modify_event_symbol (symbol_num,
+ 				      event->modifiers,
+ 				      Qmouse_click,
+ 				      Qnil,
+ 				      lispy_wheel_names,
+ 				      &wheel_syms,
+ 				      ASIZE (wheel_syms));
+ 	}
+ 	
+ 	if (event->modifiers & (double_modifier | triple_modifier))
+ 	  return Fcons (head,
+ 			Fcons (position,
+ 			       Fcons (make_number (double_click_count),
+ 				      Qnil)));
+ 	else
+ 	  return Fcons (head,
+ 			Fcons (position,
+ 			       Qnil));
+       }
+
   #ifdef USE_TOOLKIT_SCROLL_BARS

         /* We don't have down and up events if using toolkit scroll bars,
***************
*** 10675,10681 ****
     staticpro (&Qfunction_key);
     Qmouse_click = intern ("mouse-click");
     staticpro (&Qmouse_click);
! #if defined(WINDOWSNT) || defined(MAC_OSX)
     Qmouse_wheel = intern ("mouse-wheel");
     staticpro (&Qmouse_wheel);
   #endif
--- 10868,10874 ----
     staticpro (&Qfunction_key);
     Qmouse_click = intern ("mouse-click");
     staticpro (&Qmouse_click);
! #if defined(MAC_OSX)
     Qmouse_wheel = intern ("mouse-wheel");
     staticpro (&Qmouse_wheel);
   #endif
***************
*** 10793,10798 ****
--- 10986,10993 ----
     staticpro (&button_down_location);
     mouse_syms = Fmake_vector (make_number (1), Qnil);
     staticpro (&mouse_syms);
+   wheel_syms = Fmake_vector (make_number (2), Qnil);
+   staticpro (&wheel_syms);

     {
       int i;
***************
*** 10827,10838 ****
     func_key_syms = Qnil;
     staticpro (&func_key_syms);

! #if defined(WINDOWSNT) || defined(MAC_OSX)
     mouse_wheel_syms = Qnil;
     staticpro (&mouse_wheel_syms);
     drag_n_drop_syms = Qnil;
     staticpro (&drag_n_drop_syms);
- #endif

     unread_switch_frame = Qnil;
     staticpro (&unread_switch_frame);
--- 11022,11033 ----
     func_key_syms = Qnil;
     staticpro (&func_key_syms);

! #if defined(MAC_OSX)
     mouse_wheel_syms = Qnil;
     staticpro (&mouse_wheel_syms);
+ #endif
     drag_n_drop_syms = Qnil;
     staticpro (&drag_n_drop_syms);

     unread_switch_frame = Qnil;
     staticpro (&unread_switch_frame);
Index: src/termhooks.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/termhooks.h,v
retrieving revision 1.62
diff -c -r1.62 termhooks.h
*** src/termhooks.h	4 Feb 2003 14:03:13 -0000	1.62
--- src/termhooks.h	30 May 2003 11:43:26 -0000
***************
*** 228,234 ****
   				   which the key was typed.
   				   .timestamp gives a timestamp (in
   				   milliseconds) for the keystroke.  */
!   TIMER_EVENT,                  /* A timer fired.  */
     MOUSE_CLICK_EVENT,		/* The button number is in .code; it must
   				   be >= 0 and < NUM_MOUSE_BUTTONS, defined
   				   below.
--- 228,234 ----
   				   which the key was typed.
   				   .timestamp gives a timestamp (in
   				   milliseconds) for the keystroke.  */
!   TIMER_EVENT,			/* A timer fired.  */
     MOUSE_CLICK_EVENT,		/* The button number is in .code; it must
   				   be >= 0 and < NUM_MOUSE_BUTTONS, defined
   				   below.
***************
*** 240,253 ****
   				   the mouse click occurred in.
   				   .timestamp gives a timestamp (in
   				   milliseconds) for the click.  */
! #if defined(WINDOWSNT) || defined(MAC_OSX)
!   MOUSE_WHEEL_EVENT,		/* A mouse-wheel event is generated
! 				   on WINDOWSNT or MAC_OSX by a
! 				   wheel on a mouse (e.g., MS Intellimouse).
! 				   The event contains a delta that corresponds
! 				   to the amount and direction that the wheel
! 				   is rotated.  This delta is typically
! 				   used to implement a scroll or zoom.
   				   .code gives the delta.
   				   .modifiers holds the state of the
   				   modifier keys.
--- 240,266 ----
   				   the mouse click occurred in.
   				   .timestamp gives a timestamp (in
   				   milliseconds) for the click.  */
!   WHEEL_EVENT,			/* A wheel event is generated by a
! 				   wheel on a mouse (e.g., MS
! 				   Intellimouse).
! 				   .modifiers holds the rotate
! 				   direction (up or down), and the
! 				   state of the modifier keys.
! 				   .x and .y give the mouse position,
! 				   in characters, within the window.
! 				   .frame_or_window gives the frame
! 				   the wheel event occurred in.
! 				   .timestamp gives a timestamp (in
! 				   milliseconds) for the event.  */
! #if defined(MAC_OSX)
!   MOUSE_WHEEL_EVENT,		/* A mouse-wheel event is generated on
! 				   MAC_OSX by a wheel on a mouse
! 				   (e.g., MS Intellimouse).  The event
! 				   contains a delta that corresponds
! 				   to the amount and direction that
! 				   the wheel is rotated.  This delta
! 				   is typically used to implement a
! 				   scroll or zoom.
   				   .code gives the delta.
   				   .modifiers holds the state of the
   				   modifier keys.
***************
*** 256,262 ****
   				   .frame_or_window gives the frame
   				   the wheel event occurred in.
   				   .timestamp gives a timestamp (in
! 				   milliseconds) for the wheel event.  */
   #endif
   #ifdef WINDOWSNT
     LANGUAGE_CHANGE_EVENT,	/* A LANGUAGE_CHANGE_EVENT is generated
--- 269,276 ----
   				   .frame_or_window gives the frame
   				   the wheel event occurred in.
   				   .timestamp gives a timestamp (in
! 				   milliseconds) for the wheel
! 				   event.  */
   #endif
   #ifdef WINDOWSNT
     LANGUAGE_CHANGE_EVENT,	/* A LANGUAGE_CHANGE_EVENT is generated
***************
*** 308,315 ****
   				   .timestamp gives a timestamp (in
   				   milliseconds) for the click.  */
     USER_SIGNAL_EVENT,		/* A user signal.
!                                    code is a number identifying it,
!                                    index into lispy_user_signals.  */

     /* Help events.  Member `frame_or_window' of the input_event is the
        frame on which the event occurred, and member `arg' contains
--- 322,329 ----
   				   .timestamp gives a timestamp (in
   				   milliseconds) for the click.  */
     USER_SIGNAL_EVENT,		/* A user signal.
! 				   code is a number identifying it,
! 				   index into lispy_user_signals.  */

     /* Help events.  Member `frame_or_window' of the input_event is the
        frame on which the event occurred, and member `arg' contains
Index: src/w32term.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/w32term.c,v
retrieving revision 1.192
diff -c -r1.192 w32term.c
*** src/w32term.c	27 May 2003 22:34:58 -0000	1.192
--- src/w32term.c	30 May 2003 11:44:01 -0000
***************
*** 2916,2925 ****
        struct frame *f;
   {
     POINT p;
!   result->kind = MOUSE_CLICK_EVENT;
!   result->code = (GET_WHEEL_DELTA_WPARAM (msg->msg.wParam) < 0) ? 4 : 3;
     result->timestamp = msg->msg.time;
!   result->modifiers = msg->dwModifiers;
     p.x = LOWORD (msg->msg.lParam);
     p.y = HIWORD (msg->msg.lParam);
     ScreenToClient (msg->msg.hwnd, &p);
--- 2916,2936 ----
        struct frame *f;
   {
     POINT p;
!   int delta;
!
!   result->kind = WHEEL_EVENT;
!   result->code = 0;
     result->timestamp = msg->msg.time;
!
!   /* A WHEEL_DELTA positive value indicates that the wheel was rotated
!      forward, away from the user (up); a negative value indicates that
!      the wheel was rotated backward, toward the user (down).  */
!   delta = GET_WHEEL_DELTA_WPARAM (msg->msg.wParam);
!
!   /* The up and down modifiers indicate if the wheel was rotated up or
!      down based on WHEEL_DELTA value.  */
!   result->modifiers = (msg->dwModifiers
!                        | ((delta < 0 ) ? down_modifier : up_modifier));
     p.x = LOWORD (msg->msg.lParam);
     p.y = HIWORD (msg->msg.lParam);
     ScreenToClient (msg->msg.hwnd, &p);
***************
*** 4389,4403 ****

   	case WM_MOUSEWHEEL:
   	  {
- 	    /* Convert each Windows mouse wheel event in a couple of
- 	       Emacs mouse click down/up events.  Scrolling the wheel up
- 	       is associated to mouse button 4 and scrolling the wheel
- 	       down to the mouse button 5.  */
- 	    int button;
- 	    int up;
-
- 	    up = msg.dwModifiers & up_modifier;
-
   	    if (dpyinfo->grabbed && last_mouse_frame
   		&& FRAME_LIVE_P (last_mouse_frame))
   	      f = last_mouse_frame;
--- 4400,4405 ----
***************
*** 4406,4475 ****

   	    if (f)
   	      {
- 		Lisp_Object window;
- 		POINT p;
- 		int x, y;
-
- 		p.x = LOWORD (msg.msg.lParam);
- 		p.y = HIWORD (msg.msg.lParam);
- 		ScreenToClient (msg.msg.hwnd, &p);
- 		x = XFASTINT (p.x);
- 		y = XFASTINT (p.y);
-
- 		window = window_from_coordinates (f, x, y, 0, 0, 0, 0);
-
- 		/* Ignore mouse wheel events not in a window.  */
- 		if (!WINDOWP(window))
- 		  break;
-
   		if ((!dpyinfo->w32_focus_frame
   		     || f == dpyinfo->w32_focus_frame)
   		    && (numchars >= 1))
   		  {
! 		    if ( !up )
! 		      {
! 			/* Emit an Emacs mouse down message.  */
! 			msg.dwModifiers |= down_modifier;
! 			construct_mouse_wheel (bufp, &msg, f);
! 			bufp++;
! 			count++;
! 			numchars--;
!
! 			/* Push a simulated WM_MOUSEWHEEL up message.  */
! 			msg.dwModifiers &= ~down_modifier;
! 			msg.dwModifiers |= up_modifier;
! 			prepend_msg (&msg);
! 		      }
! 		    else
! 		      {
! 			/* Emit an Emacs mouse up message.  */
! 			construct_mouse_wheel (bufp, &msg, f);
! 			bufp++;
! 			count++;
! 			numchars--;
! 		      }
   		  }
   	      }
!
! 	    button = (GET_WHEEL_DELTA_WPARAM (msg.msg.wParam) < 0)? 4 : 3;
!
! 	    if (up)
! 	      {
! 		dpyinfo->grabbed &= ~ (1 << button);
! 	      }
! 	    else
! 	      {
! 		dpyinfo->grabbed |= (1 << button);
! 		last_mouse_frame = f;
! 		/* Ignore any mouse motion that happened
! 		   before this event; any subsequent mouse-movement
! 		   Emacs events should reflect only motion after
! 		   the ButtonPress.  */
! 		if (f != 0)
! 		  f->mouse_moved = 0;
!
! 		last_tool_bar_item = -1;
! 	      }
   	  }
   	  break;

--- 4408,4431 ----

   	    if (f)
   	      {
   		if ((!dpyinfo->w32_focus_frame
   		     || f == dpyinfo->w32_focus_frame)
   		    && (numchars >= 1))
   		  {
! 		    /* Emit an Emacs wheel-up/down event.  */
! 		    construct_mouse_wheel (bufp, &msg, f);
! 		    bufp++;
! 		    count++;
! 		    numchars--;
   		  }
+ 		/* Ignore any mouse motion that happened before this
+ 		   event; any subsequent mouse-movement Emacs events
+ 		   should reflect only motion after the
+ 		   ButtonPress.	 */
+ 		f->mouse_moved = 0;
   	      }
! 	    last_mouse_frame = f;
! 	    last_tool_bar_item = -1;
   	  }
   	  break;

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2003-05-30 12:14 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-05-27  8:12 Subject: w32 mouse wheel handling David PONCE
2003-05-27  8:29 ` Juanma Barranquero
2003-05-27  8:45   ` Jason Rumney
2003-05-27  8:49     ` Juanma Barranquero
2003-05-27 22:41     ` Richard Stallman
2003-05-28  7:50       ` Oliver Scholz
2003-05-27 14:28   ` Stefan Monnier
  -- strict thread matches above, loose matches on Subject: below --
2003-05-23 14:47 David PONCE
2003-05-25  4:17 ` Michael Welsh Duggan
2003-05-25  8:34   ` David Ponce
2003-05-25 15:19   ` Stefan Monnier
2003-05-25 23:22     ` Kim F. Storm
2003-05-26  5:09       ` Kai Großjohann
2003-05-27 12:44         ` Richard Stallman
2003-05-28 22:18           ` David Ponce
2003-05-29  7:33             ` Jason Rumney
2003-05-30  0:50             ` Richard Stallman
2003-05-30 12:14               ` David Ponce
2003-05-26 13:30   ` Jason Rumney
2003-05-27  7:21 ` Jason Rumney

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).