> > From: Christophe Fergeau <cfergeau@xxxxxxxxxx> > > This inherits from RedCharDevice. Once all char device states are > converted, we can turn the associated vfuncs into RedCharDeviceClass > vfuncs. > --- > server/smartcard.c | 221 > +++++++++++++++++++++++++++++------------------------ > server/smartcard.h | 30 +++++++- > 2 files changed, 150 insertions(+), 101 deletions(-) > > diff --git a/server/smartcard.c b/server/smartcard.c > index c63fea3..fc27bfe 100644 > --- a/server/smartcard.c > +++ b/server/smartcard.c > @@ -1,6 +1,6 @@ > /* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ > /* > - Copyright (C) 2010 Red Hat, Inc. > + Copyright (C) 2010-2015 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 > @@ -49,7 +49,7 @@ > // Maximal length of APDU > #define APDUBufSize 270 > > -typedef struct SmartCardDeviceState SmartCardDeviceState; > +typedef RedCharDeviceSmartcard SmartCardDeviceState; > > typedef struct SmartCardChannelClient { > RedChannelClient base; > @@ -62,7 +62,11 @@ typedef struct SmartCardChannelClient { > * or was it explicitly malloced */ > } SmartCardChannelClient; > > -struct SmartCardDeviceState { > +G_DEFINE_TYPE(RedCharDeviceSmartcard, red_char_device_smartcard, > RED_TYPE_CHAR_DEVICE) > + > +#define RED_CHAR_DEVICE_SMARTCARD_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE > ((o), RED_TYPE_CHAR_DEVICE_SMARTCARD, RedCharDeviceSmartcardPrivate)) > + > +struct RedCharDeviceSmartcardPrivate { > SpiceCharDeviceState *chardev_st; > uint32_t reader_id; > /* read_from_device buffer */ > @@ -118,7 +122,6 @@ static void > smartcard_channel_write_to_reader(SpiceCharDeviceWriteBuffer *write_ > static MsgItem *smartcard_char_device_on_message_from_device( > SmartCardDeviceState *state, VSCMsgHeader *header); > static SmartCardDeviceState *smartcard_device_state_new(RedsState *reds, > SpiceCharDeviceInstance *sin); > -static void smartcard_device_state_free(SmartCardDeviceState* st); > static void smartcard_init(RedsState *reds); > > static void smartcard_read_buf_prepare(SmartCardDeviceState *state, > VSCMsgHeader *vheader) > @@ -126,9 +129,9 @@ static void > smartcard_read_buf_prepare(SmartCardDeviceState *state, VSCMsgHeader > uint32_t msg_len; > > msg_len = ntohl(vheader->length); > - if (msg_len > state->buf_size) { > - state->buf_size = MAX(state->buf_size * 2, msg_len + > sizeof(VSCMsgHeader)); > - state->buf = spice_realloc(state->buf, state->buf_size); > + if (msg_len > state->priv->buf_size) { > + state->priv->buf_size = MAX(state->priv->buf_size * 2, msg_len + > sizeof(VSCMsgHeader)); > + state->priv->buf = spice_realloc(state->priv->buf, > state->priv->buf_size); > } > } > > @@ -137,31 +140,31 @@ SpiceCharDeviceMsgToClient > *smartcard_read_msg_from_device(SpiceCharDeviceInstan > { > SmartCardDeviceState *state = opaque; > SpiceCharDeviceInterface *sif = spice_char_device_get_interface(sin); > - VSCMsgHeader *vheader = (VSCMsgHeader*)state->buf; > + VSCMsgHeader *vheader = (VSCMsgHeader*)state->priv->buf; > int n; > int remaining; > int actual_length; > > - while ((n = sif->read(sin, state->buf_pos, state->buf_size - > state->buf_used)) > 0) { > + while ((n = sif->read(sin, state->priv->buf_pos, state->priv->buf_size - > state->priv->buf_used)) > 0) { > MsgItem *msg_to_client; > > - state->buf_pos += n; > - state->buf_used += n; > - if (state->buf_used < sizeof(VSCMsgHeader)) { > + state->priv->buf_pos += n; > + state->priv->buf_used += n; > + if (state->priv->buf_used < sizeof(VSCMsgHeader)) { > continue; > } > smartcard_read_buf_prepare(state, vheader); > actual_length = ntohl(vheader->length); > - if (state->buf_used - sizeof(VSCMsgHeader) < actual_length) { > + if (state->priv->buf_used - sizeof(VSCMsgHeader) < actual_length) { > continue; > } > msg_to_client = smartcard_char_device_on_message_from_device(state, > vheader); > - remaining = state->buf_used - sizeof(VSCMsgHeader) - actual_length; > + remaining = state->priv->buf_used - sizeof(VSCMsgHeader) - > actual_length; > if (remaining > 0) { > - memcpy(state->buf, state->buf_pos, remaining); > + memcpy(state->priv->buf, state->priv->buf_pos, remaining); > } > - state->buf_pos = state->buf; > - state->buf_used = remaining; > + state->priv->buf_pos = state->priv->buf; > + state->priv->buf_used = remaining; > if (msg_to_client) { > return msg_to_client; > } > @@ -186,8 +189,8 @@ static void > smartcard_send_msg_to_client(SpiceCharDeviceMsgToClient *msg, > void *opaque) > { > SmartCardDeviceState *dev = opaque; > - spice_assert(dev->scc && dev->scc->base.client == client); > - smartcard_channel_client_pipe_add_push(&dev->scc->base, &((MsgItem > *)msg)->base); > + spice_assert(dev->priv->scc && dev->priv->scc->base.client == client); > + smartcard_channel_client_pipe_add_push(&dev->priv->scc->base, &((MsgItem > *)msg)->base); > > } > > @@ -201,8 +204,8 @@ static void smartcard_remove_client(RedClient *client, > void *opaque) > SmartCardDeviceState *dev = opaque; > > spice_printerr("smartcard state %p, client %p", dev, client); > - spice_assert(dev->scc && dev->scc->base.client == client); > - red_channel_client_shutdown(&dev->scc->base); > + spice_assert(dev->priv->scc && dev->priv->scc->base.client == client); > + red_channel_client_shutdown(&dev->priv->scc->base); > } > > MsgItem *smartcard_char_device_on_message_from_device(SmartCardDeviceState > *state, > @@ -221,15 +224,15 @@ MsgItem > *smartcard_char_device_on_message_from_device(SmartCardDeviceState *stat > break; > } > /* We pass any VSC_Error right now - might need to ignore some? */ > - if (state->reader_id == VSCARD_UNDEFINED_READER_ID && vheader->type != > VSC_Init) { > + if (state->priv->reader_id == VSCARD_UNDEFINED_READER_ID && > vheader->type != VSC_Init) { > spice_printerr("error: reader_id not assigned for message of type > %d", vheader->type); > } > - if (state->scc) { > + if (state->priv->scc) { > sent_header = spice_memdup(vheader, sizeof(*vheader) + > vheader->length); > /* We patch the reader_id, since the device only knows about itself, > and > * we know about the sum of readers. */ > - sent_header->reader_id = state->reader_id; > - return smartcard_get_vsc_msg_item(&state->scc->base, sent_header); > + sent_header->reader_id = state->priv->reader_id; > + return smartcard_get_vsc_msg_item(&state->priv->scc->base, > sent_header); > } > return NULL; > } > @@ -241,7 +244,7 @@ static int smartcard_char_device_add_to_readers(RedsState > *reds, SpiceCharDevice > if (g_smartcard_readers.num >= SMARTCARD_MAX_READERS) { > return -1; > } > - state->reader_id = g_smartcard_readers.num; > + state->priv->reader_id = g_smartcard_readers.num; > g_smartcard_readers.sin[g_smartcard_readers.num++] = char_device; > smartcard_init(reds); > return 0; > @@ -262,7 +265,7 @@ static SpiceCharDeviceInstance > *smartcard_readers_get_unattached(void) > > for (i = 0; i < g_smartcard_readers.num; ++i) { > state = > spice_char_device_state_opaque_get(g_smartcard_readers.sin[i]->st); > - if (!state->scc) { > + if (!state->priv->scc) { > return g_smartcard_readers.sin[i]; > } > } > @@ -271,48 +274,33 @@ static SpiceCharDeviceInstance > *smartcard_readers_get_unattached(void) > > static SmartCardDeviceState *smartcard_device_state_new(RedsState *reds, > SpiceCharDeviceInstance *sin) > { > - SmartCardDeviceState *st; > - SpiceCharDeviceCallbacks chardev_cbs = { NULL, }; > - > - chardev_cbs.read_one_msg_from_device = smartcard_read_msg_from_device; > - chardev_cbs.ref_msg_to_client = smartcard_ref_msg_to_client; > - chardev_cbs.unref_msg_to_client = smartcard_unref_msg_to_client; > - chardev_cbs.send_msg_to_client = smartcard_send_msg_to_client; > - chardev_cbs.send_tokens_to_client = smartcard_send_tokens_to_client; > - chardev_cbs.remove_client = smartcard_remove_client; > - > - st = spice_new0(SmartCardDeviceState, 1); > - st->chardev_st = spice_char_device_state_create(sin, > - reds, > - 0, /* tokens interval */ > - ~0, /* self tokens */ > - &chardev_cbs, > - st); > - st->reader_id = VSCARD_UNDEFINED_READER_ID; > - st->reader_added = FALSE; > - st->buf_size = APDUBufSize + sizeof(VSCMsgHeader); > - st->buf = spice_malloc(st->buf_size); > - st->buf_pos = st->buf; > - st->buf_used = 0; > - st->scc = NULL; > - return st; > -} > - > -static void smartcard_device_state_free(SmartCardDeviceState* st) > -{ > - if (st->scc) { > - st->scc->smartcard_state = NULL; > - } > - free(st->buf); > - spice_char_device_state_destroy(st->chardev_st); > - free(st); > + RedCharDevice *char_dev; > + SpiceCharDeviceCallbacks 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, > + "spice-server", reds, > + "client-tokens-interval", 0ULL, > + "self-tokens", ~0ULL, > + NULL); > + > + red_char_device_set_callbacks(RED_CHAR_DEVICE(char_dev), > + &char_dev_cbs, char_dev); > + return RED_CHAR_DEVICE_SMARTCARD(char_dev); > } > > void smartcard_device_disconnect(SpiceCharDeviceInstance *char_device) > { > - SmartCardDeviceState *st = > spice_char_device_state_opaque_get(char_device->st); > + g_return_if_fail(RED_IS_CHAR_DEVICE_SMARTCARD(char_device)); > > - smartcard_device_state_free(st); > + g_object_unref(char_device); > } > > SpiceCharDeviceState *smartcard_device_connect(RedsState *reds, > SpiceCharDeviceInstance *char_device) > @@ -321,10 +309,10 @@ SpiceCharDeviceState > *smartcard_device_connect(RedsState *reds, SpiceCharDeviceI > > st = smartcard_device_state_new(reds, char_device); > if (smartcard_char_device_add_to_readers(reds, char_device) == -1) { > - smartcard_device_state_free(st); > + g_object_unref(st); > return NULL; > } > - return st->chardev_st; > + return RED_CHAR_DEVICE(st); > } > > static void smartcard_char_device_notify_reader_add(SmartCardDeviceState > *st) > @@ -332,15 +320,15 @@ static void > smartcard_char_device_notify_reader_add(SmartCardDeviceState *st) > SpiceCharDeviceWriteBuffer *write_buf; > VSCMsgHeader *vheader; > > - write_buf = spice_char_device_write_buffer_get(st->chardev_st, NULL, > sizeof(vheader)); > + write_buf = spice_char_device_write_buffer_get(RED_CHAR_DEVICE(st), > NULL, sizeof(vheader)); > if (!write_buf) { > spice_error("failed to allocate write buffer"); > return; > } > - st->reader_added = TRUE; > + st->priv->reader_added = TRUE; > vheader = (VSCMsgHeader *)write_buf->buf; > vheader->type = VSC_ReaderAdd; > - vheader->reader_id = st->reader_id; > + vheader->reader_id = st->priv->reader_id; > vheader->length = 0; > smartcard_channel_write_to_reader(write_buf); > } > @@ -351,10 +339,10 @@ static void > smartcard_char_device_attach_client(SpiceCharDeviceInstance *char_de > SmartCardDeviceState *st = > spice_char_device_state_opaque_get(char_device->st); > int client_added; > > - spice_assert(!scc->smartcard_state && !st->scc); > - st->scc = scc; > + spice_assert(!scc->smartcard_state && !st->priv->scc); > + st->priv->scc = scc; > scc->smartcard_state = st; > - client_added = spice_char_device_client_add(st->chardev_st, > + client_added = spice_char_device_client_add(RED_CHAR_DEVICE(st), > scc->base.client, > FALSE, /* no flow control > yet */ > 0, /* send queue size */ > @@ -364,7 +352,7 @@ static void > smartcard_char_device_attach_client(SpiceCharDeviceInstance *char_de > &scc->base)); > if (!client_added) { > spice_warning("failed"); > - st->scc = NULL; > + st->priv->scc = NULL; > scc->smartcard_state = NULL; > red_channel_client_disconnect(&scc->base); > } > @@ -375,19 +363,19 @@ static void > smartcard_char_device_notify_reader_remove(SmartCardDeviceState *st) > SpiceCharDeviceWriteBuffer *write_buf; > VSCMsgHeader *vheader; > > - if (!st->reader_added) { > + if (!st->priv->reader_added) { > spice_debug("reader add was never sent to the device"); > return; > } > - write_buf = spice_char_device_write_buffer_get(st->chardev_st, NULL, > sizeof(vheader)); > + write_buf = spice_char_device_write_buffer_get(RED_CHAR_DEVICE(st), > NULL, sizeof(vheader)); > if (!write_buf) { > spice_error("failed to allocate write buffer"); > return; > } > - st->reader_added = FALSE; > + st->priv->reader_added = FALSE; > vheader = (VSCMsgHeader *)write_buf->buf; > vheader->type = VSC_ReaderRemove; > - vheader->reader_id = st->reader_id; > + vheader->reader_id = st->priv->reader_id; > vheader->length = 0; > smartcard_channel_write_to_reader(write_buf); > } > @@ -400,10 +388,10 @@ static void > smartcard_char_device_detach_client(SmartCardChannelClient *scc) > return; > } > st = scc->smartcard_state; > - spice_assert(st->scc == scc); > - spice_char_device_client_remove(st->chardev_st, scc->base.client); > + spice_assert(st->priv->scc == scc); > + spice_char_device_client_remove(st->priv->chardev_st, scc->base.client); > scc->smartcard_state = NULL; > - st->scc = NULL; > + st->priv->scc = NULL; > } > > static int smartcard_channel_client_config_socket(RedChannelClient *rcc) > @@ -428,9 +416,9 @@ static uint8_t > *smartcard_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, > > spice_assert(g_smartcard_readers.num == 1); > st = scc->smartcard_state; > - spice_assert(st->scc || scc->smartcard_state); > + spice_assert(st->priv->scc || scc->smartcard_state); > spice_assert(!scc->write_buf); > - scc->write_buf = spice_char_device_write_buffer_get(st->chardev_st, > rcc->client, size); > + scc->write_buf = > spice_char_device_write_buffer_get(RED_CHAR_DEVICE(st), rcc->client, size); > > if (!scc->write_buf) { > spice_error("failed to allocate write buffer"); > @@ -456,11 +444,9 @@ static void > smartcard_channel_release_msg_rcv_buf(RedChannelClient *rcc, > spice_assert(!scc->write_buf); > free(msg); > } else { > - SpiceCharDeviceState *dev_st; > if (scc->write_buf) { /* msg hasn't been pushed to the guest */ > spice_assert(scc->write_buf->buf == msg); > - dev_st = scc->smartcard_state ? scc->smartcard_state->chardev_st > : NULL; > - spice_char_device_write_buffer_release(dev_st, scc->write_buf); > + > spice_char_device_write_buffer_release(RED_CHAR_DEVICE(scc->smartcard_state), > scc->write_buf); > scc->write_buf = NULL; > } > } > @@ -514,12 +500,12 @@ static void > smartcard_channel_send_migrate_data(RedChannelClient *rcc, > spice_marshaller_add_uint32(m, 0); > spice_debug("null char dev state"); > } else { > - spice_char_device_state_migrate_data_marshall(state->chardev_st, m); > - spice_marshaller_add_uint8(m, state->reader_added); > - spice_marshaller_add_uint32(m, state->buf_used); > + > spice_char_device_state_migrate_data_marshall(RED_CHAR_DEVICE(state), > m); > + spice_marshaller_add_uint8(m, state->priv->reader_added); > + spice_marshaller_add_uint32(m, state->priv->buf_used); > m2 = spice_marshaller_get_ptr_submarshaller(m, 0); > - spice_marshaller_add(m2, state->buf, state->buf_used); > - spice_debug("reader added %d partial read size %u", > state->reader_added, state->buf_used); > + spice_marshaller_add(m2, state->priv->buf, state->priv->buf_used); > + spice_debug("reader added %d partial read size %u", > state->priv->reader_added, state->priv->buf_used); > } > } > > @@ -625,7 +611,7 @@ static void > smartcard_remove_reader(SmartCardChannelClient *scc, uint32_t reader > } > > state = spice_char_device_state_opaque_get(char_device->st); > - if (state->reader_added == FALSE) { > + if (state->priv->reader_added == FALSE) { > smartcard_push_error(&scc->base, reader_id, > VSC_GENERAL_ERROR); > return; > @@ -666,7 +652,7 @@ static void > smartcard_channel_write_to_reader(SpiceCharDeviceWriteBuffer *write_ > spice_assert(vheader->reader_id <= g_smartcard_readers.num); > sin = g_smartcard_readers.sin[vheader->reader_id]; > st = (SmartCardDeviceState > *)spice_char_device_state_opaque_get(sin->st); > - spice_assert(!st->scc || st == st->scc->smartcard_state); > + spice_assert(!st->priv->scc || st == st->priv->scc->smartcard_state); > /* protocol requires messages to be in network endianess */ > vheader->type = htonl(vheader->type); > vheader->length = htonl(vheader->length); > @@ -675,8 +661,8 @@ static void > smartcard_channel_write_to_reader(SpiceCharDeviceWriteBuffer *write_ > /* pushing the buffer to the write queue; It will be released > * when it will be fully consumed by the device */ > spice_char_device_write_buffer_add(sin->st, write_buf); > - if (st->scc && write_buf == st->scc->write_buf) { > - st->scc->write_buf = NULL; > + if (st->priv->scc && write_buf == st->priv->scc->write_buf) { > + st->priv->scc->write_buf = NULL; > } > } > > @@ -694,13 +680,13 @@ static void > smartcard_device_state_restore_partial_read(SmartCardDeviceState *st > spice_debug("read_size %u", mig_data->read_size); > read_data = (uint8_t *)mig_data + mig_data->read_data_ptr - > sizeof(SpiceMigrateDataHeader); > if (mig_data->read_size < sizeof(VSCMsgHeader)) { > - spice_assert(state->buf_size >= mig_data->read_size); > + spice_assert(state->priv->buf_size >= mig_data->read_size); > } else { > smartcard_read_buf_prepare(state, (VSCMsgHeader *)read_data); > } > - memcpy(state->buf, read_data, mig_data->read_size); > - state->buf_used = mig_data->read_size; > - state->buf_pos = state->buf + mig_data->read_size; > + memcpy(state->priv->buf, read_data, mig_data->read_size); > + state->priv->buf_used = mig_data->read_size; > + state->priv->buf_pos = state->priv->buf + mig_data->read_size; > } > > static int smartcard_channel_client_handle_migrate_data(RedChannelClient > *rcc, > @@ -739,10 +725,10 @@ static int > smartcard_channel_client_handle_migrate_data(RedChannelClient *rcc, > } > } > spice_debug("reader added %d partial read_size %u", > mig_data->reader_added, mig_data->read_size); > - scc->smartcard_state->reader_added = mig_data->reader_added; > + scc->smartcard_state->priv->reader_added = mig_data->reader_added; > > smartcard_device_state_restore_partial_read(scc->smartcard_state, > mig_data); > - return spice_char_device_state_restore(scc->smartcard_state->chardev_st, > &mig_data->base); > + return > spice_char_device_state_restore(RED_CHAR_DEVICE(scc->smartcard_state), > &mig_data->base); > } > > static int smartcard_channel_handle_message(RedChannelClient *rcc, > @@ -867,3 +853,38 @@ static void smartcard_init(RedsState *reds) > > reds_register_channel(reds, &g_smartcard_channel->base); > } > + > + > +static void > +red_char_device_smartcard_finalize(GObject *object) > +{ > + RedCharDeviceSmartcard *self = RED_CHAR_DEVICE_SMARTCARD(object); > + > + free(self->priv->buf); > + if (self->priv->scc) { > + self->priv->scc->smartcard_state = NULL; > + } > + > + > G_OBJECT_CLASS(red_char_device_smartcard_parent_class)->finalize(object); > +} > + > +static void > +red_char_device_smartcard_class_init(RedCharDeviceSmartcardClass *klass) > +{ > + GObjectClass *object_class = G_OBJECT_CLASS(klass); > + > + g_type_class_add_private(klass, sizeof (RedCharDeviceSmartcardPrivate)); > + > + object_class->finalize = red_char_device_smartcard_finalize; > +} > + > +static void > +red_char_device_smartcard_init(RedCharDeviceSmartcard *self) > +{ > + self->priv = RED_CHAR_DEVICE_SMARTCARD_PRIVATE(self); > + > + self->priv->reader_id = VSCARD_UNDEFINED_READER_ID; > + self->priv->buf_size = APDUBufSize + sizeof(VSCMsgHeader); > + self->priv->buf = spice_malloc(self->priv->buf_size); > + self->priv->buf_pos = self->priv->buf; > +} > diff --git a/server/smartcard.h b/server/smartcard.h > index 32d2367..4b00433 100644 > --- a/server/smartcard.h > +++ b/server/smartcard.h > @@ -1,6 +1,6 @@ > /* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ > /* > - Copyright (C) 2010 Red Hat, Inc. > + Copyright (C) 2010-2015 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 > @@ -18,6 +18,34 @@ > #ifndef __SMART_CARD_H__ > #define __SMART_CARD_H__ > > +#include <glib-object.h> > + > +#define RED_TYPE_CHAR_DEVICE_SMARTCARD red_char_device_smartcard_get_type() > + > +#define RED_CHAR_DEVICE_SMARTCARD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), > RED_TYPE_CHAR_DEVICE_SMARTCARD, RedCharDeviceSmartcard)) > +#define RED_CHAR_DEVICE_SMARTCARD_CLASS(klass) > (G_TYPE_CHECK_CLASS_CAST((klass), RED_TYPE_CHAR_DEVICE_SMARTCARD, > RedCharDeviceSmartcardClass)) > +#define RED_IS_CHAR_DEVICE_SMARTCARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), > RED_TYPE_CHAR_DEVICE_SMARTCARD)) > +#define RED_IS_CHAR_DEVICE_SMARTCARD_CLASS(klass) > (G_TYPE_CHECK_CLASS_TYPE((klass), RED_TYPE_CHAR_DEVICE_SMARTCARD)) > +#define RED_CHAR_DEVICE_SMARTCARD_GET_CLASS(obj) > (G_TYPE_INSTANCE_GET_CLASS((obj), RED_TYPE_CHAR_DEVICE_SMARTCARD, > RedCharDeviceSmartcardClass)) > + > +typedef struct RedCharDeviceSmartcard RedCharDeviceSmartcard; > +typedef struct RedCharDeviceSmartcardClass RedCharDeviceSmartcardClass; > +typedef struct RedCharDeviceSmartcardPrivate RedCharDeviceSmartcardPrivate; > + > +struct RedCharDeviceSmartcard > +{ > + RedCharDevice parent; > + > + RedCharDeviceSmartcardPrivate *priv; > +}; > + > +struct RedCharDeviceSmartcardClass > +{ > + RedCharDeviceClass parent_class; > +}; > + > +GType red_char_device_smartcard_get_type(void) G_GNUC_CONST; > + > /* > * connect to smartcard interface, used by smartcard channel > */ The header was much private before. What's the point in declaring all these stuff in the header? Frediano _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel