session: create MksScreen from GDBusObject

This uses the object manager object instead of the proxy directly to
create the MksScreen instances.

We might want to move the object initialization to MksDevice since it
is likely to be copied across a number of device types.
This commit is contained in:
Christian Hergert 2023-02-09 01:36:54 -08:00
parent b976580e43
commit 353a6d905d
3 changed files with 59 additions and 86 deletions

View File

@ -23,16 +23,11 @@
#include <gio/gio.h> #include <gio/gio.h>
#include "mks-qemu.h"
#include "mks-screen.h" #include "mks-screen.h"
G_BEGIN_DECLS G_BEGIN_DECLS
void _mks_screen_new (GDBusConnection *connection, MksDevice *_mks_screen_new (MksQemuObject *object);
const char *object_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
MksScreen *_mks_screen_new_finish (GAsyncResult *result,
GError **error);
G_END_DECLS G_END_DECLS

View File

@ -32,6 +32,7 @@ struct _MksScreen
{ {
MksDevice parent_instance; MksDevice parent_instance;
MksQemuObject *console_object;
MksQemuConsole *console; MksQemuConsole *console;
gulong console_notify_handler; gulong console_notify_handler;
@ -86,6 +87,19 @@ _mks_screen_set_height (MksScreen *self,
} }
} }
static void
_mks_screen_set_number (MksScreen *self,
guint number)
{
g_assert (MKS_IS_SCREEN (self));
if (self->number != number)
{
self->number = number;
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_NUMBER]);
}
}
static void static void
mks_screen_console_notify_cb (MksScreen *self, mks_screen_console_notify_cb (MksScreen *self,
GParamSpec *pspec, GParamSpec *pspec,
@ -101,6 +115,8 @@ mks_screen_console_notify_cb (MksScreen *self,
_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) 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));
} }
static void static void
@ -109,12 +125,16 @@ mks_screen_set_console (MksScreen *self,
{ {
g_assert (MKS_IS_SCREEN (self)); g_assert (MKS_IS_SCREEN (self));
g_assert (!console || MKS_QEMU_IS_CONSOLE (console)); g_assert (!console || MKS_QEMU_IS_CONSOLE (console));
g_assert (self->console == NULL);
if (self->console != NULL)
return;
if (g_set_object (&self->console, console)) if (g_set_object (&self->console, console))
{ {
const char *type; const char *type;
_mks_device_set_name (MKS_DEVICE (self), mks_qemu_console_get_label (console));
self->console_notify_handler = self->console_notify_handler =
g_signal_connect_object (console, g_signal_connect_object (console,
"notify", "notify",
@ -145,6 +165,7 @@ mks_screen_dispose (GObject *object)
g_clear_object (&self->console); g_clear_object (&self->console);
} }
g_clear_object (&self->console_object);
g_clear_object (&self->keyboard); g_clear_object (&self->keyboard);
g_clear_object (&self->mouse); g_clear_object (&self->mouse);
@ -190,21 +211,6 @@ mks_screen_get_property (GObject *object,
} }
} }
static void
mks_screen_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MksScreen *self = MKS_SCREEN (object);
switch (prop_id)
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void static void
mks_screen_class_init (MksScreenClass *klass) mks_screen_class_init (MksScreenClass *klass)
{ {
@ -212,7 +218,6 @@ mks_screen_class_init (MksScreenClass *klass)
object_class->dispose = mks_screen_dispose; object_class->dispose = mks_screen_dispose;
object_class->get_property = mks_screen_get_property; object_class->get_property = mks_screen_get_property;
object_class->set_property = mks_screen_set_property;
properties [PROP_KEYBOARD] = properties [PROP_KEYBOARD] =
g_param_spec_object ("keyboard", NULL, NULL, g_param_spec_object ("keyboard", NULL, NULL,
@ -253,71 +258,31 @@ mks_screen_init (MksScreen *self)
{ {
} }
static void MksDevice *
mks_screen_new_cb (GObject *object, _mks_screen_new (MksQemuObject *object)
GAsyncResult *result,
gpointer user_data)
{ {
g_autoptr(MksQemuConsole) console = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(GTask) task = user_data;
MksScreen *self;
g_assert (G_IS_ASYNC_RESULT (result));
g_assert (G_IS_TASK (task));
self = g_task_get_source_object (task);
console = mks_qemu_console_proxy_new_finish (result, &error);
g_assert (MKS_IS_SCREEN (self));
g_assert (!console || MKS_QEMU_IS_CONSOLE (console));
mks_screen_set_console (self, console);
if (error)
g_task_return_error (task, g_steal_pointer (&error));
else
g_task_return_pointer (task, g_object_ref (self), g_object_unref);
}
void
_mks_screen_new (GDBusConnection *connection,
const char *object_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_autoptr(GTask) task = NULL;
g_autoptr(MksScreen) self = NULL; g_autoptr(MksScreen) self = NULL;
g_autolist(GDBusInterface) interfaces = NULL;
g_return_if_fail (G_IS_DBUS_CONNECTION (connection)); g_return_val_if_fail (MKS_QEMU_IS_OBJECT (object), NULL);
g_return_if_fail (object_path != NULL);
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
self = g_object_new (MKS_TYPE_SCREEN, NULL); self = g_object_new (MKS_TYPE_SCREEN, NULL);
task = g_task_new (self, cancellable, callback, user_data); self->console_object = g_object_ref (object);
g_task_set_source_tag (task, _mks_screen_new);
mks_qemu_console_proxy_new (connection, interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (object));
G_DBUS_PROXY_FLAGS_NONE,
"org.qemu",
object_path,
cancellable,
mks_screen_new_cb,
g_steal_pointer (&task));
}
MksScreen * for (const GList *iter = interfaces; iter; iter = iter->next)
_mks_screen_new_finish (GAsyncResult *result, {
GError **error) GDBusInterface *iface = iter->data;
{
MksScreen *ret;
g_return_val_if_fail (G_IS_TASK (result), NULL); if (MKS_QEMU_IS_CONSOLE (iface))
ret = g_task_propagate_pointer (G_TASK (result), error); mks_screen_set_console (self, MKS_QEMU_CONSOLE (iface));
g_return_val_if_fail (!ret || MKS_IS_SCREEN (ret), NULL); }
return ret; if (self->console == NULL)
return NULL;
return MKS_DEVICE (g_steal_pointer (&self));
} }
/** /**

View File

@ -24,6 +24,7 @@
#include "mks-device.h" #include "mks-device.h"
#include "mks-read-only-list-model-private.h" #include "mks-read-only-list-model-private.h"
#include "mks-qemu.h" #include "mks-qemu.h"
#include "mks-screen-private.h"
#include "mks-session.h" #include "mks-session.h"
/** /**
@ -144,13 +145,23 @@ mks_session_set_connection (MksSession *self,
g_assert (self->connection == NULL); g_assert (self->connection == NULL);
if (connection == NULL) if (connection == NULL)
{ g_critical ("%s created without a GDBusConnection, this cannot work.",
g_critical ("%s created without a GDBusConnection, this cannot work.", G_OBJECT_TYPE_NAME (self));
G_OBJECT_TYPE_NAME (self)); else
return; self->connection = g_object_ref (connection);
} }
self->connection = g_object_ref (connection); static void
mks_session_add_device (MksSession *self,
MksDevice *device)
{
g_assert (MKS_IS_SESSION (self));
g_assert (!device || MKS_IS_DEVICE (device));
if (device == NULL)
return;
g_list_store_append (self->devices, device);
} }
static void static void
@ -213,6 +224,8 @@ mks_session_object_manager_object_added_cb (MksSession *self,
if (MKS_QEMU_IS_VM (iface)) if (MKS_QEMU_IS_VM (iface))
mks_session_set_vm (self, object, MKS_QEMU_VM (iface)); mks_session_set_vm (self, object, MKS_QEMU_VM (iface));
else if (MKS_QEMU_IS_CONSOLE (iface))
mks_session_add_device (self, _mks_screen_new (object));
} }
} }