root/src/xterm.c

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

DEFINITIONS

This source file includes following definitions.
  1. x_defer_selection_requests
  2. x_release_selection_requests
  3. x_release_selection_requests_and_flush
  4. xm_side_effect_from_action
  5. xm_operations_from_actions
  6. xm_read_targets_table_header
  7. xm_read_targets_table_rec
  8. xm_find_targets_table_idx
  9. x_atoms_compare
  10. xm_write_targets_table
  11. xm_write_drag_initiator_info
  12. xm_drag_window_error_handler
  13. xm_drag_window_io_error_handler
  14. x_special_window_exists_p
  15. xm_get_drag_window_1
  16. xm_get_drag_window
  17. xm_setup_dnd_targets
  18. xm_get_drag_atom_1
  19. xm_get_drag_atom
  20. xm_setup_drag_info
  21. xm_send_drop_message
  22. xm_send_top_level_enter_message
  23. xm_send_drag_motion_message
  24. xm_send_top_level_leave_message
  25. xm_read_drop_start_reply
  26. xm_read_drop_start_message
  27. xm_read_drag_receiver_info
  28. xm_read_drag_motion_message
  29. xm_read_drag_motion_reply
  30. x_dnd_send_xm_leave_for_drop
  31. x_dnd_free_toplevels
  32. x_dnd_compute_toplevels
  33. x_dnd_io_error_handler
  34. x_dnd_get_proxy_proto
  35. x_dnd_get_target_window_2
  36. x_dnd_get_target_window_1
  37. x_dnd_get_wm_state_and_proto
  38. x_dnd_do_unsupported_drop
  39. x_dnd_send_unsupported_drop
  40. x_dnd_fill_empty_target
  41. x_dnd_get_target_window
  42. x_dnd_get_window_proxy
  43. x_dnd_get_window_proto
  44. x_dnd_send_enter
  45. x_dnd_send_position
  46. x_dnd_send_leave
  47. x_dnd_send_drop
  48. x_dnd_do_drop
  49. x_set_dnd_targets
  50. x_free_dnd_targets
  51. x_clear_dnd_variables
  52. x_free_dnd_toplevels
  53. x_restore_events_after_dnd
  54. x_dnd_cancel_dnd_early
  55. x_dnd_cleanup_drag_and_drop
  56. x_dnd_note_self_position
  57. x_dnd_note_self_wheel
  58. x_dnd_note_self_drop
  59. x_flush
  60. x_drop_xrender_surfaces
  61. x_xr_ensure_picture
  62. record_event
  63. xi_frame_selected_for
  64. x_toolkit_position
  65. x_update_opaque_region
  66. x_gc_free_ext_data_private
  67. x_gc_get_ext_data
  68. x_extension_initialize
  69. xi_convert_button_state
  70. xi_convert_event_state
  71. xi_convert_event_keyboard_state
  72. x_free_xi_devices
  73. xi_populate_scroll_valuator
  74. xi_populate_device_from_info
  75. x_cache_xi_devices
  76. x_get_scroll_valuator_delta
  77. xi_device_from_id
  78. xi_link_touch_point
  79. xi_unlink_touch_point
  80. xi_unlink_touch_points
  81. xi_find_touch_point
  82. xi_reset_scroll_valuators_for_device_id
  83. x_cr_destroy_frame_context
  84. x_cr_update_surface_desired_size
  85. x_cr_gc_clip
  86. x_begin_cr_clip
  87. x_end_cr_clip
  88. x_set_cr_source_with_gc_foreground
  89. x_set_cr_source_with_gc_background
  90. x_cr_destroy_xlib_surface
  91. x_try_cr_xlib_drawable
  92. x_end_cr_xlib_drawable
  93. x_cr_define_fringe_bitmap
  94. x_cr_destroy_fringe_bitmap
  95. x_cr_draw_image
  96. x_cr_draw_frame
  97. x_cr_accumulate_data
  98. x_cr_destroy
  99. x_cr_export_frames
  100. x_xr_apply_ext_clip
  101. x_xr_reset_ext_clip
  102. x_set_clip_rectangles
  103. x_reset_clip_rectangles
  104. x_xrender_color_from_gc_foreground
  105. x_xrender_color_from_gc_background
  106. x_fill_rectangle
  107. x_clear_rectangle
  108. x_draw_rectangle
  109. x_clear_window
  110. x_fill_trapezoid_for_relief
  111. x_erase_corners_for_relief
  112. x_draw_horizontal_wave
  113. x_display_info_for_display
  114. x_find_topmost_parent
  115. x_set_frame_alpha
  116. x_if_event
  117. x_sync_get_monotonic_time
  118. x_sync_current_monotonic_time
  119. x_sync_note_frame_times
  120. x_sync_is_frame_drawn_event
  121. x_sync_wait_for_frame_drawn_event
  122. x_sync_update_begin
  123. x_sync_trigger_fence
  124. x_sync_init_fences
  125. x_sync_free_fences
  126. x_sync_update_finish
  127. x_sync_handle_frame_drawn
  128. x_update_begin
  129. x_draw_vertical_window_border
  130. x_draw_window_divider
  131. show_back_buffer
  132. x_flip_and_flush
  133. x_update_end
  134. XTframe_up_to_date
  135. XTbuffer_flipping_unblocked_hook
  136. x_clear_under_internal_border
  137. x_after_update_window_line
  138. x_premultiply_pixel
  139. x_draw_fringe_bitmap
  140. x_display_set_last_user_time
  141. x_set_gtk_user_time
  142. x_create_special_window
  143. x_update_frame_user_time_window
  144. x_set_last_user_time_from_lisp
  145. x_set_cursor_gc
  146. x_set_mouse_face_gc
  147. x_set_mode_line_face_gc
  148. x_set_glyph_string_gc
  149. x_set_glyph_string_clipping
  150. x_set_glyph_string_clipping_exactly
  151. x_compute_glyph_string_overhangs
  152. x_clear_glyph_string_rect
  153. x_clear_point
  154. x_draw_glyph_string_background
  155. x_draw_glyph_string_foreground
  156. x_draw_composite_glyph_string_foreground
  157. x_draw_glyphless_glyph_string_foreground
  158. x_frame_of_widget
  159. x_alloc_lighter_color_for_widget
  160. cvt_string_to_pixel
  161. cvt_pixel_dtor
  162. x_color_cells
  163. x_query_colors
  164. x_query_frame_background_color
  165. x_hash_string_ignore_case
  166. x_parse_color
  167. x_alloc_nearest_color_1
  168. x_alloc_nearest_color
  169. x_copy_color
  170. x_alloc_lighter_color
  171. x_setup_relief_color
  172. x_setup_relief_colors
  173. x_fill_triangle
  174. x_make_point
  175. x_inside_rect_p
  176. x_draw_relief_rect
  177. x_draw_box_rect
  178. x_draw_glyph_string_box
  179. x_composite_image
  180. x_draw_image_foreground
  181. x_draw_image_relief
  182. x_draw_image_foreground_1
  183. x_draw_glyph_string_bg_rect
  184. x_draw_image_glyph_string
  185. x_draw_stretch_glyph_string
  186. x_get_scale_factor
  187. x_draw_underwave
  188. x_draw_glyph_string
  189. x_shift_glyphs_for_insert
  190. x_delete_glyphs
  191. x_clear_area1
  192. x_clear_area
  193. x_clear_frame
  194. x_send_hourglass_message
  195. x_show_hourglass
  196. x_hide_hourglass
  197. XTflash
  198. XTring_bell
  199. x_ins_del_lines
  200. x_scroll_run
  201. x_frame_highlight
  202. x_frame_unhighlight
  203. x_new_focus_frame
  204. x_fixes_pointer_blanking_supported
  205. xfixes_toggle_visible_pointer
  206. make_invisible_cursor
  207. x_toggle_visible_pointer
  208. XTtoggle_invisible_pointer
  209. x_focus_changed
  210. x_window_to_frame
  211. x_tooltip_window_to_frame
  212. x_any_window_to_frame
  213. x_menubar_window_to_frame
  214. x_top_window_to_frame
  215. x_top_window_to_frame
  216. x_next_event_from_any_display
  217. x_handle_pending_selection_requests_1
  218. x_handle_pending_selection_requests
  219. x_push_selection_request
  220. x_detect_pending_selection_requests
  221. x_clear_dnd_action
  222. x_dnd_delete_action_list
  223. x_dnd_lose_ownership
  224. x_dnd_process_quit
  225. x_dnd_begin_drag_and_drop

     1 /* X Communication module for terminals which understand the X protocol.
     2 
     3 Copyright (C) 1989, 1993-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 /* New display code by Gerd Moellmann <gerd@gnu.org>.  */
    21 /* Xt features made by Fred Pierresteguy.  */
    22 
    23 /* X window system support for GNU Emacs
    24 
    25    This file is part of the X window system support for GNU Emacs.  It
    26    contains subroutines comprising the redisplay interface, setting up
    27    scroll bars and widgets, and handling input.
    28 
    29    X WINDOW SYSTEM
    30 
    31    The X Window System is a windowing system for bitmap graphics
    32    displays which originated at MIT in 1984.  Version 11, which is
    33    currently supported by Emacs, first appeared in September 1987.
    34 
    35    X has a long history and has been developed by many different
    36    organizations over the years; at present, it is being primarily
    37    developed by the X.Org Foundation.  It is the main window system
    38    that Emacs is developed and tested against, and X version 10 was
    39    the first window system that Emacs was ported to.  As a consequence
    40    of its age and wide availability, X contains many idiosyncrasies,
    41    but that has not prevented it from becoming the dominant free
    42    window system, and the platform of reference for all GUI code in
    43    Emacs.
    44 
    45    Some of what is explained below also applies to the other window
    46    systems that Emacs supports, to varying degrees.  YMMV.
    47 
    48    INPUT
    49 
    50    Emacs handles input by running pselect in a loop, which returns
    51    whenever there is input available on the connection to the X
    52    server.  On some systems, Emacs also arranges for any new input on
    53    that connection to send an asynchronous signal.  Whenever pselect
    54    returns, or such a signal is received and input is not blocked,
    55    XTread_socket is called and translates X11 events read by Xlib into
    56    struct input_events, which are then stored in the keyboard buffer,
    57    to be processed and acted upon at some later time.  The function
    58    handle_one_xevent is responsible for handling core events after
    59    they are filtered, and filtering X Input Extension events.  It also
    60    performs actions on some special events, such as updating the
    61    dimensions of a frame after a ConfigureNotify is sent by the X
    62    server to inform us that it changed.
    63 
    64    Before such events are translated, an Emacs build with
    65    internationalization enabled (the default since X11R6) will filter
    66    events through an X Input Method (XIM) or GTK, which might decide
    67    to intercept the event and send a different one in its place, for
    68    reasons such as enabling the user to insert international
    69    characters that aren't on his keyboard by typing a sequence of
    70    characters which are.  See the function x_filter_event and its
    71    callers for more details.
    72 
    73    Events that cause Emacs to quit are treated specially by the code
    74    that stores them in the keyboard buffer and generally cause an
    75    immediate interrupt.  Such an interrupt can lead to a longjmp from
    76    the code that stored the keyboard event, which isn't safe inside
    77    XTread_socket.  To avoid this problem, XTread_socket is provided a
    78    special event buffer named hold_quit.  When a quit event is
    79    encountered, it is stored inside this special buffer, which will
    80    cause the keyboard code that called XTread_socket to store it at a
    81    later time when it is safe to do so.
    82 
    83    handle_one_xevent will generally have to determine which frame an
    84    event should be attributed to.  This is not easy, because events
    85    can come from multiple X windows, and a frame can also have
    86    multiple windows.  handle_one_xevent usually calls the function
    87    x_any_window_to_frame, which searches for a frame by toplevel
    88    window and widget windows.  There are also some other functions for
    89    searching by specific types of window, such as
    90    x_top_window_to_frame (which only searches for frames by toplevel
    91    window), and x_menubar_window_to_frame (which will only search
    92    through frame menu bars).
    93 
    94    INPUT FOCUS
    95 
    96    Under X, the window where keyboard input is sent is not always
    97    explicitly defined.  When there is a focus window, it receives what
    98    is referred to as "explicit focus", but when there is none, it
    99    receives "implicit focus" whenever the pointer enters it, and loses
   100    that focus when the pointer leaves.  When the toplevel window of a
   101    frame receives an explicit focus event (FocusIn or FocusOut), we
   102    treat that frame as having the current input focus, but when there
   103    is no focus window, we treat each frame as having the input focus
   104    whenever the pointer enters it, and undo that treatment when the
   105    pointer leaves it.  See the callers of x_detect_focus_change for
   106    more details.
   107 
   108    REDISPLAY
   109 
   110    The redisplay engine communicates with X through the "redisplay
   111    interface", which is a structure containing pointers to functions
   112    which output graphics to a frame.
   113 
   114    Some of the functions included in the redisplay interface include
   115    `x_clear_frame_area', which is called by the display engine when it
   116    determines that a part of the display has to be cleared,
   117    x_draw_window_cursor, which is called to perform the calculations
   118    necessary to display the cursor glyph with a special "highlight"
   119    (more on that later) and to set the input method spot location.
   120 
   121    Most of the actual display is performed by the function
   122    `x_draw_glyph_string', also included in the redisplay interface.
   123    It takes a list of glyphs of the same type and face, computes the
   124    correct graphics context for the string through the function
   125    `x_set_glyph_string_gc', and draws whichever glyphs it might
   126    contain, along with decorations such as the box face, underline and
   127    overline.  That list is referred to as a "glyph string".
   128 
   129    GRAPHICS CONTEXTS
   130 
   131    A graphics context ("GC") is an X server-side object which contains
   132    drawing attributes such as fill style, stipple, and foreground and
   133    background pixel values.
   134 
   135    Usually, one graphics context is computed for each face when it is
   136    about to be displayed for the first time, and this graphics context
   137    is the one which is used for future X drawing operations in a glyph
   138    string with that face.  (See `prepare_face_for_display' in
   139    xfaces.c).
   140 
   141    However, when drawing glyph strings for special display elements
   142    such as the cursor, or mouse sensitive text, different GCs may be
   143    used.  When displaying the cursor, for example, the frame's cursor
   144    graphics context is used for the common case where the cursor is
   145    drawn with the default font, and the colors of the string's face
   146    are the same as the default face.  In all other cases, a temporary
   147    graphics context is created with the foreground and background
   148    colors of the cursor face adjusted to ensure that the cursor can be
   149    distinguished from its surroundings and that the text inside the
   150    cursor stays visible.
   151 
   152    Various graphics contexts are also calculated when the frame is
   153    created by the function `x_make_gcs' in xfns.c, and are adjusted
   154    whenever the foreground or background colors change.  The "normal"
   155    graphics context is used for operations performed without a face,
   156    and always corresponds to the foreground and background colors of
   157    the frame's default face, the "reverse" graphics context is used to
   158    draw text in inverse video, and the cursor graphics context is used
   159    to display the cursor in the most common case.
   160 
   161    N.B. that some of the other window systems supported by use an
   162    emulation of graphics contexts to hold the foreground and
   163    background colors used in a glyph string, while the some others
   164    ports compute those colors directly based on the colors of the
   165    string's face and its highlight, but only on X are graphics
   166    contexts a data structure inherent to the window system.
   167 
   168    COLOR ALLOCATION
   169 
   170    In (and only in) X, pixel values for colors are not guaranteed to
   171    correspond to their individual components.  The rules for
   172    converting colors into pixel values are defined by the visual class
   173    of each display opened by Emacs.  When a display is opened, a
   174    suitable visual is obtained from the X server, and a colormap is
   175    created based on that visual, which is then used for each frame
   176    created.
   177 
   178    The colormap is then used by the X server to convert pixel values
   179    from a frame created by Emacs into actual colors which are output
   180    onto the physical display.
   181 
   182    When the visual class is TrueColor, the colormap will be indexed
   183    based on the red, green, and blue (RGB) components of the pixel
   184    values, and the colormap will be statically allocated so as to
   185    contain linear ramps for each component.  As such, most of the
   186    color allocation described below is bypassed, and the pixel values
   187    are computed directly from the color.
   188 
   189    Otherwise, each time Emacs wants a pixel value that corresponds to
   190    a color, Emacs has to ask the X server to obtain the pixel value
   191    that corresponds to a "color cell" containing the color (or a close
   192    approximation) from the colormap.  Exactly how this is accomplished
   193    further depends on the visual class, since some visuals have
   194    immutable colormaps which contain color cells with pre-defined
   195    values, while others have colormaps where the color cells are
   196    dynamically allocated by individual X clients.
   197 
   198    With visuals that have a visual class of StaticColor and StaticGray
   199    (where the former is the case), the X server is asked to procure
   200    the pixel value of a color cell that contains the closest
   201    approximation of the color which Emacs wants.  On the other hand,
   202    when the visual class is DirectColor, PseudoColor, or GrayScale,
   203    where color cells are dynamically allocated by clients, Emacs asks
   204    the X server to allocate a color cell containing the desired color,
   205    and uses its pixel value.
   206 
   207    (If the color already exists, the X server returns an existing color
   208    cell, but increases its reference count, so it still has to be
   209    freed afterwards.)
   210 
   211    Otherwise, if no color could be allocated (due to the colormap
   212    being full), Emacs looks for a color cell inside the colormap
   213    closest to the desired color, and uses its pixel value instead.
   214 
   215    Since the capacity of a colormap is finite, X clients have to take
   216    special precautions in order to not allocate too many color cells
   217    that are never used.  Emacs allocates its color cells when a face
   218    is being realized or when a frame changes its foreground and
   219    background colors, and releases them alongside the face or frame.
   220    See calls to `unload_color' and `load_color' in xterm.c, xfaces.c
   221    and xfns.c for more details.
   222 
   223    The driving logic behind color allocation is in
   224    `x_alloc_nearest_color_1', while the optimization for TrueColor
   225    visuals is in `x_make_truecolor_pixel'.  Also see `x_query_colors`,
   226    which is used to determine the color values for given pixel
   227    values.
   228 
   229    In other window systems supported by Emacs, color allocation is
   230    handled by the window system itself, to whom Emacs simply passes 24
   231    (or 32-bit) RGB values.
   232 
   233    OPTIONAL FEATURES
   234 
   235    While X servers and client libraries tend to come with many
   236    extensions to the core X11R6 protocol, dependencies on anything
   237    other than the core X11R6 protocol and Xlib should be optional at
   238    both compile-time and runtime.  Emacs should also not crash
   239    regardless of what combination of X server and client-side features
   240    are present.  For example, if you are developing a feature that
   241    will need Xfixes, then add a test in configure.ac for the library
   242    at compile-time which defines `HAVE_XFIXES', like this:
   243 
   244      ### Use Xfixes (-lXfixes) if available
   245      HAVE_XFIXES=no
   246      if test "${HAVE_X11}" = "yes"; then
   247        XFIXES_REQUIRED=4.0.0
   248        XFIXES_MODULES="xfixes >= $XFIXES_REQUIRED"
   249        EMACS_CHECK_MODULES([XFIXES], [$XFIXES_MODULES])
   250        if test $HAVE_XFIXES = no; then
   251          # Test old way in case pkg-config doesn't have it (older machines).
   252          AC_CHECK_HEADER([X11/extensions/Xfixes.h],
   253            [AC_CHECK_LIB([Xfixes], [XFixesHideCursor], [HAVE_XFIXES=yes])])
   254          if test $HAVE_XFIXES = yes; then
   255            XFIXES_LIBS=-lXfixes
   256          fi
   257        fi
   258        if test $HAVE_XFIXES = yes; then
   259          AC_DEFINE([HAVE_XFIXES], [1],
   260            [Define to 1 if you have the Xfixes extension.])
   261        fi
   262      fi
   263      AC_SUBST([XFIXES_CFLAGS])
   264      AC_SUBST([XFIXES_LIBS])
   265 
   266   Then, make sure to adjust CFLAGS and LIBES in src/Makefile.in and
   267   add the new XFIXES_CFLAGS and XFIXES_LIBS variables to
   268   msdos/sed1v2.inp.  (The latter has to be adjusted for any new
   269   variables that are included in CFLAGS and LIBES even if the
   270   libraries are not used by the MS-DOS port.)
   271 
   272   Finally, add some fields in `struct x_display_info' which specify
   273   the major and minor versions of the extension, and whether or not to
   274   support them.  They (and their accessors) should be protected by the
   275   `HAVE_XFIXES' preprocessor conditional.  Then, these fields should
   276   be set in `x_term_init', and all Xfixes calls must be protected by
   277   not only the preprocessor conditional, but also by checks against
   278   those variables.
   279 
   280   X TOOLKIT SUPPORT
   281 
   282   Emacs supports being built with many different toolkits (and also no
   283   toolkit at all), which provide decorations such as menu bars and
   284   scroll bars, along with handy features like file panels, dialog
   285   boxes, font panels, and popup menus.  Those configurations can
   286   roughly be classified as belonging to one of three categories:
   287 
   288     - Using no toolkit at all.
   289     - Using the X Toolkit Intrinsics (Xt).
   290     - Using GTK.
   291 
   292   The no toolkit configuration is the simplest: no toolkit widgets are
   293   used, Emacs uses its own implementation of scroll bars, and the
   294   XMenu library that came with X11R2 and earlier versions of X is used
   295   for popup menus.  There is also no complicated window structure to
   296   speak of.
   297 
   298   The Xt configurations come in either the Lucid or Motif flavors.
   299   The former utilizes Emacs's own Xt-based Lucid widget library for
   300   menus, and Xaw (or derivatives such as neXTaw and Xaw3d) for dialog
   301   boxes and, optionally, scroll bars.  It does not support file
   302   panels.  The latter uses either Motif or LessTif for menu bars,
   303   popup menus, dialogs and file panels.
   304 
   305   The GTK configurations come in the GTK+ 2 or GTK 3 configurations,
   306   where the toolkit provides all the aforementioned decorations and
   307   features.  They work mostly the same, though GTK 3 has various small
   308   annoyances that complicate maintenance.
   309 
   310   All of those configurations have various special technicalities
   311   about event handling and the layout of windows inside a frame that
   312   must be kept in mind when writing X code which is run on all of
   313   them.
   314 
   315   The no toolkit configuration has no noteworthy aspects about the
   316   layout of windows inside a frame, since each frame has only one
   317   associated window aside from scroll bars.  However, in the Xt
   318   configurations, every widget is a separate window, and there are
   319   quite a few widgets.  The "outer widget", a widget of class
   320   ApplicationShell, is the top-level window of a frame.  Its window is
   321   accessed via the macro `FRAME_OUTER_WINDOW'.  The "edit widget", a
   322   widget class of EmacsFrame, is a child of the outer widget that
   323   controls the size of a frame as known to Emacs, and is the widget
   324   that Emacs draws to during display operations.  The "menu bar
   325   widget" is the widget holding the menu bar.
   326 
   327   Special care must be taken when performing operations on a frame.
   328   Properties that are used by the window manager, for example, must be
   329   set on the outer widget.  Drawing, on the other hand, must be done
   330   to the edit widget, and button press events on the menu bar widget
   331   must be redirected and not sent to Xt until the Lisp code is run to
   332   update the menu bar.
   333 
   334   The EmacsFrame widget is specific to Emacs and is implemented in
   335   widget.c.  See that file for more details.
   336 
   337   In the GTK configurations, GTK widgets do not necessarily correspond
   338   to X windows, since the toolkit might decide to keep only a
   339   client-side record of the widgets for performance reasons.
   340 
   341   Because the GtkFixed widget that holds the "edit area" might not
   342   correspond to an X window, drawing operations may be directly
   343   performed on the outer window, with special care taken to not
   344   overwrite the surrounding GTK widgets.  This also means that the
   345   only important window for most purposes is the outer window, which
   346   on GTK builds can usually be accessed using the macro
   347   `FRAME_X_WINDOW'.
   348 
   349   How `handle_one_xevent' is called also depends on the configuration.
   350   Without a toolkit, Emacs performs all event processing by itself,
   351   running XPending and XNextEvent in a loop whenever there is input,
   352   passing the event to `handle_one_xevent'.
   353 
   354   When using Xt, the same is performed, but `handle_one_xevent' may
   355   also decide to call XtDispatchEvent on an event after Emacs finishes
   356   processing it.
   357 
   358   When using GTK, however, `handle_one_xevent' is called from an event
   359   filter installed on the GTK event loop.  Unless the event filter
   360   elects to drop the event, it will be passed to GTK right after
   361   leaving the event filter.
   362 
   363   Fortunately, `handle_one_xevent' is provided a `*finish' parameter
   364   that abstracts away all these details.  If it is `X_EVENT_DROP',
   365   then the event will not be dispatched to Xt or utilized by GTK.
   366   Code inside `handle_one_xevent' should thus avoid making assumptions
   367   about the event dispatch mechanism and use that parameter
   368   instead.
   369 
   370   FRAME RESIZING
   371 
   372   In the following explanations "frame size" refers to the "native
   373   size" of a frame as reported by the (frame.h) macros
   374   FRAME_PIXEL_WIDTH and FRAME_PIXEL_HEIGHT.  These specify the size of
   375   a frame as the values passed to/received from a toolkit and the
   376   window manager.  The "text size" Emacs Lisp code uses in functions
   377   like 'set-frame-size' or sees in the ‘width’ and 'height' frame
   378   parameters is only loosely related to the native size.  The
   379   necessary translations are provided by the macros
   380   FRAME_TEXT_TO_PIXEL_WIDTH and FRAME_TEXT_TO_PIXEL_HEIGHT as well as
   381   FRAME_PIXEL_TO_TEXT_WIDTH and FRAME_PIXEL_TO_TEXT_HEIGHT (in
   382   frame.h).
   383 
   384   Lisp functions may ask for resizing a frame either explicitly, using
   385   one of the interfaces provided for that purpose like, for example,
   386   'set-frame-size' or changing the 'height' or 'width' parameter of
   387   that frame, or implicitly, for example, by turning off/on or
   388   changing the width of fringes or scroll bars for that frame.  Any
   389   such request passes through the routine 'adjust_frame_size' (in
   390   frame.c) which decides, among others, whether the native frame size
   391   would really change and whether it is allowed to change it at that
   392   moment.  Only if 'adjust_frame_size' decides that the corresponding
   393   terminal's 'set_window_size_hook' may be run, it will dispatch
   394   execution to the appropriate function which, for X builds, is
   395   'x_set_window_size' in this file.
   396 
   397   For GTK builds, 'x_set_window_size' calls 'xg_frame_set_char_size'
   398   in gtkutil.c if the frame has an edit widget and
   399   'x_set_window_size_1' in this file otherwise.  For non-GTK builds,
   400   'x_set_window_size' always calls 'x_set_window_size_1' directly.
   401 
   402   'xg_frame_set_char_size' calls the GTK function 'gtk_window_resize'
   403   for the frame's outer widget; x_set_window_size_1 calls the Xlib
   404   function 'XResizeWindow' instead.  In either case, if Emacs thinks
   405   that the frame is visible, it will wait for a ConfigureNotify event
   406   (see below) to occur within a timeout of 'x-wait-for-event-timeout'
   407   (the default is 0.1 seconds).  If Emacs thinks that the frame is not
   408   visible, it calls 'adjust_frame_size' to run 'resize_frame_windows'
   409   (see below) and hopes for the best.
   410 
   411   Note that if Emacs receives a ConfigureEvent in response to an
   412   earlier resize request, the sizes specified by that event are not
   413   necessarily the sizes Emacs requested.  Window manager and toolkit
   414   may override any of the requested sizes for their own reasons.
   415 
   416   On X, size notifications are received as ConfigureNotify events.
   417   The expected reaction to such an event on the Emacs side is to
   418   resize all Emacs windows that are on the frame referred to by the
   419   event.  Since resizing Emacs windows and redisplaying their buffers
   420   is a costly operation, Emacs may collapse several subsequent
   421   ConfigureNotify events into one to avoid that Emacs falls behind in
   422   user interactions like resizing a frame by dragging one of its
   423   borders with the mouse.
   424 
   425   Each ConfigureEvent event specifies a window, a width and a height.
   426   The event loop uses 'x_top_window_to_frame' to associate the window
   427   with its frame.  Once the frame has been identified, on GTK the
   428   event is dispatched to 'xg_frame_resized'.  On Motif/Lucid
   429   'x_window' has installed 'EmacsFrameResize' as the routine that
   430   handles resize events.  In either case, these routines end up
   431   calling the function 'change_frame_size' in dispnew.c.  On
   432   non-toolkit builds the effect is to call 'change_frame_size'
   433   directly from the event loop.  In either case, the value true is
   434   passed as the DELAY argument.
   435 
   436   'change_frame_size' is the central function to decide whether it is
   437   safe to process a resize request immediately or it has to be delayed
   438   (usually because its DELAY argument is true).  Since resizing a
   439   frame's windows may run arbitrary Lisp code, Emacs cannot generally
   440   process resize requests during redisplay and therefore has to queue
   441   them.  If processing the event must be delayed, the new sizes (that
   442   is, the ones requested by the ConfigureEvent) are stored in the
   443   new_width and new_height slots of the respective frame structure,
   444   possibly replacing ones that have been stored there upon the receipt
   445   of a preceding ConfigureEvent.
   446 
   447   Delayed size changes are applied eventually upon calls of the
   448   function 'do_pending_window_change' (in dispnew.c) which is called
   449   by the redisplay code at suitable spots where it's safe to change
   450   sizes.  'do_pending_window_change' calls 'change_frame_size' with
   451   its DELAY argument false in the hope that it is now safe to call the
   452   function 'resize_frame_windows' (in window.c) which is in charge of
   453   adjusting the sizes of all Emacs windows on the frame accordingly.
   454   Note that if 'resize_frame_windows' decides that the windows of a
   455   frame do not fit into the constraints set up by the new frame sizes,
   456   it will resize the windows to some minimum sizes with the effect
   457   that parts of the frame at the right and bottom will appear clipped
   458   off.
   459 
   460   In addition to explicitly passing width and height values in
   461   functions like 'gtk_window_resize' or 'XResizeWindow', Emacs also
   462   sets window manager size hints - a more implicit form of asking for
   463   the size Emacs would like its frames to assume.  Some of these hints
   464   only restate the size and the position explicitly requested for a
   465   frame.  Another hint specifies the increments in which the window
   466   manager should resize a frame to - either set to the default
   467   character size of a frame or to one pixel for a non-nil value of
   468   'frame-resize-pixelwise'.  See the function 'x_wm_set_size_hint' -
   469   in gtkutil.c for GTK and in this file for other builds - for the
   470   details.
   471 
   472   We have not discussed here a number of special issues like, for
   473   example, how to handle size requests and notifications for maximized
   474   and fullscreen frames or how to resize child frames.  Some of these
   475   require special treatment depending on the desktop or window manager
   476   used.
   477 
   478   One thing that might come handy when investigating problems wrt
   479   resizing frames is the variable 'frame-size-history'.  Setting this
   480   to a non-nil value, will cause Emacs to start recording frame size
   481   adjustments, usually specified by the function that asked for an
   482   adjustment, a sizes part that records the old and new values of the
   483   frame's width and height and maybe some additional information.  The
   484   internal function `frame--size-history' can then be used to display
   485   the value of this variable in a more readable form.
   486 
   487   FRAME RESIZE SYNCHRONIZATION
   488 
   489   The X window system operates asynchronously.  That is to say, the
   490   window manager and X server might think a window has been resized
   491   before Emacs has a chance to process the ConfigureNotify event that
   492   was sent.
   493 
   494   When a compositing manager is present, and the X server and Emacs
   495   both support the X synchronization extension, the semi-standard
   496   frame synchronization protocol can be used to notify the compositing
   497   manager of when Emacs has actually finished redisplaying the
   498   contents of a frame after a resize.  The compositing manager will
   499   customarily then postpone displaying the contents of the frame until
   500   the redisplay is complete.
   501 
   502   Emacs announces support for this protocol by creating an X
   503   server-side counter object, and setting it as the
   504   `_NET_WM_SYNC_REQUEST_COUNTER' property of the frame's top-level
   505   window.  The window manager then initiates the synchronized resize
   506   process by sending Emacs a ClientMessage event before the
   507   ConfigureNotify event where:
   508 
   509     type = ClientMessage
   510     window = the respective client window
   511     message_type = WM_PROTOCOLS
   512     format = 32
   513     data.l[0] = _NET_WM_SYNC_REQUEST
   514     data.l[1] = timestamp
   515     data.l[2] = low 32 bits of a provided frame counter value
   516     data.l[3] = high 32 bits of a provided frame counter value
   517     data.l[4] = 1 if the extended frame counter should be updated,
   518     otherwise 0
   519 
   520   Upon receiving such an event, Emacs constructs and saves a counter
   521   value from the provided low and high 32 bits.  Then, when the
   522   display engine tells us that a frame has been completely updated
   523   (presumably because of a redisplay caused by a ConfigureNotify
   524   event), we set the counter to the saved value, telling the
   525   compositing manager that the contents of the window now accurately
   526   reflect the new size.  The compositing manager will then display the
   527   contents of the window, and the window manager might also postpone
   528   updating the window decorations until this moment.
   529 
   530   DRAG AND DROP
   531 
   532   Drag and drop in Emacs is implemented in two ways, depending on
   533   which side initiated the drag-and-drop operation.  When another X
   534   client initiates a drag, and the user drops something on Emacs, a
   535   `drag-n-drop-event' is sent with the contents of the ClientMessage,
   536   and further processing (i.e. retrieving selection contents and
   537   replying to the initiating client) is performed from Lisp inside
   538   `x-dnd.el'.
   539 
   540   However, dragging contents from Emacs is implemented almost entirely
   541   in C.  X Windows has several competing drag-and-drop protocols, of
   542   which Emacs supports two on the C level: the XDND protocol (see
   543   https://freedesktop.org/wiki/Specifications/XDND) and the Motif drag
   544   and drop protocols.  These protocols are based on the initiator
   545   owning a special selection, specifying an action the recipient
   546   should perform, grabbing the mouse, and sending various different
   547   client messages to the toplevel window underneath the mouse as it
   548   moves, or when buttons are released.
   549 
   550   The Lisp interface to drag-and-drop is synchronous, and involves
   551   running a nested event loop with some global state until the drag
   552   finishes.  When the mouse moves, Emacs looks up the toplevel window
   553   underneath the pointer (the target window) either using a cache
   554   provided by window managers that support the
   555   _NET_WM_CLIENT_LIST_STACKING root window property, or by calling
   556   XTranslateCoordinates in a loop until a toplevel window is found,
   557   and sends various entry, exit, or motion events to the window
   558   containing a list of targets the special selection can be converted
   559   to, and the chosen action that the recipient should perform.  The
   560   recipient can then send messages in reply detailing the action it
   561   has actually chosen to perform.  Finally, when the mouse buttons are
   562   released over the recipient window, Emacs sends a "drop" message to
   563   the target window, waits for a reply, and returns the action
   564   selected by the recipient to the Lisp code that initiated the
   565   drag-and-drop operation.
   566 
   567   When a drop happens on a window not supporting any protocol
   568   implemented on the C level, the function inside
   569   `x-dnd-unsupported-drop-function' is called with some parameters of
   570   the drop.  If it returns non-nil, then Emacs tries to simulate a
   571   drop happening with the primary selection and synthetic button
   572   events (see `x_dnd_do_unsupported_drop').  That function implements
   573   the OffiX drag-and-drop protocol by default.  See
   574   `x-dnd-handle-unsupported-drop' in `x-dnd.el' for more details.
   575 
   576   DISPLAY ERROR HANDLING
   577 
   578   While error handling under X was originally designed solely as a
   579   mechanism for the X server to report fatal errors to clients, most
   580   clients (including Emacs) have adopted a system of "error traps" to
   581   handle or discard these errors as they arrive.  Discarding errors is
   582   usually necessary when Emacs performs an X request that might fail:
   583   for example, sending a message to a window that may no longer exist,
   584   or might not exist at all.  Handling errors is then necessary when
   585   the detailed error must be reported to another piece of code: for
   586   example, as a Lisp error.
   587 
   588   It is not acceptable for Emacs to crash when it is sent invalid data
   589   by another client, or by Lisp.  As a result, errors must be caught
   590   around Xlib functions generating requests containing resource
   591   identifiers that could potentially be invalid, such as window or
   592   atom identifiers provided in a client message from another program,
   593   or a child window ID obtained through XTranslateCoordinates that may
   594   refer to a window that has been deleted in the meantime.
   595 
   596   There are two sets of functions used to perform this "error
   597   trapping".  Which one should be used depends on what kind of
   598   processing must be done on the error.  The first consists of the
   599   functions `x_ignore_errors_for_next_request' and
   600   `x_stop_ignoring_errors', which ignore errors generated by requests
   601   made in between a call to the first function and a corresponding
   602   call to the second.  They should be used for simple asynchronous
   603   requests that do not require a reply from the X server: using them
   604   instead of the second set improves performance, as they simply
   605   record a range of request serials to ignore errors from, instead of
   606   synchronizing with the X server to handle errors.
   607 
   608   The second set consists of the following functions:
   609 
   610     - x_catch_errors_with_handler
   611     - x_catch_errors
   612     - x_uncatch_errors_after_check
   613     - x_uncatch_errors
   614     - x_check_errors
   615     - x_had_errors_p
   616     - x_clear_errors
   617 
   618   Callers using this set should consult the comment(s) on top of the
   619   aformentioned functions.  They should not be used when the requests
   620   being made do not require roundtrips to the X server, and obtaining
   621   the details of any error generated is unecessary, as
   622   `x_uncatch_errors' will always synchronize with the X server, which
   623   is a potentially slow operation.  */
   624 
   625 #include <config.h>
   626 #include <stdlib.h>
   627 #include <math.h>
   628 #include <signal.h>
   629 
   630 #include "lisp.h"
   631 #include "blockinput.h"
   632 #include "sysstdio.h"
   633 
   634 /* This may include sys/types.h, and that somehow loses
   635    if this is not done before the other system files.  */
   636 #include "xterm.h"
   637 #include <X11/cursorfont.h>
   638 
   639 #ifdef HAVE_X_I18N
   640 #include "textconv.h"
   641 #endif
   642 
   643 #ifdef USE_XCB
   644 #include <xcb/xproto.h>
   645 #include <xcb/xcb.h>
   646 #endif
   647 
   648 /* If we have Xfixes extension, use it for pointer blanking.  */
   649 #ifdef HAVE_XFIXES
   650 #include <X11/extensions/Xfixes.h>
   651 #endif
   652 
   653 #ifdef HAVE_XDBE
   654 #include <X11/extensions/Xdbe.h>
   655 #endif
   656 
   657 #ifdef HAVE_XINPUT2
   658 #include <X11/extensions/XInput2.h>
   659 #endif
   660 
   661 #ifdef HAVE_XRANDR
   662 #include <X11/extensions/Xrandr.h>
   663 #endif
   664 
   665 #ifdef HAVE_XSYNC
   666 #include <X11/extensions/sync.h>
   667 #endif
   668 
   669 #ifdef HAVE_XINERAMA
   670 #include <X11/extensions/Xinerama.h>
   671 #endif
   672 
   673 #ifdef HAVE_XCOMPOSITE
   674 #include <X11/extensions/Xcomposite.h>
   675 #endif
   676 
   677 #ifdef HAVE_XSHAPE
   678 #include <X11/extensions/shape.h>
   679 #endif
   680 
   681 #ifdef HAVE_XCB_SHAPE
   682 #include <xcb/shape.h>
   683 #endif
   684 
   685 /* Load sys/types.h if not already loaded.
   686    In some systems loading it twice is suicidal.  */
   687 #ifndef makedev
   688 #include <sys/types.h>
   689 #endif /* makedev */
   690 
   691 #include <sys/ioctl.h>
   692 
   693 #include "systime.h"
   694 
   695 #include <fcntl.h>
   696 #include <errno.h>
   697 #include <sys/stat.h>
   698 #include <flexmember.h>
   699 #include <c-ctype.h>
   700 #include <byteswap.h>
   701 
   702 #include "character.h"
   703 #include "coding.h"
   704 #include "composite.h"
   705 #include "frame.h"
   706 #include "dispextern.h"
   707 #include "xwidget.h"
   708 #include "fontset.h"
   709 #include "termhooks.h"
   710 #include "termopts.h"
   711 #include "termchar.h"
   712 #include "emacs-icon.h"
   713 #include "buffer.h"
   714 #include "window.h"
   715 #include "keyboard.h"
   716 #include "atimer.h"
   717 #include "font.h"
   718 #include "xsettings.h"
   719 #include "sysselect.h"
   720 #include "menu.h"
   721 #include "pdumper.h"
   722 
   723 #ifdef USE_X_TOOLKIT
   724 #include <X11/Shell.h>
   725 #include <X11/ShellP.h>
   726 #endif
   727 
   728 #include <unistd.h>
   729 
   730 #ifdef USE_GTK
   731 #include "gtkutil.h"
   732 #ifdef HAVE_GTK3
   733 #include <X11/Xproto.h>
   734 #endif
   735 #endif
   736 
   737 #if defined (USE_LUCID) || defined (USE_MOTIF)
   738 #include "../lwlib/xlwmenu.h"
   739 #endif
   740 
   741 #ifdef HAVE_XWIDGETS
   742 #include <cairo-xlib.h>
   743 #endif
   744 
   745 #ifdef USE_MOTIF
   746 #include <Xm/Xm.h>
   747 #include <Xm/CascadeB.h>
   748 #endif
   749 
   750 #ifdef USE_X_TOOLKIT
   751 
   752 /* Include toolkit specific headers for the scroll bar widget.  */
   753 #ifdef USE_TOOLKIT_SCROLL_BARS
   754 #if defined USE_MOTIF
   755 #include <Xm/ScrollBar.h>
   756 #else /* !USE_MOTIF i.e. use Xaw */
   757 
   758 #ifdef HAVE_XAW3D
   759 #include <X11/Xaw3d/Simple.h>
   760 #include <X11/Xaw3d/Scrollbar.h>
   761 #include <X11/Xaw3d/ThreeD.h>
   762 #else /* !HAVE_XAW3D */
   763 #include <X11/Xaw/Simple.h>
   764 #include <X11/Xaw/Scrollbar.h>
   765 #endif /* !HAVE_XAW3D */
   766 #ifndef XtNpickTop
   767 #define XtNpickTop "pickTop"
   768 #endif /* !XtNpickTop */
   769 #endif /* !USE_MOTIF */
   770 #endif /* USE_TOOLKIT_SCROLL_BARS */
   771 
   772 #endif /* USE_X_TOOLKIT */
   773 
   774 #ifdef USE_X_TOOLKIT
   775 #include "widget.h"
   776 #ifndef XtNinitialState
   777 #define XtNinitialState "initialState"
   778 #endif
   779 #endif
   780 
   781 #ifdef USE_GTK
   782 #include <xgselect.h>
   783 #endif
   784 
   785 #include "bitmaps/gray.xbm"
   786 
   787 #ifdef HAVE_XKB
   788 #include <X11/XKBlib.h>
   789 #endif
   790 
   791 /* Although X11/Xlib.h commonly defines the types XErrorHandler and
   792    XIOErrorHandler, they are not in the Xlib spec, so for portability
   793    define and use names with an Emacs_ prefix instead.  */
   794 typedef int (*Emacs_XErrorHandler) (Display *, XErrorEvent *);
   795 typedef int (*Emacs_XIOErrorHandler) (Display *);
   796 
   797 #if defined USE_XCB && defined USE_CAIRO_XCB
   798 #define USE_CAIRO_XCB_SURFACE
   799 #endif
   800 
   801 #if XCB_SHAPE_MAJOR_VERSION > 1       \
   802   || (XCB_SHAPE_MAJOR_VERSION == 1 && \
   803       XCB_SHAPE_MINOR_VERSION >= 1)
   804 #define HAVE_XCB_SHAPE_INPUT_RECTS
   805 #endif
   806 
   807 #ifdef USE_GTK
   808 /* GTK can't tolerate a call to `handle_interrupt' inside an event
   809    signal handler, but we have to store input events inside the
   810    handler for native input to work.
   811 
   812    This acts as a `hold_quit', and it is stored in the keyboard buffer
   813    (thereby causing the call to `handle_interrupt') after the GTK
   814    signal handler exits and control returns to XTread_socket.  */
   815 struct input_event xg_pending_quit_event = { .kind = NO_EVENT };
   816 #endif
   817 
   818 /* Non-zero means that a HELP_EVENT has been generated since Emacs
   819    start.  */
   820 
   821 static bool any_help_event_p;
   822 
   823 /* This is a chain of structures for all the X displays currently in
   824    use.  */
   825 
   826 struct x_display_info *x_display_list;
   827 
   828 #ifdef USE_X_TOOLKIT
   829 
   830 /* The application context for Xt use.  */
   831 XtAppContext Xt_app_con;
   832 static String Xt_default_resources[] = {0};
   833 
   834 /* Non-zero means user is interacting with a toolkit scroll bar.  */
   835 static bool toolkit_scroll_bar_interaction;
   836 
   837 #endif /* USE_X_TOOLKIT */
   838 
   839 /* Non-zero timeout value means ignore next mouse click if it arrives
   840    before that timeout elapses (i.e. as part of the same sequence of
   841    events resulting from clicking on a frame to select it).  */
   842 
   843 static Time ignore_next_mouse_click_timeout;
   844 
   845 /* The display that ignore_next_mouse_click_timeout applies to.  */
   846 
   847 static struct x_display_info *mouse_click_timeout_display;
   848 
   849 /* Used locally within XTread_socket.  */
   850 
   851 static int x_noop_count;
   852 
   853 #ifdef USE_GTK
   854 /* The name of the Emacs icon file.  */
   855 static Lisp_Object xg_default_icon_file;
   856 #endif
   857 
   858 #ifdef HAVE_X_I18N
   859 /* Some functions take this as char *, not const char *.  */
   860 static char emacs_class[] = EMACS_CLASS;
   861 #endif
   862 
   863 #ifdef USE_GTK
   864 static int current_count;
   865 static int current_finish;
   866 static struct input_event *current_hold_quit;
   867 #endif
   868 
   869 #ifdef HAVE_XINPUT2
   870 #ifndef X_XIGrabDevice
   871 #define X_XIGrabDevice 51
   872 #endif
   873 
   874 #ifndef X_XIUngrabDevice
   875 #define X_XIUngrabDevice 52
   876 #endif
   877 
   878 #ifndef X_XIAllowEvents
   879 #define X_XIAllowEvents 53
   880 #endif
   881 #endif
   882 
   883 /* Queue selection requests in `pending_selection_requests' if more
   884    than 0.  */
   885 static int x_use_pending_selection_requests;
   886 
   887 /* Like `next_kbd_event', but for use in X code.  */
   888 #define X_NEXT_KBD_EVENT(ptr) \
   889   ((ptr) == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : (ptr) + 1)
   890 
   891 static void x_push_selection_request (struct selection_input_event *);
   892 
   893 /* Defer selection requests.  Between this and
   894    x_release_selection_requests, any selection requests can be
   895    processed by calling `x_handle_pending_selection_requests'.
   896 
   897    Also run through and queue all the selection events already in the
   898    keyboard buffer.  */
   899 void
   900 x_defer_selection_requests (void)
   901 {
   902   union buffered_input_event *event;
   903   bool between;
   904 
   905   between = false;
   906 
   907   block_input ();
   908   if (!x_use_pending_selection_requests)
   909     {
   910       event = kbd_fetch_ptr;
   911 
   912       while (event != kbd_store_ptr)
   913         {
   914           if (event->ie.kind == SELECTION_REQUEST_EVENT
   915               || event->ie.kind == SELECTION_CLEAR_EVENT)
   916             {
   917               x_push_selection_request (&event->sie);
   918 
   919               /* Mark this selection event as invalid.   */
   920               SELECTION_EVENT_DPYINFO (&event->sie) = NULL;
   921 
   922               /* Move the kbd_fetch_ptr along if doing so would not
   923                  result in any other events being skipped.  This
   924                  avoids exhausting the keyboard buffer with some
   925                  over-enthusiastic clipboard managers.  */
   926               if (!between)
   927                 {
   928                   kbd_fetch_ptr = X_NEXT_KBD_EVENT (event);
   929 
   930                   /* `detect_input_pending' will then recompute
   931                      whether or not pending input events exist.  */
   932                   input_pending = false;
   933                 }
   934             }
   935           else
   936             between = true;
   937 
   938           event = X_NEXT_KBD_EVENT (event);
   939         }
   940     }
   941 
   942   x_use_pending_selection_requests++;
   943   unblock_input ();
   944 }
   945 
   946 static void
   947 x_release_selection_requests (void)
   948 {
   949   x_use_pending_selection_requests--;
   950 }
   951 
   952 void
   953 x_release_selection_requests_and_flush (void)
   954 {
   955   x_release_selection_requests ();
   956 
   957   if (!x_use_pending_selection_requests)
   958     x_handle_pending_selection_requests ();
   959 }
   960 
   961 struct x_selection_request_event
   962 {
   963   /* The selection request event.  */
   964   struct selection_input_event se;
   965 
   966   /* The next unprocessed selection request event.  */
   967   struct x_selection_request_event *next;
   968 };
   969 
   970 /* Chain of unprocessed selection request events.  Used to handle
   971    selection requests inside long-lasting modal event loops, such as
   972    the drag-and-drop loop.  */
   973 
   974 struct x_selection_request_event *pending_selection_requests;
   975 
   976 struct x_atom_ref
   977 {
   978   /* Atom name.  */
   979   const char *name;
   980 
   981   /* Offset of atom in the display info structure.  */
   982   int offset;
   983 };
   984 
   985 /* List of all atoms that should be interned when connecting to a
   986    display.  */
   987 static const struct x_atom_ref x_atom_refs[] =
   988   {
   989 #define ATOM_REFS_INIT(string, member)                          \
   990     { string, offsetof (struct x_display_info, member) },
   991     ATOM_REFS_INIT ("WM_PROTOCOLS", Xatom_wm_protocols)
   992     ATOM_REFS_INIT ("WM_TAKE_FOCUS", Xatom_wm_take_focus)
   993     ATOM_REFS_INIT ("WM_SAVE_YOURSELF", Xatom_wm_save_yourself)
   994     ATOM_REFS_INIT ("WM_DELETE_WINDOW", Xatom_wm_delete_window)
   995     ATOM_REFS_INIT ("WM_CHANGE_STATE", Xatom_wm_change_state)
   996     ATOM_REFS_INIT ("WM_STATE", Xatom_wm_state)
   997     ATOM_REFS_INIT ("WM_CONFIGURE_DENIED", Xatom_wm_configure_denied)
   998     ATOM_REFS_INIT ("WM_MOVED", Xatom_wm_window_moved)
   999     ATOM_REFS_INIT ("WM_CLIENT_LEADER", Xatom_wm_client_leader)
  1000     ATOM_REFS_INIT ("WM_TRANSIENT_FOR", Xatom_wm_transient_for)
  1001     ATOM_REFS_INIT ("Editres", Xatom_editres)
  1002     ATOM_REFS_INIT ("CLIPBOARD", Xatom_CLIPBOARD)
  1003     ATOM_REFS_INIT ("TIMESTAMP", Xatom_TIMESTAMP)
  1004     ATOM_REFS_INIT ("TEXT", Xatom_TEXT)
  1005     ATOM_REFS_INIT ("COMPOUND_TEXT", Xatom_COMPOUND_TEXT)
  1006     ATOM_REFS_INIT ("UTF8_STRING", Xatom_UTF8_STRING)
  1007     ATOM_REFS_INIT ("DELETE", Xatom_DELETE)
  1008     ATOM_REFS_INIT ("MULTIPLE", Xatom_MULTIPLE)
  1009     ATOM_REFS_INIT ("INCR", Xatom_INCR)
  1010     ATOM_REFS_INIT ("_EMACS_TMP_",  Xatom_EMACS_TMP)
  1011     ATOM_REFS_INIT ("_EMACS_SERVER_TIME_PROP", Xatom_EMACS_SERVER_TIME_PROP)
  1012     ATOM_REFS_INIT ("TARGETS", Xatom_TARGETS)
  1013     ATOM_REFS_INIT ("NULL", Xatom_NULL)
  1014     ATOM_REFS_INIT ("ATOM", Xatom_ATOM)
  1015     ATOM_REFS_INIT ("ATOM_PAIR", Xatom_ATOM_PAIR)
  1016     ATOM_REFS_INIT ("CLIPBOARD_MANAGER", Xatom_CLIPBOARD_MANAGER)
  1017     ATOM_REFS_INIT ("_XEMBED_INFO", Xatom_XEMBED_INFO)
  1018     ATOM_REFS_INIT ("_MOTIF_WM_HINTS", Xatom_MOTIF_WM_HINTS)
  1019     ATOM_REFS_INIT ("_EMACS_DRAG_ATOM", Xatom_EMACS_DRAG_ATOM)
  1020     /* For properties of font.  */
  1021     ATOM_REFS_INIT ("PIXEL_SIZE", Xatom_PIXEL_SIZE)
  1022     ATOM_REFS_INIT ("AVERAGE_WIDTH", Xatom_AVERAGE_WIDTH)
  1023     ATOM_REFS_INIT ("_MULE_BASELINE_OFFSET", Xatom_MULE_BASELINE_OFFSET)
  1024     ATOM_REFS_INIT ("_MULE_RELATIVE_COMPOSE", Xatom_MULE_RELATIVE_COMPOSE)
  1025     ATOM_REFS_INIT ("_MULE_DEFAULT_ASCENT", Xatom_MULE_DEFAULT_ASCENT)
  1026     /* Ghostscript support.  */
  1027     ATOM_REFS_INIT ("DONE", Xatom_DONE)
  1028     ATOM_REFS_INIT ("PAGE", Xatom_PAGE)
  1029     ATOM_REFS_INIT ("_EMACS_SCROLLBAR", Xatom_Scrollbar)
  1030     ATOM_REFS_INIT ("_EMACS_HORIZONTAL_SCROLLBAR", Xatom_Horizontal_Scrollbar)
  1031     ATOM_REFS_INIT ("_XEMBED", Xatom_XEMBED)
  1032     /* EWMH */
  1033     ATOM_REFS_INIT ("_NET_WM_STATE", Xatom_net_wm_state)
  1034     ATOM_REFS_INIT ("_NET_WM_STATE_FULLSCREEN", Xatom_net_wm_state_fullscreen)
  1035     ATOM_REFS_INIT ("_NET_WM_STATE_MAXIMIZED_HORZ",
  1036                     Xatom_net_wm_state_maximized_horz)
  1037     ATOM_REFS_INIT ("_NET_WM_STATE_MAXIMIZED_VERT",
  1038                     Xatom_net_wm_state_maximized_vert)
  1039     ATOM_REFS_INIT ("_NET_WM_STATE_STICKY", Xatom_net_wm_state_sticky)
  1040     ATOM_REFS_INIT ("_NET_WM_STATE_SHADED", Xatom_net_wm_state_shaded)
  1041     ATOM_REFS_INIT ("_NET_WM_STATE_HIDDEN", Xatom_net_wm_state_hidden)
  1042     ATOM_REFS_INIT ("_NET_WM_WINDOW_TYPE", Xatom_net_window_type)
  1043     ATOM_REFS_INIT ("_NET_WM_WINDOW_TYPE_TOOLTIP",
  1044                     Xatom_net_window_type_tooltip)
  1045     ATOM_REFS_INIT ("_NET_WM_ICON_NAME", Xatom_net_wm_icon_name)
  1046     ATOM_REFS_INIT ("_NET_WM_NAME", Xatom_net_wm_name)
  1047     ATOM_REFS_INIT ("_NET_SUPPORTED",  Xatom_net_supported)
  1048     ATOM_REFS_INIT ("_NET_SUPPORTING_WM_CHECK", Xatom_net_supporting_wm_check)
  1049     ATOM_REFS_INIT ("_NET_WM_WINDOW_OPACITY", Xatom_net_wm_window_opacity)
  1050     ATOM_REFS_INIT ("_NET_ACTIVE_WINDOW", Xatom_net_active_window)
  1051     ATOM_REFS_INIT ("_NET_FRAME_EXTENTS", Xatom_net_frame_extents)
  1052     ATOM_REFS_INIT ("_NET_CURRENT_DESKTOP", Xatom_net_current_desktop)
  1053     ATOM_REFS_INIT ("_NET_WORKAREA", Xatom_net_workarea)
  1054     ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST", Xatom_net_wm_sync_request)
  1055     ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST_COUNTER", Xatom_net_wm_sync_request_counter)
  1056     ATOM_REFS_INIT ("_NET_WM_SYNC_FENCES", Xatom_net_wm_sync_fences)
  1057     ATOM_REFS_INIT ("_NET_WM_BYPASS_COMPOSITOR", Xatom_net_wm_bypass_compositor)
  1058     ATOM_REFS_INIT ("_NET_WM_FRAME_DRAWN", Xatom_net_wm_frame_drawn)
  1059     ATOM_REFS_INIT ("_NET_WM_FRAME_TIMINGS", Xatom_net_wm_frame_timings)
  1060     ATOM_REFS_INIT ("_NET_WM_USER_TIME", Xatom_net_wm_user_time)
  1061     ATOM_REFS_INIT ("_NET_WM_USER_TIME_WINDOW", Xatom_net_wm_user_time_window)
  1062     ATOM_REFS_INIT ("_NET_CLIENT_LIST_STACKING", Xatom_net_client_list_stacking)
  1063     /* Session management */
  1064     ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID)
  1065     ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop)
  1066     ATOM_REFS_INIT ("MANAGER", Xatom_xsettings_mgr)
  1067     ATOM_REFS_INIT ("_NET_WM_STATE_SKIP_TASKBAR", Xatom_net_wm_state_skip_taskbar)
  1068     ATOM_REFS_INIT ("_NET_WM_STATE_ABOVE", Xatom_net_wm_state_above)
  1069     ATOM_REFS_INIT ("_NET_WM_STATE_BELOW", Xatom_net_wm_state_below)
  1070     ATOM_REFS_INIT ("_NET_WM_OPAQUE_REGION", Xatom_net_wm_opaque_region)
  1071     ATOM_REFS_INIT ("_NET_WM_PING", Xatom_net_wm_ping)
  1072     ATOM_REFS_INIT ("_NET_WM_PID", Xatom_net_wm_pid)
  1073 #ifdef HAVE_XKB
  1074     ATOM_REFS_INIT ("Meta", Xatom_Meta)
  1075     ATOM_REFS_INIT ("Super", Xatom_Super)
  1076     ATOM_REFS_INIT ("Hyper", Xatom_Hyper)
  1077     ATOM_REFS_INIT ("ShiftLock", Xatom_ShiftLock)
  1078     ATOM_REFS_INIT ("Alt", Xatom_Alt)
  1079 #endif
  1080     /* DND source.  */
  1081     ATOM_REFS_INIT ("XdndAware", Xatom_XdndAware)
  1082     ATOM_REFS_INIT ("XdndSelection", Xatom_XdndSelection)
  1083     ATOM_REFS_INIT ("XdndTypeList", Xatom_XdndTypeList)
  1084     ATOM_REFS_INIT ("XdndActionCopy", Xatom_XdndActionCopy)
  1085     ATOM_REFS_INIT ("XdndActionMove", Xatom_XdndActionMove)
  1086     ATOM_REFS_INIT ("XdndActionLink", Xatom_XdndActionLink)
  1087     ATOM_REFS_INIT ("XdndActionAsk", Xatom_XdndActionAsk)
  1088     ATOM_REFS_INIT ("XdndActionPrivate", Xatom_XdndActionPrivate)
  1089     ATOM_REFS_INIT ("XdndActionList", Xatom_XdndActionList)
  1090     ATOM_REFS_INIT ("XdndActionDescription", Xatom_XdndActionDescription)
  1091     ATOM_REFS_INIT ("XdndProxy", Xatom_XdndProxy)
  1092     ATOM_REFS_INIT ("XdndEnter", Xatom_XdndEnter)
  1093     ATOM_REFS_INIT ("XdndPosition", Xatom_XdndPosition)
  1094     ATOM_REFS_INIT ("XdndStatus", Xatom_XdndStatus)
  1095     ATOM_REFS_INIT ("XdndLeave", Xatom_XdndLeave)
  1096     ATOM_REFS_INIT ("XdndDrop", Xatom_XdndDrop)
  1097     ATOM_REFS_INIT ("XdndFinished", Xatom_XdndFinished)
  1098     /* XDS source and target.  */
  1099     ATOM_REFS_INIT ("XdndDirectSave0", Xatom_XdndDirectSave0)
  1100     ATOM_REFS_INIT ("XdndActionDirectSave", Xatom_XdndActionDirectSave)
  1101     ATOM_REFS_INIT ("text/plain", Xatom_text_plain)
  1102     /* Motif drop protocol support.  */
  1103     ATOM_REFS_INIT ("_MOTIF_DRAG_WINDOW", Xatom_MOTIF_DRAG_WINDOW)
  1104     ATOM_REFS_INIT ("_MOTIF_DRAG_TARGETS", Xatom_MOTIF_DRAG_TARGETS)
  1105     ATOM_REFS_INIT ("_MOTIF_DRAG_AND_DROP_MESSAGE",
  1106                     Xatom_MOTIF_DRAG_AND_DROP_MESSAGE)
  1107     ATOM_REFS_INIT ("_MOTIF_DRAG_INITIATOR_INFO",
  1108                     Xatom_MOTIF_DRAG_INITIATOR_INFO)
  1109     ATOM_REFS_INIT ("_MOTIF_DRAG_RECEIVER_INFO",
  1110                     Xatom_MOTIF_DRAG_RECEIVER_INFO)
  1111     ATOM_REFS_INIT ("XmTRANSFER_SUCCESS", Xatom_XmTRANSFER_SUCCESS)
  1112     ATOM_REFS_INIT ("XmTRANSFER_FAILURE", Xatom_XmTRANSFER_FAILURE)
  1113     /* Old OffiX (a.k.a. old KDE) drop protocol support.  */
  1114     ATOM_REFS_INIT ("DndProtocol", Xatom_DndProtocol)
  1115     ATOM_REFS_INIT ("_DND_PROTOCOL", Xatom_DND_PROTOCOL)
  1116     /* Here are some atoms that are not actually used from C, just
  1117        defined to make replying to selection requests fast.  */
  1118     ATOM_REFS_INIT ("text/plain;charset=utf-8", Xatom_text_plain_charset_utf_8)
  1119     ATOM_REFS_INIT ("LENGTH", Xatom_LENGTH)
  1120     ATOM_REFS_INIT ("FILE_NAME", Xatom_FILE_NAME)
  1121     ATOM_REFS_INIT ("CHARACTER_POSITION", Xatom_CHARACTER_POSITION)
  1122     ATOM_REFS_INIT ("LINE_NUMBER", Xatom_LINE_NUMBER)
  1123     ATOM_REFS_INIT ("COLUMN_NUMBER", Xatom_COLUMN_NUMBER)
  1124     ATOM_REFS_INIT ("OWNER_OS", Xatom_OWNER_OS)
  1125     ATOM_REFS_INIT ("HOST_NAME", Xatom_HOST_NAME)
  1126     ATOM_REFS_INIT ("USER", Xatom_USER)
  1127     ATOM_REFS_INIT ("CLASS", Xatom_CLASS)
  1128     ATOM_REFS_INIT ("NAME", Xatom_NAME)
  1129     ATOM_REFS_INIT ("SAVE_TARGETS", Xatom_SAVE_TARGETS)
  1130   };
  1131 
  1132 enum
  1133 {
  1134   X_EVENT_NORMAL,
  1135   X_EVENT_GOTO_OUT,
  1136   X_EVENT_DROP
  1137 };
  1138 
  1139 enum xembed_info
  1140   {
  1141     XEMBED_MAPPED = 1 << 0
  1142   };
  1143 
  1144 enum xembed_message
  1145   {
  1146     XEMBED_EMBEDDED_NOTIFY        = 0,
  1147     XEMBED_WINDOW_ACTIVATE        = 1,
  1148     XEMBED_WINDOW_DEACTIVATE      = 2,
  1149     XEMBED_REQUEST_FOCUS          = 3,
  1150     XEMBED_FOCUS_IN               = 4,
  1151     XEMBED_FOCUS_OUT              = 5,
  1152     XEMBED_FOCUS_NEXT             = 6,
  1153     XEMBED_FOCUS_PREV             = 7,
  1154 
  1155     XEMBED_MODALITY_ON            = 10,
  1156     XEMBED_MODALITY_OFF           = 11,
  1157     XEMBED_REGISTER_ACCELERATOR   = 12,
  1158     XEMBED_UNREGISTER_ACCELERATOR = 13,
  1159     XEMBED_ACTIVATE_ACCELERATOR   = 14
  1160   };
  1161 
  1162 static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *);
  1163 static void x_raise_frame (struct frame *);
  1164 static void x_lower_frame (struct frame *);
  1165 static int x_io_error_quitter (Display *);
  1166 static struct terminal *x_create_terminal (struct x_display_info *);
  1167 static void x_frame_rehighlight (struct x_display_info *);
  1168 
  1169 static void x_clip_to_row (struct window *, struct glyph_row *,
  1170                            enum glyph_row_area, GC);
  1171 static struct scroll_bar *x_window_to_scroll_bar (Display *, Window, int);
  1172 static struct frame *x_window_to_frame (struct x_display_info *, int);
  1173 static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
  1174                                         enum scroll_bar_part *,
  1175                                         Lisp_Object *, Lisp_Object *,
  1176                                         Time *);
  1177 static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *,
  1178                                                    enum scroll_bar_part *,
  1179                                                    Lisp_Object *, Lisp_Object *,
  1180                                                    Time *);
  1181 static bool x_handle_net_wm_state (struct frame *, const XPropertyEvent *);
  1182 static void x_check_fullscreen (struct frame *);
  1183 static void x_check_expected_move (struct frame *, int, int);
  1184 static void x_sync_with_move (struct frame *, int, int, bool);
  1185 #ifndef HAVE_XINPUT2
  1186 static int handle_one_xevent (struct x_display_info *,
  1187                               const XEvent *, int *,
  1188                               struct input_event *);
  1189 #else
  1190 static int handle_one_xevent (struct x_display_info *,
  1191                               XEvent *, int *,
  1192                               struct input_event *);
  1193 #endif
  1194 #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF) && defined USE_GTK
  1195 static int x_dispatch_event (XEvent *, Display *);
  1196 #endif
  1197 static void x_wm_set_window_state (struct frame *, int);
  1198 static void x_wm_set_icon_pixmap (struct frame *, ptrdiff_t);
  1199 static void x_initialize (void);
  1200 
  1201 static bool x_get_current_wm_state (struct frame *, Window, int *, bool *, bool *);
  1202 static void x_update_opaque_region (struct frame *, XEvent *);
  1203 
  1204 #ifdef HAVE_X_I18N
  1205 static int x_filter_event (struct x_display_info *, XEvent *);
  1206 #endif
  1207 static void x_clean_failable_requests (struct x_display_info *);
  1208 
  1209 static struct frame *x_tooltip_window_to_frame (struct x_display_info *,
  1210                                                 Window, bool *);
  1211 static Window x_get_window_below (Display *, Window, int, int, int *, int *);
  1212 static void x_set_input_focus (struct x_display_info *, Window, Time);
  1213 
  1214 #ifndef USE_TOOLKIT_SCROLL_BARS
  1215 static void x_scroll_bar_redraw (struct scroll_bar *);
  1216 #endif
  1217 
  1218 /* Global state maintained during a drag-and-drop operation.  */
  1219 
  1220 /* Flag that indicates if a drag-and-drop operation is in progress.  */
  1221 bool x_dnd_in_progress;
  1222 
  1223 /* The frame where the drag-and-drop operation originated.  */
  1224 struct frame *x_dnd_frame;
  1225 
  1226 /* That frame, but set when x_dnd_waiting_for_finish is true.  Used to
  1227    prevent the frame from being deleted inside selection handlers and
  1228    other callbacks.  */
  1229 struct frame *x_dnd_finish_frame;
  1230 
  1231 /* Flag that indicates if a drag-and-drop operation is no longer in
  1232    progress, but the nested event loop should continue to run, because
  1233    handle_one_xevent is waiting for the drop target to return some
  1234    important information.  */
  1235 bool x_dnd_waiting_for_finish;
  1236 
  1237 /* Flag that means (when set in addition to
  1238    `x_dnd_waiting_for_finish') to run the unsupported drop function
  1239    with the given arguments.  */
  1240 static bool x_dnd_run_unsupported_drop_function;
  1241 
  1242 /* The "before"-time of the unsupported drop.  */
  1243 static Time x_dnd_unsupported_drop_time;
  1244 
  1245 /* The target window of the unsupported drop.  */
  1246 static Window x_dnd_unsupported_drop_window;
  1247 
  1248 /* The Lisp data associated with the unsupported drop function.  */
  1249 static Lisp_Object x_dnd_unsupported_drop_data;
  1250 
  1251 /* Whether or not to move the tooltip along with the mouse pointer
  1252    during drag-and-drop.  */
  1253 static bool x_dnd_update_tooltip;
  1254 
  1255 /* Monitor attribute list used for updating the tooltip position.  */
  1256 static Lisp_Object x_dnd_monitors;
  1257 
  1258 /* The display the drop target that is supposed to send information is
  1259    on.  */
  1260 static Display *x_dnd_finish_display;
  1261 
  1262 /* State of the Motif drop operation.
  1263 
  1264    0 means nothing has happened, i.e. the event loop should not wait
  1265    for the receiver to send any data.  1 means an XmDROP_START message
  1266    was sent to the target, but no response has yet been received.  2
  1267    means a response to our XmDROP_START message was received and the
  1268    target accepted the drop, so Emacs should start waiting for the
  1269    drop target to convert one of the special selections
  1270    XmTRANSFER_SUCCESS or XmTRANSFER_FAILURE.  */
  1271 static int x_dnd_waiting_for_motif_finish;
  1272 
  1273 /* The display the Motif drag receiver will send response data
  1274    from.  */
  1275 struct x_display_info *x_dnd_waiting_for_motif_finish_display;
  1276 
  1277 /* Whether or not F1 was pressed during the drag-and-drop operation.
  1278 
  1279    Motif programs rely on this to decide whether or not help
  1280    information about the drop site should be displayed.  */
  1281 static bool x_dnd_xm_use_help;
  1282 
  1283 /* Whether or not Motif drag initiator info was set up.  */
  1284 static bool x_dnd_motif_setup_p;
  1285 
  1286 /* The Motif drag atom used during the drag-and-drop operation.  */
  1287 static Atom x_dnd_motif_atom;
  1288 
  1289 /* The target window we are waiting for an XdndFinished message
  1290    from.  */
  1291 static Window x_dnd_pending_finish_target;
  1292 
  1293 /* The protocol version of that target window.  */
  1294 static int x_dnd_waiting_for_finish_proto;
  1295 
  1296 /* Whether or not it is OK for something to be dropped on the frame
  1297    where the drag-and-drop operation originated.  */
  1298 static bool x_dnd_allow_current_frame;
  1299 
  1300 /* Whether or not the `XdndTypeList' property has already been set on
  1301    the drag frame.  */
  1302 static bool x_dnd_init_type_lists;
  1303 
  1304 /* Whether or not to return a frame from `x_dnd_begin_drag_and_drop'.
  1305 
  1306    0 means to do nothing.  1 means to wait for the mouse to first exit
  1307    `x_dnd_frame'.  2 means to wait for the mouse to move onto a frame,
  1308    and 3 means to return `x_dnd_return_frame_object'.  */
  1309 static int x_dnd_return_frame;
  1310 
  1311 /* The frame that should be returned by
  1312    `x_dnd_begin_drag_and_drop'.  */
  1313 static struct frame *x_dnd_return_frame_object;
  1314 
  1315 /* The last drop target window the mouse pointer moved over.  This can
  1316    be different from `x_dnd_last_seen_toplevel' if that window had an
  1317    XdndProxy.  */
  1318 static Window x_dnd_last_seen_window;
  1319 
  1320 /* The last toplevel the mouse pointer moved over.  */
  1321 static Window x_dnd_last_seen_toplevel;
  1322 
  1323 /* The window where the drop happened.  Normally None, but it is set
  1324    when something is actually dropped.  */
  1325 static Window x_dnd_end_window;
  1326 
  1327 /* The XDND protocol version of `x_dnd_last_seen_window'.  -1 means it
  1328    did not support XDND.  */
  1329 static int x_dnd_last_protocol_version;
  1330 
  1331 /* Whether or not the last seen window is actually one of our
  1332    frames.  */
  1333 static bool x_dnd_last_window_is_frame;
  1334 
  1335 /* The Motif drag and drop protocol style of `x_dnd_last_seen_window'.
  1336    XM_DRAG_STYLE_NONE means the window does not support the Motif drag
  1337    or drop protocol.  XM_DRAG_STYLE_DROP_ONLY means the window does
  1338    not respond to any drag protocol messages, so only drops should be
  1339    sent.  Any other value means that the window supports both the drag
  1340    and drop protocols.  */
  1341 static int x_dnd_last_motif_style;
  1342 
  1343 /* The timestamp where Emacs last acquired ownership of the
  1344    `XdndSelection' selection.  */
  1345 static Time x_dnd_selection_timestamp;
  1346 
  1347 /* The drop target window to which the rectangle below applies.  */
  1348 static Window x_dnd_mouse_rect_target;
  1349 
  1350 /* A rectangle where XDND position messages should not be sent to the
  1351    drop target if the mouse pointer lies within.  */
  1352 static XRectangle x_dnd_mouse_rect;
  1353 
  1354 /* If not None, Emacs is waiting for an XdndStatus event from this
  1355    window.  */
  1356 static Window x_dnd_waiting_for_status_window;
  1357 
  1358 /* If .type != 0, an event that should be sent to .xclient.window
  1359    upon receiving an XdndStatus event from said window.  */
  1360 static XEvent x_dnd_pending_send_position;
  1361 
  1362 /* Whether or not that event corresponds to a button press.  */
  1363 static bool x_dnd_pending_send_position_button;
  1364 
  1365 /* The root-window position of that event.  */
  1366 static int x_dnd_pending_send_position_root_x;
  1367 
  1368 /* Likewise.  */
  1369 static int x_dnd_pending_send_position_root_y;
  1370 
  1371 /* If true, send a drop from `x_dnd_finish_frame' to the pending
  1372    status window after receiving all pending XdndStatus events.  */
  1373 static bool x_dnd_need_send_drop;
  1374 
  1375 /* The protocol version of any such drop.  */
  1376 static int x_dnd_send_drop_proto;
  1377 
  1378 /* The action the drop target actually chose to perform.
  1379 
  1380    Under XDND, this is set upon receiving the XdndFinished or
  1381    XdndStatus messages from the drop target.
  1382 
  1383    Under Motif, this is changed upon receiving a XmDROP_START message
  1384    in reply to our own.
  1385 
  1386    When dropping on a target that doesn't support any drag-and-drop
  1387    protocol, this is set to the atom XdndActionPrivate.  */
  1388 static Atom x_dnd_action;
  1389 
  1390 /* The symbol to return from `x-begin-drag' if non-nil.  Takes
  1391    precedence over `x_dnd_action`.  */
  1392 static Lisp_Object x_dnd_action_symbol;
  1393 
  1394 /* The action we want the drop target to perform.  The drop target may
  1395    elect to perform some different action, which is guaranteed to be
  1396    in `x_dnd_action' upon completion of a drop.  */
  1397 static Atom x_dnd_wanted_action;
  1398 
  1399 /* The set of optional actions available to a Motif drop target
  1400    computed at the start of the drag-and-drop operation.  */
  1401 static uint8_t x_dnd_motif_operations;
  1402 
  1403 /* The preferred optional action out of that set.  Only takes effect
  1404    if `x_dnd_action' is XdndAsk.  */
  1405 static uint8_t x_dnd_first_motif_operation;
  1406 
  1407 /* Array of selection targets available to the drop target.  */
  1408 static Atom *x_dnd_targets;
  1409 
  1410 /* The number of elements in that array.  */
  1411 static int x_dnd_n_targets;
  1412 
  1413 /* The old window attributes of the root window before the
  1414    drag-and-drop operation started.  It is used to keep the old event
  1415    mask around, since that should be restored after the operation
  1416    finishes.  */
  1417 static XWindowAttributes x_dnd_old_window_attrs;
  1418 
  1419 /* Whether or not `x_dnd_cleaup_drag_and_drop' should actually clean
  1420    up the drag and drop operation.  */
  1421 static bool x_dnd_unwind_flag;
  1422 
  1423 /* The frame for which `x-dnd-movement-function' should be called.  */
  1424 static struct frame *x_dnd_movement_frame;
  1425 
  1426 /* The coordinates which the movement function should be called
  1427    with.  */
  1428 static int x_dnd_movement_x, x_dnd_movement_y;
  1429 
  1430 /* The frame for which `x-dnd-wheel-function' should be called.  */
  1431 static struct frame *x_dnd_wheel_frame;
  1432 
  1433 /* The coordinates which the wheel function should be called with.  */
  1434 static int x_dnd_wheel_x, x_dnd_wheel_y;
  1435 
  1436 /* The button that was pressed.  */
  1437 static int x_dnd_wheel_button;
  1438 
  1439 /* The modifier state when the button was pressed.  */
  1440 static int x_dnd_wheel_state;
  1441 
  1442 /* When the button was pressed.  */
  1443 static Time x_dnd_wheel_time;
  1444 
  1445 #ifdef HAVE_XKB
  1446 /* The keyboard state during the drag-and-drop operation.  */
  1447 static unsigned int x_dnd_keyboard_state;
  1448 #endif
  1449 
  1450 /* jmp_buf that gets us out of the IO error handler if an error occurs
  1451    terminating DND as part of the display disconnect handler.  */
  1452 static sigjmp_buf x_dnd_disconnect_handler;
  1453 
  1454 /* Whether or not the current invocation of handle_one_xevent
  1455    happened inside the drag_and_drop event loop.  */
  1456 static bool x_dnd_inside_handle_one_xevent;
  1457 
  1458 /* The recursive edit depth when the drag-and-drop operation was
  1459    started.  */
  1460 static int x_dnd_recursion_depth;
  1461 
  1462 /* The cons cell containing the selection alias between the Motif drag
  1463    selection and `XdndSelection'.  The car and cdr are only set when
  1464    initiating Motif drag-and-drop for the first time.  */
  1465 static Lisp_Object x_dnd_selection_alias_cell;
  1466 
  1467 /* The last known position of the tooltip window.  */
  1468 static int x_dnd_last_tooltip_x, x_dnd_last_tooltip_y;
  1469 
  1470 /* Whether or not those values are actually known yet.  */
  1471 static bool x_dnd_last_tooltip_valid;
  1472 
  1473 #ifdef HAVE_XINPUT2
  1474 /* The master pointer device being used for the drag-and-drop
  1475    operation.  */
  1476 static int x_dnd_pointer_device;
  1477 
  1478 /* The keyboard device attached to that pointer device.  */
  1479 static int x_dnd_keyboard_device;
  1480 #endif
  1481 
  1482 /* Structure describing a single window that can be the target of
  1483    drag-and-drop operations.  */
  1484 struct x_client_list_window
  1485 {
  1486   /* The window itself.  */
  1487   Window window;
  1488 
  1489   /* The display that window is on.  */
  1490   Display *dpy;
  1491 
  1492   /* Its X and Y coordinates from the root window.  */
  1493   int x, y;
  1494 
  1495   /* The width and height of the window.  */
  1496   int width, height;
  1497 
  1498   /* A bitmask describing events Emacs was listening for from the
  1499      window before some extra events were added in
  1500      `x_dnd_compute_toplevels'.  */
  1501   long previous_event_mask;
  1502 
  1503   /* The window manager state of the window.  */
  1504   unsigned long wm_state;
  1505 
  1506   /* The next window in this list.  */
  1507   struct x_client_list_window *next;
  1508 
  1509   /* The extents of the frame window in each direction.  */
  1510   int frame_extents_left;
  1511   int frame_extents_right;
  1512   int frame_extents_top;
  1513   int frame_extents_bottom;
  1514 
  1515 #ifdef HAVE_XSHAPE
  1516   /* The border width of this window.  */
  1517   int border_width;
  1518 
  1519   /* The number of rectangles composing the input shape.  */
  1520   int n_input_rects;
  1521 
  1522   /* The rectangles making up the input shape.  */
  1523   XRectangle *input_rects;
  1524 
  1525   /* The rectangles making up the bounding shape.  */
  1526   XRectangle *bounding_rects;
  1527 
  1528   /* The number of rectangles composing the bounding shape.  */
  1529   int n_bounding_rects;
  1530 #endif
  1531 
  1532   /* The Motif protocol style of this window, if any.  */
  1533   uint8_t xm_protocol_style;
  1534 
  1535   /* Whether or not the window is mapped.  */
  1536   bool mapped_p;
  1537 };
  1538 
  1539 /* List of all toplevels in stacking order, from top to bottom.  */
  1540 static struct x_client_list_window *x_dnd_toplevels;
  1541 
  1542 /* Whether or not the window manager supports the required features
  1543    for `x_dnd_toplevels' to work.  */
  1544 static bool x_dnd_use_toplevels;
  1545 
  1546 /* Motif drag-and-drop protocol support.  */
  1547 
  1548 /* Pointer to a variable which stores whether or not an X error
  1549    occurred while trying to create the Motif drag window.  */
  1550 static volatile bool *xm_drag_window_error;
  1551 
  1552 typedef enum xm_byte_order
  1553   {
  1554     XM_BYTE_ORDER_LSB_FIRST = 'l',
  1555     XM_BYTE_ORDER_MSB_FIRST = 'B',
  1556 #ifndef WORDS_BIGENDIAN
  1557     XM_BYTE_ORDER_CUR_FIRST = 'l',
  1558 #else
  1559     XM_BYTE_ORDER_CUR_FIRST = 'B',
  1560 #endif
  1561   } xm_byte_order;
  1562 
  1563 #ifdef ENABLE_CHECKING
  1564 
  1565 #define SWAPCARD32(l)                           \
  1566   {                                             \
  1567     struct { unsigned t : 32; } bit32;          \
  1568     char n, *tp = (char *) &bit32;              \
  1569     bit32.t = l;                                \
  1570     n = tp[0]; tp[0] = tp[3]; tp[3] = n;        \
  1571     n = tp[1]; tp[1] = tp[2]; tp[2] = n;        \
  1572     l = bit32.t;                                \
  1573   }
  1574 
  1575 #define SWAPCARD16(s)                           \
  1576   {                                             \
  1577     struct { unsigned t : 16; } bit16;          \
  1578     char n, *tp = (char *) &bit16;              \
  1579     bit16.t = s;                                \
  1580     n = tp[0]; tp[0] = tp[1]; tp[1] = n;        \
  1581     s = bit16.t;                                \
  1582   }
  1583 
  1584 #else
  1585 #define SWAPCARD32(l)   ((l) = bswap_32 (l))
  1586 #define SWAPCARD16(l)   ((l) = bswap_16 (l))
  1587 #endif
  1588 
  1589 typedef struct xm_targets_table_header
  1590 {
  1591   /* BYTE   */ uint8_t byte_order;
  1592   /* BYTE   */ uint8_t protocol;
  1593 
  1594   /* CARD16 */ uint16_t target_list_count;
  1595   /* CARD32 */ uint32_t total_data_size;
  1596 } xm_targets_table_header;
  1597 
  1598 typedef struct xm_targets_table_rec
  1599 {
  1600   /* CARD16 */ uint16_t n_targets;
  1601   /* CARD32 */ uint32_t targets[FLEXIBLE_ARRAY_MEMBER];
  1602 } xm_targets_table_rec;
  1603 
  1604 typedef struct xm_drop_start_message
  1605 {
  1606   /* BYTE   */ uint8_t reason;
  1607   /* BYTE   */ uint8_t byte_order;
  1608 
  1609   /* CARD16 */ uint16_t side_effects;
  1610   /* CARD32 */ uint32_t timestamp;
  1611   /* CARD16 */ uint16_t x, y;
  1612   /* CARD32 */ uint32_t index_atom;
  1613   /* CARD32 */ uint32_t source_window;
  1614 } xm_drop_start_message;
  1615 
  1616 typedef struct xm_drop_start_reply
  1617 {
  1618   /* BYTE   */ uint8_t reason;
  1619   /* BYTE   */ uint8_t byte_order;
  1620 
  1621   /* CARD16 */ uint16_t side_effects;
  1622   /* CARD16 */ uint16_t better_x;
  1623   /* CARD16 */ uint16_t better_y;
  1624 } xm_drop_start_reply;
  1625 
  1626 typedef struct xm_drag_initiator_info
  1627 {
  1628   /* BYTE   */ uint8_t byteorder;
  1629   /* BYTE   */ uint8_t protocol;
  1630 
  1631   /* CARD16 */ uint16_t table_index;
  1632   /* CARD32 */ uint32_t selection;
  1633 } xm_drag_initiator_info;
  1634 
  1635 typedef struct xm_drag_receiver_info
  1636 {
  1637   /* BYTE   */ uint8_t byteorder;
  1638   /* BYTE   */ uint8_t protocol;
  1639 
  1640   /* BYTE   */ uint8_t protocol_style;
  1641   /* BYTE   */ uint8_t unspecified0;
  1642   /* CARD32 */ uint32_t unspecified1;
  1643   /* CARD32 */ uint32_t unspecified2;
  1644   /* CARD32 */ uint32_t unspecified3;
  1645 } xm_drag_receiver_info;
  1646 
  1647 typedef struct xm_top_level_enter_message
  1648 {
  1649   /* BYTE   */ uint8_t reason;
  1650   /* BYTE   */ uint8_t byteorder;
  1651 
  1652   /* CARD16 */ uint16_t zero;
  1653   /* CARD32 */ uint32_t timestamp;
  1654   /* CARD32 */ uint32_t source_window;
  1655   /* CARD32 */ uint32_t index_atom;
  1656 } xm_top_level_enter_message;
  1657 
  1658 typedef struct xm_drag_motion_message
  1659 {
  1660   /* BYTE   */ uint8_t reason;
  1661   /* BYTE   */ uint8_t byteorder;
  1662 
  1663   /* CARD16 */ uint16_t side_effects;
  1664   /* CARD32 */ uint32_t timestamp;
  1665   /* CARD16 */ uint16_t x, y;
  1666 } xm_drag_motion_message;
  1667 
  1668 typedef struct xm_drag_motion_reply
  1669 {
  1670   /* BYTE   */ uint8_t reason;
  1671   /* BYTE   */ uint8_t byte_order;
  1672 
  1673   /* CARD16 */ uint16_t side_effects;
  1674   /* CARD32 */ uint32_t timestamp;
  1675   /* CARD16 */ uint16_t better_x;
  1676   /* CARD16 */ uint16_t better_y;
  1677 } xm_drag_motion_reply;
  1678 
  1679 typedef struct xm_top_level_leave_message
  1680 {
  1681   /* BYTE   */ uint8_t reason;
  1682   /* BYTE   */ uint8_t byteorder;
  1683 
  1684   /* CARD16 */ uint16_t zero;
  1685   /* CARD32 */ uint32_t timestamp;
  1686   /* CARD32 */ uint32_t source_window;
  1687 } xm_top_level_leave_message;
  1688 
  1689 #define XM_DRAG_SIDE_EFFECT(op, site, ops, act)         \
  1690   ((op) | ((site) << 4) | ((ops) << 8) | ((act) << 12))
  1691 
  1692 /* Some of the macros below are temporarily unused.  */
  1693 
  1694 #define XM_DRAG_SIDE_EFFECT_OPERATION(effect)   ((effect) & 0xf)
  1695 #define XM_DRAG_SIDE_EFFECT_SITE_STATUS(effect) (((effect) & 0xf0) >> 4)
  1696 /* #define XM_DRAG_SIDE_EFFECT_OPERATIONS(effect)       (((effect) & 0xf00) >> 8) */
  1697 #define XM_DRAG_SIDE_EFFECT_DROP_ACTION(effect) (((effect) & 0xf000) >> 12)
  1698 
  1699 enum xm_drag_operation
  1700   {
  1701     XM_DRAG_NOOP     = 0,
  1702     XM_DRAG_MOVE     = (1L << 0),
  1703     XM_DRAG_COPY     = (1L << 1),
  1704     XM_DRAG_LINK     = (1L << 2),
  1705     XM_DRAG_LINK_REC = 3,
  1706   };
  1707 
  1708 #define XM_DRAG_OPERATION_IS_LINK(op)   ((op) == XM_DRAG_LINK           \
  1709                                          || (op) == XM_DRAG_LINK_REC)
  1710 
  1711 enum xm_drag_action
  1712   {
  1713     XM_DROP_ACTION_DROP        = 0,
  1714     XM_DROP_ACTION_DROP_HELP   = 1,
  1715     XM_DROP_ACTION_DROP_CANCEL = 2,
  1716   };
  1717 
  1718 #define XM_DRAG_REASON(originator, code)        ((code) | ((originator) << 7))
  1719 #define XM_DRAG_REASON_ORIGINATOR(reason)       (((reason) & 0x80) ? 1 : 0)
  1720 #define XM_DRAG_REASON_CODE(reason)             ((reason) & 0x7f)
  1721 
  1722 enum xm_drag_reason
  1723   {
  1724     XM_DRAG_REASON_DROP_START      = 5,
  1725     XM_DRAG_REASON_TOP_LEVEL_ENTER = 0,
  1726     XM_DRAG_REASON_TOP_LEVEL_LEAVE = 1,
  1727     XM_DRAG_REASON_DRAG_MOTION     = 2,
  1728   };
  1729 
  1730 enum xm_drag_originator
  1731   {
  1732     XM_DRAG_ORIGINATOR_INITIATOR = 0,
  1733     XM_DRAG_ORIGINATOR_RECEIVER  = 1,
  1734   };
  1735 
  1736 enum xm_drag_style
  1737   {
  1738     /* The values ending with _REC should be treated as equivalent to
  1739        the ones without in messages from the receiver.  */
  1740     XM_DRAG_STYLE_NONE          = 0,
  1741     XM_DRAG_STYLE_DROP_ONLY     = 1,
  1742     XM_DRAG_STYLE_DROP_ONLY_REC = 3,
  1743     XM_DRAG_STYLE_DYNAMIC       = 5,
  1744     XM_DRAG_STYLE_DYNAMIC_REC   = 2,
  1745     XM_DRAG_STYLE_DYNAMIC_REC1  = 4,
  1746   };
  1747 
  1748 #define XM_DRAG_STYLE_IS_DROP_ONLY(n)   ((n) == XM_DRAG_STYLE_DROP_ONLY \
  1749                                          || (n) == XM_DRAG_STYLE_DROP_ONLY_REC)
  1750 #define XM_DRAG_STYLE_IS_DYNAMIC(n)     ((n) == XM_DRAG_STYLE_DYNAMIC   \
  1751                                          || (n) == XM_DRAG_STYLE_DYNAMIC_REC \
  1752                                          || (n) == XM_DRAG_STYLE_DYNAMIC_REC1)
  1753 
  1754 enum xm_drop_site_status
  1755   {
  1756     XM_DROP_SITE_VALID   = 3,
  1757     XM_DROP_SITE_INVALID = 2,
  1758     XM_DROP_SITE_NONE    = 1,
  1759   };
  1760 
  1761 /* The version of the Motif drag-and-drop protocols that Emacs
  1762    supports.  */
  1763 #define XM_DRAG_PROTOCOL_VERSION        0
  1764 
  1765 static uint8_t
  1766 xm_side_effect_from_action (struct x_display_info *dpyinfo, Atom action)
  1767 {
  1768   if (action == dpyinfo->Xatom_XdndActionCopy)
  1769     return XM_DRAG_COPY;
  1770   else if (action == dpyinfo->Xatom_XdndActionMove)
  1771     return XM_DRAG_MOVE;
  1772   else if (action == dpyinfo->Xatom_XdndActionLink)
  1773     return XM_DRAG_LINK;
  1774   else if (action == dpyinfo->Xatom_XdndActionAsk)
  1775     return x_dnd_first_motif_operation;
  1776 
  1777   return XM_DRAG_NOOP;
  1778 }
  1779 
  1780 static uint8_t
  1781 xm_operations_from_actions (struct x_display_info *dpyinfo,
  1782                             Atom *ask_actions, int n_ask_actions)
  1783 {
  1784   int i;
  1785   uint8_t flags;
  1786 
  1787   flags = 0;
  1788 
  1789   for (i = 0; i < n_ask_actions; ++i)
  1790     {
  1791       if (ask_actions[i] == dpyinfo->Xatom_XdndActionCopy)
  1792         flags |= XM_DRAG_COPY;
  1793       else if (ask_actions[i] == dpyinfo->Xatom_XdndActionMove)
  1794         flags |= XM_DRAG_MOVE;
  1795       else if (ask_actions[i] == dpyinfo->Xatom_XdndActionLink)
  1796         flags |= XM_DRAG_LINK;
  1797     }
  1798 
  1799   return flags;
  1800 }
  1801 
  1802 static int
  1803 xm_read_targets_table_header (uint8_t *bytes, ptrdiff_t length,
  1804                               xm_targets_table_header *header_return,
  1805                               xm_byte_order *byteorder_return)
  1806 {
  1807   if (length < 8)
  1808     return -1;
  1809 
  1810   header_return->byte_order = *byteorder_return = *(bytes++);
  1811   header_return->protocol = *(bytes++);
  1812 
  1813   header_return->target_list_count = *(uint16_t *) bytes;
  1814   header_return->total_data_size = *(uint32_t *) (bytes + 2);
  1815 
  1816   if (header_return->byte_order != XM_BYTE_ORDER_CUR_FIRST)
  1817     {
  1818       SWAPCARD16 (header_return->target_list_count);
  1819       SWAPCARD32 (header_return->total_data_size);
  1820     }
  1821 
  1822   header_return->byte_order = XM_BYTE_ORDER_CUR_FIRST;
  1823 
  1824   return 8;
  1825 }
  1826 
  1827 static xm_targets_table_rec *
  1828 xm_read_targets_table_rec (uint8_t *bytes, ptrdiff_t length,
  1829                            xm_byte_order byteorder)
  1830 {
  1831   uint16_t nitems, i;
  1832   xm_targets_table_rec *rec;
  1833 
  1834   if (length < 2)
  1835     return NULL;
  1836 
  1837   nitems = *(uint16_t *) bytes;
  1838 
  1839   if (byteorder != XM_BYTE_ORDER_CUR_FIRST)
  1840     SWAPCARD16 (nitems);
  1841 
  1842   if (length < 2 + nitems * 4)
  1843     return NULL;
  1844 
  1845   rec = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
  1846                              targets, nitems * 4));
  1847   rec->n_targets = nitems;
  1848 
  1849   for (i = 0; i < nitems; ++i)
  1850     {
  1851       rec->targets[i] = ((uint32_t *) (bytes + 2))[i];
  1852 
  1853       if (byteorder != XM_BYTE_ORDER_CUR_FIRST)
  1854         SWAPCARD32 (rec->targets[i]);
  1855     }
  1856 
  1857   return rec;
  1858 }
  1859 
  1860 static int
  1861 xm_find_targets_table_idx (xm_targets_table_header *header,
  1862                            xm_targets_table_rec **recs,
  1863                            Atom *sorted_targets, int ntargets)
  1864 {
  1865   int j;
  1866   uint16_t i;
  1867   uint32_t *targets;
  1868 
  1869   targets = alloca (sizeof *targets * ntargets);
  1870 
  1871   for (j = 0; j < ntargets; ++j)
  1872     targets[j] = sorted_targets[j];
  1873 
  1874   for (i = 0; i < header->target_list_count; ++i)
  1875     {
  1876       if (recs[i]->n_targets == ntargets
  1877           && !memcmp (&recs[i]->targets, targets,
  1878                       sizeof *targets * ntargets))
  1879         return i;
  1880     }
  1881 
  1882   return -1;
  1883 }
  1884 
  1885 static int
  1886 x_atoms_compare (const void *a, const void *b)
  1887 {
  1888   return *(Atom *) a - *(Atom *) b;
  1889 }
  1890 
  1891 static void
  1892 xm_write_targets_table (Display *dpy, Window wdesc,
  1893                         Atom targets_table_atom,
  1894                         xm_targets_table_header *header,
  1895                         xm_targets_table_rec **recs)
  1896 {
  1897   uint8_t *header_buffer, *ptr, *rec_buffer;
  1898   ptrdiff_t rec_buffer_size;
  1899   uint16_t i, j;
  1900 
  1901   header_buffer = alloca (8);
  1902   ptr = header_buffer;
  1903 
  1904   *(header_buffer++) = header->byte_order;
  1905   *(header_buffer++) = header->protocol;
  1906   *((uint16_t *) header_buffer) = header->target_list_count;
  1907   *((uint32_t *) (header_buffer + 2)) = header->total_data_size;
  1908 
  1909   rec_buffer = xmalloc (600);
  1910   rec_buffer_size = 600;
  1911 
  1912   XChangeProperty (dpy, wdesc, targets_table_atom,
  1913                    targets_table_atom, 8, PropModeReplace,
  1914                    (unsigned char *) ptr, 8);
  1915 
  1916   for (i = 0; i < header->target_list_count; ++i)
  1917     {
  1918       if (rec_buffer_size < 2 + recs[i]->n_targets * 4)
  1919         {
  1920           rec_buffer_size = 2 + recs[i]->n_targets * 4;
  1921           rec_buffer = xrealloc (rec_buffer, rec_buffer_size);
  1922         }
  1923 
  1924       *((uint16_t *) rec_buffer) = recs[i]->n_targets;
  1925 
  1926       for (j = 0; j < recs[i]->n_targets; ++j)
  1927         ((uint32_t *) (rec_buffer + 2))[j] = recs[i]->targets[j];
  1928 
  1929       XChangeProperty (dpy, wdesc, targets_table_atom,
  1930                        targets_table_atom, 8, PropModeAppend,
  1931                        (unsigned char *) rec_buffer,
  1932                        2 + recs[i]->n_targets * 4);
  1933     }
  1934 
  1935   xfree (rec_buffer);
  1936 }
  1937 
  1938 static void
  1939 xm_write_drag_initiator_info (Display *dpy, Window wdesc,
  1940                               Atom prop_name, Atom type_name,
  1941                               xm_drag_initiator_info *info)
  1942 {
  1943   uint8_t *buf;
  1944 
  1945   buf = alloca (8);
  1946   buf[0] = info->byteorder;
  1947   buf[1] = info->protocol;
  1948 
  1949   if (info->byteorder != XM_BYTE_ORDER_CUR_FIRST)
  1950     {
  1951       SWAPCARD16 (info->table_index);
  1952       SWAPCARD16 (info->selection);
  1953     }
  1954 
  1955   *((uint16_t *) (buf + 2)) = info->table_index;
  1956   *((uint32_t *) (buf + 4)) = info->selection;
  1957 
  1958   XChangeProperty (dpy, wdesc, prop_name, type_name, 8,
  1959                    PropModeReplace, (unsigned char *) buf, 8);
  1960 }
  1961 
  1962 static int
  1963 xm_drag_window_error_handler (Display *display, XErrorEvent *event)
  1964 {
  1965   if (xm_drag_window_error)
  1966     *xm_drag_window_error = true;
  1967 
  1968   return 0;
  1969 }
  1970 
  1971 static _Noreturn int
  1972 xm_drag_window_io_error_handler (Display *dpy)
  1973 {
  1974   /* DPY isn't created through GDK, so it doesn't matter if we don't
  1975      crash here.  */
  1976   siglongjmp (x_dnd_disconnect_handler, 1);
  1977 }
  1978 
  1979 /* Determine whether or not WINDOW exists on DPYINFO by selecting for
  1980    input from it.  */
  1981 static bool
  1982 x_special_window_exists_p (struct x_display_info *dpyinfo,
  1983                            Window window)
  1984 {
  1985   bool rc;
  1986 
  1987   x_catch_errors (dpyinfo->display);
  1988   XSelectInput (dpyinfo->display, window,
  1989                 StructureNotifyMask);
  1990   rc = !x_had_errors_p (dpyinfo->display);
  1991   x_uncatch_errors_after_check ();
  1992 
  1993   return rc;
  1994 }
  1995 
  1996 /* Drag window creation strategy (very tricky, but race-free):
  1997 
  1998    First look for _MOTIF_DRAG_WINDOW.  If it is already present,
  1999    return it immediately to avoid the overhead of new display
  2000    connections.
  2001 
  2002    Otherwise, create a new connection to the display. In that
  2003    connection, create a window, which will be the new drag window. Set
  2004    the client disconnect mode of the new connection to
  2005    RetainPermanent, and close it.
  2006 
  2007    Grab the current display.  Look up _MOTIF_DRAG_WINDOW, the current
  2008    drag window.  If it exists (which means _MOTIF_DRAG_WINDOW was
  2009    created between the first step and now), kill the client that
  2010    created the new drag window to free the client slot on the X
  2011    server.  Otherwise, set _MOTIF_DRAG_WINDOW to the new drag window.
  2012 
  2013    Ungrab the display and return whichever window is currently in
  2014    _MOTIF_DRAG_WINDOW.  */
  2015 
  2016 static Window
  2017 xm_get_drag_window_1 (struct x_display_info *dpyinfo)
  2018 {
  2019   Atom actual_type;
  2020   int rc, actual_format;
  2021   unsigned long nitems, bytes_remaining;
  2022   unsigned char *tmp_data = NULL;
  2023   Window drag_window;
  2024   XSetWindowAttributes attrs;
  2025   Display *temp_display;
  2026   Emacs_XErrorHandler old_handler;
  2027   Emacs_XIOErrorHandler old_io_handler;
  2028 
  2029   /* This is volatile because GCC mistakenly warns about them being
  2030      clobbered by longjmp.  */
  2031   volatile bool error;
  2032 
  2033   drag_window = None;
  2034   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  2035                            dpyinfo->Xatom_MOTIF_DRAG_WINDOW,
  2036                            0, 1, False, XA_WINDOW, &actual_type,
  2037                            &actual_format, &nitems, &bytes_remaining,
  2038                            &tmp_data) == Success;
  2039 
  2040   if (rc && actual_type == XA_WINDOW
  2041       && actual_format == 32 && nitems == 1
  2042       && tmp_data)
  2043     {
  2044       drag_window = *(Window *) tmp_data;
  2045 
  2046       /* This has the side effect of selecting for
  2047          StructureNotifyMask, meaning that we will get notifications
  2048          once it is deleted.  */
  2049       rc = x_special_window_exists_p (dpyinfo, drag_window);
  2050 
  2051       if (!rc)
  2052         drag_window = None;
  2053     }
  2054 
  2055   if (tmp_data)
  2056     XFree (tmp_data);
  2057 
  2058   if (drag_window == None)
  2059     {
  2060       block_input ();
  2061       old_io_handler = XSetIOErrorHandler (xm_drag_window_io_error_handler);
  2062 
  2063       if (sigsetjmp (x_dnd_disconnect_handler, 1))
  2064         {
  2065           XSetIOErrorHandler (old_io_handler);
  2066           unblock_input ();
  2067 
  2068           return None;
  2069         }
  2070 
  2071       unrequest_sigio ();
  2072       temp_display = XOpenDisplay (XDisplayString (dpyinfo->display));
  2073       request_sigio ();
  2074 
  2075       if (!temp_display)
  2076         {
  2077           XSetIOErrorHandler (old_io_handler);
  2078           unblock_input ();
  2079 
  2080           return None;
  2081         }
  2082 
  2083       error = false;
  2084       xm_drag_window_error = &error;
  2085 
  2086       XSetCloseDownMode (temp_display, RetainPermanent);
  2087       old_handler = XSetErrorHandler (xm_drag_window_error_handler);
  2088 
  2089       attrs.override_redirect = True;
  2090       drag_window = XCreateWindow (temp_display, DefaultRootWindow (temp_display),
  2091                                    -1, -1, 1, 1, 0, CopyFromParent, InputOnly,
  2092                                    CopyFromParent, CWOverrideRedirect, &attrs);
  2093 
  2094       /* Handle all errors now.   */
  2095       XSync (temp_display, False);
  2096 
  2097       /* Some part of the drag window creation process failed, so
  2098          punt.  Release all resources too.  */
  2099       if (error)
  2100         {
  2101           XSetCloseDownMode (temp_display, DestroyAll);
  2102           drag_window = None;
  2103         }
  2104 
  2105       xm_drag_window_error = NULL;
  2106 
  2107       /* FIXME: why does XCloseDisplay hang if SIGIO arrives and there
  2108          are multiple displays? */
  2109       unrequest_sigio ();
  2110       XCloseDisplay (temp_display);
  2111       request_sigio ();
  2112 
  2113       XSetErrorHandler (old_handler);
  2114       XSetIOErrorHandler (old_io_handler);
  2115 
  2116       /* Make sure the drag window created is actually valid for the
  2117          current display, and the XOpenDisplay above didn't
  2118          accidentally connect to some other display.  */
  2119       if (!x_special_window_exists_p (dpyinfo, drag_window))
  2120         drag_window = None;
  2121       unblock_input ();
  2122 
  2123       if (drag_window != None)
  2124         {
  2125           XGrabServer (dpyinfo->display);
  2126 
  2127           x_catch_errors (dpyinfo->display);
  2128           tmp_data = NULL;
  2129 
  2130           rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  2131                                    dpyinfo->Xatom_MOTIF_DRAG_WINDOW,
  2132                                    0, 1, False, XA_WINDOW, &actual_type,
  2133                                    &actual_format, &nitems, &bytes_remaining,
  2134                                    &tmp_data) == Success;
  2135 
  2136           if (rc && actual_type == XA_WINDOW
  2137               && actual_format == 32 && nitems == 1
  2138               && tmp_data
  2139               && x_special_window_exists_p (dpyinfo,
  2140                                             *(Window *) tmp_data))
  2141             {
  2142               /* Kill the client now to avoid leaking a client slot,
  2143                  which is a limited resource.  */
  2144               XKillClient (dpyinfo->display, drag_window);
  2145               drag_window = *(Window *) tmp_data;
  2146             }
  2147           else
  2148             XChangeProperty (dpyinfo->display, dpyinfo->root_window,
  2149                              dpyinfo->Xatom_MOTIF_DRAG_WINDOW,
  2150                              XA_WINDOW, 32, PropModeReplace,
  2151                              (unsigned char *) &drag_window, 1);
  2152 
  2153           if (tmp_data)
  2154             XFree (tmp_data);
  2155 
  2156           if (x_had_errors_p (dpyinfo->display))
  2157             drag_window = None;
  2158           x_uncatch_errors ();
  2159 
  2160           XUngrabServer (dpyinfo->display);
  2161         }
  2162     }
  2163 
  2164   return drag_window;
  2165 }
  2166 
  2167 static Window
  2168 xm_get_drag_window (struct x_display_info *dpyinfo)
  2169 {
  2170   if (dpyinfo->motif_drag_window != None)
  2171     return dpyinfo->motif_drag_window;
  2172 
  2173   dpyinfo->motif_drag_window = xm_get_drag_window_1 (dpyinfo);
  2174   return dpyinfo->motif_drag_window;
  2175 }
  2176 
  2177 static int
  2178 xm_setup_dnd_targets (struct x_display_info *dpyinfo,
  2179                       Atom *targets, int ntargets)
  2180 {
  2181   Window drag_window;
  2182   Atom *targets_sorted, actual_type;
  2183   unsigned char *tmp_data = NULL;
  2184   unsigned long nitems, bytes_remaining;
  2185   int rc, actual_format, idx;
  2186   bool had_errors;
  2187   xm_targets_table_header header;
  2188   xm_targets_table_rec **recs UNINIT;
  2189   xm_byte_order byteorder;
  2190   uint8_t *data;
  2191   ptrdiff_t total_bytes, total_items, i;
  2192   uint32_t size, target_count;
  2193 
  2194  retry_drag_window:
  2195 
  2196   drag_window = xm_get_drag_window (dpyinfo);
  2197 
  2198   if (drag_window == None || ntargets > 64)
  2199     return -1;
  2200 
  2201   targets_sorted = xmalloc (sizeof *targets * ntargets);
  2202   memcpy (targets_sorted, targets,
  2203           sizeof *targets * ntargets);
  2204   qsort (targets_sorted, ntargets,
  2205          sizeof (Atom), x_atoms_compare);
  2206 
  2207   XGrabServer (dpyinfo->display);
  2208 
  2209   x_catch_errors (dpyinfo->display);
  2210   rc = XGetWindowProperty (dpyinfo->display, drag_window,
  2211                            dpyinfo->Xatom_MOTIF_DRAG_TARGETS,
  2212                            0L, LONG_MAX, False,
  2213                            dpyinfo->Xatom_MOTIF_DRAG_TARGETS,
  2214                            &actual_type, &actual_format, &nitems,
  2215                            &bytes_remaining, &tmp_data) == Success;
  2216   had_errors = x_had_errors_p (dpyinfo->display);
  2217   x_uncatch_errors_after_check ();
  2218 
  2219   /* The drag window is probably invalid, so remove our record of
  2220      it.  */
  2221   if (had_errors)
  2222     {
  2223       dpyinfo->motif_drag_window = None;
  2224       XUngrabServer (dpyinfo->display);
  2225 
  2226       goto retry_drag_window;
  2227     }
  2228 
  2229   if (rc && tmp_data && !bytes_remaining
  2230       && actual_type == dpyinfo->Xatom_MOTIF_DRAG_TARGETS
  2231       && actual_format == 8)
  2232     {
  2233       data = (uint8_t *) tmp_data;
  2234       if (xm_read_targets_table_header ((uint8_t *) tmp_data,
  2235                                         nitems, &header,
  2236                                         &byteorder) == 8)
  2237         {
  2238           data += 8;
  2239           nitems -= 8;
  2240           total_bytes = 0;
  2241           total_items = 0;
  2242 
  2243           /* The extra rec is used to store a new target list if a
  2244              preexisting one doesn't already exist.  */
  2245           recs = xmalloc ((header.target_list_count + 1)
  2246                           * sizeof *recs);
  2247 
  2248           while (total_items < header.target_list_count)
  2249             {
  2250               recs[total_items] = xm_read_targets_table_rec (data + total_bytes,
  2251                                                              nitems, byteorder);
  2252 
  2253               if (!recs[total_items])
  2254                 break;
  2255 
  2256               total_bytes += 2 + recs[total_items]->n_targets * 4;
  2257               nitems -= 2 + recs[total_items]->n_targets * 4;
  2258               total_items++;
  2259             }
  2260 
  2261           if (header.target_list_count != total_items
  2262               || header.total_data_size != 8 + total_bytes)
  2263             {
  2264               for (i = 0; i < total_items; ++i)
  2265                 {
  2266                   if (recs[i])
  2267                       xfree (recs[i]);
  2268                   else
  2269                     break;
  2270                 }
  2271 
  2272               xfree (recs);
  2273 
  2274               rc = false;
  2275             }
  2276         }
  2277       else
  2278         rc = false;
  2279     }
  2280   else
  2281     rc = false;
  2282 
  2283   if (tmp_data)
  2284     XFree (tmp_data);
  2285 
  2286   /* Now rc means whether or not the target lists weren't updated and
  2287      shouldn't be written to the drag window.  */
  2288 
  2289   if (!rc)
  2290     {
  2291       header.byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2292       header.protocol = XM_DRAG_PROTOCOL_VERSION;
  2293       header.target_list_count = 1;
  2294       header.total_data_size = 8 + 2 + ntargets * 4;
  2295 
  2296       recs = xmalloc (sizeof *recs);
  2297       recs[0] = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
  2298                                      targets, ntargets * 4));
  2299 
  2300       recs[0]->n_targets = ntargets;
  2301 
  2302       for (i = 0; i < ntargets; ++i)
  2303         recs[0]->targets[i] = targets_sorted[i];
  2304 
  2305       idx = 0;
  2306     }
  2307   else
  2308     {
  2309       idx = xm_find_targets_table_idx (&header, recs,
  2310                                        targets_sorted,
  2311                                        ntargets);
  2312 
  2313       if (idx == -1)
  2314         {
  2315           target_count = header.target_list_count;
  2316           rc = false;
  2317 
  2318           if (ckd_add (&header.target_list_count, header.target_list_count, 1)
  2319               || ckd_mul (&size, ntargets, 4)
  2320               || ckd_add (&header.total_data_size, header.total_data_size, size)
  2321               || ckd_add (&header.total_data_size, header.total_data_size, 2))
  2322             {
  2323               /* Overflow, remove every entry from the targets table
  2324                  and add one for our current targets list.  This
  2325                  confuses real Motif but not GTK 2.x, and there is no
  2326                  other choice.  */
  2327 
  2328               for (i = 0; i < target_count; ++i)
  2329                 xfree (recs[i]);
  2330 
  2331               xfree (recs);
  2332 
  2333               header.byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2334               header.protocol = XM_DRAG_PROTOCOL_VERSION;
  2335               header.target_list_count = 1;
  2336               header.total_data_size = 8 + 2 + ntargets * 4;
  2337 
  2338               recs = xmalloc (sizeof *recs);
  2339               recs[0] = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
  2340                                              targets, ntargets * 4));
  2341 
  2342               recs[0]->n_targets = ntargets;
  2343 
  2344               for (i = 0; i < ntargets; ++i)
  2345                 recs[0]->targets[i] = targets_sorted[i];
  2346 
  2347               idx = 0;
  2348             }
  2349           else
  2350             {
  2351               recs[header.target_list_count - 1]
  2352                 = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
  2353                                        targets, ntargets * 4));
  2354               recs[header.target_list_count - 1]->n_targets = ntargets;
  2355 
  2356               for (i = 0; i < ntargets; ++i)
  2357                 recs[header.target_list_count - 1]->targets[i] = targets_sorted[i];
  2358 
  2359               idx = header.target_list_count - 1;
  2360             }
  2361         }
  2362     }
  2363 
  2364   if (!rc)
  2365     {
  2366       /* Some implementations of Motif DND set the protocol version of
  2367          just the targets table to 1 without actually changing the
  2368          data format.  To avoid confusing Motif when that happens, set
  2369          it back to 0.  There will probably be no more updates to the
  2370          protocol either.  */
  2371       header.protocol = XM_DRAG_PROTOCOL_VERSION;
  2372 
  2373       x_catch_errors (dpyinfo->display);
  2374       xm_write_targets_table (dpyinfo->display, drag_window,
  2375                               dpyinfo->Xatom_MOTIF_DRAG_TARGETS,
  2376                               &header, recs);
  2377       /* Presumably we got a BadAlloc upon writing the targets
  2378          table.  */
  2379       if (x_had_errors_p (dpyinfo->display))
  2380         idx = -1;
  2381       x_uncatch_errors_after_check ();
  2382     }
  2383 
  2384   XUngrabServer (dpyinfo->display);
  2385 
  2386   for (i = 0; i < header.target_list_count; ++i)
  2387     xfree (recs[i]);
  2388 
  2389   xfree (recs);
  2390   xfree (targets_sorted);
  2391 
  2392   return idx;
  2393 }
  2394 
  2395 /* Allocate an atom that will be used for the Motif selection during
  2396    the drag-and-drop operation.
  2397 
  2398    Grab the server, and then retrieve a list of atoms named
  2399    _EMACS_DRAG_ATOM from the root window.  Find the first atom that
  2400    has no selection owner, own it and return it.  If there is no such
  2401    atom, add a unique atom to the end of the list and return that
  2402    instead.  */
  2403 
  2404 static Atom
  2405 xm_get_drag_atom_1 (struct x_display_info *dpyinfo,
  2406                     struct frame *source_frame)
  2407 {
  2408   Atom actual_type, *atoms, atom;
  2409   unsigned long nitems, bytes_remaining;
  2410   unsigned char *tmp_data;
  2411   int rc, actual_format;
  2412   unsigned long i;
  2413   char *buffer;
  2414   Window owner;
  2415 
  2416   /* Make sure this operation is done atomically.  */
  2417   XGrabServer (dpyinfo->display);
  2418 
  2419   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  2420                            dpyinfo->Xatom_EMACS_DRAG_ATOM,
  2421                            0, LONG_MAX, False, XA_ATOM, &actual_type,
  2422                            &actual_format, &nitems, &bytes_remaining,
  2423                            &tmp_data);
  2424   atom = None;
  2425   /* GCC thinks i is used uninitialized, but it's always initialized if
  2426      `atoms' exists at that particular spot.  */
  2427   i = 0;
  2428 
  2429   if (rc == Success
  2430       && actual_format == 32 && nitems
  2431       && actual_type == XA_ATOM)
  2432     {
  2433       atoms = (Atom *) tmp_data;
  2434 
  2435       x_catch_errors (dpyinfo->display);
  2436 
  2437       for (i = 0; i < nitems; ++i)
  2438         {
  2439           owner = XGetSelectionOwner (dpyinfo->display, atoms[i]);
  2440 
  2441           if (!x_had_errors_p (dpyinfo->display)
  2442               && (owner == None
  2443                   /* If we already own this selection (even if another
  2444                      frame owns it), use it.  There is no way of
  2445                      knowing when ownership was asserted, so it still
  2446                      has to be owned again.  */
  2447                   || x_window_to_frame (dpyinfo, owner)))
  2448             {
  2449               atom = atoms[i];
  2450 
  2451               break;
  2452             }
  2453         }
  2454 
  2455       x_uncatch_errors ();
  2456     }
  2457 
  2458   if (tmp_data)
  2459     XFree (tmp_data);
  2460 
  2461   buffer = dpyinfo->motif_drag_atom_name;
  2462 
  2463   if (atom)
  2464     {
  2465       sprintf (buffer, "_EMACS_ATOM_%lu", i + 1);
  2466       XSetSelectionOwner (dpyinfo->display, atom,
  2467                           FRAME_X_WINDOW (source_frame),
  2468                           dpyinfo->last_user_time);
  2469 
  2470       /* The selection's last-change time is newer than our
  2471          last_user_time, so create a new selection instead.  */
  2472       if (XGetSelectionOwner (dpyinfo->display, atom)
  2473           != FRAME_X_WINDOW (source_frame))
  2474         atom = None;
  2475     }
  2476 
  2477   while (!atom)
  2478     {
  2479       sprintf (buffer, "_EMACS_ATOM_%lu", nitems + 1);
  2480       atom = XInternAtom (dpyinfo->display, buffer, False);
  2481 
  2482       XSetSelectionOwner (dpyinfo->display, atom,
  2483                           FRAME_X_WINDOW (source_frame),
  2484                           dpyinfo->last_user_time);
  2485 
  2486       XChangeProperty (dpyinfo->display, dpyinfo->root_window,
  2487                        dpyinfo->Xatom_EMACS_DRAG_ATOM, XA_ATOM, 32,
  2488                        (rc != Success
  2489                         || (actual_format != 32
  2490                             || actual_type != XA_ATOM)
  2491                         ? PropModeReplace : PropModeAppend),
  2492                        (unsigned char *) &atom, 1);
  2493 
  2494       actual_format = 32;
  2495       actual_type = XA_ATOM;
  2496       rc = Success;
  2497       nitems += 1;
  2498 
  2499       /* The selection's last-change time is newer than our
  2500          last_user_time, so create a new selection (again).  */
  2501       if (XGetSelectionOwner (dpyinfo->display, atom)
  2502           != FRAME_X_WINDOW (source_frame))
  2503         atom = None;
  2504     }
  2505 
  2506   dpyinfo->motif_drag_atom_time = dpyinfo->last_user_time;
  2507   dpyinfo->motif_drag_atom_owner = source_frame;
  2508 
  2509   XUngrabServer (dpyinfo->display);
  2510   return atom;
  2511 }
  2512 
  2513 static Atom
  2514 xm_get_drag_atom (struct x_display_info *dpyinfo)
  2515 {
  2516   Atom atom;
  2517 
  2518   if (dpyinfo->motif_drag_atom != None)
  2519     atom = dpyinfo->motif_drag_atom;
  2520   else
  2521     atom = xm_get_drag_atom_1 (dpyinfo, x_dnd_frame);
  2522 
  2523   dpyinfo->motif_drag_atom = atom;
  2524   return atom;
  2525 }
  2526 
  2527 static void
  2528 xm_setup_drag_info (struct x_display_info *dpyinfo,
  2529                     struct frame *source_frame)
  2530 {
  2531   Atom atom;
  2532   xm_drag_initiator_info drag_initiator_info;
  2533   int idx;
  2534 
  2535   atom = xm_get_drag_atom (dpyinfo);
  2536 
  2537   if (atom == None)
  2538     return;
  2539 
  2540   XSETCAR (x_dnd_selection_alias_cell,
  2541            x_atom_to_symbol (dpyinfo, atom));
  2542   XSETCDR (x_dnd_selection_alias_cell, QXdndSelection);
  2543 
  2544   idx = xm_setup_dnd_targets (dpyinfo, x_dnd_targets,
  2545                               x_dnd_n_targets);
  2546 
  2547   if (idx != -1)
  2548     {
  2549       drag_initiator_info.byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2550       drag_initiator_info.protocol = XM_DRAG_PROTOCOL_VERSION;
  2551       drag_initiator_info.table_index = idx;
  2552       drag_initiator_info.selection = atom;
  2553 
  2554       xm_write_drag_initiator_info (dpyinfo->display,
  2555                                     FRAME_X_WINDOW (source_frame), atom,
  2556                                     dpyinfo->Xatom_MOTIF_DRAG_INITIATOR_INFO,
  2557                                     &drag_initiator_info);
  2558 
  2559       x_dnd_motif_setup_p = true;
  2560       x_dnd_motif_atom = atom;
  2561     }
  2562 }
  2563 
  2564 static void
  2565 xm_send_drop_message (struct x_display_info *dpyinfo, Window source,
  2566                       Window target, xm_drop_start_message *dmsg)
  2567 {
  2568   XEvent msg;
  2569 
  2570   msg.xclient.type = ClientMessage;
  2571   msg.xclient.message_type
  2572     = dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE;
  2573   msg.xclient.format = 8;
  2574   msg.xclient.window = target;
  2575   msg.xclient.data.b[0] = dmsg->reason;
  2576   msg.xclient.data.b[1] = dmsg->byte_order;
  2577   *((uint16_t *) &msg.xclient.data.b[2]) = dmsg->side_effects;
  2578   *((uint32_t *) &msg.xclient.data.b[4]) = dmsg->timestamp;
  2579   *((uint16_t *) &msg.xclient.data.b[8]) = dmsg->x;
  2580   *((uint16_t *) &msg.xclient.data.b[10]) = dmsg->y;
  2581   *((uint32_t *) &msg.xclient.data.b[12]) = dmsg->index_atom;
  2582   *((uint32_t *) &msg.xclient.data.b[16]) = dmsg->source_window;
  2583 
  2584   x_ignore_errors_for_next_request (dpyinfo, 0);
  2585   XSendEvent (dpyinfo->display, target, False, NoEventMask, &msg);
  2586   x_stop_ignoring_errors (dpyinfo);
  2587 }
  2588 
  2589 static void
  2590 xm_send_top_level_enter_message (struct x_display_info *dpyinfo, Window source,
  2591                                  Window target, xm_top_level_enter_message *dmsg)
  2592 {
  2593   XEvent msg;
  2594 
  2595   msg.xclient.type = ClientMessage;
  2596   msg.xclient.message_type
  2597     = dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE;
  2598   msg.xclient.format = 8;
  2599   msg.xclient.window = target;
  2600   msg.xclient.data.b[0] = dmsg->reason;
  2601   msg.xclient.data.b[1] = dmsg->byteorder;
  2602   *((uint16_t *) &msg.xclient.data.b[2]) = dmsg->zero;
  2603   *((uint32_t *) &msg.xclient.data.b[4]) = dmsg->timestamp;
  2604   *((uint32_t *) &msg.xclient.data.b[8]) = dmsg->source_window;
  2605   *((uint32_t *) &msg.xclient.data.b[12]) = dmsg->index_atom;
  2606   msg.xclient.data.b[16] = 0;
  2607   msg.xclient.data.b[17] = 0;
  2608   msg.xclient.data.b[18] = 0;
  2609   msg.xclient.data.b[19] = 0;
  2610 
  2611   x_ignore_errors_for_next_request (dpyinfo, 0);
  2612   XSendEvent (dpyinfo->display, target, False, NoEventMask, &msg);
  2613   x_stop_ignoring_errors (dpyinfo);
  2614 }
  2615 
  2616 static void
  2617 xm_send_drag_motion_message (struct x_display_info *dpyinfo, Window source,
  2618                              Window target, xm_drag_motion_message *dmsg)
  2619 {
  2620   XEvent msg;
  2621 
  2622   msg.xclient.type = ClientMessage;
  2623   msg.xclient.message_type
  2624     = dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE;
  2625   msg.xclient.format = 8;
  2626   msg.xclient.window = target;
  2627   msg.xclient.data.b[0] = dmsg->reason;
  2628   msg.xclient.data.b[1] = dmsg->byteorder;
  2629   *((uint16_t *) &msg.xclient.data.b[2]) = dmsg->side_effects;
  2630   *((uint32_t *) &msg.xclient.data.b[4]) = dmsg->timestamp;
  2631   *((uint16_t *) &msg.xclient.data.b[8]) = dmsg->x;
  2632   *((uint16_t *) &msg.xclient.data.b[10]) = dmsg->y;
  2633   msg.xclient.data.b[12] = 0;
  2634   msg.xclient.data.b[13] = 0;
  2635   msg.xclient.data.b[14] = 0;
  2636   msg.xclient.data.b[15] = 0;
  2637   msg.xclient.data.b[16] = 0;
  2638   msg.xclient.data.b[17] = 0;
  2639   msg.xclient.data.b[18] = 0;
  2640   msg.xclient.data.b[19] = 0;
  2641 
  2642   x_ignore_errors_for_next_request (dpyinfo, 0);
  2643   XSendEvent (dpyinfo->display, target, False, NoEventMask, &msg);
  2644   x_stop_ignoring_errors (dpyinfo);
  2645 }
  2646 
  2647 static void
  2648 xm_send_top_level_leave_message (struct x_display_info *dpyinfo, Window source,
  2649                                  Window target, xm_top_level_leave_message *dmsg)
  2650 {
  2651   XEvent msg;
  2652   xm_drag_motion_message mmsg;
  2653 
  2654   /* Motif support for TOP_LEVEL_LEAVE has bitrotted, since these days
  2655      it assumes every client supports the preregister protocol style,
  2656      but we only support drop-only and dynamic.  (Interestingly enough
  2657      LessTif works fine.)  Sending an event with impossible
  2658      coordinates serves to get rid of any active drop site that might
  2659      still be around in the target drag context.  */
  2660 
  2661   if (x_dnd_fix_motif_leave)
  2662     {
  2663       mmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
  2664                                     XM_DRAG_REASON_DRAG_MOTION);
  2665       mmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2666       mmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
  2667                                                                            x_dnd_wanted_action),
  2668                                                XM_DROP_SITE_NONE, x_dnd_motif_operations,
  2669                                                XM_DROP_ACTION_DROP_CANCEL);
  2670       mmsg.timestamp = dmsg->timestamp;
  2671 
  2672       /* Use X_SHRT_MAX instead of the max value of uint16_t since
  2673          that will be interpreted as a plausible position by Motif,
  2674          and as such breaks if the drop target is beneath that
  2675          position.  */
  2676       mmsg.x = X_SHRT_MAX;
  2677       mmsg.y = X_SHRT_MAX;
  2678 
  2679       xm_send_drag_motion_message (dpyinfo, source, target, &mmsg);
  2680     }
  2681 
  2682   msg.xclient.type = ClientMessage;
  2683   msg.xclient.message_type
  2684     = dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE;
  2685   msg.xclient.format = 8;
  2686   msg.xclient.window = target;
  2687   msg.xclient.data.b[0] = dmsg->reason;
  2688   msg.xclient.data.b[1] = dmsg->byteorder;
  2689   *((uint16_t *) &msg.xclient.data.b[2]) = dmsg->zero;
  2690   *((uint32_t *) &msg.xclient.data.b[4]) = dmsg->timestamp;
  2691   *((uint32_t *) &msg.xclient.data.b[8]) = dmsg->source_window;
  2692   msg.xclient.data.b[12] = 0;
  2693   msg.xclient.data.b[13] = 0;
  2694   msg.xclient.data.b[14] = 0;
  2695   msg.xclient.data.b[15] = 0;
  2696   msg.xclient.data.b[16] = 0;
  2697   msg.xclient.data.b[17] = 0;
  2698   msg.xclient.data.b[18] = 0;
  2699   msg.xclient.data.b[19] = 0;
  2700 
  2701   x_ignore_errors_for_next_request (dpyinfo, 0);
  2702   XSendEvent (dpyinfo->display, target, False, NoEventMask, &msg);
  2703   x_stop_ignoring_errors (dpyinfo);
  2704 }
  2705 
  2706 static int
  2707 xm_read_drop_start_reply (const XEvent *msg, xm_drop_start_reply *reply)
  2708 {
  2709   const uint8_t *data;
  2710 
  2711   data = (const uint8_t *) &msg->xclient.data.b[0];
  2712 
  2713   if ((XM_DRAG_REASON_ORIGINATOR (data[0])
  2714        != XM_DRAG_ORIGINATOR_RECEIVER)
  2715       || (XM_DRAG_REASON_CODE (data[0])
  2716           != XM_DRAG_REASON_DROP_START))
  2717     return 1;
  2718 
  2719   reply->reason = *(data++);
  2720   reply->byte_order = *(data++);
  2721   reply->side_effects = *(uint16_t *) data;
  2722   reply->better_x = *(uint16_t *) (data + 2);
  2723   reply->better_y = *(uint16_t *) (data + 4);
  2724 
  2725   if (reply->byte_order != XM_BYTE_ORDER_CUR_FIRST)
  2726     {
  2727       SWAPCARD16 (reply->side_effects);
  2728       SWAPCARD16 (reply->better_x);
  2729       SWAPCARD16 (reply->better_y);
  2730     }
  2731 
  2732   reply->byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2733 
  2734   return 0;
  2735 }
  2736 
  2737 static int
  2738 xm_read_drop_start_message (const XEvent *msg,
  2739                             xm_drop_start_message *dmsg)
  2740 {
  2741   const uint8_t *data;
  2742 
  2743   data = (const uint8_t *) &msg->xclient.data.b[0];
  2744 
  2745   if ((XM_DRAG_REASON_ORIGINATOR (data[0])
  2746        != XM_DRAG_ORIGINATOR_INITIATOR)
  2747       || (XM_DRAG_REASON_CODE (data[0])
  2748           != XM_DRAG_REASON_DROP_START))
  2749     return 1;
  2750 
  2751   dmsg->reason = *(data++);
  2752   dmsg->byte_order = *(data++);
  2753   dmsg->side_effects = *(uint16_t *) data;
  2754   dmsg->timestamp = *(uint32_t *) (data + 2);
  2755   dmsg->x = *(uint16_t *) (data + 6);
  2756   dmsg->y = *(uint16_t *) (data + 8);
  2757   dmsg->index_atom = *(uint32_t *) (data + 10);
  2758   dmsg->source_window = *(uint32_t *) (data + 14);
  2759 
  2760   if (dmsg->byte_order != XM_BYTE_ORDER_CUR_FIRST)
  2761     {
  2762       SWAPCARD16 (dmsg->side_effects);
  2763       SWAPCARD32 (dmsg->timestamp);
  2764       SWAPCARD16 (dmsg->x);
  2765       SWAPCARD16 (dmsg->y);
  2766       SWAPCARD32 (dmsg->index_atom);
  2767       SWAPCARD32 (dmsg->source_window);
  2768     }
  2769 
  2770   dmsg->byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2771 
  2772   return 0;
  2773 }
  2774 
  2775 static int
  2776 xm_read_drag_receiver_info (struct x_display_info *dpyinfo,
  2777                             Window wdesc, xm_drag_receiver_info *rec)
  2778 {
  2779   Atom actual_type;
  2780   int rc, actual_format;
  2781   unsigned long nitems, bytes_remaining;
  2782   unsigned char *tmp_data = NULL;
  2783   uint8_t *data;
  2784 
  2785   x_catch_errors (dpyinfo->display);
  2786   rc = XGetWindowProperty (dpyinfo->display, wdesc,
  2787                            dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  2788                            0, 4, False,
  2789                            dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  2790                            &actual_type, &actual_format, &nitems,
  2791                            &bytes_remaining,
  2792                            &tmp_data) == Success;
  2793 
  2794   if (x_had_errors_p (dpyinfo->display)
  2795       || actual_format != 8 || nitems < 16 || !tmp_data
  2796       || actual_type != dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO)
  2797     rc = 0;
  2798   x_uncatch_errors_after_check ();
  2799 
  2800   if (rc)
  2801     {
  2802       data = (uint8_t *) tmp_data;
  2803 
  2804       if (data[1] > XM_DRAG_PROTOCOL_VERSION)
  2805         return 1;
  2806 
  2807       rec->byteorder = data[0];
  2808       rec->protocol = data[1];
  2809       rec->protocol_style = data[2];
  2810       rec->unspecified0 = data[3];
  2811       rec->unspecified1 = *(uint32_t *) &data[4];
  2812       rec->unspecified2 = *(uint32_t *) &data[8];
  2813       rec->unspecified3 = *(uint32_t *) &data[12];
  2814 
  2815       if (rec->byteorder != XM_BYTE_ORDER_CUR_FIRST)
  2816         {
  2817           SWAPCARD32 (rec->unspecified1);
  2818           SWAPCARD32 (rec->unspecified2);
  2819           SWAPCARD32 (rec->unspecified3);
  2820         }
  2821 
  2822       rec->byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2823     }
  2824 
  2825   if (tmp_data)
  2826     XFree (tmp_data);
  2827 
  2828   return !rc;
  2829 }
  2830 
  2831 static int
  2832 xm_read_drag_motion_message (const XEvent *msg,
  2833                              xm_drag_motion_message *dmsg)
  2834 {
  2835   const uint8_t *data;
  2836 
  2837   data = (const uint8_t *) &msg->xclient.data.b[0];
  2838 
  2839   if ((XM_DRAG_REASON_CODE (data[0])
  2840        != XM_DRAG_REASON_DRAG_MOTION)
  2841       || (XM_DRAG_REASON_ORIGINATOR (data[0])
  2842           != XM_DRAG_ORIGINATOR_INITIATOR))
  2843     return 1;
  2844 
  2845   dmsg->reason = *(data++);
  2846   dmsg->byteorder = *(data++);
  2847   dmsg->side_effects = *(uint16_t *) data;
  2848   dmsg->timestamp = *(uint32_t *) (data + 2);
  2849   dmsg->x = *(uint16_t *) (data + 6);
  2850   dmsg->y = *(uint16_t *) (data + 8);
  2851 
  2852   if (dmsg->byteorder != XM_BYTE_ORDER_CUR_FIRST)
  2853     {
  2854       SWAPCARD16 (dmsg->side_effects);
  2855       SWAPCARD32 (dmsg->timestamp);
  2856       SWAPCARD16 (dmsg->x);
  2857       SWAPCARD16 (dmsg->y);
  2858     }
  2859 
  2860   dmsg->byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2861 
  2862   return 0;
  2863 }
  2864 
  2865 static int
  2866 xm_read_drag_motion_reply (const XEvent *msg, xm_drag_motion_reply *reply)
  2867 {
  2868   const uint8_t *data;
  2869 
  2870   data = (const uint8_t *) &msg->xclient.data.b[0];
  2871 
  2872   if ((XM_DRAG_REASON_CODE (data[0])
  2873        != XM_DRAG_REASON_DRAG_MOTION)
  2874       || (XM_DRAG_REASON_ORIGINATOR (data[0])
  2875           != XM_DRAG_ORIGINATOR_RECEIVER))
  2876     return 1;
  2877 
  2878   reply->reason = *(data++);
  2879   reply->byte_order = *(data++);
  2880   reply->side_effects = *(uint16_t *) data;
  2881   reply->timestamp = *(uint32_t *) (data + 2);
  2882   reply->better_x = *(uint16_t *) (data + 6);
  2883   reply->better_y = *(uint16_t *) (data + 8);
  2884 
  2885   if (reply->byte_order != XM_BYTE_ORDER_CUR_FIRST)
  2886     {
  2887       SWAPCARD16 (reply->side_effects);
  2888       SWAPCARD32 (reply->timestamp);
  2889       SWAPCARD16 (reply->better_x);
  2890       SWAPCARD16 (reply->better_y);
  2891     }
  2892 
  2893   reply->byte_order = XM_BYTE_ORDER_CUR_FIRST;
  2894 
  2895   return 0;
  2896 }
  2897 
  2898 static void
  2899 x_dnd_send_xm_leave_for_drop (struct x_display_info *dpyinfo,
  2900                               struct frame *f, Window wdesc,
  2901                               Time timestamp)
  2902 {
  2903   xm_top_level_leave_message lmsg;
  2904 
  2905   lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
  2906                                 XM_DRAG_REASON_TOP_LEVEL_LEAVE);
  2907   lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
  2908   lmsg.zero = 0;
  2909   lmsg.timestamp = timestamp;
  2910   lmsg.source_window = FRAME_X_WINDOW (f);
  2911 
  2912   if (x_dnd_motif_setup_p)
  2913     xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (f),
  2914                                      wdesc, &lmsg);
  2915 }
  2916 
  2917 static void
  2918 x_dnd_free_toplevels (bool display_alive)
  2919 {
  2920   struct x_client_list_window *last;
  2921   struct x_client_list_window *tem = x_dnd_toplevels;
  2922   ptrdiff_t n_windows, i, buffer_size;
  2923   Window *destroy_windows UNINIT;
  2924   unsigned long *prev_masks UNINIT;
  2925   specpdl_ref count;
  2926   Display *dpy UNINIT;
  2927   struct x_display_info *dpyinfo;
  2928 
  2929   if (!x_dnd_toplevels)
  2930     /* Probably called inside an IO error handler.  */
  2931     return;
  2932 
  2933   if (display_alive)
  2934     {
  2935       buffer_size = 1024;
  2936       destroy_windows = xmalloc (sizeof *destroy_windows
  2937                                  * buffer_size);
  2938       prev_masks = xmalloc (sizeof *prev_masks *
  2939                             buffer_size);
  2940       n_windows = 0;
  2941     }
  2942 
  2943   block_input ();
  2944   while (tem)
  2945     {
  2946       last = tem;
  2947       tem = tem->next;
  2948 
  2949       if (display_alive)
  2950         {
  2951           if (++n_windows >= buffer_size)
  2952             {
  2953               buffer_size += 1024;
  2954               destroy_windows
  2955                 = xrealloc (destroy_windows, (sizeof *destroy_windows
  2956                                               * buffer_size));
  2957               prev_masks
  2958                 = xrealloc (prev_masks, (sizeof *prev_masks
  2959                                          * buffer_size));
  2960             }
  2961 
  2962           dpy = last->dpy;
  2963           prev_masks[n_windows - 1] = last->previous_event_mask;
  2964           destroy_windows[n_windows - 1] = last->window;
  2965         }
  2966 
  2967 #ifdef HAVE_XSHAPE
  2968       if (last->n_input_rects != -1)
  2969         xfree (last->input_rects);
  2970       if (last->n_bounding_rects != -1)
  2971         xfree (last->bounding_rects);
  2972 #endif
  2973 
  2974       xfree (last);
  2975     }
  2976 
  2977   x_dnd_toplevels = NULL;
  2978 
  2979   if (!display_alive)
  2980     {
  2981       unblock_input ();
  2982       return;
  2983     }
  2984 
  2985   count = SPECPDL_INDEX ();
  2986   record_unwind_protect_ptr (xfree, destroy_windows);
  2987   record_unwind_protect_ptr (xfree, prev_masks);
  2988 
  2989   if (display_alive)
  2990     {
  2991       dpyinfo = x_display_info_for_display (dpy);
  2992 
  2993       if (n_windows)
  2994         {
  2995           eassume (dpyinfo);
  2996           x_ignore_errors_for_next_request (dpyinfo, 0);
  2997 
  2998           for (i = 0; i < n_windows; ++i)
  2999             {
  3000               XSelectInput (dpy, destroy_windows[i], prev_masks[i]);
  3001 #ifdef HAVE_XSHAPE
  3002               XShapeSelectInput (dpy, destroy_windows[i], None);
  3003 #endif
  3004             }
  3005 
  3006           x_stop_ignoring_errors (dpyinfo);
  3007         }
  3008     }
  3009 
  3010   unbind_to (count, Qnil);
  3011   unblock_input ();
  3012 }
  3013 
  3014 static int
  3015 x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
  3016 {
  3017   Atom type;
  3018   Window *toplevels;
  3019   int format, rc;
  3020   unsigned long nitems, bytes_after;
  3021   unsigned long i, real_nitems;
  3022   unsigned char *data = NULL;
  3023   int frame_extents[4];
  3024 
  3025 #ifndef USE_XCB
  3026   int dest_x, dest_y;
  3027   unsigned long *wmstate;
  3028   unsigned long wmstate_items, extent_items;
  3029   unsigned char *wmstate_data = NULL, *extent_data = NULL;
  3030   XWindowAttributes attrs;
  3031   Window child;
  3032   xm_drag_receiver_info xm_info;
  3033 #else
  3034   uint32_t *wmstate, *fextents;
  3035   uint8_t *xmdata;
  3036   xcb_get_window_attributes_cookie_t *window_attribute_cookies;
  3037   xcb_translate_coordinates_cookie_t *translate_coordinate_cookies;
  3038   xcb_get_property_cookie_t *get_property_cookies;
  3039   xcb_get_property_cookie_t *xm_property_cookies;
  3040   xcb_get_property_cookie_t *extent_property_cookies;
  3041   xcb_get_geometry_cookie_t *get_geometry_cookies;
  3042   xcb_get_window_attributes_reply_t attrs, *attrs_reply;
  3043   xcb_translate_coordinates_reply_t *coordinates_reply;
  3044   xcb_get_property_reply_t *property_reply;
  3045   xcb_get_property_reply_t *xm_property_reply;
  3046   xcb_get_property_reply_t *extent_property_reply;
  3047   xcb_get_geometry_reply_t *geometry_reply;
  3048   xcb_generic_error_t *error;
  3049 #endif
  3050 
  3051 #ifdef HAVE_XCB_SHAPE
  3052   xcb_shape_get_rectangles_cookie_t *bounding_rect_cookies;
  3053   xcb_shape_get_rectangles_reply_t *bounding_rect_reply;
  3054   xcb_rectangle_iterator_t bounding_rect_iterator;
  3055 #endif
  3056 
  3057 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3058   xcb_shape_get_rectangles_cookie_t *input_rect_cookies;
  3059   xcb_shape_get_rectangles_reply_t *input_rect_reply;
  3060   xcb_rectangle_iterator_t input_rect_iterator;
  3061 #endif
  3062 
  3063   struct x_client_list_window *tem;
  3064 #if defined HAVE_XSHAPE && !defined HAVE_XCB_SHAPE_INPUT_RECTS
  3065   int count, ordering;
  3066   XRectangle *rects;
  3067 #endif
  3068 
  3069   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
  3070                            dpyinfo->Xatom_net_client_list_stacking,
  3071                            0, LONG_MAX, False, XA_WINDOW, &type,
  3072                            &format, &nitems, &bytes_after, &data);
  3073 
  3074   if (rc != Success)
  3075     return 1;
  3076 
  3077   if (format != 32 || type != XA_WINDOW)
  3078     {
  3079       XFree (data);
  3080       return 1;
  3081     }
  3082 
  3083   toplevels = (Window *) data;
  3084 
  3085   for (i = 0, real_nitems = 0; i < nitems; ++i)
  3086     {
  3087       /* Some window managers with built in compositors end up putting
  3088          tooltips in the client list, which is silly.  */
  3089       if (!x_tooltip_window_to_frame (dpyinfo, toplevels[i], NULL))
  3090         toplevels[real_nitems++] = toplevels[i];
  3091     }
  3092 
  3093   nitems = real_nitems;
  3094 
  3095 #ifdef USE_XCB
  3096   USE_SAFE_ALLOCA;
  3097 
  3098   window_attribute_cookies
  3099     = SAFE_ALLOCA (sizeof *window_attribute_cookies * nitems);
  3100   translate_coordinate_cookies
  3101     = SAFE_ALLOCA (sizeof *translate_coordinate_cookies * nitems);
  3102   get_property_cookies
  3103     = SAFE_ALLOCA (sizeof *get_property_cookies * nitems);
  3104   xm_property_cookies
  3105     = SAFE_ALLOCA (sizeof *xm_property_cookies * nitems);
  3106   extent_property_cookies
  3107     = SAFE_ALLOCA (sizeof *extent_property_cookies * nitems);
  3108   get_geometry_cookies
  3109     = SAFE_ALLOCA (sizeof *get_geometry_cookies * nitems);
  3110 
  3111 #ifdef HAVE_XCB_SHAPE
  3112   bounding_rect_cookies
  3113     = SAFE_ALLOCA (sizeof *bounding_rect_cookies * nitems);
  3114 #endif
  3115 
  3116 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3117   input_rect_cookies
  3118     = SAFE_ALLOCA (sizeof *input_rect_cookies * nitems);
  3119 #endif
  3120 
  3121   for (i = 0; i < nitems; ++i)
  3122     {
  3123       window_attribute_cookies[i]
  3124         = xcb_get_window_attributes (dpyinfo->xcb_connection,
  3125                                      (xcb_window_t) toplevels[i]);
  3126       translate_coordinate_cookies[i]
  3127         = xcb_translate_coordinates (dpyinfo->xcb_connection,
  3128                                      (xcb_window_t) toplevels[i],
  3129                                      (xcb_window_t) dpyinfo->root_window,
  3130                                      0, 0);
  3131       get_property_cookies[i]
  3132         = xcb_get_property (dpyinfo->xcb_connection, 0, (xcb_window_t) toplevels[i],
  3133                             (xcb_atom_t) dpyinfo->Xatom_wm_state, 0,
  3134                             0, 2);
  3135       xm_property_cookies[i]
  3136         = xcb_get_property (dpyinfo->xcb_connection, 0, (xcb_window_t) toplevels[i],
  3137                             (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  3138                             (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  3139                             0, 4);
  3140       extent_property_cookies[i]
  3141         = xcb_get_property (dpyinfo->xcb_connection, 0,
  3142                             (xcb_window_t) toplevels[i],
  3143                             (xcb_atom_t) dpyinfo->Xatom_net_frame_extents,
  3144                             XA_CARDINAL, 0, 4);
  3145       get_geometry_cookies[i]
  3146         = xcb_get_geometry (dpyinfo->xcb_connection, (xcb_window_t) toplevels[i]);
  3147 
  3148 #ifdef HAVE_XCB_SHAPE
  3149       bounding_rect_cookies[i]
  3150         = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
  3151                                     (xcb_window_t) toplevels[i],
  3152                                     XCB_SHAPE_SK_BOUNDING);
  3153 #endif
  3154 
  3155 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3156       if (dpyinfo->xshape_major > 1
  3157           || (dpyinfo->xshape_major == 1
  3158               && dpyinfo->xshape_minor >= 1))
  3159         input_rect_cookies[i]
  3160           = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
  3161                                       (xcb_window_t) toplevels[i],
  3162                                       XCB_SHAPE_SK_INPUT);
  3163 #endif
  3164     }
  3165 #endif
  3166 
  3167   /* Actually right because _NET_CLIENT_LIST_STACKING has bottom-up
  3168      order.  */
  3169   for (i = 0; i < nitems; ++i)
  3170     {
  3171       frame_extents[0] = 0;
  3172       frame_extents[1] = 0;
  3173       frame_extents[2] = 0;
  3174       frame_extents[3] = 0;
  3175 
  3176 #ifndef USE_XCB
  3177       x_catch_errors (dpyinfo->display);
  3178       rc = (XGetWindowAttributes (dpyinfo->display,
  3179                                   toplevels[i], &attrs)
  3180             && !x_had_errors_p (dpyinfo->display));
  3181 
  3182       if (rc)
  3183         rc = (XTranslateCoordinates (dpyinfo->display, toplevels[i],
  3184                                      attrs.root, -attrs.border_width,
  3185                                      -attrs.border_width, &dest_x,
  3186                                      &dest_y, &child)
  3187               && !x_had_errors_p (dpyinfo->display));
  3188       if (rc)
  3189         rc = ((XGetWindowProperty (dpyinfo->display,
  3190                                    toplevels[i],
  3191                                    dpyinfo->Xatom_wm_state,
  3192                                    0, 2, False, AnyPropertyType,
  3193                                    &type, &format, &wmstate_items,
  3194                                    &bytes_after, &wmstate_data)
  3195                == Success)
  3196               && !x_had_errors_p (dpyinfo->display)
  3197               && wmstate_data && wmstate_items == 2 && format == 32);
  3198 
  3199       if (XGetWindowProperty (dpyinfo->display, toplevels[i],
  3200                               dpyinfo->Xatom_net_frame_extents,
  3201                               0, 4, False, XA_CARDINAL, &type,
  3202                               &format, &extent_items, &bytes_after,
  3203                               &extent_data) == Success
  3204           && !x_had_errors_p (dpyinfo->display)
  3205           && extent_data && extent_items >= 4 && format == 32)
  3206         {
  3207           frame_extents[0] = ((unsigned long *) extent_data)[0];
  3208           frame_extents[1] = ((unsigned long *) extent_data)[1];
  3209           frame_extents[2] = ((unsigned long *) extent_data)[2];
  3210           frame_extents[3] = ((unsigned long *) extent_data)[3];
  3211         }
  3212 
  3213       if (extent_data)
  3214         XFree (extent_data);
  3215 
  3216       x_uncatch_errors ();
  3217 #else
  3218       rc = true;
  3219 
  3220       attrs_reply
  3221         = xcb_get_window_attributes_reply (dpyinfo->xcb_connection,
  3222                                            window_attribute_cookies[i],
  3223                                            &error);
  3224 
  3225       if (!attrs_reply)
  3226         {
  3227           rc = false;
  3228           free (error);
  3229         }
  3230 
  3231       coordinates_reply
  3232         = xcb_translate_coordinates_reply (dpyinfo->xcb_connection,
  3233                                            translate_coordinate_cookies[i],
  3234                                            &error);
  3235 
  3236       if (!coordinates_reply)
  3237         {
  3238           rc = false;
  3239           free (error);
  3240         }
  3241 
  3242       property_reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3243                                                get_property_cookies[i],
  3244                                                &error);
  3245 
  3246       if (!property_reply)
  3247         {
  3248           rc = false;
  3249           free (error);
  3250         }
  3251 
  3252       /* These requests don't set rc on failure because they aren't
  3253          required.  */
  3254 
  3255       xm_property_reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3256                                                   xm_property_cookies[i],
  3257                                                   &error);
  3258 
  3259       if (!xm_property_reply)
  3260         free (error);
  3261 
  3262       extent_property_reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3263                                                       extent_property_cookies[i],
  3264                                                       &error);
  3265 
  3266       if (!extent_property_reply)
  3267         free (error);
  3268       else
  3269         {
  3270           if (xcb_get_property_value_length (extent_property_reply) == 16
  3271               && extent_property_reply->format == 32
  3272               && extent_property_reply->type == XA_CARDINAL)
  3273             {
  3274               fextents = xcb_get_property_value (extent_property_reply);
  3275               frame_extents[0] = fextents[0];
  3276               frame_extents[1] = fextents[1];
  3277               frame_extents[2] = fextents[2];
  3278               frame_extents[3] = fextents[3];
  3279             }
  3280 
  3281           free (extent_property_reply);
  3282         }
  3283 
  3284       if (property_reply
  3285           && (xcb_get_property_value_length (property_reply) != 8
  3286               || property_reply->format != 32))
  3287         rc = false;
  3288 
  3289       geometry_reply = xcb_get_geometry_reply (dpyinfo->xcb_connection,
  3290                                                get_geometry_cookies[i],
  3291                                                &error);
  3292 
  3293       if (!geometry_reply)
  3294         {
  3295           rc = false;
  3296           free (error);
  3297         }
  3298 #endif
  3299 
  3300       if (rc)
  3301         {
  3302 #ifdef USE_XCB
  3303           wmstate = (uint32_t *) xcb_get_property_value (property_reply);
  3304           attrs = *attrs_reply;
  3305 #else
  3306           wmstate = (unsigned long *) wmstate_data;
  3307 #endif
  3308 
  3309           tem = xmalloc (sizeof *tem);
  3310           tem->window = toplevels[i];
  3311           tem->dpy = dpyinfo->display;
  3312           tem->frame_extents_left = frame_extents[0];
  3313           tem->frame_extents_right = frame_extents[1];
  3314           tem->frame_extents_top = frame_extents[2];
  3315           tem->frame_extents_bottom = frame_extents[3];
  3316 
  3317 #ifndef USE_XCB
  3318           tem->x = dest_x;
  3319           tem->y = dest_y;
  3320           tem->width = attrs.width + attrs.border_width;
  3321           tem->height = attrs.height + attrs.border_width;
  3322           tem->mapped_p = (attrs.map_state != IsUnmapped);
  3323 #else
  3324           tem->x = (coordinates_reply->dst_x
  3325                     - geometry_reply->border_width);
  3326           tem->y = (coordinates_reply->dst_y
  3327                     - geometry_reply->border_width);
  3328           tem->width = (geometry_reply->width
  3329                         + geometry_reply->border_width);
  3330           tem->height = (geometry_reply->height
  3331                          + geometry_reply->border_width);
  3332           tem->mapped_p = (attrs.map_state != XCB_MAP_STATE_UNMAPPED);
  3333 #endif
  3334           tem->next = x_dnd_toplevels;
  3335           tem->previous_event_mask = attrs.your_event_mask;
  3336           tem->wm_state = wmstate[0];
  3337           tem->xm_protocol_style = XM_DRAG_STYLE_NONE;
  3338 
  3339 #ifndef USE_XCB
  3340           if (!xm_read_drag_receiver_info (dpyinfo, toplevels[i], &xm_info))
  3341             tem->xm_protocol_style = xm_info.protocol_style;
  3342 #else
  3343           if (xm_property_reply
  3344               && xm_property_reply->format == 8
  3345               && xm_property_reply->type == dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO
  3346               && xcb_get_property_value_length (xm_property_reply) >= 4)
  3347             {
  3348               xmdata = xcb_get_property_value (xm_property_reply);
  3349 
  3350               if (xmdata[1] <= XM_DRAG_PROTOCOL_VERSION)
  3351                 tem->xm_protocol_style = xmdata[2];
  3352             }
  3353 #endif
  3354 
  3355 #ifdef HAVE_XSHAPE
  3356 #ifndef USE_XCB
  3357           tem->border_width = attrs.border_width;
  3358 #else
  3359           tem->border_width = geometry_reply->border_width;
  3360 #endif
  3361           tem->n_bounding_rects = -1;
  3362           tem->n_input_rects = -1;
  3363 
  3364           if (dpyinfo->xshape_supported_p)
  3365             {
  3366               x_ignore_errors_for_next_request (dpyinfo, 0);
  3367               XShapeSelectInput (dpyinfo->display,
  3368                                  toplevels[i],
  3369                                  ShapeNotifyMask);
  3370               x_stop_ignoring_errors (dpyinfo);
  3371 
  3372 #ifndef HAVE_XCB_SHAPE
  3373               x_catch_errors (dpyinfo->display);
  3374               rects = XShapeGetRectangles (dpyinfo->display,
  3375                                            toplevels[i],
  3376                                            ShapeBounding,
  3377                                            &count, &ordering);
  3378               rc = x_had_errors_p (dpyinfo->display);
  3379               x_uncatch_errors_after_check ();
  3380 
  3381               /* Does XShapeGetRectangles allocate anything upon an
  3382                  error?  */
  3383               if (!rc)
  3384                 {
  3385                   tem->n_bounding_rects = count;
  3386                   tem->bounding_rects
  3387                     = xmalloc (sizeof *tem->bounding_rects * count);
  3388                   memcpy (tem->bounding_rects, rects,
  3389                           sizeof *tem->bounding_rects * count);
  3390 
  3391                   XFree (rects);
  3392                 }
  3393 #else
  3394               bounding_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
  3395                                                                     bounding_rect_cookies[i],
  3396                                                                     &error);
  3397 
  3398               if (bounding_rect_reply)
  3399                 {
  3400                   bounding_rect_iterator
  3401                     = xcb_shape_get_rectangles_rectangles_iterator (bounding_rect_reply);
  3402                   tem->n_bounding_rects = bounding_rect_iterator.rem + 1;
  3403                   tem->bounding_rects = xmalloc (tem->n_bounding_rects
  3404                                                  * sizeof *tem->bounding_rects);
  3405                   tem->n_bounding_rects = 0;
  3406 
  3407                   for (; bounding_rect_iterator.rem; xcb_rectangle_next (&bounding_rect_iterator))
  3408                     {
  3409                       tem->bounding_rects[tem->n_bounding_rects].x
  3410                         = bounding_rect_iterator.data->x;
  3411                       tem->bounding_rects[tem->n_bounding_rects].y
  3412                         = bounding_rect_iterator.data->y;
  3413                       tem->bounding_rects[tem->n_bounding_rects].width
  3414                         = bounding_rect_iterator.data->width;
  3415                       tem->bounding_rects[tem->n_bounding_rects].height
  3416                         = bounding_rect_iterator.data->height;
  3417 
  3418                       tem->n_bounding_rects++;
  3419                     }
  3420 
  3421                   free (bounding_rect_reply);
  3422                 }
  3423               else
  3424                 free (error);
  3425 #endif
  3426 
  3427 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3428               if (dpyinfo->xshape_major > 1
  3429                   || (dpyinfo->xshape_major == 1
  3430                       && dpyinfo->xshape_minor >= 1))
  3431                 {
  3432                   input_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
  3433                                                                      input_rect_cookies[i],
  3434                                                                      &error);
  3435 
  3436                   if (input_rect_reply)
  3437                     {
  3438                       input_rect_iterator
  3439                         = xcb_shape_get_rectangles_rectangles_iterator (input_rect_reply);
  3440                       tem->n_input_rects = input_rect_iterator.rem + 1;
  3441                       tem->input_rects = xmalloc (tem->n_input_rects
  3442                                                   * sizeof *tem->input_rects);
  3443                       tem->n_input_rects = 0;
  3444 
  3445                       for (; input_rect_iterator.rem; xcb_rectangle_next (&input_rect_iterator))
  3446                         {
  3447                           tem->input_rects[tem->n_input_rects].x
  3448                             = input_rect_iterator.data->x;
  3449                           tem->input_rects[tem->n_input_rects].y
  3450                             = input_rect_iterator.data->y;
  3451                           tem->input_rects[tem->n_input_rects].width
  3452                             = input_rect_iterator.data->width;
  3453                           tem->input_rects[tem->n_input_rects].height
  3454                             = input_rect_iterator.data->height;
  3455 
  3456                           tem->n_input_rects++;
  3457                         }
  3458 
  3459                       free (input_rect_reply);
  3460                     }
  3461                   else
  3462                     free (error);
  3463                 }
  3464 #else
  3465 #ifdef ShapeInput
  3466               if (dpyinfo->xshape_major > 1
  3467                   || (dpyinfo->xshape_major == 1
  3468                       && dpyinfo->xshape_minor >= 1))
  3469                 {
  3470                   x_catch_errors (dpyinfo->display);
  3471                   rects = XShapeGetRectangles (dpyinfo->display,
  3472                                                toplevels[i], ShapeInput,
  3473                                                &count, &ordering);
  3474                   rc = x_had_errors_p (dpyinfo->display);
  3475                   x_uncatch_errors_after_check ();
  3476 
  3477                   /* Does XShapeGetRectangles allocate anything upon
  3478                      an error?  */
  3479                   if (!rc)
  3480                     {
  3481                       tem->n_input_rects = count;
  3482                       tem->input_rects
  3483                         = xmalloc (sizeof *tem->input_rects * count);
  3484                       memcpy (tem->input_rects, rects,
  3485                               sizeof *tem->input_rects * count);
  3486 
  3487                       XFree (rects);
  3488                     }
  3489                 }
  3490 #endif
  3491 #endif
  3492             }
  3493 
  3494           /* Handle the common case where the input shape equals the
  3495              bounding shape.  */
  3496 
  3497           if (tem->n_input_rects != -1
  3498               && tem->n_bounding_rects == tem->n_input_rects
  3499               && !memcmp (tem->bounding_rects, tem->input_rects,
  3500                           tem->n_input_rects * sizeof *tem->input_rects))
  3501             {
  3502               xfree (tem->input_rects);
  3503               tem->n_input_rects = -1;
  3504             }
  3505 
  3506           /* And the common case where there is no input rect and the
  3507              bounding rect equals the window dimensions.  */
  3508 
  3509           if (tem->n_input_rects == -1
  3510               && tem->n_bounding_rects == 1
  3511 #ifdef USE_XCB
  3512               && tem->bounding_rects[0].width == (geometry_reply->width
  3513                                                   + geometry_reply->border_width)
  3514               && tem->bounding_rects[0].height == (geometry_reply->height
  3515                                                    + geometry_reply->border_width)
  3516               && tem->bounding_rects[0].x == -geometry_reply->border_width
  3517               && tem->bounding_rects[0].y == -geometry_reply->border_width
  3518 #else
  3519               && tem->bounding_rects[0].width == attrs.width + attrs.border_width
  3520               && tem->bounding_rects[0].height == attrs.height + attrs.border_width
  3521               && tem->bounding_rects[0].x == -attrs.border_width
  3522               && tem->bounding_rects[0].y == -attrs.border_width
  3523 #endif
  3524               )
  3525             {
  3526               xfree (tem->bounding_rects);
  3527               tem->n_bounding_rects = -1;
  3528             }
  3529 #endif
  3530 
  3531           x_ignore_errors_for_next_request (dpyinfo, 0);
  3532           XSelectInput (dpyinfo->display, toplevels[i],
  3533                         (attrs.your_event_mask
  3534                          | StructureNotifyMask
  3535                          | PropertyChangeMask));
  3536           x_stop_ignoring_errors (dpyinfo);
  3537 
  3538           x_dnd_toplevels = tem;
  3539         }
  3540       else
  3541         {
  3542 #ifdef HAVE_XCB_SHAPE
  3543           if (dpyinfo->xshape_supported_p)
  3544             {
  3545               bounding_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
  3546                                                                     bounding_rect_cookies[i],
  3547                                                                     &error);
  3548 
  3549               if (bounding_rect_reply)
  3550                 free (bounding_rect_reply);
  3551               else
  3552                 free (error);
  3553             }
  3554 #endif
  3555 
  3556 #ifdef HAVE_XCB_SHAPE_INPUT_RECTS
  3557           if (dpyinfo->xshape_supported_p
  3558               && (dpyinfo->xshape_major > 1
  3559                   || (dpyinfo->xshape_major == 1
  3560                       && dpyinfo->xshape_minor >= 1)))
  3561             {
  3562               input_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
  3563                                                                  input_rect_cookies[i],
  3564                                                                  &error);
  3565 
  3566               if (input_rect_reply)
  3567                 free (input_rect_reply);
  3568               else
  3569                 free (error);
  3570             }
  3571 #endif
  3572         }
  3573 
  3574 #ifdef USE_XCB
  3575       if (attrs_reply)
  3576         free (attrs_reply);
  3577 
  3578       if (coordinates_reply)
  3579         free (coordinates_reply);
  3580 
  3581       if (property_reply)
  3582         free (property_reply);
  3583 
  3584       if (xm_property_reply)
  3585         free (xm_property_reply);
  3586 
  3587       if (geometry_reply)
  3588         free (geometry_reply);
  3589 #endif
  3590 
  3591 #ifndef USE_XCB
  3592       if (wmstate_data)
  3593         {
  3594           XFree (wmstate_data);
  3595           wmstate_data = NULL;
  3596         }
  3597 #endif
  3598     }
  3599 
  3600 #ifdef USE_XCB
  3601   SAFE_FREE ();
  3602 #endif
  3603 
  3604   if (data)
  3605     XFree (data);
  3606 
  3607   return 0;
  3608 }
  3609 
  3610 static _Noreturn int
  3611 x_dnd_io_error_handler (Display *display)
  3612 {
  3613 #ifdef USE_GTK
  3614   emacs_abort ();
  3615 #else
  3616   siglongjmp (x_dnd_disconnect_handler, 1);
  3617 #endif
  3618 }
  3619 
  3620 #define X_DND_SUPPORTED_VERSION 5
  3621 
  3622 static int x_dnd_get_window_proto (struct x_display_info *, Window);
  3623 static Window x_dnd_get_window_proxy (struct x_display_info *, Window);
  3624 static void x_dnd_update_state (struct x_display_info *, Time);
  3625 
  3626 #ifdef USE_XCB
  3627 static void
  3628 x_dnd_get_proxy_proto (struct x_display_info *dpyinfo, Window wdesc,
  3629                        Window *proxy_out, int *proto_out)
  3630 {
  3631   xcb_get_property_cookie_t xdnd_proto_cookie;
  3632   xcb_get_property_cookie_t xdnd_proxy_cookie;
  3633   xcb_get_property_reply_t *reply;
  3634   xcb_generic_error_t *error;
  3635 
  3636   if (proxy_out)
  3637     *proxy_out = None;
  3638 
  3639   if (proto_out)
  3640     *proto_out = -1;
  3641 
  3642   if (proxy_out)
  3643     xdnd_proxy_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3644                                           (xcb_window_t) wdesc,
  3645                                           (xcb_atom_t) dpyinfo->Xatom_XdndProxy,
  3646                                           XA_WINDOW, 0, 1);
  3647 
  3648   if (proto_out)
  3649     xdnd_proto_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3650                                           (xcb_window_t) wdesc,
  3651                                           (xcb_atom_t) dpyinfo->Xatom_XdndAware,
  3652                                           XA_ATOM, 0, 1);
  3653 
  3654   if (proxy_out)
  3655     {
  3656       reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3657                                       xdnd_proxy_cookie, &error);
  3658 
  3659       if (!reply)
  3660         free (error);
  3661       else
  3662         {
  3663           if (reply->format == 32
  3664               && reply->type == XA_WINDOW
  3665               && (xcb_get_property_value_length (reply) >= 4))
  3666             *proxy_out = *(xcb_window_t *) xcb_get_property_value (reply);
  3667 
  3668           free (reply);
  3669         }
  3670     }
  3671 
  3672   if (proto_out)
  3673     {
  3674       reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3675                                       xdnd_proto_cookie, &error);
  3676 
  3677       if (!reply)
  3678         free (error);
  3679       else
  3680         {
  3681           if (reply->format == 32
  3682               && reply->type == XA_ATOM
  3683               && (xcb_get_property_value_length (reply) >= 4))
  3684             *proto_out = (int) *(xcb_atom_t *) xcb_get_property_value (reply);
  3685 
  3686           free (reply);
  3687         }
  3688     }
  3689 }
  3690 #endif
  3691 
  3692 #ifdef HAVE_XSHAPE
  3693 static bool
  3694 x_dnd_get_target_window_2 (XRectangle *rects, int nrects,
  3695                            int x, int y)
  3696 {
  3697   int i;
  3698   XRectangle *tem;
  3699 
  3700   for (i = 0; i < nrects; ++i)
  3701     {
  3702       tem = &rects[i];
  3703 
  3704       if (x >= tem->x && y >= tem->y
  3705           && x < tem->x + tem->width
  3706           && y < tem->y + tem->height)
  3707         return true;
  3708     }
  3709 
  3710   return false;
  3711 }
  3712 #endif
  3713 
  3714 static Window
  3715 x_dnd_get_target_window_1 (struct x_display_info *dpyinfo,
  3716                            int root_x, int root_y, int *motif_out,
  3717                            bool *extents_p)
  3718 {
  3719   struct x_client_list_window *tem, *chosen = NULL;
  3720 
  3721   /* Loop through x_dnd_toplevels until we find the toplevel where
  3722      root_x and root_y are.  */
  3723 
  3724   *motif_out = XM_DRAG_STYLE_NONE;
  3725 
  3726   for (tem = x_dnd_toplevels; tem; tem = tem->next)
  3727     {
  3728       if (!tem->mapped_p || tem->wm_state != NormalState)
  3729         continue;
  3730 
  3731       /* Test if the coordinates are inside the window's frame
  3732          extents, and return None in that case.  */
  3733 
  3734       *extents_p = true;
  3735       if (root_x > tem->x - tem->frame_extents_left
  3736           && root_x < tem->x
  3737           && root_y > tem->y - tem->frame_extents_top
  3738           && root_y < (tem->y + tem->height - 1
  3739                        + tem->frame_extents_bottom))
  3740         return None;
  3741 
  3742       if (root_x > tem->x + tem->width
  3743           && root_x < (tem->x + tem->width - 1
  3744                        + tem->frame_extents_right)
  3745           && root_y > tem->y - tem->frame_extents_top
  3746           && root_y < (tem->y + tem->height - 1
  3747                        + tem->frame_extents_bottom))
  3748         return None;
  3749 
  3750       if (root_y > tem->y - tem->frame_extents_top
  3751           && root_y < tem->y
  3752           && root_x > tem->x - tem->frame_extents_left
  3753           && root_x < (tem->x + tem->width - 1
  3754                        + tem->frame_extents_right))
  3755         return None;
  3756 
  3757       if (root_y > tem->y + tem->height
  3758           && root_y < (tem->y + tem->height - 1
  3759                        + tem->frame_extents_bottom)
  3760           && root_x >= tem->x - tem->frame_extents_left
  3761           && root_x < (tem->x + tem->width - 1
  3762                        + tem->frame_extents_right))
  3763         return None;
  3764       *extents_p = false;
  3765 
  3766       if (root_x >= tem->x && root_y >= tem->y
  3767           && root_x < tem->x + tem->width
  3768           && root_y < tem->y + tem->height)
  3769         {
  3770 #ifdef HAVE_XSHAPE
  3771           if (tem->n_bounding_rects == -1)
  3772 #endif
  3773             {
  3774               chosen = tem;
  3775               break;
  3776             }
  3777 
  3778 #ifdef HAVE_XSHAPE
  3779           if (x_dnd_get_target_window_2 (tem->bounding_rects,
  3780                                          tem->n_bounding_rects,
  3781                                          tem->border_width + root_x - tem->x,
  3782                                          tem->border_width + root_y - tem->y))
  3783             {
  3784               if (tem->n_input_rects == -1
  3785                   || x_dnd_get_target_window_2 (tem->input_rects,
  3786                                                 tem->n_input_rects,
  3787                                                 tem->border_width + root_x - tem->x,
  3788                                                 tem->border_width + root_y - tem->y))
  3789                 {
  3790                   chosen = tem;
  3791                   break;
  3792                 }
  3793             }
  3794 #endif
  3795         }
  3796     }
  3797 
  3798   if (chosen)
  3799     {
  3800       *motif_out = (x_dnd_disable_motif_protocol
  3801                     ? XM_DRAG_STYLE_NONE
  3802                     : chosen->xm_protocol_style);
  3803       return chosen->window;
  3804     }
  3805   else
  3806     *motif_out = XM_DRAG_STYLE_NONE;
  3807 
  3808   return None;
  3809 }
  3810 
  3811 static int
  3812 x_dnd_get_wm_state_and_proto (struct x_display_info *dpyinfo,
  3813                               Window window, int *wmstate_out,
  3814                               int *proto_out, int *motif_out,
  3815                               Window *proxy_out)
  3816 {
  3817 #ifndef USE_XCB
  3818   Atom type;
  3819   int format;
  3820   unsigned long nitems, bytes_after;
  3821   unsigned char *data = NULL;
  3822   xm_drag_receiver_info xm_info;
  3823 #else
  3824   xcb_get_property_cookie_t wmstate_cookie;
  3825   xcb_get_property_cookie_t xdnd_proto_cookie;
  3826   xcb_get_property_cookie_t xdnd_proxy_cookie;
  3827   xcb_get_property_cookie_t xm_style_cookie;
  3828   xcb_get_property_reply_t *reply;
  3829   xcb_generic_error_t *error;
  3830   uint8_t *xmdata;
  3831 #endif
  3832   int rc;
  3833 
  3834 #ifndef USE_XCB
  3835   x_catch_errors (dpyinfo->display);
  3836   rc = ((XGetWindowProperty (dpyinfo->display, window,
  3837                              dpyinfo->Xatom_wm_state,
  3838                              0, 2, False, AnyPropertyType,
  3839                              &type, &format, &nitems,
  3840                              &bytes_after, &data)
  3841          == Success)
  3842         && !x_had_errors_p (dpyinfo->display)
  3843         && data && nitems == 2 && format == 32);
  3844   x_uncatch_errors ();
  3845 
  3846   if (rc)
  3847     *wmstate_out = *(unsigned long *) data;
  3848 
  3849   *proto_out = x_dnd_get_window_proto (dpyinfo, window);
  3850 
  3851   if (!xm_read_drag_receiver_info (dpyinfo, window, &xm_info))
  3852     *motif_out = xm_info.protocol_style;
  3853   else
  3854     *motif_out = XM_DRAG_STYLE_NONE;
  3855 
  3856   *proxy_out = x_dnd_get_window_proxy (dpyinfo, window);
  3857 
  3858   if (data)
  3859     XFree (data);
  3860 #else
  3861   rc = true;
  3862 
  3863   wmstate_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3864                                      (xcb_window_t) window,
  3865                                      (xcb_atom_t) dpyinfo->Xatom_wm_state,
  3866                                      0, 0, 2);
  3867   xdnd_proto_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3868                                         (xcb_window_t) window,
  3869                                         (xcb_atom_t) dpyinfo->Xatom_XdndAware,
  3870                                         XA_ATOM, 0, 1);
  3871   xdnd_proxy_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3872                                         (xcb_window_t) window,
  3873                                         (xcb_atom_t) dpyinfo->Xatom_XdndProxy,
  3874                                         XA_WINDOW, 0, 1);
  3875   xm_style_cookie = xcb_get_property (dpyinfo->xcb_connection, 0,
  3876                                       (xcb_window_t) window,
  3877                                       (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  3878                                       (xcb_atom_t) dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO,
  3879                                       0, 4);
  3880 
  3881   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3882                                   wmstate_cookie, &error);
  3883 
  3884   if (!reply)
  3885     free (error), rc = false;
  3886   else
  3887     {
  3888       if (reply->format != 32
  3889           || xcb_get_property_value_length (reply) != 8)
  3890         rc = false;
  3891       else
  3892         *wmstate_out = *(uint32_t *) xcb_get_property_value (reply);
  3893 
  3894       free (reply);
  3895     }
  3896 
  3897   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3898                                   xdnd_proto_cookie, &error);
  3899 
  3900   *proto_out = -1;
  3901   if (!reply)
  3902     free (error);
  3903   else
  3904     {
  3905       if (reply->format == 32
  3906           && xcb_get_property_value_length (reply) >= 4)
  3907         *proto_out = *(uint32_t *) xcb_get_property_value (reply);
  3908 
  3909       free (reply);
  3910     }
  3911 
  3912   *proxy_out = None;
  3913   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3914                                   xdnd_proxy_cookie, &error);
  3915 
  3916   if (!reply)
  3917     free (error);
  3918   else
  3919     {
  3920       if (reply->format == 32
  3921           && reply->type == XA_WINDOW
  3922           && (xcb_get_property_value_length (reply) >= 4))
  3923         *proxy_out = *(xcb_window_t *) xcb_get_property_value (reply);
  3924 
  3925       free (reply);
  3926     }
  3927 
  3928   *motif_out = XM_DRAG_STYLE_NONE;
  3929 
  3930   reply = xcb_get_property_reply (dpyinfo->xcb_connection,
  3931                                   xm_style_cookie, &error);
  3932 
  3933   if (!reply)
  3934     free (error);
  3935  else
  3936    {
  3937      if (reply->format == 8
  3938          && reply->type == dpyinfo->Xatom_MOTIF_DRAG_RECEIVER_INFO
  3939          && xcb_get_property_value_length (reply) >= 4)
  3940        {
  3941          xmdata = xcb_get_property_value (reply);
  3942          *motif_out = xmdata[2];
  3943        }
  3944 
  3945      free (reply);
  3946    }
  3947 #endif
  3948 
  3949   return rc;
  3950 }
  3951 
  3952 /* From the XDND protocol specification:
  3953 
  3954    Dropping on windows that do not support XDND
  3955 
  3956    Since middle clicking is the universal shortcut for pasting
  3957    in X, one can drop data into a window that does not support
  3958    XDND by:
  3959 
  3960    1. After the mouse has been released to trigger the drop,
  3961    obtain ownership of XA_PRIMARY.
  3962 
  3963    2. Send a ButtonPress event and then a ButtonRelease event to
  3964    the deepest subwindow containing the mouse to simulate a
  3965    middle click.  The times for these events should be the time
  3966    of the actual button release +1 and +2, respectively.  These
  3967    values will not be used by anybody else, so one can
  3968    unambiguously recognize the resulting `XConvertSelection'
  3969    request.
  3970 
  3971    3. If a request for XA_PRIMARY arrives bearing the timestamp
  3972    of either the ButtonPress or the ButtonRelease event, treat
  3973    it as a request for XdndSelection.  Note that you must use
  3974    the X data types instead of the MIME types in this case.
  3975    (e.g. XA_STRING instead of text/plain).  */
  3976 void
  3977 x_dnd_do_unsupported_drop (struct x_display_info *dpyinfo,
  3978                            Lisp_Object frame, Lisp_Object value,
  3979                            Lisp_Object targets, Window target_window,
  3980                            int root_x, int root_y, Time before)
  3981 {
  3982   XEvent event;
  3983   int dest_x, dest_y;
  3984   Window child_return, child, owner;
  3985   Lisp_Object current_value;
  3986   struct frame *f;
  3987 
  3988   f = decode_window_system_frame (frame);
  3989 
  3990   if (NILP (value))
  3991     return;
  3992 
  3993   if (!x_dnd_use_unsupported_drop)
  3994     return;
  3995 
  3996   event.xbutton.serial = 0;
  3997   event.xbutton.send_event = True;
  3998   event.xbutton.display = dpyinfo->display;
  3999   event.xbutton.root = dpyinfo->root_window;
  4000   event.xbutton.x_root = root_x;
  4001   event.xbutton.y_root = root_y;
  4002 
  4003   x_catch_errors (dpyinfo->display);
  4004 
  4005   child = dpyinfo->root_window;
  4006   dest_x = root_x;
  4007   dest_y = root_y;
  4008 
  4009   while (XTranslateCoordinates (dpyinfo->display, dpyinfo->root_window,
  4010                                 child, root_x, root_y, &dest_x, &dest_y,
  4011                                 &child_return)
  4012          && child_return != None)
  4013     child = child_return;
  4014 
  4015   x_uncatch_errors ();
  4016 
  4017   if (!CONSP (value))
  4018     return;
  4019 
  4020   current_value = assq_no_quit (QPRIMARY,
  4021                                 dpyinfo->terminal->Vselection_alist);
  4022 
  4023   if (!NILP (current_value))
  4024     current_value = XCAR (XCDR (current_value));
  4025 
  4026   x_own_selection (QPRIMARY, current_value, frame,
  4027                    XCAR (XCDR (value)), before);
  4028 
  4029   owner = XGetSelectionOwner (dpyinfo->display, XA_PRIMARY);
  4030 
  4031   /* If we didn't successfully obtain selection ownership, refrain
  4032      from generating events that will insert something else.  */
  4033 
  4034   if (owner != FRAME_X_WINDOW (f))
  4035     return;
  4036 
  4037   /* mouse-drag-and-drop-region will immediately deactivate the mark
  4038      after this is set.  Make sure the primary selection is not
  4039      clobbered in that case by setting `deactivate-mark' to
  4040      Qdont_save.  */
  4041   Vdeactivate_mark = Qdont_save;
  4042 
  4043   event.xbutton.window = child;
  4044   event.xbutton.subwindow = None;
  4045   event.xbutton.x = dest_x;
  4046   event.xbutton.y = dest_y;
  4047   event.xbutton.state = 0;
  4048   event.xbutton.button = 2;
  4049   event.xbutton.same_screen = True;
  4050 
  4051   dpyinfo->pending_dnd_time = before;
  4052 
  4053   event.xbutton.type = ButtonPress;
  4054   event.xbutton.time = before + 1;
  4055 
  4056   x_ignore_errors_for_next_request (dpyinfo, 0);
  4057   XSendEvent (dpyinfo->display, child,
  4058               True, ButtonPressMask, &event);
  4059 
  4060   event.xbutton.type = ButtonRelease;
  4061   event.xbutton.time = before + 2;
  4062 
  4063   XSendEvent (dpyinfo->display, child,
  4064               True, ButtonReleaseMask, &event);
  4065   x_stop_ignoring_errors (dpyinfo);
  4066 
  4067   x_dnd_action_symbol = QXdndActionPrivate;
  4068 
  4069   return;
  4070 }
  4071 
  4072 static void
  4073 x_dnd_send_unsupported_drop (struct x_display_info *dpyinfo, Window target_window,
  4074                              int root_x, int root_y, Time before)
  4075 {
  4076   Lisp_Object targets, arg;
  4077   int i;
  4078   char **atom_names, *name;
  4079 
  4080   targets = Qnil;
  4081   atom_names = alloca (sizeof *atom_names * x_dnd_n_targets);
  4082 
  4083   if (!XGetAtomNames (dpyinfo->display, x_dnd_targets,
  4084                       x_dnd_n_targets, atom_names))
  4085       return;
  4086 
  4087   for (i = x_dnd_n_targets; i > 0; --i)
  4088     {
  4089       targets = Fcons (build_string (atom_names[i - 1]),
  4090                        targets);
  4091       XFree (atom_names[i - 1]);
  4092     }
  4093 
  4094   name = x_get_atom_name (dpyinfo, x_dnd_wanted_action,
  4095                           NULL);
  4096 
  4097   if (name)
  4098     {
  4099       arg = intern (name);
  4100       xfree (name);
  4101     }
  4102   else
  4103     arg = Qnil;
  4104 
  4105   x_dnd_run_unsupported_drop_function = true;
  4106   x_dnd_unsupported_drop_time = before;
  4107   x_dnd_unsupported_drop_window = target_window;
  4108   x_dnd_unsupported_drop_data
  4109     = listn (5, assq_no_quit (QXdndSelection,
  4110                               dpyinfo->terminal->Vselection_alist),
  4111              targets, arg, make_fixnum (root_x),
  4112              make_fixnum (root_y));
  4113 
  4114   x_dnd_waiting_for_finish = true;
  4115   x_dnd_finish_display = dpyinfo->display;
  4116 }
  4117 
  4118 static Window
  4119 x_dnd_fill_empty_target (int *proto_out, int *motif_out,
  4120                          Window *toplevel_out, bool *was_frame)
  4121 {
  4122   *proto_out = -1;
  4123   *motif_out = XM_DRAG_STYLE_NONE;
  4124   *toplevel_out = None;
  4125   *was_frame = false;
  4126 
  4127   return None;
  4128 }
  4129 
  4130 static Window
  4131 x_dnd_get_target_window (struct x_display_info *dpyinfo,
  4132                          int root_x, int root_y, int *proto_out,
  4133                          int *motif_out, Window *toplevel_out,
  4134                          bool *was_frame)
  4135 {
  4136   Window child_return, child, proxy;
  4137   int dest_x_return, dest_y_return, rc, proto, motif;
  4138   int parent_x, parent_y;
  4139   bool extents_p;
  4140 #if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2)
  4141   Window overlay_window;
  4142   XWindowAttributes attrs;
  4143 #endif
  4144   int wmstate;
  4145   struct frame *tooltip, *f;
  4146   bool unrelated;
  4147 
  4148   child_return = dpyinfo->root_window;
  4149   dest_x_return = root_x;
  4150   dest_y_return = root_y;
  4151 
  4152   proto = -1;
  4153   *motif_out = XM_DRAG_STYLE_NONE;
  4154   *toplevel_out = None;
  4155   *was_frame = false;
  4156 
  4157   if (x_dnd_use_toplevels)
  4158     {
  4159       extents_p = false;
  4160       child = x_dnd_get_target_window_1 (dpyinfo, root_x,
  4161                                          root_y, motif_out,
  4162                                          &extents_p);
  4163 
  4164       if (!x_dnd_allow_current_frame
  4165           && FRAME_X_WINDOW (x_dnd_frame) == child)
  4166         *motif_out = XM_DRAG_STYLE_NONE;
  4167 
  4168       f = x_top_window_to_frame (dpyinfo, child);
  4169 
  4170       *toplevel_out = child;
  4171 
  4172       if (child != None)
  4173         {
  4174           if (f)
  4175             {
  4176               *was_frame = true;
  4177               *proto_out = -1;
  4178               *motif_out = XM_DRAG_STYLE_NONE;
  4179 
  4180               return child;
  4181             }
  4182 
  4183 #ifndef USE_XCB
  4184           proxy = x_dnd_get_window_proxy (dpyinfo, child);
  4185 #else
  4186           x_dnd_get_proxy_proto (dpyinfo, child, &proxy, proto_out);
  4187 #endif
  4188 
  4189           if (proxy != None)
  4190             {
  4191               proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4192 
  4193               if (proto != -1)
  4194                 {
  4195                   *proto_out = proto;
  4196                   return proxy;
  4197                 }
  4198             }
  4199 
  4200 #ifndef USE_XCB
  4201           *proto_out = x_dnd_get_window_proto (dpyinfo, child);
  4202 #endif
  4203           return child;
  4204         }
  4205 
  4206       if (extents_p)
  4207         {
  4208           *proto_out = -1;
  4209           *motif_out = XM_DRAG_STYLE_NONE;
  4210           *toplevel_out = None;
  4211 
  4212           return None;
  4213         }
  4214 
  4215       /* Then look at the composite overlay window.  */
  4216 #if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2)
  4217       if (dpyinfo->composite_supported_p
  4218           && (dpyinfo->composite_major > 0
  4219               || dpyinfo->composite_minor > 2))
  4220         {
  4221           if (XGetSelectionOwner (dpyinfo->display,
  4222                                   dpyinfo->Xatom_NET_WM_CM_Sn) != None)
  4223             {
  4224               x_catch_errors (dpyinfo->display);
  4225               XGrabServer (dpyinfo->display);
  4226               overlay_window = XCompositeGetOverlayWindow (dpyinfo->display,
  4227                                                            dpyinfo->root_window);
  4228               XCompositeReleaseOverlayWindow (dpyinfo->display,
  4229                                               dpyinfo->root_window);
  4230               XUngrabServer (dpyinfo->display);
  4231 
  4232               if (!x_had_errors_p (dpyinfo->display))
  4233                 {
  4234                   XGetWindowAttributes (dpyinfo->display, overlay_window, &attrs);
  4235 
  4236                   if (attrs.map_state == IsViewable)
  4237                     {
  4238                       proxy = x_dnd_get_window_proxy (dpyinfo, overlay_window);
  4239 
  4240                       if (proxy != None)
  4241                         {
  4242                           proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4243 
  4244                           if (proto != -1)
  4245                             {
  4246                               *proto_out = proto;
  4247                               *toplevel_out = overlay_window;
  4248                               x_uncatch_errors_after_check ();
  4249 
  4250                               return proxy;
  4251                             }
  4252                         }
  4253                     }
  4254                 }
  4255               x_uncatch_errors_after_check ();
  4256             }
  4257         }
  4258 #endif
  4259 
  4260       /* Now look for an XdndProxy on the root window.  */
  4261 
  4262       proxy = x_dnd_get_window_proxy (dpyinfo, dpyinfo->root_window);
  4263 
  4264       if (proxy != None)
  4265         {
  4266           proto = x_dnd_get_window_proto (dpyinfo, dpyinfo->root_window);
  4267 
  4268           if (proto != -1)
  4269             {
  4270               *toplevel_out = dpyinfo->root_window;
  4271               *proto_out = proto;
  4272               return proxy;
  4273             }
  4274         }
  4275 
  4276       /* No toplevel was found and the overlay and root windows were
  4277          not proxies, so return None.  */
  4278       *proto_out = -1;
  4279       *toplevel_out = dpyinfo->root_window;
  4280       return None;
  4281     }
  4282 
  4283   /* Not strictly necessary, but satisfies GCC.  */
  4284   child = dpyinfo->root_window;
  4285 
  4286   while (child_return != None)
  4287     {
  4288       child = child_return;
  4289       parent_x = dest_x_return;
  4290       parent_y = dest_y_return;
  4291 
  4292       x_catch_errors (dpyinfo->display);
  4293       rc = XTranslateCoordinates (dpyinfo->display, dpyinfo->root_window,
  4294                                   child_return, root_x, root_y, &dest_x_return,
  4295                                   &dest_y_return, &child_return);
  4296 
  4297       if (x_had_errors_p (dpyinfo->display) || !rc)
  4298         {
  4299           x_uncatch_errors_after_check ();
  4300           break;
  4301         }
  4302 
  4303       if (child_return)
  4304         {
  4305           /* If child_return is a tooltip frame, look beneath it.  We
  4306              never want to drop anything onto a tooltip frame.  */
  4307 
  4308           tooltip = x_tooltip_window_to_frame (dpyinfo, child_return,
  4309                                                &unrelated);
  4310 
  4311           if (tooltip || unrelated)
  4312             child_return = x_get_window_below (dpyinfo->display, child_return,
  4313                                                parent_x, parent_y, &dest_x_return,
  4314                                                &dest_y_return);
  4315 
  4316           if (!child_return)
  4317             {
  4318               x_uncatch_errors ();
  4319               break;
  4320             }
  4321 
  4322           f = x_top_window_to_frame (dpyinfo, child_return);
  4323 
  4324           if (f)
  4325             {
  4326               *proto_out = -1;
  4327               *motif_out = XM_DRAG_STYLE_NONE;
  4328               *toplevel_out = child_return;
  4329               *was_frame = true;
  4330 
  4331               return child_return;
  4332             }
  4333 
  4334           if (x_dnd_get_wm_state_and_proto (dpyinfo, child_return,
  4335                                             &wmstate, &proto, &motif,
  4336                                             &proxy)
  4337               /* `proto' and `motif' are set by x_dnd_get_wm_state
  4338                  even if getting the wm state failed.  */
  4339               || proto != -1 || motif != XM_DRAG_STYLE_NONE)
  4340             {
  4341               *proto_out = proto;
  4342               *motif_out = (x_dnd_disable_motif_protocol
  4343                             ? XM_DRAG_STYLE_NONE : motif);
  4344               *toplevel_out = child_return;
  4345               x_uncatch_errors ();
  4346 
  4347               return child_return;
  4348             }
  4349 
  4350           if (proxy != None)
  4351             {
  4352               proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4353 
  4354               if (proto != -1)
  4355                 {
  4356                   *proto_out = proto;
  4357                   *toplevel_out = child_return;
  4358 
  4359                   x_uncatch_errors ();
  4360                   return proxy;
  4361                 }
  4362             }
  4363         }
  4364 
  4365       x_uncatch_errors ();
  4366     }
  4367 
  4368 #if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2)
  4369   if (child != dpyinfo->root_window)
  4370     {
  4371 #endif
  4372       if (child != None)
  4373         {
  4374           proxy = x_dnd_get_window_proxy (dpyinfo, child);
  4375 
  4376           if (proxy)
  4377             {
  4378               proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4379 
  4380               if (proto != -1)
  4381                 {
  4382                   *proto_out = proto;
  4383                   *toplevel_out = child;
  4384                   return proxy;
  4385                 }
  4386             }
  4387         }
  4388 
  4389       *proto_out = x_dnd_get_window_proto (dpyinfo, child);
  4390       return child;
  4391 #if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2)
  4392     }
  4393   else if (dpyinfo->composite_supported_p
  4394            && (dpyinfo->composite_major > 0
  4395                || dpyinfo->composite_minor > 2))
  4396     {
  4397       /* Only do this if a compositing manager is present.  */
  4398       if (XGetSelectionOwner (dpyinfo->display,
  4399                               dpyinfo->Xatom_NET_WM_CM_Sn) != None)
  4400         {
  4401           x_catch_errors (dpyinfo->display);
  4402           XGrabServer (dpyinfo->display);
  4403           overlay_window = XCompositeGetOverlayWindow (dpyinfo->display,
  4404                                                        dpyinfo->root_window);
  4405           XCompositeReleaseOverlayWindow (dpyinfo->display,
  4406                                           dpyinfo->root_window);
  4407           XUngrabServer (dpyinfo->display);
  4408 
  4409           if (!x_had_errors_p (dpyinfo->display))
  4410             {
  4411               XGetWindowAttributes (dpyinfo->display, overlay_window, &attrs);
  4412 
  4413               if (attrs.map_state == IsViewable)
  4414                 {
  4415                   proxy = x_dnd_get_window_proxy (dpyinfo, overlay_window);
  4416 
  4417                   if (proxy != None)
  4418                     {
  4419                       proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4420 
  4421                       if (proto != -1)
  4422                         {
  4423                           *proto_out = proto;
  4424                           *toplevel_out = overlay_window;
  4425                           x_uncatch_errors_after_check ();
  4426 
  4427                           return proxy;
  4428                         }
  4429                     }
  4430                 }
  4431             }
  4432           x_uncatch_errors_after_check ();
  4433         }
  4434     }
  4435 
  4436   if (child != None)
  4437     {
  4438       proxy = x_dnd_get_window_proxy (dpyinfo, child);
  4439 
  4440       if (proxy)
  4441         {
  4442           proto = x_dnd_get_window_proto (dpyinfo, proxy);
  4443 
  4444           if (proto != -1)
  4445             {
  4446               *toplevel_out = child;
  4447               *proto_out = proto;
  4448               return proxy;
  4449             }
  4450         }
  4451     }
  4452 
  4453   *proto_out = x_dnd_get_window_proto (dpyinfo, child);
  4454   *toplevel_out = child;
  4455   return child;
  4456 #endif
  4457 }
  4458 
  4459 static Window
  4460 x_dnd_get_window_proxy (struct x_display_info *dpyinfo, Window wdesc)
  4461 {
  4462   int rc, actual_format;
  4463   unsigned long actual_size, bytes_remaining;
  4464   unsigned char *tmp_data = NULL;
  4465   XWindowAttributes attrs;
  4466   Atom actual_type;
  4467   Window proxy;
  4468 
  4469   proxy = None;
  4470   x_catch_errors (dpyinfo->display);
  4471   rc = XGetWindowProperty (dpyinfo->display, wdesc,
  4472                            dpyinfo->Xatom_XdndProxy,
  4473                            0, 1, False, XA_WINDOW,
  4474                            &actual_type, &actual_format,
  4475                            &actual_size, &bytes_remaining,
  4476                            &tmp_data);
  4477 
  4478   if (!x_had_errors_p (dpyinfo->display)
  4479       && rc == Success
  4480       && tmp_data
  4481       && actual_type == XA_WINDOW
  4482       && actual_format == 32
  4483       && actual_size == 1)
  4484     {
  4485       proxy = *(Window *) tmp_data;
  4486 
  4487       /* Verify the proxy window exists.  */
  4488       XGetWindowAttributes (dpyinfo->display, proxy, &attrs);
  4489 
  4490       if (x_had_errors_p (dpyinfo->display))
  4491         proxy = None;
  4492     }
  4493 
  4494   if (tmp_data)
  4495     XFree (tmp_data);
  4496   x_uncatch_errors_after_check ();
  4497 
  4498   return proxy;
  4499 }
  4500 
  4501 static int
  4502 x_dnd_get_window_proto (struct x_display_info *dpyinfo, Window wdesc)
  4503 {
  4504   Atom actual, value;
  4505   unsigned char *tmp_data = NULL;
  4506   int rc, format;
  4507   unsigned long n, left;
  4508   bool had_errors;
  4509 
  4510   if (wdesc == None || (!x_dnd_allow_current_frame
  4511                         && wdesc == FRAME_OUTER_WINDOW (x_dnd_frame)))
  4512     return -1;
  4513 
  4514   x_catch_errors (dpyinfo->display);
  4515   rc = XGetWindowProperty (dpyinfo->display, wdesc, dpyinfo->Xatom_XdndAware,
  4516                            0, 1, False, XA_ATOM, &actual, &format, &n, &left,
  4517                            &tmp_data);
  4518   had_errors = x_had_errors_p (dpyinfo->display);
  4519   x_uncatch_errors_after_check ();
  4520 
  4521   if (had_errors || rc != Success || actual != XA_ATOM || format != 32 || n < 1
  4522       || !tmp_data)
  4523     {
  4524       if (tmp_data)
  4525         XFree (tmp_data);
  4526       return -1;
  4527     }
  4528 
  4529   value = (int) *(Atom *) tmp_data;
  4530   XFree (tmp_data);
  4531 
  4532   return min (X_DND_SUPPORTED_VERSION, (int) value);
  4533 }
  4534 
  4535 static void
  4536 x_dnd_send_enter (struct frame *f, Window target, Window toplevel,
  4537                   int supported)
  4538 {
  4539   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4540   int i;
  4541   XEvent msg;
  4542 
  4543   msg.xclient.type = ClientMessage;
  4544   msg.xclient.message_type = dpyinfo->Xatom_XdndEnter;
  4545   msg.xclient.format = 32;
  4546   msg.xclient.window = toplevel;
  4547   msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
  4548   msg.xclient.data.l[1] = (((unsigned int) min (X_DND_SUPPORTED_VERSION,
  4549                                                 supported) << 24)
  4550                            | (x_dnd_n_targets > 3 ? 1 : 0));
  4551   msg.xclient.data.l[2] = 0;
  4552   msg.xclient.data.l[3] = 0;
  4553   msg.xclient.data.l[4] = 0;
  4554 
  4555   for (i = 0; i < min (3, x_dnd_n_targets); ++i)
  4556     msg.xclient.data.l[i + 2] = x_dnd_targets[i];
  4557 
  4558   if (x_dnd_n_targets > 3 && !x_dnd_init_type_lists)
  4559     XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  4560                      dpyinfo->Xatom_XdndTypeList, XA_ATOM, 32,
  4561                      PropModeReplace, (unsigned char *) x_dnd_targets,
  4562                      x_dnd_n_targets);
  4563 
  4564   /* Now record that the type list has already been set (if required),
  4565      so we don't have to set it again.  */
  4566   x_dnd_init_type_lists = true;
  4567 
  4568   x_ignore_errors_for_next_request (dpyinfo, 0);
  4569   XSendEvent (FRAME_X_DISPLAY (f), target, False, NoEventMask, &msg);
  4570   x_stop_ignoring_errors (dpyinfo);
  4571 }
  4572 
  4573 static void
  4574 x_dnd_send_position (struct frame *f, Window target, Window toplevel,
  4575                      int supported, unsigned short root_x,
  4576                      unsigned short root_y, Time timestamp, Atom action,
  4577                      int button, unsigned state)
  4578 {
  4579   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4580   XEvent msg;
  4581 
  4582   msg.xclient.type = ClientMessage;
  4583   msg.xclient.message_type = dpyinfo->Xatom_XdndPosition;
  4584   msg.xclient.format = 32;
  4585   msg.xclient.window = toplevel;
  4586   msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
  4587   msg.xclient.data.l[1] = 0;
  4588 
  4589   /* This is problematic because it's not specified in the
  4590      freedesktop.org copy of the protocol specification, but the copy
  4591      maintained by the original author of the protocol specifies it
  4592      for all versions.  Since at least one program supports these
  4593      flags, but uses protocol v4 (and not v5), set them for all
  4594      protocol versions.  */
  4595   if (button >= 4 && button <= 7)
  4596     {
  4597       msg.xclient.data.l[1] |= (1 << 10);
  4598       msg.xclient.data.l[1] |= (button - 4) << 8;
  4599     }
  4600   else if (button)
  4601     return;
  4602 
  4603   msg.xclient.data.l[1] |= state & 0xff;
  4604 
  4605   msg.xclient.data.l[2] = (root_x << 16) | root_y;
  4606   msg.xclient.data.l[3] = 0;
  4607   msg.xclient.data.l[4] = 0;
  4608 
  4609   if (supported >= 3)
  4610     msg.xclient.data.l[3] = timestamp;
  4611 
  4612   if (supported >= 4)
  4613     msg.xclient.data.l[4] = action;
  4614 
  4615   if (x_dnd_waiting_for_status_window == target)
  4616     {
  4617       x_dnd_pending_send_position = msg;
  4618       x_dnd_pending_send_position_button = button;
  4619       x_dnd_pending_send_position_root_x = root_x;
  4620       x_dnd_pending_send_position_root_y = root_y;
  4621     }
  4622   else
  4623     {
  4624       if (target == x_dnd_mouse_rect_target
  4625           && x_dnd_mouse_rect.width
  4626           && x_dnd_mouse_rect.height
  4627           /* Ignore the mouse rectangle if we're supposed to be sending a
  4628              button press instead.  */
  4629           && !button)
  4630         {
  4631           if (root_x >= x_dnd_mouse_rect.x
  4632               && root_x < (x_dnd_mouse_rect.x
  4633                            + x_dnd_mouse_rect.width)
  4634               && root_y >= x_dnd_mouse_rect.y
  4635               && root_y < (x_dnd_mouse_rect.y
  4636                            + x_dnd_mouse_rect.height))
  4637             return;
  4638         }
  4639 
  4640       x_ignore_errors_for_next_request (dpyinfo, 0);
  4641       XSendEvent (FRAME_X_DISPLAY (f), target, False, NoEventMask, &msg);
  4642       x_stop_ignoring_errors (dpyinfo);
  4643 
  4644       x_dnd_waiting_for_status_window = target;
  4645     }
  4646 }
  4647 
  4648 static void
  4649 x_dnd_send_leave (struct frame *f, Window target, Window toplevel)
  4650 {
  4651   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  4652   XEvent msg;
  4653 
  4654   msg.xclient.type = ClientMessage;
  4655   msg.xclient.message_type = dpyinfo->Xatom_XdndLeave;
  4656   msg.xclient.format = 32;
  4657   msg.xclient.window = toplevel;
  4658   msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
  4659   msg.xclient.data.l[1] = 0;
  4660   msg.xclient.data.l[2] = 0;
  4661   msg.xclient.data.l[3] = 0;
  4662   msg.xclient.data.l[4] = 0;
  4663 
  4664   x_dnd_waiting_for_status_window = None;
  4665   x_dnd_pending_send_position.type = 0;
  4666 
  4667   x_ignore_errors_for_next_request (dpyinfo, 0);
  4668   XSendEvent (FRAME_X_DISPLAY (f), target, False, NoEventMask, &msg);
  4669   x_stop_ignoring_errors (dpyinfo);
  4670 }
  4671 
  4672 static bool
  4673 x_dnd_send_drop (struct frame *f, Window target, Window toplevel,
  4674                  Time timestamp, int supported)
  4675 {
  4676   struct x_display_info *dpyinfo;
  4677   XEvent msg;
  4678 
  4679   if (x_dnd_action == None)
  4680     {
  4681       x_dnd_send_leave (f, target, toplevel);
  4682       return false;
  4683     }
  4684 
  4685   dpyinfo = FRAME_DISPLAY_INFO (f);
  4686 
  4687   msg.xclient.type = ClientMessage;
  4688   msg.xclient.message_type = dpyinfo->Xatom_XdndDrop;
  4689   msg.xclient.format = 32;
  4690   msg.xclient.window = toplevel;
  4691   msg.xclient.data.l[0] = FRAME_X_WINDOW (f);
  4692   msg.xclient.data.l[1] = 0;
  4693   msg.xclient.data.l[2] = 0;
  4694   msg.xclient.data.l[3] = 0;
  4695   msg.xclient.data.l[4] = 0;
  4696 
  4697   if (supported >= 1)
  4698     msg.xclient.data.l[2] = timestamp;
  4699 
  4700   x_ignore_errors_for_next_request (dpyinfo, 0);
  4701   XSendEvent (FRAME_X_DISPLAY (f), target, False, NoEventMask, &msg);
  4702   x_stop_ignoring_errors (dpyinfo);
  4703   return true;
  4704 }
  4705 
  4706 static bool
  4707 x_dnd_do_drop (Window target, Window toplevel, int supported)
  4708 {
  4709   if (x_dnd_waiting_for_status_window != target)
  4710     return x_dnd_send_drop (x_dnd_frame, target, toplevel,
  4711                             x_dnd_selection_timestamp, supported);
  4712 
  4713   x_dnd_need_send_drop = true;
  4714   x_dnd_send_drop_proto = supported;
  4715 
  4716   return true;
  4717 }
  4718 
  4719 static void
  4720 x_set_dnd_targets (Atom *targets, int ntargets)
  4721 {
  4722   if (x_dnd_targets)
  4723     xfree (x_dnd_targets);
  4724 
  4725   block_input ();
  4726   x_dnd_targets = xmalloc (sizeof *targets * ntargets);
  4727   x_dnd_n_targets = ntargets;
  4728 
  4729   memcpy (x_dnd_targets, targets,
  4730           sizeof *targets * ntargets);
  4731   unblock_input ();
  4732 }
  4733 
  4734 static void
  4735 x_free_dnd_targets (void)
  4736 {
  4737   if (!x_dnd_targets)
  4738     return;
  4739 
  4740   xfree (x_dnd_targets);
  4741   x_dnd_targets = NULL;
  4742   x_dnd_n_targets = 0;
  4743 }
  4744 
  4745 /* Clear some Lisp variables after the drop finishes, so they are
  4746    freed by the GC.  */
  4747 
  4748 static void
  4749 x_clear_dnd_variables (void)
  4750 {
  4751   x_dnd_monitors = Qnil;
  4752   x_dnd_unsupported_drop_data = Qnil;
  4753 }
  4754 
  4755 static void
  4756 x_free_dnd_toplevels (void)
  4757 {
  4758   if (!x_dnd_use_toplevels || !x_dnd_toplevels)
  4759     return;
  4760 
  4761   /* If the display is deleted, x_dnd_toplevels will already be
  4762      NULL, so we can always assume the display is alive here.  */
  4763 
  4764   x_dnd_free_toplevels (true);
  4765 }
  4766 
  4767 /* Restore event masks and window properties changed during a
  4768    drag-and-drop operation, after it finishes.  */
  4769 static void
  4770 x_restore_events_after_dnd (struct frame *f, XWindowAttributes *wa)
  4771 {
  4772   struct x_display_info *dpyinfo;
  4773 
  4774   dpyinfo = FRAME_DISPLAY_INFO (f);
  4775 
  4776   /* Restore the old event mask.  */
  4777   XSelectInput (dpyinfo->display, dpyinfo->root_window,
  4778                 wa->your_event_mask);
  4779 #ifdef HAVE_XKB
  4780   if (dpyinfo->supports_xkb)
  4781     XkbSelectEvents (dpyinfo->display, XkbUseCoreKbd,
  4782                      XkbStateNotifyMask, 0);
  4783 #endif
  4784   /* Delete the Motif drag initiator info if it was set up.  */
  4785   if (x_dnd_motif_setup_p)
  4786     XDeleteProperty (dpyinfo->display, FRAME_X_WINDOW (f),
  4787                      x_dnd_motif_atom);
  4788 
  4789   /* Remove any type list set as well.  */
  4790   if (x_dnd_init_type_lists && x_dnd_n_targets > 3)
  4791     XDeleteProperty (dpyinfo->display, FRAME_X_WINDOW (f),
  4792                      dpyinfo->Xatom_XdndTypeList);
  4793 }
  4794 
  4795 #ifdef HAVE_XINPUT2
  4796 
  4797 /* Cancel the current drag-and-drop operation, sending leave messages
  4798    to any relevant toplevels.  This is called from the event loop when
  4799    an event is received telling Emacs to gracefully cancel the
  4800    drag-and-drop operation.  */
  4801 
  4802 static void
  4803 x_dnd_cancel_dnd_early (void)
  4804 {
  4805   struct frame *f;
  4806   xm_drop_start_message dmsg;
  4807 
  4808   eassert (x_dnd_frame && x_dnd_in_progress);
  4809 
  4810   f = x_dnd_frame;
  4811 
  4812   if (x_dnd_last_seen_window != None
  4813       && x_dnd_last_protocol_version != -1)
  4814     x_dnd_send_leave (x_dnd_frame,
  4815                       x_dnd_last_seen_window,
  4816                       x_dnd_last_seen_toplevel);
  4817   else if (x_dnd_last_seen_window != None
  4818            && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
  4819            && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
  4820            && x_dnd_motif_setup_p)
  4821     {
  4822       dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
  4823                                     XM_DRAG_REASON_DROP_START);
  4824       dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
  4825       dmsg.timestamp = FRAME_DISPLAY_INFO (f)->last_user_time;
  4826       dmsg.side_effects
  4827         = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
  4828                                                            x_dnd_wanted_action),
  4829                                XM_DROP_SITE_VALID, x_dnd_motif_operations,
  4830                                XM_DROP_ACTION_DROP_CANCEL);
  4831       dmsg.x = 0;
  4832       dmsg.y = 0;
  4833       dmsg.index_atom = x_dnd_motif_atom;
  4834       dmsg.source_window = FRAME_X_WINDOW (f);
  4835 
  4836       x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
  4837                                     x_dnd_last_seen_window,
  4838                                     FRAME_DISPLAY_INFO (f)->last_user_time);
  4839       xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
  4840                             x_dnd_last_seen_window, &dmsg);
  4841     }
  4842 
  4843   x_dnd_last_seen_window = None;
  4844   x_dnd_last_seen_toplevel = None;
  4845   x_dnd_in_progress = false;
  4846   x_dnd_waiting_for_finish = false;
  4847   x_dnd_return_frame_object = NULL;
  4848   x_dnd_movement_frame = NULL;
  4849   x_dnd_wheel_frame = NULL;
  4850   x_dnd_frame = NULL;
  4851   x_dnd_action = None;
  4852   x_dnd_action_symbol = Qnil;
  4853 }
  4854 
  4855 #endif
  4856 
  4857 static void
  4858 x_dnd_cleanup_drag_and_drop (void *frame)
  4859 {
  4860   struct frame *f = frame;
  4861   xm_drop_start_message dmsg;
  4862 
  4863   if (!x_dnd_unwind_flag)
  4864     return;
  4865 
  4866   if (x_dnd_in_progress)
  4867     {
  4868       eassert (x_dnd_frame);
  4869 
  4870       block_input ();
  4871       if (x_dnd_last_seen_window != None
  4872           && x_dnd_last_protocol_version != -1)
  4873         x_dnd_send_leave (x_dnd_frame,
  4874                           x_dnd_last_seen_window,
  4875                           x_dnd_last_seen_toplevel);
  4876       else if (x_dnd_last_seen_window != None
  4877                && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
  4878                && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
  4879                && x_dnd_motif_setup_p)
  4880         {
  4881           dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
  4882                                         XM_DRAG_REASON_DROP_START);
  4883           dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
  4884           dmsg.timestamp = FRAME_DISPLAY_INFO (f)->last_user_time;
  4885           dmsg.side_effects
  4886             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
  4887                                                                x_dnd_wanted_action),
  4888                                    XM_DROP_SITE_VALID, x_dnd_motif_operations,
  4889                                    XM_DROP_ACTION_DROP_CANCEL);
  4890           dmsg.x = 0;
  4891           dmsg.y = 0;
  4892           dmsg.index_atom = x_dnd_motif_atom;
  4893           dmsg.source_window = FRAME_X_WINDOW (f);
  4894 
  4895           x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
  4896                                         x_dnd_last_seen_window,
  4897                                         FRAME_DISPLAY_INFO (f)->last_user_time);
  4898           xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
  4899                                 x_dnd_last_seen_window, &dmsg);
  4900         }
  4901       unblock_input ();
  4902 
  4903       x_dnd_end_window = x_dnd_last_seen_window;
  4904       x_dnd_last_seen_window = None;
  4905       x_dnd_last_seen_toplevel = None;
  4906       x_dnd_in_progress = false;
  4907     }
  4908 
  4909   x_dnd_waiting_for_finish = false;
  4910 
  4911   FRAME_DISPLAY_INFO (f)->grabbed = 0;
  4912 #ifdef USE_GTK
  4913   current_hold_quit = NULL;
  4914 #endif
  4915   x_dnd_return_frame_object = NULL;
  4916   x_dnd_movement_frame = NULL;
  4917   x_dnd_wheel_frame = NULL;
  4918   x_dnd_frame = NULL;
  4919 
  4920   x_restore_events_after_dnd (f, &x_dnd_old_window_attrs);
  4921 }
  4922 
  4923 static void
  4924 x_dnd_note_self_position (struct x_display_info *dpyinfo, Window target,
  4925                           unsigned short root_x, unsigned short root_y)
  4926 {
  4927   struct frame *f;
  4928   int dest_x, dest_y;
  4929 
  4930   f = x_top_window_to_frame (dpyinfo, target);
  4931 
  4932   if (f)
  4933     {
  4934       x_translate_coordinates (f, root_x, root_y, &dest_x, &dest_y);
  4935 
  4936       x_dnd_movement_frame = f;
  4937       x_dnd_movement_x = dest_x;
  4938       x_dnd_movement_y = dest_y;
  4939 
  4940       return;
  4941     }
  4942 }
  4943 
  4944 static void
  4945 x_dnd_note_self_wheel (struct x_display_info *dpyinfo, Window target,
  4946                        unsigned short root_x, unsigned short root_y,
  4947                        int button, unsigned int state, Time time)
  4948 {
  4949   struct frame *f;
  4950   int dest_x, dest_y;
  4951 
  4952   if (button < 4 || button > 7)
  4953     return;
  4954 
  4955   f = x_top_window_to_frame (dpyinfo, target);
  4956 
  4957   if (f)
  4958     {
  4959       x_translate_coordinates (f, root_x, root_y, &dest_x, &dest_y);
  4960 
  4961       x_dnd_wheel_frame = f;
  4962       x_dnd_wheel_x = dest_x;
  4963       x_dnd_wheel_y = dest_y;
  4964       x_dnd_wheel_button = button;
  4965       x_dnd_wheel_state = state;
  4966       x_dnd_wheel_time = time;
  4967 
  4968       return;
  4969     }
  4970 }
  4971 
  4972 static void
  4973 x_dnd_note_self_drop (struct x_display_info *dpyinfo, Window target,
  4974                       unsigned short root_x, unsigned short root_y,
  4975                       Time timestamp)
  4976 {
  4977   struct input_event ie;
  4978   struct frame *f;
  4979   Lisp_Object lval;
  4980   char **atom_names;
  4981   char *name;
  4982   int win_x, win_y, i;
  4983 
  4984   if (!x_dnd_allow_current_frame
  4985       && (FRAME_OUTER_WINDOW (x_dnd_frame)
  4986           == target))
  4987     return;
  4988 
  4989   f = x_top_window_to_frame (dpyinfo, target);
  4990 
  4991   if (!f)
  4992     return;
  4993 
  4994   if (NILP (Vx_dnd_native_test_function))
  4995     return;
  4996 
  4997   x_translate_coordinates (f, root_x, root_y, &win_x, &win_y);
  4998 
  4999   /* Emacs can't respond to DND events inside the nested event loop,
  5000      so when dragging items to itself, call the test function
  5001      manually.  */
  5002 
  5003   XSETFRAME (lval, f);
  5004   x_dnd_action = None;
  5005   x_dnd_action_symbol
  5006     = safe_call2 (Vx_dnd_native_test_function,
  5007                   Fposn_at_x_y (make_fixnum (win_x),
  5008                                 make_fixnum (win_y),
  5009                                 lval, Qnil),
  5010                   x_atom_to_symbol (dpyinfo,
  5011                                     x_dnd_wanted_action));
  5012 
  5013   if (!SYMBOLP (x_dnd_action_symbol))
  5014     return;
  5015 
  5016   EVENT_INIT (ie);
  5017 
  5018   ie.kind = DRAG_N_DROP_EVENT;
  5019   XSETFRAME (ie.frame_or_window, f);
  5020 
  5021   lval = Qnil;
  5022   atom_names = alloca (x_dnd_n_targets * sizeof *atom_names);
  5023   name = x_get_atom_name (dpyinfo, x_dnd_wanted_action, NULL);
  5024 
  5025   if (!XGetAtomNames (dpyinfo->display, x_dnd_targets,
  5026                       x_dnd_n_targets, atom_names))
  5027     {
  5028       xfree (name);
  5029       return;
  5030     }
  5031 
  5032   for (i = x_dnd_n_targets; i != 0; --i)
  5033     {
  5034       lval = Fcons (intern (atom_names[i - 1]), lval);
  5035       XFree (atom_names[i - 1]);
  5036     }
  5037 
  5038   lval = Fcons (assq_no_quit (QXdndSelection,
  5039                               FRAME_TERMINAL (f)->Vselection_alist),
  5040                 lval);
  5041   lval = Fcons (intern (name), lval);
  5042   lval = Fcons (QXdndSelection, lval);
  5043   ie.arg = lval;
  5044   ie.timestamp = timestamp;
  5045 
  5046   XSETINT (ie.x, win_x);
  5047   XSETINT (ie.y, win_y);
  5048 
  5049   xfree (name);
  5050   kbd_buffer_store_event (&ie);
  5051 }
  5052 
  5053 /* Flush display of frame F.  */
  5054 
  5055 static void
  5056 x_flush (struct frame *f)
  5057 {
  5058   eassert (f && FRAME_X_P (f));
  5059   /* Don't call XFlush when it is not safe to redisplay; the X
  5060      connection may be broken.  */
  5061   if (!NILP (Vinhibit_redisplay))
  5062     return;
  5063 
  5064   block_input ();
  5065   XFlush (FRAME_X_DISPLAY (f));
  5066   unblock_input ();
  5067 }
  5068 
  5069 #ifdef HAVE_XDBE
  5070 static void
  5071 x_drop_xrender_surfaces (struct frame *f)
  5072 {
  5073   font_drop_xrender_surfaces (f);
  5074 
  5075 #ifdef HAVE_XRENDER
  5076   if (f && FRAME_X_DOUBLE_BUFFERED_P (f)
  5077       && FRAME_X_PICTURE (f) != None)
  5078     {
  5079       XRenderFreePicture (FRAME_X_DISPLAY (f),
  5080                           FRAME_X_PICTURE (f));
  5081       FRAME_X_PICTURE (f) = None;
  5082     }
  5083 #endif
  5084 }
  5085 #endif
  5086 
  5087 #ifdef HAVE_XRENDER
  5088 void
  5089 x_xr_ensure_picture (struct frame *f)
  5090 {
  5091   if (FRAME_X_PICTURE (f) == None && FRAME_X_PICTURE_FORMAT (f))
  5092     {
  5093       XRenderPictureAttributes attrs;
  5094       attrs.clip_mask = None;
  5095       XRenderPictFormat *fmt = FRAME_X_PICTURE_FORMAT (f);
  5096 
  5097       FRAME_X_PICTURE (f) = XRenderCreatePicture (FRAME_X_DISPLAY (f),
  5098                                                   FRAME_X_RAW_DRAWABLE (f),
  5099                                                   fmt, CPClipMask, &attrs);
  5100     }
  5101 }
  5102 #endif
  5103 
  5104 
  5105 /***********************************************************************
  5106                               Debugging
  5107  ***********************************************************************/
  5108 
  5109 #if false
  5110 
  5111 /* This is a function useful for recording debugging information about
  5112    the sequence of occurrences in this file.  */
  5113 
  5114 struct record
  5115 {
  5116   char *locus;
  5117   int type;
  5118 };
  5119 
  5120 struct record event_record[100];
  5121 
  5122 int event_record_index;
  5123 
  5124 void
  5125 record_event (char *locus, int type)
  5126 {
  5127   if (event_record_index == ARRAYELTS (event_record))
  5128     event_record_index = 0;
  5129 
  5130   event_record[event_record_index].locus = locus;
  5131   event_record[event_record_index].type = type;
  5132   event_record_index++;
  5133 }
  5134 
  5135 #endif
  5136 
  5137 #ifdef HAVE_XINPUT2
  5138 bool
  5139 xi_frame_selected_for (struct frame *f, unsigned long event)
  5140 {
  5141   XIEventMask *masks;
  5142   int i;
  5143 
  5144   masks = FRAME_X_OUTPUT (f)->xi_masks;
  5145 
  5146   if (!masks)
  5147     return false;
  5148 
  5149   for (i = 0; i < FRAME_X_OUTPUT (f)->num_xi_masks; ++i)
  5150     {
  5151       if (masks[i].mask_len >= XIMaskLen (event)
  5152           && XIMaskIsSet (masks[i].mask, event))
  5153         return true;
  5154     }
  5155 
  5156   return false;
  5157 }
  5158 #endif
  5159 
  5160 static void
  5161 x_toolkit_position (struct frame *f, int x, int y,
  5162                     bool *menu_bar_p, bool *tool_bar_p)
  5163 {
  5164 #ifdef USE_GTK
  5165   GdkRectangle test_rect;
  5166   int scale;
  5167 
  5168   y += (FRAME_MENUBAR_HEIGHT (f)
  5169         + FRAME_TOOLBAR_TOP_HEIGHT (f));
  5170   x += FRAME_TOOLBAR_LEFT_WIDTH (f);
  5171 
  5172   if (FRAME_EXTERNAL_MENU_BAR (f))
  5173     *menu_bar_p = (x >= 0 && x < FRAME_PIXEL_WIDTH (f)
  5174                    && y >= 0 && y < FRAME_MENUBAR_HEIGHT (f));
  5175 
  5176   if (FRAME_X_OUTPUT (f)->toolbar_widget)
  5177     {
  5178       scale = xg_get_scale (f);
  5179       test_rect.x = x / scale;
  5180       test_rect.y = y / scale;
  5181       test_rect.width = 1;
  5182       test_rect.height = 1;
  5183 
  5184       *tool_bar_p = gtk_widget_intersect (FRAME_X_OUTPUT (f)->toolbar_widget,
  5185                                           &test_rect, NULL);
  5186     }
  5187 #elif defined USE_X_TOOLKIT
  5188   *menu_bar_p = (x > 0 && x < FRAME_PIXEL_WIDTH (f)
  5189                  && (y < 0 && y >= -FRAME_MENUBAR_HEIGHT (f)));
  5190 #else
  5191   *menu_bar_p = (WINDOWP (f->menu_bar_window)
  5192                  && (x > 0 && x < FRAME_PIXEL_WIDTH (f)
  5193                      && (y > 0 && y < FRAME_MENU_BAR_HEIGHT (f))));
  5194 #endif
  5195 }
  5196 
  5197 static void
  5198 x_update_opaque_region (struct frame *f, XEvent *configure)
  5199 {
  5200   unsigned long opaque_region[] = {0, 0,
  5201                                    (configure
  5202                                     ? configure->xconfigure.width
  5203                                     : FRAME_PIXEL_WIDTH (f)),
  5204                                    (configure
  5205                                     ? configure->xconfigure.height
  5206                                     : FRAME_PIXEL_HEIGHT (f))};
  5207 #ifdef HAVE_GTK3
  5208   GObjectClass *object_class;
  5209   GtkWidgetClass *class;
  5210 #endif
  5211 
  5212   if (!FRAME_DISPLAY_INFO (f)->alpha_bits)
  5213     return;
  5214 
  5215   if (f->alpha_background < 1.0)
  5216     XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  5217                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
  5218                      XA_CARDINAL, 32, PropModeReplace,
  5219                      NULL, 0);
  5220 #ifndef HAVE_GTK3
  5221   else
  5222     XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  5223                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
  5224                      XA_CARDINAL, 32, PropModeReplace,
  5225                      (unsigned char *) &opaque_region, 4);
  5226 #else
  5227   else if (FRAME_TOOLTIP_P (f))
  5228     XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
  5229                      FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
  5230                      XA_CARDINAL, 32, PropModeReplace,
  5231                      (unsigned char *) &opaque_region, 4);
  5232   else
  5233     {
  5234       /* This causes child frames to not update correctly for an
  5235          unknown reason.  (bug#55779) */
  5236       if (!FRAME_PARENT_FRAME (f))
  5237         {
  5238           object_class = G_OBJECT_GET_CLASS (FRAME_GTK_OUTER_WIDGET (f));
  5239           class = GTK_WIDGET_CLASS (object_class);
  5240 
  5241           if (class->style_updated)
  5242             class->style_updated (FRAME_GTK_OUTER_WIDGET (f));
  5243         }
  5244     }
  5245 #endif
  5246 }
  5247 
  5248 
  5249 #if defined USE_CAIRO || defined HAVE_XRENDER
  5250 static int
  5251 x_gc_free_ext_data_private (XExtData *extension)
  5252 {
  5253   xfree (extension->private_data);
  5254 
  5255   return 0;
  5256 }
  5257 
  5258 static struct x_gc_ext_data *
  5259 x_gc_get_ext_data (struct frame *f, GC gc, int create_if_not_found_p)
  5260 {
  5261   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  5262   XEDataObject object;
  5263   XExtData **head, *ext_data;
  5264 
  5265   object.gc = gc;
  5266   head = XEHeadOfExtensionList (object);
  5267   ext_data = XFindOnExtensionList (head, dpyinfo->ext_codes->extension);
  5268   if (ext_data == NULL)
  5269     {
  5270       if (!create_if_not_found_p)
  5271         return NULL;
  5272       else
  5273         {
  5274           ext_data = xzalloc (sizeof (*ext_data));
  5275           ext_data->number = dpyinfo->ext_codes->extension;
  5276           ext_data->private_data = xzalloc (sizeof (struct x_gc_ext_data));
  5277           ext_data->free_private = x_gc_free_ext_data_private;
  5278           XAddToExtensionList (head, ext_data);
  5279         }
  5280     }
  5281   return (struct x_gc_ext_data *) ext_data->private_data;
  5282 }
  5283 
  5284 static void
  5285 x_extension_initialize (struct x_display_info *dpyinfo)
  5286 {
  5287   XExtCodes *ext_codes = XAddExtension (dpyinfo->display);
  5288 
  5289   dpyinfo->ext_codes = ext_codes;
  5290 }
  5291 #endif
  5292 
  5293 #ifdef USE_CAIRO
  5294 
  5295 #define FRAME_CR_CONTEXT(f)     ((f)->output_data.x->cr_context)
  5296 #define FRAME_CR_SURFACE_DESIRED_WIDTH(f) \
  5297   ((f)->output_data.x->cr_surface_desired_width)
  5298 #define FRAME_CR_SURFACE_DESIRED_HEIGHT(f) \
  5299   ((f)->output_data.x->cr_surface_desired_height)
  5300 
  5301 #endif /* HAVE_CAIRO */
  5302 
  5303 #ifdef HAVE_XINPUT2
  5304 
  5305 /* Convert XI2 button state IN to a standard X button modifier
  5306    mask, and place it in OUT.  */
  5307 static void
  5308 xi_convert_button_state (XIButtonState *in, unsigned int *out)
  5309 {
  5310   int i;
  5311 
  5312   if (in->mask_len)
  5313     {
  5314       for (i = 1; i <= 8; ++i)
  5315         {
  5316           if (XIMaskIsSet (in->mask, i))
  5317             *out |= (Button1Mask << (i - 1));
  5318         }
  5319     }
  5320 }
  5321 
  5322 /* Return the modifier state in XEV as a standard X modifier mask.
  5323    This should be used for non-keyboard events, where the group does
  5324    not matter.  */
  5325 
  5326 #ifdef USE_GTK
  5327 static
  5328 #endif
  5329 unsigned int
  5330 xi_convert_event_state (XIDeviceEvent *xev)
  5331 {
  5332   unsigned int mods, buttons;
  5333 
  5334   mods = xev->mods.effective;
  5335   buttons = 0;
  5336 
  5337   xi_convert_button_state (&xev->buttons, &buttons);
  5338 
  5339   return mods | buttons;
  5340 }
  5341 
  5342 /* Like the above.  However, buttons are not converted, while the
  5343    group is.  This should be used for key events being passed to the
  5344    likes of input methods and Xt.  */
  5345 
  5346 static unsigned int
  5347 xi_convert_event_keyboard_state (XIDeviceEvent *xev)
  5348 {
  5349   return ((xev->mods.effective & ~(1 << 13 | 1 << 14))
  5350           | (xev->group.effective << 13));
  5351 }
  5352 
  5353 /* Free all XI2 devices on DPYINFO.  */
  5354 static void
  5355 x_free_xi_devices (struct x_display_info *dpyinfo)
  5356 {
  5357 #ifdef HAVE_XINPUT2_2
  5358   struct xi_touch_point_t *tem, *last;
  5359 #endif
  5360 
  5361   block_input ();
  5362 
  5363   if (dpyinfo->num_devices)
  5364     {
  5365       for (int i = 0; i < dpyinfo->num_devices; ++i)
  5366         {
  5367 #ifdef HAVE_XINPUT2_1
  5368           xfree (dpyinfo->devices[i].valuators);
  5369 #endif
  5370 
  5371 #ifdef HAVE_XINPUT2_2
  5372           tem = dpyinfo->devices[i].touchpoints;
  5373           while (tem)
  5374             {
  5375               last = tem;
  5376               tem = tem->next;
  5377               xfree (last);
  5378             }
  5379 #endif
  5380         }
  5381 
  5382       xfree (dpyinfo->devices);
  5383       dpyinfo->devices = NULL;
  5384       dpyinfo->num_devices = 0;
  5385     }
  5386 
  5387   unblock_input ();
  5388 }
  5389 
  5390 #ifdef HAVE_XINPUT2_1
  5391 
  5392 struct xi_known_valuator
  5393 {
  5394   /* The current value of this valuator.  */
  5395   double current_value;
  5396 
  5397   /* The number of the valuator.  */
  5398   int number;
  5399 
  5400   /* The next valuator whose value we already know.  */
  5401   struct xi_known_valuator *next;
  5402 };
  5403 
  5404 /* Populate the scroll valuator at INDEX in DEVICE with the scroll
  5405    valuator information provided in INFO.
  5406 
  5407    The information consists of:
  5408 
  5409      - whether or not the valuator is horizontal.
  5410 
  5411      - whether or not the valuator's value is currently unknown,
  5412        until the next XI_Motion event is received or the valuator's
  5413        value is restored by the caller upon encountering valuator
  5414        class data.
  5415 
  5416      - what the current value of the valuator is.  This is set to
  5417        DBL_MIN for debugging purposes, but can be any value, as
  5418        invalid_p is currently true.
  5419 
  5420      - the increment, which defines the amount of movement equal to a
  5421        single unit of scrolling.  For example, if the increment is
  5422        2.0, then a WHEEL_DOWN or WHEEL_UP event will be sent every
  5423        time the valuator value changes by 2.0, unless
  5424        mwheel-coalesce-scroll-events is nil.
  5425 
  5426      - the number used in XI_Motion events and elsewhere to identify
  5427        the valuator.  */
  5428 
  5429 static void
  5430 xi_populate_scroll_valuator (struct xi_device_t *device,
  5431                              int index, XIScrollClassInfo *info)
  5432 {
  5433   struct xi_scroll_valuator_t *valuator;
  5434 
  5435   valuator = &device->valuators[index];
  5436   valuator->horizontal
  5437     = (info->scroll_type == XIScrollTypeHorizontal);
  5438   valuator->invalid_p = true;
  5439   valuator->emacs_value = DBL_MIN;
  5440   valuator->increment = info->increment;
  5441   valuator->number = info->number;
  5442 }
  5443 
  5444 #endif
  5445 
  5446 static void
  5447 xi_populate_device_from_info (struct x_display_info *dpyinfo,
  5448                               struct xi_device_t *xi_device,
  5449                               XIDeviceInfo *device)
  5450 {
  5451 #ifdef HAVE_XINPUT2_1
  5452   struct xi_known_valuator *values, *tem;
  5453   int actual_valuator_count, c;
  5454   XIScrollClassInfo *info;
  5455   XIValuatorClassInfo *valuator_info;
  5456 #endif
  5457 #ifdef HAVE_XINPUT2_2
  5458   XITouchClassInfo *touch_info;
  5459 #endif
  5460 
  5461 #ifdef HAVE_XINPUT2_1
  5462   USE_SAFE_ALLOCA;
  5463 #endif
  5464 
  5465   /* Initialize generic information about the device: its ID, which
  5466      buttons are currently pressed and thus presumably actively
  5467      grabbing the device, what kind of device it is (master pointer,
  5468      master keyboard, slave pointer, slave keyboard, or floating
  5469      slave), and its attachment.
  5470 
  5471      Here is a brief description of what device uses and attachments
  5472      are.  Under XInput 2, user input from individual input devices is
  5473      multiplexed into specific seats before being delivered, with each
  5474      seat corresponding to a single on-screen mouse pointer and having
  5475      its own keyboard focus.  Each seat consists of two virtual
  5476      devices: the master keyboard and the master pointer, the first of
  5477      which is used to report all keyboard input, with the other used
  5478      to report all other input.
  5479 
  5480      Input from each physical device (mouse, trackpad or keyboard) is
  5481      then associated with that slave device's paired master device.
  5482      For example, moving the device "Logitech USB Optical Mouse",
  5483      enslaved by the master pointer device "Virtual core pointer",
  5484      will result in movement of the mouse pointer associated with that
  5485      master device's seat.  If the pointer moves over an Emacs frame,
  5486      then the frame will receive XI_Enter and XI_Motion events from
  5487      that master pointer.
  5488 
  5489      Likewise, keyboard input from the device "AT Translated Set 2
  5490      keyboard", enslaved by the master keyboard device "Virtual core
  5491      keyboard", will be reported to its seat's input focus window.
  5492 
  5493      The device use describes what the device is.  The meanings of
  5494      MasterPointer, MasterKeyboard, SlavePointer and SlaveKeyboard
  5495      should be obvious.  FloatingSlave means the device is a slave
  5496      device that is not associated with any seat, and thus generates
  5497      no input.
  5498 
  5499      The device attachment is a device ID whose meaning varies
  5500      depending on the device's use.  If a device is a master device,
  5501      then its attachment is the device ID of the other device in its
  5502      seat (the master keyboard for master pointer devices and vice
  5503      versa.)  Otherwise, it is the ID of the master device the slave
  5504      device is attached to.  For slave devices not attached to any
  5505      seat, its value is undefined.
  5506 
  5507      Emacs receives ordinary pointer and keyboard events from the
  5508      master devices associated with each seat, discarding events from
  5509      slave devices.  However, multiplexing events from touch devices
  5510      onto a master device poses problems: if both dependent and direct
  5511      touch devices are attached to the same master pointer device, the
  5512      coordinate space of touch events sent from that seat becomes
  5513      ambiguous.  In addition, the X server does not send TouchEnd
  5514      events to cancel ongoing touch sequences if the slave device that
  5515      is their source is detached.  As a result of these ambiguities,
  5516      touch events are processed from and recorded onto their slave
  5517      devices instead.  */
  5518 
  5519   xi_device->device_id = device->deviceid;
  5520   xi_device->grab = 0;
  5521   xi_device->use = device->use;
  5522   xi_device->name = build_string (device->name);
  5523   xi_device->attachment = device->attachment;
  5524 
  5525   /* Clear the list of active touch points on the device, which are
  5526      individual touches tracked by a touchscreen.  */
  5527 
  5528 #ifdef HAVE_XINPUT2_2
  5529   xi_device->touchpoints = NULL;
  5530   xi_device->direct_p = false;
  5531 #endif /* HAVE_XINPUT2_1 */
  5532 
  5533 #ifdef HAVE_XINPUT2_1
  5534   if (!dpyinfo->xi2_version)
  5535     {
  5536       /* Skip everything below as there are no classes of interest on
  5537          XI 2.0 servers.  */
  5538       xi_device->valuators = NULL;
  5539       xi_device->scroll_valuator_count = 0;
  5540 
  5541       SAFE_FREE ();
  5542       return;
  5543     }
  5544 
  5545   actual_valuator_count = 0;
  5546   xi_device->valuators = xnmalloc (device->num_classes,
  5547                                    sizeof *xi_device->valuators);
  5548   values = NULL;
  5549 
  5550   /* Initialize device info based on a list of "device classes".
  5551      Device classes are little pieces of information associated with a
  5552      device.  Emacs is interested in scroll valuator information and
  5553      touch handling information, which respectively describe the axes
  5554      (if any) along which the device's scroll wheel rotates, and how
  5555      the device reports touch input.  */
  5556 
  5557   for (c = 0; c < device->num_classes; ++c)
  5558     {
  5559       switch (device->classes[c]->type)
  5560         {
  5561         case XIScrollClass:
  5562           {
  5563             info = (XIScrollClassInfo *) device->classes[c];
  5564             xi_populate_scroll_valuator (xi_device, actual_valuator_count++,
  5565                                          info);
  5566             break;
  5567           }
  5568 
  5569         case XIValuatorClass:
  5570           {
  5571             valuator_info = (XIValuatorClassInfo *) device->classes[c];
  5572             tem = SAFE_ALLOCA (sizeof *tem);
  5573 
  5574             /* Avoid restoring bogus values if some driver
  5575                accidentally specifies relative values in scroll
  5576                valuator classes how the input extension spec says they
  5577                should be, but allow restoring values when a value is
  5578                set, which is how the input extension actually
  5579                behaves.  */
  5580 
  5581             if (valuator_info->value == 0.0
  5582                 && valuator_info->mode != XIModeAbsolute)
  5583               continue;
  5584 
  5585             tem->next = values;
  5586             tem->number = valuator_info->number;
  5587             tem->current_value = valuator_info->value;
  5588 
  5589             values = tem;
  5590             break;
  5591           }
  5592 
  5593 #ifdef HAVE_XINPUT2_2
  5594         case XITouchClass:
  5595           {
  5596             touch_info = (XITouchClassInfo *) device->classes[c];
  5597 
  5598             /* touch_info->mode indicates the coordinate space that
  5599                this device reports in its touch events.
  5600 
  5601                DirectTouch means that the device uses a coordinate
  5602                space that corresponds to locations on the screen.  It
  5603                is set by touch screen devices which are overlaid
  5604                over the raster itself.
  5605 
  5606                The other value (DependentTouch) means that the device
  5607                uses a separate abstract coordinate space corresponding
  5608                to its own surface.  Emacs ignores events from these
  5609                devices because it does not support recognizing touch
  5610                gestures from surfaces other than the screen.
  5611 
  5612                Master devices may report multiple touch classes for
  5613                attached slave devices, leaving the nature of touch
  5614                events they send ambiguous.  The problem of
  5615                discriminating between these events is bypassed
  5616                entirely through only processing touch events from the
  5617                slave devices where they originate.  */
  5618 
  5619             if (touch_info->mode == XIDirectTouch)
  5620               xi_device->direct_p = true;
  5621             else
  5622               xi_device->direct_p = false;
  5623           }
  5624 #endif /* HAVE_XINPUT2_2 */
  5625         default:
  5626           break;
  5627         }
  5628     }
  5629 
  5630   xi_device->scroll_valuator_count = actual_valuator_count;
  5631 
  5632   /* Now look through all the valuators whose values are already known
  5633      and populate our client-side records with their current
  5634      values.  */
  5635 
  5636   for (tem = values; values; values = values->next)
  5637     {
  5638       for (c = 0; c < xi_device->scroll_valuator_count; ++c)
  5639         {
  5640           if (xi_device->valuators[c].number == tem->number)
  5641             {
  5642               xi_device->valuators[c].invalid_p = false;
  5643               xi_device->valuators[c].current_value
  5644                 = tem->current_value;
  5645               xi_device->valuators[c].emacs_value = 0.0;
  5646             }
  5647         }
  5648     }
  5649 
  5650   SAFE_FREE ();
  5651 #endif /* HAVE_XINPUT2_1 */
  5652 }
  5653 
  5654 /* Populate our client-side record of all devices, which includes
  5655    basic information about the device and also touchscreen tracking
  5656    information and scroll valuators.
  5657 
  5658    Keeping track of scroll valuators is required in order to support
  5659    scroll wheels that report information in a fashion more detailed
  5660    than a single turn of a "step" in the wheel.
  5661 
  5662    When the input extension is being utilized, the states of the mouse
  5663    wheels on each axis are stored as absolute values inside
  5664    "valuators" attached to each mouse device.  To obtain the delta of
  5665    the scroll wheel from a motion event (which is used to report that
  5666    some valuator has changed), it is necessary to iterate over every
  5667    valuator that changed, and compare its previous value to the
  5668    current value of the valuator.
  5669 
  5670    Each individual valuator also has an "interval", which is the
  5671    amount you must divide that delta by in order to obtain a delta in
  5672    the terms of scroll units.
  5673 
  5674    This delta however is still intermediate, to make driver
  5675    implementations easier.  The XInput developers recommend (and most
  5676    programs use) the following algorithm to convert from scroll unit
  5677    deltas to pixel deltas by which the display must actually be
  5678    scrolled:
  5679 
  5680      pixels_scrolled = pow (window_height, 2.0 / 3.0) * delta;  */
  5681 
  5682 static void
  5683 x_cache_xi_devices (struct x_display_info *dpyinfo)
  5684 {
  5685   int ndevices, actual_devices, i;
  5686   XIDeviceInfo *infos;
  5687 
  5688   actual_devices = 0;
  5689   block_input ();
  5690   x_free_xi_devices (dpyinfo);
  5691   infos = XIQueryDevice (dpyinfo->display,
  5692                          XIAllDevices,
  5693                          &ndevices);
  5694 
  5695   if (!ndevices)
  5696     {
  5697       XIFreeDeviceInfo (infos);
  5698       unblock_input ();
  5699       return;
  5700     }
  5701 
  5702   dpyinfo->devices = xzalloc (sizeof *dpyinfo->devices * ndevices);
  5703 
  5704   for (i = 0; i < ndevices; ++i)
  5705     {
  5706       if (infos[i].enabled)
  5707         xi_populate_device_from_info (dpyinfo,
  5708                                       &dpyinfo->devices[actual_devices++],
  5709                                       &infos[i]);
  5710     }
  5711 
  5712   dpyinfo->num_devices = actual_devices;
  5713   XIFreeDeviceInfo (infos);
  5714   unblock_input ();
  5715 }
  5716 
  5717 #ifdef HAVE_XINPUT2_1
  5718 /* Return the delta of the scroll valuator VALUATOR_NUMBER under
  5719    DEVICE in the display DPYINFO with VALUE.  The valuator's valuator
  5720    will be set to VALUE afterwards.  In case no scroll valuator is
  5721    found, or if the valuator state is invalid (see the comment under
  5722    XI_Enter in handle_one_xevent).  Otherwise, the valuator is
  5723    returned in VALUATOR_RETURN.  */
  5724 static double
  5725 x_get_scroll_valuator_delta (struct x_display_info *dpyinfo,
  5726                              struct xi_device_t *device,
  5727                              int valuator_number, double value,
  5728                              struct xi_scroll_valuator_t **valuator_return)
  5729 {
  5730   struct xi_scroll_valuator_t *sv;
  5731   double delta;
  5732   int i;
  5733 
  5734   for (i = 0; i < device->scroll_valuator_count; ++i)
  5735     {
  5736       sv = &device->valuators[i];
  5737 
  5738       if (sv->number == valuator_number)
  5739         {
  5740           *valuator_return = sv;
  5741 
  5742           if (sv->increment == 0)
  5743             return DBL_MAX;
  5744 
  5745           if (sv->invalid_p)
  5746             {
  5747               sv->current_value = value;
  5748               sv->invalid_p = false;
  5749 
  5750               return DBL_MAX;
  5751             }
  5752           else
  5753             {
  5754               delta = (sv->current_value - value) / sv->increment;
  5755               sv->current_value = value;
  5756 
  5757               return delta;
  5758             }
  5759         }
  5760     }
  5761 
  5762   *valuator_return = NULL;
  5763   return DBL_MAX;
  5764 }
  5765 
  5766 #endif
  5767 
  5768 struct xi_device_t *
  5769 xi_device_from_id (struct x_display_info *dpyinfo, int deviceid)
  5770 {
  5771   for (int i = 0; i < dpyinfo->num_devices; ++i)
  5772     {
  5773       if (dpyinfo->devices[i].device_id == deviceid)
  5774         return &dpyinfo->devices[i];
  5775     }
  5776 
  5777   return NULL;
  5778 }
  5779 
  5780 #ifdef HAVE_XINPUT2_2
  5781 
  5782 /* Record a touch sequence with the identifier DETAIL from the given
  5783    FRAME on the specified DEVICE.  Round X and Y and record them as
  5784    its current position.  */
  5785 
  5786 static void
  5787 xi_link_touch_point (struct xi_device_t *device,
  5788                      int detail, double x, double y,
  5789                      struct frame *frame)
  5790 {
  5791   struct xi_touch_point_t *touchpoint;
  5792 
  5793   touchpoint = xmalloc (sizeof *touchpoint);
  5794   touchpoint->next = device->touchpoints;
  5795   touchpoint->x = lrint (x);
  5796   touchpoint->y = lrint (y);
  5797   touchpoint->number = detail;
  5798   touchpoint->frame = frame;
  5799   touchpoint->ownership = TOUCH_OWNERSHIP_NONE;
  5800 
  5801   device->touchpoints = touchpoint;
  5802 }
  5803 
  5804 /* Free and remove the touch sequence with the identifier DETAIL.
  5805    DEVICE is the device in which the touch sequence should be
  5806    recorded.
  5807 
  5808    Value is 0 if no touch sequence by that identifier exists inside
  5809    DEVICE, 1 if a touch sequence has been found but is not owned by
  5810    Emacs, and 2 otherwise.  */
  5811 
  5812 static int
  5813 xi_unlink_touch_point (int detail, struct xi_device_t *device)
  5814 {
  5815   struct xi_touch_point_t *last, *tem;
  5816   enum xi_touch_ownership ownership;
  5817 
  5818   for (last = NULL, tem = device->touchpoints; tem;
  5819        last = tem, tem = tem->next)
  5820     {
  5821       if (tem->number == detail)
  5822         {
  5823           if (!last)
  5824             device->touchpoints = tem->next;
  5825           else
  5826             last->next = tem->next;
  5827 
  5828           ownership = tem->ownership;
  5829           xfree (tem);
  5830 
  5831           if (ownership == TOUCH_OWNERSHIP_SELF)
  5832             return 2;
  5833 
  5834           return 1;
  5835         }
  5836     }
  5837 
  5838   return 0;
  5839 }
  5840 
  5841 /* Unlink all touch points associated with the frame F.
  5842    This is done upon unmapping or destroying F's window, because
  5843    touch point delivery after that point is undefined.  */
  5844 
  5845 static void
  5846 xi_unlink_touch_points (struct frame *f)
  5847 {
  5848   struct xi_device_t *device;
  5849   struct xi_touch_point_t **next, *last;
  5850   int i;
  5851 
  5852   for (i = 0; i < FRAME_DISPLAY_INFO (f)->num_devices; ++i)
  5853     {
  5854       device = &FRAME_DISPLAY_INFO (f)->devices[i];
  5855 
  5856       /* Now unlink all touch points on DEVICE matching F.  */
  5857 
  5858       for (next = &device->touchpoints; (last = *next);)
  5859         {
  5860           if (last->frame == f)
  5861             {
  5862               *next = last->next;
  5863               xfree (last);
  5864             }
  5865           else
  5866             next = &last->next;
  5867         }
  5868     }
  5869 }
  5870 
  5871 /* Return the data associated with a touch sequence DETAIL recorded by
  5872    `xi_link_touch_point' from DEVICE, or NULL if it can't be
  5873    found.  */
  5874 
  5875 static struct xi_touch_point_t *
  5876 xi_find_touch_point (struct xi_device_t *device, int detail)
  5877 {
  5878   struct xi_touch_point_t *point;
  5879 
  5880   for (point = device->touchpoints; point; point = point->next)
  5881     {
  5882       if (point->number == detail)
  5883         return point;
  5884     }
  5885 
  5886   return NULL;
  5887 }
  5888 
  5889 #endif /* HAVE_XINPUT2_2 */
  5890 
  5891 #ifdef HAVE_XINPUT2_1
  5892 
  5893 static void
  5894 xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo,
  5895                                          int id)
  5896 {
  5897   struct xi_device_t *device;
  5898   struct xi_scroll_valuator_t *valuator;
  5899   int i;
  5900 
  5901   device = xi_device_from_id (dpyinfo, id);
  5902 
  5903   if (!device)
  5904     return;
  5905 
  5906   if (!device->scroll_valuator_count)
  5907     return;
  5908 
  5909   for (i = 0; i < device->scroll_valuator_count; ++i)
  5910     {
  5911       valuator = &device->valuators[i];
  5912       valuator->invalid_p = true;
  5913       valuator->emacs_value = 0.0;
  5914     }
  5915 
  5916   return;
  5917 }
  5918 
  5919 #endif /* HAVE_XINPUT2_1 */
  5920 
  5921 #endif
  5922 
  5923 #ifdef USE_CAIRO
  5924 
  5925 void
  5926 x_cr_destroy_frame_context (struct frame *f)
  5927 {
  5928   if (FRAME_CR_CONTEXT (f))
  5929     {
  5930       cairo_destroy (FRAME_CR_CONTEXT (f));
  5931       FRAME_CR_CONTEXT (f) = NULL;
  5932     }
  5933 }
  5934 
  5935 void
  5936 x_cr_update_surface_desired_size (struct frame *f, int width, int height)
  5937 {
  5938   if (FRAME_CR_SURFACE_DESIRED_WIDTH (f) != width
  5939       || FRAME_CR_SURFACE_DESIRED_HEIGHT (f) != height)
  5940     {
  5941       x_cr_destroy_frame_context (f);
  5942       FRAME_CR_SURFACE_DESIRED_WIDTH (f) = width;
  5943       FRAME_CR_SURFACE_DESIRED_HEIGHT (f) = height;
  5944     }
  5945 }
  5946 
  5947 static void
  5948 x_cr_gc_clip (cairo_t *cr, struct frame *f, GC gc)
  5949 {
  5950   if (gc)
  5951     {
  5952       struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
  5953 
  5954       if (gc_ext && gc_ext->n_clip_rects)
  5955         {
  5956           for (int i = 0; i < gc_ext->n_clip_rects; i++)
  5957             cairo_rectangle (cr, gc_ext->clip_rects[i].x,
  5958                              gc_ext->clip_rects[i].y,
  5959                              gc_ext->clip_rects[i].width,
  5960                              gc_ext->clip_rects[i].height);
  5961           cairo_clip (cr);
  5962         }
  5963     }
  5964 }
  5965 
  5966 cairo_t *
  5967 x_begin_cr_clip (struct frame *f, GC gc)
  5968 {
  5969   cairo_t *cr = FRAME_CR_CONTEXT (f);
  5970 
  5971   if (!cr)
  5972     {
  5973       int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
  5974       int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f);
  5975       cairo_surface_t *surface;
  5976 #ifdef USE_CAIRO_XCB_SURFACE
  5977       if (FRAME_DISPLAY_INFO (f)->xcb_visual)
  5978         surface = cairo_xcb_surface_create (FRAME_DISPLAY_INFO (f)->xcb_connection,
  5979                                             (xcb_drawable_t) FRAME_X_RAW_DRAWABLE (f),
  5980                                             FRAME_DISPLAY_INFO (f)->xcb_visual,
  5981                                             width, height);
  5982       else
  5983 #endif
  5984         surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
  5985                                              FRAME_X_RAW_DRAWABLE (f),
  5986                                              FRAME_X_VISUAL (f),
  5987                                              width, height);
  5988 
  5989       cr = FRAME_CR_CONTEXT (f) = cairo_create (surface);
  5990       cairo_surface_destroy (surface);
  5991     }
  5992   cairo_save (cr);
  5993   x_cr_gc_clip (cr, f, gc);
  5994 
  5995   return cr;
  5996 }
  5997 
  5998 void
  5999 x_end_cr_clip (struct frame *f)
  6000 {
  6001   cairo_restore (FRAME_CR_CONTEXT (f));
  6002 #ifdef HAVE_XDBE
  6003   if (FRAME_X_DOUBLE_BUFFERED_P (f))
  6004     x_mark_frame_dirty (f);
  6005 #endif
  6006 }
  6007 
  6008 void
  6009 x_set_cr_source_with_gc_foreground (struct frame *f, GC gc,
  6010                                     bool respect_alpha_background)
  6011 {
  6012   XGCValues xgcv;
  6013   XColor color;
  6014   unsigned int depth;
  6015 
  6016   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
  6017   color.pixel = xgcv.foreground;
  6018   x_query_colors (f, &color, 1);
  6019   depth = FRAME_DISPLAY_INFO (f)->n_planes;
  6020 
  6021   if (f->alpha_background < 1.0 && depth == 32
  6022       && respect_alpha_background)
  6023     {
  6024       cairo_set_source_rgba (FRAME_CR_CONTEXT (f), color.red / 65535.0,
  6025                              color.green / 65535.0, color.blue / 65535.0,
  6026                              f->alpha_background);
  6027 
  6028       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_SOURCE);
  6029     }
  6030   else
  6031     {
  6032       cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
  6033                             color.green / 65535.0, color.blue / 65535.0);
  6034       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_OVER);
  6035     }
  6036 }
  6037 
  6038 void
  6039 x_set_cr_source_with_gc_background (struct frame *f, GC gc,
  6040                                     bool respect_alpha_background)
  6041 {
  6042   XGCValues xgcv;
  6043   XColor color;
  6044   unsigned int depth;
  6045 
  6046   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
  6047   color.pixel = xgcv.background;
  6048 
  6049   x_query_colors (f, &color, 1);
  6050 
  6051   depth = FRAME_DISPLAY_INFO (f)->n_planes;
  6052 
  6053   if (f->alpha_background < 1.0 && depth == 32
  6054       && respect_alpha_background)
  6055     {
  6056       cairo_set_source_rgba (FRAME_CR_CONTEXT (f), color.red / 65535.0,
  6057                              color.green / 65535.0, color.blue / 65535.0,
  6058                              f->alpha_background);
  6059 
  6060       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_SOURCE);
  6061     }
  6062   else
  6063     {
  6064       cairo_set_source_rgb (FRAME_CR_CONTEXT (f), color.red / 65535.0,
  6065                             color.green / 65535.0, color.blue / 65535.0);
  6066       cairo_set_operator (FRAME_CR_CONTEXT (f), CAIRO_OPERATOR_OVER);
  6067     }
  6068 }
  6069 
  6070 static const cairo_user_data_key_t xlib_surface_key, saved_drawable_key;
  6071 
  6072 static void
  6073 x_cr_destroy_xlib_surface (cairo_surface_t *xlib_surface)
  6074 {
  6075   if (xlib_surface)
  6076     {
  6077       XFreePixmap (cairo_xlib_surface_get_display (xlib_surface),
  6078                    cairo_xlib_surface_get_drawable (xlib_surface));
  6079       cairo_surface_destroy (xlib_surface);
  6080     }
  6081 }
  6082 
  6083 static bool
  6084 x_try_cr_xlib_drawable (struct frame *f, GC gc)
  6085 {
  6086   cairo_t *cr = FRAME_CR_CONTEXT (f);
  6087   if (!cr)
  6088     return true;
  6089 
  6090   cairo_surface_t *surface = cairo_get_target (cr);
  6091   switch (cairo_surface_get_type (surface))
  6092     {
  6093     case CAIRO_SURFACE_TYPE_XLIB:
  6094 #ifdef USE_CAIRO_XCB_SURFACE
  6095     case CAIRO_SURFACE_TYPE_XCB:
  6096 #endif
  6097       cairo_surface_flush (surface);
  6098       return true;
  6099 
  6100     case CAIRO_SURFACE_TYPE_IMAGE:
  6101       break;
  6102 
  6103     default:
  6104       return false;
  6105     }
  6106 
  6107   /* FRAME_CR_CONTEXT (f) is an image surface we can not draw into
  6108      directly with Xlib.  Set up a Pixmap so we can copy back the
  6109      result later in x_end_cr_xlib_drawable.  */
  6110   cairo_surface_t *xlib_surface = cairo_get_user_data (cr, &xlib_surface_key);
  6111   int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
  6112   int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f);
  6113   Pixmap pixmap;
  6114   if (xlib_surface
  6115       && cairo_xlib_surface_get_width (xlib_surface) == width
  6116       && cairo_xlib_surface_get_height (xlib_surface) == height)
  6117     pixmap = cairo_xlib_surface_get_drawable (xlib_surface);
  6118   else
  6119     {
  6120       pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_RAW_DRAWABLE (f),
  6121                               width, height,
  6122                               DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
  6123       xlib_surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
  6124                                                 pixmap, FRAME_X_VISUAL (f),
  6125                                                 width, height);
  6126       cairo_set_user_data (cr, &xlib_surface_key, xlib_surface,
  6127                            (cairo_destroy_func_t) x_cr_destroy_xlib_surface);
  6128     }
  6129 
  6130   cairo_t *buf = cairo_create (xlib_surface);
  6131   cairo_set_source_surface (buf, surface, 0, 0);
  6132   cairo_matrix_t matrix;
  6133   cairo_get_matrix (cr, &matrix);
  6134   cairo_pattern_set_matrix (cairo_get_source (cr), &matrix);
  6135   cairo_set_operator (buf, CAIRO_OPERATOR_SOURCE);
  6136   x_cr_gc_clip (buf, f, gc);
  6137   cairo_paint (buf);
  6138   cairo_destroy (buf);
  6139 
  6140   cairo_set_user_data (cr, &saved_drawable_key,
  6141                        (void *) (uintptr_t) FRAME_X_RAW_DRAWABLE (f), NULL);
  6142   FRAME_X_RAW_DRAWABLE (f) = pixmap;
  6143   cairo_surface_flush (xlib_surface);
  6144 
  6145   return true;
  6146 }
  6147 
  6148 static void
  6149 x_end_cr_xlib_drawable (struct frame *f, GC gc)
  6150 {
  6151   cairo_t *cr = FRAME_CR_CONTEXT (f);
  6152   if (!cr)
  6153     return;
  6154 
  6155   Drawable saved_drawable
  6156     = (uintptr_t) cairo_get_user_data (cr, &saved_drawable_key);
  6157   cairo_surface_t *surface = (saved_drawable
  6158                               ? cairo_get_user_data (cr, &xlib_surface_key)
  6159                               : cairo_get_target (cr));
  6160   struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
  6161   if (gc_ext && gc_ext->n_clip_rects)
  6162     for (int i = 0; i < gc_ext->n_clip_rects; i++)
  6163       cairo_surface_mark_dirty_rectangle (surface, gc_ext->clip_rects[i].x,
  6164                                           gc_ext->clip_rects[i].y,
  6165                                           gc_ext->clip_rects[i].width,
  6166                                           gc_ext->clip_rects[i].height);
  6167   else
  6168     cairo_surface_mark_dirty (surface);
  6169   if (!saved_drawable)
  6170     return;
  6171 
  6172   cairo_save (cr);
  6173   cairo_set_source_surface (cr, surface, 0, 0);
  6174   cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
  6175   x_cr_gc_clip (cr, f, gc);
  6176   cairo_paint (cr);
  6177   cairo_restore (cr);
  6178 
  6179   FRAME_X_RAW_DRAWABLE (f) = saved_drawable;
  6180   cairo_set_user_data (cr, &saved_drawable_key, NULL, NULL);
  6181 }
  6182 
  6183 /* Fringe bitmaps.  */
  6184 
  6185 static int max_fringe_bmp = 0;
  6186 static cairo_pattern_t **fringe_bmp = 0;
  6187 
  6188 static void
  6189 x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
  6190 {
  6191   int i, stride;
  6192   cairo_surface_t *surface;
  6193   cairo_pattern_t *pattern;
  6194   unsigned char *data;
  6195 
  6196   if (which >= max_fringe_bmp)
  6197     {
  6198       i = max_fringe_bmp;
  6199       max_fringe_bmp = which + 20;
  6200       fringe_bmp = xrealloc (fringe_bmp, max_fringe_bmp * sizeof (*fringe_bmp));
  6201       while (i < max_fringe_bmp)
  6202         fringe_bmp[i++] = 0;
  6203     }
  6204 
  6205   block_input ();
  6206 
  6207   surface = cairo_image_surface_create (CAIRO_FORMAT_A1, wd, h);
  6208   stride = cairo_image_surface_get_stride (surface);
  6209   data = cairo_image_surface_get_data (surface);
  6210 
  6211   for (i = 0; i < h; i++)
  6212     {
  6213       *((unsigned short *) data) = bits[i];
  6214       data += stride;
  6215     }
  6216 
  6217   cairo_surface_mark_dirty (surface);
  6218   pattern = cairo_pattern_create_for_surface (surface);
  6219   cairo_surface_destroy (surface);
  6220 
  6221   unblock_input ();
  6222 
  6223   fringe_bmp[which] = pattern;
  6224 }
  6225 
  6226 static void
  6227 x_cr_destroy_fringe_bitmap (int which)
  6228 {
  6229   if (which >= max_fringe_bmp)
  6230     return;
  6231 
  6232   if (fringe_bmp[which])
  6233     {
  6234       block_input ();
  6235       cairo_pattern_destroy (fringe_bmp[which]);
  6236       unblock_input ();
  6237     }
  6238   fringe_bmp[which] = 0;
  6239 }
  6240 
  6241 static void
  6242 x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
  6243                  int src_x, int src_y, int width, int height,
  6244                  int dest_x, int dest_y, bool overlay_p)
  6245 {
  6246   cairo_t *cr = x_begin_cr_clip (f, gc);
  6247 
  6248   if (overlay_p)
  6249     cairo_rectangle (cr, dest_x, dest_y, width, height);
  6250   else
  6251     {
  6252       x_set_cr_source_with_gc_background (f, gc, false);
  6253       cairo_rectangle (cr, dest_x, dest_y, width, height);
  6254       cairo_fill_preserve (cr);
  6255     }
  6256 
  6257   cairo_translate (cr, dest_x - src_x, dest_y - src_y);
  6258 
  6259   cairo_surface_t *surface;
  6260   cairo_pattern_get_surface (image, &surface);
  6261   cairo_format_t format = cairo_image_surface_get_format (surface);
  6262   if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
  6263     {
  6264       cairo_set_source (cr, image);
  6265       cairo_fill (cr);
  6266     }
  6267   else
  6268     {
  6269       x_set_cr_source_with_gc_foreground (f, gc, false);
  6270       cairo_clip (cr);
  6271       cairo_mask (cr, image);
  6272     }
  6273 
  6274   x_end_cr_clip (f);
  6275 }
  6276 
  6277 void
  6278 x_cr_draw_frame (cairo_t *cr, struct frame *f)
  6279 {
  6280   int width, height;
  6281 
  6282   width = FRAME_PIXEL_WIDTH (f);
  6283   height = FRAME_PIXEL_HEIGHT (f);
  6284 
  6285   cairo_t *saved_cr = FRAME_CR_CONTEXT (f);
  6286   FRAME_CR_CONTEXT (f) = cr;
  6287   x_clear_area (f, 0, 0, width, height);
  6288   expose_frame (f, 0, 0, width, height);
  6289   FRAME_CR_CONTEXT (f) = saved_cr;
  6290 }
  6291 
  6292 static cairo_status_t
  6293 x_cr_accumulate_data (void *closure, const unsigned char *data,
  6294                       unsigned int length)
  6295 {
  6296   Lisp_Object *acc = (Lisp_Object *) closure;
  6297 
  6298   *acc = Fcons (make_unibyte_string ((char const *) data, length), *acc);
  6299 
  6300   return CAIRO_STATUS_SUCCESS;
  6301 }
  6302 
  6303 static void
  6304 x_cr_destroy (void *cr)
  6305 {
  6306   block_input ();
  6307   cairo_destroy (cr);
  6308   unblock_input ();
  6309 }
  6310 
  6311 Lisp_Object
  6312 x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
  6313 {
  6314   struct frame *f;
  6315   cairo_surface_t *surface;
  6316   cairo_t *cr;
  6317   int width, height;
  6318   void (*surface_set_size_func) (cairo_surface_t *, double, double) = NULL;
  6319   Lisp_Object acc = Qnil;
  6320   specpdl_ref count = SPECPDL_INDEX ();
  6321 
  6322   specbind (Qredisplay_dont_pause, Qt);
  6323   redisplay_preserve_echo_area (31);
  6324 
  6325   f = XFRAME (XCAR (frames));
  6326   frames = XCDR (frames);
  6327   width = FRAME_PIXEL_WIDTH (f);
  6328   height = FRAME_PIXEL_HEIGHT (f);
  6329 
  6330   block_input ();
  6331 #ifdef CAIRO_HAS_PDF_SURFACE
  6332   if (surface_type == CAIRO_SURFACE_TYPE_PDF)
  6333     {
  6334       surface = cairo_pdf_surface_create_for_stream (x_cr_accumulate_data, &acc,
  6335                                                      width, height);
  6336       surface_set_size_func = cairo_pdf_surface_set_size;
  6337     }
  6338   else
  6339 #endif
  6340 #ifdef CAIRO_HAS_PNG_FUNCTIONS
  6341   if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
  6342     surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
  6343   else
  6344 #endif
  6345 #ifdef CAIRO_HAS_PS_SURFACE
  6346   if (surface_type == CAIRO_SURFACE_TYPE_PS)
  6347     {
  6348       surface = cairo_ps_surface_create_for_stream (x_cr_accumulate_data, &acc,
  6349                                                     width, height);
  6350       surface_set_size_func = cairo_ps_surface_set_size;
  6351     }
  6352   else
  6353 #endif
  6354 #ifdef CAIRO_HAS_SVG_SURFACE
  6355   if (surface_type == CAIRO_SURFACE_TYPE_SVG)
  6356     surface = cairo_svg_surface_create_for_stream (x_cr_accumulate_data, &acc,
  6357                                                    width, height);
  6358   else
  6359 #endif
  6360     abort ();
  6361 
  6362   cr = cairo_create (surface);
  6363   cairo_surface_destroy (surface);
  6364   record_unwind_protect_ptr (x_cr_destroy, cr);
  6365 
  6366   while (1)
  6367     {
  6368       cairo_t *saved_cr = FRAME_CR_CONTEXT (f);
  6369       FRAME_CR_CONTEXT (f) = cr;
  6370       x_clear_area (f, 0, 0, width, height);
  6371       expose_frame (f, 0, 0, width, height);
  6372       FRAME_CR_CONTEXT (f) = saved_cr;
  6373 
  6374       if (NILP (frames))
  6375         break;
  6376 
  6377       cairo_surface_show_page (surface);
  6378       f = XFRAME (XCAR (frames));
  6379       frames = XCDR (frames);
  6380       width = FRAME_PIXEL_WIDTH (f);
  6381       height = FRAME_PIXEL_HEIGHT (f);
  6382       if (surface_set_size_func)
  6383         (*surface_set_size_func) (surface, width, height);
  6384 
  6385       unblock_input ();
  6386       maybe_quit ();
  6387       block_input ();
  6388     }
  6389 
  6390 #ifdef CAIRO_HAS_PNG_FUNCTIONS
  6391   if (surface_type == CAIRO_SURFACE_TYPE_IMAGE)
  6392     {
  6393       cairo_surface_flush (surface);
  6394       cairo_surface_write_to_png_stream (surface, x_cr_accumulate_data, &acc);
  6395     }
  6396 #endif
  6397   unblock_input ();
  6398 
  6399   unbind_to (count, Qnil);
  6400 
  6401   return CALLN (Fapply, Qconcat, Fnreverse (acc));
  6402 }
  6403 
  6404 #endif  /* USE_CAIRO */
  6405 
  6406 #if defined HAVE_XRENDER
  6407 void
  6408 x_xr_apply_ext_clip (struct frame *f, GC gc)
  6409 {
  6410   eassert (FRAME_X_PICTURE (f) != None);
  6411 
  6412   struct x_gc_ext_data *data = x_gc_get_ext_data (f, gc, 1);
  6413 
  6414   if (data->n_clip_rects)
  6415     XRenderSetPictureClipRectangles (FRAME_X_DISPLAY (f),
  6416                                      FRAME_X_PICTURE (f),
  6417                                      0, 0, data->clip_rects,
  6418                                      data->n_clip_rects);
  6419 }
  6420 
  6421 void
  6422 x_xr_reset_ext_clip (struct frame *f)
  6423 {
  6424   XRenderPictureAttributes attrs = { .clip_mask = None };
  6425 
  6426   XRenderChangePicture (FRAME_X_DISPLAY (f),
  6427                         FRAME_X_PICTURE (f),
  6428                         CPClipMask, &attrs);
  6429 }
  6430 #endif
  6431 
  6432 static void
  6433 x_set_clip_rectangles (struct frame *f, GC gc, XRectangle *rectangles, int n)
  6434 {
  6435   XSetClipRectangles (FRAME_X_DISPLAY (f), gc, 0, 0, rectangles, n, Unsorted);
  6436 #if defined USE_CAIRO || defined HAVE_XRENDER
  6437   eassert (n >= 0 && n <= MAX_CLIP_RECTS);
  6438 
  6439   {
  6440     struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 1);
  6441 
  6442     gc_ext->n_clip_rects = n;
  6443     memcpy (gc_ext->clip_rects, rectangles, sizeof (XRectangle) * n);
  6444   }
  6445 #endif
  6446 }
  6447 
  6448 static void
  6449 x_reset_clip_rectangles (struct frame *f, GC gc)
  6450 {
  6451   XSetClipMask (FRAME_X_DISPLAY (f), gc, None);
  6452 #if defined USE_CAIRO || defined HAVE_XRENDER
  6453   {
  6454     struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0);
  6455 
  6456     if (gc_ext)
  6457       gc_ext->n_clip_rects = 0;
  6458   }
  6459 #endif
  6460 }
  6461 
  6462 #ifdef HAVE_XRENDER
  6463 # if !defined USE_CAIRO && (RENDER_MAJOR > 0 || RENDER_MINOR >= 2)
  6464 static void
  6465 x_xrender_color_from_gc_foreground (struct frame *f, GC gc, XRenderColor *color,
  6466                                     bool apply_alpha_background)
  6467 {
  6468   XGCValues xgcv;
  6469   XColor xc;
  6470 
  6471   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCForeground, &xgcv);
  6472   xc.pixel = xgcv.foreground;
  6473   x_query_colors (f, &xc, 1);
  6474 
  6475   color->alpha = (apply_alpha_background
  6476                   ? 65535 * f->alpha_background
  6477                   : 65535);
  6478 
  6479   if (color->alpha == 65535)
  6480     {
  6481       color->red = xc.red;
  6482       color->blue = xc.blue;
  6483       color->green = xc.green;
  6484     }
  6485   else
  6486     {
  6487       color->red = (xc.red * color->alpha) / 65535;
  6488       color->blue = (xc.blue * color->alpha) / 65535;
  6489       color->green = (xc.green * color->alpha) / 65535;
  6490     }
  6491 }
  6492 # endif
  6493 
  6494 void
  6495 x_xrender_color_from_gc_background (struct frame *f, GC gc, XRenderColor *color,
  6496                                     bool apply_alpha_background)
  6497 {
  6498   XGCValues xgcv;
  6499   XColor xc;
  6500 
  6501   XGetGCValues (FRAME_X_DISPLAY (f), gc, GCBackground, &xgcv);
  6502   xc.pixel = xgcv.background;
  6503   x_query_colors (f, &xc, 1);
  6504 
  6505   color->alpha = (apply_alpha_background
  6506                   ? 65535 * f->alpha_background
  6507                   : 65535);
  6508 
  6509   if (color->alpha == 65535)
  6510     {
  6511       color->red = xc.red;
  6512       color->blue = xc.blue;
  6513       color->green = xc.green;
  6514     }
  6515   else
  6516     {
  6517       color->red = (xc.red * color->alpha) / 65535;
  6518       color->blue = (xc.blue * color->alpha) / 65535;
  6519       color->green = (xc.green * color->alpha) / 65535;
  6520     }
  6521 }
  6522 #endif
  6523 
  6524 static void
  6525 x_fill_rectangle (struct frame *f, GC gc, int x, int y, int width, int height,
  6526                   bool respect_alpha_background)
  6527 {
  6528 #ifdef USE_CAIRO
  6529   Display *dpy = FRAME_X_DISPLAY (f);
  6530   cairo_t *cr;
  6531   XGCValues xgcv;
  6532 
  6533   cr = x_begin_cr_clip (f, gc);
  6534   XGetGCValues (dpy, gc, GCFillStyle | GCStipple, &xgcv);
  6535   if (xgcv.fill_style == FillSolid
  6536       /* Invalid resource ID (one or more of the three most
  6537          significant bits set to 1) is obtained if the GCStipple
  6538          component has never been explicitly set.  It should be
  6539          regarded as Pixmap of unspecified size filled with ones.  */
  6540       || (xgcv.stipple & ((Pixmap) 7 << (sizeof (Pixmap) * CHAR_BIT - 3))))
  6541     {
  6542       x_set_cr_source_with_gc_foreground (f, gc, respect_alpha_background);
  6543       cairo_rectangle (cr, x, y, width, height);
  6544       cairo_fill (cr);
  6545     }
  6546   else
  6547     {
  6548       eassert (xgcv.fill_style == FillOpaqueStippled);
  6549       eassert (xgcv.stipple != None);
  6550       x_set_cr_source_with_gc_background (f, gc, respect_alpha_background);
  6551       cairo_rectangle (cr, x, y, width, height);
  6552       cairo_fill_preserve (cr);
  6553 
  6554       cairo_pattern_t *pattern = x_bitmap_stipple (f, xgcv.stipple);
  6555       if (pattern)
  6556         {
  6557           x_set_cr_source_with_gc_foreground (f, gc, respect_alpha_background);
  6558           cairo_clip (cr);
  6559           cairo_mask (cr, pattern);
  6560         }
  6561     }
  6562   x_end_cr_clip (f);
  6563 #else
  6564 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
  6565   if (respect_alpha_background
  6566       && f->alpha_background != 1.0
  6567       && FRAME_DISPLAY_INFO (f)->alpha_bits
  6568       && FRAME_CHECK_XR_VERSION (f, 0, 2))
  6569     {
  6570       x_xr_ensure_picture (f);
  6571 
  6572       if (FRAME_X_PICTURE (f) != None)
  6573         {
  6574           XRenderColor xc;
  6575 
  6576 #if RENDER_MAJOR > 0 || (RENDER_MINOR >= 10)
  6577           XGCValues xgcv;
  6578           XRenderPictureAttributes attrs;
  6579           XRenderColor alpha;
  6580           Picture stipple, fill;
  6581 #endif
  6582 
  6583           x_xr_apply_ext_clip (f, gc);
  6584 
  6585 #if RENDER_MAJOR > 0 || (RENDER_MINOR >= 10)
  6586           XGetGCValues (FRAME_X_DISPLAY (f),
  6587                         gc, GCFillStyle | GCStipple, &xgcv);
  6588 
  6589           if (xgcv.fill_style == FillOpaqueStippled
  6590               && FRAME_CHECK_XR_VERSION (f, 0, 10))
  6591             {
  6592               x_xrender_color_from_gc_background (f, gc, &alpha, true);
  6593               x_xrender_color_from_gc_foreground (f, gc, &xc, true);
  6594               attrs.repeat = RepeatNormal;
  6595 
  6596               stipple = XRenderCreatePicture (FRAME_X_DISPLAY (f),
  6597                                               xgcv.stipple,
  6598                                               XRenderFindStandardFormat (FRAME_X_DISPLAY (f),
  6599                                                                          PictStandardA1),
  6600                                               CPRepeat, &attrs);
  6601 
  6602               XRenderFillRectangle (FRAME_X_DISPLAY (f), PictOpSrc,
  6603                                     FRAME_X_PICTURE (f),
  6604                                     &alpha, x, y, width, height);
  6605 
  6606               fill = XRenderCreateSolidFill (FRAME_X_DISPLAY (f), &xc);
  6607 
  6608               XRenderComposite (FRAME_X_DISPLAY (f), PictOpOver, fill, stipple,
  6609                                 FRAME_X_PICTURE (f), 0, 0, x, y, x, y, width, height);
  6610 
  6611               XRenderFreePicture (FRAME_X_DISPLAY (f), stipple);
  6612               XRenderFreePicture (FRAME_X_DISPLAY (f), fill);
  6613             }
  6614           else
  6615 #endif
  6616             {
  6617               x_xrender_color_from_gc_foreground (f, gc, &xc, true);
  6618               XRenderFillRectangle (FRAME_X_DISPLAY (f),
  6619                                     PictOpSrc, FRAME_X_PICTURE (f),
  6620                                     &xc, x, y, width, height);
  6621             }
  6622           x_xr_reset_ext_clip (f);
  6623           x_mark_frame_dirty (f);
  6624 
  6625           return;
  6626         }
  6627     }
  6628 #endif
  6629   XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  6630                   gc, x, y, width, height);
  6631 #endif
  6632 }
  6633 
  6634 
  6635 static void
  6636 x_clear_rectangle (struct frame *f, GC gc, int x, int y, int width, int height,
  6637                    bool respect_alpha_background)
  6638 {
  6639 #ifdef USE_CAIRO
  6640   cairo_t *cr;
  6641 
  6642   cr = x_begin_cr_clip (f, gc);
  6643   x_set_cr_source_with_gc_background (f, gc, respect_alpha_background);
  6644   cairo_rectangle (cr, x, y, width, height);
  6645   cairo_fill (cr);
  6646   x_end_cr_clip (f);
  6647 #else
  6648 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
  6649   if (respect_alpha_background
  6650       && f->alpha_background != 1.0
  6651       && FRAME_DISPLAY_INFO (f)->alpha_bits
  6652       && FRAME_CHECK_XR_VERSION (f, 0, 2))
  6653     {
  6654       x_xr_ensure_picture (f);
  6655 
  6656       if (FRAME_X_PICTURE (f) != None)
  6657         {
  6658           XRenderColor xc;
  6659 
  6660           x_xr_apply_ext_clip (f, gc);
  6661           x_xrender_color_from_gc_background (f, gc, &xc, true);
  6662           XRenderFillRectangle (FRAME_X_DISPLAY (f),
  6663                                 PictOpSrc, FRAME_X_PICTURE (f),
  6664                                 &xc, x, y, width, height);
  6665           x_xr_reset_ext_clip (f);
  6666           x_mark_frame_dirty (f);
  6667 
  6668           return;
  6669         }
  6670     }
  6671 #endif
  6672 
  6673   XGCValues xgcv;
  6674   Display *dpy = FRAME_X_DISPLAY (f);
  6675   XGetGCValues (dpy, gc, GCBackground | GCForeground, &xgcv);
  6676   XSetForeground (dpy, gc, xgcv.background);
  6677   XFillRectangle (dpy, FRAME_X_DRAWABLE (f),
  6678                   gc, x, y, width, height);
  6679   XSetForeground (dpy, gc, xgcv.foreground);
  6680 #endif
  6681 }
  6682 
  6683 static void
  6684 x_draw_rectangle (struct frame *f, GC gc, int x, int y, int width, int height)
  6685 {
  6686 #ifdef USE_CAIRO
  6687   cairo_t *cr;
  6688 
  6689   cr = x_begin_cr_clip (f, gc);
  6690   x_set_cr_source_with_gc_foreground (f, gc, false);
  6691   cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
  6692   cairo_set_line_width (cr, 1);
  6693   cairo_stroke (cr);
  6694   x_end_cr_clip (f);
  6695 #else
  6696   XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  6697                   gc, x, y, width, height);
  6698 #endif
  6699 }
  6700 
  6701 static void
  6702 x_clear_window (struct frame *f)
  6703 {
  6704 #ifdef USE_CAIRO
  6705   cairo_t *cr;
  6706 
  6707   cr = x_begin_cr_clip (f, NULL);
  6708   x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc, true);
  6709   cairo_paint (cr);
  6710   x_end_cr_clip (f);
  6711 #else
  6712 #ifndef USE_GTK
  6713   if (f->alpha_background != 1.0
  6714 #ifdef HAVE_XDBE
  6715       || FRAME_X_DOUBLE_BUFFERED_P (f)
  6716 #endif
  6717       )
  6718 #endif
  6719     x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f),
  6720                   FRAME_PIXEL_HEIGHT (f));
  6721 #ifndef USE_GTK
  6722   else
  6723     XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
  6724 #endif
  6725 #endif
  6726 }
  6727 
  6728 #ifdef USE_CAIRO
  6729 static void
  6730 x_fill_trapezoid_for_relief (struct frame *f, GC gc, int x, int y,
  6731                              int width, int height, int top_p)
  6732 {
  6733   cairo_t *cr;
  6734 
  6735   cr = x_begin_cr_clip (f, gc);
  6736   x_set_cr_source_with_gc_foreground (f, gc, false);
  6737   cairo_move_to (cr, top_p ? x : x + height, y);
  6738   cairo_line_to (cr, x, y + height);
  6739   cairo_line_to (cr, top_p ? x + width - height : x + width, y + height);
  6740   cairo_line_to (cr, x + width, y);
  6741   cairo_fill (cr);
  6742   x_end_cr_clip (f);
  6743 }
  6744 
  6745 enum corners
  6746   {
  6747     CORNER_BOTTOM_RIGHT,        /* 0 -> pi/2 */
  6748     CORNER_BOTTOM_LEFT,         /* pi/2 -> pi */
  6749     CORNER_TOP_LEFT,            /* pi -> 3pi/2 */
  6750     CORNER_TOP_RIGHT,           /* 3pi/2 -> 2pi */
  6751     CORNER_LAST
  6752   };
  6753 
  6754 static void
  6755 x_erase_corners_for_relief (struct frame *f, GC gc, int x, int y,
  6756                             int width, int height,
  6757                             double radius, double margin, int corners)
  6758 {
  6759   cairo_t *cr;
  6760   int i;
  6761 
  6762   cr = x_begin_cr_clip (f, gc);
  6763   x_set_cr_source_with_gc_background (f, gc, false);
  6764   for (i = 0; i < CORNER_LAST; i++)
  6765     if (corners & (1 << i))
  6766       {
  6767         double xm, ym, xc, yc;
  6768 
  6769         if (i == CORNER_TOP_LEFT || i == CORNER_BOTTOM_LEFT)
  6770           xm = x - margin, xc = xm + radius;
  6771         else
  6772           xm = x + width + margin, xc = xm - radius;
  6773         if (i == CORNER_TOP_LEFT || i == CORNER_TOP_RIGHT)
  6774           ym = y - margin, yc = ym + radius;
  6775         else
  6776           ym = y + height + margin, yc = ym - radius;
  6777 
  6778         cairo_move_to (cr, xm, ym);
  6779         cairo_arc (cr, xc, yc, radius, i * M_PI_2, (i + 1) * M_PI_2);
  6780       }
  6781   cairo_clip (cr);
  6782   cairo_rectangle (cr, x, y, width, height);
  6783   cairo_fill (cr);
  6784   x_end_cr_clip (f);
  6785 }
  6786 
  6787 static void
  6788 x_draw_horizontal_wave (struct frame *f, GC gc, int x, int y,
  6789                         int width, int height, int wave_length)
  6790 {
  6791   cairo_t *cr;
  6792   double dx = wave_length, dy = height - 1;
  6793   int xoffset, n;
  6794 
  6795   cr = x_begin_cr_clip (f, gc);
  6796   x_set_cr_source_with_gc_foreground (f, gc, false);
  6797   cairo_rectangle (cr, x, y, width, height);
  6798   cairo_clip (cr);
  6799 
  6800   if (x >= 0)
  6801     {
  6802       xoffset = x % (wave_length * 2);
  6803       if (xoffset == 0)
  6804         xoffset = wave_length * 2;
  6805     }
  6806   else
  6807     xoffset = x % (wave_length * 2) + wave_length * 2;
  6808   n = (width + xoffset) / wave_length + 1;
  6809   if (xoffset > wave_length)
  6810     {
  6811       xoffset -= wave_length;
  6812       --n;
  6813       y += height - 1;
  6814       dy = -dy;
  6815     }
  6816 
  6817   cairo_move_to (cr, x - xoffset + 0.5, y + 0.5);
  6818   while (--n >= 0)
  6819     {
  6820       cairo_rel_line_to (cr, dx, dy);
  6821       dy = -dy;
  6822     }
  6823   cairo_set_line_width (cr, 1);
  6824   cairo_stroke (cr);
  6825   x_end_cr_clip (f);
  6826 }
  6827 #endif
  6828 
  6829 
  6830 /* Return the struct x_display_info corresponding to DPY.  */
  6831 
  6832 struct x_display_info *
  6833 x_display_info_for_display (Display *dpy)
  6834 {
  6835   struct x_display_info *dpyinfo;
  6836 
  6837   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
  6838     if (dpyinfo->display == dpy)
  6839       return dpyinfo;
  6840 
  6841   return 0;
  6842 }
  6843 
  6844 static Window
  6845 x_find_topmost_parent (struct frame *f)
  6846 {
  6847   struct x_output *x = f->output_data.x;
  6848   Window win = None, wi = x->parent_desc;
  6849   Display *dpy = FRAME_X_DISPLAY (f);
  6850 
  6851   while (wi != FRAME_DISPLAY_INFO (f)->root_window)
  6852     {
  6853       Window root;
  6854       Window *children;
  6855       unsigned int nchildren;
  6856 
  6857       win = wi;
  6858       if (XQueryTree (dpy, win, &root, &wi, &children, &nchildren))
  6859         XFree (children);
  6860       else
  6861         break;
  6862     }
  6863 
  6864   return win;
  6865 }
  6866 
  6867 #define OPAQUE  0xffffffff
  6868 
  6869 static void
  6870 x_set_frame_alpha (struct frame *f)
  6871 {
  6872   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  6873   Display *dpy = FRAME_X_DISPLAY (f);
  6874   Window win = FRAME_OUTER_WINDOW (f);
  6875   double alpha = 1.0;
  6876   double alpha_min = 1.0;
  6877   unsigned long opac;
  6878   Window parent;
  6879 
  6880   if (dpyinfo->highlight_frame == f)
  6881     alpha = f->alpha[0];
  6882   else
  6883     alpha = f->alpha[1];
  6884 
  6885   if (alpha < 0.0)
  6886     return;
  6887 
  6888   if (FLOATP (Vframe_alpha_lower_limit))
  6889     alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
  6890   else if (FIXNUMP (Vframe_alpha_lower_limit))
  6891     alpha_min = (XFIXNUM (Vframe_alpha_lower_limit)) / 100.0;
  6892 
  6893   if (alpha > 1.0)
  6894     alpha = 1.0;
  6895   else if (alpha < alpha_min && alpha_min <= 1.0)
  6896     alpha = alpha_min;
  6897 
  6898   opac = alpha * OPAQUE;
  6899 
  6900   /* If there is a parent from the window manager, put the property there
  6901      also, to work around broken window managers that fail to do that.
  6902      Do this unconditionally as this function is called on reparent when
  6903      alpha has not changed on the frame.  */
  6904 
  6905   x_ignore_errors_for_next_request (dpyinfo, 0);
  6906 
  6907   if (!FRAME_PARENT_FRAME (f))
  6908     {
  6909       parent = x_find_topmost_parent (f);
  6910 
  6911       if (parent != None)
  6912         {
  6913           XChangeProperty (dpy, parent,
  6914                            dpyinfo->Xatom_net_wm_window_opacity,
  6915                            XA_CARDINAL, 32, PropModeReplace,
  6916                            (unsigned char *) &opac, 1);
  6917         }
  6918     }
  6919 
  6920   XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity,
  6921                    XA_CARDINAL, 32, PropModeReplace,
  6922                    (unsigned char *) &opac, 1);
  6923   x_stop_ignoring_errors (dpyinfo);
  6924 }
  6925 
  6926 /***********************************************************************
  6927                     Starting and ending an update
  6928  ***********************************************************************/
  6929 
  6930 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  6931 
  6932 /* Wait for an event matching PREDICATE to show up in the event
  6933    queue, or TIMEOUT to elapse.
  6934 
  6935    If TIMEOUT passes without an event being found, return 1.
  6936    Otherwise, return 0 and behave as XIfEvent would.  */
  6937 
  6938 static int
  6939 x_if_event (Display *dpy, XEvent *event_return,
  6940             Bool (*predicate) (Display *, XEvent *, XPointer),
  6941             XPointer arg, struct timespec timeout)
  6942 {
  6943   struct timespec current_time, target;
  6944   int fd;
  6945   fd_set fds;
  6946 
  6947   fd = ConnectionNumber (dpy);
  6948   current_time = current_timespec ();
  6949   target = timespec_add (current_time, timeout);
  6950 
  6951   /* Check if an event is already in the queue.  If it is, avoid
  6952      syncing.  */
  6953   if (XCheckIfEvent (dpy, event_return, predicate, arg))
  6954     return 0;
  6955 
  6956   while (true)
  6957     {
  6958       /* Get events into the queue.  */
  6959       XSync (dpy, False);
  6960 
  6961       /* Look for an event again.  */
  6962       if (XCheckIfEvent (dpy, event_return, predicate, arg))
  6963         return 0;
  6964 
  6965       /* Calculate the timeout.  */
  6966       current_time = current_timespec ();
  6967       timeout = timespec_sub (target, current_time);
  6968 
  6969       /* If not, wait for some input to show up on the X connection,
  6970          or for the timeout to elapse.  */
  6971       FD_ZERO (&fds);
  6972       FD_SET (fd, &fds);
  6973 
  6974       /* If this fails due to an IO error, XSync will call the IO
  6975          error handler.  */
  6976       pselect (fd + 1, &fds, NULL, NULL, &timeout, NULL);
  6977 
  6978       /* Timeout elapsed.  */
  6979       current_time = current_timespec ();
  6980       if (timespec_cmp (target, current_time) < 0)
  6981         return 1;
  6982     }
  6983 }
  6984 
  6985 /* Return the monotonic time corresponding to the high-resolution
  6986    server timestamp TIMESTAMP.  Return 0 if the necessary information
  6987    is not available.  */
  6988 
  6989 static uint_fast64_t
  6990 x_sync_get_monotonic_time (struct x_display_info *dpyinfo,
  6991                            uint_fast64_t timestamp)
  6992 {
  6993   if (dpyinfo->server_time_monotonic_p)
  6994     return timestamp;
  6995 
  6996   /* This means we haven't yet initialized the server time offset.  */
  6997   if (!dpyinfo->server_time_offset)
  6998     return 0;
  6999 
  7000   uint_fast64_t t;
  7001   return ckd_sub (&t, timestamp, dpyinfo->server_time_offset) ? 0 : t;
  7002 }
  7003 
  7004 # ifndef CLOCK_MONOTONIC
  7005 #  define CLOCK_MONOTONIC CLOCK_REALTIME
  7006 # endif
  7007 
  7008 /* Return the current monotonic time in the same format as a
  7009    high-resolution server timestamp, or 0 if not available.  */
  7010 
  7011 static uint_fast64_t
  7012 x_sync_current_monotonic_time (void)
  7013 {
  7014   struct timespec time;
  7015   uint_fast64_t t;
  7016   return (((clock_gettime (CLOCK_MONOTONIC, &time) != 0
  7017             && (CLOCK_MONOTONIC == CLOCK_REALTIME
  7018                 || clock_gettime (CLOCK_REALTIME, &time) != 0))
  7019            || ckd_mul (&t, time.tv_sec, 1000000)
  7020            || ckd_add (&t, t, time.tv_nsec / 1000))
  7021           ? 0 : t);
  7022 }
  7023 
  7024 /* Decode a _NET_WM_FRAME_DRAWN message and calculate the time it took
  7025    to draw the last frame.  */
  7026 
  7027 static void
  7028 x_sync_note_frame_times (struct x_display_info *dpyinfo,
  7029                          struct frame *f, XEvent *event)
  7030 {
  7031   uint_fast64_t low, high, time;
  7032   struct x_output *output;
  7033 
  7034   low = event->xclient.data.l[2];
  7035   high = event->xclient.data.l[3];
  7036   output = FRAME_X_OUTPUT (f);
  7037 
  7038   time = x_sync_get_monotonic_time (dpyinfo, low | (high << 32));
  7039 
  7040   if (!time || !output->temp_frame_time
  7041       || ckd_sub (&output->last_frame_time, time, output->temp_frame_time))
  7042     output->last_frame_time = 0;
  7043 
  7044 #ifdef FRAME_DEBUG
  7045   uint_fast64_t last_frame_ms = output->last_frame_time / 1000;
  7046   fprintf (stderr,
  7047            "Drawing the last frame took: %"PRIuFAST64" ms (%"PRIuFAST64")\n",
  7048            last_frame_ms, time);
  7049 #endif
  7050 }
  7051 
  7052 static Bool
  7053 x_sync_is_frame_drawn_event (Display *dpy, XEvent *event,
  7054                              XPointer user_data)
  7055 {
  7056   struct frame *f;
  7057   struct x_display_info *dpyinfo;
  7058 
  7059   f = (struct frame *) user_data;
  7060   dpyinfo = FRAME_DISPLAY_INFO (f);
  7061 
  7062   if (event->type == ClientMessage
  7063       && (event->xclient.message_type
  7064           == dpyinfo->Xatom_net_wm_frame_drawn)
  7065       && event->xclient.window == FRAME_OUTER_WINDOW (f))
  7066     return True;
  7067 
  7068   return False;
  7069 }
  7070 
  7071 /* Wait for the compositing manager to finish drawing the last frame.
  7072    If the compositing manager has already drawn everything, do
  7073    nothing.  */
  7074 
  7075 static void
  7076 x_sync_wait_for_frame_drawn_event (struct frame *f)
  7077 {
  7078   XEvent event;
  7079   struct x_display_info *dpyinfo;
  7080 
  7081   if (!FRAME_X_WAITING_FOR_DRAW (f)
  7082       /* The compositing manager can't draw a frame if it is
  7083          unmapped.  */
  7084       || !FRAME_VISIBLE_P (f))
  7085     return;
  7086 
  7087   dpyinfo = FRAME_DISPLAY_INFO (f);
  7088 
  7089   /* Wait for the frame drawn message to arrive.  */
  7090   if (x_if_event (FRAME_X_DISPLAY (f), &event,
  7091                   x_sync_is_frame_drawn_event, (XPointer) f,
  7092                   make_timespec (1, 0)))
  7093     {
  7094       /* The first time a draw hangs, treat it as a random fluctuation
  7095          on the part of the compositor.  If the next draw continues to
  7096          hang, disable frame synchronization.  */
  7097       if (FRAME_X_DRAW_JUST_HUNG (f))
  7098         {
  7099           fprintf (stderr, "Warning: compositing manager spent more than 1 "
  7100                    "second drawing a frame.  Frame synchronization has "
  7101                    "been disabled\n");
  7102           FRAME_X_OUTPUT (f)->use_vsync_p = false;
  7103 
  7104           /* Remove the compositor bypass property from the outer
  7105              window.  */
  7106           XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  7107                            dpyinfo->Xatom_net_wm_bypass_compositor);
  7108 
  7109           /* Also change the frame parameter to reflect the new
  7110              state.  */
  7111           store_frame_param (f, Quse_frame_synchronization, Qnil);
  7112         }
  7113       else
  7114         {
  7115           fprintf (stderr, "Warning: compositing manager spent more than 1 "
  7116                    "second drawing a frame.  Frame synchronization will be "
  7117                    "disabled if this happens again\n");
  7118           FRAME_X_DRAW_JUST_HUNG (f) = true;
  7119         }
  7120     }
  7121   else
  7122     x_sync_note_frame_times (dpyinfo, f, &event);
  7123 
  7124   FRAME_X_WAITING_FOR_DRAW (f) = false;
  7125 }
  7126 
  7127 /* Tell the compositing manager to postpone updates of F until a frame
  7128    has finished drawing.  */
  7129 
  7130 static void
  7131 x_sync_update_begin (struct frame *f)
  7132 {
  7133   XSyncValue value, add;
  7134   Bool overflow;
  7135 
  7136   if (FRAME_X_EXTENDED_COUNTER (f) == None)
  7137     return;
  7138 
  7139   value = FRAME_X_COUNTER_VALUE (f);
  7140 
  7141   if (FRAME_X_OUTPUT (f)->ext_sync_end_pending_p)
  7142     {
  7143       FRAME_X_COUNTER_VALUE (f)
  7144         = FRAME_X_OUTPUT (f)->resize_counter_value;
  7145 
  7146       value = FRAME_X_COUNTER_VALUE (f);
  7147 
  7148       if (XSyncValueLow32 (value) % 2)
  7149         {
  7150           XSyncIntToValue (&add, 1);
  7151           XSyncValueAdd (&value, value, add, &overflow);
  7152 
  7153           if (overflow)
  7154             XSyncIntToValue (&value, 0);
  7155         }
  7156 
  7157       FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = false;
  7158     }
  7159 
  7160   /* Since a frame is already in progress, there is no point in
  7161      continuing.  */
  7162   if (XSyncValueLow32 (value) % 2)
  7163     return;
  7164 
  7165   /* Wait for the last frame to be drawn before drawing this one.  */
  7166   x_sync_wait_for_frame_drawn_event (f);
  7167 
  7168   /* Make a note of the time at which we started to draw this
  7169      frame.  */
  7170   FRAME_X_OUTPUT (f)->temp_frame_time = x_sync_current_monotonic_time ();
  7171 
  7172   /* Since Emacs needs a non-urgent redraw, ensure that value % 4 ==
  7173      1.  Later, add 3 to create the even counter value.  */
  7174   if (XSyncValueLow32 (value) % 4 == 2)
  7175     XSyncIntToValue (&add, 3);
  7176   else
  7177     XSyncIntToValue (&add, 1);
  7178 
  7179   XSyncValueAdd (&FRAME_X_COUNTER_VALUE (f),
  7180                  value, add, &overflow);
  7181 
  7182   if (overflow)
  7183     XSyncIntToValue (&FRAME_X_COUNTER_VALUE (f), 3);
  7184 
  7185   eassert (XSyncValueLow32 (FRAME_X_COUNTER_VALUE (f)) % 4 == 1);
  7186 
  7187   XSyncSetCounter (FRAME_X_DISPLAY (f),
  7188                    FRAME_X_EXTENDED_COUNTER (f),
  7189                    FRAME_X_COUNTER_VALUE (f));
  7190 }
  7191 
  7192 #ifdef HAVE_XSYNCTRIGGERFENCE
  7193 
  7194 /* Trigger the sync fence for counter VALUE immediately before a frame
  7195    finishes.  */
  7196 
  7197 static void
  7198 x_sync_trigger_fence (struct frame *f, XSyncValue value)
  7199 {
  7200   uint_fast64_t n, low, high, idx;
  7201 
  7202   /* Sync fences aren't supported by the X server.  */
  7203   if (FRAME_DISPLAY_INFO (f)->xsync_major < 3
  7204       || (FRAME_DISPLAY_INFO (f)->xsync_major == 3
  7205           && FRAME_DISPLAY_INFO (f)->xsync_minor < 1))
  7206     return;
  7207 
  7208   low = XSyncValueLow32 (value);
  7209   high = XSyncValueHigh32 (value);
  7210 
  7211   n = low | (high << 32);
  7212   idx = (n / 4) % 2;
  7213 
  7214 #ifdef FRAME_DEBUG
  7215   fprintf (stderr, "Triggering synchronization fence: %lu\n", idx);
  7216 #endif
  7217 
  7218   XSyncTriggerFence (FRAME_X_DISPLAY (f),
  7219                      FRAME_X_OUTPUT (f)->sync_fences[idx]);
  7220 }
  7221 
  7222 /* Initialize the sync fences on F.  */
  7223 
  7224 void
  7225 x_sync_init_fences (struct frame *f)
  7226 {
  7227   struct x_output *output;
  7228   struct x_display_info *dpyinfo;
  7229 
  7230   output = FRAME_X_OUTPUT (f);
  7231   dpyinfo = FRAME_DISPLAY_INFO (f);
  7232 
  7233   /* Sync fences aren't supported by the X server.  */
  7234   if (dpyinfo->xsync_major < 3
  7235       || (dpyinfo->xsync_major == 3
  7236           && dpyinfo->xsync_minor < 1))
  7237     return;
  7238 
  7239   output->sync_fences[0]
  7240     = XSyncCreateFence (FRAME_X_DISPLAY (f),
  7241                         /* The drawable given below is only used to
  7242                            determine the screen on which the fence is
  7243                            created.  */
  7244                         FRAME_X_WINDOW (f),
  7245                         False);
  7246   output->sync_fences[1]
  7247     = XSyncCreateFence (FRAME_X_DISPLAY (f),
  7248                         FRAME_X_WINDOW (f),
  7249                         False);
  7250 
  7251   XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
  7252                    dpyinfo->Xatom_net_wm_sync_fences, XA_CARDINAL,
  7253                    32, PropModeReplace,
  7254                    (unsigned char *) &output->sync_fences, 2);
  7255 }
  7256 
  7257 static void
  7258 x_sync_free_fences (struct frame *f)
  7259 {
  7260   if (FRAME_X_OUTPUT (f)->sync_fences[0] != None)
  7261     XSyncDestroyFence (FRAME_X_DISPLAY (f),
  7262                        FRAME_X_OUTPUT (f)->sync_fences[0]);
  7263 
  7264   if (FRAME_X_OUTPUT (f)->sync_fences[1] != None)
  7265     XSyncDestroyFence (FRAME_X_DISPLAY (f),
  7266                        FRAME_X_OUTPUT (f)->sync_fences[1]);
  7267 }
  7268 
  7269 #endif
  7270 
  7271 /* Tell the compositing manager that FRAME has been drawn and can be
  7272    updated.  */
  7273 
  7274 static void
  7275 x_sync_update_finish (struct frame *f)
  7276 {
  7277   XSyncValue value, add;
  7278   Bool overflow;
  7279 
  7280   if (FRAME_X_EXTENDED_COUNTER (f) == None)
  7281     return;
  7282 
  7283   value = FRAME_X_COUNTER_VALUE (f);
  7284 
  7285   if (!(XSyncValueLow32 (value) % 2))
  7286     return;
  7287 
  7288   if ((XSyncValueLow32 (value) % 4) == 1)
  7289     /* This means the frame is non-urgent and should be drawn at the
  7290        next redraw point.  */
  7291     XSyncIntToValue (&add, 3);
  7292   else
  7293     /* Otherwise, the frame is urgent and should be drawn as soon as
  7294        possible.  */
  7295     XSyncIntToValue (&add, 1);
  7296 
  7297   XSyncValueAdd (&FRAME_X_COUNTER_VALUE (f),
  7298                  value, add, &overflow);
  7299 
  7300   if (overflow)
  7301     XSyncIntToValue (&FRAME_X_COUNTER_VALUE (f), 0);
  7302 
  7303   /* Trigger any sync fences if necessary.  */
  7304 #ifdef HAVE_XSYNCTRIGGERFENCE
  7305   x_sync_trigger_fence (f, FRAME_X_COUNTER_VALUE (f));
  7306 #endif
  7307 
  7308   XSyncSetCounter (FRAME_X_DISPLAY (f),
  7309                    FRAME_X_EXTENDED_COUNTER (f),
  7310                    FRAME_X_COUNTER_VALUE (f));
  7311 
  7312   if (FRAME_OUTPUT_DATA (f)->use_vsync_p)
  7313     FRAME_X_WAITING_FOR_DRAW (f) = true;
  7314 }
  7315 
  7316 /* Handle a _NET_WM_FRAME_DRAWN message from the compositor.  */
  7317 
  7318 static void
  7319 x_sync_handle_frame_drawn (struct x_display_info *dpyinfo,
  7320                            XEvent *message, struct frame *f)
  7321 {
  7322   XSyncValue value, counter;
  7323 
  7324   if (FRAME_OUTER_WINDOW (f) == message->xclient.window)
  7325     {
  7326       counter = FRAME_X_COUNTER_VALUE (f);
  7327 
  7328       /* Check that the counter in the message is the same as the
  7329          counter in the frame.  */
  7330       XSyncIntsToValue (&value,
  7331                         message->xclient.data.l[0] & 0xffffffff,
  7332                         message->xclient.data.l[1] & 0xffffffff);
  7333 
  7334       if (XSyncValueEqual (value, counter))
  7335         FRAME_X_WAITING_FOR_DRAW (f) = false;
  7336 
  7337       /* As long as a _NET_WM_FRAME_DRAWN message arrives, we know
  7338          that the compositor is still sending events, so avoid timing
  7339          out.  */
  7340       FRAME_X_DRAW_JUST_HUNG (f) = false;
  7341     }
  7342 
  7343   x_sync_note_frame_times (dpyinfo, f, message);
  7344 }
  7345 #endif
  7346 
  7347 /* Start an update of frame F.  This function is installed as a hook
  7348    for update_begin, i.e. it is called when update_begin is called.
  7349    This function is called prior to calls to gui_update_window_begin for
  7350    each window being updated.  Currently, there is nothing to do here
  7351    because all interesting stuff is done on a window basis.  */
  7352 
  7353 static void
  7354 x_update_begin (struct frame *f)
  7355 {
  7356 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7357   /* If F is double-buffered, we can make the entire frame center
  7358      around XdbeSwapBuffers.  */
  7359 #ifdef HAVE_XDBE
  7360   if (!FRAME_X_DOUBLE_BUFFERED_P (f))
  7361 #endif
  7362     x_sync_update_begin (f);
  7363 #else
  7364   /* Nothing to do.  */
  7365 #endif
  7366 
  7367 #ifdef HAVE_XDBE
  7368   if (FRAME_X_DOUBLE_BUFFERED_P (f))
  7369     /* The frame is no longer complete, as it is in the midst of an
  7370        update.  */
  7371     FRAME_X_COMPLETE_P (f) = false;
  7372 #endif
  7373 }
  7374 
  7375 /* Draw a vertical window border from (x,y0) to (x,y1)  */
  7376 
  7377 static void
  7378 x_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
  7379 {
  7380   struct frame *f = XFRAME (WINDOW_FRAME (w));
  7381   struct face *face;
  7382 
  7383   face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
  7384   if (face)
  7385     XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
  7386                     face->foreground);
  7387 
  7388 #ifdef USE_CAIRO
  7389   x_fill_rectangle (f, f->output_data.x->normal_gc, x, y0, 1, y1 - y0, false);
  7390 #else
  7391   XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  7392              f->output_data.x->normal_gc, x, y0, x, y1);
  7393 #endif
  7394 }
  7395 
  7396 /* Draw a window divider from (x0,y0) to (x1,y1)  */
  7397 
  7398 static void
  7399 x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
  7400 {
  7401   struct frame *f = XFRAME (WINDOW_FRAME (w));
  7402   struct face *face = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FACE_ID);
  7403   struct face *face_first
  7404     = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
  7405   struct face *face_last
  7406     = FACE_FROM_ID_OR_NULL (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
  7407   unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
  7408   unsigned long color_first = (face_first
  7409                                ? face_first->foreground
  7410                                : FRAME_FOREGROUND_PIXEL (f));
  7411   unsigned long color_last = (face_last
  7412                               ? face_last->foreground
  7413                               : FRAME_FOREGROUND_PIXEL (f));
  7414   Display *display = FRAME_X_DISPLAY (f);
  7415 
  7416   if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
  7417     /* A vertical divider, at least three pixels wide: Draw first and
  7418        last pixels differently.  */
  7419     {
  7420       XSetForeground (display, f->output_data.x->normal_gc, color_first);
  7421       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7422                         x0, y0, 1, y1 - y0, false);
  7423       XSetForeground (display, f->output_data.x->normal_gc, color);
  7424       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7425                         x0 + 1, y0, x1 - x0 - 2, y1 - y0, false);
  7426       XSetForeground (display, f->output_data.x->normal_gc, color_last);
  7427       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7428                         x1 - 1, y0, 1, y1 - y0, false);
  7429     }
  7430   else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
  7431     /* A horizontal divider, at least three pixels high: Draw first and
  7432        last pixels differently.  */
  7433     {
  7434       XSetForeground (display, f->output_data.x->normal_gc, color_first);
  7435       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7436                         x0, y0, x1 - x0, 1, false);
  7437       XSetForeground (display, f->output_data.x->normal_gc, color);
  7438       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7439                         x0, y0 + 1, x1 - x0, y1 - y0 - 2, false);
  7440       XSetForeground (display, f->output_data.x->normal_gc, color_last);
  7441       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7442                         x0, y1 - 1, x1 - x0, 1, false);
  7443     }
  7444   else
  7445     {
  7446     /* In any other case do not draw the first and last pixels
  7447        differently.  */
  7448       XSetForeground (display, f->output_data.x->normal_gc, color);
  7449       x_fill_rectangle (f, f->output_data.x->normal_gc,
  7450                         x0, y0, x1 - x0, y1 - y0, false);
  7451     }
  7452 }
  7453 
  7454 #ifdef HAVE_XDBE
  7455 
  7456 /* Show the frame back buffer.  If frame is double-buffered,
  7457    atomically publish to the user's screen graphics updates made since
  7458    the last call to show_back_buffer.  */
  7459 
  7460 static void
  7461 show_back_buffer (struct frame *f)
  7462 {
  7463   XdbeSwapInfo swap_info;
  7464 #ifdef USE_CAIRO
  7465   cairo_t *cr;
  7466 #endif
  7467 
  7468   if (FRAME_X_DOUBLE_BUFFERED_P (f))
  7469     {
  7470 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7471       /* Wait for drawing of the previous frame to complete before
  7472          displaying this new frame.  */
  7473       x_sync_wait_for_frame_drawn_event (f);
  7474 
  7475       /* Begin a new frame.  */
  7476       x_sync_update_begin (f);
  7477 #endif
  7478 
  7479 #ifdef USE_CAIRO
  7480       cr = FRAME_CR_CONTEXT (f);
  7481       if (cr)
  7482         cairo_surface_flush (cairo_get_target (cr));
  7483 #endif
  7484       memset (&swap_info, 0, sizeof (swap_info));
  7485       swap_info.swap_window = FRAME_X_WINDOW (f);
  7486       swap_info.swap_action = XdbeCopied;
  7487       XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1);
  7488 
  7489 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7490       /* Finish the frame here.  */
  7491       x_sync_update_finish (f);
  7492 #endif
  7493     }
  7494 
  7495   FRAME_X_NEED_BUFFER_FLIP (f) = false;
  7496 }
  7497 
  7498 #endif
  7499 
  7500 /* Updates back buffer and flushes changes to display.  Called from
  7501    minibuf read code.  Note that we display the back buffer even if
  7502    buffer flipping is blocked.  */
  7503 static void
  7504 x_flip_and_flush (struct frame *f)
  7505 {
  7506   /* Flipping buffers requires a working connection to the X server,
  7507      which isn't always present if `inhibit-redisplay' is t, since
  7508      this can be called from the IO error handler.  */
  7509   if (!NILP (Vinhibit_redisplay)
  7510       /* This has to work for tooltip frames, however, and redisplay
  7511          cannot happen when they are being flushed anyway.  (bug#55519) */
  7512       && !FRAME_TOOLTIP_P (f))
  7513     return;
  7514 
  7515   block_input ();
  7516 #ifdef HAVE_XDBE
  7517   if (FRAME_X_NEED_BUFFER_FLIP (f))
  7518     show_back_buffer (f);
  7519 
  7520   /* The frame is complete again as its contents were just
  7521      flushed.  */
  7522   FRAME_X_COMPLETE_P (f) = true;
  7523 #endif
  7524   x_flush (f);
  7525   unblock_input ();
  7526 }
  7527 
  7528 /* End update of frame F.  This function is installed as a hook in
  7529    update_end.  */
  7530 
  7531 static void
  7532 x_update_end (struct frame *f)
  7533 {
  7534   /* Mouse highlight may be displayed again.  */
  7535   MOUSE_HL_INFO (f)->mouse_face_defer = false;
  7536 
  7537 #ifdef USE_CAIRO
  7538 # ifdef HAVE_XDBE
  7539   if (!FRAME_X_DOUBLE_BUFFERED_P (f) && FRAME_CR_CONTEXT (f))
  7540     cairo_surface_flush (cairo_get_target (FRAME_CR_CONTEXT (f)));
  7541 # endif
  7542 #endif
  7543 
  7544   /* If double buffering is disabled, finish the update here.
  7545      Otherwise, finish the update when the back buffer is next
  7546      displayed.  */
  7547 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7548 #ifdef HAVE_XDBE
  7549   if (!FRAME_X_DOUBLE_BUFFERED_P (f))
  7550 #endif
  7551     x_sync_update_finish (f);
  7552 #endif
  7553 }
  7554 
  7555 /* This function is called from various places in xdisp.c
  7556    whenever a complete update has been performed.  */
  7557 
  7558 static void
  7559 XTframe_up_to_date (struct frame *f)
  7560 {
  7561 #if defined HAVE_XSYNC && defined HAVE_GTK3
  7562   GtkWidget *widget;
  7563   GdkWindow *window;
  7564   GdkFrameClock *clock;
  7565 #endif
  7566 
  7567   eassert (FRAME_X_P (f));
  7568   block_input ();
  7569   FRAME_MOUSE_UPDATE (f);
  7570 
  7571 #ifdef HAVE_XDBE
  7572   if (!buffer_flipping_blocked_p ()
  7573       && FRAME_X_NEED_BUFFER_FLIP (f))
  7574     show_back_buffer (f);
  7575 
  7576   /* The frame is now complete, as its contents have been drawn.  */
  7577   FRAME_X_COMPLETE_P (f) = true;
  7578 #endif
  7579 
  7580 #ifdef HAVE_XSYNC
  7581 #ifndef HAVE_GTK3
  7582   if (FRAME_X_OUTPUT (f)->sync_end_pending_p
  7583       && FRAME_X_BASIC_COUNTER (f) != None)
  7584     {
  7585       XSyncSetCounter (FRAME_X_DISPLAY (f),
  7586                        FRAME_X_BASIC_COUNTER (f),
  7587                        FRAME_X_OUTPUT (f)->pending_basic_counter_value);
  7588       FRAME_X_OUTPUT (f)->sync_end_pending_p = false;
  7589     }
  7590 #else
  7591   if (FRAME_X_OUTPUT (f)->xg_sync_end_pending_p)
  7592     {
  7593       widget = FRAME_GTK_OUTER_WIDGET (f);
  7594       window = gtk_widget_get_window (widget);
  7595       eassert (window);
  7596       clock = gdk_window_get_frame_clock (window);
  7597       eassert (clock);
  7598 
  7599       gdk_frame_clock_request_phase (clock,
  7600                                      GDK_FRAME_CLOCK_PHASE_AFTER_PAINT);
  7601       FRAME_X_OUTPUT (f)->xg_sync_end_pending_p = false;
  7602     }
  7603 #endif
  7604 #endif
  7605   unblock_input ();
  7606 }
  7607 
  7608 #ifdef HAVE_XDBE
  7609 static void
  7610 XTbuffer_flipping_unblocked_hook (struct frame *f)
  7611 {
  7612   block_input ();
  7613 
  7614   if (FRAME_X_NEED_BUFFER_FLIP (f))
  7615     show_back_buffer (f);
  7616 
  7617   unblock_input ();
  7618 }
  7619 #endif
  7620 
  7621 /**
  7622  * x_clear_under_internal_border:
  7623  *
  7624  * Clear area of frame F's internal border.  If the internal border face
  7625  * of F has been specified (is not null), fill the area with that face.
  7626  */
  7627 void
  7628 x_clear_under_internal_border (struct frame *f)
  7629 {
  7630   if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
  7631     {
  7632       int border = FRAME_INTERNAL_BORDER_WIDTH (f);
  7633       int width = FRAME_PIXEL_WIDTH (f);
  7634       int height = FRAME_PIXEL_HEIGHT (f);
  7635       int margin = FRAME_TOP_MARGIN_HEIGHT (f);
  7636       int bottom_margin = FRAME_BOTTOM_MARGIN_HEIGHT (f);
  7637       int face_id = (FRAME_PARENT_FRAME (f)
  7638                      ? (!NILP (Vface_remapping_alist)
  7639                         ? lookup_basic_face (NULL, f,
  7640                                              CHILD_FRAME_BORDER_FACE_ID)
  7641                         : CHILD_FRAME_BORDER_FACE_ID)
  7642                      : (!NILP (Vface_remapping_alist)
  7643                         ? lookup_basic_face (NULL, f,
  7644                                              INTERNAL_BORDER_FACE_ID)
  7645                         : INTERNAL_BORDER_FACE_ID));
  7646       struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
  7647 
  7648       if (face)
  7649         {
  7650           unsigned long color = face->background;
  7651           Display *display = FRAME_X_DISPLAY (f);
  7652           GC gc = f->output_data.x->normal_gc;
  7653 
  7654           XSetForeground (display, gc, color);
  7655           x_fill_rectangle (f, gc, 0, margin, width, border, false);
  7656           x_fill_rectangle (f, gc, 0, 0, border, height, false);
  7657           x_fill_rectangle (f, gc, width - border, 0, border, height, false);
  7658           x_fill_rectangle (f, gc, 0, height - bottom_margin - border,
  7659                             width, border, false);
  7660           XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
  7661         }
  7662       else
  7663         {
  7664           x_clear_area (f, 0, 0, border, height);
  7665           x_clear_area (f, 0, margin, width, border);
  7666           x_clear_area (f, width - border, 0, border, height);
  7667           x_clear_area (f, 0, height - bottom_margin - border,
  7668                         width, border);
  7669         }
  7670     }
  7671 }
  7672 
  7673 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
  7674    arrow bitmaps, or clear the fringes if no bitmaps are required
  7675    before DESIRED_ROW is made current.  This function is called from
  7676    update_window_line only if it is known that there are differences
  7677    between bitmaps to be drawn between current row and DESIRED_ROW.  */
  7678 
  7679 static void
  7680 x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
  7681 {
  7682   eassert (w);
  7683 
  7684   if (!desired_row->mode_line_p && !w->pseudo_window_p)
  7685     desired_row->redraw_fringe_bitmaps_p = true;
  7686 
  7687 #ifdef USE_X_TOOLKIT
  7688   /* When a window has disappeared, make sure that no rest of
  7689      full-width rows stays visible in the internal border.  Could
  7690      check here if updated window is the leftmost/rightmost window,
  7691      but I guess it's not worth doing since vertically split windows
  7692      are almost never used, internal border is rarely set, and the
  7693      overhead is very small.  */
  7694   {
  7695     struct frame *f;
  7696     int width, height;
  7697 
  7698     if (windows_or_buffers_changed
  7699         && desired_row->full_width_p
  7700         && (f = XFRAME (w->frame),
  7701             width = FRAME_INTERNAL_BORDER_WIDTH (f),
  7702             width != 0)
  7703         && (height = desired_row->visible_height,
  7704             height > 0))
  7705       {
  7706         int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
  7707         int face_id =
  7708           (FRAME_PARENT_FRAME (f)
  7709            ? (!NILP (Vface_remapping_alist)
  7710               ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
  7711               : CHILD_FRAME_BORDER_FACE_ID)
  7712            : (!NILP (Vface_remapping_alist)
  7713               ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
  7714               : INTERNAL_BORDER_FACE_ID));
  7715         struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
  7716 
  7717         if (face)
  7718           {
  7719             unsigned long color = face->background;
  7720             Display *display = FRAME_X_DISPLAY (f);
  7721             GC gc = f->output_data.x->normal_gc;
  7722 
  7723             XSetForeground (display, gc, color);
  7724             x_fill_rectangle (f, gc, 0, y, width, height, true);
  7725             x_fill_rectangle (f, gc, FRAME_PIXEL_WIDTH (f) - width, y,
  7726                               width, height, true);
  7727             XSetForeground (display, gc, FRAME_FOREGROUND_PIXEL (f));
  7728           }
  7729         else
  7730           {
  7731             x_clear_area (f, 0, y, width, height);
  7732             x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
  7733           }
  7734       }
  7735   }
  7736 #endif
  7737 }
  7738 
  7739 /* Generate a premultiplied pixel value for COLOR with ALPHA applied
  7740    on the given display.  COLOR will be modified.  The display must
  7741    use a visual that supports an alpha channel.
  7742 
  7743    This is possibly dead code on builds which do not support
  7744    XRender.  */
  7745 
  7746 #ifndef USE_CAIRO
  7747 
  7748 static unsigned long
  7749 x_premultiply_pixel (struct x_display_info *dpyinfo,
  7750                      XColor *color, double alpha)
  7751 {
  7752   unsigned long pixel;
  7753 
  7754   eassert (dpyinfo->alpha_bits);
  7755 
  7756   /* Multiply the RGB channels.  */
  7757   color->red *= alpha;
  7758   color->green *= alpha;
  7759   color->blue *= alpha;
  7760 
  7761   /* First, allocate a fully opaque pixel.  */
  7762   pixel = x_make_truecolor_pixel (dpyinfo, color->red,
  7763                                   color->green,
  7764                                   color->blue);
  7765 
  7766   /* Next, erase the alpha component.  */
  7767   pixel &= ~dpyinfo->alpha_mask;
  7768 
  7769   /* And add an alpha channel.  */
  7770   pixel |= (((unsigned long) (alpha * 65535)
  7771              >> (16 - dpyinfo->alpha_bits))
  7772             << dpyinfo->alpha_offset);
  7773 
  7774   return pixel;
  7775 }
  7776 
  7777 #endif
  7778 
  7779 static void
  7780 x_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
  7781                       struct draw_fringe_bitmap_params *p)
  7782 {
  7783   struct frame *f = XFRAME (WINDOW_FRAME (w));
  7784   Display *display = FRAME_X_DISPLAY (f);
  7785   GC gc = f->output_data.x->normal_gc;
  7786   struct face *face = p->face;
  7787 
  7788   /* Must clip because of partially visible lines.  */
  7789   x_clip_to_row (w, row, ANY_AREA, gc);
  7790 
  7791   if (p->bx >= 0 && !p->overlay_p)
  7792     {
  7793       /* In case the same realized face is used for fringes and
  7794          for something displayed in the text (e.g. face `region' on
  7795          mono-displays, the fill style may have been changed to
  7796          FillSolid in x_draw_glyph_string_background.  */
  7797       if (face->stipple)
  7798         {
  7799           XSetFillStyle (display, face->gc, FillOpaqueStippled);
  7800           x_fill_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny,
  7801                             true);
  7802           XSetFillStyle (display, face->gc, FillSolid);
  7803 
  7804           row->stipple_p = true;
  7805         }
  7806       else
  7807         {
  7808           XSetBackground (display, face->gc, face->background);
  7809           x_clear_rectangle (f, face->gc, p->bx, p->by, p->nx, p->ny,
  7810                            true);
  7811           XSetForeground (display, face->gc, face->foreground);
  7812         }
  7813     }
  7814 
  7815 #ifdef USE_CAIRO
  7816   if (p->which
  7817       && p->which < max_fringe_bmp
  7818       && p->which < max_used_fringe_bitmap)
  7819     {
  7820       XGCValues gcv;
  7821 
  7822       XGetGCValues (display, gc, GCForeground | GCBackground, &gcv);
  7823       XSetForeground (display, gc, (p->cursor_p
  7824                                     ? (p->overlay_p ? face->background
  7825                                        : f->output_data.x->cursor_pixel)
  7826                                     : face->foreground));
  7827       XSetBackground (display, gc, face->background);
  7828       if (!fringe_bmp[p->which])
  7829         {
  7830           /* This fringe bitmap is known to fringe.c, but lacks the
  7831              cairo_pattern_t pattern which shadows that bitmap.  This
  7832              is typical to define-fringe-bitmap being called when the
  7833              selected frame was not a GUI frame, for example, when
  7834              packages that define fringe bitmaps are loaded by a
  7835              daemon Emacs.  Create the missing pattern now.  */
  7836           gui_define_fringe_bitmap (f, p->which);
  7837         }
  7838       x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
  7839                        p->wd, p->h, p->x, p->y, p->overlay_p);
  7840       XSetForeground (display, gc, gcv.foreground);
  7841       XSetBackground (display, gc, gcv.background);
  7842     }
  7843 #else  /* not USE_CAIRO */
  7844   if (p->which)
  7845     {
  7846       Drawable drawable = FRAME_X_DRAWABLE (f);
  7847       char *bits;
  7848       Pixmap pixmap, clipmask = None;
  7849       int depth = FRAME_DISPLAY_INFO (f)->n_planes;
  7850       XGCValues gcv;
  7851       unsigned long background = face->background;
  7852       XColor bg;
  7853 #ifdef HAVE_XRENDER
  7854       Picture picture = None;
  7855       XRenderPictureAttributes attrs;
  7856 
  7857       memset (&attrs, 0, sizeof attrs);
  7858 #endif
  7859 
  7860       if (p->wd > 8)
  7861         bits = (char *) (p->bits + p->dh);
  7862       else
  7863         bits = (char *) p->bits + p->dh;
  7864 
  7865       if (FRAME_DISPLAY_INFO (f)->alpha_bits
  7866           && f->alpha_background < 1.0)
  7867         {
  7868           /* Extend the background color with an alpha channel
  7869              according to f->alpha_background.  */
  7870           bg.pixel = background;
  7871           x_query_colors (f, &bg, 1);
  7872 
  7873           background
  7874             = x_premultiply_pixel (FRAME_DISPLAY_INFO (f),
  7875                                    &bg,
  7876                                    f->alpha_background);
  7877         }
  7878 
  7879       /* Draw the bitmap.  I believe these small pixmaps can be cached
  7880          by the server.  */
  7881       pixmap = XCreatePixmapFromBitmapData (display, drawable, bits, p->wd, p->h,
  7882                                             (p->cursor_p
  7883                                              ? (p->overlay_p ? face->background
  7884                                                 : f->output_data.x->cursor_pixel)
  7885                                              : face->foreground),
  7886                                             background, depth);
  7887 
  7888 #ifdef HAVE_XRENDER
  7889       if (FRAME_X_PICTURE_FORMAT (f)
  7890           && (x_xr_ensure_picture (f), FRAME_X_PICTURE (f)))
  7891         picture = XRenderCreatePicture (display, pixmap,
  7892                                         FRAME_X_PICTURE_FORMAT (f),
  7893                                         0, &attrs);
  7894 #endif
  7895 
  7896       if (p->overlay_p)
  7897         {
  7898           clipmask = XCreatePixmapFromBitmapData (display,
  7899                                                   FRAME_DISPLAY_INFO (f)->root_window,
  7900                                                   bits, p->wd, p->h,
  7901                                                   1, 0, 1);
  7902 
  7903 #ifdef HAVE_XRENDER
  7904           if (picture != None)
  7905             {
  7906               attrs.clip_mask = clipmask;
  7907               attrs.clip_x_origin = p->x;
  7908               attrs.clip_y_origin = p->y;
  7909 
  7910               XRenderChangePicture (display, FRAME_X_PICTURE (f),
  7911                                     CPClipMask | CPClipXOrigin | CPClipYOrigin,
  7912                                     &attrs);
  7913             }
  7914           else
  7915 #endif
  7916             {
  7917               gcv.clip_mask = clipmask;
  7918               gcv.clip_x_origin = p->x;
  7919               gcv.clip_y_origin = p->y;
  7920               XChangeGC (display, gc, GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
  7921             }
  7922         }
  7923 
  7924 #ifdef HAVE_XRENDER
  7925       if (picture != None)
  7926         {
  7927           x_xr_apply_ext_clip (f, gc);
  7928           XRenderComposite (display, PictOpSrc, picture,
  7929                             None, FRAME_X_PICTURE (f),
  7930                             0, 0, 0, 0, p->x, p->y, p->wd, p->h);
  7931           x_xr_reset_ext_clip (f);
  7932 
  7933           XRenderFreePicture (display, picture);
  7934         }
  7935       else
  7936 #endif
  7937         XCopyArea (display, pixmap, drawable, gc, 0, 0,
  7938                    p->wd, p->h, p->x, p->y);
  7939       XFreePixmap (display, pixmap);
  7940 
  7941       if (p->overlay_p)
  7942         {
  7943           gcv.clip_mask = (Pixmap) 0;
  7944           XChangeGC (display, gc, GCClipMask, &gcv);
  7945           XFreePixmap (display, clipmask);
  7946         }
  7947     }
  7948 #endif  /* not USE_CAIRO */
  7949 
  7950   x_reset_clip_rectangles (f, gc);
  7951 }
  7952 
  7953 /***********************************************************************
  7954                             Glyph display
  7955  ***********************************************************************/
  7956 
  7957 static bool x_alloc_lighter_color (struct frame *, Display *, Colormap,
  7958                                    unsigned long *, double, int);
  7959 static void x_scroll_bar_clear (struct frame *);
  7960 
  7961 #ifdef GLYPH_DEBUG
  7962 static void x_check_font (struct frame *, struct font *);
  7963 #endif
  7964 
  7965 /* If SEND_EVENT, make sure that TIME is larger than the current last
  7966    user time.  We don't sanitize timestamps from events sent by the X
  7967    server itself because some Lisp might have set the user time to a
  7968    ridiculously large value, and this way a more reasonable timestamp
  7969    can be obtained upon the next event.
  7970 
  7971    Alternatively, the server time could've overflowed.
  7972 
  7973    SET_PROPERTY specifies whether or not to change the user time
  7974    property for the active frame.  The important thing is to not set
  7975    the last user time upon leave events; on Metacity and GNOME Shell,
  7976    mapping a new frame on top of the old frame potentially causes
  7977    crossing events to be sent to the old frame if it contains the
  7978    pointer, as the new frame will initially stack above the old frame.
  7979    If _NET_WM_USER_TIME is changed at that point, then GNOME may get
  7980    notified about the user time change on the old frame before it
  7981    tries to focus the new frame, which will make it consider the new
  7982    frame (whose user time property will not have been updated at that
  7983    point, due to not being focused) as having been mapped
  7984    out-of-order, and lower the new frame, which is typically not what
  7985    users want.  */
  7986 
  7987 static void
  7988 x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time,
  7989                               bool send_event, bool set_property)
  7990 {
  7991 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  7992   uint_fast64_t monotonic_time;
  7993   uint_fast64_t monotonic_ms;
  7994   int_fast64_t diff_ms;
  7995 #endif
  7996 #ifndef USE_GTK
  7997   struct frame *focus_frame;
  7998   Time old_time;
  7999 
  8000   focus_frame = dpyinfo->x_focus_frame;
  8001   old_time = dpyinfo->last_user_time;
  8002 #endif
  8003 
  8004 #ifdef ENABLE_CHECKING
  8005   eassert (time <= X_ULONG_MAX);
  8006 #endif
  8007 
  8008   if (!send_event || time > dpyinfo->last_user_time)
  8009     dpyinfo->last_user_time = time;
  8010 
  8011 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
  8012   if (!send_event)
  8013     {
  8014       /* See if the current CLOCK_MONOTONIC time is reasonably close
  8015          to the X server time.  */
  8016       monotonic_time = x_sync_current_monotonic_time ();
  8017       monotonic_ms = monotonic_time / 1000;
  8018 
  8019       dpyinfo->server_time_monotonic_p
  8020         = (monotonic_time != 0
  8021            && !ckd_sub (&diff_ms, time, monotonic_ms)
  8022            && -500 < diff_ms && diff_ms < 500);
  8023 
  8024       if (!dpyinfo->server_time_monotonic_p)
  8025         {
  8026           /* Compute an offset that can be subtracted from the server
  8027              time to estimate the monotonic time on the X server.  */
  8028 
  8029           if (!monotonic_time
  8030               || ckd_mul (&dpyinfo->server_time_offset, time, 1000)
  8031               || ckd_sub (&dpyinfo->server_time_offset,
  8032                           dpyinfo->server_time_offset, monotonic_time))
  8033             dpyinfo->server_time_offset = 0;
  8034 
  8035           /* If the server time is reasonably close to the monotonic
  8036              time after the latter is truncated to CARD32, simply make
  8037              the offset that between the server time in ms and the
  8038              actual time in ms.  */
  8039 
  8040           monotonic_ms = monotonic_ms & 0xffffffff;
  8041           if (!ckd_sub (&diff_ms, time, monotonic_ms)
  8042               && -500 < diff_ms && diff_ms < 500)
  8043             {
  8044               /* The server timestamp overflowed.  Make the time
  8045                  offset exactly how much it overflowed by.  */
  8046 
  8047               if (ckd_sub (&dpyinfo->server_time_offset,
  8048                            monotonic_time / 1000, monotonic_ms)
  8049                   || ckd_mul (&dpyinfo->server_time_offset,
  8050                               dpyinfo->server_time_offset, 1000)
  8051                   || ckd_sub (&dpyinfo->server_time_offset,
  8052                               0, dpyinfo->server_time_offset))
  8053                 dpyinfo->server_time_offset = 0;
  8054             }
  8055         }
  8056     }
  8057 #endif
  8058 
  8059 #ifndef USE_GTK
  8060   /* Don't waste bandwidth if the time hasn't actually changed.  */
  8061   if (focus_frame && old_time != dpyinfo->last_user_time
  8062       && set_property)
  8063     {
  8064       time = dpyinfo->last_user_time;
  8065 
  8066       while (FRAME_PARENT_FRAME (focus_frame))
  8067         focus_frame = FRAME_PARENT_FRAME (focus_frame);
  8068 
  8069       if (FRAME_X_OUTPUT (focus_frame)->user_time_window != None)
  8070         XChangeProperty (dpyinfo->display,
  8071                          FRAME_X_OUTPUT (focus_frame)->user_time_window,
  8072                          dpyinfo->Xatom_net_wm_user_time,
  8073                          XA_CARDINAL, 32, PropModeReplace,
  8074                          (unsigned char *) &time, 1);
  8075     }
  8076 #endif
  8077 }
  8078 
  8079 #ifdef USE_GTK
  8080 
  8081 static void
  8082 x_set_gtk_user_time (struct frame *f, Time time)
  8083 {
  8084   GtkWidget *widget;
  8085   GdkWindow *window;
  8086 
  8087   widget = FRAME_GTK_OUTER_WIDGET (f);
  8088   window = gtk_widget_get_window (widget);
  8089 
  8090   /* This widget isn't realized yet.  */
  8091   if (!window)
  8092     return;
  8093 
  8094   gdk_x11_window_set_user_time (window, time);
  8095 }
  8096 
  8097 #endif
  8098 
  8099 #if !defined USE_GTK || defined HAVE_XFIXES
  8100 
  8101 /* Create and return a special window for receiving events such as
  8102    selection notify events, and reporting user time.  The window is an
  8103    1x1 unmapped override-redirect InputOnly window at -1, -1 relative
  8104    to the parent, which should prevent it from doing anything.  */
  8105 
  8106 static Window
  8107 x_create_special_window (struct x_display_info *dpyinfo,
  8108                          Window parent_window)
  8109 {
  8110   XSetWindowAttributes attrs;
  8111 
  8112   attrs.override_redirect = True;
  8113 
  8114   return XCreateWindow (dpyinfo->display, parent_window,
  8115                         -1, -1, 1, 1, 0, CopyFromParent, InputOnly,
  8116                         CopyFromParent, CWOverrideRedirect, &attrs);
  8117 }
  8118 
  8119 #endif
  8120 
  8121 /* Not needed on GTK because GTK handles reporting the user time
  8122    itself.  */
  8123 
  8124 #ifndef USE_GTK
  8125 
  8126 static void
  8127 x_update_frame_user_time_window (struct frame *f)
  8128 {
  8129   struct x_output *output;
  8130   struct x_display_info *dpyinfo;
  8131 
  8132   output = FRAME_X_OUTPUT (f);
  8133   dpyinfo = FRAME_DISPLAY_INFO (f);
  8134 
  8135   if (!NILP (Vx_no_window_manager)
  8136       || !x_wm_supports (f, dpyinfo->Xatom_net_wm_user_time))
  8137     {
  8138       if (output->user_time_window != None
  8139           && output->user_time_window != FRAME_OUTER_WINDOW (f))
  8140         {
  8141           XDestroyWindow (dpyinfo->display, output->user_time_window);
  8142           XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  8143                            dpyinfo->Xatom_net_wm_user_time_window);
  8144         }
  8145       else
  8146         XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  8147                          dpyinfo->Xatom_net_wm_user_time);
  8148 
  8149       output->user_time_window = None;
  8150       return;
  8151     }
  8152 
  8153   if (!x_wm_supports (f, dpyinfo->Xatom_net_wm_user_time_window))
  8154     {
  8155       if (output->user_time_window == None)
  8156         output->user_time_window = FRAME_OUTER_WINDOW (f);
  8157       else if (output->user_time_window != FRAME_OUTER_WINDOW (f))
  8158         {
  8159           XDestroyWindow (dpyinfo->display,
  8160                           output->user_time_window);
  8161           XDeleteProperty (dpyinfo->display,
  8162                            FRAME_OUTER_WINDOW (f),
  8163                            dpyinfo->Xatom_net_wm_user_time_window);
  8164           output->user_time_window = FRAME_OUTER_WINDOW (f);
  8165         }
  8166     }
  8167   else
  8168     {
  8169       if (output->user_time_window == FRAME_OUTER_WINDOW (f)
  8170           || output->user_time_window == None)
  8171         {
  8172           /* Create a "user time" window that is used to report user
  8173              activity on a given frame.  This is used in preference to
  8174              _NET_WM_USER_TIME, as using a separate window allows the
  8175              window manager to express interest in other properties
  8176              while only reading the user time when necessary, thereby
  8177              improving battery life by not involving the window
  8178              manager in each key press.  */
  8179 
  8180           output->user_time_window
  8181             = x_create_special_window (dpyinfo, FRAME_X_WINDOW (f));
  8182 
  8183           XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  8184                            dpyinfo->Xatom_net_wm_user_time);
  8185           XChangeProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
  8186                            dpyinfo->Xatom_net_wm_user_time_window,
  8187                            XA_WINDOW, 32, PropModeReplace,
  8188                            (unsigned char *) &output->user_time_window, 1);
  8189         }
  8190     }
  8191 }
  8192 
  8193 #endif
  8194 
  8195 void
  8196 x_set_last_user_time_from_lisp (struct x_display_info *dpyinfo,
  8197                                 Time time)
  8198 {
  8199   x_display_set_last_user_time (dpyinfo, time, true, true);
  8200 }
  8201 
  8202 
  8203 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
  8204    face.  */
  8205 
  8206 static void
  8207 x_set_cursor_gc (struct glyph_string *s)
  8208 {
  8209   if (s->font == FRAME_FONT (s->f)
  8210       && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
  8211       && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
  8212       && !s->cmp)
  8213     s->gc = s->f->output_data.x->cursor_gc;
  8214   else
  8215     {
  8216       /* Cursor on non-default face: must merge.  */
  8217       XGCValues xgcv;
  8218       unsigned long mask;
  8219       Display *display = FRAME_X_DISPLAY (s->f);
  8220 
  8221       xgcv.background = s->f->output_data.x->cursor_pixel;
  8222       xgcv.foreground = s->face->background;
  8223 
  8224       /* If the glyph would be invisible, try a different foreground.  */
  8225       if (xgcv.foreground == xgcv.background)
  8226         xgcv.foreground = s->face->foreground;
  8227       if (xgcv.foreground == xgcv.background)
  8228         xgcv.foreground = s->f->output_data.x->cursor_foreground_pixel;
  8229       if (xgcv.foreground == xgcv.background)
  8230         xgcv.foreground = s->face->foreground;
  8231 
  8232       /* Make sure the cursor is distinct from text in this face.  */
  8233       if (xgcv.background == s->face->background
  8234           && xgcv.foreground == s->face->foreground)
  8235         {
  8236           xgcv.background = s->face->foreground;
  8237           xgcv.foreground = s->face->background;
  8238         }
  8239 
  8240       IF_DEBUG (x_check_font (s->f, s->font));
  8241       xgcv.graphics_exposures = False;
  8242       xgcv.line_width = 1;
  8243       mask = (GCForeground | GCBackground
  8244               | GCGraphicsExposures
  8245               | GCLineWidth);
  8246 
  8247       if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
  8248         XChangeGC (display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
  8249                    mask, &xgcv);
  8250       else
  8251         FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
  8252           = XCreateGC (display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
  8253 
  8254       s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
  8255     }
  8256 }
  8257 
  8258 
  8259 /* Set up S->gc of glyph string S for drawing text in mouse face.  */
  8260 
  8261 static void
  8262 x_set_mouse_face_gc (struct glyph_string *s)
  8263 {
  8264   if (s->font == s->face->font)
  8265     s->gc = s->face->gc;
  8266   else
  8267     {
  8268       /* Otherwise construct scratch_cursor_gc with values from FACE
  8269          except for FONT.  */
  8270       XGCValues xgcv;
  8271       unsigned long mask;
  8272       Display *display = FRAME_X_DISPLAY (s->f);
  8273 
  8274       xgcv.background = s->face->background;
  8275       xgcv.foreground = s->face->foreground;
  8276       xgcv.graphics_exposures = False;
  8277       xgcv.line_width = 1;
  8278 
  8279       mask = (GCForeground | GCBackground
  8280               | GCGraphicsExposures
  8281               | GCLineWidth);
  8282 
  8283       if (FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc)
  8284         XChangeGC (display, FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc,
  8285                    mask, &xgcv);
  8286       else
  8287         FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc
  8288           = XCreateGC (display, FRAME_X_DRAWABLE (s->f), mask, &xgcv);
  8289 
  8290       s->gc = FRAME_DISPLAY_INFO (s->f)->scratch_cursor_gc;
  8291 
  8292     }
  8293   eassert (s->gc != 0);
  8294 }
  8295 
  8296 
  8297 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
  8298    Faces to use in the mode line have already been computed when the
  8299    matrix was built, so there isn't much to do, here.  */
  8300 
  8301 static void
  8302 x_set_mode_line_face_gc (struct glyph_string *s)
  8303 {
  8304   s->gc = s->face->gc;
  8305 }
  8306 
  8307 
  8308 /* Set S->gc of glyph string S for drawing that glyph string.  Set
  8309    S->stippled_p to a non-zero value if the face of S has a stipple
  8310    pattern.  */
  8311 
  8312 static void
  8313 x_set_glyph_string_gc (struct glyph_string *s)
  8314 {
  8315   prepare_face_for_display (s->f, s->face);
  8316 
  8317   if (s->hl == DRAW_NORMAL_TEXT)
  8318     {
  8319       s->gc = s->face->gc;
  8320       s->stippled_p = s->face->stipple != 0;
  8321     }
  8322   else if (s->hl == DRAW_INVERSE_VIDEO)
  8323     {
  8324       x_set_mode_line_face_gc (s);
  8325       s->stippled_p = s->face->stipple != 0;
  8326     }
  8327   else if (s->hl == DRAW_CURSOR)
  8328     {
  8329       x_set_cursor_gc (s);
  8330       s->stippled_p = false;
  8331     }
  8332   else if (s->hl == DRAW_MOUSE_FACE)
  8333     {
  8334       x_set_mouse_face_gc (s);
  8335       s->stippled_p = s->face->stipple != 0;
  8336     }
  8337   else if (s->hl == DRAW_IMAGE_RAISED
  8338            || s->hl == DRAW_IMAGE_SUNKEN)
  8339     {
  8340       s->gc = s->face->gc;
  8341       s->stippled_p = s->face->stipple != 0;
  8342     }
  8343   else
  8344     emacs_abort ();
  8345 
  8346   /* GC must have been set.  */
  8347   eassert (s->gc != 0);
  8348 }
  8349 
  8350 
  8351 /* Set clipping for output of glyph string S.  S may be part of a mode
  8352    line or menu if we don't have X toolkit support.  */
  8353 
  8354 static void
  8355 x_set_glyph_string_clipping (struct glyph_string *s)
  8356 {
  8357   XRectangle *r = s->clip;
  8358   int n = get_glyph_string_clip_rects (s, r, 2);
  8359 
  8360   if (n > 0)
  8361     x_set_clip_rectangles (s->f, s->gc, r, n);
  8362   s->num_clips = n;
  8363 }
  8364 
  8365 
  8366 /* Set SRC's clipping for output of glyph string DST.  This is called
  8367    when we are drawing DST's left_overhang or right_overhang only in
  8368    the area of SRC.  */
  8369 
  8370 static void
  8371 x_set_glyph_string_clipping_exactly (struct glyph_string *src, struct glyph_string *dst)
  8372 {
  8373   XRectangle r;
  8374 
  8375   r.x = src->x;
  8376   r.width = src->width;
  8377   r.y = src->y;
  8378   r.height = src->height;
  8379   dst->clip[0] = r;
  8380   dst->num_clips = 1;
  8381   x_set_clip_rectangles (dst->f, dst->gc, &r, 1);
  8382 }
  8383 
  8384 
  8385 /* RIF:
  8386    Compute left and right overhang of glyph string S.  */
  8387 
  8388 static void
  8389 x_compute_glyph_string_overhangs (struct glyph_string *s)
  8390 {
  8391   if (s->cmp == NULL
  8392       && (s->first_glyph->type == CHAR_GLYPH
  8393           || s->first_glyph->type == COMPOSITE_GLYPH))
  8394     {
  8395       struct font_metrics metrics;
  8396 
  8397       if (s->first_glyph->type == CHAR_GLYPH)
  8398         {
  8399           struct font *font = s->font;
  8400           font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
  8401         }
  8402       else
  8403         {
  8404           Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
  8405 
  8406           composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
  8407         }
  8408       s->right_overhang = (metrics.rbearing > metrics.width
  8409                            ? metrics.rbearing - metrics.width : 0);
  8410       s->left_overhang = metrics.lbearing < 0 ? - metrics.lbearing : 0;
  8411     }
  8412   else if (s->cmp)
  8413     {
  8414       s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
  8415       s->left_overhang = - s->cmp->lbearing;
  8416     }
  8417 }
  8418 
  8419 
  8420 /* Fill rectangle X, Y, W, H with background color of glyph string S.  */
  8421 
  8422 static void
  8423 x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
  8424 {
  8425   x_clear_rectangle (s->f, s->gc, x, y, w, h, s->hl != DRAW_CURSOR);
  8426 }
  8427 
  8428 #ifndef USE_CAIRO
  8429 
  8430 static void
  8431 x_clear_point (struct frame *f, GC gc, int x, int y,
  8432                bool respect_alpha_background)
  8433 {
  8434   XGCValues xgcv;
  8435   Display *dpy;
  8436 
  8437   dpy = FRAME_X_DISPLAY (f);
  8438 
  8439   if (f->alpha_background != 1.0
  8440       && respect_alpha_background)
  8441     {
  8442       x_clear_rectangle (f, gc, x, y, 1, 1, true);
  8443       return;
  8444     }
  8445 
  8446   XGetGCValues (dpy, gc, GCBackground | GCForeground, &xgcv);
  8447   XSetForeground (dpy, gc, xgcv.background);
  8448   XDrawPoint (dpy, FRAME_X_DRAWABLE (f), gc, x, y);
  8449   XSetForeground (dpy, gc, xgcv.foreground);
  8450 }
  8451 
  8452 #endif
  8453 
  8454 /* Draw the background of glyph_string S.  If S->background_filled_p
  8455    is non-zero don't draw it.  FORCE_P non-zero means draw the
  8456    background even if it wouldn't be drawn normally.  This is used
  8457    when a string preceding S draws into the background of S, or S
  8458    contains the first component of a composition.  */
  8459 
  8460 static void
  8461 x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
  8462 {
  8463   /* Nothing to do if background has already been drawn or if it
  8464      shouldn't be drawn in the first place.  */
  8465   if (!s->background_filled_p)
  8466     {
  8467       int box_line_width = max (s->face->box_horizontal_line_width, 0);
  8468 
  8469       if (s->stippled_p)
  8470         {
  8471           Display *display = FRAME_X_DISPLAY (s->f);
  8472 
  8473           /* Fill background with a stipple pattern.  */
  8474           XSetFillStyle (display, s->gc, FillOpaqueStippled);
  8475           x_fill_rectangle (s->f, s->gc, s->x,
  8476                             s->y + box_line_width,
  8477                             s->background_width,
  8478                             s->height - 2 * box_line_width,
  8479                             s->hl != DRAW_CURSOR);
  8480           XSetFillStyle (display, s->gc, FillSolid);
  8481           s->background_filled_p = true;
  8482         }
  8483       else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
  8484                /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
  8485                   font dimensions, since the actual glyphs might be
  8486                   much smaller.  So in that case we always clear the
  8487                   rectangle with background color.  */
  8488                || FONT_TOO_HIGH (s->font)
  8489                || s->font_not_found_p
  8490                || s->extends_to_end_of_line_p
  8491                || force_p)
  8492         {
  8493           x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
  8494                                      s->background_width,
  8495                                      s->height - 2 * box_line_width);
  8496           s->background_filled_p = true;
  8497         }
  8498     }
  8499 }
  8500 
  8501 
  8502 /* Draw the foreground of glyph string S.  */
  8503 
  8504 static void
  8505 x_draw_glyph_string_foreground (struct glyph_string *s)
  8506 {
  8507   int i, x;
  8508 
  8509   /* If first glyph of S has a left box line, start drawing the text
  8510      of S to the right of that box line.  */
  8511   if (s->face->box != FACE_NO_BOX
  8512       && s->first_glyph->left_box_line_p)
  8513     x = s->x + max (s->face->box_vertical_line_width, 0);
  8514   else
  8515     x = s->x;
  8516 
  8517   /* Draw characters of S as rectangles if S's font could not be
  8518      loaded.  */
  8519   if (s->font_not_found_p)
  8520     {
  8521       for (i = 0; i < s->nchars; ++i)
  8522         {
  8523           struct glyph *g = s->first_glyph + i;
  8524           x_draw_rectangle (s->f,
  8525                           s->gc, x, s->y, g->pixel_width - 1,
  8526                           s->height - 1);
  8527           x += g->pixel_width;
  8528         }
  8529     }
  8530   else
  8531     {
  8532       struct font *font = s->font;
  8533 #ifdef USE_CAIRO
  8534       if (!EQ (font->driver->type, Qx)
  8535           || x_try_cr_xlib_drawable (s->f, s->gc))
  8536         {
  8537 #endif  /* USE_CAIRO */
  8538           int boff = font->baseline_offset;
  8539           int y;
  8540 
  8541           if (font->vertical_centering)
  8542             boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
  8543 
  8544           y = s->ybase - boff;
  8545           if (s->for_overlaps
  8546               || (s->background_filled_p && s->hl != DRAW_CURSOR))
  8547             font->driver->draw (s, 0, s->nchars, x, y, false);
  8548           else
  8549             font->driver->draw (s, 0, s->nchars, x, y, true);
  8550           if (s->face->overstrike)
  8551             font->driver->draw (s, 0, s->nchars, x + 1, y, false);
  8552 #ifdef USE_CAIRO
  8553           if (EQ (font->driver->type, Qx))
  8554             x_end_cr_xlib_drawable (s->f, s->gc);
  8555         }
  8556       else
  8557         {
  8558           /* Fallback for the case that no Xlib Drawable is available
  8559              for drawing text with X core fonts.  */
  8560           if (!(s->for_overlaps
  8561                 || (s->background_filled_p && s->hl != DRAW_CURSOR)))
  8562             {
  8563               int box_line_width = max (s->face->box_horizontal_line_width, 0);
  8564 
  8565               if (s->stippled_p)
  8566                 {
  8567                   Display *display = FRAME_X_DISPLAY (s->f);
  8568 
  8569                   /* Fill background with a stipple pattern.  */
  8570                   XSetFillStyle (display, s->gc, FillOpaqueStippled);
  8571                   x_fill_rectangle (s->f, s->gc, s->x,
  8572                                     s->y + box_line_width,
  8573                                     s->background_width,
  8574                                     s->height - 2 * box_line_width,
  8575                                     false);
  8576                   XSetFillStyle (display, s->gc, FillSolid);
  8577                 }
  8578               else
  8579                 x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
  8580                                            s->background_width,
  8581                                            s->height - 2 * box_line_width);
  8582             }
  8583           for (i = 0; i < s->nchars; ++i)
  8584             {
  8585               struct glyph *g = s->first_glyph + i;
  8586               x_draw_rectangle (s->f,
  8587                                 s->gc, x, s->y, g->pixel_width - 1,
  8588                                 s->height - 1);
  8589               x += g->pixel_width;
  8590             }
  8591         }
  8592 #endif  /* USE_CAIRO */
  8593     }
  8594 }
  8595 
  8596 /* Draw the foreground of composite glyph string S.  */
  8597 
  8598 static void
  8599 x_draw_composite_glyph_string_foreground (struct glyph_string *s)
  8600 {
  8601   int i, j, x;
  8602   struct font *font = s->font;
  8603 
  8604   /* If first glyph of S has a left box line, start drawing the text
  8605      of S to the right of that box line.  */
  8606   if (s->face && s->face->box != FACE_NO_BOX
  8607       && s->first_glyph->left_box_line_p)
  8608     x = s->x + max (s->face->box_vertical_line_width, 0);
  8609   else
  8610     x = s->x;
  8611 
  8612   /* S is a glyph string for a composition.  S->cmp_from is the index
  8613      of the first character drawn for glyphs of this composition.
  8614      S->cmp_from == 0 means we are drawing the very first character of
  8615      this composition.  */
  8616 
  8617   /* Draw a rectangle for the composition if the font for the very
  8618      first character of the composition could not be loaded.  */
  8619   if (s->font_not_found_p)
  8620     {
  8621       if (s->cmp_from == 0)
  8622         x_draw_rectangle (s->f, s->gc, x, s->y,
  8623                         s->width - 1, s->height - 1);
  8624     }
  8625   else
  8626 #ifdef USE_CAIRO
  8627     if (!EQ (font->driver->type, Qx)
  8628         || x_try_cr_xlib_drawable (s->f, s->gc))
  8629       {
  8630 #endif  /* USE_CAIRO */
  8631         if (! s->first_glyph->u.cmp.automatic)
  8632           {
  8633             int y = s->ybase;
  8634 
  8635             for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
  8636               /* TAB in a composition means display glyphs with
  8637                  padding space on the left or right.  */
  8638               if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
  8639                 {
  8640                   int xx = x + s->cmp->offsets[j * 2];
  8641                   int yy = y - s->cmp->offsets[j * 2 + 1];
  8642 
  8643                   font->driver->draw (s, j, j + 1, xx, yy, false);
  8644                   if (s->face->overstrike)
  8645                     font->driver->draw (s, j, j + 1, xx + 1, yy, false);
  8646                 }
  8647           }
  8648         else
  8649           {
  8650             Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
  8651             Lisp_Object glyph;
  8652             int y = s->ybase;
  8653             int width = 0;
  8654 
  8655             for (i = j = s->cmp_from; i < s->cmp_to; i++)
  8656               {
  8657                 glyph = LGSTRING_GLYPH (gstring, i);
  8658                 if (NILP (LGLYPH_ADJUSTMENT (glyph)))
  8659                   width += LGLYPH_WIDTH (glyph);
  8660                 else
  8661                   {
  8662                     int xoff, yoff, wadjust;
  8663 
  8664                     if (j < i)
  8665                       {
  8666                         font->driver->draw (s, j, i, x, y, false);
  8667                         if (s->face->overstrike)
  8668                           font->driver->draw (s, j, i, x + 1, y, false);
  8669                         x += width;
  8670                       }
  8671                     xoff = LGLYPH_XOFF (glyph);
  8672                     yoff = LGLYPH_YOFF (glyph);
  8673                     wadjust = LGLYPH_WADJUST (glyph);
  8674                     font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false);
  8675                     if (s->face->overstrike)
  8676                       font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff,
  8677                                           false);
  8678                     x += wadjust;
  8679                     j = i + 1;
  8680                     width = 0;
  8681                   }
  8682               }
  8683             if (j < i)
  8684               {
  8685                 font->driver->draw (s, j, i, x, y, false);
  8686                 if (s->face->overstrike)
  8687                   font->driver->draw (s, j, i, x + 1, y, false);
  8688               }
  8689           }
  8690 #ifdef USE_CAIRO
  8691         if (EQ (font->driver->type, Qx))
  8692           x_end_cr_xlib_drawable (s->f, s->gc);
  8693       }
  8694     else
  8695       {
  8696         /* Fallback for the case that no Xlib Drawable is available
  8697            for drawing text with X core fonts.  */
  8698         if (s->cmp_from == 0)
  8699           x_draw_rectangle (s->f, s->gc, x, s->y,
  8700                             s->width - 1, s->height - 1);
  8701       }
  8702 #endif  /* USE_CAIRO */
  8703 }
  8704 
  8705 
  8706 /* Draw the foreground of glyph string S for glyphless characters.  */
  8707 
  8708 static void
  8709 x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
  8710 {
  8711   struct glyph *glyph = s->first_glyph;
  8712   unsigned char2b[8];
  8713   int x, i, j;
  8714 
  8715   /* If first glyph of S has a left box line, start drawing the text
  8716      of S to the right of that box line.  */
  8717   if (s->face && s->face->box != FACE_NO_BOX
  8718       && s->first_glyph->left_box_line_p)
  8719     x = s->x + max (s->face->box_vertical_line_width, 0);
  8720   else
  8721     x = s->x;
  8722 
  8723   s->char2b = char2b;
  8724 
  8725   for (i = 0; i < s->nchars; i++, glyph++)
  8726     {
  8727 #ifdef GCC_LINT
  8728       enum { PACIFY_GCC_BUG_81401 = 1 };
  8729 #else
  8730       enum { PACIFY_GCC_BUG_81401 = 0 };
  8731 #endif
  8732       char buf[7 + PACIFY_GCC_BUG_81401];
  8733       char *str = NULL;
  8734       int len = glyph->u.glyphless.len;
  8735 
  8736       if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
  8737         {
  8738           if (len > 0
  8739               && CHAR_TABLE_P (Vglyphless_char_display)
  8740               && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
  8741                   >= 1))
  8742             {
  8743               Lisp_Object acronym
  8744                 = (! glyph->u.glyphless.for_no_font
  8745                    ? CHAR_TABLE_REF (Vglyphless_char_display,
  8746                                      glyph->u.glyphless.ch)
  8747                    : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
  8748               if (CONSP (acronym))
  8749                 acronym = XCAR (acronym);
  8750               if (STRINGP (acronym))
  8751                 str = SSDATA (acronym);
  8752             }
  8753         }
  8754       else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
  8755         {
  8756           unsigned int ch = glyph->u.glyphless.ch;
  8757           eassume (ch <= MAX_CHAR);
  8758           sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
  8759           str = buf;
  8760         }
  8761 
  8762       if (str)
  8763         {
  8764           int upper_len = (len + 1) / 2;
  8765 
  8766           /* It is assured that all LEN characters in STR is ASCII.  */
  8767           for (j = 0; j < len; j++)
  8768             char2b[j] = s->font->driver->encode_char (s->font, str[j]) & 0xFFFF;
  8769           s->font->driver->draw (s, 0, upper_len,
  8770                                  x + glyph->slice.glyphless.upper_xoff,
  8771                                  s->ybase + glyph->slice.glyphless.upper_yoff,
  8772                                  false);
  8773           s->font->driver->draw (s, upper_len, len,
  8774                                  x + glyph->slice.glyphless.lower_xoff,
  8775                                  s->ybase + glyph->slice.glyphless.lower_yoff,
  8776                                  false);
  8777         }
  8778       if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
  8779         x_draw_rectangle (s->f, s->gc,
  8780                         x, s->ybase - glyph->ascent,
  8781                         glyph->pixel_width - 1,
  8782                         glyph->ascent + glyph->descent - 1);
  8783       x += glyph->pixel_width;
  8784    }
  8785 
  8786   /* Defend against hypothetical bad code elsewhere that uses
  8787      s->char2b after this function returns.  */
  8788   s->char2b = NULL;
  8789 }
  8790 
  8791 #ifdef USE_X_TOOLKIT
  8792 
  8793 #ifdef USE_LUCID
  8794 
  8795 /* Return the frame on which widget WIDGET is used.. Abort if frame
  8796    cannot be determined.  */
  8797 
  8798 static struct frame *
  8799 x_frame_of_widget (Widget widget)
  8800 {
  8801   struct x_display_info *dpyinfo;
  8802   Lisp_Object tail, frame;
  8803   struct frame *f;
  8804 
  8805   dpyinfo = x_display_info_for_display (XtDisplay (widget));
  8806 
  8807   /* Find the top-level shell of the widget.  Note that this function
  8808      can be called when the widget is not yet realized, so XtWindow
  8809      (widget) == 0.  That's the reason we can't simply use
  8810      x_any_window_to_frame.  */
  8811   while (!XtIsTopLevelShell (widget))
  8812     widget = XtParent (widget);
  8813 
  8814   /* Look for a frame with that top-level widget.  Allocate the color
  8815      on that frame to get the right gamma correction value.  */
  8816   FOR_EACH_FRAME (tail, frame)
  8817     {
  8818       f = XFRAME (frame);
  8819       if (FRAME_X_P (f)
  8820           && FRAME_DISPLAY_INFO (f) == dpyinfo
  8821           && f->output_data.x->widget == widget)
  8822         return f;
  8823     }
  8824   emacs_abort ();
  8825 }
  8826 
  8827 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
  8828    or DELTA.  Try a color with RGB values multiplied by FACTOR first.
  8829    If this produces the same color as PIXEL, try a color where all RGB
  8830    values have DELTA added.  Return the allocated color in *PIXEL.
  8831    DISPLAY is the X display, CMAP is the colormap to operate on.
  8832    Value is true if successful.  */
  8833 
  8834 bool
  8835 x_alloc_lighter_color_for_widget (Widget widget, Display *display, Colormap cmap,
  8836                                   unsigned long *pixel, double factor, int delta)
  8837 {
  8838   struct frame *f = x_frame_of_widget (widget);
  8839   return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
  8840 }
  8841 
  8842 #endif /* USE_LUCID */
  8843 
  8844 
  8845 /* Structure specifying which arguments should be passed by Xt to
  8846    cvt_string_to_pixel.  We want the widget's screen and colormap.  */
  8847 
  8848 static XtConvertArgRec cvt_string_to_pixel_args[] =
  8849   {
  8850     {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.screen),
  8851      sizeof (Screen *)},
  8852     {XtWidgetBaseOffset, (XtPointer) offsetof (WidgetRec, core.colormap),
  8853      sizeof (Colormap)}
  8854   };
  8855 
  8856 
  8857 /* The address of this variable is returned by
  8858    cvt_string_to_pixel.  */
  8859 
  8860 static Pixel cvt_string_to_pixel_value;
  8861 
  8862 
  8863 /* Convert a color name to a pixel color.
  8864 
  8865    DPY is the display we are working on.
  8866 
  8867    ARGS is an array of *NARGS XrmValue structures holding additional
  8868    information about the widget for which the conversion takes place.
  8869    The contents of this array are determined by the specification
  8870    in cvt_string_to_pixel_args.
  8871 
  8872    FROM is a pointer to an XrmValue which points to the color name to
  8873    convert.  TO is an XrmValue in which to return the pixel color.
  8874 
  8875    CLOSURE_RET is a pointer to user-data, in which we record if
  8876    we allocated the color or not.
  8877 
  8878    Value is True if successful, False otherwise.  */
  8879 
  8880 static Boolean
  8881 cvt_string_to_pixel (Display *dpy, XrmValue *args, Cardinal *nargs,
  8882                      XrmValue *from, XrmValue *to,
  8883                      XtPointer *closure_ret)
  8884 {
  8885   Screen *screen;
  8886   Colormap cmap;
  8887   Pixel pixel;
  8888   String color_name;
  8889   XColor color;
  8890 
  8891   if (*nargs != 2)
  8892     {
  8893       XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
  8894                        "wrongParameters", "cvt_string_to_pixel",
  8895                        "XtToolkitError",
  8896                        "Screen and colormap args required", NULL, NULL);
  8897       return False;
  8898     }
  8899 
  8900   screen = *(Screen **) args[0].addr;
  8901   cmap = *(Colormap *) args[1].addr;
  8902   color_name = (String) from->addr;
  8903 
  8904   if (strcmp (color_name, XtDefaultBackground) == 0)
  8905     {
  8906       *closure_ret = (XtPointer) False;
  8907       pixel = WhitePixelOfScreen (screen);
  8908     }
  8909   else if (strcmp (color_name, XtDefaultForeground) == 0)
  8910     {
  8911       *closure_ret = (XtPointer) False;
  8912       pixel = BlackPixelOfScreen (screen);
  8913     }
  8914   else if (XParseColor (dpy, cmap, color_name, &color)
  8915            && x_alloc_nearest_color_1 (dpy, cmap, &color))
  8916     {
  8917       pixel = color.pixel;
  8918       *closure_ret = (XtPointer) True;
  8919     }
  8920   else
  8921     {
  8922       String params[1];
  8923       Cardinal nparams = 1;
  8924 
  8925       params[0] = color_name;
  8926       XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
  8927                        "badValue", "cvt_string_to_pixel",
  8928                        "XtToolkitError", "Invalid color '%s'",
  8929                        params, &nparams);
  8930       return False;
  8931     }
  8932 
  8933   if (to->addr != NULL)
  8934     {
  8935       if (to->size < sizeof (Pixel))
  8936         {
  8937           to->size = sizeof (Pixel);
  8938           return False;
  8939         }
  8940 
  8941       *(Pixel *) to->addr = pixel;
  8942     }
  8943   else
  8944     {
  8945       cvt_string_to_pixel_value = pixel;
  8946       to->addr = (XtPointer) &cvt_string_to_pixel_value;
  8947     }
  8948 
  8949   to->size = sizeof (Pixel);
  8950   return True;
  8951 }
  8952 
  8953 
  8954 /* Free a pixel color which was previously allocated via
  8955    cvt_string_to_pixel.  This is registered as the destructor
  8956    for this type of resource via XtSetTypeConverter.
  8957 
  8958    APP is the application context in which we work.
  8959 
  8960    TO is a pointer to an XrmValue holding the color to free.
  8961    CLOSURE is the value we stored in CLOSURE_RET for this color
  8962    in cvt_string_to_pixel.
  8963 
  8964    ARGS and NARGS are like for cvt_string_to_pixel.  */
  8965 
  8966 static void
  8967 cvt_pixel_dtor (XtAppContext app, XrmValuePtr to, XtPointer closure, XrmValuePtr args,
  8968                 Cardinal *nargs)
  8969 {
  8970   if (*nargs != 2)
  8971     {
  8972       XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
  8973                        "XtToolkitError",
  8974                        "Screen and colormap arguments required",
  8975                        NULL, NULL);
  8976     }
  8977   else if (closure != NULL)
  8978     {
  8979       /* We did allocate the pixel, so free it.  */
  8980       Screen *screen = *(Screen **) args[0].addr;
  8981       Colormap cmap = *(Colormap *) args[1].addr;
  8982       x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
  8983                          (Pixel *) to->addr, 1);
  8984     }
  8985 }
  8986 
  8987 
  8988 #endif /* USE_X_TOOLKIT */
  8989 
  8990 
  8991 /* Value is an array of XColor structures for the contents of the
  8992    color map of display DPY.  Set *NCELLS to the size of the array.
  8993    Note that this probably shouldn't be called for large color maps,
  8994    say a 24-bit TrueColor map.  */
  8995 
  8996 static const XColor *
  8997 x_color_cells (Display *dpy, int *ncells)
  8998 {
  8999   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
  9000   eassume (dpyinfo);
  9001 
  9002   if (dpyinfo->color_cells == NULL)
  9003     {
  9004       int ncolor_cells = dpyinfo->visual_info.colormap_size;
  9005       int i;
  9006 
  9007       dpyinfo->color_cells = xnmalloc (ncolor_cells,
  9008                                        sizeof *dpyinfo->color_cells);
  9009       dpyinfo->ncolor_cells = ncolor_cells;
  9010 
  9011       for (i = 0; i < ncolor_cells; ++i)
  9012         dpyinfo->color_cells[i].pixel = i;
  9013 
  9014       XQueryColors (dpy, dpyinfo->cmap,
  9015                     dpyinfo->color_cells, ncolor_cells);
  9016     }
  9017 
  9018   *ncells = dpyinfo->ncolor_cells;
  9019   return dpyinfo->color_cells;
  9020 }
  9021 
  9022 
  9023 /* On frame F, translate pixel colors to RGB values for the NCOLORS
  9024    colors in COLORS.  Use cached information, if available.
  9025 
  9026    Pixel values are in unsigned normalized format, meaning that
  9027    extending missing bits is done straightforwardly without any
  9028    complex colorspace conversions.  */
  9029 
  9030 void
  9031 x_query_colors (struct frame *f, XColor *colors, int ncolors)
  9032 {
  9033   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  9034   int i;
  9035 
  9036   if (dpyinfo->red_bits > 0)
  9037     {
  9038       /* For TrueColor displays, we can decompose the RGB value
  9039          directly.  */
  9040       unsigned int rmult, gmult, bmult;
  9041       unsigned int rmask, gmask, bmask;
  9042 
  9043       rmask = (1 << dpyinfo->red_bits) - 1;
  9044       gmask = (1 << dpyinfo->green_bits) - 1;
  9045       bmask = (1 << dpyinfo->blue_bits) - 1;
  9046       /* If we're widening, for example, 8 bits in the pixel value to
  9047          16 bits for the separate-color representation, we want to
  9048          extrapolate the lower bits based on those bits available --
  9049          in other words, we'd like 0xff to become 0xffff instead of
  9050          the 0xff00 we'd get by just zero-filling the lower bits.
  9051 
  9052          We generate a 32-bit scaled-up value and shift it, in case
  9053          the bit count doesn't divide 16 evenly (e.g., when dealing
  9054          with a 3-3-2 bit RGB display), to get more of the lower bits
  9055          correct.
  9056 
  9057          Should we cache the multipliers in dpyinfo?  Maybe
  9058          special-case the 8-8-8 common case?  */
  9059       rmult = 0xffffffff / rmask;
  9060       gmult = 0xffffffff / gmask;
  9061       bmult = 0xffffffff / bmask;
  9062 
  9063       for (i = 0; i < ncolors; ++i)
  9064         {
  9065           unsigned int r, g, b;
  9066           unsigned long pixel = colors[i].pixel;
  9067 
  9068           r = (pixel >> dpyinfo->red_offset) & rmask;
  9069           g = (pixel >> dpyinfo->green_offset) & gmask;
  9070           b = (pixel >> dpyinfo->blue_offset) & bmask;
  9071 
  9072           colors[i].red = (r * rmult) >> 16;
  9073           colors[i].green = (g * gmult) >> 16;
  9074           colors[i].blue = (b * bmult) >> 16;
  9075         }
  9076 
  9077       return;
  9078     }
  9079 
  9080   if (dpyinfo->color_cells)
  9081     {
  9082       int i;
  9083       for (i = 0; i < ncolors; ++i)
  9084         {
  9085           unsigned long pixel = colors[i].pixel;
  9086           eassert (pixel < dpyinfo->ncolor_cells);
  9087           eassert (dpyinfo->color_cells[pixel].pixel == pixel);
  9088           colors[i] = dpyinfo->color_cells[pixel];
  9089         }
  9090       return;
  9091     }
  9092 
  9093   XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
  9094 }
  9095 
  9096 /* Store F's real background color into *BGCOLOR.  */
  9097 
  9098 static void
  9099 x_query_frame_background_color (struct frame *f, XColor *bgcolor)
  9100 {
  9101   unsigned long background = FRAME_BACKGROUND_PIXEL (f);
  9102 #ifndef USE_CAIRO
  9103   XColor bg;
  9104 #endif
  9105 
  9106   if (FRAME_DISPLAY_INFO (f)->alpha_bits)
  9107     {
  9108 #ifdef USE_CAIRO
  9109       background = (background & ~FRAME_DISPLAY_INFO (f)->alpha_mask);
  9110       background |= (((unsigned long) (f->alpha_background * 0xffff)
  9111                       >> (16 - FRAME_DISPLAY_INFO (f)->alpha_bits))
  9112                      << FRAME_DISPLAY_INFO (f)->alpha_offset);
  9113 #else
  9114       if (FRAME_DISPLAY_INFO (f)->alpha_bits
  9115           && f->alpha_background < 1.0)
  9116         {
  9117           bg.pixel = background;
  9118           x_query_colors (f, &bg, 1);
  9119 
  9120           background
  9121             = x_premultiply_pixel (FRAME_DISPLAY_INFO (f),
  9122                                    &bg, f->alpha_background);
  9123         }
  9124 #endif
  9125     }
  9126 
  9127   bgcolor->pixel = background;
  9128 
  9129   x_query_colors (f, bgcolor, 1);
  9130 }
  9131 
  9132 static unsigned int
  9133 x_hash_string_ignore_case (const char *string)
  9134 {
  9135   unsigned int i;
  9136 
  9137   i = 3323198485ul;
  9138   for (; *string; ++string)
  9139     {
  9140       i ^= c_tolower (*string);
  9141       i *= 0x5bd1e995;
  9142       i ^= i >> 15;
  9143     }
  9144   return i;
  9145 }
  9146 
  9147 /* On frame F, translate the color name to RGB values.  Use cached
  9148    information, if possible.
  9149 
  9150    If too many entries are placed in the cache, the least recently
  9151    used entries are removed.  */
  9152 
  9153 Status
  9154 x_parse_color (struct frame *f, const char *color_name,
  9155                XColor *color)
  9156 {
  9157   unsigned short r, g, b;
  9158   Display *dpy;
  9159   Colormap cmap;
  9160   struct x_display_info *dpyinfo;
  9161   struct color_name_cache_entry *cache_entry, *last;
  9162   struct color_name_cache_entry *next, *color_entry;
  9163   unsigned int hash, idx;
  9164   int rc, i;
  9165 
  9166   /* Don't pass #RGB strings directly to XParseColor, because that
  9167      follows the X convention of zero-extending each channel
  9168      value: #f00 means #f00000.  We want the convention of scaling
  9169      channel values, so #f00 means #ff0000, just as it does for
  9170      HTML, SVG, and CSS.  */
  9171   if (parse_color_spec (color_name, &r, &g, &b))
  9172     {
  9173       color->red = r;
  9174       color->green = g;
  9175       color->blue = b;
  9176 
  9177       return 1;
  9178     }
  9179 
  9180   /* Some X servers send BadValue on empty color names.  */
  9181   if (!strlen (color_name))
  9182     return 0;
  9183 
  9184   cmap = FRAME_X_COLORMAP (f);
  9185   dpy = FRAME_X_DISPLAY (f);
  9186   dpyinfo = FRAME_DISPLAY_INFO (f);
  9187 
  9188   hash = x_hash_string_ignore_case (color_name);
  9189   idx = hash % dpyinfo->color_names_size;
  9190 
  9191   last = NULL;
  9192 
  9193   for (cache_entry = dpyinfo->color_names[idx];
  9194        cache_entry; cache_entry = cache_entry->next)
  9195     {
  9196       if (!xstrcasecmp (cache_entry->name, color_name))
  9197         {
  9198           /* Move recently used entries to the start of the color
  9199              cache.  */
  9200 
  9201           if (last)
  9202             {
  9203               last->next = cache_entry->next;
  9204               cache_entry->next = dpyinfo->color_names[idx];
  9205 
  9206               dpyinfo->color_names[idx] = cache_entry;
  9207             }
  9208 
  9209           if (cache_entry->valid)
  9210             *color = cache_entry->rgb;
  9211 
  9212           return cache_entry->valid;
  9213         }
  9214 
  9215       last = cache_entry;
  9216     }
  9217 
  9218   block_input ();
  9219   rc = XParseColor (dpy, cmap, color_name, color);
  9220   unblock_input ();
  9221 
  9222   cache_entry = xzalloc (sizeof *cache_entry);
  9223   dpyinfo->color_names_length[idx] += 1;
  9224 
  9225   if (rc)
  9226     cache_entry->rgb = *color;
  9227 
  9228   cache_entry->valid = rc;
  9229   cache_entry->name = xstrdup (color_name);
  9230   cache_entry->next = dpyinfo->color_names[idx];
  9231 
  9232   dpyinfo->color_names[idx] = cache_entry;
  9233 
  9234   /* Don't let the color cache become too big.  */
  9235   if (dpyinfo->color_names_length[idx] > (x_color_cache_bucket_size > 0
  9236                                           ? x_color_cache_bucket_size : 128))
  9237     {
  9238       i = 0;
  9239 
  9240       for (last = dpyinfo->color_names[idx]; last; last = last->next)
  9241         {
  9242           if (++i == (x_color_cache_bucket_size > 0
  9243                       ? x_color_cache_bucket_size : 128))
  9244             {
  9245               next = last->next;
  9246               last->next = NULL;
  9247 
  9248               for (color_entry = next; color_entry; color_entry = last)
  9249                 {
  9250                   last = color_entry->next;
  9251 
  9252                   xfree (color_entry->name);
  9253                   xfree (color_entry);
  9254 
  9255                   dpyinfo->color_names_length[idx] -= 1;
  9256                 }
  9257 
  9258               return rc;
  9259             }
  9260         }
  9261     }
  9262 
  9263   return rc;
  9264 }
  9265 
  9266 
  9267 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP.  If an
  9268    exact match can't be allocated, try the nearest color available.
  9269    Value is true if successful.  Set *COLOR to the color
  9270    allocated.  */
  9271 
  9272 static bool
  9273 x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color)
  9274 {
  9275   struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
  9276   bool rc;
  9277 
  9278   eassume (dpyinfo);
  9279   rc = XAllocColor (dpy, cmap, color) != 0;
  9280 
  9281   if (dpyinfo->visual_info.class == DirectColor)
  9282     return rc;
  9283 
  9284   if (rc == 0)
  9285     {
  9286       /* If we got to this point, the colormap is full, so we're going
  9287          to try and get the next closest color.  The algorithm used is
  9288          a least-squares matching, which is what X uses for closest
  9289          color matching with StaticColor visuals.  */
  9290 
  9291       const XColor *cells;
  9292       int no_cells;
  9293       int nearest;
  9294       long nearest_delta, trial_delta;
  9295       int x;
  9296       Status status;
  9297       bool retry = false;
  9298       int ncolor_cells, i;
  9299       bool temp_allocated;
  9300       XColor temp;
  9301 
  9302     start:
  9303       cells = x_color_cells (dpy, &no_cells);
  9304       temp_allocated = false;
  9305 
  9306       nearest = 0;
  9307       /* I'm assuming CSE so I'm not going to condense this. */
  9308       nearest_delta = ((((color->red >> 8) - (cells[0].red >> 8))
  9309                         * ((color->red >> 8) - (cells[0].red >> 8)))
  9310                        + (((color->green >> 8) - (cells[0].green >> 8))
  9311                           * ((color->green >> 8) - (cells[0].green >> 8)))
  9312                        + (((color->blue >> 8) - (cells[0].blue >> 8))
  9313                           * ((color->blue >> 8) - (cells[0].blue >> 8))));
  9314       for (x = 1; x < no_cells; x++)
  9315         {
  9316           trial_delta = ((((color->red >> 8) - (cells[x].red >> 8))
  9317                           * ((color->red >> 8) - (cells[x].red >> 8)))
  9318                          + (((color->green >> 8) - (cells[x].green >> 8))
  9319                             * ((color->green >> 8) - (cells[x].green >> 8)))
  9320                          + (((color->blue >> 8) - (cells[x].blue >> 8))
  9321                             * ((color->blue >> 8) - (cells[x].blue >> 8))));
  9322           if (trial_delta < nearest_delta)
  9323             {
  9324               /* We didn't decide to use this color, so free it.  */
  9325               if (temp_allocated)
  9326                 {
  9327                   XFreeColors (dpy, cmap, &temp.pixel, 1, 0);
  9328                   temp_allocated = false;
  9329                 }
  9330 
  9331               temp.red = cells[x].red;
  9332               temp.green = cells[x].green;
  9333               temp.blue = cells[x].blue;
  9334               status = XAllocColor (dpy, cmap, &temp);
  9335 
  9336               if (status)
  9337                 {
  9338                   temp_allocated = true;
  9339                   nearest = x;
  9340                   nearest_delta = trial_delta;
  9341                 }
  9342             }
  9343         }
  9344       color->red = cells[nearest].red;
  9345       color->green = cells[nearest].green;
  9346       color->blue = cells[nearest].blue;
  9347 
  9348       if (!temp_allocated)
  9349         status = XAllocColor (dpy, cmap, color);
  9350       else
  9351         {
  9352           *color = temp;
  9353           status = 1;
  9354         }
  9355 
  9356       if (status == 0 && !retry)
  9357         {
  9358           /* Our private cache of color cells is probably out of date.
  9359              Refresh it here, and try to allocate the nearest color
  9360              from the new colormap.  */
  9361 
  9362           retry = true;
  9363           xfree (dpyinfo->color_cells);
  9364 
  9365           ncolor_cells = dpyinfo->visual_info.colormap_size;
  9366 
  9367           dpyinfo->color_cells = xnmalloc (ncolor_cells,
  9368                                            sizeof *dpyinfo->color_cells);
  9369           dpyinfo->ncolor_cells = ncolor_cells;
  9370 
  9371           for (i = 0; i < ncolor_cells; ++i)
  9372             dpyinfo->color_cells[i].pixel = i;
  9373 
  9374           XQueryColors (dpy, dpyinfo->cmap,
  9375                         dpyinfo->color_cells, ncolor_cells);
  9376 
  9377           goto start;
  9378         }
  9379 
  9380       rc = status != 0;
  9381     }
  9382   else
  9383     {
  9384       /* If allocation succeeded, and the allocated pixel color is not
  9385          equal to a cached pixel color recorded earlier, there was a
  9386          change in the colormap, so clear the color cache.  */
  9387       struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
  9388       eassume (dpyinfo);
  9389 
  9390       if (dpyinfo->color_cells)
  9391         {
  9392           XColor *cached_color = &dpyinfo->color_cells[color->pixel];
  9393           if (cached_color->red != color->red
  9394               || cached_color->blue != color->blue
  9395               || cached_color->green != color->green)
  9396             {
  9397               xfree (dpyinfo->color_cells);
  9398               dpyinfo->color_cells = NULL;
  9399               dpyinfo->ncolor_cells = 0;
  9400             }
  9401         }
  9402     }
  9403 
  9404 #ifdef DEBUG_X_COLORS
  9405   if (rc)
  9406     register_color (color->pixel);
  9407 #endif /* DEBUG_X_COLORS */
  9408 
  9409   return rc;
  9410 }
  9411 
  9412 
  9413 /* Allocate the color COLOR->pixel on frame F, colormap CMAP, after
  9414    gamma correction.  If an exact match can't be allocated, try the
  9415    nearest color available.  Value is true if successful.  Set *COLOR
  9416    to the color allocated.  */
  9417 
  9418 bool
  9419 x_alloc_nearest_color (struct frame *f, Colormap cmap, XColor *color)
  9420 {
  9421   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  9422 
  9423   gamma_correct (f, color);
  9424 
  9425   if (dpyinfo->red_bits > 0)
  9426     {
  9427       color->pixel = x_make_truecolor_pixel (dpyinfo,
  9428                                              color->red,
  9429                                              color->green,
  9430                                              color->blue);
  9431       return true;
  9432     }
  9433 
  9434   return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
  9435 }
  9436 
  9437 
  9438 /* Allocate color PIXEL on frame F.  PIXEL must already be allocated.
  9439    It's necessary to do this instead of just using PIXEL directly to
  9440    get color reference counts right.  */
  9441 
  9442 unsigned long
  9443 x_copy_color (struct frame *f, unsigned long pixel)
  9444 {
  9445   XColor color;
  9446 
  9447   /* If display has an immutable color map, freeing colors is not
  9448      necessary and some servers don't allow it.  Since we won't free a
  9449      color once we've allocated it, we don't need to re-allocate it to
  9450      maintain the server's reference count.  */
  9451   if (!x_mutable_colormap (FRAME_X_VISUAL_INFO (f)))
  9452     return pixel;
  9453 
  9454   color.pixel = pixel;
  9455   block_input ();
  9456   /* The color could still be found in the color_cells array.  */
  9457   x_query_colors (f, &color, 1);
  9458   XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
  9459   unblock_input ();
  9460 #ifdef DEBUG_X_COLORS
  9461   register_color (pixel);
  9462 #endif
  9463   return color.pixel;
  9464 }
  9465 
  9466 
  9467 /* Brightness beyond which a color won't have its highlight brightness
  9468    boosted.
  9469 
  9470    Nominally, highlight colors for `3d' faces are calculated by
  9471    brightening an object's color by a constant scale factor, but this
  9472    doesn't yield good results for dark colors, so for colors who's
  9473    brightness is less than this value (on a scale of 0-65535) have an
  9474    use an additional additive factor.
  9475 
  9476    The value here is set so that the default menu-bar/mode-line color
  9477    (grey75) will not have its highlights changed at all.  */
  9478 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
  9479 
  9480 
  9481 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
  9482    or DELTA.  Try a color with RGB values multiplied by FACTOR first.
  9483    If this produces the same color as PIXEL, try a color where all RGB
  9484    values have DELTA added.  Return the allocated color in *PIXEL.
  9485    DISPLAY is the X display, CMAP is the colormap to operate on.
  9486    Value is non-zero if successful.  */
  9487 
  9488 static bool
  9489 x_alloc_lighter_color (struct frame *f, Display *display, Colormap cmap,
  9490                        unsigned long *pixel, double factor, int delta)
  9491 {
  9492   XColor color, new;
  9493   long bright;
  9494   bool success_p;
  9495 
  9496   /* Get RGB color values.  */
  9497   color.pixel = *pixel;
  9498   x_query_colors (f, &color, 1);
  9499 
  9500   /* Change RGB values by specified FACTOR.  Avoid overflow!  */
  9501   eassert (factor >= 0);
  9502   new.red = min (0xffff, factor * color.red);
  9503   new.green = min (0xffff, factor * color.green);
  9504   new.blue = min (0xffff, factor * color.blue);
  9505 
  9506   /* Calculate brightness of COLOR.  */
  9507   bright = (2 * color.red + 3 * color.green + color.blue) / 6;
  9508 
  9509   /* We only boost colors that are darker than
  9510      HIGHLIGHT_COLOR_DARK_BOOST_LIMIT.  */
  9511   if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
  9512     /* Make an additive adjustment to NEW, because it's dark enough so
  9513        that scaling by FACTOR alone isn't enough.  */
  9514     {
  9515       /* How far below the limit this color is (0 - 1, 1 being darker).  */
  9516       double dimness = 1 - (double) bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
  9517       /* The additive adjustment.  */
  9518       int min_delta = delta * dimness * factor / 2;
  9519 
  9520       if (factor < 1)
  9521         {
  9522           new.red =   max (0, new.red -   min_delta);
  9523           new.green = max (0, new.green - min_delta);
  9524           new.blue =  max (0, new.blue -  min_delta);
  9525         }
  9526       else
  9527         {
  9528           new.red =   min (0xffff, min_delta + new.red);
  9529           new.green = min (0xffff, min_delta + new.green);
  9530           new.blue =  min (0xffff, min_delta + new.blue);
  9531         }
  9532     }
  9533 
  9534   /* Try to allocate the color.  */
  9535   success_p = x_alloc_nearest_color (f, cmap, &new);
  9536   if (success_p)
  9537     {
  9538       if (new.pixel == *pixel)
  9539         {
  9540           /* If we end up with the same color as before, try adding
  9541              delta to the RGB values.  */
  9542           x_free_colors (f, &new.pixel, 1);
  9543 
  9544           new.red = min (0xffff, delta + color.red);
  9545           new.green = min (0xffff, delta + color.green);
  9546           new.blue = min (0xffff, delta + color.blue);
  9547           success_p = x_alloc_nearest_color (f, cmap, &new);
  9548         }
  9549       else
  9550         success_p = true;
  9551       *pixel = new.pixel;
  9552     }
  9553 
  9554   return success_p;
  9555 }
  9556 
  9557 
  9558 /* Set up the foreground color for drawing relief lines of glyph
  9559    string S.  RELIEF is a pointer to a struct relief containing the GC
  9560    with which lines will be drawn.  Use a color that is FACTOR or
  9561    DELTA lighter or darker than the relief's background which is found
  9562    in S->f->output_data.x->relief_background.  If such a color cannot
  9563    be allocated, use DEFAULT_PIXEL, instead.  */
  9564 
  9565 static void
  9566 x_setup_relief_color (struct frame *f, struct relief *relief, double factor,
  9567                       int delta, unsigned long default_pixel)
  9568 {
  9569   XGCValues xgcv;
  9570   struct x_output *di = f->output_data.x;
  9571   unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
  9572   unsigned long pixel;
  9573   unsigned long background = di->relief_background;
  9574   Colormap cmap = FRAME_X_COLORMAP (f);
  9575   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
  9576   Display *dpy = FRAME_X_DISPLAY (f);
  9577 
  9578   xgcv.graphics_exposures = False;
  9579   xgcv.line_width = 1;
  9580 
  9581   /* Free previously allocated color.  The color cell will be reused
  9582      when it has been freed as many times as it was allocated, so this
  9583      doesn't affect faces using the same colors.  */
  9584   if (relief->gc && relief->pixel != -1)
  9585     {
  9586       x_free_colors (f, &relief->pixel, 1);
  9587       relief->pixel = -1;
  9588     }
  9589 
  9590   /* Allocate new color.  */
  9591   xgcv.foreground = default_pixel;
  9592   pixel = background;
  9593   if (dpyinfo->n_planes != 1
  9594       && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta))
  9595     xgcv.foreground = relief->pixel = pixel;
  9596 
  9597   if (relief->gc == 0)
  9598     {
  9599       xgcv.stipple = dpyinfo->gray;
  9600       mask |= GCStipple;
  9601       relief->gc = XCreateGC (dpy, FRAME_X_DRAWABLE (f), mask, &xgcv);
  9602     }
  9603   else
  9604     XChangeGC (dpy, relief->gc, mask, &xgcv);
  9605 }
  9606 
  9607 
  9608 /* Set up colors for the relief lines around glyph string S.  */
  9609 
  9610 static void
  9611 x_setup_relief_colors (struct glyph_string *s)
  9612 {
  9613   struct x_output *di = s->f->output_data.x;
  9614   unsigned long color;
  9615 
  9616   if (s->face->use_box_color_for_shadows_p)
  9617     color = s->face->box_color;
  9618   else if (s->first_glyph->type == IMAGE_GLYPH
  9619            && s->img->pixmap
  9620            && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
  9621     color = IMAGE_BACKGROUND (s->img, s->f, 0);
  9622   else
  9623     {
  9624       XGCValues xgcv;
  9625 
  9626       /* Get the background color of the face.  */
  9627       XGetGCValues (FRAME_X_DISPLAY (s->f), s->gc, GCBackground, &xgcv);
  9628       color = xgcv.background;
  9629     }
  9630 
  9631   if (di->white_relief.gc == 0
  9632       || color != di->relief_background)
  9633     {
  9634       di->relief_background = color;
  9635       x_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
  9636                             WHITE_PIX_DEFAULT (s->f));
  9637       x_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
  9638                             BLACK_PIX_DEFAULT (s->f));
  9639     }
  9640 }
  9641 
  9642 #ifndef USE_CAIRO
  9643 static void
  9644 x_fill_triangle (struct frame *f, GC gc, XPoint point1,
  9645                  XPoint point2, XPoint point3)
  9646 {
  9647   XPoint abc[3];
  9648 
  9649   abc[0] = point1;
  9650   abc[1] = point2;
  9651   abc[2] = point3;
  9652 
  9653   XFillPolygon (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
  9654                 gc, abc, 3, Convex, CoordModeOrigin);
  9655 }
  9656 
  9657 static XPoint
  9658 x_make_point (int x, int y)
  9659 {
  9660   XPoint pt;
  9661 
  9662   pt.x = x;
  9663   pt.y = y;
  9664 
  9665   return pt;
  9666 }
  9667 
  9668 static bool
  9669 x_inside_rect_p (XRectangle *rects, int nrects, int x, int y)
  9670 {
  9671   int i;
  9672 
  9673   for (i = 0; i < nrects; ++i)
  9674     {
  9675       if (x >= rects[i].x && y >= rects[i].y
  9676           && x < rects[i].x + rects[i].width
  9677           && y < rects[i].y + rects[i].height)
  9678         return true;
  9679     }
  9680 
  9681   return false;
  9682 }
  9683 #endif
  9684 
  9685 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
  9686    TOP_Y, RIGHT_X, and BOTTOM_Y.  VWIDTH and HWIDTH are respectively
  9687    the thickness of the vertical relief (left and right) and
  9688    horizontal relief (top and bottom) to draw, it must be >= 0.
  9689    RAISED_P means draw a raised relief.  LEFT_P means draw a relief on
  9690    the left side of the rectangle.  RIGHT_P means draw a relief on the
  9691    right side of the rectangle.  CLIP_RECT is the clipping rectangle
  9692    to use when drawing.  */
  9693 
  9694 static void
  9695 x_draw_relief_rect (struct frame *f, int left_x, int top_y, int right_x,
  9696                     int bottom_y, int hwidth, int vwidth, bool raised_p,
  9697                     bool top_p, bool bot_p, bool left_p, bool right_p,
  9698                     XRectangle *clip_rect)
  9699 {
  9700 #ifdef USE_CAIRO
  9701   GC top_left_gc, bottom_right_gc;
  9702   int corners = 0;
  9703 
  9704   if (raised_p)
  9705     {
  9706       top_left_gc = f->output_data.x->white_relief.gc;
  9707       bottom_right_gc = f->output_data.x->black_relief.gc;
  9708     }
  9709   else
  9710     {
  9711       top_left_gc = f->output_data.x->black_relief.gc;
  9712       bottom_right_gc = f->output_data.x->white_relief.gc;
  9713     }
  9714 
  9715   x_set_clip_rectangles (f, top_left_gc, clip_rect, 1);
  9716   x_set_clip_rectangles (f, bottom_right_gc, clip_rect, 1);
  9717 
  9718   if (left_p)
  9719     {
  9720       x_fill_rectangle (f, top_left_gc, left_x, top_y,
  9721                         vwidth, bottom_y + 1 - top_y, false);
  9722       if (top_p)
  9723         corners |= 1 << CORNER_TOP_LEFT;
  9724       if (bot_p)
  9725         corners |= 1 << CORNER_BOTTOM_LEFT;
  9726     }
  9727   if (right_p)
  9728     {
  9729       x_fill_rectangle (f, bottom_right_gc, right_x + 1 - vwidth, top_y,
  9730                         vwidth, bottom_y + 1 - top_y, false);
  9731       if (top_p)
  9732         corners |= 1 << CORNER_TOP_RIGHT;
  9733       if (bot_p)
  9734         corners |= 1 << CORNER_BOTTOM_RIGHT;
  9735     }
  9736   if (top_p)
  9737     {
  9738       if (!right_p)
  9739         x_fill_rectangle (f, top_left_gc, left_x, top_y,
  9740                           right_x + 1 - left_x, hwidth, false);
  9741       else
  9742         x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
  9743                                      right_x + 1 - left_x, hwidth, 1);
  9744     }
  9745   if (bot_p)
  9746     {
  9747       if (!left_p)
  9748         x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - hwidth,
  9749                           right_x + 1 - left_x, hwidth, false);
  9750       else
  9751         x_fill_trapezoid_for_relief (f, bottom_right_gc,
  9752                                      left_x, bottom_y + 1 - hwidth,
  9753                                      right_x + 1 - left_x, hwidth, 0);
  9754     }
  9755   if (left_p && vwidth > 1)
  9756     x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
  9757                       1, bottom_y + 1 - top_y, false);
  9758   if (top_p && hwidth > 1)
  9759     x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
  9760                       right_x + 1 - left_x, 1, false);
  9761   if (corners)
  9762     {
  9763       XSetBackground (FRAME_X_DISPLAY (f), top_left_gc,
  9764                       FRAME_BACKGROUND_PIXEL (f));
  9765       x_erase_corners_for_relief (f, top_left_gc, left_x, top_y,
  9766                                   right_x - left_x + 1, bottom_y - top_y + 1,
  9767                                   6, 1, corners);
  9768     }
  9769 
  9770   x_reset_clip_rectangles (f, top_left_gc);
  9771   x_reset_clip_rectangles (f, bottom_right_gc);
  9772 #else
  9773   GC gc, white_gc, black_gc, normal_gc;
  9774   Drawable drawable;
  9775   Display *dpy;
  9776 
  9777   /* This code is more complicated than it has to be, because of two
  9778      minor hacks to make the boxes look nicer: (i) if width > 1, draw
  9779      the outermost line using the black relief.  (ii) Omit the four
  9780      corner pixels.  */
  9781 
  9782   white_gc = f->output_data.x->white_relief.gc;
  9783   black_gc = f->output_data.x->black_relief.gc;
  9784   normal_gc = f->output_data.x->normal_gc;
  9785 
  9786   drawable = FRAME_X_DRAWABLE (f);
  9787   dpy = FRAME_X_DISPLAY (f);
  9788 
  9789   x_set_clip_rectangles (f, white_gc, clip_rect, 1);
  9790   x_set_clip_rectangles (f, black_gc, clip_rect, 1);
  9791 
  9792   if (raised_p)
  9793     gc = white_gc;
  9794   else
  9795     gc = black_gc;
  9796 
  9797   /* Draw lines.  */
  9798 
  9799   if (top_p)
  9800     x_fill_rectangle (f, gc, left_x, top_y,
  9801                       right_x - left_x + 1, hwidth,
  9802                       false);
  9803 
  9804   if (left_p)
  9805     x_fill_rectangle (f, gc, left_x, top_y, vwidth,
  9806                       bottom_y - top_y + 1, false);
  9807 
  9808   if (raised_p)
  9809     gc = black_gc;
  9810   else
  9811     gc = white_gc;
  9812 
  9813   if (bot_p)
  9814     x_fill_rectangle (f, gc, left_x, bottom_y - hwidth + 1,
  9815                       right_x - left_x + 1, hwidth, false);
  9816 
  9817   if (right_p)
  9818     x_fill_rectangle (f, gc, right_x - vwidth + 1, top_y,
  9819                       vwidth, bottom_y - top_y + 1, false);
  9820 
  9821   /* Draw corners.  */
  9822 
  9823   if (bot_p && left_p)
  9824     x_fill_triangle (f, raised_p ? white_gc : black_gc,
  9825                      x_make_point (left_x, bottom_y - hwidth),
  9826                      x_make_point (left_x + vwidth, bottom_y - hwidth),
  9827                      x_make_point (left_x, bottom_y));
  9828 
  9829   if (top_p && right_p)
  9830     x_fill_triangle (f, raised_p ? white_gc : black_gc,
  9831                      x_make_point (right_x - vwidth, top_y),
  9832                      x_make_point (right_x, top_y),
  9833                      x_make_point (right_x - vwidth, top_y + hwidth));
  9834 
  9835   /* Draw outer line.  */
  9836 
  9837   if (top_p && left_p && bot_p && right_p
  9838       && hwidth > 1 && vwidth > 1)
  9839     x_draw_rectangle (f, black_gc, left_x, top_y,
  9840                       right_x - left_x, bottom_y - top_y);
  9841   else
  9842     {
  9843       if (top_p && hwidth > 1)
  9844         XDrawLine (dpy, drawable, black_gc, left_x, top_y,
  9845                    right_x + 1, top_y);
  9846 
  9847       if (bot_p && hwidth > 1)
  9848         XDrawLine (dpy, drawable, black_gc, left_x, bottom_y,
  9849                    right_x + 1, bottom_y);
  9850 
  9851       if (left_p && vwidth > 1)
  9852         XDrawLine (dpy, drawable, black_gc, left_x, top_y,
  9853                    left_x, bottom_y + 1);
  9854 
  9855       if (right_p && vwidth > 1)
  9856         XDrawLine (dpy, drawable, black_gc, right_x, top_y,
  9857                    right_x, bottom_y + 1);
  9858     }
  9859 
  9860   /* Erase corners.  */
  9861 
  9862   if (hwidth > 1 && vwidth > 1)
  9863     {
  9864       if (left_p && top_p && x_inside_rect_p (clip_rect, 1,
  9865                                               left_x, top_y))
  9866         /* This should respect `alpha-background' since it's being
  9867            cleared with the background color of the frame.  */
  9868         x_clear_point (f, normal_gc, left_x, top_y, true);
  9869 
  9870       if (left_p && bot_p && x_inside_rect_p (clip_rect, 1,
  9871                                               left_x, bottom_y))
  9872         x_clear_point (f, normal_gc, left_x, bottom_y, true);
  9873 
  9874       if (right_p && top_p && x_inside_rect_p (clip_rect, 1,
  9875                                                right_x, top_y))
  9876         x_clear_point (f, normal_gc, right_x, top_y, true);
  9877 
  9878       if (right_p && bot_p && x_inside_rect_p (clip_rect, 1,
  9879                                                right_x, bottom_y))
  9880         x_clear_point (f, normal_gc, right_x, bottom_y, true);
  9881     }
  9882 
  9883   x_reset_clip_rectangles (f, white_gc);
  9884   x_reset_clip_rectangles (f, black_gc);
  9885 #endif
  9886 }
  9887 
  9888 
  9889 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
  9890    RIGHT_X, and BOTTOM_Y.  WIDTH is the thickness of the lines to
  9891    draw, it must be >= 0.  LEFT_P means draw a line on the
  9892    left side of the rectangle.  RIGHT_P means draw a line
  9893    on the right side of the rectangle.  CLIP_RECT is the clipping
  9894    rectangle to use when drawing.  */
  9895 
  9896 static void
  9897 x_draw_box_rect (struct glyph_string *s,
  9898                  int left_x, int top_y, int right_x, int bottom_y, int hwidth,
  9899                  int vwidth, bool left_p, bool right_p, XRectangle *clip_rect)
  9900 {
  9901   Display *display = FRAME_X_DISPLAY (s->f);
  9902   XGCValues xgcv;
  9903 
  9904   XGetGCValues (display, s->gc, GCForeground, &xgcv);
  9905   XSetForeground (display, s->gc, s->face->box_color);
  9906   x_set_clip_rectangles (s->f, s->gc, clip_rect, 1);
  9907 
  9908   /* Top.  */
  9909   x_fill_rectangle (s->f, s->gc,
  9910                     left_x, top_y, right_x - left_x + 1, hwidth,
  9911                     false);
  9912 
  9913   /* Left.  */
  9914   if (left_p)
  9915     x_fill_rectangle (s->f, s->gc,
  9916                       left_x, top_y, vwidth, bottom_y - top_y + 1,
  9917                       false);
  9918 
  9919   /* Bottom.  */
  9920   x_fill_rectangle (s->f, s->gc,
  9921                     left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth,
  9922                     false);
  9923 
  9924   /* Right.  */
  9925   if (right_p)
  9926     x_fill_rectangle (s->f, s->gc,
  9927                       right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1,
  9928                       false);
  9929 
  9930   XSetForeground (display, s->gc, xgcv.foreground);
  9931   x_reset_clip_rectangles (s->f, s->gc);
  9932 }
  9933 
  9934 
  9935 /* Draw a box around glyph string S.  */
  9936 
  9937 static void
  9938 x_draw_glyph_string_box (struct glyph_string *s)
  9939 {
  9940   int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
  9941   bool raised_p, left_p, right_p;
  9942   struct glyph *last_glyph;
  9943   XRectangle clip_rect;
  9944 
  9945   last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
  9946             ? WINDOW_RIGHT_EDGE_X (s->w)
  9947             : window_box_right (s->w, s->area));
  9948 
  9949   /* The glyph that may have a right box line.  For static
  9950      compositions and images, the right-box flag is on the first glyph
  9951      of the glyph string; for other types it's on the last glyph.  */
  9952   if (s->cmp || s->img)
  9953     last_glyph = s->first_glyph;
  9954   else if (s->first_glyph->type == COMPOSITE_GLYPH
  9955            && s->first_glyph->u.cmp.automatic)
  9956     {
  9957       /* For automatic compositions, we need to look up the last glyph
  9958          in the composition.  */
  9959         struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
  9960         struct glyph *g = s->first_glyph;
  9961         for (last_glyph = g++;
  9962              g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
  9963                && g->slice.cmp.to < s->cmp_to;
  9964              last_glyph = g++)
  9965           ;
  9966     }
  9967   else
  9968     last_glyph = s->first_glyph + s->nchars - 1;
  9969 
  9970   vwidth = eabs (s->face->box_vertical_line_width);
  9971   hwidth = eabs (s->face->box_horizontal_line_width);
  9972   raised_p = s->face->box == FACE_RAISED_BOX;
  9973   left_x = s->x;
  9974   right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
  9975              ? last_x - 1
  9976              : min (last_x, s->x + s->background_width) - 1);
  9977   top_y = s->y;
  9978   bottom_y = top_y + s->height - 1;
  9979 
  9980   left_p = (s->first_glyph->left_box_line_p
  9981             || (s->hl == DRAW_MOUSE_FACE
  9982                 && (s->prev == NULL
  9983                     || s->prev->hl != s->hl)));
  9984   right_p = (last_glyph->right_box_line_p
  9985              || (s->hl == DRAW_MOUSE_FACE
  9986                  && (s->next == NULL
  9987                      || s->next->hl != s->hl)));
  9988 
  9989   get_glyph_string_clip_rect (s, &clip_rect);
  9990 
  9991   if (s->face->box == FACE_SIMPLE_BOX)
  9992     x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
  9993                      vwidth, left_p, right_p, &clip_rect);
  9994   else
  9995     {
  9996       x_setup_relief_colors (s);
  9997       x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, hwidth,
  9998                           vwidth, raised_p, true, true, left_p, right_p,
  9999                           &clip_rect);
 10000     }
 10001 }
 10002 
 10003 
 10004 #ifndef USE_CAIRO
 10005 
 10006 static void
 10007 x_composite_image (struct glyph_string *s, Pixmap dest,
 10008 #ifdef HAVE_XRENDER
 10009                    Picture destination,
 10010 #endif
 10011                    int srcX, int srcY, int dstX, int dstY,
 10012                    int width, int height)
 10013 {
 10014   Display *display;
 10015 #ifdef HAVE_XRENDER
 10016   XRenderPictFormat *default_format;
 10017   XRenderPictureAttributes attr UNINIT;
 10018 #endif
 10019 
 10020   display = FRAME_X_DISPLAY (s->f);
 10021 
 10022 #ifdef HAVE_XRENDER
 10023   if (s->img->picture && FRAME_X_PICTURE_FORMAT (s->f))
 10024     {
 10025       if (destination == None)
 10026         {
 10027           /* The destination picture was not specified.  This means we
 10028              have to create a picture representing the */
 10029           default_format = FRAME_X_PICTURE_FORMAT (s->f);
 10030           destination = XRenderCreatePicture (display, dest,
 10031                                               default_format, 0, &attr);
 10032 
 10033           XRenderComposite (display, (s->img->mask_picture
 10034                                       ? PictOpOver : PictOpSrc),
 10035                             s->img->picture, s->img->mask_picture,
 10036                             destination, srcX, srcY, srcX, srcY,
 10037                             dstX, dstY, width, height);
 10038 
 10039           XRenderFreePicture (display, destination);
 10040         }
 10041       else
 10042         XRenderComposite (display, (s->img->mask_picture
 10043                                     ? PictOpOver : PictOpSrc),
 10044                           s->img->picture, s->img->mask_picture,
 10045                           destination, srcX, srcY, srcX, srcY,
 10046                           dstX, dstY, width, height);
 10047 
 10048       return;
 10049     }
 10050 #endif
 10051 
 10052   XCopyArea (display, s->img->pixmap,
 10053              dest, s->gc,
 10054              srcX, srcY,
 10055              width, height, dstX, dstY);
 10056 }
 10057 
 10058 #endif  /* !USE_CAIRO */
 10059 
 10060 
 10061 /* Draw foreground of image glyph string S.  */
 10062 
 10063 static void
 10064 x_draw_image_foreground (struct glyph_string *s)
 10065 {
 10066   int x = s->x;
 10067   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
 10068 
 10069   /* If first glyph of S has a left box line, start drawing it to the
 10070      right of that line.  */
 10071   if (s->face->box != FACE_NO_BOX
 10072       && s->first_glyph->left_box_line_p
 10073       && s->slice.x == 0)
 10074     x += max (s->face->box_vertical_line_width, 0);
 10075 
 10076   /* If there is a margin around the image, adjust x- and y-position
 10077      by that margin.  */
 10078   if (s->slice.x == 0)
 10079     x += s->img->hmargin;
 10080   if (s->slice.y == 0)
 10081     y += s->img->vmargin;
 10082 
 10083 #ifdef USE_CAIRO
 10084   if (s->img->cr_data)
 10085     {
 10086       x_set_glyph_string_clipping (s);
 10087       x_cr_draw_image (s->f, s->gc, s->img->cr_data,
 10088                        s->slice.x, s->slice.y, s->slice.width, s->slice.height,
 10089                        x, y, true);
 10090       if (!s->img->mask)
 10091         {
 10092           /* When the image has a mask, we can expect that at
 10093              least part of a mouse highlight or a block cursor will
 10094              be visible.  If the image doesn't have a mask, make
 10095              a block cursor visible by drawing a rectangle around
 10096              the image.  I believe it's looking better if we do
 10097              nothing here for mouse-face.  */
 10098           if (s->hl == DRAW_CURSOR)
 10099             {
 10100               int relief = eabs (s->img->relief);
 10101               x_draw_rectangle (s->f, s->gc, x - relief, y - relief,
 10102                                 s->slice.width + relief*2 - 1,
 10103                                 s->slice.height + relief*2 - 1);
 10104             }
 10105         }
 10106     }
 10107 #else  /* ! USE_CAIRO */
 10108   if (s->img->pixmap)
 10109     {
 10110       if (s->img->mask)
 10111         {
 10112           /* We can't set both a clip mask and use XSetClipRectangles
 10113              because the latter also sets a clip mask.  We also can't
 10114              trust on the shape extension to be available
 10115              (XShapeCombineRegion).  So, compute the rectangle to draw
 10116              manually.  */
 10117           /* FIXME: Do we need to do this when using XRender compositing?  */
 10118           unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
 10119                                 | GCFunction);
 10120           XGCValues xgcv;
 10121           XRectangle clip_rect, image_rect, r;
 10122 
 10123           xgcv.clip_mask = s->img->mask;
 10124           xgcv.clip_x_origin = x;
 10125           xgcv.clip_y_origin = y;
 10126           xgcv.function = GXcopy;
 10127           XChangeGC (FRAME_X_DISPLAY (s->f), s->gc, mask, &xgcv);
 10128 
 10129           get_glyph_string_clip_rect (s, &clip_rect);
 10130           image_rect.x = x;
 10131           image_rect.y = y;
 10132           image_rect.width = s->slice.width;
 10133           image_rect.height = s->slice.height;
 10134           if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
 10135             x_composite_image (s, FRAME_X_DRAWABLE (s->f),
 10136 #ifdef HAVE_XRENDER
 10137                                FRAME_X_PICTURE (s->f),
 10138 #endif
 10139                                s->slice.x + r.x - x, s->slice.y + r.y - y,
 10140                                r.x, r.y, r.width, r.height);
 10141         }
 10142       else
 10143         {
 10144           XRectangle clip_rect, image_rect, r;
 10145 
 10146           get_glyph_string_clip_rect (s, &clip_rect);
 10147           image_rect.x = x;
 10148           image_rect.y = y;
 10149           image_rect.width = s->slice.width;
 10150           image_rect.height = s->slice.height;
 10151           if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
 10152             x_composite_image (s, FRAME_X_DRAWABLE (s->f),
 10153 #ifdef HAVE_XRENDER
 10154                                FRAME_X_PICTURE (s->f),
 10155 #endif
 10156                                s->slice.x + r.x - x,
 10157                                s->slice.y + r.y - y,
 10158                                r.x, r.y, r.width, r.height);
 10159 
 10160           /* When the image has a mask, we can expect that at
 10161              least part of a mouse highlight or a block cursor will
 10162              be visible.  If the image doesn't have a mask, make
 10163              a block cursor visible by drawing a rectangle around
 10164              the image.  I believe it's looking better if we do
 10165              nothing here for mouse-face.  */
 10166           if (s->hl == DRAW_CURSOR)
 10167             {
 10168               int relief = eabs (s->img->relief);
 10169               x_draw_rectangle (s->f, s->gc,
 10170                               x - relief, y - relief,
 10171                               s->slice.width + relief*2 - 1,
 10172                               s->slice.height + relief*2 - 1);
 10173             }
 10174         }
 10175     }
 10176 #endif  /* ! USE_CAIRO */
 10177   else
 10178     /* Draw a rectangle if image could not be loaded.  */
 10179     x_draw_rectangle (s->f, s->gc, x, y,
 10180                     s->slice.width - 1, s->slice.height - 1);
 10181 }
 10182 
 10183 
 10184 /* Draw a relief around the image glyph string S.  */
 10185 
 10186 static void
 10187 x_draw_image_relief (struct glyph_string *s)
 10188 {
 10189   int x1, y1, thick;
 10190   bool raised_p, top_p, bot_p, left_p, right_p;
 10191   int extra_x, extra_y;
 10192   XRectangle r;
 10193   int x = s->x;
 10194   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
 10195 
 10196   /* If first glyph of S has a left box line, start drawing it to the
 10197      right of that line.  */
 10198   if (s->face->box != FACE_NO_BOX
 10199       && s->first_glyph->left_box_line_p
 10200       && s->slice.x == 0)
 10201     x += max (s->face->box_vertical_line_width, 0);
 10202 
 10203   /* If there is a margin around the image, adjust x- and y-position
 10204      by that margin.  */
 10205   if (s->slice.x == 0)
 10206     x += s->img->hmargin;
 10207   if (s->slice.y == 0)
 10208     y += s->img->vmargin;
 10209 
 10210   if (s->hl == DRAW_IMAGE_SUNKEN
 10211       || s->hl == DRAW_IMAGE_RAISED)
 10212     {
 10213       if (s->face->id == TAB_BAR_FACE_ID)
 10214         thick = (tab_bar_button_relief < 0
 10215                  ? DEFAULT_TAB_BAR_BUTTON_RELIEF
 10216                  : min (tab_bar_button_relief, 1000000));
 10217       else
 10218         thick = (tool_bar_button_relief < 0
 10219                  ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
 10220                  : min (tool_bar_button_relief, 1000000));
 10221       raised_p = s->hl == DRAW_IMAGE_RAISED;
 10222     }
 10223   else
 10224     {
 10225       thick = eabs (s->img->relief);
 10226       raised_p = s->img->relief > 0;
 10227     }
 10228 
 10229   x1 = x + s->slice.width - 1;
 10230   y1 = y + s->slice.height - 1;
 10231 
 10232   extra_x = extra_y = 0;
 10233   if (s->face->id == TAB_BAR_FACE_ID)
 10234     {
 10235       if (CONSP (Vtab_bar_button_margin)
 10236           && FIXNUMP (XCAR (Vtab_bar_button_margin))
 10237           && FIXNUMP (XCDR (Vtab_bar_button_margin)))
 10238         {
 10239           extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin)) - thick;
 10240           extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin)) - thick;
 10241         }
 10242       else if (FIXNUMP (Vtab_bar_button_margin))
 10243         extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin) - thick;
 10244     }
 10245 
 10246   if (s->face->id == TOOL_BAR_FACE_ID)
 10247     {
 10248       if (CONSP (Vtool_bar_button_margin)
 10249           && FIXNUMP (XCAR (Vtool_bar_button_margin))
 10250           && FIXNUMP (XCDR (Vtool_bar_button_margin)))
 10251         {
 10252           extra_x = XFIXNUM (XCAR (Vtool_bar_button_margin));
 10253           extra_y = XFIXNUM (XCDR (Vtool_bar_button_margin));
 10254         }
 10255       else if (FIXNUMP (Vtool_bar_button_margin))
 10256         extra_x = extra_y = XFIXNUM (Vtool_bar_button_margin);
 10257     }
 10258 
 10259   top_p = bot_p = left_p = right_p = false;
 10260 
 10261   if (s->slice.x == 0)
 10262     x -= thick + extra_x, left_p = true;
 10263   if (s->slice.y == 0)
 10264     y -= thick + extra_y, top_p = true;
 10265   if (s->slice.x + s->slice.width == s->img->width)
 10266     x1 += thick + extra_x, right_p = true;
 10267   if (s->slice.y + s->slice.height == s->img->height)
 10268     y1 += thick + extra_y, bot_p = true;
 10269 
 10270   x_setup_relief_colors (s);
 10271   get_glyph_string_clip_rect (s, &r);
 10272   x_draw_relief_rect (s->f, x, y, x1, y1, thick, thick, raised_p,
 10273                       top_p, bot_p, left_p, right_p, &r);
 10274 }
 10275 
 10276 
 10277 #ifndef USE_CAIRO
 10278 /* Draw the foreground of image glyph string S to PIXMAP.  */
 10279 
 10280 static void
 10281 x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
 10282 {
 10283   int x = 0;
 10284   int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
 10285 
 10286   /* If first glyph of S has a left box line, start drawing it to the
 10287      right of that line.  */
 10288   if (s->face->box != FACE_NO_BOX
 10289       && s->first_glyph->left_box_line_p
 10290       && s->slice.x == 0)
 10291     x += max (s->face->box_vertical_line_width, 0);
 10292 
 10293   /* If there is a margin around the image, adjust x- and y-position
 10294      by that margin.  */
 10295   if (s->slice.x == 0)
 10296     x += s->img->hmargin;
 10297   if (s->slice.y == 0)
 10298     y += s->img->vmargin;
 10299 
 10300   if (s->img->pixmap)
 10301     {
 10302       Display *display = FRAME_X_DISPLAY (s->f);
 10303 
 10304       if (s->img->mask)
 10305         {
 10306           /* We can't set both a clip mask and use XSetClipRectangles
 10307              because the latter also sets a clip mask.  We also can't
 10308              trust on the shape extension to be available
 10309              (XShapeCombineRegion).  So, compute the rectangle to draw
 10310              manually.  */
 10311           /* FIXME: Do we need to do this when using XRender compositing?  */
 10312           unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
 10313                                 | GCFunction);
 10314           XGCValues xgcv;
 10315 
 10316           xgcv.clip_mask = s->img->mask;
 10317           xgcv.clip_x_origin = x - s->slice.x;
 10318           xgcv.clip_y_origin = y - s->slice.y;
 10319           xgcv.function = GXcopy;
 10320           XChangeGC (display, s->gc, mask, &xgcv);
 10321 
 10322           x_composite_image (s, pixmap,
 10323 #ifdef HAVE_XRENDER
 10324                              None,
 10325 #endif
 10326                              s->slice.x, s->slice.y, x, y,
 10327                              s->slice.width, s->slice.height);
 10328           XSetClipMask (display, s->gc, None);
 10329         }
 10330       else
 10331         {
 10332           XCopyArea (display, s->img->pixmap, pixmap, s->gc,
 10333                      s->slice.x, s->slice.y,
 10334                      s->slice.width, s->slice.height, x, y);
 10335 
 10336           /* When the image has a mask, we can expect that at
 10337              least part of a mouse highlight or a block cursor will
 10338              be visible.  If the image doesn't have a mask, make
 10339              a block cursor visible by drawing a rectangle around
 10340              the image.  I believe it's looking better if we do
 10341              nothing here for mouse-face.  */
 10342           if (s->hl == DRAW_CURSOR)
 10343             {
 10344               int r = eabs (s->img->relief);
 10345               x_draw_rectangle (s->f, s->gc, x - r, y - r,
 10346                               s->slice.width + r*2 - 1,
 10347                               s->slice.height + r*2 - 1);
 10348             }
 10349         }
 10350     }
 10351   else
 10352     /* Draw a rectangle if image could not be loaded.  */
 10353     x_draw_rectangle (s->f, s->gc, x, y,
 10354                     s->slice.width - 1, s->slice.height - 1);
 10355 }
 10356 #endif  /* ! USE_CAIRO */
 10357 
 10358 
 10359 /* Draw part of the background of glyph string S.  X, Y, W, and H
 10360    give the rectangle to draw.  */
 10361 
 10362 static void
 10363 x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
 10364 {
 10365   if (s->stippled_p)
 10366     {
 10367       Display *display = FRAME_X_DISPLAY (s->f);
 10368 
 10369       /* Fill background with a stipple pattern.  */
 10370       XSetFillStyle (display, s->gc, FillOpaqueStippled);
 10371       x_fill_rectangle (s->f, s->gc, x, y, w, h, true);
 10372       XSetFillStyle (display, s->gc, FillSolid);
 10373     }
 10374   else
 10375     x_clear_glyph_string_rect (s, x, y, w, h);
 10376 }
 10377 
 10378 
 10379 /* Draw image glyph string S.
 10380 
 10381             s->y
 10382    s->x      +-------------------------
 10383              |   s->face->box
 10384              |
 10385              |     +-------------------------
 10386              |     |  s->img->margin
 10387              |     |
 10388              |     |       +-------------------
 10389              |     |       |  the image
 10390 
 10391  */
 10392 
 10393 static void
 10394 x_draw_image_glyph_string (struct glyph_string *s)
 10395 {
 10396   int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
 10397   int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
 10398   int height;
 10399 #ifndef USE_CAIRO
 10400   Display *display = FRAME_X_DISPLAY (s->f);
 10401   Pixmap pixmap = None;
 10402 #endif
 10403 
 10404   height = s->height;
 10405   if (s->slice.y == 0)
 10406     height -= box_line_vwidth;
 10407   if (s->slice.y + s->slice.height >= s->img->height)
 10408     height -= box_line_vwidth;
 10409 
 10410   /* Fill background with face under the image.  Do it only if row is
 10411      taller than image or if image has a clip mask to reduce
 10412      flickering.  */
 10413   s->stippled_p = s->face->stipple != 0;
 10414   if (height > s->slice.height
 10415       || s->img->hmargin
 10416       || s->img->vmargin
 10417       || s->img->mask
 10418       || s->img->pixmap == 0
 10419       || s->width != s->background_width)
 10420     {
 10421       if (s->stippled_p)
 10422         s->row->stipple_p = true;
 10423 
 10424 #ifndef USE_CAIRO
 10425       if (s->img->mask)
 10426         {
 10427           /* Create a pixmap as large as the glyph string.  Fill it
 10428              with the background color.  Copy the image to it, using
 10429              its mask.  Copy the temporary pixmap to the display.  */
 10430           int depth = FRAME_DISPLAY_INFO (s->f)->n_planes;
 10431 
 10432           /* Create a pixmap as large as the glyph string.  */
 10433           pixmap = XCreatePixmap (display, FRAME_X_DRAWABLE (s->f),
 10434                                   s->background_width,
 10435                                   s->height, depth);
 10436 
 10437           /* Don't clip in the following because we're working on the
 10438              pixmap.  */
 10439           XSetClipMask (display, s->gc, None);
 10440 
 10441           /* Fill the pixmap with the background color/stipple.  */
 10442           if (s->stippled_p)
 10443             {
 10444               /* Fill background with a stipple pattern.  */
 10445               XSetFillStyle (display, s->gc, FillOpaqueStippled);
 10446               XSetTSOrigin (display, s->gc, - s->x, - s->y);
 10447               XFillRectangle (display, pixmap, s->gc,
 10448                               0, 0, s->background_width, s->height);
 10449               XSetFillStyle (display, s->gc, FillSolid);
 10450               XSetTSOrigin (display, s->gc, 0, 0);
 10451             }
 10452           else
 10453             {
 10454               XGCValues xgcv;
 10455 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
 10456               if (FRAME_DISPLAY_INFO (s->f)->alpha_bits
 10457                   && s->f->alpha_background != 1.0
 10458                   && FRAME_CHECK_XR_VERSION (s->f, 0, 2)
 10459                   && FRAME_X_PICTURE_FORMAT (s->f))
 10460                 {
 10461                   XRenderColor xc;
 10462                   XRenderPictureAttributes attrs;
 10463                   Picture pict;
 10464                   memset (&attrs, 0, sizeof attrs);
 10465 
 10466                   pict = XRenderCreatePicture (display, pixmap,
 10467                                                FRAME_X_PICTURE_FORMAT (s->f),
 10468                                                0, &attrs);
 10469                   x_xrender_color_from_gc_background (s->f, s->gc, &xc, true);
 10470                   XRenderFillRectangle (FRAME_X_DISPLAY (s->f), PictOpSrc, pict,
 10471                                         &xc, 0, 0, s->background_width, s->height);
 10472                   XRenderFreePicture (display, pict);
 10473                 }
 10474               else
 10475 #endif
 10476                 {
 10477                   XGetGCValues (display, s->gc, GCForeground | GCBackground,
 10478                                 &xgcv);
 10479                   XSetForeground (display, s->gc, xgcv.background);
 10480                   XFillRectangle (display, pixmap, s->gc,
 10481                                   0, 0, s->background_width, s->height);
 10482                   XSetForeground (display, s->gc, xgcv.foreground);
 10483                 }
 10484             }
 10485         }
 10486       else
 10487 #endif  /* ! USE_CAIRO */
 10488         {
 10489           int x = s->x;
 10490           int y = s->y;
 10491           int width = s->background_width;
 10492 
 10493           if (s->first_glyph->left_box_line_p
 10494               && s->slice.x == 0)
 10495             {
 10496               x += box_line_hwidth;
 10497               width -= box_line_hwidth;
 10498             }
 10499 
 10500           if (s->slice.y == 0)
 10501             y += box_line_vwidth;
 10502 
 10503           x_draw_glyph_string_bg_rect (s, x, y, width, height);
 10504         }
 10505 
 10506       s->background_filled_p = true;
 10507     }
 10508 
 10509   /* Draw the foreground.  */
 10510 #ifndef USE_CAIRO
 10511   if (pixmap != None)
 10512     {
 10513       x_draw_image_foreground_1 (s, pixmap);
 10514       x_set_glyph_string_clipping (s);
 10515       XCopyArea (display, pixmap, FRAME_X_DRAWABLE (s->f), s->gc,
 10516                  0, 0, s->background_width, s->height, s->x, s->y);
 10517       XFreePixmap (display, pixmap);
 10518     }
 10519   else
 10520 #endif  /* ! USE_CAIRO */
 10521     x_draw_image_foreground (s);
 10522 
 10523   /* If we must draw a relief around the image, do it.  */
 10524   if (s->img->relief
 10525       || s->hl == DRAW_IMAGE_RAISED
 10526       || s->hl == DRAW_IMAGE_SUNKEN)
 10527     x_draw_image_relief (s);
 10528 }
 10529 
 10530 
 10531 /* Draw stretch glyph string S.  */
 10532 
 10533 static void
 10534 x_draw_stretch_glyph_string (struct glyph_string *s)
 10535 {
 10536   eassert (s->first_glyph->type == STRETCH_GLYPH);
 10537 
 10538   if (s->hl == DRAW_CURSOR
 10539       && !x_stretch_cursor_p)
 10540     {
 10541       /* If `x-stretch-cursor' is nil, don't draw a block cursor as
 10542          wide as the stretch glyph.  */
 10543       int width, background_width = s->background_width;
 10544       int x = s->x;
 10545 
 10546       if (!s->row->reversed_p)
 10547         {
 10548           int left_x = window_box_left_offset (s->w, TEXT_AREA);
 10549 
 10550           if (x < left_x)
 10551             {
 10552               background_width -= left_x - x;
 10553               x = left_x;
 10554             }
 10555         }
 10556       else
 10557         {
 10558           /* In R2L rows, draw the cursor on the right edge of the
 10559              stretch glyph.  */
 10560           int right_x = window_box_right (s->w, TEXT_AREA);
 10561 
 10562           if (x + background_width > right_x)
 10563             background_width -= x - right_x;
 10564           x += background_width;
 10565         }
 10566       width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
 10567       if (s->row->reversed_p)
 10568         x -= width;
 10569 
 10570       /* Draw cursor.  */
 10571       x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
 10572 
 10573       /* Clear rest using the GC of the original non-cursor face.  */
 10574       if (width < background_width)
 10575         {
 10576           int y = s->y;
 10577           int w = background_width - width, h = s->height;
 10578           Display *display = FRAME_X_DISPLAY (s->f);
 10579           XRectangle r;
 10580           GC gc;
 10581 
 10582           if (!s->row->reversed_p)
 10583             x += width;
 10584           else
 10585             x = s->x;
 10586           if (s->row->mouse_face_p
 10587               && cursor_in_mouse_face_p (s->w))
 10588             {
 10589               x_set_mouse_face_gc (s);
 10590               gc = s->gc;
 10591             }
 10592           else
 10593             gc = s->face->gc;
 10594 
 10595           get_glyph_string_clip_rect (s, &r);
 10596           x_set_clip_rectangles (s->f, gc, &r, 1);
 10597 
 10598           if (s->face->stipple)
 10599             {
 10600               /* Fill background with a stipple pattern.  */
 10601               XSetFillStyle (display, gc, FillOpaqueStippled);
 10602               x_fill_rectangle (s->f, gc, x, y, w, h, true);
 10603               XSetFillStyle (display, gc, FillSolid);
 10604 
 10605               s->row->stipple_p = true;
 10606             }
 10607           else
 10608             {
 10609               XGCValues xgcv;
 10610               XGetGCValues (display, gc, GCForeground | GCBackground, &xgcv);
 10611               XSetForeground (display, gc, xgcv.background);
 10612               x_fill_rectangle (s->f, gc, x, y, w, h, true);
 10613               XSetForeground (display, gc, xgcv.foreground);
 10614             }
 10615 
 10616           x_reset_clip_rectangles (s->f, gc);
 10617         }
 10618     }
 10619   else if (!s->background_filled_p)
 10620     {
 10621       int background_width = s->background_width;
 10622       int x = s->x, text_left_x = window_box_left (s->w, TEXT_AREA);
 10623 
 10624       /* Don't draw into left fringe or scrollbar area except for
 10625          header line and mode line.  */
 10626       if (s->area == TEXT_AREA
 10627           && x < text_left_x && !s->row->mode_line_p)
 10628         {
 10629           background_width -= text_left_x - x;
 10630           x = text_left_x;
 10631         }
 10632 
 10633       if (!s->row->stipple_p)
 10634         s->row->stipple_p = s->stippled_p;
 10635 
 10636       if (background_width > 0)
 10637         x_draw_glyph_string_bg_rect (s, x, s->y,
 10638                                      background_width, s->height);
 10639     }
 10640 
 10641   s->background_filled_p = true;
 10642 }
 10643 
 10644 static void
 10645 x_get_scale_factor (Display *disp, int *scale_x, int *scale_y)
 10646 {
 10647   const int base_res = 96;
 10648   struct x_display_info * dpyinfo = x_display_info_for_display (disp);
 10649 
 10650   *scale_x = *scale_y = 1;
 10651 
 10652   if (dpyinfo)
 10653     {
 10654       if (dpyinfo->resx > base_res)
 10655         *scale_x = floor (dpyinfo->resx / base_res);
 10656       if (dpyinfo->resy > base_res)
 10657         *scale_y = floor (dpyinfo->resy / base_res);
 10658     }
 10659 }
 10660 
 10661 /*
 10662    Draw a wavy line under S. The wave fills wave_height pixels from y0.
 10663 
 10664                     x0         wave_length = 2
 10665                                  --
 10666                 y0   *   *   *   *   *
 10667                      |* * * * * * * * *
 10668     wave_height = 3  | *   *   *   *
 10669 
 10670 */
 10671 static void
 10672 x_draw_underwave (struct glyph_string *s, int decoration_width)
 10673 {
 10674   Display *display = FRAME_X_DISPLAY (s->f);
 10675 
 10676   /* Adjust for scale/HiDPI.  */
 10677   int scale_x, scale_y;
 10678 
 10679   x_get_scale_factor (display, &scale_x, &scale_y);
 10680 
 10681   int wave_height = 3 * scale_y, wave_length = 2 * scale_x;
 10682 
 10683 #ifdef USE_CAIRO
 10684   x_draw_horizontal_wave (s->f, s->gc, s->x, s->ybase - wave_height + 3,
 10685                           decoration_width, wave_height, wave_length);
 10686 #else  /* not USE_CAIRO */
 10687   int dx, dy, x0, y0, width, x1, y1, x2, y2, xmax, thickness = scale_y;;
 10688   bool odd;
 10689   XRectangle wave_clip, string_clip, final_clip;
 10690 
 10691   dx = wave_length;
 10692   dy = wave_height - 1;
 10693   x0 = s->x;
 10694   y0 = s->ybase + wave_height / 2 - scale_y;
 10695   width = decoration_width;
 10696   xmax = x0 + width;
 10697 
 10698   /* Find and set clipping rectangle */
 10699 
 10700   wave_clip.x = x0;
 10701   wave_clip.y = y0;
 10702   wave_clip.width = width;
 10703   wave_clip.height = wave_height;
 10704   get_glyph_string_clip_rect (s, &string_clip);
 10705 
 10706   if (!gui_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
 10707     return;
 10708 
 10709   XSetClipRectangles (display, s->gc, 0, 0, &final_clip, 1, Unsorted);
 10710 
 10711   /* Draw the waves */
 10712 
 10713   x1 = x0 - (x0 % dx);
 10714   x2 = x1 + dx;
 10715   odd = (x1 / dx) & 1;
 10716   y1 = y2 = y0;
 10717 
 10718   if (odd)
 10719     y1 += dy;
 10720   else
 10721     y2 += dy;
 10722 
 10723   if (INT_MAX - dx < xmax)
 10724     emacs_abort ();
 10725 
 10726   while (x1 <= xmax)
 10727     {
 10728       XSetLineAttributes (display, s->gc, thickness, LineSolid, CapButt,
 10729                           JoinRound);
 10730       XDrawLine (display, FRAME_X_DRAWABLE (s->f), s->gc, x1, y1, x2, y2);
 10731       x1  = x2, y1 = y2;
 10732       x2 += dx, y2 = y0 + odd*dy;
 10733       odd = !odd;
 10734     }
 10735 
 10736   /* Restore previous clipping rectangle(s) */
 10737   XSetClipRectangles (display, s->gc, 0, 0, s->clip, s->num_clips, Unsorted);
 10738 #endif  /* not USE_CAIRO */
 10739 }
 10740 
 10741 
 10742 /* Draw glyph string S.  */
 10743 
 10744 static void
 10745 x_draw_glyph_string (struct glyph_string *s)
 10746 {
 10747   bool relief_drawn_p = false;
 10748 
 10749   /* If S draws into the background of its successors, draw the
 10750      background of the successors first so that S can draw into it.
 10751      This makes S->next use XDrawString instead of XDrawImageString.  */
 10752   if (s->next && s->right_overhang && !s->for_overlaps)
 10753     {
 10754       int width;
 10755       struct glyph_string *next;
 10756 
 10757       for (width = 0, next = s->next;
 10758            next && width < s->right_overhang;
 10759            width += next->width, next = next->next)
 10760         if (next->first_glyph->type != IMAGE_GLYPH)
 10761           {
 10762             x_set_glyph_string_gc (next);
 10763             x_set_glyph_string_clipping (next);
 10764             if (next->first_glyph->type == STRETCH_GLYPH)
 10765               x_draw_stretch_glyph_string (next);
 10766             else
 10767               x_draw_glyph_string_background (next, true);
 10768             next->num_clips = 0;
 10769           }
 10770     }
 10771 
 10772   /* Set up S->gc, set clipping and draw S.  */
 10773   x_set_glyph_string_gc (s);
 10774 
 10775   /* Draw relief (if any) in advance for char/composition so that the
 10776      glyph string can be drawn over it.  */
 10777   if (!s->for_overlaps
 10778       && s->face->box != FACE_NO_BOX
 10779       && (s->first_glyph->type == CHAR_GLYPH
 10780           || s->first_glyph->type == COMPOSITE_GLYPH))
 10781 
 10782     {
 10783       x_set_glyph_string_clipping (s);
 10784       x_draw_glyph_string_background (s, true);
 10785       x_draw_glyph_string_box (s);
 10786       x_set_glyph_string_clipping (s);
 10787       relief_drawn_p = true;
 10788     }
 10789   else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
 10790            && !s->clip_tail
 10791            && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
 10792                || (s->next && s->next->hl != s->hl && s->right_overhang)))
 10793     /* We must clip just this glyph.  left_overhang part has already
 10794        drawn when s->prev was drawn, and right_overhang part will be
 10795        drawn later when s->next is drawn. */
 10796     x_set_glyph_string_clipping_exactly (s, s);
 10797   else
 10798     x_set_glyph_string_clipping (s);
 10799 
 10800   switch (s->first_glyph->type)
 10801     {
 10802     case IMAGE_GLYPH:
 10803       x_draw_image_glyph_string (s);
 10804       break;
 10805 
 10806     case XWIDGET_GLYPH:
 10807       x_draw_xwidget_glyph_string (s);
 10808       break;
 10809 
 10810     case STRETCH_GLYPH:
 10811       x_draw_stretch_glyph_string (s);
 10812       break;
 10813 
 10814     case CHAR_GLYPH:
 10815       if (s->for_overlaps)
 10816         s->background_filled_p = true;
 10817       else
 10818         x_draw_glyph_string_background (s, false);
 10819       x_draw_glyph_string_foreground (s);
 10820       break;
 10821 
 10822     case COMPOSITE_GLYPH:
 10823       if (s->for_overlaps || (s->cmp_from > 0
 10824                               && ! s->first_glyph->u.cmp.automatic))
 10825         s->background_filled_p = true;
 10826       else
 10827         x_draw_glyph_string_background (s, true);
 10828       x_draw_composite_glyph_string_foreground (s);
 10829       break;
 10830 
 10831     case GLYPHLESS_GLYPH:
 10832       if (s->for_overlaps)
 10833         s->background_filled_p = true;
 10834       else
 10835         x_draw_glyph_string_background (s, true);
 10836       x_draw_glyphless_glyph_string_foreground (s);
 10837       break;
 10838 
 10839     default:
 10840       emacs_abort ();
 10841     }
 10842 
 10843   if (!s->for_overlaps)
 10844     {
 10845       int area_x, area_y, area_width, area_height;
 10846       int area_max_x, decoration_width;
 10847 
 10848       /* Prevent the underline from overwriting surrounding areas
 10849          and the fringe.  */
 10850       window_box (s->w, s->area, &area_x, &area_y,
 10851                   &area_width, &area_height);
 10852       area_max_x = area_x + area_width - 1;
 10853 
 10854       decoration_width = s->width;
 10855       if (!s->row->mode_line_p
 10856           && !s->row->tab_line_p
 10857           && area_max_x < (s->x + decoration_width - 1))
 10858         decoration_width -= (s->x + decoration_width - 1) - area_max_x;
 10859 
 10860       /* Draw relief if not yet drawn.  */
 10861       if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
 10862         x_draw_glyph_string_box (s);
 10863 
 10864       /* Draw underline.  */
 10865       if (s->face->underline)
 10866         {
 10867           if (s->face->underline == FACE_UNDER_WAVE)
 10868             {
 10869               if (s->face->underline_defaulted_p)
 10870                 x_draw_underwave (s, decoration_width);
 10871               else
 10872                 {
 10873                   Display *display = FRAME_X_DISPLAY (s->f);
 10874                   XGCValues xgcv;
 10875                   XGetGCValues (display, s->gc, GCForeground, &xgcv);
 10876                   XSetForeground (display, s->gc, s->face->underline_color);
 10877                   x_draw_underwave (s, decoration_width);
 10878                   XSetForeground (display, s->gc, xgcv.foreground);
 10879                 }
 10880             }
 10881           else if (s->face->underline == FACE_UNDER_LINE)
 10882             {
 10883               unsigned long thickness, position;
 10884               int y;
 10885 
 10886               if (s->prev
 10887                   && s->prev->face->underline == FACE_UNDER_LINE
 10888                   && (s->prev->face->underline_at_descent_line_p
 10889                       == s->face->underline_at_descent_line_p)
 10890                   && (s->prev->face->underline_pixels_above_descent_line
 10891                       == s->face->underline_pixels_above_descent_line))
 10892                 {
 10893                   /* We use the same underline style as the previous one.  */
 10894                   thickness = s->prev->underline_thickness;
 10895                   position = s->prev->underline_position;
 10896                 }
 10897               else
 10898                 {
 10899                   struct font *font = font_for_underline_metrics (s);
 10900                   unsigned long minimum_offset;
 10901                   bool underline_at_descent_line;
 10902                   bool use_underline_position_properties;
 10903                   Lisp_Object val = (WINDOW_BUFFER_LOCAL_VALUE
 10904                                      (Qunderline_minimum_offset, s->w));
 10905 
 10906                   if (FIXNUMP (val))
 10907                     minimum_offset = max (0, XFIXNUM (val));
 10908                   else
 10909                     minimum_offset = 1;
 10910 
 10911                   val = (WINDOW_BUFFER_LOCAL_VALUE
 10912                          (Qx_underline_at_descent_line, s->w));
 10913                   underline_at_descent_line
 10914                     = (!(NILP (val) || BASE_EQ (val, Qunbound))
 10915                        || s->face->underline_at_descent_line_p);
 10916 
 10917                   val = (WINDOW_BUFFER_LOCAL_VALUE
 10918                          (Qx_use_underline_position_properties, s->w));
 10919                   use_underline_position_properties
 10920                     = !(NILP (val) || BASE_EQ (val, Qunbound));
 10921 
 10922                   /* Get the underline thickness.  Default is 1 pixel.  */
 10923                   if (font && font->underline_thickness > 0)
 10924                     thickness = font->underline_thickness;
 10925                   else
 10926                     thickness = 1;
 10927                   if (underline_at_descent_line)
 10928                     position = ((s->height - thickness)
 10929                                 - (s->ybase - s->y)
 10930                                 - s->face->underline_pixels_above_descent_line);
 10931                   else
 10932                     {
 10933                       /* Get the underline position.  This is the
 10934                          recommended vertical offset in pixels from
 10935                          the baseline to the top of the underline.
 10936                          This is a signed value according to the
 10937                          specs, and its default is
 10938 
 10939                          ROUND ((maximum descent) / 2), with
 10940                          ROUND(x) = floor (x + 0.5)  */
 10941 
 10942                       if (use_underline_position_properties
 10943                           && font && font->underline_position >= 0)
 10944                         position = font->underline_position;
 10945                       else if (font)
 10946                         position = (font->descent + 1) / 2;
 10947                       else
 10948                         position = minimum_offset;
 10949                     }
 10950 
 10951                   /* Ignore minimum_offset if the amount of pixels was
 10952                      explicitly specified.  */
 10953                   if (!s->face->underline_pixels_above_descent_line)
 10954                     position = max (position, minimum_offset);
 10955                 }
 10956               /* Check the sanity of thickness and position.  We should
 10957                  avoid drawing underline out of the current line area.  */
 10958               if (s->y + s->height <= s->ybase + position)
 10959                 position = (s->height - 1) - (s->ybase - s->y);
 10960               if (s->y + s->height < s->ybase + position + thickness)
 10961                 thickness = (s->y + s->height) - (s->ybase + position);
 10962               s->underline_thickness = thickness;
 10963               s->underline_position = position;
 10964               y = s->ybase + position;
 10965               if (s->face->underline_defaulted_p)
 10966                 x_fill_rectangle (s->f, s->gc,
 10967                                   s->x, y, decoration_width, thickness,
 10968                                   false);
 10969               else
 10970                 {
 10971                   Display *display = FRAME_X_DISPLAY (s->f);
 10972                   XGCValues xgcv;
 10973                   XGetGCValues (display, s->gc, GCForeground, &xgcv);
 10974                   XSetForeground (display, s->gc, s->face->underline_color);
 10975                   x_fill_rectangle (s->f, s->gc,
 10976                                     s->x, y, decoration_width, thickness,
 10977                                     false);
 10978                   XSetForeground (display, s->gc, xgcv.foreground);
 10979                 }
 10980             }
 10981         }
 10982       /* Draw overline.  */
 10983       if (s->face->overline_p)
 10984         {
 10985           unsigned long dy = 0, h = 1;
 10986 
 10987           if (s->face->overline_color_defaulted_p)
 10988             x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
 10989                               decoration_width, h, false);
 10990           else
 10991             {
 10992               Display *display = FRAME_X_DISPLAY (s->f);
 10993               XGCValues xgcv;
 10994               XGetGCValues (display, s->gc, GCForeground, &xgcv);
 10995               XSetForeground (display, s->gc, s->face->overline_color);
 10996               x_fill_rectangle (s->f, s->gc, s->x, s->y + dy,
 10997                                 decoration_width, h, false);
 10998               XSetForeground (display, s->gc, xgcv.foreground);
 10999             }
 11000         }
 11001 
 11002       /* Draw strike-through.  */
 11003       if (s->face->strike_through_p)
 11004         {
 11005           /* Y-coordinate and height of the glyph string's first
 11006              glyph.  We cannot use s->y and s->height because those
 11007              could be larger if there are taller display elements
 11008              (e.g., characters displayed with a larger font) in the
 11009              same glyph row.  */
 11010           int glyph_y = s->ybase - s->first_glyph->ascent;
 11011           int glyph_height = s->first_glyph->ascent + s->first_glyph->descent;
 11012           /* Strike-through width and offset from the glyph string's
 11013              top edge.  */
 11014           unsigned long h = 1;
 11015           unsigned long dy = (glyph_height - h) / 2;
 11016 
 11017           if (s->face->strike_through_color_defaulted_p)
 11018             x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
 11019                               s->width, h, false);
 11020           else
 11021             {
 11022               Display *display = FRAME_X_DISPLAY (s->f);
 11023               XGCValues xgcv;
 11024               XGetGCValues (display, s->gc, GCForeground, &xgcv);
 11025               XSetForeground (display, s->gc, s->face->strike_through_color);
 11026               x_fill_rectangle (s->f, s->gc, s->x, glyph_y + dy,
 11027                                 decoration_width, h, false);
 11028               XSetForeground (display, s->gc, xgcv.foreground);
 11029             }
 11030         }
 11031 
 11032       if (s->prev)
 11033         {
 11034           struct glyph_string *prev;
 11035 
 11036           for (prev = s->prev; prev; prev = prev->prev)
 11037             if (prev->hl != s->hl
 11038                 && prev->x + prev->width + prev->right_overhang > s->x)
 11039               {
 11040                 /* As prev was drawn while clipped to its own area, we
 11041                    must draw the right_overhang part using s->hl now.  */
 11042                 enum draw_glyphs_face save = prev->hl;
 11043 
 11044                 prev->hl = s->hl;
 11045                 x_set_glyph_string_gc (prev);
 11046                 x_set_glyph_string_clipping_exactly (s, prev);
 11047                 if (prev->first_glyph->type == CHAR_GLYPH)
 11048                   x_draw_glyph_string_foreground (prev);
 11049                 else
 11050                   x_draw_composite_glyph_string_foreground (prev);
 11051                 x_reset_clip_rectangles (prev->f, prev->gc);
 11052                 prev->hl = save;
 11053                 prev->num_clips = 0;
 11054               }
 11055         }
 11056 
 11057       if (s->next)
 11058         {
 11059           struct glyph_string *next;
 11060 
 11061           for (next = s->next; next; next = next->next)
 11062             if (next->hl != s->hl
 11063                 && next->x - next->left_overhang < s->x + s->width)
 11064               {
 11065                 /* As next will be drawn while clipped to its own area,
 11066                    we must draw the left_overhang part using s->hl now.  */
 11067                 enum draw_glyphs_face save = next->hl;
 11068 
 11069                 next->hl = s->hl;
 11070                 x_set_glyph_string_gc (next);
 11071                 x_set_glyph_string_clipping_exactly (s, next);
 11072                 if (next->first_glyph->type == CHAR_GLYPH)
 11073                   x_draw_glyph_string_foreground (next);
 11074                 else
 11075                   x_draw_composite_glyph_string_foreground (next);
 11076                 x_reset_clip_rectangles (next->f, next->gc);
 11077                 next->hl = save;
 11078                 next->num_clips = 0;
 11079                 next->clip_head = s->next;
 11080               }
 11081         }
 11082     }
 11083 
 11084   /* Reset clipping.  */
 11085   x_reset_clip_rectangles (s->f, s->gc);
 11086   s->num_clips = 0;
 11087 
 11088   /* Set the stippled flag that tells redisplay whether or not a
 11089      stipple was actually draw.  */
 11090 
 11091   if (s->first_glyph->type != STRETCH_GLYPH
 11092       && s->first_glyph->type != IMAGE_GLYPH
 11093       && !s->row->stipple_p)
 11094     s->row->stipple_p = s->stippled_p;
 11095 }
 11096 
 11097 /* Shift display to make room for inserted glyphs.   */
 11098 
 11099 static void
 11100 x_shift_glyphs_for_insert (struct frame *f, int x, int y, int width, int height, int shift_by)
 11101 {
 11102 /* Never called on a GUI frame, see
 11103    https://lists.gnu.org/r/emacs-devel/2015-05/msg00456.html
 11104 */
 11105   XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
 11106              f->output_data.x->normal_gc,
 11107              x, y, width, height,
 11108              x + shift_by, y);
 11109 }
 11110 
 11111 /* Delete N glyphs at the nominal cursor position.  Not implemented
 11112    for X frames.  */
 11113 
 11114 static void
 11115 x_delete_glyphs (struct frame *f, int n)
 11116 {
 11117   emacs_abort ();
 11118 }
 11119 
 11120 
 11121 /* Like XClearArea, but check that WIDTH and HEIGHT are reasonable.
 11122    If they are <= 0, this is probably an error.  */
 11123 
 11124 #if defined USE_GTK || !defined USE_CAIRO
 11125 static void
 11126 x_clear_area1 (Display *dpy, Window window,
 11127                int x, int y, int width, int height, int exposures)
 11128 {
 11129   eassert (width > 0 && height > 0);
 11130   XClearArea (dpy, window, x, y, width, height, exposures);
 11131 }
 11132 #endif
 11133 
 11134 void
 11135 x_clear_area (struct frame *f, int x, int y, int width, int height)
 11136 {
 11137 #ifdef USE_CAIRO
 11138   cairo_t *cr;
 11139 
 11140   eassert (width > 0 && height > 0);
 11141 
 11142   cr = x_begin_cr_clip (f, NULL);
 11143   x_set_cr_source_with_gc_background (f, f->output_data.x->normal_gc,
 11144                                       true);
 11145   cairo_rectangle (cr, x, y, width, height);
 11146   cairo_fill (cr);
 11147   x_end_cr_clip (f);
 11148 #else
 11149 #ifndef USE_GTK
 11150   if (f->alpha_background != 1.0
 11151 #ifdef HAVE_XDBE
 11152       || FRAME_X_DOUBLE_BUFFERED_P (f)
 11153 #endif
 11154       )
 11155 #endif
 11156     {
 11157 #if defined HAVE_XRENDER && \
 11158   (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
 11159       x_xr_ensure_picture (f);
 11160       if (FRAME_DISPLAY_INFO (f)->alpha_bits
 11161           && FRAME_X_PICTURE (f) != None
 11162           && f->alpha_background != 1.0
 11163           && FRAME_CHECK_XR_VERSION (f, 0, 2))
 11164         {
 11165           XRenderColor xc;
 11166           GC gc = f->output_data.x->normal_gc;
 11167 
 11168           x_xr_apply_ext_clip (f, gc);
 11169           x_xrender_color_from_gc_background (f, gc, &xc, true);
 11170           XRenderFillRectangle (FRAME_X_DISPLAY (f),
 11171                                 PictOpSrc, FRAME_X_PICTURE (f),
 11172                                 &xc, x, y, width, height);
 11173           x_xr_reset_ext_clip (f);
 11174           x_mark_frame_dirty (f);
 11175         }
 11176       else
 11177 #endif
 11178         XFillRectangle (FRAME_X_DISPLAY (f),
 11179                         FRAME_X_DRAWABLE (f),
 11180                         f->output_data.x->reverse_gc,
 11181                         x, y, width, height);
 11182     }
 11183 #ifndef USE_GTK
 11184   else
 11185     x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 11186                    x, y, width, height, False);
 11187 #endif
 11188 #endif
 11189 }
 11190 
 11191 
 11192 /* Clear an entire frame.  */
 11193 
 11194 static void
 11195 x_clear_frame (struct frame *f)
 11196 {
 11197   /* Clearing the frame will erase any cursor, so mark them all as no
 11198      longer visible.  */
 11199   mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
 11200 
 11201   block_input ();
 11202   font_drop_xrender_surfaces (f);
 11203   x_clear_window (f);
 11204 
 11205   /* We have to clear the scroll bars.  If we have changed colors or
 11206      something like that, then they should be notified.  */
 11207   x_scroll_bar_clear (f);
 11208 
 11209   unblock_input ();
 11210 }
 11211 
 11212 /* Send a message to frame F telling the event loop to track whether
 11213    or not an hourglass is being displayed.  This is required to ignore
 11214    the right events when the hourglass is mapped without callig XSync
 11215    after displaying or hiding the hourglass.  */
 11216 
 11217 static void
 11218 x_send_hourglass_message (struct frame *f, bool hourglass_enabled)
 11219 {
 11220   struct x_display_info *dpyinfo;
 11221   XEvent msg;
 11222 
 11223   dpyinfo = FRAME_DISPLAY_INFO (f);
 11224   memset (&msg, 0, sizeof msg);
 11225 
 11226   msg.xclient.type = ClientMessage;
 11227   msg.xclient.message_type
 11228     = dpyinfo->Xatom_EMACS_TMP;
 11229   msg.xclient.format = 8;
 11230   msg.xclient.window = FRAME_X_WINDOW (f);
 11231   msg.xclient.data.b[0] = hourglass_enabled ? 1 : 0;
 11232 
 11233   XSendEvent (dpyinfo->display, FRAME_X_WINDOW (f),
 11234               False, NoEventMask, &msg);
 11235 }
 11236 
 11237 /* RIF: Show hourglass cursor on frame F.  */
 11238 
 11239 static void
 11240 x_show_hourglass (struct frame *f)
 11241 {
 11242   Display *dpy = FRAME_X_DISPLAY (f);
 11243 
 11244   if (dpy)
 11245     {
 11246       struct x_output *x = FRAME_X_OUTPUT (f);
 11247 
 11248       /* If the hourglass window is mapped inside a popup menu, input
 11249          could be lost if the menu is popped down and the grab is
 11250          relinquished, but the hourglass window is still up.  Just
 11251          avoid displaying the hourglass at all while popups are
 11252          active.  */
 11253 
 11254       if (popup_activated ())
 11255         return;
 11256 
 11257       x_send_hourglass_message (f, true);
 11258 
 11259 #ifdef USE_X_TOOLKIT
 11260       if (x->widget)
 11261 #else
 11262       if (FRAME_OUTER_WINDOW (f))
 11263 #endif
 11264        {
 11265          if (!x->hourglass_window)
 11266            {
 11267 #ifndef USE_XCB
 11268              unsigned long mask = CWCursor;
 11269              XSetWindowAttributes attrs;
 11270 #ifdef USE_GTK
 11271              Window parent = FRAME_X_WINDOW (f);
 11272 #else
 11273              Window parent = FRAME_OUTER_WINDOW (f);
 11274 #endif
 11275              attrs.cursor = x->hourglass_cursor;
 11276 
 11277              x->hourglass_window = XCreateWindow
 11278                (dpy, parent, 0, 0, 32000, 32000, 0, 0,
 11279                 InputOnly, CopyFromParent, mask, &attrs);
 11280 #else
 11281              uint32_t cursor = (uint32_t) x->hourglass_cursor;
 11282 #ifdef USE_GTK
 11283              xcb_window_t parent = (xcb_window_t) FRAME_X_WINDOW (f);
 11284 #else
 11285              xcb_window_t parent = (xcb_window_t) FRAME_OUTER_WINDOW (f);
 11286 #endif
 11287              x->hourglass_window
 11288                = (Window) xcb_generate_id (FRAME_DISPLAY_INFO (f)->xcb_connection);
 11289 
 11290              xcb_create_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11291                                 XCB_COPY_FROM_PARENT,
 11292                                 (xcb_window_t) x->hourglass_window,
 11293                                 parent, 0, 0, FRAME_PIXEL_WIDTH (f),
 11294                                 FRAME_PIXEL_HEIGHT (f), 0,
 11295                                 XCB_WINDOW_CLASS_INPUT_ONLY,
 11296                                 XCB_COPY_FROM_PARENT, XCB_CW_CURSOR,
 11297                                 &cursor);
 11298 #endif
 11299            }
 11300 
 11301 #ifndef USE_XCB
 11302          XMapRaised (dpy, x->hourglass_window);
 11303          /* Ensure that the spinning hourglass is shown.  */
 11304          flush_frame (f);
 11305 #else
 11306          uint32_t value = XCB_STACK_MODE_ABOVE;
 11307 
 11308          xcb_configure_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11309                                (xcb_window_t) x->hourglass_window,
 11310                                XCB_CONFIG_WINDOW_STACK_MODE, &value);
 11311          xcb_map_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11312                          (xcb_window_t) x->hourglass_window);
 11313          xcb_flush (FRAME_DISPLAY_INFO (f)->xcb_connection);
 11314 #endif
 11315        }
 11316     }
 11317 }
 11318 
 11319 /* RIF: Cancel hourglass cursor on frame F.  */
 11320 
 11321 static void
 11322 x_hide_hourglass (struct frame *f)
 11323 {
 11324   struct x_output *x = FRAME_X_OUTPUT (f);
 11325 
 11326   /* Watch out for newly created frames.  */
 11327   if (x->hourglass_window)
 11328     {
 11329 #ifndef USE_XCB
 11330       XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
 11331 #else
 11332       xcb_unmap_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11333                         (xcb_window_t) x->hourglass_window);
 11334 #endif
 11335       x_send_hourglass_message (f, false);
 11336     }
 11337 }
 11338 
 11339 /* Invert the middle quarter of the frame for .15 sec.  */
 11340 
 11341 static void
 11342 XTflash (struct frame *f)
 11343 {
 11344   GC gc;
 11345   XGCValues values;
 11346   fd_set fds;
 11347   int fd, rc;
 11348 
 11349   block_input ();
 11350 
 11351   if (FRAME_X_VISUAL_INFO (f)->class == TrueColor)
 11352     {
 11353       values.function = GXxor;
 11354       values.foreground = (FRAME_FOREGROUND_PIXEL (f)
 11355                            ^ FRAME_BACKGROUND_PIXEL (f));
 11356 
 11357       gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 11358                       GCFunction | GCForeground, &values);
 11359     }
 11360   else
 11361     gc = FRAME_X_OUTPUT (f)->normal_gc;
 11362 
 11363 
 11364   /* Get the height not including a menu bar widget.  */
 11365   int height = FRAME_PIXEL_HEIGHT (f);
 11366   /* Height of each line to flash.  */
 11367   int flash_height = FRAME_LINE_HEIGHT (f);
 11368   /* These will be the left and right margins of the rectangles.  */
 11369   int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
 11370   int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
 11371   int width = flash_right - flash_left;
 11372 
 11373   /* If window is tall, flash top and bottom line.  */
 11374   if (height > 3 * FRAME_LINE_HEIGHT (f))
 11375     {
 11376       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11377                       flash_left,
 11378                       (FRAME_INTERNAL_BORDER_WIDTH (f)
 11379                        + FRAME_TOP_MARGIN_HEIGHT (f)),
 11380                       width, flash_height);
 11381       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11382                       flash_left,
 11383                       (height - flash_height
 11384                        - FRAME_INTERNAL_BORDER_WIDTH (f)
 11385                        - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
 11386                       width, flash_height);
 11387 
 11388     }
 11389   else
 11390     /* If it is short, flash it all.  */
 11391     XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11392                     flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
 11393                     width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
 11394 
 11395   x_flush (f);
 11396 
 11397   struct timespec delay = make_timespec (0, 150 * 1000 * 1000);
 11398   struct timespec wakeup = timespec_add (current_timespec (), delay);
 11399   fd = ConnectionNumber (FRAME_X_DISPLAY (f));
 11400 
 11401   /* Keep waiting until past the time wakeup or any input gets
 11402      available.  */
 11403   while (! detect_input_pending ())
 11404     {
 11405       struct timespec current = current_timespec ();
 11406       struct timespec timeout;
 11407 
 11408       /* Break if result would not be positive.  */
 11409       if (timespec_cmp (wakeup, current) <= 0)
 11410         break;
 11411 
 11412       /* How long `select' should wait.  */
 11413       timeout = make_timespec (0, 10 * 1000 * 1000);
 11414 
 11415       /* Wait for some input to become available on the X
 11416          connection.  */
 11417       FD_ZERO (&fds);
 11418       FD_SET (fd, &fds);
 11419 
 11420       /* Try to wait that long--but we might wake up sooner.  */
 11421       rc = pselect (fd + 1, &fds, NULL, NULL, &timeout, NULL);
 11422 
 11423       /* Some input is available, exit the visible bell.  */
 11424       if (rc >= 0 && FD_ISSET (fd, &fds))
 11425         break;
 11426     }
 11427 
 11428   /* If window is tall, flash top and bottom line.  */
 11429   if (height > 3 * FRAME_LINE_HEIGHT (f))
 11430     {
 11431       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11432                       flash_left,
 11433                       (FRAME_INTERNAL_BORDER_WIDTH (f)
 11434                        + FRAME_TOP_MARGIN_HEIGHT (f)),
 11435                       width, flash_height);
 11436       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11437                       flash_left,
 11438                       (height - flash_height
 11439                        - FRAME_INTERNAL_BORDER_WIDTH (f)
 11440                        - FRAME_BOTTOM_MARGIN_HEIGHT (f)),
 11441                       width, flash_height);
 11442     }
 11443   else
 11444     /* If it is short, flash it all.  */
 11445     XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
 11446                     flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
 11447                     width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
 11448 
 11449   if (FRAME_X_VISUAL_INFO (f)->class == TrueColor)
 11450     XFreeGC (FRAME_X_DISPLAY (f), gc);
 11451   x_flush (f);
 11452 
 11453   unblock_input ();
 11454 }
 11455 
 11456 /* Make audible bell.  */
 11457 
 11458 static void
 11459 XTring_bell (struct frame *f)
 11460 {
 11461   struct x_display_info *dpyinfo;
 11462 
 11463   if (!FRAME_X_DISPLAY (f))
 11464     return;
 11465 
 11466   dpyinfo = FRAME_DISPLAY_INFO (f);
 11467 
 11468   if (visible_bell)
 11469     XTflash (f);
 11470   else
 11471     {
 11472       /* When Emacs is untrusted, Bell requests sometimes generate
 11473          Access errors.  This is not in the security extension
 11474          specification but seems to be a bug in the X consortium XKB
 11475          implementation.  */
 11476 
 11477       block_input ();
 11478       x_ignore_errors_for_next_request (dpyinfo, 0);
 11479 #ifdef HAVE_XKB
 11480       XkbBell (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 0, None);
 11481 #else
 11482       XBell (FRAME_X_DISPLAY (f), 0);
 11483 #endif
 11484       XFlush (FRAME_X_DISPLAY (f));
 11485       x_stop_ignoring_errors (dpyinfo);
 11486       unblock_input ();
 11487     }
 11488 }
 11489 
 11490 /***********************************************************************
 11491                               Line Dance
 11492  ***********************************************************************/
 11493 
 11494 /* Perform an insert-lines or delete-lines operation, inserting N
 11495    lines or deleting -N lines at vertical position VPOS.  */
 11496 
 11497 static void
 11498 x_ins_del_lines (struct frame *f, int vpos, int n)
 11499 {
 11500   emacs_abort ();
 11501 }
 11502 
 11503 
 11504 /* Scroll part of the display as described by RUN.  */
 11505 
 11506 static void
 11507 x_scroll_run (struct window *w, struct run *run)
 11508 {
 11509   struct frame *f = XFRAME (w->frame);
 11510   int x, y, width, height, from_y, to_y, bottom_y;
 11511 
 11512   /* Get frame-relative bounding box of the text display area of W,
 11513      without mode lines.  Include in this box the left and right
 11514      fringe of W.  */
 11515   window_box (w, ANY_AREA, &x, &y, &width, &height);
 11516 
 11517   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
 11518   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
 11519   bottom_y = y + height;
 11520 
 11521   if (to_y < from_y)
 11522     {
 11523       /* Scrolling up.  Make sure we don't copy part of the mode
 11524          line at the bottom.  */
 11525       if (from_y + run->height > bottom_y)
 11526         height = bottom_y - from_y;
 11527       else
 11528         height = run->height;
 11529     }
 11530   else
 11531     {
 11532       /* Scrolling down.  Make sure we don't copy over the mode line.
 11533          at the bottom.  */
 11534       if (to_y + run->height > bottom_y)
 11535         height = bottom_y - to_y;
 11536       else
 11537         height = run->height;
 11538     }
 11539 
 11540   block_input ();
 11541 
 11542   /* Cursor off.  Will be switched on again in gui_update_window_end.  */
 11543   gui_clear_cursor (w);
 11544 
 11545 #ifdef HAVE_XWIDGETS
 11546   /* "Copy" xwidget windows in the area that will be scrolled.  */
 11547   Display *dpy = FRAME_X_DISPLAY (f);
 11548   Window window = FRAME_X_WINDOW (f);
 11549 
 11550   Window root, parent, *children;
 11551   unsigned int nchildren;
 11552 
 11553   if (XQueryTree (dpy, window, &root, &parent, &children, &nchildren))
 11554     {
 11555       /* Now find xwidget views situated between from_y and to_y, and
 11556          attached to w.  */
 11557       for (unsigned int i = 0; i < nchildren; ++i)
 11558         {
 11559           Window child = children[i];
 11560           struct xwidget_view *view = xwidget_view_from_window (child);
 11561 
 11562           if (view && !view->hidden)
 11563             {
 11564               int window_y = view->y + view->clip_top;
 11565               int window_height = view->clip_bottom - view->clip_top;
 11566 
 11567               Emacs_Rectangle r1, r2, result;
 11568               r1.x = w->pixel_left;
 11569               r1.y = from_y;
 11570               r1.width = w->pixel_width;
 11571               r1.height = height;
 11572               r2 = r1;
 11573               r2.y = window_y;
 11574               r2.height = window_height;
 11575 
 11576               /* The window is offscreen, just unmap it.  */
 11577               if (window_height == 0)
 11578                 {
 11579                   view->hidden = true;
 11580                   XUnmapWindow (dpy, child);
 11581                   continue;
 11582                 }
 11583 
 11584               bool intersects_p =
 11585                 gui_intersect_rectangles (&r1, &r2, &result);
 11586 
 11587               if (XWINDOW (view->w) == w && intersects_p)
 11588                 {
 11589                   int y = view->y + (to_y - from_y);
 11590                   int text_area_x, text_area_y, text_area_width, text_area_height;
 11591                   int clip_top, clip_bottom;
 11592 
 11593                   window_box (w, view->area, &text_area_x, &text_area_y,
 11594                               &text_area_width, &text_area_height);
 11595 
 11596                   view->y = y;
 11597 
 11598                   clip_top = 0;
 11599                   clip_bottom = XXWIDGET (view->model)->height;
 11600 
 11601                   if (y < text_area_y)
 11602                     clip_top = text_area_y - y;
 11603 
 11604                   if ((y + clip_bottom) > (text_area_y + text_area_height))
 11605                     {
 11606                       clip_bottom -= (y + clip_bottom) - (text_area_y + text_area_height);
 11607                     }
 11608 
 11609                   view->clip_top = clip_top;
 11610                   view->clip_bottom = clip_bottom;
 11611 
 11612                   /* This means the view has moved offscreen.  Unmap
 11613                      it and hide it here.  */
 11614                   if ((view->clip_bottom - view->clip_top) <= 0)
 11615                     {
 11616                       view->hidden = true;
 11617                       XUnmapWindow (dpy, child);
 11618                     }
 11619                   else
 11620                     {
 11621                       XMoveResizeWindow (dpy, child, view->x + view->clip_left,
 11622                                          view->y + view->clip_top,
 11623                                          view->clip_right - view->clip_left,
 11624                                          view->clip_bottom - view->clip_top);
 11625                       cairo_xlib_surface_set_size (view->cr_surface,
 11626                                                    view->clip_right - view->clip_left,
 11627                                                    view->clip_bottom - view->clip_top);
 11628                     }
 11629                   xwidget_expose (view);
 11630                 }
 11631             }
 11632         }
 11633       XFree (children);
 11634     }
 11635 #endif
 11636 
 11637 #ifdef USE_CAIRO_XCB_SURFACE
 11638   /* Some of the following code depends on `normal_gc' being
 11639      up-to-date on the X server, but doesn't call a routine that will
 11640      flush it first.  So do this ourselves instead.  */
 11641   XFlushGC (FRAME_X_DISPLAY (f),
 11642             f->output_data.x->normal_gc);
 11643 #endif
 11644 
 11645 #ifdef USE_CAIRO
 11646   if (FRAME_CR_CONTEXT (f))
 11647     {
 11648       cairo_surface_t *surface = cairo_get_target (FRAME_CR_CONTEXT (f));
 11649       if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB)
 11650         {
 11651           eassert (cairo_xlib_surface_get_display (surface)
 11652                    == FRAME_X_DISPLAY (f));
 11653           eassert (cairo_xlib_surface_get_drawable (surface)
 11654                    == FRAME_X_RAW_DRAWABLE (f));
 11655           cairo_surface_flush (surface);
 11656           XCopyArea (FRAME_X_DISPLAY (f),
 11657                      FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
 11658                      f->output_data.x->normal_gc,
 11659                      x, from_y,
 11660                      width, height,
 11661                      x, to_y);
 11662           cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
 11663         }
 11664 #ifdef USE_CAIRO_XCB_SURFACE
 11665       else if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XCB)
 11666         {
 11667           cairo_surface_flush (surface);
 11668           xcb_copy_area (FRAME_DISPLAY_INFO (f)->xcb_connection,
 11669                          (xcb_drawable_t) FRAME_X_DRAWABLE (f),
 11670                          (xcb_drawable_t) FRAME_X_DRAWABLE (f),
 11671                          (xcb_gcontext_t) XGContextFromGC (f->output_data.x->normal_gc),
 11672                          x, from_y, x, to_y, width, height);
 11673           cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
 11674         }
 11675 #endif
 11676       else
 11677         {
 11678           cairo_surface_t *s
 11679             = cairo_surface_create_similar (surface,
 11680                                             cairo_surface_get_content (surface),
 11681                                             width, height);
 11682           cairo_t *cr = cairo_create (s);
 11683           cairo_set_source_surface (cr, surface, -x, -from_y);
 11684           cairo_paint (cr);
 11685           cairo_destroy (cr);
 11686 
 11687           cr = FRAME_CR_CONTEXT (f);
 11688           cairo_save (cr);
 11689           cairo_set_source_surface (cr, s, x, to_y);
 11690           cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
 11691           cairo_rectangle (cr, x, to_y, width, height);
 11692           cairo_fill (cr);
 11693           cairo_restore (cr);
 11694           cairo_surface_destroy (s);
 11695         }
 11696     }
 11697   else
 11698 #endif  /* USE_CAIRO */
 11699     XCopyArea (FRAME_X_DISPLAY (f),
 11700                FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f),
 11701                f->output_data.x->normal_gc,
 11702                x, from_y,
 11703                width, height,
 11704                x, to_y);
 11705 
 11706   unblock_input ();
 11707 }
 11708 
 11709 
 11710 
 11711 /***********************************************************************
 11712                            Exposure Events
 11713  ***********************************************************************/
 11714 
 11715 
 11716 static void
 11717 x_frame_highlight (struct frame *f)
 11718 {
 11719   struct x_display_info *dpyinfo;
 11720 
 11721   dpyinfo = FRAME_DISPLAY_INFO (f);
 11722 
 11723   /* We used to only do this if Vx_no_window_manager was non-nil, but
 11724      the ICCCM (section 4.1.6) says that the window's border pixmap
 11725      and border pixel are window attributes which are "private to the
 11726      client", so we can always change it to whatever we want.  */
 11727   block_input ();
 11728   /* I recently started to get errors in this XSetWindowBorder, depending on
 11729      the window-manager in use, tho something more is at play since I've been
 11730      using that same window-manager binary for ever.  Let's not crash just
 11731      because of this (bug#9310).  */
 11732   x_ignore_errors_for_next_request (dpyinfo, 0);
 11733   XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 11734                     f->output_data.x->border_pixel);
 11735   x_stop_ignoring_errors (dpyinfo);
 11736   unblock_input ();
 11737   gui_update_cursor (f, true);
 11738   x_set_frame_alpha (f);
 11739 }
 11740 
 11741 static void
 11742 x_frame_unhighlight (struct frame *f)
 11743 {
 11744   struct x_display_info *dpyinfo;
 11745 
 11746   dpyinfo = FRAME_DISPLAY_INFO (f);
 11747 
 11748   /* We used to only do this if Vx_no_window_manager was non-nil, but
 11749      the ICCCM (section 4.1.6) says that the window's border pixmap
 11750      and border pixel are window attributes which are "private to the
 11751      client", so we can always change it to whatever we want.  */
 11752 
 11753   block_input ();
 11754   /* Same as above for XSetWindowBorder (bug#9310).  */
 11755   x_ignore_errors_for_next_request (dpyinfo, 0);
 11756   XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 11757                           f->output_data.x->border_tile);
 11758   x_stop_ignoring_errors (dpyinfo);
 11759   unblock_input ();
 11760 
 11761   gui_update_cursor (f, true);
 11762   x_set_frame_alpha (f);
 11763 }
 11764 
 11765 /* The focus has changed.  Update the frames as necessary to reflect
 11766    the new situation.  Note that we can't change the selected frame
 11767    here, because the Lisp code we are interrupting might become confused.
 11768    Each event gets marked with the frame in which it occurred, so the
 11769    Lisp code can tell when the switch took place by examining the events.  */
 11770 
 11771 static void
 11772 x_new_focus_frame (struct x_display_info *dpyinfo, struct frame *frame)
 11773 {
 11774   struct frame *old_focus = dpyinfo->x_focus_frame;
 11775 #if defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
 11776   XIEventMask mask;
 11777   ptrdiff_t l;
 11778 
 11779   if (dpyinfo->supports_xi2)
 11780     {
 11781       l = XIMaskLen (XI_LASTEVENT);
 11782       mask.mask = alloca (l);
 11783       mask.mask_len = l;
 11784       memset (mask.mask, 0, l);
 11785 
 11786       mask.deviceid = XIAllDevices;
 11787     }
 11788 #endif
 11789 
 11790   if (frame != dpyinfo->x_focus_frame)
 11791     {
 11792       /* Set this before calling other routines, so that they see
 11793          the correct value of x_focus_frame.  */
 11794       dpyinfo->x_focus_frame = frame;
 11795 
 11796       /* Once none of our frames are focused anymore, stop selecting
 11797          for raw input events from the root window.  */
 11798 
 11799 #if defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
 11800       if (frame && dpyinfo->supports_xi2)
 11801         XISetMask (mask.mask, XI_RawKeyPress);
 11802 
 11803       if (dpyinfo->supports_xi2)
 11804         XISelectEvents (dpyinfo->display, dpyinfo->root_window, &mask, 1);
 11805 #endif
 11806 
 11807       if (old_focus && old_focus->auto_lower)
 11808         x_lower_frame (old_focus);
 11809 
 11810       if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
 11811         dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
 11812       else
 11813         dpyinfo->x_pending_autoraise_frame = NULL;
 11814     }
 11815 
 11816   x_frame_rehighlight (dpyinfo);
 11817 }
 11818 
 11819 #if defined HAVE_XFIXES && XFIXES_VERSION >= 40000
 11820 
 11821 /* True if the display in DPYINFO supports a version of Xfixes
 11822    sufficient for pointer blanking.  */
 11823 
 11824 static bool
 11825 x_fixes_pointer_blanking_supported (struct x_display_info *dpyinfo)
 11826 {
 11827   return (dpyinfo->xfixes_supported_p
 11828           && dpyinfo->xfixes_major >= 4);
 11829 }
 11830 
 11831 #endif /* HAVE_XFIXES && XFIXES_VERSION >= 40000 */
 11832 
 11833 /* Toggle mouse pointer visibility on frame F using the XFixes
 11834    extension.  */
 11835 #if defined HAVE_XFIXES && XFIXES_VERSION >= 40000
 11836 
 11837 static void
 11838 xfixes_toggle_visible_pointer (struct frame *f, bool invisible)
 11839 
 11840 {
 11841   if (invisible)
 11842     XFixesHideCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 11843   else
 11844     XFixesShowCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 11845   f->pointer_invisible = invisible;
 11846 }
 11847 
 11848 #endif /* HAVE_XFIXES */
 11849 
 11850 /* Create invisible cursor on the X display referred by DPYINFO.  */
 11851 static Cursor
 11852 make_invisible_cursor (struct x_display_info *dpyinfo)
 11853 {
 11854   Display *dpy = dpyinfo->display;
 11855   static char const no_data[] = { 0 };
 11856   Pixmap pix;
 11857   XColor col;
 11858   Cursor c;
 11859 
 11860   c = None;
 11861 
 11862   x_catch_errors (dpy);
 11863   pix = XCreateBitmapFromData (dpy, dpyinfo->root_window, no_data, 1, 1);
 11864   if (!x_had_errors_p (dpy) && pix != None)
 11865     {
 11866       Cursor pixc;
 11867       col.pixel = 0;
 11868       col.red = col.green = col.blue = 0;
 11869       col.flags = DoRed | DoGreen | DoBlue;
 11870       pixc = XCreatePixmapCursor (dpy, pix, pix, &col, &col, 0, 0);
 11871       if (! x_had_errors_p (dpy) && pixc != None)
 11872         c = pixc;
 11873       XFreePixmap (dpy, pix);
 11874     }
 11875 
 11876   x_uncatch_errors ();
 11877 
 11878   return c;
 11879 }
 11880 
 11881 /* Toggle mouse pointer visibility on frame F by using an invisible
 11882    cursor.  */
 11883 static void
 11884 x_toggle_visible_pointer (struct frame *f, bool invisible)
 11885 {
 11886   struct x_display_info *dpyinfo;
 11887 
 11888   dpyinfo = FRAME_DISPLAY_INFO (f);
 11889 
 11890   /* We could have gotten a BadAlloc error while creating the
 11891      invisible cursor.  Try to create it again, but if that fails,
 11892      just give up.  */
 11893   if (dpyinfo->invisible_cursor == None)
 11894     dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo);
 11895 
 11896 #if !defined HAVE_XFIXES || XFIXES_VERSION < 40000
 11897   if (dpyinfo->invisible_cursor == None)
 11898     invisible = false;
 11899 #else
 11900   /* But if Xfixes is available, try using it instead.  */
 11901   if (dpyinfo->invisible_cursor == None)
 11902     {
 11903       if (x_fixes_pointer_blanking_supported (dpyinfo))
 11904         {
 11905           dpyinfo->fixes_pointer_blanking = true;
 11906           xfixes_toggle_visible_pointer (f, invisible);
 11907 
 11908           return;
 11909         }
 11910       else
 11911         invisible = false;
 11912     }
 11913 #endif
 11914 
 11915   if (invisible)
 11916     XDefineCursor (dpyinfo->display, FRAME_X_WINDOW (f),
 11917                    dpyinfo->invisible_cursor);
 11918   else
 11919     XDefineCursor (dpyinfo->display, FRAME_X_WINDOW (f),
 11920                    f->output_data.x->current_cursor);
 11921 
 11922   f->pointer_invisible = invisible;
 11923 }
 11924 
 11925 static void
 11926 XTtoggle_invisible_pointer (struct frame *f, bool invisible)
 11927 {
 11928   block_input ();
 11929 #if defined HAVE_XFIXES && XFIXES_VERSION >= 40000
 11930   if (FRAME_DISPLAY_INFO (f)->fixes_pointer_blanking
 11931       && x_fixes_pointer_blanking_supported (FRAME_DISPLAY_INFO (f)))
 11932     xfixes_toggle_visible_pointer (f, invisible);
 11933   else
 11934 #endif
 11935     x_toggle_visible_pointer (f, invisible);
 11936   unblock_input ();
 11937 }
 11938 
 11939 /* Handle FocusIn and FocusOut state changes for FRAME.  If FRAME has
 11940    focus and there exists more than one frame, puts a FOCUS_IN_EVENT
 11941    into *BUFP.  Note that this code is not used to handle focus
 11942    changes on builds that can use the X Input extension for handling
 11943    input focus when it is available (currently the no toolkit and GTK
 11944    3 toolkits).  */
 11945 
 11946 static void
 11947 x_focus_changed (int type, int state, struct x_display_info *dpyinfo,
 11948                  struct frame *frame, struct input_event *bufp)
 11949 {
 11950   if (type == FocusIn)
 11951     {
 11952       if (dpyinfo->x_focus_event_frame != frame)
 11953         {
 11954           x_new_focus_frame (dpyinfo, frame);
 11955           dpyinfo->x_focus_event_frame = frame;
 11956           bufp->kind = FOCUS_IN_EVENT;
 11957           XSETFRAME (bufp->frame_or_window, frame);
 11958         }
 11959 
 11960       frame->output_data.x->focus_state |= state;
 11961 
 11962 #ifdef HAVE_X_I18N
 11963       if (FRAME_XIC (frame))
 11964         XSetICFocus (FRAME_XIC (frame));
 11965 #ifdef USE_GTK
 11966       GtkWidget *widget;
 11967 
 11968       if (x_gtk_use_native_input)
 11969         {
 11970           gtk_im_context_focus_in (FRAME_X_OUTPUT (frame)->im_context);
 11971           widget = FRAME_GTK_OUTER_WIDGET (frame);
 11972           gtk_im_context_set_client_window (FRAME_X_OUTPUT (frame)->im_context,
 11973                                             gtk_widget_get_window (widget));
 11974         }
 11975 #endif
 11976 #endif
 11977     }
 11978   else if (type == FocusOut)
 11979     {
 11980       frame->output_data.x->focus_state &= ~state;
 11981 
 11982       if (dpyinfo->x_focus_event_frame == frame)
 11983         {
 11984           dpyinfo->x_focus_event_frame = 0;
 11985           x_new_focus_frame (dpyinfo, 0);
 11986 
 11987           bufp->kind = FOCUS_OUT_EVENT;
 11988           XSETFRAME (bufp->frame_or_window, frame);
 11989         }
 11990 
 11991       if (!frame->output_data.x->focus_state)
 11992         {
 11993 #ifdef HAVE_X_I18N
 11994           if (FRAME_XIC (frame))
 11995             XUnsetICFocus (FRAME_XIC (frame));
 11996 #ifdef USE_GTK
 11997           if (x_gtk_use_native_input)
 11998             {
 11999               gtk_im_context_focus_out (FRAME_X_OUTPUT (frame)->im_context);
 12000               gtk_im_context_set_client_window (FRAME_X_OUTPUT (frame)->im_context, NULL);
 12001             }
 12002 #endif
 12003 #endif
 12004         }
 12005 
 12006       if (frame->pointer_invisible)
 12007         XTtoggle_invisible_pointer (frame, false);
 12008     }
 12009 }
 12010 
 12011 /* Return the Emacs frame-object corresponding to an X window.  It
 12012    could be the frame's main window, an icon window, or an xwidget
 12013    window.  */
 12014 
 12015 static struct frame *
 12016 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 12017 {
 12018   Lisp_Object tail, frame;
 12019   struct frame *f;
 12020 
 12021   if (wdesc == None)
 12022     return NULL;
 12023 
 12024 #ifdef HAVE_XWIDGETS
 12025   struct xwidget_view *xvw = xwidget_view_from_window (wdesc);
 12026 
 12027   if (xvw && xvw->frame)
 12028     return xvw->frame;
 12029 #endif
 12030 
 12031   FOR_EACH_FRAME (tail, frame)
 12032     {
 12033       f = XFRAME (frame);
 12034       if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
 12035         continue;
 12036       if (f->output_data.x->hourglass_window == wdesc)
 12037         return f;
 12038 #ifdef USE_X_TOOLKIT
 12039       if ((f->output_data.x->edit_widget
 12040            && XtWindow (f->output_data.x->edit_widget) == wdesc)
 12041           /* A tooltip frame?  */
 12042           || (!f->output_data.x->edit_widget
 12043               && FRAME_X_WINDOW (f) == wdesc)
 12044           || f->output_data.x->icon_desc == wdesc)
 12045         return f;
 12046 #else /* not USE_X_TOOLKIT */
 12047 #ifdef USE_GTK
 12048       if (f->output_data.x->edit_widget)
 12049       {
 12050         GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 12051         struct x_output *x = f->output_data.x;
 12052         if (gwdesc != 0 && gwdesc == x->edit_widget)
 12053           return f;
 12054       }
 12055 #endif /* USE_GTK */
 12056       if (FRAME_X_WINDOW (f) == wdesc
 12057           || f->output_data.x->icon_desc == wdesc)
 12058         return f;
 12059 #endif /* not USE_X_TOOLKIT */
 12060     }
 12061   return 0;
 12062 }
 12063 
 12064 /* Like x_any_window_to_frame but only try to find tooltip frames.
 12065 
 12066    If wdesc is a toolkit tooltip without an associated frame, set
 12067    UNRELATED_TOOLTIP_P to true.  Otherwise, set it to false.  */
 12068 static struct frame *
 12069 x_tooltip_window_to_frame (struct x_display_info *dpyinfo,
 12070                            Window wdesc, bool *unrelated_tooltip_p)
 12071 {
 12072   Lisp_Object tail, frame;
 12073   struct frame *f;
 12074 #ifdef USE_GTK
 12075   GtkWidget *widget;
 12076   GdkWindow *tooltip_window;
 12077 #endif
 12078 
 12079   if (unrelated_tooltip_p)
 12080     *unrelated_tooltip_p = false;
 12081 
 12082   FOR_EACH_FRAME (tail, frame)
 12083     {
 12084       f = XFRAME (frame);
 12085 
 12086       if (FRAME_X_P (f) && FRAME_TOOLTIP_P (f)
 12087           && FRAME_DISPLAY_INFO (f) == dpyinfo
 12088           && FRAME_X_WINDOW (f) == wdesc)
 12089         return f;
 12090 
 12091 #ifdef USE_GTK
 12092       if (!FRAME_X_P (f))
 12093         continue;
 12094 
 12095       if (FRAME_X_OUTPUT (f)->ttip_window)
 12096         widget = GTK_WIDGET (FRAME_X_OUTPUT (f)->ttip_window);
 12097       else
 12098         widget = NULL;
 12099 
 12100       if (widget)
 12101         tooltip_window = gtk_widget_get_window (widget);
 12102       else
 12103         tooltip_window = NULL;
 12104 
 12105 #ifdef HAVE_GTK3
 12106       if (tooltip_window
 12107           && (gdk_x11_window_get_xid (tooltip_window) == wdesc))
 12108         {
 12109           if (unrelated_tooltip_p)
 12110             *unrelated_tooltip_p = true;
 12111           break;
 12112         }
 12113 #else
 12114       if (tooltip_window
 12115           && (GDK_WINDOW_XID (tooltip_window) == wdesc))
 12116         {
 12117           if (unrelated_tooltip_p)
 12118             *unrelated_tooltip_p = true;
 12119           break;
 12120         }
 12121 #endif
 12122 #endif
 12123     }
 12124 
 12125   return NULL;
 12126 }
 12127 
 12128 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 12129 
 12130 /* Like x_window_to_frame but also compares the window with the widget's
 12131    windows.  */
 12132 
 12133 static struct frame *
 12134 x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 12135 {
 12136   Lisp_Object tail, frame;
 12137   struct frame *f, *found = NULL;
 12138   struct x_output *x;
 12139 
 12140   if (wdesc == None)
 12141     return NULL;
 12142 
 12143 #ifdef HAVE_XWIDGETS
 12144   struct xwidget_view *xv = xwidget_view_from_window (wdesc);
 12145 
 12146   if (xv)
 12147     return xv->frame;
 12148 #endif
 12149 
 12150   FOR_EACH_FRAME (tail, frame)
 12151     {
 12152       if (found)
 12153         break;
 12154       f = XFRAME (frame);
 12155       if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
 12156         {
 12157           /* This frame matches if the window is any of its widgets.  */
 12158           x = f->output_data.x;
 12159           if (x->hourglass_window == wdesc)
 12160             found = f;
 12161           else if (x->widget)
 12162             {
 12163 #ifdef USE_GTK
 12164               GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 12165               if (gwdesc != 0
 12166                   && gtk_widget_get_toplevel (gwdesc) == x->widget)
 12167                 found = f;
 12168 #else
 12169               if (wdesc == XtWindow (x->widget)
 12170                   || wdesc == XtWindow (x->column_widget)
 12171                   || wdesc == XtWindow (x->edit_widget))
 12172                 found = f;
 12173               /* Match if the window is this frame's menubar.  */
 12174               else if (lw_window_is_in_menubar (wdesc, x->menubar_widget))
 12175                 found = f;
 12176 #endif
 12177             }
 12178           else if (FRAME_X_WINDOW (f) == wdesc)
 12179             /* A tooltip frame.  */
 12180             found = f;
 12181         }
 12182     }
 12183 
 12184   return found;
 12185 }
 12186 
 12187 /* Likewise, but consider only the menu bar widget.  */
 12188 
 12189 static struct frame *
 12190 x_menubar_window_to_frame (struct x_display_info *dpyinfo,
 12191                            const XEvent *event)
 12192 {
 12193   Window wdesc;
 12194 #ifdef HAVE_XINPUT2
 12195   if (event->type == GenericEvent
 12196       && dpyinfo->supports_xi2
 12197       && (event->xcookie.evtype == XI_ButtonPress
 12198           || event->xcookie.evtype == XI_ButtonRelease))
 12199     wdesc = ((XIDeviceEvent *) event->xcookie.data)->event;
 12200   else
 12201 #endif
 12202     wdesc = event->xany.window;
 12203   Lisp_Object tail, frame;
 12204   struct frame *f;
 12205   struct x_output *x;
 12206 
 12207   if (wdesc == None)
 12208     return NULL;
 12209 
 12210   FOR_EACH_FRAME (tail, frame)
 12211     {
 12212       f = XFRAME (frame);
 12213       if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
 12214         continue;
 12215       x = f->output_data.x;
 12216 #ifdef USE_GTK
 12217       if (x->menubar_widget && xg_event_is_for_menubar (f, event))
 12218         return f;
 12219 #else
 12220       /* Match if the window is this frame's menubar.  */
 12221       if (x->menubar_widget
 12222           && lw_window_is_in_menubar (wdesc, x->menubar_widget))
 12223         return f;
 12224 #endif
 12225     }
 12226   return 0;
 12227 }
 12228 
 12229 /* Return the frame whose principal (outermost) window is WDESC.
 12230    If WDESC is some other (smaller) window, we return 0.  */
 12231 
 12232 struct frame *
 12233 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 12234 {
 12235   Lisp_Object tail, frame;
 12236   struct frame *f;
 12237   struct x_output *x;
 12238 
 12239   if (wdesc == None)
 12240     return NULL;
 12241 
 12242   FOR_EACH_FRAME (tail, frame)
 12243     {
 12244       f = XFRAME (frame);
 12245       if (!FRAME_X_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
 12246         continue;
 12247       x = f->output_data.x;
 12248 
 12249       if (x->widget)
 12250         {
 12251           /* This frame matches if the window is its topmost widget.  */
 12252 #ifdef USE_GTK
 12253           GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
 12254           if (gwdesc == x->widget)
 12255             return f;
 12256 #else
 12257           if (wdesc == XtWindow (x->widget))
 12258             return f;
 12259 #endif
 12260         }
 12261       else if (FRAME_X_WINDOW (f) == wdesc)
 12262         /* Tooltip frame.  */
 12263         return f;
 12264     }
 12265   return 0;
 12266 }
 12267 
 12268 #else /* !USE_X_TOOLKIT && !USE_GTK */
 12269 
 12270 #define x_any_window_to_frame(d, i) x_window_to_frame (d, i)
 12271 
 12272 struct frame *
 12273 x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 12274 {
 12275   return x_window_to_frame (dpyinfo, wdesc);
 12276 }
 12277 
 12278 static void
 12279 x_next_event_from_any_display (XEvent *event)
 12280 {
 12281   struct x_display_info *dpyinfo;
 12282   fd_set fds, rfds;
 12283   int fd, maxfd, rc;
 12284 
 12285   rc = -1;
 12286   FD_ZERO (&rfds);
 12287 
 12288   while (true)
 12289     {
 12290       FD_ZERO (&fds);
 12291       maxfd = -1;
 12292 
 12293       for (dpyinfo = x_display_list; dpyinfo;
 12294            dpyinfo = dpyinfo->next)
 12295         {
 12296           fd = ConnectionNumber (dpyinfo->display);
 12297 
 12298           if ((rc < 0 || FD_ISSET (fd, &rfds))
 12299               && XPending (dpyinfo->display))
 12300             {
 12301               XNextEvent (dpyinfo->display, event);
 12302               return;
 12303             }
 12304 
 12305           if (fd > maxfd)
 12306             maxfd = fd;
 12307 
 12308           eassert (fd < FD_SETSIZE);
 12309           FD_SET (fd, &fds);
 12310         }
 12311 
 12312       eassert (maxfd >= 0);
 12313 
 12314       /* Continue to read input even if pselect fails, because if an
 12315          error occurs XPending will call the IO error handler, which
 12316          then brings us out of this loop.  */
 12317       rc = pselect (maxfd + 1, &fds, NULL, NULL, NULL, NULL);
 12318 
 12319       if (rc >= 0)
 12320         rfds = fds;
 12321     }
 12322 }
 12323 
 12324 #endif /* USE_X_TOOLKIT || USE_GTK */
 12325 
 12326 static void
 12327 x_handle_pending_selection_requests_1 (struct x_selection_request_event *tem)
 12328 {
 12329   specpdl_ref count;
 12330   struct selection_input_event se;
 12331 
 12332   count = SPECPDL_INDEX ();
 12333   se = tem->se;
 12334 
 12335   record_unwind_protect_ptr (xfree, tem);
 12336   x_handle_selection_event (&se);
 12337   unbind_to (count, Qnil);
 12338 }
 12339 
 12340 /* Handle all pending selection request events from modal event
 12341    loops.  */
 12342 void
 12343 x_handle_pending_selection_requests (void)
 12344 {
 12345   struct x_selection_request_event *tem;
 12346 
 12347   while (pending_selection_requests)
 12348     {
 12349       tem = pending_selection_requests;
 12350       pending_selection_requests = tem->next;
 12351 
 12352       x_handle_pending_selection_requests_1 (tem);
 12353     }
 12354 }
 12355 
 12356 static void
 12357 x_push_selection_request (struct selection_input_event *se)
 12358 {
 12359   struct x_selection_request_event *tem;
 12360 
 12361   tem = xmalloc (sizeof *tem);
 12362   tem->next = pending_selection_requests;
 12363   tem->se = *se;
 12364   pending_selection_requests = tem;
 12365 }
 12366 
 12367 bool
 12368 x_detect_pending_selection_requests (void)
 12369 {
 12370   return !!pending_selection_requests;
 12371 }
 12372 
 12373 static void
 12374 x_clear_dnd_action (void)
 12375 {
 12376   x_dnd_action_symbol = Qnil;
 12377 }
 12378 
 12379 /* Delete action descriptions from F after drag-and-drop.  */
 12380 static void
 12381 x_dnd_delete_action_list (Lisp_Object frame)
 12382 {
 12383   struct frame *f;
 12384 
 12385   /* Delete those two properties, since some clients look at them and
 12386      not the action to decide whether or not the user should be
 12387      prompted to select an action.  This can be called with FRAME no
 12388      longer alive (or its display dead).  */
 12389 
 12390   f = XFRAME (frame);
 12391 
 12392   if (!FRAME_LIVE_P (f) || !FRAME_DISPLAY_INFO (f)->display)
 12393     return;
 12394 
 12395   block_input ();
 12396   XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 12397                    FRAME_DISPLAY_INFO (f)->Xatom_XdndActionList);
 12398   XDeleteProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 12399                    FRAME_DISPLAY_INFO (f)->Xatom_XdndActionDescription);
 12400   unblock_input ();
 12401 }
 12402 
 12403 static void
 12404 x_dnd_lose_ownership (Lisp_Object timestamp_and_frame)
 12405 {
 12406   struct frame *f;
 12407 
 12408   f = XFRAME (XCDR (timestamp_and_frame));
 12409 
 12410   if (FRAME_LIVE_P (f))
 12411     Fx_disown_selection_internal (QXdndSelection,
 12412                                   XCAR (timestamp_and_frame),
 12413                                   XCDR (timestamp_and_frame));
 12414 }
 12415 
 12416 /* Clean up an existing drag-and-drop operation in preparation for its
 12417    sudden termination.  */
 12418 
 12419 static void
 12420 x_dnd_process_quit (struct frame *f, Time timestamp)
 12421 {
 12422   xm_drop_start_message dmsg;
 12423 
 12424   if (x_dnd_in_progress)
 12425     {
 12426       if (x_dnd_last_seen_window != None
 12427           && x_dnd_last_protocol_version != -1)
 12428         x_dnd_send_leave (f, x_dnd_last_seen_window,
 12429                           x_dnd_last_seen_toplevel);
 12430       else if (x_dnd_last_seen_window != None
 12431                && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
 12432                && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
 12433                && x_dnd_motif_setup_p)
 12434         {
 12435           dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 12436                                         XM_DRAG_REASON_DROP_START);
 12437           dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
 12438           dmsg.timestamp = timestamp;
 12439           dmsg.side_effects
 12440             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
 12441                                                                x_dnd_wanted_action),
 12442                                    XM_DROP_SITE_VALID, x_dnd_motif_operations,
 12443                                    XM_DROP_ACTION_DROP_CANCEL);
 12444           dmsg.x = 0;
 12445           dmsg.y = 0;
 12446           dmsg.index_atom = x_dnd_motif_atom;
 12447           dmsg.source_window = FRAME_X_WINDOW (f);
 12448 
 12449           x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
 12450                                         x_dnd_last_seen_window,
 12451                                         timestamp);
 12452           xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
 12453                                 x_dnd_last_seen_window, &dmsg);
 12454         }
 12455 
 12456       x_dnd_end_window = x_dnd_last_seen_window;
 12457       x_dnd_last_seen_window = None;
 12458       x_dnd_last_seen_toplevel = None;
 12459       x_dnd_in_progress = false;
 12460       x_dnd_frame = NULL;
 12461     }
 12462 
 12463   x_dnd_waiting_for_finish = false;
 12464   x_dnd_return_frame_object = NULL;
 12465   x_dnd_movement_frame = NULL;
 12466   x_dnd_wheel_frame = NULL;
 12467 }
 12468 
 12469 /* This function is defined far away from the rest of the XDND code so
 12470    it can utilize `x_any_window_to_frame'.  */
 12471 
 12472 /* Implementors beware!  On most other platforms (where drag-and-drop
 12473    data is not provided via selections, but some kind of serialization
 12474    mechanism), it is usually much easier to implement a suitable
 12475    primitive instead of copying the C code here, and then to build
 12476    `x-begin-drag' on top of that, by making it a wrapper function in
 12477    Lisp that converts the list of targets and value of `XdndSelection'
 12478    to serialized data.  Also be sure to update the data types used in
 12479    dnd.el.
 12480 
 12481    For examples of how to do this, see `haiku-drag-message' and
 12482    `x-begin-drag' in haikuselect.c and lisp/term/haiku-win.el, and
 12483    `ns-begin-drag' and `x-begin-drag' in nsselect.m and
 12484    lisp/term/ns-win.el.  */
 12485 
 12486 Lisp_Object
 12487 x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
 12488                            Lisp_Object return_frame, Atom *ask_action_list,
 12489                            const char **ask_action_names, size_t n_ask_actions,
 12490                            bool allow_current_frame, Atom *target_atoms,
 12491                            int ntargets, Lisp_Object selection_target_list,
 12492                            bool follow_tooltip)
 12493 {
 12494 #ifndef USE_GTK
 12495   XEvent next_event;
 12496   int finish;
 12497 #endif
 12498   XWindowAttributes root_window_attrs;
 12499   struct input_event hold_quit;
 12500   char *atom_name, *ask_actions;
 12501   Lisp_Object action, ltimestamp, val;
 12502   specpdl_ref ref, count, base;
 12503   ptrdiff_t i, end, fill;
 12504   XTextProperty prop;
 12505   Lisp_Object frame_object, x, y, frame, local_value;
 12506   bool signals_were_pending, need_sync;
 12507 #ifdef HAVE_XKB
 12508   XkbStateRec keyboard_state;
 12509 #endif
 12510 #ifndef USE_GTK
 12511   struct x_display_info *event_display;
 12512 #endif
 12513   unsigned int additional_mask;
 12514 #ifdef HAVE_XINPUT2
 12515   struct xi_device_t *device;
 12516 #endif
 12517 
 12518   if (FRAME_DISPLAY_INFO (f)->untrusted)
 12519     /* Untrusted clients cannot send messages to trusted clients or
 12520        read the window tree, so drag and drop will likely not work at
 12521        all.  */
 12522     error ("Drag-and-drop is not possible when the client is"
 12523            " not trusted by the X server.");
 12524 
 12525   base = SPECPDL_INDEX ();
 12526 
 12527   /* Bind this here to avoid juggling bindings and SAFE_FREE in
 12528      Fx_begin_drag.  */
 12529   specbind (Qx_dnd_targets_list, selection_target_list);
 12530 
 12531   if (!FRAME_VISIBLE_P (f))
 12532     error ("Frame must be visible");
 12533 
 12534   XSETFRAME (frame, f);
 12535   local_value = assq_no_quit (QXdndSelection,
 12536                               FRAME_TERMINAL (f)->Vselection_alist);
 12537 
 12538   if (x_dnd_in_progress || x_dnd_waiting_for_finish)
 12539     error ("A drag-and-drop session is already in progress");
 12540 
 12541   DEFER_SELECTIONS;
 12542 
 12543   /* If local_value is nil, then we lost ownership of XdndSelection.
 12544      Signal a more informative error than args-out-of-range.  */
 12545   if (NILP (local_value))
 12546     error ("No local value for XdndSelection");
 12547 
 12548   if (popup_activated ())
 12549     error ("Trying to drag-and-drop from within a menu-entry");
 12550 
 12551   x_set_dnd_targets (target_atoms, ntargets);
 12552   record_unwind_protect_void (x_free_dnd_targets);
 12553   record_unwind_protect_void (x_clear_dnd_action);
 12554 
 12555   ltimestamp = x_timestamp_for_selection (FRAME_DISPLAY_INFO (f),
 12556                                           QXdndSelection);
 12557 
 12558   if (NILP (ltimestamp))
 12559     error ("No local value for XdndSelection");
 12560 
 12561   if (BIGNUMP (ltimestamp))
 12562     x_dnd_selection_timestamp = bignum_to_intmax (ltimestamp);
 12563   else
 12564     x_dnd_selection_timestamp = XFIXNUM (ltimestamp);
 12565 
 12566   /* Release ownership of XdndSelection after this function returns.
 12567      VirtualBox uses the owner of XdndSelection to determine whether
 12568      or not mouse motion is part of a drag-and-drop operation.  */
 12569 
 12570   if (!x_dnd_preserve_selection_data)
 12571     record_unwind_protect (x_dnd_lose_ownership,
 12572                            Fcons (ltimestamp, frame));
 12573 
 12574   x_dnd_motif_operations
 12575     = xm_side_effect_from_action (FRAME_DISPLAY_INFO (f), xaction);
 12576 
 12577   x_dnd_first_motif_operation = XM_DRAG_NOOP;
 12578 
 12579   if (n_ask_actions)
 12580     {
 12581       x_dnd_motif_operations
 12582         = xm_operations_from_actions (FRAME_DISPLAY_INFO (f),
 12583                                       ask_action_list,
 12584                                       n_ask_actions);
 12585       x_dnd_first_motif_operation
 12586         = xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
 12587                                       ask_action_list[0]);
 12588 
 12589       record_unwind_protect (x_dnd_delete_action_list, frame);
 12590 
 12591       ask_actions = NULL;
 12592       end = 0;
 12593       count = SPECPDL_INDEX ();
 12594 
 12595       for (i = 0; i < n_ask_actions; ++i)
 12596         {
 12597           fill = end;
 12598           end += strlen (ask_action_names[i]) + 1;
 12599 
 12600           if (ask_actions)
 12601             ask_actions = xrealloc (ask_actions, end);
 12602           else
 12603             ask_actions = xmalloc (end);
 12604 
 12605           strncpy (ask_actions + fill,
 12606                    ask_action_names[i],
 12607                    end - fill);
 12608         }
 12609 
 12610       prop.value = (unsigned char *) ask_actions;
 12611       prop.encoding = XA_STRING;
 12612       prop.format = 8;
 12613       prop.nitems = end;
 12614 
 12615       record_unwind_protect_ptr (xfree, ask_actions);
 12616 
 12617       /* This can potentially store a lot of data in window
 12618          properties, so check for allocation errors.  */
 12619       block_input ();
 12620       x_catch_errors (FRAME_X_DISPLAY (f));
 12621       XSetTextProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 12622                         &prop, FRAME_DISPLAY_INFO (f)->Xatom_XdndActionDescription);
 12623 
 12624       XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 12625                        FRAME_DISPLAY_INFO (f)->Xatom_XdndActionList, XA_ATOM, 32,
 12626                        PropModeReplace, (unsigned char *) ask_action_list,
 12627                        n_ask_actions);
 12628       x_check_errors (FRAME_X_DISPLAY (f),
 12629                       "Can't set action descriptions: %s");
 12630       x_uncatch_errors_after_check ();
 12631       unblock_input ();
 12632 
 12633       unbind_to (count, Qnil);
 12634     }
 12635 
 12636   record_unwind_protect_void (x_clear_dnd_variables);
 12637 
 12638   if (follow_tooltip)
 12639     {
 12640 #if defined HAVE_XRANDR || defined USE_GTK
 12641       x_dnd_monitors
 12642         = FRAME_DISPLAY_INFO (f)->last_monitor_attributes_list;
 12643 
 12644       if (NILP (x_dnd_monitors))
 12645 #endif
 12646         x_dnd_monitors
 12647           = Fx_display_monitor_attributes_list (frame);
 12648     }
 12649 
 12650   x_dnd_update_tooltip = follow_tooltip;
 12651 
 12652   /* This shouldn't happen.  */
 12653   if (x_dnd_toplevels)
 12654     x_dnd_free_toplevels (true);
 12655 
 12656 #ifdef USE_GTK
 12657   /* Prevent GTK+ timeouts from being run, since they can call
 12658      handle_one_xevent behind our back.  */
 12659   suppress_xg_select ();
 12660   record_unwind_protect_void (release_xg_select);
 12661 #endif
 12662 
 12663   /* Set up a meaningless alias.  */
 12664   XSETCAR (x_dnd_selection_alias_cell, QSECONDARY);
 12665   XSETCDR (x_dnd_selection_alias_cell, QSECONDARY);
 12666 
 12667   /* Bind this here.  The cell doesn't actually alias between
 12668      anything until `xm_setup_dnd_targets' is called.  */
 12669   specbind (Qx_selection_alias_alist,
 12670             Fcons (x_dnd_selection_alias_cell,
 12671                    Vx_selection_alias_alist));
 12672 
 12673   /* Initialize most of the state for the drag-and-drop operation.  */
 12674   x_dnd_in_progress = true;
 12675   x_dnd_recursion_depth = command_loop_level + minibuf_level;
 12676   x_dnd_frame = f;
 12677   x_dnd_last_seen_window = None;
 12678   x_dnd_last_seen_toplevel = None;
 12679   x_dnd_last_protocol_version = -1;
 12680   x_dnd_last_window_is_frame = false;
 12681   x_dnd_last_motif_style = XM_DRAG_STYLE_NONE;
 12682   x_dnd_mouse_rect_target = None;
 12683   x_dnd_action = None;
 12684   x_dnd_action_symbol = Qnil;
 12685   x_dnd_wanted_action = xaction;
 12686   x_dnd_return_frame = 0;
 12687   x_dnd_waiting_for_finish = false;
 12688   x_dnd_waiting_for_motif_finish = 0;
 12689   x_dnd_waiting_for_status_window = None;
 12690   x_dnd_pending_send_position.type = 0;
 12691   x_dnd_xm_use_help = false;
 12692   x_dnd_motif_setup_p = false;
 12693   x_dnd_end_window = None;
 12694   x_dnd_run_unsupported_drop_function = false;
 12695   x_dnd_use_toplevels
 12696     = x_wm_supports (f, FRAME_DISPLAY_INFO (f)->Xatom_net_client_list_stacking);
 12697   x_dnd_last_tooltip_valid = false;
 12698   x_dnd_toplevels = NULL;
 12699   x_dnd_allow_current_frame = allow_current_frame;
 12700   x_dnd_movement_frame = NULL;
 12701   x_dnd_wheel_frame = NULL;
 12702   x_dnd_init_type_lists = false;
 12703   x_dnd_need_send_drop = false;
 12704 
 12705 #ifdef HAVE_XINPUT2
 12706 
 12707   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
 12708     {
 12709       /* Only accept input from the last master pointer to have interacted
 12710          with Emacs.  This prevents another pointer device getting our
 12711          idea of the button state messed up.  */
 12712       if (FRAME_DISPLAY_INFO (f)->client_pointer_device != -1)
 12713         x_dnd_pointer_device
 12714           = FRAME_DISPLAY_INFO (f)->client_pointer_device;
 12715       else
 12716         /* This returns Bool but cannot actually fail.  */
 12717         XIGetClientPointer (FRAME_X_DISPLAY (f), None,
 12718                             &x_dnd_pointer_device);
 12719 
 12720       x_dnd_keyboard_device = -1;
 12721 
 12722       device = xi_device_from_id (FRAME_DISPLAY_INFO (f),
 12723                                   x_dnd_pointer_device);
 12724 
 12725       if (device)
 12726         x_dnd_keyboard_device = device->attachment;
 12727     }
 12728   else
 12729     {
 12730       x_dnd_pointer_device = -1;
 12731       x_dnd_keyboard_device = -1;
 12732     }
 12733 
 12734 #endif
 12735 
 12736 #ifdef HAVE_XKB
 12737   x_dnd_keyboard_state = 0;
 12738 
 12739   if (FRAME_DISPLAY_INFO (f)->supports_xkb)
 12740     {
 12741       XkbSelectEvents (FRAME_X_DISPLAY (f), XkbUseCoreKbd,
 12742                        XkbStateNotifyMask, XkbStateNotifyMask);
 12743       XkbGetState (FRAME_X_DISPLAY (f), XkbUseCoreKbd,
 12744                    &keyboard_state);
 12745 
 12746       x_dnd_keyboard_state = (keyboard_state.mods
 12747                               | keyboard_state.ptr_buttons);
 12748     }
 12749 #endif
 12750 
 12751   if (x_dnd_use_toplevels)
 12752     {
 12753       if (x_dnd_compute_toplevels (FRAME_DISPLAY_INFO (f)))
 12754         {
 12755           x_dnd_free_toplevels (true);
 12756           x_dnd_use_toplevels = false;
 12757         }
 12758       else
 12759         record_unwind_protect_void (x_free_dnd_toplevels);
 12760     }
 12761 
 12762   if (!NILP (return_frame))
 12763     x_dnd_return_frame = 1;
 12764 
 12765   if (EQ (return_frame, Qnow))
 12766     x_dnd_return_frame = 2;
 12767 
 12768   /* Now select for SubstructureNotifyMask and PropertyChangeMask on
 12769      the root window, so we can get notified when window stacking
 12770      changes, a common operation during drag-and-drop.  */
 12771 
 12772   XGetWindowAttributes (FRAME_X_DISPLAY (f),
 12773                         FRAME_DISPLAY_INFO (f)->root_window,
 12774                         &root_window_attrs);
 12775 
 12776   additional_mask = SubstructureNotifyMask;
 12777 
 12778   if (x_dnd_use_toplevels)
 12779     additional_mask |= PropertyChangeMask;
 12780 
 12781   XSelectInput (FRAME_X_DISPLAY (f),
 12782                 FRAME_DISPLAY_INFO (f)->root_window,
 12783                 root_window_attrs.your_event_mask
 12784                 | additional_mask);
 12785 
 12786   if (EQ (return_frame, Qnow))
 12787     x_dnd_update_state (FRAME_DISPLAY_INFO (f), CurrentTime);
 12788 
 12789   while (x_dnd_in_progress || x_dnd_waiting_for_finish)
 12790     {
 12791       EVENT_INIT (hold_quit);
 12792 
 12793 #ifdef USE_GTK
 12794       current_finish = X_EVENT_NORMAL;
 12795       current_hold_quit = &hold_quit;
 12796       current_count = 0;
 12797       xg_pending_quit_event.kind = NO_EVENT;
 12798 #endif
 12799 
 12800       block_input ();
 12801       x_dnd_inside_handle_one_xevent = true;
 12802 #ifdef USE_GTK
 12803       gtk_main_iteration ();
 12804 #elif defined USE_X_TOOLKIT
 12805       XtAppNextEvent (Xt_app_con, &next_event);
 12806 #else
 12807       x_next_event_from_any_display (&next_event);
 12808 #endif
 12809 
 12810 #ifndef USE_GTK
 12811       event_display
 12812         = x_display_info_for_display (next_event.xany.display);
 12813 
 12814       if (event_display)
 12815         {
 12816 #ifdef HAVE_X_I18N
 12817 #ifdef HAVE_XINPUT2
 12818           if (next_event.type != GenericEvent
 12819               || !event_display->supports_xi2
 12820               || (next_event.xgeneric.extension
 12821                   != event_display->xi2_opcode))
 12822             {
 12823 #endif
 12824               if (!x_filter_event (event_display, &next_event))
 12825                 handle_one_xevent (event_display,
 12826                                    &next_event, &finish, &hold_quit);
 12827 #ifdef HAVE_XINPUT2
 12828             }
 12829           else
 12830             handle_one_xevent (event_display,
 12831                                &next_event, &finish, &hold_quit);
 12832 #endif
 12833 #else
 12834           handle_one_xevent (event_display,
 12835                              &next_event, &finish, &hold_quit);
 12836 #endif
 12837         }
 12838 #else
 12839       /* Clear these before the read_socket_hook can be called.  */
 12840       current_count = -1;
 12841       current_hold_quit = NULL;
 12842 #endif
 12843       x_dnd_inside_handle_one_xevent = false;
 12844 
 12845       /* Clean up any event handlers that are now out of date.  */
 12846       x_clean_failable_requests (FRAME_DISPLAY_INFO (f));
 12847 
 12848       /* The unblock_input below might try to read input, but
 12849          XTread_socket does nothing inside a drag-and-drop event
 12850          loop, so don't let it clear the pending_signals flag.  */
 12851       signals_were_pending = pending_signals;
 12852       unblock_input ();
 12853       pending_signals = signals_were_pending;
 12854 
 12855       /* Ignore mouse movement from displays that aren't the DND
 12856          display.  */
 12857 #ifndef USE_GTK
 12858       if (event_display == FRAME_DISPLAY_INFO (f))
 12859         {
 12860 #endif
 12861           if (x_dnd_movement_frame
 12862               /* FIXME: how come this can end up with movement frames
 12863                  from other displays on GTK builds?  */
 12864               && (FRAME_X_DISPLAY (x_dnd_movement_frame)
 12865                   == FRAME_X_DISPLAY (f))
 12866               /* If both those variables are false, then F is no
 12867                  longer protected from deletion by Lisp code.  This
 12868                  can only happen during the final iteration of the DND
 12869                  event loop.  */
 12870               && (x_dnd_in_progress || x_dnd_waiting_for_finish))
 12871             {
 12872               XSETFRAME (frame_object, x_dnd_movement_frame);
 12873               XSETINT (x, x_dnd_movement_x);
 12874               XSETINT (y, x_dnd_movement_y);
 12875               x_dnd_movement_frame = NULL;
 12876 
 12877               if (!NILP (Vx_dnd_movement_function)
 12878                   && FRAME_LIVE_P (XFRAME (frame_object))
 12879                   && !FRAME_TOOLTIP_P (XFRAME (frame_object))
 12880                   && x_dnd_movement_x >= 0
 12881                   && x_dnd_movement_y >= 0
 12882                   && x_dnd_frame
 12883                   && (XFRAME (frame_object) != x_dnd_frame
 12884                       || x_dnd_allow_current_frame))
 12885                 {
 12886                   x_dnd_old_window_attrs = root_window_attrs;
 12887                   x_dnd_unwind_flag = true;
 12888 
 12889                   ref = SPECPDL_INDEX ();
 12890                   record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
 12891                   call2 (Vx_dnd_movement_function, frame_object,
 12892                          Fposn_at_x_y (x, y, frame_object, Qnil));
 12893                   x_dnd_unwind_flag = false;
 12894                   unbind_to (ref, Qnil);
 12895 
 12896                   /* Redisplay this way to preserve the echo area.
 12897                      Otherwise, the contents will abruptly disappear
 12898                      when the mouse moves over a frame.  */
 12899                   redisplay_preserve_echo_area (33);
 12900                 }
 12901             }
 12902 
 12903           if (x_dnd_wheel_frame
 12904               && (x_dnd_in_progress || x_dnd_waiting_for_finish))
 12905             {
 12906               XSETFRAME (frame_object, x_dnd_wheel_frame);
 12907               XSETINT (x, x_dnd_wheel_x);
 12908               XSETINT (y, x_dnd_wheel_y);
 12909               x_dnd_wheel_frame = NULL;
 12910 
 12911               if (!NILP (Vx_dnd_wheel_function)
 12912                   && FRAME_LIVE_P (XFRAME (frame_object))
 12913                   && !FRAME_TOOLTIP_P (XFRAME (frame_object))
 12914                   && x_dnd_movement_x >= 0
 12915                   && x_dnd_movement_y >= 0
 12916                   && x_dnd_frame
 12917                   && (XFRAME (frame_object) != x_dnd_frame
 12918                       || x_dnd_allow_current_frame))
 12919                 {
 12920                   x_dnd_old_window_attrs = root_window_attrs;
 12921                   x_dnd_unwind_flag = true;
 12922 
 12923                   ref = SPECPDL_INDEX ();
 12924                   record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
 12925                   call4 (Vx_dnd_wheel_function,
 12926                          Fposn_at_x_y (x, y, frame_object, Qnil),
 12927                          make_fixnum (x_dnd_wheel_button),
 12928                          make_uint (x_dnd_wheel_state),
 12929                          make_uint (x_dnd_wheel_time));
 12930                   x_dnd_unwind_flag = false;
 12931                   unbind_to (ref, Qnil);
 12932 
 12933                   /* Redisplay this way to preserve the echo area.
 12934                      Otherwise, the contents will abruptly disappear
 12935                      when the mouse moves over a frame.  */
 12936                   redisplay_preserve_echo_area (33);
 12937                 }
 12938             }
 12939 
 12940           if (hold_quit.kind != NO_EVENT)
 12941             {
 12942               x_dnd_process_quit (f, hold_quit.timestamp);
 12943 #ifdef USE_GTK
 12944               current_hold_quit = NULL;
 12945 #endif
 12946               /* Restore the old event mask.  */
 12947               x_restore_events_after_dnd (f, &root_window_attrs);
 12948 
 12949               /* Call kbd_buffer_store event, which calls
 12950                  handle_interrupt and sets `last-event-frame' along
 12951                  with various other things.  */
 12952               kbd_buffer_store_event (&hold_quit);
 12953               /* Now quit anyway.  */
 12954               quit ();
 12955             }
 12956 
 12957           if (pending_selection_requests
 12958               && (x_dnd_in_progress || x_dnd_waiting_for_finish))
 12959             {
 12960               x_dnd_old_window_attrs = root_window_attrs;
 12961               x_dnd_unwind_flag = true;
 12962 
 12963               ref = SPECPDL_INDEX ();
 12964               record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
 12965               x_handle_pending_selection_requests ();
 12966               x_dnd_unwind_flag = false;
 12967               unbind_to (ref, Qnil);
 12968             }
 12969 
 12970           /* Sometimes C-g can be pressed inside a selection
 12971              converter, where quitting is inhibited.  We want
 12972              to quit after the converter exits.  */
 12973           if (!NILP (Vquit_flag) && !NILP (Vinhibit_quit))
 12974             {
 12975               x_dnd_process_quit (f, FRAME_DISPLAY_INFO (f)->last_user_time);
 12976 #ifdef USE_GTK
 12977               current_hold_quit = NULL;
 12978 #endif
 12979               x_restore_events_after_dnd (f, &root_window_attrs);
 12980               quit ();
 12981             }
 12982 
 12983           if (x_dnd_run_unsupported_drop_function
 12984               && x_dnd_waiting_for_finish)
 12985             {
 12986               x_dnd_run_unsupported_drop_function = false;
 12987               x_dnd_waiting_for_finish = false;
 12988               x_dnd_unwind_flag = true;
 12989 
 12990               ref = SPECPDL_INDEX ();
 12991               record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f);
 12992 
 12993               if (!NILP (Vx_dnd_unsupported_drop_function))
 12994                 val = call8 (Vx_dnd_unsupported_drop_function,
 12995                              XCAR (XCDR (x_dnd_unsupported_drop_data)),
 12996                              Fnth (make_fixnum (3), x_dnd_unsupported_drop_data),
 12997                              Fnth (make_fixnum (4), x_dnd_unsupported_drop_data),
 12998                              Fnth (make_fixnum (2), x_dnd_unsupported_drop_data),
 12999                              make_uint (x_dnd_unsupported_drop_window),
 13000                              frame, make_uint (x_dnd_unsupported_drop_time),
 13001                              Fcopy_sequence (XCAR (x_dnd_unsupported_drop_data)));
 13002               else
 13003                 val = Qnil;
 13004 
 13005               if (NILP (val))
 13006                 x_dnd_do_unsupported_drop (FRAME_DISPLAY_INFO (f),
 13007                                            frame, XCAR (x_dnd_unsupported_drop_data),
 13008                                            XCAR (XCDR (x_dnd_unsupported_drop_data)),
 13009                                            x_dnd_unsupported_drop_window,
 13010                                            XFIXNUM (Fnth (make_fixnum (3),
 13011                                                           x_dnd_unsupported_drop_data)),
 13012                                            XFIXNUM (Fnth (make_fixnum (4),
 13013                                                           x_dnd_unsupported_drop_data)),
 13014                                            x_dnd_unsupported_drop_time);
 13015               else if (SYMBOLP (val))
 13016                 x_dnd_action_symbol = val;
 13017 
 13018               x_dnd_unwind_flag = false;
 13019               unbind_to (ref, Qnil);
 13020 
 13021               /* Break out of the loop now, since DND has
 13022                  completed.  */
 13023               break;
 13024             }
 13025 
 13026 #ifdef USE_GTK
 13027           if (xg_pending_quit_event.kind != NO_EVENT)
 13028             {
 13029               xg_pending_quit_event.kind = NO_EVENT;
 13030               current_hold_quit = NULL;
 13031 
 13032               x_dnd_process_quit (f, FRAME_DISPLAY_INFO (f)->last_user_time);
 13033               x_restore_events_after_dnd (f, &root_window_attrs);
 13034               quit ();
 13035             }
 13036 #else
 13037         }
 13038       else
 13039         {
 13040           if (x_dnd_movement_frame)
 13041             x_dnd_movement_frame = NULL;
 13042 
 13043           if (x_dnd_wheel_frame)
 13044             x_dnd_wheel_frame = NULL;
 13045 
 13046           if (hold_quit.kind != NO_EVENT)
 13047             EVENT_INIT (hold_quit);
 13048         }
 13049 #endif
 13050     }
 13051 
 13052   x_dnd_waiting_for_finish = false;
 13053 
 13054 #ifdef USE_GTK
 13055   current_hold_quit = NULL;
 13056 #endif
 13057   x_dnd_movement_frame = NULL;
 13058   x_dnd_wheel_frame = NULL;
 13059   x_restore_events_after_dnd (f, &root_window_attrs);
 13060 
 13061   if (x_dnd_return_frame == 3
 13062       && FRAME_LIVE_P (x_dnd_return_frame_object))
 13063     {
 13064       /* Deliberately preserve the last device if
 13065          x_dnd_return_frame_object is the drag source.  */
 13066 
 13067       if (x_dnd_return_frame_object != x_dnd_frame)
 13068         x_dnd_return_frame_object->last_mouse_device = Qnil;
 13069 
 13070       x_dnd_return_frame_object->mouse_moved = true;
 13071 
 13072       XSETFRAME (action, x_dnd_return_frame_object);
 13073       x_dnd_return_frame_object = NULL;
 13074 
 13075       return unbind_to (base, action);
 13076     }
 13077 
 13078   x_dnd_return_frame_object = NULL;
 13079   FRAME_DISPLAY_INFO (f)->grabbed = 0;
 13080 
 13081   if (!NILP (x_dnd_action_symbol))
 13082     return unbind_to (base, x_dnd_action_symbol);
 13083 
 13084   if (x_dnd_action != None)
 13085     {
 13086       block_input ();
 13087       x_catch_errors (FRAME_X_DISPLAY (f));
 13088       atom_name = x_get_atom_name (FRAME_DISPLAY_INFO (f),
 13089                                    x_dnd_action, &need_sync);
 13090 
 13091       if (need_sync)
 13092         x_uncatch_errors ();
 13093       else
 13094         /* No protocol request actually happened, so avoid the extra
 13095            sync by calling x_uncatch_errors_after_check instead.  */
 13096         x_uncatch_errors_after_check ();
 13097 
 13098       if (atom_name)
 13099         {
 13100           action = intern (atom_name);
 13101           xfree (atom_name);
 13102         }
 13103       else
 13104         action = Qnil;
 13105       unblock_input ();
 13106 
 13107       return unbind_to (base, action);
 13108     }
 13109 
 13110   return unbind_to (base, Qnil);
 13111 }
 13112 
 13113 #ifdef HAVE_XINPUT2
 13114 
 13115 /* Since the input extension assigns a keyboard focus to each master
 13116    device, there is no longer a 1:1 correspondence between the
 13117    selected frame and the focus frame immediately after the keyboard
 13118    focus is switched to a given frame.  This situation is handled by
 13119    keeping track of each master device's focus frame, the time of the
 13120    last interaction with that frame, and always keeping the focus on
 13121    the most recently selected frame.  We also use the pointer of the
 13122    device that is keeping the current frame focused in functions like
 13123    `mouse-position'.  */
 13124 
 13125 static void
 13126 xi_handle_focus_change (struct x_display_info *dpyinfo)
 13127 {
 13128   struct input_event ie;
 13129   struct frame *focus, *new;
 13130   struct xi_device_t *device, *source = NULL;
 13131   ptrdiff_t i;
 13132   Time time;
 13133 #ifdef USE_GTK
 13134   struct x_output *output;
 13135   GtkWidget *widget;
 13136 #endif
 13137 
 13138   focus = dpyinfo->x_focus_frame;
 13139   new = NULL;
 13140   time = 0;
 13141 
 13142   dpyinfo->client_pointer_device = -1;
 13143 
 13144   for (i = 0; i < dpyinfo->num_devices; ++i)
 13145     {
 13146       device = &dpyinfo->devices[i];
 13147 
 13148       if (device->focus_frame
 13149           && device->focus_frame_time > time)
 13150         {
 13151           new = device->focus_frame;
 13152           time = device->focus_frame_time;
 13153           source = device;
 13154 
 13155           /* Use this device for future calls to `mouse-position' etc.
 13156              If it is a keyboard, use its attached pointer.  */
 13157 
 13158           if (device->use == XIMasterKeyboard)
 13159             dpyinfo->client_pointer_device = device->attachment;
 13160           else
 13161             dpyinfo->client_pointer_device = device->device_id;
 13162         }
 13163       /* Even if the implicit focus was set after the explicit focus
 13164          on this specific device, the explicit focus is what really
 13165          matters.  So use it instead.  */
 13166       else if (device->focus_implicit_frame
 13167                && device->focus_implicit_time > time)
 13168         {
 13169           new = device->focus_implicit_frame;
 13170           time = device->focus_implicit_time;
 13171           source = device;
 13172 
 13173           /* Use this device for future calls to `mouse-position' etc.
 13174              If it is a keyboard, use its attached pointer.  */
 13175 
 13176           if (device->use == XIMasterKeyboard)
 13177             dpyinfo->client_pointer_device = device->attachment;
 13178           else
 13179             dpyinfo->client_pointer_device = device->device_id;
 13180         }
 13181     }
 13182 
 13183   if (new != focus && focus)
 13184     {
 13185 #ifdef HAVE_X_I18N
 13186       if (FRAME_XIC (focus))
 13187         XUnsetICFocus (FRAME_XIC (focus));
 13188 #endif
 13189 
 13190 #ifdef USE_GTK
 13191       output = FRAME_X_OUTPUT (focus);
 13192 
 13193       if (x_gtk_use_native_input)
 13194         {
 13195           gtk_im_context_focus_out (output->im_context);
 13196           gtk_im_context_set_client_window (output->im_context,
 13197                                             NULL);
 13198         }
 13199 #endif
 13200 
 13201       EVENT_INIT (ie);
 13202       ie.kind = FOCUS_OUT_EVENT;
 13203       XSETFRAME (ie.frame_or_window, focus);
 13204 
 13205       kbd_buffer_store_event (&ie);
 13206     }
 13207 
 13208   if (new != focus && new)
 13209     {
 13210 #ifdef HAVE_X_I18N
 13211       if (FRAME_XIC (new))
 13212         XSetICFocus (FRAME_XIC (new));
 13213 #endif
 13214 
 13215 #ifdef USE_GTK
 13216       output = FRAME_X_OUTPUT (new);
 13217 
 13218       if (x_gtk_use_native_input)
 13219         {
 13220           widget = FRAME_GTK_OUTER_WIDGET (new);
 13221 
 13222           gtk_im_context_focus_in (output->im_context);
 13223           gtk_im_context_set_client_window (output->im_context,
 13224                                             gtk_widget_get_window (widget));
 13225         }
 13226 #endif
 13227 
 13228       EVENT_INIT (ie);
 13229       ie.kind = FOCUS_IN_EVENT;
 13230       ie.device = source->name;
 13231       XSETFRAME (ie.frame_or_window, new);
 13232 
 13233       kbd_buffer_store_event (&ie);
 13234     }
 13235 
 13236   x_new_focus_frame (dpyinfo, new);
 13237 }
 13238 
 13239 static void
 13240 xi_focus_handle_for_device (struct x_display_info *dpyinfo,
 13241                             struct frame *mentioned_frame,
 13242                             XIEvent *base_event)
 13243 {
 13244   struct xi_device_t *device;
 13245   XIEnterEvent *event;
 13246 
 13247   /* XILeaveEvent, XIFocusInEvent, etc are just synonyms for
 13248      XIEnterEvent.  */
 13249   event = (XIEnterEvent *) base_event;
 13250   device = xi_device_from_id (dpyinfo, event->deviceid);
 13251 
 13252   if (!device)
 13253     return;
 13254 
 13255   switch (event->evtype)
 13256     {
 13257     case XI_FocusIn:
 13258       /* The last-focus-change time of the device changed, so update the
 13259          frame's user time.  */
 13260       x_display_set_last_user_time (dpyinfo, event->time,
 13261                                     event->send_event, true);
 13262 
 13263       device->focus_frame = mentioned_frame;
 13264       device->focus_frame_time = event->time;
 13265       break;
 13266 
 13267     case XI_FocusOut:
 13268       /* The last-focus-change time of the device changed, so update the
 13269          frame's user time.  */
 13270       x_display_set_last_user_time (dpyinfo, event->time,
 13271                                     event->send_event, false);
 13272 
 13273       device->focus_frame = NULL;
 13274 
 13275       /* So, unfortunately, the X Input Extension is implemented such
 13276          that means XI_Leave events will not have their focus field
 13277          set if the core focus is transferred to another window after
 13278          an entry event that pretends to (or really does) set the
 13279          implicit focus.  In addition, if the core focus is set, but
 13280          the extension focus on the client pointer is not, all
 13281          XI_Enter events will have their focus fields set, despite not
 13282          actually changing the effective focus window.  Combined with
 13283          almost all window managers not setting the focus on input
 13284          extension devices, this means that Emacs will continue to
 13285          think the implicit focus is set on one of its frames if the
 13286          actual (core) focus is transferred to another window while
 13287          the pointer remains inside a frame.  The only workaround in
 13288          this case is to clear the implicit focus along with
 13289          XI_FocusOut events, which is not correct at all, but better
 13290          than leaving frames in an incorrectly-focused state.
 13291          (bug#57468) */
 13292       device->focus_implicit_frame = NULL;
 13293       break;
 13294 
 13295     case XI_Enter:
 13296       if (!event->focus)
 13297         break;
 13298 
 13299       if (device->use == XIMasterPointer)
 13300         device = xi_device_from_id (dpyinfo, device->attachment);
 13301 
 13302       if (!device)
 13303         break;
 13304 
 13305       device->focus_implicit_frame = mentioned_frame;
 13306       device->focus_implicit_time = event->time;
 13307       break;
 13308 
 13309     case XI_Leave:
 13310       if (!event->focus)
 13311         break;
 13312 
 13313       if (device->use == XIMasterPointer)
 13314         device = xi_device_from_id (dpyinfo, device->attachment);
 13315 
 13316       if (!device)
 13317         break;
 13318 
 13319       device->focus_implicit_frame = NULL;
 13320       break;
 13321     }
 13322 
 13323   xi_handle_focus_change (dpyinfo);
 13324 }
 13325 
 13326 static void
 13327 xi_handle_delete_frame (struct x_display_info *dpyinfo,
 13328                         struct frame *f)
 13329 {
 13330   struct xi_device_t *device;
 13331   ptrdiff_t i;
 13332 
 13333   for (i = 0; i < dpyinfo->num_devices; ++i)
 13334     {
 13335       device = &dpyinfo->devices[i];
 13336 
 13337       if (device->focus_frame == f)
 13338         device->focus_frame = NULL;
 13339 
 13340       if (device->focus_implicit_frame == f)
 13341         device->focus_implicit_frame = NULL;
 13342     }
 13343 }
 13344 
 13345 /* Handle an interaction by DEVICE on frame F.  TIME is the time of
 13346    the interaction; if F isn't currently the global focus frame, but
 13347    is the focus of DEVICE, make it the focus frame.  */
 13348 
 13349 static void
 13350 xi_handle_interaction (struct x_display_info *dpyinfo,
 13351                        struct frame *f, struct xi_device_t *device,
 13352                        Time time)
 13353 {
 13354   bool change;
 13355 
 13356   /* If DEVICE is a pointer, use its attached keyboard device.  */
 13357   if (device->use == XIMasterPointer)
 13358     device = xi_device_from_id (dpyinfo, device->attachment);
 13359 
 13360   if (!device)
 13361     return;
 13362 
 13363   change = false;
 13364 
 13365   if (device->focus_frame == f)
 13366     {
 13367       device->focus_frame_time = time;
 13368       change = true;
 13369     }
 13370 
 13371   if (device->focus_implicit_frame == f)
 13372     {
 13373       device->focus_implicit_time = time;
 13374       change = true;
 13375     }
 13376 
 13377   /* If F isn't currently focused, update the focus state.  */
 13378   if (change && f != dpyinfo->x_focus_frame)
 13379     xi_handle_focus_change (dpyinfo);
 13380 }
 13381 
 13382 /* Return whether or not XEV actually represents a change in the
 13383    position of the pointer on DEVICE, with respect to the last event
 13384    received.  This is necessary because the input extension reports
 13385    motion events in very high resolution, while Emacs is only fast
 13386    enough to process motion events aligned to the pixel grid.  */
 13387 
 13388 static bool
 13389 xi_position_changed (struct xi_device_t *device, XIDeviceEvent *xev)
 13390 {
 13391   bool changed;
 13392 
 13393   changed = true;
 13394 
 13395   if (xev->event != device->last_motion_window)
 13396     goto out;
 13397 
 13398   if (lrint (xev->event_x) == device->last_motion_x
 13399       && lrint (xev->event_y) == device->last_motion_y)
 13400     {
 13401       changed = false;
 13402       goto out;
 13403     }
 13404 
 13405  out:
 13406   device->last_motion_x = lrint (xev->event_x);
 13407   device->last_motion_y = lrint (xev->event_y);
 13408   device->last_motion_window = xev->event;
 13409 
 13410   return changed;
 13411 }
 13412 
 13413 static void
 13414 xi_report_motion_window_clear (struct xi_device_t *device)
 13415 {
 13416   device->last_motion_window = None;
 13417 }
 13418 
 13419 #ifdef HAVE_XINPUT2_1
 13420 
 13421 /* Look up a scroll valuator in DEVICE by NUMBER.  */
 13422 
 13423 static struct xi_scroll_valuator_t *
 13424 xi_get_scroll_valuator (struct xi_device_t *device, int number)
 13425 {
 13426   int i;
 13427 
 13428   for (i = 0; i < device->scroll_valuator_count; ++i)
 13429     {
 13430       if (device->valuators[i].number == number)
 13431         return &device->valuators[i];
 13432     }
 13433 
 13434   return NULL;
 13435 }
 13436 
 13437 /* Check if EVENT, a DeviceChanged event, contains any scroll
 13438    valuators.  */
 13439 
 13440 static bool
 13441 xi_has_scroll_valuators (XIDeviceChangedEvent *event)
 13442 {
 13443   int i;
 13444 
 13445   for (i = 0; i < event->num_classes; ++i)
 13446     {
 13447       if (event->classes[i]->type == XIScrollClass)
 13448         return true;
 13449     }
 13450 
 13451   return false;
 13452 }
 13453 
 13454 /* Repopulate the information (touchpoint tracking information, scroll
 13455    valuators, etc) in DEVICE with the device classes provided in
 13456    CLASSES.  This is called upon receiving a DeviceChanged event.
 13457 
 13458    This function is not present on XI 2.0 as there are no worthwhile
 13459    classes there.  */
 13460 
 13461 static void
 13462 xi_handle_new_classes (struct x_display_info *dpyinfo, struct xi_device_t *device,
 13463                        XIAnyClassInfo **classes, int num_classes)
 13464 {
 13465   XIScrollClassInfo *scroll;
 13466   struct xi_scroll_valuator_t *valuator;
 13467   XIValuatorClassInfo *valuator_info;
 13468   int i;
 13469 #ifdef HAVE_XINPUT2_2
 13470   XITouchClassInfo *touch;
 13471 #endif
 13472 
 13473   if (dpyinfo->xi2_version < 1)
 13474     /* Emacs is connected to an XI 2.0 server, which reports no
 13475        classes of interest.  */
 13476     return;
 13477 
 13478   device->valuators = xnmalloc (num_classes,
 13479                                 sizeof *device->valuators);
 13480   device->scroll_valuator_count = 0;
 13481 #ifdef HAVE_XINPUT2_2
 13482   device->direct_p = false;
 13483 #endif /* HAVE_XINPUT2_2 */
 13484 
 13485   for (i = 0; i < num_classes; ++i)
 13486     {
 13487       switch (classes[i]->type)
 13488         {
 13489         case XIScrollClass:
 13490           scroll = (XIScrollClassInfo *) classes[i];
 13491 
 13492           xi_populate_scroll_valuator (device,
 13493                                        device->scroll_valuator_count++,
 13494                                        scroll);
 13495           break;
 13496 
 13497 #ifdef HAVE_XINPUT2_2
 13498         case XITouchClass:
 13499           touch = (XITouchClassInfo *) classes[i];
 13500 
 13501           /* touch_info->mode indicates the coordinate space that this
 13502              device reports in its touch events.
 13503 
 13504              DirectTouch means that the device uses a coordinate space
 13505              that corresponds to locations on the screen.  It is set
 13506              by touch screen devices which are overlaid over the
 13507              raster itself.
 13508 
 13509              The other value (DependentTouch) means that the device
 13510              uses a separate abstract coordinate space corresponding
 13511              to its own surface.  Emacs ignores events from these
 13512              devices because it does not support recognizing touch
 13513              gestures from surfaces other than the screen.
 13514 
 13515              Master devices may report multiple touch classes for
 13516              attached slave devices, leaving the nature of touch
 13517              events they send ambiguous.  The problem of
 13518              discriminating between these events is bypassed entirely
 13519              through only processing touch events from the slave
 13520              devices where they originate.  */
 13521 
 13522           if (touch->mode == XIDirectTouch)
 13523             device->direct_p = true;
 13524           else
 13525             device->direct_p = false;
 13526 
 13527           break;
 13528 #endif /* HAVE_XINPUT2_2 */
 13529         }
 13530     }
 13531 
 13532   /* Restore the values of any scroll valuators that we already
 13533      know about.  */
 13534 
 13535   for (i = 0; i < num_classes; ++i)
 13536     {
 13537       if (classes[i]->type != XIValuatorClass)
 13538         continue;
 13539 
 13540       valuator_info = (XIValuatorClassInfo *) classes[i];
 13541 
 13542       /* Avoid restoring bogus values if some driver accidentally
 13543          specifies relative values in scroll valuator classes how the
 13544          input extension spec says they should be, but allow restoring
 13545          values when a value is set, which is how the input extension
 13546          actually behaves.  */
 13547 
 13548       if (valuator_info->value == 0.0
 13549           && valuator_info->mode != XIModeAbsolute)
 13550         continue;
 13551 
 13552       valuator = xi_get_scroll_valuator (device,
 13553                                          valuator_info->number);
 13554 
 13555       if (!valuator)
 13556         continue;
 13557 
 13558       valuator->invalid_p = false;
 13559       valuator->current_value = valuator_info->value;
 13560       valuator->emacs_value = 0;
 13561 
 13562       break;
 13563     }
 13564 }
 13565 
 13566 #endif /* HAVE_XINPUT2_1 */
 13567 
 13568 /* Handle EVENT, a DeviceChanged event.  Look up the device that
 13569    changed, and update its information with the data in EVENT.  */
 13570 
 13571 static void
 13572 xi_handle_device_changed (struct x_display_info *dpyinfo,
 13573                           struct xi_device_t *device,
 13574                           XIDeviceChangedEvent *event)
 13575 {
 13576 #ifdef HAVE_XINPUT2_1
 13577   int ndevices;
 13578   XIDeviceInfo *info;
 13579 #endif
 13580 #ifdef HAVE_XINPUT2_2
 13581   struct xi_touch_point_t *tem, *last;
 13582 #endif
 13583 
 13584 #ifdef HAVE_XINPUT2_1
 13585   if (xi_has_scroll_valuators (event))
 13586     /* Scroll valuators are provided by this event.  Use the values
 13587        provided in this event to populate the device's new scroll
 13588        valuator list: if this event is a SlaveSwitch event caused by
 13589        wheel movement, then querying for the device info will probably
 13590        return the value after the wheel movement, leading to a delta
 13591        of 0 being computed upon handling the subsequent XI_Motion
 13592        event.  (bug#58980) */
 13593     xi_handle_new_classes (dpyinfo, device, event->classes,
 13594                            event->num_classes);
 13595   else
 13596     {
 13597       /* When a DeviceChange event is received for a master device,
 13598          the X server sometimes does not send any scroll valuators
 13599          along with it.  This is possibly an X server bug but I really
 13600          don't want to dig any further, so fetch the scroll valuators
 13601          manually.  (bug#57020) */
 13602 
 13603       x_catch_errors (dpyinfo->display);
 13604       info = XIQueryDevice (dpyinfo->display, event->deviceid,
 13605                             /* ndevices is always 1 if a deviceid is
 13606                                specified.  If the request fails, NULL will
 13607                                be returned.  */
 13608                             &ndevices);
 13609       x_uncatch_errors ();
 13610 
 13611       if (!info)
 13612         return;
 13613 
 13614       /* info contains the classes currently associated with the
 13615          event.  Apply them.  */
 13616       xi_handle_new_classes (dpyinfo, device, info->classes,
 13617                              info->num_classes);
 13618     }
 13619 #endif
 13620 
 13621 #ifdef HAVE_XINPUT2_2
 13622   /* The device is no longer a DirectTouch device, so remove any
 13623      touchpoints that we might have recorded.  */
 13624   if (!device->direct_p)
 13625     {
 13626       tem = device->touchpoints;
 13627 
 13628       while (tem)
 13629         {
 13630           last = tem;
 13631           tem = tem->next;
 13632           xfree (last);
 13633         }
 13634 
 13635       device->touchpoints = NULL;
 13636     }
 13637 #endif
 13638 }
 13639 
 13640 /* Remove the client-side record of every device in TO_DISABLE.
 13641    Called while processing XI_HierarchyChanged events.  We batch up
 13642    multiple disabled devices because it is more efficient to disable
 13643    them at once.  */
 13644 
 13645 static void
 13646 xi_disable_devices (struct x_display_info *dpyinfo,
 13647                     int *to_disable, int n_disabled)
 13648 {
 13649   struct xi_device_t *devices;
 13650   int ndevices, i, j;
 13651 #ifdef HAVE_XINPUT2_2
 13652   struct xi_touch_point_t *tem, *last;
 13653 #endif
 13654 #if defined HAVE_XINPUT2_2 && !defined HAVE_EXT_TOOL_BAR
 13655   struct x_output *output;
 13656   Lisp_Object tail, frame;
 13657 #endif
 13658 
 13659   /* Don't pointlessly copy dpyinfo->devices if there are no devices
 13660      to disable.  */
 13661   if (!n_disabled)
 13662     return;
 13663 
 13664   ndevices = 0;
 13665   devices = xzalloc (sizeof *devices * dpyinfo->num_devices);
 13666 
 13667   /* Loop through every device currently in DPYINFO, and copy it to
 13668      DEVICES if it is not in TO_DISABLE.  Note that this function
 13669      should be called with input blocked, since xfree can otherwise
 13670      call GC, which will call mark_xterm with invalid state.  */
 13671   for (i = 0; i < dpyinfo->num_devices; ++i)
 13672     {
 13673       for (j = 0; j < n_disabled; ++j)
 13674         {
 13675           if (to_disable[j] == dpyinfo->devices[i].device_id)
 13676             {
 13677               if (x_dnd_in_progress
 13678                   /* If the drag-and-drop pointer device is being
 13679                      disabled, then cancel the drag and drop
 13680                      operation.  */
 13681                   && to_disable[j] == x_dnd_pointer_device)
 13682                 x_dnd_cancel_dnd_early ();
 13683 
 13684               /* Free any scroll valuators that might be on this
 13685                  device.  */
 13686 #ifdef HAVE_XINPUT2_1
 13687               xfree (dpyinfo->devices[i].valuators);
 13688 #endif
 13689 
 13690               /* Free any currently active touch points on this
 13691                  device.  */
 13692 #ifdef HAVE_XINPUT2_2
 13693               tem = dpyinfo->devices[i].touchpoints;
 13694               while (tem)
 13695                 {
 13696                   last = tem;
 13697                   tem = tem->next;
 13698                   xfree (last);
 13699                 }
 13700 
 13701 #ifndef HAVE_EXT_TOOL_BAR
 13702 
 13703               /* Now look through each frame on DPYINFO.  If it has an
 13704                  outstanding tool bar press for this device, release
 13705                  the tool bar.  */
 13706 
 13707               FOR_EACH_FRAME (tail, frame)
 13708                 {
 13709                   if (!FRAME_X_P (XFRAME (frame))
 13710                       || (FRAME_DISPLAY_INFO (XFRAME (frame))
 13711                           != dpyinfo))
 13712                     continue;
 13713 
 13714                   output = FRAME_OUTPUT_DATA (XFRAME (frame));
 13715 
 13716                   if (output->tool_bar_touch_device
 13717                       == dpyinfo->devices[i].device_id)
 13718                     {
 13719                       if (XFRAME (frame)->last_tool_bar_item != -1
 13720                           && WINDOWP (XFRAME (frame)->tool_bar_window))
 13721                         handle_tool_bar_click (XFRAME (frame), 0, 0,
 13722                                                false, 0);
 13723 
 13724                       output->tool_bar_touch_device = 0;
 13725                     }
 13726                 }
 13727 #endif
 13728 #endif
 13729 
 13730               goto out;
 13731             }
 13732 
 13733           devices[ndevices++] = dpyinfo->devices[i];
 13734 
 13735         out:
 13736           continue;
 13737         }
 13738     }
 13739 
 13740   /* Free the old devices array and replace it with ndevices.  */
 13741   xfree (dpyinfo->devices);
 13742 
 13743   dpyinfo->devices = devices;
 13744   dpyinfo->num_devices = ndevices;
 13745 }
 13746 
 13747 #endif
 13748 
 13749 /* The focus may have changed.  Figure out if it is a real focus change,
 13750    by checking both FocusIn/Out and Enter/LeaveNotify events.
 13751 
 13752    Returns FOCUS_IN_EVENT event in *BUFP. */
 13753 
 13754 static void
 13755 x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
 13756                        const XEvent *event, struct input_event *bufp)
 13757 {
 13758   if (!frame)
 13759     return;
 13760 
 13761   switch (event->type)
 13762     {
 13763     case EnterNotify:
 13764     case LeaveNotify:
 13765       {
 13766         struct frame *focus_frame = dpyinfo->x_focus_event_frame;
 13767         int focus_state
 13768           = focus_frame ? focus_frame->output_data.x->focus_state : 0;
 13769 
 13770         if (event->xcrossing.detail != NotifyInferior
 13771             && event->xcrossing.focus
 13772             && ! (focus_state & FOCUS_EXPLICIT))
 13773           x_focus_changed ((event->type == EnterNotify ? FocusIn : FocusOut),
 13774                            FOCUS_IMPLICIT,
 13775                            dpyinfo, frame, bufp);
 13776       }
 13777       break;
 13778 
 13779     case FocusIn:
 13780     case FocusOut:
 13781       /* Ignore transient focus events from hotkeys, window manager
 13782          gadgets, and other odd sources.  Some buggy window managers
 13783          (e.g., Muffin 4.2.4) send FocusIn events of this type without
 13784          corresponding FocusOut events even when some other window
 13785          really has focus, and these kinds of focus event don't
 13786          correspond to real user input changes.  GTK+ uses the same
 13787          filtering. */
 13788       if (event->xfocus.mode == NotifyGrab
 13789           || event->xfocus.mode == NotifyUngrab)
 13790         return;
 13791       x_focus_changed (event->type,
 13792                        (event->xfocus.detail == NotifyPointer ?
 13793                         FOCUS_IMPLICIT : FOCUS_EXPLICIT),
 13794                        dpyinfo, frame, bufp);
 13795       break;
 13796 
 13797     case ClientMessage:
 13798       if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
 13799         {
 13800           enum xembed_message msg = event->xclient.data.l[1];
 13801           x_focus_changed ((msg == XEMBED_FOCUS_IN ? FocusIn : FocusOut),
 13802                            FOCUS_EXPLICIT, dpyinfo, frame, bufp);
 13803         }
 13804       break;
 13805     }
 13806 }
 13807 
 13808 
 13809 #if (defined USE_LUCID && defined HAVE_XINPUT2) \
 13810   || (!defined USE_X_TOOLKIT && !defined USE_GTK)
 13811 /* Handle an event saying the mouse has moved out of an Emacs frame.  */
 13812 
 13813 void
 13814 x_mouse_leave (struct x_display_info *dpyinfo)
 13815 {
 13816 #if defined HAVE_XINPUT2 && !defined USE_X_TOOLKIT
 13817   struct xi_device_t *device;
 13818 #endif
 13819   Mouse_HLInfo *hlinfo;
 13820 
 13821   hlinfo = &dpyinfo->mouse_highlight;
 13822 
 13823   if (hlinfo->mouse_face_mouse_frame)
 13824     {
 13825       clear_mouse_face (hlinfo);
 13826       hlinfo->mouse_face_mouse_frame = NULL;
 13827     }
 13828 
 13829 #if defined HAVE_XINPUT2 && !defined USE_X_TOOLKIT
 13830   if (!dpyinfo->supports_xi2)
 13831     /* The call below is supposed to reset the implicit focus and
 13832        revert the focus back to the last explicitly focused frame.  It
 13833        doesn't work on input extension builds because focus tracking
 13834        does not set x_focus_event_frame, and proceeds on a per-device
 13835        basis.  On such builds, clear the implicit focus of the client
 13836        pointer instead.  */
 13837 #endif
 13838     x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame);
 13839 #if defined HAVE_XINPUT2 && !defined USE_X_TOOLKIT
 13840   else
 13841     {
 13842       if (dpyinfo->client_pointer_device == -1)
 13843         /* If there's no client pointer device, then no implicit focus
 13844            is currently set.  */
 13845         return;
 13846 
 13847       device = xi_device_from_id (dpyinfo, dpyinfo->client_pointer_device);
 13848 
 13849       if (device && device->focus_implicit_frame)
 13850         {
 13851           device->focus_implicit_frame = NULL;
 13852 
 13853           /* The focus might have changed; compute the new focus.  */
 13854           xi_handle_focus_change (dpyinfo);
 13855         }
 13856     }
 13857 #endif
 13858 }
 13859 #endif
 13860 
 13861 /* The focus has changed, or we have redirected a frame's focus to
 13862    another frame (this happens when a frame uses a surrogate
 13863    mini-buffer frame).  Shift the highlight as appropriate.
 13864 
 13865    The FRAME argument doesn't necessarily have anything to do with which
 13866    frame is being highlighted or un-highlighted; we only use it to find
 13867    the appropriate X display info.  */
 13868 
 13869 static void
 13870 XTframe_rehighlight (struct frame *frame)
 13871 {
 13872   x_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
 13873 }
 13874 
 13875 static void
 13876 x_frame_rehighlight (struct x_display_info *dpyinfo)
 13877 {
 13878   struct frame *old_highlight = dpyinfo->highlight_frame;
 13879 
 13880   if (dpyinfo->x_focus_frame)
 13881     {
 13882       dpyinfo->highlight_frame
 13883         = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
 13884            ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
 13885            : dpyinfo->x_focus_frame);
 13886       if (! FRAME_LIVE_P (dpyinfo->highlight_frame))
 13887         {
 13888           fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
 13889           dpyinfo->highlight_frame = dpyinfo->x_focus_frame;
 13890         }
 13891     }
 13892   else
 13893     dpyinfo->highlight_frame = 0;
 13894 
 13895   if (dpyinfo->highlight_frame != old_highlight)
 13896     {
 13897       if (old_highlight)
 13898         x_frame_unhighlight (old_highlight);
 13899       if (dpyinfo->highlight_frame)
 13900         x_frame_highlight (dpyinfo->highlight_frame);
 13901     }
 13902 }
 13903 
 13904 
 13905 
 13906 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc.  */
 13907 
 13908 /* Initialize mode_switch_bit and modifier_meaning.  */
 13909 static void
 13910 x_find_modifier_meanings (struct x_display_info *dpyinfo)
 13911 {
 13912   int min_code, max_code;
 13913   KeySym *syms;
 13914   int syms_per_code;
 13915   XModifierKeymap *mods;
 13916 #ifdef HAVE_XKB
 13917   int i;
 13918   int found_meta_p = false;
 13919   unsigned int vmodmask;
 13920 #endif
 13921 
 13922   dpyinfo->meta_mod_mask = 0;
 13923   dpyinfo->shift_lock_mask = 0;
 13924   dpyinfo->alt_mod_mask = 0;
 13925   dpyinfo->super_mod_mask = 0;
 13926   dpyinfo->hyper_mod_mask = 0;
 13927 
 13928 #ifdef HAVE_XKB
 13929   if (dpyinfo->xkb_desc
 13930       && dpyinfo->xkb_desc->server)
 13931     {
 13932       for (i = 0; i < XkbNumVirtualMods; i++)
 13933         {
 13934           vmodmask = dpyinfo->xkb_desc->server->vmods[i];
 13935 
 13936           if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Meta)
 13937             {
 13938               dpyinfo->meta_mod_mask |= vmodmask;
 13939 
 13940               if (vmodmask)
 13941                 found_meta_p = true;
 13942             }
 13943           else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Alt)
 13944             dpyinfo->alt_mod_mask |= vmodmask;
 13945           else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Super)
 13946             dpyinfo->super_mod_mask |= vmodmask;
 13947           else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Hyper)
 13948             dpyinfo->hyper_mod_mask |= vmodmask;
 13949           else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_ShiftLock)
 13950             dpyinfo->shift_lock_mask |= vmodmask;
 13951         }
 13952 
 13953       if (!found_meta_p)
 13954         {
 13955           dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
 13956           dpyinfo->alt_mod_mask = 0;
 13957         }
 13958 
 13959       if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
 13960         dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
 13961 
 13962       if (dpyinfo->hyper_mod_mask & dpyinfo->super_mod_mask)
 13963         dpyinfo->hyper_mod_mask &= ~dpyinfo->super_mod_mask;
 13964 
 13965       return;
 13966     }
 13967 #endif
 13968 
 13969   XDisplayKeycodes (dpyinfo->display, &min_code, &max_code);
 13970 
 13971   syms = XGetKeyboardMapping (dpyinfo->display,
 13972                               min_code, max_code - min_code + 1,
 13973                               &syms_per_code);
 13974 
 13975   if (!syms)
 13976     {
 13977       dpyinfo->meta_mod_mask = Mod1Mask;
 13978       dpyinfo->super_mod_mask = Mod2Mask;
 13979       return;
 13980     }
 13981 
 13982   mods = XGetModifierMapping (dpyinfo->display);
 13983 
 13984   /* Scan the modifier table to see which modifier bits the Meta and
 13985      Alt keysyms are on.  */
 13986   {
 13987     int row, col;       /* The row and column in the modifier table.  */
 13988     bool found_alt_or_meta;
 13989 
 13990     for (row = 3; row < 8; row++)
 13991       {
 13992         found_alt_or_meta = false;
 13993         for (col = 0; col < mods->max_keypermod; col++)
 13994           {
 13995             KeyCode code = mods->modifiermap[(row * mods->max_keypermod) + col];
 13996 
 13997             /* Zeroes are used for filler.  Skip them.  */
 13998             if (code == 0)
 13999               continue;
 14000 
 14001             /* Are any of this keycode's keysyms a meta key?  */
 14002             {
 14003               int code_col;
 14004 
 14005               for (code_col = 0; code_col < syms_per_code; code_col++)
 14006                 {
 14007                   int sym = syms[((code - min_code) * syms_per_code) + code_col];
 14008 
 14009                   switch (sym)
 14010                     {
 14011                     case XK_Meta_L:
 14012                     case XK_Meta_R:
 14013                       found_alt_or_meta = true;
 14014                       dpyinfo->meta_mod_mask |= (1 << row);
 14015                       break;
 14016 
 14017                     case XK_Alt_L:
 14018                     case XK_Alt_R:
 14019                       found_alt_or_meta = true;
 14020                       dpyinfo->alt_mod_mask |= (1 << row);
 14021                       break;
 14022 
 14023                     case XK_Hyper_L:
 14024                     case XK_Hyper_R:
 14025                       if (!found_alt_or_meta)
 14026                         dpyinfo->hyper_mod_mask |= (1 << row);
 14027                       code_col = syms_per_code;
 14028                       col = mods->max_keypermod;
 14029                       break;
 14030 
 14031                     case XK_Super_L:
 14032                     case XK_Super_R:
 14033                       if (!found_alt_or_meta)
 14034                         dpyinfo->super_mod_mask |= (1 << row);
 14035                       code_col = syms_per_code;
 14036                       col = mods->max_keypermod;
 14037                       break;
 14038 
 14039                     case XK_Shift_Lock:
 14040                       /* Ignore this if it's not on the lock modifier.  */
 14041                       if (!found_alt_or_meta && ((1 << row) == LockMask))
 14042                         dpyinfo->shift_lock_mask = LockMask;
 14043                       code_col = syms_per_code;
 14044                       col = mods->max_keypermod;
 14045                       break;
 14046                     }
 14047                 }
 14048             }
 14049           }
 14050       }
 14051   }
 14052 
 14053   /* If we couldn't find any meta keys, accept any alt keys as meta keys.  */
 14054   if (! dpyinfo->meta_mod_mask)
 14055     {
 14056       dpyinfo->meta_mod_mask = dpyinfo->alt_mod_mask;
 14057       dpyinfo->alt_mod_mask = 0;
 14058     }
 14059 
 14060   /* If some keys are both alt and meta,
 14061      make them just meta, not alt.  */
 14062   if (dpyinfo->alt_mod_mask & dpyinfo->meta_mod_mask)
 14063     {
 14064       dpyinfo->alt_mod_mask &= ~dpyinfo->meta_mod_mask;
 14065     }
 14066 
 14067   /* If some keys are both super and hyper, make them just super.
 14068      Many X servers are misconfigured so that super and hyper are both
 14069      Mod4, but most users have no hyper key.  */
 14070   if (dpyinfo->hyper_mod_mask & dpyinfo->super_mod_mask)
 14071     dpyinfo->hyper_mod_mask &= ~dpyinfo->super_mod_mask;
 14072 
 14073   XFree (syms);
 14074 
 14075   if (dpyinfo->modmap)
 14076     XFreeModifiermap (dpyinfo->modmap);
 14077   dpyinfo->modmap = mods;
 14078 }
 14079 
 14080 /* Convert between the modifier bits X uses and the modifier bits
 14081    Emacs uses.  */
 14082 
 14083 int
 14084 x_x_to_emacs_modifiers (struct x_display_info *dpyinfo, int state)
 14085 {
 14086   int mod_ctrl = ctrl_modifier;
 14087   int mod_meta = meta_modifier;
 14088   int mod_alt  = alt_modifier;
 14089   int mod_hyper = hyper_modifier;
 14090   int mod_super = super_modifier;
 14091   Lisp_Object tem;
 14092 
 14093   tem = Fget (Vx_ctrl_keysym, Qmodifier_value);
 14094   if (FIXNUMP (tem)) mod_ctrl = XFIXNUM (tem) & INT_MAX;
 14095   tem = Fget (Vx_alt_keysym, Qmodifier_value);
 14096   if (FIXNUMP (tem)) mod_alt = XFIXNUM (tem) & INT_MAX;
 14097   tem = Fget (Vx_meta_keysym, Qmodifier_value);
 14098   if (FIXNUMP (tem)) mod_meta = XFIXNUM (tem) & INT_MAX;
 14099   tem = Fget (Vx_hyper_keysym, Qmodifier_value);
 14100   if (FIXNUMP (tem)) mod_hyper = XFIXNUM (tem) & INT_MAX;
 14101   tem = Fget (Vx_super_keysym, Qmodifier_value);
 14102   if (FIXNUMP (tem)) mod_super = XFIXNUM (tem) & INT_MAX;
 14103 
 14104   return (  ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0)
 14105             | ((state & ControlMask)                    ? mod_ctrl      : 0)
 14106             | ((state & dpyinfo->meta_mod_mask)         ? mod_meta      : 0)
 14107             | ((state & dpyinfo->alt_mod_mask)          ? mod_alt       : 0)
 14108             | ((state & dpyinfo->super_mod_mask)        ? mod_super     : 0)
 14109             | ((state & dpyinfo->hyper_mod_mask)        ? mod_hyper     : 0));
 14110 }
 14111 
 14112 int
 14113 x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, intmax_t state)
 14114 {
 14115   EMACS_INT mod_ctrl = ctrl_modifier;
 14116   EMACS_INT mod_meta = meta_modifier;
 14117   EMACS_INT mod_alt  = alt_modifier;
 14118   EMACS_INT mod_hyper = hyper_modifier;
 14119   EMACS_INT mod_super = super_modifier;
 14120 
 14121   Lisp_Object tem;
 14122 
 14123   tem = Fget (Vx_ctrl_keysym, Qmodifier_value);
 14124   if (FIXNUMP (tem)) mod_ctrl = XFIXNUM (tem);
 14125   tem = Fget (Vx_alt_keysym, Qmodifier_value);
 14126   if (FIXNUMP (tem)) mod_alt = XFIXNUM (tem);
 14127   tem = Fget (Vx_meta_keysym, Qmodifier_value);
 14128   if (FIXNUMP (tem)) mod_meta = XFIXNUM (tem);
 14129   tem = Fget (Vx_hyper_keysym, Qmodifier_value);
 14130   if (FIXNUMP (tem)) mod_hyper = XFIXNUM (tem);
 14131   tem = Fget (Vx_super_keysym, Qmodifier_value);
 14132   if (FIXNUMP (tem)) mod_super = XFIXNUM (tem);
 14133 
 14134 
 14135   return (  ((state & mod_alt)          ? dpyinfo->alt_mod_mask   : 0)
 14136             | ((state & mod_super)      ? dpyinfo->super_mod_mask : 0)
 14137             | ((state & mod_hyper)      ? dpyinfo->hyper_mod_mask : 0)
 14138             | ((state & shift_modifier) ? ShiftMask        : 0)
 14139             | ((state & mod_ctrl)       ? ControlMask      : 0)
 14140             | ((state & mod_meta)       ? dpyinfo->meta_mod_mask  : 0));
 14141 }
 14142 
 14143 /* Convert a keysym to its name.  */
 14144 
 14145 char *
 14146 get_keysym_name (int keysym)
 14147 {
 14148   char *value;
 14149 
 14150   block_input ();
 14151   value = XKeysymToString (keysym);
 14152   unblock_input ();
 14153 
 14154   return value;
 14155 }
 14156 
 14157 /* Given the root and event coordinates of an X event destined for F's
 14158    edit window, compute the offset between that window and F's root
 14159    window.  This information is then used as an optimization to avoid
 14160    synchronizing when converting coordinates from some other event to
 14161    F's edit window.  */
 14162 
 14163 static void
 14164 x_compute_root_window_offset (struct frame *f, int root_x, int root_y,
 14165                               int event_x, int event_y)
 14166 {
 14167   FRAME_X_OUTPUT (f)->window_offset_certain_p = true;
 14168   FRAME_X_OUTPUT (f)->root_x = root_x - event_x;
 14169   FRAME_X_OUTPUT (f)->root_y = root_y - event_y;
 14170 }
 14171 
 14172 /* Translate the given coordinates from the root window to the edit
 14173    window of FRAME, taking into account any cached root window
 14174    offsets.  This allows Emacs to avoid excessive calls to _XReply in
 14175    many cases while handling events, which would otherwise result in
 14176    slowdowns over slow network connections.  */
 14177 
 14178 void
 14179 x_translate_coordinates (struct frame *f, int root_x, int root_y,
 14180                          int *x_out, int *y_out)
 14181 {
 14182   struct x_output *output;
 14183   Window dummy;
 14184 
 14185   output = FRAME_X_OUTPUT (f);
 14186 
 14187   if (output->window_offset_certain_p)
 14188     {
 14189       /* Use the cached root window offset.  */
 14190       *x_out = root_x - output->root_x;
 14191       *y_out = root_y - output->root_y;
 14192 
 14193       return;
 14194     }
 14195 
 14196   /* Otherwise, do the transformation manually.  Then, cache the root
 14197      window position.  */
 14198   if (!XTranslateCoordinates (FRAME_X_DISPLAY (f),
 14199                               FRAME_DISPLAY_INFO (f)->root_window,
 14200                               FRAME_X_WINDOW (f), root_x, root_y,
 14201                               x_out, y_out, &dummy))
 14202     /* Use some dummy values.  This is not supposed to be called with
 14203        coordinates out of the screen.  */
 14204     *x_out = 0, *y_out = 0;
 14205   else
 14206     {
 14207       /* Cache the root window offset of the edit window.  */
 14208       output->window_offset_certain_p = true;
 14209       output->root_x = root_x - *x_out;
 14210       output->root_y = root_y - *y_out;
 14211     }
 14212 }
 14213 
 14214 /* Translate the given coordinates from the edit window of FRAME,
 14215    taking into account any cached root window offsets.  This is mainly
 14216    used from the popup menu code.  */
 14217 
 14218 void
 14219 x_translate_coordinates_to_root (struct frame *f, int x, int y,
 14220                                  int *x_out, int *y_out)
 14221 {
 14222   struct x_output *output;
 14223   Window dummy;
 14224 
 14225   output = FRAME_X_OUTPUT (f);
 14226 
 14227   if (output->window_offset_certain_p)
 14228     {
 14229       /* Use the cached root window offset.  */
 14230       *x_out = x + output->root_x;
 14231       *y_out = y + output->root_y;
 14232 
 14233       return;
 14234     }
 14235 
 14236   /* Otherwise, do the transform manually and compute and cache the
 14237      root window position.  */
 14238   if (!XTranslateCoordinates (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 14239                               FRAME_DISPLAY_INFO (f)->root_window,
 14240                               x, y, x_out, y_out, &dummy))
 14241     *x_out = 0, *y_out = 0;
 14242   else
 14243     {
 14244       /* Cache the root window offset of the edit window.  */
 14245       output->window_offset_certain_p = true;
 14246       output->root_x = *x_out - x;
 14247       output->root_y = *y_out - y;
 14248     }
 14249 }
 14250 
 14251 /* Do x-translate-coordinates, but try to avoid a roundtrip to the X
 14252    server at the cost of not returning `child', which most callers
 14253    have no reason to use.  */
 14254 
 14255 Lisp_Object
 14256 x_handle_translate_coordinates (struct frame *f, Lisp_Object dest_window,
 14257                                 int source_x, int source_y)
 14258 {
 14259   if (NILP (dest_window))
 14260     {
 14261       /* We are translating coordinates from a frame to the root
 14262          window.  Avoid a roundtrip if possible by using cached
 14263          coordinates.  */
 14264 
 14265       if (!FRAME_X_OUTPUT (f)->window_offset_certain_p)
 14266         return Qnil;
 14267 
 14268       return list3 (make_fixnum (source_x + FRAME_X_OUTPUT (f)->root_x),
 14269                     make_fixnum (source_y + FRAME_X_OUTPUT (f)->root_y),
 14270                     Qnil);
 14271     }
 14272 
 14273   return Qnil;
 14274 }
 14275 
 14276 /* The same, but for an XIDeviceEvent.  */
 14277 
 14278 #ifdef HAVE_XINPUT2
 14279 
 14280 static void
 14281 xi_compute_root_window_offset (struct frame *f, XIDeviceEvent *xev)
 14282 {
 14283   /* Truncate coordinates instead of rounding them, because that is
 14284      how the X server handles window hierarchy.  */
 14285   x_compute_root_window_offset (f, xev->root_x, xev->root_y,
 14286                                 xev->event_x, xev->event_y);
 14287 }
 14288 
 14289 static void
 14290 xi_compute_root_window_offset_enter (struct frame *f, XIEnterEvent *enter)
 14291 {
 14292   x_compute_root_window_offset (f, enter->root_x, enter->root_y,
 14293                                 enter->event_x, enter->event_y);
 14294 }
 14295 
 14296 #ifdef HAVE_XINPUT2_4
 14297 
 14298 static void
 14299 xi_compute_root_window_offset_pinch (struct frame *f, XIGesturePinchEvent *pev)
 14300 {
 14301   /* Truncate coordinates instead of rounding them, because that is
 14302      how the X server handles window hierarchy.  */
 14303   x_compute_root_window_offset (f, pev->root_x, pev->root_y,
 14304                                 pev->event_x, pev->event_y);
 14305 }
 14306 
 14307 #endif
 14308 
 14309 #endif
 14310 
 14311 static Bool
 14312 x_query_pointer_1 (struct x_display_info *dpyinfo,
 14313                    int client_pointer_device, Window w,
 14314                    Window *root_return, Window *child_return,
 14315                    int *root_x_return, int *root_y_return,
 14316                    int *win_x_return, int *win_y_return,
 14317                    unsigned int *mask_return)
 14318 {
 14319   Bool rc;
 14320   Display *dpy;
 14321 #ifdef HAVE_XINPUT2
 14322   bool had_errors;
 14323   XIModifierState modifiers;
 14324   XIButtonState buttons;
 14325   XIGroupState group; /* Unused.  */
 14326   double root_x, root_y, win_x, win_y;
 14327   unsigned int state;
 14328 #endif
 14329 
 14330   dpy = dpyinfo->display;
 14331 
 14332 #ifdef HAVE_XINPUT2
 14333   if (client_pointer_device != -1)
 14334     {
 14335       /* Catch errors caused by the device going away.  This is not
 14336          very expensive, since XIQueryPointer will sync anyway.  */
 14337       x_catch_errors (dpy);
 14338       rc = XIQueryPointer (dpyinfo->display,
 14339                            dpyinfo->client_pointer_device,
 14340                            w, root_return, child_return,
 14341                            &root_x, &root_y, &win_x, &win_y,
 14342                            &buttons, &modifiers, &group);
 14343       had_errors = x_had_errors_p (dpy);
 14344       x_uncatch_errors_after_check ();
 14345 
 14346       if (had_errors)
 14347         {
 14348           /* If the specified client pointer is the display's client
 14349              pointer, clear it now.  A new client pointer might not be
 14350              found before the next call to x_query_pointer_1 and
 14351              waiting for the error leads to excessive syncing.  */
 14352 
 14353           if (client_pointer_device == dpyinfo->client_pointer_device)
 14354             dpyinfo->client_pointer_device = -1;
 14355 
 14356           rc = XQueryPointer (dpyinfo->display, w, root_return,
 14357                               child_return, root_x_return,
 14358                               root_y_return, win_x_return,
 14359                               win_y_return, mask_return);
 14360         }
 14361       else
 14362         {
 14363           state = 0;
 14364 
 14365           xi_convert_button_state (&buttons, &state);
 14366           *mask_return = state | modifiers.effective;
 14367 
 14368           XFree (buttons.mask);
 14369 
 14370           *root_x_return = lrint (root_x);
 14371           *root_y_return = lrint (root_y);
 14372           *win_x_return = lrint (win_x);
 14373           *win_y_return = lrint (win_y);
 14374         }
 14375     }
 14376   else
 14377 #endif
 14378     rc = XQueryPointer (dpy, w, root_return, child_return,
 14379                         root_x_return, root_y_return, win_x_return,
 14380                         win_y_return, mask_return);
 14381 
 14382   return rc;
 14383 }
 14384 
 14385 Bool
 14386 x_query_pointer (Display *dpy, Window w, Window *root_return,
 14387                  Window *child_return, int *root_x_return,
 14388                  int *root_y_return, int *win_x_return,
 14389                  int *win_y_return, unsigned int *mask_return)
 14390 {
 14391   struct x_display_info *dpyinfo;
 14392 
 14393   dpyinfo = x_display_info_for_display (dpy);
 14394 
 14395   if (!dpyinfo)
 14396     emacs_abort ();
 14397 
 14398 #ifdef HAVE_XINPUT2
 14399   return x_query_pointer_1 (dpyinfo, dpyinfo->client_pointer_device,
 14400                             w, root_return, child_return, root_x_return,
 14401                             root_y_return, win_x_return, win_y_return,
 14402                             mask_return);
 14403 #else
 14404   return x_query_pointer_1 (dpyinfo, -1, w, root_return, child_return,
 14405                             root_x_return, root_y_return, win_x_return,
 14406                             win_y_return, mask_return);
 14407 #endif
 14408 }
 14409 
 14410 /* Mouse clicks and mouse movement.  Rah.
 14411 
 14412    Formerly, we used PointerMotionHintMask (in standard_event_mask)
 14413    so that we would have to call XQueryPointer after each MotionNotify
 14414    event to ask for another such event.  However, this made mouse tracking
 14415    slow, and there was a bug that made it eventually stop.
 14416 
 14417    Simply asking for MotionNotify all the time seems to work better.
 14418 
 14419    In order to avoid asking for motion events and then throwing most
 14420    of them away or busy-polling the server for mouse positions, we ask
 14421    the server for pointer motion hints.  This means that we get only
 14422    one event per group of mouse movements.  "Groups" are delimited by
 14423    other kinds of events (focus changes and button clicks, for
 14424    example), or by XQueryPointer calls; when one of these happens, we
 14425    get another MotionNotify event the next time the mouse moves.  This
 14426    is at least as efficient as getting motion events when mouse
 14427    tracking is on, and I suspect only negligibly worse when tracking
 14428    is off.  */
 14429 
 14430 /* Prepare a mouse-event in *RESULT for placement in the input queue.
 14431 
 14432    If the event is a button press, then note that we have grabbed
 14433    the mouse.
 14434 
 14435    The XButtonEvent structure passed as EVENT might not come from the
 14436    X server, and instead be artificially constructed from input
 14437    extension events.  In these special events, the only fields that
 14438    are initialized are `time', `button', `state', `type', `window' and
 14439    `x', `y', `x_root' and `y_root'.  This function should not access
 14440    any other fields in EVENT without also initializing the
 14441    corresponding fields in `bv' under the XI_ButtonPress and
 14442    XI_ButtonRelease labels inside `handle_one_xevent'.  */
 14443 
 14444 static Lisp_Object
 14445 x_construct_mouse_click (struct input_event *result,
 14446                          const XButtonEvent *event,
 14447                          struct frame *f)
 14448 {
 14449   int x = event->x;
 14450   int y = event->y;
 14451 
 14452   /* Make the event type NO_EVENT; we'll change that when we decide
 14453      otherwise.  */
 14454   result->kind = MOUSE_CLICK_EVENT;
 14455   result->code = event->button - Button1;
 14456   result->timestamp = event->time;
 14457   result->modifiers = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f),
 14458                                                event->state)
 14459                        | (event->type == ButtonRelease
 14460                           ? up_modifier
 14461                           : down_modifier));
 14462 
 14463   /* If result->window is not the frame's edit widget (which can
 14464      happen with GTK+ scroll bars, for example), translate the
 14465      coordinates so they appear at the correct position.  */
 14466   if (event->window != FRAME_X_WINDOW (f))
 14467     x_translate_coordinates (f, event->x_root, event->y_root,
 14468                              &x, &y);
 14469 
 14470   XSETINT (result->x, x);
 14471   XSETINT (result->y, y);
 14472   XSETFRAME (result->frame_or_window, f);
 14473   result->arg = Qnil;
 14474   return Qnil;
 14475 }
 14476 
 14477 /* Function to report a mouse movement to the mainstream Emacs code.
 14478    The input handler calls this.
 14479 
 14480    We have received a mouse movement event, which is given in *event.
 14481    If the mouse is over a different glyph than it was last time, tell
 14482    the mainstream emacs code by setting mouse_moved.  If not, ask for
 14483    another motion event, so we can check again the next time it moves.
 14484 
 14485    The XMotionEvent structure passed as EVENT might not come from the
 14486    X server, and instead be artificially constructed from input
 14487    extension events.  In these special events, the only fields that
 14488    are initialized are `time', `window', `send_event', `x' and `y'.
 14489    This function should not access any other fields in EVENT without
 14490    also initializing the corresponding fields in `ev' under the
 14491    XI_Motion, XI_Enter and XI_Leave labels inside
 14492    `handle_one_xevent'.  */
 14493 
 14494 static bool
 14495 x_note_mouse_movement (struct frame *frame, const XMotionEvent *event,
 14496                        Lisp_Object device)
 14497 {
 14498   XRectangle *r;
 14499   struct x_display_info *dpyinfo;
 14500 
 14501   if (!FRAME_X_OUTPUT (frame))
 14502     return false;
 14503 
 14504   dpyinfo = FRAME_DISPLAY_INFO (frame);
 14505   dpyinfo->last_mouse_movement_time = event->time;
 14506   dpyinfo->last_mouse_movement_time_send_event = event->send_event;
 14507   dpyinfo->last_mouse_motion_frame = frame;
 14508   dpyinfo->last_mouse_motion_x = event->x;
 14509   dpyinfo->last_mouse_motion_y = event->y;
 14510 
 14511   if (event->window != FRAME_X_WINDOW (frame))
 14512     {
 14513       frame->mouse_moved = true;
 14514       frame->last_mouse_device = device;
 14515       dpyinfo->last_mouse_scroll_bar = NULL;
 14516       note_mouse_highlight (frame, -1, -1);
 14517       dpyinfo->last_mouse_glyph_frame = NULL;
 14518       return true;
 14519     }
 14520 
 14521 
 14522   /* Has the mouse moved off the glyph it was on at the last sighting?  */
 14523   r = &dpyinfo->last_mouse_glyph;
 14524   if (frame != dpyinfo->last_mouse_glyph_frame
 14525       || event->x < r->x || event->x >= r->x + r->width
 14526       || event->y < r->y || event->y >= r->y + r->height)
 14527     {
 14528       frame->mouse_moved = true;
 14529       frame->last_mouse_device = device;
 14530       dpyinfo->last_mouse_scroll_bar = NULL;
 14531       note_mouse_highlight (frame, event->x, event->y);
 14532       /* Remember which glyph we're now on.  */
 14533       remember_mouse_glyph (frame, event->x, event->y, r);
 14534       dpyinfo->last_mouse_glyph_frame = frame;
 14535       return true;
 14536     }
 14537 
 14538   return false;
 14539 }
 14540 
 14541 /* Get a sibling below WINDOW on DPY at PARENT_X and PARENT_Y.  */
 14542 static Window
 14543 x_get_window_below (Display *dpy, Window window,
 14544                     int parent_x, int parent_y,
 14545                     int *inner_x, int *inner_y)
 14546 {
 14547   int rc, i, cx, cy;
 14548   XWindowAttributes attrs;
 14549   unsigned int nchildren;
 14550   Window root, parent, *children, value;
 14551   bool window_seen;
 14552 
 14553   /* TODO: rewrite to have less dependencies.  */
 14554 
 14555   children = NULL;
 14556   window_seen = false;
 14557   value = None;
 14558 
 14559   rc = XQueryTree (dpy, window, &root, &parent,
 14560                    &children, &nchildren);
 14561 
 14562   if (rc)
 14563     {
 14564       if (children)
 14565         XFree (children);
 14566 
 14567       rc = XQueryTree (dpy, parent, &root,
 14568                        &parent, &children, &nchildren);
 14569     }
 14570 
 14571   if (rc)
 14572     {
 14573       for (i = nchildren - 1; i >= 0; --i)
 14574         {
 14575           if (children[i] == window)
 14576             {
 14577               window_seen = true;
 14578               continue;
 14579             }
 14580 
 14581           if (!window_seen)
 14582             continue;
 14583 
 14584           rc = XGetWindowAttributes (dpy, children[i], &attrs);
 14585 
 14586           if (rc && attrs.map_state != IsViewable)
 14587             continue;
 14588 
 14589           if (rc && parent_x >= attrs.x
 14590               && parent_y >= attrs.y
 14591               && parent_x < attrs.x + attrs.width
 14592               && parent_y < attrs.y + attrs.height)
 14593             {
 14594               value = children[i];
 14595               cx = parent_x - attrs.x;
 14596               cy = parent_y - attrs.y;
 14597 
 14598               break;
 14599             }
 14600         }
 14601     }
 14602 
 14603   if (children)
 14604     XFree (children);
 14605 
 14606   if (value)
 14607     {
 14608       *inner_x = cx;
 14609       *inner_y = cy;
 14610     }
 14611 
 14612   return value;
 14613 }
 14614 
 14615 /* Like XTmouse_position, but much faster.  */
 14616 
 14617 static void
 14618 x_fast_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 14619                        enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
 14620                        Time *timestamp)
 14621 {
 14622   int root_x, root_y, win_x, win_y;
 14623   unsigned int mask;
 14624   Window dummy;
 14625   struct scroll_bar *bar;
 14626   struct x_display_info *dpyinfo;
 14627   Lisp_Object tail, frame;
 14628   struct frame *f1;
 14629 
 14630   dpyinfo = FRAME_DISPLAY_INFO (*fp);
 14631 
 14632   if (dpyinfo->last_mouse_scroll_bar && !insist)
 14633     {
 14634       bar = dpyinfo->last_mouse_scroll_bar;
 14635 
 14636       if (bar->horizontal)
 14637         x_horizontal_scroll_bar_report_motion (fp, bar_window, part,
 14638                                                x, y, timestamp);
 14639       else
 14640         x_scroll_bar_report_motion (fp, bar_window, part,
 14641                                     x, y, timestamp);
 14642 
 14643       return;
 14644     }
 14645 
 14646   if (!EQ (Vx_use_fast_mouse_position, Qreally_fast))
 14647     {
 14648       /* This means that Emacs should select a frame and report the
 14649          mouse position relative to it.  The approach used here avoids
 14650          making multiple roundtrips to the X server querying for the
 14651          window beneath the pointer, and was borrowed from
 14652          haiku_mouse_position in haikuterm.c.  */
 14653 
 14654       FOR_EACH_FRAME (tail, frame)
 14655         {
 14656           if (FRAME_X_P (XFRAME (frame))
 14657               && (FRAME_DISPLAY_INFO (XFRAME (frame))
 14658                   == dpyinfo))
 14659             XFRAME (frame)->mouse_moved = false;
 14660         }
 14661 
 14662       if (gui_mouse_grabbed (dpyinfo)
 14663           && !EQ (track_mouse, Qdropping)
 14664           && !EQ (track_mouse, Qdrag_source))
 14665         /* Pick the last mouse frame if dropping.  */
 14666         f1 = dpyinfo->last_mouse_frame;
 14667       else
 14668         /* Otherwise, pick the last mouse motion frame.  */
 14669         f1 = dpyinfo->last_mouse_motion_frame;
 14670 
 14671       if (!f1 && (FRAME_X_P (SELECTED_FRAME ())
 14672                   && (FRAME_DISPLAY_INFO (SELECTED_FRAME ())
 14673                       == dpyinfo)))
 14674         f1 = SELECTED_FRAME ();
 14675 
 14676       if (!f1 || (!FRAME_X_P (f1) && (insist > 0)))
 14677         FOR_EACH_FRAME (tail, frame)
 14678           if (FRAME_X_P (XFRAME (frame))
 14679               && (FRAME_DISPLAY_INFO (XFRAME (frame))
 14680                   == dpyinfo)
 14681               && !FRAME_TOOLTIP_P (XFRAME (frame)))
 14682             f1 = XFRAME (frame);
 14683 
 14684       if (f1 && FRAME_TOOLTIP_P (f1))
 14685         f1 = NULL;
 14686 
 14687       if (f1 && FRAME_X_P (f1) && FRAME_X_WINDOW (f1))
 14688         {
 14689           if (!x_query_pointer (dpyinfo->display, FRAME_X_WINDOW (f1),
 14690                                 &dummy, &dummy, &root_x, &root_y,
 14691                                 &win_x, &win_y, &mask))
 14692             /* The pointer is out of the screen.  */
 14693             return;
 14694 
 14695           remember_mouse_glyph (f1, win_x, win_y,
 14696                                 &dpyinfo->last_mouse_glyph);
 14697           dpyinfo->last_mouse_glyph_frame = f1;
 14698 
 14699           *bar_window = Qnil;
 14700           *part = scroll_bar_nowhere;
 14701 
 14702           /* If track-mouse is `drag-source' and the mouse pointer is
 14703              certain to not be actually under the chosen frame, return
 14704              NULL in FP.  */
 14705           if (EQ (track_mouse, Qdrag_source)
 14706               && (win_x < 0 || win_y < 0
 14707                   || win_x >= FRAME_PIXEL_WIDTH (f1)
 14708                   || win_y >= FRAME_PIXEL_HEIGHT (f1)))
 14709             *fp = NULL;
 14710           else
 14711             *fp = f1;
 14712 
 14713           *timestamp = dpyinfo->last_mouse_movement_time;
 14714           XSETINT (*x, win_x);
 14715           XSETINT (*y, win_y);
 14716         }
 14717     }
 14718   else
 14719     {
 14720       /* This means Emacs should only report the coordinates of the
 14721          last mouse motion.  */
 14722 
 14723       if (dpyinfo->last_mouse_motion_frame)
 14724         {
 14725           *fp = dpyinfo->last_mouse_motion_frame;
 14726           *timestamp = dpyinfo->last_mouse_movement_time;
 14727           *x = make_fixnum (dpyinfo->last_mouse_motion_x);
 14728           *y = make_fixnum (dpyinfo->last_mouse_motion_y);
 14729           *bar_window = Qnil;
 14730           *part = scroll_bar_nowhere;
 14731 
 14732           FOR_EACH_FRAME (tail, frame)
 14733             {
 14734               if (FRAME_X_P (XFRAME (frame))
 14735                   && (FRAME_DISPLAY_INFO (XFRAME (frame))
 14736                       == dpyinfo))
 14737                 XFRAME (frame)->mouse_moved = false;
 14738             }
 14739 
 14740           dpyinfo->last_mouse_motion_frame->mouse_moved = false;
 14741         }
 14742     }
 14743 }
 14744 
 14745 /* Return the current position of the mouse.
 14746    *FP should be a frame which indicates which display to ask about.
 14747 
 14748    If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
 14749    and *PART to the frame, window, and scroll bar part that the mouse
 14750    is over.  Set *X and *Y to the portion and whole of the mouse's
 14751    position on the scroll bar.
 14752 
 14753    If the mouse movement started elsewhere, set *FP to the frame the
 14754    mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
 14755    the mouse is over.
 14756 
 14757    Set *TIMESTAMP to the server time-stamp for the time at which the mouse
 14758    was at this position.
 14759 
 14760    Don't store anything if we don't have a valid set of values to report.
 14761 
 14762    This clears the mouse_moved flag, so we can wait for the next mouse
 14763    movement.  */
 14764 
 14765 static void
 14766 XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 14767                   enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
 14768                   Time *timestamp)
 14769 {
 14770   struct frame *f1, *maybe_tooltip;
 14771   struct x_display_info *dpyinfo;
 14772   bool unrelated_tooltip;
 14773 
 14774   dpyinfo = FRAME_DISPLAY_INFO (*fp);
 14775 
 14776   if (!NILP (Vx_use_fast_mouse_position))
 14777     {
 14778       /* The user says that Emacs is running over the network, and a
 14779          fast approximation of `mouse-position' should be used.
 14780 
 14781          Depending on what the value of `x-use-fast-mouse-position'
 14782          is, do one of two things: only perform the XQueryPointer to
 14783          obtain the coordinates from the last mouse frame, or only
 14784          return the last mouse motion frame and the
 14785          last_mouse_motion_x and Y.  */
 14786 
 14787       x_fast_mouse_position (fp, insist, bar_window, part, x,
 14788                              y, timestamp);
 14789       return;
 14790     }
 14791 
 14792   block_input ();
 14793 
 14794   if (dpyinfo->last_mouse_scroll_bar && insist == 0)
 14795     {
 14796       struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
 14797 
 14798       if (bar->horizontal)
 14799         x_horizontal_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
 14800       else
 14801         x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
 14802     }
 14803   else
 14804     {
 14805       Window root;
 14806       int root_x, root_y;
 14807 
 14808       Window dummy_window;
 14809       int dummy;
 14810 
 14811       Lisp_Object frame, tail;
 14812 
 14813       /* Clear the mouse-moved flag for every frame on this display.  */
 14814       FOR_EACH_FRAME (tail, frame)
 14815         if (FRAME_X_P (XFRAME (frame))
 14816             && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
 14817           XFRAME (frame)->mouse_moved = false;
 14818 
 14819       dpyinfo->last_mouse_scroll_bar = NULL;
 14820 
 14821       /* Figure out which root window we're on.  */
 14822       x_query_pointer (FRAME_X_DISPLAY (*fp),
 14823                        DefaultRootWindow (FRAME_X_DISPLAY (*fp)),
 14824                        /* The root window which contains the pointer.  */
 14825                        &root,
 14826                        /* Trash which we can't trust if the pointer is on
 14827                           a different screen.  */
 14828                        &dummy_window,
 14829                        /* The position on that root window.  */
 14830                        &root_x, &root_y,
 14831                        /* More trash we can't trust.  */
 14832                        &dummy, &dummy,
 14833                        /* Modifier keys and pointer buttons, about which
 14834                           we don't care.  */
 14835                        (unsigned int *) &dummy);
 14836 
 14837       /* Now we have a position on the root; find the innermost window
 14838          containing the pointer.  */
 14839       {
 14840         Window win, child;
 14841 #ifdef USE_GTK
 14842         Window first_win = 0;
 14843 #endif
 14844         int win_x, win_y;
 14845         int parent_x, parent_y;
 14846 
 14847         win = root;
 14848         parent_x = root_x;
 14849         parent_y = root_y;
 14850 
 14851         /* XTranslateCoordinates can get errors if the window
 14852            structure is changing at the same time this function
 14853            is running.  So at least we must not crash from them.  */
 14854 
 14855         x_catch_errors (FRAME_X_DISPLAY (*fp));
 14856 
 14857         if (gui_mouse_grabbed (dpyinfo) && !EQ (track_mouse, Qdropping)
 14858             && !EQ (track_mouse, Qdrag_source))
 14859           {
 14860             /* If mouse was grabbed on a frame, give coords for that frame
 14861                even if the mouse is now outside it.  */
 14862             XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
 14863                                    /* From-window.  */
 14864                                    root,
 14865                                    /* To-window.  */
 14866                                    FRAME_X_WINDOW (dpyinfo->last_mouse_frame),
 14867                                    /* From-position, to-position.  */
 14868                                    root_x, root_y, &win_x, &win_y,
 14869                                    /* Child of win.  */
 14870                                    &child);
 14871             f1 = dpyinfo->last_mouse_frame;
 14872           }
 14873         else
 14874           {
 14875             while (true)
 14876               {
 14877                 XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
 14878                                        /* From-window, to-window.  */
 14879                                        root, win,
 14880                                        /* From-position, to-position.  */
 14881                                        root_x, root_y, &win_x, &win_y,
 14882                                        /* Child of win.  */
 14883                                        &child);
 14884 
 14885                 /* If CHILD is a tooltip frame, look below it if
 14886                    track-mouse is drag-source.  */
 14887                 if (child != None
 14888                     && (EQ (track_mouse, Qdrag_source)
 14889                         || EQ (track_mouse, Qdropping)))
 14890                   {
 14891                     maybe_tooltip = x_tooltip_window_to_frame (dpyinfo, child,
 14892                                                                &unrelated_tooltip);
 14893 
 14894                     if (maybe_tooltip || unrelated_tooltip)
 14895                       child = x_get_window_below (dpyinfo->display, child,
 14896                                                   parent_x, parent_y, &win_x,
 14897                                                   &win_y);
 14898                   }
 14899 
 14900                 if (child == None || child == win)
 14901                   {
 14902 #ifdef USE_GTK
 14903                     /* On GTK we have not inspected WIN yet.  If it has
 14904                        a frame and that frame has a parent, use it.  */
 14905                     struct frame *f = x_window_to_frame (dpyinfo, win);
 14906 
 14907                     if (f && FRAME_PARENT_FRAME (f))
 14908                       first_win = win;
 14909 #endif
 14910                     break;
 14911                   }
 14912 #ifdef USE_GTK
 14913                 /* We don't want to know the innermost window.  We
 14914                    want the edit window.  For non-Gtk+ the innermost
 14915                    window is the edit window.  For Gtk+ it might not
 14916                    be.  It might be the tool bar for example.  */
 14917                 if (x_window_to_frame (dpyinfo, win))
 14918                   /* But don't hurry.  We might find a child frame
 14919                      beneath.  */
 14920                   first_win = win;
 14921 #endif
 14922                 win = child;
 14923                 parent_x = win_x;
 14924                 parent_y = win_y;
 14925               }
 14926 
 14927 #ifdef USE_GTK
 14928             if (first_win)
 14929               win = first_win;
 14930 #endif
 14931 
 14932             /* Now we know that:
 14933                win is the innermost window containing the pointer
 14934                (XTC says it has no child containing the pointer),
 14935                win_x and win_y are the pointer's position in it
 14936                (XTC did this the last time through), and
 14937                parent_x and parent_y are the pointer's position in win's parent.
 14938                (They are what win_x and win_y were when win was child.
 14939                If win is the root window, it has no parent, and
 14940                parent_{x,y} are invalid, but that's okay, because we'll
 14941                never use them in that case.)  */
 14942 
 14943 #ifdef USE_GTK
 14944             /* We don't want to know the innermost window.  We
 14945                want the edit window.  */
 14946             f1 = x_window_to_frame (dpyinfo, win);
 14947 #else
 14948             /* Is win one of our frames?  */
 14949             f1 = x_any_window_to_frame (dpyinfo, win);
 14950 #endif
 14951 
 14952 #ifdef USE_X_TOOLKIT
 14953             /* If we end up with the menu bar window, say it's not
 14954                on the frame.  */
 14955             if (f1 != NULL
 14956                 && f1->output_data.x->menubar_widget
 14957                 && win == XtWindow (f1->output_data.x->menubar_widget))
 14958               f1 = NULL;
 14959 #endif /* USE_X_TOOLKIT */
 14960           }
 14961 
 14962         /* Set last user time to avoid confusing some window managers
 14963            about the tooltip displayed during drag-and-drop.  */
 14964 
 14965         if ((EQ (track_mouse, Qdrag_source)
 14966              || EQ (track_mouse, Qdropping))
 14967             && (dpyinfo->last_user_time
 14968                 < dpyinfo->last_mouse_movement_time))
 14969           x_display_set_last_user_time (dpyinfo,
 14970                                         dpyinfo->last_mouse_movement_time,
 14971                                         dpyinfo->last_mouse_movement_time_send_event,
 14972                                         true);
 14973 
 14974         if ((!f1 || FRAME_TOOLTIP_P (f1))
 14975             && (EQ (track_mouse, Qdropping)
 14976                 || EQ (track_mouse, Qdrag_source))
 14977             && gui_mouse_grabbed (dpyinfo))
 14978           {
 14979             /* When dropping then if we didn't get a frame or only a
 14980                tooltip frame and the mouse was grabbed on a frame,
 14981                give coords for that frame even if the mouse is now
 14982                outside it.  */
 14983             XTranslateCoordinates (FRAME_X_DISPLAY (*fp),
 14984                                    /* From-window.  */
 14985                                    root,
 14986                                    /* To-window.  */
 14987                                    FRAME_X_WINDOW (dpyinfo->last_mouse_frame),
 14988                                    /* From-position, to-position.  */
 14989                                    root_x, root_y, &win_x, &win_y,
 14990                                    /* Child of win.  */
 14991                                    &child);
 14992 
 14993             if (!EQ (track_mouse, Qdrag_source)
 14994                 /* Don't let tooltips interfere.  */
 14995                 || (f1 && FRAME_TOOLTIP_P (f1)))
 14996               f1 = dpyinfo->last_mouse_frame;
 14997             else
 14998               {
 14999                 /* Don't set FP but do set WIN_X and WIN_Y in this
 15000                    case, so make_lispy_movement knows which
 15001                    coordinates to report.  */
 15002                 *bar_window = Qnil;
 15003                 *part = 0;
 15004                 *fp = NULL;
 15005                 XSETINT (*x, win_x);
 15006                 XSETINT (*y, win_y);
 15007                 *timestamp = dpyinfo->last_mouse_movement_time;
 15008               }
 15009           }
 15010         else if (f1 && FRAME_TOOLTIP_P (f1))
 15011           f1 = NULL;
 15012 
 15013         if (x_had_errors_p (dpyinfo->display))
 15014           f1 = NULL;
 15015 
 15016         x_uncatch_errors_after_check ();
 15017 
 15018         /* If not, is it one of our scroll bars?  */
 15019         if (!f1)
 15020           {
 15021             struct scroll_bar *bar;
 15022 
 15023             bar = x_window_to_scroll_bar (dpyinfo->display, win, 2);
 15024 
 15025             if (bar)
 15026               {
 15027                 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 15028                 win_x = parent_x;
 15029                 win_y = parent_y;
 15030               }
 15031           }
 15032 
 15033         if (!f1 && insist > 0)
 15034           f1 = SELECTED_FRAME ();
 15035 
 15036         if (f1 && FRAME_X_P (f1))
 15037           {
 15038             /* Ok, we found a frame.  Store all the values.
 15039                last_mouse_glyph is a rectangle used to reduce the
 15040                generation of mouse events.  To not miss any motion
 15041                events, we must divide the frame into rectangles of the
 15042                size of the smallest character that could be displayed
 15043                on it, i.e. into the same rectangles that matrices on
 15044                the frame are divided into.  */
 15045 
 15046             dpyinfo = FRAME_DISPLAY_INFO (f1);
 15047             remember_mouse_glyph (f1, win_x, win_y, &dpyinfo->last_mouse_glyph);
 15048             dpyinfo->last_mouse_glyph_frame = f1;
 15049 
 15050             *bar_window = Qnil;
 15051             *part = 0;
 15052             *fp = f1;
 15053             XSETINT (*x, win_x);
 15054             XSETINT (*y, win_y);
 15055             *timestamp = dpyinfo->last_mouse_movement_time;
 15056           }
 15057       }
 15058     }
 15059 
 15060   unblock_input ();
 15061 }
 15062 
 15063 
 15064 
 15065 /***********************************************************************
 15066                                Scroll bars
 15067  ***********************************************************************/
 15068 
 15069 /* Scroll bar support.  */
 15070 
 15071 #if defined HAVE_XINPUT2
 15072 
 15073 /* Select for input extension events used by scroll bars.  This will
 15074    result in the corresponding core events not being generated for
 15075    SCROLL_BAR.  */
 15076 
 15077 MAYBE_UNUSED static void
 15078 xi_select_scroll_bar_events (struct x_display_info *dpyinfo,
 15079                              Window scroll_bar)
 15080 {
 15081   XIEventMask mask;
 15082   unsigned char *m;
 15083   ptrdiff_t length;
 15084 
 15085   length = XIMaskLen (XI_LASTEVENT);
 15086   mask.mask = m = alloca (length);
 15087   memset (m, 0, length);
 15088   mask.mask_len = length;
 15089 
 15090   mask.deviceid = XIAllMasterDevices;
 15091   XISetMask (m, XI_ButtonPress);
 15092   XISetMask (m, XI_ButtonRelease);
 15093   XISetMask (m, XI_Motion);
 15094   XISetMask (m, XI_Enter);
 15095   XISetMask (m, XI_Leave);
 15096 
 15097   XISelectEvents (dpyinfo->display, scroll_bar, &mask, 1);
 15098 }
 15099 
 15100 #endif
 15101 
 15102 /* Given an X window ID and a DISPLAY, find the struct scroll_bar which
 15103    manages it.
 15104    This can be called in GC, so we have to make sure to strip off mark
 15105    bits.  */
 15106 
 15107 static struct scroll_bar *
 15108 x_window_to_scroll_bar (Display *display, Window window_id, int type)
 15109 {
 15110   Lisp_Object tail, frame;
 15111 
 15112 #if defined (USE_GTK) && !defined (HAVE_GTK3) && defined (USE_TOOLKIT_SCROLL_BARS)
 15113   window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
 15114 #endif /* USE_GTK && !HAVE_GTK3  && USE_TOOLKIT_SCROLL_BARS */
 15115 
 15116   FOR_EACH_FRAME (tail, frame)
 15117     {
 15118       Lisp_Object bar, condemned;
 15119 
 15120       if (! FRAME_X_P (XFRAME (frame)))
 15121         continue;
 15122 
 15123       /* Scan this frame's scroll bar list for a scroll bar with the
 15124          right window ID.  */
 15125       condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
 15126       for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
 15127            /* This trick allows us to search both the ordinary and
 15128               condemned scroll bar lists with one loop.  */
 15129            ! NILP (bar) || (bar = condemned,
 15130                                condemned = Qnil,
 15131                                ! NILP (bar));
 15132            bar = XSCROLL_BAR (bar)->next)
 15133         if (XSCROLL_BAR (bar)->x_window == window_id
 15134             && FRAME_X_DISPLAY (XFRAME (frame)) == display
 15135             && (type == 2
 15136                 || (type == 1 && XSCROLL_BAR (bar)->horizontal)
 15137                 || (type == 0 && !XSCROLL_BAR (bar)->horizontal)))
 15138           return XSCROLL_BAR (bar);
 15139     }
 15140 
 15141   return NULL;
 15142 }
 15143 
 15144 
 15145 #if defined USE_LUCID
 15146 
 15147 /* Return the Lucid menu bar WINDOW is part of.  Return null
 15148    if WINDOW is not part of a menu bar.  */
 15149 
 15150 static Widget
 15151 x_window_to_menu_bar (Window window)
 15152 {
 15153   Lisp_Object tail, frame;
 15154 
 15155   FOR_EACH_FRAME (tail, frame)
 15156     if (FRAME_X_P (XFRAME (frame)))
 15157       {
 15158         Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
 15159 
 15160         if (menu_bar && xlwmenu_window_p (menu_bar, window))
 15161           return menu_bar;
 15162       }
 15163   return NULL;
 15164 }
 15165 
 15166 #endif /* USE_LUCID */
 15167 
 15168 
 15169 /************************************************************************
 15170                          Toolkit scroll bars
 15171  ************************************************************************/
 15172 
 15173 #ifdef USE_TOOLKIT_SCROLL_BARS
 15174 
 15175 static void x_send_scroll_bar_event (Lisp_Object, enum scroll_bar_part,
 15176                                      int, int, bool);
 15177 
 15178 /* Lisp window being scrolled.  Set when starting to interact with
 15179    a toolkit scroll bar, reset to nil when ending the interaction.  */
 15180 
 15181 static Lisp_Object window_being_scrolled;
 15182 
 15183 static Time
 15184 x_get_last_toolkit_time (struct x_display_info *dpyinfo)
 15185 {
 15186 #ifdef USE_X_TOOLKIT
 15187   return XtLastTimestampProcessed (dpyinfo->display);
 15188 #else
 15189   return dpyinfo->last_user_time;
 15190 #endif
 15191 }
 15192 
 15193 #ifndef USE_GTK
 15194 /* Id of action hook installed for scroll bars and horizontal scroll
 15195    bars.  */
 15196 
 15197 static XtActionHookId action_hook_id;
 15198 static XtActionHookId horizontal_action_hook_id;
 15199 
 15200 /* Whether this is an Xaw with arrow-scrollbars.  This should imply
 15201    that movements of 1/20 of the screen size are mapped to up/down.  */
 15202 
 15203 static Boolean xaw3d_arrow_scroll;
 15204 
 15205 /* Whether the drag scrolling maintains the mouse at the top of the
 15206    thumb.  If not, resizing the thumb needs to be done more carefully
 15207    to avoid jerkiness.  */
 15208 
 15209 static Boolean xaw3d_pick_top;
 15210 
 15211 /* Action hook installed via XtAppAddActionHook when toolkit scroll
 15212    bars are used..  The hook is responsible for detecting when
 15213    the user ends an interaction with the scroll bar, and generates
 15214    a `end-scroll' SCROLL_BAR_CLICK_EVENT' event if so.  */
 15215 
 15216 static void
 15217 xt_action_hook (Widget widget, XtPointer client_data, String action_name,
 15218                 XEvent *event, String *params, Cardinal *num_params)
 15219 {
 15220   bool scroll_bar_p;
 15221   const char *end_action;
 15222 
 15223 #ifdef USE_MOTIF
 15224   scroll_bar_p = XmIsScrollBar (widget);
 15225   end_action = "Release";
 15226 #else /* !USE_MOTIF i.e. use Xaw */
 15227   scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass);
 15228   end_action = "EndScroll";
 15229 #endif /* USE_MOTIF */
 15230 
 15231   if (scroll_bar_p
 15232       && strcmp (action_name, end_action) == 0
 15233       && WINDOWP (window_being_scrolled))
 15234     {
 15235       struct window *w;
 15236       struct scroll_bar *bar;
 15237 
 15238       x_send_scroll_bar_event (window_being_scrolled,
 15239                                scroll_bar_end_scroll, 0, 0, false);
 15240       w = XWINDOW (window_being_scrolled);
 15241       bar = XSCROLL_BAR (w->vertical_scroll_bar);
 15242 
 15243       if (bar->dragging != -1)
 15244         {
 15245           bar->dragging = -1;
 15246           /* The thumb size is incorrect while dragging: fix it.  */
 15247           set_vertical_scroll_bar (w);
 15248         }
 15249       window_being_scrolled = Qnil;
 15250 #if defined (USE_LUCID)
 15251       bar->last_seen_part = scroll_bar_nowhere;
 15252 #endif
 15253       /* Xt timeouts no longer needed.  */
 15254       toolkit_scroll_bar_interaction = false;
 15255     }
 15256 }
 15257 
 15258 
 15259 static void
 15260 xt_horizontal_action_hook (Widget widget, XtPointer client_data, String action_name,
 15261                            XEvent *event, String *params, Cardinal *num_params)
 15262 {
 15263   bool scroll_bar_p;
 15264   const char *end_action;
 15265 
 15266 #ifdef USE_MOTIF
 15267   scroll_bar_p = XmIsScrollBar (widget);
 15268   end_action = "Release";
 15269 #else /* !USE_MOTIF i.e. use Xaw */
 15270   scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass);
 15271   end_action = "EndScroll";
 15272 #endif /* USE_MOTIF */
 15273 
 15274   if (scroll_bar_p
 15275       && strcmp (action_name, end_action) == 0
 15276       && WINDOWP (window_being_scrolled))
 15277     {
 15278       struct window *w;
 15279       struct scroll_bar *bar;
 15280 
 15281       x_send_scroll_bar_event (window_being_scrolled,
 15282                                scroll_bar_end_scroll, 0, 0, true);
 15283       w = XWINDOW (window_being_scrolled);
 15284       if (!NILP (w->horizontal_scroll_bar))
 15285         {
 15286           bar = XSCROLL_BAR (w->horizontal_scroll_bar);
 15287           if (bar->dragging != -1)
 15288             {
 15289               bar->dragging = -1;
 15290               /* The thumb size is incorrect while dragging: fix it.  */
 15291               set_horizontal_scroll_bar (w);
 15292             }
 15293           window_being_scrolled = Qnil;
 15294 #if defined (USE_LUCID)
 15295           bar->last_seen_part = scroll_bar_nowhere;
 15296 #endif
 15297           /* Xt timeouts no longer needed.  */
 15298           toolkit_scroll_bar_interaction = false;
 15299         }
 15300     }
 15301 }
 15302 #endif /* not USE_GTK */
 15303 
 15304 /* Protect WINDOW from garbage collection until a matching scroll bar
 15305    message is received.  Return whether or not protection
 15306    succeeded.  */
 15307 static bool
 15308 x_protect_window_for_callback (struct x_display_info *dpyinfo,
 15309                                Lisp_Object window)
 15310 {
 15311   if (dpyinfo->n_protected_windows + 1
 15312       >= dpyinfo->protected_windows_max)
 15313     return false;
 15314 
 15315   dpyinfo->protected_windows[dpyinfo->n_protected_windows++]
 15316     = window;
 15317   return true;
 15318 }
 15319 
 15320 static Lisp_Object
 15321 x_unprotect_window_for_callback (struct x_display_info *dpyinfo)
 15322 {
 15323   Lisp_Object window;
 15324 
 15325   if (!dpyinfo->n_protected_windows)
 15326     return Qnil;
 15327 
 15328   window = dpyinfo->protected_windows[0];
 15329 
 15330   dpyinfo->n_protected_windows--;
 15331 
 15332   if (dpyinfo->n_protected_windows)
 15333     memmove (dpyinfo->protected_windows, &dpyinfo->protected_windows[1],
 15334              sizeof (Lisp_Object) * dpyinfo->n_protected_windows);
 15335 
 15336   return window;
 15337 }
 15338 
 15339 /* Send a client message with message type Xatom_Scrollbar for a
 15340    scroll action to the frame of WINDOW.  PART is a value identifying
 15341    the part of the scroll bar that was clicked on.  PORTION is the
 15342    amount to scroll of a whole of WHOLE.  */
 15343 
 15344 static void
 15345 x_send_scroll_bar_event (Lisp_Object window, enum scroll_bar_part part,
 15346                          int portion, int whole, bool horizontal)
 15347 {
 15348   XEvent event;
 15349   XClientMessageEvent *ev = &event.xclient;
 15350   struct window *w = XWINDOW (window);
 15351   struct frame *f = XFRAME (w->frame);
 15352   verify (INTPTR_WIDTH <= 64);
 15353 
 15354   /* Don't do anything if too many scroll bar events have been
 15355      sent but not received.  */
 15356   if (!x_protect_window_for_callback (FRAME_DISPLAY_INFO (f), window))
 15357     return;
 15358 
 15359   block_input ();
 15360   /* Construct a ClientMessage event to send to the frame.  */
 15361   ev->type = ClientMessage;
 15362   ev->message_type = (horizontal
 15363                       ? FRAME_DISPLAY_INFO (f)->Xatom_Horizontal_Scrollbar
 15364                       : FRAME_DISPLAY_INFO (f)->Xatom_Scrollbar);
 15365   ev->display = FRAME_X_DISPLAY (f);
 15366   ev->window = FRAME_X_WINDOW (f);
 15367   ev->format = 32;
 15368 
 15369   /* These messages formerly contained a pointer to the window, but
 15370      now that information is kept internally.  The following two
 15371      fields are thus zero.  */
 15372   ev->data.l[0] = 0;
 15373   ev->data.l[1] = 0;
 15374   ev->data.l[2] = part;
 15375   ev->data.l[3] = portion;
 15376   ev->data.l[4] = whole;
 15377 
 15378   /* Make Xt timeouts work while the scroll bar is active.  */
 15379 #ifdef USE_X_TOOLKIT
 15380   toolkit_scroll_bar_interaction = true;
 15381   x_activate_timeout_atimer ();
 15382 #endif
 15383 
 15384   /* Setting the event mask to zero means that the message will
 15385      be sent to the client that created the window, and if that
 15386      window no longer exists, no event will be sent.  */
 15387   XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), False,
 15388               NoEventMask, &event);
 15389   unblock_input ();
 15390 }
 15391 
 15392 
 15393 /* Transform a scroll bar ClientMessage EVENT to an Emacs input event
 15394    in *IEVENT.  */
 15395 
 15396 static void
 15397 x_scroll_bar_to_input_event (struct x_display_info *dpyinfo,
 15398                              const XEvent *event,
 15399                              struct input_event *ievent)
 15400 {
 15401   Lisp_Object window;
 15402 
 15403   /* Every time a scroll bar ClientMessage event is sent, the window
 15404      is pushed onto a queue that is traced for garbage collection.
 15405      Every time we need a window for a read scroll bar event, we
 15406      simply read from the other side of the queue.  */
 15407   window = x_unprotect_window_for_callback (dpyinfo);
 15408 
 15409   if (NILP (window))
 15410     {
 15411       /* This means we are getting extra scroll bar events for some
 15412          reason, and shouldn't be possible in practice.  */
 15413       EVENT_INIT (*ievent);
 15414       return;
 15415     }
 15416 
 15417   ievent->kind = SCROLL_BAR_CLICK_EVENT;
 15418   ievent->frame_or_window = window;
 15419   ievent->arg = Qnil;
 15420   ievent->timestamp = x_get_last_toolkit_time (dpyinfo);
 15421   ievent->code = 0;
 15422   ievent->part = event->xclient.data.l[2];
 15423   ievent->x = make_fixnum (event->xclient.data.l[3]);
 15424   ievent->y = make_fixnum (event->xclient.data.l[4]);
 15425   ievent->modifiers = 0;
 15426 }
 15427 
 15428 /* Transform a horizontal scroll bar ClientMessage EVENT to an Emacs
 15429    input event in *IEVENT.  */
 15430 
 15431 static void
 15432 x_horizontal_scroll_bar_to_input_event (struct x_display_info *dpyinfo,
 15433                                         const XEvent *event,
 15434                                         struct input_event *ievent)
 15435 {
 15436   Lisp_Object window;
 15437 
 15438   /* Every time a scroll bar ClientMessage event is sent, the window
 15439      is pushed onto a queue that is traced for garbage collection.
 15440      Every time we need a window for a read scroll bar event, we
 15441      simply read from the other side of the queue.  */
 15442   window = x_unprotect_window_for_callback (dpyinfo);
 15443 
 15444   if (NILP (window))
 15445     {
 15446       /* This means we are getting extra scroll bar events for some
 15447          reason, and shouldn't be possible in practice.  */
 15448       EVENT_INIT (*ievent);
 15449       return;
 15450     }
 15451 
 15452   ievent->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT;
 15453   ievent->frame_or_window = window;
 15454   ievent->arg = Qnil;
 15455   ievent->timestamp = x_get_last_toolkit_time (dpyinfo);
 15456   ievent->code = 0;
 15457   ievent->part = event->xclient.data.l[2];
 15458   ievent->x = make_fixnum (event->xclient.data.l[3]);
 15459   ievent->y = make_fixnum (event->xclient.data.l[4]);
 15460   ievent->modifiers = 0;
 15461 }
 15462 
 15463 
 15464 #ifdef USE_MOTIF
 15465 
 15466 /* Minimum and maximum values used for Motif scroll bars.  */
 15467 
 15468 #define XM_SB_MAX 10000000
 15469 
 15470 /* Scroll bar callback for Motif scroll bars.  WIDGET is the scroll
 15471    bar widget.  CLIENT_DATA is a pointer to the scroll_bar structure.
 15472    CALL_DATA is a pointer to a XmScrollBarCallbackStruct.  */
 15473 
 15474 static void
 15475 xm_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 15476 {
 15477   struct scroll_bar *bar = client_data;
 15478   XmScrollBarCallbackStruct *cs = call_data;
 15479   enum scroll_bar_part part = scroll_bar_nowhere;
 15480   bool horizontal = bar->horizontal;
 15481   int whole = 0, portion = 0;
 15482 
 15483   switch (cs->reason)
 15484     {
 15485     case XmCR_DECREMENT:
 15486       bar->dragging = -1;
 15487       part = horizontal ? scroll_bar_left_arrow : scroll_bar_up_arrow;
 15488       break;
 15489 
 15490     case XmCR_INCREMENT:
 15491       bar->dragging = -1;
 15492       part = horizontal ? scroll_bar_right_arrow : scroll_bar_down_arrow;
 15493       break;
 15494 
 15495     case XmCR_PAGE_DECREMENT:
 15496       bar->dragging = -1;
 15497       part = horizontal ? scroll_bar_before_handle : scroll_bar_above_handle;
 15498       break;
 15499 
 15500     case XmCR_PAGE_INCREMENT:
 15501       bar->dragging = -1;
 15502       part = horizontal ? scroll_bar_after_handle : scroll_bar_below_handle;
 15503       break;
 15504 
 15505     case XmCR_TO_TOP:
 15506       bar->dragging = -1;
 15507       part = horizontal ? scroll_bar_to_leftmost : scroll_bar_to_top;
 15508       break;
 15509 
 15510     case XmCR_TO_BOTTOM:
 15511       bar->dragging = -1;
 15512       part = horizontal ? scroll_bar_to_rightmost : scroll_bar_to_bottom;
 15513       break;
 15514 
 15515     case XmCR_DRAG:
 15516       {
 15517         int slider_size;
 15518 
 15519         block_input ();
 15520         XtVaGetValues (widget, XmNsliderSize, &slider_size, NULL);
 15521         unblock_input ();
 15522 
 15523         if (horizontal)
 15524           {
 15525             portion = bar->whole * ((float)cs->value / XM_SB_MAX);
 15526             whole = bar->whole * ((float)(XM_SB_MAX - slider_size) / XM_SB_MAX);
 15527             portion = min (portion, whole);
 15528             part = scroll_bar_horizontal_handle;
 15529           }
 15530         else
 15531           {
 15532             whole = XM_SB_MAX - slider_size;
 15533             portion = min (cs->value, whole);
 15534             part = scroll_bar_handle;
 15535           }
 15536 
 15537         bar->dragging = cs->value;
 15538       }
 15539       break;
 15540 
 15541     case XmCR_VALUE_CHANGED:
 15542       break;
 15543     };
 15544 
 15545   if (part != scroll_bar_nowhere)
 15546     {
 15547       window_being_scrolled = bar->window;
 15548       x_send_scroll_bar_event (bar->window, part, portion, whole,
 15549                                bar->horizontal);
 15550     }
 15551 }
 15552 
 15553 #elif defined USE_GTK
 15554 
 15555 /* Scroll bar callback for GTK scroll bars.  WIDGET is the scroll
 15556    bar widget.  DATA is a pointer to the scroll_bar structure. */
 15557 
 15558 static gboolean
 15559 xg_scroll_callback (GtkRange *range, GtkScrollType scroll,
 15560                     gdouble value, gpointer user_data)
 15561 {
 15562   int whole, portion;
 15563   struct scroll_bar *bar;
 15564   enum scroll_bar_part part;
 15565   GtkAdjustment *adj;
 15566   struct frame *f;
 15567   guint32 time;
 15568   struct x_display_info *dpyinfo;
 15569 
 15570   if (xg_ignore_gtk_scrollbar) return false;
 15571 
 15572   whole = 0;
 15573   portion = 0;
 15574   bar = user_data;
 15575   part = scroll_bar_nowhere;
 15576   adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range));
 15577   f = g_object_get_data (G_OBJECT (range), XG_FRAME_DATA);
 15578   time = gtk_get_current_event_time ();
 15579   dpyinfo = FRAME_DISPLAY_INFO (f);
 15580 
 15581   if (time != GDK_CURRENT_TIME)
 15582     x_display_set_last_user_time (dpyinfo, time, true,
 15583                                   true);
 15584 
 15585   switch (scroll)
 15586     {
 15587     case GTK_SCROLL_JUMP:
 15588       /* Buttons 1 2 or 3 must be grabbed.  */
 15589       if (FRAME_DISPLAY_INFO (f)->grabbed != 0
 15590           && FRAME_DISPLAY_INFO (f)->grabbed < (1 << 4))
 15591         {
 15592           if (bar->horizontal)
 15593             {
 15594               part = scroll_bar_horizontal_handle;
 15595               whole = (int)(gtk_adjustment_get_upper (adj) -
 15596                             gtk_adjustment_get_page_size (adj));
 15597               portion = min ((int)value, whole);
 15598               bar->dragging = portion;
 15599             }
 15600           else
 15601             {
 15602               part = scroll_bar_handle;
 15603               whole = gtk_adjustment_get_upper (adj) -
 15604                 gtk_adjustment_get_page_size (adj);
 15605               portion = min ((int)value, whole);
 15606               bar->dragging = portion;
 15607             }
 15608         }
 15609       break;
 15610     case GTK_SCROLL_STEP_BACKWARD:
 15611       part = (bar->horizontal
 15612               ? scroll_bar_left_arrow : scroll_bar_up_arrow);
 15613       bar->dragging = -1;
 15614       break;
 15615     case GTK_SCROLL_STEP_FORWARD:
 15616       part = (bar->horizontal
 15617               ? scroll_bar_right_arrow : scroll_bar_down_arrow);
 15618       bar->dragging = -1;
 15619       break;
 15620     case GTK_SCROLL_PAGE_BACKWARD:
 15621       part = (bar->horizontal
 15622               ? scroll_bar_before_handle : scroll_bar_above_handle);
 15623       bar->dragging = -1;
 15624       break;
 15625     case GTK_SCROLL_PAGE_FORWARD:
 15626       part = (bar->horizontal
 15627               ? scroll_bar_after_handle : scroll_bar_below_handle);
 15628       bar->dragging = -1;
 15629       break;
 15630     default:
 15631       break;
 15632     }
 15633 
 15634   if (part != scroll_bar_nowhere)
 15635     {
 15636       window_being_scrolled = bar->window;
 15637       x_send_scroll_bar_event (bar->window, part, portion, whole,
 15638                                bar->horizontal);
 15639     }
 15640 
 15641   return false;
 15642 }
 15643 
 15644 /* Callback for button release. Sets dragging to -1 when dragging is done.  */
 15645 
 15646 static gboolean
 15647 xg_end_scroll_callback (GtkWidget *widget,
 15648                         GdkEventButton *event,
 15649                         gpointer user_data)
 15650 {
 15651   struct scroll_bar *bar;
 15652 
 15653   bar = user_data;
 15654   bar->dragging = -1;
 15655 
 15656   if (WINDOWP (window_being_scrolled))
 15657     {
 15658       x_send_scroll_bar_event (window_being_scrolled,
 15659                                scroll_bar_end_scroll, 0, 0, bar->horizontal);
 15660       window_being_scrolled = Qnil;
 15661     }
 15662 
 15663   return false;
 15664 }
 15665 
 15666 
 15667 #else /* not USE_GTK and not USE_MOTIF */
 15668 
 15669 /* Xaw scroll bar callback.  Invoked when the thumb is dragged.
 15670    WIDGET is the scroll bar widget.  CLIENT_DATA is a pointer to the
 15671    scroll bar struct.  CALL_DATA is a pointer to a float saying where
 15672    the thumb is.  */
 15673 
 15674 static void
 15675 xaw_jump_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 15676 {
 15677   struct scroll_bar *bar = client_data;
 15678   float *top_addr = call_data;
 15679   float top = *top_addr;
 15680   float shown;
 15681   int whole, portion, height, width;
 15682   enum scroll_bar_part part;
 15683   bool horizontal = bar->horizontal;
 15684 
 15685   if (horizontal)
 15686     {
 15687       /* Get the size of the thumb, a value between 0 and 1.  */
 15688       block_input ();
 15689       XtVaGetValues (widget, XtNshown, &shown, XtNwidth, &width, NULL);
 15690       unblock_input ();
 15691 
 15692       if (shown < 1)
 15693         {
 15694           whole = bar->whole - (shown * bar->whole);
 15695           portion = min (top * bar->whole, whole);
 15696         }
 15697       else
 15698         {
 15699           whole = bar->whole;
 15700           portion = 0;
 15701         }
 15702 
 15703       part = scroll_bar_horizontal_handle;
 15704     }
 15705   else
 15706     {
 15707       /* Get the size of the thumb, a value between 0 and 1.  */
 15708       block_input ();
 15709       XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
 15710       unblock_input ();
 15711 
 15712       whole = 10000000;
 15713       portion = shown < 1 ? top * whole : 0;
 15714 
 15715       if (shown < 1 && (eabs (top + shown - 1) < 1.0f / height))
 15716         /* Some derivatives of Xaw refuse to shrink the thumb when you reach
 15717            the bottom, so we force the scrolling whenever we see that we're
 15718            too close to the bottom (in x_set_toolkit_scroll_bar_thumb
 15719            we try to ensure that we always stay two pixels away from the
 15720            bottom).  */
 15721         part = scroll_bar_down_arrow;
 15722       else
 15723         part = scroll_bar_handle;
 15724     }
 15725 
 15726   window_being_scrolled = bar->window;
 15727   bar->dragging = portion;
 15728   bar->last_seen_part = part;
 15729   x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal);
 15730 }
 15731 
 15732 
 15733 /* Xaw scroll bar callback.  Invoked for incremental scrolling.,
 15734    i.e. line or page up or down.  WIDGET is the Xaw scroll bar
 15735    widget.  CLIENT_DATA is a pointer to the scroll_bar structure for
 15736    the scroll bar.  CALL_DATA is an integer specifying the action that
 15737    has taken place.  Its magnitude is in the range 0..height of the
 15738    scroll bar.  Negative values mean scroll towards buffer start.
 15739    Values < height of scroll bar mean line-wise movement.  */
 15740 
 15741 static void
 15742 xaw_scroll_callback (Widget widget, XtPointer client_data, XtPointer call_data)
 15743 {
 15744   struct scroll_bar *bar = client_data;
 15745   /* The position really is stored cast to a pointer.  */
 15746   int position = (intptr_t) call_data;
 15747   Dimension height, width;
 15748   enum scroll_bar_part part;
 15749 
 15750   if (bar->horizontal)
 15751     {
 15752       /* Get the width of the scroll bar.  */
 15753       block_input ();
 15754       XtVaGetValues (widget, XtNwidth, &width, NULL);
 15755       unblock_input ();
 15756 
 15757       if (eabs (position) >= width)
 15758         part = (position < 0) ? scroll_bar_before_handle : scroll_bar_after_handle;
 15759 
 15760       /* If Xaw3d was compiled with ARROW_SCROLLBAR,
 15761          it maps line-movement to call_data = max(5, height/20).  */
 15762       else if (xaw3d_arrow_scroll && eabs (position) <= max (5, width / 20))
 15763         part = (position < 0) ? scroll_bar_left_arrow : scroll_bar_right_arrow;
 15764       else
 15765         part = scroll_bar_move_ratio;
 15766 
 15767       window_being_scrolled = bar->window;
 15768       bar->dragging = -1;
 15769       bar->last_seen_part = part;
 15770       x_send_scroll_bar_event (bar->window, part, position, width,
 15771                                bar->horizontal);
 15772     }
 15773   else
 15774     {
 15775 
 15776       /* Get the height of the scroll bar.  */
 15777       block_input ();
 15778       XtVaGetValues (widget, XtNheight, &height, NULL);
 15779       unblock_input ();
 15780 
 15781       if (eabs (position) >= height)
 15782         part = (position < 0) ? scroll_bar_above_handle : scroll_bar_below_handle;
 15783 
 15784       /* If Xaw3d was compiled with ARROW_SCROLLBAR,
 15785          it maps line-movement to call_data = max(5, height/20).  */
 15786       else if (xaw3d_arrow_scroll && eabs (position) <= max (5, height / 20))
 15787         part = (position < 0) ? scroll_bar_up_arrow : scroll_bar_down_arrow;
 15788       else
 15789         part = scroll_bar_move_ratio;
 15790 
 15791       window_being_scrolled = bar->window;
 15792       bar->dragging = -1;
 15793       bar->last_seen_part = part;
 15794       x_send_scroll_bar_event (bar->window, part, position, height,
 15795                                bar->horizontal);
 15796     }
 15797 }
 15798 
 15799 #endif /* not USE_GTK and not USE_MOTIF */
 15800 
 15801 #define SCROLL_BAR_NAME "verticalScrollBar"
 15802 #define SCROLL_BAR_HORIZONTAL_NAME "horizontalScrollBar"
 15803 
 15804 /* Create the widget for scroll bar BAR on frame F.  Record the widget
 15805    and X window of the scroll bar in BAR.  */
 15806 
 15807 #ifdef USE_GTK
 15808 static void
 15809 x_create_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
 15810 {
 15811   const char *scroll_bar_name = SCROLL_BAR_NAME;
 15812 
 15813   block_input ();
 15814   xg_create_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
 15815                         G_CALLBACK (xg_end_scroll_callback),
 15816                         scroll_bar_name);
 15817   unblock_input ();
 15818 }
 15819 
 15820 static void
 15821 x_create_horizontal_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
 15822 {
 15823   const char *scroll_bar_name = SCROLL_BAR_HORIZONTAL_NAME;
 15824 
 15825   block_input ();
 15826   xg_create_horizontal_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
 15827                                    G_CALLBACK (xg_end_scroll_callback),
 15828                                    scroll_bar_name);
 15829   unblock_input ();
 15830 }
 15831 
 15832 #else /* not USE_GTK */
 15833 
 15834 static void
 15835 x_create_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
 15836 {
 15837   Window xwindow;
 15838   Widget widget;
 15839   Arg av[20];
 15840   int ac = 0;
 15841   const char *scroll_bar_name = SCROLL_BAR_NAME;
 15842   unsigned long pixel;
 15843 
 15844   block_input ();
 15845 
 15846 #ifdef USE_MOTIF
 15847   /* Set resources.  Create the widget.  */
 15848   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 15849   XtSetArg (av[ac], XmNminimum, 0); ++ac;
 15850   XtSetArg (av[ac], XmNmaximum, XM_SB_MAX); ++ac;
 15851   XtSetArg (av[ac], XmNorientation, XmVERTICAL); ++ac;
 15852   XtSetArg (av[ac], XmNprocessingDirection, XmMAX_ON_BOTTOM), ++ac;
 15853   XtSetArg (av[ac], XmNincrement, 1); ++ac;
 15854   XtSetArg (av[ac], XmNpageIncrement, 1); ++ac;
 15855 
 15856   /* Note: "background" is the thumb color, and "trough" is the color behind
 15857      everything. */
 15858   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 15859   if (pixel != -1)
 15860     {
 15861       XtSetArg (av[ac], XmNbackground, pixel);
 15862       ++ac;
 15863     }
 15864 
 15865   pixel = f->output_data.x->scroll_bar_background_pixel;
 15866   if (pixel != -1)
 15867     {
 15868       XtSetArg (av[ac], XmNtroughColor, pixel);
 15869       ++ac;
 15870     }
 15871 
 15872   widget = XmCreateScrollBar (f->output_data.x->edit_widget,
 15873                               (char *) scroll_bar_name, av, ac);
 15874 
 15875   /* Add one callback for everything that can happen.  */
 15876   XtAddCallback (widget, XmNdecrementCallback, xm_scroll_callback,
 15877                  (XtPointer) bar);
 15878   XtAddCallback (widget, XmNdragCallback, xm_scroll_callback,
 15879                  (XtPointer) bar);
 15880   XtAddCallback (widget, XmNincrementCallback, xm_scroll_callback,
 15881                  (XtPointer) bar);
 15882   XtAddCallback (widget, XmNpageDecrementCallback, xm_scroll_callback,
 15883                  (XtPointer) bar);
 15884   XtAddCallback (widget, XmNpageIncrementCallback, xm_scroll_callback,
 15885                  (XtPointer) bar);
 15886   XtAddCallback (widget, XmNtoBottomCallback, xm_scroll_callback,
 15887                  (XtPointer) bar);
 15888   XtAddCallback (widget, XmNtoTopCallback, xm_scroll_callback,
 15889                  (XtPointer) bar);
 15890 
 15891   /* Realize the widget.  Only after that is the X window created.  */
 15892   XtRealizeWidget (widget);
 15893 
 15894   /* Set the cursor to an arrow.  I didn't find a resource to do that.
 15895      And I'm wondering why it hasn't an arrow cursor by default.  */
 15896   XDefineCursor (XtDisplay (widget), XtWindow (widget),
 15897                  f->output_data.x->nontext_cursor);
 15898 
 15899 #ifdef HAVE_XINPUT2
 15900   /* Ask for input extension button and motion events.  This lets us
 15901      send the proper `wheel-up' or `wheel-down' events to Emacs.  */
 15902   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
 15903     xi_select_scroll_bar_events (FRAME_DISPLAY_INFO (f),
 15904                                  XtWindow (widget));
 15905 #endif
 15906 #else /* !USE_MOTIF i.e. use Xaw */
 15907 
 15908   /* Set resources.  Create the widget.  The background of the
 15909      Xaw3d scroll bar widget is a little bit light for my taste.
 15910      We don't alter it here to let users change it according
 15911      to their taste with `emacs*verticalScrollBar.background: xxx'.  */
 15912   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 15913   XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac;
 15914   /* For smoother scrolling with Xaw3d   -sm */
 15915   /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
 15916 
 15917   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 15918   if (pixel != -1)
 15919     {
 15920       XtSetArg (av[ac], XtNforeground, pixel);
 15921       ++ac;
 15922     }
 15923 
 15924   pixel = f->output_data.x->scroll_bar_background_pixel;
 15925   if (pixel != -1)
 15926     {
 15927       XtSetArg (av[ac], XtNbackground, pixel);
 15928       ++ac;
 15929     }
 15930 
 15931   /* Top/bottom shadow colors.  */
 15932 
 15933   /* Allocate them, if necessary.  */
 15934   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1)
 15935     {
 15936       pixel = f->output_data.x->scroll_bar_background_pixel;
 15937       if (pixel != -1)
 15938         {
 15939           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 15940                                       FRAME_X_COLORMAP (f),
 15941                                       &pixel, 1.2, 0x8000))
 15942             pixel = -1;
 15943           f->output_data.x->scroll_bar_top_shadow_pixel = pixel;
 15944         }
 15945     }
 15946   if (f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 15947     {
 15948       pixel = f->output_data.x->scroll_bar_background_pixel;
 15949       if (pixel != -1)
 15950         {
 15951           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 15952                                       FRAME_X_COLORMAP (f),
 15953                                       &pixel, 0.6, 0x4000))
 15954             pixel = -1;
 15955           f->output_data.x->scroll_bar_bottom_shadow_pixel = pixel;
 15956         }
 15957     }
 15958 
 15959 #ifdef XtNbeNiceToColormap
 15960   /* Tell the toolkit about them.  */
 15961   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1
 15962       || f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 15963     /* We tried to allocate a color for the top/bottom shadow, and
 15964        failed, so tell Xaw3d to use dithering instead.   */
 15965     /* But only if we have a small colormap.  Xaw3d can allocate nice
 15966        colors itself.  */
 15967     {
 15968       XtSetArg (av[ac], (String) XtNbeNiceToColormap,
 15969                 DefaultDepthOfScreen (FRAME_X_SCREEN (f)) < 16);
 15970       ++ac;
 15971     }
 15972   else
 15973     /* Tell what colors Xaw3d should use for the top/bottom shadow, to
 15974        be more consistent with other emacs 3d colors, and since Xaw3d is
 15975        not good at dealing with allocation failure.  */
 15976     {
 15977       /* This tells Xaw3d to use real colors instead of dithering for
 15978          the shadows.  */
 15979       XtSetArg (av[ac], (String) XtNbeNiceToColormap, False);
 15980       ++ac;
 15981 
 15982       /* Specify the colors.  */
 15983       pixel = f->output_data.x->scroll_bar_top_shadow_pixel;
 15984       if (pixel != -1)
 15985         {
 15986           XtSetArg (av[ac], (String) XtNtopShadowPixel, pixel);
 15987           ++ac;
 15988         }
 15989       pixel = f->output_data.x->scroll_bar_bottom_shadow_pixel;
 15990       if (pixel != -1)
 15991         {
 15992           XtSetArg (av[ac], (String) XtNbottomShadowPixel, pixel);
 15993           ++ac;
 15994         }
 15995     }
 15996 #endif
 15997 
 15998   widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
 15999                            f->output_data.x->edit_widget, av, ac);
 16000 
 16001   {
 16002     char const *initial = "";
 16003     char const *val = initial;
 16004     XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val,
 16005 #ifdef XtNarrowScrollbars
 16006                    XtNarrowScrollbars, (XtPointer) &xaw3d_arrow_scroll,
 16007 #endif
 16008                    XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL);
 16009     if (xaw3d_arrow_scroll || val == initial)
 16010       { /* ARROW_SCROLL */
 16011         xaw3d_arrow_scroll = True;
 16012         /* Isn't that just a personal preference ?   --Stef */
 16013         XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL);
 16014       }
 16015   }
 16016 
 16017   /* Define callbacks.  */
 16018   XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar);
 16019   XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback,
 16020                  (XtPointer) bar);
 16021 
 16022   /* Realize the widget.  Only after that is the X window created.  */
 16023   XtRealizeWidget (widget);
 16024 
 16025 #endif /* !USE_MOTIF */
 16026 
 16027   /* Install an action hook that lets us detect when the user
 16028      finishes interacting with a scroll bar.  */
 16029   if (action_hook_id == 0)
 16030     action_hook_id = XtAppAddActionHook (Xt_app_con, xt_action_hook, 0);
 16031 
 16032   /* Remember X window and widget in the scroll bar vector.  */
 16033   SET_SCROLL_BAR_X_WIDGET (bar, widget);
 16034   xwindow = XtWindow (widget);
 16035   bar->x_window = xwindow;
 16036   bar->whole = 1;
 16037   bar->horizontal = false;
 16038 
 16039   unblock_input ();
 16040 }
 16041 
 16042 static void
 16043 x_create_horizontal_toolkit_scroll_bar (struct frame *f, struct scroll_bar *bar)
 16044 {
 16045   Window xwindow;
 16046   Widget widget;
 16047   Arg av[20];
 16048   int ac = 0;
 16049   const char *scroll_bar_name = SCROLL_BAR_HORIZONTAL_NAME;
 16050   unsigned long pixel;
 16051 
 16052   block_input ();
 16053 
 16054 #ifdef USE_MOTIF
 16055   /* Set resources.  Create the widget.  */
 16056   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 16057   XtSetArg (av[ac], XmNminimum, 0); ++ac;
 16058   XtSetArg (av[ac], XmNmaximum, XM_SB_MAX); ++ac;
 16059   XtSetArg (av[ac], XmNorientation, XmHORIZONTAL); ++ac;
 16060   XtSetArg (av[ac], XmNprocessingDirection, XmMAX_ON_RIGHT), ++ac;
 16061   XtSetArg (av[ac], XmNincrement, 1); ++ac;
 16062   XtSetArg (av[ac], XmNpageIncrement, 1); ++ac;
 16063 
 16064   /* Note: "background" is the thumb color, and "trough" is the color behind
 16065      everything. */
 16066   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 16067   if (pixel != -1)
 16068     {
 16069       XtSetArg (av[ac], XmNbackground, pixel);
 16070       ++ac;
 16071     }
 16072 
 16073   pixel = f->output_data.x->scroll_bar_background_pixel;
 16074   if (pixel != -1)
 16075     {
 16076       XtSetArg (av[ac], XmNtroughColor, pixel);
 16077       ++ac;
 16078     }
 16079 
 16080   widget = XmCreateScrollBar (f->output_data.x->edit_widget,
 16081                               (char *) scroll_bar_name, av, ac);
 16082 
 16083   /* Add one callback for everything that can happen.  */
 16084   XtAddCallback (widget, XmNdecrementCallback, xm_scroll_callback,
 16085                  (XtPointer) bar);
 16086   XtAddCallback (widget, XmNdragCallback, xm_scroll_callback,
 16087                  (XtPointer) bar);
 16088   XtAddCallback (widget, XmNincrementCallback, xm_scroll_callback,
 16089                  (XtPointer) bar);
 16090   XtAddCallback (widget, XmNpageDecrementCallback, xm_scroll_callback,
 16091                  (XtPointer) bar);
 16092   XtAddCallback (widget, XmNpageIncrementCallback, xm_scroll_callback,
 16093                  (XtPointer) bar);
 16094   XtAddCallback (widget, XmNtoBottomCallback, xm_scroll_callback,
 16095                  (XtPointer) bar);
 16096   XtAddCallback (widget, XmNtoTopCallback, xm_scroll_callback,
 16097                  (XtPointer) bar);
 16098 
 16099   /* Realize the widget.  Only after that is the X window created.  */
 16100   XtRealizeWidget (widget);
 16101 
 16102   /* Set the cursor to an arrow.  I didn't find a resource to do that.
 16103      And I'm wondering why it hasn't an arrow cursor by default.  */
 16104   XDefineCursor (XtDisplay (widget), XtWindow (widget),
 16105                  f->output_data.x->nontext_cursor);
 16106 
 16107 #ifdef HAVE_XINPUT2
 16108   /* Ask for input extension button and motion events.  This lets us
 16109      send the proper `wheel-up' or `wheel-down' events to Emacs.  */
 16110   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
 16111     xi_select_scroll_bar_events (FRAME_DISPLAY_INFO (f),
 16112                                  XtWindow (widget));
 16113 #endif
 16114 #else /* !USE_MOTIF i.e. use Xaw */
 16115 
 16116   /* Set resources.  Create the widget.  The background of the
 16117      Xaw3d scroll bar widget is a little bit light for my taste.
 16118      We don't alter it here to let users change it according
 16119      to their taste with `emacs*verticalScrollBar.background: xxx'.  */
 16120   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
 16121   XtSetArg (av[ac], XtNorientation, XtorientHorizontal); ++ac;
 16122   /* For smoother scrolling with Xaw3d   -sm */
 16123   /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
 16124 
 16125   pixel = f->output_data.x->scroll_bar_foreground_pixel;
 16126   if (pixel != -1)
 16127     {
 16128       XtSetArg (av[ac], XtNforeground, pixel);
 16129       ++ac;
 16130     }
 16131 
 16132   pixel = f->output_data.x->scroll_bar_background_pixel;
 16133   if (pixel != -1)
 16134     {
 16135       XtSetArg (av[ac], XtNbackground, pixel);
 16136       ++ac;
 16137     }
 16138 
 16139   /* Top/bottom shadow colors.  */
 16140 
 16141   /* Allocate them, if necessary.  */
 16142   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1)
 16143     {
 16144       pixel = f->output_data.x->scroll_bar_background_pixel;
 16145       if (pixel != -1)
 16146         {
 16147           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 16148                                       FRAME_X_COLORMAP (f),
 16149                                       &pixel, 1.2, 0x8000))
 16150             pixel = -1;
 16151           f->output_data.x->scroll_bar_top_shadow_pixel = pixel;
 16152         }
 16153     }
 16154   if (f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 16155     {
 16156       pixel = f->output_data.x->scroll_bar_background_pixel;
 16157       if (pixel != -1)
 16158         {
 16159           if (!x_alloc_lighter_color (f, FRAME_X_DISPLAY (f),
 16160                                       FRAME_X_COLORMAP (f),
 16161                                       &pixel, 0.6, 0x4000))
 16162             pixel = -1;
 16163           f->output_data.x->scroll_bar_bottom_shadow_pixel = pixel;
 16164         }
 16165     }
 16166 
 16167 #ifdef XtNbeNiceToColormap
 16168   /* Tell the toolkit about them.  */
 16169   if (f->output_data.x->scroll_bar_top_shadow_pixel == -1
 16170       || f->output_data.x->scroll_bar_bottom_shadow_pixel == -1)
 16171     /* We tried to allocate a color for the top/bottom shadow, and
 16172        failed, so tell Xaw3d to use dithering instead.   */
 16173     /* But only if we have a small colormap.  Xaw3d can allocate nice
 16174        colors itself.  */
 16175     {
 16176       XtSetArg (av[ac], (String) XtNbeNiceToColormap,
 16177                 DefaultDepthOfScreen (FRAME_X_SCREEN (f)) < 16);
 16178       ++ac;
 16179     }
 16180   else
 16181     /* Tell what colors Xaw3d should use for the top/bottom shadow, to
 16182        be more consistent with other emacs 3d colors, and since Xaw3d is
 16183        not good at dealing with allocation failure.  */
 16184     {
 16185       /* This tells Xaw3d to use real colors instead of dithering for
 16186          the shadows.  */
 16187       XtSetArg (av[ac], (String) XtNbeNiceToColormap, False);
 16188       ++ac;
 16189 
 16190       /* Specify the colors.  */
 16191       pixel = f->output_data.x->scroll_bar_top_shadow_pixel;
 16192       if (pixel != -1)
 16193         {
 16194           XtSetArg (av[ac], (String) XtNtopShadowPixel, pixel);
 16195           ++ac;
 16196         }
 16197       pixel = f->output_data.x->scroll_bar_bottom_shadow_pixel;
 16198       if (pixel != -1)
 16199         {
 16200           XtSetArg (av[ac], (String) XtNbottomShadowPixel, pixel);
 16201           ++ac;
 16202         }
 16203     }
 16204 #endif
 16205 
 16206   widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
 16207                            f->output_data.x->edit_widget, av, ac);
 16208 
 16209   {
 16210     char const *initial = "";
 16211     char const *val = initial;
 16212     XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val,
 16213 #ifdef XtNarrowScrollbars
 16214                    XtNarrowScrollbars, (XtPointer) &xaw3d_arrow_scroll,
 16215 #endif
 16216                    XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL);
 16217     if (xaw3d_arrow_scroll || val == initial)
 16218       { /* ARROW_SCROLL */
 16219         xaw3d_arrow_scroll = True;
 16220         /* Isn't that just a personal preference ?   --Stef */
 16221         XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL);
 16222       }
 16223   }
 16224 
 16225   /* Define callbacks.  */
 16226   XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar);
 16227   XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback,
 16228                  (XtPointer) bar);
 16229 
 16230   /* Realize the widget.  Only after that is the X window created.  */
 16231   XtRealizeWidget (widget);
 16232 
 16233 #endif /* !USE_MOTIF */
 16234 
 16235   /* Install an action hook that lets us detect when the user
 16236      finishes interacting with a scroll bar.  */
 16237   if (horizontal_action_hook_id == 0)
 16238    horizontal_action_hook_id
 16239      = XtAppAddActionHook (Xt_app_con, xt_horizontal_action_hook, 0);
 16240 
 16241   /* Remember X window and widget in the scroll bar vector.  */
 16242   SET_SCROLL_BAR_X_WIDGET (bar, widget);
 16243   xwindow = XtWindow (widget);
 16244   bar->x_window = xwindow;
 16245   bar->whole = 1;
 16246   bar->horizontal = true;
 16247 
 16248   unblock_input ();
 16249 }
 16250 #endif /* not USE_GTK */
 16251 
 16252 
 16253 /* Set the thumb size and position of scroll bar BAR.  We are currently
 16254    displaying PORTION out of a whole WHOLE, and our position POSITION.  */
 16255 
 16256 #ifdef USE_GTK
 16257 static void
 16258 x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, int whole)
 16259 {
 16260   xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 16261 }
 16262 
 16263 static void
 16264 x_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position, int whole)
 16265 {
 16266   xg_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole);
 16267 }
 16268 
 16269 #else /* not USE_GTK */
 16270 static void
 16271 x_set_toolkit_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position,
 16272                                 int whole)
 16273 {
 16274   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 16275   Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
 16276   float top, shown;
 16277 
 16278   block_input ();
 16279 
 16280 #ifdef USE_MOTIF
 16281 
 16282   if (scroll_bar_adjust_thumb_portion_p)
 16283     {
 16284       /* We use an estimate of 30 chars per line rather than the real
 16285          `portion' value.  This has the disadvantage that the thumb size
 16286          is not very representative, but it makes our life a lot easier.
 16287          Otherwise, we have to constantly adjust the thumb size, which
 16288          we can't always do quickly enough: while dragging, the size of
 16289          the thumb might prevent the user from dragging the thumb all the
 16290          way to the end.  but Motif and some versions of Xaw3d don't allow
 16291          updating the thumb size while dragging.  Also, even if we can update
 16292          its size, the update will often happen too late.
 16293          If you don't believe it, check out revision 1.650 of xterm.c to see
 16294          what hoops we were going through and the still poor behavior we got.  */
 16295       portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30;
 16296       /* When the thumb is at the bottom, position == whole.
 16297          So we need to increase `whole' to make space for the thumb.  */
 16298       whole += portion;
 16299     }
 16300 
 16301   if (whole <= 0)
 16302     top = 0, shown = 1;
 16303   else
 16304     {
 16305       top = (float) position / whole;
 16306       shown = (float) portion / whole;
 16307     }
 16308 
 16309   if (bar->dragging == -1)
 16310     {
 16311       int size, value;
 16312 
 16313       /* Slider size.  Must be in the range [1 .. MAX - MIN] where MAX
 16314          is the scroll bar's maximum and MIN is the scroll bar's minimum
 16315          value.  */
 16316       size = clip_to_bounds (1, shown * XM_SB_MAX, XM_SB_MAX);
 16317 
 16318       /* Position.  Must be in the range [MIN .. MAX - SLIDER_SIZE].  */
 16319       value = top * XM_SB_MAX;
 16320       value = min (value, XM_SB_MAX - size);
 16321 
 16322       XmScrollBarSetValues (widget, value, size, 0, 0, False);
 16323     }
 16324 #else /* !USE_MOTIF i.e. use Xaw */
 16325 
 16326   if (whole == 0)
 16327     top = 0, shown = 1;
 16328   else
 16329     {
 16330       top = (float) position / whole;
 16331       shown = (float) portion / whole;
 16332     }
 16333 
 16334   {
 16335     float old_top, old_shown;
 16336     Dimension height;
 16337     XtVaGetValues (widget,
 16338                    XtNtopOfThumb, &old_top,
 16339                    XtNshown, &old_shown,
 16340                    XtNheight, &height,
 16341                    NULL);
 16342 
 16343     /* Massage the top+shown values.  */
 16344     if (bar->dragging == -1 || bar->last_seen_part == scroll_bar_down_arrow)
 16345       top = max (0, min (1, top));
 16346     else
 16347       top = old_top;
 16348 #if ! defined (HAVE_XAW3D)
 16349     /* With Xaw, 'top' values too closer to 1.0 may
 16350        cause the thumb to disappear.  Fix that.  */
 16351     top = min (top, 0.99f);
 16352 #endif
 16353     /* Keep two pixels available for moving the thumb down.  */
 16354     shown = max (0, min (1 - top - (2.0f / height), shown));
 16355 #if ! defined (HAVE_XAW3D)
 16356     /* Likewise with too small 'shown'.  */
 16357     shown = max (shown, 0.01f);
 16358 #endif
 16359 
 16360     /* If the call to XawScrollbarSetThumb below doesn't seem to
 16361        work, check that 'NARROWPROTO' is defined in src/config.h.
 16362        If this is not so, most likely you need to fix configure.  */
 16363     if (top != old_top || shown != old_shown)
 16364       {
 16365         if (bar->dragging == -1)
 16366           XawScrollbarSetThumb (widget, top, shown);
 16367         else
 16368           {
 16369             /* Try to make the scrolling a tad smoother.  */
 16370             if (!xaw3d_pick_top)
 16371               shown = min (shown, old_shown);
 16372 
 16373             XawScrollbarSetThumb (widget, top, shown);
 16374           }
 16375       }
 16376   }
 16377 #endif /* !USE_MOTIF */
 16378 
 16379   unblock_input ();
 16380 }
 16381 
 16382 static void
 16383 x_set_toolkit_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion, int position,
 16384                                 int whole)
 16385 {
 16386   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 16387   Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
 16388   float top, shown;
 16389 
 16390   block_input ();
 16391 
 16392 #ifdef USE_MOTIF
 16393   bar->whole = whole;
 16394   shown = (float) portion / whole;
 16395   top = (float) position / (whole - portion);
 16396   {
 16397     int size = clip_to_bounds (1, shown * XM_SB_MAX, XM_SB_MAX);
 16398     int value = clip_to_bounds (0, top * (XM_SB_MAX - size), XM_SB_MAX - size);
 16399 
 16400     XmScrollBarSetValues (widget, value, size, 0, 0, False);
 16401   }
 16402 #else /* !USE_MOTIF i.e. use Xaw */
 16403   bar->whole = whole;
 16404   if (whole == 0)
 16405     top = 0, shown = 1;
 16406   else
 16407     {
 16408       top = (float) position / whole;
 16409       shown = (float) portion / whole;
 16410     }
 16411 
 16412   {
 16413     float old_top, old_shown;
 16414     Dimension height;
 16415     XtVaGetValues (widget,
 16416                    XtNtopOfThumb, &old_top,
 16417                    XtNshown, &old_shown,
 16418                    XtNheight, &height,
 16419                    NULL);
 16420 
 16421 #if false
 16422     /* Massage the top+shown values.  */
 16423     if (bar->dragging == -1 || bar->last_seen_part == scroll_bar_down_arrow)
 16424       top = max (0, min (1, top));
 16425     else
 16426       top = old_top;
 16427 #if ! defined (HAVE_XAW3D)
 16428     /* With Xaw, 'top' values too closer to 1.0 may
 16429        cause the thumb to disappear.  Fix that.  */
 16430     top = min (top, 0.99f);
 16431 #endif
 16432     /* Keep two pixels available for moving the thumb down.  */
 16433     shown = max (0, min (1 - top - (2.0f / height), shown));
 16434 #if ! defined (HAVE_XAW3D)
 16435     /* Likewise with too small 'shown'.  */
 16436     shown = max (shown, 0.01f);
 16437 #endif
 16438 #endif
 16439 
 16440     /* If the call to XawScrollbarSetThumb below doesn't seem to
 16441        work, check that 'NARROWPROTO' is defined in src/config.h.
 16442        If this is not so, most likely you need to fix configure.  */
 16443     XawScrollbarSetThumb (widget, top, shown);
 16444 #if false
 16445     if (top != old_top || shown != old_shown)
 16446       {
 16447         if (bar->dragging == -1)
 16448           XawScrollbarSetThumb (widget, top, shown);
 16449         else
 16450           {
 16451             /* Try to make the scrolling a tad smoother.  */
 16452             if (!xaw3d_pick_top)
 16453               shown = min (shown, old_shown);
 16454 
 16455             XawScrollbarSetThumb (widget, top, shown);
 16456           }
 16457       }
 16458 #endif
 16459   }
 16460 #endif /* !USE_MOTIF */
 16461 
 16462   unblock_input ();
 16463 }
 16464 #endif /* not USE_GTK */
 16465 
 16466 #endif /* USE_TOOLKIT_SCROLL_BARS */
 16467 
 16468 
 16469 
 16470 /************************************************************************
 16471                          Scroll bars, general
 16472  ************************************************************************/
 16473 
 16474 /* Create a scroll bar and return the scroll bar vector for it.  W is
 16475    the Emacs window on which to create the scroll bar. TOP, LEFT,
 16476    WIDTH and HEIGHT are the pixel coordinates and dimensions of the
 16477    scroll bar. */
 16478 
 16479 static struct scroll_bar *
 16480 x_scroll_bar_create (struct window *w, int top, int left,
 16481                      int width, int height, bool horizontal)
 16482 {
 16483   struct frame *f = XFRAME (w->frame);
 16484   struct scroll_bar *bar = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, prev,
 16485                                                   PVEC_OTHER);
 16486   Lisp_Object barobj;
 16487 
 16488   block_input ();
 16489 
 16490 #ifdef USE_TOOLKIT_SCROLL_BARS
 16491   if (horizontal)
 16492     x_create_horizontal_toolkit_scroll_bar (f, bar);
 16493   else
 16494     x_create_toolkit_scroll_bar (f, bar);
 16495 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16496   {
 16497     XSetWindowAttributes a;
 16498     unsigned long mask;
 16499     Window window;
 16500 
 16501     a.event_mask = (ButtonPressMask | ButtonReleaseMask
 16502                     | ButtonMotionMask | PointerMotionHintMask);
 16503     a.cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
 16504 
 16505     mask = (CWEventMask | CWCursor);
 16506 
 16507     /* Clear the area of W that will serve as a scroll bar.  This is
 16508        for the case that a window has been split horizontally.  In
 16509        this case, no clear_frame is generated to reduce flickering.  */
 16510     if (width > 0 && window_box_height (w) > 0)
 16511       x_clear_area (f, left, top, width, window_box_height (w));
 16512 
 16513     /* Create an input only window.  Scroll bar contents are drawn to
 16514        the frame window itself, so they can be double buffered and
 16515        synchronized using the same mechanism as the frame.  */
 16516     window = XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 16517                             /* Position and size of scroll bar.  */
 16518                             left, top, width, height,
 16519                             /* Border width.  */
 16520                             0,
 16521                             /* Depth.  */
 16522                             CopyFromParent,
 16523                             /* Class.  */
 16524                             InputOnly,
 16525                             /* Visual class.  */
 16526                             CopyFromParent,
 16527                              /* Attributes.  */
 16528                             mask, &a);
 16529 
 16530 #ifdef HAVE_XINPUT2
 16531   /* Ask for input extension button and motion events.  This lets us
 16532      send the proper `wheel-up' or `wheel-down' events to Emacs.  */
 16533   if (FRAME_DISPLAY_INFO (f)->supports_xi2)
 16534     xi_select_scroll_bar_events (FRAME_DISPLAY_INFO (f),
 16535                                  window);
 16536 #endif
 16537 
 16538     bar->x_window = window;
 16539   }
 16540 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16541 
 16542   XSETWINDOW (bar->window, w);
 16543   bar->top = top;
 16544   bar->left = left;
 16545   bar->width = width;
 16546   bar->height = height;
 16547   bar->start = 0;
 16548   bar->end = 0;
 16549   bar->dragging = -1;
 16550   bar->horizontal = horizontal;
 16551 #if defined (USE_TOOLKIT_SCROLL_BARS) && defined (USE_LUCID)
 16552   bar->last_seen_part = scroll_bar_nowhere;
 16553 #endif
 16554 
 16555   /* Add bar to its frame's list of scroll bars.  */
 16556   bar->next = FRAME_SCROLL_BARS (f);
 16557   bar->prev = Qnil;
 16558   XSETVECTOR (barobj, bar);
 16559   fset_scroll_bars (f, barobj);
 16560   if (!NILP (bar->next))
 16561     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 16562 
 16563   /* Map the window/widget.  */
 16564 #ifdef USE_TOOLKIT_SCROLL_BARS
 16565   {
 16566 #ifdef USE_GTK
 16567     if (horizontal)
 16568       xg_update_horizontal_scrollbar_pos (f, bar->x_window, top,
 16569                                           left, width, max (height, 1));
 16570     else
 16571       xg_update_scrollbar_pos (f, bar->x_window, top,
 16572                                left, width, max (height, 1));
 16573 #else /* not USE_GTK */
 16574     Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
 16575     XtConfigureWidget (scroll_bar, left, top, width, max (height, 1), 0);
 16576     XtMapWidget (scroll_bar);
 16577     /* Don't obscure any child frames.  */
 16578     XLowerWindow (FRAME_X_DISPLAY (f), bar->x_window);
 16579 #endif /* not USE_GTK */
 16580     }
 16581 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16582   XMapWindow (FRAME_X_DISPLAY (f), bar->x_window);
 16583   /* Don't obscure any child frames.  */
 16584   XLowerWindow (FRAME_X_DISPLAY (f), bar->x_window);
 16585 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16586 
 16587   unblock_input ();
 16588   return bar;
 16589 }
 16590 
 16591 
 16592 #ifndef USE_TOOLKIT_SCROLL_BARS
 16593 
 16594 /* Draw BAR's handle in the proper position.
 16595 
 16596    If the handle is already drawn from START to END, don't bother
 16597    redrawing it, unless REBUILD; in that case, always
 16598    redraw it.  (REBUILD is handy for drawing the handle after expose
 16599    events.)
 16600 
 16601    Normally, we want to constrain the start and end of the handle to
 16602    fit inside its rectangle, but if the user is dragging the scroll
 16603    bar handle, we want to let them drag it down all the way, so that
 16604    the bar's top is as far down as it goes; otherwise, there's no way
 16605    to move to the very end of the buffer.  */
 16606 
 16607 static void
 16608 x_scroll_bar_set_handle (struct scroll_bar *bar, int start, int end,
 16609                          bool rebuild)
 16610 {
 16611   bool dragging;
 16612   struct frame *f;
 16613   Drawable w;
 16614   GC gc;
 16615   int inside_width, inside_height, top_range, length;
 16616 
 16617   /* If the display is already accurate, do nothing.  */
 16618   if (! rebuild
 16619       && start == bar->start
 16620       && end == bar->end)
 16621     return;
 16622 
 16623   f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 16624   dragging = bar->dragging != -1;
 16625   gc = f->output_data.x->normal_gc;
 16626   w = FRAME_X_DRAWABLE (f);
 16627 
 16628   block_input ();
 16629 
 16630   inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f, bar->width);
 16631   inside_height = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, bar->height);
 16632   top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
 16633 
 16634   /* Make sure the values are reasonable, and try to preserve
 16635      the distance between start and end.  */
 16636   length = end - start;
 16637 
 16638   if (start < 0)
 16639     start = 0;
 16640   else if (start > top_range)
 16641     start = top_range;
 16642   end = start + length;
 16643 
 16644   if (end < start)
 16645     end = start;
 16646   else if (end > top_range && ! dragging)
 16647     end = top_range;
 16648 
 16649   /* Store the adjusted setting in the scroll bar.  */
 16650   bar->start = start;
 16651   bar->end = end;
 16652 
 16653   /* Clip the end position, just for display.  */
 16654   if (end > top_range)
 16655     end = top_range;
 16656 
 16657   /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
 16658      below top positions, to make sure the handle is always at least
 16659      that many pixels tall.  */
 16660   end += VERTICAL_SCROLL_BAR_MIN_HANDLE;
 16661 
 16662   /* Draw the empty space above the handle.  Note that we can't clear
 16663      zero-height areas; that means "clear to end of window."  */
 16664   if ((inside_width > 0) && (start > 0))
 16665     {
 16666       if (f->output_data.x->scroll_bar_background_pixel != -1)
 16667         XSetForeground (FRAME_X_DISPLAY (f), gc,
 16668                         f->output_data.x->scroll_bar_background_pixel);
 16669       else
 16670         XSetForeground (FRAME_X_DISPLAY (f), gc,
 16671                         FRAME_BACKGROUND_PIXEL (f));
 16672 
 16673       XFillRectangle (FRAME_X_DISPLAY (f), w, gc,
 16674                       bar->left + VERTICAL_SCROLL_BAR_LEFT_BORDER,
 16675                       bar->top + VERTICAL_SCROLL_BAR_TOP_BORDER,
 16676                       inside_width, start);
 16677 
 16678       XSetForeground (FRAME_X_DISPLAY (f), gc,
 16679                       FRAME_FOREGROUND_PIXEL (f));
 16680     }
 16681 
 16682   /* Change to proper foreground color if one is specified.  */
 16683   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 16684     XSetForeground (FRAME_X_DISPLAY (f), gc,
 16685                     f->output_data.x->scroll_bar_foreground_pixel);
 16686 
 16687   /* Draw the handle itself.  */
 16688   XFillRectangle (FRAME_X_DISPLAY (f), w, gc,
 16689                   /* x, y, width, height */
 16690                   bar->left + VERTICAL_SCROLL_BAR_LEFT_BORDER,
 16691                   bar->top + VERTICAL_SCROLL_BAR_TOP_BORDER + start,
 16692                   inside_width, end - start);
 16693 
 16694 
 16695   /* Draw the empty space below the handle.  Note that we can't
 16696      clear zero-height areas; that means "clear to end of window." */
 16697   if ((inside_width > 0) && (end < inside_height))
 16698     {
 16699       if (f->output_data.x->scroll_bar_background_pixel != -1)
 16700         XSetForeground (FRAME_X_DISPLAY (f), gc,
 16701                         f->output_data.x->scroll_bar_background_pixel);
 16702       else
 16703         XSetForeground (FRAME_X_DISPLAY (f), gc,
 16704                         FRAME_BACKGROUND_PIXEL (f));
 16705 
 16706       XFillRectangle (FRAME_X_DISPLAY (f), w, gc,
 16707                       bar->left + VERTICAL_SCROLL_BAR_LEFT_BORDER,
 16708                       bar->top + VERTICAL_SCROLL_BAR_TOP_BORDER + end,
 16709                       inside_width, inside_height - end);
 16710 
 16711       XSetForeground (FRAME_X_DISPLAY (f), gc,
 16712                       FRAME_FOREGROUND_PIXEL (f));
 16713     }
 16714 
 16715   /* Restore the foreground color of the GC if we changed it above.  */
 16716   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 16717     XSetForeground (FRAME_X_DISPLAY (f), gc,
 16718                     FRAME_FOREGROUND_PIXEL (f));
 16719 
 16720   unblock_input ();
 16721 }
 16722 
 16723 #endif /* !USE_TOOLKIT_SCROLL_BARS */
 16724 
 16725 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
 16726    nil.  */
 16727 
 16728 static void
 16729 x_scroll_bar_remove (struct scroll_bar *bar)
 16730 {
 16731   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 16732   block_input ();
 16733 
 16734 #ifdef USE_TOOLKIT_SCROLL_BARS
 16735 #ifdef USE_GTK
 16736   xg_remove_scroll_bar (f, bar->x_window);
 16737 #else /* not USE_GTK */
 16738   XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
 16739 #endif /* not USE_GTK */
 16740 #else
 16741   XDestroyWindow (FRAME_X_DISPLAY (f), bar->x_window);
 16742 #endif
 16743 
 16744   /* Dissociate this scroll bar from its window.  */
 16745   if (bar->horizontal)
 16746     wset_horizontal_scroll_bar (XWINDOW (bar->window), Qnil);
 16747   else
 16748     wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
 16749 
 16750   unblock_input ();
 16751 }
 16752 
 16753 
 16754 /* Set the handle of the vertical scroll bar for WINDOW to indicate
 16755    that we are displaying PORTION characters out of a total of WHOLE
 16756    characters, starting at POSITION.  If WINDOW has no scroll bar,
 16757    create one.  */
 16758 
 16759 static void
 16760 XTset_vertical_scroll_bar (struct window *w, int portion, int whole, int position)
 16761 {
 16762   struct frame *f = XFRAME (w->frame);
 16763   Lisp_Object barobj;
 16764   struct scroll_bar *bar;
 16765   int top, height, left, width;
 16766   int window_y, window_height;
 16767 
 16768   /* Get window dimensions.  */
 16769   window_box (w, ANY_AREA, 0, &window_y, 0, &window_height);
 16770   top = window_y;
 16771   height = window_height;
 16772   left = WINDOW_SCROLL_BAR_AREA_X (w);
 16773   width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
 16774 
 16775   /* Does the scroll bar exist yet?  */
 16776   if (NILP (w->vertical_scroll_bar))
 16777     {
 16778       if (width > 0 && height > 0)
 16779         {
 16780           block_input ();
 16781           x_clear_area (f, left, top, width, height);
 16782           unblock_input ();
 16783         }
 16784 
 16785       bar = x_scroll_bar_create (w, top, left, width, max (height, 1), false);
 16786 #ifndef USE_TOOLKIT_SCROLL_BARS
 16787       /* Since non-toolkit scroll bars don't display their contents to
 16788          a dedicated window, no expose event will be generated.
 16789          Redraw the scroll bar manually.  */
 16790       x_scroll_bar_redraw (bar);
 16791 #endif
 16792     }
 16793   else
 16794     {
 16795       /* It may just need to be moved and resized.  */
 16796       unsigned int mask = 0;
 16797 
 16798       bar = XSCROLL_BAR (w->vertical_scroll_bar);
 16799 
 16800       block_input ();
 16801 
 16802       if (left != bar->left)
 16803         mask |= CWX;
 16804       if (top != bar->top)
 16805         mask |= CWY;
 16806       if (width != bar->width)
 16807         mask |= CWWidth;
 16808       if (height != bar->height)
 16809         mask |= CWHeight;
 16810 
 16811 #ifdef USE_TOOLKIT_SCROLL_BARS
 16812 
 16813       /* Move/size the scroll bar widget.  */
 16814       if (mask)
 16815         {
 16816           /* Since toolkit scroll bars are smaller than the space reserved
 16817              for them on the frame, we have to clear "under" them.  */
 16818           if (width > 0 && height > 0)
 16819             x_clear_area (f, left, top, width, height);
 16820 #ifdef USE_GTK
 16821           xg_update_scrollbar_pos (f, bar->x_window, top,
 16822                                    left, width, max (height, 1));
 16823 #else /* not USE_GTK */
 16824           XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
 16825                              left, top, width, max (height, 1), 0);
 16826 #endif /* not USE_GTK */
 16827         }
 16828 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16829 
 16830       /* Move/size the scroll bar window.  */
 16831       if (mask)
 16832         {
 16833           XWindowChanges wc;
 16834 
 16835           wc.x = left;
 16836           wc.y = top;
 16837           wc.width = width;
 16838           wc.height = height;
 16839           XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window,
 16840                             mask, &wc);
 16841         }
 16842 
 16843 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16844 
 16845       /* Remember new settings.  */
 16846       bar->left = left;
 16847       bar->top = top;
 16848       bar->width = width;
 16849       bar->height = height;
 16850 
 16851 #ifndef USE_TOOLKIT_SCROLL_BARS
 16852       /* Redraw the scroll bar.  */
 16853       x_scroll_bar_redraw (bar);
 16854 #endif
 16855 
 16856       unblock_input ();
 16857     }
 16858 
 16859 #ifdef USE_TOOLKIT_SCROLL_BARS
 16860   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 16861 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16862   /* Set the scroll bar's current state, unless we're currently being
 16863      dragged.  */
 16864   if (bar->dragging == -1)
 16865     {
 16866       int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height);
 16867 
 16868       if (whole == 0)
 16869         x_scroll_bar_set_handle (bar, 0, top_range, false);
 16870       else
 16871         {
 16872           int start = ((double) position * top_range) / whole;
 16873           int end = ((double) (position + portion) * top_range) / whole;
 16874           x_scroll_bar_set_handle (bar, start, end, false);
 16875         }
 16876     }
 16877 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16878 
 16879   XSETVECTOR (barobj, bar);
 16880   wset_vertical_scroll_bar (w, barobj);
 16881 }
 16882 
 16883 
 16884 static void
 16885 XTset_horizontal_scroll_bar (struct window *w, int portion, int whole, int position)
 16886 {
 16887   struct frame *f = XFRAME (w->frame);
 16888   Lisp_Object barobj;
 16889   struct scroll_bar *bar;
 16890   int top, height, left, width;
 16891   int window_x, window_width;
 16892   int pixel_width = WINDOW_PIXEL_WIDTH (w);
 16893 
 16894   /* Get window dimensions.  */
 16895   window_box (w, ANY_AREA, &window_x, 0, &window_width, 0);
 16896   left = window_x;
 16897   width = window_width;
 16898   top = WINDOW_SCROLL_BAR_AREA_Y (w);
 16899   height = WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
 16900 
 16901   /* Does the scroll bar exist yet?  */
 16902   if (NILP (w->horizontal_scroll_bar))
 16903     {
 16904       if (width > 0 && height > 0)
 16905         {
 16906           block_input ();
 16907 
 16908           /* Clear also part between window_width and
 16909              WINDOW_PIXEL_WIDTH.  */
 16910           x_clear_area (f, left, top, pixel_width, height);
 16911           unblock_input ();
 16912         }
 16913 
 16914       bar = x_scroll_bar_create (w, top, left, width, height, true);
 16915     }
 16916   else
 16917     {
 16918       /* It may just need to be moved and resized.  */
 16919       unsigned int mask = 0;
 16920 
 16921       bar = XSCROLL_BAR (w->horizontal_scroll_bar);
 16922 
 16923       block_input ();
 16924 
 16925       if (left != bar->left)
 16926         mask |= CWX;
 16927       if (top != bar->top)
 16928         mask |= CWY;
 16929       if (width != bar->width)
 16930         mask |= CWWidth;
 16931       if (height != bar->height)
 16932         mask |= CWHeight;
 16933 
 16934 #ifdef USE_TOOLKIT_SCROLL_BARS
 16935       /* Move/size the scroll bar widget.  */
 16936       if (mask)
 16937         {
 16938           /* Since toolkit scroll bars are smaller than the space reserved
 16939              for them on the frame, we have to clear "under" them.  */
 16940           if (width > 0 && height > 0)
 16941             x_clear_area (f,
 16942                           WINDOW_LEFT_EDGE_X (w), top,
 16943                           pixel_width - WINDOW_RIGHT_DIVIDER_WIDTH (w), height);
 16944 #ifdef USE_GTK
 16945           xg_update_horizontal_scrollbar_pos (f, bar->x_window, top, left,
 16946                                               width, height);
 16947 #else /* not USE_GTK */
 16948           XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
 16949                              left, top, width, height, 0);
 16950 #endif /* not USE_GTK */
 16951         }
 16952 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16953 
 16954       /* Clear areas not covered by the scroll bar because it's not as
 16955          wide as the area reserved for it.  This makes sure a
 16956          previous mode line display is cleared after C-x 2 C-x 1, for
 16957          example.  */
 16958       {
 16959         int area_height = WINDOW_CONFIG_SCROLL_BAR_HEIGHT (w);
 16960         int rest = area_height - height;
 16961         if (rest > 0 && width > 0)
 16962           x_clear_area (f, left, top, width, rest);
 16963       }
 16964 
 16965       /* Move/size the scroll bar window.  */
 16966       if (mask)
 16967         {
 16968           XWindowChanges wc;
 16969 
 16970           wc.x = left;
 16971           wc.y = top;
 16972           wc.width = width;
 16973           wc.height = height;
 16974           XConfigureWindow (FRAME_X_DISPLAY (f), bar->x_window,
 16975                             mask, &wc);
 16976         }
 16977 
 16978 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 16979 
 16980       /* Remember new settings.  */
 16981       bar->left = left;
 16982       bar->top = top;
 16983       bar->width = width;
 16984       bar->height = height;
 16985 
 16986       unblock_input ();
 16987     }
 16988 
 16989 #ifdef USE_TOOLKIT_SCROLL_BARS
 16990   x_set_toolkit_horizontal_scroll_bar_thumb (bar, portion, position, whole);
 16991 #else /* not USE_TOOLKIT_SCROLL_BARS */
 16992   /* Set the scroll bar's current state, unless we're currently being
 16993      dragged.  */
 16994   if (bar->dragging == -1)
 16995     {
 16996       int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, width);
 16997 
 16998       if (whole == 0)
 16999         x_scroll_bar_set_handle (bar, 0, left_range, false);
 17000       else
 17001         {
 17002           int start = ((double) position * left_range) / whole;
 17003           int end = ((double) (position + portion) * left_range) / whole;
 17004           x_scroll_bar_set_handle (bar, start, end, false);
 17005         }
 17006     }
 17007 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 17008 
 17009   XSETVECTOR (barobj, bar);
 17010   wset_horizontal_scroll_bar (w, barobj);
 17011 }
 17012 
 17013 
 17014 /* The following three hooks are used when we're doing a thorough
 17015    redisplay of the frame.  We don't explicitly know which scroll bars
 17016    are going to be deleted, because keeping track of when windows go
 17017    away is a real pain - "Can you say set-window-configuration, boys
 17018    and girls?"  Instead, we just assert at the beginning of redisplay
 17019    that *all* scroll bars are to be removed, and then save a scroll bar
 17020    from the fiery pit when we actually redisplay its window.  */
 17021 
 17022 /* Arrange for all scroll bars on FRAME to be removed at the next call
 17023    to `*judge_scroll_bars_hook'.  A scroll bar may be spared if
 17024    `*redeem_scroll_bar_hook' is applied to its window before the judgment.  */
 17025 
 17026 static void
 17027 XTcondemn_scroll_bars (struct frame *frame)
 17028 {
 17029   if (!NILP (FRAME_SCROLL_BARS (frame)))
 17030     {
 17031       if (!NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
 17032         {
 17033           /* Prepend scrollbars to already condemned ones.  */
 17034           Lisp_Object last = FRAME_SCROLL_BARS (frame);
 17035 
 17036           while (!NILP (XSCROLL_BAR (last)->next))
 17037             last = XSCROLL_BAR (last)->next;
 17038 
 17039           XSCROLL_BAR (last)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
 17040           XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = last;
 17041         }
 17042 
 17043       fset_condemned_scroll_bars (frame, FRAME_SCROLL_BARS (frame));
 17044       fset_scroll_bars (frame, Qnil);
 17045     }
 17046 }
 17047 
 17048 
 17049 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
 17050    Note that WINDOW isn't necessarily condemned at all.  */
 17051 
 17052 static void
 17053 XTredeem_scroll_bar (struct window *w)
 17054 {
 17055   struct scroll_bar *bar;
 17056   Lisp_Object barobj;
 17057   struct frame *f;
 17058 
 17059   /* We can't redeem this window's scroll bar if it doesn't have one.  */
 17060   if (NILP (w->vertical_scroll_bar) && NILP (w->horizontal_scroll_bar))
 17061     emacs_abort ();
 17062 
 17063   if (!NILP (w->vertical_scroll_bar) && WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
 17064     {
 17065       bar = XSCROLL_BAR (w->vertical_scroll_bar);
 17066       /* Unlink it from the condemned list.  */
 17067       f = XFRAME (WINDOW_FRAME (w));
 17068       if (NILP (bar->prev))
 17069         {
 17070           /* If the prev pointer is nil, it must be the first in one of
 17071              the lists.  */
 17072           if (EQ (FRAME_SCROLL_BARS (f), w->vertical_scroll_bar))
 17073             /* It's not condemned.  Everything's fine.  */
 17074             goto horizontal;
 17075           else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
 17076                        w->vertical_scroll_bar))
 17077             fset_condemned_scroll_bars (f, bar->next);
 17078           else
 17079             /* If its prev pointer is nil, it must be at the front of
 17080                one or the other!  */
 17081             emacs_abort ();
 17082         }
 17083       else
 17084         XSCROLL_BAR (bar->prev)->next = bar->next;
 17085 
 17086       if (! NILP (bar->next))
 17087         XSCROLL_BAR (bar->next)->prev = bar->prev;
 17088 
 17089       bar->next = FRAME_SCROLL_BARS (f);
 17090       bar->prev = Qnil;
 17091       XSETVECTOR (barobj, bar);
 17092       fset_scroll_bars (f, barobj);
 17093       if (! NILP (bar->next))
 17094         XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 17095     }
 17096 
 17097  horizontal:
 17098   if (!NILP (w->horizontal_scroll_bar) && WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
 17099     {
 17100       bar = XSCROLL_BAR (w->horizontal_scroll_bar);
 17101       /* Unlink it from the condemned list.  */
 17102       f = XFRAME (WINDOW_FRAME (w));
 17103       if (NILP (bar->prev))
 17104         {
 17105           /* If the prev pointer is nil, it must be the first in one of
 17106              the lists.  */
 17107           if (EQ (FRAME_SCROLL_BARS (f), w->horizontal_scroll_bar))
 17108             /* It's not condemned.  Everything's fine.  */
 17109             return;
 17110           else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
 17111                        w->horizontal_scroll_bar))
 17112             fset_condemned_scroll_bars (f, bar->next);
 17113           else
 17114             /* If its prev pointer is nil, it must be at the front of
 17115                one or the other!  */
 17116             emacs_abort ();
 17117         }
 17118       else
 17119         XSCROLL_BAR (bar->prev)->next = bar->next;
 17120 
 17121       if (! NILP (bar->next))
 17122         XSCROLL_BAR (bar->next)->prev = bar->prev;
 17123 
 17124       bar->next = FRAME_SCROLL_BARS (f);
 17125       bar->prev = Qnil;
 17126       XSETVECTOR (barobj, bar);
 17127       fset_scroll_bars (f, barobj);
 17128       if (! NILP (bar->next))
 17129         XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 17130     }
 17131 }
 17132 
 17133 /* Remove all scroll bars on FRAME that haven't been saved since the
 17134    last call to `*condemn_scroll_bars_hook'.  */
 17135 
 17136 static void
 17137 XTjudge_scroll_bars (struct frame *f)
 17138 {
 17139   Lisp_Object bar, next;
 17140 
 17141   bar = FRAME_CONDEMNED_SCROLL_BARS (f);
 17142 
 17143   /* Clear out the condemned list now so we won't try to process any
 17144      more events on the hapless scroll bars.  */
 17145   fset_condemned_scroll_bars (f, Qnil);
 17146 
 17147   for (; ! NILP (bar); bar = next)
 17148     {
 17149       struct scroll_bar *b = XSCROLL_BAR (bar);
 17150 
 17151       x_scroll_bar_remove (b);
 17152 
 17153       next = b->next;
 17154       b->next = b->prev = Qnil;
 17155     }
 17156 
 17157   /* Now there should be no references to the condemned scroll bars,
 17158      and they should get garbage-collected.  */
 17159 }
 17160 
 17161 
 17162 #ifndef USE_TOOLKIT_SCROLL_BARS
 17163 /* Handle exposure event EVENT generated for F, by redrawing all
 17164    intersecting scroll bars.  */
 17165 
 17166 static void
 17167 x_scroll_bar_handle_exposure (struct frame *f, XEvent *event)
 17168 {
 17169   int x, y, width, height;
 17170   XRectangle rect, scroll_bar_rect, intersection;
 17171   Lisp_Object bar, condemned;
 17172   struct scroll_bar *b;
 17173 
 17174   if (event->type == GraphicsExpose)
 17175     {
 17176       x = event->xgraphicsexpose.x;
 17177       y = event->xgraphicsexpose.y;
 17178       width = event->xgraphicsexpose.width;
 17179       height = event->xgraphicsexpose.height;
 17180     }
 17181   else
 17182     {
 17183       x = event->xexpose.x;
 17184       y = event->xexpose.y;
 17185       width = event->xexpose.width;
 17186       height = event->xexpose.height;
 17187     }
 17188 
 17189   rect.x = x;
 17190   rect.y = y;
 17191   rect.width = width;
 17192   rect.height = height;
 17193 
 17194   /* Scan this frame's scroll bar list for intersecting scroll
 17195      bars.  */
 17196   condemned = FRAME_CONDEMNED_SCROLL_BARS (f);
 17197   for (bar = FRAME_SCROLL_BARS (f);
 17198        /* This trick allows us to search both the ordinary and
 17199           condemned scroll bar lists with one loop.  */
 17200        !NILP (bar) || (bar = condemned,
 17201                        condemned = Qnil,
 17202                        !NILP (bar));
 17203        bar = XSCROLL_BAR (bar)->next)
 17204     {
 17205       b = XSCROLL_BAR (bar);
 17206 
 17207       scroll_bar_rect.x = b->left;
 17208       scroll_bar_rect.y = b->top;
 17209       scroll_bar_rect.width = b->width;
 17210       scroll_bar_rect.height = b->height;
 17211 
 17212       if (gui_intersect_rectangles (&rect,
 17213                                     &scroll_bar_rect,
 17214                                     &intersection))
 17215         x_scroll_bar_redraw (b);
 17216     }
 17217 }
 17218 
 17219 /* Redraw the scroll bar BAR.  Draw its border and set its thumb.
 17220    This is usually called from x_clear_frame, but is also used to
 17221    handle exposure events that overlap scroll bars.  */
 17222 
 17223 static void
 17224 x_scroll_bar_redraw (struct scroll_bar *bar)
 17225 {
 17226   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 17227   GC gc = f->output_data.x->normal_gc;
 17228 
 17229   if (f->output_data.x->scroll_bar_background_pixel != -1)
 17230     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17231                     f->output_data.x->scroll_bar_background_pixel);
 17232   else
 17233     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17234                     FRAME_BACKGROUND_PIXEL (f));
 17235 
 17236   XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), gc,
 17237                   bar->left, bar->top, bar->width, bar->height);
 17238 
 17239   XSetForeground (FRAME_X_DISPLAY (f), gc,
 17240                   FRAME_FOREGROUND_PIXEL (f));
 17241 
 17242   x_scroll_bar_set_handle (bar, bar->start, bar->end, true);
 17243 
 17244   /* Switch to scroll bar foreground color.  */
 17245   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 17246     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17247                     f->output_data.x->scroll_bar_foreground_pixel);
 17248 
 17249   /* Draw a one-pixel border just inside the edges of the scroll bar.  */
 17250   XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), gc,
 17251                   bar->left, bar->top, bar->width - 1, bar->height - 1);
 17252 
 17253   /* Restore the foreground color of the GC if we changed it above.  */
 17254   if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 17255     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17256                     FRAME_FOREGROUND_PIXEL (f));
 17257 }
 17258 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 17259 
 17260 /* Handle a mouse click on the scroll bar BAR.  If *EMACS_EVENT's kind
 17261    is set to something other than NO_EVENT, it is enqueued.
 17262 
 17263    This may be called from a signal handler, so we have to ignore GC
 17264    mark bits.  */
 17265 
 17266 
 17267 static void
 17268 x_scroll_bar_handle_click (struct scroll_bar *bar,
 17269                            const XEvent *event,
 17270                            struct input_event *emacs_event,
 17271                            Lisp_Object device)
 17272 {
 17273   int left_range, x, top_range, y;
 17274 #ifndef USE_TOOLKIT_SCROLL_BARS
 17275   int new_start, new_end;
 17276 #endif
 17277 
 17278   if (! WINDOWP (bar->window))
 17279     emacs_abort ();
 17280 
 17281   emacs_event->kind = (bar->horizontal
 17282                        ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT
 17283                        : SCROLL_BAR_CLICK_EVENT);
 17284   emacs_event->code = event->xbutton.button - Button1;
 17285   emacs_event->modifiers
 17286     = (x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO
 17287                                (XFRAME (WINDOW_FRAME (XWINDOW (bar->window)))),
 17288                                event->xbutton.state)
 17289        | (event->type == ButtonRelease
 17290           ? up_modifier
 17291           : down_modifier));
 17292   emacs_event->frame_or_window = bar->window;
 17293   emacs_event->arg = Qnil;
 17294   emacs_event->timestamp = event->xbutton.time;
 17295 
 17296   if (!NILP (device))
 17297     emacs_event->device = device;
 17298 
 17299   if (bar->horizontal)
 17300     {
 17301 
 17302       left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
 17303       x = event->xbutton.x - HORIZONTAL_SCROLL_BAR_LEFT_BORDER;
 17304 
 17305       if (x < 0) x = 0;
 17306       if (x > left_range) x = left_range;
 17307 
 17308       if (x < bar->start)
 17309         emacs_event->part = scroll_bar_before_handle;
 17310       else if (x < bar->end + HORIZONTAL_SCROLL_BAR_MIN_HANDLE)
 17311         emacs_event->part = scroll_bar_horizontal_handle;
 17312       else
 17313         emacs_event->part = scroll_bar_after_handle;
 17314 
 17315 #ifndef USE_TOOLKIT_SCROLL_BARS
 17316       /* If the user has released the handle, set it to its final position.  */
 17317       if (event->type == ButtonRelease && bar->dragging != -1)
 17318         {
 17319           new_start = - bar->dragging;
 17320           new_end = new_start + bar->end - bar->start;
 17321 
 17322           x_scroll_bar_set_handle (bar, new_start, new_end, false);
 17323           bar->dragging = -1;
 17324         }
 17325 #endif
 17326 
 17327       XSETINT (emacs_event->x, left_range);
 17328       XSETINT (emacs_event->y, x);
 17329     }
 17330   else
 17331     {
 17332       top_range
 17333         = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
 17334       y = event->xbutton.y - VERTICAL_SCROLL_BAR_TOP_BORDER;
 17335 
 17336       if (y < 0) y = 0;
 17337       if (y > top_range) y = top_range;
 17338 
 17339       if (y < bar->start)
 17340         emacs_event->part = scroll_bar_above_handle;
 17341       else if (y < bar->end + VERTICAL_SCROLL_BAR_MIN_HANDLE)
 17342         emacs_event->part = scroll_bar_handle;
 17343       else
 17344         emacs_event->part = scroll_bar_below_handle;
 17345 
 17346 #ifndef USE_TOOLKIT_SCROLL_BARS
 17347       /* If the user has released the handle, set it to its final position.  */
 17348       if (event->type == ButtonRelease && bar->dragging != -1)
 17349         {
 17350           new_start = y - bar->dragging;
 17351           new_end = new_start + bar->end - bar->start;
 17352 
 17353           x_scroll_bar_set_handle (bar, new_start, new_end, false);
 17354           bar->dragging = -1;
 17355         }
 17356 #endif
 17357 
 17358       XSETINT (emacs_event->x, y);
 17359       XSETINT (emacs_event->y, top_range);
 17360     }
 17361 }
 17362 
 17363 #ifndef USE_TOOLKIT_SCROLL_BARS
 17364 
 17365 /* Handle some mouse motion while someone is dragging the scroll bar.
 17366 
 17367    This may be called from a signal handler, so we have to ignore GC
 17368    mark bits.  */
 17369 
 17370 static void
 17371 x_scroll_bar_note_movement (struct scroll_bar *bar,
 17372                             const XMotionEvent *event)
 17373 {
 17374   struct frame *f = XFRAME (XWINDOW (bar->window)->frame);
 17375   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 17376 
 17377   dpyinfo->last_mouse_movement_time = event->time;
 17378   dpyinfo->last_mouse_movement_time_send_event = event->send_event;
 17379   dpyinfo->last_mouse_scroll_bar = bar;
 17380   f->mouse_moved = true;
 17381 
 17382   /* If we're dragging the bar, display it.  */
 17383   if (bar->dragging != -1)
 17384     {
 17385       /* Where should the handle be now?  */
 17386       int new_start = event->y - bar->dragging;
 17387 
 17388       if (new_start != bar->start)
 17389         {
 17390           int new_end = new_start + bar->end - bar->start;
 17391 
 17392           x_scroll_bar_set_handle (bar, new_start, new_end, false);
 17393         }
 17394     }
 17395 }
 17396 
 17397 #endif /* !USE_TOOLKIT_SCROLL_BARS */
 17398 
 17399 /* Return information to the user about the current position of the mouse
 17400    on the scroll bar.  */
 17401 
 17402 static void
 17403 x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
 17404                             enum scroll_bar_part *part, Lisp_Object *x,
 17405                             Lisp_Object *y, Time *timestamp)
 17406 {
 17407   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
 17408   struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
 17409   Window w = bar->x_window;
 17410   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 17411   int win_x, win_y;
 17412   Window dummy_window;
 17413   int dummy_coord;
 17414   unsigned int dummy_mask;
 17415 
 17416   block_input ();
 17417 
 17418   /* Get the mouse's position relative to the scroll bar window, and
 17419      report that.  */
 17420   if (x_query_pointer (FRAME_X_DISPLAY (f), w,
 17421 
 17422                        /* Root, child, root x and root y.  */
 17423                        &dummy_window, &dummy_window,
 17424                        &dummy_coord, &dummy_coord,
 17425 
 17426                        /* Position relative to scroll bar.  */
 17427                        &win_x, &win_y,
 17428 
 17429                        /* Mouse buttons and modifier keys.  */
 17430                        &dummy_mask))
 17431     {
 17432       int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
 17433 
 17434       win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
 17435 
 17436       if (bar->dragging != -1)
 17437         win_y -= bar->dragging;
 17438 
 17439       if (win_y < 0)
 17440         win_y = 0;
 17441       if (win_y > top_range)
 17442         win_y = top_range;
 17443 
 17444       *fp = f;
 17445       *bar_window = bar->window;
 17446 
 17447       if (bar->dragging != -1)
 17448         *part = scroll_bar_handle;
 17449       else if (win_y < bar->start)
 17450         *part = scroll_bar_above_handle;
 17451       else if (win_y < bar->end + VERTICAL_SCROLL_BAR_MIN_HANDLE)
 17452         *part = scroll_bar_handle;
 17453       else
 17454         *part = scroll_bar_below_handle;
 17455 
 17456       XSETINT (*x, win_y);
 17457       XSETINT (*y, top_range);
 17458 
 17459       f->mouse_moved = false;
 17460       dpyinfo->last_mouse_scroll_bar = NULL;
 17461       *timestamp = dpyinfo->last_mouse_movement_time;
 17462     }
 17463 
 17464   unblock_input ();
 17465 }
 17466 
 17467 
 17468 /* Return information to the user about the current position of the mouse
 17469    on the scroll bar.  */
 17470 
 17471 static void
 17472 x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
 17473                                        enum scroll_bar_part *part, Lisp_Object *x,
 17474                                        Lisp_Object *y, Time *timestamp)
 17475 {
 17476   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
 17477   struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
 17478   Window w = bar->x_window;
 17479   struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
 17480   int win_x, win_y;
 17481   Window dummy_window;
 17482   int dummy_coord;
 17483   unsigned int dummy_mask;
 17484 
 17485   block_input ();
 17486 
 17487   /* Get the mouse's position relative to the scroll bar window, and
 17488      report that.  */
 17489   if (x_query_pointer (FRAME_X_DISPLAY (f), w,
 17490 
 17491                        /* Root, child, root x and root y.  */
 17492                        &dummy_window, &dummy_window,
 17493                        &dummy_coord, &dummy_coord,
 17494 
 17495                        /* Position relative to scroll bar.  */
 17496                        &win_x, &win_y,
 17497 
 17498                        /* Mouse buttons and modifier keys.  */
 17499                        &dummy_mask))
 17500     {
 17501       int left_range = HORIZONTAL_SCROLL_BAR_LEFT_RANGE (f, bar->width);
 17502 
 17503       win_x -= HORIZONTAL_SCROLL_BAR_LEFT_BORDER;
 17504 
 17505       if (bar->dragging != -1)
 17506         win_x -= bar->dragging;
 17507 
 17508       if (win_x < 0)
 17509         win_x = 0;
 17510       if (win_x > left_range)
 17511         win_x = left_range;
 17512 
 17513       *fp = f;
 17514       *bar_window = bar->window;
 17515 
 17516       if (bar->dragging != -1)
 17517         *part = scroll_bar_horizontal_handle;
 17518       else if (win_x < bar->start)
 17519         *part = scroll_bar_before_handle;
 17520       else if (win_x < bar->end + HORIZONTAL_SCROLL_BAR_MIN_HANDLE)
 17521         *part = scroll_bar_handle;
 17522       else
 17523         *part = scroll_bar_after_handle;
 17524 
 17525       XSETINT (*y, win_x);
 17526       XSETINT (*x, left_range);
 17527 
 17528       f->mouse_moved = false;
 17529       dpyinfo->last_mouse_scroll_bar = NULL;
 17530       *timestamp = dpyinfo->last_mouse_movement_time;
 17531     }
 17532 
 17533   unblock_input ();
 17534 }
 17535 
 17536 
 17537 /* The screen has been cleared and foreground or background colors may
 17538    have changed, so the scroll bars need to be redrawn.  Clear the
 17539    scroll bars and redraw them.  */
 17540 
 17541 static void
 17542 x_scroll_bar_clear (struct frame *f)
 17543 {
 17544 #ifndef USE_TOOLKIT_SCROLL_BARS
 17545   Lisp_Object bar, condemned;
 17546   GC gc = f->output_data.x->normal_gc;
 17547 
 17548   if (f->output_data.x->scroll_bar_background_pixel != -1)
 17549     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17550                     f->output_data.x->scroll_bar_background_pixel);
 17551   else
 17552     XSetForeground (FRAME_X_DISPLAY (f), gc,
 17553                     FRAME_BACKGROUND_PIXEL (f));
 17554 
 17555   /* We can have scroll bars even if this is 0,
 17556      if we just turned off scroll bar mode.
 17557      But in that case we should not clear them.  */
 17558   if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
 17559     {
 17560       condemned = FRAME_CONDEMNED_SCROLL_BARS (f);
 17561       for (bar = FRAME_SCROLL_BARS (f);
 17562            /* This trick allows us to search both the ordinary and
 17563               condemned scroll bar lists with one loop.  */
 17564            !NILP (bar) || (bar = condemned,
 17565                            condemned = Qnil,
 17566                            !NILP (bar));
 17567            bar = XSCROLL_BAR (bar)->next)
 17568         x_scroll_bar_redraw (XSCROLL_BAR (bar));
 17569     }
 17570 
 17571   XSetForeground (FRAME_X_DISPLAY (f), gc,
 17572                   FRAME_FOREGROUND_PIXEL (f));
 17573 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 17574 }
 17575 
 17576 #ifdef ENABLE_CHECKING
 17577 
 17578 /* Record the last 100 characters stored
 17579    to help debug the loss-of-chars-during-GC problem.  */
 17580 
 17581 static int temp_index;
 17582 static short temp_buffer[100];
 17583 
 17584 #define STORE_KEYSYM_FOR_DEBUG(keysym)                          \
 17585   if (temp_index == ARRAYELTS (temp_buffer))                    \
 17586     temp_index = 0;                                             \
 17587   temp_buffer[temp_index++] = (keysym)
 17588 
 17589 #else /* not ENABLE_CHECKING */
 17590 
 17591 #define STORE_KEYSYM_FOR_DEBUG(keysym) ((void)0)
 17592 
 17593 #endif /* ENABLE_CHECKING */
 17594 
 17595 /* Set this to nonzero to fake an "X I/O error"
 17596    on a particular display.  */
 17597 
 17598 static struct x_display_info *XTread_socket_fake_io_error;
 17599 
 17600 /* When we find no input here, we occasionally do a no-op command
 17601    to verify that the X server is still running and we can still talk with it.
 17602    We try all the open displays, one by one.
 17603    This variable is used for cycling thru the displays.  */
 17604 
 17605 static struct x_display_info *next_noop_dpyinfo;
 17606 
 17607 /* Filter events for the current X input method.
 17608    DPYINFO is the display this event is for.
 17609    EVENT is the X event to filter.
 17610 
 17611    Returns non-zero if the event was filtered, caller shall not process
 17612    this event further.
 17613    Returns zero if event is wasn't filtered.  */
 17614 
 17615 #ifdef HAVE_X_I18N
 17616 static int
 17617 x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
 17618 {
 17619   /* XFilterEvent returns non-zero if the input method has
 17620    consumed the event.  We pass the frame's X window to
 17621    XFilterEvent because that's the one for which the IC
 17622    was created.  */
 17623 
 17624   struct frame *f1;
 17625 
 17626 #if defined HAVE_XINPUT2 && defined USE_GTK
 17627   bool xinput_event = false;
 17628   if (dpyinfo->supports_xi2
 17629       && event->type == GenericEvent
 17630       && (event->xgeneric.extension
 17631           == dpyinfo->xi2_opcode)
 17632       && ((event->xgeneric.evtype
 17633            == XI_KeyPress)
 17634           || (event->xgeneric.evtype
 17635               == XI_KeyRelease)))
 17636     {
 17637       f1 = x_any_window_to_frame (dpyinfo,
 17638                                   ((XIDeviceEvent *)
 17639                                    event->xcookie.data)->event);
 17640       xinput_event = true;
 17641     }
 17642   else
 17643 #endif
 17644     f1 = x_any_window_to_frame (dpyinfo,
 17645                                 event->xclient.window);
 17646 
 17647 #ifdef USE_GTK
 17648   if (!x_gtk_use_native_input
 17649       && !dpyinfo->prefer_native_input)
 17650     {
 17651 #endif
 17652       return XFilterEvent (event, f1 ? FRAME_X_WINDOW (f1) : None);
 17653 #ifdef USE_GTK
 17654     }
 17655   else if (f1 && (event->type == KeyPress
 17656                   || event->type == KeyRelease
 17657 #ifdef HAVE_XINPUT2
 17658                   || xinput_event
 17659 #endif
 17660                   ))
 17661     {
 17662       bool result;
 17663 
 17664       block_input ();
 17665       result = xg_filter_key (f1, event);
 17666       unblock_input ();
 17667 
 17668       /* Clear `xg_pending_quit_event' so we don't end up reacting to quit
 17669          events sent outside the main event loop (i.e. those sent from
 17670          inside a popup menu event loop).  */
 17671 
 17672       if (popup_activated ())
 17673         xg_pending_quit_event.kind = NO_EVENT;
 17674 
 17675       if (result && f1)
 17676         /* There will probably be a GDK event generated soon, so
 17677            exercise the wire to make pselect return.  */
 17678         XNoOp (FRAME_X_DISPLAY (f1));
 17679 
 17680       return result;
 17681     }
 17682 
 17683   return 0;
 17684 #endif
 17685 }
 17686 #endif
 17687 
 17688 #ifdef USE_GTK
 17689 /* This is the filter function invoked by the GTK event loop.
 17690    It is invoked before the XEvent is translated to a GdkEvent,
 17691    so we have a chance to act on the event before GTK.  */
 17692 static GdkFilterReturn
 17693 event_handler_gdk (GdkXEvent *gxev, GdkEvent *ev, gpointer data)
 17694 {
 17695   XEvent *xev = (XEvent *) gxev;
 17696 
 17697   block_input ();
 17698   if (current_count >= 0)
 17699     {
 17700       struct x_display_info *dpyinfo;
 17701 
 17702       dpyinfo = x_display_info_for_display (xev->xany.display);
 17703 
 17704 #ifdef HAVE_X_I18N
 17705       /* Filter events for the current X input method.
 17706          GTK calls XFilterEvent but not for key press and release,
 17707          so we do it here.  */
 17708       if ((xev->type == KeyPress || xev->type == KeyRelease)
 17709           && dpyinfo
 17710           && x_filter_event (dpyinfo, xev))
 17711         {
 17712           unblock_input ();
 17713           return GDK_FILTER_REMOVE;
 17714         }
 17715 #elif USE_GTK
 17716       if (dpyinfo && (dpyinfo->prefer_native_input
 17717                       || x_gtk_use_native_input)
 17718           && (xev->type == KeyPress
 17719 #ifdef HAVE_XINPUT2
 17720               /* GTK claims cookies for us, so we don't have to claim
 17721                  them here.  */
 17722               || (dpyinfo->supports_xi2
 17723                   && xev->type == GenericEvent
 17724                   && (xev->xgeneric.extension
 17725                       == dpyinfo->xi2_opcode)
 17726                   && ((xev->xgeneric.evtype
 17727                        == XI_KeyPress)
 17728                       || (xev->xgeneric.evtype
 17729                           == XI_KeyRelease)))
 17730 #endif
 17731               ))
 17732         {
 17733           struct frame *f;
 17734 
 17735 #ifdef HAVE_XINPUT2
 17736           if (xev->type == GenericEvent)
 17737             f = x_any_window_to_frame (dpyinfo,
 17738                                        ((XIDeviceEvent *) xev->xcookie.data)->event);
 17739           else
 17740 #endif
 17741             f = x_any_window_to_frame (dpyinfo, xev->xany.window);
 17742 
 17743           if (f && xg_filter_key (f, xev))
 17744             {
 17745               unblock_input ();
 17746               return GDK_FILTER_REMOVE;
 17747             }
 17748         }
 17749 #endif
 17750 
 17751       if (! dpyinfo)
 17752         current_finish = X_EVENT_NORMAL;
 17753       else
 17754         current_count
 17755           += handle_one_xevent (dpyinfo, xev, &current_finish,
 17756                                 current_hold_quit);
 17757     }
 17758   else
 17759     current_finish = x_dispatch_event (xev, xev->xany.display);
 17760 
 17761   unblock_input ();
 17762 
 17763   if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP)
 17764     return GDK_FILTER_REMOVE;
 17765 
 17766   return GDK_FILTER_CONTINUE;
 17767 }
 17768 #endif /* USE_GTK */
 17769 
 17770 
 17771 static void xembed_send_message (struct frame *f, Time,
 17772                                  enum xembed_message,
 17773                                  long detail, long data1, long data2);
 17774 
 17775 static void
 17776 x_net_wm_state (struct frame *f, Window window)
 17777 {
 17778   int value = FULLSCREEN_NONE;
 17779   Lisp_Object lval = Qnil;
 17780   bool sticky = false, shaded = false;
 17781 
 17782   x_get_current_wm_state (f, window, &value, &sticky, &shaded);
 17783 
 17784   switch (value)
 17785     {
 17786     case FULLSCREEN_WIDTH:
 17787       lval = Qfullwidth;
 17788       break;
 17789     case FULLSCREEN_HEIGHT:
 17790       lval = Qfullheight;
 17791       break;
 17792     case FULLSCREEN_BOTH:
 17793       lval = Qfullboth;
 17794       break;
 17795     case FULLSCREEN_MAXIMIZED:
 17796       lval = Qmaximized;
 17797       break;
 17798     }
 17799 
 17800   store_frame_param (f, Qfullscreen, lval);
 17801   store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
 17802   store_frame_param (f, Qshaded, shaded ? Qt : Qnil);
 17803 }
 17804 
 17805 /* Flip back buffers on F if it has undrawn content.  */
 17806 
 17807 static void
 17808 x_flush_dirty_back_buffer_on (struct frame *f)
 17809 {
 17810 #ifdef HAVE_XDBE
 17811   if (FRAME_GARBAGED_P (f)
 17812       || buffer_flipping_blocked_p ()
 17813       /* If the frame is not already up to date, do not flush buffers
 17814          on input, as that will result in flicker.  */
 17815       || !FRAME_X_COMPLETE_P (f)
 17816       || !FRAME_X_NEED_BUFFER_FLIP (f))
 17817     return;
 17818 
 17819   show_back_buffer (f);
 17820 #endif
 17821 }
 17822 
 17823 #ifdef HAVE_GTK3
 17824 void
 17825 x_scroll_bar_configure (GdkEvent *event)
 17826 {
 17827   XEvent configure;
 17828   GdkDisplay *gdpy;
 17829   Display *dpy;
 17830 
 17831   configure.xconfigure.type = ConfigureNotify;
 17832   configure.xconfigure.serial = 0;
 17833   configure.xconfigure.send_event = event->configure.send_event;
 17834   configure.xconfigure.x = event->configure.x;
 17835   configure.xconfigure.y = event->configure.y;
 17836   configure.xconfigure.width = event->configure.width;
 17837   configure.xconfigure.height = event->configure.height;
 17838   configure.xconfigure.border_width = 0;
 17839   configure.xconfigure.event = GDK_WINDOW_XID (event->configure.window);
 17840   configure.xconfigure.window = GDK_WINDOW_XID (event->configure.window);
 17841   configure.xconfigure.above = None;
 17842   configure.xconfigure.override_redirect = False;
 17843 
 17844   gdpy = gdk_window_get_display (event->configure.window);
 17845   dpy = gdk_x11_display_get_xdisplay (gdpy);
 17846 
 17847   x_dispatch_event (&configure, dpy);
 17848 }
 17849 #endif
 17850 
 17851 /**
 17852   mouse_or_wdesc_frame: When not dropping and the mouse was grabbed
 17853   for DPYINFO, return the frame where the mouse was seen last.  If
 17854   there's no such frame, return the frame according to WDESC.  When
 17855   dropping, return the frame according to WDESC.  If there's no such
 17856   frame and the mouse was grabbed for DPYINFO, return the frame where
 17857   the mouse was seen last.  In either case, never return a tooltip
 17858   frame.  */
 17859 static struct frame *
 17860 mouse_or_wdesc_frame (struct x_display_info *dpyinfo, int wdesc)
 17861 {
 17862   struct frame *lm_f = (gui_mouse_grabbed (dpyinfo)
 17863                         ? dpyinfo->last_mouse_frame
 17864                         : NULL);
 17865 
 17866   if (lm_f && !EQ (track_mouse, Qdropping)
 17867       && !EQ (track_mouse, Qdrag_source))
 17868     return lm_f;
 17869   else
 17870     {
 17871       struct frame *w_f = x_window_to_frame (dpyinfo, wdesc);
 17872 
 17873       /* Do not return a tooltip frame.  */
 17874       if (!w_f || FRAME_TOOLTIP_P (w_f))
 17875         return EQ (track_mouse, Qdropping) ? lm_f : NULL;
 17876       else
 17877         /* When dropping it would be probably nice to raise w_f
 17878            here.  */
 17879         return w_f;
 17880     }
 17881 }
 17882 
 17883 static void
 17884 x_dnd_compute_tip_xy (int *root_x, int *root_y, Lisp_Object attributes)
 17885 {
 17886   Lisp_Object monitor, geometry;
 17887   int min_x, min_y, max_x, max_y;
 17888   int width, height;
 17889 
 17890   width = FRAME_PIXEL_WIDTH (XFRAME (tip_frame));
 17891   height = FRAME_PIXEL_HEIGHT (XFRAME (tip_frame));
 17892 
 17893   max_y = -1;
 17894 
 17895   /* Try to determine the monitor where the mouse pointer is and
 17896      its geometry.  See bug#22549.  */
 17897   while (CONSP (attributes))
 17898     {
 17899       monitor = XCAR (attributes);
 17900       geometry = assq_no_quit (Qgeometry, monitor);
 17901 
 17902       if (CONSP (geometry))
 17903         {
 17904           min_x = XFIXNUM (Fnth (make_fixnum (1), geometry));
 17905           min_y = XFIXNUM (Fnth (make_fixnum (2), geometry));
 17906           max_x = min_x + XFIXNUM (Fnth (make_fixnum (3), geometry));
 17907           max_y = min_y + XFIXNUM (Fnth (make_fixnum (4), geometry));
 17908 
 17909           if (min_x <= *root_x && *root_x < max_x
 17910               && min_y <= *root_y && *root_y < max_y)
 17911             break;
 17912 
 17913           max_y = -1;
 17914         }
 17915 
 17916       attributes = XCDR (attributes);
 17917     }
 17918 
 17919   /* It was not possible to determine the monitor's geometry, so we
 17920      assign some sane defaults here: */
 17921   if (max_y < 0)
 17922     {
 17923       min_x = 0;
 17924       min_y = 0;
 17925       max_x = x_display_pixel_width (FRAME_DISPLAY_INFO (x_dnd_frame));
 17926       max_y = x_display_pixel_height (FRAME_DISPLAY_INFO (x_dnd_frame));
 17927     }
 17928 
 17929   if (*root_y + XFIXNUM (tip_dy) <= min_y)
 17930     *root_y = min_y; /* Can happen for negative dy */
 17931   else if (*root_y + XFIXNUM (tip_dy) + height <= max_y)
 17932     /* It fits below the pointer */
 17933     *root_y += XFIXNUM (tip_dy);
 17934   else if (height + XFIXNUM (tip_dy) + min_y <= *root_y)
 17935     /* It fits above the pointer.  */
 17936     *root_y -= height + XFIXNUM (tip_dy);
 17937   else
 17938     /* Put it on the top.  */
 17939     *root_y = min_y;
 17940 
 17941   if (*root_x + XFIXNUM (tip_dx) <= min_x)
 17942     *root_x = 0; /* Can happen for negative dx */
 17943   else if (*root_x + XFIXNUM (tip_dx) + width <= max_x)
 17944     /* It fits to the right of the pointer.  */
 17945     *root_x += XFIXNUM (tip_dx);
 17946   else if (width + XFIXNUM (tip_dx) + min_x <= *root_x)
 17947     /* It fits to the left of the pointer.  */
 17948     *root_x -= width + XFIXNUM (tip_dx);
 17949   else
 17950     /* Put it left justified on the screen -- it ought to fit that way.  */
 17951     *root_x = min_x;
 17952 }
 17953 
 17954 static void
 17955 x_dnd_update_tooltip_position (int root_x, int root_y)
 17956 {
 17957   struct frame *tip_f;
 17958 
 17959   if (!x_dnd_in_progress || !x_dnd_update_tooltip)
 17960     return;
 17961 
 17962   if (!FRAMEP (tip_frame))
 17963     return;
 17964 
 17965   tip_f = XFRAME (tip_frame);
 17966 
 17967   if (!FRAME_LIVE_P (tip_f)
 17968       || !FRAME_VISIBLE_P (tip_f)
 17969       || (FRAME_X_DISPLAY (tip_f)
 17970           != FRAME_X_DISPLAY (x_dnd_frame)))
 17971     return;
 17972 
 17973   if (tip_window != None
 17974       && FIXNUMP (tip_dx) && FIXNUMP (tip_dy))
 17975     {
 17976       x_dnd_compute_tip_xy (&root_x, &root_y,
 17977                             x_dnd_monitors);
 17978 
 17979       if (x_dnd_last_tooltip_valid
 17980           && root_x == x_dnd_last_tooltip_x
 17981           && root_y == x_dnd_last_tooltip_y)
 17982         return;
 17983 
 17984       x_dnd_last_tooltip_x = root_x;
 17985       x_dnd_last_tooltip_y = root_y;
 17986       x_dnd_last_tooltip_valid = true;
 17987 
 17988       XMoveWindow (FRAME_X_DISPLAY (x_dnd_frame),
 17989                    tip_window, root_x, root_y);
 17990     }
 17991 }
 17992 
 17993 static void
 17994 x_dnd_update_tooltip_now (void)
 17995 {
 17996   int root_x, root_y;
 17997   Window root, child;
 17998   int win_x, win_y;
 17999   unsigned int mask;
 18000   Bool rc;
 18001   struct x_display_info *dpyinfo;
 18002 
 18003   if (!x_dnd_in_progress || !x_dnd_update_tooltip)
 18004     return;
 18005 
 18006   dpyinfo = FRAME_DISPLAY_INFO (x_dnd_frame);
 18007 
 18008 #ifndef HAVE_XINPUT2
 18009   rc = XQueryPointer (dpyinfo->display,
 18010                       dpyinfo->root_window,
 18011                       &root, &child, &root_x,
 18012                       &root_y, &win_x, &win_y,
 18013                       &mask);
 18014 #else
 18015   rc = x_query_pointer_1 (dpyinfo, x_dnd_pointer_device,
 18016                           dpyinfo->root_window,
 18017                           &root, &child, &root_x,
 18018                           &root_y, &win_x, &win_y,
 18019                           &mask);
 18020 #endif
 18021 
 18022   if (rc)
 18023     x_dnd_update_tooltip_position (root_x, root_y);
 18024 }
 18025 
 18026 /* Get the window underneath the pointer, see if it moved, and update
 18027    the DND state accordingly.  */
 18028 static void
 18029 x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp)
 18030 {
 18031   int root_x, root_y, dummy_x, dummy_y, target_proto, motif_style;
 18032   unsigned int dummy_mask;
 18033   Window dummy, dummy_child, target, toplevel;
 18034   xm_top_level_leave_message lmsg;
 18035   xm_top_level_enter_message emsg;
 18036   xm_drag_motion_message dmsg;
 18037   xm_drop_start_message dsmsg;
 18038   bool was_frame;
 18039 
 18040   if (x_query_pointer_1 (dpyinfo,
 18041 #ifdef HAVE_XINPUT2
 18042                          x_dnd_pointer_device,
 18043 #else
 18044                          -1,
 18045 #endif
 18046                          dpyinfo->root_window,
 18047                          &dummy, &dummy_child,
 18048                          &root_x, &root_y,
 18049                          &dummy_x, &dummy_y,
 18050                          &dummy_mask))
 18051     {
 18052       target = x_dnd_get_target_window (dpyinfo, root_x,
 18053                                         root_y, &target_proto,
 18054                                         &motif_style, &toplevel,
 18055                                         &was_frame);
 18056 
 18057       if (toplevel != x_dnd_last_seen_toplevel)
 18058         {
 18059           if (toplevel != FRAME_OUTER_WINDOW (x_dnd_frame)
 18060               && x_dnd_return_frame == 1)
 18061             x_dnd_return_frame = 2;
 18062 
 18063           if (x_dnd_return_frame == 2
 18064               && x_any_window_to_frame (dpyinfo, toplevel))
 18065             {
 18066               if (x_dnd_last_seen_window != None
 18067                   && x_dnd_last_protocol_version != -1
 18068                   && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 18069                 x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 18070                                   x_dnd_last_seen_toplevel);
 18071               else if (x_dnd_last_seen_window != None
 18072                        && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 18073                        && !x_dnd_disable_motif_drag
 18074                        && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 18075                 {
 18076                   if (!x_dnd_motif_setup_p)
 18077                     xm_setup_drag_info (dpyinfo, x_dnd_frame);
 18078 
 18079                   lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 18080                                                 XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 18081                   lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 18082                   lmsg.zero = 0;
 18083                   lmsg.timestamp = timestamp;
 18084                   lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 18085 
 18086                   if (x_dnd_motif_setup_p)
 18087                     xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 18088                                                      x_dnd_last_seen_window, &lmsg);
 18089                 }
 18090 
 18091               x_dnd_end_window = x_dnd_last_seen_window;
 18092               x_dnd_last_seen_window = None;
 18093               x_dnd_last_seen_toplevel = None;
 18094               x_dnd_in_progress = false;
 18095               x_dnd_return_frame_object
 18096                 = x_any_window_to_frame (dpyinfo, toplevel);
 18097               x_dnd_return_frame = 3;
 18098               x_dnd_waiting_for_finish = false;
 18099               target = None;
 18100             }
 18101         }
 18102 
 18103       if (target != x_dnd_last_seen_window)
 18104         {
 18105           if (x_dnd_last_seen_window != None
 18106               && x_dnd_last_protocol_version != -1
 18107               && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 18108             x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 18109                               x_dnd_last_seen_toplevel);
 18110           else if (x_dnd_last_seen_window != None
 18111                    && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 18112                    && !x_dnd_disable_motif_drag
 18113                    && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 18114             {
 18115               if (!x_dnd_motif_setup_p)
 18116                 xm_setup_drag_info (dpyinfo, x_dnd_frame);
 18117 
 18118               lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 18119                                             XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 18120               lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 18121               lmsg.zero = 0;
 18122               lmsg.timestamp = timestamp;
 18123               lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 18124 
 18125               if (x_dnd_motif_setup_p)
 18126                 xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 18127                                                  x_dnd_last_seen_window, &lmsg);
 18128             }
 18129 
 18130           x_dnd_action = None;
 18131           x_dnd_last_seen_toplevel = toplevel;
 18132           x_dnd_last_seen_window = target;
 18133           x_dnd_last_protocol_version = target_proto;
 18134           x_dnd_last_motif_style = motif_style;
 18135           x_dnd_last_window_is_frame = was_frame;
 18136 
 18137           if (target != None && x_dnd_last_protocol_version != -1)
 18138             x_dnd_send_enter (x_dnd_frame, target, x_dnd_last_seen_toplevel,
 18139                               x_dnd_last_protocol_version);
 18140           else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 18141                    && !x_dnd_disable_motif_drag)
 18142             {
 18143               if (!x_dnd_motif_setup_p)
 18144                 xm_setup_drag_info (dpyinfo, x_dnd_frame);
 18145 
 18146               emsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 18147                                             XM_DRAG_REASON_TOP_LEVEL_ENTER);
 18148               emsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 18149               emsg.zero = 0;
 18150               emsg.timestamp = timestamp;
 18151               emsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 18152               emsg.index_atom = x_dnd_motif_atom;
 18153 
 18154               if (x_dnd_motif_setup_p)
 18155                 xm_send_top_level_enter_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 18156                                                  target, &emsg);
 18157             }
 18158         }
 18159       else
 18160         x_dnd_last_seen_toplevel = toplevel;
 18161 
 18162       if (x_dnd_last_window_is_frame && target != None)
 18163         x_dnd_note_self_position (dpyinfo, target, root_x, root_y);
 18164       else if (x_dnd_last_protocol_version != -1 && target != None)
 18165         x_dnd_send_position (x_dnd_frame, target,
 18166                              x_dnd_last_seen_toplevel,
 18167                              x_dnd_last_protocol_version,
 18168                              root_x, root_y,
 18169                              x_dnd_selection_timestamp,
 18170                              x_dnd_wanted_action, 0,
 18171 #ifdef HAVE_XKB
 18172                              x_dnd_keyboard_state
 18173 #else
 18174                              0
 18175 #endif
 18176                              );
 18177       else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None
 18178                && !x_dnd_disable_motif_drag)
 18179         {
 18180           if (!x_dnd_motif_setup_p)
 18181             xm_setup_drag_info (dpyinfo, x_dnd_frame);
 18182 
 18183           dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 18184                                         XM_DRAG_REASON_DRAG_MOTION);
 18185           dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 18186           dmsg.side_effects
 18187             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 18188                                                                x_dnd_wanted_action),
 18189                                    XM_DROP_SITE_VALID, x_dnd_motif_operations,
 18190                                    (!x_dnd_xm_use_help
 18191                                     ? XM_DROP_ACTION_DROP
 18192                                     : XM_DROP_ACTION_DROP_HELP));
 18193           dmsg.timestamp = timestamp;
 18194           dmsg.x = root_x;
 18195           dmsg.y = root_y;
 18196 
 18197           if (x_dnd_motif_setup_p)
 18198             xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 18199                                          target, &dmsg);
 18200         }
 18201 
 18202       x_dnd_update_tooltip_position (root_x, root_y);
 18203     }
 18204   /* The pointer moved out of the screen.  */
 18205   else if (x_dnd_last_protocol_version != -1)
 18206     {
 18207       if (x_dnd_last_seen_window != None
 18208           && x_dnd_last_protocol_version != -1)
 18209         x_dnd_send_leave (x_dnd_frame,
 18210                           x_dnd_last_seen_window,
 18211                           x_dnd_last_seen_toplevel);
 18212       else if (x_dnd_last_seen_window != None
 18213                && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
 18214                && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
 18215                && x_dnd_motif_setup_p)
 18216         {
 18217           dsmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 18218                                          XM_DRAG_REASON_DROP_START);
 18219           dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 18220           dsmsg.timestamp = timestamp;
 18221           dsmsg.side_effects
 18222             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 18223                                                                x_dnd_wanted_action),
 18224                                    XM_DROP_SITE_VALID, x_dnd_motif_operations,
 18225                                    XM_DROP_ACTION_DROP_CANCEL);
 18226           dsmsg.x = 0;
 18227           dsmsg.y = 0;
 18228           dsmsg.index_atom = x_dnd_motif_atom;
 18229           dsmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 18230 
 18231           x_dnd_send_xm_leave_for_drop (dpyinfo, x_dnd_frame,
 18232                                         x_dnd_last_seen_window, timestamp);
 18233           xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 18234                                 x_dnd_last_seen_window, &dsmsg);
 18235         }
 18236 
 18237       x_dnd_end_window = x_dnd_last_seen_window;
 18238       x_dnd_last_seen_window = None;
 18239       x_dnd_last_seen_toplevel = None;
 18240       x_dnd_in_progress = false;
 18241       x_dnd_waiting_for_finish = false;
 18242       x_dnd_frame = NULL;
 18243     }
 18244 }
 18245 
 18246 int
 18247 x_display_pixel_height (struct x_display_info *dpyinfo)
 18248 {
 18249   if (dpyinfo->screen_height)
 18250     return dpyinfo->screen_height;
 18251 
 18252   return HeightOfScreen (dpyinfo->screen);
 18253 }
 18254 
 18255 int
 18256 x_display_pixel_width (struct x_display_info *dpyinfo)
 18257 {
 18258   if (dpyinfo->screen_width)
 18259     return dpyinfo->screen_width;
 18260 
 18261   return WidthOfScreen (dpyinfo->screen);
 18262 }
 18263 
 18264 /* Handle events from each display until CELL's car becomes non-nil,
 18265    or TIMEOUT elapses.  */
 18266 void
 18267 x_wait_for_cell_change (Lisp_Object cell, struct timespec timeout)
 18268 {
 18269   struct x_display_info *dpyinfo;
 18270   fd_set fds;
 18271   int fd, maxfd;
 18272 #ifndef USE_GTK
 18273   int finish, rc;
 18274   XEvent event;
 18275   fd_set rfds;
 18276 #endif
 18277   struct input_event hold_quit;
 18278   struct timespec current, at;
 18279 
 18280   at = timespec_add (current_timespec (), timeout);
 18281 
 18282 #ifndef USE_GTK
 18283   FD_ZERO (&rfds);
 18284   rc = -1;
 18285 #endif
 18286 
 18287   while (true)
 18288     {
 18289       FD_ZERO (&fds);
 18290       maxfd = -1;
 18291 
 18292       for (dpyinfo = x_display_list; dpyinfo;
 18293            dpyinfo = dpyinfo->next)
 18294         {
 18295           fd = ConnectionNumber (dpyinfo->display);
 18296 
 18297 #ifndef USE_GTK
 18298           if ((rc < 0 || FD_ISSET (fd, &rfds))
 18299               /* If pselect failed, the erroring display's IO error
 18300                  handler will eventually be called.  */
 18301               && XPending (dpyinfo->display))
 18302             {
 18303               while (XPending (dpyinfo->display))
 18304                 {
 18305                   EVENT_INIT (hold_quit);
 18306 
 18307                   XNextEvent (dpyinfo->display, &event);
 18308                   handle_one_xevent (dpyinfo, &event,
 18309                                      &finish, &hold_quit);
 18310 
 18311                   if (!NILP (XCAR (cell)))
 18312                     return;
 18313 
 18314                   if (finish == X_EVENT_GOTO_OUT)
 18315                     break;
 18316 
 18317                   /* Make us quit now.  */
 18318                   if (hold_quit.kind != NO_EVENT)
 18319                     kbd_buffer_store_event (&hold_quit);
 18320                 }
 18321             }
 18322 #endif
 18323 
 18324           if (fd > maxfd)
 18325             maxfd = fd;
 18326 
 18327           eassert (fd < FD_SETSIZE);
 18328           FD_SET (fd, &fds);
 18329         }
 18330 
 18331       /* Prevent events from being lost (from GTK's point of view) by
 18332          using GDK to run the event loop.  */
 18333 #ifdef USE_GTK
 18334       while (gtk_events_pending ())
 18335         {
 18336           EVENT_INIT (hold_quit);
 18337           current_count = 0;
 18338           current_hold_quit = &hold_quit;
 18339           current_finish = X_EVENT_NORMAL;
 18340 
 18341           gtk_main_iteration ();
 18342 
 18343           current_count = -1;
 18344           current_hold_quit = NULL;
 18345 
 18346           /* Make us quit now.  */
 18347           if (hold_quit.kind != NO_EVENT)
 18348             kbd_buffer_store_event (&hold_quit);
 18349 
 18350           if (!NILP (XCAR (cell)))
 18351             return;
 18352 
 18353           if (current_finish == X_EVENT_GOTO_OUT)
 18354             break;
 18355         }
 18356 #endif
 18357 
 18358       eassert (maxfd >= 0);
 18359 
 18360       current = current_timespec ();
 18361 
 18362       if (timespec_cmp (at, current) < 0
 18363           || !NILP (XCAR (cell)))
 18364         return;
 18365 
 18366       timeout = timespec_sub (at, current);
 18367 
 18368 #ifndef USE_GTK
 18369       rc = pselect (maxfd + 1, &fds, NULL, NULL, &timeout, NULL);
 18370 
 18371       if (rc >= 0)
 18372         rfds = fds;
 18373 #else
 18374       pselect (maxfd + 1, &fds, NULL, NULL, &timeout, NULL);
 18375 #endif
 18376     }
 18377 }
 18378 
 18379 /* Find whether or not an undelivered MONITORS_CHANGED_EVENT is
 18380    already on the event queue.  DPYINFO is the display any such event
 18381    must apply to.  */
 18382 
 18383 static bool
 18384 x_find_monitors_changed_event (struct x_display_info *dpyinfo)
 18385 {
 18386   union buffered_input_event *event;
 18387 
 18388   event = kbd_fetch_ptr;
 18389 
 18390   while (event != kbd_store_ptr)
 18391     {
 18392       if (event->ie.kind == MONITORS_CHANGED_EVENT
 18393           && XTERMINAL (event->ie.arg) == dpyinfo->terminal)
 18394         return true;
 18395 
 18396       event = X_NEXT_KBD_EVENT (event);
 18397     }
 18398 
 18399   return false;
 18400 }
 18401 
 18402 #ifdef USE_GTK
 18403 static void
 18404 x_monitors_changed_cb (GdkScreen *gscr, gpointer user_data)
 18405 {
 18406   struct x_display_info *dpyinfo;
 18407   struct input_event ie;
 18408   Lisp_Object current_monitors, terminal;
 18409   GdkDisplay *gdpy;
 18410   Display *dpy;
 18411 
 18412   gdpy = gdk_screen_get_display (gscr);
 18413   dpy = gdk_x11_display_get_xdisplay (gdpy);
 18414   dpyinfo = x_display_info_for_display (dpy);
 18415 
 18416   if (!dpyinfo)
 18417     return;
 18418 
 18419   if (x_find_monitors_changed_event (dpyinfo))
 18420     return;
 18421 
 18422   XSETTERMINAL (terminal, dpyinfo->terminal);
 18423 
 18424   current_monitors
 18425     = Fx_display_monitor_attributes_list (terminal);
 18426 
 18427   if (NILP (Fequal (current_monitors,
 18428                     dpyinfo->last_monitor_attributes_list)))
 18429     {
 18430       EVENT_INIT (ie);
 18431       ie.kind = MONITORS_CHANGED_EVENT;
 18432       ie.arg = terminal;
 18433 
 18434       kbd_buffer_store_event (&ie);
 18435 
 18436       if (x_dnd_in_progress && x_dnd_update_tooltip)
 18437         x_dnd_monitors = current_monitors;
 18438 
 18439       x_dnd_update_tooltip_now ();
 18440     }
 18441 
 18442   dpyinfo->last_monitor_attributes_list = current_monitors;
 18443 }
 18444 #endif
 18445 
 18446 /* Extract the root window coordinates from the client message EVENT
 18447    if it is a message that we already understand.  Return false if the
 18448    event was not understood.  */
 18449 static bool
 18450 x_coords_from_dnd_message (struct x_display_info *dpyinfo,
 18451                            XEvent *event, int *x_out, int *y_out)
 18452 {
 18453   xm_drag_motion_message dmsg;
 18454   xm_drag_motion_reply dreply;
 18455   xm_drop_start_message smsg;
 18456   xm_drop_start_reply reply;
 18457   unsigned long kde_data;
 18458 
 18459   if (event->type != ClientMessage)
 18460     return false;
 18461 
 18462   if (event->xclient.message_type == dpyinfo->Xatom_XdndPosition)
 18463     {
 18464       if (event->xclient.format != 32)
 18465         return false;
 18466 
 18467       *x_out = (((unsigned long) event->xclient.data.l[2]) >> 16
 18468                 & 0xffff);
 18469       *y_out = (event->xclient.data.l[2] & 0xffff);
 18470 
 18471       return true;
 18472     }
 18473 
 18474   if ((event->xclient.message_type
 18475        == dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE)
 18476       && event->xclient.format == 8)
 18477     {
 18478       if (!xm_read_drag_motion_message (event, &dmsg))
 18479         {
 18480           *x_out = dmsg.x;
 18481           *y_out = dmsg.y;
 18482 
 18483           return true;
 18484         }
 18485       else if (!xm_read_drag_motion_reply (event, &dreply))
 18486         {
 18487           *x_out = dreply.better_x;
 18488           *y_out = dreply.better_y;
 18489 
 18490           return true;
 18491         }
 18492       else if (!xm_read_drop_start_message (event, &smsg))
 18493         {
 18494           *x_out = smsg.x;
 18495           *y_out = smsg.y;
 18496 
 18497           return true;
 18498         }
 18499       else if (!xm_read_drop_start_reply (event, &reply))
 18500         {
 18501           *x_out = reply.better_x;
 18502           *y_out = reply.better_y;
 18503 
 18504           return true;
 18505         }
 18506     }
 18507 
 18508   if (((event->xclient.message_type
 18509         == dpyinfo->Xatom_DndProtocol)
 18510        || (event->xclient.message_type
 18511            == dpyinfo->Xatom_DND_PROTOCOL))
 18512       && event->xclient.format == 32
 18513       /* Check that the version of the old KDE protocol is new
 18514          enough to include coordinates.  */
 18515       && event->xclient.data.l[4])
 18516     {
 18517       kde_data = (unsigned long) event->xclient.data.l[3];
 18518 
 18519       *x_out = (kde_data & 0xffff);
 18520       *y_out = (kde_data >> 16 & 0xffff);
 18521 
 18522       return true;
 18523     }
 18524 
 18525   return false;
 18526 }
 18527 
 18528 static void
 18529 x_handle_wm_state (struct frame *f, struct input_event *ie)
 18530 {
 18531   struct x_display_info *dpyinfo;
 18532   Atom type;
 18533   int format;
 18534   unsigned long nitems, bytes_after;
 18535   unsigned char *data;
 18536   unsigned long *state;
 18537 
 18538   data = NULL;
 18539   dpyinfo = FRAME_DISPLAY_INFO (f);
 18540 
 18541   if (XGetWindowProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 18542                           dpyinfo->Xatom_wm_state, 0, 2, False,
 18543                           AnyPropertyType, &type, &format, &nitems,
 18544                           &bytes_after, &data) != Success)
 18545     return;
 18546 
 18547   if (!data || nitems != 2 || format != 32)
 18548     {
 18549       if (data)
 18550         XFree (data);
 18551 
 18552       return;
 18553     }
 18554 
 18555   state = (unsigned long *) data;
 18556 
 18557   if (state[0] == NormalState && FRAME_ICONIFIED_P (f))
 18558     {
 18559       /* The frame has been deiconified.  It has not been withdrawn
 18560          and is now visible.  */
 18561       SET_FRAME_VISIBLE (f, 1);
 18562       SET_FRAME_ICONIFIED (f, false);
 18563       f->output_data.x->has_been_visible = true;
 18564 
 18565       ie->kind = DEICONIFY_EVENT;
 18566       XSETFRAME (ie->frame_or_window, f);
 18567     }
 18568   else if (state[0] == IconicState
 18569            /* _NET_WM_STATE_HIDDEN should be used if the window
 18570               manager supports that.  */
 18571            && !x_wm_supports (f, dpyinfo->Xatom_net_wm_state_hidden))
 18572     {
 18573       /* The frame is actually iconified right now.  Mark it as
 18574          such.  */
 18575 
 18576       SET_FRAME_VISIBLE (f, 0);
 18577       SET_FRAME_ICONIFIED (f, true);
 18578 
 18579       ie->kind = ICONIFY_EVENT;
 18580       XSETFRAME (ie->frame_or_window, f);
 18581     }
 18582 
 18583   /* state[0] can also be WithdrawnState, meaning that the window has
 18584      been withdrawn and is no longer iconified.  However, Emacs sets
 18585      the correct flags upon withdrawing the window, so there is no
 18586      need to do anything here.  */
 18587 
 18588   XFree (data);
 18589 }
 18590 
 18591 #ifdef HAVE_XFIXES
 18592 
 18593 static bool
 18594 x_handle_selection_monitor_event (struct x_display_info *dpyinfo,
 18595                                   const XEvent *event)
 18596 {
 18597   XFixesSelectionNotifyEvent *notify;
 18598   int i;
 18599 
 18600   notify = (XFixesSelectionNotifyEvent *) event;
 18601 
 18602   if (notify->window != dpyinfo->selection_tracking_window)
 18603     return false;
 18604 
 18605   for (i = 0; i < dpyinfo->n_monitored_selections; ++i)
 18606     {
 18607       /* We don't have to keep track of timestamps here.  */
 18608       if (notify->selection == dpyinfo->monitored_selections[i].name)
 18609         dpyinfo->monitored_selections[i].owner = notify->owner;
 18610     }
 18611 
 18612   return true;
 18613 }
 18614 
 18615 Window
 18616 x_find_selection_owner (struct x_display_info *dpyinfo, Atom selection)
 18617 {
 18618   int i;
 18619 
 18620   for (i = 0; i < dpyinfo->n_monitored_selections; ++i)
 18621     {
 18622       if (selection == dpyinfo->monitored_selections[i].name)
 18623         return dpyinfo->monitored_selections[i].owner;
 18624     }
 18625 
 18626   return X_INVALID_WINDOW;
 18627 }
 18628 
 18629 #endif
 18630 
 18631 /* Handles the XEvent EVENT on display DPYINFO.
 18632 
 18633    *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
 18634    *FINISH is zero if caller should continue reading events.
 18635    *FINISH is X_EVENT_DROP if event should not be passed to the toolkit.
 18636    *EVENT is unchanged unless we're processing KeyPress event.
 18637 
 18638    We return the number of characters stored into the buffer.  */
 18639 
 18640 static int
 18641 handle_one_xevent (struct x_display_info *dpyinfo,
 18642 #ifndef HAVE_XINPUT2
 18643                    const XEvent *event,
 18644 #else
 18645                    XEvent *event,
 18646 #endif
 18647                    int *finish, struct input_event *hold_quit)
 18648 {
 18649   union buffered_input_event inev;
 18650   int count = 0;
 18651   int do_help = 0;
 18652 #ifdef HAVE_XINPUT2
 18653   struct xi_device_t *gen_help_device;
 18654   Time gen_help_time UNINIT;
 18655 #endif
 18656   ptrdiff_t nbytes = 0;
 18657   struct frame *any, *f = NULL, *mouse_frame;
 18658   Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
 18659   /* This holds the state XLookupString needs to implement dead keys
 18660      and other tricks known as "compose processing".  _X Window System_
 18661      says that a portable program can't use this, but Stephen Gildea assures
 18662      me that letting the compiler initialize it to zeros will work okay.  */
 18663   static XComposeStatus compose_status;
 18664   XEvent configureEvent;
 18665   XEvent next_event;
 18666   Lisp_Object coding;
 18667 #if defined USE_X_TOOLKIT && defined HAVE_XINPUT2
 18668   /* Some XInput 2 events are important for Motif and Lucid menu bars
 18669      to work correctly, so they must be translated into core events
 18670      before being passed to XtDispatchEvent.  */
 18671   bool use_copy = false;
 18672   XEvent copy;
 18673 #elif defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
 18674   GdkEvent *copy = NULL;
 18675   GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 18676 #endif
 18677   int dx, dy;
 18678 
 18679   /* Avoid warnings when SAFE_ALLOCA is not actually used.  */
 18680 #if defined HAVE_XINPUT2 || defined HAVE_XKB || defined HAVE_X_I18N
 18681   USE_SAFE_ALLOCA;
 18682 #endif
 18683 
 18684   /* This function is not reentrant, so input should be blocked before
 18685      it is called.  */
 18686 
 18687   if (!input_blocked_p ())
 18688     emacs_abort ();
 18689 
 18690   *finish = X_EVENT_NORMAL;
 18691 
 18692   EVENT_INIT (inev.ie);
 18693   inev.ie.kind = NO_EVENT;
 18694   inev.ie.arg = Qnil;
 18695 #ifdef HAVE_XINPUT2
 18696   gen_help_device = NULL;
 18697 #endif
 18698 
 18699   /* Ignore events coming from various extensions, such as XFIXES and
 18700      XKB.  */
 18701   if (event->type < LASTEvent)
 18702     {
 18703 #ifdef HAVE_XINPUT2
 18704       if (event->type != GenericEvent)
 18705 #endif
 18706         any = x_any_window_to_frame (dpyinfo, event->xany.window);
 18707 #ifdef HAVE_XINPUT2
 18708       else
 18709         any = NULL;
 18710 #endif
 18711     }
 18712   else
 18713     any = NULL;
 18714 
 18715   if (any && any->wait_event_type == event->type)
 18716     any->wait_event_type = 0; /* Indicates we got it.  */
 18717 
 18718   switch (event->type)
 18719     {
 18720     case ClientMessage:
 18721       {
 18722         int rc;
 18723 
 18724         if (((x_dnd_in_progress
 18725               && FRAME_DISPLAY_INFO (x_dnd_frame) == dpyinfo)
 18726              || (x_dnd_waiting_for_finish
 18727                  && FRAME_DISPLAY_INFO (x_dnd_finish_frame) == dpyinfo))
 18728             && event->xclient.message_type == dpyinfo->Xatom_XdndStatus)
 18729           {
 18730             Window target;
 18731             unsigned long r1, r2;
 18732             int root_x, root_y;
 18733             bool button;
 18734 
 18735             target = event->xclient.data.l[0];
 18736 
 18737             if (x_dnd_last_protocol_version != -1
 18738                 && x_dnd_in_progress
 18739                 && target == x_dnd_last_seen_toplevel
 18740                 /* The XDND documentation is not very clearly worded.
 18741                    But this should be the correct behavior, since
 18742                    "kDNDStatusSendHereFlag" in the reference
 18743                    implementation is 2, and means the mouse rect
 18744                    should be ignored.  */
 18745                 && !(event->xclient.data.l[1] & 2))
 18746               {
 18747                 r1 = event->xclient.data.l[2];
 18748                 r2 = event->xclient.data.l[3];
 18749 
 18750                 x_dnd_mouse_rect_target = target;
 18751                 x_dnd_mouse_rect.x = (r1 & 0xffff0000) >> 16;
 18752                 x_dnd_mouse_rect.y = (r1 & 0xffff);
 18753                 x_dnd_mouse_rect.width = (r2 & 0xffff0000) >> 16;
 18754                 x_dnd_mouse_rect.height = (r2 & 0xffff);
 18755               }
 18756             else
 18757               x_dnd_mouse_rect_target = None;
 18758 
 18759             if (x_dnd_last_protocol_version != -1
 18760                 && (x_dnd_in_progress
 18761                     && target == x_dnd_last_seen_window))
 18762               {
 18763                 if (event->xclient.data.l[1] & 1)
 18764                   {
 18765                     if (x_dnd_last_protocol_version >= 2)
 18766                       x_dnd_action = event->xclient.data.l[4];
 18767                     else
 18768                       x_dnd_action = dpyinfo->Xatom_XdndActionCopy;
 18769                   }
 18770                 else
 18771                   x_dnd_action = None;
 18772               }
 18773 
 18774             /* Send any pending XdndPosition message.  */
 18775             if (x_dnd_waiting_for_status_window == target)
 18776               {
 18777                 if (x_dnd_pending_send_position.type != 0)
 18778                   {
 18779                     /* If the last XdndStatus specified a mouse
 18780                        rectangle and this event falls inside, don't
 18781                        send the event, but clear
 18782                        x_dnd_waiting_for_status_window instead.  */
 18783 
 18784                     root_x = x_dnd_pending_send_position_root_x;
 18785                     root_y = x_dnd_pending_send_position_root_y;
 18786                     button = x_dnd_pending_send_position_button;
 18787 
 18788                     if (target == x_dnd_mouse_rect_target
 18789                         && x_dnd_mouse_rect.width
 18790                         && x_dnd_mouse_rect.height
 18791                         /* Ignore the mouse rectangle if we're
 18792                            supposed to be sending a button press
 18793                            instead.  */
 18794                         && !button
 18795                         && (root_x >= x_dnd_mouse_rect.x
 18796                             && root_x < (x_dnd_mouse_rect.x
 18797                                          + x_dnd_mouse_rect.width)
 18798                             && root_y >= x_dnd_mouse_rect.y
 18799                             && root_y < (x_dnd_mouse_rect.y
 18800                                          + x_dnd_mouse_rect.height)))
 18801                       x_dnd_waiting_for_status_window = None;
 18802                     else
 18803                       {
 18804                         x_ignore_errors_for_next_request (dpyinfo, 0);
 18805                         XSendEvent (dpyinfo->display, target,
 18806                                     False, NoEventMask,
 18807                                     &x_dnd_pending_send_position);
 18808                         x_stop_ignoring_errors (dpyinfo);
 18809                         x_dnd_pending_send_position.type = 0;
 18810 
 18811                         /* Since we sent another XdndPosition message, we
 18812                            have to wait for another one in reply, so don't
 18813                            reset `x_dnd_waiting_for_status_window'
 18814                            here.  */
 18815                       }
 18816                   }
 18817                 else
 18818                   x_dnd_waiting_for_status_window = None;
 18819 
 18820                 /* Send any pending drop if warranted.  */
 18821                 if (x_dnd_waiting_for_finish && x_dnd_need_send_drop
 18822                     && x_dnd_waiting_for_status_window == None)
 18823                   {
 18824                     if (event->xclient.data.l[1] & 1)
 18825                       {
 18826                         if (x_dnd_send_drop_proto >= 2)
 18827                           x_dnd_action = event->xclient.data.l[4];
 18828                         else
 18829                           x_dnd_action = dpyinfo->Xatom_XdndActionCopy;
 18830                       }
 18831                     else
 18832                       x_dnd_action = None;
 18833 
 18834                     x_dnd_waiting_for_finish
 18835                       = x_dnd_send_drop (x_dnd_finish_frame,
 18836                                          target,
 18837                                          x_dnd_last_seen_toplevel,
 18838                                          x_dnd_selection_timestamp,
 18839                                          x_dnd_send_drop_proto);
 18840                   }
 18841               }
 18842 
 18843             goto done;
 18844           }
 18845 
 18846         if (event->xclient.message_type == dpyinfo->Xatom_XdndFinished
 18847             && (x_dnd_waiting_for_finish && !x_dnd_waiting_for_motif_finish)
 18848             /* Also check that the display is correct, since
 18849                `x_dnd_pending_finish_target' could still be valid on
 18850                another X server.  */
 18851             && dpyinfo->display == x_dnd_finish_display
 18852             && event->xclient.data.l[0] == x_dnd_pending_finish_target)
 18853           {
 18854             x_dnd_waiting_for_finish = false;
 18855 
 18856             if (x_dnd_waiting_for_finish_proto >= 5)
 18857               x_dnd_action = event->xclient.data.l[2];
 18858 
 18859             if (x_dnd_waiting_for_finish_proto >= 5
 18860                 && !(event->xclient.data.l[1] & 1))
 18861               x_dnd_action = None;
 18862 
 18863             goto done;
 18864           }
 18865 
 18866         if ((event->xclient.message_type
 18867              == dpyinfo->Xatom_MOTIF_DRAG_AND_DROP_MESSAGE)
 18868             && x_dnd_waiting_for_finish
 18869             && x_dnd_waiting_for_motif_finish == 1
 18870             && dpyinfo == x_dnd_waiting_for_motif_finish_display)
 18871           {
 18872             xm_drop_start_reply reply;
 18873             uint16_t operation, status, action;
 18874 
 18875             if (!xm_read_drop_start_reply (event, &reply))
 18876               {
 18877                 operation = XM_DRAG_SIDE_EFFECT_OPERATION (reply.side_effects);
 18878                 status = XM_DRAG_SIDE_EFFECT_SITE_STATUS (reply.side_effects);
 18879                 action = XM_DRAG_SIDE_EFFECT_DROP_ACTION (reply.side_effects);
 18880 
 18881                 if (operation != XM_DRAG_MOVE
 18882                     && operation != XM_DRAG_COPY
 18883                     && XM_DRAG_OPERATION_IS_LINK (operation))
 18884                   {
 18885                     x_dnd_waiting_for_finish = false;
 18886                     goto done;
 18887                   }
 18888 
 18889                 if (status != XM_DROP_SITE_VALID
 18890                     || (action == XM_DROP_ACTION_DROP_CANCEL
 18891                         || action == XM_DROP_ACTION_DROP_HELP))
 18892                   {
 18893                     x_dnd_waiting_for_finish = false;
 18894                     goto done;
 18895                   }
 18896 
 18897                 switch (operation)
 18898                   {
 18899                   case XM_DRAG_MOVE:
 18900                     x_dnd_action_symbol = QXdndActionMove;
 18901                     break;
 18902 
 18903                   case XM_DRAG_COPY:
 18904                     x_dnd_action_symbol = QXdndActionCopy;
 18905                     break;
 18906 
 18907                     /* This means XM_DRAG_OPERATION_IS_LINK (operation).  */
 18908                   default:
 18909                     x_dnd_action_symbol = QXdndActionLink;
 18910                     break;
 18911                   }
 18912 
 18913                 x_dnd_waiting_for_motif_finish = 2;
 18914                 goto done;
 18915               }
 18916           }
 18917 
 18918         if (event->xclient.message_type == dpyinfo->Xatom_EMACS_TMP
 18919             && event->xclient.format == 8)
 18920           {
 18921             /* This is actually an hourglass message.  Set whether or
 18922                not events from here on have the hourglass enabled.  */
 18923 
 18924             if (any)
 18925               FRAME_X_OUTPUT (any)->hourglass_p = event->xclient.data.b[0];
 18926           }
 18927 
 18928         if (event->xclient.message_type == dpyinfo->Xatom_wm_protocols
 18929             && event->xclient.format == 32)
 18930           {
 18931             if (event->xclient.data.l[0] == dpyinfo->Xatom_wm_take_focus)
 18932               {
 18933                 /* Use the value returned by x_any_window_to_frame
 18934                    because this could be the shell widget window
 18935                    if the frame has no title bar.  */
 18936                 f = any;
 18937 #ifdef HAVE_X_I18N
 18938                 /* Not quite sure this is needed -pd */
 18939                 if (f && FRAME_XIC (f))
 18940                   XSetICFocus (FRAME_XIC (f));
 18941 #endif
 18942 #if false
 18943       /* Emacs sets WM hints whose `input' field is `true'.  This
 18944          instructs the WM to set the input focus automatically for
 18945          Emacs with a call to XSetInputFocus.  Setting WM_TAKE_FOCUS
 18946          tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
 18947          it has set the focus.  So, XSetInputFocus below is not
 18948          needed.
 18949 
 18950          The call to XSetInputFocus below has also caused trouble.  In
 18951          cases where the XSetInputFocus done by the WM and the one
 18952          below are temporally close (on a fast machine), the call
 18953          below can generate additional FocusIn events which confuse
 18954          Emacs.  */
 18955 
 18956                 /* Since we set WM_TAKE_FOCUS, we must call
 18957                    XSetInputFocus explicitly.  But not if f is null,
 18958                    since that might be an event for a deleted frame.  */
 18959                 if (f)
 18960                   {
 18961                     Display *d = event->xclient.display;
 18962                     /* Catch and ignore errors, in case window has been
 18963                        iconified by a window manager such as GWM.  */
 18964                     x_catch_errors (d);
 18965                     XSetInputFocus (d, event->xclient.window,
 18966                                     /* The ICCCM says this is
 18967                                        the only valid choice.  */
 18968                                     RevertToParent,
 18969                                     event->xclient.data.l[1]);
 18970                     x_uncatch_errors ();
 18971                   }
 18972                 /* Not certain about handling scroll bars here */
 18973 #endif
 18974                 /* Set the provided time as the user time, which is
 18975                    required for SetInputFocus to work correctly after
 18976                    taking the input focus.  */
 18977 
 18978                 /* Time can be sign extended if retrieved from a client message.
 18979                    Make sure it is always 32 bits, or systems with 64-bit longs
 18980                    will crash after 24 days of X server uptime.  (bug#59480) */
 18981                 x_display_set_last_user_time (dpyinfo, (event->xclient.data.l[1]
 18982                                                         & 0xffffffff),
 18983                                               true, true);
 18984                 goto done;
 18985               }
 18986 
 18987             if (event->xclient.data.l[0] == dpyinfo->Xatom_wm_save_yourself)
 18988               {
 18989                 /* Save state modify the WM_COMMAND property to
 18990                    something which can reinstate us.  This notifies
 18991                    the session manager, who's looking for such a
 18992                    PropertyNotify.  Can restart processing when
 18993                    a keyboard or mouse event arrives.  */
 18994                 /* If we have a session manager, don't set this.
 18995                    KDE will then start two Emacsen, one for the
 18996                    session manager and one for this. */
 18997 #ifdef HAVE_X_SM
 18998                 if (! x_session_have_connection ())
 18999 #endif
 19000                   {
 19001                     f = x_top_window_to_frame (dpyinfo,
 19002                                                event->xclient.window);
 19003                     /* This is just so we only give real data once
 19004                        for a single Emacs process.  */
 19005                     if (f == SELECTED_FRAME ())
 19006                       XSetCommand (FRAME_X_DISPLAY (f),
 19007                                    event->xclient.window,
 19008                                    initial_argv, initial_argc);
 19009                     else if (f)
 19010                       XSetCommand (FRAME_X_DISPLAY (f),
 19011                                    event->xclient.window,
 19012                                    0, 0);
 19013                   }
 19014                 goto done;
 19015               }
 19016 
 19017             if (event->xclient.data.l[0] == dpyinfo->Xatom_wm_delete_window)
 19018               {
 19019                 f = x_top_window_to_frame (dpyinfo,
 19020                                            event->xclient.window);
 19021 
 19022                 if (!f)
 19023                   goto OTHER; /* May be a dialog that is to be removed  */
 19024 
 19025                 inev.ie.kind = DELETE_WINDOW_EVENT;
 19026                 inev.ie.timestamp = event->xclient.data.l[1];
 19027                 XSETFRAME (inev.ie.frame_or_window, f);
 19028                 goto done;
 19029               }
 19030 
 19031 
 19032             if (event->xclient.data.l[0] == dpyinfo->Xatom_net_wm_ping
 19033                 /* Handling window stacking changes during
 19034                    drag-and-drop requires Emacs to select for
 19035                    SubstructureNotifyMask, which in turn causes the
 19036                    message to be sent to Emacs itself using the event
 19037                    mask specified by the EWMH.  To avoid an infinite
 19038                    loop, make sure the client message's window is not
 19039                    the root window if DND is in progress.  */
 19040                 && (!(x_dnd_in_progress
 19041                       || x_dnd_waiting_for_finish)
 19042                     || event->xclient.window != dpyinfo->root_window)
 19043                 && event->xclient.format == 32)
 19044               {
 19045                 XEvent send_event = *event;
 19046 
 19047                 send_event.xclient.window = dpyinfo->root_window;
 19048                 XSendEvent (dpyinfo->display, dpyinfo->root_window, False,
 19049                             SubstructureRedirectMask | SubstructureNotifyMask,
 19050                             &send_event);
 19051 
 19052                 *finish = X_EVENT_DROP;
 19053                 goto done;
 19054               }
 19055 
 19056 #if defined HAVE_XSYNC
 19057             if (event->xclient.data.l[0] == dpyinfo->Xatom_net_wm_sync_request
 19058                 && event->xclient.format == 32
 19059                 && dpyinfo->xsync_supported_p)
 19060               {
 19061                 struct frame *f
 19062                   = x_top_window_to_frame (dpyinfo,
 19063                                            event->xclient.window);
 19064 #if defined HAVE_GTK3
 19065                 GtkWidget *widget;
 19066                 GdkWindow *window;
 19067                 GdkFrameClock *frame_clock;
 19068 #endif
 19069 
 19070                 if (f)
 19071                   {
 19072 #ifndef HAVE_GTK3
 19073                     if (event->xclient.data.l[4] == 0)
 19074                       {
 19075                         XSyncIntsToValue (&FRAME_X_OUTPUT (f)->pending_basic_counter_value,
 19076                                           event->xclient.data.l[2], event->xclient.data.l[3]);
 19077                         FRAME_X_OUTPUT (f)->sync_end_pending_p = true;
 19078                       }
 19079                     else if (event->xclient.data.l[4] == 1)
 19080                       {
 19081                         XSyncIntsToValue (&FRAME_X_OUTPUT (f)->resize_counter_value,
 19082                                           event->xclient.data.l[2],
 19083                                           event->xclient.data.l[3]);
 19084 
 19085                         FRAME_X_OUTPUT (f)->ext_sync_end_pending_p = true;
 19086                       }
 19087 
 19088                     *finish = X_EVENT_DROP;
 19089 #else
 19090                     widget = FRAME_GTK_OUTER_WIDGET (f);
 19091                     window = gtk_widget_get_window (widget);
 19092                     eassert (window);
 19093 
 19094                     /* This could be a (former) child frame for which
 19095                        frame synchronization was disabled.  Enable it
 19096                        now.  */
 19097                     gdk_x11_window_set_frame_sync_enabled (window, TRUE);
 19098 
 19099                     if (widget && !FRAME_X_OUTPUT (f)->xg_sync_end_pending_p)
 19100                       {
 19101                         frame_clock = gdk_window_get_frame_clock (window);
 19102                         eassert (frame_clock);
 19103 
 19104                         gdk_frame_clock_request_phase (frame_clock,
 19105                                                        GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT);
 19106                         FRAME_X_OUTPUT (f)->xg_sync_end_pending_p = true;
 19107                       }
 19108 #endif
 19109                     goto done;
 19110                   }
 19111               }
 19112 #endif
 19113 
 19114             goto done;
 19115           }
 19116 
 19117         if (event->xclient.message_type == dpyinfo->Xatom_wm_configure_denied)
 19118           goto done;
 19119 
 19120         if (event->xclient.message_type == dpyinfo->Xatom_wm_window_moved)
 19121           {
 19122             int new_x, new_y;
 19123             f = x_window_to_frame (dpyinfo, event->xclient.window);
 19124 
 19125             new_x = event->xclient.data.s[0];
 19126             new_y = event->xclient.data.s[1];
 19127 
 19128             if (f)
 19129               {
 19130                 f->left_pos = new_x;
 19131                 f->top_pos = new_y;
 19132               }
 19133             goto done;
 19134           }
 19135 
 19136 #ifdef X_TOOLKIT_EDITRES
 19137         if (event->xclient.message_type == dpyinfo->Xatom_editres)
 19138           {
 19139             f = any;
 19140             if (f)
 19141               {
 19142                 _XEditResCheckMessages (f->output_data.x->widget,
 19143                                         NULL, (XEvent *) event, NULL);
 19144                 goto done;
 19145               }
 19146 
 19147             goto OTHER;
 19148           }
 19149 #endif /* X_TOOLKIT_EDITRES */
 19150 
 19151         if (event->xclient.message_type == dpyinfo->Xatom_DONE
 19152             || event->xclient.message_type == dpyinfo->Xatom_PAGE)
 19153           {
 19154             /* Ghostview job completed.  Kill it.  We could
 19155                reply with "Next" if we received "Page", but we
 19156                currently never do because we are interested in
 19157                images, only, which should have 1 page.  */
 19158             f = x_window_to_frame (dpyinfo, event->xclient.window);
 19159             if (!f)
 19160               goto OTHER;
 19161 #ifndef USE_CAIRO
 19162             Pixmap pixmap = (Pixmap) event->xclient.data.l[1];
 19163             /* FIXME: why does this sometimes generate a BadMatch
 19164                error?  */
 19165             x_catch_errors (dpyinfo->display);
 19166             x_kill_gs_process (pixmap, f);
 19167             x_uncatch_errors ();
 19168             expose_frame (f, 0, 0, 0, 0);
 19169 #endif  /* !USE_CAIRO */
 19170             goto done;
 19171           }
 19172 
 19173 #ifdef USE_TOOLKIT_SCROLL_BARS
 19174         /* Scroll bar callbacks send a ClientMessage from which
 19175            we construct an input_event.  */
 19176         if (event->xclient.message_type == dpyinfo->Xatom_Scrollbar)
 19177           {
 19178             /* Convert the scroll bar event to an input event using
 19179                the first window entered into the scroll bar event
 19180                queue. */
 19181             x_scroll_bar_to_input_event (dpyinfo, event, &inev.ie);
 19182 
 19183             *finish = X_EVENT_GOTO_OUT;
 19184             goto done;
 19185           }
 19186         else if (event->xclient.message_type == dpyinfo->Xatom_Horizontal_Scrollbar)
 19187           {
 19188             /* Convert the horizontal scroll bar event to an input
 19189                event using the first window entered into the scroll
 19190                bar event queue. */
 19191             x_horizontal_scroll_bar_to_input_event (dpyinfo, event,
 19192                                                     &inev.ie);
 19193 
 19194             *finish = X_EVENT_GOTO_OUT;
 19195             goto done;
 19196           }
 19197 #endif /* USE_TOOLKIT_SCROLL_BARS */
 19198 
 19199         /* XEmbed messages from the embedder (if any).  */
 19200         if (event->xclient.message_type == dpyinfo->Xatom_XEMBED)
 19201           {
 19202             enum xembed_message msg = event->xclient.data.l[1];
 19203             if (msg == XEMBED_FOCUS_IN || msg == XEMBED_FOCUS_OUT)
 19204               x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 19205 
 19206             *finish = X_EVENT_GOTO_OUT;
 19207             goto done;
 19208           }
 19209 
 19210 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
 19211         /* These messages are sent by the compositing manager after a
 19212            frame is drawn under extended synchronization.  */
 19213         if (event->xclient.message_type
 19214             == dpyinfo->Xatom_net_wm_frame_drawn)
 19215           {
 19216             if (any)
 19217               x_sync_handle_frame_drawn (dpyinfo, (XEvent *) event, any);
 19218 
 19219             goto done;
 19220           }
 19221 
 19222         if (event->xclient.message_type
 19223             == dpyinfo->Xatom_net_wm_frame_timings)
 19224           goto done;
 19225 #endif
 19226 
 19227         if (xft_settings_event (dpyinfo, event))
 19228           goto done;
 19229 
 19230         f = any;
 19231         /* We don't want to ever leak tooltip frames to Lisp code.  */
 19232         if (!f || FRAME_TOOLTIP_P (f))
 19233           goto OTHER;
 19234 
 19235         /* These values are always used initialized, but GCC doesn't
 19236            know that.  */
 19237         dx = 0;
 19238         dy = 0;
 19239 
 19240         rc = x_coords_from_dnd_message (dpyinfo, (XEvent *) event,
 19241                                         &dx, &dy);
 19242 
 19243         if (x_handle_dnd_message (f, &event->xclient, dpyinfo, &inev.ie,
 19244                                   rc, dx, dy))
 19245           *finish = X_EVENT_DROP;
 19246       }
 19247       break;
 19248 
 19249     case SelectionNotify:
 19250 #if defined USE_X_TOOLKIT || defined USE_GTK
 19251       if (!x_window_to_frame (dpyinfo, event->xselection.requestor))
 19252         goto OTHER;
 19253 #endif /* not USE_X_TOOLKIT and not USE_GTK */
 19254 #ifdef HAVE_GTK3
 19255       /* GTK 3 apparently chokes on these events since they have no
 19256          associated device.  (bug#56869, another bug as well that I
 19257          can't find) */
 19258       *finish = X_EVENT_DROP;
 19259 #endif
 19260       x_handle_selection_notify (&event->xselection);
 19261       break;
 19262 
 19263     case SelectionClear:        /* Someone has grabbed ownership.  */
 19264 #if defined USE_X_TOOLKIT || defined USE_GTK
 19265       if (!x_window_to_frame (dpyinfo, event->xselectionclear.window))
 19266         goto OTHER;
 19267 #endif /* not USE_X_TOOLKIT and not USE_GTK */
 19268 #ifdef HAVE_GTK3
 19269       *finish = X_EVENT_DROP;
 19270 #endif
 19271       {
 19272         const XSelectionClearEvent *eventp = &event->xselectionclear;
 19273 
 19274         if (eventp->selection == dpyinfo->motif_drag_atom
 19275             && (eventp->time == CurrentTime
 19276                 || dpyinfo->motif_drag_atom_time <= eventp->time))
 19277           dpyinfo->motif_drag_atom = None;
 19278 
 19279         inev.sie.kind = SELECTION_CLEAR_EVENT;
 19280         SELECTION_EVENT_DPYINFO (&inev.sie) = dpyinfo;
 19281         SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
 19282         SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
 19283 
 19284         if (x_use_pending_selection_requests)
 19285           {
 19286             x_push_selection_request (&inev.sie);
 19287             EVENT_INIT (inev.ie);
 19288           }
 19289       }
 19290       break;
 19291 
 19292     case SelectionRequest:      /* Someone wants our selection.  */
 19293 #ifdef USE_X_TOOLKIT
 19294       if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner))
 19295         goto OTHER;
 19296 #endif /* USE_X_TOOLKIT */
 19297 #ifdef HAVE_GTK3
 19298       *finish = X_EVENT_DROP;
 19299 #endif
 19300       {
 19301         const XSelectionRequestEvent *eventp = &event->xselectionrequest;
 19302 
 19303         inev.sie.kind = SELECTION_REQUEST_EVENT;
 19304         SELECTION_EVENT_DPYINFO (&inev.sie) = dpyinfo;
 19305         SELECTION_EVENT_REQUESTOR (&inev.sie) = eventp->requestor;
 19306         SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
 19307         SELECTION_EVENT_TARGET (&inev.sie) = eventp->target;
 19308         SELECTION_EVENT_PROPERTY (&inev.sie) = eventp->property;
 19309         SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
 19310 
 19311         /* If drag-and-drop or another modal dialog/menu is in
 19312            progress, handle SelectionRequest events immediately, by
 19313            pushing it onto the selection queue.  */
 19314 
 19315         if (x_use_pending_selection_requests)
 19316           {
 19317             x_push_selection_request (&inev.sie);
 19318             EVENT_INIT (inev.ie);
 19319           }
 19320 
 19321         if (x_dnd_waiting_for_finish
 19322             && x_dnd_waiting_for_motif_finish == 2
 19323             && dpyinfo == x_dnd_waiting_for_motif_finish_display
 19324             && eventp->selection == x_dnd_motif_atom
 19325             && (eventp->target == dpyinfo->Xatom_XmTRANSFER_SUCCESS
 19326                 || eventp->target == dpyinfo->Xatom_XmTRANSFER_FAILURE))
 19327           {
 19328             x_dnd_waiting_for_finish = false;
 19329 
 19330             /* If the transfer failed, then return nil from
 19331                `x-begin-drag'.  */
 19332             if (eventp->target == dpyinfo->Xatom_XmTRANSFER_FAILURE)
 19333               x_dnd_action = None;
 19334           }
 19335       }
 19336       break;
 19337 
 19338     case PropertyNotify:
 19339       if (x_dnd_in_progress && x_dnd_use_toplevels
 19340           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)
 19341           && event->xproperty.atom == dpyinfo->Xatom_wm_state)
 19342         {
 19343           struct x_client_list_window *tem, *last;
 19344 
 19345           for (last = NULL, tem = x_dnd_toplevels; tem;
 19346                last = tem, tem = tem->next)
 19347             {
 19348               if (tem->window == event->xproperty.window)
 19349                 {
 19350                   Atom actual_type;
 19351                   int actual_format, rc;
 19352                   unsigned long nitems, bytesafter;
 19353                   unsigned char *data = NULL;
 19354 
 19355                   if (event->xproperty.state == PropertyDelete)
 19356                     {
 19357                       if (!last)
 19358                         x_dnd_toplevels = tem->next;
 19359                       else
 19360                         last->next = tem->next;
 19361 
 19362 #ifdef HAVE_XSHAPE
 19363                       if (tem->n_input_rects != -1)
 19364                         xfree (tem->input_rects);
 19365                       if (tem->n_bounding_rects != -1)
 19366                         xfree (tem->bounding_rects);
 19367 #endif
 19368                       xfree (tem);
 19369                     }
 19370                   else
 19371                     {
 19372                       x_catch_errors (dpyinfo->display);
 19373                       rc = XGetWindowProperty (dpyinfo->display,
 19374                                                event->xproperty.window,
 19375                                                dpyinfo->Xatom_wm_state,
 19376                                                0, 2, False, AnyPropertyType,
 19377                                                &actual_type, &actual_format,
 19378                                                &nitems, &bytesafter, &data);
 19379 
 19380                       if (!x_had_errors_p (dpyinfo->display) && rc == Success && data
 19381                           && nitems == 2 && actual_format == 32)
 19382                         tem->wm_state = ((unsigned long *) data)[0];
 19383                       else
 19384                         tem->wm_state = WithdrawnState;
 19385 
 19386                       if (data)
 19387                         XFree (data);
 19388                       x_uncatch_errors_after_check ();
 19389                     }
 19390 
 19391                   x_dnd_update_state (dpyinfo, event->xproperty.time);
 19392                   break;
 19393                 }
 19394             }
 19395         }
 19396 
 19397       f = x_top_window_to_frame (dpyinfo, event->xproperty.window);
 19398       if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state
 19399           /* This should never happen with embedded windows.  */
 19400           && !FRAME_X_EMBEDDED_P (f))
 19401         {
 19402           bool not_hidden = x_handle_net_wm_state (f, &event->xproperty);
 19403 
 19404           if (not_hidden && FRAME_ICONIFIED_P (f))
 19405             {
 19406               if (CONSP (frame_size_history))
 19407                 frame_size_history_plain
 19408                   (f, build_string ("PropertyNotify, not hidden & iconified"));
 19409 
 19410               /* Gnome shell does not iconify us when C-z is pressed.
 19411                  It hides the frame.  So if our state says we aren't
 19412                  hidden anymore, treat it as deiconified.  */
 19413               SET_FRAME_VISIBLE (f, 1);
 19414               SET_FRAME_ICONIFIED (f, false);
 19415 
 19416               f->output_data.x->has_been_visible = true;
 19417               inev.ie.kind = DEICONIFY_EVENT;
 19418 #if defined USE_GTK && defined HAVE_GTK3
 19419               /* If GTK3 wants to impose some old size here (Bug#24526),
 19420                  tell it that the current size is what we want.  */
 19421               if (f->was_invisible)
 19422                 {
 19423                   xg_frame_set_char_size
 19424                     (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
 19425                   f->was_invisible = false;
 19426                 }
 19427 #endif
 19428               XSETFRAME (inev.ie.frame_or_window, f);
 19429             }
 19430           else if (!not_hidden && !FRAME_ICONIFIED_P (f))
 19431             {
 19432               if (CONSP (frame_size_history))
 19433                 frame_size_history_plain
 19434                   (f, build_string ("PropertyNotify, hidden & not iconified"));
 19435 
 19436               SET_FRAME_VISIBLE (f, 0);
 19437               SET_FRAME_ICONIFIED (f, true);
 19438               inev.ie.kind = ICONIFY_EVENT;
 19439               XSETFRAME (inev.ie.frame_or_window, f);
 19440             }
 19441         }
 19442 
 19443       if (f && event->xproperty.atom == dpyinfo->Xatom_wm_state
 19444           && !FRAME_X_EMBEDDED_P (f) && !FRAME_PARENT_FRAME (f))
 19445         /* Handle WM_STATE.  We use this to clear the iconified flag
 19446            on a frame if it is set.
 19447 
 19448            GTK builds ignore deiconifying frames on FocusIn or Expose
 19449            by default, and cannot wait for the window manager to
 19450            remove _NET_WM_STATE_HIDDEN, as it is ambiguous when not
 19451            set.  Handling UnmapNotify also checks for
 19452            _NET_WM_STATE_HIDDEN, and thus suffers from the same
 19453            problem.  */
 19454         x_handle_wm_state (f, &inev.ie);
 19455 
 19456       if (f && FRAME_X_OUTPUT (f)->alpha_identical_p
 19457           && (event->xproperty.atom
 19458               == dpyinfo->Xatom_net_wm_window_opacity))
 19459         {
 19460 #ifndef USE_XCB
 19461           int rc, actual_format;
 19462           Atom actual;
 19463           unsigned char *tmp_data;
 19464           unsigned long n, left, opacity;
 19465 
 19466           tmp_data = NULL;
 19467 #else
 19468           xcb_get_property_cookie_t opacity_cookie;
 19469           xcb_get_property_reply_t *opacity_reply;
 19470           xcb_generic_error_t *error;
 19471           bool rc;
 19472           uint32_t value;
 19473 #endif
 19474 
 19475           if (event->xproperty.state == PropertyDelete)
 19476             {
 19477               f->alpha[0] = 1.0;
 19478               f->alpha[1] = 1.0;
 19479 
 19480               store_frame_param (f, Qalpha, Qnil);
 19481             }
 19482           else
 19483             {
 19484 #ifndef USE_XCB
 19485               rc = XGetWindowProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
 19486                                        dpyinfo->Xatom_net_wm_window_opacity,
 19487                                        0, 1, False, AnyPropertyType, &actual,
 19488                                        &actual_format, &n, &left, &tmp_data);
 19489 
 19490               if (rc == Success && actual_format == 32
 19491                   && (actual == XA_CARDINAL
 19492                       /* Some broken programs set the opacity property
 19493                          to those types, but window managers accept
 19494                          them anyway.  */
 19495                       || actual == XA_ATOM
 19496                       || actual == XA_WINDOW) && n)
 19497                 {
 19498                   opacity = *(unsigned long *) tmp_data & OPAQUE;
 19499                   f->alpha[0] = (double) opacity / (double) OPAQUE;
 19500                   f->alpha[1] = (double) opacity / (double) OPAQUE;
 19501 
 19502                   store_frame_param (f, Qalpha, make_float (f->alpha[0]));
 19503                 }
 19504               else
 19505                 {
 19506                   f->alpha[0] = 1.0;
 19507                   f->alpha[1] = 1.0;
 19508 
 19509                   store_frame_param (f, Qalpha, Qnil);
 19510                 }
 19511 #else
 19512               opacity_cookie
 19513                 = xcb_get_property (dpyinfo->xcb_connection, 0,
 19514                                     (xcb_window_t) FRAME_OUTER_WINDOW (f),
 19515                                     (xcb_atom_t) dpyinfo->Xatom_net_wm_window_opacity,
 19516                                     XA_CARDINAL, 0, 1);
 19517               opacity_reply
 19518                 = xcb_get_property_reply (dpyinfo->xcb_connection,
 19519                                           opacity_cookie, &error);
 19520 
 19521               if (!opacity_reply)
 19522                 free (error), rc = false;
 19523               else
 19524                 rc = (opacity_reply->format == 32
 19525                       && (opacity_reply->type == XA_CARDINAL
 19526                           || opacity_reply->type == XA_ATOM
 19527                           || opacity_reply->type == XA_WINDOW)
 19528                       && (xcb_get_property_value_length (opacity_reply) >= 4));
 19529 
 19530               if (rc)
 19531                 {
 19532                   value = *(uint32_t *) xcb_get_property_value (opacity_reply);
 19533 
 19534                   f->alpha[0] = (double) value / (double) OPAQUE;
 19535                   f->alpha[1] = (double) value / (double) OPAQUE;
 19536                   store_frame_param (f, Qalpha, make_float (f->alpha[0]));
 19537                 }
 19538               else
 19539                 {
 19540                   f->alpha[0] = 1.0;
 19541                   f->alpha[1] = 1.0;
 19542 
 19543                   store_frame_param (f, Qalpha, Qnil);
 19544                 }
 19545 
 19546               if (opacity_reply)
 19547                 free (opacity_reply);
 19548 #endif
 19549             }
 19550 
 19551 #ifndef USE_XCB
 19552           if (tmp_data)
 19553             XFree (tmp_data);
 19554 #endif
 19555         }
 19556 
 19557       if (event->xproperty.window == dpyinfo->root_window
 19558           && (event->xproperty.atom == dpyinfo->Xatom_net_client_list_stacking
 19559               || event->xproperty.atom == dpyinfo->Xatom_net_current_desktop)
 19560           && x_dnd_in_progress
 19561           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 19562         {
 19563           if (x_dnd_use_toplevels)
 19564             {
 19565               x_dnd_free_toplevels (true);
 19566 
 19567               if (x_dnd_compute_toplevels (dpyinfo))
 19568                 {
 19569                   x_dnd_free_toplevels (true);
 19570                   x_dnd_use_toplevels = false;
 19571                 }
 19572             }
 19573 
 19574           x_dnd_update_state (dpyinfo, event->xproperty.time);
 19575         }
 19576 
 19577       x_handle_property_notify (&event->xproperty);
 19578       xft_settings_event (dpyinfo, event);
 19579       goto OTHER;
 19580 
 19581     case ReparentNotify:
 19582       f = x_top_window_to_frame (dpyinfo, event->xreparent.window);
 19583       if (f)
 19584         {
 19585 #ifndef USE_GTK
 19586           if (FRAME_OUTPUT_DATA (f)->parent_desc
 19587               && FRAME_X_EMBEDDED_P (f))
 19588             {
 19589               /* The frame's embedder was destroyed; mark the frame as
 19590                  no longer embedded, and map the frame.  An
 19591                  UnmapNotify event must have previously been received
 19592                  during the start of save-set processing.  */
 19593 
 19594               FRAME_X_OUTPUT (f)->explicit_parent = false;
 19595 
 19596               /* Remove the leftover XEMBED_INFO property.  */
 19597               XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
 19598                                dpyinfo->Xatom_XEMBED_INFO);
 19599               x_make_frame_visible (f);
 19600             }
 19601 #endif
 19602 
 19603           /* Maybe we shouldn't set this for child frames ??  */
 19604           f->output_data.x->parent_desc = event->xreparent.parent;
 19605 
 19606           if (!FRAME_PARENT_FRAME (f))
 19607             {
 19608               x_real_positions (f, &f->left_pos, &f->top_pos);
 19609 
 19610               /* Perhaps reparented due to a WM restart.  Reset this.  */
 19611               dpyinfo->wm_type = X_WMTYPE_UNKNOWN;
 19612               dpyinfo->net_supported_window = 0;
 19613 
 19614 #ifndef USE_GTK
 19615               /* The window manager could have restarted and the new
 19616                  window manager might not support user time windows,
 19617                  so update what is used accordingly.
 19618 
 19619                  Note that this doesn't handle changes between
 19620                  non-reparenting window managers.  */
 19621               if (FRAME_X_OUTPUT (f)->has_been_visible)
 19622                 x_update_frame_user_time_window (f);
 19623 #endif
 19624             }
 19625           else
 19626             {
 19627               Window root;
 19628               unsigned int dummy_uint;
 19629 
 19630               XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 19631                             &root, &f->left_pos, &f->top_pos,
 19632                             &dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint);
 19633             }
 19634 
 19635           x_set_frame_alpha (f);
 19636         }
 19637       goto OTHER;
 19638 
 19639     case Expose:
 19640 
 19641 #ifdef HAVE_XWIDGETS
 19642       {
 19643         struct xwidget_view *xv;
 19644 
 19645         xv = xwidget_view_from_window (event->xexpose.window);
 19646 
 19647         if (xv)
 19648           {
 19649             xwidget_expose (xv);
 19650             goto OTHER;
 19651           }
 19652       }
 19653 #endif
 19654 
 19655       f = x_window_to_frame (dpyinfo, event->xexpose.window);
 19656       if (f)
 19657         {
 19658           if (!FRAME_VISIBLE_P (f))
 19659             {
 19660               /* By default, do not set the frame's visibility here, see
 19661                  https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
 19662                  The default behavior can be overridden by setting
 19663                  'x-set-frame-visibility-more-laxly' (Bug#49955,
 19664                  Bug#53298).  */
 19665               if (EQ (x_set_frame_visibility_more_laxly, Qexpose)
 19666                   || EQ (x_set_frame_visibility_more_laxly, Qt))
 19667                 {
 19668                   SET_FRAME_VISIBLE (f, 1);
 19669                   SET_FRAME_ICONIFIED (f, false);
 19670                 }
 19671 
 19672 #ifdef HAVE_XDBE
 19673               if (FRAME_X_DOUBLE_BUFFERED_P (f))
 19674                 x_drop_xrender_surfaces (f);
 19675 #endif
 19676               f->output_data.x->has_been_visible = true;
 19677               SET_FRAME_GARBAGED (f);
 19678             }
 19679           else if (FRAME_GARBAGED_P (f))
 19680             {
 19681 #ifdef USE_GTK
 19682               /* Go around the back buffer and manually clear the
 19683                  window the first time we show it.  This way, we avoid
 19684                  showing users the sanity-defying horror of whatever
 19685                  GtkWindow is rendering beneath us.  We've garbaged
 19686                  the frame, so we'll redraw the whole thing on next
 19687                  redisplay anyway.  Yuck.  */
 19688               x_clear_area1 (FRAME_X_DISPLAY (f),
 19689                              FRAME_X_WINDOW (f),
 19690                              event->xexpose.x, event->xexpose.y,
 19691                              event->xexpose.width, event->xexpose.height,
 19692                              0);
 19693               x_clear_under_internal_border (f);
 19694 #endif
 19695             }
 19696 
 19697           if (!FRAME_GARBAGED_P (f))
 19698             {
 19699 #if defined USE_X_TOOLKIT && defined USE_TOOLKIT_SCROLL_BARS
 19700               if (f->output_data.x->edit_widget)
 19701                 /* The widget's expose proc will be run in this
 19702                    case.  */
 19703                 goto OTHER;
 19704 #endif
 19705 #ifdef USE_GTK
 19706               /* This seems to be needed for GTK 2.6 and later, see
 19707                  https://debbugs.gnu.org/cgi/bugreport.cgi?bug=15398.  */
 19708               x_clear_area (f,
 19709                             event->xexpose.x, event->xexpose.y,
 19710                             event->xexpose.width, event->xexpose.height);
 19711 #endif
 19712               expose_frame (f, event->xexpose.x, event->xexpose.y,
 19713                             event->xexpose.width, event->xexpose.height);
 19714 #ifndef USE_TOOLKIT_SCROLL_BARS
 19715               x_scroll_bar_handle_exposure (f, (XEvent *) event);
 19716 #endif
 19717 #ifdef USE_GTK
 19718               x_clear_under_internal_border (f);
 19719 #endif
 19720             }
 19721 #ifndef USE_TOOLKIT_SCROLL_BARS
 19722           else
 19723             x_scroll_bar_handle_exposure (f, (XEvent *) event);
 19724 #endif
 19725 
 19726 #ifdef HAVE_XDBE
 19727           if (!FRAME_GARBAGED_P (f))
 19728             show_back_buffer (f);
 19729 #endif
 19730         }
 19731       else
 19732         {
 19733 #if defined USE_LUCID
 19734           /* Submenus of the Lucid menu bar aren't widgets
 19735              themselves, so there's no way to dispatch events
 19736              to them.  Recognize this case separately.  */
 19737           {
 19738             Widget widget = x_window_to_menu_bar (event->xexpose.window);
 19739             if (widget)
 19740               xlwmenu_redisplay (widget);
 19741           }
 19742 #endif /* USE_LUCID */
 19743 
 19744           /* Dispatch event to the widget.  */
 19745           goto OTHER;
 19746         }
 19747       break;
 19748 
 19749     case GraphicsExpose:        /* This occurs when an XCopyArea's
 19750                                    source area was obscured or not
 19751                                    available.  */
 19752       f = x_window_to_frame (dpyinfo, event->xgraphicsexpose.drawable);
 19753       if (f)
 19754         {
 19755           expose_frame (f, event->xgraphicsexpose.x,
 19756                         event->xgraphicsexpose.y,
 19757                         event->xgraphicsexpose.width,
 19758                         event->xgraphicsexpose.height);
 19759 #ifndef USE_TOOLKIT_SCROLL_BARS
 19760           x_scroll_bar_handle_exposure (f, (XEvent *) event);
 19761 #endif
 19762 #ifdef USE_GTK
 19763           x_clear_under_internal_border (f);
 19764 #endif
 19765 #ifdef HAVE_XDBE
 19766           show_back_buffer (f);
 19767 #endif
 19768         }
 19769 #ifdef USE_X_TOOLKIT
 19770       else
 19771         goto OTHER;
 19772 #endif /* USE_X_TOOLKIT */
 19773       break;
 19774 
 19775     case NoExpose:              /* This occurs when an XCopyArea's
 19776                                    source area was completely
 19777                                    available.  */
 19778 #ifdef USE_X_TOOLKIT
 19779       *finish = X_EVENT_DROP;
 19780 #endif
 19781       break;
 19782 
 19783     case UnmapNotify:
 19784       if (x_dnd_in_progress && x_dnd_use_toplevels
 19785           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 19786         {
 19787           for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
 19788                tem = tem->next)
 19789             {
 19790               if (tem->window == event->xunmap.window)
 19791                 {
 19792                   tem->mapped_p = false;
 19793                   break;
 19794                 }
 19795             }
 19796         }
 19797 
 19798       /* Redo the mouse-highlight after the tooltip has gone.  */
 19799       if (event->xunmap.window == tip_window)
 19800         {
 19801           tip_window = None;
 19802           gui_redo_mouse_highlight (dpyinfo);
 19803         }
 19804 
 19805       f = x_top_window_to_frame (dpyinfo, event->xunmap.window);
 19806       if (f)            /* F may no longer exist if
 19807                            the frame was deleted.  */
 19808         {
 19809           bool visible = FRAME_VISIBLE_P (f);
 19810 
 19811 #ifdef USE_LUCID
 19812           /* Bloodcurdling hack alert: The Lucid menu bar widget's
 19813              redisplay procedure is not called when a tip frame over
 19814              menu items is unmapped.  Redisplay the menu manually...  */
 19815           if (FRAME_TOOLTIP_P (f) && popup_activated ())
 19816             {
 19817               Widget w;
 19818               Lisp_Object tail, frame;
 19819               struct frame *f1;
 19820 
 19821               FOR_EACH_FRAME (tail, frame)
 19822                 {
 19823                   if (!FRAME_X_P (XFRAME (frame)))
 19824                     continue;
 19825 
 19826                   f1 = XFRAME (frame);
 19827 
 19828                   if (FRAME_LIVE_P (f1))
 19829                     {
 19830                       w = FRAME_X_OUTPUT (f1)->menubar_widget;
 19831 
 19832                       if (w && !DoesSaveUnders (FRAME_DISPLAY_INFO (f1)->screen))
 19833                         xlwmenu_redisplay (w);
 19834                     }
 19835                 }
 19836             }
 19837 #endif /* USE_LUCID */
 19838 
 19839           /* While a frame is unmapped, display generation is
 19840              disabled; you don't want to spend time updating a
 19841              display that won't ever be seen.  */
 19842           SET_FRAME_VISIBLE (f, 0);
 19843           /* We can't distinguish, from the event, whether the window
 19844              has become iconified or invisible.  So assume, if it
 19845              was previously visible, than now it is iconified.
 19846              But x_make_frame_invisible clears both
 19847              the visible flag and the iconified flag;
 19848              and that way, we know the window is not iconified now.  */
 19849           if (visible || FRAME_ICONIFIED_P (f))
 19850             {
 19851               if (CONSP (frame_size_history))
 19852                 frame_size_history_plain
 19853                   (f, build_string ("UnmapNotify, visible | iconified"));
 19854 
 19855               SET_FRAME_ICONIFIED (f, true);
 19856               inev.ie.kind = ICONIFY_EVENT;
 19857               XSETFRAME (inev.ie.frame_or_window, f);
 19858             }
 19859           else if (CONSP (frame_size_history))
 19860             frame_size_history_plain
 19861               (f, build_string ("UnmapNotify, not visible & not iconified"));
 19862         }
 19863       goto OTHER;
 19864 
 19865     case MapNotify:
 19866 #if defined HAVE_XINPUT2 && defined HAVE_GTK3
 19867       if (xg_is_menu_window (dpyinfo->display, event->xmap.window))
 19868         popup_activated_flag = 1;
 19869 #endif
 19870 
 19871       if (x_dnd_in_progress
 19872           /* When _NET_WM_CLIENT_LIST stacking is being used, changes
 19873              in that property are watched for, and it's not necessary
 19874              to update the state in response to ordinary window
 19875              substructure events.  */
 19876           && !x_dnd_use_toplevels
 19877           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 19878         x_dnd_update_state (dpyinfo, dpyinfo->last_user_time);
 19879 
 19880       if (x_dnd_in_progress && x_dnd_use_toplevels
 19881           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 19882         {
 19883           for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
 19884                tem = tem->next)
 19885             {
 19886               if (tem->window == event->xmap.window)
 19887                 {
 19888                   tem->mapped_p = true;
 19889                   break;
 19890                 }
 19891             }
 19892         }
 19893 
 19894       /* We use x_top_window_to_frame because map events can
 19895          come for sub-windows and they don't mean that the
 19896          frame is visible.  */
 19897       f = x_top_window_to_frame (dpyinfo, event->xmap.window);
 19898       if (f)
 19899         {
 19900           bool iconified = FRAME_ICONIFIED_P (f);
 19901           int value;
 19902           bool sticky, shaded;
 19903           bool not_hidden = x_get_current_wm_state (f, event->xmap.window, &value, &sticky,
 19904                                                     &shaded);
 19905 
 19906           if (CONSP (frame_size_history))
 19907             frame_size_history_extra
 19908               (f,
 19909                iconified
 19910                ? (not_hidden
 19911                   ? build_string ("MapNotify, not hidden & iconified")
 19912                   : build_string ("MapNotify, hidden & iconified"))
 19913                : (not_hidden
 19914                   ? build_string ("MapNotify, not hidden & not iconified")
 19915                   : build_string ("MapNotify, hidden & not iconified")),
 19916                FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
 19917                -1, -1, f->new_width, f->new_height);
 19918 
 19919           /* Check if fullscreen was specified before we where mapped the
 19920              first time, i.e. from the command line.  */
 19921           if (!f->output_data.x->has_been_visible)
 19922             {
 19923 
 19924               x_check_fullscreen (f);
 19925 #ifndef USE_GTK
 19926               /* For systems that cannot synthesize `skip_taskbar' for
 19927                  unmapped windows do the following.  */
 19928               if (FRAME_SKIP_TASKBAR (f))
 19929                 x_set_skip_taskbar (f, Qt, Qnil);
 19930 #endif /* Not USE_GTK */
 19931             }
 19932 
 19933           if (!iconified)
 19934             {
 19935               /* The `z-group' is reset every time a frame becomes
 19936                  invisible.  Handle this here.  */
 19937               if (FRAME_Z_GROUP (f) == z_group_above)
 19938                 x_set_z_group (f, Qabove, Qnil);
 19939               else if (FRAME_Z_GROUP (f) == z_group_below)
 19940                 x_set_z_group (f, Qbelow, Qnil);
 19941             }
 19942 
 19943           /* Embedded frames might have NET_WM_STATE left over, but
 19944              are always visible once mapped.  */
 19945           if (not_hidden || FRAME_X_EMBEDDED_P (f))
 19946             {
 19947               SET_FRAME_VISIBLE (f, 1);
 19948               SET_FRAME_ICONIFIED (f, false);
 19949 #if defined USE_GTK && defined HAVE_GTK3
 19950               /* If GTK3 wants to impose some old size here (Bug#24526),
 19951                  tell it that the current size is what we want.  */
 19952               if (f->was_invisible)
 19953                 {
 19954                   xg_frame_set_char_size
 19955                     (f, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
 19956                   f->was_invisible = false;
 19957                 }
 19958 #endif
 19959               f->output_data.x->has_been_visible = true;
 19960             }
 19961 
 19962           x_update_opaque_region (f, NULL);
 19963 
 19964           if ((not_hidden || FRAME_X_EMBEDDED_P (f)) && iconified)
 19965             {
 19966               inev.ie.kind = DEICONIFY_EVENT;
 19967               XSETFRAME (inev.ie.frame_or_window, f);
 19968             }
 19969         }
 19970       goto OTHER;
 19971 
 19972     case KeyPress:
 19973       x_display_set_last_user_time (dpyinfo, event->xkey.time,
 19974                                     event->xkey.send_event,
 19975                                     true);
 19976       ignore_next_mouse_click_timeout = 0;
 19977 
 19978       coding = Qlatin_1;
 19979 
 19980 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 19981       /* Dispatch KeyPress events when in menu.  */
 19982       if (popup_activated ())
 19983         goto OTHER;
 19984 #endif
 19985 
 19986       f = any;
 19987 
 19988 #ifdef USE_GTK
 19989       if (f)
 19990         x_set_gtk_user_time (f, event->xkey.time);
 19991 #endif
 19992 
 19993       /* If mouse-highlight is an integer, input clears out
 19994          mouse highlighting.  */
 19995       if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
 19996           && (f == 0
 19997 #if ! defined (USE_GTK)
 19998               || !EQ (f->tool_bar_window, hlinfo->mouse_face_window)
 19999 #endif
 20000               || !EQ (f->tab_bar_window, hlinfo->mouse_face_window))
 20001           )
 20002         {
 20003           mouse_frame = hlinfo->mouse_face_mouse_frame;
 20004 
 20005           clear_mouse_face (hlinfo);
 20006           hlinfo->mouse_face_hidden = true;
 20007 
 20008           if (mouse_frame)
 20009             x_flush_dirty_back_buffer_on (mouse_frame);
 20010         }
 20011 
 20012 #if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
 20013       if (f == 0)
 20014         {
 20015           /* Scroll bars consume key events, but we want
 20016              the keys to go to the scroll bar's frame.  */
 20017           Widget widget = XtWindowToWidget (dpyinfo->display,
 20018                                             event->xkey.window);
 20019           if (widget && XmIsScrollBar (widget))
 20020             {
 20021               widget = XtParent (widget);
 20022               f = x_any_window_to_frame (dpyinfo, XtWindow (widget));
 20023             }
 20024         }
 20025 #endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
 20026 
 20027       if (f != 0)
 20028         {
 20029           KeySym keysym, orig_keysym;
 20030           /* al%imercury@uunet.uu.net says that making this 81
 20031              instead of 80 fixed a bug whereby meta chars made
 20032              his Emacs hang.
 20033 
 20034              It seems that some version of XmbLookupString has
 20035              a bug of not returning XBufferOverflow in
 20036              status_return even if the input is too long to
 20037              fit in 81 bytes.  So, we must prepare sufficient
 20038              bytes for copy_buffer.  513 bytes (256 chars for
 20039              two-byte character set) seems to be a fairly good
 20040              approximation.  -- 2000.8.10 handa@gnu.org  */
 20041           unsigned char copy_buffer[513];
 20042           unsigned char *copy_bufptr = copy_buffer;
 20043           int copy_bufsiz = sizeof (copy_buffer);
 20044           int modifiers;
 20045           Lisp_Object c;
 20046           /* `xkey' will be modified, but it's not important to modify
 20047              `event' itself.  */
 20048           XKeyEvent xkey = event->xkey;
 20049 
 20050           if (event->xkey.window == FRAME_X_WINDOW (f))
 20051             /* See the comment above x_compute_root_window_offset for
 20052                why this optimization is performed.  */
 20053             x_compute_root_window_offset (f, event->xkey.x_root,
 20054                                           event->xkey.y_root,
 20055                                           event->xkey.x, event->xkey.y);
 20056 
 20057 #ifdef HAVE_XINPUT2
 20058           Time pending_keystroke_time;
 20059           struct xi_device_t *source;
 20060 
 20061           pending_keystroke_time = dpyinfo->pending_keystroke_time;
 20062 
 20063           if (event->xkey.time >= pending_keystroke_time)
 20064             {
 20065 #if defined USE_GTK && !defined HAVE_GTK3
 20066               if (!dpyinfo->pending_keystroke_time_special_p)
 20067 #endif
 20068                 dpyinfo->pending_keystroke_time = 0;
 20069 #if defined USE_GTK && !defined HAVE_GTK3
 20070               else
 20071                 dpyinfo->pending_keystroke_time_special_p = false;
 20072 #endif
 20073             }
 20074 #endif
 20075 
 20076 #ifdef USE_GTK
 20077           /* Don't pass keys to GTK.  A Tab will shift focus to the
 20078              tool bar in GTK 2.4.  Keys will still go to menus and
 20079              dialogs because in that case popup_activated is nonzero
 20080              (see above).  */
 20081           *finish = X_EVENT_DROP;
 20082 #endif
 20083 
 20084           xkey.state |= x_emacs_to_x_modifiers (dpyinfo,
 20085                                                 extra_keyboard_modifiers);
 20086           modifiers = xkey.state;
 20087 
 20088           /* This will have to go some day...  */
 20089 
 20090           /* make_lispy_event turns chars into control chars.
 20091              Don't do it here because XLookupString is too eager.  */
 20092           xkey.state &= ~ControlMask;
 20093           xkey.state &= ~(dpyinfo->meta_mod_mask
 20094                           | dpyinfo->super_mod_mask
 20095                           | dpyinfo->hyper_mod_mask
 20096                           | dpyinfo->alt_mod_mask);
 20097 
 20098           /* In case Meta is ComposeCharacter,
 20099              clear its status.  According to Markus Ehrnsperger
 20100              Markus.Ehrnsperger@lehrstuhl-bross.physik.uni-muenchen.de
 20101              this enables ComposeCharacter to work whether or
 20102              not it is combined with Meta.  */
 20103           if (modifiers & dpyinfo->meta_mod_mask)
 20104             memset (&compose_status, 0, sizeof (compose_status));
 20105 
 20106 #ifdef HAVE_X_I18N
 20107           if (FRAME_XIC (f))
 20108             {
 20109               Status status_return;
 20110 
 20111               nbytes = XmbLookupString (FRAME_XIC (f),
 20112                                         &xkey, (char *) copy_bufptr,
 20113                                         copy_bufsiz, &keysym,
 20114                                         &status_return);
 20115               coding = FRAME_X_XIM_CODING (f);
 20116               if (status_return == XBufferOverflow)
 20117                 {
 20118                   copy_bufsiz = nbytes + 1;
 20119                   copy_bufptr = SAFE_ALLOCA (copy_bufsiz);
 20120                   nbytes = XmbLookupString (FRAME_XIC (f),
 20121                                             &xkey, (char *) copy_bufptr,
 20122                                             copy_bufsiz, &keysym,
 20123                                             &status_return);
 20124                 }
 20125               /* Xutf8LookupString is a new but already deprecated interface.  -stef  */
 20126               if (status_return == XLookupNone)
 20127                 break;
 20128               else if (status_return == XLookupChars)
 20129                 {
 20130                   keysym = NoSymbol;
 20131                   modifiers = 0;
 20132                 }
 20133               else if (status_return != XLookupKeySym
 20134                        && status_return != XLookupBoth)
 20135                 emacs_abort ();
 20136             }
 20137           else
 20138 #endif
 20139             {
 20140 #ifdef HAVE_XKB
 20141               int overflow;
 20142               unsigned int consumed;
 20143 
 20144               if (dpyinfo->xkb_desc)
 20145                 {
 20146                   if (!XkbTranslateKeyCode (dpyinfo->xkb_desc,
 20147                                             xkey.keycode, xkey.state,
 20148                                             &consumed, &keysym))
 20149                     goto done_keysym;
 20150 
 20151                   overflow = 0;
 20152 
 20153                   nbytes = XkbTranslateKeySym (dpyinfo->display, &keysym,
 20154                                                xkey.state & ~consumed,
 20155                                                (char *) copy_bufptr,
 20156                                                copy_bufsiz, &overflow);
 20157 
 20158                   if (overflow)
 20159                     {
 20160                       copy_bufptr = SAFE_ALLOCA ((copy_bufsiz += overflow)
 20161                                                  * sizeof *copy_bufptr);
 20162                       overflow = 0;
 20163                       nbytes = XkbTranslateKeySym (dpyinfo->display, &keysym,
 20164                                                    xkey.state & ~consumed,
 20165                                                    (char *) copy_bufptr,
 20166                                                    copy_bufsiz, &overflow);
 20167 
 20168                       if (overflow)
 20169                         nbytes = 0;
 20170                     }
 20171 
 20172                   if (nbytes)
 20173                     coding = Qnil;
 20174                 }
 20175               else
 20176 #endif
 20177                 nbytes = XLookupString (&xkey, (char *) copy_bufptr,
 20178                                         copy_bufsiz, &keysym,
 20179                                         &compose_status);
 20180             }
 20181 
 20182 #ifdef XK_F1
 20183           if (x_dnd_in_progress && keysym == XK_F1)
 20184             {
 20185               x_dnd_xm_use_help = true;
 20186               goto done_keysym;
 20187             }
 20188 #endif
 20189 
 20190           /* See if keysym should make Emacs quit.  */
 20191 
 20192           if (keysym == dpyinfo->quit_keysym
 20193               && (xkey.time - dpyinfo->quit_keysym_time
 20194                   <= 350))
 20195             {
 20196               Vquit_flag = Qt;
 20197               goto done_keysym;
 20198             }
 20199 
 20200           if (keysym == dpyinfo->quit_keysym)
 20201             {
 20202               /* Otherwise, set the last time that keysym was
 20203                  pressed.  */
 20204               dpyinfo->quit_keysym_time = xkey.time;
 20205               goto done_keysym;
 20206             }
 20207 
 20208           /* If not using XIM/XIC, and a compose sequence is in progress,
 20209              we break here.  Otherwise, chars_matched is always 0.  */
 20210           if (compose_status.chars_matched > 0 && nbytes == 0)
 20211             break;
 20212 
 20213           memset (&compose_status, 0, sizeof (compose_status));
 20214           orig_keysym = keysym;
 20215 
 20216           /* Common for all keysym input events.  */
 20217           XSETFRAME (inev.ie.frame_or_window, f);
 20218           inev.ie.modifiers
 20219             = x_x_to_emacs_modifiers (dpyinfo, modifiers);
 20220           inev.ie.timestamp = xkey.time;
 20221 
 20222           /* First deal with keysyms which have defined
 20223              translations to characters.  */
 20224           if (keysym >= 32 && keysym < 128)
 20225             /* Avoid explicitly decoding each ASCII character.  */
 20226             {
 20227               inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 20228               inev.ie.code = keysym;
 20229 
 20230 #ifdef HAVE_XINPUT2
 20231               if (event->xkey.time == pending_keystroke_time)
 20232                 {
 20233                   source = xi_device_from_id (dpyinfo,
 20234                                               dpyinfo->pending_keystroke_source);
 20235 
 20236                   if (source)
 20237                     inev.ie.device = source->name;
 20238                 }
 20239 #endif
 20240 
 20241               goto done_keysym;
 20242             }
 20243 
 20244           /* Keysyms directly mapped to Unicode characters.  */
 20245           if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
 20246             {
 20247               if (keysym < 0x01000080)
 20248                 inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 20249               else
 20250                 inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 20251               inev.ie.code = keysym & 0xFFFFFF;
 20252 
 20253 #ifdef HAVE_XINPUT2
 20254               if (event->xkey.time == pending_keystroke_time)
 20255                 {
 20256                   source = xi_device_from_id (dpyinfo,
 20257                                               dpyinfo->pending_keystroke_source);
 20258 
 20259                   if (source)
 20260                     inev.ie.device = source->name;
 20261                 }
 20262 #endif
 20263 
 20264               goto done_keysym;
 20265             }
 20266 
 20267           /* Now non-ASCII.  */
 20268           if (HASH_TABLE_P (Vx_keysym_table)
 20269               && (c = Fgethash (make_fixnum (keysym),
 20270                                 Vx_keysym_table,
 20271                                 Qnil),
 20272                   FIXNATP (c)))
 20273             {
 20274               inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
 20275                               ? ASCII_KEYSTROKE_EVENT
 20276                               : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
 20277               inev.ie.code = XFIXNAT (c);
 20278 
 20279 #ifdef HAVE_XINPUT2
 20280               if (event->xkey.time == pending_keystroke_time)
 20281                 {
 20282                   source = xi_device_from_id (dpyinfo,
 20283                                               dpyinfo->pending_keystroke_source);
 20284 
 20285                   if (source)
 20286                     inev.ie.device = source->name;
 20287                 }
 20288 #endif
 20289 
 20290               goto done_keysym;
 20291             }
 20292 
 20293           /* Random non-modifier sorts of keysyms.  */
 20294           if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
 20295                || keysym == XK_Delete
 20296 #ifdef XK_ISO_Left_Tab
 20297                || (keysym >= XK_ISO_Left_Tab
 20298                    && keysym <= XK_ISO_Enter)
 20299 #endif
 20300                || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
 20301                || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
 20302 #ifdef HPUX
 20303                /* This recognizes the "extended function
 20304                   keys".  It seems there's no cleaner way.
 20305                   Test IsModifierKey to avoid handling
 20306                   mode_switch incorrectly.  */
 20307                || (XK_Select <= keysym && keysym < XK_KP_Space)
 20308 #endif
 20309 #ifdef XK_dead_circumflex
 20310                || orig_keysym == XK_dead_circumflex
 20311 #endif
 20312 #ifdef XK_dead_grave
 20313                || orig_keysym == XK_dead_grave
 20314 #endif
 20315 #ifdef XK_dead_tilde
 20316                || orig_keysym == XK_dead_tilde
 20317 #endif
 20318 #ifdef XK_dead_diaeresis
 20319                || orig_keysym == XK_dead_diaeresis
 20320 #endif
 20321 #ifdef XK_dead_macron
 20322                || orig_keysym == XK_dead_macron
 20323 #endif
 20324 #ifdef XK_dead_degree
 20325                || orig_keysym == XK_dead_degree
 20326 #endif
 20327 #ifdef XK_dead_acute
 20328                || orig_keysym == XK_dead_acute
 20329 #endif
 20330 #ifdef XK_dead_cedilla
 20331                || orig_keysym == XK_dead_cedilla
 20332 #endif
 20333 #ifdef XK_dead_breve
 20334                || orig_keysym == XK_dead_breve
 20335 #endif
 20336 #ifdef XK_dead_ogonek
 20337                || orig_keysym == XK_dead_ogonek
 20338 #endif
 20339 #ifdef XK_dead_caron
 20340                || orig_keysym == XK_dead_caron
 20341 #endif
 20342 #ifdef XK_dead_doubleacute
 20343                || orig_keysym == XK_dead_doubleacute
 20344 #endif
 20345 #ifdef XK_dead_abovedot
 20346                || orig_keysym == XK_dead_abovedot
 20347 #endif
 20348 #ifdef XK_dead_abovering
 20349                || orig_keysym == XK_dead_abovering
 20350 #endif
 20351 #ifdef XK_dead_belowdot
 20352                || orig_keysym == XK_dead_belowdot
 20353 #endif
 20354 #ifdef XK_dead_voiced_sound
 20355                || orig_keysym == XK_dead_voiced_sound
 20356 #endif
 20357 #ifdef XK_dead_semivoiced_sound
 20358                || orig_keysym == XK_dead_semivoiced_sound
 20359 #endif
 20360 #ifdef XK_dead_hook
 20361                || orig_keysym == XK_dead_hook
 20362 #endif
 20363 #ifdef XK_dead_horn
 20364                || orig_keysym == XK_dead_horn
 20365 #endif
 20366 #ifdef XK_dead_stroke
 20367                || orig_keysym == XK_dead_stroke
 20368 #endif
 20369 #ifdef XK_dead_abovecomma
 20370                || orig_keysym == XK_dead_abovecomma
 20371 #endif
 20372                || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
 20373                || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
 20374                /* Any "vendor-specific" key is ok.  */
 20375                || (orig_keysym & (1 << 28))
 20376                || (keysym != NoSymbol && nbytes == 0))
 20377               && ! (IsModifierKey (orig_keysym)
 20378                     /* The symbols from XK_ISO_Lock
 20379                        to XK_ISO_Last_Group_Lock
 20380                        don't have real modifiers but
 20381                        should be treated similarly to
 20382                        Mode_switch by Emacs. */
 20383 #if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock
 20384                     || (XK_ISO_Lock <= orig_keysym
 20385                         && orig_keysym <= XK_ISO_Last_Group_Lock)
 20386 #endif
 20387                     ))
 20388             {
 20389               STORE_KEYSYM_FOR_DEBUG (keysym);
 20390               /* make_lispy_event will convert this to a symbolic
 20391                  key.  */
 20392               inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
 20393               inev.ie.code = keysym;
 20394 
 20395 #ifdef HAVE_XINPUT2
 20396               if (event->xkey.time == pending_keystroke_time)
 20397                 {
 20398                   source = xi_device_from_id (dpyinfo,
 20399                                               dpyinfo->pending_keystroke_source);
 20400 
 20401                   if (source)
 20402                     inev.ie.device = source->name;
 20403                 }
 20404 #endif
 20405 
 20406               goto done_keysym;
 20407             }
 20408 
 20409           {     /* Raw bytes, not keysym.  */
 20410             ptrdiff_t i;
 20411 
 20412             for (i = 0; i < nbytes; i++)
 20413               {
 20414                 STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]);
 20415               }
 20416 
 20417             if (nbytes)
 20418               {
 20419                 inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 20420                 inev.ie.arg = make_unibyte_string ((char *) copy_bufptr, nbytes);
 20421 
 20422                 Fput_text_property (make_fixnum (0), make_fixnum (nbytes),
 20423                                     Qcoding, coding, inev.ie.arg);
 20424 
 20425 #ifdef HAVE_XINPUT2
 20426                 if (event->xkey.time == pending_keystroke_time
 20427                     /* I-Bus sometimes sends events generated from
 20428                        multiple filtered keystrokes with a time of 0,
 20429                        so just use the recorded source device if it
 20430                        exists.  */
 20431                     || (pending_keystroke_time && !event->xkey.time))
 20432                   {
 20433                     source = xi_device_from_id (dpyinfo,
 20434                                                 dpyinfo->pending_keystroke_source);
 20435 
 20436                     if (source)
 20437                       inev.ie.device = source->name;
 20438                   }
 20439 #endif
 20440               }
 20441 
 20442             if (keysym == NoSymbol)
 20443               break;
 20444           }
 20445         }
 20446     done_keysym:
 20447 #ifdef HAVE_X_I18N
 20448       if (f)
 20449         {
 20450           struct window *w = XWINDOW (f->selected_window);
 20451           xic_set_preeditarea (w, w->cursor.x, w->cursor.y);
 20452 
 20453           if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
 20454             xic_set_statusarea (f);
 20455         }
 20456 
 20457       /* Don't dispatch this event since XtDispatchEvent calls
 20458          XFilterEvent, and two calls in a row may freeze the
 20459          client.  */
 20460       break;
 20461 #else
 20462       goto OTHER;
 20463 #endif
 20464 
 20465     case KeyRelease:
 20466 #ifdef HAVE_X_I18N
 20467       /* Don't dispatch this event since XtDispatchEvent calls
 20468          XFilterEvent, and two calls in a row may freeze the
 20469          client.  */
 20470       break;
 20471 #else
 20472       goto OTHER;
 20473 #endif
 20474 
 20475     case EnterNotify:
 20476       x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
 20477                                     event->xcrossing.send_event,
 20478                                     false);
 20479 
 20480 #ifdef HAVE_XWIDGETS
 20481       {
 20482         struct xwidget_view *xvw;
 20483         Mouse_HLInfo *hlinfo;
 20484 
 20485         xvw = xwidget_view_from_window (event->xcrossing.window);
 20486 
 20487         if (xvw)
 20488           {
 20489             xwidget_motion_or_crossing (xvw, event);
 20490             hlinfo = MOUSE_HL_INFO (xvw->frame);
 20491 
 20492             if (xvw->frame == hlinfo->mouse_face_mouse_frame)
 20493               {
 20494                 clear_mouse_face (hlinfo);
 20495                 hlinfo->mouse_face_mouse_frame = 0;
 20496                 x_flush_dirty_back_buffer_on (xvw->frame);
 20497               }
 20498 
 20499             if (any_help_event_p)
 20500               do_help = -1;
 20501 
 20502             goto OTHER;
 20503           }
 20504       }
 20505 #endif
 20506 
 20507 #ifdef HAVE_XINPUT2
 20508       /* For whatever reason, the X server continues to deliver
 20509          EnterNotify and LeaveNotify events despite us selecting for
 20510          related XI_Enter and XI_Leave events.  It's not just our
 20511          problem, since windows created by "xinput test-xi2" suffer
 20512          from the same defect.  Simply ignore all such events while
 20513          the input extension is enabled.  (bug#57468) */
 20514 
 20515       if (dpyinfo->supports_xi2)
 20516         goto OTHER;
 20517 #endif
 20518 
 20519       if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
 20520         x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 20521 
 20522       f = any;
 20523 
 20524       if (f && event->xcrossing.window == FRAME_X_WINDOW (f))
 20525         x_compute_root_window_offset (f, event->xcrossing.x_root,
 20526                                       event->xcrossing.y_root,
 20527                                       event->xcrossing.x,
 20528                                       event->xcrossing.y);
 20529 
 20530       /* The code below relies on the first several fields of
 20531          XCrossingEvent being laid out the same way as
 20532          XMotionEvent.  */
 20533 
 20534       if (f && x_mouse_click_focus_ignore_position)
 20535         {
 20536           ignore_next_mouse_click_timeout = (event->xmotion.time
 20537                                              + x_mouse_click_focus_ignore_time);
 20538           mouse_click_timeout_display = dpyinfo;
 20539         }
 20540 
 20541       /* EnterNotify counts as mouse movement,
 20542          so update things that depend on mouse position.  */
 20543       if (f && !f->output_data.x->hourglass_p)
 20544         x_note_mouse_movement (f, &event->xmotion, Qnil);
 20545 #ifdef USE_GTK
 20546       /* We may get an EnterNotify on the buttons in the toolbar.  In that
 20547          case we moved out of any highlighted area and need to note this.  */
 20548       if (!f && dpyinfo->last_mouse_glyph_frame)
 20549         x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &event->xmotion,
 20550                                Qnil);
 20551 #endif
 20552       goto OTHER;
 20553 
 20554     case FocusIn:
 20555 #if defined HAVE_XINPUT2                                                \
 20556   && (defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT))
 20557       /* If a FocusIn event is received (because the window manager
 20558          sent us one), don't set the core focus if XInput 2 is
 20559          enabled, since that would mess up the device-specific focus
 20560          tracking.
 20561 
 20562          The long looking preprocessor conditional only enables this
 20563          code on GTK 3 and no toolkit builds, since those are the only
 20564          builds where focus is tracked specific to each master device.
 20565          Other builds use core events and the client pointer to handle
 20566          focus, much like on a build without XInput 2.  */
 20567       if (dpyinfo->supports_xi2)
 20568         goto OTHER;
 20569 #endif
 20570 #ifdef USE_GTK
 20571       /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
 20572          minimized/iconified windows; thus, for those WMs we won't get
 20573          a MapNotify when unminimizing/deiconifying.  Check here if we
 20574          are deiconizing a window (Bug42655).
 20575 
 20576          But don't do that by default on GTK since it may cause a plain
 20577          invisible frame get reported as iconified, compare
 20578          https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
 20579          That is fixed above but bites us here again.
 20580 
 20581          The option x_set_frame_visibility_more_laxly allows to override
 20582          the default behavior (Bug#49955, Bug#53298).  */
 20583       if (EQ (x_set_frame_visibility_more_laxly, Qfocus_in)
 20584           || EQ (x_set_frame_visibility_more_laxly, Qt))
 20585 #endif /* USE_GTK */
 20586         {
 20587           f = any;
 20588           if (f && FRAME_ICONIFIED_P (f))
 20589             {
 20590               SET_FRAME_VISIBLE (f, 1);
 20591               SET_FRAME_ICONIFIED (f, false);
 20592               f->output_data.x->has_been_visible = true;
 20593               inev.ie.kind = DEICONIFY_EVENT;
 20594               XSETFRAME (inev.ie.frame_or_window, f);
 20595             }
 20596         }
 20597 
 20598       x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 20599       goto OTHER;
 20600 
 20601     case LeaveNotify:
 20602       x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
 20603                                     event->xcrossing.send_event, false);
 20604 
 20605 #ifdef HAVE_XINPUT2
 20606       /* For whatever reason, the X server continues to deliver
 20607          EnterNotify and LeaveNotify events despite us selecting for
 20608          related XI_Enter and XI_Leave events.  It's not just our
 20609          problem, since windows created by "xinput test-xi2" suffer
 20610          from the same defect.  Simply ignore all such events while
 20611          the input extension is enabled.  (bug#57468) */
 20612 
 20613       if (dpyinfo->supports_xi2)
 20614         {
 20615 #if !defined USE_X_TOOLKIT && (!defined USE_GTK || defined HAVE_GTK3)
 20616           goto OTHER;
 20617 #else
 20618           /* Unfortunately, X toolkit popups generate LeaveNotify
 20619              events due to the core grabs they acquire (and our
 20620              releasing of the device grab).  This leads to the mouse
 20621              face persisting if a popup is activated by clicking on a
 20622              button, and then dismissed by releasing the mouse button
 20623              outside the frame, in which case no XI_Enter event is
 20624              generated for the grab.  */
 20625           goto just_clear_mouse_face;
 20626 #endif
 20627         }
 20628 #endif
 20629 
 20630 #ifdef HAVE_XWIDGETS
 20631       {
 20632         struct xwidget_view *xvw;
 20633 
 20634         xvw = xwidget_view_from_window (event->xcrossing.window);
 20635 
 20636         if (xvw)
 20637           {
 20638             xwidget_motion_or_crossing (xvw, event);
 20639             goto OTHER;
 20640           }
 20641       }
 20642 #endif
 20643 
 20644       if (x_top_window_to_frame (dpyinfo, event->xcrossing.window))
 20645         x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 20646 
 20647 #if defined HAVE_XINPUT2                                                \
 20648   && (defined USE_X_TOOLKIT || (defined USE_GTK && !defined HAVE_GTK3))
 20649     just_clear_mouse_face:
 20650 #endif
 20651 
 20652 #if defined USE_X_TOOLKIT
 20653       /* If the mouse leaves the edit widget, then any mouse highlight
 20654          should be cleared.  */
 20655       f = x_window_to_frame (dpyinfo, event->xcrossing.window);
 20656 
 20657       if (!f)
 20658         f = x_top_window_to_frame (dpyinfo, event->xcrossing.window);
 20659 #else
 20660       f = x_top_window_to_frame (dpyinfo, event->xcrossing.window);
 20661 #endif
 20662 
 20663       if (f)
 20664         {
 20665           /* Now clear dpyinfo->last_mouse_motion_frame, or
 20666              gui_redo_mouse_highlight will end up highlighting the
 20667              last known position of the mouse if a tooltip frame is
 20668              later unmapped.  */
 20669 
 20670           if (f == dpyinfo->last_mouse_motion_frame)
 20671             dpyinfo->last_mouse_motion_frame = NULL;
 20672 
 20673           /* Something similar applies to
 20674              dpyinfo->last_mouse_glyph_frame.  */
 20675           if (f == dpyinfo->last_mouse_glyph_frame)
 20676             dpyinfo->last_mouse_glyph_frame = NULL;
 20677 
 20678           if (f == hlinfo->mouse_face_mouse_frame)
 20679             {
 20680               /* If we move outside the frame, then we're
 20681                  certainly no longer on any text in the frame.  */
 20682               clear_mouse_face (hlinfo);
 20683               hlinfo->mouse_face_mouse_frame = 0;
 20684               x_flush_dirty_back_buffer_on (f);
 20685             }
 20686 
 20687           /* Generate a nil HELP_EVENT to cancel a help-echo.
 20688              Do it only if there's something to cancel.
 20689              Otherwise, the startup message is cleared when
 20690              the mouse leaves the frame.  */
 20691           if (any_help_event_p
 20692               /* But never if `mouse-drag-and-drop-region' is in
 20693                  progress, since that results in the tooltip being
 20694                  dismissed when the mouse moves on top.  */
 20695               && !((EQ (track_mouse, Qdrag_source)
 20696                     || EQ (track_mouse, Qdropping))
 20697                    && gui_mouse_grabbed (dpyinfo)))
 20698             do_help = -1;
 20699 
 20700           if (event->xcrossing.window == FRAME_X_WINDOW (f))
 20701             x_compute_root_window_offset (f, event->xcrossing.x_root,
 20702                                           event->xcrossing.y_root,
 20703                                           event->xcrossing.x,
 20704                                           event->xcrossing.y);
 20705 
 20706         }
 20707 #ifdef USE_GTK
 20708       /* See comment in EnterNotify above */
 20709       else if (dpyinfo->last_mouse_glyph_frame)
 20710         x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame,
 20711                                &event->xmotion, Qnil);
 20712 #endif
 20713       goto OTHER;
 20714 
 20715     case FocusOut:
 20716 #if defined HAVE_XINPUT2                                                \
 20717   && (defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT))
 20718       /* If a FocusIn event is received (because the window manager
 20719          sent us one), don't set the core focus if XInput 2 is
 20720          enabled, since that would mess up the device-specific focus
 20721          tracking.
 20722 
 20723          The long looking preprocessor conditional only enables this
 20724          code on GTK 3 and no toolkit builds, since those are the only
 20725          builds where focus is tracked specific to each master device.
 20726          Other builds use core events and the client pointer to handle
 20727          focus, much like on a build without XInput 2.  */
 20728       if (dpyinfo->supports_xi2)
 20729         goto OTHER;
 20730 #endif
 20731       x_detect_focus_change (dpyinfo, any, event, &inev.ie);
 20732       goto OTHER;
 20733 
 20734     case MotionNotify:
 20735       {
 20736         XMotionEvent xmotion = event->xmotion;
 20737 
 20738         previous_help_echo_string = help_echo_string;
 20739         help_echo_string = Qnil;
 20740 
 20741         if (hlinfo->mouse_face_hidden)
 20742           {
 20743             hlinfo->mouse_face_hidden = false;
 20744             clear_mouse_face (hlinfo);
 20745           }
 20746 
 20747         f = mouse_or_wdesc_frame (dpyinfo, event->xmotion.window);
 20748 
 20749         if (f && event->xmotion.window == FRAME_X_WINDOW (f))
 20750           /* See the comment above x_compute_root_window_offset for
 20751              why this optimization is performed.  */
 20752           x_compute_root_window_offset (f, event->xmotion.x_root,
 20753                                         event->xmotion.y_root,
 20754                                         event->xmotion.x,
 20755                                         event->xmotion.y);
 20756 
 20757         if (x_dnd_in_progress
 20758             /* Handle these events normally if the recursion
 20759                level is higher than when the drag-and-drop
 20760                operation was initiated.  This is so that mouse
 20761                input works while we're in the debugger for, say,
 20762                `x-dnd-movement-function`.  */
 20763             && (command_loop_level + minibuf_level
 20764                 <= x_dnd_recursion_depth)
 20765             && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 20766           {
 20767             Window target, toplevel;
 20768             int target_proto, motif_style;
 20769             xm_top_level_leave_message lmsg;
 20770             xm_top_level_enter_message emsg;
 20771             xm_drag_motion_message dmsg;
 20772             XRectangle *r;
 20773             bool was_frame;
 20774 
 20775             /* Always clear mouse face.  */
 20776             clear_mouse_face (hlinfo);
 20777             hlinfo->mouse_face_hidden = true;
 20778 
 20779             /* Sometimes the drag-and-drop operation starts with the
 20780                pointer of a frame invisible due to input.  Since
 20781                motion events are ignored during that, make the pointer
 20782                visible manually.  */
 20783 
 20784             if (f)
 20785               {
 20786                 XTtoggle_invisible_pointer (f, false);
 20787 
 20788                 r = &dpyinfo->last_mouse_glyph;
 20789 
 20790                 /* Also remember the mouse glyph and set
 20791                    mouse_moved.  */
 20792                 if (f != dpyinfo->last_mouse_glyph_frame
 20793                     || event->xmotion.x < r->x
 20794                     || event->xmotion.x >= r->x + r->width
 20795                     || event->xmotion.y < r->y
 20796                     || event->xmotion.y >= r->y + r->height)
 20797                   {
 20798                     f->mouse_moved = true;
 20799                     f->last_mouse_device = Qnil;
 20800                     dpyinfo->last_mouse_scroll_bar = NULL;
 20801 
 20802                     remember_mouse_glyph (f, event->xmotion.x,
 20803                                           event->xmotion.y, r);
 20804                     dpyinfo->last_mouse_glyph_frame = f;
 20805                   }
 20806               }
 20807 
 20808             if (event->xmotion.same_screen)
 20809               target = x_dnd_get_target_window (dpyinfo,
 20810                                                 event->xmotion.x_root,
 20811                                                 event->xmotion.y_root,
 20812                                                 &target_proto,
 20813                                                 &motif_style, &toplevel,
 20814                                                 &was_frame);
 20815             else
 20816               target = x_dnd_fill_empty_target (&target_proto, &motif_style,
 20817                                                 &toplevel, &was_frame);
 20818 
 20819             if (toplevel != x_dnd_last_seen_toplevel)
 20820               {
 20821                 if (toplevel != FRAME_OUTER_WINDOW (x_dnd_frame)
 20822                     && x_dnd_return_frame == 1)
 20823                   x_dnd_return_frame = 2;
 20824 
 20825                 if (x_dnd_return_frame == 2
 20826                     && x_any_window_to_frame (dpyinfo, toplevel))
 20827                   {
 20828                     if (x_dnd_last_seen_window != None
 20829                         && x_dnd_last_protocol_version != -1
 20830                         && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 20831                       x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 20832                                         x_dnd_last_seen_toplevel);
 20833                     else if (x_dnd_last_seen_window != None
 20834                              && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 20835                              && !x_dnd_disable_motif_drag
 20836                              && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 20837                       {
 20838                         if (!x_dnd_motif_setup_p)
 20839                           xm_setup_drag_info (dpyinfo, x_dnd_frame);
 20840 
 20841                         lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20842                                                       XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 20843                         lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20844                         lmsg.zero = 0;
 20845                         lmsg.timestamp = event->xmotion.time;
 20846                         lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 20847 
 20848                         if (x_dnd_motif_setup_p)
 20849                           xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20850                                                            x_dnd_last_seen_window, &lmsg);
 20851                       }
 20852 
 20853                     x_dnd_end_window = x_dnd_last_seen_window;
 20854                     x_dnd_last_seen_window = None;
 20855                     x_dnd_last_seen_toplevel = None;
 20856                     x_dnd_in_progress = false;
 20857                     x_dnd_return_frame_object
 20858                       = x_any_window_to_frame (dpyinfo, toplevel);
 20859                     x_dnd_return_frame = 3;
 20860                     x_dnd_waiting_for_finish = false;
 20861                     target = None;
 20862                   }
 20863               }
 20864 
 20865             if (target != x_dnd_last_seen_window)
 20866               {
 20867                 if (x_dnd_last_seen_window != None
 20868                     && x_dnd_last_protocol_version != -1
 20869                     && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 20870                   x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 20871                                     x_dnd_last_seen_toplevel);
 20872                 else if (x_dnd_last_seen_window != None
 20873                          && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 20874                          && x_dnd_disable_motif_drag
 20875                          && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 20876                   {
 20877                     if (!x_dnd_motif_setup_p)
 20878                       xm_setup_drag_info (dpyinfo, x_dnd_frame);
 20879 
 20880                     /* This is apparently required.  If we don't send
 20881                        a motion event with the current root window
 20882                        coordinates of the pointer before the top level
 20883                        leave, then Motif displays an ugly black border
 20884                        around the previous drop site.  */
 20885 
 20886                     dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20887                                                   XM_DRAG_REASON_DRAG_MOTION);
 20888                     dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20889                     dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 20890                                                                                          x_dnd_wanted_action),
 20891                                                              XM_DROP_SITE_NONE, x_dnd_motif_operations,
 20892                                                              XM_DROP_ACTION_DROP_CANCEL);
 20893                     dmsg.timestamp = event->xmotion.time;
 20894                     dmsg.x = event->xmotion.x_root;
 20895                     dmsg.y = event->xmotion.y_root;
 20896 
 20897                     lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20898                                                   XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 20899                     lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20900                     lmsg.zero = 0;
 20901                     lmsg.timestamp = event->xbutton.time;
 20902                     lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 20903 
 20904                     if (x_dnd_motif_setup_p)
 20905                       {
 20906                         xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20907                                                      x_dnd_last_seen_window, &dmsg);
 20908                         xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20909                                                          x_dnd_last_seen_window, &lmsg);
 20910                       }
 20911                   }
 20912 
 20913                 x_dnd_action = None;
 20914                 x_dnd_last_seen_toplevel = toplevel;
 20915                 x_dnd_last_seen_window = target;
 20916                 x_dnd_last_protocol_version = target_proto;
 20917                 x_dnd_last_motif_style = motif_style;
 20918                 x_dnd_last_window_is_frame = was_frame;
 20919 
 20920                 if (target != None && x_dnd_last_protocol_version != -1)
 20921                   x_dnd_send_enter (x_dnd_frame, target,
 20922                                     x_dnd_last_seen_toplevel,
 20923                                     x_dnd_last_protocol_version);
 20924                 else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 20925                          && !x_dnd_disable_motif_drag)
 20926                   {
 20927                     if (!x_dnd_motif_setup_p)
 20928                       xm_setup_drag_info (dpyinfo, x_dnd_frame);
 20929 
 20930                     emsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20931                                                   XM_DRAG_REASON_TOP_LEVEL_ENTER);
 20932                     emsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20933                     emsg.zero = 0;
 20934                     emsg.timestamp = event->xbutton.time;
 20935                     emsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 20936                     emsg.index_atom = x_dnd_motif_atom;
 20937 
 20938                     if (x_dnd_motif_setup_p)
 20939                       xm_send_top_level_enter_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20940                                                        target, &emsg);
 20941                   }
 20942               }
 20943             else
 20944               x_dnd_last_seen_toplevel = toplevel;
 20945 
 20946             if (x_dnd_last_window_is_frame && target != None)
 20947               x_dnd_note_self_position (dpyinfo, target,
 20948                                         event->xbutton.x_root,
 20949                                         event->xbutton.y_root);
 20950             else if (x_dnd_last_protocol_version != -1 && target != None)
 20951               x_dnd_send_position (x_dnd_frame, target,
 20952                                    x_dnd_last_seen_toplevel,
 20953                                    x_dnd_last_protocol_version,
 20954                                    event->xmotion.x_root,
 20955                                    event->xmotion.y_root,
 20956                                    x_dnd_selection_timestamp,
 20957                                    x_dnd_wanted_action, 0,
 20958                                    event->xmotion.state);
 20959             else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None
 20960                      && !x_dnd_disable_motif_drag)
 20961               {
 20962                 if (!x_dnd_motif_setup_p)
 20963                   xm_setup_drag_info (dpyinfo, x_dnd_frame);
 20964 
 20965                 dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 20966                                               XM_DRAG_REASON_DRAG_MOTION);
 20967                 dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 20968                 dmsg.side_effects = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 20969                                                                                      x_dnd_wanted_action),
 20970                                                          XM_DROP_SITE_VALID, x_dnd_motif_operations,
 20971                                                          (!x_dnd_xm_use_help
 20972                                                           ? XM_DROP_ACTION_DROP
 20973                                                           : XM_DROP_ACTION_DROP_HELP));
 20974                 dmsg.timestamp = event->xbutton.time;
 20975                 dmsg.x = event->xmotion.x_root;
 20976                 dmsg.y = event->xmotion.y_root;
 20977 
 20978                 if (x_dnd_motif_setup_p)
 20979                   xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 20980                                                target, &dmsg);
 20981               }
 20982 
 20983             x_dnd_update_tooltip_position (event->xmotion.x_root,
 20984                                            event->xmotion.y_root);
 20985 
 20986             goto OTHER;
 20987           }
 20988 
 20989 #ifdef USE_GTK
 20990         if (f && xg_event_is_for_scrollbar (f, event, false))
 20991           f = 0;
 20992 #endif
 20993 #ifdef HAVE_XWIDGETS
 20994         struct xwidget_view *xvw;
 20995 
 20996         xvw = xwidget_view_from_window (event->xmotion.window);
 20997 
 20998         if (xvw)
 20999           xwidget_motion_or_crossing (xvw, event);
 21000 #endif
 21001         if (f)
 21002           {
 21003             /* Maybe generate a SELECT_WINDOW_EVENT for
 21004                `mouse-autoselect-window' but don't let popup menus
 21005                interfere with this (Bug#1261).  */
 21006             if (!NILP (Vmouse_autoselect_window)
 21007                 && !popup_activated ()
 21008                 /* Don't switch if we're currently in the minibuffer.
 21009                    This tries to work around problems where the
 21010                    minibuffer gets unselected unexpectedly, and where
 21011                    you then have to move your mouse all the way down to
 21012                    the minibuffer to select it.  */
 21013                 && !MINI_WINDOW_P (XWINDOW (selected_window))
 21014                 /* With `focus-follows-mouse' non-nil create an event
 21015                    also when the target window is on another frame.  */
 21016                 && (f == XFRAME (selected_frame)
 21017                     || !NILP (focus_follows_mouse)))
 21018               {
 21019                 static Lisp_Object last_mouse_window;
 21020 
 21021                 if (xmotion.window != FRAME_X_WINDOW (f))
 21022                   {
 21023                     x_translate_coordinates (f, xmotion.x_root, xmotion.y_root,
 21024                                              &xmotion.x, &xmotion.y);
 21025                     xmotion.window = FRAME_X_WINDOW (f);
 21026                   }
 21027 
 21028                 Lisp_Object window = window_from_coordinates
 21029                   (f, xmotion.x, xmotion.y, 0, false, false);
 21030 
 21031                 /* A window will be autoselected only when it is not
 21032                    selected now and the last mouse movement event was
 21033                    not in it.  The remainder of the code is a bit vague
 21034                    wrt what a "window" is.  For immediate autoselection,
 21035                    the window is usually the entire window but for GTK
 21036                    where the scroll bars don't count.  For delayed
 21037                    autoselection the window is usually the window's text
 21038                    area including the margins.  */
 21039                 if (WINDOWP (window)
 21040                     && !EQ (window, last_mouse_window)
 21041                     && !EQ (window, selected_window))
 21042                   {
 21043                     inev.ie.kind = SELECT_WINDOW_EVENT;
 21044                     inev.ie.frame_or_window = window;
 21045                   }
 21046 
 21047                 /* Remember the last window where we saw the mouse.  */
 21048                 last_mouse_window = window;
 21049               }
 21050 
 21051             if (!x_note_mouse_movement (f, &xmotion, Qnil))
 21052               help_echo_string = previous_help_echo_string;
 21053           }
 21054         else
 21055           {
 21056 #ifndef USE_TOOLKIT_SCROLL_BARS
 21057             struct scroll_bar *bar
 21058               = x_window_to_scroll_bar (event->xmotion.display,
 21059                                         event->xmotion.window, 2);
 21060 
 21061             if (bar)
 21062               x_scroll_bar_note_movement (bar, &event->xmotion);
 21063 #endif /* USE_TOOLKIT_SCROLL_BARS */
 21064 
 21065             /* If we move outside the frame, then we're
 21066                certainly no longer on any text in the frame.  */
 21067             clear_mouse_face (hlinfo);
 21068           }
 21069 
 21070         /* If the contents of the global variable help_echo_string
 21071            has changed, generate a HELP_EVENT.  */
 21072         if (!NILP (help_echo_string)
 21073             || !NILP (previous_help_echo_string))
 21074           do_help = 1;
 21075 
 21076         if (f)
 21077           x_flush_dirty_back_buffer_on (f);
 21078         goto OTHER;
 21079       }
 21080 
 21081     case ConfigureNotify:
 21082       /* An opaque move can generate a stream of events as the window
 21083          is dragged around.  If the connection round trip time isn't
 21084          really short, they may come faster than we can respond to
 21085          them, given the multiple queries we can do to check window
 21086          manager state, translate coordinates, etc.
 21087 
 21088          So if this ConfigureNotify is immediately followed by another
 21089          for the same window, use the info from the latest update, and
 21090          consider the events all handled.  */
 21091 
 21092       /* Opaque resize may be trickier; ConfigureNotify events are
 21093          mixed with Expose events for multiple windows.  */
 21094       configureEvent = *event;
 21095       while (XPending (dpyinfo->display))
 21096         {
 21097           XNextEvent (dpyinfo->display, &next_event);
 21098           if (next_event.type != ConfigureNotify
 21099               || next_event.xconfigure.window != event->xconfigure.window
 21100               /* Skipping events with different sizes can lead to a
 21101                  mispositioned mode line at initial window creation.
 21102                  Only drop window motion events for now.  */
 21103               || next_event.xconfigure.width != event->xconfigure.width
 21104               || next_event.xconfigure.height != event->xconfigure.height)
 21105             {
 21106               XPutBackEvent (dpyinfo->display, &next_event);
 21107               break;
 21108             }
 21109           else
 21110             configureEvent = next_event;
 21111         }
 21112 
 21113       /* If we get a ConfigureNotify for the root window, this means
 21114          the dimensions of the screen it's on changed.  */
 21115 
 21116       if (configureEvent.xconfigure.window == dpyinfo->root_window)
 21117         {
 21118 #ifdef HAVE_XRANDR
 21119           /* This function is OK to call even if the X server doesn't
 21120              support RandR.  */
 21121           XRRUpdateConfiguration (&configureEvent);
 21122 #elif !defined USE_GTK
 21123           /* Catch screen size changes even if RandR is not available
 21124              on the client.  GTK does this internally.  */
 21125 
 21126           if (configureEvent.xconfigure.width != dpyinfo->screen_width
 21127               || configureEvent.xconfigure.height != dpyinfo->screen_height)
 21128             {
 21129               /* Also avoid storing duplicate events here, since
 21130                  Fx_display_monitor_attributes_list will return the
 21131                  same information for both invocations of the
 21132                  hook.  */
 21133               if (!x_find_monitors_changed_event (dpyinfo))
 21134                 {
 21135                   inev.ie.kind = MONITORS_CHANGED_EVENT;
 21136                   XSETTERMINAL (inev.ie.arg, dpyinfo->terminal);
 21137 
 21138                   /* Store this event now since inev.ie.type could be set to
 21139                      MOVE_FRAME_EVENT later.  */
 21140                   kbd_buffer_store_event (&inev.ie);
 21141                   inev.ie.kind = NO_EVENT;
 21142                 }
 21143 
 21144               /* Also update the position of the drag-and-drop
 21145                  tooltip.  */
 21146               x_dnd_update_tooltip_now ();
 21147             }
 21148 #endif
 21149 
 21150           dpyinfo->screen_width = configureEvent.xconfigure.width;
 21151           dpyinfo->screen_height = configureEvent.xconfigure.height;
 21152         }
 21153 
 21154       if (x_dnd_in_progress && x_dnd_use_toplevels
 21155           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 21156         {
 21157           int rc, dest_x, dest_y;
 21158           Window child;
 21159           struct x_client_list_window *tem, *last = NULL;
 21160 
 21161           for (tem = x_dnd_toplevels; tem; last = tem, tem = tem->next)
 21162             {
 21163               /* Not completely right, since the parent could be
 21164                  unmapped, but good enough.  */
 21165 
 21166               if (tem->window == configureEvent.xconfigure.window)
 21167                 {
 21168                   x_catch_errors (dpyinfo->display);
 21169                   rc = (XTranslateCoordinates (dpyinfo->display,
 21170                                                configureEvent.xconfigure.window,
 21171                                                dpyinfo->root_window,
 21172                                                -configureEvent.xconfigure.border_width,
 21173                                                -configureEvent.xconfigure.border_width,
 21174                                                &dest_x, &dest_y, &child)
 21175                         && !x_had_errors_p (dpyinfo->display));
 21176                   x_uncatch_errors_after_check ();
 21177 
 21178                   if (rc)
 21179                     {
 21180                       tem->x = dest_x;
 21181                       tem->y = dest_y;
 21182                       tem->width = (configureEvent.xconfigure.width
 21183                                     + configureEvent.xconfigure.border_width);
 21184                       tem->height = (configureEvent.xconfigure.height
 21185                                      + configureEvent.xconfigure.border_width);
 21186                     }
 21187                   else
 21188                     {
 21189                       /* The window was probably destroyed, so get rid
 21190                          of it.  */
 21191 
 21192                       if (!last)
 21193                         x_dnd_toplevels = tem->next;
 21194                       else
 21195                         last->next = tem->next;
 21196 
 21197 #ifdef HAVE_XSHAPE
 21198                       if (tem->n_input_rects != -1)
 21199                         xfree (tem->input_rects);
 21200                       if (tem->n_bounding_rects != -1)
 21201                         xfree (tem->bounding_rects);
 21202 #endif
 21203                       xfree (tem);
 21204                     }
 21205 
 21206                   break;
 21207                 }
 21208             }
 21209         }
 21210 
 21211 #if defined HAVE_GTK3 && defined USE_TOOLKIT_SCROLL_BARS
 21212           struct scroll_bar *bar = x_window_to_scroll_bar (dpyinfo->display,
 21213                                                            configureEvent.xconfigure.window, 2);
 21214 
 21215           /* There is really no other way to make GTK scroll bars fit
 21216              in the dimensions we want them to.  */
 21217           if (bar)
 21218             {
 21219               /* Skip all the pending configure events, not just the
 21220                  ones where window motion occurred.  */
 21221               while (XPending (dpyinfo->display))
 21222                 {
 21223                   XNextEvent (dpyinfo->display, &next_event);
 21224                   if (next_event.type != ConfigureNotify
 21225                       || next_event.xconfigure.window != event->xconfigure.window)
 21226                     {
 21227                       XPutBackEvent (dpyinfo->display, &next_event);
 21228                       break;
 21229                     }
 21230                   else
 21231                     configureEvent = next_event;
 21232                 }
 21233 
 21234               if (configureEvent.xconfigure.width != max (bar->width, 1)
 21235                   || configureEvent.xconfigure.height != max (bar->height, 1))
 21236                 {
 21237                   XResizeWindow (dpyinfo->display, bar->x_window,
 21238                                  max (bar->width, 1), max (bar->height, 1));
 21239                   x_flush (WINDOW_XFRAME (XWINDOW (bar->window)));
 21240                 }
 21241 
 21242 #ifdef HAVE_XDBE
 21243               if (f && FRAME_X_DOUBLE_BUFFERED_P (f))
 21244                 x_drop_xrender_surfaces (f);
 21245 #endif
 21246 
 21247               goto OTHER;
 21248             }
 21249 #endif
 21250 
 21251       f = x_top_window_to_frame (dpyinfo, configureEvent.xconfigure.window);
 21252 
 21253       /* This means we can no longer be certain of the root window
 21254          coordinates of any's edit window.  */
 21255       if (any)
 21256         FRAME_X_OUTPUT (any)->window_offset_certain_p = false;
 21257 
 21258       /* Unfortunately, we need to call x_drop_xrender_surfaces for
 21259          _all_ ConfigureNotify events, otherwise we miss some and
 21260          flicker.  Don't try to optimize these calls by looking only
 21261          for size changes: that's not sufficient.  We miss some
 21262          surface invalidations and flicker.  */
 21263 #ifdef HAVE_XDBE
 21264       if (f && FRAME_X_DOUBLE_BUFFERED_P (f))
 21265         x_drop_xrender_surfaces (f);
 21266 #endif
 21267 #if defined USE_CAIRO && !defined USE_GTK
 21268       if (f)
 21269         x_cr_update_surface_desired_size (f, configureEvent.xconfigure.width,
 21270                                           configureEvent.xconfigure.height);
 21271       else if (any && configureEvent.xconfigure.window == FRAME_X_WINDOW (any))
 21272         x_cr_update_surface_desired_size (any,
 21273                                           configureEvent.xconfigure.width,
 21274                                           configureEvent.xconfigure.height);
 21275 #endif
 21276 
 21277 #if !defined USE_X_TOOLKIT && !defined USE_GTK
 21278 
 21279       /* Make the new size of the frame its opaque region.  This is a
 21280          region describing areas of the window which are always
 21281          guaranteed to be completely opaque and can be treated as such
 21282          by the compositor.  It is set to the width and height of the
 21283          only window in no-toolkit builds when `alpha_background' is
 21284          not set, and is cleared otherwise.  */
 21285 
 21286       if (f || (any && configureEvent.xconfigure.window
 21287                 == FRAME_OUTER_WINDOW (any)))
 21288         x_update_opaque_region (f ? f : any, &configureEvent);
 21289 
 21290 #endif /* !defined USE_X_TOOLKIT && !defined USE_GTK */
 21291 
 21292 #ifdef USE_GTK
 21293       if (!f
 21294           && (f = any)
 21295           && configureEvent.xconfigure.window == FRAME_X_WINDOW (f)
 21296           && (FRAME_VISIBLE_P (f)
 21297               || !(configureEvent.xconfigure.width <= 1
 21298                    && configureEvent.xconfigure.height <= 1)))
 21299         {
 21300 
 21301           if (CONSP (frame_size_history))
 21302             frame_size_history_extra
 21303               (f, build_string ("ConfigureNotify"),
 21304                FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
 21305                configureEvent.xconfigure.width,
 21306                configureEvent.xconfigure.height,
 21307                f->new_width, f->new_height);
 21308 
 21309 #ifdef HAVE_XDBE
 21310           if (FRAME_X_DOUBLE_BUFFERED_P (f))
 21311             x_drop_xrender_surfaces (f);
 21312 #endif
 21313           xg_frame_resized (f, configureEvent.xconfigure.width,
 21314                             configureEvent.xconfigure.height);
 21315 #ifdef USE_CAIRO
 21316           x_cr_update_surface_desired_size (f, configureEvent.xconfigure.width,
 21317                                             configureEvent.xconfigure.height);
 21318 #endif
 21319           x_update_opaque_region (f, &configureEvent);
 21320           f = 0;
 21321         }
 21322 #endif
 21323       if (f && (FRAME_VISIBLE_P (f)
 21324                 || !(configureEvent.xconfigure.width <= 1
 21325                      && configureEvent.xconfigure.height <= 1)))
 21326         {
 21327 #ifdef USE_GTK
 21328           /* For GTK+ don't call x_net_wm_state for the scroll bar
 21329              window.  (Bug#24963, Bug#25887) */
 21330           if (configureEvent.xconfigure.window == FRAME_X_WINDOW (f))
 21331 #endif
 21332             x_net_wm_state (f, configureEvent.xconfigure.window);
 21333 
 21334 #if defined USE_X_TOOLKIT || defined USE_GTK
 21335           /* Tip frames are pure X window, set size for them.  */
 21336           if (FRAME_TOOLTIP_P (f))
 21337             {
 21338               if (FRAME_PIXEL_HEIGHT (f) != configureEvent.xconfigure.height
 21339                   || FRAME_PIXEL_WIDTH (f) != configureEvent.xconfigure.width)
 21340                 SET_FRAME_GARBAGED (f);
 21341 
 21342               FRAME_PIXEL_HEIGHT (f) = configureEvent.xconfigure.height;
 21343               FRAME_PIXEL_WIDTH (f) = configureEvent.xconfigure.width;
 21344             }
 21345 #endif
 21346 
 21347 #ifndef USE_X_TOOLKIT
 21348 #ifndef USE_GTK
 21349           int width = configureEvent.xconfigure.width;
 21350           int height = configureEvent.xconfigure.height;
 21351 
 21352           if (CONSP (frame_size_history))
 21353             frame_size_history_extra
 21354               (f, build_string ("ConfigureNotify"),
 21355                FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
 21356                width, height, f->new_width, f->new_height);
 21357 
 21358           /* In the toolkit version, change_frame_size
 21359              is called by the code that handles resizing
 21360              of the EmacsFrame widget.  */
 21361 
 21362           /* Even if the number of character rows and columns has
 21363              not changed, the font size may have changed, so we need
 21364              to check the pixel dimensions as well.  */
 21365 
 21366           if (width != FRAME_PIXEL_WIDTH (f)
 21367               || height != FRAME_PIXEL_HEIGHT (f)
 21368               || (f->new_size_p
 21369                   && ((f->new_width >= 0 && width != f->new_width)
 21370                       || (f->new_height >= 0 && height != f->new_height))))
 21371             {
 21372               change_frame_size (f, width, height, false, true, false);
 21373               x_clear_under_internal_border (f);
 21374               SET_FRAME_GARBAGED (f);
 21375               cancel_mouse_face (f);
 21376             }
 21377 #endif /* not USE_GTK */
 21378 #endif
 21379 
 21380 #ifdef USE_GTK
 21381           /* GTK creates windows but doesn't map them.
 21382              Only get real positions when mapped.  */
 21383           if (FRAME_GTK_OUTER_WIDGET (f)
 21384               && gtk_widget_get_mapped (FRAME_GTK_OUTER_WIDGET (f)))
 21385 #endif
 21386             {
 21387               int old_left = f->left_pos;
 21388               int old_top = f->top_pos;
 21389               Lisp_Object frame;
 21390 
 21391               XSETFRAME (frame, f);
 21392 
 21393               if (!FRAME_PARENT_FRAME (f))
 21394                 x_real_positions (f, &f->left_pos, &f->top_pos);
 21395               else
 21396                 {
 21397                   Window root;
 21398                   unsigned int dummy_uint;
 21399 
 21400                   XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 21401                                 &root, &f->left_pos, &f->top_pos,
 21402                                 &dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint);
 21403                 }
 21404 
 21405               if (!FRAME_TOOLTIP_P (f)
 21406                   && (old_left != f->left_pos || old_top != f->top_pos))
 21407                 {
 21408                   inev.ie.kind = MOVE_FRAME_EVENT;
 21409                   XSETFRAME (inev.ie.frame_or_window, f);
 21410                 }
 21411             }
 21412 
 21413 
 21414 #ifdef HAVE_X_I18N
 21415           if (f)
 21416             {
 21417               if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
 21418                 xic_set_statusarea (f);
 21419 
 21420               struct window *w = XWINDOW (f->selected_window);
 21421               xic_set_preeditarea (w, w->cursor.x, w->cursor.y);
 21422             }
 21423 #endif
 21424 
 21425 #ifdef HAVE_XINPUT2
 21426           if (f && dpyinfo->supports_xi2)
 21427             {
 21428               Mouse_HLInfo *hlinfo;
 21429 
 21430               /* The input extension doesn't report motion events when
 21431                  the part of the window below the pointer changes.  To
 21432                  avoid outdated information from keeping
 21433                  i.e. mouse-highlight at the wrong position after the
 21434                  frame is moved or resized, reset the mouse highlight
 21435                  and last_mouse_motion_frame.  */
 21436 
 21437               if (dpyinfo->last_mouse_motion_frame == f)
 21438                 dpyinfo->last_mouse_motion_frame = NULL;
 21439 
 21440               hlinfo = MOUSE_HL_INFO (f);
 21441 
 21442               if (hlinfo->mouse_face_mouse_frame == f)
 21443                 reset_mouse_highlight (hlinfo);
 21444             }
 21445 #endif
 21446 
 21447         }
 21448 
 21449       if (x_dnd_in_progress
 21450           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 21451         x_dnd_update_state (dpyinfo, dpyinfo->last_user_time);
 21452       goto OTHER;
 21453 
 21454     case ButtonRelease:
 21455     case ButtonPress:
 21456       {
 21457         if (event->xbutton.type == ButtonPress)
 21458           x_display_set_last_user_time (dpyinfo, event->xbutton.time,
 21459                                         event->xbutton.send_event, true);
 21460 
 21461 #ifdef HAVE_XWIDGETS
 21462         struct xwidget_view *xvw;
 21463 
 21464         xvw = xwidget_view_from_window (event->xbutton.window);
 21465 
 21466         if (xvw)
 21467           {
 21468             xwidget_button (xvw, event->type == ButtonPress,
 21469                             event->xbutton.x, event->xbutton.y,
 21470                             event->xbutton.button, event->xbutton.state,
 21471                             event->xbutton.time);
 21472 
 21473             if (!EQ (selected_window, xvw->w) && (event->xbutton.button < 4))
 21474               {
 21475                 inev.ie.kind = SELECT_WINDOW_EVENT;
 21476                 inev.ie.frame_or_window = xvw->w;
 21477               }
 21478 
 21479             *finish = X_EVENT_DROP;
 21480             goto OTHER;
 21481           }
 21482 #endif
 21483         /* If we decide we want to generate an event to be seen
 21484            by the rest of Emacs, we put it here.  */
 21485         Lisp_Object tab_bar_arg = Qnil;
 21486         bool tab_bar_p = false;
 21487         bool tool_bar_p = false;
 21488         bool dnd_grab = false;
 21489 
 21490         if (x_dnd_in_progress
 21491             /* Handle these events normally if the recursion
 21492                level is higher than when the drag-and-drop
 21493                operation was initiated.  This is so that mouse
 21494                input works while we're in the debugger for, say,
 21495                `x-dnd-movement-function`.  */
 21496             && (command_loop_level + minibuf_level
 21497                 <= x_dnd_recursion_depth)
 21498             && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 21499           {
 21500             f = mouse_or_wdesc_frame (dpyinfo, event->xbutton.window);
 21501 
 21502             if (f && event->xbutton.window == FRAME_X_WINDOW (f))
 21503               /* See the comment above x_compute_root_window_offset
 21504                  for why this optimization is performed.  */
 21505               x_compute_root_window_offset (f, event->xbutton.x_root,
 21506                                             event->xbutton.y_root,
 21507                                             event->xbutton.x,
 21508                                             event->xbutton.y);
 21509 
 21510             if (event->type == ButtonPress)
 21511               {
 21512                 x_display_set_last_user_time (dpyinfo, event->xbutton.time,
 21513                                               event->xbutton.send_event, true);
 21514 
 21515                 dpyinfo->grabbed |= (1 << event->xbutton.button);
 21516                 dpyinfo->last_mouse_frame = f;
 21517 
 21518                 if (f)
 21519                   f->last_tab_bar_item = -1;
 21520 #if ! defined (USE_GTK)
 21521                 if (f)
 21522                   f->last_tool_bar_item = -1;
 21523 #endif /* not USE_GTK */
 21524               }
 21525             else
 21526               dpyinfo->grabbed &= ~(1 << event->xbutton.button);
 21527 
 21528             if (event->xbutton.type == ButtonPress
 21529                 && x_dnd_last_seen_window != None)
 21530               {
 21531                 if (x_dnd_last_window_is_frame)
 21532                   x_dnd_note_self_wheel (dpyinfo,
 21533                                          x_dnd_last_seen_window,
 21534                                          event->xbutton.x_root,
 21535                                          event->xbutton.y_root,
 21536                                          event->xbutton.button,
 21537                                          event->xbutton.state,
 21538                                          event->xbutton.time);
 21539                 else if (x_dnd_last_protocol_version != -1)
 21540                   x_dnd_send_position (x_dnd_frame,
 21541                                        x_dnd_last_seen_window,
 21542                                        x_dnd_last_seen_toplevel,
 21543                                        x_dnd_last_protocol_version,
 21544                                        event->xbutton.x_root,
 21545                                        event->xbutton.y_root,
 21546                                        event->xbutton.time,
 21547                                        x_dnd_wanted_action,
 21548                                        event->xbutton.button,
 21549                                        event->xbutton.state);
 21550 
 21551                 goto OTHER;
 21552               }
 21553 
 21554             if (event->xbutton.type == ButtonRelease)
 21555               {
 21556                 for (int i = 1; i < 8; ++i)
 21557                   {
 21558                     if (i != event->xbutton.button
 21559                         && event->xbutton.state & (Button1Mask << (i - 1)))
 21560                       dnd_grab = true;
 21561                   }
 21562 
 21563                 if (!dnd_grab)
 21564                   {
 21565                     x_dnd_end_window = x_dnd_last_seen_window;
 21566                     x_dnd_in_progress = false;
 21567 
 21568                     if (x_dnd_update_tooltip
 21569                         && FRAMEP (tip_frame)
 21570                         && FRAME_LIVE_P (XFRAME (tip_frame))
 21571                         && (FRAME_X_DISPLAY (XFRAME (tip_frame))
 21572                             == FRAME_X_DISPLAY (x_dnd_frame)))
 21573                       Fx_hide_tip ();
 21574 
 21575                     x_dnd_finish_frame = x_dnd_frame;
 21576 
 21577                     if (x_dnd_last_seen_window != None
 21578                         && x_dnd_last_window_is_frame)
 21579                       {
 21580                         x_dnd_waiting_for_finish = false;
 21581                         x_dnd_note_self_drop (dpyinfo,
 21582                                               x_dnd_last_seen_window,
 21583                                               event->xbutton.x_root,
 21584                                               event->xbutton.y_root,
 21585                                               event->xbutton.time);
 21586                       }
 21587                     else if (x_dnd_last_seen_window != None
 21588                              && x_dnd_last_protocol_version != -1)
 21589                       {
 21590                         x_dnd_pending_finish_target = x_dnd_last_seen_toplevel;
 21591                         x_dnd_waiting_for_finish_proto = x_dnd_last_protocol_version;
 21592 
 21593                         x_dnd_waiting_for_finish
 21594                           = x_dnd_do_drop (x_dnd_last_seen_window,
 21595                                            x_dnd_last_seen_toplevel,
 21596                                            x_dnd_last_protocol_version);
 21597                         x_dnd_finish_display = dpyinfo->display;
 21598                       }
 21599                     else if (x_dnd_last_seen_window != None)
 21600                       {
 21601                         xm_drop_start_message dmsg;
 21602                         xm_drag_receiver_info drag_receiver_info;
 21603 
 21604                         if (!xm_read_drag_receiver_info (dpyinfo, x_dnd_last_seen_window,
 21605                                                          &drag_receiver_info)
 21606                             && !x_dnd_disable_motif_protocol
 21607                             && drag_receiver_info.protocol_style != XM_DRAG_STYLE_NONE
 21608                             && (x_dnd_allow_current_frame
 21609                                 || x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame)))
 21610                           {
 21611                             if (!x_dnd_motif_setup_p)
 21612                               xm_setup_drag_info (dpyinfo, x_dnd_frame);
 21613 
 21614                             if (x_dnd_motif_setup_p)
 21615                               {
 21616                                 memset (&dmsg, 0, sizeof dmsg);
 21617 
 21618                                 dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 21619                                                               XM_DRAG_REASON_DROP_START);
 21620                                 dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
 21621                                 dmsg.side_effects
 21622                                   = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 21623                                                                                      x_dnd_wanted_action),
 21624                                                          XM_DROP_SITE_VALID, x_dnd_motif_operations,
 21625                                                          (!x_dnd_xm_use_help
 21626                                                           ? XM_DROP_ACTION_DROP
 21627                                                           : XM_DROP_ACTION_DROP_HELP));
 21628                                 dmsg.timestamp = event->xbutton.time;
 21629                                 dmsg.x = event->xbutton.x_root;
 21630                                 dmsg.y = event->xbutton.y_root;
 21631                                 dmsg.index_atom = x_dnd_motif_atom;
 21632                                 dmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 21633 
 21634                                 if (!XM_DRAG_STYLE_IS_DROP_ONLY (drag_receiver_info.protocol_style))
 21635                                   x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (x_dnd_frame),
 21636                                                                 x_dnd_frame, x_dnd_last_seen_window,
 21637                                                                 event->xbutton.time);
 21638 
 21639                                 xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 21640                                                       x_dnd_last_seen_window, &dmsg);
 21641 
 21642                                 x_dnd_waiting_for_finish = true;
 21643                                 x_dnd_waiting_for_motif_finish_display = dpyinfo;
 21644                                 x_dnd_waiting_for_motif_finish = 1;
 21645                                 x_dnd_finish_display = dpyinfo->display;
 21646                               }
 21647                           }
 21648                         else
 21649                           x_dnd_send_unsupported_drop (dpyinfo, (x_dnd_last_seen_toplevel != None
 21650                                                                  ? x_dnd_last_seen_toplevel
 21651                                                                  : x_dnd_last_seen_window),
 21652                                                        event->xbutton.x_root, event->xbutton.y_root,
 21653                                                        event->xbutton.time);
 21654                       }
 21655                     else if (x_dnd_last_seen_toplevel != None)
 21656                       x_dnd_send_unsupported_drop (dpyinfo, x_dnd_last_seen_toplevel,
 21657                                                    event->xbutton.x_root,
 21658                                                    event->xbutton.y_root,
 21659                                                    event->xbutton.time);
 21660 
 21661 
 21662                     x_dnd_last_protocol_version = -1;
 21663                     x_dnd_last_motif_style = XM_DRAG_STYLE_NONE;
 21664                     x_dnd_last_seen_window = None;
 21665                     x_dnd_last_seen_toplevel = None;
 21666                     x_dnd_last_window_is_frame = false;
 21667                     x_dnd_frame = NULL;
 21668                   }
 21669               }
 21670 
 21671             goto OTHER;
 21672           }
 21673 
 21674         if (x_dnd_in_progress
 21675             && (command_loop_level + minibuf_level
 21676                 <= x_dnd_recursion_depth))
 21677           goto OTHER;
 21678 
 21679         memset (&compose_status, 0, sizeof (compose_status));
 21680         dpyinfo->last_mouse_glyph_frame = NULL;
 21681 
 21682         f = mouse_or_wdesc_frame (dpyinfo, event->xbutton.window);
 21683 
 21684         if (f && event->xbutton.window == FRAME_X_WINDOW (f))
 21685           /* See the comment above x_compute_root_window_offset
 21686              for why this optimization is performed.  */
 21687           x_compute_root_window_offset (f, event->xbutton.x_root,
 21688                                         event->xbutton.y_root,
 21689                                         event->xbutton.x,
 21690                                         event->xbutton.y);
 21691 
 21692         if (f && event->xbutton.type == ButtonPress
 21693             && !popup_activated ()
 21694             && !x_window_to_scroll_bar (event->xbutton.display,
 21695                                         event->xbutton.window, 2)
 21696             && !FRAME_NO_ACCEPT_FOCUS (f))
 21697           {
 21698             /* When clicking into a child frame or when clicking
 21699                into a parent frame with the child frame selected and
 21700                `no-accept-focus' is not set, select the clicked
 21701                frame.  */
 21702             struct frame *hf = dpyinfo->highlight_frame;
 21703 
 21704             if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
 21705               {
 21706                 x_ignore_errors_for_next_request (dpyinfo, 0);
 21707                 XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 21708                                 RevertToParent, event->xbutton.time);
 21709                 x_stop_ignoring_errors (dpyinfo);
 21710 
 21711                 if (FRAME_PARENT_FRAME (f))
 21712                   XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
 21713               }
 21714           }
 21715 
 21716 #ifdef USE_GTK
 21717         if (!f)
 21718           {
 21719             f = x_any_window_to_frame (dpyinfo, event->xbutton.window);
 21720 
 21721             if (event->xbutton.button > 3
 21722                 && event->xbutton.button < 8
 21723                 && f)
 21724               {
 21725                 if (ignore_next_mouse_click_timeout
 21726                     && dpyinfo == mouse_click_timeout_display)
 21727                   {
 21728                     if (event->type == ButtonPress
 21729                         && event->xbutton.time > ignore_next_mouse_click_timeout)
 21730                       {
 21731                         ignore_next_mouse_click_timeout = 0;
 21732                         x_construct_mouse_click (&inev.ie, &event->xbutton, f);
 21733                       }
 21734                     if (event->type == ButtonRelease)
 21735                       ignore_next_mouse_click_timeout = 0;
 21736                   }
 21737                 else
 21738                   x_construct_mouse_click (&inev.ie, &event->xbutton, f);
 21739 
 21740                 *finish = X_EVENT_DROP;
 21741                 goto OTHER;
 21742               }
 21743             else
 21744               f = NULL;
 21745           }
 21746 
 21747         if (f && xg_event_is_for_scrollbar (f, event, false))
 21748           f = 0;
 21749 #endif
 21750         if (f)
 21751           {
 21752             /* Is this in the tab-bar?  */
 21753             if (WINDOWP (f->tab_bar_window)
 21754                 && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
 21755               {
 21756                 Lisp_Object window;
 21757                 int x = event->xbutton.x;
 21758                 int y = event->xbutton.y;
 21759 
 21760                 window = window_from_coordinates (f, x, y, 0, true, true);
 21761                 tab_bar_p = EQ (window, f->tab_bar_window);
 21762 
 21763                 if (tab_bar_p)
 21764                   {
 21765                     tab_bar_arg = handle_tab_bar_click
 21766                       (f, x, y, event->xbutton.type == ButtonPress,
 21767                        x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state));
 21768                     x_flush_dirty_back_buffer_on (f);
 21769                   }
 21770               }
 21771 
 21772 #if ! defined (USE_GTK)
 21773             /* Is this in the tool-bar?  */
 21774             if (WINDOWP (f->tool_bar_window)
 21775                 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
 21776               {
 21777                 Lisp_Object window;
 21778                 int x = event->xbutton.x;
 21779                 int y = event->xbutton.y;
 21780 
 21781                 window = window_from_coordinates (f, x, y, 0, true, true);
 21782                 tool_bar_p = (EQ (window, f->tool_bar_window)
 21783                               && (event->xbutton.type != ButtonRelease
 21784                                   || f->last_tool_bar_item != -1));
 21785 
 21786                 if (tool_bar_p && event->xbutton.button < 4)
 21787                   {
 21788                     handle_tool_bar_click
 21789                       (f, x, y, event->xbutton.type == ButtonPress,
 21790                        x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state));
 21791                     x_flush_dirty_back_buffer_on (f);
 21792                   }
 21793               }
 21794 #endif /* !USE_GTK */
 21795 
 21796             if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
 21797 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 21798               if (! popup_activated ())
 21799 #endif
 21800                 {
 21801                   if (ignore_next_mouse_click_timeout
 21802                       && dpyinfo == mouse_click_timeout_display)
 21803                     {
 21804                       if (event->type == ButtonPress
 21805                           && event->xbutton.time > ignore_next_mouse_click_timeout)
 21806                         {
 21807                           ignore_next_mouse_click_timeout = 0;
 21808                           x_construct_mouse_click (&inev.ie, &event->xbutton, f);
 21809                         }
 21810                       if (event->type == ButtonRelease)
 21811                         ignore_next_mouse_click_timeout = 0;
 21812                     }
 21813                   else
 21814                     x_construct_mouse_click (&inev.ie, &event->xbutton, f);
 21815 
 21816                   if (!NILP (tab_bar_arg))
 21817                     inev.ie.arg = tab_bar_arg;
 21818                 }
 21819 
 21820             if (FRAME_X_EMBEDDED_P (f)
 21821                 && !FRAME_NO_ACCEPT_FOCUS (f))
 21822               xembed_send_message (f, event->xbutton.time,
 21823                                    XEMBED_REQUEST_FOCUS, 0, 0, 0);
 21824           }
 21825         else
 21826           {
 21827             struct scroll_bar *bar
 21828               = x_window_to_scroll_bar (event->xbutton.display,
 21829                                         event->xbutton.window, 2);
 21830 
 21831 #ifdef USE_TOOLKIT_SCROLL_BARS
 21832             /* Make the "Ctrl-Mouse-2 splits window" work for toolkit
 21833                scroll bars.  */
 21834             if (bar && event->xbutton.state & ControlMask)
 21835               {
 21836                 x_scroll_bar_handle_click (bar, event, &inev.ie, Qnil);
 21837                 *finish = X_EVENT_DROP;
 21838               }
 21839 #else /* not USE_TOOLKIT_SCROLL_BARS */
 21840             if (bar)
 21841               x_scroll_bar_handle_click (bar, event, &inev.ie, Qnil);
 21842 #endif /* not USE_TOOLKIT_SCROLL_BARS */
 21843           }
 21844 
 21845         if (event->type == ButtonPress)
 21846           {
 21847             dpyinfo->grabbed |= (1 << event->xbutton.button);
 21848             dpyinfo->last_mouse_frame = f;
 21849             if (f && !tab_bar_p)
 21850               f->last_tab_bar_item = -1;
 21851 #if ! defined (USE_GTK)
 21852             if (f && !tool_bar_p)
 21853               f->last_tool_bar_item = -1;
 21854 #endif /* not USE_GTK */
 21855           }
 21856         else
 21857           dpyinfo->grabbed &= ~(1 << event->xbutton.button);
 21858 
 21859         /* Ignore any mouse motion that happened before this event;
 21860            any subsequent mouse-movement Emacs events should reflect
 21861            only motion after the ButtonPress/Release.  */
 21862         if (f != 0)
 21863           f->mouse_moved = false;
 21864 
 21865 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 21866         f = x_menubar_window_to_frame (dpyinfo, event);
 21867         /* For a down-event in the menu bar, don't pass it to Xt or
 21868            GTK right away.  Instead, save it and pass it to Xt or GTK
 21869            from kbd_buffer_get_event.  That way, we can run some Lisp
 21870            code first.  */
 21871         if (! popup_activated ()
 21872 #ifdef USE_GTK
 21873             /* Gtk+ menus only react to the first three buttons. */
 21874             && event->xbutton.button < 3
 21875 #endif
 21876             && f && event->type == ButtonPress
 21877             /* Verify the event is really within the menu bar
 21878                and not just sent to it due to grabbing.  */
 21879             && event->xbutton.x >= 0
 21880             && event->xbutton.x < FRAME_PIXEL_WIDTH (f)
 21881             && event->xbutton.y >= 0
 21882             && event->xbutton.y < FRAME_MENUBAR_HEIGHT (f)
 21883             && event->xbutton.same_screen)
 21884           {
 21885 #ifdef USE_MOTIF
 21886             Widget widget;
 21887 
 21888             widget = XtWindowToWidget (dpyinfo->display,
 21889                                        event->xbutton.window);
 21890 
 21891             if (widget && XmIsCascadeButton (widget)
 21892                 && XtIsSensitive (widget))
 21893               {
 21894 #endif
 21895                 if (!f->output_data.x->saved_menu_event)
 21896                   f->output_data.x->saved_menu_event = xmalloc (sizeof *event);
 21897                 *f->output_data.x->saved_menu_event = *event;
 21898                 inev.ie.kind = MENU_BAR_ACTIVATE_EVENT;
 21899                 XSETFRAME (inev.ie.frame_or_window, f);
 21900                 *finish = X_EVENT_DROP;
 21901 #ifdef USE_MOTIF
 21902               }
 21903 #endif
 21904           }
 21905         else
 21906           goto OTHER;
 21907 #endif /* USE_X_TOOLKIT || USE_GTK */
 21908       }
 21909       break;
 21910 
 21911     case CirculateNotify:
 21912       if (x_dnd_in_progress
 21913           /* When _NET_WM_CLIENT_LIST stacking is being used, changes
 21914              in that property are watched for, and it's not necessary
 21915              to update the state in response to ordinary window
 21916              substructure events.  */
 21917           && !x_dnd_use_toplevels
 21918           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 21919         x_dnd_update_state (dpyinfo, dpyinfo->last_user_time);
 21920       goto OTHER;
 21921 
 21922     case CirculateRequest:
 21923       goto OTHER;
 21924 
 21925     case VisibilityNotify:
 21926       f = x_top_window_to_frame (dpyinfo, event->xvisibility.window);
 21927 
 21928       if (f)
 21929         FRAME_X_OUTPUT (f)->visibility_state = event->xvisibility.state;
 21930 
 21931       goto OTHER;
 21932 
 21933     case MappingNotify:
 21934       /* Someone has changed the keyboard mapping - update the
 21935          local cache.  */
 21936       switch (event->xmapping.request)
 21937         {
 21938         case MappingModifier:
 21939           x_find_modifier_meanings (dpyinfo);
 21940           FALLTHROUGH;
 21941         case MappingKeyboard:
 21942           XRefreshKeyboardMapping ((XMappingEvent *) &event->xmapping);
 21943         }
 21944       goto OTHER;
 21945 
 21946     case DestroyNotify:
 21947       if (event->xdestroywindow.window
 21948           == dpyinfo->net_supported_window)
 21949         dpyinfo->net_supported_window = None;
 21950 
 21951       if (event->xdestroywindow.window
 21952           == dpyinfo->motif_drag_window)
 21953         /* We get DestroyNotify events for the drag window because
 21954            x_special_window_exists_p selects for structure
 21955            notification.  The drag window is not supposed to go away
 21956            but not all clients obey that requirement when setting the
 21957            drag window property.  */
 21958         dpyinfo->motif_drag_window = None;
 21959 
 21960       xft_settings_event (dpyinfo, event);
 21961       break;
 21962 
 21963 #ifdef HAVE_XINPUT2
 21964     case GenericEvent:
 21965       {
 21966         if (!dpyinfo->supports_xi2)
 21967           goto OTHER;
 21968 
 21969         if (event->xgeneric.extension != dpyinfo->xi2_opcode)
 21970           /* Not an XI2 event. */
 21971           goto OTHER;
 21972 
 21973         bool must_free_data = false;
 21974         XIEvent *xi_event = (XIEvent *) event->xcookie.data;
 21975 
 21976         /* Sometimes the event is already claimed by GTK, which
 21977            will free its data in due course. */
 21978         if (!xi_event)
 21979           {
 21980             if (XGetEventData (dpyinfo->display, &event->xcookie))
 21981               must_free_data = true;
 21982 
 21983             xi_event = (XIEvent *) event->xcookie.data;
 21984           }
 21985 
 21986         XIDeviceEvent *xev = (XIDeviceEvent *) xi_event;
 21987 
 21988         if (!xi_event)
 21989           {
 21990             /* It may turn out that the event data has already been
 21991                implicitly freed for various reasons up to and
 21992                including XMenuActivate pushing some other event onto
 21993                the foreign-event queue, or x_menu_wait_for_events
 21994                calling XNextEvent through a timer that tries to wait
 21995                for input.
 21996 
 21997                In that case, XGetEventData will return True, but
 21998                cookie->data will be NULL.  Since handling such input
 21999                events is not really important, we can afford to
 22000                discard them.
 22001 
 22002                The way Xlib is currently implemented makes calling
 22003                XFreeEventData unnecessary in this case, but call it
 22004                anyway, since not doing so may lead to a memory leak in
 22005                the future.  */
 22006 
 22007             if (must_free_data)
 22008               XFreeEventData (dpyinfo->display, &event->xcookie);
 22009             goto OTHER;
 22010           }
 22011 
 22012         switch (event->xcookie.evtype)
 22013           {
 22014           case XI_FocusIn:
 22015             {
 22016               XIFocusInEvent *focusin;
 22017 
 22018               focusin = (XIFocusInEvent *) xi_event;
 22019               any = x_any_window_to_frame (dpyinfo, focusin->event);
 22020 
 22021 #ifdef USE_GTK
 22022               /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
 22023                  minimized/iconified windows; thus, for those WMs we won't get
 22024                  a MapNotify when unminimizing/deiconifying.  Check here if we
 22025                  are deiconizing a window (Bug42655).
 22026 
 22027                  But don't do that by default on GTK since it may cause a plain
 22028                  invisible frame get reported as iconified, compare
 22029                  https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
 22030                  That is fixed above but bites us here again.
 22031 
 22032                  The option x_set_frame_visibility_more_laxly allows to override
 22033                  the default behavior (Bug#49955, Bug#53298).  */
 22034               if (EQ (x_set_frame_visibility_more_laxly, Qfocus_in)
 22035                   || EQ (x_set_frame_visibility_more_laxly, Qt))
 22036 #endif /* USE_GTK */
 22037                 {
 22038                   f = any;
 22039                   if (f && FRAME_ICONIFIED_P (f))
 22040                     {
 22041                       SET_FRAME_VISIBLE (f, 1);
 22042                       SET_FRAME_ICONIFIED (f, false);
 22043                       f->output_data.x->has_been_visible = true;
 22044                       inev.ie.kind = DEICONIFY_EVENT;
 22045                       XSETFRAME (inev.ie.frame_or_window, f);
 22046                     }
 22047                 }
 22048 
 22049               xi_focus_handle_for_device (dpyinfo, any, xi_event);
 22050 
 22051               goto XI_OTHER;
 22052             }
 22053 
 22054           case XI_FocusOut:
 22055             {
 22056               XIFocusOutEvent *focusout;
 22057 
 22058               focusout = (XIFocusOutEvent *) xi_event;
 22059               any = x_any_window_to_frame (dpyinfo, focusout->event);
 22060               xi_focus_handle_for_device (dpyinfo, any, xi_event);
 22061 
 22062               goto XI_OTHER;
 22063             }
 22064 
 22065           case XI_Enter:
 22066             {
 22067               XIEnterEvent *enter = (XIEnterEvent *) xi_event;
 22068               XMotionEvent ev;
 22069               struct xi_device_t *source;
 22070 
 22071               any = x_top_window_to_frame (dpyinfo, enter->event);
 22072               source = xi_device_from_id (dpyinfo, enter->sourceid);
 22073 
 22074               ev.x = lrint (enter->event_x);
 22075               ev.y = lrint (enter->event_y);
 22076               ev.window = enter->event;
 22077               ev.time = enter->time;
 22078               ev.send_event = enter->send_event;
 22079 
 22080               x_display_set_last_user_time (dpyinfo, enter->time,
 22081                                             enter->send_event, false);
 22082 
 22083 #ifdef USE_MOTIF
 22084               use_copy = true;
 22085 
 22086               copy.xcrossing.type = EnterNotify;
 22087               copy.xcrossing.serial = enter->serial;
 22088               copy.xcrossing.send_event = enter->send_event;
 22089               copy.xcrossing.display = dpyinfo->display;
 22090               copy.xcrossing.window = enter->event;
 22091               copy.xcrossing.root = enter->root;
 22092               copy.xcrossing.subwindow = enter->child;
 22093               copy.xcrossing.time = enter->time;
 22094               copy.xcrossing.x = lrint (enter->event_x);
 22095               copy.xcrossing.y = lrint (enter->event_y);
 22096               copy.xcrossing.x_root = lrint (enter->root_x);
 22097               copy.xcrossing.y_root = lrint (enter->root_y);
 22098               copy.xcrossing.mode = enter->mode;
 22099               copy.xcrossing.detail = enter->detail;
 22100               copy.xcrossing.focus = enter->focus;
 22101               copy.xcrossing.state = 0;
 22102               copy.xcrossing.same_screen = True;
 22103 #endif
 22104 
 22105               /* There is no need to handle entry/exit events for
 22106                  passive focus from non-top windows at all, since they
 22107                  are an inferiors of the frame's top window, which will
 22108                  get virtual events.  */
 22109               if (any)
 22110                 xi_focus_handle_for_device (dpyinfo, any, xi_event);
 22111 
 22112               if (!any)
 22113                 any = x_any_window_to_frame (dpyinfo, enter->event);
 22114 
 22115 #ifdef HAVE_XINPUT2_1
 22116               /* xfwm4 selects for button events on the frame window,
 22117                  resulting in passive grabs being generated along with
 22118                  the delivery of emulated button events; this then
 22119                  interferes with scrolling, since device valuators
 22120                  will constantly be reset as the crossing events
 22121                  related to those grabs arrive.  The only way to
 22122                  remedy this is to never reset scroll valuators on a
 22123                  grab-related crossing event.  (bug#57476) */
 22124 
 22125               if (enter->mode != XINotifyUngrab
 22126                   && enter->mode != XINotifyGrab
 22127                   && enter->mode != XINotifyPassiveGrab
 22128                   && enter->mode != XINotifyPassiveUngrab)
 22129                 xi_reset_scroll_valuators_for_device_id (dpyinfo,
 22130                                                          enter->deviceid);
 22131 #endif
 22132 
 22133               {
 22134 #ifdef HAVE_XWIDGETS
 22135                 struct xwidget_view *xwidget_view;
 22136 
 22137                 xwidget_view = xwidget_view_from_window (enter->event);
 22138 
 22139                 if (xwidget_view)
 22140                   {
 22141                     xwidget_motion_or_crossing (xwidget_view, event);
 22142 
 22143                     goto XI_OTHER;
 22144                   }
 22145 #endif
 22146               }
 22147 
 22148               f = any;
 22149 
 22150               if (f && enter->event == FRAME_X_WINDOW (f))
 22151                 xi_compute_root_window_offset_enter (f, enter);
 22152 
 22153               if (f && x_mouse_click_focus_ignore_position)
 22154                 {
 22155                   ignore_next_mouse_click_timeout = (enter->time
 22156                                                      + x_mouse_click_focus_ignore_time);
 22157                   mouse_click_timeout_display = dpyinfo;
 22158                 }
 22159 
 22160               /* EnterNotify counts as mouse movement,
 22161                  so update things that depend on mouse position.  */
 22162               if (f && !f->output_data.x->hourglass_p)
 22163                 x_note_mouse_movement (f, &ev, source ? source->name : Qnil);
 22164 #ifdef USE_GTK
 22165               /* We may get an EnterNotify on the buttons in the toolbar.  In that
 22166                  case we moved out of any highlighted area and need to note this.  */
 22167               if (!f && dpyinfo->last_mouse_glyph_frame)
 22168                 x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev,
 22169                                        source ? source->name : Qnil);
 22170 #endif
 22171               goto XI_OTHER;
 22172             }
 22173 
 22174           case XI_Leave:
 22175             {
 22176               XILeaveEvent *leave;
 22177               struct xi_device_t *device;
 22178 
 22179               leave = (XILeaveEvent *) xi_event;
 22180 #ifdef USE_GTK
 22181               struct xi_device_t *source;
 22182               XMotionEvent ev;
 22183 
 22184               ev.x = lrint (leave->event_x);
 22185               ev.y = lrint (leave->event_y);
 22186               ev.window = leave->event;
 22187               ev.time = leave->time;
 22188               ev.send_event = leave->send_event;
 22189 #endif
 22190 
 22191               any = x_top_window_to_frame (dpyinfo, leave->event);
 22192 
 22193 #ifdef USE_GTK
 22194               source = xi_device_from_id (dpyinfo, leave->sourceid);
 22195 #endif
 22196               device = xi_device_from_id (dpyinfo, leave->deviceid);
 22197 
 22198               if (device)
 22199                 xi_report_motion_window_clear (device);
 22200 
 22201               /* This allows us to catch LeaveNotify events generated by
 22202                  popup menu grabs.  FIXME: this is right when there is a
 22203                  focus menu, but implicit focus tracking can get screwed
 22204                  up if we get this and no XI_Enter event later.   */
 22205 
 22206 #ifdef USE_X_TOOLKIT
 22207               if (popup_activated ()
 22208                   && (leave->mode == XINotifyPassiveUngrab
 22209                       || leave->mode == XINotifyUngrab))
 22210                 any = x_any_window_to_frame (dpyinfo, leave->event);
 22211 #endif
 22212 
 22213 #ifdef USE_MOTIF
 22214               use_copy = true;
 22215 
 22216               copy.xcrossing.type = LeaveNotify;
 22217               copy.xcrossing.serial = leave->serial;
 22218               copy.xcrossing.send_event = leave->send_event;
 22219               copy.xcrossing.display = dpyinfo->display;
 22220               copy.xcrossing.window = leave->event;
 22221               copy.xcrossing.root = leave->root;
 22222               copy.xcrossing.subwindow = leave->child;
 22223               copy.xcrossing.time = leave->time;
 22224               copy.xcrossing.x = lrint (leave->event_x);
 22225               copy.xcrossing.y = lrint (leave->event_y);
 22226               copy.xcrossing.x_root = lrint (leave->root_x);
 22227               copy.xcrossing.y_root = lrint (leave->root_y);
 22228               copy.xcrossing.mode = leave->mode;
 22229               copy.xcrossing.detail = leave->detail;
 22230               copy.xcrossing.focus = leave->focus;
 22231               copy.xcrossing.state = 0;
 22232               copy.xcrossing.same_screen = True;
 22233 #endif
 22234 
 22235               /* One problem behind the design of XInput 2 scrolling is
 22236                  that valuators are not unique to each window, but only
 22237                  the window that has grabbed the valuator's device or
 22238                  the window that the device's pointer is on top of can
 22239                  receive motion events.  There is also no way to
 22240                  retrieve the value of a valuator outside of each motion
 22241                  event.
 22242 
 22243                  As such, to prevent wildly inaccurate results when
 22244                  the valuators have changed outside Emacs, we reset
 22245                  our records of each valuator's value whenever the
 22246                  pointer moves out of a frame.  Ideally, this would
 22247                  ignore events with a detail of XINotifyInferior, as
 22248                  the window the pointer moved to would be one known to
 22249                  Emacs, but the code to keep track of which valuators
 22250                  had to be reset upon the corresponding XI_Enter event
 22251                  was very complicated and kept running into server
 22252                  bugs.  */
 22253 #ifdef HAVE_XINPUT2_1
 22254               /* xfwm4 selects for button events on the frame window,
 22255                  resulting in passive grabs being generated along with
 22256                  the delivery of emulated button events; this then
 22257                  interferes with scrolling, since device valuators
 22258                  will constantly be reset as the crossing events
 22259                  related to those grabs arrive.  The only way to
 22260                  remedy this is to never reset scroll valuators on a
 22261                  grab-related crossing event.  (bug#57476) */
 22262 
 22263               if (leave->mode != XINotifyUngrab
 22264                   && leave->mode != XINotifyGrab
 22265                   && leave->mode != XINotifyPassiveUngrab
 22266                   && leave->mode != XINotifyPassiveGrab)
 22267                 xi_reset_scroll_valuators_for_device_id (dpyinfo,
 22268                                                          leave->deviceid);
 22269 #endif
 22270 
 22271               x_display_set_last_user_time (dpyinfo, leave->time,
 22272                                             leave->send_event, false);
 22273 
 22274 #ifdef HAVE_XWIDGETS
 22275               {
 22276                 struct xwidget_view *xvw;
 22277 
 22278                 xvw = xwidget_view_from_window (leave->event);
 22279 
 22280                 if (xvw)
 22281                   {
 22282                     *finish = X_EVENT_DROP;
 22283                     xwidget_motion_or_crossing (xvw, event);
 22284 
 22285                     goto XI_OTHER;
 22286                   }
 22287               }
 22288 #endif
 22289 
 22290               if (any)
 22291                 xi_focus_handle_for_device (dpyinfo, any, xi_event);
 22292 
 22293 #ifndef USE_X_TOOLKIT
 22294               f = x_top_window_to_frame (dpyinfo, leave->event);
 22295 #else
 22296               /* On Xt builds that have XI2, the enter and leave event
 22297                  masks are set on the frame widget's window.  */
 22298               f = x_window_to_frame (dpyinfo, leave->event);
 22299 
 22300               if (!f)
 22301                 f = x_top_window_to_frame (dpyinfo, leave->event);
 22302 #endif
 22303 
 22304               if (f)
 22305                 {
 22306                   /* Now clear dpyinfo->last_mouse_motion_frame, or
 22307                      gui_redo_mouse_highlight will end up highlighting
 22308                      the last known position of the mouse if a
 22309                      tooltip frame is later unmapped.  */
 22310 
 22311                   if (f == dpyinfo->last_mouse_motion_frame)
 22312                     dpyinfo->last_mouse_motion_frame = NULL;
 22313 
 22314                   /* Something similar applies to
 22315                      dpyinfo->last_mouse_glyph_frame.  */
 22316                   if (f == dpyinfo->last_mouse_glyph_frame)
 22317                     dpyinfo->last_mouse_glyph_frame = NULL;
 22318 
 22319                   if (f == hlinfo->mouse_face_mouse_frame)
 22320                     {
 22321                       /* If we move outside the frame, then we're
 22322                          certainly no longer on any text in the frame.  */
 22323                       clear_mouse_face (hlinfo);
 22324                       hlinfo->mouse_face_mouse_frame = 0;
 22325                       x_flush_dirty_back_buffer_on (f);
 22326                     }
 22327 
 22328                   /* Generate a nil HELP_EVENT to cancel a help-echo.
 22329                      Do it only if there's something to cancel.
 22330                      Otherwise, the startup message is cleared when
 22331                      the mouse leaves the frame.  */
 22332                   if (any_help_event_p
 22333                       /* But never if `mouse-drag-and-drop-region' is
 22334                          in progress, since that results in the
 22335                          tooltip being dismissed when the mouse moves
 22336                          on top.  */
 22337                       && !((EQ (track_mouse, Qdrag_source)
 22338                             || EQ (track_mouse, Qdropping))
 22339                            && gui_mouse_grabbed (dpyinfo)))
 22340                     do_help = -1;
 22341 
 22342                   if (f && leave->event == FRAME_X_WINDOW (f))
 22343                     xi_compute_root_window_offset_enter (f, leave);
 22344                 }
 22345 #ifdef USE_GTK
 22346               /* See comment in EnterNotify above */
 22347               else if (dpyinfo->last_mouse_glyph_frame)
 22348                 x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev,
 22349                                        source ? source->name : Qnil);
 22350 #endif
 22351               goto XI_OTHER;
 22352             }
 22353 
 22354           case XI_Motion:
 22355             {
 22356               struct xi_device_t *device, *source;
 22357 #ifdef HAVE_XINPUT2_1
 22358               XIValuatorState *states;
 22359               double *values;
 22360               bool found_valuator = false;
 22361               bool other_valuators_found = false;
 22362 #endif
 22363               /* A fake XMotionEvent for x_note_mouse_movement. */
 22364               XMotionEvent ev;
 22365               xm_top_level_leave_message lmsg;
 22366               xm_top_level_enter_message emsg;
 22367               xm_drag_motion_message dmsg;
 22368               unsigned int dnd_state;
 22369 
 22370               source = xi_device_from_id (dpyinfo, xev->sourceid);
 22371 
 22372 #ifdef HAVE_XINPUT2_1
 22373               states = &xev->valuators;
 22374               values = states->values;
 22375 #endif
 22376 
 22377               device = xi_device_from_id (dpyinfo, xev->deviceid);
 22378 
 22379               if (!device)
 22380                 goto XI_OTHER;
 22381 
 22382 #ifdef HAVE_XINPUT2_2
 22383               if (xev->flags & XIPointerEmulated)
 22384                 goto XI_OTHER;
 22385 #endif
 22386 
 22387 #ifdef HAVE_XINPUT2_1
 22388 #ifdef HAVE_XWIDGETS
 22389               struct xwidget_view *xv = xwidget_view_from_window (xev->event);
 22390               double xv_total_x = 0.0;
 22391               double xv_total_y = 0.0;
 22392 #endif
 22393               double total_x = 0.0;
 22394               double total_y = 0.0;
 22395 
 22396               int real_x, real_y;
 22397 
 22398               for (int i = 0; i < states->mask_len * 8; i++)
 22399                 {
 22400                   if (XIMaskIsSet (states->mask, i))
 22401                     {
 22402                       struct xi_scroll_valuator_t *val;
 22403                       double delta, scroll_unit;
 22404                       int scroll_height;
 22405                       Lisp_Object window;
 22406                       struct scroll_bar *bar;
 22407 
 22408                       bar = NULL;
 22409 
 22410                       /* See the comment on top of x_cache_xi_devices
 22411                          for more details on how scroll wheel movement
 22412                          is reported on XInput 2.  */
 22413                       delta = x_get_scroll_valuator_delta (dpyinfo, device,
 22414                                                            i, *values, &val);
 22415                       values++;
 22416 
 22417                       if (!val)
 22418                         {
 22419                           other_valuators_found = true;
 22420                           continue;
 22421                         }
 22422 
 22423                       if (delta != DBL_MAX)
 22424                         {
 22425                           if (!f)
 22426                             {
 22427                               f = x_any_window_to_frame (dpyinfo, xev->event);
 22428 
 22429                               if (!f)
 22430                                 {
 22431 #if defined USE_MOTIF || !defined USE_TOOLKIT_SCROLL_BARS
 22432                                   bar = x_window_to_scroll_bar (dpyinfo->display,
 22433                                                                 xev->event, 2);
 22434 
 22435                                   if (bar)
 22436                                     f = WINDOW_XFRAME (XWINDOW (bar->window));
 22437 
 22438                                   if (!f)
 22439 #endif
 22440                                     goto XI_OTHER;
 22441                                 }
 22442                             }
 22443 
 22444 #ifdef USE_GTK
 22445                           if (f && xg_event_is_for_scrollbar (f, event, true))
 22446                             *finish = X_EVENT_DROP;
 22447 #endif
 22448 
 22449                           if (FRAME_X_WINDOW (f) != xev->event)
 22450                             {
 22451                               if (!bar)
 22452                                 bar = x_window_to_scroll_bar (dpyinfo->display, xev->event, 2);
 22453 
 22454                               /* If this is a scroll bar, compute the
 22455                                  actual position directly to avoid an
 22456                                  extra roundtrip.  */
 22457 
 22458                               if (bar)
 22459                                 {
 22460                                   real_x = lrint (xev->event_x + bar->left);
 22461                                   real_y = lrint (xev->event_y + bar->top);
 22462                                 }
 22463                               else
 22464                                 x_translate_coordinates (f,
 22465                                                          lrint (xev->root_x),
 22466                                                          lrint (xev->root_y),
 22467                                                          &real_x, &real_y);
 22468                             }
 22469                           else
 22470                             {
 22471                               real_x = lrint (xev->event_x);
 22472                               real_y = lrint (xev->event_y);
 22473                             }
 22474 
 22475 #ifdef HAVE_XWIDGETS
 22476                           if (xv)
 22477                             {
 22478                               if (val->horizontal)
 22479                                 xv_total_x += delta;
 22480                               else
 22481                                 xv_total_y += delta;
 22482 
 22483                               found_valuator = true;
 22484                               continue;
 22485                             }
 22486 #endif
 22487 
 22488                           if (delta == 0.0)
 22489                             found_valuator = true;
 22490 
 22491                           if (signbit (delta) != signbit (val->emacs_value))
 22492                             val->emacs_value = 0;
 22493 
 22494                           val->emacs_value += delta;
 22495 
 22496                           if (mwheel_coalesce_scroll_events
 22497                               && (fabs (val->emacs_value) < 1)
 22498                               && (fabs (delta) > 0))
 22499                             continue;
 22500 
 22501                           window = window_from_coordinates (f, real_x, real_y, NULL,
 22502                                                             false, false);
 22503 
 22504                           if (WINDOWP (window))
 22505                             scroll_height = XWINDOW (window)->pixel_height;
 22506                           else
 22507                             /* EVENT_X and EVENT_Y can be outside the
 22508                                frame if F holds the input grab, so fall
 22509                                back to the height of the frame instead.  */
 22510                             scroll_height = FRAME_PIXEL_HEIGHT (f);
 22511 
 22512                           scroll_unit = pow (scroll_height, 2.0 / 3.0);
 22513 
 22514                           if (NUMBERP (Vx_scroll_event_delta_factor))
 22515                             scroll_unit *= XFLOATINT (Vx_scroll_event_delta_factor);
 22516 
 22517                           if (val->horizontal)
 22518                             total_x += val->emacs_value * scroll_unit;
 22519                           else
 22520                             total_y += val->emacs_value * scroll_unit;
 22521 
 22522                           found_valuator = true;
 22523                           val->emacs_value = 0;
 22524                         }
 22525                     }
 22526                 }
 22527 
 22528 #ifdef HAVE_XWIDGETS
 22529               if (xv)
 22530                 {
 22531                   unsigned int state;
 22532 
 22533                   state = xi_convert_event_state (xev);
 22534                   x_display_set_last_user_time (dpyinfo, xev->time,
 22535                                                 xev->send_event, true);
 22536 
 22537                   if (found_valuator)
 22538                     xwidget_scroll (xv, xev->event_x, xev->event_y,
 22539                                     -xv_total_x, -xv_total_y, state,
 22540                                     xev->time, (xv_total_x == 0.0
 22541                                                 && xv_total_y == 0.0));
 22542                   else
 22543                     xwidget_motion_notify (xv, xev->event_x, xev->event_y,
 22544                                            xev->root_x, xev->root_y, state,
 22545                                            xev->time);
 22546 
 22547                   goto XI_OTHER;
 22548                 }
 22549               else
 22550                 {
 22551 #endif
 22552                   if (found_valuator)
 22553                     {
 22554                       x_display_set_last_user_time (dpyinfo, xev->time,
 22555                                                     xev->send_event, true);
 22556 
 22557 
 22558 #if defined USE_GTK && !defined HAVE_GTK3
 22559                       /* Unlike on Motif, we can't select for XI
 22560                          events on the scroll bar window under GTK+ 2.
 22561                          So instead of that, just ignore XI wheel
 22562                          events which land on a scroll bar.
 22563 
 22564                          Here we assume anything which isn't the edit
 22565                          widget window is a scroll bar.  */
 22566 
 22567                       if (xev->child != None
 22568                           && xev->child != FRAME_X_WINDOW (f))
 22569                         goto XI_OTHER;
 22570 #endif
 22571 
 22572                       /* If this happened during a drag-and-drop
 22573                          operation, don't send an event.  We only have
 22574                          to set the user time.  */
 22575                       if (x_dnd_in_progress
 22576                           /* If another master device moved the
 22577                              pointer, we should put a wheel event on
 22578                              the keyboard buffer as usual.  It will be
 22579                              run once the drag-and-drop operation
 22580                              completes.  */
 22581                           && xev->deviceid == x_dnd_pointer_device
 22582                           && (command_loop_level + minibuf_level
 22583                               <= x_dnd_recursion_depth)
 22584                           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 22585                         goto XI_OTHER;
 22586 
 22587                       if (fabs (total_x) > 0 || fabs (total_y) > 0)
 22588                         {
 22589                           inev.ie.kind = (fabs (total_y) >= fabs (total_x)
 22590                                           ? WHEEL_EVENT : HORIZ_WHEEL_EVENT);
 22591                           inev.ie.timestamp = xev->time;
 22592 
 22593                           XSETINT (inev.ie.x, lrint (real_x));
 22594                           XSETINT (inev.ie.y, lrint (real_y));
 22595                           XSETFRAME (inev.ie.frame_or_window, f);
 22596 
 22597                           inev.ie.modifiers = (signbit (fabs (total_y) >= fabs (total_x)
 22598                                                         ? total_y : total_x)
 22599                                                ? down_modifier : up_modifier);
 22600                           inev.ie.modifiers
 22601                             |= x_x_to_emacs_modifiers (dpyinfo,
 22602                                                        xev->mods.effective);
 22603                           inev.ie.arg = list3 (Qnil,
 22604                                                make_float (total_x),
 22605                                                make_float (total_y));
 22606                         }
 22607                       else
 22608                         {
 22609                           inev.ie.kind = TOUCH_END_EVENT;
 22610                           inev.ie.timestamp = xev->time;
 22611 
 22612                           XSETINT (inev.ie.x, lrint (real_x));
 22613                           XSETINT (inev.ie.y, lrint (real_y));
 22614                           XSETFRAME (inev.ie.frame_or_window, f);
 22615                         }
 22616 
 22617                       if (source && !NILP (source->name))
 22618                         inev.ie.device = source->name;
 22619 
 22620                       if (!other_valuators_found)
 22621                         goto XI_OTHER;
 22622                     }
 22623 #ifdef HAVE_XWIDGETS
 22624                 }
 22625 #endif
 22626 #endif /* HAVE_XINPUT2_1 */
 22627 
 22628               if (!xi_position_changed (device, xev))
 22629                 goto XI_OTHER;
 22630 
 22631               ev.x = lrint (xev->event_x);
 22632               ev.y = lrint (xev->event_y);
 22633               ev.window = xev->event;
 22634               ev.time = xev->time;
 22635               ev.send_event = xev->send_event;
 22636 
 22637 #ifdef USE_MOTIF
 22638               use_copy = true;
 22639 
 22640               copy.xmotion.type = MotionNotify;
 22641               copy.xmotion.serial = xev->serial;
 22642               copy.xmotion.send_event = xev->send_event;
 22643               copy.xmotion.display = dpyinfo->display;
 22644               copy.xmotion.window = xev->event;
 22645               copy.xmotion.root = xev->root;
 22646               copy.xmotion.subwindow = xev->child;
 22647               copy.xmotion.time = xev->time;
 22648               copy.xmotion.x = lrint (xev->event_x);
 22649               copy.xmotion.y = lrint (xev->event_y);
 22650               copy.xmotion.x_root = lrint (xev->root_x);
 22651               copy.xmotion.y_root = lrint (xev->root_y);
 22652               copy.xmotion.state = xi_convert_event_state (xev);
 22653 
 22654               copy.xmotion.is_hint = False;
 22655               copy.xmotion.same_screen = True;
 22656 #endif
 22657 
 22658               previous_help_echo_string = help_echo_string;
 22659               help_echo_string = Qnil;
 22660 
 22661               if (hlinfo->mouse_face_hidden)
 22662                 {
 22663                   hlinfo->mouse_face_hidden = false;
 22664                   clear_mouse_face (hlinfo);
 22665                 }
 22666 
 22667               f = mouse_or_wdesc_frame (dpyinfo, xev->event);
 22668 
 22669               if (f && xev->event == FRAME_X_WINDOW (f))
 22670                 /* See the comment above x_compute_root_window_offset
 22671                    for why this optimization is performed.  */
 22672                 xi_compute_root_window_offset (f, xev);
 22673 
 22674               if (x_dnd_in_progress
 22675                   /* Handle these events normally if the recursion
 22676                      level is higher than when the drag-and-drop
 22677                      operation was initiated.  This is so that mouse
 22678                      input works while we're in the debugger for, say,
 22679                      `x-dnd-movement-function`.  */
 22680                   && (command_loop_level + minibuf_level
 22681                       <= x_dnd_recursion_depth)
 22682                   && xev->deviceid == x_dnd_pointer_device
 22683                   && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 22684                 {
 22685                   Window target, toplevel;
 22686                   int target_proto, motif_style;
 22687                   XRectangle *r;
 22688                   bool was_frame;
 22689 
 22690                   /* Always clear mouse face.  */
 22691                   clear_mouse_face (hlinfo);
 22692                   hlinfo->mouse_face_hidden = true;
 22693 
 22694                   /* Sometimes the drag-and-drop operation starts with the
 22695                      pointer of a frame invisible due to input.  Since
 22696                      motion events are ignored during that, make the pointer
 22697                      visible manually.  */
 22698 
 22699                   if (f)
 22700                     {
 22701                       XTtoggle_invisible_pointer (f, false);
 22702 
 22703                       r = &dpyinfo->last_mouse_glyph;
 22704 
 22705                       /* Also remember the mouse glyph and set
 22706                          mouse_moved.  */
 22707                       if (f != dpyinfo->last_mouse_glyph_frame
 22708                           || lrint (xev->event_x) < r->x
 22709                           || lrint (xev->event_x) >= r->x + r->width
 22710                           || lrint (xev->event_y) < r->y
 22711                           || lrint (xev->event_y) >= r->y + r->height)
 22712                         {
 22713                           f->mouse_moved = true;
 22714                           f->last_mouse_device = (source ? source->name
 22715                                                   : Qnil);
 22716                           dpyinfo->last_mouse_scroll_bar = NULL;
 22717 
 22718                           remember_mouse_glyph (f, lrint (xev->event_x),
 22719                                                 lrint (xev->event_y), r);
 22720                           dpyinfo->last_mouse_glyph_frame = f;
 22721                         }
 22722                     }
 22723 
 22724                   if (xev->root == dpyinfo->root_window)
 22725                     target = x_dnd_get_target_window (dpyinfo,
 22726                                                       lrint (xev->root_x),
 22727                                                       lrint (xev->root_y),
 22728                                                       &target_proto,
 22729                                                       &motif_style,
 22730                                                       &toplevel,
 22731                                                       &was_frame);
 22732                   else
 22733                     target = x_dnd_fill_empty_target (&target_proto,
 22734                                                       &motif_style,
 22735                                                       &toplevel,
 22736                                                       &was_frame);
 22737 
 22738                   if (toplevel != x_dnd_last_seen_toplevel)
 22739                     {
 22740                       if (toplevel != FRAME_OUTER_WINDOW (x_dnd_frame)
 22741                           && x_dnd_return_frame == 1)
 22742                         x_dnd_return_frame = 2;
 22743 
 22744                       if (x_dnd_return_frame == 2
 22745                           && x_any_window_to_frame (dpyinfo, toplevel))
 22746                         {
 22747                           if (x_dnd_last_seen_window != None
 22748                               && x_dnd_last_protocol_version != -1
 22749                               && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 22750                             x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 22751                                               x_dnd_last_seen_toplevel);
 22752                           else if (x_dnd_last_seen_window != None
 22753                                    && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 22754                                    && !x_dnd_disable_motif_drag
 22755                                    && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 22756                             {
 22757                               if (!x_dnd_motif_setup_p)
 22758                                 xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22759 
 22760                               lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22761                                                             XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 22762                               lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22763                               lmsg.zero = 0;
 22764                               lmsg.timestamp = xev->time;
 22765                               lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 22766 
 22767                               if (x_dnd_motif_setup_p)
 22768                                 xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22769                                                                  x_dnd_last_seen_window, &lmsg);
 22770                             }
 22771 
 22772                           x_dnd_end_window = x_dnd_last_seen_window;
 22773                           x_dnd_last_seen_window = None;
 22774                           x_dnd_last_seen_toplevel = None;
 22775                           x_dnd_in_progress = false;
 22776                           x_dnd_return_frame_object
 22777                             = x_any_window_to_frame (dpyinfo, toplevel);
 22778                           x_dnd_return_frame = 3;
 22779                           x_dnd_waiting_for_finish = false;
 22780                           target = None;
 22781                         }
 22782                     }
 22783 
 22784                   if (target != x_dnd_last_seen_window)
 22785                     {
 22786                       if (x_dnd_last_seen_window != None
 22787                           && x_dnd_last_protocol_version != -1
 22788                           && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 22789                         x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window,
 22790                                           x_dnd_last_seen_toplevel);
 22791                       else if (x_dnd_last_seen_window != None
 22792                                && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 22793                                && !x_dnd_disable_motif_drag
 22794                                && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
 22795                         {
 22796                           if (!x_dnd_motif_setup_p)
 22797                             xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22798 
 22799                           /* This is apparently required.  If we don't
 22800                              send a motion event with the current root
 22801                              window coordinates of the pointer before
 22802                              the top level leave, then Motif displays
 22803                              an ugly black border around the previous
 22804                              drop site.  */
 22805 
 22806                           dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22807                                                         XM_DRAG_REASON_DRAG_MOTION);
 22808                           dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22809                           dmsg.side_effects
 22810                             = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 22811                                                                                x_dnd_wanted_action),
 22812                                                    XM_DROP_SITE_NONE, x_dnd_motif_operations,
 22813                                                    XM_DROP_ACTION_DROP_CANCEL);
 22814                           dmsg.timestamp = xev->time;
 22815                           dmsg.x = lrint (xev->root_x);
 22816                           dmsg.y = lrint (xev->root_y);
 22817 
 22818                           lmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22819                                                         XM_DRAG_REASON_TOP_LEVEL_LEAVE);
 22820                           lmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22821                           lmsg.zero = 0;
 22822                           lmsg.timestamp = xev->time;
 22823                           lmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 22824 
 22825                           if (x_dnd_motif_setup_p)
 22826                             {
 22827                               xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22828                                                            x_dnd_last_seen_window, &dmsg);
 22829                               xm_send_top_level_leave_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22830                                                                x_dnd_last_seen_window, &lmsg);
 22831                             }
 22832                         }
 22833 
 22834                       x_dnd_action = None;
 22835                       x_dnd_last_seen_toplevel = toplevel;
 22836                       x_dnd_last_seen_window = target;
 22837                       x_dnd_last_protocol_version = target_proto;
 22838                       x_dnd_last_motif_style = motif_style;
 22839                       x_dnd_last_window_is_frame = was_frame;
 22840 
 22841                       if (target != None && x_dnd_last_protocol_version != -1)
 22842                         x_dnd_send_enter (x_dnd_frame, target,
 22843                                           x_dnd_last_seen_toplevel,
 22844                                           x_dnd_last_protocol_version);
 22845                       else if (target != None && XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style)
 22846                                && !x_dnd_disable_motif_drag)
 22847                         {
 22848                           if (!x_dnd_motif_setup_p)
 22849                             xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22850 
 22851                           emsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22852                                                         XM_DRAG_REASON_TOP_LEVEL_ENTER);
 22853                           emsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22854                           emsg.zero = 0;
 22855                           emsg.timestamp = xev->time;
 22856                           emsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 22857                           emsg.index_atom = x_dnd_motif_atom;
 22858 
 22859                           if (x_dnd_motif_setup_p)
 22860                             xm_send_top_level_enter_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22861                                                              target, &emsg);
 22862                         }
 22863                     }
 22864                   else
 22865                     x_dnd_last_seen_toplevel = toplevel;
 22866 
 22867                   if (x_dnd_last_window_is_frame && target != None)
 22868                     x_dnd_note_self_position (dpyinfo, target,
 22869                                               lrint (xev->root_x),
 22870                                               lrint (xev->root_y));
 22871                   else if (x_dnd_last_protocol_version != -1 && target != None)
 22872                     {
 22873                       dnd_state = xi_convert_event_state (xev);
 22874 
 22875                       x_dnd_send_position (x_dnd_frame, target,
 22876                                            x_dnd_last_seen_toplevel,
 22877                                            x_dnd_last_protocol_version,
 22878                                            lrint (xev->root_x),
 22879                                            lrint (xev->root_y),
 22880                                            x_dnd_selection_timestamp,
 22881                                            x_dnd_wanted_action, 0,
 22882                                            dnd_state);
 22883                     }
 22884                   else if (XM_DRAG_STYLE_IS_DYNAMIC (x_dnd_last_motif_style) && target != None
 22885                            && !x_dnd_disable_motif_drag)
 22886                     {
 22887                       if (!x_dnd_motif_setup_p)
 22888                         xm_setup_drag_info (dpyinfo, x_dnd_frame);
 22889 
 22890                       dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 22891                                                     XM_DRAG_REASON_DRAG_MOTION);
 22892                       dmsg.byteorder = XM_BYTE_ORDER_CUR_FIRST;
 22893                       dmsg.side_effects
 22894                         = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 22895                                                                            x_dnd_wanted_action),
 22896                                                XM_DROP_SITE_VALID, x_dnd_motif_operations,
 22897                                                (!x_dnd_xm_use_help
 22898                                                 ? XM_DROP_ACTION_DROP
 22899                                                 : XM_DROP_ACTION_DROP_HELP));
 22900                       dmsg.timestamp = xev->time;
 22901                       dmsg.x = lrint (xev->root_x);
 22902                       dmsg.y = lrint (xev->root_y);
 22903 
 22904                       if (x_dnd_motif_setup_p)
 22905                         xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 22906                                                      target, &dmsg);
 22907                     }
 22908 
 22909                   x_dnd_update_tooltip_position (xev->root_x, xev->root_y);
 22910 
 22911                   goto XI_OTHER;
 22912                 }
 22913 
 22914 #ifdef USE_GTK
 22915               if (f && xg_event_is_for_scrollbar (f, event, false))
 22916                 f = 0;
 22917 #endif
 22918               if (f)
 22919                 {
 22920                   if (xev->event != FRAME_X_WINDOW (f))
 22921                     {
 22922                       x_translate_coordinates (f, lrint (xev->root_x),
 22923                                                lrint (xev->root_y),
 22924                                                &ev.x, &ev.y);
 22925                       ev.window = FRAME_X_WINDOW (f);
 22926                     }
 22927 
 22928                   /* Maybe generate a SELECT_WINDOW_EVENT for
 22929                      `mouse-autoselect-window' but don't let popup menus
 22930                      interfere with this (Bug#1261).  */
 22931                   if (!NILP (Vmouse_autoselect_window)
 22932                       && !popup_activated ()
 22933                       /* Don't switch if we're currently in the minibuffer.
 22934                          This tries to work around problems where the
 22935                          minibuffer gets unselected unexpectedly, and where
 22936                          you then have to move your mouse all the way down to
 22937                          the minibuffer to select it.  */
 22938                       && !MINI_WINDOW_P (XWINDOW (selected_window))
 22939                       /* With `focus-follows-mouse' non-nil create an event
 22940                          also when the target window is on another frame.  */
 22941                       && (f == XFRAME (selected_frame)
 22942                           || !NILP (focus_follows_mouse)))
 22943                     {
 22944                       static Lisp_Object last_mouse_window;
 22945                       Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false);
 22946 
 22947                       /* A window will be autoselected only when it is not
 22948                          selected now and the last mouse movement event was
 22949                          not in it.  The remainder of the code is a bit vague
 22950                          wrt what a "window" is.  For immediate autoselection,
 22951                          the window is usually the entire window but for GTK
 22952                          where the scroll bars don't count.  For delayed
 22953                          autoselection the window is usually the window's text
 22954                          area including the margins.  */
 22955                       if (WINDOWP (window)
 22956                           && !EQ (window, last_mouse_window)
 22957                           && !EQ (window, selected_window))
 22958                         {
 22959                           inev.ie.kind = SELECT_WINDOW_EVENT;
 22960                           inev.ie.frame_or_window = window;
 22961 
 22962                           if (source)
 22963                             inev.ie.device = source->name;
 22964                         }
 22965 
 22966                       /* Remember the last window where we saw the mouse.  */
 22967                       last_mouse_window = window;
 22968                     }
 22969 
 22970                   if (!x_note_mouse_movement (f, &ev, source ? source->name : Qnil))
 22971                     help_echo_string = previous_help_echo_string;
 22972                 }
 22973               else
 22974                 {
 22975 #ifndef USE_TOOLKIT_SCROLL_BARS
 22976                   struct scroll_bar *bar
 22977                     = x_window_to_scroll_bar (dpyinfo->display, xev->event, 2);
 22978 
 22979                   if (bar)
 22980                     x_scroll_bar_note_movement (bar, &ev);
 22981 #endif /* USE_TOOLKIT_SCROLL_BARS */
 22982 
 22983                   /* If we move outside the frame, then we're
 22984                      certainly no longer on any text in the frame.  */
 22985                   clear_mouse_face (hlinfo);
 22986                 }
 22987 
 22988               /* If the contents of the global variable help_echo_string
 22989                  has changed, generate a HELP_EVENT.  */
 22990               if (!NILP (help_echo_string)
 22991                   || !NILP (previous_help_echo_string))
 22992                 {
 22993                   /* Also allow the focus and client pointer to be
 22994                      adjusted accordingly, in case a help tooltip is
 22995                      shown.  */
 22996                   gen_help_device = device;
 22997                   gen_help_time = xev->time;
 22998 
 22999                   do_help = 1;
 23000                 }
 23001 
 23002               if (f)
 23003                 x_flush_dirty_back_buffer_on (f);
 23004               goto XI_OTHER;
 23005             }
 23006 
 23007           case XI_ButtonRelease:
 23008           case XI_ButtonPress:
 23009             {
 23010               /* If we decide we want to generate an event to be seen
 23011                  by the rest of Emacs, we put it here.  */
 23012               Lisp_Object tab_bar_arg = Qnil;
 23013               bool tab_bar_p = false;
 23014               bool tool_bar_p = false;
 23015               struct xi_device_t *device, *source;
 23016 #ifdef HAVE_XWIDGETS
 23017               struct xwidget_view *xvw;
 23018 #endif
 23019               /* A fake XButtonEvent for x_construct_mouse_click. */
 23020               XButtonEvent bv;
 23021               bool dnd_grab = false;
 23022               int dnd_state;
 23023 
 23024               if (x_dnd_in_progress
 23025                   && (command_loop_level + minibuf_level
 23026                       <= x_dnd_recursion_depth)
 23027                   && xev->deviceid == x_dnd_pointer_device
 23028                   && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 23029                 {
 23030                   f = mouse_or_wdesc_frame (dpyinfo, xev->event);
 23031                   device = xi_device_from_id (dpyinfo, xev->deviceid);
 23032 
 23033                   if (f && xev->event == FRAME_X_WINDOW (f))
 23034                     /* See the comment above
 23035                        x_compute_root_window_offset for why this
 23036                        optimization is performed.  */
 23037                     xi_compute_root_window_offset (f, xev);
 23038 
 23039                   /* Don't track grab status for emulated pointer
 23040                      events, because they are ignored by the regular
 23041                      mouse click processing code.  */
 23042 #ifdef XIPointerEmulated
 23043                   if (!(xev->flags & XIPointerEmulated))
 23044                     {
 23045 #endif
 23046                       if (xev->evtype == XI_ButtonPress)
 23047                         {
 23048                           x_display_set_last_user_time (dpyinfo, xev->time,
 23049                                                         xev->send_event, true);
 23050 
 23051                           dpyinfo->grabbed |= (1 << xev->detail);
 23052                           dpyinfo->last_mouse_frame = f;
 23053 
 23054                           if (device)
 23055                             device->grab |= (1 << xev->detail);
 23056 
 23057                           if (f)
 23058                             f->last_tab_bar_item = -1;
 23059 #if ! defined (USE_GTK)
 23060                           if (f)
 23061                             f->last_tool_bar_item = -1;
 23062 #endif /* not USE_GTK */
 23063                         }
 23064                       else
 23065                         {
 23066                           dpyinfo->grabbed &= ~(1 << xev->detail);
 23067                           if (device)
 23068                             device->grab &= ~(1 << xev->detail);
 23069                         }
 23070 #ifdef XIPointerEmulated
 23071                     }
 23072 #endif
 23073 
 23074                   if (f && device)
 23075                     xi_handle_interaction (dpyinfo, f, device,
 23076                                            xev->time);
 23077 
 23078                   if (xev->evtype == XI_ButtonPress
 23079                       && x_dnd_last_seen_window != None)
 23080                     {
 23081                       dnd_state = xi_convert_event_state (xev);
 23082 
 23083                       if (x_dnd_last_window_is_frame)
 23084                         {
 23085 #ifdef XI_PointerEmulated
 23086                           /* Set the last user time here even if this
 23087                              is an emulated button event, since
 23088                              something happened in response.  */
 23089 
 23090                           if (xev->flags & XIPointerEmulated)
 23091                             x_display_set_last_user_time (dpyinfo, xev->time,
 23092                                                           xev->send_event, true);
 23093 #endif
 23094                           x_dnd_note_self_wheel (dpyinfo,
 23095                                                  x_dnd_last_seen_window,
 23096                                                  lrint (xev->root_x),
 23097                                                  lrint (xev->root_y),
 23098                                                  xev->detail, dnd_state,
 23099                                                  xev->time);
 23100                         }
 23101                       else
 23102                         x_dnd_send_position (x_dnd_frame,
 23103                                              x_dnd_last_seen_window,
 23104                                              x_dnd_last_seen_toplevel,
 23105                                              x_dnd_last_protocol_version,
 23106                                              lrint (xev->root_x),
 23107                                              lrint (xev->root_y),
 23108                                              xev->time, x_dnd_wanted_action,
 23109                                              xev->detail, dnd_state);
 23110 
 23111                       goto OTHER;
 23112                     }
 23113 
 23114                   if (xev->evtype == XI_ButtonRelease)
 23115                     {
 23116                       for (int i = 0; i < xev->buttons.mask_len * 8; ++i)
 23117                         {
 23118                           if (i != xev->detail && XIMaskIsSet (xev->buttons.mask, i))
 23119                             dnd_grab = true;
 23120                         }
 23121 
 23122                       if (!dnd_grab)
 23123                         {
 23124                           x_dnd_end_window = x_dnd_last_seen_window;
 23125                           x_dnd_in_progress = false;
 23126 
 23127                           /* If a tooltip that we're following is
 23128                              displayed, hide it now.  */
 23129 
 23130                           if (x_dnd_update_tooltip
 23131                               && FRAMEP (tip_frame)
 23132                               && FRAME_LIVE_P (XFRAME (tip_frame))
 23133                               && (FRAME_X_DISPLAY (XFRAME (tip_frame))
 23134                                   == FRAME_X_DISPLAY (x_dnd_frame)))
 23135                             Fx_hide_tip ();
 23136 
 23137                           /* This doesn't have to be marked since it
 23138                              is only accessed if
 23139                              x_dnd_waiting_for_finish is true, which
 23140                              is only possible inside the DND event
 23141                              loop where that frame is on the
 23142                              stack.  */
 23143                           x_dnd_finish_frame = x_dnd_frame;
 23144 
 23145                           if (x_dnd_last_seen_window != None
 23146                               && x_dnd_last_window_is_frame)
 23147                             {
 23148                               x_dnd_waiting_for_finish = false;
 23149                               x_dnd_note_self_drop (dpyinfo, x_dnd_last_seen_window,
 23150                                                     lrint (xev->root_x),
 23151                                                     lrint (xev->root_y), xev->time);
 23152                             }
 23153                           else if (x_dnd_last_seen_window != None
 23154                                    && x_dnd_last_protocol_version != -1)
 23155                             {
 23156                               x_dnd_pending_finish_target = x_dnd_last_seen_toplevel;
 23157                               x_dnd_waiting_for_finish_proto = x_dnd_last_protocol_version;
 23158 
 23159                               x_dnd_waiting_for_finish
 23160                                 = x_dnd_do_drop (x_dnd_last_seen_window,
 23161                                                  x_dnd_last_seen_toplevel,
 23162                                                  x_dnd_last_protocol_version);
 23163                               x_dnd_finish_display = dpyinfo->display;
 23164                             }
 23165                           else if (x_dnd_last_seen_window != None)
 23166                             {
 23167                               xm_drop_start_message dmsg;
 23168                               xm_drag_receiver_info drag_receiver_info;
 23169 
 23170                               if (!xm_read_drag_receiver_info (dpyinfo, x_dnd_last_seen_window,
 23171                                                                &drag_receiver_info)
 23172                                   && !x_dnd_disable_motif_protocol
 23173                                   && drag_receiver_info.protocol_style != XM_DRAG_STYLE_NONE
 23174                                   && (x_dnd_allow_current_frame
 23175                                       || x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame)))
 23176                                 {
 23177                                   if (!x_dnd_motif_setup_p)
 23178                                     xm_setup_drag_info (dpyinfo, x_dnd_frame);
 23179 
 23180                                   if (x_dnd_motif_setup_p)
 23181                                     {
 23182                                       memset (&dmsg, 0, sizeof dmsg);
 23183 
 23184                                       dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 23185                                                                     XM_DRAG_REASON_DROP_START);
 23186                                       dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
 23187                                       dmsg.side_effects
 23188                                         = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (dpyinfo,
 23189                                                                                            x_dnd_wanted_action),
 23190                                                                XM_DROP_SITE_VALID, x_dnd_motif_operations,
 23191                                                                (!x_dnd_xm_use_help
 23192                                                                 ? XM_DROP_ACTION_DROP
 23193                                                                 : XM_DROP_ACTION_DROP_HELP));
 23194                                       dmsg.timestamp = xev->time;
 23195                                       dmsg.x = lrint (xev->root_x);
 23196                                       dmsg.y = lrint (xev->root_y);
 23197                                       /* This atom technically has to be
 23198                                          unique to each drag-and-drop
 23199                                          operation, but that isn't easy to
 23200                                          accomplish, since we cannot
 23201                                          randomly move data around between
 23202                                          selections.  Let's hope no two
 23203                                          instances of Emacs try to drag
 23204                                          into the same window at the same
 23205                                          time.  */
 23206                                       dmsg.index_atom = x_dnd_motif_atom;
 23207                                       dmsg.source_window = FRAME_X_WINDOW (x_dnd_frame);
 23208 
 23209                                       if (!XM_DRAG_STYLE_IS_DROP_ONLY (drag_receiver_info.protocol_style))
 23210                                         x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (x_dnd_frame),
 23211                                                                       x_dnd_frame, x_dnd_last_seen_window,
 23212                                                                       xev->time);
 23213 
 23214                                       xm_send_drop_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame),
 23215                                                             x_dnd_last_seen_window, &dmsg);
 23216 
 23217                                       x_dnd_waiting_for_finish = true;
 23218                                       x_dnd_waiting_for_motif_finish_display = dpyinfo;
 23219                                       x_dnd_waiting_for_motif_finish = 1;
 23220                                       x_dnd_finish_display = dpyinfo->display;
 23221                                     }
 23222                                 }
 23223                               else
 23224                                 x_dnd_send_unsupported_drop (dpyinfo, (x_dnd_last_seen_toplevel != None
 23225                                                                        ? x_dnd_last_seen_toplevel
 23226                                                                        : x_dnd_last_seen_window),
 23227                                                              lrint (xev->root_x),
 23228                                                              lrint (xev->root_y), xev->time);
 23229                             }
 23230                           else if (x_dnd_last_seen_toplevel != None)
 23231                             x_dnd_send_unsupported_drop (dpyinfo,
 23232                                                          x_dnd_last_seen_toplevel,
 23233                                                          lrint (xev->root_x),
 23234                                                          lrint (xev->root_y),
 23235                                                          xev->time);
 23236 
 23237                           x_dnd_last_protocol_version = -1;
 23238                           x_dnd_last_motif_style = XM_DRAG_STYLE_NONE;
 23239                           x_dnd_last_seen_window = None;
 23240                           x_dnd_last_seen_toplevel = None;
 23241                           x_dnd_last_window_is_frame = false;
 23242                           x_dnd_frame = NULL;
 23243 
 23244                           goto XI_OTHER;
 23245                         }
 23246                     }
 23247                 }
 23248 
 23249               if (x_dnd_in_progress
 23250                   && (command_loop_level + minibuf_level
 23251                       <= x_dnd_recursion_depth))
 23252                 goto XI_OTHER;
 23253 
 23254 #ifdef USE_MOTIF
 23255 #ifdef USE_TOOLKIT_SCROLL_BARS
 23256               struct scroll_bar *bar
 23257                 = x_window_to_scroll_bar (dpyinfo->display,
 23258                                           xev->event, 2);
 23259 #endif
 23260 
 23261               use_copy = true;
 23262               copy.xbutton.type = (xev->evtype == XI_ButtonPress
 23263                                    ? ButtonPress : ButtonRelease);
 23264               copy.xbutton.serial = xev->serial;
 23265               copy.xbutton.send_event = xev->send_event;
 23266               copy.xbutton.display = dpyinfo->display;
 23267               copy.xbutton.window = xev->event;
 23268               copy.xbutton.root = xev->root;
 23269               copy.xbutton.subwindow = xev->child;
 23270               copy.xbutton.time = xev->time;
 23271               copy.xbutton.x = lrint (xev->event_x);
 23272               copy.xbutton.y = lrint (xev->event_y);
 23273               copy.xbutton.x_root = lrint (xev->root_x);
 23274               copy.xbutton.y_root = lrint (xev->root_y);
 23275               copy.xbutton.state = xi_convert_event_state (xev);
 23276               copy.xbutton.button = xev->detail;
 23277               copy.xbutton.same_screen = True;
 23278 
 23279 #elif defined USE_GTK && !defined HAVE_GTK3
 23280               copy = gdk_event_new (xev->evtype == XI_ButtonPress
 23281                                     ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
 23282 
 23283               copy->button.window = gdk_x11_window_lookup_for_display (gdpy, xev->event);
 23284               copy->button.send_event = xev->send_event;
 23285               copy->button.time = xev->time;
 23286               copy->button.x = xev->event_x;
 23287               copy->button.y = xev->event_y;
 23288               copy->button.x_root = xev->root_x;
 23289               copy->button.y_root = xev->root_y;
 23290               copy->button.state = xi_convert_event_state (xev);
 23291               copy->button.button = xev->detail;
 23292 
 23293               if (!copy->button.window)
 23294                 emacs_abort ();
 23295 
 23296               g_object_ref (copy->button.window);
 23297 
 23298               if (popup_activated ())
 23299                 {
 23300                   /* GTK+ popup menus don't respond to core buttons
 23301                      after Button3, so don't dismiss popup menus upon
 23302                      wheel movement here either.  */
 23303                   if (xev->detail > 3)
 23304                     *finish = X_EVENT_DROP;
 23305 
 23306                   if (xev->evtype == XI_ButtonRelease)
 23307                     goto XI_OTHER;
 23308                 }
 23309 #endif
 23310 
 23311 #ifdef HAVE_XINPUT2_1
 23312               /* Ignore emulated scroll events when XI2 native
 23313                  scroll events are present.  */
 23314               if (xev->flags & XIPointerEmulated)
 23315                 {
 23316 #if !defined USE_MOTIF || !defined USE_TOOLKIT_SCROLL_BARS
 23317                   *finish = X_EVENT_DROP;
 23318 #else
 23319                   if (bar)
 23320                     *finish = X_EVENT_DROP;
 23321 #endif
 23322                   goto XI_OTHER;
 23323                 }
 23324 #endif
 23325 
 23326               if (xev->evtype == XI_ButtonPress)
 23327                 x_display_set_last_user_time (dpyinfo, xev->time,
 23328                                               xev->send_event, true);
 23329 
 23330               source = xi_device_from_id (dpyinfo, xev->sourceid);
 23331               device = xi_device_from_id (dpyinfo, xev->deviceid);
 23332 
 23333 #ifdef HAVE_XWIDGETS
 23334               xvw = xwidget_view_from_window (xev->event);
 23335               if (xvw)
 23336                 {
 23337                   /* If the user interacts with a frame that's focused
 23338                      on another device, but not the current focus
 23339                      frame, make it the focus frame.  */
 23340                   if (device)
 23341                     xi_handle_interaction (dpyinfo, xvw->frame,
 23342                                            device, xev->time);
 23343 
 23344                   xwidget_button (xvw, xev->evtype == XI_ButtonPress,
 23345                                   lrint (xev->event_x), lrint (xev->event_y),
 23346                                   xev->detail, xi_convert_event_state (xev),
 23347                                   xev->time);
 23348 
 23349                   if (!EQ (selected_window, xvw->w) && (xev->detail < 4))
 23350                     {
 23351                       inev.ie.kind = SELECT_WINDOW_EVENT;
 23352                       inev.ie.frame_or_window = xvw->w;
 23353 
 23354                       if (source)
 23355                         inev.ie.device = source->name;
 23356                     }
 23357 
 23358                   *finish = X_EVENT_DROP;
 23359                   goto XI_OTHER;
 23360                 }
 23361 #endif
 23362 
 23363               if (!device)
 23364                 goto XI_OTHER;
 23365 
 23366               bv.button = xev->detail;
 23367               bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease;
 23368               bv.x = lrint (xev->event_x);
 23369               bv.y = lrint (xev->event_y);
 23370               bv.x_root = lrint (xev->root_x);
 23371               bv.y_root = lrint (xev->root_y);
 23372               bv.window = xev->event;
 23373               bv.state = xi_convert_event_state (xev);
 23374               bv.time = xev->time;
 23375 
 23376               dpyinfo->last_mouse_glyph_frame = NULL;
 23377 
 23378               f = mouse_or_wdesc_frame (dpyinfo, xev->event);
 23379 
 23380               if (f && xev->event == FRAME_X_WINDOW (f))
 23381                 /* See the comment above x_compute_root_window_offset
 23382                    for why this optimization is performed.  */
 23383                 xi_compute_root_window_offset (f, xev);
 23384 
 23385               if (f && xev->evtype == XI_ButtonPress
 23386                   && !popup_activated ()
 23387                   && !x_window_to_scroll_bar (dpyinfo->display, xev->event, 2)
 23388                   && !FRAME_NO_ACCEPT_FOCUS (f))
 23389                 {
 23390                   /* When clicking into a child frame or when clicking
 23391                      into a parent frame with the child frame selected and
 23392                      `no-accept-focus' is not set, select the clicked
 23393                      frame.  */
 23394                   struct frame *hf = dpyinfo->highlight_frame;
 23395 
 23396                   if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
 23397                     {
 23398 #if defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT)
 23399                       if (device)
 23400                         {
 23401                           /* This can generate XI_BadDevice if the
 23402                              device's attachment was destroyed
 23403                              server-side.  */
 23404                           x_ignore_errors_for_next_request (dpyinfo, 0);
 23405                           XISetFocus (dpyinfo->display, device->attachment,
 23406                                       /* Note that the input extension
 23407                                          only supports RevertToParent-type
 23408                                          behavior.  */
 23409                                       FRAME_OUTER_WINDOW (f), xev->time);
 23410                           x_stop_ignoring_errors (dpyinfo);
 23411                         }
 23412 #else
 23413                       /* Non-no toolkit builds without GTK 3 use core
 23414                          events to handle focus.  Errors are still
 23415                          caught here in case the window is not
 23416                          viewable.  */
 23417                       x_ignore_errors_for_next_request (dpyinfo, 0);
 23418                       XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 23419                                       RevertToParent, xev->time);
 23420                       x_stop_ignoring_errors (dpyinfo);
 23421 #endif
 23422                       if (FRAME_PARENT_FRAME (f))
 23423                         XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
 23424                     }
 23425                 }
 23426 
 23427               if (f)
 23428                 {
 23429                   /* If the user interacts with a frame that's focused
 23430                      on another device, but not the current focus
 23431                      frame, make it the focus frame.  */
 23432                   if (device)
 23433                     xi_handle_interaction (dpyinfo, f, device,
 23434                                            xev->time);
 23435                 }
 23436 
 23437 #ifdef USE_GTK
 23438               if (!f)
 23439                 {
 23440                   int real_x = lrint (xev->root_x);
 23441                   int real_y = lrint (xev->root_y);
 23442 
 23443                   f = x_any_window_to_frame (dpyinfo, xev->event);
 23444 
 23445                   if (xev->detail > 3 && xev->detail < 8 && f)
 23446                     {
 23447                       if (xev->evtype == XI_ButtonRelease)
 23448                         {
 23449                           if (FRAME_X_WINDOW (f) != xev->event)
 23450                             x_translate_coordinates (f, real_x, real_y,
 23451                                                      &real_x, &real_y);
 23452 
 23453                           if (xev->detail <= 5)
 23454                             inev.ie.kind = WHEEL_EVENT;
 23455                           else
 23456                             inev.ie.kind = HORIZ_WHEEL_EVENT;
 23457 
 23458                           if (source)
 23459                             inev.ie.device = source->name;
 23460 
 23461                           inev.ie.timestamp = xev->time;
 23462 
 23463                           XSETINT (inev.ie.x, real_x);
 23464                           XSETINT (inev.ie.y, real_y);
 23465                           XSETFRAME (inev.ie.frame_or_window, f);
 23466 
 23467                           inev.ie.modifiers
 23468                             |= x_x_to_emacs_modifiers (dpyinfo,
 23469                                                        xev->mods.effective);
 23470 
 23471                           inev.ie.modifiers |= xev->detail % 2 ? down_modifier : up_modifier;
 23472                         }
 23473 
 23474                       *finish = X_EVENT_DROP;
 23475                       goto XI_OTHER;
 23476                     }
 23477                   else
 23478                     f = NULL;
 23479                 }
 23480 
 23481               if (f && xg_event_is_for_scrollbar (f, event, false))
 23482                 f = 0;
 23483 #endif
 23484 
 23485               if (f)
 23486                 {
 23487                   if (xev->detail >= 4 && xev->detail < 8)
 23488                     {
 23489                       if (xev->evtype == XI_ButtonRelease)
 23490                         {
 23491                           if (xev->detail <= 5)
 23492                             inev.ie.kind = WHEEL_EVENT;
 23493                           else
 23494                             inev.ie.kind = HORIZ_WHEEL_EVENT;
 23495 
 23496                           if (source)
 23497                             inev.ie.device = source->name;
 23498 
 23499                           inev.ie.timestamp = xev->time;
 23500 
 23501                           XSETINT (inev.ie.x, lrint (xev->event_x));
 23502                           XSETINT (inev.ie.y, lrint (xev->event_y));
 23503                           XSETFRAME (inev.ie.frame_or_window, f);
 23504 
 23505                           inev.ie.modifiers
 23506                             |= x_x_to_emacs_modifiers (dpyinfo,
 23507                                                        xev->mods.effective);
 23508 
 23509                           inev.ie.modifiers |= xev->detail % 2 ? down_modifier : up_modifier;
 23510                         }
 23511 
 23512                       goto XI_OTHER;
 23513                     }
 23514 
 23515                   /* Is this in the tab-bar?  */
 23516                   if (WINDOWP (f->tab_bar_window)
 23517                       && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
 23518                     {
 23519                       Lisp_Object window;
 23520                       int x = bv.x;
 23521                       int y = bv.y;
 23522 
 23523                       window = window_from_coordinates (f, x, y, 0, true, true);
 23524                       tab_bar_p = EQ (window, f->tab_bar_window);
 23525 
 23526                       if (tab_bar_p)
 23527                         {
 23528                           tab_bar_arg = handle_tab_bar_click
 23529                             (f, x, y, xev->evtype == XI_ButtonPress,
 23530                              x_x_to_emacs_modifiers (dpyinfo, bv.state));
 23531                           x_flush_dirty_back_buffer_on (f);
 23532                         }
 23533                     }
 23534 
 23535 #if ! defined (USE_GTK)
 23536                   /* Is this in the tool-bar?  */
 23537                   if (WINDOWP (f->tool_bar_window)
 23538                       && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
 23539                     {
 23540                       Lisp_Object window;
 23541                       int x = bv.x;
 23542                       int y = bv.y;
 23543 
 23544                       window = window_from_coordinates (f, x, y, 0, true, true);
 23545                       /* Ignore button release events if the mouse
 23546                          wasn't previously pressed on the tool bar.
 23547                          We do this because otherwise selecting some
 23548                          text with the mouse and then releasing it on
 23549                          the tool bar doesn't stop selecting text,
 23550                          since the tool bar eats the button up
 23551                          event.  */
 23552                       tool_bar_p = (EQ (window, f->tool_bar_window)
 23553                                     && (xev->evtype != XI_ButtonRelease
 23554                                         || f->last_tool_bar_item != -1));
 23555 
 23556                       if (tool_bar_p && xev->detail < 4)
 23557                         {
 23558                           handle_tool_bar_click_with_device
 23559                             (f, x, y, xev->evtype == XI_ButtonPress,
 23560                              x_x_to_emacs_modifiers (dpyinfo, bv.state),
 23561                              source ? source->name : Qt);
 23562                           x_flush_dirty_back_buffer_on (f);
 23563                         }
 23564                     }
 23565 #endif /* !USE_GTK */
 23566 
 23567                   if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p)
 23568 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 23569                     if (! popup_activated ())
 23570 #endif
 23571                       {
 23572                         if (ignore_next_mouse_click_timeout)
 23573                           {
 23574                             if (xev->evtype == XI_ButtonPress
 23575                                 && xev->time > ignore_next_mouse_click_timeout)
 23576                               {
 23577                                 ignore_next_mouse_click_timeout = 0;
 23578                                 x_construct_mouse_click (&inev.ie, &bv, f);
 23579                               }
 23580                             if (xev->evtype == XI_ButtonRelease)
 23581                               ignore_next_mouse_click_timeout = 0;
 23582                           }
 23583                         else
 23584                           x_construct_mouse_click (&inev.ie, &bv, f);
 23585 
 23586                         if (!NILP (tab_bar_arg))
 23587                           inev.ie.arg = tab_bar_arg;
 23588                       }
 23589 
 23590                   if (FRAME_X_EMBEDDED_P (f)
 23591                       && !FRAME_NO_ACCEPT_FOCUS (f))
 23592                     xembed_send_message (f, xev->time,
 23593                                          XEMBED_REQUEST_FOCUS, 0, 0, 0);
 23594                 }
 23595               else
 23596                 {
 23597                   struct scroll_bar *bar
 23598                     = x_window_to_scroll_bar (dpyinfo->display,
 23599                                               xev->event, 2);
 23600 
 23601 #ifndef USE_TOOLKIT_SCROLL_BARS
 23602                   if (bar)
 23603                     x_scroll_bar_handle_click (bar, (XEvent *) &bv, &inev.ie,
 23604                                                source ? source->name : Qnil);
 23605 #else
 23606                   /* Make the "Ctrl-Mouse-2 splits window" work for toolkit
 23607                      scroll bars.  */
 23608                   if (bar && xev->mods.effective & ControlMask)
 23609                     {
 23610                       x_scroll_bar_handle_click (bar, (XEvent *) &bv, &inev.ie,
 23611                                                  source ? source->name : Qnil);
 23612                       *finish = X_EVENT_DROP;
 23613                     }
 23614 #endif
 23615                 }
 23616 
 23617               if (xev->evtype == XI_ButtonPress)
 23618                 {
 23619                   dpyinfo->grabbed |= (1 << xev->detail);
 23620                   device->grab |= (1 << xev->detail);
 23621                   dpyinfo->last_mouse_frame = f;
 23622                   if (f && !tab_bar_p)
 23623                     f->last_tab_bar_item = -1;
 23624 #if ! defined (USE_GTK)
 23625                   if (f && !tool_bar_p)
 23626                     f->last_tool_bar_item = -1;
 23627 #endif /* not USE_GTK */
 23628 
 23629                 }
 23630               else
 23631                 {
 23632                   dpyinfo->grabbed &= ~(1 << xev->detail);
 23633                   device->grab &= ~(1 << xev->detail);
 23634                 }
 23635 
 23636               if (source && inev.ie.kind != NO_EVENT)
 23637                 inev.ie.device = source->name;
 23638 
 23639               if (f)
 23640                 f->mouse_moved = false;
 23641 
 23642 #if defined (USE_GTK)
 23643               /* No Xt toolkit currently available has support for XI2.
 23644                  So the code here assumes use of GTK.  */
 23645               f = x_menubar_window_to_frame (dpyinfo, event);
 23646               if (f /* Gtk+ menus only react to the first three buttons. */
 23647                   && xev->detail < 3)
 23648                 {
 23649                   /* What is done with Core Input ButtonPressed is not
 23650                      possible here, because GenericEvents cannot be saved.  */
 23651                   bool was_waiting_for_input = waiting_for_input;
 23652                   /* This hack was adopted from the NS port.  Whether
 23653                      or not it is actually safe is a different story
 23654                      altogether.  */
 23655                   if (waiting_for_input)
 23656                     waiting_for_input = 0;
 23657                   set_frame_menubar (f, true);
 23658                   waiting_for_input = was_waiting_for_input;
 23659                 }
 23660 #endif
 23661               goto XI_OTHER;
 23662             }
 23663 
 23664           case XI_KeyPress:
 23665             {
 23666               int state = xev->mods.effective;
 23667               Lisp_Object c;
 23668 #ifdef HAVE_XKB
 23669               unsigned int mods_rtrn;
 23670 #endif
 23671               int keycode = xev->detail;
 23672               KeySym keysym;
 23673               char copy_buffer[81];
 23674               char *copy_bufptr = copy_buffer;
 23675               int copy_bufsiz = sizeof (copy_buffer);
 23676               ptrdiff_t i;
 23677               unsigned int old_state;
 23678               struct xi_device_t *device, *source;
 23679 
 23680               coding = Qlatin_1;
 23681 
 23682               device = xi_device_from_id (dpyinfo, xev->deviceid);
 23683               source = xi_device_from_id (dpyinfo, xev->sourceid);
 23684 
 23685               if (!device)
 23686                 goto XI_OTHER;
 23687 
 23688 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 23689               /* Dispatch XI_KeyPress events when in menu.  */
 23690               if (popup_activated ())
 23691                 {
 23692 #ifdef USE_LUCID
 23693                   /* This makes key navigation work inside menus.  */
 23694                   use_copy = true;
 23695                   copy.xkey.type = KeyPress;
 23696                   copy.xkey.serial = xev->serial;
 23697                   copy.xkey.send_event = xev->send_event;
 23698                   copy.xkey.display = dpyinfo->display;
 23699                   copy.xkey.window = xev->event;
 23700                   copy.xkey.root = xev->root;
 23701                   copy.xkey.subwindow = xev->child;
 23702                   copy.xkey.time = xev->time;
 23703                   copy.xkey.state = xi_convert_event_keyboard_state (xev);
 23704                   xi_convert_button_state (&xev->buttons, &copy.xkey.state);
 23705 
 23706                   copy.xkey.x = lrint (xev->event_x);
 23707                   copy.xkey.y = lrint (xev->event_y);
 23708                   copy.xkey.x_root = lrint (xev->root_x);
 23709                   copy.xkey.y_root = lrint (xev->root_y);
 23710                   copy.xkey.keycode = xev->detail;
 23711                   copy.xkey.same_screen = True;
 23712 #endif
 23713                   goto XI_OTHER;
 23714                 }
 23715 #endif
 23716 
 23717               x_display_set_last_user_time (dpyinfo, xev->time,
 23718                                             xev->send_event, true);
 23719               ignore_next_mouse_click_timeout = 0;
 23720 
 23721               f = x_any_window_to_frame (dpyinfo, xev->event);
 23722 
 23723               if (f && xev->event == FRAME_X_WINDOW (f))
 23724                 /* See the comment above x_compute_root_window_offset
 23725                    for why this optimization is performed.  */
 23726                 xi_compute_root_window_offset (f, xev);
 23727 
 23728               /* GTK handles TAB events in an undesirable manner, so
 23729                  keyboard events are always dropped.  But as a side
 23730                  effect, the user time will no longer be set by GDK,
 23731                  so do that manually.  */
 23732 #ifdef USE_GTK
 23733               if (f)
 23734                 x_set_gtk_user_time (f, xev->time);
 23735 #endif
 23736 
 23737               if (f)
 23738                 {
 23739                   /* If the user interacts with a frame that's focused
 23740                      on another device, but not the current focus
 23741                      frame, make it the focus frame.  */
 23742                   if (device)
 23743                     xi_handle_interaction (dpyinfo, f, device,
 23744                                            xev->time);
 23745                 }
 23746 
 23747               XKeyPressedEvent xkey;
 23748 
 23749               memset (&xkey, 0, sizeof xkey);
 23750 
 23751               xkey.type = KeyPress;
 23752               xkey.serial = xev->serial;
 23753               xkey.send_event = xev->send_event;
 23754               xkey.display = dpyinfo->display;
 23755               xkey.window = xev->event;
 23756               xkey.root = xev->root;
 23757               xkey.subwindow = xev->child;
 23758               xkey.time = xev->time;
 23759               xkey.state = xi_convert_event_keyboard_state (xev);
 23760 
 23761               xkey.x = lrint (xev->event_x);
 23762               xkey.y = lrint (xev->event_y);
 23763               xkey.x_root = lrint (xev->root_x);
 23764               xkey.y_root = lrint (xev->root_y);
 23765 
 23766               /* Some input methods react differently depending on the
 23767                  buttons that are pressed.  */
 23768               xi_convert_button_state (&xev->buttons, &xkey.state);
 23769 
 23770               xkey.keycode = xev->detail;
 23771               xkey.same_screen = True;
 23772 
 23773 #ifdef HAVE_X_I18N
 23774 #ifdef USE_GTK
 23775               if ((!x_gtk_use_native_input
 23776                    && x_filter_event (dpyinfo, (XEvent *) &xkey))
 23777                   || (x_gtk_use_native_input
 23778                       && x_filter_event (dpyinfo, event)))
 23779                 {
 23780                   /* Try to attribute core key events from the input
 23781                      method to the input extension event that caused
 23782                      them.  */
 23783                   dpyinfo->pending_keystroke_time = xev->time;
 23784                   dpyinfo->pending_keystroke_source = xev->sourceid;
 23785 
 23786                   *finish = X_EVENT_DROP;
 23787                   goto XI_OTHER;
 23788                 }
 23789 #else
 23790               if (x_filter_event (dpyinfo, (XEvent *) &xkey))
 23791                 {
 23792                   /* Try to attribute core key events from the input
 23793                      method to the input extension event that caused
 23794                      them.  */
 23795                   dpyinfo->pending_keystroke_time = xev->time;
 23796                   dpyinfo->pending_keystroke_source = xev->sourceid;
 23797 
 23798                   *finish = X_EVENT_DROP;
 23799                   goto XI_OTHER;
 23800                 }
 23801 #endif
 23802 #elif USE_GTK
 23803               if ((x_gtk_use_native_input
 23804                    || dpyinfo->prefer_native_input)
 23805                   && xg_filter_key (any, event))
 23806                 {
 23807                   /* Try to attribute core key events from the input
 23808                      method to the input extension event that caused
 23809                      them.  */
 23810                   dpyinfo->pending_keystroke_time = xev->time;
 23811                   dpyinfo->pending_keystroke_source = xev->sourceid;
 23812 
 23813                   *finish = X_EVENT_DROP;
 23814                   goto XI_OTHER;
 23815                 }
 23816 #endif
 23817 
 23818               state |= x_emacs_to_x_modifiers (dpyinfo, extra_keyboard_modifiers);
 23819 
 23820 #ifdef HAVE_XKB
 23821               if (dpyinfo->xkb_desc)
 23822                 {
 23823                   unsigned int xkb_state;
 23824 
 23825                   xkb_state = state & ~(1 << 13 | 1 << 14);
 23826                   xkb_state |= xev->group.effective << 13;
 23827 
 23828                   if (!XkbTranslateKeyCode (dpyinfo->xkb_desc, keycode,
 23829                                             xkb_state, &mods_rtrn, &keysym))
 23830                     goto XI_OTHER;
 23831                 }
 23832               else
 23833                 {
 23834 #endif
 23835                   int keysyms_per_keycode_return;
 23836                   KeySym *ksms = XGetKeyboardMapping (dpyinfo->display, keycode, 1,
 23837                                                       &keysyms_per_keycode_return);
 23838                   if (!(keysym = ksms[0]))
 23839                     {
 23840                       XFree (ksms);
 23841                       goto XI_OTHER;
 23842                     }
 23843                   XFree (ksms);
 23844 #ifdef HAVE_XKB
 23845                 }
 23846 #endif
 23847 
 23848               if (keysym == NoSymbol)
 23849                 goto XI_OTHER;
 23850 
 23851               /* If mouse-highlight is an integer, input clears out
 23852                  mouse highlighting.  */
 23853               if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight)
 23854                   && (f == 0
 23855 #if ! defined (USE_GTK)
 23856                       || !EQ (f->tool_bar_window, hlinfo->mouse_face_window)
 23857 #endif
 23858                       || !EQ (f->tab_bar_window, hlinfo->mouse_face_window))
 23859                   )
 23860                 {
 23861                   mouse_frame = hlinfo->mouse_face_mouse_frame;
 23862 
 23863                   clear_mouse_face (hlinfo);
 23864                   hlinfo->mouse_face_hidden = true;
 23865 
 23866                   if (mouse_frame)
 23867                     x_flush_dirty_back_buffer_on (mouse_frame);
 23868                 }
 23869 
 23870               if (f != 0)
 23871                 {
 23872 #ifdef USE_GTK
 23873                   /* Don't pass keys to GTK.  A Tab will shift focus to the
 23874                      tool bar in GTK 2.4.  Keys will still go to menus and
 23875                      dialogs because in that case popup_activated is nonzero
 23876                      (see above).  */
 23877                   *finish = X_EVENT_DROP;
 23878 #endif
 23879 
 23880                   XSETFRAME (inev.ie.frame_or_window, f);
 23881                   inev.ie.timestamp = xev->time;
 23882 
 23883 #ifdef HAVE_X_I18N
 23884                   if (FRAME_XIC (f))
 23885                     {
 23886                       Status status_return;
 23887                       nbytes = XmbLookupString (FRAME_XIC (f),
 23888                                                 &xkey, (char *) copy_bufptr,
 23889                                                 copy_bufsiz, &keysym,
 23890                                                 &status_return);
 23891                       coding = FRAME_X_XIM_CODING (f);
 23892 
 23893                       if (status_return == XBufferOverflow)
 23894                         {
 23895                           copy_bufsiz = nbytes + 1;
 23896                           copy_bufptr = SAFE_ALLOCA (copy_bufsiz);
 23897                           nbytes = XmbLookupString (FRAME_XIC (f),
 23898                                                     &xkey, (char *) copy_bufptr,
 23899                                                     copy_bufsiz, &keysym,
 23900                                                     &status_return);
 23901                         }
 23902 
 23903                       if (status_return == XLookupNone)
 23904                         goto xi_done_keysym;
 23905                       else if (status_return == XLookupChars)
 23906                         {
 23907                           keysym = NoSymbol;
 23908                           state = 0;
 23909                         }
 23910                       else if (status_return != XLookupKeySym
 23911                                && status_return != XLookupBoth)
 23912                         emacs_abort ();
 23913                     }
 23914                   else
 23915 #endif
 23916                     {
 23917 #ifdef HAVE_XKB
 23918                       int overflow = 0;
 23919                       KeySym sym = keysym;
 23920 
 23921                       if (dpyinfo->xkb_desc)
 23922                         {
 23923                           nbytes = XkbTranslateKeySym (dpyinfo->display, &sym,
 23924                                                        state & ~mods_rtrn, copy_bufptr,
 23925                                                        copy_bufsiz, &overflow);
 23926                           if (overflow)
 23927                             {
 23928                               copy_bufptr = SAFE_ALLOCA ((copy_bufsiz += overflow)
 23929                                                          * sizeof *copy_bufptr);
 23930                               overflow = 0;
 23931                               nbytes = XkbTranslateKeySym (dpyinfo->display, &sym,
 23932                                                            state & ~mods_rtrn, copy_bufptr,
 23933                                                            copy_bufsiz, &overflow);
 23934 
 23935                               if (overflow)
 23936                                 nbytes = 0;
 23937                             }
 23938 
 23939                           coding = Qnil;
 23940                         }
 23941                       else
 23942 #endif
 23943                         {
 23944                           old_state = xkey.state;
 23945                           xkey.state &= ~ControlMask;
 23946                           xkey.state &= ~(dpyinfo->meta_mod_mask
 23947                                           | dpyinfo->super_mod_mask
 23948                                           | dpyinfo->hyper_mod_mask
 23949                                           | dpyinfo->alt_mod_mask);
 23950 
 23951                           nbytes = XLookupString (&xkey, copy_bufptr,
 23952                                                   copy_bufsiz, &keysym,
 23953                                                   NULL);
 23954 
 23955                           xkey.state = old_state;
 23956                         }
 23957                     }
 23958 
 23959                   inev.ie.modifiers = x_x_to_emacs_modifiers (dpyinfo, state);
 23960 
 23961 #ifdef XK_F1
 23962                   if (x_dnd_in_progress
 23963                       && xev->deviceid == x_dnd_keyboard_device
 23964                       && keysym == XK_F1)
 23965                     {
 23966                       x_dnd_xm_use_help = true;
 23967                       goto xi_done_keysym;
 23968                     }
 23969 #endif
 23970 
 23971                   /* See if keysym should make Emacs quit.  */
 23972 
 23973                   if (keysym == dpyinfo->quit_keysym
 23974                       && (xev->time - dpyinfo->quit_keysym_time
 23975                           <= 350))
 23976                     {
 23977                       Vquit_flag = Qt;
 23978                       goto xi_done_keysym;
 23979                     }
 23980 
 23981                   if (keysym == dpyinfo->quit_keysym)
 23982                     {
 23983                       /* Otherwise, set the last time that keysym was
 23984                          pressed.  */
 23985                       dpyinfo->quit_keysym_time = xev->time;
 23986                       goto xi_done_keysym;
 23987                     }
 23988 
 23989                   /* First deal with keysyms which have defined
 23990                      translations to characters.  */
 23991                   if (keysym >= 32 && keysym < 128)
 23992                     /* Avoid explicitly decoding each ASCII character.  */
 23993                     {
 23994                       inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 23995                       inev.ie.code = keysym;
 23996 
 23997                       if (source)
 23998                         inev.ie.device = source->name;
 23999 
 24000                       goto xi_done_keysym;
 24001                     }
 24002 
 24003                   /* Keysyms directly mapped to Unicode characters.  */
 24004                   if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
 24005                     {
 24006                       if (keysym < 0x01000080)
 24007                         inev.ie.kind = ASCII_KEYSTROKE_EVENT;
 24008                       else
 24009                         inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 24010 
 24011                       if (source)
 24012                         inev.ie.device = source->name;
 24013 
 24014                       inev.ie.code = keysym & 0xFFFFFF;
 24015                       goto xi_done_keysym;
 24016                     }
 24017 
 24018                   /* Now non-ASCII.  */
 24019                   if (HASH_TABLE_P (Vx_keysym_table)
 24020                       && (c = Fgethash (make_fixnum (keysym),
 24021                                         Vx_keysym_table,
 24022                                         Qnil),
 24023                           FIXNATP (c)))
 24024                     {
 24025                       inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c))
 24026                                       ? ASCII_KEYSTROKE_EVENT
 24027                                       : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
 24028                       inev.ie.code = XFIXNAT (c);
 24029 
 24030                       if (source)
 24031                         inev.ie.device = source->name;
 24032 
 24033                       goto xi_done_keysym;
 24034                     }
 24035 
 24036                   /* Random non-modifier sorts of keysyms.  */
 24037                   if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
 24038                        || keysym == XK_Delete
 24039 #ifdef XK_ISO_Left_Tab
 24040                        || (keysym >= XK_ISO_Left_Tab
 24041                            && keysym <= XK_ISO_Enter)
 24042 #endif
 24043                        || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */
 24044                        || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */
 24045 #ifdef HPUX
 24046                        /* This recognizes the "extended function
 24047                           keys".  It seems there's no cleaner way.
 24048                           Test IsModifierKey to avoid handling
 24049                           mode_switch incorrectly.  */
 24050                        || (XK_Select <= keysym && keysym < XK_KP_Space)
 24051 #endif
 24052 #ifdef XK_dead_circumflex
 24053                        || keysym == XK_dead_circumflex
 24054 #endif
 24055 #ifdef XK_dead_grave
 24056                        || keysym == XK_dead_grave
 24057 #endif
 24058 #ifdef XK_dead_tilde
 24059                        || keysym == XK_dead_tilde
 24060 #endif
 24061 #ifdef XK_dead_diaeresis
 24062                        || keysym == XK_dead_diaeresis
 24063 #endif
 24064 #ifdef XK_dead_macron
 24065                        || keysym == XK_dead_macron
 24066 #endif
 24067 #ifdef XK_dead_degree
 24068                        || keysym == XK_dead_degree
 24069 #endif
 24070 #ifdef XK_dead_acute
 24071                        || keysym == XK_dead_acute
 24072 #endif
 24073 #ifdef XK_dead_cedilla
 24074                        || keysym == XK_dead_cedilla
 24075 #endif
 24076 #ifdef XK_dead_breve
 24077                        || keysym == XK_dead_breve
 24078 #endif
 24079 #ifdef XK_dead_ogonek
 24080                        || keysym == XK_dead_ogonek
 24081 #endif
 24082 #ifdef XK_dead_caron
 24083                        || keysym == XK_dead_caron
 24084 #endif
 24085 #ifdef XK_dead_doubleacute
 24086                        || keysym == XK_dead_doubleacute
 24087 #endif
 24088 #ifdef XK_dead_abovedot
 24089                        || keysym == XK_dead_abovedot
 24090 #endif
 24091 #ifdef XK_dead_abovering
 24092                        || keysym == XK_dead_abovering
 24093 #endif
 24094 #ifdef XK_dead_belowdot
 24095                        || keysym == XK_dead_belowdot
 24096 #endif
 24097 #ifdef XK_dead_voiced_sound
 24098                        || keysym == XK_dead_voiced_sound
 24099 #endif
 24100 #ifdef XK_dead_semivoiced_sound
 24101                        || keysym == XK_dead_semivoiced_sound
 24102 #endif
 24103 #ifdef XK_dead_hook
 24104                        || keysym == XK_dead_hook
 24105 #endif
 24106 #ifdef XK_dead_horn
 24107                        || keysym == XK_dead_horn
 24108 #endif
 24109 #ifdef XK_dead_stroke
 24110                        || keysym == XK_dead_stroke
 24111 #endif
 24112 #ifdef XK_dead_abovecomma
 24113                        || keysym == XK_dead_abovecomma
 24114 #endif
 24115                        || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */
 24116                        || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */
 24117                        /* Any "vendor-specific" key is ok.  */
 24118                        || (keysym & (1 << 28))
 24119                        || (keysym != NoSymbol && nbytes == 0))
 24120                       && ! (IsModifierKey (keysym)
 24121                             /* The symbols from XK_ISO_Lock
 24122                                to XK_ISO_Last_Group_Lock
 24123                                don't have real modifiers but
 24124                                should be treated similarly to
 24125                                Mode_switch by Emacs. */
 24126 #if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock
 24127                             || (XK_ISO_Lock <= keysym
 24128                                 && keysym <= XK_ISO_Last_Group_Lock)
 24129 #endif
 24130                             ))
 24131                     {
 24132                       STORE_KEYSYM_FOR_DEBUG (keysym);
 24133                       /* make_lispy_event will convert this to a symbolic
 24134                          key.  */
 24135                       inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
 24136                       inev.ie.code = keysym;
 24137 
 24138                       if (source)
 24139                         inev.ie.device = source->name;
 24140 
 24141                       goto xi_done_keysym;
 24142                     }
 24143 
 24144                   for (i = 0; i < nbytes; i++)
 24145                     {
 24146                       STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]);
 24147                     }
 24148 
 24149                   if (nbytes)
 24150                     {
 24151                       inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
 24152                       inev.ie.arg = make_unibyte_string (copy_bufptr, nbytes);
 24153 
 24154                       Fput_text_property (make_fixnum (0), make_fixnum (nbytes),
 24155                                           Qcoding, coding, inev.ie.arg);
 24156 
 24157                       if (source)
 24158                         inev.ie.device = source->name;
 24159                     }
 24160                   goto xi_done_keysym;
 24161                 }
 24162 
 24163               goto XI_OTHER;
 24164             }
 24165 
 24166 #if defined USE_GTK && !defined HAVE_GTK3
 24167           case XI_RawKeyPress:
 24168             {
 24169               XIRawEvent *raw_event = (XIRawEvent *) xi_event;
 24170 
 24171               /* This is the only way to attribute core keyboard
 24172                  events generated on GTK+ 2.x to the extension device
 24173                  that generated them.  */
 24174               dpyinfo->pending_keystroke_time = raw_event->time;
 24175               dpyinfo->pending_keystroke_source = raw_event->sourceid;
 24176               dpyinfo->pending_keystroke_time_special_p = true;
 24177               goto XI_OTHER;
 24178             }
 24179 #endif
 24180 
 24181           case XI_KeyRelease:
 24182 #if defined HAVE_X_I18N || defined USE_GTK || defined USE_LUCID
 24183             {
 24184               XKeyPressedEvent xkey;
 24185 
 24186               memset (&xkey, 0, sizeof xkey);
 24187 
 24188               xkey.type = KeyRelease;
 24189               xkey.serial = xev->serial;
 24190               xkey.send_event = xev->send_event;
 24191               xkey.display = dpyinfo->display;
 24192               xkey.window = xev->event;
 24193               xkey.root = xev->root;
 24194               xkey.subwindow = xev->child;
 24195               xkey.time = xev->time;
 24196               xkey.state = xi_convert_event_keyboard_state (xev);
 24197               xkey.x = lrint (xev->event_x);
 24198               xkey.y = lrint (xev->event_y);
 24199               xkey.x_root = lrint (xev->root_x);
 24200               xkey.y_root = lrint (xev->root_y);
 24201 
 24202               /* Some input methods react differently depending on the
 24203                  buttons that are pressed.  */
 24204               xi_convert_button_state (&xev->buttons, &xkey.state);
 24205 
 24206               xkey.keycode = xev->detail;
 24207               xkey.same_screen = True;
 24208 
 24209 #ifdef USE_LUCID
 24210               if (!popup_activated ())
 24211                 {
 24212 #endif
 24213 #ifdef HAVE_X_I18N
 24214                   if (x_filter_event (dpyinfo, (XEvent *) &xkey))
 24215                     *finish = X_EVENT_DROP;
 24216 #elif defined USE_GTK
 24217                   f = x_any_window_to_frame (xkey->event);
 24218 
 24219                   if (f && xg_filter_key (f, event))
 24220                     *finish = X_EVENT_DROP;
 24221 #endif
 24222 #ifdef USE_LUCID
 24223                 }
 24224               else
 24225                 {
 24226                   /* FIXME: the Lucid menu bar pops down upon any key
 24227                      release event, so we don't dispatch these events
 24228                      at all, which doesn't seem to be the right
 24229                      solution.
 24230 
 24231                      use_copy = true;
 24232                      copy.xkey = xkey; */
 24233                 }
 24234 #endif
 24235             }
 24236 #endif
 24237 
 24238             goto XI_OTHER;
 24239 
 24240           case XI_PropertyEvent:
 24241             goto XI_OTHER;
 24242 
 24243           case XI_HierarchyChanged:
 24244             {
 24245               XIHierarchyEvent *hev;
 24246               XIDeviceInfo *info;
 24247               int i, ndevices, n_disabled, *disabled;
 24248               struct xi_device_t *device;
 24249               bool any_changed;
 24250 
 24251               any_changed = false;
 24252               hev = (XIHierarchyEvent *) xi_event;
 24253               disabled = SAFE_ALLOCA (sizeof *disabled * hev->num_info);
 24254               n_disabled = 0;
 24255 
 24256               for (i = 0; i < hev->num_info; ++i)
 24257                 {
 24258                   if (hev->info[i].flags & XIDeviceEnabled)
 24259                     {
 24260                       /* Handle all disabled devices now, to prevent
 24261                          things happening out-of-order later.  */
 24262 
 24263                       if (n_disabled)
 24264                         {
 24265                           xi_disable_devices (dpyinfo, disabled, n_disabled);
 24266                           n_disabled = 0;
 24267 
 24268                           /* This flag really just means that disabled
 24269                              devices were handled early and should be
 24270                              used in conjunction with n_disabled.  */
 24271                           any_changed = true;
 24272                         }
 24273 
 24274                       /* Under unknown circumstances, multiple
 24275                          XIDeviceEnabled events are sent at once,
 24276                          causing the device to be duplicated.  Check
 24277                          that the device doesn't exist before adding
 24278                          it.  */
 24279 
 24280                       if (!xi_device_from_id (dpyinfo,
 24281                                               hev->info[i].deviceid))
 24282                         {
 24283                           x_catch_errors (dpyinfo->display);
 24284                           info = XIQueryDevice (dpyinfo->display,
 24285                                                 hev->info[i].deviceid,
 24286                                                 &ndevices);
 24287                           x_uncatch_errors ();
 24288 
 24289                           if (info && info->enabled)
 24290                             {
 24291                               dpyinfo->devices
 24292                                 = xrealloc (dpyinfo->devices,
 24293                                             (sizeof *dpyinfo->devices
 24294                                              * ++dpyinfo->num_devices));
 24295                               memset (dpyinfo->devices + dpyinfo->num_devices - 1,
 24296                                       0, sizeof *dpyinfo->devices);
 24297                               device = &dpyinfo->devices[dpyinfo->num_devices - 1];
 24298                               xi_populate_device_from_info (dpyinfo, device, info);
 24299                             }
 24300 
 24301                           if (info)
 24302                             XIFreeDeviceInfo (info);
 24303                         }
 24304                     }
 24305                   else if (hev->info[i].flags & XIDeviceDisabled)
 24306                     disabled[n_disabled++] = hev->info[i].deviceid;
 24307                   else if (hev->info[i].flags & XISlaveDetached
 24308                            || hev->info[i].flags & XISlaveAttached)
 24309                     {
 24310                       device = xi_device_from_id (dpyinfo, hev->info[i].deviceid);
 24311                       x_catch_errors (dpyinfo->display);
 24312                       info = XIQueryDevice (dpyinfo->display, hev->info[i].deviceid,
 24313                                             &ndevices);
 24314                       x_uncatch_errors ();
 24315 
 24316                       if (info)
 24317                         {
 24318                           if (device)
 24319                             {
 24320                               device->use = info->use;
 24321                               device->attachment = info->attachment;
 24322                             }
 24323 
 24324                           /* device could have been disabled by now.
 24325                              But instead of removing it immediately,
 24326                              wait for XIDeviceDisabled, or internal
 24327                              state could be left inconsistent.  */
 24328 
 24329                           XIFreeDeviceInfo (info);
 24330                         }
 24331                     }
 24332                 }
 24333 
 24334               /* Delete all devices that were disabled by this
 24335                  event.  */
 24336               xi_disable_devices (dpyinfo, disabled, n_disabled);
 24337 
 24338               /* If the device hierarchy has been changed, recompute
 24339                  focus.  This might seem like a micro-optimization but
 24340                  it actually keeps the focus from changing in some
 24341                  cases where it would be undesierable.  */
 24342               if (any_changed || n_disabled)
 24343                 xi_handle_focus_change (dpyinfo);
 24344 
 24345               goto XI_OTHER;
 24346             }
 24347 
 24348           case XI_DeviceChanged:
 24349             {
 24350               XIDeviceChangedEvent *device_changed;
 24351               struct xi_device_t *device;
 24352 
 24353               device_changed = (XIDeviceChangedEvent *) xi_event;
 24354               device = xi_device_from_id (dpyinfo, device_changed->deviceid);
 24355 
 24356               /* If the device isn't enabled, then stop handling this
 24357                  event.  A HierarchyChanged event will be sent if it
 24358                  is enabled afterwards.  */
 24359               if (!device)
 24360                 goto XI_OTHER;
 24361 
 24362               /* Now handle the event by retrieving scroll valuators
 24363                  and touch info.  */
 24364               xi_handle_device_changed (dpyinfo, device, device_changed);
 24365               goto XI_OTHER;
 24366             }
 24367 
 24368 #ifdef HAVE_XINPUT2_2
 24369           case XI_TouchBegin:
 24370             {
 24371               struct xi_device_t *device, *source;
 24372               bool menu_bar_p = false, tool_bar_p = false;
 24373 #ifdef HAVE_GTK3
 24374               GdkRectangle test_rect;
 24375 #endif
 24376               device = xi_device_from_id (dpyinfo, xev->deviceid);
 24377               source = xi_device_from_id (dpyinfo, xev->sourceid);
 24378               x_display_set_last_user_time (dpyinfo, xev->time,
 24379                                             xev->send_event, true);
 24380 
 24381               /* Don't process touch sequences from this device if
 24382                  it's a master pointer.  Touch sequences aren't
 24383                  canceled by the X server if a slave device is
 24384                  detached, and master pointers may also represent
 24385                  dependent touch devices.  */
 24386 
 24387               if (!device || device->use == XIMasterPointer)
 24388                 goto XI_OTHER;
 24389 
 24390               if (xi_find_touch_point (device, xev->detail))
 24391                 emacs_abort ();
 24392 
 24393               f = x_window_to_frame (dpyinfo, xev->event);
 24394 
 24395               if (f)
 24396                 /* See the comment above x_compute_root_window_offset
 24397                    for why this optimization is performed.  */
 24398                 xi_compute_root_window_offset (f, xev);
 24399 
 24400 #ifdef HAVE_GTK3
 24401               menu_bar_p = (f && FRAME_X_OUTPUT (f)->menubar_widget
 24402                             && xg_event_is_for_menubar (f, event));
 24403               if (f && FRAME_X_OUTPUT (f)->toolbar_widget)
 24404                 {
 24405                   int scale = xg_get_scale (f);
 24406 
 24407                   test_rect.x = xev->event_x / scale;
 24408                   test_rect.y = xev->event_y / scale;
 24409                   test_rect.width = 1;
 24410                   test_rect.height = 1;
 24411 
 24412                   tool_bar_p = gtk_widget_intersect (FRAME_X_OUTPUT (f)->toolbar_widget,
 24413                                                      &test_rect, NULL);
 24414                 }
 24415 #endif
 24416 
 24417 #ifndef HAVE_EXT_TOOL_BAR
 24418               /* Is this a touch from a direct touch device that is in
 24419                  the tool-bar?  */
 24420               if (device->direct_p
 24421                   && WINDOWP (f->tool_bar_window)
 24422                   && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
 24423                 {
 24424                   Lisp_Object window;
 24425                   int x = xev->event_x;
 24426                   int y = xev->event_y;
 24427 
 24428                   window = window_from_coordinates (f, x, y, 0, true, true);
 24429                   /* Ignore button release events if the mouse
 24430                      wasn't previously pressed on the tool bar.
 24431                      We do this because otherwise selecting some
 24432                      text with the mouse and then releasing it on
 24433                      the tool bar doesn't stop selecting text,
 24434                      since the tool bar eats the button up
 24435                      event.  */
 24436                   tool_bar_p = EQ (window, f->tool_bar_window);
 24437 
 24438                   /* If this touch has started in the tool bar, do not
 24439                      send it to Lisp.  Instead, simulate a tool bar
 24440                      click, releasing it once it goes away.  */
 24441 
 24442                   if (tool_bar_p)
 24443                     {
 24444                       /* Call note_mouse_highlight on the tool bar
 24445                          item.  Otherwise, get_tool_bar_item will
 24446                          return 1.
 24447 
 24448                          This is not necessary when mouse-highlight is
 24449                          nil.  */
 24450 
 24451                       if (!NILP (Vmouse_highlight))
 24452                         {
 24453                           note_mouse_highlight (f, x, y);
 24454 
 24455                           /* Always allow future mouse motion to
 24456                              update the mouse highlight, no matter
 24457                              where it is.  */
 24458                           memset (&dpyinfo->last_mouse_glyph, 0,
 24459                                   sizeof dpyinfo->last_mouse_glyph);
 24460                           dpyinfo->last_mouse_glyph_frame = f;
 24461                         }
 24462 
 24463                       handle_tool_bar_click_with_device (f, x, y, true, 0,
 24464                                                          (source
 24465                                                           ? source->name : Qt));
 24466 
 24467                       /* Flush any changes made by that to the front
 24468                          buffer.  */
 24469                       x_flush_dirty_back_buffer_on (f);
 24470 
 24471                       /* Record the device and the touch ID on the
 24472                          frame.  That way, Emacs knows when to dismiss
 24473                          the tool bar click later.  */
 24474 
 24475                       FRAME_OUTPUT_DATA (f)->tool_bar_touch_device
 24476                         = device->device_id;
 24477                       FRAME_OUTPUT_DATA (f)->tool_bar_touch_id = xev->detail;
 24478 
 24479                       goto XI_OTHER;
 24480                     }
 24481                 }
 24482 #endif
 24483 
 24484               if (!menu_bar_p && !tool_bar_p)
 24485                 {
 24486                   if (f && device->direct_p)
 24487                     {
 24488                       *finish = X_EVENT_DROP;
 24489 
 24490                       x_catch_errors (dpyinfo->display);
 24491 
 24492                       if (x_input_grab_touch_events)
 24493                         XIAllowTouchEvents (dpyinfo->display,
 24494                                             xev->deviceid,
 24495                                             xev->detail, xev->event,
 24496                                             XIAcceptTouch);
 24497 
 24498                       if (!x_had_errors_p (dpyinfo->display))
 24499                         {
 24500                           xi_link_touch_point (device, xev->detail,
 24501                                                xev->event_x,
 24502                                                xev->event_y, f);
 24503 
 24504                           inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT;
 24505                           inev.ie.timestamp = xev->time;
 24506                           XSETFRAME (inev.ie.frame_or_window, f);
 24507                           XSETINT (inev.ie.x, lrint (xev->event_x));
 24508                           XSETINT (inev.ie.y, lrint (xev->event_y));
 24509                           XSETINT (inev.ie.arg, xev->detail);
 24510 
 24511                           if (source)
 24512                             inev.ie.device = source->name;
 24513                         }
 24514 
 24515                       x_uncatch_errors ();
 24516                     }
 24517 #ifndef HAVE_GTK3
 24518                   else if (x_input_grab_touch_events)
 24519                     {
 24520                       x_ignore_errors_for_next_request (dpyinfo, 0);
 24521                       XIAllowTouchEvents (dpyinfo->display, xev->deviceid,
 24522                                           xev->detail, xev->event, XIRejectTouch);
 24523                       x_stop_ignoring_errors (dpyinfo);
 24524                     }
 24525 #endif
 24526                 }
 24527               else
 24528                 {
 24529 #ifdef HAVE_GTK3
 24530                   bool was_waiting_for_input = waiting_for_input;
 24531                   /* This hack was adopted from the NS port.  Whether
 24532                      or not it is actually safe is a different story
 24533                      altogether.  */
 24534                   if (waiting_for_input)
 24535                     waiting_for_input = 0;
 24536                   set_frame_menubar (f, true);
 24537                   waiting_for_input = was_waiting_for_input;
 24538 #endif
 24539                 }
 24540 
 24541               goto XI_OTHER;
 24542             }
 24543 
 24544           case XI_TouchOwnership:
 24545             {
 24546               struct xi_device_t *device;
 24547               struct xi_touch_point_t *touchpoint;
 24548               XITouchOwnershipEvent *event;
 24549 
 24550               /* All grabbing clients have decided to reject ownership
 24551                  of this touch sequence.  */
 24552 
 24553               event  = (XITouchOwnershipEvent *) xi_event;
 24554               device = xi_device_from_id (dpyinfo, event->deviceid);
 24555 
 24556               if (!device || device->use == XIMasterPointer)
 24557                 goto XI_OTHER;
 24558 
 24559               touchpoint = xi_find_touch_point (device, event->touchid);
 24560 
 24561               if (!touchpoint)
 24562                 goto XI_OTHER;
 24563 
 24564               /* As a result, Emacs should complete whatever editing
 24565                  operations result from this touch sequence.  */
 24566               touchpoint->ownership = TOUCH_OWNERSHIP_SELF;
 24567 
 24568               goto XI_OTHER;
 24569             }
 24570 
 24571           case XI_TouchUpdate:
 24572             {
 24573               struct xi_device_t *device, *source;
 24574               struct xi_touch_point_t *touchpoint;
 24575               Lisp_Object arg = Qnil;
 24576 
 24577               /* If flags & TouchPendingEnd, the touch sequence has
 24578                  already ended, but some grabbing clients remain
 24579                  undecided as to whether they will obtain ownership of
 24580                  the touch sequence.
 24581 
 24582                  Wait for them to make their decision, resulting in
 24583                  TouchOwnership and TouchEnd events being sent.  */
 24584 
 24585               if (xev->flags & XITouchPendingEnd)
 24586                 goto XI_OTHER;
 24587 
 24588               device = xi_device_from_id (dpyinfo, xev->deviceid);
 24589               source = xi_device_from_id (dpyinfo, xev->sourceid);
 24590               x_display_set_last_user_time (dpyinfo, xev->time,
 24591                                             xev->send_event, true);
 24592 
 24593               /* Don't process touch sequences from this device if
 24594                  it's a master pointer.  Touch sequences aren't
 24595                  canceled by the X server if a slave device is
 24596                  detached, and master pointers may also represent
 24597                  dependent touch devices.  */
 24598 
 24599               if (!device || device->use == XIMasterPointer)
 24600                 goto XI_OTHER;
 24601 
 24602               touchpoint = xi_find_touch_point (device, xev->detail);
 24603 
 24604               if (!touchpoint
 24605                   /* Don't send this event if nothing has changed
 24606                      either.  */
 24607                   || (touchpoint->x == lrint (xev->event_x)
 24608                       && touchpoint->y == lrint (xev->event_y)))
 24609                 goto XI_OTHER;
 24610 
 24611               touchpoint->x = lrint (xev->event_x);
 24612               touchpoint->y = lrint (xev->event_y);
 24613 
 24614               f = x_window_to_frame (dpyinfo, xev->event);
 24615 
 24616               if (f && device->direct_p)
 24617                 {
 24618                   inev.ie.kind = TOUCHSCREEN_UPDATE_EVENT;
 24619                   inev.ie.timestamp = xev->time;
 24620                   XSETFRAME (inev.ie.frame_or_window, f);
 24621 
 24622                   for (touchpoint = device->touchpoints;
 24623                        touchpoint; touchpoint = touchpoint->next)
 24624                     {
 24625                       if (touchpoint->frame == f)
 24626                         arg = Fcons (list3i (touchpoint->x, touchpoint->y,
 24627                                              lrint (touchpoint->number)),
 24628                                      arg);
 24629                     }
 24630 
 24631                   if (source)
 24632                     inev.ie.device = source->name;
 24633 
 24634                   inev.ie.arg = arg;
 24635                 }
 24636 
 24637               goto XI_OTHER;
 24638             }
 24639 
 24640           case XI_TouchEnd:
 24641             {
 24642               struct xi_device_t *device, *source;
 24643               int state;
 24644 
 24645               device = xi_device_from_id (dpyinfo, xev->deviceid);
 24646               source = xi_device_from_id (dpyinfo, xev->sourceid);
 24647               x_display_set_last_user_time (dpyinfo, xev->time,
 24648                                             xev->send_event, true);
 24649 
 24650               /* Don't process touch sequences from this device if
 24651                  it's a master pointer.  Touch sequences aren't
 24652                  canceled by the X server if a slave device is
 24653                  detached, and master pointers may also represent
 24654                  dependent touch devices.  */
 24655 
 24656               if (!device || device->use == XIMasterPointer)
 24657                 goto XI_OTHER;
 24658 
 24659               state = xi_unlink_touch_point (xev->detail, device);
 24660 
 24661               if (state)
 24662                 {
 24663                   f = x_window_to_frame (dpyinfo, xev->event);
 24664 
 24665                   if (f && device->direct_p)
 24666                     {
 24667                       inev.ie.kind = TOUCHSCREEN_END_EVENT;
 24668                       inev.ie.timestamp = xev->time;
 24669                       inev.ie.modifiers = state != 2;
 24670 
 24671                       XSETFRAME (inev.ie.frame_or_window, f);
 24672                       XSETINT (inev.ie.x, lrint (xev->event_x));
 24673                       XSETINT (inev.ie.y, lrint (xev->event_y));
 24674                       XSETINT (inev.ie.arg, xev->detail);
 24675 
 24676                       if (source)
 24677                         inev.ie.device = source->name;
 24678                     }
 24679                 }
 24680 
 24681 #ifndef HAVE_EXT_TOOL_BAR
 24682               /* Now see if the touchpoint was previously on the tool bar.
 24683                  If it was, release the tool bar.  */
 24684 
 24685               if (!f)
 24686                 f = x_window_to_frame (dpyinfo, xev->event);
 24687 
 24688               if (f && (FRAME_OUTPUT_DATA (f)->tool_bar_touch_id
 24689                         == xev->detail))
 24690                 {
 24691                   if (f->last_tool_bar_item != -1)
 24692                     handle_tool_bar_click_with_device (f, xev->event_x,
 24693                                                        xev->event_y,
 24694                                                        false, 0,
 24695                                                        (source
 24696                                                         ? source->name
 24697                                                         : Qnil));
 24698 
 24699                   /* Cancel any outstanding mouse highlight.  */
 24700                   note_mouse_highlight (f, -1, -1);
 24701                   x_flush_dirty_back_buffer_on (f);
 24702 
 24703                   /* Now clear the tool bar device.  */
 24704                   FRAME_OUTPUT_DATA (f)->tool_bar_touch_device = 0;
 24705                 }
 24706 #endif
 24707 
 24708               goto XI_OTHER;
 24709             }
 24710 
 24711 #endif
 24712 
 24713 #ifdef HAVE_XINPUT2_4
 24714           case XI_GesturePinchBegin:
 24715           case XI_GesturePinchUpdate:
 24716             {
 24717               XIGesturePinchEvent *pev = (XIGesturePinchEvent *) xi_event;
 24718               struct xi_device_t *device, *source;
 24719 
 24720               device = xi_device_from_id (dpyinfo, pev->deviceid);
 24721               source = xi_device_from_id (dpyinfo, pev->sourceid);
 24722               x_display_set_last_user_time (dpyinfo, pev->time,
 24723                                             pev->send_event, true);
 24724 
 24725               if (!device || device->use != XIMasterPointer)
 24726                 goto XI_OTHER;
 24727 
 24728 #ifdef HAVE_XWIDGETS
 24729               struct xwidget_view *xvw = xwidget_view_from_window (pev->event);
 24730 
 24731               if (xvw)
 24732                 {
 24733                   *finish = X_EVENT_DROP;
 24734                   xwidget_pinch (xvw, pev);
 24735                   goto XI_OTHER;
 24736                 }
 24737 #endif
 24738 
 24739               any = x_window_to_frame (dpyinfo, pev->event);
 24740 
 24741               if (any)
 24742                 {
 24743                   if (pev->event == FRAME_X_WINDOW (any))
 24744                     xi_compute_root_window_offset_pinch (any, pev);
 24745 
 24746                   inev.ie.kind = PINCH_EVENT;
 24747                   inev.ie.modifiers
 24748                     = x_x_to_emacs_modifiers (dpyinfo, pev->mods.effective);
 24749 
 24750                   XSETINT (inev.ie.x, lrint (pev->event_x));
 24751                   XSETINT (inev.ie.y, lrint (pev->event_y));
 24752                   XSETFRAME (inev.ie.frame_or_window, any);
 24753                   inev.ie.arg = list4 (make_float (pev->delta_x),
 24754                                        make_float (pev->delta_y),
 24755                                        make_float (pev->scale),
 24756                                        make_float (pev->delta_angle));
 24757 
 24758                   if (source)
 24759                     inev.ie.device = source->name;
 24760                 }
 24761 
 24762               /* Once again GTK seems to crash when confronted by
 24763                  events it doesn't understand.  */
 24764               *finish = X_EVENT_DROP;
 24765               goto XI_OTHER;
 24766             }
 24767 
 24768           case XI_GesturePinchEnd:
 24769             {
 24770 #if defined HAVE_XWIDGETS
 24771               XIGesturePinchEvent *pev = (XIGesturePinchEvent *) xi_event;
 24772               struct xwidget_view *xvw = xwidget_view_from_window (pev->event);
 24773 
 24774               if (xvw)
 24775                 xwidget_pinch (xvw, pev);
 24776 #endif
 24777               *finish = X_EVENT_DROP;
 24778               goto XI_OTHER;
 24779             }
 24780 #endif
 24781           default:
 24782             goto XI_OTHER;
 24783           }
 24784 
 24785       xi_done_keysym:
 24786 #ifdef HAVE_X_I18N
 24787       if (f)
 24788         {
 24789           struct window *w = XWINDOW (f->selected_window);
 24790           xic_set_preeditarea (w, w->cursor.x, w->cursor.y);
 24791 
 24792           if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
 24793             xic_set_statusarea (f);
 24794         }
 24795 #endif
 24796         if (must_free_data)
 24797           XFreeEventData (dpyinfo->display, &event->xcookie);
 24798         goto done_keysym;
 24799 
 24800       XI_OTHER:
 24801         if (must_free_data)
 24802           XFreeEventData (dpyinfo->display, &event->xcookie);
 24803         goto OTHER;
 24804       }
 24805 #endif
 24806 
 24807     default:
 24808 #ifdef HAVE_XKB
 24809       if (dpyinfo->supports_xkb
 24810           && event->type == dpyinfo->xkb_event_type)
 24811         {
 24812           XkbEvent *xkbevent = (XkbEvent *) event;
 24813 
 24814           if (xkbevent->any.xkb_type == XkbNewKeyboardNotify
 24815               || xkbevent->any.xkb_type == XkbMapNotify)
 24816             {
 24817               XkbRefreshKeyboardMapping (&xkbevent->map);
 24818 
 24819               if (dpyinfo->xkb_desc)
 24820                 {
 24821                   if (XkbGetUpdatedMap (dpyinfo->display,
 24822                                         (XkbKeySymsMask
 24823                                          | XkbKeyTypesMask
 24824                                          | XkbModifierMapMask
 24825                                          | XkbVirtualModsMask),
 24826                                         dpyinfo->xkb_desc) == Success)
 24827                     XkbGetNames (dpyinfo->display, XkbAllNamesMask,
 24828                                  dpyinfo->xkb_desc);
 24829                   else
 24830                     {
 24831                       XkbFreeKeyboard (dpyinfo->xkb_desc,
 24832                                        XkbAllComponentsMask, True);
 24833                       dpyinfo->xkb_desc = NULL;
 24834                     }
 24835                 }
 24836               else
 24837                 {
 24838                   dpyinfo->xkb_desc = XkbGetMap (dpyinfo->display,
 24839                                                  (XkbKeySymsMask
 24840                                                   | XkbKeyTypesMask
 24841                                                   | XkbModifierMapMask
 24842                                                   | XkbVirtualModsMask),
 24843                                                  XkbUseCoreKbd);
 24844 
 24845                   if (dpyinfo->xkb_desc)
 24846                     XkbGetNames (dpyinfo->display, XkbAllNamesMask,
 24847                                  dpyinfo->xkb_desc);
 24848                 }
 24849 
 24850               x_find_modifier_meanings (dpyinfo);
 24851             }
 24852           else if (x_dnd_in_progress
 24853                    && xkbevent->any.xkb_type == XkbStateNotify)
 24854             x_dnd_keyboard_state = (xkbevent->state.mods
 24855                                     | xkbevent->state.ptr_buttons);
 24856         }
 24857 #endif
 24858 #ifdef HAVE_XSHAPE
 24859       if (dpyinfo->xshape_supported_p
 24860           && event->type == dpyinfo->xshape_event_base + ShapeNotify
 24861           && x_dnd_in_progress && x_dnd_use_toplevels
 24862           && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
 24863         {
 24864 #ifndef USE_GTK
 24865           XEvent xevent;
 24866 #endif
 24867           XShapeEvent *xse = (XShapeEvent *) event;
 24868 #if defined HAVE_XCB_SHAPE && defined HAVE_XCB_SHAPE_INPUT_RECTS
 24869           xcb_shape_get_rectangles_cookie_t bounding_rect_cookie;
 24870           xcb_shape_get_rectangles_reply_t *bounding_rect_reply;
 24871           xcb_rectangle_iterator_t bounding_rect_iterator;
 24872 
 24873           xcb_shape_get_rectangles_cookie_t input_rect_cookie;
 24874           xcb_shape_get_rectangles_reply_t *input_rect_reply;
 24875           xcb_rectangle_iterator_t input_rect_iterator;
 24876 
 24877           xcb_generic_error_t *error;
 24878 #else
 24879           XRectangle *rects;
 24880           int rc, ordering;
 24881 #endif
 24882 
 24883           /* Somehow this really interferes with GTK's own processing
 24884              of ShapeNotify events.  Not sure what GTK uses them for,
 24885              but we cannot skip any of them here.  */
 24886 #ifndef USE_GTK
 24887           while (XPending (dpyinfo->display))
 24888             {
 24889               XNextEvent (dpyinfo->display, &xevent);
 24890 
 24891               if (xevent.type == dpyinfo->xshape_event_base + ShapeNotify
 24892                   && ((XShapeEvent *) &xevent)->window == xse->window)
 24893                 xse = (XShapeEvent *) &xevent;
 24894               else
 24895                 {
 24896                   XPutBackEvent (dpyinfo->display, &xevent);
 24897                   break;
 24898                 }
 24899             }
 24900 #endif
 24901 
 24902           for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
 24903                tem = tem->next)
 24904             {
 24905               if (tem->window == xse->window)
 24906                 {
 24907                   if (tem->n_input_rects != -1)
 24908                     xfree (tem->input_rects);
 24909                   if (tem->n_bounding_rects != -1)
 24910                     xfree (tem->bounding_rects);
 24911 
 24912                   tem->n_input_rects = -1;
 24913                   tem->n_bounding_rects = -1;
 24914 
 24915 #if defined HAVE_XCB_SHAPE && defined HAVE_XCB_SHAPE_INPUT_RECTS
 24916                   bounding_rect_cookie = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
 24917                                                                    (xcb_window_t) xse->window,
 24918                                                                    XCB_SHAPE_SK_BOUNDING);
 24919                   if (dpyinfo->xshape_major > 1
 24920                       || (dpyinfo->xshape_major == 1
 24921                           && dpyinfo->xshape_minor >= 1))
 24922                     input_rect_cookie
 24923                       = xcb_shape_get_rectangles (dpyinfo->xcb_connection,
 24924                                                   (xcb_window_t) xse->window,
 24925                                                   XCB_SHAPE_SK_INPUT);
 24926 
 24927                   bounding_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
 24928                                                                         bounding_rect_cookie,
 24929                                                                         &error);
 24930 
 24931                   if (bounding_rect_reply)
 24932                     {
 24933                       bounding_rect_iterator
 24934                         = xcb_shape_get_rectangles_rectangles_iterator (bounding_rect_reply);
 24935                       tem->n_bounding_rects = bounding_rect_iterator.rem + 1;
 24936                       tem->bounding_rects = xmalloc (tem->n_bounding_rects
 24937                                                      * sizeof *tem->bounding_rects);
 24938                       tem->n_bounding_rects = 0;
 24939 
 24940                       for (; bounding_rect_iterator.rem; xcb_rectangle_next (&bounding_rect_iterator))
 24941                         {
 24942                           tem->bounding_rects[tem->n_bounding_rects].x
 24943                             = bounding_rect_iterator.data->x;
 24944                           tem->bounding_rects[tem->n_bounding_rects].y
 24945                             = bounding_rect_iterator.data->y;
 24946                           tem->bounding_rects[tem->n_bounding_rects].width
 24947                             = bounding_rect_iterator.data->width;
 24948                           tem->bounding_rects[tem->n_bounding_rects].height
 24949                             = bounding_rect_iterator.data->height;
 24950 
 24951                           tem->n_bounding_rects++;
 24952                         }
 24953 
 24954                       free (bounding_rect_reply);
 24955                     }
 24956                   else
 24957                     free (error);
 24958 
 24959                   if (dpyinfo->xshape_major > 1
 24960                       || (dpyinfo->xshape_major == 1
 24961                           && dpyinfo->xshape_minor >= 1))
 24962                     {
 24963                       input_rect_reply = xcb_shape_get_rectangles_reply (dpyinfo->xcb_connection,
 24964                                                                          input_rect_cookie, &error);
 24965 
 24966                       if (input_rect_reply)
 24967                         {
 24968                           input_rect_iterator
 24969                             = xcb_shape_get_rectangles_rectangles_iterator (input_rect_reply);
 24970                           tem->n_input_rects = input_rect_iterator.rem + 1;
 24971                           tem->input_rects = xmalloc (tem->n_input_rects
 24972                                                       * sizeof *tem->input_rects);
 24973                           tem->n_input_rects = 0;
 24974 
 24975                           for (; input_rect_iterator.rem; xcb_rectangle_next (&input_rect_iterator))
 24976                             {
 24977                               tem->input_rects[tem->n_input_rects].x
 24978                                 = input_rect_iterator.data->x;
 24979                               tem->input_rects[tem->n_input_rects].y
 24980                                 = input_rect_iterator.data->y;
 24981                               tem->input_rects[tem->n_input_rects].width
 24982                                 = input_rect_iterator.data->width;
 24983                               tem->input_rects[tem->n_input_rects].height
 24984                                 = input_rect_iterator.data->height;
 24985 
 24986                               tem->n_input_rects++;
 24987                             }
 24988 
 24989                           free (input_rect_reply);
 24990                         }
 24991                       else
 24992                         free (error);
 24993                     }
 24994 #else
 24995                   x_catch_errors (dpyinfo->display);
 24996                   rects = XShapeGetRectangles (dpyinfo->display,
 24997                                                xse->window,
 24998                                                ShapeBounding,
 24999                                                &count, &ordering);
 25000                   rc = x_had_errors_p (dpyinfo->display);
 25001                   x_uncatch_errors_after_check ();
 25002 
 25003                   /* Does XShapeGetRectangles allocate anything upon an
 25004                      error?  */
 25005                   if (!rc)
 25006                     {
 25007                       tem->n_bounding_rects = count;
 25008                       tem->bounding_rects
 25009                         = xmalloc (sizeof *tem->bounding_rects * count);
 25010                       memcpy (tem->bounding_rects, rects,
 25011                               sizeof *tem->bounding_rects * count);
 25012 
 25013                       XFree (rects);
 25014                     }
 25015 
 25016 #ifdef ShapeInput
 25017                   if (dpyinfo->xshape_major > 1
 25018                       || (dpyinfo->xshape_major == 1
 25019                           && dpyinfo->xshape_minor >= 1))
 25020                     {
 25021                       x_catch_errors (dpyinfo->display);
 25022                       rects = XShapeGetRectangles (dpyinfo->display,
 25023                                                    xse->window, ShapeInput,
 25024                                                    &count, &ordering);
 25025                       rc = x_had_errors_p (dpyinfo->display);
 25026                       x_uncatch_errors_after_check ();
 25027 
 25028                       /* Does XShapeGetRectangles allocate anything upon
 25029                          an error?  */
 25030                       if (!rc)
 25031                         {
 25032                           tem->n_input_rects = count;
 25033                           tem->input_rects
 25034                             = xmalloc (sizeof *tem->input_rects * count);
 25035                           memcpy (tem->input_rects, rects,
 25036                                   sizeof *tem->input_rects * count);
 25037 
 25038                           XFree (rects);
 25039                         }
 25040                     }
 25041 #endif
 25042 #endif
 25043 
 25044                   /* Handle the common case where the input shape equals the
 25045                      bounding shape.  */
 25046 
 25047                   if (tem->n_input_rects != -1
 25048                       && tem->n_bounding_rects == tem->n_input_rects
 25049                       && !memcmp (tem->bounding_rects, tem->input_rects,
 25050                                   tem->n_input_rects * sizeof *tem->input_rects))
 25051                     {
 25052                       xfree (tem->input_rects);
 25053                       tem->n_input_rects = -1;
 25054                     }
 25055 
 25056                   /* And the common case where there is no input rect and the
 25057                      bounding rect equals the window dimensions.  */
 25058 
 25059                   if (tem->n_input_rects == -1
 25060                       && tem->n_bounding_rects == 1
 25061                       && tem->bounding_rects[0].width == tem->width
 25062                       && tem->bounding_rects[0].height == tem->height
 25063                       && tem->bounding_rects[0].x == -tem->border_width
 25064                       && tem->bounding_rects[0].y == -tem->border_width)
 25065                     {
 25066                       xfree (tem->bounding_rects);
 25067                       tem->n_bounding_rects = -1;
 25068                     }
 25069 
 25070                   break;
 25071                 }
 25072             }
 25073         }
 25074 #endif
 25075 #if defined HAVE_XRANDR && !defined USE_GTK
 25076       if (dpyinfo->xrandr_supported_p
 25077           && (event->type == (dpyinfo->xrandr_event_base
 25078                               + RRScreenChangeNotify)
 25079               || event->type == (dpyinfo->xrandr_event_base
 25080                                  + RRNotify)))
 25081         {
 25082           Time timestamp;
 25083           Lisp_Object current_monitors;
 25084           XRRScreenChangeNotifyEvent *notify;
 25085 
 25086           if (event->type == (dpyinfo->xrandr_event_base
 25087                               + RRScreenChangeNotify))
 25088             XRRUpdateConfiguration ((XEvent *) event);
 25089 
 25090           if (event->type == (dpyinfo->xrandr_event_base
 25091                               + RRScreenChangeNotify))
 25092             {
 25093               notify = ((XRRScreenChangeNotifyEvent *) event);
 25094               timestamp = notify->timestamp;
 25095 
 25096               /* Don't set screen dimensions if the notification is
 25097                  for a different screen.  */
 25098               if (notify->root == dpyinfo->root_window)
 25099                 {
 25100                   dpyinfo->screen_width = notify->width;
 25101                   dpyinfo->screen_height = notify->height;
 25102                   dpyinfo->screen_mm_width = notify->mwidth;
 25103                   dpyinfo->screen_mm_height = notify->mheight;
 25104                 }
 25105             }
 25106           else
 25107             timestamp = 0;
 25108 
 25109           if (x_find_monitors_changed_event (dpyinfo))
 25110             /* Don't store a MONITORS_CHANGED_EVENT if there is
 25111                already an undelivered event on the queue.  */
 25112             goto OTHER;
 25113 
 25114           inev.ie.kind = MONITORS_CHANGED_EVENT;
 25115           inev.ie.timestamp = timestamp;
 25116           XSETTERMINAL (inev.ie.arg, dpyinfo->terminal);
 25117 
 25118           /* Also don't do anything if the monitor configuration
 25119              didn't really change.  */
 25120 
 25121           current_monitors
 25122             = Fx_display_monitor_attributes_list (inev.ie.arg);
 25123 
 25124           if (!NILP (Fequal (current_monitors,
 25125                              dpyinfo->last_monitor_attributes_list)))
 25126             inev.ie.kind = NO_EVENT;
 25127 
 25128           dpyinfo->last_monitor_attributes_list = current_monitors;
 25129 
 25130           if (x_dnd_in_progress && x_dnd_update_tooltip)
 25131             x_dnd_monitors = current_monitors;
 25132 
 25133           if (inev.ie.kind != NO_EVENT)
 25134             x_dnd_update_tooltip_now ();
 25135         }
 25136 #endif
 25137 #ifdef HAVE_XFIXES
 25138       if (dpyinfo->xfixes_supported_p
 25139           && event->type == (dpyinfo->xfixes_event_base
 25140                              + XFixesSelectionNotify)
 25141           && x_handle_selection_monitor_event (dpyinfo, event))
 25142         /* GTK 3 crashes if an XFixesSelectionNotify arrives with a
 25143            window other than the root window, because it wants to know
 25144            the screen in order to determine the compositing manager
 25145            selection name.  (bug#58584) */
 25146         *finish = X_EVENT_DROP;
 25147 #endif
 25148     OTHER:
 25149 #ifdef USE_X_TOOLKIT
 25150       if (*finish != X_EVENT_DROP)
 25151         {
 25152           /* Ignore some obviously bogus ConfigureNotify events that
 25153              other clients have been known to send Emacs.
 25154              (bug#54051) */
 25155           if (event->type != ConfigureNotify
 25156               || (event->xconfigure.width != 0
 25157                   && event->xconfigure.height != 0))
 25158             {
 25159 #if defined USE_X_TOOLKIT && defined HAVE_XINPUT2
 25160               XtDispatchEvent (use_copy ? &copy : (XEvent *) event);
 25161 #else
 25162               XtDispatchEvent ((XEvent *) event);
 25163 #endif
 25164             }
 25165         }
 25166 #endif /* USE_X_TOOLKIT */
 25167 #if defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
 25168       if (*finish != X_EVENT_DROP && copy)
 25169         {
 25170           gtk_main_do_event (copy);
 25171           *finish = X_EVENT_DROP;
 25172         }
 25173 
 25174       if (copy)
 25175         gdk_event_free (copy);
 25176 #endif
 25177     break;
 25178     }
 25179 
 25180  done:
 25181   if (inev.ie.kind != NO_EVENT)
 25182     {
 25183       kbd_buffer_store_buffered_event (&inev, hold_quit);
 25184       count++;
 25185     }
 25186 
 25187   if (do_help
 25188       && !(hold_quit && hold_quit->kind != NO_EVENT))
 25189     {
 25190       Lisp_Object frame;
 25191 
 25192       if (f)
 25193         XSETFRAME (frame, f);
 25194       else
 25195         frame = Qnil;
 25196 
 25197       if (do_help > 0)
 25198         {
 25199           any_help_event_p = true;
 25200 #ifdef HAVE_XINPUT2
 25201           if (gen_help_device)
 25202             xi_handle_interaction (dpyinfo, f,
 25203                                    gen_help_device,
 25204                                    gen_help_time);
 25205 #endif
 25206           gen_help_event (help_echo_string, frame, help_echo_window,
 25207                           help_echo_object, help_echo_pos);
 25208         }
 25209       else
 25210         {
 25211           help_echo_string = Qnil;
 25212           gen_help_event (Qnil, frame, Qnil, Qnil, 0);
 25213         }
 25214       count++;
 25215     }
 25216 
 25217 #if defined HAVE_XINPUT2 || defined HAVE_XKB || defined HAVE_X_I18N
 25218   SAFE_FREE ();
 25219 #endif
 25220 
 25221   return count;
 25222 }
 25223 
 25224 /* Handles the XEvent EVENT on display DISPLAY.
 25225    This is used for event loops outside the normal event handling,
 25226    i.e. looping while a popup menu or a dialog is posted.
 25227 
 25228    Returns the value handle_one_xevent sets in the finish argument.  */
 25229 
 25230 #ifdef USE_GTK
 25231 static int
 25232 #else
 25233 int
 25234 #endif
 25235 x_dispatch_event (XEvent *event, Display *display)
 25236 {
 25237   struct x_display_info *dpyinfo;
 25238   int finish = X_EVENT_NORMAL;
 25239 
 25240   dpyinfo = x_display_info_for_display (display);
 25241 
 25242   if (dpyinfo)
 25243     {
 25244       /* Block input before calling x_dispatch_event.  */
 25245       block_input ();
 25246       handle_one_xevent (dpyinfo, event, &finish, 0);
 25247       unblock_input ();
 25248     }
 25249 
 25250   return finish;
 25251 }
 25252 
 25253 /* Read events coming from the X server.
 25254    Return as soon as there are no more events to be read.
 25255 
 25256    Return the number of characters stored into the buffer,
 25257    thus pretending to be `read' (except the characters we store
 25258    in the keyboard buffer can be multibyte, so are not necessarily
 25259    C chars).  */
 25260 
 25261 static int
 25262 XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
 25263 {
 25264   int count = 0;
 25265   bool event_found = false;
 25266   struct x_display_info *dpyinfo = terminal->display_info.x;
 25267 
 25268   /* Don't allow XTread_socket to do anything if drag-and-drop is in
 25269      progress.  If unblock_input causes XTread_socket to be called and
 25270      read X events while the drag-and-drop event loop is in progress,
 25271      things can go wrong very quick.
 25272 
 25273      When x_dnd_unwind_flag is true, the above doesn't apply, since
 25274      the surrounding code takes special precautions to keep it safe.
 25275 
 25276      That doesn't matter for events from displays other than the
 25277      display of the drag-and-drop operation, though.  */
 25278   if (!x_dnd_unwind_flag
 25279       && ((x_dnd_in_progress
 25280            && dpyinfo->display == FRAME_X_DISPLAY (x_dnd_frame))
 25281           || (x_dnd_waiting_for_finish
 25282               && dpyinfo->display == x_dnd_finish_display)))
 25283     return 0;
 25284 
 25285   x_clean_failable_requests (dpyinfo);
 25286 
 25287   block_input ();
 25288 
 25289   /* For debugging, this gives a way to fake an I/O error.  */
 25290   if (dpyinfo == XTread_socket_fake_io_error)
 25291     {
 25292       XTread_socket_fake_io_error = 0;
 25293       x_io_error_quitter (dpyinfo->display);
 25294     }
 25295 
 25296 #ifndef USE_GTK
 25297   while (XPending (dpyinfo->display))
 25298     {
 25299       int finish;
 25300       XEvent event;
 25301 
 25302       XNextEvent (dpyinfo->display, &event);
 25303 
 25304 #ifdef HAVE_X_I18N
 25305       /* Filter events for the current X input method.  */
 25306 #ifdef HAVE_XINPUT2
 25307       if (event.type != GenericEvent
 25308           || !dpyinfo->supports_xi2
 25309           || event.xgeneric.extension != dpyinfo->xi2_opcode)
 25310         {
 25311           /* Input extension key events are filtered inside
 25312              handle_one_xevent.  */
 25313 #endif
 25314           if (x_filter_event (dpyinfo, &event))
 25315             continue;
 25316 #ifdef HAVE_XINPUT2
 25317         }
 25318 #endif
 25319 #endif
 25320       event_found = true;
 25321 
 25322       count += handle_one_xevent (dpyinfo, &event, &finish, hold_quit);
 25323 
 25324       if (finish == X_EVENT_GOTO_OUT)
 25325         break;
 25326     }
 25327 
 25328 #else /* USE_GTK */
 25329 
 25330   /* For GTK we must use the GTK event loop.  But XEvents gets passed
 25331      to our filter function above, and then to the big event switch.
 25332      We use a bunch of globals to communicate with our filter function,
 25333      that is kind of ugly, but it works.
 25334 
 25335      There is no way to do one display at the time, GTK just does events
 25336      from all displays.  */
 25337 
 25338   while (gtk_events_pending ())
 25339     {
 25340       current_count = count;
 25341       current_hold_quit = hold_quit;
 25342 
 25343       gtk_main_iteration ();
 25344 
 25345       count = current_count;
 25346       current_count = -1;
 25347       current_hold_quit = 0;
 25348 
 25349       if (current_finish == X_EVENT_GOTO_OUT)
 25350         break;
 25351     }
 25352 
 25353   /* Now see if `xg_pending_quit_event' was set.  */
 25354   if (xg_pending_quit_event.kind != NO_EVENT)
 25355     {
 25356       /* Check that the frame is still valid.  It could have been
 25357          deleted between now and the time the event was recorded.  */
 25358       if (FRAME_LIVE_P (XFRAME (xg_pending_quit_event.frame_or_window)))
 25359         /* Store that event into hold_quit and clear the pending quit
 25360            event.  */
 25361         *hold_quit = xg_pending_quit_event;
 25362 
 25363       /* If the frame is invalid, just clear the event as well.  */
 25364       xg_pending_quit_event.kind = NO_EVENT;
 25365     }
 25366 #endif /* USE_GTK */
 25367 
 25368   /* On some systems, an X bug causes Emacs to get no more events
 25369      when the window is destroyed.  Detect that.  (1994.)  */
 25370   if (! event_found)
 25371     {
 25372       /* Emacs and the X Server eats up CPU time if XNoOp is done every time.
 25373          One XNOOP in 100 loops will make Emacs terminate.
 25374          B. Bretthauer, 1994 */
 25375       x_noop_count++;
 25376       if (x_noop_count >= 100)
 25377         {
 25378           x_noop_count=0;
 25379 
 25380           if (next_noop_dpyinfo == 0)
 25381             next_noop_dpyinfo = x_display_list;
 25382 
 25383           XNoOp (next_noop_dpyinfo->display);
 25384 
 25385           /* Each time we get here, cycle through the displays now open.  */
 25386           next_noop_dpyinfo = next_noop_dpyinfo->next;
 25387         }
 25388     }
 25389 
 25390   /* If the focus was just given to an auto-raising frame,
 25391      raise it now.  FIXME: handle more than one such frame.  */
 25392   if (dpyinfo->x_pending_autoraise_frame)
 25393     {
 25394       x_raise_frame (dpyinfo->x_pending_autoraise_frame);
 25395       dpyinfo->x_pending_autoraise_frame = NULL;
 25396     }
 25397 
 25398   unblock_input ();
 25399 
 25400   return count;
 25401 }
 25402 
 25403 
 25404 
 25405 
 25406 /***********************************************************************
 25407                              Text Cursor
 25408  ***********************************************************************/
 25409 
 25410 /* Set clipping for output in glyph row ROW.  W is the window in which
 25411    we operate.  GC is the graphics context to set clipping in.
 25412 
 25413    ROW may be a text row or, e.g., a mode line.  Text rows must be
 25414    clipped to the interior of the window dedicated to text display,
 25415    mode lines must be clipped to the whole window.  */
 25416 
 25417 static void
 25418 x_clip_to_row (struct window *w, struct glyph_row *row,
 25419                enum glyph_row_area area, GC gc)
 25420 {
 25421   struct frame *f = XFRAME (WINDOW_FRAME (w));
 25422   XRectangle clip_rect;
 25423   int window_x, window_y, window_width;
 25424 
 25425   window_box (w, area, &window_x, &window_y, &window_width, 0);
 25426 
 25427   clip_rect.x = window_x;
 25428   clip_rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
 25429   clip_rect.y = max (clip_rect.y, window_y);
 25430   clip_rect.width = window_width;
 25431   clip_rect.height = row->visible_height;
 25432 
 25433   x_set_clip_rectangles (f, gc, &clip_rect, 1);
 25434 }
 25435 
 25436 
 25437 /* Draw a hollow box cursor on window W in glyph row ROW.  */
 25438 
 25439 static void
 25440 x_draw_hollow_cursor (struct window *w, struct glyph_row *row)
 25441 {
 25442   struct frame *f = XFRAME (WINDOW_FRAME (w));
 25443   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 25444   Display *dpy = FRAME_X_DISPLAY (f);
 25445   int x, y, wd, h;
 25446   XGCValues xgcv;
 25447   struct glyph *cursor_glyph;
 25448   GC gc;
 25449 
 25450   /* Get the glyph the cursor is on.  If we can't tell because
 25451      the current matrix is invalid or such, give up.  */
 25452   cursor_glyph = get_phys_cursor_glyph (w);
 25453   if (cursor_glyph == NULL)
 25454     return;
 25455 
 25456   /* Compute frame-relative coordinates for phys cursor.  */
 25457   get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
 25458   wd = w->phys_cursor_width - 1;
 25459 
 25460   /* The foreground of cursor_gc is typically the same as the normal
 25461      background color, which can cause the cursor box to be invisible.  */
 25462   xgcv.foreground = f->output_data.x->cursor_pixel;
 25463   xgcv.line_width = 1;
 25464   if (dpyinfo->scratch_cursor_gc)
 25465     XChangeGC (dpy, dpyinfo->scratch_cursor_gc, GCForeground | GCLineWidth, &xgcv);
 25466   else
 25467     dpyinfo->scratch_cursor_gc = XCreateGC (dpy, FRAME_X_DRAWABLE (f),
 25468                                             GCForeground | GCLineWidth, &xgcv);
 25469   gc = dpyinfo->scratch_cursor_gc;
 25470 
 25471   /* When on R2L character, show cursor at the right edge of the
 25472      glyph, unless the cursor box is as wide as the glyph or wider
 25473      (the latter happens when x-stretch-cursor is non-nil).  */
 25474   if ((cursor_glyph->resolved_level & 1) != 0
 25475       && cursor_glyph->pixel_width > wd)
 25476     {
 25477       x += cursor_glyph->pixel_width - wd;
 25478       if (wd > 0)
 25479         wd -= 1;
 25480     }
 25481   /* Set clipping, draw the rectangle, and reset clipping again.  */
 25482   x_clip_to_row (w, row, TEXT_AREA, gc);
 25483   x_draw_rectangle (f, gc, x, y, wd, h - 1);
 25484   x_reset_clip_rectangles (f, gc);
 25485 }
 25486 
 25487 
 25488 /* Draw a bar cursor on window W in glyph row ROW.
 25489 
 25490    Implementation note: One would like to draw a bar cursor with an
 25491    angle equal to the one given by the font property XA_ITALIC_ANGLE.
 25492    Unfortunately, I didn't find a font yet that has this property set.
 25493    --gerd.  */
 25494 
 25495 static void
 25496 x_draw_bar_cursor (struct window *w, struct glyph_row *row, int width, enum text_cursor_kinds kind)
 25497 {
 25498   struct frame *f = XFRAME (w->frame);
 25499   struct glyph *cursor_glyph;
 25500 
 25501   /* If cursor is out of bounds, don't draw garbage.  This can happen
 25502      in mini-buffer windows when switching between echo area glyphs
 25503      and mini-buffer.  */
 25504   cursor_glyph = get_phys_cursor_glyph (w);
 25505   if (cursor_glyph == NULL)
 25506     return;
 25507 
 25508   /* Experimental avoidance of cursor on xwidget.  */
 25509   if (cursor_glyph->type == XWIDGET_GLYPH)
 25510     return;
 25511 
 25512   /* If on an image, draw like a normal cursor.  That's usually better
 25513      visible than drawing a bar, esp. if the image is large so that
 25514      the bar might not be in the window.  */
 25515   if (cursor_glyph->type == IMAGE_GLYPH)
 25516     {
 25517       struct glyph_row *r;
 25518       r = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
 25519       draw_phys_cursor_glyph (w, r, DRAW_CURSOR);
 25520     }
 25521   else
 25522     {
 25523       Display *dpy = FRAME_X_DISPLAY (f);
 25524       Drawable drawable = FRAME_X_DRAWABLE (f);
 25525       GC gc = FRAME_DISPLAY_INFO (f)->scratch_cursor_gc;
 25526       unsigned long mask = GCForeground | GCBackground | GCGraphicsExposures;
 25527       struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
 25528       XGCValues xgcv;
 25529 
 25530       /* If the glyph's background equals the color we normally draw
 25531          the bars cursor in, the bar cursor in its normal color is
 25532          invisible.  Use the glyph's foreground color instead in this
 25533          case, on the assumption that the glyph's colors are chosen so
 25534          that the glyph is legible.  */
 25535       if (face->background == f->output_data.x->cursor_pixel)
 25536         xgcv.background = xgcv.foreground = face->foreground;
 25537       else
 25538         xgcv.background = xgcv.foreground = f->output_data.x->cursor_pixel;
 25539       xgcv.graphics_exposures = False;
 25540       xgcv.line_width = 1;
 25541 
 25542       mask |= GCLineWidth;
 25543 
 25544       if (gc)
 25545         XChangeGC (dpy, gc, mask, &xgcv);
 25546       else
 25547         {
 25548           gc = XCreateGC (dpy, drawable, mask, &xgcv);
 25549           FRAME_DISPLAY_INFO (f)->scratch_cursor_gc = gc;
 25550         }
 25551 
 25552       x_clip_to_row (w, row, TEXT_AREA, gc);
 25553 
 25554       if (kind == BAR_CURSOR)
 25555         {
 25556           int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
 25557 
 25558           if (width < 0)
 25559             width = FRAME_CURSOR_WIDTH (f);
 25560           width = min (cursor_glyph->pixel_width, width);
 25561 
 25562           w->phys_cursor_width = width;
 25563 
 25564           /* If the character under cursor is R2L, draw the bar cursor
 25565              on the right of its glyph, rather than on the left.  */
 25566           if ((cursor_glyph->resolved_level & 1) != 0)
 25567             x += cursor_glyph->pixel_width - width;
 25568 
 25569           x_fill_rectangle (f, gc, x,
 25570                             WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
 25571                             width, row->height, false);
 25572         }
 25573       else /* HBAR_CURSOR */
 25574         {
 25575           int dummy_x, dummy_y, dummy_h;
 25576           int x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
 25577 
 25578           if (width < 0)
 25579             width = row->height;
 25580 
 25581           width = min (row->height, width);
 25582 
 25583           get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
 25584                                     &dummy_y, &dummy_h);
 25585 
 25586           if ((cursor_glyph->resolved_level & 1) != 0
 25587               && cursor_glyph->pixel_width > w->phys_cursor_width - 1)
 25588             x += cursor_glyph->pixel_width - w->phys_cursor_width + 1;
 25589           x_fill_rectangle (f, gc, x,
 25590                             WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
 25591                                                      row->height - width),
 25592                             w->phys_cursor_width - 1, width, false);
 25593         }
 25594 
 25595       x_reset_clip_rectangles (f, gc);
 25596     }
 25597 }
 25598 
 25599 
 25600 /* RIF: Define cursor CURSOR on frame F.  */
 25601 
 25602 static void
 25603 x_define_frame_cursor (struct frame *f, Emacs_Cursor cursor)
 25604 {
 25605   if (!f->pointer_invisible
 25606       && f->output_data.x->current_cursor != cursor)
 25607     XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
 25608   f->output_data.x->current_cursor = cursor;
 25609 }
 25610 
 25611 
 25612 /* RIF: Clear area on frame F.  */
 25613 
 25614 static void
 25615 x_clear_frame_area (struct frame *f, int x, int y, int width, int height)
 25616 {
 25617   x_clear_area (f, x, y, width, height);
 25618 }
 25619 
 25620 
 25621 /* RIF: Draw cursor on window W.  */
 25622 
 25623 static void
 25624 x_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x,
 25625                       int y, enum text_cursor_kinds cursor_type,
 25626                       int cursor_width, bool on_p, bool active_p)
 25627 {
 25628 #ifdef HAVE_X_I18N
 25629   struct frame *f = XFRAME (WINDOW_FRAME (w));
 25630 #endif
 25631 
 25632   if (on_p)
 25633     {
 25634       w->phys_cursor_type = cursor_type;
 25635       w->phys_cursor_on_p = true;
 25636 
 25637       if (glyph_row->exact_window_width_line_p
 25638           && (glyph_row->reversed_p
 25639               ? (w->phys_cursor.hpos < 0)
 25640               : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
 25641         {
 25642           glyph_row->cursor_in_fringe_p = true;
 25643           draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
 25644         }
 25645       else
 25646         {
 25647           switch (cursor_type)
 25648             {
 25649             case HOLLOW_BOX_CURSOR:
 25650               x_draw_hollow_cursor (w, glyph_row);
 25651               break;
 25652 
 25653             case FILLED_BOX_CURSOR:
 25654               draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
 25655               break;
 25656 
 25657             case BAR_CURSOR:
 25658               x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
 25659               break;
 25660 
 25661             case HBAR_CURSOR:
 25662               x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
 25663               break;
 25664 
 25665             case NO_CURSOR:
 25666               w->phys_cursor_width = 0;
 25667               break;
 25668 
 25669             default:
 25670               emacs_abort ();
 25671             }
 25672         }
 25673 
 25674 #ifdef HAVE_X_I18N
 25675       if (w == XWINDOW (f->selected_window))
 25676         xic_set_preeditarea (w, x, y);
 25677 #endif
 25678     }
 25679 }
 25680 
 25681 
 25682 /* Icons.  */
 25683 
 25684 /* Make the x-window of frame F use the gnu icon bitmap.  */
 25685 
 25686 static bool
 25687 x_bitmap_icon (struct frame *f, Lisp_Object file)
 25688 {
 25689   ptrdiff_t bitmap_id;
 25690 
 25691   if (FRAME_X_WINDOW (f) == 0)
 25692     return true;
 25693 
 25694   /* Free up our existing icon bitmap and mask if any.  */
 25695   if (f->output_data.x->icon_bitmap > 0)
 25696     image_destroy_bitmap (f, f->output_data.x->icon_bitmap);
 25697   f->output_data.x->icon_bitmap = 0;
 25698 
 25699   if (STRINGP (file))
 25700     {
 25701 #ifdef USE_GTK
 25702       /* Use gtk_window_set_icon_from_file () if available,
 25703          It's not restricted to bitmaps */
 25704       if (xg_set_icon (f, file))
 25705         return false;
 25706 #endif /* USE_GTK */
 25707       bitmap_id = image_create_bitmap_from_file (f, file);
 25708       x_create_bitmap_mask (f, bitmap_id);
 25709     }
 25710   else
 25711     {
 25712       /* Create the GNU bitmap and mask if necessary.  */
 25713       if (FRAME_DISPLAY_INFO (f)->icon_bitmap_id < 0)
 25714         {
 25715           ptrdiff_t rc = -1;
 25716 
 25717 #ifdef USE_GTK
 25718 
 25719           if (xg_set_icon (f, xg_default_icon_file)
 25720               || xg_set_icon_from_xpm_data (f, gnu_xpm_bits))
 25721             {
 25722               FRAME_DISPLAY_INFO (f)->icon_bitmap_id = -2;
 25723               return false;
 25724             }
 25725 
 25726 #elif defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
 25727           /* This allocates too many colors.  */
 25728           if ((FRAME_X_VISUAL_INFO (f)->class == TrueColor
 25729                || FRAME_X_VISUAL_INFO (f)->class == StaticColor
 25730                || FRAME_X_VISUAL_INFO (f)->class == StaticGray)
 25731               /* That pixmap needs about 240 colors, and we should
 25732                  also leave some more space for other colors as
 25733                  well.  */
 25734               || FRAME_X_VISUAL_INFO (f)->colormap_size >= (240 * 4))
 25735             {
 25736               rc = x_create_bitmap_from_xpm_data (f, gnu_xpm_bits);
 25737               if (rc != -1)
 25738                 FRAME_DISPLAY_INFO (f)->icon_bitmap_id = rc;
 25739             }
 25740 #endif
 25741 
 25742           /* If all else fails, use the (black and white) xbm image. */
 25743           if (rc == -1)
 25744             {
 25745               rc = image_create_bitmap_from_data (f,
 25746                                                   (char *) gnu_xbm_bits,
 25747                                                   gnu_xbm_width,
 25748                                                   gnu_xbm_height);
 25749               if (rc == -1)
 25750                 return true;
 25751 
 25752               FRAME_DISPLAY_INFO (f)->icon_bitmap_id = rc;
 25753               x_create_bitmap_mask (f, FRAME_DISPLAY_INFO (f)->icon_bitmap_id);
 25754             }
 25755         }
 25756 
 25757       /* The first time we create the GNU bitmap and mask,
 25758          this increments the ref-count one extra time.
 25759          As a result, the GNU bitmap and mask are never freed.
 25760          That way, we don't have to worry about allocating it again.  */
 25761       image_reference_bitmap (f, FRAME_DISPLAY_INFO (f)->icon_bitmap_id);
 25762 
 25763       bitmap_id = FRAME_DISPLAY_INFO (f)->icon_bitmap_id;
 25764     }
 25765 
 25766   x_wm_set_icon_pixmap (f, bitmap_id);
 25767   f->output_data.x->icon_bitmap = bitmap_id;
 25768 
 25769   return false;
 25770 }
 25771 
 25772 
 25773 /* Make the x-window of frame F use a rectangle with text.
 25774    Use ICON_NAME as the text.  */
 25775 
 25776 bool
 25777 x_text_icon (struct frame *f, const char *icon_name)
 25778 {
 25779   if (FRAME_X_WINDOW (f) == 0)
 25780     return true;
 25781 
 25782   {
 25783     XTextProperty text;
 25784     text.value = (unsigned char *) icon_name;
 25785     text.encoding = XA_STRING;
 25786     text.format = 8;
 25787     text.nitems = strlen (icon_name);
 25788     XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
 25789   }
 25790 
 25791   if (f->output_data.x->icon_bitmap > 0)
 25792     image_destroy_bitmap (f, f->output_data.x->icon_bitmap);
 25793   f->output_data.x->icon_bitmap = 0;
 25794   x_wm_set_icon_pixmap (f, 0);
 25795 
 25796   return false;
 25797 }
 25798 
 25799 
 25800 struct x_error_message_stack
 25801 {
 25802   /* Pointer to the error message of any error that was generated, or
 25803      NULL.  */
 25804   char *string;
 25805 
 25806   /* The display this error handler applies to.  */
 25807   Display *dpy;
 25808 
 25809   /* A function to call upon an error if non-NULL.  */
 25810   x_special_error_handler handler;
 25811 
 25812   /* Some data to pass to that handler function.  */
 25813   void *handler_data;
 25814 
 25815   /* The previous handler in this stack.  */
 25816   struct x_error_message_stack *prev;
 25817 
 25818   /* The first request that this error handler applies to.  Keeping
 25819      track of this allows us to avoid an XSync yet still have errors
 25820      for previously made requests be handled correctly.  */
 25821   unsigned long first_request;
 25822 };
 25823 
 25824 /* Stack of X error message handlers.  Whenever an error is generated
 25825    on a display, look in this stack for an appropriate error handler,
 25826    set its `string' to the error message and call its `handler' with
 25827    `handler_data'.  If no handler applies to the error, don't catch
 25828    it, and let it crash Emacs instead.
 25829 
 25830    This used to be a pointer to a string in which any error would be
 25831    placed before 2006.  */
 25832 static struct x_error_message_stack *x_error_message;
 25833 
 25834 /* The amount of items (depth) in that stack.  */
 25835 int x_error_message_count;
 25836 
 25837 /* Compare various request serials while handling wraparound.  Treat a
 25838    difference of more than X_ULONG_MAX / 2 as wraparound.
 25839 
 25840    Note that these functions truncate serials to 32 bits before
 25841    comparison.  */
 25842 
 25843 static bool
 25844 x_is_serial_more_than (unsigned int a, unsigned int b)
 25845 {
 25846   if (a > b)
 25847     return true;
 25848 
 25849   return (b - a > X_ULONG_MAX / 2);
 25850 }
 25851 
 25852 static bool
 25853 x_is_serial_more_than_or_equal_to (unsigned int a, unsigned int b)
 25854 {
 25855   if (a >= b)
 25856     return true;
 25857 
 25858   return (b - a > X_ULONG_MAX / 2);
 25859 }
 25860 
 25861 static bool
 25862 x_is_serial_less_than (unsigned int a, unsigned int b)
 25863 {
 25864   if (a < b)
 25865     return true;
 25866 
 25867   return (a - b > X_ULONG_MAX / 2);
 25868 }
 25869 
 25870 static bool
 25871 x_is_serial_less_than_or_equal_to (unsigned int a, unsigned int b)
 25872 {
 25873   if (a <= b)
 25874     return true;
 25875 
 25876   return (a - b > X_ULONG_MAX / 2);
 25877 }
 25878 
 25879 static struct x_error_message_stack *
 25880 x_find_error_handler (Display *dpy, XErrorEvent *event)
 25881 {
 25882   struct x_error_message_stack *stack;
 25883 
 25884   stack = x_error_message;
 25885 
 25886   while (stack)
 25887     {
 25888       if (x_is_serial_more_than_or_equal_to (event->serial,
 25889                                              stack->first_request)
 25890           && dpy == stack->dpy)
 25891         return stack;
 25892 
 25893       stack = stack->prev;
 25894     }
 25895 
 25896   return NULL;
 25897 }
 25898 
 25899 void
 25900 x_unwind_errors_to (int depth)
 25901 {
 25902   while (x_error_message_count > depth)
 25903     /* This is safe to call because we check whether or not
 25904        x_error_message->dpy is still alive before calling XSync.  */
 25905     x_uncatch_errors ();
 25906 }
 25907 
 25908 #define X_ERROR_MESSAGE_SIZE 200
 25909 
 25910 /* An X error handler which stores the error message in the first
 25911    applicable handler in the x_error_message stack.  This is called
 25912    from *x_error_handler if an x_catch_errors for DISPLAY is in
 25913    effect.  */
 25914 
 25915 static void
 25916 x_error_catcher (Display *display, XErrorEvent *event,
 25917                  struct x_error_message_stack *stack)
 25918 {
 25919   char buf[X_ERROR_MESSAGE_SIZE];
 25920 
 25921   XGetErrorText (display, event->error_code,
 25922                  buf, X_ERROR_MESSAGE_SIZE);
 25923 
 25924   if (stack->string)
 25925     xfree (stack->string);
 25926 
 25927   stack->string = xstrdup (buf);
 25928 
 25929   if (stack->handler)
 25930     stack->handler (display, event, stack->string,
 25931                     stack->handler_data);
 25932 }
 25933 
 25934 /* Begin trapping X errors for display DPY.
 25935 
 25936    After calling this function, X protocol errors generated on DPY no
 25937    longer cause Emacs to exit; instead, they are recorded in an error
 25938    handler pushed onto the stack `x_error_message'.
 25939 
 25940    Calling x_check_errors signals an Emacs error if an X error has
 25941    occurred since the last call to x_catch_errors or x_check_errors.
 25942 
 25943    Calling x_uncatch_errors resumes the normal error handling,
 25944    skipping an XSync if the last request made is known to have been
 25945    processed.  Calling x_uncatch_errors_after_check is similar, but
 25946    always skips an XSync to the server, and should be used only
 25947    immediately after x_had_errors_p or x_check_errors, or when it is
 25948    known that no requests have been made since the last x_catch_errors
 25949    call for DPY.
 25950 
 25951    There is no need to use this mechanism for ignoring errors from
 25952    single asynchronous requests, such as sending a ClientMessage to a
 25953    window that might no longer exist.  Use
 25954    x_ignore_errors_for_next_request (paired with
 25955    x_stop_ignoring_errors) instead.  */
 25956 
 25957 void
 25958 x_catch_errors_with_handler (Display *dpy, x_special_error_handler handler,
 25959                              void *handler_data)
 25960 {
 25961   struct x_error_message_stack *data;
 25962 
 25963   data = xzalloc (sizeof *data);
 25964   data->dpy = dpy;
 25965   data->handler = handler;
 25966   data->handler_data = handler_data;
 25967   data->prev = x_error_message;
 25968   data->first_request = XNextRequest (dpy);
 25969   x_error_message = data;
 25970 
 25971   ++x_error_message_count;
 25972 }
 25973 
 25974 void
 25975 x_catch_errors (Display *dpy)
 25976 {
 25977   x_catch_errors_with_handler (dpy, NULL, NULL);
 25978 }
 25979 
 25980 /* Return if errors for REQUEST should be ignored even if there is no
 25981    error handler applied.  */
 25982 static struct x_failable_request *
 25983 x_request_can_fail (struct x_display_info *dpyinfo,
 25984                     unsigned long request)
 25985 {
 25986   struct x_failable_request *failable_requests;
 25987 
 25988   for (failable_requests = dpyinfo->failable_requests;
 25989        failable_requests < dpyinfo->next_failable_request;
 25990        failable_requests++)
 25991     {
 25992       if (x_is_serial_more_than_or_equal_to (request,
 25993                                              failable_requests->start)
 25994           && (!failable_requests->end
 25995               || x_is_serial_less_than_or_equal_to (request,
 25996                                                     failable_requests->end)))
 25997         return failable_requests;
 25998     }
 25999 
 26000   return NULL;
 26001 }
 26002 
 26003 /* Remove outdated request serials from
 26004    dpyinfo->failable_requests.  */
 26005 static void
 26006 x_clean_failable_requests (struct x_display_info *dpyinfo)
 26007 {
 26008   struct x_failable_request *first, *last;
 26009 
 26010   last = dpyinfo->next_failable_request;
 26011 
 26012   for (first = dpyinfo->failable_requests; first < last; first++)
 26013     {
 26014       if (x_is_serial_more_than (first->start,
 26015                                  LastKnownRequestProcessed (dpyinfo->display))
 26016           || !first->end
 26017           || x_is_serial_more_than (first->end,
 26018                                     LastKnownRequestProcessed (dpyinfo->display)))
 26019         break;
 26020     }
 26021 
 26022   if (first != last)
 26023     memmove (&dpyinfo->failable_requests, first,
 26024              sizeof *first * (last - first));
 26025 
 26026   dpyinfo->next_failable_request = (dpyinfo->failable_requests
 26027                                     + (last - first));
 26028 }
 26029 
 26030 /* Protect a section of X requests.
 26031 
 26032    Ignore errors generated by X requests made from now until
 26033    `x_stop_ignoring_errors'.  Each call must be paired with a call to
 26034    `x_stop_ignoring_errors', and recursive calls inside the protected
 26035    section are not allowed.
 26036 
 26037    The advantage over x_catch_errors followed by
 26038    x_uncatch_errors_after_check is that this function does not sync to
 26039    catch errors if requests were made.  It should be used instead of
 26040    those two functions for catching errors around requests that do not
 26041    require a reply.
 26042 
 26043    If SELECTION_SERIAL is an arbitrary number greater than zero,
 26044    x_select_handle_selection_error is called with the specified number
 26045    after any errors within the protected section are received to
 26046    delete the selection request that encountered errors.  */
 26047 
 26048 void
 26049 x_ignore_errors_for_next_request (struct x_display_info *dpyinfo,
 26050                                   unsigned int selection_serial)
 26051 {
 26052   struct x_failable_request *request, *max;
 26053   unsigned long next_request;
 26054 #ifdef HAVE_GTK3
 26055   GdkDisplay *gdpy;
 26056 #endif
 26057 
 26058   /* This code is not reentrant, so be sure nothing calls it
 26059      recursively in response to input.  */
 26060   block_input ();
 26061 
 26062 #ifdef HAVE_GTK3
 26063   /* GTK 3 tends to override our own error handler inside certain
 26064      callbacks, which this can be called from.  Instead of trying to
 26065      restore our own, add a trap for the following requests with
 26066      GDK as well.  */
 26067 
 26068   gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 26069 
 26070   if (gdpy)
 26071     gdk_x11_display_error_trap_push (gdpy);
 26072 #endif
 26073 
 26074   if ((dpyinfo->next_failable_request
 26075        != dpyinfo->failable_requests)
 26076       && (dpyinfo->next_failable_request - 1)->end == 0)
 26077     /* A new sequence should never be started before an old one
 26078        finishes.  Use `x_catch_errors' to nest error handlers.  */
 26079     emacs_abort ();
 26080 
 26081   request = dpyinfo->next_failable_request;
 26082   max = dpyinfo->failable_requests + N_FAILABLE_REQUESTS;
 26083   next_request = XNextRequest (dpyinfo->display);
 26084 
 26085   if (request >= max)
 26086     {
 26087       /* There is no point in making this extra sync if all requests
 26088          are known to have been fully processed.  */
 26089       if ((LastKnownRequestProcessed (dpyinfo->display)
 26090            != next_request - 1))
 26091         XSync (dpyinfo->display, False);
 26092 
 26093       x_clean_failable_requests (dpyinfo);
 26094       request = dpyinfo->next_failable_request;
 26095     }
 26096 
 26097   if (request >= max)
 26098     /* A request should always be made immediately after calling this
 26099        function.  */
 26100     emacs_abort ();
 26101 
 26102   request->start = next_request;
 26103   request->end = 0;
 26104   request->selection_serial = selection_serial;
 26105 
 26106   dpyinfo->next_failable_request++;
 26107 }
 26108 
 26109 void
 26110 x_stop_ignoring_errors (struct x_display_info *dpyinfo)
 26111 {
 26112   struct x_failable_request *range;
 26113 #ifdef HAVE_GTK3
 26114   GdkDisplay *gdpy;
 26115 #endif
 26116 
 26117   range = dpyinfo->next_failable_request - 1;
 26118   range->end = XNextRequest (dpyinfo->display) - 1;
 26119 
 26120   /* Abort if no request was made since
 26121      `x_ignore_errors_for_next_request'.  */
 26122 
 26123   if (x_is_serial_less_than (range->end, range->start))
 26124     emacs_abort ();
 26125 
 26126 #ifdef HAVE_GTK3
 26127   gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 26128 
 26129   if (gdpy)
 26130     gdk_x11_display_error_trap_pop_ignored (gdpy);
 26131 #endif
 26132 
 26133   unblock_input ();
 26134 }
 26135 
 26136 /* Undo the last x_catch_errors call.
 26137    DPY should be the display that was passed to x_catch_errors.
 26138 
 26139    This version should be used only if the immediately preceding
 26140    X-protocol-related thing was x_check_errors or x_had_error_p, both
 26141    of which issue XSync calls, so we don't need to re-sync here.  */
 26142 
 26143 void
 26144 x_uncatch_errors_after_check (void)
 26145 {
 26146   struct x_error_message_stack *tmp;
 26147 
 26148   block_input ();
 26149   tmp = x_error_message;
 26150   x_error_message = x_error_message->prev;
 26151   --x_error_message_count;
 26152   if (tmp->string)
 26153     xfree (tmp->string);
 26154   xfree (tmp);
 26155   unblock_input ();
 26156 }
 26157 
 26158 /* Undo the last x_catch_errors call.  */
 26159 
 26160 void
 26161 x_uncatch_errors (void)
 26162 {
 26163   struct x_error_message_stack *tmp;
 26164   struct x_display_info *dpyinfo;
 26165 
 26166   /* In rare situations when running Emacs run in daemon mode,
 26167      shutting down an emacsclient via delete-frame can cause
 26168      x_uncatch_errors to be called when x_error_message is set to
 26169      NULL.  */
 26170   if (x_error_message == NULL)
 26171     return;
 26172 
 26173   block_input ();
 26174 
 26175   dpyinfo = x_display_info_for_display (x_error_message->dpy);
 26176 
 26177   /* The display may have been closed before this function is called.
 26178      Check if it is still open before calling XSync.  */
 26179   if (dpyinfo != 0
 26180       /* There is no point in making this extra sync if all requests
 26181          are known to have been fully processed.  */
 26182       && (LastKnownRequestProcessed (x_error_message->dpy)
 26183           != XNextRequest (x_error_message->dpy) - 1)
 26184       /* Likewise if no request was made since the trap was
 26185          installed.  */
 26186       && (NextRequest (x_error_message->dpy)
 26187           > x_error_message->first_request))
 26188     {
 26189       XSync (x_error_message->dpy, False);
 26190       x_clean_failable_requests (dpyinfo);
 26191     }
 26192 
 26193   tmp = x_error_message;
 26194   x_error_message = x_error_message->prev;
 26195   --x_error_message_count;
 26196   if (tmp->string)
 26197     xfree (tmp->string);
 26198   xfree (tmp);
 26199   unblock_input ();
 26200 }
 26201 
 26202 /* If any X protocol errors have arrived since the last call to
 26203    x_catch_errors or x_check_errors, signal an Emacs error using
 26204    sprintf (a buffer, FORMAT, the x error message text) as the text.  */
 26205 
 26206 void
 26207 x_check_errors (Display *dpy, const char *format)
 26208 {
 26209   struct x_display_info *dpyinfo;
 26210   char *string;
 26211 
 26212   /* This shouldn't happen, since x_check_errors should be called
 26213      immediately inside an x_catch_errors block.  */
 26214   if (dpy != x_error_message->dpy)
 26215     emacs_abort ();
 26216 
 26217   /* There is no point in making this extra sync if all requests
 26218      are known to have been fully processed.  */
 26219   if ((LastKnownRequestProcessed (dpy)
 26220        != XNextRequest (dpy) - 1)
 26221       && (NextRequest (dpy)
 26222           > x_error_message->first_request))
 26223     XSync (dpy, False);
 26224 
 26225   dpyinfo = x_display_info_for_display (dpy);
 26226 
 26227   /* Clean the array of failable requests, since a sync happened.  */
 26228   if (dpyinfo)
 26229     x_clean_failable_requests (dpyinfo);
 26230 
 26231   if (x_error_message->string)
 26232     {
 26233       string = alloca (strlen (x_error_message->string) + 1);
 26234       strcpy (string, x_error_message->string);
 26235 
 26236       error (format, string);
 26237     }
 26238 }
 26239 
 26240 /* Nonzero if any X protocol errors were generated since the last call
 26241    to x_catch_errors on DPY.  */
 26242 
 26243 bool
 26244 x_had_errors_p (Display *dpy)
 26245 {
 26246   struct x_display_info *dpyinfo;
 26247 
 26248   /* This shouldn't happen, since x_check_errors should be called
 26249      immediately inside an x_catch_errors block.  */
 26250   if (dpy != x_error_message->dpy)
 26251     emacs_abort ();
 26252 
 26253   /* Make sure to catch any errors incurred so far.  */
 26254   if ((LastKnownRequestProcessed (dpy)
 26255        != XNextRequest (dpy) - 1)
 26256       && (NextRequest (dpy)
 26257           > x_error_message->first_request))
 26258     XSync (dpy, False);
 26259 
 26260   dpyinfo = x_display_info_for_display (dpy);
 26261 
 26262   /* Clean the array of failable requests, since a sync happened.  */
 26263   if (dpyinfo)
 26264     x_clean_failable_requests (dpyinfo);
 26265 
 26266   return !!x_error_message->string;
 26267 }
 26268 
 26269 /* Forget about any errors we have had, since we did x_catch_errors on
 26270    DPY.  */
 26271 
 26272 void
 26273 x_clear_errors (Display *dpy)
 26274 {
 26275   /* This shouldn't happen, since x_check_errors should be called
 26276      immediately inside an x_catch_errors block.  */
 26277   if (dpy != x_error_message->dpy)
 26278     emacs_abort ();
 26279 
 26280   xfree (x_error_message->string);
 26281   x_error_message->string = NULL;
 26282 }
 26283 
 26284 #if false
 26285       /* See comment in unwind_to_catch why calling this is a bad
 26286        * idea.  --lorentey   */
 26287 /* Close off all unclosed x_catch_errors calls.  */
 26288 
 26289 void
 26290 x_fully_uncatch_errors (void)
 26291 {
 26292   while (x_error_message)
 26293     x_uncatch_errors ();
 26294 }
 26295 #endif
 26296 
 26297 #if false
 26298 static unsigned int x_wire_count;
 26299 
 26300 static int
 26301 x_trace_wire (Display *dpy)
 26302 {
 26303   fprintf (stderr, "Lib call: %u\n", ++x_wire_count);
 26304   return 0;
 26305 }
 26306 #endif
 26307 
 26308 
 26309 /************************************************************************
 26310                           Handling X errors
 26311  ************************************************************************/
 26312 
 26313 /* Error message passed to x_connection_closed.  */
 26314 
 26315 static char *error_msg;
 26316 
 26317 /* Try to find a frame in Vframe_list, and make it the selected frame.
 26318    `delete_frame' sometimes misses the initial frame for an unknown
 26319    reason when Emacs is running as a background daemon.  */
 26320 
 26321 static void
 26322 x_try_restore_frame (void)
 26323 {
 26324   Lisp_Object tail, frame;
 26325 
 26326   FOR_EACH_FRAME (tail, frame)
 26327     {
 26328       if (!NILP (do_switch_frame (frame, 0, 1, Qnil)))
 26329         return;
 26330     }
 26331 }
 26332 
 26333 /* Handle the loss of connection to display DPY.  ERROR_MESSAGE is
 26334    the text of an error message that lead to the connection loss.  */
 26335 
 26336 static void
 26337 x_connection_closed (Display *dpy, const char *error_message, bool ioerror)
 26338 {
 26339   struct x_display_info *dpyinfo;
 26340   Lisp_Object frame, tail;
 26341   specpdl_ref idx = SPECPDL_INDEX ();
 26342   Emacs_XIOErrorHandler io_error_handler;
 26343   xm_drop_start_message dmsg;
 26344   struct frame *f;
 26345   Lisp_Object minibuf_frame, tmp;
 26346   struct x_failable_request *failable;
 26347   struct x_error_message_stack *stack;
 26348   static Display *current_display;
 26349 
 26350   /* Prevent recursive calls of this function for the same display.
 26351      This is because destroying a frame might still cause an IO error
 26352      in some cases.  (bug#56528) */
 26353   if (current_display == dpy)
 26354     return;
 26355 
 26356   current_display = dpy;
 26357 
 26358   dpyinfo = x_display_info_for_display (dpy);
 26359   error_msg = alloca (strlen (error_message) + 1);
 26360   strcpy (error_msg, error_message);
 26361 
 26362   /* Inhibit redisplay while frames are being deleted. */
 26363   specbind (Qinhibit_redisplay, Qt);
 26364 
 26365   /* If drag-and-drop is in progress, cancel drag-and-drop.  If DND
 26366      frame's display is DPY, don't reset event masks or try to send
 26367      responses to other programs because the display is going
 26368      away.  */
 26369 
 26370   if (x_dnd_in_progress || x_dnd_waiting_for_finish)
 26371     {
 26372       if (!ioerror)
 26373         {
 26374           /* Handle display disconnect errors here because this function
 26375              is not reentrant at this particular spot.  */
 26376           io_error_handler = XSetIOErrorHandler (x_dnd_io_error_handler);
 26377 
 26378           if (!!sigsetjmp (x_dnd_disconnect_handler, 1)
 26379               && x_dnd_in_progress
 26380               && dpy == (x_dnd_waiting_for_finish
 26381                          ? x_dnd_finish_display
 26382                          : FRAME_X_DISPLAY (x_dnd_frame)))
 26383             {
 26384               /* Clean up drag and drop if the drag frame's display isn't
 26385                  the one being disconnected.  */
 26386               f = x_dnd_frame;
 26387 
 26388               if (x_dnd_last_seen_window != None
 26389                   && x_dnd_last_protocol_version != -1)
 26390                 x_dnd_send_leave (x_dnd_frame,
 26391                                   x_dnd_last_seen_window,
 26392                                   x_dnd_last_seen_toplevel);
 26393               else if (x_dnd_last_seen_window != None
 26394                        && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
 26395                        && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
 26396                        && x_dnd_motif_setup_p)
 26397                 {
 26398                   dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
 26399                                                 XM_DRAG_REASON_DROP_START);
 26400                   dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
 26401                   dmsg.timestamp = FRAME_DISPLAY_INFO (f)->last_user_time;
 26402                   dmsg.side_effects
 26403                     = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
 26404                                                                        x_dnd_wanted_action),
 26405                                            XM_DROP_SITE_VALID, x_dnd_motif_operations,
 26406                                            XM_DROP_ACTION_DROP_CANCEL);
 26407                   dmsg.x = 0;
 26408                   dmsg.y = 0;
 26409                   dmsg.index_atom = x_dnd_motif_atom;
 26410                   dmsg.source_window = FRAME_X_WINDOW (f);
 26411 
 26412                   x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
 26413                                                 x_dnd_last_seen_window, 0);
 26414                   xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
 26415                                         x_dnd_last_seen_window, &dmsg);
 26416                 }
 26417             }
 26418 
 26419           XSetIOErrorHandler (io_error_handler);
 26420         }
 26421 
 26422       dpyinfo = x_display_info_for_display (dpy);
 26423 
 26424       x_dnd_last_seen_window = None;
 26425       x_dnd_last_seen_toplevel = None;
 26426       x_dnd_in_progress = false;
 26427       x_dnd_waiting_for_finish = false;
 26428 
 26429       if (x_dnd_use_toplevels)
 26430         x_dnd_free_toplevels (!ioerror);
 26431 
 26432       x_dnd_return_frame_object = NULL;
 26433       x_dnd_movement_frame = NULL;
 26434       x_dnd_wheel_frame = NULL;
 26435       x_dnd_frame = NULL;
 26436     }
 26437 
 26438   if (dpyinfo)
 26439     {
 26440       /* Protect display from being closed when we delete the last
 26441          frame on it. */
 26442       dpyinfo->reference_count++;
 26443       dpyinfo->terminal->reference_count++;
 26444       if (ioerror)
 26445         dpyinfo->display = 0;
 26446     }
 26447 
 26448   /* delete_frame can still try to read async input (even though we
 26449      tell pass `noelisp'), because looking up the `delete-before'
 26450      parameter calls Fassq which then calls maybe_quit.  So block
 26451      input while deleting frames.  */
 26452   block_input ();
 26453 
 26454   /* First delete frames whose mini-buffers are on frames
 26455      that are on the dead display.  */
 26456   FOR_EACH_FRAME (tail, frame)
 26457     {
 26458       /* Tooltip frames don't have these, so avoid crashing.  */
 26459 
 26460       if (FRAME_TOOLTIP_P (XFRAME (frame)))
 26461         continue;
 26462 
 26463       minibuf_frame
 26464         = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame))));
 26465 
 26466       if (FRAME_X_P (XFRAME (frame))
 26467           && FRAME_X_P (XFRAME (minibuf_frame))
 26468           && ! EQ (frame, minibuf_frame)
 26469           && FRAME_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo)
 26470         delete_frame (frame, Qnoelisp);
 26471     }
 26472 
 26473   /* Now delete all remaining frames on the dead display.
 26474      We are now sure none of these is used as the mini-buffer
 26475      for another frame that we need to delete.  */
 26476   FOR_EACH_FRAME (tail, frame)
 26477     if (FRAME_X_P (XFRAME (frame))
 26478         && FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
 26479       {
 26480         /* Set this to t so that delete_frame won't get confused
 26481            trying to find a replacement.  */
 26482         kset_default_minibuffer_frame (FRAME_KBOARD (XFRAME (frame)), Qt);
 26483         delete_frame (frame, Qnoelisp);
 26484       }
 26485 
 26486   /* If DPYINFO is null, this means we didn't open the display in the
 26487      first place, so don't try to close it.  */
 26488   if (dpyinfo)
 26489     {
 26490       /* We can not call XtCloseDisplay here because it calls XSync.
 26491          XSync inside the error handler apparently hangs Emacs.  On
 26492          current Xt versions, this isn't needed either.  */
 26493 #ifdef USE_GTK
 26494       /* A long-standing GTK bug prevents proper disconnect handling
 26495          <https://gitlab.gnome.org/GNOME/gtk/issues/221>.  Once,
 26496          the resulting Glib error message loop filled a user's disk.
 26497          To avoid this, kill Emacs unconditionally on disconnect.  */
 26498       shut_down_emacs (0, Qnil);
 26499       fprintf (stderr, "%s\n\
 26500 When compiled with GTK, Emacs cannot recover from X disconnects.\n\
 26501 This is a GTK bug: https://gitlab.gnome.org/GNOME/gtk/issues/221\n\
 26502 For details, see etc/PROBLEMS.\n",
 26503                error_msg);
 26504       emacs_abort ();
 26505 #endif /* USE_GTK */
 26506 
 26507       /* Indicate that this display is dead.  */
 26508       dpyinfo->display = 0;
 26509 
 26510       dpyinfo->reference_count--;
 26511       dpyinfo->terminal->reference_count--;
 26512       if (dpyinfo->reference_count != 0)
 26513         /* We have just closed all frames on this display. */
 26514         emacs_abort ();
 26515 
 26516       /* This was the last terminal remaining, so print the error
 26517          message and associated error handlers and kill Emacs.  */
 26518       if (dpyinfo->terminal == terminal_list
 26519           && !terminal_list->next_terminal)
 26520         {
 26521           fprintf (stderr, "%s\n", error_msg);
 26522 
 26523           if (!ioerror && dpyinfo)
 26524             {
 26525               /* Dump the list of error handlers for debugging
 26526                  purposes if the list exists.  */
 26527 
 26528               if ((dpyinfo->failable_requests
 26529                    != dpyinfo->next_failable_request) || x_error_message)
 26530                 fprintf (stderr, "X error handlers currently installed:\n");
 26531 
 26532               for (failable = dpyinfo->failable_requests;
 26533                    failable < dpyinfo->next_failable_request;
 26534                    ++failable)
 26535                 {
 26536                   if (failable->end)
 26537                     fprintf (stderr, "Ignoring errors between %lu to %lu\n",
 26538                              failable->start, failable->end);
 26539                   else
 26540                     fprintf (stderr, "Ignoring errors from %lu onwards\n",
 26541                              failable->start);
 26542                 }
 26543 
 26544               for (stack = x_error_message; stack; stack = stack->prev)
 26545                 fprintf (stderr, "Trapping errors from %lu\n",
 26546                          stack->first_request);
 26547             }
 26548         }
 26549 
 26550       XSETTERMINAL (tmp, dpyinfo->terminal);
 26551       Fdelete_terminal (tmp, Qnoelisp);
 26552     }
 26553 
 26554   /* The initial "daemon" frame is sometimes not selected by
 26555      `delete_frame' when Emacs is a background daemon.  */
 26556   if (NILP (selected_frame))
 26557     x_try_restore_frame ();
 26558 
 26559   unblock_input ();
 26560 
 26561   /* Sometimes another terminal is still alive, but deleting this
 26562      terminal caused all frames to vanish.  In that case, simply kill
 26563      Emacs, since the next redisplay will abort as there is no more
 26564      selected frame.  (bug#56528) */
 26565   if (terminal_list == 0 || NILP (selected_frame))
 26566     Fkill_emacs (make_fixnum (70), Qnil);
 26567 
 26568   totally_unblock_input ();
 26569 
 26570   unbind_to (idx, Qnil);
 26571   clear_waiting_for_input ();
 26572 
 26573   /* Here, we absolutely have to use a non-local exit (e.g. signal, throw,
 26574      longjmp), because returning from this function would get us back into
 26575      Xlib's code which will directly call `exit'.  */
 26576   current_display = NULL;
 26577   error ("%s", error_msg);
 26578 }
 26579 
 26580 static void x_error_quitter (Display *, XErrorEvent *);
 26581 
 26582 /* This is the first-level handler for X protocol errors.
 26583    It calls x_error_quitter or x_error_catcher.  */
 26584 
 26585 static int
 26586 x_error_handler (Display *display, XErrorEvent *event)
 26587 {
 26588   struct x_error_message_stack *stack;
 26589   struct x_display_info *dpyinfo;
 26590   struct x_failable_request *fail, *last;
 26591 
 26592 #if defined USE_GTK && defined HAVE_GTK3
 26593   if ((event->error_code == BadMatch
 26594        || event->error_code == BadWindow)
 26595       && event->request_code == X_SetInputFocus)
 26596     return 0;
 26597 #endif
 26598 
 26599   dpyinfo = x_display_info_for_display (display);
 26600 
 26601   if (dpyinfo)
 26602     {
 26603       fail = x_request_can_fail (dpyinfo, event->serial);
 26604 
 26605       if (fail)
 26606         {
 26607           /* Now that this request sequence has been fully handled,
 26608              remove it from the list of requests that can fail.  */
 26609 
 26610           if (event->serial == fail->end)
 26611             {
 26612               last = dpyinfo->next_failable_request;
 26613               memmove (&dpyinfo->failable_requests, fail,
 26614                        sizeof *fail * (last - fail));
 26615               dpyinfo->next_failable_request = (dpyinfo->failable_requests
 26616                                                 + (last - fail));
 26617             }
 26618 
 26619           /* If a selection transfer is the cause of this error,
 26620              remove the selection transfer now.  */
 26621 
 26622           if (fail->selection_serial)
 26623             {
 26624               x_handle_selection_error (fail->selection_serial,
 26625                                         event);
 26626 
 26627               /* Clear selection_serial to prevent
 26628                  x_handle_selection_error from being called again if
 26629                  any more requests within the protected section cause
 26630                  errors to be reported.  */
 26631               fail->selection_serial = 0;
 26632             }
 26633 
 26634           return 0;
 26635         }
 26636     }
 26637 
 26638   /* If we try to ungrab or grab a device that doesn't exist anymore
 26639      (that happens a lot in xmenu.c), just ignore the error.  */
 26640 
 26641 #ifdef HAVE_XINPUT2
 26642   /* Handle errors from some specific XI2 requests here to avoid a
 26643      sync in handle_one_xevent.  */
 26644   if (dpyinfo && dpyinfo->supports_xi2
 26645       && event->request_code == dpyinfo->xi2_opcode
 26646       && (event->minor_code == X_XIGrabDevice
 26647           || event->minor_code == X_XIUngrabDevice
 26648           || event->minor_code == X_XIAllowEvents))
 26649     return 0;
 26650 #endif
 26651 
 26652   stack = x_find_error_handler (display, event);
 26653 
 26654   if (stack)
 26655     x_error_catcher (display, event, stack);
 26656   else
 26657     x_error_quitter (display, event);
 26658   return 0;
 26659 }
 26660 
 26661 /* This is the usual handler for X protocol errors.
 26662    It kills all frames on the display that we got the error for.
 26663    If that was the only one, it prints an error message and kills Emacs.  */
 26664 
 26665 /* .gdbinit puts a breakpoint here, so make sure it is not inlined.  */
 26666 
 26667 static void NO_INLINE
 26668 x_error_quitter (Display *display, XErrorEvent *event)
 26669 {
 26670   char buf[256], buf1[800 + INT_STRLEN_BOUND (int)
 26671                       + INT_STRLEN_BOUND (unsigned long)
 26672                       + INT_STRLEN_BOUND (XID)
 26673                       + INT_STRLEN_BOUND (int)];
 26674 
 26675   /* Ignore BadName errors.  They can happen because of fonts
 26676      or colors that are not defined.  */
 26677 
 26678   if (event->error_code == BadName)
 26679     return;
 26680 
 26681   /* Note that there is no real way portable across R3/R4 to get the
 26682      original error handler.  */
 26683 
 26684   XGetErrorText (display, event->error_code, buf, sizeof (buf));
 26685   sprintf (buf1, "X protocol error: %s on protocol request %d\n"
 26686            "Serial no: %lu\n"
 26687            "Failing resource ID (if any): 0x%lx\n"
 26688            "Minor code: %d\n"
 26689            "This is a bug!  Please report this to bug-gnu-emacs@gnu.org!\n",
 26690            buf, event->request_code, event->serial, event->resourceid,
 26691            event->minor_code);
 26692   x_connection_closed (display, buf1, false);
 26693 }
 26694 
 26695 
 26696 /* This is the handler for X IO errors, always.
 26697    It kills all frames on the display that we lost touch with.
 26698    If that was the only one, it prints an error message and kills Emacs.  */
 26699 
 26700 static int NO_INLINE
 26701 x_io_error_quitter (Display *display)
 26702 {
 26703   char buf[256];
 26704 
 26705   snprintf (buf, sizeof buf, "Connection lost to X server '%s'",
 26706             DisplayString (display));
 26707   x_connection_closed (display, buf, true);
 26708 
 26709   return 0;
 26710 }
 26711 
 26712 
 26713 /* Changing the font of the frame.  */
 26714 
 26715 /* Give frame F the font FONT-OBJECT as its default font.  The return
 26716    value is FONT-OBJECT.  FONTSET is an ID of the fontset for the
 26717    frame.  If it is negative, generate a new fontset from
 26718    FONT-OBJECT.  */
 26719 
 26720 static Lisp_Object
 26721 x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
 26722 {
 26723   struct font *font = XFONT_OBJECT (font_object);
 26724   int unit, font_ascent, font_descent;
 26725 
 26726   if (fontset < 0)
 26727     fontset = fontset_from_font (font_object);
 26728   FRAME_FONTSET (f) = fontset;
 26729   if (FRAME_FONT (f) == font)
 26730     /* This font is already set in frame F.  There's nothing more to
 26731        do.  */
 26732     return font_object;
 26733 
 26734   FRAME_FONT (f) = font;
 26735   FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
 26736   FRAME_COLUMN_WIDTH (f) = font->average_width;
 26737   get_font_ascent_descent (font, &font_ascent, &font_descent);
 26738   FRAME_LINE_HEIGHT (f) = font_ascent + font_descent;
 26739 
 26740 #ifndef USE_X_TOOLKIT
 26741   FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
 26742 #endif
 26743   /* We could use a more elaborate calculation here.  */
 26744   FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
 26745 
 26746   /* Compute character columns occupied by scrollbar.
 26747 
 26748      Don't do things differently for non-toolkit scrollbars
 26749      (Bug#17163).  */
 26750   unit = FRAME_COLUMN_WIDTH (f);
 26751   if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
 26752     FRAME_CONFIG_SCROLL_BAR_COLS (f)
 26753       = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
 26754   else
 26755     FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
 26756 
 26757 
 26758   /* Don't change the size of a tip frame; there's no point in doing it
 26759      because it's done in Fx_show_tip, and it leads to problems because
 26760      the tip frame has no widget.  */
 26761   if (FRAME_X_WINDOW (f) != 0 && !FRAME_TOOLTIP_P (f))
 26762     adjust_frame_size
 26763       (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
 26764        FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, false, Qfont);
 26765 
 26766 #ifdef HAVE_X_I18N
 26767   if (FRAME_XIC (f)
 26768       && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
 26769     {
 26770       block_input ();
 26771       xic_set_xfontset (f, SSDATA (fontset_ascii (fontset)));
 26772       unblock_input ();
 26773     }
 26774 #endif
 26775 
 26776   return font_object;
 26777 }
 26778 
 26779 
 26780 /***********************************************************************
 26781                            X Input Methods
 26782  ***********************************************************************/
 26783 
 26784 #ifdef HAVE_X_I18N
 26785 
 26786 #ifdef HAVE_X11R6
 26787 
 26788 /* HAVE_X11R6 means Xlib conforms to the R6 specification or later.
 26789    HAVE_X11R6_XIM, OTOH, means that Emacs should try to use R6-style
 26790    callback driven input method initialization.  They are separate
 26791    because Sun apparently ships buggy Xlib with some versions of
 26792    Solaris... */
 26793 
 26794 #ifdef HAVE_X11R6_XIM
 26795 
 26796 /* If preedit text is set on F, cancel preedit, free the text, and
 26797    generate the appropriate events to cancel the preedit display.
 26798 
 26799    This is mainly useful when the connection to the IM server is
 26800    dropped during preconversion.  */
 26801 
 26802 static void
 26803 x_maybe_clear_preedit (struct frame *f)
 26804 {
 26805   struct x_output *output;
 26806   struct input_event ie;
 26807 
 26808   output = FRAME_X_OUTPUT (f);
 26809 
 26810   if (!output->preedit_chars)
 26811     return;
 26812 
 26813   EVENT_INIT (ie);
 26814   ie.kind = PREEDIT_TEXT_EVENT;
 26815   ie.arg = Qnil;
 26816   XSETFRAME (ie.frame_or_window, f);
 26817   XSETINT (ie.x, 0);
 26818   XSETINT (ie.y, 0);
 26819   kbd_buffer_store_event (&ie);
 26820 
 26821   xfree (output->preedit_chars);
 26822 
 26823   output->preedit_size = 0;
 26824   output->preedit_active = false;
 26825   output->preedit_chars = NULL;
 26826   output->preedit_caret = 0;
 26827 }
 26828 
 26829 /* XIM destroy callback function, which is called whenever the
 26830    connection to input method XIM dies.  CLIENT_DATA contains a
 26831    pointer to the x_display_info structure corresponding to XIM.  */
 26832 
 26833 static void
 26834 xim_destroy_callback (XIM xim, XPointer client_data, XPointer call_data)
 26835 {
 26836   struct x_display_info *dpyinfo = (struct x_display_info *) client_data;
 26837   Lisp_Object frame, tail;
 26838 
 26839   block_input ();
 26840 
 26841   /* No need to call XDestroyIC.. */
 26842   FOR_EACH_FRAME (tail, frame)
 26843     {
 26844       struct frame *f = XFRAME (frame);
 26845       if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo)
 26846         {
 26847           FRAME_XIC (f) = NULL;
 26848           xic_free_xfontset (f);
 26849 
 26850           /* Free the preedit text if necessary.  */
 26851           x_maybe_clear_preedit (f);
 26852         }
 26853     }
 26854 
 26855   /* No need to call XCloseIM.  */
 26856   dpyinfo->xim = NULL;
 26857 
 26858   /* Also free IM values; those are allocated separately upon
 26859      XGetIMValues.  */
 26860   if (dpyinfo->xim_styles)
 26861     XFree (dpyinfo->xim_styles);
 26862   dpyinfo->xim_styles = NULL;
 26863   unblock_input ();
 26864 }
 26865 
 26866 #endif
 26867 
 26868 #endif /* HAVE_X11R6 */
 26869 
 26870 /* Open the connection to the XIM server on display DPYINFO.
 26871    RESOURCE_NAME is the resource name Emacs uses.  */
 26872 
 26873 static void
 26874 xim_open_dpy (struct x_display_info *dpyinfo, char *resource_name)
 26875 {
 26876 #ifdef HAVE_XIM
 26877   XIM xim;
 26878   const char *locale;
 26879 
 26880   if (dpyinfo->use_xim)
 26881     {
 26882       if (dpyinfo->xim)
 26883         {
 26884           XCloseIM (dpyinfo->xim);
 26885 
 26886           /* Free values left over from the last time the IM
 26887              connection was established.  */
 26888 
 26889           if (dpyinfo->xim_styles)
 26890             XFree (dpyinfo->xim_styles);
 26891           dpyinfo->xim_styles = NULL;
 26892         }
 26893 
 26894       xim = XOpenIM (dpyinfo->display, dpyinfo->rdb, resource_name,
 26895                      emacs_class);
 26896       dpyinfo->xim = xim;
 26897 
 26898       if (xim)
 26899         {
 26900 #ifdef HAVE_X11R6_XIM
 26901           XIMCallback destroy;
 26902 #endif
 26903 
 26904           /* Get supported styles and XIM values.  */
 26905           XGetIMValues (xim, XNQueryInputStyle, &dpyinfo->xim_styles, NULL);
 26906 
 26907 #ifdef HAVE_X11R6_XIM
 26908           destroy.callback = xim_destroy_callback;
 26909           destroy.client_data = (XPointer)dpyinfo;
 26910           XSetIMValues (xim, XNDestroyCallback, &destroy, NULL);
 26911 #endif
 26912 
 26913           locale = XLocaleOfIM (xim);
 26914 
 26915           /* Now try to determine the coding system that should be
 26916              used.  locale is in Host Portable Character Encoding, and
 26917              as such can be passed to build_string as is.  */
 26918           dpyinfo->xim_coding = safe_call1 (Vx_input_coding_function,
 26919                                             build_string (locale));
 26920         }
 26921     }
 26922   else
 26923 #endif /* HAVE_XIM */
 26924     dpyinfo->xim = NULL;
 26925 }
 26926 
 26927 
 26928 #ifdef HAVE_X11R6_XIM
 26929 
 26930 /* XIM instantiate callback function, which is called whenever an XIM
 26931    server is available.  DISPLAY is the display of the XIM.
 26932    CLIENT_DATA contains a pointer to an xim_inst_t structure created
 26933    when the callback was registered.  */
 26934 
 26935 static void
 26936 xim_instantiate_callback (Display *display, XPointer client_data, XPointer call_data)
 26937 {
 26938   struct xim_inst_t *xim_inst = (struct xim_inst_t *) client_data;
 26939   struct x_display_info *dpyinfo = xim_inst->dpyinfo;
 26940 
 26941   if (x_dnd_in_progress)
 26942     return;
 26943 
 26944   /* We don't support multiple XIM connections. */
 26945   if (dpyinfo->xim)
 26946     return;
 26947 
 26948   xim_open_dpy (dpyinfo, xim_inst->resource_name);
 26949 
 26950   /* Create XIC for the existing frames on the same display, as long
 26951      as they have no XIC.  */
 26952   if (dpyinfo->xim && dpyinfo->reference_count > 0)
 26953     {
 26954       Lisp_Object tail, frame;
 26955 
 26956       block_input ();
 26957       FOR_EACH_FRAME (tail, frame)
 26958         {
 26959           struct frame *f = XFRAME (frame);
 26960 
 26961           if (FRAME_X_P (f)
 26962               && FRAME_DISPLAY_INFO (f) == xim_inst->dpyinfo)
 26963             if (FRAME_XIC (f) == NULL)
 26964               {
 26965                 create_frame_xic (f);
 26966                 if (FRAME_XIC_STYLE (f) & XIMStatusArea)
 26967                   xic_set_statusarea (f);
 26968                 struct window *w = XWINDOW (f->selected_window);
 26969                 xic_set_preeditarea (w, w->cursor.x, w->cursor.y);
 26970               }
 26971         }
 26972 
 26973       unblock_input ();
 26974     }
 26975 }
 26976 
 26977 #endif /* HAVE_X11R6_XIM */
 26978 
 26979 
 26980 /* Open a connection to the XIM server on display DPYINFO.
 26981    RESOURCE_NAME is the resource name for Emacs.  On X11R5, open the
 26982    connection only at the first time.  On X11R6, open the connection
 26983    in the XIM instantiate callback function.  */
 26984 
 26985 static void
 26986 xim_initialize (struct x_display_info *dpyinfo, char *resource_name)
 26987 {
 26988   dpyinfo->xim = NULL;
 26989 #ifdef HAVE_XIM
 26990   if (dpyinfo->use_xim)
 26991     {
 26992 #ifdef HAVE_X11R6_XIM
 26993       struct xim_inst_t *xim_inst = xmalloc (sizeof *xim_inst);
 26994       Bool ret;
 26995 
 26996       dpyinfo->xim_callback_data = xim_inst;
 26997       xim_inst->dpyinfo = dpyinfo;
 26998       xim_inst->resource_name = xstrdup (resource_name);
 26999 
 27000       /* The last argument is XPointer in XFree86 but (XPointer *) on
 27001          Tru64, at least, but the configure test doesn't work because
 27002          xim_instantiate_callback can either be XIMProc or XIDProc, so
 27003          just cast to void *.  */
 27004 
 27005       ret = XRegisterIMInstantiateCallback (dpyinfo->display,
 27006                                             dpyinfo->rdb,
 27007                                             xim_inst->resource_name,
 27008                                             emacs_class,
 27009                                             xim_instantiate_callback,
 27010                                             (void *) xim_inst);
 27011       eassert (ret);
 27012 #else /* not HAVE_X11R6_XIM */
 27013       xim_open_dpy (dpyinfo, resource_name);
 27014 #endif /* not HAVE_X11R6_XIM */
 27015     }
 27016 #endif /* HAVE_XIM */
 27017 }
 27018 
 27019 
 27020 /* Close the connection to the XIM server on display DPYINFO.
 27021    Unregister any IM instantiation callback previously installed,
 27022    close the connection to the IM server if possible, and free any
 27023    retrieved IM values.  */
 27024 
 27025 static void
 27026 xim_close_dpy (struct x_display_info *dpyinfo)
 27027 {
 27028 #ifdef HAVE_XIM
 27029 #ifdef HAVE_X11R6_XIM
 27030   struct xim_inst_t *xim_inst;
 27031   Bool rc;
 27032 
 27033   /* If dpyinfo->xim_callback_data is not set, then IM support wasn't
 27034      initialized, which can happen if Xlib doesn't understand the C
 27035      locale being used.  */
 27036 
 27037   if (dpyinfo->xim_callback_data)
 27038     {
 27039       xim_inst = dpyinfo->xim_callback_data;
 27040 
 27041       if (dpyinfo->display)
 27042         {
 27043           rc = XUnregisterIMInstantiateCallback (dpyinfo->display,
 27044                                                  dpyinfo->rdb,
 27045                                                  xim_inst->resource_name,
 27046                                                  emacs_class,
 27047                                                  xim_instantiate_callback,
 27048                                                  (void *) xim_inst);
 27049           eassert (rc);
 27050         }
 27051 
 27052       xfree (xim_inst->resource_name);
 27053       xfree (xim_inst);
 27054     }
 27055 #endif /* HAVE_X11R6_XIM */
 27056 
 27057   /* Now close the connection to the input method server.  This may
 27058      access the display connection, and isn't safe if the display has
 27059      already been closed.  */
 27060 
 27061   if (dpyinfo->display && dpyinfo->xim)
 27062     XCloseIM (dpyinfo->xim);
 27063   dpyinfo->xim = NULL;
 27064 
 27065   /* Free the list of XIM styles retrieved.  */
 27066 
 27067   if (dpyinfo->xim_styles)
 27068     XFree (dpyinfo->xim_styles);
 27069   dpyinfo->xim_styles = NULL;
 27070 #endif /* HAVE_XIM */
 27071 }
 27072 
 27073 #endif /* not HAVE_X11R6_XIM */
 27074 
 27075 
 27076 
 27077 /* Calculate the absolute position in frame F
 27078    from its current recorded position values and gravity.  */
 27079 
 27080 static void
 27081 x_calc_absolute_position (struct frame *f)
 27082 {
 27083   int flags = f->size_hint_flags;
 27084   struct frame *p = FRAME_PARENT_FRAME (f);
 27085 
 27086   /* We have nothing to do if the current position
 27087      is already for the top-left corner.  */
 27088   if (! ((flags & XNegative) || (flags & YNegative)))
 27089     return;
 27090 
 27091   /* Treat negative positions as relative to the leftmost bottommost
 27092      position that fits on the screen.  */
 27093   if ((flags & XNegative) && (f->left_pos <= 0))
 27094     {
 27095       int width = FRAME_PIXEL_WIDTH (f);
 27096 
 27097       /* A frame that has been visible at least once should have outer
 27098          edges.  */
 27099       if (f->output_data.x->has_been_visible && !p)
 27100         {
 27101           Lisp_Object frame;
 27102           Lisp_Object edges = Qnil;
 27103 
 27104           XSETFRAME (frame, f);
 27105           edges = Fx_frame_edges (frame, Qouter_edges);
 27106           if (!NILP (edges))
 27107             width = (XFIXNUM (Fnth (make_fixnum (2), edges))
 27108                      - XFIXNUM (Fnth (make_fixnum (0), edges)));
 27109         }
 27110 
 27111       if (p)
 27112         f->left_pos = (FRAME_PIXEL_WIDTH (p) - width - 2 * f->border_width
 27113                        + f->left_pos);
 27114       else
 27115         f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f))
 27116                        - width + f->left_pos);
 27117 
 27118     }
 27119 
 27120   if ((flags & YNegative) && (f->top_pos <= 0))
 27121     {
 27122       int height = FRAME_PIXEL_HEIGHT (f);
 27123 
 27124 #if defined USE_X_TOOLKIT && defined USE_MOTIF
 27125       /* Something is fishy here.  When using Motif, starting Emacs with
 27126          `-g -0-0', the frame appears too low by a few pixels.
 27127 
 27128          This seems to be so because initially, while Emacs is starting,
 27129          the column widget's height and the frame's pixel height are
 27130          different.  The column widget's height is the right one.  In
 27131          later invocations, when Emacs is up, the frame's pixel height
 27132          is right, though.
 27133 
 27134          It's not obvious where the initial small difference comes from.
 27135          2000-12-01, gerd.  */
 27136 
 27137       XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL);
 27138 #endif
 27139 
 27140       if (f->output_data.x->has_been_visible && !p)
 27141         {
 27142           Lisp_Object frame;
 27143           Lisp_Object edges = Qnil;
 27144 
 27145           XSETFRAME (frame, f);
 27146           if (NILP (edges))
 27147             edges = Fx_frame_edges (frame, Qouter_edges);
 27148           if (!NILP (edges))
 27149             height = (XFIXNUM (Fnth (make_fixnum (3), edges))
 27150                       - XFIXNUM (Fnth (make_fixnum (1), edges)));
 27151         }
 27152 
 27153       if (p)
 27154         f->top_pos = (FRAME_PIXEL_HEIGHT (p) - height - 2 * f->border_width
 27155                        + f->top_pos);
 27156       else
 27157         f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f))
 27158                       - height + f->top_pos);
 27159   }
 27160 
 27161   /* The left_pos and top_pos
 27162      are now relative to the top and left screen edges,
 27163      so the flags should correspond.  */
 27164   f->size_hint_flags &= ~ (XNegative | YNegative);
 27165 }
 27166 
 27167 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
 27168    to really change the position, and 0 when calling from
 27169    x_make_frame_visible (in that case, XOFF and YOFF are the current
 27170    position values).  It is -1 when calling from gui_set_frame_parameters,
 27171    which means, do adjust for borders but don't change the gravity.  */
 27172 
 27173 static void
 27174 x_set_offset (struct frame *f, int xoff, int yoff, int change_gravity)
 27175 {
 27176   int modified_top, modified_left;
 27177 #ifdef USE_GTK
 27178   int scale = xg_get_scale (f);
 27179 #endif
 27180 
 27181   if (change_gravity > 0)
 27182     {
 27183       f->top_pos = yoff;
 27184       f->left_pos = xoff;
 27185       f->size_hint_flags &= ~ (XNegative | YNegative);
 27186       if (xoff < 0)
 27187         f->size_hint_flags |= XNegative;
 27188       if (yoff < 0)
 27189         f->size_hint_flags |= YNegative;
 27190       f->win_gravity = NorthWestGravity;
 27191     }
 27192 
 27193   x_calc_absolute_position (f);
 27194 
 27195   block_input ();
 27196   x_wm_set_size_hint (f, 0, false);
 27197 
 27198 #ifdef USE_GTK
 27199   if (x_gtk_use_window_move)
 27200     {
 27201       /* When a position change was requested and the outer GTK widget
 27202          has been realized already, leave it to gtk_window_move to
 27203          DTRT and return.  Used for Bug#25851 and Bug#25943.  Convert
 27204          from X pixels to GTK scaled pixels.  */
 27205       if (change_gravity != 0 && FRAME_GTK_OUTER_WIDGET (f))
 27206         gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
 27207                          f->left_pos / scale, f->top_pos / scale);
 27208       unblock_input ();
 27209       return;
 27210     }
 27211 #endif /* USE_GTK */
 27212 
 27213   modified_left = f->left_pos;
 27214   modified_top = f->top_pos;
 27215 
 27216   if (change_gravity != 0 && FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
 27217     {
 27218       /* Some WMs (twm, wmaker at least) has an offset that is smaller
 27219          than the WM decorations.  So we use the calculated offset instead
 27220          of the WM decoration sizes here (x/y_pixels_outer_diff).  */
 27221       modified_left += FRAME_X_OUTPUT (f)->move_offset_left;
 27222       modified_top += FRAME_X_OUTPUT (f)->move_offset_top;
 27223     }
 27224 
 27225 #ifdef USE_GTK
 27226   /* Make sure we adjust for possible scaling.  */
 27227   gtk_window_move (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
 27228                    modified_left / scale, modified_top / scale);
 27229 #else
 27230   XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 27231                modified_left, modified_top);
 27232 #endif
 27233 
 27234   /* The following code is too slow over a latent network
 27235      connection.  */
 27236   if (NILP (Vx_lax_frame_positioning))
 27237     {
 27238       /* 'x_sync_with_move' is too costly for dragging child frames.  */
 27239       if (!FRAME_PARENT_FRAME (f)
 27240           /* If no window manager exists, just calling XSync will be
 27241              sufficient to ensure that the window geometry has been
 27242              updated.  */
 27243           && NILP (Vx_no_window_manager))
 27244         {
 27245           x_sync_with_move (f, f->left_pos, f->top_pos,
 27246                             FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN);
 27247 
 27248           /* change_gravity is non-zero when this function is called from Lisp to
 27249              programmatically move a frame.  In that case, we call
 27250              x_check_expected_move to discover if we have a "Type A" or "Type B"
 27251              window manager, and, for a "Type A" window manager, adjust the position
 27252              of the frame.
 27253 
 27254              We call x_check_expected_move if a programmatic move occurred, and
 27255              either the window manager type (A/B) is unknown or it is Type A but we
 27256              need to compute the top/left offset adjustment for this frame.  */
 27257 
 27258           if (change_gravity != 0
 27259               && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
 27260                   || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
 27261                       && (FRAME_X_OUTPUT (f)->move_offset_left == 0
 27262                           && FRAME_X_OUTPUT (f)->move_offset_top == 0))))
 27263             x_check_expected_move (f, modified_left, modified_top);
 27264         }
 27265       /* Instead, just wait for the last ConfigureWindow request to
 27266          complete.  No window manager is involved when moving child
 27267          frames.  */
 27268       else
 27269         XSync (FRAME_X_DISPLAY (f), False);
 27270     }
 27271 
 27272   unblock_input ();
 27273 }
 27274 
 27275 static Window
 27276 x_get_wm_check_window (struct x_display_info *dpyinfo)
 27277 {
 27278   Window result;
 27279   unsigned char *tmp_data = NULL;
 27280   int rc, actual_format;
 27281   unsigned long actual_size, bytes_remaining;
 27282   Atom actual_type;
 27283 
 27284   rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
 27285                            dpyinfo->Xatom_net_supporting_wm_check,
 27286                            0, 1, False, XA_WINDOW, &actual_type,
 27287                            &actual_format, &actual_size,
 27288                            &bytes_remaining, &tmp_data);
 27289 
 27290   if (rc != Success || actual_type != XA_WINDOW
 27291       || actual_format != 32 || actual_size != 1)
 27292     {
 27293       if (tmp_data)
 27294         XFree (tmp_data);
 27295 
 27296       return None;
 27297     }
 27298 
 27299   result = *(Window *) tmp_data;
 27300   XFree (tmp_data);
 27301 
 27302   return result;
 27303 }
 27304 
 27305 /* Return true if _NET_SUPPORTING_WM_CHECK window exists and _NET_SUPPORTED
 27306    on the root window for frame F contains ATOMNAME.
 27307    This is how a WM check shall be done according to the Window Manager
 27308    Specification/Extended Window Manager Hints at
 27309    https://freedesktop.org/wiki/Specifications/wm-spec/.  */
 27310 
 27311 bool
 27312 x_wm_supports_1 (struct x_display_info *dpyinfo, Atom want_atom)
 27313 {
 27314   Atom actual_type;
 27315   unsigned long actual_size, bytes_remaining;
 27316   int i, rc, actual_format;
 27317   bool ret;
 27318   Window wmcheck_window;
 27319   Window target_window = dpyinfo->root_window;
 27320   int max_len = 65536;
 27321   Display *dpy = dpyinfo->display;
 27322   unsigned char *tmp_data = NULL;
 27323   Atom target_type = XA_WINDOW;
 27324 
 27325   /* The user says there's no window manager, so take him up on
 27326      it.  */
 27327   if (!NILP (Vx_no_window_manager))
 27328     return false;
 27329 
 27330   /* If the window system says Emacs is untrusted, there will be no
 27331      way to send any information to the window manager, making any
 27332      hints useless.  */
 27333   if (dpyinfo->untrusted)
 27334     return false;
 27335 
 27336   block_input ();
 27337 
 27338   x_catch_errors (dpy);
 27339 
 27340   wmcheck_window = dpyinfo->net_supported_window;
 27341 
 27342   if (wmcheck_window == None)
 27343     wmcheck_window = x_get_wm_check_window (dpyinfo);
 27344 
 27345   if (!x_special_window_exists_p (dpyinfo, wmcheck_window))
 27346     {
 27347       if (dpyinfo->net_supported_window != None)
 27348         {
 27349           dpyinfo->net_supported_window = None;
 27350           wmcheck_window = x_get_wm_check_window (dpyinfo);
 27351 
 27352           if (!x_special_window_exists_p (dpyinfo, wmcheck_window))
 27353             {
 27354               x_uncatch_errors ();
 27355               unblock_input ();
 27356               return false;
 27357             }
 27358         }
 27359       else
 27360         {
 27361           x_uncatch_errors ();
 27362           unblock_input ();
 27363           return false;
 27364         }
 27365     }
 27366 
 27367   if (dpyinfo->net_supported_window != wmcheck_window)
 27368     {
 27369       /* Window changed, reload atoms */
 27370       if (dpyinfo->net_supported_atoms != NULL)
 27371         XFree (dpyinfo->net_supported_atoms);
 27372       dpyinfo->net_supported_atoms = NULL;
 27373       dpyinfo->nr_net_supported_atoms = 0;
 27374       dpyinfo->net_supported_window = 0;
 27375 
 27376       target_type = XA_ATOM;
 27377       tmp_data = NULL;
 27378       rc = XGetWindowProperty (dpy, target_window,
 27379                                dpyinfo->Xatom_net_supported,
 27380                                0, max_len, False, target_type,
 27381                                &actual_type, &actual_format, &actual_size,
 27382                                &bytes_remaining, &tmp_data);
 27383 
 27384       if (rc != Success || actual_type != XA_ATOM || x_had_errors_p (dpy))
 27385         {
 27386           if (tmp_data)
 27387             XFree (tmp_data);
 27388           x_uncatch_errors ();
 27389           unblock_input ();
 27390           return false;
 27391         }
 27392 
 27393       dpyinfo->net_supported_atoms = (Atom *) tmp_data;
 27394       dpyinfo->nr_net_supported_atoms = actual_size;
 27395       dpyinfo->net_supported_window = wmcheck_window;
 27396     }
 27397 
 27398   ret = false;
 27399 
 27400   for (i = 0; !ret && i < dpyinfo->nr_net_supported_atoms; ++i)
 27401     ret = dpyinfo->net_supported_atoms[i] == want_atom;
 27402 
 27403   x_uncatch_errors ();
 27404   unblock_input ();
 27405 
 27406   return ret;
 27407 }
 27408 
 27409 bool
 27410 x_wm_supports (struct frame *f, Atom want_atom)
 27411 {
 27412   return x_wm_supports_1 (FRAME_DISPLAY_INFO (f),
 27413                           want_atom);
 27414 }
 27415 
 27416 static void
 27417 set_wm_state (Lisp_Object frame, bool add, Atom atom, Atom value)
 27418 {
 27419   struct x_display_info *dpyinfo;
 27420   XEvent msg;
 27421 
 27422   dpyinfo = FRAME_DISPLAY_INFO (XFRAME (frame));
 27423   msg.xclient.type = ClientMessage;
 27424   msg.xclient.window = FRAME_OUTER_WINDOW (XFRAME (frame));
 27425   msg.xclient.message_type = dpyinfo->Xatom_net_wm_state;
 27426   msg.xclient.format = 32;
 27427 
 27428   msg.xclient.data.l[0] = add ? 1 : 0;
 27429   msg.xclient.data.l[1] = atom;
 27430   msg.xclient.data.l[2] = value;
 27431   msg.xclient.data.l[3] = 1; /* Source indication.  */
 27432   msg.xclient.data.l[4] = 0;
 27433 
 27434   block_input ();
 27435   XSendEvent (dpyinfo->display, dpyinfo->root_window,
 27436               False, (SubstructureRedirectMask
 27437                       | SubstructureNotifyMask), &msg);
 27438   unblock_input ();
 27439 }
 27440 
 27441 void
 27442 x_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 27443 {
 27444   Lisp_Object frame;
 27445   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27446 
 27447   XSETFRAME (frame, f);
 27448 
 27449   set_wm_state (frame, !NILP (new_value),
 27450                 dpyinfo->Xatom_net_wm_state_sticky, None);
 27451 }
 27452 
 27453 void
 27454 x_set_shaded (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 27455 {
 27456   Lisp_Object frame;
 27457   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27458 
 27459   XSETFRAME (frame, f);
 27460 
 27461   set_wm_state (frame, !NILP (new_value),
 27462                 dpyinfo->Xatom_net_wm_state_shaded, None);
 27463 }
 27464 
 27465 /**
 27466  * x_set_skip_taskbar:
 27467  *
 27468  * Set frame F's `skip-taskbar' parameter.  If non-nil, this should
 27469  * remove F's icon from the taskbar associated with the display of F's
 27470  * window-system window and inhibit switching to F's window via
 27471  * <Alt>-<TAB>.  If nil, lift these restrictions.
 27472  *
 27473  * Some window managers may not honor this parameter.
 27474  */
 27475 void
 27476 x_set_skip_taskbar (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 27477 {
 27478   if (!EQ (new_value, old_value))
 27479     {
 27480 #ifdef USE_GTK
 27481       xg_set_skip_taskbar (f, new_value);
 27482 #else
 27483       Lisp_Object frame;
 27484       struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27485 
 27486       XSETFRAME (frame, f);
 27487       set_wm_state (frame, !NILP (new_value),
 27488                     dpyinfo->Xatom_net_wm_state_skip_taskbar, None);
 27489 #endif /* USE_GTK */
 27490       FRAME_SKIP_TASKBAR (f) = !NILP (new_value);
 27491     }
 27492 }
 27493 
 27494 /**
 27495  * x_set_z_group:
 27496  *
 27497  * Set frame F's `z-group' parameter.  If `above', F's window-system
 27498  * window is displayed above all windows that do not have the `above'
 27499  * property set.  If nil, F's window is shown below all windows that
 27500  * have the `above' property set and above all windows that have the
 27501  * `below' property set.  If `below', F's window is displayed below all
 27502  * windows that do not have the `below' property set.
 27503  *
 27504  * Some window managers may not honor this parameter.
 27505  *
 27506  * Internally, this function also handles a value 'above-suspended'.
 27507  * That value is used to temporarily remove F from the 'above' group
 27508  * to make sure that it does not obscure a menu currently popped up.
 27509  */
 27510 void
 27511 x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
 27512 {
 27513   /* We don't care about old_value.  The window manager might have
 27514      reset the value without telling us.  */
 27515   Lisp_Object frame;
 27516   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27517 
 27518   XSETFRAME (frame, f);
 27519 
 27520   if (NILP (new_value))
 27521     {
 27522       set_wm_state (frame, false,
 27523                     dpyinfo->Xatom_net_wm_state_above, None);
 27524       set_wm_state (frame, false,
 27525                     dpyinfo->Xatom_net_wm_state_below, None);
 27526       FRAME_Z_GROUP (f) = z_group_none;
 27527     }
 27528   else if (EQ (new_value, Qabove))
 27529     {
 27530       set_wm_state (frame, true,
 27531                     dpyinfo->Xatom_net_wm_state_above, None);
 27532       set_wm_state (frame, false,
 27533                     dpyinfo->Xatom_net_wm_state_below, None);
 27534       FRAME_Z_GROUP (f) = z_group_above;
 27535     }
 27536   else if (EQ (new_value, Qbelow))
 27537     {
 27538       set_wm_state (frame, false,
 27539                     dpyinfo->Xatom_net_wm_state_above, None);
 27540       set_wm_state (frame, true,
 27541                     dpyinfo->Xatom_net_wm_state_below, None);
 27542       FRAME_Z_GROUP (f) = z_group_below;
 27543     }
 27544   else if (EQ (new_value, Qabove_suspended))
 27545     {
 27546       set_wm_state (frame, false,
 27547                     dpyinfo->Xatom_net_wm_state_above, None);
 27548       FRAME_Z_GROUP (f) = z_group_above_suspended;
 27549     }
 27550   else
 27551     error ("Invalid z-group specification");
 27552 }
 27553 
 27554 
 27555 /* Return the current _NET_WM_STATE.
 27556    SIZE_STATE is set to one of the FULLSCREEN_* values.
 27557    Set *STICKY to the sticky state.
 27558 
 27559    Return true iff we are not hidden.  */
 27560 
 27561 static bool
 27562 x_get_current_wm_state (struct frame *f,
 27563                         Window window,
 27564                         int *size_state,
 27565                         bool *sticky,
 27566                         bool *shaded)
 27567 {
 27568   unsigned long actual_size;
 27569   int i;
 27570   bool is_hidden = false;
 27571   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27572   long max_len = 65536;
 27573   Atom target_type = XA_ATOM;
 27574   /* If XCB is available, we can avoid three XSync calls.  */
 27575 #ifdef USE_XCB
 27576   xcb_get_property_cookie_t prop_cookie;
 27577   xcb_get_property_reply_t *prop;
 27578   typedef xcb_atom_t reply_data_object;
 27579 #else
 27580   Display *dpy = FRAME_X_DISPLAY (f);
 27581   unsigned long bytes_remaining;
 27582   int rc, actual_format;
 27583   Atom actual_type;
 27584   unsigned char *tmp_data = NULL;
 27585   typedef Atom reply_data_object;
 27586 #endif
 27587   reply_data_object *reply_data;
 27588 # if defined GCC_LINT || defined lint
 27589   reply_data_object reply_data_dummy;
 27590   reply_data = &reply_data_dummy;
 27591 # endif
 27592 
 27593   *sticky = false;
 27594   *size_state = FULLSCREEN_NONE;
 27595   *shaded = false;
 27596 
 27597   block_input ();
 27598 
 27599 #ifdef USE_XCB
 27600   prop_cookie = xcb_get_property (dpyinfo->xcb_connection, 0, window,
 27601                                   dpyinfo->Xatom_net_wm_state,
 27602                                   target_type, 0, max_len);
 27603   prop = xcb_get_property_reply (dpyinfo->xcb_connection, prop_cookie, NULL);
 27604   if (prop && prop->type == target_type)
 27605     {
 27606       int actual_bytes = xcb_get_property_value_length (prop);
 27607       eassume (0 <= actual_bytes);
 27608       actual_size = actual_bytes / sizeof *reply_data;
 27609       reply_data = xcb_get_property_value (prop);
 27610     }
 27611   else
 27612     {
 27613       actual_size = 0;
 27614       is_hidden = FRAME_ICONIFIED_P (f);
 27615     }
 27616 #else
 27617   x_catch_errors (dpy);
 27618   rc = XGetWindowProperty (dpy, window, dpyinfo->Xatom_net_wm_state,
 27619                            0, max_len, False, target_type,
 27620                            &actual_type, &actual_format, &actual_size,
 27621                            &bytes_remaining, &tmp_data);
 27622 
 27623   if (rc == Success && actual_type == target_type && ! x_had_errors_p (dpy))
 27624     reply_data = (Atom *) tmp_data;
 27625   else
 27626     {
 27627       actual_size = 0;
 27628       is_hidden = FRAME_ICONIFIED_P (f);
 27629     }
 27630 
 27631   x_uncatch_errors ();
 27632 #endif
 27633 
 27634   for (i = 0; i < actual_size; ++i)
 27635     {
 27636       Atom a = reply_data[i];
 27637       if (a == dpyinfo->Xatom_net_wm_state_hidden)
 27638         is_hidden = true;
 27639       else if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
 27640         {
 27641           if (*size_state == FULLSCREEN_HEIGHT)
 27642             *size_state = FULLSCREEN_MAXIMIZED;
 27643           else
 27644             *size_state = FULLSCREEN_WIDTH;
 27645         }
 27646       else if (a == dpyinfo->Xatom_net_wm_state_maximized_vert)
 27647         {
 27648           if (*size_state == FULLSCREEN_WIDTH)
 27649             *size_state = FULLSCREEN_MAXIMIZED;
 27650           else
 27651             *size_state = FULLSCREEN_HEIGHT;
 27652         }
 27653       else if (a == dpyinfo->Xatom_net_wm_state_fullscreen)
 27654         *size_state = FULLSCREEN_BOTH;
 27655       else if (a == dpyinfo->Xatom_net_wm_state_sticky)
 27656         *sticky = true;
 27657       else if (a == dpyinfo->Xatom_net_wm_state_shaded)
 27658         *shaded = true;
 27659     }
 27660 
 27661 #ifdef USE_XCB
 27662   free (prop);
 27663 #else
 27664   if (tmp_data) XFree (tmp_data);
 27665 #endif
 27666 
 27667   unblock_input ();
 27668   return ! is_hidden;
 27669 }
 27670 
 27671 /* Do fullscreen as specified in extended window manager hints */
 27672 
 27673 static bool
 27674 do_ewmh_fullscreen (struct frame *f)
 27675 {
 27676   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27677   bool have_net_atom = x_wm_supports (f, dpyinfo->Xatom_net_wm_state);
 27678   int cur;
 27679   bool dummy;
 27680 
 27681   x_get_current_wm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy, &dummy);
 27682 
 27683   /* Some window managers don't say they support _NET_WM_STATE, but they do say
 27684      they support _NET_WM_STATE_FULLSCREEN.  Try that also.  */
 27685   if (!have_net_atom)
 27686     have_net_atom = x_wm_supports (f, dpyinfo->Xatom_net_wm_state_fullscreen);
 27687 
 27688   if (have_net_atom && cur != f->want_fullscreen)
 27689     {
 27690       Lisp_Object frame;
 27691 
 27692       XSETFRAME (frame, f);
 27693 
 27694       /* Keep number of calls to set_wm_state as low as possible.
 27695          Some window managers, or possible Gtk+, hangs when too many
 27696          are sent at once.  */
 27697       switch (f->want_fullscreen)
 27698         {
 27699         case FULLSCREEN_BOTH:
 27700           if (cur != FULLSCREEN_BOTH)
 27701             set_wm_state (frame, true, dpyinfo->Xatom_net_wm_state_fullscreen,
 27702                           None);
 27703           break;
 27704         case FULLSCREEN_WIDTH:
 27705           if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED)
 27706             {
 27707               set_wm_state (frame, false,
 27708                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27709                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27710               set_wm_state (frame, true,
 27711                             dpyinfo->Xatom_net_wm_state_maximized_horz, None);
 27712             }
 27713           else
 27714             {
 27715               if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT
 27716                   || cur == FULLSCREEN_MAXIMIZED)
 27717                 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
 27718                               dpyinfo->Xatom_net_wm_state_maximized_vert);
 27719               if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize)
 27720                 set_wm_state (frame, true,
 27721                               dpyinfo->Xatom_net_wm_state_maximized_horz, None);
 27722             }
 27723           break;
 27724         case FULLSCREEN_HEIGHT:
 27725           if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED)
 27726             {
 27727               set_wm_state (frame, false,
 27728                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27729                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27730               set_wm_state (frame, true,
 27731                             dpyinfo->Xatom_net_wm_state_maximized_vert, None);
 27732             }
 27733           else
 27734             {
 27735               if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH
 27736                   || cur == FULLSCREEN_MAXIMIZED)
 27737                 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
 27738                               dpyinfo->Xatom_net_wm_state_maximized_horz);
 27739               if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize)
 27740                 set_wm_state (frame, true,
 27741                               dpyinfo->Xatom_net_wm_state_maximized_vert, None);
 27742             }
 27743           break;
 27744         case FULLSCREEN_MAXIMIZED:
 27745           if (x_frame_normalize_before_maximize && cur == FULLSCREEN_BOTH)
 27746             {
 27747               set_wm_state (frame, false,
 27748                             dpyinfo->Xatom_net_wm_state_fullscreen, None);
 27749               set_wm_state (frame, true,
 27750                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27751                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27752             }
 27753           else if (x_frame_normalize_before_maximize && cur == FULLSCREEN_WIDTH)
 27754             {
 27755               set_wm_state (frame, false,
 27756                             dpyinfo->Xatom_net_wm_state_maximized_horz, None);
 27757               set_wm_state (frame, true,
 27758                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27759                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27760             }
 27761           else if (x_frame_normalize_before_maximize && cur == FULLSCREEN_HEIGHT)
 27762             {
 27763               set_wm_state (frame, false,
 27764                             dpyinfo->Xatom_net_wm_state_maximized_vert, None);
 27765               set_wm_state (frame, true,
 27766                             dpyinfo->Xatom_net_wm_state_maximized_horz,
 27767                             dpyinfo->Xatom_net_wm_state_maximized_vert);
 27768             }
 27769           else
 27770             {
 27771               if (cur == FULLSCREEN_BOTH)
 27772                 set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
 27773                               None);
 27774               else if (cur == FULLSCREEN_HEIGHT)
 27775                 set_wm_state (frame, true,
 27776                               dpyinfo->Xatom_net_wm_state_maximized_horz, None);
 27777               else if (cur == FULLSCREEN_WIDTH)
 27778                 set_wm_state (frame, true, None,
 27779                               dpyinfo->Xatom_net_wm_state_maximized_vert);
 27780               else
 27781                 set_wm_state (frame, true,
 27782                               dpyinfo->Xatom_net_wm_state_maximized_horz,
 27783                               dpyinfo->Xatom_net_wm_state_maximized_vert);
 27784             }
 27785           break;
 27786         case FULLSCREEN_NONE:
 27787           if (cur == FULLSCREEN_BOTH)
 27788             set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen,
 27789                           None);
 27790           else
 27791             set_wm_state (frame, false,
 27792                           dpyinfo->Xatom_net_wm_state_maximized_horz,
 27793                           dpyinfo->Xatom_net_wm_state_maximized_vert);
 27794         }
 27795 
 27796       f->want_fullscreen = FULLSCREEN_NONE;
 27797 
 27798     }
 27799 
 27800   return have_net_atom;
 27801 }
 27802 
 27803 static void
 27804 XTfullscreen_hook (struct frame *f)
 27805 {
 27806   if (!FRAME_VISIBLE_P (f))
 27807     return;
 27808 
 27809   block_input ();
 27810   x_check_fullscreen (f);
 27811   unblock_input ();
 27812 }
 27813 
 27814 
 27815 static bool
 27816 x_handle_net_wm_state (struct frame *f, const XPropertyEvent *event)
 27817 {
 27818   int value = FULLSCREEN_NONE;
 27819   Lisp_Object lval;
 27820   bool sticky = false, shaded = false;
 27821   bool not_hidden = x_get_current_wm_state (f, event->window,
 27822                                             &value, &sticky,
 27823                                             &shaded);
 27824 
 27825   lval = Qnil;
 27826   switch (value)
 27827     {
 27828     case FULLSCREEN_WIDTH:
 27829       lval = Qfullwidth;
 27830       break;
 27831     case FULLSCREEN_HEIGHT:
 27832       lval = Qfullheight;
 27833       break;
 27834     case FULLSCREEN_BOTH:
 27835       lval = Qfullboth;
 27836       break;
 27837     case FULLSCREEN_MAXIMIZED:
 27838       lval = Qmaximized;
 27839       break;
 27840     }
 27841 
 27842   store_frame_param (f, Qfullscreen, lval);
 27843   store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
 27844   store_frame_param (f, Qshaded, shaded ? Qt : Qnil);
 27845 
 27846   return not_hidden;
 27847 }
 27848 
 27849 /* Check if we need to resize the frame due to a fullscreen request.
 27850    If so needed, resize the frame. */
 27851 static void
 27852 x_check_fullscreen (struct frame *f)
 27853 {
 27854   Lisp_Object lval = Qnil;
 27855 
 27856   if (do_ewmh_fullscreen (f))
 27857     return;
 27858 
 27859   if (f->output_data.x->parent_desc != FRAME_DISPLAY_INFO (f)->root_window)
 27860     return; /* Only fullscreen without WM or with EWM hints (above). */
 27861 
 27862   /* Setting fullscreen to nil doesn't do anything.  We could save the
 27863      last non-fullscreen size and restore it, but it seems like a
 27864      lot of work for this unusual case (no window manager running).  */
 27865 
 27866   if (f->want_fullscreen != FULLSCREEN_NONE)
 27867     {
 27868       int width = FRAME_PIXEL_WIDTH (f), height = FRAME_PIXEL_HEIGHT (f);
 27869       struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 27870 
 27871       switch (f->want_fullscreen)
 27872         {
 27873           /* No difference between these two when there is no WM */
 27874         case FULLSCREEN_MAXIMIZED:
 27875           lval = Qmaximized;
 27876           width = x_display_pixel_width (dpyinfo);
 27877           height = x_display_pixel_height (dpyinfo);
 27878           break;
 27879         case FULLSCREEN_BOTH:
 27880           lval = Qfullboth;
 27881           width = x_display_pixel_width (dpyinfo);
 27882           height = x_display_pixel_height (dpyinfo);
 27883           break;
 27884         case FULLSCREEN_WIDTH:
 27885           lval = Qfullwidth;
 27886           width = x_display_pixel_width (dpyinfo);
 27887           height = height + FRAME_MENUBAR_HEIGHT (f);
 27888           break;
 27889         case FULLSCREEN_HEIGHT:
 27890           lval = Qfullheight;
 27891           height = x_display_pixel_height (dpyinfo);
 27892           break;
 27893         default:
 27894           emacs_abort ();
 27895         }
 27896 
 27897       x_wm_set_size_hint (f, 0, false);
 27898 
 27899       XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 27900                      width, height);
 27901 
 27902       if (FRAME_VISIBLE_P (f))
 27903         x_wait_for_event (f, ConfigureNotify);
 27904       else
 27905         change_frame_size (f, width, height, false, true, false);
 27906     }
 27907 
 27908   /* `x_net_wm_state' might have reset the fullscreen frame parameter,
 27909      restore it. */
 27910   store_frame_param (f, Qfullscreen, lval);
 27911 }
 27912 
 27913 /* This function is called by x_set_offset to determine whether the window
 27914    manager interfered with the positioning of the frame.  Type A window
 27915    managers position the surrounding window manager decorations a small
 27916    amount above and left of the user-supplied position.  Type B window
 27917    managers position the surrounding window manager decorations at the
 27918    user-specified position.  If we detect a Type A window manager, we
 27919    compensate by moving the window right and down by the proper amount.  */
 27920 
 27921 static void
 27922 x_check_expected_move (struct frame *f, int expected_left, int expected_top)
 27923 {
 27924   int current_left = 0, current_top = 0;
 27925 
 27926   /* x_real_positions returns the left and top offsets of the outermost
 27927      window manager window around the frame.  */
 27928 
 27929   x_real_positions (f, &current_left, &current_top);
 27930 
 27931   if (current_left != expected_left || current_top != expected_top)
 27932     {
 27933       /* It's a "Type A" window manager. */
 27934 
 27935       int adjusted_left;
 27936       int adjusted_top;
 27937 
 27938       FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A;
 27939       FRAME_X_OUTPUT (f)->move_offset_left = expected_left - current_left;
 27940       FRAME_X_OUTPUT (f)->move_offset_top = expected_top - current_top;
 27941 
 27942       /* Now fix the mispositioned frame's location. */
 27943 
 27944       adjusted_left = expected_left + FRAME_X_OUTPUT (f)->move_offset_left;
 27945       adjusted_top = expected_top + FRAME_X_OUTPUT (f)->move_offset_top;
 27946 
 27947       XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 27948                    adjusted_left, adjusted_top);
 27949 
 27950       x_sync_with_move (f, expected_left, expected_top, false);
 27951     }
 27952   else
 27953     /* It's a "Type B" window manager.  We don't have to adjust the
 27954        frame's position. */
 27955       FRAME_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;
 27956 }
 27957 
 27958 
 27959 /* Wait for XGetGeometry to return up-to-date position information for a
 27960    recently-moved frame.  Call this immediately after calling XMoveWindow.
 27961    If FUZZY is non-zero, then LEFT and TOP are just estimates of where the
 27962    frame has been moved to, so we use a fuzzy position comparison instead
 27963    of an exact comparison.  */
 27964 
 27965 static void
 27966 x_sync_with_move (struct frame *f, int left, int top, bool fuzzy)
 27967 {
 27968   sigset_t emptyset;
 27969   int count, current_left, current_top;
 27970   struct timespec fallback;
 27971 
 27972   sigemptyset (&emptyset);
 27973   count = 0;
 27974 
 27975   while (count++ < 50)
 27976     {
 27977       current_left = 0;
 27978       current_top = 0;
 27979 
 27980       /* There is no need to call XSync (even when no window manager
 27981          is present) because x_real_positions already does that
 27982          implicitly.  */
 27983       x_real_positions (f, &current_left, &current_top);
 27984 
 27985       if (fuzzy)
 27986         {
 27987           /* The left fuzz-factor is 10 pixels.  The top fuzz-factor is 40
 27988              pixels.  */
 27989 
 27990           if (eabs (current_left - left) <= 10
 27991               && eabs (current_top - top) <= 40)
 27992             return;
 27993         }
 27994       else if (current_left == left && current_top == top)
 27995         return;
 27996     }
 27997 
 27998   /* As a last resort, just wait 0.5 seconds and hope that XGetGeometry
 27999      will then return up-to-date position info. */
 28000 
 28001   fallback = dtotimespec (0.5);
 28002 
 28003   /* This will hang if input is blocked, so use pselect to wait
 28004      instead.  */
 28005   if (input_blocked_p ())
 28006     pselect (0, NULL, NULL, NULL, &fallback, &emptyset);
 28007   else
 28008     wait_reading_process_output (0, 500000000, 0, false, Qnil, NULL, 0);
 28009 }
 28010 
 28011 /* Wait for an event on frame F matching EVENTTYPE.  */
 28012 void
 28013 x_wait_for_event (struct frame *f, int eventtype)
 28014 {
 28015   if (!FLOATP (Vx_wait_for_event_timeout))
 28016     return;
 28017 
 28018   int level = interrupt_input_blocked;
 28019   fd_set fds;
 28020   struct timespec tmo, tmo_at, time_now;
 28021   int fd = ConnectionNumber (FRAME_X_DISPLAY (f));
 28022 
 28023   f->wait_event_type = eventtype;
 28024 
 28025   /* Default timeout is 0.1 second.  Hopefully not noticeable.  */
 28026   double timeout = XFLOAT_DATA (Vx_wait_for_event_timeout);
 28027   time_t timeout_seconds = (time_t) timeout;
 28028   tmo = make_timespec
 28029     (timeout_seconds, (long int) ((timeout - timeout_seconds)
 28030                                   * 1000 * 1000 * 1000));
 28031   tmo_at = timespec_add (current_timespec (), tmo);
 28032 
 28033   while (f->wait_event_type)
 28034     {
 28035       pending_signals = true;
 28036       totally_unblock_input ();
 28037       /* XTread_socket is called after unblock.  */
 28038       block_input ();
 28039       interrupt_input_blocked = level;
 28040 
 28041       FD_ZERO (&fds);
 28042       FD_SET (fd, &fds);
 28043 
 28044       time_now = current_timespec ();
 28045       if (timespec_cmp (tmo_at, time_now) < 0)
 28046         break;
 28047 
 28048       tmo = timespec_sub (tmo_at, time_now);
 28049       if (pselect (fd + 1, &fds, NULL, NULL, &tmo, NULL) == 0)
 28050         break; /* Timeout */
 28051     }
 28052 
 28053   f->wait_event_type = 0;
 28054 }
 28055 
 28056 
 28057 /* Change the size of frame F's X window to WIDTH/HEIGHT in the case F
 28058    doesn't have a widget.  If CHANGE_GRAVITY, change to
 28059    top-left-corner window gravity for this size change and subsequent
 28060    size changes.  Otherwise leave the window gravity unchanged.  */
 28061 
 28062 static void
 28063 x_set_window_size_1 (struct frame *f, bool change_gravity,
 28064                      int width, int height)
 28065 {
 28066   if (change_gravity)
 28067     f->win_gravity = NorthWestGravity;
 28068   x_wm_set_size_hint (f, 0, false);
 28069 
 28070   XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28071                  width, height + FRAME_MENUBAR_HEIGHT (f));
 28072 
 28073   /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
 28074      receive in the ConfigureNotify event; if we get what we asked
 28075      for, then the event won't cause the screen to become garbaged, so
 28076      we have to make sure to do it here.  */
 28077   SET_FRAME_GARBAGED (f);
 28078 
 28079   /* The following code is too slow over a latent network
 28080      connection, so skip it when the user says so.  */
 28081 
 28082   if (!NILP (Vx_lax_frame_positioning))
 28083     return;
 28084 
 28085   /* Now, strictly speaking, we can't be sure that this is accurate,
 28086      but the window manager will get around to dealing with the size
 28087      change request eventually, and we'll hear how it went when the
 28088      ConfigureNotify event gets here.
 28089 
 28090      We could just not bother storing any of this information here,
 28091      and let the ConfigureNotify event set everything up, but that
 28092      might be kind of confusing to the Lisp code, since size changes
 28093      wouldn't be reported in the frame parameters until some random
 28094      point in the future when the ConfigureNotify event arrives.
 28095 
 28096      Pass true for DELAY since we can't run Lisp code inside of
 28097      a BLOCK_INPUT.  */
 28098 
 28099   /* But the ConfigureNotify may in fact never arrive, and then this is
 28100      not right if the frame is visible.  Instead wait (with timeout)
 28101      for the ConfigureNotify.  */
 28102   if (FRAME_VISIBLE_P (f))
 28103     {
 28104       x_wait_for_event (f, ConfigureNotify);
 28105 
 28106       if (CONSP (frame_size_history))
 28107         frame_size_history_extra
 28108           (f, build_string ("x_set_window_size_1, visible"),
 28109            FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height,
 28110            f->new_width, f->new_height);
 28111     }
 28112   else
 28113     {
 28114       if (CONSP (frame_size_history))
 28115         frame_size_history_extra
 28116           (f, build_string ("x_set_window_size_1, invisible"),
 28117            FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), width, height,
 28118            f->new_width, f->new_height);
 28119 
 28120       /* Call adjust_frame_size right away as with GTK.  It might be
 28121          tempting to clear out f->new_width and f->new_height here.  */
 28122       adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, width),
 28123                          FRAME_PIXEL_TO_TEXT_HEIGHT (f, height),
 28124                          5, 0, Qx_set_window_size_1);
 28125     }
 28126 }
 28127 
 28128 
 28129 /* Change the size of frame F's X window to WIDTH and HEIGHT pixels.  If
 28130    CHANGE_GRAVITY, change to top-left-corner window gravity for this
 28131    size change and subsequent size changes.  Otherwise we leave the
 28132    window gravity unchanged.  */
 28133 
 28134 void
 28135 x_set_window_size (struct frame *f, bool change_gravity,
 28136                    int width, int height)
 28137 {
 28138   block_input ();
 28139 
 28140 #ifdef USE_GTK
 28141   if (FRAME_GTK_WIDGET (f))
 28142     xg_frame_set_char_size (f, width, height);
 28143   else
 28144     x_set_window_size_1 (f, change_gravity, width, height);
 28145 #else /* not USE_GTK */
 28146   x_set_window_size_1 (f, change_gravity, width, height);
 28147   x_clear_under_internal_border (f);
 28148 #endif /* not USE_GTK */
 28149 
 28150   /* If cursor was outside the new size, mark it as off.  */
 28151   mark_window_cursors_off (XWINDOW (f->root_window));
 28152 
 28153   /* Clear out any recollection of where the mouse highlighting was,
 28154      since it might be in a place that's outside the new frame size.
 28155      Actually checking whether it is outside is a pain in the neck,
 28156      so don't try--just let the highlighting be done afresh with new size.  */
 28157   cancel_mouse_face (f);
 28158 
 28159   unblock_input ();
 28160 
 28161   do_pending_window_change (false);
 28162 }
 28163 
 28164 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F.  */
 28165 
 28166 void
 28167 frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
 28168 {
 28169 #ifdef HAVE_XINPUT2
 28170   int deviceid;
 28171 
 28172   deviceid = FRAME_DISPLAY_INFO (f)->client_pointer_device;
 28173 
 28174   if (FRAME_DISPLAY_INFO (f)->supports_xi2
 28175       && deviceid != -1)
 28176     {
 28177       block_input ();
 28178       x_ignore_errors_for_next_request (FRAME_DISPLAY_INFO (f), 0);
 28179       XIWarpPointer (FRAME_X_DISPLAY (f), deviceid, None,
 28180                      FRAME_X_WINDOW (f), 0, 0, 0, 0, pix_x, pix_y);
 28181       x_stop_ignoring_errors (FRAME_DISPLAY_INFO (f));
 28182       unblock_input ();
 28183     }
 28184   else
 28185 #endif
 28186     XWarpPointer (FRAME_X_DISPLAY (f), None, FRAME_X_WINDOW (f),
 28187                   0, 0, 0, 0, pix_x, pix_y);
 28188 }
 28189 
 28190 /* Raise frame F.  */
 28191 
 28192 static void
 28193 x_raise_frame (struct frame *f)
 28194 {
 28195   block_input ();
 28196 
 28197   if (FRAME_VISIBLE_P (f))
 28198     {
 28199       XRaiseWindow (FRAME_X_DISPLAY (f),
 28200                     FRAME_OUTER_WINDOW (f));
 28201       XFlush (FRAME_X_DISPLAY (f));
 28202     }
 28203 
 28204   unblock_input ();
 28205 }
 28206 
 28207 static void
 28208 x_lower_frame_1 (struct frame *f)
 28209 {
 28210   Window *windows;
 28211   Lisp_Object frame, tail;
 28212   struct frame *sibling;
 28213 
 28214   windows = alloca (2 * sizeof *windows);
 28215 
 28216   /* Lowering a child frame leads to the window being put below any
 28217      scroll bars on the parent.  To avoid that, restack the child
 28218      frame below all of its siblings instead of just lowering it.  */
 28219 
 28220   FOR_EACH_FRAME (tail, frame)
 28221     {
 28222       sibling = XFRAME (frame);
 28223 
 28224       if (sibling == f)
 28225         continue;
 28226 
 28227       if (FRAME_PARENT_FRAME (sibling)
 28228           != FRAME_PARENT_FRAME (f))
 28229         continue;
 28230 
 28231       windows[0] = FRAME_OUTER_WINDOW (sibling);
 28232       windows[1] = FRAME_OUTER_WINDOW (f);
 28233 
 28234       XRestackWindows (FRAME_X_DISPLAY (f), windows, 2);
 28235     }
 28236 }
 28237 
 28238 /* Lower frame F.  */
 28239 
 28240 static void
 28241 x_lower_frame (struct frame *f)
 28242 {
 28243   if (FRAME_PARENT_FRAME (f)
 28244       && (FRAME_HAS_VERTICAL_SCROLL_BARS (FRAME_PARENT_FRAME (f))
 28245           || FRAME_HAS_HORIZONTAL_SCROLL_BARS (FRAME_PARENT_FRAME (f))))
 28246     x_lower_frame_1 (f);
 28247   else
 28248     XLowerWindow (FRAME_X_DISPLAY (f),
 28249                   FRAME_OUTER_WINDOW (f));
 28250 
 28251 #ifdef HAVE_XWIDGETS
 28252   /* Make sure any X windows owned by xwidget views of the parent
 28253      still display below the lowered frame.  */
 28254 
 28255   if (FRAME_PARENT_FRAME (f))
 28256     lower_frame_xwidget_views (FRAME_PARENT_FRAME (f));
 28257 #endif
 28258 
 28259   XFlush (FRAME_X_DISPLAY (f));
 28260 }
 28261 
 28262 static void
 28263 XTframe_raise_lower (struct frame *f, bool raise_flag)
 28264 {
 28265   if (raise_flag)
 28266     x_raise_frame (f);
 28267   else
 28268     x_lower_frame (f);
 28269 }
 28270 
 28271 /* Request focus with XEmbed */
 28272 
 28273 static void
 28274 xembed_request_focus (struct frame *f)
 28275 {
 28276   /* See XEmbed Protocol Specification at
 28277      https://freedesktop.org/wiki/Specifications/xembed-spec/  */
 28278   if (FRAME_VISIBLE_P (f))
 28279     xembed_send_message (f, CurrentTime,
 28280                          XEMBED_REQUEST_FOCUS, 0, 0, 0);
 28281 }
 28282 
 28283 static Bool
 28284 server_timestamp_predicate (Display *display, XEvent *xevent,
 28285                             XPointer arg)
 28286 {
 28287   XID *args = (XID *) arg;
 28288 
 28289   if (xevent->type == PropertyNotify
 28290       && xevent->xproperty.window == args[0]
 28291       && xevent->xproperty.atom == args[1])
 28292     return True;
 28293 
 28294   return False;
 28295 }
 28296 
 28297 /* Get the server time.  The X server is guaranteed to deliver the
 28298    PropertyNotify event, so there is no reason to use x_if_event.  */
 28299 
 28300 static Time
 28301 x_get_server_time (struct frame *f)
 28302 {
 28303   Atom property_atom;
 28304   XEvent property_dummy;
 28305   struct x_display_info *dpyinfo;
 28306   XID client_data[2];
 28307 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
 28308   uint_fast64_t current_monotonic_time;
 28309 #endif
 28310 
 28311   /* If the server time is the same as the monotonic time, avoid a
 28312      roundtrip by using that instead.  */
 28313 
 28314 #if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
 28315   if (FRAME_DISPLAY_INFO (f)->server_time_monotonic_p)
 28316     {
 28317       current_monotonic_time = x_sync_current_monotonic_time ();
 28318 
 28319       if (current_monotonic_time)
 28320         /* Truncate the time to CARD32.  */
 28321         return (current_monotonic_time / 1000) & X_ULONG_MAX;
 28322     }
 28323 #endif
 28324 
 28325   dpyinfo = FRAME_DISPLAY_INFO (f);
 28326   property_atom = dpyinfo->Xatom_EMACS_SERVER_TIME_PROP;
 28327   client_data[0] = FRAME_OUTER_WINDOW (f);
 28328   client_data[1] = property_atom;
 28329 
 28330   XChangeProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
 28331                    property_atom, XA_ATOM, 32,
 28332                    PropModeReplace,
 28333                    (unsigned char *) &property_atom, 1);
 28334 
 28335   XIfEvent (dpyinfo->display, &property_dummy,
 28336             server_timestamp_predicate, (XPointer) client_data);
 28337 
 28338   return property_dummy.xproperty.time;
 28339 }
 28340 
 28341 /* Activate frame with Extended Window Manager Hints */
 28342 
 28343 static void
 28344 x_ewmh_activate_frame (struct frame *f)
 28345 {
 28346   XEvent msg;
 28347   struct x_display_info *dpyinfo;
 28348   Time time;
 28349 
 28350   dpyinfo = FRAME_DISPLAY_INFO (f);
 28351 
 28352   if (FRAME_VISIBLE_P (f))
 28353     {
 28354       /* See the documentation at
 28355          https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html
 28356          for more details on the format of this message.  */
 28357       msg.xclient.type = ClientMessage;
 28358       msg.xclient.window = FRAME_OUTER_WINDOW (f);
 28359       msg.xclient.message_type = dpyinfo->Xatom_net_active_window;
 28360       msg.xclient.format = 32;
 28361       msg.xclient.data.l[0] = 1;
 28362       msg.xclient.data.l[1] = dpyinfo->last_user_time;
 28363       msg.xclient.data.l[2] = (!dpyinfo->x_focus_frame
 28364                                ? None
 28365                                : FRAME_OUTER_WINDOW (dpyinfo->x_focus_frame));
 28366       msg.xclient.data.l[3] = 0;
 28367       msg.xclient.data.l[4] = 0;
 28368 
 28369       /* No frame is currently focused on that display, so apply any
 28370          bypass for focus stealing prevention that the user has
 28371          specified.  */
 28372       if (!dpyinfo->x_focus_frame)
 28373         {
 28374           if (EQ (Vx_allow_focus_stealing, Qimitate_pager))
 28375             msg.xclient.data.l[0] = 2;
 28376           else if (EQ (Vx_allow_focus_stealing, Qnewer_time))
 28377             {
 28378               block_input ();
 28379               time = x_get_server_time (f);
 28380 #ifdef USE_GTK
 28381               x_set_gtk_user_time (f, time);
 28382 #endif
 28383               /* Temporarily override dpyinfo->x_focus_frame so the
 28384                  user time property is set on the right window.  */
 28385               dpyinfo->x_focus_frame = f;
 28386               x_display_set_last_user_time (dpyinfo, time, true, true);
 28387               dpyinfo->x_focus_frame = NULL;
 28388               unblock_input ();
 28389 
 28390               msg.xclient.data.l[1] = time;
 28391             }
 28392           else if (EQ (Vx_allow_focus_stealing, Qraise_and_focus))
 28393             {
 28394               time = x_get_server_time (f);
 28395 
 28396               x_set_input_focus (FRAME_DISPLAY_INFO (f),
 28397                                  FRAME_OUTER_WINDOW (f),
 28398                                  time);
 28399               XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
 28400 
 28401               return;
 28402             }
 28403         }
 28404 
 28405       XSendEvent (dpyinfo->display, dpyinfo->root_window,
 28406                   False, (SubstructureRedirectMask
 28407                           | SubstructureNotifyMask), &msg);
 28408     }
 28409 }
 28410 
 28411 static Lisp_Object
 28412 x_get_focus_frame (struct frame *f)
 28413 {
 28414   Lisp_Object lisp_focus;
 28415 
 28416   struct frame *focus =  FRAME_DISPLAY_INFO (f)->x_focus_frame;
 28417 
 28418   if (!focus)
 28419     return Qnil;
 28420 
 28421   XSETFRAME (lisp_focus, focus);
 28422   return lisp_focus;
 28423 }
 28424 
 28425 /* Return the toplevel parent of F, if it is a child frame.
 28426    Otherwise, return NULL.  */
 28427 
 28428 static struct frame *
 28429 x_get_toplevel_parent (struct frame *f)
 28430 {
 28431   struct frame *parent;
 28432 
 28433   if (!FRAME_PARENT_FRAME (f))
 28434     return NULL;
 28435 
 28436   parent = FRAME_PARENT_FRAME (f);
 28437 
 28438   while (FRAME_PARENT_FRAME (parent))
 28439     parent = FRAME_PARENT_FRAME (parent);
 28440 
 28441   return parent;
 28442 }
 28443 
 28444 static void
 28445 x_set_input_focus (struct x_display_info *dpyinfo, Window window,
 28446                    Time time)
 28447 {
 28448 #ifdef HAVE_XINPUT2
 28449   struct xi_device_t *device;
 28450 #endif
 28451 
 28452   /* Do the equivalent of XSetInputFocus with the specified window and
 28453      time, but use the attachment to the device that Emacs has
 28454      designated the client pointer on X Input Extension builds.
 28455      Asynchronously trap errors around the generated XI_SetFocus or
 28456      SetInputFocus request, in case the device has been destroyed or
 28457      the window obscured.
 28458 
 28459      The revert_to will be set to RevertToParent for generated
 28460      SetInputFocus requests.  */
 28461 
 28462 #ifdef HAVE_XINPUT2
 28463   if (dpyinfo->supports_xi2
 28464       && dpyinfo->client_pointer_device != -1)
 28465     {
 28466       device = xi_device_from_id (dpyinfo, dpyinfo->client_pointer_device);
 28467 
 28468       /* The device is a master pointer.  Use its attachment, which
 28469          should be the master keyboard.  */
 28470 
 28471       if (device)
 28472         {
 28473           eassert (device->use == XIMasterPointer);
 28474 
 28475           x_ignore_errors_for_next_request (dpyinfo, 0);
 28476           XISetFocus (dpyinfo->display, device->attachment,
 28477                       /* Note that the input extension
 28478                          only supports RevertToParent-type
 28479                          behavior.  */
 28480                       window, time);
 28481           x_stop_ignoring_errors (dpyinfo);
 28482 
 28483           return;
 28484         }
 28485     }
 28486 #endif
 28487 
 28488   /* Otherwise, use the pointer device that the X server says is the
 28489      client pointer.  */
 28490   x_ignore_errors_for_next_request (dpyinfo, 0);
 28491   XSetInputFocus (dpyinfo->display, window, RevertToParent, time);
 28492   x_stop_ignoring_errors (dpyinfo);
 28493 }
 28494 
 28495 /* In certain situations, when the window manager follows a
 28496    click-to-focus policy, there seems to be no way around calling
 28497    XSetInputFocus to give another frame the input focus.
 28498 
 28499    In an ideal world, XSetInputFocus should generally be avoided so
 28500    that applications don't interfere with the window manager's focus
 28501    policy.  But I think it's okay to use when it's clearly done
 28502    following a user-command.  */
 28503 
 28504 static void
 28505 x_focus_frame (struct frame *f, bool noactivate)
 28506 {
 28507   struct x_display_info *dpyinfo;
 28508   Time time;
 28509 
 28510   dpyinfo = FRAME_DISPLAY_INFO (f);
 28511 
 28512   if (dpyinfo->untrusted)
 28513     /* The X server ignores all input focus related requests from
 28514        untrusted clients.  */
 28515     return;
 28516 
 28517   /* The code below is not reentrant wrt to dpyinfo->x_focus_frame and
 28518      friends being set.  */
 28519   block_input ();
 28520 
 28521   if (FRAME_X_EMBEDDED_P (f))
 28522     /* For Xembedded frames, normally the embedder forwards key
 28523        events.  See XEmbed Protocol Specification at
 28524        https://freedesktop.org/wiki/Specifications/xembed-spec/  */
 28525     xembed_request_focus (f);
 28526   else
 28527     {
 28528       if (!noactivate
 28529           /* If F is override-redirect, use SetInputFocus instead.
 28530              Override-redirect frames are not subject to window
 28531              management.  */
 28532           && !FRAME_OVERRIDE_REDIRECT (f)
 28533           /* If F is a child frame, use SetInputFocus instead.  This
 28534              may not work if its parent is not activated.  */
 28535           && !FRAME_PARENT_FRAME (f)
 28536           /* If the focus is being transferred from a child frame to
 28537              its toplevel parent, also use SetInputFocus.  */
 28538           && (!dpyinfo->x_focus_frame
 28539               || (x_get_toplevel_parent (dpyinfo->x_focus_frame)
 28540                   != f))
 28541           && x_wm_supports (f, dpyinfo->Xatom_net_active_window))
 28542         {
 28543           /* When window manager activation is possible, use it
 28544              instead.  The window manager is expected to perform any
 28545              necessary actions such as raising the frame, moving it to
 28546              the current workspace, and mapping it, etc, before moving
 28547              input focus to the frame.  */
 28548           x_ewmh_activate_frame (f);
 28549           goto out;
 28550         }
 28551 
 28552       if (NILP (Vx_no_window_manager))
 28553         {
 28554           /* Use the last user time.  It is invalid to use CurrentTime
 28555              according to the ICCCM:
 28556 
 28557                Clients that use a SetInputFocus request must set the
 28558                time field to the timestamp of the event that caused
 28559                them to make the attempt. [...] Note that clients must
 28560                not use CurrentTime in the time field.  */
 28561           time = dpyinfo->last_user_time;
 28562 
 28563           /* Unless the focus doesn't belong to Emacs anymore and
 28564              `x-allow-focus-stealing' is set to Qnewer_time.  */
 28565           if (EQ (Vx_allow_focus_stealing, Qnewer_time)
 28566               && !dpyinfo->x_focus_frame)
 28567             time = x_get_server_time (f);
 28568 
 28569           /* Ignore any BadMatch error this request might result in.
 28570              A BadMatch error can occur if the window was obscured
 28571              after the time of the last user interaction without
 28572              changing the last-focus-change-time.  */
 28573           x_set_input_focus (FRAME_DISPLAY_INFO (f), FRAME_OUTER_WINDOW (f),
 28574                              time);
 28575         }
 28576       else
 28577         x_set_input_focus (FRAME_DISPLAY_INFO (f), FRAME_OUTER_WINDOW (f),
 28578                            /* But when no window manager is in use,
 28579                               respecting the ICCCM doesn't really
 28580                               matter.  */
 28581                            CurrentTime);
 28582     }
 28583 
 28584  out:
 28585   unblock_input ();
 28586 }
 28587 
 28588 
 28589 /* XEmbed implementation.  */
 28590 
 28591 #if defined USE_X_TOOLKIT || ! defined USE_GTK
 28592 
 28593 /* XEmbed implementation.  */
 28594 
 28595 #define XEMBED_VERSION 0
 28596 
 28597 static void
 28598 xembed_set_info (struct frame *f, enum xembed_info flags)
 28599 {
 28600   unsigned long data[2];
 28601   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 28602 
 28603   data[0] = XEMBED_VERSION;
 28604   data[1] = flags;
 28605 
 28606   XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28607                    dpyinfo->Xatom_XEMBED_INFO, dpyinfo->Xatom_XEMBED_INFO,
 28608                    32, PropModeReplace, (unsigned char *) data, 2);
 28609 }
 28610 #endif /* defined USE_X_TOOLKIT || ! defined USE_GTK */
 28611 
 28612 static void
 28613 xembed_send_message (struct frame *f, Time t, enum xembed_message msg,
 28614                      long int detail, long int data1, long int data2)
 28615 {
 28616   XEvent event;
 28617 
 28618   event.xclient.type = ClientMessage;
 28619   event.xclient.window = FRAME_X_OUTPUT (f)->parent_desc;
 28620   event.xclient.message_type = FRAME_DISPLAY_INFO (f)->Xatom_XEMBED;
 28621   event.xclient.format = 32;
 28622   event.xclient.data.l[0] = t;
 28623   event.xclient.data.l[1] = msg;
 28624   event.xclient.data.l[2] = detail;
 28625   event.xclient.data.l[3] = data1;
 28626   event.xclient.data.l[4] = data2;
 28627 
 28628   /* XXX: the XEmbed spec tells us to trap errors around this request,
 28629      but I don't understand why: there is no way for clients to
 28630      survive the death of the parent anyway.  */
 28631 
 28632   x_ignore_errors_for_next_request (FRAME_DISPLAY_INFO (f), 0);
 28633   XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_OUTPUT (f)->parent_desc,
 28634               False, NoEventMask, &event);
 28635   x_stop_ignoring_errors (FRAME_DISPLAY_INFO (f));
 28636 }
 28637 
 28638 /* Change of visibility.  */
 28639 
 28640 /* This tries to wait until the frame is really visible, depending on
 28641    the value of Vx_wait_for_event_timeout.
 28642    However, if the window manager asks the user where to position
 28643    the frame, this will return before the user finishes doing that.
 28644    The frame will not actually be visible at that time,
 28645    but it will become visible later when the window manager
 28646    finishes with it.  */
 28647 
 28648 void
 28649 x_make_frame_visible (struct frame *f)
 28650 {
 28651 #ifndef USE_GTK
 28652   struct x_display_info *dpyinfo;
 28653   struct x_output *output;
 28654 #endif
 28655   bool output_flushed;
 28656 
 28657   if (FRAME_PARENT_FRAME (f))
 28658     {
 28659       if (!FRAME_VISIBLE_P (f))
 28660         {
 28661           block_input ();
 28662 #ifdef USE_GTK
 28663           gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
 28664           XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28665                        f->left_pos, f->top_pos);
 28666 #else
 28667           XMapRaised (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
 28668 #endif
 28669           unblock_input ();
 28670 
 28671           SET_FRAME_VISIBLE (f, true);
 28672           SET_FRAME_ICONIFIED (f, false);
 28673         }
 28674       return;
 28675     }
 28676 
 28677   block_input ();
 28678 
 28679   gui_set_bitmap_icon (f);
 28680 
 28681 #ifndef USE_GTK
 28682   dpyinfo = FRAME_DISPLAY_INFO (f);
 28683 #endif
 28684 
 28685   if (! FRAME_VISIBLE_P (f))
 28686     {
 28687       /* We test asked_for_visible here to make sure we don't
 28688          call x_set_offset a second time
 28689          if we get to x_make_frame_visible a second time
 28690          before the window gets really visible.  */
 28691       if (! FRAME_ICONIFIED_P (f)
 28692           && ! FRAME_X_EMBEDDED_P (f)
 28693           && ! f->output_data.x->asked_for_visible)
 28694         x_set_offset (f, f->left_pos, f->top_pos, 0);
 28695 
 28696 #ifndef USE_GTK
 28697       output = FRAME_X_OUTPUT (f);
 28698       x_update_frame_user_time_window (f);
 28699 
 28700       /* It's been a while since I wrote that code...  I don't
 28701          remember if it can leave `user_time_window' unset or not.  */
 28702       if (output->user_time_window != None)
 28703         {
 28704           if (dpyinfo->last_user_time)
 28705             XChangeProperty (dpyinfo->display, output->user_time_window,
 28706                              dpyinfo->Xatom_net_wm_user_time,
 28707                              XA_CARDINAL, 32, PropModeReplace,
 28708                              (unsigned char *) &dpyinfo->last_user_time, 1);
 28709           else
 28710             XDeleteProperty (dpyinfo->display, output->user_time_window,
 28711                              dpyinfo->Xatom_net_wm_user_time);
 28712         }
 28713 #endif
 28714 
 28715       f->output_data.x->asked_for_visible = true;
 28716 
 28717       if (! EQ (Vx_no_window_manager, Qt))
 28718         x_wm_set_window_state (f, NormalState);
 28719 #ifdef USE_X_TOOLKIT
 28720       if (FRAME_X_EMBEDDED_P (f))
 28721         xembed_set_info (f, XEMBED_MAPPED);
 28722       else
 28723         {
 28724           /* This was XtPopup, but that did nothing for an iconified frame.  */
 28725           XtMapWidget (f->output_data.x->widget);
 28726         }
 28727 #else /* not USE_X_TOOLKIT */
 28728 #ifdef USE_GTK
 28729       gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
 28730       gtk_window_deiconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
 28731 #else
 28732       if (FRAME_X_EMBEDDED_P (f))
 28733         xembed_set_info (f, XEMBED_MAPPED);
 28734       else
 28735         XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 28736 #endif /* not USE_GTK */
 28737 #endif /* not USE_X_TOOLKIT */
 28738 
 28739       if (FRAME_X_EMBEDDED_P (f))
 28740         {
 28741           SET_FRAME_VISIBLE (f, true);
 28742           SET_FRAME_ICONIFIED (f, false);
 28743         }
 28744     }
 28745 
 28746   /* Synchronize to ensure Emacs knows the frame is visible
 28747      before we do anything else.  We do this loop with input not blocked
 28748      so that incoming events are handled.  */
 28749   {
 28750     Lisp_Object frame;
 28751     /* This must be before UNBLOCK_INPUT
 28752        since events that arrive in response to the actions above
 28753        will set it when they are handled.  */
 28754     bool previously_visible = f->output_data.x->has_been_visible;
 28755 
 28756     XSETFRAME (frame, f);
 28757 
 28758     int original_left = f->left_pos;
 28759     int original_top = f->top_pos;
 28760 
 28761     /* This must come after we set COUNT.  */
 28762     unblock_input ();
 28763 
 28764     /* Keep track of whether or not the output buffer was flushed, to
 28765        avoid any extra flushes.  */
 28766     output_flushed = false;
 28767 
 28768     /* We unblock here so that arriving X events are processed.  */
 28769 
 28770     /* Now move the window back to where it was "supposed to be".
 28771        But don't do it if the gravity is negative.
 28772        When the gravity is negative, this uses a position
 28773        that is 3 pixels too low.  Perhaps that's really the border width.
 28774 
 28775        Don't do this if the window has never been visible before,
 28776        because the window manager may choose the position
 28777        and we don't want to override it.  */
 28778 
 28779     if (!FRAME_VISIBLE_P (f)
 28780         && !FRAME_ICONIFIED_P (f)
 28781         && !FRAME_X_EMBEDDED_P (f)
 28782         && !FRAME_PARENT_FRAME (f)
 28783         && NILP (Vx_lax_frame_positioning)
 28784         && f->win_gravity == NorthWestGravity
 28785         && previously_visible)
 28786       {
 28787         Drawable rootw;
 28788         int x, y;
 28789         unsigned int width, height, border, depth;
 28790 
 28791         block_input ();
 28792 
 28793         /* On some window managers (such as FVWM) moving an existing
 28794            window, even to the same place, causes the window manager
 28795            to introduce an offset.  This can cause the window to move
 28796            to an unexpected location.  Check the geometry (a little
 28797            slow here) and then verify that the window is in the right
 28798            place.  If the window is not in the right place, move it
 28799            there, and take the potential window manager hit.  */
 28800         XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28801                       &rootw, &x, &y, &width, &height, &border, &depth);
 28802         output_flushed = true;
 28803 
 28804         if (original_left != x || original_top != y)
 28805           XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
 28806                        original_left, original_top);
 28807 
 28808         unblock_input ();
 28809       }
 28810 
 28811     /* Try to wait for a MapNotify event (that is what tells us when a
 28812        frame becomes visible).  Unless `x-lax-frame-positioning' is
 28813        non-nil: there, that is a little slow.  */
 28814 
 28815 #ifdef CYGWIN
 28816     /* On Cygwin, which uses input polling, we need to force input to
 28817        be read.  See
 28818        https://lists.gnu.org/r/emacs-devel/2013-12/msg00351.html
 28819        and https://debbugs.gnu.org/cgi/bugreport.cgi?bug=24091#131.
 28820        Fake an alarm signal to let the handler know that there's
 28821        something to be read.
 28822 
 28823        It could be confusing if a real alarm arrives while processing
 28824        the fake one.  Turn it off and let the handler reset it.  */
 28825     int old_poll_suppress_count = poll_suppress_count;
 28826     poll_suppress_count = 1;
 28827     poll_for_input_1 ();
 28828     poll_suppress_count = old_poll_suppress_count;
 28829 #endif
 28830 
 28831     if (!FRAME_VISIBLE_P (f)
 28832         && NILP (Vx_lax_frame_positioning))
 28833       {
 28834         if (CONSP (frame_size_history))
 28835           frame_size_history_plain
 28836             (f, build_string ("x_make_frame_visible"));
 28837 
 28838         x_wait_for_event (f, MapNotify);
 28839         output_flushed = true;
 28840       }
 28841 
 28842     if (!output_flushed)
 28843       x_flush (f);
 28844   }
 28845 }
 28846 
 28847 /* Change from mapped state to withdrawn state.  */
 28848 
 28849 /* Make the frame visible (mapped and not iconified).  */
 28850 
 28851 void
 28852 x_make_frame_invisible (struct frame *f)
 28853 {
 28854   Window window;
 28855 
 28856   /* Use the frame's outermost window, not the one we normally draw on.  */
 28857   window = FRAME_OUTER_WINDOW (f);
 28858 
 28859   /* Don't keep the highlight on an invisible frame.  */
 28860   if (FRAME_DISPLAY_INFO (f)->highlight_frame == f)
 28861     FRAME_DISPLAY_INFO (f)->highlight_frame = 0;
 28862 
 28863   block_input ();
 28864 
 28865 #ifdef HAVE_XINPUT2_2
 28866   /* Remove any touch points associated with F.  */
 28867   xi_unlink_touch_points (f);
 28868 #endif
 28869 
 28870   /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
 28871      that the current position of the window is user-specified, rather than
 28872      program-specified, so that when the window is mapped again, it will be
 28873      placed at the same location, without forcing the user to position it
 28874      by hand again (they have already done that once for this window.)  */
 28875   x_wm_set_size_hint (f, 0, true);
 28876 
 28877 #ifdef USE_GTK
 28878   if (FRAME_GTK_OUTER_WIDGET (f))
 28879     gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
 28880   else
 28881 #else
 28882   if (FRAME_X_EMBEDDED_P (f))
 28883     xembed_set_info (f, 0);
 28884   else
 28885 #endif
 28886 
 28887     if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window,
 28888                            DefaultScreen (FRAME_X_DISPLAY (f))))
 28889       {
 28890         unblock_input ();
 28891         error ("Can't notify window manager of window withdrawal");
 28892       }
 28893 
 28894   /* Don't perform the synchronization if the network connection is
 28895      slow, and the user says it is unwanted.  */
 28896   if (NILP (Vx_lax_frame_positioning))
 28897     XSync (FRAME_X_DISPLAY (f), False);
 28898 
 28899   /* We can't distinguish this from iconification
 28900      just by the event that we get from the server.
 28901      So we can't win using the usual strategy of letting
 28902      FRAME_SAMPLE_VISIBILITY set this.  So do it by hand,
 28903      and synchronize with the server to make sure we agree.  */
 28904   SET_FRAME_VISIBLE (f, 0);
 28905   SET_FRAME_ICONIFIED (f, false);
 28906 
 28907   if (CONSP (frame_size_history))
 28908     frame_size_history_plain (f, build_string ("x_make_frame_invisible"));
 28909 
 28910   unblock_input ();
 28911 }
 28912 
 28913 static void
 28914 x_make_frame_visible_invisible (struct frame *f, bool visible)
 28915 {
 28916   if (visible)
 28917     x_make_frame_visible (f);
 28918   else
 28919     x_make_frame_invisible (f);
 28920 }
 28921 
 28922 Cursor
 28923 x_create_font_cursor (struct x_display_info *dpyinfo, int glyph)
 28924 {
 28925   if (glyph <= 65535)
 28926     return XCreateFontCursor (dpyinfo->display, glyph);
 28927 
 28928   /* x-pointer-invisible cannot fit in CARD16, and thus cannot be any
 28929      existing cursor.  */
 28930   return make_invisible_cursor (dpyinfo);
 28931 }
 28932 
 28933 
 28934 /* Change window state from mapped to iconified.  */
 28935 
 28936 void
 28937 x_iconify_frame (struct frame *f)
 28938 {
 28939 #ifdef USE_X_TOOLKIT
 28940   int result;
 28941 #endif
 28942 
 28943   /* Don't keep the highlight on an invisible frame.  */
 28944   if (FRAME_DISPLAY_INFO (f)->highlight_frame == f)
 28945     FRAME_DISPLAY_INFO (f)->highlight_frame = 0;
 28946 
 28947   if (FRAME_ICONIFIED_P (f))
 28948     return;
 28949 
 28950   block_input ();
 28951 
 28952   gui_set_bitmap_icon (f);
 28953 
 28954 #if defined (USE_GTK)
 28955   if (FRAME_GTK_OUTER_WIDGET (f))
 28956     {
 28957       if (! FRAME_VISIBLE_P (f))
 28958         gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
 28959 
 28960       gtk_window_iconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
 28961       SET_FRAME_VISIBLE (f, 0);
 28962       SET_FRAME_ICONIFIED (f, true);
 28963       unblock_input ();
 28964       return;
 28965     }
 28966 #endif
 28967 
 28968 #ifdef USE_X_TOOLKIT
 28969 
 28970   if (! FRAME_VISIBLE_P (f))
 28971     {
 28972       if (! EQ (Vx_no_window_manager, Qt))
 28973         x_wm_set_window_state (f, IconicState);
 28974       /* This was XtPopup, but that did nothing for an iconified frame.  */
 28975       XtMapWidget (f->output_data.x->widget);
 28976       /* The server won't give us any event to indicate
 28977          that an invisible frame was changed to an icon,
 28978          so we have to record it here.  */
 28979       SET_FRAME_VISIBLE (f, 0);
 28980       SET_FRAME_ICONIFIED (f, true);
 28981       unblock_input ();
 28982       return;
 28983     }
 28984 
 28985   result = XIconifyWindow (FRAME_X_DISPLAY (f),
 28986                            XtWindow (f->output_data.x->widget),
 28987                            DefaultScreen (FRAME_X_DISPLAY (f)));
 28988   unblock_input ();
 28989 
 28990   if (!result)
 28991     error ("Can't notify window manager of iconification");
 28992 
 28993   SET_FRAME_ICONIFIED (f, true);
 28994   SET_FRAME_VISIBLE (f, 0);
 28995 
 28996   block_input ();
 28997   XFlush (FRAME_X_DISPLAY (f));
 28998   unblock_input ();
 28999 #else /* not USE_X_TOOLKIT */
 29000 
 29001   /* Make sure the X server knows where the window should be positioned,
 29002      in case the user deiconifies with the window manager.  */
 29003   if (! FRAME_VISIBLE_P (f)
 29004       && ! FRAME_ICONIFIED_P (f)
 29005       && ! FRAME_X_EMBEDDED_P (f))
 29006     x_set_offset (f, f->left_pos, f->top_pos, 0);
 29007 
 29008   /* Since we don't know which revision of X we're running, we'll use both
 29009      the X11R3 and X11R4 techniques.  I don't know if this is a good idea.  */
 29010 
 29011   /* X11R4: send a ClientMessage to the window manager using the
 29012      WM_CHANGE_STATE type.  */
 29013   {
 29014     XEvent msg;
 29015 
 29016     msg.xclient.window = FRAME_X_WINDOW (f);
 29017     msg.xclient.type = ClientMessage;
 29018     msg.xclient.message_type = FRAME_DISPLAY_INFO (f)->Xatom_wm_change_state;
 29019     msg.xclient.format = 32;
 29020     msg.xclient.data.l[0] = IconicState;
 29021     msg.xclient.data.l[1] = 0;
 29022     msg.xclient.data.l[2] = 0;
 29023     msg.xclient.data.l[3] = 0;
 29024     msg.xclient.data.l[4] = 0;
 29025 
 29026     if (! XSendEvent (FRAME_X_DISPLAY (f),
 29027                       FRAME_DISPLAY_INFO (f)->root_window,
 29028                       False,
 29029                       SubstructureRedirectMask | SubstructureNotifyMask,
 29030                       &msg))
 29031       {
 29032         unblock_input ();
 29033         error ("Can't notify window manager of iconification");
 29034       }
 29035   }
 29036 
 29037   /* X11R3: set the initial_state field of the window manager hints to
 29038      IconicState.  */
 29039   x_wm_set_window_state (f, IconicState);
 29040 
 29041   if (!FRAME_VISIBLE_P (f))
 29042     {
 29043       /* If the frame was withdrawn, before, we must map it.  */
 29044       XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 29045     }
 29046 
 29047   SET_FRAME_ICONIFIED (f, true);
 29048   SET_FRAME_VISIBLE (f, 0);
 29049 
 29050   XFlush (FRAME_X_DISPLAY (f));
 29051   unblock_input ();
 29052 #endif /* not USE_X_TOOLKIT */
 29053 }
 29054 
 29055 
 29056 /* Free X resources of frame F.  */
 29057 
 29058 void
 29059 x_free_frame_resources (struct frame *f)
 29060 {
 29061   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 29062   Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
 29063 #ifdef USE_X_TOOLKIT
 29064   Lisp_Object bar;
 29065   struct scroll_bar *b;
 29066 #endif
 29067 
 29068   block_input ();
 29069 
 29070 #ifdef HAVE_XINPUT2
 29071   /* Remove any record of this frame being focused.  */
 29072   xi_handle_delete_frame (dpyinfo, f);
 29073 #endif
 29074 
 29075 #ifdef HAVE_XINPUT2_2
 29076   /* Remove any touch points associated with F.  */
 29077   xi_unlink_touch_points (f);
 29078 #endif
 29079 
 29080   /* If a display connection is dead, don't try sending more
 29081      commands to the X server.  */
 29082   if (dpyinfo->display)
 29083     {
 29084       /* Always exit with visible pointer to avoid weird issue
 29085          with Xfixes (Bug#17609).  */
 29086       if (f->pointer_invisible)
 29087         XTtoggle_invisible_pointer (f, 0);
 29088 
 29089       /* We must free faces before destroying windows because some
 29090          font-driver (e.g. xft) access a window while finishing a
 29091          face.  */
 29092       free_frame_faces (f);
 29093       tear_down_x_back_buffer (f);
 29094 
 29095       if (f->output_data.x->icon_desc)
 29096         XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
 29097 
 29098 #ifdef USE_X_TOOLKIT
 29099       /* Explicitly destroy the scroll bars of the frame.  Without
 29100          this, we get "BadDrawable" errors from the toolkit later on,
 29101          presumably from expose events generated for the disappearing
 29102          toolkit scroll bars.  */
 29103       for (bar = FRAME_SCROLL_BARS (f); !NILP (bar); bar = b->next)
 29104         {
 29105           b = XSCROLL_BAR (bar);
 29106           x_scroll_bar_remove (b);
 29107         }
 29108 #endif
 29109 
 29110 #ifdef HAVE_X_I18N
 29111       if (FRAME_XIC (f))
 29112         free_frame_xic (f);
 29113 #endif
 29114 
 29115 #ifdef USE_CAIRO
 29116       x_cr_destroy_frame_context (f);
 29117 #endif
 29118 #ifdef USE_X_TOOLKIT
 29119       if (f->output_data.x->widget)
 29120         {
 29121           XtDestroyWidget (f->output_data.x->widget);
 29122           f->output_data.x->widget = NULL;
 29123         }
 29124       /* Tooltips don't have widgets, only a simple X window, even if
 29125          we are using a toolkit.  */
 29126       else if (FRAME_X_WINDOW (f))
 29127         XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 29128 
 29129       free_frame_menubar (f);
 29130 
 29131       if (f->shell_position)
 29132         xfree (f->shell_position);
 29133 #else  /* !USE_X_TOOLKIT */
 29134 
 29135 #ifdef HAVE_XWIDGETS
 29136       kill_frame_xwidget_views (f);
 29137 #endif
 29138 
 29139 #ifdef USE_GTK
 29140       xg_free_frame_widgets (f);
 29141 #endif /* USE_GTK */
 29142 
 29143       tear_down_x_back_buffer (f);
 29144       if (FRAME_X_WINDOW (f))
 29145         XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
 29146 #endif /* !USE_X_TOOLKIT */
 29147 
 29148 #ifdef HAVE_XSYNC
 29149       if (FRAME_X_BASIC_COUNTER (f) != None)
 29150         XSyncDestroyCounter (FRAME_X_DISPLAY (f),
 29151                              FRAME_X_BASIC_COUNTER (f));
 29152 
 29153       if (FRAME_X_EXTENDED_COUNTER (f) != None)
 29154         XSyncDestroyCounter (FRAME_X_DISPLAY (f),
 29155                              FRAME_X_EXTENDED_COUNTER (f));
 29156 #endif
 29157 
 29158       unload_color (f, FRAME_FOREGROUND_PIXEL (f));
 29159       unload_color (f, FRAME_BACKGROUND_PIXEL (f));
 29160       unload_color (f, f->output_data.x->cursor_pixel);
 29161       unload_color (f, f->output_data.x->cursor_foreground_pixel);
 29162       unload_color (f, f->output_data.x->border_pixel);
 29163       unload_color (f, f->output_data.x->mouse_pixel);
 29164 
 29165       if (f->output_data.x->scroll_bar_background_pixel != -1)
 29166         unload_color (f, f->output_data.x->scroll_bar_background_pixel);
 29167       if (f->output_data.x->scroll_bar_foreground_pixel != -1)
 29168         unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
 29169 #if defined (USE_LUCID) && defined (USE_TOOLKIT_SCROLL_BARS)
 29170       /* Scrollbar shadow colors.  */
 29171       if (f->output_data.x->scroll_bar_top_shadow_pixel != -1)
 29172         unload_color (f, f->output_data.x->scroll_bar_top_shadow_pixel);
 29173       if (f->output_data.x->scroll_bar_bottom_shadow_pixel != -1)
 29174         unload_color (f, f->output_data.x->scroll_bar_bottom_shadow_pixel);
 29175 #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */
 29176       if (f->output_data.x->white_relief.pixel != -1)
 29177         unload_color (f, f->output_data.x->white_relief.pixel);
 29178       if (f->output_data.x->black_relief.pixel != -1)
 29179         unload_color (f, f->output_data.x->black_relief.pixel);
 29180 
 29181       x_free_gcs (f);
 29182 
 29183       /* Free extra GCs allocated by x_setup_relief_colors.  */
 29184       if (f->output_data.x->white_relief.gc)
 29185         {
 29186           XFreeGC (dpyinfo->display, f->output_data.x->white_relief.gc);
 29187           f->output_data.x->white_relief.gc = 0;
 29188         }
 29189       if (f->output_data.x->black_relief.gc)
 29190         {
 29191           XFreeGC (dpyinfo->display, f->output_data.x->black_relief.gc);
 29192           f->output_data.x->black_relief.gc = 0;
 29193         }
 29194 
 29195       /* Free cursors.  */
 29196       if (f->output_data.x->text_cursor != 0)
 29197         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->text_cursor);
 29198       if (f->output_data.x->nontext_cursor != 0)
 29199         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->nontext_cursor);
 29200       if (f->output_data.x->modeline_cursor != 0)
 29201         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->modeline_cursor);
 29202       if (f->output_data.x->hand_cursor != 0)
 29203         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->hand_cursor);
 29204       if (f->output_data.x->hourglass_cursor != 0)
 29205         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->hourglass_cursor);
 29206       if (f->output_data.x->horizontal_drag_cursor != 0)
 29207         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->horizontal_drag_cursor);
 29208       if (f->output_data.x->vertical_drag_cursor != 0)
 29209         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->vertical_drag_cursor);
 29210       if (f->output_data.x->left_edge_cursor != 0)
 29211         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->left_edge_cursor);
 29212       if (f->output_data.x->top_left_corner_cursor != 0)
 29213         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->top_left_corner_cursor);
 29214       if (f->output_data.x->top_edge_cursor != 0)
 29215         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->top_edge_cursor);
 29216       if (f->output_data.x->top_right_corner_cursor != 0)
 29217         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->top_right_corner_cursor);
 29218       if (f->output_data.x->right_edge_cursor != 0)
 29219         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->right_edge_cursor);
 29220       if (f->output_data.x->bottom_right_corner_cursor != 0)
 29221         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_right_corner_cursor);
 29222       if (f->output_data.x->bottom_edge_cursor != 0)
 29223         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_edge_cursor);
 29224       if (f->output_data.x->bottom_left_corner_cursor != 0)
 29225         XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->bottom_left_corner_cursor);
 29226 
 29227       /* Free sync fences.  */
 29228 #if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
 29229       x_sync_free_fences (f);
 29230 #endif
 29231 
 29232 #ifdef USE_TOOLKIT_SCROLL_BARS
 29233       /* Since the frame was destroyed, we can no longer guarantee
 29234          that scroll bar events will be received.  Clear
 29235          protected_windows.  */
 29236       dpyinfo->n_protected_windows = 0;
 29237 #endif
 29238     }
 29239 
 29240 #ifdef HAVE_GTK3
 29241   if (FRAME_OUTPUT_DATA (f)->scrollbar_background_css_provider)
 29242     g_object_unref (FRAME_OUTPUT_DATA (f)->scrollbar_background_css_provider);
 29243 
 29244   if (FRAME_OUTPUT_DATA (f)->scrollbar_foreground_css_provider)
 29245     g_object_unref (FRAME_OUTPUT_DATA (f)->scrollbar_foreground_css_provider);
 29246 #endif
 29247 
 29248   if (f == dpyinfo->motif_drag_atom_owner)
 29249     {
 29250       dpyinfo->motif_drag_atom_owner = NULL;
 29251       dpyinfo->motif_drag_atom = None;
 29252     }
 29253 
 29254   if (f == dpyinfo->x_focus_frame)
 29255     dpyinfo->x_focus_frame = 0;
 29256   if (f == dpyinfo->x_focus_event_frame)
 29257     dpyinfo->x_focus_event_frame = 0;
 29258   if (f == dpyinfo->highlight_frame)
 29259     dpyinfo->highlight_frame = 0;
 29260   if (f == hlinfo->mouse_face_mouse_frame)
 29261     reset_mouse_highlight (hlinfo);
 29262 
 29263   /* These two need to be freed now that they are used to compute the
 29264      mouse position, I think.  */
 29265   if (f == dpyinfo->last_mouse_motion_frame)
 29266     dpyinfo->last_mouse_motion_frame = NULL;
 29267   if (f == dpyinfo->last_mouse_frame)
 29268     dpyinfo->last_mouse_frame = NULL;
 29269 
 29270 #ifdef HAVE_XINPUT2
 29271   /* Consider a frame being unfocused with no following FocusIn event
 29272      while an older focus from another seat exists.  The client
 29273      pointer should then revert to the other seat, so handle potential
 29274      focus changes.  */
 29275 
 29276   if (dpyinfo->supports_xi2)
 29277     xi_handle_focus_change (dpyinfo);
 29278 #endif
 29279 
 29280   unblock_input ();
 29281 }
 29282 
 29283 
 29284 /* Destroy the X window of frame F.  */
 29285 
 29286 static void
 29287 x_destroy_window (struct frame *f)
 29288 {
 29289   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
 29290 
 29291   /* If a display connection is dead, don't try sending more
 29292      commands to the X server.  */
 29293   if (dpyinfo->display != 0)
 29294     x_free_frame_resources (f);
 29295 
 29296   xfree (f->output_data.x->saved_menu_event);
 29297 
 29298 #ifdef HAVE_X_I18N
 29299   if (f->output_data.x->preedit_chars)
 29300     xfree (f->output_data.x->preedit_chars);
 29301 #endif
 29302 
 29303 #ifdef HAVE_XINPUT2
 29304 #ifdef HAVE_XINPUT2_1
 29305   if (f->output_data.x->xi_masks)
 29306     XFree (f->output_data.x->xi_masks);
 29307 #else
 29308   /* This is allocated by us under very old versions of libXi; see
 29309      `setup_xi_event_mask'.  */
 29310   if (f->output_data.x->xi_masks)
 29311     xfree (f->output_data.x->xi_masks);
 29312 #endif
 29313 #endif
 29314 
 29315   xfree (f->output_data.x);
 29316   f->output_data.x = NULL;
 29317 
 29318   dpyinfo->reference_count--;
 29319 }
 29320 
 29321 /* Intern NAME in DPYINFO, but check to see if the atom was already
 29322    interned when the X connection was opened, and use that instead.
 29323 
 29324    If PREDEFINED_ONLY, return None if the atom was not interned during
 29325    connection setup or is predefined.  */
 29326 Atom
 29327 x_intern_cached_atom (struct x_display_info *dpyinfo,
 29328                       const char *name, bool predefined_only)
 29329 {
 29330   int i;
 29331   char *ptr;
 29332   Atom *atom;
 29333 
 29334   /* Special atoms that depend on the screen number.  */
 29335   char xsettings_atom_name[sizeof "_XSETTINGS_S%d" - 2
 29336                            + INT_STRLEN_BOUND (int)];
 29337   char cm_atom_name[sizeof "_NET_WM_CM_S%d" - 2
 29338                     + INT_STRLEN_BOUND (int)];
 29339 
 29340   sprintf (xsettings_atom_name, "_XSETTINGS_S%d",
 29341            XScreenNumberOfScreen (dpyinfo->screen));
 29342   sprintf (cm_atom_name, "_NET_WM_CM_S%d",
 29343            XScreenNumberOfScreen (dpyinfo->screen));
 29344 
 29345   if (!strcmp (name, xsettings_atom_name))
 29346     return dpyinfo->Xatom_xsettings_sel;
 29347 
 29348   if (!strcmp (name, cm_atom_name))
 29349     return dpyinfo->Xatom_NET_WM_CM_Sn;
 29350 
 29351   /* Now do some common predefined atoms.  */
 29352   if (!strcmp (name, "PRIMARY"))
 29353     return XA_PRIMARY;
 29354 
 29355   if (!strcmp (name, "SECONDARY"))
 29356     return XA_SECONDARY;
 29357 
 29358   if (!strcmp (name, "STRING"))
 29359     return XA_STRING;
 29360 
 29361   if (!strcmp (name, "INTEGER"))
 29362     return XA_INTEGER;
 29363 
 29364   if (!strcmp (name, "ATOM"))
 29365     return XA_ATOM;
 29366 
 29367   if (!strcmp (name, "WINDOW"))
 29368     return XA_WINDOW;
 29369 
 29370   if (!strcmp (name, "DRAWABLE"))
 29371     return XA_DRAWABLE;
 29372 
 29373   if (!strcmp (name, "BITMAP"))
 29374     return XA_BITMAP;
 29375 
 29376   if (!strcmp (name, "CARDINAL"))
 29377     return XA_CARDINAL;
 29378 
 29379   if (!strcmp (name, "COLORMAP"))
 29380     return XA_COLORMAP;
 29381 
 29382   if (!strcmp (name, "CURSOR"))
 29383     return XA_CURSOR;
 29384 
 29385   if (!strcmp (name, "FONT"))
 29386     return XA_FONT;
 29387 
 29388   if (dpyinfo->motif_drag_atom != None
 29389       && !strcmp (name, dpyinfo->motif_drag_atom_name))
 29390     return dpyinfo->motif_drag_atom;
 29391 
 29392   for (i = 0; i < ARRAYELTS (x_atom_refs); ++i)
 29393     {
 29394       ptr = (char *) dpyinfo;
 29395 
 29396       if (!strcmp (x_atom_refs[i].name, name))
 29397         {
 29398           atom = (Atom *) (ptr + x_atom_refs[i].offset);
 29399 
 29400           return *atom;
 29401         }
 29402     }
 29403 
 29404   if (predefined_only)
 29405     return None;
 29406 
 29407   return XInternAtom (dpyinfo->display, name, False);
 29408 }
 29409 
 29410 /* Get the name of ATOM, but try not to make a request to the X
 29411    server.  Whether or not a request to the X server happened is
 29412    placed in NEED_SYNC.  */
 29413 char *
 29414 x_get_atom_name (struct x_display_info *dpyinfo, Atom atom,
 29415                  bool *need_sync)
 29416 {
 29417   char *dpyinfo_pointer, *name, *value, *buffer;
 29418   int i;
 29419   Atom ref_atom;
 29420 
 29421   dpyinfo_pointer = (char *) dpyinfo;
 29422   value = NULL;
 29423 
 29424   if (need_sync)
 29425     *need_sync = false;
 29426 
 29427   buffer = alloca (45 + INT_STRLEN_BOUND (int));
 29428 
 29429   switch (atom)
 29430     {
 29431     case XA_PRIMARY:
 29432       return xstrdup ("PRIMARY");
 29433 
 29434     case XA_SECONDARY:
 29435       return xstrdup ("SECONDARY");
 29436 
 29437     case XA_INTEGER:
 29438       return xstrdup ("INTEGER");
 29439 
 29440     case XA_ATOM:
 29441       return xstrdup ("ATOM");
 29442 
 29443     case XA_CARDINAL:
 29444       return xstrdup ("CARDINAL");
 29445 
 29446     case XA_WINDOW:
 29447       return xstrdup ("WINDOW");
 29448 
 29449     case XA_DRAWABLE:
 29450       return xstrdup ("DRAWABLE");
 29451 
 29452     case XA_BITMAP:
 29453       return xstrdup ("BITMAP");
 29454 
 29455     case XA_COLORMAP:
 29456       return xstrdup ("COLORMAP");
 29457 
 29458     case XA_FONT:
 29459       return xstrdup ("FONT");
 29460 
 29461     default:
 29462       if (dpyinfo->motif_drag_atom
 29463           && atom == dpyinfo->motif_drag_atom)
 29464         return xstrdup (dpyinfo->motif_drag_atom_name);
 29465 
 29466       if (atom == dpyinfo->Xatom_xsettings_sel)
 29467         {
 29468           sprintf (buffer, "_XSETTINGS_S%d",
 29469                    XScreenNumberOfScreen (dpyinfo->screen));
 29470           return xstrdup (buffer);
 29471         }
 29472 
 29473       if (atom == dpyinfo->Xatom_NET_WM_CM_Sn)
 29474         {
 29475           sprintf (buffer, "_NET_WM_CM_S%d",
 29476                    XScreenNumberOfScreen (dpyinfo->screen));
 29477           return xstrdup (buffer);
 29478         }
 29479 
 29480       for (i = 0; i < ARRAYELTS (x_atom_refs); ++i)
 29481         {
 29482           ref_atom = *(Atom *) (dpyinfo_pointer
 29483                                 + x_atom_refs[i].offset);
 29484 
 29485           if (atom == ref_atom)
 29486             return xstrdup (x_atom_refs[i].name);
 29487         }
 29488 
 29489       name = XGetAtomName (dpyinfo->display, atom);
 29490 
 29491       if (need_sync)
 29492         *need_sync = true;
 29493 
 29494       if (name)
 29495         {
 29496           value = xstrdup (name);
 29497           XFree (name);
 29498         }
 29499 
 29500       break;
 29501     }
 29502 
 29503   return value;
 29504 }
 29505 
 29506 /* Intern an array of atoms, and do so quickly, avoiding extraneous
 29507    roundtrips to the X server.
 29508 
 29509    Avoid sending atoms that have already been found to the X server.
 29510    This cannot do anything that will end up triggering garbage
 29511    collection.  */
 29512 
 29513 void
 29514 x_intern_atoms (struct x_display_info *dpyinfo, char **names, int count,
 29515                 Atom *atoms_return)
 29516 {
 29517   int i, j, indices[256];
 29518   char *new_names[256];
 29519   Atom results[256], candidate;
 29520 
 29521   if (count > 256)
 29522     /* Atoms array too big to inspect reasonably, just send it to the
 29523        server and back.  */
 29524     XInternAtoms (dpyinfo->display, new_names, count, False, atoms_return);
 29525   else
 29526     {
 29527       for (i = 0, j = 0; i < count; ++i)
 29528         {
 29529           candidate = x_intern_cached_atom (dpyinfo, names[i],
 29530                                             true);
 29531 
 29532           if (candidate)
 29533             atoms_return[i] = candidate;
 29534           else
 29535             {
 29536               indices[j++] = i;
 29537               new_names[j - 1] = names[i];
 29538             }
 29539         }
 29540 
 29541       if (!j)
 29542         return;
 29543 
 29544       /* Now, get the results back from the X server.  */
 29545       XInternAtoms (dpyinfo->display, new_names, j, False,
 29546                     results);
 29547 
 29548       for (i = 0; i < j; ++i)
 29549         atoms_return[indices[i]] = results[i];
 29550     }
 29551 }
 29552 
 29553 #ifndef USE_GTK
 29554 
 29555 /* Set up XEmbed for F, and change its save set to handle the parent
 29556    being destroyed.  */
 29557 
 29558 bool
 29559 x_embed_frame (struct x_display_info *dpyinfo, struct frame *f)
 29560 {
 29561   bool rc;
 29562 
 29563   x_catch_errors (dpyinfo->display);
 29564   /* Catch errors; the target window might no longer exist.  */
 29565   XReparentWindow (dpyinfo->display, FRAME_OUTER_WINDOW (f),
 29566                    FRAME_OUTPUT_DATA (f)->parent_desc, 0, 0);
 29567   rc = x_had_errors_p (dpyinfo->display);
 29568   x_uncatch_errors_after_check ();
 29569 
 29570   if (rc)
 29571     return false;
 29572 
 29573   return true;
 29574 }
 29575 
 29576 #endif
 29577 
 29578 
 29579 /* Setting window manager hints.  */
 29580 
 29581 /* Set the normal size hints for the window manager, for frame F.
 29582    FLAGS is the flags word to use--or 0 meaning preserve the flags
 29583    that the window now has.
 29584    If USER_POSITION, set the USPosition
 29585    flag (this is useful when FLAGS is 0).
 29586    The GTK version is in gtkutils.c.  */
 29587 
 29588 void
 29589 x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
 29590 {
 29591 #ifndef USE_GTK
 29592   XSizeHints size_hints;
 29593   Window window = FRAME_OUTER_WINDOW (f);
 29594 #ifdef USE_X_TOOLKIT
 29595   WMShellWidget shell;
 29596 #ifndef USE_MOTIF
 29597   bool hints_changed;
 29598 #endif
 29599 #endif
 29600 
 29601   if (!window)
 29602     return;
 29603 
 29604 #ifdef USE_X_TOOLKIT
 29605   if (f->output_data.x->widget)
 29606     {
 29607       /* Do this dance in xterm.c because some stuff is not as easily
 29608          available in widget.c.  */
 29609 
 29610       eassert (XtIsWMShell (f->output_data.x->widget));
 29611       shell = (WMShellWidget) f->output_data.x->widget;
 29612 
 29613       if (flags)
 29614         {
 29615           shell->wm.size_hints.flags &= ~(PPosition | USPosition);
 29616           shell->wm.size_hints.flags |= flags & (PPosition | USPosition);
 29617         }
 29618 
 29619       if (user_position)
 29620         {
 29621           shell->wm.size_hints.flags &= ~PPosition;
 29622           shell->wm.size_hints.flags |= USPosition;
 29623         }
 29624 
 29625 #ifndef USE_MOTIF
 29626       hints_changed
 29627         = widget_update_wm_size_hints (f->output_data.x->widget,
 29628                                        f->output_data.x->edit_widget);
 29629 #else
 29630       widget_update_wm_size_hints (f->output_data.x->widget,
 29631                                    f->output_data.x->edit_widget);
 29632 
 29633       /* Do this all over again for the benefit of Motif, which always
 29634          knows better than the programmer.  */
 29635       shell->wm.size_hints.flags &= ~(PPosition | USPosition);
 29636       shell->wm.size_hints.flags |= flags & (PPosition | USPosition);
 29637 
 29638       if (user_position)
 29639         {
 29640           shell->wm.size_hints.flags &= ~PPosition;
 29641           shell->wm.size_hints.flags |= USPosition;
 29642         }
 29643 #endif
 29644 
 29645       /* Drill hints into Motif, since it keeps setting its own.  */
 29646       size_hints.flags = shell->wm.size_hints.flags;
 29647       size_hints.x = shell->wm.size_hints.x;
 29648       size_hints.y = shell->wm.size_hints.y;
 29649       size_hints.width = shell->wm.size_hints.width;
 29650       size_hints.height = shell->wm.size_hints.height;
 29651       size_hints.min_width = shell->wm.size_hints.min_width;
 29652       size_hints.min_height = shell->wm.size_hints.min_height;
 29653       size_hints.max_width = shell->wm.size_hints.max_width;
 29654       size_hints.max_height = shell->wm.size_hints.max_height;
 29655       size_hints.width_inc = shell->wm.size_hints.width_inc;
 29656       size_hints.height_inc = shell->wm.size_hints.height_inc;
 29657       size_hints.min_aspect.x = shell->wm.size_hints.min_aspect.x;
 29658       size_hints.min_aspect.y = shell->wm.size_hints.min_aspect.y;
 29659       size_hints.max_aspect.x = shell->wm.size_hints.max_aspect.x;
 29660       size_hints.max_aspect.y = shell->wm.size_hints.max_aspect.y;
 29661       size_hints.base_width = shell->wm.base_width;
 29662       size_hints.base_height = shell->wm.base_height;
 29663       size_hints.win_gravity = shell->wm.win_gravity;
 29664 
 29665 #ifdef USE_MOTIF
 29666       XSetWMNormalHints (XtDisplay (f->output_data.x->widget),
 29667                          XtWindow (f->output_data.x->widget),
 29668                          &size_hints);
 29669 #else
 29670       /* In many cases, widget_update_wm_size_hints will not have
 29671          updated the size hints if only flags changed.  When that
 29672          happens, set the WM hints manually.  */
 29673 
 29674       if (!hints_changed)
 29675         XSetWMNormalHints (XtDisplay (f->output_data.x->widget),
 29676                            XtWindow (f->output_data.x->widget),
 29677                            &size_hints);
 29678 #endif
 29679 
 29680       return;
 29681     }
 29682 #endif
 29683 
 29684   /* Setting PMaxSize caused various problems.  */
 29685   size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
 29686 
 29687   size_hints.x = f->left_pos;
 29688   size_hints.y = f->top_pos;
 29689 
 29690   size_hints.width = FRAME_PIXEL_WIDTH (f);
 29691   size_hints.height = FRAME_PIXEL_HEIGHT (f);
 29692 
 29693   size_hints.width_inc = frame_resize_pixelwise ? 1 : FRAME_COLUMN_WIDTH (f);
 29694   size_hints.height_inc = frame_resize_pixelwise ? 1 : FRAME_LINE_HEIGHT (f);
 29695 
 29696   size_hints.max_width = x_display_pixel_width (FRAME_DISPLAY_INFO (f))
 29697     - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
 29698   size_hints.max_height = x_display_pixel_height (FRAME_DISPLAY_INFO (f))
 29699     - FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
 29700 
 29701   /* Calculate the base and minimum sizes.  */
 29702   {
 29703     int base_width, base_height;
 29704 
 29705     base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
 29706     base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
 29707 
 29708     /* The window manager uses the base width hints to calculate the
 29709        current number of rows and columns in the frame while
 29710        resizing; min_width and min_height aren't useful for this
 29711        purpose, since they might not give the dimensions for a
 29712        zero-row, zero-column frame.  */
 29713 
 29714     size_hints.flags |= PBaseSize;
 29715     size_hints.base_width = base_width;
 29716     size_hints.base_height = base_height + FRAME_MENUBAR_HEIGHT (f);
 29717     size_hints.min_width  = base_width;
 29718     size_hints.min_height = base_height;
 29719   }
 29720 
 29721   /* If we don't need the old flags, we don't need the old hint at all.  */
 29722   if (flags)
 29723     {
 29724       size_hints.flags |= flags;
 29725       goto no_read;
 29726     }
 29727 
 29728   {
 29729     XSizeHints hints;           /* Sometimes I hate X Windows... */
 29730     long supplied_return;
 29731     int value;
 29732 
 29733     value = XGetWMNormalHints (FRAME_X_DISPLAY (f), window, &hints,
 29734                                &supplied_return);
 29735 
 29736     if (flags)
 29737       size_hints.flags |= flags;
 29738     else
 29739       {
 29740         if (value == 0)
 29741           hints.flags = 0;
 29742         if (hints.flags & PSize)
 29743           size_hints.flags |= PSize;
 29744         if (hints.flags & PPosition)
 29745           size_hints.flags |= PPosition;
 29746         if (hints.flags & USPosition)
 29747           size_hints.flags |= USPosition;
 29748         if (hints.flags & USSize)
 29749           size_hints.flags |= USSize;
 29750       }
 29751   }
 29752 
 29753  no_read:
 29754 
 29755 #ifdef PWinGravity
 29756   size_hints.win_gravity = f->win_gravity;
 29757   size_hints.flags |= PWinGravity;
 29758 
 29759   if (user_position)
 29760     {
 29761       size_hints.flags &= ~ PPosition;
 29762       size_hints.flags |= USPosition;
 29763     }
 29764 #endif /* PWinGravity */
 29765 
 29766   XSetWMNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
 29767 #else
 29768   xg_wm_set_size_hint (f, flags, user_position);
 29769 #endif /* USE_GTK */
 29770 }
 29771 
 29772 /* Used for IconicState or NormalState */
 29773 
 29774 static void
 29775 x_wm_set_window_state (struct frame *f, int state)
 29776 {
 29777 #ifdef USE_X_TOOLKIT
 29778   Arg al[1];
 29779 
 29780   XtSetArg (al[0], XtNinitialState, state);
 29781   XtSetValues (f->output_data.x->widget, al, 1);
 29782 #else /* not USE_X_TOOLKIT */
 29783   Window window = FRAME_X_WINDOW (f);
 29784 
 29785   f->output_data.x->wm_hints.flags |= StateHint;
 29786   f->output_data.x->wm_hints.initial_state = state;
 29787 
 29788   XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
 29789 #endif /* not USE_X_TOOLKIT */
 29790 }
 29791 
 29792 static void
 29793 x_wm_set_icon_pixmap (struct frame *f, ptrdiff_t pixmap_id)
 29794 {
 29795   Pixmap icon_pixmap, icon_mask;
 29796 
 29797 #if !defined USE_X_TOOLKIT && !defined USE_GTK
 29798   Window window = FRAME_OUTER_WINDOW (f);
 29799 #endif
 29800 
 29801   if (pixmap_id > 0)
 29802     {
 29803       icon_pixmap = image_bitmap_pixmap (f, pixmap_id);
 29804       f->output_data.x->wm_hints.icon_pixmap = icon_pixmap;
 29805       icon_mask = x_bitmap_mask (f, pixmap_id);
 29806       f->output_data.x->wm_hints.icon_mask = icon_mask;
 29807     }
 29808   else
 29809     {
 29810       /* It seems there is no way to turn off use of an icon
 29811          pixmap.  */
 29812       return;
 29813     }
 29814 
 29815 
 29816 #ifdef USE_GTK
 29817   {
 29818     xg_set_frame_icon (f, icon_pixmap, icon_mask);
 29819     return;
 29820   }
 29821 
 29822 #elif defined (USE_X_TOOLKIT) /* same as in x_wm_set_window_state.  */
 29823 
 29824   {
 29825     Arg al[1];
 29826     XtSetArg (al[0], XtNiconPixmap, icon_pixmap);
 29827     XtSetValues (f->output_data.x->widget, al, 1);
 29828     XtSetArg (al[0], XtNiconMask, icon_mask);
 29829     XtSetValues (f->output_data.x->widget, al, 1);
 29830   }
 29831 
 29832 #else /* not USE_X_TOOLKIT && not USE_GTK */
 29833 
 29834   f->output_data.x->wm_hints.flags |= (IconPixmapHint | IconMaskHint);
 29835   XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
 29836 
 29837 #endif /* not USE_X_TOOLKIT && not USE_GTK */
 29838 }
 29839 
 29840 void
 29841 x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y)
 29842 {
 29843   Window window = FRAME_OUTER_WINDOW (f);
 29844 
 29845   f->output_data.x->wm_hints.flags |= IconPositionHint;
 29846   f->output_data.x->wm_hints.icon_x = icon_x;
 29847   f->output_data.x->wm_hints.icon_y = icon_y;
 29848 
 29849   XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints);
 29850 }
 29851 
 29852 
 29853 /***********************************************************************
 29854                                 Fonts
 29855  ***********************************************************************/
 29856 
 29857 #ifdef GLYPH_DEBUG
 29858 
 29859 /* Check that FONT is valid on frame F.  It is if it can be found in F's
 29860    font table.  */
 29861 
 29862 static void
 29863 x_check_font (struct frame *f, struct font *font)
 29864 {
 29865   eassert (font != NULL && ! NILP (font->props[FONT_TYPE_INDEX]));
 29866   if (font->driver->check)
 29867     eassert (font->driver->check (f, font) == 0);
 29868 }
 29869 
 29870 #endif /* GLYPH_DEBUG */
 29871 
 29872 
 29873 /***********************************************************************
 29874                              Image Hooks
 29875  ***********************************************************************/
 29876 
 29877 static void
 29878 x_free_pixmap (struct frame *f, Emacs_Pixmap pixmap)
 29879 {
 29880 #ifdef USE_CAIRO
 29881   if (pixmap)
 29882     {
 29883       xfree (pixmap->data);
 29884       xfree (pixmap);
 29885     }
 29886 #else
 29887   XFreePixmap (FRAME_X_DISPLAY (f), pixmap);
 29888 #endif
 29889 }
 29890 
 29891 
 29892 /***********************************************************************
 29893                             Initialization
 29894  ***********************************************************************/
 29895 
 29896 #ifdef USE_X_TOOLKIT
 29897 static XrmOptionDescRec emacs_options[] = {
 29898   {(char *) "-geometry", (char *) ".geometry", XrmoptionSepArg, NULL},
 29899   {(char *) "-iconic", (char *) ".iconic", XrmoptionNoArg, (XtPointer) "yes"},
 29900 
 29901   {(char *) "-internal-border-width",
 29902    (char *) "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL},
 29903   {(char *) "-ib", (char *) "*EmacsScreen.internalBorderWidth",
 29904    XrmoptionSepArg, NULL},
 29905   {(char *) "-T", (char *) "*EmacsShell.title", XrmoptionSepArg, NULL},
 29906   {(char *) "-wn", (char *) "*EmacsShell.title", XrmoptionSepArg, NULL},
 29907   {(char *) "-title", (char *) "*EmacsShell.title", XrmoptionSepArg, NULL},
 29908   {(char *) "-iconname", (char *) "*EmacsShell.iconName",
 29909    XrmoptionSepArg, NULL},
 29910   {(char *) "-in", (char *) "*EmacsShell.iconName", XrmoptionSepArg, NULL},
 29911   {(char *) "-mc", (char *) "*pointerColor", XrmoptionSepArg, NULL},
 29912   {(char *) "-cr", (char *) "*cursorColor", XrmoptionSepArg, NULL}
 29913 };
 29914 
 29915 /* Whether atimer for Xt timeouts is activated or not.  */
 29916 
 29917 static bool x_timeout_atimer_activated_flag;
 29918 
 29919 #endif /* USE_X_TOOLKIT */
 29920 
 29921 static int x_initialized;
 29922 
 29923 /* Test whether two display-name strings agree up to the dot that separates
 29924    the screen number from the server number.  */
 29925 static bool
 29926 same_x_server (const char *name1, const char *name2)
 29927 {
 29928   bool seen_colon = false;
 29929   Lisp_Object sysname = Fsystem_name ();
 29930   if (! STRINGP (sysname))
 29931     sysname = empty_unibyte_string;
 29932   const char *system_name = SSDATA (sysname);
 29933   ptrdiff_t system_name_length = SBYTES (sysname);
 29934   ptrdiff_t length_until_period = 0;
 29935 
 29936   while (system_name[length_until_period] != 0
 29937          && system_name[length_until_period] != '.')
 29938     length_until_period++;
 29939 
 29940   /* Treat `unix' like an empty host name.  */
 29941   if (! strncmp (name1, "unix:", 5))
 29942     name1 += 4;
 29943   if (! strncmp (name2, "unix:", 5))
 29944     name2 += 4;
 29945   /* Treat this host's name like an empty host name.  */
 29946   if (! strncmp (name1, system_name, system_name_length)
 29947       && name1[system_name_length] == ':')
 29948     name1 += system_name_length;
 29949   if (! strncmp (name2, system_name, system_name_length)
 29950       && name2[system_name_length] == ':')
 29951     name2 += system_name_length;
 29952   /* Treat this host's domainless name like an empty host name.  */
 29953   if (! strncmp (name1, system_name, length_until_period)
 29954       && name1[length_until_period] == ':')
 29955     name1 += length_until_period;
 29956   if (! strncmp (name2, system_name, length_until_period)
 29957       && name2[length_until_period] == ':')
 29958     name2 += length_until_period;
 29959 
 29960   for (; *name1 != '\0' && *name1 == *name2; name1++, name2++)
 29961     {
 29962       if (*name1 == ':')
 29963         seen_colon = true;
 29964       if (seen_colon && *name1 == '.')
 29965         return true;
 29966     }
 29967   return (seen_colon
 29968           && (*name1 == '.' || *name1 == '\0')
 29969           && (*name2 == '.' || *name2 == '\0'));
 29970 }
 29971 
 29972 /* Count number of set bits in mask and number of bits to shift to
 29973    get to the first bit.  With MASK 0x7e0, *BITS is set to 6, and *OFFSET
 29974    to 5.  */
 29975 static void
 29976 get_bits_and_offset (unsigned long mask, int *bits, int *offset)
 29977 {
 29978   int nr = 0;
 29979   int off = 0;
 29980 
 29981   while (!(mask & 1))
 29982     {
 29983       off++;
 29984       mask >>= 1;
 29985     }
 29986 
 29987   while (mask & 1)
 29988     {
 29989       nr++;
 29990       mask >>= 1;
 29991     }
 29992 
 29993   *offset = off;
 29994   *bits = nr;
 29995 }
 29996 
 29997 /* Return true iff display DISPLAY is available for use.
 29998    But don't permanently open it, just test its availability.  */
 29999 
 30000 bool
 30001 x_display_ok (const char *display)
 30002 {
 30003   /* XOpenDisplay fails if it gets a signal.  Block SIGIO which may arrive.  */
 30004   unrequest_sigio ();
 30005   Display *dpy = XOpenDisplay (display);
 30006   request_sigio ();
 30007   if (!dpy)
 30008     return false;
 30009   XCloseDisplay (dpy);
 30010   return true;
 30011 }
 30012 
 30013 #ifdef USE_GTK
 30014 static void
 30015 my_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
 30016                 const gchar *msg, gpointer user_data)
 30017 {
 30018   if (!strstr (msg, "g_set_prgname"))
 30019       fprintf (stderr, "%s-WARNING **: %s\n", log_domain, msg);
 30020 }
 30021 #endif
 30022 
 30023 /* Current X display connection identifier.  Incremented for each next
 30024    connection established.  */
 30025 static unsigned x_display_id;
 30026 
 30027 #if defined HAVE_XINPUT2 && !defined HAVE_GTK3
 30028 
 30029 /* Select for device change events on the root window of DPYINFO.
 30030    These include device change and hierarchy change notifications.  */
 30031 
 30032 static void
 30033 xi_select_hierarchy_events (struct x_display_info *dpyinfo)
 30034 {
 30035   XIEventMask mask;
 30036   ptrdiff_t l;
 30037   unsigned char *m;
 30038 
 30039   l = XIMaskLen (XI_LASTEVENT);
 30040   mask.mask = m = alloca (l);
 30041   memset (m, 0, l);
 30042   mask.mask_len = l;
 30043 
 30044   mask.deviceid = XIAllDevices;
 30045 
 30046   XISetMask (m, XI_PropertyEvent);
 30047   XISetMask (m, XI_HierarchyChanged);
 30048   XISetMask (m, XI_DeviceChanged);
 30049 
 30050   XISelectEvents (dpyinfo->display, dpyinfo->root_window,
 30051                   &mask, 1);
 30052 }
 30053 
 30054 #endif
 30055 
 30056 #if defined HAVE_XINPUT2 && defined HAVE_GTK3
 30057 
 30058 /* Look up whether or not GTK already initialized the X input
 30059    extension.
 30060 
 30061    Value is 0 if GTK was not built with the input extension, or if it
 30062    was explicitly disabled, 1 if GTK enabled the input extension and
 30063    the version was successfully determined, and 2 if that information
 30064    could not be determined.  */
 30065 
 30066 static int
 30067 xi_check_toolkit (Display *display)
 30068 {
 30069   GdkDisplay *gdpy;
 30070   GdkDeviceManager *manager;
 30071 
 30072   gdpy = gdk_x11_lookup_xdisplay (display);
 30073   eassume (gdpy);
 30074   manager = gdk_display_get_device_manager (gdpy);
 30075 
 30076   if (!strcmp (G_OBJECT_TYPE_NAME (manager),
 30077                "GdkX11DeviceManagerXI2"))
 30078     return 1;
 30079 
 30080   if (!strcmp (G_OBJECT_TYPE_NAME (manager),
 30081                "GdkX11DeviceManagerCore"))
 30082     return 0;
 30083 
 30084   /* Something changed in GDK so this information is no longer
 30085      available.  */
 30086 
 30087   return 2;
 30088 }
 30089 
 30090 #endif
 30091 
 30092 /* Open a connection to X display DISPLAY_NAME, and return the
 30093    structure that describes the open display.  If obtaining the XCB
 30094    connection or toolkit-specific display fails, return NULL.  Signal
 30095    an error if opening the display itself failed.  */
 30096 
 30097 struct x_display_info *
 30098 x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 30099 {
 30100   Display *dpy;
 30101   XKeyboardState keyboard_state;
 30102   struct terminal *terminal;
 30103   struct x_display_info *dpyinfo;
 30104   XrmDatabase xrdb;
 30105   Lisp_Object tem, quit_keysym;
 30106 #ifdef USE_XCB
 30107   xcb_connection_t *xcb_conn;
 30108 #endif
 30109   static char const cm_atom_fmt[] = "_NET_WM_CM_S%d";
 30110   char cm_atom_sprintf[sizeof cm_atom_fmt - 2 + INT_STRLEN_BOUND (int)];
 30111 #ifdef USE_GTK
 30112   GdkDisplay *gdpy;
 30113   GdkScreen *gscr;
 30114 #endif
 30115 #ifdef HAVE_XFIXES
 30116   Lisp_Object lisp_name;
 30117   int num_fast_selections;
 30118   Atom selection_name;
 30119 #ifdef USE_XCB
 30120   xcb_get_selection_owner_cookie_t *selection_cookies;
 30121   xcb_get_selection_owner_reply_t *selection_reply;
 30122   xcb_generic_error_t *selection_error;
 30123 #endif
 30124 #endif
 30125   int i;
 30126 
 30127 #if defined HAVE_XFIXES && defined USE_XCB
 30128   USE_SAFE_ALLOCA;
 30129 #endif
 30130 
 30131   block_input ();
 30132 
 30133   if (!x_initialized)
 30134     {
 30135       x_initialize ();
 30136       ++x_initialized;
 30137     }
 30138 
 30139 #if defined USE_X_TOOLKIT || defined USE_GTK
 30140 
 30141   if (!x_display_ok (SSDATA (display_name)))
 30142     error ("Display %s can't be opened", SSDATA (display_name));
 30143 
 30144 #endif
 30145 
 30146 #ifdef USE_GTK
 30147   {
 30148 #define NUM_ARGV 10
 30149     int argc;
 30150     char *argv[NUM_ARGV];
 30151     char **argv2 = argv;
 30152     guint id;
 30153 
 30154     if (x_initialized++ > 1)
 30155       {
 30156         xg_display_open (SSDATA (display_name), &dpy);
 30157       }
 30158     else
 30159       {
 30160         static char display_opt[] = "--display";
 30161         static char name_opt[] = "--name";
 30162 
 30163         for (argc = 0; argc < NUM_ARGV; ++argc)
 30164           argv[argc] = 0;
 30165 
 30166         argc = 0;
 30167         argv[argc++] = initial_argv[0];
 30168 
 30169         if (! NILP (display_name))
 30170           {
 30171             argv[argc++] = display_opt;
 30172             argv[argc++] = SSDATA (display_name);
 30173           }
 30174 
 30175         argv[argc++] = name_opt;
 30176         argv[argc++] = resource_name;
 30177 
 30178         XSetLocaleModifiers ("");
 30179 
 30180         /* Work around GLib bug that outputs a faulty warning. See
 30181            https://bugzilla.gnome.org/show_bug.cgi?id=563627.  */
 30182         id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL
 30183                                   | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
 30184 
 30185         /* NULL window -> events for all windows go to our function.
 30186            Call before gtk_init so Gtk+ event filters comes after our.  */
 30187         gdk_window_add_filter (NULL, event_handler_gdk, NULL);
 30188 
 30189         /* gtk_init does set_locale.  Fix locale before and after.  */
 30190         fixup_locale ();
 30191         unrequest_sigio (); /* See comment in x_display_ok.  */
 30192         gtk_init (&argc, &argv2);
 30193         request_sigio ();
 30194 
 30195         g_log_remove_handler ("GLib", id);
 30196 
 30197         xg_initialize ();
 30198 
 30199         /* Do this after the call to xg_initialize, because when
 30200            Fontconfig is used, xg_initialize calls its initialization
 30201            function which in some versions of Fontconfig calls setlocale.  */
 30202         fixup_locale ();
 30203 
 30204         dpy = DEFAULT_GDK_DISPLAY ();
 30205 
 30206 #ifndef HAVE_GTK3
 30207         /* Load our own gtkrc if it exists.  */
 30208         {
 30209           const char *file = "~/.emacs.d/gtkrc";
 30210           Lisp_Object s, abs_file;
 30211 
 30212           s = build_string (file);
 30213           abs_file = Fexpand_file_name (s, Qnil);
 30214 
 30215           if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file)))
 30216             gtk_rc_parse (SSDATA (abs_file));
 30217         }
 30218 #endif
 30219 
 30220         XSetErrorHandler (x_error_handler);
 30221         XSetIOErrorHandler (x_io_error_quitter);
 30222       }
 30223   }
 30224 #else /* not USE_GTK */
 30225 #ifdef USE_X_TOOLKIT
 30226   /* weiner@footloose.sps.mot.com reports that this causes
 30227      errors with X11R5:
 30228            X protocol error: BadAtom (invalid Atom parameter)
 30229            on protocol request 18skiloaf.
 30230      So let's not use it until R6.  */
 30231 #ifdef HAVE_X11XTR6
 30232   XtSetLanguageProc (NULL, NULL, NULL);
 30233 #endif
 30234 
 30235   {
 30236     int argc = 0;
 30237     char *argv[3];
 30238 
 30239     argv[0] = (char *) "";
 30240     argc = 1;
 30241     if (xrm_option)
 30242       {
 30243         argv[argc++] = (char *) "-xrm";
 30244         argv[argc++] = xrm_option;
 30245       }
 30246     turn_on_atimers (false);
 30247     unrequest_sigio ();  /* See comment in x_display_ok.  */
 30248     dpy = XtOpenDisplay (Xt_app_con, SSDATA (display_name),
 30249                          resource_name, EMACS_CLASS,
 30250                          emacs_options, XtNumber (emacs_options),
 30251                          &argc, argv);
 30252     request_sigio ();
 30253     turn_on_atimers (true);
 30254 
 30255 #ifdef HAVE_X11XTR6
 30256     /* I think this is to compensate for XtSetLanguageProc.  */
 30257     fixup_locale ();
 30258 #endif
 30259   }
 30260 
 30261 #else /* not USE_X_TOOLKIT */
 30262   XSetLocaleModifiers ("");
 30263   unrequest_sigio ();  /* See comment in x_display_ok.  */
 30264   dpy = XOpenDisplay (SSDATA (display_name));
 30265   request_sigio ();
 30266 #endif /* not USE_X_TOOLKIT */
 30267 #endif /* not USE_GTK*/
 30268 
 30269   /* Detect failure.  */
 30270   if (dpy == 0)
 30271     {
 30272 #if !defined USE_X_TOOLKIT && !defined USE_GTK
 30273       /* Avoid opening a display three times (once in dispextern.c
 30274          upon startup, once in x_display_ok, and once above) to
 30275          determine whether or not the display is alive on no toolkit
 30276          builds, where no toolkit initialization happens at all.  */
 30277 
 30278       error ("Display %s can't be opened", SSDATA (display_name));
 30279 #endif
 30280 
 30281       unblock_input ();
 30282 
 30283 #if defined HAVE_XFIXES && defined USE_XCB
 30284       SAFE_FREE ();
 30285 #endif
 30286       return 0;
 30287     }
 30288 
 30289 #ifdef USE_XCB
 30290   xcb_conn = XGetXCBConnection (dpy);
 30291   if (!xcb_conn)
 30292     {
 30293 #ifdef USE_GTK
 30294       xg_display_close (dpy);
 30295 #else
 30296 #ifdef USE_X_TOOLKIT
 30297       XtCloseDisplay (dpy);
 30298 #else
 30299       XCloseDisplay (dpy);
 30300 #endif
 30301 #endif /* ! USE_GTK */
 30302 
 30303       unblock_input ();
 30304 
 30305 #if defined HAVE_XFIXES && defined USE_XCB
 30306       SAFE_FREE ();
 30307 #endif
 30308       return 0;
 30309     }
 30310 #endif
 30311 
 30312   /* Select for structure events on the root window, since this allows
 30313      us to record changes to the size of the screen.  */
 30314 
 30315   XSelectInput (dpy, DefaultRootWindow (dpy), StructureNotifyMask);
 30316 
 30317   /* We have definitely succeeded.  Record the new connection.  */
 30318 
 30319   dpyinfo = xzalloc (sizeof *dpyinfo);
 30320   terminal = x_create_terminal (dpyinfo);
 30321 
 30322   if (!NILP (Vx_detect_server_trust))
 30323     {
 30324       /* Detect whether or not the X server trusts this client, which
 30325          is done by making a SetKeyboardControl request and checking
 30326          for an Access error.  */
 30327       XGrabServer (dpy);
 30328       XGetKeyboardControl (dpy, &keyboard_state);
 30329 
 30330       x_catch_errors (dpy);
 30331 
 30332       /* At this point, the display is not on x_display_list, so
 30333          x_uncatch_errors won't sync.  However, that's okay because
 30334          x_had_errors_p will.  */
 30335 
 30336       if (keyboard_state.global_auto_repeat
 30337           == AutoRepeatModeOn)
 30338         XAutoRepeatOn (dpy);
 30339       else
 30340         XAutoRepeatOff (dpy);
 30341 
 30342       if (x_had_errors_p (dpy))
 30343         dpyinfo->untrusted = true;
 30344       x_uncatch_errors_after_check ();
 30345       XUngrabServer (dpy);
 30346     }
 30347 
 30348   dpyinfo->next_failable_request = dpyinfo->failable_requests;
 30349 
 30350   {
 30351     struct x_display_info *share;
 30352 
 30353     for (share = x_display_list; share; share = share->next)
 30354       if (same_x_server (SSDATA (XCAR (share->name_list_element)),
 30355                          SSDATA (display_name)))
 30356         break;
 30357     if (share)
 30358       terminal->kboard = share->terminal->kboard;
 30359     else
 30360       {
 30361         terminal->kboard = allocate_kboard (Qx);
 30362 
 30363         if (!BASE_EQ (XSYMBOL (Qvendor_specific_keysyms)->u.s.function,
 30364                       Qunbound))
 30365           {
 30366             char *vendor = ServerVendor (dpy);
 30367 
 30368             /* Temporarily hide the partially initialized terminal.
 30369                Use safe_call so that if a signal happens, a partially
 30370                initialized display (and display connection) is not
 30371                kept around.  */
 30372             terminal_list = terminal->next_terminal;
 30373             unblock_input ();
 30374             kset_system_key_alist (terminal->kboard,
 30375                                    safe_call1 (Qvendor_specific_keysyms,
 30376                                                (vendor
 30377                                                 ? build_string (vendor)
 30378                                                 : empty_unibyte_string)));
 30379             block_input ();
 30380             terminal->next_terminal = terminal_list;
 30381             terminal_list = terminal;
 30382           }
 30383 
 30384         /* Don't let the initial kboard remain current longer than necessary.
 30385            That would cause problems if a file loaded on startup tries to
 30386            prompt in the mini-buffer.  */
 30387         if (current_kboard == initial_kboard)
 30388           current_kboard = terminal->kboard;
 30389       }
 30390     terminal->kboard->reference_count++;
 30391   }
 30392 
 30393   /* Now look through Vx_quit_keysym for the quit keysym associated
 30394      with this display.  */
 30395   tem = Vx_quit_keysym;
 30396   FOR_EACH_TAIL_SAFE (tem)
 30397     {
 30398       quit_keysym = XCAR (tem);
 30399 
 30400       /* Check if its car is a string and its cdr a valid keysym.
 30401          Skip if it is not.  */
 30402 
 30403       if (!CONSP (quit_keysym) || !FIXNUMP (XCDR (quit_keysym))
 30404           || !STRINGP (XCAR (quit_keysym)))
 30405         continue;
 30406 
 30407       /* Check if this is the keysym to be used.  */
 30408 
 30409       if (strcmp (SSDATA (XCAR (quit_keysym)), ServerVendor (dpy)))
 30410         continue;
 30411 
 30412       dpyinfo->quit_keysym = XFIXNUM (XCDR (quit_keysym));
 30413     }
 30414 
 30415   /* Put this display on the chain.  */
 30416   dpyinfo->next = x_display_list;
 30417   x_display_list = dpyinfo;
 30418 
 30419   dpyinfo->name_list_element = Fcons (display_name, Qnil);
 30420   dpyinfo->display = dpy;
 30421   dpyinfo->connection = ConnectionNumber (dpyinfo->display);
 30422 #ifdef USE_XCB
 30423   dpyinfo->xcb_connection = xcb_conn;
 30424 #endif
 30425 
 30426   /* https://lists.gnu.org/r/emacs-devel/2015-11/msg00194.html  */
 30427   dpyinfo->smallest_font_height = 1;
 30428   dpyinfo->smallest_char_width = 1;
 30429 
 30430   dpyinfo->color_names_size = 256;
 30431   dpyinfo->color_names = xzalloc (dpyinfo->color_names_size
 30432                                   * sizeof *dpyinfo->color_names);
 30433   dpyinfo->color_names_length = xzalloc (dpyinfo->color_names_size
 30434                                          * sizeof *dpyinfo->color_names_length);
 30435 
 30436   /* Set the name of the terminal. */
 30437   terminal->name = xlispstrdup (display_name);
 30438 
 30439 #if false
 30440   XSetAfterFunction (dpyinfo->display, x_trace_wire);
 30441 #endif
 30442 
 30443   Lisp_Object system_name = Fsystem_name ();
 30444   static char const title[] = "GNU Emacs";
 30445   if (STRINGP (system_name))
 30446     {
 30447       static char const at[] = " at ";
 30448       ptrdiff_t nbytes = sizeof (title) + sizeof (at);
 30449       if (ckd_add (&nbytes, nbytes, SBYTES (system_name)))
 30450         memory_full (SIZE_MAX);
 30451       dpyinfo->x_id_name = xmalloc (nbytes);
 30452       sprintf (dpyinfo->x_id_name, "%s%s%s", title, at, SDATA (system_name));
 30453     }
 30454   else
 30455     {
 30456       dpyinfo->x_id_name = xmalloc (sizeof (title));
 30457       strcpy (dpyinfo->x_id_name, title);
 30458     }
 30459 
 30460   dpyinfo->x_id = ++x_display_id;
 30461 
 30462 #ifndef HAVE_XKB
 30463   /* Figure out which modifier bits mean what.  */
 30464   x_find_modifier_meanings (dpyinfo);
 30465 #endif
 30466 
 30467   /* Get the scroll bar cursor.  */
 30468 #ifdef USE_GTK
 30469   /* We must create a GTK cursor, it is required for GTK widgets.  */
 30470   dpyinfo->xg_cursor = xg_create_default_cursor (dpyinfo->display);
 30471 #endif /* USE_GTK */
 30472 
 30473   dpyinfo->vertical_scroll_bar_cursor
 30474     = XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow);
 30475 
 30476   dpyinfo->horizontal_scroll_bar_cursor
 30477     = XCreateFontCursor (dpyinfo->display, XC_sb_h_double_arrow);
 30478 
 30479   xrdb = x_load_resources (dpyinfo->display, xrm_option,
 30480                            resource_name, EMACS_CLASS);
 30481 #ifdef HAVE_XRMSETDATABASE
 30482   XrmSetDatabase (dpyinfo->display, xrdb);
 30483 #else
 30484   dpyinfo->display->db = xrdb;
 30485 #endif
 30486 
 30487 #ifdef HAVE_XRENDER
 30488   int event_base, error_base;
 30489   dpyinfo->xrender_supported_p
 30490     = XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
 30491 
 30492   if (dpyinfo->xrender_supported_p)
 30493     dpyinfo->xrender_supported_p
 30494       = XRenderQueryVersion (dpyinfo->display, &dpyinfo->xrender_major,
 30495                              &dpyinfo->xrender_minor);
 30496 #endif
 30497 
 30498   /* This must come after XRenderQueryVersion! */
 30499 #ifdef HAVE_XCOMPOSITE
 30500   int composite_event_base, composite_error_base;
 30501   dpyinfo->composite_supported_p = XCompositeQueryExtension (dpyinfo->display,
 30502                                                              &composite_event_base,
 30503                                                              &composite_error_base);
 30504 
 30505   if (dpyinfo->composite_supported_p)
 30506     dpyinfo->composite_supported_p
 30507       = XCompositeQueryVersion (dpyinfo->display,
 30508                                 &dpyinfo->composite_major,
 30509                                 &dpyinfo->composite_minor);
 30510 #endif
 30511 
 30512 #ifdef HAVE_XSHAPE
 30513   dpyinfo->xshape_supported_p
 30514     = XShapeQueryExtension (dpyinfo->display,
 30515                             &dpyinfo->xshape_event_base,
 30516                             &dpyinfo->xshape_error_base);
 30517 
 30518   if (dpyinfo->xshape_supported_p)
 30519     dpyinfo->xshape_supported_p
 30520       = XShapeQueryVersion (dpyinfo->display,
 30521                             &dpyinfo->xshape_major,
 30522                             &dpyinfo->xshape_minor);
 30523 #endif
 30524 
 30525   /* Put the rdb where we can find it in a way that works on
 30526      all versions.  */
 30527   dpyinfo->rdb = xrdb;
 30528 
 30529   dpyinfo->screen = ScreenOfDisplay (dpyinfo->display,
 30530                                      DefaultScreen (dpyinfo->display));
 30531   select_visual (dpyinfo);
 30532   dpyinfo->cmap = DefaultColormapOfScreen (dpyinfo->screen);
 30533   dpyinfo->root_window = RootWindowOfScreen (dpyinfo->screen);
 30534   dpyinfo->icon_bitmap_id = -1;
 30535   dpyinfo->wm_type = X_WMTYPE_UNKNOWN;
 30536 
 30537   reset_mouse_highlight (&dpyinfo->mouse_highlight);
 30538 
 30539 #ifdef HAVE_XRENDER
 30540   if (dpyinfo->xrender_supported_p
 30541       /* This could already have been initialized by
 30542          `select_visual'.  */
 30543       && !dpyinfo->pict_format)
 30544     dpyinfo->pict_format = XRenderFindVisualFormat (dpyinfo->display,
 30545                                                     dpyinfo->visual);
 30546 #endif
 30547 
 30548 #ifdef HAVE_XSYNC
 30549   int xsync_event_base, xsync_error_base;
 30550   dpyinfo->xsync_supported_p
 30551     = XSyncQueryExtension (dpyinfo->display,
 30552                            &xsync_event_base,
 30553                            &xsync_error_base);
 30554 
 30555   if (dpyinfo->xsync_supported_p)
 30556     dpyinfo->xsync_supported_p = XSyncInitialize (dpyinfo->display,
 30557                                                   &dpyinfo->xsync_major,
 30558                                                   &dpyinfo->xsync_minor);
 30559 
 30560   {
 30561     AUTO_STRING (synchronizeResize, "synchronizeResize");
 30562     AUTO_STRING (SynchronizeResize, "SynchronizeResize");
 30563 
 30564     Lisp_Object value = gui_display_get_resource (dpyinfo,
 30565                                                   synchronizeResize,
 30566                                                   SynchronizeResize,
 30567                                                   Qnil, Qnil);
 30568 
 30569     if (STRINGP (value)
 30570         && (!strcmp (SSDATA (value), "false")
 30571             || !strcmp (SSDATA (value), "off")))
 30572       dpyinfo->xsync_supported_p = false;
 30573   }
 30574 #endif
 30575 
 30576 #ifdef HAVE_XINERAMA
 30577   int xin_event_base, xin_error_base;
 30578   dpyinfo->xinerama_supported_p
 30579     = XineramaQueryExtension (dpy, &xin_event_base, &xin_error_base);
 30580 #endif
 30581 
 30582   /* See if a private colormap is requested.  */
 30583   if (dpyinfo->visual == DefaultVisualOfScreen (dpyinfo->screen))
 30584     {
 30585       if (dpyinfo->visual_info.class == PseudoColor)
 30586         {
 30587           AUTO_STRING (privateColormap, "privateColormap");
 30588           AUTO_STRING (PrivateColormap, "PrivateColormap");
 30589           Lisp_Object value
 30590             = gui_display_get_resource (dpyinfo, privateColormap,
 30591                                         PrivateColormap, Qnil, Qnil);
 30592           if (STRINGP (value)
 30593               && (!strcmp (SSDATA (value), "true")
 30594                   || !strcmp (SSDATA (value), "on")))
 30595             dpyinfo->cmap = XCopyColormapAndFree (dpyinfo->display, dpyinfo->cmap);
 30596         }
 30597     }
 30598   else
 30599     dpyinfo->cmap = XCreateColormap (dpyinfo->display, dpyinfo->root_window,
 30600                                      dpyinfo->visual, AllocNone);
 30601 
 30602   /* See if we can construct pixel values from RGB values.  */
 30603   if (dpyinfo->visual_info.class == TrueColor)
 30604     {
 30605       get_bits_and_offset (dpyinfo->visual_info.red_mask,
 30606                            &dpyinfo->red_bits, &dpyinfo->red_offset);
 30607       get_bits_and_offset (dpyinfo->visual_info.blue_mask,
 30608                            &dpyinfo->blue_bits, &dpyinfo->blue_offset);
 30609       get_bits_and_offset (dpyinfo->visual_info.green_mask,
 30610                            &dpyinfo->green_bits, &dpyinfo->green_offset);
 30611 
 30612 #ifdef HAVE_XRENDER
 30613       if (dpyinfo->pict_format)
 30614         {
 30615           unsigned long channel_mask
 30616             = ((unsigned long) dpyinfo->pict_format->direct.alphaMask
 30617                << dpyinfo->pict_format->direct.alpha);
 30618 
 30619           if (channel_mask)
 30620             get_bits_and_offset (channel_mask, &dpyinfo->alpha_bits,
 30621                                  &dpyinfo->alpha_offset);
 30622           dpyinfo->alpha_mask = channel_mask;
 30623         }
 30624       else
 30625 #endif
 30626         {
 30627           XColor xc;
 30628           unsigned long alpha_mask;
 30629           xc.red = 65535;
 30630           xc.green = 65535;
 30631           xc.blue = 65535;
 30632 
 30633           if (XAllocColor (dpyinfo->display,
 30634                            dpyinfo->cmap, &xc) != 0)
 30635             {
 30636               alpha_mask = xc.pixel & ~(dpyinfo->visual_info.red_mask
 30637                                         | dpyinfo->visual_info.blue_mask
 30638                                         | dpyinfo->visual_info.green_mask);
 30639 
 30640               if (alpha_mask)
 30641                 get_bits_and_offset (alpha_mask, &dpyinfo->alpha_bits,
 30642                                      &dpyinfo->alpha_offset);
 30643               dpyinfo->alpha_mask = alpha_mask;
 30644             }
 30645         }
 30646     }
 30647 
 30648 #ifdef HAVE_XDBE
 30649   dpyinfo->supports_xdbe = false;
 30650   int xdbe_major;
 30651   int xdbe_minor;
 30652   if (XdbeQueryExtension (dpyinfo->display, &xdbe_major, &xdbe_minor))
 30653     dpyinfo->supports_xdbe = true;
 30654 #endif
 30655 
 30656 #ifdef USE_XCB
 30657   xcb_screen_t *xcb_screen = NULL;
 30658   xcb_screen_iterator_t iter;
 30659   xcb_visualid_t wanted = { XVisualIDFromVisual (dpyinfo->visual) };
 30660   xcb_depth_iterator_t depth_iter;
 30661   xcb_visualtype_iterator_t visual_iter;
 30662 
 30663   int screen = DefaultScreen (dpyinfo->display);
 30664 
 30665   iter = xcb_setup_roots_iterator (xcb_get_setup (dpyinfo->xcb_connection));
 30666   for (; iter.rem; --screen, xcb_screen_next (&iter))
 30667     {
 30668       if (!screen)
 30669         xcb_screen = iter.data;
 30670     }
 30671 
 30672   if (xcb_screen)
 30673     {
 30674       depth_iter = xcb_screen_allowed_depths_iterator (xcb_screen);
 30675       for (; depth_iter.rem; xcb_depth_next (&depth_iter))
 30676         {
 30677           visual_iter = xcb_depth_visuals_iterator (depth_iter.data);
 30678           for (; visual_iter.rem; xcb_visualtype_next (&visual_iter))
 30679             {
 30680               if (wanted == visual_iter.data->visual_id)
 30681                 {
 30682                   dpyinfo->xcb_visual = visual_iter.data;
 30683                   break;
 30684                 }
 30685             }
 30686         }
 30687     }
 30688 #endif
 30689 
 30690 #ifdef HAVE_XINPUT2
 30691   dpyinfo->supports_xi2 = false;
 30692   int rc;
 30693   int major = 2;
 30694   int xi_first_event, xi_first_error;
 30695 
 30696 #ifndef HAVE_GTK3
 30697   {
 30698     AUTO_STRING (disableInputExtension, "disableInputExtension");
 30699     AUTO_STRING (DisableInputExtension, "DisableInputExtension");
 30700 
 30701     Lisp_Object value = gui_display_get_resource (dpyinfo,
 30702                                                   disableInputExtension,
 30703                                                   DisableInputExtension,
 30704                                                   Qnil, Qnil);
 30705 
 30706     if (STRINGP (value)
 30707         && (!strcmp (SSDATA (value), "on")
 30708             || !strcmp (SSDATA (value), "true")))
 30709       goto skip_xi_setup;
 30710   }
 30711 #endif
 30712 
 30713 #ifdef HAVE_XINPUT2_4
 30714   int minor = 4;
 30715 #elif defined HAVE_XINPUT2_3 /* XInput 2.3 */
 30716   int minor = 3;
 30717 #elif defined HAVE_XINPUT2_2 /* XInput 2.2 */
 30718   int minor = 2;
 30719 #elif defined HAVE_XINPUT2_1 /* XInput 2.1 */
 30720   int minor = 1;
 30721 #else /* Some old version of XI2 we're not interested in. */
 30722   int minor = 0;
 30723 #endif
 30724 
 30725   dpyinfo->client_pointer_device = -1;
 30726 
 30727 #ifdef HAVE_GTK3
 30728   /* GTK gets a chance to request use of the input extension first.
 30729      If we later try to enable it if GDK did not, then GTK will not
 30730      get the resulting extension events.  */
 30731 
 30732   rc = xi_check_toolkit (dpyinfo->display);
 30733 
 30734   if (!rc)
 30735     goto skip_xi_setup;
 30736 #endif
 30737 
 30738   if (XQueryExtension (dpyinfo->display, "XInputExtension",
 30739                        &dpyinfo->xi2_opcode, &xi_first_event,
 30740                        &xi_first_error))
 30741     {
 30742 #ifdef HAVE_GTK3
 30743       bool move_backwards = false;
 30744       int original_minor = minor;
 30745 
 30746     query:
 30747 
 30748       /* Catch errors caused by GTK requesting a different version of
 30749          XInput 2 than what Emacs was built with.  Usually, the X
 30750          server tolerates these mistakes, but a BadValue error can
 30751          result if only one of GTK or Emacs wasn't built with support
 30752          for XInput 2.2.
 30753 
 30754          To work around the first, it suffices to increase the minor
 30755          version until the X server is happy if the XIQueryVersion
 30756          request results in an error.  If that doesn't work, however,
 30757          then it's the latter, so decrease the minor until the version
 30758          that GTK requested is found.  */
 30759 #endif
 30760 
 30761       x_catch_errors (dpyinfo->display);
 30762 
 30763       rc = XIQueryVersion (dpyinfo->display, &major, &minor);
 30764 
 30765 #ifdef HAVE_GTK3
 30766       /* Increase the minor version until we find one the X
 30767          server agrees with.  If that didn't work, then
 30768          decrease the version until it either hits zero or
 30769          becomes agreeable to the X server.  */
 30770 
 30771       if (x_had_errors_p (dpyinfo->display))
 30772         {
 30773           x_uncatch_errors_after_check ();
 30774 
 30775           /* Since BadValue errors can't be generated if both the
 30776              prior and current requests specify a version of 2.2 or
 30777              later, this means the prior request specified a version
 30778              of the input extension less than 2.2.  */
 30779           if (minor >= 2)
 30780             {
 30781               move_backwards = true;
 30782               minor = original_minor;
 30783 
 30784               if (--minor < 0)
 30785                 rc = BadRequest;
 30786               else
 30787                 goto query;
 30788             }
 30789           else
 30790             {
 30791               if (!move_backwards)
 30792                 {
 30793                   minor++;
 30794                   goto query;
 30795                 }
 30796 
 30797               if (--minor < 0)
 30798                 rc = BadRequest;
 30799               else
 30800                 goto query;
 30801 
 30802             }
 30803         }
 30804       else
 30805         x_uncatch_errors_after_check ();
 30806 
 30807       /* But don't delude ourselves into thinking that we can use
 30808          features provided by a version of the input extension that
 30809          libXi itself doesn't support.  */
 30810 
 30811       if (minor > original_minor)
 30812         minor = original_minor;
 30813 #else
 30814       if (x_had_errors_p (dpyinfo->display))
 30815         rc = BadRequest;
 30816 
 30817       x_uncatch_errors_after_check ();
 30818 #endif
 30819 
 30820       if (rc == Success)
 30821         {
 30822           dpyinfo->supports_xi2 = true;
 30823 #ifndef HAVE_GTK3
 30824           /* Select for hierarchy events on the root window.  GTK 3.x
 30825              does this itself.  */
 30826           xi_select_hierarchy_events (dpyinfo);
 30827 #endif
 30828 
 30829           dpyinfo->xi2_version = minor;
 30830           x_cache_xi_devices (dpyinfo);
 30831         }
 30832     }
 30833  skip_xi_setup:
 30834   ;
 30835 #endif
 30836 
 30837 #if defined HAVE_XRANDR || defined USE_GTK
 30838   Lisp_Object term;
 30839 
 30840   XSETTERMINAL (term, terminal);
 30841 #endif
 30842 
 30843 #ifdef HAVE_XRANDR
 30844   dpyinfo->xrandr_supported_p
 30845     = XRRQueryExtension (dpy, &dpyinfo->xrandr_event_base,
 30846                          &dpyinfo->xrandr_error_base);
 30847 
 30848 #ifndef USE_GTK
 30849   dpyinfo->last_monitor_attributes_list = Qnil;
 30850 #endif
 30851 
 30852   if (dpyinfo->xrandr_supported_p)
 30853     {
 30854       XRRQueryVersion (dpy, &dpyinfo->xrandr_major_version,
 30855                        &dpyinfo->xrandr_minor_version);
 30856 
 30857 #ifndef USE_GTK
 30858       if (dpyinfo->xrandr_major_version == 1
 30859           && dpyinfo->xrandr_minor_version >= 2)
 30860         {
 30861           XRRSelectInput (dpyinfo->display,
 30862                           dpyinfo->root_window,
 30863                           (RRScreenChangeNotifyMask
 30864                            | RRCrtcChangeNotifyMask
 30865                            | RROutputChangeNotifyMask
 30866 #ifdef USE_GTK
 30867                            /* Emacs doesn't actually need this, but
 30868                               GTK selects for it when the display is
 30869                               initialized.  */
 30870                            | RROutputPropertyNotifyMask
 30871 #endif
 30872                            ));
 30873 
 30874           dpyinfo->last_monitor_attributes_list
 30875             = Fx_display_monitor_attributes_list (term);
 30876         }
 30877 #endif
 30878     }
 30879 #endif
 30880 
 30881 #ifdef USE_GTK
 30882   dpyinfo->last_monitor_attributes_list
 30883     = Fx_display_monitor_attributes_list (term);
 30884 
 30885   gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 30886   gscr = gdk_display_get_default_screen (gdpy);
 30887 
 30888   g_signal_connect (G_OBJECT (gscr), "monitors-changed",
 30889                     G_CALLBACK (x_monitors_changed_cb),
 30890                     NULL);
 30891 #endif
 30892 
 30893 #ifdef HAVE_XKB
 30894   int xkb_major, xkb_minor, xkb_op, xkb_error_code;
 30895   xkb_major = XkbMajorVersion;
 30896   xkb_minor = XkbMinorVersion;
 30897 
 30898   if (XkbLibraryVersion (&xkb_major, &xkb_minor)
 30899       && XkbQueryExtension (dpyinfo->display, &xkb_op, &dpyinfo->xkb_event_type,
 30900                             &xkb_error_code, &xkb_major, &xkb_minor))
 30901     {
 30902       dpyinfo->supports_xkb = true;
 30903       dpyinfo->xkb_desc = XkbGetMap (dpyinfo->display,
 30904                                      (XkbKeySymsMask
 30905                                       | XkbKeyTypesMask
 30906                                       | XkbModifierMapMask
 30907                                       | XkbVirtualModsMask),
 30908                                      XkbUseCoreKbd);
 30909 
 30910       if (dpyinfo->xkb_desc)
 30911         XkbGetNames (dpyinfo->display, XkbAllNamesMask,
 30912                      dpyinfo->xkb_desc);
 30913 
 30914       XkbSelectEvents (dpyinfo->display, XkbUseCoreKbd,
 30915                        XkbNewKeyboardNotifyMask | XkbMapNotifyMask,
 30916                        XkbNewKeyboardNotifyMask | XkbMapNotifyMask);
 30917     }
 30918 #endif
 30919 
 30920 #ifdef HAVE_XFIXES
 30921   int xfixes_error_base;
 30922   dpyinfo->xfixes_supported_p
 30923     = XFixesQueryExtension (dpyinfo->display,
 30924                             &dpyinfo->xfixes_event_base,
 30925                             &xfixes_error_base);
 30926 
 30927   if (dpyinfo->xfixes_supported_p)
 30928     {
 30929       if (!XFixesQueryVersion (dpyinfo->display, &dpyinfo->xfixes_major,
 30930                                &dpyinfo->xfixes_minor))
 30931         dpyinfo->xfixes_supported_p = false;
 30932     }
 30933 #endif
 30934 
 30935 #if defined USE_CAIRO || defined HAVE_XFT
 30936   {
 30937     /* If we are using Xft, the following precautions should be made:
 30938 
 30939        1. Make sure that the Xrender extension is added before the Xft one.
 30940        Otherwise, the close-display hook set by Xft is called after the one
 30941        for Xrender, and the former tries to re-add the latter.  This results
 30942        in inconsistency of internal states and leads to X protocol error when
 30943        one reconnects to the same X server (Bug#1696).
 30944 
 30945        2. Check dpi value in X resources.  It is better we use it as well,
 30946        since Xft will use it, as will all Gnome applications.  If our real DPI
 30947        is smaller or larger than the one Xft uses, our font will look smaller
 30948        or larger than other for other applications, even if it is the same
 30949        font name (monospace-10 for example).  */
 30950 
 30951     char *v = XGetDefault (dpyinfo->display, "Xft", "dpi");
 30952     double d;
 30953     if (v != NULL && sscanf (v, "%lf", &d) == 1)
 30954       dpyinfo->resy = dpyinfo->resx = d;
 30955   }
 30956 #endif
 30957 
 30958   if (dpyinfo->resy < 1)
 30959     {
 30960       int screen_number = XScreenNumberOfScreen (dpyinfo->screen);
 30961       double pixels = DisplayHeight (dpyinfo->display, screen_number);
 30962       double mm = DisplayHeightMM (dpyinfo->display, screen_number);
 30963       /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
 30964       dpyinfo->resy = (mm < 1) ? 100 : pixels * 25.4 / mm;
 30965       pixels = DisplayWidth (dpyinfo->display, screen_number);
 30966       mm = DisplayWidthMM (dpyinfo->display, screen_number);
 30967       /* Mac OS X 10.3's Xserver sometimes reports 0.0mm.  */
 30968       dpyinfo->resx = (mm < 1) ? 100 : pixels * 25.4 / mm;
 30969     }
 30970 
 30971   sprintf (cm_atom_sprintf, cm_atom_fmt,
 30972            XScreenNumberOfScreen (dpyinfo->screen));
 30973 
 30974   {
 30975     enum { atom_count = ARRAYELTS (x_atom_refs) };
 30976     /* 1 for _XSETTINGS_SN.  */
 30977     enum { total_atom_count = 2 + atom_count };
 30978     Atom atoms_return[total_atom_count];
 30979     char *atom_names[total_atom_count];
 30980     static char const xsettings_fmt[] = "_XSETTINGS_S%d";
 30981     char xsettings_atom_name[sizeof xsettings_fmt - 2
 30982                              + INT_STRLEN_BOUND (int)];
 30983 
 30984     for (i = 0; i < atom_count; i++)
 30985       atom_names[i] = (char *) x_atom_refs[i].name;
 30986 
 30987     /* Build _XSETTINGS_SN atom name.  */
 30988     sprintf (xsettings_atom_name, xsettings_fmt,
 30989              XScreenNumberOfScreen (dpyinfo->screen));
 30990     atom_names[i] = xsettings_atom_name;
 30991     atom_names[i + 1] = cm_atom_sprintf;
 30992 
 30993     XInternAtoms (dpyinfo->display, atom_names, total_atom_count,
 30994                   False, atoms_return);
 30995 
 30996     for (i = 0; i < atom_count; i++)
 30997       *(Atom *) ((char *) dpyinfo + x_atom_refs[i].offset) = atoms_return[i];
 30998 
 30999     /* Manually copy last two atoms.  */
 31000     dpyinfo->Xatom_xsettings_sel = atoms_return[i];
 31001     dpyinfo->Xatom_NET_WM_CM_Sn = atoms_return[i + 1];
 31002   }
 31003 
 31004 #ifdef HAVE_XKB
 31005   /* Figure out which modifier bits mean what.  */
 31006   x_find_modifier_meanings (dpyinfo);
 31007 #endif
 31008 
 31009   dpyinfo->x_dnd_atoms_size = 16;
 31010   dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms
 31011                                   * dpyinfo->x_dnd_atoms_size);
 31012   dpyinfo->gray
 31013     = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window,
 31014                                    gray_bits, gray_width, gray_height,
 31015                                    1, 0, 1);
 31016 
 31017   dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo);
 31018 #if defined HAVE_XFIXES && XFIXES_VERSION >= 40000
 31019   dpyinfo->fixes_pointer_blanking = (egetenv ("EMACS_XFIXES") != NULL);
 31020 #endif
 31021 
 31022   xsettings_initialize (dpyinfo);
 31023 
 31024   /* This is only needed for distinguishing keyboard and process input.  */
 31025   if (dpyinfo->connection != 0)
 31026     add_keyboard_wait_descriptor (dpyinfo->connection);
 31027 
 31028 #ifdef F_SETOWN
 31029   fcntl (dpyinfo->connection, F_SETOWN, getpid ());
 31030 #endif /* ! defined (F_SETOWN) */
 31031 
 31032   if (interrupt_input)
 31033     init_sigio (dpyinfo->connection);
 31034 
 31035 #ifdef USE_LUCID
 31036   {
 31037     XrmValue d, fr, to;
 31038     Font font;
 31039     XFontStruct *query_result;
 31040 
 31041     dpy = dpyinfo->display;
 31042     d.addr = (XPointer) &dpy;
 31043     d.size = sizeof (Display *);
 31044     fr.addr = (char *) XtDefaultFont;
 31045     fr.size = sizeof (XtDefaultFont);
 31046     to.size = sizeof (Font *);
 31047     to.addr = (XPointer) &font;
 31048     x_catch_errors (dpy);
 31049     if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
 31050       emacs_abort ();
 31051     query_result = XQueryFont (dpy, font);
 31052 
 31053     /* Set the dialog font to some fallback (here, 9x15) if the font
 31054        specified is invalid.  */
 31055     if (x_had_errors_p (dpy) || !font)
 31056       XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
 31057 
 31058     /* Do not destroy the font struct returned above with XFreeFont;
 31059        that also destroys the font, leading to X protocol errors at
 31060        XtCloseDisplay.  Just free the font info structure.
 31061        (Bug#18403) */
 31062     XFreeFontInfo (NULL, query_result, 1);
 31063     x_uncatch_errors ();
 31064   }
 31065 #endif
 31066 
 31067   /* See if we should run in synchronous mode.  This is useful
 31068      for debugging X code.  */
 31069   {
 31070     AUTO_STRING (synchronous, "synchronous");
 31071     AUTO_STRING (Synchronous, "Synchronous");
 31072     Lisp_Object value = gui_display_get_resource (dpyinfo, synchronous,
 31073                                                   Synchronous, Qnil, Qnil);
 31074     if (STRINGP (value)
 31075         && (!strcmp (SSDATA (value), "true")
 31076             || !strcmp (SSDATA (value), "on")))
 31077       XSynchronize (dpyinfo->display, True);
 31078   }
 31079 
 31080 #ifdef HAVE_X_I18N
 31081   {
 31082     AUTO_STRING (useXIM, "useXIM");
 31083     AUTO_STRING (UseXIM, "UseXIM");
 31084     Lisp_Object value = gui_display_get_resource (dpyinfo, useXIM, UseXIM,
 31085                                                   Qnil, Qnil);
 31086 
 31087     /* `USE_XIM' controls whether Emacs should use X input methods by
 31088        default, not whether or not XIM is available.  */
 31089 
 31090 #ifdef USE_XIM
 31091     dpyinfo->use_xim = true;
 31092 
 31093     if (STRINGP (value)
 31094         && (!strcmp (SSDATA (value), "false")
 31095             || !strcmp (SSDATA (value), "off")))
 31096       dpyinfo->use_xim = false;
 31097 #else /* !USE_XIM */
 31098     dpyinfo->use_xim = false;
 31099 
 31100     if (STRINGP (value)
 31101         && (!strcmp (SSDATA (value), "true")
 31102             || !strcmp (SSDATA (value), "on")))
 31103       dpyinfo->use_xim = true;
 31104 #endif /* USE_XIM */
 31105   }
 31106 
 31107   {
 31108     AUTO_STRING (inputStyle, "inputStyle");
 31109     AUTO_STRING (InputStyle, "InputStyle");
 31110     Lisp_Object value = gui_display_get_resource (dpyinfo, inputStyle, InputStyle,
 31111                                                   Qnil, Qnil);
 31112 
 31113     if (STRINGP (value))
 31114       {
 31115         if (!strcmp (SSDATA (value), "callback"))
 31116           dpyinfo->preferred_xim_style = STYLE_CALLBACK;
 31117         else if (!strcmp (SSDATA (value), "none"))
 31118           dpyinfo->preferred_xim_style = STYLE_NONE;
 31119         else if (!strcmp (SSDATA (value), "overthespot"))
 31120           dpyinfo->preferred_xim_style = STYLE_OVERTHESPOT;
 31121         else if (!strcmp (SSDATA (value), "offthespot"))
 31122           dpyinfo->preferred_xim_style = STYLE_OFFTHESPOT;
 31123         else if (!strcmp (SSDATA (value), "root"))
 31124           dpyinfo->preferred_xim_style = STYLE_ROOT;
 31125 #ifdef USE_GTK
 31126         else if (!strcmp (SSDATA (value), "native"))
 31127           dpyinfo->prefer_native_input = true;
 31128 #endif /* HAVE_GTK */
 31129       }
 31130   }
 31131 
 31132   /* Now that defaults have been set up, initialize input method
 31133      support.  */
 31134 
 31135   /* Avoid initializing input methods if the X library does not
 31136      support Emacs's locale.  When the current locale is not
 31137      supported, decoding input method strings becomes undefined.  */
 31138   if (XSupportsLocale ())
 31139     xim_initialize (dpyinfo, resource_name);
 31140 #endif /* HAVE_X_I18N */
 31141 
 31142 #ifdef HAVE_X_SM
 31143   /* Only do this for the very first display in the Emacs session.
 31144      Ignore X session management when Emacs was first started on a
 31145      tty or started as a daemon.  */
 31146   if (!dpyinfo->next && ! IS_DAEMON)
 31147     x_session_initialize (dpyinfo);
 31148 #endif
 31149 
 31150 #if defined USE_CAIRO || defined HAVE_XRENDER
 31151   x_extension_initialize (dpyinfo);
 31152 #endif
 31153 
 31154 #ifdef USE_TOOLKIT_SCROLL_BARS
 31155   dpyinfo->protected_windows = xmalloc (sizeof (Lisp_Object) * 256);
 31156   dpyinfo->n_protected_windows = 0;
 31157   dpyinfo->protected_windows_max = 256;
 31158 #endif
 31159 
 31160 #ifdef HAVE_XFIXES
 31161   /* Initialize selection tracking for the selections in
 31162      x-fast-selection-list.  */
 31163 
 31164   if (CONSP (Vx_fast_selection_list)
 31165       && dpyinfo->xfixes_supported_p
 31166       && dpyinfo->xfixes_major >= 1)
 31167     {
 31168       num_fast_selections = 0;
 31169       tem = Vx_fast_selection_list;
 31170 
 31171       FOR_EACH_TAIL_SAFE (tem)
 31172         {
 31173           if (!SYMBOLP (XCAR (tem)))
 31174             continue;
 31175 
 31176           num_fast_selections++;
 31177         }
 31178 
 31179       dpyinfo->n_monitored_selections = num_fast_selections;
 31180       dpyinfo->selection_tracking_window
 31181         = x_create_special_window (dpyinfo, dpyinfo->root_window);
 31182       dpyinfo->monitored_selections
 31183         = xmalloc (num_fast_selections
 31184                    * sizeof *dpyinfo->monitored_selections);
 31185 
 31186       num_fast_selections = 0;
 31187       tem = Vx_fast_selection_list;
 31188 
 31189       FOR_EACH_TAIL_SAFE (tem)
 31190         {
 31191           lisp_name = XCAR (tem);
 31192 
 31193           if (!SYMBOLP (lisp_name))
 31194             continue;
 31195 
 31196           selection_name = symbol_to_x_atom (dpyinfo, lisp_name);
 31197           dpyinfo->monitored_selections[num_fast_selections++].name
 31198             = selection_name;
 31199           dpyinfo->monitored_selections[num_fast_selections - 1].owner
 31200             = X_INVALID_WINDOW;
 31201 
 31202           /* Select for selection input.  */
 31203           XFixesSelectSelectionInput (dpyinfo->display,
 31204                                       dpyinfo->selection_tracking_window,
 31205                                       selection_name,
 31206                                       (XFixesSetSelectionOwnerNotifyMask
 31207                                        | XFixesSetSelectionOwnerNotifyMask
 31208                                        | XFixesSelectionClientCloseNotifyMask));
 31209         }
 31210 
 31211 #ifdef USE_XCB
 31212       selection_cookies = SAFE_ALLOCA (sizeof *selection_cookies
 31213                                        * num_fast_selections);
 31214 #endif
 31215 
 31216       /* Now, ask for the current owners of all those selections.  */
 31217       for (i = 0; i < num_fast_selections; ++i)
 31218         {
 31219 #ifdef USE_XCB
 31220           selection_cookies[i]
 31221             = xcb_get_selection_owner (dpyinfo->xcb_connection,
 31222                                        dpyinfo->monitored_selections[i].name);
 31223 #else
 31224           dpyinfo->monitored_selections[i].owner
 31225             = XGetSelectionOwner (dpyinfo->display,
 31226                                   dpyinfo->monitored_selections[i].name);
 31227 #endif
 31228         }
 31229 
 31230 #ifdef USE_XCB
 31231       for (i = 0; i < num_fast_selections; ++i)
 31232         {
 31233           selection_reply
 31234             = xcb_get_selection_owner_reply (dpyinfo->xcb_connection,
 31235                                              selection_cookies[i],
 31236                                              &selection_error);
 31237 
 31238           if (selection_reply)
 31239             {
 31240               dpyinfo->monitored_selections[i].owner
 31241                 = selection_reply->owner;
 31242               free (selection_reply);
 31243             }
 31244           else if (selection_error)
 31245             free (selection_error);
 31246         }
 31247 #endif
 31248     }
 31249 #endif
 31250 
 31251   unblock_input ();
 31252 
 31253 #if defined HAVE_XFIXES && defined USE_XCB
 31254   SAFE_FREE ();
 31255 #endif
 31256   return dpyinfo;
 31257 }
 31258 
 31259 
 31260 
 31261 /* Remove all the selection input events on the keyboard buffer
 31262    intended for DPYINFO.  */
 31263 
 31264 static void
 31265 x_delete_selection_requests (struct x_display_info *dpyinfo)
 31266 {
 31267   union buffered_input_event *event;
 31268   int moved_events;
 31269 
 31270   for (event = kbd_fetch_ptr; event != kbd_store_ptr;
 31271        event = X_NEXT_KBD_EVENT (event))
 31272     {
 31273       if (event->kind == SELECTION_REQUEST_EVENT
 31274           || event->kind == SELECTION_CLEAR_EVENT)
 31275         {
 31276           if (SELECTION_EVENT_DPYINFO (&event->sie) != dpyinfo)
 31277             continue;
 31278 
 31279           /* Remove the event from the fifo buffer before processing;
 31280              otherwise swallow_events called recursively could see it
 31281              and process it again.  To do this, we move the events
 31282              between kbd_fetch_ptr and EVENT one slot to the right,
 31283              cyclically.  */
 31284 
 31285           if (event < kbd_fetch_ptr)
 31286             {
 31287               memmove (kbd_buffer + 1, kbd_buffer,
 31288                        (event - kbd_buffer) * sizeof *kbd_buffer);
 31289               kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1];
 31290               moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr;
 31291             }
 31292           else
 31293             moved_events = event - kbd_fetch_ptr;
 31294 
 31295           memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr,
 31296                    moved_events * sizeof *kbd_fetch_ptr);
 31297           kbd_fetch_ptr = X_NEXT_KBD_EVENT (kbd_fetch_ptr);
 31298 
 31299           /* `detect_input_pending' will then recompute whether or not
 31300              pending input events exist.  */
 31301           input_pending = false;
 31302         }
 31303     }
 31304 }
 31305 
 31306 /* Get rid of display DPYINFO, deleting all frames on it,
 31307    and without sending any more commands to the X server.  */
 31308 
 31309 static void
 31310 x_delete_display (struct x_display_info *dpyinfo)
 31311 {
 31312   struct terminal *t;
 31313   struct color_name_cache_entry *color_entry, *next_color_entry;
 31314   int i;
 31315   struct x_selection_request_event *ie, *last, *temp;
 31316 
 31317   /* Close all frames and delete the generic struct terminal for this
 31318      X display.  */
 31319   for (t = terminal_list; t; t = t->next_terminal)
 31320     if (t->type == output_x_window && t->display_info.x == dpyinfo)
 31321       {
 31322 #ifdef HAVE_X_SM
 31323         /* Close X session management when we close its display.  */
 31324         if (t->id == 1 && x_session_have_connection ())
 31325           x_session_close ();
 31326 #endif
 31327         delete_terminal (t);
 31328         break;
 31329       }
 31330 
 31331   /* Find any pending selection requests for this display and unchain
 31332      them.  */
 31333 
 31334   last = NULL;
 31335 
 31336   for (ie = pending_selection_requests; ie; ie = ie->next)
 31337     {
 31338     again:
 31339 
 31340       if (SELECTION_EVENT_DPYINFO (&ie->se) == dpyinfo)
 31341         {
 31342           if (last)
 31343             last->next = ie->next;
 31344 
 31345           temp = ie;
 31346           ie = ie->next;
 31347           xfree (temp);
 31348 
 31349           goto again;
 31350         }
 31351 
 31352       last = ie;
 31353     }
 31354 
 31355   /* Delete selection requests bound for dpyinfo from the keyboard
 31356      buffer.  */
 31357   x_delete_selection_requests (dpyinfo);
 31358 
 31359   /* And remove any outstanding selection transfers.  */
 31360   x_remove_selection_transfers (dpyinfo);
 31361 
 31362   if (next_noop_dpyinfo == dpyinfo)
 31363     next_noop_dpyinfo = dpyinfo->next;
 31364 
 31365   if (mouse_click_timeout_display == dpyinfo)
 31366     mouse_click_timeout_display = NULL;
 31367 
 31368   if (x_display_list == dpyinfo)
 31369     x_display_list = dpyinfo->next;
 31370   else
 31371     {
 31372       struct x_display_info *tail;
 31373 
 31374       for (tail = x_display_list; tail; tail = tail->next)
 31375         if (tail->next == dpyinfo)
 31376           tail->next = tail->next->next;
 31377     }
 31378 
 31379   for (i = 0; i < dpyinfo->color_names_size; ++i)
 31380     {
 31381       for (color_entry = dpyinfo->color_names[i];
 31382            color_entry; color_entry = next_color_entry)
 31383         {
 31384           next_color_entry = color_entry->next;
 31385 
 31386           xfree (color_entry->name);
 31387           xfree (color_entry);
 31388         }
 31389     }
 31390 
 31391   if (dpyinfo->net_supported_atoms)
 31392     XFree (dpyinfo->net_supported_atoms);
 31393 
 31394   xfree (dpyinfo->color_names);
 31395   xfree (dpyinfo->color_names_length);
 31396   xfree (dpyinfo->x_id_name);
 31397   xfree (dpyinfo->x_dnd_atoms);
 31398   xfree (dpyinfo->color_cells);
 31399 #ifdef HAVE_XFIXES
 31400   if (dpyinfo->monitored_selections)
 31401     xfree (dpyinfo->monitored_selections);
 31402 #endif
 31403 #ifdef USE_TOOLKIT_SCROLL_BARS
 31404   xfree (dpyinfo->protected_windows);
 31405 #endif
 31406 #ifdef HAVE_XINPUT2
 31407   if (dpyinfo->supports_xi2)
 31408     x_free_xi_devices (dpyinfo);
 31409 #endif
 31410   xfree (dpyinfo);
 31411 }
 31412 
 31413 #ifdef USE_X_TOOLKIT
 31414 
 31415 /* Atimer callback function for TIMER.  Called every 0.1s to process
 31416    Xt timeouts, if needed.  We must avoid calling XtAppPending as
 31417    much as possible because that function does an implicit XFlush
 31418    that slows us down.  */
 31419 
 31420 static void
 31421 x_process_timeouts (struct atimer *timer)
 31422 {
 31423   block_input ();
 31424   x_timeout_atimer_activated_flag = false;
 31425   if (toolkit_scroll_bar_interaction || popup_activated ())
 31426     {
 31427       while (XtAppPending (Xt_app_con) & XtIMTimer)
 31428         XtAppProcessEvent (Xt_app_con, XtIMTimer);
 31429       /* Reactivate the atimer for next time.  */
 31430       x_activate_timeout_atimer ();
 31431     }
 31432   unblock_input ();
 31433 }
 31434 
 31435 /* Install an asynchronous timer that processes Xt timeout events
 31436    every 0.1s as long as either `toolkit_scroll_bar_interaction' or
 31437    `popup_activated_flag' (in xmenu.c) is set.  Make sure to call this
 31438    function whenever these variables are set.  This is necessary
 31439    because some widget sets use timeouts internally, for example the
 31440    LessTif menu bar, or the Xaw3d scroll bar.  When Xt timeouts aren't
 31441    processed, these widgets don't behave normally.  */
 31442 
 31443 void
 31444 x_activate_timeout_atimer (void)
 31445 {
 31446   block_input ();
 31447   if (!x_timeout_atimer_activated_flag)
 31448     {
 31449       struct timespec interval = make_timespec (0, 100 * 1000 * 1000);
 31450       start_atimer (ATIMER_RELATIVE, interval, x_process_timeouts, 0);
 31451       x_timeout_atimer_activated_flag = true;
 31452     }
 31453   unblock_input ();
 31454 }
 31455 
 31456 #endif /* USE_X_TOOLKIT */
 31457 
 31458 
 31459 /* Set up use of X before we make the first connection.  */
 31460 
 31461 extern frame_parm_handler x_frame_parm_handlers[];
 31462 
 31463 static struct redisplay_interface x_redisplay_interface =
 31464   {
 31465     x_frame_parm_handlers,
 31466     gui_produce_glyphs,
 31467     gui_write_glyphs,
 31468     gui_insert_glyphs,
 31469     gui_clear_end_of_line,
 31470     x_scroll_run,
 31471     x_after_update_window_line,
 31472     NULL, /* update_window_begin */
 31473     NULL, /* update_window_end   */
 31474     x_flip_and_flush,
 31475     gui_clear_window_mouse_face,
 31476     gui_get_glyph_overhangs,
 31477     gui_fix_overlapping_area,
 31478     x_draw_fringe_bitmap,
 31479 #ifdef USE_CAIRO
 31480     x_cr_define_fringe_bitmap,
 31481     x_cr_destroy_fringe_bitmap,
 31482 #else
 31483     0, /* define_fringe_bitmap */
 31484     0, /* destroy_fringe_bitmap */
 31485 #endif
 31486     x_compute_glyph_string_overhangs,
 31487     x_draw_glyph_string,
 31488     x_define_frame_cursor,
 31489     x_clear_frame_area,
 31490     x_clear_under_internal_border,
 31491     x_draw_window_cursor,
 31492     x_draw_vertical_window_border,
 31493     x_draw_window_divider,
 31494     x_shift_glyphs_for_insert, /* Never called; see comment in function.  */
 31495     x_show_hourglass,
 31496     x_hide_hourglass,
 31497     x_default_font_parameter
 31498   };
 31499 
 31500 
 31501 /* This function is called when the last frame on a display is deleted. */
 31502 void
 31503 x_delete_terminal (struct terminal *terminal)
 31504 {
 31505   struct x_display_info *dpyinfo;
 31506   struct frame *f;
 31507   Lisp_Object tail, frame;
 31508 
 31509   dpyinfo = terminal->display_info.x;
 31510 
 31511   /* Protect against recursive calls.  delete_frame in
 31512      delete_terminal calls us back when it deletes our last frame.  */
 31513   if (!terminal->name)
 31514     return;
 31515 
 31516   block_input ();
 31517 
 31518   /* Delete all remaining frames on the display that is going away.
 31519      Otherwise, font backends assume the display is still up, and
 31520      xftfont_end_for_frame crashes.  */
 31521   FOR_EACH_FRAME (tail, frame)
 31522     {
 31523       f = XFRAME (frame);
 31524 
 31525       if (FRAME_LIVE_P (f) && f->terminal == terminal)
 31526         /* Pass Qnoelisp rather than Qt.  */
 31527         delete_frame (frame, Qnoelisp);
 31528     }
 31529 
 31530 #ifdef HAVE_X_I18N
 31531   /* We must close our connection to the XIM server before closing the
 31532      X display.  */
 31533   xim_close_dpy (dpyinfo);
 31534 #endif
 31535 
 31536   /* Destroy all bitmap images created on the display.  */
 31537   image_destroy_all_bitmaps (dpyinfo);
 31538 
 31539   /* Free the storage allocated to hold bitmap records.  */
 31540   xfree (dpyinfo->bitmaps);
 31541 
 31542   /* In case someone decides to use `bitmaps' again... */
 31543   dpyinfo->bitmaps = NULL;
 31544   dpyinfo->bitmaps_last = 0;
 31545 
 31546   /* Normally, the display is available...  */
 31547   if (dpyinfo->display)
 31548     {
 31549       XSetCloseDownMode (dpyinfo->display, DestroyAll);
 31550 
 31551       /* Delete the scratch cursor GC, should it exist.  */
 31552       if (dpyinfo->scratch_cursor_gc)
 31553         XFreeGC (dpyinfo->display, dpyinfo->scratch_cursor_gc);
 31554 
 31555       /* Get rid of any drag-and-drop operation that might be in
 31556          progress as well.  */
 31557       if ((x_dnd_in_progress || x_dnd_waiting_for_finish)
 31558           && dpyinfo->display == (x_dnd_waiting_for_finish
 31559                                   ? x_dnd_finish_display
 31560                                   : FRAME_X_DISPLAY (x_dnd_frame)))
 31561         {
 31562           x_dnd_last_seen_window = None;
 31563           x_dnd_last_seen_toplevel = None;
 31564           x_dnd_in_progress = false;
 31565           x_dnd_waiting_for_finish = false;
 31566 
 31567           /* The display is going away, so there's no point in
 31568              de-selecting for input on the DND toplevels.  */
 31569           if (x_dnd_use_toplevels)
 31570             x_dnd_free_toplevels (false);
 31571 
 31572           x_dnd_return_frame_object = NULL;
 31573           x_dnd_movement_frame = NULL;
 31574           x_dnd_wheel_frame = NULL;
 31575           x_dnd_frame = NULL;
 31576         }
 31577 
 31578       /* Whether or not XCloseDisplay destroys the associated resource
 31579          database depends on the version of libX11.  To avoid both
 31580          crash and memory leak, we dissociate the database from the
 31581          display and then destroy dpyinfo->rdb ourselves.
 31582 
 31583          Unfortunately, the above strategy does not work in some
 31584          situations due to a bug in newer versions of libX11: because
 31585          XrmSetDatabase doesn't clear the flag XlibDisplayDfltRMDB if
 31586          dpy->db is NULL, XCloseDisplay destroys the associated
 31587          database whereas it has not been created by XGetDefault
 31588          (Bug#21974 in freedesktop.org Bugzilla).  As a workaround, we
 31589          don't destroy the database here in order to avoid the crash
 31590          in the above situations for now, though that may cause memory
 31591          leaks in other situations.  */
 31592 #if false
 31593 #ifdef HAVE_XRMSETDATABASE
 31594       XrmSetDatabase (dpyinfo->display, NULL);
 31595 #else
 31596       dpyinfo->display->db = NULL;
 31597 #endif
 31598       /* We used to call XrmDestroyDatabase from x_delete_display, but
 31599          some older versions of libX11 crash if we call it after
 31600          closing all the displays.  */
 31601       XrmDestroyDatabase (dpyinfo->rdb);
 31602 #endif
 31603 #ifdef USE_GTK
 31604       xg_display_close (dpyinfo->display);
 31605 #else
 31606 #ifdef USE_X_TOOLKIT
 31607       XtCloseDisplay (dpyinfo->display);
 31608 #else
 31609       XCloseDisplay (dpyinfo->display);
 31610 #endif
 31611 #endif /* ! USE_GTK */
 31612       /* Do not close the connection here because it's already closed
 31613          by X(t)CloseDisplay (Bug#18403).  */
 31614       dpyinfo->display = NULL;
 31615     }
 31616 
 31617   /* ...but if called from x_connection_closed, the display may already
 31618      be closed and dpyinfo->display was set to 0 to indicate that.  Since
 31619      X server is most likely gone, explicit close is the only reliable
 31620      way to continue and avoid Bug#19147.  */
 31621   else if (dpyinfo->connection >= 0)
 31622     emacs_close (dpyinfo->connection);
 31623 
 31624   /* Free the keyboard and modifier maps here; that is safe to do
 31625      without a display, and not doing so leads to a lot of data being
 31626      leaked upon IO error.  */
 31627 
 31628 #ifdef HAVE_XKB
 31629   if (dpyinfo->xkb_desc)
 31630     XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True);
 31631 #endif
 31632 
 31633   if (dpyinfo->modmap)
 31634     XFreeModifiermap (dpyinfo->modmap);
 31635 
 31636   /* No more input on this descriptor.  */
 31637   delete_keyboard_wait_descriptor (dpyinfo->connection);
 31638   /* Mark as dead. */
 31639   dpyinfo->connection = -1;
 31640 
 31641   x_delete_display (dpyinfo);
 31642   unblock_input ();
 31643 }
 31644 
 31645 #ifdef HAVE_XINPUT2
 31646 static bool
 31647 x_have_any_grab (struct x_display_info *dpyinfo)
 31648 {
 31649   int i;
 31650 
 31651   if (!dpyinfo->supports_xi2)
 31652     return false;
 31653 
 31654   for (i = 0; i < dpyinfo->num_devices; ++i)
 31655     {
 31656       if (dpyinfo->devices[i].grab)
 31657         return true;
 31658     }
 31659 
 31660   return false;
 31661 }
 31662 #endif
 31663 
 31664 /* Create a struct terminal, initialize it with the X11 specific
 31665    functions and make DISPLAY->TERMINAL point to it.  */
 31666 
 31667 static struct terminal *
 31668 x_create_terminal (struct x_display_info *dpyinfo)
 31669 {
 31670   struct terminal *terminal;
 31671 
 31672   terminal = create_terminal (output_x_window, &x_redisplay_interface);
 31673 
 31674   terminal->display_info.x = dpyinfo;
 31675   dpyinfo->terminal = terminal;
 31676 
 31677   /* kboard is initialized in x_term_init. */
 31678 
 31679   terminal->clear_frame_hook = x_clear_frame;
 31680   terminal->ins_del_lines_hook = x_ins_del_lines;
 31681   terminal->delete_glyphs_hook = x_delete_glyphs;
 31682   terminal->ring_bell_hook = XTring_bell;
 31683   terminal->toggle_invisible_pointer_hook = XTtoggle_invisible_pointer;
 31684   terminal->update_begin_hook = x_update_begin;
 31685   terminal->update_end_hook = x_update_end;
 31686   terminal->read_socket_hook = XTread_socket;
 31687   terminal->frame_up_to_date_hook = XTframe_up_to_date;
 31688 #ifdef HAVE_XDBE
 31689   terminal->buffer_flipping_unblocked_hook = XTbuffer_flipping_unblocked_hook;
 31690 #endif
 31691   terminal->defined_color_hook = x_defined_color;
 31692   terminal->query_frame_background_color = x_query_frame_background_color;
 31693   terminal->query_colors = x_query_colors;
 31694   terminal->mouse_position_hook = XTmouse_position;
 31695   terminal->get_focus_frame = x_get_focus_frame;
 31696   terminal->focus_frame_hook = x_focus_frame;
 31697   terminal->frame_rehighlight_hook = XTframe_rehighlight;
 31698   terminal->frame_raise_lower_hook = XTframe_raise_lower;
 31699   terminal->frame_visible_invisible_hook = x_make_frame_visible_invisible;
 31700   terminal->fullscreen_hook = XTfullscreen_hook;
 31701   terminal->iconify_frame_hook = x_iconify_frame;
 31702   terminal->set_window_size_hook = x_set_window_size;
 31703   terminal->set_frame_offset_hook = x_set_offset;
 31704   terminal->set_frame_alpha_hook = x_set_frame_alpha;
 31705   terminal->set_new_font_hook = x_new_font;
 31706   terminal->set_bitmap_icon_hook = x_bitmap_icon;
 31707   terminal->implicit_set_name_hook = x_implicitly_set_name;
 31708   terminal->menu_show_hook = x_menu_show;
 31709 #ifdef HAVE_EXT_MENU_BAR
 31710   terminal->activate_menubar_hook = x_activate_menubar;
 31711 #endif
 31712 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
 31713   terminal->popup_dialog_hook = xw_popup_dialog;
 31714 #endif
 31715   terminal->change_tab_bar_height_hook = x_change_tab_bar_height;
 31716 #ifndef HAVE_EXT_TOOL_BAR
 31717   terminal->change_tool_bar_height_hook = x_change_tool_bar_height;
 31718 #endif
 31719   terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
 31720   terminal->set_horizontal_scroll_bar_hook = XTset_horizontal_scroll_bar;
 31721   terminal->set_scroll_bar_default_width_hook = x_set_scroll_bar_default_width;
 31722   terminal->set_scroll_bar_default_height_hook = x_set_scroll_bar_default_height;
 31723   terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
 31724   terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
 31725   terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
 31726   terminal->get_string_resource_hook = x_get_string_resource;
 31727   terminal->free_pixmap = x_free_pixmap;
 31728   terminal->delete_frame_hook = x_destroy_window;
 31729   terminal->delete_terminal_hook = x_delete_terminal;
 31730   terminal->toolkit_position_hook = x_toolkit_position;
 31731 #ifdef HAVE_XINPUT2
 31732   terminal->any_grab_hook = x_have_any_grab;
 31733 #endif
 31734   /* Other hooks are NULL by default.  */
 31735 
 31736   return terminal;
 31737 }
 31738 
 31739 static void
 31740 x_initialize (void)
 31741 {
 31742   baud_rate = 19200;
 31743 
 31744   x_noop_count = 0;
 31745   any_help_event_p = false;
 31746   ignore_next_mouse_click_timeout = 0;
 31747   mouse_click_timeout_display = NULL;
 31748 
 31749 #ifdef USE_GTK
 31750   current_count = -1;
 31751 #endif
 31752 
 31753   /* Try to use interrupt input; if we can't, then start polling.  */
 31754   Fset_input_interrupt_mode (Qt);
 31755 
 31756 #if THREADS_ENABLED
 31757   /* This must be called before any other Xlib routines.  */
 31758   if (XInitThreads () == 0)
 31759     fputs ("Warning: An error occurred initializing X11 thread support!\n",
 31760            stderr);
 31761 #endif
 31762 
 31763 #ifdef USE_X_TOOLKIT
 31764   XtToolkitInitialize ();
 31765 
 31766   Xt_app_con = XtCreateApplicationContext ();
 31767 
 31768   /* Register a converter from strings to pixels, which uses
 31769      Emacs' color allocation infrastructure.  */
 31770   XtAppSetTypeConverter (Xt_app_con,
 31771                          XtRString, XtRPixel, cvt_string_to_pixel,
 31772                          cvt_string_to_pixel_args,
 31773                          XtNumber (cvt_string_to_pixel_args),
 31774                          XtCacheByDisplay, cvt_pixel_dtor);
 31775 
 31776   XtAppSetFallbackResources (Xt_app_con, Xt_default_resources);
 31777 #endif
 31778 
 31779 #ifdef USE_TOOLKIT_SCROLL_BARS
 31780 #ifndef USE_GTK
 31781   xaw3d_arrow_scroll = False;
 31782   xaw3d_pick_top = True;
 31783 #endif
 31784 #endif
 31785 
 31786 #ifdef USE_CAIRO
 31787   gui_init_fringe (&x_redisplay_interface);
 31788 #endif
 31789 
 31790   /* Note that there is no real way portable across R3/R4 to get the
 31791      original error handler.  */
 31792   XSetErrorHandler (x_error_handler);
 31793   XSetIOErrorHandler (x_io_error_quitter);
 31794 }
 31795 
 31796 #ifdef HAVE_X_I18N
 31797 
 31798 /* Notice that a change has occured on F that requires its input
 31799    method state to be reset.  */
 31800 
 31801 static void
 31802 x_reset_conversion (struct frame *f)
 31803 {
 31804   char *string;
 31805 
 31806   if (FRAME_XIC (f))
 31807     {
 31808       string = XmbResetIC (FRAME_XIC (f));
 31809 
 31810       /* string is actually any string that was being composed at the
 31811          time of the reset.  */
 31812 
 31813       if (string)
 31814         XFree (string);
 31815     }
 31816 }
 31817 
 31818 /* Interface used to control input method ``text conversion''.  */
 31819 
 31820 static struct textconv_interface text_conversion_interface =
 31821   {
 31822     x_reset_conversion,
 31823   };
 31824 
 31825 #endif
 31826 
 31827 void
 31828 init_xterm (void)
 31829 {
 31830 #ifndef HAVE_XINPUT2
 31831   /* Emacs can handle only core input events when built without XI2
 31832      support, so make sure Gtk doesn't use Xinput or Xinput2
 31833      extensions.  */
 31834 #ifndef HAVE_GTK3
 31835   xputenv ("GDK_CORE_DEVICE_EVENTS=1");
 31836 #else
 31837   gdk_disable_multidevice ();
 31838 #endif
 31839 #endif
 31840 
 31841 #ifdef HAVE_X_I18N
 31842   register_textconv_interface (&text_conversion_interface);
 31843 #endif
 31844 }
 31845 
 31846 void
 31847 mark_xterm (void)
 31848 {
 31849   Lisp_Object val;
 31850 #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS \
 31851   || defined HAVE_XRANDR || defined USE_GTK || defined HAVE_X_I18N
 31852   struct x_display_info *dpyinfo;
 31853 #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS
 31854   int i;
 31855 #endif
 31856 #endif
 31857 
 31858   if (x_dnd_return_frame_object)
 31859     {
 31860       XSETFRAME (val, x_dnd_return_frame_object);
 31861       mark_object (val);
 31862     }
 31863 
 31864   if (x_dnd_movement_frame)
 31865     {
 31866       XSETFRAME (val, x_dnd_movement_frame);
 31867       mark_object (val);
 31868     }
 31869 
 31870   if (x_dnd_wheel_frame)
 31871     {
 31872       XSETFRAME (val, x_dnd_wheel_frame);
 31873       mark_object (val);
 31874     }
 31875 
 31876 #if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS \
 31877   || defined HAVE_XRANDR || defined USE_GTK || defined HAVE_X_I18N
 31878   for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
 31879     {
 31880 #ifdef HAVE_XINPUT2
 31881       for (i = 0; i < dpyinfo->num_devices; ++i)
 31882         mark_object (dpyinfo->devices[i].name);
 31883 #endif
 31884 #ifdef USE_TOOLKIT_SCROLL_BARS
 31885       for (i = 0; i < dpyinfo->n_protected_windows; ++i)
 31886         mark_object (dpyinfo->protected_windows[i]);
 31887 #endif
 31888 #if defined HAVE_XRANDR || defined USE_GTK
 31889       mark_object (dpyinfo->last_monitor_attributes_list);
 31890 #endif
 31891 #if defined HAVE_X_I18N
 31892       mark_object (dpyinfo->xim_coding);
 31893 #endif
 31894     }
 31895 #endif
 31896 }
 31897 
 31898 /* Error handling functions for Lisp functions that expose X protocol
 31899    requests.  They are mostly like `x_catch_errors' and friends, but
 31900    respect `x-fast-protocol-requests'.  */
 31901 
 31902 void
 31903 x_catch_errors_for_lisp (struct x_display_info *dpyinfo)
 31904 {
 31905   if (!x_fast_protocol_requests)
 31906     x_catch_errors (dpyinfo->display);
 31907   else
 31908     x_ignore_errors_for_next_request (dpyinfo, 0);
 31909 }
 31910 
 31911 void
 31912 x_check_errors_for_lisp (struct x_display_info *dpyinfo,
 31913                          const char *format)
 31914 {
 31915   if (!x_fast_protocol_requests)
 31916     x_check_errors (dpyinfo->display, format);
 31917 }
 31918 
 31919 void
 31920 x_uncatch_errors_for_lisp (struct x_display_info *dpyinfo)
 31921 {
 31922   if (!x_fast_protocol_requests)
 31923     x_uncatch_errors ();
 31924   else
 31925     x_stop_ignoring_errors (dpyinfo);
 31926 }
 31927 
 31928 /* Preserve the selections in LOST in another frame on DPYINFO.  LOST
 31929    is a list of local selections that were lost, due to their frame
 31930    being deleted.  */
 31931 
 31932 void
 31933 x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost,
 31934                        Lisp_Object current_owner)
 31935 {
 31936   Lisp_Object tail, frame, new_owner;
 31937   Time timestamp;
 31938   Window *owners;
 31939   Atom *names;
 31940   ptrdiff_t nowners, counter;
 31941   struct selection_input_event clear;
 31942 #ifdef USE_XCB
 31943   xcb_get_selection_owner_cookie_t *cookies;
 31944   xcb_generic_error_t *error;
 31945   xcb_get_selection_owner_reply_t *reply;
 31946 #endif
 31947 
 31948   new_owner = Qnil;
 31949 
 31950   FOR_EACH_FRAME (tail, frame)
 31951     {
 31952       if (FRAME_X_P (XFRAME (frame))
 31953           && !EQ (frame, current_owner)
 31954           && FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
 31955         {
 31956           new_owner = frame;
 31957           break;
 31958         }
 31959     }
 31960 
 31961   tail = lost;
 31962   nowners = 0;
 31963 
 31964   FOR_EACH_TAIL_SAFE (tail)
 31965     {
 31966       Lisp_Object tem = XCAR (tail);
 31967       ++nowners;
 31968 
 31969       /* The selection is really lost (since we cannot find a new
 31970          owner), so run the appropriate hooks.  */
 31971       if (NILP (new_owner))
 31972         CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
 31973                XCAR (tem));
 31974       else
 31975         {
 31976           CONS_TO_INTEGER (XCAR (XCDR (XCDR (tem))), Time, timestamp);
 31977 
 31978           /* This shouldn't be able to signal any errors, despite the
 31979              call to `x_check_errors' inside.  */
 31980           x_own_selection (XCAR (tem), XCAR (XCDR (tem)),
 31981                            new_owner, XCAR (XCDR (XCDR (XCDR (XCDR (tem))))),
 31982                            timestamp);
 31983         }
 31984     }
 31985 
 31986   if (!NILP (new_owner))
 31987     {
 31988       owners = alloca (sizeof *owners * nowners);
 31989       names = alloca (sizeof *names * nowners);
 31990 #ifdef USE_XCB
 31991       cookies = alloca (sizeof *cookies * nowners);
 31992 #endif
 31993 
 31994       tail = lost;
 31995       nowners = 0;
 31996       counter = 0;
 31997 
 31998       FOR_EACH_TAIL_SAFE (tail)
 31999         {
 32000           Lisp_Object tem = XCAR (tail);
 32001 
 32002           /* Now check if we still don't own that selection, which can
 32003              happen if another program set itself as the owner.  */
 32004           names[counter++] = symbol_to_x_atom (dpyinfo, XCAR (tem));
 32005 
 32006 #ifndef USE_XCB
 32007           owners[nowners++] = XGetSelectionOwner (dpyinfo->display,
 32008                                                   names[counter - 1]);
 32009 #else
 32010           cookies[nowners++]
 32011             = xcb_get_selection_owner (dpyinfo->xcb_connection,
 32012                                        names[counter - 1]);
 32013         }
 32014 
 32015       nowners = 0;
 32016       tail = lost;
 32017 
 32018       FOR_EACH_TAIL_SAFE (tail)
 32019         {
 32020           Lisp_Object tem = XCAR (tail);
 32021 
 32022           reply = xcb_get_selection_owner_reply (dpyinfo->xcb_connection,
 32023                                                  cookies[nowners++], &error);
 32024           if (reply)
 32025             owners[nowners - 1] = reply->owner;
 32026           else
 32027             owners[nowners - 1] = None;
 32028 
 32029           free (reply ? (void *) reply : (void *) error);
 32030 #endif
 32031 
 32032           if (owners[nowners - 1] != FRAME_X_WINDOW (XFRAME (new_owner)))
 32033             {
 32034               /* Clear the local selection, since we know we don't own
 32035                  it any longer.  */
 32036               CONS_TO_INTEGER (XCAR (XCDR (XCDR (tem))), Time, timestamp);
 32037 
 32038               clear.kind = SELECTION_CLEAR_EVENT;
 32039 
 32040               SELECTION_EVENT_DPYINFO (&clear) = dpyinfo;
 32041               SELECTION_EVENT_SELECTION (&clear) = names[nowners - 1];
 32042               SELECTION_EVENT_TIME (&clear) = timestamp;
 32043 
 32044               x_handle_selection_event (&clear);
 32045             }
 32046         }
 32047 
 32048       tail = lost;
 32049       nowners = 0;
 32050 
 32051       FOR_EACH_TAIL_SAFE (tail)
 32052         {
 32053           Lisp_Object tem = XCAR (tail);
 32054 
 32055           /* If the selection isn't owned by us anymore, note that the
 32056              selection was lost.  */
 32057           if (owners[nowners++] != FRAME_X_WINDOW (XFRAME (new_owner)))
 32058             CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
 32059                    XCAR (tem));
 32060         }
 32061     }
 32062 }
 32063 
 32064 /* Return a list of the keyboard modifier masks in DPYINFO.
 32065 
 32066    Value is a list of (HYPER SUPER ALT SHIFT-LOCK META), each element
 32067    being the appropriate modifier mask.  */
 32068 
 32069 Lisp_Object
 32070 x_get_keyboard_modifiers (struct x_display_info *dpyinfo)
 32071 {
 32072   /* This sometimes happens when the function is called during display
 32073      initialization, which can happen while obtaining vendor specific
 32074      keysyms.  */
 32075 
 32076 #ifdef HAVE_XKB
 32077   if (!dpyinfo->xkb_desc && !dpyinfo->modmap)
 32078     x_find_modifier_meanings (dpyinfo);
 32079 #else
 32080   if (!dpyinfo->modmap)
 32081     x_find_modifier_meanings (dpyinfo);
 32082 #endif
 32083 
 32084   return list5 (make_uint (dpyinfo->hyper_mod_mask),
 32085                 make_uint (dpyinfo->super_mod_mask),
 32086                 make_uint (dpyinfo->alt_mod_mask),
 32087                 make_uint (dpyinfo->shift_lock_mask),
 32088                 make_uint (dpyinfo->meta_mod_mask));
 32089 }
 32090 
 32091 void
 32092 syms_of_xterm (void)
 32093 {
 32094   x_error_message = NULL;
 32095   PDUMPER_IGNORE (x_error_message);
 32096 
 32097   x_dnd_monitors = Qnil;
 32098   staticpro (&x_dnd_monitors);
 32099 
 32100   x_dnd_action_symbol = Qnil;
 32101   staticpro (&x_dnd_action_symbol);
 32102 
 32103   x_dnd_selection_alias_cell = Fcons (Qnil, Qnil);
 32104   staticpro (&x_dnd_selection_alias_cell);
 32105 
 32106   x_dnd_unsupported_drop_data = Qnil;
 32107   staticpro (&x_dnd_unsupported_drop_data);
 32108 
 32109   /* Used by x_cr_export_frames.  */
 32110   DEFSYM (Qconcat, "concat");
 32111 
 32112   DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
 32113   DEFSYM (Qlatin_1, "latin-1");
 32114   DEFSYM (Qnow, "now");
 32115   DEFSYM (Qx_dnd_targets_list, "x-dnd-targets-list");
 32116   DEFSYM (Qx_auto_preserve_selections, "x-auto-preserve-selections");
 32117   DEFSYM (Qexpose, "expose");
 32118   DEFSYM (Qdont_save, "dont-save");
 32119 
 32120 #ifdef USE_GTK
 32121   xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg");
 32122   staticpro (&xg_default_icon_file);
 32123 
 32124   DEFSYM (Qx_gtk_map_stock, "x-gtk-map-stock");
 32125 #endif
 32126 
 32127   DEFVAR_BOOL ("x-use-underline-position-properties",
 32128                x_use_underline_position_properties,
 32129      doc: /* Non-nil means make use of UNDERLINE_POSITION font properties.
 32130 A value of nil means ignore them.  If you encounter fonts with bogus
 32131 UNDERLINE_POSITION font properties, set this to nil.  You can also use
 32132 `underline-minimum-offset' to override the font's UNDERLINE_POSITION for
 32133 small font display sizes.  */);
 32134   x_use_underline_position_properties = true;
 32135   DEFSYM (Qx_use_underline_position_properties,
 32136           "x-use-underline-position-properties");
 32137 
 32138   DEFVAR_BOOL ("x-underline-at-descent-line",
 32139                x_underline_at_descent_line,
 32140      doc: /* Non-nil means to draw the underline at the same place as the descent line.
 32141 (If `line-spacing' is in effect, that moves the underline lower by
 32142 that many pixels.)
 32143 A value of nil means to draw the underline according to the value of the
 32144 variable `x-use-underline-position-properties', which is usually at the
 32145 baseline level.  The default value is nil.  */);
 32146   x_underline_at_descent_line = false;
 32147   DEFSYM (Qx_underline_at_descent_line, "x-underline-at-descent-line");
 32148 
 32149   DEFVAR_BOOL ("x-mouse-click-focus-ignore-position",
 32150                x_mouse_click_focus_ignore_position,
 32151     doc: /* Non-nil means that a mouse click to focus a frame does not move point.
 32152 This variable is used only when the window manager requires that you
 32153 click on a frame to select it (give it focus).  In that case, a value
 32154 of nil, means that the selected window and cursor position changes to
 32155 reflect the mouse click position, while a non-nil value means that the
 32156 selected window or cursor position is preserved.
 32157 
 32158 This option works by ignoring button press events for a given amount
 32159 of time after a frame might've been focused.  If it does not work for
 32160 you, try increasing the value of
 32161 `x-mouse-click-focus-ignore-time'.  */);
 32162   x_mouse_click_focus_ignore_position = false;
 32163 
 32164   DEFVAR_INT ("x-mouse-click-focus-ignore-time", x_mouse_click_focus_ignore_time,
 32165     doc: /* Number of milliseconds for which to ignore buttons after focus change.
 32166 This variable only takes effect if
 32167 `x-mouse-click-focus-ignore-position' is non-nil, and should be
 32168 adjusted if the default value does not work for whatever reason.  */);
 32169   x_mouse_click_focus_ignore_time = 200;
 32170 
 32171   DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
 32172     doc: /* Which toolkit scroll bars Emacs uses, if any.
 32173 A value of nil means Emacs doesn't use toolkit scroll bars.
 32174 With the X Window system, the value is a symbol describing the
 32175 X toolkit.  Possible values are: gtk, motif, xaw, or xaw3d.
 32176 With MS Windows, Haiku windowing or Nextstep, the value is t.
 32177 With Android, the value is nil, but that is because Emacs on
 32178 Android does not support scroll bars at all.  */);
 32179 #ifdef USE_TOOLKIT_SCROLL_BARS
 32180 #ifdef USE_MOTIF
 32181   Vx_toolkit_scroll_bars = intern_c_string ("motif");
 32182 #elif defined HAVE_XAW3D
 32183   Vx_toolkit_scroll_bars = intern_c_string ("xaw3d");
 32184 #elif USE_GTK
 32185   Vx_toolkit_scroll_bars = intern_c_string ("gtk");
 32186 #else
 32187   Vx_toolkit_scroll_bars = intern_c_string ("xaw");
 32188 #endif
 32189 #else
 32190   Vx_toolkit_scroll_bars = Qnil;
 32191 #endif
 32192 
 32193   DEFSYM (Qmodifier_value, "modifier-value");
 32194   DEFSYM (Qctrl, "ctrl");
 32195   Fput (Qctrl, Qmodifier_value, make_fixnum (ctrl_modifier));
 32196   DEFSYM (Qalt, "alt");
 32197   Fput (Qalt, Qmodifier_value, make_fixnum (alt_modifier));
 32198   DEFSYM (Qhyper, "hyper");
 32199   Fput (Qhyper, Qmodifier_value, make_fixnum (hyper_modifier));
 32200   DEFSYM (Qmeta, "meta");
 32201   Fput (Qmeta, Qmodifier_value, make_fixnum (meta_modifier));
 32202   DEFSYM (Qsuper, "super");
 32203   Fput (Qsuper, Qmodifier_value, make_fixnum (super_modifier));
 32204   DEFSYM (QXdndSelection, "XdndSelection");
 32205   DEFSYM (Qx_selection_alias_alist, "x-selection-alias-alist");
 32206   DEFSYM (Qimitate_pager, "imitate-pager");
 32207   DEFSYM (Qnewer_time, "newer-time");
 32208   DEFSYM (Qraise_and_focus, "raise-and-focus");
 32209   DEFSYM (Qreally_fast, "really-fast");
 32210 
 32211   DEFVAR_LISP ("x-ctrl-keysym", Vx_ctrl_keysym,
 32212     doc: /* Which keys Emacs uses for the ctrl modifier.
 32213 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 32214 `super'.  For example, `ctrl' means use the Ctrl_L and Ctrl_R keysyms.
 32215 The default is nil, which is the same as `ctrl'.  */);
 32216   Vx_ctrl_keysym = Qnil;
 32217 
 32218   DEFVAR_LISP ("x-alt-keysym", Vx_alt_keysym,
 32219     doc: /* Which keys Emacs uses for the alt modifier.
 32220 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 32221 `super'.  For example, `alt' means use the Alt_L and Alt_R keysyms.
 32222 The default is nil, which is the same as `alt'.  */);
 32223   Vx_alt_keysym = Qnil;
 32224 
 32225   DEFVAR_LISP ("x-hyper-keysym", Vx_hyper_keysym,
 32226     doc: /* Which keys Emacs uses for the hyper modifier.
 32227 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 32228 `super'.  For example, `hyper' means use the Hyper_L and Hyper_R
 32229 keysyms.  The default is nil, which is the same as `hyper'.  */);
 32230   Vx_hyper_keysym = Qnil;
 32231 
 32232   DEFVAR_LISP ("x-meta-keysym", Vx_meta_keysym,
 32233     doc: /* Which keys Emacs uses for the meta modifier.
 32234 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 32235 `super'.  For example, `meta' means use the Meta_L and Meta_R keysyms.
 32236 The default is nil, which is the same as `meta'.  */);
 32237   Vx_meta_keysym = Qnil;
 32238 
 32239   DEFVAR_LISP ("x-super-keysym", Vx_super_keysym,
 32240     doc: /* Which keys Emacs uses for the super modifier.
 32241 This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 32242 `super'.  For example, `super' means use the Super_L and Super_R
 32243 keysyms.  The default is nil, which is the same as `super'.  */);
 32244   Vx_super_keysym = Qnil;
 32245 
 32246   DEFVAR_LISP ("x-wait-for-event-timeout", Vx_wait_for_event_timeout,
 32247     doc: /* How long to wait for X events.
 32248 
 32249 Emacs will wait up to this many seconds to receive X events after
 32250 making changes which affect the state of the graphical interface.
 32251 Under some window managers this can take an indefinite amount of time,
 32252 so it is important to limit the wait.
 32253 
 32254 If set to a non-float value, there will be no wait at all.  */);
 32255   Vx_wait_for_event_timeout = make_float (0.1);
 32256 
 32257   DEFVAR_LISP ("x-keysym-table", Vx_keysym_table,
 32258     doc: /* Hash table of character codes indexed by X keysym codes.  */);
 32259   Vx_keysym_table = make_hash_table (hashtest_eql, 900,
 32260                                      DEFAULT_REHASH_SIZE,
 32261                                      DEFAULT_REHASH_THRESHOLD,
 32262                                      Qnil, false);
 32263 
 32264   DEFVAR_BOOL ("x-frame-normalize-before-maximize",
 32265                x_frame_normalize_before_maximize,
 32266     doc: /* Non-nil means normalize frame before maximizing.
 32267 If this variable is t, Emacs first asks the window manager to give the
 32268 frame its normal size, and only then the final state, whenever changing
 32269 from a full-height, full-width or full-both state to the maximized one
 32270 or when changing from the maximized to the full-height or full-width
 32271 state.
 32272 
 32273 Set this variable only if your window manager cannot handle the
 32274 transition between the various maximization states.  */);
 32275   x_frame_normalize_before_maximize = false;
 32276 
 32277   DEFVAR_BOOL ("x-gtk-use-window-move", x_gtk_use_window_move,
 32278     doc: /* Non-nil means rely on gtk_window_move to set frame positions.
 32279 If this variable is t (the default), the GTK build uses the function
 32280 gtk_window_move to set or store frame positions and disables some time
 32281 consuming frame position adjustments.  In newer versions of GTK, Emacs
 32282 always uses gtk_window_move and ignores the value of this variable.  */);
 32283   x_gtk_use_window_move = true;
 32284 
 32285   DEFVAR_LISP ("x-scroll-event-delta-factor", Vx_scroll_event_delta_factor,
 32286                doc: /* A scale to apply to pixel deltas reported in scroll events.
 32287 This option is only effective when Emacs is built with XInput 2
 32288 support. */);
 32289   Vx_scroll_event_delta_factor = make_float (1.0);
 32290 
 32291   DEFVAR_BOOL ("x-gtk-use-native-input", x_gtk_use_native_input,
 32292                doc: /* Non-nil means to use GTK for input method support.
 32293 This provides better support for some modern input methods, and is
 32294 only effective when Emacs is built with GTK.  */);
 32295   x_gtk_use_native_input = false;
 32296 
 32297   DEFVAR_LISP ("x-set-frame-visibility-more-laxly",
 32298                x_set_frame_visibility_more_laxly,
 32299     doc: /* Non-nil means set frame visibility more laxly.
 32300 If this is nil, Emacs is more strict when marking a frame as visible.
 32301 Since this may cause problems on some window managers, this variable can
 32302 be also set as follows: The value `focus-in' means to mark a frame as
 32303 visible also when a FocusIn event is received for it on GTK builds.  The
 32304 value `expose' means to mark a frame as visible also when an Expose
 32305 event is received for it on any X build.  The value `t' means to mark a
 32306 frame as visible in either of these two cases.
 32307 
 32308 Note that any non-nil setting may cause invisible frames get erroneously
 32309 reported as iconified.  */);
 32310   x_set_frame_visibility_more_laxly = Qnil;
 32311 
 32312   DEFVAR_BOOL ("x-input-grab-touch-events", x_input_grab_touch_events,
 32313                doc: /* Non-nil means to actively grab touch events.
 32314 This means touch sequences that are obtained through a passive grab on
 32315 an Emacs frame (or a parent window of such a frame) will reliably
 32316 continue to receive updates, but may cause crashes with some window
 32317 managers and/or external programs.  Changing this option is only
 32318 useful when other programs are making their own X requests pertaining
 32319 to the window hierarchy of an Emacs frame.  */);
 32320   x_input_grab_touch_events = true;
 32321 
 32322   DEFVAR_BOOL ("x-dnd-fix-motif-leave", x_dnd_fix_motif_leave,
 32323                doc: /* Work around Motif bug during drag-and-drop.
 32324 When non-nil, Emacs will send a motion event containing impossible
 32325 coordinates to a Motif drop receiver when the mouse moves outside it
 32326 during a drag-and-drop session, to work around broken implementations
 32327 of Motif.  */);
 32328   x_dnd_fix_motif_leave = true;
 32329 
 32330   DEFVAR_BOOL ("x-dnd-disable-motif-drag", x_dnd_disable_motif_drag,
 32331                doc: /* Disable the Motif drag protocol during DND.
 32332 This reduces network usage, but also means you can no longer scroll
 32333 around inside the Motif window underneath the cursor during
 32334 drag-and-drop.  */);
 32335   x_dnd_disable_motif_drag = false;
 32336 
 32337   DEFVAR_LISP ("x-dnd-movement-function", Vx_dnd_movement_function,
 32338     doc: /* Function called upon mouse movement on a frame during drag-and-drop.
 32339 It should either be nil, or accept two arguments FRAME and POSITION,
 32340 where FRAME is the frame the mouse is on top of, and POSITION is a
 32341 mouse position list.  */);
 32342   Vx_dnd_movement_function = Qnil;
 32343 
 32344   DEFVAR_LISP ("x-dnd-wheel-function", Vx_dnd_wheel_function,
 32345     doc: /* Function called upon wheel movement on a frame during drag-and-drop.
 32346 It should either be nil, or accept four arguments POSITION, BUTTON,
 32347 STATE and TIME, where POSITION is a mouse position list describing
 32348 where the wheel moved, BUTTON is the wheel button that was pressed,
 32349 STATE is the X modifier state at the time of the wheel movement, and
 32350 TIME is the X server time at which the wheel moved.  */);
 32351   Vx_dnd_wheel_function = Qnil;
 32352 
 32353   DEFVAR_LISP ("x-dnd-unsupported-drop-function", Vx_dnd_unsupported_drop_function,
 32354     doc: /* Function called when trying to drop on an unsupported window.
 32355 This function is called whenever the user tries to drop something on a
 32356 window that does not support either the XDND or Motif protocols for
 32357 drag-and-drop.  It should return a non-nil value if the drop was
 32358 handled by the function, and nil if it was not.  It should accept
 32359 several arguments TARGETS, X, Y, ACTION, WINDOW-ID, FRAME, TIME and
 32360 LOCAL-SELECTION, where TARGETS is the list of targets that was passed
 32361 to `x-begin-drag', WINDOW-ID is the numeric XID of the window that is
 32362 being dropped on, X and Y are the root window-relative coordinates
 32363 where the drop happened, ACTION is the action that was passed to
 32364 `x-begin-drag', FRAME is the frame which initiated the drag-and-drop
 32365 operation, TIME is the X server time when the drop happened, and
 32366 LOCAL-SELECTION is the contents of the `XdndSelection' when
 32367 `x-begin-drag' was run; its contents can be retrieved by calling the
 32368 function `x-get-local-selection'.
 32369 
 32370 If a symbol is returned, then it will be used as the return value of
 32371 `x-begin-drag'.  */);
 32372   Vx_dnd_unsupported_drop_function = Qnil;
 32373 
 32374   DEFVAR_INT ("x-color-cache-bucket-size", x_color_cache_bucket_size,
 32375     doc: /* Max number of buckets allowed per display in the internal color cache.
 32376 Values less than 1 mean 128.  This option is for debugging only.  */);
 32377   x_color_cache_bucket_size = 128;
 32378 
 32379   DEFVAR_LISP ("x-dnd-targets-list", Vx_dnd_targets_list,
 32380     doc: /* List of drag-and-drop targets.
 32381 This variable contains the list of drag-and-drop selection targets
 32382 during a drag-and-drop operation, in the same format as the TARGET
 32383 argument to `x-begin-drag'.  */);
 32384   Vx_dnd_targets_list = Qnil;
 32385 
 32386   DEFVAR_LISP ("x-dnd-native-test-function", Vx_dnd_native_test_function,
 32387     doc: /* Function that determines return value of drag-and-drop on Emacs frames.
 32388 If the value is a function, `x-begin-drag' will call it with two
 32389 arguments, POS and ACTION, where POS is a mouse position list
 32390 that specifies the location of the drop, and ACTION is the
 32391 action specified by the caller of `x-begin-drag'.  The function
 32392 should return a symbol describing what to return from
 32393 `x-begin-drag' if the drop happens on an Emacs frame.
 32394 
 32395 If the value is nil, or the function returns a value that is not
 32396 a symbol, a drop on an Emacs frame will be canceled.  */);
 32397   Vx_dnd_native_test_function = Qnil;
 32398 
 32399   DEFVAR_BOOL ("x-dnd-preserve-selection-data", x_dnd_preserve_selection_data,
 32400     doc: /* Preserve selection data after `x-begin-drag' returns.
 32401 This lets you inspect the contents of `XdndSelection' after a
 32402 drag-and-drop operation, which is useful when writing tests for
 32403 drag-and-drop code.  */);
 32404   x_dnd_preserve_selection_data = false;
 32405 
 32406   DEFVAR_BOOL ("x-dnd-disable-motif-protocol", x_dnd_disable_motif_protocol,
 32407     doc: /* Disable the Motif drag-and-drop protocols.
 32408 When non-nil, `x-begin-drag' will not drop onto any window that only
 32409 supports the Motif drag-and-drop protocols.  */);
 32410   x_dnd_disable_motif_protocol = false;
 32411 
 32412   DEFVAR_BOOL ("x-dnd-use-unsupported-drop", x_dnd_use_unsupported_drop,
 32413     doc: /* Enable the emulation of drag-and-drop based on the primary selection.
 32414 When nil, do not use the primary selection and synthetic mouse clicks
 32415 to emulate the drag-and-drop of `STRING', `UTF8_STRING',
 32416 `COMPOUND_TEXT' or `TEXT'.  */);
 32417   x_dnd_use_unsupported_drop = true;
 32418 
 32419   DEFVAR_BOOL ("x-fast-protocol-requests", x_fast_protocol_requests,
 32420     doc: /* Whether or not X protocol-related functions should wait for errors.
 32421 When this is nil, functions such as `x-delete-window-property',
 32422 `x-change-window-property' and `x-send-client-message' will wait for a
 32423 reply from the X server, and signal any errors that occurred while
 32424 executing the protocol request.  Otherwise, errors will be silently
 32425 ignored without waiting, which is generally faster.  */);
 32426   x_fast_protocol_requests = false;
 32427 
 32428   DEFVAR_LISP ("x-auto-preserve-selections", Vx_auto_preserve_selections,
 32429     doc: /* Whether or not to transfer selection ownership when deleting a frame.
 32430 When non-nil, deleting a frame that is currently the owner of a
 32431 selection will cause its ownership to be transferred to another frame
 32432 on the same display.
 32433 
 32434 In addition, when this variable is a list, only preserve the
 32435 selections whose names are contained within.  */);
 32436   Vx_auto_preserve_selections = list2 (QCLIPBOARD, QPRIMARY);
 32437 
 32438   DEFVAR_LISP ("x-input-coding-system", Vx_input_coding_system,
 32439     doc: /* Coding system used for input from X input methods.
 32440 If a symbol and non-nil, this is the coding system that will be used
 32441 to decode input from X input methods.  It does not affect input from
 32442 GTK native input methods enabled through `x-gtk-use-native-input'.  */);
 32443   Vx_input_coding_system = Qnil;
 32444 
 32445   DEFVAR_LISP ("x-input-coding-function", Vx_input_coding_function,
 32446     doc: /* Function used to determine the coding system used by input methods.
 32447 It should accept a single argument, a string describing the locale of
 32448 the input method, and return a coding system that can decode keyboard
 32449 input generated by said input method.  */);
 32450   Vx_input_coding_function = Qnil;
 32451 
 32452   DEFVAR_LISP ("x-fast-selection-list", Vx_fast_selection_list,
 32453     doc: /* List of selections for which `x-selection-exists-p' should be fast.
 32454 
 32455 List of selection names as atoms that will be monitored by Emacs for
 32456 ownership changes when the X server supports the XFIXES extension.
 32457 The result of the monitoring is then used by `x-selection-exists-p' to
 32458 avoid a server round trip, which is important as it is called while
 32459 updating the tool bar.  The value of this variable is only read upon
 32460 connection setup.  */);
 32461   /* The default value of this variable is chosen so that updating the
 32462      tool bar does not require a call to _XReply.  */
 32463   Vx_fast_selection_list = list1 (QCLIPBOARD);
 32464 
 32465   DEFVAR_LISP ("x-allow-focus-stealing", Vx_allow_focus_stealing,
 32466     doc: /* How to bypass window manager focus stealing prevention.
 32467 
 32468 Some window managers prevent `x-focus-frame' from activating the given
 32469 frame when Emacs is in the background, which is especially prone to
 32470 cause problems when the Emacs server wants to activate itself.
 32471 
 32472 In addition, when an old-fashioned (pre-EWMH) window manager is being
 32473 run and `x-no-window-manager' is nil, the X server will not let Emacs
 32474 focus itself if another program was focused after the last time Emacs
 32475 obtained the input focus.
 32476 
 32477 This variable specifies the strategy used to activate frames when that
 32478 is the case, and has several valid values (any other value means to
 32479 not bypass window manager focus stealing prevention):
 32480 
 32481   - The symbol `imitate-pager', which means to pretend that Emacs is a
 32482     pager.
 32483 
 32484   - The symbol `newer-time', which means to fetch the current time
 32485     from the X server and use it to activate the frame.
 32486 
 32487   - The symbol `raise-and-focus', which means to raise the window and
 32488     focus it manually.  */);
 32489   Vx_allow_focus_stealing = Qnewer_time;
 32490 
 32491   DEFVAR_LISP ("x-use-fast-mouse-position", Vx_use_fast_mouse_position,
 32492     doc: /* How to make `mouse-position' faster.
 32493 
 32494 `mouse-position' and `mouse-pixel-position' default to querying the X
 32495 server for the window under the mouse pointer.  This results in
 32496 accurate results, but is also very slow when the X connection has
 32497 moderate to high latency.  Setting this variable to a non-nil value
 32498 makes Emacs query only for the position of the pointer, which is
 32499 usually faster.  Doing so improves the performance of dragging to
 32500 select text over slow X connections.
 32501 
 32502 If that is still too slow, setting this variable to the symbol
 32503 `really-fast' will make Emacs return only cached values.  */);
 32504   Vx_use_fast_mouse_position = Qnil;
 32505 
 32506   DEFVAR_LISP ("x-detect-server-trust", Vx_detect_server_trust,
 32507     doc: /* If non-nil, Emacs should detect whether or not it is trusted by X.
 32508 
 32509 If non-nil, Emacs will make an X request at connection startup that is
 32510 prohibited to untrusted clients under the X Security Extension and
 32511 check whether or not a resulting Access error is generated by the X
 32512 server.  If the X server reports the error, Emacs will disable certain
 32513 features that do not work for untrusted clients.  */);
 32514   Vx_detect_server_trust = Qnil;
 32515 
 32516   DEFVAR_LISP ("x-lax-frame-positioning", Vx_lax_frame_positioning,
 32517     doc: /* If non-nil, Emacs won't compensate for WM geometry behavior.
 32518 
 32519 Setting this to non-nil is useful when the compensation proves to be
 32520 too slow, which is usually true when the X server is located over a
 32521 network connection with high latency.  Doing so will make frame
 32522 creation and placement faster at the cost of reducing the accuracy of
 32523 frame placement via frame parameters, `set-frame-position', and
 32524 `set-frame-size', along with the actual state of a frame after
 32525 `x_make_frame_invisible'.  */);
 32526   Vx_lax_frame_positioning = Qnil;
 32527 
 32528   DEFVAR_LISP ("x-quit-keysym", Vx_quit_keysym,
 32529     doc: /* Keysyms which will cause Emacs to quit if rapidly pressed twice.
 32530 
 32531 This is used to support quitting on devices that do not have any kind
 32532 of physical keyboard, or where the physical keyboard is incapable of
 32533 entering `C-g'.  It defaults to `XF86XK_AudioLowerVolume' on XFree86
 32534 and X.Org servers, and is unset.
 32535 
 32536 The value is an alist associating between strings, describing X server
 32537 vendor names, and a single number describing the keysym to use.  The
 32538 keysym to use for each display connection is determined upon
 32539 connection setup, and does not reflect further changes to this
 32540 variable.  */);
 32541   Vx_quit_keysym
 32542     = list2 (Fcons (build_string ("The X.Org Foundation"),
 32543                     make_int (269025041)),
 32544              Fcons (build_string ("The XFree86 Project, Inc."),
 32545                     make_int (269025041)));
 32546 }

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