mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-28 08:01:26 +00:00
Make channel client callbacks virtual functions
Rather than having an API to register client callbacks for each channel type, make them vfuncs. Since the client callbacks are registered identically for each channel of the same type, it doesn't make sense for to require these to be registered separately for each object. It's cleaner to have these be per-class properties, so they've been converted to virtual functions. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
This commit is contained in:
parent
fe52264204
commit
14403117b5
@ -75,6 +75,12 @@ enum {
|
||||
RED_PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE,
|
||||
};
|
||||
|
||||
/**
|
||||
* Migrate a client channel from a CursorChannel.
|
||||
* This is the equivalent of RedChannel client migrate callback.
|
||||
*/
|
||||
void cursor_channel_client_migrate(RedChannelClient *client);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* CURSOR_CHANNEL_CLIENT_H_ */
|
||||
|
||||
@ -335,9 +335,12 @@ void cursor_channel_set_mouse_mode(CursorChannel *cursor, uint32_t mode)
|
||||
cursor->mouse_mode = mode;
|
||||
}
|
||||
|
||||
void cursor_channel_connect(CursorChannel *cursor, RedClient *client, RedStream *stream,
|
||||
int migrate,
|
||||
RedChannelCapabilities *caps)
|
||||
/**
|
||||
* Connect a new client to CursorChannel.
|
||||
*/
|
||||
static void
|
||||
cursor_channel_connect(CursorChannel *cursor, RedClient *client, RedStream *stream,
|
||||
int migrate, RedChannelCapabilities *caps)
|
||||
{
|
||||
CursorChannelClient *ccc;
|
||||
|
||||
@ -392,6 +395,10 @@ cursor_channel_class_init(CursorChannelClass *klass)
|
||||
channel_class->handle_message = red_channel_client_handle_message;
|
||||
|
||||
channel_class->send_item = cursor_channel_send_item;
|
||||
|
||||
// client callbacks
|
||||
channel_class->connect = (channel_client_connect_proc) cursor_channel_connect;
|
||||
channel_class->migrate = cursor_channel_client_migrate;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@ -60,21 +60,6 @@ void cursor_channel_do_init (CursorChannel *cursor);
|
||||
void cursor_channel_process_cmd (CursorChannel *cursor, RedCursorCmd *cursor_cmd);
|
||||
void cursor_channel_set_mouse_mode(CursorChannel *cursor, uint32_t mode);
|
||||
|
||||
/**
|
||||
* Connect a new client to CursorChannel.
|
||||
*/
|
||||
void cursor_channel_connect (CursorChannel *cursor, RedClient *client,
|
||||
RedStream *stream,
|
||||
int migrate,
|
||||
RedChannelCapabilities *caps);
|
||||
|
||||
/**
|
||||
* Migrate a client channel from a CursorChannel.
|
||||
* This is the equivalent of RedChannel client migrate callback.
|
||||
* See comment on cursor_channel_new.
|
||||
*/
|
||||
void cursor_channel_client_migrate(RedChannelClient *client);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* CURSOR_CHANNEL_H_ */
|
||||
|
||||
@ -26,6 +26,12 @@
|
||||
|
||||
G_DEFINE_TYPE(DisplayChannel, display_channel, TYPE_COMMON_GRAPHICS_CHANNEL)
|
||||
|
||||
static void display_channel_connect(RedChannel *channel, RedClient *client,
|
||||
RedStream *stream, int migration,
|
||||
RedChannelCapabilities *caps);
|
||||
static void display_channel_disconnect(RedChannelClient *rcc);
|
||||
static void display_channel_migrate(RedChannelClient *rcc);
|
||||
|
||||
enum {
|
||||
PROP0,
|
||||
PROP_N_SURFACES,
|
||||
@ -2500,6 +2506,11 @@ display_channel_class_init(DisplayChannelClass *klass)
|
||||
channel_class->handle_migrate_data = handle_migrate_data;
|
||||
channel_class->handle_migrate_data_get_serial = handle_migrate_data_get_serial;
|
||||
|
||||
// client callbacks
|
||||
channel_class->connect = display_channel_connect;
|
||||
channel_class->disconnect = display_channel_disconnect;
|
||||
channel_class->migrate = display_channel_migrate;
|
||||
|
||||
g_object_class_install_property(object_class,
|
||||
PROP_N_SURFACES,
|
||||
g_param_spec_uint("n-surfaces",
|
||||
@ -2590,7 +2601,7 @@ void display_channel_update_qxl_running(DisplayChannel *display, bool running)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
display_channel_connect(RedChannel *channel, RedClient *client,
|
||||
RedStream *stream, int migration,
|
||||
RedChannelCapabilities *caps)
|
||||
@ -2613,7 +2624,7 @@ display_channel_connect(RedChannel *channel, RedClient *client,
|
||||
dcc_start(dcc);
|
||||
}
|
||||
|
||||
void display_channel_disconnect(RedChannelClient *rcc)
|
||||
static void display_channel_disconnect(RedChannelClient *rcc)
|
||||
{
|
||||
DisplayChannel *display = DISPLAY_CHANNEL(red_channel_client_get_channel(rcc));
|
||||
|
||||
@ -2640,7 +2651,7 @@ static void red_migrate_display(DisplayChannel *display, RedChannelClient *rcc)
|
||||
}
|
||||
}
|
||||
|
||||
void display_channel_migrate(RedChannelClient *rcc)
|
||||
static void display_channel_migrate(RedChannelClient *rcc)
|
||||
{
|
||||
DisplayChannel *display = DISPLAY_CHANNEL(red_channel_client_get_channel(rcc));
|
||||
red_migrate_display(display, rcc);
|
||||
|
||||
@ -159,11 +159,6 @@ void display_channel_reset_image_cache(DisplayChannel *self);
|
||||
void display_channel_debug_oom(DisplayChannel *display, const char *msg);
|
||||
|
||||
void display_channel_update_qxl_running(DisplayChannel *display, bool running);
|
||||
void display_channel_connect(RedChannel *channel, RedClient *client,
|
||||
RedStream *stream, int migration,
|
||||
RedChannelCapabilities *caps);
|
||||
void display_channel_disconnect(RedChannelClient *rcc);
|
||||
void display_channel_migrate(RedChannelClient *rcc);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@ -542,17 +542,12 @@ InputsChannel* inputs_channel_new(RedsState *reds)
|
||||
static void
|
||||
inputs_channel_constructed(GObject *object)
|
||||
{
|
||||
ClientCbs client_cbs = { NULL, };
|
||||
InputsChannel *self = INPUTS_CHANNEL(object);
|
||||
RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
|
||||
SpiceCoreInterfaceInternal *core = red_channel_get_core_interface(RED_CHANNEL(self));
|
||||
|
||||
G_OBJECT_CLASS(inputs_channel_parent_class)->constructed(object);
|
||||
|
||||
client_cbs.connect = inputs_connect;
|
||||
client_cbs.migrate = inputs_migrate;
|
||||
red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs);
|
||||
|
||||
red_channel_set_cap(RED_CHANNEL(self), SPICE_INPUTS_CAP_KEY_SCANCODE);
|
||||
reds_register_channel(reds, RED_CHANNEL(self));
|
||||
|
||||
@ -596,6 +591,10 @@ inputs_channel_class_init(InputsChannelClass *klass)
|
||||
channel_class->send_item = inputs_channel_send_item;
|
||||
channel_class->handle_migrate_data = inputs_channel_handle_migrate_data;
|
||||
channel_class->handle_migrate_flush_mark = inputs_channel_handle_migrate_flush_mark;
|
||||
|
||||
// client callbacks
|
||||
channel_class->connect = inputs_connect;
|
||||
channel_class->migrate = inputs_migrate;
|
||||
}
|
||||
|
||||
static SpiceKbdInstance* inputs_channel_get_keyboard(InputsChannel *inputs)
|
||||
|
||||
@ -264,15 +264,11 @@ static void
|
||||
main_channel_constructed(GObject *object)
|
||||
{
|
||||
MainChannel *self = MAIN_CHANNEL(object);
|
||||
ClientCbs client_cbs = { NULL, };
|
||||
|
||||
G_OBJECT_CLASS(main_channel_parent_class)->constructed(object);
|
||||
|
||||
red_channel_set_cap(RED_CHANNEL(self), SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE);
|
||||
red_channel_set_cap(RED_CHANNEL(self), SPICE_MAIN_CAP_SEAMLESS_MIGRATE);
|
||||
|
||||
client_cbs.migrate = main_channel_client_migrate;
|
||||
red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -295,6 +291,9 @@ main_channel_class_init(MainChannelClass *klass)
|
||||
channel_class->send_item = main_channel_client_send_item;
|
||||
channel_class->handle_migrate_flush_mark = main_channel_handle_migrate_flush_mark;
|
||||
channel_class->handle_migrate_data = main_channel_handle_migrate_data;
|
||||
|
||||
// client callbacks
|
||||
channel_class->migrate = main_channel_client_migrate;
|
||||
}
|
||||
|
||||
static int main_channel_connect_semi_seamless(MainChannel *main_channel)
|
||||
|
||||
@ -86,7 +86,6 @@ struct RedChannelPrivate
|
||||
RedChannelCapabilities local_caps;
|
||||
uint32_t migration_flags;
|
||||
|
||||
ClientCbs client_cbs;
|
||||
// TODO: when different channel_clients are in different threads
|
||||
// from Channel -> need to protect!
|
||||
pthread_t thread_id;
|
||||
@ -302,6 +301,10 @@ red_channel_class_init(RedChannelClass *klass)
|
||||
| G_PARAM_READWRITE
|
||||
| G_PARAM_CONSTRUCT_ONLY);
|
||||
g_object_class_install_property(object_class, PROP_DISPATCHER, spec);
|
||||
|
||||
klass->connect = red_channel_client_default_connect;
|
||||
klass->disconnect = red_channel_client_default_disconnect;
|
||||
klass->migrate = red_channel_client_default_migrate;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -311,10 +314,6 @@ red_channel_init(RedChannel *self)
|
||||
|
||||
red_channel_set_common_cap(self, SPICE_COMMON_CAP_MINI_HEADER);
|
||||
self->priv->thread_id = pthread_self();
|
||||
|
||||
self->priv->client_cbs.connect = red_channel_client_default_connect;
|
||||
self->priv->client_cbs.disconnect = red_channel_client_default_disconnect;
|
||||
self->priv->client_cbs.migrate = red_channel_client_default_migrate;
|
||||
}
|
||||
|
||||
// utility to avoid possible invalid function cast
|
||||
@ -380,20 +379,6 @@ const RedStatNode *red_channel_get_stat_node(RedChannel *channel)
|
||||
return &channel->priv->stat;
|
||||
}
|
||||
|
||||
void red_channel_register_client_cbs(RedChannel *channel, const ClientCbs *client_cbs)
|
||||
{
|
||||
spice_assert(client_cbs->connect || channel->priv->type == SPICE_CHANNEL_MAIN);
|
||||
channel->priv->client_cbs.connect = client_cbs->connect;
|
||||
|
||||
if (client_cbs->disconnect) {
|
||||
channel->priv->client_cbs.disconnect = client_cbs->disconnect;
|
||||
}
|
||||
|
||||
if (client_cbs->migrate) {
|
||||
channel->priv->client_cbs.migrate = client_cbs->migrate;
|
||||
}
|
||||
}
|
||||
|
||||
static void add_capability(uint32_t **caps, int *num_caps, uint32_t cap)
|
||||
{
|
||||
int nbefore, n;
|
||||
@ -518,9 +503,9 @@ static void handle_dispatcher_connect(void *opaque, void *payload)
|
||||
{
|
||||
RedMessageConnect *msg = payload;
|
||||
RedChannel *channel = msg->channel;
|
||||
RedChannelClass *klass = RED_CHANNEL_GET_CLASS(channel);
|
||||
|
||||
channel->priv->client_cbs.connect(channel, msg->client, msg->stream,
|
||||
msg->migration, &msg->caps);
|
||||
klass->connect(channel, msg->client, msg->stream, msg->migration, &msg->caps);
|
||||
g_object_unref(msg->client);
|
||||
red_channel_capabilities_reset(&msg->caps);
|
||||
}
|
||||
@ -531,7 +516,8 @@ void red_channel_connect(RedChannel *channel, RedClient *client,
|
||||
{
|
||||
if (channel->priv->dispatcher == NULL ||
|
||||
pthread_equal(pthread_self(), channel->priv->thread_id)) {
|
||||
channel->priv->client_cbs.connect(channel, client, stream, migration, caps);
|
||||
RedChannelClass *klass = RED_CHANNEL_GET_CLASS(channel);
|
||||
klass->connect(channel, client, stream, migration, caps);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -759,8 +745,9 @@ static void handle_dispatcher_migrate(void *opaque, void *payload)
|
||||
{
|
||||
RedMessageMigrate *msg = payload;
|
||||
RedChannel *channel = red_channel_client_get_channel(msg->rcc);
|
||||
RedChannelClass *klass = RED_CHANNEL_GET_CLASS(channel);
|
||||
|
||||
channel->priv->client_cbs.migrate(msg->rcc);
|
||||
klass->migrate(msg->rcc);
|
||||
g_object_unref(msg->rcc);
|
||||
}
|
||||
|
||||
@ -768,7 +755,8 @@ void red_channel_migrate_client(RedChannel *channel, RedChannelClient *rcc)
|
||||
{
|
||||
if (channel->priv->dispatcher == NULL ||
|
||||
pthread_equal(pthread_self(), channel->priv->thread_id)) {
|
||||
channel->priv->client_cbs.migrate(rcc);
|
||||
RedChannelClass *klass = RED_CHANNEL_GET_CLASS(channel);
|
||||
klass->migrate(rcc);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -785,15 +773,17 @@ static void handle_dispatcher_disconnect(void *opaque, void *payload)
|
||||
{
|
||||
RedMessageDisconnect *msg = payload;
|
||||
RedChannel *channel = red_channel_client_get_channel(msg->rcc);
|
||||
RedChannelClass *klass = RED_CHANNEL_GET_CLASS(channel);
|
||||
|
||||
channel->priv->client_cbs.disconnect(msg->rcc);
|
||||
klass->disconnect(msg->rcc);
|
||||
}
|
||||
|
||||
void red_channel_disconnect_client(RedChannel *channel, RedChannelClient *rcc)
|
||||
{
|
||||
if (channel->priv->dispatcher == NULL ||
|
||||
pthread_equal(pthread_self(), channel->priv->thread_id)) {
|
||||
channel->priv->client_cbs.disconnect(rcc);
|
||||
RedChannelClass *klass = RED_CHANNEL_GET_CLASS(channel);
|
||||
klass->disconnect(rcc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -63,16 +63,6 @@ typedef void (*channel_client_disconnect_proc)(RedChannelClient *base);
|
||||
typedef void (*channel_client_migrate_proc)(RedChannelClient *base);
|
||||
|
||||
|
||||
/*
|
||||
* callbacks that are triggered from client events.
|
||||
* They should be called from the thread that handles the RedClient
|
||||
*/
|
||||
typedef struct {
|
||||
channel_client_connect_proc connect;
|
||||
channel_client_disconnect_proc disconnect;
|
||||
channel_client_migrate_proc migrate;
|
||||
} ClientCbs;
|
||||
|
||||
static inline gboolean test_capability(const uint32_t *caps, int num_caps, uint32_t cap)
|
||||
{
|
||||
return VD_AGENT_HAS_CAPABILITY(caps, num_caps, cap);
|
||||
@ -107,6 +97,14 @@ struct RedChannelClass
|
||||
channel_handle_migrate_flush_mark_proc handle_migrate_flush_mark;
|
||||
channel_handle_migrate_data_proc handle_migrate_data;
|
||||
channel_handle_migrate_data_get_serial_proc handle_migrate_data_get_serial;
|
||||
|
||||
/*
|
||||
* callbacks that are triggered from client events.
|
||||
* They should be called from the thread that handles the RedClient
|
||||
*/
|
||||
channel_client_connect_proc connect;
|
||||
channel_client_disconnect_proc disconnect;
|
||||
channel_client_migrate_proc migrate;
|
||||
};
|
||||
|
||||
#define FOREACH_CLIENT(_channel, _data) \
|
||||
@ -122,7 +120,6 @@ void red_channel_remove_client(RedChannel *channel, RedChannelClient *rcc);
|
||||
|
||||
void red_channel_init_stat_node(RedChannel *channel, const RedStatNode *parent, const char *name);
|
||||
|
||||
void red_channel_register_client_cbs(RedChannel *channel, const ClientCbs *client_cbs);
|
||||
// caps are freed when the channel is destroyed
|
||||
void red_channel_set_common_cap(RedChannel *channel, uint32_t cap);
|
||||
void red_channel_set_cap(RedChannel *channel, uint32_t cap);
|
||||
|
||||
@ -695,12 +695,7 @@ stream_device_create_channel(StreamDevice *dev)
|
||||
g_return_if_fail(id >= 0);
|
||||
|
||||
StreamChannel *stream_channel = stream_channel_new(reds, id);
|
||||
|
||||
CursorChannel *cursor_channel = cursor_channel_new(reds, id, core, NULL);
|
||||
ClientCbs client_cbs = { NULL, };
|
||||
client_cbs.connect = (channel_client_connect_proc) cursor_channel_connect;
|
||||
client_cbs.migrate = cursor_channel_client_migrate;
|
||||
red_channel_register_client_cbs(RED_CHANNEL(cursor_channel), &client_cbs);
|
||||
|
||||
dev->stream_channel = stream_channel;
|
||||
dev->cursor_channel = cursor_channel;
|
||||
|
||||
@ -1144,12 +1144,6 @@ RedWorker* red_worker_new(QXLInstance *qxl)
|
||||
channel = RED_CHANNEL(worker->cursor_channel);
|
||||
red_channel_init_stat_node(channel, &worker->stat, "cursor_channel");
|
||||
|
||||
ClientCbs client_cursor_cbs = { NULL, };
|
||||
client_cursor_cbs.connect = (channel_client_connect_proc) cursor_channel_connect;
|
||||
client_cursor_cbs.disconnect = NULL;
|
||||
client_cursor_cbs.migrate = cursor_channel_client_migrate;
|
||||
red_channel_register_client_cbs(channel, &client_cursor_cbs);
|
||||
|
||||
// TODO: handle seamless migration. Temp, setting migrate to FALSE
|
||||
worker->display_channel = display_channel_new(reds, qxl, &worker->core, dispatcher,
|
||||
FALSE,
|
||||
@ -1159,12 +1153,6 @@ RedWorker* red_worker_new(QXLInstance *qxl)
|
||||
channel = RED_CHANNEL(worker->display_channel);
|
||||
red_channel_init_stat_node(channel, &worker->stat, "display_channel");
|
||||
|
||||
ClientCbs client_display_cbs = { NULL, };
|
||||
client_display_cbs.connect = display_channel_connect;
|
||||
client_display_cbs.disconnect = display_channel_disconnect;
|
||||
client_display_cbs.migrate = display_channel_migrate;
|
||||
red_channel_register_client_cbs(channel, &client_display_cbs);
|
||||
|
||||
return worker;
|
||||
}
|
||||
|
||||
|
||||
@ -535,13 +535,9 @@ red_smartcard_channel_constructed(GObject *object)
|
||||
{
|
||||
RedSmartcardChannel *self = RED_SMARTCARD_CHANNEL(object);
|
||||
RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
|
||||
ClientCbs client_cbs = { NULL, };
|
||||
|
||||
G_OBJECT_CLASS(red_smartcard_channel_parent_class)->constructed(object);
|
||||
|
||||
client_cbs.connect = smartcard_connect_client;
|
||||
red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs);
|
||||
|
||||
reds_register_channel(reds, RED_CHANNEL(self));
|
||||
}
|
||||
|
||||
@ -559,6 +555,8 @@ red_smartcard_channel_class_init(RedSmartcardChannelClass *klass)
|
||||
channel_class->handle_migrate_flush_mark = smartcard_channel_client_handle_migrate_flush_mark;
|
||||
channel_class->handle_migrate_data = smartcard_channel_client_handle_migrate_data;
|
||||
|
||||
// client callbacks
|
||||
channel_class->connect = smartcard_connect_client;
|
||||
}
|
||||
|
||||
static void smartcard_init(RedsState *reds)
|
||||
|
||||
@ -1377,16 +1377,11 @@ playback_channel_init(PlaybackChannel *self)
|
||||
static void
|
||||
playback_channel_constructed(GObject *object)
|
||||
{
|
||||
ClientCbs client_cbs = { NULL, };
|
||||
SndChannel *self = SND_CHANNEL(object);
|
||||
RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
|
||||
|
||||
G_OBJECT_CLASS(playback_channel_parent_class)->constructed(object);
|
||||
|
||||
client_cbs.connect = snd_set_playback_peer;
|
||||
client_cbs.migrate = snd_migrate_channel_client;
|
||||
red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs);
|
||||
|
||||
if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY)) {
|
||||
red_channel_set_cap(RED_CHANNEL(self), SPICE_PLAYBACK_CAP_CELT_0_5_1);
|
||||
}
|
||||
@ -1407,6 +1402,10 @@ playback_channel_class_init(PlaybackChannelClass *klass)
|
||||
channel_class->parser = spice_get_client_channel_parser(SPICE_CHANNEL_PLAYBACK, NULL);
|
||||
channel_class->handle_message = red_channel_client_handle_message;
|
||||
channel_class->send_item = playback_channel_send_item;
|
||||
|
||||
// client callbacks
|
||||
channel_class->connect = snd_set_playback_peer;
|
||||
channel_class->migrate = snd_migrate_channel_client;
|
||||
}
|
||||
|
||||
void snd_attach_playback(RedsState *reds, SpicePlaybackInstance *sin)
|
||||
@ -1427,16 +1426,11 @@ record_channel_init(RecordChannel *self)
|
||||
static void
|
||||
record_channel_constructed(GObject *object)
|
||||
{
|
||||
ClientCbs client_cbs = { NULL, };
|
||||
SndChannel *self = SND_CHANNEL(object);
|
||||
RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
|
||||
|
||||
G_OBJECT_CLASS(record_channel_parent_class)->constructed(object);
|
||||
|
||||
client_cbs.connect = snd_set_record_peer;
|
||||
client_cbs.migrate = snd_migrate_channel_client;
|
||||
red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs);
|
||||
|
||||
if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY)) {
|
||||
red_channel_set_cap(RED_CHANNEL(self), SPICE_RECORD_CAP_CELT_0_5_1);
|
||||
}
|
||||
@ -1457,6 +1451,10 @@ record_channel_class_init(RecordChannelClass *klass)
|
||||
channel_class->parser = spice_get_client_channel_parser(SPICE_CHANNEL_RECORD, NULL);
|
||||
channel_class->handle_message = record_channel_handle_message;
|
||||
channel_class->send_item = record_channel_send_item;
|
||||
|
||||
// client callbacks
|
||||
channel_class->connect = snd_set_record_peer;
|
||||
channel_class->migrate = snd_migrate_channel_client;
|
||||
}
|
||||
|
||||
void snd_attach_record(RedsState *reds, SpiceRecordInstance *sin)
|
||||
|
||||
@ -185,14 +185,10 @@ static void
|
||||
red_vmc_channel_constructed(GObject *object)
|
||||
{
|
||||
RedVmcChannel *self = RED_VMC_CHANNEL(object);
|
||||
ClientCbs client_cbs = { NULL, };
|
||||
RedsState *reds = red_channel_get_server(RED_CHANNEL(self));
|
||||
|
||||
G_OBJECT_CLASS(red_vmc_channel_parent_class)->constructed(object);
|
||||
|
||||
client_cbs.connect = spicevmc_connect;
|
||||
red_channel_register_client_cbs(RED_CHANNEL(self), &client_cbs);
|
||||
|
||||
red_channel_init_stat_node(RED_CHANNEL(self), NULL, "spicevmc");
|
||||
const RedStatNode *stat = red_channel_get_stat_node(RED_CHANNEL(self));
|
||||
stat_init_counter(&self->in_data, reds, stat, "in_data", TRUE);
|
||||
@ -723,6 +719,9 @@ red_vmc_channel_class_init(RedVmcChannelClass *klass)
|
||||
channel_class->send_item = spicevmc_red_channel_send_item;
|
||||
channel_class->handle_migrate_flush_mark = spicevmc_channel_client_handle_migrate_flush_mark;
|
||||
channel_class->handle_migrate_data = spicevmc_channel_client_handle_migrate_data;
|
||||
|
||||
// client callbacks
|
||||
channel_class->connect = spicevmc_connect;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@ -443,15 +443,11 @@ stream_channel_connect(RedChannel *red_channel, RedClient *red_client, RedStream
|
||||
static void
|
||||
stream_channel_constructed(GObject *object)
|
||||
{
|
||||
ClientCbs client_cbs = { NULL, };
|
||||
RedChannel *red_channel = RED_CHANNEL(object);
|
||||
RedsState *reds = red_channel_get_server(red_channel);
|
||||
|
||||
G_OBJECT_CLASS(stream_channel_parent_class)->constructed(object);
|
||||
|
||||
client_cbs.connect = stream_channel_connect;
|
||||
red_channel_register_client_cbs(red_channel, &client_cbs);
|
||||
|
||||
red_channel_set_cap(red_channel, SPICE_DISPLAY_CAP_MONITORS_CONFIG);
|
||||
red_channel_set_cap(red_channel, SPICE_DISPLAY_CAP_STREAM_REPORT);
|
||||
|
||||
@ -470,6 +466,7 @@ stream_channel_class_init(StreamChannelClass *klass)
|
||||
channel_class->handle_message = handle_message;
|
||||
|
||||
channel_class->send_item = stream_channel_send_item;
|
||||
channel_class->connect = stream_channel_connect;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@ -105,25 +105,14 @@ test_connect_client(RedChannel *channel, RedClient *client, RedStream *stream,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
red_test_channel_constructed(GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS(red_test_channel_parent_class)->constructed(object);
|
||||
|
||||
ClientCbs client_cbs = { .connect = test_connect_client, };
|
||||
red_channel_register_client_cbs(RED_CHANNEL(object), &client_cbs);
|
||||
}
|
||||
|
||||
static void
|
||||
red_test_channel_class_init(RedTestChannelClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
object_class->constructed = red_test_channel_constructed;
|
||||
|
||||
RedChannelClass *channel_class = RED_CHANNEL_CLASS(klass);
|
||||
channel_class->parser = spice_get_client_channel_parser(SPICE_CHANNEL_PORT, NULL);
|
||||
channel_class->handle_message = red_channel_client_handle_message;
|
||||
channel_class->send_item = test_channel_send_item;
|
||||
channel_class->connect = test_connect_client;
|
||||
}
|
||||
|
||||
static uint8_t *
|
||||
|
||||
Loading…
Reference in New Issue
Block a user