This uses GTK functionality, which makes some interactions non-obvious. --- src/channel-power.c | 89 +++++++++++++++++++++++++++++++++++++++++++++ src/channel-power.h | 68 ++++++++++++++++++++++++++++++++++ src/map-file-glib | 1 + src/meson.build | 2 + src/spice-channel.c | 4 ++ src/spice-client.h | 1 + 6 files changed, 165 insertions(+)
diff --git a/src/channel-power.c b/src/channel-power.c new file mode 100644 index 0000000..ad678f8 --- /dev/null +++ b/src/channel-power.c @@ -0,0 +1,89 @@ +/* + Copyright (C) 2026 Red Hat, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ +#include "config.h" + +#include "spice-client.h" +#include "spice-common.h" +#include "spice-channel-priv.h" + +/** + * SECTION:channel-power + * @short_description: control the power of the target system + * @title: Power Channel + * @section_id: + * @see_also: #SpiceChannel + * @stability: Experimental + * @include: spice-client.h + * + * TODO write description here + */ + +G_DEFINE_TYPE(SpicePowerChannel, spice_power_channel, SPICE_TYPE_CHANNEL) + +static void spice_power_channel_up(SpiceChannel *channel); +static void spice_power_channel_reset(SpiceChannel *channel, gboolean migrating); + +/* ------------------------------------------------------------------ */ + +static void spice_power_channel_init(SpicePowerChannel *channel) +{ + SPICE_DEBUG("spice_power_channel_init() called"); +} + +static void spice_power_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + SPICE_DEBUG("spice_power_get_property() called"); + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); +} + +static void spice_power_channel_finalize(GObject *obj) +{ + SPICE_DEBUG("spice_power_channel_finalize() called"); + if (G_OBJECT_CLASS(spice_power_channel_parent_class)->finalize) { + G_OBJECT_CLASS(spice_power_channel_parent_class)->finalize(obj); + } +} + +static void spice_power_channel_class_init(SpicePowerChannelClass *klass) +{ + SPICE_DEBUG("spice_power_channel_class_init() called"); + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass); + + gobject_class->finalize = spice_power_channel_finalize; + gobject_class->get_property = spice_power_get_property; + channel_class->channel_up = spice_power_channel_up; + channel_class->channel_reset = spice_power_channel_reset; +} + +/* ------------------------------------------------------------------ */ + +/* coroutine context */ +static void spice_power_channel_up(SpiceChannel *channel) +{ + SPICE_DEBUG("spice_power_channel_up() called"); +} + +static void spice_power_channel_reset(SpiceChannel *channel, gboolean migrating) +{ + SPICE_DEBUG("spice_power_channel_reset() called"); + + SPICE_CHANNEL_CLASS(spice_power_channel_parent_class)->channel_reset(channel, migrating); +} diff --git a/src/channel-power.h b/src/channel-power.h new file mode 100644 index 0000000..36a84c5 --- /dev/null +++ b/src/channel-power.h @@ -0,0 +1,68 @@ +/* + Copyright (C) 2026 Red Hat, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ +#ifndef __SPICE_CLIENT_POWER_CHANNEL_H__ +#define __SPICE_CLIENT_POWER_CHANNEL_H__ + +#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION) +#warning "Only <spice-client.h> can be included directly" +#endif + +#include "spice-client.h" + +G_BEGIN_DECLS + +#define SPICE_TYPE_POWER_CHANNEL (spice_power_channel_get_type()) +#define SPICE_POWER_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_POWER_CHANNEL, SpicePowerChannel)) +#define SPICE_POWER_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_POWER_CHANNEL, SpicePowerChannelClass)) +#define SPICE_IS_POWER_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_POWER_CHANNEL)) +#define SPICE_IS_POWER_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_POWER_CHANNEL)) +#define SPICE_POWER_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_POWER_CHANNEL, SpicePowerChannelClass)) + +typedef struct _SpicePowerChannel SpicePowerChannel; +typedef struct _SpicePowerChannelClass SpicePowerChannelClass; + +/** + * SpicePowerChannel: + * + * The #SpicePowerChannel struct is opaque and should not be accessed directly. + */ +struct _SpicePowerChannel { + SpiceChannel parent; + + /*< private >*/ + /* Do not add fields to this struct */ +}; + +/** + * SpicePowerChannelClass: + * @parent_class: Parent class. + * + * Class structure for #SpicePowerChannel. + */ +struct _SpicePowerChannelClass { + SpiceChannelClass parent_class; + + /*< private >*/ + /* Do not add fields to this struct */ +}; + +SPICE_GTK_AVAILABLE_IN_ALL +GType spice_power_channel_get_type(void); + +G_END_DECLS + +#endif /* __SPICE_CLIENT_POWER_CHANNEL_H__ */ diff --git a/src/map-file-glib b/src/map-file-glib index 24b3859..a4fd22f 100644 --- a/src/map-file-glib +++ b/src/map-file-glib @@ -106,6 +106,7 @@ spice_port_channel_write_finish; spice_port_event; spice_port_write_async; spice_port_write_finish; +spice_power_channel_get_type; spice_qmp_port_get; spice_qmp_port_get_type; spice_qmp_port_query_status_async; diff --git a/src/meson.build b/src/meson.build index d26e173..264b4b0 100644 --- a/src/meson.build +++ b/src/meson.build @@ -79,6 +79,7 @@ spice_client_glib_headers = [ 'channel-main.h', 'channel-playback.h', 'channel-port.h', + 'channel-power.h', 'channel-record.h', 'channel-smartcard.h', 'channel-usbredir.h', @@ -119,6 +120,7 @@ spice_client_glib_introspection_sources = [ 'channel-main.c', 'channel-playback.c', 'channel-port.c', + 'channel-power.c', 'channel-record.c', 'channel-smartcard.c', 'channel-usbredir.c', diff --git a/src/spice-channel.c b/src/spice-channel.c index 242886a..a536fed 100644 --- a/src/spice-channel.c +++ b/src/spice-channel.c @@ -2186,6 +2186,7 @@ static const char *to_string[] = { [ SPICE_CHANNEL_USBREDIR ] = "usbredir", [ SPICE_CHANNEL_PORT ] = "port", [ SPICE_CHANNEL_WEBDAV ] = "webdav", + [ SPICE_CHANNEL_POWER ] = "power", }; /** @@ -2322,6 +2323,9 @@ SpiceChannel *spice_channel_new(SpiceSession *s, int type, int id) case SPICE_CHANNEL_PORT: gtype = SPICE_TYPE_PORT_CHANNEL; break; + case SPICE_CHANNEL_POWER: + gtype = SPICE_TYPE_POWER_CHANNEL; + break; default: SPICE_DEBUG("unsupported channel kind: %s: %d", spice_channel_type_to_string(type), type); diff --git a/src/spice-client.h b/src/spice-client.h index b753f60..69543ad 100644 --- a/src/spice-client.h +++ b/src/spice-client.h @@ -45,6 +45,7 @@ #include "channel-usbredir.h" #include "channel-port.h" #include "channel-webdav.h" +#include "channel-power.h" #include "smartcard-manager.h" #include "usb-device-manager.h" -- 2.52.0
