mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-08-07 21:03:10 +00:00
Move RedCharDeviceCallbacks into RedCharDeviceClass
This structure holding virtual function pointers was kept until now as a RedCharDevice member in order to make the GObject conversion easier. Now that all RedCharDevice children are converted to GObject, it can be moved into RedCharDeviceClass.
This commit is contained in:
parent
87b6b9273d
commit
0c6e51011b
@ -69,7 +69,6 @@ struct RedCharDevicePrivate {
|
||||
int during_read_from_device;
|
||||
int during_write_to_device;
|
||||
|
||||
RedCharDeviceCallbacks cbs;
|
||||
void *opaque;
|
||||
SpiceServer *reds;
|
||||
};
|
||||
@ -106,21 +105,27 @@ typedef struct RedCharDeviceMsgToClientItem {
|
||||
static RedCharDeviceMsgToClient *
|
||||
red_char_device_read_one_msg_from_device(RedCharDevice *dev)
|
||||
{
|
||||
return dev->priv->cbs.read_one_msg_from_device(dev->priv->sin, dev->priv->opaque);
|
||||
RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
|
||||
|
||||
return klass->read_one_msg_from_device(dev->priv->sin, dev->priv->opaque);
|
||||
}
|
||||
|
||||
static RedCharDeviceMsgToClient *
|
||||
red_char_device_ref_msg_to_client(RedCharDevice *dev,
|
||||
RedCharDeviceMsgToClient *msg)
|
||||
{
|
||||
return dev->priv->cbs.ref_msg_to_client(msg, dev->priv->opaque);
|
||||
RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
|
||||
|
||||
return klass->ref_msg_to_client(msg, dev->priv->opaque);
|
||||
}
|
||||
|
||||
static void
|
||||
red_char_device_unref_msg_to_client(RedCharDevice *dev,
|
||||
RedCharDeviceMsgToClient *msg)
|
||||
{
|
||||
dev->priv->cbs.unref_msg_to_client(msg, dev->priv->opaque);
|
||||
RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
|
||||
|
||||
klass->unref_msg_to_client(msg, dev->priv->opaque);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -128,7 +133,9 @@ red_char_device_send_msg_to_client(RedCharDevice *dev,
|
||||
RedCharDeviceMsgToClient *msg,
|
||||
RedClient *client)
|
||||
{
|
||||
dev->priv->cbs.send_msg_to_client(msg, client, dev->priv->opaque);
|
||||
RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
|
||||
|
||||
klass->send_msg_to_client(msg, client, dev->priv->opaque);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -136,21 +143,27 @@ red_char_device_send_tokens_to_client(RedCharDevice *dev,
|
||||
RedClient *client,
|
||||
uint32_t tokens)
|
||||
{
|
||||
dev->priv->cbs.send_tokens_to_client(client, tokens, dev->priv->opaque);
|
||||
RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
|
||||
|
||||
klass->send_tokens_to_client(client, tokens, dev->priv->opaque);
|
||||
}
|
||||
|
||||
static void
|
||||
red_char_device_on_free_self_token(RedCharDevice *dev)
|
||||
{
|
||||
if (dev->priv->cbs.on_free_self_token != NULL) {
|
||||
dev->priv->cbs.on_free_self_token(dev->priv->opaque);
|
||||
RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
|
||||
|
||||
if (klass->on_free_self_token != NULL) {
|
||||
klass->on_free_self_token(dev->priv->opaque);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
red_char_device_remove_client(RedCharDevice *dev, RedClient *client)
|
||||
{
|
||||
dev->priv->cbs.remove_client(client, dev->priv->opaque);
|
||||
RedCharDeviceClass *klass = RED_CHAR_DEVICE_GET_CLASS(dev);
|
||||
|
||||
klass->remove_client(client, dev->priv->opaque);
|
||||
}
|
||||
|
||||
static void red_char_device_write_buffer_free(RedCharDeviceWriteBuffer *buf)
|
||||
@ -1234,17 +1247,3 @@ red_char_device_init(RedCharDevice *self)
|
||||
|
||||
g_signal_connect(self, "notify::sin", G_CALLBACK(red_char_device_on_sin_changed), NULL);
|
||||
}
|
||||
|
||||
/* TODO: needs to be moved to class vfuncs once all child classes are gobjects */
|
||||
void
|
||||
red_char_device_set_callbacks(RedCharDevice *dev,
|
||||
RedCharDeviceCallbacks *cbs,
|
||||
gpointer opaque)
|
||||
{
|
||||
g_assert(cbs->read_one_msg_from_device && cbs->ref_msg_to_client &&
|
||||
cbs->unref_msg_to_client && cbs->send_msg_to_client &&
|
||||
cbs->send_tokens_to_client && cbs->remove_client);
|
||||
|
||||
dev->priv->cbs = *cbs;
|
||||
dev->priv->opaque = opaque;
|
||||
}
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
#include "red-channel.h"
|
||||
#include "migration-protocol.h"
|
||||
|
||||
typedef void RedCharDeviceMsgToClient;
|
||||
|
||||
#define RED_TYPE_CHAR_DEVICE red_char_device_get_type()
|
||||
|
||||
#define RED_CHAR_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), RED_TYPE_CHAR_DEVICE, RedCharDevice))
|
||||
@ -48,15 +50,40 @@ struct SpiceCharDeviceState
|
||||
struct RedCharDeviceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
/*
|
||||
* Messages that are addressed to the client can be queued in case we have
|
||||
* multiple clients and some of them don't have enough tokens.
|
||||
*/
|
||||
|
||||
/* reads from the device till reaching a msg that should be sent to the client,
|
||||
* or till the reading fails */
|
||||
RedCharDeviceMsgToClient* (*read_one_msg_from_device)(SpiceCharDeviceInstance *sin,
|
||||
void *opaque);
|
||||
RedCharDeviceMsgToClient* (*ref_msg_to_client)(RedCharDeviceMsgToClient *msg,
|
||||
void *opaque);
|
||||
void (*unref_msg_to_client)(RedCharDeviceMsgToClient *msg,
|
||||
void *opaque);
|
||||
void (*send_msg_to_client)(RedCharDeviceMsgToClient *msg,
|
||||
RedClient *client,
|
||||
void *opaque); /* after this call, the message is unreferenced */
|
||||
|
||||
/* The cb is called when a predefined number of write buffers were consumed by the
|
||||
* device */
|
||||
void (*send_tokens_to_client)(RedClient *client, uint32_t tokens, void *opaque);
|
||||
|
||||
/* The cb is called when a server (self) message that was addressed to the device,
|
||||
* has been completely written to it */
|
||||
void (*on_free_self_token)(void *opaque);
|
||||
|
||||
/* This cb is called if it is recommanded that a client will be removed
|
||||
* due to slow flow or due to some other error.
|
||||
* The called instance should disconnect the client, or at least the corresponding channel */
|
||||
void (*remove_client)(RedClient *client, void *opaque);
|
||||
};
|
||||
|
||||
GType red_char_device_get_type(void) G_GNUC_CONST;
|
||||
|
||||
typedef struct RedCharDeviceCallbacks RedCharDeviceCallbacks;
|
||||
void red_char_device_set_callbacks(RedCharDevice *dev,
|
||||
RedCharDeviceCallbacks *cbs,
|
||||
gpointer opaque);
|
||||
|
||||
/*
|
||||
* Shared code for char devices, mainly for flow control.
|
||||
*
|
||||
@ -133,40 +160,6 @@ typedef struct RedCharDeviceWriteBuffer {
|
||||
uint32_t refs;
|
||||
} RedCharDeviceWriteBuffer;
|
||||
|
||||
typedef void RedCharDeviceMsgToClient;
|
||||
|
||||
struct RedCharDeviceCallbacks {
|
||||
/*
|
||||
* Messages that are addressed to the client can be queued in case we have
|
||||
* multiple clients and some of them don't have enough tokens.
|
||||
*/
|
||||
|
||||
/* reads from the device till reaching a msg that should be sent to the client,
|
||||
* or till the reading fails */
|
||||
RedCharDeviceMsgToClient* (*read_one_msg_from_device)(SpiceCharDeviceInstance *sin,
|
||||
void *opaque);
|
||||
RedCharDeviceMsgToClient* (*ref_msg_to_client)(RedCharDeviceMsgToClient *msg,
|
||||
void *opaque);
|
||||
void (*unref_msg_to_client)(RedCharDeviceMsgToClient *msg,
|
||||
void *opaque);
|
||||
void (*send_msg_to_client)(RedCharDeviceMsgToClient *msg,
|
||||
RedClient *client,
|
||||
void *opaque); /* after this call, the message is unreferenced */
|
||||
|
||||
/* The cb is called when a predefined number of write buffers were consumed by the
|
||||
* device */
|
||||
void (*send_tokens_to_client)(RedClient *client, uint32_t tokens, void *opaque);
|
||||
|
||||
/* The cb is called when a server (self) message that was addressed to the device,
|
||||
* has been completely written to it */
|
||||
void (*on_free_self_token)(void *opaque);
|
||||
|
||||
/* This cb is called if it is recommanded that a client will be removed
|
||||
* due to slow flow or due to some other error.
|
||||
* The called instance should disconnect the client, or at least the corresponding channel */
|
||||
void (*remove_client)(RedClient *client, void *opaque);
|
||||
};
|
||||
|
||||
void red_char_device_reset_dev_instance(RedCharDevice *dev,
|
||||
SpiceCharDeviceInstance *sin);
|
||||
void red_char_device_destroy(RedCharDevice *dev);
|
||||
|
||||
@ -4322,33 +4322,28 @@ static void
|
||||
red_char_device_vdi_port_class_init(RedCharDeviceVDIPortClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
RedCharDeviceClass *char_dev_class = RED_CHAR_DEVICE_CLASS(klass);
|
||||
|
||||
g_type_class_add_private(klass, sizeof (RedCharDeviceVDIPortPrivate));
|
||||
|
||||
object_class->finalize = red_char_device_vdi_port_finalize;
|
||||
object_class->constructed = red_char_device_vdi_port_constructed;
|
||||
|
||||
char_dev_class->read_one_msg_from_device = vdi_port_read_one_msg_from_device;
|
||||
char_dev_class->ref_msg_to_client = vdi_port_ref_msg_to_client;
|
||||
char_dev_class->unref_msg_to_client = vdi_port_unref_msg_to_client;
|
||||
char_dev_class->send_msg_to_client = vdi_port_send_msg_to_client;
|
||||
char_dev_class->send_tokens_to_client = vdi_port_send_tokens_to_client;
|
||||
char_dev_class->remove_client = vdi_port_remove_client;
|
||||
char_dev_class->on_free_self_token = vdi_port_on_free_self_token;
|
||||
}
|
||||
|
||||
static RedCharDeviceVDIPort *red_char_device_vdi_port_new(RedsState *reds)
|
||||
{
|
||||
RedCharDevice *char_dev;
|
||||
RedCharDeviceCallbacks char_dev_cbs = {
|
||||
.read_one_msg_from_device = vdi_port_read_one_msg_from_device,
|
||||
.ref_msg_to_client = vdi_port_ref_msg_to_client,
|
||||
.unref_msg_to_client = vdi_port_unref_msg_to_client,
|
||||
.send_msg_to_client = vdi_port_send_msg_to_client,
|
||||
.send_tokens_to_client = vdi_port_send_tokens_to_client,
|
||||
.remove_client = vdi_port_remove_client,
|
||||
.on_free_self_token = vdi_port_on_free_self_token,
|
||||
};
|
||||
|
||||
char_dev = g_object_new(RED_TYPE_CHAR_DEVICE_VDIPORT,
|
||||
"spice-server", reds,
|
||||
"client-tokens-interval", REDS_TOKENS_TO_SEND,
|
||||
"self-tokens", REDS_NUM_INTERNAL_AGENT_MESSAGES,
|
||||
NULL);
|
||||
|
||||
red_char_device_set_callbacks(RED_CHAR_DEVICE(char_dev),
|
||||
&char_dev_cbs, reds);
|
||||
return RED_CHAR_DEVICE_VDIPORT(char_dev);
|
||||
return g_object_new(RED_TYPE_CHAR_DEVICE_VDIPORT,
|
||||
"spice-server", reds,
|
||||
"client-tokens-interval", REDS_TOKENS_TO_SEND,
|
||||
"self-tokens", REDS_NUM_INTERNAL_AGENT_MESSAGES,
|
||||
"opaque", reds,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@ -272,14 +272,6 @@ static SpiceCharDeviceInstance *smartcard_readers_get_unattached(void)
|
||||
static RedCharDeviceSmartcard *smartcard_device_new(RedsState *reds, SpiceCharDeviceInstance *sin)
|
||||
{
|
||||
RedCharDevice *char_dev;
|
||||
RedCharDeviceCallbacks char_dev_cbs = {
|
||||
.read_one_msg_from_device = smartcard_read_msg_from_device,
|
||||
.ref_msg_to_client = smartcard_ref_msg_to_client,
|
||||
.unref_msg_to_client = smartcard_unref_msg_to_client,
|
||||
.send_msg_to_client = smartcard_send_msg_to_client,
|
||||
.send_tokens_to_client = smartcard_send_tokens_to_client,
|
||||
.remove_client = smartcard_remove_client,
|
||||
};
|
||||
|
||||
char_dev = g_object_new(RED_TYPE_CHAR_DEVICE_SMARTCARD,
|
||||
"sin", sin,
|
||||
@ -288,8 +280,8 @@ static RedCharDeviceSmartcard *smartcard_device_new(RedsState *reds, SpiceCharDe
|
||||
"self-tokens", ~0ULL,
|
||||
NULL);
|
||||
|
||||
red_char_device_set_callbacks(RED_CHAR_DEVICE(char_dev),
|
||||
&char_dev_cbs, char_dev);
|
||||
g_object_set(char_dev, "opaque", char_dev, NULL);
|
||||
|
||||
return RED_CHAR_DEVICE_SMARTCARD(char_dev);
|
||||
}
|
||||
|
||||
@ -869,10 +861,18 @@ static void
|
||||
red_char_device_smartcard_class_init(RedCharDeviceSmartcardClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
RedCharDeviceClass *char_dev_class = RED_CHAR_DEVICE_CLASS(klass);
|
||||
|
||||
g_type_class_add_private(klass, sizeof (RedCharDeviceSmartcardPrivate));
|
||||
|
||||
object_class->finalize = red_char_device_smartcard_finalize;
|
||||
|
||||
char_dev_class->read_one_msg_from_device = smartcard_read_msg_from_device;
|
||||
char_dev_class->ref_msg_to_client = smartcard_ref_msg_to_client;
|
||||
char_dev_class->unref_msg_to_client = smartcard_unref_msg_to_client;
|
||||
char_dev_class->send_msg_to_client = smartcard_send_msg_to_client;
|
||||
char_dev_class->send_tokens_to_client = smartcard_send_tokens_to_client;
|
||||
char_dev_class->remove_client = smartcard_remove_client;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@ -611,6 +611,14 @@ SPICE_GNUC_VISIBLE void spice_server_port_event(SpiceCharDeviceInstance *sin, ui
|
||||
static void
|
||||
red_char_device_spicevmc_class_init(RedCharDeviceSpiceVmcClass *klass)
|
||||
{
|
||||
RedCharDeviceClass *char_dev_class = RED_CHAR_DEVICE_CLASS(klass);
|
||||
|
||||
char_dev_class->read_one_msg_from_device = spicevmc_chardev_read_msg_from_dev;
|
||||
char_dev_class->ref_msg_to_client = spicevmc_chardev_ref_msg_to_client;
|
||||
char_dev_class->unref_msg_to_client = spicevmc_chardev_unref_msg_to_client;
|
||||
char_dev_class->send_msg_to_client = spicevmc_chardev_send_msg_to_client;
|
||||
char_dev_class->send_tokens_to_client = spicevmc_char_dev_send_tokens_to_client;
|
||||
char_dev_class->remove_client = spicevmc_char_dev_remove_client;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -623,25 +631,11 @@ red_char_device_spicevmc_new(SpiceCharDeviceInstance *sin,
|
||||
RedsState *reds,
|
||||
void *opaque)
|
||||
{
|
||||
RedCharDevice *char_dev;
|
||||
RedCharDeviceCallbacks char_dev_cbs = {
|
||||
.read_one_msg_from_device = spicevmc_chardev_read_msg_from_dev,
|
||||
.ref_msg_to_client = spicevmc_chardev_ref_msg_to_client,
|
||||
.unref_msg_to_client = spicevmc_chardev_unref_msg_to_client,
|
||||
.send_msg_to_client = spicevmc_chardev_send_msg_to_client,
|
||||
.send_tokens_to_client = spicevmc_char_dev_send_tokens_to_client,
|
||||
.remove_client = spicevmc_char_dev_remove_client,
|
||||
};
|
||||
|
||||
char_dev = g_object_new(RED_TYPE_CHAR_DEVICE_SPICEVMC,
|
||||
"sin", sin,
|
||||
"spice-server", reds,
|
||||
"client-tokens-interval", 0ULL,
|
||||
"self-tokens", ~0ULL,
|
||||
"opaque", opaque,
|
||||
NULL);
|
||||
|
||||
red_char_device_set_callbacks(RED_CHAR_DEVICE(char_dev),
|
||||
&char_dev_cbs, opaque);
|
||||
return char_dev;
|
||||
return g_object_new(RED_TYPE_CHAR_DEVICE_SPICEVMC,
|
||||
"sin", sin,
|
||||
"spice-server", reds,
|
||||
"client-tokens-interval", 0ULL,
|
||||
"self-tokens", ~0ULL,
|
||||
"opaque", opaque,
|
||||
NULL);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user