static int do_mouse_event (MOUSE_EVENT_RECORD *event, struct input_event *emacs_ev) { static DWORD button_state = 0; static Lisp_Object last_mouse_window; DWORD but_change, mask; int i; if (event->dwEventFlags == MOUSE_MOVED) { FRAME_PTR 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) { 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->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; }
static int do_mouse_event (MOUSE_EVENT_RECORD *event, struct input_event *emacs_ev) { static DWORD button_state = 0; static Lisp_Object last_mouse_window; DWORD but_change, mask, flags = event->dwEventFlags; int i; switch (flags) { case MOUSE_MOVED: { 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 already 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; 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; } }