mirror of
https://gitlab.gnome.org/GNOME/libmks.git
synced 2024-12-22 05:35:21 +00:00
lib: set cursor from guest provided texture data
This commit is contained in:
parent
8dd08014b1
commit
5c52047800
@ -26,6 +26,7 @@
|
||||
#include "mks-display.h"
|
||||
#include "mks-keyboard.h"
|
||||
#include "mks-mouse.h"
|
||||
#include "mks-paintable-private.h"
|
||||
#include "mks-screen.h"
|
||||
#include "mks-util-private.h"
|
||||
|
||||
@ -42,6 +43,7 @@ typedef struct
|
||||
GdkPaintable *paintable;
|
||||
gulong invalidate_contents_handler;
|
||||
gulong invalidate_size_handler;
|
||||
gulong notify_cursor_handler;
|
||||
|
||||
/* Tracking the last known positions of mouse events so that we may
|
||||
* do something "reasonable" if the pointer is not absolute.
|
||||
@ -98,24 +100,39 @@ mks_display_get_paintable_area (MksDisplay *self,
|
||||
|
||||
static void
|
||||
mks_display_invalidate_contents_cb (MksDisplay *self,
|
||||
GdkPaintable *paintable)
|
||||
MksPaintable *paintable)
|
||||
{
|
||||
g_assert (MKS_IS_DISPLAY (self));
|
||||
g_assert (GDK_IS_PAINTABLE (paintable));
|
||||
g_assert (MKS_IS_PAINTABLE (paintable));
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
mks_display_invalidate_size_cb (MksDisplay *self,
|
||||
GdkPaintable *paintable)
|
||||
MksPaintable *paintable)
|
||||
{
|
||||
g_assert (MKS_IS_DISPLAY (self));
|
||||
g_assert (GDK_IS_PAINTABLE (paintable));
|
||||
g_assert (MKS_IS_PAINTABLE (paintable));
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
mks_display_notify_cursor_cb (MksDisplay *self,
|
||||
GParamSpec *pspec,
|
||||
MksPaintable *paintable)
|
||||
{
|
||||
GdkCursor *cursor;
|
||||
|
||||
g_assert (MKS_IS_DISPLAY (self));
|
||||
g_assert (MKS_IS_PAINTABLE (paintable));
|
||||
|
||||
cursor = _mks_paintable_get_cursor (paintable);
|
||||
|
||||
gtk_widget_set_cursor (GTK_WIDGET (self), cursor);
|
||||
}
|
||||
|
||||
static void
|
||||
mks_display_set_paintable (MksDisplay *self,
|
||||
GdkPaintable *paintable)
|
||||
@ -132,6 +149,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_object (&priv->paintable);
|
||||
}
|
||||
|
||||
@ -150,6 +168,12 @@ mks_display_set_paintable (MksDisplay *self,
|
||||
G_CALLBACK (mks_display_invalidate_size_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
priv->notify_cursor_handler =
|
||||
g_signal_connect_object (paintable,
|
||||
"notify::cursor",
|
||||
G_CALLBACK (mks_display_notify_cursor_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PAINTABLE]);
|
||||
|
@ -29,8 +29,9 @@ G_BEGIN_DECLS
|
||||
|
||||
G_DECLARE_FINAL_TYPE (MksPaintable, mks_paintable, MKS, PAINTABLE, GObject)
|
||||
|
||||
GdkPaintable *_mks_paintable_new (GCancellable *cancellable,
|
||||
int *peer_fd,
|
||||
GError **error);
|
||||
GdkPaintable *_mks_paintable_new (GCancellable *cancellable,
|
||||
int *peer_fd,
|
||||
GError **error);
|
||||
GdkCursor *_mks_paintable_get_cursor (MksPaintable *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -39,10 +39,12 @@ struct _MksPaintable
|
||||
MksQemuListener *listener;
|
||||
GDBusConnection *connection;
|
||||
GdkPaintable *child;
|
||||
GdkCursor *cursor;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CURSOR,
|
||||
PROP_PAINTABLE,
|
||||
N_PROPS
|
||||
};
|
||||
@ -149,6 +151,7 @@ mks_paintable_dispose (GObject *object)
|
||||
g_clear_object (&self->listener);
|
||||
g_clear_object (&self->child);
|
||||
g_clear_object (&self->gl_context);
|
||||
g_clear_object (&self->cursor);
|
||||
|
||||
G_OBJECT_CLASS (mks_paintable_parent_class)->dispose (object);
|
||||
}
|
||||
@ -163,6 +166,10 @@ mks_paintable_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CURSOR:
|
||||
g_value_set_object (value, _mks_paintable_get_cursor (self));
|
||||
break;
|
||||
|
||||
case PROP_PAINTABLE:
|
||||
g_value_set_object (value, self->child);
|
||||
break;
|
||||
@ -180,6 +187,11 @@ mks_paintable_class_init (MksPaintableClass *klass)
|
||||
object_class->dispose = mks_paintable_dispose;
|
||||
object_class->get_property = mks_paintable_get_property;
|
||||
|
||||
properties [PROP_CURSOR] =
|
||||
g_param_spec_object ("cursor", NULL, NULL,
|
||||
GDK_TYPE_CURSOR,
|
||||
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
properties [PROP_PAINTABLE] =
|
||||
g_param_spec_object ("paintable", NULL, NULL,
|
||||
GDK_TYPE_PAINTABLE,
|
||||
@ -497,13 +509,43 @@ mks_paintable_listener_cursor_define (MksPaintable *self,
|
||||
int height,
|
||||
int hot_x,
|
||||
int hot_y,
|
||||
GVariant *bytes,
|
||||
GVariant *bytestring,
|
||||
MksQemuListener *listener)
|
||||
{
|
||||
g_autoptr(GBytes) bytes = NULL;
|
||||
g_autoptr(GdkTexture) texture = NULL;
|
||||
g_autoptr(GdkCursor) cursor = NULL;
|
||||
gsize data_len;
|
||||
|
||||
g_assert (MKS_IS_PAINTABLE (self));
|
||||
g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
|
||||
g_assert (MKS_QEMU_IS_LISTENER (listener));
|
||||
|
||||
if (width < 1 || width > 512 ||
|
||||
height < 1 || height > 512 ||
|
||||
!(bytes = g_variant_get_data_as_bytes (bytestring)))
|
||||
goto failure;
|
||||
|
||||
data_len = g_bytes_get_size (bytes);
|
||||
if (data_len != (4 * width * height))
|
||||
goto failure;
|
||||
|
||||
texture = gdk_memory_texture_new (width,
|
||||
height,
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
GDK_MEMORY_B8G8R8A8_PREMULTIPLIED,
|
||||
#else
|
||||
GDK_MEMORY_A8R8G8B8_PREMULTIPLIED,
|
||||
#endif
|
||||
bytes,
|
||||
width * 4);
|
||||
|
||||
cursor = gdk_cursor_new_from_texture (texture, hot_x, hot_y, NULL);
|
||||
|
||||
if (g_set_object (&self->cursor, cursor))
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CURSOR]);
|
||||
|
||||
failure:
|
||||
mks_qemu_listener_complete_cursor_define (listener, invocation);
|
||||
|
||||
return TRUE;
|
||||
@ -693,3 +735,19 @@ _mks_paintable_new (GCancellable *cancellable,
|
||||
|
||||
return GDK_PAINTABLE (g_steal_pointer (&self));
|
||||
}
|
||||
|
||||
/**
|
||||
* _mks_paintable_get_cursor:
|
||||
* @self: a #MksPaintable
|
||||
*
|
||||
* Gets the cursor as defined by the Qemu instance.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #GdkCursor or %NULL
|
||||
*/
|
||||
GdkCursor *
|
||||
_mks_paintable_get_cursor (MksPaintable *self)
|
||||
{
|
||||
g_return_val_if_fail (MKS_IS_PAINTABLE (self), NULL);
|
||||
|
||||
return self->cursor;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user