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