summaryrefslogtreecommitdiff
path: root/gnome-settings-daemon
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@src.gnome.org>2002-07-24 02:39:03 +0000
committerOwen Taylor <otaylor@src.gnome.org>2002-07-24 02:39:03 +0000
commit05fb268094d119c236f4a01689fc5aa722cf4bac (patch)
tree5a7af868b7b0b540a44f90674e4281695b5b26ec /gnome-settings-daemon
parenta8339d6fc10ebc65518b7641cb6327f4cc77b796 (diff)
downloadgnome-control-center-05fb268094d119c236f4a01689fc5aa722cf4bac.tar.gz
ue Jul 23 22:35:10 2002 Owen Taylor <otaylor@redhat.com>
* acconfig.h configure.in: Check for Xft2. * capplets/font/main.c capplets/font/Makefile.am capplets/font/font-properties.glade: If XFt2 is present, allow the user to control various font rendering attributes. * gnome-settings-daemon/gnome-settings-xsettings.c: Mirror the Xft rendering attributes from the font capplet to XSETTINGS and Xrdb. * schemas/Makefile.am schemas/desktop_gnome_font_rendering.schemas: Add schemas for the new GConf settings.
Diffstat (limited to 'gnome-settings-daemon')
-rw-r--r--gnome-settings-daemon/gnome-settings-xsettings.c296
1 files changed, 296 insertions, 0 deletions
diff --git a/gnome-settings-daemon/gnome-settings-xsettings.c b/gnome-settings-daemon/gnome-settings-xsettings.c
index 8ff939b32..fa0023b7d 100644
--- a/gnome-settings-daemon/gnome-settings-xsettings.c
+++ b/gnome-settings-daemon/gnome-settings-xsettings.c
@@ -4,12 +4,24 @@
#include <glib.h>
#include <libgnome/gnome-i18n.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
#include "gnome-settings-daemon.h"
#include "gnome-settings-xsettings.h"
#include "xsettings-manager.h"
extern XSettingsManager *manager;
+#ifdef HAVE_XFT2
+#define FONT_RENDER_DIR "/desktop/gnome/font_rendering"
+#define FONT_ANTIALIASING_KEY FONT_RENDER_DIR "/antialiasing"
+#define FONT_HINTING_KEY FONT_RENDER_DIR "/hinting"
+#define FONT_RGBA_ORDER_KEY FONT_RENDER_DIR "/rgba_order"
+#define FONT_DPI_KEY FONT_RENDER_DIR "/dpi"
+#endif /* HAVE_XFT2 */
typedef struct _TranslationEntry TranslationEntry;
typedef void (* TranslationFunc) (TranslationEntry *trans,
@@ -23,6 +35,10 @@ struct _TranslationEntry
TranslationFunc translate;
};
+#ifdef HAVE_XFT2
+static void gnome_settings_update_xft (GConfClient *client);
+static void xft_callback (GConfEntry *entry);
+#endif /* HAVE_XFT2 */
static void
translate_bool_int (TranslationEntry *trans,
@@ -175,8 +191,284 @@ gnome_settings_xsettings_init (GConfClient *client)
gnome_settings_daemon_register_callback ("/desktop/gnome/peripherals/mouse", xsettings_callback);
gnome_settings_daemon_register_callback ("/desktop/gtk", xsettings_callback);
gnome_settings_daemon_register_callback ("/desktop/gnome/interface", xsettings_callback);
+
+#ifdef HAVE_XFT2
+ gnome_settings_daemon_register_callback (FONT_RENDER_DIR, xft_callback);
+#endif /* HAVE_XFT2 */
}
+#ifdef HAVE_XFT2
+static void
+xft_callback (GConfEntry *entry)
+{
+ GConfClient *client;
+
+ client = gconf_client_get_default ();
+
+ gnome_settings_update_xft (client);
+ xsettings_manager_notify (manager);
+}
+
+typedef struct
+{
+ gboolean antialias;
+ gboolean hinting;
+ int dpi;
+ const char *rgba;
+ const char *hintstyle;
+} GnomeXftSettings;
+
+static const char *rgba_types[] = { "rgb", "bgr", "vbgr", "vrgb" };
+
+/* Read GConf settings and determine the appropriate Xft settings based on them
+ * This probably could be done a bit more cleanly with gconf_string_to_enum
+ */
+static void
+gnome_xft_settings_get (GConfClient *client,
+ GnomeXftSettings *settings)
+{
+ char *antialiasing = gconf_client_get_string (client, FONT_ANTIALIASING_KEY, NULL);
+ char *hinting = gconf_client_get_string (client, FONT_HINTING_KEY, NULL);
+ char *rgba_order = gconf_client_get_string (client, FONT_RGBA_ORDER_KEY, NULL);
+ double dpi = gconf_client_get_float (client, FONT_DPI_KEY, NULL);
+
+ settings->antialias = TRUE;
+ settings->hinting = TRUE;
+ settings->hintstyle = "hintfull";
+ settings->dpi = 96;
+ settings->rgba = "rgb";
+
+ if ((int)(1024 * dpi + 0.5) > 0)
+ settings->dpi = (int)(1024 * dpi + 0.5);
+
+ if (rgba_order)
+ {
+ int i;
+ gboolean found = FALSE;
+
+ for (i = 0; i < G_N_ELEMENTS (rgba_types) && !found; i++)
+ if (strcmp (rgba_order, rgba_types[i]) == 0)
+ {
+ settings->rgba = rgba_types[i];
+ found = TRUE;
+ }
+
+ if (!found)
+ g_warning ("Invalid value for " FONT_RGBA_ORDER_KEY ": '%s'",
+ rgba_order);
+ }
+
+ if (hinting)
+ {
+ if (strcmp (hinting, "none") == 0)
+ {
+ settings->hinting = 0;
+ settings->hintstyle = "hintnone";
+ }
+ else if (strcmp (hinting, "slight") == 0)
+ {
+ settings->hinting = 1;
+ settings->hintstyle = "hintslight";
+ }
+ else if (strcmp (hinting, "medium") == 0)
+ {
+ settings->hinting = 1;
+ settings->hintstyle = "hintmedium";
+ }
+ else if (strcmp (hinting, "full") == 0)
+ {
+ settings->hinting = 1;
+ settings->hintstyle = "hintfull";
+ }
+ else
+ g_warning ("Invalid value for " FONT_HINTING_KEY ": '%s'",
+ hinting);
+ }
+
+ if (antialiasing)
+ {
+ gboolean use_rgba = FALSE;
+
+ if (strcmp (antialiasing, "none") == 0)
+ settings->antialias = 0;
+ else if (strcmp (antialiasing, "grayscale") == 0)
+ settings->antialias = 1;
+ else if (strcmp (antialiasing, "rgba") == 0)
+ {
+ settings->antialias = 1;
+ use_rgba = TRUE;
+ }
+ else
+ g_warning ("Invalid value for " FONT_ANTIALIASING_KEY " : '%s'",
+ antialiasing);
+
+ if (!use_rgba)
+ settings->rgba = "none";
+ }
+
+ g_free (rgba_order);
+ g_free (hinting);
+ g_free (antialiasing);
+}
+
+static void
+gnome_xft_settings_set_xsettings (GnomeXftSettings *settings)
+{
+ xsettings_manager_set_int (manager, "Xft/Antialias", settings->antialias);
+ xsettings_manager_set_int (manager, "Xft/Hinting", settings->hinting);
+ xsettings_manager_set_string (manager, "Xft/HintStyle", settings->hintstyle);
+ xsettings_manager_set_int (manager, "Xft/DPI", settings->dpi);
+ xsettings_manager_set_string (manager, "Xft/RGBA", settings->rgba);
+}
+
+/*
+ * Helper function for spawn_with_input() - write an entire
+ * string to a fd.
+ */
+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;
+}
+
+/*
+ * Helper function for spawn_with_input() - wait for a child
+ * to exit.
+ */
+gboolean
+wait_for_child (int pid,
+ int *status)
+{
+ gint ret;
+
+ again:
+ ret = waitpid (pid, status, 0);
+
+ if (ret < 0)
+ {
+ if (errno == EINTR)
+ goto again;
+ else
+ {
+ g_warning ("Unexpected error in waitpid() (%s)",
+ g_strerror (errno));
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * spawn_with_input:
+ * @argv: command line to run
+ * @input: string to write to the child process.
+ *
+ * Spawns a child process specified by @argv, writes the text in
+ * @input to it, then waits for the child to exit. Any failures
+ * are output through g_warning(); if you wanted to use this in
+ * cases where errors need to be presented to the user, some
+ * modification would be needed.
+ **/
+static void
+spawn_with_input (char **argv,
+ const char *input)
+{
+ int exit_status;
+ int child_pid;
+ int inpipe;
+ GError *err = NULL;
+
+ if (!g_spawn_async_with_pipes (NULL /* working directory */, argv, NULL /* envp */,
+ G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL, NULL, /* child setup and data */
+ &child_pid,
+ &inpipe, NULL, NULL, /* stdin, stdout, stderr */
+ &err))
+ {
+ gchar *command = g_strjoinv (" ", argv);
+ g_warning ("Could not execute %s: %s", command, err->message);
+ g_error_free (err);
+ g_free (command);
+
+ return;
+ }
+
+ if (input)
+ {
+ if (!write_all (inpipe, input, strlen (input)))
+ {
+ gchar *command = g_strjoinv (" ", argv);
+ g_warning ("Could not write input to %s", command);
+ g_free (command);
+ }
+
+ close (inpipe);
+ }
+
+ wait_for_child (child_pid, &exit_status);
+
+ if (!WIFEXITED (exit_status) || WEXITSTATUS (exit_status))
+ {
+ gchar *command = g_strjoinv (" ", argv);
+ g_warning ("Command %s failed", command);
+ g_free (command);
+ }
+}
+
+static void
+gnome_xft_settings_set_xresources (GnomeXftSettings *settings)
+{
+ char *add[] = { "xrdb", "-merge", NULL };
+ GString *add_string = g_string_new (NULL);
+
+ g_string_append_printf (add_string,
+ "Xft.dpi: %f\n", settings->dpi / 1024.);
+ 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", settings->hintstyle);
+ g_string_append_printf (add_string,
+ "Xft.rgba: %s\n", settings->rgba);
+
+ spawn_with_input (add, add_string->str);
+
+ g_string_free (add_string, TRUE);
+}
+
+/* We mirror the Xft properties both through XSETTINGS and through
+ * X resources
+ */
+static void
+gnome_settings_update_xft (GConfClient *client)
+{
+ GnomeXftSettings settings;
+
+ gnome_xft_settings_get (client, &settings);
+ gnome_xft_settings_set_xsettings (&settings);
+ gnome_xft_settings_set_xresources (&settings);
+}
+#endif /* HAVE_XFT2 */
+
void
gnome_settings_xsettings_load (GConfClient *client)
{
@@ -207,5 +499,9 @@ gnome_settings_xsettings_load (GConfClient *client)
++i;
}
+#ifdef HAVE_XFT2
+ gnome_settings_update_xft (client);
+#endif /* HAVE_XFT */
+
xsettings_manager_notify (manager);
}