--- Changes in v2: - pass 'channel' property to char device constructor - assert that 'channel' device is non-null in char device set_property - minor indentation fix server/spicevmc.c | 83 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 22 deletions(-) diff --git a/server/spicevmc.c b/server/spicevmc.c index cf743de..532598d 100644 --- a/server/spicevmc.c +++ b/server/spicevmc.c @@ -89,7 +89,7 @@ struct RedCharDeviceSpiceVmcClass static GType red_char_device_spicevmc_get_type(void) G_GNUC_CONST; static RedCharDevice *red_char_device_spicevmc_new(SpiceCharDeviceInstance *sin, RedsState *reds, - uint8_t channel_type); + RedVmcChannel *channel); G_DEFINE_TYPE(RedCharDeviceSpiceVmc, red_char_device_spicevmc, RED_TYPE_CHAR_DEVICE) @@ -806,7 +806,19 @@ RedCharDevice *spicevmc_device_connect(RedsState *reds, SpiceCharDeviceInstance *sin, uint8_t channel_type) { - return red_char_device_spicevmc_new(sin, reds, channel_type); + RedCharDevice *dev; + RedVmcChannel *channel = red_vmc_channel_new(reds, channel_type); + if (!channel) { + return NULL; + } + + /* char device takes ownership of channel */ + dev = red_char_device_spicevmc_new(sin, reds, channel); + + channel->chardev_sin = sin; + g_object_unref(channel); + + return dev; } /* Must be called from RedClient handling thread. */ @@ -861,18 +873,56 @@ red_char_device_spicevmc_dispose(GObject *object) } } +enum { + PROP0, + PROP_CHANNEL +}; + +static void +red_char_device_spicevmc_set_property(GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + RedCharDeviceSpiceVmc *self = RED_CHAR_DEVICE_SPICEVMC(object); + + switch (property_id) + { + case PROP_CHANNEL: + spice_assert(self->channel == NULL); + self->channel = g_value_dup_object(value); + spice_assert(self->channel != NULL); + self->channel->chardev = RED_CHAR_DEVICE(self); + + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + } +} + static void red_char_device_spicevmc_class_init(RedCharDeviceSpiceVmcClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); RedCharDeviceClass *char_dev_class = RED_CHAR_DEVICE_CLASS(klass); + object_class->set_property = red_char_device_spicevmc_set_property; object_class->dispose = red_char_device_spicevmc_dispose; char_dev_class->read_one_msg_from_device = spicevmc_chardev_read_msg_from_dev; 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; + + g_object_class_install_property(object_class, + PROP_CHANNEL, + g_param_spec_object("channel", + "Channel", + "Channel associated with this device", + RED_TYPE_VMC_CHANNEL, + G_PARAM_STATIC_STRINGS | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT)); } static void @@ -883,25 +933,14 @@ red_char_device_spicevmc_init(RedCharDeviceSpiceVmc *self) static RedCharDevice * red_char_device_spicevmc_new(SpiceCharDeviceInstance *sin, RedsState *reds, - uint8_t channel_type) + RedVmcChannel *channel) { - RedCharDeviceSpiceVmc *dev; - RedVmcChannel *channel = red_vmc_channel_new(reds, channel_type); - if (!channel) { - return NULL; - } - - dev = g_object_new(RED_TYPE_CHAR_DEVICE_SPICEVMC, - "sin", sin, - "spice-server", reds, - "client-tokens-interval", 0ULL, - "self-tokens", ~0ULL, - "opaque", channel, - NULL); - - channel->chardev = RED_CHAR_DEVICE(dev); - channel->chardev_sin = sin; - dev->channel = channel; - - return RED_CHAR_DEVICE(dev); + return g_object_new(RED_TYPE_CHAR_DEVICE_SPICEVMC, + "sin", sin, + "spice-server", reds, + "client-tokens-interval", 0ULL, + "self-tokens", ~0ULL, + "channel", channel, + "opaque", channel, + NULL); } -- 2.7.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel