root/src/xfns.c

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

DEFINITIONS

This source file includes following definitions.
  1. check_x_display_info
  2. x_real_pos_and_offsets
  3. x_real_positions
  4. x_relative_mouse_position
  5. gamma_correct
  6. x_defined_color
  7. x_decode_color
  8. x_set_wait_for_wm
  9. x_set_alpha_background
  10. x_set_tool_bar_position
  11. x_set_inhibit_double_buffering
  12. x_set_undecorated
  13. x_set_parent_frame
  14. x_set_no_focus_on_map
  15. x_set_no_accept_focus
  16. x_set_override_redirect
  17. xg_set_icon
  18. xg_set_icon_from_xpm_data
  19. x_set_foreground_color
  20. x_set_background_color
  21. x_set_mouse_color_handler
  22. x_set_mouse_color
  23. x_set_cursor_color
  24. x_set_border_pixel
  25. x_set_border_color
  26. x_set_cursor_type
  27. x_set_icon_type
  28. x_set_icon_name
  29. x_set_menu_bar_lines
  30. x_set_tab_bar_lines
  31. x_change_tab_bar_height
  32. x_set_tool_bar_lines
  33. x_change_tool_bar_height
  34. x_set_child_frame_border_width
  35. x_set_internal_border_width
  36. x_set_scroll_bar_foreground
  37. x_set_scroll_bar_background
  38. x_encode_text
  39. x_set_name_internal
  40. x_set_name
  41. x_explicitly_set_name
  42. x_implicitly_set_name
  43. x_set_title
  44. x_set_scroll_bar_default_width
  45. x_set_scroll_bar_default_height
  46. x_set_alpha
  47. x_set_use_frame_synchronization
  48. x_default_scroll_bar_color_parameter
  49. hack_wm_protocols
  50. append_wm_protocols
  51. xic_create_fontsetname
  52. print_fontset_result
  53. xic_create_xfontset
  54. xic_free_xfontset
  55. best_xim_style
  56. create_frame_xic
  57. free_frame_xic
  58. xic_set_preeditarea
  59. xic_set_statusarea
  60. x_xic_to_frame
  61. xic_preedit_start_callback
  62. xic_preedit_caret_callback
  63. xic_preedit_done_callback
  64. x_xim_text_to_utf8_unix_1
  65. x_xim_text_to_utf8_unix_2
  66. x_xim_text_to_utf8_unix
  67. xic_preedit_draw_callback
  68. xic_set_xfontset
  69. x_mark_frame_dirty
  70. set_up_x_back_buffer
  71. tear_down_x_back_buffer
  72. initial_set_up_x_back_buffer
  73. setup_xi_event_mask
  74. x_window
  75. x_window
  76. x_window
  77. x_icon_verify
  78. x_icon
  79. x_make_gc
  80. x_free_gcs
  81. unwind_create_frame
  82. do_unwind_create_frame
  83. x_default_font_parameter
  84. DEFUN
  85. set_machine_and_pid_properties
  86. DEFUN
  87. DEFUN
  88. DEFUN
  89. DEFUN
  90. DEFUN
  91. DEFUN
  92. DEFUN
  93. DEFUN
  94. DEFUN
  95. DEFUN
  96. DEFUN
  97. DEFUN
  98. DEFUN
  99. DEFUN
  100. DEFUN
  101. DEFUN
  102. DEFUN
  103. x_get_net_workarea
  104. x_get_monitor_for_frame
  105. x_make_monitor_attribute_list
  106. x_get_monitor_attributes_fallback
  107. x_get_monitor_attributes_xinerama
  108. x_get_monitor_attributes_xrandr
  109. x_get_monitor_attributes
  110. xlw_monitor_dimensions_at_pos_1
  111. xlw_monitor_dimensions_at_pos
  112. DEFUN
  113. frame_geometry
  114. DEFUN
  115. x_frame_list_z_order
  116. DEFUN
  117. x_frame_restack
  118. DEFUN
  119. XScreenNumberOfScreen
  120. select_visual
  121. x_display_info_for_name
  122. DEFUN
  123. DEFUN
  124. x_sync
  125. x_window_property_intern
  126. unwind_create_tip_frame
  127. x_create_tip_frame
  128. compute_tip_xy
  129. x_hide_tip
  130. DEFUN
  131. DEFUN
  132. DEFUN
  133. file_dialog_cb
  134. file_dialog_unmap_cb
  135. clean_up_file_dialog
  136. clean_up_dialog
  137. DEFUN
  138. DEFUN
  139. DEFUN
  140. DEFUN
  141. DEFUN
  142. DEFUN
  143. DEFUN
  144. XkbRefreshKeyboardMapping
  145. XkbFreeNames
  146. XDisplayCells
  147. XDestroySubwindows
  148. syms_of_xfns

     1 /* Functions for the X Window System.
     2 
     3 Copyright (C) 1989, 1992-2023 Free Software Foundation, Inc.
     4 
     5 This file is part of GNU Emacs.
     6 
     7 GNU Emacs is free software: you can redistribute it and/or modify
     8 it under the terms of the GNU General Public License as published by
     9 the Free Software Foundation, either version 3 of the License, or (at
    10 your option) any later version.
    11 
    12 GNU Emacs is distributed in the hope that it will be useful,
    13 but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 GNU General Public License for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    19 
    20 #include <config.h>
    21 #include <stdio.h>
    22 #include <stdlib.h>
    23 #include <math.h>
    24 #include <unistd.h>
    25 
    26 #include "lisp.h"
    27 #include "character.h"
    28 #include "xterm.h"
    29 #include "frame.h"
    30 #include "window.h"
    31 #include "buffer.h"
    32 #include "dispextern.h"
    33 #include "keyboard.h"
    34 #include "blockinput.h"
    35 #include "charset.h"
    36 #include "coding.h"
    37 #include "termhooks.h"
    38 #include "font.h"
    39 
    40 #include <sys/types.h>
    41 #include <sys/stat.h>
    42 
    43 #ifdef USE_XCB
    44 #include <xcb/xcb.h>
    45 #include <xcb/xproto.h>
    46 #include <xcb/xcb_aux.h>
    47 #endif
    48 
    49 #include "bitmaps/gray.xbm"
    50 #include "xsettings.h"
    51 
    52 #ifdef HAVE_XRANDR
    53 #include <X11/extensions/Xrandr.h>
    54 #endif
    55 #ifdef HAVE_XINERAMA
    56 #include <X11/extensions/Xinerama.h>
    57 #endif
    58 
    59 #ifdef USE_GTK
    60 #include "gtkutil.h"
    61 #endif
    62 
    63 #ifdef HAVE_XDBE
    64 #include <X11/extensions/Xdbe.h>
    65 #endif
    66 
    67 #ifdef HAVE_XINPUT2
    68 #include <X11/extensions/XInput2.h>
    69 #endif
    70 
    71 #ifdef USE_X_TOOLKIT
    72 #include <X11/Shell.h>
    73 
    74 #ifndef USE_MOTIF
    75 #ifdef HAVE_XAW3D
    76 #include <X11/Xaw3d/Paned.h>
    77 #include <X11/Xaw3d/Label.h>
    78 #else /* !HAVE_XAW3D */
    79 #include <X11/Xaw/Paned.h>
    80 #include <X11/Xaw/Label.h>
    81 #endif /* HAVE_XAW3D */
    82 #endif /* USE_MOTIF */
    83 
    84 #ifdef USG
    85 #undef USG      /* ####KLUDGE for Solaris 2.2 and up */
    86 #include <X11/Xos.h>
    87 #define USG
    88 #ifdef USG /* Pacify gcc -Wunused-macros.  */
    89 #endif
    90 #else
    91 #include <X11/Xos.h>
    92 #endif
    93 
    94 #include "widget.h"
    95 
    96 #include "../lwlib/lwlib.h"
    97 
    98 #ifdef USE_MOTIF
    99 #include <Xm/Xm.h>
   100 #include <Xm/DialogS.h>
   101 #include <Xm/FileSB.h>
   102 #include <Xm/List.h>
   103 #include <Xm/TextF.h>
   104 #include <Xm/MwmUtil.h>
   105 #endif
   106 
   107 #ifdef USE_LUCID
   108 #include "../lwlib/xlwmenu.h"
   109 #endif
   110 
   111 /* Unique id counter for widgets created by the Lucid Widget Library.  */
   112 
   113 extern LWLIB_ID widget_id_tick;
   114 
   115 #ifdef USE_MOTIF
   116 
   117 #endif /* USE_MOTIF */
   118 
   119 #endif /* USE_X_TOOLKIT */
   120 
   121 #ifdef USE_GTK
   122 
   123 #endif /* USE_GTK */
   124 
   125 #define MAXREQUEST(dpy) (XMaxRequestSize (dpy))
   126 
   127 static ptrdiff_t image_cache_refcount;
   128 #ifdef GLYPH_DEBUG
   129 static int dpyinfo_refcount;
   130 #endif
   131 
   132 #ifndef USE_MOTIF
   133 #ifndef USE_GTK
   134 /** #define MWM_HINTS_FUNCTIONS     (1L << 0) **/
   135 #define MWM_HINTS_DECORATIONS   (1L << 1)
   136 /** #define MWM_HINTS_INPUT_MODE    (1L << 2) **/
   137 /** #define MWM_HINTS_STATUS        (1L << 3) **/
   138 
   139 #define MWM_DECOR_ALL           (1L << 0)
   140 /** #define MWM_DECOR_BORDER        (1L << 1) **/
   141 /** #define MWM_DECOR_RESIZEH       (1L << 2) **/
   142 /** #define MWM_DECOR_TITLE         (1L << 3) **/
   143 /** #define MWM_DECOR_MENU          (1L << 4) **/
   144 /** #define MWM_DECOR_MINIMIZE      (1L << 5) **/
   145 /** #define MWM_DECOR_MAXIMIZE      (1L << 6) **/
   146 
   147 /** #define _XA_MOTIF_WM_HINTS "_MOTIF_WM_HINTS" **/
   148 
   149 typedef struct {
   150     unsigned long flags;
   151     unsigned long functions;
   152     unsigned long decorations;
   153     long input_mode;
   154     unsigned long status;
   155 } PropMotifWmHints;
   156 
   157 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
   158 #endif /* NOT USE_GTK */
   159 #endif /* NOT USE_MOTIF */
   160 
   161 static struct x_display_info *x_display_info_for_name (Lisp_Object);
   162 static void set_up_x_back_buffer (struct frame *f);
   163 
   164 /* Let the user specify an X display with a Lisp object.
   165    OBJECT may be nil, a frame or a terminal object.
   166    nil stands for the selected frame--or, if that is not an X frame,
   167    the first X display on the list.  */
   168 
   169 struct x_display_info *
   170 check_x_display_info (Lisp_Object object)
   171 {
   172   struct x_display_info *dpyinfo = NULL;
   173 
   174   if (NILP (object))
   175     {
   176       struct frame *sf = XFRAME (selected_frame);
   177 
   178       if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
   179         dpyinfo = FRAME_DISPLAY_INFO (sf);
   180       else if (x_display_list != 0)
   181         dpyinfo = x_display_list;
   182       else
   183         error ("X windows are not in use or not initialized");
   184     }
   185   else if (TERMINALP (object))
   186     {
   187       struct terminal *t = decode_live_terminal (object);
   188 
   189       if (t->type != output_x_window)
   190         error ("Terminal %d is not an X display", t->id);
   191 
   192       dpyinfo = t->display_info.x;
   193     }
   194   else if (STRINGP (object))
   195     dpyinfo = x_display_info_for_name (object);
   196   else
   197     {
   198       struct frame *f = decode_window_system_frame (object);
   199       dpyinfo = FRAME_DISPLAY_INFO (f);
   200     }
   201 
   202   return dpyinfo;
   203 }
   204 
   205 /* Return the screen positions and offsets of frame F.
   206    Store the offsets between FRAME_OUTER_WINDOW and the containing
   207    window manager window into LEFT_OFFSET_X, RIGHT_OFFSET_X,
   208    TOP_OFFSET_Y and BOTTOM_OFFSET_Y.
   209    Store the offsets between FRAME_X_WINDOW and the containing
   210    window manager window into X_PIXELS_DIFF and Y_PIXELS_DIFF.
   211    Store the screen positions of frame F into XPTR and YPTR.
   212    These are the positions of the containing window manager window,
   213    not Emacs's own window.  */
   214 void
   215 x_real_pos_and_offsets (struct frame *f,
   216                         int *left_offset_x,
   217                         int *right_offset_x,
   218                         int *top_offset_y,
   219                         int *bottom_offset_y,
   220                         int *x_pixels_diff,
   221                         int *y_pixels_diff,
   222                         int *xptr,
   223                         int *yptr,
   224                         int *outer_border)
   225 {
   226   int win_x = 0, win_y = 0, outer_x = 0, outer_y = 0;
   227   int real_x = 0, real_y = 0;
   228   bool had_errors = false;
   229   struct frame *parent_frame = FRAME_PARENT_FRAME (f);
   230   Window win = (parent_frame
   231                 ? FRAME_X_WINDOW (parent_frame)
   232                 : f->output_data.x->parent_desc);
   233   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   234   long max_len = 400;
   235   Atom target_type = XA_CARDINAL;
   236   unsigned int ow = 0, oh = 0;
   237   unsigned int fw = 0, fh = 0;
   238   unsigned int bw = 0;
   239   /* We resort to XCB if possible because there are several X calls
   240      here which require responses from the server but do not have data
   241      dependencies between them.  Using XCB lets us pipeline requests,
   242      whereas with Xlib we must wait for each answer before sending the
   243      next request.
   244 
   245      For a non-local display, the round-trip time could be a few tens
   246      of milliseconds, depending on the network distance.  It doesn't
   247      take a lot of those to add up to a noticeable hesitation in
   248      responding to user actions.  */
   249 #ifdef USE_XCB
   250   xcb_connection_t *xcb_conn = dpyinfo->xcb_connection;
   251   xcb_get_property_cookie_t prop_cookie;
   252   xcb_get_geometry_cookie_t outer_geom_cookie;
   253   bool sent_requests = false;
   254 #else
   255   Atom actual_type;
   256   unsigned long actual_size, bytes_remaining;
   257   int rc, actual_format;
   258   Display *dpy = FRAME_X_DISPLAY (f);
   259   unsigned char *tmp_data = NULL;
   260 #endif
   261 
   262   if (x_pixels_diff) *x_pixels_diff = 0;
   263   if (y_pixels_diff) *y_pixels_diff = 0;
   264   if (left_offset_x) *left_offset_x = 0;
   265   if (top_offset_y) *top_offset_y = 0;
   266   if (right_offset_x) *right_offset_x = 0;
   267   if (bottom_offset_y) *bottom_offset_y = 0;
   268   if (xptr) *xptr = 0;
   269   if (yptr) *yptr = 0;
   270   if (outer_border) *outer_border = 0;
   271 
   272   if (win == dpyinfo->root_window)
   273     win = FRAME_OUTER_WINDOW (f);
   274 
   275   block_input ();
   276 
   277 #ifndef USE_XCB
   278   /* If we're using XCB, all errors are checked for on each call.  */
   279   x_catch_errors (dpy);
   280 #endif
   281 
   282   /* This loop traverses up the containment tree until we hit the root
   283      window.  Window managers may intersect many windows between our window
   284      and the root window.  The window we find just before the root window
   285      should be the outer WM window. */
   286   for (;;)
   287     {
   288       Window wm_window UNINIT, rootw UNINIT;
   289 
   290 #ifdef USE_XCB
   291       xcb_query_tree_cookie_t query_tree_cookie;
   292       xcb_query_tree_reply_t *query_tree;
   293 
   294       query_tree_cookie = xcb_query_tree (xcb_conn, win);
   295       query_tree = xcb_query_tree_reply (xcb_conn, query_tree_cookie, NULL);
   296       if (query_tree == NULL)
   297         had_errors = true;
   298       else
   299         {
   300           wm_window = query_tree->parent;
   301           rootw = query_tree->root;
   302           free (query_tree);
   303         }
   304 #else
   305       Window *tmp_children;
   306       unsigned int tmp_nchildren;
   307       int success;
   308 
   309       success = XQueryTree (dpy, win, &rootw,
   310                             &wm_window, &tmp_children, &tmp_nchildren);
   311 
   312       had_errors = x_had_errors_p (dpy);
   313 
   314       /* Don't free tmp_children if XQueryTree failed.  */
   315       if (! success)
   316         break;
   317 
   318       XFree (tmp_children);
   319 #endif
   320 
   321       if (had_errors || wm_window == rootw)
   322         break;
   323 
   324       win = wm_window;
   325     }
   326 
   327   if (! had_errors)
   328     {
   329 #ifdef USE_XCB
   330       xcb_get_geometry_cookie_t geom_cookie;
   331       xcb_translate_coordinates_cookie_t trans_cookie;
   332       xcb_translate_coordinates_cookie_t outer_trans_cookie;
   333 
   334       xcb_translate_coordinates_reply_t *trans;
   335       xcb_get_geometry_reply_t *geom;
   336 #else
   337       Window child, rootw;
   338       unsigned int ign;
   339 #endif
   340 
   341 #ifdef USE_XCB
   342       /* Fire off the requests that don't have data dependencies.
   343 
   344          Once we've done this, we must collect the results for each
   345          one before returning, even if other errors are detected,
   346          making the other responses moot.  */
   347       geom_cookie = xcb_get_geometry (xcb_conn, win);
   348 
   349       trans_cookie =
   350         xcb_translate_coordinates (xcb_conn,
   351                                    /* From-window, to-window.  */
   352                                    FRAME_DISPLAY_INFO (f)->root_window,
   353                                    FRAME_X_WINDOW (f),
   354 
   355                                    /* From-position.  */
   356                                    0, 0);
   357       if (FRAME_X_WINDOW (f) != FRAME_OUTER_WINDOW (f))
   358         outer_trans_cookie =
   359           xcb_translate_coordinates (xcb_conn,
   360                                      /* From-window, to-window.  */
   361                                      FRAME_DISPLAY_INFO (f)->root_window,
   362                                      FRAME_OUTER_WINDOW (f),
   363 
   364                                      /* From-position.  */
   365                                      0, 0);
   366       if (right_offset_x || bottom_offset_y)
   367         outer_geom_cookie = xcb_get_geometry (xcb_conn,
   368                                               FRAME_OUTER_WINDOW (f));
   369 
   370       if (!parent_frame
   371           && dpyinfo->root_window == f->output_data.x->parent_desc)
   372         /* Try _NET_FRAME_EXTENTS if our parent is the root window.  */
   373         prop_cookie = xcb_get_property (xcb_conn, 0, win,
   374                                         dpyinfo->Xatom_net_frame_extents,
   375                                         target_type, 0, max_len);
   376 
   377       sent_requests = true;
   378 #endif
   379 
   380       /* Get the real coordinates for the WM window upper left corner */
   381 #ifdef USE_XCB
   382       geom = xcb_get_geometry_reply (xcb_conn, geom_cookie, NULL);
   383       if (geom)
   384         {
   385           real_x = geom->x;
   386           real_y = geom->y;
   387           ow = geom->width;
   388           oh = geom->height;
   389           bw = geom->border_width;
   390           free (geom);
   391         }
   392       else
   393         had_errors = true;
   394 #else
   395       XGetGeometry (dpy, win,
   396                     &rootw, &real_x, &real_y, &ow, &oh, &bw, &ign);
   397 #endif
   398 
   399       /* Translate real coordinates to coordinates relative to our
   400          window.  For our window, the upper left corner is 0, 0.
   401          Since the upper left corner of the WM window is outside
   402          our window, win_x and win_y will be negative:
   403 
   404          ------------------          ---> x
   405          |      title                |
   406          | -----------------         v y
   407          | |  our window
   408 
   409          Since we don't care about the child window corresponding to
   410          the actual coordinates, we can send zero to get the offsets
   411          and compute the resulting coordinates below.  This reduces
   412          the data dependencies between calls and lets us pipeline the
   413          requests better in the XCB case.  */
   414 #ifdef USE_XCB
   415       trans = xcb_translate_coordinates_reply (xcb_conn, trans_cookie, NULL);
   416       if (trans)
   417         {
   418           win_x = trans->dst_x;
   419           win_y = trans->dst_y;
   420           free (trans);
   421         }
   422       else
   423         had_errors = true;
   424 #else
   425       XTranslateCoordinates (dpy,
   426 
   427                              /* From-window, to-window.  */
   428                              FRAME_DISPLAY_INFO (f)->root_window,
   429                              FRAME_X_WINDOW (f),
   430 
   431                              /* From-position, to-position.  */
   432                              0, 0, &win_x, &win_y,
   433 
   434                              /* Child of win.  */
   435                              &child);
   436 #endif
   437 
   438       win_x += real_x;
   439       win_y += real_y;
   440 
   441       if (FRAME_X_WINDOW (f) == FRAME_OUTER_WINDOW (f))
   442         {
   443           outer_x = win_x;
   444           outer_y = win_y;
   445         }
   446       else
   447         {
   448 #ifdef USE_XCB
   449           xcb_translate_coordinates_reply_t *outer_trans;
   450 
   451           outer_trans = xcb_translate_coordinates_reply (xcb_conn,
   452                                                          outer_trans_cookie,
   453                                                          NULL);
   454           if (outer_trans)
   455             {
   456               outer_x = outer_trans->dst_x;
   457               outer_y = outer_trans->dst_y;
   458               free (outer_trans);
   459             }
   460           else
   461             had_errors = true;
   462 #else
   463           XTranslateCoordinates (dpy,
   464 
   465                                  /* From-window, to-window.  */
   466                                  FRAME_DISPLAY_INFO (f)->root_window,
   467                                  FRAME_OUTER_WINDOW (f),
   468 
   469                                  /* From-position, to-position.  */
   470                                  0, 0, &outer_x, &outer_y,
   471 
   472                                  /* Child of win.  */
   473                                  &child);
   474 #endif
   475 
   476           outer_x += real_x;
   477           outer_y += real_y;
   478         }
   479 
   480 #ifndef USE_XCB
   481       had_errors = x_had_errors_p (dpy);
   482 #endif
   483     }
   484 
   485   if (!parent_frame && dpyinfo->root_window == f->output_data.x->parent_desc)
   486     {
   487       /* Try _NET_FRAME_EXTENTS if our parent is the root window.  */
   488 #ifdef USE_XCB
   489       /* Make sure we didn't get an X error early and skip sending the
   490          request.  */
   491       if (sent_requests)
   492         {
   493           xcb_get_property_reply_t *prop;
   494 
   495           prop = xcb_get_property_reply (xcb_conn, prop_cookie, NULL);
   496           if (prop)
   497             {
   498               if (prop->type == target_type
   499                   && prop->format == 32
   500                   && (xcb_get_property_value_length (prop)
   501                       == 4 * sizeof (int32_t)))
   502                 {
   503                   int32_t *fe = xcb_get_property_value (prop);
   504 
   505                   outer_x = -fe[0];
   506                   outer_y = -fe[2];
   507                   real_x -= fe[0];
   508                   real_y -= fe[2];
   509                 }
   510               free (prop);
   511             }
   512           /* Xlib version doesn't set had_errors here.  Intentional or bug?  */
   513         }
   514 #else
   515       rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_frame_extents,
   516                                0, max_len, False, target_type,
   517                                &actual_type, &actual_format, &actual_size,
   518                                &bytes_remaining, &tmp_data);
   519 
   520       if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
   521           && actual_size == 4 && actual_format == 32)
   522         {
   523           long *fe = (long *)tmp_data;
   524 
   525           outer_x = -fe[0];
   526           outer_y = -fe[2];
   527           real_x -= fe[0];
   528           real_y -= fe[2];
   529         }
   530 
   531       if (tmp_data) XFree (tmp_data);
   532 #endif
   533     }
   534 
   535   if (right_offset_x || bottom_offset_y)
   536     {
   537 #ifdef USE_XCB
   538       /* Make sure we didn't get an X error early and skip sending the
   539          request.  */
   540       if (sent_requests)
   541         {
   542           xcb_get_geometry_reply_t *outer_geom;
   543 
   544           outer_geom = xcb_get_geometry_reply (xcb_conn, outer_geom_cookie,
   545                                                NULL);
   546           if (outer_geom)
   547             {
   548               fw = outer_geom->width;
   549               fh = outer_geom->height;
   550               free (outer_geom);
   551             }
   552           else
   553             had_errors = true;
   554         }
   555 #else
   556       int xy_ign;
   557       unsigned int ign;
   558       Window rootw;
   559 
   560       XGetGeometry (dpy, FRAME_OUTER_WINDOW (f),
   561                     &rootw, &xy_ign, &xy_ign, &fw, &fh, &ign, &ign);
   562 #endif
   563     }
   564 
   565 #ifndef USE_XCB
   566   x_uncatch_errors ();
   567 #endif
   568 
   569   unblock_input ();
   570 
   571   if (had_errors) return;
   572 
   573   if (x_pixels_diff) *x_pixels_diff = -win_x;
   574   if (y_pixels_diff) *y_pixels_diff = -win_y;
   575 
   576   if (left_offset_x) *left_offset_x = -outer_x;
   577   if (top_offset_y) *top_offset_y = -outer_y;
   578 
   579   if (xptr) *xptr = real_x;
   580   if (yptr) *yptr = real_y;
   581 
   582   if (outer_border) *outer_border = bw;
   583 
   584   if (right_offset_x) *right_offset_x = ow - fw + outer_x;
   585   if (bottom_offset_y) *bottom_offset_y = oh - fh + outer_y;
   586 }
   587 
   588 /* Store the screen positions of frame F into XPTR and YPTR.
   589    These are the positions of the containing window manager window,
   590    not Emacs's own window.  */
   591 
   592 void
   593 x_real_positions (struct frame *f, int *xptr, int *yptr)
   594 {
   595   x_real_pos_and_offsets (f, NULL, NULL, NULL, NULL, NULL, NULL, xptr, yptr,
   596                           NULL);
   597 }
   598 
   599 
   600 /* Get the mouse position in frame relative coordinates.  */
   601 
   602 void
   603 x_relative_mouse_position (struct frame *f, int *x, int *y)
   604 {
   605   Window root, dummy_window;
   606   int dummy;
   607 
   608   eassert (FRAME_X_P (f));
   609 
   610   block_input ();
   611 
   612   x_query_pointer (FRAME_X_DISPLAY (f),
   613                    FRAME_DISPLAY_INFO (f)->root_window,
   614 
   615                    /* The root window which contains the pointer.  */
   616                    &root,
   617 
   618                    /* Window pointer is on, not used  */
   619                    &dummy_window,
   620 
   621                    /* The position on that root window.  */
   622                    x, y,
   623 
   624                    /* x/y in dummy_window coordinates, not used.  */
   625                    &dummy, &dummy,
   626 
   627                    /* Modifier keys and pointer buttons, about which
   628                       we don't care.  */
   629                    (unsigned int *) &dummy);
   630 
   631   XTranslateCoordinates (FRAME_X_DISPLAY (f),
   632 
   633                          /* From-window, to-window.  */
   634                          FRAME_DISPLAY_INFO (f)->root_window,
   635                          FRAME_X_WINDOW (f),
   636 
   637                          /* From-position, to-position.  */
   638                          *x, *y, x, y,
   639 
   640                          /* Child of win.  */
   641                          &dummy_window);
   642 
   643   unblock_input ();
   644 }
   645 
   646 /* Gamma-correct COLOR on frame F.  */
   647 
   648 void
   649 gamma_correct (struct frame *f, XColor *color)
   650 {
   651   if (f->gamma)
   652     {
   653       color->red = pow (color->red / 65535.0, f->gamma) * 65535.0 + 0.5;
   654       color->green = pow (color->green / 65535.0, f->gamma) * 65535.0 + 0.5;
   655       color->blue = pow (color->blue / 65535.0, f->gamma) * 65535.0 + 0.5;
   656     }
   657 }
   658 
   659 
   660 /* Decide if color named COLOR_NAME is valid for use on frame F.  If
   661    so, return the RGB values in COLOR.  If ALLOC_P,
   662    allocate the color.  Value is false if COLOR_NAME is invalid, or
   663    no color could be allocated.  */
   664 
   665 bool
   666 x_defined_color (struct frame *f, const char *color_name,
   667                  Emacs_Color *color, bool alloc_p, bool _makeIndex)
   668 {
   669   bool success_p = false;
   670   Colormap cmap = FRAME_X_COLORMAP (f);
   671 
   672   block_input ();
   673 #ifdef USE_GTK
   674   success_p = xg_check_special_colors (f, color_name, color);
   675 #endif
   676   if (!success_p)
   677     success_p = x_parse_color (f, color_name, color) != 0;
   678   if (success_p && alloc_p)
   679     success_p = x_alloc_nearest_color (f, cmap, color);
   680   unblock_input ();
   681 
   682   return success_p;
   683 }
   684 
   685 
   686 /* Return the pixel color value for color COLOR_NAME on frame F.  If F
   687    is a monochrome frame, return MONO_COLOR regardless of what ARG says.
   688    Signal an error if color can't be allocated.  */
   689 
   690 static unsigned long
   691 x_decode_color (struct frame *f, Lisp_Object color_name, int mono_color)
   692 {
   693   XColor cdef;
   694 
   695   CHECK_STRING (color_name);
   696 
   697 #if false /* Don't do this.  It's wrong when we're not using the default
   698              colormap, it makes freeing difficult, and it's probably not
   699              an important optimization.  */
   700   if (strcmp (SDATA (color_name), "black") == 0)
   701     return BLACK_PIX_DEFAULT (f);
   702   else if (strcmp (SDATA (color_name), "white") == 0)
   703     return WHITE_PIX_DEFAULT (f);
   704 #endif
   705 
   706   /* Return MONO_COLOR for monochrome frames.  */
   707   if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
   708     return mono_color;
   709 
   710   /* x_defined_color is responsible for coping with failures
   711      by looking for a near-miss.  */
   712   if (x_defined_color (f, SSDATA (color_name), &cdef, true, false))
   713     return cdef.pixel;
   714 
   715   signal_error ("Undefined color", color_name);
   716 }
   717 
   718 
   719 
   720 /* Change the `wait-for-wm' frame parameter of frame F.  OLD_VALUE is
   721    the previous value of that parameter, NEW_VALUE is the new value.
   722    See also the comment of wait_for_wm in struct x_output.  */
   723 
   724 static void
   725 x_set_wait_for_wm (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
   726 {
   727   f->output_data.x->wait_for_wm = !NILP (new_value);
   728 }
   729 
   730 static void
   731 x_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   732 {
   733   unsigned long opaque_region[] = {0, 0, FRAME_PIXEL_WIDTH (f),
   734                                    FRAME_PIXEL_HEIGHT (f)};
   735 #ifdef HAVE_GTK3
   736   GObjectClass *object_class;
   737   GtkWidgetClass *class;
   738 #endif
   739 
   740   gui_set_alpha_background (f, arg, oldval);
   741 
   742 #ifdef HAVE_XRENDER
   743   /* Setting `alpha_background' to something other than opaque on a
   744      display that doesn't support the required features leads to
   745      confusing results.  */
   746   if (f->alpha_background < 1.0
   747       && !FRAME_DISPLAY_INFO (f)->alpha_bits
   748       && !FRAME_CHECK_XR_VERSION (f, 0, 2))
   749     f->alpha_background = 1.0;
   750 #else
   751   f->alpha_background = 1.0;
   752 #endif
   753 
   754 #ifdef USE_GTK
   755   /* This prevents GTK from painting the window's background, which
   756      interferes with transparent background in some environments */
   757 
   758   if (!FRAME_TOOLTIP_P (f))
   759     gtk_widget_set_app_paintable (FRAME_GTK_OUTER_WIDGET (f),
   760                                   f->alpha_background != 1.0);
   761 #endif
   762 
   763   if (!FRAME_DISPLAY_INFO (f)->alpha_bits)
   764     return;
   765 
   766   if (f->alpha_background != 1.0)
   767     {
   768       XChangeProperty (FRAME_X_DISPLAY (f),
   769                        FRAME_X_WINDOW (f),
   770                        FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
   771                        XA_CARDINAL, 32, PropModeReplace,
   772                        NULL, 0);
   773     }
   774 #ifndef HAVE_GTK3
   775   else
   776     XChangeProperty (FRAME_X_DISPLAY (f),
   777                      FRAME_X_WINDOW (f),
   778                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
   779                      XA_CARDINAL, 32, PropModeReplace,
   780                      (unsigned char *) &opaque_region, 4);
   781 #else
   782   else
   783     {
   784       if (FRAME_TOOLTIP_P (f))
   785         XChangeProperty (FRAME_X_DISPLAY (f),
   786                          FRAME_X_WINDOW (f),
   787                          FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
   788                          XA_CARDINAL, 32, PropModeReplace,
   789                          (unsigned char *) &opaque_region, 4);
   790       else
   791         {
   792           object_class = G_OBJECT_GET_CLASS (FRAME_GTK_OUTER_WIDGET (f));
   793           class = GTK_WIDGET_CLASS (object_class);
   794 
   795           if (class->style_updated)
   796             class->style_updated (FRAME_GTK_OUTER_WIDGET (f));
   797         }
   798     }
   799 #endif
   800 }
   801 
   802 static void
   803 x_set_tool_bar_position (struct frame *f,
   804                          Lisp_Object new_value,
   805                          Lisp_Object old_value)
   806 {
   807   Lisp_Object choice = list4 (Qleft, Qright, Qtop, Qbottom);
   808 
   809   if (!NILP (Fmemq (new_value, choice)))
   810     {
   811 #ifdef USE_GTK
   812       if (!EQ (new_value, old_value))
   813         {
   814           xg_change_toolbar_position (f, new_value);
   815           fset_tool_bar_position (f, new_value);
   816         }
   817 #else
   818       if (!EQ (new_value, Qtop))
   819         error ("The only supported tool bar position is top");
   820 #endif
   821     }
   822   else
   823     wrong_choice (choice, new_value);
   824 }
   825 
   826 #ifdef HAVE_XDBE
   827 static void
   828 x_set_inhibit_double_buffering (struct frame *f,
   829                                 Lisp_Object new_value,
   830                                 Lisp_Object old_value)
   831 {
   832   bool want_double_buffering, was_double_buffered;
   833 
   834   if (FRAME_X_WINDOW (f) && !EQ (new_value, old_value))
   835     {
   836       want_double_buffering = NILP (new_value);
   837       was_double_buffered = FRAME_X_DOUBLE_BUFFERED_P (f);
   838 
   839       block_input ();
   840       if (want_double_buffering != was_double_buffered)
   841         /* Force XftDraw etc to be recreated with the new double
   842            buffered drawable.  */
   843         font_drop_xrender_surfaces (f);
   844       if (FRAME_X_DOUBLE_BUFFERED_P (f) && !want_double_buffering)
   845         tear_down_x_back_buffer (f);
   846       else if (!FRAME_X_DOUBLE_BUFFERED_P (f) && want_double_buffering)
   847         set_up_x_back_buffer (f);
   848       if (FRAME_X_DOUBLE_BUFFERED_P (f) != was_double_buffered)
   849         {
   850           SET_FRAME_GARBAGED (f);
   851           font_drop_xrender_surfaces (f);
   852         }
   853       unblock_input ();
   854     }
   855 }
   856 #endif
   857 
   858 /**
   859  * x_set_undecorated:
   860  *
   861  * Set frame F's `undecorated' parameter.  If non-nil, F's window-system
   862  * window is drawn without decorations, title, minimize/maximize boxes
   863  * and external borders.  This usually means that the window cannot be
   864  * dragged, resized, iconified, maximized or deleted with the mouse.  If
   865  * nil, draw the frame with all the elements listed above unless these
   866  * have been suspended via window manager settings.
   867  *
   868  * Some window managers may not honor this parameter.
   869  */
   870 static void
   871 x_set_undecorated (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
   872 {
   873   if (!EQ (new_value, old_value))
   874     {
   875       FRAME_UNDECORATED (f) = NILP (new_value) ? false : true;
   876 #ifdef USE_GTK
   877       xg_set_undecorated (f, new_value);
   878 #else
   879       Display *dpy = FRAME_X_DISPLAY (f);
   880       PropMotifWmHints hints;
   881       Atom prop = FRAME_DISPLAY_INFO (f)->Xatom_MOTIF_WM_HINTS;
   882 
   883       memset (&hints, 0, sizeof(hints));
   884       hints.flags = MWM_HINTS_DECORATIONS;
   885       hints.decorations = NILP (new_value) ? MWM_DECOR_ALL : 0;
   886 
   887       block_input ();
   888       /* For some reason the third and fourth arguments in the following
   889          call must be identical: In the corresponding XGetWindowProperty
   890          call in getMotifHints, xfwm has the third and seventh args both
   891          display_info->atoms[MOTIF_WM_HINTS].  Obviously, YMMV.   */
   892       XChangeProperty (dpy, FRAME_OUTER_WINDOW (f), prop, prop, 32,
   893                        PropModeReplace, (unsigned char *) &hints,
   894                        PROP_MOTIF_WM_HINTS_ELEMENTS);
   895       unblock_input ();
   896 
   897 #endif /* USE_GTK */
   898     }
   899 }
   900 
   901 /**
   902  * x_set_parent_frame:
   903  *
   904  * Set frame F's `parent-frame' parameter.  If non-nil, make F a child
   905  * frame of the frame specified by that parameter.  Technically, this
   906  * makes F's window-system window a child window of the parent frame's
   907  * window-system window.  If nil, make F's window-system window a
   908  * top-level window--a child of its display's root window.
   909  *
   910  * A child frame is clipped at the native edges of its parent frame.
   911  * Its `left' and `top' parameters specify positions relative to the
   912  * top-left corner of its parent frame's native rectangle.  Usually,
   913  * moving a parent frame moves all its child frames too, keeping their
   914  * position relative to the parent unaltered.  When a parent frame is
   915  * iconified or made invisible, its child frames are made invisible.
   916  * When a parent frame is deleted, its child frames are deleted too.
   917  *
   918  * A visible child frame always appears on top of its parent frame thus
   919  * obscuring parts of it.  When a frame has more than one child frame,
   920  * their stacking order is specified just as that of non-child frames
   921  * relative to their display.
   922  *
   923  * Whether a child frame has a menu or tool bar may be window-system or
   924  * window manager dependent.  It's advisable to disable both via the
   925  * frame parameter settings.
   926  *
   927  * Some window managers may not honor this parameter.
   928  */
   929 static void
   930 x_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
   931 {
   932   struct frame *p = NULL;
   933 #ifdef HAVE_GTK3
   934   GdkWindow *window;
   935 #endif
   936 
   937   if (!NILP (new_value)
   938       && (!FRAMEP (new_value)
   939           || !FRAME_LIVE_P (p = XFRAME (new_value))
   940           || !FRAME_X_P (p)))
   941     {
   942       store_frame_param (f, Qparent_frame, old_value);
   943       error ("Invalid specification of `parent-frame'");
   944     }
   945 
   946   if (p != FRAME_PARENT_FRAME (f))
   947     {
   948       block_input ();
   949       XReparentWindow
   950         (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
   951          p ? FRAME_X_WINDOW (p) : FRAME_DISPLAY_INFO (f)->root_window,
   952          f->left_pos, f->top_pos);
   953 #ifdef USE_GTK
   954       if (EQ (x_gtk_resize_child_frames, Qresize_mode))
   955         gtk_container_set_resize_mode
   956           (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)),
   957            p ? GTK_RESIZE_IMMEDIATE : GTK_RESIZE_QUEUE);
   958 #endif
   959 
   960 #ifdef HAVE_GTK3
   961       if (p)
   962         {
   963           window = gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f));
   964           gdk_x11_window_set_frame_sync_enabled (window, FALSE);
   965         }
   966 #endif
   967 
   968 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
   969       /* Frame synchronization can't be used in child frames since
   970          they are not directly managed by the compositing manager.
   971          Re-enabling vsync in former child frames also leads to
   972          inconsistent display.  In addition, they can only be updated
   973          outside of a toplevel frame.  */
   974       FRAME_X_OUTPUT (f)->use_vsync_p = false;
   975       FRAME_X_WAITING_FOR_DRAW (f) = false;
   976 #endif
   977       unblock_input ();
   978 
   979       fset_parent_frame (f, new_value);
   980     }
   981 }
   982 
   983 /**
   984  * x_set_no_focus_on_map:
   985  *
   986  * Set frame F's `no-focus-on-map' parameter which, if non-nil, means
   987  * that F's window-system window does not want to receive input focus
   988  * when it is mapped.  (A frame's window is mapped when the frame is
   989  * displayed for the first time and when the frame changes its state
   990  * from `iconified' or `invisible' to `visible'.)
   991  *
   992  * Some window managers may not honor this parameter.
   993  */
   994 static void
   995 x_set_no_focus_on_map (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
   996 {
   997   if (!EQ (new_value, old_value))
   998     {
   999 #ifdef USE_GTK
  1000       xg_set_no_focus_on_map (f, new_value);
  1001 #else /* not USE_GTK */
  1002       Display *dpy = FRAME_X_DISPLAY (f);
  1003       Atom prop = FRAME_DISPLAY_INFO (f)->Xatom_net_wm_user_time;
  1004       Time timestamp = NILP (new_value) ? CurrentTime : 0;
  1005 
  1006       XChangeProperty (dpy, FRAME_OUTER_WINDOW (f), prop,
  1007                        XA_CARDINAL, 32, PropModeReplace,
  1008                        (unsigned char *) &timestamp, 1);
  1009 #endif /* USE_GTK */
  1010       FRAME_NO_FOCUS_ON_MAP (f) = !NILP (new_value);
  1011     }
  1012 }
  1013 
  1014 /**
  1015  * x_set_no_accept_focus:
  1016  *
  1017  * Set frame F's `no-accept-focus' parameter which, if non-nil, hints
  1018  * that F's window-system window does not want to receive input focus
  1019  * via mouse clicks or by moving the mouse into it.
  1020  *
  1021  * If non-nil, this may have the unwanted side-effect that a user cannot
  1022  * scroll a non-selected frame with the mouse.
  1023  *
  1024  * Some window managers may not honor this parameter.
  1025  */
  1026 static void
  1027 x_set_no_accept_focus (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
  1028 {
  1029   if (!EQ (new_value, old_value))
  1030     {
  1031 #ifdef USE_GTK
  1032       xg_set_no_accept_focus (f, new_value);
  1033 #else /* not USE_GTK */
  1034 #ifdef USE_X_TOOLKIT
  1035       Arg al[1];
  1036 
  1037       XtSetArg (al[0], XtNinput, NILP (new_value) ? True : False);
  1038       XtSetValues (f->output_data.x->widget, al, 1);
  1039 #else /* not USE_X_TOOLKIT */
  1040       Window window = FRAME_X_WINDOW (f);
  1041 
  1042       f->output_data.x->wm_hints.input = NILP (new_value) ? True : False;
  1043       XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
  1044 #endif /* USE_X_TOOLKIT */
  1045 #endif /* USE_GTK */
  1046       FRAME_NO_ACCEPT_FOCUS (f) = !NILP (new_value);
  1047     }
  1048 }
  1049 
  1050 /**
  1051  * x_set_override_redirect:
  1052  *
  1053  * Set frame F's `override_redirect' parameter which, if non-nil, hints
  1054  * that the window manager doesn't want to deal with F.  Usually, such
  1055  * frames have no decorations and always appear on top of all frames.
  1056  *
  1057  * Some window managers may not honor this parameter.
  1058  */
  1059 static void
  1060 x_set_override_redirect (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
  1061 {
  1062   if (!EQ (new_value, old_value))
  1063     {
  1064       /* Here (xfwm) override_redirect can be changed for invisible
  1065          frames only.  */
  1066       x_make_frame_invisible (f);
  1067 
  1068 #ifdef USE_GTK
  1069       xg_set_override_redirect (f, new_value);
  1070 #else /* not USE_GTK */
  1071       XSetWindowAttributes attributes;
  1072 
  1073       attributes.override_redirect = NILP (new_value) ? False : True;
  1074       XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
  1075                                CWOverrideRedirect, &attributes);
  1076 #endif
  1077       x_make_frame_visible (f);
  1078       FRAME_OVERRIDE_REDIRECT (f) = !NILP (new_value);
  1079     }
  1080 }
  1081 
  1082 
  1083 #ifdef USE_GTK
  1084 
  1085 /* Set icon from FILE for frame F.  By using GTK functions the icon
  1086    may be any format that GdkPixbuf knows about, i.e. not just bitmaps.  */
  1087 
  1088 bool
  1089 xg_set_icon (struct frame *f, Lisp_Object file)
  1090 {
  1091   bool result = false;
  1092   Lisp_Object found;
  1093 
  1094   found = image_find_image_file (file);
  1095 
  1096   if (! NILP (found))
  1097     {
  1098       GdkPixbuf *pixbuf;
  1099       GError *err = NULL;
  1100       char *filename = SSDATA (ENCODE_FILE (found));
  1101       block_input ();
  1102 
  1103       pixbuf = gdk_pixbuf_new_from_file (filename, &err);
  1104 
  1105       if (pixbuf)
  1106         {
  1107           gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
  1108                                pixbuf);
  1109           g_object_unref (pixbuf);
  1110 
  1111           result = true;
  1112         }
  1113       else
  1114         g_error_free (err);
  1115 
  1116       unblock_input ();
  1117     }
  1118 
  1119   return result;
  1120 }
  1121 
  1122 bool
  1123 xg_set_icon_from_xpm_data (struct frame *f, const char **data)
  1124 {
  1125   GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (data);
  1126 
  1127   if (!pixbuf)
  1128     return false;
  1129 
  1130   gtk_window_set_icon (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), pixbuf);
  1131   g_object_unref (pixbuf);
  1132   return true;
  1133 }
  1134 #endif /* USE_GTK */
  1135 
  1136 
  1137 /* Functions called only from `gui_set_frame_parameters'
  1138    to set individual parameters.
  1139 
  1140    If FRAME_X_WINDOW (f) is 0,
  1141    the frame is being created and its X-window does not exist yet.
  1142    In that case, just record the parameter's new value
  1143    in the standard place; do not attempt to change the window.  */
  1144 
  1145 static void
  1146 x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  1147 {
  1148   struct x_output *x = f->output_data.x;
  1149   unsigned long fg, old_fg;
  1150 
  1151   fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
  1152   old_fg = FRAME_FOREGROUND_PIXEL (f);
  1153   FRAME_FOREGROUND_PIXEL (f) = fg;
  1154 
  1155   if (FRAME_X_WINDOW (f) != 0)
  1156     {
  1157       Display *dpy = FRAME_X_DISPLAY (f);
  1158 
  1159       block_input ();
  1160       XSetForeground (dpy, x->normal_gc, fg);
  1161       XSetBackground (dpy, x->reverse_gc, fg);
  1162 
  1163       if (x->cursor_pixel == old_fg)
  1164         {
  1165           unload_color (f, x->cursor_pixel);
  1166           x->cursor_pixel = x_copy_color (f, fg);
  1167           XSetBackground (dpy, x->cursor_gc, x->cursor_pixel);
  1168         }
  1169 
  1170       unblock_input ();
  1171 
  1172       update_face_from_frame_parameter (f, Qforeground_color, arg);
  1173 
  1174       if (FRAME_VISIBLE_P (f))
  1175         redraw_frame (f);
  1176     }
  1177 
  1178   unload_color (f, old_fg);
  1179 }
  1180 
  1181 static void
  1182 x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  1183 {
  1184   struct x_output *x = f->output_data.x;
  1185   unsigned long bg;
  1186 
  1187   bg = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
  1188   unload_color (f, FRAME_BACKGROUND_PIXEL (f));
  1189   FRAME_BACKGROUND_PIXEL (f) = bg;
  1190 
  1191   if (FRAME_X_WINDOW (f) != 0)
  1192     {
  1193       Display *dpy = FRAME_X_DISPLAY (f);
  1194 
  1195       block_input ();
  1196       XSetBackground (dpy, x->normal_gc, bg);
  1197       XSetForeground (dpy, x->reverse_gc, bg);
  1198       XSetWindowBackground (dpy, FRAME_X_WINDOW (f), bg);
  1199       XSetForeground (dpy, x->cursor_gc, bg);
  1200 
  1201 #ifdef USE_GTK
  1202       xg_set_background_color (f, bg);
  1203 #endif
  1204 
  1205       unblock_input ();
  1206       update_face_from_frame_parameter (f, Qbackground_color, arg);
  1207 
  1208       if (FRAME_VISIBLE_P (f))
  1209         redraw_frame (f);
  1210     }
  1211 }
  1212 
  1213 /* This array must stay in sync with the mouse_cursor_types array below!  */
  1214 enum mouse_cursor {
  1215   mouse_cursor_text,
  1216   mouse_cursor_nontext,
  1217   mouse_cursor_hourglass,
  1218   mouse_cursor_mode,
  1219   mouse_cursor_hand,
  1220   mouse_cursor_horizontal_drag,
  1221   mouse_cursor_vertical_drag,
  1222   mouse_cursor_left_edge,
  1223   mouse_cursor_top_left_corner,
  1224   mouse_cursor_top_edge,
  1225   mouse_cursor_top_right_corner,
  1226   mouse_cursor_right_edge,
  1227   mouse_cursor_bottom_right_corner,
  1228   mouse_cursor_bottom_edge,
  1229   mouse_cursor_bottom_left_corner,
  1230   mouse_cursor_max
  1231 };
  1232 
  1233 struct mouse_cursor_types {
  1234   /* Printable name for error messages (optional).  */
  1235   const char *name;
  1236 
  1237   /* Lisp variable controlling the cursor shape.  */
  1238   /* FIXME: A couple of these variables are defined in the C code but
  1239      are not actually accessible from Lisp.  They should probably be
  1240      made accessible or removed.  */
  1241   Lisp_Object *shape_var_ptr;
  1242 
  1243   /* The default shape.  */
  1244   int default_shape;
  1245 };
  1246 
  1247 /* This array must stay in sync with enum mouse_cursor above!  */
  1248 static const struct mouse_cursor_types mouse_cursor_types[] =
  1249   {
  1250     { "text",      &Vx_pointer_shape,                    XC_xterm               },
  1251     { "nontext",   &Vx_nontext_pointer_shape,            XC_left_ptr            },
  1252     { "hourglass", &Vx_hourglass_pointer_shape,          XC_watch               },
  1253     { "modeline",  &Vx_mode_pointer_shape,               XC_xterm               },
  1254     { NULL,        &Vx_sensitive_text_pointer_shape,     XC_hand2               },
  1255     { NULL,        &Vx_window_horizontal_drag_shape,     XC_sb_h_double_arrow   },
  1256     { NULL,        &Vx_window_vertical_drag_shape,       XC_sb_v_double_arrow   },
  1257     { NULL,        &Vx_window_left_edge_shape,           XC_left_side           },
  1258     { NULL,        &Vx_window_top_left_corner_shape,     XC_top_left_corner     },
  1259     { NULL,        &Vx_window_top_edge_shape,            XC_top_side            },
  1260     { NULL,        &Vx_window_top_right_corner_shape,    XC_top_right_corner    },
  1261     { NULL,        &Vx_window_right_edge_shape,          XC_right_side          },
  1262     { NULL,        &Vx_window_bottom_right_corner_shape, XC_bottom_right_corner },
  1263     { NULL,        &Vx_window_bottom_edge_shape,         XC_bottom_side         },
  1264     { NULL,        &Vx_window_bottom_left_corner_shape,  XC_bottom_left_corner  },
  1265   };
  1266 
  1267 struct mouse_cursor_data
  1268 {
  1269   /* Last index for which XCreateFontCursor has been called, and thus
  1270      the last index for which x_request_serial[] is valid.  */
  1271   int last_cursor_create_request;
  1272 
  1273   /* Last index for which an X error event was received in response to
  1274      attempting to create the cursor.  */
  1275   int error_cursor;
  1276 
  1277   /* Cursor numbers chosen.  */
  1278   unsigned int cursor_num[mouse_cursor_max];
  1279 
  1280   /* Allocated Cursor values, or zero for failed attempts.  */
  1281   Cursor cursor[mouse_cursor_max];
  1282 
  1283   /* X serial numbers for the first request sent by XCreateFontCursor.
  1284      Note that there may be more than one request sent.  */
  1285   unsigned long x_request_serial[mouse_cursor_max];
  1286 
  1287   /* If an error has been received, a pointer to where the current
  1288      error-message text is stored.  */
  1289   char *error_string;
  1290 };
  1291 
  1292 static void
  1293 x_set_mouse_color_handler (Display *dpy, XErrorEvent *event,
  1294                            char *error_string, void *data)
  1295 {
  1296   struct mouse_cursor_data *cursor_data = data;
  1297   int i;
  1298 
  1299   cursor_data->error_cursor = -1;
  1300   cursor_data->error_string = error_string;
  1301   for (i = 0; i < cursor_data->last_cursor_create_request; i++)
  1302     {
  1303       if (event->serial >= cursor_data->x_request_serial[i])
  1304         cursor_data->error_cursor = i;
  1305     }
  1306   if (cursor_data->error_cursor >= 0)
  1307     /* If we failed to allocate it, don't try to free it.  */
  1308     cursor_data->cursor[cursor_data->error_cursor] = 0;
  1309 }
  1310 
  1311 static void
  1312 x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  1313 {
  1314   struct x_output *x = f->output_data.x;
  1315   Display *dpy = FRAME_X_DISPLAY (f);
  1316   struct mouse_cursor_data cursor_data = { -1, -1 };
  1317   unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
  1318   unsigned long mask_color = FRAME_BACKGROUND_PIXEL (f);
  1319   int i;
  1320 
  1321   /* Don't let pointers be invisible.  */
  1322   if (mask_color == pixel)
  1323     {
  1324       x_free_colors (f, &pixel, 1);
  1325       pixel = x_copy_color (f, FRAME_FOREGROUND_PIXEL (f));
  1326     }
  1327 
  1328   unload_color (f, x->mouse_pixel);
  1329   x->mouse_pixel = pixel;
  1330 
  1331   for (i = 0; i < mouse_cursor_max; i++)
  1332     {
  1333       Lisp_Object shape_var = *mouse_cursor_types[i].shape_var_ptr;
  1334       cursor_data.cursor_num[i]
  1335         = (!NILP (shape_var)
  1336            ? check_uinteger_max (shape_var, UINT_MAX)
  1337            : mouse_cursor_types[i].default_shape);
  1338     }
  1339 
  1340   block_input ();
  1341 
  1342   /* It's not okay to crash if the user selects a screwy cursor.  */
  1343   x_catch_errors_with_handler (dpy, x_set_mouse_color_handler, &cursor_data);
  1344 
  1345   for (i = 0; i < mouse_cursor_max; i++)
  1346     {
  1347       cursor_data.x_request_serial[i] = XNextRequest (dpy);
  1348       cursor_data.last_cursor_create_request = i;
  1349 
  1350       cursor_data.cursor[i]
  1351         = x_create_font_cursor (FRAME_DISPLAY_INFO (f),
  1352                                 cursor_data.cursor_num[i]);
  1353     }
  1354 
  1355   /* Now sync up and process all received errors from cursor
  1356      creation.  */
  1357   if (x_had_errors_p (dpy))
  1358     {
  1359       const char *bad_cursor_name = NULL;
  1360       /* Bounded by X_ERROR_MESSAGE_SIZE in xterm.c.  */
  1361       size_t message_length = strlen (cursor_data.error_string);
  1362       char *xmessage = alloca (1 + message_length);
  1363       memcpy (xmessage, cursor_data.error_string, message_length);
  1364 
  1365       x_uncatch_errors_after_check ();
  1366 
  1367       /* XFreeCursor can generate BadCursor errors, because
  1368          XCreateFontCursor is not a request that waits for a reply,
  1369          and as such can return IDs that will not actually be used by
  1370          the server.  */
  1371       x_ignore_errors_for_next_request (FRAME_DISPLAY_INFO (f));
  1372 
  1373       /* Free any successfully created cursors.  */
  1374       for (i = 0; i < mouse_cursor_max; i++)
  1375         if (cursor_data.cursor[i] != 0)
  1376           XFreeCursor (dpy, cursor_data.cursor[i]);
  1377 
  1378       x_stop_ignoring_errors (FRAME_DISPLAY_INFO (f));
  1379 
  1380       /* This should only be able to fail if the server's serial
  1381          number tracking is broken.  */
  1382       if (cursor_data.error_cursor >= 0)
  1383         bad_cursor_name = mouse_cursor_types[cursor_data.error_cursor].name;
  1384       if (bad_cursor_name)
  1385         error ("bad %s pointer cursor: %s", bad_cursor_name, xmessage);
  1386       else
  1387         error ("can't set cursor shape: %s", xmessage);
  1388     }
  1389 
  1390   x_uncatch_errors_after_check ();
  1391 
  1392   {
  1393     XColor colors[2]; /* 0=foreground, 1=background */
  1394 
  1395     colors[0].pixel = x->mouse_pixel;
  1396     colors[1].pixel = mask_color;
  1397     x_query_colors (f, colors, 2);
  1398 
  1399     for (i = 0; i < mouse_cursor_max; i++)
  1400       XRecolorCursor (dpy, cursor_data.cursor[i], &colors[0], &colors[1]);
  1401   }
  1402 
  1403   if (FRAME_X_WINDOW (f) != 0)
  1404     {
  1405       f->output_data.x->current_cursor = cursor_data.cursor[mouse_cursor_text];
  1406       XDefineCursor (dpy, FRAME_X_WINDOW (f),
  1407                      f->output_data.x->current_cursor);
  1408     }
  1409 
  1410 #define INSTALL_CURSOR(FIELD, SHORT_INDEX)                              \
  1411   eassert (x->FIELD != cursor_data.cursor[mouse_cursor_ ## SHORT_INDEX]); \
  1412   if (x->FIELD != 0)                                                    \
  1413     XFreeCursor (dpy, x->FIELD);                                        \
  1414   x->FIELD = cursor_data.cursor[mouse_cursor_ ## SHORT_INDEX];
  1415 
  1416   INSTALL_CURSOR (text_cursor, text);
  1417   INSTALL_CURSOR (nontext_cursor, nontext);
  1418   INSTALL_CURSOR (hourglass_cursor, hourglass);
  1419   INSTALL_CURSOR (modeline_cursor, mode);
  1420   INSTALL_CURSOR (hand_cursor, hand);
  1421   INSTALL_CURSOR (horizontal_drag_cursor, horizontal_drag);
  1422   INSTALL_CURSOR (vertical_drag_cursor, vertical_drag);
  1423   INSTALL_CURSOR (left_edge_cursor, left_edge);
  1424   INSTALL_CURSOR (top_left_corner_cursor, top_left_corner);
  1425   INSTALL_CURSOR (top_edge_cursor, top_edge);
  1426   INSTALL_CURSOR (top_right_corner_cursor, top_right_corner);
  1427   INSTALL_CURSOR (right_edge_cursor, right_edge);
  1428   INSTALL_CURSOR (bottom_right_corner_cursor, bottom_right_corner);
  1429   INSTALL_CURSOR (bottom_edge_cursor, bottom_edge);
  1430   INSTALL_CURSOR (bottom_left_corner_cursor, bottom_left_corner);
  1431 
  1432 #undef INSTALL_CURSOR
  1433 
  1434   XFlush (dpy);
  1435   unblock_input ();
  1436 
  1437   update_face_from_frame_parameter (f, Qmouse_color, arg);
  1438 }
  1439 
  1440 static void
  1441 x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  1442 {
  1443   unsigned long fore_pixel, pixel;
  1444   bool fore_pixel_allocated_p = false, pixel_allocated_p = false;
  1445   struct x_output *x = f->output_data.x;
  1446 
  1447   if (!NILP (Vx_cursor_fore_pixel))
  1448     {
  1449       fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
  1450                                    WHITE_PIX_DEFAULT (f));
  1451       fore_pixel_allocated_p = true;
  1452     }
  1453   else
  1454     fore_pixel = FRAME_BACKGROUND_PIXEL (f);
  1455 
  1456   pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
  1457   pixel_allocated_p = true;
  1458 
  1459   /* Make sure that the cursor color differs from the background color.  */
  1460   if (pixel == FRAME_BACKGROUND_PIXEL (f))
  1461     {
  1462       if (pixel_allocated_p)
  1463         {
  1464           x_free_colors (f, &pixel, 1);
  1465           pixel_allocated_p = false;
  1466         }
  1467 
  1468       pixel = x->mouse_pixel;
  1469       if (pixel == fore_pixel)
  1470         {
  1471           if (fore_pixel_allocated_p)
  1472             {
  1473               x_free_colors (f, &fore_pixel, 1);
  1474               fore_pixel_allocated_p = false;
  1475             }
  1476           fore_pixel = FRAME_BACKGROUND_PIXEL (f);
  1477         }
  1478     }
  1479 
  1480   unload_color (f, x->cursor_foreground_pixel);
  1481   if (!fore_pixel_allocated_p)
  1482     fore_pixel = x_copy_color (f, fore_pixel);
  1483   x->cursor_foreground_pixel = fore_pixel;
  1484 
  1485   unload_color (f, x->cursor_pixel);
  1486   if (!pixel_allocated_p)
  1487     pixel = x_copy_color (f, pixel);
  1488   x->cursor_pixel = pixel;
  1489 
  1490   if (FRAME_X_WINDOW (f) != 0)
  1491     {
  1492       block_input ();
  1493       XSetBackground (FRAME_X_DISPLAY (f), x->cursor_gc, x->cursor_pixel);
  1494       XSetForeground (FRAME_X_DISPLAY (f), x->cursor_gc, fore_pixel);
  1495       unblock_input ();
  1496 
  1497       if (FRAME_VISIBLE_P (f))
  1498         {
  1499           gui_update_cursor (f, false);
  1500           gui_update_cursor (f, true);
  1501         }
  1502     }
  1503 
  1504   update_face_from_frame_parameter (f, Qcursor_color, arg);
  1505 }
  1506 
  1507 /* Set the border-color of frame F to pixel value PIX.
  1508    Note that this does not fully take effect if done before
  1509    F has an x-window.  */
  1510 
  1511 static void
  1512 x_set_border_pixel (struct frame *f, unsigned long pix)
  1513 {
  1514   unload_color (f, f->output_data.x->border_pixel);
  1515   f->output_data.x->border_pixel = pix;
  1516 
  1517 #ifdef USE_X_TOOLKIT
  1518   if (f->output_data.x->widget && f->border_width > 0)
  1519     {
  1520       block_input ();
  1521       XtVaSetValues (f->output_data.x->widget, XtNborderColor,
  1522                      (Pixel) pix, NULL);
  1523       unblock_input ();
  1524 
  1525       if (FRAME_VISIBLE_P (f))
  1526         redraw_frame (f);
  1527 
  1528       return;
  1529     }
  1530 #endif
  1531 
  1532   if (FRAME_X_WINDOW (f) != 0 && f->border_width > 0)
  1533     {
  1534       block_input ();
  1535       XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), pix);
  1536       unblock_input ();
  1537 
  1538       if (FRAME_VISIBLE_P (f))
  1539         redraw_frame (f);
  1540     }
  1541 }
  1542 
  1543 /* Set the border-color of frame F to value described by ARG.
  1544    ARG can be a string naming a color.
  1545    The border-color is used for the border that is drawn by the X server.
  1546    Note that this does not fully take effect if done before
  1547    F has an x-window; it must be redone when the window is created.
  1548 
  1549    Note: this is done in two routines because of the way X10 works.
  1550 
  1551    Note: under X11, this is normally the province of the window manager,
  1552    and so emacs's border colors may be overridden.  */
  1553 
  1554 static void
  1555 x_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  1556 {
  1557   unsigned long pix;
  1558 
  1559   CHECK_STRING (arg);
  1560   pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
  1561   x_set_border_pixel (f, pix);
  1562   update_face_from_frame_parameter (f, Qborder_color, arg);
  1563 }
  1564 
  1565 
  1566 static void
  1567 x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  1568 {
  1569   set_frame_cursor_types (f, arg);
  1570 }
  1571 
  1572 static void
  1573 x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  1574 {
  1575   bool result;
  1576 
  1577   if (STRINGP (arg))
  1578     {
  1579       if (STRINGP (oldval) && BASE_EQ (Fstring_equal (oldval, arg), Qt))
  1580         return;
  1581     }
  1582   else if (!STRINGP (oldval) && NILP (oldval) == NILP (arg))
  1583     return;
  1584 
  1585   block_input ();
  1586   if (NILP (arg))
  1587     result = x_text_icon (f,
  1588                           SSDATA ((!NILP (f->icon_name)
  1589                                    ? f->icon_name
  1590                                    : f->name)));
  1591   else
  1592     result = FRAME_TERMINAL (f)->set_bitmap_icon_hook (f, arg);
  1593 
  1594   if (result)
  1595     {
  1596       unblock_input ();
  1597       error ("No icon window available");
  1598     }
  1599 
  1600   XFlush (FRAME_X_DISPLAY (f));
  1601   unblock_input ();
  1602 }
  1603 
  1604 static void
  1605 x_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  1606 {
  1607   bool result;
  1608 
  1609   if (STRINGP (arg))
  1610     {
  1611       if (STRINGP (oldval) && BASE_EQ (Fstring_equal (oldval, arg), Qt))
  1612         return;
  1613     }
  1614   else if (!NILP (arg) || NILP (oldval))
  1615     return;
  1616 
  1617   fset_icon_name (f, arg);
  1618 
  1619   if (f->output_data.x->icon_bitmap != 0)
  1620     return;
  1621 
  1622   block_input ();
  1623 
  1624   result = x_text_icon (f,
  1625                         SSDATA ((!NILP (f->icon_name)
  1626                                  ? f->icon_name
  1627                                  : !NILP (f->title)
  1628                                  ? f->title
  1629                                  : f->name)));
  1630 
  1631   if (result)
  1632     {
  1633       unblock_input ();
  1634       error ("No icon window available");
  1635     }
  1636 
  1637   XFlush (FRAME_X_DISPLAY (f));
  1638   unblock_input ();
  1639 }
  1640 
  1641 
  1642 static void
  1643 x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
  1644 {
  1645   int nlines;
  1646 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
  1647   int olines = FRAME_MENU_BAR_LINES (f);
  1648 #endif
  1649 
  1650   /* Right now, menu bars don't work properly in minibuf-only frames;
  1651      most of the commands try to apply themselves to the minibuffer
  1652      frame itself, and get an error because you can't switch buffers
  1653      in or split the minibuffer window.  */
  1654   if (FRAME_MINIBUF_ONLY_P (f) || FRAME_PARENT_FRAME (f))
  1655     return;
  1656 
  1657   if (TYPE_RANGED_FIXNUMP (int, value))
  1658     nlines = XFIXNUM (value);
  1659   else
  1660     nlines = 0;
  1661 
  1662   /* Make sure we redisplay all windows in this frame.  */
  1663   fset_redisplay (f);
  1664 
  1665 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
  1666   FRAME_MENU_BAR_LINES (f) = 0;
  1667   FRAME_MENU_BAR_HEIGHT (f) = 0;
  1668   if (nlines)
  1669     {
  1670       FRAME_EXTERNAL_MENU_BAR (f) = 1;
  1671       if (FRAME_X_P (f) && f->output_data.x->menubar_widget == 0)
  1672         /* Make sure next redisplay shows the menu bar.  */
  1673         XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = true;
  1674     }
  1675   else
  1676     {
  1677       if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
  1678         free_frame_menubar (f);
  1679       FRAME_EXTERNAL_MENU_BAR (f) = 0;
  1680       if (FRAME_X_P (f))
  1681         f->output_data.x->menubar_widget = 0;
  1682     }
  1683 #else /* not USE_X_TOOLKIT && not USE_GTK */
  1684   FRAME_MENU_BAR_LINES (f) = nlines;
  1685   FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
  1686   if (FRAME_X_WINDOW (f))
  1687     x_clear_under_internal_border (f);
  1688 
  1689   /* If the menu bar height gets changed, the internal border below
  1690      the top margin has to be cleared.  Also, if the menu bar gets
  1691      larger, the area for the added lines has to be cleared except for
  1692      the first menu bar line that is to be drawn later.  */
  1693   if (nlines != olines)
  1694     {
  1695       int height = FRAME_INTERNAL_BORDER_WIDTH (f);
  1696       int width = FRAME_PIXEL_WIDTH (f);
  1697       int y;
  1698 
  1699       adjust_frame_size (f, -1, -1, 3, true, Qmenu_bar_lines);
  1700 
  1701       /* height can be zero here. */
  1702       if (FRAME_X_WINDOW (f) && height > 0 && width > 0)
  1703         {
  1704           y = FRAME_TOP_MARGIN_HEIGHT (f);
  1705 
  1706           block_input ();
  1707           x_clear_area (f, 0, y, width, height);
  1708           unblock_input ();
  1709         }
  1710 
  1711       if (nlines > 1 && nlines > olines)
  1712         {
  1713           y = (olines == 0 ? 1 : olines) * FRAME_LINE_HEIGHT (f);
  1714           height = nlines * FRAME_LINE_HEIGHT (f) - y;
  1715 
  1716           block_input ();
  1717           x_clear_area (f, 0, y, width, height);
  1718           unblock_input ();
  1719         }
  1720 
  1721       if (nlines == 0 && WINDOWP (f->menu_bar_window))
  1722         clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
  1723     }
  1724 #endif /* not USE_X_TOOLKIT && not USE_GTK */
  1725   adjust_frame_glyphs (f);
  1726 }
  1727 
  1728 
  1729 /* Set the number of lines used for the tab bar of frame F to VALUE.
  1730    VALUE not an integer, or < 0 means set the lines to zero.  OLDVAL
  1731    is the old number of tab bar lines.  This function may change the
  1732    height of all windows on frame F to match the new tab bar height.
  1733    The frame's height may change if frame_inhibit_implied_resize was
  1734    set accordingly.  */
  1735 
  1736 static void
  1737 x_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
  1738 {
  1739   int olines = FRAME_TAB_BAR_LINES (f);
  1740   int nlines;
  1741 
  1742   /* Treat tab bars like menu bars.  */
  1743   if (FRAME_MINIBUF_ONLY_P (f))
  1744     return;
  1745 
  1746   /* Use VALUE only if an int >= 0.  */
  1747   if (RANGED_FIXNUMP (0, value, INT_MAX))
  1748     nlines = XFIXNAT (value);
  1749   else
  1750     nlines = 0;
  1751 
  1752   if (nlines != olines && (olines == 0 || nlines == 0))
  1753     x_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
  1754 }
  1755 
  1756 
  1757 /* Set the pixel height of the tab bar of frame F to HEIGHT.  */
  1758 void
  1759 x_change_tab_bar_height (struct frame *f, int height)
  1760 {
  1761   int unit = FRAME_LINE_HEIGHT (f);
  1762   int old_height = FRAME_TAB_BAR_HEIGHT (f);
  1763 
  1764   /* This differs from the tool bar code in that the tab bar height is
  1765      not rounded up.  Otherwise, if redisplay_tab_bar decides to grow
  1766      the tab bar by even 1 pixel, FRAME_TAB_BAR_LINES will be changed,
  1767      leading to the tab bar height being incorrectly set upon the next
  1768      call to x_set_font.  (bug#59285) */
  1769   int lines = height / unit;
  1770   if (lines == 0 && height != 0)
  1771     lines = 1;
  1772 
  1773   /* Make sure we redisplay all windows in this frame.  */
  1774   fset_redisplay (f);
  1775 
  1776   /* Recalculate tab bar and frame text sizes.  */
  1777   FRAME_TAB_BAR_HEIGHT (f) = height;
  1778   FRAME_TAB_BAR_LINES (f) = lines;
  1779   store_frame_param (f, Qtab_bar_lines, make_fixnum (lines));
  1780 
  1781   if (FRAME_X_WINDOW (f) && FRAME_TAB_BAR_HEIGHT (f) == 0)
  1782     {
  1783       clear_frame (f);
  1784       clear_current_matrices (f);
  1785     }
  1786 
  1787   if ((height < old_height) && WINDOWP (f->tab_bar_window))
  1788     clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
  1789 
  1790   if (!f->tab_bar_resized)
  1791     {
  1792       Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
  1793 
  1794       /* As long as tab_bar_resized is false, effectively try to change
  1795          F's native height.  */
  1796       if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
  1797         adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
  1798                            1, false, Qtab_bar_lines);
  1799       else
  1800         adjust_frame_size (f, -1, -1, 4, false, Qtab_bar_lines);
  1801 
  1802       f->tab_bar_resized = f->tab_bar_redisplayed;
  1803     }
  1804   else
  1805     /* Any other change may leave the native size of F alone.  */
  1806     adjust_frame_size (f, -1, -1, 3, false, Qtab_bar_lines);
  1807 
  1808   /* adjust_frame_size might not have done anything, garbage frame
  1809      here.  */
  1810   adjust_frame_glyphs (f);
  1811   SET_FRAME_GARBAGED (f);
  1812   if (FRAME_X_WINDOW (f))
  1813     x_clear_under_internal_border (f);
  1814 }
  1815 
  1816 
  1817 /* Set the number of lines used for the tool bar of frame F to VALUE.
  1818    VALUE not an integer, or < 0 means set the lines to zero.  OLDVAL
  1819    is the old number of tool bar lines.  This function changes the
  1820    height of all windows on frame F to match the new tool bar height.
  1821    The frame's height doesn't change.  */
  1822 
  1823 static void
  1824 x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
  1825 {
  1826   int nlines;
  1827 
  1828   /* Treat tool bars like menu bars.  */
  1829   if (FRAME_MINIBUF_ONLY_P (f))
  1830     return;
  1831 
  1832   /* Use VALUE only if an int >= 0.  */
  1833   if (RANGED_FIXNUMP (0, value, INT_MAX))
  1834     nlines = XFIXNAT (value);
  1835   else
  1836     nlines = 0;
  1837 
  1838   x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
  1839 }
  1840 
  1841 
  1842 /* Set the pixel height of the tool bar of frame F to HEIGHT.  */
  1843 void
  1844 x_change_tool_bar_height (struct frame *f, int height)
  1845 {
  1846 #ifdef USE_GTK
  1847   FRAME_TOOL_BAR_LINES (f) = 0;
  1848   FRAME_TOOL_BAR_HEIGHT (f) = 0;
  1849   if (height)
  1850     {
  1851       FRAME_EXTERNAL_TOOL_BAR (f) = true;
  1852       if (FRAME_X_P (f) && f->output_data.x->toolbar_widget == 0)
  1853         /* Make sure next redisplay shows the tool bar.  */
  1854         XWINDOW (FRAME_SELECTED_WINDOW (f))->update_mode_line = true;
  1855       update_frame_tool_bar (f);
  1856     }
  1857   else
  1858     {
  1859       if (FRAME_EXTERNAL_TOOL_BAR (f))
  1860         free_frame_tool_bar (f);
  1861       FRAME_EXTERNAL_TOOL_BAR (f) = false;
  1862     }
  1863 #else /* !USE_GTK */
  1864   int unit = FRAME_LINE_HEIGHT (f);
  1865   int old_height = FRAME_TOOL_BAR_HEIGHT (f);
  1866   int lines = (height + unit - 1) / unit;
  1867   Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
  1868 
  1869   /* Make sure we redisplay all windows in this frame.  */
  1870   fset_redisplay (f);
  1871 
  1872   FRAME_TOOL_BAR_HEIGHT (f) = height;
  1873   FRAME_TOOL_BAR_LINES (f) = lines;
  1874   store_frame_param (f, Qtool_bar_lines, make_fixnum (lines));
  1875 
  1876   if (FRAME_X_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
  1877     {
  1878       clear_frame (f);
  1879       clear_current_matrices (f);
  1880     }
  1881 
  1882   if ((height < old_height) && WINDOWP (f->tool_bar_window))
  1883     clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
  1884 
  1885   if (!f->tool_bar_resized)
  1886     {
  1887       /* As long as tool_bar_resized is false, effectively try to change
  1888          F's native height.  */
  1889       if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
  1890         adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
  1891                            1, false, Qtool_bar_lines);
  1892       else
  1893         adjust_frame_size (f, -1, -1, 4, false, Qtool_bar_lines);
  1894 
  1895       f->tool_bar_resized =  f->tool_bar_redisplayed;
  1896     }
  1897   else
  1898     /* Any other change may leave the native size of F alone.  */
  1899     adjust_frame_size (f, -1, -1, 3, false, Qtool_bar_lines);
  1900 
  1901   /* adjust_frame_size might not have done anything, garbage frame
  1902      here.  */
  1903   adjust_frame_glyphs (f);
  1904   SET_FRAME_GARBAGED (f);
  1905   if (FRAME_X_WINDOW (f))
  1906     x_clear_under_internal_border (f);
  1907 
  1908 #endif /* USE_GTK */
  1909 }
  1910 
  1911 static void
  1912 x_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  1913 {
  1914   int border;
  1915 
  1916   if (NILP (arg))
  1917     border = -1;
  1918   else if (RANGED_FIXNUMP (0, arg, INT_MAX))
  1919     border = XFIXNAT (arg);
  1920   else
  1921     signal_error ("Invalid child frame border width", arg);
  1922 
  1923   if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
  1924     {
  1925       f->child_frame_border_width = border;
  1926 
  1927 #ifdef USE_X_TOOLKIT
  1928       if (FRAME_X_OUTPUT (f)->edit_widget)
  1929         widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
  1930 #endif
  1931 
  1932       if (FRAME_X_WINDOW (f))
  1933         {
  1934           adjust_frame_size (f, -1, -1, 3, false, Qchild_frame_border_width);
  1935           x_clear_under_internal_border (f);
  1936         }
  1937     }
  1938 
  1939 }
  1940 
  1941 static void
  1942 x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  1943 {
  1944   int border = check_int_nonnegative (arg);
  1945 
  1946   if (border != FRAME_INTERNAL_BORDER_WIDTH (f))
  1947     {
  1948       f->internal_border_width = border;
  1949 
  1950 #ifdef USE_X_TOOLKIT
  1951       if (FRAME_X_OUTPUT (f)->edit_widget)
  1952         widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
  1953 #endif
  1954 
  1955       if (FRAME_X_WINDOW (f))
  1956         {
  1957           adjust_frame_size (f, -1, -1, 3, false, Qinternal_border_width);
  1958           x_clear_under_internal_border (f);
  1959         }
  1960     }
  1961 
  1962 }
  1963 
  1964 
  1965 /* Set the foreground color for scroll bars on frame F to VALUE.
  1966    VALUE should be a string, a color name.  If it isn't a string or
  1967    isn't a valid color name, do nothing.  OLDVAL is the old value of
  1968    the frame parameter.  */
  1969 
  1970 static void
  1971 x_set_scroll_bar_foreground (struct frame *f, Lisp_Object value, Lisp_Object oldval)
  1972 {
  1973   unsigned long pixel;
  1974 #ifdef HAVE_GTK3
  1975   XColor color;
  1976   char css[64];
  1977 #endif
  1978 
  1979   if (STRINGP (value))
  1980     pixel = x_decode_color (f, value, BLACK_PIX_DEFAULT (f));
  1981   else
  1982     pixel = -1;
  1983 
  1984   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
  1985     unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
  1986 
  1987   f->output_data.x->scroll_bar_foreground_pixel = pixel;
  1988   if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
  1989     {
  1990       /* Remove all scroll bars because they have wrong colors.  */
  1991       if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
  1992         (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
  1993       if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
  1994         (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
  1995 
  1996       update_face_from_frame_parameter (f, Qscroll_bar_foreground, value);
  1997       redraw_frame (f);
  1998     }
  1999 
  2000 #ifdef HAVE_GTK3
  2001   if (!FRAME_TOOLTIP_P (f))
  2002     {
  2003       if (pixel != -1)
  2004         {
  2005           color.pixel = pixel;
  2006 
  2007           XQueryColor (FRAME_X_DISPLAY (f),
  2008                        FRAME_X_COLORMAP (f),
  2009                        &color);
  2010 
  2011           sprintf (css, "scrollbar slider { background-color: #%02x%02x%02x; }",
  2012                    color.red >> 8, color.green >> 8, color.blue >> 8);
  2013           gtk_css_provider_load_from_data (FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider,
  2014                                            css, -1, NULL);
  2015         }
  2016       else
  2017         gtk_css_provider_load_from_data (FRAME_X_OUTPUT (f)->scrollbar_foreground_css_provider,
  2018                                          "", -1, NULL);
  2019     }
  2020 #endif
  2021 }
  2022 
  2023 
  2024 /* Set the background color for scroll bars on frame F to VALUE VALUE
  2025    should be a string, a color name.  If it isn't a string or isn't a
  2026    valid color name, do nothing.  OLDVAL is the old value of the frame
  2027    parameter.  */
  2028 
  2029 static void
  2030 x_set_scroll_bar_background (struct frame *f, Lisp_Object value, Lisp_Object oldval)
  2031 {
  2032   unsigned long pixel;
  2033 #ifdef HAVE_GTK3
  2034   XColor color;
  2035   char css[64];
  2036 #endif
  2037 
  2038   if (STRINGP (value))
  2039     pixel = x_decode_color (f, value, WHITE_PIX_DEFAULT (f));
  2040   else
  2041     pixel = -1;
  2042 
  2043   if (f->output_data.x->scroll_bar_background_pixel != -1)
  2044     unload_color (f, f->output_data.x->scroll_bar_background_pixel);
  2045 
  2046 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
  2047   /* Scrollbar shadow colors.  */
  2048   if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
  2049     {
  2050       unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
  2051       f->output_data.x->scroll_bar_top_shadow_pixel = -1;
  2052     }
  2053   if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
  2054     {
  2055       unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
  2056       f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
  2057     }
  2058 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
  2059 
  2060   f->output_data.x->scroll_bar_background_pixel = pixel;
  2061   if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f))
  2062     {
  2063       /* Remove all scroll bars because they have wrong colors.  */
  2064       if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
  2065         (*FRAME_TERMINAL (f)->condemn_scroll_bars_hook) (f);
  2066       if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
  2067         (*FRAME_TERMINAL (f)->judge_scroll_bars_hook) (f);
  2068 
  2069       update_face_from_frame_parameter (f, Qscroll_bar_background, value);
  2070       redraw_frame (f);
  2071     }
  2072 
  2073 #ifdef HAVE_GTK3
  2074     if (!FRAME_TOOLTIP_P (f))
  2075       {
  2076         if (pixel != -1)
  2077           {
  2078             color.pixel = pixel;
  2079 
  2080             XQueryColor (FRAME_X_DISPLAY (f),
  2081                          FRAME_X_COLORMAP (f),
  2082                          &color);
  2083 
  2084             sprintf (css, "scrollbar trough { background-color: #%02x%02x%02x; }",
  2085                      color.red >> 8, color.green >> 8, color.blue >> 8);
  2086             gtk_css_provider_load_from_data (FRAME_X_OUTPUT (f)->scrollbar_background_css_provider,
  2087                                              css, -1, NULL);
  2088           }
  2089         else
  2090           gtk_css_provider_load_from_data (FRAME_X_OUTPUT (f)->scrollbar_background_css_provider,
  2091                                            "", -1, NULL);
  2092       }
  2093 #endif
  2094 }
  2095 
  2096 
  2097 /* Encode Lisp string STRING as a text in a format appropriate for
  2098    the ICCCM (Inter Client Communication Conventions Manual).
  2099 
  2100    If STRING contains only ASCII characters, do no conversion and
  2101    return the string data of STRING.  Otherwise, encode the text by
  2102    CODING_SYSTEM, and return a newly allocated memory area which
  2103    should be freed by `xfree' by a caller.
  2104 
  2105    Store the byte length of resulting text in *TEXT_BYTES.
  2106 
  2107    If the text contains only ASCII and Latin-1, store true in *STRING_P,
  2108    which means that the `encoding' of the result can be `STRING'.
  2109    Otherwise store false in *STRINGP, which means that the `encoding' of
  2110    the result should be `COMPOUND_TEXT'.  */
  2111 
  2112 static unsigned char *
  2113 x_encode_text (Lisp_Object string, Lisp_Object coding_system,
  2114                ptrdiff_t *text_bytes, bool *stringp, bool *freep)
  2115 {
  2116   int result = string_xstring_p (string);
  2117   struct coding_system coding;
  2118 
  2119   if (result == 0)
  2120     {
  2121       /* No multibyte character in OBJ.  We need not encode it.  */
  2122       *text_bytes = SBYTES (string);
  2123       *stringp = true;
  2124       *freep = false;
  2125       return SDATA (string);
  2126     }
  2127 
  2128   setup_coding_system (coding_system, &coding);
  2129   coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
  2130   /* We suppress producing escape sequences for composition.  */
  2131   coding.common_flags &= ~CODING_ANNOTATION_MASK;
  2132   coding.destination = xnmalloc (SCHARS (string), 2);
  2133   coding.dst_bytes = SCHARS (string) * 2;
  2134   encode_coding_object (&coding, string, 0, 0,
  2135                         SCHARS (string), SBYTES (string), Qnil);
  2136   *text_bytes = coding.produced;
  2137   *stringp = (result == 1 || !EQ (coding_system, Qcompound_text));
  2138   *freep = true;
  2139   return coding.destination;
  2140 }
  2141 
  2142 
  2143 /* Set the WM name to NAME for frame F. Also set the icon name.
  2144    If the frame already has an icon name, use that, otherwise set the
  2145    icon name to NAME.  */
  2146 
  2147 static void
  2148 x_set_name_internal (struct frame *f, Lisp_Object name)
  2149 {
  2150   if (FRAME_X_WINDOW (f))
  2151     {
  2152       block_input ();
  2153       {
  2154         XTextProperty text, icon;
  2155         ptrdiff_t bytes;
  2156         bool stringp;
  2157         bool do_free_icon_value = false, do_free_text_value = false;
  2158         Lisp_Object coding_system;
  2159         Lisp_Object encoded_name;
  2160         Lisp_Object encoded_icon_name;
  2161 
  2162         /* As ENCODE_UTF_8 may cause GC and relocation of string data,
  2163            we use it before x_encode_text that may return string data.  */
  2164         encoded_name = ENCODE_UTF_8 (name);
  2165 
  2166         coding_system = Qcompound_text;
  2167         /* Note: Encoding strategy
  2168 
  2169            We encode NAME by compound-text and use "COMPOUND-TEXT" in
  2170            text.encoding.  But, there are non-internationalized window
  2171            managers which don't support that encoding.  So, if NAME
  2172            contains only ASCII and 8859-1 characters, encode it by
  2173            iso-latin-1, and use "STRING" in text.encoding hoping that
  2174            such window managers at least analyze this format correctly,
  2175            i.e. treat 8-bit bytes as 8859-1 characters.
  2176 
  2177            We may also be able to use "UTF8_STRING" in text.encoding
  2178            in the future which can encode all Unicode characters.
  2179            But, for the moment, there's no way to know that the
  2180            current window manager supports it or not.
  2181 
  2182            Either way, we also set the _NET_WM_NAME and _NET_WM_ICON_NAME
  2183            properties.  Per the EWMH specification, those two properties
  2184            are always UTF8_STRING.  This matches what gtk_window_set_title()
  2185            does in the USE_GTK case. */
  2186         text.value = x_encode_text (name, coding_system, &bytes,
  2187                                     &stringp, &do_free_text_value);
  2188         text.encoding = (stringp ? XA_STRING
  2189                          : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
  2190         text.format = 8;
  2191         text.nitems = bytes;
  2192 
  2193         if (!STRINGP (f->icon_name))
  2194           {
  2195             icon = text;
  2196             encoded_icon_name = encoded_name;
  2197           }
  2198         else
  2199           {
  2200             /* See the above comment "Note: Encoding strategy".  */
  2201             icon.value = x_encode_text (f->icon_name, coding_system, &bytes,
  2202                                         &stringp, &do_free_icon_value);
  2203             icon.encoding = (stringp ? XA_STRING
  2204                              : FRAME_DISPLAY_INFO (f)->Xatom_COMPOUND_TEXT);
  2205             icon.format = 8;
  2206             icon.nitems = bytes;
  2207 
  2208             encoded_icon_name = ENCODE_UTF_8 (f->icon_name);
  2209           }
  2210 
  2211 #ifdef USE_GTK
  2212         gtk_window_set_title (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
  2213                               SSDATA (encoded_name));
  2214 #else /* not USE_GTK */
  2215         XSetWMName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
  2216         XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
  2217                          FRAME_DISPLAY_INFO (f)->Xatom_net_wm_name,
  2218                          FRAME_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
  2219                          8, PropModeReplace,
  2220                          SDATA (encoded_name),
  2221                          SBYTES (encoded_name));
  2222 #endif /* not USE_GTK */
  2223 
  2224         XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &icon);
  2225         XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
  2226                          FRAME_DISPLAY_INFO (f)->Xatom_net_wm_icon_name,
  2227                          FRAME_DISPLAY_INFO (f)->Xatom_UTF8_STRING,
  2228                          8, PropModeReplace,
  2229                          SDATA (encoded_icon_name),
  2230                          SBYTES (encoded_icon_name));
  2231 
  2232         if (do_free_icon_value)
  2233           xfree (icon.value);
  2234         if (do_free_text_value)
  2235           xfree (text.value);
  2236       }
  2237       unblock_input ();
  2238     }
  2239 }
  2240 
  2241 /* Change the name of frame F to NAME.  If NAME is nil, set F's name to
  2242        x_id_name.
  2243 
  2244    If EXPLICIT is true, that indicates that lisp code is setting the
  2245        name; if NAME is a string, set F's name to NAME and set
  2246        F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
  2247 
  2248    If EXPLICIT is false, that indicates that Emacs redisplay code is
  2249        suggesting a new name, which lisp code should override; if
  2250        F->explicit_name is set, ignore the new name; otherwise, set it.  */
  2251 
  2252 static void
  2253 x_set_name (struct frame *f, Lisp_Object name, bool explicit)
  2254 {
  2255   /* Make sure that requests from lisp code override requests from
  2256      Emacs redisplay code.  */
  2257   if (explicit)
  2258     {
  2259       /* If we're switching from explicit to implicit, we had better
  2260          update the mode lines and thereby update the title.  */
  2261       if (f->explicit_name && NILP (name))
  2262         update_mode_lines = 37;
  2263 
  2264       f->explicit_name = ! NILP (name);
  2265     }
  2266   else if (f->explicit_name)
  2267     return;
  2268 
  2269   /* If NAME is nil, set the name to the x_id_name.  */
  2270   if (NILP (name))
  2271     {
  2272       /* Check for no change needed in this very common case
  2273          before we do any consing.  */
  2274       if (!strcmp (FRAME_DISPLAY_INFO (f)->x_id_name,
  2275                    SSDATA (f->name)))
  2276         return;
  2277       name = build_string (FRAME_DISPLAY_INFO (f)->x_id_name);
  2278     }
  2279   else
  2280     CHECK_STRING (name);
  2281 
  2282   /* Don't change the name if it's already NAME.  */
  2283   if (! NILP (Fstring_equal (name, f->name)))
  2284     return;
  2285 
  2286   fset_name (f, name);
  2287 
  2288   /* For setting the frame title, the title parameter should override
  2289      the name parameter.  */
  2290   if (! NILP (f->title))
  2291     name = f->title;
  2292 
  2293   x_set_name_internal (f, name);
  2294 }
  2295 
  2296 /* This function should be called when the user's lisp code has
  2297    specified a name for the frame; the name will override any set by the
  2298    redisplay code.  */
  2299 static void
  2300 x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  2301 {
  2302   x_set_name (f, arg, true);
  2303 }
  2304 
  2305 /* This function should be called by Emacs redisplay code to set the
  2306    name; names set this way will never override names set by the user's
  2307    lisp code.  */
  2308 void
  2309 x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  2310 {
  2311   x_set_name (f, arg, false);
  2312 }
  2313 
  2314 /* Change the title of frame F to NAME.
  2315    If NAME is nil, use the frame name as the title.  */
  2316 
  2317 static void
  2318 x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
  2319 {
  2320   /* Don't change the title if it's already NAME.  */
  2321   if (EQ (name, f->title))
  2322     return;
  2323 
  2324   update_mode_lines = 38;
  2325 
  2326   fset_title (f, name);
  2327 
  2328   if (NILP (name))
  2329     name = f->name;
  2330   else
  2331     CHECK_STRING (name);
  2332 
  2333   x_set_name_internal (f, name);
  2334 }
  2335 
  2336 void
  2337 x_set_scroll_bar_default_width (struct frame *f)
  2338 {
  2339   int unit = FRAME_COLUMN_WIDTH (f);
  2340 #ifdef USE_TOOLKIT_SCROLL_BARS
  2341 #ifdef USE_GTK
  2342   int minw = xg_get_default_scrollbar_width (f);
  2343 #else
  2344   int minw = 16;
  2345 #endif
  2346   /* A minimum width of 14 doesn't look good for toolkit scroll bars.  */
  2347   FRAME_CONFIG_SCROLL_BAR_COLS (f) = (minw + unit - 1) / unit;
  2348   FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = minw;
  2349 #else
  2350   /* The width of a non-toolkit scrollbar is 14 pixels.  */
  2351   FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
  2352   FRAME_CONFIG_SCROLL_BAR_WIDTH (f)
  2353     = FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit;
  2354 #endif
  2355 }
  2356 
  2357 void
  2358 x_set_scroll_bar_default_height (struct frame *f)
  2359 {
  2360   int height = FRAME_LINE_HEIGHT (f);
  2361 #ifdef USE_TOOLKIT_SCROLL_BARS
  2362 #ifdef USE_GTK
  2363   int min_height = xg_get_default_scrollbar_height (f);
  2364 #else
  2365   int min_height = 16;
  2366 #endif
  2367   /* A minimum height of 14 doesn't look good for toolkit scroll bars.  */
  2368   FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = min_height;
  2369   FRAME_CONFIG_SCROLL_BAR_LINES (f) = (min_height + height - 1) / height;
  2370 #else
  2371   /* The height of a non-toolkit scrollbar is 14 pixels.  */
  2372   FRAME_CONFIG_SCROLL_BAR_LINES (f) = (14 + height - 1) / height;
  2373 
  2374   /* Use all of that space (aside from required margins) for the
  2375      scroll bar.  */
  2376   FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = 14;
  2377 #endif
  2378 }
  2379 
  2380 static void
  2381 x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
  2382 {
  2383   double alpha = 1.0;
  2384   double newval[2];
  2385   int i;
  2386   Lisp_Object item;
  2387   bool alpha_identical_p;
  2388 
  2389   alpha_identical_p = true;
  2390 
  2391   for (i = 0; i < 2; i++)
  2392     {
  2393       newval[i] = 1.0;
  2394       if (CONSP (arg))
  2395         {
  2396           item = CAR (arg);
  2397           arg  = CDR (arg);
  2398 
  2399           alpha_identical_p = false;
  2400         }
  2401       else
  2402         item = arg;
  2403 
  2404       if (NILP (item))
  2405         alpha = - 1.0;
  2406       else if (FLOATP (item))
  2407         {
  2408           alpha = XFLOAT_DATA (item);
  2409           if (! (0 <= alpha && alpha <= 1.0))
  2410             args_out_of_range (make_float (0.0), make_float (1.0));
  2411         }
  2412       else if (FIXNUMP (item))
  2413         {
  2414           EMACS_INT ialpha = XFIXNUM (item);
  2415           if (! (0 <= ialpha && ialpha <= 100))
  2416             args_out_of_range (make_fixnum (0), make_fixnum (100));
  2417           alpha = ialpha / 100.0;
  2418         }
  2419       else
  2420         wrong_type_argument (Qnumberp, item);
  2421       newval[i] = alpha;
  2422     }
  2423 
  2424   for (i = 0; i < 2; i++)
  2425     f->alpha[i] = newval[i];
  2426 
  2427   FRAME_X_OUTPUT (f)->alpha_identical_p = alpha_identical_p;
  2428 
  2429   if (FRAME_TERMINAL (f)->set_frame_alpha_hook)
  2430     {
  2431       block_input ();
  2432       FRAME_TERMINAL (f)->set_frame_alpha_hook (f);
  2433       unblock_input ();
  2434     }
  2435 }
  2436 
  2437 static void
  2438 x_set_use_frame_synchronization (struct frame *f, Lisp_Object arg,
  2439                                  Lisp_Object oldval)
  2440 {
  2441 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  2442   struct x_display_info *dpyinfo;
  2443   unsigned long bypass_compositor;
  2444 
  2445   dpyinfo = FRAME_DISPLAY_INFO (f);
  2446 
  2447   if (!NILP (arg) && FRAME_X_EXTENDED_COUNTER (f))
  2448     {
  2449       FRAME_X_OUTPUT (f)->use_vsync_p
  2450         = x_wm_supports (f, dpyinfo->Xatom_net_wm_frame_drawn);
  2451 
  2452       /* At the same time, write the bypass compositor property to the
  2453          outer window.  2 means to never bypass the compositor, as we
  2454          need its cooperation for frame synchronization.  */
  2455       bypass_compositor = 2;
  2456       XChangeProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  2457                        dpyinfo->Xatom_net_wm_bypass_compositor,
  2458                        XA_CARDINAL, 32, PropModeReplace,
  2459                        (unsigned char *) &bypass_compositor, 1);
  2460     }
  2461   else
  2462     {
  2463       FRAME_X_OUTPUT (f)->use_vsync_p = false;
  2464 
  2465       /* Remove the compositor bypass property from the outer
  2466          window.  */
  2467       XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  2468                        dpyinfo->Xatom_net_wm_bypass_compositor);
  2469     }
  2470 
  2471   store_frame_param (f, Quse_frame_synchronization,
  2472                      FRAME_X_OUTPUT (f)->use_vsync_p ? Qt : Qnil);
  2473 #else
  2474   store_frame_param (f, Quse_frame_synchronization, Qnil);
  2475 #endif
  2476 }
  2477 
  2478 
  2479 /* Record in frame F the specified or default value according to ALIST
  2480    of the parameter named PROP (a Lisp symbol).  If no value is
  2481    specified for PROP, look for an X default for XPROP on the frame
  2482    named NAME.  If that is not found either, use the value DEFLT.  */
  2483 
  2484 static Lisp_Object
  2485 x_default_scroll_bar_color_parameter (struct frame *f,
  2486                                       Lisp_Object alist, Lisp_Object prop,
  2487                                       const char *xprop, const char *xclass,
  2488                                       bool foreground_p)
  2489 {
  2490   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  2491   Lisp_Object tem;
  2492 
  2493   tem = gui_display_get_arg (dpyinfo, alist, prop, xprop, xclass,
  2494                              RES_TYPE_STRING);
  2495   if (BASE_EQ (tem, Qunbound))
  2496     {
  2497 #ifdef USE_TOOLKIT_SCROLL_BARS
  2498 
  2499       /* See if an X resource for the scroll bar color has been
  2500          specified.  */
  2501       AUTO_STRING (foreground, "foreground");
  2502       AUTO_STRING (background, "foreground");
  2503       AUTO_STRING (verticalScrollBar, "verticalScrollBar");
  2504       tem = (gui_display_get_resource
  2505              (dpyinfo, foreground_p ? foreground : background,
  2506               empty_unibyte_string,
  2507               verticalScrollBar,
  2508               empty_unibyte_string));
  2509       if (!STRINGP (tem))
  2510         {
  2511           /* If nothing has been specified, scroll bars will use a
  2512              toolkit-dependent default.  Because these defaults are
  2513              difficult to get at without actually creating a scroll
  2514              bar, use nil to indicate that no color has been
  2515              specified.  */
  2516           tem = Qnil;
  2517         }
  2518 
  2519 #else /* not USE_TOOLKIT_SCROLL_BARS */
  2520 
  2521       tem = Qnil;
  2522 
  2523 #endif /* not USE_TOOLKIT_SCROLL_BARS */
  2524     }
  2525 
  2526   AUTO_FRAME_ARG (arg, prop, tem);
  2527   gui_set_frame_parameters (f, arg);
  2528   return tem;
  2529 }
  2530 
  2531 
  2532 
  2533 
  2534 #ifdef USE_X_TOOLKIT
  2535 
  2536 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS,
  2537    WM_DELETE_WINDOW, and WM_SAVE_YOURSELF, then add them.  (They may
  2538    already be present because of the toolkit (Motif adds some of them,
  2539    for example, but Xt doesn't).  */
  2540 
  2541 static void
  2542 hack_wm_protocols (struct frame *f, Widget widget)
  2543 {
  2544   Display *dpy = XtDisplay (widget);
  2545   Window w = XtWindow (widget);
  2546   bool need_delete = true;
  2547   bool need_focus = true;
  2548   bool need_save = true;
  2549 
  2550   block_input ();
  2551   {
  2552     Atom type;
  2553     unsigned char *catoms;
  2554     int format = 0;
  2555     unsigned long nitems = 0;
  2556     unsigned long bytes_after;
  2557 
  2558     if ((XGetWindowProperty (dpy, w,
  2559                              FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
  2560                              0, 100, False, XA_ATOM,
  2561                              &type, &format, &nitems, &bytes_after,
  2562                              &catoms)
  2563          == Success)
  2564         && format == 32 && type == XA_ATOM)
  2565       {
  2566         Atom *atoms = (Atom *) catoms;
  2567         while (nitems > 0)
  2568           {
  2569             nitems--;
  2570             if (atoms[nitems]
  2571                 == FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window)
  2572               need_delete = false;
  2573             else if (atoms[nitems]
  2574                      == FRAME_DISPLAY_INFO (f)->Xatom_wm_take_focus)
  2575               need_focus = false;
  2576             else if (atoms[nitems]
  2577                      == FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself)
  2578               need_save = false;
  2579           }
  2580       }
  2581     if (catoms)
  2582       XFree (catoms);
  2583   }
  2584   {
  2585     Atom props[10];
  2586     int count = 0;
  2587     if (need_delete)
  2588       props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window;
  2589     if (need_focus)
  2590       props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_take_focus;
  2591     if (need_save)
  2592       props[count++] = FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
  2593     if (count)
  2594       XChangeProperty (dpy, w, FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
  2595                        XA_ATOM, 32, PropModeAppend,
  2596                        (unsigned char *) props, count);
  2597   }
  2598   unblock_input ();
  2599 }
  2600 #endif
  2601 
  2602 static void
  2603 append_wm_protocols (struct x_display_info *dpyinfo,
  2604                      struct frame *f)
  2605 {
  2606   unsigned char *existing = NULL;
  2607   int format = 0;
  2608   unsigned long nitems = 0;
  2609   Atom type;
  2610   Atom *existing_protocols;
  2611   Atom protos[10];
  2612   int num_protos = 0;
  2613   bool found_wm_ping = false;
  2614 #if !defined HAVE_GTK3 && defined HAVE_XSYNC
  2615   bool found_wm_sync_request = false;
  2616 #endif
  2617   unsigned long bytes_after;
  2618 
  2619   block_input ();
  2620   if ((XGetWindowProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  2621                            dpyinfo->Xatom_wm_protocols,
  2622                            0, 100, False, XA_ATOM, &type, &format, &nitems,
  2623                            &bytes_after, &existing) == Success)
  2624       && format == 32 && type == XA_ATOM)
  2625     {
  2626       existing_protocols = (Atom *) existing;
  2627 
  2628       while (nitems)
  2629         {
  2630           nitems--;
  2631 
  2632           if (existing_protocols[nitems]
  2633               == dpyinfo->Xatom_net_wm_ping)
  2634             found_wm_ping = true;
  2635 #if !defined HAVE_GTK3 && defined HAVE_XSYNC
  2636           else if (existing_protocols[nitems]
  2637                    == dpyinfo->Xatom_net_wm_sync_request)
  2638             found_wm_sync_request = true;
  2639 #endif
  2640         }
  2641     }
  2642 
  2643   if (existing)
  2644     XFree (existing);
  2645 
  2646   if (!found_wm_ping)
  2647     protos[num_protos++] = dpyinfo->Xatom_net_wm_ping;
  2648 #if !defined HAVE_GTK3 && defined HAVE_XSYNC
  2649   if (!found_wm_sync_request && dpyinfo->xsync_supported_p)
  2650     protos[num_protos++] = dpyinfo->Xatom_net_wm_sync_request;
  2651 #endif
  2652 
  2653   if (num_protos)
  2654     XChangeProperty (dpyinfo->display,
  2655                      FRAME_OUTER_WINDOW (f),
  2656                      dpyinfo->Xatom_wm_protocols,
  2657                      XA_ATOM, 32, PropModeAppend,
  2658                      (unsigned char *) protos,
  2659                      num_protos);
  2660   unblock_input ();
  2661 }
  2662 
  2663 
  2664 
  2665 /* Support routines for XIC (X Input Context).  */
  2666 
  2667 #ifdef HAVE_X_I18N
  2668 
  2669 static void xic_preedit_draw_callback (XIC, XPointer, XIMPreeditDrawCallbackStruct *);
  2670 static void xic_preedit_caret_callback (XIC, XPointer, XIMPreeditCaretCallbackStruct *);
  2671 static void xic_preedit_done_callback (XIC, XPointer, XPointer);
  2672 static int xic_preedit_start_callback (XIC, XPointer, XPointer);
  2673 
  2674 #ifndef HAVE_XICCALLBACK_CALLBACK
  2675 #define XICCallback XIMCallback
  2676 #define XICProc XIMProc
  2677 #endif
  2678 
  2679 static XIMCallback Xxic_preedit_draw_callback = { NULL,
  2680                                                   (XIMProc) xic_preedit_draw_callback };
  2681 static XIMCallback Xxic_preedit_caret_callback = { NULL,
  2682                                                    (XIMProc) xic_preedit_caret_callback };
  2683 static XIMCallback Xxic_preedit_done_callback = { NULL,
  2684                                                   (XIMProc) xic_preedit_done_callback };
  2685 static XICCallback Xxic_preedit_start_callback = { NULL,
  2686                                                    (XICProc) xic_preedit_start_callback };
  2687 
  2688 #if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
  2689 /* Create an X fontset on frame F with base font name BASE_FONTNAME.  */
  2690 
  2691 static const char xic_default_fontset[] = "-*-*-*-r-normal--14-*-*-*-*-*-*-*";
  2692 
  2693 /* Create an Xt fontset spec from the name of a base font.
  2694    If `motif' is True use the Motif syntax.  */
  2695 char *
  2696 xic_create_fontsetname (const char *base_fontname, bool motif)
  2697 {
  2698   const char *sep = motif ? ";" : ",";
  2699   char *fontsetname;
  2700   char *z;
  2701 
  2702   /* Make a fontset name from the base font name.  */
  2703   if (xic_default_fontset == base_fontname)
  2704     {
  2705       /* There is no base font name, use the default.  */
  2706       fontsetname = xmalloc (strlen (base_fontname) + 2);
  2707       z = stpcpy (fontsetname, base_fontname);
  2708     }
  2709   else
  2710     {
  2711       /* Make a fontset name from the base font name.
  2712          The font set will be made of the following elements:
  2713          - the base font.
  2714          - the base font where the charset spec is replaced by -*-*.
  2715          - the same but with the family also replaced with -*-*-.  */
  2716       const char *p = base_fontname;
  2717       ptrdiff_t i;
  2718 
  2719       for (i = 0; *p; p++)
  2720         if (*p == '-') i++;
  2721       if (i != 14)
  2722         {
  2723           /* As the font name doesn't conform to XLFD, we can't
  2724              modify it to generalize it to allcs and allfamilies.
  2725              Use the specified font plus the default.  */
  2726           fontsetname = xmalloc (strlen (base_fontname)
  2727                                  + strlen (xic_default_fontset) + 3);
  2728           z = stpcpy (fontsetname, base_fontname);
  2729           z = stpcpy (z, sep);
  2730           z = stpcpy (z, xic_default_fontset);
  2731         }
  2732       else
  2733         {
  2734           ptrdiff_t len;
  2735           const char *p1 = NULL, *p2 = NULL, *p3 = NULL;
  2736           char *font_allcs = NULL;
  2737           char *font_allfamilies = NULL;
  2738           char *font_all = NULL;
  2739           const char *allcs = "*-*-*-*-*-*-*";
  2740           const char *allfamilies = "-*-*-";
  2741           const char *all = "*-*-*-*-";
  2742           char *base;
  2743 
  2744           for (i = 0, p = base_fontname; i < 8; p++)
  2745             {
  2746               if (*p == '-')
  2747                 {
  2748                   i++;
  2749                   if (i == 3)
  2750                     p1 = p + 1;
  2751                   else if (i == 7)
  2752                     p2 = p + 1;
  2753                   else if (i == 6)
  2754                     p3 = p + 1;
  2755                 }
  2756             }
  2757           /* If base_fontname specifies ADSTYLE, make it a
  2758              wildcard.  */
  2759           if (*p3 != '*')
  2760             {
  2761               ptrdiff_t diff = (p2 - p3) - 2;
  2762 
  2763               base = alloca (strlen (base_fontname) + 1);
  2764               memcpy (base, base_fontname, p3 - base_fontname);
  2765               base[p3 - base_fontname] = '*';
  2766               base[(p3 - base_fontname) + 1] = '-';
  2767               strcpy (base + (p3 - base_fontname) + 2, p2);
  2768               p = base + (p - base_fontname) - diff;
  2769               p1 = base + (p1 - base_fontname);
  2770               p2 = base + (p2 - base_fontname) - diff;
  2771               base_fontname = base;
  2772             }
  2773 
  2774           /* Build the font spec that matches all charsets.  */
  2775           len = p - base_fontname + strlen (allcs) + 1;
  2776           font_allcs = alloca (len);
  2777           memcpy (font_allcs, base_fontname, p - base_fontname);
  2778           strcpy (font_allcs + (p - base_fontname), allcs);
  2779 
  2780           /* Build the font spec that matches all families and
  2781              add-styles.  */
  2782           len = p - p1 + strlen (allcs) + strlen (allfamilies) + 1;
  2783           font_allfamilies = alloca (len);
  2784           strcpy (font_allfamilies, allfamilies);
  2785           memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1);
  2786           strcpy (font_allfamilies + strlen (allfamilies) + (p - p1), allcs);
  2787 
  2788           /* Build the font spec that matches all.  */
  2789           len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1;
  2790           font_all = alloca (len);
  2791           z = stpcpy (font_all, allfamilies);
  2792           z = stpcpy (z, all);
  2793           memcpy (z, p2, p - p2);
  2794           strcpy (z + (p - p2), allcs);
  2795 
  2796           /* Build the actual font set name.  */
  2797           len = strlen (base_fontname) + strlen (font_allcs)
  2798             + strlen (font_allfamilies) + strlen (font_all) + 5;
  2799           fontsetname = xmalloc (len);
  2800           z = stpcpy (fontsetname, base_fontname);
  2801           z = stpcpy (z, sep);
  2802           z = stpcpy (z, font_allcs);
  2803           z = stpcpy (z, sep);
  2804           z = stpcpy (z, font_allfamilies);
  2805           z = stpcpy (z, sep);
  2806           z = stpcpy (z, font_all);
  2807         }
  2808     }
  2809   if (motif)
  2810     strcpy (z, ":");
  2811   return fontsetname;
  2812 }
  2813 #endif /* HAVE_X_WINDOWS && USE_X_TOOLKIT */
  2814 
  2815 #ifdef DEBUG_XIC_FONTSET
  2816 static void
  2817 print_fontset_result (XFontSet xfs, char *name, char **missing_list,
  2818                       int missing_count)
  2819 {
  2820   if (xfs)
  2821     fprintf (stderr, "XIC Fontset created: %s\n", name);
  2822   else
  2823     {
  2824       fprintf (stderr, "XIC Fontset failed: %s\n", name);
  2825       while (missing_count-- > 0)
  2826         {
  2827           fprintf (stderr, "  missing: %s\n", *missing_list);
  2828           missing_list++;
  2829         }
  2830     }
  2831 
  2832 }
  2833 #endif
  2834 
  2835 static XFontSet
  2836 xic_create_xfontset (struct frame *f)
  2837 {
  2838   XFontSet xfs = NULL;
  2839   struct font *font = FRAME_FONT (f);
  2840   int pixel_size = font->pixel_size;
  2841   Lisp_Object rest, frame;
  2842 
  2843   /* See if there is another frame already using same fontset.  */
  2844   FOR_EACH_FRAME (rest, frame)
  2845     {
  2846       struct frame *cf = XFRAME (frame);
  2847 
  2848       if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
  2849           && FRAME_DISPLAY_INFO (cf) == FRAME_DISPLAY_INFO (f)
  2850           && FRAME_FONT (f)
  2851           && FRAME_FONT (f)->pixel_size == pixel_size)
  2852         {
  2853           xfs = FRAME_XIC_FONTSET (cf);
  2854           break;
  2855         }
  2856     }
  2857 
  2858   if (! xfs)
  2859     {
  2860       char buf[256];
  2861       char **missing_list;
  2862       int missing_count;
  2863       char *def_string;
  2864       const char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*";
  2865 
  2866       sprintf (buf, xlfd_format, pixel_size);
  2867       missing_list = NULL;
  2868       xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
  2869                             &missing_list, &missing_count, &def_string);
  2870 #ifdef DEBUG_XIC_FONTSET
  2871       print_fontset_result (xfs, buf, missing_list, missing_count);
  2872 #endif
  2873       if (missing_list)
  2874         XFreeStringList (missing_list);
  2875       if (! xfs)
  2876         {
  2877           /* List of pixel sizes most likely available.  Find one that
  2878              is closest to pixel_size.  */
  2879           int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0};
  2880           int *smaller, *larger;
  2881 
  2882           for (smaller = sizes; smaller[1]; smaller++)
  2883             if (smaller[1] >= pixel_size)
  2884               break;
  2885           larger = smaller + 1;
  2886           if (*larger == pixel_size)
  2887             larger++;
  2888           while (*smaller || *larger)
  2889             {
  2890               int this_size;
  2891 
  2892               if (! *larger)
  2893                 this_size = *smaller--;
  2894               else if (! *smaller)
  2895                 this_size = *larger++;
  2896               else if (pixel_size - *smaller < *larger - pixel_size)
  2897                 this_size = *smaller--;
  2898               else
  2899                 this_size = *larger++;
  2900               sprintf (buf, xlfd_format, this_size);
  2901               missing_list = NULL;
  2902               xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf,
  2903                                     &missing_list, &missing_count, &def_string);
  2904 #ifdef DEBUG_XIC_FONTSET
  2905               print_fontset_result (xfs, buf, missing_list, missing_count);
  2906 #endif
  2907               if (missing_list)
  2908                 XFreeStringList (missing_list);
  2909               if (xfs)
  2910                 break;
  2911             }
  2912         }
  2913       if (! xfs)
  2914         {
  2915           const char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*";
  2916 
  2917           missing_list = NULL;
  2918           xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort,
  2919                                 &missing_list, &missing_count, &def_string);
  2920 #ifdef DEBUG_XIC_FONTSET
  2921           print_fontset_result (xfs, last_resort, missing_list, missing_count);
  2922 #endif
  2923           if (missing_list)
  2924             XFreeStringList (missing_list);
  2925         }
  2926 
  2927     }
  2928 
  2929   return xfs;
  2930 }
  2931 
  2932 /* Free the X fontset of frame F if it is the last frame using it.  */
  2933 
  2934 void
  2935 xic_free_xfontset (struct frame *f)
  2936 {
  2937   Lisp_Object rest, frame;
  2938   bool shared_p = false;
  2939 
  2940   if (!FRAME_XIC_FONTSET (f))
  2941     return;
  2942 
  2943   /* See if there is another frame sharing the same fontset.  */
  2944   FOR_EACH_FRAME (rest, frame)
  2945     {
  2946       struct frame *cf = XFRAME (frame);
  2947       if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf)
  2948           && FRAME_DISPLAY_INFO (cf) == FRAME_DISPLAY_INFO (f)
  2949           && FRAME_XIC_FONTSET (cf) == FRAME_XIC_FONTSET (f))
  2950         {
  2951           shared_p = true;
  2952           break;
  2953         }
  2954     }
  2955 
  2956   if (!shared_p)
  2957     /* The fontset is not used anymore.  It is safe to free it.  */
  2958     XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f));
  2959 
  2960   FRAME_XIC_FONTSET (f) = NULL;
  2961 }
  2962 
  2963 /* Create XIC for frame F. */
  2964 
  2965 static const XIMStyle supported_xim_styles[] =
  2966   {
  2967     STYLE_NONE,
  2968     STYLE_CALLBACK,
  2969     STYLE_OVERTHESPOT,
  2970     STYLE_OFFTHESPOT,
  2971     STYLE_ROOT
  2972   };
  2973 
  2974 /* Value is the best input style, given user preferences USER (already
  2975    checked to be supported by Emacs), and styles supported by the
  2976    input method XIM.  */
  2977 
  2978 static XIMStyle
  2979 best_xim_style (struct x_display_info *dpyinfo,
  2980                 XIMStyles *xim)
  2981 {
  2982   int i, j;
  2983   int nr_supported = ARRAYELTS (supported_xim_styles);
  2984 
  2985   if (dpyinfo->preferred_xim_style)
  2986     return dpyinfo->preferred_xim_style;
  2987 
  2988   for (i = 0; i < nr_supported; ++i)
  2989     for (j = 0; j < xim->count_styles; ++j)
  2990       if (supported_xim_styles[i] == xim->supported_styles[j])
  2991         return supported_xim_styles[i];
  2992 
  2993   /* Return the default style.  */
  2994   return XIMPreeditNothing | XIMStatusNothing;
  2995 }
  2996 
  2997 /* Create XIC for frame F. */
  2998 
  2999 void
  3000 create_frame_xic (struct frame *f)
  3001 {
  3002   XIM xim;
  3003   XIC xic = NULL;
  3004   XFontSet xfs = NULL;
  3005   XVaNestedList status_attr = NULL;
  3006   XVaNestedList preedit_attr = NULL;
  3007   XRectangle s_area;
  3008   XPoint spot;
  3009   XIMStyle xic_style;
  3010 
  3011   if (FRAME_XIC (f))
  3012     goto out;
  3013 
  3014   xim = FRAME_X_XIM (f);
  3015   if (!xim || ! FRAME_X_XIM_STYLES(f))
  3016     goto out;
  3017 
  3018   /* Determine XIC style.  */
  3019   xic_style = best_xim_style (FRAME_DISPLAY_INFO (f),
  3020                               FRAME_X_XIM_STYLES (f));
  3021 
  3022   /* Create X fontset. */
  3023   if (xic_style & (XIMPreeditPosition | XIMStatusArea))
  3024     {
  3025       xfs = xic_create_xfontset (f);
  3026       if (!xfs)
  3027         goto out;
  3028 
  3029       FRAME_XIC_FONTSET (f) = xfs;
  3030     }
  3031 
  3032   if (xic_style & XIMPreeditPosition)
  3033     {
  3034       spot.x = 0; spot.y = 1;
  3035       preedit_attr = XVaCreateNestedList (0,
  3036                                           XNFontSet, xfs,
  3037                                           XNForeground,
  3038                                           FRAME_FOREGROUND_PIXEL (f),
  3039                                           XNBackground,
  3040                                           FRAME_BACKGROUND_PIXEL (f),
  3041                                           (xic_style & XIMPreeditPosition
  3042                                            ? XNSpotLocation
  3043                                            : NULL),
  3044                                           &spot,
  3045                                           NULL);
  3046 
  3047       if (!preedit_attr)
  3048         goto out;
  3049     }
  3050 
  3051   if (xic_style & XIMStatusArea)
  3052     {
  3053       s_area.x = 0; s_area.y = 0; s_area.width = 1; s_area.height = 1;
  3054       status_attr = XVaCreateNestedList (0,
  3055                                          XNArea,
  3056                                          &s_area,
  3057                                          XNFontSet,
  3058                                          xfs,
  3059                                          XNForeground,
  3060                                          FRAME_FOREGROUND_PIXEL (f),
  3061                                          XNBackground,
  3062                                          FRAME_BACKGROUND_PIXEL (f),
  3063                                          NULL);
  3064 
  3065       if (!status_attr)
  3066         goto out;
  3067     }
  3068 
  3069   if (xic_style & XIMPreeditCallbacks)
  3070     {
  3071       spot.x = 0;
  3072       spot.y = 0;
  3073       preedit_attr = XVaCreateNestedList (0,
  3074                                           XNSpotLocation, &spot,
  3075                                           XNPreeditStartCallback, &Xxic_preedit_start_callback,
  3076                                           XNPreeditDoneCallback, &Xxic_preedit_done_callback,
  3077                                           XNPreeditDrawCallback, &Xxic_preedit_draw_callback,
  3078                                           XNPreeditCaretCallback, &Xxic_preedit_caret_callback,
  3079                                           NULL);
  3080 
  3081       if (!preedit_attr)
  3082         goto out;
  3083     }
  3084 
  3085   if (preedit_attr && status_attr)
  3086     xic = XCreateIC (xim,
  3087                      XNInputStyle, xic_style,
  3088                      XNClientWindow, FRAME_X_WINDOW (f),
  3089                      XNFocusWindow, FRAME_X_WINDOW (f),
  3090                      XNStatusAttributes, status_attr,
  3091                      XNPreeditAttributes, preedit_attr,
  3092                      NULL);
  3093   else if (preedit_attr)
  3094     xic = XCreateIC (xim,
  3095                      XNInputStyle, xic_style,
  3096                      XNClientWindow, FRAME_X_WINDOW (f),
  3097                      XNFocusWindow, FRAME_X_WINDOW (f),
  3098                      XNPreeditAttributes, preedit_attr,
  3099                      NULL);
  3100   else if (status_attr)
  3101     xic = XCreateIC (xim,
  3102                      XNInputStyle, xic_style,
  3103                      XNClientWindow, FRAME_X_WINDOW (f),
  3104                      XNFocusWindow, FRAME_X_WINDOW (f),
  3105                      XNStatusAttributes, status_attr,
  3106                      NULL);
  3107   else
  3108     xic = XCreateIC (xim,
  3109                      XNInputStyle, xic_style,
  3110                      XNClientWindow, FRAME_X_WINDOW (f),
  3111                      XNFocusWindow, FRAME_X_WINDOW (f),
  3112                      NULL);
  3113 
  3114   if (!xic)
  3115     goto out;
  3116 
  3117   FRAME_XIC (f) = xic;
  3118   FRAME_XIC_STYLE (f) = xic_style;
  3119   xfs = NULL; /* Don't free below.  */
  3120 
  3121  out:
  3122 
  3123   if (xfs)
  3124     free_frame_xic (f);
  3125 
  3126   if (preedit_attr)
  3127     XFree (preedit_attr);
  3128 
  3129   if (status_attr)
  3130     XFree (status_attr);
  3131 }
  3132 
  3133 
  3134 /* Destroy XIC and free XIC fontset of frame F, if any. */
  3135 
  3136 void
  3137 free_frame_xic (struct frame *f)
  3138 {
  3139   if (FRAME_XIC (f) == NULL)
  3140     return;
  3141 
  3142   XDestroyIC (FRAME_XIC (f));
  3143   xic_free_xfontset (f);
  3144 
  3145   FRAME_XIC (f) = NULL;
  3146 }
  3147 
  3148 
  3149 /* Place preedit area for XIC of window W's frame to specified
  3150    pixel position X/Y.  X and Y are relative to window W.  */
  3151 
  3152 void
  3153 xic_set_preeditarea (struct window *w, int x, int y)
  3154 {
  3155   struct frame *f = WINDOW_XFRAME (w);
  3156   XVaNestedList attr;
  3157   XPoint spot;
  3158 
  3159   if (FRAME_XIC (f))
  3160     {
  3161       spot.x = (WINDOW_TO_FRAME_PIXEL_X (w, x)
  3162                 + WINDOW_LEFT_FRINGE_WIDTH (w)
  3163                 + WINDOW_LEFT_MARGIN_WIDTH (w));
  3164       spot.y = (WINDOW_TO_FRAME_PIXEL_Y (w, y)
  3165                 + w->phys_cursor_height);
  3166 
  3167       if (FRAME_XIC_STYLE (f) & XIMPreeditCallbacks)
  3168         attr = XVaCreateNestedList (0, XNSpotLocation, &spot,
  3169                                     XNPreeditStartCallback, &Xxic_preedit_start_callback,
  3170                                     XNPreeditDoneCallback, &Xxic_preedit_done_callback,
  3171                                     XNPreeditDrawCallback, &Xxic_preedit_draw_callback,
  3172                                     XNPreeditCaretCallback, &Xxic_preedit_caret_callback,
  3173                                     NULL);
  3174       else
  3175         attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
  3176       XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
  3177       XFree (attr);
  3178     }
  3179 #ifdef USE_GTK
  3180   if (f->tooltip)
  3181     return;
  3182 
  3183   GdkRectangle rect;
  3184   int scale = xg_get_scale (f);
  3185 
  3186   rect.x = (WINDOW_TO_FRAME_PIXEL_X (w, x)
  3187             + WINDOW_LEFT_FRINGE_WIDTH (w)
  3188             + WINDOW_LEFT_MARGIN_WIDTH (w)) / scale;
  3189   rect.y = (WINDOW_TO_FRAME_PIXEL_Y (w, y)
  3190             + FRAME_TOOLBAR_HEIGHT (f)
  3191             + FRAME_MENUBAR_HEIGHT (f)) / scale;
  3192   rect.width = w->phys_cursor_width / scale;
  3193   rect.height = w->phys_cursor_height / scale;
  3194 
  3195   gtk_im_context_set_cursor_location (FRAME_X_OUTPUT (f)->im_context,
  3196                                       &rect);
  3197 #endif
  3198 }
  3199 
  3200 
  3201 /* Place status area for XIC in bottom right corner of frame F.. */
  3202 
  3203 void
  3204 xic_set_statusarea (struct frame *f)
  3205 {
  3206   XIC xic = FRAME_XIC (f);
  3207   XVaNestedList attr;
  3208   XRectangle area;
  3209   XRectangle *needed;
  3210 
  3211   /* Negotiate geometry of status area.  If input method has existing
  3212      status area, use its current size.  */
  3213   area.x = area.y = area.width = area.height = 0;
  3214   attr = XVaCreateNestedList (0, XNAreaNeeded, &area, NULL);
  3215   XSetICValues (xic, XNStatusAttributes, attr, NULL);
  3216   XFree (attr);
  3217 
  3218   attr = XVaCreateNestedList (0, XNAreaNeeded, &needed, NULL);
  3219   XGetICValues (xic, XNStatusAttributes, attr, NULL);
  3220   XFree (attr);
  3221 
  3222   if (needed->width == 0) /* Use XNArea instead of XNAreaNeeded */
  3223     {
  3224       attr = XVaCreateNestedList (0, XNArea, &needed, NULL);
  3225       XGetICValues (xic, XNStatusAttributes, attr, NULL);
  3226       XFree (attr);
  3227     }
  3228 
  3229   area.width  = needed->width;
  3230   area.height = needed->height;
  3231   area.x = FRAME_PIXEL_WIDTH (f) - area.width - FRAME_INTERNAL_BORDER_WIDTH (f);
  3232   area.y = (FRAME_PIXEL_HEIGHT (f) - area.height
  3233             - FRAME_MENUBAR_HEIGHT (f)
  3234             - FRAME_TOOLBAR_TOP_HEIGHT (f)
  3235             - FRAME_INTERNAL_BORDER_WIDTH (f));
  3236   XFree (needed);
  3237 
  3238   attr = XVaCreateNestedList (0, XNArea, &area, NULL);
  3239   XSetICValues (xic, XNStatusAttributes, attr, NULL);
  3240   XFree (attr);
  3241 }
  3242 
  3243 static struct frame *
  3244 x_xic_to_frame (XIC xic)
  3245 {
  3246   Lisp_Object tail, tem;
  3247   struct frame *f;
  3248 
  3249   FOR_EACH_FRAME (tail, tem)
  3250     {
  3251       f = XFRAME (tem);
  3252 
  3253       if (FRAME_X_P (f) && FRAME_XIC (f) == xic)
  3254         return f;
  3255     }
  3256 
  3257   return NULL;
  3258 }
  3259 
  3260 static int
  3261 xic_preedit_start_callback (XIC xic, XPointer client_data,
  3262                             XPointer call_data)
  3263 {
  3264   struct frame *f = x_xic_to_frame (xic);
  3265   struct x_output *output;
  3266 
  3267   if (f)
  3268     {
  3269       output = FRAME_X_OUTPUT (f);
  3270 
  3271       output->preedit_size = 0;
  3272       output->preedit_active = true;
  3273       output->preedit_caret = 0;
  3274 
  3275       if (output->preedit_chars)
  3276         xfree (output->preedit_chars);
  3277 
  3278       output->preedit_chars = NULL;
  3279     }
  3280 
  3281   return -1;
  3282 }
  3283 
  3284 static void
  3285 xic_preedit_caret_callback (XIC xic, XPointer client_data,
  3286                             XIMPreeditCaretCallbackStruct *call_data)
  3287 {
  3288   struct frame *f = x_xic_to_frame (xic);
  3289   struct x_output *output;
  3290   struct input_event ie;
  3291   EVENT_INIT (ie);
  3292 
  3293   if (f)
  3294     {
  3295       output = FRAME_X_OUTPUT (f);
  3296 
  3297       if (!output->preedit_active)
  3298         return;
  3299 
  3300       switch (call_data->direction)
  3301         {
  3302         case XIMAbsolutePosition:
  3303           output->preedit_caret = call_data->position;
  3304           break;
  3305         case XIMForwardChar:
  3306         case XIMForwardWord:
  3307           call_data->position = output->preedit_caret++;
  3308           break;
  3309         case XIMBackwardChar:
  3310         case XIMBackwardWord:
  3311           call_data->position = max (0, output->preedit_caret--);
  3312           break;
  3313         default:
  3314           call_data->position = output->preedit_caret;
  3315         }
  3316 
  3317       if (output->preedit_chars)
  3318         {
  3319           ie.kind = PREEDIT_TEXT_EVENT;
  3320           XSETFRAME (ie.frame_or_window, f);
  3321           ie.arg = make_string_from_utf8 (output->preedit_chars,
  3322                                           output->preedit_size);
  3323 
  3324           if (SCHARS (ie.arg))
  3325             Fput_text_property (make_fixnum (min (SCHARS (ie.arg) - 1,
  3326                                                   max (0, output->preedit_caret))),
  3327                                 make_fixnum (max (SCHARS (ie.arg),
  3328                                                   max (0, output->preedit_caret) + 1)),
  3329                                 Qcursor, Qt, ie.arg);
  3330 
  3331           XSETINT (ie.x, 0);
  3332           XSETINT (ie.y, 0);
  3333 
  3334           kbd_buffer_store_event (&ie);
  3335         }
  3336     }
  3337 }
  3338 
  3339 
  3340 static void
  3341 xic_preedit_done_callback (XIC xic, XPointer client_data,
  3342                            XPointer call_data)
  3343 {
  3344   struct frame *f = x_xic_to_frame (xic);
  3345   struct x_output *output;
  3346   struct input_event ie;
  3347   EVENT_INIT (ie);
  3348 
  3349   if (f)
  3350     {
  3351       ie.kind = PREEDIT_TEXT_EVENT;
  3352       ie.arg = Qnil;
  3353       XSETFRAME (ie.frame_or_window, f);
  3354       XSETINT (ie.x, 0);
  3355       XSETINT (ie.y, 0);
  3356       kbd_buffer_store_event (&ie);
  3357 
  3358       output = FRAME_X_OUTPUT (f);
  3359 
  3360       if (output->preedit_chars)
  3361         xfree (output->preedit_chars);
  3362 
  3363       output->preedit_size = 0;
  3364       output->preedit_active = false;
  3365       output->preedit_chars = NULL;
  3366       output->preedit_caret = 0;
  3367     }
  3368 }
  3369 
  3370 struct x_xim_text_conversion_data
  3371 {
  3372   struct coding_system *coding;
  3373   char *source;
  3374   struct x_display_info *dpyinfo;
  3375 };
  3376 
  3377 static Lisp_Object
  3378 x_xim_text_to_utf8_unix_1 (ptrdiff_t nargs, Lisp_Object *args)
  3379 {
  3380   struct x_xim_text_conversion_data *data;
  3381   ptrdiff_t nbytes;
  3382   Lisp_Object coding_system;
  3383 
  3384   data = xmint_pointer (args[0]);
  3385 
  3386   if (SYMBOLP (Vx_input_coding_system))
  3387     coding_system = Vx_input_coding_system;
  3388   else if (!NILP (data->dpyinfo->xim_coding))
  3389     coding_system = data->dpyinfo->xim_coding;
  3390   else
  3391     coding_system = Vlocale_coding_system;
  3392 
  3393   nbytes = strlen (data->source);
  3394 
  3395   data->coding->destination = NULL;
  3396 
  3397   setup_coding_system (coding_system, data->coding);
  3398   data->coding->mode |= (CODING_MODE_LAST_BLOCK
  3399                          | CODING_MODE_SAFE_ENCODING);
  3400   data->coding->source = (const unsigned char *) data->source;
  3401   data->coding->dst_bytes = 2048;
  3402   data->coding->destination = xmalloc (2048);
  3403   decode_coding_object (data->coding, Qnil, 0, 0,
  3404                         nbytes, nbytes, Qnil);
  3405 
  3406   return Qnil;
  3407 }
  3408 
  3409 static Lisp_Object
  3410 x_xim_text_to_utf8_unix_2 (Lisp_Object val, ptrdiff_t nargs,
  3411                            Lisp_Object *args)
  3412 {
  3413   struct x_xim_text_conversion_data *data;
  3414 
  3415   data = xmint_pointer (args[0]);
  3416 
  3417   if (data->coding->destination)
  3418     xfree (data->coding->destination);
  3419 
  3420   data->coding->destination = NULL;
  3421 
  3422   return Qnil;
  3423 }
  3424 
  3425 /* The string returned is not null-terminated.  */
  3426 static char *
  3427 x_xim_text_to_utf8_unix (struct x_display_info *dpyinfo,
  3428                          XIMText *text, ptrdiff_t *length)
  3429 {
  3430   unsigned char *wchar_buf;
  3431   ptrdiff_t wchar_actual_length, i;
  3432   struct coding_system coding;
  3433   struct x_xim_text_conversion_data data;
  3434   bool was_waiting_for_input_p;
  3435   Lisp_Object arg;
  3436 
  3437   if (text->encoding_is_wchar)
  3438     {
  3439       wchar_buf = xmalloc ((text->length + 1) * MAX_MULTIBYTE_LENGTH);
  3440       wchar_actual_length = 0;
  3441 
  3442       for (i = 0; i < text->length; ++i)
  3443         wchar_actual_length += CHAR_STRING (text->string.wide_char[i],
  3444                                             wchar_buf + wchar_actual_length);
  3445       *length = wchar_actual_length;
  3446 
  3447       return (char *) wchar_buf;
  3448     }
  3449 
  3450   data.coding = &coding;
  3451   data.source = text->string.multi_byte;
  3452   data.dpyinfo = dpyinfo;
  3453 
  3454   was_waiting_for_input_p = waiting_for_input;
  3455   /* Otherwise Fsignal will crash.  */
  3456   waiting_for_input = false;
  3457   arg = make_mint_ptr (&data);
  3458   internal_condition_case_n (x_xim_text_to_utf8_unix_1, 1, &arg,
  3459                              Qt, x_xim_text_to_utf8_unix_2);
  3460   waiting_for_input = was_waiting_for_input_p;
  3461 
  3462   *length = coding.produced;
  3463   return (char *) coding.destination;
  3464 }
  3465 
  3466 static void
  3467 xic_preedit_draw_callback (XIC xic, XPointer client_data,
  3468                            XIMPreeditDrawCallbackStruct *call_data)
  3469 {
  3470   struct frame *f;
  3471   struct x_output *output;
  3472   ptrdiff_t text_length;
  3473   ptrdiff_t charpos;
  3474   ptrdiff_t original_size;
  3475   char *text;
  3476   char *chg_start, *chg_end;
  3477   struct input_event ie;
  3478 
  3479   f = x_xic_to_frame (xic);
  3480   EVENT_INIT (ie);
  3481 
  3482   if (f)
  3483     {
  3484       text_length = 0;
  3485       output = FRAME_X_OUTPUT (f);
  3486 
  3487       if (!output->preedit_active)
  3488         return;
  3489 
  3490       if (call_data->text)
  3491         {
  3492           text = x_xim_text_to_utf8_unix (FRAME_DISPLAY_INFO (f),
  3493                                           call_data->text, &text_length);
  3494 
  3495           if (!text)
  3496             /* Decoding the IM text failed.  */
  3497             goto im_abort;
  3498         }
  3499       else
  3500         text = NULL;
  3501 
  3502       original_size = output->preedit_size;
  3503 
  3504       /* This is an ordinary insertion: reallocate the buffer to hold
  3505          enough for TEXT.  */
  3506       if (!call_data->chg_length)
  3507         {
  3508           if (!text)
  3509             goto im_abort;
  3510 
  3511           if (output->preedit_chars)
  3512             output->preedit_chars = xrealloc (output->preedit_chars,
  3513                                               output->preedit_size += text_length);
  3514           else
  3515             output->preedit_chars = xmalloc (output->preedit_size += text_length);
  3516         }
  3517 
  3518       chg_start = output->preedit_chars;
  3519 
  3520       /* The IM sent bad data: the buffer is empty, but the change
  3521          position is more than 0.  */
  3522       if (!output->preedit_chars && call_data->chg_first)
  3523         goto im_abort;
  3524 
  3525       /* Find the byte position for the character position where the
  3526          first change is to be made.  */
  3527       if (call_data->chg_first)
  3528         {
  3529           charpos = 0;
  3530 
  3531           while (charpos < call_data->chg_first)
  3532             {
  3533               chg_start += BYTES_BY_CHAR_HEAD (*chg_start);
  3534 
  3535               if ((chg_start - output->preedit_chars) > output->preedit_size)
  3536                 /* The IM sent bad data: chg_start is larger than the
  3537                    current buffer.  */
  3538                 goto im_abort;
  3539               ++charpos;
  3540             }
  3541         }
  3542 
  3543       if (!call_data->chg_length)
  3544         {
  3545           if (!text)
  3546             goto im_abort;
  3547 
  3548           memmove (chg_start + text_length, chg_start,
  3549                    original_size - (chg_start - output->preedit_chars));
  3550           memcpy (chg_start, text, text_length);
  3551         }
  3552       else
  3553         {
  3554           if (call_data->chg_length < 1)
  3555             goto im_abort;
  3556 
  3557           charpos = 0;
  3558           chg_end = chg_start;
  3559 
  3560           while (charpos < call_data->chg_length)
  3561             {
  3562               chg_end += BYTES_BY_CHAR_HEAD (*chg_end);
  3563 
  3564               if ((chg_end - output->preedit_chars) > output->preedit_size)
  3565                 /* The IM sent bad data: chg_end ends someplace outside
  3566                    the current buffer.  */
  3567                 goto im_abort;
  3568               ++charpos;
  3569             }
  3570 
  3571           memmove (chg_start, chg_end, ((output->preedit_chars
  3572                                          + output->preedit_size) - chg_end));
  3573           output->preedit_size -= (chg_end - chg_start);
  3574 
  3575           if (text)
  3576             {
  3577               original_size = output->preedit_size;
  3578               output->preedit_chars = xrealloc (output->preedit_chars,
  3579                                                 output->preedit_size += text_length);
  3580 
  3581               /* Find chg_start again, since preedit_chars was reallocated.  */
  3582 
  3583               chg_start = output->preedit_chars;
  3584               charpos = 0;
  3585 
  3586               while (charpos < call_data->chg_first)
  3587                 {
  3588                   chg_start += BYTES_BY_CHAR_HEAD (*chg_start);
  3589 
  3590                   if ((chg_start - output->preedit_chars) > output->preedit_size)
  3591                     /* The IM sent bad data: chg_start is larger than the
  3592                        current buffer.  */
  3593                     goto im_abort;
  3594                   ++charpos;
  3595                 }
  3596 
  3597               memmove (chg_start + text_length, chg_start,
  3598                        original_size - (chg_start - output->preedit_chars));
  3599               memcpy (chg_start, text, text_length);
  3600             }
  3601         }
  3602 
  3603       if (text)
  3604         xfree (text);
  3605 
  3606       output->preedit_caret = call_data->caret;
  3607 
  3608       /* This is okay because this callback is called from the big XIM
  3609          event filter, which runs inside XTread_socket.  */
  3610 
  3611       ie.kind = PREEDIT_TEXT_EVENT;
  3612       XSETFRAME (ie.frame_or_window, f);
  3613       ie.arg = make_string_from_utf8 (output->preedit_chars,
  3614                                       output->preedit_size);
  3615 
  3616       if (SCHARS (ie.arg))
  3617         Fput_text_property (make_fixnum (min (SCHARS (ie.arg) - 1,
  3618                                               max (0, output->preedit_caret))),
  3619                             make_fixnum (min (SCHARS (ie.arg),
  3620                                               max (0, output->preedit_caret) + 1)),
  3621                             Qcursor, Qt, ie.arg);
  3622 
  3623       XSETINT (ie.x, 0);
  3624       XSETINT (ie.y, 0);
  3625 
  3626       kbd_buffer_store_event (&ie);
  3627     }
  3628 
  3629   return;
  3630 
  3631  im_abort:
  3632   if (text)
  3633     xfree (text);
  3634   if (output->preedit_chars)
  3635     xfree (output->preedit_chars);
  3636   output->preedit_chars = NULL;
  3637   output->preedit_size = 0;
  3638   output->preedit_active = false;
  3639   output->preedit_caret = 0;
  3640 }
  3641 
  3642 void
  3643 xic_set_xfontset (struct frame *f, const char *base_fontname)
  3644 {
  3645   XVaNestedList attr;
  3646   XFontSet xfs;
  3647 
  3648   xic_free_xfontset (f);
  3649 
  3650   xfs = xic_create_xfontset (f);
  3651 
  3652   attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL);
  3653   if (FRAME_XIC_STYLE (f) & XIMPreeditPosition)
  3654     XSetICValues (FRAME_XIC (f), XNPreeditAttributes, attr, NULL);
  3655   if (FRAME_XIC_STYLE (f) & XIMStatusArea)
  3656     XSetICValues (FRAME_XIC (f), XNStatusAttributes, attr, NULL);
  3657   XFree (attr);
  3658 
  3659   FRAME_XIC_FONTSET (f) = xfs;
  3660 }
  3661 
  3662 #endif /* HAVE_X_I18N */
  3663 
  3664 
  3665 
  3666 
  3667 void
  3668 x_mark_frame_dirty (struct frame *f)
  3669 {
  3670 #ifdef HAVE_XDBE
  3671   if (FRAME_X_DOUBLE_BUFFERED_P (f)
  3672       && !FRAME_X_NEED_BUFFER_FLIP (f))
  3673     FRAME_X_NEED_BUFFER_FLIP (f) = true;
  3674 #endif
  3675 }
  3676 
  3677 static void
  3678 set_up_x_back_buffer (struct frame *f)
  3679 {
  3680 #ifdef HAVE_XRENDER
  3681   block_input ();
  3682   if (FRAME_X_PICTURE (f) != None)
  3683     {
  3684       XRenderFreePicture (FRAME_X_DISPLAY (f),
  3685                           FRAME_X_PICTURE (f));
  3686       FRAME_X_PICTURE (f) = None;
  3687     }
  3688   unblock_input ();
  3689 #endif
  3690 
  3691 #ifdef HAVE_XDBE
  3692   block_input ();
  3693   if (FRAME_X_WINDOW (f) && !FRAME_X_DOUBLE_BUFFERED_P (f))
  3694     {
  3695 #ifdef USE_CAIRO
  3696       x_cr_destroy_frame_context (f);
  3697 #endif
  3698       FRAME_X_RAW_DRAWABLE (f) = FRAME_X_WINDOW (f);
  3699       if (FRAME_DISPLAY_INFO (f)->supports_xdbe)
  3700         {
  3701           /* If allocating a back buffer fails, either because the
  3702              server ran out of memory or we don't have the right kind
  3703              of visual, just use single-buffered rendering.  */
  3704           x_catch_errors (FRAME_X_DISPLAY (f));
  3705           FRAME_X_RAW_DRAWABLE (f)
  3706             = XdbeAllocateBackBufferName (FRAME_X_DISPLAY (f),
  3707                                           FRAME_X_WINDOW (f),
  3708                                           XdbeCopied);
  3709           if (x_had_errors_p (FRAME_X_DISPLAY (f)))
  3710             FRAME_X_RAW_DRAWABLE (f) = FRAME_X_WINDOW (f);
  3711           x_uncatch_errors_after_check ();
  3712         }
  3713     }
  3714   unblock_input ();
  3715 #endif
  3716 }
  3717 
  3718 void
  3719 tear_down_x_back_buffer (struct frame *f)
  3720 {
  3721 #ifdef HAVE_XRENDER
  3722   block_input ();
  3723   if (FRAME_X_PICTURE (f) != None)
  3724     {
  3725       XRenderFreePicture (FRAME_X_DISPLAY (f),
  3726                           FRAME_X_PICTURE (f));
  3727       FRAME_X_PICTURE (f) = None;
  3728     }
  3729   unblock_input ();
  3730 #endif
  3731 
  3732 #ifdef HAVE_XDBE
  3733   block_input ();
  3734   if (FRAME_X_WINDOW (f) && FRAME_X_DOUBLE_BUFFERED_P (f))
  3735     {
  3736       if (FRAME_X_DOUBLE_BUFFERED_P (f))
  3737         {
  3738 #ifdef USE_CAIRO
  3739           x_cr_destroy_frame_context (f);
  3740 #endif
  3741           XdbeDeallocateBackBufferName (FRAME_X_DISPLAY (f),
  3742                                         FRAME_X_DRAWABLE (f));
  3743           FRAME_X_RAW_DRAWABLE (f) = FRAME_X_WINDOW (f);
  3744         }
  3745     }
  3746   unblock_input ();
  3747 #endif
  3748 }
  3749 
  3750 /* Set up double buffering if the frame parameters don't prohibit
  3751    it.  */
  3752 void
  3753 initial_set_up_x_back_buffer (struct frame *f)
  3754 {
  3755   eassert (FRAME_X_WINDOW (f));
  3756   FRAME_X_RAW_DRAWABLE (f) = FRAME_X_WINDOW (f);
  3757 
  3758   if (NILP (CDR (Fassq (Qinhibit_double_buffering,
  3759                         f->param_alist))))
  3760     set_up_x_back_buffer (f);
  3761 }
  3762 
  3763 #if defined HAVE_XINPUT2
  3764 static void
  3765 setup_xi_event_mask (struct frame *f)
  3766 {
  3767   XIEventMask mask;
  3768   ptrdiff_t l = XIMaskLen (XI_LASTEVENT);
  3769   unsigned char *m;
  3770 #ifndef HAVE_XINPUT2_1
  3771   /* Set up fallback values, since XIGetSelectedEvents doesn't work
  3772      with this version of libXi.  */
  3773   XIEventMask *selected;
  3774 
  3775   selected = xzalloc (sizeof *selected + l);
  3776   selected->mask = ((unsigned char *) selected) + sizeof *selected;
  3777   selected->mask_len = l;
  3778   selected->deviceid = XIAllMasterDevices;
  3779 #endif
  3780 
  3781   mask.mask = m = alloca (l);
  3782   memset (m, 0, l);
  3783   mask.mask_len = l;
  3784 
  3785   block_input ();
  3786 #ifndef HAVE_GTK3
  3787   mask.deviceid = XIAllMasterDevices;
  3788 
  3789   XISetMask (m, XI_ButtonPress);
  3790   XISetMask (m, XI_ButtonRelease);
  3791   XISetMask (m, XI_Motion);
  3792   XISetMask (m, XI_Enter);
  3793   XISetMask (m, XI_Leave);
  3794 #ifndef USE_GTK
  3795   XISetMask (m, XI_FocusIn);
  3796   XISetMask (m, XI_FocusOut);
  3797   XISetMask (m, XI_KeyPress);
  3798   XISetMask (m, XI_KeyRelease);
  3799 #endif
  3800   XISelectEvents (FRAME_X_DISPLAY (f),
  3801                   FRAME_X_WINDOW (f),
  3802                   &mask, 1);
  3803 
  3804   /* Fortunately `xi_masks' isn't used on GTK 3, where we really have
  3805      to get the event mask from the X server.  */
  3806 #ifndef HAVE_XINPUT2_1
  3807   memcpy (selected->mask, m, l);
  3808 #endif
  3809 
  3810   memset (m, 0, l);
  3811 #endif /* !HAVE_GTK3 */
  3812 
  3813 #ifdef USE_X_TOOLKIT
  3814   XISetMask (m, XI_KeyPress);
  3815   XISetMask (m, XI_KeyRelease);
  3816   XISetMask (m, XI_FocusIn);
  3817   XISetMask (m, XI_FocusOut);
  3818 
  3819   XISelectEvents (FRAME_X_DISPLAY (f),
  3820                   FRAME_OUTER_WINDOW (f),
  3821                   &mask, 1);
  3822   memset (m, 0, l);
  3823 #endif
  3824 
  3825 #ifdef HAVE_XINPUT2_2
  3826   if (FRAME_DISPLAY_INFO (f)->xi2_version >= 2)
  3827     {
  3828       mask.deviceid = XIAllDevices;
  3829 
  3830       XISetMask (m, XI_TouchBegin);
  3831       XISetMask (m, XI_TouchUpdate);
  3832       XISetMask (m, XI_TouchEnd);
  3833 #ifdef HAVE_XINPUT2_4
  3834       if (FRAME_DISPLAY_INFO (f)->xi2_version >= 4)
  3835         {
  3836           XISetMask (m, XI_GesturePinchBegin);
  3837           XISetMask (m, XI_GesturePinchUpdate);
  3838           XISetMask (m, XI_GesturePinchEnd);
  3839         }
  3840 #endif
  3841 
  3842       XISelectEvents (FRAME_X_DISPLAY (f),
  3843                       FRAME_X_WINDOW (f),
  3844                       &mask, 1);
  3845     }
  3846 #endif
  3847 
  3848 #ifndef HAVE_XINPUT2_1
  3849   FRAME_X_OUTPUT (f)->xi_masks = selected;
  3850   FRAME_X_OUTPUT (f)->num_xi_masks = 1;
  3851 #endif
  3852 
  3853   unblock_input ();
  3854 }
  3855 #endif
  3856 
  3857 #ifdef USE_X_TOOLKIT
  3858 
  3859 /* Create and set up the X widget for frame F.  */
  3860 
  3861 static void
  3862 x_window (struct frame *f, long window_prompting)
  3863 {
  3864   XClassHint class_hints;
  3865   XSetWindowAttributes attributes;
  3866   unsigned long attribute_mask;
  3867   Widget shell_widget;
  3868   Widget pane_widget;
  3869   Widget frame_widget;
  3870   Arg al[25];
  3871   int ac;
  3872 
  3873   block_input ();
  3874 
  3875   /* Use the resource name as the top-level widget name
  3876      for looking up resources.  Make a non-Lisp copy
  3877      for the window manager, so GC relocation won't bother it.
  3878 
  3879      Elsewhere we specify the window name for the window manager.  */
  3880   f->namebuf = xlispstrdup (Vx_resource_name);
  3881 
  3882   ac = 0;
  3883   XtSetArg (al[ac], XtNallowShellResize, 1); ac++;
  3884   XtSetArg (al[ac], XtNinput, 1); ac++;
  3885   XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
  3886   XtSetArg (al[ac], XtNborderWidth, f->border_width); ac++;
  3887   XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
  3888   XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
  3889   XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
  3890   shell_widget = XtAppCreateShell (f->namebuf, EMACS_CLASS,
  3891                                    applicationShellWidgetClass,
  3892                                    FRAME_X_DISPLAY (f), al, ac);
  3893 
  3894   f->output_data.x->widget = shell_widget;
  3895   /* maybe_set_screen_title_format (shell_widget); */
  3896 
  3897   pane_widget = lw_create_widget ("main", "pane", widget_id_tick++,
  3898                                   NULL, shell_widget, False,
  3899                                   NULL, NULL, NULL, NULL);
  3900 
  3901   ac = 0;
  3902   XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
  3903   XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
  3904   XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
  3905   XtSetArg (al[ac], XtNborderWidth, 0); ac++;
  3906   XtSetValues (pane_widget, al, ac);
  3907   f->output_data.x->column_widget = pane_widget;
  3908 
  3909   /* mappedWhenManaged to false tells to the paned window to not map/unmap
  3910      the emacs screen when changing menubar.  This reduces flickering.  */
  3911 
  3912   ac = 0;
  3913   XtSetArg (al[ac], XtNmappedWhenManaged, 0); ac++;
  3914   XtSetArg (al[ac], (char *) XtNshowGrip, 0); ac++;
  3915   XtSetArg (al[ac], (char *) XtNallowResize, 1); ac++;
  3916   XtSetArg (al[ac], (char *) XtNresizeToPreferred, 1); ac++;
  3917   XtSetArg (al[ac], (char *) XtNemacsFrame, f); ac++;
  3918   XtSetArg (al[ac], XtNvisual, FRAME_X_VISUAL (f)); ac++;
  3919   XtSetArg (al[ac], XtNdepth, FRAME_DISPLAY_INFO (f)->n_planes); ac++;
  3920   XtSetArg (al[ac], XtNcolormap, FRAME_X_COLORMAP (f)); ac++;
  3921   XtSetArg (al[ac], XtNborderWidth, 0); ac++;
  3922   frame_widget = XtCreateWidget (f->namebuf, emacsFrameClass (), pane_widget,
  3923                                  al, ac);
  3924 
  3925   f->output_data.x->edit_widget = frame_widget;
  3926 
  3927   XtManageChild (frame_widget);
  3928 
  3929   /* Do some needed geometry management.  */
  3930   {
  3931     Arg gal[3];
  3932     int gac = 0;
  3933     int extra_borders = 0;
  3934     int menubar_size
  3935       = (f->output_data.x->menubar_widget
  3936          ? (f->output_data.x->menubar_widget->core.height
  3937             + f->output_data.x->menubar_widget->core.border_width)
  3938          : 0);
  3939 
  3940 #if false /* Experimentally, we now get the right results
  3941              for -geometry -0-0 without this.  24 Aug 96, rms.  */
  3942     if (FRAME_EXTERNAL_MENU_BAR (f))
  3943       {
  3944         Dimension ibw = 0;
  3945         XtVaGetValues (pane_widget, XtNinternalBorderWidth, &ibw, NULL);
  3946         menubar_size += ibw;
  3947       }
  3948 #endif
  3949 
  3950     FRAME_MENUBAR_HEIGHT (f) = menubar_size;
  3951 
  3952 #ifndef USE_LUCID
  3953     /* Motif seems to need this amount added to the sizes
  3954        specified for the shell widget.  The Athena/Lucid widgets don't.
  3955        Both conclusions reached experimentally.  -- rms.  */
  3956     XtVaGetValues (f->output_data.x->edit_widget, XtNinternalBorderWidth,
  3957                    &extra_borders, NULL);
  3958     extra_borders *= 2;
  3959 #endif
  3960 
  3961     f->shell_position = xmalloc (sizeof "=x++" + 4 * INT_STRLEN_BOUND (int));
  3962 
  3963     /* Convert our geometry parameters into a geometry string
  3964        and specify it.
  3965        Note that we do not specify here whether the position
  3966        is a user-specified or program-specified one.
  3967        We pass that information later, in x_wm_set_size_hint.  */
  3968     {
  3969       int left = f->left_pos;
  3970       bool xneg = (window_prompting & XNegative) != 0;
  3971       int top = f->top_pos;
  3972       bool yneg = (window_prompting & YNegative) != 0;
  3973       if (xneg)
  3974         left = -left;
  3975       if (yneg)
  3976         top = -top;
  3977 
  3978       if (window_prompting & USPosition)
  3979         sprintf (f->shell_position, "=%dx%d%c%d%c%d",
  3980                  FRAME_PIXEL_WIDTH (f) + extra_borders,
  3981                  FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders,
  3982                  (xneg ? '-' : '+'), left,
  3983                  (yneg ? '-' : '+'), top);
  3984       else
  3985         {
  3986           sprintf (f->shell_position, "=%dx%d",
  3987                    FRAME_PIXEL_WIDTH (f) + extra_borders,
  3988                    FRAME_PIXEL_HEIGHT (f) + menubar_size + extra_borders);
  3989 
  3990           /* Setting x and y when the position is not specified in
  3991              the geometry string will set program position in the WM hints.
  3992              If Emacs had just one program position, we could set it in
  3993              fallback resources, but since each make-frame call can specify
  3994              different program positions, this is easier.  */
  3995           XtSetArg (gal[gac], XtNx, left); gac++;
  3996           XtSetArg (gal[gac], XtNy, top); gac++;
  3997         }
  3998     }
  3999 
  4000     XtSetArg (gal[gac], XtNgeometry, f->shell_position); gac++;
  4001     XtSetValues (shell_widget, gal, gac);
  4002   }
  4003 
  4004   XtManageChild (pane_widget);
  4005   XtRealizeWidget (shell_widget);
  4006 
  4007   FRAME_X_WINDOW (f) = XtWindow (frame_widget);
  4008   initial_set_up_x_back_buffer (f);
  4009   validate_x_resource_name ();
  4010 
  4011   class_hints.res_name = SSDATA (Vx_resource_name);
  4012   class_hints.res_class = SSDATA (Vx_resource_class);
  4013   XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
  4014 
  4015 #ifdef HAVE_X_I18N
  4016   FRAME_XIC (f) = NULL;
  4017   if (use_xim)
  4018     create_frame_xic (f);
  4019 #endif
  4020 
  4021   f->output_data.x->wm_hints.input = True;
  4022   f->output_data.x->wm_hints.flags |= InputHint;
  4023   XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  4024                &f->output_data.x->wm_hints);
  4025 
  4026   hack_wm_protocols (f, shell_widget);
  4027   append_wm_protocols (FRAME_DISPLAY_INFO (f), f);
  4028 
  4029 #ifdef X_TOOLKIT_EDITRES
  4030   XtAddEventHandler (shell_widget, 0, True, _XEditResCheckMessages, 0);
  4031 #endif
  4032 
  4033   /* Do a stupid property change to force the server to generate a
  4034      PropertyNotify event so that the event_stream server timestamp will
  4035      be initialized to something relevant to the time we created the window.
  4036      */
  4037   XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget),
  4038                    FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols,
  4039                    XA_ATOM, 32, PropModeAppend, NULL, 0);
  4040 
  4041   /* Make all the standard events reach the Emacs frame.  */
  4042   attributes.event_mask = STANDARD_EVENT_SET;
  4043 
  4044 #ifdef HAVE_X_I18N
  4045   if (FRAME_XIC (f))
  4046     {
  4047       /* XIM server might require some X events. */
  4048       unsigned long fevent = NoEventMask;
  4049       XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
  4050       attributes.event_mask |= fevent;
  4051     }
  4052 #endif /* HAVE_X_I18N */
  4053 
  4054   attributes.override_redirect = FRAME_OVERRIDE_REDIRECT (f);
  4055   attribute_mask = CWEventMask | CWOverrideRedirect;
  4056   XChangeWindowAttributes (XtDisplay (shell_widget), XtWindow (shell_widget),
  4057                            attribute_mask, &attributes);
  4058 
  4059   XtMapWidget (frame_widget);
  4060 
  4061   /* x_set_name normally ignores requests to set the name if the
  4062      requested name is the same as the current name.  This is the one
  4063      place where that assumption isn't correct; f->name is set, but
  4064      the X server hasn't been told.  */
  4065   {
  4066     Lisp_Object name;
  4067     bool explicit = f->explicit_name;
  4068 
  4069     f->explicit_name = false;
  4070     name = f->name;
  4071     fset_name (f, Qnil);
  4072     x_set_name (f, name, explicit);
  4073   }
  4074 
  4075   if (FRAME_UNDECORATED (f))
  4076     {
  4077       Display *dpy = FRAME_X_DISPLAY (f);
  4078       PropMotifWmHints hints;
  4079       Atom prop = FRAME_DISPLAY_INFO (f)->Xatom_MOTIF_WM_HINTS;
  4080 
  4081       memset (&hints, 0, sizeof(hints));
  4082       hints.flags = MWM_HINTS_DECORATIONS;
  4083       hints.decorations = 0;
  4084 
  4085       /* For some reason the third and fourth arguments in the following
  4086          call must be identical: In the corresponding XGetWindowProperty
  4087          call in getMotifHints, xfwm has the third and seventh args both
  4088          display_info->atoms[MOTIF_WM_HINTS].  Obviously, YMMV.   */
  4089       XChangeProperty (dpy, FRAME_OUTER_WINDOW (f), prop, prop, 32,
  4090                        PropModeReplace, (unsigned char *) &hints,
  4091                        PROP_MOTIF_WM_HINTS_ELEMENTS);
  4092     }
  4093 
  4094   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  4095                  f->output_data.x->current_cursor
  4096                  = f->output_data.x->text_cursor);
  4097 
  4098   unblock_input ();
  4099 
  4100   /* This is a no-op, except under Motif.  Make sure main areas are
  4101      set to something reasonable, in case we get an error later.  */
  4102   lw_set_main_areas (pane_widget, 0, frame_widget);
  4103 
  4104 #ifdef HAVE_XINPUT2
  4105   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
  4106     setup_xi_event_mask (f);
  4107 #endif
  4108 }
  4109 
  4110 #else /* not USE_X_TOOLKIT */
  4111 #ifdef USE_GTK
  4112 static void
  4113 x_window (struct frame *f)
  4114 {
  4115   if (! xg_create_frame_widgets (f))
  4116     error ("Unable to create window");
  4117 
  4118 #ifdef HAVE_X_I18N
  4119   FRAME_XIC (f) = NULL;
  4120   if (use_xim)
  4121   {
  4122     block_input ();
  4123     create_frame_xic (f);
  4124     if (FRAME_XIC (f))
  4125       {
  4126         /* XIM server might require some X events. */
  4127         unsigned long fevent = NoEventMask;
  4128         XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
  4129 
  4130         if (fevent != NoEventMask)
  4131           {
  4132             XSetWindowAttributes attributes;
  4133             XWindowAttributes wattr;
  4134             unsigned long attribute_mask;
  4135 
  4136             XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  4137                                   &wattr);
  4138             attributes.event_mask = wattr.your_event_mask | fevent;
  4139             attribute_mask = CWEventMask;
  4140             XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  4141                                      attribute_mask, &attributes);
  4142           }
  4143       }
  4144     unblock_input ();
  4145   }
  4146 #endif
  4147 
  4148   append_wm_protocols (FRAME_DISPLAY_INFO (f), f);
  4149 
  4150 #ifdef HAVE_XINPUT2
  4151   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
  4152     setup_xi_event_mask (f);
  4153 #endif
  4154 }
  4155 
  4156 #else /*! USE_GTK */
  4157 /* Create and set up the X window for frame F.  */
  4158 
  4159 static void
  4160 x_window (struct frame *f)
  4161 {
  4162   XClassHint class_hints;
  4163   XSetWindowAttributes attributes;
  4164   unsigned long attribute_mask;
  4165 
  4166   attributes.background_pixel = FRAME_BACKGROUND_PIXEL (f);
  4167   attributes.border_pixel = f->output_data.x->border_pixel;
  4168   attributes.bit_gravity = StaticGravity;
  4169   attributes.backing_store = NotUseful;
  4170   attributes.save_under = True;
  4171   attributes.event_mask = STANDARD_EVENT_SET;
  4172   attributes.colormap = FRAME_X_COLORMAP (f);
  4173   attributes.override_redirect = FRAME_OVERRIDE_REDIRECT (f);
  4174   attribute_mask = (CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask
  4175                     | CWOverrideRedirect | CWColormap);
  4176 
  4177   block_input ();
  4178   FRAME_X_WINDOW (f)
  4179     = XCreateWindow (FRAME_X_DISPLAY (f),
  4180                      FRAME_DISPLAY_INFO (f)->root_window,
  4181                      f->left_pos,
  4182                      f->top_pos,
  4183                      FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
  4184                      f->border_width,
  4185                      FRAME_DISPLAY_INFO (f)->n_planes, /* depth */
  4186                      InputOutput, /* class */
  4187                      FRAME_X_VISUAL (f),
  4188                      attribute_mask, &attributes);
  4189   initial_set_up_x_back_buffer (f);
  4190 
  4191 #ifdef HAVE_X_I18N
  4192   if (use_xim)
  4193     {
  4194       create_frame_xic (f);
  4195       if (FRAME_XIC (f))
  4196         {
  4197           /* XIM server might require some X events. */
  4198           unsigned long fevent = NoEventMask;
  4199 
  4200           if (fevent)
  4201             {
  4202               XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
  4203               attributes.event_mask |= fevent;
  4204               attribute_mask = CWEventMask;
  4205               XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  4206                                        attribute_mask, &attributes);
  4207             }
  4208         }
  4209     }
  4210 #endif /* HAVE_X_I18N */
  4211 
  4212 #ifdef HAVE_XINPUT2
  4213   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
  4214     setup_xi_event_mask (f);
  4215 #endif
  4216 
  4217   validate_x_resource_name ();
  4218 
  4219   class_hints.res_name = SSDATA (Vx_resource_name);
  4220   class_hints.res_class = SSDATA (Vx_resource_class);
  4221   XSetClassHint (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &class_hints);
  4222 
  4223   /* This indicates that we use the "Passive Input" input model.
  4224      Unless we do this, we don't get the Focus{In,Out} events that we
  4225      need to draw the cursor correctly.  Accursed bureaucrats.
  4226    XWhipsAndChains (FRAME_X_DISPLAY (f), IronMaiden, &TheRack);  */
  4227 
  4228   f->output_data.x->wm_hints.input = True;
  4229   f->output_data.x->wm_hints.flags |= InputHint;
  4230   XSetWMHints (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  4231                &f->output_data.x->wm_hints);
  4232   f->output_data.x->wm_hints.icon_pixmap = None;
  4233 
  4234   /* Request "save yourself" and "delete window" commands from wm.  */
  4235   {
  4236     Atom protocols[2];
  4237     protocols[0] = FRAME_DISPLAY_INFO (f)->Xatom_wm_delete_window;
  4238     protocols[1] = FRAME_DISPLAY_INFO (f)->Xatom_wm_save_yourself;
  4239     XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
  4240   }
  4241 
  4242   append_wm_protocols (FRAME_DISPLAY_INFO (f), f);
  4243 
  4244   /* x_set_name normally ignores requests to set the name if the
  4245      requested name is the same as the current name.  This is the one
  4246      place where that assumption isn't correct; f->name is set, but
  4247      the X server hasn't been told.  */
  4248   {
  4249     Lisp_Object name;
  4250     bool explicit = f->explicit_name;
  4251 
  4252     f->explicit_name = false;
  4253     name = f->name;
  4254     fset_name (f, Qnil);
  4255     x_set_name (f, name, explicit);
  4256   }
  4257 
  4258   if (FRAME_UNDECORATED (f))
  4259     {
  4260       Display *dpy = FRAME_X_DISPLAY (f);
  4261       PropMotifWmHints hints;
  4262       Atom prop = FRAME_DISPLAY_INFO (f)->Xatom_MOTIF_WM_HINTS;
  4263 
  4264       memset (&hints, 0, sizeof(hints));
  4265       hints.flags = MWM_HINTS_DECORATIONS;
  4266       hints.decorations = 0;
  4267 
  4268       /* For some reason the third and fourth arguments in the following
  4269          call must be identical: In the corresponding XGetWindowProperty
  4270          call in getMotifHints, xfwm has the third and seventh args both
  4271          display_info->atoms[MOTIF_WM_HINTS].  Obviously, YMMV.   */
  4272       XChangeProperty (dpy, FRAME_OUTER_WINDOW (f), prop, prop, 32,
  4273                        PropModeReplace, (unsigned char *) &hints,
  4274                        PROP_MOTIF_WM_HINTS_ELEMENTS);
  4275     }
  4276 
  4277 
  4278   XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  4279                  f->output_data.x->current_cursor
  4280                  = f->output_data.x->text_cursor);
  4281 
  4282   unblock_input ();
  4283 
  4284   if (FRAME_X_WINDOW (f) == 0)
  4285     error ("Unable to create window");
  4286 }
  4287 
  4288 #endif /* not USE_GTK */
  4289 #endif /* not USE_X_TOOLKIT */
  4290 
  4291 /* Verify that the icon position args for this window are valid.  */
  4292 
  4293 static void
  4294 x_icon_verify (struct frame *f, Lisp_Object parms)
  4295 {
  4296   Lisp_Object icon_x, icon_y;
  4297 
  4298   /* Set the position of the icon.  Note that twm groups all
  4299      icons in an icon window.  */
  4300   icon_x = gui_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
  4301   icon_y = gui_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
  4302   if (!BASE_EQ (icon_x, Qunbound) && !BASE_EQ (icon_y, Qunbound))
  4303     {
  4304       CHECK_FIXNUM (icon_x);
  4305       CHECK_FIXNUM (icon_y);
  4306     }
  4307   else if (!BASE_EQ (icon_x, Qunbound) || !BASE_EQ (icon_y, Qunbound))
  4308     error ("Both left and top icon corners of icon must be specified");
  4309 }
  4310 
  4311 /* Handle the icon stuff for this window.  Perhaps later we might
  4312    want an x_set_icon_position which can be called interactively as
  4313    well.  */
  4314 
  4315 static void
  4316 x_icon (struct frame *f, Lisp_Object parms)
  4317 {
  4318   /* Set the position of the icon.  Note that twm groups all
  4319      icons in an icon window.  */
  4320   Lisp_Object icon_x
  4321     = gui_frame_get_and_record_arg (f, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
  4322   Lisp_Object icon_y
  4323     = gui_frame_get_and_record_arg (f, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
  4324   int icon_xval, icon_yval;
  4325 
  4326   bool xgiven = !BASE_EQ (icon_x, Qunbound);
  4327   bool ygiven = !BASE_EQ (icon_y, Qunbound);
  4328   if (xgiven != ygiven)
  4329     error ("Both left and top icon corners of icon must be specified");
  4330   if (xgiven)
  4331     {
  4332       icon_xval = check_integer_range (icon_x, INT_MIN, INT_MAX);
  4333       icon_yval = check_integer_range (icon_y, INT_MIN, INT_MAX);
  4334     }
  4335 
  4336   block_input ();
  4337 
  4338   if (xgiven)
  4339     x_wm_set_icon_position (f, icon_xval, icon_yval);
  4340 
  4341 #if false /* gui_display_get_arg removes the visibility parameter as a
  4342              side effect, but x_create_frame still needs it.  */
  4343   /* Start up iconic or window? */
  4344   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4345   x_wm_set_window_state
  4346     (f, (EQ (gui_display_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
  4347                                   RES_TYPE_SYMBOL),
  4348              Qicon)
  4349          ? IconicState
  4350          : NormalState));
  4351 #endif
  4352 
  4353   x_text_icon (f, SSDATA ((!NILP (f->icon_name)
  4354                            ? f->icon_name
  4355                            : f->name)));
  4356 
  4357   unblock_input ();
  4358 }
  4359 
  4360 /* Make the GCs needed for this window, setting the
  4361    background, border and mouse colors; also create the
  4362    mouse cursor and the gray border tile.  */
  4363 
  4364 static void
  4365 x_make_gc (struct frame *f)
  4366 {
  4367   XGCValues gc_values;
  4368 
  4369   block_input ();
  4370 
  4371   /* Create the GCs of this frame.
  4372      Note that many default values are used.  */
  4373 
  4374   gc_values.foreground = FRAME_FOREGROUND_PIXEL (f);
  4375   gc_values.background = FRAME_BACKGROUND_PIXEL (f);
  4376   gc_values.line_width = 1;
  4377   f->output_data.x->normal_gc
  4378     = XCreateGC (FRAME_X_DISPLAY (f),
  4379                  FRAME_X_DRAWABLE (f),
  4380                  GCLineWidth | GCForeground | GCBackground,
  4381                  &gc_values);
  4382 
  4383   /* Reverse video style.  */
  4384   gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
  4385   gc_values.background = FRAME_FOREGROUND_PIXEL (f);
  4386   f->output_data.x->reverse_gc
  4387     = XCreateGC (FRAME_X_DISPLAY (f),
  4388                  FRAME_X_DRAWABLE (f),
  4389                  GCForeground | GCBackground | GCLineWidth,
  4390                  &gc_values);
  4391 
  4392   /* Cursor has cursor-color background, background-color foreground.  */
  4393   gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
  4394   gc_values.background = f->output_data.x->cursor_pixel;
  4395   f->output_data.x->cursor_gc
  4396     = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  4397                  (GCForeground | GCBackground | GCLineWidth),
  4398                  &gc_values);
  4399 
  4400   /* Create the gray border tile used when the pointer is not in
  4401      the frame.  Since this depends on the frame's pixel values,
  4402      this must be done on a per-frame basis.  */
  4403   f->output_data.x->border_tile
  4404     = (XCreatePixmapFromBitmapData
  4405        (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
  4406         gray_bits, gray_width, gray_height,
  4407         FRAME_FOREGROUND_PIXEL (f),
  4408         FRAME_BACKGROUND_PIXEL (f),
  4409         DefaultDepth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f))));
  4410 
  4411   unblock_input ();
  4412 }
  4413 
  4414 
  4415 /* Free what was allocated in x_make_gc.  */
  4416 
  4417 void
  4418 x_free_gcs (struct frame *f)
  4419 {
  4420   Display *dpy = FRAME_X_DISPLAY (f);
  4421 
  4422   block_input ();
  4423 
  4424   if (f->output_data.x->normal_gc)
  4425     {
  4426       XFreeGC (dpy, f->output_data.x->normal_gc);
  4427       f->output_data.x->normal_gc = 0;
  4428     }
  4429 
  4430   if (f->output_data.x->reverse_gc)
  4431     {
  4432       XFreeGC (dpy, f->output_data.x->reverse_gc);
  4433       f->output_data.x->reverse_gc = 0;
  4434     }
  4435 
  4436   if (f->output_data.x->cursor_gc)
  4437     {
  4438       XFreeGC (dpy, f->output_data.x->cursor_gc);
  4439       f->output_data.x->cursor_gc = 0;
  4440     }
  4441 
  4442   if (f->output_data.x->border_tile)
  4443     {
  4444       XFreePixmap (dpy, f->output_data.x->border_tile);
  4445       f->output_data.x->border_tile = 0;
  4446     }
  4447 
  4448   unblock_input ();
  4449 }
  4450 
  4451 
  4452 /* Handler for signals raised during x_create_frame and
  4453    Fx_create_tip_frame.  FRAME is the frame which is partially
  4454    constructed.  */
  4455 
  4456 static Lisp_Object
  4457 unwind_create_frame (Lisp_Object frame)
  4458 {
  4459   struct frame *f = XFRAME (frame);
  4460 
  4461   /* If frame is already dead, nothing to do.  This can happen if the
  4462      display is disconnected after the frame has become official, but
  4463      before Fx_create_frame removes the unwind protect.  */
  4464   if (!FRAME_LIVE_P (f))
  4465     return Qnil;
  4466 
  4467   /* If frame is ``official'', nothing to do.  */
  4468   if (NILP (Fmemq (frame, Vframe_list)))
  4469     {
  4470 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
  4471       struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4472 #endif
  4473 
  4474       /* If the frame's image cache refcount is still the same as our
  4475          private shadow variable, it means we are unwinding a frame
  4476          for which we didn't yet call init_frame_faces, where the
  4477          refcount is incremented.  Therefore, we increment it here, so
  4478          that free_frame_faces, called in x_free_frame_resources
  4479          below, will not mistakenly decrement the counter that was not
  4480          incremented yet to account for this new frame.  */
  4481       if (FRAME_IMAGE_CACHE (f) != NULL
  4482           && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount)
  4483         FRAME_IMAGE_CACHE (f)->refcount++;
  4484 
  4485       x_free_frame_resources (f);
  4486       free_glyphs (f);
  4487 
  4488 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
  4489       /* Check that reference counts are indeed correct.  */
  4490       eassert (dpyinfo->reference_count == dpyinfo_refcount);
  4491       eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
  4492 #endif
  4493       return Qt;
  4494     }
  4495 
  4496   return Qnil;
  4497 }
  4498 
  4499 static void
  4500 do_unwind_create_frame (Lisp_Object frame)
  4501 {
  4502   unwind_create_frame (frame);
  4503 }
  4504 
  4505 void
  4506 x_default_font_parameter (struct frame *f, Lisp_Object parms)
  4507 {
  4508   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4509   Lisp_Object font_param = gui_display_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
  4510                                                 RES_TYPE_STRING);
  4511   Lisp_Object font = Qnil;
  4512   if (BASE_EQ (font_param, Qunbound))
  4513     font_param = Qnil;
  4514 
  4515   if (NILP (font_param))
  4516     {
  4517       /* System font should take precedence over X resources.  We suggest this
  4518          regardless of font-use-system-font because .emacs may not have been
  4519          read yet.  */
  4520       const char *system_font = xsettings_get_system_font ();
  4521       if (system_font)
  4522         font = font_open_by_name (f, build_unibyte_string (system_font));
  4523     }
  4524 
  4525   if (NILP (font))
  4526     font = (!NILP (font_param)
  4527             ? font_param
  4528             : gui_display_get_arg (dpyinfo, parms,
  4529                                    Qfont, "font", "Font",
  4530                                    RES_TYPE_STRING));
  4531 
  4532   if (! FONTP (font) && ! STRINGP (font))
  4533     {
  4534       const char *names[]
  4535         = {
  4536 #if defined USE_CAIRO || defined HAVE_XFT
  4537             /* This will find the normal Xft font.  */
  4538             "monospace-10",
  4539 #endif
  4540             "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
  4541             "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
  4542             "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
  4543             /* This was formerly the first thing tried, but it finds
  4544                too many fonts and takes too long.  */
  4545             "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1",
  4546             /* If those didn't work, look for something which will
  4547                at least work.  */
  4548             "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1",
  4549             "fixed",
  4550             NULL };
  4551       int i;
  4552 
  4553       for (i = 0; names[i]; i++)
  4554         {
  4555           font = font_open_by_name (f, build_unibyte_string (names[i]));
  4556           if (! NILP (font))
  4557             break;
  4558         }
  4559       if (NILP (font))
  4560         error ("No suitable font was found");
  4561     }
  4562 
  4563   /* This call will make X resources override any system font setting.  */
  4564   gui_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
  4565 }
  4566 
  4567 
  4568 DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint,
  4569        0, 1, 0,
  4570        doc: /* Send the size hints for frame FRAME to the window manager.
  4571 If FRAME is omitted or nil, use the selected frame.
  4572 Signal error if FRAME is not an X frame.  */)
  4573   (Lisp_Object frame)
  4574 {
  4575   struct frame *f = decode_window_system_frame (frame);
  4576 
  4577   block_input ();
  4578   x_wm_set_size_hint (f, 0, false);
  4579   unblock_input ();
  4580   return Qnil;
  4581 }
  4582 
  4583 static void
  4584 set_machine_and_pid_properties (struct frame *f)
  4585 {
  4586   /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME.  */
  4587   XSetWMProperties (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), NULL, NULL,
  4588                     NULL, 0, NULL, NULL, NULL);
  4589   pid_t pid = getpid ();
  4590   if (pid <= 0xffffffffu)
  4591     {
  4592       unsigned long xpid = pid;
  4593       XChangeProperty (FRAME_X_DISPLAY (f),
  4594                        FRAME_OUTER_WINDOW (f),
  4595                        FRAME_DISPLAY_INFO (f)->Xatom_net_wm_pid,
  4596                        XA_CARDINAL, 32, PropModeReplace,
  4597                        (unsigned char *) &xpid, 1);
  4598     }
  4599 }
  4600 
  4601 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
  4602        1, 1, 0,
  4603        doc: /* Make a new X window, which is called a "frame" in Emacs terms.
  4604 Return an Emacs frame object.  PARMS is an alist of frame parameters.
  4605 If the parameters specify that the frame should not have a minibuffer,
  4606 and do not specify a specific minibuffer window to use, then
  4607 `default-minibuffer-frame' must be a frame whose minibuffer can be
  4608 shared by the new frame.
  4609 
  4610 This function is an internal primitive--use `make-frame' instead.  */)
  4611   (Lisp_Object parms)
  4612 {
  4613   struct frame *f;
  4614   Lisp_Object frame, tem;
  4615   Lisp_Object name;
  4616   bool minibuffer_only = false;
  4617   bool undecorated = false, override_redirect = false;
  4618   long window_prompting = 0;
  4619   specpdl_ref count = SPECPDL_INDEX ();
  4620   Lisp_Object display;
  4621   struct x_display_info *dpyinfo = NULL;
  4622   Lisp_Object parent, parent_frame;
  4623   struct kboard *kb;
  4624 #ifdef HAVE_GTK3
  4625   GdkWindow *gwin;
  4626 #endif
  4627 
  4628   parms = Fcopy_alist (parms);
  4629 
  4630   /* Use this general default value to start with
  4631      until we know if this frame has a specified name.  */
  4632   Vx_resource_name = Vinvocation_name;
  4633 
  4634   display = gui_display_get_arg (dpyinfo, parms, Qterminal, 0, 0,
  4635                                  RES_TYPE_NUMBER);
  4636   if (BASE_EQ (display, Qunbound))
  4637     display = gui_display_get_arg (dpyinfo, parms, Qdisplay, 0, 0,
  4638                                    RES_TYPE_STRING);
  4639   if (BASE_EQ (display, Qunbound))
  4640     display = Qnil;
  4641   dpyinfo = check_x_display_info (display);
  4642   kb = dpyinfo->terminal->kboard;
  4643 
  4644   if (!dpyinfo->terminal->name)
  4645     error ("Terminal is not live, can't create new frames on it");
  4646 
  4647   name = gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name",
  4648                               RES_TYPE_STRING);
  4649   if (!STRINGP (name)
  4650       && ! BASE_EQ (name, Qunbound)
  4651       && ! NILP (name))
  4652     error ("Invalid frame name--not a string or nil");
  4653 
  4654   if (STRINGP (name))
  4655     Vx_resource_name = name;
  4656 
  4657   /* See if parent window is specified.  */
  4658   parent = gui_display_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL,
  4659                                 RES_TYPE_NUMBER);
  4660   if (BASE_EQ (parent, Qunbound))
  4661     parent = Qnil;
  4662   if (! NILP (parent))
  4663     CHECK_FIXNUM (parent);
  4664 
  4665   frame = Qnil;
  4666   tem = gui_display_get_arg (dpyinfo,
  4667                              parms, Qminibuffer, "minibuffer", "Minibuffer",
  4668                              RES_TYPE_SYMBOL);
  4669   if (EQ (tem, Qnone) || NILP (tem))
  4670     f = make_frame_without_minibuffer (Qnil, kb, display);
  4671   else if (EQ (tem, Qonly))
  4672     {
  4673       f = make_minibuffer_frame ();
  4674       minibuffer_only = true;
  4675     }
  4676   else if (WINDOWP (tem))
  4677     f = make_frame_without_minibuffer (tem, kb, display);
  4678   else
  4679     f = make_frame (true);
  4680 
  4681   parent_frame = gui_display_get_arg (dpyinfo,
  4682                                       parms,
  4683                                       Qparent_frame,
  4684                                       NULL,
  4685                                       NULL,
  4686                                       RES_TYPE_SYMBOL);
  4687   /* Accept parent-frame iff parent-id was not specified.  */
  4688   if (!NILP (parent)
  4689       || BASE_EQ (parent_frame, Qunbound)
  4690       || NILP (parent_frame)
  4691       || !FRAMEP (parent_frame)
  4692       || !FRAME_LIVE_P (XFRAME (parent_frame))
  4693       || !FRAME_X_P (XFRAME (parent_frame)))
  4694     parent_frame = Qnil;
  4695 
  4696   fset_parent_frame (f, parent_frame);
  4697   store_frame_param (f, Qparent_frame, parent_frame);
  4698 
  4699   if (!NILP (tem = (gui_display_get_arg (dpyinfo,
  4700                                          parms,
  4701                                          Qundecorated,
  4702                                          NULL,
  4703                                          NULL,
  4704                                          RES_TYPE_BOOLEAN)))
  4705       && !(BASE_EQ (tem, Qunbound)))
  4706     undecorated = true;
  4707 
  4708   FRAME_UNDECORATED (f) = undecorated;
  4709   store_frame_param (f, Qundecorated, undecorated ? Qt : Qnil);
  4710 
  4711   if (!NILP (tem = (gui_display_get_arg (dpyinfo,
  4712                                          parms,
  4713                                          Qoverride_redirect,
  4714                                          NULL,
  4715                                          NULL,
  4716                                          RES_TYPE_BOOLEAN)))
  4717       && !(BASE_EQ (tem, Qunbound)))
  4718     override_redirect = true;
  4719 
  4720   FRAME_OVERRIDE_REDIRECT (f) = override_redirect;
  4721   store_frame_param (f, Qoverride_redirect, override_redirect ? Qt : Qnil);
  4722 
  4723   XSETFRAME (frame, f);
  4724 
  4725   f->terminal = dpyinfo->terminal;
  4726 
  4727   f->output_method = output_x_window;
  4728   f->output_data.x = xzalloc (sizeof *f->output_data.x);
  4729   f->output_data.x->icon_bitmap = -1;
  4730   FRAME_FONTSET (f) = -1;
  4731   f->output_data.x->scroll_bar_foreground_pixel = -1;
  4732   f->output_data.x->scroll_bar_background_pixel = -1;
  4733 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
  4734   f->output_data.x->scroll_bar_top_shadow_pixel = -1;
  4735   f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
  4736 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
  4737   f->output_data.x->white_relief.pixel = -1;
  4738   f->output_data.x->black_relief.pixel = -1;
  4739 
  4740   fset_icon_name (f, gui_display_get_arg (dpyinfo,
  4741                                           parms,
  4742                                           Qicon_name,
  4743                                           "iconName",
  4744                                           "Title",
  4745                                           RES_TYPE_STRING));
  4746   if (! STRINGP (f->icon_name))
  4747     fset_icon_name (f, Qnil);
  4748 
  4749   FRAME_DISPLAY_INFO (f) = dpyinfo;
  4750 
  4751   /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe.  */
  4752   record_unwind_protect (do_unwind_create_frame, frame);
  4753 
  4754   /* These colors will be set anyway later, but it's important
  4755      to get the color reference counts right, so initialize them!  */
  4756   {
  4757     Lisp_Object black;
  4758 
  4759     /* Function x_decode_color can signal an error.  Make
  4760        sure to initialize color slots so that we won't try
  4761        to free colors we haven't allocated.  */
  4762     FRAME_FOREGROUND_PIXEL (f) = -1;
  4763     FRAME_BACKGROUND_PIXEL (f) = -1;
  4764     f->output_data.x->cursor_pixel = -1;
  4765     f->output_data.x->cursor_foreground_pixel = -1;
  4766     f->output_data.x->border_pixel = -1;
  4767     f->output_data.x->mouse_pixel = -1;
  4768 
  4769     black = build_string ("black");
  4770     FRAME_FOREGROUND_PIXEL (f)
  4771       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  4772     FRAME_BACKGROUND_PIXEL (f)
  4773       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  4774     f->output_data.x->cursor_pixel
  4775       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  4776     f->output_data.x->cursor_foreground_pixel
  4777       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  4778     f->output_data.x->border_pixel
  4779       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  4780     f->output_data.x->mouse_pixel
  4781       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  4782   }
  4783 
  4784   /* Specify the parent under which to make this X window.  */
  4785   if (!NILP (parent))
  4786     {
  4787       f->output_data.x->parent_desc = (Window) XFIXNAT (parent);
  4788       f->output_data.x->explicit_parent = true;
  4789     }
  4790   else
  4791     {
  4792       f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
  4793       f->output_data.x->explicit_parent = false;
  4794     }
  4795 
  4796   /* Set the name; the functions to which we pass f expect the name to
  4797      be set.  */
  4798   if (BASE_EQ (name, Qunbound) || NILP (name))
  4799     {
  4800       fset_name (f, build_string (dpyinfo->x_id_name));
  4801       f->explicit_name = false;
  4802     }
  4803   else
  4804     {
  4805       fset_name (f, name);
  4806       f->explicit_name = true;
  4807       /* Use the frame's title when getting resources for this frame.  */
  4808       specbind (Qx_resource_name, name);
  4809     }
  4810 
  4811 #ifdef USE_CAIRO
  4812   register_font_driver (&ftcrfont_driver, f);
  4813 #ifdef HAVE_HARFBUZZ
  4814   register_font_driver (&ftcrhbfont_driver, f);
  4815 #endif  /* HAVE_HARFBUZZ */
  4816 #else
  4817 #ifdef HAVE_FREETYPE
  4818 #ifdef HAVE_XFT
  4819   register_font_driver (&xftfont_driver, f);
  4820 #ifdef HAVE_HARFBUZZ
  4821   register_font_driver (&xfthbfont_driver, f);
  4822 #endif
  4823 #endif  /* not HAVE_XFT */
  4824 #endif  /* HAVE_FREETYPE */
  4825 #endif  /* not USE_CAIRO */
  4826   register_font_driver (&xfont_driver, f);
  4827 
  4828   image_cache_refcount =
  4829     FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
  4830 #ifdef GLYPH_DEBUG
  4831   dpyinfo_refcount = dpyinfo->reference_count;
  4832 #endif /* GLYPH_DEBUG */
  4833 
  4834   gui_default_parameter (f, parms, Qfont_backend, Qnil,
  4835                          "fontBackend", "FontBackend", RES_TYPE_STRING);
  4836 
  4837   /* Extract the window parameters from the supplied values
  4838      that are needed to determine window geometry.  */
  4839   x_default_font_parameter (f, parms);
  4840   if (!FRAME_FONT (f))
  4841     {
  4842       delete_frame (frame, Qnoelisp);
  4843       error ("Invalid frame font");
  4844     }
  4845 
  4846   /* Frame contents get displaced if an embedded X window has a border.  */
  4847   if (! FRAME_X_EMBEDDED_P (f))
  4848     gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
  4849                            "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
  4850 
  4851   /* This defaults to 1 in order to match xterm.  We recognize either
  4852      internalBorderWidth or internalBorder (which is what xterm calls
  4853      it).  */
  4854   if (NILP (Fassq (Qinternal_border_width, parms)))
  4855     {
  4856       Lisp_Object value;
  4857 
  4858       value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width,
  4859                                    "internalBorder", "internalBorder",
  4860                                    RES_TYPE_NUMBER);
  4861       if (! BASE_EQ (value, Qunbound))
  4862         parms = Fcons (Fcons (Qinternal_border_width, value),
  4863                        parms);
  4864     }
  4865 
  4866   gui_default_parameter (f, parms, Qinternal_border_width,
  4867 #ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets.  */
  4868                          make_fixnum (0),
  4869 #else
  4870                          make_fixnum (1),
  4871 #endif
  4872                          "internalBorderWidth", "internalBorderWidth",
  4873                          RES_TYPE_NUMBER);
  4874 
  4875   /* Same for child frames.  */
  4876   if (NILP (Fassq (Qchild_frame_border_width, parms)))
  4877     {
  4878       Lisp_Object value;
  4879 
  4880       value = gui_display_get_arg (dpyinfo, parms, Qchild_frame_border_width,
  4881                                    "childFrameBorder", "childFrameBorder",
  4882                                    RES_TYPE_NUMBER);
  4883       if (! BASE_EQ (value, Qunbound))
  4884         parms = Fcons (Fcons (Qchild_frame_border_width, value),
  4885                        parms);
  4886     }
  4887 
  4888   gui_default_parameter (f, parms, Qchild_frame_border_width, Qnil,
  4889                          "childFrameBorderWidth", "childFrameBorderWidth",
  4890                          RES_TYPE_NUMBER);
  4891   gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
  4892                          NULL, NULL, RES_TYPE_NUMBER);
  4893   gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
  4894                          NULL, NULL, RES_TYPE_NUMBER);
  4895   gui_default_parameter (f, parms, Qvertical_scroll_bars,
  4896 #if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
  4897                          Qright,
  4898 #else
  4899                          Qleft,
  4900 #endif
  4901                          "verticalScrollBars", "ScrollBars",
  4902                          RES_TYPE_SYMBOL);
  4903   gui_default_parameter (f, parms, Qhorizontal_scroll_bars, Qnil,
  4904                          "horizontalScrollBars", "ScrollBars",
  4905                          RES_TYPE_SYMBOL);
  4906   /* Also do the stuff which must be set before the window exists.  */
  4907   gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
  4908                          "foreground", "Foreground", RES_TYPE_STRING);
  4909   gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
  4910                          "background", "Background", RES_TYPE_STRING);
  4911   gui_default_parameter (f, parms, Qmouse_color, build_string ("black"),
  4912                          "pointerColor", "Foreground", RES_TYPE_STRING);
  4913   gui_default_parameter (f, parms, Qborder_color, build_string ("black"),
  4914                          "borderColor", "BorderColor", RES_TYPE_STRING);
  4915   gui_default_parameter (f, parms, Qscreen_gamma, Qnil,
  4916                          "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
  4917   gui_default_parameter (f, parms, Qline_spacing, Qnil,
  4918                          "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
  4919   gui_default_parameter (f, parms, Qleft_fringe, Qnil,
  4920                          "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
  4921   gui_default_parameter (f, parms, Qright_fringe, Qnil,
  4922                          "rightFringe", "RightFringe", RES_TYPE_NUMBER);
  4923   gui_default_parameter (f, parms, Qno_special_glyphs, Qnil,
  4924                          NULL, NULL, RES_TYPE_BOOLEAN);
  4925 
  4926 #ifdef HAVE_GTK3
  4927   FRAME_OUTPUT_DATA (f)->scrollbar_background_css_provider
  4928     = gtk_css_provider_new ();
  4929   FRAME_OUTPUT_DATA (f)->scrollbar_foreground_css_provider
  4930     = gtk_css_provider_new ();
  4931 #endif
  4932 
  4933   x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_foreground,
  4934                                         "scrollBarForeground",
  4935                                         "ScrollBarForeground", true);
  4936   x_default_scroll_bar_color_parameter (f, parms, Qscroll_bar_background,
  4937                                         "scrollBarBackground",
  4938                                         "ScrollBarBackground", false);
  4939 
  4940   /* Init faces before gui_default_parameter is called for the
  4941      scroll-bar-width parameter because otherwise we end up in
  4942      init_iterator with a null face cache, which should not happen.  */
  4943   init_frame_faces (f);
  4944 
  4945   tem = gui_display_get_arg (dpyinfo, parms, Qmin_width, NULL, NULL,
  4946                              RES_TYPE_NUMBER);
  4947   if (FIXNUMP (tem))
  4948     store_frame_param (f, Qmin_width, tem);
  4949   tem = gui_display_get_arg (dpyinfo, parms, Qmin_height, NULL, NULL,
  4950                              RES_TYPE_NUMBER);
  4951   if (FIXNUMP (tem))
  4952     store_frame_param (f, Qmin_height, tem);
  4953 
  4954   adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
  4955                      FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, true,
  4956                      Qx_create_frame_1);
  4957 
  4958   /* Set the menu-bar-lines and tool-bar-lines parameters.  We don't
  4959      look up the X resources controlling the menu-bar and tool-bar
  4960      here; they are processed specially at startup, and reflected in
  4961      the values of the mode variables.  */
  4962 
  4963   gui_default_parameter (f, parms, Qmenu_bar_lines,
  4964                          NILP (Vmenu_bar_mode)
  4965                          ? make_fixnum (0) : make_fixnum (1),
  4966                          NULL, NULL, RES_TYPE_NUMBER);
  4967   gui_default_parameter (f, parms, Qtab_bar_lines,
  4968                          NILP (Vtab_bar_mode)
  4969                          ? make_fixnum (0) : make_fixnum (1),
  4970                          NULL, NULL, RES_TYPE_NUMBER);
  4971   gui_default_parameter (f, parms, Qtool_bar_lines,
  4972                          NILP (Vtool_bar_mode)
  4973                          ? make_fixnum (0) : make_fixnum (1),
  4974                          NULL, NULL, RES_TYPE_NUMBER);
  4975 
  4976   gui_default_parameter (f, parms, Qbuffer_predicate, Qnil,
  4977                          "bufferPredicate", "BufferPredicate",
  4978                          RES_TYPE_SYMBOL);
  4979   gui_default_parameter (f, parms, Qtitle, Qnil,
  4980                          "title", "Title", RES_TYPE_STRING);
  4981   gui_default_parameter (f, parms, Qwait_for_wm, Qt,
  4982                          "waitForWM", "WaitForWM", RES_TYPE_BOOLEAN);
  4983   gui_default_parameter (f, parms, Qtool_bar_position,
  4984                          FRAME_TOOL_BAR_POSITION (f), 0, 0, RES_TYPE_SYMBOL);
  4985   gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
  4986                          "inhibitDoubleBuffering", "InhibitDoubleBuffering",
  4987                          RES_TYPE_BOOLEAN);
  4988 
  4989   /* Compute the size of the X window.  */
  4990   window_prompting = gui_figure_window_size (f, parms, true, true);
  4991 
  4992   tem = gui_display_get_arg (dpyinfo, parms, Qunsplittable, 0, 0,
  4993                              RES_TYPE_BOOLEAN);
  4994   f->no_split = minibuffer_only || EQ (tem, Qt);
  4995 
  4996   x_icon_verify (f, parms);
  4997 
  4998   /* Create the X widget or window.  */
  4999 #ifdef USE_X_TOOLKIT
  5000   x_window (f, window_prompting);
  5001 #else
  5002   x_window (f);
  5003 #endif
  5004 
  5005 #ifndef USE_GTK
  5006   if (FRAME_X_EMBEDDED_P (f)
  5007       && !x_embed_frame (dpyinfo, f))
  5008     error ("The frame could not be embedded; does the embedder exist?");
  5009 #endif
  5010 
  5011   x_icon (f, parms);
  5012   x_make_gc (f);
  5013 
  5014   /* While this function is present in versions of libXi that only
  5015      support 2.0, it does not release the display lock after
  5016      finishing, leading to a deadlock.  */
  5017 #if defined HAVE_XINPUT2 && defined HAVE_XINPUT2_1
  5018   if (dpyinfo->supports_xi2)
  5019     FRAME_X_OUTPUT (f)->xi_masks
  5020       = XIGetSelectedEvents (dpyinfo->display, FRAME_X_WINDOW (f),
  5021                              &FRAME_X_OUTPUT (f)->num_xi_masks);
  5022 #endif
  5023 
  5024   /* Now consider the frame official.  */
  5025   f->terminal->reference_count++;
  5026   FRAME_DISPLAY_INFO (f)->reference_count++;
  5027   Vframe_list = Fcons (frame, Vframe_list);
  5028 
  5029   /* We need to do this after creating the X window, so that the
  5030      icon-creation functions can say whose icon they're describing.  */
  5031   gui_default_parameter (f, parms, Qicon_type, Qt,
  5032                          "bitmapIcon", "BitmapIcon", RES_TYPE_BOOLEAN);
  5033 
  5034   gui_default_parameter (f, parms, Qauto_raise, Qnil,
  5035                          "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
  5036   gui_default_parameter (f, parms, Qauto_lower, Qnil,
  5037                          "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
  5038   gui_default_parameter (f, parms, Qcursor_type, Qbox,
  5039                          "cursorType", "CursorType", RES_TYPE_SYMBOL);
  5040   gui_default_parameter (f, parms, Qscroll_bar_width, Qnil,
  5041                          "scrollBarWidth", "ScrollBarWidth",
  5042                          RES_TYPE_NUMBER);
  5043   gui_default_parameter (f, parms, Qscroll_bar_height, Qnil,
  5044                          "scrollBarHeight", "ScrollBarHeight",
  5045                          RES_TYPE_NUMBER);
  5046   gui_default_parameter (f, parms, Qalpha, Qnil,
  5047                          "alpha", "Alpha", RES_TYPE_NUMBER);
  5048   gui_default_parameter (f, parms, Qalpha_background, Qnil,
  5049                          "alphaBackground", "AlphaBackground", RES_TYPE_NUMBER);
  5050 
  5051   if (!NILP (parent_frame))
  5052     {
  5053       struct frame *p = XFRAME (parent_frame);
  5054 
  5055       block_input ();
  5056       XReparentWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
  5057                        FRAME_X_WINDOW (p), f->left_pos, f->top_pos);
  5058 #ifdef USE_GTK
  5059       if (EQ (x_gtk_resize_child_frames, Qresize_mode))
  5060         gtk_container_set_resize_mode
  5061           (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)), GTK_RESIZE_IMMEDIATE);
  5062 #endif
  5063 #ifdef HAVE_GTK3
  5064       gwin = gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET (f));
  5065       gdk_x11_window_set_frame_sync_enabled (gwin, FALSE);
  5066 #endif
  5067       unblock_input ();
  5068     }
  5069 
  5070   gui_default_parameter (f, parms, Qno_focus_on_map, Qnil,
  5071                          NULL, NULL, RES_TYPE_BOOLEAN);
  5072   gui_default_parameter (f, parms, Qno_accept_focus, Qnil,
  5073                          NULL, NULL, RES_TYPE_BOOLEAN);
  5074 
  5075 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
  5076   /* Create the menu bar.  */
  5077   if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
  5078     {
  5079       /* If this signals an error, we haven't set size hints for the
  5080          frame and we didn't make it visible.  */
  5081       initialize_frame_menubar (f);
  5082 
  5083 #ifndef USE_GTK
  5084       /* This is a no-op, except under Motif where it arranges the
  5085          main window for the widgets on it.  */
  5086       lw_set_main_areas (f->output_data.x->column_widget,
  5087                          f->output_data.x->menubar_widget,
  5088                          f->output_data.x->edit_widget);
  5089 #endif /* not USE_GTK */
  5090     }
  5091 #endif /* USE_X_TOOLKIT || USE_GTK */
  5092 
  5093   /* Consider frame official, now.  */
  5094   f->can_set_window_size = true;
  5095 
  5096   /* Tell the server what size and position, etc, we want, and how
  5097      badly we want them.  This should be done after we have the menu
  5098      bar so that its size can be taken into account.  */
  5099   block_input ();
  5100   x_wm_set_size_hint (f, window_prompting, false);
  5101   unblock_input ();
  5102 
  5103   adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
  5104                      0, true, Qx_create_frame_2);
  5105 
  5106   /* Process fullscreen parameter here in the hope that normalizing a
  5107      fullheight/fullwidth frame will produce the size set by the last
  5108      adjust_frame_size call.  */
  5109   gui_default_parameter (f, parms, Qfullscreen, Qnil,
  5110                          "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
  5111 
  5112 #ifdef USE_CAIRO
  5113   /* Set the initial size of the Cairo surface to the frame's current
  5114      width and height.  If the window manager doesn't resize the new
  5115      frame after it's first mapped, Emacs will create a surface with
  5116      empty dimensions in response to to the initial exposure event,
  5117      which will persist until the next time it's resized.
  5118      (bug#64923) */
  5119   x_cr_update_surface_desired_size (f, FRAME_PIXEL_WIDTH (f),
  5120                                     FRAME_PIXEL_HEIGHT (f));
  5121 #endif /* USE_CAIRO */
  5122 
  5123   /* Make the window appear on the frame and enable display, unless
  5124      the caller says not to.  However, with explicit parent, Emacs
  5125      cannot control visibility, so don't try.  */
  5126   if (!f->output_data.x->explicit_parent)
  5127     {
  5128       /* When called from `x-create-frame-with-faces' visibility is
  5129          always explicitly nil.  */
  5130       Lisp_Object visibility
  5131         = gui_display_get_arg (dpyinfo, parms, Qvisibility, 0, 0,
  5132                                RES_TYPE_SYMBOL);
  5133       Lisp_Object height
  5134         = gui_display_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
  5135       Lisp_Object width
  5136         = gui_display_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
  5137 
  5138       if (EQ (visibility, Qicon))
  5139         {
  5140           f->was_invisible = true;
  5141           x_iconify_frame (f);
  5142         }
  5143       else
  5144         {
  5145           if (BASE_EQ (visibility, Qunbound))
  5146             visibility = Qt;
  5147 
  5148           if (!NILP (visibility))
  5149             x_make_frame_visible (f);
  5150           else
  5151             f->was_invisible = true;
  5152         }
  5153 
  5154       /* Leave f->was_invisible true only if height or width were
  5155          specified too.  This takes effect only when we are not called
  5156          from `x-create-frame-with-faces' (see above comment).  */
  5157       f->was_invisible
  5158         = (f->was_invisible
  5159            && (!BASE_EQ (height, Qunbound) || !BASE_EQ (width, Qunbound)));
  5160 
  5161       store_frame_param (f, Qvisibility, visibility);
  5162     }
  5163 
  5164   block_input ();
  5165 
  5166   /* Set machine name and pid for the purpose of window managers.  */
  5167   set_machine_and_pid_properties (f);
  5168 
  5169   /* Set the WM leader property.  GTK does this itself, so this is not
  5170      needed when using GTK.  */
  5171   if (dpyinfo->client_leader_window != 0)
  5172     {
  5173       XChangeProperty (FRAME_X_DISPLAY (f),
  5174                        FRAME_OUTER_WINDOW (f),
  5175                        dpyinfo->Xatom_wm_client_leader,
  5176                        XA_WINDOW, 32, PropModeReplace,
  5177                        (unsigned char *) &dpyinfo->client_leader_window, 1);
  5178     }
  5179 
  5180 #ifdef HAVE_XSYNC
  5181   if (dpyinfo->xsync_supported_p
  5182       /* Frame synchronization isn't supported in child frames.  */
  5183       && NILP (parent_frame)
  5184       && !f->output_data.x->explicit_parent)
  5185     {
  5186 #ifndef HAVE_GTK3
  5187       XSyncValue initial_value;
  5188       XSyncCounter counters[2];
  5189 
  5190       AUTO_STRING (synchronizeResize, "synchronizeResize");
  5191       AUTO_STRING (SynchronizeResize, "SynchronizeResize");
  5192 
  5193       Lisp_Object value = gui_display_get_resource (dpyinfo,
  5194                                                     synchronizeResize,
  5195                                                     SynchronizeResize,
  5196                                                     Qnil, Qnil);
  5197 
  5198       XSyncIntToValue (&initial_value, 0);
  5199       counters[0]
  5200         = FRAME_X_BASIC_COUNTER (f)
  5201         = XSyncCreateCounter (FRAME_X_DISPLAY (f),
  5202                               initial_value);
  5203 
  5204       if (STRINGP (value) && !strcmp (SSDATA (value), "extended"))
  5205         counters[1]
  5206           = FRAME_X_EXTENDED_COUNTER (f)
  5207           = XSyncCreateCounter (FRAME_X_DISPLAY (f),
  5208                                 initial_value);
  5209 
  5210       FRAME_X_OUTPUT (f)->current_extended_counter_value
  5211         = initial_value;
  5212 
  5213       XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
  5214                        dpyinfo->Xatom_net_wm_sync_request_counter,
  5215                        XA_CARDINAL, 32, PropModeReplace,
  5216                        (unsigned char *) &counters,
  5217                        ((STRINGP (value)
  5218                          && !strcmp (SSDATA (value), "extended")) ? 2 : 1));
  5219 
  5220 #if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK \
  5221   && defined HAVE_CLOCK_GETTIME
  5222       x_sync_init_fences (f);
  5223 #endif
  5224 #endif
  5225     }
  5226 #endif
  5227 
  5228   unblock_input ();
  5229 
  5230   /* Set whether or not frame synchronization is enabled.  */
  5231   gui_default_parameter (f, parms, Quse_frame_synchronization, Qt,
  5232                          NULL, NULL, RES_TYPE_BOOLEAN);
  5233 
  5234   /* Works iff frame has been already mapped.  */
  5235   gui_default_parameter (f, parms, Qskip_taskbar, Qnil,
  5236                          NULL, NULL, RES_TYPE_BOOLEAN);
  5237   /* The `z-group' parameter works only for visible frames.  */
  5238   gui_default_parameter (f, parms, Qz_group, Qnil,
  5239                          NULL, NULL, RES_TYPE_SYMBOL);
  5240 
  5241   /* Initialize `default-minibuffer-frame' in case this is the first
  5242      frame on this terminal.  */
  5243   if (FRAME_HAS_MINIBUF_P (f)
  5244       && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
  5245           || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
  5246     kset_default_minibuffer_frame (kb, frame);
  5247 
  5248   /* All remaining specified parameters, which have not been "used" by
  5249      gui_display_get_arg and friends, now go in the misc. alist of the
  5250      frame.  */
  5251   for (tem = parms; CONSP (tem); tem = XCDR (tem))
  5252     if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
  5253       fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
  5254 
  5255   /* Make sure windows on this frame appear in calls to next-window
  5256      and similar functions.  */
  5257   Vwindow_list = Qnil;
  5258 
  5259  return unbind_to (count, frame);
  5260 }
  5261 
  5262 
  5263 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
  5264        doc: /* Internal function called by `color-defined-p'.
  5265 \(Note that the Nextstep version of this function ignores FRAME.)  */)
  5266   (Lisp_Object color, Lisp_Object frame)
  5267 {
  5268   XColor foo;
  5269   struct frame *f = decode_window_system_frame (frame);
  5270 
  5271   CHECK_STRING (color);
  5272 
  5273   if (x_defined_color (f, SSDATA (color), &foo, false, false))
  5274     return Qt;
  5275   else
  5276     return Qnil;
  5277 }
  5278 
  5279 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
  5280        doc: /* Internal function called by `color-values'.
  5281 \(Note that the Nextstep version of this function ignores FRAME.)  */)
  5282   (Lisp_Object color, Lisp_Object frame)
  5283 {
  5284   XColor foo;
  5285   struct frame *f = decode_window_system_frame (frame);
  5286 
  5287   CHECK_STRING (color);
  5288 
  5289   if (x_defined_color (f, SSDATA (color), &foo, false, false))
  5290     return list3i (foo.red, foo.green, foo.blue);
  5291   else
  5292     return Qnil;
  5293 }
  5294 
  5295 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
  5296        doc: /* Internal function called by `display-color-p'.  */)
  5297   (Lisp_Object terminal)
  5298 {
  5299   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5300 
  5301   if (dpyinfo->n_planes <= 2)
  5302     return Qnil;
  5303 
  5304   switch (dpyinfo->visual_info.class)
  5305     {
  5306     case StaticColor:
  5307     case PseudoColor:
  5308     case TrueColor:
  5309     case DirectColor:
  5310       return Qt;
  5311 
  5312     default:
  5313       return Qnil;
  5314     }
  5315 }
  5316 
  5317 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
  5318        0, 1, 0,
  5319        doc: /* Return t if the X display supports shades of gray.
  5320 Note that color displays do support shades of gray.
  5321 The optional argument TERMINAL specifies which display to ask about.
  5322 TERMINAL should be a terminal object, a frame or a display name (a string).
  5323 If omitted or nil, that stands for the selected frame's display.  */)
  5324   (Lisp_Object terminal)
  5325 {
  5326   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5327 
  5328   if (dpyinfo->n_planes <= 1)
  5329     return Qnil;
  5330 
  5331   switch (dpyinfo->visual_info.class)
  5332     {
  5333     case StaticColor:
  5334     case PseudoColor:
  5335     case TrueColor:
  5336     case DirectColor:
  5337     case StaticGray:
  5338     case GrayScale:
  5339       return Qt;
  5340 
  5341     default:
  5342       return Qnil;
  5343     }
  5344 }
  5345 
  5346 DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
  5347        0, 1, 0,
  5348        doc: /* Return the width in pixels of the X display TERMINAL.
  5349 The optional argument TERMINAL specifies which display to ask about.
  5350 TERMINAL should be a terminal object, a frame or a display name (a string).
  5351 If omitted or nil, that stands for the selected frame's display.
  5352 \(On MS Windows, this function does not accept terminal objects.)
  5353 
  5354 On \"multi-monitor\" setups this refers to the pixel width for all
  5355 physical monitors associated with TERMINAL.  To get information for
  5356 each physical monitor, use `display-monitor-attributes-list'.  */)
  5357   (Lisp_Object terminal)
  5358 {
  5359   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5360 
  5361   return make_fixnum (x_display_pixel_width (dpyinfo));
  5362 }
  5363 
  5364 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
  5365        Sx_display_pixel_height, 0, 1, 0,
  5366        doc: /* Return the height in pixels of the X display TERMINAL.
  5367 The optional argument TERMINAL specifies which display to ask about.
  5368 TERMINAL should be a terminal object, a frame or a display name (a string).
  5369 If omitted or nil, that stands for the selected frame's display.
  5370 \(On MS Windows, this function does not accept terminal objects.)
  5371 
  5372 On \"multi-monitor\" setups this refers to the pixel height for all
  5373 physical monitors associated with TERMINAL.  To get information for
  5374 each physical monitor, use `display-monitor-attributes-list'.  */)
  5375   (Lisp_Object terminal)
  5376 {
  5377   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5378 
  5379   return make_fixnum (x_display_pixel_height (dpyinfo));
  5380 }
  5381 
  5382 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
  5383        0, 1, 0,
  5384        doc: /* Return the number of bitplanes of the X display TERMINAL.
  5385 The optional argument TERMINAL specifies which display to ask about.
  5386 TERMINAL should be a terminal object, a frame or a display name (a string).
  5387 If omitted or nil, that stands for the selected frame's display.
  5388 \(On MS Windows, this function does not accept terminal objects.)  */)
  5389   (Lisp_Object terminal)
  5390 {
  5391   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5392 
  5393   return make_fixnum (dpyinfo->n_planes);
  5394 }
  5395 
  5396 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
  5397        0, 1, 0,
  5398        doc: /* Return the number of color cells of the X display TERMINAL.
  5399 The optional argument TERMINAL specifies which display to ask about.
  5400 TERMINAL should be a terminal object, a frame or a display name (a string).
  5401 If omitted or nil, that stands for the selected frame's display.
  5402 \(On MS Windows, this function does not accept terminal objects.)  */)
  5403   (Lisp_Object terminal)
  5404 {
  5405   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5406 
  5407   if (dpyinfo->visual_info.class != TrueColor
  5408       && dpyinfo->visual_info.class != DirectColor)
  5409     return make_fixnum (dpyinfo->visual_info.colormap_size);
  5410 
  5411   int nr_planes = dpyinfo->n_planes;
  5412 
  5413   /* Truncate nr_planes to 24 to avoid integer overflow.  Some
  5414      displays says 32, but only 24 bits are actually significant.
  5415      There are only very few and rare video cards that have more than
  5416      24 significant bits.  Also 24 bits is more than 16 million
  5417      colors, it "should be enough for everyone".  */
  5418   if (nr_planes > 24) nr_planes = 24;
  5419 
  5420   return make_fixnum (1 << nr_planes);
  5421 }
  5422 
  5423 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
  5424        Sx_server_max_request_size,
  5425        0, 1, 0,
  5426        doc: /* Return the maximum request size of the X server of display TERMINAL.
  5427 The optional argument TERMINAL specifies which display to ask about.
  5428 TERMINAL should be a terminal object, a frame or a display name (a string).
  5429 If omitted or nil, that stands for the selected frame's display.
  5430 
  5431 On MS Windows, this function just returns 1.
  5432 On Nextstep, this function just returns nil.  */)
  5433   (Lisp_Object terminal)
  5434 {
  5435   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5436 
  5437   return make_fixnum (MAXREQUEST (dpyinfo->display));
  5438 }
  5439 
  5440 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
  5441        doc: /* Return the "vendor ID" string of the GUI software on TERMINAL.
  5442 
  5443 \(Labeling every distributor as a "vendor" embodies the false assumption
  5444 that operating systems cannot be developed and distributed noncommercially.)
  5445 The optional argument TERMINAL specifies which display to ask about.
  5446 
  5447 For GNU and Unix systems, this queries the X server software.
  5448 For MS Windows and Nextstep the result is hard-coded.
  5449 
  5450 TERMINAL should be a terminal object, a frame or a display name (a string).
  5451 If omitted or nil, that stands for the selected frame's display.  */)
  5452   (Lisp_Object terminal)
  5453 {
  5454   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5455   const char *vendor = ServerVendor (dpyinfo->display);
  5456 
  5457   if (! vendor) vendor = "";
  5458   return build_string (vendor);
  5459 }
  5460 
  5461 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
  5462        doc: /* Return the version numbers of the GUI software on TERMINAL.
  5463 The value is a list of three integers specifying the version of the GUI
  5464 software in use.
  5465 
  5466 For GNU and Unix system, the first 2 numbers are the version of the X
  5467 Protocol used on TERMINAL and the 3rd number is the distributor-specific
  5468 release number.  For MS Windows, the 3 numbers report the OS major and
  5469 minor version and build number.  For Nextstep, the first 2 numbers are
  5470 hard-coded and the 3rd represents the OS version.  For Haiku, all 3
  5471 numbers are hard-coded.
  5472 
  5473 See also the function `x-server-vendor'.
  5474 
  5475 The optional argument TERMINAL specifies which display to ask about.
  5476 TERMINAL should be a terminal object, a frame or a display name (a string).
  5477 If omitted or nil, that stands for the selected frame's display.  */)
  5478   (Lisp_Object terminal)
  5479 {
  5480   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5481   Display *dpy = dpyinfo->display;
  5482 
  5483   return list3i (ProtocolVersion (dpy), ProtocolRevision (dpy),
  5484                  VendorRelease (dpy));
  5485 }
  5486 
  5487 DEFUN ("x-server-input-extension-version", Fx_server_input_extension_version,
  5488        Sx_server_input_extension_version, 0, 1, 0,
  5489        doc: /* Return the version of the X Input Extension supported by TERMINAL.
  5490 The value is nil if TERMINAL's X server doesn't support the X Input
  5491 Extension extension, or if Emacs doesn't support the version present
  5492 on that server.  Otherwise, the return value is a list of the major
  5493 and minor versions of the X Input Extension extension running on that
  5494 server.  */)
  5495   (Lisp_Object terminal)
  5496 {
  5497 #ifdef HAVE_XINPUT2
  5498   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5499 
  5500   return (dpyinfo->supports_xi2
  5501           ? list2i (2, dpyinfo->xi2_version)
  5502           : Qnil);
  5503 #else
  5504   return Qnil;
  5505 #endif
  5506 }
  5507 
  5508 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
  5509        doc: /* Return the number of screens on the X server of display TERMINAL.
  5510 The optional argument TERMINAL specifies which display to ask about.
  5511 TERMINAL should be a terminal object, a frame or a display name (a string).
  5512 If omitted or nil, that stands for the selected frame's display.
  5513 
  5514 On MS Windows, this function just returns 1.
  5515 On Nextstep, "screen" is in X terminology, not that of Nextstep.
  5516 For the number of physical monitors, use `(length
  5517 \(display-monitor-attributes-list TERMINAL))' instead.  */)
  5518   (Lisp_Object terminal)
  5519 {
  5520   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5521 
  5522   return make_fixnum (ScreenCount (dpyinfo->display));
  5523 }
  5524 
  5525 DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
  5526        doc: /* Return the height in millimeters of the X display TERMINAL.
  5527 The optional argument TERMINAL specifies which display to ask about.
  5528 TERMINAL should be a terminal object, a frame or a display name (a string).
  5529 If omitted or nil, that stands for the selected frame's display.
  5530 \(On MS Windows, this function does not accept terminal objects.)
  5531 
  5532 On \"multi-monitor\" setups this refers to the height in millimeters for
  5533 all physical monitors associated with TERMINAL.  To get information
  5534 for each physical monitor, use `display-monitor-attributes-list'.  */)
  5535   (Lisp_Object terminal)
  5536 {
  5537   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5538 
  5539   if (dpyinfo->screen_mm_height)
  5540     return make_fixnum (dpyinfo->screen_mm_height);
  5541 
  5542   return make_fixnum (HeightMMOfScreen (dpyinfo->screen));
  5543 }
  5544 
  5545 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
  5546        doc: /* Return the width in millimeters of the X display TERMINAL.
  5547 The optional argument TERMINAL specifies which display to ask about.
  5548 TERMINAL should be a terminal object, a frame or a display name (a string).
  5549 If omitted or nil, that stands for the selected frame's display.
  5550 \(On MS Windows, this function does not accept terminal objects.)
  5551 
  5552 On \"multi-monitor\" setups this refers to the width in millimeters for
  5553 all physical monitors associated with TERMINAL.  To get information
  5554 for each physical monitor, use `display-monitor-attributes-list'.  */)
  5555   (Lisp_Object terminal)
  5556 {
  5557   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5558 
  5559   if (dpyinfo->screen_mm_width)
  5560     return make_fixnum (dpyinfo->screen_mm_width);
  5561 
  5562   return make_fixnum (WidthMMOfScreen (dpyinfo->screen));
  5563 }
  5564 
  5565 DEFUN ("x-display-backing-store", Fx_display_backing_store,
  5566        Sx_display_backing_store, 0, 1, 0,
  5567        doc: /* Return an indication of whether X display TERMINAL does backing store.
  5568 The optional argument TERMINAL specifies which display to ask about.
  5569 TERMINAL should be a terminal object, a frame or a display name (a string).
  5570 If omitted or nil, that stands for the selected frame's display.
  5571 
  5572 The value may be `always', `when-mapped', or `not-useful'.
  5573 On Nextstep, the value may be `buffered', `retained', or `non-retained'.
  5574 On MS Windows, this returns nothing useful.  */)
  5575   (Lisp_Object terminal)
  5576 {
  5577   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5578   Lisp_Object result;
  5579 
  5580   switch (DoesBackingStore (dpyinfo->screen))
  5581     {
  5582     case Always:
  5583       result = Qalways;
  5584       break;
  5585 
  5586     case WhenMapped:
  5587       result = Qwhen_mapped;
  5588       break;
  5589 
  5590     case NotUseful:
  5591       result = Qnot_useful;
  5592       break;
  5593 
  5594     default:
  5595       error ("Strange value for BackingStore parameter of screen");
  5596     }
  5597 
  5598   return result;
  5599 }
  5600 
  5601 DEFUN ("x-display-visual-class", Fx_display_visual_class,
  5602        Sx_display_visual_class, 0, 1, 0,
  5603        doc: /* Return the visual class of the X display TERMINAL.
  5604 The value is one of the symbols `static-gray', `gray-scale',
  5605 `static-color', `pseudo-color', `true-color', or `direct-color'.
  5606 \(On MS Windows, the second and last result above are not possible.)
  5607 
  5608 The optional argument TERMINAL specifies which display to ask about.
  5609 TERMINAL should a terminal object, a frame or a display name (a string).
  5610 If omitted or nil, that stands for the selected frame's display.
  5611 \(On MS Windows, this function does not accept terminal objects.)  */)
  5612   (Lisp_Object terminal)
  5613 {
  5614   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5615   Lisp_Object result;
  5616 
  5617   switch (dpyinfo->visual_info.class)
  5618     {
  5619     case StaticGray:
  5620       result = Qstatic_gray;
  5621       break;
  5622     case GrayScale:
  5623       result = Qgray_scale;
  5624       break;
  5625     case StaticColor:
  5626       result = Qstatic_color;
  5627       break;
  5628     case PseudoColor:
  5629       result = Qpseudo_color;
  5630       break;
  5631     case TrueColor:
  5632       result = Qtrue_color;
  5633       break;
  5634     case DirectColor:
  5635       result = Qdirect_color;
  5636       break;
  5637     default:
  5638       error ("Display has an unknown visual class");
  5639     }
  5640 
  5641   return result;
  5642 }
  5643 
  5644 DEFUN ("x-display-save-under", Fx_display_save_under,
  5645        Sx_display_save_under, 0, 1, 0,
  5646        doc: /* Return t if the X display TERMINAL supports the save-under feature.
  5647 The optional argument TERMINAL specifies which display to ask about.
  5648 TERMINAL should be a terminal object, a frame or a display name (a string).
  5649 If omitted or nil, that stands for the selected frame's display.
  5650 
  5651 On MS Windows, this just returns nil.  */)
  5652   (Lisp_Object terminal)
  5653 {
  5654   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  5655 
  5656   if (DoesSaveUnders (dpyinfo->screen) == True)
  5657     return Qt;
  5658   else
  5659     return Qnil;
  5660 }
  5661 
  5662 #if !(defined USE_GTK && defined HAVE_GTK3)
  5663 
  5664 /* Store the geometry of the workarea on display DPYINFO into *RECT.
  5665    Return false if and only if the workarea information cannot be
  5666    obtained via the _NET_WORKAREA root window property.  */
  5667 
  5668 static bool
  5669 x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect)
  5670 {
  5671 #ifndef USE_XCB
  5672   Display *dpy = dpyinfo->display;
  5673   long offset, max_len;
  5674   Atom target_type, actual_type;
  5675   unsigned long actual_size, bytes_remaining;
  5676   int rc, actual_format;
  5677   unsigned char *tmp_data = NULL;
  5678   bool result = false;
  5679 
  5680   x_catch_errors (dpy);
  5681   offset = 0;
  5682   max_len = 1;
  5683   target_type = XA_CARDINAL;
  5684   rc = XGetWindowProperty (dpy, dpyinfo->root_window,
  5685                            dpyinfo->Xatom_net_current_desktop,
  5686                            offset, max_len, False, target_type,
  5687                            &actual_type, &actual_format, &actual_size,
  5688                            &bytes_remaining, &tmp_data);
  5689   if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
  5690       && actual_format == 32 && actual_size == max_len)
  5691     {
  5692       long current_desktop = ((long *) tmp_data)[0];
  5693 
  5694       XFree (tmp_data);
  5695       tmp_data = NULL;
  5696 
  5697       offset = 4 * current_desktop;
  5698       max_len = 4;
  5699       rc = XGetWindowProperty (dpy, dpyinfo->root_window,
  5700                                dpyinfo->Xatom_net_workarea,
  5701                                offset, max_len, False, target_type,
  5702                                &actual_type, &actual_format, &actual_size,
  5703                                &bytes_remaining, &tmp_data);
  5704       if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
  5705           && actual_format == 32 && actual_size == max_len)
  5706         {
  5707           long *values = (long *) tmp_data;
  5708 
  5709           rect->x = values[0];
  5710           rect->y = values[1];
  5711           rect->width = values[2];
  5712           rect->height = values[3];
  5713 
  5714           XFree (tmp_data);
  5715           tmp_data = NULL;
  5716 
  5717           result = true;
  5718         }
  5719     }
  5720   if (tmp_data)
  5721     XFree (tmp_data);
  5722   x_uncatch_errors ();
  5723 
  5724   return result;
  5725 #else
  5726   xcb_get_property_cookie_t current_desktop_cookie;
  5727   xcb_get_property_cookie_t workarea_cookie;
  5728   xcb_get_property_reply_t *reply;
  5729   xcb_generic_error_t *error;
  5730   bool rc;
  5731   uint32_t current_workspace, *values;
  5732 
  5733   current_desktop_cookie
  5734     = xcb_get_property (dpyinfo->xcb_connection, 0,
  5735                         (xcb_window_t) dpyinfo->root_window,
  5736                         (xcb_atom_t) dpyinfo->Xatom_net_current_desktop,
  5737                         XCB_ATOM_CARDINAL, 0, 1);
  5738 
  5739   workarea_cookie
  5740     = xcb_get_property (dpyinfo->xcb_connection, 0,
  5741                         (xcb_window_t) dpyinfo->root_window,
  5742                         (xcb_atom_t) dpyinfo->Xatom_net_workarea,
  5743                         XCB_ATOM_CARDINAL, 0, UINT32_MAX);
  5744 
  5745   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  5746                                   current_desktop_cookie, &error);
  5747   rc = true;
  5748 
  5749   if (!reply)
  5750     free (error), rc = false;
  5751   else
  5752     {
  5753       if (xcb_get_property_value_length (reply) != 4
  5754           || reply->type != XCB_ATOM_CARDINAL || reply->format != 32)
  5755         rc = false;
  5756       else
  5757         current_workspace = *(uint32_t *) xcb_get_property_value (reply);
  5758 
  5759       free (reply);
  5760     }
  5761 
  5762   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  5763                                   workarea_cookie, &error);
  5764 
  5765   if (!reply)
  5766     free (error), rc = false;
  5767   else
  5768     {
  5769       if (rc && reply->type == XCB_ATOM_CARDINAL && reply->format == 32
  5770           && (xcb_get_property_value_length (reply) / sizeof (uint32_t)
  5771               >= current_workspace + 4))
  5772         {
  5773           values = xcb_get_property_value (reply);
  5774 
  5775           rect->x = values[current_workspace];
  5776           rect->y = values[current_workspace + 1];
  5777           rect->width = values[current_workspace + 2];
  5778           rect->height = values[current_workspace + 3];
  5779         }
  5780       else
  5781         rc = false;
  5782 
  5783       free (reply);
  5784     }
  5785 
  5786   return rc;
  5787 #endif
  5788 }
  5789 #endif /* !(USE_GTK && HAVE_GTK3) */
  5790 
  5791 #ifndef USE_GTK
  5792 
  5793 /* Return monitor number where F is "most" or closest to.  */
  5794 static int
  5795 x_get_monitor_for_frame (struct frame *f,
  5796                          struct MonitorInfo *monitors,
  5797                          int n_monitors)
  5798 {
  5799   XRectangle frect;
  5800   int area = 0, dist = -1;
  5801   int best_area = -1, best_dist = -1;
  5802   int i;
  5803 
  5804   if (n_monitors == 1) return 0;
  5805   frect.x = f->left_pos;
  5806   frect.y = f->top_pos;
  5807   frect.width = FRAME_PIXEL_WIDTH (f);
  5808   frect.height = FRAME_PIXEL_HEIGHT (f);
  5809 
  5810   for (i = 0; i < n_monitors; ++i)
  5811     {
  5812       struct MonitorInfo *mi = &monitors[i];
  5813       XRectangle res;
  5814       int a = 0;
  5815 
  5816       if (mi->geom.width == 0) continue;
  5817 
  5818       if (gui_intersect_rectangles (&mi->geom, &frect, &res))
  5819         {
  5820           a = res.width * res.height;
  5821           if (a > area)
  5822             {
  5823               area = a;
  5824               best_area = i;
  5825             }
  5826         }
  5827 
  5828       if (a == 0 && area == 0)
  5829         {
  5830           int dx, dy, d;
  5831           if (frect.x + frect.width < mi->geom.x)
  5832             dx = mi->geom.x - frect.x + frect.width;
  5833           else if (frect.x > mi->geom.x + mi->geom.width)
  5834             dx = frect.x - mi->geom.x + mi->geom.width;
  5835           else
  5836             dx = 0;
  5837           if (frect.y + frect.height < mi->geom.y)
  5838             dy = mi->geom.y - frect.y + frect.height;
  5839           else if (frect.y > mi->geom.y + mi->geom.height)
  5840             dy = frect.y - mi->geom.y + mi->geom.height;
  5841           else
  5842             dy = 0;
  5843 
  5844           d = dx*dx + dy*dy;
  5845           if (dist == -1 || dist > d)
  5846             {
  5847               dist = d;
  5848               best_dist = i;
  5849             }
  5850         }
  5851     }
  5852 
  5853   return best_area != -1 ? best_area : (best_dist != -1 ? best_dist : 0);
  5854 }
  5855 
  5856 static Lisp_Object
  5857 x_make_monitor_attribute_list (struct MonitorInfo *monitors,
  5858                                int n_monitors,
  5859                                int primary_monitor,
  5860                                struct x_display_info *dpyinfo,
  5861                                const char *source)
  5862 {
  5863   Lisp_Object monitor_frames = make_nil_vector (n_monitors);
  5864   Lisp_Object frame, rest;
  5865 
  5866   FOR_EACH_FRAME (rest, frame)
  5867     {
  5868       struct frame *f = XFRAME (frame);
  5869 
  5870       if (FRAME_X_P (f)
  5871           && FRAME_DISPLAY_INFO (f) == dpyinfo
  5872           && !FRAME_TOOLTIP_P (f))
  5873         {
  5874           int i = x_get_monitor_for_frame (f, monitors, n_monitors);
  5875           ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
  5876         }
  5877     }
  5878 
  5879   return make_monitor_attribute_list (monitors, n_monitors, primary_monitor,
  5880                                       monitor_frames, source);
  5881 }
  5882 
  5883 static Lisp_Object
  5884 x_get_monitor_attributes_fallback (struct x_display_info *dpyinfo)
  5885 {
  5886   struct MonitorInfo monitor;
  5887   XRectangle workarea_r;
  5888 
  5889   /* Fallback: treat (possibly) multiple physical monitors as if they
  5890      formed a single monitor as a whole.  This should provide a
  5891      consistent result at least on single monitor environments.  */
  5892   monitor.geom.x = monitor.geom.y = 0;
  5893   monitor.geom.width = x_display_pixel_width (dpyinfo);
  5894   monitor.geom.height = x_display_pixel_height (dpyinfo);
  5895   monitor.mm_width = WidthMMOfScreen (dpyinfo->screen);
  5896   monitor.mm_height = HeightMMOfScreen (dpyinfo->screen);
  5897   monitor.name = xstrdup ("combined screen");
  5898 
  5899   if (x_get_net_workarea (dpyinfo, &workarea_r))
  5900     monitor.work = workarea_r;
  5901   else
  5902     monitor.work = monitor.geom;
  5903   return x_make_monitor_attribute_list (&monitor, 1, 0, dpyinfo, "fallback");
  5904 }
  5905 
  5906 
  5907 #ifdef HAVE_XINERAMA
  5908 static Lisp_Object
  5909 x_get_monitor_attributes_xinerama (struct x_display_info *dpyinfo)
  5910 {
  5911   int n_monitors, i;
  5912   Lisp_Object attributes_list = Qnil;
  5913   Display *dpy = dpyinfo->display;
  5914   XineramaScreenInfo *info = XineramaQueryScreens (dpy, &n_monitors);
  5915   struct MonitorInfo *monitors;
  5916   double mm_width_per_pixel, mm_height_per_pixel;
  5917 
  5918   if (! info || n_monitors == 0)
  5919     {
  5920       if (info)
  5921         XFree (info);
  5922       return attributes_list;
  5923     }
  5924 
  5925   mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
  5926                         / x_display_pixel_width (dpyinfo));
  5927   mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
  5928                          / x_display_pixel_height (dpyinfo));
  5929   monitors = xzalloc (n_monitors * sizeof *monitors);
  5930   for (i = 0; i < n_monitors; ++i)
  5931     {
  5932       struct MonitorInfo *mi = &monitors[i];
  5933       XRectangle workarea_r;
  5934 
  5935       mi->geom.x = info[i].x_org;
  5936       mi->geom.y = info[i].y_org;
  5937       mi->geom.width = info[i].width;
  5938       mi->geom.height = info[i].height;
  5939       mi->mm_width = mi->geom.width * mm_width_per_pixel + 0.5;
  5940       mi->mm_height = mi->geom.height * mm_height_per_pixel + 0.5;
  5941       mi->name = 0;
  5942 
  5943       /* Xinerama usually have primary monitor first, just use that.  */
  5944       if (i == 0 && x_get_net_workarea (dpyinfo, &workarea_r))
  5945         {
  5946           mi->work = workarea_r;
  5947           if (! gui_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
  5948             mi->work = mi->geom;
  5949         }
  5950       else
  5951         mi->work = mi->geom;
  5952     }
  5953   XFree (info);
  5954 
  5955   attributes_list = x_make_monitor_attribute_list (monitors,
  5956                                                    n_monitors,
  5957                                                    0,
  5958                                                    dpyinfo,
  5959                                                    "Xinerama");
  5960   free_monitors (monitors, n_monitors);
  5961   return attributes_list;
  5962 }
  5963 #endif /* HAVE_XINERAMA */
  5964 
  5965 
  5966 #ifdef HAVE_XRANDR
  5967 static Lisp_Object
  5968 x_get_monitor_attributes_xrandr (struct x_display_info *dpyinfo)
  5969 {
  5970   Lisp_Object attributes_list = Qnil;
  5971   XRRScreenResources *resources;
  5972   Display *dpy = dpyinfo->display;
  5973   int i, n_monitors, primary = -1;
  5974   RROutput pxid = None;
  5975   struct MonitorInfo *monitors;
  5976   bool randr15_p = false;
  5977 
  5978 #if RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 5)
  5979   XRRMonitorInfo *rr_monitors;
  5980 #ifdef USE_XCB
  5981   xcb_get_atom_name_cookie_t *atom_name_cookies;
  5982   xcb_get_atom_name_reply_t *reply;
  5983   xcb_generic_error_t *error;
  5984   int length;
  5985 #endif
  5986 
  5987   /* If RandR 1.5 or later is available, use that instead, as some
  5988      video drivers don't report correct dimensions via other versions
  5989      of RandR.  */
  5990   if (dpyinfo->xrandr_major_version > 1
  5991       || (dpyinfo->xrandr_major_version == 1
  5992           && dpyinfo->xrandr_minor_version >= 5))
  5993     {
  5994       XRectangle workarea;
  5995       char *name;
  5996 
  5997       rr_monitors = XRRGetMonitors (dpyinfo->display,
  5998                                     dpyinfo->root_window,
  5999                                     True, &n_monitors);
  6000       if (!rr_monitors)
  6001         goto fallback;
  6002 
  6003       monitors = xzalloc (n_monitors * sizeof *monitors);
  6004 #ifdef USE_XCB
  6005       atom_name_cookies = alloca (n_monitors * sizeof *atom_name_cookies);
  6006 #endif
  6007 
  6008       for (int i = 0; i < n_monitors; ++i)
  6009         {
  6010           monitors[i].geom.x = rr_monitors[i].x;
  6011           monitors[i].geom.y = rr_monitors[i].y;
  6012           monitors[i].geom.width = rr_monitors[i].width;
  6013           monitors[i].geom.height = rr_monitors[i].height;
  6014           monitors[i].mm_width = rr_monitors[i].mwidth;
  6015           monitors[i].mm_height = rr_monitors[i].mheight;
  6016 
  6017 #ifndef USE_XCB
  6018           name = XGetAtomName (dpyinfo->display, rr_monitors[i].name);
  6019           if (name)
  6020             {
  6021               monitors[i].name = xstrdup (name);
  6022               XFree (name);
  6023             }
  6024           else
  6025             monitors[i].name = xstrdup ("Unknown Monitor");
  6026 #else
  6027           atom_name_cookies[i]
  6028             = xcb_get_atom_name (dpyinfo->xcb_connection,
  6029                                  (xcb_atom_t) rr_monitors[i].name);
  6030 #endif
  6031 
  6032           if (rr_monitors[i].primary)
  6033             primary = i;
  6034 
  6035           if (rr_monitors[i].primary
  6036               && x_get_net_workarea (dpyinfo, &workarea))
  6037             {
  6038               monitors[i].work = workarea;
  6039               if (!gui_intersect_rectangles (&monitors[i].geom,
  6040                                              &monitors[i].work,
  6041                                              &monitors[i].work))
  6042                 monitors[i].work = monitors[i].geom;
  6043             }
  6044           else
  6045             monitors[i].work = monitors[i].geom;
  6046         }
  6047 
  6048 #ifdef USE_XCB
  6049       for (int i = 0; i < n_monitors; ++i)
  6050         {
  6051           reply = xcb_get_atom_name_reply (dpyinfo->xcb_connection,
  6052                                            atom_name_cookies[i], &error);
  6053 
  6054           if (!reply)
  6055             {
  6056               monitors[i].name = xstrdup ("Unknown monitor");
  6057               free (error);
  6058             }
  6059           else
  6060             {
  6061               length = xcb_get_atom_name_name_length (reply);
  6062               name = xmalloc (length + 1);
  6063               memcpy (name, xcb_get_atom_name_name (reply), length);
  6064               name[length] = '\0';
  6065               monitors[i].name = name;
  6066               free (reply);
  6067             }
  6068         }
  6069 #endif
  6070 
  6071       XRRFreeMonitors (rr_monitors);
  6072       randr15_p = true;
  6073       goto out;
  6074     }
  6075 
  6076  fallback:;
  6077 #endif
  6078 
  6079 #define RANDR13_LIBRARY \
  6080   (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3))
  6081 
  6082 #if RANDR13_LIBRARY
  6083   /* Check if the display supports 1.3 too.  */
  6084   bool randr13_avail = (dpyinfo->xrandr_major_version > 1
  6085                         || (dpyinfo->xrandr_major_version == 1
  6086                             && dpyinfo->xrandr_minor_version >= 3));
  6087 
  6088   if (randr13_avail)
  6089     resources = XRRGetScreenResourcesCurrent (dpy, dpyinfo->root_window);
  6090   else
  6091     resources = XRRGetScreenResources (dpy, dpyinfo->root_window);
  6092 #else
  6093   resources = XRRGetScreenResources (dpy, dpyinfo->root_window);
  6094 #endif
  6095   if (! resources || resources->noutput == 0)
  6096     {
  6097       if (resources)
  6098         XRRFreeScreenResources (resources);
  6099       return Qnil;
  6100     }
  6101   n_monitors = resources->noutput;
  6102   monitors = xzalloc (n_monitors * sizeof *monitors);
  6103 
  6104 #if RANDR13_LIBRARY
  6105   if (randr13_avail)
  6106     pxid = XRRGetOutputPrimary (dpy, dpyinfo->root_window);
  6107 #endif
  6108 
  6109 #undef RANDR13_LIBRARY
  6110 
  6111   for (i = 0; i < n_monitors; ++i)
  6112     {
  6113       XRROutputInfo *info = XRRGetOutputInfo (dpy, resources,
  6114                                               resources->outputs[i]);
  6115       if (!info)
  6116         continue;
  6117 
  6118       if (strcmp (info->name, "default") == 0)
  6119         {
  6120           /* Non XRandr 1.2 driver, does not give useful data.  */
  6121           XRRFreeOutputInfo (info);
  6122           XRRFreeScreenResources (resources);
  6123           free_monitors (monitors, n_monitors);
  6124           return Qnil;
  6125         }
  6126 
  6127       if (info->connection != RR_Disconnected && info->crtc != None)
  6128         {
  6129           XRRCrtcInfo *crtc = XRRGetCrtcInfo (dpy, resources, info->crtc);
  6130           struct MonitorInfo *mi = &monitors[i];
  6131           XRectangle workarea_r;
  6132 
  6133           if (! crtc)
  6134             {
  6135               XRRFreeOutputInfo (info);
  6136               continue;
  6137             }
  6138 
  6139           mi->geom.x = crtc->x;
  6140           mi->geom.y = crtc->y;
  6141           mi->geom.width = crtc->width;
  6142           mi->geom.height = crtc->height;
  6143           mi->mm_width = info->mm_width;
  6144           mi->mm_height = info->mm_height;
  6145           mi->name = xstrdup (info->name);
  6146 
  6147           if (pxid != None && pxid == resources->outputs[i])
  6148             primary = i;
  6149           else if (primary == -1 && strcmp (info->name, "LVDS") == 0)
  6150             primary = i;
  6151 
  6152           if (i == primary && x_get_net_workarea (dpyinfo, &workarea_r))
  6153             {
  6154               mi->work= workarea_r;
  6155               if (! gui_intersect_rectangles (&mi->geom, &mi->work, &mi->work))
  6156                 mi->work = mi->geom;
  6157             }
  6158           else
  6159             mi->work = mi->geom;
  6160 
  6161           XRRFreeCrtcInfo (crtc);
  6162         }
  6163       XRRFreeOutputInfo (info);
  6164     }
  6165   XRRFreeScreenResources (resources);
  6166 #if RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 5)
  6167  out:
  6168 #endif
  6169   attributes_list = x_make_monitor_attribute_list (monitors,
  6170                                                    n_monitors,
  6171                                                    primary,
  6172                                                    dpyinfo,
  6173                                                    (randr15_p
  6174                                                     ? "XRandR 1.5"
  6175                                                     : "XRandr"));
  6176   free_monitors (monitors, n_monitors);
  6177   return attributes_list;
  6178 }
  6179 #endif /* HAVE_XRANDR */
  6180 
  6181 static Lisp_Object
  6182 x_get_monitor_attributes (struct x_display_info *dpyinfo)
  6183 {
  6184   Lisp_Object attributes_list = Qnil;
  6185   Display *dpy = dpyinfo->display;
  6186 
  6187   (void) dpy; /* Suppress unused variable warning.  */
  6188 
  6189 #ifdef HAVE_XRANDR
  6190   bool xrr_ok = ((dpyinfo->xrandr_major_version == 1
  6191                   && dpyinfo->xrandr_minor_version >= 2)
  6192                  || dpyinfo->xrandr_major_version > 1);
  6193 
  6194   if (xrr_ok)
  6195     attributes_list = x_get_monitor_attributes_xrandr (dpyinfo);
  6196 #endif /* HAVE_XRANDR */
  6197 
  6198 #ifdef HAVE_XINERAMA
  6199   if (NILP (attributes_list))
  6200     {
  6201       if (dpyinfo->xinerama_supported_p && XineramaIsActive (dpy))
  6202         attributes_list = x_get_monitor_attributes_xinerama (dpyinfo);
  6203     }
  6204 #endif /* HAVE_XINERAMA */
  6205 
  6206   if (NILP (attributes_list))
  6207     attributes_list = x_get_monitor_attributes_fallback (dpyinfo);
  6208 
  6209   return attributes_list;
  6210 }
  6211 
  6212 #endif /* !USE_GTK */
  6213 
  6214 #ifdef USE_LUCID
  6215 /* This is used by the Lucid menu widget, but it's defined here so we
  6216    can make use of a great deal of existing code.  */
  6217 static void
  6218 xlw_monitor_dimensions_at_pos_1 (struct x_display_info *dpyinfo,
  6219                                  Screen *screen, int src_x, int src_y,
  6220                                  int *x, int *y, int *width, int *height)
  6221 {
  6222   Lisp_Object attrs, tem, val;
  6223 
  6224   attrs = x_get_monitor_attributes (dpyinfo);
  6225 
  6226   for (tem = attrs; CONSP (tem); tem = XCDR (tem))
  6227     {
  6228       int sx, sy, swidth, sheight;
  6229       val = assq_no_quit (Qworkarea, XCAR (tem));
  6230       if (!NILP (val))
  6231         {
  6232           sx = XFIXNUM (XCAR (XCDR (val)));
  6233           sy = XFIXNUM (XCAR (XCDR (XCDR (val))));
  6234           swidth = XFIXNUM (XCAR (XCDR (XCDR (XCDR (val)))));
  6235           sheight = XFIXNUM (XCAR (XCDR (XCDR (XCDR (XCDR (val))))));
  6236 
  6237           if (sx <= src_x && src_x < (sx + swidth)
  6238               && sy <= src_y && src_y < (sy + swidth))
  6239             {
  6240               *x = sx;
  6241               *y = sy;
  6242               *width = swidth;
  6243               *height = sheight;
  6244               return;
  6245             }
  6246         }
  6247     }
  6248 
  6249   *x = 0;
  6250   *y = 0;
  6251   *width = WidthOfScreen (screen);
  6252   *height = HeightOfScreen (screen);
  6253 }
  6254 
  6255 void
  6256 xlw_monitor_dimensions_at_pos (Display *dpy, Screen *screen, int src_x,
  6257                                int src_y, int *x, int *y, int *width, int *height)
  6258 {
  6259   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
  6260 
  6261   if (!dpyinfo)
  6262     emacs_abort ();
  6263 
  6264   block_input ();
  6265   xlw_monitor_dimensions_at_pos_1 (dpyinfo, screen, src_x, src_y,
  6266                                    x, y, width, height);
  6267 
  6268   unblock_input ();
  6269 }
  6270 #endif
  6271 
  6272 
  6273 DEFUN ("x-display-monitor-attributes-list", Fx_display_monitor_attributes_list,
  6274        Sx_display_monitor_attributes_list,
  6275        0, 1, 0,
  6276        doc: /* Return a list of physical monitor attributes on the X display TERMINAL.
  6277 
  6278 The optional argument TERMINAL specifies which display to ask about.
  6279 TERMINAL should be a terminal object, a frame or a display name (a string).
  6280 If omitted or nil, that stands for the selected frame's display.
  6281 
  6282 In addition to the standard attribute keys listed in
  6283 `display-monitor-attributes-list', the following keys are contained in
  6284 the attributes:
  6285 
  6286  source -- String describing the source from which multi-monitor
  6287            information is obtained, one of \"Gdk\", \"XRandR 1.5\",
  6288            \"XRandr\", \"Xinerama\", or \"fallback\"
  6289 
  6290 Internal use only, use `display-monitor-attributes-list' instead.  */)
  6291   (Lisp_Object terminal)
  6292 {
  6293   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  6294   Lisp_Object attributes_list = Qnil;
  6295 
  6296 #ifdef USE_GTK
  6297   GdkDisplay *gdpy;
  6298 #if ! GTK_CHECK_VERSION (3, 22, 0)
  6299   double mm_width_per_pixel, mm_height_per_pixel;
  6300   GdkScreen *gscreen;
  6301 #endif
  6302   gint primary_monitor = 0, n_monitors, i;
  6303   Lisp_Object monitor_frames, rest, frame;
  6304   static const char *source = "Gdk";
  6305   struct MonitorInfo *monitors;
  6306 
  6307   block_input ();
  6308   gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
  6309 #if GTK_CHECK_VERSION (3, 22, 0)
  6310   n_monitors = gdk_display_get_n_monitors (gdpy);
  6311 #else
  6312   gscreen = gdk_display_get_default_screen (gdpy);
  6313   n_monitors = gdk_screen_get_n_monitors (gscreen);
  6314   primary_monitor = gdk_screen_get_primary_monitor (gscreen);
  6315   /* Fallback if gdk_screen_get_monitor_{width,height}_mm fail */
  6316   mm_width_per_pixel = ((double) WidthMMOfScreen (dpyinfo->screen)
  6317                         / x_display_pixel_width (dpyinfo));
  6318   mm_height_per_pixel = ((double) HeightMMOfScreen (dpyinfo->screen)
  6319                          / x_display_pixel_height (dpyinfo));
  6320 #endif
  6321   monitor_frames = make_nil_vector (n_monitors);
  6322   monitors = xzalloc (n_monitors * sizeof *monitors);
  6323 
  6324   FOR_EACH_FRAME (rest, frame)
  6325     {
  6326       struct frame *f = XFRAME (frame);
  6327 
  6328       if (FRAME_X_P (f)
  6329           && FRAME_DISPLAY_INFO (f) == dpyinfo
  6330           && !FRAME_TOOLTIP_P (f))
  6331         {
  6332           GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
  6333 
  6334 #if GTK_CHECK_VERSION (3, 22, 0)
  6335           for (i = 0; i < n_monitors; i++)
  6336             if (gdk_display_get_monitor_at_window (gdpy, gwin)
  6337                 == gdk_display_get_monitor (gdpy, i))
  6338               break;
  6339 #else
  6340           i = gdk_screen_get_monitor_at_window (gscreen, gwin);
  6341 #endif
  6342           ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
  6343         }
  6344     }
  6345 
  6346   for (i = 0; i < n_monitors; ++i)
  6347     {
  6348       gint width_mm, height_mm;
  6349       GdkRectangle rec, work;
  6350       struct MonitorInfo *mi = &monitors[i];
  6351       int scale = 1;
  6352 
  6353 #if GTK_CHECK_VERSION (3, 22, 0)
  6354       GdkMonitor *monitor = gdk_display_get_monitor (gdpy, i);
  6355       if (gdk_monitor_is_primary (monitor))
  6356         primary_monitor = i;
  6357       gdk_monitor_get_geometry (monitor, &rec);
  6358 #else
  6359       gdk_screen_get_monitor_geometry (gscreen, i, &rec);
  6360 #endif
  6361 
  6362 #if GTK_CHECK_VERSION (3, 22, 0)
  6363       width_mm = gdk_monitor_get_width_mm (monitor);
  6364       height_mm = gdk_monitor_get_height_mm (monitor);
  6365 #else
  6366       width_mm = gdk_screen_get_monitor_width_mm (gscreen, i);
  6367       height_mm = gdk_screen_get_monitor_height_mm (gscreen, i);
  6368       if (width_mm < 0)
  6369         width_mm = rec.width * mm_width_per_pixel + 0.5;
  6370       if (height_mm < 0)
  6371         height_mm = rec.height * mm_height_per_pixel + 0.5;
  6372 #endif
  6373 #if GTK_CHECK_VERSION (3, 22, 0)
  6374       gdk_monitor_get_workarea (monitor, &work);
  6375 #elif defined HAVE_GTK3
  6376       gdk_screen_get_monitor_workarea (gscreen, i, &work);
  6377 #else
  6378       /* Emulate the behavior of GTK+ 3.4.  */
  6379       {
  6380         XRectangle workarea_r;
  6381 
  6382         if (i == primary_monitor && x_get_net_workarea (dpyinfo, &workarea_r))
  6383           {
  6384             work.x = workarea_r.x;
  6385             work.y = workarea_r.y;
  6386             work.width = workarea_r.width;
  6387             work.height = workarea_r.height;
  6388             if (! gdk_rectangle_intersect (&rec, &work, &work))
  6389               work = rec;
  6390           }
  6391         else
  6392           work = rec;
  6393       }
  6394 #endif
  6395 
  6396       /* GTK returns scaled sizes for the workareas.  */
  6397 #if GTK_CHECK_VERSION (3, 22, 0)
  6398       scale = gdk_monitor_get_scale_factor (monitor);
  6399 #elif defined HAVE_GTK3
  6400       scale = gdk_screen_get_monitor_scale_factor (gscreen, i);
  6401 #endif
  6402       rec.x *= scale;
  6403       rec.y *= scale;
  6404       rec.width *= scale;
  6405       rec.height *= scale;
  6406       work.x *= scale;
  6407       work.y *= scale;
  6408       work.width *= scale;
  6409       work.height *= scale;
  6410 
  6411       mi->geom.x = rec.x;
  6412       mi->geom.y = rec.y;
  6413       mi->geom.width = rec.width;
  6414       mi->geom.height = rec.height;
  6415       mi->work.x = work.x;
  6416       mi->work.y = work.y;
  6417       mi->work.width = work.width;
  6418       mi->work.height = work.height;
  6419       mi->mm_width = width_mm;
  6420       mi->mm_height = height_mm;
  6421 
  6422 #if GTK_CHECK_VERSION (3, 22, 0)
  6423       dupstring (&mi->name, (gdk_monitor_get_model (monitor)));
  6424 #else
  6425       mi->name = gdk_screen_get_monitor_plug_name (gscreen, i);
  6426 #endif
  6427     }
  6428 
  6429   attributes_list = make_monitor_attribute_list (monitors,
  6430                                                  n_monitors,
  6431                                                  primary_monitor,
  6432                                                  monitor_frames,
  6433                                                  source);
  6434   free_monitors (monitors, n_monitors);
  6435   unblock_input ();
  6436 #else  /* not USE_GTK */
  6437 
  6438   block_input ();
  6439   attributes_list = x_get_monitor_attributes (dpyinfo);
  6440   unblock_input ();
  6441 
  6442 #endif  /* not USE_GTK */
  6443 
  6444   return attributes_list;
  6445 }
  6446 
  6447 /* Return geometric attributes of FRAME.  According to the value of
  6448    ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the native
  6449    edges of FRAME (Qnative_edges), or the inner edges of frame
  6450    (Qinner_edges).  Any other value means to return the geometry as
  6451    returned by Fx_frame_geometry.  */
  6452 static Lisp_Object
  6453 frame_geometry (Lisp_Object frame, Lisp_Object attribute)
  6454 {
  6455   struct frame *f = decode_live_frame (frame);
  6456   /**   XWindowAttributes atts; **/
  6457   Window rootw;
  6458   unsigned int ign, native_width, native_height, x_border_width = 0;
  6459   int x_native = 0, y_native = 0, xptr = 0, yptr = 0;
  6460   int left_off = 0, right_off = 0, top_off = 0, bottom_off = 0;
  6461   int outer_left, outer_top, outer_right, outer_bottom;
  6462   int native_left, native_top, native_right, native_bottom;
  6463   int inner_left, inner_top, inner_right, inner_bottom;
  6464   int internal_border_width;
  6465   bool menu_bar_external = false, tool_bar_external = false;
  6466   int menu_bar_height = 0, menu_bar_width = 0;
  6467   int tab_bar_height = 0, tab_bar_width = 0;
  6468   int tool_bar_height = 0, tool_bar_width = 0;
  6469 
  6470   if (FRAME_INITIAL_P (f) || !FRAME_X_P (f) || !FRAME_OUTER_WINDOW (f))
  6471     return Qnil;
  6472 
  6473   block_input ();
  6474   XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
  6475                 &rootw, &x_native, &y_native, &native_width, &native_height,
  6476                 &x_border_width, &ign);
  6477   /**   XGetWindowAttributes (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &atts); **/
  6478   if (!FRAME_PARENT_FRAME (f))
  6479     x_real_pos_and_offsets (f, &left_off, &right_off, &top_off, &bottom_off,
  6480                             NULL, NULL, &xptr, &yptr, NULL);
  6481   unblock_input ();
  6482 
  6483   /**   native_width = atts.width; **/
  6484   /**   native_height = atts.height; **/
  6485 
  6486   if (FRAME_PARENT_FRAME (f))
  6487     {
  6488       Lisp_Object parent, edges;
  6489 
  6490       XSETFRAME (parent, FRAME_PARENT_FRAME (f));
  6491       edges = Fx_frame_edges (parent, Qnative_edges);
  6492       if (!NILP (edges))
  6493         {
  6494           x_native += XFIXNUM (Fnth (make_fixnum (0), edges));
  6495           y_native += XFIXNUM (Fnth (make_fixnum (1), edges));
  6496         }
  6497 
  6498       outer_left = x_native;
  6499       outer_top = y_native;
  6500       outer_right = outer_left + native_width + 2 * x_border_width;
  6501       outer_bottom = outer_top + native_height + 2 * x_border_width;
  6502 
  6503       native_left = x_native + x_border_width;
  6504       native_top = y_native + x_border_width;
  6505       native_right = native_left + native_width;
  6506       native_bottom = native_top + native_height;
  6507     }
  6508   else
  6509     {
  6510       outer_left = xptr;
  6511       outer_top = yptr;
  6512       outer_right = outer_left + left_off + native_width + right_off;
  6513       outer_bottom = outer_top + top_off + native_height + bottom_off;
  6514 
  6515       native_left = outer_left + left_off;
  6516       native_top = outer_top + top_off;
  6517       native_right = native_left + native_width;
  6518       native_bottom = native_top + native_height;
  6519     }
  6520 
  6521   internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
  6522   inner_left = native_left + internal_border_width;
  6523   inner_top = native_top + internal_border_width;
  6524   inner_right = native_right - internal_border_width;
  6525   inner_bottom = native_bottom - internal_border_width;
  6526 
  6527 #ifdef HAVE_EXT_MENU_BAR
  6528   menu_bar_external = true;
  6529   menu_bar_height = FRAME_MENUBAR_HEIGHT (f);
  6530   native_top += menu_bar_height;
  6531   inner_top += menu_bar_height;
  6532 #else
  6533   menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
  6534   inner_top += menu_bar_height;
  6535 #endif
  6536   menu_bar_width = menu_bar_height ? native_width : 0;
  6537 
  6538   tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
  6539   tab_bar_width = (tab_bar_height
  6540                     ? native_width - 2 * internal_border_width
  6541                     : 0);
  6542   inner_top += tab_bar_height;
  6543 
  6544 #ifdef HAVE_EXT_TOOL_BAR
  6545   tool_bar_external = true;
  6546   if (EQ (FRAME_TOOL_BAR_POSITION (f), Qleft))
  6547     {
  6548       tool_bar_width = FRAME_TOOLBAR_WIDTH (f);
  6549       native_left += tool_bar_width;
  6550       inner_left += tool_bar_width;
  6551       tool_bar_height
  6552         = tool_bar_width ? native_height - menu_bar_height : 0;
  6553     }
  6554   else if (EQ (FRAME_TOOL_BAR_POSITION (f), Qtop))
  6555     {
  6556       tool_bar_height = FRAME_TOOLBAR_HEIGHT (f);
  6557       native_top += tool_bar_height;
  6558       inner_top += tool_bar_height;
  6559       tool_bar_width = tool_bar_height ? native_width : 0;
  6560     }
  6561   else if (EQ (FRAME_TOOL_BAR_POSITION (f), Qright))
  6562     {
  6563       tool_bar_width = FRAME_TOOLBAR_WIDTH (f);
  6564       native_right -= tool_bar_width;
  6565       inner_right -= tool_bar_width;
  6566       tool_bar_height
  6567         = tool_bar_width ? native_height - menu_bar_height : 0;
  6568     }
  6569   else
  6570     {
  6571       tool_bar_height = FRAME_TOOLBAR_HEIGHT (f);
  6572       native_bottom -= tool_bar_height;
  6573       inner_bottom -= tool_bar_height;
  6574       tool_bar_width = tool_bar_height ? native_width : 0;
  6575     }
  6576 #else
  6577   tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
  6578   tool_bar_width = (tool_bar_height
  6579                     ? native_width - 2 * internal_border_width
  6580                     : 0);
  6581   inner_top += tool_bar_height;
  6582 #endif
  6583 
  6584   /* Construct list.  */
  6585   if (EQ (attribute, Qouter_edges))
  6586     return list4i (outer_left, outer_top, outer_right, outer_bottom);
  6587   else if (EQ (attribute, Qnative_edges))
  6588     return list4i (native_left, native_top, native_right, native_bottom);
  6589   else if (EQ (attribute, Qinner_edges))
  6590     return list4i (inner_left, inner_top, inner_right, inner_bottom);
  6591   else
  6592     return
  6593        list (Fcons (Qouter_position,
  6594                     Fcons (make_fixnum (outer_left),
  6595                            make_fixnum (outer_top))),
  6596              Fcons (Qouter_size,
  6597                     Fcons (make_fixnum (outer_right - outer_left),
  6598                            make_fixnum (outer_bottom - outer_top))),
  6599              /* Approximate.  */
  6600              Fcons (Qexternal_border_size,
  6601                     Fcons (make_fixnum (right_off),
  6602                            make_fixnum (bottom_off))),
  6603              Fcons (Qouter_border_width, make_fixnum (x_border_width)),
  6604              /* Approximate.  */
  6605              Fcons (Qtitle_bar_size,
  6606                     Fcons (make_fixnum (0),
  6607                            make_fixnum (top_off - bottom_off))),
  6608              Fcons (Qmenu_bar_external, menu_bar_external ? Qt : Qnil),
  6609              Fcons (Qmenu_bar_size,
  6610                     Fcons (make_fixnum (menu_bar_width),
  6611                            make_fixnum (menu_bar_height))),
  6612              Fcons (Qtab_bar_size,
  6613                     Fcons (make_fixnum (tab_bar_width),
  6614                            make_fixnum (tab_bar_height))),
  6615              Fcons (Qtool_bar_external, tool_bar_external ? Qt : Qnil),
  6616              Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
  6617              Fcons (Qtool_bar_size,
  6618                     Fcons (make_fixnum (tool_bar_width),
  6619                            make_fixnum (tool_bar_height))),
  6620              Fcons (Qinternal_border_width,
  6621                     make_fixnum (internal_border_width)));
  6622 }
  6623 
  6624 DEFUN ("x-frame-geometry", Fx_frame_geometry, Sx_frame_geometry, 0, 1, 0,
  6625        doc: /* Return geometric attributes of FRAME.
  6626 FRAME must be a live frame and defaults to the selected one.  The return
  6627 value is an association list of the attributes listed below.  All height
  6628 and width values are in pixels.
  6629 
  6630 `outer-position' is a cons of the outer left and top edges of FRAME
  6631   relative to the origin - the position (0, 0) - of FRAME's display.
  6632 
  6633 `outer-size' is a cons of the outer width and height of FRAME.  The
  6634   outer size includes the title bar and the external borders as well as
  6635   any menu and/or tool bar of frame.  For a child frame the value
  6636   includes FRAME's X borders, if any.
  6637 
  6638 `external-border-size' is a cons of the horizontal and vertical width of
  6639   FRAME's external borders as supplied by the window manager.
  6640 
  6641 `title-bar-size' is a cons of the width and height of the title bar of
  6642   FRAME as supplied by the window manager.  If both of them are zero,
  6643   FRAME has no title bar.  If only the width is zero, Emacs was not
  6644   able to retrieve the width information.
  6645 
  6646 `menu-bar-external', if non-nil, means the menu bar is external (never
  6647   included in the inner edges of FRAME).
  6648 
  6649 `menu-bar-size' is a cons of the width and height of the menu bar of
  6650   FRAME.
  6651 
  6652 `tool-bar-external', if non-nil, means the tool bar is external (never
  6653   included in the inner edges of FRAME).
  6654 
  6655 `tool-bar-position' tells on which side the tool bar on FRAME is and can
  6656   be one of `left', `top', `right' or `bottom'.  If this is nil, FRAME
  6657   has no tool bar.
  6658 
  6659 `tool-bar-size' is a cons of the width and height of the tool bar of
  6660   FRAME.
  6661 
  6662 `internal-border-width' is the width of the internal border of
  6663   FRAME.
  6664 
  6665 `outer-border-width' is the width of the X border of FRAME.  The X
  6666   border is usually shown only for frames without window manager
  6667   decorations, such as child and tooltip frames.  */)
  6668   (Lisp_Object frame)
  6669 {
  6670   return frame_geometry (frame, Qnil);
  6671 }
  6672 
  6673 DEFUN ("x-frame-edges", Fx_frame_edges, Sx_frame_edges, 0, 2, 0,
  6674        doc: /* Return edge coordinates of FRAME.
  6675 FRAME must be a live frame and defaults to the selected one.  The return
  6676 value is a list of the form (LEFT, TOP, RIGHT, BOTTOM).  All values are
  6677 in pixels relative to the origin - the position (0, 0) - of FRAME's
  6678 display.
  6679 
  6680 If optional argument TYPE is the symbol `outer-edges', return the outer
  6681 edges of FRAME.  The outer edges comprise the decorations of the window
  6682 manager (like the title bar or external borders) as well as any external
  6683 menu or tool bar of FRAME.  If optional argument TYPE is the symbol
  6684 `native-edges' or nil, return the native edges of FRAME.  The native
  6685 edges exclude the decorations of the window manager and any external
  6686 menu or tool bar of FRAME.  If TYPE is the symbol `inner-edges', return
  6687 the inner edges of FRAME.  These edges exclude title bar, any borders,
  6688 menu bar or tool bar of FRAME.  */)
  6689   (Lisp_Object frame, Lisp_Object type)
  6690 {
  6691   return frame_geometry (frame, ((EQ (type, Qouter_edges)
  6692                                   || EQ (type, Qinner_edges))
  6693                                  ? type
  6694                                  : Qnative_edges));
  6695 }
  6696 
  6697 /**
  6698  * x_frame_list_z_order:
  6699  *
  6700  * Recursively add list of all frames on the display specified via
  6701  * DPYINFO and whose window-system window's parent is specified by
  6702  * WINDOW to FRAMES and return FRAMES.
  6703  */
  6704 static Lisp_Object
  6705 x_frame_list_z_order (struct x_display_info *dpyinfo, Window window)
  6706 {
  6707   Display *dpy;
  6708   Window root, parent, *children;
  6709   unsigned int nchildren;
  6710   unsigned long i;
  6711   Lisp_Object frames, val;
  6712   Atom type;
  6713   Window *toplevels;
  6714   int format, rc;
  6715   unsigned long nitems, bytes_after;
  6716   unsigned char *data;
  6717   struct frame *f;
  6718 
  6719   dpy = dpyinfo->display;
  6720   data = NULL;
  6721   frames = Qnil;
  6722 
  6723   if (window == dpyinfo->root_window
  6724       && x_wm_supports_1 (dpyinfo,
  6725                           dpyinfo->Xatom_net_client_list_stacking))
  6726     {
  6727       rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  6728                                dpyinfo->Xatom_net_client_list_stacking,
  6729                                0, LONG_MAX, False, XA_WINDOW, &type,
  6730                                &format, &nitems, &bytes_after, &data);
  6731 
  6732       if (rc != Success)
  6733         return Qnil;
  6734 
  6735       if (format != 32 || type != XA_WINDOW)
  6736         {
  6737           XFree (data);
  6738           return Qnil;
  6739         }
  6740 
  6741       toplevels = (Window *) data;
  6742 
  6743       for (i = 0; i < nitems; ++i)
  6744         {
  6745           f = x_top_window_to_frame (dpyinfo, toplevels[i]);
  6746 
  6747           if (f)
  6748             {
  6749               XSETFRAME (val, f);
  6750               frames = Fcons (val, frames);
  6751             }
  6752         }
  6753 
  6754       XFree (data);
  6755       return frames;
  6756     }
  6757 
  6758   if (XQueryTree (dpy, window, &root, &parent, &children, &nchildren))
  6759     {
  6760       for (i = 0; i < nchildren; i++)
  6761         {
  6762           Lisp_Object frame, tail;
  6763 
  6764           FOR_EACH_FRAME (tail, frame)
  6765             {
  6766               struct frame *cf = XFRAME (frame);
  6767               /* With a reparenting window manager the parent_desc
  6768                  field usually specifies the topmost windows of our
  6769                  frames.  Otherwise FRAME_OUTER_WINDOW should do.  */
  6770               if (FRAME_X_P (cf)
  6771                   && (cf->output_data.x->parent_desc == children[i]
  6772                       || FRAME_OUTER_WINDOW (cf) == children[i]))
  6773                 frames = Fcons (frame, frames);
  6774             }
  6775         }
  6776 
  6777       if (children)
  6778         XFree (children);
  6779     }
  6780 
  6781   return frames;
  6782 }
  6783 
  6784 
  6785 DEFUN ("x-frame-list-z-order", Fx_frame_list_z_order,
  6786        Sx_frame_list_z_order, 0, 1, 0,
  6787        doc: /* Return list of Emacs' frames, in Z (stacking) order.
  6788 The optional argument TERMINAL specifies which display to ask about.
  6789 TERMINAL should be either a frame or a display name (a string).  If
  6790 omitted or nil, that stands for the selected frame's display.  Return
  6791 nil if TERMINAL contains no Emacs frame.
  6792 
  6793 As a special case, if TERMINAL is non-nil and specifies a live frame,
  6794 return the child frames of that frame in Z (stacking) order.
  6795 
  6796 Frames are listed from topmost (first) to bottommost (last).  */)
  6797   (Lisp_Object terminal)
  6798 {
  6799   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  6800   Window window;
  6801 
  6802   if (FRAMEP (terminal) && FRAME_LIVE_P (XFRAME (terminal)))
  6803     window = FRAME_X_WINDOW (XFRAME (terminal));
  6804   else
  6805     window = dpyinfo->root_window;
  6806 
  6807   return x_frame_list_z_order (dpyinfo, window);
  6808 }
  6809 
  6810 /**
  6811  * x_frame_restack:
  6812  *
  6813  * Restack frame F1 below frame F2, above if ABOVE_FLAG is non-nil.  In
  6814  * practice this is a two-step action: The first step removes F1's
  6815  * window-system window from the display.  The second step reinserts
  6816  * F1's window below (above if ABOVE_FLAG is true) that of F2.
  6817  */
  6818 static void
  6819 x_frame_restack (struct frame *f1, struct frame *f2, bool above_flag)
  6820 {
  6821 #ifdef USE_GTK
  6822   block_input ();
  6823   xg_frame_restack (f1, f2, above_flag);
  6824   unblock_input ();
  6825 #else
  6826   Display *dpy = FRAME_X_DISPLAY (f1);
  6827   Window window1 = FRAME_OUTER_WINDOW (f1);
  6828   XWindowChanges wc;
  6829   unsigned long mask = (CWSibling | CWStackMode);
  6830 
  6831   wc.sibling = FRAME_OUTER_WINDOW (f2);
  6832   wc.stack_mode = above_flag ? Above : Below;
  6833   block_input ();
  6834   /* Configure the window manager window (a normal XConfigureWindow
  6835      won't cut it).  This should also work for child frames.  */
  6836   XReconfigureWMWindow (dpy, window1, FRAME_X_SCREEN_NUMBER (f1), mask, &wc);
  6837   unblock_input ();
  6838 #endif /* USE_GTK */
  6839 }
  6840 
  6841 
  6842 DEFUN ("x-frame-restack", Fx_frame_restack, Sx_frame_restack, 2, 3, 0,
  6843        doc: /* Restack FRAME1 below FRAME2.
  6844 This means that if both frames are visible and the display areas of
  6845 these frames overlap, FRAME2 (partially) obscures FRAME1.  If optional
  6846 third argument ABOVE is non-nil, restack FRAME1 above FRAME2.  This
  6847 means that if both frames are visible and the display areas of these
  6848 frames overlap, FRAME1 (partially) obscures FRAME2.
  6849 
  6850 This may be thought of as an atomic action performed in two steps: The
  6851 first step removes FRAME1's window-step window from the display.  The
  6852 second step reinserts FRAME1's window below (above if ABOVE is true)
  6853 that of FRAME2.  Hence the position of FRAME2 in its display's Z
  6854 \(stacking) order relative to all other frames excluding FRAME1 remains
  6855 unaltered.
  6856 
  6857 Some window managers may refuse to restack windows.  */)
  6858      (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above)
  6859 {
  6860   struct frame *f1 = decode_live_frame (frame1);
  6861   struct frame *f2 = decode_live_frame (frame2);
  6862 
  6863   if (! (FRAME_OUTER_WINDOW (f1) && FRAME_OUTER_WINDOW (f2)))
  6864     error ("Cannot restack frames");
  6865   x_frame_restack (f1, f2, !NILP (above));
  6866   return Qt;
  6867 }
  6868 
  6869 
  6870 DEFUN ("x-mouse-absolute-pixel-position", Fx_mouse_absolute_pixel_position,
  6871        Sx_mouse_absolute_pixel_position, 0, 0, 0,
  6872        doc: /* Return absolute position of mouse cursor in pixels.
  6873 The position is returned as a cons cell (X . Y) of the coordinates of
  6874 the mouse cursor position in pixels relative to a position (0, 0) of the
  6875 selected frame's display.  */)
  6876   (void)
  6877 {
  6878   struct frame *f = SELECTED_FRAME ();
  6879   Window root, dummy_window;
  6880   int x, y, dummy;
  6881 
  6882   if (FRAME_INITIAL_P (f) || !FRAME_X_P (f))
  6883     return Qnil;
  6884 
  6885   block_input ();
  6886   x_query_pointer (FRAME_X_DISPLAY (f),
  6887                    FRAME_DISPLAY_INFO (f)->root_window,
  6888                    &root, &dummy_window, &x, &y, &dummy, &dummy,
  6889                    (unsigned int *) &dummy);
  6890   unblock_input ();
  6891 
  6892   return Fcons (make_fixnum (x), make_fixnum (y));
  6893 }
  6894 
  6895 DEFUN ("x-set-mouse-absolute-pixel-position", Fx_set_mouse_absolute_pixel_position,
  6896        Sx_set_mouse_absolute_pixel_position, 2, 2, 0,
  6897        doc: /* Move mouse pointer to absolute pixel position (X, Y).
  6898 The coordinates X and Y are interpreted in pixels relative to a position
  6899 \(0, 0) of the selected frame's display.  */)
  6900   (Lisp_Object x, Lisp_Object y)
  6901 {
  6902   struct frame *f = SELECTED_FRAME ();
  6903 
  6904   if (FRAME_INITIAL_P (f) || !FRAME_X_P (f))
  6905     return Qnil;
  6906 
  6907   int xval = check_integer_range (x, INT_MIN, INT_MAX);
  6908   int yval = check_integer_range (y, INT_MIN, INT_MAX);
  6909 
  6910   block_input ();
  6911 #ifdef HAVE_XINPUT2
  6912   int deviceid;
  6913 
  6914   deviceid = FRAME_DISPLAY_INFO (f)->client_pointer_device;
  6915 
  6916   if (FRAME_DISPLAY_INFO (f)->supports_xi2
  6917       && deviceid != -1)
  6918     {
  6919       x_catch_errors_for_lisp (FRAME_DISPLAY_INFO (f));
  6920       XIWarpPointer (FRAME_X_DISPLAY (f), deviceid, None,
  6921                      FRAME_DISPLAY_INFO (f)->root_window,
  6922                      0, 0, 0, 0, xval, yval);
  6923       x_uncatch_errors_for_lisp (FRAME_DISPLAY_INFO (f));
  6924     }
  6925   else
  6926 #endif
  6927     XWarpPointer (FRAME_X_DISPLAY (f), None,
  6928                   FRAME_DISPLAY_INFO (f)->root_window,
  6929                   0, 0, 0, 0, xval, yval);
  6930   unblock_input ();
  6931 
  6932   return Qnil;
  6933 }
  6934 
  6935 DEFUN ("x-begin-drag", Fx_begin_drag, Sx_begin_drag, 1, 6, 0,
  6936        doc: /* Begin dragging contents on FRAME, with targets TARGETS.
  6937 TARGETS is a list of strings, which defines the X selection targets
  6938 that will be available to the drop target.  Block until the mouse
  6939 buttons are released, then return the action chosen by the target, or
  6940 `nil' if the drop was not accepted by the drop target.  Dragging
  6941 starts when the mouse is pressed on FRAME, and the contents of the
  6942 selection `XdndSelection' will be sent to the X window underneath the
  6943 mouse pointer (the drop target) when the mouse button is released.
  6944 
  6945 ACTION is a symbol which tells the target what it should do, and can
  6946 be one of the following:
  6947 
  6948  - `XdndActionCopy', which means to copy the contents from the drag
  6949    source (FRAME) to the drop target.
  6950 
  6951  - `XdndActionMove', which means to first take the contents of
  6952    `XdndSelection', and to delete whatever was saved into that
  6953    selection afterwards.
  6954 
  6955 `XdndActionPrivate' is also a valid return value, and means that the
  6956 drop target chose to perform an unspecified or unknown action.
  6957 
  6958 The source is also expected to cooperate with the target to perform
  6959 the action chosen by the target.  For example, callers should delete
  6960 the buffer text that was dragged if `XdndActionMove' is returned.
  6961 
  6962 There are also some other valid values of ACTION that depend on
  6963 details of both the drop target's implementation details and that of
  6964 Emacs.  For that reason, they are not mentioned here.  Consult
  6965 "Drag-and-Drop Protocol for the X Window System" for more details:
  6966 https://freedesktop.org/wiki/Specifications/XDND/.
  6967 
  6968 If RETURN-FRAME is non-nil, this function will return the frame if the
  6969 mouse pointer moves onto an Emacs frame, after first moving out of
  6970 FRAME.  (This is not guaranteed to work on some systems.)  If
  6971 RETURN-FRAME is the symbol `now', any frame underneath the mouse
  6972 pointer will be returned immediately.
  6973 
  6974 If ACTION is a list and not nil, its elements are assumed to be a cons
  6975 of (ITEM . STRING), where ITEM is the name of an action, and STRING is
  6976 a string describing ITEM to the user.  The drop target is expected to
  6977 prompt the user to choose between any of the actions in the list.
  6978 
  6979 If ACTION is not specified or nil, `XdndActionCopy' is used
  6980 instead.
  6981 
  6982 If ALLOW-CURRENT-FRAME is not specified or nil, then the drop target
  6983 is allowed to be FRAME.  Otherwise, no action will be taken if the
  6984 mouse buttons are released on top of FRAME.
  6985 
  6986 If FOLLOW-TOOLTIP is non-nil, any tooltip currently being displayed
  6987 will be moved to follow the mouse pointer while the drag is in
  6988 progress.  Note that this does not work with system tooltips (tooltips
  6989 created when `use-system-tooltips' is non-nil).
  6990 
  6991 This function will sometimes return immediately if no mouse buttons
  6992 are currently held down.  It should only be called when it is known
  6993 that mouse buttons are being held down, such as immediately after a
  6994 `down-mouse-1' (or similar) event.  */)
  6995   (Lisp_Object targets, Lisp_Object action, Lisp_Object frame,
  6996    Lisp_Object return_frame, Lisp_Object allow_current_frame,
  6997    Lisp_Object follow_tooltip)
  6998 {
  6999   struct frame *f = decode_window_system_frame (frame);
  7000   int ntargets = 0, nnames = 0;
  7001   char *target_names[2048];
  7002   Atom *target_atoms;
  7003   Lisp_Object lval, original, targets_arg, tem, t1, t2;
  7004   Atom xaction;
  7005   Atom action_list[2048];
  7006   char *name_list[2048];
  7007 
  7008   USE_SAFE_ALLOCA;
  7009 
  7010   CHECK_LIST (targets);
  7011   original = targets;
  7012   targets_arg = targets;
  7013 
  7014   FOR_EACH_TAIL (targets)
  7015     {
  7016       CHECK_STRING (XCAR (targets));
  7017 
  7018       if (ntargets < 2048)
  7019         {
  7020           SAFE_ALLOCA_STRING (target_names[ntargets],
  7021                               XCAR (targets));
  7022           ntargets++;
  7023         }
  7024       else
  7025         error ("Too many targets");
  7026     }
  7027 
  7028   CHECK_LIST_END (targets, original);
  7029 
  7030   if (NILP (action) || EQ (action, QXdndActionCopy))
  7031     xaction = FRAME_DISPLAY_INFO (f)->Xatom_XdndActionCopy;
  7032   else if (EQ (action, QXdndActionMove))
  7033     xaction = FRAME_DISPLAY_INFO (f)->Xatom_XdndActionMove;
  7034   else if (EQ (action, QXdndActionLink))
  7035     xaction = FRAME_DISPLAY_INFO (f)->Xatom_XdndActionLink;
  7036   else if (EQ (action, QXdndActionPrivate))
  7037     xaction = FRAME_DISPLAY_INFO (f)->Xatom_XdndActionPrivate;
  7038   else if (EQ (action, QXdndActionAsk))
  7039     xaction = FRAME_DISPLAY_INFO (f)->Xatom_XdndActionAsk;
  7040   else if (SYMBOLP (action))
  7041     /* This is to accommodate non-standard DND protocols such as XDS
  7042        that are explicitly implemented by Emacs, and is not documented
  7043        for that reason.  */
  7044     xaction = symbol_to_x_atom (FRAME_DISPLAY_INFO (f), action);
  7045   else if (CONSP (action))
  7046     {
  7047       xaction = FRAME_DISPLAY_INFO (f)->Xatom_XdndActionAsk;
  7048       original = action;
  7049 
  7050       CHECK_LIST (action);
  7051       FOR_EACH_TAIL (action)
  7052         {
  7053           tem = XCAR (action);
  7054           CHECK_CONS (tem);
  7055           t1 = XCAR (tem);
  7056           t2 = XCDR (tem);
  7057           CHECK_SYMBOL (t1);
  7058           CHECK_STRING (t2);
  7059 
  7060           if (nnames < 2048)
  7061             {
  7062               if (EQ (t1, QXdndActionCopy))
  7063                 action_list[nnames] = FRAME_DISPLAY_INFO (f)->Xatom_XdndActionCopy;
  7064               else if (EQ (t1, QXdndActionMove))
  7065                 action_list[nnames] = FRAME_DISPLAY_INFO (f)->Xatom_XdndActionMove;
  7066               else if (EQ (t1, QXdndActionLink))
  7067                 action_list[nnames] = FRAME_DISPLAY_INFO (f)->Xatom_XdndActionLink;
  7068               else if (EQ (t1, QXdndActionAsk))
  7069                 action_list[nnames] = FRAME_DISPLAY_INFO (f)->Xatom_XdndActionAsk;
  7070               else if (EQ (t1, QXdndActionPrivate))
  7071                 action_list[nnames] = FRAME_DISPLAY_INFO (f)->Xatom_XdndActionPrivate;
  7072               else
  7073                 signal_error ("Invalid drag-and-drop action", tem);
  7074 
  7075               SAFE_ALLOCA_STRING (name_list[nnames],
  7076                                   ENCODE_SYSTEM (t2));
  7077 
  7078               nnames++;
  7079             }
  7080           else
  7081             error ("Too many actions");
  7082         }
  7083       CHECK_LIST_END (action, original);
  7084     }
  7085   else
  7086     signal_error ("Invalid drag-and-drop action", action);
  7087 
  7088   target_atoms = SAFE_ALLOCA (ntargets * sizeof *target_atoms);
  7089 
  7090   /* Catch errors since interning lots of targets can potentially
  7091      generate a BadAlloc error.  */
  7092   x_catch_errors (FRAME_X_DISPLAY (f));
  7093   XInternAtoms (FRAME_X_DISPLAY (f), target_names,
  7094                 ntargets, False, target_atoms);
  7095   x_check_errors (FRAME_X_DISPLAY (f),
  7096                   "Failed to intern target atoms: %s");
  7097   x_uncatch_errors_after_check ();
  7098 
  7099   lval = x_dnd_begin_drag_and_drop (f, FRAME_DISPLAY_INFO (f)->last_user_time,
  7100                                     xaction, return_frame, action_list,
  7101                                     (const char **) &name_list, nnames,
  7102                                     !NILP (allow_current_frame), target_atoms,
  7103                                     ntargets, targets_arg, !NILP (follow_tooltip));
  7104 
  7105   SAFE_FREE ();
  7106   return lval;
  7107 }
  7108 
  7109 /************************************************************************
  7110                               X Displays
  7111  ************************************************************************/
  7112 
  7113 
  7114 /* Mapping visual names to visuals.  */
  7115 
  7116 static struct visual_class
  7117 {
  7118   const char *name;
  7119   int class;
  7120 }
  7121 visual_classes[] =
  7122 {
  7123   {"StaticGray",        StaticGray},
  7124   {"GrayScale",         GrayScale},
  7125   {"StaticColor",       StaticColor},
  7126   {"PseudoColor",       PseudoColor},
  7127   {"TrueColor",         TrueColor},
  7128   {"DirectColor",       DirectColor},
  7129   {NULL, 0}
  7130 };
  7131 
  7132 
  7133 #ifndef HAVE_XSCREENNUMBEROFSCREEN
  7134 
  7135 /* Value is the screen number of screen SCR.  This is a substitute for
  7136    the X function with the same name when that doesn't exist.  */
  7137 
  7138 int
  7139 XScreenNumberOfScreen (Screen *scr)
  7140 {
  7141   Display *dpy = scr->display;
  7142   int i;
  7143 
  7144   for (i = 0; i < dpy->nscreens; ++i)
  7145     if (scr == dpy->screens + i)
  7146       break;
  7147 
  7148   return i;
  7149 }
  7150 
  7151 #endif /* not HAVE_XSCREENNUMBEROFSCREEN */
  7152 
  7153 
  7154 /* Select the visual that should be used on display DPYINFO.  Set
  7155    members of DPYINFO appropriately.  Called from x_term_init.  */
  7156 
  7157 void
  7158 select_visual (struct x_display_info *dpyinfo)
  7159 {
  7160   Display *dpy = dpyinfo->display;
  7161   Screen *screen = dpyinfo->screen;
  7162 
  7163   /* See if a visual is specified.  */
  7164   AUTO_STRING (visualClass, "visualClass");
  7165   AUTO_STRING (VisualClass, "VisualClass");
  7166   Lisp_Object value = gui_display_get_resource (dpyinfo, visualClass,
  7167                                                 VisualClass, Qnil, Qnil);
  7168 
  7169   if (STRINGP (value))
  7170     {
  7171       /* VALUE should be of the form CLASS-DEPTH, where CLASS is one
  7172          of `PseudoColor', `TrueColor' etc. and DEPTH is the color
  7173          depth, a decimal number.  NAME is compared with case ignored.  */
  7174       char *s = alloca (SBYTES (value) + 1);
  7175       char *dash;
  7176       int i, class = -1;
  7177       XVisualInfo vinfo;
  7178 
  7179       lispstpcpy (s, value);
  7180       dash = strchr (s, '-');
  7181       if (dash)
  7182         {
  7183           dpyinfo->n_planes = atoi (dash + 1);
  7184           *dash = '\0';
  7185         }
  7186       else
  7187         /* We won't find a matching visual with depth 0, so that
  7188            an error will be printed below.  */
  7189         dpyinfo->n_planes = 0;
  7190 
  7191       /* Determine the visual class.  */
  7192       for (i = 0; visual_classes[i].name; ++i)
  7193         if (xstrcasecmp (s, visual_classes[i].name) == 0)
  7194           {
  7195             class = visual_classes[i].class;
  7196             break;
  7197           }
  7198 
  7199       /* Look up a matching visual for the specified class.  */
  7200       if (class == -1
  7201           || !XMatchVisualInfo (dpy, XScreenNumberOfScreen (screen),
  7202                                 dpyinfo->n_planes, class, &vinfo))
  7203         fatal ("Invalid visual specification '%s'",
  7204                SSDATA (ENCODE_SYSTEM (value)));
  7205 
  7206       dpyinfo->visual = vinfo.visual;
  7207       dpyinfo->visual_info = vinfo;
  7208     }
  7209   else
  7210     {
  7211       int n_visuals;
  7212       XVisualInfo *vinfo, vinfo_template;
  7213 
  7214       vinfo_template.screen = XScreenNumberOfScreen (screen);
  7215 
  7216 #if !defined USE_X_TOOLKIT && !(defined USE_GTK && !defined HAVE_GTK3) \
  7217   && defined HAVE_XRENDER
  7218       int i;
  7219       XRenderPictFormat *format;
  7220 
  7221       /* First attempt to find a visual with an alpha mask if
  7222          available.  That information is only available when the
  7223          render extension is present, and we cannot do much with such
  7224          a visual if it isn't.  */
  7225 
  7226       if (dpyinfo->xrender_supported_p)
  7227         {
  7228 
  7229           vinfo = XGetVisualInfo (dpy, VisualScreenMask,
  7230                                   &vinfo_template, &n_visuals);
  7231 
  7232           for (i = 0; i < n_visuals; ++i)
  7233             {
  7234               format = XRenderFindVisualFormat (dpy, vinfo[i].visual);
  7235 
  7236               if (format && format->type == PictTypeDirect
  7237                   && format->direct.alphaMask)
  7238                 {
  7239                   dpyinfo->n_planes = vinfo[i].depth;
  7240                   dpyinfo->visual = vinfo[i].visual;
  7241                   dpyinfo->visual_info = vinfo[i];
  7242                   dpyinfo->pict_format = format;
  7243 
  7244                   XFree (vinfo);
  7245                   return;
  7246                 }
  7247             }
  7248 
  7249           if (vinfo)
  7250             XFree (vinfo);
  7251         }
  7252 #endif /* !USE_X_TOOLKIT */
  7253 
  7254       /* Visual with alpha channel (or the Render extension) not
  7255          available, fallback to default visual.  */
  7256       dpyinfo->visual = DefaultVisualOfScreen (screen);
  7257       vinfo_template.visualid = XVisualIDFromVisual (dpyinfo->visual);
  7258       vinfo = XGetVisualInfo (dpy, VisualIDMask | VisualScreenMask,
  7259                               &vinfo_template, &n_visuals);
  7260       if (n_visuals <= 0)
  7261         fatal ("Can't get proper X visual info");
  7262       dpyinfo->visual_info = *vinfo;
  7263       dpyinfo->n_planes = vinfo->depth;
  7264       XFree (vinfo);
  7265     }
  7266 }
  7267 
  7268 
  7269 /* Return the X display structure for the display named NAME.
  7270    Open a new connection if necessary.  */
  7271 
  7272 static struct x_display_info *
  7273 x_display_info_for_name (Lisp_Object name)
  7274 {
  7275   struct x_display_info *dpyinfo;
  7276 
  7277   CHECK_STRING (name);
  7278 
  7279   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
  7280     if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name)))
  7281       return dpyinfo;
  7282 
  7283   /* Use this general default value to start with.  */
  7284   Vx_resource_name = Vinvocation_name;
  7285 
  7286   validate_x_resource_name ();
  7287 
  7288   dpyinfo = x_term_init (name, 0, SSDATA (Vx_resource_name));
  7289 
  7290   if (dpyinfo == 0)
  7291     error ("Cannot connect to X server %s", SDATA (name));
  7292 
  7293   return dpyinfo;
  7294 }
  7295 
  7296 
  7297 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
  7298        1, 3, 0,
  7299        doc: /* Open a connection to a display server.
  7300 DISPLAY is the name of the display to connect to.
  7301 Optional second arg XRM-STRING is a string of resources in xrdb format.
  7302 If the optional third arg MUST-SUCCEED is non-nil,
  7303 terminate Emacs if we can't open the connection.
  7304 \(In the Nextstep version, the last two arguments are currently ignored.)  */)
  7305   (Lisp_Object display, Lisp_Object xrm_string, Lisp_Object must_succeed)
  7306 {
  7307   char *xrm_option;
  7308   struct x_display_info *dpyinfo;
  7309 
  7310   CHECK_STRING (display);
  7311   if (! NILP (xrm_string))
  7312     CHECK_STRING (xrm_string);
  7313 
  7314   xrm_option = NILP (xrm_string) ? 0 : SSDATA (xrm_string);
  7315 
  7316   validate_x_resource_name ();
  7317 
  7318   /* This is what opens the connection and sets x_current_display.
  7319      This also initializes many symbols, such as those used for input.  */
  7320   dpyinfo = x_term_init (display, xrm_option,
  7321                          SSDATA (Vx_resource_name));
  7322 
  7323   if (dpyinfo == 0)
  7324     {
  7325       if (!NILP (must_succeed))
  7326         fatal ("Cannot connect to X server %s.\n\
  7327 Check the DISPLAY environment variable or use `-d'.\n\
  7328 Also use the `xauth' program to verify that you have the proper\n\
  7329 authorization information needed to connect the X server.\n\
  7330 An insecure way to solve the problem may be to use `xhost'.\n",
  7331                SDATA (display));
  7332       else
  7333         error ("Cannot connect to X server %s", SDATA (display));
  7334     }
  7335 
  7336   return Qnil;
  7337 }
  7338 
  7339 DEFUN ("x-close-connection", Fx_close_connection,
  7340        Sx_close_connection, 1, 1, 0,
  7341        doc: /* Close the connection to TERMINAL's X server.
  7342 For TERMINAL, specify a terminal object, a frame or a display name (a
  7343 string).  If TERMINAL is nil, that stands for the selected frame's terminal.
  7344 \(On MS Windows, this function does not accept terminal objects.)  */)
  7345   (Lisp_Object terminal)
  7346 {
  7347   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  7348 
  7349   if (dpyinfo->reference_count > 0)
  7350     error ("Display still has frames on it");
  7351 
  7352   x_delete_terminal (dpyinfo->terminal);
  7353 
  7354   return Qnil;
  7355 }
  7356 
  7357 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
  7358        doc: /* Return the list of display names that Emacs has connections to.  */)
  7359   (void)
  7360 {
  7361   Lisp_Object result = Qnil;
  7362   struct x_display_info *xdi;
  7363 
  7364   for (xdi = x_display_list; xdi; xdi = xdi->next)
  7365     result = Fcons (XCAR (xdi->name_list_element), result);
  7366 
  7367   return result;
  7368 }
  7369 
  7370 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
  7371        doc: /* If ON is non-nil, report X errors as soon as the erring request is made.
  7372 This function has an effect only on X Windows.  With MS Windows, it is
  7373 defined but does nothing.
  7374 
  7375 If ON is nil, allow buffering of requests.
  7376 Turning on synchronization prohibits the Xlib routines from buffering
  7377 requests and seriously degrades performance, but makes debugging much
  7378 easier.
  7379 The optional second argument TERMINAL specifies which display to act on.
  7380 TERMINAL should be a terminal object, a frame or a display name (a string).
  7381 If TERMINAL is omitted or nil, that stands for the selected frame's display.  */)
  7382   (Lisp_Object on, Lisp_Object terminal)
  7383 {
  7384   struct x_display_info *dpyinfo = check_x_display_info (terminal);
  7385 
  7386   XSynchronize (dpyinfo->display, !NILP (on));
  7387 
  7388   return Qnil;
  7389 }
  7390 
  7391 /* Wait for responses to all X commands issued so far for frame F.  */
  7392 
  7393 void
  7394 x_sync (struct frame *f)
  7395 {
  7396   block_input ();
  7397 #ifndef USE_XCB
  7398   XSync (FRAME_X_DISPLAY (f), False);
  7399 #else
  7400   xcb_aux_sync (FRAME_DISPLAY_INFO (f)->xcb_connection);
  7401 #endif
  7402   unblock_input ();
  7403 }
  7404 
  7405 
  7406 /***********************************************************************
  7407                            Window properties
  7408  ***********************************************************************/
  7409 
  7410 DEFUN ("x-change-window-property", Fx_change_window_property,
  7411        Sx_change_window_property, 2, 7, 0,
  7412        doc: /* Change window property PROP to VALUE on the X window of FRAME.
  7413 PROP must be a string.  VALUE may be a string or a list of conses,
  7414 numbers and/or strings.  If an element in the list is a string, it is
  7415 converted to an atom and the value of the atom is used.  If an element
  7416 is a cons, it is converted to a 32 bit number where the car is the 16
  7417 top bits and the cdr is the lower 16 bits.
  7418 
  7419 FRAME nil or omitted means use the selected frame.  If TYPE is given
  7420 and non-nil, it is the name of the type of VALUE.  If TYPE is not
  7421 given or nil, the type is STRING.
  7422 
  7423 FORMAT gives the size in bits of each element if VALUE is a list.  It
  7424 must be one of 8, 16 or 32.
  7425 
  7426 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to
  7427 8.  If OUTER-P is non-nil, the property is changed for the outer X
  7428 window of FRAME.  Default is to change on the edit X window.
  7429 
  7430 If WINDOW-ID is non-nil, change the property of that window instead of
  7431 FRAME's X window; the number 0 denotes the root window.  This argument
  7432 is separate from FRAME because window IDs are not unique across X
  7433 displays or screens on the same display, so FRAME provides context for
  7434 the window ID.
  7435 
  7436 If VALUE is a string and FORMAT is 32, then the format of VALUE is
  7437 system-specific.  VALUE must contain unsigned integer data in native
  7438 endian-ness in multiples of the size of the C type 'long': the low 32
  7439 bits of each such number are used as the value of each element of the
  7440 property.
  7441 
  7442 Wait for the request to complete and signal any error, unless
  7443 `x-fast-protocol-requests' is non-nil, in which case errors will be
  7444 silently ignored.  */)
  7445   (Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
  7446    Lisp_Object type, Lisp_Object format, Lisp_Object outer_p,
  7447    Lisp_Object window_id)
  7448 {
  7449   struct frame *f;
  7450   Atom prop_atom;
  7451   Atom target_type = XA_STRING;
  7452   int element_format = 8;
  7453   unsigned char *data;
  7454   int nelements;
  7455   Window target_window;
  7456   struct x_display_info *dpyinfo;
  7457 #ifdef USE_XCB
  7458   bool intern_prop;
  7459   bool intern_target;
  7460   xcb_intern_atom_cookie_t prop_atom_cookie;
  7461   xcb_intern_atom_cookie_t target_type_cookie;
  7462   xcb_intern_atom_reply_t *reply;
  7463   xcb_generic_error_t *generic_error;
  7464   bool rc;
  7465 #endif
  7466 
  7467   f = decode_window_system_frame (frame);
  7468   dpyinfo = FRAME_DISPLAY_INFO (f);
  7469 
  7470   CHECK_STRING (prop);
  7471 
  7472   if (! NILP (format))
  7473     {
  7474       CHECK_FIXNUM (format);
  7475 
  7476       if (XFIXNUM (format) != 8 && XFIXNUM (format) != 16
  7477           && XFIXNUM (format) != 32)
  7478         error ("FORMAT must be one of 8, 16 or 32");
  7479       element_format = XFIXNUM (format);
  7480     }
  7481 
  7482   if (CONSP (value))
  7483     {
  7484       ptrdiff_t elsize;
  7485 
  7486       nelements = x_check_property_data (value);
  7487       if (nelements == -1)
  7488         error ("Bad data in VALUE, must be number, string or cons");
  7489 
  7490       /* The man page for XChangeProperty:
  7491              "If the specified format is 32, the property data must be a
  7492               long array."
  7493          This applies even if long is more than 32 bits.  The X library
  7494          converts to 32 bits before sending to the X server.  */
  7495       elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
  7496       data = xnmalloc (nelements, elsize);
  7497 
  7498       x_fill_property_data (FRAME_X_DISPLAY (f), value, data, nelements,
  7499                             element_format);
  7500     }
  7501   else
  7502     {
  7503       ptrdiff_t elsize;
  7504 
  7505       CHECK_STRING (value);
  7506       data = SDATA (value);
  7507       if (INT_MAX < SBYTES (value))
  7508         error ("VALUE too long");
  7509 
  7510       /* See comment above about longs and format=32 */
  7511       elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
  7512       if (SBYTES (value) % elsize != 0)
  7513         error ("VALUE must contain an integral number of octets for FORMAT");
  7514       nelements = SBYTES (value) / elsize;
  7515     }
  7516 
  7517   if (! NILP (window_id))
  7518     {
  7519       CONS_TO_INTEGER (window_id, Window, target_window);
  7520       if (! target_window)
  7521         target_window = dpyinfo->root_window;
  7522     }
  7523   else
  7524     {
  7525       if (! NILP (outer_p))
  7526         target_window = FRAME_OUTER_WINDOW (f);
  7527       else
  7528         target_window = FRAME_X_WINDOW (f);
  7529     }
  7530 
  7531   block_input ();
  7532 #ifndef USE_XCB
  7533   prop_atom = x_intern_cached_atom (dpyinfo, SSDATA (prop),
  7534                                     false);
  7535   if (! NILP (type))
  7536     {
  7537       CHECK_STRING (type);
  7538       target_type = x_intern_cached_atom (dpyinfo, SSDATA (type),
  7539                                           false);
  7540     }
  7541 #else
  7542   rc = true;
  7543   intern_target = true;
  7544   intern_prop = true;
  7545 
  7546   prop_atom = x_intern_cached_atom (dpyinfo, SSDATA (prop),
  7547                                     true);
  7548 
  7549   if (prop_atom != None)
  7550     intern_prop = false;
  7551   else
  7552     prop_atom_cookie
  7553       = xcb_intern_atom (dpyinfo->xcb_connection,
  7554                          0, SBYTES (prop), SSDATA (prop));
  7555 
  7556   if (!NILP (type))
  7557     {
  7558       CHECK_STRING (type);
  7559 
  7560       target_type = x_intern_cached_atom (dpyinfo, SSDATA (type),
  7561                                           true);
  7562 
  7563       if (target_type)
  7564         intern_target = false;
  7565       else
  7566         target_type_cookie
  7567           = xcb_intern_atom (dpyinfo->xcb_connection,
  7568                              0, SBYTES (type), SSDATA (type));
  7569     }
  7570 
  7571   if (intern_prop)
  7572     {
  7573       reply = xcb_intern_atom_reply (dpyinfo->xcb_connection,
  7574                                      prop_atom_cookie, &generic_error);
  7575 
  7576       if (reply)
  7577         {
  7578           prop_atom = (Atom) reply->atom;
  7579           free (reply);
  7580         }
  7581       else
  7582         {
  7583           free (generic_error);
  7584           rc = false;
  7585         }
  7586     }
  7587 
  7588   if (!NILP (type) && intern_target)
  7589     {
  7590       reply = xcb_intern_atom_reply (dpyinfo->xcb_connection,
  7591                                      target_type_cookie, &generic_error);
  7592 
  7593       if (reply)
  7594         {
  7595           target_type = (Atom) reply->atom;
  7596           free (reply);
  7597         }
  7598       else
  7599         {
  7600           free (generic_error);
  7601           rc = false;
  7602         }
  7603     }
  7604 
  7605   if (!rc)
  7606     error ("Failed to intern type or property atom");
  7607 #endif
  7608 
  7609   x_catch_errors_for_lisp (dpyinfo);
  7610 
  7611   XChangeProperty (dpyinfo->display, target_window,
  7612                    prop_atom, target_type, element_format,
  7613                    PropModeReplace, data, nelements);
  7614 
  7615   if (CONSP (value))
  7616     xfree (data);
  7617 
  7618   x_check_errors_for_lisp (dpyinfo,
  7619                            "Couldn't change window property: %s");
  7620   x_uncatch_errors_for_lisp (dpyinfo);
  7621 
  7622   unblock_input ();
  7623   return value;
  7624 }
  7625 
  7626 
  7627 DEFUN ("x-delete-window-property", Fx_delete_window_property,
  7628        Sx_delete_window_property, 1, 3, 0,
  7629        doc: /* Remove window property PROP from X window of FRAME.
  7630 FRAME nil or omitted means use the selected frame.
  7631 If WINDOW-ID is non-nil, remove property from that window instead
  7632  of FRAME's X window; the number 0 denotes the root window.  This
  7633  argument is separate from FRAME because window IDs are not unique
  7634  across X displays or screens on the same display, so FRAME provides
  7635  context for the window ID.
  7636 
  7637 Value is PROP.
  7638 
  7639 Wait for the request to complete and signal any error, unless
  7640 `x-fast-protocol-requests' is non-nil, in which case errors will be
  7641 silently ignored.  */)
  7642   (Lisp_Object prop, Lisp_Object frame, Lisp_Object window_id)
  7643 {
  7644   struct frame *f = decode_window_system_frame (frame);
  7645   Window target_window = FRAME_X_WINDOW (f);
  7646   Atom prop_atom;
  7647 
  7648   CHECK_STRING (prop);
  7649 
  7650   if (! NILP (window_id))
  7651     {
  7652       CONS_TO_INTEGER (window_id, Window, target_window);
  7653       if (! target_window)
  7654         target_window = FRAME_DISPLAY_INFO (f)->root_window;
  7655     }
  7656 
  7657   block_input ();
  7658   prop_atom = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
  7659                                     SSDATA (prop), false);
  7660 
  7661   x_catch_errors_for_lisp (FRAME_DISPLAY_INFO (f));
  7662   XDeleteProperty (FRAME_X_DISPLAY (f), target_window, prop_atom);
  7663   x_check_errors_for_lisp (FRAME_DISPLAY_INFO (f),
  7664                            "Couldn't delete window property: %s");
  7665   x_uncatch_errors_for_lisp (FRAME_DISPLAY_INFO (f));
  7666 
  7667   unblock_input ();
  7668   return prop;
  7669 }
  7670 
  7671 
  7672 static Lisp_Object
  7673 x_window_property_intern (struct frame *f,
  7674                           Window target_window,
  7675                           Atom prop_atom,
  7676                           Atom target_type,
  7677                           Lisp_Object delete_p,
  7678                           Lisp_Object vector_ret_p,
  7679                           bool *found)
  7680 {
  7681   unsigned char *tmp_data = NULL;
  7682   Lisp_Object prop_value = Qnil;
  7683   Atom actual_type;
  7684   int actual_format;
  7685   unsigned long actual_size, bytes_remaining;
  7686   int rc;
  7687 
  7688   rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
  7689                            prop_atom, 0, 0, False, target_type,
  7690                            &actual_type, &actual_format, &actual_size,
  7691                            &bytes_remaining, &tmp_data);
  7692 
  7693   *found = actual_format != 0;
  7694 
  7695   if (rc == Success && *found)
  7696     {
  7697       XFree (tmp_data);
  7698       tmp_data = NULL;
  7699 
  7700       rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
  7701                                prop_atom, 0, bytes_remaining,
  7702                                ! NILP (delete_p), target_type,
  7703                                &actual_type, &actual_format,
  7704                                &actual_size, &bytes_remaining,
  7705                                &tmp_data);
  7706       if (rc == Success && tmp_data)
  7707         {
  7708           /* The man page for XGetWindowProperty says:
  7709              "If the returned format is 32, the returned data is represented
  7710              as a long array and should be cast to that type to obtain the
  7711              elements."
  7712              This applies even if long is more than 32 bits, the X library
  7713              converts from 32 bit elements received from the X server to long
  7714              and passes the long array to us.  Thus, for that case memcpy can not
  7715              be used.  We convert to a 32 bit type here, because so much code
  7716              assume on that.
  7717 
  7718              The bytes and offsets passed to XGetWindowProperty refers to the
  7719              property and those are indeed in 32 bit quantities if format is
  7720              32.  */
  7721 
  7722           if (LONG_WIDTH > 32 && actual_format == 32)
  7723             {
  7724               unsigned long i;
  7725               int  *idata = (int *) tmp_data;
  7726               long *ldata = (long *) tmp_data;
  7727 
  7728               for (i = 0; i < actual_size; ++i)
  7729                 idata[i] = (int) ldata[i];
  7730             }
  7731 
  7732           if (NILP (vector_ret_p))
  7733             prop_value = make_string ((char *) tmp_data,
  7734                                       (actual_format >> 3) * actual_size);
  7735           else
  7736             prop_value = x_property_data_to_lisp (f,
  7737                                                   tmp_data,
  7738                                                   actual_type,
  7739                                                   actual_format,
  7740                                                   actual_size);
  7741         }
  7742 
  7743       if (tmp_data) XFree (tmp_data);
  7744     }
  7745 
  7746   return prop_value;
  7747 }
  7748 
  7749 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
  7750        1, 6, 0,
  7751        doc: /* Value is the value of window property PROP on FRAME.
  7752 If FRAME is nil or omitted, use the selected frame.
  7753 
  7754 On X Windows, the following optional arguments are also accepted: If
  7755 TYPE is nil or omitted, get the property as a string.  Otherwise TYPE
  7756 is the name of the atom that denotes the expected type.
  7757 
  7758 If TYPE is the string "AnyPropertyType", decode and return the data
  7759 regardless of what the type really is.
  7760 
  7761 The format of the data returned is the same as a selection conversion
  7762 to the given type.  For example, if `x-get-selection-internal' returns
  7763 an integer when the selection data is a given type,
  7764 `x-window-property' will do the same for that type.
  7765 
  7766 If WINDOW-ID is non-nil, get the property of that window instead of
  7767 FRAME's X window; the number 0 denotes the root window.  This argument
  7768 is separate from FRAME because window IDs are not unique across X
  7769 displays, so FRAME provides context for the window ID.
  7770 
  7771 If DELETE-P is non-nil, delete the property after retrieving it.
  7772 If VECTOR-RET-P is non-nil, return a vector of values instead of a string.
  7773 
  7774 X allows an arbitrary number of properties to be set on any window.
  7775 However, properties are most often set by the window manager or other
  7776 programs on the root window or FRAME's X window in order to
  7777 communicate information to Emacs and other programs.  Most of these
  7778 properties are specified as part of the Extended Window Manager Hints
  7779 and the Inter-Client Communication Conventions Manual, which are
  7780 located here:
  7781 
  7782   https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html
  7783 
  7784 and
  7785 
  7786   https://x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html
  7787 
  7788 Return value is nil if FRAME doesn't have a property with name PROP or
  7789 if PROP has no value of TYPE (always a string in the MS Windows case). */)
  7790   (Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
  7791    Lisp_Object window_id, Lisp_Object delete_p, Lisp_Object vector_ret_p)
  7792 {
  7793   struct frame *f = decode_window_system_frame (frame);
  7794   Atom prop_atom;
  7795   Lisp_Object prop_value = Qnil;
  7796   Atom target_type = XA_STRING;
  7797   Window target_window = FRAME_X_WINDOW (f);
  7798   bool found;
  7799 
  7800   CHECK_STRING (prop);
  7801 
  7802   if (! NILP (window_id))
  7803     {
  7804       CONS_TO_INTEGER (window_id, Window, target_window);
  7805       if (! target_window)
  7806         target_window = FRAME_DISPLAY_INFO (f)->root_window;
  7807     }
  7808 
  7809   block_input ();
  7810   x_catch_errors (FRAME_X_DISPLAY (f));
  7811 
  7812   if (STRINGP (type))
  7813     {
  7814       if (strcmp ("AnyPropertyType", SSDATA (type)) == 0)
  7815         target_type = AnyPropertyType;
  7816       else
  7817         target_type = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
  7818                                             SSDATA (type), false);
  7819     }
  7820 
  7821   prop_atom = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
  7822                                     SSDATA (prop), false);
  7823   prop_value = x_window_property_intern (f,
  7824                                          target_window,
  7825                                          prop_atom,
  7826                                          target_type,
  7827                                          delete_p,
  7828                                          vector_ret_p,
  7829                                          &found);
  7830   if (NILP (prop_value)
  7831       && ! found
  7832       && NILP (window_id)
  7833       && target_window != FRAME_OUTER_WINDOW (f))
  7834     {
  7835       prop_value = x_window_property_intern (f,
  7836                                              FRAME_OUTER_WINDOW (f),
  7837                                              prop_atom,
  7838                                              target_type,
  7839                                              delete_p,
  7840                                              vector_ret_p,
  7841                                              &found);
  7842     }
  7843 
  7844   x_check_errors (FRAME_X_DISPLAY (f),
  7845                   "Can't retrieve window property: %s");
  7846   x_uncatch_errors_after_check ();
  7847 
  7848   unblock_input ();
  7849   return prop_value;
  7850 }
  7851 
  7852 DEFUN ("x-window-property-attributes", Fx_window_property_attributes, Sx_window_property_attributes,
  7853        1, 3, 0,
  7854        doc: /* Retrieve metadata about window property PROP on FRAME.
  7855 If FRAME is nil or omitted, use the selected frame.
  7856 If WINDOW-ID is non-nil, get the property of that window instead of
  7857  FRAME's X window; the number 0 denotes the root window.  This
  7858  argument is separate from FRAME because window IDs are not unique
  7859  across X displays or screens on the same display, so FRAME provides
  7860  context for the window ID.
  7861 
  7862 Return value is nil if FRAME doesn't have a property named PROP.
  7863 Otherwise, the return value is a vector with the following fields:
  7864 
  7865 0. The property type, as an integer.  The symbolic name of
  7866  the type can be obtained with `x-get-atom-name'.
  7867 1. The format of each element; one of 8, 16, or 32.
  7868 2. The length of the property, in number of elements. */)
  7869   (Lisp_Object prop, Lisp_Object frame, Lisp_Object window_id)
  7870 {
  7871   struct frame *f = decode_window_system_frame (frame);
  7872   Window target_window = FRAME_X_WINDOW (f);
  7873   Atom prop_atom;
  7874   Lisp_Object prop_attr = Qnil;
  7875   Atom actual_type;
  7876   int actual_format;
  7877   unsigned long actual_size, bytes_remaining;
  7878   unsigned char *tmp_data = NULL;
  7879   int rc;
  7880 
  7881   CHECK_STRING (prop);
  7882 
  7883   if (! NILP (window_id))
  7884     {
  7885       CONS_TO_INTEGER (window_id, Window, target_window);
  7886       if (! target_window)
  7887         target_window = FRAME_DISPLAY_INFO (f)->root_window;
  7888     }
  7889 
  7890   block_input ();
  7891 
  7892   x_catch_errors (FRAME_X_DISPLAY (f));
  7893   prop_atom = x_intern_cached_atom (FRAME_DISPLAY_INFO (f),
  7894                                     SSDATA (prop), false);
  7895   rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
  7896                            prop_atom, 0, 0, False, AnyPropertyType,
  7897                            &actual_type, &actual_format, &actual_size,
  7898                            &bytes_remaining, &tmp_data);
  7899   if (rc == Success          /* no invalid params */
  7900       && actual_format == 0  /* but prop not found */
  7901       && NILP (window_id)
  7902       && target_window != FRAME_OUTER_WINDOW (f))
  7903     {
  7904       /* analogous behavior to x-window-property: if property isn't found
  7905          on the frame's inner window and no alternate window id was
  7906          provided, try the frame's outer window. */
  7907       target_window = FRAME_OUTER_WINDOW (f);
  7908       rc = XGetWindowProperty (FRAME_X_DISPLAY (f), target_window,
  7909                                prop_atom, 0, 0, False, AnyPropertyType,
  7910                                &actual_type, &actual_format, &actual_size,
  7911                                &bytes_remaining, &tmp_data);
  7912     }
  7913 
  7914   if (rc == Success && actual_format != 0)
  7915     {
  7916       XFree (tmp_data);
  7917 
  7918       prop_attr = CALLN (Fvector,
  7919                          make_fixnum (actual_type),
  7920                          make_fixnum (actual_format),
  7921                          make_fixnum (bytes_remaining / (actual_format >> 3)));
  7922     }
  7923 
  7924   x_check_errors (FRAME_X_DISPLAY (f),
  7925                   "Can't retrieve window property: %s");
  7926   x_uncatch_errors_after_check ();
  7927 
  7928   unblock_input ();
  7929   return prop_attr;
  7930 }
  7931 
  7932 
  7933 /***********************************************************************
  7934                            Coordinate management
  7935  ***********************************************************************/
  7936 
  7937 DEFUN ("x-translate-coordinates", Fx_translate_coordinates,
  7938        Sx_translate_coordinates,
  7939        1, 6, 0, doc: /* Translate coordinates from FRAME.
  7940 Translate the given coordinates SOURCE-X and SOURCE-Y from
  7941 SOURCE-WINDOW's coordinate space to that of DEST-WINDOW, on FRAME.
  7942 
  7943 If SOURCE-X and SOURCE-Y are nil, use 0 instead.
  7944 
  7945 FRAME can either be a terminal or a frame.  If nil, it defaults to the
  7946 selected frame.  SOURCE-WINDOW must be an X window ID, 0 (which means
  7947 to use the root window), or nil, which means to use FRAME's inner
  7948 window.  DEST-WINDOW must be another X window ID, or nil (which means
  7949 to use the root window).
  7950 
  7951 Return a list of (X Y CHILD) if the given coordinates are on the same
  7952 screen, or nil otherwise, where X and Y are the coordinates in
  7953 DEST-WINDOW's coordinate space, and CHILD is the window ID of any
  7954 mapped child in DEST-WINDOW at those coordinates, or nil if there is
  7955 no such window.  If REQUIRE-CHILD is nil, avoid fetching CHILD if it
  7956 would result in an avoidable request to the X server, thereby
  7957 improving performance when the X connection is over a slow network.
  7958 Otherwise, always obtain the mapped child window from the X
  7959 server.  */)
  7960   (Lisp_Object frame, Lisp_Object source_window,
  7961    Lisp_Object dest_window, Lisp_Object source_x,
  7962    Lisp_Object source_y, Lisp_Object require_child)
  7963 {
  7964   struct x_display_info *dpyinfo;
  7965   struct frame *source_frame;
  7966   int dest_x, dest_y;
  7967   Window child_return, src, dest;
  7968   Bool rc;
  7969   Lisp_Object temp_result;
  7970 
  7971   dpyinfo = check_x_display_info (frame);
  7972   dest_x = 0;
  7973   dest_y = 0;
  7974 
  7975   if (!NILP (source_x))
  7976     {
  7977       CHECK_FIXNUM (source_x);
  7978       dest_x = XFIXNUM (source_x);
  7979     }
  7980 
  7981   if (!NILP (source_y))
  7982     {
  7983       CHECK_FIXNUM (source_y);
  7984       dest_y = XFIXNUM (source_y);
  7985     }
  7986 
  7987   source_frame = NULL;
  7988 
  7989   if (!NILP (source_window))
  7990     CONS_TO_INTEGER (source_window, Window, src);
  7991   else
  7992     {
  7993       source_frame = decode_window_system_frame (frame);
  7994       src = FRAME_X_WINDOW (source_frame);
  7995     }
  7996 
  7997   /* If require_child is nil, try to avoid an avoidable roundtrip to
  7998      the X server.  */
  7999   if (NILP (require_child) && source_frame)
  8000     {
  8001       temp_result
  8002         = x_handle_translate_coordinates (source_frame, dest_window, dest_x,
  8003                                           dest_y);
  8004       if (!NILP (temp_result))
  8005         return temp_result;
  8006     }
  8007 
  8008   if (!src)
  8009     src = dpyinfo->root_window;
  8010 
  8011   if (!NILP (dest_window))
  8012     CONS_TO_INTEGER (dest_window, Window, dest);
  8013   else
  8014     dest = dpyinfo->root_window;
  8015 
  8016   block_input ();
  8017   x_catch_errors (dpyinfo->display);
  8018   rc = XTranslateCoordinates (dpyinfo->display, src, dest,
  8019                               dest_x, dest_y, &dest_x, &dest_y,
  8020                               &child_return);
  8021   x_check_errors (dpyinfo->display,
  8022                   "Couldn't translate coordinates: %s");
  8023   x_uncatch_errors_after_check ();
  8024   unblock_input ();
  8025 
  8026   if (!rc)
  8027     return Qnil;
  8028 
  8029   return list3 (make_int (dest_x),
  8030                 make_int (dest_y),
  8031                 (child_return != None
  8032                  ? make_uint (child_return)
  8033                  : Qnil));
  8034 }
  8035 
  8036 /***********************************************************************
  8037                                 Tool tips
  8038  ***********************************************************************/
  8039 
  8040 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
  8041                             Lisp_Object, int, int, int *, int *);
  8042 
  8043 /* The frame of the currently visible tooltip, or nil if none.  */
  8044 Lisp_Object tip_frame;
  8045 
  8046 /* The window-system window corresponding to the frame of the
  8047    currently visible tooltip.  */
  8048 Window tip_window;
  8049 
  8050 /* The X and Y deltas of the last call to `x-show-tip'.  */
  8051 Lisp_Object tip_dx, tip_dy;
  8052 
  8053 /* A timer that hides or deletes the currently visible tooltip when it
  8054    fires.  */
  8055 static Lisp_Object tip_timer;
  8056 
  8057 /* STRING argument of last `x-show-tip' call.  */
  8058 static Lisp_Object tip_last_string;
  8059 
  8060 /* Normalized FRAME argument of last `x-show-tip' call.  */
  8061 static Lisp_Object tip_last_frame;
  8062 
  8063 /* PARMS argument of last `x-show-tip' call.  */
  8064 static Lisp_Object tip_last_parms;
  8065 
  8066 
  8067 static void
  8068 unwind_create_tip_frame (Lisp_Object frame)
  8069 {
  8070   Lisp_Object deleted;
  8071 
  8072   deleted = unwind_create_frame (frame);
  8073   if (EQ (deleted, Qt))
  8074     {
  8075       tip_window = None;
  8076       tip_frame = Qnil;
  8077     }
  8078 }
  8079 
  8080 
  8081 /* Create a frame for a tooltip on the display described by DPYINFO.
  8082    PARMS is a list of frame parameters.  TEXT is the string to
  8083    display in the tip frame.  Value is the frame.
  8084 
  8085    Note that functions called here, esp. gui_default_parameter can
  8086    signal errors, for instance when a specified color name is
  8087    undefined.  We have to make sure that we're in a consistent state
  8088    when this happens.  */
  8089 
  8090 static Lisp_Object
  8091 x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
  8092 {
  8093   struct frame *f;
  8094   Lisp_Object frame;
  8095   Lisp_Object name;
  8096   specpdl_ref count = SPECPDL_INDEX ();
  8097   bool face_change_before = face_change;
  8098 
  8099   if (!dpyinfo->terminal->name)
  8100     error ("Terminal is not live, can't create new frames on it");
  8101 
  8102   parms = Fcopy_alist (parms);
  8103 
  8104   /* Get the name of the frame to use for resource lookup.  */
  8105   name = gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name",
  8106                               RES_TYPE_STRING);
  8107   if (!STRINGP (name)
  8108       && !BASE_EQ (name, Qunbound)
  8109       && !NILP (name))
  8110     error ("Invalid frame name--not a string or nil");
  8111 
  8112   frame = Qnil;
  8113   f = make_frame (false);
  8114   f->wants_modeline = false;
  8115   XSETFRAME (frame, f);
  8116   record_unwind_protect (unwind_create_tip_frame, frame);
  8117 
  8118   f->terminal = dpyinfo->terminal;
  8119 
  8120   /* By setting the output method, we're essentially saying that
  8121      the frame is live, as per FRAME_LIVE_P.  If we get a signal
  8122      from this point on, x_destroy_window might screw up reference
  8123      counts etc.  */
  8124   f->output_method = output_x_window;
  8125   f->output_data.x = xzalloc (sizeof *f->output_data.x);
  8126   f->output_data.x->icon_bitmap = -1;
  8127   FRAME_FONTSET (f) = -1;
  8128   f->output_data.x->scroll_bar_foreground_pixel = -1;
  8129   f->output_data.x->scroll_bar_background_pixel = -1;
  8130 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
  8131   f->output_data.x->scroll_bar_top_shadow_pixel = -1;
  8132   f->output_data.x->scroll_bar_bottom_shadow_pixel = -1;
  8133 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
  8134   f->output_data.x->white_relief.pixel = -1;
  8135   f->output_data.x->black_relief.pixel = -1;
  8136 
  8137   f->tooltip = true;
  8138   fset_icon_name (f, Qnil);
  8139   FRAME_DISPLAY_INFO (f) = dpyinfo;
  8140   f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
  8141   f->output_data.x->explicit_parent = false;
  8142 
  8143   /* These colors will be set anyway later, but it's important
  8144      to get the color reference counts right, so initialize them!  */
  8145   {
  8146     Lisp_Object black;
  8147 
  8148     /* Function x_decode_color can signal an error.  Make
  8149        sure to initialize color slots so that we won't try
  8150        to free colors we haven't allocated.  */
  8151     FRAME_FOREGROUND_PIXEL (f) = -1;
  8152     FRAME_BACKGROUND_PIXEL (f) = -1;
  8153     f->output_data.x->cursor_pixel = -1;
  8154     f->output_data.x->cursor_foreground_pixel = -1;
  8155     f->output_data.x->border_pixel = -1;
  8156     f->output_data.x->mouse_pixel = -1;
  8157 
  8158     black = build_string ("black");
  8159     FRAME_FOREGROUND_PIXEL (f)
  8160       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  8161     FRAME_BACKGROUND_PIXEL (f)
  8162       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  8163     f->output_data.x->cursor_pixel
  8164       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  8165     f->output_data.x->cursor_foreground_pixel
  8166       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  8167     f->output_data.x->border_pixel
  8168       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  8169     f->output_data.x->mouse_pixel
  8170       = x_decode_color (f, black, BLACK_PIX_DEFAULT (f));
  8171   }
  8172 
  8173   /* Set the name; the functions to which we pass f expect the name to
  8174      be set.  */
  8175   if (BASE_EQ (name, Qunbound) || NILP (name))
  8176     {
  8177       fset_name (f, build_string (dpyinfo->x_id_name));
  8178       f->explicit_name = false;
  8179     }
  8180   else
  8181     {
  8182       fset_name (f, name);
  8183       f->explicit_name = true;
  8184       /* use the frame's title when getting resources for this frame.  */
  8185       specbind (Qx_resource_name, name);
  8186     }
  8187 
  8188 #ifdef USE_CAIRO
  8189   register_font_driver (&ftcrfont_driver, f);
  8190 #ifdef HAVE_HARFBUZZ
  8191   register_font_driver (&ftcrhbfont_driver, f);
  8192 #endif  /* HAVE_HARFBUZZ */
  8193 #else
  8194 #ifdef HAVE_FREETYPE
  8195 #ifdef HAVE_XFT
  8196   register_font_driver (&xftfont_driver, f);
  8197 #ifdef HAVE_HARFBUZZ
  8198   register_font_driver (&xfthbfont_driver, f);
  8199 #endif
  8200 #endif  /* not HAVE_XFT */
  8201 #endif  /* HAVE_FREETYPE */
  8202 #endif  /* not USE_CAIRO */
  8203   register_font_driver (&xfont_driver, f);
  8204 
  8205   image_cache_refcount =
  8206     FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
  8207 #ifdef GLYPH_DEBUG
  8208   dpyinfo_refcount = dpyinfo->reference_count;
  8209 #endif /* GLYPH_DEBUG */
  8210 
  8211   gui_default_parameter (f, parms, Qfont_backend, Qnil,
  8212                          "fontBackend", "FontBackend", RES_TYPE_STRING);
  8213 
  8214   /* Extract the window parameters from the supplied values that are
  8215      needed to determine window geometry.  */
  8216   x_default_font_parameter (f, parms);
  8217 
  8218   gui_default_parameter (f, parms, Qborder_width, make_fixnum (0),
  8219                          "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
  8220 
  8221   /* This defaults to 1 in order to match xterm.  We recognize either
  8222      internalBorderWidth or internalBorder (which is what xterm calls
  8223      it).  */
  8224   if (NILP (Fassq (Qinternal_border_width, parms)))
  8225     {
  8226       Lisp_Object value;
  8227 
  8228       value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width,
  8229                                    "internalBorder", "internalBorder",
  8230                                    RES_TYPE_NUMBER);
  8231       if (! BASE_EQ (value, Qunbound))
  8232         parms = Fcons (Fcons (Qinternal_border_width, value),
  8233                        parms);
  8234     }
  8235 
  8236   gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (1),
  8237                          "internalBorderWidth", "internalBorderWidth",
  8238                          RES_TYPE_NUMBER);
  8239   gui_default_parameter (f, parms, Qright_divider_width, make_fixnum (0),
  8240                          NULL, NULL, RES_TYPE_NUMBER);
  8241   gui_default_parameter (f, parms, Qbottom_divider_width, make_fixnum (0),
  8242                          NULL, NULL, RES_TYPE_NUMBER);
  8243 
  8244   /* Also do the stuff which must be set before the window exists.  */
  8245   gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
  8246                          "foreground", "Foreground", RES_TYPE_STRING);
  8247   gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
  8248                          "background", "Background", RES_TYPE_STRING);
  8249   gui_default_parameter (f, parms, Qmouse_color, build_string ("black"),
  8250                          "pointerColor", "Foreground", RES_TYPE_STRING);
  8251   gui_default_parameter (f, parms, Qcursor_color, build_string ("black"),
  8252                          "cursorColor", "Foreground", RES_TYPE_STRING);
  8253   gui_default_parameter (f, parms, Qborder_color, build_string ("black"),
  8254                          "borderColor", "BorderColor", RES_TYPE_STRING);
  8255   gui_default_parameter (f, parms, Qno_special_glyphs, Qnil,
  8256                          NULL, NULL, RES_TYPE_BOOLEAN);
  8257 
  8258   {
  8259 #ifndef USE_XCB
  8260     XSetWindowAttributes attrs;
  8261     unsigned long mask;
  8262     Atom type = FRAME_DISPLAY_INFO (f)->Xatom_net_window_type_tooltip;
  8263 
  8264     block_input ();
  8265     mask = (CWBackPixel | CWOverrideRedirect | CWEventMask
  8266             | CWCursor | CWColormap | CWBorderPixel);
  8267     if (DoesSaveUnders (dpyinfo->screen))
  8268       mask |= CWSaveUnder;
  8269 
  8270     /* Window managers look at the override-redirect flag to determine
  8271        whether or net to give windows a decoration (Xlib spec, chapter
  8272        3.2.8).  */
  8273     attrs.override_redirect = True;
  8274     attrs.save_under = True;
  8275     attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
  8276     attrs.colormap = FRAME_X_COLORMAP (f);
  8277     attrs.cursor =
  8278       f->output_data.x->current_cursor
  8279       = f->output_data.x->text_cursor;
  8280     attrs.border_pixel = f->output_data.x->border_pixel;
  8281     /* Arrange for getting MapNotify and UnmapNotify events.  */
  8282     attrs.event_mask = StructureNotifyMask;
  8283     tip_window
  8284       = FRAME_X_WINDOW (f)
  8285       = XCreateWindow (FRAME_X_DISPLAY (f),
  8286                        FRAME_DISPLAY_INFO (f)->root_window,
  8287                        /* x, y, width, height */
  8288                        0, 0, 1, 1,
  8289                        /* Border.  */
  8290                        f->border_width,
  8291                        dpyinfo->n_planes, InputOutput,
  8292                        FRAME_X_VISUAL (f),
  8293                        mask, &attrs);
  8294     initial_set_up_x_back_buffer (f);
  8295     XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
  8296                      FRAME_DISPLAY_INFO (f)->Xatom_net_window_type,
  8297                      XA_ATOM, 32, PropModeReplace,
  8298                      (unsigned char *)&type, 1);
  8299     unblock_input ();
  8300 #else
  8301     uint32_t value_list[6];
  8302     xcb_atom_t net_wm_window_type_tooltip
  8303       = (xcb_atom_t) dpyinfo->Xatom_net_window_type_tooltip;
  8304     xcb_visualid_t visual_id
  8305       = (xcb_visualid_t) XVisualIDFromVisual (FRAME_X_VISUAL (f));
  8306 
  8307     f->output_data.x->current_cursor = f->output_data.x->text_cursor;
  8308     /* Values are set in the order of their enumeration in `enum
  8309        xcb_cw_t'.  */
  8310     value_list[0] = FRAME_BACKGROUND_PIXEL (f);
  8311     value_list[1] = f->output_data.x->border_pixel;
  8312     value_list[2] = true;
  8313     value_list[3] = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
  8314     value_list[4] = (xcb_colormap_t) FRAME_X_COLORMAP (f);
  8315     value_list[5] = (xcb_cursor_t) f->output_data.x->text_cursor;
  8316 
  8317     block_input ();
  8318     tip_window
  8319       = FRAME_X_WINDOW (f)
  8320       = (Window) xcb_generate_id (dpyinfo->xcb_connection);
  8321 
  8322     xcb_create_window (dpyinfo->xcb_connection,
  8323                        dpyinfo->n_planes,
  8324                        (xcb_window_t) tip_window,
  8325                        (xcb_window_t) dpyinfo->root_window,
  8326                        0, 0, 1, 1, f->border_width,
  8327                        XCB_WINDOW_CLASS_INPUT_OUTPUT,
  8328                        visual_id,
  8329                        (XCB_CW_BACK_PIXEL
  8330                         | XCB_CW_BORDER_PIXEL
  8331                         | XCB_CW_OVERRIDE_REDIRECT
  8332                         | XCB_CW_EVENT_MASK
  8333                         | XCB_CW_COLORMAP
  8334                         | XCB_CW_CURSOR),
  8335                        &value_list);
  8336 
  8337     xcb_change_property (dpyinfo->xcb_connection,
  8338                          XCB_PROP_MODE_REPLACE,
  8339                          (xcb_window_t) tip_window,
  8340                          (xcb_atom_t) dpyinfo->Xatom_net_window_type,
  8341                          (xcb_atom_t) dpyinfo->Xatom_ATOM,
  8342                          32, 1, &net_wm_window_type_tooltip);
  8343 
  8344     initial_set_up_x_back_buffer (f);
  8345     unblock_input ();
  8346 #endif
  8347   }
  8348 
  8349   /* Init faces before gui_default_parameter is called for the
  8350      scroll-bar-width parameter because otherwise we end up in
  8351      init_iterator with a null face cache, which should not happen.  */
  8352   init_frame_faces (f);
  8353 
  8354   gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
  8355                          "inhibitDoubleBuffering", "InhibitDoubleBuffering",
  8356                          RES_TYPE_BOOLEAN);
  8357 
  8358   gui_figure_window_size (f, parms, false, false);
  8359 
  8360   f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
  8361 
  8362   x_make_gc (f);
  8363 
  8364   gui_default_parameter (f, parms, Qauto_raise, Qnil,
  8365                          "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
  8366   gui_default_parameter (f, parms, Qauto_lower, Qnil,
  8367                          "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
  8368   gui_default_parameter (f, parms, Qcursor_type, Qbox,
  8369                          "cursorType", "CursorType", RES_TYPE_SYMBOL);
  8370   gui_default_parameter (f, parms, Qalpha, Qnil,
  8371                          "alpha", "Alpha", RES_TYPE_NUMBER);
  8372   gui_default_parameter (f, parms, Qalpha_background, Qnil,
  8373                          "alphaBackground", "AlphaBackground", RES_TYPE_NUMBER);
  8374 
  8375   /* Add `tooltip' frame parameter's default value. */
  8376   if (NILP (Fframe_parameter (frame, Qtooltip)))
  8377     {
  8378       AUTO_FRAME_ARG (arg, Qtooltip, Qt);
  8379       Fmodify_frame_parameters (frame, arg);
  8380     }
  8381 
  8382   /* FIXME - can this be done in a similar way to normal frames?
  8383      https://lists.gnu.org/r/emacs-devel/2007-10/msg00641.html */
  8384 
  8385   /* Set the `display-type' frame parameter before setting up faces. */
  8386   {
  8387     Lisp_Object disptype;
  8388 
  8389     if (FRAME_DISPLAY_INFO (f)->n_planes == 1)
  8390       disptype = Qmono;
  8391     else if (FRAME_X_VISUAL_INFO (f)->class == GrayScale
  8392              || FRAME_X_VISUAL_INFO (f)->class == StaticGray)
  8393       disptype = Qgrayscale;
  8394     else
  8395       disptype = Qcolor;
  8396 
  8397     if (NILP (Fframe_parameter (frame, Qdisplay_type)))
  8398       {
  8399         AUTO_FRAME_ARG (arg, Qdisplay_type, disptype);
  8400         Fmodify_frame_parameters (frame, arg);
  8401       }
  8402   }
  8403 
  8404   /* Set up faces after all frame parameters are known.  This call
  8405      also merges in face attributes specified for new frames.
  8406 
  8407      Frame parameters may be changed if .Xdefaults contains
  8408      specifications for the default font.  For example, if there is an
  8409      `Emacs.default.attributeBackground: pink', the `background-color'
  8410      attribute of the frame gets set, which let's the internal border
  8411      of the tooltip frame appear in pink.  Prevent this.  */
  8412   {
  8413     Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
  8414 
  8415     call2 (Qface_set_after_frame_default, frame, Qnil);
  8416 
  8417     if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
  8418       {
  8419         AUTO_FRAME_ARG (arg, Qbackground_color, bg);
  8420         Fmodify_frame_parameters (frame, arg);
  8421       }
  8422   }
  8423 
  8424   f->no_split = true;
  8425 
  8426   /* Now that the frame will be official, it counts as a reference to
  8427      its display and terminal.  */
  8428   FRAME_DISPLAY_INFO (f)->reference_count++;
  8429   f->terminal->reference_count++;
  8430 
  8431   /* It is now ok to make the frame official even if we get an error
  8432      below.  And the frame needs to be on Vframe_list or making it
  8433      visible won't work.  */
  8434   Vframe_list = Fcons (frame, Vframe_list);
  8435   f->can_set_window_size = true;
  8436   adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
  8437                      0, true, Qtip_frame);
  8438 
  8439   /* Setting attributes of faces of the tooltip frame from resources
  8440      and similar will set face_change, which leads to the clearing of
  8441      all current matrices.  Since this isn't necessary here, avoid it
  8442      by resetting face_change to the value it had before we created
  8443      the tip frame.  */
  8444   face_change = face_change_before;
  8445 
  8446   /* Discard the unwind_protect.  */
  8447   return unbind_to (count, frame);
  8448 }
  8449 
  8450 
  8451 /* Compute where to display tip frame F.  PARMS is the list of frame
  8452    parameters for F.  DX and DY are specified offsets from the current
  8453    location of the mouse.  WIDTH and HEIGHT are the width and height
  8454    of the tooltip.  Return coordinates relative to the root window of
  8455    the display in *ROOT_X, and *ROOT_Y.  */
  8456 
  8457 static void
  8458 compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx,
  8459                 Lisp_Object dy, int width, int height, int *root_x,
  8460                 int *root_y)
  8461 {
  8462   Lisp_Object left, top, right, bottom;
  8463   int win_x, win_y;
  8464   Window root, child;
  8465   unsigned pmask;
  8466   int min_x, min_y, max_x, max_y = -1;
  8467 
  8468   /* User-specified position?  */
  8469   left = CDR (Fassq (Qleft, parms));
  8470   top  = CDR (Fassq (Qtop, parms));
  8471   right = CDR (Fassq (Qright, parms));
  8472   bottom = CDR (Fassq (Qbottom, parms));
  8473 
  8474   /* Move the tooltip window where the mouse pointer is.  Resize and
  8475      show it.  */
  8476   if ((!FIXNUMP (left) && !FIXNUMP (right))
  8477       || (!FIXNUMP (top) && !FIXNUMP (bottom)))
  8478     {
  8479       Lisp_Object frame, attributes, monitor, geometry;
  8480 
  8481       block_input ();
  8482       x_query_pointer (FRAME_X_DISPLAY (f), FRAME_DISPLAY_INFO (f)->root_window,
  8483                        &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
  8484       unblock_input ();
  8485 
  8486       XSETFRAME (frame, f);
  8487 
  8488 #if defined HAVE_XRANDR || defined USE_GTK
  8489       if (!NILP (FRAME_DISPLAY_INFO (f)->last_monitor_attributes_list))
  8490         /* Use cached values if available to avoid fetching the
  8491            monitor list from the X server.  If XRandR is not
  8492            available, then fetching the attributes will probably not
  8493            sync anyway, and will thus be relatively harmless.  */
  8494         attributes = FRAME_DISPLAY_INFO (f)->last_monitor_attributes_list;
  8495       else
  8496 #endif
  8497         attributes = Fx_display_monitor_attributes_list (frame);
  8498 
  8499       /* Try to determine the monitor where the mouse pointer is and
  8500          its geometry.  See bug#22549.  */
  8501       while (CONSP (attributes))
  8502         {
  8503           monitor = XCAR (attributes);
  8504           geometry = Fassq (Qgeometry, monitor);
  8505           if (CONSP (geometry))
  8506             {
  8507               min_x = XFIXNUM (Fnth (make_fixnum (1), geometry));
  8508               min_y = XFIXNUM (Fnth (make_fixnum (2), geometry));
  8509               max_x = min_x + XFIXNUM (Fnth (make_fixnum (3), geometry));
  8510               max_y = min_y + XFIXNUM (Fnth (make_fixnum (4), geometry));
  8511 
  8512               if (min_x <= *root_x && *root_x < max_x
  8513                   && min_y <= *root_y && *root_y < max_y)
  8514                 {
  8515                   break;
  8516                 }
  8517 
  8518               max_y = -1;
  8519             }
  8520 
  8521           attributes = XCDR (attributes);
  8522         }
  8523     }
  8524 
  8525   /* It was not possible to determine the monitor's geometry, so we
  8526      assign some sane defaults here: */
  8527   if (max_y < 0)
  8528     {
  8529       min_x = 0;
  8530       min_y = 0;
  8531       max_x = x_display_pixel_width (FRAME_DISPLAY_INFO (f));
  8532       max_y = x_display_pixel_height (FRAME_DISPLAY_INFO (f));
  8533     }
  8534 
  8535   if (FIXNUMP (top))
  8536     *root_y = XFIXNUM (top);
  8537   else if (FIXNUMP (bottom))
  8538     *root_y = XFIXNUM (bottom) - height;
  8539   else if (*root_y + XFIXNUM (dy) <= min_y)
  8540     *root_y = min_y; /* Can happen for negative dy */
  8541   else if (*root_y + XFIXNUM (dy) + height <= max_y)
  8542     /* It fits below the pointer */
  8543     *root_y += XFIXNUM (dy);
  8544   else if (height + XFIXNUM (dy) + min_y <= *root_y)
  8545     /* It fits above the pointer.  */
  8546     *root_y -= height + XFIXNUM (dy);
  8547   else
  8548     /* Put it on the top.  */
  8549     *root_y = min_y;
  8550 
  8551   if (FIXNUMP (left))
  8552     *root_x = XFIXNUM (left);
  8553   else if (FIXNUMP (right))
  8554     *root_x = XFIXNUM (right) - width;
  8555   else if (*root_x + XFIXNUM (dx) <= min_x)
  8556     *root_x = 0; /* Can happen for negative dx */
  8557   else if (*root_x + XFIXNUM (dx) + width <= max_x)
  8558     /* It fits to the right of the pointer.  */
  8559     *root_x += XFIXNUM (dx);
  8560   else if (width + XFIXNUM (dx) + min_x <= *root_x)
  8561     /* It fits to the left of the pointer.  */
  8562     *root_x -= width + XFIXNUM (dx);
  8563   else
  8564     /* Put it left justified on the screen -- it ought to fit that way.  */
  8565     *root_x = min_x;
  8566 }
  8567 
  8568 
  8569 /**
  8570  * x_hide_tip:
  8571  *
  8572  * Hide currently visible tooltip and cancel its timer.
  8573  *
  8574  * If GTK+ system tooltips are used, this will try to hide the tooltip
  8575  * referenced by the x_output structure of tooltip_last_frame.  For
  8576  * Emacs tooltips this will try to make tooltip_frame invisible (if
  8577  * DELETE is false) or delete tooltip_frame (if DELETE is true).
  8578  *
  8579  * Return Qt if the tooltip was either deleted or made invisible, Qnil
  8580  * otherwise.
  8581  */
  8582 static Lisp_Object
  8583 x_hide_tip (bool delete)
  8584 {
  8585   if (!NILP (tip_timer))
  8586     {
  8587       call1 (Qcancel_timer, tip_timer);
  8588       tip_timer = Qnil;
  8589     }
  8590 
  8591 #ifdef USE_GTK
  8592   /* Any GTK+ system tooltip can be found via the x_output structure
  8593      of tip_last_frame, provided that frame is still live.  Any Emacs
  8594      tooltip is found via the tip_frame variable.  Note that the
  8595      current value of use_system_tooltips might not be the same as
  8596      used for the tooltip we have to hide, see Bug#30399.  */
  8597   if ((NILP (tip_last_frame) && NILP (tip_frame))
  8598       || (!use_system_tooltips
  8599           && !delete
  8600           && !NILP (tip_frame)
  8601           && FRAME_LIVE_P (XFRAME (tip_frame))
  8602           && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
  8603     /* Either there's no tooltip to hide or it's an already invisible
  8604        Emacs tooltip and we don't want to change its type.  Return
  8605        quickly.  */
  8606     return Qnil;
  8607   else
  8608     {
  8609       Lisp_Object was_open = Qnil;
  8610 
  8611       specpdl_ref count = SPECPDL_INDEX ();
  8612       specbind (Qinhibit_redisplay, Qt);
  8613       specbind (Qinhibit_quit, Qt);
  8614 
  8615       /* Try to hide the GTK+ system tip first.  */
  8616       if (!NILP (tip_last_frame))
  8617         {
  8618           struct frame *f = XFRAME (tip_last_frame);
  8619 
  8620           if (FRAME_LIVE_P (f))
  8621             {
  8622               if (xg_hide_tooltip (f))
  8623                 was_open = Qt;
  8624             }
  8625         }
  8626 
  8627       /* When using GTK+ system tooltips (compare Bug#41200) reset
  8628          tip_last_frame.  It will be reassigned when showing the next
  8629          GTK+ system tooltip.  */
  8630       if (use_system_tooltips)
  8631         tip_last_frame = Qnil;
  8632 
  8633       /* Now look whether there's an Emacs tip around.  */
  8634       if (!NILP (tip_frame))
  8635         {
  8636           struct frame *f = XFRAME (tip_frame);
  8637 
  8638           if (FRAME_LIVE_P (f))
  8639             {
  8640               if (delete || use_system_tooltips)
  8641                 {
  8642                   /* Delete the Emacs tooltip frame when DELETE is true
  8643                      or we change the tooltip type from an Emacs one to
  8644                      a GTK+ system one.  */
  8645                   delete_frame (tip_frame, Qnil);
  8646                   tip_frame = Qnil;
  8647                 }
  8648               else
  8649                 x_make_frame_invisible (f);
  8650 
  8651               was_open = Qt;
  8652             }
  8653           else
  8654             tip_frame = Qnil;
  8655         }
  8656       else
  8657         tip_frame = Qnil;
  8658 
  8659       return unbind_to (count, was_open);
  8660     }
  8661 #else /* not USE_GTK */
  8662   if (NILP (tip_frame)
  8663       || (!delete
  8664           && !NILP (tip_frame)
  8665           && FRAME_LIVE_P (XFRAME (tip_frame))
  8666           && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
  8667     return Qnil;
  8668   else
  8669     {
  8670       Lisp_Object was_open = Qnil;
  8671 
  8672       specpdl_ref count = SPECPDL_INDEX ();
  8673       specbind (Qinhibit_redisplay, Qt);
  8674       specbind (Qinhibit_quit, Qt);
  8675 
  8676       if (!NILP (tip_frame))
  8677         {
  8678           struct frame *f = XFRAME (tip_frame);
  8679 
  8680           if (FRAME_LIVE_P (f))
  8681             {
  8682               if (delete)
  8683                 {
  8684                   delete_frame (tip_frame, Qnil);
  8685                   tip_frame = Qnil;
  8686                 }
  8687               else
  8688                 x_make_frame_invisible (XFRAME (tip_frame));
  8689 
  8690               was_open = Qt;
  8691             }
  8692           else
  8693             tip_frame = Qnil;
  8694         }
  8695       else
  8696         tip_frame = Qnil;
  8697 
  8698       return unbind_to (count, was_open);
  8699     }
  8700 #endif /* USE_GTK */
  8701 }
  8702 
  8703 
  8704 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
  8705        doc: /* Show STRING in a "tooltip" window on frame FRAME.
  8706 A tooltip window is a small X window displaying a string.
  8707 
  8708 This is an internal function; Lisp code should call `tooltip-show'.
  8709 
  8710 FRAME nil or omitted means use the selected frame.
  8711 
  8712 PARMS is an optional list of frame parameters which can be used to
  8713 change the tooltip's appearance.
  8714 
  8715 Automatically hide the tooltip after TIMEOUT seconds.  TIMEOUT nil
  8716 means use the default timeout from the `x-show-tooltip-timeout'
  8717 variable.
  8718 
  8719 If the list of frame parameters PARMS contains a `left' parameter,
  8720 display the tooltip at that x-position.  If the list of frame parameters
  8721 PARMS contains no `left' but a `right' parameter, display the tooltip
  8722 right-adjusted at that x-position. Otherwise display it at the
  8723 x-position of the mouse, with offset DX added (default is 5 if DX isn't
  8724 specified).
  8725 
  8726 Likewise for the y-position: If a `top' frame parameter is specified, it
  8727 determines the position of the upper edge of the tooltip window.  If a
  8728 `bottom' parameter but no `top' frame parameter is specified, it
  8729 determines the position of the lower edge of the tooltip window.
  8730 Otherwise display the tooltip window at the y-position of the mouse,
  8731 with offset DY added (default is -10).
  8732 
  8733 A tooltip's maximum size is specified by `x-max-tooltip-size'.
  8734 Text larger than the specified size is clipped.  */)
  8735   (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
  8736    Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
  8737 {
  8738   struct frame *f, *tip_f;
  8739   struct window *w;
  8740   int root_x, root_y;
  8741   struct buffer *old_buffer;
  8742   struct text_pos pos;
  8743   int width, height;
  8744   int old_windows_or_buffers_changed = windows_or_buffers_changed;
  8745   specpdl_ref count = SPECPDL_INDEX ();
  8746   Lisp_Object window, size, tip_buf;
  8747   bool displayed;
  8748 #ifdef ENABLE_CHECKING
  8749   struct glyph_row *row, *end;
  8750 #endif
  8751   AUTO_STRING (tip, " *tip*");
  8752 
  8753   specbind (Qinhibit_redisplay, Qt);
  8754 
  8755   CHECK_STRING (string);
  8756   if (SCHARS (string) == 0)
  8757     string = make_unibyte_string (" ", 1);
  8758 
  8759   if (NILP (frame))
  8760     frame = selected_frame;
  8761   f = decode_window_system_frame (frame);
  8762 
  8763   if (NILP (timeout))
  8764     timeout = Vx_show_tooltip_timeout;
  8765   CHECK_FIXNAT (timeout);
  8766 
  8767   if (NILP (dx))
  8768     dx = make_fixnum (5);
  8769   else
  8770     CHECK_FIXNUM (dx);
  8771 
  8772   if (NILP (dy))
  8773     dy = make_fixnum (-10);
  8774   else
  8775     CHECK_FIXNUM (dy);
  8776 
  8777   tip_dx = dx;
  8778   tip_dy = dy;
  8779 
  8780 #ifdef USE_GTK
  8781   if (use_system_tooltips)
  8782     {
  8783       bool ok;
  8784 
  8785       /* Hide a previous tip, if any.  */
  8786       Fx_hide_tip ();
  8787 
  8788       block_input ();
  8789       ok = xg_prepare_tooltip (f, string, &width, &height);
  8790       if (ok)
  8791         {
  8792           compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
  8793           xg_show_tooltip (f, root_x, root_y);
  8794           tip_last_frame = frame;
  8795         }
  8796 
  8797       unblock_input ();
  8798       if (ok) goto start_timer;
  8799     }
  8800 #endif /* USE_GTK */
  8801 
  8802   if (!NILP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
  8803     {
  8804       if (FRAME_VISIBLE_P (XFRAME (tip_frame))
  8805           && (FRAME_X_DISPLAY (XFRAME (frame))
  8806               == FRAME_X_DISPLAY (XFRAME (tip_last_frame)))
  8807           && !NILP (Fequal_including_properties (tip_last_string, string))
  8808           && !NILP (Fequal (tip_last_parms, parms)))
  8809         {
  8810           /* Only DX and DY have changed.  */
  8811           tip_f = XFRAME (tip_frame);
  8812           if (!NILP (tip_timer))
  8813             {
  8814               call1 (Qcancel_timer, tip_timer);
  8815               tip_timer = Qnil;
  8816             }
  8817 
  8818           block_input ();
  8819           compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
  8820                           FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
  8821           XMoveWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
  8822                        root_x, root_y);
  8823           unblock_input ();
  8824 
  8825           goto start_timer;
  8826         }
  8827       else if (tooltip_reuse_hidden_frame && BASE_EQ (frame, tip_last_frame))
  8828         {
  8829           bool delete = false;
  8830           Lisp_Object tail, elt, parm, last;
  8831 
  8832           /* Check if every parameter in PARMS has the same value in
  8833              tip_last_parms.  This may destruct tip_last_parms which,
  8834              however, will be recreated below.  */
  8835           for (tail = parms; CONSP (tail); tail = XCDR (tail))
  8836             {
  8837               elt = XCAR (tail);
  8838               parm = CAR (elt);
  8839               /* The left, top, right and bottom parameters are handled
  8840                  by compute_tip_xy so they can be ignored here.  */
  8841               if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
  8842                   && !EQ (parm, Qright) && !EQ (parm, Qbottom))
  8843                 {
  8844                   last = Fassq (parm, tip_last_parms);
  8845                   if (NILP (Fequal (CDR (elt), CDR (last))))
  8846                     {
  8847                       /* We lost, delete the old tooltip.  */
  8848                       delete = true;
  8849                       break;
  8850                     }
  8851                   else
  8852                     tip_last_parms =
  8853                       call2 (Qassq_delete_all, parm, tip_last_parms);
  8854                 }
  8855               else
  8856                 tip_last_parms =
  8857                   call2 (Qassq_delete_all, parm, tip_last_parms);
  8858             }
  8859 
  8860           /* Now check if every parameter in what is left of
  8861              tip_last_parms with a non-nil value has an association in
  8862              PARMS.  */
  8863           for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
  8864             {
  8865               elt = XCAR (tail);
  8866               parm = CAR (elt);
  8867               if (!EQ (parm, Qleft) && !EQ (parm, Qtop) && !EQ (parm, Qright)
  8868                   && !EQ (parm, Qbottom) && !NILP (CDR (elt)))
  8869                 {
  8870                   /* We lost, delete the old tooltip.  */
  8871                   delete = true;
  8872                   break;
  8873                 }
  8874             }
  8875 
  8876           x_hide_tip (delete);
  8877         }
  8878       else
  8879         x_hide_tip (true);
  8880     }
  8881   else
  8882     x_hide_tip (true);
  8883 
  8884   tip_last_frame = frame;
  8885   tip_last_string = string;
  8886   tip_last_parms = parms;
  8887 
  8888   if (NILP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
  8889     {
  8890       /* Add default values to frame parameters.  */
  8891       if (NILP (Fassq (Qname, parms)))
  8892         parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
  8893       if (NILP (Fassq (Qinternal_border_width, parms)))
  8894         parms = Fcons (Fcons (Qinternal_border_width, make_fixnum (3)), parms);
  8895       if (NILP (Fassq (Qborder_width, parms)))
  8896         parms = Fcons (Fcons (Qborder_width, make_fixnum (1)), parms);
  8897       if (NILP (Fassq (Qborder_color, parms)))
  8898         parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
  8899       if (NILP (Fassq (Qbackground_color, parms)))
  8900         parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
  8901                        parms);
  8902 
  8903       /* Create a frame for the tooltip, and record it in the global
  8904          variable tip_frame.  */
  8905       if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms)))
  8906         /* Creating the tip frame failed.  */
  8907         return unbind_to (count, Qnil);
  8908     }
  8909 
  8910   tip_f = XFRAME (tip_frame);
  8911   window = FRAME_ROOT_WINDOW (tip_f);
  8912   tip_buf = Fget_buffer_create (tip, Qnil);
  8913   /* We will mark the tip window a "pseudo-window" below, and such
  8914      windows cannot have display margins.  */
  8915   bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
  8916   bset_right_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
  8917   set_window_buffer (window, tip_buf, false, false);
  8918   w = XWINDOW (window);
  8919   w->pseudo_window_p = true;
  8920   /* Try to avoid that `other-window' select us (Bug#47207).  */
  8921   Fset_window_parameter (window, Qno_other_window, Qt);
  8922 
  8923   /* Set up the frame's root window.  Note: The following code does not
  8924      try to size the window or its frame correctly.  Its only purpose is
  8925      to make the subsequent text size calculations work.  The right
  8926      sizes should get installed when the toolkit gets back to us.  */
  8927   w->left_col = 0;
  8928   w->top_line = 0;
  8929   w->pixel_left = 0;
  8930   w->pixel_top = 0;
  8931 
  8932   if (CONSP (Vx_max_tooltip_size)
  8933       && RANGED_FIXNUMP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
  8934       && RANGED_FIXNUMP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
  8935     {
  8936       w->total_cols = XFIXNAT (XCAR (Vx_max_tooltip_size));
  8937       w->total_lines = XFIXNAT (XCDR (Vx_max_tooltip_size));
  8938     }
  8939   else
  8940     {
  8941       w->total_cols = 80;
  8942       w->total_lines = 40;
  8943     }
  8944 
  8945   w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f);
  8946   w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f);
  8947   FRAME_TOTAL_COLS (tip_f) = w->total_cols;
  8948   adjust_frame_glyphs (tip_f);
  8949 
  8950   /* Insert STRING into root window's buffer and fit the frame to the
  8951      buffer.  */
  8952   specpdl_ref count_1 = SPECPDL_INDEX ();
  8953   old_buffer = current_buffer;
  8954   set_buffer_internal_1 (XBUFFER (w->contents));
  8955   bset_truncate_lines (current_buffer, Qnil);
  8956   specbind (Qinhibit_read_only, Qt);
  8957   specbind (Qinhibit_modification_hooks, Qt);
  8958   specbind (Qinhibit_point_motion_hooks, Qt);
  8959   Ferase_buffer ();
  8960   Finsert (1, &string);
  8961   clear_glyph_matrix (w->desired_matrix);
  8962   clear_glyph_matrix (w->current_matrix);
  8963   SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
  8964   displayed = try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
  8965 
  8966   if (!displayed && NILP (Vx_max_tooltip_size))
  8967     {
  8968 #ifdef ENABLE_CHECKING
  8969       row = w->desired_matrix->rows;
  8970       end = w->desired_matrix->rows + w->desired_matrix->nrows;
  8971 
  8972       while (row < end)
  8973         {
  8974           if (!row->displays_text_p
  8975               || row->ends_at_zv_p)
  8976             break;
  8977           ++row;
  8978         }
  8979 
  8980       eassert (row < end && row->ends_at_zv_p);
  8981 #endif
  8982     }
  8983 
  8984   /* Calculate size of tooltip window.  */
  8985   size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil,
  8986                                   make_fixnum (w->pixel_height), Qnil,
  8987                                   Qnil);
  8988   /* Add the frame's internal border to calculated size.  */
  8989   width = XFIXNUM (CAR (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
  8990   height = XFIXNUM (CDR (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
  8991 
  8992   /* Calculate position of tooltip frame.  */
  8993   compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y);
  8994 
  8995   /* Show tooltip frame.  */
  8996   block_input ();
  8997 #ifndef USE_XCB
  8998   XMoveResizeWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
  8999                      root_x, root_y, width, height);
  9000   XMapRaised (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f));
  9001 #else
  9002   uint32_t values[] = { root_x, root_y, width, height, XCB_STACK_MODE_ABOVE };
  9003 
  9004   xcb_configure_window (FRAME_DISPLAY_INFO (tip_f)->xcb_connection,
  9005                         (xcb_window_t) FRAME_X_WINDOW (tip_f),
  9006                         (XCB_CONFIG_WINDOW_X
  9007                          | XCB_CONFIG_WINDOW_Y
  9008                          | XCB_CONFIG_WINDOW_WIDTH
  9009                          | XCB_CONFIG_WINDOW_HEIGHT
  9010                          | XCB_CONFIG_WINDOW_STACK_MODE), &values);
  9011   xcb_map_window (FRAME_DISPLAY_INFO (tip_f)->xcb_connection,
  9012                   (xcb_window_t) FRAME_X_WINDOW (tip_f));
  9013 #endif
  9014   unblock_input ();
  9015 
  9016 #ifdef USE_CAIRO
  9017   x_cr_update_surface_desired_size (tip_f, width, height);
  9018 #endif  /* USE_CAIRO */
  9019 
  9020   w->must_be_updated_p = true;
  9021   update_single_window (w);
  9022   flush_frame (tip_f);
  9023   set_buffer_internal_1 (old_buffer);
  9024   unbind_to (count_1, Qnil);
  9025   windows_or_buffers_changed = old_windows_or_buffers_changed;
  9026 
  9027  start_timer:
  9028   /* Let the tip disappear after timeout seconds.  */
  9029   tip_timer = call3 (Qrun_at_time, timeout, Qnil,
  9030                      Qx_hide_tip);
  9031 
  9032   return unbind_to (count, Qnil);
  9033 }
  9034 
  9035 
  9036 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
  9037        doc: /* Hide the current tooltip window, if there is any.
  9038 Value is t if tooltip was open, nil otherwise.  */)
  9039   (void)
  9040 {
  9041   return x_hide_tip (!tooltip_reuse_hidden_frame);
  9042 }
  9043 
  9044 DEFUN ("x-double-buffered-p", Fx_double_buffered_p, Sx_double_buffered_p,
  9045        0, 1, 0,
  9046        doc: /* Return t if FRAME is being double buffered.  */)
  9047      (Lisp_Object frame)
  9048 {
  9049 #ifdef HAVE_XDBE
  9050   struct frame *f = decode_live_frame (frame);
  9051   return FRAME_X_DOUBLE_BUFFERED_P (f) ? Qt : Qnil;
  9052 #else
  9053   return Qnil;
  9054 #endif
  9055 }
  9056 
  9057 
  9058 /***********************************************************************
  9059                         File selection dialog
  9060  ***********************************************************************/
  9061 
  9062 DEFUN ("x-uses-old-gtk-dialog", Fx_uses_old_gtk_dialog,
  9063        Sx_uses_old_gtk_dialog,
  9064        0, 0, 0,
  9065        doc: /* Return t if the old Gtk+ file selection dialog is used.  */)
  9066   (void)
  9067 {
  9068 #ifdef USE_GTK
  9069   if (use_dialog_box
  9070       && use_file_dialog
  9071       && window_system_available (SELECTED_FRAME ())
  9072       && xg_uses_old_file_dialog ())
  9073     return Qt;
  9074 #endif
  9075   return Qnil;
  9076 }
  9077 
  9078 
  9079 #ifdef USE_MOTIF
  9080 /* Callback for "OK" and "Cancel" on file selection dialog.  */
  9081 
  9082 static void
  9083 file_dialog_cb (Widget widget, XtPointer client_data, XtPointer call_data)
  9084 {
  9085   int *result = client_data;
  9086   XmAnyCallbackStruct *cb = call_data;
  9087   *result = cb->reason;
  9088 }
  9089 
  9090 
  9091 /* Callback for unmapping a file selection dialog.  This is used to
  9092    capture the case where a dialog is closed via a window manager's
  9093    closer button, for example. Using a XmNdestroyCallback didn't work
  9094    in this case.  */
  9095 
  9096 static void
  9097 file_dialog_unmap_cb (Widget widget, XtPointer client_data, XtPointer call_data)
  9098 {
  9099   int *result = client_data;
  9100   *result = XmCR_CANCEL;
  9101 }
  9102 
  9103 static void
  9104 clean_up_file_dialog (void *arg)
  9105 {
  9106   Widget dialog = arg;
  9107 
  9108   /* Clean up.  */
  9109   block_input ();
  9110   XtUnmanageChild (dialog);
  9111   XtDestroyWidget (dialog);
  9112   x_menu_set_in_use (false);
  9113   unblock_input ();
  9114 }
  9115 
  9116 
  9117 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
  9118        doc: /* SKIP: real doc in USE_GTK definition in xfns.c.  */)
  9119   (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename,
  9120    Lisp_Object mustmatch, Lisp_Object only_dir_p)
  9121 {
  9122   int result;
  9123   struct frame *f = SELECTED_FRAME ();
  9124   Lisp_Object file = Qnil;
  9125   Lisp_Object decoded_file;
  9126   Widget dialog, text, help;
  9127   Arg al[10];
  9128   int ac = 0;
  9129   XmString dir_xmstring, pattern_xmstring;
  9130   specpdl_ref count = SPECPDL_INDEX ();
  9131 
  9132   check_window_system (f);
  9133 
  9134   if (popup_activated ())
  9135     error ("Trying to use a menu from within a menu-entry");
  9136 
  9137   CHECK_STRING (prompt);
  9138   CHECK_STRING (dir);
  9139 
  9140   /* Prevent redisplay.  */
  9141   specbind (Qinhibit_redisplay, Qt);
  9142 
  9143   /* Defer selection requests.  */
  9144   DEFER_SELECTIONS;
  9145 
  9146   block_input ();
  9147 
  9148   /* Create the dialog with PROMPT as title, using DIR as initial
  9149      directory and using "*" as pattern.  */
  9150   dir = Fexpand_file_name (dir, Qnil);
  9151   dir_xmstring = XmStringCreateLocalized (SSDATA (dir));
  9152   pattern_xmstring = XmStringCreateLocalized ("*");
  9153 
  9154   XtSetArg (al[ac], XmNtitle, SDATA (prompt)); ++ac;
  9155   XtSetArg (al[ac], XmNdirectory, dir_xmstring); ++ac;
  9156   XtSetArg (al[ac], XmNpattern, pattern_xmstring); ++ac;
  9157   XtSetArg (al[ac], XmNresizePolicy, XmRESIZE_GROW); ++ac;
  9158   XtSetArg (al[ac], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); ++ac;
  9159   dialog = XmCreateFileSelectionDialog (f->output_data.x->widget,
  9160                                         "fsb", al, ac);
  9161   XmStringFree (dir_xmstring);
  9162   XmStringFree (pattern_xmstring);
  9163 
  9164   /* Add callbacks for OK and Cancel.  */
  9165   XtAddCallback (dialog, XmNokCallback, file_dialog_cb,
  9166                  (XtPointer) &result);
  9167   XtAddCallback (dialog, XmNcancelCallback, file_dialog_cb,
  9168                  (XtPointer) &result);
  9169   XtAddCallback (dialog, XmNunmapCallback, file_dialog_unmap_cb,
  9170                  (XtPointer) &result);
  9171 
  9172   /* Remove the help button since we can't display help.  */
  9173   help = XmFileSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON);
  9174   XtUnmanageChild (help);
  9175 
  9176   /* Mark OK button as default.  */
  9177   XtVaSetValues (XmFileSelectionBoxGetChild (dialog, XmDIALOG_OK_BUTTON),
  9178                  XmNshowAsDefault, True, NULL);
  9179 
  9180   /* If MUSTMATCH is non-nil, disable the file entry field of the
  9181      dialog, so that the user must select a file from the files list
  9182      box.  We can't remove it because we wouldn't have a way to get at
  9183      the result file name, then.  */
  9184   text = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
  9185   if (!NILP (mustmatch))
  9186     {
  9187       Widget label;
  9188       label = XmFileSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL);
  9189       XtSetSensitive (text, False);
  9190       XtSetSensitive (label, False);
  9191     }
  9192 
  9193   /* Manage the dialog, so that list boxes get filled.  */
  9194   XtManageChild (dialog);
  9195 
  9196   if (STRINGP (default_filename))
  9197     {
  9198       XmString default_xmstring;
  9199       Widget wtext = XmFileSelectionBoxGetChild (dialog, XmDIALOG_TEXT);
  9200       Widget list = XmFileSelectionBoxGetChild (dialog, XmDIALOG_LIST);
  9201 
  9202       XmTextPosition last_pos = XmTextFieldGetLastPosition (wtext);
  9203       XmTextFieldReplace (wtext, 0, last_pos,
  9204                           (SSDATA (Ffile_name_nondirectory (default_filename))));
  9205 
  9206       /* Select DEFAULT_FILENAME in the files list box.  DEFAULT_FILENAME
  9207          must include the path for this to work.  */
  9208 
  9209       default_xmstring = XmStringCreateLocalized (SSDATA (default_filename));
  9210 
  9211       if (XmListItemExists (list, default_xmstring))
  9212         {
  9213           int item_pos = XmListItemPos (list, default_xmstring);
  9214           /* Select the item and scroll it into view.  */
  9215           XmListSelectPos (list, item_pos, True);
  9216           XmListSetPos (list, item_pos);
  9217         }
  9218 
  9219       XmStringFree (default_xmstring);
  9220     }
  9221 
  9222   record_unwind_protect_ptr (clean_up_file_dialog, dialog);
  9223 
  9224   /* Process events until the user presses Cancel or OK.  */
  9225   x_menu_set_in_use (true);
  9226   result = 0;
  9227   while (result == 0)
  9228     {
  9229       XEvent event, copy;
  9230       x_menu_wait_for_event (0);
  9231 
  9232       if (XtAppPending (Xt_app_con))
  9233         {
  9234           XtAppNextEvent (Xt_app_con, &event);
  9235 
  9236           copy = event;
  9237           if (event.type == KeyPress
  9238               && FRAME_X_DISPLAY (f) == event.xkey.display)
  9239             {
  9240               KeySym keysym = XLookupKeysym (&event.xkey, 0);
  9241 
  9242               /* Pop down on C-g.  */
  9243               if (keysym == XK_g && (event.xkey.state & ControlMask) != 0)
  9244                 XtUnmanageChild (dialog);
  9245             }
  9246 #ifdef HAVE_XINPUT2
  9247           else if (event.type == GenericEvent
  9248                    && FRAME_X_DISPLAY (f) == event.xgeneric.display
  9249                    && FRAME_DISPLAY_INFO (f)->supports_xi2
  9250                    && (event.xgeneric.extension
  9251                        == FRAME_DISPLAY_INFO (f)->xi2_opcode)
  9252                    && event.xgeneric.evtype == XI_KeyPress)
  9253             {
  9254               KeySym keysym;
  9255               XIDeviceEvent *xev;
  9256 
  9257               if (event.xcookie.data)
  9258                 emacs_abort ();
  9259 
  9260               if (XGetEventData (FRAME_X_DISPLAY (f), &event.xcookie))
  9261                 {
  9262                   xev = (XIDeviceEvent *) event.xcookie.data;
  9263 
  9264                   copy.xkey.type = KeyPress;
  9265                   copy.xkey.serial = xev->serial;
  9266                   copy.xkey.send_event = xev->send_event;
  9267                   copy.xkey.display = FRAME_X_DISPLAY (f);
  9268                   copy.xkey.window = xev->event;
  9269                   copy.xkey.root = xev->root;
  9270                   copy.xkey.subwindow = xev->child;
  9271                   copy.xkey.time = xev->time;
  9272                   copy.xkey.x = lrint (xev->event_x);
  9273                   copy.xkey.y = lrint (xev->event_y);
  9274                   copy.xkey.x_root = lrint (xev->root_x);
  9275                   copy.xkey.y_root = lrint (xev->root_y);
  9276                   copy.xkey.state = xev->mods.effective;
  9277                   copy.xkey.keycode = xev->detail;
  9278                   copy.xkey.same_screen = True;
  9279 
  9280                   keysym = XLookupKeysym (&copy.xkey, 0);
  9281 
  9282                   if (keysym == XK_g
  9283                       && (copy.xkey.state & ControlMask) != 0) /* Any escape, ignore modifiers.  */
  9284                     XtUnmanageChild (dialog);
  9285 
  9286                   XFreeEventData (FRAME_X_DISPLAY (f), &event.xcookie);
  9287                 }
  9288             }
  9289 #endif
  9290 
  9291           (void) x_dispatch_event (&copy, FRAME_X_DISPLAY (f));
  9292         }
  9293     }
  9294 
  9295   /* Get the result.  */
  9296   if (result == XmCR_OK)
  9297     {
  9298       XmString text_string;
  9299       String data;
  9300 
  9301       XtVaGetValues (dialog, XmNtextString, &text_string, NULL);
  9302       XmStringGetLtoR (text_string, XmFONTLIST_DEFAULT_TAG, &data);
  9303       XmStringFree (text_string);
  9304       file = build_string (data);
  9305       XtFree (data);
  9306     }
  9307   else
  9308     file = Qnil;
  9309 
  9310   unblock_input ();
  9311 
  9312   /* Make "Cancel" equivalent to C-g.  */
  9313   if (NILP (file))
  9314     quit ();
  9315 
  9316   decoded_file = DECODE_FILE (file);
  9317 
  9318   return unbind_to (count, decoded_file);
  9319 }
  9320 
  9321 #endif /* USE_MOTIF */
  9322 
  9323 #ifdef USE_GTK
  9324 
  9325 static void
  9326 clean_up_dialog (void)
  9327 {
  9328   x_menu_set_in_use (false);
  9329 }
  9330 
  9331 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
  9332        doc: /* Read file name, prompting with PROMPT in directory DIR.
  9333 Use a file selection dialog.  Select DEFAULT-FILENAME in the dialog's file
  9334 selection box, if specified.  If MUSTMATCH is non-nil, the returned file
  9335 or directory must exist.
  9336 
  9337 This function is defined only on NS, Haiku, MS Windows, and X Windows with the
  9338 Motif or Gtk toolkits.  With the Motif toolkit, ONLY-DIR-P is ignored.
  9339 Otherwise, if ONLY-DIR-P is non-nil, the user can select only directories.
  9340 On MS Windows 7 and later, the file selection dialog "remembers" the last
  9341 directory where the user selected a file, and will open that directory
  9342 instead of DIR on subsequent invocations of this function with the same
  9343 value of DIR as in previous invocations; this is standard MS Windows behavior.  */)
  9344   (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
  9345 {
  9346   struct frame *f = SELECTED_FRAME ();
  9347   char *fn;
  9348   Lisp_Object file = Qnil;
  9349   Lisp_Object decoded_file;
  9350   specpdl_ref count = SPECPDL_INDEX ();
  9351   char *cdef_file;
  9352 
  9353   check_window_system (f);
  9354 
  9355   if (popup_activated ())
  9356     error ("Trying to use a menu from within a menu-entry");
  9357   else
  9358     x_menu_set_in_use (true);
  9359 
  9360   CHECK_STRING (prompt);
  9361   CHECK_STRING (dir);
  9362 
  9363   /* Prevent redisplay.  */
  9364   specbind (Qinhibit_redisplay, Qt);
  9365   record_unwind_protect_void (clean_up_dialog);
  9366 
  9367   block_input ();
  9368 
  9369   if (STRINGP (default_filename))
  9370     cdef_file = SSDATA (default_filename);
  9371   else
  9372     cdef_file = SSDATA (dir);
  9373 
  9374   fn = xg_get_file_name (f, SSDATA (prompt), cdef_file,
  9375                          ! NILP (mustmatch),
  9376                          ! NILP (only_dir_p));
  9377 
  9378   if (fn)
  9379     {
  9380       file = build_string (fn);
  9381       xfree (fn);
  9382     }
  9383 
  9384   unblock_input ();
  9385 
  9386   /* Make "Cancel" equivalent to C-g.  */
  9387   if (NILP (file))
  9388     quit ();
  9389 
  9390   decoded_file = DECODE_FILE (file);
  9391 
  9392   return unbind_to (count, decoded_file);
  9393 }
  9394 
  9395 
  9396 #ifdef HAVE_FREETYPE
  9397 
  9398 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
  9399        doc: /* Read a font using a GTK dialog.
  9400 Return either a font spec (for GTK versions >= 3.2) or a string
  9401 containing a GTK-style font name.
  9402 
  9403 FRAME is the frame on which to pop up the font chooser.  If omitted or
  9404 nil, it defaults to the selected frame. */)
  9405   (Lisp_Object frame, Lisp_Object ignored)
  9406 {
  9407   struct frame *f = decode_window_system_frame (frame);
  9408   Lisp_Object font;
  9409   Lisp_Object font_param;
  9410   char *default_name = NULL;
  9411   specpdl_ref count = SPECPDL_INDEX ();
  9412 
  9413   if (popup_activated ())
  9414     error ("Trying to use a menu from within a menu-entry");
  9415   else
  9416     x_menu_set_in_use (true);
  9417 
  9418   /* Prevent redisplay.  */
  9419   specbind (Qinhibit_redisplay, Qt);
  9420   record_unwind_protect_void (clean_up_dialog);
  9421 
  9422   block_input ();
  9423 
  9424   XSETFONT (font, FRAME_FONT (f));
  9425   font_param = Ffont_get (font, QCname);
  9426   if (STRINGP (font_param))
  9427     default_name = xlispstrdup (font_param);
  9428   else
  9429     {
  9430       font_param = Fframe_parameter (frame, Qfont_parameter);
  9431       if (STRINGP (font_param))
  9432         default_name = xlispstrdup (font_param);
  9433     }
  9434 
  9435   font = xg_get_font (f, default_name);
  9436   xfree (default_name);
  9437 
  9438   unblock_input ();
  9439 
  9440   if (NILP (font))
  9441     quit ();
  9442 
  9443   return unbind_to (count, font);
  9444 }
  9445 #endif /* HAVE_FREETYPE */
  9446 
  9447 #endif /* USE_GTK */
  9448 
  9449 
  9450 /***********************************************************************
  9451                                Keyboard
  9452  ***********************************************************************/
  9453 
  9454 #ifdef HAVE_XKB
  9455 #include <X11/XKBlib.h>
  9456 #include <X11/keysym.h>
  9457 #endif
  9458 
  9459 DEFUN ("x-backspace-delete-keys-p", Fx_backspace_delete_keys_p,
  9460        Sx_backspace_delete_keys_p, 0, 1, 0,
  9461        doc: /* Check if both Backspace and Delete keys are on the keyboard of FRAME.
  9462 FRAME nil means use the selected frame.
  9463 Value is t if we know that both keys are present, and are mapped to the
  9464 usual X keysyms.  Value is `lambda' if we cannot determine if both keys are
  9465 present and mapped to the usual X keysyms.  */)
  9466   (Lisp_Object frame)
  9467 {
  9468 #ifdef HAVE_XKB
  9469   XkbDescPtr kb;
  9470   struct frame *f;
  9471   Display *dpy;
  9472   Lisp_Object have_keys;
  9473   int delete_keycode, backspace_keycode, i;
  9474 #endif
  9475 
  9476 #ifndef HAVE_XKB
  9477   return Qlambda;
  9478 #else
  9479   delete_keycode = 0;
  9480   backspace_keycode = 0;
  9481   f = decode_window_system_frame (frame);
  9482   dpy = FRAME_X_DISPLAY (f);
  9483 
  9484   if (!FRAME_DISPLAY_INFO (f)->supports_xkb)
  9485     return Qlambda;
  9486 
  9487   block_input ();
  9488 
  9489   /* In this code we check that the keyboard has physical keys with names
  9490      that start with BKSP (Backspace) and DELE (Delete), and that they
  9491      generate keysym XK_BackSpace and XK_Delete respectively.
  9492      This function is used to test if normal-erase-is-backspace should be
  9493      turned on.
  9494      An alternative approach would be to just check if XK_BackSpace and
  9495      XK_Delete are mapped to any key.  But if any of those are mapped to
  9496      some non-intuitive key combination (Meta-Shift-Ctrl-whatever) and the
  9497      user doesn't know about it, it is better to return false here.
  9498      It is more obvious to the user what to do if there are two keys
  9499      clearly marked with names/symbols and one key does something not
  9500      expected (and the user then tries the other).
  9501      The cases where Backspace/Delete is mapped to some other key combination
  9502      are rare, and in those cases, normal-erase-is-backspace can be turned on
  9503      manually.  */
  9504 
  9505   have_keys = Qnil;
  9506   kb = FRAME_DISPLAY_INFO (f)->xkb_desc;
  9507   if (kb && kb->names)
  9508     {
  9509       for (i = kb->min_key_code; (i < kb->max_key_code
  9510                                   && (delete_keycode == 0
  9511                                       || backspace_keycode == 0));
  9512            ++i)
  9513         {
  9514           /* The XKB symbolic key names can be seen most easily in
  9515              the PS file generated by `xkbprint -label name
  9516              $DISPLAY'.  */
  9517           if (!memcmp ("DELE", kb->names->keys[i].name, 4))
  9518             delete_keycode = i;
  9519           else if (!memcmp ("BKSP", kb->names->keys[i].name, 4))
  9520             backspace_keycode = i;
  9521         }
  9522 
  9523       if (delete_keycode && backspace_keycode
  9524           && XKeysymToKeycode (dpy, XK_Delete) == delete_keycode
  9525           && XKeysymToKeycode (dpy, XK_BackSpace) == backspace_keycode)
  9526         have_keys = Qt;
  9527     }
  9528   else
  9529     /* The keyboard names couldn't be obtained for some reason.  */
  9530     have_keys = Qlambda;
  9531   unblock_input ();
  9532   return have_keys;
  9533 #endif
  9534 }
  9535 
  9536 DEFUN ("x-get-modifier-masks", Fx_get_modifier_masks, Sx_get_modifier_masks,
  9537        0, 1, 0,
  9538        doc: /* Return the X modifier masks corresponding to keyboard modifiers.
  9539 The optional second argument TERMINAL specifies which display to fetch
  9540 modifier masks from.  TERMINAL should be a terminal object, a frame or
  9541 a display name (a string).  If TERMINAL is omitted or nil, that stands
  9542 for the selected frame's display.
  9543 
  9544 Return a list of (HYPER SUPER ALT SHIFT-LOCK META), each element being
  9545 a number describing the modifier mask for the corresponding Emacs
  9546 modifier.  */)
  9547   (Lisp_Object terminal)
  9548 {
  9549   struct x_display_info *dpyinfo;
  9550 
  9551   dpyinfo = check_x_display_info (terminal);
  9552   return x_get_keyboard_modifiers (dpyinfo);
  9553 }
  9554 
  9555 
  9556 /***********************************************************************
  9557                                Printing
  9558  ***********************************************************************/
  9559 
  9560 #ifdef USE_CAIRO
  9561 DEFUN ("x-export-frames", Fx_export_frames, Sx_export_frames, 0, 2, 0,
  9562        doc: /* Return image data of FRAMES in TYPE format.
  9563 FRAMES should be nil (the selected frame), a frame, or a list of
  9564 frames (each of which corresponds to one page).  Each frame should be
  9565 visible.  Optional arg TYPE should be either `pdf' (default), `png',
  9566 `postscript', or `svg'.  Supported types are determined by the
  9567 compile-time configuration of cairo.
  9568 
  9569 Note: Text drawn with the `x' font backend is shown with hollow boxes
  9570 unless TYPE is `png'.  */)
  9571      (Lisp_Object frames, Lisp_Object type)
  9572 {
  9573   Lisp_Object rest, tmp;
  9574   cairo_surface_type_t surface_type;
  9575 
  9576   if (!CONSP (frames))
  9577     frames = list1 (frames);
  9578 
  9579   tmp = Qnil;
  9580   for (rest = frames; CONSP (rest); rest = XCDR (rest))
  9581     {
  9582       struct frame *f = decode_window_system_frame (XCAR (rest));
  9583       Lisp_Object frame;
  9584 
  9585       XSETFRAME (frame, f);
  9586       if (!FRAME_VISIBLE_P (f))
  9587         error ("Frames to be exported must be visible.");
  9588       tmp = Fcons (frame, tmp);
  9589     }
  9590   frames = Fnreverse (tmp);
  9591 
  9592 #ifdef CAIRO_HAS_PDF_SURFACE
  9593   if (NILP (type) || EQ (type, Qpdf))
  9594     surface_type = CAIRO_SURFACE_TYPE_PDF;
  9595   else
  9596 #endif
  9597 #ifdef CAIRO_HAS_PNG_FUNCTIONS
  9598   if (EQ (type, Qpng))
  9599     {
  9600       if (!NILP (XCDR (frames)))
  9601         error ("PNG export cannot handle multiple frames.");
  9602       surface_type = CAIRO_SURFACE_TYPE_IMAGE;
  9603     }
  9604   else
  9605 #endif
  9606 #ifdef CAIRO_HAS_PS_SURFACE
  9607   if (EQ (type, Qpostscript))
  9608     surface_type = CAIRO_SURFACE_TYPE_PS;
  9609   else
  9610 #endif
  9611 #ifdef CAIRO_HAS_SVG_SURFACE
  9612   if (EQ (type, Qsvg))
  9613     {
  9614       /* For now, we stick to SVG 1.1.  */
  9615       if (!NILP (XCDR (frames)))
  9616         error ("SVG export cannot handle multiple frames.");
  9617       surface_type = CAIRO_SURFACE_TYPE_SVG;
  9618     }
  9619   else
  9620 #endif
  9621     error ("Unsupported export type");
  9622 
  9623   return x_cr_export_frames (frames, surface_type);
  9624 }
  9625 
  9626 #ifdef USE_GTK
  9627 DEFUN ("x-page-setup-dialog", Fx_page_setup_dialog, Sx_page_setup_dialog, 0, 0, 0,
  9628        doc: /* Pop up a page setup dialog.
  9629 The current page setup can be obtained using `x-get-page-setup'.  */)
  9630      (void)
  9631 {
  9632   block_input ();
  9633   xg_page_setup_dialog ();
  9634   unblock_input ();
  9635 
  9636   return Qnil;
  9637 }
  9638 
  9639 DEFUN ("x-get-page-setup", Fx_get_page_setup, Sx_get_page_setup, 0, 0, 0,
  9640        doc: /* Return the value of the current page setup.
  9641 The return value is an alist containing the following keys:
  9642 
  9643   orientation: page orientation (symbol `portrait', `landscape',
  9644         `reverse-portrait', or `reverse-landscape').
  9645   width, height: page width/height in points not including margins.
  9646   left-margin, right-margin, top-margin, bottom-margin: print margins,
  9647         which is the parts of the page that the printer cannot print
  9648         on, in points.
  9649 
  9650 The paper width can be obtained as the sum of width, left-margin, and
  9651 right-margin values if the page orientation is `portrait' or
  9652 `reverse-portrait'.  Otherwise, it is the sum of width, top-margin,
  9653 and bottom-margin values.  Likewise, the paper height is the sum of
  9654 height, top-margin, and bottom-margin values if the page orientation
  9655 is `portrait' or `reverse-portrait'.  Otherwise, it is the sum of
  9656 height, left-margin, and right-margin values.  */)
  9657      (void)
  9658 {
  9659   Lisp_Object result;
  9660 
  9661   block_input ();
  9662   result = xg_get_page_setup ();
  9663   unblock_input ();
  9664 
  9665   return result;
  9666 }
  9667 
  9668 DEFUN ("x-print-frames-dialog", Fx_print_frames_dialog, Sx_print_frames_dialog, 0, 1, "",
  9669        doc: /* Pop up a print dialog to print the current contents of FRAMES.
  9670 FRAMES should be nil (the selected frame), a frame, or a list of
  9671 frames (each of which corresponds to one page).  Each frame should be
  9672 visible.
  9673 
  9674 Note: Text drawn with the `x' font backend is shown with hollow boxes.  */)
  9675      (Lisp_Object frames)
  9676 {
  9677   Lisp_Object rest, tmp;
  9678 
  9679   if (!CONSP (frames))
  9680     frames = list1 (frames);
  9681 
  9682   tmp = Qnil;
  9683   for (rest = frames; CONSP (rest); rest = XCDR (rest))
  9684     {
  9685       struct frame *f = decode_window_system_frame (XCAR (rest));
  9686       Lisp_Object frame;
  9687 
  9688       XSETFRAME (frame, f);
  9689       if (!FRAME_VISIBLE_P (f))
  9690         error ("Frames to be printed must be visible.");
  9691       tmp = Fcons (frame, tmp);
  9692     }
  9693   frames = Fnreverse (tmp);
  9694 
  9695   /* Make sure the current matrices are up-to-date.  */
  9696   specpdl_ref count = SPECPDL_INDEX ();
  9697   specbind (Qredisplay_dont_pause, Qt);
  9698   redisplay_preserve_echo_area (32);
  9699   unbind_to (count, Qnil);
  9700 
  9701   block_input ();
  9702   xg_print_frames_dialog (frames);
  9703   unblock_input ();
  9704 
  9705   return Qnil;
  9706 }
  9707 #endif  /* USE_GTK */
  9708 #endif  /* USE_CAIRO */
  9709 
  9710 #ifdef USE_GTK
  9711 #ifdef HAVE_GTK3
  9712 #if GTK_CHECK_VERSION (3, 14, 0)
  9713 DEFUN ("x-gtk-debug", Fx_gtk_debug, Sx_gtk_debug, 1, 1, 0,
  9714        doc: /* Toggle interactive GTK debugging.   */)
  9715   (Lisp_Object enable)
  9716 {
  9717   gboolean enable_debug = !NILP (enable);
  9718 
  9719   block_input ();
  9720   gtk_window_set_interactive_debugging (enable_debug);
  9721   unblock_input ();
  9722 
  9723   return NILP (enable) ? Qnil : Qt;
  9724 }
  9725 #endif /* GTK_CHECK_VERSION (3, 14, 0) */
  9726 #endif /* HAVE_GTK3 */
  9727 #endif  /* USE_GTK */
  9728 
  9729 DEFUN ("x-display-set-last-user-time", Fx_display_last_user_time,
  9730        Sx_display_set_last_user_time, 1, 2, 0,
  9731        doc: /* Set the last user time of TERMINAL to TIME-OBJECT.
  9732 TIME-OBJECT is the X server time, in milliseconds, of the last user
  9733 interaction.  This is the timestamp that `x-get-selection-internal'
  9734 will use by default to fetch selection data.
  9735 The optional second argument TERMINAL specifies which display to act
  9736 on.  TERMINAL should be a terminal object, a frame or a display name
  9737 (a string).  If TERMINAL is omitted or nil, that stands for the
  9738 selected frame's display.  */)
  9739   (Lisp_Object time_object, Lisp_Object terminal)
  9740 {
  9741   struct x_display_info *dpyinfo;
  9742   uint32_t time;
  9743 
  9744   /* time should be a 32-bit integer, regardless of what the size of
  9745      the X type `Time' is on this system.  */
  9746   dpyinfo = check_x_display_info (terminal);
  9747   CONS_TO_INTEGER (time_object, uint32_t, time);
  9748 
  9749   x_set_last_user_time_from_lisp (dpyinfo, time);
  9750   return Qnil;
  9751 }
  9752 
  9753 DEFUN ("x-internal-focus-input-context", Fx_internal_focus_input_context,
  9754        Sx_internal_focus_input_context, 1, 1, 0,
  9755        doc: /* Focus and set the client window of all focused frames' GTK input context.
  9756 If FOCUS is nil, focus out and remove the client window instead.
  9757 This should be called from a variable watcher for `x-gtk-use-native-input'.  */)
  9758   (Lisp_Object focus)
  9759 {
  9760 #ifdef USE_GTK
  9761   struct x_display_info *dpyinfo;
  9762   struct frame *f;
  9763   GtkWidget *widget;
  9764 
  9765   block_input ();
  9766   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
  9767     {
  9768       f = dpyinfo->x_focus_frame;
  9769 
  9770       if (f)
  9771         {
  9772           widget = FRAME_GTK_OUTER_WIDGET (f);
  9773 
  9774           if (!NILP (focus))
  9775             {
  9776               gtk_im_context_focus_in (FRAME_X_OUTPUT (f)->im_context);
  9777               gtk_im_context_set_client_window (FRAME_X_OUTPUT (f)->im_context,
  9778                                                 gtk_widget_get_window (widget));
  9779             }
  9780           else
  9781             {
  9782               gtk_im_context_focus_out (FRAME_X_OUTPUT (f)->im_context);
  9783               gtk_im_context_set_client_window (FRAME_X_OUTPUT (f)->im_context,
  9784                                                 NULL);
  9785             }
  9786         }
  9787     }
  9788   unblock_input ();
  9789 #endif
  9790 
  9791   return Qnil;
  9792 }
  9793 
  9794 /***********************************************************************
  9795                             Initialization
  9796  ***********************************************************************/
  9797 
  9798 /* Keep this list in the same order as frame_parms in frame.c.
  9799    Use 0 for unsupported frame parameters.  */
  9800 
  9801 frame_parm_handler x_frame_parm_handlers[] =
  9802 {
  9803   gui_set_autoraise,
  9804   gui_set_autolower,
  9805   x_set_background_color,
  9806   x_set_border_color,
  9807   gui_set_border_width,
  9808   x_set_cursor_color,
  9809   x_set_cursor_type,
  9810   gui_set_font,
  9811   x_set_foreground_color,
  9812   x_set_icon_name,
  9813   x_set_icon_type,
  9814   x_set_child_frame_border_width,
  9815   x_set_internal_border_width,
  9816   gui_set_right_divider_width,
  9817   gui_set_bottom_divider_width,
  9818   x_set_menu_bar_lines,
  9819   x_set_mouse_color,
  9820   x_explicitly_set_name,
  9821   gui_set_scroll_bar_width,
  9822   gui_set_scroll_bar_height,
  9823   x_set_title,
  9824   gui_set_unsplittable,
  9825   gui_set_vertical_scroll_bars,
  9826   gui_set_horizontal_scroll_bars,
  9827   gui_set_visibility,
  9828   x_set_tab_bar_lines,
  9829   x_set_tool_bar_lines,
  9830   x_set_scroll_bar_foreground,
  9831   x_set_scroll_bar_background,
  9832   gui_set_screen_gamma,
  9833   gui_set_line_spacing,
  9834   gui_set_left_fringe,
  9835   gui_set_right_fringe,
  9836   x_set_wait_for_wm,
  9837   gui_set_fullscreen,
  9838   gui_set_font_backend,
  9839   x_set_alpha,
  9840   x_set_sticky,
  9841   x_set_tool_bar_position,
  9842 #ifdef HAVE_XDBE
  9843   x_set_inhibit_double_buffering,
  9844 #else
  9845   NULL,
  9846 #endif
  9847   x_set_undecorated,
  9848   x_set_parent_frame,
  9849   x_set_skip_taskbar,
  9850   x_set_no_focus_on_map,
  9851   x_set_no_accept_focus,
  9852   x_set_z_group,
  9853   x_set_override_redirect,
  9854   gui_set_no_special_glyphs,
  9855   x_set_alpha_background,
  9856   x_set_use_frame_synchronization,
  9857   x_set_shaded,
  9858 };
  9859 
  9860 /* Some versions of libX11 don't have symbols for a few functions we
  9861    need, so define replacements here.  */
  9862 
  9863 #ifdef HAVE_XKB
  9864 #ifndef HAVE_XKBREFRESHKEYBOARDMAPPING
  9865 Status
  9866 XkbRefreshKeyboardMapping (XkbMapNotifyEvent *event)
  9867 {
  9868   return Success;
  9869 }
  9870 #endif
  9871 
  9872 #ifndef HAVE_XKBFREENAMES
  9873 void
  9874 XkbFreeNames (XkbDescPtr xkb, unsigned int which, Bool free_map)
  9875 {
  9876   return;
  9877 }
  9878 #endif
  9879 #endif
  9880 
  9881 #ifndef HAVE_XDISPLAYCELLS
  9882 int
  9883 XDisplayCells (Display *dpy, int screen_number)
  9884 {
  9885   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
  9886 
  9887   if (!dpyinfo)
  9888     emacs_abort ();
  9889 
  9890   /* Not strictly correct, since the display could be using a
  9891      non-default visual, but it satisfies the callers we need to care
  9892      about.  */
  9893   return dpyinfo->visual_info.colormap_size;
  9894 }
  9895 #endif
  9896 
  9897 #ifndef HAVE_XDESTROYSUBWINDOWS
  9898 int
  9899 XDestroySubwindows (Display *dpy, Window w)
  9900 {
  9901   Window root, parent, *children;
  9902   unsigned int nchildren, i;
  9903 
  9904   if (XQueryTree (dpy, w, &root, &parent, &children,
  9905                   &nchildren))
  9906     {
  9907       for (i = 0; i < nchildren; ++i)
  9908         XDestroyWindow (dpy, children[i]);
  9909       XFree (children);
  9910     }
  9911 
  9912   return 0;
  9913 }
  9914 #endif
  9915 
  9916 void
  9917 syms_of_xfns (void)
  9918 {
  9919   DEFSYM (Qundefined_color, "undefined-color");
  9920   DEFSYM (Qcompound_text, "compound-text");
  9921   DEFSYM (Qcancel_timer, "cancel-timer");
  9922   DEFSYM (Qfont_parameter, "font-parameter");
  9923   DEFSYM (Qmono, "mono");
  9924   DEFSYM (Qassq_delete_all, "assq-delete-all");
  9925   DEFSYM (Qresize_mode, "resize-mode");
  9926 
  9927 #ifdef USE_CAIRO
  9928   DEFSYM (Qpdf, "pdf");
  9929 
  9930   DEFSYM (Qorientation, "orientation");
  9931   DEFSYM (Qtop_margin, "top-margin");
  9932   DEFSYM (Qbottom_margin, "bottom-margin");
  9933   DEFSYM (Qportrait, "portrait");
  9934   DEFSYM (Qlandscape, "landscape");
  9935   DEFSYM (Qreverse_portrait, "reverse-portrait");
  9936   DEFSYM (Qreverse_landscape, "reverse-landscape");
  9937 #endif
  9938 
  9939   DEFSYM (QXdndActionCopy, "XdndActionCopy");
  9940   DEFSYM (QXdndActionMove, "XdndActionMove");
  9941   DEFSYM (QXdndActionLink, "XdndActionLink");
  9942   DEFSYM (QXdndActionAsk, "XdndActionAsk");
  9943   DEFSYM (QXdndActionPrivate, "XdndActionPrivate");
  9944 
  9945   Fput (Qundefined_color, Qerror_conditions,
  9946         pure_list (Qundefined_color, Qerror));
  9947   Fput (Qundefined_color, Qerror_message,
  9948         build_pure_c_string ("Undefined color"));
  9949 
  9950   DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape,
  9951     doc: /* The shape of the pointer when over text.
  9952 Changing the value does not affect existing frames
  9953 unless you set the mouse color.  */);
  9954   Vx_pointer_shape = Qnil;
  9955 
  9956 #if false /* This doesn't really do anything.  */
  9957   DEFVAR_LISP ("x-nontext-pointer-shape", Vx_nontext_pointer_shape,
  9958     doc: /* The shape of the pointer when not over text.
  9959 This variable takes effect when you create a new frame
  9960 or when you set the mouse color.  */);
  9961 #endif
  9962   Vx_nontext_pointer_shape = Qnil;
  9963 
  9964   DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape,
  9965     doc: /* The shape of the pointer when Emacs is busy.
  9966 This variable takes effect when you create a new frame
  9967 or when you set the mouse color.  */);
  9968   Vx_hourglass_pointer_shape = Qnil;
  9969 
  9970 #if false /* This doesn't really do anything.  */
  9971   DEFVAR_LISP ("x-mode-pointer-shape", Vx_mode_pointer_shape,
  9972     doc: /* The shape of the pointer when over the mode line.
  9973 This variable takes effect when you create a new frame
  9974 or when you set the mouse color.  */);
  9975 #endif
  9976   Vx_mode_pointer_shape = Qnil;
  9977 
  9978   DEFVAR_LISP ("x-sensitive-text-pointer-shape",
  9979               Vx_sensitive_text_pointer_shape,
  9980                doc: /* The shape of the pointer when over mouse-sensitive text.
  9981 This variable takes effect when you create a new frame
  9982 or when you set the mouse color.  */);
  9983   Vx_sensitive_text_pointer_shape = Qnil;
  9984 
  9985   DEFVAR_LISP ("x-window-horizontal-drag-cursor",
  9986               Vx_window_horizontal_drag_shape,
  9987   doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
  9988 This variable takes effect when you create a new frame
  9989 or when you set the mouse color.  */);
  9990   Vx_window_horizontal_drag_shape = Qnil;
  9991 
  9992   DEFVAR_LISP ("x-window-vertical-drag-cursor",
  9993               Vx_window_vertical_drag_shape,
  9994   doc: /* Pointer shape to use for indicating a window can be dragged vertically.
  9995 This variable takes effect when you create a new frame
  9996 or when you set the mouse color.  */);
  9997   Vx_window_vertical_drag_shape = Qnil;
  9998 
  9999   DEFVAR_LISP ("x-window-left-edge-cursor",
 10000                Vx_window_left_edge_shape,
 10001   doc: /* Pointer shape indicating a left x-window edge can be dragged.
 10002 This variable takes effect when you create a new frame
 10003 or when you set the mouse color.  */);
 10004   Vx_window_left_edge_shape = Qnil;
 10005 
 10006   DEFVAR_LISP ("x-window-top-left-corner-cursor",
 10007                Vx_window_top_left_corner_shape,
 10008   doc: /* Pointer shape indicating a top left x-window corner can be dragged.
 10009 This variable takes effect when you create a new frame
 10010 or when you set the mouse color.  */);
 10011   Vx_window_top_left_corner_shape = Qnil;
 10012 
 10013   DEFVAR_LISP ("x-window-top-edge-cursor",
 10014                Vx_window_top_edge_shape,
 10015   doc: /* Pointer shape indicating a top x-window edge can be dragged.
 10016 This variable takes effect when you create a new frame
 10017 or when you set the mouse color.  */);
 10018   Vx_window_top_edge_shape = Qnil;
 10019 
 10020   DEFVAR_LISP ("x-window-top-right-corner-cursor",
 10021                Vx_window_top_right_corner_shape,
 10022   doc: /* Pointer shape indicating a top right x-window corner can be dragged.
 10023 This variable takes effect when you create a new frame
 10024 or when you set the mouse color.  */);
 10025   Vx_window_top_right_corner_shape = Qnil;
 10026 
 10027   DEFVAR_LISP ("x-window-right-edge-cursor",
 10028                Vx_window_right_edge_shape,
 10029   doc: /* Pointer shape indicating a right x-window edge can be dragged.
 10030 This variable takes effect when you create a new frame
 10031 or when you set the mouse color.  */);
 10032   Vx_window_right_edge_shape = Qnil;
 10033 
 10034   DEFVAR_LISP ("x-window-bottom-right-corner-cursor",
 10035                Vx_window_bottom_right_corner_shape,
 10036   doc: /* Pointer shape indicating a bottom right x-window corner can be dragged.
 10037 This variable takes effect when you create a new frame
 10038 or when you set the mouse color.  */);
 10039   Vx_window_bottom_right_corner_shape = Qnil;
 10040 
 10041   DEFVAR_LISP ("x-window-bottom-edge-cursor",
 10042                Vx_window_bottom_edge_shape,
 10043   doc: /* Pointer shape indicating a bottom x-window edge can be dragged.
 10044 This variable takes effect when you create a new frame
 10045 or when you set the mouse color.  */);
 10046   Vx_window_bottom_edge_shape = Qnil;
 10047 
 10048   DEFVAR_LISP ("x-window-bottom-left-corner-cursor",
 10049                Vx_window_bottom_left_corner_shape,
 10050   doc: /* Pointer shape indicating a bottom left x-window corner can be dragged.
 10051 This variable takes effect when you create a new frame
 10052 or when you set the mouse color.  */);
 10053   Vx_window_bottom_left_corner_shape = Qnil;
 10054 
 10055   DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
 10056     doc: /* A string indicating the foreground color of the cursor box.  */);
 10057   Vx_cursor_fore_pixel = Qnil;
 10058 
 10059   DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
 10060     doc: /* Maximum size for tooltips.
 10061 Value is a pair (COLUMNS . ROWS).  Text larger than this is clipped.  */);
 10062   Vx_max_tooltip_size = Qnil;
 10063 
 10064   DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager,
 10065     doc: /* Non-nil if no X window manager is in use.
 10066 Emacs doesn't try to figure this out; this is always nil
 10067 unless you set it to something else.  */);
 10068   /* We don't have any way to find this out, so set it to nil
 10069      and maybe the user would like to set it to t.  */
 10070   Vx_no_window_manager = Qnil;
 10071 
 10072   DEFVAR_LISP ("x-pixel-size-width-font-regexp",
 10073                Vx_pixel_size_width_font_regexp,
 10074     doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
 10075 
 10076 Since Emacs gets the width of a font matching this regexp from the
 10077 PIXEL_SIZE field of the name, the font-finding mechanism gets faster for
 10078 such a font.  This is especially effective for large fonts such as
 10079 Chinese, Japanese, and Korean.  */);
 10080   Vx_pixel_size_width_font_regexp = Qnil;
 10081 
 10082 /* This is not ifdef:ed, so other builds than GTK can customize it.  */
 10083   DEFVAR_BOOL ("x-gtk-use-old-file-dialog", x_gtk_use_old_file_dialog,
 10084     doc: /* Non-nil means prompt with the old GTK file selection dialog.
 10085 If nil or if the file selection dialog is not available, the new GTK file
 10086 chooser is used instead.  To turn off all file dialogs set the
 10087 variable `use-file-dialog'.  */);
 10088   x_gtk_use_old_file_dialog = false;
 10089 
 10090   DEFVAR_BOOL ("x-gtk-show-hidden-files", x_gtk_show_hidden_files,
 10091     doc: /* If non-nil, the GTK file chooser will by default show hidden files.
 10092 Note that this is just the default, there is a toggle button on the file
 10093 chooser to show or not show hidden files on a case by case basis.  */);
 10094   x_gtk_show_hidden_files = false;
 10095 
 10096   DEFVAR_BOOL ("x-gtk-file-dialog-help-text", x_gtk_file_dialog_help_text,
 10097     doc: /* If non-nil, the GTK file chooser will show additional help text.
 10098 If more space for files in the file chooser dialog is wanted, set this to nil
 10099 to turn the additional text off.  */);
 10100   x_gtk_file_dialog_help_text = true;
 10101 
 10102   DEFVAR_LISP ("x-gtk-resize-child-frames", x_gtk_resize_child_frames,
 10103     doc: /* If non-nil, resize child frames specially with GTK builds.
 10104 If this is nil, resize child frames like any other frames.  This is the
 10105 default and usually works with most desktops.  Some desktop environments
 10106 (GNOME shell in particular when using the mutter window manager),
 10107 however, may refuse to resize a child frame when Emacs is built with
 10108 GTK3.  For those environments, the two settings below are provided.
 10109 
 10110 If this equals the symbol `hide', Emacs temporarily hides the child
 10111 frame during resizing.  This approach seems to work reliably, may
 10112 however induce some flicker when the frame is made visible again.
 10113 
 10114 If this equals the symbol `resize-mode', Emacs uses GTK's resize mode to
 10115 always trigger an immediate resize of the child frame.  This method is
 10116 deprecated by GTK and may not work in future versions of that toolkit.
 10117 It also may freeze Emacs when used with other desktop environments.  It
 10118 avoids, however, the unpleasant flicker induced by the hiding approach.
 10119 
 10120 This variable is considered a temporary workaround and will be hopefully
 10121 eliminated in future versions of Emacs.  */);
 10122   x_gtk_resize_child_frames = Qnil;
 10123 
 10124   /* Tell Emacs about this window system.  */
 10125   Fprovide (Qx, Qnil);
 10126 
 10127   /* Used by Fx_show_tip.  */
 10128   DEFSYM (Qrun_at_time, "run-at-time");
 10129   DEFSYM (Qx_hide_tip, "x-hide-tip");
 10130 
 10131   /* Used by display class and backing store reporting functions.  */
 10132   DEFSYM (Qalways, "always");
 10133   DEFSYM (Qwhen_mapped, "when-mapped");
 10134   DEFSYM (Qnot_useful, "not-useful");
 10135   DEFSYM (Qstatic_gray, "static-gray");
 10136   DEFSYM (Qgray_scale, "gray-scale");
 10137   DEFSYM (Qstatic_color, "static-color");
 10138   DEFSYM (Qpseudo_color, "pseudo-color");
 10139   DEFSYM (Qtrue_color, "true-color");
 10140   DEFSYM (Qdirect_color, "direct-color");
 10141   DEFSYM (Qgrayscale, "grayscale");
 10142   DEFSYM (Qcolor, "color");
 10143 
 10144 #ifdef HAVE_XINPUT2
 10145   DEFSYM (Qxinput2, "xinput2");
 10146 
 10147   Fprovide (Qxinput2, Qnil);
 10148 #endif
 10149 
 10150 #ifdef USE_X_TOOLKIT
 10151   Fprovide (intern_c_string ("x-toolkit"), Qnil);
 10152 #ifdef USE_MOTIF
 10153   Fprovide (intern_c_string ("motif"), Qnil);
 10154 
 10155   DEFVAR_LISP ("motif-version-string", Vmotif_version_string,
 10156                doc: /* Version info for LessTif/Motif.  */);
 10157   Vmotif_version_string = build_string (XmVERSION_STRING);
 10158 #endif /* USE_MOTIF */
 10159 #endif /* USE_X_TOOLKIT */
 10160 
 10161 #ifdef USE_GTK
 10162   /* Provide x-toolkit also for GTK.  Internally GTK does not use Xt so it
 10163      is not an X toolkit in that sense (USE_X_TOOLKIT is not defined).
 10164      But for a user it is a toolkit for X, and indeed, configure
 10165      accepts --with-x-toolkit=gtk.  */
 10166   Fprovide (intern_c_string ("x-toolkit"), Qnil);
 10167   Fprovide (intern_c_string ("gtk"), Qnil);
 10168   Fprovide (intern_c_string ("move-toolbar"), Qnil);
 10169 
 10170   DEFVAR_LISP ("gtk-version-string", Vgtk_version_string,
 10171                doc: /* Version info for GTK+.  */);
 10172   {
 10173     char gtk_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
 10174     int len = sprintf (gtk_version, "%d.%d.%d",
 10175                        GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
 10176     Vgtk_version_string = make_pure_string (gtk_version, len, len, false);
 10177   }
 10178 #endif /* USE_GTK */
 10179 
 10180 #ifdef USE_CAIRO
 10181   Fprovide (intern_c_string ("cairo"), Qnil);
 10182 
 10183   DEFVAR_LISP ("cairo-version-string", Vcairo_version_string,
 10184                doc: /* Version info for cairo.  */);
 10185   {
 10186     char cairo_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
 10187     int len = sprintf (cairo_version, "%d.%d.%d",
 10188                        CAIRO_VERSION_MAJOR, CAIRO_VERSION_MINOR,
 10189                        CAIRO_VERSION_MICRO);
 10190     Vcairo_version_string = make_pure_string (cairo_version, len, len, false);
 10191   }
 10192 #endif
 10193 
 10194   /* X window properties.  */
 10195   defsubr (&Sx_change_window_property);
 10196   defsubr (&Sx_delete_window_property);
 10197   defsubr (&Sx_window_property);
 10198   defsubr (&Sx_window_property_attributes);
 10199 
 10200   defsubr (&Sxw_display_color_p);
 10201   defsubr (&Sx_display_grayscale_p);
 10202   defsubr (&Sxw_color_defined_p);
 10203   defsubr (&Sxw_color_values);
 10204   defsubr (&Sx_server_max_request_size);
 10205   defsubr (&Sx_server_vendor);
 10206   defsubr (&Sx_server_version);
 10207   defsubr (&Sx_server_input_extension_version);
 10208   defsubr (&Sx_display_pixel_width);
 10209   defsubr (&Sx_display_pixel_height);
 10210   defsubr (&Sx_display_mm_width);
 10211   defsubr (&Sx_display_mm_height);
 10212   defsubr (&Sx_display_screens);
 10213   defsubr (&Sx_display_planes);
 10214   defsubr (&Sx_display_color_cells);
 10215   defsubr (&Sx_display_visual_class);
 10216   defsubr (&Sx_display_backing_store);
 10217   defsubr (&Sx_display_save_under);
 10218   defsubr (&Sx_display_monitor_attributes_list);
 10219   defsubr (&Sx_frame_geometry);
 10220   defsubr (&Sx_frame_edges);
 10221   defsubr (&Sx_frame_list_z_order);
 10222   defsubr (&Sx_frame_restack);
 10223   defsubr (&Sx_mouse_absolute_pixel_position);
 10224   defsubr (&Sx_set_mouse_absolute_pixel_position);
 10225   defsubr (&Sx_wm_set_size_hint);
 10226   defsubr (&Sx_create_frame);
 10227   defsubr (&Sx_open_connection);
 10228   defsubr (&Sx_close_connection);
 10229   defsubr (&Sx_display_list);
 10230   defsubr (&Sx_synchronize);
 10231   defsubr (&Sx_backspace_delete_keys_p);
 10232   defsubr (&Sx_show_tip);
 10233   defsubr (&Sx_hide_tip);
 10234   defsubr (&Sx_double_buffered_p);
 10235   defsubr (&Sx_begin_drag);
 10236   defsubr (&Sx_display_set_last_user_time);
 10237   defsubr (&Sx_translate_coordinates);
 10238   defsubr (&Sx_get_modifier_masks);
 10239 
 10240   tip_timer = Qnil;
 10241   staticpro (&tip_timer);
 10242   tip_frame = Qnil;
 10243   staticpro (&tip_frame);
 10244   tip_last_frame = Qnil;
 10245   staticpro (&tip_last_frame);
 10246   tip_last_string = Qnil;
 10247   staticpro (&tip_last_string);
 10248   tip_last_parms = Qnil;
 10249   staticpro (&tip_last_parms);
 10250   tip_dx = Qnil;
 10251   staticpro (&tip_dx);
 10252   tip_dy = Qnil;
 10253   staticpro (&tip_dy);
 10254 
 10255   defsubr (&Sx_uses_old_gtk_dialog);
 10256 #if defined (USE_MOTIF) || defined (USE_GTK)
 10257   defsubr (&Sx_file_dialog);
 10258 #endif
 10259 
 10260 #if defined (USE_GTK) && defined (HAVE_FREETYPE)
 10261   defsubr (&Sx_select_font);
 10262 #endif
 10263 
 10264   defsubr (&Sx_internal_focus_input_context);
 10265 
 10266 #ifdef USE_CAIRO
 10267   defsubr (&Sx_export_frames);
 10268 #ifdef USE_GTK
 10269   defsubr (&Sx_page_setup_dialog);
 10270   defsubr (&Sx_get_page_setup);
 10271   defsubr (&Sx_print_frames_dialog);
 10272 #endif
 10273 #endif
 10274 #ifdef USE_GTK
 10275 #ifdef HAVE_GTK3
 10276 #if GTK_CHECK_VERSION (3, 14, 0)
 10277   defsubr (&Sx_gtk_debug);
 10278 #endif
 10279 #endif
 10280 #endif
 10281 }

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