Add gdk_set_allowed_backends

This new function allows programmatic control over the
GDK backends that will be used at runtime.
This commit is contained in:
Matthias Clasen 2013-03-23 00:16:24 -04:00
parent 832c698776
commit ce7c6d58c2
5 changed files with 128 additions and 22 deletions

View File

@ -10,6 +10,7 @@ gdk_parse_args
gdk_get_display_arg_name
gdk_notify_startup_complete
gdk_notify_startup_complete_with_id
gdk_set_allowed_backends
<SUBSECTION>
gdk_get_program_class

View File

@ -461,6 +461,9 @@ nevertheless.
</varlistentry>
</variablelist>
Since 3.10, this environment variable can contain a comma-separated list
of backend names, which are tried in order. The list may also contain
a *, which means: try all remaining backends.
For more information about selecting backends, see the gdk_display_manager_get() function.
</para>
</formalpara>

View File

@ -335,6 +335,7 @@ gdk_set_program_class
gdk_set_show_events
gdk_setting_action_get_type
gdk_setting_get
gdk_set_allowed_backends
gdk_status_get_type
gdk_synthesize_window_state
gdk_test_render_sync

View File

@ -225,6 +225,48 @@ gdk_display_manager_get_property (GObject *object,
}
}
static const gchar *allowed_backends;
/**
* gdk_set_allowed_backends:
* @backends: a comma-separated list of backends
*
* Sets a list of backends that GDK should try to use.
*
* This can be be useful if your application does not
* work with certain GDK backends.
*
* By default, GDK tries all included backends.
*
* For example,
* <programlisting>
* gdk_set_allowed_backends ("wayland,quartz,*");
* </programlisting>
* instructs GDK to try the Wayland backend first,
* followed by the Quartz backend, and then all
* others.
*
* If the <envvar>GDK_BACKEND</envvar> environment variable
* is set, it determines what backends are tried in what
* order, while still respecting the set of allowed backends
* that are specified by this function.
*
* The possible backend names are x11, win32, quartz,
* broadway, wayland. You can also include a * in the
* list to try all remaining backends.
*
* This call must happen prior to gdk_display_open(),
* gtk_init(), gtk_init_with_args() or gtk_init_check()
* in order to take effect.
*
* Since: 3.10
*/
void
gdk_set_allowed_backends (const gchar *backends)
{
allowed_backends = g_strdup (backends);
}
/**
* gdk_display_manager_get:
*
@ -233,7 +275,8 @@ gdk_display_manager_get_property (GObject *object,
* When called for the first time, this function consults the
* <envar>GDK_BACKEND</envar> environment variable to find out which
* of the supported GDK backends to use (in case GDK has been compiled
* with multiple backends).
* with multiple backends). Applications can use gdk_set_allowed_backends()
* to limit what backends can be used.
*
* Returns: (transfer none): The global #GdkDisplayManager singleton;
* gdk_parse_args(), gdk_init(), or gdk_init_check() must have
@ -246,38 +289,93 @@ gdk_display_manager_get (void)
{
static GdkDisplayManager *manager = NULL;
if (!manager)
if (manager == NULL)
{
const gchar *backend;
const gchar *backend_list;
gchar **backends;
gint i;
gboolean allow_any;
if (allowed_backends == NULL)
allowed_backends = "*";
allow_any = strstr (allowed_backends, "*") != NULL;
backend_list = g_getenv ("GDK_BACKEND");
if (backend_list == NULL)
backend_list = allowed_backends;
backends = g_strsplit (backend_list, ",", 0);
for (i = 0; manager == NULL && backends[i] != NULL; i++)
{
const gchar *backend = backends[i];
gboolean any = g_str_equal (backend, "*");
if (!allow_any && !any && !strstr (allowed_backends, backend))
continue;
backend = g_getenv ("GDK_BACKEND");
#ifdef GDK_WINDOWING_QUARTZ
if (backend == NULL || strcmp (backend, "quartz") == 0)
manager = g_initable_new (gdk_quartz_display_manager_get_type (), NULL, NULL, NULL);
if ((any && allow_any) ||
(any && strstr (allowed_backends, "quartz")) ||
g_str_equal (backend, "quartz"))
{
GDK_NOTE (MISC, g_message ("Trying quartz backend"));
manager = g_initable_new (gdk_quartz_display_manager_get_type (), NULL, NULL, NULL);
if (manager)
break;
}
#endif
#ifdef GDK_WINDOWING_WIN32
if (!manager && (backend == NULL || strcmp (backend, "win32") == 0))
manager = g_initable_new (gdk_win32_display_manager_get_type (), NULL, NULL, NULL);
#endif
#ifdef GDK_WINDOWING_WAYLAND
if (!manager && (backend == NULL || strcmp (backend, "wayland") == 0))
manager = g_initable_new (gdk_wayland_display_manager_get_type (), NULL, NULL, NULL);
if ((any && allow_any) ||
(any && strstr (allowed_backends, "win32")) ||
g_str_equal (backend, "win32"))
{
GDK_NOTE (MISC, g_message ("Trying win32 backend"));
manager = g_initable_new (gdk_win32_display_manager_get_type (), NULL, NULL, NULL);
if (manager)
break;
}
#endif
#ifdef GDK_WINDOWING_X11
if (!manager && (backend == NULL || strcmp (backend, "x11") == 0))
manager = g_initable_new (gdk_x11_display_manager_get_type (), NULL, NULL, NULL);
if ((any && allow_any) ||
(any && strstr (allowed_backends, "x11")) ||
g_str_equal (backend, "x11"))
{
GDK_NOTE (MISC, g_message ("Trying x11 backend"));
manager = g_initable_new (gdk_x11_display_manager_get_type (), NULL, NULL, NULL);
if (manager)
break;
}
#endif
#ifdef GDK_WINDOWING_WAYLAND
if ((any && allow_any) ||
(any && strstr (allowed_backends, "wayland")) ||
g_str_equal (backend, "wayland"))
{
GDK_NOTE (MISC, g_message ("Trying wayland backend"));
manager = g_initable_new (gdk_wayland_display_manager_get_type (), NULL, NULL, NULL);
if (manager)
break;
}
#endif
#ifdef GDK_WINDOWING_BROADWAY
if (!manager && (backend == NULL || strcmp (backend, "broadway") == 0))
manager = g_initable_new (gdk_broadway_display_manager_get_type (), NULL, NULL, NULL);
if ((any && allow_any) ||
(any && strstr (allowed_backends, "broadway")) ||
g_str_equal (backend, "broadway"))
{
GDK_NOTE (MISC, g_message ("Trying broadway backend"));
manager = g_initable_new (gdk_broadway_display_manager_get_type (), NULL, NULL, NULL);
if (manager)
break;
}
#endif
if (!manager)
{
if (backend != NULL)
g_error ("Unsupported GDK backend: %s", backend);
else
g_error ("No GDK backend found");
}
g_strfreev (backends);
if (manager == NULL)
g_error ("No GDK backend found (%s)", allowed_backends);
GDK_NOTE (MISC, if (manager) g_message ("Using %s", G_OBJECT_TYPE_NAME (manager)));
}
return manager;

View File

@ -117,6 +117,9 @@ void gdk_flush (void);
void gdk_disable_multidevice (void);
GDK_AVAILABLE_IN_3_10
void gdk_set_allowed_backends (const gchar *backends);
G_END_DECLS
#endif /* __GDK_MAIN_H__ */