gnome-control-center/libbackground/preferences.c
Rodney Dawes 3d5e4d4e75 Make sure that the UTF8 filename is valid and exists before trying to use
2005-10-01  Rodney Dawes  <dobey@novell.com>

	* preferences.c (bg_preferences_load, bg_preferences_merge_entry):
	Make sure that the UTF8 filename is valid and exists before trying
	to use it, otherwise fall back to using the filename encoding specified
	by the user with the environment variables used by glib to determine
	the locale encoding of filenames

	Fixes #168604
2005-10-01 21:18:21 +00:00

500 lines
14 KiB
C

/* -*- mode: c; style: linux -*- */
/* preferences.c
* Copyright (C) 2001 Ximian, Inc.
*
* Written by Bradford Hovinen <hovinen@ximian.com>
*
* 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., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gdk/gdk.h>
#include "preferences.h"
static GObjectClass *parent_class;
static void bg_preferences_init (BGPreferences *prefs,
BGPreferencesClass *class);
static void bg_preferences_class_init (BGPreferencesClass *class);
static void bg_preferences_finalize (GObject *object);
static GdkColor *read_color_from_string (const gchar *string);
static orientation_t read_orientation_from_string (gchar *string);
static wallpaper_type_t read_wptype_from_string (gchar *string);
static GEnumValue _bg_wptype_values[] = {
{ WPTYPE_TILED, "WPTYPE_TILED", "wallpaper"},
{ WPTYPE_CENTERED, "WPTYPE_CENTERED", "centered"},
{ WPTYPE_SCALED, "WPTYPE_SCALED", "scaled"},
{ WPTYPE_STRETCHED, "WPTYPE_STRETCHED", "stretched"},
{ WPTYPE_NONE, "WPTYPE_NONE", "none"},
{ 0, NULL, NULL }
};
static GEnumValue _bg_orientation_values[] = {
{ ORIENTATION_SOLID, "ORIENTATION_SOLID", "solid"},
{ ORIENTATION_HORIZ, "ORIENTATION_HORIZ", "horizontal-gradient"},
{ ORIENTATION_VERT, "ORIENTATION_VERT", "vertical-gradient"},
{ 0, NULL, NULL }
};
GType
bg_preferences_wptype_get_type (void)
{
static GType type = 0;
if (!type)
{
type = g_enum_register_static ("BgPreferencesWptype",
_bg_wptype_values);
}
return type;
}
GType
bg_preferences_orientation_get_type (void)
{
static GType type = 0;
if (!type)
{
type = g_enum_register_static ("BgPreferencesOrientation",
_bg_orientation_values);
}
return type;
}
GType
bg_preferences_get_type (void)
{
static GType bg_preferences_type = 0;
if (!bg_preferences_type) {
GTypeInfo bg_preferences_info = {
sizeof (BGPreferencesClass),
NULL,
NULL,
(GClassInitFunc) bg_preferences_class_init,
NULL,
NULL,
sizeof (BGPreferences),
0,
(GInstanceInitFunc) bg_preferences_init,
};
bg_preferences_type =
g_type_register_static (G_TYPE_OBJECT, "BGPreferences", &bg_preferences_info, 0);
}
return bg_preferences_type;
}
static void
bg_preferences_init (BGPreferences *prefs,
BGPreferencesClass *class)
{
prefs->frozen = FALSE;
/* Load default values */
prefs->color1 = read_color_from_string ("#39374b");
prefs->color2 = read_color_from_string ("#42528f");
prefs->enabled = TRUE;
prefs->wallpaper_enabled = FALSE;
prefs->gradient_enabled = TRUE;
prefs->orientation = ORIENTATION_VERT;
prefs->wallpaper_type = WPTYPE_TILED;
prefs->wallpaper_filename = NULL;
prefs->wallpaper_sel_path = g_strdup (g_get_home_dir ());
prefs->auto_apply = TRUE;
prefs->wallpapers = NULL;
prefs->adjust_opacity = TRUE;
prefs->opacity = 255;
}
static void
bg_preferences_class_init (BGPreferencesClass *class)
{
GObjectClass *object_class;
object_class = (GObjectClass *) class;
object_class->finalize = bg_preferences_finalize;
parent_class =
G_OBJECT_CLASS (g_type_class_ref (G_TYPE_OBJECT));
}
GObject *
bg_preferences_new (void)
{
GObject *object;
object = g_object_new (bg_preferences_get_type (), NULL);
BG_PREFERENCES (object)->enabled = TRUE;
return object;
}
GObject *
bg_preferences_clone (const BGPreferences *prefs)
{
GObject *object;
BGPreferences *new_prefs;
g_return_val_if_fail (prefs != NULL, NULL);
g_return_val_if_fail (IS_BG_PREFERENCES (prefs), NULL);
object = bg_preferences_new ();
new_prefs = BG_PREFERENCES (object);
new_prefs->enabled = prefs->enabled;
new_prefs->gradient_enabled = prefs->gradient_enabled;
new_prefs->wallpaper_enabled = prefs->wallpaper_enabled;
new_prefs->orientation = prefs->orientation;
new_prefs->wallpaper_type = prefs->wallpaper_type;
if (new_prefs->color1 != NULL)
gdk_color_free (new_prefs->color1);
new_prefs->color1 = (prefs->color1 != NULL)
? gdk_color_copy (prefs->color1) : NULL;
if (new_prefs->color2 != NULL)
gdk_color_free (new_prefs->color2);
new_prefs->color2 = (prefs->color2 != NULL)
? gdk_color_copy (prefs->color2) : NULL;
if (new_prefs->wallpaper_filename != NULL)
g_free (new_prefs->wallpaper_filename);
new_prefs->wallpaper_filename = g_strdup (prefs->wallpaper_filename);
if (new_prefs->wallpaper_sel_path != NULL)
g_free (new_prefs->wallpaper_sel_path);
new_prefs->wallpaper_sel_path = g_strdup (prefs->wallpaper_sel_path);;
new_prefs->auto_apply = prefs->auto_apply;
new_prefs->adjust_opacity = prefs->adjust_opacity;
new_prefs->opacity = prefs->opacity;
return object;
}
static void
bg_preferences_finalize (GObject *object)
{
BGPreferences *prefs;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_BG_PREFERENCES (object));
prefs = BG_PREFERENCES (object);
g_free (prefs->wallpaper_filename);
prefs->wallpaper_filename = NULL;
g_free (prefs->wallpaper_sel_path);
prefs->wallpaper_sel_path = NULL;
if (prefs->color1 != NULL) {
gdk_color_free (prefs->color1);
prefs->color1 = NULL;
}
if (prefs->color2 != NULL) {
gdk_color_free (prefs->color2);
prefs->color2 = NULL;
}
parent_class->finalize (object);
}
void
bg_preferences_load (BGPreferences *prefs)
{
GConfClient *client;
GError *error = NULL;
char *tmp;
g_return_if_fail (prefs != NULL);
g_return_if_fail (IS_BG_PREFERENCES (prefs));
client = gconf_client_get_default ();
prefs->enabled = gconf_client_get_bool (client, BG_PREFERENCES_DRAW_BACKGROUND, &error);
tmp = gconf_client_get_string (client, BG_PREFERENCES_PICTURE_FILENAME, &error);
if (g_utf8_validate (tmp, -1, NULL) &&
g_file_test (tmp, G_FILE_TEST_EXISTS))
prefs->wallpaper_filename = g_strdup (tmp);
else
prefs->wallpaper_filename = g_filename_from_utf8 (tmp, -1, NULL,
NULL, NULL);
g_free (tmp);
if (prefs->color1 != NULL)
gdk_color_free (prefs->color1);
tmp = gconf_client_get_string (client, BG_PREFERENCES_PRIMARY_COLOR, &error);
prefs->color1 = read_color_from_string (tmp);
g_free (tmp);
if (prefs->color2 != NULL)
gdk_color_free (prefs->color2);
tmp = gconf_client_get_string (client, BG_PREFERENCES_SECONDARY_COLOR, &error);
prefs->color2 = read_color_from_string (tmp);
g_free (tmp);
prefs->opacity = gconf_client_get_int (client, BG_PREFERENCES_PICTURE_OPACITY, &error);
if (prefs->opacity >= 100 || prefs->opacity < 0)
prefs->adjust_opacity = FALSE;
prefs->orientation = read_orientation_from_string (gconf_client_get_string (client, BG_PREFERENCES_COLOR_SHADING_TYPE, &error));
if (prefs->orientation == ORIENTATION_SOLID)
prefs->gradient_enabled = FALSE;
else
prefs->gradient_enabled = TRUE;
prefs->wallpaper_type = read_wptype_from_string (gconf_client_get_string (client, BG_PREFERENCES_PICTURE_OPTIONS, &error));
if (prefs->wallpaper_type == WPTYPE_UNSET) {
prefs->wallpaper_enabled = FALSE;
prefs->wallpaper_type = WPTYPE_CENTERED;
} else {
prefs->wallpaper_enabled = TRUE;
}
g_object_unref (client);
}
/* Parse the event name given (the event being notification of a property having
* changed and apply that change to the bg_preferences structure. Eliminates the
* need to reload the structure entirely on every event notification
*/
void
bg_preferences_merge_entry (BGPreferences *prefs,
const GConfEntry *entry)
{
const GConfValue *value = gconf_entry_get_value (entry);
g_return_if_fail (prefs != NULL);
g_return_if_fail (IS_BG_PREFERENCES (prefs));
if (!strcmp (entry->key, BG_PREFERENCES_PICTURE_OPTIONS)) {
wallpaper_type_t wallpaper_type = read_wptype_from_string (g_strdup (gconf_value_get_string (value)));
if (wallpaper_type == WPTYPE_UNSET) {
prefs->wallpaper_enabled = FALSE;
} else {
prefs->wallpaper_type = wallpaper_type;
prefs->wallpaper_enabled = TRUE;
}
}
else if (!strcmp (entry->key, BG_PREFERENCES_PICTURE_FILENAME)) {
const char *tmp;
tmp = gconf_value_get_string (value);
if (g_utf8_validate (tmp, -1, NULL) &&
g_file_test (tmp, G_FILE_TEST_EXISTS))
prefs->wallpaper_filename = g_strdup (tmp);
else
prefs->wallpaper_filename = g_filename_from_utf8 (tmp, -1,
NULL,
NULL,
NULL);
if (prefs->wallpaper_filename != NULL &&
strcmp (prefs->wallpaper_filename, "") != 0 &&
strcmp (prefs->wallpaper_filename, "(none)") != 0)
prefs->wallpaper_enabled = TRUE;
else
prefs->wallpaper_enabled = FALSE;
}
else if (!strcmp (entry->key, BG_PREFERENCES_PRIMARY_COLOR)) {
if (prefs->color1 != NULL)
gdk_color_free (prefs->color1);
prefs->color1 = read_color_from_string (gconf_value_get_string (value));
}
else if (!strcmp (entry->key, BG_PREFERENCES_SECONDARY_COLOR)) {
if (prefs->color2 != NULL)
gdk_color_free (prefs->color2);
prefs->color2 = read_color_from_string (gconf_value_get_string (value));
}
else if (!strcmp (entry->key, BG_PREFERENCES_PICTURE_OPACITY)) {
prefs->opacity = gconf_value_get_int (value);
if (prefs->opacity >= 100)
prefs->adjust_opacity = FALSE;
}
else if (!strcmp (entry->key, BG_PREFERENCES_COLOR_SHADING_TYPE)) {
prefs->orientation = read_orientation_from_string (g_strdup (gconf_value_get_string (value)));
if (prefs->orientation == ORIENTATION_SOLID)
prefs->gradient_enabled = FALSE;
else
prefs->gradient_enabled = TRUE;
}
else if (!strcmp (entry->key, BG_PREFERENCES_DRAW_BACKGROUND)) {
if (gconf_value_get_bool (value) &&
(prefs->wallpaper_filename != NULL) &&
strcmp (prefs->wallpaper_filename, "") != 0 &&
strcmp (prefs->wallpaper_filename, "(none)") != 0)
prefs->wallpaper_enabled = TRUE;
else
prefs->enabled = FALSE;
} else {
g_warning ("%s: Unknown property: %s", G_GNUC_FUNCTION, entry->key);
}
}
static wallpaper_type_t
read_wptype_from_string (gchar *string)
{
wallpaper_type_t type = WPTYPE_UNSET;
if (string) {
if (!strncmp (string, "wallpaper", sizeof ("wallpaper"))) {
type = WPTYPE_TILED;
} else if (!strncmp (string, "centered", sizeof ("centered"))) {
type = WPTYPE_CENTERED;
} else if (!strncmp (string, "scaled", sizeof ("scaled"))) {
type = WPTYPE_SCALED;
} else if (!strncmp (string, "stretched", sizeof ("stretched"))) {
type = WPTYPE_STRETCHED;
}
g_free (string);
}
return type;
}
static orientation_t
read_orientation_from_string (gchar *string)
{
orientation_t type = ORIENTATION_SOLID;
if (string) {
if (!strncmp (string, "vertical-gradient", sizeof ("vertical-gradient"))) {
type = ORIENTATION_VERT;
} else if (!strncmp (string, "horizontal-gradient", sizeof ("horizontal-gradient"))) {
type = ORIENTATION_HORIZ;
}
g_free (string);
}
return type;
}
static GdkColor *
read_color_from_string (const gchar *string)
{
GdkColor color;
/* If all else fails use black */
if (string == NULL || !gdk_color_parse (string, &color))
gdk_color_parse ("black", &color);
gdk_rgb_find_color (gdk_rgb_get_colormap (), &color);
return gdk_color_copy (&color);
}
const gchar*
bg_preferences_get_wptype_as_string (wallpaper_type_t wp)
{
switch (wp)
{
case WPTYPE_TILED:
return "wallpaper";
case WPTYPE_CENTERED:
return "centered";
case WPTYPE_SCALED:
return "scaled";
case WPTYPE_STRETCHED:
return "stretched";
case WPTYPE_NONE:
return "none";
case WPTYPE_UNSET:
return NULL;
}
return NULL;
}
const gchar*
bg_preferences_get_orientation_as_string (orientation_t o)
{
switch (o)
{
case ORIENTATION_SOLID:
return "solid";
case ORIENTATION_HORIZ:
return "horizontal-gradient";
case ORIENTATION_VERT:
return "vertical-gradient";
}
return NULL;
}
void
bg_preferences_save (BGPreferences *prefs)
{
GConfChangeSet *cs;
gchar *tmp;
GConfClient *client;
g_return_if_fail (prefs != NULL);
g_return_if_fail (IS_BG_PREFERENCES (prefs));
client = gconf_client_get_default();
cs = gconf_change_set_new ();
gconf_change_set_set_bool (cs, BG_PREFERENCES_DRAW_BACKGROUND, prefs->enabled);
if (prefs->wallpaper_enabled)
gconf_change_set_set_string (cs, BG_PREFERENCES_PICTURE_OPTIONS, bg_preferences_get_wptype_as_string (prefs->wallpaper_type));
else
gconf_change_set_set_string (cs, BG_PREFERENCES_PICTURE_OPTIONS, "none");
gconf_change_set_set_string (cs, BG_PREFERENCES_PICTURE_FILENAME, prefs->wallpaper_filename);
tmp = g_strdup_printf ("#%02x%02x%02x",
prefs->color1->red >> 8,
prefs->color1->green >> 8,
prefs->color1->blue >> 8);
gconf_change_set_set_string (cs, BG_PREFERENCES_PRIMARY_COLOR, tmp);
g_free (tmp);
tmp = g_strdup_printf ("#%02x%02x%02x",
prefs->color2->red >> 8,
prefs->color2->green >> 8,
prefs->color2->blue >> 8);
gconf_change_set_set_string (cs, BG_PREFERENCES_SECONDARY_COLOR, tmp);
g_free (tmp);
gconf_change_set_set_string (cs, BG_PREFERENCES_COLOR_SHADING_TYPE, bg_preferences_get_orientation_as_string (prefs->orientation));
gconf_client_commit_change_set (client, cs, TRUE, NULL);
gconf_change_set_unref (cs);
g_object_unref (client);
}