diff --git a/lib/mks-keyboard.c b/lib/mks-keyboard.c index 09dc1df..99a1a80 100644 --- a/lib/mks-keyboard.c +++ b/lib/mks-keyboard.c @@ -56,6 +56,19 @@ enum { static GParamSpec *properties [N_PROPS]; +static void +mks_keyboard_set_modifiers (MksKeyboard *self, + MksKeyboardModifier modifiers) +{ + g_assert (MKS_IS_KEYBOARD (self)); + + if (self->modifiers != modifiers) + { + self->modifiers = modifiers; + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_MODIFIERS]); + } +} + static void mks_keyboard_keyboard_notify_cb (MksKeyboard *self, GParamSpec *pspec, @@ -68,10 +81,7 @@ mks_keyboard_keyboard_notify_cb (MksKeyboard *self, g_assert (MKS_QEMU_IS_KEYBOARD (keyboard)); if (strcmp (pspec->name, "modifiers") == 0) - { - self->modifiers = mks_qemu_keyboard_get_modifiers (keyboard); - g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_MODIFIERS]); - } + mks_keyboard_set_modifiers (self, mks_qemu_keyboard_get_modifiers (keyboard)); MKS_EXIT; } @@ -82,6 +92,7 @@ mks_keyboard_set_keyboard (MksKeyboard *self, { g_assert (MKS_IS_KEYBOARD (self)); g_assert (!keyboard || MKS_QEMU_IS_KEYBOARD (keyboard)); + g_assert (self->keyboard == NULL); if (g_set_object (&self->keyboard, keyboard)) { @@ -90,7 +101,7 @@ mks_keyboard_set_keyboard (MksKeyboard *self, G_CALLBACK (mks_keyboard_keyboard_notify_cb), self, G_CONNECT_SWAPPED); - self->modifiers = mks_qemu_keyboard_get_modifiers (keyboard); + mks_keyboard_set_modifiers (self, mks_qemu_keyboard_get_modifiers (keyboard)); } } diff --git a/lib/mks-mouse.c b/lib/mks-mouse.c index 9672507..eb24876 100644 --- a/lib/mks-mouse.c +++ b/lib/mks-mouse.c @@ -37,6 +37,8 @@ struct _MksMouse MksQemuMouse *mouse; double last_known_x; double last_known_y; + + guint is_absolute: 1; }; struct _MksMouseClass @@ -54,14 +56,53 @@ enum { static GParamSpec *properties [N_PROPS]; +static void +mks_mouse_set_is_absolute (MksMouse *self, + gboolean is_absolute) +{ + g_assert (MKS_IS_MOUSE (self)); + + if (self->is_absolute != is_absolute) + { + self->is_absolute = is_absolute; + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_IS_ABSOLUTE]); + } +} + +static void +mks_mouse_mouse_notify_cb (MksMouse *self, + GParamSpec *pspec, + MksQemuMouse *mouse) +{ + MKS_ENTRY; + + g_assert (MKS_IS_MOUSE (self)); + g_assert (pspec != NULL); + g_assert (MKS_QEMU_IS_MOUSE (mouse)); + + if (strcmp (pspec->name, "is-absolute") == 0) + mks_mouse_set_is_absolute (self, mks_qemu_mouse_get_is_absolute (mouse)); + + MKS_EXIT; +} + static void mks_mouse_set_mouse (MksMouse *self, MksQemuMouse *mouse) { g_assert (MKS_IS_MOUSE (self)); g_assert (MKS_QEMU_IS_MOUSE (mouse)); + g_assert (self->mouse == NULL); - g_set_object (&self->mouse, mouse); + if (g_set_object (&self->mouse, mouse)) + { + g_signal_connect_object (self->mouse, + "notify", + G_CALLBACK (mks_mouse_mouse_notify_cb), + self, + G_CONNECT_SWAPPED); + mks_mouse_set_is_absolute (self, mks_qemu_mouse_get_is_absolute (mouse)); + } } static gboolean @@ -156,10 +197,7 @@ mks_mouse_get_is_absolute (MksMouse *self) { g_return_val_if_fail (MKS_IS_MOUSE (self), FALSE); - if (self->mouse) - return mks_qemu_mouse_get_is_absolute (self->mouse); - - return FALSE; + return self->is_absolute; } static gboolean diff --git a/lib/mks-screen.c b/lib/mks-screen.c index 27cacb9..92b350c 100644 --- a/lib/mks-screen.c +++ b/lib/mks-screen.c @@ -76,8 +76,8 @@ enum { static GParamSpec *properties [N_PROPS]; static void -_mks_screen_set_width (MksScreen *self, - guint width) +mks_screen_set_width (MksScreen *self, + guint width) { g_assert (MKS_IS_SCREEN (self)); @@ -89,8 +89,8 @@ _mks_screen_set_width (MksScreen *self, } static void -_mks_screen_set_height (MksScreen *self, - guint height) +mks_screen_set_height (MksScreen *self, + guint height) { g_assert (MKS_IS_SCREEN (self)); @@ -102,8 +102,8 @@ _mks_screen_set_height (MksScreen *self, } static void -_mks_screen_set_number (MksScreen *self, - guint number) +mks_screen_set_number (MksScreen *self, + guint number) { g_assert (MKS_IS_SCREEN (self)); @@ -114,6 +114,26 @@ _mks_screen_set_number (MksScreen *self, } } +static void +mks_screen_set_type (MksScreen *self, + const char *type) +{ + MksScreenKind kind; + + g_assert (MKS_IS_SCREEN (self)); + + kind = MKS_SCREEN_KIND_TEXT; + + if (strcmp (type, "Graphic") == 0) + kind = MKS_SCREEN_KIND_GRAPHIC; + + if (kind != self->kind) + { + self->kind = kind; + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_KIND]); + } +} + static void mks_screen_console_notify_cb (MksScreen *self, GParamSpec *pspec, @@ -126,29 +146,13 @@ mks_screen_console_notify_cb (MksScreen *self, if (strcmp (pspec->name, "label") == 0) _mks_device_set_name (MKS_DEVICE (self), mks_qemu_console_get_label (console)); else if (strcmp (pspec->name, "width") == 0) - _mks_screen_set_width (self, mks_qemu_console_get_width (console)); + mks_screen_set_width (self, mks_qemu_console_get_width (console)); else if (strcmp (pspec->name, "height") == 0) - _mks_screen_set_height (self, mks_qemu_console_get_height (console)); + mks_screen_set_height (self, mks_qemu_console_get_height (console)); else if (strcmp (pspec->name, "number") == 0) - _mks_screen_set_number (self, mks_qemu_console_get_head (console)); + mks_screen_set_number (self, mks_qemu_console_get_head (console)); else if (strcmp (pspec->name, "type") == 0) - { - const char *type; - - if ((type = mks_qemu_console_get_type_ ((console)))) - { - MksScreenKind kind = MKS_SCREEN_KIND_TEXT; - - if (strcmp (type, "Graphic") == 0) - kind = MKS_SCREEN_KIND_GRAPHIC; - - if (kind != self->kind) - { - self->kind = kind; - g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_KIND]); - } - } - } + mks_screen_set_type (self, mks_qemu_console_get_type_ ((console))); } static void @@ -163,8 +167,6 @@ mks_screen_set_console (MksScreen *self, if (g_set_object (&self->console, console)) { - const char *type; - _mks_device_set_name (MKS_DEVICE (self), mks_qemu_console_get_label (console)); self->console_notify_handler = @@ -174,15 +176,10 @@ mks_screen_set_console (MksScreen *self, self, G_CONNECT_SWAPPED); - if ((type = mks_qemu_console_get_type_ ((console)))) - { - if (strcmp (type, "Graphic") == 0) - self->kind = MKS_SCREEN_KIND_GRAPHIC; - } - - self->width = mks_qemu_console_get_width (console); - self->height = mks_qemu_console_get_height (console); - self->number = mks_qemu_console_get_head (console); + mks_screen_set_type (self, mks_qemu_console_get_type_ ((console))); + mks_screen_set_width (self, mks_qemu_console_get_width (console)); + mks_screen_set_height (self, mks_qemu_console_get_height (console)); + mks_screen_set_number (self, mks_qemu_console_get_head (console)); } } diff --git a/lib/mks-session.c b/lib/mks-session.c index 788c6a7..87c5cbe 100644 --- a/lib/mks-session.c +++ b/lib/mks-session.c @@ -106,6 +106,9 @@ struct _MksSession */ MksQemuObject *vm_object; MksQemuVM *vm; + + char *name; + char *uuid; }; static void @@ -164,6 +167,26 @@ mks_session_add_device (MksSession *self, g_list_store_append (self->devices, device); } +static void +mks_session_set_name (MksSession *self, + const char *name) +{ + g_assert (MKS_IS_SESSION (self)); + + if (g_set_str (&self->name, name)) + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_NAME]); +} + +static void +mks_session_set_uuid (MksSession *self, + const char *uuid) +{ + g_assert (MKS_IS_SESSION (self)); + + if (g_set_str (&self->uuid, uuid)) + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_UUID]); +} + static void mks_session_vm_notify_cb (MksSession *self, GParamSpec *pspec, @@ -173,11 +196,10 @@ mks_session_vm_notify_cb (MksSession *self, g_assert (pspec != NULL); g_assert (MKS_QEMU_IS_VM (vm)); - if (0) {} - else if (strcmp (pspec->name, "name") == 0) - g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_NAME]); + if (strcmp (pspec->name, "name") == 0) + mks_session_set_name (self, mks_qemu_vm_get_name (vm)); else if (strcmp (pspec->name, "uuid") == 0) - g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_UUID]); + mks_session_set_uuid (self, mks_qemu_vm_get_uuid (vm)); } static void @@ -200,9 +222,8 @@ mks_session_set_vm (MksSession *self, G_CALLBACK (mks_session_vm_notify_cb), self, G_CONNECT_SWAPPED); - - g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_NAME]); - g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_UUID]); + mks_session_set_name (self, mks_qemu_vm_get_name (vm)); + mks_session_set_uuid (self, mks_qemu_vm_get_uuid (vm)); } static void @@ -286,6 +307,8 @@ mks_session_dispose (GObject *object) g_clear_object (&self->object_manager); g_clear_object (&self->vm); g_clear_object (&self->vm_object); + g_clear_pointer (&self->name, g_free); + g_clear_pointer (&self->uuid, g_free); G_OBJECT_CLASS (mks_session_parent_class)->dispose (object); } @@ -682,10 +705,7 @@ mks_session_get_uuid (MksSession *self) { g_return_val_if_fail (MKS_IS_SESSION (self), NULL); - if (self->vm != NULL) - return mks_qemu_vm_get_uuid (self->vm); - - return NULL; + return self->uuid; } /** @@ -699,10 +719,7 @@ mks_session_get_name (MksSession *self) { g_return_val_if_fail (MKS_IS_SESSION (self), NULL); - if (self->vm != NULL) - return mks_qemu_vm_get_name (self->vm); - - return NULL; + return self->name; } /** diff --git a/lib/mks-touchable.c b/lib/mks-touchable.c index 979b165..a550816 100644 --- a/lib/mks-touchable.c +++ b/lib/mks-touchable.c @@ -35,6 +35,7 @@ struct _MksTouchable { MksDevice parent_instance; MksQemuMultiTouch *touch; + int max_slots; }; struct _MksTouchableClass @@ -53,14 +54,55 @@ enum { static GParamSpec *properties [N_PROPS]; +static void +mks_touchable_set_max_slots (MksTouchable *self, + int max_slots) +{ + g_assert (MKS_IS_TOUCHABLE (self)); + // Per INPUT_EVENT_SLOTS_MIN / INPUT_EVENT_SLOTS_MAX in QEMU + g_assert (max_slots >= 0 && max_slots <= 10); + + if (self->max_slots != max_slots) + { + self->max_slots = max_slots; + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_MAX_SLOTS]); + } +} + +static void +mks_touchable_touch_notify_cb (MksTouchable *self, + GParamSpec *pspec, + MksQemuMultiTouch *touch) +{ + MKS_ENTRY; + + g_assert (MKS_IS_TOUCHABLE (self)); + g_assert (pspec != NULL); + g_assert (MKS_QEMU_IS_MULTI_TOUCH (touch)); + + if (strcmp (pspec->name, "max-slots") == 0) + mks_touchable_set_max_slots (self, mks_qemu_multi_touch_get_max_slots (touch)); + + MKS_EXIT; +} + static void mks_touchable_set_touch (MksTouchable *self, MksQemuMultiTouch *touch) { g_assert (MKS_IS_TOUCHABLE (self)); g_assert (!touch || MKS_QEMU_IS_MULTI_TOUCH (touch)); + g_assert (self->touch == NULL); - g_set_object (&self->touch, touch); + if (g_set_object (&self->touch, touch)) + { + g_signal_connect_object (self->touch, + "notify", + G_CALLBACK (mks_touchable_touch_notify_cb), + self, + G_CONNECT_SWAPPED); + mks_touchable_set_max_slots (self, mks_qemu_multi_touch_get_max_slots (touch)); + } } static gboolean @@ -133,7 +175,7 @@ mks_touchable_class_init (MksTouchableClass *klass) */ properties [PROP_MAX_SLOTS] = g_param_spec_int ("max-slots", NULL, NULL, - 0, G_MAXINT, 0, + 0, 10, 0, (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_properties (object_class, N_PROPS, properties); @@ -309,8 +351,5 @@ mks_touchable_get_max_slots (MksTouchable *self) { g_return_val_if_fail (MKS_IS_TOUCHABLE (self), 0); - if (self->touch) - return mks_qemu_multi_touch_get_max_slots (self->touch); - - return 0; + return self->max_slots; }