static void handle_motion_event (GdkWindow *window, const MirInputEvent *event) { const MirPointerEvent *pointer_event = mir_input_event_get_pointer_event (event); GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl); gdouble x, y; gboolean cursor_inside; guint button_state; guint modifier_state; guint32 event_time; GdkEventType event_type; guint changed_button_state; if (!pointer_event) return; _gdk_mir_window_impl_get_cursor_state (impl, &x, &y, &cursor_inside, &button_state); modifier_state = get_modifier_state (mir_pointer_event_modifiers (pointer_event), mir_pointer_event_get_button_state (pointer_event)); event_time = NANO_TO_MILLI (mir_input_event_get_event_time (event)); /* TODO: Remove once we have proper transient window support. */ if (mir_pointer_event_action (pointer_event) == mir_pointer_action_leave) { LeaveInfo info; info.x = x; info.y = y; info.time = event_time; info.except = window; /* Leave all transient children from leaf to root, except the root since we do it later. */ _gdk_mir_window_transient_children_foreach (window, leave_windows_except, &info); } else { LeaveInfo info; info.x = x; info.y = y; info.time = event_time; info.except = _gdk_mir_window_get_visible_transient_child (window, x, y, &x, &y); /* Leave all transient children from leaf to root, except the pointer window since we enter it. */ _gdk_mir_window_transient_children_foreach (window, leave_windows_except, &info); window = info.except; if (window) { /* Enter the pointer window. */ gboolean cursor_inside_pointer_window; impl = GDK_MIR_WINDOW_IMPL (window->impl); _gdk_mir_window_impl_get_cursor_state (impl, NULL, NULL, &cursor_inside_pointer_window, NULL); if (!cursor_inside_pointer_window) { generate_crossing_event (window, GDK_ENTER_NOTIFY, x, y, event_time); _gdk_mir_window_impl_set_cursor_state (impl, x, y, TRUE, mir_pointer_event_get_button_state (pointer_event)); } } } if (window) { gdouble new_x; gdouble new_y; gdouble hscroll; gdouble vscroll; /* Update which window has focus */ _gdk_mir_pointer_set_location (get_pointer (window), x, y, window, modifier_state); switch (mir_pointer_event_action (pointer_event)) { case mir_pointer_action_button_up: case mir_pointer_action_button_down: event_type = mir_pointer_event_action (pointer_event) == mir_pointer_action_button_down ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE; changed_button_state = button_state ^ mir_pointer_event_get_button_state (pointer_event); if (changed_button_state == 0 || (changed_button_state & mir_pointer_button_primary) != 0) generate_button_event (window, event_type, x, y, GDK_BUTTON_PRIMARY, modifier_state, event_time); if ((changed_button_state & mir_pointer_button_secondary) != 0) generate_button_event (window, event_type, x, y, GDK_BUTTON_SECONDARY, modifier_state, event_time); if ((changed_button_state & mir_pointer_button_tertiary) != 0) generate_button_event (window, event_type, x, y, GDK_BUTTON_MIDDLE, modifier_state, event_time); button_state = mir_pointer_event_get_button_state (pointer_event); break; case mir_pointer_action_motion: new_x = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_x); new_y = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_y); hscroll = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_hscroll); vscroll = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_vscroll); if (hscroll > 0.5 || vscroll > 0.5) generate_scroll_event (window, x, y, hscroll, vscroll, modifier_state, event_time); if (ABS (new_x - x) > 0.5 || ABS (new_y - y) > 0.5) generate_motion_event (window, new_x, new_y, modifier_state, event_time); break; case mir_pointer_action_leave: if (cursor_inside) { cursor_inside = FALSE; generate_crossing_event (window, GDK_LEAVE_NOTIFY, x, y, event_time); } break; default: break; } _gdk_mir_window_impl_set_cursor_state (impl, x, y, cursor_inside, button_state); } }
static void handle_motion_event (GdkWindow *window, const MirInputEvent *event) { const MirPointerEvent *pointer_event = mir_input_event_get_pointer_event (event); GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl); gdouble x, y; gboolean cursor_inside; guint button_state; guint new_button_state; guint modifier_state; guint32 event_time; GdkEventType event_type; guint changed_button_state; if (!pointer_event) return; _gdk_mir_window_impl_get_cursor_state (impl, &x, &y, &cursor_inside, &button_state); new_button_state = get_button_state (pointer_event); modifier_state = get_modifier_state (mir_pointer_event_modifiers (pointer_event), new_button_state); event_time = NANO_TO_MILLI (mir_input_event_get_event_time (event)); if (window) { gdouble new_x; gdouble new_y; gdouble hscroll; gdouble vscroll; /* Update which window has focus */ _gdk_mir_pointer_set_location (get_pointer (window), x, y, window, modifier_state); switch (mir_pointer_event_action (pointer_event)) { case mir_pointer_action_button_up: case mir_pointer_action_button_down: event_type = mir_pointer_event_action (pointer_event) == mir_pointer_action_button_down ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE; changed_button_state = button_state ^ new_button_state; if (changed_button_state == 0 || (changed_button_state & GDK_BUTTON1_MASK) != 0) generate_button_event (window, event_type, x, y, GDK_BUTTON_PRIMARY, modifier_state, event_time); if ((changed_button_state & GDK_BUTTON2_MASK) != 0) generate_button_event (window, event_type, x, y, GDK_BUTTON_MIDDLE, modifier_state, event_time); if ((changed_button_state & GDK_BUTTON3_MASK) != 0) generate_button_event (window, event_type, x, y, GDK_BUTTON_SECONDARY, modifier_state, event_time); button_state = new_button_state; break; case mir_pointer_action_motion: new_x = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_x); new_y = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_y); hscroll = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_hscroll); vscroll = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_vscroll); if (hscroll != 0.0 || vscroll != 0.0) generate_scroll_event (window, x, y, hscroll, vscroll, modifier_state, event_time); if (ABS (new_x - x) > 0.5 || ABS (new_y - y) > 0.5) { generate_motion_event (window, new_x, new_y, modifier_state, event_time); x = new_x; y = new_y; } break; case mir_pointer_action_enter: if (!cursor_inside) { cursor_inside = TRUE; generate_crossing_event (window, GDK_ENTER_NOTIFY, x, y, event_time); } break; case mir_pointer_action_leave: if (cursor_inside) { cursor_inside = FALSE; generate_crossing_event (window, GDK_LEAVE_NOTIFY, x, y, event_time); } break; default: break; } _gdk_mir_window_impl_set_cursor_state (impl, x, y, cursor_inside, button_state); } }