[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