root/src/pgtkfns.c

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

DEFINITIONS

This source file includes following definitions.
  1. pgtk_get_monitor_scale_factor
  2. check_pgtk_display_info
  3. is_wayland_display
  4. pgtk_display_info_for_name
  5. pgtk_set_foreground_color
  6. pgtk_set_background_color
  7. pgtk_set_alpha_background
  8. pgtk_set_border_color
  9. pgtk_set_cursor_color
  10. pgtk_set_name_internal
  11. pgtk_set_name
  12. pgtk_explicitly_set_name
  13. pgtk_implicitly_set_name
  14. pgtk_set_title
  15. pgtk_set_menu_bar_lines
  16. pgtk_set_tab_bar_lines
  17. pgtk_change_tab_bar_height
  18. x_change_tool_bar_height
  19. pgtk_set_tool_bar_lines
  20. pgtk_set_child_frame_border_width
  21. pgtk_set_internal_border_width
  22. pgtk_set_icon_type
  23. pgtk_set_icon_name
  24. pgtk_set_cursor_type
  25. pgtk_set_mouse_color
  26. pgtk_set_undecorated
  27. pgtk_set_skip_taskbar
  28. pgtk_set_override_redirect
  29. xg_set_icon
  30. xg_set_icon_from_xpm_data
  31. pgtk_set_sticky
  32. pgtk_set_tool_bar_position
  33. pgtk_set_scroll_bar_foreground
  34. pgtk_set_scroll_bar_background
  35. unwind_create_frame
  36. do_unwind_create_frame
  37. x_decode_color
  38. pgtk_default_font_parameter
  39. update_watched_scale_factor
  40. DEFUN
  41. pgtk_frame_restack
  42. pgtk_is_lower_char
  43. pgtk_is_upper_char
  44. pgtk_is_numeric_char
  45. parse_resource_key
  46. pgtk_get_defaults_value
  47. pgtk_set_defaults_value
  48. pgtk_get_defaults_value
  49. pgtk_set_defaults_value
  50. DEFUN
  51. DEFUN
  52. DEFUN
  53. DEFUN
  54. DEFUN
  55. DEFUN
  56. DEFUN
  57. DEFUN
  58. DEFUN
  59. DEFUN
  60. check_x_display_info
  61. pgtk_set_scroll_bar_default_width
  62. pgtk_set_scroll_bar_default_height
  63. pgtk_get_string_resource
  64. pgtk_get_focus_frame
  65. DEFUN
  66. DEFUN
  67. DEFUN
  68. DEFUN
  69. DEFUN
  70. pgtk_frame_scale_factor
  71. DEFUN
  72. DEFUN
  73. unwind_create_tip_frame
  74. x_create_tip_frame
  75. compute_tip_xy
  76. pgtk_hide_tip
  77. DEFUN
  78. frame_geometry
  79. DEFUN
  80. DEFUN
  81. DEFUN
  82. DEFUN
  83. DEFUN
  84. clean_up_dialog
  85. DEFUN
  86. DEFUN
  87. syms_of_pgtkfns

     1 /* Functions for the pure Gtk+-3.
     2 
     3 Copyright (C) 1989, 1992-1994, 2005-2006, 2008-2020, 2022-2023 Free
     4 Software Foundation, Inc.
     5 
     6 This file is part of GNU Emacs.
     7 
     8 GNU Emacs is free software: you can redistribute it and/or modify
     9 it under the terms of the GNU General Public License as published by
    10 the Free Software Foundation, either version 3 of the License, or (at
    11 your option) any later version.
    12 
    13 GNU Emacs is distributed in the hope that it will be useful,
    14 but WITHOUT ANY WARRANTY; without even the implied warranty of
    15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16 GNU General Public License for more details.
    17 
    18 You should have received a copy of the GNU General Public License
    19 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    20 
    21 /* This should be the first include, as it may set up #defines affecting
    22    interpretation of even the system includes. */
    23 #include <config.h>
    24 
    25 #include <math.h>
    26 #include <c-strcase.h>
    27 
    28 #include "lisp.h"
    29 #include "blockinput.h"
    30 #include "gtkutil.h"
    31 #include "window.h"
    32 #include "character.h"
    33 #include "buffer.h"
    34 #include "keyboard.h"
    35 #include "termhooks.h"
    36 #include "fontset.h"
    37 #include "font.h"
    38 #include "xsettings.h"
    39 #include "atimer.h"
    40 
    41 static ptrdiff_t image_cache_refcount;
    42 
    43 static int x_decode_color (struct frame *f, Lisp_Object color_name,
    44                            int mono_color);
    45 static struct pgtk_display_info *pgtk_display_info_for_name (Lisp_Object);
    46 
    47 static const char *pgtk_app_name = "Emacs";
    48 
    49 /* Scale factor manually set per monitor.  */
    50 static Lisp_Object monitor_scale_factor_alist;
    51 
    52 /* ==========================================================================
    53 
    54     Internal utility functions
    55 
    56    ========================================================================== */
    57 
    58 static double
    59 pgtk_get_monitor_scale_factor (const char *model)
    60 {
    61   if (model == NULL)
    62     return 0.0;
    63 
    64   Lisp_Object mdl = build_string (model);
    65   Lisp_Object tem = Fassoc (mdl, monitor_scale_factor_alist, Qnil);
    66   if (NILP (tem))
    67     return 0;
    68   Lisp_Object cdr = Fcdr (tem);
    69   if (NILP (cdr))
    70     return 0;
    71   if (FIXNUMP (cdr))
    72     return XFIXNUM (cdr);
    73   else if (FLOATP (cdr))
    74     return XFLOAT_DATA (cdr);
    75   else
    76     error ("unknown type of scale-factor");
    77 }
    78 
    79 struct pgtk_display_info *
    80 check_pgtk_display_info (Lisp_Object object)
    81 {
    82   struct pgtk_display_info *dpyinfo = NULL;
    83 
    84   if (NILP (object))
    85     {
    86       struct frame *sf = XFRAME (selected_frame);
    87 
    88       if (FRAME_PGTK_P (sf) && FRAME_LIVE_P (sf))
    89         dpyinfo = FRAME_DISPLAY_INFO (sf);
    90       else if (x_display_list != 0)
    91         dpyinfo = x_display_list;
    92       else
    93         error ("Frames are not in use or not initialized");
    94     }
    95   else if (TERMINALP (object))
    96     {
    97       struct terminal *t = decode_live_terminal (object);
    98 
    99       if (t->type != output_pgtk)
   100         error ("Terminal %d is not a display", t->id);
   101 
   102       dpyinfo = t->display_info.pgtk;
   103     }
   104   else if (STRINGP (object))
   105     dpyinfo = pgtk_display_info_for_name (object);
   106   else
   107     {
   108       struct frame *f = decode_window_system_frame (object);
   109       dpyinfo = FRAME_DISPLAY_INFO (f);
   110     }
   111 
   112   return dpyinfo;
   113 }
   114 
   115 /* On Wayland, even if without WAYLAND_DISPLAY, --display DISPLAY
   116    works, but gdk_display_get_name always return "wayland-0", which
   117    may be different from DISPLAY.  If with WAYLAND_DISPLAY, then it
   118    always returns WAYLAND_DISPLAY.  So pgtk Emacs is confused and
   119    enters multi display environment.  To workaround this situation,
   120    treat all the wayland-* as the same display.  */
   121 static Lisp_Object
   122 is_wayland_display (Lisp_Object dpyname)
   123 {
   124   const char *p = SSDATA (dpyname);
   125   if (strncmp (p, "wayland-", 8) != 0)
   126     return Qnil;
   127   p += 8;
   128   do {
   129     if (*p < '0' || *p > '9')
   130       return Qnil;
   131   } while (*++p != '\0');
   132   return Qt;
   133 }
   134 
   135 /* Return the X display structure for the display named NAME.
   136    Open a new connection if necessary.  */
   137 static struct pgtk_display_info *
   138 pgtk_display_info_for_name (Lisp_Object name)
   139 {
   140   struct pgtk_display_info *dpyinfo;
   141 
   142   CHECK_STRING (name);
   143 
   144   if (!NILP (is_wayland_display (name)))
   145     {
   146       for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
   147         if (!NILP (is_wayland_display (XCAR (dpyinfo->name_list_element))))
   148           return dpyinfo;
   149     }
   150   else
   151     {
   152       for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
   153         if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name)))
   154           return dpyinfo;
   155     }
   156 
   157   /* Use this general default value to start with.  */
   158   Vx_resource_name = Vinvocation_name;
   159 
   160   validate_x_resource_name ();
   161 
   162   dpyinfo = pgtk_term_init (name, SSDATA (Vx_resource_name));
   163 
   164   if (dpyinfo == 0)
   165     error ("Cannot connect to display server %s", SDATA (name));
   166 
   167   return dpyinfo;
   168 }
   169 
   170 /* ==========================================================================
   171 
   172     Frame parameter setters
   173 
   174    ========================================================================== */
   175 
   176 
   177 static void
   178 pgtk_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   179 {
   180   unsigned long fg, old_fg;
   181 
   182   block_input ();
   183   old_fg = FRAME_FOREGROUND_COLOR (f);
   184   fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
   185   FRAME_FOREGROUND_PIXEL (f) = fg;
   186   FRAME_X_OUTPUT (f)->foreground_color = fg;
   187 
   188   if (FRAME_GTK_WIDGET (f))
   189     {
   190       if (FRAME_X_OUTPUT (f)->cursor_color == old_fg)
   191         {
   192           FRAME_X_OUTPUT (f)->cursor_color = fg;
   193           FRAME_X_OUTPUT (f)->cursor_xgcv.background = fg;
   194         }
   195 
   196       update_face_from_frame_parameter (f, Qforeground_color, arg);
   197       if (FRAME_VISIBLE_P (f))
   198         SET_FRAME_GARBAGED (f);
   199     }
   200   unblock_input ();
   201 }
   202 
   203 
   204 static void
   205 pgtk_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   206 {
   207   unsigned long bg;
   208 
   209   block_input ();
   210   bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
   211   FRAME_BACKGROUND_PIXEL (f) = bg;
   212 
   213   /* Clear the frame.  */
   214   if (FRAME_VISIBLE_P (f))
   215     pgtk_clear_frame (f);
   216 
   217   FRAME_X_OUTPUT (f)->background_color = bg;
   218   FRAME_X_OUTPUT (f)->cursor_xgcv.foreground = bg;
   219 
   220   xg_set_background_color (f, bg);
   221   update_face_from_frame_parameter (f, Qbackground_color, arg);
   222 
   223   if (FRAME_VISIBLE_P (f))
   224     SET_FRAME_GARBAGED (f);
   225   unblock_input ();
   226 }
   227 
   228 static void
   229 pgtk_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   230 {
   231   gui_set_alpha_background (f, arg, oldval);
   232 
   233   /* This prevents GTK from painting the window's background, which
   234      interferes with transparent background in some environments */
   235 
   236   gtk_widget_set_app_paintable (FRAME_GTK_OUTER_WIDGET (f),
   237                                 f->alpha_background != 1.0);
   238 
   239   if (FRAME_GTK_OUTER_WIDGET (f)
   240       && gtk_widget_get_realized (FRAME_GTK_OUTER_WIDGET (f))
   241       && f->alpha_background != 1.0)
   242     gdk_window_set_opaque_region (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f)),
   243                                   NULL);
   244 }
   245 
   246 static void
   247 pgtk_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   248 {
   249   int pix;
   250 
   251   CHECK_STRING (arg);
   252   pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
   253   FRAME_X_OUTPUT (f)->border_pixel = pix;
   254   pgtk_frame_rehighlight (FRAME_DISPLAY_INFO (f));
   255 }
   256 
   257 static void
   258 pgtk_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   259 {
   260   unsigned long fore_pixel, pixel;
   261   struct pgtk_output *x = f->output_data.pgtk;
   262 
   263   if (!NILP (Vx_cursor_fore_pixel))
   264     {
   265       fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
   266                                    WHITE_PIX_DEFAULT (f));
   267     }
   268   else
   269     fore_pixel = FRAME_BACKGROUND_PIXEL (f);
   270 
   271   pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
   272 
   273   /* Make sure that the cursor color differs from the background color.  */
   274   if (pixel == FRAME_BACKGROUND_PIXEL (f))
   275     {
   276       pixel = x->mouse_color;
   277       if (pixel == fore_pixel)
   278         {
   279           fore_pixel = FRAME_BACKGROUND_PIXEL (f);
   280         }
   281     }
   282 
   283   x->cursor_foreground_color = fore_pixel;
   284   x->cursor_color = pixel;
   285 
   286   if (FRAME_X_WINDOW (f) != 0)
   287     {
   288       x->cursor_xgcv.background = x->cursor_color;
   289       x->cursor_xgcv.foreground = fore_pixel;
   290 
   291       if (FRAME_VISIBLE_P (f))
   292         {
   293           gui_update_cursor (f, false);
   294           gui_update_cursor (f, true);
   295         }
   296     }
   297 
   298   update_face_from_frame_parameter (f, Qcursor_color, arg);
   299 }
   300 
   301 static void
   302 pgtk_set_name_internal (struct frame *f, Lisp_Object name)
   303 {
   304   if (FRAME_GTK_OUTER_WIDGET (f))
   305     {
   306       block_input ();
   307       {
   308         Lisp_Object encoded_name;
   309 
   310         /* As ENCODE_UTF_8 may cause GC and relocation of string data,
   311            we use it before x_encode_text that may return string data.  */
   312         encoded_name = ENCODE_UTF_8 (name);
   313 
   314         gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
   315                               SSDATA (encoded_name));
   316       }
   317       unblock_input ();
   318     }
   319 }
   320 
   321 static void
   322 pgtk_set_name (struct frame *f, Lisp_Object name, int explicit)
   323 {
   324   /* Make sure that requests from lisp code override requests from
   325      Emacs redisplay code.  */
   326   if (explicit)
   327     {
   328       /* If we're switching from explicit to implicit, we had better
   329          update the mode lines and thereby update the title.  */
   330       if (f->explicit_name && NILP (name))
   331         update_mode_lines = 12;
   332 
   333       f->explicit_name = !NILP (name);
   334     }
   335   else if (f->explicit_name)
   336     return;
   337 
   338   if (NILP (name))
   339     name = build_string (pgtk_app_name);
   340   else
   341     CHECK_STRING (name);
   342 
   343   /* Don't change the name if it's already NAME.  */
   344   if (!NILP (Fstring_equal (name, f->name)))
   345     return;
   346 
   347   fset_name (f, name);
   348 
   349   /* Title overrides explicit name.  */
   350   if (!NILP (f->title))
   351     name = f->title;
   352 
   353   pgtk_set_name_internal (f, name);
   354 }
   355 
   356 
   357 /* This function should be called when the user's lisp code has
   358    specified a name for the frame; the name will override any set by the
   359    redisplay code.  */
   360 static void
   361 pgtk_explicitly_set_name (struct frame *f, Lisp_Object arg,
   362                           Lisp_Object oldval)
   363 {
   364   pgtk_set_name (f, arg, true);
   365 }
   366 
   367 
   368 /* This function should be called by Emacs redisplay code to set the
   369    name; names set this way will never override names set by the user's
   370    lisp code.  */
   371 void
   372 pgtk_implicitly_set_name (struct frame *f, Lisp_Object arg,
   373                           Lisp_Object oldval)
   374 {
   375   pgtk_set_name (f, arg, false);
   376 }
   377 
   378 
   379 /* Change the title of frame F to NAME.
   380    If NAME is nil, use the frame name as the title.  */
   381 
   382 static void
   383 pgtk_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
   384 {
   385   /* Don't change the title if it's already NAME.  */
   386   if (EQ (name, f->title))
   387     return;
   388 
   389   update_mode_lines = 22;
   390 
   391   fset_title (f, name);
   392 
   393   if (NILP (name))
   394     name = f->name;
   395   else
   396     CHECK_STRING (name);
   397 
   398   pgtk_set_name_internal (f, name);
   399 }
   400 
   401 static void
   402 pgtk_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
   403 {
   404   int nlines;
   405   /* Right now, menu bars don't work properly in minibuf-only frames;
   406      most of the commands try to apply themselves to the minibuffer
   407      frame itself, and get an error because you can't switch buffers
   408      in or split the minibuffer window.  */
   409   if (FRAME_MINIBUF_ONLY_P (f) || FRAME_PARENT_FRAME (f))
   410     return;
   411 
   412   if (TYPE_RANGED_FIXNUMP (int, value))
   413     nlines = XFIXNUM (value);
   414   else
   415     nlines = 0;
   416 
   417   /* Make sure we redisplay all windows in this frame.  */
   418   fset_redisplay (f);
   419 
   420   FRAME_MENU_BAR_LINES (f) = 0;
   421   FRAME_MENU_BAR_HEIGHT (f) = 0;
   422   if (nlines)
   423     {
   424       FRAME_EXTERNAL_MENU_BAR (f) = 1;
   425       if (FRAME_PGTK_P (f) && f->output_data.pgtk->menubar_widget == 0)
   426         /* Make sure next redisplay shows the menu bar.  */
   427         XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = true;
   428     }
   429   else
   430     {
   431       if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
   432         free_frame_menubar (f);
   433       FRAME_EXTERNAL_MENU_BAR (f) = 0;
   434       if (FRAME_X_P (f))
   435         f->output_data.pgtk->menubar_widget = 0;
   436     }
   437 
   438   adjust_frame_glyphs (f);
   439 }
   440 
   441 /* Set the number of lines used for the tab bar of frame F to VALUE.
   442    VALUE not an integer, or < 0 means set the lines to zero.  OLDVAL
   443    is the old number of tab bar lines.  This function changes the
   444    height of all windows on frame F to match the new tab bar height.
   445    The frame's height doesn't change.  */
   446 
   447 static void
   448 pgtk_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
   449 {
   450   int nlines;
   451 
   452   /* Treat tab bars like menu bars.  */
   453   if (FRAME_MINIBUF_ONLY_P (f))
   454     return;
   455 
   456   /* Use VALUE only if an int >= 0.  */
   457   if (RANGED_FIXNUMP (0, value, INT_MAX))
   458     nlines = XFIXNAT (value);
   459   else
   460     nlines = 0;
   461 
   462   pgtk_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
   463 }
   464 
   465 /* Set the pixel height of the tab bar of frame F to HEIGHT.  */
   466 void
   467 pgtk_change_tab_bar_height (struct frame *f, int height)
   468 {
   469   int unit = FRAME_LINE_HEIGHT (f);
   470   int old_height = FRAME_TAB_BAR_HEIGHT (f);
   471 
   472   /* This differs from the tool bar code in that the tab bar height is
   473      not rounded up.  Otherwise, if redisplay_tab_bar decides to grow
   474      the tab bar by even 1 pixel, FRAME_TAB_BAR_LINES will be changed,
   475      leading to the tab bar height being incorrectly set upon the next
   476      call to x_set_font.  (bug#59285) */
   477   int lines = height / unit;
   478   if (lines == 0 && height != 0)
   479     lines = 1;
   480 
   481   /* Make sure we redisplay all windows in this frame.  */
   482   fset_redisplay (f);
   483 
   484   /* Recalculate tab bar and frame text sizes.  */
   485   FRAME_TAB_BAR_HEIGHT (f) = height;
   486   FRAME_TAB_BAR_LINES (f) = lines;
   487   store_frame_param (f, Qtab_bar_lines, make_fixnum (lines));
   488 
   489   if (FRAME_X_WINDOW (f) && FRAME_TAB_BAR_HEIGHT (f) == 0)
   490     {
   491       clear_frame (f);
   492       clear_current_matrices (f);
   493     }
   494 
   495   if ((height < old_height) && WINDOWP (f->tab_bar_window))
   496     clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
   497 
   498   if (!f->tab_bar_resized)
   499     {
   500       Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
   501 
   502       /* As long as tab_bar_resized is false, effectively try to change
   503         F's native height.  */
   504       if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
   505         adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
   506                            1, false, Qtab_bar_lines);
   507       else
   508         adjust_frame_size (f, -1, -1, 4, false, Qtab_bar_lines);
   509 
   510       f->tab_bar_resized = f->tab_bar_redisplayed;
   511     }
   512   else
   513     /* Any other change may leave the native size of F alone.  */
   514     adjust_frame_size (f, -1, -1, 3, false, Qtab_bar_lines);
   515 
   516   /* adjust_frame_size might not have done anything, garbage frame
   517      here.  */
   518   adjust_frame_glyphs (f);
   519   SET_FRAME_GARBAGED (f);
   520   if (FRAME_X_WINDOW (f))
   521     pgtk_clear_under_internal_border (f);
   522 }
   523 
   524 /* Set the pixel height of the tool bar of frame F to HEIGHT.  */
   525 static void
   526 x_change_tool_bar_height (struct frame *f, int height)
   527 {
   528   FRAME_TOOL_BAR_LINES (f) = 0;
   529   FRAME_TOOL_BAR_HEIGHT (f) = 0;
   530   if (height)
   531     {
   532       FRAME_EXTERNAL_TOOL_BAR (f) = true;
   533       if (FRAME_X_P (f) && f->output_data.pgtk->toolbar_widget == 0)
   534         /* Make sure next redisplay shows the tool bar.  */
   535         XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = true;
   536       update_frame_tool_bar (f);
   537     }
   538   else
   539     {
   540       if (FRAME_EXTERNAL_TOOL_BAR (f))
   541         free_frame_tool_bar (f);
   542       FRAME_EXTERNAL_TOOL_BAR (f) = false;
   543     }
   544 }
   545 
   546 /* Toolbar support.  */
   547 static void
   548 pgtk_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
   549 {
   550   int nlines;
   551 
   552   /* Treat tool bars like menu bars.  */
   553   if (FRAME_MINIBUF_ONLY_P (f))
   554     return;
   555 
   556   /* Use VALUE only if an int >= 0.  */
   557   if (RANGED_FIXNUMP (0, value, INT_MAX))
   558     nlines = XFIXNAT (value);
   559   else
   560     nlines = 0;
   561 
   562   x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
   563 
   564 }
   565 
   566 static void
   567 pgtk_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   568 {
   569   int border;
   570 
   571   if (NILP (arg))
   572     border = -1;
   573   else if (RANGED_FIXNUMP (0, arg, INT_MAX))
   574     border = XFIXNAT (arg);
   575   else
   576     signal_error ("Invalid child frame border width", arg);
   577 
   578   if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
   579     {
   580       f->child_frame_border_width = border;
   581 
   582       if (FRAME_GTK_WIDGET (f))
   583         {
   584           adjust_frame_size (f, -1, -1, 3,
   585                              false, Qchild_frame_border_width);
   586           pgtk_clear_under_internal_border (f);
   587         }
   588     }
   589 }
   590 
   591 static void
   592 pgtk_set_internal_border_width (struct frame *f, Lisp_Object arg,
   593                                 Lisp_Object oldval)
   594 {
   595   int border = check_int_nonnegative (arg);
   596 
   597   if (border != FRAME_INTERNAL_BORDER_WIDTH (f))
   598     {
   599       f->internal_border_width = border;
   600 
   601       if (FRAME_X_WINDOW (f))
   602         {
   603           adjust_frame_size (f, -1, -1, 3, false, Qinternal_border_width);
   604           pgtk_clear_under_internal_border (f);
   605         }
   606     }
   607 }
   608 
   609 static void
   610 pgtk_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   611 {
   612   bool result;
   613 
   614   if (STRINGP (arg))
   615     {
   616       if (STRINGP (oldval) && BASE_EQ (Fstring_equal (oldval, arg), Qt))
   617         return;
   618     }
   619   else if (!STRINGP (oldval) && NILP (oldval) == NILP (arg))
   620     return;
   621 
   622   block_input ();
   623   if (NILP (arg))
   624     result = pgtk_text_icon (f,
   625                              SSDATA ((!NILP (f->icon_name)
   626                                       ? f->icon_name : f->name)));
   627   else
   628     result = FRAME_TERMINAL (f)->set_bitmap_icon_hook (f, arg);
   629 
   630   if (result)
   631     {
   632       unblock_input ();
   633       error ("No icon window available");
   634     }
   635 
   636   unblock_input ();
   637 }
   638 
   639 static void
   640 pgtk_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   641 {
   642   bool result;
   643 
   644   if (STRINGP (arg))
   645     {
   646       if (STRINGP (oldval) && BASE_EQ (Fstring_equal (oldval, arg), Qt))
   647         return;
   648     }
   649   else if (!NILP (arg) || NILP (oldval))
   650     return;
   651 
   652   fset_icon_name (f, arg);
   653 
   654   block_input ();
   655 
   656   result = pgtk_text_icon (f,
   657                            SSDATA ((!NILP (f->icon_name)
   658                                     ? f->icon_name
   659                                     : !NILP (f->title)
   660                                     ? f->title : f->name)));
   661 
   662   if (result)
   663     {
   664       unblock_input ();
   665       error ("No icon window available");
   666     }
   667 
   668   unblock_input ();
   669 }
   670 
   671 static void
   672 pgtk_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   673 {
   674   set_frame_cursor_types (f, arg);
   675 }
   676 
   677 static void
   678 pgtk_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   679 {
   680 }
   681 
   682 static void
   683 pgtk_set_undecorated (struct frame *f, Lisp_Object new_value,
   684                    Lisp_Object old_value)
   685 {
   686   if (!EQ (new_value, old_value))
   687     {
   688       FRAME_UNDECORATED (f) = NILP (new_value) ? false : true;
   689       xg_set_undecorated (f, new_value);
   690     }
   691 }
   692 
   693 static void
   694 pgtk_set_skip_taskbar (struct frame *f, Lisp_Object new_value,
   695                     Lisp_Object old_value)
   696 {
   697   if (!EQ (new_value, old_value))
   698     {
   699       xg_set_skip_taskbar (f, new_value);
   700       FRAME_SKIP_TASKBAR (f) = !NILP (new_value);
   701     }
   702 }
   703 
   704 static void
   705 pgtk_set_override_redirect (struct frame *f, Lisp_Object new_value,
   706                             Lisp_Object old_value)
   707 {
   708   if (!EQ (new_value, old_value))
   709     {
   710       /* Here (xfwm) override_redirect can be changed for invisible
   711          frames only.  */
   712       pgtk_make_frame_invisible (f);
   713 
   714       xg_set_override_redirect (f, new_value);
   715 
   716       pgtk_make_frame_visible (f);
   717       FRAME_OVERRIDE_REDIRECT (f) = !NILP (new_value);
   718     }
   719 }
   720 
   721 /* Set icon from FILE for frame F.  */
   722 bool
   723 xg_set_icon (struct frame *f, Lisp_Object file)
   724 {
   725   bool result = false;
   726   Lisp_Object found;
   727 
   728   if (!FRAME_GTK_OUTER_WIDGET (f))
   729     return false;
   730 
   731   found = image_find_image_file (file);
   732 
   733   if (!NILP (found))
   734     {
   735       GdkPixbuf *pixbuf;
   736       GError *err = NULL;
   737       char *filename = SSDATA (ENCODE_FILE (found));
   738       block_input ();
   739 
   740       pixbuf = gdk_pixbuf_new_from_file (filename, &err);
   741 
   742       if (pixbuf)
   743         {
   744           gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
   745                                pixbuf);
   746           g_object_unref (pixbuf);
   747 
   748           result = true;
   749         }
   750       else
   751         g_error_free (err);
   752 
   753       unblock_input ();
   754     }
   755 
   756   return result;
   757 }
   758 
   759 bool
   760 xg_set_icon_from_xpm_data (struct frame *f, const char **data)
   761 {
   762   GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
   763 
   764   if (!pixbuf)
   765     return false;
   766 
   767   if (!FRAME_GTK_OUTER_WIDGET (f))
   768     return false;
   769 
   770   gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
   771   g_object_unref (pixbuf);
   772   return true;
   773 }
   774 
   775 static void
   776 pgtk_set_sticky (struct frame *f, Lisp_Object new_value,
   777                  Lisp_Object old_value)
   778 {
   779   if (!FRAME_GTK_OUTER_WIDGET (f))
   780     return;
   781 
   782   if (!NILP (new_value))
   783     gtk_window_stick (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
   784   else
   785     gtk_window_unstick (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
   786 }
   787 
   788 static void
   789 pgtk_set_tool_bar_position (struct frame *f,
   790                             Lisp_Object new_value, Lisp_Object old_value)
   791 {
   792   Lisp_Object choice = list4 (Qleft, Qright, Qtop, Qbottom);
   793 
   794   if (!NILP (Fmemq (new_value, choice)))
   795     {
   796       if (!EQ (new_value, old_value))
   797         {
   798           xg_change_toolbar_position (f, new_value);
   799           fset_tool_bar_position (f, new_value);
   800         }
   801     }
   802   else
   803     wrong_choice (choice, new_value);
   804 }
   805 
   806 static void
   807 pgtk_set_scroll_bar_foreground (struct frame *f, Lisp_Object new_value,
   808                                 Lisp_Object old_value)
   809 {
   810   GtkCssProvider *css_provider =
   811     FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider;
   812 
   813   if (FRAME_TOOLTIP_P (f))
   814     return;
   815 
   816   if (NILP (new_value))
   817     {
   818       gtk_css_provider_load_from_data (css_provider, "", -1, NULL);
   819       update_face_from_frame_parameter (f, Qscroll_bar_foreground, new_value);
   820     }
   821   else if (STRINGP (new_value))
   822     {
   823       Emacs_Color rgb;
   824 
   825       if (!pgtk_parse_color (f, SSDATA (new_value), &rgb))
   826         error ("Unknown color.");
   827 
   828       char css[64];
   829       sprintf (css, "scrollbar slider { background-color: #%06x; }",
   830                (unsigned int) rgb.pixel & 0xffffff);
   831       gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
   832       update_face_from_frame_parameter (f, Qscroll_bar_foreground, new_value);
   833 
   834     }
   835   else
   836     error ("Invalid scroll-bar-foreground.");
   837 }
   838 
   839 static void
   840 pgtk_set_scroll_bar_background (struct frame *f, Lisp_Object new_value,
   841                                 Lisp_Object old_value)
   842 {
   843   GtkCssProvider *css_provider =
   844     FRAME_X_OUTPUT (f)->scrollbar_background_css_provider;
   845 
   846   if (NILP (new_value))
   847     {
   848       gtk_css_provider_load_from_data (css_provider, "", -1, NULL);
   849       update_face_from_frame_parameter (f, Qscroll_bar_background, new_value);
   850     }
   851   else if (STRINGP (new_value))
   852     {
   853       Emacs_Color rgb;
   854 
   855       if (!pgtk_parse_color (f, SSDATA (new_value), &rgb))
   856         error ("Unknown color.");
   857 
   858       /* On pgtk, this frame parameter should be ignored, and honor
   859          gtk theme.  (It honors the GTK theme if not explicitly set, so
   860          I see no harm in letting users tinker a bit more.)  */
   861       char css[64];
   862       sprintf (css, "scrollbar trough { background-color: #%06x; }",
   863                (unsigned int) rgb.pixel & 0xffffff);
   864       gtk_css_provider_load_from_data (css_provider, css, -1, NULL);
   865       update_face_from_frame_parameter (f, Qscroll_bar_background, new_value);
   866 
   867     }
   868   else
   869     error ("Invalid scroll-bar-background.");
   870 }
   871 
   872 
   873 /***********************************************************************
   874                                Printing
   875  ***********************************************************************/
   876 
   877 
   878 DEFUN ("x-export-frames", Fx_export_frames, Sx_export_frames, 0, 2, 0,
   879        doc: /* Return image data of FRAMES in TYPE format.
   880 FRAMES should be nil (the selected frame), a frame, or a list of
   881 frames (each of which corresponds to one page).  Each frame should be
   882 visible.  Optional arg TYPE should be either `pdf' (default), `png',
   883 `postscript', or `svg'.  Supported types are determined by the
   884 compile-time configuration of cairo.
   885 
   886 Note: Text drawn with the `x' font backend is shown with hollow boxes
   887 unless TYPE is `png'.  */)
   888      (Lisp_Object frames, Lisp_Object type)
   889 {
   890   Lisp_Object rest, tmp;
   891   cairo_surface_type_t surface_type;
   892 
   893   if (!CONSP (frames))
   894     frames = list1 (frames);
   895 
   896   tmp = Qnil;
   897   for (rest = frames; CONSP (rest); rest = XCDR (rest))
   898     {
   899       struct frame *f = decode_window_system_frame (XCAR (rest));
   900       Lisp_Object frame;
   901 
   902       XSETFRAME (frame, f);
   903       if (!FRAME_VISIBLE_P (f))
   904         error ("Frames to be exported must be visible.");
   905       tmp = Fcons (frame, tmp);
   906     }
   907   frames = Fnreverse (tmp);
   908 
   909 #ifdef CAIRO_HAS_PDF_SURFACE
   910   if (NILP (type) || EQ (type, Qpdf))
   911     surface_type = CAIRO_SURFACE_TYPE_PDF;
   912   else
   913 #endif
   914 #ifdef CAIRO_HAS_PNG_FUNCTIONS
   915   if (EQ (type, Qpng))
   916     {
   917       if (!NILP (XCDR (frames)))
   918         error ("PNG export cannot handle multiple frames.");
   919       surface_type = CAIRO_SURFACE_TYPE_IMAGE;
   920     }
   921   else
   922 #endif
   923 #ifdef CAIRO_HAS_PS_SURFACE
   924   if (EQ (type, Qpostscript))
   925     surface_type = CAIRO_SURFACE_TYPE_PS;
   926   else
   927 #endif
   928 #ifdef CAIRO_HAS_SVG_SURFACE
   929   if (EQ (type, Qsvg))
   930     {
   931       /* For now, we stick to SVG 1.1.  */
   932       if (!NILP (XCDR (frames)))
   933         error ("SVG export cannot handle multiple frames.");
   934       surface_type = CAIRO_SURFACE_TYPE_SVG;
   935     }
   936   else
   937 #endif
   938     error ("Unsupported export type");
   939 
   940   return pgtk_cr_export_frames (frames, surface_type);
   941 }
   942 
   943 frame_parm_handler pgtk_frame_parm_handlers[] =
   944   {
   945     gui_set_autoraise,          /* generic OK */
   946     gui_set_autolower,          /* generic OK */
   947     pgtk_set_background_color,
   948     pgtk_set_border_color,
   949     gui_set_border_width,
   950     pgtk_set_cursor_color,
   951     pgtk_set_cursor_type,
   952     gui_set_font,               /* generic OK */
   953     pgtk_set_foreground_color,
   954     pgtk_set_icon_name,
   955     pgtk_set_icon_type,
   956     pgtk_set_child_frame_border_width,
   957     pgtk_set_internal_border_width,     /* generic OK */
   958     gui_set_right_divider_width,
   959     gui_set_bottom_divider_width,
   960     pgtk_set_menu_bar_lines,
   961     pgtk_set_mouse_color,
   962     pgtk_explicitly_set_name,
   963     gui_set_scroll_bar_width,   /* generic OK */
   964     gui_set_scroll_bar_height,  /* generic OK */
   965     pgtk_set_title,
   966     gui_set_unsplittable,       /* generic OK */
   967     gui_set_vertical_scroll_bars,       /* generic OK */
   968     gui_set_horizontal_scroll_bars,     /* generic OK */
   969     gui_set_visibility,         /* generic OK */
   970     pgtk_set_tab_bar_lines,
   971     pgtk_set_tool_bar_lines,
   972     pgtk_set_scroll_bar_foreground,
   973     pgtk_set_scroll_bar_background,
   974     gui_set_screen_gamma,       /* generic OK */
   975     gui_set_line_spacing,       /* generic OK, sets f->extra_line_spacing to int */
   976     gui_set_left_fringe,        /* generic OK */
   977     gui_set_right_fringe,       /* generic OK */
   978     0,
   979     gui_set_fullscreen,         /* generic OK */
   980     gui_set_font_backend,       /* generic OK */
   981     gui_set_alpha,
   982     pgtk_set_sticky,
   983     pgtk_set_tool_bar_position,
   984     0,
   985     pgtk_set_undecorated,
   986     pgtk_set_parent_frame,
   987     pgtk_set_skip_taskbar,
   988     pgtk_set_no_focus_on_map,
   989     pgtk_set_no_accept_focus,
   990     pgtk_set_z_group,
   991     pgtk_set_override_redirect,
   992     gui_set_no_special_glyphs,
   993     pgtk_set_alpha_background,
   994     NULL,
   995   };
   996 
   997 
   998 /* Handler for signals raised during x_create_frame and
   999    x_create_tip_frame.  FRAME is the frame which is partially
  1000    constructed.  */
  1001 
  1002 static Lisp_Object
  1003 unwind_create_frame (Lisp_Object frame)
  1004 {
  1005   struct frame *f = XFRAME (frame);
  1006 
  1007   /* If frame is already dead, nothing to do.  This can happen if the
  1008      display is disconnected after the frame has become official, but
  1009      before x_create_frame removes the unwind protect.  */
  1010   if (!FRAME_LIVE_P (f))
  1011     return Qnil;
  1012 
  1013   /* If frame is ``official'', nothing to do.  */
  1014   if (NILP (Fmemq (frame, Vframe_list)))
  1015     {
  1016       /* If the frame's image cache refcount is still the same as our
  1017          private shadow variable, it means we are unwinding a frame
  1018          for which we didn't yet call init_frame_faces, where the
  1019          refcount is incremented.  Therefore, we increment it here, so
  1020          that free_frame_faces, called in x_free_frame_resources
  1021          below, will not mistakenly decrement the counter that was not
  1022          incremented yet to account for this new frame.  */
  1023       if (FRAME_IMAGE_CACHE (f) != NULL
  1024           && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount)
  1025         FRAME_IMAGE_CACHE (f)->refcount++;
  1026 
  1027       pgtk_free_frame_resources (f);
  1028       free_glyphs (f);
  1029       return Qt;
  1030     }
  1031 
  1032   return Qnil;
  1033 }
  1034 
  1035 static void
  1036 do_unwind_create_frame (Lisp_Object frame)
  1037 {
  1038   unwind_create_frame (frame);
  1039 }
  1040 
  1041 /* Return the pixel color value for color COLOR_NAME on frame F.  If F
  1042    is a monochrome frame, return MONO_COLOR regardless of what ARG says.
  1043    Signal an error if color can't be allocated.  */
  1044 
  1045 static int
  1046 x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color)
  1047 {
  1048   Emacs_Color cdef;
  1049 
  1050   CHECK_STRING (color_name);
  1051 
  1052   /* Return MONO_COLOR for monochrome frames.  */
  1053   if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
  1054     return mono_color;
  1055 
  1056   /* x_defined_color is responsible for coping with failures
  1057      by looking for a near-miss.  */
  1058   if (pgtk_defined_color (f, SSDATA (color_name), &cdef, true, 0))
  1059     return cdef.pixel;
  1060 
  1061   signal_error ("Undefined color", color_name);
  1062 }
  1063 
  1064 void
  1065 pgtk_default_font_parameter (struct frame *f, Lisp_Object parms)
  1066 {
  1067   struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  1068   Lisp_Object font_param =
  1069     gui_display_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
  1070                          RES_TYPE_STRING);
  1071   Lisp_Object font = Qnil;
  1072   if (BASE_EQ (font_param, Qunbound))
  1073     font_param = Qnil;
  1074 
  1075   if (NILP (font_param))
  1076     {
  1077       /* System font should take precedence over X resources.  We suggest this
  1078          regardless of font-use-system-font because .emacs may not have been
  1079          read yet.  */
  1080       const char *system_font = xsettings_get_system_font ();
  1081       if (system_font)
  1082         font = font_open_by_name (f, build_unibyte_string (system_font));
  1083     }
  1084 
  1085   if (NILP (font))
  1086     font = !NILP (font_param) ? font_param
  1087       : gui_display_get_arg (dpyinfo, parms, Qfont, "font", "Font",
  1088                              RES_TYPE_STRING);
  1089 
  1090   if (!FONTP (font) && !STRINGP (font))
  1091     {
  1092       const char *names[] = {
  1093         "monospace-10",
  1094         "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
  1095         "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
  1096         "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
  1097         /* This was formerly the first thing tried, but it finds
  1098            too many fonts and takes too long.  */
  1099         "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
  1100         /* If those didn't work, look for something which will
  1101            at least work.  */
  1102         "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
  1103         "fixed",
  1104         NULL
  1105       };
  1106       int i;
  1107 
  1108       for (i = 0; names[i]; i++)
  1109         {
  1110           font = font_open_by_name (f, build_unibyte_string (names[i]));
  1111           if (!NILP (font))
  1112             break;
  1113         }
  1114       if (NILP (font))
  1115         error ("No suitable font was found");
  1116     }
  1117 
  1118   /* This call will make X resources override any system font setting.  */
  1119   gui_default_parameter (f, parms, Qfont, font, "font", "Font",
  1120                          RES_TYPE_STRING);
  1121 }
  1122 
  1123 static void
  1124 update_watched_scale_factor (struct atimer *timer)
  1125 {
  1126   struct frame *f = timer->client_data;
  1127   double scale_factor = FRAME_SCALE_FACTOR (f);
  1128 
  1129   if (scale_factor != FRAME_X_OUTPUT (f)->watched_scale_factor)
  1130     {
  1131       FRAME_X_OUTPUT (f)->watched_scale_factor = scale_factor;
  1132       pgtk_cr_update_surface_desired_size (f,
  1133                                            FRAME_CR_SURFACE_DESIRED_WIDTH (f),
  1134                                            FRAME_CR_SURFACE_DESIRED_HEIGHT (f),
  1135                                            true);
  1136     }
  1137 }
  1138 
  1139 /* ==========================================================================
  1140 
  1141     Lisp definitions
  1142 
  1143    ========================================================================== */
  1144 
  1145 DEFUN ("pgtk-set-monitor-scale-factor", Fpgtk_set_monitor_scale_factor,
  1146        Spgtk_set_monitor_scale_factor, 2, 2, 0,
  1147        doc: /* Set monitor MONITOR-MODEL's scale factor to SCALE-FACTOR.
  1148 Since Gdk's scale factor is integer, physical pixel width/height is
  1149 incorrect when you specify fractional scale factor in compositor.
  1150 If you set scale factor by this function, it is used instead of Gdk's one.
  1151 
  1152 Pass nil as SCALE-FACTOR if you want to reset the specified monitor's
  1153 scale factor.  */)
  1154   (Lisp_Object monitor_model, Lisp_Object scale_factor)
  1155 {
  1156   CHECK_STRING (monitor_model);
  1157   if (!NILP (scale_factor))
  1158     {
  1159       CHECK_NUMBER (scale_factor);
  1160       if (FIXNUMP (scale_factor))
  1161         {
  1162           if (XFIXNUM (scale_factor) <= 0)
  1163             error ("scale factor must be > 0.");
  1164         }
  1165       else if (FLOATP (scale_factor))
  1166         {
  1167           if (XFLOAT_DATA (scale_factor) <= 0.0)
  1168             error ("scale factor must be > 0.");
  1169         }
  1170       else
  1171         error ("unknown type of scale-factor");
  1172     }
  1173 
  1174   Lisp_Object tem = Fassoc (monitor_model, monitor_scale_factor_alist, Qnil);
  1175   if (NILP (tem))
  1176     {
  1177       if (!NILP (scale_factor))
  1178         monitor_scale_factor_alist = Fcons (Fcons (monitor_model, scale_factor),
  1179                                             monitor_scale_factor_alist);
  1180     }
  1181   else
  1182     Fsetcdr (tem, scale_factor);
  1183 
  1184   return scale_factor;
  1185 }
  1186 
  1187 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 1, 1, 0,
  1188        doc: /* Make a new X window, which is called a "frame" in Emacs terms.
  1189 Return an Emacs frame object.  PARMS is an alist of frame parameters.
  1190 If the parameters specify that the frame should not have a minibuffer,
  1191 and do not specify a specific minibuffer window to use, then
  1192 `default-minibuffer-frame' must be a frame whose minibuffer can be
  1193 shared by the new frame.
  1194 
  1195 This function is an internal primitive--use `make-frame' instead.  */ )
  1196   (Lisp_Object parms)
  1197 {
  1198   struct frame *f;
  1199   Lisp_Object frame, tem;
  1200   Lisp_Object name;
  1201   bool minibuffer_only = false;
  1202   bool undecorated = false, override_redirect = false;
  1203   long window_prompting = 0;
  1204   specpdl_ref count = SPECPDL_INDEX ();
  1205   Lisp_Object display;
  1206   struct pgtk_display_info *dpyinfo = NULL;
  1207   Lisp_Object parent, parent_frame;
  1208   struct kboard *kb;
  1209 
  1210   parms = Fcopy_alist (parms);
  1211 
  1212   /* Use this general default value to start with
  1213      until we know if this frame has a specified name.  */
  1214   Vx_resource_name = Vinvocation_name;
  1215 
  1216   display =
  1217     gui_display_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
  1218   if (BASE_EQ (display, Qunbound))
  1219     display =
  1220       gui_display_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
  1221   if (BASE_EQ (display, Qunbound))
  1222     display = Qnil;
  1223   dpyinfo = check_pgtk_display_info (display);
  1224   kb = dpyinfo->terminal->kboard;
  1225 
  1226   if (!dpyinfo->terminal->name)
  1227     error ("Terminal is not live, can't create new frames on it");
  1228 
  1229   name =
  1230     gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name",
  1231                          RES_TYPE_STRING);
  1232   if (!STRINGP (name) && !BASE_EQ (name, Qunbound) && !NILP (name))
  1233     error ("Invalid frame name--not a string or nil");
  1234 
  1235   if (STRINGP (name))
  1236     Vx_resource_name = name;
  1237 
  1238   /* See if parent window is specified.  */
  1239   parent =
  1240     gui_display_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL,
  1241                          RES_TYPE_NUMBER);
  1242   if (BASE_EQ (parent, Qunbound))
  1243     parent = Qnil;
  1244   if (!NILP (parent))
  1245     CHECK_NUMBER (parent);
  1246 
  1247   frame = Qnil;
  1248   tem =
  1249     gui_display_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer",
  1250                          "Minibuffer", RES_TYPE_SYMBOL);
  1251   if (EQ (tem, Qnone) || NILP (tem))
  1252     f = make_frame_without_minibuffer (Qnil, kb, display);
  1253   else if (EQ (tem, Qonly))
  1254     {
  1255       f = make_minibuffer_frame ();
  1256       minibuffer_only = true;
  1257     }
  1258   else if (WINDOWP (tem))
  1259     f = make_frame_without_minibuffer (tem, kb, display);
  1260   else
  1261     f = make_frame (true);
  1262 
  1263   parent_frame =
  1264     gui_display_get_arg (dpyinfo, parms, Qparent_frame, NULL, NULL,
  1265                          RES_TYPE_SYMBOL);
  1266   /* Accept parent-frame iff parent-id was not specified.  */
  1267   if (!NILP (parent)
  1268       || BASE_EQ (parent_frame, Qunbound)
  1269       || NILP (parent_frame)
  1270       || !FRAMEP (parent_frame)
  1271       || !FRAME_LIVE_P (XFRAME (parent_frame))
  1272       || !FRAME_PGTK_P (XFRAME (parent_frame)))
  1273     parent_frame = Qnil;
  1274 
  1275   fset_parent_frame (f, parent_frame);
  1276   store_frame_param (f, Qparent_frame, parent_frame);
  1277 
  1278   if (!NILP
  1279       (tem =
  1280        (gui_display_get_arg
  1281         (dpyinfo, parms, Qundecorated, NULL, NULL, RES_TYPE_BOOLEAN)))
  1282       && !(BASE_EQ (tem, Qunbound)))
  1283     undecorated = true;
  1284 
  1285   FRAME_UNDECORATED (f) = undecorated;
  1286   store_frame_param (f, Qundecorated, undecorated ? Qt : Qnil);
  1287 
  1288   if (!NILP
  1289       (tem =
  1290        (gui_display_get_arg
  1291         (dpyinfo, parms, Qoverride_redirect, NULL, NULL, RES_TYPE_BOOLEAN)))
  1292       && !(BASE_EQ (tem, Qunbound)))
  1293     override_redirect = true;
  1294 
  1295   FRAME_OVERRIDE_REDIRECT (f) = override_redirect;
  1296   store_frame_param (f, Qoverride_redirect, override_redirect ? Qt : Qnil);
  1297 
  1298   XSETFRAME (frame, f);
  1299 
  1300   f->terminal = dpyinfo->terminal;
  1301 
  1302   f->output_method = output_pgtk;
  1303   FRAME_X_OUTPUT (f) = xzalloc (sizeof *FRAME_X_OUTPUT (f));
  1304   FRAME_FONTSET (f) = -1;
  1305   FRAME_X_OUTPUT (f)->white_relief.pixel = -1;
  1306   FRAME_X_OUTPUT (f)->black_relief.pixel = -1;
  1307 
  1308   FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider =
  1309     gtk_css_provider_new ();
  1310   FRAME_X_OUTPUT (f)->scrollbar_background_css_provider =
  1311     gtk_css_provider_new ();
  1312 
  1313   fset_icon_name (f,
  1314                   gui_display_get_arg (dpyinfo, parms, Qicon_name, "iconName",
  1315                                        "Title", RES_TYPE_STRING));
  1316   if (!STRINGP (f->icon_name))
  1317     fset_icon_name (f, Qnil);
  1318 
  1319   FRAME_DISPLAY_INFO (f) = dpyinfo;
  1320 
  1321   /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe.  */
  1322   record_unwind_protect (do_unwind_create_frame, frame);
  1323 
  1324   /* These colors will be set anyway later, but it's important
  1325      to get the color reference counts right, so initialize them!  */
  1326   {
  1327     Lisp_Object black;
  1328 
  1329     /* Function x_decode_color can signal an error.  Make
  1330        sure to initialize color slots so that we won't try
  1331        to free colors we haven't allocated.  */
  1332     FRAME_FOREGROUND_PIXEL (f) = -1;
  1333     FRAME_BACKGROUND_PIXEL (f) = -1;
  1334     FRAME_X_OUTPUT (f)->cursor_color = -1;
  1335     FRAME_X_OUTPUT (f)->cursor_foreground_color = -1;
  1336     FRAME_X_OUTPUT (f)->border_pixel = -1;
  1337     FRAME_X_OUTPUT (f)->mouse_color = -1;
  1338 
  1339     black = build_string ("black");
  1340     FRAME_FOREGROUND_PIXEL (f)
  1341       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  1342     FRAME_BACKGROUND_PIXEL (f)
  1343       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  1344     FRAME_X_OUTPUT (f)->cursor_color
  1345       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  1346     FRAME_X_OUTPUT (f)->cursor_foreground_color
  1347       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  1348     FRAME_X_OUTPUT (f)->border_pixel
  1349       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  1350     FRAME_X_OUTPUT (f)->mouse_color
  1351       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  1352   }
  1353 
  1354   /* Specify the parent under which to make this X window.  */
  1355   if (!NILP (parent))
  1356     {
  1357       FRAME_X_OUTPUT (f)->parent_desc = (Window) XFIXNAT (parent);
  1358       FRAME_X_OUTPUT (f)->explicit_parent = true;
  1359     }
  1360   else
  1361     {
  1362       FRAME_X_OUTPUT (f)->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
  1363       FRAME_X_OUTPUT (f)->explicit_parent = false;
  1364     }
  1365 
  1366   /* Set the name; the functions to which we pass f expect the name to
  1367      be set.  */
  1368   if (BASE_EQ (name, Qunbound) || NILP (name))
  1369     {
  1370       fset_name (f, build_string (dpyinfo->x_id_name));
  1371       f->explicit_name = false;
  1372     }
  1373   else
  1374     {
  1375       fset_name (f, name);
  1376       f->explicit_name = true;
  1377       /* Use the frame's title when getting resources for this frame.  */
  1378       specbind (Qx_resource_name, name);
  1379     }
  1380 
  1381   register_font_driver (&ftcrfont_driver, f);
  1382 #ifdef HAVE_HARFBUZZ
  1383   register_font_driver (&ftcrhbfont_driver, f);
  1384 #endif  /* HAVE_HARFBUZZ */
  1385 
  1386   image_cache_refcount =
  1387     FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
  1388 
  1389   gui_default_parameter (f, parms, Qfont_backend, Qnil,
  1390                          "fontBackend", "FontBackend", RES_TYPE_STRING);
  1391 
  1392   /* Extract the window parameters from the supplied values
  1393      that are needed to determine window geometry.  */
  1394   pgtk_default_font_parameter (f, parms);
  1395   if (!FRAME_FONT (f))
  1396     {
  1397       delete_frame (frame, Qnoelisp);
  1398       error ("Invalid frame font");
  1399     }
  1400 
  1401   gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
  1402                          "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
  1403 
  1404   if (NILP (Fassq (Qinternal_border_width, parms)))
  1405     {
  1406       Lisp_Object value;
  1407 
  1408       value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width,
  1409                                    "internalBorder", "internalBorder",
  1410                                    RES_TYPE_NUMBER);
  1411       if (!BASE_EQ (value, Qunbound))
  1412         parms = Fcons (Fcons (Qinternal_border_width, value), parms);
  1413     }
  1414 
  1415   gui_default_parameter (f, parms, Qinternal_border_width,
  1416                          make_fixnum (0),
  1417                          "internalBorderWidth", "internalBorderWidth",
  1418                          RES_TYPE_NUMBER);
  1419 
  1420   /* Same for child frames.  */
  1421   if (NILP (Fassq (Qchild_frame_border_width, parms)))
  1422     {
  1423       Lisp_Object value;
  1424 
  1425       value = gui_display_get_arg (dpyinfo, parms, Qchild_frame_border_width,
  1426                                    "childFrameBorder", "childFrameBorder",
  1427                                    RES_TYPE_NUMBER);
  1428       if (! BASE_EQ (value, Qunbound))
  1429         parms = Fcons (Fcons (Qchild_frame_border_width, value),
  1430                        parms);
  1431 
  1432     }
  1433 
  1434   gui_default_parameter (f, parms, Qchild_frame_border_width, Qnil,
  1435                          "childFrameBorderWidth", "childFrameBorderWidth",
  1436                          RES_TYPE_NUMBER);
  1437   gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
  1438                          NULL, NULL, RES_TYPE_NUMBER);
  1439   gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
  1440                          NULL, NULL, RES_TYPE_NUMBER);
  1441   gui_default_parameter (f, parms, Qvertical_scroll_bars,
  1442                          Qright,
  1443                          "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
  1444   gui_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
  1445                          "horizontalScrollBars", "ScrollBars",
  1446                          RES_TYPE_SYMBOL);
  1447   /* Also do the stuff which must be set before the window exists.  */
  1448   gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
  1449                          "foreground", "Foreground", RES_TYPE_STRING);
  1450   gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
  1451                          "background", "Background", RES_TYPE_STRING);
  1452   gui_default_parameter (f, parms, Qmouse_color, build_string ("black"),
  1453                          "pointerColor", "Foreground", RES_TYPE_STRING);
  1454   gui_default_parameter (f, parms, Qborder_color, build_string ("black"),
  1455                          "borderColor", "BorderColor", RES_TYPE_STRING);
  1456   gui_default_parameter (f, parms, Qscreen_gamma, Qnil,
  1457                          "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
  1458   gui_default_parameter (f, parms, Qline_spacing, Qnil,
  1459                          "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
  1460   gui_default_parameter (f, parms, Qleft_fringe, Qnil,
  1461                          "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
  1462   gui_default_parameter (f, parms, Qright_fringe, Qnil,
  1463                          "rightFringe", "RightFringe", RES_TYPE_NUMBER);
  1464   gui_default_parameter (f, parms, Qno_special_glyphs, Qnil,
  1465                          NULL, NULL, RES_TYPE_BOOLEAN);
  1466 
  1467   gui_default_parameter (f, parms, Qscroll_bar_foreground, Qnil,
  1468                          "scrollBarForeground", "ScrollBarForeground",
  1469                          RES_TYPE_STRING);
  1470   gui_default_parameter (f, parms, Qscroll_bar_background, Qnil,
  1471                          "scrollBarBackground", "ScrollBarBackground",
  1472                          RES_TYPE_STRING);
  1473 
  1474   /* Init faces before gui_default_parameter is called for the
  1475      scroll-bar-width parameter because otherwise we end up in
  1476      init_iterator with a null face cache, which should not happen.  */
  1477   init_frame_faces (f);
  1478 
  1479   /* We have to call adjust_frame_size here since otherwise
  1480      pgtk_set_tool_bar_lines will already work with the character
  1481      sizes installed by init_frame_faces while the frame's pixel size
  1482      is still calculated from a character size of 1 and we
  1483      subsequently hit the (height >= 0) assertion in
  1484      window_box_height.
  1485 
  1486      The non-pixelwise code apparently worked around this because it
  1487      had one frame line vs one toolbar line which left us with a zero
  1488      root window height which was obviously wrong as well ...
  1489 
  1490      Also process `min-width' and `min-height' parameters right here
  1491      because `frame-windows-min-size' needs them.  */
  1492   tem = gui_display_get_arg (dpyinfo, parms, Qmin_width, NULL, NULL,
  1493                              RES_TYPE_NUMBER);
  1494   if (NUMBERP (tem))
  1495     store_frame_param (f, Qmin_width, tem);
  1496   tem = gui_display_get_arg (dpyinfo, parms, Qmin_height, NULL, NULL,
  1497                              RES_TYPE_NUMBER);
  1498   if (NUMBERP (tem))
  1499     store_frame_param (f, Qmin_height, tem);
  1500   adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
  1501                      FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, true,
  1502                      Qx_create_frame_1);
  1503 
  1504   /* Set the menu-bar-lines and tool-bar-lines parameters.  We don't
  1505      look up the X resources controlling the menu-bar and tool-bar
  1506      here; they are processed specially at startup, and reflected in
  1507      the values of the mode variables.  */
  1508 
  1509   gui_default_parameter (f, parms, Qmenu_bar_lines,
  1510                          NILP (Vmenu_bar_mode)
  1511                          ? make_fixnum (0) : make_fixnum (1),
  1512                          NULL, NULL, RES_TYPE_NUMBER);
  1513   gui_default_parameter (f, parms, Qtab_bar_lines,
  1514                          NILP (Vtab_bar_mode)
  1515                          ? make_fixnum (0) : make_fixnum (1),
  1516                          NULL, NULL, RES_TYPE_NUMBER);
  1517   gui_default_parameter (f, parms, Qtool_bar_lines,
  1518                          NILP (Vtool_bar_mode)
  1519                          ? make_fixnum (0) : make_fixnum (1),
  1520                          NULL, NULL, RES_TYPE_NUMBER);
  1521 
  1522   gui_default_parameter (f, parms, Qbuffer_predicate, Qnil,
  1523                          "bufferPredicate", "BufferPredicate",
  1524                          RES_TYPE_SYMBOL);
  1525   gui_default_parameter (f, parms, Qtitle, Qnil,
  1526                          "title", "Title", RES_TYPE_STRING);
  1527   gui_default_parameter (f, parms, Qwait_for_wm, Qt,
  1528                          "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
  1529   gui_default_parameter (f, parms, Qtool_bar_position,
  1530                          FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL);
  1531   gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
  1532                          "inhibitDoubleBuffering", "InhibitDoubleBuffering",
  1533                          RES_TYPE_BOOLEAN);
  1534 
  1535   /* Compute the size of the X window.  */
  1536   window_prompting =
  1537     gui_figure_window_size (f, parms, true, true);
  1538 
  1539   tem =
  1540     gui_display_get_arg (dpyinfo, parms, Qunsplittable, 0, 0,
  1541                          RES_TYPE_BOOLEAN);
  1542   f->no_split = minibuffer_only || EQ (tem, Qt);
  1543 
  1544   xg_create_frame_widgets (f);
  1545   pgtk_set_event_handler (f);
  1546 
  1547   if (FRAME_GTK_OUTER_WIDGET (f))
  1548     gtk_widget_realize (FRAME_GTK_OUTER_WIDGET (f));
  1549 
  1550   /* Many callers (including the Lisp functions that call
  1551      FRAME_SCALE_FACTOR) expect the widget to be realized.  */
  1552   if (FRAME_GTK_WIDGET (f))
  1553     gtk_widget_realize (FRAME_GTK_WIDGET (f));
  1554 
  1555 #define INSTALL_CURSOR(FIELD, NAME) \
  1556   FRAME_X_OUTPUT (f)->FIELD = gdk_cursor_new_for_display (FRAME_X_DISPLAY (f), GDK_ ## NAME)
  1557 
  1558   INSTALL_CURSOR (text_cursor, XTERM);
  1559   INSTALL_CURSOR (nontext_cursor, LEFT_PTR);
  1560   INSTALL_CURSOR (modeline_cursor, XTERM);
  1561   INSTALL_CURSOR (hand_cursor, HAND2);
  1562   INSTALL_CURSOR (hourglass_cursor, WATCH);
  1563   INSTALL_CURSOR (horizontal_drag_cursor, SB_H_DOUBLE_ARROW);
  1564   INSTALL_CURSOR (vertical_drag_cursor, SB_V_DOUBLE_ARROW);
  1565   INSTALL_CURSOR (left_edge_cursor, LEFT_SIDE);
  1566   INSTALL_CURSOR (right_edge_cursor, RIGHT_SIDE);
  1567   INSTALL_CURSOR (top_edge_cursor, TOP_SIDE);
  1568   INSTALL_CURSOR (bottom_edge_cursor, BOTTOM_SIDE);
  1569   INSTALL_CURSOR (top_left_corner_cursor, TOP_LEFT_CORNER);
  1570   INSTALL_CURSOR (top_right_corner_cursor, TOP_RIGHT_CORNER);
  1571   INSTALL_CURSOR (bottom_right_corner_cursor, BOTTOM_RIGHT_CORNER);
  1572   INSTALL_CURSOR (bottom_left_corner_cursor, BOTTOM_LEFT_CORNER);
  1573 
  1574 #undef INSTALL_CURSOR
  1575 
  1576   /* Now consider the frame official.  */
  1577   f->terminal->reference_count++;
  1578   FRAME_DISPLAY_INFO (f)->reference_count++;
  1579   Vframe_list = Fcons (frame, Vframe_list);
  1580 
  1581   /* We need to do this after creating the X window, so that the
  1582      icon-creation functions can say whose icon they're describing.  */
  1583   gui_default_parameter (f, parms, Qicon_type, Qt,
  1584                          "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN);
  1585 
  1586   gui_default_parameter (f, parms, Qauto_raise, Qnil,
  1587                          "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
  1588   gui_default_parameter (f, parms, Qauto_lower, Qnil,
  1589                          "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
  1590   gui_default_parameter (f, parms, Qcursor_type, Qbox,
  1591                          "cursorType", "CursorType", RES_TYPE_SYMBOL);
  1592   gui_default_parameter (f, parms, Qscroll_bar_width, Qnil,
  1593                          "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
  1594   gui_default_parameter (f, parms, Qscroll_bar_height, Qnil,
  1595                          "scrollBarHeight", "ScrollBarHeight",
  1596                          RES_TYPE_NUMBER);
  1597   gui_default_parameter (f, parms, Qalpha, Qnil,
  1598                          "alpha", "Alpha", RES_TYPE_NUMBER);
  1599   gui_default_parameter (f, parms, Qalpha_background, Qnil,
  1600                          "alphaBackground", "AlphaBackground", RES_TYPE_NUMBER);
  1601 
  1602   if (!NILP (parent_frame))
  1603     {
  1604       struct frame *p = XFRAME (parent_frame);
  1605 
  1606       block_input ();
  1607 
  1608       GtkWidget *fixed = FRAME_GTK_WIDGET (f);
  1609       GtkWidget *fixed_of_p = FRAME_GTK_WIDGET (p);
  1610       GtkWidget *whbox_of_f = gtk_widget_get_parent (fixed);
  1611       g_object_ref (fixed);
  1612       gtk_container_remove (GTK_CONTAINER (whbox_of_f), fixed);
  1613       gtk_fixed_put (GTK_FIXED (fixed_of_p), fixed, f->left_pos, f->top_pos);
  1614       gtk_widget_show_all (fixed);
  1615       g_object_unref (fixed);
  1616 
  1617       gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
  1618       FRAME_GTK_OUTER_WIDGET (f) = NULL;
  1619       FRAME_OUTPUT_DATA (f)->vbox_widget = NULL;
  1620       FRAME_OUTPUT_DATA (f)->hbox_widget = NULL;
  1621       FRAME_OUTPUT_DATA (f)->menubar_widget = NULL;
  1622       FRAME_OUTPUT_DATA (f)->toolbar_widget = NULL;
  1623       FRAME_OUTPUT_DATA (f)->ttip_widget = NULL;
  1624       FRAME_OUTPUT_DATA (f)->ttip_lbl = NULL;
  1625       FRAME_OUTPUT_DATA (f)->ttip_window = NULL;
  1626 
  1627       unblock_input ();
  1628     }
  1629 
  1630   if (FRAME_GTK_OUTER_WIDGET (f))
  1631     {
  1632       GList *w = gtk_container_get_children (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)));
  1633       for (; w != NULL; w = w->next)
  1634         gtk_widget_show_all (GTK_WIDGET (w->data));
  1635     }
  1636 
  1637   gui_default_parameter (f, parms, Qno_focus_on_map, Qnil,
  1638                          NULL, NULL, RES_TYPE_BOOLEAN);
  1639   gui_default_parameter (f, parms, Qno_accept_focus, Qnil,
  1640                          NULL, NULL, RES_TYPE_BOOLEAN);
  1641 
  1642   /* Create the menu bar.  */
  1643   if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
  1644     {
  1645       /* If this signals an error, we haven't set size hints for the
  1646          frame and we didn't make it visible.  */
  1647       initialize_frame_menubar (f);
  1648 
  1649     }
  1650 
  1651   /* Consider frame official, now.  */
  1652   f->can_set_window_size = true;
  1653 
  1654   /* Tell the server what size and position, etc, we want, and how
  1655      badly we want them.  This should be done after we have the menu
  1656      bar so that its size can be taken into account.  */
  1657   block_input ();
  1658   xg_wm_set_size_hint (f, window_prompting, false);
  1659   unblock_input ();
  1660 
  1661   adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
  1662                      0, true, Qx_create_frame_2);
  1663 
  1664   /* Process fullscreen parameter here in the hope that normalizing a
  1665      fullheight/fullwidth frame will produce the size set by the last
  1666      adjust_frame_size call.  */
  1667   gui_default_parameter (f, parms, Qfullscreen, Qnil,
  1668                          "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
  1669 
  1670   /* Make the window appear on the frame and enable display, unless
  1671      the caller says not to.  However, with explicit parent, Emacs
  1672      cannot control visibility, so don't try.  */
  1673   if (!FRAME_X_OUTPUT (f)->explicit_parent)
  1674     {
  1675       /* When called from `x-create-frame-with-faces' visibility is
  1676          always explicitly nil.  */
  1677       Lisp_Object visibility
  1678         = gui_display_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
  1679                                RES_TYPE_SYMBOL);
  1680       Lisp_Object height
  1681         = gui_display_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
  1682       Lisp_Object width
  1683         = gui_display_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
  1684 
  1685       if (EQ (visibility, Qicon))
  1686         {
  1687           f->was_invisible = true;
  1688           pgtk_iconify_frame (f);
  1689         }
  1690       else
  1691         {
  1692           if (BASE_EQ (visibility, Qunbound))
  1693             visibility = Qt;
  1694 
  1695           if (!NILP (visibility))
  1696             pgtk_make_frame_visible (f);
  1697           else
  1698             f->was_invisible = true;
  1699         }
  1700 
  1701       /* Leave f->was_invisible true only if height or width were
  1702          specified too.  This takes effect only when we are not called
  1703          from `x-create-frame-with-faces' (see above comment).  */
  1704       f->was_invisible
  1705         = (f->was_invisible
  1706            && (!BASE_EQ (height, Qunbound) || !BASE_EQ (width, Qunbound)));
  1707 
  1708       store_frame_param (f, Qvisibility, visibility);
  1709     }
  1710 
  1711   /* Works iff frame has been already mapped.  */
  1712   gui_default_parameter (f, parms, Qskip_taskbar, Qnil,
  1713                          NULL, NULL, RES_TYPE_BOOLEAN);
  1714   /* The `z-group' parameter works only for visible frames.  */
  1715   gui_default_parameter (f, parms, Qz_group, Qnil,
  1716                          NULL, NULL, RES_TYPE_SYMBOL);
  1717 
  1718   /* Initialize `default-minibuffer-frame' in case this is the first
  1719      frame on this terminal.  */
  1720   if (FRAME_HAS_MINIBUF_P (f)
  1721       && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
  1722           || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
  1723     kset_default_minibuffer_frame (kb, frame);
  1724 
  1725   /* All remaining specified parameters, which have not been "used"
  1726      by gui_display_get_arg and friends, now go in the misc. alist of the frame.  */
  1727   for (tem = parms; CONSP (tem); tem = XCDR (tem))
  1728     if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
  1729       fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
  1730 
  1731   FRAME_X_OUTPUT (f)->border_color_css_provider = NULL;
  1732 
  1733   FRAME_X_OUTPUT (f)->cr_surface_visible_bell = NULL;
  1734   FRAME_X_OUTPUT (f)->atimer_visible_bell = NULL;
  1735   FRAME_X_OUTPUT (f)->watched_scale_factor = 1.0;
  1736   struct timespec ts = make_timespec (1, 0);
  1737   FRAME_X_OUTPUT (f)->scale_factor_atimer = start_atimer(ATIMER_CONTINUOUS,
  1738                                                          ts,
  1739                                                          update_watched_scale_factor,
  1740                                                          f);
  1741 
  1742   /* Make sure windows on this frame appear in calls to next-window
  1743      and similar functions.  */
  1744   Vwindow_list = Qnil;
  1745 
  1746   return unbind_to (count, frame);
  1747 }
  1748 
  1749 /* Restack frame F1 below frame F2, above if ABOVE_FLAG is non-nil.
  1750    In practice this is a two-step action: The first step removes F1's
  1751    window-system window from the display.  The second step reinserts
  1752    F1's window below (above if ABOVE_FLAG is true) that of F2.  */
  1753 static void
  1754 pgtk_frame_restack (struct frame *f1, struct frame *f2, bool above_flag)
  1755 {
  1756   block_input ();
  1757   xg_frame_restack (f1, f2, above_flag);
  1758   unblock_input ();
  1759 }
  1760 
  1761 DEFUN ("pgtk-frame-restack", Fpgtk_frame_restack, Spgtk_frame_restack, 2, 3, 0,
  1762        doc: /* Restack FRAME1 below FRAME2.
  1763 This means that if both frames are visible and the display areas of
  1764 these frames overlap, FRAME2 (partially) obscures FRAME1.  If optional
  1765 third argument ABOVE is non-nil, restack FRAME1 above FRAME2.  This
  1766 means that if both frames are visible and the display areas of these
  1767 frames overlap, FRAME1 (partially) obscures FRAME2.
  1768 
  1769 This may be thought of as an atomic action performed in two steps: The
  1770 first step removes FRAME1's window-step window from the display.  The
  1771 second step reinserts FRAME1's window below (above if ABOVE is true)
  1772 that of FRAME2.  Hence the position of FRAME2 in its display's Z
  1773 \(stacking) order relative to all other frames excluding FRAME1 remains
  1774 unaltered.
  1775 
  1776 Some window managers may refuse to restack windows.  */)
  1777   (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above)
  1778 {
  1779   struct frame *f1 = decode_live_frame (frame1);
  1780   struct frame *f2 = decode_live_frame (frame2);
  1781 
  1782   if (!(FRAME_GTK_OUTER_WIDGET (f1) && FRAME_GTK_OUTER_WIDGET (f2)))
  1783     error ("Cannot restack frames");
  1784   pgtk_frame_restack (f1, f2, !NILP (above));
  1785   return Qt;
  1786 }
  1787 
  1788 #ifdef HAVE_GSETTINGS
  1789 
  1790 #define RESOURCE_KEY_MAX_LEN 128
  1791 #define SCHEMA_ID "org.gnu.emacs.defaults"
  1792 #define PATH_FOR_CLASS_TYPE "/org/gnu/emacs/defaults-by-class/"
  1793 #define PATH_PREFIX_FOR_NAME_TYPE "/org/gnu/emacs/defaults-by-name/"
  1794 
  1795 static inline int
  1796 pgtk_is_lower_char (int c)
  1797 {
  1798   return c >= 'a' && c <= 'z';
  1799 }
  1800 
  1801 static inline int
  1802 pgtk_is_upper_char (int c)
  1803 {
  1804   return c >= 'A' && c <= 'Z';
  1805 }
  1806 
  1807 static inline int
  1808 pgtk_is_numeric_char (int c)
  1809 {
  1810   return c >= '0' && c <= '9';
  1811 }
  1812 
  1813 static GSettings *
  1814 parse_resource_key (const char *res_key, char *setting_key)
  1815 {
  1816   char path[32 + RESOURCE_KEY_MAX_LEN];
  1817   const char *sp = res_key;
  1818   char *dp;
  1819 
  1820   /*
  1821    * res_key="emacs.cursorBlink"
  1822    *   -> path="/org/gnu/emacs/defaults-by-name/emacs/"
  1823    *      setting_key="cursor-blink"
  1824    *
  1825    * res_key="Emacs.CursorBlink"
  1826    *   -> path="/org/gnu/emacs/defaults-by-class/"
  1827    *      setting_key="cursor-blink"
  1828    *
  1829    * Returns GSettings* if setting_key exists in schema, otherwise NULL.
  1830    */
  1831 
  1832   /* generate path */
  1833   if (pgtk_is_upper_char (*sp))
  1834     {
  1835       /* First letter is upper case. It should be "Emacs",
  1836        * but don't care.
  1837        */
  1838       strcpy (path, PATH_FOR_CLASS_TYPE);
  1839       while (*sp != '\0')
  1840         {
  1841           if (*sp == '.')
  1842             break;
  1843           sp++;
  1844         }
  1845     }
  1846   else
  1847     {
  1848       strcpy (path, PATH_PREFIX_FOR_NAME_TYPE);
  1849       dp = path + strlen (path);
  1850       while (*sp != '\0')
  1851         {
  1852           int c = *sp;
  1853           if (c == '.')
  1854             break;
  1855           if (pgtk_is_lower_char (c))
  1856             (void) 0;           /* lower -> NOP */
  1857           else if (pgtk_is_upper_char (c))
  1858             c = c - 'A' + 'a';  /* upper -> lower */
  1859           else if (pgtk_is_numeric_char (c))
  1860             (void) 0;           /* numeric -> NOP */
  1861           else
  1862             return NULL;        /* invalid */
  1863           *dp++ = c;
  1864           sp++;
  1865         }
  1866       *dp++ = '/';              /* must ends with '/' */
  1867       *dp = '\0';
  1868     }
  1869 
  1870   if (*sp++ != '.')
  1871     return NULL;
  1872 
  1873   /* generate setting_key */
  1874   dp = setting_key;
  1875   while (*sp != '\0')
  1876     {
  1877       int c = *sp;
  1878       if (pgtk_is_lower_char (c))
  1879         (void) 0;               /* lower -> NOP */
  1880       else if (pgtk_is_upper_char (c))
  1881         {
  1882           c = c - 'A' + 'a';    /* upper -> lower */
  1883           if (dp != setting_key)
  1884             *dp++ = '-';        /* store '-' unless first char */
  1885         }
  1886       else if (pgtk_is_numeric_char (c))
  1887         (void) 0;               /* numeric -> NOP */
  1888       else
  1889         return NULL;            /* invalid */
  1890 
  1891       *dp++ = c;
  1892       sp++;
  1893     }
  1894   *dp = '\0';
  1895 
  1896   /* check existence of setting_key */
  1897   GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default ();
  1898   GSettingsSchema *scm = g_settings_schema_source_lookup (ssrc, SCHEMA_ID, TRUE);
  1899   if (!scm)
  1900     return NULL;        /* *.schema.xml is not installed. */
  1901   if (!g_settings_schema_has_key (scm, setting_key))
  1902     {
  1903       g_settings_schema_unref (scm);
  1904       return NULL;
  1905     }
  1906 
  1907   /* create GSettings, and return it */
  1908   GSettings *gs = g_settings_new_full (scm, NULL, path);
  1909 
  1910   g_settings_schema_unref (scm);
  1911   return gs;
  1912 }
  1913 
  1914 const char *
  1915 pgtk_get_defaults_value (const char *key)
  1916 {
  1917   char skey[(RESOURCE_KEY_MAX_LEN + 1) * 2];
  1918 
  1919   if (strlen (key) >= RESOURCE_KEY_MAX_LEN)
  1920     error ("resource key too long.");
  1921 
  1922   GSettings *gs = parse_resource_key (key, skey);
  1923   if (gs == NULL)
  1924     {
  1925       return NULL;
  1926     }
  1927 
  1928   gchar *str = g_settings_get_string (gs, skey);
  1929 
  1930   /* There is no timing to free str.
  1931    * So, copy it here and free it.
  1932    *
  1933    * MEMO: Resource values for emacs shouldn't need such a long string value.
  1934    */
  1935   static char holder[128];
  1936   strncpy (holder, str, 128);
  1937   holder[127] = '\0';
  1938 
  1939   g_object_unref (gs);
  1940   g_free (str);
  1941   return holder[0] != '\0' ? holder : NULL;
  1942 }
  1943 
  1944 static void
  1945 pgtk_set_defaults_value (const char *key, const char *value)
  1946 {
  1947   char skey[(RESOURCE_KEY_MAX_LEN + 1) * 2];
  1948 
  1949   if (strlen (key) >= RESOURCE_KEY_MAX_LEN)
  1950     error ("resource key too long.");
  1951 
  1952   GSettings *gs = parse_resource_key (key, skey);
  1953   if (gs == NULL)
  1954     error ("unknown resource key.");
  1955 
  1956   if (value != NULL)
  1957     {
  1958       g_settings_set_string (gs, skey, value);
  1959     }
  1960   else
  1961     {
  1962       g_settings_reset (gs, skey);
  1963     }
  1964 
  1965   g_object_unref (gs);
  1966 }
  1967 
  1968 #undef RESOURCE_KEY_MAX_LEN
  1969 #undef SCHEMA_ID
  1970 #undef PATH_FOR_CLASS_TYPE
  1971 #undef PATH_PREFIX_FOR_NAME_TYPE
  1972 
  1973 #else /* not HAVE_GSETTINGS */
  1974 
  1975 const char *
  1976 pgtk_get_defaults_value (const char *key)
  1977 {
  1978   return NULL;
  1979 }
  1980 
  1981 static void
  1982 pgtk_set_defaults_value (const char *key, const char *value)
  1983 {
  1984   error ("gsettings not supported.");
  1985 }
  1986 
  1987 #endif
  1988 
  1989 
  1990 DEFUN ("pgtk-set-resource", Fpgtk_set_resource, Spgtk_set_resource, 2, 2, 0,
  1991        doc: /* Set the value of ATTRIBUTE, of class CLASS, as VALUE, into defaults database. */ )
  1992   (Lisp_Object attribute, Lisp_Object value)
  1993 {
  1994   check_window_system (NULL);
  1995 
  1996   CHECK_STRING (attribute);
  1997   if (!NILP (value))
  1998     CHECK_STRING (value);
  1999 
  2000   char *res = SSDATA (Vx_resource_name);
  2001   char *attr = SSDATA (attribute);
  2002   if (attr[0] >= 'A' && attr[0] <= 'Z')
  2003     res = SSDATA (Vx_resource_class);
  2004 
  2005   char *key = g_strdup_printf ("%s.%s", res, attr);
  2006 
  2007   pgtk_set_defaults_value (key, NILP (value) ? NULL : SSDATA (value));
  2008 
  2009   return Qnil;
  2010 }
  2011 
  2012 
  2013 DEFUN ("x-server-max-request-size", Fx_server_max_request_size, Sx_server_max_request_size, 0, 1, 0,
  2014        doc: /* This function is a no-op.  It is only present for completeness.  */ )
  2015   (Lisp_Object terminal)
  2016 {
  2017   check_pgtk_display_info (terminal);
  2018   /* This function has no real equivalent under PGTK.  Return nil to
  2019      indicate this. */
  2020   return Qnil;
  2021 }
  2022 
  2023 
  2024 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
  2025        doc: /* Return the number of screens on the display server TERMINAL.
  2026 The optional argument TERMINAL specifies which display to ask about.
  2027 TERMINAL should be a terminal object, a frame or a display name (a string).
  2028 If omitted or nil, that stands for the selected frame's display.
  2029 
  2030 Note: "screen" here is not in X11's.  For the number of physical monitors,
  2031 use `(length \(display-monitor-attributes-list TERMINAL))' instead.  */)
  2032   (Lisp_Object terminal)
  2033 {
  2034   check_pgtk_display_info (terminal);
  2035   return make_fixnum (1);
  2036 }
  2037 
  2038 
  2039 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
  2040        doc: /* Return the height in millimeters of the display TERMINAL.
  2041 The optional argument TERMINAL specifies which display to ask about.
  2042 TERMINAL should be a terminal object, a frame or a display name (a string).
  2043 If omitted or nil, that stands for the selected frame's display.
  2044 
  2045 On \"multi-monitor\" setups this refers to the height in millimeters for
  2046 all physical monitors associated with TERMINAL.  To get information
  2047 for each physical monitor, use `display-monitor-attributes-list'.  */)
  2048   (Lisp_Object terminal)
  2049 {
  2050   struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
  2051   GdkDisplay *gdpy;
  2052   gint n_monitors, i;
  2053   int height_mm_at_0 = 0, height_mm_at_other = 0;
  2054 
  2055   block_input ();
  2056   gdpy = dpyinfo->gdpy;
  2057   n_monitors = gdk_display_get_n_monitors (gdpy);
  2058 
  2059   for (i = 0; i < n_monitors; ++i)
  2060     {
  2061       GdkRectangle rec;
  2062 
  2063       GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
  2064       gdk_monitor_get_geometry (monitor, &rec);
  2065 
  2066       int mm = gdk_monitor_get_height_mm (monitor);
  2067 
  2068       if (rec.y == 0)
  2069         height_mm_at_0 = max (height_mm_at_0, mm);
  2070       else
  2071         height_mm_at_other += mm;
  2072     }
  2073 
  2074   unblock_input ();
  2075 
  2076   return make_fixnum (height_mm_at_0 + height_mm_at_other);
  2077 }
  2078 
  2079 
  2080 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
  2081        doc: /* Return the width in millimeters of the display TERMINAL.
  2082 The optional argument TERMINAL specifies which display to ask about.
  2083 TERMINAL should be a terminal object, a frame or a display name (a string).
  2084 If omitted or nil, that stands for the selected frame's display.
  2085 
  2086 On \"multi-monitor\" setups this refers to the width in millimeters for
  2087 all physical monitors associated with TERMINAL.  To get information
  2088 for each physical monitor, use `display-monitor-attributes-list'.  */)
  2089   (Lisp_Object terminal)
  2090 {
  2091   struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
  2092   GdkDisplay *gdpy;
  2093   gint n_monitors, i;
  2094   int width_mm_at_0 = 0, width_mm_at_other = 0;
  2095 
  2096   block_input ();
  2097   gdpy = dpyinfo->gdpy;
  2098   n_monitors = gdk_display_get_n_monitors (gdpy);
  2099 
  2100   for (i = 0; i < n_monitors; ++i)
  2101     {
  2102       GdkRectangle rec;
  2103 
  2104       GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
  2105       gdk_monitor_get_geometry (monitor, &rec);
  2106 
  2107       int mm = gdk_monitor_get_width_mm (monitor);
  2108 
  2109       if (rec.x == 0)
  2110         width_mm_at_0 = max (width_mm_at_0, mm);
  2111       else
  2112         width_mm_at_other += mm;
  2113     }
  2114 
  2115   unblock_input ();
  2116 
  2117   return make_fixnum (width_mm_at_0 + width_mm_at_other);
  2118 }
  2119 
  2120 
  2121 DEFUN ("x-display-backing-store", Fx_display_backing_store, Sx_display_backing_store, 0, 1, 0,
  2122        doc: /* Return an indication of whether the display TERMINAL does backing store.
  2123 The value may be `buffered', `retained', or `non-retained'.
  2124 The optional argument TERMINAL specifies which display to ask about.
  2125 TERMINAL should be a terminal object, a frame or a display name (a string).
  2126 If omitted or nil, that stands for the selected frame's display.  */)
  2127   (Lisp_Object terminal)
  2128 {
  2129   check_pgtk_display_info (terminal);
  2130   return Qnil;
  2131 }
  2132 
  2133 
  2134 DEFUN ("x-display-visual-class", Fx_display_visual_class, Sx_display_visual_class, 0, 1, 0,
  2135        doc: /* Return the visual class of the display TERMINAL.
  2136 The value is one of the symbols `static-gray', `gray-scale',
  2137 `static-color', `pseudo-color', `true-color', or `direct-color'.
  2138 
  2139 The optional argument TERMINAL specifies which display to ask about.
  2140 TERMINAL should a terminal object, a frame or a display name (a string).
  2141 If omitted or nil, that stands for the selected frame's display.
  2142 
  2143 On PGTK, always return true-color.  */)
  2144   (Lisp_Object terminal)
  2145 {
  2146   return intern ("true-color");
  2147 }
  2148 
  2149 
  2150 DEFUN ("x-display-save-under", Fx_display_save_under, Sx_display_save_under, 0, 1, 0,
  2151        doc: /* Return t if TERMINAL supports the save-under feature.
  2152 The optional argument TERMINAL specifies which display to ask about.
  2153 TERMINAL should be a terminal object, a frame or a display name (a string).
  2154 If omitted or nil, that stands for the selected frame's display.  */)
  2155   (Lisp_Object terminal)
  2156 {
  2157   check_pgtk_display_info (terminal);
  2158   return Qnil;
  2159 }
  2160 
  2161 
  2162 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection, 1, 3, 0,
  2163        doc: /* Open a connection to a display server.
  2164 DISPLAY is the name of the display to connect to.
  2165 Optional second arg XRM-STRING is a string of resources in xrdb format.
  2166 If the optional third arg MUST-SUCCEED is non-nil,
  2167 terminate Emacs if we can't open the connection.  */)
  2168   (Lisp_Object display, Lisp_Object resource_string, Lisp_Object must_succeed)
  2169 {
  2170   struct pgtk_display_info *dpyinfo;
  2171 
  2172   if (NILP (display))
  2173     display = build_string ("");
  2174 
  2175   CHECK_STRING (display);
  2176 
  2177   dpyinfo = pgtk_term_init (display, SSDATA (Vx_resource_name));
  2178   if (dpyinfo == 0)
  2179     {
  2180       if (!NILP (must_succeed))
  2181         fatal ("Display on %s not responding.\n", SSDATA (display));
  2182       else
  2183         error ("Display on %s not responding.\n", SSDATA (display));
  2184     }
  2185 
  2186   return Qnil;
  2187 }
  2188 
  2189 
  2190 DEFUN ("x-close-connection", Fx_close_connection, Sx_close_connection, 1, 1, 0,
  2191        doc: /* Close the connection to TERMINAL's display server.
  2192 For TERMINAL, specify a terminal object, a frame or a display name (a
  2193 string).  If TERMINAL is nil, that stands for the selected frame's
  2194 terminal.  */)
  2195   (Lisp_Object terminal)
  2196 {
  2197   struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
  2198 
  2199   if (dpyinfo->reference_count > 0)
  2200     error ("Display still has frames on it");
  2201 
  2202   pgtk_delete_terminal (dpyinfo->terminal);
  2203 
  2204   return Qnil;
  2205 }
  2206 
  2207 
  2208 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
  2209        doc: /* Return the list of display names that Emacs has connections to.  */)
  2210   (void)
  2211 {
  2212   Lisp_Object result = Qnil;
  2213   struct pgtk_display_info *ndi;
  2214 
  2215   for (ndi = x_display_list; ndi; ndi = ndi->next)
  2216     result = Fcons (XCAR (ndi->name_list_element), result);
  2217 
  2218   return result;
  2219 }
  2220 
  2221 DEFUN ("pgtk-font-name", Fpgtk_font_name, Spgtk_font_name, 1, 1, 0,
  2222        doc: /* Determine font PostScript or family name for font NAME.
  2223 NAME should be a string containing either the font name or an XLFD
  2224 font descriptor.  If string contains `fontset' and not
  2225 `fontset-startup', it is left alone. */)
  2226   (Lisp_Object name)
  2227 {
  2228   char *nm;
  2229   CHECK_STRING (name);
  2230   nm = SSDATA (name);
  2231 
  2232   if (nm[0] != '-')
  2233     return name;
  2234   if (strstr (nm, "fontset") && !strstr (nm, "fontset-startup"))
  2235     return name;
  2236 
  2237   char *str = pgtk_xlfd_to_fontname (SSDATA (name));
  2238   name = build_string (str);
  2239   xfree (str);
  2240   return name;
  2241 }
  2242 
  2243 /* ==========================================================================
  2244 
  2245     Miscellaneous functions not called through hooks
  2246 
  2247    ========================================================================== */
  2248 
  2249 /* Called from frame.c.  */
  2250 struct pgtk_display_info *
  2251 check_x_display_info (Lisp_Object frame)
  2252 {
  2253   return check_pgtk_display_info (frame);
  2254 }
  2255 
  2256 void
  2257 pgtk_set_scroll_bar_default_width (struct frame *f)
  2258 {
  2259   int unit = FRAME_COLUMN_WIDTH (f);
  2260   int minw = xg_get_default_scrollbar_width (f);
  2261   /* A minimum width of 14 doesn't look good for toolkit scroll bars.  */
  2262   FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + unit - 1) / unit;
  2263   FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw;
  2264 }
  2265 
  2266 void
  2267 pgtk_set_scroll_bar_default_height (struct frame *f)
  2268 {
  2269   int height = FRAME_LINE_HEIGHT (f);
  2270   int min_height = xg_get_default_scrollbar_height (f);
  2271   /* A minimum height of 14 doesn't look good for toolkit scroll bars.  */
  2272   FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = min_height;
  2273   FRAME_CONFIG_SCROLL_BAR_LINES (f) = (min_height + height - 1) / height;
  2274 }
  2275 
  2276 /* Terminals implement this instead of x-get-resource directly.  */
  2277 const char *
  2278 pgtk_get_string_resource (XrmDatabase rdb, const char *name,
  2279                           const char *class)
  2280 {
  2281   check_window_system (NULL);
  2282 
  2283   if (inhibit_x_resources)
  2284     /* --quick was passed, so this is a no-op.  */
  2285     return NULL;
  2286 
  2287   const char *res = pgtk_get_defaults_value (name);
  2288   if (res == NULL)
  2289     res = pgtk_get_defaults_value (class);
  2290 
  2291   if (res == NULL)
  2292     return NULL;
  2293 
  2294   if (c_strncasecmp (res, "YES", 3) == 0)
  2295     return "true";
  2296 
  2297   if (c_strncasecmp (res, "NO", 2) == 0)
  2298     return "false";
  2299 
  2300   return res;
  2301 }
  2302 
  2303 Lisp_Object
  2304 pgtk_get_focus_frame (struct frame *frame)
  2305 {
  2306   struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
  2307   Lisp_Object focus;
  2308 
  2309   if (!dpyinfo->x_focus_frame)
  2310     return Qnil;
  2311 
  2312   XSETFRAME (focus, dpyinfo->x_focus_frame);
  2313   return focus;
  2314 }
  2315 
  2316 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
  2317        doc: /* Internal function called by `color-defined-p', which see.  */)
  2318   (Lisp_Object color, Lisp_Object frame)
  2319 {
  2320   Emacs_Color col;
  2321   struct frame *f = decode_window_system_frame (frame);
  2322 
  2323   CHECK_STRING (color);
  2324 
  2325   if (pgtk_defined_color (f, SSDATA (color), &col, false, false))
  2326     return Qt;
  2327   else
  2328     return Qnil;
  2329 }
  2330 
  2331 
  2332 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
  2333        doc: /* Internal function called by `color-values', which see.  */)
  2334   (Lisp_Object color, Lisp_Object frame)
  2335 {
  2336   Emacs_Color col;
  2337   struct frame *f = decode_window_system_frame (frame);
  2338 
  2339   CHECK_STRING (color);
  2340 
  2341   if (pgtk_defined_color (f, SSDATA (color), &col, false, false))
  2342     return list3i (col.red, col.green, col.blue);
  2343   else
  2344     return Qnil;
  2345 }
  2346 
  2347 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
  2348        doc: /* Internal function called by `display-color-p', which see.  */)
  2349   (Lisp_Object terminal)
  2350 {
  2351   check_pgtk_display_info (terminal);
  2352   return Qt;
  2353 }
  2354 
  2355 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p, 0, 1, 0,
  2356        doc: /* Return t if the display supports shades of gray.
  2357 Note that color displays do support shades of gray.
  2358 The optional argument TERMINAL specifies which display to ask about.
  2359 TERMINAL should be a terminal object, a frame or a display name (a string).
  2360 If omitted or nil, that stands for the selected frame's display.  */)
  2361   (Lisp_Object terminal)
  2362 {
  2363   return Qnil;
  2364 }
  2365 
  2366 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width, 0, 1, 0,
  2367        doc: /* Return the width in pixels of the display TERMINAL.
  2368 The optional argument TERMINAL specifies which display to ask about.
  2369 TERMINAL should be a terminal object, a frame or a display name (a string).
  2370 If omitted or nil, that stands for the selected frame's display.
  2371 
  2372 On \"multi-monitor\" setups this refers to the pixel width for all
  2373 physical monitors associated with TERMINAL.  To get information for
  2374 each physical monitor, use `display-monitor-attributes-list'.  */)
  2375   (Lisp_Object terminal)
  2376 {
  2377   struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
  2378   GdkDisplay *gdpy;
  2379   gint n_monitors, i;
  2380   int width = 0;
  2381 
  2382   block_input ();
  2383   gdpy = dpyinfo->gdpy;
  2384   n_monitors = gdk_display_get_n_monitors (gdpy);
  2385 
  2386   for (i = 0; i < n_monitors; ++i)
  2387     {
  2388       GdkRectangle rec;
  2389       double scale = 1;
  2390 
  2391       GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
  2392       gdk_monitor_get_geometry (monitor, &rec);
  2393 
  2394       /* GTK returns scaled sizes for the workareas.  */
  2395       scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
  2396       if (scale == 0.0)
  2397         scale = gdk_monitor_get_scale_factor (monitor);
  2398       rec.x = rec.x * scale + 0.5;
  2399       rec.y = rec.y * scale + 0.5;
  2400       rec.width = rec.width * scale + 0.5;
  2401       rec.height = rec.height * scale + 0.5;
  2402 
  2403       width = max (width, rec.x + rec.width);
  2404     }
  2405 
  2406   unblock_input ();
  2407 
  2408   return make_fixnum (width);
  2409 }
  2410 
  2411 DEFUN ("x-display-pixel-height", Fx_display_pixel_height, Sx_display_pixel_height, 0, 1, 0,
  2412        doc: /* Return the height in pixels of the display TERMINAL.
  2413 The optional argument TERMINAL specifies which display to ask about.
  2414 TERMINAL should be a terminal object, a frame or a display name (a string).
  2415 If omitted or nil, that stands for the selected frame's display.
  2416 
  2417 On \"multi-monitor\" setups this refers to the pixel height for all
  2418 physical monitors associated with TERMINAL.  To get information for
  2419 each physical monitor, use `display-monitor-attributes-list'.  */)
  2420   (Lisp_Object terminal)
  2421 {
  2422   struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
  2423   GdkDisplay *gdpy;
  2424   gint n_monitors, i;
  2425   int height = 0;
  2426 
  2427   block_input ();
  2428   gdpy = dpyinfo->gdpy;
  2429   n_monitors = gdk_display_get_n_monitors (gdpy);
  2430 
  2431   for (i = 0; i < n_monitors; ++i)
  2432     {
  2433       GdkRectangle rec;
  2434       double scale = 1;
  2435 
  2436       GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
  2437       gdk_monitor_get_geometry (monitor, &rec);
  2438 
  2439       /* GTK returns scaled sizes for the workareas.  */
  2440       scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
  2441       if (scale == 0.0)
  2442         scale = gdk_monitor_get_scale_factor (monitor);
  2443       rec.x = rec.x * scale + 0.5;
  2444       rec.y = rec.y * scale + 0.5;
  2445       rec.width = rec.width * scale + 0.5;
  2446       rec.height = rec.height * scale + 0.5;
  2447 
  2448       height = max (height, rec.y + rec.height);
  2449     }
  2450 
  2451   unblock_input ();
  2452 
  2453   return make_fixnum (height);
  2454 }
  2455 
  2456 DEFUN ("pgtk-display-monitor-attributes-list", Fpgtk_display_monitor_attributes_list,
  2457        Spgtk_display_monitor_attributes_list,
  2458        0, 1, 0,
  2459        doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
  2460 
  2461 The optional argument TERMINAL specifies which display to ask about.
  2462 TERMINAL should be a terminal object, a frame or a display name (a string).
  2463 If omitted or nil, that stands for the selected frame's display.
  2464 
  2465 In addition to the standard attribute keys listed in
  2466 `display-monitor-attributes-list', the following keys are contained in
  2467 the attributes:
  2468 
  2469  source -- String describing the source from which multi-monitor
  2470            information is obtained, \"Gdk\"
  2471 
  2472 Internal use only, use `display-monitor-attributes-list' instead.  */)
  2473   (Lisp_Object terminal)
  2474 {
  2475   struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
  2476   Lisp_Object attributes_list = Qnil;
  2477 
  2478   GdkDisplay *gdpy;
  2479   gint primary_monitor = 0, n_monitors, i;
  2480   Lisp_Object monitor_frames, rest, frame;
  2481   static const char *source = "Gdk";
  2482   struct MonitorInfo *monitors;
  2483 
  2484   block_input ();
  2485   gdpy = dpyinfo->gdpy;
  2486   n_monitors = gdk_display_get_n_monitors (gdpy);
  2487   monitor_frames = make_nil_vector (n_monitors);
  2488   monitors = xzalloc (n_monitors * sizeof *monitors);
  2489 
  2490   FOR_EACH_FRAME (rest, frame)
  2491     {
  2492       struct frame *f = XFRAME (frame);
  2493 
  2494       if (FRAME_PGTK_P (f)
  2495           && FRAME_DISPLAY_INFO (f) == dpyinfo
  2496           && !FRAME_TOOLTIP_P (f))
  2497         {
  2498           GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
  2499 
  2500           for (i = 0; i < n_monitors; i++)
  2501             if (gdk_display_get_monitor_at_window (gdpy, gwin)
  2502                 == gdk_display_get_monitor (gdpy, i))
  2503               break;
  2504           ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
  2505         }
  2506     }
  2507 
  2508   for (i = 0; i < n_monitors; ++i)
  2509     {
  2510       gint width_mm, height_mm;
  2511       GdkRectangle rec, work;
  2512       struct MonitorInfo *mi = &monitors[i];
  2513       double scale = 1;
  2514 
  2515       GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
  2516       if (gdk_monitor_is_primary (monitor))
  2517         primary_monitor = i;
  2518       gdk_monitor_get_geometry (monitor, &rec);
  2519 
  2520       width_mm = gdk_monitor_get_width_mm (monitor);
  2521       height_mm = gdk_monitor_get_height_mm (monitor);
  2522       gdk_monitor_get_workarea (monitor, &work);
  2523 
  2524       /* GTK returns scaled sizes for the workareas.  */
  2525       scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (monitor));
  2526       if (scale == 0.0)
  2527         scale = gdk_monitor_get_scale_factor (monitor);
  2528       rec.x = rec.x * scale + 0.5;
  2529       rec.y = rec.y * scale + 0.5;
  2530       rec.width = rec.width * scale + 0.5;
  2531       rec.height = rec.height * scale + 0.5;
  2532       work.x = work.x * scale + 0.5;
  2533       work.y = work.y * scale + 0.5;
  2534       work.width = work.width * scale + 0.5;
  2535       work.height = work.height * scale + 0.5;
  2536 
  2537       mi->geom.x = rec.x;
  2538       mi->geom.y = rec.y;
  2539       mi->geom.width = rec.width;
  2540       mi->geom.height = rec.height;
  2541       mi->work.x = work.x;
  2542       mi->work.y = work.y;
  2543       mi->work.width = work.width;
  2544       mi->work.height = work.height;
  2545       mi->mm_width = width_mm;
  2546       mi->mm_height = height_mm;
  2547       mi->scale_factor = scale;
  2548 
  2549       dupstring (&mi->name, (gdk_monitor_get_model (monitor)));
  2550     }
  2551 
  2552   attributes_list = make_monitor_attribute_list (monitors,
  2553                                                  n_monitors,
  2554                                                  primary_monitor,
  2555                                                  monitor_frames,
  2556                                                  source);
  2557   free_monitors (monitors, n_monitors);
  2558   unblock_input ();
  2559 
  2560   return attributes_list;
  2561 }
  2562 
  2563 double
  2564 pgtk_frame_scale_factor (struct frame *f)
  2565 {
  2566   struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  2567   GdkDisplay *gdpy = dpyinfo->gdpy;
  2568 
  2569   block_input ();
  2570 
  2571   GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
  2572   GdkMonitor *gmon = gdk_display_get_monitor_at_window (gdpy, gwin);
  2573 
  2574   /* GTK returns scaled sizes for the workareas.  */
  2575   double scale = pgtk_get_monitor_scale_factor (gdk_monitor_get_model (gmon));
  2576   if (scale == 0.0)
  2577     scale = gdk_monitor_get_scale_factor (gmon);
  2578 
  2579   unblock_input ();
  2580 
  2581   return scale;
  2582 }
  2583 
  2584 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes, 0, 1, 0,
  2585        doc: /* Return the number of bitplanes of the display TERMINAL.
  2586 The optional argument TERMINAL specifies which display to ask about.
  2587 TERMINAL should be a terminal object, a frame or a display name (a string).
  2588 If omitted or nil, that stands for the selected frame's display.  */)
  2589   (Lisp_Object terminal)
  2590 {
  2591   check_pgtk_display_info (terminal);
  2592   return make_fixnum (32);
  2593 }
  2594 
  2595 
  2596 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells, 0, 1, 0,
  2597        doc: /* Returns the number of color cells of the display TERMINAL.
  2598 The optional argument TERMINAL specifies which display to ask about.
  2599 TERMINAL should be a terminal object, a frame or a display name (a string).
  2600 If omitted or nil, that stands for the selected frame's display.  */)
  2601   (Lisp_Object terminal)
  2602 {
  2603   struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
  2604   /* We force 24+ bit depths to 24-bit to prevent an overflow.  */
  2605   return make_fixnum (1 << min (dpyinfo->n_planes, 24));
  2606 }
  2607 
  2608 /***********************************************************************
  2609                                 Tool tips
  2610  ***********************************************************************/
  2611 
  2612 /* The frame of the currently visible tooltip.  */
  2613 static Lisp_Object tip_frame;
  2614 
  2615 /* The window-system window corresponding to the frame of the
  2616    currently visible tooltip.  */
  2617 GtkWidget *tip_window;
  2618 
  2619 /* A timer that hides or deletes the currently visible tooltip when it
  2620    fires.  */
  2621 static Lisp_Object tip_timer;
  2622 
  2623 /* STRING argument of last `x-show-tip' call.  */
  2624 static Lisp_Object tip_last_string;
  2625 
  2626 /* Normalized FRAME argument of last `x-show-tip' call.  */
  2627 static Lisp_Object tip_last_frame;
  2628 
  2629 /* PARMS argument of last `x-show-tip' call.  */
  2630 static Lisp_Object tip_last_parms;
  2631 
  2632 
  2633 static void
  2634 unwind_create_tip_frame (Lisp_Object frame)
  2635 {
  2636   Lisp_Object deleted;
  2637 
  2638   deleted = unwind_create_frame (frame);
  2639   if (EQ (deleted, Qt))
  2640     {
  2641       tip_window = NULL;
  2642       tip_frame = Qnil;
  2643     }
  2644 }
  2645 
  2646 
  2647 /* Create a frame for a tooltip on the display described by DPYINFO.
  2648    PARMS is a list of frame parameters.  TEXT is the string to
  2649    display in the tip frame.  Value is the frame.
  2650 
  2651    Note that functions called here, esp. gui_default_parameter can
  2652    signal errors, for instance when a specified color name is
  2653    undefined.  We have to make sure that we're in a consistent state
  2654    when this happens.  */
  2655 
  2656 static Lisp_Object
  2657 x_create_tip_frame (struct pgtk_display_info *dpyinfo, Lisp_Object parms, struct frame *p)
  2658 {
  2659   struct frame *f;
  2660   Lisp_Object frame;
  2661   Lisp_Object name;
  2662   specpdl_ref count = SPECPDL_INDEX ();
  2663   bool face_change_before = face_change;
  2664 
  2665   if (!dpyinfo->terminal->name)
  2666     error ("Terminal is not live, can't create new frames on it");
  2667 
  2668   parms = Fcopy_alist (parms);
  2669 
  2670   /* Get the name of the frame to use for resource lookup.  */
  2671   name = gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name",
  2672                               RES_TYPE_STRING);
  2673   if (!STRINGP (name)
  2674       && !BASE_EQ (name, Qunbound)
  2675       && !NILP (name))
  2676     error ("Invalid frame name--not a string or nil");
  2677 
  2678   frame = Qnil;
  2679   f = make_frame (false);
  2680   f->wants_modeline = false;
  2681   XSETFRAME (frame, f);
  2682   record_unwind_protect (unwind_create_tip_frame, frame);
  2683 
  2684   f->terminal = dpyinfo->terminal;
  2685 
  2686   /* By setting the output method, we're essentially saying that
  2687      the frame is live, as per FRAME_LIVE_P.  If we get a signal
  2688      from this point on, x_destroy_window might screw up reference
  2689      counts etc.  */
  2690   f->output_method = output_pgtk;
  2691   f->output_data.pgtk = xzalloc (sizeof *f->output_data.pgtk);
  2692   FRAME_FONTSET (f) = -1;
  2693   f->output_data.pgtk->white_relief.pixel = -1;
  2694   f->output_data.pgtk->black_relief.pixel = -1;
  2695 
  2696   f->tooltip = true;
  2697   fset_icon_name (f, Qnil);
  2698   FRAME_DISPLAY_INFO (f) = dpyinfo;
  2699   f->output_data.pgtk->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
  2700   f->output_data.pgtk->explicit_parent = false;
  2701 
  2702   /* These colors will be set anyway later, but it's important
  2703      to get the color reference counts right, so initialize them!  */
  2704   {
  2705     Lisp_Object black;
  2706 
  2707     /* Function x_decode_color can signal an error.  Make
  2708        sure to initialize color slots so that we won't try
  2709        to free colors we haven't allocated.  */
  2710     FRAME_FOREGROUND_PIXEL (f) = -1;
  2711     FRAME_BACKGROUND_PIXEL (f) = -1;
  2712     f->output_data.pgtk->border_pixel = -1;
  2713 
  2714     black = build_string ("black");
  2715     FRAME_FOREGROUND_PIXEL (f)
  2716       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  2717     FRAME_BACKGROUND_PIXEL (f)
  2718       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  2719     f->output_data.pgtk->border_pixel
  2720       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  2721   }
  2722 
  2723   /* Set the name; the functions to which we pass f expect the name to
  2724      be set.  */
  2725   if (BASE_EQ (name, Qunbound) || NILP (name))
  2726     {
  2727       fset_name (f, build_string (dpyinfo->x_id_name));
  2728       f->explicit_name = false;
  2729     }
  2730   else
  2731     {
  2732       fset_name (f, name);
  2733       f->explicit_name = true;
  2734       /* use the frame's title when getting resources for this frame.  */
  2735       specbind (Qx_resource_name, name);
  2736     }
  2737 
  2738   register_font_driver (&ftcrfont_driver, f);
  2739 #ifdef HAVE_HARFBUZZ
  2740   register_font_driver (&ftcrhbfont_driver, f);
  2741 #endif  /* HAVE_HARFBUZZ */
  2742 
  2743   image_cache_refcount =
  2744     FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
  2745 
  2746   gui_default_parameter (f, parms, Qfont_backend, Qnil,
  2747                          "fontBackend", "FontBackend", RES_TYPE_STRING);
  2748 
  2749   /* Extract the window parameters from the supplied values that are
  2750      needed to determine window geometry.  */
  2751   pgtk_default_font_parameter (f, parms);
  2752 
  2753   gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
  2754                          "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
  2755 
  2756   /* This defaults to 2 in order to match xterm.  We recognize either
  2757      internalBorderWidth or internalBorder (which is what xterm calls
  2758      it).  */
  2759   if (NILP (Fassq (Qinternal_border_width, parms)))
  2760     {
  2761       Lisp_Object value;
  2762 
  2763       value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width,
  2764                                    "internalBorder", "internalBorder",
  2765                                    RES_TYPE_NUMBER);
  2766       if (! BASE_EQ (value, Qunbound))
  2767         parms = Fcons (Fcons (Qinternal_border_width, value),
  2768                        parms);
  2769     }
  2770 
  2771   gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (1),
  2772                          "internalBorderWidth", "internalBorderWidth",
  2773                          RES_TYPE_NUMBER);
  2774   gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
  2775                          NULL, NULL, RES_TYPE_NUMBER);
  2776   gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
  2777                          NULL, NULL, RES_TYPE_NUMBER);
  2778 
  2779   /* Also do the stuff which must be set before the window exists.  */
  2780   gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
  2781                          "foreground", "Foreground", RES_TYPE_STRING);
  2782   gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
  2783                          "background", "Background", RES_TYPE_STRING);
  2784   gui_default_parameter (f, parms, Qmouse_color, build_string ("black"),
  2785                          "pointerColor", "Foreground", RES_TYPE_STRING);
  2786   gui_default_parameter (f, parms, Qcursor_color, build_string ("black"),
  2787                          "cursorColor", "Foreground", RES_TYPE_STRING);
  2788   gui_default_parameter (f, parms, Qborder_color, build_string ("black"),
  2789                          "borderColor", "BorderColor", RES_TYPE_STRING);
  2790   gui_default_parameter (f, parms, Qno_special_glyphs, Qnil,
  2791                          NULL, NULL, RES_TYPE_BOOLEAN);
  2792 
  2793   /* Init faces before gui_default_parameter is called for the
  2794      scroll-bar-width parameter because otherwise we end up in
  2795      init_iterator with a null face cache, which should not happen.  */
  2796   init_frame_faces (f);
  2797 
  2798   f->output_data.pgtk->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
  2799 
  2800   gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
  2801                          "inhibitDoubleBuffering", "InhibitDoubleBuffering",
  2802                          RES_TYPE_BOOLEAN);
  2803 
  2804   gui_figure_window_size (f, parms, false, false);
  2805 
  2806   xg_create_frame_widgets (f);
  2807   pgtk_set_event_handler (f);
  2808   tip_window = FRAME_GTK_OUTER_WIDGET (f);
  2809   gtk_window_set_transient_for (GTK_WINDOW (tip_window),
  2810                                 GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (p)));
  2811   gtk_window_set_attached_to (GTK_WINDOW (tip_window), FRAME_GTK_WIDGET (p));
  2812   gtk_window_set_destroy_with_parent (GTK_WINDOW (tip_window), TRUE);
  2813   gtk_window_set_decorated (GTK_WINDOW (tip_window), FALSE);
  2814   gtk_window_set_type_hint (GTK_WINDOW (tip_window), GDK_WINDOW_TYPE_HINT_TOOLTIP);
  2815   f->output_data.pgtk->current_cursor = f->output_data.pgtk->text_cursor;
  2816 
  2817   gui_default_parameter (f, parms, Qauto_raise, Qnil,
  2818                          "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
  2819   gui_default_parameter (f, parms, Qauto_lower, Qnil,
  2820                          "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
  2821   gui_default_parameter (f, parms, Qcursor_type, Qbox,
  2822                          "cursorType", "CursorType", RES_TYPE_SYMBOL);
  2823   gui_default_parameter (f, parms, Qalpha, Qnil,
  2824                          "alpha", "Alpha", RES_TYPE_NUMBER);
  2825   gui_default_parameter (f, parms, Qalpha_background, Qnil,
  2826                          "alphaBackground", "AlphaBackground", RES_TYPE_NUMBER);
  2827 
  2828   /* Add `tooltip' frame parameter's default value. */
  2829   if (NILP (Fframe_parameter (frame, Qtooltip)))
  2830     {
  2831       AUTO_FRAME_ARG (arg, Qtooltip, Qt);
  2832       Fmodify_frame_parameters (frame, arg);
  2833     }
  2834 
  2835   /* FIXME - can this be done in a similar way to normal frames?
  2836      https://lists.gnu.org/r/emacs-devel/2007-10/msg00641.html */
  2837 
  2838   /* Set the `display-type' frame parameter before setting up faces. */
  2839   {
  2840     Lisp_Object disptype;
  2841 
  2842     disptype = intern ("color");
  2843 
  2844     if (NILP (Fframe_parameter (frame, Qdisplay_type)))
  2845       {
  2846         AUTO_FRAME_ARG (arg, Qdisplay_type, disptype);
  2847         Fmodify_frame_parameters (frame, arg);
  2848       }
  2849   }
  2850 
  2851   /* Set up faces after all frame parameters are known.  This call
  2852      also merges in face attributes specified for new frames.
  2853 
  2854      Frame parameters may be changed if .Xdefaults contains
  2855      specifications for the default font.  For example, if there is an
  2856      `Emacs.default.attributeBackground: pink', the `background-color'
  2857      attribute of the frame gets set, which lets the internal border
  2858      of the tooltip frame appear in pink.  Prevent this.  */
  2859   {
  2860     Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
  2861 
  2862     call2 (Qface_set_after_frame_default, frame, Qnil);
  2863 
  2864     if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
  2865       {
  2866         AUTO_FRAME_ARG (arg, Qbackground_color, bg);
  2867         Fmodify_frame_parameters (frame, arg);
  2868       }
  2869   }
  2870 
  2871   f->no_split = true;
  2872 
  2873   /* Now that the frame will be official, it counts as a reference to
  2874      its display and terminal.  */
  2875   FRAME_DISPLAY_INFO (f)->reference_count++;
  2876   f->terminal->reference_count++;
  2877 
  2878   /* It is now ok to make the frame official even if we get an error
  2879      below.  And the frame needs to be on Vframe_list or making it
  2880      visible won't work.  */
  2881   Vframe_list = Fcons (frame, Vframe_list);
  2882   f->can_set_window_size = true;
  2883   adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
  2884                      0, true, Qtip_frame);
  2885 
  2886   /* Setting attributes of faces of the tooltip frame from resources
  2887      and similar will set face_change, which leads to the clearing of
  2888      all current matrices.  Since this isn't necessary here, avoid it
  2889      by resetting face_change to the value it had before we created
  2890      the tip frame.  */
  2891   face_change = face_change_before;
  2892 
  2893   /* Discard the unwind_protect.  */
  2894   return unbind_to (count, frame);
  2895 }
  2896 
  2897 /* Compute where to display tip frame F.  PARMS is the list of frame
  2898    parameters for F.  DX and DY are specified offsets from the current
  2899    location of the mouse.  WIDTH and HEIGHT are the width and height
  2900    of the tooltip.  Return coordinates relative to the root window of
  2901    the display in *ROOT_X, and *ROOT_Y.  */
  2902 
  2903 static void
  2904 compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx,
  2905                 Lisp_Object dy, int width, int height, int *root_x,
  2906                 int *root_y)
  2907 {
  2908   Lisp_Object left, top, right, bottom;
  2909   int min_x, min_y, max_x, max_y = -1;
  2910 
  2911   /* User-specified position?  */
  2912   left = Fcdr (Fassq (Qleft, parms));
  2913   top = Fcdr (Fassq (Qtop, parms));
  2914   right = Fcdr (Fassq (Qright, parms));
  2915   bottom = Fcdr (Fassq (Qbottom, parms));
  2916 
  2917   /* Move the tooltip window where the mouse pointer is.  Resize and
  2918      show it.  */
  2919   if ((!INTEGERP (left) && !INTEGERP (right))
  2920       || (!INTEGERP (top) && !INTEGERP (bottom)))
  2921     {
  2922       Lisp_Object frame, attributes, monitor, geometry;
  2923       GdkSeat *seat =
  2924         gdk_display_get_default_seat (FRAME_DISPLAY_INFO (f)->gdpy);
  2925       GdkDevice *dev = gdk_seat_get_pointer (seat);
  2926       GdkScreen *scr;
  2927 
  2928       block_input ();
  2929       gdk_device_get_position (dev, &scr, root_x, root_y);
  2930       unblock_input ();
  2931 
  2932       XSETFRAME (frame, f);
  2933       attributes = Fpgtk_display_monitor_attributes_list (frame);
  2934 
  2935       /* Try to determine the monitor where the mouse pointer is and
  2936          its geometry.  See bug#22549.  */
  2937       while (CONSP (attributes))
  2938         {
  2939           monitor = XCAR (attributes);
  2940           geometry = Fassq (Qgeometry, monitor);
  2941           if (CONSP (geometry))
  2942             {
  2943               min_x = XFIXNUM (Fnth (make_fixnum (1), geometry));
  2944               min_y = XFIXNUM (Fnth (make_fixnum (2), geometry));
  2945               max_x = min_x + XFIXNUM (Fnth (make_fixnum (3), geometry));
  2946               max_y = min_y + XFIXNUM (Fnth (make_fixnum (4), geometry));
  2947               if (min_x <= *root_x && *root_x < max_x
  2948                   && min_y <= *root_y && *root_y < max_y)
  2949                 {
  2950                   break;
  2951                 }
  2952               max_y = -1;
  2953             }
  2954 
  2955           attributes = XCDR (attributes);
  2956         }
  2957     }
  2958 
  2959   /* It was not possible to determine the monitor's geometry, so we
  2960      assign some sane defaults here: */
  2961   if (max_y < 0)
  2962     {
  2963       min_x = 0;
  2964       min_y = 0;
  2965       max_x = pgtk_display_pixel_width (FRAME_DISPLAY_INFO (f));
  2966       max_y = pgtk_display_pixel_height (FRAME_DISPLAY_INFO (f));
  2967     }
  2968 
  2969   if (INTEGERP (top))
  2970     *root_y = XFIXNUM (top);
  2971   else if (INTEGERP (bottom))
  2972     *root_y = XFIXNUM (bottom) - height;
  2973   else if (*root_y + XFIXNUM (dy) <= min_y)
  2974     *root_y = min_y;            /* Can happen for negative dy */
  2975   else if (*root_y + XFIXNUM (dy) + height <= max_y)
  2976     /* It fits below the pointer */
  2977     *root_y += XFIXNUM (dy);
  2978   else if (height + XFIXNUM (dy) + min_y <= *root_y)
  2979     /* It fits above the pointer.  */
  2980     *root_y -= height + XFIXNUM (dy);
  2981   else
  2982     /* Put it on the top.  */
  2983     *root_y = min_y;
  2984 
  2985   if (INTEGERP (left))
  2986     *root_x = XFIXNUM (left);
  2987   else if (INTEGERP (right))
  2988     *root_x = XFIXNUM (right) - width;
  2989   else if (*root_x + XFIXNUM (dx) <= min_x)
  2990     *root_x = 0;                /* Can happen for negative dx */
  2991   else if (*root_x + XFIXNUM (dx) + width <= max_x)
  2992     /* It fits to the right of the pointer.  */
  2993     *root_x += XFIXNUM (dx);
  2994   else if (width + XFIXNUM (dx) + min_x <= *root_x)
  2995     /* It fits to the left of the pointer.  */
  2996     *root_x -= width + XFIXNUM (dx);
  2997   else
  2998     /* Put it left justified on the screen -- it ought to fit that way.  */
  2999     *root_x = min_x;
  3000 }
  3001 
  3002 
  3003 /* Hide tooltip.  Delete its frame if DELETE is true.  */
  3004 static Lisp_Object
  3005 pgtk_hide_tip (bool delete)
  3006 {
  3007   if (!NILP (tip_timer))
  3008     {
  3009       call1 (Qcancel_timer, tip_timer);
  3010       tip_timer = Qnil;
  3011     }
  3012 
  3013   /* Any GTK+ system tooltip can be found via the x_output structure of
  3014      tip_last_frame, provided that frame is still live.  Any Emacs
  3015      tooltip is found via the tip_frame variable.  Note that the current
  3016      value of x_gtk_use_system_tooltips might not be the same as used
  3017      for the tooltip we have to hide, see Bug#30399.  */
  3018   if ((NILP (tip_last_frame) && NILP (tip_frame))
  3019       || (!use_system_tooltips
  3020           && !delete
  3021           && FRAMEP (tip_frame)
  3022           && FRAME_LIVE_P (XFRAME (tip_frame))
  3023           && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
  3024     /* Either there's no tooltip to hide or it's an already invisible
  3025        Emacs tooltip and we don't want to change its type.  Return
  3026        quickly.  */
  3027     return Qnil;
  3028   else
  3029     {
  3030       Lisp_Object was_open = Qnil;
  3031 
  3032       specpdl_ref count = SPECPDL_INDEX ();
  3033       specbind (Qinhibit_redisplay, Qt);
  3034       specbind (Qinhibit_quit, Qt);
  3035 
  3036       /* Try to hide the GTK+ system tip first.  */
  3037       if (FRAMEP (tip_last_frame))
  3038         {
  3039           struct frame *f = XFRAME (tip_last_frame);
  3040 
  3041           if (FRAME_LIVE_P (f))
  3042             {
  3043               if (xg_hide_tooltip (f))
  3044                 was_open = Qt;
  3045             }
  3046         }
  3047 
  3048       /* When using GTK+ system tooltips (compare Bug#41200) reset
  3049          tip_last_frame.  It will be reassigned when showing the next
  3050          GTK+ system tooltip.  */
  3051       if (use_system_tooltips)
  3052         tip_last_frame = Qnil;
  3053 
  3054       /* Now look whether there's an Emacs tip around.  */
  3055       if (FRAMEP (tip_frame))
  3056         {
  3057           struct frame *f = XFRAME (tip_frame);
  3058 
  3059           if (FRAME_LIVE_P (f))
  3060             {
  3061               if (delete || use_system_tooltips)
  3062                 {
  3063                   /* Delete the Emacs tooltip frame when DELETE is true
  3064                      or we change the tooltip type from an Emacs one to
  3065                      a GTK+ system one.  */
  3066                   delete_frame (tip_frame, Qnil);
  3067                   tip_frame = Qnil;
  3068                 }
  3069               else
  3070                 pgtk_make_frame_invisible (f);
  3071 
  3072               was_open = Qt;
  3073             }
  3074           else
  3075             tip_frame = Qnil;
  3076         }
  3077       else
  3078         tip_frame = Qnil;
  3079 
  3080       return unbind_to (count, was_open);
  3081     }
  3082 }
  3083 
  3084 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
  3085        doc: /* Show STRING in a "tooltip" window on frame FRAME.
  3086 A tooltip window is a small X window displaying a string.
  3087 
  3088 This is an internal function; Lisp code should call `tooltip-show'.
  3089 
  3090 FRAME nil or omitted means use the selected frame.
  3091 
  3092 PARMS is an optional list of frame parameters which can be used to
  3093 change the tooltip's appearance.
  3094 
  3095 Automatically hide the tooltip after TIMEOUT seconds.  TIMEOUT nil
  3096 means use the default timeout from the `x-show-tooltip-timeout'
  3097 variable.
  3098 
  3099 If the list of frame parameters PARMS contains a `left' parameter,
  3100 display the tooltip at that x-position.  If the list of frame parameters
  3101 PARMS contains no `left' but a `right' parameter, display the tooltip
  3102 right-adjusted at that x-position. Otherwise display it at the
  3103 x-position of the mouse, with offset DX added (default is 5 if DX isn't
  3104 specified).
  3105 
  3106 Likewise for the y-position: If a `top' frame parameter is specified, it
  3107 determines the position of the upper edge of the tooltip window.  If a
  3108 `bottom' parameter but no `top' frame parameter is specified, it
  3109 determines the position of the lower edge of the tooltip window.
  3110 Otherwise display the tooltip window at the y-position of the mouse,
  3111 with offset DY added (default is -10).
  3112 
  3113 A tooltip's maximum size is specified by `x-max-tooltip-size'.
  3114 Text larger than the specified size is clipped.  */)
  3115   (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
  3116    Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
  3117 {
  3118   struct frame *f, *tip_f;
  3119   struct window *w;
  3120   int root_x, root_y;
  3121   struct buffer *old_buffer;
  3122   struct text_pos pos;
  3123   int width, height;
  3124   int old_windows_or_buffers_changed = windows_or_buffers_changed;
  3125   specpdl_ref count = SPECPDL_INDEX ();
  3126   Lisp_Object window, size, tip_buf;
  3127   bool displayed;
  3128 #ifdef ENABLE_CHECKING
  3129   struct glyph_row *row, *end;
  3130 #endif
  3131   AUTO_STRING (tip, " *tip*");
  3132 
  3133   specbind (Qinhibit_redisplay, Qt);
  3134 
  3135   CHECK_STRING (string);
  3136   if (SCHARS (string) == 0)
  3137     string = make_unibyte_string (" ", 1);
  3138 
  3139   if (NILP (frame))
  3140     frame = selected_frame;
  3141   f = decode_window_system_frame (frame);
  3142 
  3143   if (!FRAME_GTK_OUTER_WIDGET (f))
  3144     return unbind_to (count, Qnil);
  3145 
  3146   if (NILP (timeout))
  3147     timeout = Vx_show_tooltip_timeout;
  3148   CHECK_FIXNAT (timeout);
  3149 
  3150   if (NILP (dx))
  3151     dx = make_fixnum (5);
  3152   else
  3153     CHECK_FIXNUM (dx);
  3154 
  3155   if (NILP (dy))
  3156     dy = make_fixnum (-10);
  3157   else
  3158     CHECK_FIXNUM (dy);
  3159 
  3160   if (use_system_tooltips)
  3161     {
  3162       bool ok;
  3163 
  3164       /* Hide a previous tip, if any.  */
  3165       Fx_hide_tip ();
  3166 
  3167       block_input ();
  3168 
  3169       ok = true;
  3170       xg_show_tooltip (f, string);
  3171       tip_last_frame = frame;
  3172 
  3173       unblock_input ();
  3174       if (ok) goto start_timer;
  3175     }
  3176 
  3177   if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
  3178     {
  3179       if (FRAME_VISIBLE_P (XFRAME (tip_frame))
  3180           && EQ (frame, tip_last_frame)
  3181           && !NILP (Fequal_including_properties (tip_last_string, string))
  3182           && !NILP (Fequal (tip_last_parms, parms)))
  3183         {
  3184           /* Only DX and DY have changed.  */
  3185           tip_f = XFRAME (tip_frame);
  3186           if (!NILP (tip_timer))
  3187             {
  3188               call1 (Qcancel_timer, tip_timer);
  3189               tip_timer = Qnil;
  3190             }
  3191 
  3192           block_input ();
  3193           compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
  3194                           FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
  3195           gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), root_x, root_y);
  3196           unblock_input ();
  3197 
  3198           goto start_timer;
  3199         }
  3200       else if (tooltip_reuse_hidden_frame && EQ (frame, tip_last_frame))
  3201         {
  3202           bool delete = false;
  3203           Lisp_Object tail, elt, parm, last;
  3204 
  3205           /* Check if every parameter in PARMS has the same value in
  3206              tip_last_parms.  This may destruct tip_last_parms which,
  3207              however, will be recreated below.  */
  3208           for (tail = parms; CONSP (tail); tail = XCDR (tail))
  3209             {
  3210               elt = XCAR (tail);
  3211               parm = Fcar (elt);
  3212               /* The left, top, right and bottom parameters are handled
  3213                  by compute_tip_xy so they can be ignored here.  */
  3214               if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
  3215                   && !EQ (parm, Qright) && !EQ (parm, Qbottom))
  3216                 {
  3217                   last = Fassq (parm, tip_last_parms);
  3218                   if (NILP (Fequal (Fcdr (elt), Fcdr (last))))
  3219                     {
  3220                       /* We lost, delete the old tooltip.  */
  3221                       delete = true;
  3222                       break;
  3223                     }
  3224                   else
  3225                     tip_last_parms =
  3226                       call2 (Qassq_delete_all, parm, tip_last_parms);
  3227                 }
  3228               else
  3229                 tip_last_parms =
  3230                   call2 (Qassq_delete_all, parm, tip_last_parms);
  3231             }
  3232 
  3233           /* Now check if every parameter in what is left of
  3234              tip_last_parms with a non-nil value has an association in
  3235              PARMS.  */
  3236           for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
  3237             {
  3238               elt = XCAR (tail);
  3239               parm = Fcar (elt);
  3240               if (!EQ (parm, Qleft) && !EQ (parm, Qtop) && !EQ (parm, Qright)
  3241                   && !EQ (parm, Qbottom) && !NILP (Fcdr (elt)))
  3242                 {
  3243                   /* We lost, delete the old tooltip.  */
  3244                   delete = true;
  3245                   break;
  3246                 }
  3247             }
  3248 
  3249           pgtk_hide_tip (delete);
  3250         }
  3251       else
  3252         pgtk_hide_tip (true);
  3253     }
  3254   else
  3255     pgtk_hide_tip (true);
  3256 
  3257   tip_last_frame = frame;
  3258   tip_last_string = string;
  3259   tip_last_parms = parms;
  3260 
  3261   if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
  3262     {
  3263       /* Add default values to frame parameters.  */
  3264       if (NILP (Fassq (Qname, parms)))
  3265         parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
  3266       if (NILP (Fassq (Qinternal_border_width, parms)))
  3267         parms = Fcons (Fcons (Qinternal_border_width, make_fixnum (3)), parms);
  3268       if (NILP (Fassq (Qborder_width, parms)))
  3269         parms = Fcons (Fcons (Qborder_width, make_fixnum (1)), parms);
  3270       if (NILP (Fassq (Qborder_color, parms)))
  3271         parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
  3272       if (NILP (Fassq (Qbackground_color, parms)))
  3273         parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
  3274                        parms);
  3275 
  3276       /* Create a frame for the tooltip, and record it in the global
  3277          variable tip_frame.  */
  3278       if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, f)))
  3279         /* Creating the tip frame failed.  */
  3280         return unbind_to (count, Qnil);
  3281     }
  3282 
  3283   tip_f = XFRAME (tip_frame);
  3284   window = FRAME_ROOT_WINDOW (tip_f);
  3285   tip_buf = Fget_buffer_create (tip, Qnil);
  3286   /* We will mark the tip window a "pseudo-window" below, and such
  3287      windows cannot have display margins.  */
  3288   bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
  3289   bset_right_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
  3290   set_window_buffer (window, tip_buf, false, false);
  3291   w = XWINDOW (window);
  3292   w->pseudo_window_p = true;
  3293 
  3294   /* Set up the frame's root window.  Note: The following code does not
  3295      try to size the window or its frame correctly.  Its only purpose is
  3296      to make the subsequent text size calculations work.  The right
  3297      sizes should get installed when the toolkit gets back to us.  */
  3298   w->left_col = 0;
  3299   w->top_line = 0;
  3300   w->pixel_left = 0;
  3301   w->pixel_top = 0;
  3302 
  3303   if (CONSP (Vx_max_tooltip_size)
  3304       && RANGED_FIXNUMP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
  3305       && RANGED_FIXNUMP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
  3306     {
  3307       w->total_cols = XFIXNAT (XCAR (Vx_max_tooltip_size));
  3308       w->total_lines = XFIXNAT (XCDR (Vx_max_tooltip_size));
  3309     }
  3310   else
  3311     {
  3312       w->total_cols = 80;
  3313       w->total_lines = 40;
  3314     }
  3315 
  3316   w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f);
  3317   w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f);
  3318   FRAME_TOTAL_COLS (tip_f) = w->total_cols;
  3319   adjust_frame_glyphs (tip_f);
  3320 
  3321   /* Insert STRING into root window's buffer and fit the frame to the
  3322      buffer.  */
  3323   specpdl_ref count_1 = SPECPDL_INDEX ();
  3324   old_buffer = current_buffer;
  3325   set_buffer_internal_1 (XBUFFER (w->contents));
  3326   bset_truncate_lines (current_buffer, Qnil);
  3327   specbind (Qinhibit_read_only, Qt);
  3328   specbind (Qinhibit_modification_hooks, Qt);
  3329   specbind (Qinhibit_point_motion_hooks, Qt);
  3330   Ferase_buffer ();
  3331   Finsert (1, &string);
  3332   clear_glyph_matrix (w->desired_matrix);
  3333   clear_glyph_matrix (w->current_matrix);
  3334   SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
  3335   displayed = try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
  3336 
  3337   if (!displayed && NILP (Vx_max_tooltip_size))
  3338     {
  3339 #ifdef ENABLE_CHECKING
  3340       row = w->desired_matrix->rows;
  3341       end = w->desired_matrix->rows + w->desired_matrix->nrows;
  3342 
  3343       while (row < end)
  3344         {
  3345           if (!row->displays_text_p
  3346               || row->ends_at_zv_p)
  3347             break;
  3348           ++row;
  3349         }
  3350 
  3351       eassert (row < end && row->ends_at_zv_p);
  3352 #endif
  3353     }
  3354 
  3355   /* Calculate size of tooltip window.  */
  3356   size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil,
  3357                                   make_fixnum (w->pixel_height), Qnil,
  3358                                   Qnil);
  3359   /* Add the frame's internal border to calculated size.  */
  3360   width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
  3361   height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
  3362   width += FRAME_COLUMN_WIDTH (tip_f);
  3363 
  3364   /* Calculate position of tooltip frame.  */
  3365   compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y);
  3366 
  3367   /* Show tooltip frame.  */
  3368   block_input ();
  3369   gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), width, height);
  3370   gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (tip_f)), root_x, root_y);
  3371   gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (tip_f));
  3372   SET_FRAME_VISIBLE (tip_f, 1);
  3373   gdk_window_set_cursor (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (tip_f)),
  3374                          f->output_data.pgtk->current_cursor);
  3375 
  3376   unblock_input ();
  3377 
  3378   pgtk_cr_update_surface_desired_size (tip_f, width, height, false);
  3379 
  3380   w->must_be_updated_p = true;
  3381   update_single_window (w);
  3382   flush_frame (tip_f);
  3383   set_buffer_internal_1 (old_buffer);
  3384   unbind_to (count_1, Qnil);
  3385   windows_or_buffers_changed = old_windows_or_buffers_changed;
  3386 
  3387  start_timer:
  3388   /* Let the tip disappear after timeout seconds.  */
  3389   tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
  3390                      intern ("x-hide-tip"));
  3391 
  3392   return unbind_to (count, Qnil);
  3393 }
  3394 
  3395 
  3396 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
  3397        doc: /* Hide the current tooltip window, if there is any.
  3398 Value is t if tooltip was open, nil otherwise.  */)
  3399   (void)
  3400 {
  3401   return pgtk_hide_tip (!tooltip_reuse_hidden_frame);
  3402 }
  3403 
  3404 /* Return geometric attributes of FRAME.  According to the value of
  3405    ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the inner
  3406    edges of FRAME, the root window edges of frame (Qroot_edges).  Any
  3407    other value means to return the geometry as returned by
  3408    Fx_frame_geometry.  */
  3409 static Lisp_Object
  3410 frame_geometry (Lisp_Object frame, Lisp_Object attribute)
  3411 {
  3412   struct frame *f = decode_live_frame (frame);
  3413   Lisp_Object fullscreen_symbol = Fframe_parameter (frame, Qfullscreen);
  3414   bool fullscreen = (EQ (fullscreen_symbol, Qfullboth)
  3415                      || EQ (fullscreen_symbol, Qfullscreen));
  3416   int border = fullscreen ? 0 : f->border_width;
  3417   int title_height = 0;
  3418   int native_width = FRAME_PIXEL_WIDTH (f);
  3419   int native_height = FRAME_PIXEL_HEIGHT (f);
  3420   int outer_width = native_width + 2 * border;
  3421   int outer_height = native_height + 2 * border + title_height;
  3422 
  3423   /* Get these here because they can't be got in configure_event(). */
  3424   int left_pos, top_pos;
  3425 
  3426   if (FRAME_GTK_OUTER_WIDGET (f))
  3427     gtk_window_get_position (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
  3428                              &left_pos, &top_pos);
  3429   else
  3430     {
  3431       GtkAllocation alloc;
  3432 
  3433       if (FRAME_GTK_WIDGET (f) == NULL)
  3434         return Qnil;    /* This can occur while creating a frame.  */
  3435 
  3436       gtk_widget_get_allocation (FRAME_GTK_WIDGET (f), &alloc);
  3437       left_pos = alloc.x;
  3438       top_pos = alloc.y;
  3439     }
  3440 
  3441   int native_left = left_pos + border;
  3442   int native_top = top_pos + border + title_height;
  3443   int native_right = left_pos + outer_width - border;
  3444   int native_bottom = top_pos + outer_height - border;
  3445   int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
  3446   int tab_bar_height = 0, tab_bar_width = 0;
  3447   int tool_bar_height = FRAME_TOOLBAR_HEIGHT (f);
  3448   int tool_bar_width = (tool_bar_height
  3449                         ? outer_width - 2 * internal_border_width : 0);
  3450 
  3451   tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
  3452   tab_bar_width = (tab_bar_height
  3453                    ? native_width - 2 * internal_border_width : 0);
  3454 
  3455   /* Construct list.  */
  3456   if (EQ (attribute, Qouter_edges))
  3457     return list4 (make_fixnum (left_pos), make_fixnum (top_pos),
  3458                   make_fixnum (left_pos + outer_width),
  3459                   make_fixnum (top_pos + outer_height));
  3460   else if (EQ (attribute, Qnative_edges))
  3461     return list4 (make_fixnum (native_left), make_fixnum (native_top),
  3462                   make_fixnum (native_right), make_fixnum (native_bottom));
  3463   else if (EQ (attribute, Qinner_edges))
  3464     return list4 (make_fixnum (native_left + internal_border_width),
  3465                   make_fixnum (native_top
  3466                                + tab_bar_height
  3467                                + FRAME_TOOL_BAR_TOP_HEIGHT (f)
  3468                                + internal_border_width),
  3469                   make_fixnum (native_right - internal_border_width),
  3470                   make_fixnum (native_bottom - internal_border_width
  3471                                - FRAME_TOOL_BAR_BOTTOM_HEIGHT (f)));
  3472   else
  3473     return
  3474       list (Fcons (Qouter_position,
  3475                    Fcons (make_fixnum (left_pos),
  3476                           make_fixnum (top_pos))),
  3477             Fcons (Qouter_size,
  3478                    Fcons (make_fixnum (outer_width),
  3479                           make_fixnum (outer_height))),
  3480             Fcons (Qexternal_border_size,
  3481                    (fullscreen
  3482                     ? Fcons (make_fixnum (0), make_fixnum (0))
  3483                     : Fcons (make_fixnum (border), make_fixnum (border)))),
  3484             Fcons (Qtitle_bar_size,
  3485                    Fcons (make_fixnum (0), make_fixnum (title_height))),
  3486             Fcons (Qmenu_bar_external, Qnil),
  3487             Fcons (Qmenu_bar_size, Fcons (make_fixnum (0), make_fixnum (0))),
  3488             Fcons (Qtab_bar_size,
  3489                    Fcons (make_fixnum (tab_bar_width),
  3490                           make_fixnum (tab_bar_height))),
  3491             Fcons (Qtool_bar_external,
  3492                    FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil),
  3493             Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
  3494             Fcons (Qtool_bar_size,
  3495                    Fcons (make_fixnum (tool_bar_width),
  3496                           make_fixnum (tool_bar_height))),
  3497             Fcons (Qinternal_border_width,
  3498                    make_fixnum (internal_border_width)));
  3499 }
  3500 
  3501 DEFUN ("pgtk-frame-geometry", Fpgtk_frame_geometry, Spgtk_frame_geometry, 0, 1, 0,
  3502        doc: /* Return geometric attributes of FRAME.
  3503 FRAME must be a live frame and defaults to the selected one.  The return
  3504 value is an association list of the attributes listed below.  All height
  3505 and width values are in pixels.
  3506 
  3507 `outer-position' is a cons of the outer left and top edges of FRAME
  3508 relative to the origin - the position (0, 0) - of FRAME's display.
  3509 
  3510 `outer-size' is a cons of the outer width and height of FRAME.  The
  3511 outer size includes the title bar and the external borders as well as
  3512 any menu and/or tool bar of frame.
  3513 
  3514 `external-border-size' is a cons of the horizontal and vertical width of
  3515 FRAME's external borders as supplied by the window manager.
  3516 
  3517 `title-bar-size' is a cons of the width and height of the title bar of
  3518 FRAME as supplied by the window manager.  If both of them are zero,
  3519 FRAME has no title bar.  If only the width is zero, Emacs was not
  3520 able to retrieve the width information.
  3521 
  3522 `menu-bar-external', if non-nil, means the menu bar is external (never
  3523 included in the inner edges of FRAME).
  3524 
  3525 `menu-bar-size' is a cons of the width and height of the menu bar of
  3526 FRAME.
  3527 
  3528 `tool-bar-external', if non-nil, means the tool bar is external (never
  3529 included in the inner edges of FRAME).
  3530 
  3531 `tool-bar-position' tells on which side the tool bar on FRAME is and can
  3532 be one of `left', `top', `right' or `bottom'.  If this is nil, FRAME
  3533 has no tool bar.
  3534 
  3535 `tool-bar-size' is a cons of the width and height of the tool bar of
  3536 FRAME.
  3537 
  3538 `internal-border-width' is the width of the internal border of
  3539 FRAME.  */)
  3540   (Lisp_Object frame)
  3541 {
  3542   return frame_geometry (frame, Qnil);
  3543 }
  3544 
  3545 DEFUN ("pgtk-frame-edges", Fpgtk_frame_edges, Spgtk_frame_edges, 0, 2, 0,
  3546        doc: /* Return edge coordinates of FRAME.
  3547 FRAME must be a live frame and defaults to the selected one.  The return
  3548 value is a list of the form (LEFT, TOP, RIGHT, BOTTOM).  All values are
  3549 in pixels relative to the origin - the position (0, 0) - of FRAME's
  3550 display.
  3551 
  3552 If optional argument TYPE is the symbol `outer-edges', return the outer
  3553 edges of FRAME.  The outer edges comprise the decorations of the window
  3554 manager (like the title bar or external borders) as well as any external
  3555 menu or tool bar of FRAME.  If optional argument TYPE is the symbol
  3556 `native-edges' or nil, return the native edges of FRAME.  The native
  3557 edges exclude the decorations of the window manager and any external
  3558 menu or tool bar of FRAME.  If TYPE is the symbol `inner-edges', return
  3559 the inner edges of FRAME.  These edges exclude title bar, any borders,
  3560 menu bar or tool bar of FRAME.  */)
  3561   (Lisp_Object frame, Lisp_Object type)
  3562 {
  3563   return frame_geometry (frame, ((EQ (type, Qouter_edges)
  3564                                   || EQ (type, Qinner_edges))
  3565                                  ? type : Qnative_edges));
  3566 }
  3567 
  3568 DEFUN ("pgtk-set-mouse-absolute-pixel-position",
  3569        Fpgtk_set_mouse_absolute_pixel_position,
  3570        Spgtk_set_mouse_absolute_pixel_position, 2, 2, 0,
  3571        doc: /* Move mouse pointer to absolute pixel position (X, Y).
  3572 The coordinates X and Y are interpreted in pixels relative to a position
  3573 \(0, 0) of the selected frame's display.  */)
  3574   (Lisp_Object x, Lisp_Object y)
  3575 {
  3576   struct frame *f = SELECTED_FRAME ();
  3577   GtkWidget *widget = gtk_widget_get_toplevel (FRAME_WIDGET (f));
  3578   GdkWindow *window = gtk_widget_get_window (widget);
  3579   GdkDisplay *gdpy = gdk_window_get_display (window);
  3580   GdkScreen *gscr = gdk_window_get_screen (window);
  3581   GdkSeat *seat = gdk_display_get_default_seat (gdpy);
  3582   GdkDevice *device = gdk_seat_get_pointer (seat);
  3583 
  3584   gdk_device_warp (device, gscr, XFIXNUM (x), XFIXNUM (y));     /* No effect on wayland. */
  3585 
  3586   return Qnil;
  3587 }
  3588 
  3589 DEFUN ("pgtk-mouse-absolute-pixel-position",
  3590        Fpgtk_mouse_absolute_pixel_position,
  3591        Spgtk_mouse_absolute_pixel_position, 0, 0, 0,
  3592        doc: /* Return absolute position of mouse cursor in pixels.
  3593 The position is returned as a cons cell (X . Y) of the
  3594 coordinates of the mouse cursor position in pixels relative to a
  3595 position (0, 0) of the selected frame's terminal. */)
  3596   (void)
  3597 {
  3598   struct frame *f = SELECTED_FRAME ();
  3599   GtkWidget *widget = gtk_widget_get_toplevel (FRAME_WIDGET (f));
  3600   GdkWindow *window = gtk_widget_get_window (widget);
  3601   GdkDisplay *gdpy = gdk_window_get_display (window);
  3602   GdkScreen *gscr;
  3603   GdkSeat *seat = gdk_display_get_default_seat (gdpy);
  3604   GdkDevice *device = gdk_seat_get_pointer (seat);
  3605   int x = 0, y = 0;
  3606 
  3607   gdk_device_get_position (device, &gscr, &x, &y);      /* can't get on wayland? */
  3608 
  3609   return Fcons (make_fixnum (x), make_fixnum (y));
  3610 }
  3611 
  3612 
  3613 DEFUN ("pgtk-page-setup-dialog", Fpgtk_page_setup_dialog,
  3614        Spgtk_page_setup_dialog, 0, 0, 0,
  3615        doc: /* Pop up a page setup dialog.
  3616 The current page setup can be obtained using `x-get-page-setup'.  */)
  3617   (void)
  3618 {
  3619   block_input ();
  3620   xg_page_setup_dialog ();
  3621   unblock_input ();
  3622 
  3623   return Qnil;
  3624 }
  3625 
  3626 DEFUN ("pgtk-get-page-setup", Fpgtk_get_page_setup,
  3627        Spgtk_get_page_setup, 0, 0, 0,
  3628        doc: /* Return the value of the current page setup.
  3629 The return value is an alist containing the following keys:
  3630 
  3631 orientation: page orientation (symbol `portrait', `landscape',
  3632 `reverse-portrait', or `reverse-landscape').
  3633 width, height: page width/height in points not including margins.
  3634 left-margin, right-margin, top-margin, bottom-margin: print margins,
  3635 which is the parts of the page that the printer cannot print
  3636 on, in points.
  3637 
  3638 The paper width can be obtained as the sum of width, left-margin, and
  3639 right-margin values if the page orientation is `portrait' or
  3640 `reverse-portrait'.  Otherwise, it is the sum of width, top-margin,
  3641 and bottom-margin values.  Likewise, the paper height is the sum of
  3642 height, top-margin, and bottom-margin values if the page orientation
  3643 is `portrait' or `reverse-portrait'.  Otherwise, it is the sum of
  3644 height, left-margin, and right-margin values.  */)
  3645   (void)
  3646 {
  3647   Lisp_Object result;
  3648 
  3649   block_input ();
  3650   result = xg_get_page_setup ();
  3651   unblock_input ();
  3652 
  3653   return result;
  3654 }
  3655 
  3656 DEFUN ("pgtk-print-frames-dialog", Fpgtk_print_frames_dialog, Spgtk_print_frames_dialog, 0, 1, "",
  3657        doc: /* Pop up a print dialog to print the current contents of FRAMES.
  3658 FRAMES should be nil (the selected frame), a frame, or a list of
  3659 frames (each of which corresponds to one page).  Each frame should be
  3660 visible.  */)
  3661   (Lisp_Object frames)
  3662 {
  3663   Lisp_Object rest, tmp;
  3664 
  3665   if (!CONSP (frames))
  3666     frames = list1 (frames);
  3667 
  3668   tmp = Qnil;
  3669   for (rest = frames; CONSP (rest); rest = XCDR (rest))
  3670     {
  3671       struct frame *f = decode_window_system_frame (XCAR (rest));
  3672       Lisp_Object frame;
  3673 
  3674       XSETFRAME (frame, f);
  3675       if (!FRAME_VISIBLE_P (f))
  3676         error ("Frames to be printed must be visible.");
  3677       tmp = Fcons (frame, tmp);
  3678     }
  3679   frames = Fnreverse (tmp);
  3680 
  3681   /* Make sure the current matrices are up-to-date.  */
  3682   specpdl_ref count = SPECPDL_INDEX ();
  3683   specbind (Qredisplay_dont_pause, Qt);
  3684   redisplay_preserve_echo_area (32);
  3685   unbind_to (count, Qnil);
  3686 
  3687   block_input ();
  3688   xg_print_frames_dialog (frames);
  3689   unblock_input ();
  3690 
  3691   return Qnil;
  3692 }
  3693 
  3694 static void
  3695 clean_up_dialog (void)
  3696 {
  3697   pgtk_menu_set_in_use (false);
  3698 }
  3699 
  3700 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
  3701        doc: /* Read file name, prompting with PROMPT in directory DIR.
  3702 Use a file selection dialog.  Select DEFAULT-FILENAME in the dialog's file
  3703 selection box, if specified.  If MUSTMATCH is non-nil, the returned file
  3704 or directory must exist.
  3705 
  3706 This function is defined only on PGTK, NS, MS Windows, and X Windows with the
  3707 Motif or Gtk toolkits.  With the Motif toolkit, ONLY-DIR-P is ignored.
  3708 Otherwise, if ONLY-DIR-P is non-nil, the user can select only directories.
  3709 On MS Windows 7 and later, the file selection dialog "remembers" the last
  3710 directory where the user selected a file, and will open that directory
  3711 instead of DIR on subsequent invocations of this function with the same
  3712 value of DIR as in previous invocations; this is standard MS Windows behavior.  */)
  3713   (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename,
  3714    Lisp_Object mustmatch, Lisp_Object only_dir_p)
  3715 {
  3716   struct frame *f = SELECTED_FRAME ();
  3717   char *fn;
  3718   Lisp_Object file = Qnil;
  3719   Lisp_Object decoded_file;
  3720   specpdl_ref count = SPECPDL_INDEX ();
  3721   char *cdef_file;
  3722 
  3723   check_window_system (f);
  3724 
  3725   if (popup_activated ())
  3726     error ("Trying to use a menu from within a menu-entry");
  3727   else
  3728     pgtk_menu_set_in_use (true);
  3729 
  3730   CHECK_STRING (prompt);
  3731   CHECK_STRING (dir);
  3732 
  3733   /* Prevent redisplay.  */
  3734   specbind (Qinhibit_redisplay, Qt);
  3735   record_unwind_protect_void (clean_up_dialog);
  3736 
  3737   block_input ();
  3738 
  3739   if (STRINGP (default_filename))
  3740     cdef_file = SSDATA (default_filename);
  3741   else
  3742     cdef_file = SSDATA (dir);
  3743 
  3744   fn = xg_get_file_name (f, SSDATA (prompt), cdef_file,
  3745                          !NILP (mustmatch), !NILP (only_dir_p));
  3746 
  3747   if (fn)
  3748     {
  3749       file = build_string (fn);
  3750       xfree (fn);
  3751     }
  3752 
  3753   unblock_input ();
  3754 
  3755   /* Make "Cancel" equivalent to C-g.  */
  3756   if (NILP (file))
  3757     quit ();
  3758 
  3759   decoded_file = DECODE_FILE (file);
  3760 
  3761   return unbind_to (count, decoded_file);
  3762 }
  3763 
  3764 DEFUN ("pgtk-backend-display-class", Fpgtk_backend_display_class, Spgtk_backend_display_class, 0, 1, "",
  3765        doc: /* Return the name of the Gdk backend display class of TERMINAL.
  3766 The optional argument TERMINAL specifies which display to ask about.
  3767 TERMINAL should be a terminal object, a frame or a display name (a string).
  3768 If omitted or nil, that stands for the selected frame's display.  */)
  3769   (Lisp_Object terminal)
  3770 {
  3771   struct pgtk_display_info *dpyinfo = check_pgtk_display_info (terminal);
  3772   GdkDisplay *gdpy = dpyinfo->gdpy;
  3773   const gchar *type_name = G_OBJECT_TYPE_NAME (G_OBJECT (gdpy));
  3774   return build_string (type_name);
  3775 }
  3776 
  3777 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
  3778        doc: /* Read a font using a GTK dialog and return a font spec.
  3779 
  3780 FRAME is the frame on which to pop up the font chooser.  If omitted or
  3781 nil, it defaults to the selected frame. */)
  3782   (Lisp_Object frame, Lisp_Object ignored)
  3783 {
  3784   struct frame *f = decode_window_system_frame (frame);
  3785   Lisp_Object font;
  3786   Lisp_Object font_param;
  3787   char *default_name = NULL;
  3788   specpdl_ref count = SPECPDL_INDEX ();
  3789 
  3790   if (popup_activated ())
  3791     error ("Trying to use a menu from within a menu-entry");
  3792   else
  3793     pgtk_menu_set_in_use (true);
  3794 
  3795   /* Prevent redisplay.  */
  3796   specbind (Qinhibit_redisplay, Qt);
  3797   record_unwind_protect_void (clean_up_dialog);
  3798 
  3799   block_input ();
  3800 
  3801   XSETFONT (font, FRAME_FONT (f));
  3802   font_param = Ffont_get (font, QCname);
  3803   if (STRINGP (font_param))
  3804     default_name = xlispstrdup (font_param);
  3805   else
  3806     {
  3807       font_param = Fframe_parameter (frame, Qfont_parameter);
  3808       if (STRINGP (font_param))
  3809         default_name = xlispstrdup (font_param);
  3810     }
  3811 
  3812   font = xg_get_font (f, default_name);
  3813   xfree (default_name);
  3814 
  3815   unblock_input ();
  3816 
  3817   if (NILP (font))
  3818     quit ();
  3819 
  3820   return unbind_to (count, font);
  3821 }
  3822 
  3823 DEFUN ("x-gtk-debug", Fx_gtk_debug, Sx_gtk_debug, 1, 1, 0,
  3824        doc: /* SKIP: real doc in xfns.c.  */)
  3825   (Lisp_Object enable)
  3826 {
  3827   gboolean enable_debug = !NILP (enable);
  3828 
  3829   block_input ();
  3830   gtk_window_set_interactive_debugging (enable_debug);
  3831   unblock_input ();
  3832 
  3833   return NILP (enable) ? Qnil : Qt;
  3834 }
  3835 
  3836 void
  3837 syms_of_pgtkfns (void)
  3838 {
  3839   DEFSYM (Qfont_parameter, "font-parameter");
  3840   DEFSYM (Qfontsize, "fontsize");
  3841   DEFSYM (Qcancel_timer, "cancel-timer");
  3842   DEFSYM (Qframe_title_format, "frame-title-format");
  3843   DEFSYM (Qicon_title_format, "icon-title-format");
  3844   DEFSYM (Qdark, "dark");
  3845   DEFSYM (Qhide, "hide");
  3846   DEFSYM (Qresize_mode, "resize-mode");
  3847 
  3848   DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
  3849                doc: /* SKIP: real doc in xfns.c.  */);
  3850   Vx_cursor_fore_pixel = Qnil;
  3851 
  3852   Fprovide (intern_c_string ("gtk"), Qnil);
  3853 
  3854   DEFVAR_LISP ("gtk-version-string", Vgtk_version_string,
  3855                doc: /* Version info for GTK+.  */);
  3856   {
  3857     char *ver = g_strdup_printf ("%d.%d.%d",
  3858                                  GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
  3859                                  GTK_MICRO_VERSION);
  3860     int len = strlen (ver);
  3861     Vgtk_version_string = make_pure_string (ver, len, len, false);
  3862     g_free (ver);
  3863   }
  3864 
  3865 
  3866   Fprovide (intern_c_string ("cairo"), Qnil);
  3867 
  3868   DEFVAR_LISP ("cairo-version-string", Vcairo_version_string,
  3869                doc: /* Version info for cairo.  */);
  3870   {
  3871     char *ver = g_strdup_printf ("%d.%d.%d",
  3872                                  CAIRO_VERSION_MAJOR, CAIRO_VERSION_MINOR,
  3873                                  CAIRO_VERSION_MICRO);
  3874     int len = strlen (ver);
  3875     Vcairo_version_string = make_pure_string (ver, len, len, false);
  3876     g_free (ver);
  3877   }
  3878 
  3879   defsubr (&Spgtk_set_resource);
  3880   defsubr (&Sxw_display_color_p);       /* this and next called directly by C code */
  3881   defsubr (&Sx_display_grayscale_p);
  3882   defsubr (&Spgtk_font_name);
  3883   defsubr (&Sxw_color_defined_p);
  3884   defsubr (&Sxw_color_values);
  3885   defsubr (&Sx_server_max_request_size);
  3886   defsubr (&Sx_display_pixel_width);
  3887   defsubr (&Sx_display_pixel_height);
  3888   defsubr (&Spgtk_display_monitor_attributes_list);
  3889   defsubr (&Spgtk_frame_geometry);
  3890   defsubr (&Spgtk_frame_edges);
  3891   defsubr (&Spgtk_frame_restack);
  3892   defsubr (&Spgtk_set_mouse_absolute_pixel_position);
  3893   defsubr (&Spgtk_mouse_absolute_pixel_position);
  3894   defsubr (&Sx_display_mm_width);
  3895   defsubr (&Sx_display_mm_height);
  3896   defsubr (&Sx_display_screens);
  3897   defsubr (&Sx_display_planes);
  3898   defsubr (&Sx_display_color_cells);
  3899   defsubr (&Sx_display_visual_class);
  3900   defsubr (&Sx_display_backing_store);
  3901   defsubr (&Sx_display_save_under);
  3902   defsubr (&Sx_create_frame);
  3903   defsubr (&Sx_open_connection);
  3904   defsubr (&Sx_close_connection);
  3905   defsubr (&Sx_display_list);
  3906   defsubr (&Sx_gtk_debug);
  3907 
  3908   defsubr (&Sx_show_tip);
  3909   defsubr (&Sx_hide_tip);
  3910 
  3911   defsubr (&Sx_export_frames);
  3912   defsubr (&Spgtk_page_setup_dialog);
  3913   defsubr (&Spgtk_get_page_setup);
  3914   defsubr (&Spgtk_print_frames_dialog);
  3915   defsubr (&Spgtk_backend_display_class);
  3916 
  3917   defsubr (&Spgtk_set_monitor_scale_factor);
  3918 
  3919   defsubr (&Sx_file_dialog);
  3920   defsubr (&Sx_select_font);
  3921 
  3922   monitor_scale_factor_alist = Qnil;
  3923   staticpro (&monitor_scale_factor_alist);
  3924 
  3925   tip_timer = Qnil;
  3926   staticpro (&tip_timer);
  3927   tip_frame = Qnil;
  3928   staticpro (&tip_frame);
  3929   tip_last_frame = Qnil;
  3930   staticpro (&tip_last_frame);
  3931   tip_last_string = Qnil;
  3932   staticpro (&tip_last_string);
  3933   tip_last_parms = Qnil;
  3934   staticpro (&tip_last_parms);
  3935 
  3936   /* This is not ifdef:ed, so other builds than GTK can customize it.  */
  3937   DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog,
  3938                doc: /* SKIP: real doc in xfns.c.  */);
  3939   x_gtk_use_old_file_dialog = false;
  3940 
  3941   DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files,
  3942                doc: /* SKIP: real doc in xfns.c.  */);
  3943   x_gtk_show_hidden_files = false;
  3944 
  3945   DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text,
  3946                doc: /* SKIP: real doc in xfns.c.  */);
  3947   x_gtk_file_dialog_help_text = true;
  3948 
  3949   DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
  3950                doc: /* SKIP: real doc in xfns.c.  */);
  3951   Vx_max_tooltip_size = Qnil;
  3952 
  3953   DEFSYM (Qmono, "mono");
  3954   DEFSYM (Qassq_delete_all, "assq-delete-all");
  3955 
  3956   DEFSYM (Qpdf, "pdf");
  3957 
  3958   DEFSYM (Qorientation, "orientation");
  3959   DEFSYM (Qtop_margin, "top-margin");
  3960   DEFSYM (Qbottom_margin, "bottom-margin");
  3961   DEFSYM (Qportrait, "portrait");
  3962   DEFSYM (Qlandscape, "landscape");
  3963   DEFSYM (Qreverse_portrait, "reverse-portrait");
  3964   DEFSYM (Qreverse_landscape, "reverse-landscape");
  3965 }

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