diff --git a/lib/mks-display.c b/lib/mks-display.c index 6971d17..5448bc0 100644 --- a/lib/mks-display.c +++ b/lib/mks-display.c @@ -44,6 +44,7 @@ typedef struct gulong invalidate_contents_handler; gulong invalidate_size_handler; gulong notify_cursor_handler; + gulong mouse_set_handler; /* Tracking the last known positions of mouse events so that we may * do something "reasonable" if the pointer is not absolute. @@ -133,6 +134,21 @@ mks_display_notify_cursor_cb (MksDisplay *self, gtk_widget_set_cursor (GTK_WIDGET (self), cursor); } +static void +mks_display_mouse_set_cb (MksDisplay *self, + int x, + int y, + MksPaintable *paintable) +{ + MksDisplayPrivate *priv = mks_display_get_instance_private (self); + + g_assert (MKS_IS_DISPLAY (self)); + g_assert (MKS_IS_PAINTABLE (paintable)); + + priv->last_mouse_x = x; + priv->last_mouse_y = y; +} + static void mks_display_set_paintable (MksDisplay *self, GdkPaintable *paintable) @@ -150,6 +166,7 @@ mks_display_set_paintable (MksDisplay *self, g_clear_signal_handler (&priv->invalidate_contents_handler, priv->paintable); g_clear_signal_handler (&priv->invalidate_size_handler, priv->paintable); g_clear_signal_handler (&priv->notify_cursor_handler, priv->paintable); + g_clear_signal_handler (&priv->mouse_set_handler, priv->paintable); g_clear_object (&priv->paintable); } @@ -174,6 +191,12 @@ mks_display_set_paintable (MksDisplay *self, G_CALLBACK (mks_display_notify_cursor_cb), self, G_CONNECT_SWAPPED); + priv->notify_cursor_handler = + g_signal_connect_object (paintable, + "mouse-set", + G_CALLBACK (mks_display_mouse_set_cb), + self, + G_CONNECT_SWAPPED); } g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PAINTABLE]); @@ -388,11 +411,8 @@ mks_display_legacy_event_cb (MksDisplay *self, if (gdk_event_get_axis (event, GDK_AXIS_X, &x) && gdk_event_get_axis (event, GDK_AXIS_Y, &y)) { - double delta_x = floor (x - priv->last_mouse_x) / area.size.width * guest_width; - double delta_y = floor (y - priv->last_mouse_y) / area.size.height * guest_height; - - priv->last_mouse_x = x; - priv->last_mouse_y = y; + double delta_x = priv->last_mouse_x - (x / area.size.width) * guest_width; + double delta_y = priv->last_mouse_y - (y / area.size.height) * guest_height; mks_mouse_move_by (mouse, delta_x, diff --git a/lib/mks-paintable-private.h b/lib/mks-paintable-private.h index 0cc841e..1daa418 100644 --- a/lib/mks-paintable-private.h +++ b/lib/mks-paintable-private.h @@ -29,9 +29,12 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (MksPaintable, mks_paintable, MKS, PAINTABLE, GObject) -GdkPaintable *_mks_paintable_new (GCancellable *cancellable, - int *peer_fd, - GError **error); -GdkCursor *_mks_paintable_get_cursor (MksPaintable *self); +GdkPaintable *_mks_paintable_new (GCancellable *cancellable, + int *peer_fd, + GError **error); +GdkCursor *_mks_paintable_get_cursor (MksPaintable *self); +void _mks_paintable_get_position (MksPaintable *self, + int *x, + int *y); G_END_DECLS diff --git a/lib/mks-paintable.c b/lib/mks-paintable.c index 7e6d9ca..21fa570 100644 --- a/lib/mks-paintable.c +++ b/lib/mks-paintable.c @@ -32,6 +32,8 @@ #include "mks-paintable-private.h" #include "mks-qemu.h" +#include "mks-marshal.h" + struct _MksPaintable { GObject parent_instance; @@ -40,6 +42,8 @@ struct _MksPaintable GDBusConnection *connection; GdkPaintable *child; GdkCursor *cursor; + int mouse_x; + int mouse_y; }; enum { @@ -49,7 +53,13 @@ enum { N_PROPS }; +enum { + MOUSE_SET, + N_SIGNALS +}; + static GParamSpec *properties [N_PROPS]; +static guint signals [N_SIGNALS]; static cairo_format_t _pixman_format_to_cairo_format (guint pixman_format) @@ -198,6 +208,18 @@ mks_paintable_class_init (MksPaintableClass *klass) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_properties (object_class, N_PROPS, properties); + + signals [MOUSE_SET] = + g_signal_new ("mouse-set", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + _mks_marshal_VOID__INT_INT, + G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); + g_signal_set_va_marshaller (signals [MOUSE_SET], + G_TYPE_FROM_CLASS (klass), + _mks_marshal_VOID__INT_INTv); } static void @@ -563,8 +585,13 @@ mks_paintable_listener_mouse_set (MksPaintable *self, g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); g_assert (MKS_QEMU_IS_LISTENER (listener)); + self->mouse_x = x; + self->mouse_y = y; + mks_qemu_listener_complete_mouse_set (listener, invocation); + g_signal_emit (self, signals[MOUSE_SET], 0, x, y); + return TRUE; }