+ else if (msframe->button2_is_down)
+ {
+ msframe->button2_is_down = 0;
+ msframe->ignore_next_rbutton_up = 1;
+ mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP,
+ MAKEPOINTS (lParam),
+ wParam
+ &~ (MK_LBUTTON | MK_MBUTTON
+ | MK_RBUTTON),
+ GetMessageTime());
+ }
+ else
+ {
+ if (msframe->button2_need_rbutton)
+ {
+ msframe->button2_need_rbutton = 0;
+ mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
+ MAKEPOINTS (lParam),
+ wParam &~ MK_LBUTTON,
+ GetMessageTime());
+ }
+ mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONUP,
+ MAKEPOINTS (lParam),
+ wParam &~ MK_LBUTTON,
+ GetMessageTime());
+ }
+ break;
+
+ case WM_RBUTTONUP:
+ msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+ msframe->last_click_time = GetMessageTime();
+
+ KillTimer (hwnd, BUTTON_2_TIMER_ID);
+ msframe->button2_need_rbutton = 0;
+ if (msframe->ignore_next_rbutton_up)
+ {
+ msframe->ignore_next_rbutton_up = 0;
+ }
+ else if (msframe->button2_is_down)
+ {
+ msframe->button2_is_down = 0;
+ msframe->ignore_next_lbutton_up = 1;
+ mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP,
+ MAKEPOINTS (lParam),
+ wParam
+ &~ (MK_LBUTTON | MK_MBUTTON
+ | MK_RBUTTON),
+ GetMessageTime());
+ }
+ else
+ {
+ if (msframe->button2_need_lbutton)
+ {
+ msframe->button2_need_lbutton = 0;
+ mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
+ MAKEPOINTS (lParam),
+ wParam &~ MK_RBUTTON,
+ GetMessageTime());
+ }
+ mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONUP,
+ MAKEPOINTS (lParam),
+ wParam &~ MK_RBUTTON,
+ GetMessageTime());
+ }
+ break;
+
+ case WM_LBUTTONDOWN:
+ msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+
+ if (msframe->button2_need_lbutton)
+ {
+ KillTimer (hwnd, BUTTON_2_TIMER_ID);
+ msframe->button2_need_lbutton = 0;
+ msframe->button2_need_rbutton = 0;
+ if (mswindows_button2_near_enough (msframe->last_click_point,
+ MAKEPOINTS (lParam)))
+ {
+ mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN,
+ MAKEPOINTS (lParam),
+ wParam
+ &~ (MK_LBUTTON | MK_MBUTTON
+ | MK_RBUTTON),
+ GetMessageTime());
+ msframe->button2_is_down = 1;
+ }
+ else
+ {
+ mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
+ msframe->last_click_point,
+ msframe->last_click_mods
+ &~ MK_RBUTTON,
+ msframe->last_click_time);
+ mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
+ MAKEPOINTS (lParam),
+ wParam &~ MK_LBUTTON,
+ GetMessageTime());
+ }
+ }
+ else
+ {
+ mswindows_set_chord_timer (hwnd);
+ msframe->button2_need_rbutton = 1;
+ msframe->last_click_point = MAKEPOINTS (lParam);
+ msframe->last_click_mods = wParam;
+ }
+ msframe->last_click_time = GetMessageTime();
+ break;
+
+ case WM_RBUTTONDOWN:
+ msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+
+ if (msframe->button2_need_rbutton)
+ {
+ KillTimer (hwnd, BUTTON_2_TIMER_ID);
+ msframe->button2_need_lbutton = 0;
+ msframe->button2_need_rbutton = 0;
+ if (mswindows_button2_near_enough (msframe->last_click_point,
+ MAKEPOINTS (lParam)))
+ {
+ mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN,
+ MAKEPOINTS (lParam),
+ wParam
+ &~ (MK_LBUTTON | MK_MBUTTON
+ | MK_RBUTTON),
+ GetMessageTime());
+ msframe->button2_is_down = 1;
+ }
+ else
+ {
+ mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
+ msframe->last_click_point,
+ msframe->last_click_mods
+ &~ MK_LBUTTON,
+ msframe->last_click_time);
+ mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
+ MAKEPOINTS (lParam),
+ wParam &~ MK_RBUTTON,
+ GetMessageTime());
+ }
+ }
+ else
+ {
+ mswindows_set_chord_timer (hwnd);
+ msframe->button2_need_lbutton = 1;
+ msframe->last_click_point = MAKEPOINTS (lParam);
+ msframe->last_click_mods = wParam;
+ }
+ msframe->last_click_time = GetMessageTime();
+ break;
+
+ case WM_TIMER:
+ if (wParam == BUTTON_2_TIMER_ID)
+ {
+ msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+ KillTimer (hwnd, BUTTON_2_TIMER_ID);
+
+ if (msframe->button2_need_lbutton)
+ {
+ msframe->button2_need_lbutton = 0;
+ mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
+ msframe->last_click_point,
+ msframe->last_click_mods
+ &~ MK_RBUTTON,
+ msframe->last_click_time);
+ }
+ else if (msframe->button2_need_rbutton)
+ {
+ msframe->button2_need_rbutton = 0;
+ mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
+ msframe->last_click_point,
+ msframe->last_click_mods
+ &~ MK_LBUTTON,
+ msframe->last_click_time);
+ }
+ }
+ else
+ assert ("Spurious timer fired" == 0);
+ break;
+
+ case WM_MOUSEMOVE:
+ /* Optimization: don't report mouse movement while size is changing */
+ msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+ if (!msframe->sizing)
+ {
+ /* When waiting for the second mouse button to finish
+ button2 emulation, and have moved too far, just pretend
+ as if timer has expired. This improves drag-select feedback */
+ if ((msframe->button2_need_lbutton || msframe->button2_need_rbutton)
+ && !mswindows_button2_near_enough (msframe->last_click_point,
+ MAKEPOINTS (lParam)))
+ {
+ KillTimer (hwnd, BUTTON_2_TIMER_ID);
+ SendMessage (hwnd, WM_TIMER, BUTTON_2_TIMER_ID, 0);
+ }
+
+ emacs_event = Fmake_event (Qnil, Qnil);
+ event = XEVENT(emacs_event);
+
+ event->channel = mswindows_find_frame(hwnd);
+ event->timestamp = GetMessageTime();
+ event->event_type = pointer_motion_event;
+ event->event.motion.x = MAKEPOINTS(lParam).x;
+ event->event.motion.y = MAKEPOINTS(lParam).y;
+ event->event.motion.modifiers =
+ mswindows_modifier_state (NULL, wParam, 0);
+
+ mswindows_enqueue_dispatch_event (emacs_event);
+ }
+ break;
+
+ case WM_CANCELMODE:
+ ReleaseCapture ();
+ /* Queue a `cancel-mode-internal' misc user event, so mouse
+ selection would be canceled if any */
+ mswindows_enqueue_misc_user_event (mswindows_find_frame (hwnd),
+ Qcancel_mode_internal, Qnil);
+ break;
+
+ case WM_NOTIFY:
+ {
+ LPNMHDR nmhdr = (LPNMHDR)lParam;
+
+ if (nmhdr->code == TTN_NEEDTEXT)
+ {
+#ifdef HAVE_TOOLBARS
+ LPTOOLTIPTEXT tttext = (LPTOOLTIPTEXT)lParam;
+ Lisp_Object btext;
+
+ /* find out which toolbar */
+ frame = XFRAME (mswindows_find_frame (hwnd));
+ btext = mswindows_get_toolbar_button_text ( frame,
+ nmhdr->idFrom );
+
+ tttext->lpszText = NULL;
+ tttext->hinst = NULL;
+
+ if (!NILP(btext))
+ {
+ /* I think this is safe since the text will only go away
+ when the toolbar does...*/
+ LISP_STRING_TO_EXTERNAL (btext, tttext->lpszText, Qnative);
+ }