Re: CairoIO - Cairo compatible successor to GdkPixbuf
On 13/11/2007, BJörn Lindqvist <[EMAIL PROTECTED]> wrote: > > Hello all! > > Some background info about this project is found here: > > * http://www.mail-archive.com/gtk-devel-list@gnome.org/msg06472.html > * http://live.gnome.org/GtkCairoIntegration > * http://bugzilla.gnome.org/show_bug.cgi?id=395578#c6 > > In short, GdkPixbuf has some big problems which are hard to solve, so > we need a new image library which is more compatible with Cairo. > CairoIO is my attempt at creating such a library. The library is not a > reimplementation of GdkPixbuf, it only wraps it to provide a > cairoified front end to all the image loading functionality. > > Currently it consists of nothing more than a executable specification > written in Python and unit tests. The intention is to first create a > rock-solid, future-proof interface that solves all architectural > problems GdkPixbuf has. So lets have some nice discussion about it! > The things I've found really bad with GdkPixbuf and which I think > CairoIO can solve are listed in "Targeted GdkPixbuf Problems" in the > /ref/cairoio.py file. In particular I was not happy with how > PixbufAnimations work so I've tried to make them better. > > Checkout using: > > svn co svn.gnome.org/svn/cairoio/trunk cairoio > > The implementation is in /ref/cairoio.py which also contain lots of > documentation. I know the name "CairoIO" might not be so nice, but it > is only seven characters. Maybe someone can think of a better name? > > Feedback welcome! And thou shalt have feedback :-) 1) I am wondering if it should integrate with the upcoming libgio? Ie, take a GFile instead of a filename in function args..? Or maybe going entirely G{Input,Output}Stream based? That would obsolete a few of the methods in the API. 2) I see that you do not have any methods to match GdkPixbuf.get_has_alfaand a handful other methods on GdkPixbuf. Is the reason documented somewhere or am I missing something obvious? 3) Why is there a load_xpm()? 4) I gather that the load*() family functions replace the constructors of GDkPixbuf. 4.1) How exactly would you map the load_frames() method with the keyword arguments? 4.2) Why do I have to call load_frames() to request the image size on construction of the surface? Just load() would space me the linked list for normal images. 4.3 (Assuming gio based) If we are in stream terminology s/load/read is probably more in line 5) All load_*() family functions returns a SurfaceInfo, but load() returns a Surface... A bit odd maybe. I am really exited about the idea about joggling cairo surfaces around over G{In,Out}putStreams, but the idea may be bonkers, I have not read the GIO api much, not do I understand the finer details of cairo surfaces. Cheers, Mikkel ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Signals with gchar** arguments
On Thu, 2007-11-15 at 13:06 +, Emmanuele Bassi wrote: > On Thu, 2007-11-15 at 12:52 +0100, Mathias Hasselmann wrote: > > > static void > > authenticate (SoupSession *session, > > /* other arguments... */ > > gchar **username, > > gchar **password, > > gpointer user_data) > > { > > /* ... */ > > > > g_free (*username); > > *username = g_strdup (lookup_username ()); > > > > /* ... */ > > } > > > > Notice that this use of "gchar**" arguments is different from the usage > > as "NULL terminated arrays of strings", aka. "G_TYPE_STRV". > > this is probably the most evil use of signals I've seen in a while. ;-) > > the SoupSession should really take a AuthenticateCallback function and > emit a signal on success or one on failure. That makes a lot of sense. It wouldn't make sense to have two signal handlers connected to this signal. Mathias, could you please turn the signal into a set_func() in our libepc. -- [EMAIL PROTECTED] www.murrayc.com www.openismus.com ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: GInterfaces and API Stability
On Thu, 2007-11-15 at 01:16 +0100, Mathias Hasselmann wrote: > Wouldn't it possible to implement the GInterface as C++ class and add > an > operator like this to the GObject wrapper class: > > public: > GLib::RefPtr operator () { > return GLib::wrap_interface (gobj ()); > } As well as a general learned avoidance of reckless C++ operator overloading, I think you'd lose the advantages of actually using the regular C++ hierarchy, such as type-safe casts at compile-time. For gtkmm I am not greatly troubled by the new-interfaces-break-ABI issue because it happens so rarely. -- [EMAIL PROTECTED] www.murrayc.com www.openismus.com ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Signals with gchar** arguments
Am Donnerstag, den 15.11.2007, 14:21 +0100 schrieb Alexander Larsson: > On Thu, 2007-11-15 at 13:06 +, Emmanuele Bassi wrote: > > On Thu, 2007-11-15 at 12:52 +0100, Mathias Hasselmann wrote: > > > > > static void > > > authenticate (SoupSession *session, > > > /* other arguments... */ > > > gchar **username, > > > gchar **password, > > > gpointer user_data) > > > { > > > /* ... */ > > > > > > g_free (*username); > > > *username = g_strdup (lookup_username ()); > > > > > > /* ... */ > > > } > > > > > > Notice that this use of "gchar**" arguments is different from the > usage > > > as "NULL terminated arrays of strings", aka. "G_TYPE_STRV". > > > > this is probably the most evil use of signals I've seen in a while. ;-) > > > > the SoupSession should really take a AuthenticateCallback function and > > emit a signal on success or one on failure. > > What gio does in the similar case of mounting is that GMountOperation > gets a ask_for_password signal. Then the implementation of this gets to > throw up some dialog and then it calls back into the GMountOperation > when it knows the answer. This also allows the ask-for-password code to > run async, and not having to recurse the mainloop (and generally be > modal). Sounds interesting, but guess I have to read your code to understand what __exactly__ you mean. Ciao, Mathias -- Mathias Hasselmann <[EMAIL PROTECTED]> http://taschenorakel.de/ signature.asc Description: Dies ist ein digital signierter Nachrichtenteil ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Signals with gchar** arguments
On Thu, 2007-11-15 at 13:06 +, Emmanuele Bassi wrote: > On Thu, 2007-11-15 at 12:52 +0100, Mathias Hasselmann wrote: > > > static void > > authenticate (SoupSession *session, > > /* other arguments... */ > > gchar **username, > > gchar **password, > > gpointer user_data) > > { > > /* ... */ > > > > g_free (*username); > > *username = g_strdup (lookup_username ()); > > > > /* ... */ > > } > > > > Notice that this use of "gchar**" arguments is different from the usage > > as "NULL terminated arrays of strings", aka. "G_TYPE_STRV". > > this is probably the most evil use of signals I've seen in a while. ;-) > > the SoupSession should really take a AuthenticateCallback function and > emit a signal on success or one on failure. What gio does in the similar case of mounting is that GMountOperation gets a ask_for_password signal. Then the implementation of this gets to throw up some dialog and then it calls back into the GMountOperation when it knows the answer. This also allows the ask-for-password code to run async, and not having to recurse the mainloop (and generally be modal). ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: GInterfaces and API Stability
On Thu, 2007-11-15 at 11:28 +0100, Paolo Molaro wrote: > On 11/14/07 Sven Herzberg wrote: > > I think it's not about "the compiler doesn't barf". It was a design > > decision to be able to always extend interfaces. The only thing GTK+ > > I guess this is a documentation issue, then, as this design decision > is not mentioned at all in the GObject documentation at > http://library.gnome.org/devel/gobject/unstable/gtype-non-instantiable-classed.html. > > It actually says that GInterfaces are very similar to Java interfaces > but Java interfaces definitely don't allow adding new methods > (without breaking previously working code). This is because someone other than Tim wrote those docs. GObject interfaces was not modeled on Java style interfaces, but rather on an gcc c++ extension calles signatures, which is slightly different than java interfaces. > So, let's create a table with the options available in the C libs and > in the bindings and see if there is a compromise that would make most > people happy. Please comment on this, as my understanding of some of the > bindings is lacking. > > In GObject (and Gtk+) we have two options: adding new methods to > existing interfaces or adding new interfaces. Let's see how the major > bindings cope with this: > > new methods new interface > Pythondoesn't caredoesn't care > Perl doesn't caredoesn't care > Ruby doesn't caredoesn't care > C++ ABI break ABI break I believe C++ could work around the new methods approach by padding classes with stub vcalls and using those for new methods. > Java ABI break OK > C#ABI break OK > Here "doesn't care" means that the language doesn't really care much about > the issue, though there may be problems as the mentioned > NULL dereferences (nothing much can be done in Gtk+ here, except what > Sven rightly mentioned about checking for NULL method implementations > and updating the documentation to match, so other people follow this > pattern as well). If you install a default handler for the new interface method there is never any NULL problem. > If the above table is correct (please send me corrections or add more > language bindings) it seems that adding new interfaces would be the > preferred extension mechanism. There is another dimension too. Extension of an interface is often the most natural way for people using the interface in C. Having a totally new interface for a minor optional addition to an interface is pretty ugly. ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Signals with gchar** arguments
On Thu, 2007-11-15 at 12:52 +0100, Mathias Hasselmann wrote: > static void > authenticate (SoupSession *session, > /* other arguments... */ > gchar **username, > gchar **password, > gpointer user_data) > { > /* ... */ > > g_free (*username); > *username = g_strdup (lookup_username ()); > > /* ... */ > } > > Notice that this use of "gchar**" arguments is different from the usage > as "NULL terminated arrays of strings", aka. "G_TYPE_STRV". this is probably the most evil use of signals I've seen in a while. ;-) the SoupSession should really take a AuthenticateCallback function and emit a signal on success or one on failure. ciao, Emmanuele. -- Emmanuele Bassi, W: http://www.emmanuelebassi.net B: http://log.emmanuelebassi.net ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Signals with gchar** arguments
On Thu, 2007-11-15 at 23:28 +1100, James "Doc" Livingston wrote: > On Thu, 2007-11-15 at 12:52 +0100, Mathias Hasselmann wrote: > > Currently glib doesn't provide a fundamental type for dealing with that > > kind of arguments, so usually G_TYPE_POINTER is used as argument for the > > g_signal_new call registering such signals. Technically this works, but > > it leads to bad API documentation. The signal argument is documented as > > "gpointer" whilst being in fact of the type "gchar**", which is quite a > > difference. > > As well as bad API documentation, it means that you can't use the signal > from many bindings (such as python), because they can't know what the > argument is supposed to be. This happens fairly often, so bindings hand-code their .defs files. For instance, for gtkmm the *-event signals have to be changed from GdkEvent to, for instance, GdkButtonEvent. It needs to be improved when pygtk one day uses the future full GObject introspection. > > So my question is: How to solve this issue? > > > > - Introduce a new fundamental type "G_TYPE_STRING_PTR" duplicating > > the behaviour of "G_TYPE_POINTER" under a new name. > > - Patch gtk-doc to retrieve the real argument by inspecting for > > instance the signature of the signal's virtual method? > > - Make the return type of the signal be char*, and use an appropriate > signal accumulator. That's no good if there are two gchar** parameters, as in this case. > Exactly what you should do depends on what semantics you want when > multiple handlers are registered on the signal, but one common method is > to stop the signal emission as soon as any handler returns a non-NULL > value, and use that as the return value of the signal. -- [EMAIL PROTECTED] www.murrayc.com www.openismus.com ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Signals with gchar** arguments
On Thu, 2007-11-15 at 12:52 +0100, Mathias Hasselmann wrote: > So my question is: How to solve this issue? > > - Introduce a new fundamental type "G_TYPE_STRING_PTR" duplicating > the behaviour of "G_TYPE_POINTER" under a new name. > - Patch gtk-doc to retrieve the real argument by inspecting for > instance the signature of the signal's virtual method? - Use a helper object that has methods (or fields) to set the string. Jürg ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: Signals with gchar** arguments
On Thu, 2007-11-15 at 12:52 +0100, Mathias Hasselmann wrote: > Currently glib doesn't provide a fundamental type for dealing with that > kind of arguments, so usually G_TYPE_POINTER is used as argument for the > g_signal_new call registering such signals. Technically this works, but > it leads to bad API documentation. The signal argument is documented as > "gpointer" whilst being in fact of the type "gchar**", which is quite a > difference. As well as bad API documentation, it means that you can't use the signal from many bindings (such as python), because they can't know what the argument is supposed to be. > So my question is: How to solve this issue? > > - Introduce a new fundamental type "G_TYPE_STRING_PTR" duplicating > the behaviour of "G_TYPE_POINTER" under a new name. > - Patch gtk-doc to retrieve the real argument by inspecting for > instance the signature of the signal's virtual method? - Make the return type of the signal be char*, and use an appropriate signal accumulator. Exactly what you should do depends on what semantics you want when multiple handlers are registered on the signal, but one common method is to stop the signal emission as soon as any handler returns a non-NULL value, and use that as the return value of the signal. Cheers, -- "25 grams of wafers and 20 ml of wine undergo transubstantiation and become the flesh and blood of our Lord. How many Joules of heat are released by the transformation?" --Theological Physics exam, 1997 ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Signals with gchar** arguments
It happens that you want a signal having pointers to strings (gchar**) as argument. Those arguments are used to retrieve strings in the signal handler, and return them to the signal emitter. A prominent real-world example is the "authenticate" signal of SoupSession[1]: static void authenticate (SoupSession *session, /* other arguments... */ gchar **username, gchar **password, gpointer user_data) { /* ... */ g_free (*username); *username = g_strdup (lookup_username ()); /* ... */ } Notice that this use of "gchar**" arguments is different from the usage as "NULL terminated arrays of strings", aka. "G_TYPE_STRV". Currently glib doesn't provide a fundamental type for dealing with that kind of arguments, so usually G_TYPE_POINTER is used as argument for the g_signal_new call registering such signals. Technically this works, but it leads to bad API documentation. The signal argument is documented as "gpointer" whilst being in fact of the type "gchar**", which is quite a difference. So my question is: How to solve this issue? - Introduce a new fundamental type "G_TYPE_STRING_PTR" duplicating the behaviour of "G_TYPE_POINTER" under a new name. - Patch gtk-doc to retrieve the real argument by inspecting for instance the signature of the signal's virtual method? Currently I use the approach of registering an artificial fundamental type of the name EpcStringPtr to get proper documentation in libepc: GType epc_string_ptr_get_type (void) { static GType type = G_TYPE_INVALID; if (!type) { static GTypeInfo info = { 0,/* class_size */ NULL, /* base_init */ NULL, /* base_finalize */ NULL, /* class_init */ NULL, /* class_finalize */ NULL, /* class_data */ 0,/* instance_size */ 0,/* n_preallocs */ NULL, /* instance_init */ NULL /* value_table */ }; static GTypeFundamentalInfo fundamental_info = { G_TYPE_FLAG_DERIVABLE }; info.value_table = g_type_value_table_peek (G_TYPE_POINTER); g_assert (NULL != info.value_table); type = g_type_register_fundamental (g_type_fundamental_next (), g_intern_static_string ("EpcStringPtr"), &info, &fundamental_info, 0); } return type; } It fulfills my needs of documenting the argument type, but my feeling is there should be a better solution for this problem. Feels like shooting birds with cannons ("to break a butterfly on a wheel"?). Ciao, Mathias [1] http://library.gnome.org/devel/libsoup/2.2/SoupSession.html#SoupSession-authenticate -- Mathias Hasselmann <[EMAIL PROTECTED]> http://taschenorakel.de/ signature.asc Description: Dies ist ein digital signierter Nachrichtenteil ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Re: GInterfaces and API Stability
On 11/14/07 Sven Herzberg wrote: > I think it's not about "the compiler doesn't barf". It was a design > decision to be able to always extend interfaces. The only thing GTK+ I guess this is a documentation issue, then, as this design decision is not mentioned at all in the GObject documentation at http://library.gnome.org/devel/gobject/unstable/gtype-non-instantiable-classed.html. It actually says that GInterfaces are very similar to Java interfaces but Java interfaces definitely don't allow adding new methods (without breaking previously working code). > (talking about the concrete additions) has to handle non-implementations > gracefully, which it easily can by NULL-checking before calling into the > interface implementation. Even a default implementation can be added to > be called if the interface function is not explicitly implemented. > > This reminds me of the Microsoft API Design video that Philipp van Hoof > has blogged about. The speaker even claims that MS is extending their > .Net-interfaces in similar ways. I didn't watch that video, but this claim looks strange. Adding a method to an interface in C#/CLI will break the code and I don't know of a single case where this happened. What happens instead is that a new interface is defined and the relevant types are extended to implement the new interface. This is exactly what Mike suggested. Regardless, even if a future .net implementation allowed adding methods to interfaces, this wouldn't address Java's needs (but I don't know the status of the java bindings: do they support GInterfaces at all?And if they do, do they use Java interfaces? In the following I assume they do). So, let's create a table with the options available in the C libs and in the bindings and see if there is a compromise that would make most people happy. Please comment on this, as my understanding of some of the bindings is lacking. In GObject (and Gtk+) we have two options: adding new methods to existing interfaces or adding new interfaces. Let's see how the major bindings cope with this: new methods new interface Python doesn't caredoesn't care Perldoesn't caredoesn't care Rubydoesn't caredoesn't care C++ ABI break ABI break JavaABI break OK C# ABI break OK Here "doesn't care" means that the language doesn't really care much about the issue, though there may be problems as the mentioned NULL dereferences (nothing much can be done in Gtk+ here, except what Sven rightly mentioned about checking for NULL method implementations and updating the documentation to match, so other people follow this pattern as well). "ABI break" means that following the existing implementation of GInterfaces for the language (or following the most natural implementation of the concept for the language) the ABI would break when the change is introduced. There may be workarounds (like just using the C function in C++ or explicitly adding new interfaces for C# and Java). If the above table is correct (please send me corrections or add more language bindings) it seems that adding new interfaces would be the preferred extension mechanism. lupus -- - [EMAIL PROTECTED] debian/rules [EMAIL PROTECTED] Monkeys do it better ___ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list