On Tue, 2016-10-11 at 16:13 +0200, Pavel Grunt wrote: > Hi Frediano, > > On Tue, 2016-10-11 at 09:55 -0400, Frediano Ziglio wrote: > > > > > > > > > > > On Mon, 2016-10-10 at 12:48 -0400, Frediano Ziglio wrote: > > > > > > > > > > > > > > > > > > > Subject: [PATCH spice-server v2 7/8] Convert > > > > > RedChannel heirarchy to GObject > > > > > > > > > > > > > Small spell, it's "hierarchy". > > > > > > > > > > > > > > > > > > > From: Jonathon Jongsma <jjongsma@xxxxxxxxxx> > > > > > > > > > > FIXME: this commit appears to introduce a vdagent-related > > > > > crash in > > > > > vdi_port_read_one_msg_from_device(). sin->st is NULL. > > > > > > > > If this is still true I would fix it. > > > > > > I added this comment a long time ago when I was running into a > > > crash > > > while testing the refactory branch. I bisected and ended up at > > > this > > > commit, but didn't have time to fix the crash right away, so I > > > added > > > the comment to remind myself. However, I have not seen the crash > > > at all > > > recently. > > > > > > My theory is that perhaps this crash was caused by a bad rebase > > > that > > > introduced an error that we've subsequently fixed due to reviews > > > and > > > additional rebasing. > > > > > > > > > > > > > > > > > > > > > > > > @@ -381,7 +367,7 @@ void > > > > > cursor_channel_process_cmd(CursorChannel > > > > > *cursor, > > > > > RedCursorCmd *cursor_cmd) > > > > > > > > > > void cursor_channel_reset(CursorChannel *cursor) > > > > > { > > > > > - RedChannel *channel = &cursor->common.base; > > > > > + RedChannel *channel = RED_CHANNEL(cursor); > > > > > > > > > > spice_return_if_fail(cursor); > > > > > > > > > > @@ -395,9 +381,9 @@ void cursor_channel_reset(CursorChannel > > > > > *cursor) > > > > > if > > > > > (!common_graphics_channel_get_during_target_migrate( > > > > > C > > > > > OMMON > > > > > _GRAPHICS_CHANNEL(cursor))) > > > > > { > > > > > red_pipes_add_verb(channel, > > > > > SPICE_MSG_CURSOR_RESET); > > > > > } > > > > > - if (!red_channel_wait_all_sent(&cursor->common.base, > > > > > + if (!red_channel_wait_all_sent(RED_CHANNEL(cursor), > > > > > COMMON_CLIENT_TIMEOUT > > > > > ) > > > > > ) { > > > > > - red_channel_apply_clients(channel, > > > > > + red_channel_apply_clients(RED_CHANNEL(cursor), > > > > > > > > Why not using channel variable ?? > > > > > > > > > > > > > Strange. Not sure. Will change. > > > > > > > > > > > > > > > > > > > > > > red_channel_client_dis > > > > > c > > > > > onnec > > > > > t_if_pending_send); > > > > > } > > > > > } > > > > > @@ -407,7 +393,7 @@ static void > > > > > cursor_channel_init_client(CursorChannel > > > > > *cursor, CursorChannelClien > > > > > { > > > > > spice_return_if_fail(cursor); > > > > > > > > > > - if (!red_channel_is_connected(&cursor->common.base) > > > > > + if (!red_channel_is_connected(RED_CHANNEL(cursor)) > > > > > || > > > > > common_graphics_channel_get_during_target_migrate(COMMON_GRAP > > > > > H > > > > > ICS_C > > > > > HANNEL(cursor))) > > > > > || { > > > > > spice_debug("during_target_migrate: skip init"); > > > > > return; > > > > > @@ -420,7 +406,7 @@ static void > > > > > cursor_channel_init_client(CursorChannel > > > > > *cursor, CursorChannelClien > > > > > red_channel_pipes_add_type(RED_CHANNEL(cursor), > > > > > RED_PIPE_ITEM_TYPE_CURSOR_INIT); > > > > > } > > > > > > > > > > -void cursor_channel_init(CursorChannel *cursor) > > > > > +void cursor_channel_do_init(CursorChannel *cursor) > > > > > { > > > > > cursor_channel_init_client(cursor, NULL); > > > > > } > > > > > @@ -454,3 +440,25 @@ void > > > > > cursor_channel_connect(CursorChannel > > > > > *cursor, > > > > > RedClient *client, RedsStream > > > > > > > > > > cursor_channel_init_client(cursor, ccc); > > > > > } > > > > > + > > > > > +static void > > > > > +cursor_channel_class_init(CursorChannelClass *klass) > > > > > +{ > > > > > + RedChannelClass *channel_class = > > > > > RED_CHANNEL_CLASS(klass); > > > > > + > > > > > + g_type_class_add_private(klass, > > > > > sizeof(CursorChannelPrivate)); > > > > > + > > > > > + channel_class->parser = > > > > > spice_get_client_channel_parser(SPICE_CHANNEL_CURSOR, NULL); > > > > > + channel_class->handle_parsed = > > > > > red_channel_client_handle_message; > > > > > + > > > > > + channel_class->on_disconnect > > > > > = cursor_channel_client_on_disconnect; > > > > > + channel_class->send_item = cursor_channel_send_item; > > > > > +} > > > > > + > > > > > +static void > > > > > +cursor_channel_init(CursorChannel *self) > > > > > +{ > > > > > + self->priv = CURSOR_CHANNEL_PRIVATE(self); > > > > > + self->priv->cursor_visible = TRUE; > > > > > + self->priv->mouse_mode = SPICE_MOUSE_MODE_SERVER; > > > > > +} > > > > > diff --git a/server/cursor-channel.h b/server/cursor- > > > > > channel.h > > > > > index a3ddaa3..8b3bc17 100644 > > > > > --- a/server/cursor-channel.h > > > > > +++ b/server/cursor-channel.h > > > > > @@ -19,6 +19,17 @@ > > > > > # define CURSOR_CHANNEL_H_ > > > > > > > > > > #include "common-graphics-channel.h" > > > > > +#include "red-parse-qxl.h" > > > > > + > > > > > +G_BEGIN_DECLS > > > > > + > > > > > +#define TYPE_CURSOR_CHANNEL cursor_channel_get_type() > > > > > + > > > > > +#define CURSOR_CHANNEL(obj) > > > > > (G_TYPE_CHECK_INSTANCE_CAST((obj), > > > > > TYPE_CURSOR_CHANNEL, CursorChannel)) > > > > > +#define CURSOR_CHANNEL_CLASS(klass) > > > > > (G_TYPE_CHECK_CLASS_CAST((klass), > > > > > TYPE_CURSOR_CHANNEL, CursorChannelClass)) > > > > > +#define IS_CURSOR_CHANNEL(obj) > > > > > (G_TYPE_CHECK_INSTANCE_TYPE((obj), > > > > > TYPE_CURSOR_CHANNEL)) > > > > > +#define IS_CURSOR_CHANNEL_CLASS(klass) > > > > > (G_TYPE_CHECK_CLASS_TYPE((klass), > > > > > TYPE_CURSOR_CHANNEL)) > > > > > +#define CURSOR_CHANNEL_GET_CLASS(obj) > > > > > (G_TYPE_INSTANCE_GET_CLASS((obj), > > > > > TYPE_CURSOR_CHANNEL, CursorChannelClass)) > > > > > > > > > > /** > > > > > * This type it's a RedChannel class which implement cursor > > > > > (mouse) > > > > > @@ -26,6 +37,22 @@ > > > > > * A pointer to CursorChannel can be converted to a > > > > > RedChannel. > > > > > */ > > > > > typedef struct CursorChannel CursorChannel; > > > > > +typedef struct CursorChannelClass CursorChannelClass; > > > > > +typedef struct CursorChannelPrivate CursorChannelPrivate; > > > > > + > > > > > +struct CursorChannel > > > > > +{ > > > > > + CommonGraphicsChannel parent; > > > > > + > > > > > + CursorChannelPrivate *priv; > > > > > +}; > > > > > + > > > > > +struct CursorChannelClass > > > > > +{ > > > > > + CommonGraphicsChannelClass parent_class; > > > > > +}; > > > > > + > > > > > +GType cursor_channel_get_type(void) G_GNUC_CONST; > > > > > > > > > > > > > Why we need to expose this here ? On the C file is not enough ? > > > > > > This is used above in all of the 'standard' GObject macros (e.g. > > > CURSOR_CHANNEL(), IS_CURSOR_CHANNEL(), etc). It's standard > > > practice to > > > expose it in the header. In this case, it's possible that we > > > could > > > move > > > it down to the .c file, depending on whether any other files use > > > these > > > macros, but I don't see much advantage to doing so. I'd prefer to > > > leave > > > the standard GObject boilerplate here. > > > > > > > Some months ago my sister decided it was time to change the car. > > As she has some child she decided for a bigger car. She was also > > thinking > > about having additional space to allow to go to holidays. After > > viewing > > different car we discussed if it was worth buying a bigger car > > considering > > it was more expensive to buy and to maintain (insurance and fuel). > > At the end she decided to buy a car enough for the child and family > > but that was not worth buying some more big one just for the > > holiday > > opting for a car roof bag. > > The 'standard' solution for the car is buying a bigger car but not > > all standard solutions are the best. > > The main reason why the standard is that way is that it supports > > more > > cases and so it's easier to put in a guide or tutorial or a book... > > just that we are not writing a book or following a tutorial or > > guide. > > > > Exposing CursorChannel and CursorChannelClass in the header is a > > way > > to tell that this is the object structure and can be used for > > instance > > for inheritance. Some languages introduced the "final" keyword to > > avoid > > inheritance... C just do not support objects so not exposing the > > structure it's a way to use. > > Also is there is no need to expose the structure why to do it? > > Another reason in favor of not exposing it is that you could avoid > > to > > pay the penalty (memory, code and cpu) of the "priv" field. > > > > About all that macros boilerplate I don't understand why they > > don't came to a better solution, something like > > > > G_TYPE_CAST(pointer, RedChannel) > > > > instead of having to define all these macro for every object... > > Maybe we can use G_DECLARE_FINAL_TYPE > > https://developer.gnome.org/gobject/unstable/gobject-Type-Information > . > html#G-DECLARE-FINAL-TYPE:CAPS > > In general I prefer to expose declarations only if needed > > Pavel This would still expose the same declarations, it would just hide it behind a macro, I think. In addition, this particular macro was introduced in glib 2.44, and we currently only require 2.22. _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel