mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 16:10:41 -05:00
Add a configuration file for ClutterSettings
ClutterSettings should be able to load its initial state by using configuration files in SYSCONFDIR and XDG_CONFIG_HOME. This allows Clutter to have a system (and user) configuration on platforms that do not have XSETTINGS bridges.
This commit is contained in:
parent
01080dc5f3
commit
f5eee5aec7
@ -27,6 +27,7 @@ AM_CPPFLAGS = \
|
||||
-DCLUTTER_LIBDIR=\""$(libdir)"\" \
|
||||
-DCLUTTER_DATADIR=\""$(datadir)"\" \
|
||||
-DCLUTTER_LOCALEDIR=\""$(localedir)"\" \
|
||||
-DCLUTTER_SYSCONFDIR=\""$(sysconfdir)"\" \
|
||||
-DCLUTTER_COMPILATION=1 \
|
||||
-DCOGL_ENABLE_EXPERIMENTAL_API \
|
||||
-DG_LOG_DOMAIN=\"Clutter\" \
|
||||
@ -240,6 +241,7 @@ source_h_priv = \
|
||||
$(srcdir)/clutter-private.h \
|
||||
$(srcdir)/clutter-profile.h \
|
||||
$(srcdir)/clutter-script-private.h \
|
||||
$(srcdir)/clutter-settings-private.h \
|
||||
$(srcdir)/clutter-stage-manager-private.h \
|
||||
$(srcdir)/clutter-stage-private.h \
|
||||
$(srcdir)/clutter-timeout-interval.h \
|
||||
|
@ -99,6 +99,7 @@
|
||||
#include "clutter-master-clock.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-profile.h"
|
||||
#include "clutter-settings-private.h"
|
||||
#include "clutter-stage-manager.h"
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-version.h" /* For flavour define */
|
||||
@ -215,6 +216,35 @@ clutter_threads_init_default (void)
|
||||
clutter_threads_unlock = clutter_threads_impl_unlock;
|
||||
}
|
||||
|
||||
#define N_CONF_DIRS 2
|
||||
|
||||
static void
|
||||
clutter_config_read (void)
|
||||
{
|
||||
ClutterSettings *settings;
|
||||
gchar *config_path;
|
||||
|
||||
settings = clutter_settings_get_default ();
|
||||
|
||||
config_path = g_build_filename (CLUTTER_SYSCONFDIR,
|
||||
"clutter-1.0",
|
||||
"settings.ini",
|
||||
NULL);
|
||||
if (g_file_test (config_path, G_FILE_TEST_EXISTS))
|
||||
_clutter_settings_read_from_file (settings, config_path);
|
||||
|
||||
g_free (config_path);
|
||||
|
||||
config_path = g_build_filename (g_get_user_config_dir (),
|
||||
"clutter-1.0",
|
||||
"settings.ini",
|
||||
NULL);
|
||||
if (g_file_test (config_path, G_FILE_TEST_EXISTS))
|
||||
_clutter_settings_read_from_file (settings, config_path);
|
||||
|
||||
g_free (config_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_get_show_fps:
|
||||
*
|
||||
@ -1105,6 +1135,12 @@ clutter_context_get_default_unlocked (void)
|
||||
ctx->is_initialized = FALSE;
|
||||
ctx->motion_events_per_actor = TRUE;
|
||||
|
||||
/* create the default settings object, and store a back pointer to
|
||||
* the backend singleton
|
||||
*/
|
||||
ctx->settings = clutter_settings_get_default ();
|
||||
_clutter_settings_set_backend (ctx->settings, ctx->backend);
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
ctx->timer = g_timer_new ();
|
||||
g_timer_start (ctx->timer);
|
||||
@ -1370,6 +1406,12 @@ pre_parse_hook (GOptionContext *context,
|
||||
g_warning ("Locale not supported by C library.\n"
|
||||
"Using the fallback 'C' locale.");
|
||||
|
||||
/* read the configuration file, if it exists; the configuration file
|
||||
* determines the initial state of the settings, so that command line
|
||||
* arguments can override them.
|
||||
*/
|
||||
clutter_config_read ();
|
||||
|
||||
clutter_context = _clutter_context_get_default ();
|
||||
|
||||
clutter_context->id_pool = _clutter_id_pool_new (256);
|
||||
|
16
clutter/clutter-settings-private.h
Normal file
16
clutter/clutter-settings-private.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef __CLUTTER_SETTINGS_PRIVATE_H__
|
||||
#define __CLUTTER_SETTINGS_PRIVATE_H__
|
||||
|
||||
#include <clutter/clutter-backend-private.h>
|
||||
#include <clutter/clutter-settings.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _clutter_settings_set_backend (ClutterSettings *settings,
|
||||
ClutterBackend *backend);
|
||||
void _clutter_settings_read_from_file (ClutterSettings *settings,
|
||||
const gchar *file);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_SETTINGS_PRIVATE_H__ */
|
@ -118,6 +118,9 @@ settings_update_font_options (ClutterSettings *self)
|
||||
cairo_subpixel_order_t subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
|
||||
cairo_font_options_t *options;
|
||||
|
||||
if (self->backend == NULL)
|
||||
return;
|
||||
|
||||
options = cairo_font_options_create ();
|
||||
|
||||
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
|
||||
@ -187,7 +190,8 @@ settings_update_font_name (ClutterSettings *self)
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "New font-name: %s", self->font_name);
|
||||
|
||||
g_signal_emit_by_name (self->backend, "font-changed");
|
||||
if (self->backend != NULL)
|
||||
g_signal_emit_by_name (self->backend, "font-changed");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -195,13 +199,17 @@ settings_update_resolution (ClutterSettings *self)
|
||||
{
|
||||
CLUTTER_NOTE (BACKEND, "New resolution: %.2f", self->resolution);
|
||||
|
||||
g_signal_emit_by_name (self->backend, "resolution-changed");
|
||||
if (self->backend != NULL)
|
||||
g_signal_emit_by_name (self->backend, "resolution-changed");
|
||||
}
|
||||
|
||||
static void
|
||||
settings_update_fontmap (ClutterSettings *self,
|
||||
guint stamp)
|
||||
{
|
||||
if (self->backend == NULL)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_PANGO_FT2
|
||||
CLUTTER_NOTE (BACKEND, "Update fontmaps (stamp: %d)", stamp);
|
||||
|
||||
@ -391,7 +399,8 @@ clutter_settings_dispatch_properties_changed (GObject *gobject,
|
||||
klass->dispatch_properties_changed (gobject, n_pspecs, pspecs);
|
||||
|
||||
/* emit settings-changed just once for multiple properties */
|
||||
g_signal_emit_by_name (self->backend, "settings-changed");
|
||||
if (self->backend != NULL)
|
||||
g_signal_emit_by_name (self->backend, "settings-changed");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -405,13 +414,17 @@ clutter_settings_class_init (ClutterSettingsClass *klass)
|
||||
* A back pointer to the #ClutterBackend
|
||||
*
|
||||
* Since: 1.4
|
||||
*
|
||||
* Deprecated: 1.10
|
||||
*/
|
||||
obj_props[PROP_BACKEND] =
|
||||
g_param_spec_object ("backend",
|
||||
"Backend",
|
||||
"A pointer to the backend",
|
||||
CLUTTER_TYPE_BACKEND,
|
||||
CLUTTER_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
|
||||
CLUTTER_PARAM_WRITABLE |
|
||||
G_PARAM_DEPRECATED |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
/**
|
||||
* ClutterSettings:double-click-time:
|
||||
@ -656,14 +669,143 @@ clutter_settings_init (ClutterSettings *self)
|
||||
ClutterSettings *
|
||||
clutter_settings_get_default (void)
|
||||
{
|
||||
ClutterMainContext *context = _clutter_context_get_default ();
|
||||
static ClutterSettings *settings = NULL;
|
||||
|
||||
if (G_LIKELY (context->settings != NULL))
|
||||
return context->settings;
|
||||
if (G_UNLIKELY (settings == NULL))
|
||||
settings = g_object_new (CLUTTER_TYPE_SETTINGS, NULL);
|
||||
|
||||
context->settings = g_object_new (CLUTTER_TYPE_SETTINGS,
|
||||
"backend", context->backend,
|
||||
NULL);
|
||||
|
||||
return context->settings;
|
||||
return settings;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_settings_set_backend (ClutterSettings *settings,
|
||||
ClutterBackend *backend)
|
||||
{
|
||||
g_assert (CLUTTER_IS_SETTINGS (settings));
|
||||
g_assert (CLUTTER_IS_BACKEND (backend));
|
||||
|
||||
settings->backend = backend;
|
||||
}
|
||||
|
||||
#define SETTINGS_GROUP "Settings"
|
||||
|
||||
void
|
||||
_clutter_settings_read_from_file (ClutterSettings *settings,
|
||||
const gchar *file)
|
||||
{
|
||||
GObjectClass *settings_class;
|
||||
GObject *settings_obj;
|
||||
GParamSpec **pspecs;
|
||||
GKeyFile *keyfile;
|
||||
GError *error;
|
||||
guint n_pspecs, i;
|
||||
|
||||
error = NULL;
|
||||
keyfile = g_key_file_new ();
|
||||
g_key_file_load_from_file (keyfile, file, G_KEY_FILE_NONE, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_critical ("Unable to read configuration from '%s': %s",
|
||||
file,
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!g_key_file_has_group (keyfile, SETTINGS_GROUP))
|
||||
goto out;
|
||||
|
||||
settings_obj = G_OBJECT (settings);
|
||||
settings_class = G_OBJECT_GET_CLASS (settings);
|
||||
pspecs = g_object_class_list_properties (settings_class, &n_pspecs);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Reading settings from '%s'", file);
|
||||
|
||||
for (i = 0; i < n_pspecs; i++)
|
||||
{
|
||||
GParamSpec *pspec = pspecs[i];
|
||||
const gchar *p_name = pspec->name;
|
||||
GType p_type = G_TYPE_FUNDAMENTAL (pspec->value_type);
|
||||
GValue value = G_VALUE_INIT;
|
||||
GError *key_error = NULL;
|
||||
|
||||
g_value_init (&value, p_type);
|
||||
|
||||
switch (p_type)
|
||||
{
|
||||
case G_TYPE_INT:
|
||||
case G_TYPE_UINT:
|
||||
{
|
||||
gint val;
|
||||
|
||||
val = g_key_file_get_integer (keyfile,
|
||||
SETTINGS_GROUP, p_name,
|
||||
&key_error);
|
||||
if (p_type == G_TYPE_INT)
|
||||
g_value_set_int (&value, val);
|
||||
else
|
||||
g_value_set_uint (&value, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case G_TYPE_BOOLEAN:
|
||||
{
|
||||
gboolean val;
|
||||
|
||||
val = g_key_file_get_boolean (keyfile,
|
||||
SETTINGS_GROUP, p_name,
|
||||
&key_error);
|
||||
g_value_set_boolean (&value, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case G_TYPE_FLOAT:
|
||||
case G_TYPE_DOUBLE:
|
||||
{
|
||||
gdouble val;
|
||||
|
||||
val = g_key_file_get_double (keyfile,
|
||||
SETTINGS_GROUP, p_name,
|
||||
&key_error);
|
||||
if (p_type == G_TYPE_FLOAT)
|
||||
g_value_set_float (&value, val);
|
||||
else
|
||||
g_value_set_double (&value, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case G_TYPE_STRING:
|
||||
{
|
||||
const gchar *val;
|
||||
|
||||
val = g_key_file_get_string (keyfile,
|
||||
SETTINGS_GROUP, p_name,
|
||||
&key_error);
|
||||
g_value_set_string (&value, val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (key_error != NULL &&
|
||||
key_error->domain != G_KEY_FILE_ERROR &&
|
||||
key_error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
|
||||
{
|
||||
g_critical ("Unable to read the value for setting '%s' in '%s': %s",
|
||||
p_name,
|
||||
file,
|
||||
key_error->message);
|
||||
}
|
||||
|
||||
if (key_error == NULL)
|
||||
g_object_set_property (settings_obj, p_name, &value);
|
||||
else
|
||||
g_error_free (key_error);
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
g_free (pspecs);
|
||||
|
||||
out:
|
||||
g_key_file_free (keyfile);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user