diff options
-rw-r--r-- | src/local.mk | 1 | ||||
-rw-r--r-- | src/settings.c | 439 | ||||
-rw-r--r-- | src/settings.h | 74 |
3 files changed, 514 insertions, 0 deletions
diff --git a/src/local.mk b/src/local.mk index 12b66d0..3b71b14 100644 --- a/src/local.mk +++ b/src/local.mk @@ -7,6 +7,7 @@ marquee_SOURCES += \ %reldir%/main.c \ %reldir%/notebook.c \ %reldir%/resources.c \ + %reldir%/settings.c \ %reldir%/string-utils.c \ %reldir%/tab-label.c \ %reldir%/tab-page.c \ diff --git a/src/settings.c b/src/settings.c new file mode 100644 index 0000000..c48ccb0 --- /dev/null +++ b/src/settings.c @@ -0,0 +1,439 @@ +/* + * Web view settings + * + * Copyright (C) 2017 Patrick McDermott + * + * This file is part of Marquee. + * + * Marquee 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 3 of the License, or + * (at your option) any later version. + * + * Marquee 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 Marquee. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "settings.h" + +#include <glib.h> +#include <webkit2/webkit2.h> + +#include "config.h" + +enum mapping_type { + MAP_BOOL, + MAP_BOOL_N, + MAP_INT, + /* MAP_DBL, */ + MAP_STR, + /* MAP_STRL, */ +}; + +struct mapping { + enum mapping_type type; + const gchar *mq_name; + const gchar *wk_name; +}; + +static struct mapping mappings[] = { + /* General -> Navigation and Accessibility */ + {MAP_BOOL, "navigation.smooth-scrolling", + "enable-smooth-scrolling"}, + {MAP_BOOL, "navigation.tabbing", + "enable-tabs-to-links"}, + {MAP_BOOL, "navigation.caret", + "enable-caret-browsing"}, + {MAP_BOOL, "navigation.spatial", + "enable-spatial-navigation"}, + + /* General -> Miscellaneous */ + {MAP_BOOL, "display.textarea.resize.enable", + "enable-resizable-text-areas"}, + {MAP_BOOL, "devtools.enable", + "enable-developer-extras"}, + + /* General -> Compatibility */ + // compatibility.user-agent + {MAP_BOOL, "compatibility.quirks", + "enable-site-specific-quirks"}, + + /* Display -> Fonts */ + {MAP_STR, "font.family.default", + "default-font-family"}, + {MAP_STR, "font.family.monospace", + "monospace-font-family"}, + {MAP_STR, "font.family.serif", + "serif-font-family"}, + {MAP_STR, "font.family.sans-serif", + "sans-serif-font-family"}, + {MAP_STR, "font.family.cursive", + "cursive-font-family"}, + {MAP_STR, "font.family.fantasy", + "fantasy-font-family"}, + {MAP_STR, "font.family.pictograph", + "pictograph-font-family"}, + {MAP_INT, "font.size.default", + "default-font-size"}, + {MAP_INT, "font.size.monospace-default", + "default-monospace-font-size"}, + {MAP_INT, "font.size.minimum", + "minimum-font-size"}, + + /* Display -> Languages */ + {MAP_STR, "intl.default-charset", + "default-charset"}, + + /* Display -> Zoom */ + {MAP_BOOL, "zoom.text-only", + "zoom-text-only"}, + + /* Permissions -> General */ + {MAP_BOOL, "permissions.images.auto-load", + "auto-load-images"}, + {MAP_BOOL, "permissions.images.favicons.override", + "load-icons-ignoring-image-load-setting"}, + {MAP_BOOL, "permissions.java.enable", + "enable-java"}, + {MAP_BOOL, "permissions.javascript.enable", + "enable-javascript"}, + {MAP_BOOL, "permissions.plugins.enable", + "enable-plugins"}, + + /* Permissions -> JavaScript */ + {MAP_BOOL, "permissions.javascript.open-windows", + "javascript-can-open-windows-automatically"}, + {MAP_BOOL, "permissions.javascript.fullscreen", + "enable-fullscreen"}, + {MAP_BOOL, "permissions.javascript.modal-dialogs", + "allow-modal-dialogs"}, + {MAP_BOOL, "permissions.javascript.clipboard", + "javascript-can-access-clipboard"}, + + /* Permissions -> Data Storage */ + {MAP_BOOL, "permissions.javascript.database", + "enable-html5-database"}, + {MAP_BOOL, "permissions.javascript.storage", + "enable-html5-local-storage"}, + {MAP_BOOL, "permissions.appcache", + "enable-offline-web-application-cache"}, + + /* Permissions -> Graphics and Multimedia */ + {MAP_BOOL, "canvas.acceleration.enable", + "enable-accelerated-2d-canvas"}, + {MAP_BOOL, "permissions.javascript.webgl", + "enable-webgl"}, + {MAP_BOOL, "permissions.javascript.audio", + "enable-webaudio"}, + {MAP_BOOL_N, "media.autoplay", + "media-playback-requires-user-gesture"}, + {MAP_BOOL_N, "media.force-fullscreen", + "media-playback-allows-inline"}, + {MAP_BOOL, "permissions.javascript.mediastream.enable", + "enable-media-stream"}, + {MAP_BOOL, "permissions.javascript.mediasource.enable", + "enable-mediasource"}, + + /* Security and Privacy -> History */ + {MAP_BOOL, "privacy.private-browsing.enabled", + "enable-private-browsing"}, + + /* Security and Privacy -> Security */ + {MAP_BOOL, "security.xss-auditor.enable", + "enable-xss-auditor"}, + + /* Security and Privacy -> Network */ + {MAP_BOOL, "dns.prefetch.enable", + "enable-dns-prefetching"}, +}; + +static GHashTable *mappings_table = NULL; + +static gboolean true_value = TRUE; + +struct _MqSettings { + WebKitSettings parent_instance; + WebKitWebContext *web_context; + GHashTable *overrides; +}; + +struct _MqSettingsClass { + WebKitSettingsClass parent_class; +}; + +G_DEFINE_TYPE(MqSettings, mq_settings, WEBKIT_TYPE_SETTINGS) + +static void +init_mappings_table(void) +{ + gsize i; + + if (mappings_table) { + return; + } + + mappings_table = g_hash_table_new(g_str_hash, g_str_equal); + + for (i = 0; i < sizeof(mappings) / sizeof(mappings[0]); ++i) { + g_hash_table_insert(mappings_table, + g_strdup(mappings[i].mq_name), + g_strdup(mappings[i].wk_name)); + } +} + +static void +mq_settings_class_init(MqSettingsClass G_GNUC_UNUSED *klass) +{ +} + +static void +mq_settings_init(MqSettings *settings) +{ + init_mappings_table(); + + settings->overrides = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, NULL); +} + +MqSettings * +mq_settings_new(void) +{ + return g_object_new(MQ_TYPE_SETTINGS, NULL); +} + +void +mq_settings_set_web_context(MqSettings *settings, WebKitWebContext *web_context) +{ + settings->web_context = web_context; +} + +static void +set_bool(MqSettings *settings, const gchar *name, const gboolean value) +{ + GValue g_value = G_VALUE_INIT; + + g_value_init(&g_value, G_TYPE_BOOLEAN); + g_value_set_boolean(&g_value, value); + g_object_set_property(G_OBJECT(settings), + g_hash_table_lookup(mappings_table, name), &g_value); +} + +static void +set_int(MqSettings *settings, const gchar *name, const gint value) +{ + GValue g_value = G_VALUE_INIT; + + g_value_init(&g_value, G_TYPE_INT); + g_value_set_int(&g_value, value); + g_object_set_property(G_OBJECT(settings), + g_hash_table_lookup(mappings_table, name), &g_value); +} + +static void +set_str(MqSettings *settings, const gchar *name, const gchar *value) +{ + GValue g_value = G_VALUE_INIT; + + g_value_init(&g_value, G_TYPE_STRING); + g_value_set_static_string(&g_value, value); + g_object_set_property(G_OBJECT(settings), + g_hash_table_lookup(mappings_table, name), &g_value); +} + +void +mq_settings_override_bool(MqSettings *settings, const gchar *name, + const gboolean value) +{ + g_hash_table_insert(settings->overrides, g_strdup(name), &true_value); + set_bool(settings, name, value); +} + +void +mq_settings_override_int(MqSettings *settings, const gchar *name, + const gint value) +{ + g_hash_table_insert(settings->overrides, g_strdup(name), &true_value); + set_int(settings, name, value); +} + +void +mq_settings_override_str(MqSettings *settings, const gchar *name, + const gchar *value) +{ + g_hash_table_insert(settings->overrides, g_strdup(name), &true_value); + set_str(settings, name, value); +} + +static void +bool_cb(MqConfig G_GNUC_UNUSED *config, const gchar *name, + const gboolean value, MqSettings *settings) +{ + set_bool(settings, name, value); +} + +static void +bool_n_cb(MqConfig G_GNUC_UNUSED *config, const gchar *name, + const gboolean value, MqSettings *settings) +{ + set_bool(settings, name, value); +} + +static void +int_cb(MqConfig G_GNUC_UNUSED *config, const gchar *name, + const gint value, MqSettings *settings) +{ + set_int(settings, name, value); +} + +static void +str_cb(MqConfig G_GNUC_UNUSED *config, const gchar *name, + const gchar *value, MqSettings *settings) +{ + set_str(settings, name, value); +} + +static void +wc_spell_checking_enabled_cb(MqConfig G_GNUC_UNUSED *config, + const gchar G_GNUC_UNUSED *name, const gboolean value, + WebKitWebContext *web_context) +{ + webkit_web_context_set_spell_checking_enabled(web_context, value); +} + +static void +wc_spell_checking_languages_cb(MqConfig *config, const gchar *name, + const gchar G_GNUC_UNUSED *value, WebKitWebContext *web_context) +{ + webkit_web_context_set_spell_checking_languages(web_context, + (const gchar * const *) mq_config_get_string_list(config, + name)); +} + +static void +wc_preferred_languages_cb(MqConfig *config, const gchar *name, + const gchar G_GNUC_UNUSED *value, WebKitWebContext *web_context) +{ + webkit_web_context_set_preferred_languages(web_context, + (const gchar * const *) mq_config_get_string_list(config, + name)); +} + +static void +cm_accept_policy_cb(MqConfig G_GNUC_UNUSED *config, + const gchar G_GNUC_UNUSED *name, const gchar *value, + WebKitCookieManager *cookie_manager) +{ + if (g_strcmp0(value, "always") == 0) { + webkit_cookie_manager_set_accept_policy(cookie_manager, + WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); + } else if (g_strcmp0(value, "never") == 0) { + webkit_cookie_manager_set_accept_policy(cookie_manager, + WEBKIT_COOKIE_POLICY_ACCEPT_NEVER); + } else if (g_strcmp0(value, "never") == 0) { + webkit_cookie_manager_set_accept_policy(cookie_manager, + WEBKIT_COOKIE_POLICY_ACCEPT_NEVER); + } else if (g_strcmp0(value, "no-third-party") == 0) { + webkit_cookie_manager_set_accept_policy(cookie_manager, + WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY); + } else { + g_assert_not_reached(); + } +} + +void +mq_settings_connect_config(MqSettings *settings, MqConfig *config) +{ + gsize i; + WebKitCookieManager *cookie_manager; + + /* mq_settings_set_web_context() must be called first. */ + g_assert(settings->web_context); + + cookie_manager = webkit_web_context_get_cookie_manager( + settings->web_context); + + for (i = 0; i < sizeof(mappings) / sizeof(mappings[0]); ++i) { + if (g_hash_table_lookup(settings->overrides, + mappings[i].mq_name)) { + continue; + } + switch (mappings[i].type) { + case MAP_BOOL: + mq_config_notify_boolean(config, + mappings[i].mq_name, + (MqConfigBooleanCallback) bool_cb, + settings); + bool_cb(config, mappings[i].mq_name, + mq_config_get_boolean(config, + mappings[i].mq_name), + settings); + break; + case MAP_BOOL_N: + mq_config_notify_boolean(config, + mappings[i].mq_name, + (MqConfigBooleanCallback) bool_n_cb, + settings); + bool_n_cb(config, mappings[i].mq_name, + mq_config_get_boolean(config, + mappings[i].mq_name), + settings); + break; + case MAP_INT: + mq_config_notify_integer(config, + mappings[i].mq_name, + (MqConfigIntegerCallback) int_cb, + settings); + int_cb(config, mappings[i].mq_name, + mq_config_get_integer(config, + mappings[i].mq_name), + settings); + break; + case MAP_STR: + mq_config_notify_string(config, + mappings[i].mq_name, + (MqConfigStringCallback) str_cb, + settings); + str_cb(config, mappings[i].mq_name, + mq_config_get_string(config, + mappings[i].mq_name), + settings); + break; + } + } + + /* The overrides table is no longer needed. */ + g_hash_table_unref(settings->overrides); + + /* General -> Spell Checking */ + mq_config_notify_boolean(config, "spell.enable", + (MqConfigBooleanCallback) wc_spell_checking_enabled_cb, + settings->web_context); + wc_spell_checking_enabled_cb(config, "spell.enable", + mq_config_get_boolean(config, "spell.enable"), + settings->web_context); + mq_config_notify_string(config, "spell.langs", + (MqConfigStringCallback) wc_spell_checking_languages_cb, + settings->web_context); + wc_spell_checking_languages_cb(config, "spell.langs", NULL, + settings->web_context); + + /* Display -> Languages */ + mq_config_notify_string(config, "intl.accept-languages", + (MqConfigStringCallback) wc_preferred_languages_cb, + settings->web_context); + wc_preferred_languages_cb(config, "intl.accept-languages", NULL, + settings->web_context); + + /* Security and Privacy -> Cookies */ + mq_config_notify_string(config, "cookies.accept", + (MqConfigStringCallback) cm_accept_policy_cb, + cookie_manager); + cm_accept_policy_cb(config, "cookies.accept", + mq_config_get_string(config, "cookies.accept"), + cookie_manager); +} diff --git a/src/settings.h b/src/settings.h new file mode 100644 index 0000000..2424c59 --- /dev/null +++ b/src/settings.h @@ -0,0 +1,74 @@ +/* + * Web view settings + * + * Copyright (C) 2017 Patrick McDermott + * + * This file is part of Marquee. + * + * Marquee 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 3 of the License, or + * (at your option) any later version. + * + * Marquee 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 Marquee. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MQ_SETTINGS_H +#define MQ_SETTINGS_H + +typedef struct _MqSettings MqSettings; +typedef struct _MqSettingsClass MqSettingsClass; + +#include <glib.h> +#include <webkit2/webkit2.h> + +#include "config.h" + +G_BEGIN_DECLS + +#define MQ_TYPE_SETTINGS (mq_settings_get_type()) +#define MQ_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + MQ_TYPE_SETTINGS, MqSettings)) +#define MQ_IS_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ + MQ_TYPE_SETTINGS)) +#define MQ_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \ + MQ_TYPE_SETTINGS, MqSettingsClass)) +#define MQ_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \ + MQ_TYPE_SETTINGS)) +#define MQ_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \ + MQ_TYPE_SETTINGS, MqSettingsClass)) + +GType +mq_settings_get_type(void); + +MqSettings * +mq_settings_new(void); + +void +mq_settings_set_web_context(MqSettings *settings, + WebKitWebContext *web_context); + +void +mq_settings_override_bool(MqSettings *settings, const gchar *name, + const gboolean value); + +void +mq_settings_override_int(MqSettings *settings, const gchar *name, + const gint value); + +void +mq_settings_override_str(MqSettings *settings, const gchar *name, + const gchar *value); + +void +mq_settings_connect_config(MqSettings *settings, MqConfig *config); + +G_END_DECLS + +#endif /* MQ_SETTINGS_H */ |