lib: add MksScreenAttributes and mks_screen_configure()

MksScreenAttributes is an opaque type with setters so that we can
potentially extend it in the future without ABI issues.

Furthermore, this adds a configure API for both sync and async to
MksScreen.

Currently, I get NOT_SUPPORTED back from Qemu, but I think that's because
I'm not even past the bootloader/EFI stage for tests.
This commit is contained in:
Christian Hergert 2023-02-09 15:39:03 -08:00
parent 0478d202f8
commit 9bb71b8ea8
9 changed files with 401 additions and 14 deletions

View File

@ -32,6 +32,7 @@ G_BEGIN_DECLS
# include "mks-mouse.h"
# include "mks-paintable.h"
# include "mks-screen.h"
# include "mks-screen-attributes.h"
# include "mks-session.h"
# include "mks-types.h"
# include "mks-version.h"

View File

@ -5,6 +5,7 @@ libmks_sources = [
'mks-mouse.c',
'mks-paintable.c',
'mks-screen.c',
'mks-screen-attributes.c',
'mks-session.c',
]
@ -16,6 +17,7 @@ libmks_headers = [
'mks-mouse.h',
'mks-paintable.h',
'mks-screen.h',
'mks-screen-attributes.h',
'mks-session.h',
'mks-types.h',
]

View File

@ -30,6 +30,7 @@
#include "mks-qemu.h"
#include "mks-read-only-list-model-private.h"
#include "mks-screen.h"
#include "mks-screen-attributes.h"
#include "mks-session.h"
#include "mks-version.h"
@ -56,6 +57,7 @@ mks_init_gtypes (void)
g_type_ensure (MKS_TYPE_MOUSE);
g_type_ensure (MKS_TYPE_PAINTABLE);
g_type_ensure (MKS_TYPE_SCREEN);
g_type_ensure (MKS_TYPE_SCREEN_ATTRIBUTES);
g_type_ensure (MKS_TYPE_SESSION);
}

View File

@ -0,0 +1,38 @@
/*
* mks-screen-attributes-private.h
*
* Copyright 2023 Christian Hergert <chergert@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#pragma once
#include "mks-screen-attributes.h"
G_BEGIN_DECLS
struct _MksScreenAttributes
{
guint16 width_mm;
guint16 height_mm;
int x_offset;
int y_offset;
guint width;
guint height;
};
G_END_DECLS

115
lib/mks-screen-attributes.c Normal file
View File

@ -0,0 +1,115 @@
/*
* mks-screen-attributes.c
*
* Copyright 2023 Christian Hergert <chergert@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "config.h"
#include "mks-screen-attributes-private.h"
G_DEFINE_BOXED_TYPE (MksScreenAttributes,
mks_screen_attributes,
mks_screen_attributes_copy,
mks_screen_attributes_free)
/**
* mks_screen_attributes_new:
*
* Creates a new #MksScreenAttributes.
*
* Returns: (transfer full): A newly created #MksScreenAttributes
*/
MksScreenAttributes *
mks_screen_attributes_new (void)
{
return g_new0 (MksScreenAttributes, 1);
}
/**
* mks_screen_attributes_copy:
* @self: (nullable): a #MksScreenAttributes
*
* Makes a deep copy of a #MksScreenAttributes.
*
* Returns: (transfer full): A newly created #MksScreenAttributes with the same
* contents as @self. If @self is %NULL, %NULL is returned.
*/
MksScreenAttributes *
mks_screen_attributes_copy (MksScreenAttributes *self)
{
if (self == NULL)
return NULL;
return g_memdup2 (self, sizeof *self);
}
/**
* mks_screen_attributes_free:
* @self: a #MksScreenAttributes
*
* Frees a #MksScreenAttributes allocated using mks_screen_attributes_new()
* or mks_screen_attributes_copy().
*/
void
mks_screen_attributes_free (MksScreenAttributes *self)
{
g_free (self);
}
void
mks_screen_attributes_set_width_mm (MksScreenAttributes *self,
guint16 width_mm)
{
self->width_mm = width_mm;
}
void
mks_screen_attributes_set_height_mm (MksScreenAttributes *self,
guint16 height_mm)
{
self->height_mm = height_mm;
}
void
mks_screen_attributes_set_x_offset (MksScreenAttributes *self,
int x_offset)
{
self->x_offset = x_offset;
}
void
mks_screen_attributes_set_y_offset (MksScreenAttributes *self,
int y_offset)
{
self->y_offset = y_offset;
}
void
mks_screen_attributes_set_width (MksScreenAttributes *self,
guint width)
{
self->width = width;
}
void
mks_screen_attributes_set_height (MksScreenAttributes *self,
guint height)
{
self->height = height;
}

