Commit 5d64d770 authored by Eli Zaretskii's avatar Eli Zaretskii

Support mouse wheel on MS-Windows text-mode console.

 src/w32inevt.c (do_mouse_event): Support mouse wheel and all the 5
 standard mouse buttons.
 src/termhooks.h (struct input_event): Remove incorrect commentary.
parent 454e2fb9
2013-10-15 Eli Zaretskii <eliz@gnu.org>
* w32inevt.c (do_mouse_event): Support mouse wheel and all the 5
standard mouse buttons.
* termhooks.h (struct input_event): Remove incorrect commentary.
2013-10-15 Paul Eggert <eggert@cs.ucla.edu>
Disallow bool vector operations on mixed-length operands.
......
......@@ -243,7 +243,6 @@ struct input_event
For a mouse event, this is the button number.
For a HELP_EVENT, this is the position within the object
(stored in ARG below) where the help was found. */
/* In WindowsNT, for a mouse wheel event, this is the delta. */
ptrdiff_t code;
enum scroll_bar_part part;
......
......@@ -30,6 +30,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifndef MOUSE_MOVED
#define MOUSE_MOVED 1
#endif
#ifndef MOUSE_HWHEELED
#define MOUSE_HWHEELED 8
#endif
#include "lisp.h"
#include "keyboard.h"
......@@ -438,16 +441,16 @@ mouse_moved_to (int x, int y)
next - Leftmost+1
next - Leftmost+2...
Assume emacs likes three button mice, so
For the 3 standard buttons, we have:
Left == 0
Middle == 1
Right == 2
Others increase from there. */
#define NUM_TRANSLATED_MOUSE_BUTTONS 3
#define NUM_TRANSLATED_MOUSE_BUTTONS 5
static int emacs_button_translation[NUM_TRANSLATED_MOUSE_BUTTONS] =
{
0, 2, 1
0, 2, 1, 3, 4
};
static int
......@@ -456,100 +459,127 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
{
static DWORD button_state = 0;
static Lisp_Object last_mouse_window;
DWORD but_change, mask;
DWORD but_change, mask, flags = event->dwEventFlags;
int i;
if (event->dwEventFlags == MOUSE_MOVED)
switch (flags)
{
struct frame *f = SELECTED_FRAME ();
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
int mx = event->dwMousePosition.X, my = event->dwMousePosition.Y;
mouse_moved_to (mx, my);
if (f->mouse_moved)
{
if (hlinfo->mouse_face_hidden)
{
hlinfo->mouse_face_hidden = 0;
clear_mouse_face (hlinfo);
}
/* Generate SELECT_WINDOW_EVENTs when needed. */
if (!NILP (Vmouse_autoselect_window))
{
Lisp_Object mouse_window = window_from_coordinates (f, mx, my,
0, 0);
/* A window will be selected only when it is not
selected now, and the last mouse movement event was
not in it. A minibuffer window will be selected iff
it is active. */
if (WINDOWP (mouse_window)
&& !EQ (mouse_window, last_mouse_window)
&& !EQ (mouse_window, selected_window))
{
struct input_event event;
EVENT_INIT (event);
event.kind = SELECT_WINDOW_EVENT;
event.frame_or_window = mouse_window;
event.arg = Qnil;
event.timestamp = movement_time;
kbd_buffer_store_event (&event);
}
last_mouse_window = mouse_window;
}
else
last_mouse_window = Qnil;
previous_help_echo_string = help_echo_string;
help_echo_string = help_echo_object = help_echo_window = Qnil;
help_echo_pos = -1;
note_mouse_highlight (f, mx, my);
/* If the contents of the global variable help_echo has
changed (inside note_mouse_highlight), generate a HELP_EVENT. */
if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
gen_help_event (help_echo_string, selected_frame, help_echo_window,
help_echo_object, help_echo_pos);
}
return 0;
}
/* It looks like the console code sends us a mouse event with
dwButtonState == 0 when a window is activated. Ignore this case. */
if (event->dwButtonState == button_state)
return 0;
emacs_ev->kind = MOUSE_CLICK_EVENT;
/* Find out what button has changed state since the last button event. */
but_change = button_state ^ event->dwButtonState;
mask = 1;
for (i = 0; mask; i++, mask <<= 1)
if (but_change & mask)
case MOUSE_MOVED:
{
if (i < NUM_TRANSLATED_MOUSE_BUTTONS)
emacs_ev->code = emacs_button_translation[i];
else
emacs_ev->code = i;
break;
struct frame *f = get_frame ();
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
int mx = event->dwMousePosition.X, my = event->dwMousePosition.Y;
mouse_moved_to (mx, my);
if (f->mouse_moved)
{
if (hlinfo->mouse_face_hidden)
{
hlinfo->mouse_face_hidden = 0;
clear_mouse_face (hlinfo);
}
/* Generate SELECT_WINDOW_EVENTs when needed. */
if (!NILP (Vmouse_autoselect_window))
{
Lisp_Object mouse_window = window_from_coordinates (f, mx, my,
0, 0);
/* A window will be selected only when it is not
selected now, and the last mouse movement event was
not in it. A minibuffer window will be selected iff
it is active. */
if (WINDOWP (mouse_window)
&& !EQ (mouse_window, last_mouse_window)
&& !EQ (mouse_window, selected_window))
{
struct input_event event;
EVENT_INIT (event);
event.kind = SELECT_WINDOW_EVENT;
event.frame_or_window = mouse_window;
event.arg = Qnil;
event.timestamp = movement_time;
kbd_buffer_store_event (&event);
}
last_mouse_window = mouse_window;
}
else
last_mouse_window = Qnil;
previous_help_echo_string = help_echo_string;
help_echo_string = help_echo_object = help_echo_window = Qnil;
help_echo_pos = -1;
note_mouse_highlight (f, mx, my);
/* If the contents of the global variable help_echo has
changed (inside note_mouse_highlight), generate a HELP_EVENT. */
if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
gen_help_event (help_echo_string, selected_frame,
help_echo_window, help_echo_object,
help_echo_pos);
}
/* We alread called kbd_buffer_store_event, so indicate the
the caller it shouldn't. */
return 0;
}
case MOUSE_WHEELED:
case MOUSE_HWHEELED:
{
struct frame *f = get_frame ();
int mx = event->dwMousePosition.X, my = event->dwMousePosition.Y;
bool down_p = (event->dwButtonState & 0x10000000) != 0;
emacs_ev->kind =
flags == MOUSE_HWHEELED ? HORIZ_WHEEL_EVENT : WHEEL_EVENT;
emacs_ev->code = 0;
emacs_ev->modifiers = down_p ? down_modifier : up_modifier;
emacs_ev->modifiers |=
w32_kbd_mods_to_emacs (event->dwControlKeyState, 0);
XSETINT (emacs_ev->x, mx);
XSETINT (emacs_ev->y, my);
XSETFRAME (emacs_ev->frame_or_window, f);
emacs_ev->arg = Qnil;
emacs_ev->timestamp = GetTickCount ();
return 1;
}
case DOUBLE_CLICK:
default: /* mouse pressed or released */
/* It looks like the console code sends us a button-release
mouse event with dwButtonState == 0 when a window is
activated and when the mouse is first clicked. Ignore this
case. */
if (event->dwButtonState == button_state)
return 0;
button_state = event->dwButtonState;
emacs_ev->timestamp = GetTickCount ();
emacs_ev->modifiers = w32_kbd_mods_to_emacs (event->dwControlKeyState, 0) |
((event->dwButtonState & mask) ? down_modifier : up_modifier);
XSETFASTINT (emacs_ev->x, event->dwMousePosition.X);
XSETFASTINT (emacs_ev->y, event->dwMousePosition.Y);
/* for Mule 2.2 (Based on Emacs 19.28 */
#ifdef MULE
XSET (emacs_ev->frame_or_window, Lisp_Frame, get_frame ());
#else
XSETFRAME (emacs_ev->frame_or_window, get_frame ());
#endif
return 1;
emacs_ev->kind = MOUSE_CLICK_EVENT;
/* Find out what button has changed state since the last button
event. */
but_change = button_state ^ event->dwButtonState;
mask = 1;
for (i = 0; mask; i++, mask <<= 1)
if (but_change & mask)
{
if (i < NUM_TRANSLATED_MOUSE_BUTTONS)
emacs_ev->code = emacs_button_translation[i];
else
emacs_ev->code = i;
break;
}
button_state = event->dwButtonState;
emacs_ev->modifiers =
w32_kbd_mods_to_emacs (event->dwControlKeyState, 0)
| ((event->dwButtonState & mask) ? down_modifier : up_modifier);
XSETFASTINT (emacs_ev->x, event->dwMousePosition.X);
XSETFASTINT (emacs_ev->y, event->dwMousePosition.Y);
XSETFRAME (emacs_ev->frame_or_window, get_frame ());
emacs_ev->arg = Qnil;
emacs_ev->timestamp = GetTickCount ();
return 1;
}
}
static void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment