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

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