gnome-control-center/gnome-settings-daemon/gnome-settings-xrdb.c
Sebastien Bacher 581c37e2bb Cleanup of gconf and a few other things, patch from Kjartan Maraas
2005-05-22  Sebastien Bacher  <seb128@debian.org>

        * ChangeLog capplets/about-me/e-image-chooser.c
        capplets/accessibility/at-properties/at-startup-session.h
        capplets/accessibility/keyboard/accessibility-keyboard.c
        capplets/background/gnome-wp-info.c
        capplets/common/gconf-property-editor.c
        capplets/common/gnome-theme-apply.c
        capplets/default-applications/gnome-default-applications-properties.c
        capplets/keybindings/gnome-keybinding-properties.c
        capplets/keyboard/gnome-keyboard-properties.c
        capplets/mouse/gnome-mouse-properties.c
        capplets/network/gnome-network-preferences.c
        capplets/sound/sound-properties-capplet.c
        capplets/theme-switcher/gnome-theme-details.c
        capplets/theme-switcher/gnome-theme-manager.c
        capplets/ui-properties/gnome-ui-properties.c
        capplets/windows/gnome-window-properties.c
        gnome-settings-daemon/factory.c
        gnome-settings-daemon/gnome-settings-accessibility-keyboard.c
        gnome-settings-daemon/gnome-settings-background.c
        gnome-settings-daemon/gnome-settings-daemon.c
        gnome-settings-daemon/gnome-settings-daemon.h
        gnome-settings-daemon/gnome-settings-font.c
        gnome-settings-daemon/gnome-settings-keybindings.c
        gnome-settings-daemon/gnome-settings-keybindings.h
        gnome-settings-daemon/gnome-settings-keyboard-xkb.c
        gnome-settings-daemon/gnome-settings-keyboard.c
        gnome-settings-daemon/gnome-settings-locate-pointer.h
        gnome-settings-daemon/gnome-settings-mouse.c
        gnome-settings-daemon/gnome-settings-multimedia-keys.c
        gnome-settings-daemon/gnome-settings-screensaver.c
        gnome-settings-daemon/gnome-settings-sound.c
        gnome-settings-daemon/gnome-settings-xmodmap.c
        gnome-settings-daemon/gnome-settings-xrdb.c
        gnome-settings-daemon/gnome-settings-xsettings.c
        libbackground/applier.c libbackground/applier.h
        libbackground/preferences.c libsounds/sound-properties.c
        libsounds/sound-view.h libwindow-settings/gnome-wm-manager.c
        libwindow-settings/metacity-window-manager.c
        typing-break/drw-break-window.c typing-break/drw-utils.h
        typing-break/drwright.c vfs-methods/fontilus/font-view.c
        vfs-methods/themus/themus-theme-applier.c:
        Cleanup of gconf and a few other things,
        patch from Kjartan Maraas <kmaraas@gnome.org> (Closes: #301945).
2005-05-22 15:46:45 +00:00

342 lines
8.4 KiB
C

/* -*- Mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; style: linux -*- */
/* gnome-settings-xrdb.c
*
* Copyright © 2003 Ross Burton
*
* Written by Ross Burton <ross@burtonini.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.
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <glib/gi18n.h>
#include <gtk/gtkwindow.h>
#include <gconf/gconf-client.h>
#include "gnome-settings-daemon.h"
#include "gnome-settings-xrdb.h"
#define SYSTEM_AD_DIR DATADIR "/control-center-2.0/xrdb"
#define GENERAL_AD SYSTEM_AD_DIR "/General.ad"
#define USER_AD_DIR ".gnome2/xrdb"
#define USER_X_RESOURCES ".Xresources"
#define USER_X_DEFAULTS ".Xdefaults"
#define GTK_THEME_KEY "/desktop/gnome/interface/gtk_theme"
GtkWidget *widget;
/*
* Theme colour functions
*/
/*
* TODO: replace with the code from Smooth? (which should really be
* public in GTK+)
*/
static GdkColor*
colour_shade (GdkColor *a, gdouble shade, GdkColor *b)
{
guint16 red, green, blue;
red = CLAMP ((a->red) * shade, 0, 0xFFFF);
green = CLAMP ((a->green) * shade, 0, 0xFFFF);
blue = CLAMP ((a->blue) * shade, 0, 0xFFFF);
b->red = red;
b->green = green;
b->blue = blue;
return b;
}
static void
append_colour_define (GString *string, const gchar* name, const GdkColor* colour)
{
g_return_if_fail (string != NULL);
g_return_if_fail (name != NULL);
g_return_if_fail (colour != NULL);
g_string_append_printf (string, "#define %s #%2.2hx%2.2hx%2.2hx\n",
name, colour->red>>8, colour->green>>8, colour->blue>>8);
}
static void
append_theme_colours (GtkStyle *style, GString *string)
{
GdkColor tmp;
g_return_if_fail (style != NULL);
g_return_if_fail (string != NULL);
append_colour_define(string, "BACKGROUND",
&style->bg[GTK_STATE_NORMAL]);
append_colour_define(string, "FOREGROUND",
&style->fg[GTK_STATE_NORMAL]);
append_colour_define(string, "SELECT_BACKGROUND",
&style->bg[GTK_STATE_SELECTED]);
append_colour_define(string, "SELECT_FOREGROUND",
&style->text[GTK_STATE_SELECTED]);
append_colour_define(string, "WINDOW_BACKGROUND",
&style->base[GTK_STATE_NORMAL]);
append_colour_define(string, "WINDOW_FOREGROUND",
&style->text[GTK_STATE_NORMAL]);
append_colour_define(string, "INACTIVE_BACKGROUND",
&style->bg[GTK_STATE_INSENSITIVE]);
append_colour_define(string, "INACTIVE_FOREGROUND",
&style->text[GTK_STATE_INSENSITIVE]);
append_colour_define(string, "ACTIVE_BACKGROUND",
&style->bg[GTK_STATE_SELECTED]);
append_colour_define(string, "ACTIVE_FOREGROUND",
&style->text[GTK_STATE_SELECTED]);
append_colour_define(string, "HIGHLIGHT",
colour_shade (&style->bg[GTK_STATE_NORMAL],
1.2, &tmp));
append_colour_define(string, "LOWLIGHT",
colour_shade (&style->bg[GTK_STATE_NORMAL],
2.0/3.0, &tmp));
return;
}
/*
* Directory scanning functions
*/
/**
* Compare two file names on their base names.
*/
static gint
compare_basenames (gconstpointer a, gconstpointer b)
{
char *base_a, *base_b;
int res;
base_a = g_path_get_basename (a);
base_b = g_path_get_basename (b);
res = strcmp (base_a, base_b);
g_free (base_a);
g_free (base_b);
return res;
}
/**
* Append the contents of a file onto the end of a GString
*/
static void
append_file (const char* file, GString *string, GError **error)
{
gchar *contents;
g_return_if_fail (string != NULL);
g_return_if_fail (file != NULL);
if (g_file_get_contents (file, &contents, NULL, error)) {
g_string_append (string, contents);
g_free (contents);
}
}
/**
* Scan a single directory for .ad files, and return them all in a
* GSList*
*/
static GSList*
scan_ad_directory (const char *path, GError **error)
{
GSList *list = NULL;
GDir *dir;
const gchar *entry;
g_return_val_if_fail (path != NULL, NULL);
dir = g_dir_open (path, 0, error);
if (*error) {
return NULL;
}
while ((entry = g_dir_read_name (dir)) != NULL) {
int len;
len = strlen (entry);
if (g_str_has_suffix (entry, ".ad")) {
list = g_slist_prepend (list, g_strdup_printf ("%s/%s", path, entry));
}
}
g_dir_close (dir);
/* TODO: sort still? */
return g_slist_sort (list, (GCompareFunc)strcmp);
}
/**
* Scan the user and system paths, and return a list of strings in the
* right order for processing.
*/
static GSList*
scan_for_files (GError **error)
{
const char* home_dir;
GSList *user_list = NULL, *system_list = NULL;
GSList *list = NULL, *p;
system_list = scan_ad_directory (SYSTEM_AD_DIR, error);
if (*error) return NULL;
home_dir = g_get_home_dir ();
if (home_dir) {
char *user_ad = g_build_filename (home_dir, USER_AD_DIR, NULL);
if (g_file_test (user_ad, G_FILE_TEST_IS_DIR)) {
user_list = scan_ad_directory (user_ad, error);
if (*error) {
g_slist_foreach (system_list, (GFunc)g_free, NULL);
g_slist_free (system_list);
g_free (user_ad);
return NULL;
}
}
g_free (user_ad);
} else {
g_warning (_("Cannot determine user's home directory"));
}
/* An alternative approach would be to strdup() the strings
and free the entire contents of these lists, but that is a
little inefficient for my liking - RB */
for (p = system_list; p != NULL; p = g_slist_next (p)) {
if (strcmp (p->data, GENERAL_AD) == 0) {
/* We ignore this, free the data now */
g_free (p->data);
continue;
}
if (g_slist_find_custom (user_list, p->data, compare_basenames)) {
/* Ditto */
g_free (p->data);
continue;
}
list = g_slist_prepend (list, p->data);
}
g_slist_free (system_list);
for (p = user_list; p != NULL; p = g_slist_next (p)) {
list = g_slist_prepend (list, p->data);
}
g_slist_free (user_list);
/* Reverse the order so it is the correct way */
list = g_slist_reverse (list);
/* Add the initial file */
list = g_slist_prepend (list, g_strdup (GENERAL_AD));
return list;
}
/**
* Append an X resources file, such as .Xresources, or .Xdefaults
*/
static void
append_xresource_file (const char * filename, GString *string, GError **error)
{
const char* home_path;
char *xresources;
g_return_if_fail (string != NULL);
home_path = g_get_home_dir ();
if (home_path == NULL) {
g_warning (_("Cannot determine user's home directory"));
return;
}
xresources = g_build_filename (home_path, filename, NULL);
if (g_file_test (xresources, G_FILE_TEST_EXISTS)) {
append_file (xresources, string, error);
if (*error) {
g_warning ("%s", (*error)->message);
g_error_free (*error);
error = NULL;
}
}
g_free (xresources);
}
/*
* Entry point
*/
static void
apply_settings (GtkStyle *style)
{
char *xrdb[] = { "xrdb", "-merge", NULL };
GString *string;
GSList *list = NULL, *p;
GError *error = NULL;
string = g_string_sized_new (256);
append_theme_colours (style, string);
list = scan_for_files (&error);
if (error) {
g_warning (error->message);
g_error_free (error);
error = NULL;
}
for (p = list; p != NULL; p=g_slist_next (p)) {
append_file (p->data, string, &error);
if (error) {
g_warning (error->message);
g_error_free (error);
error = NULL;
}
}
g_slist_foreach (list, (GFunc)g_free, NULL);
g_slist_free (list);
append_xresource_file (USER_X_RESOURCES, string, &error);
append_xresource_file (USER_X_DEFAULTS, string, &error);
if (error) {
g_warning (error->message);
g_error_free (error);
error = NULL;
}
gnome_settings_daemon_spawn_with_input (xrdb, string->str);
g_string_free (string, TRUE);
return;
}
static void
style_set_cb (GtkWidget *widget, GtkStyle *s, gpointer data)
{
apply_settings (gtk_widget_get_style (widget));
}
void
gnome_settings_xrdb_init (GConfClient *client)
{
widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (widget, "style-set", (GCallback)style_set_cb, NULL);
gtk_widget_ensure_style (widget);
}
void
gnome_settings_xrdb_load (GConfClient *client)
{
style_set_cb (widget, NULL, NULL);
}