]> code.delx.au - gnu-emacs/blobdiff - src/xsettings.c
Merge from origin/emacs-24
[gnu-emacs] / src / xsettings.c
index f48c49dbafe1ca3ed2b6ac7198f050cb0dc9e811..028487b91ee1a10305aab89f60dfbf8a9b01db59 100644 (file)
@@ -1,6 +1,6 @@
 /* Functions for handling font and other changes dynamically.
 
-Copyright (C) 2009-2013 Free Software Foundation, Inc.
+Copyright (C) 2009-2015 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -22,6 +22,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <float.h>
 #include <limits.h>
 #include <fcntl.h>
+
+#include <byteswap.h>
+
 #include "lisp.h"
 #include "xterm.h"
 #include "xsettings.h"
@@ -48,8 +51,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 static char *current_mono_font;
 static char *current_font;
 static struct x_display_info *first_dpyinfo;
-static Lisp_Object Qmonospace_font_name, Qfont_name, Qfont_render,
-  Qtool_bar_style;
 static Lisp_Object current_tool_bar_style;
 
 /* Store an config changed event in to the event queue.  */
@@ -65,11 +66,11 @@ store_config_changed_event (Lisp_Object arg, Lisp_Object display_name)
   kbd_buffer_store_event (&event);
 }
 
