[Xfce4-commits] <xfce4-settings:master> Add fontconfig monitoring (bug #5011).
Nick Schermer
noreply at xfce.org
Mon Feb 28 17:16:05 CET 2011
Updating branch refs/heads/master
to 8ada5216aeeb20eac7e0ba382fcb95d0a0abd333 (commit)
from c1dd7e2db4b563fee18cd08c1b7752bf433043ad (commit)
commit 8ada5216aeeb20eac7e0ba382fcb95d0a0abd333
Author: Nick Schermer <nick at xfce.org>
Date: Wed Feb 23 18:29:58 2011 +0100
Add fontconfig monitoring (bug #5011).
Monitor the font directories and config files and notify
the applications through xsettings if there are modifications.
configure.ac.in | 4 +-
xfsettingsd/Makefile.am | 6 ++-
xfsettingsd/xsettings.c | 184 ++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 181 insertions(+), 13 deletions(-)
diff --git a/configure.ac.in b/configure.ac.in
index cfcea35..800e30a 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -63,7 +63,7 @@ AC_PROG_LIBTOOL()
dnl **********************************
dnl *** Check for standard headers ***
dnl **********************************
-AC_CHECK_HEADERS([errno.h memory.h math.h stdlib.h string.h unistd.h signal.h])
+AC_CHECK_HEADERS([errno.h memory.h math.h stdlib.h string.h unistd.h signal.h time.h])
dnl ******************************
dnl *** Check for i18n support ***
@@ -76,11 +76,13 @@ dnl ***********************************
XDT_CHECK_PACKAGE([EXO], [exo-1], [0.6.0])
XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.14.0])
XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.16.0])
+XDT_CHECK_PACKAGE([GIO], [gio-2.0], [2.16.0])
XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.8.0])
XDT_CHECK_PACKAGE([LIBXFCE4UI], [libxfce4ui-1], [4.8.0])
XDT_CHECK_PACKAGE([LIBXFCE4KBD_PRIVATE], [libxfce4kbd-private-2], [4.8.0])
XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.8.0])
XDT_CHECK_PACKAGE([DBUS_GLIB], [dbus-glib-1], [0.34])
+XDT_CHECK_PACKAGE([FONTCONFIG], [fontconfig], [2.6.0])
XDT_CHECK_PACKAGE([XI], [xi], [1.2.0], [],
[
diff --git a/xfsettingsd/Makefile.am b/xfsettingsd/Makefile.am
index 646176d..9e22d10 100644
--- a/xfsettingsd/Makefile.am
+++ b/xfsettingsd/Makefile.am
@@ -38,6 +38,7 @@ xfsettingsd_CFLAGS = \
$(GTK_CFLAGS) \
$(GLIB_CFLAGS) \
$(GTHREAD_CFLAGS) \
+ $(GIO_CFLAGS) \
$(DBUS_GLIB_CFLAGS) \
$(XFCONF_CFLAGS) \
$(LIBXFCE4UTIL_CFLAGS) \
@@ -47,6 +48,7 @@ xfsettingsd_CFLAGS = \
$(XI_CFLAGS) \
$(LIBX11_CFLAGS) \
$(LIBNOTIFY_CFLAGS) \
+ $(FONTCONFIG_CFLAGS) \
$(PLATFORM_CFLAGS)
xfsettingsd_LDFLAGS = \
@@ -57,6 +59,7 @@ xfsettingsd_LDADD = \
$(GTK_LIBS) \
$(GLIB_LIBS) \
$(GTHREAD_LIBS) \
+ $(GIO_LIBS) \
$(DBUS_GLIB_LIBS) \
$(XFCONF_LIBS) \
$(LIBXFCE4UTIL_LIBS) \
@@ -65,7 +68,8 @@ xfsettingsd_LDADD = \
$(LIBXKLAVIER_LIBS) \
$(XI_LIBS) \
$(LIBX11_LIBS) \
- $(LIBNOTIFY_LIBS)
+ $(LIBNOTIFY_LIBS) \
+ $(FONTCONFIG_LIBS)
#
# Optional support for the display settings
diff --git a/xfsettingsd/xsettings.c b/xfsettingsd/xsettings.c
index 3c1a045..28ddc36 100644
--- a/xfsettingsd/xsettings.c
+++ b/xfsettingsd/xsettings.c
@@ -32,6 +32,9 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
#include <X11/Xlib.h>
#include <X11/Xmd.h>
@@ -40,10 +43,12 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
-#include <gdk/gdkx.h>
#include <xfconf/xfconf.h>
#include <libxfce4util/libxfce4util.h>
+#include <gio/gio.h>
+#include <fontconfig/fontconfig.h>
+
#include "xsettings.h"
#define XSettingsTypeInteger 0
@@ -56,6 +61,9 @@
#define DPI_LOW_REASONABLE 50
#define DPI_HIGH_REASONABLE 500
+#define FC_TIMEOUT_SEC 2 /* timeout before xsettings notify */
+#define FC_PROPERTY "/Fontconfig/Timestamp"
+
typedef struct _XfceXSettingsScreen XfceXSettingsScreen;
@@ -64,16 +72,19 @@ typedef struct _XfceXSettingsNotify XfceXSettingsNotify;
-static void xfce_xsettings_helper_finalize (GObject *object);
-static void xfce_xsettings_helper_setting_free (gpointer data);
-static void xfce_xsettings_helper_prop_changed (XfconfChannel *channel,
- const gchar *prop_name,
- const GValue *value,
- XfceXSettingsHelper *helper);
-static void xfce_xsettings_helper_load (XfceXSettingsHelper *helper);
-static void xfce_xsettings_helper_screen_free (XfceXSettingsScreen *screen);
-static void xfce_xsettings_helper_notify_xft (XfceXSettingsHelper *helper);
-static void xfce_xsettings_helper_notify (XfceXSettingsHelper *helper);
+static void xfce_xsettings_helper_finalize (GObject *object);
+static void xfce_xsettings_helper_fc_free (XfceXSettingsHelper *helper);
+static gboolean xfce_xsettings_helper_fc_init (gpointer data);
+static gboolean xfce_xsettings_helper_notify_idle (gpointer data);
+static void xfce_xsettings_helper_setting_free (gpointer data);
+static void xfce_xsettings_helper_prop_changed (XfconfChannel *channel,
+ const gchar *prop_name,
+ const GValue *value,
+ XfceXSettingsHelper *helper);
+static void xfce_xsettings_helper_load (XfceXSettingsHelper *helper);
+static void xfce_xsettings_helper_screen_free (XfceXSettingsScreen *screen);
+static void xfce_xsettings_helper_notify_xft (XfceXSettingsHelper *helper);
+static void xfce_xsettings_helper_notify (XfceXSettingsHelper *helper);
@@ -101,7 +112,13 @@ struct _XfceXSettingsHelper
guint notify_idle_id;
guint notify_xft_idle_id;
+ /* atom for xsetting property changes */
Atom xsettings_atom;
+
+ /* fontconfig monitoring */
+ GPtrArray *fc_monitors;
+ guint fc_notify_timeout_id;
+ guint fc_init_id;
};
struct _XfceXSetting
@@ -165,6 +182,9 @@ xfce_xsettings_helper_finalize (GObject *object)
XfceXSettingsHelper *helper = XFCE_XSETTINGS_HELPER (object);
GSList *li;
+ /* stop fontconfig monitoring */
+ xfce_xsettings_helper_fc_free (helper);
+
/* stop pending update */
if (helper->notify_idle_id != 0)
g_source_remove (helper->notify_idle_id);
@@ -187,6 +207,145 @@ xfce_xsettings_helper_finalize (GObject *object)
static gboolean
+xfce_xsettings_helper_fc_notify (gpointer data)
+{
+ XfceXSettingsHelper *helper = XFCE_XSETTINGS_HELPER (data);
+ XfceXSetting *setting;
+
+ helper->fc_notify_timeout_id = 0;
+
+ /* check if the font config setup changed */
+ if (!FcConfigUptoDate (NULL) && FcInitReinitialize ())
+ {
+ /* stop the monitors */
+ xfce_xsettings_helper_fc_free (helper);
+
+ setting = g_hash_table_lookup (helper->settings, FC_PROPERTY);
+ if (setting == NULL)
+ {
+ /* create new setting */
+ setting = g_slice_new0 (XfceXSetting);
+ setting->value = g_new0 (GValue, 1);
+ g_value_init (setting->value, G_TYPE_INT);
+ g_hash_table_insert (helper->settings, g_strdup (FC_PROPERTY), setting);
+ }
+
+ /* update setting */
+ setting->last_change_serial = helper->serial;
+ g_value_set_int (setting->value, time (NULL));
+
+ /* schedule xsettings update */
+ if (helper->notify_idle_id == 0)
+ helper->notify_idle_id = g_idle_add (xfce_xsettings_helper_notify_idle, helper);
+
+ /* restart monitoring */
+ helper->fc_init_id = g_idle_add (xfce_xsettings_helper_fc_init, helper);
+ }
+
+ return FALSE;
+}
+
+
+
+static void
+xfce_xsettings_helper_fc_changed (XfceXSettingsHelper *helper)
+{
+ /* reschedule monitor */
+ if (helper->fc_notify_timeout_id != 0)
+ g_source_remove (helper->fc_notify_timeout_id);
+
+ helper->fc_notify_timeout_id = g_timeout_add_seconds (FC_TIMEOUT_SEC,
+ xfce_xsettings_helper_fc_notify, helper);
+}
+
+
+
+static void
+xfce_xsettings_helper_fc_free (XfceXSettingsHelper *helper)
+{
+ if (helper->fc_notify_timeout_id != 0)
+ {
+ /* stop update timeout */
+ g_source_remove (helper->fc_notify_timeout_id);
+ helper->fc_notify_timeout_id = 0;
+ }
+
+ if (helper->fc_init_id != 0)
+ {
+ /* stop startup timeout */
+ g_source_remove (helper->fc_init_id);
+ helper->fc_init_id = 0;
+ }
+
+ if (helper->fc_monitors != NULL)
+ {
+ /* remove monitors */
+ g_ptr_array_foreach (helper->fc_monitors, (GFunc) g_object_unref, NULL);
+ g_ptr_array_free (helper->fc_monitors, TRUE);
+ helper->fc_monitors = NULL;
+ }
+}
+
+
+
+static void
+xfce_xsettings_helper_fc_monitor (XfceXSettingsHelper *helper,
+ FcStrList *files)
+{
+ const gchar *path;
+ GFile *file;
+ GFileMonitor *monitor;
+
+ if (G_UNLIKELY (files == NULL))
+ return;
+
+ for (;;)
+ {
+ path = (const gchar *) FcStrListNext (files);
+ if (G_UNLIKELY (path == NULL))
+ break;
+
+ file = g_file_new_for_path (path);
+ monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_object_unref (G_OBJECT (file));
+
+ if (G_LIKELY (monitor != NULL))
+ {
+ g_ptr_array_add (helper->fc_monitors, monitor);
+ g_signal_connect_swapped (G_OBJECT (monitor), "changed",
+ G_CALLBACK (xfce_xsettings_helper_fc_changed), helper);
+ }
+ }
+
+ FcStrListDone (files);
+}
+
+
+
+static gboolean
+xfce_xsettings_helper_fc_init (gpointer data)
+{
+ XfceXSettingsHelper *helper = XFCE_XSETTINGS_HELPER (data);
+
+ g_return_val_if_fail (helper->fc_monitors == NULL, FALSE);
+
+ helper->fc_init_id = 0;
+
+ if (FcInit ())
+ {
+ helper->fc_monitors = g_ptr_array_new ();
+
+ /* start monitoring config files and font directories */
+ xfce_xsettings_helper_fc_monitor (helper, FcConfigGetConfigFiles (NULL));
+ xfce_xsettings_helper_fc_monitor (helper, FcConfigGetFontDirs (NULL));
+ }
+
+ return FALSE;
+}
+
+
+
+static gboolean
xfce_xsettings_helper_notify_idle (gpointer data)
{
XfceXSettingsHelper *helper = XFCE_XSETTINGS_HELPER (data);
@@ -960,6 +1119,9 @@ xfce_xsettings_helper_register (XfceXSettingsHelper *helper,
xfce_xsettings_helper_notify (helper);
xfce_xsettings_helper_notify_xft (helper);
+ /* startup fontconfig monitoring */
+ helper->fc_init_id = g_idle_add (xfce_xsettings_helper_fc_init, helper);
+
return TRUE;
}
More information about the Xfce4-commits
mailing list