View File

@ -0,0 +1,66 @@
/*
* mks-screen-attributes.h
*
* Copyright 2023 Christian Hergert <chergert@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#pragma once
#if !defined(MKS_INSIDE) && !defined(MKS_COMPILATION)
# error "Only <libmks.h> can be included directly."
#endif
#include <glib-object.h>
#include "mks-types.h"
#include "mks-version-macros.h"
G_BEGIN_DECLS
#define MKS_TYPE_SCREEN_ATTRIBUTES (mks_screen_attributes_get_type ())
MKS_AVAILABLE_IN_ALL
GType mks_screen_attributes_get_type (void) G_GNUC_CONST;
MKS_AVAILABLE_IN_ALL
MksScreenAttributes *mks_screen_attributes_new (void);
MKS_AVAILABLE_IN_ALL
MksScreenAttributes *mks_screen_attributes_copy (MksScreenAttributes *self);
MKS_AVAILABLE_IN_ALL
void mks_screen_attributes_free (MksScreenAttributes *self);
MKS_AVAILABLE_IN_ALL
void mks_screen_attributes_set_width_mm (MksScreenAttributes *self,
guint16 width_mm);
MKS_AVAILABLE_IN_ALL
void mks_screen_attributes_set_height_mm (MksScreenAttributes *self,
guint16 height_mm);
MKS_AVAILABLE_IN_ALL
void mks_screen_attributes_set_x_offset (MksScreenAttributes *self,
int x_offset);
MKS_AVAILABLE_IN_ALL
void mks_screen_attributes_set_y_offset (MksScreenAttributes *self,
int y_offset);
MKS_AVAILABLE_IN_ALL
void mks_screen_attributes_set_width (MksScreenAttributes *self,
guint width);
MKS_AVAILABLE_IN_ALL
void mks_screen_attributes_set_height (MksScreenAttributes *self,
guint height);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MksScreenAttributes, mks_screen_attributes_free)
G_END_DECLS

View File

@ -26,6 +26,7 @@
#include "mks-qemu.h"
#include "mks-keyboard-private.h"
#include "mks-mouse-private.h"
#include "mks-screen-attributes-private.h"
#include "mks-screen-private.h"
struct _MksScreenClass
@ -409,3 +410,149 @@ mks_screen_get_device_address (MksScreen *self)
return NULL;
}
static gboolean
check_console (MksScreen *self,
GError **error)
{
if (self->console == NULL)
{
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_NOT_CONNECTED,
"Not connected");
return FALSE;
}
return TRUE;
}
static void
mks_screen_configure_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
MksQemuConsole *console = (MksQemuConsole *)object;
g_autoptr(GError) error = NULL;
g_autoptr(GTask) task = user_data;
g_assert (MKS_QEMU_IS_CONSOLE (console));
g_assert (G_IS_ASYNC_RESULT (result));
g_assert (G_IS_TASK (task));
if (!mks_qemu_console_call_set_uiinfo_finish (console, result, &error))
g_task_return_error (task, g_steal_pointer (&error));
else
g_task_return_boolean (task, TRUE);
}
/**
* mks_screen_configure_async:
* @self: an #MksScreen
* @attributes: (transfer full): a #MksScreenAttributes
* @cancellable: (nullable): a #GCancellable
* @callback: a #GAsyncReadyCallback to execute upon completion
* @user_data: closure data for @callback
*
* Requests the Qemu instance reconfigure the screen with @attributes.
*
* This function takes ownership of @attributes.
*
* @callback is executed upon acknowledgment from the Qemu instance or
* if the request timed out.
*
* Call mks_screen_configure_finish() to get the result.
*/
void
mks_screen_configure (MksScreen *self,
MksScreenAttributes *attributes,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_autoptr(GTask) task = NULL;
g_autoptr(GError) error = NULL;
g_return_if_fail (MKS_IS_SCREEN (self));
g_return_if_fail (attributes != NULL);
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_source_tag (task, mks_screen_configure);
if (!check_console (self, &error))
g_task_return_error (task, g_steal_pointer (&error));
else
mks_qemu_console_call_set_uiinfo (self->console,
attributes->width_mm,
attributes->height_mm,
attributes->x_offset,
attributes->y_offset,
attributes->width,
attributes->height,
cancellable,
mks_screen_configure_cb,
g_steal_pointer (&task));
mks_screen_attributes_free (attributes);
}
/**
* mks_screen_configure_finish:
* @self: an #MksScreen
* @result: a #GAsyncResult provided to callback
* @error: a location for a #GError, or %NULL
*
* Completes a call to mks_screen_configure().
*
* Returns: %TRUE if the operation completed successfully; otherwise %FALSE
* and @error is set.
*/
gboolean
mks_screen_configure_finish (MksScreen *self,
GAsyncResult *result,
GError **error)
{
g_return_val_if_fail (MKS_IS_SCREEN (self), FALSE);
g_return_val_if_fail (g_task_is_valid (result, self), FALSE);
return g_task_propagate_boolean (G_TASK (result), error);
}
/**
* mks_screen_configure_sync:
* @self: a #MksScreen
* @attributes: (transfer full): a #MksScreenAttributes
* @cancellable: a #GCancellable
* @error: a location for a #GError, or %NULL
*
* Requests the Qemu instance reconfigure the screen using @attributes.
*
* This function takes ownership of @attributes.
*
* Returns: %TRUE if the operation completed successfully; otherwise %FALSE
* and @error is set.
*/
gboolean
mks_screen_configure_sync (MksScreen *self,
MksScreenAttributes *attributes,
GCancellable *cancellable,
GError **error)
{
g_return_val_if_fail (MKS_IS_SCREEN (self), FALSE);
g_return_val_if_fail (attributes != NULL, FALSE);
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
if (!check_console (self, error))
return FALSE;
return mks_qemu_console_call_set_uiinfo_sync (self->console,
attributes->width_mm,
attributes->height_mm,
attributes->x_offset,
attributes->y_offset,
attributes->width,
attributes->height,
cancellable,
error);
}

