[gnome-settings-daemon] Bug 586276 - Don't spawn xrdb



commit aa32ea50fc596100750988513004f7b86148388a
Author: Martin Pitt <martin pitt ubuntu com>
Date:   Thu Jan 21 23:52:28 2010 +0100

    Bug 586276 - Don't spawn xrdb
    
    Use XLib calls to set the RESOURCE_MANAGER Xft.* properties in the xsettings
    and font plugins, instead of calling xrdb directly. This saves some startup
    time, since these plugins are in the critical path and everything else needs to
    wait for it.

 plugins/font/gsd-font-manager.c           |  137 +++++++++-------------------
 plugins/xsettings/gsd-xsettings-manager.c |  138 +++++++++-------------------
 2 files changed, 90 insertions(+), 185 deletions(-)
---
diff --git a/plugins/font/gsd-font-manager.c b/plugins/font/gsd-font-manager.c
index 7b6ce89..2c7135d 100644
--- a/plugins/font/gsd-font-manager.c
+++ b/plugins/font/gsd-font-manager.c
@@ -33,6 +33,8 @@
 
 #include <locale.h>
 
+#include <X11/Xatom.h>
+
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gdk/gdk.h>
@@ -52,86 +54,33 @@ G_DEFINE_TYPE (GsdFontManager, gsd_font_manager, G_TYPE_OBJECT)
 
 static gpointer manager_object = NULL;
 
-static gboolean
-write_all (int         fd,
-           const char *buf,
-           gsize       to_write)
-{
-        while (to_write > 0) {
-                gssize count = write (fd, buf, to_write);
-                if (count < 0) {
-                        if (errno != EINTR)
-                                return FALSE;
-                } else {
-                        to_write -= count;
-                        buf += count;
-                }
-        }
-
-        return TRUE;
-}
-
-static void
-child_watch_cb (GPid     pid,
-                int      status,
-                gpointer user_data)
-{
-        char *command = user_data;
-
-        gnome_settings_profile_end ("%s", command);
-        if (!WIFEXITED (status) || WEXITSTATUS (status)) {
-                g_warning ("Command %s failed", command);
-        }
-}
-
 static void
-spawn_with_input (const char *command,
-                  const char *input)
+update_property (GString *props, const gchar* key, const gchar* value)
 {
-        char   **argv;
-        int      child_pid;
-        int      inpipe;
-        GError  *error;
-        gboolean res;
-
-        argv = NULL;
-        res = g_shell_parse_argv (command, NULL, &argv, NULL);
-        if (! res) {
-                g_warning ("Unable to parse command: %s", command);
-                return;
-        }
-
-        gnome_settings_profile_start ("%s", command);
-        error = NULL;
-        res = g_spawn_async_with_pipes (NULL,
-                                        argv,
-                                        NULL,
-                                        G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
-                                        NULL,
-                                        NULL,
-                                        &child_pid,
-                                        &inpipe,
-                                        NULL,
-                                        NULL,
-                                        &error);
-        g_strfreev (argv);
-
-        if (! res) {
-                g_warning ("Could not execute %s: %s", command, error->message);
-                g_error_free (error);
-
-                return;
-        }
-
-        if (input != NULL) {
-                if (! write_all (inpipe, input, strlen (input))) {
-                        g_warning ("Could not write input to %s", command);
-                }
-
-                close (inpipe);
+        gchar* needle;
+        size_t needle_len;
+        gchar* found = NULL;
+
+        /* update an existing property */
+        needle = g_strconcat (key, ":", NULL);
+        needle_len = strlen (needle);
+        if (g_str_has_prefix (props->str, needle))
+                found = props->str;
+        else 
+            found = strstr (props->str, needle);
+
+        if (found) {
+                size_t value_index;
+                gchar* end;
+
+                end = strchr (found, '\n');
+                value_index = (found - props->str) + needle_len + 1;
+                g_string_erase (props, value_index, end ? (end - found - needle_len) : -1);
+                g_string_insert (props, value_index, "\n");
+                g_string_insert (props, value_index, value);
+        } else {
+                g_string_append_printf (props, "%s:\t%s\n", key, value);
         }
-
-        g_child_watch_add (child_pid, (GChildWatchFunc) child_watch_cb, (gpointer)command);
 }
 
 static void
@@ -140,13 +89,11 @@ load_xcursor_theme (GConfClient *client)
         char       *cursor_theme;
         int         size;
         GString    *add_string;
-        const char *command;
+        Display    *dpy;
+        gchar      numbuf[20];
 
         gnome_settings_profile_start (NULL);
 
-        command = "xrdb -nocpp -merge";
-
-
         size = gconf_client_get_int (client,
                                      "/desktop/gnome/peripherals/mouse/cursor_size",
                                      NULL);
@@ -161,17 +108,23 @@ load_xcursor_theme (GConfClient *client)
                 return;
         }
 
