From: Eli Zaretskii Date: Tue, 15 Oct 2013 18:38:26 +0000 (+0300) Subject: Support mouse wheel on MS-Windows text-mode console. X-Git-Tag: emacs-24.3.90~173^2^2~42^2~45^2~387^2~1259 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=5d64d7704ec60bcc95084173336851c5822f8ca5;p=emacs.git 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. --- diff --git a/src/ChangeLog b/src/ChangeLog index b951c37a646..ece16c869c0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2013-10-15 Eli Zaretskii + + * 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 Disallow bool vector operations on mixed-length operands. diff --git a/src/termhooks.h b/src/termhooks.h index 52f30b4bf98..a3977f5336e 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -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; diff --git a/src/w32inevt.c b/src/w32inevt.c index 3c41bec6bb5..c5d3fa3ad7d 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c @@ -30,6 +30,9 @@ along with GNU Emacs. If not, see . */ #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