View File

@ -25,7 +25,7 @@
# error "Only <libmks.h> can be included directly."
#endif
#include <glib-object.h>
#include <gio/gio.h>
#include "mks-types.h"
#include "mks-version-macros.h"
@ -51,19 +51,34 @@ typedef enum _MksScreenKind
MKS_AVAILABLE_IN_ALL
GType mks_screen_get_type (void) G_GNUC_CONST;
MKS_AVAILABLE_IN_ALL
MksScreenKind mks_screen_get_kind (MksScreen *self);
MksScreenKind mks_screen_get_kind (MksScreen *self);
MKS_AVAILABLE_IN_ALL
MksKeyboard *mks_screen_get_keyboard (MksScreen *self);
MksKeyboard *mks_screen_get_keyboard (MksScreen *self);
MKS_AVAILABLE_IN_ALL
MksMouse *mks_screen_get_mouse (MksScreen *self);
MksMouse *mks_screen_get_mouse (MksScreen *self);
MKS_AVAILABLE_IN_ALL
guint mks_screen_get_width (MksScreen *self);
guint mks_screen_get_width (MksScreen *self);
MKS_AVAILABLE_IN_ALL
guint mks_screen_get_height (MksScreen *self);
guint mks_screen_get_height (MksScreen *self);
MKS_AVAILABLE_IN_ALL
guint mks_screen_get_number (MksScreen *self);
guint mks_screen_get_number (MksScreen *self);
MKS_AVAILABLE_IN_ALL
const char *mks_screen_get_device_address (MksScreen *self);
const char *mks_screen_get_device_address (MksScreen *self);
MKS_AVAILABLE_IN_ALL
void mks_screen_configure (MksScreen *self,
MksScreenAttributes *attributes,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
MKS_AVAILABLE_IN_ALL
gboolean mks_screen_configure_finish (MksScreen *self,
GAsyncResult *result,
GError **error);
MKS_AVAILABLE_IN_ALL
gboolean mks_screen_configure_sync (MksScreen *self,
MksScreenAttributes *attributes,
GCancellable *cancellable,
GError **error);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MksScreen, g_object_unref)

View File

@ -29,15 +29,16 @@
G_BEGIN_DECLS
typedef struct _MksDevice MksDevice;
typedef struct _MksKeyboard MksKeyboard;
typedef struct _MksMouse MksMouse;
typedef struct _MksScreen MksScreen;
typedef struct _MksSession MksSession;
typedef struct _MksScreenAttributes MksScreenAttributes;
typedef struct _MksAudio MksAudio;
typedef struct _MksChardev MksChardev;
typedef struct _MksClipboard MksClipboard;
typedef struct _MksDevice MksDevice;
typedef struct _MksKeyboard MksKeyboard;
typedef struct _MksMouse MksMouse;
typedef struct _MksScreen MksScreen;
typedef struct _MksSerial MksSerial;
typedef struct _MksSession MksSession;
typedef struct _MksUsb MksUsb;
G_END_DECLS