-        add_string = g_string_new (NULL);
-        g_string_append_printf (add_string,
-                                "Xcursor.theme: %s\n",
-                                cursor_theme);
-        g_string_append (add_string,
-                         "Xcursor.theme_core: true\n");
-        g_string_append_printf (add_string,
-                                "Xcursor.size: %d\n",
-                                size);
-
-        spawn_with_input (command, add_string->str);
+        /* get existing properties */
+        dpy = XOpenDisplay (NULL);
+        g_return_if_fail (dpy != NULL);
+        add_string = g_string_new (XResourceManagerString (dpy));
+        g_debug("load_xcursor_theme: existing res '%s'", add_string->str);
+
+        update_property (add_string, "Xcursor.theme", cursor_theme);
+        update_property (add_string, "Xcursor.theme_core", "true");
+        g_snprintf (numbuf, sizeof (numbuf), "%i", size);
+        update_property (add_string, "Xcursor.size", numbuf);
+
+        g_debug("load_xcursor_theme: new res '%s'", add_string->str);
+
+        /* Set the new X property */
+        XChangeProperty(dpy, RootWindow (dpy, 0),
+                XA_RESOURCE_MANAGER, XA_STRING, 8, PropModeReplace, add_string->str, add_string->len);
+        XCloseDisplay (dpy);
 
         g_free (cursor_theme);
         g_string_free (add_string, TRUE);
diff --git a/plugins/xsettings/gsd-xsettings-manager.c b/plugins/xsettings/gsd-xsettings-manager.c
index 8aee25b..40c2651 100644
--- a/plugins/xsettings/gsd-xsettings-manager.c
+++ b/plugins/xsettings/gsd-xsettings-manager.c
@@ -30,6 +30,8 @@
 #include <errno.h>
 #include <time.h>
 
+#include <X11/Xatom.h>
+
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gdk/gdk.h>
@@ -399,118 +401,68 @@ xft_settings_set_xsettings (GnomeXSettingsManager *manager,
         gnome_settings_profile_end (NULL);
 }
 
-static gboolean
-write_all (int         fd,
-           const char *buf,
-           gsize       to_write)
-{
-        while (to_write > 0) {
-                gssize count = write (fd, buf, to_write);
-                if (count < 0) {
-                        if (errno != EINTR)
-                                return FALSE;
-                } else {
-                        to_write -= count;
-                        buf += count;
-                }
-        }
-
-        return TRUE;
-}
-
-static void
-child_watch_cb (GPid     pid,
-                int      status,
-                gpointer user_data)
-{
-        char *command = user_data;
-
-        gnome_settings_profile_end ("%s", command);
-        if (!WIFEXITED (status) || WEXITSTATUS (status)) {
-                g_warning ("Command %s failed", command);
-        }
-}
-
 static void
