Re: Building multiple backends on on same system



On Mon, 2010-12-06 at 16:17 +0000, Benjamin Otte wrote:
> Alexander Larsson <alexl <at> redhat.com> writes:
> > Support specifying multiple targets in --with-gdktarget, then build a
> > single libgtk-3.0.so supporting all of these, switching at runtime. At
> > one time i was thinking we could load the backends dynamically to avoid
> > linking to all the dependencies of all backends, but since cairo links
> > in all backends in the same library anyway this will not work.
> > 
> I suppose you're targetting something similar to Cairo? So that you can query 
> the backend of a GdkWindow or GdkVisual or GdkDisplay at runtime? And when 
> starting the application you pick a certain default backend?

Yeah.

> > We then have a gtk+-3.0.pc file that does not pull in any backend
> > libraries (like xlib) into the app. The we add e.g. gtk+-x11-3.0 that
> > contains the backend specific headers like gdkx.h, the backend libraries
> > and headers. This file would be installed only if gtk+ was built with X
> > support of course.
> > 
> or we'd do it like Cairo and uild all of them into libgtk.so. But that's a 
> detail I don't particularly care about. The only important thing is that 
> libgtk knows what the default backend to is and has a way to use it.

This is exactly how i meant. Maybe i described it poorly. gtk+-x11-3.0
will only contain gdk/gdkx.h and the set of -L/usr/X11/inclue -lX11 type
of flags.

> > Then we take the current internal defines like GDK_WINDOWING_X11 and put
> > the supported ones in a public header, so that apps can build
> > conditional backend support. Additionally we now allow multiple of these
> > to be defined in the same build.
> > 
> > Then we add a GdkBackend type that each backend implements. This is a
> > singleton created at init to hang global stuff off. Its also useful for
> > backend specific code. For instance:
> > 
> > #ifdef GDK_WINDOWING_X11
> >   if (timestamp != GDK_CURRENT_TIME)
> >     gdk_x11_window_set_user_time (gdk_window, timestamp);
> > #endif
> > 
> > Will turn into:
> > 
> > #ifdef GDK_WINDOWING_X11
> >    if (GDK_IS_BACKEND_X11 (gdk_backend_get ()))
> >      {
> >       if (timestamp != GDK_CURRENT_TIME)
> > 	gdk_x11_window_set_user_time (gdk_window, timestamp);
> >      }
> > #endif
> > 
> I would make that part of the GdkDisplay, as that pretty much is our 
> current singleton. So you'd do something like:
> 
> #ifdef GDK_WINDOWING_X11
>   if (GDK_IS_X11_DISPLAY (display))
>     {
>       if (timestamp != GDK_CURRENT_TIME)
>         gdk_x11_window_set_user_time (gdk_window, timestamp);
>     }
> #endif

You can of course check on the type of anything, like the display or a
window. However, sometimes there might be no display availible, like if
its not been opened yet.

> > Additionally, I think we should drop libgdk.so and just combine the two
> > into one. There are no users of gdk without gtk anyway, and gtk has
> > backend specific code in it anyway, so gdk is not a full abstraction.
> > This will get us one less library, plus it will make all gdk calls from
> > gtk+ intra-object calls which is a (minor) performance gain.
> > 
> I do like the split conceptually, because it forces us to define a sane 
> interface between GTK and the backends. But I guess as long as we keep 
> stuff in seperate directories and make sure to not let GTK use private APIs 
> (as it currently does in the configure event trickery ;)) we'll be fine and 
> it doesn't matter if we use noinst_LTLIBRIRES or lib_LTLIBRARIES for libgdk.

We already have some _libgtk_only gdk symbols... But, i don't mean to
drop the distinction in the implementation, just not force the overhead
of it on the user.

> > * Convert all backend object method calls to true vtable calls, rather
> > than have the linker pick the right one. (For instance,
> > gdk_device_ungrab() is right now duplicated in each backend, and relies
> > on the linker to pick the one from the backend you link with. Obviously
> > this will not work in a multi-backend scenario, instead we need a single
> > gdk_device_ungrab() call in the common code that does a vcall on the
> > GdkDevice class.)
> > 
> I somewhat disagree on this one. At least in the case of GdkWindow do we have 
> a sane abstraction in the form of GdkWindowImpl already that we can put into 
> the backend. So making all GdkWindow APIs vfuncs doesn't sound like that 
> awesome of an idea to me. For most the other types, we need to add more vfuncs 
> though.

Yes, obviously on the GdkWindow case we use the Impl (and the code in
the branch already does this). However, for the other types we use the
normal class.

> > * Convert GdkCursor to a GObject so we get a class vtable
> > 
> That should have been done ages ago. Will do that now.

Where are you commiting this? The gdk-backend branch?

> > * (Optionally) move code common to all backends (for instance,  
> >   typechecks, etc) from the backend code to the common code that does
> >   the vtable call.
> >
> I'd go the other way and move code into backends only when it can't stay in 
> the core implementation. Otherwise we'll end up with lots of duplications 
> again. And I just worked hard to get rid of that...

Obviously we should not add new code in multiple places. I was talking
about the exisiting code that was already duplicated and could (with a
bunch of work) be combined back into the new shared code. However, this
is optional in the sense that it could be done later.

> > * Add a GdkBackend type, derive from this in all backends
> > 
> See my comment above about using GdkDisplay for that.

This is not right at all. There can be zero or multiple display objects
in any single gtk+ app.

> > * Convert all global functions (both external and gdk internal ones) in
> >   the backend to vtable calls on the backend object.
> > 
> Do we have lots of those? I mean functions that differ between backends and 
> don't take some sort of GObject as an argument? Could we hang them off 
> GdkDisplay?

Yes, there are many. Let me enumerate some:

gdk_add_client_message_filter
gdk_atom_intern
gdk_error_trap_pop
gdk_query_depths
gdk_utf8_to_string_target
gdk_set_locale
etc, etc

> Also, do you target this for 3.0? Because I don't think it's doable in an 
> API-stable way during 3.x?

What API changes do you envision? I expect this to be both API and ABI
compat.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
       alexl redhat com            alexander larsson gmail com 
He's an uncontrollable moralistic master criminal for the 21st century. She's 
a foxy green-skinned mermaid from the wrong side of the tracks. They fight 
crime! 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]