]> code.delx.au - gnu-emacs/blobdiff - src/xsettings.c
Ibuffer change marks
[gnu-emacs] / src / xsettings.c
index 458c3d45e9aa0fcbf493c0cb83305950bfc7f20a..d7af68f1c5f58d712b7f4f421f318a2b705e5f47 100644 (file)
@@ -1,13 +1,13 @@
 /* Functions for handling font and other changes dynamically.
 
-Copyright (C) 2009-2014 Free Software Foundation, Inc.
+Copyright (C) 2009-2016 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs 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 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -51,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.  */
@@ -68,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;
@@ -91,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)
     {
@@ -111,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))
     {
@@ -406,7 +402,7 @@ 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 = bswap_32 (n_settings);
   bytes_parsed = 12;
@@ -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';
@@ -431,8 +427,8 @@ parse_settings (unsigned char *prop,
       memcpy (&nlen, prop+bytes_parsed, 2);
       bytes_parsed += 2;
       if (my_bo != that_bo) nlen = bswap_16 (nlen);
-      if (bytes_parsed+nlen > bytes) return BadLength;
-      to_cpy = nlen > 127 ? 127 : 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,20 +436,19 @@ 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);
@@ -463,13 +458,13 @@ parse_settings (unsigned char *prop,
           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 = 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)
@@ -543,10 +537,10 @@ parse_settings (unsigned char *prop,
               else
                 settings->seen &= ~SEEN_RGBA;
             }
-          else if (strcmp (name, "Xft/DPI") == 0)
+          else if (strcmp (name, "Xft/DPI") == 0 && ival != (CARD32) -1)
             {
               settings->seen |= SEEN_DPI;
-              settings->dpi = (double)ival/1024.0;
+              settings->dpi = ival / 1024.0;
             }
           else if (strcmp (name, "Xft/lcdfilter") == 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.
@@ -701,9 +698,8 @@ apply_xft_settings (struct x_display_info *dpyinfo,
       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
@@ -756,27 +749,27 @@ read_and_apply_settings (struct x_display_info *dpyinfo, int send_event_p)
 void
 xft_settings_event (struct x_display_info *dpyinfo, const XEvent *event)
 {
-  bool check_window_p = 0, apply_settings_p = 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_p = 1;
+        apply_settings_p = true;
       break;
     }
 
@@ -786,11 +779,11 @@ xft_settings_event (struct x_display_info *dpyinfo, const XEvent *event)
       dpyinfo->xsettings_window = None;
       get_prop_window (dpyinfo);
       if (dpyinfo->xsettings_window != None)
-        apply_settings_p = 1;
+        apply_settings_p = true;
     }
 
   if (apply_settings_p)
-    read_and_apply_settings (dpyinfo, True);
+    read_and_apply_settings (dpyinfo, true);
 }
 
 /* Initialize GSettings and read startup values.  */
@@ -800,17 +793,29 @@ init_gsettings (void)
 {
 #ifdef HAVE_GSETTINGS
   GVariant *val;
-  const gchar *const *schemas;
-  int schema_found = 0;
+  bool schema_found = false;
 
 #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);
@@ -835,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);
     }
 
@@ -844,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 */
@@ -886,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,
@@ -930,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 ();
 }
@@ -1023,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.  */);