-spawn_with_input (const char *command,
-                  const char *input)
+update_property (GString *props, const gchar* key, const gchar* value)
 {
-        char   **argv;
-        int      child_pid;
-        int      inpipe;
-        GError  *error;
-        gboolean res;
-
-        argv = NULL;
-        res = g_shell_parse_argv (command, NULL, &argv, NULL);
-        if (! res) {
-                g_warning ("Unable to parse command: %s", command);
-                return;
-        }
-
-        gnome_settings_profile_start ("%s", command);
-        error = NULL;
-        res = g_spawn_async_with_pipes (NULL,
-                                        argv,
-                                        NULL,
-                                        G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
-                                        NULL,
-                                        NULL,
-                                        &child_pid,
-                                        &inpipe,
-                                        NULL,
-                                        NULL,
-                                        &error);
-        g_strfreev (argv);
-
-        if (! res) {
-                g_warning ("Could not execute %s: %s", command, error->message);
-                g_error_free (error);
-
-                return;
-        }
-
-        if (input != NULL) {
-                if (! write_all (inpipe, input, strlen (input))) {
-                        g_warning ("Could not write input to %s", command);
-                }
-
-                close (inpipe);
+        gchar* needle;
+        size_t needle_len;
+        gchar* found = NULL;
+
+        /* update an existing property */
+        needle = g_strconcat (key, ":", NULL);
+        needle_len = strlen (needle);
+        if (g_str_has_prefix (props->str, needle))
+                found = props->str;
+        else 
+            found = strstr (props->str, needle);
+
+        if (found) {
+                size_t value_index;
+                gchar* end;
+
+                end = strchr (found, '\n');
+                value_index = (found - props->str) + needle_len + 1;
+                g_string_erase (props, value_index, end ? (end - found - needle_len) : -1);
+                g_string_insert (props, value_index, "\n");
+                g_string_insert (props, value_index, value);
+        } else {
+                g_string_append_printf (props, "%s:\t%s\n", key, value);
         }
-
-        g_child_watch_add (child_pid, (GChildWatchFunc) child_watch_cb, (gpointer)command);
 }
 
 static void
 xft_settings_set_xresources (GnomeXftSettings *settings)
 {
-        const char *command;
         GString    *add_string;
         char        dpibuf[G_ASCII_DTOSTR_BUF_SIZE];
+        Display    *dpy;
 
         gnome_settings_profile_start (NULL);
 
-        command = "xrdb -nocpp -merge";
+        /* get existing properties */
+        dpy = XOpenDisplay (NULL);
+        g_return_if_fail (dpy != NULL);
+        add_string = g_string_new (XResourceManagerString (dpy));
 
-        add_string = g_string_new (NULL);
+        g_debug("xft_settings_set_xresources: orig res '%s'", add_string->str);
 
-        g_string_append_printf (add_string,
-                                "Xft.dpi: %s\n",
+        update_property (add_string, "Xft.dpi",
                                 g_ascii_dtostr (dpibuf, sizeof (dpibuf), (double) settings->dpi / 1024.0));
-        g_string_append_printf (add_string,
-                                "Xft.antialias: %d\n",
-                                settings->antialias);
-        g_string_append_printf (add_string,
-                                "Xft.hinting: %d\n",
-                                settings->hinting);
-        g_string_append_printf (add_string,
-                                "Xft.hintstyle: %s\n",
+        update_property (add_string, "Xft.antialias",
+                                settings->antialias ? "1" : "0");
+        update_property (add_string, "Xft.hinting",
+                                settings->hinting ? "1" : "0");
+        update_property (add_string, "Xft.hintstyle",
                                 settings->hintstyle);
-        g_string_append_printf (add_string,
-                                "Xft.rgba: %s\n",
+        update_property (add_string, "Xft.rgba",
                                 settings->rgba);
 
-        spawn_with_input (command, add_string->str);
+        g_debug("xft_settings_set_xresources: new res '%s'", add_string->str);
+
+        /* Set the new X property */
+        XChangeProperty(dpy, RootWindow (dpy, 0),
+                XA_RESOURCE_MANAGER, XA_STRING, 8, PropModeReplace, add_string->str, add_string->len);
+        XCloseDisplay (dpy);
 
         g_string_free (add_string, TRUE);
 



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