root/src/xsettings.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. store_config_changed_event
  2. dpyinfo_valid
  3. store_monospaced_changed
  4. store_font_name_changed
  5. map_tool_bar_style
  6. store_tool_bar_style_changed
  7. xg_settings_key_valid_p
  8. store_font_options_changed
  9. apply_gsettings_font_hinting
  10. apply_gsettings_font_antialias
  11. apply_gsettings_font_rgba_order
  12. something_changed_gsettingsCB
  13. something_changed_gconfCB
  14. get_prop_window
  15. parse_settings
  16. read_settings
  17. apply_xft_settings
  18. read_and_apply_settings
  19. xft_settings_event
  20. init_gsettings
  21. init_gconf
  22. init_xsettings
  23. xsettings_initialize
  24. xsettings_get_system_font
  25. xsettings_get_system_normal_font
  26. xsettings_get_font_options
  27. DEFUN
  28. DEFUN
  29. DEFUN
  30. syms_of_xsettings

     1 /* Functions for handling font and other changes dynamically.
     2 
     3 Copyright (C) 2009-2023 Free Software Foundation, Inc.
     4 
     5 This file is part of GNU Emacs.
     6 
     7 GNU Emacs is free software: you can redistribute it and/or modify
     8 it under the terms of the GNU General Public License as published by
     9 the Free Software Foundation, either version 3 of the License, or (at
    10 your option) any later version.
    11 
    12 GNU Emacs is distributed in the hope that it will be useful,
    13 but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 GNU General Public License for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    19 
    20 #include <config.h>
    21 
    22 #include <float.h>
    23 #include <limits.h>
    24 #include <fcntl.h>
    25 
    26 #include <byteswap.h>
    27 
    28 #include "lisp.h"
    29 #ifndef HAVE_PGTK
    30 #include "xterm.h"
    31 #else
    32 #include "gtkutil.h"
    33 #endif
    34 #include "xsettings.h"
    35 #include "frame.h"
    36 #include "keyboard.h"
    37 #include "blockinput.h"
    38 #include "termhooks.h"
    39 #include "pdumper.h"
    40 
    41 #ifndef HAVE_PGTK
    42 #include <X11/Xproto.h>
    43 #else
    44 typedef unsigned short CARD16;
    45 typedef unsigned int CARD32;
    46 #endif
    47 
    48 #ifdef HAVE_GSETTINGS
    49 #include <glib-object.h>
    50 #include <gio/gio.h>
    51 #endif
    52 
    53 #ifdef HAVE_GCONF
    54 #include <gconf/gconf-client.h>
    55 #endif
    56 
    57 #ifdef USE_CAIRO
    58 #include <fontconfig/fontconfig.h>
    59 #include "ftfont.h"
    60 #elif defined HAVE_XFT
    61 #include <X11/Xft/Xft.h>
    62 #endif
    63 
    64 #if defined USE_CAIRO && defined CAIRO_HAS_FT_FONT
    65 #include <cairo/cairo-ft.h>
    66 #endif
    67 
    68 static char *current_mono_font;
    69 static char *current_font;
    70 static Display_Info *first_dpyinfo;
    71 static Lisp_Object current_tool_bar_style;
    72 
    73 /* Store a config changed event in to the event queue.  */
    74 
    75 static void
    76 store_config_changed_event (Lisp_Object arg, Lisp_Object display_name)
    77 {
    78   struct input_event event;
    79   EVENT_INIT (event);
    80   event.kind = CONFIG_CHANGED_EVENT;
    81   event.frame_or_window = display_name;
    82   event.arg = arg;
    83   kbd_buffer_store_event (&event);
    84 }
    85 
    86 /* Return true if DPYINFO is still valid.  */
    87 static bool
    88 dpyinfo_valid (Display_Info *dpyinfo)
    89 {
    90   bool found = false;
    91   if (dpyinfo != NULL)
    92     {
    93       Display_Info *d;
    94       for (d = x_display_list; !found && d; d = d->next)
    95 #ifndef HAVE_PGTK
    96         found = d == dpyinfo && d->display == dpyinfo->display;
    97 #else
    98         found = d == dpyinfo && d->gdpy == dpyinfo->gdpy;
    99 #endif
   100     }
   101   return found;
   102 }
   103 
   104 /* Store a monospace font change event if the monospaced font changed.  */
   105 
   106 #if (defined USE_CAIRO || defined HAVE_XFT) && (defined HAVE_GSETTINGS || defined HAVE_GCONF)
   107 static void
   108 store_monospaced_changed (const char *newfont)
   109 {
   110   if (current_mono_font != NULL && strcmp (newfont, current_mono_font) == 0)
   111     return; /* No change. */
   112 
   113   dupstring (&current_mono_font, newfont);
   114 
   115   if (dpyinfo_valid (first_dpyinfo) && use_system_font)
   116     {
   117       store_config_changed_event (Qmonospace_font_name,
   118                                   XCAR (first_dpyinfo->name_list_element));
   119     }
   120 }
   121 #endif
   122 
   123 /* Store a font name change event if the font name changed.  */
   124 
   125 #if defined USE_CAIRO || defined HAVE_XFT
   126 static void
   127 store_font_name_changed (const char *newfont)
   128 {
   129   if (current_font != NULL && strcmp (newfont, current_font) == 0)
   130     return; /* No change. */
   131 
   132   dupstring (&current_font, newfont);
   133 
   134   if (dpyinfo_valid (first_dpyinfo))
   135     {
   136       store_config_changed_event (Qfont_name,
   137                                   XCAR (first_dpyinfo->name_list_element));
   138     }
   139 }
   140 #endif /* USE_CAIRO || HAVE_XFT */
   141 
   142 /* Map TOOL_BAR_STYLE from a string to its corresponding Lisp value.
   143    Return Qnil if TOOL_BAR_STYLE is not known.  */
   144 
   145 static Lisp_Object
   146 map_tool_bar_style (const char *tool_bar_style)
   147 {
   148   Lisp_Object style = Qnil;
   149   if (tool_bar_style)
   150     {
   151       if (strcmp (tool_bar_style, "both") == 0)
   152         style = Qboth;
   153       else if (strcmp (tool_bar_style, "both-horiz") == 0)
   154         style = Qboth_horiz;
   155       else if (strcmp (tool_bar_style, "icons") == 0)
   156         style = Qimage;
   157       else if (strcmp (tool_bar_style, "text") == 0)
   158         style = Qtext;
   159     }
   160 
   161   return style;
   162 }
   163 
   164 /* Store a tool bar style change event if the tool bar style changed.  */
   165 
   166 static void
   167 store_tool_bar_style_changed (const char *newstyle,
   168                               Display_Info *dpyinfo)
   169 {
   170   Lisp_Object style = map_tool_bar_style (newstyle);
   171   if (EQ (current_tool_bar_style, style))
   172     return; /* No change. */
   173 
   174   current_tool_bar_style = style;
   175   if (dpyinfo_valid (dpyinfo))
   176     store_config_changed_event (Qtool_bar_style,
   177                                 XCAR (dpyinfo->name_list_element));
   178 }
   179 
   180 #ifndef HAVE_PGTK
   181 #if defined USE_CAIRO || defined HAVE_XFT
   182 #define XSETTINGS_FONT_NAME       "Gtk/FontName"
   183 #endif
   184 #define XSETTINGS_TOOL_BAR_STYLE  "Gtk/ToolbarStyle"
   185 #endif
   186 
   187 enum {
   188   SEEN_AA         = 0x01,
   189   SEEN_HINTING    = 0x02,
   190   SEEN_RGBA       = 0x04,
   191   SEEN_LCDFILTER  = 0x08,
   192   SEEN_HINTSTYLE  = 0x10,
   193   SEEN_DPI        = 0x20,
   194   SEEN_FONT       = 0x40,
   195   SEEN_TB_STYLE   = 0x80
   196 };
   197 struct xsettings
   198 {
   199 #if defined USE_CAIRO || defined HAVE_XFT
   200   FcBool aa, hinting;
   201   int rgba, lcdfilter, hintstyle;
   202   double dpi;
   203 
   204   char *font;
   205 #endif
   206 
   207   char *tb_style;
   208 
   209   unsigned seen;
   210 };
   211 
   212 #ifdef HAVE_PGTK
   213 /* The cairo font_options as obtained using gsettings.  */
   214 static cairo_font_options_t *font_options;
   215 #endif
   216 
   217 #ifdef HAVE_GSETTINGS
   218 #define GSETTINGS_SCHEMA         "org.gnome.desktop.interface"
   219 #define GSETTINGS_TOOL_BAR_STYLE "toolbar-style"
   220 
   221 #if defined USE_CAIRO || defined HAVE_XFT
   222 #define GSETTINGS_MONO_FONT  "monospace-font-name"
   223 #define GSETTINGS_FONT_NAME  "font-name"
   224 #endif
   225 
   226 #ifdef HAVE_PGTK
   227 #define GSETTINGS_FONT_ANTIALIASING  "font-antialiasing"
   228 #define GSETTINGS_FONT_RGBA_ORDER    "font-rgba-order"
   229 #define GSETTINGS_FONT_HINTING       "font-hinting"
   230 #endif
   231 
   232 /* The single GSettings instance, or NULL if not connected to GSettings.  */
   233 
   234 static GSettings *gsettings_client;
   235 
   236 #if defined HAVE_PGTK && defined HAVE_GSETTINGS
   237 
   238 static bool
   239 xg_settings_key_valid_p (GSettings *settings, const char *key)
   240 {
   241 #ifdef GLIB_VERSION_2_32
   242   GSettingsSchema *schema;
   243   bool rc;
   244 
   245   g_object_get (G_OBJECT (settings),
   246                 "settings-schema", &schema,
   247                 NULL);
   248 
   249   if (!schema)
   250     return false;
   251 
   252   rc = g_settings_schema_has_key (schema, key);
   253   g_settings_schema_unref (schema);
   254 
   255   return rc;
   256 #else
   257   return false;
   258 #endif
   259 }
   260 
   261 #endif
   262 
   263 #ifdef HAVE_PGTK
   264 /* Store an event for re-rendering of the fonts.  */
   265 static void
   266 store_font_options_changed (void)
   267 {
   268   if (dpyinfo_valid (first_dpyinfo))
   269     store_config_changed_event (Qfont_render,
   270                                 XCAR (first_dpyinfo->name_list_element));
   271 }
   272 
   273 /* Apply changes in the hinting system setting.  */
   274 static void
   275 apply_gsettings_font_hinting (GSettings *settings)
   276 {
   277   GVariant *val;
   278   const char *hinting;
   279 
   280   if (!xg_settings_key_valid_p (settings, GSETTINGS_FONT_HINTING))
   281     return;
   282 
   283   val = g_settings_get_value (settings, GSETTINGS_FONT_HINTING);
   284 
   285   if (val)
   286     {
   287       g_variant_ref_sink (val);
   288 
   289       if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
   290         {
   291           hinting = g_variant_get_string (val, NULL);
   292 
   293           if (!strcmp (hinting, "full"))
   294             cairo_font_options_set_hint_style (font_options,
   295                                                CAIRO_HINT_STYLE_FULL);
   296           else if (!strcmp (hinting, "medium"))
   297             cairo_font_options_set_hint_style (font_options,
   298                                                CAIRO_HINT_STYLE_MEDIUM);
   299           else if (!strcmp (hinting, "slight"))
   300             cairo_font_options_set_hint_style (font_options,
   301                                                CAIRO_HINT_STYLE_SLIGHT);
   302           else if (!strcmp (hinting, "none"))
   303             cairo_font_options_set_hint_style (font_options,
   304                                                CAIRO_HINT_STYLE_NONE);
   305         }
   306       g_variant_unref (val);
   307     }
   308 }
   309 
   310 /* Apply changes in the antialiasing system setting.  */
   311 static void
   312 apply_gsettings_font_antialias (GSettings *settings)
   313 {
   314   GVariant *val;
   315   const char *antialias;
   316 
   317   if (!xg_settings_key_valid_p (settings, GSETTINGS_FONT_ANTIALIASING))
   318     return;
   319 
   320   val = g_settings_get_value (settings, GSETTINGS_FONT_ANTIALIASING);
   321 
   322   if (val)
   323     {
   324       g_variant_ref_sink (val);
   325       if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
   326         {
   327           antialias = g_variant_get_string (val, NULL);
   328 
   329           if (!strcmp (antialias, "none"))
   330             cairo_font_options_set_antialias (font_options,
   331                                               CAIRO_ANTIALIAS_NONE);
   332           else if (!strcmp (antialias, "grayscale"))
   333             cairo_font_options_set_antialias (font_options,
   334                                               CAIRO_ANTIALIAS_GRAY);
   335           else if (!strcmp (antialias, "rgba"))
   336             cairo_font_options_set_antialias (font_options,
   337                                               CAIRO_ANTIALIAS_SUBPIXEL);
   338         }
   339       g_variant_unref (val);
   340     }
   341 }
   342 
   343 /* Apply the settings for the rgb element ordering.  */
   344 static void
   345 apply_gsettings_font_rgba_order (GSettings *settings)
   346 {
   347   GVariant *val;
   348   const char *rgba_order;
   349 
   350   if (!xg_settings_key_valid_p (settings, GSETTINGS_FONT_RGBA_ORDER))
   351     return;
   352 
   353   val = g_settings_get_value (settings,
   354                               GSETTINGS_FONT_RGBA_ORDER);
   355 
   356   if (val)
   357     {
   358       g_variant_ref_sink (val);
   359 
   360       if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
   361         {
   362           rgba_order = g_variant_get_string (val, NULL);
   363 
   364           if (!strcmp (rgba_order, "rgb"))
   365             cairo_font_options_set_subpixel_order (font_options,
   366                                                    CAIRO_SUBPIXEL_ORDER_RGB);
   367           else if (!strcmp (rgba_order, "bgr"))
   368             cairo_font_options_set_subpixel_order (font_options,
   369                                                    CAIRO_SUBPIXEL_ORDER_BGR);
   370           else if (!strcmp (rgba_order, "vrgb"))
   371             cairo_font_options_set_subpixel_order (font_options,
   372                                                    CAIRO_SUBPIXEL_ORDER_VRGB);
   373           else if (!strcmp (rgba_order, "vbgr"))
   374             cairo_font_options_set_subpixel_order (font_options,
   375                                                    CAIRO_SUBPIXEL_ORDER_VBGR);
   376         }
   377       g_variant_unref (val);
   378     }
   379 }
   380 #endif /* HAVE_PGTK */
   381 
   382 /* Callback called when something changed in GSettings.  */
   383 
   384 static void
   385 something_changed_gsettingsCB (GSettings *settings,
   386                                gchar *key,
   387                                gpointer user_data)
   388 {
   389   GVariant *val;
   390 
   391   if (strcmp (key, GSETTINGS_TOOL_BAR_STYLE) == 0)
   392     {
   393       val = g_settings_get_value (settings, GSETTINGS_TOOL_BAR_STYLE);
   394       if (val)
   395         {
   396           g_variant_ref_sink (val);
   397           if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
   398             {
   399               const gchar *newstyle = g_variant_get_string (val, NULL);
   400               store_tool_bar_style_changed (newstyle, first_dpyinfo);
   401             }
   402           g_variant_unref (val);
   403         }
   404     }
   405 #if defined USE_CAIRO || defined HAVE_XFT
   406   else if (strcmp (key, GSETTINGS_MONO_FONT) == 0)
   407     {
   408       val = g_settings_get_value (settings, GSETTINGS_MONO_FONT);
   409       if (val)
   410         {
   411           g_variant_ref_sink (val);
   412           if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
   413             {
   414               const gchar *newfont = g_variant_get_string (val, NULL);
   415               store_monospaced_changed (newfont);
   416             }
   417           g_variant_unref (val);
   418         }
   419     }
   420   else if (strcmp (key, GSETTINGS_FONT_NAME) == 0)
   421     {
   422       val = g_settings_get_value (settings, GSETTINGS_FONT_NAME);
   423       if (val)
   424         {
   425           g_variant_ref_sink (val);
   426           if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
   427             {
   428               const gchar *newfont = g_variant_get_string (val, NULL);
   429               store_font_name_changed (newfont);
   430             }
   431           g_variant_unref (val);
   432         }
   433     }
   434 #endif /* USE_CAIRO || HAVE_XFT */
   435 #ifdef HAVE_PGTK
   436   else if (!strcmp (key, GSETTINGS_FONT_ANTIALIASING))
   437     {
   438       apply_gsettings_font_antialias (settings);
   439       store_font_options_changed ();
   440     }
   441   else if (!strcmp (key, GSETTINGS_FONT_HINTING))
   442     {
   443       apply_gsettings_font_hinting (settings);
   444       store_font_options_changed ();
   445     }
   446   else if (!strcmp (key, GSETTINGS_FONT_RGBA_ORDER))
   447     {
   448       apply_gsettings_font_rgba_order (settings);
   449       store_font_options_changed ();
   450     }
   451 #endif /* HAVE_PGTK */
   452 }
   453 
   454 #endif /* HAVE_GSETTINGS */
   455 
   456 #ifdef HAVE_GCONF
   457 #define GCONF_TOOL_BAR_STYLE "/desktop/gnome/interface/toolbar_style"
   458 #if defined USE_CAIRO || defined HAVE_XFT
   459 #define GCONF_MONO_FONT  "/desktop/gnome/interface/monospace_font_name"
   460 #define GCONF_FONT_NAME  "/desktop/gnome/interface/font_name"
   461 #endif
   462 
   463 /* The single GConf instance, or NULL if not connected to GConf.  */
   464 
   465 static GConfClient *gconf_client;
   466 
   467 /* Callback called when something changed in GConf that we care about.  */
   468 
   469 static void
   470 something_changed_gconfCB (GConfClient *client,
   471                            guint cnxn_id,
   472                            GConfEntry *entry,
   473                            gpointer user_data)
   474 {
   475   GConfValue *v = gconf_entry_get_value (entry);
   476   const char *key = gconf_entry_get_key (entry);
   477 
   478   if (!v || v->type != GCONF_VALUE_STRING || ! key) return;
   479   if (strcmp (key, GCONF_TOOL_BAR_STYLE) == 0)
   480     {
   481       const char *value = gconf_value_get_string (v);
   482       store_tool_bar_style_changed (value, first_dpyinfo);
   483     }
   484 #if defined USE_CAIRO || defined HAVE_XFT
   485   else if (strcmp (key, GCONF_MONO_FONT) == 0)
   486     {
   487       const char *value = gconf_value_get_string (v);
   488       store_monospaced_changed (value);
   489     }
   490   else if (strcmp (key, GCONF_FONT_NAME) == 0)
   491     {
   492       const char *value = gconf_value_get_string (v);
   493       store_font_name_changed (value);
   494     }
   495 #endif /* USE_CAIRO || HAVE_XFT */
   496 }
   497 
   498 #endif /* HAVE_GCONF */
   499 
   500 #if defined USE_CAIRO || defined HAVE_XFT
   501 
   502 /* Older fontconfig versions don't have FC_LCD_*.  */
   503 #ifndef FC_LCD_NONE
   504 #define FC_LCD_NONE 0
   505 #endif
   506 #ifndef FC_LCD_DEFAULT
   507 #define FC_LCD_DEFAULT 1
   508 #endif
   509 #ifndef FC_LCD_FILTER
   510 #define FC_LCD_FILTER "lcdfilter"
   511 #endif
   512 
   513 #endif /* USE_CAIRO || HAVE_XFT */
   514 
   515 #ifndef HAVE_PGTK
   516 /* Find the window that contains the XSETTINGS property values.  */
   517 
   518 static void
   519 get_prop_window (Display_Info *dpyinfo)
   520 {
   521   Display *dpy = dpyinfo->display;
   522 
   523   XGrabServer (dpy);
   524   dpyinfo->xsettings_window = XGetSelectionOwner (dpy,
   525                                                   dpyinfo->Xatom_xsettings_sel);
   526   if (dpyinfo->xsettings_window != None)
   527     /* Select events so we can detect if window is deleted or if settings
   528        are changed.  */
   529     XSelectInput (dpy, dpyinfo->xsettings_window,
   530                   PropertyChangeMask|StructureNotifyMask);
   531 
   532   XUngrabServer (dpy);
   533 }
   534 #endif
   535 
   536 #ifndef HAVE_PGTK
   537 
   538 #define PAD(nr)    (((nr) + 3) & ~3)
   539 
   540 /* Parse xsettings and extract those that deal with Xft.
   541    See https://freedesktop.org/wiki/Specifications/XSettingsRegistry/
   542    and https://specifications.freedesktop.org/xsettings-spec/xsettings-spec-0.5.html.
   543 
   544    Layout of prop.  First is a header:
   545 
   546    bytes   type     what
   547    ------------------------------------
   548    1      CARD8    byte-order
   549    3               unused
   550    4      CARD32   SERIAL
   551    4      CARD32   N_SETTINGS
   552 
   553    Then N_SETTINGS records, with header:
   554 
   555    bytes   type          what
   556    ------------------------------------
   557    1      SETTING_TYPE  type (0 = integer, 1 = string, 2 RGB color).
   558    1                    unused
   559    2      CARD16        n == name-length
   560    n      STRING8       name
   561    p                    unused, p=pad_to_even_4(n)
   562    4      CARD32        last-change-serial
   563 
   564    and then the value, For string:
   565 
   566    bytes   type          what
   567    ------------------------------------
   568    4      CARD32        n = value-length
   569    n      STRING8       value
   570    p                    unused, p=pad_to_even_4(n)
   571 
   572    For integer:
   573 
   574    bytes   type          what
   575    ------------------------------------
   576    4      INT32         value
   577 
   578    For RGB color:
   579 
   580    bytes   type          what
   581    ------------------------------------
   582    2      CARD16        red
   583    2      CARD16        blue
   584    2      CARD16        green
   585    2      CARD16        alpha
   586 
   587    Returns non-zero if some Xft settings was seen, zero otherwise.
   588 */
   589 
   590 static int
   591 parse_settings (unsigned char *prop,
   592                 unsigned long bytes,
   593                 struct xsettings *settings)
   594 {
   595   int int1 = 1;
   596   int my_bo = *(char *) &int1 == 1 ? LSBFirst : MSBFirst;
   597   int that_bo = prop[0];
   598   CARD32 n_settings;
   599   int bytes_parsed = 0;
   600   int settings_seen = 0;
   601   int i = 0;
   602 
   603   /* First 4 bytes is a serial number, skip that.  */
   604 
   605   if (bytes < 12) return settings_seen;
   606   memcpy (&n_settings, prop+8, 4);
   607   if (my_bo != that_bo) n_settings = bswap_32 (n_settings);
   608   bytes_parsed = 12;
   609 
   610   memset (settings, 0, sizeof (*settings));
   611 
   612   while (bytes_parsed+4 < bytes && settings_seen < 7
   613          && i < n_settings)
   614     {
   615       int type = prop[bytes_parsed++];
   616       CARD16 nlen;
   617       CARD32 vlen, ival = 0;
   618       char name[128]; /* The names we are looking for are not this long.  */
   619       char sval[128]; /* The values we are looking for are not this long.  */
   620       bool want_this;
   621       int to_cpy;
   622 
   623       sval[0] = '\0';
   624       ++i;
   625       ++bytes_parsed; /* Padding */
   626 
   627       memcpy (&nlen, prop+bytes_parsed, 2);
   628       bytes_parsed += 2;
   629       if (my_bo != that_bo) nlen = bswap_16 (nlen);
   630       if (bytes_parsed + nlen > bytes) return settings_seen;
   631       to_cpy = min (nlen, sizeof name - 1);
   632       memcpy (name, prop+bytes_parsed, to_cpy);
   633       name[to_cpy] = '\0';
   634 
   635       bytes_parsed += nlen;
   636       bytes_parsed = PAD (bytes_parsed);
   637 
   638       bytes_parsed += 4; /* Skip serial for this value */
   639       if (bytes_parsed > bytes) return settings_seen;
   640 
   641       want_this = strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0;
   642 #if defined USE_CAIRO || defined HAVE_XFT
   643       if ((nlen > 6 && memcmp (name, "Xft/", 4) == 0)
   644           || strcmp (XSETTINGS_FONT_NAME, name) == 0)
   645         want_this = true;
   646 #endif
   647 
   648       switch (type)
   649         {
   650         case 0: /* Integer */
   651           if (bytes_parsed + 4 > bytes) return settings_seen;
   652           if (want_this)
   653             {
   654               memcpy (&ival, prop+bytes_parsed, 4);
   655               if (my_bo != that_bo) ival = bswap_32 (ival);
   656             }
   657           bytes_parsed += 4;
   658           break;
   659 
   660         case 1: /* String */
   661           if (bytes_parsed + 4 > bytes) return settings_seen;
   662           memcpy (&vlen, prop+bytes_parsed, 4);
   663           bytes_parsed += 4;
   664           if (my_bo != that_bo) vlen = bswap_32 (vlen);
   665           if (want_this)
   666             {
   667               to_cpy = min (vlen, sizeof sval - 1);
   668               memcpy (sval, prop+bytes_parsed, to_cpy);
   669               sval[to_cpy] = '\0';
   670             }
   671           bytes_parsed += vlen;
   672           bytes_parsed = PAD (bytes_parsed);
   673           break;
   674 
   675         case 2: /* RGB value */
   676           /* No need to parse this */
   677           if (bytes_parsed + 8 > bytes) return settings_seen;
   678           bytes_parsed += 8; /* 4 values (r, b, g, alpha), 2 bytes each.  */
   679           break;
   680 
   681         default: /* Parse Error */
   682           return settings_seen;
   683         }
   684 
   685       if (want_this)
   686         {
   687           if (strcmp (name, XSETTINGS_TOOL_BAR_STYLE) == 0)
   688             {
   689               dupstring (&settings->tb_style, sval);
   690               settings->seen |= SEEN_TB_STYLE;
   691             }
   692 #if defined USE_CAIRO || defined HAVE_XFT
   693           else if (strcmp (name, XSETTINGS_FONT_NAME) == 0)
   694             {
   695               dupstring (&settings->font, sval);
   696               settings->seen |= SEEN_FONT;
   697             }
   698           else if (strcmp (name, "Xft/Antialias") == 0)
   699             {
   700               settings->seen |= SEEN_AA;
   701               settings->aa = ival != 0;
   702             }
   703           else if (strcmp (name, "Xft/Hinting") == 0)
   704             {
   705               settings->seen |= SEEN_HINTING;
   706               settings->hinting = ival != 0;
   707             }
   708 # ifdef FC_HINT_STYLE
   709           else if (strcmp (name, "Xft/HintStyle") == 0)
   710             {
   711               settings->seen |= SEEN_HINTSTYLE;
   712               if (strcmp (sval, "hintnone") == 0)
   713                 settings->hintstyle = FC_HINT_NONE;
   714               else if (strcmp (sval, "hintslight") == 0)
   715                 settings->hintstyle = FC_HINT_SLIGHT;
   716               else if (strcmp (sval, "hintmedium") == 0)
   717                 settings->hintstyle = FC_HINT_MEDIUM;
   718               else if (strcmp (sval, "hintfull") == 0)
   719                 settings->hintstyle = FC_HINT_FULL;
   720               else
   721                 settings->seen &= ~SEEN_HINTSTYLE;
   722             }
   723 # endif
   724           else if (strcmp (name, "Xft/RGBA") == 0)
   725             {
   726               settings->seen |= SEEN_RGBA;
   727               if (strcmp (sval, "none") == 0)
   728                 settings->rgba = FC_RGBA_NONE;
   729               else if (strcmp (sval, "rgb") == 0)
   730                 settings->rgba = FC_RGBA_RGB;
   731               else if (strcmp (sval, "bgr") == 0)
   732                 settings->rgba = FC_RGBA_BGR;
   733               else if (strcmp (sval, "vrgb") == 0)
   734                 settings->rgba = FC_RGBA_VRGB;
   735               else if (strcmp (sval, "vbgr") == 0)
   736                 settings->rgba = FC_RGBA_VBGR;
   737               else
   738                 settings->seen &= ~SEEN_RGBA;
   739             }
   740           else if (strcmp (name, "Xft/DPI") == 0 && ival != (CARD32) -1)
   741             {
   742               settings->seen |= SEEN_DPI;
   743               settings->dpi = ival / 1024.0;
   744             }
   745           else if (strcmp (name, "Xft/lcdfilter") == 0)
   746             {
   747               settings->seen |= SEEN_LCDFILTER;
   748               if (strcmp (sval, "none") == 0)
   749                 settings->lcdfilter = FC_LCD_NONE;
   750               else if (strcmp (sval, "lcddefault") == 0)
   751                 settings->lcdfilter = FC_LCD_DEFAULT;
   752               else
   753                 settings->seen &= ~SEEN_LCDFILTER;
   754             }
   755 #endif /* USE_CAIRO || HAVE_XFT */
   756           else
   757             want_this = false;
   758           settings_seen += want_this;
   759         }
   760     }
   761 
   762   return settings_seen;
   763 }
   764 #endif
   765 
   766 #ifndef HAVE_PGTK
   767 /* Read settings from the XSettings property window on display for DPYINFO.
   768    Store settings read in SETTINGS.
   769    Return true if successful.  */
   770 
   771 static bool
   772 read_settings (Display_Info *dpyinfo, struct xsettings *settings)
   773 {
   774   Atom act_type;
   775   int act_form;
   776   unsigned long nitems, bytes_after;
   777   unsigned char *prop = NULL;
   778   Display *dpy = dpyinfo->display;
   779   int rc;
   780   bool got_settings = false;
   781 
   782   x_catch_errors (dpy);
   783   rc = XGetWindowProperty (dpy,
   784                            dpyinfo->xsettings_window,
   785                            dpyinfo->Xatom_xsettings_prop,
   786                            0, LONG_MAX, False, AnyPropertyType,
   787                            &act_type, &act_form, &nitems, &bytes_after,
   788                            &prop);
   789 
   790   if (rc == Success && prop != NULL && act_form == 8 && nitems > 0
   791       && act_type == dpyinfo->Xatom_xsettings_prop)
   792     got_settings = parse_settings (prop, nitems, settings) != 0;
   793 
   794   XFree (prop);
   795 
   796   x_uncatch_errors ();
   797 
   798   return got_settings;
   799 }
   800 #endif
   801 
   802 #ifndef HAVE_PGTK
   803 /* Apply Xft settings in SETTINGS to the Xft library.
   804    Store a Lisp event that Xft settings changed.  */
   805 
   806 static void
   807 apply_xft_settings (Display_Info *dpyinfo,
   808                     struct xsettings *settings)
   809 {
   810 #if defined HAVE_XFT                                    \
   811   || (defined USE_CAIRO && defined CAIRO_HAS_FC_FONT    \
   812       && defined CAIRO_HAS_FT_FONT)
   813   FcPattern *pat;
   814   struct xsettings oldsettings;
   815   bool changed = false;
   816 #ifndef HAVE_XFT
   817   cairo_font_options_t *options;
   818 #endif
   819 
   820 
   821   memset (&oldsettings, 0, sizeof (oldsettings));
   822   pat = FcPatternCreate ();
   823 #ifdef HAVE_XFT
   824   XftDefaultSubstitute (dpyinfo->display,
   825                         XScreenNumberOfScreen (dpyinfo->screen),
   826                         pat);
   827 #else
   828   FcConfigSubstitute (NULL, pat, FcMatchPattern);
   829   options = cairo_font_options_create ();
   830   ftcrfont_get_default_font_options (dpyinfo, options);
   831   cairo_ft_font_options_substitute (options, pat);
   832   cairo_font_options_destroy (options);
   833   FcDefaultSubstitute (pat);
   834 #endif
   835   FcPatternGetBool (pat, FC_ANTIALIAS, 0, &oldsettings.aa);
   836   FcPatternGetBool (pat, FC_HINTING, 0, &oldsettings.hinting);
   837 #ifdef FC_HINT_STYLE
   838   FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &oldsettings.hintstyle);
   839 #endif
   840   FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &oldsettings.lcdfilter);
   841   FcPatternGetInteger (pat, FC_RGBA, 0, &oldsettings.rgba);
   842   FcPatternGetDouble (pat, FC_DPI, 0, &oldsettings.dpi);
   843 
   844   if ((settings->seen & SEEN_AA) != 0 && oldsettings.aa != settings->aa)
   845     {
   846       FcPatternDel (pat, FC_ANTIALIAS);
   847       FcPatternAddBool (pat, FC_ANTIALIAS, settings->aa);
   848       changed = true;
   849       oldsettings.aa = settings->aa;
   850     }
   851 
   852   if ((settings->seen & SEEN_HINTING) != 0
   853       && oldsettings.hinting != settings->hinting)
   854     {
   855       FcPatternDel (pat, FC_HINTING);
   856       FcPatternAddBool (pat, FC_HINTING, settings->hinting);
   857       changed = true;
   858       oldsettings.hinting = settings->hinting;
   859     }
   860   if ((settings->seen & SEEN_RGBA) != 0 && oldsettings.rgba != settings->rgba)
   861     {
   862       FcPatternDel (pat, FC_RGBA);
   863       FcPatternAddInteger (pat, FC_RGBA, settings->rgba);
   864       oldsettings.rgba = settings->rgba;
   865       changed = true;
   866     }
   867 
   868   /* Older fontconfig versions don't have FC_LCD_FILTER. */
   869   if ((settings->seen & SEEN_LCDFILTER) != 0
   870       && oldsettings.lcdfilter != settings->lcdfilter)
   871     {
   872       FcPatternDel (pat, FC_LCD_FILTER);
   873       FcPatternAddInteger (pat, FC_LCD_FILTER, settings->lcdfilter);
   874       changed = true;
   875       oldsettings.lcdfilter = settings->lcdfilter;
   876     }
   877 
   878 #ifdef FC_HINT_STYLE
   879   if ((settings->seen & SEEN_HINTSTYLE) != 0
   880       && oldsettings.hintstyle != settings->hintstyle)
   881     {
   882       FcPatternDel (pat, FC_HINT_STYLE);
   883       FcPatternAddInteger (pat, FC_HINT_STYLE, settings->hintstyle);
   884       changed = true;
   885       oldsettings.hintstyle = settings->hintstyle;
   886     }
   887 #endif
   888 
   889 #ifdef USE_CAIRO
   890   /* When Cairo is being used, set oldsettings.dpi to dpyinfo->resx.
   891      This is a gross hack, but seeing as Cairo fails to report
   892      anything reasonable, just use it to avoid config-changed events
   893      being sent at startup.  */
   894   oldsettings.dpi = dpyinfo->resx;
   895 #endif
   896 
   897   if ((settings->seen & SEEN_DPI) != 0
   898       && settings->dpi > 0
   899       /* The following conjunct avoids setting `changed' to true when
   900          old and new dpi settings do not differ "substantially".
   901          Otherwise, the dynamic-setting Elisp code may process all sorts
   902          of unrelated settings that override users' font customizations,
   903          among others.  Compare:
   904 
   905          https://lists.gnu.org/r/emacs-devel/2016-05/msg00557.html
   906          https://lists.gnu.org/r/bug-gnu-emacs/2016-12/msg00820.html
   907 
   908          As soon as the dynamic-settings code has been tested and
   909          verified, this Emacs 25.2 workaround should be removed.  */
   910       && ((oldsettings.dpi >= settings->dpi
   911            && (oldsettings.dpi - settings->dpi) > 2)
   912           || ((settings->dpi > oldsettings.dpi)
   913               && (settings->dpi - oldsettings.dpi) > 2)))
   914     {
   915       FcPatternDel (pat, FC_DPI);
   916       FcPatternAddDouble (pat, FC_DPI, settings->dpi);
   917       changed = true;
   918       oldsettings.dpi = settings->dpi;
   919 
   920       /* Changing the DPI on this display affects all frames on it.
   921          Check FRAME_RES_X and FRAME_RES_Y in frame.h to see how.  */
   922       dpyinfo->resy = dpyinfo->resx = settings->dpi;
   923     }
   924 
   925   if (changed)
   926     {
   927       static char const format[] =
   928         "Antialias: %d, Hinting: %d, RGBA: %d, LCDFilter: %d, "
   929         "Hintstyle: %d, DPI: %f";
   930       enum
   931       {
   932         d_formats = 5,
   933         d_growth = INT_BUFSIZE_BOUND (int) - sizeof "%d",
   934         lf_formats = 1,
   935         max_f_integer_digits = DBL_MAX_10_EXP + 1,
   936         f_precision = 6,
   937         lf_growth = (sizeof "-." + max_f_integer_digits + f_precision
   938                      - sizeof "%f")
   939       };
   940       char buf[sizeof format + d_formats * d_growth + lf_formats * lf_growth];
   941 #ifdef HAVE_XFT
   942       XftDefaultSet (dpyinfo->display, pat);
   943 #else
   944       FcPatternDestroy (pat);
   945 #endif
   946       store_config_changed_event (Qfont_render,
   947                                   XCAR (dpyinfo->name_list_element));
   948       Vxft_settings
   949         = make_formatted_string (buf, format,
   950                                  oldsettings.aa, oldsettings.hinting,
   951                                  oldsettings.rgba, oldsettings.lcdfilter,
   952                                  oldsettings.hintstyle, oldsettings.dpi);
   953 
   954     }
   955   else
   956     FcPatternDestroy (pat);
   957 #endif /* HAVE_XFT || (USE_CAIRO && CAIRO_HAS_FC_FONT && CAIRO_HAS_FT_FONT) */
   958 }
   959 #endif
   960 
   961 #ifndef HAVE_PGTK
   962 /* Read XSettings from the display for DPYINFO.
   963    If SEND_EVENT_P store a Lisp event settings that changed.  */
   964 
   965 static void
   966 read_and_apply_settings (Display_Info *dpyinfo, bool send_event_p)
   967 {
   968   struct xsettings settings;
   969 
   970   if (!read_settings (dpyinfo, &settings))
   971     return;
   972 
   973   apply_xft_settings (dpyinfo, &settings);
   974   if (settings.seen & SEEN_TB_STYLE)
   975     {
   976       if (send_event_p)
   977         store_tool_bar_style_changed (settings.tb_style, dpyinfo);
   978       else
   979         current_tool_bar_style = map_tool_bar_style (settings.tb_style);
   980       xfree (settings.tb_style);
   981     }
   982 #if defined USE_CAIRO || defined HAVE_XFT
   983   if (settings.seen & SEEN_FONT)
   984     {
   985       if (send_event_p)
   986         store_font_name_changed (settings.font);
   987       else
   988         dupstring (&current_font, settings.font);
   989       xfree (settings.font);
   990     }
   991 #endif
   992 }
   993 #endif
   994 
   995 #ifndef HAVE_PGTK
   996 /* Check if EVENT for the display in DPYINFO is XSettings related.
   997    Return true if it is, after performing associated side effects.  */
   998 
   999 bool
  1000 xft_settings_event (Display_Info *dpyinfo, const XEvent *event)
  1001 {
  1002   bool check_window_p = false, apply_settings_p = false;
  1003 
  1004   switch (event->type)
  1005     {
  1006     case DestroyNotify:
  1007       if (dpyinfo->xsettings_window == event->xany.window)
  1008         check_window_p = true;
  1009       break;
  1010 
  1011     case ClientMessage:
  1012       if (event->xclient.message_type == dpyinfo->Xatom_xsettings_mgr
  1013           && event->xclient.data.l[1] == dpyinfo->Xatom_xsettings_sel
  1014           && event->xclient.window == dpyinfo->root_window)
  1015         check_window_p = true;
  1016       break;
  1017 
  1018     case PropertyNotify:
  1019       if (event->xproperty.window == dpyinfo->xsettings_window
  1020           && event->xproperty.state == PropertyNewValue
  1021           && event->xproperty.atom == dpyinfo->Xatom_xsettings_prop)
  1022         apply_settings_p = true;
  1023       break;
  1024     }
  1025 
  1026 
  1027   if (check_window_p)
  1028     {
  1029       dpyinfo->xsettings_window = None;
  1030       get_prop_window (dpyinfo);
  1031       if (dpyinfo->xsettings_window != None)
  1032         apply_settings_p = true;
  1033     }
  1034 
  1035   if (apply_settings_p)
  1036     read_and_apply_settings (dpyinfo, true);
  1037 
  1038   return check_window_p || apply_settings_p;
  1039 }
  1040 #endif
  1041 
  1042 /* Initialize GSettings and read startup values.  */
  1043 
  1044 static void
  1045 init_gsettings (void)
  1046 {
  1047 #ifdef HAVE_GSETTINGS
  1048   GVariant *val;
  1049   bool schema_found = false;
  1050 
  1051 #if ! GLIB_CHECK_VERSION (2, 36, 0)
  1052   g_type_init ();
  1053 #endif
  1054 
  1055 #if GLIB_CHECK_VERSION (2, 32, 0)
  1056   {
  1057     GSettingsSchema *sc = g_settings_schema_source_lookup
  1058       (g_settings_schema_source_get_default (),
  1059        GSETTINGS_SCHEMA,
  1060        true);
  1061     schema_found = sc != NULL;
  1062     if (sc) g_settings_schema_unref (sc);
  1063   }
  1064 #else
  1065   {
  1066     const gchar *const *schemas = g_settings_list_schemas ();
  1067     if (schemas == NULL) return;
  1068     while (! schema_found && *schemas != NULL)
  1069       schema_found = strcmp (*schemas++, GSETTINGS_SCHEMA) == 0;
  1070   }
  1071 #endif
  1072   if (!schema_found) return;
  1073 
  1074   gsettings_client = g_settings_new (GSETTINGS_SCHEMA);
  1075   if (!gsettings_client) return;
  1076   g_object_ref_sink (G_OBJECT (gsettings_client));
  1077   g_signal_connect (G_OBJECT (gsettings_client), "changed",
  1078                     G_CALLBACK (something_changed_gsettingsCB), NULL);
  1079 
  1080   val = g_settings_get_value (gsettings_client, GSETTINGS_TOOL_BAR_STYLE);
  1081   if (val)
  1082     {
  1083       g_variant_ref_sink (val);
  1084       if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
  1085         current_tool_bar_style
  1086           = map_tool_bar_style (g_variant_get_string (val, NULL));
  1087       g_variant_unref (val);
  1088     }
  1089 
  1090 #if defined USE_CAIRO || defined HAVE_XFT
  1091   val = g_settings_get_value (gsettings_client, GSETTINGS_MONO_FONT);
  1092   if (val)
  1093     {
  1094       g_variant_ref_sink (val);
  1095       if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
  1096         dupstring (&current_mono_font, g_variant_get_string (val, NULL));
  1097       g_variant_unref (val);
  1098     }
  1099 
  1100   val = g_settings_get_value (gsettings_client, GSETTINGS_FONT_NAME);
  1101   if (val)
  1102     {
  1103       g_variant_ref_sink (val);
  1104       if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
  1105         dupstring (&current_font, g_variant_get_string (val, NULL));
  1106       g_variant_unref (val);
  1107     }
  1108 
  1109   /* Only use the gsettings font entries for the Cairo backend
  1110      running on PGTK.  */
  1111 #ifdef HAVE_PGTK
  1112   font_options = cairo_font_options_create ();
  1113   apply_gsettings_font_antialias (gsettings_client);
  1114   apply_gsettings_font_hinting (gsettings_client);
  1115   apply_gsettings_font_rgba_order (gsettings_client);
  1116 #endif /* HAVE_PGTK */
  1117 
  1118 #endif /* USE_CAIRO || HAVE_XFT */
  1119 
  1120 #endif /* HAVE_GSETTINGS */
  1121 }
  1122 
  1123 /* Init GConf and read startup values.  */
  1124 
  1125 static void
  1126 init_gconf (void)
  1127 {
  1128 #if defined (HAVE_GCONF)
  1129   char *s;
  1130 
  1131 #if ! GLIB_CHECK_VERSION (2, 36, 0)
  1132   g_type_init ();
  1133 #endif
  1134 
  1135   gconf_client = gconf_client_get_default ();
  1136   gconf_client_set_error_handling (gconf_client, GCONF_CLIENT_HANDLE_NONE);
  1137   gconf_client_add_dir (gconf_client,
  1138                         GCONF_TOOL_BAR_STYLE,
  1139                         GCONF_CLIENT_PRELOAD_ONELEVEL,
  1140                         NULL);
  1141   gconf_client_notify_add (gconf_client,
  1142                            GCONF_TOOL_BAR_STYLE,
  1143                            something_changed_gconfCB,
  1144                            NULL, NULL, NULL);
  1145 
  1146   s = gconf_client_get_string (gconf_client, GCONF_TOOL_BAR_STYLE, NULL);
  1147   if (s)
  1148     {
  1149       current_tool_bar_style = map_tool_bar_style (s);
  1150       g_free (s);
  1151     }
  1152 
  1153 #if defined USE_CAIRO || defined HAVE_XFT
  1154   s = gconf_client_get_string (gconf_client, GCONF_MONO_FONT, NULL);
  1155   if (s)
  1156     {
  1157       dupstring (&current_mono_font, s);
  1158       g_free (s);
  1159     }
  1160   s = gconf_client_get_string (gconf_client, GCONF_FONT_NAME, NULL);
  1161   if (s)
  1162     {
  1163       dupstring (&current_font, s);
  1164       g_free (s);
  1165     }
  1166   gconf_client_add_dir (gconf_client,
  1167                         GCONF_MONO_FONT,
  1168                         GCONF_CLIENT_PRELOAD_ONELEVEL,
  1169                         NULL);
  1170   gconf_client_notify_add (gconf_client,
  1171                            GCONF_MONO_FONT,
  1172                            something_changed_gconfCB,
  1173                            NULL, NULL, NULL);
  1174   gconf_client_add_dir (gconf_client,
  1175                         GCONF_FONT_NAME,
  1176                         GCONF_CLIENT_PRELOAD_ONELEVEL,
  1177                         NULL);
  1178   gconf_client_notify_add (gconf_client,
  1179                            GCONF_FONT_NAME,
  1180                            something_changed_gconfCB,
  1181                            NULL, NULL, NULL);
  1182 #endif /* USE_CAIRO || HAVE_XFT */
  1183 #endif /* HAVE_GCONF */
  1184 }
  1185 
  1186 #ifndef HAVE_PGTK
  1187 /* Init Xsettings and read startup values.  */
  1188 
  1189 static void
  1190 init_xsettings (Display_Info *dpyinfo)
  1191 {
  1192   Display *dpy = dpyinfo->display;
  1193 
  1194   block_input ();
  1195 
  1196   /* Select events so we can detect client messages sent when selection
  1197      owner changes.  */
  1198   XSelectInput (dpy, dpyinfo->root_window, StructureNotifyMask);
  1199 
  1200   get_prop_window (dpyinfo);
  1201   if (dpyinfo->xsettings_window != None)
  1202     read_and_apply_settings (dpyinfo, false);
  1203 
  1204   unblock_input ();
  1205 }
  1206 #endif
  1207 
  1208 void
  1209 xsettings_initialize (Display_Info *dpyinfo)
  1210 {
  1211   if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo;
  1212   init_gconf ();
  1213 #ifndef HAVE_PGTK
  1214   init_xsettings (dpyinfo);
  1215 #endif
  1216   init_gsettings ();
  1217 }
  1218 
  1219 /* Return the system monospaced font.
  1220    May be NULL if not known.  */
  1221 
  1222 const char *
  1223 xsettings_get_system_font (void)
  1224 {
  1225   return current_mono_font;
  1226 }
  1227 
  1228 #ifdef USE_LUCID
  1229 /* Return the system font.
  1230    May be NULL if not known.  */
  1231 
  1232 const char *
  1233 xsettings_get_system_normal_font (void)
  1234 {
  1235   return current_font;
  1236 }
  1237 #endif
  1238 
  1239 #ifdef HAVE_PGTK
  1240 /* Return the cairo font options, updated from the gsettings font
  1241    config entries.  The caller should call cairo_font_options_destroy
  1242    on the result.  */
  1243 cairo_font_options_t *
  1244 xsettings_get_font_options (void)
  1245 {
  1246   if (font_options != NULL)
  1247     return cairo_font_options_copy (font_options);
  1248   else
  1249     /* GSettings is not configured.  */
  1250     return cairo_font_options_create ();
  1251 }
  1252 #endif
  1253 
  1254 DEFUN ("font-get-system-normal-font", Ffont_get_system_normal_font,
  1255        Sfont_get_system_normal_font,
  1256        0, 0, 0,
  1257        doc: /* Get the system default application font.
  1258 The font is returned as either a font-spec or font name.  */)
  1259   (void)
  1260 {
  1261   return current_font ? build_string (current_font) : Qnil;
  1262 }
  1263 
  1264 DEFUN ("font-get-system-font", Ffont_get_system_font, Sfont_get_system_font,
  1265        0, 0, 0,
  1266        doc: /* Get the system default fixed width font.
  1267 The font is returned as either a font-spec or font name.  */)
  1268   (void)
  1269 {
  1270   return current_mono_font ? build_string (current_mono_font) : Qnil;
  1271 }
  1272 
  1273 DEFUN ("tool-bar-get-system-style", Ftool_bar_get_system_style,
  1274        Stool_bar_get_system_style, 0, 0, 0,
  1275        doc: /* Get the system tool bar style.
  1276 If no system tool bar style is known, return `tool-bar-style' if set to a
  1277 known style.  Otherwise return image.  */)
  1278   (void)
  1279 {
  1280   if (EQ (Vtool_bar_style, Qimage)
  1281       || EQ (Vtool_bar_style, Qtext)
  1282       || EQ (Vtool_bar_style, Qboth)
  1283       || EQ (Vtool_bar_style, Qboth_horiz)
  1284       || EQ (Vtool_bar_style, Qtext_image_horiz))
  1285     return Vtool_bar_style;
  1286   if (!NILP (current_tool_bar_style))
  1287     return current_tool_bar_style;
  1288   return Qimage;
  1289 }
  1290 
  1291 void
  1292 syms_of_xsettings (void)
  1293 {
  1294   current_mono_font = NULL;
  1295   PDUMPER_IGNORE (current_mono_font);
  1296   current_font = NULL;
  1297   PDUMPER_IGNORE (current_font);
  1298   first_dpyinfo = NULL;
  1299   PDUMPER_IGNORE (first_dpyinfo);
  1300 #ifdef HAVE_GSETTINGS
  1301   gsettings_client = NULL;
  1302   PDUMPER_IGNORE (gsettings_client);
  1303 #endif
  1304 #ifdef HAVE_GCONF
  1305   gconf_client = NULL;
  1306   PDUMPER_IGNORE (gconf_client);
  1307 #endif
  1308 #ifdef HAVE_PGTK
  1309   font_options = NULL;
  1310   PDUMPER_IGNORE (font_options);
  1311 #endif
  1312 
  1313   DEFSYM (Qmonospace_font_name, "monospace-font-name");
  1314   DEFSYM (Qfont_name, "font-name");
  1315   DEFSYM (Qfont_render, "font-render");
  1316   DEFSYM (Qdynamic_setting, "dynamic-setting");
  1317   DEFSYM (Qfont_render_setting, "font-render-setting");
  1318   DEFSYM (Qsystem_font_setting, "system-font-setting");
  1319 
  1320   defsubr (&Sfont_get_system_font);
  1321   defsubr (&Sfont_get_system_normal_font);
  1322 
  1323   DEFVAR_BOOL ("font-use-system-font", use_system_font,
  1324     doc: /* Non-nil means to apply the system defined font dynamically.
  1325 When this is non-nil and the system defined fixed width font changes, we
  1326 update frames dynamically.
  1327 If this variable is nil, Emacs ignores system font changes.  */);
  1328   use_system_font = false;
  1329 
  1330   DEFVAR_LISP ("xft-settings", Vxft_settings,
  1331                doc: /* Font settings applied to Xft.  */);
  1332   Vxft_settings = empty_unibyte_string;
  1333 
  1334 #if defined USE_CAIRO || defined HAVE_XFT
  1335   Fprovide (Qfont_render_setting, Qnil);
  1336 #if defined (HAVE_GCONF) || defined (HAVE_GSETTINGS)
  1337   Fprovide (Qsystem_font_setting, Qnil);
  1338 #endif
  1339 #endif
  1340 
  1341   current_tool_bar_style = Qnil;
  1342   DEFSYM (Qtool_bar_style, "tool-bar-style");
  1343   defsubr (&Stool_bar_get_system_style);
  1344 
  1345   Fprovide (Qdynamic_setting, Qnil);
  1346 }

/* [<][>][^][v][top][bottom][index][help] */