diff options
author | Owen Taylor <otaylor@src.gnome.org> | 2002-07-24 02:39:03 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2002-07-24 02:39:03 +0000 |
commit | 05fb268094d119c236f4a01689fc5aa722cf4bac (patch) | |
tree | 5a7af868b7b0b540a44f90674e4281695b5b26ec /gnome-settings-daemon | |
parent | a8339d6fc10ebc65518b7641cb6327f4cc77b796 (diff) | |
download | gnome-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.c | 296 |
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); } |