From 2b2816622012be0b494b59330dc08587c5e27b14 Mon Sep 17 00:00:00 2001 From: Sayamindu Dasgupta Date: Sun, 31 Jan 2010 09:20:21 +0000 Subject: Initial import --- diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/AUTHORS diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..e6b68ce --- /dev/null +++ b/COPYING @@ -0,0 +1,25 @@ + +Copyright (c) 2001 Red Hat, Inc. + (c) 2010 One Laptop Per Child + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name of Red Hat not be used in advertising or +publicity pertaining to distribution of the software without specific, +written prior permission. Red Hat makes no representations about the +suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT +BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Authors: Owen Taylor, Red Hat, Inc. + Sayamindu Dasgupta, One Laptop Per Child + + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..af437a6 --- /dev/null +++ b/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/NEWS diff --git a/README b/README new file mode 100644 index 0000000..17200cc --- /dev/null +++ b/README @@ -0,0 +1,4 @@ +Settings manager daemon for Sugar Learning Environment. + +Based on sample xsettings-manager reference +implementation from http://webcvs.freedesktop.org/xsettings/xsettings diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..0f0c5ed --- /dev/null +++ b/autogen.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +PKG_NAME="sugar-settings-manager" + +(test -f $srcdir/configure.in) || { + echo -n "**Error**: Directory \"\`$srcdir\'\" does not look like the" + echo " top-level $PKG_NAME directory" + exit 1 +} + +which gnome-autogen.sh || { + echo "You need to install gnome-common from the GNOME CVS" + exit 1 +} + +REQUIRED_AUTOMAKE_VERSION=1.6 +export REQUIRED_AUTOMAKE_VERSION + +USE_GNOME2_MACROS=1 . gnome-autogen.sh diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..6c1030e --- /dev/null +++ b/configure.in @@ -0,0 +1,17 @@ +AC_PREREQ(2.52) + +AC_INIT(sugar-settings-manager, 0.1) +AC_CONFIG_SRCDIR(src) +AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) +AM_CONFIG_HEADER(config.h) + +AC_PROG_CC + +PKG_CHECK_MODULES(SSM, [gtk+-2.0 gconf-2.0]) +AC_SUBST(SSM_CFLAGS) +AC_SUBST(SSM_LIBS) + +AC_OUTPUT([ +Makefile +src/Makefile +]) diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..64a84fb --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = $(SSM_CFLAGS) + +bin_PROGRAMS = sugar-settings-manager + +sugar_settings_manager_SOURCES = sugar-settings-manager.c \ + xsettings-common.c \ + xsettings-common.h \ + xsettings-manager.c \ + xsettings-manager.h +sugar_settings_manager_LDADD = $(SSM_LIBS) diff --git a/src/sugar-settings-manager.c b/src/sugar-settings-manager.c new file mode 100644 index 0000000..37b93a1 --- /dev/null +++ b/src/sugar-settings-manager.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2001 Red Hat, Inc. + * (c) 2010 One Laptop Per Child + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Owen Taylor, Red Hat, Inc. + * Sayamindu Dasgupta + * + +#include +#include + +#include +#include + +#include + +#include "xsettings-manager.h" + +#define SUGAR_FONT_DIR "/desktop/sugar/font" +#define SUGAR_FONT_FACE_KEY "/desktop/sugar/font/default_face" +#define SUGAR_FONT_SIZE_KEY "/desktop/sugar/font/default_size" + +/* See http://freedesktop.org/wiki/Specifications/XSettingsRegistry */ +#define XSETTINGS_REGISTRY_GTK_FONT_NAME "Gtk/FontName" + +XSettingsManager *manager; +GConfClient *client; + +void terminate_cb() +{ + gtk_main_quit(); +} + +GdkFilterReturn +manager_event_filter(GdkXEvent * xevent, GdkEvent * event, gpointer data) +{ + if (xsettings_manager_process_event(manager, (XEvent *) xevent)) + return GDK_FILTER_REMOVE; + else + return GDK_FILTER_CONTINUE; +} + +void update_font() +{ + gchar *font_face, *font_name; + gdouble font_size; + + font_face = gconf_client_get_string(client, SUGAR_FONT_FACE_KEY, NULL); + if (!font_face) + return; + + font_size = gconf_client_get_float(client, SUGAR_FONT_SIZE_KEY, NULL); + if (!font_size) + return; + + font_name = g_strdup_printf("%s %f", font_face, font_size); + + xsettings_manager_set_string(manager, XSETTINGS_REGISTRY_GTK_FONT_NAME, + font_name); + xsettings_manager_notify(manager); +} + +void +font_face_changed_callback(GConfClient * client, + guint cnxn_id, + GConfEntry * entry, gpointer user_data) +{ + if (entry->value == NULL) { + return; + } else { + if (entry->value->type == GCONF_VALUE_STRING) { + update_font(); + } else { + return; + } + } +} + +void +font_size_changed_callback(GConfClient * client, + guint cnxn_id, + GConfEntry * entry, gpointer user_data) +{ + if (entry->value == NULL) { + return; + } else { + if (entry->value->type == GCONF_VALUE_FLOAT) { + update_font(); + } else { + return; + } + } +} + + +void setup_font() +{ + client = gconf_client_get_default(); + gconf_client_add_dir(client, + SUGAR_FONT_DIR, GCONF_CLIENT_PRELOAD_NONE, NULL); + + gconf_client_notify_add(client, SUGAR_FONT_FACE_KEY, + (GConfClientNotifyFunc) + font_face_changed_callback, NULL, NULL, NULL); + + gconf_client_notify_add(client, SUGAR_FONT_SIZE_KEY, + (GConfClientNotifyFunc) + font_size_changed_callback, NULL, NULL, NULL); + + update_font(); +} + +int main(int argc, char **argv) +{ + gtk_init(&argc, &argv); + + if (xsettings_manager_check_running + (gdk_display, DefaultScreen(gdk_display))) { + fprintf(stderr, + "Could not create manager! Manager already running.\n"); + exit(1); + } + + manager = + xsettings_manager_new(gdk_display, DefaultScreen(gdk_display), + terminate_cb, NULL); + if (!manager) { + fprintf(stderr, "Could not create manager!\n"); + exit(1); + } + + gdk_window_add_filter(NULL, manager_event_filter, NULL); + + setup_font(); + gtk_main(); + + xsettings_manager_destroy(manager); + g_object_unref(client); + + return 0; +} diff --git a/src/xsettings-common.c b/src/xsettings-common.c new file mode 100644 index 0000000..3d74440 --- /dev/null +++ b/src/xsettings-common.c @@ -0,0 +1,264 @@ +/* + * Copyright © 2001 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Owen Taylor, Red Hat, Inc. + */ +#include "string.h" +#include "stdlib.h" + +#include +#include /* For CARD32 */ + +#include "xsettings-common.h" + +XSettingsSetting * +xsettings_setting_copy (XSettingsSetting *setting) +{ + XSettingsSetting *result; + size_t str_len; + + result = malloc (sizeof *result); + if (!result) + return NULL; + + str_len = strlen (setting->name); + result->name = malloc (str_len + 1); + if (!result->name) + goto err; + + memcpy (result->name, setting->name, str_len + 1); + + result->type = setting->type; + + switch (setting->type) + { + case XSETTINGS_TYPE_INT: + result->data.v_int = setting->data.v_int; + break; + case XSETTINGS_TYPE_COLOR: + result->data.v_color = setting->data.v_color; + break; + case XSETTINGS_TYPE_STRING: + str_len = strlen (setting->data.v_string); + result->data.v_string = malloc (str_len + 1); + if (!result->data.v_string) + goto err; + + memcpy (result->data.v_string, setting->data.v_string, str_len + 1); + break; + } + + result->last_change_serial = setting->last_change_serial; + + return result; + + err: + if (result->name) + free (result->name); + free (result); + + return NULL; +} + +XSettingsList * +xsettings_list_copy (XSettingsList *list) +{ + XSettingsList *new = NULL; + XSettingsList *old_iter = list; + XSettingsList *new_iter = NULL; + + while (old_iter) + { + XSettingsList *new_node; + + new_node = malloc (sizeof *new_node); + if (!new_node) + goto error; + + new_node->setting = xsettings_setting_copy (old_iter->setting); + if (!new_node->setting) + { + free (new_node); + goto error; + } + + if (new_iter) + new_iter->next = new_node; + else + new = new_node; + + new_iter = new_node; + + old_iter = old_iter->next; + } + + return new; + + error: + xsettings_list_free (new); + return NULL; +} + +int +xsettings_setting_equal (XSettingsSetting *setting_a, + XSettingsSetting *setting_b) +{ + if (setting_a->type != setting_b->type) + return 0; + + if (strcmp (setting_a->name, setting_b->name) != 0) + return 0; + + switch (setting_a->type) + { + case XSETTINGS_TYPE_INT: + return setting_a->data.v_int == setting_b->data.v_int; + case XSETTINGS_TYPE_COLOR: + return (setting_a->data.v_color.red == setting_b->data.v_color.red && + setting_a->data.v_color.green == setting_b->data.v_color.green && + setting_a->data.v_color.blue == setting_b->data.v_color.blue && + setting_a->data.v_color.alpha == setting_b->data.v_color.alpha); + case XSETTINGS_TYPE_STRING: + return strcmp (setting_a->data.v_string, setting_b->data.v_string) == 0; + } + + return 0; +} + +void +xsettings_setting_free (XSettingsSetting *setting) +{ + if (setting->type == XSETTINGS_TYPE_STRING) + free (setting->data.v_string); + + if (setting->name) + free (setting->name); + + free (setting); +} + +void +xsettings_list_free (XSettingsList *list) +{ + while (list) + { + XSettingsList *next = list->next; + + xsettings_setting_free (list->setting); + free (list); + + list = next; + } +} + +XSettingsResult +xsettings_list_insert (XSettingsList **list, + XSettingsSetting *setting) +{ + XSettingsList *node; + XSettingsList *iter; + XSettingsList *last = NULL; + + node = malloc (sizeof *node); + if (!node) + return XSETTINGS_NO_MEM; + node->setting = setting; + + iter = *list; + while (iter) + { + int cmp = strcmp (setting->name, iter->setting->name); + + if (cmp < 0) + break; + else if (cmp == 0) + { + free (node); + return XSETTINGS_DUPLICATE_ENTRY; + } + + last = iter; + iter = iter->next; + } + + if (last) + last->next = node; + else + *list = node; + + node->next = iter; + + return XSETTINGS_SUCCESS; +} + +XSettingsResult +xsettings_list_delete (XSettingsList **list, + const char *name) +{ + XSettingsList *iter; + XSettingsList *last = NULL; + + iter = *list; + while (iter) + { + if (strcmp (name, iter->setting->name) == 0) + { + if (last) + last->next = iter->next; + else + *list = iter->next; + + xsettings_setting_free (iter->setting); + free (iter); + + return XSETTINGS_SUCCESS; + } + + last = iter; + iter = iter->next; + } + + return XSETTINGS_FAILED; +} + +XSettingsSetting * +xsettings_list_lookup (XSettingsList *list, + const char *name) +{ + XSettingsList *iter; + + iter = list; + while (iter) + { + if (strcmp (name, iter->setting->name) == 0) + return iter->setting; + + iter = iter->next; + } + + return NULL; +} + +char +xsettings_byte_order (void) +{ + CARD32 myint = 0x01020304; + return (*(char *)&myint == 1) ? MSBFirst : LSBFirst; +} diff --git a/src/xsettings-common.h b/src/xsettings-common.h new file mode 100644 index 0000000..e3af4a6 --- /dev/null +++ b/src/xsettings-common.h @@ -0,0 +1,110 @@ +/* + * Copyright © 2001 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Owen Taylor, Red Hat, Inc. + */ +#ifndef XSETTINGS_COMMON_H +#define XSETTINGS_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _XSettingsBuffer XSettingsBuffer; +typedef struct _XSettingsColor XSettingsColor; +typedef struct _XSettingsList XSettingsList; +typedef struct _XSettingsSetting XSettingsSetting; + +/* Types of settings possible. Enum values correspond to + * protocol values. + */ +typedef enum +{ + XSETTINGS_TYPE_INT = 0, + XSETTINGS_TYPE_STRING = 1, + XSETTINGS_TYPE_COLOR = 2 +} XSettingsType; + +typedef enum +{ + XSETTINGS_SUCCESS, + XSETTINGS_NO_MEM, + XSETTINGS_ACCESS, + XSETTINGS_FAILED, + XSETTINGS_NO_ENTRY, + XSETTINGS_DUPLICATE_ENTRY +} XSettingsResult; + +struct _XSettingsBuffer +{ + char byte_order; + size_t len; + unsigned char *data; + unsigned char *pos; +}; + +struct _XSettingsColor +{ + unsigned short red, green, blue, alpha; +}; + +struct _XSettingsList +{ + XSettingsSetting *setting; + XSettingsList *next; +}; + +struct _XSettingsSetting +{ + char *name; + XSettingsType type; + + union { + int v_int; + char *v_string; + XSettingsColor v_color; + } data; + + unsigned long last_change_serial; +}; + +XSettingsSetting *xsettings_setting_copy (XSettingsSetting *setting); +void xsettings_setting_free (XSettingsSetting *setting); +int xsettings_setting_equal (XSettingsSetting *setting_a, + XSettingsSetting *setting_b); + +void xsettings_list_free (XSettingsList *list); +XSettingsList *xsettings_list_copy (XSettingsList *list); +XSettingsResult xsettings_list_insert (XSettingsList **list, + XSettingsSetting *setting); +XSettingsSetting *xsettings_list_lookup (XSettingsList *list, + const char *name); +XSettingsResult xsettings_list_delete (XSettingsList **list, + const char *name); + +char xsettings_byte_order (void); + +#define XSETTINGS_PAD(n,m) ((n + m - 1) & (~(m-1))) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XSETTINGS_COMMON_H */ diff --git a/src/xsettings-manager.c b/src/xsettings-manager.c new file mode 100644 index 0000000..ced791d --- /dev/null +++ b/src/xsettings-manager.c @@ -0,0 +1,425 @@ +/* + * Copyright © 2001 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Owen Taylor, Red Hat, Inc. + */ + +#include +#include +#include + +#include /* For CARD16 */ + +#include "xsettings-manager.h" + +struct _XSettingsManager +{ + Display *display; + int screen; + + Window window; + Atom manager_atom; + Atom selection_atom; + Atom xsettings_atom; + + XSettingsTerminateFunc terminate; + void *cb_data; + + XSettingsList *settings; + unsigned long serial; +}; + +XSettingsList *settings; + +typedef struct +{ + Window window; + Atom timestamp_prop_atom; +} TimeStampInfo; + +static Bool +timestamp_predicate (Display *display, + XEvent *xevent, + XPointer arg) +{ + TimeStampInfo *info = (TimeStampInfo *)arg; + + if (xevent->type == PropertyNotify && + xevent->xproperty.window == info->window && + xevent->xproperty.atom == info->timestamp_prop_atom) + return True; + + return False; +} + +/** + * get_server_time: + * @display: display from which to get the time + * @window: a #Window, used for communication with the server. + * The window must have PropertyChangeMask in its + * events mask or a hang will result. + * + * Routine to get the current X server time stamp. + * + * Return value: the time stamp. + **/ +static Time +get_server_time (Display *display, + Window window) +{ + unsigned char c = 'a'; + XEvent xevent; + TimeStampInfo info; + + info.timestamp_prop_atom = XInternAtom (display, "_TIMESTAMP_PROP", False); + info.window = window; + + XChangeProperty (display, window, + info.timestamp_prop_atom, info.timestamp_prop_atom, + 8, PropModeReplace, &c, 1); + + XIfEvent (display, &xevent, + timestamp_predicate, (XPointer)&info); + + return xevent.xproperty.time; +} + +Bool +xsettings_manager_check_running (Display *display, + int screen) +{ + char buffer[256]; + Atom selection_atom; + + sprintf(buffer, "_XSETTINGS_S%d", screen); + selection_atom = XInternAtom (display, buffer, False); + + if (XGetSelectionOwner (display, selection_atom)) + return True; + else + return False; +} + +XSettingsManager * +xsettings_manager_new (Display *display, + int screen, + XSettingsTerminateFunc terminate, + void *cb_data) +{ + XSettingsManager *manager; + Time timestamp; + XClientMessageEvent xev; + + char buffer[256]; + + manager = malloc (sizeof *manager); + if (!manager) + return NULL; + + manager->display = display; + manager->screen = screen; + + sprintf(buffer, "_XSETTINGS_S%d", screen); + manager->selection_atom = XInternAtom (display, buffer, False); + manager->xsettings_atom = XInternAtom (display, "_XSETTINGS_SETTINGS", False); + manager->manager_atom = XInternAtom (display, "MANAGER", False); + + manager->terminate = terminate; + manager->cb_data = cb_data; + + manager->settings = NULL; + manager->serial = 0; + + manager->window = XCreateSimpleWindow (display, + RootWindow (display, screen), + 0, 0, 10, 10, 0, + WhitePixel (display, screen), + WhitePixel (display, screen)); + + XSelectInput (display, manager->window, PropertyChangeMask); + timestamp = get_server_time (display, manager->window); + + XSetSelectionOwner (display, manager->selection_atom, + manager->window, timestamp); + + /* Check to see if we managed to claim the selection. If not, + * we treat it as if we got it then immediately lost it + */ + + if (XGetSelectionOwner (display, manager->selection_atom) == + manager->window) + { + xev.type = ClientMessage; + xev.window = RootWindow (display, screen); + xev.message_type = manager->manager_atom; + xev.format = 32; + xev.data.l[0] = timestamp; + xev.data.l[1] = manager->selection_atom; + xev.data.l[2] = manager->window; + xev.data.l[3] = 0; /* manager specific data */ + xev.data.l[4] = 0; /* manager specific data */ + + XSendEvent (display, RootWindow (display, screen), + False, StructureNotifyMask, (XEvent *)&xev); + } + else + { + manager->terminate (manager->cb_data); + } + + return manager; +} + +void +xsettings_manager_destroy (XSettingsManager *manager) +{ + XDestroyWindow (manager->display, manager->window); + + xsettings_list_free (manager->settings); + free (manager); +} + +Window +xsettings_manager_get_window (XSettingsManager *manager) +{ + return manager->window; +} + +Bool +xsettings_manager_process_event (XSettingsManager *manager, + XEvent *xev) +{ + if (xev->xany.window == manager->window && + xev->xany.type == SelectionClear && + xev->xselectionclear.selection == manager->selection_atom) + { + manager->terminate (manager->cb_data); + return True; + } + + return False; +} + +XSettingsResult +xsettings_manager_set_setting (XSettingsManager *manager, + XSettingsSetting *setting) +{ + XSettingsSetting *old_setting = xsettings_list_lookup (settings, setting->name); + XSettingsSetting *new_setting; + XSettingsResult result; + + if (old_setting) + { + if (xsettings_setting_equal (old_setting, setting)) + return XSETTINGS_SUCCESS; + + xsettings_list_delete (&settings, setting->name); + } + + new_setting = xsettings_setting_copy (setting); + if (!new_setting) + return XSETTINGS_NO_MEM; + + new_setting->last_change_serial = manager->serial; + + result = xsettings_list_insert (&settings, new_setting); + + if (result != XSETTINGS_SUCCESS) + xsettings_setting_free (new_setting); + + return result; +} + +XSettingsResult +xsettings_manager_delete_setting (XSettingsManager *manager, + const char *name) +{ + return xsettings_list_delete (&settings, name); +} + +XSettingsResult +xsettings_manager_set_int (XSettingsManager *manager, + const char *name, + int value) +{ + XSettingsSetting setting; + + setting.name = (char *)name; + setting.type = XSETTINGS_TYPE_INT; + setting.data.v_int = value; + + return xsettings_manager_set_setting (manager, &setting); +} + +XSettingsResult +xsettings_manager_set_string (XSettingsManager *manager, + const char *name, + const char *value) +{ + XSettingsSetting setting; + + setting.name = (char *)name; + setting.type = XSETTINGS_TYPE_STRING; + setting.data.v_string = (char *)value; + + return xsettings_manager_set_setting (manager, &setting); +} + +XSettingsResult +xsettings_manager_set_color (XSettingsManager *manager, + const char *name, + XSettingsColor *value) +{ + XSettingsSetting setting; + + setting.name = (char *)name; + setting.type = XSETTINGS_TYPE_COLOR; + setting.data.v_color = *value; + + return xsettings_manager_set_setting (manager, &setting); +} + +size_t +setting_length (XSettingsSetting *setting) +{ + size_t length = 8; /* type + pad + name-len + last-change-serial */ + length += XSETTINGS_PAD (strlen (setting->name), 4); + + switch (setting->type) + { + case XSETTINGS_TYPE_INT: + length += 4; + break; + case XSETTINGS_TYPE_STRING: + length += 4 + XSETTINGS_PAD (strlen (setting->data.v_string), 4); + break; + case XSETTINGS_TYPE_COLOR: + length += 8; + break; + } + + return length; +} + +void +setting_store (XSettingsSetting *setting, + XSettingsBuffer *buffer) +{ + size_t string_len; + size_t length; + + *(buffer->pos++) = setting->type; + *(buffer->pos++) = 0; + + string_len = strlen (setting->name); + *(CARD16 *)(buffer->pos) = string_len; + buffer->pos += 2; + + length = XSETTINGS_PAD (string_len, 4); + memcpy (buffer->pos, setting->name, string_len); + length -= string_len; + buffer->pos += string_len; + + while (length > 0) + { + *(buffer->pos++) = 0; + length--; + } + + *(CARD32 *)(buffer->pos) = setting->last_change_serial; + buffer->pos += 4; + + switch (setting->type) + { + case XSETTINGS_TYPE_INT: + *(CARD32 *)(buffer->pos) = setting->data.v_int; + buffer->pos += 4; + break; + case XSETTINGS_TYPE_STRING: + string_len = strlen (setting->data.v_string); + *(CARD32 *)(buffer->pos) = string_len; + buffer->pos += 4; + + length = XSETTINGS_PAD (string_len, 4); + memcpy (buffer->pos, setting->data.v_string, string_len); + length -= string_len; + buffer->pos += string_len; + + while (length > 0) + { + *(buffer->pos++) = 0; + length--; + } + break; + case XSETTINGS_TYPE_COLOR: + *(CARD16 *)(buffer->pos) = setting->data.v_color.red; + *(CARD16 *)(buffer->pos + 2) = setting->data.v_color.green; + *(CARD16 *)(buffer->pos + 4) = setting->data.v_color.blue; + *(CARD16 *)(buffer->pos + 6) = setting->data.v_color.alpha; + buffer->pos += 8; + break; + } +} + +XSettingsResult +xsettings_manager_notify (XSettingsManager *manager) +{ + XSettingsBuffer buffer; + XSettingsList *iter; + int n_settings = 0; + + buffer.len = 12; /* byte-order + pad + SERIAL + N_SETTINGS */ + + iter = settings; + while (iter) + { + buffer.len += setting_length (iter->setting); + n_settings++; + iter = iter->next; + } + + buffer.data = buffer.pos = malloc (buffer.len); + if (!buffer.data) + return XSETTINGS_NO_MEM; + + *buffer.pos = xsettings_byte_order (); + + buffer.pos += 4; + *(CARD32 *)buffer.pos = manager->serial++; + buffer.pos += 4; + *(CARD32 *)buffer.pos = n_settings; + buffer.pos += 4; + + iter = settings; + while (iter) + { + setting_store (iter->setting, &buffer); + iter = iter->next; + } + + XChangeProperty (manager->display, manager->window, + manager->xsettings_atom, manager->xsettings_atom, + 8, PropModeReplace, buffer.data, buffer.len); + + free (buffer.data); + + return XSETTINGS_SUCCESS; +} + diff --git a/src/xsettings-manager.h b/src/xsettings-manager.h new file mode 100644 index 0000000..2439b42 --- /dev/null +++ b/src/xsettings-manager.h @@ -0,0 +1,69 @@ +/* + * Copyright © 2001 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Owen Taylor, Red Hat, Inc. + */ +#ifndef XSETTINGS_MANAGER_H +#define XSETTINGS_MANAGER_H + +#include +#include "xsettings-common.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _XSettingsManager XSettingsManager; + +typedef void (*XSettingsTerminateFunc) (void *cb_data); + +Bool xsettings_manager_check_running (Display *display, + int screen); + +XSettingsManager *xsettings_manager_new (Display *display, + int screen, + XSettingsTerminateFunc terminate, + void *cb_data); + +void xsettings_manager_destroy (XSettingsManager *manager); +Window xsettings_manager_get_window (XSettingsManager *manager); +Bool xsettings_manager_process_event (XSettingsManager *manager, + XEvent *xev); + +XSettingsResult xsettings_manager_set_setting (XSettingsManager *manager, + XSettingsSetting *setting); +XSettingsResult xsettings_manager_delete_setting (XSettingsManager *manager, + const char *name); +XSettingsResult xsettings_manager_set_int (XSettingsManager *manager, + const char *name, + int value); +XSettingsResult xsettings_manager_set_string (XSettingsManager *manager, + const char *name, + const char *value); +XSettingsResult xsettings_manager_set_color (XSettingsManager *manager, + const char *name, + XSettingsColor *value); +XSettingsResult xsettings_manager_notify (XSettingsManager *manager); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XSETTINGS_MANAGER_H */ -- cgit v0.9.1