-/* Return non-zero if DPYINFO is still valid.  */
-static int
+/* Return true if DPYINFO is still valid.  */
+static bool
 dpyinfo_valid (struct x_display_info *dpyinfo)
 {
-  int found = 0;
+  bool found = false;
   if (dpyinfo != NULL)
     {
       struct x_display_info *d;
@@ -88,8 +89,7 @@ store_monospaced_changed (const char *newfont)
   if (current_mono_font != NULL && strcmp (newfont, current_mono_font) == 0)
     return; /* No change. */
 
-  xfree (current_mono_font);
-  current_mono_font = xstrdup (newfont);
+  dupstring (&current_mono_font, newfont);
 
   if (dpyinfo_valid (first_dpyinfo) && use_system_font)
     {
@@ -108,8 +108,7 @@ store_font_name_changed (const char *newfont)
   if (current_font != NULL && strcmp (newfont, current_font) == 0)
     return; /* No change. */
 
-  xfree (current_font);
-  current_font = xstrdup (newfont);
+  dupstring (&current_font, newfont);
 
   if (dpyinfo_valid (first_dpyinfo))
     {
@@ -170,7 +169,7 @@ enum {
   SEEN_HINTSTYLE  = 0x10,
   SEEN_DPI        = 0x20,
   SEEN_FONT       = 0x40,
-  SEEN_TB_STYLE   = 0x80,
+  SEEN_TB_STYLE   = 0x80
 };
 struct xsettings
 {
@@ -336,9 +335,6 @@ get_prop_window (struct x_display_info *dpyinfo)
   XUngrabServer (dpy);
 }
 
-#define SWAP32(nr) (((nr) << 24) | (((nr) << 8) & 0xff0000)     \
-                    | (((nr) >> 8) & 0xff00) | ((nr) >> 24))
-#define SWAP16(nr) (((nr) << 8) | ((nr) >> 8))
 #define PAD(nr)    (((nr) + 3) & ~3)
 
 /* Parse xsettings and extract those that deal with Xft.
@@ -393,7 +389,7 @@ get_prop_window (struct x_display_info *dpyinfo)
 
 static int
 parse_settings (unsigned char *prop,
-                long unsigned int bytes,
+                unsigned long bytes,
                 struct xsettings *settings)
 {
   Lisp_Object byteorder = Fbyteorder ();
@@ -406,9 +402,9 @@ parse_settings (unsigned char *prop,
 
   /* First 4 bytes is a serial number, skip that.  */
 
-  if (bytes < 12) return BadLength;
+  if (bytes < 12) return settings_seen;
   memcpy (&n_settings, prop+8, 4);
-  if (my_bo != that_bo) n_settings = SWAP32 (n_settings);
+  if (my_bo != that_bo) n_settings = bswap_32 (n_settings);
   bytes_parsed = 12;
 
   memset (settings, 0, sizeof (*settings));
@@ -421,7 +417,7 @@ parse_settings (unsigned char *prop,
       CARD32 vlen, ival = 0;
       char name[128]; /* The names we are looking for are not this long.  */
       char sval[128]; /* The values we are looking for are not this long.  */
-      int want_this;
+      bool want_this;
       int to_cpy;
 
       sval[0] = '\0';
@@ -430,9 +426,9 @@ parse_settings (unsigned char *prop,
 
       memcpy (&nlen, prop+bytes_parsed, 2);
       bytes_parsed += 2;
-      if (my_bo != that_bo) nlen = SWAP16 (nlen);
-      if (bytes_parsed+nlen > bytes) return BadLength;
-      to_cpy = nlen > 127 ? 127 : nlen;
+      if (my_bo != that_bo) nlen = bswap_16 (nlen);
+      if (bytes_parsed + nlen > bytes) return settings_seen;
+      to_cpy = min (nlen, sizeof name - 1);
       memcpy (name, prop+bytes_parsed, to_cpy);
       name[to_cpy] = '\0';
 
@@ -440,36 +436,35 @@ parse_settings (unsigned char *prop,
       bytes_parsed = PAD (bytes_parsed);
 
       bytes_parsed += 4; /* Skip serial for this value */
-      if (bytes_parsed > bytes) return BadLength;
+      if (bytes_parsed > bytes) return settings_seen;
 
-      want_this =
+      want_this = strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0;
 #ifdef HAVE_XFT
-        (nlen > 6 && strncmp (name, "Xft/", 4) == 0)
-        || strcmp (XSETTINGS_FONT_NAME, name) == 0
-        ||
+      if ((nlen > 6 && memcmp (name, "Xft/", 4) == 0)
+         || strcmp (XSETTINGS_FONT_NAME, name) == 0)
+       want_this = true;
 #endif
-        strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0;
 
       switch (type)
         {
         case 0: /* Integer */
-          if (bytes_parsed+4 > bytes) return BadLength;
+          if (bytes_parsed + 4 > bytes) return settings_seen;
           if (want_this)
             {
               memcpy (&ival, prop+bytes_parsed, 4);
-              if (my_bo != that_bo) ival = SWAP32 (ival);
+              if (my_bo != that_bo) ival = bswap_32 (ival);
             }
           bytes_parsed += 4;
           break;
 
         case 1: /* String */
-          if (bytes_parsed+4 > bytes) return BadLength;
+          if (bytes_parsed + 4 > bytes) return settings_seen;
           memcpy (&vlen, prop+bytes_parsed, 4);
           bytes_parsed += 4;
-          if (my_bo != that_bo) vlen = SWAP32 (vlen);
+          if (my_bo != that_bo) vlen = bswap_32 (vlen);
           if (want_this)
             {
-              to_cpy = vlen > 127 ? 127 : vlen;
+              to_cpy = min (vlen, sizeof sval - 1);
               memcpy (sval, prop+bytes_parsed, to_cpy);
               sval[to_cpy] = '\0';
             }
@@ -479,26 +474,25 @@ parse_settings (unsigned char *prop,
 
         case 2: /* RGB value */
           /* No need to parse this */
-          if (bytes_parsed+8 > bytes) return BadLength;
+          if (bytes_parsed + 8 > bytes) return settings_seen;
           bytes_parsed += 8; /* 4 values (r, b, g, alpha), 2 bytes each.  */
           break;
 
         default: /* Parse Error */
-          return BadValue;
+          return settings_seen;
         }
 
       if (want_this)
         {
-          ++settings_seen;
           if (strcmp (name, XSETTINGS_TOOL_BAR_STYLE) == 0)
             {
-              settings->tb_style = xstrdup (sval);
+              dupstring (&settings->tb_style, sval);
               settings->seen |= SEEN_TB_STYLE;
             }
 #ifdef HAVE_XFT
           else if (strcmp (name, XSETTINGS_FONT_NAME) == 0)
             {
-              settings->font = xstrdup (sval);
+              dupstring (&settings->font, sval);
               settings->seen |= SEEN_FONT;
             }
           else if (strcmp (name, "Xft/Antialias") == 0)
@@ -559,6 +553,9 @@ parse_settings (unsigned char *prop,
                 settings->seen &= ~SEEN_LCDFILTER;
             }
 #endif /* HAVE_XFT */
+         else
+           want_this = false;
+         settings_seen += want_this;
         }
     }
 
@@ -567,9 +564,9 @@ parse_settings (unsigned char *prop,
 
 /* Read settings from the XSettings property window on display for DPYINFO.
    Store settings read in SETTINGS.
-   Return non-zero if successful, zero if not.  */
+   Return true iff successful.  */
 
-static int
+static bool
 read_settings (struct x_display_info *dpyinfo, struct xsettings *settings)
 {
   Atom act_type;
@@ -578,6 +575,7 @@ read_settings (struct x_display_info *dpyinfo, struct xsettings *settings)
   unsigned char *prop = NULL;
   Display *dpy = dpyinfo->display;
   int rc;
+  bool got_settings = false;
 
   x_catch_errors (dpy);
   rc = XGetWindowProperty (dpy,
@@ -589,27 +587,26 @@ read_settings (struct x_display_info *dpyinfo, struct xsettings *settings)
 
   if (rc == Success && prop != NULL && act_form == 8 && nitems > 0
       && act_type == dpyinfo->Xatom_xsettings_prop)
-    rc = parse_settings (prop, nitems, settings);
+    got_settings = parse_settings (prop, nitems, settings) != 0;
 
   XFree (prop);
 
   x_uncatch_errors ();
 
-  return rc != 0;
+  return got_settings;
 }
 
 /* Apply Xft settings in SETTINGS to the Xft library.
-   If SEND_EVENT_P is non-zero store a Lisp event that Xft settings changed.  */
+   Store a Lisp event that Xft settings changed.  */
 
 static void
 apply_xft_settings (struct x_display_info *dpyinfo,
-                    int send_event_p,
                     struct xsettings *settings)
 {
 #ifdef HAVE_XFT
   FcPattern *pat;
   struct xsettings oldsettings;
-  int changed = 0;
+  bool changed = false;
 
   memset (&oldsettings, 0, sizeof (oldsettings));
   pat = FcPatternCreate ();
@@ -629,7 +626,7 @@ apply_xft_settings (struct x_display_info *dpyinfo,
     {
       FcPatternDel (pat, FC_ANTIALIAS);
       FcPatternAddBool (pat, FC_ANTIALIAS, settings->aa);
-      ++changed;
+      changed = true;
       oldsettings.aa = settings->aa;
     }
 
@@ -638,7 +635,7 @@ apply_xft_settings (struct x_display_info *dpyinfo,
     {
       FcPatternDel (pat, FC_HINTING);
       FcPatternAddBool (pat, FC_HINTING, settings->hinting);
-      ++changed;
+      changed = true;
       oldsettings.hinting = settings->hinting;
     }
   if ((settings->seen & SEEN_RGBA) != 0 && oldsettings.rgba != settings->rgba)
@@ -646,7 +643,7 @@ apply_xft_settings (struct x_display_info *dpyinfo,
       FcPatternDel (pat, FC_RGBA);
       FcPatternAddInteger (pat, FC_RGBA, settings->rgba);
       oldsettings.rgba = settings->rgba;
-      ++changed;
+      changed = true;
     }
 
   /* Older fontconfig versions don't have FC_LCD_FILTER. */
@@ -655,7 +652,7 @@ apply_xft_settings (struct x_display_info *dpyinfo,
     {
       FcPatternDel (pat, FC_LCD_FILTER);
       FcPatternAddInteger (pat, FC_LCD_FILTER, settings->lcdfilter);
-      ++changed;
+      changed = true;
       oldsettings.lcdfilter = settings->lcdfilter;
     }
 
@@ -665,7 +662,7 @@ apply_xft_settings (struct x_display_info *dpyinfo,
     {
       FcPatternDel (pat, FC_HINT_STYLE);
       FcPatternAddInteger (pat, FC_HINT_STYLE, settings->hintstyle);
-      ++changed;
+      changed = true;
       oldsettings.hintstyle = settings->hintstyle;
     }
 #endif
@@ -675,7 +672,7 @@ apply_xft_settings (struct x_display_info *dpyinfo,
     {
       FcPatternDel (pat, FC_DPI);
       FcPatternAddDouble (pat, FC_DPI, settings->dpi);
-      ++changed;
+      changed = true;
       oldsettings.dpi = settings->dpi;
 
       /* Changing the DPI on this display affects all frames on it.
@@ -687,7 +684,7 @@ apply_xft_settings (struct x_display_info *dpyinfo,
     {
       static char const format[] =
        "Antialias: %d, Hinting: %d, RGBA: %d, LCDFilter: %d, "
-       "Hintstyle: %d, DPI: %lf";
+       "Hintstyle: %d, DPI: %f";
       enum
       {
        d_formats = 5,
@@ -696,14 +693,13 @@ apply_xft_settings (struct x_display_info *dpyinfo,
        max_f_integer_digits = DBL_MAX_10_EXP + 1,
        f_precision = 6,
        lf_growth = (sizeof "-." + max_f_integer_digits + f_precision
-                    - sizeof "%lf")
+                    - sizeof "%f")
       };
       char buf[sizeof format + d_formats * d_growth + lf_formats * lf_growth];
 
       XftDefaultSet (dpyinfo->display, pat);
-      if (send_event_p)
-        store_config_changed_event (Qfont_render,
-                                    XCAR (dpyinfo->name_list_element));
+      store_config_changed_event (Qfont_render,
+                                 XCAR (dpyinfo->name_list_element));
       Vxft_settings
        = make_formatted_string (buf, format,
                                 oldsettings.aa, oldsettings.hinting,
@@ -717,17 +713,17 @@ apply_xft_settings (struct x_display_info *dpyinfo,
 }
 
 /* Read XSettings from the display for DPYINFO.
-   If SEND_EVENT_P is non-zero store a Lisp event settings that changed.  */
+   If SEND_EVENT_P store a Lisp event settings that changed.  */
 
 static void
-read_and_apply_settings (struct x_display_info *dpyinfo, int send_event_p)
+read_and_apply_settings (struct x_display_info *dpyinfo, bool send_event_p)
 {
   struct xsettings settings;
 
   if (!read_settings (dpyinfo, &settings))
     return;
 
-  apply_xft_settings (dpyinfo, True, &settings);
+  apply_xft_settings (dpyinfo, &settings);
   if (settings.seen & SEEN_TB_STYLE)
     {
       if (send_event_p)
@@ -742,10 +738,7 @@ read_and_apply_settings (struct x_display_info *dpyinfo, int send_event_p)
       if (send_event_p)
         store_font_name_changed (settings.font);
       else
-        {
-          xfree (current_font);
-          current_font = xstrdup (settings.font);
-        }
+       dupstring (&current_font, settings.font);
       xfree (settings.font);
     }
 #endif
@@ -754,30 +747,29 @@ read_and_apply_settings (struct x_display_info *dpyinfo, int send_event_p)
 /* Check if EVENT for the display in DPYINFO is XSettings related.  */
 
 void
-xft_settings_event (struct x_display_info *dpyinfo, XEvent *event)
+xft_settings_event (struct x_display_info *dpyinfo, const XEvent *event)
 {
-  int check_window_p = 0;
-  int apply_settings = 0;
+  bool check_window_p = false, apply_settings_p = false;
 
   switch (event->type)
     {
     case DestroyNotify:
       if (dpyinfo->xsettings_window == event->xany.window)
-        check_window_p = 1;
+        check_window_p = true;
       break;
 
     case ClientMessage:
       if (event->xclient.message_type == dpyinfo->Xatom_xsettings_mgr
           && event->xclient.data.l[1] == dpyinfo->Xatom_xsettings_sel
           && event->xclient.window == dpyinfo->root_window)
-        check_window_p = 1;
+        check_window_p = true;
       break;
 
     case PropertyNotify:
       if (event->xproperty.window == dpyinfo->xsettings_window
           && event->xproperty.state == PropertyNewValue
           && event->xproperty.atom == dpyinfo->Xatom_xsettings_prop)
-        apply_settings = 1;
+        apply_settings_p = true;
       break;
     }
 
@@ -787,11 +779,11 @@ xft_settings_event (struct x_display_info *dpyinfo, XEvent *event)
       dpyinfo->xsettings_window = None;
       get_prop_window (dpyinfo);
       if (dpyinfo->xsettings_window != None)
-        apply_settings = 1;
+        apply_settings_p = true;
     }
 
-  if (apply_settings)
-    read_and_apply_settings (dpyinfo, True);
+  if (apply_settings_p)
+    read_and_apply_settings (dpyinfo, true);
 }
 
 /* Initialize GSettings and read startup values.  */
@@ -801,17 +793,29 @@ init_gsettings (void)
 {
 #ifdef HAVE_GSETTINGS
   GVariant *val;
-  const gchar *const *schemas;
-  int schema_found = 0;
+  bool schema_found = false;
 
-#ifdef HAVE_G_TYPE_INIT
+#if ! GLIB_CHECK_VERSION (2, 36, 0)
   g_type_init ();
 #endif
 
-  schemas = g_settings_list_schemas ();
-  if (schemas == NULL) return;
-  while (! schema_found && *schemas != NULL)
-    schema_found = strcmp (*schemas++, GSETTINGS_SCHEMA) == 0;
+#if GLIB_CHECK_VERSION (2, 32, 0)
+  {
+    GSettingsSchema *sc = g_settings_schema_source_lookup
+      (g_settings_schema_source_get_default (),
+       GSETTINGS_SCHEMA,
+       true);
+    schema_found = sc != NULL;
+    if (sc) g_settings_schema_unref (sc);
+  }
+#else
+  {
+    const gchar *const *schemas = g_settings_list_schemas ();
+    if (schemas == NULL) return;
+    while (! schema_found && *schemas != NULL)
+      schema_found = strcmp (*schemas++, GSETTINGS_SCHEMA) == 0;
+  }
+#endif
   if (!schema_found) return;
 
   gsettings_client = g_settings_new (GSETTINGS_SCHEMA);
@@ -836,7 +840,7 @@ init_gsettings (void)
     {
       g_variant_ref_sink (val);
       if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
-        current_mono_font = xstrdup (g_variant_get_string (val, NULL));
+       dupstring (&current_mono_font, g_variant_get_string (val, NULL));
       g_variant_unref (val);
     }
 
@@ -845,7 +849,7 @@ init_gsettings (void)
     {
       g_variant_ref_sink (val);
       if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
-        current_font = xstrdup (g_variant_get_string (val, NULL));
+        dupstring (&current_font, g_variant_get_string (val, NULL));
       g_variant_unref (val);
     }
 #endif /* HAVE_XFT */
@@ -861,7 +865,7 @@ init_gconf (void)
 #if defined (HAVE_GCONF)
   char *s;
 
-#ifdef HAVE_G_TYPE_INIT
+#if ! GLIB_CHECK_VERSION (2, 36, 0)
   g_type_init ();
 #endif
 
@@ -887,13 +891,13 @@ init_gconf (void)
   s = gconf_client_get_string (gconf_client, GCONF_MONO_FONT, NULL);
   if (s)
     {
-      current_mono_font = xstrdup (s);
+      dupstring (&current_mono_font, s);
       g_free (s);
     }
   s = gconf_client_get_string (gconf_client, GCONF_FONT_NAME, NULL);
   if (s)
     {
-      current_font = xstrdup (s);
+      dupstring (&current_font, s);
       g_free (s);
     }
   gconf_client_add_dir (gconf_client,
@@ -931,7 +935,7 @@ init_xsettings (struct x_display_info *dpyinfo)
 
   get_prop_window (dpyinfo);
   if (dpyinfo->xsettings_window != None)
-    read_and_apply_settings (dpyinfo, False);
+    read_and_apply_settings (dpyinfo, false);
 
   unblock_input ();
 }
@@ -1024,7 +1028,7 @@ syms_of_xsettings (void)
 When this is non-nil and the system defined fixed width font changes, we
 update frames dynamically.
 If this variable is nil, Emacs ignores system font changes.  */);
-  use_system_font = 0;
+  use_system_font = false;
 
   DEFVAR_LISP ("xft-settings", Vxft_settings,
                doc: /* Font settings applied to Xft.  */);