/* * Copyright © 2000 Nate Case * Copyright © 2000-2004 Marco Pesenti Gritti * Copyright © 2003, 2004 Christian Persch * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, OR (AT YOUR OPTION) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * $Id$ */ #include "mozilla-config.h" #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "eel-gconf-extensions.h" #include "ephy-debug.h" #include "ephy-embed-prefs.h" #include "ephy-embed-shell.h" #include "ephy-encodings.h" #include "ephy-langs.h" #include "ephy-node.h" #include "ephy-prefs.h" #include "mozilla-notifiers.h" /* define to migrate epiphany 1.0 font preferences */ #define MIGRATE_PIXEL_SIZE #define MAX_FONT_SIZE 128 /* Keeps the list of the notifiers we installed for mozilla prefs */ /* to be able to remove them when exiting */ static GList *notifiers = NULL; static nsIPrefBranch *gPrefBranch; typedef struct { char *gconf_key; char *mozilla_pref; PrefValueTransformFunc func; gpointer user_data; guint cnxn_id; } PrefData; static void free_pref_data (PrefData *data) { g_free (data->gconf_key); g_free (data->mozilla_pref); g_slice_free (PrefData, data); } static gboolean transform_accept_languages_list (GConfEntry *gcentry, GValue *value, gpointer user_data) { GConfValue *gcvalue; GArray *array; GSList *languages, *l; char **langs; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_LIST || gconf_value_get_list_type (gcvalue) != GCONF_VALUE_STRING) return FALSE; languages = gconf_value_get_list (gcvalue); array = g_array_new (TRUE, FALSE, sizeof (char *)); for (l = languages; l != NULL; l = l->next) { const char *lang; lang = gconf_value_get_string ((GConfValue *) l->data); if (lang != NULL && strcmp (lang, "system") == 0) { ephy_langs_append_languages (array); } else if (lang != NULL && lang[0] != '\0') { char *str; str = g_ascii_strdown (lang, -1); g_array_append_val (array, str); } } ephy_langs_sanitise (array); langs = (char **) g_array_free (array, FALSE); g_value_init (value, G_TYPE_STRING); g_value_take_string (value, g_strjoinv (",", langs)); g_strfreev (langs); return TRUE; } static gboolean transform_cache_size (GConfEntry *gcentry, GValue *value, gpointer user_data) { GConfValue *gcvalue; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_INT) return FALSE; g_value_init (value, G_TYPE_INT); g_value_set_int (value, gconf_value_get_int (gcvalue) * 1024); return TRUE; } static gboolean transform_cookies_accept_mode (GConfEntry *gcentry, GValue *value, gpointer user_data) { GConfValue *gcvalue; const char *mode; int mozilla_mode = 0; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_STRING) return FALSE; mode = gconf_value_get_string (gcvalue); if (mode == NULL) return FALSE; if (strcmp (mode, "anywhere") == 0) { mozilla_mode = 0; } else if (strcmp (mode, "current site") == 0) { mozilla_mode = 1; } else if (strcmp (mode, "nowhere") == 0) { mozilla_mode = 2; } g_value_init (value, G_TYPE_INT); g_value_set_int (value, mozilla_mode); return TRUE; } static gboolean transform_encoding (GConfEntry *gcentry, GValue *value, gpointer user_data) { GConfValue *gcvalue; EphyEncodings *encodings; EphyNode *node; const char *code; gboolean is_autodetector; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_STRING) return FALSE; code = gconf_value_get_string (gcvalue); if (code == NULL) return FALSE; encodings = EPHY_ENCODINGS (ephy_embed_shell_get_encodings (embed_shell)); node = ephy_encodings_get_node (encodings, code, FALSE); if (node == NULL) return FALSE; is_autodetector = ephy_node_get_property_boolean (node, EPHY_NODE_ENCODING_PROP_IS_AUTODETECTOR); if (is_autodetector != GPOINTER_TO_INT (user_data)) return FALSE; g_value_init (value, G_TYPE_STRING); g_value_set_string (value, code); return TRUE; } static gboolean transform_image_animation_mode (GConfEntry *gcentry, GValue *value, gpointer user_data) { GConfValue *gcvalue; const char *mode; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_STRING) return FALSE; mode = gconf_value_get_string (gcvalue); if (mode == NULL) return FALSE; if (strcmp (mode, "disabled") == 0) { mode = "none"; } g_value_init (value, G_TYPE_STRING); g_value_set_string (value, mode); return TRUE; } static gboolean transform_proxy_ignore_list (GConfEntry *gcentry, GValue *value, gpointer user_data) { GConfValue *gcvalue; GArray *array; GSList *hosts, *l; char **strings; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_LIST || gconf_value_get_list_type (gcvalue) != GCONF_VALUE_STRING) return FALSE; hosts = gconf_value_get_list (gcvalue); array = g_array_new (TRUE, FALSE, sizeof (char *)); for (l = hosts; l != NULL; l = l->next) { const char *host; host = gconf_value_get_string ((GConfValue *) l->data); if (host != NULL && host[0] != '\0') { g_array_append_val (array, host); } } strings = (char **) g_array_free (array, FALSE); g_value_init (value, G_TYPE_STRING); g_value_take_string (value, g_strjoinv (",", strings)); /* the strings themselves are const */ g_free (strings); return TRUE; } static gboolean transform_proxy_mode (GConfEntry *gcentry, GValue *value, gpointer user_data) { GConfValue *gcvalue; const char *mode; int mozilla_mode = 0; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_STRING) return FALSE; mode = gconf_value_get_string (gcvalue); if (mode == NULL) return FALSE; if (strcmp (mode, "manual") == 0) { mozilla_mode = 1; } else if (strcmp (mode, "auto") == 0) { mozilla_mode = 2; } g_value_init (value, G_TYPE_INT); g_value_set_int (value, mozilla_mode); return TRUE; } static gboolean transform_use_own_fonts (GConfEntry *gcentry, GValue *value, gpointer user_data) { GConfValue *gcvalue; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_BOOL) return FALSE; g_value_init (value, G_TYPE_INT); g_value_set_int (value, gconf_value_get_bool (gcvalue) ? 0 : 1); return TRUE; } extern "C" gboolean mozilla_notifier_transform_bool (GConfEntry *gcentry, GValue *value, gpointer user_data) { GConfValue *gcvalue; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_BOOL) return FALSE; g_value_init (value, G_TYPE_BOOLEAN); g_value_set_boolean (value, gconf_value_get_bool (gcvalue)); return TRUE; } extern "C" gboolean mozilla_notifier_transform_bool_invert (GConfEntry *gcentry, GValue *value, gpointer user_data) { GConfValue *gcvalue; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_BOOL) return FALSE; g_value_init (value, G_TYPE_BOOLEAN); g_value_set_boolean (value, !gconf_value_get_bool (gcvalue)); return TRUE; } extern "C" gboolean mozilla_notifier_transform_int (GConfEntry *gcentry, GValue *value, gpointer user_data) { GConfValue *gcvalue; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_INT) return FALSE; g_value_init (value, G_TYPE_INT); g_value_set_int (value, gconf_value_get_int (gcvalue)); return TRUE; } extern "C" gboolean mozilla_notifier_transform_string (GConfEntry *gcentry, GValue *value, gpointer user_data) { GConfValue *gcvalue; const char *str; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_STRING) return FALSE; str = gconf_value_get_string (gcvalue); if (str == NULL) return FALSE; g_value_init (value, G_TYPE_STRING); g_value_set_string (value, str); return TRUE; } static const PrefData notifier_entries[] = { { CONF_BROWSE_WITH_CARET, "accessibility.browsewithcaret", mozilla_notifier_transform_bool }, { CONF_NETWORK_CACHE_SIZE, "browser.cache.disk.capacity", transform_cache_size }, { CONF_RENDERING_USE_OWN_COLORS, "browser.display.use_document_colors", mozilla_notifier_transform_bool_invert }, { CONF_RENDERING_USE_OWN_FONTS, "browser.display.use_document_fonts", transform_use_own_fonts }, { CONF_SECURITY_ALLOW_POPUPS, "dom.disable_open_during_load", mozilla_notifier_transform_bool_invert }, { CONF_DISPLAY_SMOOTHSCROLL, "general.smoothScroll", mozilla_notifier_transform_bool }, { CONF_IMAGE_ANIMATION_MODE, "image.animation_mode", transform_image_animation_mode }, { CONF_RENDERING_LANGUAGE, "intl.accept_languages", transform_accept_languages_list }, { CONF_LANGUAGE_DEFAULT_ENCODING, "intl.charset.default", transform_encoding, GINT_TO_POINTER (FALSE) }, { CONF_LANGUAGE_AUTODETECT_ENCODING, "intl.charset.detector", transform_encoding, GINT_TO_POINTER (TRUE) }, { CONF_SECURITY_JAVA_ENABLED, "security.enable_java", mozilla_notifier_transform_bool }, { CONF_SECURITY_JAVASCRIPT_ENABLED, "javascript.enabled", mozilla_notifier_transform_bool }, { CONF_NETWORK_PROXY_AUTO_URL, "network.proxy.autoconfig_url", mozilla_notifier_transform_string }, { CONF_NETWORK_HTTP_PROXY, "network.proxy.http", mozilla_notifier_transform_string }, { CONF_NETWORK_HTTP_PROXY_PORT, "network.proxy.http_port", mozilla_notifier_transform_int }, { CONF_NETWORK_FTP_PROXY, "network.proxy.ftp", mozilla_notifier_transform_string }, { CONF_NETWORK_FTP_PROXY_PORT, "network.proxy.ftp_port", mozilla_notifier_transform_int }, { CONF_NETWORK_SSL_PROXY, "network.proxy.ssl", mozilla_notifier_transform_string }, { CONF_NETWORK_SSL_PROXY_PORT, "network.proxy.ssl_port", mozilla_notifier_transform_int }, { CONF_NETWORK_SOCKS_PROXY, "network.proxy.socks", mozilla_notifier_transform_string }, { CONF_NETWORK_SOCKS_PROXY_PORT, "network.proxy.socks_port", mozilla_notifier_transform_int }, { CONF_NETWORK_PROXY_IGNORE_HOSTS, "network.proxy.no_proxies_on", transform_proxy_ignore_list }, { CONF_NETWORK_PROXY_MODE, "network.proxy.type", transform_proxy_mode }, { CONF_SECURITY_COOKIES_ACCEPT, "network.cookie.cookieBehavior", transform_cookies_accept_mode }, { CONF_PRIVACY_REMEMBER_PASSWORDS, "signon.rememberSignons", mozilla_notifier_transform_bool } }; gboolean mozilla_pref_set (const char *pref, const GValue *value) { NS_ENSURE_TRUE (gPrefBranch, FALSE); g_return_val_if_fail (pref != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); nsresult rv; PRInt32 prefType; rv = gPrefBranch->GetPrefType (pref, &prefType); if (NS_FAILED (rv)) { /* probably just an unset pref */ prefType = nsIPrefBranch::PREF_INVALID; rv = NS_OK; } switch (G_VALUE_TYPE (value)) { case G_TYPE_INT: { if (prefType != nsIPrefBranch::PREF_INT && prefType != nsIPrefBranch::PREF_INVALID) break; PRInt32 old_value = 0; PRInt32 new_value = g_value_get_int (value); rv = gPrefBranch->GetIntPref (pref, &old_value); if (NS_FAILED (rv) || old_value != new_value) { rv = gPrefBranch->SetIntPref (pref, new_value); } break; } case G_TYPE_BOOLEAN: { if (prefType != nsIPrefBranch::PREF_BOOL && prefType != nsIPrefBranch::PREF_INVALID) break; PRBool old_value = PR_FALSE; PRBool new_value = g_value_get_boolean (value); rv = gPrefBranch->GetBoolPref (pref, &old_value); if (NS_FAILED (rv) || old_value != new_value) { rv = gPrefBranch->SetBoolPref (pref, new_value); } break; } case G_TYPE_STRING: { if (prefType != nsIPrefBranch::PREF_STRING && prefType != nsIPrefBranch::PREF_INVALID) break; const char *new_value = g_value_get_string (value); if (new_value == NULL) { rv = gPrefBranch->ClearUserPref (pref); } else { char *old_value = nsnull; rv = gPrefBranch->GetCharPref (pref, &old_value); if (NS_FAILED (rv) || old_value == nsnull || strcmp (old_value, new_value) != 0) { rv = gPrefBranch->SetCharPref (pref, new_value); } if (old_value) { nsMemory::Free (old_value); } } break; } default: g_return_val_if_reached (FALSE); rv = NS_ERROR_FAILURE; break; } return NS_SUCCEEDED (rv) != PR_FALSE; } static void notify_cb (GConfClient *client, guint cnxn_id, GConfEntry *gcentry, PrefData *data) { GValue value = { 0, }; g_return_if_fail (gcentry != NULL); g_assert (data != NULL); if (data->func (gcentry, &value, data->user_data)) { mozilla_pref_set (data->mozilla_pref, &value); g_value_unset (&value); } else { /* Reset the pref */ NS_ENSURE_TRUE (gPrefBranch, ); gPrefBranch->ClearUserPref (data->mozilla_pref); } } extern "C" guint mozilla_notifier_add (const char *gconf_key, const char *mozilla_pref, PrefValueTransformFunc func, gpointer user_data) { GConfClient *client; PrefData *data; GError *error = NULL; guint cnxn_id; g_return_val_if_fail (gconf_key != NULL, 0); g_return_val_if_fail (mozilla_pref != NULL, 0); g_return_val_if_fail (func, 0); client = eel_gconf_client_get_global (); g_return_val_if_fail (client != NULL, 0); data = g_slice_new (PrefData); data->gconf_key = g_strdup (gconf_key); data->mozilla_pref = g_strdup (mozilla_pref); data->func = func; data->user_data = user_data; cnxn_id = gconf_client_notify_add (client, gconf_key, (GConfClientNotifyFunc) notify_cb, data, (GFreeFunc) free_pref_data, &error); if (eel_gconf_handle_error (&error)) { if (cnxn_id != EEL_GCONF_UNDEFINED_CONNECTION) { gconf_client_notify_remove (client, cnxn_id); } return 0; } data->cnxn_id = cnxn_id; notifiers = g_list_prepend (notifiers, data); gconf_client_notify (client, gconf_key); return cnxn_id; } static int find_data (const PrefData *a, gconstpointer idptr) { return a->cnxn_id != GPOINTER_TO_UINT (idptr); } extern "C" void mozilla_notifier_remove (guint id) { GList *l; g_return_if_fail (id != 0); l = g_list_find_custom (notifiers, GUINT_TO_POINTER (id), (GCompareFunc) find_data); g_return_if_fail (l != NULL); notifiers = g_list_delete_link (notifiers, l); eel_gconf_notification_remove (id); } #ifdef MIGRATE_PIXEL_SIZE #define INT_ROUND(a) gint((a) + 0.5f) /** * This function gets the dpi in the same way that mozilla gets the dpi, * this allows us to convert from pixels to points easily */ static gint mozilla_get_dpi () { GtkSettings* settings = gtk_settings_get_default (); gint dpi = 0; /* Use the gdk-xft-dpi setting if it is set */ if (g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (settings)), "gtk-xft-dpi")) { g_object_get (G_OBJECT (settings), "gtk-xft-dpi", &dpi, (char *) NULL); if (dpi) return INT_ROUND (dpi / PANGO_SCALE); } /* Fall back to what xft thinks it is */ char *val = XGetDefault (GDK_DISPLAY (), "Xft", "dpi"); if (val) { char *e; double d = strtod(val, &e); if (e != val) return INT_ROUND (d); } /* Fall back to calculating manually from the gdk screen settings */ float screenWidthIn = float (gdk_screen_width_mm()) / 25.4f; return INT_ROUND (gdk_screen_width() / screenWidthIn); } static void migrate_font_gconf_key (const char *pixel_key, const char *point_key) { int size; size = eel_gconf_get_integer (pixel_key); if (size > 0) { /* Use doubles to get more accurate arithmetic */ double dpi = (double) mozilla_get_dpi (); double value = (double) eel_gconf_get_integer (pixel_key); gint point = INT_ROUND ((value * 72) / dpi); eel_gconf_set_integer (point_key, point); } } #endif static gboolean parse_pango_font (const char *font, char **name, int *size) { PangoFontMask mask = (PangoFontMask) (PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE); PangoFontDescription *desc = pango_font_description_from_string (font); if (desc == NULL) return FALSE; if ((pango_font_description_get_set_fields (desc) & mask) != mask) { pango_font_description_free (desc); return FALSE; } *size = PANGO_PIXELS (pango_font_description_get_size (desc)); *name = g_strdup (pango_font_description_get_family (desc)); pango_font_description_free (desc); LOG ("Parsed pango font description '%s' -> name:%s, size:%d", font, *name ? *name : "-", *size); return *name != NULL && *size > 0; } typedef struct { guint cnxn_id; char **font_name_prefs; char **font_size_prefs; char *font_name; int font_size; } DesktopFontData; static gboolean transform_font_name (GConfEntry *gcentry, GValue *value, gpointer user_data) { DesktopFontData *data = (DesktopFontData *) user_data; GConfValue *gcvalue; const char *font_name; gcvalue = gconf_entry_get_value (gcentry); if (gconf_entry_get_is_default (gcentry) || gcvalue == NULL || gcvalue->type != GCONF_VALUE_STRING) { font_name = data->font_name; } else { font_name = gconf_value_get_string (gcvalue); if ((font_name == NULL || font_name[0] == '\0')) { font_name = data->font_name; } } LOG ("%s value for key '%s'", gconf_entry_get_is_default (gcentry) ? "default" : "NON-default", gconf_entry_get_key (gcentry)); if (font_name == NULL) return FALSE; LOG ("Inferred font name '%s' for key '%s'", font_name, gconf_entry_get_key (gcentry)); g_value_init (value, G_TYPE_STRING); g_value_set_string (value, font_name); return TRUE; } static gboolean transform_font_size (GConfEntry *gcentry, GValue *value, gpointer user_data) { DesktopFontData *data = (DesktopFontData *) user_data; GConfValue *gcvalue; int size = 0; gcvalue = gconf_entry_get_value (gcentry); if (gconf_entry_get_is_default (gcentry) || gcvalue == NULL || gcvalue->type != GCONF_VALUE_INT) { size = data->font_size; } else { size = gconf_value_get_int (gcvalue); } if (size <= 0 || size > MAX_FONT_SIZE) return FALSE; g_value_init (value, G_TYPE_INT); g_value_set_int (value, size); return TRUE; } static void notify_desktop_font_cb (GConfClient *client, guint cnxn_id, GConfEntry *gcentry, DesktopFontData *data) { GConfValue *gcvalue; char *name = NULL; int size = 0, i; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue != NULL && gcvalue->type == GCONF_VALUE_STRING && parse_pango_font (gconf_value_get_string (gcvalue), &name, &size)) { LOG ("Desktop font %s -> name=%s, size=%d", gconf_entry_get_key (gcentry), name, size); g_free (data->font_name); data->font_name = name; data->font_size = size; } else { g_free (name); g_free (data->font_name); data->font_name = NULL; data->font_size = 0; } for (i = 0; data->font_name_prefs[i] != NULL; ++i) { gconf_client_notify (client, data->font_name_prefs[i]); } for (i = 0; data->font_size_prefs[i] != NULL; ++i) { gconf_client_notify (client, data->font_size_prefs[i]); } } typedef struct { guint cnxn_id; char **prefs; int size; } MinimumFontSizeData; static gboolean transform_minimum_font_size (GConfEntry *gcentry, GValue *value, gpointer user_data) { MinimumFontSizeData *data = (MinimumFontSizeData *) user_data; GConfValue *gcvalue; int size = 0; gcvalue = gconf_entry_get_value (gcentry); if (gcvalue == NULL || gcvalue->type != GCONF_VALUE_INT) { size = data->size; } else { size = MAX (gconf_value_get_int (gcvalue), data->size); } if (size <= 0) return FALSE; g_value_init (value, G_TYPE_INT); g_value_set_int (value, size); return TRUE; } static void notify_minimum_size_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, MinimumFontSizeData *data) { GConfValue *gcvalue; int i; data->size = 0; gcvalue = gconf_entry_get_value (entry); /* happens on initial notify if the key doesn't exist */ if (gcvalue != NULL && gcvalue->type == GCONF_VALUE_INT) { data->size = gconf_value_get_int (gcvalue); data->size = MAX (data->size, 0); } LOG ("Minimum font size now %d", data->size); for (i = 0; data->prefs[i] != NULL; ++i) { gconf_client_notify (client, data->prefs[i]); } } static DesktopFontData *desktop_font_data; static MinimumFontSizeData *minimum_font_size_data; static void mozilla_font_notifiers_init (void) { static const char *types [] = { "variable", "monospace" }; const EphyFontsLanguageInfo *font_languages; guint n_font_languages, i; eel_gconf_monitor_add ("/desktop/gnome/interface"); font_languages = ephy_font_languages (); n_font_languages = ephy_font_n_languages (); desktop_font_data = g_new0 (DesktopFontData, 2); desktop_font_data[0].font_name_prefs = g_new0 (char*, n_font_languages + 1); desktop_font_data[0].font_size_prefs = g_new0 (char*, n_font_languages + 1); desktop_font_data[1].font_name_prefs = g_new0 (char*, n_font_languages + 1); desktop_font_data[1].font_size_prefs = g_new0 (char*, n_font_languages + 1); desktop_font_data[0].cnxn_id = eel_gconf_notification_add (CONF_DESKTOP_FONT_VARIABLE, (GConfClientNotifyFunc) notify_desktop_font_cb, &desktop_font_data[0]); eel_gconf_notify (CONF_DESKTOP_FONT_VARIABLE); desktop_font_data[1].cnxn_id = eel_gconf_notification_add (CONF_DESKTOP_FONT_MONOSPACE, (GConfClientNotifyFunc) notify_desktop_font_cb, &desktop_font_data[1]); eel_gconf_notify (CONF_DESKTOP_FONT_MONOSPACE); minimum_font_size_data = g_new0 (MinimumFontSizeData, 1); minimum_font_size_data->prefs = g_new0 (char*, n_font_languages + 1); minimum_font_size_data->cnxn_id = eel_gconf_notification_add (CONF_RENDERING_FONT_MIN_SIZE, (GConfClientNotifyFunc) notify_minimum_size_cb, minimum_font_size_data); eel_gconf_notify (CONF_RENDERING_FONT_MIN_SIZE); #ifdef MIGRATE_PIXEL_SIZE gboolean migrate_size; migrate_size = (eel_gconf_get_integer (CONF_SCHEMA_VERSION) < EPIPHANY_SCHEMA_VERSION); if (migrate_size) { eel_gconf_set_integer (CONF_SCHEMA_VERSION, EPIPHANY_SCHEMA_VERSION); } #endif for (i=0; i < n_font_languages; i++) { const char *code = font_languages[i].code; guint k; char key[255], pref[255]; #ifdef MIGRATE_PIXEL_SIZE char old_key[255]; #endif for (k = 0; k < G_N_ELEMENTS (types); k++) { g_snprintf (key, sizeof (key), "%s_%s_%s", CONF_RENDERING_FONT, types[k], code); g_snprintf (pref, sizeof (pref), "font.name.%s.%s", types[k], code); desktop_font_data[k].font_name_prefs[i] = g_strdup (key); mozilla_notifier_add (key, pref, transform_font_name, &desktop_font_data[k]); } #ifdef MIGRATE_PIXEL_SIZE if (migrate_size) { char *type; type = eel_gconf_get_string (CONF_RENDERING_FONT_TYPE_OLD); if (type && (strcmp (type, "serif") == 0 || strcmp (type, "sans-serif") == 0)) { char *family; g_snprintf (old_key, sizeof (old_key), "%s_%s_%s", CONF_RENDERING_FONT, type, code); g_snprintf (key, sizeof (key), "%s_%s_%s", CONF_RENDERING_FONT, "variable", code); family = eel_gconf_get_string (old_key); if (family) { eel_gconf_set_string (key, family); g_free (family); } } g_free (type); } #endif /* FIXME is it "minimum-size" or "min-size" !!? */ g_snprintf (key, sizeof (key), "%s_%s", CONF_RENDERING_FONT_MIN_SIZE, code); g_snprintf (pref, sizeof (pref), "font.minimum-size.%s", code); minimum_font_size_data->prefs[i] = g_strdup (key); mozilla_notifier_add (key, pref, transform_minimum_font_size, minimum_font_size_data); #ifdef MIGRATE_PIXEL_SIZE if (migrate_size) { g_snprintf (old_key, sizeof (key), "%s_%s", CONF_RENDERING_FONT_MIN_SIZE_OLD, code); migrate_font_gconf_key (old_key, key); } #endif g_snprintf (key, sizeof (key), "%s_%s", CONF_RENDERING_FONT_FIXED_SIZE, code); g_snprintf (pref, sizeof (pref), "font.size.fixed.%s", code); desktop_font_data[1].font_size_prefs[i] = g_strdup (key); mozilla_notifier_add (key, pref, transform_font_size, &desktop_font_data[1]); #ifdef MIGRATE_PIXEL_SIZE if (migrate_size) { g_snprintf (old_key, sizeof (old_key), "%s_%s", CONF_RENDERING_FONT_FIXED_SIZE_OLD, code); migrate_font_gconf_key (old_key, key); } #endif g_snprintf (key, sizeof (key), "%s_%s", CONF_RENDERING_FONT_VAR_SIZE, code); g_snprintf (pref, sizeof (pref), "font.size.variable.%s", code); desktop_font_data[0].font_size_prefs[i] = g_strdup (key); mozilla_notifier_add (key, pref, transform_font_size, &desktop_font_data[0]); #ifdef MIGRATE_PIXEL_SIZE if (migrate_size) { g_snprintf (old_key, sizeof (old_key), "%s_%s", CONF_RENDERING_FONT_VAR_SIZE_OLD, code); migrate_font_gconf_key (old_key, key); } #endif } } static void mozilla_font_notifiers_shutdown (void) { eel_gconf_monitor_remove ("/desktop/gnome/interface"); eel_gconf_notification_remove (desktop_font_data[0].cnxn_id); eel_gconf_notification_remove (desktop_font_data[1].cnxn_id); eel_gconf_notification_remove (minimum_font_size_data->cnxn_id); g_free (desktop_font_data[0].font_name); g_free (desktop_font_data[1].font_name); g_strfreev (desktop_font_data[0].font_name_prefs); g_strfreev (desktop_font_data[0].font_size_prefs); g_strfreev (desktop_font_data[1].font_name_prefs); g_strfreev (desktop_font_data[1].font_size_prefs); g_strfreev (minimum_font_size_data->prefs); g_free (desktop_font_data); g_free (minimum_font_size_data); } #if 0 static void notify_generic_cb (GConfClient *client, guint cnxn_id, GConfEntry *gcentry, gpointer data) { GConfValue *gcvalue; const char *key, *pref; static const gsize len = strlen ("/apps/epiphany/web/gecko_prefs/"); GValue value = { 0, }; key = gconf_entry_get_key (gcentry); if (!key || strlen (key) <= len) return; pref = key + len; gcvalue = gconf_entry_get_value (gcentry); if (!gcvalue) return; switch (gcvalue->type) { case GCONF_VALUE_STRING: g_value_init (&value, G_TYPE_STRING); g_value_set_static_string (&value, gconf_value_get_string (gcvalue)); break; case GCONF_VALUE_INT: g_value_init (&value, G_TYPE_INT); g_value_set_int (&value, gconf_value_get_int (gcvalue)); break; case GCONF_VALUE_BOOL: g_value_init (&value, G_TYPE_BOOLEAN); g_value_set_boolean (&value, gconf_value_get_bool (gcvalue)); break; /* case GCONF_VALUE_INVALID: */ /* case GCONF_VALUE_FLOAT: */ /* case GCONF_VALUE_SCHEMA: */ /* case GCONF_VALUE_LIST: */ /* case GCONF_VALUE_PAIR: */ default: g_warning ("Unsupported value type for key '%s'\n", key); return; } g_assert (G_IS_VALUE (&value)); mozilla_pref_set (pref, &value); g_value_unset (&value); } static void mozilla_generic_notifier_init (void) { GConfClient *client; GError *error = NULL; guint cnxn_id; PrefData *data; GSList *list, *l; client = eel_gconf_client_get_global (); cnxn_id = gconf_client_notify_add (client, "/apps/epiphany/web/gecko_prefs", (GConfClientNotifyFunc) notify_generic_cb, NULL, NULL, &error); if (eel_gconf_handle_error (&error)) { if (cnxn_id != EEL_GCONF_UNDEFINED_CONNECTION) { gconf_client_notify_remove (client, cnxn_id); } return; } data = g_slice_new0 (PrefData); data->cnxn_id = cnxn_id; notifiers = g_list_prepend (notifiers, data); list = gconf_client_all_entries (client, "/apps/epiphany/web/gecko_prefs", NULL); for (l = list; l != NULL; l = l->next) { GConfEntry *gcentry = (GConfEntry *) l->data; notify_generic_cb (client, cnxn_id, gcentry, NULL); gconf_entry_unref (gcentry); } g_slist_free (list); } #endif extern "C" gboolean mozilla_notifiers_init (void) { guint i; eel_gconf_monitor_add ("/apps/epiphany/web"); eel_gconf_monitor_add ("/system/proxy"); eel_gconf_monitor_add ("/system/http_proxy"); /* the pref service conveniently implements the root pref branch */ gPrefBranch = nsnull; nsresult rv = CallGetService (NS_PREFSERVICE_CONTRACTID, &gPrefBranch); if (NS_FAILED (rv) || !gPrefBranch) { g_warning ("Failed to get the pref service!\n"); return FALSE; } #if 0 /* First init the generic notifier, so our regular prefs override prefs set there */ mozilla_generic_notifier_init (); #endif for (i = 0; i < G_N_ELEMENTS (notifier_entries); i++) { mozilla_notifier_add (notifier_entries[i].gconf_key, notifier_entries[i].mozilla_pref, notifier_entries[i].func, notifier_entries[i].user_data); } mozilla_font_notifiers_init (); return TRUE; } static void remove_notification (PrefData *data) { eel_gconf_notification_remove (data->cnxn_id); } extern "C" void mozilla_notifiers_shutdown (void) { NS_IF_RELEASE (gPrefBranch); gPrefBranch = nsnull; mozilla_font_notifiers_shutdown (); eel_gconf_monitor_remove ("/apps/epiphany/web"); eel_gconf_monitor_remove ("/system/proxy"); eel_gconf_monitor_remove ("/system/http_proxy"); g_list_foreach (notifiers, (GFunc) remove_notification, NULL); g_list_free (notifiers); }