[gtk+] Add gdk_set_allowed_backends



commit ce7c6d58c230bb1d03481b097fd10fddb3d79265
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Mar 23 00:16:24 2013 -0400

    Add gdk_set_allowed_backends
    
    This new function allows programmatic control over the
    GDK backends that will be used at runtime.

 docs/reference/gdk/gdk3-sections.txt |    1 +
 docs/reference/gtk/running.sgml      |    3 +
 gdk/gdk.symbols                      |    1 +
 gdk/gdkdisplaymanager.c              |  142 ++++++++++++++++++++++++++++-----
 gdk/gdkmain.h                        |    3 +
 5 files changed, 128 insertions(+), 22 deletions(-)
---
diff --git a/docs/reference/gdk/gdk3-sections.txt b/docs/reference/gdk/gdk3-sections.txt
index 3b05221..e409bbc 100644
--- a/docs/reference/gdk/gdk3-sections.txt
+++ b/docs/reference/gdk/gdk3-sections.txt
@@ -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
diff --git a/docs/reference/gtk/running.sgml b/docs/reference/gtk/running.sgml
index 576f83f..71fb7b3 100644
--- a/docs/reference/gtk/running.sgml
+++ b/docs/reference/gtk/running.sgml
@@ -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>
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols
index 1f99c64..6e30e9a 100644
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@ -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
diff --git a/gdk/gdkdisplaymanager.c b/gdk/gdkdisplaymanager.c
index 70b6a62..e29fa51 100644
--- a/gdk/gdkdisplaymanager.c
+++ b/gdk/gdkdisplaymanager.c
@@ -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;
diff --git a/gdk/gdkmain.h b/gdk/gdkmain.h
index 27788dd..05b15b9 100644
--- a/gdk/gdkmain.h
+++ b/gdk/gdkmain.h
@@ -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__ */


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