From 109252d0e634fd3eda697459e8482b9d48d92ec6 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Thu, 29 Sep 2011 18:20:13 +0100 Subject: Support run-time backend detection Clutter moved to multi-backend support, so we need to perform run-time checks along with the compile-time ones. We can also check for the GDK backend that is available since Clutter 1.9 and use it. --- clutter-gtk/Makefile.am | 4 +- clutter-gtk/gtk-clutter-actor.c | 62 ++++++++------ clutter-gtk/gtk-clutter-embed.c | 178 +++++++++++++++++++++++++++------------- clutter-gtk/gtk-clutter-util.c | 103 ++++++++++++++--------- 4 files changed, 228 insertions(+), 119 deletions(-) (limited to 'clutter-gtk') diff --git a/clutter-gtk/Makefile.am b/clutter-gtk/Makefile.am index ebc0800..9a35919 100644 --- a/clutter-gtk/Makefile.am +++ b/clutter-gtk/Makefile.am @@ -17,7 +17,7 @@ AM_CPPFLAGS = \ $(CLUTTER_GTK_DEBUG_CFLAGS) \ $(NULL) -AM_CFLAGS = $(MAINTAINER_CFLAGS) $(CLUTTER_CFLAGS) $(GTK_CFLAGS) +AM_CFLAGS = $(MAINTAINER_CFLAGS) $(CLUTTER_GTK_DEPS_CFLAGS) lib_LTLIBRARIES = libclutter-gtk-@CLUTTER_GTK_API_VERSION@.la @@ -45,7 +45,7 @@ source_h_private = \ # please, keep the list sorted alphabetically libclutter_gtk_@CLUTTER_GTK_API_VERSION@_la_SOURCES = $(source_c) $(source_h) $(source_h_private) -libclutter_gtk_@CLUTTER_GTK_API_VERSION@_la_LIBADD = $(CLUTTER_LIBS) $(GTK_LIBS) $(LIBM) +libclutter_gtk_@CLUTTER_GTK_API_VERSION@_la_LIBADD = $(CLUTTER_GTK_DEPS_LIBS) $(LIBM) libclutter_gtk_@CLUTTER_GTK_API_VERSION@_la_LDFLAGS = \ $(CLUTTER_LT_LDFLAGS) \ -export-symbols-regex "^gtk_clutter.*" diff --git a/clutter-gtk/gtk-clutter-actor.c b/clutter-gtk/gtk-clutter-actor.c index 9016b77..af65a2b 100644 --- a/clutter-gtk/gtk-clutter-actor.c +++ b/clutter-gtk/gtk-clutter-actor.c @@ -48,18 +48,22 @@ #include -#if defined(HAVE_CLUTTER_GTK_X11) - +#ifdef CLUTTER_WINDOWING_X11 #include +#endif +#ifdef GDK_WINDOWING_X11 #include +#endif +#ifdef CAIRO_HAS_XLIB_SURFACE #include +#endif -#elif defined(HAVE_CLUTTER_GTK_WIN32) - +#ifdef CLUTTER_WINDOWING_WIN32 #include +#endif +#ifdef GDK_WINDOWING_WIN32 #include - -#endif /* HAVE_CLUTTER_GTK_{X11,WIN32} */ +#endif static void clutter_container_iface_init (ClutterContainerIface *iface); @@ -133,8 +137,9 @@ gtk_clutter_actor_realize (ClutterActor *actor) priv->surface = _gtk_clutter_offscreen_get_surface (GTK_CLUTTER_OFFSCREEN (priv->widget)); -#if HAVE_CLUTTER_GTK_X11 - if (cairo_surface_get_type (priv->surface) == CAIRO_SURFACE_TYPE_XLIB) +#if defined(CLUTTER_WINDOWING_X11) && defined(CAIRO_HAS_XLIB_SURFACE) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11) && + cairo_surface_get_type (priv->surface) == CAIRO_SURFACE_TYPE_XLIB) { Drawable pixmap; gint pixmap_width, pixmap_height; @@ -276,8 +281,9 @@ gtk_clutter_actor_allocate (ClutterActor *actor, surface = gdk_offscreen_window_get_surface (window); if (surface != priv->surface) { -#if HAVE_CLUTTER_GTK_X11 - if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB) +#if defined(CLUTTER_WINDOWING_X11) && defined(CAIRO_HAS_XLIB_SURFACE) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11) && + cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB) { Drawable pixmap = cairo_xlib_surface_get_drawable (surface); @@ -504,18 +510,21 @@ gtk_clutter_actor_init (GtkClutterActor *self) clutter_actor_push_internal (actor); -#if HAVE_CLUTTER_GTK_X11 - priv->texture = clutter_x11_texture_pixmap_new (); - - clutter_texture_set_sync_size (CLUTTER_TEXTURE (priv->texture), FALSE); - clutter_actor_set_parent (priv->texture, actor); - clutter_actor_set_name (priv->texture, "Onscreen Texture"); - clutter_actor_show (priv->texture); -#else - g_critical ("Embedding GtkWidget inside ClutterActor through " - "GtkClutterActor does not yet work on non-X11 " - "platforms."); +#if defined(CLUTTER_WINDOWING_X11) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) + { + priv->texture = clutter_x11_texture_pixmap_new (); + + clutter_texture_set_sync_size (CLUTTER_TEXTURE (priv->texture), FALSE); + clutter_actor_set_parent (priv->texture, actor); + clutter_actor_set_name (priv->texture, "Onscreen Texture"); + clutter_actor_show (priv->texture); + } + else #endif + g_critical ("Embedding GtkWidget inside ClutterActor through " + "GtkClutterActor does not yet work on non-X11 " + "platforms."); clutter_actor_pop_internal (actor); @@ -605,11 +614,14 @@ _gtk_clutter_actor_update (GtkClutterActor *actor, gint width, gint height) { - GtkClutterActorPrivate *priv = actor->priv; +#if defined(CLUTTER_WINDOWING_X11) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) + { + GtkClutterActorPrivate *priv = actor->priv; -#if HAVE_CLUTTER_GTK_X11 - clutter_x11_texture_pixmap_update_area (CLUTTER_X11_TEXTURE_PIXMAP (priv->texture), - x, y, width, height); + clutter_x11_texture_pixmap_update_area (CLUTTER_X11_TEXTURE_PIXMAP (priv->texture), + x, y, width, height); + } #endif clutter_actor_queue_redraw (CLUTTER_ACTOR (actor)); diff --git a/clutter-gtk/gtk-clutter-embed.c b/clutter-gtk/gtk-clutter-embed.c index 7cabfe5..0863f28 100644 --- a/clutter-gtk/gtk-clutter-embed.c +++ b/clutter-gtk/gtk-clutter-embed.c @@ -45,17 +45,25 @@ #include -#if defined(HAVE_CLUTTER_GTK_X11) - +#if defined(CLUTTER_WINDOWING_X11) #include -#include +#endif -#elif defined(HAVE_CLUTTER_GTK_WIN32) +#if defined(CLUTTER_WINDOWING_GDK) +#include +#endif +#if defined(CLUTTER_WINDOWING_WIN32) #include -#include +#endif -#endif /* HAVE_CLUTTER_GTK_{X11,WIN32} */ +#if defined(GDK_WINDOWING_X11) +#include +#endif + +#if defined(GDK_WINDOWING_WIN32) +#include +#endif G_DEFINE_TYPE (GtkClutterEmbed, gtk_clutter_embed, GTK_TYPE_CONTAINER); @@ -183,12 +191,26 @@ gtk_clutter_filter_func (GdkXEvent *native_event, GdkEvent *event G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED) { -#ifdef HAVE_CLUTTER_GTK_X11 - XEvent *xevent = native_event; +#if defined(CLUTTER_WINDOWING_X11) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) + { + XEvent *xevent = native_event; - /* let Clutter handle all events coming from the windowing system */ - clutter_x11_handle_event (xevent); + /* let Clutter handle all events coming from the windowing system */ + clutter_x11_handle_event (xevent); + } + else +#endif +#if defined(CLUTTER_WINDOWING_WIN32) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_WIN32)) + { + MSG *msg = native_event; + + clutter_win32_handle_event (msg); + } + else #endif + g_critical ("Unsuppored Clutter backend"); /* we don't care if Clutter handled the event: we want GDK to continue * the event processing as usual @@ -207,28 +229,27 @@ gtk_clutter_embed_realize (GtkWidget *widget) gint attributes_mask; gint border_width; - static gboolean filter_installed = FALSE; - -#ifdef HAVE_CLUTTER_GTK_X11 - { - const XVisualInfo *xvinfo; - GdkVisual *visual; - - /* We need to use the colormap from the Clutter visual, since - * the visual is tied to the GLX context - */ - xvinfo = clutter_x11_get_visual_info (); - if (xvinfo == None) - { - g_critical ("Unable to retrieve the XVisualInfo from Clutter"); - return; - } - - visual = gdk_x11_screen_lookup_visual (gtk_widget_get_screen (widget), - xvinfo->visualid); - gtk_widget_set_visual (widget, visual); - } -#endif /* HAVE_CLUTTER_GTK_X11 */ +#if defined(GDK_WINDOWING_X11) && defined(CLUTTER_WINDOWING_X11) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11)) + { + const XVisualInfo *xvinfo; + GdkVisual *visual; + + /* We need to use the colormap from the Clutter visual, since + * the visual is tied to the GLX context + */ + xvinfo = clutter_x11_get_visual_info (); + if (xvinfo == None) + { + g_critical ("Unable to retrieve the XVisualInfo from Clutter"); + return; + } + + visual = gdk_x11_screen_lookup_visual (gtk_widget_get_screen (widget), + xvinfo->visualid); + gtk_widget_set_visual (widget, visual); + } +#endif gtk_widget_set_realized (widget, TRUE); @@ -261,6 +282,7 @@ gtk_clutter_embed_realize (GtkWidget *widget) window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); + gtk_widget_set_window (widget, window); gdk_window_set_user_data (window, widget); @@ -274,19 +296,44 @@ gtk_clutter_embed_realize (GtkWidget *widget) style_context = gtk_widget_get_style_context (widget); gtk_style_context_set_background (style_context, window); - if (G_UNLIKELY (!filter_installed)) +#if defined(CLUTTER_WINDOWING_GDK) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_GDK)) + { + clutter_gdk_set_stage_foreign (CLUTTER_STAGE (priv->stage), window); + } + else +#endif +#if defined(GDK_WINDOWING_X11) && defined(CLUTTER_WINDOWING_X11) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11) && + GDK_IS_X11_WINDOW (window)) { - filter_installed = TRUE; - gdk_window_add_filter (NULL, gtk_clutter_filter_func, widget); + static gboolean has_filter = FALSE; + + clutter_x11_set_stage_foreign (CLUTTER_STAGE (priv->stage), GDK_WINDOW_XID (window)); + + if (G_UNLIKELY (!has_filter)) + { + gdk_window_add_filter (NULL, gtk_clutter_filter_func, widget); + has_filter = TRUE; + } } + else +#endif +#if defined(GDK_WINDOWING_WIN32) && defined(CLUTTER_WINDOWING_WIN32) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_WIN32) && + GDK_IS_WIN32_WINDOW (window)) + { + static gboolean has_filter = FALSE; -#if defined(HAVE_CLUTTER_GTK_X11) - clutter_x11_set_stage_foreign (CLUTTER_STAGE (priv->stage), - GDK_WINDOW_XID (window)); -#elif defined(HAVE_CLUTTER_GTK_WIN32) - clutter_win32_set_stage_foreign (CLUTTER_STAGE (priv->stage), - GDK_WINDOW_HWND (window)); -#endif /* HAVE_CLUTTER_GTK_{X11,WIN32} */ + clutter_win32_set_stage_foreign (CLUTTER_STAGE (priv->stage), GDK_WINDOW_HWND (window)); + + if (G_UNLIKELY (!has_filter)) + { + gdk_window_add_filter (NULL, gtk_clutter_filter_func, widget); + has_filter = TRUE; + } + } +#endif clutter_actor_realize (priv->stage); @@ -350,6 +397,8 @@ gtk_clutter_embed_map_event (GtkWidget *widget, clutter_actor_map (priv->stage); + clutter_actor_queue_redraw (priv->stage); + return res; } @@ -450,10 +499,10 @@ gtk_clutter_embed_style_updated (GtkWidget *widget) ClutterSettings *clutter_settings; gchar *font_name; gint double_click_time, double_click_distance; -#if HAVE_CLUTTER_GTK_X11 +#if defined(GDK_WINDOWING_X11) && defined(CLUTTER_WINDOWING_X11) gint xft_dpi, xft_hinting, xft_antialias; gchar *xft_hintstyle, *xft_rgba; -#endif /* HAVE_CLUTTER_GTK_X11 */ +#endif if (gtk_widget_get_realized (widget)) { @@ -490,15 +539,21 @@ gtk_clutter_embed_style_updated (GtkWidget *widget) "gtk-font-name", &font_name, "gtk-double-click-time", &double_click_time, "gtk-double-click-distance", &double_click_distance, -#if HAVE_CLUTTER_GTK_X11 - "gtk-xft-dpi", &xft_dpi, - "gtk-xft-antialias", &xft_antialias, - "gtk-xft-hinting", &xft_hinting, - "gtk-xft-hintstyle", &xft_hintstyle, - "gtk-xft-rgba", &xft_rgba, -#endif /* HAVE_CLUTTER_GTK_X11 */ NULL); +#if defined(GDK_WINDOWING_X11) && defined(CLUTTER_WINDOWING_X11) + if (GDK_IS_X11_SCREEN (screen)) + { + g_object_get (G_OBJECT (gtk_settings), + "gtk-xft-dpi", &xft_dpi, + "gtk-xft-antialias", &xft_antialias, + "gtk-xft-hinting", &xft_hinting, + "gtk-xft-hintstyle", &xft_hintstyle, + "gtk-xft-rgba", &xft_rgba, + NULL); + } +#endif + /* copy all settings and values coming from GTK+ into * the ClutterBackend; this way, a scene embedded into * a GtkClutterEmbed will not look completely alien @@ -508,19 +563,19 @@ gtk_clutter_embed_style_updated (GtkWidget *widget) "font-name", font_name, "double-click-time", double_click_time, "double-click-distance", double_click_distance, -#if HAVE_CLUTTER_GTK_X11 +#if defined(GDK_WINDOWING_X11) && defined(CLUTTER_WINDOWING_X11) "font-antialias", xft_antialias, "font-dpi", xft_dpi, "font-hinting", xft_hinting, "font-hint-style", xft_hintstyle, "font-subpixel-order", xft_rgba, -#endif /* HAVE_CLUTTER_GTK_X11 */ +#endif NULL); -#if HAVE_CLUTTER_GTK_X11 +#if defined(GDK_WINDOWING_X11) && defined(CLUTTER_WINDOWING_X11) g_free (xft_hintstyle); g_free (xft_rgba); -#endif /* HAVE_CLUTTER_GTK_X11 */ +#endif g_free (font_name); @@ -601,6 +656,18 @@ gtk_clutter_embed_child_type (GtkContainer *container) return GTK_CLUTTER_TYPE_OFFSCREEN; } +static gboolean +gtk_clutter_embed_event (GtkWidget *widget, + GdkEvent *event) +{ +#if defined(CLUTTER_WINDOWING_GDK) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_GDK)) + clutter_gdk_handle_event (event); +#endif + + return FALSE; +} + static void gtk_clutter_embed_class_init (GtkClutterEmbedClass *klass) { @@ -625,6 +692,7 @@ gtk_clutter_embed_class_init (GtkClutterEmbedClass *klass) widget_class->focus_out_event = gtk_clutter_embed_focus_out; widget_class->key_press_event = gtk_clutter_embed_key_event; widget_class->key_release_event = gtk_clutter_embed_key_event; + widget_class->event = gtk_clutter_embed_event; container_class->add = gtk_clutter_embed_add; container_class->remove = gtk_clutter_embed_remove; diff --git a/clutter-gtk/gtk-clutter-util.c b/clutter-gtk/gtk-clutter-util.c index be9f4ee..61c1d7a 100644 --- a/clutter-gtk/gtk-clutter-util.c +++ b/clutter-gtk/gtk-clutter-util.c @@ -11,17 +11,25 @@ #include #include -#if defined(HAVE_CLUTTER_GTK_X11) +#if defined(CLUTTER_WINDOWING_GDK) +#include +#endif +#if defined(CLUTTER_WINDOWING_X11) #include -#include - -#elif defined(HAVE_CLUTTER_GTK_WIN32) +#endif +#if defined(CLUTTER_WINDOWING_WIN32) #include -#include +#endif -#endif /* HAVE_CLUTTER_GTK_{X11,WIN32} */ +#if defined(GDK_WINDOWING_X11) +#include +#endif + +#if defined(GDK_WINDOWING_WIN32) +#include +#endif /** * SECTION:gtk-clutter-util @@ -48,27 +56,50 @@ post_parse_hook (GOptionContext *context, gpointer data, GError **error) { + GdkDisplay *display; + gtk_clutter_is_initialized = TRUE; - gdk_disable_multidevice (); + display = gdk_display_get_default (); -#if defined(HAVE_CLUTTER_GTK_X11) -# if CLUTTER_CHECK_VERSION (1, 1, 5) - /* enable ARGB visuals by default for Clutter */ - clutter_x11_set_use_argb_visual (TRUE); -# endif -#endif +#if defined(CLUTTER_WINDOWING_GDK) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_GDK)) + { + clutter_gdk_set_display (gdk_display_get_default ()); -#if defined(GDK_WINDOWING_X11) - /* share the X11 Display with GTK+ */ - clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); - - /* let GTK+ in charge of the event handling */ - clutter_x11_disable_event_retrieval (); -#elif defined(GDK_WINDOWING_WIN32) - /* let GTK+ in charge of the event handling */ - clutter_win32_disable_event_retrieval (); -#endif /* GDK_WINDOWING_{X11,WIN32} */ + /* let GDK be in charge of the event handling */ + clutter_gdk_disable_event_retrieval (); + } + else +#endif +#if defined(GDK_WINDOWING_X11) && defined(CLUTTER_WINDOWING_X11) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11) && + GDK_IS_X11_DISPLAY (display)) + { + /* we need XI enabled because GTK will enable it by default as well */ + clutter_x11_enable_xinput (); + + /* enable ARGB visuals by default for Clutter */ + clutter_x11_set_use_argb_visual (TRUE); + + /* share the X11 Display with GTK+ */ + clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); + + /* let GTK+ be in charge of the event handling */ + clutter_x11_disable_event_retrieval (); + } + else +#endif +#if defined(GDK_WINDOWING_WIN32) && defined(CLUTTER_WINDOWING_WIN32) + if (clutter_check_windowing_backend (CLUTTER_WINDOWING_WIN32) && + GDK_IS_WIN32_DISPLAY (display)) + { + /* let GTK+ be in charge of the event handling */ + clutter_win32_disable_event_retrieval (); + } + else +#endif + g_error ("*** Unsupported backend."); /* this is required since parsing clutter's option group did not * complete the initialization process @@ -150,26 +181,26 @@ gtk_clutter_init (int *argc, gtk_clutter_is_initialized = TRUE; - gdk_disable_multidevice (); - if (!gtk_init_check (argc, argv)) return CLUTTER_INIT_ERROR_UNKNOWN; -#if defined(HAVE_CLUTTER_GTK_X11) -# if CLUTTER_CHECK_VERSION (1, 1, 5) - /* enable ARGB visuals by default for Clutter */ +#if defined(CLUTTER_WINDOWING_GDK) + clutter_gdk_disable_event_retrieval (); +#endif + +#if defined(GDK_WINDOWING_X11) && defined(CLUTTER_WINDOWING_X11) + clutter_x11_enable_xinput (); + clutter_x11_set_use_argb_visual (TRUE); -# endif - /* share the X11 Display with GTK+ */ clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); - /* let GTK+ in charge of the event handling */ clutter_x11_disable_event_retrieval (); -#elif defined(HAVE_CLUTTER_GTK_WIN32) - /* let GTK+ in charge of the event handling */ +#endif + +#if defined(CLUTTER_WINDOWING_WIN32) clutter_win32_disable_event_retrieval (); -#endif /* HAVE_CLUTTER_GTK_{X11,WIN32} */ +#endif return clutter_init (argc, argv); } @@ -211,9 +242,7 @@ gtk_clutter_init_with_args (int *argc, if (gtk_clutter_is_initialized) return CLUTTER_INIT_SUCCESS; - gdk_disable_multidevice (); - -#if defined(GDK_WINDOWING_X11) && CLUTTER_CHECK_VERSION (1, 1, 5) +#if defined(CLUTTER_WINDOWING_X11) /* enable ARGB visuals by default for Clutter */ clutter_x11_set_use_argb_visual (TRUE); #endif -- cgit v1.2.1