Add API to restrict the windowing backend to load

In situations when the default backend would fail (for example
when compiled with X11 support but run without DISPLAY), or
when the application is using backend specific code, it makes
sense to let the application choose the backend explicitly.

https://bugzilla.gnome.org/show_bug.cgi?id=707869
This commit is contained in:
Giovanni Campagna 2013-09-10 18:29:28 +02:00
parent 5c035f2107
commit da3e6988ad
5 changed files with 83 additions and 50 deletions

View File

@ -99,6 +99,8 @@ struct _ClutterBackendClass
void (* settings_changed) (ClutterBackend *backend); void (* settings_changed) (ClutterBackend *backend);
}; };
ClutterBackend * _clutter_create_backend (void);
ClutterStageWindow * _clutter_backend_create_stage (ClutterBackend *backend, ClutterStageWindow * _clutter_backend_create_stage (ClutterBackend *backend,
ClutterStage *wrapper, ClutterStage *wrapper,
GError **error); GError **error);

View File

@ -83,6 +83,9 @@
/* XXX - should probably warn, here */ /* XXX - should probably warn, here */
#include "tslib/clutter-event-tslib.h" #include "tslib/clutter-event-tslib.h"
#endif #endif
#ifdef CLUTTER_WINDOWING_EGL
#include "egl/clutter-backend-eglnative.h"
#endif
#ifdef CLUTTER_INPUT_WAYLAND #ifdef CLUTTER_INPUT_WAYLAND
#include "wayland/clutter-device-manager-wayland.h" #include "wayland/clutter-device-manager-wayland.h"
#endif #endif
@ -126,6 +129,7 @@ static guint backend_signals[LAST_SIGNAL] = { 0, };
static struct wl_display *_wayland_compositor_display; static struct wl_display *_wayland_compositor_display;
#endif #endif
static const char *allowed_backend;
static void static void
clutter_backend_dispose (GObject *gobject) clutter_backend_dispose (GObject *gobject)
@ -463,6 +467,58 @@ clutter_backend_real_create_stage (ClutterBackend *backend,
NULL); NULL);
} }
ClutterBackend *
_clutter_create_backend (void)
{
const char *backend = allowed_backend;
ClutterBackend *retval = NULL;
if (backend == NULL)
{
const char *backend_env = g_getenv ("CLUTTER_BACKEND");
if (backend_env != NULL)
backend = g_intern_string (backend_env);
}
#ifdef CLUTTER_WINDOWING_OSX
if (backend == NULL || backend == I_(CLUTTER_WINDOWING_OSX))
retval = g_object_new (CLUTTER_TYPE_BACKEND_OSX, NULL);
else
#endif
#ifdef CLUTTER_WINDOWING_WIN32
if (backend == NULL || backend == I_(CLUTTER_WINDOWING_WIN32))
retval = g_object_new (CLUTTER_TYPE_BACKEND_WIN32, NULL);
else
#endif
#ifdef CLUTTER_WINDOWING_X11
if (backend == NULL || backend == I_(CLUTTER_WINDOWING_X11))
retval = g_object_new (CLUTTER_TYPE_BACKEND_X11, NULL);
else
#endif
#ifdef CLUTTER_WINDOWING_WAYLAND
if (backend == NULL || backend == I_(CLUTTER_WINDOWING_WAYLAND))
retval = g_object_new (CLUTTER_TYPE_BACKEND_WAYLAND, NULL);
else
#endif
#ifdef CLUTTER_WINDOWING_EGL
if (backend == NULL || backend == I_(CLUTTER_WINDOWING_EGL))
retval = g_object_new (CLUTTER_TYPE_BACKEND_EGL_NATIVE, NULL);
else
#endif
#ifdef CLUTTER_WINDOWING_GDK
if (backend == NULL || backend == I_(CLUTTER_WINDOWING_GDK))
retval = g_object_new (CLUTTER_TYPE_BACKEND_GDK, NULL);
else
#endif
if (backend == NULL)
g_error ("No default Clutter backend found.");
else
g_error ("Unsupported Clutter backend: '%s'", backend);
return retval;
}
static void static void
clutter_backend_real_init_events (ClutterBackend *backend) clutter_backend_real_init_events (ClutterBackend *backend)
{ {
@ -506,8 +562,8 @@ clutter_backend_real_init_events (ClutterBackend *backend)
#endif #endif
#ifdef CLUTTER_INPUT_EVDEV #ifdef CLUTTER_INPUT_EVDEV
/* Evdev can be used regardless of the windowing system */ /* Evdev can be used regardless of the windowing system */
if (input_backend != NULL && if ((input_backend != NULL && strcmp (input_backend, CLUTTER_INPUT_EVDEV) == 0) ||
strcmp (input_backend, CLUTTER_INPUT_EVDEV) == 0) clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
{ {
_clutter_events_evdev_init (backend); _clutter_events_evdev_init (backend);
} }
@ -1326,3 +1382,21 @@ clutter_wayland_set_compositor_display (void *display)
_wayland_compositor_display = display; _wayland_compositor_display = display;
} }
#endif #endif
/**
* clutter_set_windowing_backend:
* @first_backend: the name of a clutter window backend
*
* Restricts clutter to only use the specified backend.
* This must be called before the first API call to clutter, including
* clutter_get_option_context()
*
* Since: 1.16
*/
void
clutter_set_windowing_backend (const char *backend_type)
{
g_return_if_fail (backend_type != NULL);
allowed_backend = g_intern_string (backend_type);
}

View File

@ -59,6 +59,9 @@ GType clutter_backend_get_type (void) G_GNUC_CONST;
ClutterBackend *clutter_get_default_backend (void); ClutterBackend *clutter_get_default_backend (void);
CLUTTER_AVAILABLE_IN_1_16
void clutter_set_windowing_backend (const char *backend_type);
gdouble clutter_backend_get_resolution (ClutterBackend *backend); gdouble clutter_backend_get_resolution (ClutterBackend *backend);
void clutter_backend_set_font_options (ClutterBackend *backend, void clutter_backend_set_font_options (ClutterBackend *backend,

View File

@ -1390,53 +1390,6 @@ _clutter_context_is_initialized (void)
return ClutterCntx->is_initialized; return ClutterCntx->is_initialized;
} }
static ClutterBackend *
clutter_create_backend (void)
{
const char *backend = g_getenv ("CLUTTER_BACKEND");
ClutterBackend *retval = NULL;
if (backend != NULL)
backend = g_intern_string (backend);
#ifdef CLUTTER_WINDOWING_OSX
if (backend == NULL || backend == I_(CLUTTER_WINDOWING_OSX))
retval = g_object_new (CLUTTER_TYPE_BACKEND_OSX, NULL);
else
#endif
#ifdef CLUTTER_WINDOWING_WIN32
if (backend == NULL || backend == I_(CLUTTER_WINDOWING_WIN32))
retval = g_object_new (CLUTTER_TYPE_BACKEND_WIN32, NULL);
else
#endif
#ifdef CLUTTER_WINDOWING_X11
if (backend == NULL || backend == I_(CLUTTER_WINDOWING_X11))
retval = g_object_new (CLUTTER_TYPE_BACKEND_X11, NULL);
else
#endif
#ifdef CLUTTER_WINDOWING_WAYLAND
if (backend == NULL || backend == I_(CLUTTER_WINDOWING_WAYLAND))
retval = g_object_new (CLUTTER_TYPE_BACKEND_WAYLAND, NULL);
else
#endif
#ifdef CLUTTER_WINDOWING_EGL
if (backend == NULL || backend == I_(CLUTTER_WINDOWING_EGL))
retval = g_object_new (CLUTTER_TYPE_BACKEND_EGL_NATIVE, NULL);
else
#endif
#ifdef CLUTTER_WINDOWING_GDK
if (backend == NULL || backend == I_(CLUTTER_WINDOWING_GDK))
retval = g_object_new (CLUTTER_TYPE_BACKEND_GDK, NULL);
else
#endif
if (backend == NULL)
g_error ("No default Clutter backend found.");
else
g_error ("Unsupported Clutter backend: '%s'", backend);
return retval;
}
static ClutterMainContext * static ClutterMainContext *
clutter_context_get_default_unlocked (void) clutter_context_get_default_unlocked (void)
{ {
@ -1449,7 +1402,7 @@ clutter_context_get_default_unlocked (void)
ctx->is_initialized = FALSE; ctx->is_initialized = FALSE;
/* create the windowing system backend */ /* create the windowing system backend */
ctx->backend = clutter_create_backend (); ctx->backend = _clutter_create_backend ();
/* create the default settings object, and store a back pointer to /* create the default settings object, and store a back pointer to
* the backend singleton * the backend singleton

View File

@ -1193,6 +1193,7 @@ clutter_settings_get_type
clutter_set_default_frame_rate clutter_set_default_frame_rate
clutter_set_font_flags clutter_set_font_flags
clutter_set_motion_events_enabled clutter_set_motion_events_enabled
clutter_set_windowing_backend
clutter_shader_compile clutter_shader_compile
clutter_shader_effect_get_program clutter_shader_effect_get_program
clutter_shader_effect_get_shader clutter_shader_effect_get_shader